# dont show .gdb_history files
.gdb_history
+# cscope -b
+cscope.out
+# cscope -q
+cscope.in.out
+cscope.po.out
+
# generated by the top level install.html target. XXX Why does it need this?
/vms/README_vms.pod
d_munmap=''
d_nan=''
d_nearbyint=''
+d_freelocale=''
+d_newlocale=''
+d_uselocale=''
d_nextafter=''
d_nexttoward=''
d_nice=''
use64bitint=''
usecbacktrace=''
dtrace=''
+dtraceobject=''
usedtrace=''
usefaststdio=''
usekernprocpathname=''
esac
done
+case "$usedtrace" in
+$define)
+ case "$dtraceobject" in
+ $define|true|[yY]*)
+ dtraceobject=$define
+ ;;
+ ' '|'')
+ $dtrace -h -s ../perldtrace.d -o perldtrace.h
+ $cat >try.c <<EOM
+#include "perldtrace.h"
+int main(void) {
+ PERL_LOADED_FILE("dummy");
+ return 0;
+}
+EOM
+ dtraceobject=$undef
+ if $cc -c -o try.o $optimize $ccflags try.c \
+ && $dtrace -G -s ../perldtrace.d try.o >/dev/null 2>&1; then
+ dtraceobject=$define
+ echo "Your dtrace builds an object file"
+ fi
+ $rm -f try.c try.o perldtrace.o
+ ;;
+ *) dtraceobject=$undef ;;
+ esac
+esac
+
: See if we want extra modules installed
echo " "
case "$extras" in
set nearbyint d_nearbyint
eval $inlibc
+: see if newlocale exists
+set newlocale d_newlocale
+eval $inlibc
+
+: see if freelocale exists
+set freelocale d_freelocale
+eval $inlibc
+
+: see if uselocale exists
+set uselocale d_uselocale
+eval $inlibc
+
: see if nextafter exists
set nextafter d_nextafter
eval $inlibc
eval $hasfield_t;
;;
+*)
+ d_siginfo_si_errno="$undef"
+ d_siginfo_si_pid="$undef"
+ d_siginfo_si_uid="$undef"
+ d_siginfo_si_addr="$undef"
+ d_siginfo_si_status="$undef"
+ d_siginfo_si_band="$undef"
+ d_siginfo_si_value="$undef"
+ ;;
esac
: Determine if we can use sysctl with KERN_PROC_PATHNAME to find executing program
irix-) ccflags="\$ccflags -woff 1178" ;;
os2-*) ccflags="\$ccflags -Zlinker /PM:VIO" ;;
esac
-$cc -o try -Dcpp_stuff=$cpp_stuff $optimize \$ccflags $ldflags try.c $libs && $run ./try | $sed 's/ /\\\\ /g'
+$cc -o try -Dcpp_stuff=$cpp_stuff $optimize \$ccflags $ldflags try.c $libs 2>/dev/null && $run ./try | $sed 's/ /\\\\ /g'
EOSH
chmod +x Cppsym.try
$eunicefix Cppsym.try
d_fpclassl='$d_fpclassl'
d_fpgetround='$d_fpgetround'
d_fpos64_t='$d_fpos64_t'
+d_freelocale='$d_freelocale'
d_frexpl='$d_frexpl'
d_fs_data_s='$d_fs_data_s'
d_fseeko='$d_fseeko'
d_ndbm='$d_ndbm'
d_ndbm_h_uses_prototypes='$d_ndbm_h_uses_prototypes'
d_nearbyint='$d_nearbyint'
+d_newlocale='$d_newlocale'
d_nextafter='$d_nextafter'
d_nexttoward='$d_nexttoward'
d_nice='$d_nice'
d_union_semun='$d_union_semun'
d_unordered='$d_unordered'
d_unsetenv='$d_unsetenv'
+d_uselocale='$d_uselocale'
d_usleep='$d_usleep'
d_usleepproto='$d_usleepproto'
d_ustat='$d_ustat'
drand01='$drand01'
drand48_r_proto='$drand48_r_proto'
dtrace='$dtrace'
+dtraceobject='$dtraceobject'
dynamic_ext='$dynamic_ext'
eagain='$eagain'
ebcdic='$ebcdic'
$(LIBPERL_NONSHR): $(obj)
$(RMS) $(LIBPERL_NONSHR)
- $(AR) rcu $(LIBPERL_NONSHR) $(obj)
+ $(AR) rc $(LIBPERL_NONSHR) $(obj)
$(MINIPERL_NONSHR): $(LIBPERL_NONSHR) miniperlmain$(OBJ_EXT) opmini$(OBJ_EXT)
$(CC) $(LDFLAGS) -o $(MINIPERL_NONSHR) miniperlmain$(OBJ_EXT) \
*)
$spitshell >>$Makefile <<'!NO!SUBS!'
rm -f $(LIBPERL)
- $(AR) rcu $(LIBPERL) $(obj) $(DYNALOADER)
+ $(AR) rc $(LIBPERL) $(obj) $(DYNALOADER)
@$(ranlib) $(LIBPERL)
!NO!SUBS!
;;
ansi2knr=''
aphostname='/bin/hostname'
api_revision='5'
-api_subversion='8'
+api_subversion='9'
api_version='23'
-api_versionstring='5.23.8'
+api_versionstring='5.23.9'
ar='ar'
-archlib='/usr/lib/perl5/5.23.8/armv4l-linux'
-archlibexp='/usr/lib/perl5/5.23.8/armv4l-linux'
+archlib='/usr/lib/perl5/5.23.9/armv4l-linux'
+archlibexp='/usr/lib/perl5/5.23.9/armv4l-linux'
archname64=''
archname='armv4l-linux'
archobjs=''
cat='cat'
cc='cc'
cccdlflags='-fpic'
-ccdlflags='-rdynamic -Wl,-rpath,/usr/lib/perl5/5.23.8/armv4l-linux/CORE'
+ccdlflags='-rdynamic -Wl,-rpath,/usr/lib/perl5/5.23.9/armv4l-linux/CORE'
ccflags='-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
ccflags_uselargefiles='-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
ccname='arm-linux-gcc'
d_fpclassl='undef'
d_fpgetround='undef'
d_fpos64_t='undef'
+d_freelocale='undef'
d_frexpl='define'
d_fs_data_s='undef'
d_fseeko='define'
d_nan='undef'
d_ndbm_h_uses_prototypes='undef'
d_nearbyint='undef'
+d_newlocale='undef'
d_nextafter='undef'
d_nexttoward='undef'
d_nice='define'
d_union_semun='undef'
d_unordered='undef'
d_unsetenv='define'
+d_uselocale='undef'
d_usleep='define'
d_usleepproto='define'
d_ustat='define'
inc_version_list_init='0'
incpath=''
inews=''
-installarchlib='./install_me_here/usr/lib/perl5/5.23.8/armv4l-linux'
+installarchlib='./install_me_here/usr/lib/perl5/5.23.9/armv4l-linux'
installbin='./install_me_here/usr/bin'
installhtml1dir=''
installhtml3dir=''
installman3dir='./install_me_here/usr/share/man/man3'
installprefix='./install_me_here/usr'
installprefixexp='./install_me_here/usr'
-installprivlib='./install_me_here/usr/lib/perl5/5.23.8'
+installprivlib='./install_me_here/usr/lib/perl5/5.23.9'
installscript='./install_me_here/usr/bin'
-installsitearch='./install_me_here/usr/lib/perl5/site_perl/5.23.8/armv4l-linux'
+installsitearch='./install_me_here/usr/lib/perl5/site_perl/5.23.9/armv4l-linux'
installsitebin='./install_me_here/usr/bin'
installsitehtml1dir=''
installsitehtml3dir=''
-installsitelib='./install_me_here/usr/lib/perl5/site_perl/5.23.8'
+installsitelib='./install_me_here/usr/lib/perl5/site_perl/5.23.9'
installsiteman1dir='./install_me_here/usr/share/man/man1'
installsiteman3dir='./install_me_here/usr/share/man/man3'
installsitescript='./install_me_here/usr/bin'
pr=''
prefix='/usr'
prefixexp='/usr'
-privlib='/usr/lib/perl5/5.23.8'
-privlibexp='/usr/lib/perl5/5.23.8'
+privlib='/usr/lib/perl5/5.23.9'
+privlibexp='/usr/lib/perl5/5.23.9'
procselfexe='"/proc/self/exe"'
prototype='define'
ptrsize='4'
sig_num_init='0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 6, 17, 29, 31, 0'
sig_size='68'
signal_t='void'
-sitearch='/usr/lib/perl5/site_perl/5.23.8/armv4l-linux'
-sitearchexp='/usr/lib/perl5/site_perl/5.23.8/armv4l-linux'
+sitearch='/usr/lib/perl5/site_perl/5.23.9/armv4l-linux'
+sitearchexp='/usr/lib/perl5/site_perl/5.23.9/armv4l-linux'
sitebin='/usr/bin'
sitebinexp='/usr/bin'
sitehtml1dir=''
sitehtml1direxp=''
sitehtml3dir=''
sitehtml3direxp=''
-sitelib='/usr/lib/perl5/site_perl/5.23.8'
+sitelib='/usr/lib/perl5/site_perl/5.23.9'
sitelib_stem='/usr/lib/perl5/site_perl'
-sitelibexp='/usr/lib/perl5/site_perl/5.23.8'
+sitelibexp='/usr/lib/perl5/site_perl/5.23.9'
siteman1dir='/usr/share/man/man1'
siteman1direxp='/usr/share/man/man1'
siteman3dir='/usr/share/man/man3'
strerror_r_proto='0'
strings='/usr/include/string.h'
submit=''
-subversion='8'
+subversion='9'
sysman='/usr/share/man/man1'
tail=''
tar=''
vendorprefixexp=''
vendorscript=''
vendorscriptexp=''
-version='5.23.8'
-version_patchlevel_string='version 23 subversion 8'
+version='5.23.9'
+version_patchlevel_string='version 23 subversion 9'
versiononly='undef'
vi=''
xlibpth='/usr/lib/386 /lib/386'
config_argc=0
PERL_REVISION=5
PERL_VERSION=23
-PERL_SUBVERSION=8
+PERL_SUBVERSION=9
PERL_API_REVISION=5
PERL_API_VERSION=23
-PERL_API_SUBVERSION=8
+PERL_API_SUBVERSION=9
PERL_PATCHLEVEL=
PERL_CONFIG_SH=true
ansi2knr=''
aphostname='/bin/hostname'
api_revision='5'
-api_subversion='8'
+api_subversion='9'
api_version='23'
-api_versionstring='5.23.8'
+api_versionstring='5.23.9'
ar='ar'
-archlib='/usr/lib/perl5/5.23.8/armv4l-linux'
-archlibexp='/usr/lib/perl5/5.23.8/armv4l-linux'
+archlib='/usr/lib/perl5/5.23.9/armv4l-linux'
+archlibexp='/usr/lib/perl5/5.23.9/armv4l-linux'
archname64=''
archname='armv4l-linux'
archobjs=''
cat='cat'
cc='arm-none-linux-gnueabi-gcc'
cccdlflags='-fpic'
-ccdlflags='-rdynamic -Wl,-rpath,/usr/lib/perl5/5.23.8/armv4l-linux/CORE'
+ccdlflags='-rdynamic -Wl,-rpath,/usr/lib/perl5/5.23.9/armv4l-linux/CORE'
ccflags='-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
ccflags_uselargefiles='-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
ccname='arm-linux-gcc'
inc_version_list_init='0'
incpath=''
inews=''
-installarchlib='./install_me_here/usr/lib/perl5/5.23.8/armv4l-linux'
+installarchlib='./install_me_here/usr/lib/perl5/5.23.9/armv4l-linux'
installbin='./install_me_here/usr/bin'
installhtml1dir=''
installhtml3dir=''
installman3dir='./install_me_here/usr/share/man/man3'
installprefix='./install_me_here/usr'
installprefixexp='./install_me_here/usr'
-installprivlib='./install_me_here/usr/lib/perl5/5.23.8'
+installprivlib='./install_me_here/usr/lib/perl5/5.23.9'
installscript='./install_me_here/usr/bin'
-installsitearch='./install_me_here/usr/lib/perl5/site_perl/5.23.8/armv4l-linux'
+installsitearch='./install_me_here/usr/lib/perl5/site_perl/5.23.9/armv4l-linux'
installsitebin='./install_me_here/usr/bin'
installsitehtml1dir=''
installsitehtml3dir=''
-installsitelib='./install_me_here/usr/lib/perl5/site_perl/5.23.8'
+installsitelib='./install_me_here/usr/lib/perl5/site_perl/5.23.9'
installsiteman1dir='./install_me_here/usr/share/man/man1'
installsiteman3dir='./install_me_here/usr/share/man/man3'
installsitescript='./install_me_here/usr/bin'
pr=''
prefix='/usr'
prefixexp='/usr'
-privlib='/usr/lib/perl5/5.23.8'
-privlibexp='/usr/lib/perl5/5.23.8'
+privlib='/usr/lib/perl5/5.23.9'
+privlibexp='/usr/lib/perl5/5.23.9'
procselfexe='"/proc/self/exe"'
prototype='define'
ptrsize='4'
sig_num_init='0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 6, 17, 29, 31, 0'
sig_size='68'
signal_t='void'
-sitearch='/usr/lib/perl5/site_perl/5.23.8/armv4l-linux'
-sitearchexp='/usr/lib/perl5/site_perl/5.23.8/armv4l-linux'
+sitearch='/usr/lib/perl5/site_perl/5.23.9/armv4l-linux'
+sitearchexp='/usr/lib/perl5/site_perl/5.23.9/armv4l-linux'
sitebin='/usr/bin'
sitebinexp='/usr/bin'
sitehtml1dir=''
sitehtml1direxp=''
sitehtml3dir=''
sitehtml3direxp=''
-sitelib='/usr/lib/perl5/site_perl/5.23.8'
+sitelib='/usr/lib/perl5/site_perl/5.23.9'
sitelib_stem='/usr/lib/perl5/site_perl'
-sitelibexp='/usr/lib/perl5/site_perl/5.23.8'
+sitelibexp='/usr/lib/perl5/site_perl/5.23.9'
siteman1dir='/usr/share/man/man1'
siteman1direxp='/usr/share/man/man1'
siteman3dir='/usr/share/man/man3'
strerror_r_proto='0'
strings='/usr/include/string.h'
submit=''
-subversion='8'
+subversion='9'
sysman='/usr/share/man/man1'
tail=''
tar=''
vendorprefixexp=''
vendorscript=''
vendorscriptexp=''
-version='5.23.8'
-version_patchlevel_string='version 23 subversion 8'
+version='5.23.9'
+version_patchlevel_string='version 23 subversion 9'
versiononly='undef'
vi=''
xlibpth='/usr/lib/386 /lib/386'
config_argc=0
PERL_REVISION=5
PERL_VERSION=23
-PERL_SUBVERSION=8
+PERL_SUBVERSION=9
PERL_API_REVISION=5
PERL_API_VERSION=23
-PERL_API_SUBVERSION=8
+PERL_API_SUBVERSION=9
PERL_PATCHLEVEL=
PERL_CONFIG_SH=true
=item Directories for the perl distribution
-By default, Configure will use the following directories for 5.23.8.
+By default, Configure will use the following directories for 5.23.9.
$version is the full perl version number, including subversion, e.g.
5.12.3, and $archname is a string like sun4-sunos,
determined by Configure. The full definitions of all Configure
=head1 Coexistence with earlier versions of perl 5
-Perl 5.23.8 is not binary compatible with earlier versions of Perl.
+Perl 5.23.9 is not binary compatible with earlier versions of Perl.
In other words, you will have to recompile your XS modules.
In general, you can usually safely upgrade from one version of Perl
libraries after 5.6.0, but not for executables. TODO?) One convenient
way to do this is by using a separate prefix for each version, such as
- sh Configure -Dprefix=/opt/perl5.23.8
+ sh Configure -Dprefix=/opt/perl5.23.9
-and adding /opt/perl5.23.8/bin to the shell PATH variable. Such users
+and adding /opt/perl5.23.9/bin to the shell PATH variable. Such users
may also wish to add a symbolic link /usr/local/bin/perl so that
scripts can still start with #!/usr/local/bin/perl.
=head2 Upgrading from 5.23.7 or earlier
-B<Perl 5.23.8 may not be binary compatible with Perl 5.23.7 or
+B<Perl 5.23.9 may not be binary compatible with Perl 5.23.7 or
earlier Perl releases.> Perl modules having binary parts
(meaning that a C compiler is used) will have to be recompiled to be
-used with 5.23.8. If you find you do need to rebuild an extension with
-5.23.8, you may safely do so without disturbing the older
+used with 5.23.9. If you find you do need to rebuild an extension with
+5.23.9, you may safely do so without disturbing the older
installations. (See L<"Coexistence with earlier versions of perl 5">
above.)
print("$f\n");
}
-in Linux with perl-5.23.8 is as follows (under $Config{prefix}):
+in Linux with perl-5.23.9 is as follows (under $Config{prefix}):
./bin/perl
- ./lib/perl5/5.23.8/strict.pm
- ./lib/perl5/5.23.8/warnings.pm
- ./lib/perl5/5.23.8/i686-linux/File/Glob.pm
- ./lib/perl5/5.23.8/feature.pm
- ./lib/perl5/5.23.8/XSLoader.pm
- ./lib/perl5/5.23.8/i686-linux/auto/File/Glob/Glob.so
+ ./lib/perl5/5.23.9/strict.pm
+ ./lib/perl5/5.23.9/warnings.pm
+ ./lib/perl5/5.23.9/i686-linux/File/Glob.pm
+ ./lib/perl5/5.23.9/feature.pm
+ ./lib/perl5/5.23.9/XSLoader.pm
+ ./lib/perl5/5.23.9/i686-linux/auto/File/Glob/Glob.so
Secondly, for perl-5.10.1, the Debian perl-base package contains 591
files, (of which 510 are for lib/unicore) totaling about 3.5MB in its
cpan/version/t/07locale.t Tests for version objects
cpan/version/t/08_corelist.t Tests for version objects
cpan/version/t/09_list_util.t Tests for version objects
+cpan/version/t/10_lyon.t Tests for version objects
cpan/version/t/coretests.pm Tests for version objects
cpan/Win32API-File/buffers.h Win32API::File extension
cpan/Win32API-File/cFile.h Win32API::File extension
cpan/Win32API-File/cFile.pc Win32API::File extension
cpan/Win32API-File/const2perl.h Win32API::File extension
-cpan/Win32API-File/ExtUtils/Myconst2perl.pm Win32API::File extension
cpan/Win32API-File/File.pm Win32API::File extension
cpan/Win32API-File/File.xs Win32API::File extension
+cpan/Win32API-File/inc/ExtUtils/Myconst2perl.pm Win32API::File extension
cpan/Win32API-File/Makefile.PL Win32API::File extension makefile write
cpan/Win32API-File/t/file.t See if Win32API::File extension works
cpan/Win32API-File/t/tie.t See if Win32API::File extension works
dist/Net-Ping/t/500_ping_icmp.t Ping Net::Ping
dist/Net-Ping/t/510_ping_udp.t Ping Net::Ping
dist/Net-Ping/t/520_icmp_ttl.t Ping Net::Ping
+dist/PathTools/Changes Changelog for PathTools dist
dist/PathTools/Cwd.pm Various cwd routines (getcwd, fastcwd, chdir)
dist/PathTools/Cwd.xs Cwd extension external subroutines
dist/PathTools/lib/File/Spec/AmigaOS.pm portable operations on AmigaOS file names
pod/perl5235delta.pod Perl changes in version 5.23.5
pod/perl5236delta.pod Perl changes in version 5.23.6
pod/perl5237delta.pod Perl changes in version 5.23.7
+pod/perl5238delta.pod Perl changes in version 5.23.8
pod/perl561delta.pod Perl changes in version 5.6.1
pod/perl56delta.pod Perl changes in version 5.6
pod/perl581delta.pod Perl changes in version 5.8.1
"url" : "http://perl5.git.perl.org/"
}
},
- "version" : "5.023008",
+ "version" : "5.023009",
"x_serialization_backend" : "JSON::PP version 2.27300"
}
homepage: http://www.perl.org/
license: http://dev.perl.org/licenses/
repository: http://perl5.git.perl.org/
-version: '5.023008'
+version: '5.023009'
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
done
dtrace_h=''
-dtrace_o=''
-minidtrace_o=''
+
+# three object files generated by 'dtrace -G' when dtrace is enabled
+dtrace_perllib_o=''
+dtrace_mini_o=''
+dtrace_main_o=''
+
case "$usedtrace" in
define|true)
- dtrace_h='perldtrace.h'
- $dtrace -G -s perldtrace.d -o perldtrace.tmp >/dev/null 2>&1 \
- && rm -f perldtrace.tmp && dtrace_o='perldtrace$(OBJ_EXT)' \
- && minidtrace_o='miniperldtrace$(OBJ_EXT)'
+ dtrace_h='perldtrace.h'
+ case "$dtraceobject" in
+ define)
+ dtrace_perllib_o='dtrace_perllib$(OBJ_EXT)'
+ dtrace_mini_o='dtrace_mini$(OBJ_EXT)'
+ dtrace_main_o='dtrace_main$(OBJ_EXT)'
+ ;;
+ esac
;;
esac
$spitshell >>$Makefile <<!GROK!THIS!
DTRACE = $dtrace
DTRACE_H = $dtrace_h
-DTRACE_O = $dtrace_o
-MINIDTRACE_O = $minidtrace_o
+
+DTRACE_PERLLIB_O = $dtrace_perllib_o # "dtrace -G" output for perllib_objs
+DTRACE_MINI_O = $dtrace_mini_o # "dtrace -G" output for common and mini
+DTRACE_MAIN_O = $dtrace_main_o # "dtrace -G" output for perlmain.o
FIRSTMAKEFILE = $firstmakefile
c = $(c1) $(c2) $(c3) $(c4) $(c5) miniperlmain.c opmini.c perlmini.c
-obj0 = op$(OBJ_EXT) perl$(OBJ_EXT)
-obj0mini = perlmini$(OBJ_EXT) opmini$(OBJ_EXT) miniperlmain$(OBJ_EXT)
obj1 = $(mallocobj) gv$(OBJ_EXT) toke$(OBJ_EXT) perly$(OBJ_EXT) pad$(OBJ_EXT) regcomp$(OBJ_EXT) dump$(OBJ_EXT) util$(OBJ_EXT) mg$(OBJ_EXT) reentr$(OBJ_EXT) mro_core$(OBJ_EXT) keywords$(OBJ_EXT)
obj2 = hv$(OBJ_EXT) av$(OBJ_EXT) run$(OBJ_EXT) pp_hot$(OBJ_EXT) sv$(OBJ_EXT) pp$(OBJ_EXT) scope$(OBJ_EXT) pp_ctl$(OBJ_EXT) pp_sys$(OBJ_EXT)
obj3 = doop$(OBJ_EXT) doio$(OBJ_EXT) regexec$(OBJ_EXT) utf8$(OBJ_EXT) taint$(OBJ_EXT) deb$(OBJ_EXT) universal$(OBJ_EXT) globals$(OBJ_EXT) perlio$(OBJ_EXT) perlapi$(OBJ_EXT) numeric$(OBJ_EXT) mathoms$(OBJ_EXT) locale$(OBJ_EXT) pp_pack$(OBJ_EXT) pp_sort$(OBJ_EXT) caretx$(OBJ_EXT) dquote$(OBJ_EXT) time64$(OBJ_EXT)
-minindt_obj = $(obj0mini) $(obj1) $(obj2) $(obj3) $(ARCHOBJS)
-mini_obj = $(minindt_obj) $(MINIDTRACE_O)
-ndt_obj = $(obj0) $(obj1) $(obj2) $(obj3) $(ARCHOBJS)
-obj = $(ndt_obj) $(DTRACE_O)
+# split the objects into 3 exclusive sets: those used by both miniperl and
+# perl, and those used by just one or the other. Doesn't include the
+# actual perl(mini)main.o, nor any dtrace objects.
+
+common_objs = $(obj1) $(obj2) $(obj3) $(ARCHOBJS)
+mini_only_objs = opmini$(OBJ_EXT) perlmini$(OBJ_EXT)
+main_only_objs = op$(OBJ_EXT) perl$(OBJ_EXT)
-perltoc_pod_prereqs = extra.pods pod/perl5238delta.pod pod/perlapi.pod pod/perlintern.pod pod/perlmodlib.pod pod/perluniprops.pod
+miniperl_objs_nodt = $(mini_only_objs) $(common_objs) miniperlmain$(OBJ_EXT)
+perllib_objs_nodt = $(main_only_objs) $(common_objs)
+
+miniperl_objs = $(miniperl_objs_nodt) $(DTRACE_MINI_O)
+perllib_objs = $(perllib_objs_nodt) $(DTRACE_PERLLIB_O)
+perlmain_objs = perlmain$(OBJ_EXT) $(DTRACE_MAIN_O)
+
+perltoc_pod_prereqs = extra.pods pod/perl5239delta.pod pod/perlapi.pod pod/perlintern.pod pod/perlmodlib.pod pod/perluniprops.pod
generated_pods = pod/perltoc.pod $(perltoc_pod_prereqs)
generated_headers = uudmap.h bitcount.h mg_data.h
LIBPERL_NONSHR = libperl_nonshr$(LIB_EXT)
MINIPERL_NONSHR = miniperl_nonshr$(EXE_EXT)
-$(LIBPERL_NONSHR): $(obj)
+$(LIBPERL_NONSHR): $(perllib_objs)
$(RMS) $(LIBPERL_NONSHR)
- $(AR) rcu $(LIBPERL_NONSHR) $(obj)
+ $(AR) rc $(LIBPERL_NONSHR) $(perllib_objs)
$(MINIPERL_NONSHR): $(LIBPERL_NONSHR) miniperlmain$(OBJ_EXT) opmini$(OBJ_EXT) perlmini$(OBJ_EXT)
$(CC) $(LDFLAGS) -o $(MINIPERL_NONSHR) miniperlmain$(OBJ_EXT) \
LIBPERL_NONSHR = libperl$(LIB_EXT)
-$(LIBPERL_NONSHR): $(obj)
+$(LIBPERL_NONSHR): $(perllib_objs)
$(RMS) $(LIBPERL_NONSHR)
- $(AR) rcu $(LIBPERL_NONSHR) $(obj)
+ $(AR) rc $(LIBPERL_NONSHR) $(perllib_objs)
!NO!SUBS!
;;
!NO!SUBS!
;;
esac
- case "$dtrace_o" in
- ?*)
+ case "$dtraceobject" in
+ define)
$spitshell >>$Makefile <<'!NO!SUBS!'
-$(DTRACE_O): perldtrace.d $(ndt_obj)
- $(DTRACE) -G -s perldtrace.d -o $(DTRACE_O) $(ndt_obj)
+$(DTRACE_MINI_O): perldtrace.d $(miniperl_objs_nodt)
+ $(DTRACE) -G -s perldtrace.d -o $(DTRACE_MINI_O) $(miniperl_objs_nodt)
-$(MINIDTRACE_O): perldtrace.d $(minindt_obj) perlmini$(OBJ_EXT)
- $(DTRACE) -G -s perldtrace.d -o $(MINIDTRACE_O) $(minindt_obj) perlmini$(OBJ_EXT)
+$(DTRACE_PERLLIB_O): perldtrace.d $(perllib_objs_nodt)
+ $(DTRACE) -G -s perldtrace.d -o $(DTRACE_PERLLIB_O) $(perllib_objs_nodt)
+
+$(DTRACE_MAIN_O): perldtrace.d perlmain$(OBJ_EXT)
+ $(DTRACE) -G -s perldtrace.d -o $(DTRACE_MAIN_O) perlmain$(OBJ_EXT)
!NO!SUBS!
;;
esac
$spitshell >>$Makefile <<'!NO!SUBS!'
-$(LIBPERL): $& $(obj) $(DYNALOADER) $(LIBPERLEXPORT)
+$(LIBPERL): $& $(perllib_objs) $(DYNALOADER) $(LIBPERLEXPORT)
!NO!SUBS!
case "$useshrplib" in
true)
$spitshell >>$Makefile <<'!NO!SUBS!'
rm -f $@
- $(LD) -o $@ $(SHRPLDFLAGS) $(obj) $(DYNALOADER) $(libs)
+ $(LD) -o $@ $(SHRPLDFLAGS) $(perllib_objs) $(DYNALOADER) $(libs)
!NO!SUBS!
case "$osname" in
aix)
*)
$spitshell >>$Makefile <<'!NO!SUBS!'
rm -f $(LIBPERL)
- $(AR) rcu $(LIBPERL) $(obj) $(DYNALOADER)
+ $(AR) rc $(LIBPERL) $(perllib_objs) $(DYNALOADER)
@$(ranlib) $(LIBPERL)
!NO!SUBS!
;;
case "${osname}${osvers}" in
amigaos*)
$spitshell >>$Makefile <<'!NO!SUBS!'
-lib/buildcustomize.pl: $& $(mini_obj) write_buildcustomize.pl
+lib/buildcustomize.pl: $& $(miniperl_objs) write_buildcustomize.pl
-@rm -f miniperl.xok
$(CC) $(CLDFLAGS) -o $(MINIPERL_EXE) \
- $(mini_obj) $(libs)
+ $(miniperl_objs) $(libs)
# $(LDLIBPTH) ./miniperl$(HOST_EXE_EXT) -w -Ilib -Idist/Exporter/lib -MExporter -e '<?>' || sh -c 'echo >&2 Failed to build miniperl. Please run make minitest; exit 1'
$(MINIPERL) -f write_buildcustomize.pl
!NO!SUBS!
;;
aix*)
$spitshell >>$Makefile <<'!NO!SUBS!'
-lib/buildcustomize.pl: $& $(mini_obj)
- $(CC) -o $(MINIPERL_EXE) $(CLDFLAGS) $(mini_obj) $(libs)
+lib/buildcustomize.pl: $& $(miniperl_objs)
+ $(CC) -o $(MINIPERL_EXE) $(CLDFLAGS) $(miniperl_objs) $(libs)
$(LDLIBPTH) ./miniperl$(HOST_EXE_EXT) -w -Ilib -Idist/Exporter/lib -MExporter -e '<?>' || sh -c 'echo >&2 Failed to build miniperl. Please run make minitest; exit 1'
$(MINIPERL) -f write_buildcustomize.pl
!NO!SUBS!
;;
next4*)
$spitshell >>$Makefile <<'!NO!SUBS!'
-lib/buildcustomize.pl: $& $(mini_obj) write ldcustomize.pl
- $(CC) -o $(MINIPERL_EXE) $(mini_obj libs)
+lib/buildcustomize.pl: $& $(miniperl_objs) write ldcustomize.pl
+ $(CC) -o $(MINIPERL_EXE) $(miniperl_objs libs)
$(LDLIBPTH) ./miniperl$(HOST _EXT) -w -Ilib -Idist/Exporter/lib -MExporter -e '<?>' || sh -c 'echo >&2 Failed to build miniperl. Please run make minitest; exit 1'
$(MINIPERL) -f write_buildcustomize.pl
!NO!SUBS!
;;
esac
$spitshell >>$Makefile <<'!NO!SUBS!'
-lib/buildcustomize.pl: $& $(mini_obj) write_buildcustomize.pl
+lib/buildcustomize.pl: $& $(miniperl_objs) write_buildcustomize.pl
-@rm -f miniperl.xok
$(CC) $(CLDFLAGS) $(NAMESPACEFLAGS) -o $(MINIPERL_EXE) \
- $(mini_obj) $(libs)
+ $(miniperl_objs) $(libs)
$(LDLIBPTH) ./miniperl$(HOST_EXE_EXT) -w -Ilib -Idist/Exporter/lib -MExporter -e '<?>' || sh -c 'echo >&2 Failed to build miniperl. Please run make minitest; exit 1'
$(MINIPERL) -f write_buildcustomize.pl
!NO!SUBS!
*)
if test "X$hostperl" != X; then
$spitshell >>$Makefile <<!GROK!THIS!
-lib/buildcustomize.pl: \$& \$(mini_obj) write_buildcustomize.pl
+lib/buildcustomize.pl: \$& \$(miniperl_objs) write_buildcustomize.pl
-@rm -f miniperl.xok
-@rm \$(MINIPERL_EXE)
\$(LNS) \$(HOST_PERL) \$(MINIPERL_EXE)
!GROK!THIS!
else
$spitshell >>$Makefile <<'!NO!SUBS!'
-lib/buildcustomize.pl: $& $(mini_obj) write_buildcustomize.pl
+lib/buildcustomize.pl: $& $(miniperl_objs) write_buildcustomize.pl
-@rm -f miniperl.xok
$(CC) $(CLDFLAGS) -o $(MINIPERL_EXE) \
- $(mini_obj) $(libs)
+ $(miniperl_objs) $(libs)
$(LDLIBPTH) ./miniperl$(HOST_EXE_EXT) -w -Ilib -Idist/Exporter/lib -MExporter -e '<?>' || sh -c 'echo >&2 Failed to build miniperl. Please run make minitest; exit 1'
$(MINIPERL) -f write_buildcustomize.pl
!NO!SUBS!
$spitshell >>$Makefile <<'!NO!SUBS!'
-$(PERL_EXE): $& perlmain$(OBJ_EXT) $(LIBPERL) $(static_ext) ext.libs $(PERLEXPORT) write_buildcustomize.pl
+$(PERL_EXE): $& $(perlmain_objs) $(LIBPERL) $(static_ext) ext.libs $(PERLEXPORT) write_buildcustomize.pl
-@rm -f miniperl.xok
!NO!SUBS!
# In AmigaOS the Perl executable needs to be linked with -ldl,
# but none of the other executables should be.
amigaos) $spitshell >>$Makefile <<'!NO!SUBS!'
- $(SHRPENV) $(CC) -o perl $(CLDFLAGS) $(CCDLFLAGS) perlmain$(OBJ_EXT) $(LLIBPERL) $(static_ext) `cat ext.libs` $(libs) -ldl
+ $(SHRPENV) $(CC) -o perl $(CLDFLAGS) $(CCDLFLAGS) $(perlmain_objs) $(LLIBPERL) $(static_ext) `cat ext.libs` $(libs) -ldl
!NO!SUBS!
;;
os390) $spitshell >>$Makefile <<'!NO!SUBS!'
- $(SHRPENV) $(CC) -o perl $(CLDFLAGS) $(CCDLFLAGS) perlmain$(OBJ_EXT) $(LLIBPERL) $(static_ext) `cat ext.libs` $(libs)
+ $(SHRPENV) $(CC) -o perl $(CLDFLAGS) $(CCDLFLAGS) $(perlmain_objs) $(LLIBPERL) $(static_ext) `cat ext.libs` $(libs)
!NO!SUBS!
;;
*) $spitshell >>$Makefile <<'!NO!SUBS!'
- $(SHRPENV) $(CC) -o perl $(CLDFLAGS) $(CCDLFLAGS) perlmain$(OBJ_EXT) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs)
+ $(SHRPENV) $(CC) -o perl $(CLDFLAGS) $(CCDLFLAGS) $(perlmain_objs) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs)
!NO!SUBS!
;;
esac
pod/perlmodlib.pod: $(MINIPERL_EXE) pod/perlmodlib.PL MANIFEST
$(MINIPERL) pod/perlmodlib.PL -q
-pod/perl5238delta.pod: pod/perldelta.pod
- $(RMS) pod/perl5238delta.pod
- $(LNS) perldelta.pod pod/perl5238delta.pod
+pod/perl5239delta.pod: pod/perldelta.pod
+ $(RMS) pod/perl5239delta.pod
+ $(LNS) perldelta.pod pod/perl5239delta.pod
extra.pods: $(MINIPERL_EXE)
-@test ! -f extra.pods || rm -f `cat extra.pods`
rm -rf pod/perlfunc pod/perlipc
-rmdir ext/B/lib
rm -f so_locations $(LIBPERL_NONSHR) $(MINIPERL_NONSHR)
- -rmdir lib/version lib/threads lib/encoding lib/autodie/exception
- -rmdir lib/autodie/Scope lib/autodie lib/XS lib/Win32API lib/VMS
- -rmdir lib/Unicode/Collate/Locale lib/Unicode/Collate/CJK
- -rmdir lib/Unicode/Collate lib/Tie/Hash lib/Thread lib/Text
- -rmdir lib/Test/use lib/Test/Tester lib/Test/Builder/Tester
- -rmdir lib/Test/Builder/IO lib/Test/Builder lib/Test lib/Term
- -rmdir lib/TAP/Parser/YAMLish lib/TAP/Parser/SourceHandler
- -rmdir lib/TAP/Parser/Scheduler lib/TAP/Parser/Result
- -rmdir lib/TAP/Parser/Iterator lib/TAP/Parser lib/TAP/Harness
- -rmdir lib/TAP/Formatter/File lib/TAP/Formatter/Console
- -rmdir lib/TAP/Formatter lib/TAP lib/Sys/Syslog lib/Sys lib/Sub
- -rmdir lib/Search lib/Scalar lib/Pod/Text lib/Pod/Simple
- -rmdir lib/Pod/Perldoc lib/PerlIO/via lib/PerlIO lib/Perl
- -rmdir lib/Parse/CPAN lib/Parse lib/Params lib/Net/FTP lib/Module/Load
- -rmdir lib/Module/CoreList lib/Module lib/Memoize lib/Math/BigInt
- -rmdir lib/Math/BigFloat lib/Math lib/MIME lib/Locale/Maketext
- -rmdir lib/Locale/Codes lib/Locale lib/List/Util lib/List lib/JSON/PP
- -rmdir lib/JSON lib/IPC lib/IO/Uncompress/Adapter lib/IO/Uncompress
- -rmdir lib/IO/Socket lib/IO/Compress/Zlib lib/IO/Compress/Zip
- -rmdir lib/IO/Compress/Gzip lib/IO/Compress/Base
+ -rmdir lib/version lib/threads lib/inc/ExtUtils lib/inc lib/encoding
+ -rmdir lib/autodie/exception lib/autodie/Scope lib/autodie lib/XS
+ -rmdir lib/Win32API lib/VMS lib/Unicode/Collate/Locale
+ -rmdir lib/Unicode/Collate/CJK lib/Unicode/Collate lib/Tie/Hash
+ -rmdir lib/Thread lib/Text lib/Test/use lib/Test/Tester
+ -rmdir lib/Test/Builder/Tester lib/Test/Builder/IO lib/Test/Builder
+ -rmdir lib/Test lib/Term lib/TAP/Parser/YAMLish
+ -rmdir lib/TAP/Parser/SourceHandler lib/TAP/Parser/Scheduler
+ -rmdir lib/TAP/Parser/Result lib/TAP/Parser/Iterator lib/TAP/Parser
+ -rmdir lib/TAP/Harness lib/TAP/Formatter/File
+ -rmdir lib/TAP/Formatter/Console lib/TAP/Formatter lib/TAP
+ -rmdir lib/Sys/Syslog lib/Sys lib/Sub lib/Search lib/Scalar
+ -rmdir lib/Pod/Text lib/Pod/Simple lib/Pod/Perldoc lib/PerlIO/via
+ -rmdir lib/PerlIO lib/Perl lib/Parse/CPAN lib/Parse lib/Params
+ -rmdir lib/Net/FTP lib/Module/Load lib/Module/CoreList lib/Module
+ -rmdir lib/Memoize lib/Math/BigInt lib/Math/BigFloat lib/Math lib/MIME
+ -rmdir lib/Locale/Maketext lib/Locale/Codes lib/Locale lib/List/Util
+ -rmdir lib/List lib/JSON/PP lib/JSON lib/IPC lib/IO/Uncompress/Adapter
+ -rmdir lib/IO/Uncompress lib/IO/Socket lib/IO/Compress/Zlib
+ -rmdir lib/IO/Compress/Zip lib/IO/Compress/Gzip lib/IO/Compress/Base
-rmdir lib/IO/Compress/Adapter lib/IO/Compress lib/IO
-rmdir lib/I18N/LangTags lib/I18N lib/Hash/Util lib/Hash lib/HTTP
-rmdir lib/Filter/Util lib/Filter lib/File/Spec lib/ExtUtils/Typemaps
splint: $(c)
splint $(splintflags) -DPERL_CORE -D_REENTRANT -DDEBUGGING -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(splintfiles)
+cscopeflags = -Rb # Recursive, build-only.
+
+.PHONY: cscope
+# To query the cscope.out "cscope -dLnsymbol" where n = 0 means uses,
+# 1 = definitions, 2 = callees, 3 = callers, for example
+# "cscope -dL1Perl_mg_set" or run cscope interactively (no arguments).
+cscope.out cscope: $(c) $(h)
+ cscope $(cscopeflags)
+
# Need to unset during recursion to go out of loop.
# The README below ensures that the dependency list is never empty and
# that when MAKEDEPEND is empty $(FIRSTMAKEFILE) doesn't need rebuilding.
# Here comes the CW tools - TO BE FILLED TO BUILD WITH CW -
-MODULE_DESC = "Perl 5.23.8 for NetWare"
+MODULE_DESC = "Perl 5.23.9 for NetWare"
CCTYPE = CodeWarrior
C_COMPILER = mwccnlm -c
CPP_COMPILER = mwccnlm
# versioned installation can be obtained by setting INST_TOP above to a
# path that includes an arbitrary version string.
#
-INST_VER = \5.23.8
+INST_VER = \5.23.9
#
# Comment this out if you DON'T want your perl installation to have
d_fpclassl='undef'
d_fpgetround='undef'
d_fpos64_t='undef'
+d_freelocale='undef'
d_frexpl='undef'
d_fs_data_s='undef'
d_fseeko='undef'
d_nan='undef'
d_ndbm_h_uses_prototypes='undef'
d_nearbyint='undef'
+d_newlocale='undef'
d_nextafter='undef'
d_nexttoward='undef'
d_nice='undef'
d_union_semun='define'
d_unordered='undef'
d_unsetenv='undef'
+d_uselocale='undef'
d_usleep='undef'
d_usleepproto='undef'
d_ustat='undef'
* This symbol contains the ~name expanded version of ARCHLIB, to be used
* in programs that are not prepared to deal with ~ expansion at run-time.
*/
-#define ARCHLIB "c:\\perl\\5.23.8\\lib\\NetWare-x86-multi-thread" /**/
+#define ARCHLIB "c:\\perl\\5.23.9\\lib\\NetWare-x86-multi-thread" /**/
/*#define ARCHLIB_EXP "" /**/
/* ARCHNAME:
* This symbol is the filename expanded version of the BIN symbol, for
* programs that do not want to deal with that at run-time.
*/
-#define BIN "c:\\perl\\5.23.8\\bin\\NetWare-x86-multi-thread" /**/
-#define BIN_EXP "c:\\perl\\5.23.8\\bin\\NetWare-x86-multi-thread" /**/
+#define BIN "c:\\perl\\5.23.9\\bin\\NetWare-x86-multi-thread" /**/
+#define BIN_EXP "c:\\perl\\5.23.9\\bin\\NetWare-x86-multi-thread" /**/
/* BYTEORDER:
* This symbol holds the hexadecimal constant defined in byteorder,
* This symbol contains the ~name expanded version of SITEARCH, to be used
* in programs that are not prepared to deal with ~ expansion at run-time.
*/
-#define SITEARCH "c:\\perl\\site\\5.23.8\\lib\\NetWare-x86-multi-thread" /**/
+#define SITEARCH "c:\\perl\\site\\5.23.9\\lib\\NetWare-x86-multi-thread" /**/
/*#define SITEARCH_EXP "" /**/
/* SITELIB:
* removed. The elements in inc_version_list (inc_version_list.U) can
* be tacked onto this variable to generate a list of directories to search.
*/
-#define SITELIB "c:\\perl\\site\\5.23.8\\lib" /**/
+#define SITELIB "c:\\perl\\site\\5.23.9\\lib" /**/
/*#define SITELIB_EXP "" /**/
#define SITELIB_STEM "" /**/
d_fpos64_t (d_fpos64_t.U):
This symbol will be defined if the C compiler supports fpos64_t.
+d_freelocale (d_newlocale.U):
+ This variable conditionally defines the HAS_FREELOCALE symbol, which
+ indicates to the C program that the freelocale() routine is available
+ to deallocates the resources associated with a locale object.
+
d_frexpl (d_frexpl.U):
This variable conditionally defines the HAS_FREXPL symbol, which
indicates to the C program that the frexpl() routine is available.
is available to return the integral value closest to (according to
the current rounding mode) to x.
+d_newlocale (d_newlocale.U):
+ This variable conditionally defines the HAS_NEWLOCALE symbol, which
+ indicates to the C program that the newlocale() routine is available
+ to return a new locale object or modify an existing locale object.
+
d_nextafter (d_nextafter.U):
This variable conditionally defines HAS_NEXTAFTER if nextafter()
is available to return the next machine representable double from
This variable conditionally defines the HAS_UNSETENV symbol, which
indicates to the C program that the unsetenv () routine is available.
+d_uselocale (d_newlocale.U):
+ This variable conditionally defines the HAS_USELOCALE symbol, which
+ indicates to the C program that the uselocale() routine is available
+ to set the current locale for the calling thread.
+
d_usleep (d_usleep.U):
This variable conditionally defines HAS_USLEEP if usleep() is
available to do high granularity sleeps.
dtrace (usedtrace.U):
This variable holds the location of the dtrace executable.
+dtraceobject (usedtrace.U):
+ Whether we need to build an object file with the dtrace tool.
+
dynamic_ext (Extensions.U):
This variable holds a list of XS extension files we want to
link dynamically into the package. It is used by Makefile.
const-xs.inc
),
],
+ 'CUSTOMIZED' => [
+ # CPAN #118827
+ qw(t/ipcsysv.t
+ lib/IPC/Msg.pm
+ lib/IPC/Semaphore.pm
+ lib/IPC/SharedMem.pm
+ lib/IPC/SysV.pm),
+ ],
},
'JSON::PP' => {
},
'Module::CoreList' => {
- 'DISTRIBUTION' => 'BINGOS/Module-CoreList-5.20160120.tar.gz',
+ 'DISTRIBUTION' => 'BINGOS/Module-CoreList-5.20160121.tar.gz',
'FILES' => q[dist/Module-CoreList],
},
'FILES' => q[cpan/Scalar-List-Utils],
# Waiting to be merged upstream:
# https://github.com/Scalar-List-Utils/Scalar-List-Utils/pull/24
+ # https://rt.cpan.org/Public/Bug/Display.html?id=105415
'CUSTOMIZED' => [
qw( ListUtil.xs
lib/List/Util.pm
lib/List/Util/XS.pm
lib/Scalar/Util.pm
lib/Sub/Util.pm
+ t/product.t
)
],
},
# https://rt.cpan.org/Ticket/Display.html?id=106797
# https://rt.cpan.org/Ticket/Display.html?id=107058
+ # https://rt.cpan.org/Ticket/Display.html?id=111707
'CUSTOMIZED' => [ qw[ Socket.pm Socket.xs ] ],
},
},
'version' => {
- 'DISTRIBUTION' => 'JPEACOCK/version-0.9909.tar.gz',
+ 'DISTRIBUTION' => 'JPEACOCK/version-0.9916.tar.gz',
'FILES' => q[cpan/version vutil.c vutil.h vxs.inc],
'EXCLUDED' => [
qr{^vutil/lib/},
},
'Win32API::File' => {
- 'DISTRIBUTION' => 'CHORNY/Win32API-File-0.1202.tar.gz',
+ 'DISTRIBUTION' => 'CHORNY/Win32API-File-0.1203.tar.gz',
'FILES' => q[cpan/Win32API-File],
'EXCLUDED' => [
qr{^ex/},
],
-
- # Currently all EOL differences. Waiting for a new upstream release:
- # All the files in the GitHub repo have UNIX EOLs already.
- 'CUSTOMIZED' => [
- qw( ExtUtils/Myconst2perl.pm
- Makefile.PL
- buffers.h
- cFile.h
- cFile.pc
- const2perl.h
- t/file.t
- t/tie.t
- typemap
- ),
- ],
},
'XSLoader' => {
'cpan/podlators/t/lib/Test/Podlators.pm', # just a test module
'cpan/podlators/t/lib/Test/RRA.pm', # just a test module
'cpan/podlators/t/lib/Test/RRA/Config.pm', # just a test module
+ 'cpan/version/t/coretests.pm', # just a test module
'dist/Attribute-Handlers/demo/MyClass.pm', # it's just demonstration code
'dist/Exporter/lib/Exporter/Heavy.pm',
'lib/Carp/Heavy.pm',
ansi2knr=''
aphostname='/bin/hostname'
api_revision='5'
-api_subversion='8'
+api_subversion='9'
api_version='23'
-api_versionstring='5.23.8'
+api_versionstring='5.23.9'
ar='ar'
-archlib='/pro/lib/perl5/5.23.8/i686-linux-64int'
-archlibexp='/pro/lib/perl5/5.23.8/i686-linux-64int'
+archlib='/pro/lib/perl5/5.23.9/i686-linux-64int'
+archlibexp='/pro/lib/perl5/5.23.9/i686-linux-64int'
archname64='64int'
archname='i686-linux-64int'
archobjs=''
d_fpclassl='undef'
d_fpgetround='undef'
d_fpos64_t='undef'
+d_freelocale='undef'
d_frexpl='define'
d_fs_data_s='undef'
d_fseeko='define'
d_ndbm='define'
d_ndbm_h_uses_prototypes='define'
d_nearbyint='undef'
+d_newlocale='undef'
d_nextafter='undef'
d_nexttoward='undef'
d_nice='define'
d_union_semun='undef'
d_unordered='undef'
d_unsetenv='define'
+d_uselocale='undef'
d_usleep='define'
d_usleepproto='define'
d_ustat='define'
incpth='/usr/lib/gcc/i586-suse-linux/4.8/include /usr/local/include /usr/lib/gcc/i586-suse-linux/4.8/include-fixed /usr/lib/gcc/i586-suse-linux/4.8/../../../../i586-suse-linux/include /usr/include'
inews=''
initialinstalllocation='/pro/bin'
-installarchlib='/pro/lib/perl5/5.23.8/i686-linux-64int'
+installarchlib='/pro/lib/perl5/5.23.9/i686-linux-64int'
installbin='/pro/bin'
installhtml1dir=''
installhtml3dir=''
installman3dir='/pro/local/man/man3'
installprefix='/pro'
installprefixexp='/pro'
-installprivlib='/pro/lib/perl5/5.23.8'
+installprivlib='/pro/lib/perl5/5.23.9'
installscript='/pro/bin'
-installsitearch='/pro/lib/perl5/site_perl/5.23.8/i686-linux-64int'
+installsitearch='/pro/lib/perl5/site_perl/5.23.9/i686-linux-64int'
installsitebin='/pro/bin'
installsitehtml1dir=''
installsitehtml3dir=''
-installsitelib='/pro/lib/perl5/site_perl/5.23.8'
+installsitelib='/pro/lib/perl5/site_perl/5.23.9'
installsiteman1dir='/pro/local/man/man1'
installsiteman3dir='/pro/local/man/man3'
installsitescript='/pro/bin'
perl_static_inline='static __inline__'
perladmin='hmbrand@cpan.org'
perllibs='-lnsl -ldl -lm -lcrypt -lutil -lc'
-perlpath='/pro/bin/perl5.23.8'
+perlpath='/pro/bin/perl5.23.9'
pg='pg'
phostname='hostname'
pidtype='pid_t'
pr=''
prefix='/pro'
prefixexp='/pro'
-privlib='/pro/lib/perl5/5.23.8'
-privlibexp='/pro/lib/perl5/5.23.8'
+privlib='/pro/lib/perl5/5.23.9'
+privlibexp='/pro/lib/perl5/5.23.9'
procselfexe='"/proc/self/exe"'
prototype='define'
ptrsize='4'
sig_num_init='0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 6, 17, 29, 31, 0'
sig_size='69'
signal_t='void'
-sitearch='/pro/lib/perl5/site_perl/5.23.8/i686-linux-64int'
-sitearchexp='/pro/lib/perl5/site_perl/5.23.8/i686-linux-64int'
+sitearch='/pro/lib/perl5/site_perl/5.23.9/i686-linux-64int'
+sitearchexp='/pro/lib/perl5/site_perl/5.23.9/i686-linux-64int'
sitebin='/pro/bin'
sitebinexp='/pro/bin'
sitehtml1dir=''
sitehtml1direxp=''
sitehtml3dir=''
sitehtml3direxp=''
-sitelib='/pro/lib/perl5/site_perl/5.23.8'
+sitelib='/pro/lib/perl5/site_perl/5.23.9'
sitelib_stem='/pro/lib/perl5/site_perl'
-sitelibexp='/pro/lib/perl5/site_perl/5.23.8'
+sitelibexp='/pro/lib/perl5/site_perl/5.23.9'
siteman1dir='/pro/local/man/man1'
siteman1direxp='/pro/local/man/man1'
siteman3dir='/pro/local/man/man3'
ssizetype='ssize_t'
st_ino_sign='1'
st_ino_size='8'
-startperl='#!/pro/bin/perl5.23.8'
+startperl='#!/pro/bin/perl5.23.9'
startsh='#!/bin/sh'
static_ext=' '
stdchar='char'
strerror_r_proto='0'
strings='/usr/include/string.h'
submit=''
-subversion='8'
+subversion='9'
sysman='/usr/share/man/man1'
sysroot=''
tail=''
vendorprefixexp=''
vendorscript=''
vendorscriptexp=''
-version='5.23.8'
-version_patchlevel_string='version 23 subversion 8'
+version='5.23.9'
+version_patchlevel_string='version 23 subversion 9'
versiononly='define'
vi=''
xlibpth='/usr/lib/386 /lib/386'
zip='zip'
PERL_REVISION=5
PERL_VERSION=23
-PERL_SUBVERSION=8
+PERL_SUBVERSION=9
PERL_API_REVISION=5
PERL_API_VERSION=23
-PERL_API_SUBVERSION=8
+PERL_API_SUBVERSION=9
PERL_PATCHLEVEL=''
PERL_CONFIG_SH=true
: Variables propagated from previous config.sh file.
* This symbol contains the ~name expanded version of ARCHLIB, to be used
* in programs that are not prepared to deal with ~ expansion at run-time.
*/
-#define ARCHLIB "/pro/lib/perl5/5.23.8/i686-linux-64int-ld" /**/
-#define ARCHLIB_EXP "/pro/lib/perl5/5.23.8/i686-linux-64int-ld" /**/
+#define ARCHLIB "/pro/lib/perl5/5.23.9/i686-linux-64int-ld" /**/
+#define ARCHLIB_EXP "/pro/lib/perl5/5.23.9/i686-linux-64int-ld" /**/
/* ARCHNAME:
* This symbol holds a string representing the architecture name.
* This symbol contains the ~name expanded version of PRIVLIB, to be used
* in programs that are not prepared to deal with ~ expansion at run-time.
*/
-#define PRIVLIB "/pro/lib/perl5/5.23.8" /**/
-#define PRIVLIB_EXP "/pro/lib/perl5/5.23.8" /**/
+#define PRIVLIB "/pro/lib/perl5/5.23.9" /**/
+#define PRIVLIB_EXP "/pro/lib/perl5/5.23.9" /**/
/* PTRSIZE:
* This symbol contains the size of a pointer, so that the C preprocessor
* This symbol contains the ~name expanded version of SITEARCH, to be used
* in programs that are not prepared to deal with ~ expansion at run-time.
*/
-#define SITEARCH "/pro/lib/perl5/site_perl/5.23.8/i686-linux-64int-ld" /**/
-#define SITEARCH_EXP "/pro/lib/perl5/site_perl/5.23.8/i686-linux-64int-ld" /**/
+#define SITEARCH "/pro/lib/perl5/site_perl/5.23.9/i686-linux-64int-ld" /**/
+#define SITEARCH_EXP "/pro/lib/perl5/site_perl/5.23.9/i686-linux-64int-ld" /**/
/* SITELIB:
* This symbol contains the name of the private library for this package.
* removed. The elements in inc_version_list (inc_version_list.U) can
* be tacked onto this variable to generate a list of directories to search.
*/
-#define SITELIB "/pro/lib/perl5/site_perl/5.23.8" /**/
-#define SITELIB_EXP "/pro/lib/perl5/site_perl/5.23.8" /**/
+#define SITELIB "/pro/lib/perl5/site_perl/5.23.9" /**/
+#define SITELIB_EXP "/pro/lib/perl5/site_perl/5.23.9" /**/
#define SITELIB_STEM "/pro/lib/perl5/site_perl" /**/
/* SSize_t:
* script to make sure (one hopes) that it runs with perl and not
* some shell.
*/
-#define STARTPERL "#!/pro/bin/perl5.23.8" /**/
+#define STARTPERL "#!/pro/bin/perl5.23.9" /**/
/* HAS_STDIO_STREAM_ARRAY:
* This symbol, if defined, tells that there is an array
=head1 EPIGRAPHS
+=head2 v5.23.8 - Patrick Rothfuss, "The Wise Man's Fear (The Kingkiller's Chronicle: Day Two)"
+
+Denna, on the other hand, had never been trained. She knew nothing
+of shortcuts. You'd think she'd be forced to wander the city, lost and
+helpless, trapped in a twisting maze of mortared stone.
+
+But instead, she simply walked throught the walls. She didn't know
+any better. Nobody had ever told her she couldn't. Because of this,
+she moved through the city like some faerie creature. She walked roads
+no one else could see, and it made her music wild and strange and
+free.
+
=head2 v5.23.7
L<Announced on 2016-01-20 by Stevan|http://www.nntp.perl.org/group/perl.perl5.porters/2016/01/msg233856.html>
=head1 SYNOPSIS
- expand-macro.pl [options] [ < macro-name | macro-expression | - > [headers] ]
+ expand-macro.pl [options]
+ [ < macro-name | macro-expression | - > [headers] ]
options:
-f use 'indent' to format output
-F <tool> use <tool> to format output (instead of -f)
- -e erase try.[ic] instead of failing when they're present (errdetect)
+ -e erase try.[ic] instead of failing when they're present
+ (errdetect)
-k keep them after generating (for handy inspection)
-v verbose
-I <indent-opts> passed into indent
XXX Generate this with:
- perl Porting/acknowledgements.pl v5.23.8..HEAD
+ perl Porting/acknowledgements.pl v5.23.9..HEAD
=head1 Reporting Bugs
file-sharing service.
Porters have access to the "dromedary" server (users.perl5.git.perl.org),
-but as of Dec. 2015 the F<public_html> directories are not working.
+which has a F<public_html> directory to share files with.
+(L<http://users.perl5.git.perl.org/~username/perl-5.xx.y.tar.gz>)
If you use Dropbox, you can append "raw=1" as a parameter to their usual
sharing link to allow direct download (albeit with redirects).
=head4 Bump version in Module::CoreList F<Changes>
Also edit Module::CoreList's new version number in its F<Changes> file.
+This file is F<dist/Module-CoreList/Changes>.
=head4 Add Module::CoreList version bump to perldelta
15 megabyte HTTP upload successfully completes across your slow, twitchy
cable modem.
-B<Note:> as of Dec 2015, dromedary F<public_html> is not working so
-ignore the following paragraph until it is fixed.
-
You can make use of your home directory on dromedary for
this purpose: F<http://users.perl5.git.perl.org/~USERNAME> maps to
F</home/USERNAME/public_html>, where F<USERNAME> is your login account
2015-11-20 5.23.5 ✓ Abigail
2015-12-20 5.23.6 ✓ David Golden
2016-01-20 5.23.7 ✓ Stevan Little
- 2016-02-20 5.23.8 Sawyer X
+ 2016-02-20 5.23.8 ✓ Sawyer X
2016-03-20 5.23.9 Abigail
(RC0 for 5.24.0 will be released once we think that all the blockers have been
2016-07-20 5.25.2 Steve Hay
2016-08-20 5.25.3 BinGOs
2016-09-20 5.25.4 Stevan Little
- 2016-10-20 5.25.5 ?
+ 2016-10-20 5.25.5 Sawyer X
2016-11-20 5.25.6 ?
2016-12-20 5.25.7 ?
On these systems, it might be the default compilation mode, and there
is currently no guarantee that passing no use64bitall option to the
Configure process will build a 32bit perl. Implementing -Duse32bit*
-options would be nice for perl 5.23.8.
+options would be nice for perl 5.23.9.
=head2 Profile Perl - am I hot or not?
ever creep back to libperl.a.
nm libperl.a | ./miniperl -alne '$o = $F[0] if /:$/;
- print "$o $F[1]" if $F[0] eq "U" && $F[1] =~ /^(?:strn?c(?:at|py)|v?sprintf|gets)$/'
+ print "$o $F[1]" if $F[0] eq "U" && $F[1]
+ =~ /^(?:strn?c(?:at|py)|v?sprintf|gets)$/'
Note, of course, that this will only tell whether B<your> platform
is using those naughty interfaces.
=head1 Big projects
Tasks that will get your name mentioned in the description of the "Highlights
-of 5.23.8"
+of 5.23.9"
=head2 make ithreads more robust
prompts you,
Any additional ld flags (NOT including libraries)? [none] -s
- Any special flags to pass to g++ to create a dynamically loaded library?
+ Any special flags to pass to g++ to create a dynamically loaded
+ library?
[none] -s
Any special flags to pass to gcc to use dynamic linking? [none] -s
Win9x does not correctly report C<EOF> with a non-blocking read on a
closed pipe. You will see the following messages:
- But it also returns -1 to signal EOF, so be careful!
- WARNING: you can't distinguish between EOF and no data!
+ But it also returns -1 to signal EOF, so be careful!
+ WARNING: you can't distinguish between EOF and no data!
- *** WHOA THERE!!! ***
- The recommended value for $d_eofnblk on this machine was "define"!
- Keep the recommended value? [y]
+ *** WHOA THERE!!! ***
+ The recommended value for $d_eofnblk on this machine was
+ "define"!
+ Keep the recommended value? [y]
At least for consistency with WinNT, you should keep the recommended
value.
may result on a DLL baseaddress conflict. The internal cygwin error
looks like like the following:
- 0 [main] perl 8916 child_info_fork::abort: data segment start: parent
- (0xC1A000) != child(0xA6A000)
+ 0 [main] perl 8916 child_info_fork::abort: data segment start:
+ parent (0xC1A000) != child(0xA6A000)
or:
- 183 [main] perl 3588 C:\cygwin\bin\perl.exe: *** fatal error - unable to remap
- C:\cygwin\bin\cygsvn_subr-1-0.dll to same address as parent(0x6FB30000) != 0x6FE60000
- 46 [main] perl 3488 fork: child 3588 - died waiting for dll loading, errno11
+ 183 [main] perl 3588 C:\cygwin\bin\perl.exe: *** fatal error -
+ unable to remap C:\cygwin\bin\cygsvn_subr-1-0.dll to same address
+ as parent(0x6FB30000) != 0x6FE60000 46 [main] perl 3488 fork: child
+ 3588 - died waiting for dll loading, errno11
See L<http://cygwin.com/faq/faq-nochunks.html#faq.using.fixing-fork-failures>
It helps if not too many DLLs are loaded in memory so the available address space is larger,
ext/Compress-Raw-Zlib/README ext/Compress-Zlib/Changes
ext/DB_File/Changes ext/Encode/Changes ext/Sys-Syslog/Changes
ext/Win32API-File/Changes
- lib/ExtUtils/CBuilder/Changes lib/ExtUtils/Changes lib/ExtUtils/NOTES
- lib/ExtUtils/PATCHING lib/ExtUtils/README
+ lib/ExtUtils/CBuilder/Changes lib/ExtUtils/Changes
+ lib/ExtUtils/NOTES lib/ExtUtils/PATCHING lib/ExtUtils/README
lib/Net/Ping/Changes lib/Test/Harness/Changes
- lib/Term/ANSIColor/ChangeLog lib/Term/ANSIColor/README README.symbian
- symbian/TODO
+ lib/Term/ANSIColor/ChangeLog lib/Term/ANSIColor/README
+ README.symbian symbian/TODO
=item Build, Configure, Make, Install
=item Tests
t/io/fs.t - no file mode checks if not ntsec
- skip rename() check when not check_case:relaxed
+ skip rename() check when not
+ check_case:relaxed
t/io/tell.t - binmode
t/lib/cygwin.t - builtin cygwin function tests
t/op/groups.t - basegroup has ID = 0
t/op/magic.t - $^X/symlink WORKAROUND, s/.exe//
t/op/stat.t - no /dev, skip Win32 ftCreationTime quirk
- (cache manager sometimes preserves ctime of file
- previously created and deleted), no -u (setuid)
+ (cache manager sometimes preserves ctime of
+ file previously created and deleted), no -u
+ (setuid)
t/op/taint.t - can't use empty path under Cygwin Perl
t/op/time.t - no tzset()
EXTERN.h - __declspec(dllimport)
XSUB.h - __declspec(dllexport)
- cygwin/cygwin.c - os_extras (getcwd, spawn, and several Cygwin:: functions)
+ cygwin/cygwin.c - os_extras (getcwd, spawn, and several
+ Cygwin:: functions)
perl.c - os_extras, -i.bak
perl.h - binmode
doio.c - win9x can not rename a file when it is open
- pp_sys.c - do not define h_errno, init _pwent_struct.pw_comment
+ pp_sys.c - do not define h_errno, init
+ _pwent_struct.pw_comment
util.c - use setenv
util.h - PERL_FILE_IS_ABSOLUTE macro
- pp.c - Comment about Posix vs IEEE math under Cygwin
+ pp.c - Comment about Posix vs IEEE math under
+ Cygwin
perlio.c - CR/LF mode
perliol.c - Comment about EXTCONST under Cygwin
- Can't install via CPAN shell under Cygwin
ext/Compress-Raw-Zlib/zlib-src/zutil.h
- Cygwin is Unix-like and has vsnprintf
- ext/Errno/Errno_pm.PL - Special handling for Win32 Perl under Cygwin
+ ext/Errno/Errno_pm.PL - Special handling for Win32 Perl under
+ Cygwin
ext/POSIX/POSIX.xs - tzname defined externally
ext/SDBM_File/sdbm/pair.c
- - EXTCONST needs to be redefined from EXTERN.h
+ - EXTCONST needs to be redefined from
+ EXTERN.h
ext/SDBM_File/sdbm/sdbm.c
- binary open
ext/Sys/Syslog/Syslog.xs
ext/Win32/Makefile.PL - Use various libraries under Cygwin
ext/Win32/Win32.xs - Child dir and child env under Cygwin
ext/Win32API-File/File.xs
- - _open_osfhandle not implemented under Cygwin
+ - _open_osfhandle not implemented under
+ Cygwin
ext/Win32CORE/Win32CORE.c
- __declspec(dllexport)
=item Perl Modules/Scripts
- ext/B/t/OptreeCheck.pm - Comment about stderr/stdout order under Cygwin
+ ext/B/t/OptreeCheck.pm - Comment about stderr/stdout order under
+ Cygwin
ext/Digest-SHA/bin/shasum
- Use binary mode under Cygwin
ext/Sys/Syslog/win32/Win32.pm
ext/Time-HiRes/HiRes.pm
- Comment about various timers not available
ext/Win32API-File/File.pm
- - _open_osfhandle not implemented under Cygwin
+ - _open_osfhandle not implemented under
+ Cygwin
ext/Win32CORE/Win32CORE.pm
- History of Win32CORE under Cygwin
lib/Cwd.pm - hook to internal Cwd::cwd
lib/ExtUtils/MM_Cygwin.pm
- canonpath, cflags, manifypods, perl_archive
lib/File/Fetch.pm - Comment about quotes using a Cygwin example
- lib/File/Find.pm - on remote drives stat() always sets st_nlink to 1
+ lib/File/Find.pm - on remote drives stat() always sets
+ st_nlink to 1
lib/File/Spec/Cygwin.pm - case_tolerant
lib/File/Spec/Unix.pm - preserve //unc
lib/File/Spec/Win32.pm - References a message on cygwin.com
Make perl executable and create a symlink for libperl:
chmod a+x /boot/common/bin/perl
- cd /boot/common/lib; ln -s perl5/5.23.8/BePC-haiku/CORE/libperl.so .
+ cd /boot/common/lib; ln -s perl5/5.23.9/BePC-haiku/CORE/libperl.so .
-Replace C<5.23.8> with your respective version of Perl.
+Replace C<5.23.9> with your respective version of Perl.
=head1 KNOWN PROBLEMS
# swlist -s /cdrom perl
# perl D.5.8.8.B 5.8.8 Perl Programming Language
- perl.Perl5-32 D.5.8.8.B 32-bit 5.8.8 Perl Programming Language with Extensions
- perl.Perl5-64 D.5.8.8.B 64-bit 5.8.8 Perl Programming Language with Extensions
+ perl.Perl5-32 D.5.8.8.B 32-bit 5.8.8 Perl Programming Language
+ with Extensions
+ perl.Perl5-64 D.5.8.8.B 64-bit 5.8.8 Perl Programming Language
+ with Extensions
To see what is installed on your system:
# swlist -R perl
# perl E.5.8.8.J Perl Programming Language
- # perl.Perl5-32 E.5.8.8.J 32-bit Perl Programming Language with Extensions
+ # perl.Perl5-32 E.5.8.8.J 32-bit Perl Programming Language
+ with Extensions
perl.Perl5-32.PERL-MAN E.5.8.8.J 32-bit Perl Man Pages for IA
perl.Perl5-32.PERL-RUN E.5.8.8.J 32-bit Perl Binaries for IA
- # perl.Perl5-64 E.5.8.8.J 64-bit Perl Programming Language with Extensions
+ # perl.Perl5-64 E.5.8.8.J 64-bit Perl Programming Language
+ with Extensions
perl.Perl5-64.PERL-MAN E.5.8.8.J 64-bit Perl Man Pages for IA
perl.Perl5-64.PERL-RUN E.5.8.8.J 64-bit Perl Binaries for IA
The following compilation warnings may happen in HP-UX releases
earlier than 11.31 but are harmless:
- cc: "/usr/include/sys/socket.h", line 535: warning 562: Redeclaration of "sendfile" with a different storage class specifier: "sendfile" will have internal linkage.
- cc: "/usr/include/sys/socket.h", line 536: warning 562: Redeclaration of "sendpath" with a different storage class specifier: "sendpath" will have internal linkage.
+ cc: "/usr/include/sys/socket.h", line 535: warning 562:
+ Redeclaration of "sendfile" with a different storage class
+ specifier: "sendfile" will have internal linkage.
+ cc: "/usr/include/sys/socket.h", line 536: warning 562:
+ Redeclaration of "sendpath" with a different storage class
+ specifier: "sendpath" will have internal linkage.
They seem to be caused by broken system header files, and also other
open source projects are seeing them. The following HP-UX patches
Here are the statistics for Perl 5.005_62 on my system:
Failed Test Status Wstat Total Fail Failed List of failed
- -------------------------------------------------------------------------
+ -----------------------------------------------------------------------
lib/anydbm.t 12 1 8.33% 12
pragma/warnings 333 1 0.30% 215
8 tests and 24 subtests skipped.
- Failed 2/229 test scripts, 99.13% okay. 2/10850 subtests failed, 99.98% okay.
+ Failed 2/229 test scripts, 99.13% okay. 2/10850 subtests failed,
+ 99.98% okay.
There are quite a few systems out there that do worse!
During compilation you will see this warning from toke.c:
uopt: Warning: Perl_yylex: this procedure not optimized because it
- exceeds size threshold; to optimize this procedure, use -Olimit option
- with value >= 4252.
+ exceeds size threshold; to optimize this procedure, use -Olimit
+ option with value >= 4252.
Ignore the warning.
the following failures are known.
Failed Test Stat Wstat Total Fail Failed List of Failed
- --------------------------------------------------------------------------
+ -----------------------------------------------------------------------
../ext/List/Util/t/shuffle.t 0 139 ?? ?? % ??
../lib/Math/Trig.t 255 65280 29 12 41.38% 24-29
../lib/sort.t 0 138 119 72 60.50% 48-119
56 tests and 474 subtests skipped.
- Failed 3/811 test scripts, 99.63% okay. 78/75813 subtests failed, 99.90% okay.
+ Failed 3/811 test scripts, 99.63% okay. 78/75813 subtests failed,
+ 99.90% okay.
They are suspected to be compiler errors (at least the shuffle.t
failure is known from some IRIX 6 setups) and math library errors
This document briefly describes Perl under Mac OS X.
- curl -O http://www.cpan.org/src/perl-5.23.8.tar.gz
- tar -xzf perl-5.23.8.tar.gz
- cd perl-5.23.8
+ curl -O http://www.cpan.org/src/perl-5.23.9.tar.gz
+ tar -xzf perl-5.23.9.tar.gz
+ cd perl-5.23.9
./Configure -des -Dprefix=/usr/local/
make
make test
=head1 DESCRIPTION
-The latest Perl release (5.23.8 as of this writing) builds without changes
+The latest Perl release (5.23.9 as of this writing) builds without changes
under all versions of Mac OS X from 10.3 "Panther" onwards.
In order to build your own version of Perl you will need 'make',
First, export the path to the SDK into the build environment:
- export SDK=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk
+ export SDK=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk
Please make sure the SDK version (i.e. the numbers right before '.sdk')
matches your system's (in this case, Mac OS X 10.8 "Mountain Lion"), as it is
In addition to the compiler flags used to select the SDK, also add the flags
for creating a universal binary:
- ./Configure -Accflags="-arch i686 -arch ppc -nostdinc -B$SDK/usr/include/gcc \
- -B$SDK/usr/lib/gcc -isystem$SDK/usr/include \
- -F$SDK/System/Library/Frameworks" \
- -Aldflags="-arch i686 -arch ppc -Wl,-syslibroot,$SDK" \
- -de
+ ./Configure -Accflags="-arch i686 -arch ppc -nostdinc \
+ -B$SDK/usr/include/gcc \
+ -B$SDK/usr/lib/gcc -isystem$SDK/usr/include \
+ -F$SDK/System/Library/Frameworks" \
+ -Aldflags="-arch i686 -arch ppc -Wl,-syslibroot,$SDK" \
+ -de
Keep in mind that these compiler and linker settings will also be used when
building CPAN modules. For XS modules to be compiled as a universal binary, any
Example:
- perl -Ic:/perl/5.6.1/lib/NetWare-x86-multi-thread -Ic:\perl\5.6.1\lib MakeFile.pl
+ perl -Ic:/perl/5.6.1/lib/NetWare-x86-multi-thread \
+ -Ic:\perl\5.6.1\lib MakeFile.pl
or
- perl -Ic:/perl/5.8.0/lib/NetWare-x86-multi-thread -Ic:\perl\5.8.0\lib MakeFile.pl
+ perl -Ic:/perl/5.8.0/lib/NetWare-x86-multi-thread \
+ -Ic:\perl\5.8.0\lib MakeFile.pl
=item *
Example: You can execute the following on the command prompt.
- perl -Ic:/perl/5.6.1/lib/NetWare-x86-multi-thread -Ic:\perl\5.6.1\lib MakeFile.pl
+ perl -Ic:/perl/5.6.1/lib/NetWare-x86-multi-thread \
+ -Ic:\perl\5.6.1\lib MakeFile.pl
INSTALLSITELIB=i:\perl\lib
or
- perl -Ic:/perl/5.8.0/lib/NetWare-x86-multi-thread -Ic:\perl\5.8.0\lib MakeFile.pl
+ perl -Ic:/perl/5.8.0/lib/NetWare-x86-multi-thread \
+ -Ic:\perl\5.8.0\lib MakeFile.pl
INSTALLSITELIB=i:\perl\lib
=item *
Contents (This may be a little bit obsolete)
- perlos2 - Perl under OS/2, DOS, Win0.3*, Win0.95 and WinNT.
+ perlos2 - Perl under OS/2, DOS, Win0.3*, Win0.95 and WinNT.
NAME
SYNOPSIS
=item Additional Perl modules
- unzip perl_ste.zip -d f:/perllib/lib/site_perl/5.23.8/
+ unzip perl_ste.zip -d f:/perllib/lib/site_perl/5.23.9/
Same remark as above applies. Additionally, if this directory is not
one of directories on @INC (and @INC is influenced by C<PERLLIB_PREFIX>), you
The report with F<io/pipe.t> failing may look like this:
- Failed Test Status Wstat Total Fail Failed List of failed
- ------------------------------------------------------------
- io/pipe.t 12 1 8.33% 9
- 7 tests skipped, plus 56 subtests skipped.
- Failed 1/195 test scripts, 99.49% okay. 1/6542 subtests failed, 99.98% okay.
+ Failed Test Status Wstat Total Fail Failed List of failed
+ ------------------------------------------------------------
+ io/pipe.t 12 1 8.33% 9
+ 7 tests skipped, plus 56 subtests skipped.
+ Failed 1/195 test scripts, 99.49% okay. 1/6542 subtests failed,
+ 99.98% okay.
The reasons for most important skipped tests are:
Install the bundle C<Bundle::OS2_default>
- perl5.8.2 -MCPAN -e "install Bundle::OS2_default" < nul |& tee 00cpan_i_1
+ perl5.8.2 -MCPAN -e "install Bundle::OS2_default" < nul |& tee 00cpan_i_1
This may take a couple of hours on 1GHz processor (when run the first time).
And this should not be necessarily a smooth procedure. Some modules may not
specify required dependencies, so one may need to repeat this procedure several
times until the results stabilize.
- perl5.8.2 -MCPAN -e "install Bundle::OS2_default" < nul |& tee 00cpan_i_2
- perl5.8.2 -MCPAN -e "install Bundle::OS2_default" < nul |& tee 00cpan_i_3
+ perl5.8.2 -MCPAN -e "install Bundle::OS2_default" < nul |& tee 00cpan_i_2
+ perl5.8.2 -MCPAN -e "install Bundle::OS2_default" < nul |& tee 00cpan_i_3
Even after they stabilize, some tests may fail.
Here is the sample C file:
- #define INCL_DOS
- #define INCL_NOPM
- /* These are needed for compile if os2.h includes os2tk.h, not os2emx.h */
- #define INCL_DOSPROCESS
- #include <os2.h>
-
- #include "EXTERN.h"
- #define PERL_IN_MINIPERLMAIN_C
- #include "perl.h"
-
- static char *me;
- HMODULE handle;
-
- static void
- die_with(char *msg1, char *msg2, char *msg3, char *msg4)
- {
- ULONG c;
- char *s = " error: ";
-
- DosWrite(2, me, strlen(me), &c);
- DosWrite(2, s, strlen(s), &c);
- DosWrite(2, msg1, strlen(msg1), &c);
- DosWrite(2, msg2, strlen(msg2), &c);
- DosWrite(2, msg3, strlen(msg3), &c);
- DosWrite(2, msg4, strlen(msg4), &c);
- DosWrite(2, "\r\n", 2, &c);
- exit(255);
- }
-
- typedef ULONG (*fill_extLibpath_t)(int type, char *pre, char *post, int replace, char *msg);
- typedef int (*main_t)(int type, char *argv[], char *env[]);
- typedef int (*handler_t)(void* data, int which);
-
- #ifndef PERL_DLL_BASENAME
- # define PERL_DLL_BASENAME "perl"
- #endif
-
- static HMODULE
- load_perl_dll(char *basename)
- {
- char buf[300], fail[260];
- STRLEN l, dirl;
- fill_extLibpath_t f;
- ULONG rc_fullname;
- HMODULE handle, handle1;
-
- if (_execname(buf, sizeof(buf) - 13) != 0)
- die_with("Can't find full path: ", strerror(errno), "", "");
- /* XXXX Fill 'me' with new value */
- l = strlen(buf);
- while (l && buf[l-1] != '/' && buf[l-1] != '\\')
- l--;
- dirl = l - 1;
- strcpy(buf + l, basename);
- l += strlen(basename);
- strcpy(buf + l, ".dll");
- if ( (rc_fullname = DosLoadModule(fail, sizeof fail, buf, &handle)) != 0
- && DosLoadModule(fail, sizeof fail, basename, &handle) != 0 )
- die_with("Can't load DLL ", buf, "", "");
- if (rc_fullname)
- return handle; /* was loaded with short name; all is fine */
- if (DosQueryProcAddr(handle, 0, "fill_extLibpath", (PFN*)&f))
- die_with(buf, ": DLL exports no symbol ", "fill_extLibpath", "");
- buf[dirl] = 0;
- if (f(0 /*BEGINLIBPATH*/, buf /* prepend */, NULL /* append */,
- 0 /* keep old value */, me))
- die_with(me, ": prepending BEGINLIBPATH", "", "");
- if (DosLoadModule(fail, sizeof fail, basename, &handle1) != 0)
- die_with(me, ": finding perl DLL again via BEGINLIBPATH", "", "");
- buf[dirl] = '\\';
- if (handle1 != handle) {
- if (DosQueryModuleName(handle1, sizeof(fail), fail))
- strcpy(fail, "???");
- die_with(buf, ":\n\tperl DLL via BEGINLIBPATH is different: \n\t",
- fail,
- "\n\tYou may need to manipulate global BEGINLIBPATH and LIBPATHSTRICT"
- "\n\tso that the other copy is loaded via BEGINLIBPATH.");
- }
- return handle;
- }
-
- int
- main(int argc, char **argv, char **env)
- {
- main_t f;
- handler_t h;
-
- me = argv[0];
- /**/
- handle = load_perl_dll(PERL_DLL_BASENAME);
-
- if (DosQueryProcAddr(handle, 0, "Perl_OS2_handler_install", (PFN*)&h))
- die_with(PERL_DLL_BASENAME, ": DLL exports no symbol ", "Perl_OS2_handler_install", "");
- if ( !h((void *)"~installprefix", Perlos2_handler_perllib_from)
- || !h((void *)"~dll", Perlos2_handler_perllib_to)
- || !h((void *)"~dll/sh/ksh.exe", Perlos2_handler_perl_sh) )
- die_with(PERL_DLL_BASENAME, ": Can't install @INC manglers", "", "");
-
- if (DosQueryProcAddr(handle, 0, "dll_perlmain", (PFN*)&f))
- die_with(PERL_DLL_BASENAME, ": DLL exports no symbol ", "dll_perlmain", "");
- return f(argc, argv, env);
- }
-
+ #define INCL_DOS
+ #define INCL_NOPM
+ /* These are needed for compile if os2.h includes os2tk.h, not
+ * os2emx.h */
+ #define INCL_DOSPROCESS
+ #include <os2.h>
+
+ #include "EXTERN.h"
+ #define PERL_IN_MINIPERLMAIN_C
+ #include "perl.h"
+
+ static char *me;
+ HMODULE handle;
+
+ static void
+ die_with(char *msg1, char *msg2, char *msg3, char *msg4)
+ {
+ ULONG c;
+ char *s = " error: ";
+
+ DosWrite(2, me, strlen(me), &c);
+ DosWrite(2, s, strlen(s), &c);
+ DosWrite(2, msg1, strlen(msg1), &c);
+ DosWrite(2, msg2, strlen(msg2), &c);
+ DosWrite(2, msg3, strlen(msg3), &c);
+ DosWrite(2, msg4, strlen(msg4), &c);
+ DosWrite(2, "\r\n", 2, &c);
+ exit(255);
+ }
+
+ typedef ULONG (*fill_extLibpath_t)(int type,
+ char *pre,
+ char *post,
+ int replace,
+ char *msg);
+ typedef int (*main_t)(int type, char *argv[], char *env[]);
+ typedef int (*handler_t)(void* data, int which);
+
+ #ifndef PERL_DLL_BASENAME
+ # define PERL_DLL_BASENAME "perl"
+ #endif
+
+ static HMODULE
+ load_perl_dll(char *basename)
+ {
+ char buf[300], fail[260];
+ STRLEN l, dirl;
+ fill_extLibpath_t f;
+ ULONG rc_fullname;
+ HMODULE handle, handle1;
+
+ if (_execname(buf, sizeof(buf) - 13) != 0)
+ die_with("Can't find full path: ", strerror(errno), "", "");
+ /* XXXX Fill 'me' with new value */
+ l = strlen(buf);
+ while (l && buf[l-1] != '/' && buf[l-1] != '\\')
+ l--;
+ dirl = l - 1;
+ strcpy(buf + l, basename);
+ l += strlen(basename);
+ strcpy(buf + l, ".dll");
+ if ( (rc_fullname = DosLoadModule(fail, sizeof fail, buf, &handle))
+ != 0
+ && DosLoadModule(fail, sizeof fail, basename, &handle) != 0 )
+ die_with("Can't load DLL ", buf, "", "");
+ if (rc_fullname)
+ return handle; /* was loaded with short name; all is fine */
+ if (DosQueryProcAddr(handle, 0, "fill_extLibpath", (PFN*)&f))
+ die_with(buf,
+ ": DLL exports no symbol ",
+ "fill_extLibpath",
+ "");
+ buf[dirl] = 0;
+ if (f(0 /*BEGINLIBPATH*/, buf /* prepend */, NULL /* append */,
+ 0 /* keep old value */, me))
+ die_with(me, ": prepending BEGINLIBPATH", "", "");
+ if (DosLoadModule(fail, sizeof fail, basename, &handle1) != 0)
+ die_with(me,
+ ": finding perl DLL again via BEGINLIBPATH",
+ "",
+ "");
+ buf[dirl] = '\\';
+ if (handle1 != handle) {
+ if (DosQueryModuleName(handle1, sizeof(fail), fail))
+ strcpy(fail, "???");
+ die_with(buf,
+ ":\n\tperl DLL via BEGINLIBPATH is different: \n\t",
+ fail,
+ "\n\tYou may need to manipulate global BEGINLIBPATH"
+ " and LIBPATHSTRICT"
+ "\n\tso that the other copy is loaded via"
+ BEGINLIBPATH.");
+ }
+ return handle;
+ }
+
+ int
+ main(int argc, char **argv, char **env)
+ {
+ main_t f;
+ handler_t h;
+
+ me = argv[0];
+ /**/
+ handle = load_perl_dll(PERL_DLL_BASENAME);
+
+ if (DosQueryProcAddr(handle,
+ 0,
+ "Perl_OS2_handler_install",
+ (PFN*)&h))
+ die_with(PERL_DLL_BASENAME,
+ ": DLL exports no symbol ",
+ "Perl_OS2_handler_install",
+ "");
+ if ( !h((void *)"~installprefix", Perlos2_handler_perllib_from)
+ || !h((void *)"~dll", Perlos2_handler_perllib_to)
+ || !h((void *)"~dll/sh/ksh.exe", Perlos2_handler_perl_sh) )
+ die_with(PERL_DLL_BASENAME,
+ ": Can't install @INC manglers",
+ "",
+ "");
+ if (DosQueryProcAddr(handle, 0, "dll_perlmain", (PFN*)&f))
+ die_with(PERL_DLL_BASENAME,
+ ": DLL exports no symbol ",
+ "dll_perlmain",
+ "");
+ return f(argc, argv, env);
+ }
=head1 Build FAQ
- and also C<PMWIN_entries> - in F<os2ish.h>). These ordinals can be
accessed via the APIs:
- CallORD(), DeclFuncByORD(), DeclVoidFuncByORD(),
- DeclOSFuncByORD(), DeclWinFuncByORD(), AssignFuncPByORD(),
- DeclWinFuncByORD_CACHE(), DeclWinFuncByORD_CACHE_survive(),
- DeclWinFuncByORD_CACHE_resetError_survive(),
- DeclWinFunc_CACHE(), DeclWinFunc_CACHE_resetError(),
- DeclWinFunc_CACHE_survive(), DeclWinFunc_CACHE_resetError_survive()
+ CallORD(), DeclFuncByORD(), DeclVoidFuncByORD(),
+ DeclOSFuncByORD(), DeclWinFuncByORD(), AssignFuncPByORD(),
+ DeclWinFuncByORD_CACHE(), DeclWinFuncByORD_CACHE_survive(),
+ DeclWinFuncByORD_CACHE_resetError_survive(),
+ DeclWinFunc_CACHE(), DeclWinFunc_CACHE_resetError(),
+ DeclWinFunc_CACHE_survive(), DeclWinFunc_CACHE_resetError_survive()
See the header files and the C code in the supplied OS/2-related
modules for the details on usage of these functions.
modifying the versions/names as needed. Run
- perl -wnle "next if 0../EXPORTS/; print qq( \"$1\") if /\"(\w+)\"/" perl5.def >lst
+ perl -wnle "next if 0../EXPORTS/; print qq( \"$1\")
+ if /\"(\w+)\"/" perl5.def >lst
in the Perl build directory (to make the DLL smaller replace perl5.def
with the definition file for the older version of Perl if present).
If you get lots of errors of the form
- tar: FSUM7171 ...: cannot set uid/gid: EDC5139I Operation not permitted.
+ tar: FSUM7171 ...: cannot set uid/gid: EDC5139I Operation not permitted
you didn't read the above and tried to use tar instead of pax, you'll
first have to remove the (now corrupt) perl directory
A message of the form:
- (I see you are using the Korn shell. Some ksh's blow up on Configure,
- mainly on older exotic systems. If yours does, try the Bourne shell instead.)
+ (I see you are using the Korn shell. Some ksh's blow up on
+ Configure, mainly on older exotic systems. If yours does, try the
+ Bourne shell instead.)
is nothing to worry about at all.
If in trying to use Perl you see an error message similar to:
CEE3501S The module libperl.dll was not found.
- From entry point __dllstaticinit at compile unit offset +00000194 at
+ From entry point __dllstaticinit at compile unit offset +00000194
+ at
then your LIBPATH does not have the location of libperl.x and either
libperl.dll or libperl.so in it. Add that directory to your LIBPATH and
A message of the form:
- lib/ftmp-security....File::Temp::_gettemp: Parent directory (/tmp/) is not safe
- (sticky bit not set when world writable?) at lib/ftmp-security.t line 100
- File::Temp::_gettemp: Parent directory (/tmp/) is not safe (sticky bit not
- set when world writable?) at lib/ftmp-security.t line 100
+ lib/ftmp-security....File::Temp::_gettemp: Parent directory (/tmp/)
+ is not safe (sticky bit not set when world writable?) at
+ lib/ftmp-security.t line 100
+ File::Temp::_gettemp: Parent directory (/tmp/) is not safe (sticky
+ bit not set when world writable?) at lib/ftmp-security.t line 100
ok
indicates a problem with the permissions on your /tmp directory within the HFS.
L<INSTALL>, L<perlport>, L<perlebcdic>, L<ExtUtils::MakeMaker>.
- http://www.ibm.com/servers/eserver/zseries/zos/unix/bpxa1toy.html
+ http://www.ibm.com/servers/eserver/zseries/zos/unix/bpxa1toy.html
- http://www.redbooks.ibm.com/redbooks/SG245944.html
+ http://www.redbooks.ibm.com/redbooks/SG245944.html
- http://www.ibm.com/servers/eserver/zseries/zos/unix/bpxa1ty1.html#opensrc
+ http://www.ibm.com/servers/eserver/zseries/zos/unix/bpxa1ty1.html#opensrc
- http://www.xray.mpe.mpg.de/mailing-lists/perl-mvs/
+ http://www.xray.mpe.mpg.de/mailing-lists/perl-mvs/
- http://publibz.boulder.ibm.com:80/cgi-bin/bookmgr_OS390/BOOKS/ceea3030/
+ http://publibz.boulder.ibm.com:80/cgi-bin/bookmgr_OS390/BOOKS/ceea3030/
- http://publibz.boulder.ibm.com:80/cgi-bin/bookmgr_OS390/BOOKS/CBCUG030/
+ http://publibz.boulder.ibm.com:80/cgi-bin/bookmgr_OS390/BOOKS/CBCUG030/
=head2 Mailing list for Perl on OS/390
uni/tr_eucjp.t 29 7424 6 12 200.00% 1-6
uni/tr_sjis.t 29 7424 6 12 200.00% 1-6
56 tests and 467 subtests skipped.
- Failed 27/811 test scripts, 96.67% okay. 1383/75399 subtests failed, 98.17% okay.
+ Failed 27/811 test scripts, 96.67% okay. 1383/75399 subtests failed,
+ 98.17% okay.
The alarm() test failure is caused by system() apparently blocking
alarm(). That is probably a libc bug, and given that SunOS 4.x
(0) You need to have the appropriate Symbian SDK installed.
- These instructions have been tested under various Nokia Series 60
- Symbian SDKs (1.2 to 2.6, 2.8 should also work, 1.2 compiles but
- does not work), Series 80 2.0, and Nokia 7710 (Series 90) SDK.
- You can get the SDKs from Forum Nokia (L<http://www.forum.nokia.com/>).
- A very rough port ("it compiles") to UIQ 2.1 has also been made.
+These instructions have been tested under various Nokia Series 60
+Symbian SDKs (1.2 to 2.6, 2.8 should also work, 1.2 compiles but
+does not work), Series 80 2.0, and Nokia 7710 (Series 90) SDK.
+You can get the SDKs from Forum Nokia (L<http://www.forum.nokia.com/>).
+A very rough port ("it compiles") to UIQ 2.1 has also been made.
- A prerequisite for any of the SDKs is to install ActivePerl
- from ActiveState, L<http://www.activestate.com/Products/ActivePerl/>
+A prerequisite for any of the SDKs is to install ActivePerl
+from ActiveState, L<http://www.activestate.com/Products/ActivePerl/>
- Having the SDK installed also means that you need to have either
- the Metrowerks CodeWarrior installed (2.8 and 3.0 were used in testing)
- or the Microsoft Visual C++ 6.0 installed (SP3 minimum, SP5 recommended).
+Having the SDK installed also means that you need to have either
+the Metrowerks CodeWarrior installed (2.8 and 3.0 were used in testing)
+or the Microsoft Visual C++ 6.0 installed (SP3 minimum, SP5 recommended).
- Note that for example the Series 60 2.0 VC SDK installation talks
- about ActivePerl build 518, which does no more (as of mid-2005) exist
- at the ActiveState website. The ActivePerl 5.8.4 build 810 was
- used successfully for compiling Perl on Symbian. The 5.6.x ActivePerls
- do not work.
+Note that for example the Series 60 2.0 VC SDK installation talks
+about ActivePerl build 518, which does no more (as of mid-2005) exist
+at the ActiveState website. The ActivePerl 5.8.4 build 810 was
+used successfully for compiling Perl on Symbian. The 5.6.x ActivePerls
+do not work.
- Other SDKs or compilers like Visual.NET, command-line-only
- Visual.NET, Borland, GnuPoc, or sdk2unix have not been tried.
+Other SDKs or compilers like Visual.NET, command-line-only
+Visual.NET, Borland, GnuPoc, or sdk2unix have not been tried.
- These instructions almost certainly won't work with older Symbian
- releases or other SDKs. Patches to get this port running in other
- releases, SDKs, compilers, platforms, or devices are naturally welcome.
+These instructions almost certainly won't work with older Symbian
+releases or other SDKs. Patches to get this port running in other
+releases, SDKs, compilers, platforms, or devices are naturally welcome.
(1) Get a Perl source code distribution (for example the file
- perl-5.9.2.tar.gz is fine) from L<http://www.cpan.org/src/>
- and unpack it in your the C:/Symbian directory of your Windows
- system.
+perl-5.9.2.tar.gz is fine) from L<http://www.cpan.org/src/>
+and unpack it in your the C:/Symbian directory of your Windows
+system.
(2) Change to the perl source directory.
- cd c:\Symbian\perl-5.x.x
+ cd c:\Symbian\perl-5.x.x
(3) Run the following script using the perl coming with the SDK
- perl symbian\config.pl
+ perl symbian\config.pl
- You must use the cmd.exe, the Cygwin shell will not work.
- The PATH must include the SDK tools, including a Perl,
- which should be the case under cmd.exe. If you do not
- have that, see the end of symbian\sdk.pl for notes of
- how your environment should be set up for Symbian compiles.
+You must use the cmd.exe, the Cygwin shell will not work.
+The PATH must include the SDK tools, including a Perl,
+which should be the case under cmd.exe. If you do not
+have that, see the end of symbian\sdk.pl for notes of
+how your environment should be set up for Symbian compiles.
(4) Build the project, either by
- make all
+ make all
- in cmd.exe or by using either the Metrowerks CodeWarrior
- or the Visual C++ 6.0, or the Visual Studio 8 (the Visual C++
- 2005 Express Edition works fine).
+in cmd.exe or by using either the Metrowerks CodeWarrior
+or the Visual C++ 6.0, or the Visual Studio 8 (the Visual C++
+2005 Express Edition works fine).
- If you use the VC IDE, you will have to run F<symbian\config.pl>
- first using the cmd.exe, and then run 'make win.mf vc6.mf' to generate
- the VC6 makefiles and workspaces. "make vc6" will compile for the VC6,
- and "make cw" for the CodeWarrior.
+If you use the VC IDE, you will have to run F<symbian\config.pl>
+first using the cmd.exe, and then run 'make win.mf vc6.mf' to generate
+the VC6 makefiles and workspaces. "make vc6" will compile for the VC6,
+and "make cw" for the CodeWarrior.
- The following SDK and compiler configurations and Nokia phones were
- tested at some point in time (+ = compiled and PerlApp run, - = not),
- both for Perl 5.8.x and 5.9.x:
+The following SDK and compiler configurations and Nokia phones were
+tested at some point in time (+ = compiled and PerlApp run, - = not),
+both for Perl 5.8.x and 5.9.x:
- SDK | VC | CW |
- --------+----+----+---
- S60 1.2 | + | + | 3650 (*)
- S60 2.0 | + | + | 6600
- S60 2.1 | - | + | 6670
- S60 2.6 | + | + | 6630
- S60 2.8 | + | + | (not tested in a device)
- S80 2.6 | - | + | 9300
- S90 1.1 | + | - | 7710
- UIQ 2.1 | - | + | (not tested in a device)
+ SDK | VC | CW |
+ --------+----+----+---
+ S60 1.2 | + | + | 3650 (*)
+ S60 2.0 | + | + | 6600
+ S60 2.1 | - | + | 6670
+ S60 2.6 | + | + | 6630
+ S60 2.8 | + | + | (not tested in a device)
+ S80 2.6 | - | + | 9300
+ S90 1.1 | + | - | 7710
+ UIQ 2.1 | - | + | (not tested in a device)
- (*) Compiles but does not work, unfortunately, a problem with Symbian.
+ (*) Compiles but does not work, unfortunately, a problem with Symbian.
- If you are using the 'make' directly, it is the GNU make from the SDKs,
- and it will invoke the right make commands for the Windows emulator
- build and the Arm target builds ('thumb' by default) as necessary.
+If you are using the 'make' directly, it is the GNU make from the SDKs,
+and it will invoke the right make commands for the Windows emulator
+build and the Arm target builds ('thumb' by default) as necessary.
- The build scripts assume the 'absolute style' SDK installs under C:,
- the 'subst style' will not work.
+The build scripts assume the 'absolute style' SDK installs under C:,
+the 'subst style' will not work.
- If using the VC IDE, to build use for example the File->Open Workspace->
- C:\Symbian\8.0a\S60_2nd_FP2\epoc32\build\symbian\perl\perl\wins\perl.dsw
- The emulator binaries will appear in the same directory.
+If using the VC IDE, to build use for example the File->Open Workspace->
+C:\Symbian\8.0a\S60_2nd_FP2\epoc32\build\symbian\perl\perl\wins\perl.dsw
+The emulator binaries will appear in the same directory.
- If using the VC IDE, you will a lot of warnings in the beginning of
- the build because a lot of headers mentioned by the source cannot
- be found, but this is not serious since those headers are not used.
+If using the VC IDE, you will a lot of warnings in the beginning of
+the build because a lot of headers mentioned by the source cannot
+be found, but this is not serious since those headers are not used.
- The Metrowerks will give a lot of warnings about unused variables and
- empty declarations, you can ignore those.
+The Metrowerks will give a lot of warnings about unused variables and
+empty declarations, you can ignore those.
- When the Windows and Arm DLLs are built do not be scared by a very long
- messages whizzing by: it is the "export freeze" phase where the whole
- (rather large) API of Perl is listed.
+When the Windows and Arm DLLs are built do not be scared by a very long
+messages whizzing by: it is the "export freeze" phase where the whole
+(rather large) API of Perl is listed.
- Once the build is completed you need to create the DLL SIS file by
+Once the build is completed you need to create the DLL SIS file by
- make perldll.sis
+ make perldll.sis
- which will create the file perlXYZ.sis (the XYZ being the Perl version)
- which you can then install into your Symbian device: an easy way
- to do this is to send them via Bluetooth or infrared and just open
- the messages.
+which will create the file perlXYZ.sis (the XYZ being the Perl version)
+which you can then install into your Symbian device: an easy way
+to do this is to send them via Bluetooth or infrared and just open
+the messages.
- Since the total size of all Perl SIS files once installed is
- over 2 MB, it is recommended to do the installation into a
- memory card (drive E:) instead of the C: drive.
+Since the total size of all Perl SIS files once installed is
+over 2 MB, it is recommended to do the installation into a
+memory card (drive E:) instead of the C: drive.
- The size of the perlXYZ.SIS is about 370 kB but once it is in the
- device it is about one 750 kB (according to the application manager).
+The size of the perlXYZ.SIS is about 370 kB but once it is in the
+device it is about one 750 kB (according to the application manager).
- The perlXYZ.sis includes only the Perl DLL: to create an additional
- SIS file which includes some of the standard (pure) Perl libraries,
- issue the command
+The perlXYZ.sis includes only the Perl DLL: to create an additional
+SIS file which includes some of the standard (pure) Perl libraries,
+issue the command
- make perllib.sis
+ make perllib.sis
- Some of the standard Perl libraries are included, but not all:
- see L</HISTORY> or F<symbian\install.cfg> for more details
- (250 kB -> 700 kB).
+Some of the standard Perl libraries are included, but not all:
+see L</HISTORY> or F<symbian\install.cfg> for more details
+(250 kB -> 700 kB).
- Some of the standard Perl XS extensions (see L</HISTORY> are
- also available:
+Some of the standard Perl XS extensions (see L</HISTORY> are
+also available:
- make perlext.sis
+ make perlext.sis
- which will create perlXYZext.sis (290 kB -> 770 kB).
+which will create perlXYZext.sis (290 kB -> 770 kB).
- To compile the demonstration application PerlApp you need first to
- install the Perl headers under the SDK.
+To compile the demonstration application PerlApp you need first to
+install the Perl headers under the SDK.
- To install the Perl headers and the class CPerlBase documentation
- so that you no more need the Perl sources around to compile Perl
- applications using the SDK:
+To install the Perl headers and the class CPerlBase documentation
+so that you no more need the Perl sources around to compile Perl
+applications using the SDK:
- make sdkinstall
+ make sdkinstall
- The destination directory is C:\Symbian\perl\X.Y.Z. For more
- details, see F<symbian\PerlBase.pod>.
+The destination directory is C:\Symbian\perl\X.Y.Z. For more
+details, see F<symbian\PerlBase.pod>.
- Once the headers have been installed, you can create a SIS for
- the PerlApp:
+Once the headers have been installed, you can create a SIS for
+the PerlApp:
- make perlapp.sis
+ make perlapp.sis
- The perlapp.sis (11 kB -> 16 kB) will be built in the symbian
- subdirectory, but a copy will also be made to the main directory.
+The perlapp.sis (11 kB -> 16 kB) will be built in the symbian
+subdirectory, but a copy will also be made to the main directory.
- If you want to package the Perl DLLs (one for WINS, one for ARMI),
- the headers, and the documentation:
+If you want to package the Perl DLLs (one for WINS, one for ARMI),
+the headers, and the documentation:
- make perlsdk.zip
+ make perlsdk.zip
- which will create perlXYZsdk.zip that can be used in another
- Windows system with the SDK, without having to compile Perl in
- that system.
+which will create perlXYZsdk.zip that can be used in another
+Windows system with the SDK, without having to compile Perl in
+that system.
- If you want to package the PerlApp sources:
+If you want to package the PerlApp sources:
- make perlapp.zip
+ make perlapp.zip
- If you want to package the perl.exe and miniperl.exe, you
- can use the perlexe.sis and miniperlexe.sis make targets.
- You also probably want the perllib.sis for the libraries
- and maybe even the perlapp.sis for the recognizer.
+If you want to package the perl.exe and miniperl.exe, you
+can use the perlexe.sis and miniperlexe.sis make targets.
+You also probably want the perllib.sis for the libraries
+and maybe even the perlapp.sis for the recognizer.
- The make target 'allsis' combines all the above SIS targets.
+The make target 'allsis' combines all the above SIS targets.
- To clean up after compilation you can use either of
+To clean up after compilation you can use either of
- make clean
- make distclean
+ make clean
+ make distclean
- depending on how clean you want to be.
+depending on how clean you want to be.
=head2 Compilation problems
(This will show as "0.01" in the Symbian Installer.)
- - The console window is a very simple console indeed: one can
- get the newline with "000" and the "C" button is a backspace.
- Do not expect a terminal capable of vt100 or ANSI sequences.
- The console is also "ASCII", you cannot input e.g. any accented
- letters. Because of obvious physical constraints the console is
- also very small: (in Nokia 6600) 22 columns, 17 rows.
- - The following libraries are available:
- AnyDBM_File AutoLoader base Carp Config Cwd constant
- DynaLoader Exporter File::Spec integer lib strict Symbol
- vars warnings XSLoader
- - The following extensions are available:
- attributes Compress::Zlib Cwd Data::Dumper Devel::Peek Digest::MD5 DynaLoader
- Fcntl File::Glob Filter::Util::Call IO List::Util MIME::Base64
- PerlIO::scalar PerlIO::via SDBM_File Socket Storable Time::HiRes
- - The following extensions are missing for various technical reasons:
- B ByteLoader Devel::DProf Devel::PPPort Encode GDBM_File
- I18N::Langinfo IPC::SysV NDBM_File Opcode PerlIO::encoding POSIX
- re Safe Sys::Hostname Sys::Syslog
- threads threads::shared Unicode::Normalize
- - Using MakeMaker or the Module::* to build and install modules
- is not supported.
- - Building XS other than the ones in the core is not supported.
+ - The console window is a very simple console indeed: one can
+ get the newline with "000" and the "C" button is a backspace.
+ Do not expect a terminal capable of vt100 or ANSI sequences.
+ The console is also "ASCII", you cannot input e.g. any accented
+ letters. Because of obvious physical constraints the console is
+ also very small: (in Nokia 6600) 22 columns, 17 rows.
+ - The following libraries are available:
+ AnyDBM_File AutoLoader base Carp Config Cwd constant
+ DynaLoader Exporter File::Spec integer lib strict Symbol
+ vars warnings XSLoader
+ - The following extensions are available:
+ attributes Compress::Zlib Cwd Data::Dumper Devel::Peek
+ Digest::MD5 DynaLoader Fcntl File::Glob Filter::Util::Call
+ IO List::Util MIME::Base64
+ PerlIO::scalar PerlIO::via SDBM_File Socket Storable Time::HiRes
+ - The following extensions are missing for various technical
+ reasons:
+ B ByteLoader Devel::DProf Devel::PPPort Encode GDBM_File
+ I18N::Langinfo IPC::SysV NDBM_File Opcode PerlIO::encoding POSIX
+ re Safe Sys::Hostname Sys::Syslog
+ threads threads::shared Unicode::Normalize
+ - Using MakeMaker or the Module::* to build and install modules
+ is not supported.
+ - Building XS other than the ones in the core is not supported.
Since this is 0.something release, any future releases are almost
guaranteed to be binary incompatible. As a sign of this the Symbian
Also, Configure might abort with
- Build a threading Perl? [n]
- Configure[2437]: Syntax error at line 1 : 'config.sh' is not expected.
+ Build a threading Perl? [n]
+ Configure[2437]: Syntax error at line 1 : 'config.sh' is not expected.
This indicates that Configure is being run with a broken Korn shell
(even though you think you are using a Bourne shell by using
When compiling Perl in Tru64 you may (depending on the compiler
release) see two warnings like this
- cc: Warning: numeric.c, line 104: In this statement, floating-point
- overflow occurs in evaluating the expression "1.8e308". (floatoverfl)
- return HUGE_VAL;
- -----------^
+ cc: Warning: numeric.c, line 104: In this statement, floating-point
+ overflow occurs in evaluating the expression "1.8e308". (floatoverfl)
+ return HUGE_VAL;
+ -----------^
and when compiling the POSIX extension
- cc: Warning: const-c.inc, line 2007: In this statement, floating-point
- overflow occurs in evaluating the expression "1.8e308". (floatoverfl)
- return HUGE_VAL;
- -------------------^
+ cc: Warning: const-c.inc, line 2007: In this statement, floating-point
+ overflow occurs in evaluating the expression "1.8e308". (floatoverfl)
+ return HUGE_VAL;
+ -------------------^
The exact line numbers may vary between Perl releases. The warnings
are benign and can be ignored: in later C compiler releases the warnings
choice. Once you have done so, use a command like the following to
unpack the archive:
- vmstar -xvf perl-5^.23^.8.tar
+ vmstar -xvf perl-5^.23^.9.tar
Then set default to the top-level source directory like so:
- set default [.perl-5^.23^.8]
+ set default [.perl-5^.23^.9]
and proceed with configuration as described in the next section.
#include <exec/exectags.h>
#include <proto/exec.h>
#include <proto/dos.h>
+#include <proto/utility.h>
#include <dos/dos.h>
+extern struct SignalSemaphore popen_sema;
+extern unsigned int pipenum;
+
+extern int32 myruncommand(BPTR seglist, int stack, char *command, int length, char **envp);
+
void amigaos_stdio_get(pTHX_ StdioStore *store)
{
store->astdin =
}
}
+
+struct popen_data
+{
+ struct Task *parent;
+ STRPTR command;
+};
+
+static int popen_result = 0;
+
+int popen_child()
+{
+ struct Task *thisTask = IExec->FindTask(0);
+ struct popen_data *pd = (struct popen_data *)thisTask->tc_UserData;
+ const char *argv[4];
+
+ argv[0] = "sh";
+ argv[1] = "-c";
+ argv[2] = pd->command ? pd->command : NULL;
+ argv[3] = NULL;
+
+ // adebug("%s %ld %s\n",__FUNCTION__,__LINE__,command?command:"NULL");
+
+ /* We need to give this to sh via execvp, execvp expects filename,
+ * argv[]
+ */
+ IExec->ObtainSemaphore(&popen_sema);
+
+ IExec->Signal(pd->parent,SIGBREAKF_CTRL_F);
+
+ popen_result = myexecvp(FALSE, argv[0], (char **)argv);
+ if (pd->command)
+ IExec->FreeVec(pd->command);
+ IExec->FreeVec(pd);
+
+ IExec->ReleaseSemaphore(&popen_sema);
+ IExec->Forbid();
+ return 0;
+}
+
+
PerlIO *Perl_my_popen(pTHX_ const char *cmd, const char *mode)
{
+
PERL_FLUSHALL_FOR_CHILD;
- /* Call system's popen() to get a FILE *, then import it.
- * used 0 for 2nd parameter to PerlIO_importFILE;
- * apparently not used
- */
- // FILE *f=amigaos_popen(cmd,mode);
- // fprintf(stderr,"popen returned %d\n",f);
- return PerlIO_importFILE(amigaos_popen(cmd, mode), 0);
- // return PerlIO_importFILE(f, 0);
+ PerlIO *result = NULL;
+ char pipe_name[50];
+ char unix_pipe[50];
+ char ami_pipe[50];
+ BPTR input = 0;
+ BPTR output = 0;
+ struct Process *proc = NULL;
+ struct Task *thisTask = IExec->FindTask(0);
+ struct popen_data * pd = NULL;
+
+ /* First we need to check the mode
+ * We can only have unidirectional pipes
+ */
+ // adebug("%s %ld cmd %s mode %s \n",__FUNCTION__,__LINE__,cmd,
+ // mode);
+
+ switch (mode[0])
+ {
+ case 'r':
+ case 'w':
+ break;
+
+ default:
+
+ errno = EINVAL;
+ return result;
+ }
+
+ /* Make a unique pipe name
+ * we need a unix one and an amigaos version (of the same pipe!)
+ * as were linking with libunix.
+ */
+
+ sprintf(pipe_name, "%x%08lx/4096/0", pipenum++,
+ IUtility->GetUniqueID());
+ sprintf(unix_pipe, "/PIPE/%s", pipe_name);
+ sprintf(ami_pipe, "PIPE:%s", pipe_name);
+
+ /* Now we open the AmigaOs Filehandles That we wil pass to our
+ * Sub process
+ */
+
+ if (mode[0] == 'r')
+ {
+ /* A read mode pipe: Output from pipe input from Output() or NIL:*/
+ /* First attempt to DUP Output() */
+ input = IDOS->DupFileHandle(IDOS->Input());
+ if(input == 0)
+ {
+ input = IDOS->Open("NIL:", MODE_READWRITE);
+ }
+ if (input != 0)
+ {
+ output = IDOS->Open(ami_pipe, MODE_NEWFILE);
+ }
+ result = PerlIO_open(unix_pipe, mode);
+ }
+ else
+ {
+ /* Open the write end first! */
+
+ result = PerlIO_open(unix_pipe, mode);
+
+ input = IDOS->Open(ami_pipe, MODE_OLDFILE);
+ if (input != 0)
+ {
+ output = IDOS->DupFileHandle(IDOS->Output());
+ if(output == 0)
+ {
+ output = IDOS->Open("NIL:", MODE_READWRITE);
+ }
+ }
+ }
+ if ((input == 0) || (output == 0) || (result == NULL))
+ {
+ /* Ouch stream opening failed */
+ /* Close and bail */
+ if (input)
+ IDOS->Close(input);
+ if (output)
+ IDOS->Close(output);
+ if(result)
+ {
+ PerlIO_close(result);
+ result = NULL;
+ }
+ return result;
+ }
+
+ /* We have our streams now start our new process
+ * We're using a new process so that execve can modify the environment
+ * with messing things up for the shell that launched perl
+ * Copy cmd before we launch the subprocess as perl seems to waste
+ * no time in overwriting it! The subprocess will free the copy.
+ */
+
+ if((pd = (struct popen_data*)IExec->AllocVecTags(sizeof(struct popen_data),AVT_Type,MEMF_SHARED,TAG_DONE)))
+ {
+ pd->parent = thisTask;
+ if ((pd->command = mystrdup(cmd)))
+ {
+ // adebug("%s %ld
+ // %s\n",__FUNCTION__,__LINE__,cmd_copy?cmd_copy:"NULL");
+ proc = IDOS->CreateNewProcTags(
+ NP_Entry, popen_child, NP_Child, TRUE, NP_StackSize,
+ ((struct Process *)thisTask)->pr_StackSize, NP_Input, input,
+ NP_Output, output, NP_Error, IDOS->ErrorOutput(),
+ NP_CloseError, FALSE, NP_Cli, TRUE, NP_Name,
+ "Perl: popen process", NP_UserData, (int)pd,
+ TAG_DONE);
+ }
+ }
+ if(proc)
+ {
+ /* wait for the child be setup right */
+ IExec->Wait(SIGBREAKF_CTRL_F);
+ }
+ if (!proc)
+ {
+ /* New Process Failed to start
+ * Close and bail out
+ */
+ if(pd)
+ {
+ if(pd->command)
+ {
+ IExec->FreeVec(pd->command);
+ }
+ IExec->FreeVec(pd);
+ }
+ if (input)
+ IDOS->Close(input);
+ if (output)
+ IDOS->Close(output);
+ if(result)
+ {
+ PerlIO_close(result);
+ result = NULL;
+ }
+ }
+
+ /* Our new process is running and will close it streams etc
+ * once its done. All we need to is open the pipe via stdio
+ */
+
+ return result;
}
+I32
+Perl_my_pclose(pTHX_ PerlIO *ptr)
+{
+ int result = -1;
+ /* close the file before obtaining the semaphore else we might end up
+ hanging waiting for the child to read the last bit from the pipe */
+ PerlIO_close(ptr);
+ IExec->ObtainSemaphore(&popen_sema);
+ result = popen_result;
+ IExec->ReleaseSemaphore(&popen_sema);
+ return result;
+}
+
+
#ifdef USE_ITHREADS
/* An arbitrary number to start with, should work out what the real max should
if (pseudo_children[i].ti_pid == pid)
{
realpid = (Pid_t)IDOS->GetPID(pseudo_children[i].ti_Process,GPID_PROCESS);
- if(pseudo_children[i].ti_Process == IExec->FindTask(NULL))
+ if(pseudo_children[i].ti_Process == (struct Process *)IExec->FindTask(NULL))
{
thistask = TRUE;
}
int result;
if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG)
{
- result = pthread_join(pid, argflags);
+ result = pthread_join(pid, (void **)argflags);
}
else
{
- while ((result = pthread_join(pid, argflags)) == -1 &&
+ while ((result = pthread_join(pid, (void **)argflags)) == -1 &&
errno == EINTR)
{
// PERL_ASYNC_CHECK();
amigaos_stdio_restore(aTHX_ & store);
- return value;
+ return (void *)value;
}
static BOOL contains_whitespace(char *string)
(contains_whitespace(*cur) ? (2 + no_of_escapes(*cur)) : 0);
}
/* Check if it's a script file */
-
+ IExec->DebugPrintF("%s %ld %08lx %c %c\n",__FILE__,__LINE__,filename,filename[0],filename[1]);
fh = fopen(filename, "r");
if (fh)
{
if (filename_conv)
size += strlen(filename_conv);
size += 1;
- full = (char *)IExec->AllocVec(size + 10, MEMF_ANY | MEMF_CLEAR);
+ full = (char *)IExec->AllocVecTags(size + 10, AVT_ClearWithValue, 0 ,TAG_DONE);
if (full)
{
if (interpreter)
if (esc > 0)
{
- char *buff = IExec->AllocVec(
+ char *buff = (char *)IExec->AllocVecTags(
strlen(*cur) + 4 + esc,
- MEMF_ANY | MEMF_CLEAR);
+ AVT_ClearWithValue,0,
+ TAG_DONE);
char *p = *cur;
char *q = buff;
char **envp;
};
-int __myrc(char *arg)
+int __myrc(__attribute__((unused))char *arg)
{
struct Task *thisTask = IExec->FindTask(0);
struct args *myargs = (struct args *)thisTask->tc_UserData;
size = strlen(s) + 1;
- if ((result = (char *)IExec->AllocVec(size, MEMF_ANY)))
+ if ((result = (char *)IExec->AllocVecTags(size, TAG_DONE)))
{
memmove(result, s, size);
}
return result;
}
-static int pipenum = 0;
+unsigned int pipenum = 0;
int pipe(int filedes[2])
{
return -1;
}
-int wait(int *status)
+int wait(__attribute__((unused))int *status)
{
fprintf(stderr, "No wait try waitpid instead\n");
errno = ECHILD;
return mystrdup(filename);
}
-static struct SignalSemaphore environ_sema;
+struct SignalSemaphore environ_sema;
+struct SignalSemaphore popen_sema;
+
void amigaos4_init_environ_sema()
{
IExec->InitSemaphore(&environ_sema);
+ IExec->InitSemaphore(&popen_sema);
}
void amigaos4_obtain_environ()
char *val;
if ((len = strlen(*envp)))
{
- if ((var = (char *)IExec->AllocVec(
- len + 1, MEMF_ANY | MEMF_CLEAR)))
+ if ((var = (char *)IExec->AllocVecTags(len + 1, AVT_ClearWithValue,0,TAG_DONE)))
{
strcpy(var, *envp);
}
}
-static BOOL contains_whitespace(char *string)
-{
-
- if (string)
- {
-
- if (strchr(string, ' '))
- return TRUE;
- if (strchr(string, '\t'))
- return TRUE;
- if (strchr(string, '\n'))
- return TRUE;
- if (strchr(string, 0xA0))
- return TRUE;
- if (strchr(string, '"'))
- return TRUE;
- }
- return FALSE;
-}
-
-static int no_of_escapes(char *string)
-{
- int cnt = 0;
- char *p;
- for (p = string; p < string + strlen(string); p++)
- {
- if (*p == '"')
- cnt++;
- if (*p == '*')
- cnt++;
- if (*p == '\n')
- cnt++;
- if (*p == '\t')
- cnt++;
- }
- return cnt;
-}
-
struct command_data
{
STRPTR args;
struct Task *parent;
};
+
int myexecvp(bool isperlthread, const char *filename, char *argv[])
{
// adebug("%s %ld
/* if there's a slash or a colon consider filename a path and skip
* search */
int res;
+ char *name = NULL;
+ char *pathpart = NULL;
if ((strchr(filename, '/') == NULL) && (strchr(filename, ':') == NULL))
{
- char *path;
- char *name;
- char *pathpart;
- char *p;
+ const char *path;
+ const char *p;
size_t len;
struct stat st;
}
len = strlen(filename) + 1;
- name = (char *)alloca(strlen(path) + len);
- pathpart = (char *)alloca(strlen(path) + 1);
+ name = (char *)IExec->AllocVecTags(strlen(path) + len, AVT_ClearWithValue,0,AVT_Type,MEMF_SHARED,TAG_DONE);
+ pathpart = (char *)IExec->AllocVecTags(strlen(path) + 1, AVT_ClearWithValue,0,AVT_Type,MEMF_SHARED,TAG_DONE);
p = path;
do
{
}
while (*p++ != '\0');
}
+
res = myexecve(isperlthread, filename, argv, myenviron);
+
+ if(name)
+ {
+ IExec->FreeVec((APTR)name);
+ name = NULL;
+ }
+ if(pathpart)
+ {
+ IExec->FreeVec((APTR)pathpart);
+ pathpart = NULL;
+ }
return res;
}
return myexecve(isperlthread, path, argv, myenviron);
}
-#if 0
-
-int myexecve(const char *filename, char *argv[], char *envp[])
-{
- FILE *fh;
- char buffer[1000];
- int size = 0;
- char **cur;
- char *interpreter = 0;
- char *interpreter_args = 0;
- char *full = 0;
- char *filename_conv = 0;
- char *interpreter_conv = 0;
- // char *tmp = 0;
- char *fname;
- // int tmpint;
- // struct Task *thisTask = IExec->FindTask(0);
- int result = -1;
-
- StdioStore store;
-
- dTHX;
- if(aTHX) // I hope this is NULL when not on a interpreteer thread nor to level.
- {
- /* Save away our stdio */
- amigaos_stdio_save(aTHX_ & store);
- }
-
- // adebug("%s %ld %s\n",__FUNCTION__,__LINE__,filename?filename:"NULL");
-
- /* Calculate the size of filename and all args, including spaces and
- * quotes */
- size = 0; // strlen(filename) + 1;
- for (cur = (char **)argv /* +1 */; *cur; cur++)
- {
- size +=
- strlen(*cur) + 1 +
- (contains_whitespace(*cur) ? (2 + no_of_escapes(*cur)) : 0);
- }
- /* Check if it's a script file */
-
- fh = fopen(filename, "r");
- if (fh)
- {
- if (fgetc(fh) == '#' && fgetc(fh) == '!')
- {
- char *p;
- char *q;
- fgets(buffer, 999, fh);
- p = buffer;
- while (*p == ' ' || *p == '\t')
- p++;
- if (buffer[strlen(buffer) - 1] == '\n')
- buffer[strlen(buffer) - 1] = '\0';
- if ((q = strchr(p, ' ')))
- {
- *q++ = '\0';
- if (*q != '\0')
- {
- interpreter_args = mystrdup(q);
- }
- }
- else
- interpreter_args = mystrdup("");
-
- interpreter = mystrdup(p);
- size += strlen(interpreter) + 1;
- size += strlen(interpreter_args) + 1;
- }
-
- fclose(fh);
- }
- else
- {
- /* We couldn't open this why not? */
- if (errno == ENOENT)
- {
- /* file didn't exist! */
- goto out;
- }
- }
-
- /* Allocate the command line */
- filename_conv = convert_path_u2a(filename);
-
- if (filename_conv)
- size += strlen(filename_conv);
- size += 1;
- full = (char *)IExec->AllocVec(size + 10, MEMF_ANY | MEMF_CLEAR);
- if (full)
- {
- if (interpreter)
- {
- interpreter_conv = convert_path_u2a(interpreter);
-#if !defined(__USE_RUNCOMMAND__)
-#warning(using system!)
- sprintf(full, "%s %s %s ", interpreter_conv,
- interpreter_args, filename_conv);
-#else
- sprintf(full, "%s %s ", interpreter_args,
- filename_conv);
-#endif
- IExec->FreeVec(interpreter);
- IExec->FreeVec(interpreter_args);
-
- if (filename_conv)
- IExec->FreeVec(filename_conv);
- fname = mystrdup(interpreter_conv);
-
- if (interpreter_conv)
- IExec->FreeVec(interpreter_conv);
- }
- else
- {
-#ifndef __USE_RUNCOMMAND__
- sprintf(full, "%s ", filename_conv);
-#else
- sprintf(full, "");
-#endif
- fname = mystrdup(filename_conv);
- if (filename_conv)
- IExec->FreeVec(filename_conv);
- }
-
- for (cur = (char **)(argv + 1); *cur != 0; cur++)
- {
- if (contains_whitespace(*cur))
- {
- int esc = no_of_escapes(*cur);
-
- if (esc > 0)
- {
- char *buff = IExec->AllocVec(
- strlen(*cur) + 4 + esc,
- MEMF_ANY | MEMF_CLEAR);
- char *p = *cur;
- char *q = buff;
-
- *q++ = '"';
- while (*p != '\0')
- {
-
- if (*p == '\n')
- {
- *q++ = '*';
- *q++ = 'N';
- p++;
- continue;
- }
- else if (*p == '"')
- {
- *q++ = '*';
- *q++ = '"';
- p++;
- continue;
- }
- else if (*p == '*')
- {
- *q++ = '*';
- }
- *q++ = *p++;
- }
- *q++ = '"';
- *q++ = ' ';
- *q = '\0';
- strcat(full, buff);
- IExec->FreeVec(buff);
- }
- else
- {
- strcat(full, "\"");
- strcat(full, *cur);
- strcat(full, "\" ");
- }
- }
- else
- {
- strcat(full, *cur);
- strcat(full, " ");
- }
- }
- strcat(full, "\n");
-
-// if(envp)
-// createvars(envp);
-
-#ifndef __USE_RUNCOMMAND__
- result = IDOS->SystemTags(
- full, SYS_UserShell, TRUE, NP_StackSize,
- ((struct Process *)thisTask)->pr_StackSize, SYS_Input,
- ((struct Process *)thisTask)->pr_CIS, SYS_Output,
- ((struct Process *)thisTask)->pr_COS, SYS_Error,
- ((struct Process *)thisTask)->pr_CES, TAG_DONE);
-#else
-
- if (fname)
- {
- BPTR seglist = IDOS->LoadSeg(fname);
- if (seglist)
- {
- /* check if we have an executable! */
- struct PseudoSegList *ps = NULL;
- if (!IDOS->GetSegListInfoTags(
- seglist, GSLI_Native, &ps, TAG_DONE))
- {
- IDOS->GetSegListInfoTags(
- seglist, GSLI_68KPS, &ps, TAG_DONE);
- }
- if (ps != NULL)
- {
- // adebug("%s %ld %s
- // %s\n",__FUNCTION__,__LINE__,fname,full);
- IDOS->SetCliProgramName(fname);
- // result=RunCommand(seglist,8*1024,full,strlen(full));
- // result=myruncommand(seglist,8*1024,full,strlen(full),envp);
- result = myruncommand(seglist, 8 * 1024,
- full, -1, envp);
- errno = 0;
- }
- else
- {
- errno = ENOEXEC;
- }
- IDOS->UnLoadSeg(seglist);
- }
- else
- {
- errno = ENOEXEC;
- }
- IExec->FreeVec(fname);
- }
-
-#endif /* USE_RUNCOMMAND */
-
- IExec->FreeVec(full);
- if (errno == ENOEXEC)
- {
- result = -1;
- }
- goto out;
- }
-
- if (interpreter)
- IExec->FreeVec(interpreter);
- if (filename_conv)
- IExec->FreeVec(filename_conv);
-
- errno = ENOMEM;
-
-out:
-
- amigaos_stdio_restore(aTHX_ &store);
- STATUS_NATIVE_CHILD_SET(result);
- PL_exit_flags |= PERL_EXIT_EXPECTED;
- if (result != -1) my_exit(result);
-
- return(result);
-}
-
-#endif
-
int pause(void)
{
fprintf(stderr, "Pause not implemented\n");
return -1;
}
-uint32 size_env(struct Hook *hook, APTR userdata, struct ScanVarsMsg *message)
+uint32 size_env(struct Hook *hook, __attribute__((unused))APTR userdata, struct ScanVarsMsg *message)
{
if (strlen(message->sv_GDir) <= 4)
{
return 0;
}
-uint32 copy_env(struct Hook *hook, APTR userdata, struct ScanVarsMsg *message)
+uint32 copy_env(struct Hook *hook, __attribute__((unused))APTR userdata, struct ScanVarsMsg *message)
{
if (strlen(message->sv_GDir) <= 4)
{
char **env = (char **)hook->h_Data;
uint32 size =
strlen(message->sv_Name) + 1 + message->sv_VarLen + 1 + 1;
- char *buffer = (char *)IExec->AllocVec((uint32)size,
- MEMF_ANY | MEMF_CLEAR);
+ char *buffer = (char *)IExec->AllocVecTags((uint32)size,AVT_ClearWithValue,0,TAG_DONE);
+
snprintf(buffer, size - 1, "%s=%s", message->sv_Name,
message->sv_Var);
void ___makeenviron()
{
- struct Hook hook;
-
- char varbuf[8];
- uint32 flags = 0;
+ struct Hook *hook = (struct Hook *)IExec->AllocSysObjectTags(ASOT_HOOK,TAG_DONE);
- struct DOSIFace *myIDOS =
- (struct DOSIFace *)OpenInterface("dos.library", 53);
- if (myIDOS)
+ if(hook)
{
- if (myIDOS->GetVar("ABCSH_IMPORT_LOCAL", varbuf, 8,
- GVF_LOCAL_ONLY) > 0)
- {
- flags = GVF_LOCAL_ONLY;
- }
- else
+ char varbuf[8];
+ uint32 flags = 0;
+
+ struct DOSIFace *myIDOS =
+ (struct DOSIFace *)OpenInterface("dos.library", 53);
+ if (myIDOS)
{
- flags = GVF_GLOBAL_ONLY;
- }
+ uint32 size = 0;
+ if (myIDOS->GetVar("ABCSH_IMPORT_LOCAL", varbuf, 8,
+ GVF_LOCAL_ONLY) > 0)
+ {
+ flags = GVF_LOCAL_ONLY;
+ }
+ else
+ {
+ flags = GVF_GLOBAL_ONLY;
+ }
- hook.h_Entry = size_env;
- hook.h_Data = 0;
+ hook->h_Entry = size_env;
+ hook->h_Data = 0;
- myIDOS->ScanVars(&hook, flags, 0);
- hook.h_Data = (APTR)(((uint32)hook.h_Data) + 1);
+ myIDOS->ScanVars(hook, flags, 0);
+ size = ((uint32)hook->h_Data) + 1;
- myenviron = (char **)IExec->AllocVec((uint32)hook.h_Data *
- sizeof(char **),
- MEMF_ANY | MEMF_CLEAR);
- origenviron = myenviron;
- if (!myenviron)
- {
- return;
- }
- hook.h_Entry = copy_env;
- hook.h_Data = myenviron;
+ myenviron = (char **)IExec->AllocVecTags(size *
+ sizeof(char **),
+ AVT_ClearWithValue,0,TAG_DONE);
+ origenviron = myenviron;
+ if (!myenviron)
+ {
+ IExec->FreeSysObject(ASOT_HOOK,hook);
+ CloseInterface((struct Interface *)myIDOS);
+ return;
+ }
+ hook->h_Entry = copy_env;
+ hook->h_Data = myenviron;
- myIDOS->ScanVars(&hook, flags, 0);
- CloseInterface((struct Interface *)myIDOS);
+ myIDOS->ScanVars(hook, flags, 0);
+ IExec->FreeSysObject(ASOT_HOOK,hook);
+ CloseInterface((struct Interface *)myIDOS);
+ }
}
}
}
}
-/* reimplementation of popen, clib2's doesn't do all we want */
-
-static BOOL is_final_quote_character(const char *str)
-{
- BOOL result;
-
- result = (BOOL)(str[0] == '\"' && (str[1] == '\0' || isspace(str[1])));
-
- return (result);
-}
-
-static BOOL is_final_squote_character(const char *str)
-{
- BOOL result;
-
- result = (BOOL)(str[0] == '\'' && (str[1] == '\0' || isspace(str[1])));
-
- return (result);
-}
-
-int popen_child()
-{
- struct Task *thisTask = IExec->FindTask(0);
-
- char *command = (char *)thisTask->tc_UserData;
- size_t len;
- char *str;
- int argc;
- int number_of_arguments;
- char *argv[4];
-
- argv[0] = "sh";
- argv[1] = "-c";
- argv[2] = command ? command : NULL;
- argv[3] = NULL;
-
- // adebug("%s %ld %s\n",__FUNCTION__,__LINE__,command?command:"NULL");
-
- /* We need to give this to sh via execvp, execvp expects filename,
- * argv[]
- */
-
- myexecvp(FALSE, argv[0], argv);
- if (command)
- IExec->FreeVec(command);
-
- IExec->Forbid();
- return 0;
-}
-
-FILE *amigaos_popen(const char *cmd, const char *mode)
-{
- FILE *result = NULL;
- char pipe_name[50];
- char unix_pipe[50];
- char ami_pipe[50];
- char *cmd_copy;
- BPTR input = 0;
- BPTR output = 0;
- struct Process *proc = NULL;
- struct Task *thisTask = IExec->FindTask(0);
-
- /* First we need to check the mode
- * We can only have unidirectional pipes
- */
- // adebug("%s %ld cmd %s mode %s \n",__FUNCTION__,__LINE__,cmd,
- // mode);
-
- switch (mode[0])
- {
- case 'r':
- case 'w':
- break;
-
- default:
-
- errno = EINVAL;
- return result;
- }
-
- /* Make a unique pipe name
- * we need a unix one and an amigaos version (of the same pipe!)
- * as were linking with libunix.
- */
-
- sprintf(pipe_name, "%x%08lx/4096/0", pipenum++,
- IUtility->GetUniqueID());
- sprintf(unix_pipe, "/PIPE/%s", pipe_name);
- sprintf(ami_pipe, "PIPE:%s", pipe_name);
-
- /* Now we open the AmigaOs Filehandles That we wil pass to our
- * Sub process
- */
-
- if (mode[0] == 'r')
- {
- /* A read mode pipe: Output from pipe input from NIL:*/
- input = IDOS->Open("NIL:", MODE_NEWFILE);
- if (input != 0)
- {
- output = IDOS->Open(ami_pipe, MODE_NEWFILE);
- }
- }
- else
- {
-
- input = IDOS->Open(ami_pipe, MODE_NEWFILE);
- if (input != 0)
- {
- output = IDOS->Open("NIL:", MODE_NEWFILE);
- }
- }
- if ((input == 0) || (output == 0))
- {
- /* Ouch stream opening failed */
- /* Close and bail */
- if (input)
- IDOS->Close(input);
- if (output)
- IDOS->Close(output);
- return result;
- }
-
- /* We have our streams now start our new process
- * We're using a new process so that execve can modify the environment
- * with messing things up for the shell that launched perl
- * Copy cmd before we launch the subprocess as perl seems to waste
- * no time in overwriting it! The subprocess will free the copy.
- */
-
- if ((cmd_copy = mystrdup(cmd)))
- {
- // adebug("%s %ld
- // %s\n",__FUNCTION__,__LINE__,cmd_copy?cmd_copy:"NULL");
- proc = IDOS->CreateNewProcTags(
- NP_Entry, popen_child, NP_Child, TRUE, NP_StackSize,
- ((struct Process *)thisTask)->pr_StackSize, NP_Input, input,
- NP_Output, output, NP_Error, IDOS->ErrorOutput(),
- NP_CloseError, FALSE, NP_Cli, TRUE, NP_Name,
- "Perl: popen process", NP_UserData, (int)cmd_copy,
- TAG_DONE);
- }
- if (!proc)
- {
- /* New Process Failed to start
- * Close and bail out
- */
- if (input)
- IDOS->Close(input);
- if (output)
- IDOS->Close(output);
- if (cmd_copy)
- IExec->FreeVec(cmd_copy);
- }
-
- /* Our new process is running and will close it streams etc
- * once its done. All we need to is open the pipe via stdio
- */
-
- return fopen(unix_pipe, mode);
-}
/* Work arround for clib2 fstat */
#ifndef S_IFCHR
int pipe(int filedes[2]);
-FILE *amigaos_popen(const char *cmd, const char *mode);
+//FILE *amigaos_popen(const char *cmd, const char *mode);
+//int amigaos_pclose(FILE *f);
+
void amigaos4_obtain_environ();
void amigaos4_release_environ();
And documentation and comments may still use the term ASCII, when
sometimes in fact the entire range from 0 - 255 is meant.
+The non-ASCII characters below 256 can have various meanings, depending on
+various things. (See, most notably, L<perllocale>.) But usually the whole
+range can be referred to as ISO-8859-1. Often, the term "Latin-1" (or
+"Latin1") is used as an equivalent for ISO-8859-1. But some people treat
+"Latin1" as referring just to the characters in the range 128 through 255, or
+somethimes from 160 through 255.
+This documentation uses "Latin1" and "Latin-1" to refer to all 256 characters.
+
Note that Perl can be compiled and run under either ASCII or EBCDIC (See
L<perlebcdic>). Most of the documentation (and even comments in the code)
ignore the EBCDIC possibility.
/*
=for apidoc av_push
-Pushes an SV onto the end of the array. The array will grow automatically
-to accommodate the addition. This takes ownership of one reference count.
+Pushes an SV (transferring control of one reference count) onto the end of the
+array. The array will grow automatically to accommodate the addition.
Perl equivalent: C<push @myarray, $elem;>.
? mg_size(MUTABLE_SV(av)) : AvFILLp(av))
#define av_tindex(av) av_top_index(av)
+#if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_REGEXEC_C) || defined(PERL_IN_UTF8_C)
+/* Note that it doesn't make sense to do this:
+ * SvGETMAGIC(av); IV x = av_tindex_nomg(av);
+ * This name is controversial, and so is restricted by the #ifdef to the places
+ * it already occurs
+ */
+# define av_tindex_nomg(av) (__ASSERT_(SvTYPE(av) == SVt_PVAV) AvFILLp(av))
+#endif
+
#define NEGATIVE_INDICES_VAR "NEGATIVE_INDICES"
/*
#if defined(PERL_IN_REGEXEC_C)
static const bool GCB_table[14][14] = {
-/* XX CR CN EX L LF LV LVT PP RI SM T V edge*/
-/* XX*/ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1},
-/* CR*/ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1},
-/* CN*/ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-/* EX*/ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1},
-/* L*/ { 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1},
-/* LF*/ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-/* LV*/ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1},
-/* LVT*/ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1},
-/* PP*/ { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1},
-/* RI*/ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1},
-/* SM*/ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1},
-/* T*/ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1},
-/* V*/ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1},
-/*edge*/ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}
+ /* 'edg' stands for 'EDGE' */
+/* XX CR CN EX L LF LV LVT PP RI SM T V edg */
+/* XX */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 },
+/* CR */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
+/* CN */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+/* EX */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 },
+/* L */ { 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1 },
+/* LF */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+/* LV */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1 },
+/* LVT*/ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1 },
+/* PP */ { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1 },
+/* RI */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1 },
+/* SM */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 },
+/* T */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1 },
+/* V */ { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1 },
+/* edg*/ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }
};
-#define LB_NOBREAK 0
-#define LB_BREAKABLE 1
-#define LB_NOBREAK_EVEN_WITH_SP_BETWEEN 2
-#define LB_CM_foo 3
-#define LB_SP_foo 6
-#define LB_PR_or_PO_then_OP_or_HY 9
-#define LB_SY_or_IS_then_various 11
-#define LB_HY_or_BA_then_foo 13
-#define LB_various_then_PO_or_PR 16
+#define LB_NOBREAK 0
+#define LB_BREAKABLE 1
+#define LB_NOBREAK_EVEN_WITH_SP_BETWEEN 2
+#define LB_CM_foo 3
+#define LB_SP_foo 6
+#define LB_PR_or_PO_then_OP_or_HY 9
+#define LB_SY_or_IS_then_various 11
+#define LB_HY_or_BA_then_foo 13
+#define LB_various_then_PO_or_PR 16
static const U8 LB_table[36][36] = {
-
-/* 'ed' stands for 'edge' */
-/* AL BA BB B2 SY CR CP CL CM CB EX GL H2 H3 HL HY ID IS IN JL JT JV LF BK NL NS NU OP PO PR QU RI SP WJ ZW ed */
-/* AL */ { 0, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 0, 0, 1, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1 },
-/* BA */ { 14, 0, 14, 14, 2, 0, 2, 2, 0, 1, 2, 14, 14, 14, 14, 0, 14, 2, 14, 14, 14, 14, 0, 0, 0, 0, 14, 14, 14, 14, 0, 14, 0, 0, 0, 1 },
-/* BB */ { 0, 0, 0, 0, 2, 0, 2, 2, 0, 1, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
-/* B2 */ { 1, 0, 1, 2, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1 },
-/* SY */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 0, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 12, 1, 17, 17, 0, 1, 0, 0, 0, 1 },
-/* CR */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
-/* CP */ { 0, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 0, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 2, 0, 1, 17, 17, 0, 1, 0, 0, 0, 1 },
-/* CL */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 2, 1, 1, 17, 17, 0, 1, 0, 0, 0, 1 },
-/* CM */ { 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 1 },
-/* CB */ { 1, 1, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1 },
-/* EX */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1 },
-/* GL */ { 0, 0, 0, 0, 2, 0, 2, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
-/* H2 */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1 },
-/* H3 */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1 },
-/* HL */ { 0, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 0, 0, 1, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1 },
-/* HY */ { 14, 0, 14, 14, 2, 0, 2, 2, 0, 1, 2, 14, 14, 14, 14, 0, 14, 2, 14, 14, 14, 14, 0, 0, 0, 0, 13, 14, 14, 14, 0, 14, 0, 0, 0, 1 },
-/* ID */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1 },
-/* IS */ { 0, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 0, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 12, 1, 17, 17, 0, 1, 0, 0, 0, 1 },
-/* IN */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1 },
-/* JL */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 0, 0, 1, 0, 1, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1 },
-/* JT */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1 },
-/* JV */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1 },
-/* LF */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
-/* BK */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
-/* NL */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
-/* NS */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1 },
-/* NU */ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 2, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1 },
-/* OP */ { 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 1 },
-/* PO */ { 0, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 0, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 10, 1, 1, 0, 1, 0, 0, 0, 1 },
-/* PR */ { 0, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, 1, 0, 1, 0, 0, 0, 1 },
-/* QU */ { 0, 0, 0, 0, 2, 0, 2, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1 },
-/* RI */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1 },
-/* SP */ { 7, 7, 7, 7, 8, 0, 8, 8, 7, 7, 8, 7, 7, 7, 7, 7, 7, 8, 7, 7, 7, 7, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 0, 8, 0, 1 },
-/* WJ */ { 0, 0, 0, 0, 2, 0, 2, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
-/* ZW */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1 },
-/* ed */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ /* 'edg' stands for 'EDGE' */
+/* AL BA BB B2 SY CR CP CL CM CB EX GL H2 H3 HL HY ID IS IN JL JT JV LF BK NL NS NU OP PO PR QU RI SP WJ ZW edg */
+/* AL */ { 0, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 0, 0, 1, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1 },
+/* BA */ {14, 0,14,14, 2, 0, 2, 2, 0, 1, 2,14,14,14,14, 0,14, 2,14,14,14,14, 0, 0, 0, 0,14,14,14,14, 0,14, 0, 0, 0, 1 },
+/* BB */ { 0, 0, 0, 0, 2, 0, 2, 2, 0, 1, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+/* B2 */ { 1, 0, 1, 2, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1 },
+/* SY */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 0, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0,12, 1,17,17, 0, 1, 0, 0, 0, 1 },
+/* CR */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+/* CP */ { 0, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 0, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 2, 0, 1,17,17, 0, 1, 0, 0, 0, 1 },
+/* CL */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 2, 1, 1,17,17, 0, 1, 0, 0, 0, 1 },
+/* CM */ { 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 1 },
+/* CB */ { 1, 1, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1 },
+/* EX */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1 },
+/* GL */ { 0, 0, 0, 0, 2, 0, 2, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+/* H2 */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1 },
+/* H3 */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1 },
+/* HL */ { 0, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 0, 0, 1, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1 },
+/* HY */ {14, 0,14,14, 2, 0, 2, 2, 0, 1, 2,14,14,14,14, 0,14, 2,14,14,14,14, 0, 0, 0, 0,13,14,14,14, 0,14, 0, 0, 0, 1 },
+/* ID */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1 },
+/* IS */ { 0, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 0, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0,12, 1,17,17, 0, 1, 0, 0, 0, 1 },
+/* IN */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1 },
+/* JL */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 0, 0, 1, 0, 1, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1 },
+/* JT */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1 },
+/* JV */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1 },
+/* LF */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+/* BK */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+/* NL */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+/* NS */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1 },
+/* NU */ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 2, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1 },
+/* OP */ { 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 1 },
+/* PO */ { 0, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 0, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0,10, 1, 1, 0, 1, 0, 0, 0, 1 },
+/* PR */ { 0, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0,10, 1, 1, 0, 1, 0, 0, 0, 1 },
+/* QU */ { 0, 0, 0, 0, 2, 0, 2, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1 },
+/* RI */ { 1, 0, 1, 1, 2, 0, 2, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1 },
+/* SP */ { 7, 7, 7, 7, 8, 0, 8, 8, 7, 7, 8, 7, 7, 7, 7, 7, 7, 8, 7, 7, 7, 7, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 0, 8, 0, 1 },
+/* WJ */ { 0, 0, 0, 0, 2, 0, 2, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+/* ZW */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1 },
+/* edg*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
-#define WB_NOBREAK 0
-#define WB_BREAKABLE 1
-#define WB_hs_then_hs 2
-#define WB_Ex_or_FO_then_foo 3
-#define WB_DQ_then_HL 4
-#define WB_HL_then_DQ 6
-#define WB_LE_or_HL_then_MB_or_ML_or_SQ 8
-#define WB_MB_or_ML_or_SQ_then_LE_or_HL 10
-#define WB_MB_or_MN_or_SQ_then_NU 12
-#define WB_NU_then_MB_or_MN_or_SQ 14
+#define WB_NOBREAK 0
+#define WB_BREAKABLE 1
+#define WB_hs_then_hs 2
+#define WB_Ex_or_FO_then_foo 3
+#define WB_DQ_then_HL 4
+#define WB_HL_then_DQ 6
+#define WB_LE_or_HL_then_MB_or_ML_or_SQ 8
+#define WB_MB_or_ML_or_SQ_then_LE_or_HL 10
+#define WB_MB_or_MN_or_SQ_then_NU 12
+#define WB_NU_then_MB_or_MN_or_SQ 14
static const U8 WB_table[19][19] = {
-
-/* 'Ex' stands for 'Extend'; 'hs' for 'Perl_Tailored_HSpace'; 'ed' for 'edge' */
-/* XX LE CR DQ Ex EX FO HL KA LF ML MN MB NL NU hs RI SQ ed */
-/* XX */ { 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
-/* LE */ { 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 9, 1, 9, 1, 0, 1, 1, 9, 1 },
-/* CR */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 },
-/* DQ */ { 1, 1, 1, 1, 0, 1, 0, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
-/* Ex */ { 3, 3, 1, 3, 0, 3, 0, 3, 3, 1, 3, 3, 3, 1, 3, 1, 3, 3, 1 },
-/* EX */ { 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
-/* FO */ { 3, 3, 1, 3, 0, 3, 0, 3, 3, 1, 3, 3, 3, 1, 3, 1, 3, 3, 1 },
-/* HL */ { 1, 0, 1, 7, 0, 0, 0, 0, 1, 1, 9, 1, 9, 1, 0, 1, 1, 8, 1 },
-/* KA */ { 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
-/* LF */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 },
-/* ML */ { 1, 11, 1, 1, 0, 1, 0, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
-/* MN */ { 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 13, 1, 1, 1, 1 },
-/* MB */ { 1, 11, 1, 1, 0, 1, 0, 11, 1, 1, 1, 1, 1, 1, 13, 1, 1, 1, 1 },
-/* NL */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 },
-/* NU */ { 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 15, 15, 1, 0, 1, 1, 15, 1 },
-/* hs */ { 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1 },
-/* RI */ { 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1 },
-/* SQ */ { 1, 11, 1, 1, 0, 1, 0, 11, 1, 1, 1, 1, 1, 1, 13, 1, 1, 1, 1 },
-/* ed */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }
+ /* 'Ext' stands for 'Extend'; 'edg' stands for 'EDGE'; 'hs' stands
+ * for 'Perl_Tailored_HSpace'; 'unk' stands for 'UNKNOWN' */
+/* XX LE CR DQ Ext EX FO HL KA LF ML MN MB NL NU hs RI SQ edg */
+/* XX */ { 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+/* LE */ { 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 9, 1, 9, 1, 0, 1, 1, 9, 1 },
+/* CR */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 },
+/* DQ */ { 1, 1, 1, 1, 0, 1, 0, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+/* Ext*/ { 3, 3, 1, 3, 0, 3, 0, 3, 3, 1, 3, 3, 3, 1, 3, 1, 3, 3, 1 },
+/* EX */ { 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
+/* FO */ { 3, 3, 1, 3, 0, 3, 0, 3, 3, 1, 3, 3, 3, 1, 3, 1, 3, 3, 1 },
+/* HL */ { 1, 0, 1, 7, 0, 0, 0, 0, 1, 1, 9, 1, 9, 1, 0, 1, 1, 8, 1 },
+/* KA */ { 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+/* LF */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 },
+/* ML */ { 1,11, 1, 1, 0, 1, 0,11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+/* MN */ { 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1,13, 1, 1, 1, 1 },
+/* MB */ { 1,11, 1, 1, 0, 1, 0,11, 1, 1, 1, 1, 1, 1,13, 1, 1, 1, 1 },
+/* NL */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1 },
+/* NU */ { 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1,15,15, 1, 0, 1, 1,15, 1 },
+/* hs */ { 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1 },
+/* RI */ { 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1 },
+/* SQ */ { 1,11, 1, 1, 0, 1, 0,11, 1, 1, 1, 1, 1, 1,13, 1, 1, 1, 1 },
+/* edg*/ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }
};
#endif /* defined(PERL_IN_REGEXEC_C) */
* 1a0687fb9c6c4567e853913549df0944fe40821279a3e9cdaa6ab8679bc286fd lib/unicore/extracted/DLineBreak.txt
* 40bcfed3ca727c19e1331f6c33806231d5f7eeeabd2e6a9e06a3740c85d0c250 lib/unicore/extracted/DNumType.txt
* a18d502bad39d527ac5586d7bc93e29f565859e3bcc24ada627eff606d6f5fed lib/unicore/extracted/DNumValues.txt
- * 7baa3c79b0ac81279720b4871737ab448d7ddd1bfad31b981437ce49c1292535 lib/unicore/mktables
+ * 285aef7ed2bf69724b1fa9bba177640636f666e1a5dd0ba5e538d4790129bbfe lib/unicore/mktables
* 462c9aaa608fb2014cd9649af1c5c009485c60b9c8b15b89401fdc10cf6161c6 lib/unicore/version
* 913d2f93f3cb6cdf1664db888bf840bc4eb074eef824e082fceda24a9445e60c regen/charset_translations.pl
- * 5774f77d07a81945b6a679ecce07ad90cdb334f3fb402ff63bdbecd2ec67da05 regen/mk_invlists.pl
+ * 12bd58cb9d5a99f631ca95e269f7f9c90dacaf81020efa5d95a995f3cdc19200 regen/mk_invlists.pl
* ex: set ro: */
*/
#$d_nearbyint HAS_NEARBYINT /**/
+/* HAS_NEWLOCALE:
+ * This symbol, if defined, indicates that the newlocale routine is
+ * available to return a new locale object or modify an existing
+ * locale object.
+ */
+/* HAS_FREELOCALE:
+ * This symbol, if defined, indicates that the freelocale routine is
+ * available to deallocates the resources associated with a locale object.
+ */
+/* HAS_USELOCALE:
+ * This symbol, if defined, indicates that the uselocale routine is
+ * available to set the current locale for the calling thread.
+ */
+#$d_newlocale HAS_NEWLOCALE /**/
+#$d_freelocale HAS_FREELOCALE /**/
+#$d_uselocale HAS_USELOCALE /**/
+
/* HAS_NEXTAFTER:
* This symbol, if defined, indicates that the nextafter routine is
* available to return the next machine representable double from
$ WC "d_ndbm='undef'"
$ WC "d_ndbm_h_uses_prototypes='undef'"
$ WC "d_nearbyint='undef'"
+$ WC "d_newlocale='undef'"
+$ WC "d_uselocale='undef'"
+$ WC "d_freelocale='undef'"
$ WC "d_nextafter='" + d_nextafter + "'"
$ WC "d_nexttoward='" + d_nexttoward + "'"
$ WC "d_nice='define'"
$ WC "d_endprotoent_r='undef'"
$ WC "d_endpwent_r='undef'"
$ WC "d_endservent_r='undef'"
+$ WC "d_freelocale='undef'"
$ WC "d_getgrent_r='undef'"
$ WC "d_getgrgid_r='" + d_getgrgid_r + "'"
$ WC "d_getgrnam_r='" + d_getgrnam_r + "'"
$ WC "d_lgamma_r='undef'"
$ WC "d_localtime_r='undef'" ! leave undef'd; we use my_localtime
$ WC "d_localtime_r_needs_tzset='undef'"
+$ WC "d_newlocale='undef'"
$ WC "d_random_r='undef'"
$ WC "d_readdir_r='define'" ! always defined; we roll our own
$ WC "d_readdir64_r='undef'"
$ WC "d_strerror_r='undef'"
$ WC "d_tmpnam_r='undef'"
$ WC "d_ttyname_r='" + d_ttyname_r + "'"
+$ WC "d_uselocale='undef'"
$ WC "ctermid_r_proto='0'"
$ WC "crypt_r_proto='0'"
$ WC "drand48_r_proto='0'"
ST(0) = shm == (void *) -1 ? &PL_sv_undef
: sv_2mortal(newSVpvn((char *) &shm, sizeof(void *)));
} else {
+ SETERRNO(EINVAL,LIB_INVARG);
ST(0) = &PL_sv_undef;
}
XSRETURN(1);
use vars qw($VERSION);
use Carp;
-$VERSION = '2.05';
+$VERSION = '2.06_01';
# Figure out if we have support for native sized types
my $N = do { my $foo = eval { pack "L!", 0 }; $@ ? '' : '!' };
use vars qw($VERSION);
use Carp;
-$VERSION = '2.05';
+$VERSION = '2.06_01';
# Figure out if we have support for native sized types
my $N = do { my $foo = eval { pack "L!", 0 }; $@ ? '' : '!' };
use vars qw($VERSION);
use Carp;
-$VERSION = '2.05';
+$VERSION = '2.06_01';
# Figure out if we have support for native sized types
my $N = do { my $foo = eval { pack "L!", 0 }; $@ ? '' : '!' };
require Exporter;
@ISA = qw(Exporter);
-$VERSION = '2.05';
+$VERSION = '2.06_01';
# To support new constants, just add them to @EXPORT_OK
# and the C/XS code will be generated automagically.
}
SKIP: {
- skip('lacking d_shm', 10) unless
+ skip('lacking d_shm', 11) unless
$Config{'d_shm'} eq 'define';
use IPC::SysV qw(shmat shmdt memread memwrite ftok);
# Very first time called after machine is booted value may be 0
unless (defined $shm && $shm >= 0) {
- skip(skip_or_die('shmget', $!), 10);
+ skip(skip_or_die('shmget', $!), 11);
}
pass("shm acquire");
break;
case ACC_IV:
if(is_product) {
- if(!SvNOK(sv) && SvIOK(sv) && (SvIV(sv) < IV_MAX / retiv)) {
+ if(retiv == 0 ||
+ (!SvNOK(sv) && SvIOK(sv) && (SvIV(sv) < IV_MAX / retiv))) {
retiv *= SvIV(sv);
break;
}
all any first min max minstr maxstr none notall product reduce sum sum0 shuffle
pairs unpairs pairkeys pairvalues pairmap pairgrep pairfirst
);
-our $VERSION = "1.42_01";
+our $VERSION = "1.42_02";
our $XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
use strict;
use List::Util;
-our $VERSION = "1.42_01"; # FIXUP
+our $VERSION = "1.42_02"; # FIXUP
$VERSION = eval $VERSION; # FIXUP
1;
dualvar isdual isvstring looks_like_number openhandle readonly set_prototype
tainted
);
-our $VERSION = "1.42_01";
+our $VERSION = "1.42_02";
$VERSION = eval $VERSION;
require List::Util; # List::Util loads the XS
subname set_subname
);
-our $VERSION = "1.42_01";
+our $VERSION = "1.42_02";
$VERSION = eval $VERSION;
require List::Util; # as it has the XS
use strict;
use warnings;
-use Test::More tests => 13;
+use Test::More tests => 14;
use List::Util qw(product);
$v = product(-1);
is( $v, -1, 'one -1');
+$v = product(0, 1, 2);
+is( $v, 0, 'first factor zero' );
+
my $x = -3;
$v = product($x, 3);
use strict;
{ use 5.006001; }
-our $VERSION = '2.020_02'; # patched in perl5.git
+our $VERSION = '2.020_03'; # patched in perl5.git
=head1 NAME
# else
const int maxlen = (int)sizeof(addr.sun_path);
# endif
- for (addr_len = 0; addr.sun_path[addr_len]
- && addr_len < maxlen; addr_len++);
+ for (addr_len = 0; addr_len < maxlen
+ && addr.sun_path[addr_len]; addr_len++);
}
ST(0) = sv_2mortal(newSVpvn(addr.sun_path, addr_len));
use vars qw( $VERSION @ISA );
use vars qw( @EXPORT @EXPORT_OK @EXPORT_FAIL %EXPORT_TAGS );
-$VERSION= '0.1202';
+$VERSION= '0.1203';
use base qw( Exporter DynaLoader Tie::Handle IO::File );
if ($@) {
return tie *{$fh}, __PACKAGE__, $osfh;
}
- return undef if $fd < 0;
- return open( $fh, $pref."&=".$fd );
+ return undef unless $fd;
+ return open( $fh, $pref."&=".(0+$fd) );
}
sub GetOsFHandle {
-#!/usr/bin/perl -w
-use 5.001; #not tested
-use ExtUtils::MakeMaker;
-use Config;
-use strict;
-# See lib/ExtUtils/MakeMaker.pm for details of how to influence
-# the contents of the Makefile that is written.
-unless ($^O eq "MSWin32" || $^O eq "cygwin" || $^O eq "interix") { #not tested on Interix
- die "OS unsupported\n";
-}
-
-WriteMakefile1(
- 'NAME' => 'Win32API::File',
- 'VERSION_FROM' => 'File.pm', # finds $VERSION
- ( $Config{archname} =~ /-object\b/i ? ( 'CAPI' => 'TRUE' ) : () ),
- 'AUTHOR' => 'Tye McQueen <tye@metronet.com>',
- 'ABSTRACT_FROM' => 'File.pm',
- 'postamble' => { IMPORT_LIST => [qw(/._/ !/[a-z]/ :MEDIA_TYPE)],
- IFDEF => "!/[a-z\\d]/",
- CPLUSPLUS => 1,
- WRITE_PERL => 1,
- #PERL_FILE_LIST => ['File.pm'], #added by Chorny
- #C_FILE_LIST => ['File.xs'], #added by Chorny
- # Comment out next line to rebuild constants defs:
- NO_REBUILD => 1,
- },
- ( ! $Config{libperl} ? () : ( LIBPERL_A => $Config{libperl} ) ),
- 'INSTALLDIRS' => (($] >= 5.008009 and $] < 5.012) ? 'perl' : 'site'),
- 'LICENSE' => 'perl',
- 'MIN_PERL_VERSION' => 5.001,
- 'PREREQ_PM' => {
- 'Math::BigInt' => 0,
- 'Win32' => 0,
- 'Carp' => 0,
- 'IO::File' => 0,
- },
- TEST_REQUIRES => {
- 'File::Spec' => 0,
- 'Test::More' => 0,
- },
-
- META_MERGE => {
- resources => {
- repository => 'http://github.com/chorny/Win32API-File',
- },
- },
- $^O =~/win/i ? (
- dist => {
- TAR => 'ptar',
- TARFLAGS => '-c -C -f',
- },
- ) : (),
-);
-
-# Replacement for MakeMaker's "const2perl section" for versions
-# of MakeMaker prior to the addition of this functionality:
-sub MY::postamble
-{
- my( $self, %attribs )= @_;
-
- # Don't do anything if MakeMaker has const2perl
- # that already took care of all of this:
- return unless %attribs;
-
- # Don't require these here if we just C<return> above:
- eval "use ExtUtils::Myconst2perl qw(ParseAttribs); 1" or die "$@";
- eval "use ExtUtils::MakeMaker qw(neatvalue); 1" or die "$@";
-
- # If only one module, can skip one level of indirection:
- my $hvAttr= \%attribs;
- if( $attribs{IMPORT_LIST} ) {
- $hvAttr= { $self->{NAME} => \%attribs };
- }
-
- my( $module, @m, $_final, @clean, @realclean );
- foreach $module ( keys %$hvAttr ) {
- my( $outfile, @perlfiles, @cfiles, $bin, $obj, $final, $noreb );
-
- # Translate user-friendly options into coder-friendly specifics:
- ParseAttribs( $module, $hvAttr->{$module}, { OUTFILE => \$outfile,
- C_FILE_LIST => \@perlfiles, PERL_FILE_LIST => \@cfiles,
- OBJECT => \$obj, BINARY => \$bin, FINAL_PERL => \$final,
- NO_REBUILD => \$noreb } );
- die "IFDEF option in Makefile.PL must be string, not code ref.\n"
- if ref $hvAttr->{$module}->{IFDEF};
- die qq{IFDEF option in Makefile.PL must not contain quotes (").\n}
- if ref $hvAttr->{$module}->{IFDEF};
-
- # How to create F<$outfile> via ExtUtils::Myconst2perl::Myconst2perl:
- push @m, "
-$outfile: @perlfiles @cfiles Makefile" . '
- $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -MExtUtils::Myconst2perl \\
- -e "my %attribs;" \\
- ';
- $m[-1] =~ s/^/##/gm if $noreb;
- my( $key, $value );
- while( ( $key, $value )= each %{$hvAttr->{$module}} ) {
- push @m, '-e "$$attribs{' . $key . '}= ' # try {{ }} for dmake
- . neatvalue($value) . qq[;" \\\n\t ];
- $m[-1] =~ s/^/##/gm if $noreb;
- }
- push @m, '-e "Myconst2perl(' . neatvalue($module) . ",%attribs)\"\n";
-
- # If requested extra work to generate Perl instead of XS code:
- if( $bin ) {
- my @path= split /::/, $module;
- my $_final= $final;
- $_final =~ s/\W/_/g;
-
- # How to compile F<$outfile> and then run it to produce F<$final>:
- push @m, "
-$bin: $outfile" . '
- $(CC) $(INC) $(CCFLAGS) $(OPTIMIZE) $(PERLTYPE) $(LARGE) \\
- $(SPLIT) $(DEFINE_VERSION) $(XS_DEFINE_VERSION) -I$(PERL_INC) \\
- $(DEFINE)' . $outfile . " "
- . $self->catfile(qw[ $(PERL_INC) $(LIBPERL_A) ]) . " -o $bin
-
-$final: $bin
- " . $self->catfile(".",$bin) . " >$final\n";
- $m[-1] =~ s/^/##/gm if $noreb;
-
- # Make sure the rarely-used $(INST_ARCHLIB) directory exists:
- push @m, $self->dir_target('$(INST_ARCHLIB)');
-
- ##warn qq{$path[-1].pm should C<require "},
- ## join("/",@path,$final), qq{">.\n};
- # Install F<$final> whenever regular pm_to_blib target is built:
- push @m, "
-pm_to_blib: ${_final}_to_blib
-
-${_final}_to_blib: $final
- " . '@$(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" \\
- "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -MExtUtils::Install \\
- -e "pm_to_blib({ ',neatvalue($final),',',
- neatvalue($self->catfile('$(INST_ARCHLIB)',@path,$final)), ' },',
- neatvalue($self->catfile(qw[$(INST_LIB) auto])), ')"
- @$(TOUCH) ', $_final, "_to_blib
-
-realclean ::
- $self->{RM_RF} ", $self->catfile('$(INST_ARCHLIB)', $path[0]), "\n";
-
- push( @clean, $outfile, $bin, $obj, $_final . "_to_blib" );
- push( @realclean, $final ) unless $noreb;
- } else {
-
- ##my $name= ( split /::/, $module )[-1];
- ##warn qq{$name.xs should C<#include "$final"> },
- ## qq{in the C<BOOT:> section\n};
- push( @realclean, $outfile ) unless $noreb;
- }
- }
-
- push @m, "
-clean ::
- $self->{RM_F} @clean\n" if @clean;
- push @m, "
-realclean ::
- $self->{RM_F} @realclean\n" if @realclean;
- return join('',@m);
-}
-
-
-sub WriteMakefile1 { #Compatibility code for old versions of EU::MM. Written by Alexandr Ciornii, version 0.23. Added by eumm-upgrade.
- my %params=@_;
- my $eumm_version=$ExtUtils::MakeMaker::VERSION;
- $eumm_version=eval $eumm_version;
- die "EXTRA_META is deprecated" if exists $params{EXTRA_META};
- die "License not specified" if not exists $params{LICENSE};
- if ($params{AUTHOR} and ref($params{AUTHOR}) eq 'ARRAY' and $eumm_version < 6.5705) {
- $params{META_ADD}->{author}=$params{AUTHOR};
- $params{AUTHOR}=join(', ',@{$params{AUTHOR}});
- }
- if ($params{TEST_REQUIRES} and $eumm_version < 6.64) {
- $params{BUILD_REQUIRES}={ %{$params{BUILD_REQUIRES} || {}} , %{$params{TEST_REQUIRES}} };
- delete $params{TEST_REQUIRES};
- }
- if ($params{BUILD_REQUIRES} and $eumm_version < 6.5503) {
- #EUMM 6.5502 has problems with BUILD_REQUIRES
- $params{PREREQ_PM}={ %{$params{PREREQ_PM} || {}} , %{$params{BUILD_REQUIRES}} };
- delete $params{BUILD_REQUIRES};
- }
- delete $params{CONFIGURE_REQUIRES} if $eumm_version < 6.52;
- delete $params{MIN_PERL_VERSION} if $eumm_version < 6.48;
- delete $params{META_MERGE} if $eumm_version < 6.46;
- delete $params{META_ADD} if $eumm_version < 6.46;
- delete $params{LICENSE} if $eumm_version < 6.31;
- delete $params{AUTHOR} if $] < 5.005;
- delete $params{ABSTRACT_FROM} if $] < 5.005;
- delete $params{BINARY_LOCATION} if $] < 5.005;
-
- WriteMakefile(%params);
-}
-
+#!/usr/bin/perl -w\r
+use 5.001; #not tested\r
+use ExtUtils::MakeMaker;\r
+use Config;\r
+use strict;\r
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence\r
+# the contents of the Makefile that is written.\r
+unless ($^O eq "MSWin32" || $^O eq "cygwin" || $^O eq "interix") { #not tested on Interix\r
+ die "OS unsupported\n";\r
+}\r
+\r
+WriteMakefile1(\r
+ 'NAME' => 'Win32API::File',\r
+ 'VERSION_FROM' => 'File.pm', # finds $VERSION\r
+ ( $Config{archname} =~ /-object\b/i ? ( 'CAPI' => 'TRUE' ) : () ),\r
+ 'AUTHOR' => 'Tye McQueen <tye@metronet.com>',\r
+ 'ABSTRACT_FROM' => 'File.pm',\r
+ 'postamble' => { IMPORT_LIST => [qw(/._/ !/[a-z]/ :MEDIA_TYPE)],\r
+ IFDEF => "!/[a-z\\d]/",\r
+ CPLUSPLUS => 1,\r
+ WRITE_PERL => 1,\r
+ #PERL_FILE_LIST => ['File.pm'], #added by Chorny\r
+ #C_FILE_LIST => ['File.xs'], #added by Chorny\r
+ # Comment out next line to rebuild constants defs:\r
+ NO_REBUILD => 1,\r
+ },\r
+ ( ! $Config{libperl} ? () : ( LIBPERL_A => $Config{libperl} ) ),\r
+ 'INSTALLDIRS' => (($] >= 5.008009 and $] < 5.012) ? 'perl' : 'site'),\r
+ 'LICENSE' => 'perl',\r
+ 'MIN_PERL_VERSION' => 5.001,\r
+ 'PREREQ_PM' => {\r
+ 'Math::BigInt' => 0,\r
+ 'Win32' => 0,\r
+ 'Carp' => 0,\r
+ 'IO::File' => 0,\r
+ },\r
+ TEST_REQUIRES => {\r
+ 'File::Spec' => 0,\r
+ 'Test::More' => 0,\r
+ },\r
+\r
+ META_MERGE => {\r
+ resources => {\r
+ repository => 'http://github.com/chorny/Win32API-File',\r
+ },\r
+ },\r
+ $^O =~/win/i ? (\r
+ dist => {\r
+ TAR => 'ptar',\r
+ TARFLAGS => '-c -C -f',\r
+ },\r
+ ) : (),\r
+);\r
+\r
+# Replacement for MakeMaker's "const2perl section" for versions\r
+# of MakeMaker prior to the addition of this functionality:\r
+sub MY::postamble\r
+{\r
+ my( $self, %attribs )= @_;\r
+\r
+ # Don't do anything if MakeMaker has const2perl\r
+ # that already took care of all of this:\r
+ return unless %attribs;\r
+\r
+ # Don't require these here if we just C<return> above:\r
+ eval "use lib 'inc'; use ExtUtils::Myconst2perl qw(ParseAttribs); 1" or die "$@";\r
+ eval "use ExtUtils::MakeMaker qw(neatvalue); 1" or die "$@";\r
+\r
+ # If only one module, can skip one level of indirection:\r
+ my $hvAttr= \%attribs;\r
+ if( $attribs{IMPORT_LIST} ) {\r
+ $hvAttr= { $self->{NAME} => \%attribs };\r
+ }\r
+\r
+ my( $module, @m, $_final, @clean, @realclean );\r
+ foreach $module ( keys %$hvAttr ) {\r
+ my( $outfile, @perlfiles, @cfiles, $bin, $obj, $final, $noreb );\r
+\r
+ # Translate user-friendly options into coder-friendly specifics:\r
+ ParseAttribs( $module, $hvAttr->{$module}, { OUTFILE => \$outfile,\r
+ C_FILE_LIST => \@perlfiles, PERL_FILE_LIST => \@cfiles,\r
+ OBJECT => \$obj, BINARY => \$bin, FINAL_PERL => \$final,\r
+ NO_REBUILD => \$noreb } );\r
+ die "IFDEF option in Makefile.PL must be string, not code ref.\n"\r
+ if ref $hvAttr->{$module}->{IFDEF};\r
+ die qq{IFDEF option in Makefile.PL must not contain quotes (").\n}\r
+ if ref $hvAttr->{$module}->{IFDEF};\r
+\r
+ # How to create F<$outfile> via ExtUtils::Myconst2perl::Myconst2perl:\r
+ push @m, "\r
+$outfile: @perlfiles @cfiles Makefile" . '\r
+ $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -MExtUtils::Myconst2perl \\\r
+ -e "my %attribs;" \\\r
+ ';\r
+ $m[-1] =~ s/^/##/gm if $noreb;\r
+ my( $key, $value );\r
+ while( ( $key, $value )= each %{$hvAttr->{$module}} ) {\r
+ push @m, '-e "$$attribs{' . $key . '}= ' # try {{ }} for dmake\r
+ . neatvalue($value) . qq[;" \\\n\t ];\r
+ $m[-1] =~ s/^/##/gm if $noreb;\r
+ }\r
+ push @m, '-e "Myconst2perl(' . neatvalue($module) . ",%attribs)\"\n";\r
+\r
+ # If requested extra work to generate Perl instead of XS code:\r
+ if( $bin ) {\r
+ my @path= split /::/, $module;\r
+ my $_final= $final;\r
+ $_final =~ s/\W/_/g;\r
+\r
+ # How to compile F<$outfile> and then run it to produce F<$final>:\r
+ push @m, "\r
+$bin: $outfile" . '\r
+ $(CC) $(INC) $(CCFLAGS) $(OPTIMIZE) $(PERLTYPE) $(LARGE) \\\r
+ $(SPLIT) $(DEFINE_VERSION) $(XS_DEFINE_VERSION) -I$(PERL_INC) \\\r
+ $(DEFINE)' . $outfile . " "\r
+ . $self->catfile(qw[ $(PERL_INC) $(LIBPERL_A) ]) . " -o $bin\r
+\r
+$final: $bin\r
+ " . $self->catfile(".",$bin) . " >$final\n";\r
+ $m[-1] =~ s/^/##/gm if $noreb;\r
+\r
+ # Make sure the rarely-used $(INST_ARCHLIB) directory exists:\r
+ push @m, $self->dir_target('$(INST_ARCHLIB)');\r
+\r
+ ##warn qq{$path[-1].pm should C<require "},\r
+ ## join("/",@path,$final), qq{">.\n};\r
+ # Install F<$final> whenever regular pm_to_blib target is built:\r
+ push @m, "\r
+pm_to_blib: ${_final}_to_blib\r
+\r
+${_final}_to_blib: $final\r
+ " . '@$(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" \\\r
+ "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -MExtUtils::Install \\\r
+ -e "pm_to_blib({ ',neatvalue($final),',',\r
+ neatvalue($self->catfile('$(INST_ARCHLIB)',@path,$final)), ' },',\r
+ neatvalue($self->catfile(qw[$(INST_LIB) auto])), ')"\r
+ @$(TOUCH) ', $_final, "_to_blib\r
+\r
+realclean ::\r
+ $self->{RM_RF} ", $self->catfile('$(INST_ARCHLIB)', $path[0]), "\n";\r
+\r
+ push( @clean, $outfile, $bin, $obj, $_final . "_to_blib" );\r
+ push( @realclean, $final ) unless $noreb;\r
+ } else {\r
+\r
+ ##my $name= ( split /::/, $module )[-1];\r
+ ##warn qq{$name.xs should C<#include "$final"> },\r
+ ## qq{in the C<BOOT:> section\n};\r
+ push( @realclean, $outfile ) unless $noreb;\r
+ }\r
+ }\r
+\r
+ push @m, "\r
+clean ::\r
+ $self->{RM_F} @clean\n" if @clean;\r
+ push @m, "\r
+realclean ::\r
+ $self->{RM_F} @realclean\n" if @realclean;\r
+ return join('',@m);\r
+}\r
+\r
+\r
+sub WriteMakefile1 { #Compatibility code for old versions of EU::MM. Written by Alexandr Ciornii, version 0.23. Added by eumm-upgrade.\r
+ my %params=@_;\r
+ my $eumm_version=$ExtUtils::MakeMaker::VERSION;\r
+ $eumm_version=eval $eumm_version;\r
+ die "EXTRA_META is deprecated" if exists $params{EXTRA_META};\r
+ die "License not specified" if not exists $params{LICENSE};\r
+ if ($params{AUTHOR} and ref($params{AUTHOR}) eq 'ARRAY' and $eumm_version < 6.5705) {\r
+ $params{META_ADD}->{author}=$params{AUTHOR};\r
+ $params{AUTHOR}=join(', ',@{$params{AUTHOR}});\r
+ }\r
+ if ($params{TEST_REQUIRES} and $eumm_version < 6.64) {\r
+ $params{BUILD_REQUIRES}={ %{$params{BUILD_REQUIRES} || {}} , %{$params{TEST_REQUIRES}} };\r
+ delete $params{TEST_REQUIRES};\r
+ }\r
+ if ($params{BUILD_REQUIRES} and $eumm_version < 6.5503) {\r
+ #EUMM 6.5502 has problems with BUILD_REQUIRES\r
+ $params{PREREQ_PM}={ %{$params{PREREQ_PM} || {}} , %{$params{BUILD_REQUIRES}} };\r
+ delete $params{BUILD_REQUIRES};\r
+ }\r
+ delete $params{CONFIGURE_REQUIRES} if $eumm_version < 6.52;\r
+ delete $params{MIN_PERL_VERSION} if $eumm_version < 6.48;\r
+ delete $params{META_MERGE} if $eumm_version < 6.46;\r
+ delete $params{META_ADD} if $eumm_version < 6.46;\r
+ delete $params{LICENSE} if $eumm_version < 6.31;\r
+ delete $params{AUTHOR} if $] < 5.005;\r
+ delete $params{ABSTRACT_FROM} if $] < 5.005;\r
+ delete $params{BINARY_LOCATION} if $] < 5.005;\r
+\r
+ WriteMakefile(%params);\r
+}\r
+\r
-/* buffers.h -- Version 1.11 */
-
-/* The following abbreviations are used at start of parameter names
- * to indicate the type of data:
- * s string (char * or WCHAR *) [PV]
- * sw wide string (WCHAR *) [PV]
- * p pointer (usually to some structure) [PV]
- * a array (packed array as in C) (usually of some structure) [PV]
- * called a "vector" or "vect" in some places.
- * n generic number [IV, UV, or NV]
- * iv signed integral value [IV]
- * u unsigned integral value [UV]
- * d floating-point number (double) [NV]
- * b boolean (bool) [IV]
- * c count of items [UV]
- * l length (in bytes) [UV]
- * lw length in WCHARs [UV]
- * h a handle [IV]
- * r record (structure) [PV]
- * sv Perl scalar (s, i, u, d, n, or rv) [SV]
- * rv Perl reference (usually to scalar) [RV]
- * hv reference to Perl hash [HV]
- * av reference to Perl array [AV]
- * cv Perl code reference [PVCV]
- *
- * Unusual combined types:
- * pp single pointer (to non-Perl data) packed into string [PV]
- * pap vector of pointers (to non-Perl data) packed into string [PV]
- *
- * Whether a parameter is for input data, output data, or both is usually
- * not reflected by the data type prefix. In cases where this is not
- * obvious nor reflected in the variable name proper, you can use
- * the following in front of the data type prefix:
- * i an input parameter given to API (usually omitted)
- * o an Output parameter taken from API
- * io Input given to API then overwritten with Output taken from API
- */
-
-/* Buffer arguments are usually followed by an argument (or two) specifying
- * their size and/or returning the size of data written. The size can be
- * measured in bytes ["lSize"] or in characters [for (char *) buffers such as
- * for *A() routines, these sizes are also called "lSize", but are called
- * "lwSize" for (WCHAR *) buffers, UNICODE strings, such as for *W() routines].
- *
- * Before calling the actual C function, you must make sure the Perl variable
- * actually has a big enough buffer allocated, and, if the user didn't want
- * to specify a buffer size, set the buffer size to be correct. This is what
- * the grow_*() macros are for. They also handle special meanings of the
- * buffer size argument [described below].
- *
- * Once the actual C function returns, you must set the Perl variable to know
- * the size of the written data. This is what the trunc_*() macros are for.
- *
- * The size sometimes does and sometimes doesn't include the trailing '\0'
- * [or L'\0'], so we always add or subtract 1 in the appropriate places so
- * we don't care about this detail.
- *
- * A call may 1) request a pointer to the buffer size which means that
- * the buffer size will be overwritten with the size of the data written;
- * 2) have an extra argument which is a pointer to the place to write the
- * size of the written data; 3) provide the size of the written data in
- * the function's return value; 4) format the data so that the length
- * can be determined by examining the data [such as with '\0'-terminated
- * strings]; or 5) write fixed-length data [usually sizeof(STRUCT)].
- * This obviously determines what you should use in the trunc_*() macro
- # to specify the size of the output value.
- *
- * The user can pass in an empty list reference, C<[]>, to indicate C<NULL>
- * for the pointer to the buffer which means that they don't want that data.
- *
- * The user can pass in C<[]> or C<0> to indicate that they don't care about
- * the buffer size [we aren't programming in C here, after all] and just try
- * to get the data. This will work if either the buffer already allocated for
- * the SV [scalar value] is large enough to hold the data or the API provides
- * an easy way to determine the required size [and the XS code uses it].
- *
- * If the user passes in a numeric value for a buffer size, then the XS
- * code makes sure that the buffer is at least large enough to hold a value
- * of that size and then passes in how large the buffer is. So the buffer
- * size passed to the API call is the larger of the size requested by the
- * user and the size of the buffer aleady allocated to the SV.
- *
- * The user can also pass in a string consisting of a leading "=" followed
- * by digits for a buffer size. This means just use the size specified after
- * the equals sign, even if the allocated buffer is larger. The XS code will
- * still allocate a large enough buffer before the first call.
- *
- * If the function is nice enough to tell us that a buffer was too small
- * [usually via ERROR_MORE_DATA] _and_ how large the buffer needs to be,
- * then the XS code should enlarge the buffer(s) and repeat the call [once].
- * This resizing is _not_ done for buffers whose size was specified with a
- * leading "=".
- *
- * Only grow_buf() and perhaps trunc_buf() can be used in a typemap file.
- * The other macros would be used in the parameter declarations or INPUT:
- * section [grow_*()], the INIT: section [init_*()], or the OUTPUT: section
- * [trunc_*()].
- *
- * Buffer arguments should be initialised with C<= NO_INIT> [or C<= NULL;>].
- *
- * See also the F<typemap> file. C<oDWORD>, for example, is for an output-
- * only parameter of type C<DWORD> and you should simply C<#define> it to be
- * C<DWORD>. In F<typemap>, C<oDWORD> is treated differently than C<DWORD>
- * in two ways.
- *
- * First, if C<undef> is passed in, a C<DWORD> could generate a warning
- * when it gets converted to 0 while C<oDWORD> will never generate such a
- * warning for C<undef>. This first difference doesn't apply if specific
- * initialization is specified for the variable, as in C<= init_buf_l($var);>.
- * In particular, the init_*() macros also convert C<undef> to 0 without
- * ever producing a warning.
- *
- * Second, passing in a read-only SV for a C<oDWORD> parameter will generate
- * a fatal error on output when we try to update the SV. For C<DWORD>, we
- * won't update a read-only SV since passing in a literal constant for a
- * buffer size is a useful thing to do even though it prevents us from
- * returning the size of data written via that SV. Since we should use a
- * trunc_*() macro to output the actual data, the user should be able to
- * determine the size of data written based on the size of the scalar we
- * output anyway.
- *
- * This second difference doesn't apply unless the parameter is listed in
- * the OUTPUT: section without specific output instructions. We define
- * no macros for outputting buffer length parameters so be careful to use
- * C<oDWORD> [for example] for them if and only if they are output-only.
- *
- * Note that C<oDWORD> is the same as C<DWORD> in that, if a defined value
- * is passed in, it is used [and can generate a warning if the value is
- * "not numeric"]. So although C<oDWORD> is for output-only parameters,
- * we still initialize the C variable before calling the API. This is good
- * in case the parameter isn't always strictly output-only due to upgrades,
- * bugs, etc.
- *
- * Here is a made-up example that shows several cases:
- *
- * # Actual GetDataW() returns length of data written to ioswName, not bool.
- * bool
- * GetDataW( ioswName, ilwName, oswText, iolwText, opJunk, opRec, ilRec, olRec )
- * WCHAR * ioswName = NO_INIT
- * DWORD ilwName = NO_INIT
- * WCHAR * oswText = NO_INIT
- * DWORD &iolwText = init_buf_l($arg);
- * void * opJunk = NO_INIT
- * BYTE * opRec = NO_INIT
- * DWORD ilRec = init_buf_l($arg);
- * oDWORD &olRec
- * PREINIT:
- * DWORD olwName;
- * INIT:
- * grow_buf_lw( ioswName,ST(0), ilwName,ST(1) );
- * grow_buf_lw( oswText,ST(2), iolwText,ST(3) );
- * grow_buf_typ( opJunk,ST(4),void *, LONG_STRUCT_TYPEDEF );
- * grow_buf_l( opRec,ST(5),BYTE *, ilRec,ST(6) );
- * CODE:
- * olwName= GetDataW( ioswName, ilwName, oswText, &iolwText,
- * (LONG_STRUCT_TYPEDEF *)opJunk, opRec, &iolRec );
- * if( 0 == olwName && ERROR_MORE_DATA == GetLastError()
- * && ( autosize(ST(1)) || autosize(ST(3)) || autosize(ST(6)) ) ) {
- * if( autosize(ST(1)) )
- * grow_buf_lw( ioswName,ST(0), ilwName,ST(1) );
- * if( autosize(ST(3)) )
- * grow_buf_lw( oswText,ST(2), iolwText,ST(3) );
- * if( autosize(ST(6)) )
- * grow_buf_l( opRec,ST(5),BYTE *, iolRec,ST(6) );
- * olwName= GetDataW( ioswName, ilwName, oswText, &iolwText,
- * (LONG_STRUCT_TYPEDEF *)opJunk, opRec, &iolRec );
- * }
- * RETVAL= 0 != olwName;
- * OUTPUT:
- * RETVAL
- * ioswName trunc_buf_lw( RETVAL, ioswName,ST(0), olwName );
- * oswText trunc_buf_lw( RETVAL, oswText,ST(2), iolwText );
- * iolwText
- * opJunk trunc_buf_typ(RETVAL,opJunk,ST(4),LONG_STRUCT_TYPEDEF);
- * opRec trunc_buf_l( RETVAL, opRec,ST(5), olRec );
- * olRec
- *
- * The above example would be more complex and less efficient if we used
- * C<DWORD * iolwText> in place of C<DWORD &iolwText>. The only possible
- * advantage would be that C<NULL> would be passed in for C<iolwText> if
- * _both_ C<$oswText> and C<$iolwText> were specified as C<[]>. The *_pl*()
- * macros are defined [and C<DWORD *> specified in F<typemap>] so we can
- * handle those cases but it is usually better to use the *_l*() macros
- * instead by specifying C<&> instead of C<*>. Using C<&> instead of C<*>
- * is usually better when dealing with scalars, even if they aren't buffer
- * sizes. But you must use C<*> if it is important for that parameter to
- * be able to pass C<NULL> to the underlying API.
- *
- * In Win32API::, we try to use C<*> for buffer sizes of optional buffers
- * and C<&> for buffer sizes of required buffers.
- *
- * For parameters that are pointers to things other than buffers or buffer
- * sizes, we use C<*> for "important" parameters [so that using C<[]>
- * generates an error rather than fetching the value and just throwing it
- * away], and for optional parameters [in case specifying C<NULL> is or
- * becomes important]. Otherwise we use C<&> [for "unimportant" but
- * required parameters] so the user can specify C<[]> if they don't care
- * about it. The output handle of an "open" routine is "important".
- */
-
-#ifndef Debug
-# define Debug(list) /*Nothing*/
-#endif
-
-/*#ifndef CAST
- *# ifdef __cplusplus
- *# define CAST(type,expr) static_cast<type>(expr)
- *# else*/
-# define CAST(type,expr) (type)(expr)
-/*# endif
- *#endif*/
-
-/* Is an argument C<[]>, meaning we should pass C<NULL>? */
-#define null_arg(sv) ( SvROK(sv) && SVt_PVAV == SvTYPE(SvRV(sv)) \
- && -1 == av_len((AV*)SvRV(sv)) )
-
-#define PV_or_null(sv) ( null_arg(sv) ? NULL : SvPV_nolen(sv) )
-
-/* Minimum buffer size to use when no buffer existed: */
-#define MIN_GROW_SIZE 128
-
-#ifdef Debug
-/* Used in Debug() messages to show which macro call is involved: */
-#define string(arg) #arg
-#endif
-
-/* Simplify using SvGROW() for byte-sized buffers: */
-#define lSvGROW(sv,n) SvGROW( sv, 0==(n) ? MIN_GROW_SIZE : (n)+1 )
-
-/* Simplify using SvGROW() for WCHAR-sized buffers: */
-#define lwSvGROW(sv,n) CAST( WCHAR *, \
- SvGROW( sv, sizeof(WCHAR)*( 0==(n) ? MIN_GROW_SIZE : (n)+1 ) ) )
-
-/* Whether the buffer size we got lets us change what buffer size we use: */
-#define autosize(sv) (!( SvOK(sv) && ! SvROK(sv) \
- && SvPV_nolen(sv) && '=' == *SvPV_nolen(sv) ))
-
-/* Get the IV/UV for a parameter that might be C<[]> or C<undef>: */
-#define optIV(sv) ( null_arg(sv) ? 0 : !SvOK(sv) ? 0 : SvIV(sv) )
-#define optUV(sv) ( null_arg(sv) ? 0 : !SvOK(sv) ? 0 : SvUV(sv) )
-
-/* Allocate temporary storage that will automatically be freed later: */
-#ifndef TempAlloc /* Can be C<#define>d to be C<_alloca>, for example */
-# define TempAlloc( size ) sv_grow( sv_newmortal(), size )
-#endif
-
-/* Initialize a buffer size argument of type (DWORD *): */
-#define init_buf_pl( plSize, svSize, tpSize ) STMT_START { \
- if( null_arg(svSize) ) \
- plSize= NULL; \
- else { \
- STRLEN n_a; \
- *( plSize= CAST( tpSize, TempAlloc(sizeof(*plSize)) ) )= \
- autosize(svSize) ? optUV(svSize) \
- : strtoul( 1+SvPV(svSize,n_a), NULL, 10 ); \
- } } STMT_END
-/* In INPUT section put ": init_buf_pl($var,$arg,$type);" after var name. */
-
-/* Initialize a buffer size argument of type DWORD: */
-#define init_buf_l( svSize ) \
- ( null_arg(svSize) ? 0 : autosize(svSize) ? optUV(svSize) \
- : strtoul( 1+SvPV_nolen(svSize), NULL, 10 ) )
-/* In INPUT section put "= init_buf_l($arg);" after variable name. */
-
-/* Lengths in WCHARs are initialized the same as lengths in bytes: */
-#define init_buf_plw init_buf_pl
-#define init_buf_lw init_buf_l
-
-/* grow_buf_pl() and grow_buf_plw() are included so you can define
- * parameters of type C<DWORD *>, for example. In practice, it is
- * usually better to define such parameters as "DWORD &". */
-
-/* Grow a buffer where we have a pointer to its size in bytes: */
-#define grow_buf_pl( sBuf,svBuf,tpBuf, plSize,svSize,tpSize ) STMT_START { \
- Debug(("grow_buf_pl( %s==0x%lX,[%s:%ld/%ld, %s==0x%lX:%ld,[%s )\n",\
- string(sBuf),sBuf,strchr(string(svBuf),'('),SvPOK(svBuf)? \
- SvCUR(svBuf):-1,SvPOK(svBuf)?SvLEN(svBuf):-1,string(plSize), \
- plSize,plSize?*plSize:-1,strchr(string(svSize),'('))); \
- if( null_arg(svBuf) ) { \
- sBuf= NULL; \
- } else { \
- STRLEN n_a; \
- if( NULL == plSize ) \
- *( plSize= CAST(tpSize,TempAlloc(sizeof(*plSize))) )= 0;\
- if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \
- (void) SvPV_force( svBuf, n_a ); \
- sBuf= CAST( tpBuf, lSvGROW( svBuf, *plSize ) ); \
- if( autosize(svSize) ) *plSize= SvLEN(svBuf) - 1; \
- Debug(("more buf_pl( %s==0x%lX,[%s:%ld/%ld, %s==0x%lX:%ld,[%s )\n",\
- string(sBuf),sBuf,strchr(string(svBuf),'('),SvPOK(svBuf)? \
- SvCUR(svBuf):-1,SvPOK(svBuf)?SvLEN(svBuf):-1,string(plSize),\
- plSize,plSize?*plSize:-1,strchr(string(svSize),'('))); \
- } } STMT_END
-
-/* Grow a buffer where we have a pointer to its size in WCHARs: */
-#define grow_buf_plw( sBuf,svBuf, plwSize,svSize,tpSize ) STMT_START { \
- if( null_arg(svBuf) ) { \
- sBuf= NULL; \
- } else { \
- STRLEN n_a; \
- if( NULL == plwSize ) \
- *( plwSize= CAST(tpSize,TempAlloc(sizeof(*plwSize))) )= 0;\
- if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \
- (void) SvPV_force( svBuf, n_a ); \
- sBuf= lwSvGROW( svBuf, *plwSize ); \
- if( autosize(svSize) ) \
- *plwSize= SvLEN(svBuf)/sizeof(WCHAR) - 1; \
- } } STMT_END
-
-/* Grow a buffer where we have its size in bytes: */
-#define grow_buf_l( sBuf,svBuf,tpBuf, lSize,svSize ) STMT_START { \
- if( null_arg(svBuf) ) { \
- sBuf= NULL; \
- } else { \
- STRLEN n_a; \
- if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \
- (void) SvPV_force( svBuf, n_a ); \
- sBuf= CAST( tpBuf, lSvGROW( svBuf, lSize ) ); \
- if( autosize(svSize) ) lSize= SvLEN(svBuf) - 1; \
- } } STMT_END
-
-/* Grow a buffer where we have its size in WCHARs: */
-#define grow_buf_lw( swBuf,svBuf, lwSize,svSize ) STMT_START { \
- if( null_arg(svBuf) ) { \
- swBuf= NULL; \
- } else { \
- STRLEN n_a; \
- if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \
- (void) SvPV_force( svBuf, n_a ); \
- swBuf= lwSvGROW( svBuf, lwSize ); \
- if( autosize(svSize) ) \
- lwSize= SvLEN(svBuf)/sizeof(WCHAR) - 1; \
- } } STMT_END
-
-/* Grow a buffer that contains the declared fixed data type: */
-#define grow_buf( pBuf,svBuf, tpBuf ) STMT_START { \
- if( null_arg(svBuf) ) { \
- pBuf= NULL; \
- } else { \
- STRLEN n_a; \
- if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \
- (void) SvPV_force( svBuf, n_a ); \
- pBuf= CAST( tpBuf, SvGROW( svBuf, sizeof(*pBuf) ) ); \
- } } STMT_END
-
-/* Grow a buffer that contains a fixed data type other than that declared: */
-#define grow_buf_typ( pBuf,svBuf,tpBuf, Type ) STMT_START { \
- if( null_arg(svBuf) ) { \
- pBuf= NULL; \
- } else { \
- STRLEN n_a; \
- if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \
- (void) SvPV_force( svBuf, n_a ); \
- pBuf= CAST( tpBuf, SvGROW( svBuf, sizeof(Type) ) ); \
- } } STMT_END
-
-/* Grow a buffer that contains a list of items of the declared data type: */
-#define grow_vect( pBuf,svBuf,tpBuf, cItems ) STMT_START { \
- if( null_arg(svBuf) ) { \
- pBuf= NULL; \
- } else { \
- STRLEN n_a; \
- if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \
- (void) SvPV_force( svBuf, n_a ); \
- pBuf= CAST( tpBuf, SvGROW( svBuf, sizeof(*pBuf)*cItems ) ); \
- } } STMT_END
-
-/* If call succeeded, set data length to returned length (in bytes): */
-#define trunc_buf_l( bOkay, sBuf,svBuf, lSize ) STMT_START { \
- if( bOkay && NULL != sBuf ) { \
- SvPOK_only( svBuf ); \
- SvCUR_set( svBuf, lSize ); \
- } } STMT_END
-
-/* Same as above except we have a pointer to the returned length: */
-#define trunc_buf_pl( bOkay, sBuf,svBuf, plSize ) \
- trunc_buf_l( bOkay, sBuf,svBuf, *plSize )
-
-/* If call succeeded, set data length to returned length (in WCHARs): */
-#define trunc_buf_lw( bOkay, sBuf,svBuf, lwSize ) STMT_START { \
- if( bOkay && NULL != sBuf ) { \
- SvPOK_only( svBuf ); \
- SvCUR_set( svBuf, (lwSize)*sizeof(WCHAR) ); \
- } } STMT_END
-
-/* Same as above except we have a pointer to the returned length: */
-#define trunc_buf_plw( bOkay, swBuf,svBuf, plwSize ) \
- trunc_buf_lw( bOkay, swBuf,svBuf, *plwSize )
-
-/* Set data length for a buffer that contains the declared fixed data type: */
-#define trunc_buf( bOkay, pBuf,svBuf ) STMT_START { \
- if( bOkay && NULL != pBuf ) { \
- SvPOK_only( svBuf ); \
- SvCUR_set( svBuf, sizeof(*pBuf) ); \
- } } STMT_END
-
-/* Set data length for a buffer that contains some other fixed data type: */
-#define trunc_buf_typ( bOkay, pBuf,svBuf, Type ) STMT_START { \
- if( bOkay && NULL != pBuf ) { \
- SvPOK_only( svBuf ); \
- SvCUR_set( svBuf, sizeof(Type) ); \
- } } STMT_END
-
-/* Set length for buffer that contains list of items of the declared type: */
-#define trunc_vect( bOkay, pBuf,svBuf, cItems ) STMT_START { \
- if( bOkay && NULL != pBuf ) { \
- SvPOK_only( svBuf ); \
- SvCUR_set( svBuf, sizeof(*pBuf)*cItems ); \
- } } STMT_END
-
-/* Set data length for a buffer where a '\0'-terminate string was stored: */
-#define trunc_buf_z( bOkay, sBuf,svBuf ) STMT_START { \
- if( bOkay && NULL != sBuf ) { \
- SvPOK_only( svBuf ); \
- SvCUR_set( svBuf, strlen(sBuf) ); \
- } } STMT_END
-
-/* Set data length for a buffer where a L'\0'-terminate string was stored: */
-#define trunc_buf_zw( bOkay, sBuf,svBuf ) STMT_START { \
- if( bOkay && NULL != sBuf ) { \
- SvPOK_only( svBuf ); \
- SvCUR_set( svBuf, wcslen(sBuf)*sizeof(WCHAR) ); \
- } } STMT_END
+/* buffers.h -- Version 1.11 */\r
+\r
+/* The following abbreviations are used at start of parameter names\r
+ * to indicate the type of data:\r
+ * s string (char * or WCHAR *) [PV]\r
+ * sw wide string (WCHAR *) [PV]\r
+ * p pointer (usually to some structure) [PV]\r
+ * a array (packed array as in C) (usually of some structure) [PV]\r
+ * called a "vector" or "vect" in some places.\r
+ * n generic number [IV, UV, or NV]\r
+ * iv signed integral value [IV]\r
+ * u unsigned integral value [UV]\r
+ * d floating-point number (double) [NV]\r
+ * b boolean (bool) [IV]\r
+ * c count of items [UV]\r
+ * l length (in bytes) [UV]\r
+ * lw length in WCHARs [UV]\r
+ * h a handle [IV]\r
+ * r record (structure) [PV]\r
+ * sv Perl scalar (s, i, u, d, n, or rv) [SV]\r
+ * rv Perl reference (usually to scalar) [RV]\r
+ * hv reference to Perl hash [HV]\r
+ * av reference to Perl array [AV]\r
+ * cv Perl code reference [PVCV]\r
+ *\r
+ * Unusual combined types:\r
+ * pp single pointer (to non-Perl data) packed into string [PV]\r
+ * pap vector of pointers (to non-Perl data) packed into string [PV]\r
+ *\r
+ * Whether a parameter is for input data, output data, or both is usually\r
+ * not reflected by the data type prefix. In cases where this is not\r
+ * obvious nor reflected in the variable name proper, you can use\r
+ * the following in front of the data type prefix:\r
+ * i an input parameter given to API (usually omitted)\r
+ * o an Output parameter taken from API\r
+ * io Input given to API then overwritten with Output taken from API\r
+ */\r
+\r
+/* Buffer arguments are usually followed by an argument (or two) specifying\r
+ * their size and/or returning the size of data written. The size can be\r
+ * measured in bytes ["lSize"] or in characters [for (char *) buffers such as\r
+ * for *A() routines, these sizes are also called "lSize", but are called\r
+ * "lwSize" for (WCHAR *) buffers, UNICODE strings, such as for *W() routines].\r
+ *\r
+ * Before calling the actual C function, you must make sure the Perl variable\r
+ * actually has a big enough buffer allocated, and, if the user didn't want\r
+ * to specify a buffer size, set the buffer size to be correct. This is what\r
+ * the grow_*() macros are for. They also handle special meanings of the\r
+ * buffer size argument [described below].\r
+ *\r
+ * Once the actual C function returns, you must set the Perl variable to know\r
+ * the size of the written data. This is what the trunc_*() macros are for.\r
+ *\r
+ * The size sometimes does and sometimes doesn't include the trailing '\0'\r
+ * [or L'\0'], so we always add or subtract 1 in the appropriate places so\r
+ * we don't care about this detail.\r
+ *\r
+ * A call may 1) request a pointer to the buffer size which means that\r
+ * the buffer size will be overwritten with the size of the data written;\r
+ * 2) have an extra argument which is a pointer to the place to write the\r
+ * size of the written data; 3) provide the size of the written data in\r
+ * the function's return value; 4) format the data so that the length\r
+ * can be determined by examining the data [such as with '\0'-terminated\r
+ * strings]; or 5) write fixed-length data [usually sizeof(STRUCT)].\r
+ * This obviously determines what you should use in the trunc_*() macro\r
+ # to specify the size of the output value.\r
+ *\r
+ * The user can pass in an empty list reference, C<[]>, to indicate C<NULL>\r
+ * for the pointer to the buffer which means that they don't want that data.\r
+ *\r
+ * The user can pass in C<[]> or C<0> to indicate that they don't care about\r
+ * the buffer size [we aren't programming in C here, after all] and just try\r
+ * to get the data. This will work if either the buffer already allocated for\r
+ * the SV [scalar value] is large enough to hold the data or the API provides\r
+ * an easy way to determine the required size [and the XS code uses it].\r
+ *\r
+ * If the user passes in a numeric value for a buffer size, then the XS\r
+ * code makes sure that the buffer is at least large enough to hold a value\r
+ * of that size and then passes in how large the buffer is. So the buffer\r
+ * size passed to the API call is the larger of the size requested by the\r
+ * user and the size of the buffer already allocated to the SV.\r
+ *\r
+ * The user can also pass in a string consisting of a leading "=" followed\r
+ * by digits for a buffer size. This means just use the size specified after\r
+ * the equals sign, even if the allocated buffer is larger. The XS code will\r
+ * still allocate a large enough buffer before the first call.\r
+ *\r
+ * If the function is nice enough to tell us that a buffer was too small\r
+ * [usually via ERROR_MORE_DATA] _and_ how large the buffer needs to be,\r
+ * then the XS code should enlarge the buffer(s) and repeat the call [once].\r
+ * This resizing is _not_ done for buffers whose size was specified with a\r
+ * leading "=".\r
+ *\r
+ * Only grow_buf() and perhaps trunc_buf() can be used in a typemap file.\r
+ * The other macros would be used in the parameter declarations or INPUT:\r
+ * section [grow_*()], the INIT: section [init_*()], or the OUTPUT: section\r
+ * [trunc_*()].\r
+ *\r
+ * Buffer arguments should be initialised with C<= NO_INIT> [or C<= NULL;>].\r
+ *\r
+ * See also the F<typemap> file. C<oDWORD>, for example, is for an output-\r
+ * only parameter of type C<DWORD> and you should simply C<#define> it to be\r
+ * C<DWORD>. In F<typemap>, C<oDWORD> is treated differently than C<DWORD>\r
+ * in two ways.\r
+ *\r
+ * First, if C<undef> is passed in, a C<DWORD> could generate a warning\r
+ * when it gets converted to 0 while C<oDWORD> will never generate such a\r
+ * warning for C<undef>. This first difference doesn't apply if specific\r
+ * initialization is specified for the variable, as in C<= init_buf_l($var);>.\r
+ * In particular, the init_*() macros also convert C<undef> to 0 without\r
+ * ever producing a warning.\r
+ *\r
+ * Second, passing in a read-only SV for a C<oDWORD> parameter will generate\r
+ * a fatal error on output when we try to update the SV. For C<DWORD>, we\r
+ * won't update a read-only SV since passing in a literal constant for a\r
+ * buffer size is a useful thing to do even though it prevents us from\r
+ * returning the size of data written via that SV. Since we should use a\r
+ * trunc_*() macro to output the actual data, the user should be able to\r
+ * determine the size of data written based on the size of the scalar we\r
+ * output anyway.\r
+ *\r
+ * This second difference doesn't apply unless the parameter is listed in\r
+ * the OUTPUT: section without specific output instructions. We define\r
+ * no macros for outputting buffer length parameters so be careful to use\r
+ * C<oDWORD> [for example] for them if and only if they are output-only.\r
+ *\r
+ * Note that C<oDWORD> is the same as C<DWORD> in that, if a defined value\r
+ * is passed in, it is used [and can generate a warning if the value is\r
+ * "not numeric"]. So although C<oDWORD> is for output-only parameters,\r
+ * we still initialize the C variable before calling the API. This is good\r
+ * in case the parameter isn't always strictly output-only due to upgrades,\r
+ * bugs, etc.\r
+ *\r
+ * Here is a made-up example that shows several cases:\r
+ *\r
+ * # Actual GetDataW() returns length of data written to ioswName, not bool.\r
+ * bool\r
+ * GetDataW( ioswName, ilwName, oswText, iolwText, opJunk, opRec, ilRec, olRec )\r
+ * WCHAR * ioswName = NO_INIT\r
+ * DWORD ilwName = NO_INIT\r
+ * WCHAR * oswText = NO_INIT\r
+ * DWORD &iolwText = init_buf_l($arg);\r
+ * void * opJunk = NO_INIT\r
+ * BYTE * opRec = NO_INIT\r
+ * DWORD ilRec = init_buf_l($arg);\r
+ * oDWORD &olRec\r
+ * PREINIT:\r
+ * DWORD olwName;\r
+ * INIT:\r
+ * grow_buf_lw( ioswName,ST(0), ilwName,ST(1) );\r
+ * grow_buf_lw( oswText,ST(2), iolwText,ST(3) );\r
+ * grow_buf_typ( opJunk,ST(4),void *, LONG_STRUCT_TYPEDEF );\r
+ * grow_buf_l( opRec,ST(5),BYTE *, ilRec,ST(6) );\r
+ * CODE:\r
+ * olwName= GetDataW( ioswName, ilwName, oswText, &iolwText,\r
+ * (LONG_STRUCT_TYPEDEF *)opJunk, opRec, &iolRec );\r
+ * if( 0 == olwName && ERROR_MORE_DATA == GetLastError()\r
+ * && ( autosize(ST(1)) || autosize(ST(3)) || autosize(ST(6)) ) ) {\r
+ * if( autosize(ST(1)) )\r
+ * grow_buf_lw( ioswName,ST(0), ilwName,ST(1) );\r
+ * if( autosize(ST(3)) )\r
+ * grow_buf_lw( oswText,ST(2), iolwText,ST(3) );\r
+ * if( autosize(ST(6)) )\r
+ * grow_buf_l( opRec,ST(5),BYTE *, iolRec,ST(6) );\r
+ * olwName= GetDataW( ioswName, ilwName, oswText, &iolwText,\r
+ * (LONG_STRUCT_TYPEDEF *)opJunk, opRec, &iolRec );\r
+ * }\r
+ * RETVAL= 0 != olwName;\r
+ * OUTPUT:\r
+ * RETVAL\r
+ * ioswName trunc_buf_lw( RETVAL, ioswName,ST(0), olwName );\r
+ * oswText trunc_buf_lw( RETVAL, oswText,ST(2), iolwText );\r
+ * iolwText\r
+ * opJunk trunc_buf_typ(RETVAL,opJunk,ST(4),LONG_STRUCT_TYPEDEF);\r
+ * opRec trunc_buf_l( RETVAL, opRec,ST(5), olRec );\r
+ * olRec\r
+ *\r
+ * The above example would be more complex and less efficient if we used\r
+ * C<DWORD * iolwText> in place of C<DWORD &iolwText>. The only possible\r
+ * advantage would be that C<NULL> would be passed in for C<iolwText> if\r
+ * _both_ C<$oswText> and C<$iolwText> were specified as C<[]>. The *_pl*()\r
+ * macros are defined [and C<DWORD *> specified in F<typemap>] so we can\r
+ * handle those cases but it is usually better to use the *_l*() macros\r
+ * instead by specifying C<&> instead of C<*>. Using C<&> instead of C<*>\r
+ * is usually better when dealing with scalars, even if they aren't buffer\r
+ * sizes. But you must use C<*> if it is important for that parameter to\r
+ * be able to pass C<NULL> to the underlying API.\r
+ *\r
+ * In Win32API::, we try to use C<*> for buffer sizes of optional buffers\r
+ * and C<&> for buffer sizes of required buffers.\r
+ *\r
+ * For parameters that are pointers to things other than buffers or buffer\r
+ * sizes, we use C<*> for "important" parameters [so that using C<[]>\r
+ * generates an error rather than fetching the value and just throwing it\r
+ * away], and for optional parameters [in case specifying C<NULL> is or\r
+ * becomes important]. Otherwise we use C<&> [for "unimportant" but\r
+ * required parameters] so the user can specify C<[]> if they don't care\r
+ * about it. The output handle of an "open" routine is "important".\r
+ */\r
+\r
+#ifndef Debug\r
+# define Debug(list) /*Nothing*/\r
+#endif\r
+\r
+/*#ifndef CAST\r
+ *# ifdef __cplusplus\r
+ *# define CAST(type,expr) static_cast<type>(expr)\r
+ *# else*/\r
+# define CAST(type,expr) (type)(expr)\r
+/*# endif\r
+ *#endif*/\r
+\r
+/* Is an argument C<[]>, meaning we should pass C<NULL>? */\r
+#define null_arg(sv) ( SvROK(sv) && SVt_PVAV == SvTYPE(SvRV(sv)) \\r
+ && -1 == av_len((AV*)SvRV(sv)) )\r
+\r
+#define PV_or_null(sv) ( null_arg(sv) ? NULL : SvPV_nolen(sv) )\r
+\r
+/* Minimum buffer size to use when no buffer existed: */\r
+#define MIN_GROW_SIZE 128\r
+\r
+#ifdef Debug\r
+/* Used in Debug() messages to show which macro call is involved: */\r
+#define string(arg) #arg\r
+#endif\r
+\r
+/* Simplify using SvGROW() for byte-sized buffers: */\r
+#define lSvGROW(sv,n) SvGROW( sv, 0==(n) ? MIN_GROW_SIZE : (n)+1 )\r
+\r
+/* Simplify using SvGROW() for WCHAR-sized buffers: */\r
+#define lwSvGROW(sv,n) CAST( WCHAR *, \\r
+ SvGROW( sv, sizeof(WCHAR)*( 0==(n) ? MIN_GROW_SIZE : (n)+1 ) ) )\r
+\r
+/* Whether the buffer size we got lets us change what buffer size we use: */\r
+#define autosize(sv) (!( SvOK(sv) && ! SvROK(sv) \\r
+ && SvPV_nolen(sv) && '=' == *SvPV_nolen(sv) ))\r
+\r
+/* Get the IV/UV for a parameter that might be C<[]> or C<undef>: */\r
+#define optIV(sv) ( null_arg(sv) ? 0 : !SvOK(sv) ? 0 : SvIV(sv) )\r
+#define optUV(sv) ( null_arg(sv) ? 0 : !SvOK(sv) ? 0 : SvUV(sv) )\r
+\r
+/* Allocate temporary storage that will automatically be freed later: */\r
+#ifndef TempAlloc /* Can be C<#define>d to be C<_alloca>, for example */\r
+# define TempAlloc( size ) sv_grow( sv_newmortal(), size )\r
+#endif\r
+\r
+/* Initialize a buffer size argument of type (DWORD *): */\r
+#define init_buf_pl( plSize, svSize, tpSize ) STMT_START { \\r
+ if( null_arg(svSize) ) \\r
+ plSize= NULL; \\r
+ else { \\r
+ STRLEN n_a; \\r
+ *( plSize= CAST( tpSize, TempAlloc(sizeof(*plSize)) ) )= \\r
+ autosize(svSize) ? optUV(svSize) \\r
+ : strtoul( 1+SvPV(svSize,n_a), NULL, 10 ); \\r
+ } } STMT_END\r
+/* In INPUT section put ": init_buf_pl($var,$arg,$type);" after var name. */\r
+\r
+/* Initialize a buffer size argument of type DWORD: */\r
+#define init_buf_l( svSize ) \\r
+ ( null_arg(svSize) ? 0 : autosize(svSize) ? optUV(svSize) \\r
+ : strtoul( 1+SvPV_nolen(svSize), NULL, 10 ) )\r
+/* In INPUT section put "= init_buf_l($arg);" after variable name. */\r
+\r
+/* Lengths in WCHARs are initialized the same as lengths in bytes: */\r
+#define init_buf_plw init_buf_pl\r
+#define init_buf_lw init_buf_l\r
+\r
+/* grow_buf_pl() and grow_buf_plw() are included so you can define\r
+ * parameters of type C<DWORD *>, for example. In practice, it is\r
+ * usually better to define such parameters as "DWORD &". */\r
+\r
+/* Grow a buffer where we have a pointer to its size in bytes: */\r
+#define grow_buf_pl( sBuf,svBuf,tpBuf, plSize,svSize,tpSize ) STMT_START { \\r
+ Debug(("grow_buf_pl( %s==0x%lX,[%s:%ld/%ld, %s==0x%lX:%ld,[%s )\n",\\r
+ string(sBuf),sBuf,strchr(string(svBuf),'('),SvPOK(svBuf)? \\r
+ SvCUR(svBuf):-1,SvPOK(svBuf)?SvLEN(svBuf):-1,string(plSize), \\r
+ plSize,plSize?*plSize:-1,strchr(string(svSize),'('))); \\r
+ if( null_arg(svBuf) ) { \\r
+ sBuf= NULL; \\r
+ } else { \\r
+ STRLEN n_a; \\r
+ if( NULL == plSize ) \\r
+ *( plSize= CAST(tpSize,TempAlloc(sizeof(*plSize))) )= 0;\\r
+ if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \\r
+ (void) SvPV_force( svBuf, n_a ); \\r
+ sBuf= CAST( tpBuf, lSvGROW( svBuf, *plSize ) ); \\r
+ if( autosize(svSize) ) *plSize= SvLEN(svBuf) - 1; \\r
+ Debug(("more buf_pl( %s==0x%lX,[%s:%ld/%ld, %s==0x%lX:%ld,[%s )\n",\\r
+ string(sBuf),sBuf,strchr(string(svBuf),'('),SvPOK(svBuf)? \\r
+ SvCUR(svBuf):-1,SvPOK(svBuf)?SvLEN(svBuf):-1,string(plSize),\\r
+ plSize,plSize?*plSize:-1,strchr(string(svSize),'('))); \\r
+ } } STMT_END\r
+\r
+/* Grow a buffer where we have a pointer to its size in WCHARs: */\r
+#define grow_buf_plw( sBuf,svBuf, plwSize,svSize,tpSize ) STMT_START { \\r
+ if( null_arg(svBuf) ) { \\r
+ sBuf= NULL; \\r
+ } else { \\r
+ STRLEN n_a; \\r
+ if( NULL == plwSize ) \\r
+ *( plwSize= CAST(tpSize,TempAlloc(sizeof(*plwSize))) )= 0;\\r
+ if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \\r
+ (void) SvPV_force( svBuf, n_a ); \\r
+ sBuf= lwSvGROW( svBuf, *plwSize ); \\r
+ if( autosize(svSize) ) \\r
+ *plwSize= SvLEN(svBuf)/sizeof(WCHAR) - 1; \\r
+ } } STMT_END\r
+\r
+/* Grow a buffer where we have its size in bytes: */\r
+#define grow_buf_l( sBuf,svBuf,tpBuf, lSize,svSize ) STMT_START { \\r
+ if( null_arg(svBuf) ) { \\r
+ sBuf= NULL; \\r
+ } else { \\r
+ STRLEN n_a; \\r
+ if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \\r
+ (void) SvPV_force( svBuf, n_a ); \\r
+ sBuf= CAST( tpBuf, lSvGROW( svBuf, lSize ) ); \\r
+ if( autosize(svSize) ) lSize= SvLEN(svBuf) - 1; \\r
+ } } STMT_END\r
+\r
+/* Grow a buffer where we have its size in WCHARs: */\r
+#define grow_buf_lw( swBuf,svBuf, lwSize,svSize ) STMT_START { \\r
+ if( null_arg(svBuf) ) { \\r
+ swBuf= NULL; \\r
+ } else { \\r
+ STRLEN n_a; \\r
+ if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \\r
+ (void) SvPV_force( svBuf, n_a ); \\r
+ swBuf= lwSvGROW( svBuf, lwSize ); \\r
+ if( autosize(svSize) ) \\r
+ lwSize= SvLEN(svBuf)/sizeof(WCHAR) - 1; \\r
+ } } STMT_END\r
+\r
+/* Grow a buffer that contains the declared fixed data type: */\r
+#define grow_buf( pBuf,svBuf, tpBuf ) STMT_START { \\r
+ if( null_arg(svBuf) ) { \\r
+ pBuf= NULL; \\r
+ } else { \\r
+ STRLEN n_a; \\r
+ if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \\r
+ (void) SvPV_force( svBuf, n_a ); \\r
+ pBuf= CAST( tpBuf, SvGROW( svBuf, sizeof(*pBuf) ) ); \\r
+ } } STMT_END\r
+\r
+/* Grow a buffer that contains a fixed data type other than that declared: */\r
+#define grow_buf_typ( pBuf,svBuf,tpBuf, Type ) STMT_START { \\r
+ if( null_arg(svBuf) ) { \\r
+ pBuf= NULL; \\r
+ } else { \\r
+ STRLEN n_a; \\r
+ if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \\r
+ (void) SvPV_force( svBuf, n_a ); \\r
+ pBuf= CAST( tpBuf, SvGROW( svBuf, sizeof(Type) ) ); \\r
+ } } STMT_END\r
+\r
+/* Grow a buffer that contains a list of items of the declared data type: */\r
+#define grow_vect( pBuf,svBuf,tpBuf, cItems ) STMT_START { \\r
+ if( null_arg(svBuf) ) { \\r
+ pBuf= NULL; \\r
+ } else { \\r
+ STRLEN n_a; \\r
+ if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \\r
+ (void) SvPV_force( svBuf, n_a ); \\r
+ pBuf= CAST( tpBuf, SvGROW( svBuf, sizeof(*pBuf)*cItems ) ); \\r
+ } } STMT_END\r
+\r
+/* If call succeeded, set data length to returned length (in bytes): */\r
+#define trunc_buf_l( bOkay, sBuf,svBuf, lSize ) STMT_START { \\r
+ if( bOkay && NULL != sBuf ) { \\r
+ SvPOK_only( svBuf ); \\r
+ SvCUR_set( svBuf, lSize ); \\r
+ } } STMT_END\r
+\r
+/* Same as above except we have a pointer to the returned length: */\r
+#define trunc_buf_pl( bOkay, sBuf,svBuf, plSize ) \\r
+ trunc_buf_l( bOkay, sBuf,svBuf, *plSize )\r
+\r
+/* If call succeeded, set data length to returned length (in WCHARs): */\r
+#define trunc_buf_lw( bOkay, sBuf,svBuf, lwSize ) STMT_START { \\r
+ if( bOkay && NULL != sBuf ) { \\r
+ SvPOK_only( svBuf ); \\r
+ SvCUR_set( svBuf, (lwSize)*sizeof(WCHAR) ); \\r
+ } } STMT_END\r
+\r
+/* Same as above except we have a pointer to the returned length: */\r
+#define trunc_buf_plw( bOkay, swBuf,svBuf, plwSize ) \\r
+ trunc_buf_lw( bOkay, swBuf,svBuf, *plwSize )\r
+\r
+/* Set data length for a buffer that contains the declared fixed data type: */\r
+#define trunc_buf( bOkay, pBuf,svBuf ) STMT_START { \\r
+ if( bOkay && NULL != pBuf ) { \\r
+ SvPOK_only( svBuf ); \\r
+ SvCUR_set( svBuf, sizeof(*pBuf) ); \\r
+ } } STMT_END\r
+\r
+/* Set data length for a buffer that contains some other fixed data type: */\r
+#define trunc_buf_typ( bOkay, pBuf,svBuf, Type ) STMT_START { \\r
+ if( bOkay && NULL != pBuf ) { \\r
+ SvPOK_only( svBuf ); \\r
+ SvCUR_set( svBuf, sizeof(Type) ); \\r
+ } } STMT_END\r
+\r
+/* Set length for buffer that contains list of items of the declared type: */\r
+#define trunc_vect( bOkay, pBuf,svBuf, cItems ) STMT_START { \\r
+ if( bOkay && NULL != pBuf ) { \\r
+ SvPOK_only( svBuf ); \\r
+ SvCUR_set( svBuf, sizeof(*pBuf)*cItems ); \\r
+ } } STMT_END\r
+\r
+/* Set data length for a buffer where a '\0'-terminate string was stored: */\r
+#define trunc_buf_z( bOkay, sBuf,svBuf ) STMT_START { \\r
+ if( bOkay && NULL != sBuf ) { \\r
+ SvPOK_only( svBuf ); \\r
+ SvCUR_set( svBuf, strlen(sBuf) ); \\r
+ } } STMT_END\r
+\r
+/* Set data length for a buffer where a L'\0'-terminate string was stored: */\r
+#define trunc_buf_zw( bOkay, sBuf,svBuf ) STMT_START { \\r
+ if( bOkay && NULL != sBuf ) { \\r
+ SvPOK_only( svBuf ); \\r
+ SvCUR_set( svBuf, wcslen(sBuf)*sizeof(WCHAR) ); \\r
+ } } STMT_END\r
-/* Would contain C code to generate Perl constants if not using cFile.pc */
+/* Would contain C code to generate Perl constants if not using cFile.pc */\r
-# Generated by cFile_pc.cxx.
-# Package Win32API::File with options:
-# CPLUSPLUS => q[1]
-# IFDEF => q[!/[a-z\d]/]
-# IMPORT_LIST => [q[/._/], q[!/[a-z]/], q[:MEDIA_TYPE]]
-# WRITE_PERL => q[1]
-# Perl files eval'd:
-# File.pm => last if /^\s*(bootstrap|XSLoader::load)\b/
-# C files included:
-# File.xs => last if m#/[/*]\s*CONSTS_DEFINED\b|^\s*MODULE\b#
-sub CREATE_ALWAYS () { 2 }
-sub CREATE_NEW () { 1 }
-sub DDD_EXACT_MATCH_ON_REMOVE () { 4 }
-sub DDD_RAW_TARGET_PATH () { 1 }
-sub DDD_REMOVE_DEFINITION () { 2 }
-sub DRIVE_CDROM () { 5 }
-sub DRIVE_FIXED () { 3 }
-sub DRIVE_NO_ROOT_DIR () { 1 }
-sub DRIVE_RAMDISK () { 6 }
-sub DRIVE_REMOTE () { 4 }
-sub DRIVE_REMOVABLE () { 2 }
-sub DRIVE_UNKNOWN () { 0 }
-sub F3_120M_512 () { 13 }
-sub F3_1Pt44_512 () { 2 }
-sub F3_20Pt8_512 () { 4 }
-sub F3_2Pt88_512 () { 3 }
-sub F3_720_512 () { 5 }
-sub F5_160_512 () { 10 }
-sub F5_180_512 () { 9 }
-sub F5_1Pt2_512 () { 1 }
-sub F5_320_1024 () { 8 }
-sub F5_320_512 () { 7 }
-sub F5_360_512 () { 6 }
-sub FILE_ADD_FILE () { 2 }
-sub FILE_ADD_SUBDIRECTORY () { 4 }
-sub FILE_ALL_ACCESS () { 2032127 }
-sub FILE_APPEND_DATA () { 4 }
-sub FILE_ATTRIBUTE_ARCHIVE () { 32 }
-sub FILE_ATTRIBUTE_COMPRESSED () { 2048 }
-sub FILE_ATTRIBUTE_DEVICE () { 0x00000040 }
-sub FILE_ATTRIBUTE_DIRECTORY () { 0x00000010 }
-sub FILE_ATTRIBUTE_ENCRYPTED () { 0x00004000 }
-sub FILE_ATTRIBUTE_HIDDEN () { 2 }
-sub FILE_ATTRIBUTE_NORMAL () { 128 }
-sub FILE_ATTRIBUTE_NOT_CONTENT_INDEXED () { 0x00002000 }
-sub FILE_ATTRIBUTE_OFFLINE () { 4096 }
-sub FILE_ATTRIBUTE_READONLY () { 1 }
-sub FILE_ATTRIBUTE_REPARSE_POINT () { 0x00000400 }
-sub FILE_ATTRIBUTE_SPARSE_FILE () { 0x00000200 }
-sub FILE_ATTRIBUTE_SYSTEM () { 4 }
-sub FILE_ATTRIBUTE_TEMPORARY () { 256 }
-sub FILE_BEGIN () { 0 }
-sub FILE_CREATE_PIPE_INSTANCE () { 4 }
-sub FILE_CURRENT () { 1 }
-sub FILE_DELETE_CHILD () { 64 }
-sub FILE_END () { 2 }
-sub FILE_EXECUTE () { 32 }
-sub FILE_FLAG_BACKUP_SEMANTICS () { 33554432 }
-sub FILE_FLAG_DELETE_ON_CLOSE () { 67108864 }
-sub FILE_FLAG_NO_BUFFERING () { 536870912 }
-sub FILE_FLAG_OPEN_REPARSE_POINT () { 0x200000 }
-sub FILE_FLAG_OVERLAPPED () { 1073741824 }
-sub FILE_FLAG_POSIX_SEMANTICS () { 16777216 }
-sub FILE_FLAG_RANDOM_ACCESS () { 268435456 }
-sub FILE_FLAG_SEQUENTIAL_SCAN () { 134217728 }
-sub FILE_FLAG_WRITE_THROUGH () { 0x80000000 }
-sub FILE_GENERIC_EXECUTE () { 1179808 }
-sub FILE_GENERIC_READ () { 1179785 }
-sub FILE_GENERIC_WRITE () { 1179926 }
-sub FILE_LIST_DIRECTORY () { 1 }
-sub FILE_READ_ATTRIBUTES () { 128 }
-sub FILE_READ_DATA () { 1 }
-sub FILE_READ_EA () { 8 }
-sub FILE_SHARE_DELETE () { 4 }
-sub FILE_SHARE_READ () { 1 }
-sub FILE_SHARE_WRITE () { 2 }
-sub FILE_TRAVERSE () { 32 }
-sub FILE_TYPE_CHAR () { 2 }
-sub FILE_TYPE_DISK () { 1 }
-sub FILE_TYPE_PIPE () { 3 }
-sub FILE_TYPE_UNKNOWN () { 0 }
-sub FILE_WRITE_ATTRIBUTES () { 256 }
-sub FILE_WRITE_DATA () { 2 }
-sub FILE_WRITE_EA () { 16 }
-sub FS_CASE_IS_PRESERVED () { 2 }
-sub FS_CASE_SENSITIVE () { 1 }
-sub FS_FILE_COMPRESSION () { 16 }
-sub FS_PERSISTENT_ACLS () { 8 }
-sub FS_UNICODE_STORED_ON_DISK () { 4 }
-sub FS_VOL_IS_COMPRESSED () { 32768 }
-sub FSCTL_SET_REPARSE_POINT () { (9 << 16 | 0 << 14 | 41 << 2 | 0) }
-sub FSCTL_GET_REPARSE_POINT () { (9 << 16 | 0 << 14 | 42 << 2 | 0) }
-sub FSCTL_DELETE_REPARSE_POINT () { (9 << 16 | 0 << 14 | 43 << 2 | 0) }
-sub FixedMedia () { 12 }
-sub GENERIC_ALL () { 268435456 }
-sub GENERIC_EXECUTE () { 536870912 }
-sub GENERIC_READ () { 0x80000000 }
-sub GENERIC_WRITE () { 1073741824 }
-sub HANDLE_FLAG_INHERIT () { 1 }
-sub HANDLE_FLAG_PROTECT_FROM_CLOSE () { 2 }
-sub INVALID_FILE_ATTRIBUTES () { 0xFFFFFFFF }
-sub INVALID_HANDLE_VALUE () { 0xffffffff }
-sub IOCTL_DISK_FORMAT_TRACKS () { 507928 }
-sub IOCTL_DISK_FORMAT_TRACKS_EX () { 507948 }
-sub IOCTL_DISK_GET_DRIVE_GEOMETRY () { 458752 }
-sub IOCTL_DISK_GET_DRIVE_LAYOUT () { 475148 }
-sub IOCTL_DISK_GET_MEDIA_TYPES () { 461824 }
-sub IOCTL_DISK_GET_PARTITION_INFO () { 475140 }
-sub IOCTL_DISK_HISTOGRAM_DATA () { 458804 }
-sub IOCTL_DISK_HISTOGRAM_RESET () { 458808 }
-sub IOCTL_DISK_HISTOGRAM_STRUCTURE () { 458800 }
-sub IOCTL_DISK_IS_WRITABLE () { 458788 }
-sub IOCTL_DISK_LOGGING () { 458792 }
-sub IOCTL_DISK_PERFORMANCE () { 458784 }
-sub IOCTL_DISK_REASSIGN_BLOCKS () { 507932 }
-sub IOCTL_DISK_REQUEST_DATA () { 458816 }
-sub IOCTL_DISK_REQUEST_STRUCTURE () { 458812 }
-sub IOCTL_DISK_SET_DRIVE_LAYOUT () { 507920 }
-sub IOCTL_DISK_SET_PARTITION_INFO () { 507912 }
-sub IOCTL_DISK_VERIFY () { 458772 }
-sub IOCTL_STORAGE_CHECK_VERIFY () { 2967552 }
-sub IOCTL_STORAGE_EJECT_MEDIA () { 2967560 }
-sub IOCTL_STORAGE_FIND_NEW_DEVICES () { 2967576 }
-sub IOCTL_STORAGE_GET_MEDIA_TYPES () { 2952192 }
-sub IOCTL_STORAGE_LOAD_MEDIA () { 2967564 }
-sub IOCTL_STORAGE_MEDIA_REMOVAL () { 2967556 }
-sub IOCTL_STORAGE_RELEASE () { 2967572 }
-sub IOCTL_STORAGE_RESERVE () { 2967568 }
-sub MOVEFILE_COPY_ALLOWED () { 2 }
-sub MOVEFILE_DELAY_UNTIL_REBOOT () { 4 }
-sub MOVEFILE_REPLACE_EXISTING () { 1 }
-sub MOVEFILE_WRITE_THROUGH () { 8 }
-sub OPEN_ALWAYS () { 4 }
-sub OPEN_EXISTING () { 3 }
-sub PARTITION_ENTRY_UNUSED () { 0 }
-sub PARTITION_EXTENDED () { 5 }
-sub PARTITION_FAT32 () { 11 }
-sub PARTITION_FAT32_XINT13 () { 12 }
-sub PARTITION_FAT_12 () { 1 }
-sub PARTITION_FAT_16 () { 4 }
-sub PARTITION_HUGE () { 6 }
-sub PARTITION_IFS () { 7 }
-sub PARTITION_NTFT () { 128 }
-sub PARTITION_PREP () { 65 }
-sub PARTITION_UNIX () { 99 }
-sub PARTITION_XENIX_1 () { 2 }
-sub PARTITION_XENIX_2 () { 3 }
-sub PARTITION_XINT13 () { 14 }
-sub PARTITION_XINT13_EXTENDED () { 15 }
-sub RemovableMedia () { 11 }
-sub SECURITY_ANONYMOUS () { 0 }
-sub SECURITY_CONTEXT_TRACKING () { 262144 }
-sub SECURITY_DELEGATION () { 196608 }
-sub SECURITY_EFFECTIVE_ONLY () { 524288 }
-sub SECURITY_IDENTIFICATION () { 65536 }
-sub SECURITY_IMPERSONATION () { 131072 }
-sub SECURITY_SQOS_PRESENT () { 1048576 }
-sub SEM_FAILCRITICALERRORS () { 1 }
-sub SEM_NOALIGNMENTFAULTEXCEPT () { 4 }
-sub SEM_NOGPFAULTERRORBOX () { 2 }
-sub SEM_NOOPENFILEERRORBOX () { 32768 }
-sub TRUNCATE_EXISTING () { 5 }
-sub Unknown () { 0 }
-sub VALID_NTFT () { 192 }
-sub STD_ERROR_HANDLE () { 0xfffffff4 }
-sub STD_INPUT_HANDLE () { 0xfffffff6 }
-sub STD_OUTPUT_HANDLE () { 0xfffffff5 }
-1;
+# Generated by cFile_pc.cxx.\r
+# Package Win32API::File with options:\r
+# CPLUSPLUS => q[1]\r
+# IFDEF => q[!/[a-z\d]/]\r
+# IMPORT_LIST => [q[/._/], q[!/[a-z]/], q[:MEDIA_TYPE]]\r
+# WRITE_PERL => q[1]\r
+# Perl files eval'd:\r
+# File.pm => last if /^\s*(bootstrap|XSLoader::load)\b/\r
+# C files included:\r
+# File.xs => last if m#/[/*]\s*CONSTS_DEFINED\b|^\s*MODULE\b#\r
+sub CREATE_ALWAYS () { 2 }\r
+sub CREATE_NEW () { 1 }\r
+sub DDD_EXACT_MATCH_ON_REMOVE () { 4 }\r
+sub DDD_RAW_TARGET_PATH () { 1 }\r
+sub DDD_REMOVE_DEFINITION () { 2 }\r
+sub DRIVE_CDROM () { 5 }\r
+sub DRIVE_FIXED () { 3 }\r
+sub DRIVE_NO_ROOT_DIR () { 1 }\r
+sub DRIVE_RAMDISK () { 6 }\r
+sub DRIVE_REMOTE () { 4 }\r
+sub DRIVE_REMOVABLE () { 2 }\r
+sub DRIVE_UNKNOWN () { 0 }\r
+sub F3_120M_512 () { 13 }\r
+sub F3_1Pt44_512 () { 2 }\r
+sub F3_20Pt8_512 () { 4 }\r
+sub F3_2Pt88_512 () { 3 }\r
+sub F3_720_512 () { 5 }\r
+sub F5_160_512 () { 10 }\r
+sub F5_180_512 () { 9 }\r
+sub F5_1Pt2_512 () { 1 }\r
+sub F5_320_1024 () { 8 }\r
+sub F5_320_512 () { 7 }\r
+sub F5_360_512 () { 6 }\r
+sub FILE_ADD_FILE () { 2 }\r
+sub FILE_ADD_SUBDIRECTORY () { 4 }\r
+sub FILE_ALL_ACCESS () { 2032127 }\r
+sub FILE_APPEND_DATA () { 4 }\r
+sub FILE_ATTRIBUTE_ARCHIVE () { 32 }\r
+sub FILE_ATTRIBUTE_COMPRESSED () { 2048 }\r
+sub FILE_ATTRIBUTE_DEVICE () { 0x00000040 }\r
+sub FILE_ATTRIBUTE_DIRECTORY () { 0x00000010 }\r
+sub FILE_ATTRIBUTE_ENCRYPTED () { 0x00004000 }\r
+sub FILE_ATTRIBUTE_HIDDEN () { 2 }\r
+sub FILE_ATTRIBUTE_NORMAL () { 128 }\r
+sub FILE_ATTRIBUTE_NOT_CONTENT_INDEXED () { 0x00002000 }\r
+sub FILE_ATTRIBUTE_OFFLINE () { 4096 }\r
+sub FILE_ATTRIBUTE_READONLY () { 1 }\r
+sub FILE_ATTRIBUTE_REPARSE_POINT () { 0x00000400 }\r
+sub FILE_ATTRIBUTE_SPARSE_FILE () { 0x00000200 }\r
+sub FILE_ATTRIBUTE_SYSTEM () { 4 }\r
+sub FILE_ATTRIBUTE_TEMPORARY () { 256 }\r
+sub FILE_BEGIN () { 0 }\r
+sub FILE_CREATE_PIPE_INSTANCE () { 4 }\r
+sub FILE_CURRENT () { 1 }\r
+sub FILE_DELETE_CHILD () { 64 }\r
+sub FILE_END () { 2 }\r
+sub FILE_EXECUTE () { 32 }\r
+sub FILE_FLAG_BACKUP_SEMANTICS () { 33554432 }\r
+sub FILE_FLAG_DELETE_ON_CLOSE () { 67108864 }\r
+sub FILE_FLAG_NO_BUFFERING () { 536870912 }\r
+sub FILE_FLAG_OPEN_REPARSE_POINT () { 0x200000 }\r
+sub FILE_FLAG_OVERLAPPED () { 1073741824 }\r
+sub FILE_FLAG_POSIX_SEMANTICS () { 16777216 }\r
+sub FILE_FLAG_RANDOM_ACCESS () { 268435456 }\r
+sub FILE_FLAG_SEQUENTIAL_SCAN () { 134217728 }\r
+sub FILE_FLAG_WRITE_THROUGH () { 0x80000000 }\r
+sub FILE_GENERIC_EXECUTE () { 1179808 }\r
+sub FILE_GENERIC_READ () { 1179785 }\r
+sub FILE_GENERIC_WRITE () { 1179926 }\r
+sub FILE_LIST_DIRECTORY () { 1 }\r
+sub FILE_READ_ATTRIBUTES () { 128 }\r
+sub FILE_READ_DATA () { 1 }\r
+sub FILE_READ_EA () { 8 }\r
+sub FILE_SHARE_DELETE () { 4 }\r
+sub FILE_SHARE_READ () { 1 }\r
+sub FILE_SHARE_WRITE () { 2 }\r
+sub FILE_TRAVERSE () { 32 }\r
+sub FILE_TYPE_CHAR () { 2 }\r
+sub FILE_TYPE_DISK () { 1 }\r
+sub FILE_TYPE_PIPE () { 3 }\r
+sub FILE_TYPE_UNKNOWN () { 0 }\r
+sub FILE_WRITE_ATTRIBUTES () { 256 }\r
+sub FILE_WRITE_DATA () { 2 }\r
+sub FILE_WRITE_EA () { 16 }\r
+sub FS_CASE_IS_PRESERVED () { 2 }\r
+sub FS_CASE_SENSITIVE () { 1 }\r
+sub FS_FILE_COMPRESSION () { 16 }\r
+sub FS_PERSISTENT_ACLS () { 8 }\r
+sub FS_UNICODE_STORED_ON_DISK () { 4 }\r
+sub FS_VOL_IS_COMPRESSED () { 32768 }\r
+sub FSCTL_SET_REPARSE_POINT () { (9 << 16 | 0 << 14 | 41 << 2 | 0) }\r
+sub FSCTL_GET_REPARSE_POINT () { (9 << 16 | 0 << 14 | 42 << 2 | 0) }\r
+sub FSCTL_DELETE_REPARSE_POINT () { (9 << 16 | 0 << 14 | 43 << 2 | 0) }\r
+sub FixedMedia () { 12 }\r
+sub GENERIC_ALL () { 268435456 }\r
+sub GENERIC_EXECUTE () { 536870912 }\r
+sub GENERIC_READ () { 0x80000000 }\r
+sub GENERIC_WRITE () { 1073741824 }\r
+sub HANDLE_FLAG_INHERIT () { 1 }\r
+sub HANDLE_FLAG_PROTECT_FROM_CLOSE () { 2 }\r
+sub INVALID_FILE_ATTRIBUTES () { 0xFFFFFFFF }\r
+sub INVALID_HANDLE_VALUE () { 0xffffffff }\r
+sub IOCTL_DISK_FORMAT_TRACKS () { 507928 }\r
+sub IOCTL_DISK_FORMAT_TRACKS_EX () { 507948 }\r
+sub IOCTL_DISK_GET_DRIVE_GEOMETRY () { 458752 }\r
+sub IOCTL_DISK_GET_DRIVE_LAYOUT () { 475148 }\r
+sub IOCTL_DISK_GET_MEDIA_TYPES () { 461824 }\r
+sub IOCTL_DISK_GET_PARTITION_INFO () { 475140 }\r
+sub IOCTL_DISK_HISTOGRAM_DATA () { 458804 }\r
+sub IOCTL_DISK_HISTOGRAM_RESET () { 458808 }\r
+sub IOCTL_DISK_HISTOGRAM_STRUCTURE () { 458800 }\r
+sub IOCTL_DISK_IS_WRITABLE () { 458788 }\r
+sub IOCTL_DISK_LOGGING () { 458792 }\r
+sub IOCTL_DISK_PERFORMANCE () { 458784 }\r
+sub IOCTL_DISK_REASSIGN_BLOCKS () { 507932 }\r
+sub IOCTL_DISK_REQUEST_DATA () { 458816 }\r
+sub IOCTL_DISK_REQUEST_STRUCTURE () { 458812 }\r
+sub IOCTL_DISK_SET_DRIVE_LAYOUT () { 507920 }\r
+sub IOCTL_DISK_SET_PARTITION_INFO () { 507912 }\r
+sub IOCTL_DISK_VERIFY () { 458772 }\r
+sub IOCTL_STORAGE_CHECK_VERIFY () { 2967552 }\r
+sub IOCTL_STORAGE_EJECT_MEDIA () { 2967560 }\r
+sub IOCTL_STORAGE_FIND_NEW_DEVICES () { 2967576 }\r
+sub IOCTL_STORAGE_GET_MEDIA_TYPES () { 2952192 }\r
+sub IOCTL_STORAGE_LOAD_MEDIA () { 2967564 }\r
+sub IOCTL_STORAGE_MEDIA_REMOVAL () { 2967556 }\r
+sub IOCTL_STORAGE_RELEASE () { 2967572 }\r
+sub IOCTL_STORAGE_RESERVE () { 2967568 }\r
+sub MOVEFILE_COPY_ALLOWED () { 2 }\r
+sub MOVEFILE_DELAY_UNTIL_REBOOT () { 4 }\r
+sub MOVEFILE_REPLACE_EXISTING () { 1 }\r
+sub MOVEFILE_WRITE_THROUGH () { 8 }\r
+sub OPEN_ALWAYS () { 4 }\r
+sub OPEN_EXISTING () { 3 }\r
+sub PARTITION_ENTRY_UNUSED () { 0 }\r
+sub PARTITION_EXTENDED () { 5 }\r
+sub PARTITION_FAT32 () { 11 }\r
+sub PARTITION_FAT32_XINT13 () { 12 }\r
+sub PARTITION_FAT_12 () { 1 }\r
+sub PARTITION_FAT_16 () { 4 }\r
+sub PARTITION_HUGE () { 6 }\r
+sub PARTITION_IFS () { 7 }\r
+sub PARTITION_NTFT () { 128 }\r
+sub PARTITION_PREP () { 65 }\r
+sub PARTITION_UNIX () { 99 }\r
+sub PARTITION_XENIX_1 () { 2 }\r
+sub PARTITION_XENIX_2 () { 3 }\r
+sub PARTITION_XINT13 () { 14 }\r
+sub PARTITION_XINT13_EXTENDED () { 15 }\r
+sub RemovableMedia () { 11 }\r
+sub SECURITY_ANONYMOUS () { 0 }\r
+sub SECURITY_CONTEXT_TRACKING () { 262144 }\r
+sub SECURITY_DELEGATION () { 196608 }\r
+sub SECURITY_EFFECTIVE_ONLY () { 524288 }\r
+sub SECURITY_IDENTIFICATION () { 65536 }\r
+sub SECURITY_IMPERSONATION () { 131072 }\r
+sub SECURITY_SQOS_PRESENT () { 1048576 }\r
+sub SEM_FAILCRITICALERRORS () { 1 }\r
+sub SEM_NOALIGNMENTFAULTEXCEPT () { 4 }\r
+sub SEM_NOGPFAULTERRORBOX () { 2 }\r
+sub SEM_NOOPENFILEERRORBOX () { 32768 }\r
+sub TRUNCATE_EXISTING () { 5 }\r
+sub Unknown () { 0 }\r
+sub VALID_NTFT () { 192 }\r
+sub STD_ERROR_HANDLE () { 0xfffffff4 }\r
+sub STD_INPUT_HANDLE () { 0xfffffff6 }\r
+sub STD_OUTPUT_HANDLE () { 0xfffffff5 }\r
+1;\r
-/* const2perl.h -- For converting C constants into Perl constant subs
- * (usually via XS code but can just write Perl code to stdout). */
-
-
-/* #ifndef _INCLUDE_CONST2PERL_H
- * #define _INCLUDE_CONST2PERL_H 1 */
-
-#ifndef CONST2WRITE_PERL /* Default is "const to .xs": */
-
-# define newconst( sName, sFmt, xValue, newSV ) \
- newCONSTSUB( mHvStash, sName, newSV )
-
-# define noconst( const ) av_push( mAvExportFail, newSVpv(#const,0) )
-
-# define setuv(u) do { \
- mpSvNew= newSViv(0); sv_setuv(mpSvNew,u); \
- } while( 0 )
-
-#else
-
-/* #ifdef __cplusplus
- * # undef printf
- * # undef fprintf
- * # undef stderr
- * # define stderr (&_iob[2])
- * # undef iobuf
- * # undef malloc
- * #endif */
-
-# include <stdio.h> /* Probably already included, but shouldn't hurt */
-# include <errno.h> /* Possibly already included, but shouldn't hurt */
-
-# define newconst( sName, sFmt, xValue, newSV ) \
- printf( "sub %s () { " sFmt " }\n", sName, xValue )
-
-# define noconst( const ) printf( "push @EXPORT_FAIL, '%s';\n", #const )
-
-# define setuv(u) /* Nothing */
-
-# ifndef IVdf
-# define IVdf "ld"
-# endif
-# ifndef UVuf
-# define UVuf "lu"
-# endif
-# ifndef UVxf
-# define UVxf "lX"
-# endif
-# ifndef NV_DIG
-# define NV_DIG 15
-# endif
-
-static char *
-escquote( const char *sValue )
-{
- Size_t lLen= 1+2*strlen(sValue);
- char *sEscaped= (char *) malloc( lLen );
- char *sNext= sEscaped;
- if( NULL == sEscaped ) {
- fprintf( stderr, "Can't allocate %"UVuf"-byte buffer (errno=%d)\n",
- U_V(lLen), _errno );
- exit( 1 );
- }
- while( '\0' != *sValue ) {
- switch( *sValue ) {
- case '\'':
- case '\\':
- *(sNext++)= '\\';
- }
- *(sNext++)= *(sValue++);
- }
- *sNext= *sValue;
- return( sEscaped );
-}
-
-#endif
-
-
-#ifdef __cplusplus
-
-class _const2perl {
- public:
- char msBuf[64]; /* Must fit sprintf of longest NV */
-#ifndef CONST2WRITE_PERL
- HV *mHvStash;
- AV *mAvExportFail;
- SV *mpSvNew;
- _const2perl::_const2perl( char *sModName ) {
- mHvStash= gv_stashpv( sModName, TRUE );
- SV **pSv= hv_fetch( mHvStash, "EXPORT_FAIL", 11, TRUE );
- GV *gv;
- char *sVarName= (char *) malloc( 15+strlen(sModName) );
- strcpy( sVarName, sModName );
- strcat( sVarName, "::EXPORT_FAIL" );
- gv= gv_fetchpv( sVarName, 1, SVt_PVAV );
- mAvExportFail= GvAVn( gv );
- }
-#else
- _const2perl::_const2perl( char *sModName ) {
- ; /* Nothing to do */
- }
-#endif /* CONST2WRITE_PERL */
- void mkconst( char *sName, unsigned long uValue ) {
- setuv(uValue);
- newconst( sName, "0x%"UVxf, uValue, mpSvNew );
- }
- void mkconst( char *sName, unsigned int uValue ) {
- setuv(uValue);
- newconst( sName, "0x%"UVxf, uValue, mpSvNew );
- }
- void mkconst( char *sName, unsigned short uValue ) {
- setuv(uValue);
- newconst( sName, "0x%"UVxf, uValue, mpSvNew );
- }
- void mkconst( char *sName, long iValue ) {
- newconst( sName, "%"IVdf, iValue, newSViv(iValue) );
- }
- void mkconst( char *sName, int iValue ) {
- newconst( sName, "%"IVdf, iValue, newSViv(iValue) );
- }
- void mkconst( char *sName, short iValue ) {
- newconst( sName, "%"IVdf, iValue, newSViv(iValue) );
- }
- void mkconst( char *sName, double nValue ) {
- newconst( sName, "%s",
- Gconvert(nValue,NV_DIG,0,msBuf), newSVnv(nValue) );
- }
- void mkconst( char *sName, char *sValue ) {
- newconst( sName, "'%s'", escquote(sValue), newSVpv(sValue,0) );
- }
- void mkconst( char *sName, const void *pValue ) {
- setuv((UV)pValue);
- newconst( sName, "0x%"UVxf, (UV)(pValue), mpSvNew );
- }
-/*#ifdef HAS_QUAD
- * HAS_QUAD only means pack/unpack deal with them, not that SVs can.
- * void mkconst( char *sName, Quad_t *qValue ) {
- * newconst( sName, "0x%"QVxf, qValue, newSVqv(qValue) );
- * }
- *#endif / * HAS_QUAD */
-};
-
-#define START_CONSTS( sModName ) _const2perl const2( sModName );
-#define const2perl( const ) const2.mkconst( #const, const )
-
-#else /* __cplusplus */
-
-# ifndef CONST2WRITE_PERL
-# define START_CONSTS( sModName ) \
- HV *mHvStash= gv_stashpv( sModName, TRUE ); \
- AV *mAvExportFail; \
- SV *mpSvNew; \
- { char *sVarName= malloc( 15+strlen(sModName) ); \
- GV *gv; \
- strcpy( sVarName, sModName ); \
- strcat( sVarName, "::EXPORT_FAIL" ); \
- gv= gv_fetchpv( sVarName, 1, SVt_PVAV ); \
- mAvExportFail= GvAVn( gv ); \
- }
-# else
-# define START_CONSTS( sModName ) /* Nothing */
-# endif
-
-#define const2perl( const ) do { \
- if( const < 0 ) { \
- newconst( #const, "%"IVdf, const, newSViv((IV)const) ); \
- } else { \
- setuv( (UV)const ); \
- newconst( #const, "0x%"UVxf, const, mpSvNew ); \
- } \
- } while( 0 )
-
-#endif /* __cplusplus */
-
-
-//Example use:
-//#include <const2perl.h>
-// {
-// START_CONSTS( "Package::Name" ) /* No ";" */
-//#ifdef $const
-// const2perl( $const );
-//#else
-// noconst( $const );
-//#endif
-// }
-// sub ? { my( $sConstName )= @_;
-// return $sConstName; # "#ifdef $sConstName"
-// return FALSE; # Same as above
-// return "HAS_QUAD"; # "#ifdef HAS_QUAD"
-// return "#if 5.04 <= VERSION";
-// return "#if 0";
-// return 1; # No #ifdef
-/* #endif / * _INCLUDE_CONST2PERL_H */
+/* const2perl.h -- For converting C constants into Perl constant subs\r
+ * (usually via XS code but can just write Perl code to stdout). */\r
+\r
+\r
+/* #ifndef _INCLUDE_CONST2PERL_H\r
+ * #define _INCLUDE_CONST2PERL_H 1 */\r
+\r
+#ifndef CONST2WRITE_PERL /* Default is "const to .xs": */\r
+\r
+# define newconst( sName, sFmt, xValue, newSV ) \\r
+ newCONSTSUB( mHvStash, sName, newSV )\r
+\r
+# define noconst( const ) av_push( mAvExportFail, newSVpv(#const,0) )\r
+\r
+# define setuv(u) do { \\r
+ mpSvNew= newSViv(0); sv_setuv(mpSvNew,u); \\r
+ } while( 0 )\r
+\r
+#else\r
+\r
+/* #ifdef __cplusplus\r
+ * # undef printf\r
+ * # undef fprintf\r
+ * # undef stderr\r
+ * # define stderr (&_iob[2])\r
+ * # undef iobuf\r
+ * # undef malloc\r
+ * #endif */\r
+\r
+# include <stdio.h> /* Probably already included, but shouldn't hurt */\r
+# include <errno.h> /* Possibly already included, but shouldn't hurt */\r
+\r
+# define newconst( sName, sFmt, xValue, newSV ) \\r
+ printf( "sub %s () { " sFmt " }\n", sName, xValue )\r
+\r
+# define noconst( const ) printf( "push @EXPORT_FAIL, '%s';\n", #const )\r
+\r
+# define setuv(u) /* Nothing */\r
+\r
+# ifndef IVdf\r
+# define IVdf "ld"\r
+# endif\r
+# ifndef UVuf\r
+# define UVuf "lu"\r
+# endif\r
+# ifndef UVxf\r
+# define UVxf "lX"\r
+# endif\r
+# ifndef NV_DIG\r
+# define NV_DIG 15\r
+# endif\r
+\r
+static char *\r
+escquote( const char *sValue )\r
+{\r
+ Size_t lLen= 1+2*strlen(sValue);\r
+ char *sEscaped= (char *) malloc( lLen );\r
+ char *sNext= sEscaped;\r
+ if( NULL == sEscaped ) {\r
+ fprintf( stderr, "Can't allocate %"UVuf"-byte buffer (errno=%d)\n",\r
+ U_V(lLen), _errno );\r
+ exit( 1 );\r
+ }\r
+ while( '\0' != *sValue ) {\r
+ switch( *sValue ) {\r
+ case '\'':\r
+ case '\\':\r
+ *(sNext++)= '\\';\r
+ }\r
+ *(sNext++)= *(sValue++);\r
+ }\r
+ *sNext= *sValue;\r
+ return( sEscaped );\r
+}\r
+\r
+#endif\r
+\r
+\r
+#ifdef __cplusplus\r
+\r
+class _const2perl {\r
+ public:\r
+ char msBuf[64]; /* Must fit sprintf of longest NV */\r
+#ifndef CONST2WRITE_PERL\r
+ HV *mHvStash;\r
+ AV *mAvExportFail;\r
+ SV *mpSvNew;\r
+ _const2perl::_const2perl( char *sModName ) {\r
+ mHvStash= gv_stashpv( sModName, TRUE );\r
+ SV **pSv= hv_fetch( mHvStash, "EXPORT_FAIL", 11, TRUE );\r
+ GV *gv;\r
+ char *sVarName= (char *) malloc( 15+strlen(sModName) );\r
+ strcpy( sVarName, sModName );\r
+ strcat( sVarName, "::EXPORT_FAIL" );\r
+ gv= gv_fetchpv( sVarName, 1, SVt_PVAV );\r
+ mAvExportFail= GvAVn( gv );\r
+ }\r
+#else\r
+ _const2perl::_const2perl( char *sModName ) {\r
+ ; /* Nothing to do */\r
+ }\r
+#endif /* CONST2WRITE_PERL */\r
+ void mkconst( char *sName, unsigned long uValue ) {\r
+ setuv(uValue);\r
+ newconst( sName, "0x%"UVxf, uValue, mpSvNew );\r
+ }\r
+ void mkconst( char *sName, unsigned int uValue ) {\r
+ setuv(uValue);\r
+ newconst( sName, "0x%"UVxf, uValue, mpSvNew );\r
+ }\r
+ void mkconst( char *sName, unsigned short uValue ) {\r
+ setuv(uValue);\r
+ newconst( sName, "0x%"UVxf, uValue, mpSvNew );\r
+ }\r
+ void mkconst( char *sName, long iValue ) {\r
+ newconst( sName, "%"IVdf, iValue, newSViv(iValue) );\r
+ }\r
+ void mkconst( char *sName, int iValue ) {\r
+ newconst( sName, "%"IVdf, iValue, newSViv(iValue) );\r
+ }\r
+ void mkconst( char *sName, short iValue ) {\r
+ newconst( sName, "%"IVdf, iValue, newSViv(iValue) );\r
+ }\r
+ void mkconst( char *sName, double nValue ) {\r
+ newconst( sName, "%s",\r
+ Gconvert(nValue,NV_DIG,0,msBuf), newSVnv(nValue) );\r
+ }\r
+ void mkconst( char *sName, char *sValue ) {\r
+ newconst( sName, "'%s'", escquote(sValue), newSVpv(sValue,0) );\r
+ }\r
+ void mkconst( char *sName, const void *pValue ) {\r
+ setuv((UV)pValue);\r
+ newconst( sName, "0x%"UVxf, (UV)(pValue), mpSvNew );\r
+ }\r
+/*#ifdef HAS_QUAD\r
+ * HAS_QUAD only means pack/unpack deal with them, not that SVs can.\r
+ * void mkconst( char *sName, Quad_t *qValue ) {\r
+ * newconst( sName, "0x%"QVxf, qValue, newSVqv(qValue) );\r
+ * }\r
+ *#endif / * HAS_QUAD */\r
+};\r
+\r
+#define START_CONSTS( sModName ) _const2perl const2( sModName );\r
+#define const2perl( const ) const2.mkconst( #const, const )\r
+\r
+#else /* __cplusplus */\r
+\r
+# ifndef CONST2WRITE_PERL\r
+# define START_CONSTS( sModName ) \\r
+ HV *mHvStash= gv_stashpv( sModName, TRUE ); \\r
+ AV *mAvExportFail; \\r
+ SV *mpSvNew; \\r
+ { char *sVarName= malloc( 15+strlen(sModName) ); \\r
+ GV *gv; \\r
+ strcpy( sVarName, sModName ); \\r
+ strcat( sVarName, "::EXPORT_FAIL" ); \\r
+ gv= gv_fetchpv( sVarName, 1, SVt_PVAV ); \\r
+ mAvExportFail= GvAVn( gv ); \\r
+ }\r
+# else\r
+# define START_CONSTS( sModName ) /* Nothing */\r
+# endif\r
+\r
+#define const2perl( const ) do { \\r
+ if( const < 0 ) { \\r
+ newconst( #const, "%"IVdf, const, newSViv((IV)const) ); \\r
+ } else { \\r
+ setuv( (UV)const ); \\r
+ newconst( #const, "0x%"UVxf, const, mpSvNew ); \\r
+ } \\r
+ } while( 0 )\r
+\r
+#endif /* __cplusplus */\r
+\r
+\r
+//Example use:\r
+//#include <const2perl.h>\r
+// {\r
+// START_CONSTS( "Package::Name" ) /* No ";" */\r
+//#ifdef $const\r
+// const2perl( $const );\r
+//#else\r
+// noconst( $const );\r
+//#endif\r
+// }\r
+// sub ? { my( $sConstName )= @_;\r
+// return $sConstName; # "#ifdef $sConstName"\r
+// return FALSE; # Same as above\r
+// return "HAS_QUAD"; # "#ifdef HAS_QUAD"\r
+// return "#if 5.04 <= VERSION";\r
+// return "#if 0";\r
+// return 1; # No #ifdef\r
+/* #endif / * _INCLUDE_CONST2PERL_H */\r
-# This should eventually become part of MakeMaker as ExtUtils::Mkconst2perl.
-# Documentation for this is very skimpy at this point. Full documentation
-# will be added to ExtUtils::Mkconst2perl when it is created.
-package # Hide from PAUSE
- ExtUtils::Myconst2perl;
-
-use strict;
-use Config;
-
-use vars qw( @ISA @EXPORT @EXPORT_OK $VERSION );
-BEGIN {
- require Exporter;
- push @ISA, 'Exporter';
- @EXPORT= qw( &Myconst2perl );
- @EXPORT_OK= qw( &ParseAttribs );
- $VERSION= 1.00;
-}
-
-use Carp;
-use File::Basename;
-use ExtUtils::MakeMaker qw( neatvalue );
-
-# Return the extension to use for a file of C++ source code:
-sub _cc
-{
- # Some day, $Config{_cc} might be defined for us:
- return $Config{_cc} if $Config{_cc};
- return ".cxx"; # Seems to be the most widely accepted extension.
-}
-
-=item ParseAttribs
-
-Parses user-firendly options into coder-firendly specifics.
-
-=cut
-
-sub ParseAttribs
-{
- # Usage: ParseAttribs( "Package::Name", \%opts, {opt=>\$var} );
- my( $pkg, $hvAttr, $hvRequests )= @_;
- my( $outfile, @perlfiles, %perlfilecodes, @cfiles, %cfilecodes );
- my @importlist= @{$hvAttr->{IMPORT_LIST}};
- my $perlcode= $hvAttr->{PERL_PE_CODE} ||
- 'last if /^\s*(bootstrap|XSLoader::load)\b/';
- my $ccode= $hvAttr->{C_PE_CODE} ||
- 'last if m#/[/*]\s*CONSTS_DEFINED\b|^\s*MODULE\b#';
- my $ifdef= $hvAttr->{IFDEF} || 0;
- my $writeperl= !! $hvAttr->{WRITE_PERL};
- my $export= !! $hvAttr->{DO_EXPORT};
- my $importto= $hvAttr->{IMPORT_TO} || "_constants";
- my $cplusplus= $hvAttr->{CPLUSPLUS};
- $cplusplus= "" if ! defined $cplusplus;
- my $object= "";
- my $binary= "";
- my $final= "";
- my $norebuild= "";
- my $subroutine= "";
- my $base;
- my %params= (
- PERL_PE_CODE => \$perlcode,
- PERL_FILE_LIST => \@perlfiles,
- PERL_FILE_CODES => \%perlfilecodes,
- PERL_FILES => sub { map {($_,$perlfilecodes{$_})} @perlfiles },
- C_PE_CODE => \$ccode,
- C_FILE_LIST => \@cfiles,
- C_FILE_CODES => \%cfilecodes,
- C_FILES => sub { map {($_,$cfilecodes{$_})} @cfiles },
- DO_EXPORT => \$export,
- IMPORT_TO => \$importto,
- IMPORT_LIST => \@importlist,
- SUBROUTINE => \$subroutine,
- IFDEF => \$ifdef,
- WRITE_PERL => \$writeperl,
- CPLUSPLUS => \$cplusplus,
- BASEFILENAME => \$base,
- OUTFILE => \$outfile,
- OBJECT => \$object,
- BINARY => \$binary,
- FINAL_PERL => \$final,
- NO_REBUILD => \$norebuild,
- );
- { my @err= grep {! defined $params{$_}} keys %$hvAttr;
- carp "ExtUtils::Myconst2perl::ParseAttribs: ",
- "Unsupported option(s) (@err).\n"
- if @err;
- }
- $norebuild= $hvAttr->{NO_REBUILD} if exists $hvAttr->{NO_REBUILD};
- my $module= ( split /::/, $pkg )[-1];
- $base= "c".$module;
- $base= $hvAttr->{BASEFILENAME} if exists $hvAttr->{BASEFILENAME};
- my $ext= ! $cplusplus ? ($Config{_c}||".c")
- : $cplusplus =~ /^[.]/ ? $cplusplus : _cc();
- if( $writeperl ) {
- $outfile= $base . "_pc" . $ext;
- $object= $base . "_pc" . ($Config{_o}||$Config{obj_ext});
- $object= $hvAttr->{OBJECT} if $hvAttr->{OBJECT};
- $binary= $base . "_pc" . ($Config{_exe}||$Config{exe_ext});
- $binary= $hvAttr->{BINARY} if $hvAttr->{BINARY};
- $final= $base . ".pc";
- $final= $hvAttr->{FINAL_PERL} if $hvAttr->{FINAL_PERL};
- $subroutine= "main";
- } elsif( $cplusplus ) {
- $outfile= $base . $ext;
- $object= $base . ($Config{_o}||$Config{obj_ext});
- $object= $hvAttr->{OBJECT} if $hvAttr->{OBJECT};
- $subroutine= "const2perl_" . $pkg;
- $subroutine =~ s/\W/_/g;
- } else {
- $outfile= $base . ".h";
- }
- $outfile= $hvAttr->{OUTFILE} if $hvAttr->{OUTFILE};
- if( $hvAttr->{PERL_FILES} ) {
- carp "ExtUtils::Myconst2perl: PERL_FILES option not allowed ",
- "with PERL_FILE_LIST nor PERL_FILE_CODES.\n"
- if $hvAttr->{PERL_FILE_LIST} || $hvAttr->{PERL_FILE_CODES};
- %perlfilecodes= @{$hvAttr->{PERL_FILES}};
- my $odd= 0;
- @perlfiles= grep {$odd= !$odd} @{$hvAttr->{PERL_FILES}};
- } else {
- if( $hvAttr->{PERL_FILE_LIST} ) {
- @perlfiles= @{$hvAttr->{PERL_FILE_LIST}};
- } elsif( $hvAttr->{PERL_FILE_CODES} ) {
- @perlfiles= keys %{$hvAttr->{PERL_FILE_CODES}};
- } else {
- @perlfiles= ( "$module.pm" );
- }
- %perlfilecodes= %{$hvAttr->{PERL_FILE_CODES}}
- if $hvAttr->{PERL_FILE_CODES};
- }
- for my $file ( @perlfiles ) {
- $perlfilecodes{$file}= $perlcode if ! $perlfilecodes{$file};
- }
- if( ! $subroutine ) {
- ; # Don't process any C source code files.
- } elsif( $hvAttr->{C_FILES} ) {
- carp "ExtUtils::Myconst2perl: C_FILES option not allowed ",
- "with C_FILE_LIST nor C_FILE_CODES.\n"
- if $hvAttr->{C_FILE_LIST} || $hvAttr->{C_FILE_CODES};
- %cfilecodes= @{$hvAttr->{C_FILES}};
- my $odd= 0;
- @cfiles= grep {$odd= !$odd} @{$hvAttr->{C_FILES}};
- } else {
- if( $hvAttr->{C_FILE_LIST} ) {
- @cfiles= @{$hvAttr->{C_FILE_LIST}};
- } elsif( $hvAttr->{C_FILE_CODES} ) {
- @cfiles= keys %{$hvAttr->{C_FILE_CODES}};
- } elsif( $writeperl || $cplusplus ) {
- @cfiles= ( "$module.xs" );
- }
- %cfilecodes= %{$hvAttr->{C_FILE_CODES}} if $hvAttr->{C_FILE_CODES};
- }
- for my $file ( @cfiles ) {
- $cfilecodes{$file}= $ccode if ! $cfilecodes{$file};
- }
- for my $key ( keys %$hvRequests ) {
- if( ! $params{$key} ) {
- carp "ExtUtils::Myconst2perl::ParseAttribs: ",
- "Unsupported output ($key).\n";
- } elsif( "SCALAR" eq ref( $params{$key} ) ) {
- ${$hvRequests->{$key}}= ${$params{$key}};
- } elsif( "ARRAY" eq ref( $params{$key} ) ) {
- @{$hvRequests->{$key}}= @{$params{$key}};
- } elsif( "HASH" eq ref( $params{$key} ) ) {
- %{$hvRequests->{$key}}= %{$params{$key}};
- } elsif( "CODE" eq ref( $params{$key} ) ) {
- @{$hvRequests->{$key}}= &{$params{$key}};
- } else {
- die "Impossible value in \$params{$key}";
- }
- }
-}
-
-=item Myconst2perl
-
-Generates a file used to implement C constants as "constant subroutines" in
-a Perl module.
-
-Extracts a list of constants from a module's export list by C<eval>ing the
-first part of the Module's F<*.pm> file and then requesting some groups of
-symbols be exported/imported into a dummy package. Then writes C or C++
-code that can convert each C constant into a Perl "constant subroutine"
-whose name is the constant's name and whose value is the constant's value.
-
-=cut
-
-sub Myconst2perl
-{
- my( $pkg, %spec )= @_;
- my( $outfile, $writeperl, $ifdef, $export, $importto, @importlist,
- @perlfile, %perlcode, @cfile, %ccode, $routine );
- ParseAttribs( $pkg, \%spec, {
- DO_EXPORT => \$export,
- IMPORT_TO => \$importto,
- IMPORT_LIST => \@importlist,
- IFDEF => \$ifdef,
- WRITE_PERL => \$writeperl,
- OUTFILE => \$outfile,
- PERL_FILE_LIST => \@perlfile,
- PERL_FILE_CODES => \%perlcode,
- C_FILE_LIST => \@cfile,
- C_FILE_CODES => \%ccode,
- SUBROUTINE => \$routine,
- } );
- my $module= ( split /::/, $pkg )[-1];
-
- warn "Writing $outfile...\n";
- open( STDOUT, ">$outfile" ) or die "Can't create $outfile: $!\n";
-
- my $code= "";
- my $file;
- foreach $file ( @perlfile ) {
- warn "Reading Perl file, $file: $perlcode{$file}\n";
- open( MODULE, "<$file" ) or die "Can't read Perl file, $file: $!\n";
- eval qq[
- while( <MODULE> ) {
- $perlcode{$file};
- \$code .= \$_;
- }
- 1;
- ] or die "$file eval: $@\n";
- close( MODULE );
- }
-
- print
- "/* $outfile - Generated by ExtUtils::Myconst2perl::Myconst2perl */\n";
- if( $routine ) {
- print "/* See start of $routine() for generation parameters used */\n";
- #print "#define main _main_proto"
- # " /* Ignore Perl's main() prototype */\n\n";
- if( $writeperl ) {
- # Here are more reasons why the WRITE_PERL option is discouraged.
- if( $Config{useperlio} ) {
- print "#define PERLIO_IS_STDIO 1\n";
- }
- print "#define WIN32IO_IS_STDIO 1\n"; # May cause a warning
- print "#define NO_XSLOCKS 1\n"; # What a hack!
- }
- foreach $file ( @cfile ) {
- warn "Reading C file, $file: $ccode{$file}\n";
- open( XS, "<$file" ) or die "Can't read C file, $file: $!\n";
- my $code= $ccode{$file};
- $code =~ s#\\#\\\\#g;
- $code =~ s#([^\s -~])#"\\x".sprintf "%02X",unpack "C",$1#ge;
- $code =~ s#[*]/#*\\/#g;
- print qq[\n/* Include $file: $code */\n];
- print qq[\n#line 1 "$file"\n];
- eval qq[
- while( <XS> ) {
- $ccode{$file};
- print;
- }
- 1;
- ] or die "$file eval: $@\n";
- close( XS );
- }
- #print qq[\n#undef main\n];
- print qq[\n#define CONST2WRITE_PERL\n];
- print qq[\n#include "const2perl.h"\n\n];
- if( $writeperl ) {
- print "int\nmain( int argc, char *argv[], char *envp[] )\n";
- } else {
- print "void\n$routine( void )\n";
- }
- }
- print "{\n";
-
- {
- @ExtUtils::Myconst2perl::importlist= @importlist;
- my $var= '@ExtUtils::Myconst2perl::importlist';
- my $port= $export ? "export" : "import";
- my $arg2= $export ? "q[$importto]," : "";
- local( $^W )= 0;
- eval $code . "{\n"
- . " { package $importto;\n"
- . " warn qq[\u${port}ing to $importto: $var\\n];\n"
- . " \$pkg->$port( $arg2 $var );\n"
- . " }\n"
- . " { no strict 'refs';\n"
- . " $var= sort keys %{'_constants::'}; }\n"
- . " warn 0 + $var, qq[ symbols ${port}ed.\\n];\n"
- . "}\n1;\n"
- or die "eval: $@\n";
- }
- my @syms= @ExtUtils::Myconst2perl::importlist;
-
- my $if;
- my $const;
- print qq[ START_CONSTS( "$pkg" ) /* No ";" */\n];
- {
- my( $head, $tail )= ( "/*", "\n" );
- if( $writeperl ) {
- $head= ' printf( "#';
- $tail= '\\n" );' . "\n";
- print $head, " Generated by $outfile.", $tail;
- }
- print $head, " Package $pkg with options:", $tail;
- $head= " *" if ! $writeperl;
- my $key;
- foreach $key ( sort keys %spec ) {
- my $val= neatvalue($spec{$key});
- $val =~ s/\\/\\\\/g if $writeperl;
- print $head, " $key => ", $val, $tail;
- }
- print $head, " Perl files eval'd:", $tail;
- foreach $key ( @perlfile ) {
- my $code= $perlcode{$key};
- $code =~ s#\\#\\\\#g;
- $code =~ s#([^ -~])#"\\".sprintf "%03o",unpack "C",$1#ge;
- $code =~ s#"#\\"#g if $writeperl;
- print $head, " $key => ", $code, $tail;
- }
- if( $writeperl ) {
- print $head, " C files included:", $tail;
- foreach $key ( @cfile ) {
- my $code= $ccode{$key};
- $code =~ s#\\#\\\\#g;
- $code =~ s#([^ -~])#"\\".sprintf "%03o",unpack "C",$1#ge;
- $code =~ s#"#\\"#g;
- print $head, " $key => ", $code, $tail;
- }
- } else {
- print " */\n";
- }
- }
- if( ! ref($ifdef) && $ifdef =~ /[^\s\w]/ ) {
- my $sub= $ifdef;
- $sub= 'sub { local($_)= @_; ' . $sub . ' }'
- unless $sub =~ /^\s*sub\b/;
- $ifdef= eval $sub;
- die "$@: $sub\n" if $@;
- if( "CODE" ne ref($ifdef) ) {
- die "IFDEF didn't create subroutine reference: eval $sub\n";
- }
- }
- foreach $const ( @syms ) {
- $if= "CODE" eq ref($ifdef) ? $ifdef->($const) : $ifdef;
- if( ! $if ) {
- $if= "";
- } elsif( "1" eq $if ) {
- $if= "#ifdef $const\n";
- } elsif( $if !~ /^#/ ) {
- $if= "#ifdef $if\n";
- } else {
- $if= "$if\n";
- }
- print $if
- . qq[ const2perl( $const );\n];
- if( $if ) {
- print "#else\n"
- . qq[ noconst( $const );\n]
- . "#endif\n";
- }
- }
- if( $writeperl ) {
- print
- qq[ printf( "1;\\n" );\n],
- qq[ return( 0 );\n];
- }
- print "}\n";
-}
-
-1;
+# This should eventually become part of MakeMaker as ExtUtils::Mkconst2perl.\r
+# Documentation for this is very skimpy at this point. Full documentation\r
+# will be added to ExtUtils::Mkconst2perl when it is created.\r
+package # Hide from PAUSE\r
+ ExtUtils::Myconst2perl;\r
+\r
+use strict;\r
+use Config;\r
+\r
+use vars qw( @ISA @EXPORT @EXPORT_OK $VERSION );\r
+BEGIN {\r
+ require Exporter;\r
+ push @ISA, 'Exporter';\r
+ @EXPORT= qw( &Myconst2perl );\r
+ @EXPORT_OK= qw( &ParseAttribs );\r
+ $VERSION= 1.00;\r
+}\r
+\r
+use Carp;\r
+use File::Basename;\r
+use ExtUtils::MakeMaker qw( neatvalue );\r
+\r
+# Return the extension to use for a file of C++ source code:\r
+sub _cc\r
+{\r
+ # Some day, $Config{_cc} might be defined for us:\r
+ return $Config{_cc} if $Config{_cc};\r
+ return ".cxx"; # Seems to be the most widely accepted extension.\r
+}\r
+\r
+=item ParseAttribs\r
+\r
+Parses user-firendly options into coder-firendly specifics.\r
+\r
+=cut\r
+\r
+sub ParseAttribs\r
+{\r
+ # Usage: ParseAttribs( "Package::Name", \%opts, {opt=>\$var} );\r
+ my( $pkg, $hvAttr, $hvRequests )= @_;\r
+ my( $outfile, @perlfiles, %perlfilecodes, @cfiles, %cfilecodes );\r
+ my @importlist= @{$hvAttr->{IMPORT_LIST}};\r
+ my $perlcode= $hvAttr->{PERL_PE_CODE} ||\r
+ 'last if /^\s*(bootstrap|XSLoader::load)\b/';\r
+ my $ccode= $hvAttr->{C_PE_CODE} ||\r
+ 'last if m#/[/*]\s*CONSTS_DEFINED\b|^\s*MODULE\b#';\r
+ my $ifdef= $hvAttr->{IFDEF} || 0;\r
+ my $writeperl= !! $hvAttr->{WRITE_PERL};\r
+ my $export= !! $hvAttr->{DO_EXPORT};\r
+ my $importto= $hvAttr->{IMPORT_TO} || "_constants";\r
+ my $cplusplus= $hvAttr->{CPLUSPLUS};\r
+ $cplusplus= "" if ! defined $cplusplus;\r
+ my $object= "";\r
+ my $binary= "";\r
+ my $final= "";\r
+ my $norebuild= "";\r
+ my $subroutine= "";\r
+ my $base;\r
+ my %params= (\r
+ PERL_PE_CODE => \$perlcode,\r
+ PERL_FILE_LIST => \@perlfiles,\r
+ PERL_FILE_CODES => \%perlfilecodes,\r
+ PERL_FILES => sub { map {($_,$perlfilecodes{$_})} @perlfiles },\r
+ C_PE_CODE => \$ccode,\r
+ C_FILE_LIST => \@cfiles,\r
+ C_FILE_CODES => \%cfilecodes,\r
+ C_FILES => sub { map {($_,$cfilecodes{$_})} @cfiles },\r
+ DO_EXPORT => \$export,\r
+ IMPORT_TO => \$importto,\r
+ IMPORT_LIST => \@importlist,\r
+ SUBROUTINE => \$subroutine,\r
+ IFDEF => \$ifdef,\r
+ WRITE_PERL => \$writeperl,\r
+ CPLUSPLUS => \$cplusplus,\r
+ BASEFILENAME => \$base,\r
+ OUTFILE => \$outfile,\r
+ OBJECT => \$object,\r
+ BINARY => \$binary,\r
+ FINAL_PERL => \$final,\r
+ NO_REBUILD => \$norebuild,\r
+ );\r
+ { my @err= grep {! defined $params{$_}} keys %$hvAttr;\r
+ carp "ExtUtils::Myconst2perl::ParseAttribs: ",\r
+ "Unsupported option(s) (@err).\n"\r
+ if @err;\r
+ }\r
+ $norebuild= $hvAttr->{NO_REBUILD} if exists $hvAttr->{NO_REBUILD};\r
+ my $module= ( split /::/, $pkg )[-1];\r
+ $base= "c".$module;\r
+ $base= $hvAttr->{BASEFILENAME} if exists $hvAttr->{BASEFILENAME};\r
+ my $ext= ! $cplusplus ? ($Config{_c}||".c")\r
+ : $cplusplus =~ /^[.]/ ? $cplusplus : _cc();\r
+ if( $writeperl ) {\r
+ $outfile= $base . "_pc" . $ext;\r
+ $object= $base . "_pc" . ($Config{_o}||$Config{obj_ext});\r
+ $object= $hvAttr->{OBJECT} if $hvAttr->{OBJECT};\r
+ $binary= $base . "_pc" . ($Config{_exe}||$Config{exe_ext});\r
+ $binary= $hvAttr->{BINARY} if $hvAttr->{BINARY};\r
+ $final= $base . ".pc";\r
+ $final= $hvAttr->{FINAL_PERL} if $hvAttr->{FINAL_PERL};\r
+ $subroutine= "main";\r
+ } elsif( $cplusplus ) {\r
+ $outfile= $base . $ext;\r
+ $object= $base . ($Config{_o}||$Config{obj_ext});\r
+ $object= $hvAttr->{OBJECT} if $hvAttr->{OBJECT};\r
+ $subroutine= "const2perl_" . $pkg;\r
+ $subroutine =~ s/\W/_/g;\r
+ } else {\r
+ $outfile= $base . ".h";\r
+ }\r
+ $outfile= $hvAttr->{OUTFILE} if $hvAttr->{OUTFILE};\r
+ if( $hvAttr->{PERL_FILES} ) {\r
+ carp "ExtUtils::Myconst2perl: PERL_FILES option not allowed ",\r
+ "with PERL_FILE_LIST nor PERL_FILE_CODES.\n"\r
+ if $hvAttr->{PERL_FILE_LIST} || $hvAttr->{PERL_FILE_CODES};\r
+ %perlfilecodes= @{$hvAttr->{PERL_FILES}};\r
+ my $odd= 0;\r
+ @perlfiles= grep {$odd= !$odd} @{$hvAttr->{PERL_FILES}};\r
+ } else {\r
+ if( $hvAttr->{PERL_FILE_LIST} ) {\r
+ @perlfiles= @{$hvAttr->{PERL_FILE_LIST}};\r
+ } elsif( $hvAttr->{PERL_FILE_CODES} ) {\r
+ @perlfiles= keys %{$hvAttr->{PERL_FILE_CODES}};\r
+ } else {\r
+ @perlfiles= ( "$module.pm" );\r
+ }\r
+ %perlfilecodes= %{$hvAttr->{PERL_FILE_CODES}}\r
+ if $hvAttr->{PERL_FILE_CODES};\r
+ }\r
+ for my $file ( @perlfiles ) {\r
+ $perlfilecodes{$file}= $perlcode if ! $perlfilecodes{$file};\r
+ }\r
+ if( ! $subroutine ) {\r
+ ; # Don't process any C source code files.\r
+ } elsif( $hvAttr->{C_FILES} ) {\r
+ carp "ExtUtils::Myconst2perl: C_FILES option not allowed ",\r
+ "with C_FILE_LIST nor C_FILE_CODES.\n"\r
+ if $hvAttr->{C_FILE_LIST} || $hvAttr->{C_FILE_CODES};\r
+ %cfilecodes= @{$hvAttr->{C_FILES}};\r
+ my $odd= 0;\r
+ @cfiles= grep {$odd= !$odd} @{$hvAttr->{C_FILES}};\r
+ } else {\r
+ if( $hvAttr->{C_FILE_LIST} ) {\r
+ @cfiles= @{$hvAttr->{C_FILE_LIST}};\r
+ } elsif( $hvAttr->{C_FILE_CODES} ) {\r
+ @cfiles= keys %{$hvAttr->{C_FILE_CODES}};\r
+ } elsif( $writeperl || $cplusplus ) {\r
+ @cfiles= ( "$module.xs" );\r
+ }\r
+ %cfilecodes= %{$hvAttr->{C_FILE_CODES}} if $hvAttr->{C_FILE_CODES};\r
+ }\r
+ for my $file ( @cfiles ) {\r
+ $cfilecodes{$file}= $ccode if ! $cfilecodes{$file};\r
+ }\r
+ for my $key ( keys %$hvRequests ) {\r
+ if( ! $params{$key} ) {\r
+ carp "ExtUtils::Myconst2perl::ParseAttribs: ",\r
+ "Unsupported output ($key).\n";\r
+ } elsif( "SCALAR" eq ref( $params{$key} ) ) {\r
+ ${$hvRequests->{$key}}= ${$params{$key}};\r
+ } elsif( "ARRAY" eq ref( $params{$key} ) ) {\r
+ @{$hvRequests->{$key}}= @{$params{$key}};\r
+ } elsif( "HASH" eq ref( $params{$key} ) ) {\r
+ %{$hvRequests->{$key}}= %{$params{$key}};\r
+ } elsif( "CODE" eq ref( $params{$key} ) ) {\r
+ @{$hvRequests->{$key}}= &{$params{$key}};\r
+ } else {\r
+ die "Impossible value in \$params{$key}";\r
+ }\r
+ }\r
+}\r
+\r
+=item Myconst2perl\r
+\r
+Generates a file used to implement C constants as "constant subroutines" in\r
+a Perl module.\r
+\r
+Extracts a list of constants from a module's export list by C<eval>ing the\r
+first part of the Module's F<*.pm> file and then requesting some groups of\r
+symbols be exported/imported into a dummy package. Then writes C or C++\r
+code that can convert each C constant into a Perl "constant subroutine"\r
+whose name is the constant's name and whose value is the constant's value.\r
+\r
+=cut\r
+\r
+sub Myconst2perl\r
+{\r
+ my( $pkg, %spec )= @_;\r
+ my( $outfile, $writeperl, $ifdef, $export, $importto, @importlist,\r
+ @perlfile, %perlcode, @cfile, %ccode, $routine );\r
+ ParseAttribs( $pkg, \%spec, {\r
+ DO_EXPORT => \$export,\r
+ IMPORT_TO => \$importto,\r
+ IMPORT_LIST => \@importlist,\r
+ IFDEF => \$ifdef,\r
+ WRITE_PERL => \$writeperl,\r
+ OUTFILE => \$outfile,\r
+ PERL_FILE_LIST => \@perlfile,\r
+ PERL_FILE_CODES => \%perlcode,\r
+ C_FILE_LIST => \@cfile,\r
+ C_FILE_CODES => \%ccode,\r
+ SUBROUTINE => \$routine,\r
+ } );\r
+ my $module= ( split /::/, $pkg )[-1];\r
+\r
+ warn "Writing $outfile...\n";\r
+ open( STDOUT, ">$outfile" ) or die "Can't create $outfile: $!\n";\r
+\r
+ my $code= "";\r
+ my $file;\r
+ foreach $file ( @perlfile ) {\r
+ warn "Reading Perl file, $file: $perlcode{$file}\n";\r
+ open( MODULE, "<$file" ) or die "Can't read Perl file, $file: $!\n";\r
+ eval qq[\r
+ while( <MODULE> ) {\r
+ $perlcode{$file};\r
+ \$code .= \$_;\r
+ }\r
+ 1;\r
+ ] or die "$file eval: $@\n";\r
+ close( MODULE );\r
+ }\r
+\r
+ print\r
+ "/* $outfile - Generated by ExtUtils::Myconst2perl::Myconst2perl */\n";\r
+ if( $routine ) {\r
+ print "/* See start of $routine() for generation parameters used */\n";\r
+ #print "#define main _main_proto"\r
+ # " /* Ignore Perl's main() prototype */\n\n";\r
+ if( $writeperl ) {\r
+ # Here are more reasons why the WRITE_PERL option is discouraged.\r
+ if( $Config{useperlio} ) {\r
+ print "#define PERLIO_IS_STDIO 1\n";\r
+ }\r
+ print "#define WIN32IO_IS_STDIO 1\n"; # May cause a warning\r
+ print "#define NO_XSLOCKS 1\n"; # What a hack!\r
+ }\r
+ foreach $file ( @cfile ) {\r
+ warn "Reading C file, $file: $ccode{$file}\n";\r
+ open( XS, "<$file" ) or die "Can't read C file, $file: $!\n";\r
+ my $code= $ccode{$file};\r
+ $code =~ s#\\#\\\\#g;\r
+ $code =~ s#([^\s -~])#"\\x".sprintf "%02X",unpack "C",$1#ge;\r
+ $code =~ s#[*]/#*\\/#g;\r
+ print qq[\n/* Include $file: $code */\n];\r
+ print qq[\n#line 1 "$file"\n];\r
+ eval qq[\r
+ while( <XS> ) {\r
+ $ccode{$file};\r
+ print;\r
+ }\r
+ 1;\r
+ ] or die "$file eval: $@\n";\r
+ close( XS );\r
+ }\r
+ #print qq[\n#undef main\n];\r
+ print qq[\n#define CONST2WRITE_PERL\n];\r
+ print qq[\n#include "const2perl.h"\n\n];\r
+ if( $writeperl ) {\r
+ print "int\nmain( int argc, char *argv[], char *envp[] )\n";\r
+ } else {\r
+ print "void\n$routine( void )\n";\r
+ }\r
+ }\r
+ print "{\n";\r
+\r
+ {\r
+ @ExtUtils::Myconst2perl::importlist= @importlist;\r
+ my $var= '@ExtUtils::Myconst2perl::importlist';\r
+ my $port= $export ? "export" : "import";\r
+ my $arg2= $export ? "q[$importto]," : "";\r
+ local( $^W )= 0;\r
+ eval $code . "{\n"\r
+ . " { package $importto;\n"\r
+ . " warn qq[\u${port}ing to $importto: $var\\n];\n"\r
+ . " \$pkg->$port( $arg2 $var );\n"\r
+ . " }\n"\r
+ . " { no strict 'refs';\n"\r
+ . " $var= sort keys %{'_constants::'}; }\n"\r
+ . " warn 0 + $var, qq[ symbols ${port}ed.\\n];\n"\r
+ . "}\n1;\n"\r
+ or die "eval: $@\n";\r
+ }\r
+ my @syms= @ExtUtils::Myconst2perl::importlist;\r
+\r
+ my $if;\r
+ my $const;\r
+ print qq[ START_CONSTS( "$pkg" ) /* No ";" */\n];\r
+ {\r
+ my( $head, $tail )= ( "/*", "\n" );\r
+ if( $writeperl ) {\r
+ $head= ' printf( "#';\r
+ $tail= '\\n" );' . "\n";\r
+ print $head, " Generated by $outfile.", $tail;\r
+ }\r
+ print $head, " Package $pkg with options:", $tail;\r
+ $head= " *" if ! $writeperl;\r
+ my $key;\r
+ foreach $key ( sort keys %spec ) {\r
+ my $val= neatvalue($spec{$key});\r
+ $val =~ s/\\/\\\\/g if $writeperl;\r
+ print $head, " $key => ", $val, $tail;\r
+ }\r
+ print $head, " Perl files eval'd:", $tail;\r
+ foreach $key ( @perlfile ) {\r
+ my $code= $perlcode{$key};\r
+ $code =~ s#\\#\\\\#g;\r
+ $code =~ s#([^ -~])#"\\".sprintf "%03o",unpack "C",$1#ge;\r
+ $code =~ s#"#\\"#g if $writeperl;\r
+ print $head, " $key => ", $code, $tail;\r
+ }\r
+ if( $writeperl ) {\r
+ print $head, " C files included:", $tail;\r
+ foreach $key ( @cfile ) {\r
+ my $code= $ccode{$key};\r
+ $code =~ s#\\#\\\\#g;\r
+ $code =~ s#([^ -~])#"\\".sprintf "%03o",unpack "C",$1#ge;\r
+ $code =~ s#"#\\"#g;\r
+ print $head, " $key => ", $code, $tail;\r
+ }\r
+ } else {\r
+ print " */\n";\r
+ }\r
+ }\r
+ if( ! ref($ifdef) && $ifdef =~ /[^\s\w]/ ) {\r
+ my $sub= $ifdef;\r
+ $sub= 'sub { local($_)= @_; ' . $sub . ' }'\r
+ unless $sub =~ /^\s*sub\b/;\r
+ $ifdef= eval $sub;\r
+ die "$@: $sub\n" if $@;\r
+ if( "CODE" ne ref($ifdef) ) {\r
+ die "IFDEF didn't create subroutine reference: eval $sub\n";\r
+ }\r
+ }\r
+ foreach $const ( @syms ) {\r
+ $if= "CODE" eq ref($ifdef) ? $ifdef->($const) : $ifdef;\r
+ if( ! $if ) {\r
+ $if= "";\r
+ } elsif( "1" eq $if ) {\r
+ $if= "#ifdef $const\n";\r
+ } elsif( $if !~ /^#/ ) {\r
+ $if= "#ifdef $if\n";\r
+ } else {\r
+ $if= "$if\n";\r
+ }\r
+ print $if\r
+ . qq[ const2perl( $const );\n];\r
+ if( $if ) {\r
+ print "#else\n"\r
+ . qq[ noconst( $const );\n]\r
+ . "#endif\n";\r
+ }\r
+ }\r
+ if( $writeperl ) {\r
+ print\r
+ qq[ printf( "1;\\n" );\n],\r
+ qq[ return( 0 );\n];\r
+ }\r
+ print "}\n";\r
+}\r
+\r
+1;\r
-#!/usr/bin/perl -w
-# Before `make install' is performed this script should be runnable with
-# `make test'. After `make install' it should work as `perl test.pl'
-
-######################### We start with some black magic to print on failure.
-
-BEGIN {
- $|= 1;
-
- # when building perl, skip this test if Win32API::File isn't being built
- if ( $ENV{PERL_CORE} ) {
- require Config;
- if ( $Config::Config{extensions} !~ m:(?<!\S)Win32API/File(?!\S): ) {
- print "1..0 # Skip Win32API::File extension not built\n";
- exit();
- }
- }
-
- print "1..270\n";
-}
-END {print "not ok 1\n" unless $loaded;}
-
-# Win32API::File does an implicit "require Win32", but
-# the ../lib directory in @INC will no longer work once
-# we chdir() into the TEMP directory.
-
-use Win32;
-use File::Spec;
-use Carp;
-use Carp::Heavy;
-
-use Win32API::File qw(:ALL);
-$loaded = 1;
-print "ok 1\n";
-
-######################### End of black magic.
-
-$test= 1;
-
-use strict qw(subs);
-
-$temp= File::Spec->tmpdir();
-$dir= "W32ApiF.tmp";
-
-$ENV{WINDIR} = $ENV{SYSTEMROOT} if not exists $ENV{WINDIR};
-
-chdir( $temp )
- or die "# Can't cd to temp directory, $temp: $!\n";
-$tempdir = File::Spec->catdir($temp,$dir);
-if( -d $dir ) {
- print "# deleting ",File::Spec->catdir($temp,$dir,'*'),"\n" if glob "$dir/*";
-
- for (glob "$dir/*") {
- chmod 0777, $_;
- unlink $_;
- }
- rmdir $dir or die "Could not rmdir $dir: $!";
-}
-mkdir( $dir, 0777 )
- or die "# Can't create temp dir, $tempdir: $!\n";
-print "# chdir $tempdir\n";
-chdir( $dir )
- or die "# Can't cd to my dir, $tempdir: $!\n";
-$h1= createFile( "ReadOnly.txt", "r", { Attributes=>"r" } );
-$ok= ! $h1 && Win32API::File::_fileLastError() == 2; # could not find the file
-$ok or print "# ","".fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 2
-if( ! $ok ) { CloseHandle($h1); unlink("ReadOnly.txt"); }
-
-$ok= $h1= createFile( "ReadOnly.txt", "wcn", { Attributes=>"r" } );
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 3
-
-$ok= WriteFile( $h1, "Original text\n", 0, [], [] );
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 4
-
-$h2= createFile( "ReadOnly.txt", "rcn" );
-$ok= ! $h2 && Win32API::File::_fileLastError() == 80; # file exists
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 5
-if( ! $ok ) { CloseHandle($h2); }
-
-$h2= createFile( "ReadOnly.txt", "rwke" );
-$ok= ! $h2 && Win32API::File::_fileLastError() == 5; # access is denied
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 6
-if( ! $ok ) { CloseHandle($h2); }
-
-$ok= $h2= createFile( "ReadOnly.txt", "r" );
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 7
-
-$ok= SetFilePointer( $h1, length("Original"), [], FILE_BEGIN );
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 8
-
-$ok= WriteFile( $h1, "ly was other text\n", 0, $len, [] )
- && $len == length("ly was other text\n");
-$ok or print "# <$len> should be <",
- length("ly was other text\n"),">: ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 9
-
-$ok= ReadFile( $h2, $text, 80, $len, [] )
- && $len == length($text);
-$ok or print "# <$len> should be <",length($text),
- ">: ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 10
-
-$ok= $text eq "Originally was other text\n";
-if( !$ok ) {
- $text =~ s/\r/\\r/g; $text =~ s/\n/\\n/g;
- print "# <$text> should be <Originally was other text\\n>.\n";
-}
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 11
-
-$ok= CloseHandle($h2);
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 12
-
-$ok= ! ReadFile( $h2, $text, 80, $len, [] )
- && Win32API::File::_fileLastError() == 6; # handle is invalid
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 13
-
-CloseHandle($h1);
-
-$ok= $h1= createFile( "CanWrite.txt", "rw", FILE_SHARE_WRITE,
- { Create=>CREATE_ALWAYS } );
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 14
-
-$ok= WriteFile( $h1, "Just this and not this", 10, [], [] );
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 15
-
-$ok= $h2= createFile( "CanWrite.txt", "wk", { Share=>"rw" } );
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 16
-
-$ok= OsFHandleOpen( "APP", $h2, "wat" );
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 17
-
-$ok= $h2 == GetOsFHandle( "APP" );
-$ok or print "# $h2 != ",GetOsFHandle("APP"),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 18
-
-{ my $save= select(APP); $|= 1; select($save); }
-$ok= print APP "is enough\n";
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 19
-
-SetFilePointer($h1, 0, [], FILE_BEGIN) if $^O eq 'cygwin';
-
-$ok= ReadFile( $h1, $text, 0, [], [] );
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 20
-
-$ok= $text eq "is enough\r\n";
-if( !$ok ) {
- $text =~ s/\r/\\r/g;
- $text =~ s/\n/\\n/g;
- print "# <$text> should be <is enough\\r\\n>\n";
-}
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 21
-
-$skip = "";
-if ($^O eq 'cygwin') {
- $ok = 1;
- $skip = " # skip cygwin can delete open files";
-}
-else {
- unlink("CanWrite.txt");
- $ok = -e "CanWrite.txt" && $! =~ /permission denied/i;
- $ok or print "# $!\n";
-}
-print $ok ? "" : "not ", "ok ", ++$test, "$skip\n"; # ok 22
-
-close(APP); # Also does C<CloseHandle($h2)>
-## CloseHandle( $h2 );
-CloseHandle( $h1 );
-
-$ok= ! DeleteFile( "ReadOnly.txt" )
- && Win32API::File::_fileLastError() == 5; # access is denied
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 23
-
-$ok= ! CopyFile( "ReadOnly.txt", "CanWrite.txt", 1 )
- && Win32API::File::_fileLastError() == 80; # file exists
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 24
-
-$ok= ! CopyFile( "CanWrite.txt", "ReadOnly.txt", 0 )
- && Win32API::File::_fileLastError() == 5; # access is denied
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 25
-
-$ok= ! MoveFile( "NoSuchFile", "NoSuchDest" )
- && Win32API::File::_fileLastError() == 2; # not find the file
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 26
-
-$ok= ! MoveFileEx( "NoSuchFile", "NoSuchDest", 0 )
- && Win32API::File::_fileLastError() == 2; # not find the file
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 27
-
-$ok= ! MoveFile( "ReadOnly.txt", "CanWrite.txt" )
- && Win32API::File::_fileLastError() == 183; # file already exists
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 28
-
-$ok= ! MoveFileEx( "ReadOnly.txt", "CanWrite.txt", 0 )
- && Win32API::File::_fileLastError() == 183; # file already exists
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 29
-
-$ok= CopyFile( "ReadOnly.txt", "ReadOnly.cp", 1 )
- && CopyFile( "CanWrite.txt", "CanWrite.cp", 1 );
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 30
-
-$ok= ! MoveFileEx( "CanWrite.txt", "ReadOnly.cp", MOVEFILE_REPLACE_EXISTING )
- && (Win32API::File::_fileLastError() == 5 # access is denied
- || Win32API::File::_fileLastError() == 183); # already exists
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 31
-
-$ok= MoveFileEx( "ReadOnly.cp", "CanWrite.cp", MOVEFILE_REPLACE_EXISTING );
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 32
-
-$ok= MoveFile( "CanWrite.cp", "Moved.cp" );
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 33
-
-$ok= ! unlink( "ReadOnly.cp" )
- && $! =~ /no such file/i
- && ! unlink( "CanWrite.cp" )
- && $! =~ /no such file/i;
-$ok or print "# $!\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 34
-
-$ok= ! DeleteFile( "Moved.cp" )
- && Win32API::File::_fileLastError() == 5; # access is denied
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 35
-
-if ($^O eq 'cygwin') {
- chmod( 0200 | 07777 & (stat("Moved.cp"))[2], "Moved.cp" );
-}
-else {
- system( "attrib -r Moved.cp" );
-}
-
-$ok= DeleteFile( "Moved.cp" );
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 36
-
-$new= SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX;
-$old= SetErrorMode( $new );
-$renew= SetErrorMode( $old );
-$reold= SetErrorMode( $old );
-
-$ok= $old == $reold;
-$ok or print "# $old != $reold: ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 37
-
-$ok= ($renew&$new) == $new;
-$ok or print "# $new != $renew: ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 38
-
-$ok= @drives= getLogicalDrives();
-$ok && print "# @drives\n";
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 39
-
-$ok= $drives[0] !~ /^[ab]/ || DRIVE_REMOVABLE == GetDriveType($drives[0]);
-$ok or print "# ",DRIVE_REMOVABLE," != ",GetDriveType($drives[0]),
- ": ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 40
-
-$drive= substr( $ENV{WINDIR}, 0, 3 );
-
-$ok= 1 == grep /^\Q$drive\E/i, @drives;
-$ok or print "# No $drive found in list of drives.\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 41
-
-$ok= DRIVE_FIXED == GetDriveType( $drive );
-$ok or print
- "# ",DRIVE_FIXED," != ",GetDriveType($drive),": ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 42
-
-$ok= GetVolumeInformation( $drive, $vol, 64, $ser, $max, $flag, $fs, 16 );
-$ok or print "# ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 43
-$vol= $ser= $max= $flag= $fs= ""; # Prevent warnings.
-
-chop($drive);
-$ok= QueryDosDevice( $drive, $dev, 80 );
-$ok or print "# $drive: ",fileLastError(),"\n";
-if( $ok ) {
- ( $text= $dev ) =~ s/\0/\\0/g;
- print "# $drive => $text\n";
-}
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 44
-
-$bits= GetLogicalDrives();
-$let= 25;
-$bit= 1<<$let;
-while( $bit & $bits ) {
- $let--;
- $bit >>= 1;
-}
-$let= pack( "C", $let + unpack("C","A") ) . ":";
-print "# Querying undefined $let.\n";
-
-$ok= DefineDosDevice( 0, $let, $ENV{WINDIR} );
-$ok or print "# $let,$ENV{WINDIR}: ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 45
-
-$ok= -s $let."/Win.ini" == -s $ENV{WINDIR}."/Win.ini";
-$ok or print "# ", -s $let."/Win.ini", " vs. ",
- -s $ENV{WINDIR}."/Win.ini", ": ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 46
-
-$ok= DefineDosDevice( DDD_REMOVE_DEFINITION|DDD_EXACT_MATCH_ON_REMOVE,
- $let, $ENV{WINDIR} );
-$ok or print "# $let,$ENV{WINDIR}: ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 47
-
-$ok= ! -f $let."/Win.ini"
- && $! =~ /no such file/i;
-$ok or print "# $!\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 48
-
-$ok= DefineDosDevice( DDD_RAW_TARGET_PATH, $let, $dev );
-if( !$ok ) {
- ( $text= $dev ) =~ s/\0/\\0/g;
- print "# $let,$text: ",fileLastError(),"\n";
-}
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 49
-
-my $path = $ENV{WINDIR};
-$ok= -f $let.substr($path,$^O eq 'cygwin'?2:3)."/win.ini";
-$ok or print "# ",$let.substr($path,3)."/win.ini ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 50
-
-$ok= DefineDosDevice( DDD_REMOVE_DEFINITION|DDD_EXACT_MATCH_ON_REMOVE
- |DDD_RAW_TARGET_PATH, $let, $dev );
-$ok or print "# $let,$dev: ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 51
-
-my $attrs = GetFileAttributes( $path );
-$ok= $attrs != INVALID_FILE_ATTRIBUTES;
-$ok or print "# $path gave invalid attribute value, attrs=$attrs: ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 52
-
-$ok= ($attrs & FILE_ATTRIBUTE_DIRECTORY);
-$ok or print "# $path not a directory, attrs=$attrs: ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 53
-
-$path .= "/win.ini";
-$attrs = GetFileAttributes( $path );
-$ok= $attrs != INVALID_FILE_ATTRIBUTES;
-$ok or print "# $path gave invalid attribute value, attrs=$attrs: ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 54
-
-$ok= !($attrs & FILE_ATTRIBUTE_DIRECTORY);
-$ok or print "# $path is a directory, attrs=$attrs: ",fileLastError(),"\n";
-print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 55
-
-# DefineDosDevice
-# GetFileType
-# GetVolumeInformation
-# QueryDosDevice
-#Add a drive letter that points to our temp directory
-#Add a drive letter that points to the drive our directory is in
-
-#winnt.t:
-# get first drive letters and use to test disk and storage IOCTLs
-# "//./PhysicalDrive0"
-# DeviceIoControl
-
-my %consts;
-my @consts= @Win32API::File::EXPORT_OK;
-@consts{@consts}= @consts;
-
-my( @noargs, %noargs )= qw(
- attrLetsToBits fileLastError getLogicalDrives GetLogicalDrives );
-@noargs{@noargs}= @noargs;
-
-foreach $func ( @{$Win32API::File::EXPORT_TAGS{Func}} ) {
- delete $consts{$func};
- if( defined( $noargs{$func} ) ) {
- $ok= ! eval("$func(0,0)") && $@ =~ /(::|\s)_?${func}A?[(:\s]/;
- } else {
- $ok= ! eval("$func()") && $@ =~ /(::|\s)_?${func}A?[(:\s]/;
- }
- $ok or print "# $func: $@\n";
- print $ok ? "" : "not ", "ok ", ++$test, "\n";
-}
-
-foreach $func ( @{$Win32API::File::EXPORT_TAGS{FuncA}},
- @{$Win32API::File::EXPORT_TAGS{FuncW}} ) {
- $ok= ! eval("$func()") && $@ =~ /::_?${func}\(/;
- delete $consts{$func};
- $ok or print "# $func: $@\n";
- print $ok ? "" : "not ", "ok ", ++$test, "\n";
-}
-
-foreach $const ( keys(%consts) ) {
- $ok= eval("my \$x= $const(); 1");
- $ok or print "# Constant $const: $@\n";
- print $ok ? "" : "not ", "ok ", ++$test, "\n";
-}
-
-chdir( $temp );
-if (-e "$dir/ReadOnly.txt") {
- chmod 0777, "$dir/ReadOnly.txt";
- unlink "$dir/ReadOnly.txt";
-}
-unlink "$dir/CanWrite.txt" if -e "$dir/CanWrite.txt";
-rmdir $dir;
-
-__END__
+#!/usr/bin/perl -w\r
+# Before `make install' is performed this script should be runnable with\r
+# `make test'. After `make install' it should work as `perl test.pl'\r
+\r
+######################### We start with some black magic to print on failure.\r
+\r
+BEGIN {\r
+ $|= 1;\r
+\r
+ # when building perl, skip this test if Win32API::File isn't being built\r
+ if ( $ENV{PERL_CORE} ) {\r
+ require Config;\r
+ if ( $Config::Config{extensions} !~ m:(?<!\S)Win32API/File(?!\S): ) {\r
+ print "1..0 # Skip Win32API::File extension not built\n";\r
+ exit();\r
+ }\r
+ }\r
+\r
+ print "1..270\n";\r
+}\r
+END {print "not ok 1\n" unless $loaded;}\r
+\r
+# Win32API::File does an implicit "require Win32", but\r
+# the ../lib directory in @INC will no longer work once\r
+# we chdir() into the TEMP directory.\r
+\r
+use Win32;\r
+use File::Spec;\r
+use Carp;\r
+use Carp::Heavy;\r
+\r
+use Win32API::File qw(:ALL);\r
+$loaded = 1;\r
+print "ok 1\n";\r
+\r
+######################### End of black magic.\r
+\r
+$test= 1;\r
+\r
+use strict qw(subs);\r
+\r
+$temp= File::Spec->tmpdir();\r
+$dir= "W32ApiF.tmp";\r
+\r
+$ENV{WINDIR} = $ENV{SYSTEMROOT} if not exists $ENV{WINDIR};\r
+\r
+chdir( $temp )\r
+ or die "# Can't cd to temp directory, $temp: $!\n";\r
+$tempdir = File::Spec->catdir($temp,$dir);\r
+if( -d $dir ) {\r
+ print "# deleting ",File::Spec->catdir($temp,$dir,'*'),"\n" if glob "$dir/*";\r
+\r
+ for (glob "$dir/*") {\r
+ chmod 0777, $_;\r
+ unlink $_;\r
+ }\r
+ rmdir $dir or die "Could not rmdir $dir: $!";\r
+}\r
+mkdir( $dir, 0777 )\r
+ or die "# Can't create temp dir, $tempdir: $!\n";\r
+print "# chdir $tempdir\n";\r
+chdir( $dir )\r
+ or die "# Can't cd to my dir, $tempdir: $!\n";\r
+$h1= createFile( "ReadOnly.txt", "r", { Attributes=>"r" } );\r
+$ok= ! $h1 && Win32API::File::_fileLastError() == 2; # could not find the file\r
+$ok or print "# ","".fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 2\r
+if( ! $ok ) { CloseHandle($h1); unlink("ReadOnly.txt"); }\r
+\r
+$ok= $h1= createFile( "ReadOnly.txt", "wcn", { Attributes=>"r" } );\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 3\r
+\r
+$ok= WriteFile( $h1, "Original text\n", 0, [], [] );\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 4\r
+\r
+$h2= createFile( "ReadOnly.txt", "rcn" );\r
+$ok= ! $h2 && Win32API::File::_fileLastError() == 80; # file exists\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 5\r
+if( ! $ok ) { CloseHandle($h2); }\r
+\r
+$h2= createFile( "ReadOnly.txt", "rwke" );\r
+$ok= ! $h2 && Win32API::File::_fileLastError() == 5; # access is denied\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 6\r
+if( ! $ok ) { CloseHandle($h2); }\r
+\r
+$ok= $h2= createFile( "ReadOnly.txt", "r" );\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 7\r
+\r
+$ok= SetFilePointer( $h1, length("Original"), [], FILE_BEGIN );\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 8\r
+\r
+$ok= WriteFile( $h1, "ly was other text\n", 0, $len, [] )\r
+ && $len == length("ly was other text\n");\r
+$ok or print "# <$len> should be <",\r
+ length("ly was other text\n"),">: ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 9\r
+\r
+$ok= ReadFile( $h2, $text, 80, $len, [] )\r
+ && $len == length($text);\r
+$ok or print "# <$len> should be <",length($text),\r
+ ">: ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 10\r
+\r
+$ok= $text eq "Originally was other text\n";\r
+if( !$ok ) {\r
+ $text =~ s/\r/\\r/g; $text =~ s/\n/\\n/g;\r
+ print "# <$text> should be <Originally was other text\\n>.\n";\r
+}\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 11\r
+\r
+$ok= CloseHandle($h2);\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 12\r
+\r
+$ok= ! ReadFile( $h2, $text, 80, $len, [] )\r
+ && Win32API::File::_fileLastError() == 6; # handle is invalid\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 13\r
+\r
+CloseHandle($h1);\r
+\r
+$ok= $h1= createFile( "CanWrite.txt", "rw", FILE_SHARE_WRITE,\r
+ { Create=>CREATE_ALWAYS } );\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 14\r
+\r
+$ok= WriteFile( $h1, "Just this and not this", 10, [], [] );\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 15\r
+\r
+$ok= $h2= createFile( "CanWrite.txt", "wk", { Share=>"rw" } );\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 16\r
+\r
+$ok= OsFHandleOpen( "APP", $h2, "wat" );\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 17\r
+\r
+$ok= $h2 == GetOsFHandle( "APP" );\r
+$ok or print "# $h2 != ",GetOsFHandle("APP"),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 18\r
+\r
+{ my $save= select(APP); $|= 1; select($save); }\r
+$ok= print APP "is enough\n";\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 19\r
+\r
+SetFilePointer($h1, 0, [], FILE_BEGIN) if $^O eq 'cygwin';\r
+\r
+$ok= ReadFile( $h1, $text, 0, [], [] );\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 20\r
+\r
+$ok= $text eq "is enough\r\n";\r
+if( !$ok ) {\r
+ $text =~ s/\r/\\r/g;\r
+ $text =~ s/\n/\\n/g;\r
+ print "# <$text> should be <is enough\\r\\n>\n";\r
+}\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 21\r
+\r
+$skip = "";\r
+if ($^O eq 'cygwin') {\r
+ $ok = 1;\r
+ $skip = " # skip cygwin can delete open files";\r
+}\r
+else {\r
+ unlink("CanWrite.txt");\r
+ $ok = -e "CanWrite.txt" && $! =~ /permission denied/i;\r
+ $ok or print "# $!\n";\r
+}\r
+print $ok ? "" : "not ", "ok ", ++$test, "$skip\n"; # ok 22\r
+\r
+close(APP); # Also does C<CloseHandle($h2)>\r
+## CloseHandle( $h2 );\r
+CloseHandle( $h1 );\r
+\r
+$ok= ! DeleteFile( "ReadOnly.txt" )\r
+ && Win32API::File::_fileLastError() == 5; # access is denied\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 23\r
+\r
+$ok= ! CopyFile( "ReadOnly.txt", "CanWrite.txt", 1 )\r
+ && Win32API::File::_fileLastError() == 80; # file exists\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 24\r
+\r
+$ok= ! CopyFile( "CanWrite.txt", "ReadOnly.txt", 0 )\r
+ && Win32API::File::_fileLastError() == 5; # access is denied\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 25\r
+\r
+$ok= ! MoveFile( "NoSuchFile", "NoSuchDest" )\r
+ && Win32API::File::_fileLastError() == 2; # not find the file\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 26\r
+\r
+$ok= ! MoveFileEx( "NoSuchFile", "NoSuchDest", 0 )\r
+ && Win32API::File::_fileLastError() == 2; # not find the file\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 27\r
+\r
+$ok= ! MoveFile( "ReadOnly.txt", "CanWrite.txt" )\r
+ && Win32API::File::_fileLastError() == 183; # file already exists\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 28\r
+\r
+$ok= ! MoveFileEx( "ReadOnly.txt", "CanWrite.txt", 0 )\r
+ && Win32API::File::_fileLastError() == 183; # file already exists\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 29\r
+\r
+$ok= CopyFile( "ReadOnly.txt", "ReadOnly.cp", 1 )\r
+ && CopyFile( "CanWrite.txt", "CanWrite.cp", 1 );\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 30\r
+\r
+$ok= ! MoveFileEx( "CanWrite.txt", "ReadOnly.cp", MOVEFILE_REPLACE_EXISTING )\r
+ && (Win32API::File::_fileLastError() == 5 # access is denied\r
+ || Win32API::File::_fileLastError() == 183); # already exists\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 31\r
+\r
+$ok= MoveFileEx( "ReadOnly.cp", "CanWrite.cp", MOVEFILE_REPLACE_EXISTING );\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 32\r
+\r
+$ok= MoveFile( "CanWrite.cp", "Moved.cp" );\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 33\r
+\r
+$ok= ! unlink( "ReadOnly.cp" )\r
+ && $! =~ /no such file/i\r
+ && ! unlink( "CanWrite.cp" )\r
+ && $! =~ /no such file/i;\r
+$ok or print "# $!\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 34\r
+\r
+$ok= ! DeleteFile( "Moved.cp" )\r
+ && Win32API::File::_fileLastError() == 5; # access is denied\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 35\r
+\r
+if ($^O eq 'cygwin') {\r
+ chmod( 0200 | 07777 & (stat("Moved.cp"))[2], "Moved.cp" );\r
+}\r
+else {\r
+ system( "attrib -r Moved.cp" );\r
+}\r
+\r
+$ok= DeleteFile( "Moved.cp" );\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 36\r
+\r
+$new= SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX;\r
+$old= SetErrorMode( $new );\r
+$renew= SetErrorMode( $old );\r
+$reold= SetErrorMode( $old );\r
+\r
+$ok= $old == $reold;\r
+$ok or print "# $old != $reold: ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 37\r
+\r
+$ok= ($renew&$new) == $new;\r
+$ok or print "# $new != $renew: ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 38\r
+\r
+$ok= @drives= getLogicalDrives();\r
+$ok && print "# @drives\n";\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 39\r
+\r
+$ok= $drives[0] !~ /^[ab]/ || DRIVE_REMOVABLE == GetDriveType($drives[0]);\r
+$ok or print "# ",DRIVE_REMOVABLE," != ",GetDriveType($drives[0]),\r
+ ": ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 40\r
+\r
+$drive= substr( $ENV{WINDIR}, 0, 3 );\r
+\r
+$ok= 1 == grep /^\Q$drive\E/i, @drives;\r
+$ok or print "# No $drive found in list of drives.\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 41\r
+\r
+$ok= DRIVE_FIXED == GetDriveType( $drive );\r
+$ok or print\r
+ "# ",DRIVE_FIXED," != ",GetDriveType($drive),": ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 42\r
+\r
+$ok= GetVolumeInformation( $drive, $vol, 64, $ser, $max, $flag, $fs, 16 );\r
+$ok or print "# ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 43\r
+$vol= $ser= $max= $flag= $fs= ""; # Prevent warnings.\r
+\r
+chop($drive);\r
+$ok= QueryDosDevice( $drive, $dev, 80 );\r
+$ok or print "# $drive: ",fileLastError(),"\n";\r
+if( $ok ) {\r
+ ( $text= $dev ) =~ s/\0/\\0/g;\r
+ print "# $drive => $text\n";\r
+}\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 44\r
+\r
+$bits= GetLogicalDrives();\r
+$let= 25;\r
+$bit= 1<<$let;\r
+while( $bit & $bits ) {\r
+ $let--;\r
+ $bit >>= 1;\r
+}\r
+$let= pack( "C", $let + unpack("C","A") ) . ":";\r
+print "# Querying undefined $let.\n";\r
+\r
+$ok= DefineDosDevice( 0, $let, $ENV{WINDIR} );\r
+$ok or print "# $let,$ENV{WINDIR}: ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 45\r
+\r
+$ok= -s $let."/Win.ini" == -s $ENV{WINDIR}."/Win.ini";\r
+$ok or print "# ", -s $let."/Win.ini", " vs. ",\r
+ -s $ENV{WINDIR}."/Win.ini", ": ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 46\r
+\r
+$ok= DefineDosDevice( DDD_REMOVE_DEFINITION|DDD_EXACT_MATCH_ON_REMOVE,\r
+ $let, $ENV{WINDIR} );\r
+$ok or print "# $let,$ENV{WINDIR}: ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 47\r
+\r
+$ok= ! -f $let."/Win.ini"\r
+ && $! =~ /no such file/i;\r
+$ok or print "# $!\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 48\r
+\r
+$ok= DefineDosDevice( DDD_RAW_TARGET_PATH, $let, $dev );\r
+if( !$ok ) {\r
+ ( $text= $dev ) =~ s/\0/\\0/g;\r
+ print "# $let,$text: ",fileLastError(),"\n";\r
+}\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 49\r
+\r
+my $path = $ENV{WINDIR};\r
+$ok= -f $let.substr($path,$^O eq 'cygwin'?2:3)."/win.ini";\r
+$ok or print "# ",$let.substr($path,3)."/win.ini ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 50\r
+\r
+$ok= DefineDosDevice( DDD_REMOVE_DEFINITION|DDD_EXACT_MATCH_ON_REMOVE\r
+ |DDD_RAW_TARGET_PATH, $let, $dev );\r
+$ok or print "# $let,$dev: ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 51\r
+\r
+my $attrs = GetFileAttributes( $path );\r
+$ok= $attrs != INVALID_FILE_ATTRIBUTES;\r
+$ok or print "# $path gave invalid attribute value, attrs=$attrs: ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 52\r
+\r
+$ok= ($attrs & FILE_ATTRIBUTE_DIRECTORY);\r
+$ok or print "# $path not a directory, attrs=$attrs: ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 53\r
+\r
+$path .= "/win.ini";\r
+$attrs = GetFileAttributes( $path );\r
+$ok= $attrs != INVALID_FILE_ATTRIBUTES;\r
+$ok or print "# $path gave invalid attribute value, attrs=$attrs: ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 54\r
+\r
+$ok= !($attrs & FILE_ATTRIBUTE_DIRECTORY);\r
+$ok or print "# $path is a directory, attrs=$attrs: ",fileLastError(),"\n";\r
+print $ok ? "" : "not ", "ok ", ++$test, "\n"; # ok 55\r
+\r
+# DefineDosDevice\r
+# GetFileType\r
+# GetVolumeInformation\r
+# QueryDosDevice\r
+#Add a drive letter that points to our temp directory\r
+#Add a drive letter that points to the drive our directory is in\r
+\r
+#winnt.t:\r
+# get first drive letters and use to test disk and storage IOCTLs\r
+# "//./PhysicalDrive0"\r
+# DeviceIoControl\r
+\r
+my %consts;\r
+my @consts= @Win32API::File::EXPORT_OK;\r
+@consts{@consts}= @consts;\r
+\r
+my( @noargs, %noargs )= qw(\r
+ attrLetsToBits fileLastError getLogicalDrives GetLogicalDrives );\r
+@noargs{@noargs}= @noargs;\r
+\r
+foreach $func ( @{$Win32API::File::EXPORT_TAGS{Func}} ) {\r
+ delete $consts{$func};\r
+ if( defined( $noargs{$func} ) ) {\r
+ $ok= ! eval("$func(0,0)") && $@ =~ /(::|\s)_?${func}A?[(:\s]/;\r
+ } else {\r
+ $ok= ! eval("$func()") && $@ =~ /(::|\s)_?${func}A?[(:\s]/;\r
+ }\r
+ $ok or print "# $func: $@\n";\r
+ print $ok ? "" : "not ", "ok ", ++$test, "\n";\r
+}\r
+\r
+foreach $func ( @{$Win32API::File::EXPORT_TAGS{FuncA}},\r
+ @{$Win32API::File::EXPORT_TAGS{FuncW}} ) {\r
+ $ok= ! eval("$func()") && $@ =~ /::_?${func}\(/;\r
+ delete $consts{$func};\r
+ $ok or print "# $func: $@\n";\r
+ print $ok ? "" : "not ", "ok ", ++$test, "\n";\r
+}\r
+\r
+foreach $const ( keys(%consts) ) {\r
+ $ok= eval("my \$x= $const(); 1");\r
+ $ok or print "# Constant $const: $@\n";\r
+ print $ok ? "" : "not ", "ok ", ++$test, "\n";\r
+}\r
+\r
+chdir( $temp );\r
+if (-e "$dir/ReadOnly.txt") {\r
+ chmod 0777, "$dir/ReadOnly.txt";\r
+ unlink "$dir/ReadOnly.txt";\r
+}\r
+unlink "$dir/CanWrite.txt" if -e "$dir/CanWrite.txt";\r
+rmdir $dir;\r
+\r
+__END__\r
BEGIN {
$|= 1;
+ use Test::More;
+
# when building perl, skip this test if Win32API::File isn't being built
if ( $ENV{PERL_CORE} ) {
- require Config;
- if ( $Config::Config{extensions} !~ m:(?<!\S)Win32API/File(?!\S): ) {
- print "1..0 # Skip Win32API::File extension not built\n";
- exit();
- }
+ require Config;
+ if ( $Config::Config{extensions} !~ m:(?<!\S)Win32API/File(?!\S): ) {
+ plan skip_all => 'Skip Win32API::File extension not built';
+ exit;
+ }
}
- print "1..10\n";
+ plan tests => 10;
}
-END { print "not ok 1\n" unless $main::loaded; }
use strict;
use warnings;
use Win32API::File qw(:ALL);
use IO::File;
-$main::loaded = 1;
-
-print "ok 1\n";
+my $filename = 'foo.txt';
+ok(! -e $filename || unlink($filename), "unlinked $filename (if it existed)");
-unlink "foo.txt";
-
-my $fh = Win32API::File->new("+> foo.txt")
- or die fileLastError();
+my $fh = Win32API::File->new("+> $filename")
+ or die fileLastError();
my $tell = tell $fh;
-print "# tell \$fh == '$tell'\n";
-print "not " unless
- tell $fh == 0;
-print "ok 2\n";
+is(0+$tell, 0, "tell \$fh == '$tell'");
my $text = "some text\n";
-print "not " unless
- print $fh $text;
-print "ok 3\n";
+ok(print($fh $text), "printed 'some text\\n'");
$tell = tell $fh;
-print "# after printing 'some text\\n', tell is: '$tell'\n";
-print "not " unless
- $tell == length($text) + 1;
-print "ok 4\n";
+my $len = length($text) + 1; # + 1 for cr
+is($tell, $len, "after printing 'some text\\n', tell is: '$tell'");
-print "not " unless
- seek($fh, 0, 0) == 0;
-print "ok 5\n";
+my $seek = seek($fh, 0, 0);
+is(0+$seek, 0, "seek is: '$seek'");
-print "not " unless
- not eof $fh;
-print "ok 6\n";
+my $eof = eof $fh;
+ok(! $eof, 'not eof');
my $readline = <$fh>;
my $pretty_readline = $readline;
-$pretty_readline =~ s/\r/\\r/g; $pretty_readline =~ s/\n/\\n/g;
-print "# read line is '$pretty_readline'\n";
-
-print "not " unless
- $readline eq "some text\r\n";
-print "ok 7\n";
+$pretty_readline =~ s/\r/\\r/g; $pretty_readline =~ s/\n/\\n/g;
+is($pretty_readline, "some text\\r\\n", "read line is '$pretty_readline'");
-print "not " unless
- eof $fh;
-print "ok 8\n";
+$eof = eof $fh;
+ok($eof, 'reached eof');
-print "not " unless
- close $fh;
-print "ok 9\n";
+ok(close($fh), 'closed filehandle');
# Test out binmode (should be only LF with print, no CR).
-$fh = Win32API::File->new("+> foo.txt")
- or die fileLastError();
+$fh = Win32API::File->new("+> $filename")
+ or die fileLastError();
binmode $fh;
print $fh "hello there\n";
seek $fh, 0, 0;
-print "not " unless
- <$fh> eq "hello there\n";
-print "ok 10\n";
+$readline = <$fh>;
+is($readline, "hello there\n", "binmode worked (no CR)");
close $fh;
-unlink "foo.txt";
+unlink $filename;
-BOOL T_BOOL
-LONG T_IV
-HKEY T_UV
-HANDLE T_UV
-DWORD T_UV
-oDWORD O_UV
-UINT T_UV
-REGSAM T_UV
-SECURITY_INFORMATION T_UV
-char * T_BUF
-WCHAR * T_BUF
-BYTE * T_BUF
-void * T_BUF
-ValEntA * T_BUF
-ValEntW * T_BUF
-SECURITY_DESCRIPTOR * T_BUF
-SECURITY_ATTRIBUTES * T_BUF
-LPOVERLAPPED T_BUF
-LONG * T_IVBUF
-DWORD * T_UVBUF
-LPDWORD T_UVBUF
-oDWORD * O_UVBUF
-HKEY * T_UVBUFP
-oHKEY * O_UVBUFP
-FILETIME * T_SBUF
-
-#############################################################################
-INPUT
-T_BOOL
- $var= null_arg($arg)||!SvTRUE($arg) ? ($type)0 : looks_like_number($arg) ? ($type)SvIV($arg) : ($type)1
-T_BUF
- if( null_arg($arg) )
- $var= NULL;
- else
- $var= ($type) SvPV_nolen( $arg )
-T_SBUF
- grow_buf( $var,$arg, $type )
-T_IV
- $var= null_arg($arg) ? ($type)0 : INT2PTR($type,SvIV($arg))
-T_UV
- $var= null_arg($arg) ? ($type)0 : INT2PTR($type,SvUV($arg))
-O_IV
- $var= optIV($arg)
-O_UV
- $var= optUV($arg)
-T_IVBUF
- if( null_arg($arg) )
- $var= NULL;
- else
- *( $var= ($type) TempAlloc( sizeof(*($var)) ) )= SvIV($arg)
-T_UVBUF
- if( null_arg($arg) )
- $var= NULL;
- else
- *( $var= ($type) TempAlloc( sizeof(*($var)) ) )= SvUV($arg)
-O_IVBUF
- if( null_arg($arg) )
- $var= NULL;
- else
- *( $var= ($type) TempAlloc( sizeof(*($var)) ) )=
- SvOK($arg) ? SvIV($arg) : 0;
-O_UVBUF
- if( null_arg($arg) )
- $var= NULL;
- else
- *( $var= ($type) TempAlloc( sizeof(*($var)) ) )=
- SvOK($arg) ? SvUV($arg) : 0;
-T_IVBUFP
- if( null_arg($arg) )
- $var= NULL;
- else
- *( $var= ($type) TempAlloc( sizeof(*($var)) ) )= (void *)SvIV($arg)
-T_UVBUFP
- if( null_arg($arg) )
- $var= NULL;
- else
- *( $var= ($type) TempAlloc( sizeof(*($var)) ) )= (void *)SvUV($arg)
-O_IVBUFP
- if( null_arg($arg) )
- $var= NULL;
- else
- *( $var= ($type) TempAlloc( sizeof(*($var)) ) )=
- SvOK($arg) ? (void *)SvIV($arg) : 0;
-O_UVBUFP
- if( null_arg($arg) )
- $var= NULL;
- else
- *( $var= ($type) TempAlloc( sizeof(*($var)) ) )=
- SvOK($arg) ? (void *)SvUV($arg) : 0;
-
-#############################################################################
-OUTPUT
-T_BOOL
- if( ! null_arg($arg) && ! SvREADONLY($arg) ) {
- if( $var ) {
- sv_setiv( $arg, (IV)$var );
- } else {
- sv_setsv( $arg, &PL_sv_no );
- }
- }
-T_BUF
- ;
-T_SBUF
- trunc_buf( RETVAL, $var,$arg );
-T_IV
- if( ! null_arg($arg) && ! SvREADONLY($arg) )
- sv_setiv( $arg, PTR2IV($var) );
-T_UV
- if( ! null_arg($arg) && ! SvREADONLY($arg) )
- sv_setuv( $arg, PTR2UV($var) );
-O_IV
- if( ! null_arg($arg) )
- sv_setiv( $arg, PTR2IV($var) );
-O_UV
- if( ! null_arg($arg) )
- sv_setuv( $arg, PTR2UV($var) );
-T_IVBUF
- if( ! null_arg($arg) && ! SvREADONLY($arg) )
- sv_setiv( $arg, (IV)*($var) );
-T_UVBUF
- if( ! null_arg($arg) && ! SvREADONLY($arg) )
- sv_setuv( $arg, (UV)*($var) );
-O_IVBUF
- if( ! null_arg($arg) )
- sv_setiv( $arg, (IV)*($var) );
-O_UVBUF
- if( ! null_arg($arg) )
- sv_setuv( $arg, (UV)*($var) );
-T_IVBUFP
- if( ! null_arg($arg) && ! SvREADONLY($arg) )
- sv_setiv( $arg, (IV)*($var) );
-T_UVBUFP
- if( ! null_arg($arg) && ! SvREADONLY($arg) )
- sv_setuv( $arg, (UV)*($var) );
-O_IVBUFP
- if( ! null_arg($arg) )
- sv_setiv( $arg, (IV)*($var) );
-O_UVBUFP
- if( ! null_arg($arg) )
- sv_setuv( $arg, (UV)*($var) );
+BOOL T_BOOL\r
+LONG T_IV\r
+HKEY T_UV\r
+HANDLE T_UV\r
+DWORD T_UV\r
+oDWORD O_UV\r
+UINT T_UV\r
+REGSAM T_UV\r
+SECURITY_INFORMATION T_UV\r
+char * T_BUF\r
+WCHAR * T_BUF\r
+BYTE * T_BUF\r
+void * T_BUF\r
+ValEntA * T_BUF\r
+ValEntW * T_BUF\r
+SECURITY_DESCRIPTOR * T_BUF\r
+SECURITY_ATTRIBUTES * T_BUF\r
+LPOVERLAPPED T_BUF\r
+LONG * T_IVBUF\r
+DWORD * T_UVBUF\r
+LPDWORD T_UVBUF\r
+oDWORD * O_UVBUF\r
+HKEY * T_UVBUFP\r
+oHKEY * O_UVBUFP\r
+FILETIME * T_SBUF\r
+\r
+#############################################################################\r
+INPUT\r
+T_BOOL\r
+ $var= null_arg($arg)||!SvTRUE($arg) ? ($type)0 : looks_like_number($arg) ? ($type)SvIV($arg) : ($type)1\r
+T_BUF\r
+ if( null_arg($arg) )\r
+ $var= NULL;\r
+ else\r
+ $var= ($type) SvPV_nolen( $arg )\r
+T_SBUF\r
+ grow_buf( $var,$arg, $type )\r
+T_IV\r
+ $var= null_arg($arg) ? ($type)0 : INT2PTR($type,SvIV($arg))\r
+T_UV\r
+ $var= null_arg($arg) ? ($type)0 : INT2PTR($type,SvUV($arg))\r
+O_IV\r
+ $var= optIV($arg)\r
+O_UV\r
+ $var= optUV($arg)\r
+T_IVBUF\r
+ if( null_arg($arg) )\r
+ $var= NULL;\r
+ else\r
+ *( $var= ($type) TempAlloc( sizeof(*($var)) ) )= SvIV($arg)\r
+T_UVBUF\r
+ if( null_arg($arg) )\r
+ $var= NULL;\r
+ else\r
+ *( $var= ($type) TempAlloc( sizeof(*($var)) ) )= SvUV($arg)\r
+O_IVBUF\r
+ if( null_arg($arg) )\r
+ $var= NULL;\r
+ else\r
+ *( $var= ($type) TempAlloc( sizeof(*($var)) ) )=\r
+ SvOK($arg) ? SvIV($arg) : 0;\r
+O_UVBUF\r
+ if( null_arg($arg) )\r
+ $var= NULL;\r
+ else\r
+ *( $var= ($type) TempAlloc( sizeof(*($var)) ) )=\r
+ SvOK($arg) ? SvUV($arg) : 0;\r
+T_IVBUFP\r
+ if( null_arg($arg) )\r
+ $var= NULL;\r
+ else\r
+ *( $var= ($type) TempAlloc( sizeof(*($var)) ) )= (void *)SvIV($arg)\r
+T_UVBUFP\r
+ if( null_arg($arg) )\r
+ $var= NULL;\r
+ else\r
+ *( $var= ($type) TempAlloc( sizeof(*($var)) ) )= (void *)SvUV($arg)\r
+O_IVBUFP\r
+ if( null_arg($arg) )\r
+ $var= NULL;\r
+ else\r
+ *( $var= ($type) TempAlloc( sizeof(*($var)) ) )=\r
+ SvOK($arg) ? (void *)SvIV($arg) : 0;\r
+O_UVBUFP\r
+ if( null_arg($arg) )\r
+ $var= NULL;\r
+ else\r
+ *( $var= ($type) TempAlloc( sizeof(*($var)) ) )=\r
+ SvOK($arg) ? (void *)SvUV($arg) : 0;\r
+\r
+#############################################################################\r
+OUTPUT\r
+T_BOOL\r
+ if( ! null_arg($arg) && ! SvREADONLY($arg) ) {\r
+ if( $var ) {\r
+ sv_setiv( $arg, (IV)$var );\r
+ } else {\r
+ sv_setsv( $arg, &PL_sv_no );\r
+ }\r
+ }\r
+T_BUF\r
+ ;\r
+T_SBUF\r
+ trunc_buf( RETVAL, $var,$arg );\r
+T_IV\r
+ if( ! null_arg($arg) && ! SvREADONLY($arg) )\r
+ sv_setiv( $arg, PTR2IV($var) );\r
+T_UV\r
+ if( ! null_arg($arg) && ! SvREADONLY($arg) )\r
+ sv_setuv( $arg, PTR2UV($var) );\r
+O_IV\r
+ if( ! null_arg($arg) )\r
+ sv_setiv( $arg, PTR2IV($var) );\r
+O_UV\r
+ if( ! null_arg($arg) )\r
+ sv_setuv( $arg, PTR2UV($var) );\r
+T_IVBUF\r
+ if( ! null_arg($arg) && ! SvREADONLY($arg) )\r
+ sv_setiv( $arg, (IV)*($var) );\r
+T_UVBUF\r
+ if( ! null_arg($arg) && ! SvREADONLY($arg) )\r
+ sv_setuv( $arg, (UV)*($var) );\r
+O_IVBUF\r
+ if( ! null_arg($arg) )\r
+ sv_setiv( $arg, (IV)*($var) );\r
+O_UVBUF\r
+ if( ! null_arg($arg) )\r
+ sv_setuv( $arg, (UV)*($var) );\r
+T_IVBUFP\r
+ if( ! null_arg($arg) && ! SvREADONLY($arg) )\r
+ sv_setiv( $arg, (IV)*($var) );\r
+T_UVBUFP\r
+ if( ! null_arg($arg) && ! SvREADONLY($arg) )\r
+ sv_setuv( $arg, (UV)*($var) );\r
+O_IVBUFP\r
+ if( ! null_arg($arg) )\r
+ sv_setiv( $arg, (IV)*($var) );\r
+O_UVBUFP\r
+ if( ! null_arg($arg) )\r
+ sv_setuv( $arg, (UV)*($var) );\r
use 5.006002;
use strict;
+use warnings::register;
+if ($] >= 5.015) {
+ warnings::register_categories(qw/version/);
+}
use vars qw(@ISA $VERSION $CLASS $STRICT $LAX *declare *qv);
-$VERSION = 0.9909;
+$VERSION = 0.9916;
$CLASS = 'version';
# avoid using Exporter
# Declaring a dotted-decimal $VERSION (keep on one line!)
use version; our $VERSION = version->declare("v1.2.3"); # formal
- use version; our $VERSION = qv("v1.2.3"); # shorthand
- use version; our $VERSION = qv("v1.2_3"); # alpha
+ use version; our $VERSION = qv("v1.2.3"); # deprecated
+ use version; our $VERSION = qv("v1.2_3"); # deprecated
# Declaring an old-style decimal $VERSION (use quotes!)
trailing zeroes.
version->declare('v1.2')->numify; # 1.002
- version->parse('1.2')->numify; # 1.2
+ version->parse('1.2')->numify; # 1.200
=head2 stringify()
=over 4
-=item Decimal Versions
+=item Decimal versions
Any version which "looks like a number", see L<Decimal Versions>. This
also includes versions with a single decimal point and a single embedded
underscore, see L<Alpha Versions>, even though these must be quoted
to preserve the underscore formatting.
-=item Dotted-Decimal Versions
+=item Dotted-Decimal versions
Also referred to as "Dotted-Integer", these contains more than one decimal
point and may have an optional embedded underscore, see L<Dotted-Decimal
use vars qw($VERSION $CLASS $STRICT $LAX);
-$VERSION = 0.9909;
+$VERSION = 0.9916;
#--------------------------------------------------------------------------#
# Version regexp components
#########################
use Test::More qw/no_plan/;
+use File::Spec;
BEGIN {
- (my $coretests = $0) =~ s'[^/]+\.t'coretests.pm';
+ my $coretests = File::Spec->catpath(
+ (File::Spec->splitpath($0))[0,1], 'coretests.pm'
+ );
require $coretests;
- use_ok('version', 0.9909);
+ use_ok('version', 0.9916);
}
BaseTests("version","new","qv");
#########################
use Test::More qw/no_plan/;
+use File::Spec;
use File::Temp qw/tempfile/;
BEGIN {
- (my $coretests = $0) =~ s'[^/]+\.t'coretests.pm';
+ my $coretests = File::Spec->catpath(
+ (File::Spec->splitpath($0))[0,1], 'coretests.pm'
+ );
require $coretests;
- use_ok("version", 0.9909);
+ use_ok("version", 0.9916);
# If we made it this far, we are ok.
}
#########################
use Test::More qw/no_plan/;
+use File::Spec;
BEGIN {
- (my $coretests = $0) =~ s'[^/]+\.t'coretests.pm';
+ my $coretests = File::Spec->catpath(
+ (File::Spec->splitpath($0))[0,1], 'coretests.pm'
+ );
require $coretests;
}
# Don't want to use, because we need to make sure that the import doesn't
# fire just yet (some code does this to avoid importing qv() and delare()).
require_ok("version");
-is $version::VERSION, 0.9909, "Make sure we have the correct class";
+is $version::VERSION, 0.9916, "Make sure we have the correct class";
ok(!"main"->can("qv"), "We don't have the imported qv()");
ok(!"main"->can("declare"), "We don't have the imported declare()");
}
BEGIN {
- use version 0.9909;
+ use version 0.9916;
}
pass "Didn't get caught by the wrong DIE handler, which is a good thing";
use Test::More qw/no_plan/;
BEGIN {
- use_ok('version', 0.9909);
+ use_ok('version', 0.9916);
}
my $v1 = version->new('1.2');
use File::Basename;
use File::Temp qw/tempfile/;
use POSIX qw/locale_h/;
-use Test::More tests => 7;
+use Test::More tests => 8;
use Config;
BEGIN {
- use_ok('version', 0.9909);
+ use_ok('version', 0.9916);
}
SKIP: {
if(!$Config{d_setlocale});
# test locale handling
- my $warning;
+ my $warning = '';
local $SIG{__WARN__} = sub { $warning = $_[0] };
$loc = setlocale( LC_ALL, $_);
last if $loc && localeconv()->{decimal_point} eq ',';
}
- skip 'Cannot test locale handling without a comma locale', 5
+ skip 'Cannot test locale handling without a comma locale', 6
unless $loc and localeconv()->{decimal_point} eq ',';
setlocale(LC_NUMERIC, $loc);
ok ($v eq "1.23", "Locale doesn't apply to version objects");
ok ($v == $ver, "Comparison to locale floating point");
+ TODO: { # Resolve https://rt.cpan.org/Ticket/Display.html?id=102272
+ local $TODO = 'Fails for Perl 5.x.0 < 5.19.0' if $] < 5.019000;
+ $ver = version->new($]);
+ is "$ver", "$]", 'Use PV for dualvars';
+ }
setlocale( LC_ALL, $orig_loc); # reset this before possible skip
skip 'Cannot test RT#46921 with Perl < 5.008', 1
if ($] < 5.008);
- skip 'Cannot test RT#46921 with pure Perl module', 1
- if exists $INC{'version/vpp.pm'};
my ($fh, $filename) = tempfile('tXXXXXXX', SUFFIX => '.pm', UNLINK => 1);
(my $package = basename($filename)) =~ s/\.pm$//;
print $fh <<"EOF";
__DATA__
af_ZA
af_ZA.utf8
+af_ZA.UTF-8
an_ES
an_ES.utf8
+an_ES.UTF-8
az_AZ.utf8
+az_AZ.UTF-8
be_BY
be_BY.utf8
+be_BY.UTF-8
bg_BG
bg_BG.utf8
+bg_BG.UTF-8
br_FR
br_FR@euro
br_FR.utf8
+br_FR.UTF-8
bs_BA
bs_BA.utf8
+bs_BA.UTF-8
ca_ES
ca_ES@euro
ca_ES.utf8
+ca_ES.UTF-8
cs_CZ
cs_CZ.utf8
+cs_CZ.UTF-8
da_DK
da_DK.utf8
+da_DK.UTF-8
de_AT
de_AT@euro
de_AT.utf8
+de_AT.UTF-8
de_BE
de_BE@euro
de_BE.utf8
+de_BE.UTF-8
de_DE
de_DE@euro
de_DE.utf8
+de_DE.UTF-8
+de_DE.UTF-8
de_LU
de_LU@euro
de_LU.utf8
+de_LU.UTF-8
el_GR
el_GR.utf8
+el_GR.UTF-8
en_DK
en_DK.utf8
+en_DK.UTF-8
es_AR
es_AR.utf8
+es_AR.UTF-8
es_BO
es_BO.utf8
+es_BO.UTF-8
es_CL
es_CL.utf8
+es_CL.UTF-8
es_CO
es_CO.utf8
+es_CO.UTF-8
es_EC
es_EC.utf8
+es_EC.UTF-8
es_ES
es_ES@euro
es_ES.utf8
+es_ES.UTF-8
es_PY
es_PY.utf8
+es_PY.UTF-8
es_UY
es_UY.utf8
+es_UY.UTF-8
es_VE
es_VE.utf8
+es_VE.UTF-8
et_EE
et_EE.iso885915
et_EE.utf8
+et_EE.UTF-8
eu_ES
eu_ES@euro
eu_ES.utf8
+eu_ES.UTF-8
fi_FI
fi_FI@euro
fi_FI.utf8
+fi_FI.UTF-8
fo_FO
fo_FO.utf8
+fo_FO.UTF-8
fr_BE
fr_BE@euro
fr_BE.utf8
+fr_BE.UTF-8
fr_CA
fr_CA.utf8
+fr_CA.UTF-8
fr_CH
fr_CH.utf8
+fr_CH.UTF-8
fr_FR
fr_FR@euro
fr_FR.utf8
+fr_FR.UTF-8
fr_LU
fr_LU@euro
fr_LU.utf8
+fr_LU.UTF-8
gl_ES
gl_ES@euro
gl_ES.utf8
+gl_ES.UTF-8
hr_HR
hr_HR.utf8
+hr_HR.UTF-8
hu_HU
hu_HU.utf8
+hu_HU.UTF-8
id_ID
id_ID.utf8
+id_ID.UTF-8
is_IS
is_IS.utf8
+is_IS.UTF-8
it_CH
it_CH.utf8
+it_CH.UTF-8
it_IT
it_IT@euro
it_IT.utf8
+it_IT.UTF-8
ka_GE
ka_GE.utf8
+ka_GE.UTF-8
kk_KZ
kk_KZ.utf8
+kk_KZ.UTF-8
kl_GL
kl_GL.utf8
+kl_GL.UTF-8
lt_LT
lt_LT.utf8
+lt_LT.UTF-8
lv_LV
lv_LV.utf8
+lv_LV.UTF-8
mk_MK
mk_MK.utf8
+mk_MK.UTF-8
mn_MN
mn_MN.utf8
+mn_MN.UTF-8
nb_NO
nb_NO.utf8
+nb_NO.UTF-8
nl_BE
nl_BE@euro
nl_BE.utf8
+nl_BE.UTF-8
nl_NL
nl_NL@euro
nl_NL.utf8
+nl_NL.UTF-8
nn_NO
nn_NO.utf8
+nn_NO.UTF-8
no_NO
no_NO.utf8
+no_NO.UTF-8
oc_FR
oc_FR.utf8
+oc_FR.UTF-8
pl_PL
pl_PL.utf8
+pl_PL.UTF-8
pt_BR
pt_BR.utf8
+pt_BR.UTF-8
pt_PT
pt_PT@euro
pt_PT.utf8
+pt_PT.UTF-8
ro_RO
ro_RO.utf8
+ro_RO.UTF-8
ru_RU
ru_RU.koi8r
ru_RU.utf8
+ru_RU.UTF-8
ru_UA
ru_UA.utf8
+ru_UA.UTF-8
se_NO
se_NO.utf8
+se_NO.UTF-8
sh_YU
sh_YU.utf8
+sh_YU.UTF-8
sk_SK
sk_SK.utf8
+sk_SK.UTF-8
sl_SI
sl_SI.utf8
+sl_SI.UTF-8
sq_AL
sq_AL.utf8
+sq_AL.UTF-8
sr_CS
sr_CS.utf8
+sr_CS.UTF-8
sv_FI
sv_FI@euro
sv_FI.utf8
+sv_FI.UTF-8
sv_SE
sv_SE.iso885915
sv_SE.utf8
+sv_SE.UTF-8
tg_TJ
tg_TJ.utf8
+tg_TJ.UTF-8
tr_TR
tr_TR.utf8
+tr_TR.UTF-8
tt_RU.utf8
+tt_RU.UTF-8
uk_UA
uk_UA.utf8
+uk_UA.UTF-8
vi_VN
vi_VN.tcvn
wa_BE
wa_BE@euro
wa_BE.utf8
+wa_BE.UTF-8
#########################
use Test::More tests => 3;
-use_ok("version", 0.9909);
+use_ok("version", 0.9916);
# do strict lax tests in a sub to isolate a package to test importing
SKIP: {
#########################
use strict;
-use_ok("version", 0.9909);
+use_ok("version", 0.9916);
use Test::More;
BEGIN {
--- /dev/null
+#! perl
+
+use Test::More qw/no_plan/;
+
+use version;
+
+# These values are from the Lyon consensus, as taken from
+# https://gist.github.com/dagolden/9559280
+
+ok(version->new(1.0203) == version->new('1.0203'));
+ok(version->new(1.02_03) == version->new('1.02_03'));
+ok(version->new(v1.2.3) == version->new('v1.2.3'));
+if ($] >= 5.008_001) {
+ ok(version->new(v1.2.3_0) == version->new('v1.2.3_0'));
+}
+
+cmp_ok(version->new(1.0203), '==', version->new('1.0203'));
+cmp_ok(version->new(1.02_03), '==', version->new('1.02_03'));
+cmp_ok(version->new(v1.2.3), '==', version->new('v1.2.3'));
+if ($] >= 5.008_001) {
+ cmp_ok(version->new(v1.2.3_0), '==', version->new('v1.2.3_0'));
+}
+
+cmp_ok(version->new('1.0203')->numify, '==', '1.0203');
+is(version->new('1.0203')->normal, 'v1.20.300');
+
+cmp_ok(version->new('1.02_03')->numify, '==', '1.0203');
+is(version->new('1.02_03')->normal, 'v1.20.300');
+
+cmp_ok(version->new('v1.2.30')->numify, '==', '1.002030');
+is(version->new('v1.2.30')->normal, 'v1.2.30');
+cmp_ok(version->new('v1.2.3_0')->numify, '==', '1.002030');
+is(version->new('v1.2.3_0')->normal, 'v1.2.30');
+
+is(version->new("1.0203")->stringify, "1.0203");
+is(version->new("1.02_03")->stringify, "1.02_03");
+is(version->new("v1.2.30")->stringify, "v1.2.30");
+is(version->new("v1.2.3_0")->stringify, "v1.2.3_0");
+is(version->new(1.0203)->stringify, "1.0203");
+is(version->new(1.02_03)->stringify, "1.0203");
+is(version->new(v1.2.30)->stringify, "v1.2.30");
+if ($] >= 5.008_001) {
+ is(version->new(v1.2.3_0)->stringify, "v1.2.30");
+}
*main::use_ok = sub ($;@) {
my ($pkg, $req, @args) = @_;
eval "use $pkg $req ".join(' ',@args);
- is ${"$pkg\::VERSION"}, $req, 'Had to manually use version';
+ is ${"$pkg\::VERSION"}, eval($req), 'Had to manually use version';
# If we made it this far, we are ok.
};
}
ok ( $version != $new_version, '$version != $new_version' );
$version = $CLASS->$method("1.2.4");
- ok ( $version > $new_version, '$version > $new_version' );
- ok ( $new_version < $version, '$new_version < $version' );
+ ok ( $version < $new_version, '$version < $new_version' );
+ ok ( $new_version > $version, '$new_version > $version' );
ok ( $version != $new_version, '$version != $new_version' );
# now test with alpha version form with object
ok ( $new_version->is_alpha, '$new_version->is_alpha');
$version = $CLASS->$method("1.2.4");
- ok ( $version > $new_version, '$version > $new_version' );
- ok ( $new_version < $version, '$new_version < $version' );
+ ok ( $version < $new_version, '$version < $new_version' );
+ ok ( $new_version > $version, '$new_version > $version' );
ok ( $version != $new_version, '$version != $new_version' );
- $version = $CLASS->$method("1.2.3.4");
+ $version = $CLASS->$method("1.2.34");
$new_version = $CLASS->$method("1.2.3_4");
- ok ( $version > $new_version, '$version > $new_version' );
- ok ( $new_version < $version, '$new_version < $version' );
- ok ( $version != $new_version, '$version != $new_version' );
+ ok ( $version == $new_version, '$version == $new_version' );
- $version = $CLASS->$method("v1.2.3");
- $new_version = $CLASS->$method("1.2.3.0");
+ $version = $CLASS->$method("v1.2.30");
+ $new_version = $CLASS->$method("1.2.30.0");
ok ( $version == $new_version, '$version == $new_version' );
$new_version = $CLASS->$method("1.2.3_0");
ok ( $version == $new_version, '$version == $new_version' );
- $new_version = $CLASS->$method("1.2.3.1");
+ $new_version = $CLASS->$method("1.2.30.1");
ok ( $version < $new_version, '$version < $new_version' );
- $new_version = $CLASS->$method("1.2.3_1");
+ $new_version = $CLASS->$method("1.2.30_1");
ok ( $version < $new_version, '$version < $new_version' );
$new_version = $CLASS->$method("1.1.999");
ok ( $version > $new_version, '$version > $new_version' );
skip 'Cannot test bare alpha v-strings with Perl < 5.8.1', 2
if $] lt 5.008_001;
$version = $CLASS->$method(v1.2.3_4);
- is($version, "v1.2.3_4", '"$version" eq "v1.2.3_4"');
+ $DB::single = 1;
+ is($version, "v1.2.34", '"$version" eq "v1.2.34"');
$version = $CLASS->$method(eval "v1.2.3_4");
- is($version, "v1.2.3_4", '"$version" eq "v1.2.3_4" (from eval)');
+ is($version, "v1.2.34", '"$version" eq "v1.2.34" (from eval)');
}
# trailing zero testing (reported by Andreas Koenig).
eval {my $v = $CLASS->new({1 => 2}) };
like $@, qr/Invalid version format/, 'Do not crash for garbage';
}
-
+ { # https://rt.cpan.org/Ticket/Display.html?id=93603
+ eval {my $v = $CLASS->$method('.1.')};
+ like $@, qr/trailing decimal/, 'Forbid trailing decimals';
+ eval {my $v = $CLASS->$method('.1.2.')};
+ like $@, qr/trailing decimal/, 'Forbid trailing decimals';
+ }
+ { # https://rt.cpan.org/Ticket/Display.html?id=93715
+ eval {my $v = $CLASS->new(v1.2)};
+ unlike $@, qr/non-numeric data/, 'Handle short v-strings';
+ eval {my $v = $CLASS->new(v1)};
+ unlike $@, qr/non-numeric data/, 'Handle short v-strings';
+ }
+ {
+ my $two31 = '2147483648';
+ my $v = $CLASS->new($two31);
+ is "$v", 'v.Inf', 'Element Exceeds VERSION_MAX';
+ like $warning, qr/Integer overflow in version/, 'Overflow warning';
+ $v = $CLASS->new("1.$two31.$two31");
+ is "$v", 'v.Inf', 'Element Exceeds VERSION_MAX';
+ like $warning, qr/Integer overflow in version/, 'Overflow warning';
+ }
+ {
+ # now as a number
+ $two31 = 2**31;
+ $v = $CLASS->new($two31);
+ is "$v", 'v.Inf', 'Element Exceeds VERSION_MAX';
+ like $warning, qr/Integer overflow in version/, 'Overflow warning';
+ }
+ { # https://rt.cpan.org/Ticket/Display.html?id=101628
+ undef $warning;
+ $v = $CLASS->new('1.1.00000000010');
+ is $v->normal, "v1.1.10", 'Ignore leading zeros';
+ unlike $warning, qr/Integer overflow in version/, 'No overflow warning';
+ }
+ { # https://rt.cpan.org/Ticket/Display.html?id=93340
+ $v = $CLASS->parse(q[2.6_01]);
+ is $v->normal, 'v2.601.0', 'Normal strips underscores from alphas'
+ }
+ { # https://rt.cpan.org/Ticket/Display.html?id=98744
+ $v = $CLASS->new("1.02_003");
+ is $v->numify, '1.020030', 'Ignore underscores for numify';
+ }
}
1;
+version 1.40; 2016-03-10
+ * Get arg_string.t to compile in perl v5.6
+ * Add information for how to contribute to Carp.
+
+version 1.39; 2016-03-06
+ * bugfix: longmess() should return the error in scalar context
+ (CPANRT#107225)
+
version 1.38; 2015-11-06
* stable release of changes since v1.36
}
}
-our $VERSION = '1.38';
+our $VERSION = '1.40';
$VERSION =~ tr/_//d;
our $MaxEvalLen = 0;
}
sub longmess_heavy {
- return @_ if ref( $_[0] ); # don't break references as exceptions
+ if ( ref( $_[0] ) ) { # don't break references as exceptions
+ return wantarray ? @_ : $_[0];
+ }
my $i = long_error_loc();
return ret_backtrace( $i, @_ );
}
L<Carp::Always>,
L<Carp::Clan>
+=head1 CONTRIBUTING
+
+L<Carp> is maintained by the perl 5 porters as part of the core perl 5
+version control repository. Please see the L<perlhack> perldoc for how to
+submit patches and contribute to it.
+
=head1 AUTHOR
The Carp module first appeared in Larry Wall's perl 5.000 distribution.
use Carp ();
-our $VERSION = '1.38';
+our $VERSION = '1.40';
$VERSION =~ tr/_//d;
# Carp::Heavy was merged into Carp in version 1.12. Any mismatched versions
use Config;
use IPC::Open3 1.0103 qw(open3);
-use Test::More tests => 65;
+use Test::More tests => 66;
sub runperl {
my(%args) = @_;
);
}
+package MyClass;
+
+sub new { return bless +{ field => ['value1', 'SecondVal'] }; }
+
+package main;
+
+{
+ my $err = Carp::longmess(MyClass->new);
+
+ # See:
+ # https://rt.cpan.org/Public/Bug/Display.html?id=107225
+ is_deeply(
+ $err->{field},
+ ['value1', 'SecondVal',],
+ "longmess returns sth meaningful in scalar context when passed a ref.",
+ );
+}
+
{
local $SIG{__WARN__} = sub {
like $_[0], qr/ok (\d+)\n at.+\b(?i:carp\.t) line \d+\.$/, 'ok 2\n';
: ((ord("A") == 193)
? 0x51
: 0xE9));
-my $chr_e9 = chr utf8::unicode_to_native(0xe9);
+my $chr_e9 = chr eval "0x$e9";
my $nl_as_hex = sprintf "%x", ord("\n");
like lm(3), qr/main::lm\(3\)/;
+5.20160320
+ - Updated vor v5.23.9
+
+5.20160228
+ - [perl #127624] corelist: wrong Digest::SHA version in 5.18.4
+
+5.20160220
+ - Updated for v5.23.8
+
5.20160120
- Updated for v5.23.7
%bug_tracker %deprecated %delta/;
use Module::CoreList::TieHashDelta;
use version;
-$VERSION = '5.20160121';
+$VERSION = '5.20160320';
sub _released_order { # Sort helper, to make '?' sort after everything else
(substr($released{$a}, 0, 1) eq "?")
5.023006 => '2015-12-21',
5.023007 => '2016-01-20',
5.023008 => '2016-02-20',
+ 5.023009 => '2016-03-20',
);
for my $version ( sort { $a <=> $b } keys %released ) {
5.018003 => {
delta_from => 5.018002,
changed => {
+ 'Config' => '5.018003',
+ 'Digest::SHA' => '5.84_02',
'Module::CoreList' => '3.12',
'Module::CoreList::TieHashDelta'=> '3.12',
'Module::CoreList::Utils'=> '3.12',
5.018004 => {
delta_from => 5.018003,
changed => {
+ 'Config' => '5.018004',
'Module::CoreList' => '3.13',
'Module::CoreList::TieHashDelta'=> '3.13',
'Module::CoreList::Utils'=> '3.13',
removed => {
}
},
+ 5.023009 => {
+ delta_from => 5.023008,
+ changed => {
+ 'Amiga::ARexx' => '0.04',
+ 'Amiga::Exec' => '0.02',
+ 'B::Op_private' => '5.023009',
+ 'Carp' => '1.40',
+ 'Carp::Heavy' => '1.40',
+ 'Config' => '5.023009',
+ 'Errno' => '1.25',
+ 'ExtUtils::Embed' => '1.33',
+ 'File::Find' => '1.34',
+ 'File::Glob' => '1.26',
+ 'File::Spec::AmigaOS' => ';.64',
+ 'IPC::Msg' => '2.06_01',
+ 'IPC::Semaphore' => '2.06_01',
+ 'IPC::SharedMem' => '2.06_01',
+ 'IPC::SysV' => '2.06_01',
+ 'List::Util' => '1.42_02',
+ 'List::Util::XS' => '1.42_02',
+ 'Module::CoreList' => '5.20160320',
+ 'Module::CoreList::TieHashDelta'=> '5.20160320',
+ 'Module::CoreList::Utils'=> '5.20160320',
+ 'POSIX' => '1.64',
+ 'Pod::Functions' => '1.10',
+ 'Pod::Functions::Functions'=> '1.10',
+ 'Scalar::Util' => '1.42_02',
+ 'SelfLoader' => '1.23',
+ 'Socket' => '2.020_03',
+ 'Storable' => '2.56',
+ 'Sub::Util' => '1.42_02',
+ 'Thread::Queue' => '3.08',
+ 'Tie::File' => '1.02',
+ 'Time::HiRes' => '1.9732',
+ 'Win32API::File' => '0.1203',
+ 'Win32API::File::inc::ExtUtils::Myconst2perl'=> '1',
+ 'XS::APItest' => '0.80',
+ 'autouse' => '1.11',
+ 'bytes' => '1.05',
+ 'strict' => '1.11',
+ 'threads' => '2.06',
+ 'version' => '0.9916',
+ 'version::regex' => '0.9916',
+ 'warnings' => '1.36',
+ },
+ removed => {
+ 'Win32API::File::ExtUtils::Myconst2perl'=> 1,
+ }
+ },
);
sub is_core
removed => {
}
},
+ 5.023009 => {
+ delta_from => 5.023008,
+ changed => {
+ },
+ removed => {
+ }
+ },
);
for my $version (sort { $a <=> $b } keys %deprecated) {
'Unicode::Normalize' => 'cpan',
'Win32' => 'cpan',
'Win32API::File' => 'cpan',
- 'Win32API::File::ExtUtils::Myconst2perl'=> 'cpan',
+ 'Win32API::File::inc::ExtUtils::Myconst2perl'=> 'cpan',
'autodie' => 'cpan',
'autodie::Scope::Guard' => 'cpan',
'autodie::Scope::GuardStack'=> 'cpan',
'Unicode::Normalize' => 'https://rt.cpan.org/Public/Dist/Display.html?Name=Unicode-Normalize',
'Win32' => undef,
'Win32API::File' => undef,
- 'Win32API::File::ExtUtils::Myconst2perl'=> undef,
+ 'Win32API::File::inc::ExtUtils::Myconst2perl'=> undef,
'autodie' => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=autodie',
'autodie::Scope::Guard' => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=autodie',
'autodie::Scope::GuardStack'=> 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=autodie',
print $Module::CoreList::version{5.00503}{CPAN}; # prints 1.48
- print Module::CoreList->first_release('File::Spec'); # prints 5.00405
- print Module::CoreList->first_release_by_date('File::Spec'); # prints 5.005
- print Module::CoreList->first_release('File::Spec', 0.82); # prints 5.006001
+ print Module::CoreList->first_release('File::Spec');
+ # prints 5.00405
+
+ print Module::CoreList->first_release_by_date('File::Spec');
+ # prints 5.005
+
+ print Module::CoreList->first_release('File::Spec', 0.82);
+ # prints 5.006001
if (Module::CoreList::is_core('File::Spec')) {
print "File::Spec is a core module\n";
print join ', ', Module::CoreList->find_modules(qr/Data/);
# prints 'Data::Dumper'
print join ', ',
- Module::CoreList->find_modules(qr/test::h.*::.*s/i, 5.008008);
+ Module::CoreList->find_modules(qr/test::h.*::.*s/i, 5.008008);
# prints 'Test::Harness::Assert, Test::Harness::Straps'
print join ", ", @{ $Module::CoreList::families{5.005} };
use strict;
use vars qw($VERSION);
-$VERSION = '5.20160121';
+$VERSION = '5.20160320';
sub TIEHASH {
my ($class, $changed, $removed, $parent) = @_;
use Module::CoreList;
use Module::CoreList::TieHashDelta;
-$VERSION = '5.20160121';
+$VERSION = '5.20160320';
sub utilities {
my $perl = shift;
removed => {
}
},
+ 5.023009 => {
+ delta_from => 5.023008,
+ changed => {
+ },
+ removed => {
+ }
+ },
);
for my $version (sort { $a <=> $b } keys %delta) {
print $Module::CoreList::Utils::utilities{5.009003}{ptar}; # prints 1
- print Module::CoreList::Utils->first_release('corelist'); # prints 5.008009
- print Module::CoreList::Utils->first_release_by_date('corelist'); # prints 5.009002
+ print Module::CoreList::Utils->first_release('corelist');
+ # prints 5.008009
+
+ print Module::CoreList::Utils->first_release_by_date('corelist');
+ # prints 5.009002
=head1 DESCRIPTION
--- /dev/null
+Revision history for Perl distribution PathTools.
+
+3.62 - Mon Jan 11 08:39:19 EST 2016
+- ensure File::Spec::canonpath() preserves taint (CVE-2015-8607)
+
+3.61 - Sun Dec 20 12:00:00 EST 2015 (bleadperl only release)
+- improve performance of cwd on Win32 miniperl
+
+3.60 - Wed Nov 18 21:28:01 EST 2015
+- add File::Spec::AmigaOS -- and actually ship it, this time
+
+3.59 - Fri Nov 13 18:38:01 EST 2015
+- no changes since 5.58_01
+
+3.58_01 - Mon Nov 9 17:35:28 EST 2015 - TRIAL RELEASE
+- add File::Spec::AmigaOS
+- fix INSTALLDIRS on post-5.10 perls
+
+3.56_02 - Thu Jul 16 11:28:57 EDT 2015 - TRIAL RELEASE
+- fix $VERSION in loaded modules
+
+3.56_01 - Sat Jul 11 18:07:28 EDT 2015 - TRIAL RELEASE
+- CPAN release of the PathTools included in perl v5.22.0
+- support for z/OS sysplexed systems
+- long-deprecated "fixpath" and "eliminate_macros" VMS functions removed
+- avoid turning leading // into / on cygwin
+- Force barename base to be a directory in File::Spec::VMS:abs2rel
+- Revise Unix syntax detection File::Spec::VMS::abs2rel
+- compiles on Android now
+- fewer compiler warnings
+- eliminate some runtime perl warnings, too
+
+3.47 - Fri May 23 18:52:00 2014
+- Improved Android support.
+- File::Spec::Unix->tmpdir: Always return an absolute path
+- File::Spec now has an XS version for performance.
+- QNX and VMS portability
+- tmpdir is updated when the environment changes.
+
+3.40 - Wed Jan 16 07:30:00 2013
+- Stop inadvertently skipping Spec.t on VMS. (Craig Berry)
+- Rethink EFS in File::Spec::VMS. (Craig Berry)
+- File::Spec::UNIX->abs2rel() gets it wrong with ".." components
+ [perl #111510] (Volker Schatz)
+- Add C define to remove taint support from perl (Steffen Mueller)
+- Remove "register" declarations as they are no longer
+ useful (Karl Williamson)
+- Add test for fast_abs_path in LF dir
+ [perl #115962] (Father Chrysostomos)
+- Cwd::fast_abs_path's untaint should allow for multiline
+ directories (Joel Berger)
+
+3.39_01 - Tue Dec 20 08:30:00 2011
+- [perl #51562] Problem & "solution" for building 5.10.0 with
+ win32+mingw+dmake (kmx)
+- Fix various compiler warnings from XS code (Zefram)
+- Fix typos (spelling errors) (Peter J. Acklam)
+- Remove Mac OS classic only tests from Cwd's Spec.t
+ and special case code from Cwd's cwd.t (Nicholas Clark)
+- Convert File::Spec's remaining tests to Test::More from Test
+ (Nicholas Clark)
+- dist/Cwd/lib/File/Spec/Win32.pm: Fix broken link (Karl Williamson)
+- In Cwd::_win32_cwd() avoid a string eval when checking if we're
+ miniperl (Nicholas Clark)
+- Add PERL_NO_GET_CONTEXT to Cwd (Nicholas Clark)
+- In Cwd.xs on VMS, don't compile bsd_realpath() at all (Nicholas Clark)
+- Merge the implementation of Cwd::{fastcwd,getcwd} using
+ ALIAS (Nicholas Clark)
+- In Cwd.xs, swap to defaulting to disabled prototypes (Nicholas Clark)
+- Remove duplicate $VERSION handling code, made redundant
+ in 3.28_01 (Nicholas Clark)
+- In Cwd.xs, tidy the conditional code related to symlinks
+ (Nicholas Clark)
+- Keep verbatim pod within 80 cols (Father Chrysostomos)
+- [RT #36079] Convert ` to ' in docs (Jim Keenan)
+- [rt.cpan.org #45885] File::Spec: Don’t use tainted tmpdir
+ in 5.6 (Father Chrysostomos)
+
+3.33 - Mon Sep 20 18:00:00 2010
+- No functional changes since the previous release.
+- Fixes POD links
+ (part of core change2a6dc37471bea77f0c24fd1fe90c598a270c9968,
+ Florian Ragwitz)
+
+3.32 - Sun Sep 19 18:00:00 2010
+
+- Promote to stable release.
+
+3.31_03 - Fri Sep 17 20:00:00 2010
+
+- Colon delimiter and escaped delimiters for File::Spec::VMS
+ This is core change 61196b433b2b (Craig A. Berry)
+
+3.31_02 - Fri Jul 23 20:00:00 2010
+
+- Add TODO test for File::Spec->rel2abs() when under a symlink.
+- Make catpath return an empty directory rather than the current
+ directory if the directory name is empty. This allows catpath
+ to play nice with non-rooted logical names, as in
+ catpath('sys$login:', '', 'login.com');
+ (Craig A. Berry)
+- Fix abs2rel bug in handling a Unix-style input.
+ (Craig A. Berry)
+- Assorted clarification and simplification of the documentation.
+ (Craig A. Berry)
+
+3.31 - Sun Nov 1 15:15:00 2009
+
+- Do not pack a Build.PL to avoid a circular dependency involving
+ ExtUtils::CBuilder (PathTools RT #50749)
+
+3.30_02 - Tue Sep 29 08:17:00 2009
+
+- Remove more special logic required for core perl.
+
+3.30_01 - Mon Sep 21 14:39:00 2009
+
+- Merge changes from core perl.
+ (Mostly changes regarding the lib->ext migration)
+
+3.30 - Sun May 10 10:55:00 2009
+
+- Promote to stable release.
+
+3.29_01 - Thu May 7 20:22:00 2009
+
+- Minor fixes for QNX6. [Sean Boudreau]
+
+- Update to support VMS in Unix compatible mode and/or file names using
+ extended character sets. (RT #42154) [John Malmberg]
+
+- VMS support for Unix and extended file specifications in File::Spec
+ (RT #42153) [John Malmberg]
+
+3.29 - Wed Oct 29 20:48:11 2008
+
+- Promote to stable release.
+
+3.28_03 - Mon Oct 27 22:12:11 2008
+
+- In Cwd.pm, pass the un-munged $VERSION to XSLoader/DynaLoader,
+ otherwise development releases fail tests on Win32.
+
+3.28_02 - Mon Oct 27 20:13:11 2008
+
+ - Fixed some issues on QNX/NTO related to paths with double
+ slashes. [Matt Kraai & Nicholas Clark]
+
+3.28_01 - Fri Jul 25 21:18:11 2008
+
+ - Fixed and clarified the behavior of splitpath() with a $no_file
+ argument on VMS. [Craig A. Berry, Peter Edwards]
+
+ - Removed some function prototypes and other Perl::Critic violations.
+
+ - canonpath() and catdir() and catfile() on Win32 now make an
+ explicit (and unnecessary) copy of their arguments right away,
+ because apparently if we don't, we sabotage all of Win32dom. [RT
+ #33675]
+
+ - The Makefile.PL now has 'use 5.005;' to explicitly show what
+ minimum version of perl we support. [Spotted by Alexandr Ciornii]
+
+3.2701 - Mon Feb 11 21:43:51 2008
+
+ - Fixed an edge case for Win32 catdir('C:', 'foo') and catfile('C:',
+ 'foo.txt') (which the caller's not really supposed to do, that's
+ what catpath() is for) that changed between versions. Now we're
+ back to the old behavior, which was to return C:\foo and C:\foo.txt .
+ [Audrey Tang]
+
+3.27 - Wed Jan 16 20:20:49 2008
+
+ - If strlcpy() and strlcat() aren't available on the user's system,
+ we now use ppport.h to provide them, so our C code works. [Steve
+ Peters]
+
+ - Upgraded to a newer version of ppport.h [Steve Peters]
+
+3.26 - Sun Jan 13 21:59:20 2008
+
+ - case_tolerant() on Cygwin will now avoid a painful death when
+ Cygwin::mount_flags() isn't defined, as is the case for perl <
+ 5.10. It will now just return 1, which is what it always did
+ before it got so smart. [Spotted by Emanuele Zeppieri]
+
+ - abs_path() on Unix(ish) platforms has been upgraded to a much later
+ version of the underlying C code from BSD. [Michael Schwern]
+
+3.2501 - Mon Dec 24 20:33:02 2007
+
+ - Reimplemented abs_path() on VMS to use
+ VMS::Filespec::vms_realpath() when it's available. [John E. Malmberg]
+
+ - tmpdir() on Cygwin now also looks in $ENV{TMP} and $ENV{TEMP}.
+
+ - case_tolerant() on Cygwin and Win32 now take an optional path
+ argument, defaulting to the C drive, to check for case tolerance,
+ because this fact can vary on different volumes.
+
+ - File::Spec on Unix now uses Cwd::getcwd() rather than Cwd::cwd() to
+ get the current directory because I guess someone on p5p thought it
+ was more appropriate.
+
+ - Added a large set of File::Spec tests for the Cygwin platform.
+
+ - abs_path() now behaves correctly with symbolic links on VMS.
+
+ - Someone fixed a couple of mysterious edge cases in VMS' canonpath()
+ and splitdir().
+
+3.25_01 - Sat Oct 13 21:13:57 2007
+
+ - Major fixes on Win32, including a rewrite of catdir(), catfile(),
+ and canonpath() in terms of a single body of code. [Heinrich Tegethoff]
+
+ - For Win32 and Cygwin, case-tolerance can vary depending on the
+ volume under scrutiny. When Win32API::File is available, it will
+ be employed to determine case-sensitivity of the given filesystem
+ (C: by default), otherwise we still return the default of 1. [Reini
+ Urban]
+
+ - On Cygwin, we added $ENV{'TMP'} and $ENV{'TEMP'} to the list of
+ possible places to look for tmpdir() return values. [Reini Urban]
+
+ - Added lots more tests for Cygwin. [Reini Urban]
+
+ - canonpath() with no arguments and canonpath(undef) now consistently
+ return undef on all platforms. [Spotted by Peter John Edwards]
+
+ - Fixed splitdir('') and splitdir(undef) and splitdir() to return an
+ empty list on VMS and MacOS, like it does on other platforms.
+ [Craig A. Berry]
+
+ - All .pm files now have the same $VERSION number, rather than a
+ hodgepodge of various numbers.
+
+3.25 - Mon May 21 21:07:26 2007
+
+ - Added a workaround for auto-vivication-of-function-args Perl bug
+ (triggered by OS/2-specific code). [Ilya Zakharevich]
+
+ - Sync with a bleadperl change: miniperl can no longer use Win32::*
+ functions because it cannot load Win32.dll. [Jan Dubois]
+
+ - We only need to load ppport.h when building outside the core, so we
+ avoid using it when in the core.
+
+3.24 - Sun Nov 19 22:52:49 2006
+
+ - Fixed a bug in the $ENV{PWD}-updating of Cwd::chdir() when a
+ dirhandle is passed in. [Steve Peters]
+
+ - Add perl 5.005 to the list of requirements in the
+ Build.PL/Makefile.PL/META.yml.
+
+ - Add ExtUtils::CBuilder to the list of build_requires in Build.PL.
+
+ - Improved performance of canonpath() on Unix-ish platforms - on my
+ OS X laptop it looks like it's about twice as fast. [Ruslan Zakirov]
+
+3.23 - Wed Oct 11 12:11:25 2006
+
+ - Yet more Win32 fixes (sigh... seems like I'm fighting a neverending
+ waterbed...). This time, fixed file_name_is_absolute() to know
+ what it's doing when the path includes a volume but a relative
+ path, like C:foo.txt . This bug had impact in rel2abs() on Win32
+ too.
+
+3.22 - Mon Oct 9 21:50:52 2006
+
+ - Fixed the t/crossplatform.t test on Win32 (and possibly other
+ volume-aware platforms) now that rel2abs() always adds a drive
+ letter. [Reported by several parties]
+
+3.21 - Wed Oct 4 21:16:43 2006
+
+ - Added a bunch of X<> tags to the File::Spec docs to help
+ podindex. [Gabor Szabo]
+
+ - On Win32, abs2rel('C:\one\two\t\foo', 't\bar') should return
+ '..\foo' when the cwd is 'C:\one\two', but it wasn't noticing that
+ the two relevant volumes were the same so it would return the full
+ path 'C:\one\two\t\foo'. This is fixed. [Spotted by Alexandr
+ Ciornii]
+
+ - On Win32, rel2abs() now always adds a volume (drive letter) if the
+ given path doesn't have a volume (drive letter or UNC volume).
+ Previously it could return a value that didn't have a volume if the
+ input was a semi-absolute path like /foo/bar instead of a
+ fully-absolute path like C:/foo/bar .
+
+3.19 Tue Jul 11 22:40:26 CDT 2006
+
+ - When abs2rel() is called with two relative paths
+ (e.g. abs2rel('foo/bar/baz', 'foo/bar')) the resolution algorithm
+ needlessly called cwd() (twice!) to turn both arguments into
+ absolute paths. Now it avoids the cwd() calls with a workaround,
+ making a big efficiency win when abs2rel() is called
+ repeatedly. [Brendan O'Dea]
+
+ - Added a build-time dependency on ExtUtils::Install version 1.39
+ when on Windows. This is necessary because version 1.39 knows how
+ to replace an in-use Cwd shared library, but previous versions
+ don't. [Suggested by Adam Kennedy]
+
+ - Fixed File::Spec::Win32->canonpath('foo/../bar'), which was
+ returning \bar, and now properly returns just bar. [Spotted by
+ Heinrich Tegethoff]
+
+3.18 Thu Apr 27 22:01:38 CDT 2006
+
+ - Fixed some problems on VMS in which a directory called "0" would be
+ treated as a second-class citizen. [Peter (Stig) Edwards]
+
+ - Added a couple of regression tests to make sure abs2rel('/foo/bar',
+ '/') works as expected. [Chia-liang Kao]
+
+ - Added a couple of regression tests to make sure catdir('/',
+ 'foo/bar') works as expected. [Mark Grimes]
+
+3.17 Fri Mar 3 16:52:30 CST 2006
+
+ - The Cygwin version of Cwd::cwd() will croak if given any arguments
+ (which can happen if, for example, it's called as Cwd->cwd). Since
+ that croaking is bad, we now wrap the original cwd() in a
+ subroutine that ignores its arguments. We could skip this wrapping
+ if a future version of perl changes cygwin.c's cwd() to not barf
+ when fed an argument. [Jerry D. Hedden]
+
+3.16 Mon Jan 30 20:48:41 CST 2006
+
+ - Updated to version 3.06 of ppport.h, which provides backward
+ compatibility XS layers for older perl versions.
+
+ - Clarify in the docs for File::Spec's abs2rel() and rel2abs()
+ methods that the cwd() function it discusses is
+ Cwd::cwd(). [Spotted by Steven Lembark]
+
+ - Apparently the version of File::Path that ships with perl 5.8.5
+ (and perhaps others) calls Cwd::getcwd() with an argument (perhaps
+ as a method?), which causes it to die with a prototyping error.
+ We've eliminated the prototype by using the "(...)" arglist, since
+ "PROTOTYPE: DISABLE" for the function didn't seem to work. [Spotted
+ by Eamon Daly and others]
+
+3.15 Tue Dec 27 14:17:39 CST 2005
+
+ - The Cwd::getcwd() function on *nix is now a direct pass-through to
+ the underlying getcwd() C library function when possible. This is
+ safer and faster than the previous implementation, which just did
+ abs_path('.'). The pure-perl version has been kept for cases in
+ which the XS version can't load, such as when running under
+ miniperl. [Suggested by Nick Ing-Simmons]
+
+ - When Cwd searches for a 'pwd' executable in the $PATH, we now stop
+ after we find the first one rather than continuing the search. We
+ also avoid the $PATH search altogether when a 'pwd' was already
+ found in a well-known and well-trusted location like /bin or
+ /usr/bin. [Suggested by Nick Ing-Simmons]
+
+ - On Win32 abs2rel($path, $base) was failing whenever $base is the
+ root of a volume (such as C:\ or \\share\dir). This has been
+ fixed. [Reported by Bryan Daimler]
+
+ - In abs2rel() on VMS, we've fixed handling of directory trees so
+ that the test $file = File::Spec::VMS->abs2rel('[t1.t2.t3]file',
+ '[t1.t2.t3]') returns 'file' instead of an empty string. [John
+ E. Malmberg]
+
+ - In canonpath() on VMS, '[]' was totally optimized away instead of
+ just returning '[]'. Now it's fixed. [John E. Malmberg]
+
+3.14 Thu Nov 17 18:08:44 CST 2005
+
+ - canonpath() has some logic in it that avoids collapsing a
+ //double/slash at the beginning of a pathname on platforms where
+ that means something special. It used to check the value of $^O
+ rather than the classname it was called as, which meant that
+ calling File::Spec::Cygwin->canonpath() didn't act like cygwin
+ unless you were actually *on* cygwin. Now it does.
+
+ - Fixed a major bug on Cygwin in which catdir() could sometimes
+ create things that look like //network/paths in cases when it
+ shouldn't (e.g. catdir("/", "foo", "bar")).
+
+3.13 Tue Nov 15 23:50:37 CST 2005
+
+ - Calling tmpdir() on Win32 had the unintended side-effect of storing
+ some undef values in %INC for the TMPDIR, TEMP, and TMP entries if
+ they didn't exist already. This is probably a bug in perl itself
+ (submitted as #37441 on rt.perl.org), which we're now working
+ around. [Thomas L. Shinnick]
+
+ - Integrated a change from bleadperl - a certain #ifdef in Cwd.xs
+ needs to apply to WIN32 but not WinCE. [Vadim Konovalov]
+
+ - abs2rel() used to return the empty string when its two arguments
+ were identical, which made no sense. Now it returns
+ curdir(). [Spotted by David Golden]
+
+ - The Unix and Win32 implementations of abs2rel() have been unified.
+
+3.12 Mon Oct 3 22:09:12 CDT 2005
+
+ - Fixed a testing error on OS/2 in which a drive letter for the root
+ directory was confusing things. [Ilya Zakharevich]
+
+ - Integrated a patch from bleadperl for fixing path() on
+ Win32. [Gisle Aas]
+
+3.11 Sat Aug 27 20:12:55 CDT 2005
+
+ - Fixed a couple of typos in the documentation for
+ File::Spec::Mac. [Piotr Fusik]
+
+3.10 Thu Aug 25 22:24:57 CDT 2005
+
+ - eliminate_macros() and fixpath() in File::Spec::VMS are now
+ deprecated, since they are MakeMaker-specific and now live inside
+ MakeMaker. [Michael Schwern]
+
+ - canonpath() on Win32 now collapses foo/.. (or foo\..) sections
+ correctly, rather than doing the "misguided" work it was previously
+ doing. Note that canonpath() on Unix still does NOT collapse these
+ sections, as doing so would be incorrect. [Michael Schwern]
+
+3.09 Tue Jun 14 20:36:50 CDT 2005
+
+ - Added some block delimiters (brackets) in the Perl_getcwd_sv() XS
+ function, which were necessary to separate the variable
+ declarations from the statements when HAS_GETCWD is not
+ defined. [Yves]
+
+ - Apparently the _NT_cwd() routine is never defined externally like I
+ thought it was, so I simplified the code around it.
+
+ - When cwd() is implemented using the _backtick_pwd() function, it
+ sometimes could create accidental undef entries in %ENV under perl
+ 5.6, because local($hash{key}) is somewhat broken. This is now
+ fixed with an appropriate workaround. [Neil Watkiss]
+
+3.08 Sat May 28 10:10:29 CDT 2005
+
+ - Fixed a test failure with fast_abs_path() on Windows - it was
+ sensitive to the rootdir() change from version 3.07. [Steve Hay]
+
+3.07 Fri May 6 07:46:45 CDT 2005
+
+ - Fixed a bug in which the special perl variable $^O would become
+ tainted under certain versions of perl. [Michael Schwern]
+
+ - File::Spec->rootdir() was returning / on Win32. Now it returns \ .
+ [Michael Schwern]
+
+ - We now avoid modifying @_ in tmpdir() when it's not strictly
+ necessary, which reportedly provides a modest performance
+ boost. [Richard Soderberg]
+
+ - Made a couple of slight changes to the Win32 code so that it works
+ (or works better) on Symbian OS phones. [Jarkko Hietaniemi]
+
+3.06 Wed Apr 13 20:47:26 CDT 2005
+
+ (No changes in functionality)
+
+ - Added a note to the canonpath() docs about why it doesn't collapse
+ foo/../bar sections.
+
+ - The internal-only function bsd_realpath() in the XS file now uses
+ normal arg syntax instead of K&R syntax. [Nicholas Clark]
+
+3.05 Mon Feb 28 07:22:58 CST 2005
+
+ - Fixed a bug in fast_abs_path() on Win32 in which forward- and
+ backward-slashes were confusing things. [demerphq]
+
+ - Failure to load the XS code in Cwd is no longer a fatal error
+ (though failure to compile it is still a fatal error in the build
+ process). This lets Cwd work under miniperl in the core. [Rafael
+ Garcia-Suarez]
+
+ - In the t/cwd.t test, don't enforce loading from blib/ if we're
+ testing in the perl core. [Rafael Garcia-Suarez]
+
+3.04 Sun Feb 6 17:27:38 CST 2005
+
+ - For perls older than 5.006, the HAS_GETCWD symbol is not available,
+ because it wasn't checked for in older Configure scripts when perl
+ was built. We therefore just ask the user whether the getcwd() C
+ function is defined on their platform when their perl is old.
+ Maybe in the future we'll try to automate this. [Reported by
+ several parties]
+
+ - Remove lib/ppport.h from the distribution, so that MakeMaker
+ doesn't accidentally pick it up and install it as a lib
+ file. [Jerry Hedden]
+
+ - Fixed a testing error on VMS that occurred when a user had
+ read-access to the root of the current volume. [Craig A. Berry]
+
+3.03 Fri Jan 21 21:44:05 CST 2005
+
+ - Fixed a testing error if the first file we find in the root
+ directory is a symlink. [Blair Zajac]
+
+ - Added a test to make sure Cwd.pm is loaded from blib/ during
+ testing, which seems to be an issue in some people's environments
+ and makes it awfully hard to debug things on my end.
+
+ - Skip the _perl_abs_path() tests on Cygwin - they don't usually
+ pass, and this function isn't used there anyway, so I decided not
+ to push it. Let 'em use `cwd`.
+
+3.02 Sun Jan 9 19:29:52 CST 2005
+
+ - Fixed a bug in which Cwd::abs_path() called on a file in the root
+ directory returned strange results. [Bob Luckin]
+
+ - Straightened out the licensing details for the portion of the Cwd
+ module that comes from BSD sources. [Hugo van der Sanden]
+
+ - Removed the prototype from _perl_abs_path() and the XS version of
+ abs_path(), since all they seemed to be doing was causing people
+ grief, and since some platforms didn't have them anyway.
+
+ - Fixed a testing bug in which sometimes the wrong version of Cwd
+ (the version already installed on the user's machine) would get
+ loaded instead of the one we're building & installing.
+
+ - Sometimes getdcwd() returns a lower-case drive letter, so don't
+ require an upper-case letter in t/win32.t. [Jan Dubois]
+
+ - Fixed a memory leak in getdcwd() on win32. [Steve Hay]
+
+ - Added a copy of ppport.h to the distribution to aid compilation on
+ older versions of perl. [Suggested by Charlie Root]
+
+ - Don't bother looking for a 'pwd' executable on MSWin32 - there
+ won't be one, and looking for it can be extremely slow when lots of
+ disks are mounted. [Several people, including Andrew Burke]
+
+ - Eliminated a multi-argument form of open() that was causing a
+ syntax error on older versions of perl. [Fixed by Michael Schwern]
+
+ - The bug-fix changes for revision 0.90 of File::Spec somehow were
+ lost when I merged it into the PathTools distribution. They're
+ restored now. [Craig A. Berry]
+
+ - File::Spec->canonpath() will now reduce paths like '[d1.-]foo.dat'
+ down to '[000000]foo.dat' instead of '[]foo.dat' or 'foo.dat'.
+ This is in better accordance with the native filename syntax
+ parser. [Craig A. Berry]
+
+ - In order to remove a recursive dependency (PathTools -> Test-Simple
+ -> Test-Harness -> PathTools), we now include a copy of Test::More in
+ the distribution. It is only used for testing, it won't be installed
+ with the rest of the stuff.
+
+ - Removed some 5.6-isms from Cwd in order to get it to build with
+ older perls like 5.005.
+
+ - abs_path() on Windows was trampling on $ENV{PWD} - fixed. [Spotted
+ by Neil MacMullen]
+
+ - Added licensing/copyright statements to the POD in each .pm
+ file. [Spotted by Radoslaw Zielinski]
+
+3.01 Mon Sep 6 22:28:06 CDT 2004
+
+ - Removed an unnecessary and confusing dependency on File::Spec from
+ the Makefile.PL and the Build.PL.
+
+ - Added a 'NAME' entry to the Makefile.PL, because otherwise it won't
+ even begin to work. [Reported by many]
+
+3.00 Thu Sep 2 22:15:07 CDT 2004
+
+ - Merged Cwd and File::Spec into a single PathTools distribution.
+ This was done because the two modules use each other fairly
+ extensively, and extracting the common stuff into another
+ distribution was deemed nigh-impossible. The code in revision 3.00
+ of PathTools should be equivalent to the code in Cwd 2.21 and
+ File::Spec 0.90.
+
+==================================================================
+Prior to revision 3.00, Cwd and File::Spec were maintained as two
+separate distributions. The revision history for Cwd is shown here.
+The revision history for File::Spec is further below.
+==================================================================
+
+Cwd 2.21 Tue Aug 31 22:50:14 CDT 2004
+
+ - Removed "NO_META" from the Makefile.PL, since I'm not building the
+ distribution with MakeMaker anyway. [Rohan Carly]
+
+ - Only test _perl_abs_path() on platforms where it's expected to work
+ (platforms with '/' as the directory separator). [Craig A. Berry]
+
+Cwd 2.20 Thu Jul 22 08:23:53 CDT 2004
+
+ - On some implementations of perl on Win32, a memory leak (or worse?)
+ occurred when calling getdcwd(). This has been fixed. [PodMaster]
+
+ - Added tests for getdcwd() on Win32.
+
+ - Fixed a problem in the pure-perl implementation _perl_abs_path()
+ that caused a fatal error when run on plain files. [Nicholas Clark]
+ To exercise the appropriate test code on platforms that wouldn't
+ otherwise use _perl_abs_path(), run the tests with $ENV{PERL_CORE}
+ or $ENV{TEST_PERL_CWD_CODE} set.
+
+Cwd 2.19 Thu Jul 15 08:32:18 CDT 2004
+
+ - The abs_path($arg) fix from 2.18 didn't work for VMS, now it's
+ fixed there. [Craig Berry]
+
+Cwd 2.18 Thu Jun 24 08:22:57 CDT 2004
+
+ - Fixed a problem in which abs_path($arg) on some platforms could
+ only be called on directories, and died when called on files. This
+ was a problem in the pure-perl implementation _perl_abs_path().
+
+ - Fixed fast_abs_path($arg) in the same way as abs_path($arg) above.
+
+ - On Win32, a function getdcwd($vol) has been added, which gets the
+ current working directory of the specified drive/volume.
+ [Steve Hay]
+
+ - Fixed a problem on perl 5.6.2 when built with the MULTIPLICITY
+ compile-time flags. [Yitzchak Scott-Thoennes]
+
+ - When looking for a `pwd` system command, we no longer assume the
+ path separator is ':'.
+
+ - On platforms where cwd() is implemented internally (like Win32),
+ don't look for a `pwd` command externally. This can greatly speed
+ up load time. [Stefan Scherer]
+
+ - The pure-perl version of abs_path() now has the same prototype as
+ the XS version (;$).
+
+Cwd 2.17 Wed Mar 10 07:55:36 CST 2004
+
+ - The change in 2.16 created a testing failure when tested from
+ within a path that contains symlinks (for instance, /tmp ->
+ /private/tmp).
+
+Cwd 2.16 Sat Mar 6 17:56:31 CST 2004
+
+ - For VMS compatibility (and to conform to Cwd's documented
+ interface), in the regression tests we now compare output results
+ to an absolute path. [Craig A. Berry]
+
+Cwd 2.15 Fri Jan 16 08:09:44 CST 2004
+
+ - Fixed a problem on static perl builds - while creating
+ Makefile.aperl, it was loading a mismatched version of Cwd from
+ blib/ . [Reported by Blair Zajac]
+
+Cwd 2.14 Thu Jan 8 18:51:08 CST 2004
+
+ - We now use File::Spec->canonpath() and properly-escaped regular
+ expressions when comparing paths in the regression tests. This
+ fixes some testing failures in 2.13 on non-Unix platforms. No
+ changes were made in the actual Cwd module code. [Steve Hay]
+
+Cwd 2.13 Fri Jan 2 22:29:42 CST 2004
+
+ - Changed a '//' comment to a '/* */' comment in the XS code, so that
+ it'll compile properly under ANSI C rules. [Jarkko Hietaniemi]
+
+ - Fixed a 1-character buffer overrun problem in the C code. [The BSD
+ people]
+
+Cwd 2.12 Fri Dec 19 17:04:52 CST 2003
+
+ - Fixed a bug on Cygwin - the output of realpath() should have been
+ tainted, but wasn't. [Reported by Tom Wyant]
+
+Cwd 2.10 Mon Dec 15 07:50:12 CST 2003
+
+ (Note that this release was mistakenly packaged as version 2.11, even
+ though it had an internal $VERSION variable of 2.10. Not sure how
+ THAT happened...)
+
+ - There was a dependency in the Makefile.PL on Module::Build, which
+ isn't necessary. I've removed it.
+
+Cwd 2.09 Thu Dec 11 20:30:58 CST 2003
+
+ - The module should now build & install using version 5.6 of perl.
+
+ - We now note a build-time dependency on version 0.19 of
+ Module::Build, which is necessary because we don't use the standard
+ lib/-based file layout. No version of Module::Build is required if
+ you use the Makefile.PL, just if you use the Build.PL .
+
+ - Removed some gratuitous uses of 5.6-isms like our(), with the aim
+ of backporting this module to perl 5.005.
+
+ - Simplified all code that autoloads Carp.pm and calls
+ carp()/croak().
+
+ - Removed some redundant OS/2 code at the suggestion of Michael
+ Schwern and Ilya Zakharevich.
+
+ - Make sure the correct version of Cwd.pm is loaded in the regression
+ tests. [Sam Vilain]
+
+Cwd 2.08 Wed Oct 15 20:56 CDT 2003
+
+ - Code extracted from perl 5.8.1 and packaged as a separate CPAN
+ release by Ken Williams.
+
+==================================================================
+Prior to revision 3.00, Cwd and File::Spec were maintained as two
+separate distributions. The revision history for File::Spec is shown
+here. The revision history for Cwd is above.
+==================================================================
+
+File::Spec 0.90 Tue Aug 31 22:34:50 CDT 2004
+
+ - On VMS, directories use vmspath() and files use vmsify(), so
+ rel2abs() has to use some 'educated guessing' when dealing with
+ paths containing slashes. [Craig A. Berry]
+
+File::Spec 0.89 Sun Aug 29 19:02:32 CDT 2004
+
+ - Fixed some pathological cases on VMS which broke canonpath() and
+ splitdir(). [Richard Levitte and Craig A. Berry]
+
+ - Fixed rel2abs() on VMS when passed a unix-style relative
+ path. [Craig A. Berry]
+
+File::Spec 0.88 Thu Jul 22 23:14:32 CDT 2004
+
+ - rel2abs() on Win32 will now use the new Cwd::getdcwd() function, so
+ that things like rel2abs('D:foo.txt') work properly when the
+ current drive isn't 'D'. This requires Cwd version 2.18.
+ [Steve Hay]
+
+ - Got rid of a redundant double-backslash in a character
+ class. [Alexander Farber]
+
+ - Added much markup to pod for enhanced readability. [Andy Lester]
+
+File::Spec 0.87 Fri Dec 19 08:03:28 CST 2003
+
+ - With a one-line change in the tests, backported to perl 5.004.
+ [Issue reported by Barry Kemble]
+
+File::Spec 0.86 Fri Sep 26 10:07:39 CDT 2003
+
+ - This is the version released with perl 5.8.1. It is identical to
+ the code in the File::Spec beta 0.85_03.
+
+File::Spec 0.85_03 Mon Sep 15 09:35:53 CDT 2003
+
+ - On VMS, if catpath() receives volume specifiers in both its first
+ two arguments, it will now use the volume in the first argument
+ only. Previously it returned a non-syntactical result which
+ included both volumes. This change is the same in spirit to the
+ catpath() MacOS change from version 0.85_02.
+
+ - Fixed an abs2rel() bug on VMS - previously
+ abs2rel('[t1.t2.t3]file','[t1.t2]') returned '[t3]file', now it
+ properly returns '[.t3]file'.
+
+File::Spec 0.85_02 Fri Sep 12 17:11:13 CDT 2003
+
+ - abs2rel() now behaves more consistently across platforms with the
+ notion of a volume. If the volumes of the first and second
+ argument (the second argument may be implicit) do not agree, we do
+ not attempt to reconcile the paths, and simply return the first
+ argument. Previously the volume of the second argument was
+ (usually) ignored, resulting in sometimes-garbage output.
+
+ - catpath() on MacOS now looks for a volume element (i.e. "Macintosh HD:")
+ in its first argument, and then its second argument. The first
+ volume found will be used, and if none is found, none will be used.
+
+ - Fixed a problem in abs2rel() on Win32 in which the volume of the
+ current working directory would get added to the second argument if
+ none was specified. This might have been somewhat helpful, but it
+ was contrary to the documented behavior. For example,
+ abs2rel('C:/foo/bar', '/foo') used to return 'bar', now it returns
+ 'C:/foo/bar' because there's no guarantee /foo is actually C:/foo .
+
+ - catdir('/', '../') on OS2 previously erroneously returned '//..',
+ and now it returns '/'.
+
+File::Spec 0.85_01 Thu Sep 11 16:18:54 CDT 2003
+
+ Working toward 0.86, the version that will be released with perl 5.8.1.
+
+ - The t/rel2abs2rel.t test now is a little friendlier about emitting
+ its diagnostic debugging output. [Jarkko Hietaniemi]
+
+ - We now only require() Cwd when it's needed, on demand. [Michael
+ Schwern, Tels]
+
+ - Fixed some POD errors and redundancies in OS2.pm and Cygwin.pm.
+ [Michael Schwern]
+
+ - The internal method cwd() has been renamed to _cwd(), since it was
+ never meant for public use. [Michael Schwern]
+
+ - Several methods in File::Spec::Unix that just return constant
+ strings have been sped up. catdir() has also been sped up there.
+ [Tels]
+
+ - Several canonpath() and catdir() bugs on Win32 have been fixed, and
+ tests added for them:
+ catdir('/', '../') -> '\\' (was '\..')
+ catdir('/', '..\\') -> '\\ (was '')
+ canonpath('\\../') -> '\\' (was '')
+ canonpath('\\..\\') -> '\\' (was '')
+ canonpath('/../') -> '\\' (was '\..')
+ canonpath('/..\\') -> '\\' (was '')
+ catdir('\\', 'foo') -> '\foo' (was '\\foo')
+
+ - catpath($volume, $dirs, $file) on Mac OS now ignores any volume
+ that might be part of $dirs, enabling catpath($volume,
+ catdir(rootdir(), 'foo'), '') to work portably across platforms.
+
+File::Spec 0.85 Tue Jul 22 11:31 CDT 2003
+
+ A bug-fix release relative to 0.84. I've forked development into a
+ "stable" branch (this one) and a more aggressive branch (as yet
+ unreleased), with an eye toward getting the stable features in perl
+ 5.8.1.
+
+ - File::Spec::Mac->case_tolerant() returned 0 when it should have
+ returned 1.
+
+ - Many cases in File::Spec::Win32->abs2rel() were broken, because of
+ the way in which volumes were/weren't ignored. Unfortunately, part
+ of the regression tests were broken too. Now, if the $path
+ argument to abs2rel() is on a different volume than the $base
+ argument, the result will be an absolute path rather than the
+ broken relative path previous versions returned.
+
+ - Fixed a problem in File::Spec::Win32->canonpath, which was turning
+ \../foo into "foo" rather than \foo
+
+ - Greatly simplified the code in File::Spec::Unix->splitdir().
+
+File::Spec 0.84_01 Fri Jul 11 16:14:29 CDT 2003
+
+ No actual code changes, just changes in other distribution files
+
+ - Dependencies are now listed explicitly in the Makefile.PL and
+ Build.PL scripts, as well as in the META.yml file.
+
+ - The t/abs2rel2abs.t test should now be more friendly about skipping
+ on platforms where it can't run properly.
+
+File::Spec 0.84 Wed Jul 9 22:21:23 CDT 2003
+
+ I (Ken)'ve taken the changes from bleadperl and created a new CPAN release
+ from them, since they're pretty important changes. The highlights,
+ from what I can tell, are listed here.
+
+ - A huge number of changes to File::Spec::Mac in order to bring it in
+ line with the other platforms. This work was mostly/completely
+ done by Thomas Wegner.
+
+ - The Epoc and Cygwin platforms are now supported.
+
+ - Lots of generically-applicable documentation has been taken from
+ File::Spec::Unix and put in File::Spec.
+
+ - A Build.PL has been provided for people who wish to install via
+ Module::Build.
+
+ - Some spurious warnings and errors in the tests have been
+ eliminated. [Michael Schwern]
+
+ - canonpath() on File::Spec::Unix now honors a //node-name at the
+ beginning of a path.
+
+ - Cwd.pm wasn't being loaded properly on MacOS. [Chris Nandor]
+
+ - Various POD fixups
+
+ - Several testing patches for the Epoc and Cygwin platforms [Tels]
+
+ - When running under taint mode and perl >= 5.8, all the tmpdir()
+ implementations now avoid returning a tainted path.
+
+ - File::Spec::OS2 now implements canonpath(), splitpath(),
+ splitdir(), catpath(), abs2rel(), and rel2abs() directly rather
+ than inheriting them from File::Spec::Unix.
+
+ - Added 'SYS:/temp' and 'C:/temp' to the list of possible tmpdir()s
+ on Win32.
+
+ - catfile() on Win32 and VMS will now automatically call canonpath()
+ on its final argument.
+
+ - canonpath() on Win32 now does a much more extensive cleanup of the
+ path.
+
+ - abs2rel() on Win32 now defaults to using cwd() as the base of
+ relativity when no base is given.
+
+ - abs2rel() on Win32 now explicitly ignores any volume component in
+ the $path argument.
+
+ - canonpath() on VMS now does []foo ==> foo, and foo.000000] ==> foo].
+ It also fixes a bug in multiple [000000.foo ==> [foo translations.
+
+ - tmpdir() on VMS now uses 'sys$scratch:' instead of 'sys$scratch'.
+
+ - abs2rel() on VMS now uses '000000' in both the path and the base.
+
+File::Spec 0.82 Wed Jun 28 11:24:05 EDT 2000
+ - Mac.pm: file_name_is_absolute( '' ) now returns TRUE on all platforms
+ - Spec.pm: unbreak C<$VERSION = '0.xx'> to be C<$VERSION = 0.xx>, so
+ underscores can be used when I want to update CPAN without anyone
+ needing to update the perl repository.
+ - abs2rel, rel2abs doc tweaks
+ - VMS.pm: get $path =~ /\s/ checks from perl repository.
+ - Makefile.PL: added INSTALLDIRS => 'perl', since these are std. modules.
+ - Remove vestigial context prototypes from &rel2abs until some future
+ arrives where method prototypes are honored.
use vars qw(@ISA $VERSION);
require File::Spec::Unix;
-$VERSION = '3.63';
+$VERSION = ';.64';
$VERSION =~ tr/_//d;
@ISA = qw(File::Spec::Unix);
=head1 SYNOPSIS
- require File::Spec::AmigaOS; # Done automatically by File::Spec if needed
+ require File::Spec::AmigaOS; # Done automatically by File::Spec
+ # if needed
=head1 DESCRIPTION
use 5.008;
use strict;
use IO::Handle;
-our $VERSION = "1.22";
+our $VERSION = "1.23";
# The following bit of eval-magic is necessary to make this work on
# perls < 5.009005.
This package has the same copyright and license as the perl core:
- Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006 by Larry Wall and others
-
- All rights reserved.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of either:
-
- a) the GNU General Public License as published by the Free
- Software Foundation; either version 1, or (at your option) any
- later version, or
-
- b) the "Artistic License" which comes with this Kit.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either
- the GNU General Public License or the Artistic License for more details.
-
- You should have received a copy of the Artistic License with this
- Kit, in the file named "Artistic". If not, I'll be glad to provide one.
-
- You should also have received a copy of the GNU General Public License
- along with this program in the file named "Copying". If not, write to the
- Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- MA 02110-1301, USA or visit their web page on the internet at
- http://www.gnu.org/copyleft/gpl.html.
-
- For those of you that choose to use the GNU General Public License,
- my interpretation of the GNU General Public License is that no Perl
- script falls under the terms of the GPL unless you explicitly put
- said script under the terms of the GPL yourself. Furthermore, any
- object code linked with perl does not automatically fall under the
- terms of the GPL, provided such object code only adds definitions
- of subroutines and variables, and does not otherwise impair the
- resulting interpreter from executing any standard Perl script. I
- consider linking in C subroutines in this manner to be the moral
- equivalent of defining subroutines in the Perl language itself. You
- may sell such an object file as proprietary provided that you provide
- or offer to provide the Perl source, as specified by the GNU General
- Public License. (This is merely an alternate way of specifying input
- to the program.) You may also sell a binary produced by the dumping of
- a running Perl script that belongs to you, provided that you provide or
- offer to provide the Perl source as specified by the GPL. (The
- fact that a Perl interpreter and your code are in the same binary file
- is, in this case, a form of mere aggregation.) This is my interpretation
- of the GPL. If you still have concerns or difficulties understanding
- my intent, feel free to contact me. Of course, the Artistic License
- spells all this out for your protection, so you may prefer to use that.
+Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+2000, 2001, 2002, 2003, 2004, 2005, 2006 by Larry Wall and others
+
+All rights reserved.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of either:
+
+=over 4
+
+=item a)
+
+the GNU General Public License as published by the Free Software Foundation;
+either version 1, or (at your option) any later version, or
+
+=item b)
+
+the "Artistic License" which comes with this Kit.
+
+=back
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either
+the GNU General Public License or the Artistic License for more details.
+
+You should have received a copy of the Artistic License with this
+Kit, in the file named "Artistic". If not, I'll be glad to provide one.
+
+You should also have received a copy of the GNU General Public License
+along with this program in the file named "Copying". If not, write to the
+Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+MA 02110-1301, USA or visit their web page on the internet at
+http://www.gnu.org/copyleft/gpl.html.
+
+For those of you that choose to use the GNU General Public License,
+my interpretation of the GNU General Public License is that no Perl
+script falls under the terms of the GPL unless you explicitly put
+said script under the terms of the GPL yourself. Furthermore, any
+object code linked with perl does not automatically fall under the
+terms of the GPL, provided such object code only adds definitions
+of subroutines and variables, and does not otherwise impair the
+resulting interpreter from executing any standard Perl script. I
+consider linking in C subroutines in this manner to be the moral
+equivalent of defining subroutines in the Perl language itself. You
+may sell such an object file as proprietary provided that you provide
+or offer to provide the Perl source, as specified by the GNU General
+Public License. (This is merely an alternate way of specifying input
+to the program.) You may also sell a binary produced by the dumping of
+a running Perl script that belongs to you, provided that you provide or
+offer to provide the Perl source as specified by the GPL. (The
+fact that a Perl interpreter and your code are in the same binary file
+is, in this case, a form of mere aggregation.) This is my interpretation
+of the GPL. If you still have concerns or difficulties understanding
+my intent, feel free to contact me. Of course, the Artistic License
+spells all this out for your protection, so you may prefer to use that.
=cut
use vars qw($canonical $forgive_me $VERSION);
-$VERSION = '2.55';
+$VERSION = '2.56';
BEGIN {
if (eval { local $SIG{__DIE__}; require Log::Agent; 1 }) {
Here are some code samples showing a possible usage of Storable:
- use Storable qw(store retrieve freeze thaw dclone);
+ use Storable qw(store retrieve freeze thaw dclone);
- %color = ('Blue' => 0.1, 'Red' => 0.8, 'Black' => 0, 'White' => 1);
+ %color = ('Blue' => 0.1, 'Red' => 0.8, 'Black' => 0, 'White' => 1);
- store(\%color, 'mycolors') or die "Can't store %a in mycolors!\n";
+ store(\%color, 'mycolors') or die "Can't store %a in mycolors!\n";
- $colref = retrieve('mycolors');
- die "Unable to retrieve from mycolors!\n" unless defined $colref;
- printf "Blue is still %lf\n", $colref->{'Blue'};
+ $colref = retrieve('mycolors');
+ die "Unable to retrieve from mycolors!\n" unless defined $colref;
+ printf "Blue is still %lf\n", $colref->{'Blue'};
- $colref2 = dclone(\%color);
+ $colref2 = dclone(\%color);
- $str = freeze(\%color);
- printf "Serialization of %%color is %d bytes long.\n", length($str);
- $colref3 = thaw($str);
+ $str = freeze(\%color);
+ printf "Serialization of %%color is %d bytes long.\n", length($str);
+ $colref3 = thaw($str);
which prints (on my machine):
- Blue is still 0.100000
- Serialization of %color is 102 bytes long.
+ Blue is still 0.100000
+ Serialization of %color is 102 bytes long.
Serialization of CODE references and deserialization in a safe
compartment:
=for example begin
- use Storable qw(freeze thaw);
- use Safe;
- use strict;
- my $safe = new Safe;
+ use Storable qw(freeze thaw);
+ use Safe;
+ use strict;
+ my $safe = new Safe;
# because of opcodes used in "use strict":
- $safe->permit(qw(:default require));
- local $Storable::Deparse = 1;
- local $Storable::Eval = sub { $safe->reval($_[0]) };
- my $serialized = freeze(sub { 42 });
- my $code = thaw($serialized);
- $code->() == 42;
+ $safe->permit(qw(:default require));
+ local $Storable::Deparse = 1;
+ local $Storable::Eval = sub { $safe->reval($_[0]) };
+ my $serialized = freeze(sub { 42 });
+ my $code = thaw($serialized);
+ $code->() == 42;
=for example end
use strict;
use warnings;
-our $VERSION = '3.07';
+our $VERSION = '3.08';
$VERSION = eval $VERSION;
use threads::shared 1.21;
the number of pending items in the queue drops below the C<limit>. The
C<limit> does not prevent enqueuing items beyond that count:
- my $q = Thread::Queue->new(1, 2);
- $q->limit = 4;
- $q->enqueue(3, 4, 5); # Does not block
- $q->enqueue(6); # Blocks until at least 2 items are dequeued
-
- my $size = $q->limit; # Returns the current limit (may return 'undef')
- $q->limit = 0; # Queue size is now unlimited
+ my $q = Thread::Queue->new(1, 2);
+ $q->limit = 4;
+ $q->enqueue(3, 4, 5); # Does not block
+ $q->enqueue(6); # Blocks until at least 2 items are
+ # dequeued
+ my $size = $q->limit; # Returns the current limit (may return
+ # 'undef')
+ $q->limit = 0; # Queue size is now unlimited
=item ->end()
while it is being examined and/or changed, L<lock|threads::shared/"lock
VARIABLE"> the queue inside a local block:
- {
- lock($q); # Keep other threads from changing the queue's contents
- my $item = $q->peek();
- if ($item ...) {
- ...
- }
- }
- # Queue is now unlocked
+ {
+ lock($q); # Keep other threads from changing the queue's contents
+ my $item = $q->peek();
+ if ($item ...) {
+ ...
+ }
+ }
+ # Queue is now unlocked
=over
queue from the specified position (i.e. if queue size + index + count is
greater than zero):
- $q->enqueue(qw/foo bar baz/);
- my @nada = $q->extract(-6, 2); # Returns () - (3+(-6)+2) <= 0
- my @some = $q->extract(-6, 4); # Returns (foo) - (3+(-6)+4) > 0
- # Queue now contains: bar, baz
- my @rest = $q->extract(-3, 4); # Returns (bar, baz) - (2+(-3)+4) > 0
+ $q->enqueue(qw/foo bar baz/);
+ my @nada = $q->extract(-6, 2); # Returns () - (3+(-6)+2) <= 0
+ my @some = $q->extract(-6, 4); # Returns (foo) - (3+(-6)+4) > 0
+ # Queue now contains: bar, baz
+ my @rest = $q->extract(-3, 4); # Returns
+ # (bar, baz) - (2+(-3)+4) > 0
=back
sub O_ACCMODE () { O_RDONLY | O_RDWR | O_WRONLY }
-$VERSION = "1.01";
+$VERSION = "1.02";
my $DEFAULT_MEMORY_SIZE = 1<<21; # 2 megabytes
my $DEFAULT_AUTODEFER_THRESHHOLD = 3; # 3 records
my $DEFAULT_AUTODEFER_FILELEN_THRESHHOLD = 65536; # 16 disk blocksful
=head1 SYNOPSIS
- # This file documents Tie::File version 0.98
- use Tie::File;
+ # This file documents Tie::File version 0.98
+ use Tie::File;
- tie @array, 'Tie::File', filename or die ...;
+ tie @array, 'Tie::File', filename or die ...;
- $array[13] = 'blah'; # line 13 of the file is now 'blah'
- print $array[42]; # display line 42 of the file
+ $array[13] = 'blah'; # line 13 of the file is now 'blah'
+ print $array[42]; # display line 42 of the file
- $n_recs = @array; # how many records are in the file?
- $#array -= 2; # chop two records off the end
+ $n_recs = @array; # how many records are in the file?
+ $#array -= 2; # chop two records off the end
- for (@array) {
- s/PERL/Perl/g; # Replace PERL with Perl everywhere in the file
- }
+ for (@array) {
+ s/PERL/Perl/g; # Replace PERL with Perl everywhere in the file
+ }
- # These are just like regular push, pop, unshift, shift, and splice
- # Except that they modify the file in the way you would expect
+ # These are just like regular push, pop, unshift, shift, and splice
+ # Except that they modify the file in the way you would expect
- push @array, new recs...;
- my $r1 = pop @array;
- unshift @array, new recs...;
- my $r2 = shift @array;
- @old_recs = splice @array, 3, 7, new recs...;
+ push @array, new recs...;
+ my $r1 = pop @array;
+ unshift @array, new recs...;
+ my $r2 = shift @array;
+ @old_recs = splice @array, 3, 7, new recs...;
- untie @array; # all finished
+ untie @array; # all finished
=head1 DESCRIPTION
cache size by supplying the C<memory> option. The argument is the
desired cache size, in bytes.
- # I have a lot of memory, so use a large cache to speed up access
- tie @array, 'Tie::File', $file, memory => 20_000_000;
+ # I have a lot of memory, so use a large cache to speed up access
+ tie @array, 'Tie::File', $file, memory => 20_000_000;
Setting the memory limit to 0 will inhibit caching; records will be
fetched from disk every time you examine them.
print "1..1\n";
-my $testversion = "1.01";
+my $testversion = "1.02";
use Tie::File;
if ($Tie::File::VERSION != $testversion) {
Revision history for the Perl extension Time::HiRes.
+1.9732 [2016-03-13]
+ - MUTEX_LOCK, not PERL_MUTEX_LOCK: blead e5b02b5d
+ - also hrt_ualarm_itimer() is unused: 1cb6cce3
+ - the mutex needs init: 2d639e20
+ - version bump to 1.9732: 730d7fdc
+
+1.9731 [2016-03-13]
+ - mark unused variable as such: blead a914236c
+ - OS X emulation mutex accidentally unused: da7a6455
+ - remove hrt_ualarm: 6da77c36
+ - pod error fixes: 919ca095
+ - nanosleep and clock_nanosleep cleanups: c8ea02b8..e3ff671b
+ - static funcs in HiRes.xs: 4e922c26
+ - Remove unused variable: 52ffb1b5
+
1.9730 [2016-02-17]
- TIME_HIRES_DONT_RUN_PROBES=1 to build the probes but not run them
[rt.cpan.org #111391]
stat lstat
);
-our $VERSION = '1.9730';
+our $VERSION = '1.9732';
our $XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
getitimer ($which);
use Time::HiRes qw( clock_gettime clock_getres clock_nanosleep
- ITIMER_REAL ITIMER_VIRTUAL ITIMER_PROF ITIMER_REALPROF );
+ ITIMER_REAL ITIMER_VIRTUAL ITIMER_PROF
+ ITIMER_REALPROF );
$realtime = clock_gettime(CLOCK_REALTIME);
$resolution = clock_getres(CLOCK_REALTIME);
unsigned __int64 ticks;
FT_t ft;
+ PERL_UNUSED_ARG(not_used);
if (MY_CXT.run_count++ == 0 ||
MY_CXT.base_systime_as_filetime.ft_i64 > MY_CXT.reset_time) {
QueryPerformanceFrequency((LARGE_INTEGER*)&MY_CXT.tick_frequency);
#define HAS_USLEEP
#define usleep hrt_usleep /* could conflict with ncurses for static build */
-void
+static void
hrt_usleep(unsigned long usec) /* This is used to emulate usleep. */
{
struct timespec res;
#define HAS_USLEEP
#define usleep hrt_usleep /* could conflict with ncurses for static build */
-void
+static void
hrt_usleep(unsigned long usec)
{
struct timeval tv;
#define HAS_USLEEP
#define usleep hrt_usleep /* could conflict with ncurses for static build */
-void
+static void
hrt_usleep(unsigned long usec)
{
long msec;
#define HAS_USLEEP
#define usleep hrt_usleep /* could conflict with ncurses for static build */
-void
+static void
hrt_usleep(unsigned long usec)
{
int msec = usec / 1000;
return setitimer(ITIMER_REAL, &itv, oitv);
}
-int
-hrt_ualarm_itimer(int usec, int uinterval)
-{
- return hrt_ualarm_itimero(NULL, usec, uinterval);
-}
-
-#ifdef HAS_UALARM
-int
-hrt_ualarm(int usec, int interval) /* for binary compat before 1.91 */
-{
- return hrt_ualarm_itimer(usec, interval);
-}
-#endif /* #ifdef HAS_UALARM */
#endif /* #if !defined(HAS_UALARM) && defined(HAS_SETITIMER) */
#if !defined(HAS_UALARM) && defined(HAS_SETITIMER)
static struct timespec timespec_init;
static int darwin_time_init() {
-#ifdef USE_ITHREAD
- PERL_MUTEX_LOCK(&darwin_time_mutex);
+#ifdef USE_ITHREADS
+ MUTEX_LOCK(&darwin_time_mutex);
#endif
struct timeval tv;
int success = 1;
}
}
}
-#ifdef USE_ITHREAD
- PERL_MUTEX_UNLOCK(&darwin_time_mutex);
+#ifdef USE_ITHREADS
+ MUTEX_UNLOCK(&darwin_time_mutex);
#endif
return success;
}
#include "const-c.inc"
+#if (defined(TIME_HIRES_NANOSLEEP)) || \
+ (defined(TIME_HIRES_CLOCK_NANOSLEEP) && defined(TIMER_ABSTIME))
+
+static void
+nanosleep_init(NV nsec,
+ struct timespec *sleepfor,
+ struct timespec *unslept) {
+ sleepfor->tv_sec = (Time_t)(nsec / NV_1E9);
+ sleepfor->tv_nsec = (long)(nsec - ((NV)sleepfor->tv_sec) * NV_1E9);
+ unslept->tv_sec = 0;
+ unslept->tv_nsec = 0;
+}
+
+static NV
+nsec_without_unslept(struct timespec *sleepfor,
+ const struct timespec *unslept) {
+ if (sleepfor->tv_sec >= unslept->tv_sec) {
+ sleepfor->tv_sec -= unslept->tv_sec;
+ if (sleepfor->tv_nsec >= unslept->tv_nsec) {
+ sleepfor->tv_nsec -= unslept->tv_nsec;
+ } else if (sleepfor->tv_sec > 0) {
+ sleepfor->tv_sec--;
+ sleepfor->tv_nsec += IV_1E9;
+ sleepfor->tv_nsec -= unslept->tv_nsec;
+ } else {
+ sleepfor->tv_sec = 0;
+ sleepfor->tv_nsec = 0;
+ }
+ } else {
+ sleepfor->tv_sec = 0;
+ sleepfor->tv_nsec = 0;
+ }
+ return ((NV)sleepfor->tv_sec) * NV_1E9 + ((NV)sleepfor->tv_nsec);
+}
+
+#endif
+
MODULE = Time::HiRes PACKAGE = Time::HiRes
PROTOTYPES: ENABLE
}
# endif
#endif
+#if defined(PERL_DARWIN)
+# ifdef USE_ITHREADS
+ MUTEX_INIT(&darwin_time_mutex);
+# endif
+#endif
}
#if defined(USE_ITHREADS) && defined(MY_CXT_KEY)
CODE:
gettimeofday(&Ta, NULL);
if (items > 0) {
- if (useconds >= 1E6) {
- IV seconds = (IV) (useconds / 1E6);
+ if (useconds >= NV_1E6) {
+ IV seconds = (IV) (useconds / NV_1E6);
/* If usleep() has been implemented using setitimer()
* then this contortion is unnecessary-- but usleep()
* may be implemented in some other way, so let's contort. */
if (seconds) {
sleep(seconds);
- useconds -= 1E6 * seconds;
+ useconds -= NV_1E6 * seconds;
}
} else if (useconds < 0.0)
croak("Time::HiRes::usleep(%"NVgf"): negative time not invented yet", useconds);
#if 0
printf("[%ld %ld] [%ld %ld]\n", Tb.tv_sec, Tb.tv_usec, Ta.tv_sec, Ta.tv_usec);
#endif
- RETVAL = 1E6*(Tb.tv_sec-Ta.tv_sec)+(NV)((IV)Tb.tv_usec-(IV)Ta.tv_usec);
+ RETVAL = NV_1E6*(Tb.tv_sec-Ta.tv_sec)+(NV)((IV)Tb.tv_usec-(IV)Ta.tv_usec);
OUTPUT:
RETVAL
CODE:
if (nsec < 0.0)
croak("Time::HiRes::nanosleep(%"NVgf"): negative time not invented yet", nsec);
- sleepfor.tv_sec = (Time_t)(nsec / 1e9);
- sleepfor.tv_nsec = (long)(nsec - ((NV)sleepfor.tv_sec) * 1e9);
- if (!nanosleep(&sleepfor, &unslept)) {
+ nanosleep_init(nsec, &sleepfor, &unslept);
+ if (nanosleep(&sleepfor, &unslept) == 0) {
RETVAL = nsec;
} else {
- sleepfor.tv_sec -= unslept.tv_sec;
- sleepfor.tv_nsec -= unslept.tv_nsec;
- if (sleepfor.tv_nsec < 0) {
- sleepfor.tv_sec--;
- sleepfor.tv_nsec += 1000000000;
- }
- RETVAL = ((NV)sleepfor.tv_sec) * 1e9 + ((NV)sleepfor.tv_nsec);
+ RETVAL = nsec_without_unslept(&sleepfor, &unslept);
}
OUTPUT:
RETVAL
#else
status = clock_gettime(clock_id, &ts);
#endif
- RETVAL = status == 0 ? ts.tv_sec + (NV) ts.tv_nsec / (NV) 1e9 : -1;
+ RETVAL = status == 0 ? ts.tv_sec + (NV) ts.tv_nsec / NV_1E9 : -1;
OUTPUT:
RETVAL
#else
status = clock_getres(clock_id, &ts);
#endif
- RETVAL = status == 0 ? ts.tv_sec + (NV) ts.tv_nsec / (NV) 1e9 : -1;
+ RETVAL = status == 0 ? ts.tv_sec + (NV) ts.tv_nsec / NV_1E9 : -1;
OUTPUT:
RETVAL
CODE:
if (nsec < 0.0)
croak("Time::HiRes::clock_nanosleep(..., %"NVgf"): negative time not invented yet", nsec);
- sleepfor.tv_sec = (Time_t)(nsec / 1e9);
- sleepfor.tv_nsec = (long)(nsec - ((NV)sleepfor.tv_sec) * 1e9);
- if (!clock_nanosleep(clock_id, flags, &sleepfor, &unslept)) {
+ nanosleep_init(nsec, &sleepfor, &unslept);
+ if (clock_nanosleep(clock_id, flags, &sleepfor, &unslept) == 0) {
RETVAL = nsec;
} else {
- sleepfor.tv_sec -= unslept.tv_sec;
- sleepfor.tv_nsec -= unslept.tv_nsec;
- if (sleepfor.tv_nsec < 0) {
- sleepfor.tv_sec--;
- sleepfor.tv_nsec += 1000000000;
- }
- RETVAL = ((NV)sleepfor.tv_sec) * 1e9 + ((NV)sleepfor.tv_nsec);
+ RETVAL = nsec_without_unslept(&sleepfor, &unslept);
}
OUTPUT:
RETVAL
UV ctime_nsec;
hrstatns(&atime_nsec, &mtime_nsec, &ctime_nsec);
if (atime_nsec)
- ST( 8) = sv_2mortal(newSVnv(atime + 1e-9 * (NV) atime_nsec));
+ ST( 8) = sv_2mortal(newSVnv(atime + (NV) atime_nsec / NV_1E9));
if (mtime_nsec)
- ST( 9) = sv_2mortal(newSVnv(mtime + 1e-9 * (NV) mtime_nsec));
+ ST( 9) = sv_2mortal(newSVnv(mtime + (NV) mtime_nsec / NV_1E9));
if (ctime_nsec)
- ST(10) = sv_2mortal(newSVnv(ctime + 1e-9 * (NV) ctime_nsec));
+ ST(10) = sv_2mortal(newSVnv(ctime + (NV) ctime_nsec / NV_1E9));
}
XSRETURN(nret);
#use strict; # debugging only
use 5.006; # use warnings
-$autouse::VERSION = '1.08';
+$autouse::VERSION = '1.11';
$autouse::DEBUG ||= 0;
'no redefinition warning when clobbering autouse stub via *a=\&b';
}
SKIP: {
- skip "Fails from 5.10 to 5.15.5 (perl bug)", 1
- if $] < 5.0150051 and $] > 5.0099;
+ skip "Fails in 5.15.5 and below (perl bug)", 1 if $] < 5.0150051;
use Config;
skip "no B", 1 unless $Config{extensions} =~ /\bB\b/;
use warnings; local $^W = 1; no warnings 'once';
use strict;
use warnings;
-our $VERSION = '2.05';
+our $VERSION = '2.06';
my $XS_VERSION = $VERSION;
$VERSION = eval $VERSION;
then using a threads object in a string or a string context (e.g., as a hash
key) will cause its ID to be used as the value:
- use threads qw(stringify);
+ use threads qw(stringify);
- my $thr = threads->create(...);
- print("Thread $thr started...\n"); # Prints out: Thread 1 started...
+ my $thr = threads->create(...);
+ print("Thread $thr started...\n"); # Prints: Thread 1 started...
=item threads->object($tid)
To specify a particular stack size for any individual thread, call
C<-E<gt>create()> with a hash reference as the first argument:
- my $thr = threads->create({'stack_size' => 32*4096}, \&foo, @args);
+ my $thr = threads->create({'stack_size' => 32*4096}, \&foo, @args);
=item $thr2 = $thr1->create(FUNCTION, ARGS)
This creates a new thread (C<$thr2>) that inherits the stack size from an
existing thread (C<$thr1>). This is shorthand for the following:
- my $stack_size = $thr1->get_stack_size();
- my $thr2 = threads->create({'stack_size' => $stack_size}, FUNCTION, ARGS);
+ my $stack_size = $thr1->get_stack_size();
+ my $thr2 = threads->create({'stack_size' => $stack_size},
+ FUNCTION, ARGS);
=back
return (stack_size);
}
+/* run some code within a JMPENV environment.
+ * Having it in a separate small function helps avoid
+ * 'variable ‘foo’ might be clobbered by ‘longjmp’
+ * warnings.
+ * The three _p vars return values to the caller
+ */
+
+static int
+S_jmpenv_run(pTHX_ int action, ithread *thread,
+ int *len_p, int *exit_app_p, int *exit_code_p)
+{
+ dJMPENV;
+ volatile I32 oldscope = PL_scopestack_ix;
+ int jmp_rc = 0;
+
+ JMPENV_PUSH(jmp_rc);
+ if (jmp_rc == 0) {
+ if (action == 0) {
+ /* Run the specified function */
+ *len_p = (int)call_sv(thread->init_function, thread->gimme|G_EVAL);
+ }
+ else if (action == 1) {
+ /* Warn that thread died */
+ Perl_warn(aTHX_ "Thread %" UVuf " terminated abnormally: %" SVf, thread->tid, ERRSV);
+ }
+ else {
+ /* Warn if there are unjoined threads */
+ S_exit_warning(aTHX);
+ }
+ } else if (jmp_rc == 2) {
+ /* Thread exited */
+ *exit_app_p = 1;
+ *exit_code_p = STATUS_CURRENT;
+ while (PL_scopestack_ix > oldscope) {
+ LEAVE;
+ }
+ }
+ JMPENV_POP;
+ return jmp_rc;
+}
+
/* Starts executing the thread.
* Passed as the C level function to run in the new thread.
#endif
{
ithread *thread = (ithread *)arg;
- int jmp_rc = 0;
- volatile I32 oldscope;
- volatile int exit_app = 0; /* Thread terminated using 'exit' */
- volatile int exit_code = 0;
- volatile int died = 0; /* Thread terminated abnormally */
+ int exit_app = 0; /* Thread terminated using 'exit' */
+ int exit_code = 0;
+ int died = 0; /* Thread terminated abnormally */
- dJMPENV;
dTHXa(thread->interp);
{
AV *params = thread->params;
- volatile int len = (int)av_len(params)+1;
+ int len = (int)av_len(params)+1;
int ii;
+ int jmp_rc;
dSP;
ENTER;
}
PUTBACK;
- oldscope = PL_scopestack_ix;
- JMPENV_PUSH(jmp_rc);
- if (jmp_rc == 0) {
- /* Run the specified function */
- len = (int)call_sv(thread->init_function, thread->gimme|G_EVAL);
- } else if (jmp_rc == 2) {
- /* Thread exited */
- exit_app = 1;
- exit_code = STATUS_CURRENT;
- while (PL_scopestack_ix > oldscope) {
- LEAVE;
- }
- }
- JMPENV_POP;
+ jmp_rc = S_jmpenv_run(aTHX_ 0, thread, &len, &exit_app, &exit_code);
#ifdef THREAD_SIGNAL_BLOCKING
/* The interpreter is finished, so this thread can stop receiving
}
if (ckWARN_d(WARN_THREADS)) {
- oldscope = PL_scopestack_ix;
- JMPENV_PUSH(jmp_rc);
- if (jmp_rc == 0) {
- /* Warn that thread died */
- Perl_warn(aTHX_ "Thread %" UVuf " terminated abnormally: %" SVf, thread->tid, ERRSV);
- } else if (jmp_rc == 2) {
- /* Warn handler exited */
- exit_app = 1;
- exit_code = STATUS_CURRENT;
- while (PL_scopestack_ix > oldscope) {
- LEAVE;
- }
- }
- JMPENV_POP;
+ (void)S_jmpenv_run(aTHX_ 1, thread, NULL,
+ &exit_app, &exit_code);
}
}
/* Exit application if required */
if (exit_app) {
- oldscope = PL_scopestack_ix;
- JMPENV_PUSH(jmp_rc);
- if (jmp_rc == 0) {
- /* Warn if there are unjoined threads */
- S_exit_warning(aTHX);
- } else if (jmp_rc == 2) {
- /* Warn handler exited */
- exit_code = STATUS_CURRENT;
- while (PL_scopestack_ix > oldscope) {
- LEAVE;
- }
- }
- JMPENV_POP;
-
+ (void)S_jmpenv_run(aTHX_ 2, thread, NULL, &exit_app, &exit_code);
my_exit(exit_code);
}
CLANG_DIAG_IGNORE(-Wthread-safety);
/* warning: mutex 'thread->mutex' is not held on every path through here [-Wthread-safety-analysis] */
}
+#if defined(__clang__) || defined(__clang)
CLANG_DIAG_RESTORE;
+#endif
#endif /* USE_ITHREADS */
Perl_nextargv(pTHX_ GV *gv, bool nomagicopen)
{
IO * const io = GvIOp(gv);
+ SV *const old_out_name = PL_inplace ? newSVsv(GvSV(gv)) : NULL;
PERL_ARGS_ASSERT_NEXTARGV;
+ if (old_out_name)
+ SAVEFREESV(old_out_name);
+
if (!PL_argvoutgv)
PL_argvoutgv = gv_fetchpvs("ARGVOUT", GV_ADD|GV_NOTQUAL, SVt_PVIO);
if (io && (IoFLAGS(io) & (IOf_ARGV|IOf_START)) == (IOf_ARGV|IOf_START)) {
}
}
else {
+ {
+ IO * const io = GvIOp(PL_argvoutgv);
+ if (io && IoIFP(io) && old_out_name && !io_close(io, PL_argvoutgv, FALSE, FALSE)) {
+ Perl_croak(aTHX_ "Failed to close in-place edit file %"SVf": %s\n",
+ old_out_name, Strerror(errno));
+ }
+ }
/* This very long block ends with return IoIFP(GvIOp(gv));
Both this block and the block above fall through on open
failure to the warning code, and then the while loop above tries
if (io && (IoFLAGS(io) & IOf_ARGV))
IoFLAGS(io) |= IOf_START;
if (PL_inplace) {
- (void)do_close(PL_argvoutgv,FALSE);
+ if (old_out_name) {
+ IO * const io = GvIOp(PL_argvoutgv);
+ if (io && IoIFP(io) && !io_close(io, PL_argvoutgv, FALSE, FALSE)) {
+ Perl_croak(aTHX_ "Failed to close in-place edit file %"SVf": %s\n",
+ old_out_name, Strerror(errno));
+ }
+ }
+ else {
+ /* maybe this is no longer wanted */
+ (void)do_close(PL_argvoutgv,FALSE);
+ }
if (io && (IoFLAGS(io) & IOf_ARGV)
&& PL_argvout_stack && AvFILLp(PL_argvout_stack) >= 0)
{
{PREGf_ANCH_GPOS, "ANCH_GPOS,"},
};
+/* Perl_do_sv_dump():
+ *
+ * level: amount to indent the output
+ * sv: the object to dump
+ * nest: the current level of recursion
+ * maxnest: the maximum allowed level of recursion
+ * dumpops: if true, also dump the ops associated with a CV
+ * pvlim: limit on the length of any strings that are output
+ * */
+
void
Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bool dumpops, STRLEN pvlim)
{
LEAVE;
}
- OP_ENTRY_PROBE(OP_NAME(PL_op));
+ PERL_DTRACE_PROBE_OP(PL_op);
} while ((PL_op = PL_op->op_ppaddr(aTHX)));
DEBUG_l(Perl_deb(aTHX_ "leaving RUNOPS level\n"));
PERL_ASYNC_CHECK();
Ap |void |init_stacks
Ap |void |init_tm |NN struct tm *ptm
: Used in perly.y
-AnpPR |char* |instr |NN const char* big|NN const char* little
+AbmnpPR |char* |instr |NN const char* big|NN const char* little
: Used in sv.c
p |bool |io_close |NN IO* io|NULLOK GV *gv \
|bool not_implicit|bool warn_on_fail
p |int |mode_from_discipline|NULLOK const char* s|STRLEN len
Ap |const char* |moreswitches |NN const char* s
Ap |NV |my_atof |NN const char *s
-#if (!defined(HAS_MEMCPY) && !defined(HAS_BCOPY)) || (!defined(HAS_MEMMOVE) && !defined(HAS_SAFE_MEMCPY) && !defined(HAS_SAFE_BCOPY))
-Anp |char* |my_bcopy |NN const char* from|NN char* to|I32 len
+#if !defined(HAS_MEMCPY) || (!defined(HAS_MEMMOVE) && !defined(HAS_SAFE_MEMCPY))
+Anp |void* |my_bcopy |NN const void* vfrom|NN void* vto|size_t len
#endif
#if !defined(HAS_BZERO) && !defined(HAS_MEMSET)
-Anp |char* |my_bzero |NN char* loc|I32 len
+Anp |void* |my_bzero |NN void* vloc|size_t len
#endif
Apr |void |my_exit |U32 status
Apr |void |my_failure_exit
Apmb |I32 |my_lstat
pX |I32 |my_lstat_flags |NULLOK const U32 flags
#if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP)
-AnpP |I32 |my_memcmp |NN const char* s1|NN const char* s2|I32 len
+AnpP |int |my_memcmp |NN const void* vs1|NN const void* vs2|size_t len
#endif
#if !defined(HAS_MEMSET)
-Anp |void* |my_memset |NN char* loc|I32 ch|I32 len
+Anp |void* |my_memset |NN void* vloc|int ch|size_t len
#endif
#if !defined(PERL_IMPLICIT_SYS)
Ap |I32 |my_pclose |NULLOK PerlIO* ptr
EiM |void |invlist_set_len|NN SV* const invlist|const UV len|const bool offset
EiMRn |bool |invlist_is_iterating|NN SV* const invlist
#ifndef PERL_EXT_RE_BUILD
+EsM |void |invlist_replace_list_destroys_src|NN SV *dest|NN SV *src
EiMRn |IV* |get_invlist_previous_index_addr|NN SV* invlist
EiMn |void |invlist_set_previous_index|NN SV* const invlist|const IV index
EiMRn |IV |invlist_previous_index|NN SV* const invlist
-EiMn |void |invlist_trim |NN SV* const invlist
+EiMn |void |invlist_trim |NN SV* invlist
+EiM |void |invlist_clear |NN SV* invlist
#endif
EiMR |SV* |invlist_clone |NN SV* const invlist
EiMRn |STRLEN*|get_invlist_iter_addr |NN SV* invlist
#if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_REGEXEC_C)
Ep |void |regprop |NULLOK const regexp *prog|NN SV* sv|NN const regnode* o|NULLOK const regmatch_info *reginfo \
|NULLOK const RExC_state_t *pRExC_state
+Ep |int |re_printf |NN const char *fmt|...
#endif
#if defined(PERL_IN_REGCOMP_C)
Es |regnode*|reg |NN RExC_state_t *pRExC_state \
|NULLOK SV* const only_utf8_locale_list \
|NULLOK SV* const swash \
|const bool has_user_defined_property
+Es |void |output_or_return_posix_warnings \
+ |NN RExC_state_t *pRExC_state \
+ |NN AV* posix_warnings \
+ |NULLOK AV** return_posix_warnings
Es |AV* |add_multi_match|NULLOK AV* multi_char_matches \
|NN SV* multi_string \
|const STRLEN cp_count
|const bool strict \
|bool optimizable \
|NULLOK SV** ret_invlist \
- |NULLOK AV** posix_warnings
+ |NULLOK AV** return_posix_warnings
Es |void|add_above_Latin1_folds|NN RExC_state_t *pRExC_state|const U8 cp \
|NN SV** invlist
Ei |regnode*|handle_named_backref|NN RExC_state_t *pRExC_state \
|NN RExC_state_t *pRExC_state \
|NN const char* const s \
|NULLOK char ** updated_parse_ptr \
- |NULLOK AV** posix_warnings
+ |NULLOK AV** posix_warnings \
+ |const bool check_only
Es |I32 |make_trie |NN RExC_state_t *pRExC_state \
|NN regnode *startbranch|NN regnode *first \
|NN regnode *last|NN regnode *tail \
|const STRLEN y \
|const SSize_t maxDistance
# ifdef DEBUGGING
+Ep |int |re_indentf |NN const char *fmt|U32 depth|...
Es |void |regdump_intflags|NULLOK const char *lead| const U32 flags
Es |void |regdump_extflags|NULLOK const char *lead| const U32 flags
Es |const regnode*|dumpuntil|NN const regexp *r|NN const regnode *start \
|const bool utf8_target
# ifdef DEBUGGING
Es |void |dump_exec_pos |NN const char *locinput|NN const regnode *scan|NN const char *loc_regeol\
- |NN const char *loc_bostr|NN const char *loc_reg_starttry|const bool do_utf8
+ |NN const char *loc_bostr|NN const char *loc_reg_starttry|const bool do_utf8|const U32 depth
Es |void |debug_start_match|NN const REGEXP *prog|const bool do_utf8\
|NN const char *start|NN const char *end\
|NN const char *blurb
+
+Ep |int |re_exec_indentf |NN const char *fmt|U32 depth|...
# endif
#endif
AiM |void |cx_popgiven |NN PERL_CONTEXT *cx
#endif
+#ifdef USE_DTRACE
+XEop |void |dtrace_probe_call |NN CV *cv|bool is_call
+XEop |void |dtrace_probe_load |NN const char *name|bool is_loading
+XEop |void |dtrace_probe_op |NN const OP *op
+XEop |void |dtrace_probe_phase|enum perl_phase phase
+#endif
+
: ex: set ts=8 sts=4 sw=4 noet:
#define init_i18nl14n(a) Perl_init_i18nl14n(aTHX_ a)
#define init_stacks() Perl_init_stacks(aTHX)
#define init_tm(a) Perl_init_tm(aTHX_ a)
-#define instr Perl_instr
#define intro_my() Perl_intro_my(aTHX)
#define isALNUM_lazy(a) Perl_isALNUM_lazy(aTHX_ a)
#define isIDFIRST_lazy(a) Perl_isIDFIRST_lazy(aTHX_ a)
#if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP)
#define my_memcmp Perl_my_memcmp
#endif
+#if !defined(HAS_MEMCPY) || (!defined(HAS_MEMMOVE) && !defined(HAS_SAFE_MEMCPY))
+#define my_bcopy Perl_my_bcopy
+#endif
#if !defined(HAS_MEMSET)
#define my_memset Perl_my_memset
#endif
#define cx_topblock(a) S_cx_topblock(aTHX_ a)
#define is_safe_syscall(a,b,c,d) S_is_safe_syscall(aTHX_ a,b,c,d)
#endif
-#if (!defined(HAS_MEMCPY) && !defined(HAS_BCOPY)) || (!defined(HAS_MEMMOVE) && !defined(HAS_SAFE_MEMCPY) && !defined(HAS_SAFE_BCOPY))
-#define my_bcopy Perl_my_bcopy
-#endif
#if defined(DEBUGGING)
#define pad_setsv(a,b) Perl_pad_setsv(aTHX_ a,b)
#define pad_sv(a) Perl_pad_sv(aTHX_ a)
# if !defined(PERL_EXT_RE_BUILD)
# if defined(PERL_IN_REGCOMP_C)
#define get_invlist_previous_index_addr S_get_invlist_previous_index_addr
+#define invlist_clear(a) S_invlist_clear(aTHX_ a)
#define invlist_previous_index S_invlist_previous_index
+#define invlist_replace_list_destroys_src(a,b) S_invlist_replace_list_destroys_src(aTHX_ a,b)
#define invlist_set_previous_index S_invlist_set_previous_index
#define invlist_trim S_invlist_trim
# endif
#define put_charclass_bitmap_innards_invlist(a,b) S_put_charclass_bitmap_innards_invlist(aTHX_ a,b)
#define put_code_point(a,b) S_put_code_point(aTHX_ a,b)
#define put_range(a,b,c,d) S_put_range(aTHX_ a,b,c,d)
+#ifndef PERL_IMPLICIT_CONTEXT
+#define re_indentf Perl_re_indentf
+#endif
#define regdump_extflags(a,b) S_regdump_extflags(aTHX_ a,b)
#define regdump_intflags(a,b) S_regdump_intflags(aTHX_ a,b)
#define regtail_study(a,b,c,d) S_regtail_study(aTHX_ a,b,c,d)
# endif
# if defined(PERL_IN_REGEXEC_C)
#define debug_start_match(a,b,c,d,e) S_debug_start_match(aTHX_ a,b,c,d,e)
-#define dump_exec_pos(a,b,c,d,e,f) S_dump_exec_pos(aTHX_ a,b,c,d,e,f)
+#define dump_exec_pos(a,b,c,d,e,f,g) S_dump_exec_pos(aTHX_ a,b,c,d,e,f,g)
+#ifndef PERL_IMPLICIT_CONTEXT
+#define re_exec_indentf Perl_re_exec_indentf
+#endif
# endif
# endif
# if defined(PERL_ANY_COW)
#define get_invlist_iter_addr S_get_invlist_iter_addr
#define grok_bslash_N(a,b,c,d,e,f,g) S_grok_bslash_N(aTHX_ a,b,c,d,e,f,g)
#define handle_named_backref(a,b,c,d) S_handle_named_backref(aTHX_ a,b,c,d)
-#define handle_possible_posix(a,b,c,d) S_handle_possible_posix(aTHX_ a,b,c,d)
+#define handle_possible_posix(a,b,c,d,e) S_handle_possible_posix(aTHX_ a,b,c,d,e)
#define handle_regex_sets(a,b,c,d,e) S_handle_regex_sets(aTHX_ a,b,c,d,e)
#define invlist_clone(a) S_invlist_clone(aTHX_ a)
#define invlist_contents(a,b) S_invlist_contents(aTHX_ a,b)
#define join_exact(a,b,c,d,e,f,g) S_join_exact(aTHX_ a,b,c,d,e,f,g)
#define make_trie(a,b,c,d,e,f,g,h) S_make_trie(aTHX_ a,b,c,d,e,f,g,h)
#define nextchar(a) S_nextchar(aTHX_ a)
+#define output_or_return_posix_warnings(a,b,c) S_output_or_return_posix_warnings(aTHX_ a,b,c)
#define parse_lparen_question_flags(a) S_parse_lparen_question_flags(aTHX_ a)
#define populate_ANYOF_from_invlist(a,b) S_populate_ANYOF_from_invlist(aTHX_ a,b)
#define reg(a,b,c,d) S_reg(aTHX_ a,b,c,d)
# endif
# if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_REGEXEC_C)
#define _load_PL_utf8_foldclosures() Perl__load_PL_utf8_foldclosures(aTHX)
+#ifndef PERL_IMPLICIT_CONTEXT
+#define re_printf Perl_re_printf
+#endif
#define regprop(a,b,c,d,e) Perl_regprop(aTHX_ a,b,c,d,e)
# endif
# if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_REGEXEC_C) || defined(PERL_IN_UTF8_C)
our @EXPORT = qw(
);
-our $VERSION = '0.02';
+our $VERSION = '0.04';
require XSLoader;
XSLoader::load('Amiga::ARexx', $VERSION);
# Create a new host
use Amiga::ARexx;
- my $host = Amiga::ARexx->new('HostName' => "PERLREXX" ); );
+ my $host = Amiga::ARexx->new('HostName' => "PERLREXX" );
# Wait for and process rexxcommands
=head2 new
- my $host = Amiga::ARexx->new( HostName => "PERLREXX"); );
+ my $host = Amiga::ARexx->new( HostName => "PERLREXX");
Create an ARexx host for your script / program.
our @EXPORT = qw(
);
-our $VERSION = '0.01';
+our $VERSION = '0.02';
require XSLoader;
XSLoader::load('Amiga::Exec', $VERSION);
=head2 Wait
- $signals = Amiga::Exec->Wait('SignalMask' => $signalmask, 'TimeOut' => $timeoutinusecs );
+ $signals = Amiga::Exec->Wait('SignalMask' => $signalmask,
+ 'TimeOut' => $timeoutinusecs );
Wait on a signal set with optional timeout. The result ($signals) should be checked to
determine which signal was raised. It will be 0 for timeout.
use Config;
use strict;
-our $VERSION = "1.24";
+our $VERSION = "1.25";
my %err = ();
}
}
+ my $pat;
+ if ($IsMSWin32) {
+ $pat = '^\s*#\s*define\s+((?:WSA)?E\w+)\s+';
+ }
+ else {
+ $pat = '^\s*#\s*define\s+(E\w+)\s+';
+ }
while(<FH>) {
$err{$1} = 1
- if /^\s*#\s*define\s+(E\w+)\s+/;
+ if /$pat/;
}
close(FH);
EUSERS EWOULDBLOCK EXDEV));
$k =~ s/(.{50,70})\s/$1\n\t/g;
- print "\t",$k,"\n )]\n);\n\n";
+ print "\t",$k,"\n )],\n";
+
+ if ($IsMSWin32) {
+ print " WINSOCK => [qw(\n";
+ $k = join(" ", grep { /^WSAE/ } keys %err);
+ $k =~ s/(.{50,70})\s/$1\n\t/g;
+ print "\t",$k,"\n )],\n";
+ }
+
+ print ");\n\n";
print <<'ESQ';
sub TIEHASH { bless \%err }
=head1 DESCRIPTION
C<Errno> defines and conditionally exports all the error constants
-defined in your system C<errno.h> include file. It has a single export
+defined in your system F<errno.h> include file. It has a single export
tag, C<:POSIX>, which will export all POSIX defined error numbers.
+On Windows, C<Errno> also defines and conditionally exports all the
+Winsock error constants defined in your system F<WinError.h> include
+file. These are included in a second export tag, C<:WINSOCK>.
+
C<Errno> also makes C<%!> magic such that each element of C<%!> has a
non-zero value only if C<$!> is set to that value. For example:
use strict;
use warnings;
use warnings::register;
-our $VERSION = '1.33';
+our $VERSION = '1.34';
require Exporter;
require Cwd;
produces something like:
- sub wanted {
- /^\.nfs.*\z/s &&
- (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_)) &&
- int(-M _) > 7 &&
- unlink($_)
- ||
- ($nlink || (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_))) &&
- $dev < 0 &&
- ($File::Find::prune = 1);
- }
+ sub wanted {
+ /^\.nfs.*\z/s &&
+ (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_)) &&
+ int(-M _) > 7 &&
+ unlink($_)
+ ||
+ ($nlink || (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_))) &&
+ $dev < 0 &&
+ ($File::Find::prune = 1);
+ }
Notice the C<_> in the above C<int(-M _)>: the C<_> is a magical
filehandle that caches the information from the preceding
@EXPORT_OK = (@{$EXPORT_TAGS{'glob'}}, 'csh_glob');
-$VERSION = '1.25';
+$VERSION = '1.26';
sub import {
require Exporter;
E<lt>wegner_thomas@yahoo.comE<gt>. The C glob code has the
following copyright:
- Copyright (c) 1989, 1993 The Regents of the University of California.
- All rights reserved.
-
- This code is derived from software contributed to Berkeley by
- Guido van Rossum.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
+Copyright (c) 1989, 1993 The Regents of the University of California.
+All rights reserved.
+
+This code is derived from software contributed to Berkeley by
+Guido van Rossum.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+=over 4
+
+=item 1.
+
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+=item 2.
+
+Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+=item 3.
+
+Neither the name of the University nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+=back
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
=cut
{name=>"SIGRTMIN", macro=>0},
}
+if ($^O eq 'MSWin32') {
+ push @names, qw(
+ WSAEINTR WSAEBADF WSAEACCES WSAEFAULT WSAEINVAL WSAEMFILE WSAEWOULDBLOCK
+ WSAEINPROGRESS WSAEALREADY WSAENOTSOCK WSAEDESTADDRREQ WSAEMSGSIZE
+ WSAEPROTOTYPE WSAENOPROTOOPT WSAEPROTONOSUPPORT WSAESOCKTNOSUPPORT
+ WSAEOPNOTSUPP WSAEPFNOSUPPORT WSAEAFNOSUPPORT WSAEADDRINUSE
+ WSAEADDRNOTAVAIL WSAENETDOWN WSAENETUNREACH WSAENETRESET WSAECONNABORTED
+ WSAECONNRESET WSAENOBUFS WSAEISCONN WSAENOTCONN WSAESHUTDOWN
+ WSAETOOMANYREFS WSAETIMEDOUT WSAECONNREFUSED WSAELOOP WSAENAMETOOLONG
+ WSAEHOSTDOWN WSAEHOSTUNREACH WSAENOTEMPTY WSAEPROCLIM WSAEUSERS
+ WSAEDQUOT WSAESTALE WSAEREMOTE WSAEDISCON WSAENOMORE WSAECANCELLED
+ WSAEINVALIDPROCTABLE WSAEINVALIDPROVIDER WSAEPROVIDERFAILEDINIT
+ WSAEREFUSED
+ );
+}
+
WriteConstants(
PROXYSUBS => {croak_on_error => 1},
NAME => 'POSIX',
/* Save retval since subsequent setlocale() calls may overwrite it. */
retval = savepv(retval);
+ SAVEFREEPV(retval);
/* For locale == 0, we may have switched to NUMERIC_UNDERLYING. Switch
* back */
}
OUTPUT:
RETVAL
- CLEANUP:
- Safefree(RETVAL);
NV
acos(x)
our ($AUTOLOAD, %SIGRT);
-our $VERSION = '1.63';
+our $VERSION = '1.64';
require XSLoader;
utime_h => [],
);
+if ($^O eq 'MSWin32') {
+ $default_export_tags{winsock_h} = [qw(
+ WSAEINTR WSAEBADF WSAEACCES WSAEFAULT WSAEINVAL WSAEMFILE WSAEWOULDBLOCK
+ WSAEINPROGRESS WSAEALREADY WSAENOTSOCK WSAEDESTADDRREQ WSAEMSGSIZE
+ WSAEPROTOTYPE WSAENOPROTOOPT WSAEPROTONOSUPPORT WSAESOCKTNOSUPPORT
+ WSAEOPNOTSUPP WSAEPFNOSUPPORT WSAEAFNOSUPPORT WSAEADDRINUSE
+ WSAEADDRNOTAVAIL WSAENETDOWN WSAENETUNREACH WSAENETRESET WSAECONNABORTED
+ WSAECONNRESET WSAENOBUFS WSAEISCONN WSAENOTCONN WSAESHUTDOWN
+ WSAETOOMANYREFS WSAETIMEDOUT WSAECONNREFUSED WSAELOOP WSAENAMETOOLONG
+ WSAEHOSTDOWN WSAEHOSTUNREACH WSAENOTEMPTY WSAEPROCLIM WSAEUSERS
+ WSAEDQUOT WSAESTALE WSAEREMOTE WSAEDISCON WSAENOMORE WSAECANCELLED
+ WSAEINVALIDPROCTABLE WSAEINVALIDPROVIDER WSAEPROVIDERFAILEDINIT
+ WSAEREFUSED)];
+}
+
my %other_export_tags = (
fenv_h => [qw(
FE_DOWNWARD FE_TONEAREST FE_TOWARDZERO FE_UPWARD fegetround fesetround
=back
+=head1 WINSOCK
+
+(Windows only.)
+
+=over 8
+
+=item Constants
+
+C<WSAEINTR> C<WSAEBADF> C<WSAEACCES> C<WSAEFAULT> C<WSAEINVAL> C<WSAEMFILE> C<WSAEWOULDBLOCK>
+C<WSAEINPROGRESS> C<WSAEALREADY> C<WSAENOTSOCK> C<WSAEDESTADDRREQ> C<WSAEMSGSIZE>
+C<WSAEPROTOTYPE> C<WSAENOPROTOOPT> C<WSAEPROTONOSUPPORT> C<WSAESOCKTNOSUPPORT>
+C<WSAEOPNOTSUPP> C<WSAEPFNOSUPPORT> C<WSAEAFNOSUPPORT> C<WSAEADDRINUSE>
+C<WSAEADDRNOTAVAIL> C<WSAENETDOWN> C<WSAENETUNREACH> C<WSAENETRESET> C<WSAECONNABORTED>
+C<WSAECONNRESET> C<WSAENOBUFS> C<WSAEISCONN> C<WSAENOTCONN> C<WSAESHUTDOWN>
+C<WSAETOOMANYREFS> C<WSAETIMEDOUT> C<WSAECONNREFUSED> C<WSAELOOP> C<WSAENAMETOOLONG>
+C<WSAEHOSTDOWN> C<WSAEHOSTUNREACH> C<WSAENOTEMPTY> C<WSAEPROCLIM> C<WSAEUSERS>
+C<WSAEDQUOT> C<WSAESTALE> C<WSAEREMOTE> C<WSAEDISCON> C<WSAENOMORE> C<WSAECANCELLED>
+C<WSAEINVALIDPROCTABLE> C<WSAEINVALIDPROVIDER> C<WSAEPROVIDERFAILEDINIT>
+C<WSAEREFUSED>
+
+=back
+
M_1_PI M_2_PI M_2_SQRTPI M_E M_LN10 M_LN2 M_LOG10E M_LOG2E M_PI
M_PI_2 M_PI_4 M_SQRT1_2 M_SQRT2 INFINITY NAN
),
+ # this stuff was added for Windows in 5.23
+ ($^O eq 'MSWin32' ? qw(
+ WSAEINTR WSAEBADF WSAEACCES WSAEFAULT WSAEINVAL WSAEMFILE WSAEWOULDBLOCK
+ WSAEINPROGRESS WSAEALREADY WSAENOTSOCK WSAEDESTADDRREQ WSAEMSGSIZE
+ WSAEPROTOTYPE WSAENOPROTOOPT WSAEPROTONOSUPPORT WSAESOCKTNOSUPPORT
+ WSAEOPNOTSUPP WSAEPFNOSUPPORT WSAEAFNOSUPPORT WSAEADDRINUSE
+ WSAEADDRNOTAVAIL WSAENETDOWN WSAENETUNREACH WSAENETRESET WSAECONNABORTED
+ WSAECONNRESET WSAENOBUFS WSAEISCONN WSAENOTCONN WSAESHUTDOWN
+ WSAETOOMANYREFS WSAETIMEDOUT WSAECONNREFUSED WSAELOOP WSAENAMETOOLONG
+ WSAEHOSTDOWN WSAEHOSTUNREACH WSAENOTEMPTY WSAEPROCLIM WSAEUSERS
+ WSAEDQUOT WSAESTALE WSAEREMOTE WSAEDISCON WSAENOMORE WSAECANCELLED
+ WSAEINVALIDPROCTABLE WSAEINVALIDPROVIDER WSAEPROVIDERFAILEDINIT
+ WSAEREFUSED
+ ) : ()),
# adding new functions to EXPORT is a BACKWARD COMPATIBILITY BREAKING CHANGE
# it is OK to add new constants, but new functions may only go in EXPORT_OK
],
foreach my $func (@$para[2 .. $#$para]) {
next unless ref $func eq 'ARRAY';
- die "Expected only C<> blocks in paragraph after item at $TL_node->[$i-2][1]{start_line}"
- unless $func->[0] eq 'C' && !ref $func->[2];
- # Everything is plain text (ie $func->[2] is everything)
+ my $c_node =
+ $func->[0] eq 'C' && !ref $func->[2] ? $func :
+ $func->[0] eq 'L' && ref $func->[2]
+ && $func->[2][0] eq 'C' && !ref $func->[2][2] ? $func->[2] :
+ die "Expected only C<> blocks in paragraph after item at $TL_node->[$i-2][1]{start_line}";
+ # Everything is plain text (ie $c_node->[2] is everything)
# except for C<-I<X>>. So untangle up to one level of nested <>
my $funcname = join '', map {
ref $_ ? $_->[2] : $_
- } @$func[2..$#$func];
+ } @$c_node[2..$#$c_node];
$funcname =~ s!(q.?)//!$1/STRING/!;
push @{$Kinds{$text}}, $funcname;
}
=cut
-our $VERSION = '1.09';
+our $VERSION = '1.10';
require Exporter;
Functions for filehandles, files, or directories:
-X, chdir, chmod, chown, chroot, fcntl, glob, ioctl, link,
lstat, mkdir, open, opendir, readlink, rename, rmdir,
- stat, symlink, sysopen, umask, unlink, utime
+ select, stat, symlink, sysopen, umask, unlink, utime
Keywords related to the control flow of your Perl program:
__FILE__, __LINE__, __PACKAGE__, __SUB__, break, caller,
* and win32/buildext.pl will all generate references to it. The function
* should never be called though, as Win32CORE.pm doesn't use DynaLoader.
*/
+ PERL_UNUSED_ARG(cv);
}
EXTERN_C
use warnings;
use Carp;
-our $VERSION = '0.79';
+our $VERSION = '0.80';
require XSLoader;
void
xsreturn_iv()
PPCODE:
- XSRETURN_IV( (1<<31) + 1 );
+ XSRETURN_IV(I32_MIN + 1);
void
xsreturn_uv()
use ExtUtils::Constant 0.11 'WriteConstants';
use Config;
+my $dtrace_o = $Config{dtraceobject} ? ' dtrace$(OBJ_EXT)' : '';
+
WriteMakefile(
'NAME' => 'XS::APItest',
'VERSION_FROM' => 'APItest.pm', # finds $VERSION
ABSTRACT_FROM => 'APItest.pm', # retrieve abstract from module
AUTHOR => 'Tim Jenness <t.jenness@jach.hawaii.edu>, Christian Soeller <csoelle@mph.auckland.ac.nz>, Hugo van der Sanden <hv@crypt.compulink.co.uk>, Andrew Main (Zefram) <zefram@fysh.org>',
'C' => ['exception.c', 'core.c', 'notcore.c'],
- 'OBJECT' => '$(BASEEXT)$(OBJ_EXT) XSUB-undef-XS_VERSION$(OBJ_EXT) XSUB-redefined-macros$(OBJ_EXT) $(O_FILES)',
+ 'OBJECT' => '$(BASEEXT)$(OBJ_EXT) XSUB-undef-XS_VERSION$(OBJ_EXT) XSUB-redefined-macros$(OBJ_EXT) $(O_FILES)'. $dtrace_o,
realclean => {FILES => 'const-c.inc const-xs.inc'},
($Config{gccversion} && $Config{d_attribute_deprecated} ?
(CCFLAGS => $Config{ccflags} . ' -Wno-deprecated-declarations') : ()),
);
sub MY::install { "install ::\n" };
+
+
+sub MY::postamble
+{
+ package MY;
+ my $post = shift->SUPER::postamble(@_);
+ use Config;
+ return $post unless $Config{dtraceobject};
+
+ # core.o is build using PERL_CORE, so picks up any dtrace probes
+
+ $post .= <<POSTAMBLE;
+
+DTRACE_D = ../../perldtrace.d
+
+dtrace\$(OBJ_EXT): \$(DTRACE_D) core\$(OBJ_EXT)
+ $Config{dtrace} -G -s \$(DTRACE_D) -o dtrace\$(OBJ_EXT) core\$(OBJ_EXT)
+POSTAMBLE
+
+ return $post;
+}
true when called with the code point 0xDF, which is a word character in both
ASCII and EBCDIC (though it represents different characters in each).
-Variant C<isFOO_uni> is like the C<isFOO_L1> variant, but accepts any UV code
+Variant C<isFOO_uvchr> is like the C<isFOO_L1> variant, but accepts any UV code
point as input. If the code point is larger than 255, Unicode rules are used
to determine if it is in the character class. For example,
-C<isWORDCHAR_uni(0x100)> returns TRUE, since 0x100 is LATIN CAPITAL LETTER A
+C<isWORDCHAR_uvchr(0x100)> returns TRUE, since 0x100 is LATIN CAPITAL LETTER A
WITH MACRON in Unicode, and is a word character.
-Variant C<isFOO_utf8> is like C<isFOO_uni>, but the input is a pointer to a
+Variant C<isFOO_utf8> is like C<isFOO_uvchr>, but the input is a pointer to a
(known to be well-formed) UTF-8 encoded string (C<U8*> or C<char*>, and
possibly containing embedded C<NUL> characters). The classification of just
the first (possibly multi-byte) character in the string is tested.
alphabetic character, analogous to C<m/[[:alpha:]]/>.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isALPHA_A>, C<isALPHA_L1>, C<isALPHA_uni>, C<isALPHA_utf8>, C<isALPHA_LC>,
+C<isALPHA_A>, C<isALPHA_L1>, C<isALPHA_uvchr>, C<isALPHA_utf8>, C<isALPHA_LC>,
C<isALPHA_LC_uvchr>, and C<isALPHA_LC_utf8>.
=for apidoc Am|bool|isALPHANUMERIC|char ch
alphabetic character or decimal digit, analogous to C<m/[[:alnum:]]/>.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isALPHANUMERIC_A>, C<isALPHANUMERIC_L1>, C<isALPHANUMERIC_uni>,
+C<isALPHANUMERIC_A>, C<isALPHANUMERIC_L1>, C<isALPHANUMERIC_uvchr>,
C<isALPHANUMERIC_utf8>, C<isALPHANUMERIC_LC>, C<isALPHANUMERIC_LC_uvchr>, and
C<isALPHANUMERIC_LC_utf8>.
C<isASCII_L1()> are identical to C<isASCII()>.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isASCII_uni>, C<isASCII_utf8>, C<isASCII_LC>, C<isASCII_LC_uvchr>, and
+C<isASCII_uvchr>, C<isASCII_utf8>, C<isASCII_LC>, C<isASCII_LC_uvchr>, and
C<isASCII_LC_utf8>. Note, however, that some platforms do not have the C
library routine C<isascii()>. In these cases, the variants whose names contain
C<LC> are the same as the corresponding ones without.
character considered to be a blank, analogous to C<m/[[:blank:]]/>.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isBLANK_A>, C<isBLANK_L1>, C<isBLANK_uni>, C<isBLANK_utf8>, C<isBLANK_LC>,
+C<isBLANK_A>, C<isBLANK_L1>, C<isBLANK_uvchr>, C<isBLANK_utf8>, C<isBLANK_LC>,
C<isBLANK_LC_uvchr>, and C<isBLANK_LC_utf8>. Note, however, that some
platforms do not have the C library routine C<isblank()>. In these cases, the
variants whose names contain C<LC> are the same as the corresponding ones
control character, analogous to C<m/[[:cntrl:]]/>.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isCNTRL_A>, C<isCNTRL_L1>, C<isCNTRL_uni>, C<isCNTRL_utf8>, C<isCNTRL_LC>,
+C<isCNTRL_A>, C<isCNTRL_L1>, C<isCNTRL_uvchr>, C<isCNTRL_utf8>, C<isCNTRL_LC>,
C<isCNTRL_LC_uvchr>, and C<isCNTRL_LC_utf8>
On EBCDIC platforms, you almost always want to use the C<isCNTRL_L1> variant.
Variants C<isDIGIT_A> and C<isDIGIT_L1> are identical to C<isDIGIT>.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isDIGIT_uni>, C<isDIGIT_utf8>, C<isDIGIT_LC>, C<isDIGIT_LC_uvchr>, and
+C<isDIGIT_uvchr>, C<isDIGIT_utf8>, C<isDIGIT_LC>, C<isDIGIT_LC_uvchr>, and
C<isDIGIT_LC_utf8>.
=for apidoc Am|bool|isGRAPH|char ch
graphic character, analogous to C<m/[[:graph:]]/>.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isGRAPH_A>, C<isGRAPH_L1>, C<isGRAPH_uni>, C<isGRAPH_utf8>, C<isGRAPH_LC>,
+C<isGRAPH_A>, C<isGRAPH_L1>, C<isGRAPH_uvchr>, C<isGRAPH_utf8>, C<isGRAPH_LC>,
C<isGRAPH_LC_uvchr>, and C<isGRAPH_LC_utf8>.
=for apidoc Am|bool|isLOWER|char ch
lowercase character, analogous to C<m/[[:lower:]]/>.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isLOWER_A>, C<isLOWER_L1>, C<isLOWER_uni>, C<isLOWER_utf8>, C<isLOWER_LC>,
+C<isLOWER_A>, C<isLOWER_L1>, C<isLOWER_uvchr>, C<isLOWER_utf8>, C<isLOWER_LC>,
C<isLOWER_LC_uvchr>, and C<isLOWER_LC_utf8>.
=for apidoc Am|bool|isOCTAL|char ch
Classes> for details.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isPUNCT_A>, C<isPUNCT_L1>, C<isPUNCT_uni>, C<isPUNCT_utf8>, C<isPUNCT_LC>,
+C<isPUNCT_A>, C<isPUNCT_L1>, C<isPUNCT_uvchr>, C<isPUNCT_utf8>, C<isPUNCT_LC>,
C<isPUNCT_LC_uvchr>, and C<isPUNCT_LC_utf8>.
=for apidoc Am|bool|isSPACE|char ch
(See L</isPSXSPC> for a macro that matches a vertical tab in all releases.)
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isSPACE_A>, C<isSPACE_L1>, C<isSPACE_uni>, C<isSPACE_utf8>, C<isSPACE_LC>,
+C<isSPACE_A>, C<isSPACE_L1>, C<isSPACE_uvchr>, C<isSPACE_utf8>, C<isSPACE_LC>,
C<isSPACE_LC_uvchr>, and C<isSPACE_LC_utf8>.
=for apidoc Am|bool|isPSXSPC|char ch
Otherwise they are identical. Thus this macro is analogous to what
C<m/[[:space:]]/> matches in a regular expression.
See the L<top of this section|/Character classification> for an explanation of
-variants C<isPSXSPC_A>, C<isPSXSPC_L1>, C<isPSXSPC_uni>, C<isPSXSPC_utf8>,
+variants C<isPSXSPC_A>, C<isPSXSPC_L1>, C<isPSXSPC_uvchr>, C<isPSXSPC_utf8>,
C<isPSXSPC_LC>, C<isPSXSPC_LC_uvchr>, and C<isPSXSPC_LC_utf8>.
=for apidoc Am|bool|isUPPER|char ch
uppercase character, analogous to C<m/[[:upper:]]/>.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isUPPER_A>, C<isUPPER_L1>, C<isUPPER_uni>, C<isUPPER_utf8>, C<isUPPER_LC>,
+C<isUPPER_A>, C<isUPPER_L1>, C<isUPPER_uvchr>, C<isUPPER_utf8>, C<isUPPER_LC>,
C<isUPPER_LC_uvchr>, and C<isUPPER_LC_utf8>.
=for apidoc Am|bool|isPRINT|char ch
printable character, analogous to C<m/[[:print:]]/>.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isPRINT_A>, C<isPRINT_L1>, C<isPRINT_uni>, C<isPRINT_utf8>, C<isPRINT_LC>,
+C<isPRINT_A>, C<isPRINT_L1>, C<isPRINT_uvchr>, C<isPRINT_utf8>, C<isPRINT_LC>,
C<isPRINT_LC_uvchr>, and C<isPRINT_LC_utf8>.
=for apidoc Am|bool|isWORDCHAR|char ch
alphanumeric.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isWORDCHAR_A>, C<isWORDCHAR_L1>, C<isWORDCHAR_uni>, and C<isWORDCHAR_utf8>.
+C<isWORDCHAR_A>, C<isWORDCHAR_L1>, C<isWORDCHAR_uvchr>, and C<isWORDCHAR_utf8>.
C<isWORDCHAR_LC>, C<isWORDCHAR_LC_uvchr>, and C<isWORDCHAR_LC_utf8> are also as
described there, but additionally include the platform's native underscore.
and C<isXDIGIT_L1()> are identical to C<isXDIGIT()>.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isXDIGIT_uni>, C<isXDIGIT_utf8>, C<isXDIGIT_LC>, C<isXDIGIT_LC_uvchr>, and
+C<isXDIGIT_uvchr>, C<isXDIGIT_utf8>, C<isXDIGIT_LC>, C<isXDIGIT_LC_uvchr>, and
C<isXDIGIT_LC_utf8>.
=for apidoc Am|bool|isIDFIRST|char ch
returns true only if the input character also matches L</isWORDCHAR>.
See the L<top of this section|/Character classification> for an explanation of
variants
-C<isIDFIRST_A>, C<isIDFIRST_L1>, C<isIDFIRST_uni>, C<isIDFIRST_utf8>,
+C<isIDFIRST_A>, C<isIDFIRST_L1>, C<isIDFIRST_uvchr>, C<isIDFIRST_utf8>,
C<isIDFIRST_LC>, C<isIDFIRST_LC_uvchr>, and C<isIDFIRST_LC_utf8>.
=for apidoc Am|bool|isIDCONT|char ch
difference is that this returns true only if the input character also matches
L</isWORDCHAR>. See the L<top of this section|/Character classification> for
an
-explanation of variants C<isIDCONT_A>, C<isIDCONT_L1>, C<isIDCONT_uni>,
+explanation of variants C<isIDCONT_A>, C<isIDCONT_L1>, C<isIDCONT_uvchr>,
C<isIDCONT_utf8>, C<isIDCONT_LC>, C<isIDCONT_LC_uvchr>, and
C<isIDCONT_LC_utf8>.
ASCII lowercase character, that input character itself is returned. Variant
C<toUPPER_A> is equivalent.
-=for apidoc Am|UV|toUPPER_uni|UV cp|U8* s|STRLEN* lenp
-Converts the Unicode code point C<cp> to its uppercase version, and
-stores that in UTF-8 in C<s>, and its length in bytes in C<lenp>. Note
+=for apidoc Am|UV|toUPPER_uvchr|UV cp|U8* s|STRLEN* lenp
+Converts the code point C<cp> to its uppercase version, and
+stores that in UTF-8 in C<s>, and its length in bytes in C<lenp>. The code
+point is interpreted as native if less than 256; otherwise as Unicode. Note
that the buffer pointed to by C<s> needs to be at least C<UTF8_MAXBYTES_CASE+1>
bytes since the uppercase version may be longer than the original character.
Converts the specified character to foldcase. If the input is anything but an
ASCII uppercase character, that input character itself is returned. Variant
C<toFOLD_A> is equivalent. (There is no equivalent C<to_FOLD_L1> for the full
-Latin1 range, as the full generality of L</toFOLD_uni> is needed there.)
+Latin1 range, as the full generality of L</toFOLD_uvchr> is needed there.)
-=for apidoc Am|UV|toFOLD_uni|UV cp|U8* s|STRLEN* lenp
-Converts the Unicode code point C<cp> to its foldcase version, and
-stores that in UTF-8 in C<s>, and its length in bytes in C<lenp>. Note
+=for apidoc Am|UV|toFOLD_uvchr|UV cp|U8* s|STRLEN* lenp
+Converts the code point C<cp> to its foldcase version, and
+stores that in UTF-8 in C<s>, and its length in bytes in C<lenp>. The code
+point is interpreted as native if less than 256; otherwise as Unicode. Note
that the buffer pointed to by C<s> needs to be at least C<UTF8_MAXBYTES_CASE+1>
bytes since the foldcase version may be longer than the original character.
Converts the specified character to lowercase using the current locale's rules,
if possible; otherwise returns the input character itself.
-=for apidoc Am|UV|toLOWER_uni|UV cp|U8* s|STRLEN* lenp
-Converts the Unicode code point C<cp> to its lowercase version, and
-stores that in UTF-8 in C<s>, and its length in bytes in C<lenp>. Note
+=for apidoc Am|UV|toLOWER_uvchr|UV cp|U8* s|STRLEN* lenp
+Converts the code point C<cp> to its lowercase version, and
+stores that in UTF-8 in C<s>, and its length in bytes in C<lenp>. The code
+point is interpreted as native if less than 256; otherwise as Unicode. Note
that the buffer pointed to by C<s> needs to be at least C<UTF8_MAXBYTES_CASE+1>
bytes since the lowercase version may be longer than the original character.
Converts the specified character to titlecase. If the input is anything but an
ASCII lowercase character, that input character itself is returned. Variant
C<toTITLE_A> is equivalent. (There is no C<toTITLE_L1> for the full Latin1
-range, as the full generality of L</toTITLE_uni> is needed there. Titlecase is
+range, as the full generality of L</toTITLE_uvchr> is needed there. Titlecase is
not a concept used in locale handling, so there is no functionality for that.)
-=for apidoc Am|UV|toTITLE_uni|UV cp|U8* s|STRLEN* lenp
-Converts the Unicode code point C<cp> to its titlecase version, and
-stores that in UTF-8 in C<s>, and its length in bytes in C<lenp>. Note
+=for apidoc Am|UV|toTITLE_uvchr|UV cp|U8* s|STRLEN* lenp
+Converts the code point C<cp> to its titlecase version, and
+stores that in UTF-8 in C<s>, and its length in bytes in C<lenp>. The code
+point is interpreted as native if less than 256; otherwise as Unicode. Note
that the buffer pointed to by C<s> needs to be at least C<UTF8_MAXBYTES_CASE+1>
bytes since the titlecase version may be longer than the original character.
=cut
-XXX Still undocumented isVERTWS_uni and _utf8; it's unclear what their names
+XXX Still undocumented isVERTWS_uvchr and _utf8; it's unclear what their names
really should be. Also toUPPER_LC and toFOLD_LC, which are subject to change.
Note that these macros are repeated in Devel::PPPort, so should also be
#define isPSXSPC_LC(c) isSPACE_LC(c)
/* For internal core Perl use only: the base macros for defining macros like
- * isALPHA_uni. 'c' is the code point to check. 'classnum' is the POSIX class
- * number defined earlier in this file. _generic_uni() is used for POSIX
+ * isALPHA_uvchr. 'c' is the code point to check. 'classnum' is the POSIX class
+ * number defined earlier in this file. _generic_uvchr() is used for POSIX
* classes where there is a macro or function 'above_latin1' that takes the
* single argument 'c' and returns the desired value. These exist for those
* classes which have simple definitions, avoiding the overhead of a hash
- * lookup or inversion list binary search. _generic_swash_uni() can be used
+ * lookup or inversion list binary search. _generic_swash_uvchr() can be used
* for classes where that overhead is faster than a direct lookup.
- * _generic_uni() won't compile if 'c' isn't unsigned, as it won't match the
+ * _generic_uvchr() won't compile if 'c' isn't unsigned, as it won't match the
* 'above_latin1' prototype. _generic_isCC() macro does bounds checking, so
* have duplicate checks here, so could create versions of the macros that
* don't, but experiments show that gcc optimizes them out anyway. */
/* Note that all ignore 'use bytes' */
-#define _generic_uni(classnum, above_latin1, c) ((c) < 256 \
+#define _generic_uvchr(classnum, above_latin1, c) ((c) < 256 \
? _generic_isCC(c, classnum) \
: above_latin1(c))
-#define _generic_swash_uni(classnum, c) ((c) < 256 \
+#define _generic_swash_uvchr(classnum, c) ((c) < 256 \
? _generic_isCC(c, classnum) \
: _is_uni_FOO(classnum, c))
-#define isALPHA_uni(c) _generic_swash_uni(_CC_ALPHA, c)
-#define isALPHANUMERIC_uni(c) _generic_swash_uni(_CC_ALPHANUMERIC, c)
-#define isASCII_uni(c) isASCII(c)
-#define isBLANK_uni(c) _generic_uni(_CC_BLANK, is_HORIZWS_cp_high, c)
-#define isCNTRL_uni(c) isCNTRL_L1(c) /* All controls are in Latin1 */
-#define isDIGIT_uni(c) _generic_swash_uni(_CC_DIGIT, c)
-#define isGRAPH_uni(c) _generic_swash_uni(_CC_GRAPH, c)
-#define isIDCONT_uni(c) _generic_uni(_CC_WORDCHAR, _is_uni_perl_idcont, c)
-#define isIDFIRST_uni(c) _generic_uni(_CC_IDFIRST, _is_uni_perl_idstart, c)
-#define isLOWER_uni(c) _generic_swash_uni(_CC_LOWER, c)
-#define isPRINT_uni(c) _generic_swash_uni(_CC_PRINT, c)
-
-#define isPUNCT_uni(c) _generic_swash_uni(_CC_PUNCT, c)
-#define isSPACE_uni(c) _generic_uni(_CC_SPACE, is_XPERLSPACE_cp_high, c)
-#define isPSXSPC_uni(c) isSPACE_uni(c)
-
-#define isUPPER_uni(c) _generic_swash_uni(_CC_UPPER, c)
-#define isVERTWS_uni(c) _generic_uni(_CC_VERTSPACE, is_VERTWS_cp_high, c)
-#define isWORDCHAR_uni(c) _generic_swash_uni(_CC_WORDCHAR, c)
-#define isXDIGIT_uni(c) _generic_uni(_CC_XDIGIT, is_XDIGIT_cp_high, c)
-
-#define toFOLD_uni(c,s,l) to_uni_fold(c,s,l)
-#define toLOWER_uni(c,s,l) to_uni_lower(c,s,l)
-#define toTITLE_uni(c,s,l) to_uni_title(c,s,l)
-#define toUPPER_uni(c,s,l) to_uni_upper(c,s,l)
+#define isALPHA_uvchr(c) _generic_swash_uvchr(_CC_ALPHA, c)
+#define isALPHANUMERIC_uvchr(c) _generic_swash_uvchr(_CC_ALPHANUMERIC, c)
+#define isASCII_uvchr(c) isASCII(c)
+#define isBLANK_uvchr(c) _generic_uvchr(_CC_BLANK, is_HORIZWS_cp_high, c)
+#define isCNTRL_uvchr(c) isCNTRL_L1(c) /* All controls are in Latin1 */
+#define isDIGIT_uvchr(c) _generic_swash_uvchr(_CC_DIGIT, c)
+#define isGRAPH_uvchr(c) _generic_swash_uvchr(_CC_GRAPH, c)
+#define isIDCONT_uvchr(c) _generic_uvchr(_CC_WORDCHAR, _is_uni_perl_idcont, c)
+#define isIDFIRST_uvchr(c) _generic_uvchr(_CC_IDFIRST, _is_uni_perl_idstart, c)
+#define isLOWER_uvchr(c) _generic_swash_uvchr(_CC_LOWER, c)
+#define isPRINT_uvchr(c) _generic_swash_uvchr(_CC_PRINT, c)
+
+#define isPUNCT_uvchr(c) _generic_swash_uvchr(_CC_PUNCT, c)
+#define isSPACE_uvchr(c) _generic_uvchr(_CC_SPACE, is_XPERLSPACE_cp_high, c)
+#define isPSXSPC_uvchr(c) isSPACE_uvchr(c)
+
+#define isUPPER_uvchr(c) _generic_swash_uvchr(_CC_UPPER, c)
+#define isVERTWS_uvchr(c) _generic_uvchr(_CC_VERTSPACE, is_VERTWS_cp_high, c)
+#define isWORDCHAR_uvchr(c) _generic_swash_uvchr(_CC_WORDCHAR, c)
+#define isXDIGIT_uvchr(c) _generic_uvchr(_CC_XDIGIT, is_XDIGIT_cp_high, c)
+
+#define toFOLD_uvchr(c,s,l) to_uni_fold(c,s,l)
+#define toLOWER_uvchr(c,s,l) to_uni_lower(c,s,l)
+#define toTITLE_uvchr(c,s,l) to_uni_title(c,s,l)
+#define toUPPER_uvchr(c,s,l) to_uni_upper(c,s,l)
+
+/* For backwards compatibility, even though '_uni' should mean official Unicode
+ * code points, in Perl it means native for those below 256 */
+#define isALPHA_uni(c) isALPHA_uvchr(c)
+#define isALPHANUMERIC_uni(c) isALPHANUMERIC_uvchr(c)
+#define isASCII_uni(c) isASCII_uvchr(c)
+#define isBLANK_uni(c) isBLANK_uvchr(c)
+#define isCNTRL_uni(c) isCNTRL_uvchr(c)
+#define isDIGIT_uni(c) isDIGIT_uvchr(c)
+#define isGRAPH_uni(c) isGRAPH_uvchr(c)
+#define isIDCONT_uni(c) isIDCONT_uvchr(c)
+#define isIDFIRST_uni(c) isIDFIRST_uvchr(c)
+#define isLOWER_uni(c) isLOWER_uvchr(c)
+#define isPRINT_uni(c) isPRINT_uvchr(c)
+#define isPUNCT_uni(c) isPUNCT_uvchr(c)
+#define isSPACE_uni(c) isSPACE_uvchr(c)
+#define isPSXSPC_uni(c) isPSXSPC_uvchr(c)
+#define isUPPER_uni(c) isUPPER_uvchr(c)
+#define isVERTWS_uni(c) isVERTWS_uvchr(c)
+#define isWORDCHAR_uni(c) isWORDCHAR_uvchr(c)
+#define isXDIGIT_uni(c) isXDIGIT_uvchr(c)
+#define toFOLD_uni(c,s,l) toFOLD_uvchr(c,s,l)
+#define toLOWER_uni(c,s,l) toLOWER_uvchr(c,s,l)
+#define toTITLE_uni(c,s,l) toTITLE_uvchr(c,s,l)
+#define toUPPER_uni(c,s,l) toUPPER_uvchr(c,s,l)
/* For internal core Perl use only: the base macros for defining macros like
* isALPHA_LC_uvchr. These are like isALPHA_LC, but the input can be any code
- * point, not just 0-255. Like _generic_uni, there are two versions, one for
+ * point, not just 0-255. Like _generic_uvchr, there are two versions, one for
* simple class definitions; the other for more complex. These are like
- * _generic_uni, so see it for more info. */
+ * _generic_uvchr, so see it for more info. */
#define _generic_LC_uvchr(latin1, above_latin1, c) \
(c < 256 ? latin1(c) : above_latin1(c))
#define _generic_LC_swash_uvchr(latin1, classnum, c) \
*/
# define _MEM_WRAP_NEEDS_RUNTIME_CHECK(n,t) \
- ( sizeof(MEM_SIZE) < sizeof(n) \
- || sizeof(t) > ((MEM_SIZE)1 << 8*(sizeof(MEM_SIZE) - sizeof(n))))
+ (8 * sizeof(n) + sizeof(t) > sizeof(MEM_SIZE))
/* This is written in a slightly odd way to avoid various spurious
* compiler warnings. We *want* to write the expression as
# mkdir -p /opt/perl-catamount
# mkdir -p /opt/perl-catamount/include
# mkdir -p /opt/perl-catamount/lib
-# mkdir -p /opt/perl-catamount/lib/perl5/5.23.8
+# mkdir -p /opt/perl-catamount/lib/perl5/5.23.9
# mkdir -p /opt/perl-catamount/bin
# cp *.h /opt/perl-catamount/include
# cp libperl.a /opt/perl-catamount/lib
-# cp -pr lib/* /opt/perl-catamount/lib/perl5/5.23.8
+# cp -pr lib/* /opt/perl-catamount/lib/perl5/5.23.9
# cp miniperl perl run.sh cc.sh /opt/perl-catamount/lib
#
# With the headers and the libperl.a you can embed Perl to your Catamount
/*
Return true if the supplied filename has a newline character
-immediately before the final NUL.
+immediately before the first (hopefully only) NUL.
My original look at this incorrectly used the len from SvPV(), but
that's incorrect, since we allow for a NUL in pv[len-1].
PERL_ARGS_ASSERT_CX_PUSHSUB;
- ENTRY_PROBE(CvNAMED(cv)
- ? HEK_KEY(CvNAME_HEK(cv))
- : GvENAME(CvGV(cv)),
- CopFILE((const COP *)CvSTART(cv)),
- CopLINE((const COP *)CvSTART(cv)),
- CopSTASHPV((const COP *)CvSTART(cv)));
+ PERL_DTRACE_PROBE_ENTRY(cv);
cx->blk_sub.cv = cv;
cx->blk_sub.olddepth = CvDEPTH(cv);
cx->blk_sub.prevcomppad = PL_comppad;
PERL_ARGS_ASSERT_CX_POPSUB;
assert(CxTYPE(cx) == CXt_SUB);
- RETURN_PROBE(CvNAMED(cx->blk_sub.cv)
- ? HEK_KEY(CvNAME_HEK(cx->blk_sub.cv))
- : GvENAME(CvGV(cx->blk_sub.cv)),
- CopFILE((COP*)CvSTART((const CV*)cx->blk_sub.cv)),
- CopLINE((COP*)CvSTART((const CV*)cx->blk_sub.cv)),
- CopSTASHPV((COP*)CvSTART((const CV*)cx->blk_sub.cv)));
+ PERL_DTRACE_PROBE_RETURN(cx->blk_sub.cv);
if (CxHASARGS(cx))
cx_popsub_args(cx);
unless ($has_pod)
{
- warn "no documentation in $mod\n" unless $opts{silent};
+ print "no documentation in $mod\n" if $opts{verbose};
next;
}
/ExtUtils/Miniperl.pm
/ExtUtils/Mkbootstrap.pm
/ExtUtils/Mksymlists.pm
-/ExtUtils/Myconst2perl.pm
/ExtUtils/Packlist.pm
/ExtUtils/ParseXS.pm
/ExtUtils/ParseXS.pod
/experimental.pm
/fields.pm
/if.pm
+/inc/
/lib.pm
/mro.pm
/ok.pm
our %bits;
-our $VERSION = "5.023008";
+our $VERSION = "5.023009";
$bits{$_}{3} = 'OPpENTERSUB_AMPER' for qw(entersub rv2cv);
$bits{$_}{6} = 'OPpENTERSUB_DB' for qw(entersub rv2cv);
use strict;
# This is not a dual-life module, so no need for development version numbers
-$VERSION = '1.32';
+$VERSION = '1.33';
@ISA = qw(Exporter);
@EXPORT = qw(&xsinit &ldopts
each static extension found in C<$Config{static_ext}>.
The code is written to the default file name F<perlxsi.c>.
- perl -MExtUtils::Embed -e xsinit -- -o xsinit.c -std DBI DBD::Oracle
+ perl -MExtUtils::Embed -e xsinit -- -o xsinit.c \
+ -std DBI DBD::Oracle
Here, code is written for all the currently linked extensions along with code
for C<DBI> and C<DBD::Oracle>.
perl -MExtUtils::Embed -e ldopts -- -std Socket
-This will do the same as the above example, along with printing additional arguments for linking with the C<Socket> extension.
+This will do the same as the above example, along with printing additional
+arguments for linking with the C<Socket> extension.
- perl -MExtUtils::Embed -e ldopts -- -std Msql -- -L/usr/msql/lib -lmsql
+ perl -MExtUtils::Embed -e ldopts -- -std Msql -- \
+ -L/usr/msql/lib -lmsql
Any arguments after the second '--' token are additional linker
arguments that will be examined for potential conflict. If there is no
package bytes;
-our $VERSION = '1.04';
+our $VERSION = '1.05';
$bytes::hint_bits = 0x00000008;
=head1 NAME
-bytes - Perl pragma to force byte semantics rather than character semantics
+bytes - Perl pragma to expose the individual bytes of characters
=head1 NOTICE
-This pragma reflects early attempts to incorporate Unicode into perl and
-has since been superseded. It breaks encapsulation (i.e. it exposes the
-innards of how the perl executable currently happens to store a string),
-and use of this module for anything other than debugging purposes is
-strongly discouraged. If you feel that the functions here within might be
-useful for your application, this possibly indicates a mismatch between
-your mental model of Perl Unicode and the current reality. In that case,
-you may wish to read some of the perl Unicode documentation:
-L<perluniintro>, L<perlunitut>, L<perlunifaq> and L<perlunicode>.
+Because the bytes pragma breaks encapsulation (i.e. it exposes the innards of
+how the perl executable currently happens to store a string), the byte values
+that result are in an unspecified encoding.
+
+B<Use of this module for anything other than debugging purposes is
+strongly discouraged.> If you feel that the functions here within
+might be useful for your application, this possibly indicates a
+mismatch between your mental model of Perl Unicode and the current
+reality. In that case, you may wish to read some of the perl Unicode
+documentation: L<perluniintro>, L<perlunitut>, L<perlunifaq> and
+L<perlunicode>.
=head1 SYNOPSIS
=head1 DESCRIPTION
-The C<use bytes> pragma disables character semantics for the rest of the
-lexical scope in which it appears. C<no bytes> can be used to reverse
-the effect of C<use bytes> within the current lexical scope.
+Perl's characters are stored internally as sequences of one or more bytes.
+This pragma allows for the examination of the individual bytes that together
+comprise a character.
+
+Originally the pragma was designed for the loftier goal of helping incorporate
+Unicode into Perl, but the approach that used it was found to be defective,
+and the one remaining legitimate use is for debugging when you need to
+non-destructively examine characters' individual bytes. Just insert this
+pragma temporarily, and remove it after the debugging is finished.
+
+The original usage can be accomplished by explicit (rather than this pragma's
+implict) encoding using the L<Encode> module:
+
+ use Encode qw/encode/;
+
+ my $utf8_byte_string = encode "UTF8", $string;
+ my $latin1_byte_string = encode "Latin1", $string;
-Perl normally assumes character semantics in the presence of character
-data (i.e. data that has come from a source that has been marked as
-being of a particular character encoding). When C<use bytes> is in
-effect, the encoding is temporarily ignored, and each string is treated
-as a series of bytes.
+Or, if performance is needed and you are only interested in the UTF-8
+representation:
+
+ use utf8;
+
+ utf8::encode(my $utf8_byte_string = $string);
+
+C<no bytes> can be used to reverse the effect of C<use bytes> within the
+current lexical scope.
As an example, when Perl sees C<$x = chr(400)>, it encodes the character
-in UTF-8 and stores it in $x. Then it is marked as character data, so,
+in UTF-8 and stores it in C<$x>. Then it is marked as character data, so,
for instance, C<length $x> returns C<1>. However, in the scope of the
-C<bytes> pragma, $x is treated as a series of bytes - the bytes that make
+C<bytes> pragma, C<$x> is treated as a series of bytes - the bytes that make
up the UTF8 encoding - and C<length $x> returns C<2>:
- $x = chr(400);
- print "Length is ", length $x, "\n"; # "Length is 1"
- printf "Contents are %vd\n", $x; # "Contents are 400"
- {
- use bytes; # or "require bytes; bytes::length()"
- print "Length is ", length $x, "\n"; # "Length is 2"
- printf "Contents are %vd\n", $x; # "Contents are 198.144"
- }
+ $x = chr(400);
+ print "Length is ", length $x, "\n"; # "Length is 1"
+ printf "Contents are %vd\n", $x; # "Contents are 400"
+ {
+ use bytes; # or "require bytes; bytes::length()"
+ print "Length is ", length $x, "\n"; # "Length is 2"
+ printf "Contents are %vd\n", $x; # "Contents are 198.144 (on
+ # ASCII platforms)"
+ }
+
+C<chr()>, C<ord()>, C<substr()>, C<index()> and C<rindex()> behave similarly.
+
+For more on the implications, see L<perluniintro> and L<perlunicode>.
-chr(), ord(), substr(), index() and rindex() behave similarly.
+C<bytes::length()> is admittedly handy if you need to know the
+B<byte length> of a Perl scalar. But a more modern way is:
-For more on the implications and differences between character
-semantics and byte semantics, see L<perluniintro> and L<perlunicode>.
+ use Encode 'encode';
+ length(encode('UTF-8', $scalar))
=head1 LIMITATIONS
-bytes::substr() does not work as an lvalue().
+C<bytes::substr()> does not work as an I<lvalue()>.
=head1 SEE ALSO
-L<perluniintro>, L<perlunicode>, L<utf8>
+L<perluniintro>, L<perlunicode>, L<utf8>, L<Encode>
=cut
os390 => qr/ ^ italian /ix,
);
+# cygwin isn't returning proper radix length in this locale, but supposedly to
+# be fixed in later versions.
+if ($^O eq 'cygwin' && version->new(($Config{osvers} =~ /^(\d+(?:\.\d+)+)/)[0]) le v2.4.1) {
+ $known_bad_locales{'cygwin'} = qr/ ^ ps_AF /ix;
+}
+
use Dumpvalue;
my $dumper = Dumpvalue->new(
report_result($Locale, ++$locales_test_number, $ok16);
$test_names{$locales_test_number} = 'Verify that a sprintf of a number with a UTF-8 radix yields UTF-8';
+ $problematical_tests{$locales_test_number} = 1;
report_result($Locale, ++$locales_test_number, $ok17);
$test_names{$locales_test_number} = 'Verify that a sprintf of a number outside locale scope uses a dot radix';
report_result($Locale, ++$locales_test_number, $ok18);
$test_names{$locales_test_number} = 'Verify that a sprintf of a number back within locale scope uses locale radix';
+ $problematical_tests{$locales_test_number} = 1;
report_result($Locale, ++$locales_test_number, $ok19);
$test_names{$locales_test_number} = 'Verify that strftime doesn\'t return "%p" in locales where %p is empty';
# Debugger for Perl 5.00x; perl5db.pl patch level:
use vars qw($VERSION $header);
-$VERSION = '1.49_02';
+$VERSION = '1.49_03';
$header = "perl5db.pl version $VERSION";
$console = "con";
}
+=item * AmigaOS - use C<CONSOLE:>.
+
+=cut
+
+ elsif ( $^O eq 'amigaos' ) {
+ $console = "CONSOLE:";
+ }
+
=item * VMS - use C<sys$command>.
=cut
- else {
+ elsif ($^O eq 'VMS') {
+ $console = 'sys$command';
+ }
+
+# Keep this last.
- # everything else is ...
- $console = "sys\$command";
+ else {
+ _db_warn("Can't figure out your console, using stdin");
+ undef $console;
}
=pod
package strict;
-$strict::VERSION = "1.10";
-
-# Verify that we're called correctly so that strictures will work.
-unless ( __FILE__ =~ /(^|[\/\\])\Q${\__PACKAGE__}\E\.pmc?$/ ) {
- # Can't use Carp, since Carp uses us!
- my (undef, $f, $l) = caller;
- die("Incorrect use of pragma '${\__PACKAGE__}' at $f line $l.\n");
-}
+$strict::VERSION = "1.11";
my ( %bitmask, %explicit_bitmask );
BEGIN {
+ # Verify that we're called correctly so that strictures will work.
+ # Can't use Carp, since Carp uses us!
+ # see also warnings.pm.
+ die sprintf "Incorrect use of pragma '%s' at %s line %d.\n", __PACKAGE__, +(caller)[1,2]
+ if __FILE__ !~ ( '(?x) \b '.__PACKAGE__.' \.pmc? \z' )
+ && __FILE__ =~ ( '(?x) \b (?i:'.__PACKAGE__.') \.pmc? \z' );
+
%bitmask = (
refs => 0x00000002,
subs => 0x00000200,
# points not given in the input. If not present, the default from the
# normal property is used
#
- # [4] if present must be the string 'ONLY_EARLY'. Normally, when
- # compiling Unicode versions that don't invoke the early handling, the
- # name in [1] is added as an alias to the property name used for these.
- # This parameter says to not do this.
+ # [-1] If there is an extra final element that is the string 'ONLY_EARLY'.
+ # it means to not add the name in [1] as an alias to the property name
+ # used for these. Normally, when compiling Unicode versions that don't
+ # invoke the early handling, the name is added as a synonym.
#
# Not all files can be handled in the above way, and so the code ref
# alternative is available. It can do whatever it needs to. The other
# makes for easier testing later on.
main::set_access('early', \%early, 'c');
+ my %only_early;
+ main::set_access('only_early', \%only_early, 'c');
+
my %required_even_in_debug_skip;
# debug_skip is used to speed up compilation during debugging by skipping
# processing files that are not needed for the task at hand. However,
my $progress;
my $function_instead_of_file = 0;
- if ($early{$addr}->@* > 4 && $early{$addr}[4] ne 'ONLY_EARLY') {
- Carp::my_carp_bug("If present, element [4] in 'Early => [ ... ]'"
- . " must be the string 'ONLY_EARLY'");
+ if ($early{$addr}->@* && $early{$addr}[-1] eq 'ONLY_EARLY') {
+ $only_early{$addr} = 1;
+ pop $early{$addr}->@*;
}
# If we are compiling a Unicode release earlier than the file became
unshift $early{$addr}->@*, 1;
# See the definition of %early for what the array elements mean.
+ # Note that we have just unshifted onto the array, so the numbers
+ # below are +1 of those in the %early description.
# If we have a property this defines, create a table and default
# map for it now (at essentially compile time), so that it will be
# available for the whole of run time. (We will want to add this
# If not specified by the constructor, use the default mapping
# for the regular property for this substitute one.
- if ($early{$addr}[3]) {
- $prop_object->set_default_map($early{$addr}[3]);
+ if ($early{$addr}[4]) {
+ $prop_object->set_default_map($early{$addr}[4]);
}
elsif ( defined $property{$addr}
&& defined $default_mapping{$property{$addr}})
push $each_line_handler{$addr}->@*, \&_exclude_unassigned;
if ( $v_version lt v2.0 # Hanguls in this release ...
- && defined $early{$addr}[4]) # ... need special treatment
+ && defined $early{$addr}[3]) # ... need special treatment
{
push $eof_handler{$addr}->@*, \&_fixup_obsolete_hanguls;
}
# official property, we still have to allow the publicly
# inaccessible early name so that the core code which uses it
# will work regardless.
- if (! $early{$addr}[0] && $early{$addr}->@* > 2) {
+ if ( ! $only_early{$addr}
+ && ! $early{$addr}[0]
+ && $early{$addr}->@* > 2)
+ {
my $early_property_name = $early{$addr}[2];
- if ( $property{$addr} ne $early_property_name
- && $early{$addr}->@* < 5)
- {
+ if ($property{$addr} ne $early_property_name) {
main::property_ref($property{$addr})
->add_alias($early_property_name);
}
sub set_default_map {
# Define what code points that are missing from the input files should
- # map to
+ # map to. The optional second parameter 'full_name' indicates to
+ # force using the full name of the map instead of its standard name.
my $self = shift;
my $map = shift;
+ my $use_full_name = shift // 0;
Carp::carp_extra_args(\@_) if main::DEBUG && @_;
+ if ($use_full_name && $use_full_name ne 'full_name') {
+ Carp::my_carp_bug("Second parameter to set_default_map() if"
+ . " present, must be 'full_name'");
+ }
+
my $addr = do { no overloading; pack 'J', $self; };
# Convert the input to the standard equivalent, if any (won't have any
# for $STRING properties)
- my $standard = $self->_find_table_from_alias->{$map};
- $map = $standard->name if defined $standard;
+ my $standard = $self->property->table($map);
+ if (defined $standard) {
+ $map = ($use_full_name)
+ ? $standard->full_name
+ : $standard->name;
+ }
# Warn if there already is a non-equivalent default map for this
# property. Note that a default map can be a ref, which means that
END
}
- if (-e 'LineBreak.txt') {
- push @return, split /\n/, <<'END';
+ if (-e 'LineBreak.txt' || -e 'LBsubst.txt') {
+ my @lb = split /\n/, <<'END';
lb ; AI ; Ambiguous
lb ; AL ; Alphabetic
lb ; B2 ; Break_Both
lb ; XX ; Unknown
lb ; ZW ; ZWSpace
END
+ # If this Unicode version predates the lb property, we use our
+ # substitute one
+ if (-e 'LBsubst.txt') {
+ $_ = s/^lb/_Perl_LB/r for @lb;
+ }
+ push @return, @lb;
}
if (-e 'DNormalizationProps.txt') {
}
}
+sub filter_substitute_lb {
+ # Used on Unicodes that predate the LB property, where there is a
+ # substitute file. This just does the regular ea_lb handling for such
+ # files, and then substitutes the long property value name for the short
+ # one that comes with the file. (The other break files have the long
+ # names in them, so this is the odd one out.) The reason for doing this
+ # kludge is that regen/mk_invlists.pl is expecting the long name. This
+ # also fixes the typo 'Inseperable' that leads to problems.
+
+ filter_early_ea_lb;
+ return unless $_;
+
+ my @fields = split /\s*;\s*/;
+ $fields[1] = property_ref('_Perl_LB')->table($fields[1])->full_name;
+ $fields[1] = 'Inseparable' if lc $fields[1] eq 'inseperable';
+ $_ = join '; ', @fields;
+}
+
sub filter_old_style_arabic_shaping {
# Early versions used a different term for the later one.
0x2060 .. 0x206F,
0xFE00 .. 0xFE0F,
0xFFF0 .. 0xFFFB,
- 0xE0000 .. 0xE0FFF,
]);
+ $temp->add_range(0xE0000, 0xE0FFF) if $v_version ge v2.0;
$quotemeta += $temp;
}
calculate_DI();
# SA CM Only Mn or Mc
# SA AL Any except Mn and Mc
# CJ NS Any
+ #
+ # All property values are also written out in their long form, as
+ # regen/mk_invlist.pl expects that. This also fixes occurrences of the
+ # typo in early Unicode versions: 'inseperable'.
my $perl_lb = property_ref('_Perl_LB');
if (! defined $perl_lb) {
$perl_lb = Property->new('_Perl_LB',
Directory => $map_directory,
Type => $STRING);
my $lb = property_ref('Line_Break');
- $perl_lb->initialize($lb);
+
+ # Populate from $lb, but use full name and fix typo.
+ foreach my $range ($lb->ranges) {
+ my $full_name = $lb->table($range->value)->full_name;
+ $full_name = 'Inseparable'
+ if standardize($full_name) eq 'inseperable';
+ $perl_lb->add_map($range->start, $range->end, $full_name);
+ }
}
- $perl_lb->set_default_map('AL');
- # It's a little iffy relying on Unicode to not change which property value
- # synonym they use, but if they do, tests should start failing and we can
- # fix this up
+ $perl_lb->set_default_map('Alphabetic', 'full_name'); # XX -> AL
+
for my $range ($perl_lb->ranges) {
my $value = standardize($range->value);
if ( $value eq standardize('Unknown')
- || $value eq standardize('XX')
- || $value eq standardize('AI')
- || $value eq standardize('SG'))
+ || $value eq standardize('Ambiguous')
+ || $value eq standardize('Surrogate'))
{
- $perl_lb->add_map($range->start, $range->end, 'AL',
+ $perl_lb->add_map($range->start, $range->end, 'Alphabetic',
Replace => $UNCONDITIONALLY);
}
- elsif ($value eq standardize('CJ')) {
- $perl_lb->add_map($range->start, $range->end, 'NS',
+ elsif ($value eq standardize('Conditional_Japanese_Starter')) {
+ $perl_lb->add_map($range->start, $range->end, 'Nonstarter',
Replace => $UNCONDITIONALLY);
}
- elsif ($value eq standardize('SA')) {
+ elsif ($value eq standardize('Complex_Context')) {
for my $i ($range->start .. $range->end) {
my $gc_val = $gc->value_of($i);
if ($gc_val eq 'Mn' || $gc_val eq 'Mc') {
- $perl_lb->add_map($i, $i, 'CM',
+ $perl_lb->add_map($i, $i, 'Combining_Mark',
Replace => $UNCONDITIONALLY);
}
else {
- $perl_lb->add_map($i, $i, 'AL',
+ $perl_lb->add_map($i, $i, 'Alphabetic',
Replace => $UNCONDITIONALLY);
}
}
# conflating is possible. In our example, we
# don't want 2/3 matching 7/10, if there is
# a 7/10 code point.
+
+ # First, integers are not in the rationals
+ # table. Don't generate an error if this
+ # rounds to an integer using the given
+ # precision.
+ my $round = sprintf "%.0f", $table_name;
+ next PLACE if abs($table_name - $round)
+ < $MAX_FLOATING_SLOP;
+
+ # Here, isn't close enough to an integer to be
+ # confusable with one. Now, see it it's
+ # "close" to a known rational
for my $existing
(keys %nv_floating_to_rational)
{
Has_Missings_Defaults => $NOT_IGNORED,
Property => 'Line_Break',
# Early versions had problematic syntax
- Each_Line_Handler => (($v_version lt v3.1.0)
- ? \&filter_early_ea_lb
- : undef),
- Early => [ "LBsubst.txt", '_Perl_LB', 'AL',
- 'AL', # default
+ Each_Line_Handler => ($v_version ge v3.1.0)
+ ? undef
+ : ($v_version lt v3.0.0)
+ ? \&filter_substitute_lb
+ : \&filter_early_ea_lb,
+ # Must use long names for property values see comments at
+ # sub filter_substitute_lb
+ Early => [ "LBsubst.txt", '_Perl_LB', 'Alphabetic',
+ 'Alphabetic', # default to this because XX ->
+ # AL
# Don't use _Perl_LB as a synonym for
# Line_Break in later perls, as it is tailored
package warnings;
-our $VERSION = "1.35";
+our $VERSION = "1.36";
# Verify that we're called correctly so that warnings will work.
+# Can't use Carp, since Carp uses us!
+# String regexps because constant folding = smaller optree = less memory vs regexp literal
# see also strict.pm.
-unless ( __FILE__ =~ /(^|[\/\\])\Q${\__PACKAGE__}\E\.pmc?$/ ) {
- my (undef, $f, $l) = caller;
- die("Incorrect use of pragma '${\__PACKAGE__}' at $f line $l.\n");
-}
+die sprintf "Incorrect use of pragma '%s' at %s line %d.\n", __PACKAGE__, +(caller)[1,2]
+ if __FILE__ !~ ( '(?x) \b '.__PACKAGE__.' \.pmc? \z' )
+ && __FILE__ =~ ( '(?x) \b (?i:'.__PACKAGE__.') \.pmc? \z' );
our %Offsets = (
# Warnings Categories added in Perl 5.008
* in such scope than if not. However, various libc functions called by Perl
* are affected by the LC_NUMERIC category, so there are macros in perl.h that
* are used to toggle between the current locale and the C locale depending on
- * the desired behavior of those functions at the moment.
+ * the desired behavior of those functions at the moment. And, LC_MESSAGES is
+ * switched to the C locale for outputting the message unless within the scope
+ * of 'use locale'.
*/
#include "EXTERN.h"
? SvPVX(PL_numeric_radix_sv)
: "NULL",
(PL_numeric_radix_sv)
- ? SvUTF8(PL_numeric_radix_sv)
+ ? cBOOL(SvUTF8(PL_numeric_radix_sv))
: 0));
# endif /* HAS_LOCALECONV */
}
save_newnum = stdize_locale(savepv(newnum));
+
+ PL_numeric_standard = isNAME_C_OR_POSIX(save_newnum);
+ PL_numeric_local = TRUE;
+
if (! PL_numeric_name || strNE(PL_numeric_name, save_newnum)) {
Safefree(PL_numeric_name);
PL_numeric_name = save_newnum;
}
-
- PL_numeric_standard = isNAME_C_OR_POSIX(save_newnum);
- PL_numeric_local = TRUE;
+ else {
+ Safefree(save_newnum);
+ }
/* Keep LC_NUMERIC in the C locale. This is for XS modules, so they don't
* have to worry about the radix being a non-dot. (Core operations that
);
}
-unless ($define{'PERL_COPY_ON_WRITE'}) {
+if (!$define{'PERL_COPY_ON_WRITE'} || $define{'PERL_NO_COW'}) {
++$skip{Perl_sv_setsv_cow};
}
);
}
+unless ($define{'USE_DTRACE'}) {
+ ++$skip{$_} foreach qw(
+ Perl_dtrace_probe_call
+ Perl_dtrace_probe_load
+ Perl_dtrace_probe_op
+ Perl_dtrace_probe_phase
+ );
+}
+
if ($define{'NO_MATHOMS'}) {
# win32 builds happen in the win32/ subdirectory, but vms builds happen
# at the top level, so we need to look in two candidate locations for
* HAS_DLADDR
* HAS_FEGETROUND
* HAS_FPCLASSIFY
+ * HAS_FREELOCALE
* HAS_GMTIME64
* HAS_ISFINITEL
* HAS_ISINFL
* HAS_J0
* HAS_LOCALTIME64
* HAS_MKTIME64
+ * HAS_NEWLOCALE
* HAS_PRCTL
* HAS_PSEUDOFORK
* HAS_TIMEGM
+ * HAS_USELOCALE
* I16SIZE
* I64SIZE
* I8SIZE
# include "perldtrace.h"
-# if defined(STAP_PROBE_ADDR) && !defined(DEBUGGING)
+# define PERL_DTRACE_PROBE_ENTRY(cv) \
+ if (PERL_SUB_ENTRY_ENABLED()) \
+ Perl_dtrace_probe_call(aTHX_ cv, TRUE);
-/* SystemTap 1.2 uses a construct that chokes on passing a char array
- * as a char *, in this case hek_key in struct hek. Workaround it
- * with a temporary.
- */
-
-# define ENTRY_PROBE(func, file, line, stash) \
- if (PERL_SUB_ENTRY_ENABLED()) { \
- const char *tmp_func = func; \
- PERL_SUB_ENTRY(tmp_func, file, line, stash); \
- }
-
-# define RETURN_PROBE(func, file, line, stash) \
- if (PERL_SUB_RETURN_ENABLED()) { \
- const char *tmp_func = func; \
- PERL_SUB_RETURN(tmp_func, file, line, stash); \
- }
-
-# define LOADING_FILE_PROBE(name) \
- if (PERL_LOADING_FILE_ENABLED()) { \
- const char *tmp_name = name; \
- PERL_LOADING_FILE(tmp_name); \
- }
-
-# define LOADED_FILE_PROBE(name) \
- if (PERL_LOADED_FILE_ENABLED()) { \
- const char *tmp_name = name; \
- PERL_LOADED_FILE(tmp_name); \
- }
-
-# else
-
-# define ENTRY_PROBE(func, file, line, stash) \
- if (PERL_SUB_ENTRY_ENABLED()) { \
- PERL_SUB_ENTRY(func, file, line, stash); \
- }
-
-# define RETURN_PROBE(func, file, line, stash) \
- if (PERL_SUB_RETURN_ENABLED()) { \
- PERL_SUB_RETURN(func, file, line, stash); \
- }
-
-# define LOADING_FILE_PROBE(name) \
- if (PERL_LOADING_FILE_ENABLED()) { \
- PERL_LOADING_FILE(name); \
- }
+# define PERL_DTRACE_PROBE_RETURN(cv) \
+ if (PERL_SUB_ENTRY_ENABLED()) \
+ Perl_dtrace_probe_call(aTHX_ cv, FALSE);
-# define LOADED_FILE_PROBE(name) \
- if (PERL_LOADED_FILE_ENABLED()) { \
- PERL_LOADED_FILE(name); \
- }
+# define PERL_DTRACE_PROBE_FILE_LOADING(name) \
+ if (PERL_SUB_ENTRY_ENABLED()) \
+ Perl_dtrace_probe_load(aTHX_ name, TRUE);
-# endif
+# define PERL_DTRACE_PROBE_FILE_LOADED(name) \
+ if (PERL_SUB_ENTRY_ENABLED()) \
+ Perl_dtrace_probe_load(aTHX_ name, FALSE);
-# define OP_ENTRY_PROBE(name) \
- if (PERL_OP_ENTRY_ENABLED()) { \
- PERL_OP_ENTRY(name); \
- }
+# define PERL_DTRACE_PROBE_OP(op) \
+ if (PERL_OP_ENTRY_ENABLED()) \
+ Perl_dtrace_probe_op(aTHX_ op);
-# define PHASE_CHANGE_PROBE(new_phase, old_phase) \
- if (PERL_PHASE_CHANGE_ENABLED()) { \
- PERL_PHASE_CHANGE(new_phase, old_phase); \
- }
+# define PERL_DTRACE_PROBE_PHASE(phase) \
+ if (PERL_OP_ENTRY_ENABLED()) \
+ Perl_dtrace_probe_phase(aTHX_ phase);
#else
/* NOPs */
-# define ENTRY_PROBE(func, file, line, stash)
-# define RETURN_PROBE(func, file, line, stash)
-# define PHASE_CHANGE_PROBE(new_phase, old_phase)
-# define OP_ENTRY_PROBE(name)
-# define LOADING_FILE_PROBE(name)
-# define LOADED_FILE_PROBE(name)
+# define PERL_DTRACE_PROBE_ENTRY(cv)
+# define PERL_DTRACE_PROBE_RETURN(cv)
+# define PERL_DTRACE_PROBE_FILE_LOADING(cv)
+# define PERL_DTRACE_PROBE_FILE_LOADED(cv)
+# define PERL_DTRACE_PROBE_OP(op)
+# define PERL_DTRACE_PROBE_PHASE(phase)
#endif
/* Note that you'd normally expect targs to be
* contiguous in my($a,$b,$c), but that's not the case
* when external modules start doing things, e.g.
- i* Function::Parameters */
+ * Function::Parameters */
if (p->op_targ != base + count)
break;
assert(p->op_targ == base + count);
* SAVEt_CLEARPADRANGE in pp_padrange.
* (The sizeof() stuff will be constant-folded, and is
* intended to avoid getting "comparison is always false"
- * compiler warnings)
+ * compiler warnings. See the comments above
+ * MEM_WRAP_CHECK for more explanation on why we do this
+ * in a weird way to avoid compiler warnings.)
*/
if ( intro
&& (8*sizeof(base) >
8*sizeof(UV)-OPpPADRANGE_COUNTSHIFT-SAVE_TIGHT_SHIFT
- ? base : 0) >
+ ? base
+ : (UV_MAX >> (OPpPADRANGE_COUNTSHIFT+SAVE_TIGHT_SHIFT))
+ ) >
(UV_MAX >> (OPpPADRANGE_COUNTSHIFT+SAVE_TIGHT_SHIFT))
)
break;
* optimise away would have exactly the same effect as the
* padrange.
* In particular in void context, we can only optimise to
- * a padrange if see see the complete sequence
+ * a padrange if we see the complete sequence
* pushmark, pad*v, ...., list
- * which has the net effect of of leaving the markstack as it
- * was. Not pushing on to the stack (whereas padsv does touch
+ * which has the net effect of leaving the markstack as it
+ * was. Not pushing onto the stack (whereas padsv does touch
* the stack) makes no difference in void context.
*/
assert(followop);
|| o->op_next->op_type == OP_NULL))
o->op_next = o->op_next->op_next;
- /* if we're an OR and our next is a AND in void context, we'll
- follow it's op_other on short circuit, same for reverse.
+ /* If we're an OR and our next is an AND in void context, we'll
+ follow its op_other on short circuit, same for reverse.
We can't do this with OP_DOR since if it's true, its return
value is the underlying value which must be evaluated
- by the next op */
+ by the next op. */
if (o->op_next &&
(
(IS_AND_OP(o) && IS_OR_OP(o->op_next))
t/$(PERL_DLL): $(PERL_DLL)
$(LNS) $(PERL_DLL) t/$(PERL_DLL)
-$(PERL_DLL): $(obj) perl5.def perl$(OBJ_EXT) perlmain$(OBJ_EXT) $(DYNALOADER)
- $(LD) $(LD_OPT) $(LDDLFLAGS) $(PERL_DLL_LD_OPT) -o $@ perl$(OBJ_EXT) $(obj) perlmain$(OBJ_EXT) $(DYNALOADER) $(libs) perl5.def || ( rm $(PERL_DLL) && sh -c false )
+$(PERL_DLL): $(perllib_objs) perl5.def perl$(OBJ_EXT) perlmain$(OBJ_EXT) $(DYNALOADER)
+ $(LD) $(LD_OPT) $(LDDLFLAGS) $(PERL_DLL_LD_OPT) -o $@ perl$(OBJ_EXT) $(perllib_objs) perlmain$(OBJ_EXT) $(DYNALOADER) $(libs) perl5.def || ( rm $(PERL_DLL) && sh -c false )
perl5.olddef: perl.linkexp
echo "LIBRARY '$(PERL_DLL_BASE)' INITINSTANCE TERMINSTANCE" > $@
miniperl.exe: miniperl
-miniperl: $(obj) perl$(OBJ_EXT) miniperlmain$(OBJ_EXT) opmini$(OBJ_EXT)
- $(CC) $(CLDFLAGS) -o miniperl miniperlmain$(OBJ_EXT) perl$(OBJ_EXT) `echo $(obj)|sed -e 's/\bop\./opmini./g'` $(libs) -Zmap -Zlinker /map/PM:VIO
+miniperl: $(perllib_objs) perl$(OBJ_EXT) miniperlmain$(OBJ_EXT) opmini$(OBJ_EXT)
+ $(CC) $(CLDFLAGS) -o miniperl miniperlmain$(OBJ_EXT) perl$(OBJ_EXT) `echo $(perllib_objs)|sed -e 's/\bop\./opmini./g'` $(libs) -Zmap -Zlinker /map/PM:VIO
@./miniperl -w -Ilib -MExporter -e '<?>' || $(MAKE) minitest
depend: os2ish.h dlfcn.h os2thread.h os2.c
# Aout section:
-aout_obj = $(addsuffix $(AOUT_OBJ_EXT),$(basename $(obj)))
+aout_obj = $(addsuffix $(AOUT_OBJ_EXT),$(basename $(perllib_objs)))
AOUT_DYNALOADER = $(addsuffix $(AOUT_LIB_EXT),$(basename $(DYNALOADER)))
aout_ext = $(static_ext) $(dynamic_ext) $(AOUT_EXTRA_LIBS)
aout_static_ext = $(addsuffix $(AOUT_LIB_EXT),$(basename $(aout_ext)))
$(AOUT_LIBPERL) : $(aout_obj) perl$(AOUT_OBJ_EXT)
rm -f $@
- $(AOUT_AR) rcu $@ perl$(AOUT_OBJ_EXT) $(aout_obj)
+ $(AOUT_AR) rc $@ perl$(AOUT_OBJ_EXT) $(aout_obj)
cp $@ perl$(AOUT_LIB_EXT)
.c$(AOUT_OBJ_EXT):
#define PERL_REVISION 5 /* age */
#define PERL_VERSION 23 /* epoch */
-#define PERL_SUBVERSION 8 /* generation */
+#define PERL_SUBVERSION 9 /* generation */
/* The following numbers describe the earliest compatible version of
Perl ("compatibility" here being defined as sufficient binary/API
*/
#define PERL_API_REVISION 5
#define PERL_API_VERSION 23
-#define PERL_API_SUBVERSION 8
+#define PERL_API_SUBVERSION 9
/*
XXX Note: The selection of non-default Configure options, such
as -Duselonglong may invalidate these settings. Currently, Configure
assert(PL_scopestack_ix == 0);
/* Need to flush since END blocks can produce output */
+ /* flush stdout separately, since we can identify it */
+#ifdef USE_PERLIO
+ {
+ PerlIO *stdo = PerlIO_stdout();
+ if (*stdo && PerlIO_flush(stdo)) {
+ PerlIO_restore_errno(stdo);
+ PerlIO_printf(PerlIO_stderr(), "Unable to flush stdout: %s",
+ Strerror(errno));
+ if (!STATUS_UNIX)
+ STATUS_ALL_FAILURE;
+ }
+ }
+#endif
my_fflush_all();
#ifdef PERL_TRACE_OPS
}
if (env) {
char *s, *old_var;
+ STRLEN nlen;
SV *sv;
+ HV *dups = newHV();
+
for (; *env; env++) {
old_var = *env;
if (!(s = strchr(old_var,'=')) || s == old_var)
continue;
+ nlen = s - old_var;
#if defined(MSDOS) && !defined(DJGPP)
*s = '\0';
(void)strupr(old_var);
*s = '=';
#endif
- sv = newSVpv(s+1, 0);
- (void)hv_store(hv, old_var, s - old_var, sv, 0);
+ if (hv_exists(hv, old_var, nlen)) {
+ const char *name = savepvn(old_var, nlen);
+
+ /* make sure we use the same value as getenv(), otherwise code that
+ uses getenv() (like setlocale()) might see a different value to %ENV
+ */
+ sv = newSVpv(PerlEnv_getenv(name), 0);
+
+ /* keep a count of the dups of this name so we can de-dup environ later */
+ if (hv_exists(dups, name, nlen))
+ ++SvIVX(*hv_fetch(dups, name, nlen, 0));
+ else
+ (void)hv_store(dups, name, nlen, newSViv(1), 0);
+
+ Safefree(name);
+ }
+ else {
+ sv = newSVpv(s+1, 0);
+ }
+ (void)hv_store(hv, old_var, nlen, sv, 0);
if (env_is_not_environ)
mg_set(sv);
}
+ if (HvKEYS(dups)) {
+ /* environ has some duplicate definitions, remove them */
+ HE *entry;
+ hv_iterinit(dups);
+ while ((entry = hv_iternext_flags(dups, 0))) {
+ STRLEN nlen;
+ const char *name = HePV(entry, nlen);
+ IV count = SvIV(HeVAL(entry));
+ IV i;
+ SV **valp = hv_fetch(hv, name, nlen, 0);
+
+ assert(valp);
+
+ /* try to remove any duplicate names, depending on the
+ * implementation used in my_setenv() the iteration might
+ * not be necessary, but let's be safe.
+ */
+ for (i = 0; i < count; ++i)
+ my_setenv(name, 0);
+
+ /* and set it back to the value we set $ENV{name} to */
+ my_setenv(name, SvPV_nolen(*valp));
+ }
+ }
+ SvREFCNT_dec_NN(dups);
}
#endif /* USE_ENVIRON_ARRAY */
#endif /* !PERL_MICRO */
Perl_call_list(pTHX_ I32 oldscope, AV *paramList)
{
SV *atsv;
- volatile const line_t oldline = PL_curcop ? CopLINE(PL_curcop) : 0;
+ VOL const line_t oldline = PL_curcop ? CopLINE(PL_curcop) : 0;
CV *cv;
STRLEN len;
int ret;
# endif
#else
# ifndef memcpy
-# ifdef HAS_BCOPY
-# define memcpy(d,s,l) bcopy(s,d,l)
-# else
-# define memcpy(d,s,l) my_bcopy(s,d,l)
-# endif
+# define memcpy(d,s,l) my_bcopy(s,d,l)
# endif
#endif /* HAS_MEMCPY */
#endif /* HAS_MEMSET */
#if !defined(HAS_MEMMOVE) && !defined(memmove)
-# if defined(HAS_BCOPY) && defined(HAS_SAFE_BCOPY)
-# define memmove(d,s,l) bcopy(s,d,l)
+# if defined(HAS_MEMCPY) && defined(HAS_SAFE_MEMCPY)
+# define memmove(d,s,l) memcpy(d,s,l)
# else
-# if defined(HAS_MEMCPY) && defined(HAS_SAFE_MEMCPY)
-# define memmove(d,s,l) memcpy(d,s,l)
-# else
-# define memmove(d,s,l) my_bcopy(s,d,l)
-# endif
+# define memmove(d,s,l) my_bcopy(s,d,l)
# endif
#endif
#ifndef PERL_SET_PHASE
# define PERL_SET_PHASE(new_phase) \
- PHASE_CHANGE_PROBE(PL_phase_names[new_phase], PL_phase_names[PL_phase]); \
+ PERL_DTRACE_PROBE_PHASE(new_phase); \
PL_phase = new_phase;
#endif
* This symbol contains the ~name expanded version of PRIVLIB, to be used
* in programs that are not prepared to deal with ~ expansion at run-time.
*/
-#define PRIVLIB "/sys/lib/perl/5.23.8" /**/
-#define PRIVLIB_EXP "/sys/lib/perl/5.23.8" /**/
+#define PRIVLIB "/sys/lib/perl/5.23.9" /**/
+#define PRIVLIB_EXP "/sys/lib/perl/5.23.9" /**/
/* PTRSIZE:
* This symbol contains the size of a pointer, so that the C preprocessor
* removed. The elements in inc_version_list (inc_version_list.U) can
* be tacked onto this variable to generate a list of directories to search.
*/
-#define SITELIB "/sys/lib/perl/5.23.8/site_perl" /**/
-#define SITELIB_EXP "/sys/lib/perl/5.23.8/site_perl" /**/
-#define SITELIB_STEM "/sys/lib/perl/5.23.8/site_perl" /**/
+#define SITELIB "/sys/lib/perl/5.23.9/site_perl" /**/
+#define SITELIB_EXP "/sys/lib/perl/5.23.9/site_perl" /**/
+#define SITELIB_STEM "/sys/lib/perl/5.23.9/site_perl" /**/
/* Size_t_size:
* This symbol holds the size of a Size_t in bytes.
ansi2knr=''
aphostname='/bin/uname -n'
api_revision='5'
-api_subversion='8'
+api_subversion='9'
api_version='23'
-api_versionstring='5.23.8'
+api_versionstring='5.23.9'
ar='ar'
-archlib='/sys/lib/perl5/5.23.8/386'
-archlibexp='/sys/lib/perl5/5.23.8/386'
+archlib='/sys/lib/perl5/5.23.9/386'
+archlibexp='/sys/lib/perl5/5.23.9/386'
archname64=''
archname='386'
archobjs=''
d_fpclassl='undef'
d_fpgetround='undef'
d_fpos64_t='undef'
+d_freelocale='undef'
d_frexpl='undef'
d_fs_data_s='undef'
d_fseeko='undef'
d_nan='undef'
d_ndbm_h_uses_prototypes='undef'
d_nearbyint='undef'
+d_newlocale='undef'
d_nextafter='undef'
d_nexttoward='undef'
d_nice='undef'
d_union_semun='undef'
d_unordered='undef'
d_unsetenv='undef'
+d_uselocale='undef'
d_usleep='undef'
d_usleepproto='undef'
d_ustat='undef'
inc_version_list_init='0'
incpath=''
inews=''
-installarchlib='/sys/lib/perl/5.23.8/386'
+installarchlib='/sys/lib/perl/5.23.9/386'
installbin='/usr/bin'
installman1dir='/sys/man/1pub'
installman3dir='/sys/man/2pub'
installprefix='/usr'
installprefixexp='/usr'
-installprivlib='/sys/lib/perl/5.23.8'
+installprivlib='/sys/lib/perl/5.23.9'
installscript='/usr/bin'
-installsitearch='/sys/lib/perl/5.23.8/site_perl/386'
+installsitearch='/sys/lib/perl/5.23.9/site_perl/386'
installsitebin='/usr/bin'
-installsitelib='/sys/lib/perl/5.23.8/site_perl'
+installsitelib='/sys/lib/perl/5.23.9/site_perl'
installstyle='lib/perl5'
installusrbinperl='undef'
installvendorarch=''
pr=''
prefix='/usr'
prefixexp='/usr'
-privlib='/sys/lib/perl/5.23.8'
-privlibexp='/sys/lib/perl/5.23.8'
+privlib='/sys/lib/perl/5.23.9'
+privlibexp='/sys/lib/perl/5.23.9'
procselfexe=''
prototype='define'
ptrsize='4'
sig_num_init='0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 0'
sig_size='50'
signal_t='void'
-sitearch='/sys/lib/perl/5.23.8/site_perl/386'
+sitearch='/sys/lib/perl/5.23.9/site_perl/386'
sitearchexp='/sys/lib/perl/site_perl/386'
sitebin='/usr/bin'
sitebinexp='/usr/bin'
-sitelib='/sys/lib/perl/5.23.8/site_perl'
-sitelib_stem='/sys/lib/perl/5.23.8/site_perl'
-sitelibexp='/sys/lib/perl/5.23.8/site_perl'
+sitelib='/sys/lib/perl/5.23.9/site_perl'
+sitelib_stem='/sys/lib/perl/5.23.9/site_perl'
+sitelibexp='/sys/lib/perl/5.23.9/site_perl'
siteprefix='/usr'
siteprefixexp='/usr'
sizesize='4'
strerror_r_proto='0'
strings='/sys/include/ape/string.h'
submit=''
-subversion='8'
+subversion='9'
sysman='/sys/man/1pub'
tail=''
tar=''
vendorlibexp=''
vendorprefix=''
vendorprefixexp=''
-version='5.23.8'
-version_patchlevel_string='version 23 subversion 8'
+version='5.23.9'
+version_patchlevel_string='version 23 subversion 9'
versiononly='undef'
vi=''
xlibpth=''
config_argc=0
PERL_REVISION=5
PERL_VERSION=23
-PERL_SUBVERSION=8
+PERL_SUBVERSION=9
PERL_API_REVISION=5
PERL_API_VERSION=23
-PERL_API_SUBVERSION=8
+PERL_API_SUBVERSION=9
PERL_PATCHLEVEL=
PERL_CONFIG_SH=true
/roffitall
# generated
-/perl5238delta.pod
+/perl5239delta.pod
/perlapi.pod
/perlintern.pod
*.html
perlhist Perl history records
perldelta Perl changes since previous version
+ perl5238delta Perl changes in version 5.23.8
perl5237delta Perl changes in version 5.23.7
perl5236delta Perl changes in version 5.23.6
perl5235delta Perl changes in version 5.23.5
--- /dev/null
+=encoding utf8
+
+=head1 NAME
+
+perl5238delta - what is new for perl v5.23.8
+
+=head1 DESCRIPTION
+
+This document describes differences between the 5.23.7 release and the 5.23.8
+release.
+
+If you are upgrading from an earlier release such as 5.23.6, first read
+L<perl5237delta>, which describes differences between 5.23.6 and 5.23.7.
+
+=head1 Core Enhancements
+
+=head2 More fields provided to C<sigaction> callback with C<SA_SIGINFO>
+
+When passing the C<SA_SIGINFO> flag to L<sigaction|POSIX/sigaction>, the
+C<errno>, C<status>, C<uid>, C<pid>, C<addr> and C<band> fields are now
+included in the hash passed to the handler, if supported by the
+platform.
+
+=head1 Security
+
+=head2 Set proper umask before calling C<mkstemp(3)>
+
+In 5.22 perl started setting umask to 0600 before calling C<mkstemp(3)>
+and restoring it afterwards. This wrongfully tells open(2) to strip
+the owner read and write bits from the given mode before applying it,
+rather than the intended negation of leaving only those bits in place.
+
+Systems that use mode 0666 in C<mkstemp(3)> (like old versions of
+glibc) create a file with permissions 0066, leaving world read and
+write permissions regardless of current umask.
+
+This has been fixed by using umask 0177 instead. [perl #127322]
+
+=head1 Incompatible Changes
+
+=head2 C<qr/\N{}/> now disallowed under C<use re "strict">
+
+An empty C<\N{}> makes no sense, but for backwards compatibility is
+silently accepted as doing nothing. But now this is a fatal error under
+the experimental feature L<re/'strict' mode>.
+
+=head1 Performance Enhancements
+
+=over 4
+
+=item *
+
+The overhead of scope entry and exit has been considerably reduced, so
+for example subroutine calls, loops and basic blocks are all faster now.
+This empty function call now takes about a third less time to execute:
+
+ sub f{} f();
+
+=item *
+
+On Win32, C<stat>ing or C<-X>ing a path, if the file or directory does not
+exist, is now 3.5x faster on a SSD (or any drive) than before.
+
+=back
+
+=head1 Modules and Pragmata
+
+=head2 Updated Modules and Pragmata
+
+=over 4
+
+=item *
+
+F<cpan/podlators/> has been upgraded from version 4.04 to 4.06.
+
+=item *
+
+The PathTools module collection has been upgraded from version 3.62
+to 3.63.
+
+=item *
+
+L<DynaLoader> has been upgraded from version 1.37 to 1.38.
+
+DynaLoader now always looks for bootstrap files having the same base name as
+the module for which the bootstrap code is being run. Previously, and only on
+platforms that use C<mod2fname> to produce unique loadable library names,
+L<DynaLoader> would look for the bootstrap file using a base name that matched
+the loadable library and not find it.
+
+=item *
+
+L<Encode> has been upgraded from version 2.78 to 2.80.
+
+=item *
+
+L<ExtUtils::CBuilder> has been upgraded from version 0.280224 to 0.280225.
+
+=item *
+
+L<ExtUtils::MakeMaker> has been upgraded from version 7.10 to 7.10_01.
+
+=item *
+
+L<File::Spec> has been upgraded from version 3.62 to 3.63.
+
+=item *
+
+L<IPC::SysV> has been upgraded from version 2.04 to 2.05.
+
+=item *
+
+L<Module::CoreList> has been upgraded from version 5.20160120 to 5.20160121.
+
+=item *
+
+L<ODBM_File> has been upgraded from version 1.12 to 1.13.
+
+=item *
+
+L<PerlIO::encoding> has been upgraded from version 0.23 to 0.24.
+
+=item *
+
+L<POSIX> has been upgraded from version 1.59 to 1.63.
+
+It can now export constants for the C<code> value in the hash passed to the
+L<sigaction|POSIX/sigaction> handler when using the C<SA_SIGINFO> flag.
+
+These previously deprecated functions are now removed: C<isalnum>,
+C<isalpha>, C<iscntrl>, C<isdigit>, C<isgraph>, C<islower>, C<isprint>,
+C<ispunct>, C<isspace>, C<isupper>, and C<isxdigit>.
+
+=item *
+
+L<Storable> has been upgraded from version 2.54 to 2.55.
+
+=item *
+
+L<Time::HiRes> has been upgraded from version 1.9728 to 1.9730.
+
+It can now export Linux-specific and FreeBSD-specific C<clock_gettime()>
+constants. It also now has emulation for OS X C<clock_nanosleep()>,
+C<clock_gettime()>, and C<clock_getres()>.
+
+=back
+
+=head1 Documentation
+
+=head2 Changes to Existing Documentation
+
+=head3 L<perlguts>
+
+=over 4
+
+=item *
+
+A new section has been added, L<perlguts/"Dynamic Scope and the Context
+Stack">, which explains how the perl context stack works.
+
+=back
+
+=head3 L<perlmodlib>
+
+=over 4
+
+=item *
+
+We now recommend contacting the module-authors list or PAUSE in seeking
+guidance on the naming of modules.
+
+=back
+
+=head1 Diagnostics
+
+The following additions or changes have been made to diagnostic output,
+including warnings and fatal error messages. For the complete list of
+diagnostic messages, see L<perldiag>.
+
+=head2 New Diagnostics
+
+=head3 New Errors
+
+=over 4
+
+=item *
+
+L<<< Sequence (?PE<lt>... not terminated in regex; marked by E<lt>-- HERE in mE<sol>%sE<sol>
+|perldiag/"Sequence (?PE<lt>... not terminated in regex; marked by <-- HERE in mE<sol>%sE<sol>" >>>
+
+=item *
+
+L<Sequence (?PE<gt>... not terminated in regex; marked by E<lt>-- HERE in mE<sol>%sE<sol>
+|perldiag/"Sequence (?PE<gt>... not terminated in regex; marked by <-- HERE in mE<sol>%sE<sol>">
+
+=item *
+
+L<Empty \%c in regex; marked by E<lt>-- HERE in mE<sol>%sE<sol>
+|perldiag/"Empty \%c in regex; marked by <-- HERE in mE<sol>%sE<sol>">
+
+=back
+
+=head3 New Warnings
+
+=over 4
+
+=item *
+
+L<Assuming NOT a POSIX class since %s in regex; marked by E<lt>-- HERE in mE<sol>%sE<sol>|
+perldiag/Assuming NOT a POSIX class since %s in regex; marked by <-- HERE in mE<sol>%sE<sol>>
+
+=back
+
+=head1 Configuration and Compilation
+
+=over 4
+
+=item *
+
+The GNU Make makefile for Win32 now supports parallel builds. [perl #126632]
+
+=item *
+
+You can now build perl with MSVC++ on Win32 using GNU Make. [perl #126632]
+
+=item *
+
+Bison 3.0 is now supported.
+
+=back
+
+=head1 Platform Support
+
+=head2 Platform-Specific Notes
+
+=over 4
+
+=item VMS
+
+=over
+
+=item *
+
+For those C<%ENV> elements based on the CRTL environ array, we've always
+preserved case when setting them but did look-ups only after upcasing the
+key first, which made lower- or mixed-case entries go missing. This problem
+has been corrected by making C<%ENV> elements derived from the environ array
+case-sensitive on look-up as well as case-preserving on store.
+
+=item *
+
+Environment look-ups for C<PERL5LIB> and C<PERLLIB> previously only
+considered logical names, but now consider all sources of C<%ENV> as
+determined by C<PERL_ENV_TABLES> and as documented in L<perlvms/%ENV>.
+
+=back
+
+=item Win32
+
+Builds using Microsoft Visual C++ 2003 and earlier no longer produce
+an "INTERNAL COMPILER ERROR" message. [perl #126045]
+
+=back
+
+=head1 Internal Changes
+
+=over 4
+
+=item *
+
+The implementation of perl's context stack system, and its internal API,
+have been heavily reworked. Note that no significant changes have been
+made to any external APIs, but XS code which relies on such internal
+details may need to be fixed. The main changes are:
+
+=over 4
+
+=item *
+
+The C<PUSHBLOCK()>, C<POPSUB()> etc. macros have been replaced with static
+inline functions such as C<cx_pushblock()>, C<cx_popsub()> etc. These use
+function args rather than implicitly relying on local vars such as
+C<gimme> and C<newsp> being available. Also their functionality has
+changed: in particular, C<cx_popblock()> no longer decrements
+C<cxstack_ix>. The ordering of the steps in the C<pp_leave*> functions
+involving C<cx_popblock()>, C<cx_popsub()> etc. has changed. See the new
+documentation, L<perlguts/"Dynamic Scope and the Context Stack">, for
+details on how to use them.
+
+=item *
+
+Various macros, which now consistently have a CX_ prefix, have been added:
+
+ CX_CUR(), CX_LEAVE_SCOPE(), CX_POP()
+
+or renamed:
+
+ CX_POP_SAVEARRAY(), CX_DEBUG(), CX_PUSHSUBST(), CX_POPSUBST()
+
+=item *
+
+C<cx_pushblock()> now saves C<PL_savestack_ix> and C<PL_tmps_floor>, so
+C<pp_enter*> and C<pp_leave*> no longer do
+
+ ENTER; SAVETMPS; ....; LEAVE
+
+=item *
+
+C<cx_popblock()> now also restores C<PL_curpm>.
+
+=item *
+
+In C<dounwind()> for every context type, the current savestack frame is
+now processed before each context is popped; formerly this was only done
+for sub-like context frames. This action has been removed from
+C<cx_popsub()> and placed into its own macro, C<CX_LEAVE_SCOPE(cx)>, which
+must be called before C<cx_popsub()> etc.
+
+C<dounwind()> now also does a C<cx_popblock()> on the last popped frame
+(formerly it only did the C<cx_popsub()> etc. actions on each frame).
+
+=item *
+
+The temps stack is now freed on scope exit; previously, temps created
+during the last statement of a block wouldn't be freed until the next
+C<nextstate> following the block (apart from an existing hack that did
+this for recursive subs in scalar context); and in something like
+C<f(g())>, the temps created by the last statement in C<g()> would
+formerly not be freed until the statement following the return from
+C<f()>.
+
+=item *
+
+Most values that were saved on the savestack on scope entry are now
+saved in suitable new fields in the context struct, and saved and
+restored directly by C<cx_pushfoo()> and C<cx_popfoo()>, which is much
+faster.
+
+=item *
+
+Various context struct fields have been added, removed or modified.
+
+=item *
+
+The handling of C<@_> in C<cx_pushsub()> and C<cx_popsub()> has been
+considerably tidied up, including removing the C<argarray> field from the
+context struct, and extracting out some common (but rarely used) code into
+a separate function, C<clear_defarray()>. Also, useful subsets of
+C<cx_popsub()> which had been unrolled in places like C<pp_goto> have been
+gathered into the new functions C<cx_popsub_args()> and
+C<cx_popsub_common()>.
+
+=item *
+
+C<pp_leavesub> and C<pp_leavesublv> now use the same function as the rest
+of the C<pp_leave*>'s to process return args.
+
+=item *
+
+C<CXp_FOR_PAD> and C<CXp_FOR_GV> flags have been added, and
+C<CXt_LOOP_FOR> has been split into C<CXt_LOOP_LIST>, C<CXt_LOOP_ARY>.
+
+=item *
+
+Some variables formerly declared by C<dMULTICALL> (but not documented) have
+been removed.
+
+=back
+
+=back
+
+=head1 Selected Bug Fixes
+
+=over 4
+
+=item *
+
+Line numbers larger than 2**31-1 but less than 2**32 are no longer
+returned by caller() as negative numbers. [perl #126991]
+
+=item *
+
+C<< unless ( I<assignment> ) >> now properly warns when syntax
+warnings are enabled. [perl #127122]
+
+=item *
+
+Setting an C<ISA> glob to an array reference now properly adds
+C<isaelem> magic to any existing elements. Previously modifying such
+an element would not update the ISA cache, so method calls would call
+the wrong function. Perl would also crash if the C<ISA> glob was
+destroyed, since new code added in 5.23.7 would try to release the
+C<isaelem> magic from the elements. [perl #127351]
+
+=item *
+
+If a here-doc was found while parsing another operator, the parser had
+already read end of file, and the here-doc was not terminated, perl
+could produce an assertion or a segmentation fault. This now reliably
+complains about the unterminated here-doc. [perl #125540]
+
+=item *
+
+untie() would sometimes return the last value returned by the UNTIE()
+handler as well as it's normal value, messing up the stack. [perl
+#126621]
+
+=item *
+
+Fixed an operator precedence problem when C< castflags & 2> is true.
+[perl #127474]
+
+=item *
+
+Caching of DESTROY methods could result in a non-pointer or a
+non-STASH stored in the SvSTASH() slot of a stash, breaking the B
+STASH() method. The DESTROY method is now cached in the MRO metadata
+for the stash. [perl #126410]
+
+=item *
+
+The AUTOLOAD method is now called when searching for a DESTROY method,
+and correctly sets C<$AUTOLOAD> too. [perl #124387] [perl #127494]
+
+=item *
+
+Avoid parsing beyond the end of the buffer when processing a C<#line>
+directive with no filename. [perl #127334]
+
+=item *
+
+Perl now raises a warning when a regular expression pattern looks like
+it was supposed to contain a POSIX class, like C<qr/[[:alpha:]]/>, but
+there was some slight defect in its specification which causes it to
+instead be treated as a regular bracketed character class. An example
+would be missing the second colon in the above like this:
+C<qr/[[:alpha]]/>. This compiles to match a sequence of two characters.
+The second is C<"]">, and the first is any of: C<"[">, C<":">, C<"a">,
+C<"h">, C<"l">, or C<"p">. This is unlikely to be the intended
+meaning, and now a warning is raised. No warning is raised unless the
+specification is very close to one of the 14 legal POSIX classes. (See
+L<perlrecharclass/POSIX Character Classes>.)
+[perl #8904]
+
+=item *
+
+Certain regex patterns involving a complemented POSIX class in an
+inverted bracketed character class, and matching something else
+optionally would improperly fail to match. An example of one that could
+fail is C</qr/_?[^\Wbar]\x{100}/>. This has been fixed.
+[perl #127537]
+
+=item *
+
+Perl 5.22 added support to the C99 hexadecimal floating point notation,
+but sometimes misparses hex floats. This had been fixed.
+[perl #127183]
+
+=back
+
+=head1 Acknowledgements
+
+Perl 5.23.8 represents approximately 4 weeks of development since Perl 5.23.7
+and contains approximately 30,000 lines of changes across 350 files from 23
+authors.
+
+Excluding auto-generated files, documentation and release tools, there were
+approximately 14,000 lines of changes to 210 .pm, .t, .c and .h files.
+
+Perl continues to flourish into its third decade thanks to a vibrant community
+of users and developers. The following people are known to have contributed the
+improvements that became Perl 5.23.8:
+
+Aaron Crane, Chris 'BinGOs' Williams, Craig A. Berry, Dagfinn Ilmari
+Mannsåker, Daniel Dragan, David Mitchell, Ed J, Herbert Breunung, H.Merijn
+Brand, James E Keenan, Jarkko Hietaniemi, Karl Williamson, Lukas Mai, Niko
+Tyni, Pip Cet, Ricardo Signes, Sawyer X, Sisyphus, Stevan Little, Steve Hay,
+Todd Rinaldo, Tom Hukins, Tony Cook.
+
+The list above is almost certainly incomplete as it is automatically generated
+from version control history. In particular, it does not include the names of
+the (very much appreciated) contributors who reported issues to the Perl bug
+tracker.
+
+Many of the changes included in this version originated in the CPAN modules
+included in Perl's core. We're grateful to the entire CPAN community for
+helping Perl to flourish.
+
+For a more complete list of all of Perl's historical contributors, please see
+the F<AUTHORS> file in the Perl source distribution.
+
+=head1 Reporting Bugs
+
+If you find what you think is a bug, you might check the articles recently
+posted to the comp.lang.perl.misc newsgroup and the perl bug database at
+L<https://rt.perl.org/> . There may also be information at
+L<http://www.perl.org/> , the Perl Home Page.
+
+If you believe you have an unreported bug, please run the L<perlbug> program
+included with your release. Be sure to trim your bug down to a tiny but
+sufficient test case. Your bug report, along with the output of C<perl -V>,
+will be sent off to perlbug@perl.org to be analysed by the Perl porting team.
+
+If the bug you are reporting has security implications, which make it
+inappropriate to send to a publicly archived mailing list, then please send it
+to perl5-security-report@perl.org. This points to a closed subscription
+unarchived mailing list, which includes all the core committers, who will be
+able to help assess the impact of issues, figure out a resolution, and help
+co-ordinate the release of patches to mitigate or fix the problem across all
+platforms on which Perl is supported. Please only use this address for
+security issues in the Perl core, not for modules independently distributed on
+CPAN.
+
+=head1 SEE ALSO
+
+The F<Changes> file for an explanation of how to view exhaustive details on
+what changed.
+
+The F<INSTALL> file for how to build Perl.
+
+The F<README> file for general stuff.
+
+The F<Artistic> and F<Copying> files for copyright information.
+
+=cut
and some C to call it
- static void
- call_Subtract(a, b)
- int a;
- int b;
- {
- dSP;
- int count;
- SV *err_tmp;
-
- ENTER;
- SAVETMPS;
-
- PUSHMARK(SP);
- EXTEND(SP, 2);
- PUSHs(sv_2mortal(newSViv(a)));
- PUSHs(sv_2mortal(newSViv(b)));
- PUTBACK;
-
- count = call_pv("Subtract", G_EVAL|G_SCALAR);
-
- SPAGAIN;
-
- /* Check the eval first */
- err_tmp = ERRSV;
- if (SvTRUE(err_tmp))
- {
- printf ("Uh oh - %s\n", SvPV_nolen(err_tmp));
- POPs;
- }
- else
- {
- if (count != 1)
- croak("call_Subtract: wanted 1 value from 'Subtract', got %d\n",
- count);
-
- printf ("%d - %d = %d\n", a, b, POPi);
- }
-
- PUTBACK;
- FREETMPS;
- LEAVE;
- }
+ static void
+ call_Subtract(a, b)
+ int a;
+ int b;
+ {
+ dSP;
+ int count;
+ SV *err_tmp;
+
+ ENTER;
+ SAVETMPS;
+
+ PUSHMARK(SP);
+ EXTEND(SP, 2);
+ PUSHs(sv_2mortal(newSViv(a)));
+ PUSHs(sv_2mortal(newSViv(b)));
+ PUTBACK;
+
+ count = call_pv("Subtract", G_EVAL|G_SCALAR);
+
+ SPAGAIN;
+
+ /* Check the eval first */
+ err_tmp = ERRSV;
+ if (SvTRUE(err_tmp))
+ {
+ printf ("Uh oh - %s\n", SvPV_nolen(err_tmp));
+ POPs;
+ }
+ else
+ {
+ if (count != 1)
+ croak("call_Subtract: wanted 1 value from 'Subtract', got %d\n",
+ count);
+
+ printf ("%d - %d = %d\n", a, b, POPi);
+ }
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+ }
If I<call_Subtract> is called thus
...
- SV *cvrv = eval_pv("sub {
- print 'You will not find me cluttering any namespace!'
- }", TRUE);
+ SV *cvrv
+ = eval_pv("sub {
+ print 'You will not find me cluttering any namespace!'
+ }", TRUE);
...
# Regex Subroutines
GOSUB num/ofs 2L recurse to paren arg1 at (signed) ofs arg2
- GOSTART no recurse to start of pattern
# Special conditionals
NGROUPP no-sv 1 Whether the group matched.
=head1 NAME
-perldelta - what is new for perl v5.23.8
+perldelta - what is new for perl v5.23.9
=head1 DESCRIPTION
-This document describes differences between the 5.23.7 release and the 5.23.8
+This document describes differences between the 5.23.8 release and the 5.23.9
release.
-If you are upgrading from an earlier release such as 5.23.6, first read
-L<perl5237delta>, which describes differences between 5.23.6 and 5.23.7.
+If you are upgrading from an earlier release such as 5.23.7, first read
+L<perl5238delta>, which describes differences between 5.23.7 and 5.23.8.
=head1 Core Enhancements
-=head2 More fields provided to C<sigaction> callback with C<SA_SIGINFO>
+=head2 perl will now croak when closing an in-place output file fails
-When passing the C<SA_SIGINFO> flag to L<sigaction|POSIX/sigaction>, the
-C<errno>, C<status>, C<uid>, C<pid>, C<addr> and C<band> fields are now
-included in the hash passed to the handler, if supported by the
-platform.
+Until now, failure to close the output file for an in-place edit was not
+detected, meaning that the input file could be clobbered without the edit being
+successfully completed. Now, when the output file cannot be closed
+successfully, an exception is raised.
=head1 Security
-=head2 Set proper umask before calling C<mkstemp(3)>
+=head2 Remove duplicate environment variables from C<environ>
-In 5.22 perl started setting umask to 0600 before calling C<mkstemp(3)>
-and restoring it afterwards. This wrongfully tells open(2) to strip
-the owner read and write bits from the given mode before applying it,
-rather than the intended negation of leaving only those bits in place.
+Previously, if an environment variable appeared more than once in
+C<environ[]>, C<%ENV> would contain the last entry for that name,
+while a typical C<getenv()> would return the first entry. We now
+make sure C<%ENV> contains the same as what C<getenv> returns.
-Systems that use mode 0666 in C<mkstemp(3)> (like old versions of
-glibc) create a file with permissions 0066, leaving world read and
-write permissions regardless of current umask.
+Second, we remove duplicates from C<environ[]>, so if a setting
+with that name is set in C<%ENV> we won't pass an unsafe value
+to a child process.
-This has been fixed by using umask 0177 instead. [perl #127322]
-
-=head1 Incompatible Changes
-
-=head2 C<qr/\N{}/> now disallowed under C<use re "strict">
-
-An empty C<\N{}> makes no sense, but for backwards compatibility is
-silently accepted as doing nothing. But now this is a fatal error under
-the experimental feature L<re/'strict' mode>.
+[CVE-2016-2381]
=head1 Performance Enhancements
=item *
-The overhead of scope entry and exit has been considerably reduced, so
-for example subroutine calls, loops and basic blocks are all faster now.
-This empty function call now takes about a third less time to execute:
-
- sub f{} f();
-
-=item *
-
-On Win32, C<stat>ing or C<-X>ing a path, if the file or directory does not
-exist, is now 3.5x faster on a SSD (or any drive) than before.
+The number of calls to C<add_cp_to_invlist> has been reduced. This
+optimizes the compilation of inverted character classes.
=back
=item *
-F<cpan/podlators/> has been upgraded from version 4.04 to 4.06.
+L<autouse> has been upgraded from version 1.08 to 1.11.
=item *
-The PathTools module collection has been upgraded from version 3.62
-to 3.63.
+L<bytes> has been upgraded from version 1.04 to 1.05.
=item *
-L<DynaLoader> has been upgraded from version 1.37 to 1.38.
+L<Carp> has been upgraded from version 1.38 to 1.40.
-DynaLoader now always looks for bootstrap files having the same base name as
-the module for which the bootstrap code is being run. Previously, and only on
-platforms that use C<mod2fname> to produce unique loadable library names,
-L<DynaLoader> would look for the bootstrap file using a base name that matched
-the loadable library and not find it.
+C<longmess> now returns the error in scalar context. [CPAN #107225]
=item *
-L<Encode> has been upgraded from version 2.78 to 2.80.
+L<Errno> has been upgraded from version 1.24 to 1.25.
+
+It now exports Winsock error constants.
=item *
-L<ExtUtils::CBuilder> has been upgraded from version 0.280224 to 0.280225.
+L<ExtUtils::Embed> has been upgraded from version 1.32 to 1.33.
=item *
-L<ExtUtils::MakeMaker> has been upgraded from version 7.10 to 7.10_01.
+L<File::Find> has been upgraded from version 1.33 to 1.34.
=item *
-L<File::Spec> has been upgraded from version 3.62 to 3.63.
+L<File::Glob> has been upgraded from version 1.25 to 1.26.
=item *
-L<IPC::SysV> has been upgraded from version 2.04 to 2.05.
+L<IPC::SysV> has been upgraded from version 2.05 to 2.06_01.
=item *
-L<Module::CoreList> has been upgraded from version 5.20160120 to 5.20160121.
+L<List::Util> has been upgraded from version 1.42_01 to 1.42_02.
=item *
-L<ODBM_File> has been upgraded from version 1.12 to 1.13.
+L<Module::CoreList> has been upgraded from version 5.20160121 to
+5.20160320.
=item *
-L<PerlIO::encoding> has been upgraded from version 0.23 to 0.24.
+L<Pod::Functions> has been upgraded from version 1.09 to 1.10.
=item *
-L<POSIX> has been upgraded from version 1.59 to 1.63.
+L<POSIX> has been upgraded from version 1.63 to 1.64.
-It can now export constants for the C<code> value in the hash passed to the
-L<sigaction|POSIX/sigaction> handler when using the C<SA_SIGINFO> flag.
-
-These previously deprecated functions are now removed: C<isalnum>,
-C<isalpha>, C<iscntrl>, C<isdigit>, C<isgraph>, C<islower>, C<isprint>,
-C<ispunct>, C<isspace>, C<isupper>, and C<isxdigit>.
+It now exports Winsock error constants.
=item *
-L<Storable> has been upgraded from version 2.54 to 2.55.
+L<Scalar::Util> has been upgraded from version 1.42_01 to 1.42_02.
=item *
-L<Time::HiRes> has been upgraded from version 1.9728 to 1.9730.
-
-It can now export Linux-specific and FreeBSD-specific C<clock_gettime()>
-constants. It also now has emulation for OS X C<clock_nanosleep()>,
-C<clock_gettime()>, and C<clock_getres()>.
+L<SelfLoader> has been upgraded from version 1.22 to 1.23.
-=back
-
-=head1 Documentation
-
-=head2 Changes to Existing Documentation
-
-=head3 L<perlguts>
+=item *
-=over 4
+L<Socket> has been upgraded from version 2.020_02 to 2.020_03.
=item *
-A new section has been added, L<perlguts/"Dynamic Scope and the Context
-Stack">, which explains how the perl context stack works.
+L<Storable> has been upgraded from version 2.55 to 2.56.
-=back
+=item *
-=head3 L<perlmodlib>
+L<strict> has been upgraded from version 1.10 to 1.11.
-=over 4
+Narrowed the filename check.
=item *
-We now recommend contacting the module-authors list or PAUSE in seeking
-guidance on the naming of modules.
+L<Thread::Queue> has been upgraded from version 3.07 to 3.08.
-=back
+=item *
-=head1 Diagnostics
+L<threads> has been upgraded from version 2.05 to 2.06.
-The following additions or changes have been made to diagnostic output,
-including warnings and fatal error messages. For the complete list of
-diagnostic messages, see L<perldiag>.
+=item *
-=head2 New Diagnostics
+L<Tie::File> has been upgraded from version 1.01 to 1.02.
-=head3 New Errors
+=item *
-=over 4
+L<Time::HiRes> has been upgraded from version 1.9730 to 1.9732.
=item *
-L<<< Sequence (?PE<lt>... not terminated in regex; marked by E<lt>-- HERE in mE<sol>%sE<sol>
-|perldiag/"Sequence (?PE<lt>... not terminated in regex; marked by <-- HERE in mE<sol>%sE<sol>" >>>
+L<version> has been upgraded from version 0.9909 to 0.9916.
=item *
-L<Sequence (?PE<gt>... not terminated in regex; marked by E<lt>-- HERE in mE<sol>%sE<sol>
-|perldiag/"Sequence (?PE<gt>... not terminated in regex; marked by <-- HERE in mE<sol>%sE<sol>">
+L<warnings> has been upgraded from version 1.35 to 1.36.
+
+Narrowed the filename check.
=item *
-L<Empty \%c in regex; marked by E<lt>-- HERE in mE<sol>%sE<sol>
-|perldiag/"Empty \%c in regex; marked by <-- HERE in mE<sol>%sE<sol>">
+L<Win32API::File> has been upgraded from version 0.1202 to 0.1203.
=back
-=head3 New Warnings
+=head1 Documentation
+
+=head2 Changes to Existing Documentation
+
+=head3 L<perlfunc>
=over 4
=item *
-L<Assuming NOT a POSIX class since %s in regex; marked by E<lt>-- HERE in mE<sol>%sE<sol>|
-perldiag/Assuming NOT a POSIX class since %s in regex; marked by <-- HERE in mE<sol>%sE<sol>>
+The L<perlfunc> manual page got a cleanup: there's more consistency now
+(in POD usage, grammar, code examples), better practices in code examples
+(use of C<my>, removal of bareword filehandles, dropped usage of C<&>
+when calling subroutines, ...), etc.
=back
=item *
-The GNU Make makefile for Win32 now supports parallel builds. [perl #126632]
+Dtrace builds now build successfully on systems with a newer dtrace
+that require an input object file that uses the probes in the F<.d>
+file.
-=item *
-
-You can now build perl with MSVC++ on Win32 using GNU Make. [perl #126632]
+Previously the probe would fail and cause a build failure. [perl
+#122287]
=item *
-Bison 3.0 is now supported.
+F<installman> no longer warns if a module doesn't contain documentation,
+as this isn't actually an error. Now missing documentation will only
+be reported when using the B<--verbose> switch, and if it does, the
+missing documentation will be reported on C<STDOUT> instead of C<STDERR>.
-=back
-
-=head1 Platform Support
-
-=head2 Platform-Specific Notes
-
-=over 4
-
-=item VMS
+=item *
-=over
+The B<u> option to the C<ar> command was removed. This was redundant
+anyway, and on some systems, it caused a warning.
=item *
-For those C<%ENV> elements based on the CRTL environ array, we've always
-preserved case when setting them but did look-ups only after upcasing the
-key first, which made lower- or mixed-case entries go missing. This problem
-has been corrected by making C<%ENV> elements derived from the environ array
-case-sensitive on look-up as well as case-preserving on store.
+Added F<Configure> probes for C<newlocale>, C<freelocale>, and C<uselocale>.
=item *
-Environment look-ups for C<PERL5LIB> and C<PERLLIB> previously only
-considered logical names, but now consider all sources of C<%ENV> as
-determined by C<PERL_ENV_TABLES> and as documented in L<perlvms/%ENV>.
+Fix up dtrace compile/link for Solaris. [perl #127543]
=back
-=item Win32
-
-Builds using Microsoft Visual C++ 2003 and earlier no longer produce
-an "INTERNAL COMPILER ERROR" message. [perl #126045]
-
-=back
+=head1 Platform Support
-=head1 Internal Changes
+=head2 Platform-Specific Notes
=over 4
-=item *
-
-The implementation of perl's context stack system, and its internal API,
-have been heavily reworked. Note that no significant changes have been
-made to any external APIs, but XS code which relies on such internal
-details may need to be fixed. The main changes are:
+=item Win32
-=over 4
+=over
=item *
-The C<PUSHBLOCK()>, C<POPSUB()> etc. macros have been replaced with static
-inline functions such as C<cx_pushblock()>, C<cx_popsub()> etc. These use
-function args rather than implicitly relying on local vars such as
-C<gimme> and C<newsp> being available. Also their functionality has
-changed: in particular, C<cx_popblock()> no longer decrements
-C<cxstack_ix>. The ordering of the steps in the C<pp_leave*> functions
-involving C<cx_popblock()>, C<cx_popsub()> etc. has changed. See the new
-documentation, L<perlguts/"Dynamic Scope and the Context Stack">, for
-details on how to use them.
+Building a 64-bit perl with a 64-bit GCC but a 32-bit gmake would
+result in an invalid C<$Config{archname}> for the resulting perl.
+[perl #127584]
=item *
-Various macros, which now consistently have a CX_ prefix, have been added:
-
- CX_CUR(), CX_LEAVE_SCOPE(), CX_POP()
+Errors set by Winsock functions are now put directly into C<$^E>, and the
+relevant C<WSAE*> error codes are now exported from the L<Errno> and L<POSIX>
+modules for testing this against.
-or renamed:
+The previous behaviour of putting the errors (converted to POSIX-style C<E*>
+error codes since Perl 5.20.0) into C<$!> was buggy due to the non-equivalence
+of like-named Winsock and POSIX error constants, a relationship between which
+has unfortunately been established in one way or another since Perl 5.8.0.
- CX_POP_SAVEARRAY(), CX_DEBUG(), CX_PUSHSUBST(), CX_POPSUBST()
+The new behaviour provides a much more robust solution for checking Winsock
+errors in portable software without accidentally matching POSIX tests that were
+intended for other OSes and may have different meanings for Winsock.
-=item *
+The old behaviour is currently retained, warts and all, for backwards
+compatibility, but users are encouraged to change any code that tests C<$!>
+against C<E*> constants for Winsock errors to instead test C<$^E> against
+C<WSAE*> constants. After a suitable deprecation period, the old behaviour may
+be removed, leaving C<$!> unchanged after Winsock function calls, to avoid any
+possible confusion over which error variable to check.
-C<cx_pushblock()> now saves C<PL_savestack_ix> and C<PL_tmps_floor>, so
-C<pp_enter*> and C<pp_leave*> no longer do
+=back
- ENTER; SAVETMPS; ....; LEAVE
+=back
-=item *
+=head1 Selected Bug Fixes
-C<cx_popblock()> now also restores C<PL_curpm>.
+=over 4
=item *
-In C<dounwind()> for every context type, the current savestack frame is
-now processed before each context is popped; formerly this was only done
-for sub-like context frames. This action has been removed from
-C<cx_popsub()> and placed into its own macro, C<CX_LEAVE_SCOPE(cx)>, which
-must be called before C<cx_popsub()> etc.
+It now works properly to specify a user-defined property, such as
-C<dounwind()> now also does a C<cx_popblock()> on the last popped frame
-(formerly it only did the C<cx_popsub()> etc. actions on each frame).
+ qr/\p{mypkg1::IsMyProperty}/i
-=item *
-
-The temps stack is now freed on scope exit; previously, temps created
-during the last statement of a block wouldn't be freed until the next
-C<nextstate> following the block (apart from an existing hack that did
-this for recursive subs in scalar context); and in something like
-C<f(g())>, the temps created by the last statement in C<g()> would
-formerly not be freed until the statement following the return from
-C<f()>.
+with C</i> caseless matching, an explicit package name, and
+I<IsMyProperty> not defined at the time of the pattern compilation.
=item *
-Most values that were saved on the savestack on scope entry are now
-saved in suitable new fields in the context struct, and saved and
-restored directly by C<cx_pushfoo()> and C<cx_popfoo()>, which is much
-faster.
+Perl's memcpy(), memmove(), memset() and memcmp() fallbacks are now
+more compatible with the originals. [perl #127619]
=item *
-Various context struct fields have been added, removed or modified.
+The peak memory usage when compiling some regular expression patterns is
+now significantly smaller. [perl #127392]
=item *
-The handling of C<@_> in C<cx_pushsub()> and C<cx_popsub()> has been
-considerably tidied up, including removing the C<argarray> field from the
-context struct, and extracting out some common (but rarely used) code into
-a separate function, C<clear_defarray()>. Also, useful subsets of
-C<cx_popsub()> which had been unrolled in places like C<pp_goto> have been
-gathered into the new functions C<cx_popsub_args()> and
-C<cx_popsub_common()>.
+A case has been fixed in which malformed UTF-8 in the source of a Perl
+script caused an assertion failure instead of an error message. [perl
+#127262]
=item *
-C<pp_leavesub> and C<pp_leavesublv> now use the same function as the rest
-of the C<pp_leave*>'s to process return args.
+Fixed a buffer overrun issue in F<Socked.xs> which was reported by Coverity.
+[CPAN #111707]
-=item *
+=item *
-C<CXp_FOR_PAD> and C<CXp_FOR_GV> flags have been added, and
-C<CXt_LOOP_FOR> has been split into C<CXt_LOOP_LIST>, C<CXt_LOOP_ARY>.
+Fixed a possible division by 0 error in C<Scalar::List::Utils::product>
+(reported by Coverity). [CPAN #105415]
=item *
-Some variables formerly declared by C<dMULTICALL> (but not documented) have
-been removed.
-
-=back
-
-=back
-
-=head1 Selected Bug Fixes
-
-=over 4
+Fixed the issue where a C<< s///r >>) with B<< -DPERL_NO_COW >> attempts
+to modify the source SV, resulting in the program dying. [perl #127635]
=item *
-Line numbers larger than 2**31-1 but less than 2**32 are no longer
-returned by caller() as negative numbers. [perl #126991]
+Fixed a spurious warning about posix character classes. [perl #127581]
=item *
-C<< unless ( I<assignment> ) >> now properly warns when syntax
-warnings are enabled. [perl #127122]
+Fixed an obscure case where a pattern could fail to match. This only
+occurred when matching characters from the set of C1 controls, when
+the target matched string was in UTF-8, and only on EBCDIC platforms.
=item *
-Setting an C<ISA> glob to an array reference now properly adds
-C<isaelem> magic to any existing elements. Previously modifying such
-an element would not update the ISA cache, so method calls would call
-the wrong function. Perl would also crash if the C<ISA> glob was
-destroyed, since new code added in 5.23.7 would try to release the
-C<isaelem> magic from the elements. [perl #127351]
-
-=item *
+Fixed over eager warnings for C<< /[.foo.]/ >>.
-If a here-doc was found while parsing another operator, the parser had
-already read end of file, and the here-doc was not terminated, perl
-could produce an assertion or a segmentation fault. This now reliably
-complains about the unterminated here-doc. [perl #125540]
+This prevents Perl from warning about constructs like C<< /[.].*[.]/ >>.
+[perl #127582, #127604]
=item *
-untie() would sometimes return the last value returned by the UNTIE()
-handler as well as it's normal value, messing up the stack. [perl
-#126621]
+Narrow the filename check in F<strict.pm> and F<warnings.pm>. Previously,
+it assumed that if the filename (without the F<.pmc?> extension) differed
+from the package name, if was a misspelled use statement (i.e. C<use Strict>
+instead of C<use strict>). We now check whether there's really a
+miscapitalization happening, and not another issue.
=item *
-Fixed an operator precedence problem when C< castflags & 2> is true.
-[perl #127474]
+Turn an assertion into a more user friendly failure when parsing
+regexes. [perl #127599]
=item *
-Caching of DESTROY methods could result in a non-pointer or a
-non-STASH stored in the SvSTASH() slot of a stash, breaking the B
-STASH() method. The DESTROY method is now cached in the MRO metadata
-for the stash. [perl #126410]
+Correctly raise an error when trying to compile patterns with
+unterminated character classes while there are trailing backslashes.
+[perl #126141].
=item *
-The AUTOLOAD method is now called when searching for a DESTROY method,
-and correctly sets C<$AUTOLOAD> too. [perl #124387] [perl #127494]
+Added a guard against malformed UTF-8. [perl #127262]
=item *
-Avoid parsing beyond the end of the buffer when processing a C<#line>
-directive with no filename. [perl #127334]
+Only test C<semctl> if we have everything needed to use it. In a FreeBSD
+the C<semctl> entry point may exist, but it can be disabled by policy.
+[perl #127533]
=item *
-Perl now raises a warning when a regular expression pattern looks like
-it was supposed to contain a POSIX class, like C<qr/[[:alpha:]]/>, but
-there was some slight defect in its specification which causes it to
-instead be treated as a regular bracketed character class. An example
-would be missing the second colon in the above like this:
-C<qr/[[:alpha]]/>. This compiles to match a sequence of two characters.
-The second is C<"]">, and the first is any of: C<"[">, C<":">, C<"a">,
-C<"h">, C<"l">, or C<"p">. This is unlikely to be the intended
-meaning, and now a warning is raised. No warning is raised unless the
-specification is very close to one of the 14 legal POSIX classes. (See
-L<perlrecharclass/POSIX Character Classes>.)
-[perl #8904]
+Handle C<NOTHING> regops and C<EXACTFU_SS> regops in C<make_trie> properly.
+[perl #126206]
=item *
-Certain regex patterns involving a complemented POSIX class in an
-inverted bracketed character class, and matching something else
-optionally would improperly fail to match. An example of one that could
-fail is C</qr/_?[^\Wbar]\x{100}/>. This has been fixed.
-[perl #127537]
+Fix a Solaris optimiser bug which prevented certain regular expression
+to be compiled. [perl #127455]
=item *
-Perl 5.22 added support to the C99 hexadecimal floating point notation,
-but sometimes misparses hex floats. This had been fixed.
-[perl #127183]
+Improved the detection of infinite recursion in regular expressions.
+Previously, perl would in certain cases slowly consume resources until
+finally running out of memory. [perl #126182]
+
=back
=head1 Acknowledgements
-Perl 5.23.8 represents approximately 4 weeks of development since Perl 5.23.7
-and contains approximately 30,000 lines of changes across 350 files from 23
+Perl 5.23.9 represents approximately 4 weeks of development since Perl 5.23.8
+and contains approximately 21,000 lines of changes across 230 files from 23
authors.
Excluding auto-generated files, documentation and release tools, there were
-approximately 14,000 lines of changes to 210 .pm, .t, .c and .h files.
+approximately 8,500 lines of changes to 120 .pm, .t, .c and .h files.
Perl continues to flourish into its third decade thanks to a vibrant community
of users and developers. The following people are known to have contributed the
-improvements that became Perl 5.23.8:
+improvements that became Perl 5.23.9:
-Aaron Crane, Chris 'BinGOs' Williams, Craig A. Berry, Dagfinn Ilmari
-Mannsåker, Daniel Dragan, David Mitchell, Ed J, Herbert Breunung, H.Merijn
-Brand, James E Keenan, Jarkko Hietaniemi, Karl Williamson, Lukas Mai, Niko
-Tyni, Pip Cet, Ricardo Signes, Sawyer X, Sisyphus, Stevan Little, Steve Hay,
-Todd Rinaldo, Tom Hukins, Tony Cook.
+Abigail, Alex Vandiver, Andy Broad, Aristotle Pagaltzis, Chris 'BinGOs'
+Williams, Craig A. Berry, Dagfinn Ilmari Mannsåker, Daniel Dragan, David
+Mitchell, Father Chrysostomos, H.Merijn Brand, Jarkko Hietaniemi, John Peacock,
+Karl Williamson, Leon Timmermans, Lukas Mai, Matthew Horsfall, Ricardo Signes,
+Sawyer X, Shlomi Fish, Steve Hay, Tony Cook, Yves Orton.
The list above is almost certainly incomplete as it is automatically generated
from version control history. In particular, it does not include the names of
(F) The modifiers '!', '<' and '>' are allowed in pack() or unpack() only
after certain types. See L<perlfunc/pack>.
+=item alpha->numify() is lossy
+
+(W numeric) An alpha version can not be numified without losing
+information.
+
=item Ambiguous call resolved as CORE::%s(), qualify as such or use &
(W ambiguous) A subroutine you have declared has the same name as a Perl
(W unopened) You tried chdir() on a filehandle that was never opened.
-=item \C no longer supported in regex; marked by S<<-- HERE> in m/%s/
-
-(F) The \C character class used to allow a match of single byte within a
-multi-byte utf-8 character, but was removed in v5.24 as it broke
-encapsulation and its implementation was extremely buggy. If you really
-need to process the individual bytes, you probably want to convert your
-string to one where each underlying byte is stored as a character, with
-utf8::encode().
-
=item "\c%c" is more clearly written simply as "%s"
(W syntax) The C<\cI<X>> construct is intended to be a way to specify
handler is the prototype that is cloned when a new closure is created.
This subroutine cannot be called.
+=item \C no longer supported in regex; marked by S<<-- HERE> in m/%s/
+
+(F) The \C character class used to allow a match of single byte
+within a multi-byte utf-8 character, but was removed in v5.24 as
+it broke encapsulation and its implementation was extremely buggy.
+If you really need to process the individual bytes, you probably
+want to convert your string to one where each underlying byte is
+stored as a character, with utf8::encode().
+
=item Code missing after '/'
(F) You had a (sub-)template that ends with a '/'. There must be
use feature "refaliasing";
\$x = \$y;
+=item Experimental %s on scalar is now forbidden
+
+(F) An experimental feature added in Perl 5.14 allowed C<each>, C<keys>,
+C<push>, C<pop>, C<shift>, C<splice>, C<unshift>, and C<values> to be called with a
+scalar argument. This experiment is considered unsuccessful, and
+has been removed. The C<postderef> feature may meet your needs better.
+
=item Experimental subroutine signatures not enabled
(F) To use subroutine signatures, you must first enable them:
use feature "signatures";
sub foo ($left, $right) { ... }
-=item Experimental %s on scalar is now forbidden
-
-(F) An experimental feature added in Perl 5.14 allowed C<each>, C<keys>,
-C<push>, C<pop>, C<shift>, C<splice>, C<unshift>, and C<values> to be called
-with a scalar argument. This experiment is considered unsuccessful, and has
-been removed. The C<postderef> feature may meet your needs better.
-
=item Experimental "%s" subs not enabled
(F) To use lexical subs, you must first enable them:
CHECK, INIT, or END subroutine. Processing of the remainder of the
queue of such routines has been prematurely ended.
+=item Failed to close in-place edit file %s: %s
+
+(F) Closing an output file from in-place editing, as with the C<-i>
+command-line switch, failed.
+
=item False [] range "%s" in regex; marked by S<<-- HERE> in m/%s/
(W regexp)(F) A character class range must start and end at a literal
if you're expecting only one subscript. When called in list context,
it also returns the key in addition to the value.
-=item Invalid number '%s' for -C option.
-
-(F) You supplied a number to the -C option that either has extra leading
-zeroes or overflows perl's unsigned integer representation.
-
-=item %s() is deprecated on :utf8 handles
-
-(W deprecated) The sysread(), recv(), syswrite() and send() operators
-are deprecated on handles that have the C<:utf8> layer, either
-explicitly, or implicitly, eg., with the C<:encoding(UTF-16LE)> layer.
-
-Both sysread() and recv() currently use only the C<:utf8> flag for the
-stream, ignoring the actual layers. Since sysread() and recv() do no
-UTF-8 validation they can end up creating invalidly encoded scalars.
-
-Similarly, syswrite() and send() use only the C<:utf8> flag, otherwise
-ignoring any layers. If the flag is set, both write the value UTF-8
-encoded, even if the layer is some different encoding, such as the
-example above.
-
-Ideally, all of these operators would completely ignore the C<:utf8>
-state, working only with bytes, but this would result in silently
-breaking existing code. To avoid this a future version of perl will
-throw an exception when any of sysread(), recv(), syswrite() or send()
-are called on handle with the C<:utf8> layer.
-
=item Insecure dependency in %s
(F) You tried to do something that the tainting mechanism didn't like.
not valid character numbers, so it returns the Unicode replacement
character (U+FFFD).
+=item Invalid number '%s' for -C option.
+
+(F) You supplied a number to the -C option that either has extra leading
+zeroes or overflows perl's unsigned integer representation.
+
=item invalid option -D%c, use -D'' to see choices
(S debugging) Perl was called with invalid debugger flags. Call perl
Perl. The current valid ones are given in
L<perlrebackslash/\b{}, \b, \B{}, \B>.
+=item %s() is deprecated on :utf8 handles
+
+(W deprecated) The sysread(), recv(), syswrite() and send() operators are
+deprecated on handles that have the C<:utf8> layer, either explicitly, or
+implicitly, eg., with the C<:encoding(UTF-16LE)> layer.
+
+Both sysread() and recv() currently use only the C<:utf8> flag for the stream,
+ignoring the actual layers. Since sysread() and recv() do no UTF-8
+validation they can end up creating invalidly encoded scalars.
+
+Similarly, syswrite() and send() use only the C<:utf8> flag, otherwise ignoring
+any layers. If the flag is set, both write the value UTF-8 encoded, even if
+the layer is some different encoding, such as the example above.
+
+Ideally, all of these operators would completely ignore the C<:utf8> state,
+working only with bytes, but this would result in silently breaking existing
+code. To avoid this a future version of perl will throw an exception when
+any of sysread(), recv(), syswrite() or send() are called on handle with the
+C<:utf8> layer.
+
=item "%s" is more clearly written simply as "%s" in regex; marked by S<<-- HERE> in m/%s/
(W regexp) (only under C<S<use re 'strict'>> or within C<(?[...])>)
(F) The end of the perl code contained within the {...} must be
followed immediately by a ')'.
-=item Sequence ?P=... not terminated in regex; marked by S<<-- HERE> in
-m/%s/
+=item Sequence (?PE<gt>... not terminated in regex; marked by S<<-- HERE> in m/%s/
-(F) A named reference of the form C<(?P=...)> was missing the final
+(F) A named reference of the form C<(?PE<gt>...)> was missing the final
closing parenthesis after the name. The S<<-- HERE> shows whereabouts
in the regular expression the problem was discovered.
closing angle bracket. The S<<-- HERE> shows whereabouts in the
regular expression the problem was discovered.
-=item Sequence (?PE<gt>... not terminated in regex; marked by S<<-- HERE> in m/%s/
+=item Sequence ?P=... not terminated in regex; marked by S<<-- HERE> in
+m/%s/
-(F) A named reference of the form C<(?PE<gt>...)> was missing the final
+(F) A named reference of the form C<(?P=...)> was missing the final
closing parenthesis after the name. The S<<-- HERE> shows whereabouts
in the regular expression the problem was discovered.
with your single-byte locale (or perhaps you thought you had a UTF-8
locale, but Perl disagrees).
-=item %s() with negative argument
-
-(S misc) Certain operations make no sense with negative arguments.
-Warning is given and the operation is not done.
-
=item Within []-length '%c' not allowed
(F) The count in the (un)pack template may be replaced by C<[TEMPLATE]>
it contains any of the codes @, /, U, u, w or a *-length. Redesign
the template.
+=item %s() with negative argument
+
+(S misc) Certain operations make no sense with negative arguments.
+Warning is given and the operation is not done.
+
=item write() on closed filehandle %s
(W closed) The filehandle you're writing to got itself closed sometime
Early Perl versions worked on some EBCDIC machines, but the last known
version that ran on EBCDIC was v5.8.7, until v5.22, when the Perl core
again works on z/OS. Theoretically, it could work on OS/400 or Siemens'
-BS2000 (or their successors), but this is untested. In v5.22, not all
+BS2000 (or their successors), but this is untested. In v5.22 and 5.24,
+not all
the modules found on CPAN but shipped with core Perl work on z/OS.
If you want to use Perl on a non-z/OS EBCDIC machine, please let us know
an "A", or C<\xDF> to mean a "E<yuml>" (small C<"y"> with a diaeresis),
then your code may well work on your EBCDIC platform, but not on an
ASCII one. That's fine to do if no one will ever want to run your code
-on an ASCII platform; but the bias in this document will be in writing
+on an ASCII platform; but the bias in this document will be towards writing
code portable between EBCDIC and ASCII systems. Again, if every
character you care about is easily enterable from your keyboard, you
don't have to know anything about ASCII, but many keyboards don't easily
automatically translate it to C<\xDF> on your platform, and leave it as
C<\xFF> on ASCII ones. Or you could specify it by name, C<\N{LATIN
SMALL LETTER Y WITH DIAERESIS> and not have to know the numbers.
-Either way works, but require familiarity with Unicode.
+Either way works, but both require familiarity with Unicode.
=head1 COMMON CHARACTER CODE SETS
integers running from 0 to 127 (decimal) that have standardized
interpretations by the computers which use ASCII. For example, 65 means
the letter "A".
-The range 0..127 can be covered by setting the bits in a 7-bit binary
+The range 0..127 can be covered by setting various bits in a 7-bit binary
digit, hence the set is sometimes referred to as "7-bit ASCII".
ASCII was described by the American National Standards Institute
document ANSI X3.4-1986. It was also described by ISO 646:1991
=item *
-The C<cmp> (and hence C<sort>) operators do not necessarily give the
-correct results when both operands are UTF-EBCDIC encoded strings and
-there is a mixture of ASCII and/or control characters, along with other
-characters.
-
-=item *
-
-Ranges containing C<\N{...}> in the C<tr///> (and C<y///>)
-transliteration operators are treated differently than the equivalent
-ranges in regular expression patterns. They should, but don't, cause
-the values in the ranges to all be treated as Unicode code points, and
-not native ones. (L<perlre/Version 8 Regular Expressions> gives
-details as to how it should work.)
-
-=item *
-
Not all shells will allow multiple C<-e> string arguments to perl to
be concatenated together properly as recipes in this document
0, 2, 4, 5, and 6 might
=item *
-There are some bugs in the C<pack>/C<unpack> C<"U0"> template
-
-=item *
-
There are a significant number of test failures in the CPAN modules
-shipped with Perl v5.22. These are only in modules not primarily
+shipped with Perl v5.22 and 5.24. These are only in modules not primarily
maintained by Perl 5 porters. Some of these are failures in the tests
only: they don't realize that it is proper to get different results on
EBCDIC platforms. And some of the failures are real bugs. If you
compile and do a C<make test> on Perl, all tests on the C</cpan>
directory are skipped.
-In particular, the extensions L<Unicode::Collate> and
-L<Unicode::Normalize> are not supported under EBCDIC; likewise for the
-(now deprecated) L<encoding> pragma.
+In particular, the (now deprecated) L<encoding> pragma is not supported
+under EBCDIC.
L<Encode> partially works.
=item *
-In earlier versions, when byte and character data were concatenated,
-the new string was sometimes created by
+In earlier Perl versions, when byte and character data were
+concatenated, the new string was sometimes created by
decoding the byte strings as I<ISO 8859-1 (Latin-1)>, even if the
old Unicode string used EBCDIC.
a unary operator, but merely separates the arguments of a list
operator. A unary operator generally provides scalar context to its
argument, while a list operator may provide either scalar or list
-contexts for its arguments. If it does both, scalar arguments
+contexts for its arguments. If it does both, scalar arguments
come first and list argument follow, and there can only ever
-be one such list argument. For instance, splice() has three scalar
-arguments followed by a list, whereas gethostbyname() has four scalar
-arguments.
+be one such list argument. For instance,
+L<C<splice>|/splice ARRAY,OFFSET,LENGTH,LIST> has three scalar arguments
+followed by a list, whereas L<C<gethostbyname>|/gethostbyname NAME> has
+four scalar arguments.
In the syntax descriptions that follow, list operators that expect a
list (and provide list context for elements of the list) are shown
Any function in the list below may be used either with or without
parentheses around its arguments. (The syntax descriptions omit the
-parentheses.) If you use parentheses, the simple but occasionally
+parentheses.) If you use parentheses, the simple but occasionally
surprising rule is this: It I<looks> like a function, therefore it I<is> a
function, and precedence doesn't matter. Otherwise it's a list
operator or unary operator, and precedence does matter. Whitespace
print +(1+2)+4; # Prints 7.
print ((1+2)+4); # Prints 7.
-If you run Perl with the B<-w> switch it can warn you about this. For
-example, the third line above produces:
+If you run Perl with the L<C<use warnings>|warnings> pragma, it can warn
+you about this. For example, the third line above produces:
print (...) interpreted as function at - line 1.
Useless use of integer addition in void context at - line 1.
A few functions take no arguments at all, and therefore work as neither
-unary nor list operators. These include such functions as C<time>
-and C<endpwent>. For example, C<time+86_400> always means
-C<time() + 86_400>.
+unary nor list operators. These include such functions as
+L<C<time>|/time> and L<C<endpwent>|/endpwent>. For example,
+C<time+86_400> always means C<time() + 86_400>.
For functions that can be used in either a scalar or list context,
nonabortive failure is generally indicated in scalar context by
first glance appear to be a list in scalar context. You can't get a list
like C<(1,2,3)> into being in scalar context, because the compiler knows
the context at compile time. It would generate the scalar comma operator
-there, not the list construction version of the comma. That means it
+there, not the list concatenation version of the comma. That means it
was never a list to start with.
-In general, functions in Perl that serve as wrappers for system calls ("syscalls")
-of the same name (like chown(2), fork(2), closedir(2), etc.) return
-true when they succeed and C<undef> otherwise, as is usually mentioned
-in the descriptions below. This is different from the C interfaces,
-which return C<-1> on failure. Exceptions to this rule include C<wait>,
-C<waitpid>, and C<syscall>. System calls also set the special C<$!>
-variable on failure. Other functions do not, except accidentally.
+In general, functions in Perl that serve as wrappers for system calls
+("syscalls") of the same name (like L<chown(2)>, L<fork(2)>,
+L<closedir(2)>, etc.) return true when they succeed and
+L<C<undef>|/undef EXPR> otherwise, as is usually mentioned in the
+descriptions below. This is different from the C interfaces, which
+return C<-1> on failure. Exceptions to this rule include
+L<C<wait>|/wait>, L<C<waitpid>|/waitpid PID,FLAGS>, and
+L<C<syscall>|/syscall NUMBER, LIST>. System calls also set the special
+L<C<$!>|perlvar/$!> variable on failure. Other functions do not, except
+accidentally.
Extension modules can also hook into the Perl parser to define new
kinds of keyword-headed expression. These may look like functions, but
=for Pod::Functions =String
-C<chomp>, C<chop>, C<chr>, C<crypt>, C<fc>, C<hex>, C<index>, C<lc>,
-C<lcfirst>, C<length>, C<oct>, C<ord>, C<pack>, C<q//>, C<qq//>, C<reverse>,
-C<rindex>, C<sprintf>, C<substr>, C<tr///>, C<uc>, C<ucfirst>, C<y///>
-
-C<fc> is available only if the C<"fc"> feature is enabled or if it is
-prefixed with C<CORE::>. The C<"fc"> feature is enabled automatically
+L<C<chomp>|/chomp VARIABLE>, L<C<chop>|/chop VARIABLE>,
+L<C<chr>|/chr NUMBER>, L<C<crypt>|/crypt PLAINTEXT,SALT>,
+L<C<fc>|/fc EXPR>, L<C<hex>|/hex EXPR>,
+L<C<index>|/index STR,SUBSTR,POSITION>, L<C<lc>|/lc EXPR>,
+L<C<lcfirst>|/lcfirst EXPR>, L<C<length>|/length EXPR>,
+L<C<oct>|/oct EXPR>, L<C<ord>|/ord EXPR>,
+L<C<pack>|/pack TEMPLATE,LIST>,
+L<C<qE<sol>E<sol>>|/qE<sol>STRINGE<sol>>,
+L<C<qqE<sol>E<sol>>|/qqE<sol>STRINGE<sol>>, L<C<reverse>|/reverse LIST>,
+L<C<rindex>|/rindex STR,SUBSTR,POSITION>,
+L<C<sprintf>|/sprintf FORMAT, LIST>,
+L<C<substr>|/substr EXPR,OFFSET,LENGTH,REPLACEMENT>,
+L<C<trE<sol>E<sol>E<sol>>|/trE<sol>E<sol>E<sol>>, L<C<uc>|/uc EXPR>,
+L<C<ucfirst>|/ucfirst EXPR>,
+L<C<yE<sol>E<sol>E<sol>>|/yE<sol>E<sol>E<sol>>
+
+L<C<fc>|/fc EXPR> is available only if the
+L<C<"fc"> feature|feature/The 'fc' feature> is enabled or if it is
+prefixed with C<CORE::>. The
+L<C<"fc"> feature|feature/The 'fc' feature> is enabled automatically
with a C<use v5.16> (or higher) declaration in the current scope.
-
=item Regular expressions and pattern matching
X<regular expression> X<regex> X<regexp>
=for Pod::Functions =Regexp
-C<m//>, C<pos>, C<qr//>, C<quotemeta>, C<s///>, C<split>, C<study>
+L<C<mE<sol>E<sol>>|/mE<sol>E<sol>>, L<C<pos>|/pos SCALAR>,
+L<C<qrE<sol>E<sol>>|/qrE<sol>STRINGE<sol>>,
+L<C<quotemeta>|/quotemeta EXPR>,
+L<C<sE<sol>E<sol>E<sol>>|/sE<sol>E<sol>E<sol>>,
+L<C<split>|/split E<sol>PATTERNE<sol>,EXPR,LIMIT>,
+L<C<study>|/study SCALAR>
=item Numeric functions
X<numeric> X<number> X<trigonometric> X<trigonometry>
=for Pod::Functions =Math
-C<abs>, C<atan2>, C<cos>, C<exp>, C<hex>, C<int>, C<log>, C<oct>, C<rand>,
-C<sin>, C<sqrt>, C<srand>
+L<C<abs>|/abs VALUE>, L<C<atan2>|/atan2 Y,X>, L<C<cos>|/cos EXPR>,
+L<C<exp>|/exp EXPR>, L<C<hex>|/hex EXPR>, L<C<int>|/int EXPR>,
+L<C<log>|/log EXPR>, L<C<oct>|/oct EXPR>, L<C<rand>|/rand EXPR>,
+L<C<sin>|/sin EXPR>, L<C<sqrt>|/sqrt EXPR>, L<C<srand>|/srand EXPR>
=item Functions for real @ARRAYs
X<array>
=for Pod::Functions =ARRAY
-C<each>, C<keys>, C<pop>, C<push>, C<shift>, C<splice>, C<unshift>, C<values>
+L<C<each>|/each HASH>, L<C<keys>|/keys HASH>, L<C<pop>|/pop ARRAY>,
+L<C<push>|/push ARRAY,LIST>, L<C<shift>|/shift ARRAY>,
+L<C<splice>|/splice ARRAY,OFFSET,LENGTH,LIST>,
+L<C<unshift>|/unshift ARRAY,LIST>, L<C<values>|/values HASH>
=item Functions for list data
X<list>
=for Pod::Functions =LIST
-C<grep>, C<join>, C<map>, C<qw//>, C<reverse>, C<sort>, C<unpack>
+L<C<grep>|/grep BLOCK LIST>, L<C<join>|/join EXPR,LIST>,
+L<C<map>|/map BLOCK LIST>, L<C<qwE<sol>E<sol>>|/qwE<sol>STRINGE<sol>>,
+L<C<reverse>|/reverse LIST>, L<C<sort>|/sort SUBNAME LIST>,
+L<C<unpack>|/unpack TEMPLATE,EXPR>
=item Functions for real %HASHes
X<hash>
=for Pod::Functions =HASH
-C<delete>, C<each>, C<exists>, C<keys>, C<values>
+L<C<delete>|/delete EXPR>, L<C<each>|/each HASH>,
+L<C<exists>|/exists EXPR>, L<C<keys>|/keys HASH>,
+L<C<values>|/values HASH>
=item Input and output functions
X<I/O> X<input> X<output> X<dbm>
=for Pod::Functions =I/O
-C<binmode>, C<close>, C<closedir>, C<dbmclose>, C<dbmopen>, C<die>, C<eof>,
-C<fileno>, C<flock>, C<format>, C<getc>, C<print>, C<printf>, C<read>,
-C<readdir>, C<readline> C<rewinddir>, C<say>, C<seek>, C<seekdir>, C<select>,
-C<syscall>, C<sysread>, C<sysseek>, C<syswrite>, C<tell>, C<telldir>,
-C<truncate>, C<warn>, C<write>
-
-C<say> is available only if the C<"say"> feature is enabled or if it is
-prefixed with C<CORE::>. The C<"say"> feature is enabled automatically
+L<C<binmode>|/binmode FILEHANDLE, LAYER>, L<C<close>|/close FILEHANDLE>,
+L<C<closedir>|/closedir DIRHANDLE>, L<C<dbmclose>|/dbmclose HASH>,
+L<C<dbmopen>|/dbmopen HASH,DBNAME,MASK>, L<C<die>|/die LIST>,
+L<C<eof>|/eof FILEHANDLE>, L<C<fileno>|/fileno FILEHANDLE>,
+L<C<flock>|/flock FILEHANDLE,OPERATION>, L<C<format>|/format>,
+L<C<getc>|/getc FILEHANDLE>, L<C<print>|/print FILEHANDLE LIST>,
+L<C<printf>|/printf FILEHANDLE FORMAT, LIST>,
+L<C<read>|/read FILEHANDLE,SCALAR,LENGTH,OFFSET>,
+L<C<readdir>|/readdir DIRHANDLE>, L<C<readline>|/readline EXPR>
+L<C<rewinddir>|/rewinddir DIRHANDLE>, L<C<say>|/say FILEHANDLE LIST>,
+L<C<seek>|/seek FILEHANDLE,POSITION,WHENCE>,
+L<C<seekdir>|/seekdir DIRHANDLE,POS>,
+L<C<select>|/select RBITS,WBITS,EBITS,TIMEOUT>,
+L<C<syscall>|/syscall NUMBER, LIST>,
+L<C<sysread>|/sysread FILEHANDLE,SCALAR,LENGTH,OFFSET>,
+L<C<sysseek>|/sysseek FILEHANDLE,POSITION,WHENCE>,
+L<C<syswrite>|/syswrite FILEHANDLE,SCALAR,LENGTH,OFFSET>,
+L<C<tell>|/tell FILEHANDLE>, L<C<telldir>|/telldir DIRHANDLE>,
+L<C<truncate>|/truncate FILEHANDLE,LENGTH>, L<C<warn>|/warn LIST>,
+L<C<write>|/write FILEHANDLE>
+
+L<C<say>|/say FILEHANDLE LIST> is available only if the
+L<C<"say"> feature|feature/The 'say' feature> is enabled or if it is
+prefixed with C<CORE::>. The
+L<C<"say"> feature|feature/The 'say' feature> is enabled automatically
with a C<use v5.10> (or higher) declaration in the current scope.
=item Functions for fixed-length data or records
=for Pod::Functions =Binary
-C<pack>, C<read>, C<syscall>, C<sysread>, C<sysseek>, C<syswrite>, C<unpack>,
-C<vec>
+L<C<pack>|/pack TEMPLATE,LIST>,
+L<C<read>|/read FILEHANDLE,SCALAR,LENGTH,OFFSET>,
+L<C<syscall>|/syscall NUMBER, LIST>,
+L<C<sysread>|/sysread FILEHANDLE,SCALAR,LENGTH,OFFSET>,
+L<C<sysseek>|/sysseek FILEHANDLE,POSITION,WHENCE>,
+L<C<syswrite>|/syswrite FILEHANDLE,SCALAR,LENGTH,OFFSET>,
+L<C<unpack>|/unpack TEMPLATE,EXPR>, L<C<vec>|/vec EXPR,OFFSET,BITS>
=item Functions for filehandles, files, or directories
X<file> X<filehandle> X<directory> X<pipe> X<link> X<symlink>
=for Pod::Functions =File
-C<-I<X>>, C<chdir>, C<chmod>, C<chown>, C<chroot>, C<fcntl>, C<glob>,
-C<ioctl>, C<link>, C<lstat>, C<mkdir>, C<open>, C<opendir>,
-C<readlink>, C<rename>, C<rmdir>, C<stat>, C<symlink>, C<sysopen>,
-C<umask>, C<unlink>, C<utime>
+L<C<-I<X>>|/-X FILEHANDLE>, L<C<chdir>|/chdir EXPR>,
+L<C<chmod>|/chmod LIST>, L<C<chown>|/chown LIST>,
+L<C<chroot>|/chroot FILENAME>,
+L<C<fcntl>|/fcntl FILEHANDLE,FUNCTION,SCALAR>, L<C<glob>|/glob EXPR>,
+L<C<ioctl>|/ioctl FILEHANDLE,FUNCTION,SCALAR>,
+L<C<link>|/link OLDFILE,NEWFILE>, L<C<lstat>|/lstat FILEHANDLE>,
+L<C<mkdir>|/mkdir FILENAME,MASK>, L<C<open>|/open FILEHANDLE,EXPR>,
+L<C<opendir>|/opendir DIRHANDLE,EXPR>, L<C<readlink>|/readlink EXPR>,
+L<C<rename>|/rename OLDNAME,NEWNAME>, L<C<rmdir>|/rmdir FILENAME>,
+L<C<select>|/select FILEHANDLE>, L<C<stat>|/stat FILEHANDLE>,
+L<C<symlink>|/symlink OLDFILE,NEWFILE>,
+L<C<sysopen>|/sysopen FILEHANDLE,FILENAME,MODE>,
+L<C<umask>|/umask EXPR>, L<C<unlink>|/unlink LIST>,
+L<C<utime>|/utime LIST>
=item Keywords related to the control flow of your Perl program
X<control flow>
=for Pod::Functions =Flow
-C<break>, C<caller>, C<continue>, C<die>, C<do>,
-C<dump>, C<eval>, C<evalbytes> C<exit>,
-C<__FILE__>, C<goto>, C<last>, C<__LINE__>, C<next>, C<__PACKAGE__>,
-C<redo>, C<return>, C<sub>, C<__SUB__>, C<wantarray>
-
-C<break> is available only if you enable the experimental C<"switch">
-feature or use the C<CORE::> prefix. The C<"switch"> feature also enables
-the C<default>, C<given> and C<when> statements, which are documented in
-L<perlsyn/"Switch Statements">. The C<"switch"> feature is enabled
+L<C<break>|/break>, L<C<caller>|/caller EXPR>,
+L<C<continue>|/continue BLOCK>, L<C<die>|/die LIST>, L<C<do>|/do BLOCK>,
+L<C<dump>|/dump LABEL>, L<C<eval>|/eval EXPR>,
+L<C<evalbytes>|/evalbytes EXPR> L<C<exit>|/exit EXPR>,
+L<C<__FILE__>|/__FILE__>, L<C<goto>|/goto LABEL>,
+L<C<last>|/last LABEL>, L<C<__LINE__>|/__LINE__>,
+L<C<next>|/next LABEL>, L<C<__PACKAGE__>|/__PACKAGE__>,
+L<C<redo>|/redo LABEL>, L<C<return>|/return EXPR>,
+L<C<sub>|/sub NAME BLOCK>, L<C<__SUB__>|/__SUB__>,
+L<C<wantarray>|/wantarray>
+
+L<C<break>|/break> is available only if you enable the experimental
+L<C<"switch"> feature|feature/The 'switch' feature> or use the C<CORE::>
+prefix. The L<C<"switch"> feature|feature/The 'switch' feature> also
+enables the C<default>, C<given> and C<when> statements, which are
+documented in L<perlsyn/"Switch Statements">.
+The L<C<"switch"> feature|feature/The 'switch' feature> is enabled
automatically with a C<use v5.10> (or higher) declaration in the current
-scope. In Perl v5.14 and earlier, C<continue> required the C<"switch">
-feature, like the other keywords.
-
-C<evalbytes> is only available with the C<"evalbytes"> feature (see
-L<feature>) or if prefixed with C<CORE::>. C<__SUB__> is only available
-with the C<"current_sub"> feature or if prefixed with C<CORE::>. Both
-the C<"evalbytes"> and C<"current_sub"> features are enabled automatically
-with a C<use v5.16> (or higher) declaration in the current scope.
+scope. In Perl v5.14 and earlier, L<C<continue>|/continue BLOCK>
+required the L<C<"switch"> feature|feature/The 'switch' feature>, like
+the other keywords.
+
+L<C<evalbytes>|/evalbytes EXPR> is only available with the
+L<C<"evalbytes"> feature|feature/The 'unicode_eval' and 'evalbytes' features>
+(see L<feature>) or if prefixed with C<CORE::>. L<C<__SUB__>|/__SUB__>
+is only available with the
+L<C<"current_sub"> feature|feature/The 'current_sub' feature> or if
+prefixed with C<CORE::>. Both the
+L<C<"evalbytes">|feature/The 'unicode_eval' and 'evalbytes' features>
+and L<C<"current_sub">|feature/The 'current_sub' feature> features are
+enabled automatically with a C<use v5.16> (or higher) declaration in the
+current scope.
=item Keywords related to scoping
=for Pod::Functions =Namespace
-C<caller>, C<import>, C<local>, C<my>, C<our>, C<package>, C<state>, C<use>
+L<C<caller>|/caller EXPR>, L<C<import>|/import LIST>,
+L<C<local>|/local EXPR>, L<C<my>|/my VARLIST>, L<C<our>|/our VARLIST>,
+L<C<package>|/package NAMESPACE>, L<C<state>|/state VARLIST>,
+L<C<use>|/use Module VERSION LIST>
-C<state> is available only if the C<"state"> feature is enabled or if it is
-prefixed with C<CORE::>. The C<"state"> feature is enabled automatically
-with a C<use v5.10> (or higher) declaration in the current scope.
+L<C<state>|/state VARLIST> is available only if the
+L<C<"state"> feature|feature/The 'state' feature> is enabled or if it is
+prefixed with C<CORE::>. The
+L<C<"state"> feature|feature/The 'state' feature> is enabled
+automatically with a C<use v5.10> (or higher) declaration in the current
+scope.
=item Miscellaneous functions
=for Pod::Functions =Misc
-C<defined>, C<formline>, C<lock>, C<prototype>, C<reset>, C<scalar>, C<undef>
+L<C<defined>|/defined EXPR>, L<C<formline>|/formline PICTURE,LIST>,
+L<C<lock>|/lock THING>, L<C<prototype>|/prototype FUNCTION>,
+L<C<reset>|/reset EXPR>, L<C<scalar>|/scalar EXPR>,
+L<C<undef>|/undef EXPR>
=item Functions for processes and process groups
X<process> X<pid> X<process id>
=for Pod::Functions =Process
-C<alarm>, C<exec>, C<fork>, C<getpgrp>, C<getppid>, C<getpriority>, C<kill>,
-C<pipe>, C<qx//>, C<readpipe>, C<setpgrp>,
-C<setpriority>, C<sleep>, C<system>,
-C<times>, C<wait>, C<waitpid>
+L<C<alarm>|/alarm SECONDS>, L<C<exec>|/exec LIST>, L<C<fork>|/fork>,
+L<C<getpgrp>|/getpgrp PID>, L<C<getppid>|/getppid>,
+L<C<getpriority>|/getpriority WHICH,WHO>, L<C<kill>|/kill SIGNAL, LIST>,
+L<C<pipe>|/pipe READHANDLE,WRITEHANDLE>,
+L<C<qxE<sol>E<sol>>|/qxE<sol>STRINGE<sol>>,
+L<C<readpipe>|/readpipe EXPR>, L<C<setpgrp>|/setpgrp PID,PGRP>,
+L<C<setpriority>|/setpriority WHICH,WHO,PRIORITY>,
+L<C<sleep>|/sleep EXPR>, L<C<system>|/system LIST>, L<C<times>|/times>,
+L<C<wait>|/wait>, L<C<waitpid>|/waitpid PID,FLAGS>
=item Keywords related to Perl modules
X<module>
=for Pod::Functions =Modules
-C<do>, C<import>, C<no>, C<package>, C<require>, C<use>
+L<C<do>|/do EXPR>, L<C<import>|/import LIST>,
+L<C<no>|/no MODULE VERSION LIST>, L<C<package>|/package NAMESPACE>,
+L<C<require>|/require VERSION>, L<C<use>|/use Module VERSION LIST>
=item Keywords related to classes and object-orientation
X<object> X<class> X<package>
=for Pod::Functions =Objects
-C<bless>, C<dbmclose>, C<dbmopen>, C<package>, C<ref>, C<tie>, C<tied>,
-C<untie>, C<use>
+L<C<bless>|/bless REF,CLASSNAME>, L<C<dbmclose>|/dbmclose HASH>,
+L<C<dbmopen>|/dbmopen HASH,DBNAME,MASK>,
+L<C<package>|/package NAMESPACE>, L<C<ref>|/ref EXPR>,
+L<C<tie>|/tie VARIABLE,CLASSNAME,LIST>, L<C<tied>|/tied VARIABLE>,
+L<C<untie>|/untie VARIABLE>, L<C<use>|/use Module VERSION LIST>
=item Low-level socket functions
X<socket> X<sock>
=for Pod::Functions =Socket
-C<accept>, C<bind>, C<connect>, C<getpeername>, C<getsockname>,
-C<getsockopt>, C<listen>, C<recv>, C<send>, C<setsockopt>, C<shutdown>,
-C<socket>, C<socketpair>
+L<C<accept>|/accept NEWSOCKET,GENERICSOCKET>,
+L<C<bind>|/bind SOCKET,NAME>, L<C<connect>|/connect SOCKET,NAME>,
+L<C<getpeername>|/getpeername SOCKET>,
+L<C<getsockname>|/getsockname SOCKET>,
+L<C<getsockopt>|/getsockopt SOCKET,LEVEL,OPTNAME>,
+L<C<listen>|/listen SOCKET,QUEUESIZE>,
+L<C<recv>|/recv SOCKET,SCALAR,LENGTH,FLAGS>,
+L<C<send>|/send SOCKET,MSG,FLAGS,TO>,
+L<C<setsockopt>|/setsockopt SOCKET,LEVEL,OPTNAME,OPTVAL>,
+L<C<shutdown>|/shutdown SOCKET,HOW>,
+L<C<socket>|/socket SOCKET,DOMAIN,TYPE,PROTOCOL>,
+L<C<socketpair>|/socketpair SOCKET1,SOCKET2,DOMAIN,TYPE,PROTOCOL>
=item System V interprocess communication functions
X<IPC> X<System V> X<semaphore> X<shared memory> X<memory> X<message>
=for Pod::Functions =SysV
-C<msgctl>, C<msgget>, C<msgrcv>, C<msgsnd>, C<semctl>, C<semget>, C<semop>,
-C<shmctl>, C<shmget>, C<shmread>, C<shmwrite>
+L<C<msgctl>|/msgctl ID,CMD,ARG>, L<C<msgget>|/msgget KEY,FLAGS>,
+L<C<msgrcv>|/msgrcv ID,VAR,SIZE,TYPE,FLAGS>,
+L<C<msgsnd>|/msgsnd ID,MSG,FLAGS>,
+L<C<semctl>|/semctl ID,SEMNUM,CMD,ARG>,
+L<C<semget>|/semget KEY,NSEMS,FLAGS>, L<C<semop>|/semop KEY,OPSTRING>,
+L<C<shmctl>|/shmctl ID,CMD,ARG>, L<C<shmget>|/shmget KEY,SIZE,FLAGS>,
+L<C<shmread>|/shmread ID,VAR,POS,SIZE>,
+L<C<shmwrite>|/shmwrite ID,STRING,POS,SIZE>
=item Fetching user and group info
X<user> X<group> X<password> X<uid> X<gid> X<passwd> X</etc/passwd>
=for Pod::Functions =User
-C<endgrent>, C<endhostent>, C<endnetent>, C<endpwent>, C<getgrent>,
-C<getgrgid>, C<getgrnam>, C<getlogin>, C<getpwent>, C<getpwnam>,
-C<getpwuid>, C<setgrent>, C<setpwent>
+L<C<endgrent>|/endgrent>, L<C<endhostent>|/endhostent>,
+L<C<endnetent>|/endnetent>, L<C<endpwent>|/endpwent>,
+L<C<getgrent>|/getgrent>, L<C<getgrgid>|/getgrgid GID>,
+L<C<getgrnam>|/getgrnam NAME>, L<C<getlogin>|/getlogin>,
+L<C<getpwent>|/getpwent>, L<C<getpwnam>|/getpwnam NAME>,
+L<C<getpwuid>|/getpwuid UID>, L<C<setgrent>|/setgrent>,
+L<C<setpwent>|/setpwent>
=item Fetching network info
X<network> X<protocol> X<host> X<hostname> X<IP> X<address> X<service>
=for Pod::Functions =Network
-C<endprotoent>, C<endservent>, C<gethostbyaddr>, C<gethostbyname>,
-C<gethostent>, C<getnetbyaddr>, C<getnetbyname>, C<getnetent>,
-C<getprotobyname>, C<getprotobynumber>, C<getprotoent>,
-C<getservbyname>, C<getservbyport>, C<getservent>, C<sethostent>,
-C<setnetent>, C<setprotoent>, C<setservent>
+L<C<endprotoent>|/endprotoent>, L<C<endservent>|/endservent>,
+L<C<gethostbyaddr>|/gethostbyaddr ADDR,ADDRTYPE>,
+L<C<gethostbyname>|/gethostbyname NAME>, L<C<gethostent>|/gethostent>,
+L<C<getnetbyaddr>|/getnetbyaddr ADDR,ADDRTYPE>,
+L<C<getnetbyname>|/getnetbyname NAME>, L<C<getnetent>|/getnetent>,
+L<C<getprotobyname>|/getprotobyname NAME>,
+L<C<getprotobynumber>|/getprotobynumber NUMBER>,
+L<C<getprotoent>|/getprotoent>,
+L<C<getservbyname>|/getservbyname NAME,PROTO>,
+L<C<getservbyport>|/getservbyport PORT,PROTO>,
+L<C<getservent>|/getservent>, L<C<sethostent>|/sethostent STAYOPEN>,
+L<C<setnetent>|/setnetent STAYOPEN>,
+L<C<setprotoent>|/setprotoent STAYOPEN>,
+L<C<setservent>|/setservent STAYOPEN>
=item Time-related functions
X<time> X<date>
=for Pod::Functions =Time
-C<gmtime>, C<localtime>, C<time>, C<times>
+L<C<gmtime>|/gmtime EXPR>, L<C<localtime>|/localtime EXPR>,
+L<C<time>|/time>, L<C<times>|/times>
=item Non-function keywords
functionality may differ slightly. The Perl functions affected
by this are:
-C<-X>, C<binmode>, C<chmod>, C<chown>, C<chroot>, C<crypt>,
-C<dbmclose>, C<dbmopen>, C<dump>, C<endgrent>, C<endhostent>,
-C<endnetent>, C<endprotoent>, C<endpwent>, C<endservent>, C<exec>,
-C<fcntl>, C<flock>, C<fork>, C<getgrent>, C<getgrgid>, C<gethostbyname>,
-C<gethostent>, C<getlogin>, C<getnetbyaddr>, C<getnetbyname>, C<getnetent>,
-C<getppid>, C<getpgrp>, C<getpriority>, C<getprotobynumber>,
-C<getprotoent>, C<getpwent>, C<getpwnam>, C<getpwuid>,
-C<getservbyport>, C<getservent>, C<getsockopt>, C<glob>, C<ioctl>,
-C<kill>, C<link>, C<lstat>, C<msgctl>, C<msgget>, C<msgrcv>,
-C<msgsnd>, C<open>, C<pipe>, C<readlink>, C<rename>, C<select>, C<semctl>,
-C<semget>, C<semop>, C<setgrent>, C<sethostent>, C<setnetent>,
-C<setpgrp>, C<setpriority>, C<setprotoent>, C<setpwent>,
-C<setservent>, C<setsockopt>, C<shmctl>, C<shmget>, C<shmread>,
-C<shmwrite>, C<socket>, C<socketpair>,
-C<stat>, C<symlink>, C<syscall>, C<sysopen>, C<system>,
-C<times>, C<truncate>, C<umask>, C<unlink>,
-C<utime>, C<wait>, C<waitpid>
+L<C<-I<X>>|/-X FILEHANDLE>, L<C<binmode>|/binmode FILEHANDLE, LAYER>,
+L<C<chmod>|/chmod LIST>, L<C<chown>|/chown LIST>,
+L<C<chroot>|/chroot FILENAME>, L<C<crypt>|/crypt PLAINTEXT,SALT>,
+L<C<dbmclose>|/dbmclose HASH>, L<C<dbmopen>|/dbmopen HASH,DBNAME,MASK>,
+L<C<dump>|/dump LABEL>, L<C<endgrent>|/endgrent>,
+L<C<endhostent>|/endhostent>, L<C<endnetent>|/endnetent>,
+L<C<endprotoent>|/endprotoent>, L<C<endpwent>|/endpwent>,
+L<C<endservent>|/endservent>, L<C<exec>|/exec LIST>,
+L<C<fcntl>|/fcntl FILEHANDLE,FUNCTION,SCALAR>,
+L<C<flock>|/flock FILEHANDLE,OPERATION>, L<C<fork>|/fork>,
+L<C<getgrent>|/getgrent>, L<C<getgrgid>|/getgrgid GID>,
+L<C<gethostbyname>|/gethostbyname NAME>, L<C<gethostent>|/gethostent>,
+L<C<getlogin>|/getlogin>,
+L<C<getnetbyaddr>|/getnetbyaddr ADDR,ADDRTYPE>,
+L<C<getnetbyname>|/getnetbyname NAME>, L<C<getnetent>|/getnetent>,
+L<C<getppid>|/getppid>, L<C<getpgrp>|/getpgrp PID>,
+L<C<getpriority>|/getpriority WHICH,WHO>,
+L<C<getprotobynumber>|/getprotobynumber NUMBER>,
+L<C<getprotoent>|/getprotoent>, L<C<getpwent>|/getpwent>,
+L<C<getpwnam>|/getpwnam NAME>, L<C<getpwuid>|/getpwuid UID>,
+L<C<getservbyport>|/getservbyport PORT,PROTO>,
+L<C<getservent>|/getservent>,
+L<C<getsockopt>|/getsockopt SOCKET,LEVEL,OPTNAME>,
+L<C<glob>|/glob EXPR>, L<C<ioctl>|/ioctl FILEHANDLE,FUNCTION,SCALAR>,
+L<C<kill>|/kill SIGNAL, LIST>, L<C<link>|/link OLDFILE,NEWFILE>,
+L<C<lstat>|/lstat FILEHANDLE>, L<C<msgctl>|/msgctl ID,CMD,ARG>,
+L<C<msgget>|/msgget KEY,FLAGS>,
+L<C<msgrcv>|/msgrcv ID,VAR,SIZE,TYPE,FLAGS>,
+L<C<msgsnd>|/msgsnd ID,MSG,FLAGS>, L<C<open>|/open FILEHANDLE,EXPR>,
+L<C<pipe>|/pipe READHANDLE,WRITEHANDLE>, L<C<readlink>|/readlink EXPR>,
+L<C<rename>|/rename OLDNAME,NEWNAME>,
+L<C<select>|/select RBITS,WBITS,EBITS,TIMEOUT>,
+L<C<semctl>|/semctl ID,SEMNUM,CMD,ARG>,
+L<C<semget>|/semget KEY,NSEMS,FLAGS>, L<C<semop>|/semop KEY,OPSTRING>,
+L<C<setgrent>|/setgrent>, L<C<sethostent>|/sethostent STAYOPEN>,
+L<C<setnetent>|/setnetent STAYOPEN>, L<C<setpgrp>|/setpgrp PID,PGRP>,
+L<C<setpriority>|/setpriority WHICH,WHO,PRIORITY>,
+L<C<setprotoent>|/setprotoent STAYOPEN>, L<C<setpwent>|/setpwent>,
+L<C<setservent>|/setservent STAYOPEN>,
+L<C<setsockopt>|/setsockopt SOCKET,LEVEL,OPTNAME,OPTVAL>,
+L<C<shmctl>|/shmctl ID,CMD,ARG>, L<C<shmget>|/shmget KEY,SIZE,FLAGS>,
+L<C<shmread>|/shmread ID,VAR,POS,SIZE>,
+L<C<shmwrite>|/shmwrite ID,STRING,POS,SIZE>,
+L<C<socket>|/socket SOCKET,DOMAIN,TYPE,PROTOCOL>,
+L<C<socketpair>|/socketpair SOCKET1,SOCKET2,DOMAIN,TYPE,PROTOCOL>,
+L<C<stat>|/stat FILEHANDLE>, L<C<symlink>|/symlink OLDFILE,NEWFILE>,
+L<C<syscall>|/syscall NUMBER, LIST>,
+L<C<sysopen>|/sysopen FILEHANDLE,FILENAME,MODE>,
+L<C<system>|/system LIST>, L<C<times>|/times>,
+L<C<truncate>|/truncate FILEHANDLE,LENGTH>, L<C<umask>|/umask EXPR>,
+L<C<unlink>|/unlink LIST>, L<C<utime>|/utime LIST>, L<C<wait>|/wait>,
+L<C<waitpid>|/waitpid PID,FLAGS>
For more information about the portability of these functions, see
L<perlport> and other available platform-specific documentation.
=head2 Alphabetical Listing of Perl Functions
-=over
+=over
=item -X FILEHANDLE
X<-r>X<-w>X<-x>X<-o>X<-R>X<-W>X<-X>X<-O>X<-e>X<-z>X<-s>X<-f>X<-d>X<-l>X<-p>
=for Pod::Functions a file test (-r, -x, etc)
A file test, where X is one of the letters listed below. This unary
-operator takes one argument, either a filename, a filehandle, or a dirhandle,
+operator takes one argument, either a filename, a filehandle, or a dirhandle,
and tests the associated file to see if something is true about it. If the
-argument is omitted, tests C<$_>, except for C<-t>, which tests STDIN.
-Unless otherwise documented, it returns C<1> for true and C<''> for false.
-If the file doesn't exist or can't be examined, it returns C<undef> and
-sets C<$!> (errno). Despite the funny names, precedence is the same as any
-other named unary operator. The operator may be any of:
+argument is omitted, tests L<C<$_>|perlvar/$_>, except for C<-t>, which
+tests STDIN. Unless otherwise documented, it returns C<1> for true and
+C<''> for false. If the file doesn't exist or can't be examined, it
+returns L<C<undef>|/undef EXPR> and sets L<C<$!>|perlvar/$!> (errno).
+Despite the funny names, precedence is the same as any other named unary
+operator. The operator may be any of:
-r File is readable by effective uid/gid.
-w File is writable by effective uid/gid.
Also note that, for the superuser on the local filesystems, the C<-r>,
C<-R>, C<-w>, and C<-W> tests always return 1, and C<-x> and C<-X> return 1
if any execute bit is set in the mode. Scripts run by the superuser
-may thus need to do a stat() to determine the actual mode of the file,
-or temporarily set their effective uid to something else.
-
-If you are using ACLs, there is a pragma called C<filetest> that may
-produce more accurate results than the bare stat() mode bits.
-When under C<use filetest 'access'> the above-mentioned filetests
-test whether the permission can(not) be granted using the
-access(2) family of system calls. Also note that the C<-x> and C<-X> may
+may thus need to do a L<C<stat>|/stat FILEHANDLE> to determine the
+actual mode of the file, or temporarily set their effective uid to
+something else.
+
+If you are using ACLs, there is a pragma called L<C<filetest>|filetest>
+that may produce more accurate results than the bare
+L<C<stat>|/stat FILEHANDLE> mode bits.
+When under C<use filetest 'access'>, the above-mentioned filetests
+test whether the permission can(not) be granted using the L<access(2)>
+family of system calls. Also note that the C<-x> and C<-X> tests may
under this pragma return true even if there are no execute permission
bits set (nor any extra execute permission ACLs). This strangeness is
due to the underlying system calls' definitions. Note also that, due to
the implementation of C<use filetest 'access'>, the C<_> special
filehandle won't cache the results of the file tests when this pragma is
-in effect. Read the documentation for the C<filetest> pragma for more
-information.
+in effect. Read the documentation for the L<C<filetest>|filetest>
+pragma for more information.
-The C<-T> and C<-B> switches work as follows. The first block or so of
+The C<-T> and C<-B> tests work as follows. The first block or so of
the file is examined to see if it is valid UTF-8 that includes non-ASCII
-characters. If, so it's a C<-T> file. Otherwise, that same portion of
+characters. If so, it's a C<-T> file. Otherwise, that same portion of
the file is examined for odd characters such as strange control codes or
characters with the high bit set. If more than a third of the
characters are strange, it's a C<-B> file; otherwise it's a C<-T> file.
read a file to do the C<-T> test, on most occasions you want to use a C<-f>
against the file first, as in C<next unless -f $file && -T $file>.
-If any of the file tests (or either the C<stat> or C<lstat> operator) is given
-the special filehandle consisting of a solitary underline, then the stat
-structure of the previous file test (or stat operator) is used, saving
-a system call. (This doesn't work with C<-t>, and you need to remember
-that lstat() and C<-l> leave values in the stat structure for the
-symbolic link, not the real file.) (Also, if the stat buffer was filled by
-an C<lstat> call, C<-T> and C<-B> will reset it with the results of C<stat _>).
+If any of the file tests (or either the L<C<stat>|/stat FILEHANDLE> or
+L<C<lstat>|/lstat FILEHANDLE> operator) is given the special filehandle
+consisting of a solitary underline, then the stat structure of the
+previous file test (or L<C<stat>|/stat FILEHANDLE> operator) is used,
+saving a system call. (This doesn't work with C<-t>, and you need to
+remember that L<C<lstat>|/lstat FILEHANDLE> and C<-l> leave values in
+the stat structure for the symbolic link, not the real file.) (Also, if
+the stat buffer was filled by an L<C<lstat>|/lstat FILEHANDLE> call,
+C<-T> and C<-B> will reset it with the results of C<stat _>).
Example:
print "Can do.\n" if -r $a || -w _ || -x _;
=for Pod::Functions absolute value function
Returns the absolute value of its argument.
-If VALUE is omitted, uses C<$_>.
+If VALUE is omitted, uses L<C<$_>|perlvar/$_>.
=item accept NEWSOCKET,GENERICSOCKET
X<accept>
=for Pod::Functions accept an incoming socket connect
-Accepts an incoming socket connect, just as accept(2)
+Accepts an incoming socket connect, just as L<accept(2)>
does. Returns the packed address if it succeeded, false otherwise.
See the example in L<perlipc/"Sockets: Client/Server Communication">.
On systems that support a close-on-exec flag on files, the flag will
be set for the newly opened file descriptor, as determined by the
-value of $^F. See L<perlvar/$^F>.
+value of L<C<$^F>|perlvar/$^F>. See L<perlvar/$^F>.
=item alarm SECONDS
X<alarm>
Arranges to have a SIGALRM delivered to this process after the
specified number of wallclock seconds has elapsed. If SECONDS is not
-specified, the value stored in C<$_> is used. (On some machines,
-unfortunately, the elapsed time may be up to one second less or more
-than you specified because of how seconds are counted, and process
-scheduling may delay the delivery of the signal even further.)
+specified, the value stored in L<C<$_>|perlvar/$_> is used. (On some
+machines, unfortunately, the elapsed time may be up to one second less
+or more than you specified because of how seconds are counted, and
+process scheduling may delay the delivery of the signal even further.)
Only one timer may be counting at once. Each call disables the
previous timer, and an argument of C<0> may be supplied to cancel the
previous timer without starting a new one. The returned value is the
amount of time remaining on the previous timer.
-For delays of finer granularity than one second, the Time::HiRes module
+For delays of finer granularity than one second, the L<Time::HiRes> module
(from CPAN, and starting from Perl 5.8 part of the standard
-distribution) provides ualarm(). You may also use Perl's four-argument
-version of select() leaving the first three arguments undefined, or you
-might be able to use the C<syscall> interface to access setitimer(2) if
-your system supports it. See L<perlfaq8> for details.
-
-It is usually a mistake to intermix C<alarm> and C<sleep> calls, because
-C<sleep> may be internally implemented on your system with C<alarm>.
-
-If you want to use C<alarm> to time out a system call you need to use an
-C<eval>/C<die> pair. You can't rely on the alarm causing the system call to
-fail with C<$!> set to C<EINTR> because Perl sets up signal handlers to
-restart system calls on some systems. Using C<eval>/C<die> always works,
-modulo the caveats given in L<perlipc/"Signals">.
+distribution) provides
+L<C<ualarm>|Time::HiRes/ualarm ( $useconds [, $interval_useconds ] )>.
+You may also use Perl's four-argument version of
+L<C<select>|/select RBITS,WBITS,EBITS,TIMEOUT> leaving the first three
+arguments undefined, or you might be able to use the
+L<C<syscall>|/syscall NUMBER, LIST> interface to access L<setitimer(2)>
+if your system supports it. See L<perlfaq8> for details.
+
+It is usually a mistake to intermix L<C<alarm>|/alarm SECONDS> and
+L<C<sleep>|/sleep EXPR> calls, because L<C<sleep>|/sleep EXPR> may be
+internally implemented on your system with L<C<alarm>|/alarm SECONDS>.
+
+If you want to use L<C<alarm>|/alarm SECONDS> to time out a system call
+you need to use an L<C<eval>|/eval EXPR>/L<C<die>|/die LIST> pair. You
+can't rely on the alarm causing the system call to fail with
+L<C<$!>|perlvar/$!> set to C<EINTR> because Perl sets up signal handlers
+to restart system calls on some systems. Using
+L<C<eval>|/eval EXPR>/L<C<die>|/die LIST> always works, modulo the
+caveats given in L<perlipc/"Signals">.
eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
alarm $timeout;
- $nread = sysread SOCKET, $buffer, $size;
+ my $nread = sysread $socket, $buffer, $size;
alarm 0;
};
if ($@) {
Returns the arctangent of Y/X in the range -PI to PI.
-For the tangent operation, you may use the C<Math::Trig::tan>
-function, or use the familiar relation:
+For the tangent operation, you may use the
+L<C<Math::Trig::tan>|Math::Trig/B<tan>> function, or use the familiar
+relation:
sub tan { sin($_[0]) / cos($_[0]) }
The return value for C<atan2(0,0)> is implementation-defined; consult
-your atan2(3) manpage for more information.
+your L<atan2(3)> manpage for more information.
Portability issues: L<perlport/atan2>.
=for Pod::Functions binds an address to a socket
-Binds a network address to a socket, just as bind(2)
+Binds a network address to a socket, just as L<bind(2)>
does. Returns true if it succeeded, false otherwise. NAME should be a
packed address of the appropriate type for the socket. See the examples in
L<perlipc/"Sockets: Client/Server Communication">.
mode on systems where the run-time libraries distinguish between
binary and text files. If FILEHANDLE is an expression, the value is
taken as the name of the filehandle. Returns true on success,
-otherwise it returns C<undef> and sets C<$!> (errno).
+otherwise it returns L<C<undef>|/undef EXPR> and sets
+L<C<$!>|perlvar/$!> (errno).
-On some systems (in general, DOS- and Windows-based systems) binmode()
-is necessary when you're not working with a text file. For the sake
-of portability it is a good idea always to use it when appropriate,
-and never to use it when it isn't appropriate. Also, people can
-set their I/O to be by default UTF8-encoded Unicode, not bytes.
+On some systems (in general, DOS- and Windows-based systems)
+L<C<binmode>|/binmode FILEHANDLE, LAYER> is necessary when you're not
+working with a text file. For the sake of portability it is a good idea
+always to use it when appropriate, and never to use it when it isn't
+appropriate. Also, people can set their I/O to be by default
+UTF8-encoded Unicode, not bytes.
-In other words: regardless of platform, use binmode() on binary data,
-like images, for example.
+In other words: regardless of platform, use
+L<C<binmode>|/binmode FILEHANDLE, LAYER> on binary data, like images,
+for example.
If LAYER is present it is a single string, but may contain multiple
directives. The directives alter the behaviour of the filehandle.
PERLIO environment variable.
The C<:bytes>, C<:crlf>, C<:utf8>, and any other directives of the
-form C<:...>, are called I/O I<layers>. The C<open> pragma can be used to
-establish default I/O layers. See L<open>.
+form C<:...>, are called I/O I<layers>. The L<open> pragma can be used to
+establish default I/O layers.
-I<The LAYER parameter of the binmode() function is described as "DISCIPLINE"
-in "Programming Perl, 3rd Edition". However, since the publishing of this
-book, by many known as "Camel III", the consensus of the naming of this
-functionality has moved from "discipline" to "layer". All documentation
-of this version of Perl therefore refers to "layers" rather than to
-"disciplines". Now back to the regularly scheduled documentation...>
+I<The LAYER parameter of the L<C<binmode>|/binmode FILEHANDLE, LAYER>
+function is described as "DISCIPLINE" in "Programming Perl, 3rd
+Edition". However, since the publishing of this book, by many known as
+"Camel III", the consensus of the naming of this functionality has moved
+from "discipline" to "layer". All documentation of this version of Perl
+therefore refers to "layers" rather than to "disciplines". Now back to
+the regularly scheduled documentation...>
To mark FILEHANDLE as UTF-8, use C<:utf8> or C<:encoding(UTF-8)>.
C<:utf8> just marks the data as UTF-8 without further checking,
while C<:encoding(UTF-8)> checks the data for actually being valid
UTF-8. More details can be found in L<PerlIO::encoding>.
-In general, binmode() should be called after open() but before any I/O
-is done on the filehandle. Calling binmode() normally flushes any
-pending buffered output data (and perhaps pending input data) on the
-handle. An exception to this is the C<:encoding> layer that
-changes the default character encoding of the handle; see L</open>.
+In general, L<C<binmode>|/binmode FILEHANDLE, LAYER> should be called
+after L<C<open>|/open FILEHANDLE,EXPR> but before any I/O is done on the
+filehandle. Calling L<C<binmode>|/binmode FILEHANDLE, LAYER> normally
+flushes any pending buffered output data (and perhaps pending input
+data) on the handle. An exception to this is the C<:encoding> layer
+that changes the default character encoding of the handle.
The C<:encoding> layer sometimes needs to be called in
-mid-stream, and it doesn't flush the stream. The C<:encoding>
+mid-stream, and it doesn't flush the stream. C<:encoding>
also implicitly pushes on top of itself the C<:utf8> layer because
internally Perl operates on UTF8-encoded Unicode characters.
flavors of Mac OS, and is LINE FEED on Unix and most VMS files). In other
systems like OS/2, DOS, and the various flavors of MS-Windows, your program
sees a C<\n> as a simple C<\cJ>, but what's stored in text files are the
-two characters C<\cM\cJ>. That means that if you don't use binmode() on
-these systems, C<\cM\cJ> sequences on disk will be converted to C<\n> on
-input, and any C<\n> in your program will be converted back to C<\cM\cJ> on
-output. This is what you want for text files, but it can be disastrous for
-binary files.
-
-Another consequence of using binmode() (on some systems) is that
-special end-of-file markers will be seen as part of the data stream.
-For systems from the Microsoft family this means that, if your binary
-data contain C<\cZ>, the I/O subsystem will regard it as the end of
-the file, unless you use binmode().
-
-binmode() is important not only for readline() and print() operations,
-but also when using read(), seek(), sysread(), syswrite() and tell()
-(see L<perlport> for more details). See the C<$/> and C<$\> variables
-in L<perlvar> for how to manually set your input and output
+two characters C<\cM\cJ>. That means that if you don't use
+L<C<binmode>|/binmode FILEHANDLE, LAYER> on these systems, C<\cM\cJ>
+sequences on disk will be converted to C<\n> on input, and any C<\n> in
+your program will be converted back to C<\cM\cJ> on output. This is
+what you want for text files, but it can be disastrous for binary files.
+
+Another consequence of using L<C<binmode>|/binmode FILEHANDLE, LAYER>
+(on some systems) is that special end-of-file markers will be seen as
+part of the data stream. For systems from the Microsoft family this
+means that, if your binary data contain C<\cZ>, the I/O subsystem will
+regard it as the end of the file, unless you use
+L<C<binmode>|/binmode FILEHANDLE, LAYER>.
+
+L<C<binmode>|/binmode FILEHANDLE, LAYER> is important not only for
+L<C<readline>|/readline EXPR> and L<C<print>|/print FILEHANDLE LIST>
+operations, but also when using
+L<C<read>|/read FILEHANDLE,SCALAR,LENGTH,OFFSET>,
+L<C<seek>|/seek FILEHANDLE,POSITION,WHENCE>,
+L<C<sysread>|/sysread FILEHANDLE,SCALAR,LENGTH,OFFSET>,
+L<C<syswrite>|/syswrite FILEHANDLE,SCALAR,LENGTH,OFFSET> and
+L<C<tell>|/tell FILEHANDLE> (see L<perlport> for more details). See the
+L<C<$E<sol>>|perlvar/$E<sol>> and L<C<$\>|perlvar/$\> variables in
+L<perlvar> for how to manually set your input and output
line-termination sequences.
Portability issues: L<perlport/binmode>.
This function tells the thingy referenced by REF that it is now an object
in the CLASSNAME package. If CLASSNAME is omitted, the current package
-is used. Because a C<bless> is often the last thing in a constructor,
-it returns the reference for convenience. Always use the two-argument
-version if a derived class might inherit the function doing the blessing.
-See L<perlobj> for more about the blessing (and blessings) of objects.
+is used. Because a L<C<bless>|/bless REF,CLASSNAME> is often the last
+thing in a constructor, it returns the reference for convenience.
+Always use the two-argument version if a derived class might inherit the
+method doing the blessing. See L<perlobj> for more about the blessing
+(and blessings) of objects.
Consider always blessing objects in CLASSNAMEs that are mixed case.
Namespaces with all lowercase names are considered reserved for
-Perl pragmata. Builtin types have all uppercase names. To prevent
+Perl pragmas. Builtin types have all uppercase names. To prevent
confusion, you may wish to avoid such package names as well. Make sure
that CLASSNAME is a true value.
=for Pod::Functions +switch break out of a C<given> block
-Break out of a C<given()> block.
+Break out of a C<given> block.
-This keyword is enabled by the C<"switch"> feature; see L<feature> for
-more information on C<"switch">. You can also access it by prefixing it
-with C<CORE::>. Alternatively, include a C<use v5.10> or later to the
-current scope.
+L<C<break>|/break> is available only if the
+L<C<"switch"> feature|feature/The 'switch' feature> is enabled or if it
+is prefixed with C<CORE::>. The
+L<C<"switch"> feature|feature/The 'switch' feature> is enabled
+automatically with a C<use v5.10> (or higher) declaration in the current
+scope.
=item caller EXPR
X<caller> X<call stack> X<stack> X<stack trace>
Returns the context of the current pure perl subroutine call. In scalar
context, returns the caller's package name if there I<is> a caller (that is, if
-we're in a subroutine or C<eval> or C<require>) and the undefined value
-otherwise. caller never returns XS subs and they are skipped. The next pure
-perl sub will appear instead of the XS
-sub in caller's return values. In list
-context, caller returns
+we're in a subroutine or L<C<eval>|/eval EXPR> or
+L<C<require>|/require VERSION>) and the undefined value otherwise.
+caller never returns XS subs and they are skipped. The next pure perl
+sub will appear instead of the XS sub in caller's return values. In
+list context, caller returns
- # 0 1 2
- ($package, $filename, $line) = caller;
+ # 0 1 2
+ my ($package, $filename, $line) = caller;
With EXPR, it returns some extra information that the debugger uses to
print a stack trace. The value of EXPR indicates how many call frames
to go back before the current one.
# 0 1 2 3 4
- ($package, $filename, $line, $subroutine, $hasargs,
+ my ($package, $filename, $line, $subroutine, $hasargs,
# 5 6 7 8 9 10
$wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash)
- = caller($i);
+ = caller($i);
Here, $subroutine is the function that the caller called (rather than the
function containing the caller). Note that $subroutine may be C<(eval)> if
-the frame is not a subroutine call, but an C<eval>. In such a case
-additional elements $evaltext and
-C<$is_require> are set: C<$is_require> is true if the frame is created by a
-C<require> or C<use> statement, $evaltext contains the text of the
-C<eval EXPR> statement. In particular, for an C<eval BLOCK> statement,
-$subroutine is C<(eval)>, but $evaltext is undefined. (Note also that
-each C<use> statement creates a C<require> frame inside an C<eval EXPR>
-frame.) $subroutine may also be C<(unknown)> if this particular
-subroutine happens to have been deleted from the symbol table.
-C<$hasargs> is true if a new instance of C<@_> was set up for the frame.
+the frame is not a subroutine call, but an L<C<eval>|/eval EXPR>. In
+such a case additional elements $evaltext and C<$is_require> are set:
+C<$is_require> is true if the frame is created by a
+L<C<require>|/require VERSION> or L<C<use>|/use Module VERSION LIST>
+statement, $evaltext contains the text of the C<eval EXPR> statement.
+In particular, for an C<eval BLOCK> statement, $subroutine is C<(eval)>,
+but $evaltext is undefined. (Note also that each
+L<C<use>|/use Module VERSION LIST> statement creates a
+L<C<require>|/require VERSION> frame inside an C<eval EXPR> frame.)
+$subroutine may also be C<(unknown)> if this particular subroutine
+happens to have been deleted from the symbol table. C<$hasargs> is true
+if a new instance of L<C<@_>|perlvar/@_> was set up for the frame.
C<$hints> and C<$bitmask> contain pragmatic hints that the caller was
-compiled with. C<$hints> corresponds to C<$^H>, and C<$bitmask>
-corresponds to C<${^WARNING_BITS}>. The
-C<$hints> and C<$bitmask> values are subject
-to change between versions of Perl, and are not meant for external use.
-
-C<$hinthash> is a reference to a hash containing the value of C<%^H> when the
-caller was compiled, or C<undef> if C<%^H> was empty. Do not modify the values
-of this hash, as they are the actual values stored in the optree.
+compiled with. C<$hints> corresponds to L<C<$^H>|perlvar/$^H>, and
+C<$bitmask> corresponds to
+L<C<${^WARNING_BITS}>|perlvar/${^WARNING_BITS}>. The C<$hints> and
+C<$bitmask> values are subject to change between versions of Perl, and
+are not meant for external use.
+
+C<$hinthash> is a reference to a hash containing the value of
+L<C<%^H>|perlvar/%^H> when the caller was compiled, or
+L<C<undef>|/undef EXPR> if L<C<%^H>|perlvar/%^H> was empty. Do not
+modify the values of this hash, as they are the actual values stored in
+the optree.
Furthermore, when called from within the DB package in
list context, and with an argument, caller returns more
arguments with which the subroutine was invoked.
Be aware that the optimizer might have optimized call frames away before
-C<caller> had a chance to get the information. That means that C<caller(N)>
-might not return information about the call frame you expect it to, for
-C<< N > 1 >>. In particular, C<@DB::args> might have information from the
-previous time C<caller> was called.
+L<C<caller>|/caller EXPR> had a chance to get the information. That
+means that C<caller(N)> might not return information about the call
+frame you expect it to, for C<< N > 1 >>. In particular, C<@DB::args>
+might have information from the previous time L<C<caller>|/caller EXPR>
+was called.
Be aware that setting C<@DB::args> is I<best effort>, intended for
debugging or generating backtraces, and should not be relied upon. In
-particular, as C<@_> contains aliases to the caller's arguments, Perl does
-not take a copy of C<@_>, so C<@DB::args> will contain modifications the
-subroutine makes to C<@_> or its contents, not the original values at call
-time. C<@DB::args>, like C<@_>, does not hold explicit references to its
-elements, so under certain cases its elements may have become freed and
-reallocated for other variables or temporary values. Finally, a side effect
-of the current implementation is that the effects of C<shift @_> can
-I<normally> be undone (but not C<pop @_> or other splicing, I<and> not if a
-reference to C<@_> has been taken, I<and> subject to the caveat about reallocated
-elements), so C<@DB::args> is actually a hybrid of the current state and
-initial state of C<@_>. Buyer beware.
+particular, as L<C<@_>|perlvar/@_> contains aliases to the caller's
+arguments, Perl does not take a copy of L<C<@_>|perlvar/@_>, so
+C<@DB::args> will contain modifications the subroutine makes to
+L<C<@_>|perlvar/@_> or its contents, not the original values at call
+time. C<@DB::args>, like L<C<@_>|perlvar/@_>, does not hold explicit
+references to its elements, so under certain cases its elements may have
+become freed and reallocated for other variables or temporary values.
+Finally, a side effect of the current implementation is that the effects
+of C<shift @_> can I<normally> be undone (but not C<pop @_> or other
+splicing, I<and> not if a reference to L<C<@_>|perlvar/@_> has been
+taken, I<and> subject to the caveat about reallocated elements), so
+C<@DB::args> is actually a hybrid of the current state and initial state
+of L<C<@_>|perlvar/@_>. Buyer beware.
=item chdir EXPR
X<chdir>
changes to the directory specified by C<$ENV{HOME}>, if set; if not,
changes to the directory specified by C<$ENV{LOGDIR}>. (Under VMS, the
variable C<$ENV{'SYS$LOGIN'}> is also checked, and used if it is set.) If
-neither is set, C<chdir> does nothing and fails. It returns true on success,
-false otherwise. See the example under C<die>.
+neither is set, L<C<chdir>|/chdir EXPR> does nothing and fails. It
+returns true on success, false otherwise. See the example under
+L<C<die>|/die LIST>.
-On systems that support fchdir(2), you may pass a filehandle or
-directory handle as the argument. On systems that don't support fchdir(2),
+On systems that support L<fchdir(2)>, you may pass a filehandle or
+directory handle as the argument. On systems that don't support L<fchdir(2)>,
passing handles raises an exception.
=item chmod LIST
list must be the numeric mode, which should probably be an octal
number, and which definitely should I<not> be a string of octal digits:
C<0644> is okay, but C<"0644"> is not. Returns the number of files
-successfully changed. See also L</oct> if all you have is a string.
+successfully changed. See also L<C<oct>|/oct EXPR> if all you have is a
+string.
- $cnt = chmod 0755, "foo", "bar";
+ my $cnt = chmod 0755, "foo", "bar";
chmod 0755, @executables;
- $mode = "0644"; chmod $mode, "foo"; # !!! sets mode to
- # --w----r-T
- $mode = "0644"; chmod oct($mode), "foo"; # this is better
- $mode = 0644; chmod $mode, "foo"; # this is best
+ my $mode = "0644"; chmod $mode, "foo"; # !!! sets mode to
+ # --w----r-T
+ my $mode = "0644"; chmod oct($mode), "foo"; # this is better
+ my $mode = 0644; chmod $mode, "foo"; # this is best
-On systems that support fchmod(2), you may pass filehandles among the
-files. On systems that don't support fchmod(2), passing filehandles raises
+On systems that support L<fchmod(2)>, you may pass filehandles among the
+files. On systems that don't support L<fchmod(2)>, passing filehandles raises
an exception. Filehandles must be passed as globs or glob references to be
recognized; barewords are considered filenames.
my $perm = (stat $fh)[2] & 07777;
chmod($perm | 0600, $fh);
-You can also import the symbolic C<S_I*> constants from the C<Fcntl>
-module:
+You can also import the symbolic C<S_I*> constants from the
+L<C<Fcntl>|Fcntl> module:
use Fcntl qw( :mode );
chmod S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, @executables;
=for Pod::Functions remove a trailing record separator from a string
-This safer version of L</chop> removes any trailing string
-that corresponds to the current value of C<$/> (also known as
-$INPUT_RECORD_SEPARATOR in the C<English> module). It returns the total
+This safer version of L<C<chop>|/chop VARIABLE> removes any trailing
+string that corresponds to the current value of
+L<C<$E<sol>>|perlvar/$E<sol>> (also known as C<$INPUT_RECORD_SEPARATOR>
+in the L<C<English>|English> module). It returns the total
number of characters removed from all its arguments. It's often used to
remove the newline from the end of an input record when you're worried
that the final record may be missing its newline. When in paragraph
mode (C<$/ = ''>), it removes all trailing newlines from the string.
-When in slurp mode (C<$/ = undef>) or fixed-length record mode (C<$/> is
-a reference to an integer or the like; see L<perlvar>) chomp() won't
-remove anything.
-If VARIABLE is omitted, it chomps C<$_>. Example:
+When in slurp mode (C<$/ = undef>) or fixed-length record mode
+(L<C<$E<sol>>|perlvar/$E<sol>> is a reference to an integer or the like;
+see L<perlvar>), L<C<chomp>|/chomp VARIABLE> won't remove anything.
+If VARIABLE is omitted, it chomps L<C<$_>|perlvar/$_>. Example:
while (<>) {
chomp; # avoid \n on last field
- @array = split(/:/);
+ my @array = split(/:/);
# ...
}
If VARIABLE is a hash, it chomps the hash's values, but not its keys,
-resetting the C<each> iterator in the process.
+resetting the L<C<each>|/each HASH> iterator in the process.
You can actually chomp anything that's an lvalue, including an assignment:
- chomp($cwd = `pwd`);
- chomp($answer = <STDIN>);
+ chomp(my $cwd = `pwd`);
+ chomp(my $answer = <STDIN>);
If you chomp a list, each element is chomped, and the total number of
characters removed is returned.
Chops off the last character of a string and returns the character
chopped. It is much more efficient than C<s/.$//s> because it neither
-scans nor copies the string. If VARIABLE is omitted, chops C<$_>.
+scans nor copies the string. If VARIABLE is omitted, chops
+L<C<$_>|perlvar/$_>.
If VARIABLE is a hash, it chops the hash's values, but not its keys,
-resetting the C<each> iterator in the process.
+resetting the L<C<each>|/each HASH> iterator in the process.
You can actually chop anything that's an lvalue, including an assignment.
If you chop a list, each element is chopped. Only the value of the
-last C<chop> is returned.
+last L<C<chop>|/chop VARIABLE> is returned.
-Note that C<chop> returns the last character. To return all but the last
-character, use C<substr($string, 0, -1)>.
+Note that L<C<chop>|/chop VARIABLE> returns the last character. To
+return all but the last character, use C<substr($string, 0, -1)>.
-See also L</chomp>.
+See also L<C<chomp>|/chomp VARIABLE>.
=item chown LIST
X<chown> X<owner> X<user> X<group>
systems to leave that value unchanged. Returns the number of files
successfully changed.
- $cnt = chown $uid, $gid, 'foo', 'bar';
+ my $cnt = chown $uid, $gid, 'foo', 'bar';
chown $uid, $gid, @filenames;
-On systems that support fchown(2), you may pass filehandles among the
-files. On systems that don't support fchown(2), passing filehandles raises
+On systems that support L<fchown(2)>, you may pass filehandles among the
+files. On systems that don't support L<fchown(2)>, passing filehandles raises
an exception. Filehandles must be passed as globs or glob references to be
recognized; barewords are considered filenames.
Here's an example that looks up nonnumeric uids in the passwd file:
print "User: ";
- chomp($user = <STDIN>);
+ chomp(my $user = <STDIN>);
print "Files: ";
- chomp($pattern = <STDIN>);
+ chomp(my $pattern = <STDIN>);
- ($login,$pass,$uid,$gid) = getpwnam($user)
+ my ($login,$pass,$uid,$gid) = getpwnam($user)
or die "$user not in passwd file";
- @ary = glob($pattern); # expand filenames
+ my @ary = glob($pattern); # expand filenames
chown $uid, $gid, @ary;
On most systems, you are not allowed to change the ownership of the
On POSIX systems, you can detect this condition this way:
use POSIX qw(sysconf _PC_CHOWN_RESTRICTED);
- $can_chown_giveaway = not sysconf(_PC_CHOWN_RESTRICTED);
+ my $can_chown_giveaway = ! sysconf(_PC_CHOWN_RESTRICTED);
Portability issues: L<perlport/chown>.
Returns the character represented by that NUMBER in the character set.
For example, C<chr(65)> is C<"A"> in either ASCII or Unicode, and
-chr(0x263a) is a Unicode smiley face.
+chr(0x263a) is a Unicode smiley face.
Negative values give the Unicode replacement character (chr(0xfffd)),
except under the L<bytes> pragma, where the low eight bits of the value
(truncated to an integer) are used.
-If NUMBER is omitted, uses C<$_>.
+If NUMBER is omitted, uses L<C<$_>|perlvar/$_>.
-For the reverse, use L</ord>.
+For the reverse, use L<C<ord>|/ord EXPR>.
Note that characters from 128 to 255 (inclusive) are by default
internally not encoded as UTF-8 for backward compatibility reasons.
begin with a C</> by your process and all its children. (It doesn't
change your current working directory, which is unaffected.) For security
reasons, this call is restricted to the superuser. If FILENAME is
-omitted, does a C<chroot> to C<$_>.
+omitted, does a L<C<chroot>|/chroot FILENAME> to L<C<$_>|perlvar/$_>.
-B<NOTE:> It is good security practice to do C<chdir("/")> (to the root
-directory) immediately after a C<chroot()>.
+B<NOTE:> It is good security practice to do C<chdir("/")>
+(L<C<chdir>|/chdir EXPR> to the root directory) immediately after a
+L<C<chroot>|/chroot FILENAME>.
Portability issues: L<perlport/chroot>.
omitted.
You don't have to close FILEHANDLE if you are immediately going to do
-another C<open> on it, because C<open> closes it for you. (See
-L<open|/open FILEHANDLE>.) However, an explicit C<close> on an input file resets the line
-counter (C<$.>), while the implicit close done by C<open> does not.
-
-If the filehandle came from a piped open, C<close> returns false if one of
-the other syscalls involved fails or if its program exits with non-zero
-status. If the only problem was that the program exited non-zero, C<$!>
-will be set to C<0>. Closing a pipe also waits for the process executing
-on the pipe to exit--in case you wish to look at the output of the pipe
-afterwards--and implicitly puts the exit status value of that command into
-C<$?> and C<${^CHILD_ERROR_NATIVE}>.
-
-If there are multiple threads running, C<close> on a filehandle from a
-piped open returns true without waiting for the child process to terminate,
-if the filehandle is still open in another thread.
+another L<C<open>|/open FILEHANDLE,EXPR> on it, because
+L<C<open>|/open FILEHANDLE,EXPR> closes it for you. (See
+L<C<open>|/open FILEHANDLE,EXPR>.) However, an explicit
+L<C<close>|/close FILEHANDLE> on an input file resets the line counter
+(L<C<$.>|perlvar/$.>), while the implicit close done by
+L<C<open>|/open FILEHANDLE,EXPR> does not.
+
+If the filehandle came from a piped open, L<C<close>|/close FILEHANDLE>
+returns false if one of the other syscalls involved fails or if its
+program exits with non-zero status. If the only problem was that the
+program exited non-zero, L<C<$!>|perlvar/$!> will be set to C<0>.
+Closing a pipe also waits for the process executing on the pipe to
+exit--in case you wish to look at the output of the pipe afterwards--and
+implicitly puts the exit status value of that command into
+L<C<$?>|perlvar/$?> and
+L<C<${^CHILD_ERROR_NATIVE}>|perlvar/${^CHILD_ERROR_NATIVE}>.
+
+If there are multiple threads running, L<C<close>|/close FILEHANDLE> on
+a filehandle from a piped open returns true without waiting for the
+child process to terminate, if the filehandle is still open in another
+thread.
Closing the read end of a pipe before the process writing to it at the
other end is done writing results in the writer receiving a SIGPIPE. If
=for Pod::Functions close directory handle
-Closes a directory opened by C<opendir> and returns the success of that
-system call.
+Closes a directory opened by L<C<opendir>|/opendir DIRHANDLE,EXPR> and
+returns the success of that system call.
=item connect SOCKET,NAME
X<connect>
=for Pod::Functions connect to a remote socket
-Attempts to connect to a remote socket, just like connect(2).
+Attempts to connect to a remote socket, just like L<connect(2)>.
Returns true if it succeeded, false otherwise. NAME should be a
packed address of the appropriate type for the socket. See the examples in
L<perlipc/"Sockets: Client/Server Communication">.
=for Pod::Functions optional trailing block in a while or foreach
-When followed by a BLOCK, C<continue> is actually a
-flow control statement rather than a function. If
-there is a C<continue> BLOCK attached to a BLOCK (typically in a C<while> or
-C<foreach>), it is always executed just before the conditional is about to
-be evaluated again, just like the third part of a C<for> loop in C. Thus
-it can be used to increment a loop variable, even when the loop has been
-continued via the C<next> statement (which is similar to the C C<continue>
+When followed by a BLOCK, L<C<continue>|/continue BLOCK> is actually a
+flow control statement rather than a function. If there is a
+L<C<continue>|/continue BLOCK> BLOCK attached to a BLOCK (typically in a
+C<while> or C<foreach>), it is always executed just before the
+conditional is about to be evaluated again, just like the third part of
+a C<for> loop in C. Thus it can be used to increment a loop variable,
+even when the loop has been continued via the L<C<next>|/next LABEL>
+statement (which is similar to the C L<C<continue>|/continue BLOCK>
statement).
-C<last>, C<next>, or C<redo> may appear within a C<continue>
-block; C<last> and C<redo> behave as if they had been executed within
-the main block. So will C<next>, but since it will execute a C<continue>
-block, it may be more entertaining.
+L<C<last>|/last LABEL>, L<C<next>|/next LABEL>, or
+L<C<redo>|/redo LABEL> may appear within a
+L<C<continue>|/continue BLOCK> block; L<C<last>|/last LABEL> and
+L<C<redo>|/redo LABEL> behave as if they had been executed within the
+main block. So will L<C<next>|/next LABEL>, but since it will execute a
+L<C<continue>|/continue BLOCK> block, it may be more entertaining.
while (EXPR) {
### redo always comes here
}
### last always comes here
-Omitting the C<continue> section is equivalent to using an
-empty one, logically enough, so C<next> goes directly back
-to check the condition at the top of the loop.
+Omitting the L<C<continue>|/continue BLOCK> section is equivalent to
+using an empty one, logically enough, so L<C<next>|/next LABEL> goes
+directly back to check the condition at the top of the loop.
-When there is no BLOCK, C<continue> is a function that
-falls through the current C<when> or C<default> block instead of iterating
-a dynamically enclosing C<foreach> or exiting a lexically enclosing C<given>.
-In Perl 5.14 and earlier, this form of C<continue> was
-only available when the C<"switch"> feature was enabled.
-See L<feature> and L<perlsyn/"Switch Statements"> for more
-information.
+When there is no BLOCK, L<C<continue>|/continue BLOCK> is a function
+that falls through the current C<when> or C<default> block instead of
+iterating a dynamically enclosing C<foreach> or exiting a lexically
+enclosing C<given>. In Perl 5.14 and earlier, this form of
+L<C<continue>|/continue BLOCK> was only available when the
+L<C<"switch"> feature|feature/The 'switch' feature> was enabled. See
+L<feature> and L<perlsyn/"Switch Statements"> for more information.
=item cos EXPR
X<cos> X<cosine> X<acos> X<arccosine>
=for Pod::Functions cosine function
Returns the cosine of EXPR (expressed in radians). If EXPR is omitted,
-takes the cosine of C<$_>.
+takes the cosine of L<C<$_>|perlvar/$_>.
-For the inverse cosine operation, you may use the C<Math::Trig::acos()>
-function, or use this relation:
+For the inverse cosine operation, you may use the
+L<C<Math::Trig::acos>|Math::Trig> function, or use this relation:
sub acos { atan2( sqrt(1 - $_[0] * $_[0]), $_[0] ) }
=for Pod::Functions one-way passwd-style encryption
-Creates a digest string exactly like the crypt(3) function in the C
+Creates a digest string exactly like the L<crypt(3)> function in the C
library (assuming that you actually have a version there that has not
been extirpated as a potential munition).
-crypt() is a one-way hash function. The PLAINTEXT and SALT are turned
+L<C<crypt>|/crypt PLAINTEXT,SALT> is a one-way hash function. The
+PLAINTEXT and SALT are turned
into a short string, called a digest, which is returned. The same
PLAINTEXT and SALT will always return the same string, but there is no
(known) way to get the original PLAINTEXT from the hash. Small
having to transmit or store the text itself. An example is checking
if a correct password is given. The digest of the password is stored,
not the password itself. The user types in a password that is
-crypt()'d with the same salt as the stored digest. If the two digests
-match, the password is correct.
+L<C<crypt>|/crypt PLAINTEXT,SALT>'d with the same salt as the stored
+digest. If the two digests match, the password is correct.
When verifying an existing digest string you should use the digest as
the salt (like C<crypt($plain, $digest) eq $digest>). The SALT used
to create the digest is visible as part of the digest. This ensures
-crypt() will hash the new string with the same salt as the digest.
-This allows your code to work with the standard L<crypt|/crypt> and
-with more exotic implementations. In other words, assume
-nothing about the returned string itself nor about how many bytes
-of SALT may matter.
+L<C<crypt>|/crypt PLAINTEXT,SALT> will hash the new string with the same
+salt as the digest. This allows your code to work with the standard
+L<C<crypt>|/crypt PLAINTEXT,SALT> and with more exotic implementations.
+In other words, assume nothing about the returned string itself nor
+about how many bytes of SALT may matter.
Traditionally the result is a string of 13 bytes: two first bytes of
the salt, followed by 11 bytes from the set C<[./0-9A-Za-z]>, and only
'/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]>). This set of
characters is just a recommendation; the characters allowed in
the salt depend solely on your system's crypt library, and Perl can't
-restrict what salts C<crypt()> accepts.
+restrict what salts L<C<crypt>|/crypt PLAINTEXT,SALT> accepts.
Here's an example that makes sure that whoever runs this program knows
their password:
- $pwd = (getpwuid($<))[1];
+ my $pwd = (getpwuid($<))[1];
system "stty -echo";
print "Password: ";
- chomp($word = <STDIN>);
+ chomp(my $word = <STDIN>);
print "\n";
system "stty echo";
Of course, typing in your own password to whoever asks you
for it is unwise.
-The L<crypt|/crypt> function is unsuitable for hashing large quantities
-of data, not least of all because you can't get the information
-back. Look at the L<Digest> module for more robust algorithms.
+The L<C<crypt>|/crypt PLAINTEXT,SALT> function is unsuitable for hashing
+large quantities of data, not least of all because you can't get the
+information back. Look at the L<Digest> module for more robust
+algorithms.
-If using crypt() on a Unicode string (which I<potentially> has
-characters with codepoints above 255), Perl tries to make sense
-of the situation by trying to downgrade (a copy of)
-the string back to an eight-bit byte string before calling crypt()
-(on that copy). If that works, good. If not, crypt() dies with
-C<Wide character in crypt>.
+If using L<C<crypt>|/crypt PLAINTEXT,SALT> on a Unicode string (which
+I<potentially> has characters with codepoints above 255), Perl tries to
+make sense of the situation by trying to downgrade (a copy of) the
+string back to an eight-bit byte string before calling
+L<C<crypt>|/crypt PLAINTEXT,SALT> (on that copy). If that works, good.
+If not, L<C<crypt>|/crypt PLAINTEXT,SALT> dies with
+L<C<Wide character in crypt>|perldiag/Wide character in %s>.
Portability issues: L<perlport/crypt>.
=for Pod::Functions breaks binding on a tied dbm file
-[This function has been largely superseded by the C<untie> function.]
+[This function has been largely superseded by the
+L<C<untie>|/untie VARIABLE> function.]
Breaks the binding between a DBM file and a hash.
=for Pod::Functions create binding on a tied dbm file
[This function has been largely superseded by the
-L<tie|/tie VARIABLE,CLASSNAME,LIST> function.]
-
-This binds a dbm(3), ndbm(3), sdbm(3), gdbm(3), or Berkeley DB file to a
-hash. HASH is the name of the hash. (Unlike normal C<open>, the first
-argument is I<not> a filehandle, even though it looks like one). DBNAME
-is the name of the database (without the F<.dir> or F<.pag> extension if
-any). If the database does not exist, it is created with protection
-specified by MASK (as modified by the C<umask>). To prevent creation of
-the database if it doesn't exist, you may specify a MODE
-of 0, and the function will return a false value if it
-can't find an existing database. If your system supports
-only the older DBM functions, you may make only one C<dbmopen> call in your
+L<C<tie>|/tie VARIABLE,CLASSNAME,LIST> function.]
+
+This binds a L<dbm(3)>, L<ndbm(3)>, L<sdbm(3)>, L<gdbm(3)>, or Berkeley
+DB file to a hash. HASH is the name of the hash. (Unlike normal
+L<C<open>|/open FILEHANDLE,EXPR>, the first argument is I<not> a
+filehandle, even though it looks like one). DBNAME is the name of the
+database (without the F<.dir> or F<.pag> extension if any). If the
+database does not exist, it is created with protection specified by MASK
+(as modified by the L<C<umask>|/umask EXPR>). To prevent creation of
+the database if it doesn't exist, you may specify a MODE of 0, and the
+function will return a false value if it can't find an existing
+database. If your system supports only the older DBM functions, you may
+make only one L<C<dbmopen>|/dbmopen HASH,DBNAME,MASK> call in your
program. In older versions of Perl, if your system had neither DBM nor
-ndbm, calling C<dbmopen> produced a fatal error; it now falls back to
-sdbm(3).
+ndbm, calling L<C<dbmopen>|/dbmopen HASH,DBNAME,MASK> produced a fatal
+error; it now falls back to L<sdbm(3)>.
If you don't have write access to the DBM file, you can only read hash
variables, not set them. If you want to test whether you can write,
-either use file tests or try setting a dummy hash entry inside an C<eval>
-to trap the error.
+either use file tests or try setting a dummy hash entry inside an
+L<C<eval>|/eval EXPR> to trap the error.
-Note that functions such as C<keys> and C<values> may return huge lists
-when used on large DBM files. You may prefer to use the C<each>
-function to iterate over large DBM files. Example:
+Note that functions such as L<C<keys>|/keys HASH> and
+L<C<values>|/values HASH> may return huge lists when used on large DBM
+files. You may prefer to use the L<C<each>|/each HASH> function to
+iterate over large DBM files. Example:
# print out history file offsets
dbmopen(%HIST,'/usr/lib/news/history',0666);
rich implementation.
You can control which DBM library you use by loading that library
-before you call dbmopen():
+before you call L<C<dbmopen>|/dbmopen HASH,DBNAME,MASK>:
use DB_File;
dbmopen(%NS_Hist, "$ENV{HOME}/.netscape/history.db")
=for Pod::Functions test whether a value, variable, or function is defined
-Returns a Boolean value telling whether EXPR has a value other than
-the undefined value C<undef>. If EXPR is not present, C<$_> is
-checked.
-
-Many operations return C<undef> to indicate failure, end of file,
-system error, uninitialized variable, and other exceptional
-conditions. This function allows you to distinguish C<undef> from
-other values. (A simple Boolean test will not distinguish among
-C<undef>, zero, the empty string, and C<"0">, which are all equally
-false.) Note that since C<undef> is a valid scalar, its presence
-doesn't I<necessarily> indicate an exceptional condition: C<pop>
-returns C<undef> when its argument is an empty array, I<or> when the
-element to return happens to be C<undef>.
-
-You may also use C<defined(&func)> to check whether subroutine C<&func>
+Returns a Boolean value telling whether EXPR has a value other than the
+undefined value L<C<undef>|/undef EXPR>. If EXPR is not present,
+L<C<$_>|perlvar/$_> is checked.
+
+Many operations return L<C<undef>|/undef EXPR> to indicate failure, end
+of file, system error, uninitialized variable, and other exceptional
+conditions. This function allows you to distinguish
+L<C<undef>|/undef EXPR> from other values. (A simple Boolean test will
+not distinguish among L<C<undef>|/undef EXPR>, zero, the empty string,
+and C<"0">, which are all equally false.) Note that since
+L<C<undef>|/undef EXPR> is a valid scalar, its presence doesn't
+I<necessarily> indicate an exceptional condition: L<C<pop>|/pop ARRAY>
+returns L<C<undef>|/undef EXPR> when its argument is an empty array,
+I<or> when the element to return happens to be L<C<undef>|/undef EXPR>.
+
+You may also use C<defined(&func)> to check whether subroutine C<func>
has ever been defined. The return value is unaffected by any forward
-declarations of C<&func>. A subroutine that is not defined
+declarations of C<func>. A subroutine that is not defined
may still be callable: its package may have an C<AUTOLOAD> method that
makes it spring into existence the first time that it is called; see
L<perlsub>.
-Use of C<defined> on aggregates (hashes and arrays) is deprecated. It
+Use of L<C<defined>|/defined EXPR> on aggregates (hashes and arrays) is
+deprecated. It
used to report whether memory for that aggregate had ever been
allocated. This behavior may disappear in future versions of Perl.
You should instead use a simple test for size:
if (%a_hash) { print "has hash members\n" }
When used on a hash element, it tells you whether the value is defined,
-not whether the key exists in the hash. Use L</exists> for the latter
-purpose.
+not whether the key exists in the hash. Use L<C<exists>|/exists EXPR>
+for the latter purpose.
Examples:
print "$val\n" while defined($val = pop(@ary));
die "Can't readlink $sym: $!"
unless defined($value = readlink $sym);
- sub foo { defined &$bar ? &$bar(@_) : die "No bar"; }
+ sub foo { defined &$bar ? $bar->(@_) : die "No bar"; }
$debugging = 0 unless defined $debugging;
-Note: Many folks tend to overuse C<defined> and are then surprised to
-discover that the number C<0> and C<""> (the zero-length string) are, in fact,
-defined values. For example, if you say
+Note: Many folks tend to overuse L<C<defined>|/defined EXPR> and are
+then surprised to discover that the number C<0> and C<""> (the
+zero-length string) are, in fact, defined values. For example, if you
+say
"ab" =~ /a(.*)b/;
matched something that happened to be zero characters long. This is all
very above-board and honest. When a function returns an undefined value,
it's an admission that it couldn't give you an honest answer. So you
-should use C<defined> only when questioning the integrity of what
-you're trying to do. At other times, a simple comparison to C<0> or C<""> is
-what you want.
+should use L<C<defined>|/defined EXPR> only when questioning the
+integrity of what you're trying to do. At other times, a simple
+comparison to C<0> or C<""> is what you want.
-See also L</undef>, L</exists>, L</ref>.
+See also L<C<undef>|/undef EXPR>, L<C<exists>|/exists EXPR>,
+L<C<ref>|/ref EXPR>.
=item delete EXPR
X<delete>
=for Pod::Functions deletes a value from a hash
-Given an expression that specifies an element or slice of a hash, C<delete>
-deletes the specified elements from that hash so that exists() on that element
-no longer returns true. Setting a hash element to the undefined value does
-not remove its key, but deleting it does; see L</exists>.
+Given an expression that specifies an element or slice of a hash,
+L<C<delete>|/delete EXPR> deletes the specified elements from that hash
+so that L<C<exists>|/exists EXPR> on that element no longer returns
+true. Setting a hash element to the undefined value does not remove its
+key, but deleting it does; see L<C<exists>|/exists EXPR>.
In list context, returns the value or values deleted, or the last such
element in scalar context. The return list's length always matches that of
the argument list: deleting non-existent elements returns the undefined value
in their corresponding positions.
-delete() may also be used on arrays and array slices, but its behavior is less
-straightforward. Although exists() will return false for deleted entries,
-deleting array elements never changes indices of existing values; use shift()
-or splice() for that. However, if any deleted elements fall at the end of an
-array, the array's size shrinks to the position of the highest element that
-still tests true for exists(), or to 0 if none do. In other words, an
-array won't have trailing nonexistent elements after a delete.
-
-B<WARNING:> Calling C<delete> on array values is strongly discouraged. The
+L<C<delete>|/delete EXPR> may also be used on arrays and array slices,
+but its behavior is less straightforward. Although
+L<C<exists>|/exists EXPR> will return false for deleted entries,
+deleting array elements never changes indices of existing values; use
+L<C<shift>|/shift ARRAY> or L<C<splice>|/splice
+ARRAY,OFFSET,LENGTH,LIST> for that. However, if any deleted elements
+fall at the end of an array, the array's size shrinks to the position of
+the highest element that still tests true for L<C<exists>|/exists EXPR>,
+or to 0 if none do. In other words, an array won't have trailing
+nonexistent elements after a delete.
+
+B<WARNING:> Calling L<C<delete>|/delete EXPR> on array values is
+strongly discouraged. The
notion of deleting or checking the existence of Perl array elements is not
conceptually coherent, and can lead to surprising behavior.
-Deleting from C<%ENV> modifies the environment. Deleting from a hash tied to
-a DBM file deletes the entry from the DBM file. Deleting from a C<tied> hash
-or array may not necessarily return anything; it depends on the implementation
-of the C<tied> package's DELETE method, which may do whatever it pleases.
+Deleting from L<C<%ENV>|perlvar/%ENV> modifies the environment.
+Deleting from a hash tied to a DBM file deletes the entry from the DBM
+file. Deleting from a L<C<tied>|/tied VARIABLE> hash or array may not
+necessarily return anything; it depends on the implementation of the
+L<C<tied>|/tied VARIABLE> package's DELETE method, which may do whatever
+it pleases.
The C<delete local EXPR> construct localizes the deletion to the current
block at run time. Until the block exits, elements locally deleted
temporarily no longer exist. See L<perlsub/"Localized deletion of elements
of composite types">.
- %hash = (foo => 11, bar => 22, baz => 33);
- $scalar = delete $hash{foo}; # $scalar is 11
+ my %hash = (foo => 11, bar => 22, baz => 33);
+ my $scalar = delete $hash{foo}; # $scalar is 11
$scalar = delete @hash{qw(foo bar)}; # $scalar is 22
- @array = delete @hash{qw(foo baz)}; # @array is (undef,33)
+ my @array = delete @hash{qw(foo baz)}; # @array is (undef,33)
The following (inefficiently) deletes all the values of %HASH and @ARRAY:
- foreach $key (keys %HASH) {
+ foreach my $key (keys %HASH) {
delete $HASH{$key};
}
- foreach $index (0 .. $#ARRAY) {
+ foreach my $index (0 .. $#ARRAY) {
delete $ARRAY[$index];
}
delete @ARRAY[0 .. $#ARRAY];
But both are slower than assigning the empty list
-or undefining %HASH or @ARRAY, which is the customary
+or undefining %HASH or @ARRAY, which is the customary
way to empty out an aggregate:
%HASH = (); # completely empty %HASH
=for Pod::Functions raise an exception or bail out
-C<die> raises an exception. Inside an C<eval> the error message is stuffed
-into C<$@> and the C<eval> is terminated with the undefined value.
-If the exception is outside of all enclosing C<eval>s, then the uncaught
-exception prints LIST to C<STDERR> and exits with a non-zero value. If you
-need to exit the process with a specific exit code, see L</exit>.
+L<C<die>|/die LIST> raises an exception. Inside an
+L<C<eval>|/eval EXPR> the error message is stuffed into
+L<C<$@>|perlvar/$@> and the L<C<eval>|/eval EXPR> is terminated with the
+undefined value. If the exception is outside of all enclosing
+L<C<eval>|/eval EXPR>s, then the uncaught exception prints LIST to
+C<STDERR> and exits with a non-zero value. If you need to exit the
+process with a specific exit code, see L<C<exit>|/exit EXPR>.
Equivalent examples:
and a newline is supplied. Note that the "input line number" (also
known as "chunk") is subject to whatever notion of "line" happens to
be currently in effect, and is also available as the special variable
-C<$.>. See L<perlvar/"$/"> and L<perlvar/"$.">.
+L<C<$.>|perlvar/$.>. See L<perlvar/"$/"> and L<perlvar/"$.">.
Hint: sometimes appending C<", stopped"> to your message will cause it
to make better sense when the string C<"at foo line 123"> is appended.
/etc/games is no good at canasta line 123.
/etc/games is no good, stopped at canasta line 123.
-If the output is empty and C<$@> already contains a value (typically from a
-previous eval) that value is reused after appending C<"\t...propagated">.
-This is useful for propagating exceptions:
+If the output is empty and L<C<$@>|perlvar/$@> already contains a value
+(typically from a previous eval) that value is reused after appending
+C<"\t...propagated">. This is useful for propagating exceptions:
eval { ... };
die unless $@ =~ /Expected exception/;
-If the output is empty and C<$@> contains an object reference that has a
-C<PROPAGATE> method, that method will be called with additional file
-and line number parameters. The return value replaces the value in
-C<$@>; i.e., as if C<< $@ = eval { $@->PROPAGATE(__FILE__, __LINE__) }; >>
-were called.
+If the output is empty and L<C<$@>|perlvar/$@> contains an object
+reference that has a C<PROPAGATE> method, that method will be called
+with additional file and line number parameters. The return value
+replaces the value in L<C<$@>|perlvar/$@>; i.e., as if
+C<< $@ = eval { $@->PROPAGATE(__FILE__, __LINE__) }; >> were called.
-If C<$@> is empty then the string C<"Died"> is used.
+If L<C<$@>|perlvar/$@> is empty, then the string C<"Died"> is used.
If an uncaught exception results in interpreter exit, the exit code is
-determined from the values of C<$!> and C<$?> with this pseudocode:
+determined from the values of L<C<$!>|perlvar/$!> and
+L<C<$?>|perlvar/$?> with this pseudocode:
exit $! if $!; # errno
exit $? >> 8 if $? >> 8; # child exit status
exit 255; # last resort
+As with L<C<exit>|/exit EXPR>, L<C<$?>|perlvar/$?> is set prior to
+unwinding the call stack; any C<DESTROY> or C<END> handlers can then
+alter this value, and thus Perl's exit code.
+
The intent is to squeeze as much possible information about the likely cause
-into the limited space of the system exit
-code. However, as C<$!> is the value
-of C's C<errno>, which can be set by any system call, this means that the value
-of the exit code used by C<die> can be non-predictable, so should not be relied
+into the limited space of the system exit code. However, as
+L<C<$!>|perlvar/$!> is the value of C's C<errno>, which can be set by
+any system call, this means that the value of the exit code used by
+L<C<die>|/die LIST> can be non-predictable, so should not be relied
upon, other than to be non-zero.
-You can also call C<die> with a reference argument, and if this is trapped
-within an C<eval>, C<$@> contains that reference. This permits more
-elaborate exception handling using objects that maintain arbitrary state
-about the exception. Such a scheme is sometimes preferable to matching
-particular string values of C<$@> with regular expressions. Because C<$@>
-is a global variable and C<eval> may be used within object implementations,
-be careful that analyzing the error object doesn't replace the reference in
-the global variable. It's easiest to make a local copy of the reference
-before any manipulations. Here's an example:
+You can also call L<C<die>|/die LIST> with a reference argument, and if
+this is trapped within an L<C<eval>|/eval EXPR>, L<C<$@>|perlvar/$@>
+contains that reference. This permits more elaborate exception handling
+using objects that maintain arbitrary state about the exception. Such a
+scheme is sometimes preferable to matching particular string values of
+L<C<$@>|perlvar/$@> with regular expressions. Because
+L<C<$@>|perlvar/$@> is a global variable and L<C<eval>|/eval EXPR> may
+be used within object implementations, be careful that analyzing the
+error object doesn't replace the reference in the global variable. It's
+easiest to make a local copy of the reference before any manipulations.
+Here's an example:
use Scalar::Util "blessed";
you'll probably want to overload stringification operations on
exception objects. See L<overload> for details about that.
-You can arrange for a callback to be run just before the C<die>
-does its deed, by setting the C<$SIG{__DIE__}> hook. The associated
-handler is called with the error text and can change the error
-message, if it sees fit, by calling C<die> again. See
-L<perlvar/%SIG> for details on setting C<%SIG> entries, and
-L<"eval BLOCK"> for some examples. Although this feature was
-to be run only right before your program was to exit, this is not
-currently so: the C<$SIG{__DIE__}> hook is currently called
-even inside eval()ed blocks/strings! If one wants the hook to do
+You can arrange for a callback to be run just before the
+L<C<die>|/die LIST> does its deed, by setting the
+L<C<$SIG{__DIE__}>|perlvar/%SIG> hook. The associated handler is called
+with the error text and can change the error message, if it sees fit, by
+calling L<C<die>|/die LIST> again. See L<perlvar/%SIG> for details on
+setting L<C<%SIG>|perlvar/%SIG> entries, and L<C<eval>|/eval EXPR> for some
+examples. Although this feature was to be run only right before your
+program was to exit, this is not currently so: the
+L<C<$SIG{__DIE__}>|perlvar/%SIG> hook is currently called even inside
+L<C<eval>|/eval EXPR>ed blocks/strings! If one wants the hook to do
nothing in such situations, put
die @_ if $^S;
this promotes strange action at a distance, this counterintuitive
behavior may be fixed in a future release.
-See also exit(), warn(), and the Carp module.
+See also L<C<exit>|/exit EXPR>, L<C<warn>|/warn LIST>, and the L<Carp>
+module.
=item do BLOCK
X<do> X<block>
first.)
C<do BLOCK> does I<not> count as a loop, so the loop control statements
-C<next>, C<last>, or C<redo> cannot be used to leave or restart the block.
+L<C<next>|/next LABEL>, L<C<last>|/last LABEL>, or
+L<C<redo>|/redo LABEL> cannot be used to leave or restart the block.
See L<perlsyn> for alternative strategies.
=item do EXPR
eval `cat stat.pl`;
except that it's more concise, runs no external processes, keeps track of
-the current
-filename for error messages, searches the C<@INC> directories, and updates
-C<%INC> if the file is found. See L<perlvar/@INC> and L<perlvar/%INC> for
-these variables. It also differs in that code evaluated with C<do FILENAME>
-cannot see lexicals in the enclosing scope; C<eval STRING> does. It's the
-same, however, in that it does reparse the file every time you call it,
-so you probably don't want to do this inside a loop.
-
-If C<do> can read the file but cannot compile it, it returns C<undef> and sets
-an error message in C<$@>. If C<do> cannot read the file, it returns undef
-and sets C<$!> to the error. Always check C<$@> first, as compilation
-could fail in a way that also sets C<$!>. If the file is successfully
-compiled, C<do> returns the value of the last expression evaluated.
+the current filename for error messages, searches the
+L<C<@INC>|perlvar/@INC> directories, and updates L<C<%INC>|perlvar/%INC>
+if the file is found. See L<perlvar/@INC> and L<perlvar/%INC> for these
+variables. It also differs in that code evaluated with C<do FILE>
+cannot see lexicals in the enclosing scope; C<eval STRING> does. It's
+the same, however, in that it does reparse the file every time you call
+it, so you probably don't want to do this inside a loop.
+
+If L<C<do>|/do EXPR> can read the file but cannot compile it, it
+returns L<C<undef>|/undef EXPR> and sets an error message in
+L<C<$@>|perlvar/$@>. If L<C<do>|/do EXPR> cannot read the file, it
+returns undef and sets L<C<$!>|perlvar/$!> to the error. Always check
+L<C<$@>|perlvar/$@> first, as compilation could fail in a way that also
+sets L<C<$!>|perlvar/$!>. If the file is successfully compiled,
+L<C<do>|/do EXPR> returns the value of the last expression evaluated.
Inclusion of library modules is better done with the
-C<use> and C<require> operators, which also do automatic error checking
-and raise an exception if there's a problem.
+L<C<use>|/use Module VERSION LIST> and L<C<require>|/require VERSION>
+operators, which also do automatic error checking and raise an exception
+if there's a problem.
-You might like to use C<do> to read in a program configuration
-file. Manual error checking can be done this way:
+You might like to use L<C<do>|/do EXPR> to read in a program
+configuration file. Manual error checking can be done this way:
# read in config files: system first, then user
for $file ("/share/prog/defaults.rc",
supplied) to turn your core dump into an executable binary after
having initialized all your variables at the beginning of the
program. When the new binary is executed it will begin by executing
-a C<goto LABEL> (with all the restrictions that C<goto> suffers).
+a C<goto LABEL> (with all the restrictions that L<C<goto>|/goto LABEL>
+suffers).
Think of it as a goto with an intervening core dump and reincarnation.
If C<LABEL> is omitted, restarts the program from the top. The
C<dump EXPR> form, available starting in Perl 5.18.0, allows a name to be
This function is now largely obsolete, mostly because it's very hard to
convert a core file into an executable. That's why you should now invoke
-it as C<CORE::dump()>, if you don't want to be warned against a possible
+it as C<CORE::dump()> if you don't want to be warned against a possible
typo.
Unlike most named operators, this has the same precedence as assignment.
It is also exempt from the looks-like-a-function rule, so
C<dump ("foo")."bar"> will cause "bar" to be part of the argument to
-C<dump>.
+L<C<dump>|/dump LABEL>.
Portability issues: L<perlport/dump>.
order is specific to a given hash; the exact same series of operations
on two hashes may result in a different order for each hash. Any insertion
into the hash may change the order, as will any deletion, with the exception
-that the most recent key returned by C<each> or C<keys> may be deleted
-without changing the order. So long as a given hash is unmodified you may
-rely on C<keys>, C<values> and C<each> to repeatedly return the same order
+that the most recent key returned by L<C<each>|/each HASH> or
+L<C<keys>|/keys HASH> may be deleted without changing the order. So
+long as a given hash is unmodified you may rely on
+L<C<keys>|/keys HASH>, L<C<values>|/values HASH> and
+L<C<each>|/each HASH> to repeatedly return the same order
as each other. See L<perlsec/"Algorithmic Complexity Attacks"> for
details on why hash order is randomized. Aside from the guarantees
provided here the exact details of Perl's hash algorithm and the hash
traversal order are subject to change in any release of Perl.
-After C<each> has returned all entries from the hash or array, the next
-call to C<each> returns the empty list in list context and C<undef> in
-scalar context; the next call following I<that> one restarts iteration.
-Each hash or array has its own internal iterator, accessed by C<each>,
-C<keys>, and C<values>. The iterator is implicitly reset when C<each> has
-reached the end as just described; it can be explicitly reset by calling
-C<keys> or C<values> on the hash or array. If you add or delete a hash's
-elements while iterating over it, the effect on the iterator is
+After L<C<each>|/each HASH> has returned all entries from the hash or
+array, the next call to L<C<each>|/each HASH> returns the empty list in
+list context and L<C<undef>|/undef EXPR> in scalar context; the next
+call following I<that> one restarts iteration. Each hash or array has
+its own internal iterator, accessed by L<C<each>|/each HASH>,
+L<C<keys>|/keys HASH>, and L<C<values>|/values HASH>. The iterator is
+implicitly reset when L<C<each>|/each HASH> has reached the end as just
+described; it can be explicitly reset by calling L<C<keys>|/keys HASH>
+or L<C<values>|/values HASH> on the hash or array. If you add or delete
+a hash's elements while iterating over it, the effect on the iterator is
unspecified; for example, entries may be skipped or duplicated--so don't
do that. Exception: It is always safe to delete the item most recently
-returned by C<each()>, so the following code works properly:
+returned by L<C<each>|/each HASH>, so the following code works properly:
- while (($key, $value) = each %hash) {
- print $key, "\n";
- delete $hash{$key}; # This is safe
- }
+ while (my ($key, $value) = each %hash) {
+ print $key, "\n";
+ delete $hash{$key}; # This is safe
+ }
Tied hashes may have a different ordering behaviour to perl's hash
implementation.
-This prints out your environment like the printenv(1) program,
+This prints out your environment like the L<printenv(1)> program,
but in a different order:
- while (($key,$value) = each %ENV) {
+ while (my ($key,$value) = each %ENV) {
print "$key=$value\n";
}
-Starting with Perl 5.14, an experimental feature allowed C<each> to take a
-scalar expression. This experiment has been deemed unsuccessful, and was
-removed as of Perl 5.24.
+Starting with Perl 5.14, an experimental feature allowed
+L<C<each>|/each HASH> to take a scalar expression. This experiment has
+been deemed unsuccessful, and was removed as of Perl 5.24.
-As of Perl 5.18 you can use a bare C<each> in a C<while> loop,
-which will set C<$_> on every iteration.
+As of Perl 5.18 you can use a bare L<C<each>|/each HASH> in a C<while>
+loop, which will set L<C<$_>|perlvar/$_> on every iteration.
- while(each %ENV) {
+ while (each %ENV) {
print "$_=$ENV{$_}\n";
}
use 5.012; # so keys/values/each work on arrays
use 5.018; # so each assigns to $_ in a lone while test
-See also C<keys>, C<values>, and C<sort>.
+See also L<C<keys>|/keys HASH>, L<C<values>|/values HASH>, and
+L<C<sort>|/sort SUBNAME LIST>.
=item eof FILEHANDLE
X<eof>
C<eof(FILEHANDLE)> on it) after end-of-file is reached. File types such
as terminals may lose the end-of-file condition if you do.
-An C<eof> without an argument uses the last file read. Using C<eof()>
-with empty parentheses is different. It refers to the pseudo file
-formed from the files listed on the command line and accessed via the
-C<< <> >> operator. Since C<< <> >> isn't explicitly opened,
-as a normal filehandle is, an C<eof()> before C<< <> >> has been
-used will cause C<@ARGV> to be examined to determine if input is
-available. Similarly, an C<eof()> after C<< <> >> has returned
-end-of-file will assume you are processing another C<@ARGV> list,
-and if you haven't set C<@ARGV>, will read input from C<STDIN>;
-see L<perlop/"I/O Operators">.
-
-In a C<< while (<>) >> loop, C<eof> or C<eof(ARGV)> can be used to
-detect the end of each file, whereas C<eof()> will detect the end
-of the very last file only. Examples:
+An L<C<eof>|/eof FILEHANDLE> without an argument uses the last file
+read. Using L<C<eof()>|/eof FILEHANDLE> with empty parentheses is
+different. It refers to the pseudo file formed from the files listed on
+the command line and accessed via the C<< <> >> operator. Since
+C<< <> >> isn't explicitly opened, as a normal filehandle is, an
+L<C<eof()>|/eof FILEHANDLE> before C<< <> >> has been used will cause
+L<C<@ARGV>|perlvar/@ARGV> to be examined to determine if input is
+available. Similarly, an L<C<eof()>|/eof FILEHANDLE> after C<< <> >>
+has returned end-of-file will assume you are processing another
+L<C<@ARGV>|perlvar/@ARGV> list, and if you haven't set
+L<C<@ARGV>|perlvar/@ARGV>, will read input from C<STDIN>; see
+L<perlop/"I/O Operators">.
+
+In a C<< while (<>) >> loop, L<C<eof>|/eof FILEHANDLE> or C<eof(ARGV)>
+can be used to detect the end of each file, whereas
+L<C<eof()>|/eof FILEHANDLE> will detect the end of the very last file
+only. Examples:
# reset line numbering on each input file
while (<>) {
last if eof(); # needed if we're reading from a terminal
}
-Practical hint: you almost never need to use C<eof> in Perl, because the
-input operators typically return C<undef> when they run out of data or
-encounter an error.
+Practical hint: you almost never need to use L<C<eof>|/eof FILEHANDLE>
+in Perl, because the input operators typically return L<C<undef>|/undef
+EXPR> when they run out of data or encounter an error.
=item eval EXPR
X<eval> X<try> X<catch> X<evaluate> X<parse> X<execute>
visible to it, and any package variable settings or subroutine and format
definitions remain afterwards.
-Note that the value is parsed every time the C<eval> executes.
-If EXPR is omitted, evaluates C<$_>. This form is typically used to
-delay parsing and subsequent execution of the text of EXPR until run time.
-
-If the C<unicode_eval> feature is enabled (which is the default under a
-C<use 5.16> or higher declaration), EXPR or C<$_> is treated as a string of
-characters, so C<use utf8> declarations have no effect, and source filters
-are forbidden. In the absence of the C<unicode_eval> feature, the string
-will sometimes be treated as characters and sometimes as bytes, depending
-on the internal encoding, and source filters activated within the C<eval>
-exhibit the erratic, but historical, behaviour of affecting some outer file
-scope that is still compiling. See also the L</evalbytes> keyword, which
-always treats its input as a byte stream and works properly with source
-filters, and the L<feature> pragma.
+Note that the value is parsed every time the L<C<eval>|/eval EXPR>
+executes. If EXPR is omitted, evaluates L<C<$_>|perlvar/$_>. This form
+is typically used to delay parsing and subsequent execution of the text
+of EXPR until run time.
+
+If the
+L<C<"unicode_eval"> feature|feature/The 'unicode_eval' and 'evalbytes' features>
+is enabled (which is the default under a
+C<use 5.16> or higher declaration), EXPR or L<C<$_>|perlvar/$_> is
+treated as a string of characters, so L<C<use utf8>|utf8> declarations
+have no effect, and source filters are forbidden. In the absence of the
+L<C<"unicode_eval"> feature|feature/The 'unicode_eval' and 'evalbytes' features>,
+will sometimes be treated as characters and sometimes as bytes,
+depending on the internal encoding, and source filters activated within
+the L<C<eval>|/eval EXPR> exhibit the erratic, but historical, behaviour
+of affecting some outer file scope that is still compiling. See also
+the L<C<evalbytes>|/evalbytes EXPR> operator, which always treats its
+input as a byte stream and works properly with source filters, and the
+L<feature> pragma.
Problems can arise if the string expands a scalar containing a floating
point number. That scalar can expand to letters, such as C<"NaN"> or
-C<"Infinity">; or, within the scope of a C<use locale>, the decimal
-point character may be something other than a dot (such as a comma).
-None of these are likely to parse as you are likely expecting.
+C<"Infinity">; or, within the scope of a L<C<use locale>|locale>, the
+decimal point character may be something other than a dot (such as a
+comma). None of these are likely to parse as you are likely expecting.
In the second form, the code within the BLOCK is parsed only once--at the
-same time the code surrounding the C<eval> itself was parsed--and executed
+same time the code surrounding the L<C<eval>|/eval EXPR> itself was
+parsed--and executed
within the context of the current Perl program. This form is typically
used to trap exceptions more efficiently than the first (see below), while
also providing the benefit of checking the code within BLOCK at compile
In both forms, the value returned is the value of the last expression
evaluated inside the mini-program; a return statement may be also used, just
as with subroutines. The expression providing the return value is evaluated
-in void, scalar, or list context, depending on the context of the C<eval>
-itself. See L</wantarray> for more on how the evaluation context can be
-determined.
-
-If there is a syntax error or runtime error, or a C<die> statement is
-executed, C<eval> returns C<undef> in scalar context
-or an empty list in list context, and C<$@> is set to the error
-message. (Prior to 5.16, a bug caused C<undef> to be returned
-in list context for syntax errors, but not for runtime errors.)
-If there was no error, C<$@> is set to the empty string. A
-control flow operator like C<last> or C<goto> can bypass the setting of
-C<$@>. Beware that using C<eval> neither silences Perl from printing
-warnings to STDERR, nor does it stuff the text of warning messages into C<$@>.
-To do either of those, you have to use the C<$SIG{__WARN__}> facility, or
-turn off warnings inside the BLOCK or EXPR using S<C<no warnings 'all'>>.
-See L</warn>, L<perlvar>, and L<warnings>.
-
-Note that, because C<eval> traps otherwise-fatal errors, it is useful for
-determining whether a particular feature (such as C<socket> or C<symlink>)
-is implemented. It is also Perl's exception-trapping mechanism, where
-the die operator is used to raise exceptions.
+in void, scalar, or list context, depending on the context of the
+L<C<eval>|/eval EXPR> itself. See L<C<wantarray>|/wantarray> for more
+on how the evaluation context can be determined.
+
+If there is a syntax error or runtime error, or a L<C<die>|/die LIST>
+statement is executed, L<C<eval>|/eval EXPR> returns
+L<C<undef>|/undef EXPR> in scalar context or an empty list in list
+context, and L<C<$@>|perlvar/$@> is set to the error message. (Prior to
+5.16, a bug caused L<C<undef>|/undef EXPR> to be returned in list
+context for syntax errors, but not for runtime errors.) If there was no
+error, L<C<$@>|perlvar/$@> is set to the empty string. A control flow
+operator like L<C<last>|/last LABEL> or L<C<goto>|/goto LABEL> can
+bypass the setting of L<C<$@>|perlvar/$@>. Beware that using
+L<C<eval>|/eval EXPR> neither silences Perl from printing warnings to
+STDERR, nor does it stuff the text of warning messages into
+L<C<$@>|perlvar/$@>. To do either of those, you have to use the
+L<C<$SIG{__WARN__}>|perlvar/%SIG> facility, or turn off warnings inside
+the BLOCK or EXPR using S<C<no warnings 'all'>>. See
+L<C<warn>|/warn LIST>, L<perlvar>, and L<warnings>.
+
+Note that, because L<C<eval>|/eval EXPR> traps otherwise-fatal errors,
+it is useful for determining whether a particular feature (such as
+L<C<socket>|/socket SOCKET,DOMAIN,TYPE,PROTOCOL> or
+L<C<symlink>|/symlink OLDFILE,NEWFILE>) is implemented. It is also
+Perl's exception-trapping mechanism, where the L<C<die>|/die LIST>
+operator is used to raise exceptions.
If you want to trap errors when loading an XS module, some problems with
the binary interface (such as Perl version skew) may be fatal even with
-C<eval> unless C<$ENV{PERL_DL_NONLAZY}> is set. See L<perlrun>.
+L<C<eval>|/eval EXPR> unless C<$ENV{PERL_DL_NONLAZY}> is set. See
+L<perlrun>.
If the code to be executed doesn't vary, you may use the eval-BLOCK
form to trap run-time errors without incurring the penalty of
-recompiling each time. The error, if any, is still returned in C<$@>.
+recompiling each time. The error, if any, is still returned in
+L<C<$@>|perlvar/$@>.
Examples:
# make divide-by-zero nonfatal
# a run-time error
eval '$answer ='; # sets $@
-Using the C<eval{}> form as an exception trap in libraries does have some
+Using the C<eval {}> form as an exception trap in libraries does have some
issues. Due to the current arguably broken state of C<__DIE__> hooks, you
may wish not to trigger any C<__DIE__> hooks that user code may have installed.
You can use the C<local $SIG{__DIE__}> construct for this purpose,
warn $@ if $@;
This is especially significant, given that C<__DIE__> hooks can call
-C<die> again, which has the effect of changing their error messages:
+L<C<die>|/die LIST> again, which has the effect of changing their error
+messages:
# __DIE__ hooks may modify error messages
{
Because this promotes action at a distance, this counterintuitive behavior
may be fixed in a future release.
-With an C<eval>, you should be especially careful to remember what's
-being looked at when:
+With an L<C<eval>|/eval EXPR>, you should be especially careful to
+remember what's being looked at when:
eval $x; # CASE 1
eval "$x"; # CASE 2
particular situation, you can just use symbolic references instead, as
in case 6.
-Before Perl 5.14, the assignment to C<$@> occurred before restoration
+Before Perl 5.14, the assignment to L<C<$@>|perlvar/$@> occurred before
+restoration
of localized variables, which means that for your code to run on older
versions, a temporary is required if you want to mask some but not all
errors:
}
C<eval BLOCK> does I<not> count as a loop, so the loop control statements
-C<next>, C<last>, or C<redo> cannot be used to leave or restart the block.
+L<C<next>|/next LABEL>, L<C<last>|/last LABEL>, or
+L<C<redo>|/redo LABEL> cannot be used to leave or restart the block.
An C<eval ''> executed within a subroutine defined
in the C<DB> package doesn't see the usual
=for Pod::Functions +evalbytes similar to string eval, but intend to parse a bytestream
-This function is like L</eval> with a string argument, except it always
-parses its argument, or C<$_> if EXPR is omitted, as a string of bytes. A
-string containing characters whose ordinal value exceeds 255 results in an
-error. Source filters activated within the evaluated code apply to the
-code itself.
+This function is like L<C<eval>|/eval EXPR> with a string argument,
+except it always parses its argument, or L<C<$_>|perlvar/$_> if EXPR is
+omitted, as a string of bytes. A string containing characters whose
+ordinal value exceeds 255 results in an error. Source filters activated
+within the evaluated code apply to the code itself.
-This function is only available under the C<evalbytes> feature, a
-C<use v5.16> (or higher) declaration, or with a C<CORE::> prefix. See
-L<feature> for more information.
+L<C<evalbytes>|/evalbytes EXPR> is available only if the
+L<C<"evalbytes"> feature|feature/The 'unicode_eval' and 'evalbytes' features>
+is enabled or if it is prefixed with C<CORE::>. The
+L<C<"evalbytes"> feature|feature/The 'unicode_eval' and 'evalbytes' features>
+is enabled automatically with a C<use v5.16> (or higher) declaration in
+the current scope.
=item exec LIST
X<exec> X<execute>
=for Pod::Functions abandon this program to run another
-The C<exec> function executes a system command I<and never returns>;
-use C<system> instead of C<exec> if you want it to return. It fails and
+The L<C<exec>|/exec LIST> function executes a system command I<and never
+returns>; use L<C<system>|/system LIST> instead of L<C<exec>|/exec LIST>
+if you want it to return. It fails and
returns false only if the command does not exist I<and> it is executed
directly instead of via your system's command shell (see below).
-Since it's a common mistake to use C<exec> instead of C<system>, Perl
-warns you if C<exec> is called in void context and if there is a following
-statement that isn't C<die>, C<warn>, or C<exit> (if C<-w> is set--but
-you always do that, right?). If you I<really> want to follow an C<exec>
-with some other statement, you can use one of these styles to avoid the warning:
+Since it's a common mistake to use L<C<exec>|/exec LIST> instead of
+L<C<system>|/system LIST>, Perl warns you if L<C<exec>|/exec LIST> is
+called in void context and if there is a following statement that isn't
+L<C<die>|/die LIST>, L<C<warn>|/warn LIST>, or L<C<exit>|/exit EXPR> (if
+L<warnings> are enabled--but you always do that, right?). If you
+I<really> want to follow an L<C<exec>|/exec LIST> with some other
+statement, you can use one of these styles to avoid the warning:
exec ('foo') or print STDERR "couldn't exec foo: $!";
{ exec ('foo') }; print STDERR "couldn't exec foo: $!";
-If there is more than one argument in LIST, this calls execvp(3) with the
+If there is more than one argument in LIST, this calls L<execvp(3)> with the
arguments in LIST. If there is only one element in LIST, the argument is
checked for shell metacharacters, and if there are any, the entire
argument is passed to the system's command shell for parsing (this is
forces interpretation of the LIST as a multivalued list, even if there
is only a single scalar in the list.) Example:
- $shell = '/bin/csh';
+ my $shell = '/bin/csh';
exec $shell '-sh'; # pretend it's a login shell
or, more directly,
subject to its quirks and capabilities. See L<perlop/"`STRING`">
for details.
-Using an indirect object with C<exec> or C<system> is also more
-secure. This usage (which also works fine with system()) forces
+Using an indirect object with L<C<exec>|/exec LIST> or
+L<C<system>|/system LIST> is also more secure. This usage (which also
+works fine with L<C<system>|/system LIST>) forces
interpretation of the arguments as a multivalued list, even if the
list had just one argument. That way you're safe from the shell
expanding wildcards or splitting up words with whitespace in them.
- @args = ( "echo surprise" );
+ my @args = ( "echo surprise" );
exec @args; # subject to shell escapes
# if @args == 1
The first version, the one without the indirect object, ran the I<echo>
program, passing it C<"surprise"> an argument. The second version didn't;
it tried to run a program named I<"echo surprise">, didn't find it, and set
-C<$?> to a non-zero value indicating failure.
+L<C<$?>|perlvar/$?> to a non-zero value indicating failure.
On Windows, only the C<exec PROGRAM LIST> indirect object syntax will
reliably avoid using the shell; C<exec LIST>, even with more than one
Perl attempts to flush all files opened for output before the exec,
but this may not be supported on some platforms (see L<perlport>).
-To be safe, you may need to set C<$|> ($AUTOFLUSH in English) or
-call the C<autoflush()> method of C<IO::Handle> on any open handles
-to avoid lost output.
+To be safe, you may need to set L<C<$E<verbar>>|perlvar/$E<verbar>>
+(C<$AUTOFLUSH> in L<English>) or call the C<autoflush> method of
+L<C<IO::Handle>|IO::Handle/METHODS> on any open handles to avoid lost
+output.
-Note that C<exec> will not call your C<END> blocks, nor will it invoke
-C<DESTROY> methods on your objects.
+Note that L<C<exec>|/exec LIST> will not call your C<END> blocks, nor
+will it invoke C<DESTROY> methods on your objects.
Portability issues: L<perlport/exec>.
print "True\n" if $hash{$key};
exists may also be called on array elements, but its behavior is much less
-obvious and is strongly tied to the use of L</delete> on arrays.
+obvious and is strongly tied to the use of L<C<delete>|/delete EXPR> on
+arrays.
-B<WARNING:> Calling C<exists> on array values is strongly discouraged. The
+B<WARNING:> Calling L<C<exists>|/exists EXPR> on array values is
+strongly discouraged. The
notion of deleting or checking the existence of Perl array elements is not
conceptually coherent, and can lead to surprising behavior.
Although the most deeply nested array or hash element will not spring into
existence just because its existence was tested, any intervening ones will.
Thus C<< $ref->{"A"} >> and C<< $ref->{"A"}->{"B"} >> will spring
-into existence due to the existence test for the $key element above.
+into existence due to the existence test for the C<$key> element above.
This happens anywhere the arrow operator is used, including even here:
undef $ref;
release.
Use of a subroutine call, rather than a subroutine name, as an argument
-to exists() is an error.
+to L<C<exists>|/exists EXPR> is an error.
exists ⊂ # OK
exists &sub(); # Error
Evaluates EXPR and exits immediately with that value. Example:
- $ans = <STDIN>;
+ my $ans = <STDIN>;
exit 0 if $ans =~ /^[Xx]/;
-See also C<die>. If EXPR is omitted, exits with C<0> status. The only
+See also L<C<die>|/die LIST>. If EXPR is omitted, exits with C<0>
+status. The only
universally recognized values for EXPR are C<0> for success and C<1>
for error; other values are subject to interpretation depending on the
environment in which the Perl program is running. For example, exiting
69 (EX_UNAVAILABLE) from a I<sendmail> incoming-mail filter will cause
the mailer to return the item undelivered, but that's not true everywhere.
-Don't use C<exit> to abort a subroutine if there's any chance that
-someone might want to trap whatever error happened. Use C<die> instead,
-which can be trapped by an C<eval>.
+Don't use L<C<exit>|/exit EXPR> to abort a subroutine if there's any
+chance that someone might want to trap whatever error happened. Use
+L<C<die>|/die LIST> instead, which can be trapped by an
+L<C<eval>|/eval EXPR>.
-The exit() function does not always exit immediately. It calls any
-defined C<END> routines first, but these C<END> routines may not
-themselves abort the exit. Likewise any object destructors that need to
-be called are called before the real exit. C<END> routines and destructors
-can change the exit status by modifying C<$?>. If this is a problem, you
-can call C<POSIX::_exit($status)> to avoid END and destructor processing.
-See L<perlmod> for details.
+The L<C<exit>|/exit EXPR> function does not always exit immediately. It
+calls any defined C<END> routines first, but these C<END> routines may
+not themselves abort the exit. Likewise any object destructors that
+need to be called are called before the real exit. C<END> routines and
+destructors can change the exit status by modifying L<C<$?>|perlvar/$?>.
+If this is a problem, you can call
+L<C<POSIX::_exit($status)>|POSIX/C<_exit>> to avoid C<END> and destructor
+processing. See L<perlmod> for details.
Portability issues: L<perlport/exit>.
And get the correct results.
-Perl only implements the full form of casefolding,
-but you can access the simple folds using L<Unicode::UCD/casefold()> and
-L<Unicode::UCD/prop_invmap()>.
+Perl only implements the full form of casefolding, but you can access
+the simple folds using L<Unicode::UCD/B<casefold()>> and
+L<Unicode::UCD/B<prop_invmap()>>.
For further information on casefolding, refer to
the Unicode Standard, specifically sections 3.13 C<Default Case Operations>,
4.2 C<Case-Normative>, and 5.18 C<Case Mappings>,
available at L<http://www.unicode.org/versions/latest/>, as well as the
Case Charts available at L<http://www.unicode.org/charts/case/>.
-If EXPR is omitted, uses C<$_>.
+If EXPR is omitted, uses L<C<$_>|perlvar/$_>.
-This function behaves the same way under various pragma, such as within
-S<C<"use feature 'unicode_strings">>, as L</lc> does, with the single
-exception of C<fc> of LATIN CAPITAL LETTER SHARP S (U+1E9E) within the
-scope of S<C<use locale>>. The foldcase of this character would
-normally be C<"ss">, but as explained in the L</lc> section, case
+This function behaves the same way under various pragmas, such as within
+L<S<C<"use feature 'unicode_strings">>|feature/The 'unicode_strings' feature>,
+as L<C<lc>|/lc EXPR> does, with the single exception of
+L<C<fc>|/fc EXPR> of I<LATIN CAPITAL LETTER SHARP S> (U+1E9E) within the
+scope of L<S<C<use locale>>|locale>. The foldcase of this character
+would normally be C<"ss">, but as explained in the L<C<lc>|/lc EXPR>
+section, case
changes that cross the 255/256 boundary are problematic under locales,
and are hence prohibited. Therefore, this function under locale returns
-instead the string C<"\x{17F}\x{17F}">, which is the LATIN SMALL LETTER
-LONG S. Since that character itself folds to C<"s">, the string of two
+instead the string C<"\x{17F}\x{17F}">, which is the I<LATIN SMALL LETTER
+LONG S>. Since that character itself folds to C<"s">, the string of two
of them together should be equivalent to a single U+1E9E when foldcased.
While the Unicode Standard defines two additional forms of casefolding,
one for Turkic languages and one that never maps one character into multiple
-characters, these are not provided by the Perl core; However, the CPAN module
-C<Unicode::Casing> may be used to provide an implementation.
+characters, these are not provided by the Perl core. However, the CPAN module
+L<C<Unicode::Casing>|Unicode::Casing> may be used to provide an implementation.
-This keyword is available only when the C<"fc"> feature is enabled,
-or when prefixed with C<CORE::>; See L<feature>. Alternately,
-include a C<use v5.16> or later to the current scope.
+L<C<fc>|/fc EXPR> is available only if the
+L<C<"fc"> feature|feature/The 'fc' feature> is enabled or if it is
+prefixed with C<CORE::>. The
+L<C<"fc"> feature|feature/The 'fc' feature> is enabled automatically
+with a C<use v5.16> (or higher) declaration in the current scope.
=item fcntl FILEHANDLE,FUNCTION,SCALAR
X<fcntl>
=for Pod::Functions file control system call
-Implements the fcntl(2) function. You'll probably have to say
+Implements the L<fcntl(2)> function. You'll probably have to say
use Fcntl;
first to get the correct constant definitions. Argument processing and
-value returned work just like C<ioctl> below.
-For example:
+value returned work just like L<C<ioctl>|/ioctl
+FILEHANDLE,FUNCTION,SCALAR> below. For example:
use Fcntl;
my $flags = fcntl($filehandle, F_GETFL, 0)
- or die "can't fcntl F_GETFL: $!";
-
-You don't have to check for C<defined> on the return from C<fcntl>.
-Like C<ioctl>, it maps a C<0> return from the system call into
-C<"0 but true"> in Perl. This string is true in boolean context and C<0>
-in numeric context. It is also exempt from the normal B<-w> warnings
-on improper numeric conversions.
-
-Note that C<fcntl> raises an exception if used on a machine that
-doesn't implement fcntl(2). See the Fcntl module or your fcntl(2)
-manpage to learn what functions are available on your system.
-
-Here's an example of setting a filehandle named C<REMOTE> to be
-non-blocking at the system level. You'll have to negotiate C<$|>
-on your own, though.
+ or die "Can't fcntl F_GETFL: $!";
+
+You don't have to check for L<C<defined>|/defined EXPR> on the return
+from L<C<fcntl>|/fcntl FILEHANDLE,FUNCTION,SCALAR>. Like
+L<C<ioctl>|/ioctl FILEHANDLE,FUNCTION,SCALAR>, it maps a C<0> return
+from the system call into C<"0 but true"> in Perl. This string is true
+in boolean context and C<0> in numeric context. It is also exempt from
+the normal
+L<C<Argument "..." isn't numeric>|perldiag/Argument "%s" isn't numeric%s>
+L<warnings> on improper numeric conversions.
+
+Note that L<C<fcntl>|/fcntl FILEHANDLE,FUNCTION,SCALAR> raises an
+exception if used on a machine that doesn't implement L<fcntl(2)>. See
+the L<Fcntl> module or your L<fcntl(2)> manpage to learn what functions
+are available on your system.
+
+Here's an example of setting a filehandle named C<$REMOTE> to be
+non-blocking at the system level. You'll have to negotiate
+L<C<$E<verbar>>|perlvar/$E<verbar>> on your own, though.
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
- $flags = fcntl(REMOTE, F_GETFL, 0)
- or die "Can't get flags for the socket: $!\n";
+ my $flags = fcntl($REMOTE, F_GETFL, 0)
+ or die "Can't get flags for the socket: $!\n";
- $flags = fcntl(REMOTE, F_SETFL, $flags | O_NONBLOCK)
- or die "Can't set flags for the socket: $!\n";
+ fcntl($REMOTE, F_SETFL, $flags | O_NONBLOCK)
+ or die "Can't set flags for the socket: $!\n";
Portability issues: L<perlport/fcntl>.
Returns the file descriptor for a filehandle, or undefined if the
filehandle is not open. If there is no real file descriptor at the OS
level, as can happen with filehandles connected to memory objects via
-C<open> with a reference for the third argument, -1 is returned.
+L<C<open>|/open FILEHANDLE,EXPR> with a reference for the third
+argument, -1 is returned.
-This is mainly useful for constructing
-bitmaps for C<select> and low-level POSIX tty-handling operations.
+This is mainly useful for constructing bitmaps for
+L<C<select>|/select RBITS,WBITS,EBITS,TIMEOUT> and low-level POSIX
+tty-handling operations.
If FILEHANDLE is an expression, the value is taken as an indirect
filehandle, generally its name.
You can use this to find out whether two handles refer to the
same underlying descriptor:
- if (fileno(THIS) != -1 && fileno(THIS) == fileno(THAT)) {
- print "THIS and THAT are dups\n";
- } elsif (fileno(THIS) != -1 && fileno(THAT) != -1) {
- print "THIS and THAT have different " .
+ if (fileno($this) != -1 && fileno($this) == fileno($that)) {
+ print "\$this and \$that are dups\n";
+ } elsif (fileno($this) != -1 && fileno($that) != -1) {
+ print "\$this and \$that have different " .
"underlying file descriptors\n";
} else {
- print "At least one of THIS and THAT does " .
+ print "At least one of \$this and \$that does " .
"not have a real file descriptor\n";
}
-The behavior of C<fileno> on a directory handle depends on the operating
-system. On a system with dirfd(3) or similar, C<fileno> on a directory
+The behavior of L<C<fileno>|/fileno FILEHANDLE> on a directory handle
+depends on the operating system. On a system with L<dirfd(3)> or
+similar, L<C<fileno>|/fileno FILEHANDLE> on a directory
handle returns the underlying file descriptor associated with the
handle; on systems with no such support, it returns the undefined value,
-and sets C<$!> (errno).
+and sets L<C<$!>|perlvar/$!> (errno).
=item flock FILEHANDLE,OPERATION
X<flock> X<lock> X<locking>
=for Pod::Functions lock an entire file with an advisory lock
-Calls flock(2), or an emulation of it, on FILEHANDLE. Returns true
+Calls L<flock(2)>, or an emulation of it, on FILEHANDLE. Returns true
for success, false on failure. Produces a fatal error if used on a
-machine that doesn't implement flock(2), fcntl(2) locking, or lockf(3).
-C<flock> is Perl's portable file-locking interface, although it locks
-entire files only, not records.
+machine that doesn't implement L<flock(2)>, L<fcntl(2)> locking, or
+L<lockf(3)>. L<C<flock>|/flock FILEHANDLE,OPERATION> is Perl's portable
+file-locking interface, although it locks entire files only, not
+records.
-Two potentially non-obvious but traditional C<flock> semantics are
+Two potentially non-obvious but traditional L<C<flock>|/flock
+FILEHANDLE,OPERATION> semantics are
that it waits indefinitely until the lock is granted, and that its locks
are B<merely advisory>. Such discretionary locks are more flexible, but
offer fewer guarantees. This means that programs that do not also use
-C<flock> may modify files locked with C<flock>. See L<perlport>,
+L<C<flock>|/flock FILEHANDLE,OPERATION> may modify files locked with
+L<C<flock>|/flock FILEHANDLE,OPERATION>. See L<perlport>,
your port's specific documentation, and your system-specific local manpages
for details. It's best to assume traditional behavior if you're writing
portable programs. (But if you're not, you should as always feel perfectly
either individually, or as a group using the C<:flock> tag. LOCK_SH
requests a shared lock, LOCK_EX requests an exclusive lock, and LOCK_UN
releases a previously requested lock. If LOCK_NB is bitwise-or'ed with
-LOCK_SH or LOCK_EX, then C<flock> returns immediately rather than blocking
-waiting for the lock; check the return status to see if you got it.
+LOCK_SH or LOCK_EX, then L<C<flock>|/flock FILEHANDLE,OPERATION> returns
+immediately rather than blocking waiting for the lock; check the return
+status to see if you got it.
To avoid the possibility of miscoordination, Perl now flushes FILEHANDLE
before locking or unlocking it.
-Note that the emulation built with lockf(3) doesn't provide shared
+Note that the emulation built with L<lockf(3)> doesn't provide shared
locks, and it requires that FILEHANDLE be open with write intent. These
-are the semantics that lockf(3) implements. Most if not all systems
-implement lockf(3) in terms of fcntl(2) locking, though, so the
+are the semantics that L<lockf(3)> implements. Most if not all systems
+implement L<lockf(3)> in terms of L<fcntl(2)> locking, though, so the
differing semantics shouldn't bite too many people.
-Note that the fcntl(2) emulation of flock(3) requires that FILEHANDLE
+Note that the L<fcntl(2)> emulation of L<flock(3)> requires that FILEHANDLE
be open with read intent to use LOCK_SH and requires that it be open
with write intent to use LOCK_EX.
-Note also that some versions of C<flock> cannot lock things over the
-network; you would need to use the more system-specific C<fcntl> for
-that. If you like you can force Perl to ignore your system's flock(2)
-function, and so provide its own fcntl(2)-based emulation, by passing
+Note also that some versions of L<C<flock>|/flock FILEHANDLE,OPERATION>
+cannot lock things over the network; you would need to use the more
+system-specific L<C<fcntl>|/fcntl FILEHANDLE,FUNCTION,SCALAR> for
+that. If you like you can force Perl to ignore your system's L<flock(2)>
+function, and so provide its own L<fcntl(2)>-based emulation, by passing
the switch C<-Ud_flock> to the F<Configure> program when you configure
and build a new Perl.
print $mbox $msg,"\n\n";
unlock($mbox);
-On systems that support a real flock(2), locks are inherited across fork()
-calls, whereas those that must resort to the more capricious fcntl(2)
-function lose their locks, making it seriously harder to write servers.
+On systems that support a real L<flock(2)>, locks are inherited across
+L<C<fork>|/fork> calls, whereas those that must resort to the more
+capricious L<fcntl(2)> function lose their locks, making it seriously
+harder to write servers.
-See also L<DB_File> for other flock() examples.
+See also L<DB_File> for other L<C<flock>|/flock FILEHANDLE,OPERATION>
+examples.
Portability issues: L<perlport/flock>.
=for Pod::Functions create a new process just like this one
-Does a fork(2) system call to create a new process running the
+Does a L<fork(2)> system call to create a new process running the
same program at the same point. It returns the child pid to the
-parent process, C<0> to the child process, or C<undef> if the fork is
+parent process, C<0> to the child process, or L<C<undef>|/undef EXPR> if
+the fork is
unsuccessful. File descriptors (and sometimes locks on those descriptors)
are shared, while everything else is copied. On most systems supporting
-fork(), great care has gone into making it extremely efficient (for
+L<fork(2)>, great care has gone into making it extremely efficient (for
example, using copy-on-write technology on data pages), making it the
dominant paradigm for multitasking over the last few decades.
-Perl attempts to flush all files opened for
-output before forking the child process, but this may not be supported
-on some platforms (see L<perlport>). To be safe, you may need to set
-C<$|> ($AUTOFLUSH in English) or call the C<autoflush()> method of
-C<IO::Handle> on any open handles to avoid duplicate output.
+Perl attempts to flush all files opened for output before forking the
+child process, but this may not be supported on some platforms (see
+L<perlport>). To be safe, you may need to set
+L<C<$E<verbar>>|perlvar/$E<verbar>> (C<$AUTOFLUSH> in L<English>) or
+call the C<autoflush> method of L<C<IO::Handle>|IO::Handle/METHODS> on
+any open handles to avoid duplicate output.
-If you C<fork> without ever waiting on your children, you will
+If you L<C<fork>|/fork> without ever waiting on your children, you will
accumulate zombies. On some systems, you can avoid this by setting
-C<$SIG{CHLD}> to C<"IGNORE">. See also L<perlipc> for more examples of
-forking and reaping moribund children.
+L<C<$SIG{CHLD}>|perlvar/%SIG> to C<"IGNORE">. See also L<perlipc> for
+more examples of forking and reaping moribund children.
Note that if your forked child inherits system file descriptors like
STDIN and STDOUT that are actually connected by a pipe or socket, even
backgrounded job launched from a remote shell) won't think you're done.
You should reopen those to F</dev/null> if it's any issue.
-On some platforms such as Windows, where the fork() system call is not available,
-Perl can be built to emulate fork() in the Perl interpreter.
-The emulation is designed, at the level of the Perl program,
-to be as compatible as possible with the "Unix" fork().
-However it has limitations that have to be considered in code intended to be portable.
-See L<perlfork> for more details.
+On some platforms such as Windows, where the L<fork(2)> system call is
+not available, Perl can be built to emulate L<C<fork>|/fork> in the Perl
+interpreter. The emulation is designed, at the level of the Perl
+program, to be as compatible as possible with the "Unix" L<fork(2)>.
+However it has limitations that have to be considered in code intended
+to be portable. See L<perlfork> for more details.
Portability issues: L<perlport/fork>.
=for Pod::Functions declare a picture format with use by the write() function
-Declare a picture format for use by the C<write> function. For
-example:
+Declare a picture format for use by the L<C<write>|/write FILEHANDLE>
+function. For example:
format Something =
Test: @<<<<<<<< @||||| @>>>>>
=for Pod::Functions internal function used for formats
-This is an internal function used by C<format>s, though you may call it,
-too. It formats (see L<perlform>) a list of values according to the
-contents of PICTURE, placing the output into the format output
-accumulator, C<$^A> (or C<$ACCUMULATOR> in English).
-Eventually, when a C<write> is done, the contents of
-C<$^A> are written to some filehandle. You could also read C<$^A>
-and then set C<$^A> back to C<"">. Note that a format typically
-does one C<formline> per line of form, but the C<formline> function itself
-doesn't care how many newlines are embedded in the PICTURE. This means
-that the C<~> and C<~~> tokens treat the entire PICTURE as a single line.
-You may therefore need to use multiple formlines to implement a single
-record format, just like the C<format> compiler.
+This is an internal function used by L<C<format>|/format>s, though you
+may call it, too. It formats (see L<perlform>) a list of values
+according to the contents of PICTURE, placing the output into the format
+output accumulator, L<C<$^A>|perlvar/$^A> (or C<$ACCUMULATOR> in
+L<English>). Eventually, when a L<C<write>|/write FILEHANDLE> is done,
+the contents of L<C<$^A>|perlvar/$^A> are written to some filehandle.
+You could also read L<C<$^A>|perlvar/$^A> and then set
+L<C<$^A>|perlvar/$^A> back to C<"">. Note that a format typically does
+one L<C<formline>|/formline PICTURE,LIST> per line of form, but the
+L<C<formline>|/formline PICTURE,LIST> function itself doesn't care how
+many newlines are embedded in the PICTURE. This means that the C<~> and
+C<~~> tokens treat the entire PICTURE as a single line. You may
+therefore need to use multiple formlines to implement a single record
+format, just like the L<C<format>|/format> compiler.
Be careful if you put double quotes around the picture, because an C<@>
character may be taken to mean the beginning of an array name.
-C<formline> always returns true. See L<perlform> for other examples.
+L<C<formline>|/formline PICTURE,LIST> always returns true. See
+L<perlform> for other examples.
-If you are trying to use this instead of C<write> to capture the output,
-you may find it easier to open a filehandle to a scalar
-(C<< open $fh, ">", \$output >>) and write to that instead.
+If you are trying to use this instead of L<C<write>|/write FILEHANDLE>
+to capture the output, you may find it easier to open a filehandle to a
+scalar (C<< open my $fh, ">", \$output >>) and write to that instead.
=item getc FILEHANDLE
X<getc> X<getchar> X<character> X<file, read>
Returns the next character from the input file attached to FILEHANDLE,
or the undefined value at end of file or if there was an error (in
-the latter case C<$!> is set). If FILEHANDLE is omitted, reads from
+the latter case L<C<$!>|perlvar/$!> is set). If FILEHANDLE is omitted,
+reads from
STDIN. This is not particularly efficient. However, it cannot be
used by itself to fetch single characters without waiting for the user
to hit enter. For that, try something more like:
system "stty", '-icanon', 'eol', "\001";
}
- $key = getc(STDIN);
+ my $key = getc(STDIN);
if ($BSD_STYLE) {
system "stty -cbreak </dev/tty >/dev/tty 2>&1";
}
print "\n";
-Determination of whether $BSD_STYLE should be set
-is left as an exercise to the reader.
+Determination of whether C<$BSD_STYLE> should be set is left as an
+exercise to the reader.
-The C<POSIX::getattr> function can do this more portably on
-systems purporting POSIX compliance. See also the C<Term::ReadKey>
-module from your nearest L<CPAN|http://www.cpan.org> site.
+The L<C<POSIX::getattr>|POSIX/C<getattr>> function can do this more
+portably on systems purporting POSIX compliance. See also the
+L<C<Term::ReadKey>|Term::ReadKey> module on CPAN.
=item getlogin
X<getlogin> X<login>
This implements the C library function of the same name, which on most
systems returns the current login from F</etc/utmp>, if any. If it
-returns the empty string, use C<getpwuid>.
+returns the empty string, use L<C<getpwuid>|/getpwuid UID>.
- $login = getlogin || getpwuid($<) || "Kilroy";
+ my $login = getlogin || getpwuid($<) || "Kilroy";
-Do not consider C<getlogin> for authentication: it is not as
-secure as C<getpwuid>.
+Do not consider L<C<getlogin>|/getlogin> for authentication: it is not
+as secure as L<C<getpwuid>|/getpwuid UID>.
Portability issues: L<perlport/getlogin>.
connection.
use Socket;
- $hersockaddr = getpeername(SOCK);
- ($port, $iaddr) = sockaddr_in($hersockaddr);
- $herhostname = gethostbyaddr($iaddr, AF_INET);
- $herstraddr = inet_ntoa($iaddr);
+ my $hersockaddr = getpeername($sock);
+ my ($port, $iaddr) = sockaddr_in($hersockaddr);
+ my $herhostname = gethostbyaddr($iaddr, AF_INET);
+ my $herstraddr = inet_ntoa($iaddr);
=item getpgrp PID
X<getpgrp> X<group>
Returns the current process group for the specified PID. Use
a PID of C<0> to get the current process group for the
current process. Will raise an exception if used on a machine that
-doesn't implement getpgrp(2). If PID is omitted, returns the process
-group of the current process. Note that the POSIX version of C<getpgrp>
-does not accept a PID argument, so only C<PID==0> is truly portable.
+doesn't implement L<getpgrp(2)>. If PID is omitted, returns the process
+group of the current process. Note that the POSIX version of
+L<C<getpgrp>|/getpgrp PID> does not accept a PID argument, so only
+C<PID==0> is truly portable.
Portability issues: L<perlport/getpgrp>.
Returns the current priority for a process, a process group, or a user.
(See L<getpriority(2)>.) Will raise a fatal exception if used on a
-machine that doesn't implement getpriority(2).
+machine that doesn't implement L<getpriority(2)>.
Portability issues: L<perlport/getpriority>.
X<getprotobynumber> X<getservbyport> X<getpwent> X<getgrent> X<gethostent>
X<getnetent> X<getprotoent> X<getservent> X<setpwent> X<setgrent> X<sethostent>
X<setnetent> X<setprotoent> X<setservent> X<endpwent> X<endgrent> X<endhostent>
-X<endnetent> X<endprotoent> X<endservent>
+X<endnetent> X<endprotoent> X<endservent>
=for Pod::Functions get passwd record given user login name
system C library. In list context, the return values from the
various get routines are as follows:
- # 0 1 2 3 4
- ( $name, $passwd, $gid, $members ) = getgr*
- ( $name, $aliases, $addrtype, $net ) = getnet*
- ( $name, $aliases, $port, $proto ) = getserv*
- ( $name, $aliases, $proto ) = getproto*
- ( $name, $aliases, $addrtype, $length, @addrs ) = gethost*
- ( $name, $passwd, $uid, $gid, $quota,
- $comment, $gcos, $dir, $shell, $expire ) = getpw*
- # 5 6 7 8 9
+ # 0 1 2 3 4
+ my ( $name, $passwd, $gid, $members ) = getgr*
+ my ( $name, $aliases, $addrtype, $net ) = getnet*
+ my ( $name, $aliases, $port, $proto ) = getserv*
+ my ( $name, $aliases, $proto ) = getproto*
+ my ( $name, $aliases, $addrtype, $length, @addrs ) = gethost*
+ my ( $name, $passwd, $uid, $gid, $quota,
+ $comment, $gcos, $dir, $shell, $expire ) = getpw*
+ # 5 6 7 8 9
(If the entry doesn't exist, the return value is a single meaningless true
value.)
lookup by name, in which case you get the other thing, whatever it is.
(If the entry doesn't exist you get the undefined value.) For example:
- $uid = getpwnam($name);
- $name = getpwuid($num);
- $name = getpwent();
- $gid = getgrnam($name);
- $name = getgrgid($num);
- $name = getgrent();
- #etc.
+ my $uid = getpwnam($name);
+ my $name = getpwuid($num);
+ my $name = getpwent();
+ my $gid = getgrnam($name);
+ my $name = getgrgid($num);
+ my $name = getgrent();
+ # etc.
In I<getpw*()> the fields $quota, $comment, and $expire are special
in that they are unsupported on many systems. If the
aging. In some systems the $comment field may be $class. The $expire
field, if present, encodes the expiration period of the account or the
password. For the availability and the exact meaning of these fields
-in your system, please consult getpwnam(3) and your system's
+in your system, please consult L<getpwnam(3)> and your system's
F<pwd.h> file. You can also find out from within Perl what your
$quota and $comment fields mean and whether you have the $expire field
-by using the C<Config> module and the values C<d_pwquota>, C<d_pwage>,
+by using the L<C<Config>|Config> module and the values C<d_pwquota>, C<d_pwage>,
C<d_pwchange>, C<d_pwcomment>, and C<d_pwexpire>. Shadow password
files are supported only if your vendor has implemented them in the
intuitive fashion that calling the regular C library routines gets the
shadow versions if you're running under privilege or if there exists
-the shadow(3) functions as found in System V (this includes Solaris
+the L<shadow(3)> functions as found in System V (this includes Solaris
and Linux). Those systems that implement a proprietary shadow password
facility are unlikely to be supported.
the login names of the members of the group.
For the I<gethost*()> functions, if the C<h_errno> variable is supported in
-C, it will be returned to you via C<$?> if the function call fails. The
+C, it will be returned to you via L<C<$?>|perlvar/$?> if the function
+call fails. The
C<@addrs> value returned by a successful call is a list of raw
addresses returned by the corresponding library call. In the
Internet domain, each address is four bytes long; you can unpack it
by saying something like:
- ($a,$b,$c,$d) = unpack('W4',$addr[0]);
+ my ($w,$x,$y,$z) = unpack('W4',$addr[0]);
The Socket library makes this slightly easier:
use Socket;
- $iaddr = inet_aton("127.1"); # or whatever address
- $name = gethostbyaddr($iaddr, AF_INET);
+ my $iaddr = inet_aton("127.1"); # or whatever address
+ my $name = gethostbyaddr($iaddr, AF_INET);
# or going the other way
- $straddr = inet_ntoa($iaddr);
+ my $straddr = inet_ntoa($iaddr);
In the opposite way, to resolve a hostname to the IP address
you can write this:
use Socket;
- $packed_ip = gethostbyname("www.perl.org");
+ my $packed_ip = gethostbyname("www.perl.org");
+ my $ip_address;
if (defined $packed_ip) {
$ip_address = inet_ntoa($packed_ip);
}
-Make sure C<gethostbyname()> is called in SCALAR context and that
-its return value is checked for definedness.
+Make sure L<C<gethostbyname>|/gethostbyname NAME> is called in SCALAR
+context and that its return value is checked for definedness.
-The C<getprotobynumber> function, even though it only takes one argument,
-has the precedence of a list operator, so beware:
+The L<C<getprotobynumber>|/getprotobynumber NUMBER> function, even
+though it only takes one argument, has the precedence of a list
+operator, so beware:
getprotobynumber $number eq 'icmp' # WRONG
getprotobynumber($number eq 'icmp') # actually means this
getprotobynumber($number) eq 'icmp' # better this way
If you get tired of remembering which element of the return list
-contains which return value, by-name interfaces are provided
-in standard modules: C<File::stat>, C<Net::hostent>, C<Net::netent>,
-C<Net::protoent>, C<Net::servent>, C<Time::gmtime>, C<Time::localtime>,
-and C<User::grent>. These override the normal built-ins, supplying
-versions that return objects with the appropriate names
-for each field. For example:
+contains which return value, by-name interfaces are provided in standard
+modules: L<C<File::stat>|File::stat>, L<C<Net::hostent>|Net::hostent>,
+L<C<Net::netent>|Net::netent>, L<C<Net::protoent>|Net::protoent>,
+L<C<Net::servent>|Net::servent>, L<C<Time::gmtime>|Time::gmtime>,
+L<C<Time::localtime>|Time::localtime>, and
+L<C<User::grent>|User::grent>. These override the normal built-ins,
+supplying versions that return objects with the appropriate names for
+each field. For example:
use File::stat;
use User::pwent;
- $is_his = (stat($filename)->uid == pwent($whoever)->uid);
+ my $is_his = (stat($filename)->uid == pwent($whoever)->uid);
Even though it looks as though they're the same method calls (uid),
they aren't, because a C<File::stat> object is different from
IPs that the connection might have come in on.
use Socket;
- $mysockaddr = getsockname(SOCK);
- ($port, $myaddr) = sockaddr_in($mysockaddr);
+ my $mysockaddr = getsockname($sock);
+ my ($port, $myaddr) = sockaddr_in($mysockaddr);
printf "Connect to %s [%s]\n",
scalar gethostbyaddr($myaddr, AF_INET),
inet_ntoa($myaddr);
Queries the option named OPTNAME associated with SOCKET at a given LEVEL.
Options may exist at multiple protocol levels depending on the socket
type, but at least the uppermost socket level SOL_SOCKET (defined in the
-C<Socket> module) will exist. To query options at another level the
-protocol number of the appropriate protocol controlling the option
-should be supplied. For example, to indicate that an option is to be
-interpreted by the TCP protocol, LEVEL should be set to the protocol
-number of TCP, which you can get using C<getprotobyname>.
+L<C<Socket>|Socket> module) will exist. To query options at another
+level the protocol number of the appropriate protocol controlling the
+option should be supplied. For example, to indicate that an option is
+to be interpreted by the TCP protocol, LEVEL should be set to the
+protocol number of TCP, which you can get using
+L<C<getprotobyname>|/getprotobyname NAME>.
The function returns a packed string representing the requested socket
-option, or C<undef> on error, with the reason for the error placed in
-C<$!>. Just what is in the packed string depends on LEVEL and OPTNAME;
-consult getsockopt(2) for details. A common case is that the option is an
-integer, in which case the result is a packed integer, which you can decode
-using C<unpack> with the C<i> (or C<I>) format.
+option, or L<C<undef>|/undef EXPR> on error, with the reason for the
+error placed in L<C<$!>|perlvar/$!>. Just what is in the packed string
+depends on LEVEL and OPTNAME; consult L<getsockopt(2)> for details. A
+common case is that the option is an integer, in which case the result
+is a packed integer, which you can decode using
+L<C<unpack>|/unpack TEMPLATE,EXPR> with the C<i> (or C<I>) format.
Here's an example to test whether Nagle's algorithm is enabled on a socket:
scalar context, glob iterates through such filename expansions, returning
undef when the list is exhausted. This is the internal function
implementing the C<< <*.c> >> operator, but you can use it directly. If
-EXPR is omitted, C<$_> is used. The C<< <*.c> >> operator is discussed in
-more detail in L<perlop/"I/O Operators">.
+EXPR is omitted, L<C<$_>|perlvar/$_> is used. The C<< <*.c> >> operator
+is discussed in more detail in L<perlop/"I/O Operators">.
-Note that C<glob> splits its arguments on whitespace and treats
-each segment as separate pattern. As such, C<glob("*.c *.h")>
+Note that L<C<glob>|/glob EXPR> splits its arguments on whitespace and
+treats
+each segment as separate pattern. As such, C<glob("*.c *.h")>
matches all files with a F<.c> or F<.h> extension. The expression
C<glob(".* *")> matches all files in the current working directory.
If you want to glob filenames that might contain whitespace, you'll
For example, to glob filenames that have an C<e> followed by a space
followed by an C<f>, use one of:
- @spacies = <"*e f*">;
- @spacies = glob '"*e f*"';
- @spacies = glob q("*e f*");
+ my @spacies = <"*e f*">;
+ my @spacies = glob '"*e f*"';
+ my @spacies = glob q("*e f*");
If you had to get a variable through, you could do this:
- @spacies = glob "'*${var}e f*'";
- @spacies = glob qq("*${var}e f*");
+ my @spacies = glob "'*${var}e f*'";
+ my @spacies = glob qq("*${var}e f*");
If non-empty braces are the only wildcard characters used in the
-C<glob>, no filenames are matched, but potentially many strings
-are returned. For example, this produces nine strings, one for
+L<C<glob>|/glob EXPR>, no filenames are matched, but potentially many
+strings are returned. For example, this produces nine strings, one for
each pairing of fruits and colors:
- @many = glob "{apple,tomato,cherry}={green,yellow,red}";
+ my @many = glob "{apple,tomato,cherry}={green,yellow,red}";
-This operator is implemented using the standard
-C<File::Glob> extension. See L<File::Glob> for details, including
-C<bsd_glob> which does not treat whitespace as a pattern separator.
+This operator is implemented using the standard C<File::Glob> extension.
+See L<File::Glob> for details, including
+L<C<bsd_glob>|File::Glob/C<bsd_glob>>, which does not treat whitespace
+as a pattern separator.
Portability issues: L<perlport/glob>.
=for Pod::Functions convert UNIX time into record or string using Greenwich time
-Works just like L</localtime> but the returned values are
-localized for the standard Greenwich time zone.
+Works just like L<C<localtime>|/localtime EXPR> but the returned values
+are localized for the standard Greenwich time zone.
Note: When called in list context, $isdst, the last value
returned by gmtime, is always C<0>. There is no
The C<goto LABEL> form finds the statement labeled with LABEL and
resumes execution there. It can't be used to get out of a block or
-subroutine given to C<sort>. It can be used to go almost anywhere
-else within the dynamic scope, including out of subroutines, but it's
-usually better to use some other construct such as C<last> or C<die>.
-The author of Perl has never felt the need to use this form of C<goto>
-(in Perl, that is; C is another matter). (The difference is that C
-does not offer named loops combined with loop control. Perl does, and
-this replaces most structured uses of C<goto> in other languages.)
+subroutine given to L<C<sort>|/sort SUBNAME LIST>. It can be used to go
+almost anywhere else within the dynamic scope, including out of
+subroutines, but it's usually better to use some other construct such as
+L<C<last>|/last LABEL> or L<C<die>|/die LIST>. The author of Perl has
+never felt the need to use this form of L<C<goto>|/goto LABEL> (in Perl,
+that is; C is another matter). (The difference is that C does not offer
+named loops combined with loop control. Perl does, and this replaces
+most structured uses of L<C<goto>|/goto LABEL> in other languages.)
The C<goto EXPR> form expects to evaluate C<EXPR> to a code reference or
a label name. If it evaluates to a code reference, it will be handled
tail recursion via C<goto __SUB__>.
If the expression evaluates to a label name, its scope will be resolved
-dynamically. This allows for computed C<goto>s per FORTRAN, but isn't
-necessarily recommended if you're optimizing for maintainability:
+dynamically. This allows for computed L<C<goto>|/goto LABEL>s per
+FORTRAN, but isn't necessarily recommended if you're optimizing for
+maintainability:
goto ("FOO", "BAR", "GLARCH")[$i];
construct that is optimized away.
The C<goto &NAME> form is quite different from the other forms of
-C<goto>. In fact, it isn't a goto in the normal sense at all, and
-doesn't have the stigma associated with other gotos. Instead, it
-exits the current subroutine (losing any changes set by local()) and
-immediately calls in its place the named subroutine using the current
-value of @_. This is used by C<AUTOLOAD> subroutines that wish to
-load another subroutine and then pretend that the other subroutine had
-been called in the first place (except that any modifications to C<@_>
-in the current subroutine are propagated to the other subroutine.)
-After the C<goto>, not even C<caller> will be able to tell that this
-routine was called first.
+L<C<goto>|/goto LABEL>. In fact, it isn't a goto in the normal sense at
+all, and doesn't have the stigma associated with other gotos. Instead,
+it exits the current subroutine (losing any changes set by
+L<C<local>|/local EXPR>) and immediately calls in its place the named
+subroutine using the current value of L<C<@_>|perlvar/@_>. This is used
+by C<AUTOLOAD> subroutines that wish to load another subroutine and then
+pretend that the other subroutine had been called in the first place
+(except that any modifications to L<C<@_>|perlvar/@_> in the current
+subroutine are propagated to the other subroutine.) After the
+L<C<goto>|/goto LABEL>, not even L<C<caller>|/caller EXPR> will be able
+to tell that this routine was called first.
NAME needn't be the name of a subroutine; it can be a scalar variable
containing a code reference or a block that evaluates to a code
=for Pod::Functions locate elements in a list test true against a given criterion
-This is similar in spirit to, but not the same as, grep(1) and its
+This is similar in spirit to, but not the same as, L<grep(1)> and its
relatives. In particular, it is not limited to using regular expressions.
Evaluates the BLOCK or EXPR for each element of LIST (locally setting
-C<$_> to each element) and returns the list value consisting of those
+L<C<$_>|perlvar/$_> to each element) and returns the list value
+consisting of those
elements for which the expression evaluated to true. In scalar
context, returns the number of times the expression was true.
- @foo = grep(!/^#/, @bar); # weed out comments
+ my @foo = grep(!/^#/, @bar); # weed out comments
or equivalently,
- @foo = grep {!/^#/} @bar; # weed out comments
+ my @foo = grep {!/^#/} @bar; # weed out comments
-Note that C<$_> is an alias to the list value, so it can be used to
+Note that L<C<$_>|perlvar/$_> is an alias to the list value, so it can
+be used to
modify the elements of the LIST. While this is useful and supported,
it can cause bizarre results if the elements of LIST are not variables.
Similarly, grep returns aliases into the original list, much as a for
loop's index variable aliases the list elements. That is, modifying an
-element of a list returned by grep (for example, in a C<foreach>, C<map>
-or another C<grep>) actually modifies the element in the original list.
+element of a list returned by grep (for example, in a C<foreach>,
+L<C<map>|/map BLOCK LIST> or another L<C<grep>|/grep BLOCK LIST>)
+actually modifies the element in the original list.
This is usually something to be avoided when writing clear code.
-See also L</map> for a list composed of the results of the BLOCK or EXPR.
+See also L<C<map>|/map BLOCK LIST> for a list composed of the results of
+the BLOCK or EXPR.
=item hex EXPR
X<hex> X<hexadecimal>
=for Pod::Functions convert a hexadecimal string to a number
Interprets EXPR as a hex string and returns the corresponding numeric value.
-If EXPR is omitted, uses C<$_>.
+If EXPR is omitted, uses L<C<$_>|perlvar/$_>.
print hex '0xAf'; # prints '175'
print hex 'aF'; # same
A hex string consists of hex digits and an optional C<0x> or C<x> prefix.
Each hex digit may be preceded by a single underscore, which will be ignored.
Any other character triggers a warning and causes the rest of the string
-to be ignored (even leading whitespace, unlike L</oct>).
+to be ignored (even leading whitespace, unlike L<C<oct>|/oct EXPR>).
Only integers can be represented, and integer overflow triggers a warning.
-To convert strings that might start with any of C<0>, C<0x>, or C<0b>, see L</oct>.
-To present something as hex, look into L</printf>,
-L</sprintf>, and L</unpack>.
+To convert strings that might start with any of C<0>, C<0x>, or C<0b>,
+see L<C<oct>|/oct EXPR>. To present something as hex, look into
+L<C<printf>|/printf FILEHANDLE FORMAT, LIST>,
+L<C<sprintf>|/sprintf FORMAT, LIST>, and
+L<C<unpack>|/unpack TEMPLATE,EXPR>.
=item import LIST
X<import>
=for Pod::Functions patch a module's namespace into your own
-There is no builtin C<import> function. It is just an ordinary
-method (subroutine) defined (or inherited) by modules that wish to export
-names to another module. The C<use> function calls the C<import> method
-for the package used. See also L</use>, L<perlmod>, and L<Exporter>.
+There is no builtin L<C<import>|/import LIST> function. It is just an
+ordinary method (subroutine) defined (or inherited) by modules that wish
+to export names to another module. The
+L<C<use>|/use Module VERSION LIST> function calls the
+L<C<import>|/import LIST> method for the package used. See also
+L<C<use>|/use Module VERSION LIST>, L<perlmod>, and L<Exporter>.
=item index STR,SUBSTR,POSITION
X<index> X<indexOf> X<InStr>
beginning of the string. POSITION before the beginning of the string
or after its end is treated as if it were the beginning or the end,
respectively. POSITION and the return value are based at zero.
-If the substring is not found, C<index> returns -1.
+If the substring is not found, L<C<index>|/index STR,SUBSTR,POSITION>
+returns -1.
=item int EXPR
X<int> X<integer> X<truncate> X<trunc> X<floor>
=for Pod::Functions get the integer portion of a number
-Returns the integer portion of EXPR. If EXPR is omitted, uses C<$_>.
+Returns the integer portion of EXPR. If EXPR is omitted, uses
+L<C<$_>|perlvar/$_>.
You should not use this function for rounding: one because it truncates
towards C<0>, and two because machine representations of floating-point
numbers can sometimes produce counterintuitive results. For example,
C<int(-6.725/0.025)> produces -268 rather than the correct -269; that's
because it's really more like -268.99999999999994315658 instead. Usually,
-the C<sprintf>, C<printf>, or the C<POSIX::floor> and C<POSIX::ceil>
-functions will serve you better than will int().
+the L<C<sprintf>|/sprintf FORMAT, LIST>,
+L<C<printf>|/printf FILEHANDLE FORMAT, LIST>, or the
+L<C<POSIX::floor>|POSIX/C<floor>> and L<C<POSIX::ceil>|POSIX/C<ceil>>
+functions will serve you better than will L<C<int>|/int EXPR>.
=item ioctl FILEHANDLE,FUNCTION,SCALAR
X<ioctl>
=for Pod::Functions system-dependent device control system call
-Implements the ioctl(2) function. You'll probably first have to say
+Implements the L<ioctl(2)> function. You'll probably first have to say
require "sys/ioctl.ph"; # probably in
# $Config{archlib}/sys/ioctl.ph
(There is a Perl script called B<h2ph> that comes with the Perl kit that
may help you in this, but it's nontrivial.) SCALAR will be read and/or
written depending on the FUNCTION; a C pointer to the string value of SCALAR
-will be passed as the third argument of the actual C<ioctl> call. (If SCALAR
+will be passed as the third argument of the actual
+L<C<ioctl>|/ioctl FILEHANDLE,FUNCTION,SCALAR> call. (If SCALAR
has no string value but does have a numeric value, that value will be
passed rather than a pointer to the string value. To guarantee this to be
-true, add a C<0> to the scalar before using it.) The C<pack> and C<unpack>
+true, add a C<0> to the scalar before using it.) The
+L<C<pack>|/pack TEMPLATE,LIST> and L<C<unpack>|/unpack TEMPLATE,EXPR>
functions may be needed to manipulate the values of structures used by
-C<ioctl>.
+L<C<ioctl>|/ioctl FILEHANDLE,FUNCTION,SCALAR>.
-The return value of C<ioctl> (and C<fcntl>) is as follows:
+The return value of L<C<ioctl>|/ioctl FILEHANDLE,FUNCTION,SCALAR> (and
+L<C<fcntl>|/fcntl FILEHANDLE,FUNCTION,SCALAR>) is as follows:
if OS returns: then Perl returns:
-1 undefined value
still easily determine the actual value returned by the operating
system:
- $retval = ioctl(...) || -1;
+ my $retval = ioctl(...) || -1;
printf "System returned %d\n", $retval;
-The special string C<"0 but true"> is exempt from B<-w> complaints
-about improper numeric conversions.
+The special string C<"0 but true"> is exempt from
+L<C<Argument "..." isn't numeric>|perldiag/Argument "%s" isn't numeric%s>
+L<warnings> on improper numeric conversions.
Portability issues: L<perlport/ioctl>.
Joins the separate strings of LIST into a single string with fields
separated by the value of EXPR, and returns that new string. Example:
- $rec = join(':', $login,$passwd,$uid,$gid,$gcos,$home,$shell);
+ my $rec = join(':', $login,$passwd,$uid,$gid,$gcos,$home,$shell);
-Beware that unlike C<split>, C<join> doesn't take a pattern as its
-first argument. Compare L</split>.
+Beware that unlike L<C<split>|/split E<sol>PATTERNE<sol>,EXPR,LIMIT>,
+L<C<join>|/join EXPR,LIST> doesn't take a pattern as its first argument.
+Compare L<C<split>|/split E<sol>PATTERNE<sol>,EXPR,LIMIT>.
=item keys HASH
X<keys> X<key>
order is specific to a given hash; the exact same series of operations
on two hashes may result in a different order for each hash. Any insertion
into the hash may change the order, as will any deletion, with the exception
-that the most recent key returned by C<each> or C<keys> may be deleted
-without changing the order. So long as a given hash is unmodified you may
-rely on C<keys>, C<values> and C<each> to repeatedly return the same order
+that the most recent key returned by L<C<each>|/each HASH> or
+L<C<keys>|/keys HASH> may be deleted without changing the order. So
+long as a given hash is unmodified you may rely on
+L<C<keys>|/keys HASH>, L<C<values>|/values HASH> and L<C<each>|/each
+HASH> to repeatedly return the same order
as each other. See L<perlsec/"Algorithmic Complexity Attacks"> for
details on why hash order is randomized. Aside from the guarantees
provided here the exact details of Perl's hash algorithm and the hash
may behave differently to Perl's hashes with respect to changes in order on
insertion and deletion of items.
-As a side effect, calling keys() resets the internal iterator of the HASH or
-ARRAY (see L</each>). In particular, calling keys() in void context resets
-the iterator with no other overhead.
+As a side effect, calling L<C<keys>|/keys HASH> resets the internal
+iterator of the HASH or ARRAY (see L<C<each>|/each HASH>). In
+particular, calling L<C<keys>|/keys HASH> in void context resets the
+iterator with no other overhead.
Here is yet another way to print your environment:
- @keys = keys %ENV;
- @values = values %ENV;
+ my @keys = keys %ENV;
+ my @values = values %ENV;
while (@keys) {
print pop(@keys), '=', pop(@values), "\n";
}
or how about sorted by key:
- foreach $key (sort(keys %ENV)) {
+ foreach my $key (sort(keys %ENV)) {
print $key, '=', $ENV{$key}, "\n";
}
The returned values are copies of the original keys in the hash, so
-modifying them will not affect the original hash. Compare L</values>.
+modifying them will not affect the original hash. Compare
+L<C<values>|/values HASH>.
-To sort a hash by value, you'll need to use a C<sort> function.
-Here's a descending numeric sort of a hash by its values:
+To sort a hash by value, you'll need to use a
+L<C<sort>|/sort SUBNAME LIST> function. Here's a descending numeric
+sort of a hash by its values:
- foreach $key (sort { $hash{$b} <=> $hash{$a} } keys %hash) {
+ foreach my $key (sort { $hash{$b} <=> $hash{$a} } keys %hash) {
printf "%4d %s\n", $hash{$key}, $key;
}
-Used as an lvalue, C<keys> allows you to increase the number of hash buckets
+Used as an lvalue, L<C<keys>|/keys HASH> allows you to increase the
+number of hash buckets
allocated for the given hash. This can gain you a measure of efficiency if
you know the hash is going to get big. (This is similar to pre-extending
an array by assigning a larger number to $#array.) If you say
buckets will be retained even if you do C<%hash = ()>, use C<undef
%hash> if you want to free the storage while C<%hash> is still in scope.
You can't shrink the number of buckets allocated for the hash using
-C<keys> in this way (but you needn't worry about doing this by accident,
-as trying has no effect). C<keys @array> in an lvalue context is a syntax
-error.
+L<C<keys>|/keys HASH> in this way (but you needn't worry about doing
+this by accident, as trying has no effect). C<keys @array> in an lvalue
+context is a syntax error.
-Starting with Perl 5.14, an experimental feature allowed C<keys> to take a
-scalar expression. This experiment has been deemed unsuccessful, and was
-removed as of Perl 5.24.
+Starting with Perl 5.14, an experimental feature allowed
+L<C<keys>|/keys HASH> to take a scalar expression. This experiment has
+been deemed unsuccessful, and was removed as of Perl 5.24.
To avoid confusing would-be users of your code who are running earlier
versions of Perl with mysterious syntax errors, put this sort of thing at
use 5.012; # so keys/values/each work on arrays
-See also C<each>, C<values>, and C<sort>.
+See also L<C<each>|/each HASH>, L<C<values>|/values HASH>, and
+L<C<sort>|/sort SUBNAME LIST>.
=item kill SIGNAL, LIST
as the number of processes actually killed, e.g. where a process group is
killed).
- $cnt = kill 'HUP', $child1, $child2;
+ my $cnt = kill 'HUP', $child1, $child2;
kill 'KILL', @goners;
SIGNAL may be either a signal name (a string) or a signal number. A signal
the same signal may have different numbers in different operating systems.
A list of signal names supported by the current platform can be found in
-C<$Config{sig_name}>, which is provided by the C<Config> module. See L<Config>
-for more details.
+C<$Config{sig_name}>, which is provided by the L<C<Config>|Config>
+module. See L<Config> for more details.
A negative signal name is the same as a negative signal number, killing process
groups instead of processes. For example, C<kill '-KILL', $pgrp> and
means you usually want to use positive not negative signals.
If SIGNAL is either the number 0 or the string C<ZERO> (or C<SIGZERO>),
-no signal is sent to
-the process, but C<kill> checks whether it's I<possible> to send a signal to it
+no signal is sent to the process, but L<C<kill>|/kill SIGNAL, LIST>
+checks whether it's I<possible> to send a signal to it
(that means, to be brief, that the process is owned by the same user, or we are
the super-user). This is useful to check that a child process is still
alive (even if only as a zombie) and hasn't changed its UID. See
See L<perlipc/"Signals"> for more details.
-On some platforms such as Windows where the fork() system call is not
-available, Perl can be built to emulate fork() at the interpreter level.
+On some platforms such as Windows where the L<fork(2)> system call is not
+available, Perl can be built to emulate L<C<fork>|/fork> at the
+interpreter level.
This emulation has limitations related to kill that have to be considered,
for code running on Windows and in code intended to be portable.
=for Pod::Functions exit a block prematurely
-The C<last> command is like the C<break> statement in C (as used in
+The L<C<last>|/last LABEL> command is like the C<break> statement in C
+(as used in
loops); it immediately exits the loop in question. If the LABEL is
omitted, the command refers to the innermost enclosing
loop. The C<last EXPR> form, available starting in Perl
5.18.0, allows a label name to be computed at run time,
and is otherwise identical to C<last LABEL>. The
-C<continue> block, if any, is not executed:
+L<C<continue>|/continue BLOCK> block, if any, is not executed:
LINE: while (<STDIN>) {
last LINE if /^$/; # exit when done with header
#...
}
-C<last> cannot be used to exit a block that returns a value such as
-C<eval {}>, C<sub {}>, or C<do {}>, and should not be used to exit
-a grep() or map() operation.
+L<C<last>|/last LABEL> cannot be used to exit a block that returns a
+value such as C<eval {}>, C<sub {}>, or C<do {}>, and should not be used
+to exit a L<C<grep>|/grep BLOCK LIST> or L<C<map>|/map BLOCK LIST>
+operation.
Note that a block by itself is semantically identical to a loop
-that executes once. Thus C<last> can be used to effect an early
-exit out of such a block.
+that executes once. Thus L<C<last>|/last LABEL> can be used to effect
+an early exit out of such a block.
-See also L</continue> for an illustration of how C<last>, C<next>, and
-C<redo> work.
+See also L<C<continue>|/continue BLOCK> for an illustration of how
+L<C<last>|/last LABEL>, L<C<next>|/next LABEL>, and
+L<C<redo>|/redo LABEL> work.
Unlike most named operators, this has the same precedence as assignment.
It is also exempt from the looks-like-a-function rule, so
C<last ("foo")."bar"> will cause "bar" to be part of the argument to
-C<last>.
+L<C<last>|/last LABEL>.
=item lc EXPR
X<lc> X<lowercase>
Returns a lowercased version of EXPR. This is the internal function
implementing the C<\L> escape in double-quoted strings.
-If EXPR is omitted, uses C<$_>.
+If EXPR is omitted, uses L<C<$_>|perlvar/$_>.
What gets returned depends on several factors:
itself, because 0xDF may not be LATIN SMALL LETTER SHARP S in the
current locale, and Perl has no way of knowing if that character even
exists in the locale, much less what code point it is. Perl returns
-a result that is above 255 (almost always the input character unchanged,
+a result that is above 255 (almost always the input character unchanged),
for all instances (and there aren't many) where the 255/256 boundary
would otherwise be crossed; and starting in v5.22, it raises a
L<locale|perldiag/Can't do %s("%s") on non-UTF-8 locale; resolved to "%s".> warning.
is the internal function implementing the C<\l> escape in
double-quoted strings.
-If EXPR is omitted, uses C<$_>.
+If EXPR is omitted, uses L<C<$_>|perlvar/$_>.
-This function behaves the same way under various pragmata, such as in a locale,
-as L</lc> does.
+This function behaves the same way under various pragmas, such as in a locale,
+as L<C<lc>|/lc EXPR> does.
=item length EXPR
X<length> X<size>
=for Pod::Functions return the number of characters in a string
Returns the length in I<characters> of the value of EXPR. If EXPR is
-omitted, returns the length of C<$_>. If EXPR is undefined, returns
-C<undef>.
+omitted, returns the length of L<C<$_>|perlvar/$_>. If EXPR is
+undefined, returns L<C<undef>|/undef EXPR>.
This function cannot be used on an entire array or hash to find out how
many elements these have. For that, use C<scalar @array> and C<scalar keys
%hash>, respectively.
-Like all Perl character operations, length() normally deals in logical
+Like all Perl character operations, L<C<length>|/length EXPR> normally
+deals in logical
characters, not physical bytes. For how many bytes a string encoded as
UTF-8 would take up, use C<length(Encode::encode_utf8(EXPR))> (you'll have
to C<use Encode> first). See L<Encode> and L<perlunicode>.
=for Pod::Functions register your socket as a server
-Does the same thing that the listen(2) system call does. Returns true if
+Does the same thing that the L<listen(2)> system call does. Returns true if
it succeeded, false otherwise. See the example in
L<perlipc/"Sockets: Client/Server Communication">.
=for Pod::Functions create a temporary value for a global variable (dynamic scoping)
-You really probably want to be using C<my> instead, because C<local> isn't
-what most people think of as "local". See
-L<perlsub/"Private Variables via my()"> for details.
+You really probably want to be using L<C<my>|/my VARLIST> instead,
+because L<C<local>|/local EXPR> isn't what most people think of as
+"local". See L<perlsub/"Private Variables via my()"> for details.
A local modifies the listed variables to be local to the enclosing
block, file, or eval. If more than one value is listed, the list must
with the time analyzed for the local time zone. Typically used as
follows:
- # 0 1 2 3 4 5 6 7 8
- ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
+ # 0 1 2 3 4 5 6 7 8
+ my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
localtime(time);
All list elements are numeric and come straight out of the C `struct
C<$isdst> is true if the specified time occurs during Daylight Saving
Time, false otherwise.
-If EXPR is omitted, C<localtime()> uses the current time (as returned
-by time(3)).
+If EXPR is omitted, L<C<localtime>|/localtime EXPR> uses the current
+time (as returned by L<C<time>|/time>).
-In scalar context, C<localtime()> returns the ctime(3) value:
+In scalar context, L<C<localtime>|/localtime EXPR> returns the
+L<ctime(3)> value:
- $now_string = localtime; # e.g., "Thu Oct 13 04:54:34 1994"
+ my $now_string = localtime; # e.g., "Thu Oct 13 04:54:34 1994"
-The format of this scalar value is B<not> locale-dependent
-but built into Perl. For GMT instead of local
-time use the L</gmtime> builtin. See also the
-C<Time::Local> module (for converting seconds, minutes, hours, and such back to
-the integer value returned by time()), and the L<POSIX> module's strftime(3)
-and mktime(3) functions.
+The format of this scalar value is B<not> locale-dependent but built
+into Perl. For GMT instead of local time use the
+L<C<gmtime>|/gmtime EXPR> builtin. See also the
+L<C<Time::Local>|Time::Local> module (for converting seconds, minutes,
+hours, and such back to the integer value returned by L<C<time>|/time>),
+and the L<POSIX> module's L<C<strftime>|POSIX/C<strftime>> and
+L<C<mktime>|POSIX/C<mktime>> functions.
To get somewhat similar but locale-dependent date strings, set up your
locale environment variables appropriately (please see L<perllocale>) and
try for example:
use POSIX qw(strftime);
- $now_string = strftime "%a %b %e %H:%M:%S %Y", localtime;
+ my $now_string = strftime "%a %b %e %H:%M:%S %Y", localtime;
# or for GMT formatted appropriately for your locale:
- $now_string = strftime "%a %b %e %H:%M:%S %Y", gmtime;
+ my $now_string = strftime "%a %b %e %H:%M:%S %Y", gmtime;
-Note that the C<%a> and C<%b>, the short forms of the day of the week
+Note that C<%a> and C<%b>, the short forms of the day of the week
and the month of the year, may not necessarily be three characters wide.
The L<Time::gmtime> and L<Time::localtime> modules provide a convenient,
-by-name access mechanism to the gmtime() and localtime() functions,
-respectively.
+by-name access mechanism to the L<C<gmtime>|/gmtime EXPR> and
+L<C<localtime>|/localtime EXPR> functions, respectively.
For a comprehensive date and time representation look at the
L<DateTime> module on CPAN.
The value returned is the scalar itself, if the argument is a scalar, or a
reference, if the argument is a hash, array or subroutine.
-lock() is a "weak keyword" : this means that if you've defined a function
+L<C<lock>|/lock THING> is a "weak keyword"; this means that if you've
+defined a function
by this name (before any calls to it), that function will be called
instead. If you are not under C<use threads::shared> this does nothing.
See L<threads::shared>.
=for Pod::Functions retrieve the natural logarithm for a number
Returns the natural logarithm (base I<e>) of EXPR. If EXPR is omitted,
-returns the log of C<$_>. To get the
+returns the log of L<C<$_>|perlvar/$_>. To get the
log of another base, use basic algebra:
The base-N log of a number is equal to the natural log of that number
divided by the natural log of N. For example:
return log($n)/log(10);
}
-See also L</exp> for the inverse operation.
+See also L<C<exp>|/exp EXPR> for the inverse operation.
=item lstat FILEHANDLE
X<lstat>
=for Pod::Functions stat a symbolic link
-Does the same thing as the C<stat> function (including setting the
-special C<_> filehandle) but stats a symbolic link instead of the file
-the symbolic link points to. If symbolic links are unimplemented on
-your system, a normal C<stat> is done. For much more detailed
-information, please see the documentation for C<stat>.
+Does the same thing as the L<C<stat>|/stat FILEHANDLE> function
+(including setting the special C<_> filehandle) but stats a symbolic
+link instead of the file the symbolic link points to. If symbolic links
+are unimplemented on your system, a normal L<C<stat>|/stat FILEHANDLE>
+is done. For much more detailed information, please see the
+documentation for L<C<stat>|/stat FILEHANDLE>.
-If EXPR is omitted, stats C<$_>.
+If EXPR is omitted, stats L<C<$_>|perlvar/$_>.
Portability issues: L<perlport/lstat>.
=for Pod::Functions apply a change to a list to get back a new list with the changes
Evaluates the BLOCK or EXPR for each element of LIST (locally setting
-C<$_> to each element) and returns the list value composed of the
+L<C<$_>|perlvar/$_> to each element) and returns the list value composed
+of the
results of each such evaluation. In scalar context, returns the
total number of elements so generated. Evaluates BLOCK or EXPR in
list context, so each element of LIST may produce zero, one, or
more elements in the returned value.
- @chars = map(chr, @numbers);
+ my @chars = map(chr, @numbers);
translates a list of numbers to the corresponding characters.
assigned to a hash such that the elements
become key/value pairs. See L<perldata> for more details.
- %hash = map { get_a_key_for($_) => $_ } @array;
+ my %hash = map { get_a_key_for($_) => $_ } @array;
is just a funny way to write
- %hash = ();
+ my %hash;
foreach (@array) {
$hash{get_a_key_for($_)} = $_;
}
-Note that C<$_> is an alias to the list value, so it can be used to
-modify the elements of the LIST. While this is useful and supported,
-it can cause bizarre results if the elements of LIST are not variables.
-Using a regular C<foreach> loop for this purpose would be clearer in
-most cases. See also L</grep> for an array composed of those items of
-the original list for which the BLOCK or EXPR evaluates to true.
+Note that L<C<$_>|perlvar/$_> is an alias to the list value, so it can
+be used to modify the elements of the LIST. While this is useful and
+supported, it can cause bizarre results if the elements of LIST are not
+variables. Using a regular C<foreach> loop for this purpose would be
+clearer in most cases. See also L<C<grep>|/grep BLOCK LIST> for an
+array composed of those items of the original list for which the BLOCK
+or EXPR evaluates to true.
C<{> starts both hash references and blocks, so C<map { ...> could be either
the start of map BLOCK LIST or map EXPR, LIST. Because Perl doesn't look
reported close to the C<}>, but you'll need to change something near the C<{>
such as using a unary C<+> or semicolon to give Perl some help:
- %hash = map { "\L$_" => 1 } @array # perl guesses EXPR. wrong
- %hash = map { +"\L$_" => 1 } @array # perl guesses BLOCK. right
- %hash = map {; "\L$_" => 1 } @array # this also works
- %hash = map { ("\L$_" => 1) } @array # as does this
- %hash = map { lc($_) => 1 } @array # and this.
- %hash = map +( lc($_) => 1 ), @array # this is EXPR and works!
+ my %hash = map { "\L$_" => 1 } @array # perl guesses EXPR. wrong
+ my %hash = map { +"\L$_" => 1 } @array # perl guesses BLOCK. right
+ my %hash = map {; "\L$_" => 1 } @array # this also works
+ my %hash = map { ("\L$_" => 1) } @array # as does this
+ my %hash = map { lc($_) => 1 } @array # and this.
+ my %hash = map +( lc($_) => 1 ), @array # this is EXPR and works!
- %hash = map ( lc($_), 1 ), @array # evaluates to (1, @array)
+ my %hash = map ( lc($_), 1 ), @array # evaluates to (1, @array)
or to force an anon hash constructor use C<+{>:
- @hashes = map +{ lc($_) => 1 }, @array # EXPR, so needs
- # comma at end
+ my @hashes = map +{ lc($_) => 1 }, @array # EXPR, so needs
+ # comma at end
to get a list of anonymous hashes each with only one entry apiece.
=for Pod::Functions create a directory
Creates the directory specified by FILENAME, with permissions
-specified by MASK (as modified by C<umask>). If it succeeds it
-returns true; otherwise it returns false and sets C<$!> (errno).
+specified by MASK (as modified by L<C<umask>|/umask EXPR>). If it
+succeeds it returns true; otherwise it returns false and sets
+L<C<$!>|perlvar/$!> (errno).
MASK defaults to 0777 if omitted, and FILENAME defaults
-to C<$_> if omitted.
+to L<C<$_>|perlvar/$_> if omitted.
In general, it is better to create directories with a permissive MASK
-and let the user modify that with their C<umask> than it is to supply
+and let the user modify that with their L<C<umask>|/umask EXPR> than it
+is to supply
a restrictive MASK and give the user no way to be more permissive.
The exceptions to this rule are when the file or directory should be
-kept private (mail files, for instance). The perlfunc(1) entry on
-C<umask> discusses the choice of MASK in more detail.
+kept private (mail files, for instance). The documentation for
+L<C<umask>|/umask EXPR> discusses the choice of MASK in more detail.
Note that according to the POSIX 1003.1-1996 the FILENAME may have any
number of trailing slashes. Some operating and filesystems do not get
everyone happy.
To recursively create a directory structure, look at
-the C<make_path> function of the L<File::Path> module.
+the L<C<make_path>|File::Path/make_path( $dir1, $dir2, .... )> function
+of the L<File::Path> module.
=item msgctl ID,CMD,ARG
X<msgctl>
=for Pod::Functions SysV IPC message control operations
-Calls the System V IPC function msgctl(2). You'll probably have to say
+Calls the System V IPC function L<msgctl(2)>. You'll probably have to say
use IPC::SysV;
first to get the correct constant definitions. If CMD is C<IPC_STAT>,
then ARG must be a variable that will hold the returned C<msqid_ds>
-structure. Returns like C<ioctl>: the undefined value for error,
-C<"0 but true"> for zero, or the actual return value otherwise. See also
-L<perlipc/"SysV IPC"> and the documentation for C<IPC::SysV> and
-C<IPC::Semaphore>.
+structure. Returns like L<C<ioctl>|/ioctl FILEHANDLE,FUNCTION,SCALAR>:
+the undefined value for error, C<"0 but true"> for zero, or the actual
+return value otherwise. See also L<perlipc/"SysV IPC"> and the
+documentation for L<C<IPC::SysV>|IPC::SysV> and
+L<C<IPC::Semaphore>|IPC::Semaphore>.
Portability issues: L<perlport/msgctl>.
=for Pod::Functions get SysV IPC message queue
-Calls the System V IPC function msgget(2). Returns the message queue
-id, or C<undef> on error. See also
-L<perlipc/"SysV IPC"> and the documentation for C<IPC::SysV> and
-C<IPC::Msg>.
+Calls the System V IPC function L<msgget(2)>. Returns the message queue
+id, or L<C<undef>|/undef EXPR> on error. See also L<perlipc/"SysV IPC">
+and the documentation for L<C<IPC::SysV>|IPC::SysV> and
+L<C<IPC::Msg>|IPC::Msg>.
Portability issues: L<perlport/msgget>.
SIZE. Note that when a message is received, the message type as a
native long integer will be the first thing in VAR, followed by the
actual message. This packing may be opened with C<unpack("l! a*")>.
-Taints the variable. Returns true if successful, false
+Taints the variable. Returns true if successful, false
on error. See also L<perlipc/"SysV IPC"> and the documentation for
-C<IPC::SysV> and C<IPC::SysV::Msg>.
+L<C<IPC::SysV>|IPC::SysV> and L<C<IPC::Msg>|IPC::Msg>.
Portability issues: L<perlport/msgrcv>.
type, be followed by the length of the actual message, and then finally
the message itself. This kind of packing can be achieved with
C<pack("l! a*", $type, $message)>. Returns true if successful,
-false on error. See also the C<IPC::SysV>
-and C<IPC::SysV::Msg> documentation.
+false on error. See also L<perlipc/"SysV IPC"> and the documentation
+for L<C<IPC::SysV>|IPC::SysV> and L<C<IPC::Msg>|IPC::Msg>.
Portability issues: L<perlport/msgsnd>.
=for Pod::Functions declare and assign a local variable (lexical scoping)
-A C<my> declares the listed variables to be local (lexically) to the
-enclosing block, file, or C<eval>. If more than one variable is listed,
-the list must be placed in parentheses.
+A L<C<my>|/my VARLIST> declares the listed variables to be local
+(lexically) to the enclosing block, file, or L<C<eval>|/eval EXPR>. If
+more than one variable is listed, the list must be placed in
+parentheses.
The exact semantics and interface of TYPE and ATTRS are still
evolving. TYPE may be a bareword, a constant declared
-with C<use constant>, or C<__PACKAGE__>. It is
-currently bound to the use of the C<fields> pragma,
-and attributes are handled using the C<attributes> pragma, or starting
-from Perl 5.8.0 also via the C<Attribute::Handlers> module. See
-L<perlsub/"Private Variables via my()"> for details, and L<fields>,
-L<attributes>, and L<Attribute::Handlers>.
+with L<C<use constant>|constant>, or L<C<__PACKAGE__>|/__PACKAGE__>. It
+is
+currently bound to the use of the L<fields> pragma,
+and attributes are handled using the L<attributes> pragma, or starting
+from Perl 5.8.0 also via the L<Attribute::Handlers> module. See
+L<perlsub/"Private Variables via my()"> for details.
-Note that with a parenthesised list, C<undef> can be used as a dummy
-placeholder, for example to skip assignment of initial values:
+Note that with a parenthesised list, L<C<undef>|/undef EXPR> can be used
+as a dummy placeholder, for example to skip assignment of initial
+values:
my ( undef, $min, $hour ) = localtime;
=for Pod::Functions iterate a block prematurely
-The C<next> command is like the C<continue> statement in C; it starts
-the next iteration of the loop:
+The L<C<next>|/next LABEL> command is like the C<continue> statement in
+C; it starts the next iteration of the loop:
LINE: while (<STDIN>) {
next LINE if /^#/; # discard comments
#...
}
-Note that if there were a C<continue> block on the above, it would get
+Note that if there were a L<C<continue>|/continue BLOCK> block on the
+above, it would get
executed even on discarded lines. If LABEL is omitted, the command
refers to the innermost enclosing loop. The C<next EXPR> form, available
as of Perl 5.18.0, allows a label name to be computed at run time, being
otherwise identical to C<next LABEL>.
-C<next> cannot be used to exit a block which returns a value such as
-C<eval {}>, C<sub {}>, or C<do {}>, and should not be used to exit
-a grep() or map() operation.
+L<C<next>|/next LABEL> cannot be used to exit a block which returns a
+value such as C<eval {}>, C<sub {}>, or C<do {}>, and should not be used
+to exit a L<C<grep>|/grep BLOCK LIST> or L<C<map>|/map BLOCK LIST>
+operation.
Note that a block by itself is semantically identical to a loop
-that executes once. Thus C<next> will exit such a block early.
+that executes once. Thus L<C<next>|/next LABEL> will exit such a block
+early.
-See also L</continue> for an illustration of how C<last>, C<next>, and
-C<redo> work.
+See also L<C<continue>|/continue BLOCK> for an illustration of how
+L<C<last>|/last LABEL>, L<C<next>|/next LABEL>, and
+L<C<redo>|/redo LABEL> work.
Unlike most named operators, this has the same precedence as assignment.
It is also exempt from the looks-like-a-function rule, so
C<next ("foo")."bar"> will cause "bar" to be part of the argument to
-C<next>.
+L<C<next>|/next LABEL>.
=item no MODULE VERSION LIST
X<no declarations>
=for Pod::Functions unimport some module symbols or semantics at compile time
-See the C<use> function, of which C<no> is the opposite.
+See the L<C<use>|/use Module VERSION LIST> function, of which
+L<C<no>|/no MODULE VERSION LIST> is the opposite.
=item oct EXPR
X<oct> X<octal> X<hex> X<hexadecimal> X<binary> X<bin>
$val = oct($val) if $val =~ /^0/;
-If EXPR is omitted, uses C<$_>. To go the other way (produce a number
-in octal), use sprintf() or printf():
+If EXPR is omitted, uses L<C<$_>|perlvar/$_>. To go the other way
+(produce a number in octal), use L<C<sprintf>|/sprintf FORMAT, LIST> or
+L<C<printf>|/printf FILEHANDLE FORMAT, LIST>:
- $dec_perms = (stat("filename"))[2] & 07777;
- $oct_perm_str = sprintf "%o", $perms;
+ my $dec_perms = (stat("filename"))[2] & 07777;
+ my $oct_perm_str = sprintf "%o", $perms;
-The oct() function is commonly used when a string such as C<644> needs
-to be converted into a file mode, for example. Although Perl
+The L<C<oct>|/oct EXPR> function is commonly used when a string such as
+C<644> needs
+to be converted into a file mode, for example. Although Perl
automatically converts strings into numbers as needed, this automatic
conversion assumes base 10.
-Leading white space is ignored without warning, as too are any trailing
-non-digits, such as a decimal point (C<oct> only handles non-negative
-integers, not negative integers or floating point).
+Leading white space is ignored without warning, as too are any trailing
+non-digits, such as a decimal point (L<C<oct>|/oct EXPR> only handles
+non-negative integers, not negative integers or floating point).
=item open FILEHANDLE,EXPR
X<open> X<pipe> X<file, open> X<fopen>
Simple examples to open a file for reading:
- open(my $fh, "<", "input.txt")
- or die "cannot open < input.txt: $!";
+ open(my $fh, "<", "input.txt")
+ or die "Can't open < input.txt: $!";
and for writing:
- open(my $fh, ">", "output.txt")
- or die "cannot open > output.txt: $!";
+ open(my $fh, ">", "output.txt")
+ or die "Can't open > output.txt: $!";
-(The following is a comprehensive reference to open(): for a gentler
-introduction you may consider L<perlopentut>.)
+(The following is a comprehensive reference to
+L<C<open>|/open FILEHANDLE,EXPR>: for a gentler introduction you may
+consider L<perlopentut>.)
If FILEHANDLE is an undefined scalar variable (or array or hash element), a
new filehandle is autovivified, meaning that the variable is assigned a
You can put a C<+> in front of the C<< > >> or C<< < >> to
indicate that you want both read and write access to the file; thus
-C<< +< >> is almost always preferred for read/write updates--the
+C<< +< >> is almost always preferred for read/write updates--the
C<< +> >> mode would clobber the file first. You can't usually use
either read-write mode for updating textfiles, since they have
variable-length records. See the B<-i> switch in L<perlrun> for a
better approach. The file is created with permissions of C<0666>
-modified by the process's C<umask> value.
+modified by the process's L<C<umask>|/umask EXPR> value.
-These various prefixes correspond to the fopen(3) modes of C<r>,
+These various prefixes correspond to the L<fopen(3)> modes of C<r>,
C<r+>, C<w>, C<w+>, C<a>, and C<a+>.
In the one- and two-argument forms of the call, the mode and filename
should be concatenated (in that order), preferably separated by white
space. You can--but shouldn't--omit the mode in these forms when that mode
-is C<< < >>. It is always safe to use the two-argument form of C<open> if
-the filename argument is a known literal.
+is C<< < >>. It is safe to use the two-argument form of
+L<C<open>|/open FILEHANDLE,EXPR> if the filename argument is a known literal.
For three or more arguments if MODE is C<|->, the filename is
interpreted as a command to which output is to be piped, and if MODE
output to us. In the two-argument (and one-argument) form, one should
replace dash (C<->) with the command.
See L<perlipc/"Using open() for IPC"> for more examples of this.
-(You are not allowed to C<open> to a command that pipes both in I<and>
-out, but see L<IPC::Open2>, L<IPC::Open3>, and
+(You are not allowed to L<C<open>|/open FILEHANDLE,EXPR> to a command
+that pipes both in I<and> out, but see L<IPC::Open2>, L<IPC::Open3>, and
L<perlipc/"Bidirectional Communication with Another Process"> for
alternatives.)
In the form of pipe opens taking three or more arguments, if LIST is specified
(extra arguments after the command name) then LIST becomes arguments
to the command invoked if the platform supports it. The meaning of
-C<open> with more than three arguments for non-pipe modes is not yet
-defined, but experimental "layers" may give extra LIST arguments
-meaning.
+L<C<open>|/open FILEHANDLE,EXPR> with more than three arguments for
+non-pipe modes is not yet defined, but experimental "layers" may give
+extra LIST arguments meaning.
-In the two-argument (and one-argument) form, opening C<< <- >>
+In the two-argument (and one-argument) form, opening C<< <- >>
or C<-> opens STDIN and opening C<< >- >> opens STDOUT.
You may (and usually should) use the three-argument form of open to specify
that affect how the input and output are processed (see L<open> and
L<PerlIO> for more details). For example:
- open(my $fh, "<:encoding(UTF-8)", "filename")
- || die "can't open UTF-8 encoded filename: $!";
+ open(my $fh, "<:encoding(UTF-8)", $filename)
+ || die "Can't open UTF-8 encoded $filename: $!";
opens the UTF8-encoded file containing Unicode characters;
see L<perluniintro>. Note that if layers are specified in the
three-argument form, then default layers stored in ${^OPEN} (see L<perlvar>;
-usually set by the B<open> pragma or the switch B<-CioD>) are ignored.
+usually set by the L<open> pragma or the switch C<-CioD>) are ignored.
Those layers will also be ignored if you specifying a colon with no name
following it. In that case the default layer for the operating system
(:raw on Unix, :crlf on Windows) is used.
Open returns nonzero on success, the undefined value otherwise. If
-the C<open> involved a pipe, the return value happens to be the pid of
-the subprocess.
-
-If you're running Perl on a system that distinguishes between text
-files and binary files, then you should check out L</binmode> for tips
-for dealing with this. The key distinction between systems that need
-C<binmode> and those that don't is their text file formats. Systems
-like Unix, Mac OS, and Plan 9, that end lines with a single
-character and encode that character in C as C<"\n"> do not
-need C<binmode>. The rest need it.
-
-When opening a file, it's seldom a good idea to continue
-if the request failed, so C<open> is frequently used with
-C<die>. Even if C<die> won't do what you want (say, in a CGI script,
+the L<C<open>|/open FILEHANDLE,EXPR> involved a pipe, the return value
+happens to be the pid of the subprocess.
+
+On some systems (in general, DOS- and Windows-based systems)
+L<C<binmode>|/binmode FILEHANDLE, LAYER> is necessary when you're not
+working with a text file. For the sake of portability it is a good idea
+always to use it when appropriate, and never to use it when it isn't
+appropriate. Also, people can set their I/O to be by default
+UTF8-encoded Unicode, not bytes.
+
+When opening a file, it's seldom a good idea to continue
+if the request failed, so L<C<open>|/open FILEHANDLE,EXPR> is frequently
+used with L<C<die>|/die LIST>. Even if L<C<die>|/die LIST> won't do
+what you want (say, in a CGI script,
where you want to format a suitable error message (but there are
modules that can help with that problem)) always check
-the return value from opening a file.
+the return value from opening a file.
The filehandle will be closed when its reference count reaches zero.
-If it is a lexically scoped variable declared with C<my>, that usually
+If it is a lexically scoped variable declared with L<C<my>|/my VARLIST>,
+that usually
means the end of the enclosing scope. However, this automatic close
does not check for errors, so it is better to explicitly close
filehandles, especially those used for writing:
An older style is to use a bareword as the filehandle, as
open(FH, "<", "input.txt")
- or die "cannot open < input.txt: $!";
+ or die "Can't open < input.txt: $!";
Then you can use C<FH> as the filehandle, in C<< close FH >> and C<<
<FH> >> and so on. Note that it's a global variable, so this form is
open(ARTICLE) or die "Can't find article $ARTICLE: $!\n";
Here C<$ARTICLE> must be a global (package) scalar variable - not one
-declared with C<my> or C<state>.
+declared with L<C<my>|/my VARLIST> or L<C<state>|/state VARLIST>.
As a special case the three-argument form with a read/write mode and the third
-argument being C<undef>:
+argument being L<C<undef>|/undef EXPR>:
open(my $tmp, "+>", undef) or die ...
opens a filehandle to an anonymous temporary file. Also using C<< +< >>
works for symmetry, but you really should consider writing something
-to the temporary file first. You will need to seek() to do the
-reading.
+to the temporary file first. You will need to
+L<C<seek>|/seek FILEHANDLE,POSITION,WHENCE> to do the reading.
-Perl is built using PerlIO by default; Unless you've
+Perl is built using PerlIO by default. Unless you've
changed this (such as building Perl with C<Configure -Uuseperlio>), you can
open filehandles directly to Perl scalars via:
- open($fh, ">", \$variable) || ..
+ open(my $fh, ">", \$variable) || ..
To (re)open C<STDOUT> or C<STDERR> as an in-memory file, close it first:
open(STDOUT, ">", \$variable)
or die "Can't open STDOUT: $!";
-General examples:
-
- open(LOG, ">>/usr/spool/news/twitlog"); # (log is reserved)
- # if the open fails, output is discarded
-
- open(my $dbase, "+<", "dbase.mine") # open for update
- or die "Can't open 'dbase.mine' for update: $!";
-
- open(my $dbase, "+<dbase.mine") # ditto
- or die "Can't open 'dbase.mine' for update: $!";
-
- open(ARTICLE, "-|", "caesar <$article") # decrypt article
- or die "Can't start caesar: $!";
+See L<perliol> for detailed info on PerlIO.
- open(ARTICLE, "caesar <$article |") # ditto
- or die "Can't start caesar: $!";
+General examples:
- open(EXTRACT, "|sort >Tmp$$") # $$ is our process id
- or die "Can't start sort: $!";
+ open(my $log, ">>", "/usr/spool/news/twitlog");
+ # if the open fails, output is discarded
- # in-memory files
- open(MEMORY, ">", \$var)
- or die "Can't open memory file: $!";
- print MEMORY "foo!\n"; # output will appear in $var
+ open(my $dbase, "+<", "dbase.mine") # open for update
+ or die "Can't open 'dbase.mine' for update: $!";
- # process argument list of files along with any includes
+ open(my $dbase, "+<dbase.mine") # ditto
+ or die "Can't open 'dbase.mine' for update: $!";
- foreach $file (@ARGV) {
- process($file, "fh00");
- }
+ open(my $article_fh, "-|", "caesar <$article") # decrypt
+ # article
+ or die "Can't start caesar: $!";
- sub process {
- my($filename, $input) = @_;
- $input++; # this is a string increment
- unless (open($input, "<", $filename)) {
- print STDERR "Can't open $filename: $!\n";
- return;
- }
+ open(my $article_fh, "caesar <$article |") # ditto
+ or die "Can't start caesar: $!";
- local $_;
- while (<$input>) { # note use of indirection
- if (/^#include "(.*)"/) {
- process($1, $input);
- next;
- }
- #... # whatever
- }
- }
+ open(my $out_fh, "|-", "sort >Tmp$$") # $$ is our process id
+ or die "Can't start sort: $!";
-See L<perliol> for detailed info on PerlIO.
+ # in-memory files
+ open(my $memory, ">", \$var)
+ or die "Can't open memory file: $!";
+ print $memory "foo!\n"; # output will appear in $var
You may also, in the Bourne shell tradition, specify an EXPR beginning
with C<< >& >>, in which case the rest of the string is interpreted
as the name of a filehandle (or file descriptor, if numeric) to be
-duped (as C<dup(2)>) and opened. You may use C<&> after C<< > >>,
+duped (as in L<dup(2)>) and opened. You may use C<&> after C<< > >>,
C<<< >> >>>, C<< < >>, C<< +> >>, C<<< +>> >>>, and C<< +< >>.
The mode you specify should match the mode of the original filehandle.
(Duping a filehandle does not take into account any existing contents
print STDERR "stderr 2\n";
If you specify C<< '<&=X' >>, where C<X> is a file descriptor number
-or a filehandle, then Perl will do an equivalent of C's C<fdopen> of
-that file descriptor (and not call C<dup(2)>); this is more
+or a filehandle, then Perl will do an equivalent of C's L<fdopen(3)> of
+that file descriptor (and not call L<dup(2)>); this is more
parsimonious of file descriptors. For example:
# open for input, reusing the fileno of $fd
- open(FILEHANDLE, "<&=$fd")
+ open(my $fh, "<&=", $fd)
or
- open(FILEHANDLE, "<&=", $fd)
+ open(my $fh, "<&=$fd")
or
- # open for append, using the fileno of OLDFH
- open(FH, ">>&=", OLDFH)
-
-or
-
- open(FH, ">>&=OLDFH")
+ # open for append, using the fileno of $oldfh
+ open(my $fh, ">>&=", $oldfh)
Being parsimonious on filehandles is also useful (besides being
parsimonious) for example when something is dependent on file
-descriptors, like for example locking using flock(). If you do just
-C<< open(A, ">>&B") >>, the filehandle A will not have the same file
-descriptor as B, and therefore flock(A) will not flock(B) nor vice
-versa. But with C<< open(A, ">>&=B") >>, the filehandles will share
-the same underlying system file descriptor.
+descriptors, like for example locking using
+L<C<flock>|/flock FILEHANDLE,OPERATION>. If you do just
+C<< open(my $A, ">>&", $B) >>, the filehandle C<$A> will not have the
+same file descriptor as C<$B>, and therefore C<flock($A)> will not
+C<flock($B)> nor vice versa. But with C<< open(my $A, ">>&=", $B) >>,
+the filehandles will share the same underlying system file descriptor.
Note that under Perls older than 5.8.0, Perl uses the standard C library's'
-fdopen() to implement the C<=> functionality. On many Unix systems,
-fdopen() fails when file descriptors exceed a certain value, typically 255.
+L<fdopen(3)> to implement the C<=> functionality. On many Unix systems,
+L<fdopen(3)> fails when file descriptors exceed a certain value, typically 255.
For Perls 5.8.0 and later, PerlIO is (most often) the default.
-You can see whether your Perl was built with PerlIO by running C<perl -V>
-and looking for the C<useperlio=> line. If C<useperlio> is C<define>, you
-have PerlIO; otherwise you don't.
+You can see whether your Perl was built with PerlIO by running
+C<perl -V:useperlio>. If it says C<'define'>, you have PerlIO;
+otherwise you don't.
If you open a pipe on the command C<-> (that is, specify either C<|-> or C<-|>
-with the one- or two-argument forms of C<open>),
-an implicit C<fork> is done, so C<open> returns twice: in the parent
-process it returns the pid
+with the one- or two-argument forms of
+L<C<open>|/open FILEHANDLE,EXPR>), an implicit L<C<fork>|/fork> is done,
+so L<C<open>|/open FILEHANDLE,EXPR> returns twice: in the parent process
+it returns the pid
of the child process, and in the child process it returns (a defined) C<0>.
Use C<defined($pid)> or C<//> to determine whether the open was successful.
For example, use either
- $child_pid = open(FROM_KID, "-|") // die "can't fork: $!";
+ my $child_pid = open(my $from_kid, "-|") // die "Can't fork: $!";
or
- $child_pid = open(TO_KID, "|-") // die "can't fork: $!";
+ my $child_pid = open(my $to_kid, "|-") // die "Can't fork: $!";
-followed by
+followed by
if ($child_pid) {
# am the parent:
- # either write TO_KID or else read FROM_KID
+ # either write $to_kid or else read $from_kid
...
waitpid $child_pid, 0;
} else {
# am the child; use STDIN/STDOUT normally
...
exit;
- }
+ }
The filehandle behaves normally for the parent, but I/O to that
filehandle is piped from/to the STDOUT/STDIN of the child process.
The following blocks are more or less equivalent:
- open(FOO, "|tr '[a-z]' '[A-Z]'");
- open(FOO, "|-", "tr '[a-z]' '[A-Z]'");
- open(FOO, "|-") || exec 'tr', '[a-z]', '[A-Z]';
- open(FOO, "|-", "tr", '[a-z]', '[A-Z]');
+ open(my $fh, "|tr '[a-z]' '[A-Z]'");
+ open(my $fh, "|-", "tr '[a-z]' '[A-Z]'");
+ open(my $fh, "|-") || exec 'tr', '[a-z]', '[A-Z]';
+ open(my $fh, "|-", "tr", '[a-z]', '[A-Z]');
- open(FOO, "cat -n '$file'|");
- open(FOO, "-|", "cat -n '$file'");
- open(FOO, "-|") || exec "cat", "-n", $file;
- open(FOO, "-|", "cat", "-n", $file);
+ open(my $fh, "cat -n '$file'|");
+ open(my $fh, "-|", "cat -n '$file'");
+ open(my $fh, "-|") || exec "cat", "-n", $file;
+ open(my $fh, "-|", "cat", "-n", $file);
The last two examples in each block show the pipe as "list form", which is
not yet supported on all platforms. A good rule of thumb is that if
-your platform has a real C<fork()> (in other words, if your platform is
-Unix, including Linux and MacOS X), you can use the list form. You would
+your platform has a real L<C<fork>|/fork> (in other words, if your platform is
+Unix, including Linux and MacOS X), you can use the list form. You would
want to use the list form of the pipe so you can pass literal arguments
to the command without risk of the shell interpreting any shell metacharacters
in them. However, this also bars you from opening pipes to commands
that intentionally contain shell metacharacters, such as:
- open(FOO, "|cat -n | expand -4 | lpr")
- // die "Can't open pipeline to lpr: $!";
+ open(my $fh, "|cat -n | expand -4 | lpr")
+ || die "Can't open pipeline to lpr: $!";
See L<perlipc/"Safe Pipe Opens"> for more examples of this.
Perl will attempt to flush all files opened for
output before any operation that may do a fork, but this may not be
supported on some platforms (see L<perlport>). To be safe, you may need
-to set C<$|> ($AUTOFLUSH in English) or call the C<autoflush()> method
-of C<IO::Handle> on any open handles.
+to set L<C<$E<verbar>>|perlvar/$E<verbar>> (C<$AUTOFLUSH> in L<English>)
+or call the C<autoflush> method of L<C<IO::Handle>|IO::Handle/METHODS>
+on any open handles.
On systems that support a close-on-exec flag on files, the flag will
be set for the newly opened file descriptor as determined by the value
-of C<$^F>. See L<perlvar/$^F>.
+of L<C<$^F>|perlvar/$^F>. See L<perlvar/$^F>.
Closing any piped filehandle causes the parent process to wait for the
-child to finish, then returns the status value in C<$?> and
-C<${^CHILD_ERROR_NATIVE}>.
+child to finish, then returns the status value in L<C<$?>|perlvar/$?> and
+L<C<${^CHILD_ERROR_NATIVE}>|perlvar/${^CHILD_ERROR_NATIVE}>.
-The filename passed to the one- and two-argument forms of open() will
+The filename passed to the one- and two-argument forms of
+L<C<open>|/open FILEHANDLE,EXPR> will
have leading and trailing whitespace deleted and normal
redirection characters honored. This property, known as "magic open",
can often be used to good effect. A user could specify a filename of
F<"rsh cat file |">, or you could change certain filenames as needed:
$filename =~ s/(.*\.gz)\s*$/gzip -dc < $1|/;
- open(FH, $filename) or die "Can't open $filename: $!";
+ open(my $fh, $filename) or die "Can't open $filename: $!";
Use the three-argument form to open a file with arbitrary weird characters in it,
- open(FOO, "<", $file)
- || die "can't open < $file: $!";
+ open(my $fh, "<", $file)
+ || die "Can't open $file: $!";
otherwise it's necessary to protect any leading and trailing whitespace:
$file =~ s#^(\s)#./$1#;
- open(FOO, "< $file\0")
- || die "open failed: $!";
+ open(my $fh, "< $file\0")
+ || die "Can't open $file: $!";
(this may not work on some bizarre filesystems). One should
conscientiously choose between the I<magic> and I<three-argument> form
-of open():
+of L<C<open>|/open FILEHANDLE,EXPR>:
- open(IN, $ARGV[0]) || die "can't open $ARGV[0]: $!";
+ open(my $in, $ARGV[0]) || die "Can't open $ARGV[0]: $!";
will allow the user to specify an argument of the form C<"rsh cat file |">,
but will not work on a filename that happens to have a trailing space, while
- open(IN, "<", $ARGV[0])
- || die "can't open < $ARGV[0]: $!";
+ open(my $in, "<", $ARGV[0])
+ || die "Can't open $ARGV[0]: $!";
-will have exactly the opposite restrictions.
+will have exactly the opposite restrictions. (However, some shells
+support the syntax C<< perl your_program.pl <( rsh cat file ) >>, which
+produces a filename that can be opened normally.)
-If you want a "real" C C<open> (see L<open(2)> on your system), then you
-should use the C<sysopen> function, which involves no such magic (but may
-use subtly different filemodes than Perl open(), which is mapped to C
-fopen()). This is another way to protect your filenames from
-interpretation. For example:
+If you want a "real" C L<open(2)>, then you should use the
+L<C<sysopen>|/sysopen FILEHANDLE,FILENAME,MODE> function, which involves
+no such magic (but uses different filemodes than Perl
+L<C<open>|/open FILEHANDLE,EXPR>, which corresponds to C L<fopen(3)>).
+This is another way to protect your filenames from interpretation. For
+example:
use IO::Handle;
- sysopen(HANDLE, $path, O_RDWR|O_CREAT|O_EXCL)
- or die "sysopen $path: $!";
- $oldfh = select(HANDLE); $| = 1; select($oldfh);
- print HANDLE "stuff $$\n";
- seek(HANDLE, 0, 0);
- print "File contains: ", <HANDLE>;
+ sysopen(my $fh, $path, O_RDWR|O_CREAT|O_EXCL)
+ or die "Can't open $path: $!";
+ $fh->autoflush(1);
+ print $fh "stuff $$\n";
+ seek($fh, 0, 0);
+ print "File contains: ", readline($fh);
-See L</seek> for some details about mixing reading and writing.
+See L<C<seek>|/seek FILEHANDLE,POSITION,WHENCE> for some details about
+mixing reading and writing.
Portability issues: L<perlport/open>.
=for Pod::Functions open a directory
-Opens a directory named EXPR for processing by C<readdir>, C<telldir>,
-C<seekdir>, C<rewinddir>, and C<closedir>. Returns true if successful.
+Opens a directory named EXPR for processing by
+L<C<readdir>|/readdir DIRHANDLE>, L<C<telldir>|/telldir DIRHANDLE>,
+L<C<seekdir>|/seekdir DIRHANDLE,POS>,
+L<C<rewinddir>|/rewinddir DIRHANDLE>, and
+L<C<closedir>|/closedir DIRHANDLE>. Returns true if successful.
DIRHANDLE may be an expression whose value can be used as an indirect
dirhandle, usually the real dirhandle name. If DIRHANDLE is an undefined
scalar variable (or array or hash element), the variable is assigned a
reference to a new anonymous dirhandle; that is, it's autovivified.
DIRHANDLEs have their own namespace separate from FILEHANDLEs.
-See the example at C<readdir>.
+See the example at L<C<readdir>|/readdir DIRHANDLE>.
=item ord EXPR
X<ord> X<encoding>
=for Pod::Functions find a character's numeric representation
Returns the numeric value of the first character of EXPR.
-If EXPR is an empty string, returns 0. If EXPR is omitted, uses C<$_>.
+If EXPR is an empty string, returns 0. If EXPR is omitted, uses
+L<C<$_>|perlvar/$_>.
(Note I<character>, not byte.)
-For the reverse, see L</chr>.
+For the reverse, see L<C<chr>|/chr NUMBER>.
See L<perlunicode> for more about Unicode.
=item our VARLIST
=for Pod::Functions +5.6.0 declare and assign a package variable (lexical scoping)
-C<our> makes a lexical alias to a package (i.e. global) variable of the
-same name in the current package for use within the current lexical scope.
-
-C<our> has the same scoping rules as C<my> or C<state>, meaning that it is
-only valid within a lexical scope. Unlike C<my> and C<state>, which both
-declare new (lexical) variables, C<our> only creates an alias to an
-existing variable: a package variable of the same name.
-
-This means that when C<use strict 'vars'> is in effect, C<our> lets you use
-a package variable without qualifying it with the package name, but only within
-the lexical scope of the C<our>
-declaration. This applies immediately--even
+L<C<our>|/our VARLIST> makes a lexical alias to a package (i.e. global)
+variable of the same name in the current package for use within the
+current lexical scope.
+
+L<C<our>|/our VARLIST> has the same scoping rules as
+L<C<my>|/my VARLIST> or L<C<state>|/state VARLIST>, meaning that it is
+only valid within a lexical scope. Unlike L<C<my>|/my VARLIST> and
+L<C<state>|/state VARLIST>, which both declare new (lexical) variables,
+L<C<our>|/our VARLIST> only creates an alias to an existing variable: a
+package variable of the same name.
+
+This means that when C<use strict 'vars'> is in effect, L<C<our>|/our
+VARLIST> lets you use a package variable without qualifying it with the
+package name, but only within the lexical scope of the
+L<C<our>|/our VARLIST> declaration. This applies immediately--even
within the same statement.
package Foo;
our($bar, $baz);
-An C<our> declaration declares an alias for a package variable that will be visible
+An L<C<our>|/our VARLIST> declaration declares an alias for a package
+variable that will be visible
across its entire lexical scope, even across package boundaries. The
package in which the variable is entered is determined at the point
of the declaration, not at the point of use. This means the following
package Bar;
print $bar; # prints 20, as it refers to $Foo::bar
-Multiple C<our> declarations with the same name in the same lexical
+Multiple L<C<our>|/our VARLIST> declarations with the same name in the
+same lexical
scope are allowed if they are in different packages. If they happen
to be in the same package, Perl will emit warnings if you have asked
-for them, just like multiple C<my> declarations. Unlike a second
-C<my> declaration, which will bind the name to a fresh variable, a
-second C<our> declaration in the same package, in the same scope, is
-merely redundant.
+for them, just like multiple L<C<my>|/my VARLIST> declarations. Unlike
+a second L<C<my>|/my VARLIST> declaration, which will bind the name to a
+fresh variable, a second L<C<our>|/our VARLIST> declaration in the same
+package, in the same scope, is merely redundant.
use warnings;
package Foo;
our $bar; # emits warning but has no other effect
print $bar; # still prints 30
-An C<our> declaration may also have a list of attributes associated
-with it.
+An L<C<our>|/our VARLIST> declaration may also have a list of attributes
+associated with it.
The exact semantics and interface of TYPE and ATTRS are still
-evolving. TYPE is currently bound to the use of the C<fields> pragma,
-and attributes are handled using the C<attributes> pragma, or, starting
-from Perl 5.8.0, also via the C<Attribute::Handlers> module. See
-L<perlsub/"Private Variables via my()"> for details, and L<fields>,
-L<attributes>, and L<Attribute::Handlers>.
+evolving. TYPE is currently bound to the use of the L<fields> pragma,
+and attributes are handled using the L<attributes> pragma, or, starting
+from Perl 5.8.0, also via the L<Attribute::Handlers> module. See
+L<perlsub/"Private Variables via my()"> for details.
-Note that with a parenthesised list, C<undef> can be used as a dummy
-placeholder, for example to skip assignment of initial values:
+Note that with a parenthesised list, L<C<undef>|/undef EXPR> can be used
+as a dummy placeholder, for example to skip assignment of initial
+values:
our ( undef, $min, $hour ) = localtime;
-C<our> differs from C<use vars>, which allows use of an unqualified name
-I<only> within the affected package, but across scopes.
+L<C<our>|/our VARLIST> differs from L<C<use vars>|vars>, which allows
+use of an unqualified name I<only> within the affected package, but
+across scopes.
=item pack TEMPLATE,LIST
X<pack>
the converted values. Typically, each converted value looks
like its machine-level representation. For example, on 32-bit machines
an integer may be represented by a sequence of 4 bytes, which will in
-Perl be presented as a string that's 4 characters long.
+Perl be presented as a string that's 4 characters long.
See L<perlpacktut> for an introduction to this function.
< sSiIlLqQ Force little-endian byte-order on the type.
jJfFdDpP (The "little end" touches the construct.)
-The C<< > >> and C<< < >> modifiers can also be used on C<()> groups
-to force a particular byte-order on all components in that group,
+The C<< > >> and C<< < >> modifiers can also be used on C<()> groups
+to force a particular byte-order on all components in that group,
including all its subgroups.
=begin comment
The following rules apply:
-=over
+=over
=item *
something else, described below. Supplying a C<*> for the repeat count
instead of a number means to use however many items are left, except for:
-=over
+=over
-=item *
+=item *
C<@>, C<x>, and C<X>, where it is equivalent to C<0>.
-=item *
+=item *
<.>, where it means relative to the start of the string.
-=item *
+=item *
C<u>, where it is equivalent to 1 (or 45, which here is equivalent).
-=back
+=back
One can replace a numeric repeat count with a template letter enclosed in
brackets to use the packed byte length of the bracketed template for the
When used with C<.>, the repeat count determines the starting position to
calculate the value offset as follows:
-=over
+=over
=item *
=back
The repeat count for C<u> is interpreted as the maximal number of bytes
-to encode per line of output, with 0, 1 and 2 replaced by 45. The repeat
+to encode per line of output, with 0, 1 and 2 replaced by 45. The repeat
count should not be more than 65.
=item *
If the input string is longer than needed, remaining characters are ignored.
-A C<*> for the repeat count uses all characters of the input field.
+A C<*> for the repeat count uses all characters of the input field.
On unpacking, bits are converted to a string of C<0>s and C<1>s.
=item *
The C<h> and C<H> formats pack a string that many nybbles (4-bit groups,
representable as hexadecimal digits, C<"0".."9"> C<"a".."f">) long.
-For each such format, pack() generates 4 bits of result.
+For each such format, L<C<pack>|/pack TEMPLATE,LIST> generates 4 bits of result.
With non-alphabetical characters, the result is based on the 4 least-significant
bits of the input character, i.e., on C<ord($char)%16>. In particular,
characters C<"0"> and C<"1"> generate nybbles 0 and 1, as do bytes
C<"\000"> and C<"\001">. For characters C<"a".."f"> and C<"A".."F">, the result
is compatible with the usual hexadecimal digits, so that C<"a"> and
-C<"A"> both generate the nybble C<0xA==10>. Use only these specific hex
+C<"A"> both generate the nybble C<0xA==10>. Use only these specific hex
characters with this format.
-Starting from the beginning of the template to pack(), each pair
+Starting from the beginning of the template to
+L<C<pack>|/pack TEMPLATE,LIST>, each pair
of characters is converted to 1 character of output. With format C<h>, the
first character of the pair determines the least-significant nybble of the
output character; with format C<H>, it determines the most-significant
If the input string is longer than needed, extra characters are ignored.
A C<*> for the repeat count uses all characters of the input field. For
-unpack(), nybbles are converted to a string of hexadecimal digits.
+L<C<unpack>|/unpack TEMPLATE,EXPR>, nybbles are converted to a string of
+hexadecimal digits.
=item *
could potentially get deallocated before you got around to using the packed
result. The C<P> format packs a pointer to a structure of the size indicated
by the length. A null pointer is created if the corresponding value for
-C<p> or C<P> is C<undef>; similarly with unpack(), where a null pointer
-unpacks into C<undef>.
+C<p> or C<P> is L<C<undef>|/undef EXPR>; similarly with
+L<C<unpack>|/unpack TEMPLATE,EXPR>, where a null pointer unpacks into
+L<C<undef>|/undef EXPR>.
If your system has a strange pointer size--meaning a pointer is neither as
big as an int nor as big as a long--it may not be possible to pack or
unpacking has encoded the sizes or repeat counts for some of its fields
within the structure itself as separate fields.
-For C<pack>, you write I<length-item>C</>I<sequence-item>, and the
+For L<C<pack>|/pack TEMPLATE,LIST>, you write
+I<length-item>C</>I<sequence-item>, and the
I<length-item> describes how the length value is packed. Formats likely
to be of most use are integer-packing ones like C<n> for Java strings,
C<w> for ASN.1 or SNMP, and C<N> for Sun XDR.
-For C<pack>, I<sequence-item> may have a repeat count, in which case
+For L<C<pack>|/pack TEMPLATE,LIST>, I<sequence-item> may have a repeat
+count, in which case
the minimum of that and the number of available items is used as the argument
for I<length-item>. If it has no repeat count or uses a '*', the number
of available items is used.
-For C<unpack>, an internal stack of integer arguments unpacked so far is
+For L<C<unpack>|/unpack TEMPLATE,EXPR>, an internal stack of integer
+arguments unpacked so far is
used. You write C</>I<sequence-item> and the repeat count is obtained by
popping off the last element from the stack. The I<sequence-item> must not
have a repeat count.
pack("n/a* w/a","hello,","world") "\000\006hello,\005world"
pack("a/W2", ord("a") .. ord("z")) "2ab"
-The I<length-item> is not returned explicitly from C<unpack>.
+The I<length-item> is not returned explicitly from
+L<C<unpack>|/unpack TEMPLATE,EXPR>.
Supplying a count to the I<length-item> format letter is only useful with
C<A>, C<a>, or C<Z>. Packing with a I<length-item> of C<a> or C<Z> may
may be larger. This is mainly an issue on 64-bit platforms. You can
see whether using C<!> makes any difference this way:
- printf "format s is %d, s! is %d\n",
+ printf "format s is %d, s! is %d\n",
length pack("s"), length pack("s!");
- printf "format l is %d, l! is %d\n",
+ printf "format l is %d, l! is %d\n",
length pack("l"), length pack("l!");
longsize='4';
longlongsize='8';
-or programmatically via the C<Config> module:
+or programmatically via the L<C<Config>|Config> module:
use Config;
print $Config{shortsize}, "\n";
print $Config{longsize}, "\n";
print $Config{longlongsize}, "\n";
-C<$Config{longlongsize}> is undefined on systems without
+C<$Config{longlongsize}> is undefined on systems without
long long support.
=item *
Basically, Intel and VAX CPUs are little-endian, while everybody else,
including Motorola m68k/88k, PPC, Sparc, HP PA, Power, and Cray, are
-big-endian. Alpha and MIPS can be either: Digital/Compaq uses (well, used)
+big-endian. Alpha and MIPS can be either: Digital/Compaq uses (well, used)
them in little-endian mode, but SGI/Cray uses them in big-endian mode.
The names I<big-endian> and I<little-endian> are comic references to the
You can determine your system endianness with this incantation:
- printf("%#02x ", $_) for unpack("W*", pack L=>0x12345678);
+ printf("%#02x ", $_) for unpack("W*", pack L=>0x12345678);
The byteorder on the platform where Perl was built is also available
via L<Config>:
will have C<"ffff">, signifying that static information doesn't work,
one must use runtime probing.
-For portably packed integers, either use the formats C<n>, C<N>, C<v>,
+For portably packed integers, either use the formats C<n>, C<N>, C<v>,
and C<V> or else use the C<< > >> and C<< < >> modifiers described
immediately below. See also L<perlport>.
Portability-wise the best option is probably to keep to the IEEE 754
64-bit doubles, and of agreed-upon endianness. Another possibility
-is the C<"%a">) format of C<printf>.
+is the C<"%a">) format of L<C<printf>|/printf FILEHANDLE FORMAT, LIST>.
=item *
Starting with Perl 5.10.0, integer and floating-point formats, along with
-the C<p> and C<P> formats and C<()> groups, may all be followed by the
+the C<p> and C<P> formats and C<()> groups, may all be followed by the
C<< > >> or C<< < >> endianness modifiers to respectively enforce big-
-or little-endian byte-order. These modifiers are especially useful
-given how C<n>, C<N>, C<v>, and C<V> don't cover signed integers,
+or little-endian byte-order. These modifiers are especially useful
+given how C<n>, C<N>, C<v>, and C<V> don't cover signed integers,
64-bit integers, or floating-point values.
Here are some concerns to keep in mind when using an endianness modifier:
=over
-=item *
+=item *
-Exchanging signed integers between different platforms works only
+Exchanging signed integers between different platforms works only
when all platforms store them in the same format. Most platforms store
signed integers in two's-complement notation, so usually this is not an issue.
-=item *
+=item *
The C<< > >> or C<< < >> modifiers can only be used on floating-point
formats on big- or little-endian machines. Otherwise, attempting to
use them raises an exception.
-=item *
+=item *
Forcing big- or little-endian byte-order on floating-point values for
data exchange can work only if all platforms use the same
but also dangerous if you don't know exactly what you're doing.
It is not a general way to portably store floating-point values.
-=item *
+=item *
When using C<< > >> or C<< < >> on a C<()> group, this affects
all types inside the group that accept byte-order modifiers,
modifiers to force big- or little-endian byte-order on floating-point values.
Because Perl uses doubles (or long doubles, if configured) internally for
-all numeric calculation, converting from double into float and thence
+all numeric calculation, converting from double into float and thence
to double again loses precision, so C<unpack("f", pack("f", $foo)>)
will not in general equal $foo.
where the packed string is processed in its UTF-8-encoded Unicode form on
a byte-by-byte basis. Character mode is the default
unless the format string starts with C<U>. You
-can always switch mode mid-format with an explicit
-C<C0> or C<U0> in the format. This mode remains in effect until the next
+can always switch mode mid-format with an explicit
+C<C0> or C<U0> in the format. This mode remains in effect until the next
mode change, or until the end of the C<()> group it (directly) applies to.
-Using C<C0> to get Unicode characters while using C<U0> to get I<non>-Unicode
+Using C<C0> to get Unicode characters while using C<U0> to get I<non>-Unicode
bytes is not necessarily obvious. Probably only the first of these
is what you want:
- $ perl -CS -E 'say "\x{3B1}\x{3C9}"' |
+ $ perl -CS -E 'say "\x{3B1}\x{3C9}"' |
perl -CS -ne 'printf "%v04X\n", $_ for unpack("C0A*", $_)'
03B1.03C9
- $ perl -CS -E 'say "\x{3B1}\x{3C9}"' |
+ $ perl -CS -E 'say "\x{3B1}\x{3C9}"' |
perl -CS -ne 'printf "%v02X\n", $_ for unpack("U0A*", $_)'
CE.B1.CF.89
- $ perl -CS -E 'say "\x{3B1}\x{3C9}"' |
+ $ perl -CS -E 'say "\x{3B1}\x{3C9}"' |
perl -C0 -ne 'printf "%v02X\n", $_ for unpack("C0A*", $_)'
CE.B1.CF.89
- $ perl -CS -E 'say "\x{3B1}\x{3C9}"' |
+ $ perl -CS -E 'say "\x{3B1}\x{3C9}"' |
perl -C0 -ne 'printf "%v02X\n", $_ for unpack("U0A*", $_)'
C3.8E.C2.B1.C3.8F.C2.89
Those examples also illustrate that you should not try to use
-C<pack>/C<unpack> as a substitute for the L<Encode> module.
+L<C<pack>|/pack TEMPLATE,LIST>/L<C<unpack>|/unpack TEMPLATE,EXPR> as a
+substitute for the L<Encode> module.
=item *
You must yourself do any alignment or padding by inserting, for example,
-enough C<"x">es while packing. There is no way for pack() and unpack()
-to know where characters are going to or coming from, so they
+enough C<"x">es while packing. There is no way for
+L<C<pack>|/pack TEMPLATE,LIST> and L<C<unpack>|/unpack TEMPLATE,EXPR>
+to know where characters are going to or coming from, so they
handle their output and input as flat sequences of characters.
=item *
A C<()> group is a sub-TEMPLATE enclosed in parentheses. A group may
-take a repeat count either as postfix, or for unpack(), also via the C</>
+take a repeat count either as postfix, or for
+L<C<unpack>|/unpack TEMPLATE,EXPR>, also via the C</>
template character. Within each repetition of a group, positioning with
C<@> starts over at 0. Therefore, the result of
C<x> and C<X> accept the C<!> modifier to act as alignment commands: they
jump forward or back to the closest position aligned at a multiple of C<count>
-characters. For example, to pack() or unpack() a C structure like
+characters. For example, to L<C<pack>|/pack TEMPLATE,LIST> or
+L<C<unpack>|/unpack TEMPLATE,EXPR> a C structure like
struct {
char c; /* one signed, 8-bit character */
- double d;
+ double d;
char cc[2];
}
=item *
-If TEMPLATE requires more arguments than pack() is given, pack()
+If TEMPLATE requires more arguments than L<C<pack>|/pack TEMPLATE,LIST>
+is given, L<C<pack>|/pack TEMPLATE,LIST>
assumes additional C<""> arguments. If TEMPLATE requires fewer arguments
than given, extra arguments are ignored.
$foo = pack('(sl)<', -42, 4711);
# exactly the same
-The same template may generally also be used in unpack().
+The same template may generally also be used in
+L<C<unpack>|/unpack TEMPLATE,EXPR>.
=item package NAMESPACE
given namespace. The scope of the package declaration is either the
supplied code BLOCK or, in the absence of a BLOCK, from the declaration
itself through the end of current scope (the enclosing block, file, or
-C<eval>). That is, the forms without a BLOCK are operative through the end
-of the current scope, just like the C<my>, C<state>, and C<our> operators.
-All unqualified dynamic identifiers in this scope will be in the given
-namespace, except where overridden by another C<package> declaration or
+L<C<eval>|/eval EXPR>). That is, the forms without a BLOCK are
+operative through the end of the current scope, just like the
+L<C<my>|/my VARLIST>, L<C<state>|/state VARLIST>, and
+L<C<our>|/our VARLIST> operators. All unqualified dynamic identifiers
+in this scope will be in the given namespace, except where overridden by
+another L<C<package>|/package NAMESPACE> declaration or
when they're one of the special identifiers that qualify into C<main::>,
like C<STDOUT>, C<ARGV>, C<ENV>, and the punctuation variables.
A package statement affects dynamic variables only, including those
-you've used C<local> on, but I<not> lexically-scoped variables, which are created
-with C<my>, C<state>, or C<our>. Typically it would be the first
-declaration in a file included by C<require> or C<use>. You can switch into a
-package in more than one place, since this only determines which default
+you've used L<C<local>|/local EXPR> on, but I<not> lexically-scoped
+variables, which are created with L<C<my>|/my VARLIST>,
+L<C<state>|/state VARLIST>, or L<C<our>|/our VARLIST>. Typically it
+would be the first declaration in a file included by
+L<C<require>|/require VERSION> or L<C<use>|/use Module VERSION LIST>.
+You can switch into a
+package in more than one place, since this only determines which default
symbol table the compiler uses for the rest of that block. You can refer to
identifiers in other packages than the current one by prefixing the identifier
with the package name and a double colon, as in C<$SomePack::var>
C<$main::sail> (as well as to C<$main'sail>, still seen in ancient
code, mostly from Perl 4).
-If VERSION is provided, C<package> sets the C<$VERSION> variable in the given
+If VERSION is provided, L<C<package>|/package NAMESPACE> sets the
+C<$VERSION> variable in the given
namespace to a L<version> object with the VERSION provided. VERSION must be a
"strict" style version number as defined by the L<version> module: a positive
decimal number (integer or decimal-fraction) without exponentiation or else a
Opens a pair of connected pipes like the corresponding system call.
Note that if you set up a loop of piped processes, deadlock can occur
unless you are very careful. In addition, note that Perl's pipes use
-IO buffering, so you may need to set C<$|> to flush your WRITEHANDLE
-after each command, depending on the application.
+IO buffering, so you may need to set L<C<$E<verbar>>|perlvar/$E<verbar>>
+to flush your WRITEHANDLE after each command, depending on the
+application.
Returns true on success.
for examples of such things.
On systems that support a close-on-exec flag on files, that flag is set
-on all newly opened file descriptors whose C<fileno>s are I<higher> than
-the current value of $^F (by default 2 for C<STDERR>). See L<perlvar/$^F>.
+on all newly opened file descriptors whose
+L<C<fileno>|/fileno FILEHANDLE>s are I<higher> than the current value of
+L<C<$^F>|perlvar/$^F> (by default 2 for C<STDERR>). See L<perlvar/$^F>.
=item pop ARRAY
X<pop> X<stack>
Pops and returns the last value of the array, shortening the array by
one element.
-Returns the undefined value if the array is empty, although this may also
-happen at other times. If ARRAY is omitted, pops the C<@ARGV> array in the
-main program, but the C<@_> array in subroutines, just like C<shift>.
+Returns the undefined value if the array is empty, although this may
+also happen at other times. If ARRAY is omitted, pops the
+L<C<@ARGV>|perlvar/@ARGV> array in the main program, but the
+L<C<@_>|perlvar/@_> array in subroutines, just like
+L<C<shift>|/shift ARRAY>.
-Starting with Perl 5.14, an experimental feature allowed C<pop> to take a
+Starting with Perl 5.14, an experimental feature allowed
+L<C<pop>|/pop ARRAY> to take a
scalar expression. This experiment has been deemed unsuccessful, and was
removed as of Perl 5.24.
=for Pod::Functions find or set the offset for the last/next m//g search
Returns the offset of where the last C<m//g> search left off for the
-variable in question (C<$_> is used when the variable is not
-specified). Note that 0 is a valid match offset. C<undef> indicates
+variable in question (L<C<$_>|perlvar/$_> is used when the variable is not
+specified). Note that 0 is a valid match offset.
+L<C<undef>|/undef EXPR> indicates
that the search position is reset (usually due to match failure, but
can also be because no match has yet been run on the scalar).
-C<pos> directly accesses the location used by the regexp engine to
-store the offset, so assigning to C<pos> will change that offset, and
-so will also influence the C<\G> zero-width assertion in regular
-expressions. Both of these effects take place for the next match, so
-you can't affect the position with C<pos> during the current match,
-such as in C<(?{pos() = 5})> or C<s//pos() = 5/e>.
+L<C<pos>|/pos SCALAR> directly accesses the location used by the regexp
+engine to store the offset, so assigning to L<C<pos>|/pos SCALAR> will
+change that offset, and so will also influence the C<\G> zero-width
+assertion in regular expressions. Both of these effects take place for
+the next match, so you can't affect the position with
+L<C<pos>|/pos SCALAR> during the current match, such as in
+C<(?{pos() = 5})> or C<s//pos() = 5/e>.
-Setting C<pos> also resets the I<matched with zero-length> flag, described
+Setting L<C<pos>|/pos SCALAR> also resets the I<matched with
+zero-length> flag, described
under L<perlre/"Repeated Patterns Matching a Zero-length Substring">.
Because a failed C<m//gc> match doesn't reset the offset, the return
-from C<pos> won't change either in this case. See L<perlre> and
-L<perlop>.
+from L<C<pos>|/pos SCALAR> won't change either in this case. See
+L<perlre> and L<perlop>.
=item print FILEHANDLE LIST
X<print>
FILEHANDLE is a variable and the next token is a term, it may be
misinterpreted as an operator unless you interpose a C<+> or put
parentheses around the arguments.) If FILEHANDLE is omitted, prints to the
-last selected (see L</select>) output handle. If LIST is omitted, prints
-C<$_> to the currently selected output handle. To use FILEHANDLE alone to
-print the content of C<$_> to it, you must use a real filehandle like
+last selected (see L<C<select>|/select FILEHANDLE>) output handle. If
+LIST is omitted, prints L<C<$_>|perlvar/$_> to the currently selected
+output handle. To use FILEHANDLE alone to print the content of
+L<C<$_>|perlvar/$_> to it, you must use a bareword filehandle like
C<FH>, not an indirect one like C<$fh>. To set the default output handle
to something other than STDOUT, use the select operation.
-The current value of C<$,> (if any) is printed between each LIST item. The
-current value of C<$\> (if any) is printed after the entire LIST has been
-printed. Because print takes a LIST, anything in the LIST is evaluated in
-list context, including any subroutines whose return lists you pass to
-C<print>. Be careful not to follow the print keyword with a left
+The current value of L<C<$,>|perlvar/$,> (if any) is printed between
+each LIST item. The current value of L<C<$\>|perlvar/$\> (if any) is
+printed after the entire LIST has been printed. Because print takes a
+LIST, anything in the LIST is evaluated in list context, including any
+subroutines whose return lists you pass to
+L<C<print>|/print FILEHANDLE LIST>. Be careful not to follow the print
+keyword with a left
parenthesis unless you want the corresponding right parenthesis to
terminate the arguments to the print; put parentheses around all arguments
(or interpose a C<+>, but that doesn't look as good).
=for Pod::Functions output a formatted list to a filehandle
-Equivalent to C<print FILEHANDLE sprintf(FORMAT, LIST)>, except that C<$\>
-(the output record separator) is not appended. The FORMAT and the
-LIST are actually parsed as a single list. The first argument
-of the list will be interpreted as the C<printf> format. This
-means that C<printf(@_)> will use C<$_[0]> as the format. See
-L<sprintf|/sprintf FORMAT, LIST> for an
-explanation of the format argument. If C<use locale> for C<LC_NUMERIC>
-Look for this throught pod
-is in effect and
-POSIX::setlocale() has been called, the character used for the decimal
-separator in formatted floating-point numbers is affected by the C<LC_NUMERIC>
-locale setting. See L<perllocale> and L<POSIX>.
-
-For historical reasons, if you omit the list, C<$_> is used as the format;
-to use FILEHANDLE without a list, you must use a real filehandle like
+Equivalent to C<print FILEHANDLE sprintf(FORMAT, LIST)>, except that
+L<C<$\>|perlvar/$\> (the output record separator) is not appended. The
+FORMAT and the LIST are actually parsed as a single list. The first
+argument of the list will be interpreted as the
+L<C<printf>|/printf FILEHANDLE FORMAT, LIST> format. This means that
+C<printf(@_)> will use C<$_[0]> as the format. See
+L<sprintf|/sprintf FORMAT, LIST> for an explanation of the format
+argument. If C<use locale> (including C<use locale ':not_characters'>)
+is in effect and L<C<POSIX::setlocale>|POSIX/C<setlocale>> has been
+called, the character used for the decimal separator in formatted
+floating-point numbers is affected by the C<LC_NUMERIC> locale setting.
+See L<perllocale> and L<POSIX>.
+
+For historical reasons, if you omit the list, L<C<$_>|perlvar/$_> is
+used as the format;
+to use FILEHANDLE without a list, you must use a bareword filehandle like
C<FH>, not an indirect one like C<$fh>. However, this will rarely do what
-you want; if $_ contains formatting codes, they will be replaced with the
-empty string and a warning will be emitted if warnings are enabled. Just
-use C<print> if you want to print the contents of $_.
+you want; if L<C<$_>|perlvar/$_> contains formatting codes, they will be
+replaced with the empty string and a warning will be emitted if
+L<warnings> are enabled. Just use L<C<print>|/print FILEHANDLE LIST> if
+you want to print the contents of L<C<$_>|perlvar/$_>.
-Don't fall into the trap of using a C<printf> when a simple
-C<print> would do. The C<print> is more efficient and less
-error prone.
+Don't fall into the trap of using a
+L<C<printf>|/printf FILEHANDLE FORMAT, LIST> when a simple
+L<C<print>|/print FILEHANDLE LIST> would do. The
+L<C<print>|/print FILEHANDLE LIST> is more efficient and less error
+prone.
=item prototype FUNCTION
X<prototype>
=for Pod::Functions +5.002 get the prototype (if any) of a subroutine
-Returns the prototype of a function as a string (or C<undef> if the
+Returns the prototype of a function as a string (or
+L<C<undef>|/undef EXPR> if the
function has no prototype). FUNCTION is a reference to, or the name of,
the function whose prototype you want to retrieve. If FUNCTION is omitted,
-$_ is used.
+L<C<$_>|perlvar/$_> is used.
If FUNCTION is a string starting with C<CORE::>, the rest is taken as a
name for a Perl builtin. If the builtin's arguments
cannot be adequately expressed by a prototype
-(such as C<system>), prototype() returns C<undef>, because the builtin
+(such as L<C<system>|/system LIST>), L<C<prototype>|/prototype FUNCTION>
+returns L<C<undef>|/undef EXPR>, because the builtin
does not really behave like a Perl function. Otherwise, the string
describing the equivalent prototype is returned.
ARRAY. The length of ARRAY increases by the length of LIST. Has the same
effect as
- for $value (LIST) {
+ for my $value (LIST) {
$ARRAY[++$#ARRAY] = $value;
}
but is more efficient. Returns the number of elements in the array following
-the completed C<push>.
+the completed L<C<push>|/push ARRAY,LIST>.
-Starting with Perl 5.14, an experimental feature allowed C<push> to take a
+Starting with Perl 5.14, an experimental feature allowed
+L<C<push>|/push ARRAY,LIST> to take a
scalar expression. This experiment has been deemed unsuccessful, and was
removed as of Perl 5.24.
the C<\Q> escape in double-quoted strings.
(See below for the behavior on non-ASCII code points.)
-If EXPR is omitted, uses C<$_>.
+If EXPR is omitted, uses L<C<$_>|perlvar/$_>.
quotemeta (and C<\Q> ... C<\E>) are useful when interpolating strings into
regular expressions, because by default an interpolated variable will be
$sentence =~ s{$quoted_substring}{big bad wolf};
Will both leave the sentence as is.
-Normally, when accepting literal string
-input from the user, quotemeta() or C<\Q> must be used.
+Normally, when accepting literal string input from the user,
+L<C<quotemeta>|/quotemeta EXPR> or C<\Q> must be used.
In Perl v5.14, all non-ASCII characters are quoted in non-UTF-8-encoded
strings, but not quoted in UTF-8 strings.
unchanged.
Also unchanged is the quoting of non-UTF-8 strings when outside the
-scope of a C<use feature 'unicode_strings'>, which is to quote all
+scope of a
+L<C<use feature 'unicode_strings'>|feature/The 'unicode_strings' feature>,
+which is to quote all
characters in the upper Latin1 range. This provides complete backwards
compatibility for old programs which do not use Unicode. (Note that
C<unicode_strings> is automatically enabled within the scope of a
S<C<use v5.12>> or greater.)
-Within the scope of C<use locale>, all non-ASCII Latin1 code points
+Within the scope of L<C<use locale>|locale>, all non-ASCII Latin1 code
+points
are quoted whether the string is encoded as UTF-8 or not. As mentioned
above, locale does not affect the quoting of ASCII-range characters.
This protects against those locales where characters such as C<"|"> are
omitted, the value C<1> is used. Currently EXPR with the value C<0> is
also special-cased as C<1> (this was undocumented before Perl 5.8.0
and is subject to change in future versions of Perl). Automatically calls
-C<srand> unless C<srand> has already been called. See also C<srand>.
+L<C<srand>|/srand EXPR> unless L<C<srand>|/srand EXPR> has already been
+called. See also L<C<srand>|/srand EXPR>.
-Apply C<int()> to the value returned by C<rand()> if you want random
-integers instead of random fractional numbers. For example,
+Apply L<C<int>|/int EXPR> to the value returned by L<C<rand>|/rand EXPR>
+if you want random integers instead of random fractional numbers. For
+example,
int(rand(10))
large or too small, then your version of Perl was probably compiled
with the wrong number of RANDBITS.)
-B<C<rand()> is not cryptographically secure. You should not rely
+B<L<C<rand>|/rand EXPR> is not cryptographically secure. You should not rely
on it in security-sensitive situations.> As of this writing, a
number of third-party CPAN modules offer random number generators
intended by their authors to be cryptographically secure,
Attempts to read LENGTH I<characters> of data into variable SCALAR
from the specified FILEHANDLE. Returns the number of characters
actually read, C<0> at end of file, or undef if there was an error (in
-the latter case C<$!> is also set). SCALAR will be grown or shrunk
+the latter case L<C<$!>|perlvar/$!> is also set). SCALAR will be grown
+or shrunk
so that the last character actually read is the last character of the
scalar after the read.
bytes before the result of the read is appended.
The call is implemented in terms of either Perl's or your system's native
-fread(3) library function. To get a true read(2) system call, see
+L<fread(3)> library function. To get a true L<read(2)> system call, see
L<sysread|/sysread FILEHANDLE,SCALAR,LENGTH,OFFSET>.
Note the I<characters>: depending on the status of the filehandle,
either (8-bit) bytes or characters are read. By default, all
filehandles operate on bytes, but for example if the filehandle has
-been opened with the C<:utf8> I/O layer (see L</open>, and the C<open>
-pragma, L<open>), the I/O will operate on UTF8-encoded Unicode
-characters, not bytes. Similarly for the C<:encoding> pragma:
+been opened with the C<:utf8> I/O layer (see
+L<C<open>|/open FILEHANDLE,EXPR>, and the L<open>
+pragma), the I/O will operate on UTF8-encoded Unicode
+characters, not bytes. Similarly for the C<:encoding> layer:
in that case pretty much any characters can be read.
=item readdir DIRHANDLE
=for Pod::Functions get a directory from a directory handle
-Returns the next directory entry for a directory opened by C<opendir>.
+Returns the next directory entry for a directory opened by
+L<C<opendir>|/opendir DIRHANDLE,EXPR>.
If used in list context, returns all the rest of the entries in the
directory. If there are no more entries, returns the undefined value in
scalar context and the empty list in list context.
-If you're planning to filetest the return values out of a C<readdir>, you'd
-better prepend the directory in question. Otherwise, because we didn't
-C<chdir> there, it would have been testing the wrong file.
+If you're planning to filetest the return values out of a
+L<C<readdir>|/readdir DIRHANDLE>, you'd better prepend the directory in
+question. Otherwise, because we didn't L<C<chdir>|/chdir EXPR> there,
+it would have been testing the wrong file.
- opendir(my $dh, $some_dir) || die "can't opendir $some_dir: $!";
- @dots = grep { /^\./ && -f "$some_dir/$_" } readdir($dh);
+ opendir(my $dh, $some_dir) || die "Can't opendir $some_dir: $!";
+ my @dots = grep { /^\./ && -f "$some_dir/$_" } readdir($dh);
closedir $dh;
-As of Perl 5.12 you can use a bare C<readdir> in a C<while> loop,
-which will set C<$_> on every iteration.
+As of Perl 5.12 you can use a bare L<C<readdir>|/readdir DIRHANDLE> in a
+C<while> loop, which will set L<C<$_>|perlvar/$_> on every iteration.
- opendir(my $dh, $some_dir) || die;
- while(readdir $dh) {
+ opendir(my $dh, $some_dir) || die "Can't open $some_dir: $!";
+ while (readdir $dh) {
print "$some_dir/$_\n";
}
closedir $dh;
Reads from the filehandle whose typeglob is contained in EXPR (or from
C<*ARGV> if EXPR is not provided). In scalar context, each call reads and
returns the next line until end-of-file is reached, whereupon the
-subsequent call returns C<undef>. In list context, reads until end-of-file
-is reached and returns a list of lines. Note that the notion of "line"
-used here is whatever you may have defined with C<$/> or
-C<$INPUT_RECORD_SEPARATOR>). See L<perlvar/"$/">.
+subsequent call returns L<C<undef>|/undef EXPR>. In list context, reads
+until end-of-file is reached and returns a list of lines. Note that the
+notion of "line" used here is whatever you may have defined with
+L<C<$E<sol>>|perlvar/$E<sol>> (or C<$INPUT_RECORD_SEPARATOR> in
+L<English>). See L<perlvar/"$/">.
-When C<$/> is set to C<undef>, when C<readline> is in scalar
-context (i.e., file slurp mode), and when an empty file is read, it
-returns C<''> the first time, followed by C<undef> subsequently.
+When L<C<$E<sol>>|perlvar/$E<sol>> is set to L<C<undef>|/undef EXPR>,
+when L<C<readline>|/readline EXPR> is in scalar context (i.e., file
+slurp mode), and when an empty file is read, it returns C<''> the first
+time, followed by L<C<undef>|/undef EXPR> subsequently.
This is the internal function implementing the C<< <EXPR> >>
operator, but you can use it directly. The C<< <EXPR> >>
operator is discussed in more detail in L<perlop/"I/O Operators">.
- $line = <STDIN>;
- $line = readline(*STDIN); # same thing
+ my $line = <STDIN>;
+ my $line = readline(STDIN); # same thing
-If C<readline> encounters an operating system error, C<$!> will be set
-with the corresponding error message. It can be helpful to check
-C<$!> when you are reading from filehandles you don't trust, such as a
-tty or a socket. The following example uses the operator form of
-C<readline> and dies if the result is not defined.
+If L<C<readline>|/readline EXPR> encounters an operating system error,
+L<C<$!>|perlvar/$!> will be set with the corresponding error message.
+It can be helpful to check L<C<$!>|perlvar/$!> when you are reading from
+filehandles you don't trust, such as a tty or a socket. The following
+example uses the operator form of L<C<readline>|/readline EXPR> and dies
+if the result is not defined.
while ( ! eof($fh) ) {
- defined( $_ = <$fh> ) or die "readline failed: $!";
+ defined( $_ = readline $fh ) or die "readline failed: $!";
...
}
-Note that you have can't handle C<readline> errors that way with the
-C<ARGV> filehandle. In that case, you have to open each element of
-C<@ARGV> yourself since C<eof> handles C<ARGV> differently.
+Note that you have can't handle L<C<readline>|/readline EXPR> errors
+that way with the C<ARGV> filehandle. In that case, you have to open
+each element of L<C<@ARGV>|perlvar/@ARGV> yourself since
+L<C<eof>|/eof FILEHANDLE> handles C<ARGV> differently.
foreach my $arg (@ARGV) {
open(my $fh, $arg) or warn "Can't open $arg: $!";
while ( ! eof($fh) ) {
- defined( $_ = <$fh> )
+ defined( $_ = readline $fh )
or die "readline failed for $arg: $!";
...
}
Returns the value of a symbolic link, if symbolic links are
implemented. If not, raises an exception. If there is a system
-error, returns the undefined value and sets C<$!> (errno). If EXPR is
-omitted, uses C<$_>.
+error, returns the undefined value and sets L<C<$!>|perlvar/$!> (errno).
+If EXPR is omitted, uses L<C<$_>|perlvar/$_>.
Portability issues: L<perlport/readlink>.
The collected standard output of the command is returned.
In scalar context, it comes back as a single (potentially
multi-line) string. In list context, returns a list of lines
-(however you've defined lines with C<$/> or C<$INPUT_RECORD_SEPARATOR>).
+(however you've defined lines with L<C<$E<sol>>|perlvar/$E<sol>> (or
+C<$INPUT_RECORD_SEPARATOR> in L<English>)).
This is the internal function implementing the C<qx/EXPR/>
operator, but you can use it directly. The C<qx/EXPR/>
operator is discussed in more detail in L<perlop/"I/O Operators">.
-If EXPR is omitted, uses C<$_>.
+If EXPR is omitted, uses L<C<$_>|perlvar/$_>.
=item recv SOCKET,SCALAR,LENGTH,FLAGS
X<recv>
same flags as the system call of the same name. Returns the address
of the sender if SOCKET's protocol supports this; returns an empty
string otherwise. If there's an error, returns the undefined value.
-This call is actually implemented in terms of recvfrom(2) system call.
+This call is actually implemented in terms of the L<recvfrom(2)> system call.
See L<perlipc/"UDP: Message Passing"> for examples.
Note the I<characters>: depending on the status of the socket, either
(8-bit) bytes or characters are received. By default all sockets
operate on bytes, but for example if the socket has been changed using
-binmode() to operate with the C<:encoding(utf8)> I/O layer (see the
-C<open> pragma, L<open>), the I/O will operate on UTF8-encoded Unicode
-characters, not bytes. Similarly for the C<:encoding> pragma: in that
+L<C<binmode>|/binmode FILEHANDLE, LAYER> to operate with the
+C<:encoding(utf8)> I/O layer (see the L<open> pragma), the I/O will
+operate on UTF8-encoded Unicode
+characters, not bytes. Similarly for the C<:encoding> layer: in that
case pretty much any characters can be read.
=item redo LABEL
=for Pod::Functions start this loop iteration over again
-The C<redo> command restarts the loop block without evaluating the
-conditional again. The C<continue> block, if any, is not executed. If
+The L<C<redo>|/redo LABEL> command restarts the loop block without
+evaluating the conditional again. The L<C<continue>|/continue BLOCK>
+block, if any, is not executed. If
the LABEL is omitted, the command refers to the innermost enclosing
loop. The C<redo EXPR> form, available starting in Perl 5.18.0, allows a
label name to be computed at run time, and is otherwise identical to C<redo
-LABEL>. Programs that want to lie to themselves about what was just input
+LABEL>. Programs that want to lie to themselves about what was just input
normally use this command:
# a simpleminded Pascal comment stripper
while (s|({.*}.*){.*}|$1 |) {}
s|{.*}| |;
if (s|{.*| |) {
- $front = $_;
+ my $front = $_;
while (<STDIN>) {
if (/}/) { # end of comment?
s|^|$front\{|;
print;
}
-C<redo> cannot be used to retry a block that returns a value such as
-C<eval {}>, C<sub {}>, or C<do {}>, and should not be used to exit
-a grep() or map() operation.
+L<C<redo>|/redo LABEL> cannot be used to retry a block that returns a
+value such as C<eval {}>, C<sub {}>, or C<do {}>, and should not be used
+to exit a L<C<grep>|/grep BLOCK LIST> or L<C<map>|/map BLOCK LIST>
+operation.
Note that a block by itself is semantically identical to a loop
-that executes once. Thus C<redo> inside such a block will effectively
-turn it into a looping construct.
+that executes once. Thus L<C<redo>|/redo LABEL> inside such a block
+will effectively turn it into a looping construct.
-See also L</continue> for an illustration of how C<last>, C<next>, and
-C<redo> work.
+See also L<C<continue>|/continue BLOCK> for an illustration of how
+L<C<last>|/last LABEL>, L<C<next>|/next LABEL>, and
+L<C<redo>|/redo LABEL> work.
Unlike most named operators, this has the same precedence as assignment.
It is also exempt from the looks-like-a-function rule, so
C<redo ("foo")."bar"> will cause "bar" to be part of the argument to
-C<redo>.
+L<C<redo>|/redo LABEL>.
=item ref EXPR
X<ref> X<reference>
=for Pod::Functions find out the type of thing being referenced
Returns a non-empty string if EXPR is a reference, the empty
-string otherwise. If EXPR is not specified, C<$_> will be used. The
-value returned depends on the type of thing the reference is a reference to.
+string otherwise. If EXPR is not specified, L<C<$_>|perlvar/$_> will be
+used. The value returned depends on the type of thing the reference is
+a reference to.
Builtin types include:
VSTRING
Regexp
-You can think of C<ref> as a C<typeof> operator.
+You can think of L<C<ref>|/ref EXPR> as a C<typeof> operator.
if (ref($r) eq "HASH") {
print "r is a reference to a hash.\n";
The return value C<LVALUE> indicates a reference to an lvalue that is not
a variable. You get this from taking the reference of function calls like
-C<pos()> or C<substr()>. C<VSTRING> is returned if the reference points
-to a L<version string|perldata/"Version Strings">.
+L<C<pos>|/pos SCALAR> or
+L<C<substr>|/substr EXPR,OFFSET,LENGTH,REPLACEMENT>. C<VSTRING> is
+returned if the reference points to a
+L<version string|perldata/"Version Strings">.
The result C<Regexp> indicates that the argument is a regular expression
-resulting from C<qr//>.
+resulting from L<C<qrE<sol>E<sol>>|/qrE<sol>STRINGE<sol>>.
If the referenced object has been blessed into a package, then that package
name is returned instead. But don't use that, as it's now considered
"bad practice". For one reason, an object could be using a class called
-C<Regexp> or C<IO>, or even C<HASH>. Also, C<ref> doesn't take into account
-subclasses, like C<isa> does.
+C<Regexp> or C<IO>, or even C<HASH>. Also, L<C<ref>|/ref EXPR> doesn't
+take into account subclasses, like
+L<C<isa>|UNIVERSAL/C<< $obj->isa( TYPE ) >>> does.
-Instead, use C<blessed> (in the L<Scalar::Util> module) for boolean
-checks, C<isa> for specific class checks and C<reftype> (also from
-L<Scalar::Util>) for type checks. (See L<perlobj> for details and a
-C<blessed>/C<isa> example.)
+Instead, use L<C<blessed>|Scalar::Util/blessed> (in the L<Scalar::Util>
+module) for boolean checks, L<C<isa>|UNIVERSAL/C<< $obj->isa( TYPE ) >>>
+for specific class checks and L<C<reftype>|Scalar::Util/reftype> (also
+from L<Scalar::Util>) for type checks. (See L<perlobj> for details and
+a L<C<blessed>|Scalar::Util/blessed>/L<C<isa>|UNIVERSAL/C<< $obj->isa( TYPE ) >>>
+example.)
See also L<perlref>.
boundaries, even though the system I<mv> command sometimes compensates
for this. Other restrictions include whether it works on directories,
open files, or pre-existing files. Check L<perlport> and either the
-rename(2) manpage or equivalent system documentation for details.
+L<rename(2)> manpage or equivalent system documentation for details.
-For a platform independent C<move> function look at the L<File::Copy>
-module.
+For a platform independent L<C<move>|File::Copy/move> function look at
+the L<File::Copy> module.
Portability issues: L<perlport/rename>.
=for Pod::Functions load in external functions from a library at runtime
Demands a version of Perl specified by VERSION, or demands some semantics
-specified by EXPR or by C<$_> if EXPR is not supplied.
+specified by EXPR or by L<C<$_>|perlvar/$_> if EXPR is not supplied.
VERSION may be either a numeric argument such as 5.006, which will be
-compared to C<$]>, or a literal of the form v5.6.1, which will be compared
-to C<$^V> (aka $PERL_VERSION). An exception is raised if
-VERSION is greater than the version of the current Perl interpreter.
-Compare with L</use>, which can do a similar check at compile time.
+compared to L<C<$]>|perlvar/$]>, or a literal of the form v5.6.1, which
+will be compared to L<C<$^V>|perlvar/$^V> (or C<$PERL_VERSION> in
+L<English>). An exception is raised if VERSION is greater than the
+version of the current Perl interpreter. Compare with
+L<C<use>|/use Module VERSION LIST>, which can do a similar check at
+compile time.
Specifying VERSION as a literal of the form v5.6.1 should generally be
avoided, because it leads to misleading error messages under earlier
require 5.006_001; # ditto; preferred for backwards
compatibility
-Otherwise, C<require> 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 essentially just a variety of C<eval> with the
+Otherwise, L<C<require>|/require VERSION> 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 essentially just a variety of
+L<C<eval>|/eval EXPR> with the
caveat that lexical variables in the invoking script will be invisible
to the included code. If it were implemented in pure Perl, it
would have semantics similar to the following:
otherwise. But it's better just to put the C<1;>, in case you add more
statements.
-If EXPR is a bareword, the require assumes a "F<.pm>" extension and
-replaces "F<::>" with "F</>" in the filename for you,
+If EXPR is a bareword, L<C<require>|/require VERSION> assumes a F<.pm>
+extension and replaces C<::> with C</> in the filename for you,
to make it easy to load standard modules. This form of loading of
modules does not risk altering your namespace.
require Foo::Bar; # a splendid bareword
-The require function will actually look for the "F<Foo/Bar.pm>" file in the
-directories specified in the C<@INC> array.
+The require function will actually look for the F<Foo/Bar.pm> file in the
+directories specified in the L<C<@INC>|perlvar/@INC> array.
But if you try this:
- $class = 'Foo::Bar';
+ my $class = 'Foo::Bar';
require $class; # $class is not a bareword
#or
require "Foo::Bar"; # not a bareword because of the ""
-The require function will look for the "F<Foo::Bar>" file in the @INC array and
-will complain about not finding "F<Foo::Bar>" there. In this case you can do:
+The require function will look for the F<Foo::Bar> file in the
+L<C<@INC>|perlvar/@INC> array and
+will complain about not finding F<Foo::Bar> there. In this case you can do:
eval "require $class";
-Now that you understand how C<require> looks for files with a
-bareword argument, there is a little extra functionality going on behind
-the scenes. Before C<require> looks for a "F<.pm>" extension, it will
-first look for a similar filename with a "F<.pmc>" extension. If this file
-is found, it will be loaded in place of any file ending in a "F<.pm>"
-extension.
+Now that you understand how L<C<require>|/require VERSION> looks for
+files with a bareword argument, there is a little extra functionality
+going on behind the scenes. Before L<C<require>|/require VERSION> looks
+for a F<.pm> extension, it will first look for a similar filename with a
+F<.pmc> extension. If this file is found, it will be loaded in place of
+any file ending in a F<.pm> extension.
You can also insert hooks into the import facility by putting Perl code
-directly into the @INC array. There are three forms of hooks: subroutine
-references, array references, and blessed objects.
+directly into the L<C<@INC>|perlvar/@INC> array. There are three forms
+of hooks: subroutine references, array references, and blessed objects.
Subroutine references are the simplest case. When the inclusion system
-walks through @INC and encounters a subroutine, this subroutine gets
-called with two parameters, the first a reference to itself, and the
-second the name of the file to be included (e.g., "F<Foo/Bar.pm>"). The
-subroutine should return either nothing or else a list of up to four
-values in the following order:
+walks through L<C<@INC>|perlvar/@INC> and encounters a subroutine, this
+subroutine gets called with two parameters, the first a reference to
+itself, and the second the name of the file to be included (e.g.,
+F<Foo/Bar.pm>). The subroutine should return either nothing or else a
+list of up to four values in the following order:
=over
=item 2
-A filehandle, from which the file will be read.
+A filehandle, from which the file will be read.
=item 3
A reference to a subroutine. If there is no filehandle (previous item),
then this subroutine is expected to generate one line of source code per
-call, writing the line into C<$_> and returning 1, then finally at end of
-file returning 0. If there is a filehandle, then the subroutine will be
-called to act as a simple source filter, with the line as read in C<$_>.
+call, writing the line into L<C<$_>|perlvar/$_> and returning 1, then
+finally at end of file returning 0. If there is a filehandle, then the
+subroutine will be called to act as a simple source filter, with the
+line as read in L<C<$_>|perlvar/$_>.
Again, return 1 for each valid line, and 0 after all lines have been
returned.
=back
-If an empty list, C<undef>, or nothing that matches the first 3 values above
-is returned, then C<require> looks at the remaining elements of @INC.
+If an empty list, L<C<undef>|/undef EXPR>, or nothing that matches the
+first 3 values above is returned, then L<C<require>|/require VERSION>
+looks at the remaining elements of L<C<@INC>|perlvar/@INC>.
Note that this filehandle must be a real filehandle (strictly a typeglob
-or reference to a typeglob, whether blessed or unblessed); tied filehandles
+or reference to a typeglob, whether blessed or unblessed); tied filehandles
will be ignored and processing will stop there.
If the hook is an array reference, its first element must be a subroutine
sub my_sub {
my ($arrayref, $filename) = @_;
# Retrieve $x, $y, ...
- my @parameters = @$arrayref[1..$#$arrayref];
+ my (undef, @parameters) = @$arrayref;
...
}
-If the hook is an object, it must provide an INC method that will be
+If the hook is an object, it must provide an C<INC> method that will be
called as above, the first parameter being the object itself. (Note that
you must fully qualify the sub's name, as unqualified C<INC> is always forced
into package C<main>.) Here is a typical code layout:
# In the main program
push @INC, Foo->new(...);
-These hooks are also permitted to set the %INC entry
+These hooks are also permitted to set the L<C<%INC>|perlvar/%INC> entry
corresponding to the files they have loaded. See L<perlvar/%INC>.
-For a yet-more-powerful import facility, see L</use> and L<perlmod>.
+For a yet-more-powerful import facility, see
+L<C<use>|/use Module VERSION LIST> and L<perlmod>.
=item reset EXPR
X<reset>
=for Pod::Functions clear all variables of a given name
-Generally used in a C<continue> block at the end of a loop to clear
-variables and reset C<??> searches so that they work again. The
+Generally used in a L<C<continue>|/continue BLOCK> block at the end of a
+loop to clear variables and reset C<m?pattern?> searches so that they
+work again. The
expression is interpreted as a list of single characters (hyphens
allowed for ranges). All variables and arrays beginning with one of
those letters are reset to their pristine state. If the expression is
-omitted, one-match searches (C<?pattern?>) are reset to match again.
+omitted, one-match searches (C<m?pattern?>) are reset to match again.
Only resets variables or searches in the current package. Always returns
1. Examples:
reset 'X'; # reset all X variables
reset 'a-z'; # reset lower case variables
- reset; # just reset ?one-time? searches
+ reset; # just reset m?one-time? searches
Resetting C<"A-Z"> is not recommended because you'll wipe out your
-C<@ARGV> and C<@INC> arrays and your C<%ENV> hash. Resets only package
-variables; lexical variables are unaffected, but they clean themselves
-up on scope exit anyway, so you'll probably want to use them instead.
-See L</my>.
+L<C<@ARGV>|perlvar/@ARGV> and L<C<@INC>|perlvar/@INC> arrays and your
+L<C<%ENV>|perlvar/%ENV> hash.
+Resets only package variables; lexical variables are unaffected, but
+they clean themselves up on scope exit anyway, so you'll probably want
+to use them instead. See L<C<my>|/my VARLIST>.
=item return EXPR
X<return>
=for Pod::Functions get out of a function early
-Returns from a subroutine, C<eval>, C<do FILE>, sort block or regex eval
-block (but not a grep or map block) with the value
+Returns from a subroutine, L<C<eval>|/eval EXPR>,
+L<C<do FILE>|/do EXPR>, L<C<sort>|/sort SUBNAME LIST> block or regex
+eval block (but not a L<C<grep>|/grep BLOCK LIST> or
+L<C<map>|/map BLOCK LIST> block) with the value
given in EXPR. Evaluation of EXPR may be in list, scalar, or void
context, depending on how the return value will be used, and the context
-may vary from one execution to the next (see L</wantarray>). If no EXPR
+may vary from one execution to the next (see
+L<C<wantarray>|/wantarray>). If no EXPR
is given, returns an empty list in list context, the undefined value in
scalar context, and (of course) nothing at all in void context.
-(In the absence of an explicit C<return>, a subroutine, eval,
-or do FILE automatically returns the value of the last expression
+(In the absence of an explicit L<C<return>|/return EXPR>, a subroutine,
+L<C<eval>|/eval EXPR>,
+or L<C<do FILE>|/do EXPR> automatically returns the value of the last expression
evaluated.)
Unlike most named operators, this is also exempt from the
looks-like-a-function rule, so C<return ("foo")."bar"> will
-cause "bar" to be part of the argument to C<return>.
+cause C<"bar"> to be part of the argument to L<C<return>|/return EXPR>.
=item reverse LIST
X<reverse> X<rev> X<invert>
print scalar reverse "dlrow ,", "olleH"; # Hello, world
-Used without arguments in scalar context, reverse() reverses C<$_>.
+Used without arguments in scalar context, L<C<reverse>|/reverse LIST>
+reverses L<C<$_>|perlvar/$_>.
$_ = "dlrow ,olleH";
print reverse; # No output, list context
unwind one hash and build a whole new one, which may take some time
on a large hash, such as from a DBM file.
- %by_name = reverse %by_address; # Invert the hash
+ my %by_name = reverse %by_address; # Invert the hash
=item rewinddir DIRHANDLE
X<rewinddir>
=for Pod::Functions reset directory handle
Sets the current position to the beginning of the directory for the
-C<readdir> routine on DIRHANDLE.
+L<C<readdir>|/readdir DIRHANDLE> routine on DIRHANDLE.
Portability issues: L<perlport/rewinddir>.
=for Pod::Functions right-to-left substring search
-Works just like index() except that it returns the position of the I<last>
+Works just like L<C<index>|/index STR,SUBSTR,POSITION> except that it
+returns the position of the I<last>
occurrence of SUBSTR in STR. If POSITION is specified, returns the
last occurrence beginning at or before that position.
Deletes the directory specified by FILENAME if that directory is
empty. If it succeeds it returns true; otherwise it returns false and
-sets C<$!> (errno). If FILENAME is omitted, uses C<$_>.
+sets L<C<$!>|perlvar/$!> (errno). If FILENAME is omitted, uses
+L<C<$_>|perlvar/$_>.
To remove a directory tree recursively (C<rm -rf> on Unix) look at
-the C<rmtree> function of the L<File::Path> module.
+the L<C<rmtree>|File::Path/rmtree( $dir )> function of the L<File::Path>
+module.
=item s///
=for Pod::Functions +say output a list to a filehandle, appending a newline
-Just like C<print>, but implicitly appends a newline. C<say LIST> is
-simply an abbreviation for C<{ local $\ = "\n"; print LIST }>. To use
-FILEHANDLE without a LIST to print the contents of C<$_> to it, you must
-use a real filehandle like C<FH>, not an indirect one like C<$fh>.
+Just like L<C<print>|/print FILEHANDLE LIST>, but implicitly appends a
+newline. C<say LIST> is simply an abbreviation for
+C<{ local $\ = "\n"; print LIST }>. To use FILEHANDLE without a LIST to
+print the contents of L<C<$_>|perlvar/$_> to it, you must use a bareword
+filehandle like C<FH>, not an indirect one like C<$fh>.
-This keyword is available only when the C<"say"> feature
-is enabled, or when prefixed with C<CORE::>; see
-L<feature>. Alternately, add a C<use v5.10> or later to the current
-scope.
+L<C<say>|/say FILEHANDLE LIST> is available only if the
+L<C<"say"> feature|feature/The 'say' feature> is enabled or if it is
+prefixed with C<CORE::>. The
+L<C<"say"> feature|feature/The 'say' feature> is enabled automatically
+with a C<use v5.10> (or higher) declaration in the current scope.
=item scalar EXPR
X<scalar> X<context>
Forces EXPR to be interpreted in scalar context and returns the value
of EXPR.
- @counts = ( scalar @a, scalar @b, scalar @c );
+ my @counts = ( scalar @a, scalar @b, scalar @c );
There is no equivalent operator to force an expression to
be interpolated in list context because in practice, this is never
the construction C<@{[ (some expression) ]}>, but usually a simple
C<(some expression)> suffices.
-Because C<scalar> is a unary operator, if you accidentally use a
+Because L<C<scalar>|/scalar EXPR> is a unary operator, if you
+accidentally use a
parenthesized list for the EXPR, this behaves as a scalar comma expression,
evaluating all but the last element in void context and returning the final
element evaluated in scalar context. This is seldom what you want.
The following single statement:
- print uc(scalar(&foo,$bar)),$baz;
+ print uc(scalar(foo(), $bar)), $baz;
is the moral equivalent of these two:
- &foo;
- print(uc($bar),$baz);
+ foo();
+ print(uc($bar), $baz);
See L<perlop> for more details on unary operators and the comma operator.
=for Pod::Functions reposition file pointer for random-access I/O
-Sets FILEHANDLE's position, just like the C<fseek> call of C<stdio>.
+Sets FILEHANDLE's position, just like the L<fseek(3)> call of C C<stdio>.
FILEHANDLE may be an expression whose value gives the name of the
filehandle. The values for WHENCE are C<0> to set the new position
I<in bytes> to POSITION; C<1> to set it to the current position plus
Note the I<in bytes>: even if the filehandle has been set to
operate on characters (for example by using the C<:encoding(utf8)> open
-layer), tell() will return byte offsets, not character offsets
-(because implementing that would render seek() and tell() rather slow).
-
-If you want to position the file for C<sysread> or C<syswrite>, don't use
-C<seek>, because buffering makes its effect on the file's read-write position
-unpredictable and non-portable. Use C<sysseek> instead.
+layer), L<C<tell>|/tell FILEHANDLE> will return byte offsets, not
+character offsets (because implementing that would render
+L<C<seek>|/seek FILEHANDLE,POSITION,WHENCE> and
+L<C<tell>|/tell FILEHANDLE> rather slow).
+
+If you want to position the file for
+L<C<sysread>|/sysread FILEHANDLE,SCALAR,LENGTH,OFFSET> or
+L<C<syswrite>|/syswrite FILEHANDLE,SCALAR,LENGTH,OFFSET>, don't use
+L<C<seek>|/seek FILEHANDLE,POSITION,WHENCE>, because buffering makes its
+effect on the file's read-write position unpredictable and non-portable.
+Use L<C<sysseek>|/sysseek FILEHANDLE,POSITION,WHENCE> instead.
Due to the rules and rigors of ANSI C, on some systems you have to do a
seek whenever you switch between reading and writing. Amongst other
-things, this may have the effect of calling stdio's clearerr(3).
+things, this may have the effect of calling stdio's L<clearerr(3)>.
A WHENCE of C<1> (C<SEEK_CUR>) is useful for not moving the file position:
- seek(TEST,0,1);
+ seek($fh, 0, 1);
This is also useful for applications emulating C<tail -f>. Once you hit
EOF on your read and then sleep for a while, you (probably) have to stick in a
-dummy seek() to reset things. The C<seek> doesn't change the position,
+dummy L<C<seek>|/seek FILEHANDLE,POSITION,WHENCE> to reset things. The
+L<C<seek>|/seek FILEHANDLE,POSITION,WHENCE> doesn't change the position,
but it I<does> clear the end-of-file condition on the handle, so that the
-next C<< <FILE> >> makes Perl try again to read something. (We hope.)
+next C<readline FILE> makes Perl try again to read something. (We hope.)
If that doesn't work (some I/O implementations are particularly
cantankerous), you might need something like this:
for (;;) {
- for ($curpos = tell(FILE); $_ = <FILE>;
- $curpos = tell(FILE)) {
+ for ($curpos = tell($fh); $_ = readline($fh);
+ $curpos = tell($fh)) {
# search for some stuff and put it into files
}
sleep($for_a_while);
- seek(FILE, $curpos, 0);
+ seek($fh, $curpos, 0);
}
=item seekdir DIRHANDLE,POS
=for Pod::Functions reposition directory pointer
-Sets the current position for the C<readdir> routine on DIRHANDLE. POS
-must be a value returned by C<telldir>. C<seekdir> also has the same caveats
-about possible directory compaction as the corresponding system library
-routine.
+Sets the current position for the L<C<readdir>|/readdir DIRHANDLE>
+routine on DIRHANDLE. POS must be a value returned by
+L<C<telldir>|/telldir DIRHANDLE>. L<C<seekdir>|/seekdir DIRHANDLE,POS>
+also has the same caveats about possible directory compaction as the
+corresponding system library routine.
=item select FILEHANDLE
X<select> X<filehandle, default>
Returns the currently selected filehandle. If FILEHANDLE is supplied,
sets the new current default filehandle for output. This has two
-effects: first, a C<write> or a C<print> without a filehandle
+effects: first, a L<C<write>|/write FILEHANDLE> or a L<C<print>|/print
+FILEHANDLE LIST> without a filehandle
default to this FILEHANDLE. Second, references to variables related to
-output will refer to this output channel.
+output will refer to this output channel.
For example, to set the top-of-form format for more than one
output channel, you might do the following:
FILEHANDLE may be an expression whose value gives the name of the
actual filehandle. Thus:
- $oldfh = select(STDERR); $| = 1; select($oldfh);
+ my $oldfh = select(STDERR); $| = 1; select($oldfh);
Some programmers may prefer to think of filehandles as objects with
methods, preferring to write the last example as:
- use IO::Handle;
STDERR->autoflush(1);
+(Prior to Perl version 5.14, you have to C<use IO::Handle;> explicitly
+first.)
+
Portability issues: L<perlport/select>.
=item select RBITS,WBITS,EBITS,TIMEOUT
X<select>
-This calls the select(2) syscall with the bit masks specified, which
-can be constructed using C<fileno> and C<vec>, along these lines:
+This calls the L<select(2)> syscall with the bit masks specified, which
+can be constructed using L<C<fileno>|/fileno FILEHANDLE> and
+L<C<vec>|/vec EXPR,OFFSET,BITS>, along these lines:
- $rin = $win = $ein = '';
+ my $rin = my $win = my $ein = '';
vec($rin, fileno(STDIN), 1) = 1;
vec($win, fileno(STDOUT), 1) = 1;
$ein = $rin | $win;
}
return $bits;
}
- $rin = fhbits(*STDIN, *TTY, *MYSOCK);
+ my $rin = fhbits(\*STDIN, $tty, $mysock);
The usual idiom is:
- ($nfound,$timeleft) =
- select($rout=$rin, $wout=$win, $eout=$ein, $timeout);
+ my ($nfound, $timeleft) =
+ select(my $rout = $rin, my $wout = $win, my $eout = $ein,
+ $timeout);
or to block until something becomes ready just do this
- $nfound = select($rout=$rin, $wout=$win, $eout=$ein, undef);
+ my $nfound =
+ select(my $rout = $rin, my $wout = $win, my $eout = $ein, undef);
-Most systems do not bother to return anything useful in $timeleft, so
-calling select() in scalar context just returns $nfound.
+Most systems do not bother to return anything useful in C<$timeleft>, so
+calling L<C<select>|/select RBITS,WBITS,EBITS,TIMEOUT> in scalar context
+just returns C<$nfound>.
-Any of the bit masks can also be undef. The timeout, if specified, is
+Any of the bit masks can also be L<C<undef>|/undef EXPR>. The timeout,
+if specified, is
in seconds, which may be fractional. Note: not all implementations are
-capable of returning the $timeleft. If not, they always return
-$timeleft equal to the supplied $timeout.
+capable of returning the C<$timeleft>. If not, they always return
+C<$timeleft> equal to the supplied C<$timeout>.
You can effect a sleep of 250 milliseconds this way:
select(undef, undef, undef, 0.25);
-Note that whether C<select> gets restarted after signals (say, SIGALRM)
-is implementation-dependent. See also L<perlport> for notes on the
-portability of C<select>.
+Note that whether L<C<select>|/select RBITS,WBITS,EBITS,TIMEOUT> gets
+restarted after signals (say, SIGALRM) is implementation-dependent. See
+also L<perlport> for notes on the portability of
+L<C<select>|/select RBITS,WBITS,EBITS,TIMEOUT>.
-On error, C<select> behaves just like select(2): it returns
--1 and sets C<$!>.
+On error, L<C<select>|/select RBITS,WBITS,EBITS,TIMEOUT> behaves just
+like L<select(2)>: it returns C<-1> and sets L<C<$!>|perlvar/$!>.
-On some Unixes, select(2) may report a socket file descriptor as "ready for
-reading" even when no data is available, and thus any subsequent C<read>
-would block. This can be avoided if you always use O_NONBLOCK on the
-socket. See select(2) and fcntl(2) for further details.
+On some Unixes, L<select(2)> may report a socket file descriptor as
+"ready for reading" even when no data is available, and thus any
+subsequent L<C<read>|/read FILEHANDLE,SCALAR,LENGTH,OFFSET> would block.
+This can be avoided if you always use C<O_NONBLOCK> on the socket. See
+L<select(2)> and L<fcntl(2)> for further details.
-The standard C<IO::Select> module provides a user-friendlier interface
-to C<select>, mostly because it does all the bit-mask work for you.
+The standard L<C<IO::Select>|IO::Select> module provides a
+user-friendlier interface to
+L<C<select>|/select RBITS,WBITS,EBITS,TIMEOUT>, mostly because it does
+all the bit-mask work for you.
-B<WARNING>: One should not attempt to mix buffered I/O (like C<read>
-or <FH>) with C<select>, except as permitted by POSIX, and even
-then only on POSIX systems. You have to use C<sysread> instead.
+B<WARNING>: One should not attempt to mix buffered I/O (like
+L<C<read>|/read FILEHANDLE,SCALAR,LENGTH,OFFSET> or
+L<C<readline>|/readline EXPR>) with
+L<C<select>|/select RBITS,WBITS,EBITS,TIMEOUT>, except as permitted by
+POSIX, and even then only on POSIX systems. You have to use
+L<C<sysread>|/sysread FILEHANDLE,SCALAR,LENGTH,OFFSET> instead.
Portability issues: L<perlport/select>.
=for Pod::Functions SysV semaphore control operations
-Calls the System V IPC function semctl(2). You'll probably have to say
+Calls the System V IPC function L<semctl(2)>. You'll probably have to say
use IPC::SysV;
first to get the correct constant definitions. If CMD is IPC_STAT or
GETALL, then ARG must be a variable that will hold the returned
-semid_ds structure or semaphore value array. Returns like C<ioctl>:
+semid_ds structure or semaphore value array. Returns like
+L<C<ioctl>|/ioctl FILEHANDLE,FUNCTION,SCALAR>:
the undefined value for error, "C<0 but true>" for zero, or the actual
return value otherwise. The ARG must consist of a vector of native
short integers, which may be created with C<pack("s!",(0)x$nsem)>.
-See also L<perlipc/"SysV IPC">, C<IPC::SysV>, C<IPC::Semaphore>
-documentation.
+See also L<perlipc/"SysV IPC"> and the documentation for
+L<C<IPC::SysV>|IPC::SysV> and L<C<IPC::Semaphore>|IPC::Semaphore>.
Portability issues: L<perlport/semctl>.
=for Pod::Functions get set of SysV semaphores
-Calls the System V IPC function semget(2). Returns the semaphore id, or
+Calls the System V IPC function L<semget(2)>. Returns the semaphore id, or
the undefined value on error. See also
-L<perlipc/"SysV IPC">, C<IPC::SysV>, C<IPC::SysV::Semaphore>
-documentation.
+L<perlipc/"SysV IPC"> and the documentation for
+L<C<IPC::SysV>|IPC::SysV> and L<C<IPC::Semaphore>|IPC::Semaphore>.
Portability issues: L<perlport/semget>.
=for Pod::Functions SysV semaphore operations
-Calls the System V IPC function semop(2) for semaphore operations
+Calls the System V IPC function L<semop(2)> for semaphore operations
such as signalling and waiting. OPSTRING must be a packed array of
semop structures. Each semop structure can be generated with
-C<pack("s!3", $semnum, $semop, $semflag)>. The length of OPSTRING
+C<pack("s!3", $semnum, $semop, $semflag)>. The length of OPSTRING
implies the number of semaphore operations. Returns true if
successful, false on error. As an example, the
following code waits on semaphore $semnum of semaphore id $semid:
- $semop = pack("s!3", $semnum, -1, 0);
+ my $semop = pack("s!3", $semnum, -1, 0);
die "Semaphore trouble: $!\n" unless semop($semid, $semop);
To signal the semaphore, replace C<-1> with C<1>. See also
-L<perlipc/"SysV IPC">, C<IPC::SysV>, and C<IPC::SysV::Semaphore>
-documentation.
+L<perlipc/"SysV IPC"> and the documentation for
+L<C<IPC::SysV>|IPC::SysV> and L<C<IPC::Semaphore>|IPC::Semaphore>.
Portability issues: L<perlport/semop>.
Sends a message on a socket. Attempts to send the scalar MSG to the SOCKET
filehandle. Takes the same flags as the system call of the same name. On
unconnected sockets, you must specify a destination to I<send to>, in which
-case it does a sendto(2) syscall. Returns the number of characters sent,
-or the undefined value on error. The sendmsg(2) syscall is currently
+case it does a L<sendto(2)> syscall. Returns the number of characters sent,
+or the undefined value on error. The L<sendmsg(2)> syscall is currently
unimplemented. See L<perlipc/"UDP: Message Passing"> for examples.
Note the I<characters>: depending on the status of the socket, either
(8-bit) bytes or characters are sent. By default all sockets operate
on bytes, but for example if the socket has been changed using
-binmode() to operate with the C<:encoding(utf8)> I/O layer (see
-L</open>, or the C<open> pragma, L<open>), the I/O will operate on UTF-8
+L<C<binmode>|/binmode FILEHANDLE, LAYER> to operate with the
+C<:encoding(utf8)> I/O layer (see L<C<open>|/open FILEHANDLE,EXPR>, or
+the L<open> pragma), the I/O will operate on UTF-8
encoded Unicode characters, not bytes. Similarly for the C<:encoding>
-pragma: in that case pretty much any characters can be sent.
+layer: in that case pretty much any characters can be sent.
=item setpgrp PID,PGRP
X<setpgrp> X<group>
Sets the current process group for the specified PID, C<0> for the current
process. Raises an exception when used on a machine that doesn't
-implement POSIX setpgid(2) or BSD setpgrp(2). If the arguments are omitted,
-it defaults to C<0,0>. Note that the BSD 4.2 version of C<setpgrp> does not
-accept any arguments, so only C<setpgrp(0,0)> is portable. See also
-C<POSIX::setsid()>.
+implement POSIX L<setpgid(2)> or BSD L<setpgrp(2)>. If the arguments
+are omitted, it defaults to C<0,0>. Note that the BSD 4.2 version of
+L<C<setpgrp>|/setpgrp PID,PGRP> does not accept any arguments, so only
+C<setpgrp(0,0)> is portable. See also
+L<C<POSIX::setsid()>|POSIX/C<setsid>>.
Portability issues: L<perlport/setpgrp>.
=for Pod::Functions set a process's nice value
Sets the current priority for a process, a process group, or a user.
-(See setpriority(2).) Raises an exception when used on a machine
-that doesn't implement setpriority(2).
+(See L<setpriority(2)>.) Raises an exception when used on a machine
+that doesn't implement L<setpriority(2)>.
Portability issues: L<perlport/setpriority>.
=for Pod::Functions set some socket options
-Sets the socket option requested. Returns C<undef> on error.
-Use integer constants provided by the C<Socket> module for
+Sets the socket option requested. Returns L<C<undef>|/undef EXPR> on
+error. Use integer constants provided by the L<C<Socket>|Socket> module
+for
LEVEL and OPNAME. Values for LEVEL can also be obtained from
getprotobyname. OPTVAL might either be a packed string or an integer.
An integer OPTVAL is shorthand for pack("i", OPTVAL).
Shifts the first value of the array off and returns it, shortening the
array by 1 and moving everything down. If there are no elements in the
array, returns the undefined value. If ARRAY is omitted, shifts the
-C<@_> array within the lexical scope of subroutines and formats, and the
-C<@ARGV> array outside a subroutine and also within the lexical scopes
+L<C<@_>|perlvar/@_> array within the lexical scope of subroutines and
+formats, and the L<C<@ARGV>|perlvar/@ARGV> array outside a subroutine
+and also within the lexical scopes
established by the C<eval STRING>, C<BEGIN {}>, C<INIT {}>, C<CHECK {}>,
C<UNITCHECK {}>, and C<END {}> constructs.
-Starting with Perl 5.14, an experimental feature allowed C<shift> to take a
+Starting with Perl 5.14, an experimental feature allowed
+L<C<shift>|/shift ARRAY> to take a
scalar expression. This experiment has been deemed unsuccessful, and was
removed as of Perl 5.24.
-See also C<unshift>, C<push>, and C<pop>. C<shift> and C<unshift> do the
-same thing to the left end of an array that C<pop> and C<push> do to the
-right end.
+See also L<C<unshift>|/unshift ARRAY,LIST>, L<C<push>|/push ARRAY,LIST>,
+and L<C<pop>|/pop ARRAY>. L<C<shift>|/shift ARRAY> and
+L<C<unshift>|/unshift ARRAY,LIST> do the same thing to the left end of
+an array that L<C<pop>|/pop ARRAY> and L<C<push>|/push ARRAY,LIST> do to
+the right end.
=item shmctl ID,CMD,ARG
X<shmctl>
first to get the correct constant definitions. If CMD is C<IPC_STAT>,
then ARG must be a variable that will hold the returned C<shmid_ds>
-structure. Returns like ioctl: C<undef> for error; "C<0> but
-true" for zero; and the actual return value otherwise.
-See also L<perlipc/"SysV IPC"> and C<IPC::SysV> documentation.
+structure. Returns like ioctl: L<C<undef>|/undef EXPR> for error; "C<0>
+but true" for zero; and the actual return value otherwise.
+See also L<perlipc/"SysV IPC"> and the documentation for
+L<C<IPC::SysV>|IPC::SysV>.
Portability issues: L<perlport/shmctl>.
=for Pod::Functions get SysV shared memory segment identifier
Calls the System V IPC function shmget. Returns the shared memory
-segment id, or C<undef> on error.
-See also L<perlipc/"SysV IPC"> and C<IPC::SysV> documentation.
+segment id, or L<C<undef>|/undef EXPR> on error.
+See also L<perlipc/"SysV IPC"> and the documentation for
+L<C<IPC::SysV>|IPC::SysV>.
Portability issues: L<perlport/shmget>.
hold the data read. When writing, if STRING is too long, only SIZE
bytes are used; if STRING is too short, nulls are written to fill out
SIZE bytes. Return true if successful, false on error.
-shmread() taints the variable. See also L<perlipc/"SysV IPC">,
-C<IPC::SysV>, and the C<IPC::Shareable> module from CPAN.
+L<C<shmread>|/shmread ID,VAR,POS,SIZE> taints the variable. See also
+L<perlipc/"SysV IPC"> and the documentation for
+L<C<IPC::SysV>|IPC::SysV> and the L<C<IPC::Shareable>|IPC::Shareable>
+module from CPAN.
Portability issues: L<perlport/shmread> and L<perlport/shmwrite>.
Shuts down a socket connection in the manner indicated by HOW, which
has the same interpretation as in the syscall of the same name.
- shutdown(SOCKET, 0); # I/we have stopped reading data
- shutdown(SOCKET, 1); # I/we have stopped writing data
- shutdown(SOCKET, 2); # I/we have stopped using this socket
+ shutdown($socket, 0); # I/we have stopped reading data
+ shutdown($socket, 1); # I/we have stopped writing data
+ shutdown($socket, 2); # I/we have stopped using this socket
This is useful with sockets when you want to tell the other
side you're done writing but not done reading, or vice versa.
disables the file descriptor in any forked copies in other
processes.
-Returns C<1> for success; on error, returns C<undef> if
+Returns C<1> for success; on error, returns L<C<undef>|/undef EXPR> if
the first argument is not a valid filehandle, or returns C<0> and sets
-C<$!> for any other failure.
+L<C<$!>|perlvar/$!> for any other failure.
=item sin EXPR
X<sin> X<sine> X<asin> X<arcsine>
=for Pod::Functions return the sine of a number
Returns the sine of EXPR (expressed in radians). If EXPR is omitted,
-returns sine of C<$_>.
+returns sine of L<C<$_>|perlvar/$_>.
For the inverse sine operation, you may use the C<Math::Trig::asin>
function, or use this relation:
=for Pod::Functions block for some number of seconds
-Causes the script to sleep for (integer) EXPR seconds, or forever if no
-argument is given. Returns the integer number of seconds actually slept.
+Causes the script to sleep for (integer) EXPR seconds, or forever if no
+argument is given. Returns the integer number of seconds actually slept.
May be interrupted if the process receives a signal such as C<SIGALRM>.
eval {
- local $SIG{ALARM} = sub { die "Alarm!\n" };
+ local $SIG{ALRM} = sub { die "Alarm!\n" };
sleep;
};
die $@ unless $@ eq "Alarm!\n";
-You probably cannot mix C<alarm> and C<sleep> calls, because C<sleep>
-is often implemented using C<alarm>.
+You probably cannot mix L<C<alarm>|/alarm SECONDS> and
+L<C<sleep>|/sleep EXPR> calls, because L<C<sleep>|/sleep EXPR> is often
+implemented using L<C<alarm>|/alarm SECONDS>.
On some older systems, it may sleep up to a full second less than what
you requested, depending on how it counts seconds. Most modern systems
however, because your process might not be scheduled right away in a
busy multitasking system.
-For delays of finer granularity than one second, the Time::HiRes module
-(from CPAN, and starting from Perl 5.8 part of the standard
-distribution) provides usleep(). You may also use Perl's four-argument
-version of select() leaving the first three arguments undefined, or you
-might be able to use the C<syscall> interface to access setitimer(2) if
-your system supports it. See L<perlfaq8> for details.
+For delays of finer granularity than one second, the L<Time::HiRes>
+module (from CPAN, and starting from Perl 5.8 part of the standard
+distribution) provides L<C<usleep>|Time::HiRes/usleep ( $useconds )>.
+You may also use Perl's four-argument
+version of L<C<select>|/select RBITS,WBITS,EBITS,TIMEOUT> leaving the
+first three arguments undefined, or you might be able to use the
+L<C<syscall>|/syscall NUMBER, LIST> interface to access L<setitimer(2)>
+if your system supports it. See L<perlfaq8> for details.
-See also the POSIX module's C<pause> function.
+See also the L<POSIX> module's L<C<pause>|POSIX/C<pause>> function.
=item socket SOCKET,DOMAIN,TYPE,PROTOCOL
X<socket>
On systems that support a close-on-exec flag on files, the flag will
be set for the newly opened file descriptor, as determined by the
-value of $^F. See L<perlvar/$^F>.
+value of L<C<$^F>|perlvar/$^F>. See L<perlvar/$^F>.
=item socketpair SOCKET1,SOCKET2,DOMAIN,TYPE,PROTOCOL
X<socketpair>
On systems that support a close-on-exec flag on files, the flag will
be set for the newly opened file descriptors, as determined by the value
-of $^F. See L<perlvar/$^F>.
+of L<C<$^F>|perlvar/$^F>. See L<perlvar/$^F>.
-Some systems defined C<pipe> in terms of C<socketpair>, in which a call
-to C<pipe(Rdr, Wtr)> is essentially:
+Some systems define L<C<pipe>|/pipe READHANDLE,WRITEHANDLE> in terms of
+L<C<socketpair>|/socketpair SOCKET1,SOCKET2,DOMAIN,TYPE,PROTOCOL>, in
+which a call to C<pipe($rdr, $wtr)> is essentially:
use Socket;
- socketpair(Rdr, Wtr, AF_UNIX, SOCK_STREAM, PF_UNSPEC);
- shutdown(Rdr, 1); # no more writing for reader
- shutdown(Wtr, 0); # no more reading for writer
+ socketpair(my $rdr, my $wtr, AF_UNIX, SOCK_STREAM, PF_UNSPEC);
+ shutdown($rdr, 1); # no more writing for reader
+ shutdown($wtr, 0); # no more reading for writer
See L<perlipc> for an example of socketpair use. Perl 5.8 and later will
emulate socketpair using IP sockets to localhost if your system implements
=for Pod::Functions sort a list of values
In list context, this sorts the LIST and returns the sorted list value.
-In scalar context, the behaviour of C<sort()> is undefined.
+In scalar context, the behaviour of L<C<sort>|/sort SUBNAME LIST> is
+undefined.
-If SUBNAME or BLOCK is omitted, C<sort>s in standard string comparison
+If SUBNAME or BLOCK is omitted, L<C<sort>|/sort SUBNAME LIST>s in
+standard string comparison
order. If SUBNAME is specified, it gives the name of a subroutine
that returns an integer less than, equal to, or greater than C<0>,
-depending on how the elements of the list are to be ordered. (The
+depending on how the elements of the list are to be ordered. (The
C<< <=> >> and C<cmp> operators are extremely useful in such routines.)
SUBNAME may be a scalar variable name (unsubscripted), in which case
the value provides the name of (or a reference to) the actual
an anonymous, in-line sort subroutine.
If the subroutine's prototype is C<($$)>, the elements to be compared are
-passed by reference in C<@_>, as for a normal subroutine. This is slower
-than unprototyped subroutines, where the elements to be compared are passed
-into the subroutine as the package global variables $a and $b (see example
-below). Note that in the latter case, it is usually highly counter-productive
-to declare $a and $b as lexicals.
+passed by reference in L<C<@_>|perlvar/@_>, as for a normal subroutine.
+This is slower than unprototyped subroutines, where the elements to be
+compared are passed into the subroutine as the package global variables
+C<$a> and C<$b> (see example below). Note that in the latter case, it
+is usually highly counter-productive to declare C<$a> and C<$b> as
+lexicals.
-If the subroutine is an XSUB, the elements to be compared are pushed on to
-the stack, the way arguments are usually passed to XSUBs. $a and $b are
-not set.
+If the subroutine is an XSUB, the elements to be compared are pushed on
+to the stack, the way arguments are usually passed to XSUBs. C<$a> and
+C<$b> are not set.
The values to be compared are always passed by reference and should not
be modified.
You also cannot exit out of the sort block or subroutine using any of the
-loop control operators described in L<perlsyn> or with C<goto>.
+loop control operators described in L<perlsyn> or with
+L<C<goto>|/goto LABEL>.
-When C<use locale> (but not C<use locale 'not_characters'>) is in
-effect, C<sort LIST> sorts LIST according to the
+When L<C<use locale>|locale> (but not C<use locale ':not_characters'>)
+is in effect, C<sort LIST> sorts LIST according to the
current collation locale. See L<perllocale>.
-sort() returns aliases into the original list, much as a for loop's index
-variable aliases the list elements. That is, modifying an element of a
-list returned by sort() (for example, in a C<foreach>, C<map> or C<grep>)
+L<C<sort>|/sort SUBNAME LIST> returns aliases into the original list,
+much as a for loop's index variable aliases the list elements. That is,
+modifying an element of a list returned by L<C<sort>|/sort SUBNAME LIST>
+(for example, in a C<foreach>, L<C<map>|/map BLOCK LIST> or
+L<C<grep>|/grep BLOCK LIST>)
actually modifies the element in the original list. This is usually
something to be avoided when writing clear code.
Perl 5.6 and earlier used a quicksort algorithm to implement sort.
-That algorithm was not stable, so I<could> go quadratic. (A I<stable> sort
+That algorithm was not stable and I<could> go quadratic. (A I<stable> sort
preserves the input order of elements that compare equal. Although
quicksort's run time is O(NlogN) when averaged over all arrays of
length N, the time can be O(N**2), I<quadratic> behavior, for some
inputs.) In 5.7, the quicksort implementation was replaced with
a stable mergesort algorithm whose worst-case behavior is O(NlogN).
But benchmarks indicated that for some inputs, on some platforms,
-the original quicksort was faster. 5.8 has a sort pragma for
+the original quicksort was faster. 5.8 has a L<sort> pragma for
limited control of the sort. Its rather blunt control of the
underlying algorithm may not persist into future Perls, but the
ability to characterize the input or output in implementation
-independent ways quite probably will. See L<the sort pragma|sort>.
+independent ways quite probably will.
Examples:
# sort lexically
- @articles = sort @files;
+ my @articles = sort @files;
# same thing, but with explicit sort routine
- @articles = sort {$a cmp $b} @files;
+ my @articles = sort {$a cmp $b} @files;
# now case-insensitively
- @articles = sort {fc($a) cmp fc($b)} @files;
+ my @articles = sort {fc($a) cmp fc($b)} @files;
# same thing in reversed order
- @articles = sort {$b cmp $a} @files;
+ my @articles = sort {$b cmp $a} @files;
# sort numerically ascending
- @articles = sort {$a <=> $b} @files;
+ my @articles = sort {$a <=> $b} @files;
# sort numerically descending
- @articles = sort {$b <=> $a} @files;
+ my @articles = sort {$b <=> $a} @files;
# this sorts the %age hash by value instead of key
# using an in-line function
- @eldest = sort { $age{$b} <=> $age{$a} } keys %age;
+ my @eldest = sort { $age{$b} <=> $age{$a} } keys %age;
# sort using explicit subroutine name
sub byage {
$age{$a} <=> $age{$b}; # presuming numeric
}
- @sortedclass = sort byage @class;
+ my @sortedclass = sort byage @class;
sub backwards { $b cmp $a }
- @harry = qw(dog cat x Cain Abel);
- @george = qw(gone chased yz Punished Axed);
+ my @harry = qw(dog cat x Cain Abel);
+ my @george = qw(gone chased yz Punished Axed);
print sort @harry;
# prints AbelCaincatdogx
print sort backwards @harry;
];
# same thing, but without any temps
- @new = map { $_->[0] }
+ my @new = map { $_->[0] }
sort { $b->[1] <=> $a->[1]
||
$a->[2] cmp $b->[2]
# using a prototype allows you to use any comparison subroutine
# as a sort subroutine (including other package's subroutines)
- package other;
+ package Other;
sub backwards ($$) { $_[1] cmp $_[0]; } # $a and $b are
- # not set here
+ # not set here
package main;
- @new = sort other::backwards @old;
+ my @new = sort Other::backwards @old;
# guarantee stability, regardless of algorithm
use sort 'stable';
- @new = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @old;
+ my @new = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @old;
# force use of mergesort (not portable outside Perl 5.8)
use sort '_mergesort'; # note discouraging _
- @new = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @old;
+ my @new = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @old;
Warning: syntactical care is required when sorting the list returned from
a function. If you want to sort the list returned by the function call
C<find_records(@key)>, you can use:
- @contact = sort { $a cmp $b } find_records @key;
- @contact = sort +find_records(@key);
- @contact = sort &find_records(@key);
- @contact = sort(find_records(@key));
+ my @contact = sort { $a cmp $b } find_records @key;
+ my @contact = sort +find_records(@key);
+ my @contact = sort &find_records(@key);
+ my @contact = sort(find_records(@key));
-If instead you want to sort the array @key with the comparison routine
+If instead you want to sort the array C<@key> with the comparison routine
C<find_records()> then you can use:
- @contact = sort { find_records() } @key;
- @contact = sort find_records(@key);
- @contact = sort(find_records @key);
- @contact = sort(find_records (@key));
+ my @contact = sort { find_records() } @key;
+ my @contact = sort find_records(@key);
+ my @contact = sort(find_records @key);
+ my @contact = sort(find_records (@key));
-If you're using strict, you I<must not> declare $a
-and $b as lexicals. They are package globals. That means
+You I<must not> declare C<$a>
+and C<$b> as lexicals. They are package globals. That means
that if you're in the C<main> package and type
- @articles = sort {$b <=> $a} @files;
+ my @articles = sort {$b <=> $a} @files;
then C<$a> and C<$b> are C<$main::a> and C<$main::b> (or C<$::a> and C<$::b>),
but if you're in the C<FooPack> package, it's the same as typing
- @articles = sort {$FooPack::b <=> $FooPack::a} @files;
+ my @articles = sort {$FooPack::b <=> $FooPack::a} @files;
The comparison function is required to behave. If it returns
inconsistent results (sometimes saying C<$x[1]> is less than C<$x[2]> and
sometimes saying the opposite, for example) the results are not
well-defined.
-Because C<< <=> >> returns C<undef> when either operand is C<NaN>
-(not-a-number), be careful when sorting with a
+Because C<< <=> >> returns L<C<undef>|/undef EXPR> when either operand
+is C<NaN> (not-a-number), be careful when sorting with a
comparison function like C<< $a <=> $b >> any lists that might contain a
C<NaN>. The following example takes advantage that C<NaN != NaN> to
eliminate any C<NaN>s from the input list.
- @result = sort { $a <=> $b } grep { $_ == $_ } @input;
+ my @result = sort { $a <=> $b } grep { $_ == $_ } @input;
=item splice ARRAY,OFFSET,LENGTH,LIST
X<splice>
Removes the elements designated by OFFSET and LENGTH from an array, and
replaces them with the elements of LIST, if any. In list context,
returns the elements removed from the array. In scalar context,
-returns the last element removed, or C<undef> if no elements are
+returns the last element removed, or L<C<undef>|/undef EXPR> if no
+elements are
removed. The array grows or shrinks as necessary.
If OFFSET is negative then it starts that far from the end of the array.
If LENGTH is omitted, removes everything from OFFSET onward.
unshift(@a,$x,$y) splice(@a,0,0,$x,$y)
$a[$i] = $y splice(@a,$i,1,$y)
-C<splice> can be used, for example, to implement n-ary queue processing:
+L<C<splice>|/splice ARRAY,OFFSET,LENGTH,LIST> can be used, for example,
+to implement n-ary queue processing:
sub nary_print {
my $n = shift;
# d -- e -- f
# g -- h
-Starting with Perl 5.14, an experimental feature allowed C<splice> to take a
+Starting with Perl 5.14, an experimental feature allowed
+L<C<splice>|/splice ARRAY,OFFSET,LENGTH,LIST> to take a
scalar expression. This experiment has been deemed unsuccessful, and was
removed as of Perl 5.24.
Splits the string EXPR into a list of strings and returns the
list in list context, or the size of the list in scalar context.
-If only PATTERN is given, EXPR defaults to C<$_>.
+If only PATTERN is given, EXPR defaults to L<C<$_>|perlvar/$_>.
Anything in EXPR that matches PATTERN is taken to be a separator
that separates the EXPR into substrings (called "I<fields>") that
If PATTERN matches the empty string, the EXPR is split at the match
position (between characters). As an example, the following:
- print join(':', split('b', 'abc')), "\n";
+ print join(':', split(/b/, 'abc')), "\n";
-uses the 'b' in 'abc' as a separator to produce the output 'a:c'.
+uses the C<b> in C<'abc'> as a separator to produce the output C<a:c>.
However, this:
- print join(':', split('', 'abc')), "\n";
+ print join(':', split(//, 'abc')), "\n";
uses empty string matches as separators to produce the output
-'a:b:c'; thus, the empty string may be used to split EXPR into a
+C<a:b:c>; thus, the empty string may be used to split EXPR into a
list of its component characters.
-As a special case for C<split>, the empty pattern given in
+As a special case for L<C<split>|/split E<sol>PATTERNE<sol>,EXPR,LIMIT>,
+the empty pattern given in
L<match operator|perlop/"m/PATTERN/msixpodualngc"> syntax (C<//>)
specifically matches the empty string, which is contrary to its usual
interpretation as the last successful match.
L<multiline modifier|perlreref/OPERATORS> (C</^/m>), since it
isn't much use otherwise.
-As another special case, C<split> emulates the default behavior of the
-command line tool B<awk> when the PATTERN is either omitted or a I<literal
-string> composed of a single space character (such as S<C<' '>> or
+As another special case,
+L<C<split>|/split E<sol>PATTERNE<sol>,EXPR,LIMIT> emulates the default
+behavior of the
+command line tool B<awk> when the PATTERN is either omitted or a
+string composed of a single space character (such as S<C<' '>> or
S<C<"\x20">>, but not e.g. S<C</ />>). In this case, any leading
whitespace in EXPR is removed before splitting occurs, and the PATTERN is
instead treated as if it were C</\s+/>; in particular, this means that
the pattern S<C</ />> instead of the string S<C<" ">>, thereby allowing
only a single space character to be a separator. In earlier Perls this
special case was restricted to the use of a plain S<C<" ">> as the
-pattern argument to split, in Perl 5.18.0 and later this special case is
-triggered by any expression which evaluates as the simple string S<C<" ">>.
+pattern argument to split; in Perl 5.18.0 and later this special case is
+triggered by any expression which evaluates to the simple string S<C<" ">>.
If omitted, PATTERN defaults to a single space, S<C<" ">>, triggering
the previously described I<awk> emulation.
print join(':', split(//, 'abc', 1)), "\n";
-produces the output 'abc', and this:
+produces the output C<abc>, and this:
print join(':', split(//, 'abc', 2)), "\n";
-produces the output 'a:bc', and each of these:
+produces the output C<a:bc>, and each of these:
print join(':', split(//, 'abc', 3)), "\n";
print join(':', split(//, 'abc', 4)), "\n";
-produces the output 'a:b:c'.
+produces the output C<a:b:c>.
If LIMIT is negative, it is treated as if it were instead arbitrarily
large; as many fields as possible are produced.
preserved); if all fields are empty, then all fields are considered to
be trailing (and are thus stripped in this case). Thus, the following:
- print join(':', split(',', 'a,b,c,,,')), "\n";
+ print join(':', split(/,/, 'a,b,c,,,')), "\n";
-produces the output 'a:b:c', but the following:
+produces the output C<a:b:c>, but the following:
- print join(':', split(',', 'a,b,c,,,', -1)), "\n";
+ print join(':', split(/,/, 'a,b,c,,,', -1)), "\n";
-produces the output 'a:b:c:::'.
+produces the output C<a:b:c:::>.
In time-critical applications, it is worthwhile to avoid splitting
into more fields than necessary. Thus, when assigning to a list,
were one larger than the number of variables in the list; for the
following, LIMIT is implicitly 3:
- ($login, $passwd) = split(/:/);
+ my ($login, $passwd) = split(/:/);
Note that splitting an EXPR that evaluates to the empty string always
produces zero fields, regardless of the LIMIT specified.
print join(':', split(/ /, ' abc')), "\n";
-produces the output ':abc'. However, a zero-width match at the
+produces the output C<:abc>. However, a zero-width match at the
beginning of EXPR never produces an empty field, so that:
print join(':', split(//, ' abc'));
-produces the output S<' :a:b:c'> (rather than S<': :a:b:c'>).
+produces the output S<C< :a:b:c>> (rather than S<C<: :a:b:c>>).
An empty trailing field, on the other hand, is produced when there is a
match at the end of EXPR, regardless of the length of the match
print join(':', split(//, ' abc', -1)), "\n";
-produces the output S<' :a:b:c:'>.
+produces the output S<C< :a:b:c:>>.
If the PATTERN contains
L<capturing groups|perlretut/Grouping things and hierarchical matching>,
then for each separator, an additional field is produced for each substring
captured by a group (in the order in which the groups are specified,
as per L<backreferences|perlretut/Backreferences>); if any group does not
-match, then it captures the C<undef> value instead of a substring. Also,
+match, then it captures the L<C<undef>|/undef EXPR> value instead of a
+substring. Also,
note that any such additional field is produced whenever there is a
separator (that is, whenever a split occurs), and such an additional field
does B<not> count towards the LIMIT. Consider the following expressions
=for Pod::Functions formatted print into a string
-Returns a string formatted by the usual C<printf> conventions of the C
-library function C<sprintf>. See below for more details
-and see L<sprintf(3)> or L<printf(3)> on your system for an explanation of
-the general principles.
+Returns a string formatted by the usual
+L<C<printf>|/printf FILEHANDLE FORMAT, LIST> conventions of the C
+library function L<C<sprintf>|/sprintf FORMAT, LIST>. See below for
+more details and see L<sprintf(3)> or L<printf(3)> on your system for an
+explanation of the general principles.
For example:
# Format number with up to 8 leading zeroes
- $result = sprintf("%08d", $number);
+ my $result = sprintf("%08d", $number);
# Round number to 3 digits after decimal point
- $rounded = sprintf("%.3f", $number);
+ my $rounded = sprintf("%.3f", $number);
-Perl does its own C<sprintf> formatting: it emulates the C
-function sprintf(3), but doesn't use it except for floating-point
-numbers, and even then only standard modifiers are allowed.
-Non-standard extensions in your local sprintf(3) are
+Perl does its own L<C<sprintf>|/sprintf FORMAT, LIST> formatting: it
+emulates the C
+function L<sprintf(3)>, but doesn't use it except for floating-point
+numbers, and even then only standard modifiers are allowed.
+Non-standard extensions in your local L<sprintf(3)> are
therefore unavailable from Perl.
-Unlike C<printf>, C<sprintf> does not do what you probably mean when you
-pass it an array as your first argument.
+Unlike L<C<printf>|/printf FILEHANDLE FORMAT, LIST>,
+L<C<sprintf>|/sprintf FORMAT, LIST> does not do what you probably mean
+when you pass it an array as your first argument.
The array is given scalar context,
and instead of using the 0th element of the array as the format, Perl will
use the count of elements in the array as the format, which is almost never
useful.
-Perl's C<sprintf> permits the following universally-known conversions:
+Perl's L<C<sprintf>|/sprintf FORMAT, LIST> permits the following
+universally-known conversions:
%% a percent sign
%c a character with the given number
printf '<%.1e>', 10; # prints "<1.0e+01>"
For "g" and "G", this specifies the maximum number of digits to show,
-including those prior to the decimal point and those after it; for
+including those prior to the decimal point and those after it; for
example:
# These examples are subject to system-specific variation.
As of 5.14, none of these raises an exception if they are not supported on
your platform. However, if warnings are enabled, a warning of the
-C<printf> warning class is issued on an unsupported conversion flag.
-Should you instead prefer an exception, do this:
+L<C<printf>|warnings> warning class is issued on an unsupported
+conversion flag. Should you instead prefer an exception, do this:
use warnings FATAL => "printf";
=item order of arguments
-Normally, sprintf() takes the next unused argument as the value to
+Normally, L<C<sprintf>|/sprintf FORMAT, LIST> takes the next unused
+argument as the value to
format for each format specification. If the format specification
uses C<*> to require additional arguments, these are consumed from
the argument list in the order they appear in the format
=back
-If C<use locale> (including C<use locale 'not_characters'>) is in effect
-and POSIX::setlocale() has been called,
+If L<C<use locale>|locale> (including C<use locale ':not_characters'>)
+is in effect and L<C<POSIX::setlocale>|POSIX/C<setlocale>> has been
+called,
the character used for the decimal separator in formatted floating-point
numbers is affected by the C<LC_NUMERIC> locale. See L<perllocale>
and L<POSIX>.
=for Pod::Functions square root function
Return the positive square root of EXPR. If EXPR is omitted, uses
-C<$_>. Works only for non-negative operands unless you've
-loaded the C<Math::Complex> module.
+L<C<$_>|perlvar/$_>. Works only for non-negative operands unless you've
+loaded the L<C<Math::Complex>|Math::Complex> module.
use Math::Complex;
print sqrt(-4); # prints 2i
=for Pod::Functions seed the random number generator
-Sets and returns the random number seed for the C<rand> operator.
+Sets and returns the random number seed for the L<C<rand>|/rand EXPR>
+operator.
-The point of the function is to "seed" the C<rand> function so that C<rand>
-can produce a different sequence each time you run your program. When
-called with a parameter, C<srand> uses that for the seed; otherwise it
+The point of the function is to "seed" the L<C<rand>|/rand EXPR>
+function so that L<C<rand>|/rand EXPR> can produce a different sequence
+each time you run your program. When called with a parameter,
+L<C<srand>|/srand EXPR> uses that for the seed; otherwise it
(semi-)randomly chooses a seed. In either case, starting with Perl 5.14,
it returns the seed. To signal that your code will work I<only> on Perls
of a recent vintage:
use 5.014; # so srand returns the seed
-If C<srand()> is not called explicitly, it is called implicitly without a
-parameter at the first use of the C<rand> operator.
-However, there are a few situations where programs are likely to
-want to call C<srand>. One is for generating predictable results, generally for
-testing or debugging. There, you use C<srand($seed)>, with the same C<$seed>
-each time. Another case is that you may want to call C<srand()>
-after a C<fork()> to avoid child processes sharing the same seed value as the
-parent (and consequently each other).
+If L<C<srand>|/srand EXPR> is not called explicitly, it is called
+implicitly without a parameter at the first use of the
+L<C<rand>|/rand EXPR> operator. However, there are a few situations
+where programs are likely to want to call L<C<srand>|/srand EXPR>. One
+is for generating predictable results, generally for testing or
+debugging. There, you use C<srand($seed)>, with the same C<$seed> each
+time. Another case is that you may want to call L<C<srand>|/srand EXPR>
+after a L<C<fork>|/fork> to avoid child processes sharing the same seed
+value as the parent (and consequently each other).
Do B<not> call C<srand()> (i.e., without an argument) more than once per
process. The internal state of the random number generator should
contain more entropy than can be provided by any seed, so calling
-C<srand()> again actually I<loses> randomness.
+L<C<srand>|/srand EXPR> again actually I<loses> randomness.
-Most implementations of C<srand> take an integer and will silently
+Most implementations of L<C<srand>|/srand EXPR> take an integer and will
+silently
truncate decimal numbers. This means C<srand(42)> will usually
produce the same results as C<srand(42.1)>. To be safe, always pass
-C<srand> an integer.
+L<C<srand>|/srand EXPR> an integer.
A typical use of the returned seed is for a test program which has too many
combinations to test comprehensively in the time available to it each run. It
can test a random subset each time, and should there be a failure, log the seed
used for that run so that it can later be used to reproduce the same results.
-B<C<rand()> is not cryptographically secure. You should not rely
+B<L<C<rand>|/rand EXPR> is not cryptographically secure. You should not rely
on it in security-sensitive situations.> As of this writing, a
number of third-party CPAN modules offer random number generators
intended by their authors to be cryptographically secure,
=for Pod::Functions get a file's status information
Returns a 13-element list giving the status info for a file, either
-the file opened via FILEHANDLE or DIRHANDLE, or named by EXPR. If EXPR is
-omitted, it stats C<$_> (not C<_>!). Returns the empty list if C<stat> fails. Typically
+the file opened via FILEHANDLE or DIRHANDLE, or named by EXPR. If EXPR is
+omitted, it stats L<C<$_>|perlvar/$_> (not C<_>!). Returns the empty
+list if L<C<stat>|/stat FILEHANDLE> fails. Typically
used as follows:
- ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
- $atime,$mtime,$ctime,$blksize,$blocks)
+ my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+ $atime,$mtime,$ctime,$blksize,$blocks)
= stat($filename);
Not all fields are supported on all filesystem types. Here are the
ctime field is non-portable. In particular, you cannot expect it to be a
"creation time"; see L<perlport/"Files and Filesystems"> for details.
-If C<stat> is passed the special filehandle consisting of an underline, no
-stat is done, but the current contents of the stat structure from the
-last C<stat>, C<lstat>, or filetest are returned. Example:
+If L<C<stat>|/stat FILEHANDLE> is passed the special filehandle
+consisting of an underline, no stat is done, but the current contents of
+the stat structure from the last L<C<stat>|/stat FILEHANDLE>,
+L<C<lstat>|/lstat FILEHANDLE>, or filetest are returned. Example:
if (-x $file && (($d) = stat(_)) && $d < 0) {
print "$file is executable NFS file\n";
should mask off the file type portion and (s)printf using a C<"%o">
if you want to see the real permissions.
- $mode = (stat($filename))[2];
+ my $mode = (stat($filename))[2];
printf "Permissions are %04o\n", $mode & 07777;
-In scalar context, C<stat> returns a boolean value indicating success
+In scalar context, L<C<stat>|/stat FILEHANDLE> returns a boolean value
+indicating success
or failure, and, if successful, sets the information associated with
the special filehandle C<_>.
The L<File::stat> module provides a convenient, by-name access mechanism:
use File::stat;
- $sb = stat($filename);
+ my $sb = stat($filename);
printf "File is %s, size is %s, perm %04o, mtime %s\n",
$filename, $sb->size, $sb->mode & 07777,
scalar localtime $sb->mtime;
You can import symbolic mode constants (C<S_IF*>) and functions
-(C<S_IS*>) from the Fcntl module:
+(C<S_IS*>) from the L<Fcntl> module:
use Fcntl ':mode';
- $mode = (stat($filename))[2];
+ my $mode = (stat($filename))[2];
- $user_rwx = ($mode & S_IRWXU) >> 6;
- $group_read = ($mode & S_IRGRP) >> 3;
- $other_execute = $mode & S_IXOTH;
+ my $user_rwx = ($mode & S_IRWXU) >> 6;
+ my $group_read = ($mode & S_IRGRP) >> 3;
+ my $other_execute = $mode & S_IXOTH;
printf "Permissions are %04o\n", S_IMODE($mode), "\n";
- $is_setuid = $mode & S_ISUID;
- $is_directory = S_ISDIR($mode);
+ my $is_setuid = $mode & S_ISUID;
+ my $is_directory = S_ISDIR($mode);
You could write the last two using the C<-u> and C<-d> operators.
Commonly available C<S_IF*> constants are:
S_ISENFMT($mode) S_ISWHT($mode)
-See your native chmod(2) and stat(2) documentation for more details
+See your native L<chmod(2)> and L<stat(2)> documentation for more details
about the C<S_*> constants. To get status info for a symbolic link
-instead of the target file behind the link, use the C<lstat> function.
+instead of the target file behind the link, use the
+L<C<lstat>|/lstat FILEHANDLE> function.
Portability issues: L<perlport/stat>.
=for Pod::Functions +state declare and assign a persistent lexical variable
-C<state> declares a lexically scoped variable, just like C<my>.
+L<C<state>|/state VARLIST> declares a lexically scoped variable, just
+like L<C<my>|/my VARLIST>.
However, those variables will never be reinitialized, contrary to
lexical variables that are reinitialized each time their enclosing block
is entered.
See L<perlsub/"Persistent Private Variables"> for details.
If more than one variable is listed, the list must be placed in
-parentheses. With a parenthesised list, C<undef> can be used as a
+parentheses. With a parenthesised list, L<C<undef>|/undef EXPR> can be
+used as a
dummy placeholder. However, since initialization of state variables in
list context is currently not possible this would serve no purpose.
-C<state> variables are enabled only when the C<use feature "state"> pragma
-is in effect, unless the keyword is written as C<CORE::state>.
-See also L<feature>. Alternately, include a C<use v5.10> or later to the
-current scope.
+L<C<state>|/state VARLIST> is available only if the
+L<C<"state"> feature|feature/The 'state' feature> is enabled or if it is
+prefixed with C<CORE::>. The
+L<C<"state"> feature|feature/The 'state' feature> is enabled
+automatically with a C<use v5.10> (or higher) declaration in the current
+scope.
+
=item study SCALAR
X<study>
=for Pod::Functions optimize input data for repeated searches
-May take extra time to study SCALAR (C<$_> if unspecified) in anticipation
+B<Note that since Perl version 5.16 this function has been a no-op, but
+this might change in a future release.>
+
+May take extra time to study SCALAR (L<C<$_>|perlvar/$_> if unspecified)
+in anticipation
of doing many pattern matches on the string before it is next modified.
This may or may not save time, depending on the nature and number of
patterns you are searching and the distribution of character
that scan for many short constant strings (including the constant
parts of more complex patterns) will benefit most.
-Note that since Perl version 5.16 this function has been a no-op, but
-this might change in a future release.
-
-(The way C<study> works is this: a linked list of every
+(The way L<C<study>|/study SCALAR> used to work is this: a linked list
+of every
character in the string to be searched is made, so we know, for
example, where all the C<'k'> characters are. From each search string,
the rarest character is selected, based on some static frequency tables
print;
}
-In searching for C</\bfoo\b/>, only locations in C<$_> that contain C<f>
+In searching for C</\bfoo\b/>, only locations in L<C<$_>|perlvar/$_>
+that contain C<f>
will be looked at, because C<f> is rarer than C<o>. In general, this is
a big win except in pathological cases. The only question is whether
it saves you more time than it took to build the linked list in the
first place.
Note that if you have to look for strings that you don't know till
-runtime, you can build an entire loop as a string and C<eval> that to
-avoid recompiling all your patterns all the time. Together with
-undefining C<$/> to input entire files as one record, this can be quite
-fast, often faster than specialized programs like fgrep(1). The following
+runtime, you can build an entire loop as a string and L<C<eval>|/eval
+EXPR> that to avoid recompiling all your patterns all the time.
+Together with undefining L<C<$E<sol>>|perlvar/$E<sol>> to input entire
+files as one record, this can be quite
+fast, often faster than specialized programs like L<fgrep(1)>. The following
scans a list of files (C<@files>) for a list of words (C<@words>), and prints
out the names of those files that contain a match:
- $search = 'while (<>) { study;';
- foreach $word (@words) {
+ my $search = 'local $/; while (<>) { study;';
+ foreach my $word (@words) {
$search .= "++\$seen{\$ARGV} if /\\b$word\\b/;\n";
}
$search .= "}";
@ARGV = @files;
- undef $/;
+ my %seen;
eval $search; # this screams
- $/ = "\n"; # put back to normal input delimiter
- foreach $file (sort keys(%seen)) {
+ foreach my $file (sort keys(%seen)) {
print $file, "\n";
}
=for Pod::Functions +current_sub the current subroutine, or C<undef> if not in a subroutine
A special token that returns a reference to the current subroutine, or
-C<undef> outside of a subroutine.
+L<C<undef>|/undef EXPR> outside of a subroutine.
-The behaviour of C<__SUB__> within a regex code block (such as C</(?{...})/>)
-is subject to change.
+The behaviour of L<C<__SUB__>|/__SUB__> within a regex code block (such
+as C</(?{...})/>) is subject to change.
-This token is only available under C<use v5.16> or the "current_sub"
-feature. See L<feature>.
+This token is only available under C<use v5.16> or the
+L<C<"current_sub"> feature|feature/The 'current_sub' feature>.
+See L<feature>.
=item substr EXPR,OFFSET,LENGTH,REPLACEMENT
X<substr> X<substring> X<mid> X<left> X<right>
my $tail = substr $s, -4; # tree
my $z = substr $s, -4, 2; # tr
-You can use the substr() function as an lvalue, in which case EXPR
+You can use the L<C<substr>|/substr EXPR,OFFSET,LENGTH,REPLACEMENT>
+function as an lvalue, in which case EXPR
must itself be an lvalue. If you assign something shorter than LENGTH,
the string will shrink, and if you assign something longer than LENGTH,
the string will grow to accommodate it. To keep the string the same
-length, you may need to pad or chop your value using C<sprintf>.
+length, you may need to pad or chop your value using
+L<C<sprintf>|/sprintf FORMAT, LIST>.
If OFFSET and LENGTH specify a substring that is partly outside the
string, only the part within the string is returned. If the substring
-is beyond either end of the string, substr() returns the undefined
+is beyond either end of the string,
+L<C<substr>|/substr EXPR,OFFSET,LENGTH,REPLACEMENT> returns the undefined
value and produces a warning. When used as an lvalue, specifying a
substring that is entirely outside the string raises an exception.
Here's an example showing the behavior for boundary cases:
my $oops = substr $name, 7; # returns undef, with warning
substr($name, 7) = 'gap'; # raises an exception
-An alternative to using substr() as an lvalue is to specify the
+An alternative to using
+L<C<substr>|/substr EXPR,OFFSET,LENGTH,REPLACEMENT> as an lvalue is to
+specify the
replacement string as the 4th argument. This allows you to replace
parts of the EXPR and return what was there before in one operation,
-just as you can with splice().
+just as you can with
+L<C<splice>|/splice ARRAY,OFFSET,LENGTH,LIST>.
my $s = "The black cat climbed the green tree";
my $z = substr $s, 14, 7, "jumped from"; # climbed
# $s is now "The black cat jumped from the green tree"
-Note that the lvalue returned by the three-argument version of substr() acts as
+Note that the lvalue returned by the three-argument version of
+L<C<substr>|/substr EXPR,OFFSET,LENGTH,REPLACEMENT> acts as
a 'magic bullet'; each time it is assigned to, it remembers which part
of the original string is being modified; for example:
- $x = '1234';
+ my $x = '1234';
for (substr($x,1,2)) {
$_ = 'a'; print $x,"\n"; # prints 1a4
$_ = 'xyz'; print $x,"\n"; # prints 1xyz4
With negative offsets, it remembers its position from the end of the string
when the target string is modified:
- $x = '1234';
+ my $x = '1234';
for (substr($x, -3, 2)) {
$_ = 'a'; print $x,"\n"; # prints 1a4, as above
$x = 'abcdefg';
symbolic links, raises an exception. To check for that,
use eval:
- $symlink_exists = eval { symlink("",""); 1 };
+ my $symlink_exists = eval { symlink("",""); 1 };
Portability issues: L<perlport/symlink>.
an int. If not, the pointer to the string value is passed. You are
responsible to make sure a string is pre-extended long enough to
receive any result that might be written into a string. You can't use a
-string literal (or other read-only string) as an argument to C<syscall>
-because Perl has to assume that any string pointer might be written
-through. If your
+string literal (or other read-only string) as an argument to
+L<C<syscall>|/syscall NUMBER, LIST> because Perl has to assume that any
+string pointer might be written through. If your
integer arguments are not literals and have never been interpreted in a
numeric context, you may need to add C<0> to them to force them to look
-like numbers. This emulates the C<syswrite> function (or vice versa):
+like numbers. This emulates the
+L<C<syswrite>|/syswrite FILEHANDLE,SCALAR,LENGTH,OFFSET> function (or
+vice versa):
require 'syscall.ph'; # may need to run h2ph
- $s = "hi there\n";
- syscall(&SYS_write, fileno(STDOUT), $s, length $s);
+ my $s = "hi there\n";
+ syscall(SYS_write(), fileno(STDOUT), $s, length $s);
Note that Perl supports passing of up to only 14 arguments to your syscall,
which in practice should (usually) suffice.
Syscall returns whatever value returned by the system call it calls.
-If the system call fails, C<syscall> returns C<-1> and sets C<$!> (errno).
+If the system call fails, L<C<syscall>|/syscall NUMBER, LIST> returns
+C<-1> and sets L<C<$!>|perlvar/$!> (errno).
Note that some system calls I<can> legitimately return C<-1>. The proper
-way to handle such calls is to assign C<$!=0> before the call, then
-check the value of C<$!> if C<syscall> returns C<-1>.
+way to handle such calls is to assign C<$! = 0> before the call, then
+check the value of L<C<$!>|perlvar/$!> if
+L<C<syscall>|/syscall NUMBER, LIST> returns C<-1>.
-There's a problem with C<syscall(&SYS_pipe)>: it returns the file
+There's a problem with C<syscall(SYS_pipe())>: it returns the file
number of the read end of the pipe it creates, but there is no way
to retrieve the file number of the other end. You can avoid this
-problem by using C<pipe> instead.
+problem by using L<C<pipe>|/pipe READHANDLE,WRITEHANDLE> instead.
Portability issues: L<perlport/syscall>.
Opens the file whose filename is given by FILENAME, and associates it with
FILEHANDLE. If FILEHANDLE is an expression, its value is used as the real
filehandle wanted; an undefined scalar will be suitably autovivified. This
-function calls the underlying operating system's I<open>(2) function with the
+function calls the underlying operating system's L<open(2)> function with the
parameters FILENAME, MODE, and PERMS.
-Returns true on success and C<undef> otherwise.
+Returns true on success and L<C<undef>|/undef EXPR> otherwise.
The possible values and flag bits of the MODE parameter are
-system-dependent; they are available via the standard module C<Fcntl>. See
-the documentation of your operating system's I<open>(2) syscall to see
+system-dependent; they are available via the standard module
+L<C<Fcntl>|Fcntl>. See the documentation of your operating system's
+L<open(2)> syscall to see
which values and flag bits are available. You may combine several flags
using the C<|>-operator.
OS/390 and on the Macintosh; you probably don't want to
use them in new code.
-If the file named by FILENAME does not exist and the C<open> call creates
+If the file named by FILENAME does not exist and the
+L<C<open>|/open FILEHANDLE,EXPR> call creates
it (typically because MODE includes the C<O_CREAT> flag), then the value of
PERMS specifies the permissions of the newly created file. If you omit
-the PERMS argument to C<sysopen>, Perl uses the octal value C<0666>.
+the PERMS argument to L<C<sysopen>|/sysopen FILEHANDLE,FILENAME,MODE>,
+Perl uses the octal value C<0666>.
These permission values need to be in octal, and are modified by your
-process's current C<umask>.
+process's current L<C<umask>|/umask EXPR>.
X<O_CREAT>
In many systems the C<O_EXCL> flag is available for opening files in
exclusive mode. This is B<not> locking: exclusiveness means here that
-if the file already exists, sysopen() fails. C<O_EXCL> may not work
+if the file already exists,
+L<C<sysopen>|/sysopen FILEHANDLE,FILENAME,MODE> fails. C<O_EXCL> may
+not work
on network filesystems, and has no effect unless the C<O_CREAT> flag
is set as well. Setting C<O_CREAT|O_EXCL> prevents the file from
being opened if it is a symbolic link. It does not protect against
C<O_TRUNC> with C<O_RDONLY> is undefined.
X<O_TRUNC>
-You should seldom if ever use C<0644> as argument to C<sysopen>, because
+You should seldom if ever use C<0644> as argument to
+L<C<sysopen>|/sysopen FILEHANDLE,FILENAME,MODE>, because
that takes away the user's option to have a more permissive umask.
-Better to omit it. See the perlfunc(1) entry on C<umask> for more
-on this.
+Better to omit it. See L<C<umask>|/umask EXPR> for more on this.
-Note that C<sysopen> depends on the fdopen() C library function.
-On many Unix systems, fdopen() is known to fail when file descriptors
-exceed a certain value, typically 255. If you need more file
-descriptors than that, consider using the POSIX::open() function.
+Note that under Perls older than 5.8.0,
+L<C<sysopen>|/sysopen FILEHANDLE,FILENAME,MODE> depends on the
+L<fdopen(3)> C library function. On many Unix systems, L<fdopen(3)> is known
+to fail when file descriptors exceed a certain value, typically 255. If
+you need more file descriptors than that, consider using the
+L<C<POSIX::open>|POSIX/C<open>> function. For Perls 5.8.0 and later,
+PerlIO is (most often) the default.
See L<perlopentut> for a kinder, gentler explanation of opening files.
=for Pod::Functions fixed-length unbuffered input from a filehandle
Attempts to read LENGTH bytes of data into variable SCALAR from the
-specified FILEHANDLE, using the read(2). It bypasses
-buffered IO, so mixing this with other kinds of reads, C<print>,
-C<write>, C<seek>, C<tell>, or C<eof> can cause confusion because the
-perlio or stdio layers usually buffers data. Returns the number of
+specified FILEHANDLE, using L<read(2)>. It bypasses
+buffered IO, so mixing this with other kinds of reads,
+L<C<print>|/print FILEHANDLE LIST>, L<C<write>|/write FILEHANDLE>,
+L<C<seek>|/seek FILEHANDLE,POSITION,WHENCE>,
+L<C<tell>|/tell FILEHANDLE>, or L<C<eof>|/eof FILEHANDLE> can cause
+confusion because the
+perlio or stdio layers usually buffer data. Returns the number of
bytes actually read, C<0> at end of file, or undef if there was an
-error (in the latter case C<$!> is also set). SCALAR will be grown or
+error (in the latter case L<C<$!>|perlvar/$!> is also set). SCALAR will
+be grown or
shrunk so that the last byte actually read is the last byte of the
scalar after the read.
results in the string being padded to the required size with C<"\0">
bytes before the result of the read is appended.
-There is no syseof() function, which is ok, since eof() doesn't work
-well on device files (like ttys) anyway. Use sysread() and check
-for a return value for 0 to decide whether you're done.
+There is no syseof() function, which is ok, since
+L<C<eof>|/eof FILEHANDLE> doesn't work well on device files (like ttys)
+anyway. Use L<C<sysread>|/sysread FILEHANDLE,SCALAR,LENGTH,OFFSET> and
+check for a return value for 0 to decide whether you're done.
-Note that if the filehandle has been marked as C<:utf8> Unicode
+Note that if the filehandle has been marked as C<:utf8>, Unicode
characters are read instead of bytes (the LENGTH, OFFSET, and the
-return value of sysread() are in Unicode characters).
-The C<:encoding(...)> layer implicitly introduces the C<:utf8> layer.
-See L</binmode>, L</open>, and the C<open> pragma, L<open>.
+return value of L<C<sysread>|/sysread FILEHANDLE,SCALAR,LENGTH,OFFSET>
+are in Unicode characters). The C<:encoding(...)> layer implicitly
+introduces the C<:utf8> layer. See
+L<C<binmode>|/binmode FILEHANDLE, LAYER>,
+L<C<open>|/open FILEHANDLE,EXPR>, and the L<open> pragma.
=item sysseek FILEHANDLE,POSITION,WHENCE
X<sysseek> X<lseek>
=for Pod::Functions +5.004 position I/O pointer on handle used with sysread and syswrite
-Sets FILEHANDLE's system position in bytes using lseek(2). FILEHANDLE may
+Sets FILEHANDLE's system position in bytes using L<lseek(2)>. FILEHANDLE may
be an expression whose value gives the name of the filehandle. The values
for WHENCE are C<0> to set the new position to POSITION; C<1> to set the it
to the current position plus POSITION; and C<2> to set it to EOF plus
Note the I<in bytes>: even if the filehandle has been set to operate
on characters (for example by using the C<:encoding(utf8)> I/O layer),
-tell() will return byte offsets, not character offsets (because
-implementing that would render sysseek() unacceptably slow).
-
-sysseek() bypasses normal buffered IO, so mixing it with reads other
-than C<sysread> (for example C<< <> >> or read()) C<print>, C<write>,
-C<seek>, C<tell>, or C<eof> may cause confusion.
+L<C<tell>|/tell FILEHANDLE> will return byte offsets, not character
+offsets (because implementing that would render
+L<C<sysseek>|/sysseek FILEHANDLE,POSITION,WHENCE> unacceptably slow).
+
+L<C<sysseek>|/sysseek FILEHANDLE,POSITION,WHENCE> bypasses normal
+buffered IO, so mixing it with reads other than
+L<C<sysread>|/sysread FILEHANDLE,SCALAR,LENGTH,OFFSET> (for example
+L<C<readline>|/readline EXPR> or
+L<C<read>|/read FILEHANDLE,SCALAR,LENGTH,OFFSET>),
+L<C<print>|/print FILEHANDLE LIST>, L<C<write>|/write FILEHANDLE>,
+L<C<seek>|/seek FILEHANDLE,POSITION,WHENCE>,
+L<C<tell>|/tell FILEHANDLE>, or L<C<eof>|/eof FILEHANDLE> may cause
+confusion.
For WHENCE, you may also use the constants C<SEEK_SET>, C<SEEK_CUR>,
and C<SEEK_END> (start of the file, current position, end of the file)
-from the Fcntl module. Use of the constants is also more portable
+from the L<Fcntl> module. Use of the constants is also more portable
than relying on 0, 1, and 2. For example to define a "systell" function:
use Fcntl 'SEEK_CUR';
sub systell { sysseek($_[0], 0, SEEK_CUR) }
Returns the new position, or the undefined value on failure. A position
-of zero is returned as the string C<"0 but true">; thus C<sysseek> returns
+of zero is returned as the string C<"0 but true">; thus
+L<C<sysseek>|/sysseek FILEHANDLE,POSITION,WHENCE> returns
true on success and false on failure, yet you can still easily determine
the new position.
=for Pod::Functions run a separate program
-Does exactly the same thing as C<exec LIST>, except that a fork is
+Does exactly the same thing as L<C<exec>|/exec LIST>, except that a fork is
done first and the parent process waits for the child process to
exit. Note that argument processing varies depending on the
number of arguments. If there is more than one argument in LIST,
Perl will attempt to flush all files opened for
output before any operation that may do a fork, but this may not be
supported on some platforms (see L<perlport>). To be safe, you may need
-to set C<$|> ($AUTOFLUSH in English) or call the C<autoflush()> method
-of C<IO::Handle> on any open handles.
+to set L<C<$E<verbar>>|perlvar/$E<verbar>> (C<$AUTOFLUSH> in L<English>)
+or call the C<autoflush> method of L<C<IO::Handle>|IO::Handle/METHODS>
+on any open handles.
The return value is the exit status of the program as returned by the
-C<wait> call. To get the actual exit value, shift right by eight (see
-below). See also L</exec>. This is I<not> what you want to use to capture
-the output from a command; for that you should use merely backticks or
-C<qx//>, as described in L<perlop/"`STRING`">. Return value of -1
-indicates a failure to start the program or an error of the wait(2) system
-call (inspect $! for the reason).
-
-If you'd like to make C<system> (and many other bits of Perl) die on error,
-have a look at the L<autodie> pragma.
-
-Like C<exec>, C<system> allows you to lie to a program about its name if
-you use the C<system PROGRAM LIST> syntax. Again, see L</exec>.
+L<C<wait>|/wait> call. To get the actual exit value, shift right by
+eight (see below). See also L<C<exec>|/exec LIST>. This is I<not> what
+you want to use to capture the output from a command; for that you
+should use merely backticks or
+L<C<qxE<sol>E<sol>>|/qxE<sol>STRINGE<sol>>, as described in
+L<perlop/"`STRING`">. Return value of -1 indicates a failure to start
+the program or an error of the L<wait(2)> system call (inspect
+L<C<$!>|perlvar/$!> for the reason).
+
+If you'd like to make L<C<system>|/system LIST> (and many other bits of
+Perl) die on error, have a look at the L<autodie> pragma.
+
+Like L<C<exec>|/exec LIST>, L<C<system>|/system LIST> allows you to lie
+to a program about its name if you use the C<system PROGRAM LIST>
+syntax. Again, see L<C<exec>|/exec LIST>.
Since C<SIGINT> and C<SIGQUIT> are ignored during the execution of
-C<system>, if you expect your program to terminate on receipt of these
-signals you will need to arrange to do so yourself based on the return
-value.
+L<C<system>|/system LIST>, if you expect your program to terminate on
+receipt of these signals you will need to arrange to do so yourself
+based on the return value.
- @args = ("command", "arg1", "arg2");
+ my @args = ("command", "arg1", "arg2");
system(@args) == 0
- or die "system @args failed: $?"
+ or die "system @args failed: $?";
-If you'd like to manually inspect C<system>'s failure, you can check all
-possible failure modes by inspecting C<$?> like this:
+If you'd like to manually inspect L<C<system>|/system LIST>'s failure,
+you can check all possible failure modes by inspecting
+L<C<$?>|perlvar/$?> like this:
if ($? == -1) {
print "failed to execute: $!\n";
printf "child exited with value %d\n", $? >> 8;
}
-Alternatively, you may inspect the value of C<${^CHILD_ERROR_NATIVE}>
-with the C<W*()> calls from the POSIX module.
+Alternatively, you may inspect the value of
+L<C<${^CHILD_ERROR_NATIVE}>|perlvar/${^CHILD_ERROR_NATIVE}> with the
+L<C<W*()>|POSIX/C<WIFEXITED>> calls from the L<POSIX> module.
-When C<system>'s arguments are executed indirectly by the shell,
-results and return codes are subject to its quirks.
-See L<perlop/"`STRING`"> and L</exec> for details.
+When L<C<system>|/system LIST>'s arguments are executed indirectly by
+the shell, results and return codes are subject to its quirks.
+See L<perlop/"`STRING`"> and L<C<exec>|/exec LIST> for details.
-Since C<system> does a C<fork> and C<wait> it may affect a C<SIGCHLD>
-handler. See L<perlipc> for details.
+Since L<C<system>|/system LIST> does a L<C<fork>|/fork> and
+L<C<wait>|/wait> it may affect a C<SIGCHLD> handler. See L<perlipc> for
+details.
Portability issues: L<perlport/system>.
=for Pod::Functions fixed-length unbuffered output to a filehandle
Attempts to write LENGTH bytes of data from variable SCALAR to the
-specified FILEHANDLE, using write(2). If LENGTH is
+specified FILEHANDLE, using L<write(2)>. If LENGTH is
not specified, writes whole SCALAR. It bypasses buffered IO, so
-mixing this with reads (other than C<sysread())>, C<print>, C<write>,
-C<seek>, C<tell>, or C<eof> may cause confusion because the perlio and
-stdio layers usually buffer data. Returns the number of bytes
-actually written, or C<undef> if there was an error (in this case the
-errno variable C<$!> is also set). If the LENGTH is greater than the
+mixing this with reads (other than C<sysread)>),
+L<C<print>|/print FILEHANDLE LIST>, L<C<write>|/write FILEHANDLE>,
+L<C<seek>|/seek FILEHANDLE,POSITION,WHENCE>,
+L<C<tell>|/tell FILEHANDLE>, or L<C<eof>|/eof FILEHANDLE> may cause
+confusion because the perlio and stdio layers usually buffer data.
+Returns the number of bytes actually written, or L<C<undef>|/undef EXPR>
+if there was an error (in this case the errno variable
+L<C<$!>|perlvar/$!> is also set). If the LENGTH is greater than the
data available in the SCALAR after the OFFSET, only as much data as is
available will be written.
B<WARNING>: If the filehandle is marked C<:utf8>, Unicode characters
encoded in UTF-8 are written instead of bytes, and the LENGTH, OFFSET, and
-return value of syswrite() are in (UTF8-encoded Unicode) characters.
+return value of L<C<syswrite>|/syswrite FILEHANDLE,SCALAR,LENGTH,OFFSET>
+are in (UTF8-encoded Unicode) characters.
The C<:encoding(...)> layer implicitly introduces the C<:utf8> layer.
Alternately, if the handle is not marked with an encoding but you
attempt to write characters with code points over 255, raises an exception.
-See L</binmode>, L</open>, and the C<open> pragma, L<open>.
+See L<C<binmode>|/binmode FILEHANDLE, LAYER>,
+L<C<open>|/open FILEHANDLE,EXPR>, and the L<open> pragma.
=item tell FILEHANDLE
X<tell>
Note the I<in bytes>: even if the filehandle has been set to
operate on characters (for example by using the C<:encoding(utf8)> open
-layer), tell() will return byte offsets, not character offsets (because
-that would render seek() and tell() rather slow).
+layer), L<C<tell>|/tell FILEHANDLE> will return byte offsets, not
+character offsets (because that would render
+L<C<seek>|/seek FILEHANDLE,POSITION,WHENCE> and
+L<C<tell>|/tell FILEHANDLE> rather slow).
-The return value of tell() for the standard streams like the STDIN
-depends on the operating system: it may return -1 or something else.
-tell() on pipes, fifos, and sockets usually returns -1.
+The return value of L<C<tell>|/tell FILEHANDLE> for the standard streams
+like the STDIN depends on the operating system: it may return -1 or
+something else. L<C<tell>|/tell FILEHANDLE> on pipes, fifos, and
+sockets usually returns -1.
-There is no C<systell> function. Use C<sysseek(FH, 0, 1)> for that.
+There is no C<systell> function. Use C<sysseek($fh, 0, 1)> for that.
-Do not use tell() (or other buffered I/O operations) on a filehandle
-that has been manipulated by sysread(), syswrite(), or sysseek().
-Those functions ignore the buffering, while tell() does not.
+Do not use L<C<tell>|/tell FILEHANDLE> (or other buffered I/O
+operations) on a filehandle that has been manipulated by
+L<C<sysread>|/sysread FILEHANDLE,SCALAR,LENGTH,OFFSET>,
+L<C<syswrite>|/syswrite FILEHANDLE,SCALAR,LENGTH,OFFSET>, or
+L<C<sysseek>|/sysseek FILEHANDLE,POSITION,WHENCE>. Those functions
+ignore the buffering, while L<C<tell>|/tell FILEHANDLE> does not.
=item telldir DIRHANDLE
X<telldir>
=for Pod::Functions get current seekpointer on a directory handle
-Returns the current position of the C<readdir> routines on DIRHANDLE.
-Value may be given to C<seekdir> to access a particular location in a
-directory. C<telldir> has the same caveats about possible directory
-compaction as the corresponding system library routine.
+Returns the current position of the L<C<readdir>|/readdir DIRHANDLE>
+routines on DIRHANDLE. Value may be given to
+L<C<seekdir>|/seekdir DIRHANDLE,POS> to access a particular location in
+a directory. L<C<telldir>|/telldir DIRHANDLE> has the same caveats
+about possible directory compaction as the corresponding system library
+routine.
=item tie VARIABLE,CLASSNAME,LIST
X<tie>
appropriate constructor
method of the class (meaning C<TIESCALAR>, C<TIEHANDLE>, C<TIEARRAY>,
or C<TIEHASH>). Typically these are arguments such as might be passed
-to the C<dbm_open()> function of C. The object returned by the
-constructor is also returned by the C<tie> function, which would be useful
+to the L<dbm_open(3)> function of C. The object returned by the
+constructor is also returned by the
+L<C<tie>|/tie VARIABLE,CLASSNAME,LIST> function, which would be useful
if you want to access other methods in CLASSNAME.
-Note that functions such as C<keys> and C<values> may return huge lists
-when used on large objects, like DBM files. You may prefer to use the
-C<each> function to iterate over such. Example:
+Note that functions such as L<C<keys>|/keys HASH> and
+L<C<values>|/values HASH> may return huge lists when used on large
+objects, like DBM files. You may prefer to use the L<C<each>|/each
+HASH> function to iterate over such. Example:
# print out history file offsets
use NDBM_File;
- tie(%HIST, 'NDBM_File', '/usr/lib/news/history', 1, 0);
- while (($key,$val) = each %HIST) {
- print $key, ' = ', unpack('L',$val), "\n";
+ tie(my %HIST, 'NDBM_File', '/usr/lib/news/history', 1, 0);
+ while (my ($key,$val) = each %HIST) {
+ print $key, ' = ', unpack('L', $val), "\n";
}
- untie(%HIST);
A class implementing a hash should have the following methods:
Not all methods indicated above need be implemented. See L<perltie>,
L<Tie::Hash>, L<Tie::Array>, L<Tie::Scalar>, and L<Tie::Handle>.
-Unlike C<dbmopen>, the C<tie> function will not C<use> or C<require> a module
-for you; you need to do that explicitly yourself. See L<DB_File>
-or the F<Config> module for interesting C<tie> implementations.
+Unlike L<C<dbmopen>|/dbmopen HASH,DBNAME,MASK>, the
+L<C<tie>|/tie VARIABLE,CLASSNAME,LIST> function will not
+L<C<use>|/use Module VERSION LIST> or L<C<require>|/require VERSION> a
+module for you; you need to do that explicitly yourself. See L<DB_File>
+or the L<Config> module for interesting
+L<C<tie>|/tie VARIABLE,CLASSNAME,LIST> implementations.
-For further details see L<perltie>, L<"tied VARIABLE">.
+For further details see L<perltie>, L<C<tied>|/tied VARIABLE>.
=item tied VARIABLE
X<tied>
=for Pod::Functions get a reference to the object underlying a tied variable
Returns a reference to the object underlying VARIABLE (the same value
-that was originally returned by the C<tie> call that bound the variable
+that was originally returned by the
+L<C<tie>|/tie VARIABLE,CLASSNAME,LIST> call that bound the variable
to a package.) Returns the undefined value if VARIABLE isn't tied to a
package.
=for Pod::Functions return number of seconds since 1970
Returns the number of non-leap seconds since whatever time the system
-considers to be the epoch, suitable for feeding to C<gmtime> and
-C<localtime>. On most systems the epoch is 00:00:00 UTC, January 1, 1970;
+considers to be the epoch, suitable for feeding to
+L<C<gmtime>|/gmtime EXPR> and L<C<localtime>|/localtime EXPR>. On most
+systems the epoch is 00:00:00 UTC, January 1, 1970;
a prominent exception being Mac OS Classic which uses 00:00:00, January 1,
1904 in the current local time zone for its epoch.
For measuring time in better granularity than one second, use the
L<Time::HiRes> module from Perl 5.8 onwards (or from CPAN before then), or,
-if you have gettimeofday(2), you may be able to use the C<syscall>
-interface of Perl. See L<perlfaq8> for details.
+if you have L<gettimeofday(2)>, you may be able to use the
+L<C<syscall>|/syscall NUMBER, LIST> interface of Perl. See L<perlfaq8>
+for details.
For date and time processing look at the many related modules on CPAN.
For a comprehensive date and time representation look at the
Returns a four-element list giving the user and system times in
seconds for this process and any exited children of this process.
- ($user,$system,$cuser,$csystem) = times;
+ my ($user,$system,$cuser,$csystem) = times;
-In scalar context, C<times> returns C<$user>.
+In scalar context, L<C<times>|/times> returns C<$user>.
Children's times are only included for terminated children.
=for Pod::Functions transliterate a string
-The transliteration operator. Same as C<y///>. See
+The transliteration operator. Same as
+L<C<yE<sol>E<sol>E<sol>>|/yE<sol>E<sol>E<sol>>. See
L<perlop/"Quote-Like Operators">.
=item truncate FILEHANDLE,LENGTH
Truncates the file opened on FILEHANDLE, or named by EXPR, to the
specified length. Raises an exception if truncate isn't implemented
-on your system. Returns true if successful, C<undef> on error.
+on your system. Returns true if successful, L<C<undef>|/undef EXPR> on
+error.
The behavior is undefined if LENGTH is greater than the length of the
file.
The position in the file of FILEHANDLE is left unchanged. You may want to
-call L<seek|/"seek FILEHANDLE,POSITION,WHENCE"> before writing to the file.
+call L<seek|/"seek FILEHANDLE,POSITION,WHENCE"> before writing to the
+file.
Portability issues: L<perlport/truncate>.
Returns an uppercased version of EXPR. This is the internal function
implementing the C<\U> escape in double-quoted strings.
It does not attempt to do titlecase mapping on initial letters. See
-L</ucfirst> for that.
+L<C<ucfirst>|/ucfirst EXPR> for that.
-If EXPR is omitted, uses C<$_>.
+If EXPR is omitted, uses L<C<$_>|perlvar/$_>.
-This function behaves the same way under various pragma, such as in a locale,
-as L</lc> does.
+This function behaves the same way under various pragmas, such as in a locale,
+as L<C<lc>|/lc EXPR> does.
=item ucfirst EXPR
X<ucfirst> X<uppercase>
(titlecase in Unicode). This is the internal function implementing
the C<\u> escape in double-quoted strings.
-If EXPR is omitted, uses C<$_>.
+If EXPR is omitted, uses L<C<$_>|perlvar/$_>.
-This function behaves the same way under various pragma, such as in a locale,
-as L</lc> does.
+This function behaves the same way under various pragmas, such as in a locale,
+as L<C<lc>|/lc EXPR> does.
=item umask EXPR
X<umask>
The Unix permission C<rwxr-x---> is represented as three sets of three
bits, or three octal digits: C<0750> (the leading 0 indicates octal
-and isn't one of the digits). The C<umask> value is such a number
-representing disabled permissions bits. The permission (or "mode")
-values you pass C<mkdir> or C<sysopen> are modified by your umask, so
-even if you tell C<sysopen> to create a file with permissions C<0777>,
-if your umask is C<0022>, then the file will actually be created with
-permissions C<0755>. If your C<umask> were C<0027> (group can't
-write; others can't read, write, or execute), then passing
-C<sysopen> C<0666> would create a file with mode C<0640> (because
-C<0666 &~ 027> is C<0640>).
+and isn't one of the digits). The L<C<umask>|/umask EXPR> value is such
+a number representing disabled permissions bits. The permission (or
+"mode") values you pass L<C<mkdir>|/mkdir FILENAME,MASK> or
+L<C<sysopen>|/sysopen FILEHANDLE,FILENAME,MODE> are modified by your
+umask, so even if you tell
+L<C<sysopen>|/sysopen FILEHANDLE,FILENAME,MODE> to create a file with
+permissions C<0777>, if your umask is C<0022>, then the file will
+actually be created with permissions C<0755>. If your
+L<C<umask>|/umask EXPR> were C<0027> (group can't write; others can't
+read, write, or execute), then passing
+L<C<sysopen>|/sysopen FILEHANDLE,FILENAME,MODE> C<0666> would create a
+file with mode C<0640> (because C<0666 &~ 027> is C<0640>).
Here's some advice: supply a creation mode of C<0666> for regular
-files (in C<sysopen>) and one of C<0777> for directories (in
-C<mkdir>) and executable files. This gives users the freedom of
+files (in L<C<sysopen>|/sysopen FILEHANDLE,FILENAME,MODE>) and one of
+C<0777> for directories (in L<C<mkdir>|/mkdir FILENAME,MASK>) and
+executable files. This gives users the freedom of
choice: if they want protected files, they might choose process umasks
of C<022>, C<027>, or even the particularly antisocial mask of C<077>.
Programs should rarely if ever make policy decisions better left to
the user. The exception to this is when writing files that should be
-kept private: mail files, web browser cookies, I<.rhosts> files, and
+kept private: mail files, web browser cookies, F<.rhosts> files, and
so on.
-If umask(2) is not implemented on your system and you are trying to
-restrict access for I<yourself> (i.e., C<< (EXPR & 0700) > 0 >>),
-raises an exception. If umask(2) is not implemented and you are
-not trying to restrict access for yourself, returns C<undef>.
+If L<umask(2)> is not implemented on your system and you are trying to
+restrict access for I<yourself> (i.e., C<< (EXPR & 0700) > 0 >>),
+raises an exception. If L<umask(2)> is not implemented and you are
+not trying to restrict access for yourself, returns
+L<C<undef>|/undef EXPR>.
Remember that a umask is a number, usually given in octal; it is I<not> a
-string of octal digits. See also L</oct>, if all you have is a string.
+string of octal digits. See also L<C<oct>|/oct EXPR>, if all you have
+is a string.
Portability issues: L<perlport/umask>.
scalar value, an array (using C<@>), a hash (using C<%>), a subroutine
(using C<&>), or a typeglob (using C<*>). Saying C<undef $hash{$key}>
will probably not do what you expect on most predefined variables or
-DBM list values, so don't do that; see L</delete>. Always returns the
-undefined value. You can omit the EXPR, in which case nothing is
+DBM list values, so don't do that; see L<C<delete>|/delete EXPR>.
+Always returns the undefined value.
+You can omit the EXPR, in which case nothing is
undefined, but you still get an undefined value that you could, for
instance, return from a subroutine, assign to a variable, or pass as a
parameter. Examples:
undef *xyz; # destroys $xyz, @xyz, %xyz, &xyz, etc.
return (wantarray ? (undef, $errmsg) : undef) if $they_blew_it;
select undef, undef, undef, 0.25;
- ($a, $b, undef, $c) = &foo; # Ignore third value returned
+ my ($x, $y, undef, $z) = foo(); # Ignore third value returned
Note that this is a unary operator, not a list operator.
=for Pod::Functions remove one link to a file
Deletes a list of files. On success, it returns the number of files
-it successfully deleted. On failure, it returns false and sets C<$!>
-(errno):
+it successfully deleted. On failure, it returns false and sets
+L<C<$!>|perlvar/$!> (errno):
my $unlinked = unlink 'a', 'b', 'c';
unlink @goners;
unlink glob "*.bak";
-On error, C<unlink> will not tell you which files it could not remove.
+On error, L<C<unlink>|/unlink LIST> will not tell you which files it
+could not remove.
If you want to know which files you could not remove, try them one
at a time:
unlink $file or warn "Could not unlink $file: $!";
}
-Note: C<unlink> will not attempt to delete directories unless you are
+Note: L<C<unlink>|/unlink LIST> will not attempt to delete directories
+unless you are
superuser and the B<-U> flag is supplied to Perl. Even if these
conditions are met, be warned that unlinking a directory can inflict
-damage on your filesystem. Finally, using C<unlink> on directories is
-not supported on many operating systems. Use C<rmdir> instead.
+damage on your filesystem. Finally, using L<C<unlink>|/unlink LIST> on
+directories is not supported on many operating systems. Use
+L<C<rmdir>|/rmdir FILENAME> instead.
-If LIST is omitted, C<unlink> uses C<$_>.
+If LIST is omitted, L<C<unlink>|/unlink LIST> uses L<C<$_>|perlvar/$_>.
=item unpack TEMPLATE,EXPR
X<unpack>
=for Pod::Functions convert binary structure into normal perl variables
-C<unpack> does the reverse of C<pack>: it takes a string
+L<C<unpack>|/unpack TEMPLATE,EXPR> does the reverse of
+L<C<pack>|/pack TEMPLATE,LIST>: it takes a string
and expands it out into a list of values.
(In scalar context, it returns merely the first value produced.)
-If EXPR is omitted, unpacks the C<$_> string.
+If EXPR is omitted, unpacks the L<C<$_>|perlvar/$_> string.
See L<perlpacktut> for an introduction to this function.
The string is broken into chunks described by the TEMPLATE. Each chunk
is converted separately to a value. Typically, either the string is a result
-of C<pack>, or the characters of the string represent a C structure of some
-kind.
+of L<C<pack>|/pack TEMPLATE,LIST>, or the characters of the string
+represent a C structure of some kind.
-The TEMPLATE has the same format as in the C<pack> function.
+The TEMPLATE has the same format as in the
+L<C<pack>|/pack TEMPLATE,LIST> function.
Here's a subroutine that does substring:
sub substr {
- my($what,$where,$howmuch) = @_;
+ my ($what, $where, $howmuch) = @_;
unpack("x$where a$howmuch", $what);
}
sub ordinal { unpack("W",$_[0]); } # same as ord()
-In addition to fields allowed in pack(), you may prefix a field with
-a %<number> to indicate that
+In addition to fields allowed in L<C<pack>|/pack TEMPLATE,LIST>, you may
+prefix a field with a %<number> to indicate that
you want a <number>-bit checksum of the items instead of the items
-themselves. Default is a 16-bit checksum. Checksum is calculated by
+themselves. Default is a 16-bit checksum. The checksum is calculated by
summing numeric values of expanded values (for string fields the sum of
C<ord($char)> is taken; for bit fields the sum of zeroes and ones).
For example, the following
computes the same number as the System V sum program:
- $checksum = do {
+ my $checksum = do {
local $/; # slurp!
- unpack("%32W*",<>) % 65535;
+ unpack("%32W*", readline) % 65535;
};
The following efficiently counts the number of set bits in a bit vector:
- $setbits = unpack("%32b*", $selectmask);
+ my $setbits = unpack("%32b*", $selectmask);
The C<p> and C<P> formats should be used with care. Since Perl
-has no way of checking whether the value passed to C<unpack()>
+has no way of checking whether the value passed to
+L<C<unpack>|/unpack TEMPLATE,EXPR>
corresponds to a valid memory location, passing a pointer value that's
not known to be valid is likely to have disastrous consequences.
If there are more pack codes or if the repeat count of a field or a group
is larger than what the remainder of the input string allows, the result
is not well defined: the repeat count may be decreased, or
-C<unpack()> may produce empty strings or zeros, or it may raise an exception.
+L<C<unpack>|/unpack TEMPLATE,EXPR> may produce empty strings or zeros,
+or it may raise an exception.
If the input string is longer than one described by the TEMPLATE,
the remainder of that input string is ignored.
-See L</pack> for more examples and notes.
+See L<C<pack>|/pack TEMPLATE,LIST> for more examples and notes.
=item unshift ARRAY,LIST
X<unshift>
=for Pod::Functions prepend more elements to the beginning of a list
-Does the opposite of a C<shift>. Or the opposite of a C<push>,
+Does the opposite of a L<C<shift>|/shift ARRAY>. Or the opposite of a
+L<C<push>|/push ARRAY,LIST>,
depending on how you look at it. Prepends list to the front of the
array and returns the new number of elements in the array.
unshift(@ARGV, '-e') unless $ARGV[0] =~ /^-/;
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.
+prepended elements stay in the same order. Use
+L<C<reverse>|/reverse LIST> to do the reverse.
-Starting with Perl 5.14, an experimental feature allowed C<unshift> to take
+Starting with Perl 5.14, an experimental feature allowed
+L<C<unshift>|/unshift ARRAY,LIST> to take
a scalar expression. This experiment has been deemed unsuccessful, and was
removed as of Perl 5.24.
The importation can be made conditional by using the L<if> module.
In the peculiar C<use VERSION> form, VERSION may be either a positive
-decimal fraction such as 5.006, which will be compared to C<$]>, or a v-string
-of the form v5.6.1, which will be compared to C<$^V> (aka $PERL_VERSION). An
+decimal fraction such as 5.006, which will be compared to
+L<C<$]>|perlvar/$]>, or a v-string of the form v5.6.1, which will be
+compared to L<C<$^V>|perlvar/$^V> (aka $PERL_VERSION). An
exception is raised if VERSION is greater than the version of the
current Perl interpreter; Perl will not attempt to parse the rest of the
-file. Compare with L</require>, which can do a similar check at run time.
+file. Compare with L<C<require>|/require VERSION>, which can do a
+similar check at run time.
Symmetrically, C<no VERSION> allows you to specify that you want a version
of Perl older than the specified one.
use 5.006_001; # ditto; preferred for backwards compatibility
This is often useful if you need to check the current Perl version before
-C<use>ing library modules that won't work with older versions of Perl.
+L<C<use>|/use Module VERSION LIST>ing library modules that won't work
+with older versions of Perl.
(We try not to do this more than we have to.)
C<use VERSION> also lexically enables all features available in the requested
-version as defined by the C<feature> pragma, disabling any features
+version as defined by the L<feature> pragma, disabling any features
not in the requested version's feature bundle. See L<feature>.
Similarly, if the specified Perl version is greater than or equal to
5.12.0, strictures are enabled lexically as
-with C<use strict>. Any explicit use of
+with L<C<use strict>|strict>. Any explicit use of
C<use strict> or C<no strict> overrides C<use VERSION>, even if it comes
before it. Later use of C<use VERSION>
will override all behavior of a previous
load the F<feature.pm> or F<strict.pm>
files.
-The C<BEGIN> forces the C<require> and C<import> to happen at compile time. The
-C<require> makes sure the module is loaded into memory if it hasn't been
-yet. The C<import> is not a builtin; it's just an ordinary static method
+The C<BEGIN> forces the L<C<require>|/require VERSION> and
+L<C<import>|/import LIST> to happen at compile time. The
+L<C<require>|/require VERSION> makes sure the module is loaded into
+memory if it hasn't been yet. The L<C<import>|/import LIST> is not a
+builtin; it's just an ordinary static method
call into the C<Module> package to tell the module to import the list of
features back into the current package. The module can implement its
-C<import> method any way it likes, though most modules just choose to
-derive their C<import> method via inheritance from the C<Exporter> class that
-is defined in the C<Exporter> module. See L<Exporter>. If no C<import>
-method can be found then the call is skipped, even if there is an AUTOLOAD
-method.
-
-If you do not want to call the package's C<import> method (for instance,
+L<C<import>|/import LIST> method any way it likes, though most modules
+just choose to derive their L<C<import>|/import LIST> method via
+inheritance from the C<Exporter> class that is defined in the
+L<C<Exporter>|Exporter> module. See L<Exporter>. If no
+L<C<import>|/import LIST> method can be found, then the call is skipped,
+even if there is an AUTOLOAD method.
+
+If you do not want to call the package's L<C<import>|/import LIST>
+method (for instance,
to stop your namespace from being altered), explicitly supply the empty list:
use Module ();
BEGIN { require Module }
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>.
+L<C<use>|/use Module VERSION LIST> will call the C<VERSION> method in
+class Module with the given version as an argument:
+
+ use Module 12.34;
+
+is equivalent to:
-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!
+ BEGIN { require Module; Module->VERSION(12.34) }
+
+The L<default C<VERSION> method|UNIVERSAL/C<VERSION ( [ REQUIRE ] )>>,
+inherited from the L<C<UNIVERSAL>|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 (L<C<import>|/import
+LIST> called with no arguments) and an explicit empty LIST C<()>
+(L<C<import>|/import LIST> 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:
+are also implemented this way. Some of the currently implemented
+pragmas are:
use constant;
use diagnostics;
use sort qw(stable _quicksort _mergesort);
Some of these pseudo-modules import semantics into the current
-block scope (like C<strict> or C<integer>, unlike ordinary modules,
-which import symbols into the current package (which are effective
-through the end of the file).
-
-Because C<use> takes effect at compile time, it doesn't respect the
-ordinary flow control of the code being compiled. In particular, putting
-a C<use> inside the false branch of a conditional doesn't prevent it
-from being processed. If a module or pragma only needs to be loaded
+block scope (like L<C<strict>|strict> or L<C<integer>|integer>, unlike
+ordinary modules, which import symbols into the current package (which
+are effective through the end of the file).
+
+Because L<C<use>|/use Module VERSION LIST> takes effect at compile time,
+it doesn't respect the ordinary flow control of the code being compiled.
+In particular, putting a L<C<use>|/use Module VERSION LIST> inside the
+false branch of a conditional doesn't prevent it
+from being processed. If a module or pragma only needs to be loaded
conditionally, this can be done using the L<if> pragma:
use if $] < 5.008, "utf8";
use if WANT_WARNINGS, warnings => qw(all);
-There's a corresponding C<no> declaration that unimports meanings imported
-by C<use>, i.e., it calls C<unimport Module LIST> instead of C<import>.
-It behaves just as C<import> does with VERSION, an omitted or empty LIST,
+There's a corresponding L<C<no>|/no MODULE VERSION LIST> declaration
+that unimports meanings imported by L<C<use>|/use Module VERSION LIST>,
+i.e., it calls C<< Module->unimport(LIST) >> instead of
+L<C<import>|/import LIST>. It behaves just as L<C<import>|/import LIST>
+does with VERSION, an omitted or empty LIST,
or no unimport method being found.
no integer;
no strict 'refs';
no warnings;
-Care should be taken when using the C<no VERSION> form of C<no>. It is
+Care should be taken when using the C<no VERSION> form of L<C<no>|/no
+MODULE VERSION LIST>. It is
I<only> meant to be used to assert that the running Perl is of a earlier
version than its argument and I<not> to undo the feature-enabling side effects
of C<use VERSION>.
See L<perlmodlib> for a list of standard modules and pragmas. See L<perlrun>
-for the C<-M> and C<-m> command-line options to Perl that give C<use>
-functionality from the command-line.
+for the C<-M> and C<-m> command-line options to Perl that give
+L<C<use>|/use Module VERSION LIST> functionality from the command-line.
=item utime LIST
X<utime>
and modification times, in that order. Returns the number of files
successfully changed. The inode change time of each file is set
to the current time. For example, this code has the same effect as the
-Unix touch(1) command when the files I<already exist> and belong to
+Unix L<touch(1)> command when the files I<already exist> and belong to
the user running the program:
#!/usr/bin/perl
- $atime = $mtime = time;
+ my $atime = my $mtime = time;
utime $atime, $mtime, @ARGV;
-Since Perl 5.8.0, if the first two elements of the list are C<undef>,
-the utime(2) syscall from your C library is called with a null second
+Since Perl 5.8.0, if the first two elements of the list are
+L<C<undef>|/undef EXPR>,
+the L<utime(2)> syscall from your C library is called with a null second
argument. On most systems, this will set the file's access and
modification times to the current time (i.e., equivalent to the example
above) and will work even on files you don't own provided you have write
permission:
- for $file (@ARGV) {
- utime(undef, undef, $file)
- || warn "couldn't touch $file: $!";
- }
+ for my $file (@ARGV) {
+ utime(undef, undef, $file)
+ || warn "Couldn't touch $file: $!";
+ }
Under NFS this will use the time of the NFS server, not the time of
the local machine. If there is a time synchronization problem, the
NFS server and local machine will have different times. The Unix
-touch(1) command will in fact normally use this form instead of the
+L<touch(1)> command will in fact normally use this form instead of the
one shown in the first example.
-Passing only one of the first two elements as C<undef> is
-equivalent to passing a 0 and will not have the effect
-described when both are C<undef>. This also triggers an
+Passing only one of the first two elements as L<C<undef>|/undef EXPR> is
+equivalent to passing a 0 and will not have the effect described when
+both are L<C<undef>|/undef EXPR>. This also triggers an
uninitialized warning.
-On systems that support futimes(2), you may pass filehandles among the
-files. On systems that don't support futimes(2), passing filehandles raises
+On systems that support L<futimes(2)>, you may pass filehandles among the
+files. On systems that don't support L<futimes(2)>, passing filehandles raises
an exception. Filehandles must be passed as globs or glob references to be
recognized; barewords are considered filenames.
order is specific to a given hash; the exact same series of operations
on two hashes may result in a different order for each hash. Any insertion
into the hash may change the order, as will any deletion, with the exception
-that the most recent key returned by C<each> or C<keys> may be deleted
-without changing the order. So long as a given hash is unmodified you may
-rely on C<keys>, C<values> and C<each> to repeatedly return the same order
+that the most recent key returned by L<C<each>|/each HASH> or
+L<C<keys>|/keys HASH> may be deleted without changing the order. So
+long as a given hash is unmodified you may rely on
+L<C<keys>|/keys HASH>, L<C<values>|/values HASH> and
+L<C<each>|/each HASH> to repeatedly return the same order
as each other. See L<perlsec/"Algorithmic Complexity Attacks"> for
details on why hash order is randomized. Aside from the guarantees
provided here the exact details of Perl's hash algorithm and the hash
may behave differently to Perl's hashes with respect to changes in order on
insertion and deletion of items.
-As a side effect, calling values() resets the HASH or ARRAY's internal
-iterator, see L</each>. (In particular, calling values() in void context
-resets the iterator with no other overhead. Apart from resetting the
-iterator, C<values @array> in list context is the same as plain C<@array>.
+As a side effect, calling L<C<values>|/values HASH> resets the HASH or
+ARRAY's internal iterator, see L<C<each>|/each HASH>. (In particular,
+calling L<C<values>|/values HASH> in void context resets the iterator
+with no other overhead. Apart from resetting the iterator,
+C<values @array> in list context is the same as plain C<@array>.
(We recommend that you use void context C<keys @array> for this, but
reasoned that taking C<values @array> out would require more
documentation than leaving it in.)
for (values %hash) { s/foo/bar/g } # modifies %hash values
for (@hash{keys %hash}) { s/foo/bar/g } # same
-Starting with Perl 5.14, an experimental feature allowed C<values> to take a
+Starting with Perl 5.14, an experimental feature allowed
+L<C<values>|/values HASH> to take a
scalar expression. This experiment has been deemed unsuccessful, and was
removed as of Perl 5.24.
use 5.012; # so keys/values/each work on arrays
-See also C<keys>, C<each>, and C<sort>.
+See also L<C<keys>|/keys HASH>, L<C<each>|/each HASH>, and
+L<C<sort>|/sort SUBNAME LIST>.
=item vec EXPR,OFFSET,BITS
X<vec> X<bit> X<bit vector>
If BITS is 16 or more, bytes of the input string are grouped into chunks
of size BITS/8, and each group is converted to a number as with
-pack()/unpack() with big-endian formats C<n>/C<N> (and analogously
-for BITS==64). See L<"pack"> for details.
+L<C<pack>|/pack TEMPLATE,LIST>/L<C<unpack>|/unpack TEMPLATE,EXPR> with
+big-endian formats C<n>/C<N> (and analogously for BITS==64). See
+L<C<pack>|/pack TEMPLATE,LIST> for details.
If bits is 4 or less, the string is broken into bytes, then the bits
of each byte are broken into 8/BITS groups. Bits of a byte are
breaking the single input byte C<chr(0x36)> into two groups gives a list
C<(0x6, 0x3)>; breaking it into 4 groups gives C<(0x2, 0x1, 0x3, 0x0)>.
-C<vec> may also be assigned to, in which case parentheses are needed
+L<C<vec>|/vec EXPR,OFFSET,BITS> may also be assigned to, in which case
+parentheses are needed
to give the expression the correct precedence as in
vec($image, $max_x * $x + $y, 8) = 3;
to try to write off the beginning of the string (i.e., negative OFFSET).
If the string happens to be encoded as UTF-8 internally (and thus has
-the UTF8 flag set), this is ignored by C<vec>, and it operates on the
+the UTF8 flag set), this is ignored by L<C<vec>|/vec EXPR,OFFSET,BITS>,
+and it operates on the
internal byte string, not the conceptual character string, even if you
-only have characters with values less than 256.
+only have characters with values less than 256.
-Strings created with C<vec> can also be manipulated with the logical
+Strings created with L<C<vec>|/vec EXPR,OFFSET,BITS> can also be
+manipulated with the logical
operators C<|>, C<&>, C<^>, and C<~>. These operators will assume a bit
vector operation is desired when both operands are strings.
See L<perlop/"Bitwise String Operators">.
To transform a bit vector into a string or list of 0's and 1's, use these:
- $bits = unpack("b*", $vector);
- @bits = split(//, unpack("b*", $vector));
+ my $bits = unpack("b*", $vector);
+ my @bits = split(//, unpack("b*", $vector));
If you know the exact length in bits, it can be used in place of the C<*>.
.
__END__
-Regardless of the machine architecture on which it runs, the
+Regardless of the machine architecture on which it runs, the
example above should print the following table:
0 1 2 3
=for Pod::Functions wait for any child process to die
-Behaves like wait(2) on your system: it waits for a child
+Behaves like L<wait(2)> on your system: it waits for a child
process to terminate and returns the pid of the deceased process, or
-C<-1> if there are no child processes. The status is returned in C<$?>
-and C<${^CHILD_ERROR_NATIVE}>.
+C<-1> if there are no child processes. The status is returned in
+L<C<$?>|perlvar/$?> and
+L<C<${^CHILD_ERROR_NATIVE}>|perlvar/${^CHILD_ERROR_NATIVE}>.
Note that a return value of C<-1> could mean that child processes are
being automatically reaped, as described in L<perlipc>.
-If you use C<wait> in your handler for $SIG{CHLD}, it may accidentally wait
-for the child created by qx() or system(). See L<perlipc> for details.
+If you use L<C<wait>|/wait> in your handler for
+L<C<$SIG{CHLD}>|perlvar/%SIG>, it may accidentally wait for the child
+created by L<C<qx>|/qxE<sol>STRINGE<sol>> or L<C<system>|/system LIST>.
+See L<perlipc> for details.
Portability issues: L<perlport/wait>.
Waits for a particular child process to terminate and returns the pid of
the deceased process, or C<-1> if there is no such child process. A
-non-blocking wait (with L<WNOHANG|POSIX/WNOHANG> in FLAGS) can return 0 if
+non-blocking wait (with L<WNOHANG|POSIX/C<WNOHANG>> in FLAGS) can return 0 if
there are child processes matching PID but none have terminated yet.
-The status is returned in C<$?> and C<${^CHILD_ERROR_NATIVE}>.
+The status is returned in L<C<$?>|perlvar/$?> and
+L<C<${^CHILD_ERROR_NATIVE}>|perlvar/${^CHILD_ERROR_NATIVE}>.
A PID of C<0> indicates to wait for any child process whose process group ID is
equal to that of the current process. A PID of less than C<-1> indicates to
If you say
use POSIX ":sys_wait_h";
- #...
+
+ my $kid;
do {
$kid = waitpid(-1, WNOHANG);
} while $kid > 0;
+or
+
+ 1 while waitpid(-1, WNOHANG) > 0;
+
then you can do a non-blocking wait for all pending zombie processes (see
L<POSIX/WAIT>).
Non-blocking wait is available on machines supporting either the
-waitpid(2) or wait4(2) syscalls. However, waiting for a particular
+L<waitpid(2)> or L<wait4(2)> syscalls. However, waiting for a particular
pid with FLAGS of C<0> is implemented everywhere. (Perl emulates the
system call by remembering the status values of processes that have
exited but have not been harvested by the Perl script yet.)
=for Pod::Functions get void vs scalar vs list context of current subroutine call
Returns true if the context of the currently executing subroutine or
-C<eval> is looking for a list value. Returns false if the context is
+L<C<eval>|/eval EXPR> is looking for a list value. Returns false if the
+context is
looking for a scalar. Returns the undefined value if the context is
looking for no value (void context).
my @a = complex_calculation();
return wantarray ? @a : "@a";
-C<wantarray()>'s result is unspecified in the top level of a file,
+L<C<wantarray>|/wantarray>'s result is unspecified in the top level of a file,
in a C<BEGIN>, C<UNITCHECK>, C<CHECK>, C<INIT> or C<END> block, or
in a C<DESTROY> method.
=for Pod::Functions print debugging info
Prints the value of LIST to STDERR. If the last element of LIST does
-not end in a newline, it appends the same file/line number text as C<die>
-does.
+not end in a newline, it appends the same file/line number text as
+L<C<die>|/die LIST> does.
-If the output is empty and C<$@> already contains a value (typically from a
-previous eval) that value is used after appending C<"\t...caught">
-to C<$@>. This is useful for staying almost, but not entirely similar to
-C<die>.
+If the output is empty and L<C<$@>|perlvar/$@> already contains a value
+(typically from a previous eval) that value is used after appending
+C<"\t...caught"> to L<C<$@>|perlvar/$@>. This is useful for staying
+almost, but not entirely similar to L<C<die>|/die LIST>.
-If C<$@> is empty then the string C<"Warning: Something's wrong"> is used.
+If L<C<$@>|perlvar/$@> is empty, then the string
+C<"Warning: Something's wrong"> is used.
-No message is printed if there is a C<$SIG{__WARN__}> handler
+No message is printed if there is a L<C<$SIG{__WARN__}>|perlvar/%SIG>
+handler
installed. It is the handler's responsibility to deal with the message
-as it sees fit (like, for instance, converting it into a C<die>). Most
+as it sees fit (like, for instance, converting it into a
+L<C<die>|/die LIST>). Most
handlers must therefore arrange to actually display the
-warnings that they are not prepared to deal with, by calling C<warn>
+warnings that they are not prepared to deal with, by calling
+L<C<warn>|/warn LIST>
again in the handler. Note that this is quite safe and will not
produce an endless loop, since C<__WARN__> hooks are not called from
inside one.
You will find this behavior is slightly different from that of
-C<$SIG{__DIE__}> handlers (which don't suppress the error text, but can
-instead call C<die> again to change it).
+L<C<$SIG{__DIE__}>|perlvar/%SIG> handlers (which don't suppress the
+error text, but can instead call L<C<die>|/die LIST> again to change
+it).
Using a C<__WARN__> handler provides a powerful way to silence all
warnings (even the so-called mandatory ones). An example:
# run-time warnings enabled after here
warn "\$foo is alive and $foo!"; # does show up
-See L<perlvar> for details on setting C<%SIG> entries and for more
-examples. See the Carp module for other kinds of warnings using its
-carp() and cluck() functions.
+See L<perlvar> for details on setting L<C<%SIG>|perlvar/%SIG> entries
+and for more
+examples. See the L<Carp> module for other kinds of warnings using its
+C<carp> and C<cluck> functions.
=item write FILEHANDLE
X<write>
Writes a formatted record (possibly multi-line) to the specified FILEHANDLE,
using the format associated with that file. By default the format for
a file is the one having the same name as the filehandle, but the
-format for the current output channel (see the C<select> function) may be set
-explicitly by assigning the name of the format to the C<$~> variable.
+format for the current output channel (see the
+L<C<select>|/select FILEHANDLE> function) may be set explicitly by
+assigning the name of the format to the L<C<$~>|perlvar/$~> variable.
Top of form processing is handled automatically: if there is insufficient
room on the current page for the formatted record, the page is advanced by
writing a form feed and a special top-of-page
format is used to format the new
page header before the record is written. By default, the top-of-page
-format is the name of the filehandle with "_TOP" appended, or "top"
+format is the name of the filehandle with C<_TOP> appended, or C<top>
in the current package if the former does not exist. This would be a
problem with autovivified filehandles, but it may be dynamically set to the
-format of your choice by assigning the name to the C<$^> variable while
-that filehandle is selected. The number of lines remaining on the current
-page is in variable C<$->, which can be set to C<0> to force a new page.
+format of your choice by assigning the name to the L<C<$^>|perlvar/$^>
+variable while that filehandle is selected. The number of lines
+remaining on the current page is in variable L<C<$->|perlvar/$->, which
+can be set to C<0> to force a new page.
If FILEHANDLE is unspecified, output goes to the current default output
channel, which starts out as STDOUT but may be changed by the
-C<select> operator. If the FILEHANDLE is an EXPR, then the expression
+L<C<select>|/select FILEHANDLE> operator. If the FILEHANDLE is an EXPR,
+then the expression
is evaluated and the resulting string is used to look up the name of
the FILEHANDLE at run time. For more on formats, see L<perlform>.
-Note that write is I<not> the opposite of C<read>. Unfortunately.
+Note that write is I<not> the opposite of
+L<C<read>|/read FILEHANDLE,SCALAR,LENGTH,OFFSET>. Unfortunately.
=item y///
=for Pod::Functions transliterate a string
-The transliteration operator. Same as C<tr///>. See
+The transliteration operator. Same as
+L<C<trE<sol>E<sol>E<sol>>|/trE<sol>E<sol>E<sol>>. See
L<perlop/"Quote-Like Operators">.
=back
Notice here the LEN is 10. (It may differ on your platform.) Extend the
length of the string to one less than 10, and do a substitution:
- % ./perl -Ilib -MDevel::Peek -le '$a=""; $a.="123456789"; $a=~s/.//; Dump($a)'
- SV = PV(0x7ffa04008a70) at 0x7ffa04030390
- REFCNT = 1
- FLAGS = (POK,OOK,pPOK)
- OFFSET = 1
- PV = 0x7ffa03c05b61 ( "\1" . ) "23456789"\0
- CUR = 8
- LEN = 9
+ % ./perl -Ilib -MDevel::Peek -le '$a=""; $a.="123456789"; $a=~s/.//; \
+ Dump($a)'
+ SV = PV(0x7ffa04008a70) at 0x7ffa04030390
+ REFCNT = 1
+ FLAGS = (POK,OOK,pPOK)
+ OFFSET = 1
+ PV = 0x7ffa03c05b61 ( "\1" . ) "23456789"\0
+ CUR = 8
+ LEN = 9
Here the number of bytes chopped off (1) is shown next as the OFFSET. The
portion of the string between the "real" and the "fake" beginnings is
=item C<SAVEFREESV(SV *sv)>
-The refcount of C<sv> would be decremented at the end of
+The refcount of C<sv> will be decremented at the end of
I<pseudo-block>. This is similar to C<sv_2mortal> in that it is also a
mechanism for doing a delayed C<SvREFCNT_dec>. However, while C<sv_2mortal>
extends the lifetime of C<sv> until the beginning of the next statement,
David G 5.23.6 2015-Dec-21
Stevan 5.23.7 2016-Jan-20
Sawyer X 5.23.8 2016-Feb-20
+ Abigail 5.23.9 2016-Mar-20
=head2 SELECTED RELEASE SIZES
fixed, and are defined by the C<PerlIO_funcs> type. They are broadly the
same as the public C<PerlIO_xxxxx> functions:
- struct _PerlIO_funcs
- {
- Size_t fsize;
- char * name;
- Size_t size;
- IV kind;
- IV (*Pushed)(pTHX_ PerlIO *f,const char *mode,SV *arg, PerlIO_funcs *tab);
- IV (*Popped)(pTHX_ PerlIO *f);
- PerlIO * (*Open)(pTHX_ PerlIO_funcs *tab,
- PerlIO_list_t *layers, IV n,
- const char *mode,
- int fd, int imode, int perm,
- PerlIO *old,
- int narg, SV **args);
- IV (*Binmode)(pTHX_ PerlIO *f);
- SV * (*Getarg)(pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags)
- IV (*Fileno)(pTHX_ PerlIO *f);
- PerlIO * (*Dup)(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
- /* Unix-like functions - cf sfio line disciplines */
- SSize_t (*Read)(pTHX_ PerlIO *f, void *vbuf, Size_t count);
- SSize_t (*Unread)(pTHX_ PerlIO *f, const void *vbuf, Size_t count);
- SSize_t (*Write)(pTHX_ PerlIO *f, const void *vbuf, Size_t count);
- IV (*Seek)(pTHX_ PerlIO *f, Off_t offset, int whence);
- Off_t (*Tell)(pTHX_ PerlIO *f);
- IV (*Close)(pTHX_ PerlIO *f);
- /* Stdio-like buffered IO functions */
- IV (*Flush)(pTHX_ PerlIO *f);
- IV (*Fill)(pTHX_ PerlIO *f);
- IV (*Eof)(pTHX_ PerlIO *f);
- IV (*Error)(pTHX_ PerlIO *f);
- void (*Clearerr)(pTHX_ PerlIO *f);
- void (*Setlinebuf)(pTHX_ PerlIO *f);
- /* Perl's snooping functions */
- STDCHAR * (*Get_base)(pTHX_ PerlIO *f);
- Size_t (*Get_bufsiz)(pTHX_ PerlIO *f);
- STDCHAR * (*Get_ptr)(pTHX_ PerlIO *f);
- SSize_t (*Get_cnt)(pTHX_ PerlIO *f);
- void (*Set_ptrcnt)(pTHX_ PerlIO *f,STDCHAR *ptr,SSize_t cnt);
- };
+ struct _PerlIO_funcs
+ {
+ Size_t fsize;
+ char * name;
+ Size_t size;
+ IV kind;
+ IV (*Pushed)(pTHX_ PerlIO *f,
+ const char *mode,
+ SV *arg,
+ PerlIO_funcs *tab);
+ IV (*Popped)(pTHX_ PerlIO *f);
+ PerlIO * (*Open)(pTHX_ PerlIO_funcs *tab,
+ PerlIO_list_t *layers, IV n,
+ const char *mode,
+ int fd, int imode, int perm,
+ PerlIO *old,
+ int narg, SV **args);
+ IV (*Binmode)(pTHX_ PerlIO *f);
+ SV * (*Getarg)(pTHX_ PerlIO *f, CLONE_PARAMS *param, int flags)
+ IV (*Fileno)(pTHX_ PerlIO *f);
+ PerlIO * (*Dup)(pTHX_ PerlIO *f,
+ PerlIO *o,
+ CLONE_PARAMS *param,
+ int flags)
+ /* Unix-like functions - cf sfio line disciplines */
+ SSize_t (*Read)(pTHX_ PerlIO *f, void *vbuf, Size_t count);
+ SSize_t (*Unread)(pTHX_ PerlIO *f, const void *vbuf, Size_t count);
+ SSize_t (*Write)(pTHX_ PerlIO *f, const void *vbuf, Size_t count);
+ IV (*Seek)(pTHX_ PerlIO *f, Off_t offset, int whence);
+ Off_t (*Tell)(pTHX_ PerlIO *f);
+ IV (*Close)(pTHX_ PerlIO *f);
+ /* Stdio-like buffered IO functions */
+ IV (*Flush)(pTHX_ PerlIO *f);
+ IV (*Fill)(pTHX_ PerlIO *f);
+ IV (*Eof)(pTHX_ PerlIO *f);
+ IV (*Error)(pTHX_ PerlIO *f);
+ void (*Clearerr)(pTHX_ PerlIO *f);
+ void (*Setlinebuf)(pTHX_ PerlIO *f);
+ /* Perl's snooping functions */
+ STDCHAR * (*Get_base)(pTHX_ PerlIO *f);
+ Size_t (*Get_bufsiz)(pTHX_ PerlIO *f);
+ STDCHAR * (*Get_ptr)(pTHX_ PerlIO *f);
+ SSize_t (*Get_cnt)(pTHX_ PerlIO *f);
+ void (*Set_ptrcnt)(pTHX_ PerlIO *f,STDCHAR *ptr,SSize_t cnt);
+ };
The first few members of the struct give a function table size for
compatibility check "name" for the layer, the size to C<malloc> for the per-instance data,
=item Pushed
- IV (*Pushed)(pTHX_ PerlIO *f,const char *mode, SV *arg);
+ IV (*Pushed)(pTHX_ PerlIO *f,const char *mode, SV *arg);
The only absolutely mandatory method. Called when the layer is pushed
onto the stack. The C<mode> argument may be NULL if this occurs
Unread PerlIOBase_unread
Write FAILURE
- FAILURE Set errno (to EINVAL in Unixish, to LIB$_INVARG in VMS) and
- return -1 (for numeric return values) or NULL (for pointers)
+ FAILURE Set errno (to EINVAL in Unixish, to LIB$_INVARG in VMS)
+ and return -1 (for numeric return values) or NULL (for
+ pointers)
INHERITED Inherited from the layer below
SUCCESS Return 0 (for numeric return values) or a pointer
try something like the following:
- use POSIX qw(SIGALRM);
- POSIX::sigaction(SIGALRM, POSIX::SigAction->new(sub { die "alarm" }))
+ use POSIX qw(SIGALRM);
+ POSIX::sigaction(SIGALRM,
+ POSIX::SigAction->new(sub { die "alarm" }))
|| die "Error setting SIGALRM handler: $!\n";
Another way to disable the safe signal behavior locally is to use
standard file descriptors from and to F</dev/null> so that random
output doesn't wind up on the user's terminal.
- use POSIX "setsid";
+ use POSIX "setsid";
- sub daemonize {
- chdir("/") || die "can't chdir to /: $!";
- open(STDIN, "< /dev/null") || die "can't read /dev/null: $!";
- open(STDOUT, "> /dev/null") || die "can't write to /dev/null: $!";
- defined(my $pid = fork()) || die "can't fork: $!";
- exit if $pid; # non-zero now means I am the parent
- (setsid() != -1) || die "Can't start a new session: $!";
- open(STDERR, ">&STDOUT") || die "can't dup stdout: $!";
- }
+ sub daemonize {
+ chdir("/") || die "can't chdir to /: $!";
+ open(STDIN, "< /dev/null") || die "can't read /dev/null: $!";
+ open(STDOUT, "> /dev/null") || die "can't write to /dev/null: $!";
+ defined(my $pid = fork()) || die "can't fork: $!";
+ exit if $pid; # non-zero now means I am the parent
+ (setsid() != -1) || die "Can't start a new session: $!";
+ open(STDERR, ">&STDOUT") || die "can't dup stdout: $!";
+ }
The fork() has to come before the setsid() to ensure you aren't a
process group leader; the setsid() will fail if you are. If your
reopen the appropriate handles to STDIN and STDOUT and call other processes.
(The following example lacks proper error checking.)
- #!/usr/bin/perl -w
- # pipe1 - bidirectional communication using two pipe pairs
- # designed for the socketpair-challenged
- use IO::Handle; # thousands of lines just for autoflush :-(
- pipe(PARENT_RDR, CHILD_WTR); # XXX: check failure?
- pipe(CHILD_RDR, PARENT_WTR); # XXX: check failure?
- CHILD_WTR->autoflush(1);
- PARENT_WTR->autoflush(1);
-
- if ($pid = fork()) {
- close PARENT_RDR;
- close PARENT_WTR;
- print CHILD_WTR "Parent Pid $$ is sending this\n";
- chomp($line = <CHILD_RDR>);
- print "Parent Pid $$ just read this: '$line'\n";
- close CHILD_RDR; close CHILD_WTR;
- waitpid($pid, 0);
- } else {
- die "cannot fork: $!" unless defined $pid;
- close CHILD_RDR;
- close CHILD_WTR;
- chomp($line = <PARENT_RDR>);
- print "Child Pid $$ just read this: '$line'\n";
- print PARENT_WTR "Child Pid $$ is sending this\n";
- close PARENT_RDR;
- close PARENT_WTR;
- exit(0);
- }
+ #!/usr/bin/perl -w
+ # pipe1 - bidirectional communication using two pipe pairs
+ # designed for the socketpair-challenged
+ use IO::Handle; # thousands of lines just for autoflush :-(
+ pipe(PARENT_RDR, CHILD_WTR); # XXX: check failure?
+ pipe(CHILD_RDR, PARENT_WTR); # XXX: check failure?
+ CHILD_WTR->autoflush(1);
+ PARENT_WTR->autoflush(1);
+
+ if ($pid = fork()) {
+ close PARENT_RDR;
+ close PARENT_WTR;
+ print CHILD_WTR "Parent Pid $$ is sending this\n";
+ chomp($line = <CHILD_RDR>);
+ print "Parent Pid $$ just read this: '$line'\n";
+ close CHILD_RDR; close CHILD_WTR;
+ waitpid($pid, 0);
+ } else {
+ die "cannot fork: $!" unless defined $pid;
+ close CHILD_RDR;
+ close CHILD_WTR;
+ chomp($line = <PARENT_RDR>);
+ print "Child Pid $$ just read this: '$line'\n";
+ print PARENT_WTR "Child Pid $$ is sending this\n";
+ close PARENT_RDR;
+ close PARENT_WTR;
+ exit(0);
+ }
But you don't actually have to make two pipe calls. If you
have the socketpair() system call, it will do this all for you.
- #!/usr/bin/perl -w
- # pipe2 - bidirectional communication using socketpair
- # "the best ones always go both ways"
-
- use Socket;
- use IO::Handle; # thousands of lines just for autoflush :-(
-
- # We say AF_UNIX because although *_LOCAL is the
- # POSIX 1003.1g form of the constant, many machines
- # still don't have it.
- socketpair(CHILD, PARENT, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
- || die "socketpair: $!";
-
- CHILD->autoflush(1);
- PARENT->autoflush(1);
-
- if ($pid = fork()) {
- close PARENT;
- print CHILD "Parent Pid $$ is sending this\n";
- chomp($line = <CHILD>);
- print "Parent Pid $$ just read this: '$line'\n";
- close CHILD;
- waitpid($pid, 0);
- } else {
- die "cannot fork: $!" unless defined $pid;
- close CHILD;
- chomp($line = <PARENT>);
- print "Child Pid $$ just read this: '$line'\n";
- print PARENT "Child Pid $$ is sending this\n";
- close PARENT;
- exit(0);
- }
+ #!/usr/bin/perl -w
+ # pipe2 - bidirectional communication using socketpair
+ # "the best ones always go both ways"
+
+ use Socket;
+ use IO::Handle; # thousands of lines just for autoflush :-(
+
+ # We say AF_UNIX because although *_LOCAL is the
+ # POSIX 1003.1g form of the constant, many machines
+ # still don't have it.
+ socketpair(CHILD, PARENT, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
+ || die "socketpair: $!";
+
+ CHILD->autoflush(1);
+ PARENT->autoflush(1);
+
+ if ($pid = fork()) {
+ close PARENT;
+ print CHILD "Parent Pid $$ is sending this\n";
+ chomp($line = <CHILD>);
+ print "Parent Pid $$ just read this: '$line'\n";
+ close CHILD;
+ waitpid($pid, 0);
+ } else {
+ die "cannot fork: $!" unless defined $pid;
+ close CHILD;
+ chomp($line = <PARENT>);
+ print "Child Pid $$ just read this: '$line'\n";
+ print PARENT "Child Pid $$ is sending this\n";
+ close PARENT;
+ exit(0);
+ }
=head1 Sockets: Client/Server Communication
on a particular interface (like the external side of a gateway
or firewall machine), fill this in with your real address instead.
- #!/usr/bin/perl -Tw
- use strict;
- BEGIN { $ENV{PATH} = "/usr/bin:/bin" }
- use Socket;
- use Carp;
- my $EOL = "\015\012";
+ #!/usr/bin/perl -Tw
+ use strict;
+ BEGIN { $ENV{PATH} = "/usr/bin:/bin" }
+ use Socket;
+ use Carp;
+ my $EOL = "\015\012";
- sub logmsg { print "$0 $$: @_ at ", scalar localtime(), "\n" }
+ sub logmsg { print "$0 $$: @_ at ", scalar localtime(), "\n" }
- my $port = shift || 2345;
- die "invalid port" unless $port =~ /^ \d+ $/x;
+ my $port = shift || 2345;
+ die "invalid port" unless $port =~ /^ \d+ $/x;
- my $proto = getprotobyname("tcp");
+ my $proto = getprotobyname("tcp");
- socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
- setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
- || die "setsockopt: $!";
- bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $!";
- listen(Server, SOMAXCONN) || die "listen: $!";
+ socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
+ setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
+ || die "setsockopt: $!";
+ bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $!";
+ listen(Server, SOMAXCONN) || die "listen: $!";
- logmsg "server started on port $port";
+ logmsg "server started on port $port";
- my $paddr;
+ my $paddr;
- for ( ; $paddr = accept(Client, Server); close Client) {
- my($port, $iaddr) = sockaddr_in($paddr);
- my $name = gethostbyaddr($iaddr, AF_INET);
+ for ( ; $paddr = accept(Client, Server); close Client) {
+ my($port, $iaddr) = sockaddr_in($paddr);
+ my $name = gethostbyaddr($iaddr, AF_INET);
- logmsg "connection from $name [",
- inet_ntoa($iaddr), "]
- at port $port";
+ logmsg "connection from $name [",
+ inet_ntoa($iaddr), "]
+ at port $port";
- print Client "Hello there, $name, it's now ",
- scalar localtime(), $EOL;
- }
+ print Client "Hello there, $name, it's now ",
+ scalar localtime(), $EOL;
+ }
And here's a multitasking version. It's multitasked in that
like most typical servers, it spawns (fork()s) a slave server to
handle the client request so that the master server can quickly
go back to service a new client.
- #!/usr/bin/perl -Tw
- use strict;
- BEGIN { $ENV{PATH} = "/usr/bin:/bin" }
- use Socket;
- use Carp;
- my $EOL = "\015\012";
-
- sub spawn; # forward declaration
- sub logmsg { print "$0 $$: @_ at ", scalar localtime(), "\n" }
-
- my $port = shift || 2345;
- die "invalid port" unless $port =~ /^ \d+ $/x;
+ #!/usr/bin/perl -Tw
+ use strict;
+ BEGIN { $ENV{PATH} = "/usr/bin:/bin" }
+ use Socket;
+ use Carp;
+ my $EOL = "\015\012";
- my $proto = getprotobyname("tcp");
+ sub spawn; # forward declaration
+ sub logmsg { print "$0 $$: @_ at ", scalar localtime(), "\n" }
- socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
- setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
- || die "setsockopt: $!";
- bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $!";
- listen(Server, SOMAXCONN) || die "listen: $!";
+ my $port = shift || 2345;
+ die "invalid port" unless $port =~ /^ \d+ $/x;
- logmsg "server started on port $port";
+ my $proto = getprotobyname("tcp");
- my $waitedpid = 0;
- my $paddr;
+ socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
+ setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
+ || die "setsockopt: $!";
+ bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $!";
+ listen(Server, SOMAXCONN) || die "listen: $!";
- use POSIX ":sys_wait_h";
- use Errno;
+ logmsg "server started on port $port";
- sub REAPER {
- local $!; # don't let waitpid() overwrite current error
- while ((my $pid = waitpid(-1, WNOHANG)) > 0 && WIFEXITED($?)) {
- logmsg "reaped $waitedpid" . ($? ? " with exit $?" : "");
- }
- $SIG{CHLD} = \&REAPER; # loathe SysV
- }
+ my $waitedpid = 0;
+ my $paddr;
- $SIG{CHLD} = \&REAPER;
+ use POSIX ":sys_wait_h";
+ use Errno;
- while (1) {
- $paddr = accept(Client, Server) || do {
- # try again if accept() returned because got a signal
- next if $!{EINTR};
- die "accept: $!";
- };
- my ($port, $iaddr) = sockaddr_in($paddr);
- my $name = gethostbyaddr($iaddr, AF_INET);
-
- logmsg "connection from $name [",
- inet_ntoa($iaddr),
- "] at port $port";
+ sub REAPER {
+ local $!; # don't let waitpid() overwrite current error
+ while ((my $pid = waitpid(-1, WNOHANG)) > 0 && WIFEXITED($?)) {
+ logmsg "reaped $waitedpid" . ($? ? " with exit $?" : "");
+ }
+ $SIG{CHLD} = \&REAPER; # loathe SysV
+ }
- spawn sub {
- $| = 1;
- print "Hello there, $name, it's now ", scalar localtime(), $EOL;
- exec "/usr/games/fortune" # XXX: "wrong" line terminators
- or confess "can't exec fortune: $!";
- };
- close Client;
- }
+ $SIG{CHLD} = \&REAPER;
+
+ while (1) {
+ $paddr = accept(Client, Server) || do {
+ # try again if accept() returned because got a signal
+ next if $!{EINTR};
+ die "accept: $!";
+ };
+ my ($port, $iaddr) = sockaddr_in($paddr);
+ my $name = gethostbyaddr($iaddr, AF_INET);
+
+ logmsg "connection from $name [",
+ inet_ntoa($iaddr),
+ "] at port $port";
+
+ spawn sub {
+ $| = 1;
+ print "Hello there, $name, it's now ",
+ scalar localtime(),
+ $EOL;
+ exec "/usr/games/fortune" # XXX: "wrong" line terminators
+ or confess "can't exec fortune: $!";
+ };
+ close Client;
+ }
- sub spawn {
- my $coderef = shift;
+ sub spawn {
+ my $coderef = shift;
- unless (@_ == 0 && $coderef && ref($coderef) eq "CODE") {
- confess "usage: spawn CODEREF";
- }
+ unless (@_ == 0 && $coderef && ref($coderef) eq "CODE") {
+ confess "usage: spawn CODEREF";
+ }
- my $pid;
- unless (defined($pid = fork())) {
- logmsg "cannot fork: $!";
- return;
- }
- elsif ($pid) {
- logmsg "begat $pid";
- return; # I'm the parent
- }
- # else I'm the child -- go spawn
+ my $pid;
+ unless (defined($pid = fork())) {
+ logmsg "cannot fork: $!";
+ return;
+ }
+ elsif ($pid) {
+ logmsg "begat $pid";
+ return; # I'm the parent
+ }
+ # else I'm the child -- go spawn
- open(STDIN, "<&Client") || die "can't dup client to stdin";
- open(STDOUT, ">&Client") || die "can't dup client to stdout";
- ## open(STDERR, ">&STDOUT") || die "can't dup stdout to stderr";
- exit($coderef->());
- }
+ open(STDIN, "<&Client") || die "can't dup client to stdin";
+ open(STDOUT, ">&Client") || die "can't dup client to stdout";
+ ## open(STDERR, ">&STDOUT") || die "can't dup stdout to stderr";
+ exit($coderef->());
+ }
This server takes the trouble to clone off a child version via fork()
for each incoming request. That way it can handle many requests at
PeerAddr => "localhost",
PeerPort => "daytime(13)",
)
- || die "can't connect to daytime service on localhost";
+ || die "can't connect to daytime service on localhost";
while (<$remote>) { print }
When you run this program, you should get something back that
$client->autoflush(1);
print $client "Welcome to $0; type help for command list.\n";
$hostinfo = gethostbyaddr($client->peeraddr);
- printf "[Connect from %s]\n", $hostinfo ? $hostinfo->name : $client->peerhost;
+ printf "[Connect from %s]\n",
+ $hostinfo ? $hostinfo->name : $client->peerhost;
print $client "Command? ";
while ( <$client>) {
- next unless /\S/; # blank line
- if (/quit|exit/i) { last }
- elsif (/date|time/i) { printf $client "%s\n", scalar localtime() }
- elsif (/who/i ) { print $client `who 2>&1` }
- elsif (/cookie/i ) { print $client `/usr/games/fortune 2>&1` }
- elsif (/motd/i ) { print $client `cat /etc/motd 2>&1` }
+ next unless /\S/; # blank line
+ if (/quit|exit/i) { last }
+ elsif (/date|time/i) { printf $client "%s\n", scalar localtime() }
+ elsif (/who/i ) { print $client `who 2>&1` }
+ elsif (/cookie/i ) { print $client `/usr/games/fortune 2>&1` }
+ elsif (/motd/i ) { print $client `cat /etc/motd 2>&1` }
else {
print $client "Commands: quit date who cookie motd\n";
}
using select() to do a timed-out wait for I/O. To do something similar
with TCP, you'd have to use a different socket handle for each host.
- #!/usr/bin/perl -w
- use strict;
- use Socket;
- use Sys::Hostname;
-
- my ( $count, $hisiaddr, $hispaddr, $histime,
- $host, $iaddr, $paddr, $port, $proto,
- $rin, $rout, $rtime, $SECS_OF_70_YEARS);
-
- $SECS_OF_70_YEARS = 2_208_988_800;
-
- $iaddr = gethostbyname(hostname());
- $proto = getprotobyname("udp");
- $port = getservbyname("time", "udp");
- $paddr = sockaddr_in(0, $iaddr); # 0 means let kernel pick
-
- socket(SOCKET, PF_INET, SOCK_DGRAM, $proto) || die "socket: $!";
- bind(SOCKET, $paddr) || die "bind: $!";
-
- $| = 1;
- printf "%-12s %8s %s\n", "localhost", 0, scalar localtime();
- $count = 0;
- for $host (@ARGV) {
- $count++;
- $hisiaddr = inet_aton($host) || die "unknown host";
- $hispaddr = sockaddr_in($port, $hisiaddr);
- defined(send(SOCKET, 0, 0, $hispaddr)) || die "send $host: $!";
- }
+ #!/usr/bin/perl -w
+ use strict;
+ use Socket;
+ use Sys::Hostname;
+
+ my ( $count, $hisiaddr, $hispaddr, $histime,
+ $host, $iaddr, $paddr, $port, $proto,
+ $rin, $rout, $rtime, $SECS_OF_70_YEARS);
+
+ $SECS_OF_70_YEARS = 2_208_988_800;
+
+ $iaddr = gethostbyname(hostname());
+ $proto = getprotobyname("udp");
+ $port = getservbyname("time", "udp");
+ $paddr = sockaddr_in(0, $iaddr); # 0 means let kernel pick
+
+ socket(SOCKET, PF_INET, SOCK_DGRAM, $proto) || die "socket: $!";
+ bind(SOCKET, $paddr) || die "bind: $!";
+
+ $| = 1;
+ printf "%-12s %8s %s\n", "localhost", 0, scalar localtime();
+ $count = 0;
+ for $host (@ARGV) {
+ $count++;
+ $hisiaddr = inet_aton($host) || die "unknown host";
+ $hispaddr = sockaddr_in($port, $hisiaddr);
+ defined(send(SOCKET, 0, 0, $hispaddr)) || die "send $host: $!";
+ }
- $rin = "";
- vec($rin, fileno(SOCKET), 1) = 1;
-
- # timeout after 10.0 seconds
- while ($count && select($rout = $rin, undef, undef, 10.0)) {
- $rtime = "";
- $hispaddr = recv(SOCKET, $rtime, 4, 0) || die "recv: $!";
- ($port, $hisiaddr) = sockaddr_in($hispaddr);
- $host = gethostbyaddr($hisiaddr, AF_INET);
- $histime = unpack("N", $rtime) - $SECS_OF_70_YEARS;
- printf "%-12s ", $host;
- printf "%8d %s\n", $histime - time(), scalar localtime($histime);
- $count--;
- }
+ $rin = "";
+ vec($rin, fileno(SOCKET), 1) = 1;
+
+ # timeout after 10.0 seconds
+ while ($count && select($rout = $rin, undef, undef, 10.0)) {
+ $rtime = "";
+ $hispaddr = recv(SOCKET, $rtime, 4, 0) || die "recv: $!";
+ ($port, $hisiaddr) = sockaddr_in($hispaddr);
+ $host = gethostbyaddr($hisiaddr, AF_INET);
+ $histime = unpack("N", $rtime) - $SECS_OF_70_YEARS;
+ printf "%-12s ", $host;
+ printf "%8d %s\n", $histime - time(), scalar localtime($histime);
+ $count--;
+ }
This example does not include any retries and may consequently fail to
contact a reachable host. The most prominent reason for this is congestion
design deficiencies, and nowadays, there is a series of "UTF-8
locales", based on Unicode. These are locales whose character set is
Unicode, encoded in UTF-8. Starting in v5.20, Perl fully supports
-UTF-8 locales, except for sorting and string comparisons. (Use
-L<Unicode::Collate> for these.) Perl continues to support the old
-non UTF-8 locales as well. There are currently no UTF-8 locales for
-EBCDIC platforms.
+UTF-8 locales, except for sorting and string comparisons like C<lt> and
+C<ge>. (Use L<Unicode::Collate> for these.) Perl continues to support
+the old non UTF-8 locales as well. There are currently no UTF-8 locales
+for EBCDIC platforms.
(Unicode is also creating C<CLDR>, the "Common Locale Data Repository",
L<http://cldr.unicode.org/> which includes more types of information than
L<POSIX> module. Some of those functions are always affected by the
current locale. For example, C<POSIX::strftime()> uses C<LC_TIME>;
C<POSIX::strtod()> uses C<LC_NUMERIC>; C<POSIX::strcoll()> and
-C<POSIX::strxfrm()> use C<LC_COLLATE>; and character classification
-functions like C<POSIX::isalnum()> use C<LC_CTYPE>. All such functions
+C<POSIX::strxfrm()> use C<LC_COLLATE>. All such functions
will behave according to the current underlying locale, even if that
locale isn't exposed to Perl space.
strings and C<s///> substitutions; and case-independent regular expression
pattern matching using the C<i> modifier.
-Finally, C<LC_CTYPE> affects the (deprecated) POSIX character-class test
-functions--C<POSIX::isalpha()>, C<POSIX::islower()>, and so on. For
-example, if you move from the "C" locale to a 7-bit ISO 646 one,
-you may find--possibly to your surprise--that C<"|"> moves from the
-C<POSIX::ispunct()> class to C<POSIX::isalpha()>.
-Unfortunately, this creates big problems for regular expressions. "|" still
-means alternation even though it matches C<\w>. Starting in v5.22, a
-warning will be raised when such a locale is switched into. More
-details are given several paragraphs further down.
-
Starting in v5.20, Perl supports UTF-8 locales for C<LC_CTYPE>, but
otherwise Perl only supports single-byte locales, such as the ISO 8859
series. This means that wide character locales, for example for Asian
Results are never tainted.
-=item *
-
-B<POSIX character class tests> (C<POSIX::isalnum()>,
-C<POSIX::isalpha()>, C<POSIX::isdigit()>, C<POSIX::isgraph()>,
-C<POSIX::islower()>, C<POSIX::isprint()>, C<POSIX::ispunct()>,
-C<POSIX::isspace()>, C<POSIX::isupper()>, C<POSIX::isxdigit()>):
-
-True/false results are never tainted.
-
=back
Three examples illustrate locale-dependent tainting.
directive at the top of the file that needs it. That way when somebody
tries to run the new code under an old perl, rather than getting an error like
- Type of arg 1 to push must be array (not array element) at /tmp/a line 8, near ""betty";"
+ Type of arg 1 to push must be array (not array element) at /tmp/a
+ line 8, near ""betty";"
Execution of /tmp/a aborted due to compilation errors.
they'll be politely informed that
- Perl v5.14.0 required--this is only v5.12.3, stopped at /tmp/a line 1.
- BEGIN failed--compilation aborted at /tmp/a line 1.
+ Perl v5.14.0 required--this is only v5.12.3, stopped at /tmp/a line 1.
+ BEGIN failed--compilation aborted at /tmp/a line 1.
=head2 Access and Printing
The former is what the Perl debugger uses, while the latter generates
parsable Perl code. For example:
- use v5.14; # using the + prototype, new to v5.14
+ use v5.14; # using the + prototype, new to v5.14
- sub show(+) {
+ sub show(+) {
require Dumpvalue;
state $prettily = new Dumpvalue::
tick => q("),
- compactDump => 1, # comment these two lines out
- veryCompact => 1, # if you want a bigger dump
+ compactDump => 1, # comment these two lines
+ # out
+ veryCompact => 1, # if you want a bigger
+ # dump
;
dumpValue $prettily @_;
- }
+ }
- # Assign a list of array references to an array.
- my @AoA = (
+ # Assign a list of array references to an array.
+ my @AoA = (
[ "fred", "barney" ],
[ "george", "jane", "elroy" ],
[ "homer", "marge", "bart" ],
- );
- push $AoA[0], "wilma", "betty";
- show @AoA;
+ );
+ push $AoA[0], "wilma", "betty";
+ show @AoA;
will print out:
2 digits after the decimal. You can test whether it conforms to CPAN by
using
- perl -MExtUtils::MakeMaker -le 'print MM->parse_version(shift)' 'Foo.pm'
+ perl -MExtUtils::MakeMaker -le 'print MM->parse_version(shift)' \
+ 'Foo.pm'
If you want to release a 'beta' or 'alpha' version of a module but
don't want CPAN.pm to list it as most recent use an '_' after the
the user will see something like this:
- No hostname given at /usr/local/lib/perl5/site_perl/5.6.0/Net/Acme.pm
- line 123.
+ No hostname given at
+ /usr/local/lib/perl5/site_perl/5.6.0/Net/Acme.pm line 123.
which looks like your module is doing something wrong. Instead, you want
to put the blame on the user, and say this:
my $i_word = 0;
foreach my $word ( @words ) {
$i_word++;
- $count{$i_LINES}{spec} += matches($i_word, $word, '[^a-zA-Z0-9]');
- $count{$i_LINES}{only} += matches($i_word, $word, '^[^a-zA-Z0-9]+$');
- $count{$i_LINES}{cons} += matches($i_word, $word, '^[(?i:bcdfghjklmnpqrstvwxyz)]+$');
- $count{$i_LINES}{vows} += matches($i_word, $word, '^[(?i:aeiou)]+$');
- $count{$i_LINES}{caps} += matches($i_word, $word, '^[(A-Z)]+$');
+ $count{$i_LINES}{spec} += matches($i_word, $word,
+ '[^a-zA-Z0-9]');
+ $count{$i_LINES}{only} += matches($i_word, $word,
+ '^[^a-zA-Z0-9]+$');
+ $count{$i_LINES}{cons} += matches($i_word, $word,
+ '^[(?i:bcdfghjklmnpqrstvwxyz)]+$');
+ $count{$i_LINES}{vows} += matches($i_word, $word,
+ '^[(?i:aeiou)]+$');
+ $count{$i_LINES}{caps} += matches($i_word, $word,
+ '^[(A-Z)]+$');
}
}
$has++ if $1;
}
- debug("word: $i_wd ".($has ? 'matches' : 'does not match')." chars: /$regex/");
+ debug( "word: $i_wd "
+ . ($has ? 'matches' : 'does not match')
+ . " chars: /$regex/");
return $has;
}
A common sight is code which looks something like this:
- logger->debug( "A logging message via process-id: $$ INC: " . Dumper(\%INC) )
+ logger->debug( "A logging message via process-id: $$ INC: "
+ . Dumper(\%INC) )
The problem is that this code will always be parsed and executed, even when the
debug level set in the logging configuration file is zero. Once the debug()
already have been dumped, and the message string constructed, all of which work
could be bypassed by a debug variable at the statement level, like this:
- logger->debug( "A logging message via process-id: $$ INC: " . Dumper(\%INC) ) if $DEBUG;
+ logger->debug( "A logging message via process-id: $$ INC: "
+ . Dumper(\%INC) ) if $DEBUG;
This effect can be demonstrated by setting up a test script with both forms,
including a C<debug()> subroutine to emulate typical C<logger()> functionality.
things such as DHCP and NAT, the hostname you get back might not be
very useful.
-All the above "don't":s may look daunting, and they are, but the key
+All the above I<don't>s may look daunting, and they are, but the key
is to degrade gracefully if one cannot reach the particular network
service one wants. Croaking or hanging do not look very professional.
variable C<$^O> to differentiate platforms, as described in
L<"PLATFORMS">.
+Beware of the "else syndrome":
+
+ if ($^O eq 'MSWin32') {
+ # code that assumes Windows
+ } else {
+ # code that assumes Linux
+ }
+
+The C<else> branch should be used for the really ultimate fallback,
+not for code specific to some platform.
+
Be careful in the tests you supply with your module or programs.
Module code may be fully portable, but its tests might not be. This
often happens when tests spawn off other processes or call external
Known to be broken for 5.8.0 (but 5.6.1 and 5.7.2 can be used):
- AmigaOS
+ AmigaOS 3
The following platforms have been known to build Perl from source in
the past (5.005_03 and earlier), but we haven't been able to verify
{n,} Match at least n times
{n,m} Match at least n but not more than m times
-(If a curly bracket occurs in any other context and does not form part of
-a backslashed sequence like C<\x{...}>, it is treated as a regular
-character. However, a deprecation warning is raised for all such
+(If a curly bracket occurs in a context other than one of the
+quantifiers listed above, where it does not form part of a backslashed
+sequence like C<\x{...}>, it is treated as a regular character.
+However, a deprecation warning is raised for these
occurrences, and in Perl v5.26, literal uses of a curly bracket will be
required to be escaped, say by preceding them with a backslash (C<"\{">)
or enclosing them within square brackets (C<"[{]">). This change will
the part of the current pattern contained within a specified capture group
as an independent pattern that must match at the current position. Also
different is the treatment of capture buffers, unlike C<(??{ code })>
-recursive patterns have access to their callers match state, so one can
+recursive patterns have access to their caller's match state, so one can
use backreferences safely.
I<PARNO> is a sequence of digits (not starting with 0) whose value reflects
An example output might be:
- HASH_FUNCTION = ONE_AT_A_TIME_HARD HASH_SEED = 0x652e9b9349a7a032 PERTURB_KEYS = 1 (RANDOM)
+ HASH_FUNCTION = ONE_AT_A_TIME_HARD HASH_SEED = 0x652e9b9349a7a032 PERTURB_KEYS = 1 (RANDOM)
=item PERL_MEM_LOG
X<PERL_MEM_LOG>
expected to return a blessed reference to a new scalar
(probably anonymous) that it's creating. For example:
- sub TIESCALAR {
- my $class = shift;
- my $pid = shift || $$; # 0 means me
+ sub TIESCALAR {
+ my $class = shift;
+ my $pid = shift || $$; # 0 means me
- if ($pid !~ /^\d+$/) {
- carp "Nice::Tie::Scalar got non-numeric pid $pid" if $^W;
- return undef;
- }
+ if ($pid !~ /^\d+$/) {
+ carp "Nice::Tie::Scalar got non-numeric pid $pid" if $^W;
+ return undef;
+ }
- unless (kill 0, $pid) { # EPERM or ERSCH, no doubt
- carp "Nice::Tie::Scalar got bad pid $pid: $!" if $^W;
- return undef;
- }
+ unless (kill 0, $pid) { # EPERM or ERSCH, no doubt
+ carp "Nice::Tie::Scalar got bad pid $pid: $!" if $^W;
+ return undef;
+ }
- return bless \$pid, $class;
- }
+ return bless \$pid, $class;
+ }
This tie class has chosen to return an error rather than raising an
exception if its constructor should fail. While this is how dbmopen() works,
returning a value from STORE; the semantic of assignment returning the
assigned value is implemented with FETCH.
- sub STORE {
- my $self = shift;
- confess "wrong type" unless ref $self;
- my $new_nicety = shift;
- croak "usage error" if @_;
-
- if ($new_nicety < PRIO_MIN) {
- carp sprintf
- "WARNING: priority %d less than minimum system priority %d",
- $new_nicety, PRIO_MIN if $^W;
- $new_nicety = PRIO_MIN;
- }
-
- if ($new_nicety > PRIO_MAX) {
- carp sprintf
- "WARNING: priority %d greater than maximum system priority %d",
- $new_nicety, PRIO_MAX if $^W;
- $new_nicety = PRIO_MAX;
- }
-
- unless (defined setpriority(PRIO_PROCESS, $$self, $new_nicety)) {
- confess "setpriority failed: $!";
- }
- }
+ sub STORE {
+ my $self = shift;
+ confess "wrong type" unless ref $self;
+ my $new_nicety = shift;
+ croak "usage error" if @_;
+
+ if ($new_nicety < PRIO_MIN) {
+ carp sprintf
+ "WARNING: priority %d less than minimum system priority %d",
+ $new_nicety, PRIO_MIN if $^W;
+ $new_nicety = PRIO_MIN;
+ }
+
+ if ($new_nicety > PRIO_MAX) {
+ carp sprintf
+ "WARNING: priority %d greater than maximum system priority %d",
+ $new_nicety, PRIO_MAX if $^W;
+ $new_nicety = PRIO_MAX;
+ }
+
+ unless (defined setpriority(PRIO_PROCESS,
+ $$self,
+ $new_nicety))
+ {
+ confess "setpriority failed: $!";
+ }
+ }
=item UNTIE this
X<UNTIE>
In our example, C<undef> is really C<$self-E<gt>{ELEMSIZE}> number of
spaces so we have a little more work to do here:
- sub STORE {
- my $self = shift;
- my( $index, $value ) = @_;
- if ( length $value > $self->{ELEMSIZE} ) {
- croak "length of $value is greater than $self->{ELEMSIZE}";
- }
- # fill in the blanks
- $self->EXTEND( $index ) if $index > $self->FETCHSIZE();
- # right justify to keep element size for smaller elements
- $self->{ARRAY}->[$index] = sprintf "%$self->{ELEMSIZE}s", $value;
- }
+ sub STORE {
+ my $self = shift;
+ my( $index, $value ) = @_;
+ if ( length $value > $self->{ELEMSIZE} ) {
+ croak "length of $value is greater than $self->{ELEMSIZE}";
+ }
+ # fill in the blanks
+ $self->EXTEND( $index ) if $index > $self->FETCHSIZE();
+ # right justify to keep element size for smaller elements
+ $self->{ARRAY}->[$index] = sprintf "%$self->{ELEMSIZE}s", $value;
+ }
Negative indexes are treated the same as with FETCH.
In our example, we will determine that if an element consists of
C<$self-E<gt>{ELEMSIZE}> spaces only, it does not exist:
- sub EXISTS {
- my $self = shift;
- my $index = shift;
- return 0 if ! defined $self->{ARRAY}->[$index] ||
- $self->{ARRAY}->[$index] eq ' ' x $self->{ELEMSIZE};
- return 1;
- }
+ sub EXISTS {
+ my $self = shift;
+ my $index = shift;
+ return 0 if ! defined $self->{ARRAY}->[$index] ||
+ $self->{ARRAY}->[$index] eq ' ' x $self->{ELEMSIZE};
+ return 1;
+ }
=item DELETE this, key
X<DELETE>
typically by using the delete() function. Again, we'll
be careful to check whether they really want to clobber files.
- sub DELETE {
- carp &whowasi if $DEBUG;
+ sub DELETE {
+ carp &whowasi if $DEBUG;
- my $self = shift;
- my $dot = shift;
- my $file = $self->{HOME} . "/.$dot";
- croak "@{[&whowasi]}: won't remove file $file"
- unless $self->{CLOBBER};
- delete $self->{LIST}->{$dot};
- my $success = unlink($file);
- carp "@{[&whowasi]}: can't unlink $file: $!" unless $success;
- $success;
- }
+ my $self = shift;
+ my $dot = shift;
+ my $file = $self->{HOME} . "/.$dot";
+ croak "@{[&whowasi]}: won't remove file $file"
+ unless $self->{CLOBBER};
+ delete $self->{LIST}->{$dot};
+ my $success = unlink($file);
+ carp "@{[&whowasi]}: can't unlink $file: $!" unless $success;
+ $success;
+ }
The value returned by DELETE becomes the return value of the call
to delete(). If you want to emulate the normal behavior of delete(),
dangerous thing that they'll have to set CLOBBER to something higher than
1 to make it happen.
- sub CLEAR {
- carp &whowasi if $DEBUG;
- my $self = shift;
- croak "@{[&whowasi]}: won't remove all dot files for $self->{USER}"
- unless $self->{CLOBBER} > 1;
- my $dot;
- foreach $dot ( keys %{$self->{LIST}}) {
- $self->DELETE($dot);
- }
- }
+ sub CLEAR {
+ carp &whowasi if $DEBUG;
+ my $self = shift;
+ croak "@{[&whowasi]}: won't remove all dot files for $self->{USER}"
+ unless $self->{CLOBBER} > 1;
+ my $dot;
+ foreach $dot ( keys %{$self->{LIST}}) {
+ $self->DELETE($dot);
+ }
+ }
=item EXISTS this, key
X<EXISTS>
sub FIRSTKEY {
carp &whowasi if $DEBUG;
my $self = shift;
- my $a = keys %{$self->{LIST}}; # reset each() iterator
+ my $a = keys %{$self->{LIST}}; # reset each() iterator
each %{$self->{LIST}}
}
This method will be called when the handle is written to via the
C<syswrite> function.
- sub WRITE {
- $r = shift;
- my($buf,$len,$offset) = @_;
- print "WRITE called, \$buf=$buf, \$len=$len, \$offset=$offset";
- }
+ sub WRITE {
+ $r = shift;
+ my($buf,$len,$offset) = @_;
+ print "WRITE called, \$buf=$buf, \$len=$len, \$offset=$offset";
+ }
=item PRINT this, LIST
X<PRINT>
with the C<print()> or C<say()> functions. Beyond its self reference
it also expects the list that was passed to the print function.
- sub PRINT { $r = shift; $$r++; print join($,,map(uc($_),@_)),$\ }
+ sub PRINT { $r = shift; $$r++; print join($,,map(uc($_),@_)),$\ }
C<say()> acts just like C<print()> except $\ will be localized to C<\n> so
you need do nothing special to handle C<say()> in C<PRINT()>.
This method will be called when the handle is read from via the C<read>
or C<sysread> functions.
- sub READ {
- my $self = shift;
- my $bufref = \$_[0];
- my(undef,$len,$offset) = @_;
- print "READ called, \$buf=$bufref, \$len=$len, \$offset=$offset";
- # add to $$bufref, set $len to number of characters read
- $len;
- }
+ sub READ {
+ my $self = shift;
+ my $bufref = \$_[0];
+ my(undef,$len,$offset) = @_;
+ print "READ called, \$buf=$bufref, \$len=$len, \$offset=$offset";
+ # add to $$bufref, set $len to number of characters read
+ $len;
+ }
=item READLINE this
X<READLINE>
warning if appropriate. e.g. to replicate the no UNTIE case this method can
be used:
- sub UNTIE
- {
- my ($obj,$count) = @_;
- carp "untie attempted while $count inner references still exist" if $count;
- }
+ sub UNTIE
+ {
+ my ($obj,$count) = @_;
+ carp "untie attempted while $count inner references still exist"
+ if $count;
+ }
=head1 SEE ALSO
X<$^E> X<$EXTENDED_OS_ERROR>
Error information specific to the current operating system. At the
-moment, this differs from C<$!> under only VMS, OS/2, and Win32 (and
+moment, this differs from C<L</$!>> under only VMS, OS/2, and Win32 (and
for MacPerl). On all other platforms, C<$^E> is always just the same
as C<$!>.
via C<$^E>. ANSI C and Unix-like calls set C<errno> and so most
portable Perl code will report errors via C<$!>.
-Caveats mentioned in the description of C<$!> generally apply to
+Caveats mentioned in the description of C<L<$!>> generally apply to
C<$^E>, also.
This variable was added in Perl 5.003.
X<$^D> X<$DEBUGGING>
The current value of the debugging flags. May be read or set. Like its
-command-line equivalent, you can use numeric or symbolic values, eg
-C<$^D = 10> or C<$^D = "st">.
+L<command-line equivalent|perlrun/B<-D>I<letters>>, you can use numeric
+or symbolic values, e.g. C<$^D = 10> or C<$^D = "st">. See
+L<perlrun/B<-D>I<number>>. The contents of this variable also affects the
+debugger operation. See L<perldebguts/Debugger Internals>.
Mnemonic: value of B<-D> switch.
}
}
- LOADING_FILE_PROBE(unixname);
+ PERL_DTRACE_PROBE_FILE_LOADING(unixname);
/* prepare to compile file */
else
op = PL_op->op_next;
- LOADED_FILE_PROBE(unixname);
+ PERL_DTRACE_PROBE_FILE_LOADED(unixname);
return op;
}
STRLEN slen;
bool doutf8 = FALSE; /* whether replacement is in utf8 */
#ifdef PERL_ANY_COW
- bool is_cow;
+ bool was_cow;
#endif
SV *nsv = NULL;
/* known replacement string? */
SvGETMAGIC(TARG); /* must come before cow check */
#ifdef PERL_ANY_COW
- /* Awooga. Awooga. "bool" types that are actually char are dangerous,
- because they make integers such as 256 "false". */
- is_cow = SvIsCOW(TARG) ? TRUE : FALSE;
-#else
- if (SvIsCOW(TARG))
- sv_force_normal_flags(TARG,0);
+ /* note that a string might get converted to COW during matching */
+ was_cow = cBOOL(SvIsCOW(TARG));
+#endif
+ if (!(rpm->op_pmflags & PMf_NONDESTRUCT)) {
+#ifndef PERL_ANY_COW
+ if (SvIsCOW(TARG))
+ sv_force_normal_flags(TARG,0);
#endif
- if (!(rpm->op_pmflags & PMf_NONDESTRUCT)
- && (SvREADONLY(TARG)
- || ( ((SvTYPE(TARG) == SVt_PVGV && isGV_with_GP(TARG))
- || SvTYPE(TARG) > SVt_PVLV)
- && !(SvTYPE(TARG) == SVt_PVGV && SvFAKE(TARG)))))
- Perl_croak_no_modify();
+ if ((SvREADONLY(TARG)
+ || ( ((SvTYPE(TARG) == SVt_PVGV && isGV_with_GP(TARG))
+ || SvTYPE(TARG) > SVt_PVLV)
+ && !(SvTYPE(TARG) == SVt_PVGV && SvFAKE(TARG)))))
+ Perl_croak_no_modify();
+ }
PUTBACK;
orig = SvPV_nomg(TARG, len);
/* note we don't (yet) force the var into being a string; if we fail
- * to match, we leave as-is; on successful match howeverm, we *will*
+ * to match, we leave as-is; on successful match however, we *will*
* coerce into a string, then repeat the match */
if (!SvPOKp(TARG) || SvTYPE(TARG) == SVt_PVGV || SvVOK(TARG))
force_on_match = 1;
/* can do inplace substitution? */
if (c
#ifdef PERL_ANY_COW
- && !is_cow
+ && !was_cow
#endif
&& (I32)clen <= RX_MINLENRET(rx)
&& ( once
{
#ifdef PERL_ANY_COW
+ /* string might have got converted to COW since we set was_cow */
if (SvIsCOW(TARG)) {
if (!force_on_match)
goto have_a_cow;
PERL_CALLCONV void Perl_init_tm(pTHX_ struct tm *ptm);
#define PERL_ARGS_ASSERT_INIT_TM \
assert(ptm)
-PERL_CALLCONV char* Perl_instr(const char* big, const char* little)
+/* PERL_CALLCONV char* Perl_instr(const char* big, const char* little)
__attribute__warn_unused_result__
- __attribute__pure__;
+ __attribute__pure__; */
#define PERL_ARGS_ASSERT_INSTR \
assert(big); assert(little)
#endif
#if !defined(HAS_BZERO) && !defined(HAS_MEMSET)
-PERL_CALLCONV char* Perl_my_bzero(char* loc, I32 len);
+PERL_CALLCONV void* Perl_my_bzero(void* vloc, size_t len);
#define PERL_ARGS_ASSERT_MY_BZERO \
- assert(loc)
+ assert(vloc)
#endif
#if !defined(HAS_GETENV_LEN)
PERL_CALLCONV char* Perl_getenv_len(pTHX_ const char *env_elem, unsigned long *len);
assert(env_elem); assert(len)
#endif
#if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP)
-PERL_CALLCONV I32 Perl_my_memcmp(const char* s1, const char* s2, I32 len)
+PERL_CALLCONV int Perl_my_memcmp(const void* vs1, const void* vs2, size_t len)
__attribute__pure__;
#define PERL_ARGS_ASSERT_MY_MEMCMP \
- assert(s1); assert(s2)
+ assert(vs1); assert(vs2)
#endif
+#if !defined(HAS_MEMCPY) || (!defined(HAS_MEMMOVE) && !defined(HAS_SAFE_MEMCPY))
+PERL_CALLCONV void* Perl_my_bcopy(const void* vfrom, void* vto, size_t len);
+#define PERL_ARGS_ASSERT_MY_BCOPY \
+ assert(vfrom); assert(vto)
+#endif
#if !defined(HAS_MEMSET)
-PERL_CALLCONV void* Perl_my_memset(char* loc, I32 ch, I32 len);
+PERL_CALLCONV void* Perl_my_memset(void* vloc, int ch, size_t len);
#define PERL_ARGS_ASSERT_MY_MEMSET \
- assert(loc)
+ assert(vloc)
#endif
#if !defined(HAS_MKDIR) || !defined(HAS_RMDIR)
# if defined(PERL_IN_PP_SYS_C)
#define PERL_ARGS_ASSERT_GET_INVLIST_PREVIOUS_INDEX_ADDR \
assert(invlist)
+PERL_STATIC_INLINE void S_invlist_clear(pTHX_ SV* invlist);
+#define PERL_ARGS_ASSERT_INVLIST_CLEAR \
+ assert(invlist)
PERL_STATIC_INLINE IV S_invlist_previous_index(SV* const invlist)
__attribute__warn_unused_result__;
#define PERL_ARGS_ASSERT_INVLIST_PREVIOUS_INDEX \
assert(invlist)
+STATIC void S_invlist_replace_list_destroys_src(pTHX_ SV *dest, SV *src);
+#define PERL_ARGS_ASSERT_INVLIST_REPLACE_LIST_DESTROYS_SRC \
+ assert(dest); assert(src)
PERL_STATIC_INLINE void S_invlist_set_previous_index(SV* const invlist, const IV index);
#define PERL_ARGS_ASSERT_INVLIST_SET_PREVIOUS_INDEX \
assert(invlist)
-PERL_STATIC_INLINE void S_invlist_trim(SV* const invlist);
+PERL_STATIC_INLINE void S_invlist_trim(SV* invlist);
#define PERL_ARGS_ASSERT_INVLIST_TRIM \
assert(invlist)
# endif
#define PERL_ARGS_ASSERT_DO_EXEC3 \
assert(incmd)
#endif
-#if (!defined(HAS_MEMCPY) && !defined(HAS_BCOPY)) || (!defined(HAS_MEMMOVE) && !defined(HAS_SAFE_MEMCPY) && !defined(HAS_SAFE_BCOPY))
-PERL_CALLCONV char* Perl_my_bcopy(const char* from, char* to, I32 len);
-#define PERL_ARGS_ASSERT_MY_BCOPY \
- assert(from); assert(to)
-#endif
#if defined(DEBUGGING)
PERL_CALLCONV int Perl_get_debug_opts(pTHX_ const char **s, bool givehelp)
__attribute__warn_unused_result__;
STATIC void S_put_range(pTHX_ SV* sv, UV start, const UV end, const bool allow_literals);
#define PERL_ARGS_ASSERT_PUT_RANGE \
assert(sv)
+PERL_CALLCONV int Perl_re_indentf(pTHX_ const char *fmt, U32 depth, ...);
+#define PERL_ARGS_ASSERT_RE_INDENTF \
+ assert(fmt)
STATIC void S_regdump_extflags(pTHX_ const char *lead, const U32 flags);
STATIC void S_regdump_intflags(pTHX_ const char *lead, const U32 flags);
STATIC U8 S_regtail_study(pTHX_ RExC_state_t *pRExC_state, regnode *p, const regnode *val, U32 depth);
STATIC void S_debug_start_match(pTHX_ const REGEXP *prog, const bool do_utf8, const char *start, const char *end, const char *blurb);
#define PERL_ARGS_ASSERT_DEBUG_START_MATCH \
assert(prog); assert(start); assert(end); assert(blurb)
-STATIC void S_dump_exec_pos(pTHX_ const char *locinput, const regnode *scan, const char *loc_regeol, const char *loc_bostr, const char *loc_reg_starttry, const bool do_utf8);
+STATIC void S_dump_exec_pos(pTHX_ const char *locinput, const regnode *scan, const char *loc_regeol, const char *loc_bostr, const char *loc_reg_starttry, const bool do_utf8, const U32 depth);
#define PERL_ARGS_ASSERT_DUMP_EXEC_POS \
assert(locinput); assert(scan); assert(loc_regeol); assert(loc_bostr); assert(loc_reg_starttry)
+PERL_CALLCONV int Perl_re_exec_indentf(pTHX_ const char *fmt, U32 depth, ...);
+#define PERL_ARGS_ASSERT_RE_EXEC_INDENTF \
+ assert(fmt)
# endif
# if defined(PERL_IN_SV_C)
STATIC void S_del_sv(pTHX_ SV *p);
PERL_STATIC_INLINE regnode* S_handle_named_backref(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, char * parse_start, char ch);
#define PERL_ARGS_ASSERT_HANDLE_NAMED_BACKREF \
assert(pRExC_state); assert(flagp); assert(parse_start)
-STATIC int S_handle_possible_posix(pTHX_ RExC_state_t *pRExC_state, const char* const s, char ** updated_parse_ptr, AV** posix_warnings);
+STATIC int S_handle_possible_posix(pTHX_ RExC_state_t *pRExC_state, const char* const s, char ** updated_parse_ptr, AV** posix_warnings, const bool check_only);
#define PERL_ARGS_ASSERT_HANDLE_POSSIBLE_POSIX \
assert(pRExC_state); assert(s)
STATIC regnode* S_handle_regex_sets(pTHX_ RExC_state_t *pRExC_state, SV ** return_invlist, I32 *flagp, U32 depth, char * const oregcomp_parse);
STATIC void S_nextchar(pTHX_ RExC_state_t *pRExC_state);
#define PERL_ARGS_ASSERT_NEXTCHAR \
assert(pRExC_state)
+STATIC void S_output_or_return_posix_warnings(pTHX_ RExC_state_t *pRExC_state, AV* posix_warnings, AV** return_posix_warnings);
+#define PERL_ARGS_ASSERT_OUTPUT_OR_RETURN_POSIX_WARNINGS \
+ assert(pRExC_state); assert(posix_warnings)
STATIC void S_parse_lparen_question_flags(pTHX_ RExC_state_t *pRExC_state);
#define PERL_ARGS_ASSERT_PARSE_LPAREN_QUESTION_FLAGS \
assert(pRExC_state)
STATIC regnode* S_regbranch(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, I32 first, U32 depth);
#define PERL_ARGS_ASSERT_REGBRANCH \
assert(pRExC_state); assert(flagp)
-STATIC regnode* S_regclass(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth, const bool stop_at_1, bool allow_multi_fold, const bool silence_non_portable, const bool strict, bool optimizable, SV** ret_invlist, AV** posix_warnings);
+STATIC regnode* S_regclass(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth, const bool stop_at_1, bool allow_multi_fold, const bool silence_non_portable, const bool strict, bool optimizable, SV** ret_invlist, AV** return_posix_warnings);
#define PERL_ARGS_ASSERT_REGCLASS \
assert(pRExC_state); assert(flagp)
STATIC unsigned int S_regex_set_precedence(const U8 my_operator)
#define PERL_ARGS_ASSERT__GET_REGCLASS_NONBITMAP_DATA \
assert(node)
PERL_CALLCONV void Perl__load_PL_utf8_foldclosures(pTHX);
+PERL_CALLCONV int Perl_re_printf(pTHX_ const char *fmt, ...);
+#define PERL_ARGS_ASSERT_RE_PRINTF \
+ assert(fmt)
PERL_CALLCONV void Perl_regprop(pTHX_ const regexp *prog, SV* sv, const regnode* o, const regmatch_info *reginfo, const RExC_state_t *pRExC_state);
#define PERL_ARGS_ASSERT_REGPROP \
assert(sv); assert(o)
PERL_CALLCONV Perl_c_backtrace* Perl_get_c_backtrace(pTHX_ int max_depth, int skip);
PERL_CALLCONV SV* Perl_get_c_backtrace_dump(pTHX_ int max_depth, int skip);
#endif
+#if defined(USE_DTRACE)
+PERL_CALLCONV void Perl_dtrace_probe_call(pTHX_ CV *cv, bool is_call);
+#define PERL_ARGS_ASSERT_DTRACE_PROBE_CALL \
+ assert(cv)
+PERL_CALLCONV void Perl_dtrace_probe_load(pTHX_ const char *name, bool is_loading);
+#define PERL_ARGS_ASSERT_DTRACE_PROBE_LOAD \
+ assert(name)
+PERL_CALLCONV void Perl_dtrace_probe_op(pTHX_ const OP *op);
+#define PERL_ARGS_ASSERT_DTRACE_PROBE_OP \
+ assert(op)
+PERL_CALLCONV void Perl_dtrace_probe_phase(pTHX_ enum perl_phase phase);
+#endif
#if defined(USE_ITHREADS)
PERL_CALLCONV PADOFFSET Perl_alloccopstash(pTHX_ HV *hv);
#define PERL_ARGS_ASSERT_ALLOCCOPSTASH \
* 1a0687fb9c6c4567e853913549df0944fe40821279a3e9cdaa6ab8679bc286fd lib/unicore/extracted/DLineBreak.txt
* 40bcfed3ca727c19e1331f6c33806231d5f7eeeabd2e6a9e06a3740c85d0c250 lib/unicore/extracted/DNumType.txt
* a18d502bad39d527ac5586d7bc93e29f565859e3bcc24ada627eff606d6f5fed lib/unicore/extracted/DNumValues.txt
- * 7baa3c79b0ac81279720b4871737ab448d7ddd1bfad31b981437ce49c1292535 lib/unicore/mktables
+ * 285aef7ed2bf69724b1fa9bba177640636f666e1a5dd0ba5e538d4790129bbfe lib/unicore/mktables
* 462c9aaa608fb2014cd9649af1c5c009485c60b9c8b15b89401fdc10cf6161c6 lib/unicore/version
* 913d2f93f3cb6cdf1664db888bf840bc4eb074eef824e082fceda24a9445e60c regen/charset_translations.pl
* d9c04ac46bdd81bb3e26519f2b8eb6242cb12337205add3f7cf092b0c58dccc4 regen/regcharclass.pl
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
/* this is a chain of data about sub patterns we are processing that
need to be handled separately/specially in study_chunk. Its so
we can simulate recursion without losing state. */
I32 seen_zerolen;
regnode **open_parens; /* pointers to open parens */
regnode **close_parens; /* pointers to close parens */
- regnode *opend; /* END node in program */
+ regnode *end_op; /* END node in program */
I32 utf8; /* whether the pattern is utf8 or not */
I32 orig_utf8; /* whether the pattern was originally in utf8 */
/* XXX use this for future optimisation of case
HV *paren_names; /* Paren names */
regnode **recurse; /* Recurse regops */
- I32 recurse_count; /* Number of recurse regops */
+ I32 recurse_count; /* Number of recurse regops we have generated */
U8 *study_chunk_recursed; /* bitmap of which subs we have moved
through */
U32 study_chunk_recursed_bytes; /* bytes in bitmap */
#define RExC_orig_utf8 (pRExC_state->orig_utf8)
#define RExC_open_parens (pRExC_state->open_parens)
#define RExC_close_parens (pRExC_state->close_parens)
-#define RExC_opend (pRExC_state->opend)
+#define RExC_end_op (pRExC_state->end_op)
#define RExC_paren_names (pRExC_state->paren_names)
#define RExC_recurse (pRExC_state->recurse)
#define RExC_recurse_count (pRExC_state->recurse_count)
#define SF_HAS_PAR 0x0080
#define SF_IN_PAR 0x0100
#define SF_HAS_EVAL 0x0200
+
+
+/* SCF_DO_SUBSTR is the flag that tells the regexp analyzer to track the
+ * longest substring in the pattern. When it is not set the optimiser keeps
+ * track of position, but does not keep track of the actual strings seen,
+ *
+ * So for instance /foo/ will be parsed with SCF_DO_SUBSTR being true, but
+ * /foo/i will not.
+ *
+ * Similarly, /foo.*(blah|erm|huh).*fnorble/ will have "foo" and "fnorble"
+ * parsed with SCF_DO_SUBSTR on, but while processing the (...) it will be
+ * turned off because of the alternation (BRANCH). */
#define SCF_DO_SUBSTR 0x0400
+
#define SCF_DO_STCLASS_AND 0x0800
#define SCF_DO_STCLASS_OR 0x1000
#define SCF_DO_STCLASS (SCF_DO_STCLASS_AND|SCF_DO_STCLASS_OR)
#define EXPERIMENTAL_INPLACESCAN
#endif /*PERL_ENABLE_EXPERIMENTAL_REGEX_OPTIMISATIONS*/
-#define DEBUG_RExC_seen() \
+#ifdef DEBUGGING
+int
+Perl_re_printf(pTHX_ const char *fmt, ...)
+{
+ va_list ap;
+ int result;
+ PerlIO *f= Perl_debug_log;
+ PERL_ARGS_ASSERT_RE_PRINTF;
+ va_start(ap, fmt);
+ result = PerlIO_vprintf(f, fmt, ap);
+ va_end(ap);
+ return result;
+}
+
+int
+Perl_re_indentf(pTHX_ const char *fmt, U32 depth, ...)
+{
+ va_list ap;
+ int result;
+ PerlIO *f= Perl_debug_log;
+ PERL_ARGS_ASSERT_RE_INDENTF;
+ va_start(ap, depth);
+ PerlIO_printf(f, "%*s", ( depth % 20 ) * 2, "");
+ result = PerlIO_vprintf(f, fmt, ap);
+ va_end(ap);
+ return result;
+}
+#endif /* DEBUGGING */
+
+#define DEBUG_RExC_seen() \
DEBUG_OPTIMISE_MORE_r({ \
- PerlIO_printf(Perl_debug_log,"RExC_seen: "); \
+ Perl_re_printf( aTHX_ "RExC_seen: "); \
\
if (RExC_seen & REG_ZERO_LEN_SEEN) \
- PerlIO_printf(Perl_debug_log,"REG_ZERO_LEN_SEEN "); \
+ Perl_re_printf( aTHX_ "REG_ZERO_LEN_SEEN "); \
\
if (RExC_seen & REG_LOOKBEHIND_SEEN) \
- PerlIO_printf(Perl_debug_log,"REG_LOOKBEHIND_SEEN "); \
+ Perl_re_printf( aTHX_ "REG_LOOKBEHIND_SEEN "); \
\
if (RExC_seen & REG_GPOS_SEEN) \
- PerlIO_printf(Perl_debug_log,"REG_GPOS_SEEN "); \
+ Perl_re_printf( aTHX_ "REG_GPOS_SEEN "); \
\
if (RExC_seen & REG_RECURSE_SEEN) \
- PerlIO_printf(Perl_debug_log,"REG_RECURSE_SEEN "); \
+ Perl_re_printf( aTHX_ "REG_RECURSE_SEEN "); \
\
- if (RExC_seen & REG_TOP_LEVEL_BRANCHES_SEEN) \
- PerlIO_printf(Perl_debug_log,"REG_TOP_LEVEL_BRANCHES_SEEN "); \
+ if (RExC_seen & REG_TOP_LEVEL_BRANCHES_SEEN) \
+ Perl_re_printf( aTHX_ "REG_TOP_LEVEL_BRANCHES_SEEN "); \
\
if (RExC_seen & REG_VERBARG_SEEN) \
- PerlIO_printf(Perl_debug_log,"REG_VERBARG_SEEN "); \
+ Perl_re_printf( aTHX_ "REG_VERBARG_SEEN "); \
\
if (RExC_seen & REG_CUTGROUP_SEEN) \
- PerlIO_printf(Perl_debug_log,"REG_CUTGROUP_SEEN "); \
+ Perl_re_printf( aTHX_ "REG_CUTGROUP_SEEN "); \
\
if (RExC_seen & REG_RUN_ON_COMMENT_SEEN) \
- PerlIO_printf(Perl_debug_log,"REG_RUN_ON_COMMENT_SEEN "); \
+ Perl_re_printf( aTHX_ "REG_RUN_ON_COMMENT_SEEN "); \
\
if (RExC_seen & REG_UNFOLDED_MULTI_SEEN) \
- PerlIO_printf(Perl_debug_log,"REG_UNFOLDED_MULTI_SEEN "); \
+ Perl_re_printf( aTHX_ "REG_UNFOLDED_MULTI_SEEN "); \
\
- if (RExC_seen & REG_GOSTART_SEEN) \
- PerlIO_printf(Perl_debug_log,"REG_GOSTART_SEEN "); \
+ if (RExC_seen & REG_UNBOUNDED_QUANTIFIER_SEEN) \
+ Perl_re_printf( aTHX_ "REG_UNBOUNDED_QUANTIFIER_SEEN "); \
\
- if (RExC_seen & REG_UNBOUNDED_QUANTIFIER_SEEN) \
- PerlIO_printf(Perl_debug_log,"REG_UNBOUNDED_QUANTIFIER_SEEN "); \
- \
- PerlIO_printf(Perl_debug_log,"\n"); \
+ Perl_re_printf( aTHX_ "\n"); \
});
#define DEBUG_SHOW_STUDY_FLAG(flags,flag) \
- if ((flags) & flag) PerlIO_printf(Perl_debug_log, "%s ", #flag)
+ if ((flags) & flag) Perl_re_printf( aTHX_ "%s ", #flag)
#define DEBUG_SHOW_STUDY_FLAGS(flags,open_str,close_str) \
if ( ( flags ) ) { \
- PerlIO_printf(Perl_debug_log, "%s", open_str); \
+ Perl_re_printf( aTHX_ "%s", open_str); \
DEBUG_SHOW_STUDY_FLAG(flags,SF_FL_BEFORE_SEOL); \
DEBUG_SHOW_STUDY_FLAG(flags,SF_FL_BEFORE_MEOL); \
DEBUG_SHOW_STUDY_FLAG(flags,SF_IS_INF); \
DEBUG_SHOW_STUDY_FLAG(flags,SCF_SEEN_ACCEPT); \
DEBUG_SHOW_STUDY_FLAG(flags,SCF_TRIE_DOING_RESTUDY); \
DEBUG_SHOW_STUDY_FLAG(flags,SCF_IN_DEFINE); \
- PerlIO_printf(Perl_debug_log, "%s", close_str); \
+ Perl_re_printf( aTHX_ "%s", close_str); \
}
#define DEBUG_STUDYDATA(str,data,depth) \
DEBUG_OPTIMISE_MORE_r(if(data){ \
- PerlIO_printf(Perl_debug_log, \
- "%*s" str "Pos:%"IVdf"/%"IVdf \
+ Perl_re_indentf( aTHX_ "" str "Pos:%"IVdf"/%"IVdf \
" Flags: 0x%"UVXf, \
- (int)(depth)*2, "", \
+ depth, \
(IV)((data)->pos_min), \
(IV)((data)->pos_delta), \
(UV)((data)->flags) \
); \
DEBUG_SHOW_STUDY_FLAGS((data)->flags," [ ","]"); \
- PerlIO_printf(Perl_debug_log, \
+ Perl_re_printf( aTHX_ \
" Whilem_c: %"IVdf" Lcp: %"IVdf" %s", \
(IV)((data)->whilem_c), \
(IV)((data)->last_closep ? *((data)->last_closep) : -1), \
is_inf ? "INF " : "" \
); \
if ((data)->last_found) \
- PerlIO_printf(Perl_debug_log, \
+ Perl_re_printf( aTHX_ \
"Last:'%s' %"IVdf":%"IVdf"/%"IVdf" %sFixed:'%s' @ %"IVdf \
" %sFloat: '%s' @ %"IVdf"/%"IVdf"", \
SvPVX_const((data)->last_found), \
(IV)((data)->offset_float_min), \
(IV)((data)->offset_float_max) \
); \
- PerlIO_printf(Perl_debug_log,"\n"); \
+ Perl_re_printf( aTHX_ "\n"); \
});
+
/* =========================================================
* BEGIN edit_distance stuff.
*
* returned list must, and will, contain every code point that is a
* possibility. */
- SV* invlist = sv_2mortal(_new_invlist(0));
+ SV* invlist = NULL;
SV* only_utf8_locale_invlist = NULL;
unsigned int i;
const U32 n = ARG(node);
/* Here, no compile-time swash, and there are things that won't be
* known until runtime -- we have to assume it could be anything */
+ invlist = sv_2mortal(_new_invlist(1));
return _add_range_to_invlist(invlist, 0, UV_MAX);
}
else if (ary[3] && ary[3] != &PL_sv_undef) {
}
}
+ if (! invlist) {
+ invlist = sv_2mortal(_new_invlist(0));
+ }
+
/* An ANYOF node contains a bitmap for the first NUM_ANYOF_CODE_POINTS
* code points, and an inversion list for the others, but if there are code
* points that should match only conditionally on the target string being
/* Add in the points from the bit map */
for (i = 0; i < NUM_ANYOF_CODE_POINTS; i++) {
if (ANYOF_BITMAP_TEST(node, i)) {
- invlist = add_cp_to_invlist(invlist, i);
+ unsigned int start = i++;
+
+ for (; i < NUM_ANYOF_CODE_POINTS && ANYOF_BITMAP_TEST(node, i); ++i) {
+ /* empty */
+ }
+ invlist = _add_range_to_invlist(invlist, start, i-1);
new_node_has_latin1 = TRUE;
}
}
PERL_ARGS_ASSERT_DUMP_TRIE;
- PerlIO_printf( Perl_debug_log, "%*sChar : %-6s%-6s%-4s ",
- (int)depth * 2 + 2,"",
- "Match","Base","Ofs" );
+ Perl_re_indentf( aTHX_ "Char : %-6s%-6s%-4s ",
+ depth+1, "Match","Base","Ofs" );
for( state = 0 ; state < trie->uniquecharcount ; state++ ) {
SV ** const tmp = av_fetch( revcharmap, state, 0);
if ( tmp ) {
- PerlIO_printf( Perl_debug_log, "%*s",
+ Perl_re_printf( aTHX_ "%*s",
colwidth,
pv_pretty(sv, SvPV_nolen_const(*tmp), SvCUR(*tmp), colwidth,
PL_colors[0], PL_colors[1],
);
}
}
- PerlIO_printf( Perl_debug_log, "\n%*sState|-----------------------",
- (int)depth * 2 + 2,"");
+ Perl_re_printf( aTHX_ "\n");
+ Perl_re_indentf( aTHX_ "State|-----------------------", depth+1);
for( state = 0 ; state < trie->uniquecharcount ; state++ )
- PerlIO_printf( Perl_debug_log, "%.*s", colwidth, "--------");
- PerlIO_printf( Perl_debug_log, "\n");
+ Perl_re_printf( aTHX_ "%.*s", colwidth, "--------");
+ Perl_re_printf( aTHX_ "\n");
for( state = 1 ; state < trie->statecount ; state++ ) {
const U32 base = trie->states[ state ].trans.base;
- PerlIO_printf( Perl_debug_log, "%*s#%4"UVXf"|",
- (int)depth * 2 + 2,"", (UV)state);
+ Perl_re_indentf( aTHX_ "#%4"UVXf"|", depth+1, (UV)state);
if ( trie->states[ state ].wordnum ) {
- PerlIO_printf( Perl_debug_log, " W%4X",
- trie->states[ state ].wordnum );
+ Perl_re_printf( aTHX_ " W%4X", trie->states[ state ].wordnum );
} else {
- PerlIO_printf( Perl_debug_log, "%6s", "" );
+ Perl_re_printf( aTHX_ "%6s", "" );
}
- PerlIO_printf( Perl_debug_log, " @%4"UVXf" ", (UV)base );
+ Perl_re_printf( aTHX_ " @%4"UVXf" ", (UV)base );
if ( base ) {
U32 ofs = 0;
!= state))
ofs++;
- PerlIO_printf( Perl_debug_log, "+%2"UVXf"[ ", (UV)ofs);
+ Perl_re_printf( aTHX_ "+%2"UVXf"[ ", (UV)ofs);
for ( ofs = 0 ; ofs < trie->uniquecharcount ; ofs++ ) {
if ( ( base + ofs >= trie->uniquecharcount )
&& trie->trans[ base + ofs
- trie->uniquecharcount ].check == state )
{
- PerlIO_printf( Perl_debug_log, "%*"UVXf,
- colwidth,
- (UV)trie->trans[ base + ofs
- - trie->uniquecharcount ].next );
+ Perl_re_printf( aTHX_ "%*"UVXf, colwidth,
+ (UV)trie->trans[ base + ofs - trie->uniquecharcount ].next
+ );
} else {
- PerlIO_printf( Perl_debug_log, "%*s",colwidth," ." );
+ Perl_re_printf( aTHX_ "%*s",colwidth," ." );
}
}
- PerlIO_printf( Perl_debug_log, "]");
+ Perl_re_printf( aTHX_ "]");
}
- PerlIO_printf( Perl_debug_log, "\n" );
+ Perl_re_printf( aTHX_ "\n" );
}
- PerlIO_printf(Perl_debug_log, "%*sword_info N:(prev,len)=",
- (int)depth*2, "");
+ Perl_re_indentf( aTHX_ "word_info N:(prev,len)=",
+ depth);
for (word=1; word <= trie->wordcount; word++) {
- PerlIO_printf(Perl_debug_log, " %d:(%d,%d)",
+ Perl_re_printf( aTHX_ " %d:(%d,%d)",
(int)word, (int)(trie->wordinfo[word].prev),
(int)(trie->wordinfo[word].len));
}
- PerlIO_printf(Perl_debug_log, "\n" );
+ Perl_re_printf( aTHX_ "\n" );
}
/*
Dumps a fully constructed but uncompressed trie in list form.
PERL_ARGS_ASSERT_DUMP_TRIE_INTERIM_LIST;
/* print out the table precompression. */
- PerlIO_printf( Perl_debug_log, "%*sState :Word | Transition Data\n%*s%s",
- (int)depth * 2 + 2,"", (int)depth * 2 + 2,"",
- "------:-----+-----------------\n" );
+ Perl_re_indentf( aTHX_ "State :Word | Transition Data\n",
+ depth+1 );
+ Perl_re_indentf( aTHX_ "%s",
+ depth+1, "------:-----+-----------------\n" );
for( state=1 ; state < next_alloc ; state ++ ) {
U16 charid;
- PerlIO_printf( Perl_debug_log, "%*s %4"UVXf" :",
- (int)depth * 2 + 2,"", (UV)state );
+ Perl_re_indentf( aTHX_ " %4"UVXf" :",
+ depth+1, (UV)state );
if ( ! trie->states[ state ].wordnum ) {
- PerlIO_printf( Perl_debug_log, "%5s| ","");
+ Perl_re_printf( aTHX_ "%5s| ","");
} else {
- PerlIO_printf( Perl_debug_log, "W%4x| ",
+ Perl_re_printf( aTHX_ "W%4x| ",
trie->states[ state ].wordnum
);
}
SV ** const tmp = av_fetch( revcharmap,
TRIE_LIST_ITEM(state,charid).forid, 0);
if ( tmp ) {
- PerlIO_printf( Perl_debug_log, "%*s:%3X=%4"UVXf" | ",
+ Perl_re_printf( aTHX_ "%*s:%3X=%4"UVXf" | ",
colwidth,
pv_pretty(sv, SvPV_nolen_const(*tmp), SvCUR(*tmp),
colwidth,
(UV)TRIE_LIST_ITEM(state,charid).newstate
);
if (!(charid % 10))
- PerlIO_printf(Perl_debug_log, "\n%*s| ",
+ Perl_re_printf( aTHX_ "\n%*s| ",
(int)((depth * 2) + 14), "");
}
}
- PerlIO_printf( Perl_debug_log, "\n");
+ Perl_re_printf( aTHX_ "\n");
}
}
that they are identical.
*/
- PerlIO_printf( Perl_debug_log, "%*sChar : ",(int)depth * 2 + 2,"" );
+ Perl_re_indentf( aTHX_ "Char : ", depth+1 );
for( charid = 0 ; charid < trie->uniquecharcount ; charid++ ) {
SV ** const tmp = av_fetch( revcharmap, charid, 0);
if ( tmp ) {
- PerlIO_printf( Perl_debug_log, "%*s",
+ Perl_re_printf( aTHX_ "%*s",
colwidth,
pv_pretty(sv, SvPV_nolen_const(*tmp), SvCUR(*tmp), colwidth,
PL_colors[0], PL_colors[1],
}
}
- PerlIO_printf( Perl_debug_log, "\n%*sState+-",(int)depth * 2 + 2,"" );
+ Perl_re_printf( aTHX_ "\n%*sState+-",depth+1 );
for( charid=0 ; charid < trie->uniquecharcount ; charid++ ) {
- PerlIO_printf( Perl_debug_log, "%.*s", colwidth,"--------");
+ Perl_re_printf( aTHX_ "%.*s", colwidth,"--------");
}
- PerlIO_printf( Perl_debug_log, "\n" );
+ Perl_re_printf( aTHX_ "\n" );
for( state=1 ; state < next_alloc ; state += trie->uniquecharcount ) {
- PerlIO_printf( Perl_debug_log, "%*s%4"UVXf" : ",
- (int)depth * 2 + 2,"",
+ Perl_re_indentf( aTHX_ "%4"UVXf" : ",
+ depth+1,
(UV)TRIE_NODENUM( state ) );
for( charid = 0 ; charid < trie->uniquecharcount ; charid++ ) {
UV v=(UV)SAFE_TRIE_NODENUM( trie->trans[ state + charid ].next );
if (v)
- PerlIO_printf( Perl_debug_log, "%*"UVXf, colwidth, v );
+ Perl_re_printf( aTHX_ "%*"UVXf, colwidth, v );
else
- PerlIO_printf( Perl_debug_log, "%*s", colwidth, "." );
+ Perl_re_printf( aTHX_ "%*s", colwidth, "." );
}
if ( ! trie->states[ TRIE_NODENUM( state ) ].wordnum ) {
- PerlIO_printf( Perl_debug_log, " (%4"UVXf")\n",
+ Perl_re_printf( aTHX_ " (%4"UVXf")\n",
(UV)trie->trans[ state ].check );
} else {
- PerlIO_printf( Perl_debug_log, " (%4"UVXf") W%4X\n",
+ Perl_re_printf( aTHX_ " (%4"UVXf") W%4X\n",
(UV)trie->trans[ state ].check,
trie->states[ TRIE_NODENUM( state ) ].wordnum );
}
sv_setiv(re_trie_maxbuff, RE_TRIE_MAXBUF_INIT);
}
DEBUG_TRIE_COMPILE_r({
- PerlIO_printf( Perl_debug_log,
- "%*smake_trie start==%d, first==%d, last==%d, tail==%d depth=%d\n",
- (int)depth * 2 + 2, "",
+ Perl_re_indentf( aTHX_
+ "make_trie start==%d, first==%d, last==%d, tail==%d depth=%d\n",
+ depth+1,
REG_NODE_NUM(startbranch),REG_NODE_NUM(first),
REG_NODE_NUM(last), REG_NODE_NUM(tail), (int)depth);
});
for ( cur = first ; cur < last ; cur = regnext( cur ) ) {
regnode *noper = NEXTOPER( cur );
- const U8 *uc = (U8*)STRING( noper );
- const U8 *e = uc + STR_LEN( noper );
+ const U8 *uc;
+ const U8 *e;
int foldlen = 0;
U32 wordlen = 0; /* required init */
STRLEN minchars = 0;
if (OP(noper) == NOTHING) {
regnode *noper_next= regnext(noper);
- if (noper_next != tail && OP(noper_next) == flags) {
- noper = noper_next;
- uc= (U8*)STRING(noper);
- e= uc + STR_LEN(noper);
- trie->minlen= STR_LEN(noper);
- } else {
- trie->minlen= 0;
- continue;
- }
+ if (noper_next < tail)
+ noper= noper_next;
}
+ if ( noper < tail && ( OP(noper) == flags || ( flags == EXACTFU && OP(noper) == EXACTFU_SS ) ) ) {
+ uc= (U8*)STRING(noper);
+ e= uc + STR_LEN(noper);
+ } else {
+ trie->minlen= 0;
+ continue;
+ }
+
+
if ( set_bit ) { /* bitmap only alloced when !(UTF&&Folding) */
TRIE_BITMAP_SET(trie,*uc); /* store the raw first byte
regardless of encoding */
}
} /* end first pass */
DEBUG_TRIE_COMPILE_r(
- PerlIO_printf( Perl_debug_log,
- "%*sTRIE(%s): W:%d C:%d Uq:%d Min:%d Max:%d\n",
- (int)depth * 2 + 2,"",
+ Perl_re_indentf( aTHX_
+ "TRIE(%s): W:%d C:%d Uq:%d Min:%d Max:%d\n",
+ depth+1,
( widecharmap ? "UTF8" : "NATIVE" ), (int)word_count,
(int)TRIE_CHARCOUNT(trie), trie->uniquecharcount,
(int)trie->minlen, (int)trie->maxlen )
STRLEN transcount = 1;
- DEBUG_TRIE_COMPILE_MORE_r( PerlIO_printf( Perl_debug_log,
- "%*sCompiling trie using list compiler\n",
- (int)depth * 2 + 2, ""));
+ DEBUG_TRIE_COMPILE_MORE_r( Perl_re_indentf( aTHX_ "Compiling trie using list compiler\n",
+ depth+1));
trie->states = (reg_trie_state *)
PerlMemShared_calloc( TRIE_CHARCOUNT(trie) + 2,
for ( cur = first ; cur < last ; cur = regnext( cur ) ) {
regnode *noper = NEXTOPER( cur );
- U8 *uc = (U8*)STRING( noper );
- const U8 *e = uc + STR_LEN( noper );
U32 state = 1; /* required init */
U16 charid = 0; /* sanity init */
U32 wordlen = 0; /* required init */
if (OP(noper) == NOTHING) {
regnode *noper_next= regnext(noper);
- if (noper_next != tail && OP(noper_next) == flags) {
- noper = noper_next;
- uc= (U8*)STRING(noper);
- e= uc + STR_LEN(noper);
- }
+ if (noper_next < tail)
+ noper= noper_next;
}
- if (OP(noper) != NOTHING) {
+ if ( noper < tail && ( OP(noper) == flags || ( flags == EXACTFU && OP(noper) == EXACTFU_SS ) ) ) {
+ const U8 *uc= (U8*)STRING(noper);
+ const U8 *e= uc + STR_LEN(noper);
+
for ( ; uc < e ; uc += len ) {
TRIE_READ_CHAR;
/*
DEBUG_TRIE_COMPILE_MORE_r(
- PerlIO_printf( Perl_debug_log, "tp: %d zp: %d ",tp,zp)
+ Perl_re_printf( aTHX_ "tp: %d zp: %d ",tp,zp)
);
*/
}
/*
DEBUG_TRIE_COMPILE_MORE_r(
- PerlIO_printf( Perl_debug_log, " base: %d\n",base);
+ Perl_re_printf( aTHX_ " base: %d\n",base);
);
*/
trie->states[ state ].trans.base=base;
we have to use TRIE_NODENUM() to convert.
*/
- DEBUG_TRIE_COMPILE_MORE_r( PerlIO_printf( Perl_debug_log,
- "%*sCompiling trie using table compiler\n",
- (int)depth * 2 + 2, ""));
+ DEBUG_TRIE_COMPILE_MORE_r( Perl_re_indentf( aTHX_ "Compiling trie using table compiler\n",
+ depth+1));
trie->trans = (reg_trie_trans *)
PerlMemShared_calloc( ( TRIE_CHARCOUNT(trie) + 1 )
for ( cur = first ; cur < last ; cur = regnext( cur ) ) {
regnode *noper = NEXTOPER( cur );
- const U8 *uc = (U8*)STRING( noper );
- const U8 *e = uc + STR_LEN( noper );
U32 state = 1; /* required init */
if (OP(noper) == NOTHING) {
regnode *noper_next= regnext(noper);
- if (noper_next != tail && OP(noper_next) == flags) {
- noper = noper_next;
- uc= (U8*)STRING(noper);
- e= uc + STR_LEN(noper);
- }
+ if (noper_next < tail)
+ noper= noper_next;
}
- if ( OP(noper) != NOTHING ) {
+ if ( noper < tail && ( OP(noper) == flags || ( flags == EXACTFU && OP(noper) == EXACTFU_SS ) ) ) {
+ const U8 *uc= (U8*)STRING(noper);
+ const U8 *e= uc + STR_LEN(noper);
+
for ( ; uc < e ; uc += len ) {
TRIE_READ_CHAR;
PerlMemShared_realloc( trie->states, laststate
* sizeof(reg_trie_state) );
DEBUG_TRIE_COMPILE_MORE_r(
- PerlIO_printf( Perl_debug_log,
- "%*sAlloc: %d Orig: %"IVdf" elements, Final:%"IVdf". Savings of %%%5.2f\n",
- (int)depth * 2 + 2,"",
+ Perl_re_indentf( aTHX_ "Alloc: %d Orig: %"IVdf" elements, Final:%"IVdf". Savings of %%%5.2f\n",
+ depth+1,
(int)( ( TRIE_CHARCOUNT(trie) + 1 ) * trie->uniquecharcount
+ 1 ),
(IV)next_alloc,
} /* end table compress */
}
DEBUG_TRIE_COMPILE_MORE_r(
- PerlIO_printf(Perl_debug_log,
- "%*sStatecount:%"UVxf" Lasttrans:%"UVxf"\n",
- (int)depth * 2 + 2, "",
+ Perl_re_indentf( aTHX_ "Statecount:%"UVxf" Lasttrans:%"UVxf"\n",
+ depth+1,
(UV)trie->statecount,
(UV)trie->lasttrans)
);
});
}
DEBUG_OPTIMISE_r(
- PerlIO_printf(Perl_debug_log,
- "%*sMJD offset:%"UVuf" MJD length:%"UVuf"\n",
- (int)depth * 2 + 2, "",
+ Perl_re_indentf( aTHX_ "MJD offset:%"UVuf" MJD length:%"UVuf"\n",
+ depth+1,
(UV)mjd_offset, (UV)mjd_nodelen)
);
#endif
if ( count == 2 ) {
Zero(trie->bitmap, ANYOF_BITMAP_SIZE, char);
DEBUG_OPTIMISE_r(
- PerlIO_printf(Perl_debug_log,
- "%*sNew Start State=%"UVuf" Class: [",
- (int)depth * 2 + 2, "",
+ Perl_re_indentf( aTHX_ "New Start State=%"UVuf" Class: [",
+ depth+1,
(UV)state));
if (idx >= 0) {
SV ** const tmp = av_fetch( revcharmap, idx, 0);
if ( folder )
TRIE_BITMAP_SET(trie, folder[ *ch ]);
DEBUG_OPTIMISE_r(
- PerlIO_printf(Perl_debug_log, "%s", (char*)ch)
+ Perl_re_printf( aTHX_ "%s", (char*)ch)
);
}
}
TRIE_BITMAP_SET(trie,*ch);
if ( folder )
TRIE_BITMAP_SET(trie,folder[ *ch ]);
- DEBUG_OPTIMISE_r(PerlIO_printf( Perl_debug_log,"%s", ch));
+ DEBUG_OPTIMISE_r(Perl_re_printf( aTHX_ "%s", ch));
}
idx = ofs;
}
char *ch = SvPV( *tmp, len );
DEBUG_OPTIMISE_r({
SV *sv=sv_newmortal();
- PerlIO_printf( Perl_debug_log,
- "%*sPrefix State: %"UVuf" Idx:%"UVuf" Char='%s'\n",
- (int)depth * 2 + 2, "",
+ Perl_re_indentf( aTHX_ "Prefix State: %"UVuf" Idx:%"UVuf" Char='%s'\n",
+ depth+1,
(UV)state, (UV)idx,
pv_pretty(sv, SvPV_nolen_const(*tmp), SvCUR(*tmp), 6,
PL_colors[0], PL_colors[1],
} else {
#ifdef DEBUGGING
if (state>1)
- DEBUG_OPTIMISE_r(PerlIO_printf( Perl_debug_log,"]\n"));
+ DEBUG_OPTIMISE_r(Perl_re_printf( aTHX_ "]\n"));
#endif
break;
}
*/
fail[ 0 ] = fail[ 1 ] = 0;
DEBUG_TRIE_COMPILE_r({
- PerlIO_printf(Perl_debug_log,
- "%*sStclass Failtable (%"UVuf" states): 0",
- (int)(depth * 2), "", (UV)numstates
+ Perl_re_indentf( aTHX_ "Stclass Failtable (%"UVuf" states): 0",
+ depth, (UV)numstates
);
for( q_read=1; q_read<numstates; q_read++ ) {
- PerlIO_printf(Perl_debug_log, ", %"UVuf, (UV)fail[q_read]);
+ Perl_re_printf( aTHX_ ", %"UVuf, (UV)fail[q_read]);
}
- PerlIO_printf(Perl_debug_log, "\n");
+ Perl_re_printf( aTHX_ "\n");
});
Safefree(q);
/*RExC_seen |= REG_TRIEDFA_SEEN;*/
}
-#define DEBUG_PEEP(str,scan,depth) \
- DEBUG_OPTIMISE_r({if (scan){ \
- regnode *Next = regnext(scan); \
- regprop(RExC_rx, RExC_mysv, scan, NULL, pRExC_state); \
- PerlIO_printf(Perl_debug_log, "%*s" str ">%3d: %s (%d)", \
- (int)depth*2, "", REG_NODE_NUM(scan), SvPV_nolen_const(RExC_mysv),\
- Next ? (REG_NODE_NUM(Next)) : 0 ); \
+#define DEBUG_PEEP(str,scan,depth) \
+ DEBUG_OPTIMISE_r({if (scan){ \
+ regnode *Next = regnext(scan); \
+ regprop(RExC_rx, RExC_mysv, scan, NULL, pRExC_state);\
+ Perl_re_indentf( aTHX_ "" str ">%3d: %s (%d)", \
+ depth, REG_NODE_NUM(scan), SvPV_nolen_const(RExC_mysv),\
+ Next ? (REG_NODE_NUM(Next)) : 0 );\
DEBUG_SHOW_STUDY_FLAGS(flags," [ ","]");\
- PerlIO_printf(Perl_debug_log, "\n"); \
+ Perl_re_printf( aTHX_ "\n"); \
}});
/* The below joins as many adjacent EXACTish nodes as possible into a single
);
DEBUG_OPTIMISE_MORE_r(
{
- PerlIO_printf(Perl_debug_log,
- "%*sstudy_chunk stopparen=%ld recursed_count=%lu depth=%lu recursed_depth=%lu scan=%p last=%p",
- (int)(depth*2), "", (long)stopparen,
+ Perl_re_indentf( aTHX_ "study_chunk stopparen=%ld recursed_count=%lu depth=%lu recursed_depth=%lu scan=%p last=%p",
+ depth, (long)stopparen,
(unsigned long)RExC_study_chunk_recursed_count,
(unsigned long)depth, (unsigned long)recursed_depth,
scan,
(( j - 1 ) * RExC_study_chunk_recursed_bytes), i)
)
) {
- PerlIO_printf(Perl_debug_log," %d",(int)i);
+ Perl_re_printf( aTHX_ " %d",(int)i);
break;
}
}
if ( j + 1 < recursed_depth ) {
- PerlIO_printf(Perl_debug_log, ",");
+ Perl_re_printf( aTHX_ ",");
}
}
}
- PerlIO_printf(Perl_debug_log,"\n");
+ Perl_re_printf( aTHX_ "\n");
}
);
while ( scan && OP(scan) != END && scan < last ){
DEBUG_PEEP("Peep", scan, depth);
- /* The reason we do this here we need to deal with things like /(?:f)(?:o)(?:o)/
- * which cant be dealt with by the normal EXACT parsing code, as each (?:..) is handled
- * by a different invocation of reg() -- Yves
+ /* The reason we do this here is that we need to deal with things like
+ * /(?:f)(?:o)(?:o)/ which cant be dealt with by the normal EXACT
+ * parsing code, as each (?:..) is handled by a different invocation of
+ * reg() -- Yves
*/
JOIN_EXACT(scan,&min_subtract, &unfolded_multi_char, 0);
DEBUG_TRIE_COMPILE_r({
regprop(RExC_rx, RExC_mysv, tail, NULL, pRExC_state);
- PerlIO_printf( Perl_debug_log, "%*s%s%s\n",
- (int)depth * 2 + 2, "",
- "Looking for TRIE'able sequences. Tail node is: ",
+ Perl_re_indentf( aTHX_ "%s %"UVuf":%s\n",
+ depth+1,
+ "Looking for TRIE'able sequences. Tail node is ",
+ (UV)(tail - RExC_emit_start),
SvPV_nolen_const( RExC_mysv )
);
});
U8 noper_trietype = TRIE_TYPE( noper_type );
#if defined(DEBUGGING) || defined(NOJUMPTRIE)
regnode * const noper_next = regnext( noper );
- U8 noper_next_type = (noper_next && noper_next != tail) ? OP(noper_next) : 0;
- U8 noper_next_trietype = (noper_next && noper_next != tail) ? TRIE_TYPE( noper_next_type ) :0;
+ U8 noper_next_type = (noper_next && noper_next < tail) ? OP(noper_next) : 0;
+ U8 noper_next_trietype = (noper_next && noper_next < tail) ? TRIE_TYPE( noper_next_type ) :0;
#endif
DEBUG_TRIE_COMPILE_r({
regprop(RExC_rx, RExC_mysv, cur, NULL, pRExC_state);
- PerlIO_printf( Perl_debug_log, "%*s- %s (%d)",
- (int)depth * 2 + 2,"", SvPV_nolen_const( RExC_mysv ), REG_NODE_NUM(cur) );
+ Perl_re_indentf( aTHX_ "- %d:%s (%d)",
+ depth+1,
+ REG_NODE_NUM(cur), SvPV_nolen_const( RExC_mysv ), REG_NODE_NUM(cur) );
regprop(RExC_rx, RExC_mysv, noper, NULL, pRExC_state);
- PerlIO_printf( Perl_debug_log, " -> %s",
- SvPV_nolen_const(RExC_mysv));
+ Perl_re_printf( aTHX_ " -> %d:%s",
+ REG_NODE_NUM(noper), SvPV_nolen_const(RExC_mysv));
if ( noper_next ) {
regprop(RExC_rx, RExC_mysv, noper_next, NULL, pRExC_state);
- PerlIO_printf( Perl_debug_log,"\t=> %s\t",
- SvPV_nolen_const(RExC_mysv));
+ Perl_re_printf( aTHX_ "\t=> %d:%s\t",
+ REG_NODE_NUM(noper_next), SvPV_nolen_const(RExC_mysv));
}
- PerlIO_printf( Perl_debug_log, "(First==%d,Last==%d,Cur==%d,tt==%s,nt==%s,nnt==%s)\n",
+ Perl_re_printf( aTHX_ "(First==%d,Last==%d,Cur==%d,tt==%s,ntt==%s,nntt==%s)\n",
REG_NODE_NUM(first), REG_NODE_NUM(last), REG_NODE_NUM(cur),
PL_reg_name[trietype], PL_reg_name[noper_trietype], PL_reg_name[noper_next_trietype]
);
if ( noper_trietype
&&
(
- ( noper_trietype == NOTHING)
+ ( noper_trietype == NOTHING )
|| ( trietype == NOTHING )
|| ( trietype == noper_trietype )
)
#ifdef NOJUMPTRIE
- && noper_next == tail
+ && noper_next >= tail
#endif
&& count < U16_MAX)
{
if ( noper_trietype == NOTHING ) {
#if !defined(DEBUGGING) && !defined(NOJUMPTRIE)
regnode * const noper_next = regnext( noper );
- U8 noper_next_type = (noper_next && noper_next!=tail) ? OP(noper_next) : 0;
+ U8 noper_next_type = (noper_next && noper_next < tail) ? OP(noper_next) : 0;
U8 noper_next_trietype = noper_next_type ? TRIE_TYPE( noper_next_type ) :0;
#endif
}
if ( noper_trietype
#ifdef NOJUMPTRIE
- && noper_next == tail
+ && noper_next >= tail
#endif
){
/* noper is triable, so we can start a new
} /* loop over branches */
DEBUG_TRIE_COMPILE_r({
regprop(RExC_rx, RExC_mysv, cur, NULL, pRExC_state);
- PerlIO_printf( Perl_debug_log,
- "%*s- %s (%d) <SCAN FINISHED>\n",
- (int)depth * 2 + 2,
- "", SvPV_nolen_const( RExC_mysv ),REG_NODE_NUM(cur));
+ Perl_re_indentf( aTHX_ "- %s (%d) <SCAN FINISHED> ",
+ depth+1, SvPV_nolen_const( RExC_mysv ),REG_NODE_NUM(cur));
+ Perl_re_printf( aTHX_ "(First==%d, Last==%d, Cur==%d, tt==%s)\n",
+ REG_NODE_NUM(first), REG_NODE_NUM(last), REG_NODE_NUM(cur),
+ PL_reg_name[trietype]
+ );
});
if ( last && trietype ) {
depth==0 ) {
flags |= SCF_TRIE_RESTUDY;
if ( startbranch == first
- && scan == tail )
+ && scan >= tail )
{
RExC_seen &=~REG_TOP_LEVEL_BRANCHES_SEEN;
}
* turn it into a plain NOTHING op. */
DEBUG_TRIE_COMPILE_r({
regprop(RExC_rx, RExC_mysv, cur, NULL, pRExC_state);
- PerlIO_printf( Perl_debug_log,
- "%*s- %s (%d) <NOTHING BRANCH SEQUENCE>\n", (int)depth * 2 + 2,
- "", SvPV_nolen_const( RExC_mysv ),REG_NODE_NUM(cur));
+ Perl_re_indentf( aTHX_ "- %s (%d) <NOTHING BRANCH SEQUENCE>\n",
+ depth+1,
+ SvPV_nolen_const( RExC_mysv ),REG_NODE_NUM(cur));
});
OP(startbranch)= NOTHING;
} else /* single branch is optimized. */
scan = NEXTOPER(scan);
continue;
- } else if (OP(scan) == SUSPEND || OP(scan) == GOSUB || OP(scan) == GOSTART) {
+ } else if (OP(scan) == SUSPEND || OP(scan) == GOSUB) {
I32 paren = 0;
regnode *start = NULL;
regnode *end = NULL;
U32 my_recursed_depth= recursed_depth;
-
- if (OP(scan) != SUSPEND) { /* GOSUB/GOSTART */
+ if (OP(scan) != SUSPEND) { /* GOSUB */
/* Do setup, note this code has side effects beyond
* the rest of this block. Specifically setting
* RExC_recurse[] must happen at least once during
* study_chunk(). */
- if (OP(scan) == GOSUB) {
- paren = ARG(scan);
- RExC_recurse[ARG2L(scan)] = scan;
- start = RExC_open_parens[paren-1];
- end = RExC_close_parens[paren-1];
- } else {
- start = RExC_rxi->program + 1;
- end = RExC_opend;
- }
+ paren = ARG(scan);
+ RExC_recurse[ARG2L(scan)] = scan;
+ start = RExC_open_parens[paren];
+ end = RExC_close_parens[paren];
+
/* NOTE we MUST always execute the above code, even
- * if we do nothing with a GOSUB/GOSTART */
+ * if we do nothing with a GOSUB */
if (
( flags & SCF_IN_DEFINE )
||
RExC_study_chunk_recursed_bytes, U8);
}
/* we havent recursed into this paren yet, so recurse into it */
- DEBUG_STUDYDATA("set:", data,depth);
+ DEBUG_STUDYDATA("gosub-set:", data,depth);
PAREN_SET(RExC_study_chunk_recursed + (recursed_depth * RExC_study_chunk_recursed_bytes), paren);
my_recursed_depth= recursed_depth + 1;
} else {
- DEBUG_STUDYDATA("inf:", data,depth);
+ DEBUG_STUDYDATA("gosub-inf:", data,depth);
/* some form of infinite recursion, assume infinite length
* */
if (flags & SCF_DO_SUBSTR) {
if (OP(nxt) != CLOSE)
goto nogo;
if (RExC_open_parens) {
- RExC_open_parens[ARG(nxt1)-1]=oscan; /*open->CURLYM*/
- RExC_close_parens[ARG(nxt1)-1]=nxt+2; /*close->while*/
+ RExC_open_parens[ARG(nxt1)]=oscan; /*open->CURLYM*/
+ RExC_close_parens[ARG(nxt1)]=nxt+2; /*close->while*/
}
/* Now we know that nxt2 is the only contents: */
oscan->flags = (U8)ARG(nxt);
oscan->flags = (U8)ARG(nxt);
if (RExC_open_parens) {
- RExC_open_parens[ARG(nxt1)-1]=oscan; /*open->CURLYM*/
- RExC_close_parens[ARG(nxt1)-1]=nxt2+1; /*close->NOTHING*/
+ RExC_open_parens[ARG(nxt1)]=oscan; /*open->CURLYM*/
+ RExC_close_parens[ARG(nxt1)]=nxt2+1; /*close->NOTHING*/
}
OP(nxt1) = OPTIMIZED; /* was OPEN. */
OP(nxt) = OPTIMIZED; /* was CLOSE. */
/* It is counted once already... */
data->pos_min += minnext * (mincount - counted);
#if 0
-PerlIO_printf(Perl_debug_log, "counted=%"UVuf" deltanext=%"UVuf
+Perl_re_printf( aTHX_ "counted=%"UVuf" deltanext=%"UVuf
" SSize_t_MAX=%"UVuf" minnext=%"UVuf
" maxcount=%"UVuf" mincount=%"UVuf"\n",
(UV)counted, (UV)deltanext, (UV)SSize_t_MAX, (UV)minnext, (UV)maxcount,
(UV)mincount);
if (deltanext != SSize_t_MAX)
-PerlIO_printf(Perl_debug_log, "LHS=%"UVuf" RHS=%"UVuf"\n",
+Perl_re_printf( aTHX_ "LHS=%"UVuf" RHS=%"UVuf"\n",
(UV)(-counted * deltanext + (minnext + deltanext) * maxcount
- minnext * mincount), (UV)(SSize_t_MAX - data->pos_delta));
#endif
/* Dispatch a request to compile a regexp to correct regexp engine. */
DEBUG_COMPILE_r({
- PerlIO_printf(Perl_debug_log, "Using engine %"UVxf"\n",
+ Perl_re_printf( aTHX_ "Using engine %"UVxf"\n",
PTR2UV(eng));
});
return CALLREGCOMP_ENG(eng, pattern, flags);
bool do_end = 0;
GET_RE_DEBUG_FLAGS_DECL;
- DEBUG_PARSE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_PARSE_r(Perl_re_printf( aTHX_
"UTF8 mismatch! Converting to utf8 for resizing and compile\n"));
Newx(dst, *plen_p * 2 + 1, U8);
*p++ = 'x';
*p++ = '\0';
DEBUG_COMPILE_r({
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"%sre-parsing pattern for runtime code:%s %s\n",
PL_colors[4],PL_colors[5],newpat);
});
}
- DEBUG_PARSE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_PARSE_r(Perl_re_printf( aTHX_
"Assembling pattern from %d elements%s\n", pat_count,
orig_rx_flags & RXf_SPLIT ? " for split" : ""));
*is_bare_re = TRUE;
SvREFCNT_inc(re);
Safefree(pRExC_state->code_blocks);
- DEBUG_PARSE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_PARSE_r(Perl_re_printf( aTHX_
"Precompiled pattern%s\n",
orig_rx_flags & RXf_SPLIT ? " for split" : ""));
DEBUG_COMPILE_r({
SV *dsv= sv_newmortal();
RE_PV_QUOTED_DECL(s, RExC_utf8, dsv, exp, plen, 60);
- PerlIO_printf(Perl_debug_log, "%sCompiling REx%s %s\n",
+ Perl_re_printf( aTHX_ "%sCompiling REx%s %s\n",
PL_colors[4],PL_colors[5],s);
});
RExC_whilem_seen = 0;
RExC_open_parens = NULL;
RExC_close_parens = NULL;
- RExC_opend = NULL;
+ RExC_end_op = NULL;
RExC_paren_names = NULL;
#ifdef DEBUGGING
RExC_paren_name_list = NULL;
assert(*RExC_end == '\0');
DEBUG_PARSE_r(
- PerlIO_printf(Perl_debug_log, "Starting first pass (sizing)\n");
+ Perl_re_printf( aTHX_ "Starting first pass (sizing)\n");
RExC_lastnum=0;
RExC_lastparse=NULL;
);
pRExC_state->num_code_blocks);
}
else {
- DEBUG_PARSE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_PARSE_r(Perl_re_printf( aTHX_
"Need to redo pass 1\n"));
}
SvLEN_set(code_blocksv,0); /* no you can't have it, sv_clear */
DEBUG_PARSE_r({
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"Required size %"IVdf" nodes\n"
"Starting second pass (creation)\n",
(IV)RExC_size);
r->intflags = 0;
r->nparens = RExC_npar - 1; /* set early to validate backrefs */
- /* setup various meta data about recursion, this all requires
- * RExC_npar to be correctly set, and a bit later on we clear it */
- if (RExC_seen & REG_RECURSE_SEEN) {
- Newxz(RExC_open_parens, RExC_npar,regnode *);
- SAVEFREEPV(RExC_open_parens);
- Newxz(RExC_close_parens,RExC_npar,regnode *);
- SAVEFREEPV(RExC_close_parens);
- }
- if (RExC_seen & (REG_RECURSE_SEEN | REG_GOSTART_SEEN)) {
- /* Note, RExC_npar is 1 + the number of parens in a pattern.
- * So its 1 if there are no parens. */
- RExC_study_chunk_recursed_bytes= (RExC_npar >> 3) +
- ((RExC_npar & 0x07) != 0);
- Newx(RExC_study_chunk_recursed,
- RExC_study_chunk_recursed_bytes * RExC_npar, U8);
- SAVEFREEPV(RExC_study_chunk_recursed);
- }
-
/* Useful during FAIL. */
#ifdef RE_TRACK_PATTERN_OFFSETS
Newxz(ri->u.offsets, 2*RExC_size+1, U32); /* MJD 20001228 */
- DEBUG_OFFSETS_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_OFFSETS_r(Perl_re_printf( aTHX_
"%s %"UVuf" bytes for offset annotations.\n",
ri->u.offsets ? "Got" : "Couldn't get",
(UV)((2*RExC_size+1) * sizeof(U32))));
RExC_parse = exp;
RExC_end = exp + plen;
RExC_naughty = 0;
- RExC_npar = 1;
RExC_emit_start = ri->program;
RExC_emit = ri->program;
RExC_emit_bound = ri->program + RExC_size + 1;
pRExC_state->code_index = 0;
*((char*) RExC_emit++) = (char) REG_MAGIC;
+ /* setup various meta data about recursion, this all requires
+ * RExC_npar to be correctly set, and a bit later on we clear it */
+ if (RExC_seen & REG_RECURSE_SEEN) {
+ DEBUG_OPTIMISE_MORE_r(Perl_re_printf( aTHX_
+ "%*s%*s Setting up open/close parens\n",
+ 22, "| |", (int)(0 * 2 + 1), ""));
+
+ /* setup RExC_open_parens, which holds the address of each
+ * OPEN tag, and to make things simpler for the 0 index
+ * the start of the program - this is used later for offsets */
+ Newxz(RExC_open_parens, RExC_npar,regnode *);
+ SAVEFREEPV(RExC_open_parens);
+ RExC_open_parens[0] = RExC_emit;
+
+ /* setup RExC_close_parens, which holds the address of each
+ * CLOSE tag, and to make things simpler for the 0 index
+ * the end of the program - this is used later for offsets */
+ Newxz(RExC_close_parens, RExC_npar,regnode *);
+ SAVEFREEPV(RExC_close_parens);
+ /* we dont know where end op starts yet, so we dont
+ * need to set RExC_close_parens[0] like we do RExC_open_parens[0] above */
+
+ /* Note, RExC_npar is 1 + the number of parens in a pattern.
+ * So its 1 if there are no parens. */
+ RExC_study_chunk_recursed_bytes= (RExC_npar >> 3) +
+ ((RExC_npar & 0x07) != 0);
+ Newx(RExC_study_chunk_recursed,
+ RExC_study_chunk_recursed_bytes * RExC_npar, U8);
+ SAVEFREEPV(RExC_study_chunk_recursed);
+ }
+ RExC_npar = 1;
if (reg(pRExC_state, 0, &flags,1) == NULL) {
ReREFCNT_dec(rx);
Perl_croak(aTHX_ "panic: reg returned NULL to re_op_compile for generation pass, flags=%#"UVxf"", (UV) flags);
}
+ DEBUG_OPTIMISE_r(
+ Perl_re_printf( aTHX_ "Starting post parse optimization\n");
+ );
+
/* XXXX To minimize changes to RE engine we always allocate
3-units-long substrs field. */
Newx(r->substrs, 1, struct reg_substr_data);
copyRExC_state = RExC_state;
} else {
U32 seen=RExC_seen;
- DEBUG_OPTIMISE_r(PerlIO_printf(Perl_debug_log,"Restudying\n"));
+ DEBUG_OPTIMISE_r(Perl_re_printf( aTHX_ "Restudying\n"));
RExC_state = copyRExC_state;
if (seen & REG_TOP_LEVEL_BRANCHES_SEEN)
#ifdef TRIE_STUDY_OPT
DEBUG_PARSE_r(
if (!restudied)
- PerlIO_printf(Perl_debug_log, "first at %"IVdf"\n",
+ Perl_re_printf( aTHX_ "first at %"IVdf"\n",
(IV)(first - scan + 1))
);
#else
DEBUG_PARSE_r(
- PerlIO_printf(Perl_debug_log, "first at %"IVdf"\n",
+ Perl_re_printf( aTHX_ "first at %"IVdf"\n",
(IV)(first - scan + 1))
);
#endif
r->intflags &= ~PREGf_SKIP; /* Used in find_byclass(). */
DEBUG_COMPILE_r({ SV *sv = sv_newmortal();
regprop(r, sv, (regnode*)data.start_class, NULL, pRExC_state);
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"synthetic stclass \"%s\".\n",
SvPVX_const(sv));});
data.start_class = NULL;
regnode_ssc ch_class;
SSize_t last_close = 0;
- DEBUG_PARSE_r(PerlIO_printf(Perl_debug_log, "\nMulti Top Level\n"));
+ DEBUG_PARSE_r(Perl_re_printf( aTHX_ "\nMulti Top Level\n"));
scan = ri->program + 1;
ssc_init(pRExC_state, &ch_class);
r->intflags &= ~PREGf_SKIP; /* Used in find_byclass(). */
DEBUG_COMPILE_r({ SV* sv = sv_newmortal();
regprop(r, sv, (regnode*)data.start_class, NULL, pRExC_state);
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"synthetic stclass \"%s\".\n",
SvPVX_const(sv));});
data.start_class = NULL;
/* Guard against an embedded (?=) or (?<=) with a longer minlen than
the "real" pattern. */
DEBUG_OPTIMISE_r({
- PerlIO_printf(Perl_debug_log,"minlen: %"IVdf" r->minlen:%"IVdf" maxlen:%"IVdf"\n",
+ Perl_re_printf( aTHX_ "minlen: %"IVdf" r->minlen:%"IVdf" maxlen:%"IVdf"\n",
(IV)minlen, (IV)r->minlen, (IV)RExC_maxlen);
});
r->minlenret = minlen;
if (r->minlen < minlen)
r->minlen = minlen;
+ if (RExC_seen & REG_RECURSE_SEEN ) {
+ r->intflags |= PREGf_RECURSE_SEEN;
+ Newxz(r->recurse_locinput, r->nparens + 1, char *);
+ }
if (RExC_seen & REG_GPOS_SEEN)
r->intflags |= PREGf_GPOS_SEEN;
if (RExC_seen & REG_LOOKBEHIND_SEEN)
= (void*)SvREFCNT_inc(RExC_paren_name_list);
} else
#endif
- ri->name_list_idx = 0;
+ ri->name_list_idx = 0;
- if (RExC_recurse_count) {
- for ( ; RExC_recurse_count ; RExC_recurse_count-- ) {
- const regnode *scan = RExC_recurse[RExC_recurse_count-1];
- ARG2L_SET( scan, RExC_open_parens[ARG(scan)-1] - scan );
- }
+ while ( RExC_recurse_count > 0 ) {
+ const regnode *scan = RExC_recurse[ --RExC_recurse_count ];
+ ARG2L_SET( scan, RExC_open_parens[ARG(scan)] - scan );
}
+
Newxz(r->offs, RExC_npar, regexp_paren_pair);
/* assume we don't need to swap parens around before we match */
DEBUG_TEST_r({
- PerlIO_printf(Perl_debug_log,"study_chunk_recursed_count: %lu\n",
+ Perl_re_printf( aTHX_ "study_chunk_recursed_count: %lu\n",
(unsigned long)RExC_study_chunk_recursed_count);
});
DEBUG_DUMP_r({
DEBUG_RExC_seen();
- PerlIO_printf(Perl_debug_log,"Final program:\n");
+ Perl_re_printf( aTHX_ "Final program:\n");
regdump(r);
});
#ifdef RE_TRACK_PATTERN_OFFSETS
const STRLEN len = ri->u.offsets[0];
STRLEN i;
GET_RE_DEBUG_FLAGS_DECL;
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"Offsets: [%"UVuf"]\n\t", (UV)ri->u.offsets[0]);
for (i = 1; i <= len; i++) {
if (ri->u.offsets[i*2-1] || ri->u.offsets[i*2])
- PerlIO_printf(Perl_debug_log, "%"UVuf":%"UVuf"[%"UVuf"] ",
+ Perl_re_printf( aTHX_ "%"UVuf":%"UVuf"[%"UVuf"] ",
(UV)i, (UV)ri->u.offsets[i*2-1], (UV)ri->u.offsets[i*2]);
}
- PerlIO_printf(Perl_debug_log, "\n");
+ Perl_re_printf( aTHX_ "\n");
});
#endif
#define DEBUG_PARSE_MSG(funcname) DEBUG_PARSE_r({ \
int num; \
if (RExC_lastparse!=RExC_parse) { \
- PerlIO_printf(Perl_debug_log, "%s", \
+ Perl_re_printf( aTHX_ "%s", \
Perl_pv_pretty(aTHX_ RExC_mysv1, RExC_parse, \
RExC_end - RExC_parse, 16, \
"", "", \
) \
); \
} else \
- PerlIO_printf(Perl_debug_log,"%16s",""); \
+ Perl_re_printf( aTHX_ "%16s",""); \
\
if (SIZE_ONLY) \
num = RExC_size + 1; \
else \
num=REG_NODE_NUM(RExC_emit); \
if (RExC_lastnum!=num) \
- PerlIO_printf(Perl_debug_log,"|%4d",num); \
+ Perl_re_printf( aTHX_ "|%4d",num); \
else \
- PerlIO_printf(Perl_debug_log,"|%4s",""); \
- PerlIO_printf(Perl_debug_log,"|%*s%-4s", \
+ Perl_re_printf( aTHX_ "|%4s",""); \
+ Perl_re_printf( aTHX_ "|%*s%-4s", \
(int)((depth*2)), "", \
(funcname) \
); \
#define DEBUG_PARSE(funcname) DEBUG_PARSE_r({ \
DEBUG_PARSE_MSG((funcname)); \
- PerlIO_printf(Perl_debug_log,"%4s","\n"); \
+ Perl_re_printf( aTHX_ "%4s","\n"); \
})
-#define DEBUG_PARSE_FMT(funcname,fmt,args) DEBUG_PARSE_r({ \
+#define DEBUG_PARSE_FMT(funcname,fmt,args) DEBUG_PARSE_r({\
DEBUG_PARSE_MSG((funcname)); \
- PerlIO_printf(Perl_debug_log,fmt "\n",args); \
+ Perl_re_printf( aTHX_ fmt "\n",args); \
})
/* This section of code defines the inversion list object and its methods. The
#ifndef PERL_IN_XSUB_RE
+STATIC void
+S_invlist_replace_list_destroys_src(pTHX_ SV * dest, SV * src)
+{
+ /* Replaces the inversion list in 'src' with the one in 'dest'. It steals
+ * the list from 'src', so 'src' is made to have a NULL list. This is
+ * similar to what SvSetMagicSV() would do, if it were implemented on
+ * inversion lists, though this routine avoids a copy */
+
+ const UV src_len = _invlist_len(src);
+ const bool src_offset = *get_invlist_offset_addr(src);
+ const STRLEN src_byte_len = SvLEN(src);
+ char * array = SvPVX(src);
+
+ const int oldtainted = TAINT_get;
+
+ PERL_ARGS_ASSERT_INVLIST_REPLACE_LIST_DESTROYS_SRC;
+
+ assert(SvTYPE(src) == SVt_INVLIST);
+ assert(SvTYPE(dest) == SVt_INVLIST);
+ assert(! invlist_is_iterating(src));
+ assert(SvCUR(src) == 0 || SvCUR(src) < SvLEN(src));
+
+ /* Make sure it ends in the right place with a NUL, as our inversion list
+ * manipulations aren't careful to keep this true, but sv_usepvn_flags()
+ * asserts it */
+ array[src_byte_len - 1] = '\0';
+
+ TAINT_NOT; /* Otherwise it breaks */
+ sv_usepvn_flags(dest,
+ (char *) array,
+ src_byte_len - 1,
+
+ /* This flag is documented to cause a copy to be avoided */
+ SV_HAS_TRAILING_NUL);
+ TAINT_set(oldtainted);
+ SvPV_set(src, 0);
+ SvLEN_set(src, 0);
+ SvCUR_set(src, 0);
+
+ /* Finish up copying over the other fields in an inversion list */
+ *get_invlist_offset_addr(dest) = src_offset;
+ invlist_set_len(dest, src_len, src_offset);
+ *get_invlist_previous_index_addr(dest) = 0;
+ invlist_iterfinish(dest);
+}
+
PERL_STATIC_INLINE IV*
S_get_invlist_previous_index_addr(SV* invlist)
{
}
PERL_STATIC_INLINE void
-S_invlist_trim(SV* const invlist)
+S_invlist_trim(SV* invlist)
{
+ /* Free the not currently-being-used space in an inversion list */
+
+ /* But don't free up the space needed for the 0 UV that is always at the
+ * beginning of the list, nor the trailing NUL */
+ const UV min_size = TO_INTERNAL_SIZE(1) + 1;
+
PERL_ARGS_ASSERT_INVLIST_TRIM;
assert(SvTYPE(invlist) == SVt_INVLIST);
- /* Change the length of the inversion list to how many entries it currently
- * has */
- SvPV_shrink_to_cur((SV *) invlist);
+ SvPV_renew(invlist, MAX(min_size, SvCUR(invlist) + 1));
+}
+
+PERL_STATIC_INLINE void
+S_invlist_clear(pTHX_ SV* invlist) /* Empty the inversion list */
+{
+ PERL_ARGS_ASSERT_INVLIST_CLEAR;
+
+ assert(SvTYPE(invlist) == SVt_INVLIST);
+
+ invlist_set_len(invlist, 0, 0);
+ invlist_trim(invlist);
}
#endif /* ifndef PERL_IN_XSUB_RE */
/* Take the union of two inversion lists and point <output> to it. *output
* SHOULD BE DEFINED upon input, and if it points to one of the two lists,
* the reference count to that list will be decremented if not already a
- * temporary (mortal); otherwise *output will be made correspondingly
- * mortal. The first list, <a>, may be NULL, in which case a copy of the
- * second list is returned. If <complement_b> is TRUE, the union is taken
- * of the complement (inversion) of <b> instead of b itself.
+ * temporary (mortal); otherwise just its contents will be modified to be
+ * the union. The first list, <a>, may be NULL, in which case a copy of
+ * the second list is returned. If <complement_b> is TRUE, the union is
+ * taken of the complement (inversion) of <b> instead of b itself.
*
* The basis for this comes from "Unicode Demystified" Chapter 13 by
* Richard Gillam, published by Addison-Wesley, and explained at some
SV* u; /* the resulting union */
UV* array_u;
- UV len_u;
+ UV len_u = 0;
UV i_a = 0; /* current index into a's array */
UV i_b = 0;
PERL_ARGS_ASSERT__INVLIST_UNION_MAYBE_COMPLEMENT_2ND;
assert(a != b);
- /* If either one is empty, the union is the other one */
- if (a == NULL || ((len_a = _invlist_len(a)) == 0)) {
- bool make_temp = FALSE; /* Should we mortalize the result? */
+ len_b = _invlist_len(b);
+ if (len_b == 0) {
- if (*output == a) {
- if (a != NULL) {
- if (! (make_temp = cBOOL(SvTEMP(a)))) {
- SvREFCNT_dec_NN(a);
- }
+ /* Here, 'b' is empty. If the output is the complement of 'b', the
+ * union is all possible code points, and we need not even look at 'a'.
+ * It's easiest to create a new inversion list that matches everything.
+ * */
+ if (complement_b) {
+ SV* everything = _new_invlist(1);
+ _append_range_to_invlist(everything, 0, UV_MAX);
+
+ /* If the output didn't exist, just point it at the new list */
+ if (*output == NULL) {
+ *output = everything;
+ return;
}
- }
- if (*output != b) {
- *output = invlist_clone(b);
- if (complement_b) {
- _invlist_invert(*output);
+
+ /* Otherwise, replace its contents with the new list */
+ invlist_replace_list_destroys_src(*output, everything);
+ SvREFCNT_dec_NN(everything);
+ return;
+ }
+
+ /* Here, we don't want the complement of 'b', and since it is empty,
+ * the union will come entirely from 'a'. If 'a' is NULL or empty, the
+ * output will be empty */
+
+ if (a == NULL) {
+ *output = _new_invlist(0);
+ return;
+ }
+
+ if (_invlist_len(a) == 0) {
+ invlist_clear(*output);
+ return;
+ }
+
+ /* Here, 'a' is not empty, and entirely determines the union. If the
+ * output is not to overwrite 'b', we can just return 'a'. */
+ if (*output != b) {
+
+ /* If the output is to overwrite 'a', we have a no-op, as it's
+ * already in 'a' */
+ if (*output == a) {
+ return;
}
- } /* else *output already = b; */
- if (make_temp) {
- sv_2mortal(*output);
+ /* But otherwise we have to copy 'a' to the output */
+ *output = invlist_clone(a);
+ return;
}
+
+ /* Here, 'b' is to be overwritten by the output, which will be 'a' */
+ u = invlist_clone(a);
+ invlist_replace_list_destroys_src(*output, u);
+ SvREFCNT_dec_NN(u);
+
return;
}
- else if ((len_b = _invlist_len(b)) == 0) {
- bool make_temp = FALSE;
- if (*output == b) {
- if (! (make_temp = cBOOL(SvTEMP(b)))) {
- SvREFCNT_dec_NN(b);
+
+ if (a == NULL || ((len_a = _invlist_len(a)) == 0)) {
+
+ /* Here, 'a' is empty (and b is not). That means the union will come
+ * entirely from 'b'. If the output is not to overwrite 'a', we can
+ * just return what's in 'b'. */
+ if (*output != a) {
+
+ /* If the output is to overwrite 'b', it's already in 'b', but
+ * otherwise we have to copy 'b' to the output */
+ if (*output != b) {
+ *output = invlist_clone(b);
}
- }
- /* The complement of an empty list is a list that has everything in it,
- * so the union with <a> includes everything too */
- if (complement_b) {
- if (a == *output) {
- if (! (make_temp = cBOOL(SvTEMP(a)))) {
- SvREFCNT_dec_NN(a);
- }
+ /* And if the output is to be the inversion of 'b', do that */
+ if (complement_b) {
+ _invlist_invert(*output);
}
- *output = _new_invlist(1);
- _append_range_to_invlist(*output, 0, UV_MAX);
+
+ return;
}
- else if (*output != a) {
- *output = invlist_clone(a);
+
+ /* Here, 'a', which is empty or even NULL, is to be overwritten by the
+ * output, which will either be 'b' or the complement of 'b' */
+
+ if (a == NULL) {
+ *output = invlist_clone(b);
}
- /* else *output already = a; */
+ else {
+ u = invlist_clone(b);
+ invlist_replace_list_destroys_src(*output, u);
+ SvREFCNT_dec_NN(u);
+ }
- if (make_temp) {
- sv_2mortal(*output);
+ if (complement_b) {
+ _invlist_invert(*output);
}
+
return;
}
/* Here, have chosen which of the two inputs to look at. Only output
* if the running count changes to/from 0, which marks the
- * beginning/end of a range in that's in the set */
+ * beginning/end of a range that's in the set */
if (cp_in_set) {
if (count == 0) {
array_u[i_u++] = cp;
* 4) the exhausted wasn't in its set, non-exhausted is, count is 1;
* decrementing to 0 insures that we look at the remainder of the
* non-exhausted set */
- if ((i_a != len_a && PREV_RANGE_MATCHES_INVLIST(i_a))
+ if ( (i_a != len_a && PREV_RANGE_MATCHES_INVLIST(i_a))
|| (i_b != len_b && PREV_RANGE_MATCHES_INVLIST(i_b)))
{
count--;
len_u += (len_a - i_a) + (len_b - i_b);
}
- /* Set result to final length, which can change the pointer to array_u, so
- * re-find it */
+ /* Set the result to the final length, which can change the pointer to
+ * array_u, so re-find it. (Note that it is unlikely that this will
+ * change, as we are shrinking the space, not enlarging it) */
if (len_u != _invlist_len(u)) {
invlist_set_len(u, len_u, *get_invlist_offset_addr(u));
invlist_trim(u);
/* When 'count' is 0, the list that was exhausted (if one was shorter than
* the other) ended with everything above it not in its set. That means
* that the remaining part of the union is precisely the same as the
- * non-exhausted list, so can just copy it unchanged. (If both list were
+ * non-exhausted list, so can just copy it unchanged. (If both lists were
* exhausted at the same time, then the operations below will be both 0.)
*/
if (count == 0) {
}
}
- /* We may be removing a reference to one of the inputs. If so, the output
- * is made mortal if the input was. (Mortal SVs shouldn't have their ref
- * count decremented) */
- if (a == *output || b == *output) {
+ /* If the output is not to overwrite either of the inputs, just return the
+ * calculated union */
+ if (a != *output && b != *output) {
+ *output = u;
+ }
+ else {
+ /* Here, the output is to be the same as one of the input scalars,
+ * hence replacing it. The simple thing to do is to free the input
+ * scalar, making it instead be the output one. But experience has
+ * shown [perl #127392] that if the input is a mortal, we can get a
+ * huge build-up of these during regex compilation before they get
+ * freed. So for that case, replace just the input's interior with
+ * the output's, and then free the output */
+
assert(! invlist_is_iterating(*output));
- if ((SvTEMP(*output))) {
- sv_2mortal(u);
+
+ if (! SvTEMP(*output)) {
+ SvREFCNT_dec_NN(*output);
+ *output = u;
}
else {
- SvREFCNT_dec_NN(*output);
+ invlist_replace_list_destroys_src(*output, u);
+ SvREFCNT_dec_NN(u);
}
}
- *output = u;
-
return;
}
/* Take the intersection of two inversion lists and point <i> to it. *i
* SHOULD BE DEFINED upon input, and if it points to one of the two lists,
* the reference count to that list will be decremented if not already a
- * temporary (mortal); otherwise *i will be made correspondingly mortal.
- * The first list, <a>, may be NULL, in which case an empty list is
- * returned. If <complement_b> is TRUE, the result will be the
- * intersection of <a> and the complement (or inversion) of <b> instead of
- * <b> directly.
+ * temporary (mortal); otherwise just its contents will be modified to be
+ * the intersection. The first list, <a>, may be NULL, in which case an
+ * empty list is returned. If <complement_b> is TRUE, the result will be
+ * the intersection of <a> and the complement (or inversion) of <b> instead
+ * of <b> directly.
*
* The basis for this comes from "Unicode Demystified" Chapter 13 by
* Richard Gillam, published by Addison-Wesley, and explained at some
SV* r; /* the resulting intersection */
UV* array_r;
- UV len_r;
+ UV len_r = 0;
UV i_a = 0; /* current index into a's array */
UV i_b = 0;
/* Special case if either one is empty */
len_a = (a == NULL) ? 0 : _invlist_len(a);
if ((len_a == 0) || ((len_b = _invlist_len(b)) == 0)) {
- bool make_temp = FALSE;
-
if (len_a != 0 && complement_b) {
- /* Here, 'a' is not empty, therefore from the above 'if', 'b' must
- * be empty. Here, also we are using 'b's complement, which hence
- * must be every possible code point. Thus the intersection is
- * simply 'a'. */
- if (*i != a) {
- if (*i == b) {
- if (! (make_temp = cBOOL(SvTEMP(b)))) {
- SvREFCNT_dec_NN(b);
- }
- }
+ /* Here, 'a' is not empty, therefore from the enclosing 'if', 'b'
+ * must be empty. Here, also we are using 'b's complement, which
+ * hence must be every possible code point. Thus the intersection
+ * is simply 'a'. */
- *i = invlist_clone(a);
+ if (*i == a) { /* No-op */
+ return;
}
- /* else *i is already 'a' */
- if (make_temp) {
- sv_2mortal(*i);
+ /* If not overwriting either input, just make a copy of 'a' */
+ if (*i != b) {
+ *i = invlist_clone(a);
+ return;
}
+
+ /* Here we are overwriting 'b' with 'a's contents */
+ r = invlist_clone(a);
+ invlist_replace_list_destroys_src(*i, r);
+ SvREFCNT_dec_NN(r);
return;
}
/* Here, 'a' or 'b' is empty and not using the complement of 'b'. The
* intersection must be empty */
- if (*i == a) {
- if (a != NULL) {
- if (! (make_temp = cBOOL(SvTEMP(a)))) {
- SvREFCNT_dec_NN(a);
- }
- }
- }
- else if (*i == b) {
- if (! (make_temp = cBOOL(SvTEMP(b)))) {
- SvREFCNT_dec_NN(b);
- }
- }
- *i = _new_invlist(0);
- if (make_temp) {
- sv_2mortal(*i);
+ if (*i == NULL) {
+ *i = _new_invlist(0);
+ return;
}
+ invlist_clear(*i);
return;
}
* everything that remains in the non-exhausted set.
* 4) the exhausted wasn't in its set, non-exhausted is, count is 1, and
* remains 1. And the intersection has nothing more. */
- if ((i_a == len_a && PREV_RANGE_MATCHES_INVLIST(i_a))
+ if ( (i_a == len_a && PREV_RANGE_MATCHES_INVLIST(i_a))
|| (i_b == len_b && PREV_RANGE_MATCHES_INVLIST(i_b)))
{
count++;
len_r += (len_a - i_a) + (len_b - i_b);
}
- /* Set result to final length, which can change the pointer to array_r, so
- * re-find it */
+ /* Set the result to the final length, which can change the pointer to
+ * array_r, so re-find it. (Note that it is unlikely that this will
+ * change, as we are shrinking the space, not enlarging it) */
if (len_r != _invlist_len(r)) {
invlist_set_len(r, len_r, *get_invlist_offset_addr(r));
invlist_trim(r);
}
}
- /* We may be removing a reference to one of the inputs. If so, the output
- * is made mortal if the input was. (Mortal SVs shouldn't have their ref
- * count decremented) */
- if (a == *i || b == *i) {
+ /* If the output is not to overwrite either of the inputs, just return the
+ * calculated intersection */
+ if (a != *i && b != *i) {
+ *i = r;
+ }
+ else {
+ /* Here, the output is to be the same as one of the input scalars,
+ * hence replacing it. The simple thing to do is to free the input
+ * scalar, making it instead be the output one. But experience has
+ * shown [perl #127392] that if the input is a mortal, we can get a
+ * huge build-up of these during regex compilation before they get
+ * freed. So for that case, replace just the input's interior with
+ * the output's, and then free the output. A short-cut in this case
+ * is if the output is empty, we can just set the input to be empty */
+
assert(! invlist_is_iterating(*i));
- if (SvTEMP(*i)) {
- sv_2mortal(r);
+
+ if (! SvTEMP(*i)) {
+ SvREFCNT_dec_NN(*i);
+ *i = r;
}
else {
- SvREFCNT_dec_NN(*i);
+ if (len_r) {
+ invlist_replace_list_destroys_src(*i, r);
+ }
+ else {
+ invlist_clear(*i);
+ }
+ SvREFCNT_dec_NN(r);
}
}
- *i = r;
-
return;
}
: array[len - 1] - 1;
}
-SV *
+STATIC SV *
S_invlist_contents(pTHX_ SV* const invlist, const bool traditional_style)
{
/* Get the contents of an inversion list into a string SV so that they can
{
AV* list = (AV*) *listp;
IV k;
- for (k = 0; k <= av_tindex(list); k++) {
+ for (k = 0; k <= av_tindex_nomg(list); k++) {
SV** c_p = av_fetch(list, k, FALSE);
UV c;
assert(c_p);
* indivisible */
bool has_intervening_patws = paren == 2 && *(RExC_parse - 1) != '(';
- assert(RExC_parse < RExC_end);
+ if (RExC_parse >= RExC_end) {
+ vFAIL("Unmatched (");
+ }
if ( *RExC_parse == '*') { /* (*VERB:ARG) */
char *start_verb = RExC_parse + 1;
break;
case '0' : /* (?0) */
case 'R' : /* (?R) */
- if (*RExC_parse != ')')
+ if (RExC_parse == RExC_end || *RExC_parse != ')')
FAIL("Sequence (?R) not terminated");
- ret = reg_node(pRExC_state, GOSTART);
- RExC_seen |= REG_GOSTART_SEEN;
+ num = 0;
+ RExC_seen |= REG_RECURSE_SEEN;
*flagp |= POSTPONED;
- nextchar(pRExC_state);
- return ret;
+ goto gen_recurse_regop;
/*notreached*/
/* named and numeric backreferences */
case '&': /* (?&NAME) */
} else if ( paren == '+' ) {
num = RExC_npar + num - 1;
}
+ /* We keep track how many GOSUB items we have produced.
+ To start off the ARG2L() of the GOSUB holds its "id",
+ which is used later in conjunction with RExC_recurse
+ to calculate the offset we need to jump for the GOSUB,
+ which it will store in the final representation.
+ We have to defer the actual calculation until much later
+ as the regop may move.
+ */
ret = reg2Lanode(pRExC_state, GOSUB, num, RExC_recurse_count);
if (!SIZE_ONLY) {
vFAIL("Reference to nonexistent group");
}
RExC_recurse_count++;
- DEBUG_OPTIMISE_MORE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_OPTIMISE_MORE_r(Perl_re_printf( aTHX_
"%*s%*s Recurse #%"UVuf" to %"IVdf"\n",
22, "| |", (int)(depth * 2 + 1), "",
(UV)ARG(ret), (IV)ARG2L(ret)));
}
RExC_seen |= REG_RECURSE_SEEN;
+
Set_Node_Length(ret, 1 + regarglen[OP(ret)]); /* MJD */
Set_Node_Offset(ret, parse_start); /* MJD */
*flagp |= POSTPONED;
+ assert(*RExC_parse == ')');
nextchar(pRExC_state);
return ret;
}
else if (RExC_parse[0] == 'R') {
RExC_parse++;
+ /* parno == 0 => /(?(R)YES|NO)/ "in any form of recursion OR eval"
+ * parno == 1 => /(?(R0)YES|NO)/ "in GOSUB (?0) / (?R)"
+ * parno == 2 => /(?(R1)YES|NO)/ "in GOSUB (?1) (parno-1)"
+ */
parno = 0;
- if (RExC_parse[0] >= '1' && RExC_parse[0] <= '9' ) {
+ if (RExC_parse[0] == '0') {
+ parno = 1;
+ RExC_parse++;
+ }
+ else if (RExC_parse[0] >= '1' && RExC_parse[0] <= '9' ) {
UV uv;
if (grok_atoUV(RExC_parse, &uv, &endptr)
&& uv <= I32_MAX
) {
- parno = (I32)uv;
+ parno = (I32)uv + 1;
RExC_parse = (char*)endptr;
}
/* else "Switch condition not recognized" below */
SIZE_ONLY
? REG_RSN_RETURN_NULL
: REG_RSN_RETURN_DATA);
- parno = sv_dat ? *((I32 *)SvPVX(sv_dat)) : 0;
+
+ /* we should only have a false sv_dat when
+ * SIZE_ONLY is true, and we always have false
+ * sv_dat when SIZE_ONLY is true.
+ * reg_scan_name() will VFAIL() if the name is
+ * unknown when SIZE_ONLY is false, and otherwise
+ * will return something, and when SIZE_ONLY is
+ * true, reg_scan_name() just parses the string,
+ * and doesnt return anything. (in theory) */
+ assert(SIZE_ONLY ? !sv_dat : !!sv_dat);
+
+ if (sv_dat)
+ parno = 1 + *((I32 *)SvPVX(sv_dat));
}
ret = reganode(pRExC_state,INSUBP,parno);
goto insert_if_check_paren;
if (!SIZE_ONLY ){
if (!RExC_nestroot)
RExC_nestroot = parno;
- if (RExC_seen & REG_RECURSE_SEEN
- && !RExC_open_parens[parno-1])
+ if (RExC_open_parens && !RExC_open_parens[parno])
{
- DEBUG_OPTIMISE_MORE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_OPTIMISE_MORE_r(Perl_re_printf( aTHX_
"%*s%*s Setting open paren #%"IVdf" to %d\n",
22, "| |", (int)(depth * 2 + 1), "",
(IV)parno, REG_NODE_NUM(ret)));
- RExC_open_parens[parno-1]= ret;
+ RExC_open_parens[parno]= ret;
}
}
Set_Node_Length(ret, 1); /* MJD */
break;
case 1: case 2:
ender = reganode(pRExC_state, CLOSE, parno);
- if (!SIZE_ONLY && RExC_seen & REG_RECURSE_SEEN) {
- DEBUG_OPTIMISE_MORE_r(PerlIO_printf(Perl_debug_log,
+ if ( RExC_close_parens ) {
+ DEBUG_OPTIMISE_MORE_r(Perl_re_printf( aTHX_
"%*s%*s Setting close paren #%"IVdf" to %d\n",
22, "| |", (int)(depth * 2 + 1), "", (IV)parno, REG_NODE_NUM(ender)));
- RExC_close_parens[parno-1]= ender;
+ RExC_close_parens[parno]= ender;
if (RExC_nestroot == parno)
RExC_nestroot = 0;
}
case 0:
ender = reg_node(pRExC_state, END);
if (!SIZE_ONLY) {
- assert(!RExC_opend); /* there can only be one! */
- RExC_opend = ender;
+ assert(!RExC_end_op); /* there can only be one! */
+ RExC_end_op = ender;
+ if (RExC_close_parens) {
+ DEBUG_OPTIMISE_MORE_r(Perl_re_printf( aTHX_
+ "%*s%*s Setting close paren #0 (END) to %d\n",
+ 22, "| |", (int)(depth * 2 + 1), "", REG_NODE_NUM(ender)));
+
+ RExC_close_parens[0]= ender;
+ }
}
break;
}
DEBUG_PARSE_MSG("lsbr");
regprop(RExC_rx, RExC_mysv1, lastbr, NULL, pRExC_state);
regprop(RExC_rx, RExC_mysv2, ender, NULL, pRExC_state);
- PerlIO_printf(Perl_debug_log, "~ tying lastbr %s (%"IVdf") to ender %s (%"IVdf") offset %"IVdf"\n",
+ Perl_re_printf( aTHX_ "~ tying lastbr %s (%"IVdf") to ender %s (%"IVdf") offset %"IVdf"\n",
SvPV_nolen_const(RExC_mysv1),
(IV)REG_NODE_NUM(lastbr),
SvPV_nolen_const(RExC_mysv2),
DEBUG_PARSE_MSG("NADA");
regprop(RExC_rx, RExC_mysv1, ret, NULL, pRExC_state);
regprop(RExC_rx, RExC_mysv2, ender, NULL, pRExC_state);
- PerlIO_printf(Perl_debug_log, "~ converting ret %s (%"IVdf") to ender %s (%"IVdf") offset %"IVdf"\n",
+ Perl_re_printf( aTHX_ "~ converting ret %s (%"IVdf") to ender %s (%"IVdf") offset %"IVdf"\n",
SvPV_nolen_const(RExC_mysv1),
(IV)REG_NODE_NUM(ret),
SvPV_nolen_const(RExC_mysv2),
/* 'posix_warnings' and 'warn_text' are names of variables in the following
* routine. q.v. */
#define ADD_POSIX_WARNING(p, text) STMT_START { \
- if (posix_warnings && ( posix_warnings != (AV **) -1 \
- || (PASS2 && ckWARN(WARN_REGEXP)))) \
- { \
+ if (posix_warnings) { \
if (! warn_text) warn_text = newAV(); \
av_push(warn_text, Perl_newSVpvf(aTHX_ \
WARNING_PREFIX \
besides RExC_parse. */
char ** updated_parse_ptr, /* Where to set the updated parse pointer, or
NULL */
- AV ** posix_warnings /* Where to place any generated warnings, or -1
- if to output them, or NULL */
+ AV ** posix_warnings, /* Where to place any generated warnings, or
+ NULL */
+ const bool check_only /* Don't die if error */
)
{
/* This parses what the caller thinks may be one of the three POSIX
* 'updated_parse_ptr' is not changed. No warnings nor errors are
* raised.
*
- * In b) there may be warnings and even errors generated. What to do about
- * these is determined by the 'posix_warnings' parameter. If it is NULL,
- * this call is treated as a check-only, scouting-out-the-territory call,
- * and no warnings nor errors are generated at all. Otherwise, any errors
- * are raised if found. If 'posix_warnings' is -1 (appropriately cast),
- * warnings are generated and displayed (in pass 2), just as they would be
- * for any other message of the same type from this file. If it isn't NULL
- * and not -1, warnings aren't displayed, but instead an AV is generated
- * with all the warning messages (that aren't to be ignored) stored into
- * it, so that the caller can output them if it wants. This is done in all
+ * In b) there may be errors or warnings generated. If 'check_only' is
+ * TRUE, then any errors are discarded. Warnings are returned to the
+ * caller via an AV* created into '*posix_warnings' if it is not NULL. If
+ * instead it is NULL, warnings are suppressed. This is done in all
* passes. The reason for this is that the rest of the parsing is heavily
* dependent on whether this routine found a valid posix class or not. If
- * it did, the closing ']' is absorbed as part of the class. If no class
+ * it did, the closing ']' is absorbed as part of the class. If no class,
* or an invalid one is found, any ']' will be considered the terminator of
* the outer bracketed character class, leading to very different results.
* In particular, a '(?[ ])' construct will likely have a syntax error if
/* For [. .] and [= =]. These are quite different internally from [: :],
* so they are handled separately. */
- if (POSIXCC_NOTYET(*p)) {
+ if (POSIXCC_NOTYET(*p) && p < e - 3) /* 1 for the close, and 1 for the ']'
+ and 1 for at least one char in it
+ */
+ {
const char open_char = *p;
const char * temp_ptr = p + 1;
- unsigned int len = 0;
/* These two constructs are not handled by perl, and if we find a
- * syntactically valid one, we croak. It looks like just about any
- * byte can be in them, but they are likely very short, like [.ch.] to
- * denote a ligature 'ch' single character. If we find something that
- * started out to look like one of these constructs, but isn't, we
- * break so that it can be checked for being a class name with a typo
- * of '.' or '=' instead of a colon */
- while (temp_ptr < e) {
- len++;
-
- /* qr/[[.].]]/, for example, is valid. But otherwise we quit on an
- * unexpected ']'. It is possible, it appears, for such a ']' to
- * be not in the final position, but that's so unlikely that that
- * case is not handled. */
- if (*temp_ptr == ']' && temp_ptr[1] != open_char) {
- break;
- }
-
- /* XXX this could be cut down, but this value is certainly large
- * enough */
- if (len > 10) {
- break;
- }
+ * syntactically valid one, we croak. khw, who wrote this code, finds
+ * this explanation of them very unclear:
+ * http://pubs.opengroup.org/onlinepubs/009696899/basedefs/xbd_chap09.html
+ * And searching the rest of the internet wasn't very helpful either.
+ * It looks like just about any byte can be in these constructs,
+ * depending on the locale. But unless the pattern is being compiled
+ * under /l, which is very rare, Perl runs under the C or POSIX locale.
+ * In that case, it looks like [= =] isn't allowed at all, and that
+ * [. .] could be any single code point, but for longer strings the
+ * constituent characters would have to be the ASCII alphabetics plus
+ * the minus-hyphen. Any sensible locale definition would limit itself
+ * to these. And any portable one definitely should. Trying to parse
+ * the general case is a nightmare (see [perl #127604]). So, this code
+ * looks only for interiors of these constructs that match:
+ * qr/.|[-\w]{2,}/
+ * Using \w relaxes the apparent rules a little, without adding much
+ * danger of mistaking something else for one of these constructs.
+ *
+ * [. .] in some implementations described on the internet is usable to
+ * escape a character that otherwise is special in bracketed character
+ * classes. For example [.].] means a literal right bracket instead of
+ * the ending of the class
+ *
+ * [= =] can legitimately contain a [. .] construct, but we don't
+ * handle this case, as that [. .] construct will later get parsed
+ * itself and croak then. And [= =] is checked for even when not under
+ * /l, as Perl has long done so.
+ *
+ * The code below relies on there being a trailing NUL, so it doesn't
+ * have to keep checking if the parse ptr < e.
+ */
+ if (temp_ptr[1] == open_char) {
+ temp_ptr++;
+ }
+ else while ( temp_ptr < e
+ && (isWORDCHAR(*temp_ptr) || *temp_ptr == '-'))
+ {
+ temp_ptr++;
+ }
- if (*temp_ptr == open_char) {
+ if (*temp_ptr == open_char) {
+ temp_ptr++;
+ if (*temp_ptr == ']') {
temp_ptr++;
- if (*temp_ptr == ']') {
- temp_ptr++;
- if (! found_problem && posix_warnings) {
- RExC_parse = (char *) temp_ptr;
- vFAIL3("POSIX syntax [%c %c] is reserved for future "
- "extensions", open_char, open_char);
- }
-
- /* Here, the syntax wasn't completely valid, or else the
- * call is to check-only */
- if (updated_parse_ptr) {
- *updated_parse_ptr = (char *) temp_ptr;
- }
-
- return OOB_NAMEDCLASS;
+ if (! found_problem && ! check_only) {
+ RExC_parse = (char *) temp_ptr;
+ vFAIL3("POSIX syntax [%c %c] is reserved for future "
+ "extensions", open_char, open_char);
}
- }
- else if (*temp_ptr == '\\') {
-
- /* A backslash is treate as like any other character, unless it
- * precedes a comment starter. XXX multiple backslashes in a
- * row are not handled specially here, nor would they ever
- * likely to be handled specially in one of these constructs */
- if (temp_ptr[1] == '#' && (RExC_flags & RXf_PMf_EXTENDED)) {
- temp_ptr++;
+
+ /* Here, the syntax wasn't completely valid, or else the call
+ * is to check-only */
+ if (updated_parse_ptr) {
+ *updated_parse_ptr = (char *) temp_ptr;
}
- temp_ptr++;
- }
- else if (*temp_ptr == '#' && (RExC_flags & RXf_PMf_EXTENDED)) {
- break; /* Under no circumstances can we look at the interior
- of a comment */
- }
- else if (*temp_ptr == '\n') { /* And we don't allow newlines
- either as it's extremely
- unlikely that one could be in an
- intended class */
- break;
- }
- else if (UTF && ! UTF8_IS_INVARIANT(*temp_ptr)) {
- /* XXX Since perl will never handle multi-byte locales, except
- * for UTF-8, we could break if we found a byte above latin1,
- * but perhaps the person intended to use one. */
- temp_ptr += UTF8SKIP(temp_ptr);
- }
- else {
- temp_ptr++;
+
+ return OOB_NAMEDCLASS;
}
}
+
+ /* If we find something that started out to look like one of these
+ * constructs, but isn't, we continue below so that it can be checked
+ * for being a class name with a typo of '.' or '=' instead of a colon.
+ * */
}
/* Here, we think there is a possibility that a [: :] class was meant, and
}
if (warn_text) {
- if (posix_warnings != (AV **) -1) {
- *posix_warnings = warn_text;
+ if (posix_warnings) {
+ /* mortalize to avoid a leak with FATAL warnings */
+ *posix_warnings = (AV *) sv_2mortal((SV *) warn_text);
}
else {
- SV * msg;
- while ((msg = av_shift(warn_text)) != &PL_sv_undef) {
- Perl_warner(aTHX_ packWARN(WARN_REGEXP),
- "%s", SvPVX(msg));
- SvREFCNT_dec_NN(msg);
- }
SvREFCNT_dec_NN(warn_text);
}
}
* one */
return class_number + complement;
}
- else if (posix_warnings) {
+ else if (! check_only) {
/* Here, it is an unrecognized class. This is an error (unless the
* call is to check only, which we've already handled above) */
'stack' of where the undealt-with left
parens would be if they were actually
put there */
- IV fence = 0; /* Position of where most recent undealt-
+ /* The 'VOL' (expanding to 'volatile') is a workaround for an optimiser bug
+ * in Solaris Studio 12.3. See RT #127455 */
+ VOL IV fence = 0; /* Position of where most recent undealt-
with left paren in stack is; -1 if none.
*/
STRLEN len; /* Temporary */
{
/* See if this is a [:posix:] class. */
bool is_posix_class = (OOB_NAMEDCLASS
- < handle_possible_posix(pRExC_state,
- RExC_parse + 1,
- NULL,
- NULL));
+ < handle_possible_posix(pRExC_state,
+ RExC_parse + 1,
+ NULL,
+ NULL,
+ TRUE /* checking only */));
/* If it is a posix class, leave the parse pointer at the
* '[' to fool regclass() into thinking it is part of a
* '[[:posix:]]'. */
no_close:
/* We output the messages even if warnings are off, because we'll fail
* the very next thing, and these give a likely diagnosis for that */
- if (posix_warnings) {
- SV * msg;
- while ((msg = av_shift(posix_warnings)) != &PL_sv_undef) {
- Perl_warner(aTHX_ packWARN(WARN_REGEXP), "%s", SvPVX(msg));
- SvREFCNT_dec_NN(msg);
- }
- SvREFCNT_dec_NN(posix_warnings);
+ if (posix_warnings && av_tindex_nomg(posix_warnings) >= 0) {
+ output_or_return_posix_warnings(pRExC_state, posix_warnings, NULL);
}
FAIL("Syntax error in (?[...])");
redo_curchar:
- top_index = av_tindex(stack);
+ top_index = av_tindex_nomg(stack);
switch (curchar) {
SV** stacked_ptr; /* Ptr to something already on 'stack' */
{
/* See if this is a [:posix:] class. */
bool is_posix_class = (OOB_NAMEDCLASS
- < handle_possible_posix(pRExC_state,
- RExC_parse + 1,
- NULL,
- NULL));
+ < handle_possible_posix(pRExC_state,
+ RExC_parse + 1,
+ NULL,
+ NULL,
+ TRUE /* checking only */));
/* If it is a posix class, leave the parse pointer at the '['
* to fool regclass() into thinking it is part of a
* '[[:posix:]]'. */
goto done;
case ')':
- if (av_tindex(fence_stack) < 0) {
+ if (av_tindex_nomg(fence_stack) < 0) {
RExC_parse++;
vFAIL("Unexpected ')'");
}
handle_operand:
/* Here 'current' is the operand. If something is already on the
- * stack, we have to check if it is a !. */
- top_index = av_tindex(stack); /* Code above may have altered the
- * stack in the time since we
- * earlier set 'top_index'. */
+ * stack, we have to check if it is a !. But first, the code above
+ * may have altered the stack in the time since we earlier set
+ * 'top_index'. */
+
+ top_index = av_tindex_nomg(stack);
if (top_index - fence >= 0) {
/* If the top entry on the stack is an operator, it had better
* be a '!', otherwise the entry below the top operand should
only_to_avoid_leaks = av_pop(stack);
SvREFCNT_dec(only_to_avoid_leaks);
- top_index = av_tindex(stack);
/* And we redo with the inverted operand. This allows
* handling multiple ! in a row */
} /* End of loop parsing through the construct */
done:
- if (av_tindex(fence_stack) >= 0) {
+ if (av_tindex_nomg(fence_stack) >= 0) {
vFAIL("Unmatched (");
}
- if (av_tindex(stack) < 0 /* Was empty */
+ if (av_tindex_nomg(stack) < 0 /* Was empty */
|| ((final = av_pop(stack)) == NULL)
|| ! IS_OPERAND(final)
|| SvTYPE(final) != SVt_INVLIST
- || av_tindex(stack) >= 0) /* More left on stack */
+ || av_tindex_nomg(stack) >= 0) /* More left on stack */
{
bad_syntax:
SvREFCNT_dec(final);
}
}
+STATIC void
+S_output_or_return_posix_warnings(pTHX_ RExC_state_t *pRExC_state, AV* posix_warnings, AV** return_posix_warnings)
+{
+ /* If the final parameter is NULL, output the elements of the array given
+ * by '*posix_warnings' as REGEXP warnings. Otherwise, the elements are
+ * pushed onto it, (creating if necessary) */
+
+ SV * msg;
+ const bool first_is_fatal = ! return_posix_warnings
+ && ckDEAD(packWARN(WARN_REGEXP));
+
+ PERL_ARGS_ASSERT_OUTPUT_OR_RETURN_POSIX_WARNINGS;
+
+ while ((msg = av_shift(posix_warnings)) != &PL_sv_undef) {
+ if (return_posix_warnings) {
+ if (! *return_posix_warnings) { /* mortalize to not leak if
+ warnings are fatal */
+ *return_posix_warnings = (AV *) sv_2mortal((SV *) newAV());
+ }
+ av_push(*return_posix_warnings, msg);
+ }
+ else {
+ if (first_is_fatal) { /* Avoid leaking this */
+ av_undef(posix_warnings); /* This isn't necessary if the
+ array is mortal, but is a
+ fail-safe */
+ (void) sv_2mortal(msg);
+ if (PASS2) {
+ SAVEFREESV(RExC_rx_sv);
+ }
+ }
+ Perl_warner(aTHX_ packWARN(WARN_REGEXP), "%s", SvPVX(msg));
+ SvREFCNT_dec_NN(msg);
+ }
+ }
+}
+
STATIC AV *
S_add_multi_match(pTHX_ AV* multi_char_matches, SV* multi_string, const STRLEN cp_count)
{
bool optimizable, /* ? Allow a non-ANYOF return
node */
SV** ret_invlist, /* Return an inversion list, not a node */
- AV** posix_warnings
+ AV** return_posix_warnings
)
{
/* parse a bracketed class specification. Most of these will produce an
const SSize_t orig_size = RExC_size;
bool posixl_matches_all = FALSE; /* Does /l class have both e.g. \W,\w ? */
- /* This variable is used to mark where in the input something that looks
- * like a POSIX construct ends. During the parse, when something looks
- * like it could be such a construct is encountered, it is checked for
- * being one, but not if we've already checked this area of the input.
- * Only after this position is reached do we check again */
- char *dont_check_for_posix_end = RExC_parse - 1;
+ /* This variable is used to mark where the end in the input is of something
+ * that looks like a POSIX construct but isn't. During the parse, when
+ * something looks like it could be such a construct is encountered, it is
+ * checked for being one, but not if we've already checked this area of the
+ * input. Only after this position is reached do we check again */
+ char *not_posix_region_end = RExC_parse - 1;
+
+ AV* posix_warnings = NULL;
+ const bool do_posix_warnings = return_posix_warnings
+ || (PASS2 && ckWARN(WARN_REGEXP));
GET_RE_DEBUG_FLAGS_DECL;
allow_multi_folds = FALSE;
#endif
- if (posix_warnings == NULL) {
- posix_warnings = (AV **) -1;
- }
-
/* Assume we are going to generate an ANYOF node. */
ret = reganode(pRExC_state,
(LOC)
/* Check that they didn't say [:posix:] instead of [[:posix:]] */
if (! ret_invlist && MAYBE_POSIXCC(UCHARAT(RExC_parse))) {
- char *class_end;
- int maybe_class = handle_possible_posix(pRExC_state, RExC_parse,
- &class_end, NULL);
- if (maybe_class >= OOB_NAMEDCLASS) {
- dont_check_for_posix_end = class_end;
- if (PASS2 && posix_warnings == (AV **) -1) {
- SAVEFREESV(RExC_rx_sv);
- ckWARN4reg(class_end,
- "POSIX syntax [%c %c] belongs inside character classes%s",
- *RExC_parse, *RExC_parse,
- (maybe_class == OOB_NAMEDCLASS)
- ? ((POSIXCC_NOTYET(*RExC_parse))
- ? " (but this one isn't implemented)"
- : " (but this one isn't fully valid)")
- : ""
- );
- (void)ReREFCNT_inc(RExC_rx_sv);
- }
- }
+ int maybe_class = handle_possible_posix(pRExC_state,
+ RExC_parse,
+ ¬_posix_region_end,
+ NULL,
+ TRUE /* checking only */);
+ if (PASS2 && maybe_class >= OOB_NAMEDCLASS && do_posix_warnings) {
+ SAVEFREESV(RExC_rx_sv);
+ ckWARN4reg(not_posix_region_end,
+ "POSIX syntax [%c %c] belongs inside character classes%s",
+ *RExC_parse, *RExC_parse,
+ (maybe_class == OOB_NAMEDCLASS)
+ ? ((POSIXCC_NOTYET(*RExC_parse))
+ ? " (but this one isn't implemented)"
+ : " (but this one isn't fully valid)")
+ : ""
+ );
+ (void)ReREFCNT_inc(RExC_rx_sv);
+ }
}
/* If the caller wants us to just parse a single element, accomplish this
goto charclassloop;
while (1) {
+
+ if ( posix_warnings
+ && av_tindex_nomg(posix_warnings) >= 0
+ && RExC_parse > not_posix_region_end)
+ {
+ /* Warnings about posix class issues are considered tentative until
+ * we are far enough along in the parse that we can no longer
+ * change our mind, at which point we either output them or add
+ * them, if it has so specified, to what gets returned to the
+ * caller. This is done each time through the loop so that a later
+ * class won't zap them before they have been dealt with. */
+ output_or_return_posix_warnings(pRExC_state, posix_warnings,
+ return_posix_warnings);
+ }
+
if (RExC_parse >= stop_ptr) {
break;
}
value = UCHARAT(RExC_parse++);
if (value == '[') {
- namedclass = handle_possible_posix(pRExC_state, RExC_parse, &dont_check_for_posix_end, posix_warnings);
+ char * posix_class_end;
+ namedclass = handle_possible_posix(pRExC_state,
+ RExC_parse,
+ &posix_class_end,
+ do_posix_warnings ? &posix_warnings : NULL,
+ FALSE /* die if error */);
if (namedclass > OOB_NAMEDCLASS) {
- RExC_parse = dont_check_for_posix_end;
+
+ /* If there was an earlier attempt to parse this particular
+ * posix class, and it failed, it was a false alarm, as this
+ * successful one proves */
+ if ( posix_warnings
+ && av_tindex_nomg(posix_warnings) >= 0
+ && not_posix_region_end >= RExC_parse
+ && not_posix_region_end <= posix_class_end)
+ {
+ av_undef(posix_warnings);
+ }
+
+ RExC_parse = posix_class_end;
+ }
+ else if (namedclass == OOB_NAMEDCLASS) {
+ not_posix_region_end = posix_class_end;
}
else {
namedclass = OOB_NAMEDCLASS;
}
}
- else if ( RExC_parse - 1 > dont_check_for_posix_end
+ else if ( RExC_parse - 1 > not_posix_region_end
&& MAYBE_POSIXCC(value))
{
- (void) handle_possible_posix(pRExC_state, RExC_parse - 1, /* -1 because parse has already been advanced */
- &dont_check_for_posix_end, posix_warnings);
+ (void) handle_possible_posix(
+ pRExC_state,
+ RExC_parse - 1, /* -1 because parse has already been
+ advanced */
+ ¬_posix_region_end,
+ do_posix_warnings ? &posix_warnings : NULL,
+ TRUE /* checking only */);
}
else if (value == '\\') {
/* Is a backslash; get the code point of the char after it */
+
+ if (RExC_parse >= RExC_end) {
+ vFAIL("Unmatched [");
+ }
+
if (UTF && ! UTF8_IS_INVARIANT(UCHARAT(RExC_parse))) {
value = utf8n_to_uvchr((U8*)RExC_parse,
RExC_end - RExC_parse,
SV* invlist;
char* name;
char* base_name; /* name after any packages are stripped */
+ char* lookup_name = NULL;
const char * const colon_colon = "::";
/* Try to get the definition of the property into
* will have its name be <__NAME_i>. The design is
* discussed in commit
* 2f833f5208e26b208886e51e09e2c072b5eabb46 */
- name = savepv(Perl_form(aTHX_
- "%s%.*s%s\n",
- (FOLD) ? "__" : "",
- (int)n,
- RExC_parse,
- (FOLD) ? "_i" : ""
- ));
+ name = savepv(Perl_form(aTHX_ "%.*s", (int)n, RExC_parse));
+ SAVEFREEPV(name);
+ if (FOLD) {
+ lookup_name = savepv(Perl_form(aTHX_ "__%s_i", name));
+
+ /* The function call just below that uses this can fail
+ * to return, leaking memory if we don't do this */
+ SAVEFREEPV(lookup_name);
+ }
/* Look up the property name, and get its swash and
* inversion list, if the property is found */
SvREFCNT_dec(swash); /* Free any left-overs */
- swash = _core_swash_init("utf8", name, &PL_sv_undef,
+ swash = _core_swash_init("utf8",
+ (lookup_name)
+ ? lookup_name
+ : name,
+ &PL_sv_undef,
1, /* binary */
0, /* not tr/// */
NULL, /* No inversion list */
pkgname,
name);
n = strlen(full_name);
- Safefree(name);
name = savepvn(full_name, n);
+ SAVEFREEPV(name);
}
}
- Perl_sv_catpvf(aTHX_ listsv, "%cutf8::%"UTF8f"\n",
+ Perl_sv_catpvf(aTHX_ listsv, "%cutf8::%s%"UTF8f"%s\n",
(value == 'p' ? '+' : '!'),
- UTF8fARG(UTF, n, name));
+ (FOLD) ? "__" : "",
+ UTF8fARG(UTF, n, name),
+ (FOLD) ? "_i" : "");
has_user_defined_property = TRUE;
optimizable = FALSE; /* Will have to leave this an
ANYOF node */
_invlist_union(properties, invlist, &properties);
}
}
- Safefree(name);
}
RExC_parse = e + 1;
namedclass = ANYOF_UNIPROP; /* no official name, but it's
range = 0; /* this range (if it was one) is done now */
} /* End of loop through all the text within the brackets */
+
+ if ( posix_warnings && av_tindex_nomg(posix_warnings) >= 0) {
+ output_or_return_posix_warnings(pRExC_state, posix_warnings,
+ return_posix_warnings);
+ }
+
/* If anything in the class expands to more than one character, we have to
* deal with them by building up a substitute parse string, and recursively
* calling reg() on it, instead of proceeding */
#endif
/* Look at the longest folds first */
- for (cp_count = av_tindex(multi_char_matches); cp_count > 0; cp_count--) {
+ for (cp_count = av_tindex_nomg(multi_char_matches);
+ cp_count > 0;
+ cp_count--)
+ {
if (av_exists(multi_char_matches, cp_count)) {
AV** this_array_ptr;
{
AV* list = (AV*) *listp;
IV k;
- for (k = 0; k <= av_tindex(list); k++) {
+ for (k = 0; k <= av_tindex_nomg(list); k++) {
SV** c_p = av_fetch(list, k, FALSE);
UV c;
assert(c_p);
si = *ary; /* ary[0] = the string to initialize the swash with */
- if (av_tindex(av) >= 2) {
+ if (av_tindex_nomg(av) >= 2) {
if (only_utf8_locale_ptr
&& ary[2]
&& ary[2] != &PL_sv_undef)
* is any inversion list generated at compile time; [4]
* indicates if that inversion list has any user-defined
* properties in it. */
- if (av_tindex(av) >= 3) {
+ if (av_tindex_nomg(av) >= 3) {
invlist = ary[3];
if (SvUV(ary[4])) {
swash_init_flags |= _CORE_SWASH_INIT_USER_DEFINED_PROPERTY;
sv_catpvs(matches_string, " ");
} /* end of loop through the text */
+ assert(matches_string);
if (SvCUR(matches_string)) { /* Get rid of trailing blank */
SvCUR_set(matches_string, SvCUR(matches_string) - 1);
}
if (RExC_open_parens) {
int paren;
/*DEBUG_PARSE_FMT("inst"," - %"IVdf, (IV)RExC_npar);*/
+ /* remember that RExC_npar is rex->nparens + 1,
+ * iow it is 1 more than the number of parens seen in
+ * the pattern so far. */
for ( paren=0 ; paren < RExC_npar ; paren++ ) {
if ( RExC_open_parens[paren] >= opnd ) {
/*DEBUG_PARSE_FMT("open"," - %d",size);*/
}
}
}
+ if (RExC_end_op)
+ RExC_end_op += size;
while (src > opnd) {
StructCopy(--src, --dst, regnode);
DEBUG_PARSE_r({
DEBUG_PARSE_MSG((scan==p ? "tail" : ""));
regprop(RExC_rx, RExC_mysv, scan, NULL, pRExC_state);
- PerlIO_printf(Perl_debug_log, "~ %s (%d) %s %s\n",
+ Perl_re_printf( aTHX_ "~ %s (%d) %s %s\n",
SvPV_nolen_const(RExC_mysv), REG_NODE_NUM(scan),
(temp == NULL ? "->" : ""),
(temp == NULL ? PL_reg_name[OP(val)] : "")
DEBUG_PARSE_r({
DEBUG_PARSE_MSG((scan==p ? "tsdy" : ""));
regprop(RExC_rx, RExC_mysv, scan, NULL, pRExC_state);
- PerlIO_printf(Perl_debug_log, "~ %s (%d) -> %s\n",
+ Perl_re_printf( aTHX_ "~ %s (%d) -> %s\n",
SvPV_nolen_const(RExC_mysv),
REG_NODE_NUM(scan),
PL_reg_name[exact]);
DEBUG_PARSE_r({
DEBUG_PARSE_MSG("");
regprop(RExC_rx, RExC_mysv, val, NULL, pRExC_state);
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"~ attach to %s (%"IVdf") offset to %"IVdf"\n",
SvPV_nolen_const(RExC_mysv),
(IV)REG_NODE_NUM(val),
for (bit=0; bit<REG_INTFLAGS_NAME_SIZE; bit++) {
if (flags & (1<<bit)) {
if (!set++ && lead)
- PerlIO_printf(Perl_debug_log, "%s",lead);
- PerlIO_printf(Perl_debug_log, "%s ",PL_reg_intflags_name[bit]);
+ Perl_re_printf( aTHX_ "%s",lead);
+ Perl_re_printf( aTHX_ "%s ",PL_reg_intflags_name[bit]);
}
}
if (lead) {
if (set)
- PerlIO_printf(Perl_debug_log, "\n");
+ Perl_re_printf( aTHX_ "\n");
else
- PerlIO_printf(Perl_debug_log, "%s[none-set]\n",lead);
+ Perl_re_printf( aTHX_ "%s[none-set]\n",lead);
}
}
continue;
}
if (!set++ && lead)
- PerlIO_printf(Perl_debug_log, "%s",lead);
- PerlIO_printf(Perl_debug_log, "%s ",PL_reg_extflags_name[bit]);
+ Perl_re_printf( aTHX_ "%s",lead);
+ Perl_re_printf( aTHX_ "%s ",PL_reg_extflags_name[bit]);
}
}
if ((cs = get_regex_charset(flags)) != REGEX_DEPENDS_CHARSET) {
if (!set++ && lead) {
- PerlIO_printf(Perl_debug_log, "%s",lead);
+ Perl_re_printf( aTHX_ "%s",lead);
}
switch (cs) {
case REGEX_UNICODE_CHARSET:
- PerlIO_printf(Perl_debug_log, "UNICODE");
+ Perl_re_printf( aTHX_ "UNICODE");
break;
case REGEX_LOCALE_CHARSET:
- PerlIO_printf(Perl_debug_log, "LOCALE");
+ Perl_re_printf( aTHX_ "LOCALE");
break;
case REGEX_ASCII_RESTRICTED_CHARSET:
- PerlIO_printf(Perl_debug_log, "ASCII-RESTRICTED");
+ Perl_re_printf( aTHX_ "ASCII-RESTRICTED");
break;
case REGEX_ASCII_MORE_RESTRICTED_CHARSET:
- PerlIO_printf(Perl_debug_log, "ASCII-MORE_RESTRICTED");
+ Perl_re_printf( aTHX_ "ASCII-MORE_RESTRICTED");
break;
default:
- PerlIO_printf(Perl_debug_log, "UNKNOWN CHARACTER SET");
+ Perl_re_printf( aTHX_ "UNKNOWN CHARACTER SET");
break;
}
}
if (lead) {
if (set)
- PerlIO_printf(Perl_debug_log, "\n");
+ Perl_re_printf( aTHX_ "\n");
else
- PerlIO_printf(Perl_debug_log, "%s[none-set]\n",lead);
+ Perl_re_printf( aTHX_ "%s[none-set]\n",lead);
}
}
#endif
if (r->anchored_substr) {
RE_PV_QUOTED_DECL(s, 0, dsv, SvPVX_const(r->anchored_substr),
RE_SV_DUMPLEN(r->anchored_substr), 30);
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"anchored %s%s at %"IVdf" ",
s, RE_SV_TAIL(r->anchored_substr),
(IV)r->anchored_offset);
} else if (r->anchored_utf8) {
RE_PV_QUOTED_DECL(s, 1, dsv, SvPVX_const(r->anchored_utf8),
RE_SV_DUMPLEN(r->anchored_utf8), 30);
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"anchored utf8 %s%s at %"IVdf" ",
s, RE_SV_TAIL(r->anchored_utf8),
(IV)r->anchored_offset);
if (r->float_substr) {
RE_PV_QUOTED_DECL(s, 0, dsv, SvPVX_const(r->float_substr),
RE_SV_DUMPLEN(r->float_substr), 30);
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"floating %s%s at %"IVdf"..%"UVuf" ",
s, RE_SV_TAIL(r->float_substr),
(IV)r->float_min_offset, (UV)r->float_max_offset);
} else if (r->float_utf8) {
RE_PV_QUOTED_DECL(s, 1, dsv, SvPVX_const(r->float_utf8),
RE_SV_DUMPLEN(r->float_utf8), 30);
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"floating utf8 %s%s at %"IVdf"..%"UVuf" ",
s, RE_SV_TAIL(r->float_utf8),
(IV)r->float_min_offset, (UV)r->float_max_offset);
}
if (r->check_substr || r->check_utf8)
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
(const char *)
(r->check_substr == r->float_substr
&& r->check_utf8 == r->float_utf8
? "(checking floating" : "(checking anchored"));
if (r->intflags & PREGf_NOSCAN)
- PerlIO_printf(Perl_debug_log, " noscan");
+ Perl_re_printf( aTHX_ " noscan");
if (r->extflags & RXf_CHECK_ALL)
- PerlIO_printf(Perl_debug_log, " isall");
+ Perl_re_printf( aTHX_ " isall");
if (r->check_substr || r->check_utf8)
- PerlIO_printf(Perl_debug_log, ") ");
+ Perl_re_printf( aTHX_ ") ");
if (ri->regstclass) {
regprop(r, sv, ri->regstclass, NULL, NULL);
- PerlIO_printf(Perl_debug_log, "stclass %s ", SvPVX_const(sv));
+ Perl_re_printf( aTHX_ "stclass %s ", SvPVX_const(sv));
}
if (r->intflags & PREGf_ANCH) {
- PerlIO_printf(Perl_debug_log, "anchored");
+ Perl_re_printf( aTHX_ "anchored");
if (r->intflags & PREGf_ANCH_MBOL)
- PerlIO_printf(Perl_debug_log, "(MBOL)");
+ Perl_re_printf( aTHX_ "(MBOL)");
if (r->intflags & PREGf_ANCH_SBOL)
- PerlIO_printf(Perl_debug_log, "(SBOL)");
+ Perl_re_printf( aTHX_ "(SBOL)");
if (r->intflags & PREGf_ANCH_GPOS)
- PerlIO_printf(Perl_debug_log, "(GPOS)");
- (void)PerlIO_putc(Perl_debug_log, ' ');
+ Perl_re_printf( aTHX_ "(GPOS)");
+ Perl_re_printf( aTHX_ " ");
}
if (r->intflags & PREGf_GPOS_SEEN)
- PerlIO_printf(Perl_debug_log, "GPOS:%"UVuf" ", (UV)r->gofs);
+ Perl_re_printf( aTHX_ "GPOS:%"UVuf" ", (UV)r->gofs);
if (r->intflags & PREGf_SKIP)
- PerlIO_printf(Perl_debug_log, "plus ");
+ Perl_re_printf( aTHX_ "plus ");
if (r->intflags & PREGf_IMPLICIT)
- PerlIO_printf(Perl_debug_log, "implicit ");
- PerlIO_printf(Perl_debug_log, "minlen %"IVdf" ", (IV)r->minlen);
+ Perl_re_printf( aTHX_ "implicit ");
+ Perl_re_printf( aTHX_ "minlen %"IVdf" ", (IV)r->minlen);
if (r->extflags & RXf_EVAL_SEEN)
- PerlIO_printf(Perl_debug_log, "with eval ");
- PerlIO_printf(Perl_debug_log, "\n");
+ Perl_re_printf( aTHX_ "with eval ");
+ Perl_re_printf( aTHX_ "\n");
DEBUG_FLAGS_r({
regdump_extflags("r->extflags: ",r->extflags);
regdump_intflags("r->intflags: ",r->intflags);
}
/* Paren and offset */
- Perl_sv_catpvf(aTHX_ sv, "%d[%+d]", (int)ARG(o),(int)ARG2L(o));
+ Perl_sv_catpvf(aTHX_ sv, "%d[%+d:%d]", (int)ARG(o),(int)ARG2L(o),
+ (int)((o + (int)ARG2L(o)) - progi->program) );
if (name_list) {
SV **name= av_fetch(name_list, ARG(o), 0 );
if (name)
}
/* And, finally, add the above-the-bitmap stuff */
- if (nonbitmap_invlist) {
+ if (nonbitmap_invlist && _invlist_len(nonbitmap_invlist)) {
SV* contents;
/* See if truncation size is overridden */
? prog->check_utf8 : prog->check_substr);
if (!PL_colorset) reginitcolors();
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"%sUsing REx %ssubstr:%s \"%s%.60s%s%s\"\n",
PL_colors[4],
RX_UTF8(r) ? "utf8 " : "",
#endif
Safefree(r->offs);
SvREFCNT_dec(r->qr_anoncv);
+ if (r->recurse_locinput)
+ Safefree(r->recurse_locinput);
rx->sv_u.svu_rx = 0;
}
#endif
ret->mother_re = ReREFCNT_inc(r->mother_re ? r->mother_re : rx);
SvREFCNT_inc_void(ret->qr_anoncv);
+ if (r->recurse_locinput)
+ Newxz(ret->recurse_locinput,r->nparens + 1,char *);
return ret_x;
}
SV *dsv= sv_newmortal();
RE_PV_QUOTED_DECL(s, RX_UTF8(rx),
dsv, RX_PRECOMP(rx), RX_PRELEN(rx), 60);
- PerlIO_printf(Perl_debug_log,"%sFreeing REx:%s %s\n",
+ Perl_re_printf( aTHX_ "%sFreeing REx:%s %s\n",
PL_colors[4],PL_colors[5],s);
}
});
#define SAVEPVN(p,n) ((p) ? savepvn(p,n) : NULL)
/*
- re_dup - duplicate a regexp.
+ re_dup_guts - duplicate a regexp.
This routine is expected to clone a given regexp structure. It is only
compiled under USE_ITHREADS.
RXp_PAREN_NAMES(ret) = hv_dup_inc(RXp_PAREN_NAMES(ret), param);
ret->qr_anoncv = MUTABLE_CV(sv_dup_inc((const SV *)ret->qr_anoncv, param));
+ if (r->recurse_locinput)
+ Newxz(ret->recurse_locinput,r->nparens + 1,char *);
if (ret->pprivate)
RXi_SET(ret,CALLREGDUPE_PVT(dstr,param));
char, regexp_internal);
Copy(ri->program, reti->program, len+1, regnode);
+
reti->num_code_blocks = ri->num_code_blocks;
if (ri->code_blocks) {
int n;
d->data[i] = ri->data->data[i];
break;
default:
- Perl_croak(aTHX_ "panic: re_dup unknown data code '%c'",
+ Perl_croak(aTHX_ "panic: re_dup_guts unknown data code '%c'",
ri->data->what[i]);
}
}
/* And this flag for matching all non-ASCII 0xFF and below */
if (flags & ANYOF_SHARED_d_MATCHES_ALL_NON_UTF8_NON_ASCII_non_d_WARN_SUPER)
{
- if (invert) {
- not_utf8 = _new_invlist(0);
- }
- else {
- not_utf8 = invlist_clone(PL_UpperLatin1);
- }
- inverting_allowed = FALSE; /* XXX needs more work to be able
- to allow this */
+ not_utf8 = invlist_clone(PL_UpperLatin1);
}
}
else if (OP(node) == ANYOFL) {
/* Accumulate the bit map into the unconditional match list */
for (i = 0; i < NUM_ANYOF_CODE_POINTS; i++) {
if (BITMAP_TEST(bitmap, i)) {
- invlist = add_cp_to_invlist(invlist, i);
+ int start = i++;
+ for (; i < NUM_ANYOF_CODE_POINTS && BITMAP_TEST(bitmap, i); i++) {
+ /* empty */
+ }
+ invlist = _add_range_to_invlist(invlist, start, i-1);
}
}
* conditional code points, so that when inverted, they will be gone
* from it */
_invlist_union(only_utf8, invlist, &invlist);
+ _invlist_union(not_utf8, invlist, &invlist);
_invlist_union(only_utf8_locale, invlist, &invlist);
_invlist_invert(invlist);
_invlist_intersection(invlist, PL_InBitmap, &invlist);
return SvCUR(sv) > orig_sv_cur;
}
-#define CLEAR_OPTSTART \
+#define CLEAR_OPTSTART \
if (optstart) STMT_START { \
- DEBUG_OPTIMISE_r(PerlIO_printf(Perl_debug_log, \
+ DEBUG_OPTIMISE_r(Perl_re_printf( aTHX_ \
" (%"IVdf" nodes)\n", (IV)(node - optstart))); \
- optstart=NULL; \
+ optstart=NULL; \
} STMT_END
#define DUMPUNTIL(b,e) \
PERL_ARGS_ASSERT_DUMPUNTIL;
#ifdef DEBUG_DUMPUNTIL
- PerlIO_printf(Perl_debug_log, "--- %d : %d - %d - %d\n",indent,node-start,
+ Perl_re_printf( aTHX_ "--- %d : %d - %d - %d\n",indent,node-start,
last ? last-start : 0,plast ? plast-start : 0);
#endif
CLEAR_OPTSTART;
regprop(r, sv, node, NULL, NULL);
- PerlIO_printf(Perl_debug_log, "%4"IVdf":%*s%s", (IV)(node - start),
+ Perl_re_printf( aTHX_ "%4"IVdf":%*s%s", (IV)(node - start),
(int)(2*indent + 1), "", SvPVX_const(sv));
if (OP(node) != OPTIMIZED) {
if (next == NULL) /* Next ptr. */
- PerlIO_printf(Perl_debug_log, " (0)");
+ Perl_re_printf( aTHX_ " (0)");
else if (PL_regkind[(U8)op] == BRANCH
&& PL_regkind[OP(next)] != BRANCH )
- PerlIO_printf(Perl_debug_log, " (FAIL)");
+ Perl_re_printf( aTHX_ " (FAIL)");
else
- PerlIO_printf(Perl_debug_log, " (%"IVdf")", (IV)(next - start));
- (void)PerlIO_putc(Perl_debug_log, '\n');
+ Perl_re_printf( aTHX_ " (%"IVdf")", (IV)(next - start));
+ Perl_re_printf( aTHX_ "\n");
}
after_print:
for (word_idx= 0; word_idx < (I32)trie->wordcount; word_idx++) {
SV ** const elem_ptr = av_fetch(trie_words,word_idx,0);
- PerlIO_printf(Perl_debug_log, "%*s%s ",
- (int)(2*(indent+3)), "",
+ Perl_re_indentf( aTHX_ "%s ",
+ indent+3,
elem_ptr
? pv_pretty(sv, SvPV_nolen_const(*elem_ptr),
SvCUR(*elem_ptr), 60,
);
if (trie->jump) {
U16 dist= trie->jump[word_idx+1];
- PerlIO_printf(Perl_debug_log, "(%"UVuf")\n",
+ Perl_re_printf( aTHX_ "(%"UVuf")\n",
(UV)((dist ? this_trie + dist : next) - start));
if (dist) {
if (!nextbranch)
if (nextbranch && PL_regkind[OP(nextbranch)]==BRANCH)
nextbranch= regnext((regnode *)nextbranch);
} else {
- PerlIO_printf(Perl_debug_log, "\n");
+ Perl_re_printf( aTHX_ "\n");
}
}
if (last && next > last)
}
CLEAR_OPTSTART;
#ifdef DEBUG_DUMPUNTIL
- PerlIO_printf(Perl_debug_log, "--- %d\n", (int)indent);
+ Perl_re_printf( aTHX_ "--- %d\n", (int)indent);
#endif
return node;
}
/* This is the stuff that used to live in regexp.h that was truly
private to the engine itself. It now lives here. */
-
-
typedef struct regexp_internal {
int name_list_idx; /* Optional data index of an array of paren names */
union {
#define PREGf_ANCH_MBOL 0x00000400
#define PREGf_ANCH_SBOL 0x00000800
#define PREGf_ANCH_GPOS 0x00001000
+#define PREGf_RECURSE_SEEN 0x00002000
#define PREGf_ANCH \
( PREGf_ANCH_SBOL | PREGf_ANCH_GPOS | PREGf_ANCH_MBOL )
#define REG_CUTGROUP_SEEN 0x00000100
#define REG_RUN_ON_COMMENT_SEEN 0x00000200
#define REG_UNFOLDED_MULTI_SEEN 0x00000400
-#define REG_GOSTART_SEEN 0x00000800
+/* spare */
#define REG_UNBOUNDED_QUANTIFIER_SEEN 0x00001000
#*Regex Subroutines
GOSUB GOSUB, num/ofs 2L ; recurse to paren arg1 at (signed) ofs arg2
-GOSTART GOSTART, no ; recurse to start of pattern
#*Special conditionals
NGROUPP NGROUPP, no-sv 1 ; Whether the group matched.
my $in_file_pound_if = 0;
+my $max_hdr_len = 3; # In headings, how wide a name is allowed?
+
print $out_fh "/* See the generating file for comments */\n\n";
# The symbols generated by this program are all currently defined only in a
);
# This hash contains the properties with enums that have hard-coded references
-# to them in C code. Its only use is to make sure that if perl is compiled
+# to them in C code. It is neeed to make sure that if perl is compiled
# with an older Unicode data set, that all the enum values the code is
# expecting will still be in the enum typedef. Thus the code doesn't have to
-# change. The Unicode version won't have any code points that have these enum
-# values, so the code that handles them will not get exercised. This is far
-# better than having to #ifdef things.
+# change. The Unicode version won't have any code points that have the enum
+# values not in that version, so the code that handles them will not get
+# exercised. This is far better than having to #ifdef things. The names here
+# should be the long names of the respective property values. The reason for
+# this is because regexec.c uses them as case labels, and the long name is
+# generally more understandable than the short.
my %hard_coded_enums =
( gcb => [
'Control',
my %gcb_enums;
my @gcb_short_enums;
+my %gcb_abbreviations;
my %lb_enums;
my @lb_short_enums;
+my %lb_abbreviations;
my %wb_enums;
my @wb_short_enums;
+my %wb_abbreviations;
my @a2n;
else {
@enums = uniques(@$invmap);
}
+
if (! @enums) {
die "Only enum properties are currently handled; '$prop_name' isn't one";
}
else {
-
- # Convert short names to long
- @enums = map { (prop_value_aliases($prop_name, $_))[1] } @enums;
-
my @expected_enums = @{$hard_coded_enums{lc $short_name}};
- die 'You need to update %hard_coded_enums to reflect new entries in this Unicode version'
- if @expected_enums < @enums;
-
- # Remove the enums found in the input from the ones we expect
- for (my $i = @expected_enums - 1; $i >= 0; $i--) {
- splice(@expected_enums, $i, 1)
- if grep { $expected_enums[$i] eq $_ } @enums;
- }
+ my @canonical_input_enums;
+ if (@expected_enums) {
+ if (@expected_enums < @enums) {
+ die 'You need to update %hard_coded_enums to reflect new'
+ . " entries in this Unicode version\n"
+ . "Expected: " . join(", ", sort @expected_enums) . "\n"
+ . " Got: " . join(", ", sort @enums);
+ }
- # The ones remaining must be because we're using an older
- # Unicode version. Add them to the list.
- push @enums, @expected_enums;
+ if (! defined prop_aliases($prop_name)) {
- # Add in the extra values coded into this program, and sort.
- @enums = sort @enums;
+ # Convert the input enums into canonical form and
+ # save for use below
+ @canonical_input_enums = map { lc ($_ =~ s/_//gr) }
+ @enums;
+ }
+ @enums = sort @expected_enums;
+ }
- # The internal enums comes last.
- push @enums, split /,/, $extra_enums if $extra_enums ne "";
+ # The internal enums come last, and in the order specified
+ my @extras;
+ if ($extra_enums ne "") {
+ @extras = split /,/, $extra_enums;
+ push @enums, @extras;
+ }
# Assign a value to each element of the enum. The default
# value always gets 0; the others are arbitrarily assigned.
$enums{$enum} = $enum_val++ unless exists $enums{$enum};
}
- # Calculate the enum values for properties _Perl_GCB and
- # _Perl_LB because we output special tables for them
- if ($name eq '_Perl_GCB' && ! %gcb_enums) {
- while (my ($enum, $value) = each %enums) {
- my ($short) = prop_value_aliases('GCB', $enum);
- $short = lc $enum unless defined $short;
- $gcb_enums{$short} = $value;
- @gcb_short_enums[$value] = $short;
- }
- }
- elsif ($name eq '_Perl_LB' && ! %lb_enums) {
- while (my ($enum, $value) = each %enums) {
- my ($short) = prop_value_aliases('LB', $enum);
- $short = substr(lc $enum, 0, 2) unless defined $short;
- $lb_enums{$short} = $value;
- @lb_short_enums[$value] = $short;
- }
- }
- elsif ($name eq '_Perl_WB' && ! %wb_enums) {
- while (my ($enum, $value) = each %enums) {
- my ($short) = prop_value_aliases('WB', $enum);
- $short = lc $enum unless defined $short;
- $short = substr($short, 0, 2);
-
- # Special case a better name than the kludgy one
- $short = 'hs' if $short eq 'pe';
-
- $wb_enums{$short} = $value;
- @wb_short_enums[$value] = $short;
+ # Calculate the enum values for certain properties like
+ # _Perl_GCB and _Perl_LB, because we output special tables for
+ # them.
+ if ($name =~ / ^ _Perl_ (?: GCB | LB | WB ) $ /x) {
+
+ # We use string evals to allow the same code to work on
+ # all tables we're doing.
+ my $type = lc $prop_name;
+
+ # We use lowercase single letter names for any property
+ # values not in the release of Unicode being compiled now.
+ my $placeholder = "a";
+
+ # Skip if we've already done this code, which populated
+ # this hash
+ if (eval "! \%${type}_enums") {
+
+ # For each enum ...
+ foreach my $enum (sort keys %enums) {
+ my $value = $enums{$enum};
+ my $short;
+ my $abbreviated_from;
+
+ # Special case this wb property value to make the
+ # name more clear
+ if ($enum eq 'Perl_Tailored_HSpace') {
+ $short = 'hs';
+ $abbreviated_from = $enum;
+ }
+ elsif (grep { $_ eq $enum } @extras) {
+
+ # The 'short' name for one of the property
+ # values added by this file is just the
+ # lowercase of it
+ $short = lc $enum;
+ }
+ elsif (grep {$_ eq lc ( $enum =~ s/_//gr) }
+ @canonical_input_enums)
+ { # On Unicode versions that predate the
+ # official property, we have set up this array
+ # to be the canonical form of each enum in the
+ # substitute property. If the enum we're
+ # looking at is canonically the same as one of
+ # these, use its name instead of generating a
+ # placeholder one in the next clause (which
+ # will happen because prop_value_aliases()
+ # will fail because it only works on official
+ # properties)
+ $short = $enum;
+ }
+ else {
+ # Use the official short name for the other
+ # property values, which should all be
+ # official ones.
+ ($short) = prop_value_aliases($type, $enum);
+
+ # But create a placeholder for ones not in
+ # this Unicode version.
+ $short = $placeholder++ unless defined $short;
+ }
+
+ # If our short name is too long, or we already
+ # know that the name is an abbreviation, truncate
+ # to make sure it's short enough, and remember
+ # that we did this so we can later place in a
+ # comment in the generated file
+ if ( $abbreviated_from
+ || length $short > $max_hdr_len)
+ {
+ $short = substr($short, 0, $max_hdr_len);
+ $abbreviated_from = $enum
+ unless $abbreviated_from;
+ # If the name we are to display conflicts, try
+ # another.
+ while (eval "exists
+ \$${type}_abbreviations{$short}")
+ {
+ die $@ if $@;
+ $short++;
+ }
+
+ eval "\$${type}_abbreviations{$short} = '$enum'";
+ die $@ if $@;
+ }
+
+ # Remember the mapping from the property value
+ # (enum) name to its value.
+ eval "\$${type}_enums{$enum} = $value";
+ die $@ if $@;
+
+ # Remember the inverse mapping to the short name
+ # so that we can properly label the generated
+ # table's rows and columns
+ eval "\$${type}_short_enums[$value] = '$short'";
+ die $@ if $@;
+ }
}
}
}
return mk_invlist_from_sorted_cp_list([ 128 .. 255 ]);
}
+sub output_table_common {
+
+ # Common subroutine to actually output the generated rules table.
+
+ my ($property,
+ $table_value_defines_ref,
+ $table_ref,
+ $names_ref,
+ $abbreviations_ref) = @_;
+ my $size = @$table_ref;
+
+ # Output the #define list, sorted by numeric value
+ if ($table_value_defines_ref) {
+ my $max_name_length = 0;
+ my @defines;
+
+ # Put in order, and at the same time find the longest name
+ while (my ($enum, $value) = each %$table_value_defines_ref) {
+ $defines[$value] = $enum;
+
+ my $length = length $enum;
+ $max_name_length = $length if $length > $max_name_length;
+ }
+
+ print $out_fh "\n";
+
+ # Output, so that the values are vertically aligned in a column after
+ # the longest name
+ foreach my $i (0 .. @defines - 1) {
+ next unless defined $defines[$i];
+ printf $out_fh "#define %-*s %2d\n",
+ $max_name_length,
+ $defines[$i],
+ $i;
+ }
+ }
+
+ my $column_width = 2; # We currently allow 2 digits for the number
+
+ # If the maximum value in the table is 1, it can be a bool. (Being above
+ # a U8 is not currently handled
+ my $max_element = 0;
+ for my $i (0 .. $size - 1) {
+ for my $j (0 .. $size - 1) {
+ next if $max_element >= $table_ref->[$i][$j];
+ $max_element = $table_ref->[$i][$j];
+ }
+ }
+ die "Need wider table column width given '$max_element"
+ if length $max_element > $column_width;
+
+ my $table_type = ($max_element == 1)
+ ? 'bool'
+ : 'U8';
+
+ # If a name is longer than the width set aside for a column, its column
+ # needs to have increased spacing so that the name doesn't get truncated
+ # nor run into an adjacent column
+ my @spacers;
+
+ # If we are being compiled on a Unicode version earlier than that which
+ # this file was designed for, it may be that some of the property values
+ # aren't in the current release, and so would be undefined if we didn't
+ # define them ourselves. Earlier code has done this, making them
+ # lowercase characters of length one. We look to see if any exist, so
+ # that we can add an annotation to the output table
+ my $has_placeholder = 0;
+
+ for my $i (0 .. $size - 1) {
+ no warnings 'numeric';
+ $has_placeholder = 1 if $names_ref->[$i] =~ / ^ [[:lower:]] $ /ax;
+ $spacers[$i] = " " x (length($names_ref->[$i]) - $column_width);
+ }
+
+ print $out_fh "\nstatic const $table_type ${property}_table[$size][$size] = {\n";
+
+ # Calculate the column heading line
+ my $header_line = "/* "
+ . (" " x $max_hdr_len) # We let the row heading meld to
+ # the '*/' for those that are at
+ # the max
+ . " " x 3; # Space for '*/ '
+ # Now each column
+ for my $i (0 .. $size - 1) {
+ $header_line .= sprintf "%s%*s",
+ $spacers[$i],
+ $column_width + 1, # 1 for the ','
+ $names_ref->[$i];
+ }
+ $header_line .= " */\n";
+
+ # If we have annotations, output it now.
+ if ($has_placeholder || scalar %$abbreviations_ref) {
+ my $text = "";
+ foreach my $abbr (sort keys %$abbreviations_ref) {
+ $text .= "; " if $text;
+ $text .= "'$abbr' stands for '$abbreviations_ref->{$abbr}'";
+ }
+ if ($has_placeholder) {
+ $text .= "; other " if $text;
+ $text .= "lowercase names are placeholders for"
+ . " property values not defined until a later Unicode"
+ . " release, so are irrelevant in this one, as they are"
+ . " not assigned to any code points";
+ }
+
+ my $indent = " " x 3;
+ $text = $indent . "/* $text */";
+
+ # Wrap the text so that it is no wider than the table, which the
+ # header line gives.
+ my $output_width = length $header_line;
+ while (length $text > $output_width) {
+ my $cur_line = substr($text, 0, $output_width);
+
+ # Find the first blank back from the right end to wrap at.
+ for (my $i = $output_width -1; $i > 0; $i--) {
+ if (substr($text, $i, 1) eq " ") {
+ print $out_fh substr($text, 0, $i), "\n";
+
+ # Set so will look at just the remaining tail (which will
+ # be indented and have a '*' after the indent
+ $text = $indent . " * " . substr($text, $i + 1);
+ last;
+ }
+ }
+ }
+
+ # And any remaining
+ print $out_fh $text, "\n" if $text;
+ }
+
+ # We calculated the header line earlier just to get its width so that we
+ # could make sure the annotations fit into that.
+ print $out_fh $header_line;
+
+ # Now output the bulk of the table.
+ for my $i (0 .. $size - 1) {
+
+ # First the row heading.
+ printf $out_fh "/* %-*s*/ ", $max_hdr_len, $names_ref->[$i];
+ print $out_fh "{"; # Then the brace for this row
+
+ # Then each column
+ for my $j (0 .. $size -1) {
+ print $out_fh $spacers[$j];
+ printf $out_fh "%*d", $column_width, $table_ref->[$i][$j];
+ print $out_fh "," if $j < $size - 1;
+ }
+ print $out_fh " }";
+ print $out_fh "," if $i < $size - 1;
+ print $out_fh "\n";
+ }
+
+ print $out_fh "};\n";
+}
+
sub output_GCB_table() {
# Create and output the pair table for use in determining Grapheme Cluster
# GB9a × SpacingMark
# GB9b Prepend ×
for my $i (0 .. @gcb_table - 1) {
- $gcb_table[$i][$gcb_enums{'EX'}] = 0;
- $gcb_table[$i][$gcb_enums{'SM'}] = 0;
- $gcb_table[$gcb_enums{'PP'}][$i] = 0;
+ $gcb_table[$i][$gcb_enums{'Extend'}] = 0;
+ $gcb_table[$i][$gcb_enums{'SpacingMark'}] = 0;
+ $gcb_table[$gcb_enums{'Prepend'}][$i] = 0;
}
# Do not break between regional indicator symbols.
# GB8a Regional_Indicator × Regional_Indicator
- $gcb_table[$gcb_enums{'RI'}][$gcb_enums{'RI'}] = 0;
+ $gcb_table[$gcb_enums{'Regional_Indicator'}]
+ [$gcb_enums{'Regional_Indicator'}] = 0;
# Do not break Hangul syllable sequences.
# GB8 ( LVT | T) × T
$gcb_table[$gcb_enums{'L'}][$gcb_enums{'LV'}] = 0;
$gcb_table[$gcb_enums{'L'}][$gcb_enums{'LVT'}] = 0;
- # Do not break between a CR and LF. Otherwise, break before and after controls.
+ # Do not break between a CR and LF. Otherwise, break before and after
+ # controls.
# GB5 ÷ ( Control | CR | LF )
# GB4 ( Control | CR | LF ) ÷
for my $i (0 .. @gcb_table - 1) {
- $gcb_table[$i][$gcb_enums{'CN'}] = 1;
+ $gcb_table[$i][$gcb_enums{'Control'}] = 1;
$gcb_table[$i][$gcb_enums{'CR'}] = 1;
$gcb_table[$i][$gcb_enums{'LF'}] = 1;
- $gcb_table[$gcb_enums{'CN'}][$i] = 1;
+ $gcb_table[$gcb_enums{'Control'}][$i] = 1;
$gcb_table[$gcb_enums{'CR'}][$i] = 1;
$gcb_table[$gcb_enums{'LF'}][$i] = 1;
}
# GB1 sot ÷
# GB2 ÷ eot
for my $i (0 .. @gcb_table - 1) {
- $gcb_table[$i][$gcb_enums{'edge'}] = 1;
- $gcb_table[$gcb_enums{'edge'}][$i] = 1;
+ $gcb_table[$i][$gcb_enums{'EDGE'}] = 1;
+ $gcb_table[$gcb_enums{'EDGE'}][$i] = 1;
}
# But, unspecified by Unicode, we shouldn't break on an empty string.
- $gcb_table[$gcb_enums{'edge'}][$gcb_enums{'edge'}] = 0;
-
- print $out_fh "\nstatic const bool GCB_table[$table_size][$table_size] = {\n";
- print $out_fh "/* ";
- for my $i (0 .. @gcb_table - 1) {
- printf $out_fh "%5s", $gcb_short_enums[$i];
- }
- print $out_fh "*/\n";
+ $gcb_table[$gcb_enums{'EDGE'}][$gcb_enums{'EDGE'}] = 0;
- for my $i (0 .. @gcb_table - 1) {
- printf $out_fh "/*%4s*/ ", $gcb_short_enums[$i];
- print $out_fh "{";
- print $out_fh join ", ", map sprintf("%3d", $_), @{ $gcb_table[$i] };
- print $out_fh "}";
- print $out_fh "," if $i < @gcb_table - 1;
- print $out_fh "\n";
- }
-
- print $out_fh "};\n";
+ output_table_common('GCB', undef,
+ \@gcb_table, \@gcb_short_enums, \%gcb_abbreviations);
}
sub output_LB_table() {
LB_various_then_PO_or_PR => (1<<4), # Rule 25
);
- # Output the #define list, sorted by numeric value
- my @defines;
- while (my ($enum, $value) = each %lb_actions) {
- $defines[$value] = $enum;
- }
-
- print $out_fh "\n";
-
- foreach my $i (0 .. @defines - 1) {
- next unless defined $defines[$i];
- print $out_fh "#define $defines[$i]\t$i\n";
- }
-
# Construct the LB pair table. This is based on the rules in
# http://www.unicode.org/reports/tr14/, but modified as those rules are
# designed for someone taking a string of text and sequentially going
}
# LB30a. Don't break between Regional Indicators
- $lb_table[$lb_enums{'RI'}][$lb_enums{'RI'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Regional_Indicator'}]
+ [$lb_enums{'Regional_Indicator'}] = $lb_actions{'LB_NOBREAK'};
# LB30 Do not break between letters, numbers, or ordinary symbols and
# opening or closing parentheses.
# (AL | HL | NU) × OP
- $lb_table[$lb_enums{'AL'}][$lb_enums{'OP'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'HL'}][$lb_enums{'OP'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'NU'}][$lb_enums{'OP'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Alphabetic'}][$lb_enums{'Open_Punctuation'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Hebrew_Letter'}][$lb_enums{'Open_Punctuation'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Numeric'}][$lb_enums{'Open_Punctuation'}]
+ = $lb_actions{'LB_NOBREAK'};
# CP × (AL | HL | NU)
- $lb_table[$lb_enums{'CP'}][$lb_enums{'AL'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'CP'}][$lb_enums{'HL'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'CP'}][$lb_enums{'NU'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Close_Parenthesis'}][$lb_enums{'Alphabetic'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Close_Parenthesis'}][$lb_enums{'Hebrew_Letter'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Close_Parenthesis'}][$lb_enums{'Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
# LB29 Do not break between numeric punctuation and alphabetics (“e.g.”).
# IS × (AL | HL)
- $lb_table[$lb_enums{'IS'}][$lb_enums{'AL'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'IS'}][$lb_enums{'HL'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Infix_Numeric'}][$lb_enums{'Alphabetic'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Infix_Numeric'}][$lb_enums{'Hebrew_Letter'}]
+ = $lb_actions{'LB_NOBREAK'};
# LB28 Do not break between alphabetics (“at”).
# (AL | HL) × (AL | HL)
- $lb_table[$lb_enums{'AL'}][$lb_enums{'AL'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'HL'}][$lb_enums{'AL'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'AL'}][$lb_enums{'HL'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'HL'}][$lb_enums{'HL'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Alphabetic'}][$lb_enums{'Alphabetic'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Hebrew_Letter'}][$lb_enums{'Alphabetic'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Alphabetic'}][$lb_enums{'Hebrew_Letter'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Hebrew_Letter'}][$lb_enums{'Hebrew_Letter'}]
+ = $lb_actions{'LB_NOBREAK'};
# LB27 Treat a Korean Syllable Block the same as ID.
# (JL | JV | JT | H2 | H3) × IN
- $lb_table[$lb_enums{'JL'}][$lb_enums{'IN'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'JV'}][$lb_enums{'IN'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'JT'}][$lb_enums{'IN'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'H2'}][$lb_enums{'IN'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'H3'}][$lb_enums{'IN'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'JL'}][$lb_enums{'Inseparable'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'JV'}][$lb_enums{'Inseparable'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'JT'}][$lb_enums{'Inseparable'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'H2'}][$lb_enums{'Inseparable'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'H3'}][$lb_enums{'Inseparable'}]
+ = $lb_actions{'LB_NOBREAK'};
# (JL | JV | JT | H2 | H3) × PO
- $lb_table[$lb_enums{'JL'}][$lb_enums{'PO'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'JV'}][$lb_enums{'PO'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'JT'}][$lb_enums{'PO'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'H2'}][$lb_enums{'PO'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'H3'}][$lb_enums{'PO'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'JL'}][$lb_enums{'Postfix_Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'JV'}][$lb_enums{'Postfix_Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'JT'}][$lb_enums{'Postfix_Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'H2'}][$lb_enums{'Postfix_Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'H3'}][$lb_enums{'Postfix_Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
# PR × (JL | JV | JT | H2 | H3)
- $lb_table[$lb_enums{'PR'}][$lb_enums{'JL'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'PR'}][$lb_enums{'JV'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'PR'}][$lb_enums{'JT'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'PR'}][$lb_enums{'H2'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'PR'}][$lb_enums{'H3'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Prefix_Numeric'}][$lb_enums{'JL'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Prefix_Numeric'}][$lb_enums{'JV'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Prefix_Numeric'}][$lb_enums{'JT'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Prefix_Numeric'}][$lb_enums{'H2'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Prefix_Numeric'}][$lb_enums{'H3'}]
+ = $lb_actions{'LB_NOBREAK'};
# LB26 Do not break a Korean syllable.
# JL × (JL | JV | H2 | H3)
# http://www.unicode.org/reports/tr14/#Examples
# We follow that tailoring because Unicode's test cases expect it
# (PR | PO) × ( OP | HY )? NU
- $lb_table[$lb_enums{'PR'}][$lb_enums{'NU'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'PO'}][$lb_enums{'NU'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Prefix_Numeric'}][$lb_enums{'Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Postfix_Numeric'}][$lb_enums{'Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
# Given that (OP | HY )? is optional, we have to test for it in code.
# We add in the action (instead of overriding) for this, so that in
# the code we can recover the underlying break value.
- $lb_table[$lb_enums{'PR'}][$lb_enums{'OP'}]
+ $lb_table[$lb_enums{'Prefix_Numeric'}][$lb_enums{'Open_Punctuation'}]
+= $lb_actions{'LB_PR_or_PO_then_OP_or_HY'};
- $lb_table[$lb_enums{'PO'}][$lb_enums{'OP'}]
+ $lb_table[$lb_enums{'Postfix_Numeric'}][$lb_enums{'Open_Punctuation'}]
+= $lb_actions{'LB_PR_or_PO_then_OP_or_HY'};
- $lb_table[$lb_enums{'PR'}][$lb_enums{'HY'}]
+ $lb_table[$lb_enums{'Prefix_Numeric'}][$lb_enums{'Hyphen'}]
+= $lb_actions{'LB_PR_or_PO_then_OP_or_HY'};
- $lb_table[$lb_enums{'PO'}][$lb_enums{'HY'}]
+ $lb_table[$lb_enums{'Postfix_Numeric'}][$lb_enums{'Hyphen'}]
+= $lb_actions{'LB_PR_or_PO_then_OP_or_HY'};
# ( OP | HY ) × NU
- $lb_table[$lb_enums{'OP'}][$lb_enums{'NU'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'HY'}][$lb_enums{'NU'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Open_Punctuation'}][$lb_enums{'Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Hyphen'}][$lb_enums{'Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
# NU (NU | SY | IS)* × (NU | SY | IS | CL | CP )
# which can be rewritten as:
# NU (SY | IS)* × (NU | SY | IS | CL | CP )
- $lb_table[$lb_enums{'NU'}][$lb_enums{'NU'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'NU'}][$lb_enums{'SY'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'NU'}][$lb_enums{'IS'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'NU'}][$lb_enums{'CL'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'NU'}][$lb_enums{'CP'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Numeric'}][$lb_enums{'Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Numeric'}][$lb_enums{'Break_Symbols'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Numeric'}][$lb_enums{'Infix_Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Numeric'}][$lb_enums{'Close_Punctuation'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Numeric'}][$lb_enums{'Close_Parenthesis'}]
+ = $lb_actions{'LB_NOBREAK'};
# Like earlier where we have to test in code, we add in the action so
# that we can recover the underlying values. This is done in rules
# below, as well. The code assumes that we haven't added 2 actions.
# Shoul a later Unicode release break that assumption, then tests
# should start failing.
- $lb_table[$lb_enums{'SY'}][$lb_enums{'NU'}]
+ $lb_table[$lb_enums{'Break_Symbols'}][$lb_enums{'Numeric'}]
+= $lb_actions{'LB_SY_or_IS_then_various'};
- $lb_table[$lb_enums{'SY'}][$lb_enums{'SY'}]
+ $lb_table[$lb_enums{'Break_Symbols'}][$lb_enums{'Break_Symbols'}]
+= $lb_actions{'LB_SY_or_IS_then_various'};
- $lb_table[$lb_enums{'SY'}][$lb_enums{'IS'}]
+ $lb_table[$lb_enums{'Break_Symbols'}][$lb_enums{'Infix_Numeric'}]
+= $lb_actions{'LB_SY_or_IS_then_various'};
- $lb_table[$lb_enums{'SY'}][$lb_enums{'CL'}]
+ $lb_table[$lb_enums{'Break_Symbols'}][$lb_enums{'Close_Punctuation'}]
+= $lb_actions{'LB_SY_or_IS_then_various'};
- $lb_table[$lb_enums{'SY'}][$lb_enums{'CP'}]
+ $lb_table[$lb_enums{'Break_Symbols'}][$lb_enums{'Close_Parenthesis'}]
+= $lb_actions{'LB_SY_or_IS_then_various'};
- $lb_table[$lb_enums{'IS'}][$lb_enums{'NU'}]
+ $lb_table[$lb_enums{'Infix_Numeric'}][$lb_enums{'Numeric'}]
+= $lb_actions{'LB_SY_or_IS_then_various'};
- $lb_table[$lb_enums{'IS'}][$lb_enums{'SY'}]
+ $lb_table[$lb_enums{'Infix_Numeric'}][$lb_enums{'Break_Symbols'}]
+= $lb_actions{'LB_SY_or_IS_then_various'};
- $lb_table[$lb_enums{'IS'}][$lb_enums{'IS'}]
+ $lb_table[$lb_enums{'Infix_Numeric'}][$lb_enums{'Infix_Numeric'}]
+= $lb_actions{'LB_SY_or_IS_then_various'};
- $lb_table[$lb_enums{'IS'}][$lb_enums{'CL'}]
+ $lb_table[$lb_enums{'Infix_Numeric'}][$lb_enums{'Close_Punctuation'}]
+= $lb_actions{'LB_SY_or_IS_then_various'};
- $lb_table[$lb_enums{'IS'}][$lb_enums{'CP'}]
+ $lb_table[$lb_enums{'Infix_Numeric'}][$lb_enums{'Close_Parenthesis'}]
+= $lb_actions{'LB_SY_or_IS_then_various'};
# NU (NU | SY | IS)* (CL | CP)? × (PO | PR)
# which can be rewritten as:
# NU (SY | IS)* (CL | CP)? × (PO | PR)
- $lb_table[$lb_enums{'NU'}][$lb_enums{'PO'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'NU'}][$lb_enums{'PR'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Numeric'}][$lb_enums{'Postfix_Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Numeric'}][$lb_enums{'Prefix_Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'CP'}][$lb_enums{'PO'}]
+ $lb_table[$lb_enums{'Close_Parenthesis'}][$lb_enums{'Postfix_Numeric'}]
+= $lb_actions{'LB_various_then_PO_or_PR'};
- $lb_table[$lb_enums{'CL'}][$lb_enums{'PO'}]
+ $lb_table[$lb_enums{'Close_Punctuation'}][$lb_enums{'Postfix_Numeric'}]
+= $lb_actions{'LB_various_then_PO_or_PR'};
- $lb_table[$lb_enums{'IS'}][$lb_enums{'PO'}]
+ $lb_table[$lb_enums{'Infix_Numeric'}][$lb_enums{'Postfix_Numeric'}]
+= $lb_actions{'LB_various_then_PO_or_PR'};
- $lb_table[$lb_enums{'SY'}][$lb_enums{'PO'}]
+ $lb_table[$lb_enums{'Break_Symbols'}][$lb_enums{'Postfix_Numeric'}]
+= $lb_actions{'LB_various_then_PO_or_PR'};
- $lb_table[$lb_enums{'CP'}][$lb_enums{'PR'}]
+ $lb_table[$lb_enums{'Close_Parenthesis'}][$lb_enums{'Prefix_Numeric'}]
+= $lb_actions{'LB_various_then_PO_or_PR'};
- $lb_table[$lb_enums{'CL'}][$lb_enums{'PR'}]
+ $lb_table[$lb_enums{'Close_Punctuation'}][$lb_enums{'Prefix_Numeric'}]
+= $lb_actions{'LB_various_then_PO_or_PR'};
- $lb_table[$lb_enums{'IS'}][$lb_enums{'PR'}]
+ $lb_table[$lb_enums{'Infix_Numeric'}][$lb_enums{'Prefix_Numeric'}]
+= $lb_actions{'LB_various_then_PO_or_PR'};
- $lb_table[$lb_enums{'SY'}][$lb_enums{'PR'}]
+ $lb_table[$lb_enums{'Break_Symbols'}][$lb_enums{'Prefix_Numeric'}]
+= $lb_actions{'LB_various_then_PO_or_PR'};
# LB24 Do not break between prefix and letters or ideographs.
# PR × ID
- $lb_table[$lb_enums{'PR'}][$lb_enums{'ID'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Prefix_Numeric'}][$lb_enums{'Ideographic'}]
+ = $lb_actions{'LB_NOBREAK'};
# PR × (AL | HL)
- $lb_table[$lb_enums{'PR'}][$lb_enums{'AL'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'PR'}][$lb_enums{'HL'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Prefix_Numeric'}][$lb_enums{'Alphabetic'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Prefix_Numeric'}][$lb_enums{'Hebrew_Letter'}]
+ = $lb_actions{'LB_NOBREAK'};
# PO × (AL | HL)
- $lb_table[$lb_enums{'PO'}][$lb_enums{'AL'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'PO'}][$lb_enums{'HL'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Postfix_Numeric'}][$lb_enums{'Alphabetic'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Postfix_Numeric'}][$lb_enums{'Hebrew_Letter'}]
+ = $lb_actions{'LB_NOBREAK'};
# LB23 Do not break within ‘a9’, ‘3a’, or ‘H%’.
# ID × PO
- $lb_table[$lb_enums{'ID'}][$lb_enums{'PO'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Ideographic'}][$lb_enums{'Postfix_Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
# (AL | HL) × NU
- $lb_table[$lb_enums{'AL'}][$lb_enums{'NU'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'HL'}][$lb_enums{'NU'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Alphabetic'}][$lb_enums{'Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Hebrew_Letter'}][$lb_enums{'Numeric'}]
+ = $lb_actions{'LB_NOBREAK'};
# NU × (AL | HL)
- $lb_table[$lb_enums{'NU'}][$lb_enums{'AL'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'NU'}][$lb_enums{'HL'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Numeric'}][$lb_enums{'Alphabetic'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Numeric'}][$lb_enums{'Hebrew_Letter'}]
+ = $lb_actions{'LB_NOBREAK'};
# LB22 Do not break between two ellipses, or between letters, numbers or
# exclamations and ellipsis.
# (AL | HL) × IN
- $lb_table[$lb_enums{'AL'}][$lb_enums{'IN'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'HL'}][$lb_enums{'IN'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Alphabetic'}][$lb_enums{'Inseparable'}]
+ = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Hebrew_Letter'}][$lb_enums{'Inseparable'}]
+ = $lb_actions{'LB_NOBREAK'};
- # EX × IN
- $lb_table[$lb_enums{'EX'}][$lb_enums{'IN'}] = $lb_actions{'LB_NOBREAK'};
+ # Exclamation × IN
+ $lb_table[$lb_enums{'Exclamation'}][$lb_enums{'Inseparable'}]
+ = $lb_actions{'LB_NOBREAK'};
# ID × IN
- $lb_table[$lb_enums{'ID'}][$lb_enums{'IN'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Ideographic'}][$lb_enums{'Inseparable'}]
+ = $lb_actions{'LB_NOBREAK'};
# IN × IN
- $lb_table[$lb_enums{'IN'}][$lb_enums{'IN'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Inseparable'}][$lb_enums{'Inseparable'}]
+ = $lb_actions{'LB_NOBREAK'};
# NU × IN
- $lb_table[$lb_enums{'NU'}][$lb_enums{'IN'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Numeric'}][$lb_enums{'Inseparable'}]
+ = $lb_actions{'LB_NOBREAK'};
# LB21b Don’t break between Solidus and Hebrew letters.
# SY × HL
- $lb_table[$lb_enums{'SY'}][$lb_enums{'HL'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Break_Symbols'}][$lb_enums{'Hebrew_Letter'}]
+ = $lb_actions{'LB_NOBREAK'};
# LB21a Don't break after Hebrew + Hyphen.
# HL (HY | BA) ×
for my $i (0 .. @lb_table - 1) {
- $lb_table[$lb_enums{'HY'}][$i] += $lb_actions{'LB_HY_or_BA_then_foo'};
- $lb_table[$lb_enums{'BA'}][$i] += $lb_actions{'LB_HY_or_BA_then_foo'};
+ $lb_table[$lb_enums{'Hyphen'}][$i]
+ += $lb_actions{'LB_HY_or_BA_then_foo'};
+ $lb_table[$lb_enums{'Break_After'}][$i]
+ += $lb_actions{'LB_HY_or_BA_then_foo'};
}
# LB21 Do not break before hyphen-minus, other hyphens, fixed-width
# × NS
# BB ×
for my $i (0 .. @lb_table - 1) {
- $lb_table[$i][$lb_enums{'BA'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$i][$lb_enums{'HY'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$i][$lb_enums{'NS'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'BB'}][$i] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$i][$lb_enums{'Break_After'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$i][$lb_enums{'Hyphen'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$i][$lb_enums{'Nonstarter'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Break_Before'}][$i] = $lb_actions{'LB_NOBREAK'};
}
# LB20 Break before and after unresolved CB.
# rules. However, the default action is to treat unresolved CB as breaking
# before and after.
for my $i (0 .. @lb_table - 1) {
- $lb_table[$i][$lb_enums{'CB'}] = $lb_actions{'LB_BREAKABLE'};
- $lb_table[$lb_enums{'CB'}][$i] = $lb_actions{'LB_BREAKABLE'};
+ $lb_table[$i][$lb_enums{'Contingent_Break'}]
+ = $lb_actions{'LB_BREAKABLE'};
+ $lb_table[$lb_enums{'Contingent_Break'}][$i]
+ = $lb_actions{'LB_BREAKABLE'};
}
# LB19 Do not break before or after quotation marks, such as ‘ ” ’.
# × QU
# QU ×
for my $i (0 .. @lb_table - 1) {
- $lb_table[$i][$lb_enums{'QU'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$lb_enums{'QU'}][$i] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$i][$lb_enums{'Quotation'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Quotation'}][$i] = $lb_actions{'LB_NOBREAK'};
}
# LB18 Break after spaces
# SP ÷
for my $i (0 .. @lb_table - 1) {
- $lb_table[$lb_enums{'SP'}][$i] = $lb_actions{'LB_BREAKABLE'};
+ $lb_table[$lb_enums{'Space'}][$i] = $lb_actions{'LB_BREAKABLE'};
}
# LB17 Do not break within ‘——’, even with intervening spaces.
# B2 SP* × B2
- $lb_table[$lb_enums{'B2'}][$lb_enums{'B2'}]
+ $lb_table[$lb_enums{'Break_Both'}][$lb_enums{'Break_Both'}]
= $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'};
# LB16 Do not break between closing punctuation and a nonstarter even with
# intervening spaces.
# (CL | CP) SP* × NS
- $lb_table[$lb_enums{'CL'}][$lb_enums{'NS'}]
+ $lb_table[$lb_enums{'Close_Punctuation'}][$lb_enums{'Nonstarter'}]
= $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'};
- $lb_table[$lb_enums{'CP'}][$lb_enums{'NS'}]
+ $lb_table[$lb_enums{'Close_Parenthesis'}][$lb_enums{'Nonstarter'}]
= $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'};
# LB15 Do not break within ‘”[’, even with intervening spaces.
# QU SP* × OP
- $lb_table[$lb_enums{'QU'}][$lb_enums{'OP'}]
+ $lb_table[$lb_enums{'Quotation'}][$lb_enums{'Open_Punctuation'}]
= $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'};
# LB14 Do not break after ‘[’, even after spaces.
# OP SP* ×
for my $i (0 .. @lb_table - 1) {
- $lb_table[$lb_enums{'OP'}][$i]
+ $lb_table[$lb_enums{'Open_Punctuation'}][$i]
= $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'};
}
# [^NU] × IS
# [^NU] × SY
for my $i (0 .. @lb_table - 1) {
- $lb_table[$i][$lb_enums{'EX'}]
+ $lb_table[$i][$lb_enums{'Exclamation'}]
= $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'};
- next if $i == $lb_enums{'NU'};
+ next if $i == $lb_enums{'Numeric'};
- $lb_table[$i][$lb_enums{'CL'}]
+ $lb_table[$i][$lb_enums{'Close_Punctuation'}]
= $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'};
- $lb_table[$i][$lb_enums{'CP'}]
+ $lb_table[$i][$lb_enums{'Close_Parenthesis'}]
= $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'};
- $lb_table[$i][$lb_enums{'IS'}]
+ $lb_table[$i][$lb_enums{'Infix_Numeric'}]
= $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'};
- $lb_table[$i][$lb_enums{'SY'}]
+ $lb_table[$i][$lb_enums{'Break_Symbols'}]
= $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'};
}
# spaces and hyphens.
# [^SP BA HY] × GL
for my $i (0 .. @lb_table - 1) {
- next if $i == $lb_enums{'SP'}
- || $i == $lb_enums{'BA'}
- || $i == $lb_enums{'HY'};
+ next if $i == $lb_enums{'Space'}
+ || $i == $lb_enums{'Break_After'}
+ || $i == $lb_enums{'Hyphen'};
# We don't break, but if a property above has said don't break even
# with space between, don't override that (also in the next few rules)
- next if $lb_table[$i][$lb_enums{'GL'}]
+ next if $lb_table[$i][$lb_enums{'Glue'}]
== $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'};
- $lb_table[$i][$lb_enums{'GL'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$i][$lb_enums{'Glue'}] = $lb_actions{'LB_NOBREAK'};
}
# LB12 Do not break after NBSP and related characters.
# GL ×
for my $i (0 .. @lb_table - 1) {
- next if $lb_table[$lb_enums{'GL'}][$i]
+ next if $lb_table[$lb_enums{'Glue'}][$i]
== $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'};
- $lb_table[$lb_enums{'GL'}][$i] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Glue'}][$i] = $lb_actions{'LB_NOBREAK'};
}
# LB11 Do not break before or after Word joiner and related characters.
# × WJ
# WJ ×
for my $i (0 .. @lb_table - 1) {
- if ($lb_table[$i][$lb_enums{'WJ'}]
+ if ($lb_table[$i][$lb_enums{'Word_Joiner'}]
!= $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'})
{
- $lb_table[$i][$lb_enums{'WJ'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$i][$lb_enums{'Word_Joiner'}] = $lb_actions{'LB_NOBREAK'};
}
- if ($lb_table[$lb_enums{'WJ'}][$i]
+ if ($lb_table[$lb_enums{'Word_Joiner'}][$i]
!= $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'})
{
- $lb_table[$lb_enums{'WJ'}][$i] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Word_Joiner'}][$i] = $lb_actions{'LB_NOBREAK'};
}
}
# Special case this here to avoid having to do a special case in the code,
# by making this the same as other things with a SP in front of them that
# don't break, we avoid an extra test
- $lb_table[$lb_enums{'SP'}][$lb_enums{'WJ'}]
+ $lb_table[$lb_enums{'Space'}][$lb_enums{'Word_Joiner'}]
= $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'};
# LB9 and LB10 are done in the same loop
# When the CM is the first in the pair, we don't know without looking
# behind whether the CM is going to inherit from an earlier character,
# or not. So have to figure this out in the code
- $lb_table[$lb_enums{'CM'}][$i] = $lb_actions{'LB_CM_foo'};
-
- if ( $i == $lb_enums{'BK'}
- || $i == $lb_enums{'ed'}
- || $i == $lb_enums{'CR'}
- || $i == $lb_enums{'LF'}
- || $i == $lb_enums{'NL'}
- || $i == $lb_enums{'SP'}
- || $i == $lb_enums{'ZW'})
+ $lb_table[$lb_enums{'Combining_Mark'}][$i] = $lb_actions{'LB_CM_foo'};
+
+ if ( $i == $lb_enums{'Mandatory_Break'}
+ || $i == $lb_enums{'EDGE'}
+ || $i == $lb_enums{'Carriage_Return'}
+ || $i == $lb_enums{'Line_Feed'}
+ || $i == $lb_enums{'Next_Line'}
+ || $i == $lb_enums{'Space'}
+ || $i == $lb_enums{'ZWSpace'})
{
# For these classes, a following CM doesn't combine, and should do
- # whatever 'AL' would do.
- $lb_table[$i][$lb_enums{'CM'}] = $lb_table[$i][$lb_enums{'AL'}];
+ # whatever 'Alphabetic' would do.
+ $lb_table[$i][$lb_enums{'Combining_Mark'}]
+ = $lb_table[$i][$lb_enums{'Alphabetic'}];
}
else {
# For these classes, the CM combines, so doesn't break, inheriting
# the type of nobreak from the master character.
- if ($lb_table[$i][$lb_enums{'CM'}]
+ if ($lb_table[$i][$lb_enums{'Combining_Mark'}]
!= $lb_actions{'LB_NOBREAK_EVEN_WITH_SP_BETWEEN'})
{
- $lb_table[$i][$lb_enums{'CM'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$i][$lb_enums{'Combining_Mark'}]
+ = $lb_actions{'LB_NOBREAK'};
}
}
}
# or more spaces intervene.
# ZW SP* ÷
for my $i (0 .. @lb_table - 1) {
- $lb_table[$lb_enums{'ZW'}][$i] = $lb_actions{'LB_BREAKABLE'};
+ $lb_table[$lb_enums{'ZWSpace'}][$i] = $lb_actions{'LB_BREAKABLE'};
}
# Because of LB8-10, we need to look at context for "SP x", and this must
# context. By adding this action instead of replacing the existing one,
# we can get back to the original rule if necessary.
for my $i (0 .. @lb_table - 1) {
- $lb_table[$lb_enums{'SP'}][$i] += $lb_actions{'LB_SP_foo'};
+ $lb_table[$lb_enums{'Space'}][$i] += $lb_actions{'LB_SP_foo'};
}
# LB7 Do not break before spaces or zero width space.
# × SP
# × ZW
for my $i (0 .. @lb_table - 1) {
- $lb_table[$i][$lb_enums{'SP'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$i][$lb_enums{'ZW'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$i][$lb_enums{'Space'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$i][$lb_enums{'ZWSpace'}] = $lb_actions{'LB_NOBREAK'};
}
# LB6 Do not break before hard line breaks.
# × ( BK | CR | LF | NL )
for my $i (0 .. @lb_table - 1) {
- $lb_table[$i][$lb_enums{'BK'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$i][$lb_enums{'CR'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$i][$lb_enums{'LF'}] = $lb_actions{'LB_NOBREAK'};
- $lb_table[$i][$lb_enums{'NL'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$i][$lb_enums{'Mandatory_Break'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$i][$lb_enums{'Carriage_Return'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$i][$lb_enums{'Line_Feed'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$i][$lb_enums{'Next_Line'}] = $lb_actions{'LB_NOBREAK'};
}
# LB5 Treat CR followed by LF, as well as CR, LF, and NL as hard line breaks.
# LF !
# NL !
for my $i (0 .. @lb_table - 1) {
- $lb_table[$lb_enums{'CR'}][$i] = $lb_actions{'LB_BREAKABLE'};
- $lb_table[$lb_enums{'LF'}][$i] = $lb_actions{'LB_BREAKABLE'};
- $lb_table[$lb_enums{'NL'}][$i] = $lb_actions{'LB_BREAKABLE'};
+ $lb_table[$lb_enums{'Carriage_Return'}][$i]
+ = $lb_actions{'LB_BREAKABLE'};
+ $lb_table[$lb_enums{'Line_Feed'}][$i] = $lb_actions{'LB_BREAKABLE'};
+ $lb_table[$lb_enums{'Next_Line'}][$i] = $lb_actions{'LB_BREAKABLE'};
}
- $lb_table[$lb_enums{'CR'}][$lb_enums{'LF'}] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$lb_enums{'Carriage_Return'}][$lb_enums{'Line_Feed'}]
+ = $lb_actions{'LB_NOBREAK'};
# LB4 Always break after hard line breaks.
# BK !
for my $i (0 .. @lb_table - 1) {
- $lb_table[$lb_enums{'BK'}][$i] = $lb_actions{'LB_BREAKABLE'};
+ $lb_table[$lb_enums{'Mandatory_Break'}][$i]
+ = $lb_actions{'LB_BREAKABLE'};
}
# LB2 Never break at the start of text.
# but these are reversed in the loop below, so that won't break if there
# is no text
for my $i (0 .. @lb_table - 1) {
- $lb_table[$i][$lb_enums{'ed'}] = $lb_actions{'LB_BREAKABLE'};
- $lb_table[$lb_enums{'ed'}][$i] = $lb_actions{'LB_NOBREAK'};
+ $lb_table[$i][$lb_enums{'EDGE'}] = $lb_actions{'LB_BREAKABLE'};
+ $lb_table[$lb_enums{'EDGE'}][$i] = $lb_actions{'LB_NOBREAK'};
}
# LB1 Assign a line breaking class to each code point of the input.
# This is done in mktables, so we never see any of the remapped-from
# classes.
- print $out_fh "\nstatic const U8 LB_table[$table_size][$table_size] = {\n";
- print $out_fh "\n/* 'ed' stands for 'edge' */\n";
- print $out_fh "/* ";
- for my $i (0 .. @lb_table - 1) {
- print $out_fh " $lb_short_enums[$i]";
- }
- print $out_fh " */\n";
-
- for my $i (0 .. @lb_table - 1) {
- print $out_fh "/* $lb_short_enums[$i] */ ";
- print $out_fh "{ ";
- print $out_fh join ", ", map sprintf("%2d", $_), @{ $lb_table[$i] };
- print $out_fh " }";
- print $out_fh "," if $i < @lb_table - 1;
- print $out_fh "\n";
- }
-
- print $out_fh "};\n";
+ output_table_common('LB', \%lb_actions,
+ \@lb_table, \@lb_short_enums, \%lb_abbreviations);
}
sub output_WB_table() {
WB_NU_then_MB_or_MN_or_SQ => 14,
);
- # Output the #define list, sorted by numeric value
- my @defines;
- while (my ($enum, $value) = each %wb_actions) {
- $defines[$value] = $enum;
- }
-
- print $out_fh "\n";
-
- foreach my $i (0 .. @defines - 1) {
- next unless defined $defines[$i];
- print $out_fh "#define $defines[$i]\t$i\n";
- }
-
# Construct the WB pair table.
# The table is constructed in reverse order of the rules, to make the
# lower-numbered, higher priority ones override the later ones, as the
# Do not break between regional indicator symbols.
# WB13c Regional_Indicator × Regional_Indicator
- $wb_table[$wb_enums{'RI'}][$wb_enums{'RI'}] = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'Regional_Indicator'}]
+ [$wb_enums{'Regional_Indicator'}] = $wb_actions{'WB_NOBREAK'};
# Do not break from extenders.
# WB13b ExtendNumLet × (ALetter | Hebrew_Letter | Numeric | Katakana)
- $wb_table[$wb_enums{'EX'}][$wb_enums{'LE'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$wb_enums{'EX'}][$wb_enums{'HL'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$wb_enums{'EX'}][$wb_enums{'NU'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$wb_enums{'EX'}][$wb_enums{'KA'}] = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'ExtendNumLet'}][$wb_enums{'ALetter'}]
+ = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'ExtendNumLet'}][$wb_enums{'Hebrew_Letter'}]
+ = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'ExtendNumLet'}][$wb_enums{'Numeric'}]
+ = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'ExtendNumLet'}][$wb_enums{'Katakana'}]
+ = $wb_actions{'WB_NOBREAK'};
# WB13a (ALetter | Hebrew_Letter | Numeric | Katakana | ExtendNumLet)
# × # ExtendNumLet
- $wb_table[$wb_enums{'LE'}][$wb_enums{'EX'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$wb_enums{'HL'}][$wb_enums{'EX'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$wb_enums{'NU'}][$wb_enums{'EX'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$wb_enums{'KA'}][$wb_enums{'EX'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$wb_enums{'EX'}][$wb_enums{'EX'}] = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'ALetter'}][$wb_enums{'ExtendNumLet'}]
+ = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'Hebrew_Letter'}][$wb_enums{'ExtendNumLet'}]
+ = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'Numeric'}][$wb_enums{'ExtendNumLet'}]
+ = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'Katakana'}][$wb_enums{'ExtendNumLet'}]
+ = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'ExtendNumLet'}][$wb_enums{'ExtendNumLet'}]
+ = $wb_actions{'WB_NOBREAK'};
# Do not break between Katakana.
# WB13 Katakana × Katakana
- $wb_table[$wb_enums{'KA'}][$wb_enums{'KA'}] = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'Katakana'}][$wb_enums{'Katakana'}]
+ = $wb_actions{'WB_NOBREAK'};
# Do not break within sequences, such as “3.2” or “3,456.789”.
# WB12 Numeric × (MidNum | MidNumLet | Single_Quote) Numeric
- $wb_table[$wb_enums{'NU'}][$wb_enums{'MB'}]
+ $wb_table[$wb_enums{'Numeric'}][$wb_enums{'MidNumLet'}]
+= $wb_actions{'WB_NU_then_MB_or_MN_or_SQ'};
- $wb_table[$wb_enums{'NU'}][$wb_enums{'MN'}]
+ $wb_table[$wb_enums{'Numeric'}][$wb_enums{'MidNum'}]
+= $wb_actions{'WB_NU_then_MB_or_MN_or_SQ'};
- $wb_table[$wb_enums{'NU'}][$wb_enums{'SQ'}]
+ $wb_table[$wb_enums{'Numeric'}][$wb_enums{'Single_Quote'}]
+= $wb_actions{'WB_NU_then_MB_or_MN_or_SQ'};
# WB11 Numeric (MidNum | (MidNumLet | Single_Quote)) × Numeric
- $wb_table[$wb_enums{'MB'}][$wb_enums{'NU'}]
+ $wb_table[$wb_enums{'MidNumLet'}][$wb_enums{'Numeric'}]
+= $wb_actions{'WB_MB_or_MN_or_SQ_then_NU'};
- $wb_table[$wb_enums{'MN'}][$wb_enums{'NU'}]
+ $wb_table[$wb_enums{'MidNum'}][$wb_enums{'Numeric'}]
+= $wb_actions{'WB_MB_or_MN_or_SQ_then_NU'};
- $wb_table[$wb_enums{'SQ'}][$wb_enums{'NU'}]
+ $wb_table[$wb_enums{'Single_Quote'}][$wb_enums{'Numeric'}]
+= $wb_actions{'WB_MB_or_MN_or_SQ_then_NU'};
# Do not break within sequences of digits, or digits adjacent to letters
# (“3a”, or “A3”).
# WB10 Numeric × (ALetter | Hebrew_Letter)
- $wb_table[$wb_enums{'NU'}][$wb_enums{'LE'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$wb_enums{'NU'}][$wb_enums{'HL'}] = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'Numeric'}][$wb_enums{'ALetter'}]
+ = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'Numeric'}][$wb_enums{'Hebrew_Letter'}]
+ = $wb_actions{'WB_NOBREAK'};
# WB9 (ALetter | Hebrew_Letter) × Numeric
- $wb_table[$wb_enums{'LE'}][$wb_enums{'NU'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$wb_enums{'HL'}][$wb_enums{'NU'}] = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'ALetter'}][$wb_enums{'Numeric'}]
+ = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'Hebrew_Letter'}][$wb_enums{'Numeric'}]
+ = $wb_actions{'WB_NOBREAK'};
# WB8 Numeric × Numeric
- $wb_table[$wb_enums{'NU'}][$wb_enums{'NU'}] = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'Numeric'}][$wb_enums{'Numeric'}]
+ = $wb_actions{'WB_NOBREAK'};
# Do not break letters across certain punctuation.
# WB7c Hebrew_Letter Double_Quote × Hebrew_Letter
- $wb_table[$wb_enums{'DQ'}][$wb_enums{'HL'}] += $wb_actions{'WB_DQ_then_HL'};
+ $wb_table[$wb_enums{'Double_Quote'}][$wb_enums{'Hebrew_Letter'}]
+ += $wb_actions{'WB_DQ_then_HL'};
# WB7b Hebrew_Letter × Double_Quote Hebrew_Letter
- $wb_table[$wb_enums{'HL'}][$wb_enums{'DQ'}] += $wb_actions{'WB_HL_then_DQ'};
+ $wb_table[$wb_enums{'Hebrew_Letter'}][$wb_enums{'Double_Quote'}]
+ += $wb_actions{'WB_HL_then_DQ'};
# WB7a Hebrew_Letter × Single_Quote
- $wb_table[$wb_enums{'HL'}][$wb_enums{'SQ'}] = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'Hebrew_Letter'}][$wb_enums{'Single_Quote'}]
+ = $wb_actions{'WB_NOBREAK'};
# WB7 (ALetter | Hebrew_Letter) (MidLetter | MidNumLet | Single_Quote)
# × (ALetter | Hebrew_Letter)
- $wb_table[$wb_enums{'MB'}][$wb_enums{'LE'}]
+ $wb_table[$wb_enums{'MidNumLet'}][$wb_enums{'ALetter'}]
+= $wb_actions{'WB_MB_or_ML_or_SQ_then_LE_or_HL'};
- $wb_table[$wb_enums{'MB'}][$wb_enums{'HL'}]
+ $wb_table[$wb_enums{'MidNumLet'}][$wb_enums{'Hebrew_Letter'}]
+= $wb_actions{'WB_MB_or_ML_or_SQ_then_LE_or_HL'};
- $wb_table[$wb_enums{'ML'}][$wb_enums{'LE'}]
+ $wb_table[$wb_enums{'MidLetter'}][$wb_enums{'ALetter'}]
+= $wb_actions{'WB_MB_or_ML_or_SQ_then_LE_or_HL'};
- $wb_table[$wb_enums{'ML'}][$wb_enums{'HL'}]
+ $wb_table[$wb_enums{'MidLetter'}][$wb_enums{'Hebrew_Letter'}]
+= $wb_actions{'WB_MB_or_ML_or_SQ_then_LE_or_HL'};
- $wb_table[$wb_enums{'SQ'}][$wb_enums{'LE'}]
+ $wb_table[$wb_enums{'Single_Quote'}][$wb_enums{'ALetter'}]
+= $wb_actions{'WB_MB_or_ML_or_SQ_then_LE_or_HL'};
- $wb_table[$wb_enums{'SQ'}][$wb_enums{'HL'}]
+ $wb_table[$wb_enums{'Single_Quote'}][$wb_enums{'Hebrew_Letter'}]
+= $wb_actions{'WB_MB_or_ML_or_SQ_then_LE_or_HL'};
# WB6 (ALetter | Hebrew_Letter) × (MidLetter | MidNumLet
# | Single_Quote) (ALetter | Hebrew_Letter)
- $wb_table[$wb_enums{'LE'}][$wb_enums{'MB'}]
+ $wb_table[$wb_enums{'ALetter'}][$wb_enums{'MidNumLet'}]
+= $wb_actions{'WB_LE_or_HL_then_MB_or_ML_or_SQ'};
- $wb_table[$wb_enums{'HL'}][$wb_enums{'MB'}]
+ $wb_table[$wb_enums{'Hebrew_Letter'}][$wb_enums{'MidNumLet'}]
+= $wb_actions{'WB_LE_or_HL_then_MB_or_ML_or_SQ'};
- $wb_table[$wb_enums{'LE'}][$wb_enums{'ML'}]
+ $wb_table[$wb_enums{'ALetter'}][$wb_enums{'MidLetter'}]
+= $wb_actions{'WB_LE_or_HL_then_MB_or_ML_or_SQ'};
- $wb_table[$wb_enums{'HL'}][$wb_enums{'ML'}]
+ $wb_table[$wb_enums{'Hebrew_Letter'}][$wb_enums{'MidLetter'}]
+= $wb_actions{'WB_LE_or_HL_then_MB_or_ML_or_SQ'};
- $wb_table[$wb_enums{'LE'}][$wb_enums{'SQ'}]
+ $wb_table[$wb_enums{'ALetter'}][$wb_enums{'Single_Quote'}]
+= $wb_actions{'WB_LE_or_HL_then_MB_or_ML_or_SQ'};
- $wb_table[$wb_enums{'HL'}][$wb_enums{'SQ'}]
+ $wb_table[$wb_enums{'Hebrew_Letter'}][$wb_enums{'Single_Quote'}]
+= $wb_actions{'WB_LE_or_HL_then_MB_or_ML_or_SQ'};
# Do not break between most letters.
# WB5 (ALetter | Hebrew_Letter) × (ALetter | Hebrew_Letter)
- $wb_table[$wb_enums{'LE'}][$wb_enums{'LE'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$wb_enums{'LE'}][$wb_enums{'HL'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$wb_enums{'HL'}][$wb_enums{'LE'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$wb_enums{'HL'}][$wb_enums{'HL'}] = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'ALetter'}][$wb_enums{'ALetter'}]
+ = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'ALetter'}][$wb_enums{'Hebrew_Letter'}]
+ = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'Hebrew_Letter'}][$wb_enums{'ALetter'}]
+ = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'Hebrew_Letter'}][$wb_enums{'Hebrew_Letter'}]
+ = $wb_actions{'WB_NOBREAK'};
# Ignore Format and Extend characters, except when they appear at the
# beginning of a region of text.
# WB4 X (Extend | Format)* → X
for my $i (0 .. @wb_table - 1) {
- $wb_table[$wb_enums{'Ex'}][$i] = $wb_actions{'WB_Ex_or_FO_then_foo'};
- $wb_table[$wb_enums{'FO'}][$i] = $wb_actions{'WB_Ex_or_FO_then_foo'};
+ $wb_table[$wb_enums{'Extend'}][$i]
+ = $wb_actions{'WB_Ex_or_FO_then_foo'};
+ $wb_table[$wb_enums{'Format'}][$i]
+ = $wb_actions{'WB_Ex_or_FO_then_foo'};
}
# Implied is that these attach to the character before them, except for
# override the ones set up here, for all the characters that need
# overriding.
for my $i (0 .. @wb_table - 1) {
- $wb_table[$i][$wb_enums{'Ex'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$i][$wb_enums{'FO'}] = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$i][$wb_enums{'Extend'}] = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$i][$wb_enums{'Format'}] = $wb_actions{'WB_NOBREAK'};
}
# Break before and after white space
# WB3b ÷ (Newline | CR | LF)
# WB3a (Newline | CR | LF) ÷
# et. al.
- for my $i ('CR', 'LF', 'NL', 'hs') {
+ for my $i ('CR', 'LF', 'Newline', 'Perl_Tailored_HSpace') {
for my $j (0 .. @wb_table - 1) {
$wb_table[$j][$wb_enums{$i}] = $wb_actions{'WB_BREAKABLE'};
$wb_table[$wb_enums{$i}][$j] = $wb_actions{'WB_BREAKABLE'};
# But do not break within white space.
# WB3 CR × LF
# et.al.
- for my $i ('CR', 'LF', 'NL', 'hs') {
- for my $j ('CR', 'LF', 'NL', 'hs') {
+ for my $i ('CR', 'LF', 'Newline', 'Perl_Tailored_HSpace') {
+ for my $j ('CR', 'LF', 'Newline', 'Perl_Tailored_HSpace') {
$wb_table[$wb_enums{$i}][$wb_enums{$j}] = $wb_actions{'WB_NOBREAK'};
}
}
# And do not break horizontal space followed by Extend or Format
- $wb_table[$wb_enums{'hs'}][$wb_enums{'Ex'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$wb_enums{'hs'}][$wb_enums{'FO'}] = $wb_actions{'WB_NOBREAK'};
- $wb_table[$wb_enums{'hs'}][$wb_enums{'hs'}] = $wb_actions{'WB_hs_then_hs'};
+ $wb_table[$wb_enums{'Perl_Tailored_HSpace'}][$wb_enums{'Extend'}]
+ = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'Perl_Tailored_HSpace'}][$wb_enums{'Format'}]
+ = $wb_actions{'WB_NOBREAK'};
+ $wb_table[$wb_enums{'Perl_Tailored_HSpace'}]
+ [$wb_enums{'Perl_Tailored_HSpace'}]
+ = $wb_actions{'WB_hs_then_hs'};
# Break at the start and end of text.
# WB2 ÷ eot
# WB1 sot ÷
for my $i (0 .. @wb_table - 1) {
- $wb_table[$i][$wb_enums{'ed'}] = $wb_actions{'WB_BREAKABLE'};
- $wb_table[$wb_enums{'ed'}][$i] = $wb_actions{'WB_BREAKABLE'};
+ $wb_table[$i][$wb_enums{'EDGE'}] = $wb_actions{'WB_BREAKABLE'};
+ $wb_table[$wb_enums{'EDGE'}][$i] = $wb_actions{'WB_BREAKABLE'};
}
# But, unspecified by Unicode, we shouldn't break on an empty string.
- $wb_table[$wb_enums{'ed'}][$wb_enums{'ed'}] = 0;
-
- print $out_fh "\nstatic const U8 WB_table[$table_size][$table_size] = {\n";
- print $out_fh "\n/* 'Ex' stands for 'Extend'; 'hs' for 'Perl_Tailored_HSpace'; 'ed' for 'edge' */\n";
- print $out_fh "/* ";
- for my $i (0 .. @wb_table - 1) {
- print $out_fh " $wb_short_enums[$i]";
- }
- print $out_fh " */\n";
+ $wb_table[$wb_enums{'EDGE'}][$wb_enums{'EDGE'}] = 0;
- for my $i (0 .. @wb_table - 1) {
- print $out_fh "/* $wb_short_enums[$i] */ ";
- print $out_fh "{";
- print $out_fh join ", ", map sprintf("%2d", $_), @{ $wb_table[$i] };
- print $out_fh " }";
- print $out_fh "," if $i < @wb_table - 1;
- print $out_fh "\n";
- }
-
- print $out_fh "};\n";
+ output_table_common('WB', \%wb_actions,
+ \@wb_table, \@wb_short_enums, \%wb_abbreviations);
}
output_invlist("Latin1", [ 0, 256 ]);
my $to_adjust;
if ($is_local_sub) {
@invlist = eval $lookup_prop;
+ die $@ if $@;
}
else {
@invlist = prop_invlist($lookup_prop, '_perl_core_internal_ok');
#
# This script is normally invoked from regen.pl.
-$VERSION = '1.35';
+$VERSION = '1.36';
BEGIN {
require 'regen/regen_lib.pl';
VERSION
# Verify that we're called correctly so that warnings will work.
+# Can't use Carp, since Carp uses us!
+# String regexps because constant folding = smaller optree = less memory vs regexp literal
# see also strict.pm.
-unless ( __FILE__ =~ /(^|[\/\\])\Q${\__PACKAGE__}\E\.pmc?$/ ) {
- my (undef, $f, $l) = caller;
- die("Incorrect use of pragma '${\__PACKAGE__}' at $f line $l.\n");
-}
+die sprintf "Incorrect use of pragma '%s' at %s line %d.\n", __PACKAGE__, +(caller)[1,2]
+ if __FILE__ !~ ( '(?x) \b '.__PACKAGE__.' \.pmc? \z' )
+ && __FILE__ =~ ( '(?x) \b (?i:'.__PACKAGE__.') \.pmc? \z' );
KEYWORDS
= "Can't match, because target string needs to be in UTF-8\n";
#endif
-#define NON_UTF8_TARGET_BUT_UTF8_REQUIRED(target) STMT_START { \
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "%s", non_utf8_target_but_utf8_required));\
- goto target; \
+#define NON_UTF8_TARGET_BUT_UTF8_REQUIRED(target) STMT_START { \
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_ "%s", non_utf8_target_but_utf8_required));\
+ goto target; \
} STMT_END
#define HAS_NONLATIN1_FOLD_CLOSURE(i) _HAS_NONLATIN1_FOLD_CLOSURE_ONLY_FOR_USE_BY_REGCOMP_DOT_C_AND_REGEXEC_DOT_C(i)
#define STATIC static
#endif
-/* Valid only for non-utf8 strings: avoids the reginclass
- * call if there are no complications: i.e., if everything matchable is
- * straight forward in the bitmap */
-#define REGINCLASS(prog,p,c) (ANYOF_FLAGS(p) ? reginclass(prog,p,c,c+1,0) \
- : ANYOF_BITMAP_TEST(p,*(c)))
+/* Valid only if 'c', the character being looke-up, is an invariant under
+ * UTF-8: it avoids the reginclass call if there are no complications: i.e., if
+ * everything matchable is straight forward in the bitmap */
+#define REGINCLASS(prog,p,c,u) (ANYOF_FLAGS(p) \
+ ? reginclass(prog,p,c,c+1,u) \
+ : ANYOF_BITMAP_TEST(p,*(c)))
/*
* Forwards.
#define HOPBACKc(pos, off) \
(char*)(reginfo->is_utf8_target \
- ? reghopmaybe3((U8*)pos, -off, (U8*)(reginfo->strbeg)) \
+ ? reghopmaybe3((U8*)pos, (SSize_t)0-off, (U8*)(reginfo->strbeg)) \
: (pos - off >= reginfo->strbeg) \
? (U8*)pos - off \
: NULL)
*/
#define JUMPABLE(rn) ( \
OP(rn) == OPEN || \
- (OP(rn) == CLOSE && (!cur_eval || cur_eval->u.eval.close_paren != ARG(rn))) || \
+ (OP(rn) == CLOSE && \
+ !EVAL_CLOSE_PAREN_IS(cur_eval,ARG(rn)) ) || \
OP(rn) == EVAL || \
OP(rn) == SUSPEND || OP(rn) == IFMATCH || \
OP(rn) == PLUS || OP(rn) == MINMOD || \
DEBUG_BUFFERS_r(
if ((int)maxopenparen > (int)parenfloor)
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"rex=0x%"UVxf" offs=0x%"UVxf": saving capture indices:\n",
PTR2UV(rex),
PTR2UV(rex->offs)
SSPUSHIV(rex->offs[p].end);
SSPUSHIV(rex->offs[p].start);
SSPUSHINT(rex->offs[p].start_tmp);
- DEBUG_BUFFERS_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_BUFFERS_r(Perl_re_printf( aTHX_
" \\%"UVuf": %"IVdf"(%"IVdf")..%"IVdf"\n",
(UV)p,
(IV)rex->offs[p].start,
/* These are needed since we do not localize EVAL nodes: */
#define REGCP_SET(cp) \
DEBUG_STATE_r( \
- PerlIO_printf(Perl_debug_log, \
- " Setting an EVAL scope, savestack=%"IVdf"\n", \
- (IV)PL_savestack_ix)); \
+ Perl_re_exec_indentf( aTHX_ \
+ "Setting an EVAL scope, savestack=%"IVdf",\n", \
+ depth, (IV)PL_savestack_ix \
+ ) \
+ ); \
cp = PL_savestack_ix
#define REGCP_UNWIND(cp) \
DEBUG_STATE_r( \
- if (cp != PL_savestack_ix) \
- PerlIO_printf(Perl_debug_log, \
- " Clearing an EVAL scope, savestack=%"IVdf"..%"IVdf"\n", \
- (IV)(cp), (IV)PL_savestack_ix)); \
+ if (cp != PL_savestack_ix) \
+ Perl_re_exec_indentf( aTHX_ \
+ "Clearing an EVAL scope, savestack=%"IVdf"..%"IVdf"\n",\
+ depth, (IV)(cp), (IV)PL_savestack_ix \
+ ) \
+ ); \
regcpblow(cp)
#define UNWIND_PAREN(lp, lcp) \
/* Now restore the parentheses context. */
DEBUG_BUFFERS_r(
if (i || rex->lastparen + 1 <= rex->nparens)
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"rex=0x%"UVxf" offs=0x%"UVxf": restoring capture indices to:\n",
PTR2UV(rex),
PTR2UV(rex->offs)
tmps = SSPOPIV;
if (paren <= rex->lastparen)
rex->offs[paren].end = tmps;
- DEBUG_BUFFERS_r( PerlIO_printf(Perl_debug_log,
+ DEBUG_BUFFERS_r( Perl_re_printf( aTHX_
" \\%"UVuf": %"IVdf"(%"IVdf")..%"IVdf"%s\n",
(UV)paren,
(IV)rex->offs[paren].start,
if (i > *maxopenparen_p)
rex->offs[i].start = -1;
rex->offs[i].end = -1;
- DEBUG_BUFFERS_r( PerlIO_printf(Perl_debug_log,
+ DEBUG_BUFFERS_r( Perl_re_printf( aTHX_
" \\%"UVuf": %s ..-1 undeffing\n",
(UV)i,
(i > *maxopenparen_p) ? "-1" : " "
PERL_UNUSED_ARG(flags);
PERL_UNUSED_ARG(data);
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
"Intuit: trying to determine minimum start position...\n"));
/* for now, assume that all substr offsets are positive. If at some point
* to quickly reject some cases that can't match, but will reject
* them later after doing full char arithmetic */
if (prog->minlen > strend - strpos) {
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" String too short...\n"));
goto fail;
}
if (!sv)
continue;
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
" substrs[%d]: min=%"IVdf" max=%"IVdf" end shift=%"IVdf
" useful=%"IVdf" utf8=%d [%s]\n",
i,
if ( strpos != strbeg
&& (prog->intflags & PREGf_ANCH_SBOL))
{
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" Not at start...\n"));
goto fail;
}
SSize_t slen = SvCUR(check);
char *s = HOP3c(strpos, prog->check_offset_min, strend);
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" Looking for check substr at fixed offset %"IVdf"...\n",
(IV)prog->check_offset_min));
|| strend - s < slen - 1
|| (strend - s == slen && strend[-1] != '\n')))
{
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" String too long...\n"));
goto fail_finish;
}
if (slen && (*SvPVX_const(check) != *s
|| (slen > 1 && memNE(SvPVX_const(check), s, slen))))
{
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" String not equal...\n"));
goto fail_finish;
}
U8* end_point;
DEBUG_OPTIMISE_MORE_r({
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
" At restart: rx_origin=%"IVdf" Check offset min: %"IVdf
" Start shift: %"IVdf" End shift %"IVdf
" Real end Shift: %"IVdf"\n",
check_at = fbm_instr( start_point, end_point,
check, multiline ? FBMrf_MULTILINE : 0);
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" doing 'check' fbm scan, [%"IVdf"..%"IVdf"] gave %"IVdf"\n",
(IV)((char*)start_point - strbeg),
(IV)((char*)end_point - strbeg),
DEBUG_EXECUTE_r({
RE_PV_QUOTED_DECL(quoted, utf8_target, PERL_DEBUG_PAD_ZERO(0),
SvPVX_const(check), RE_SV_DUMPLEN(check), 30);
- PerlIO_printf(Perl_debug_log, " %s %s substr %s%s%s",
+ Perl_re_printf( aTHX_ " %s %s substr %s%s%s",
(check_at ? "Found" : "Did not find"),
(check == (utf8_target ? prog->anchored_utf8 : prog->anchored_substr)
? "anchored" : "floating"),
if (check_at - rx_origin > prog->check_offset_max)
rx_origin = HOP3c(check_at, -prog->check_offset_max, rx_origin);
/* Finish the diagnostic message */
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
"%ld (rx_origin now %"IVdf")...\n",
(long)(check_at - strbeg),
(IV)(rx_origin - strbeg)
if (from > to) {
s = NULL;
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" skipping 'other' fbm scan: %"IVdf" > %"IVdf"\n",
(IV)(from - strbeg),
(IV)(to - strbeg)
must,
multiline ? FBMrf_MULTILINE : 0
);
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" doing 'other' fbm scan, [%"IVdf"..%"IVdf"] gave %"IVdf"\n",
(IV)(from - strbeg),
(IV)(to - strbeg),
DEBUG_EXECUTE_r({
RE_PV_QUOTED_DECL(quoted, utf8_target, PERL_DEBUG_PAD_ZERO(0),
SvPVX_const(must), RE_SV_DUMPLEN(must), 30);
- PerlIO_printf(Perl_debug_log, " %s %s substr %s%s",
+ Perl_re_printf( aTHX_ " %s %s substr %s%s",
s ? "Found" : "Contradicts",
other_ix ? "floating" : "anchored",
quoted, RE_SV_TAIL(must));
/* last1 is latest possible substr location. If we didn't
* find it before there, we never will */
if (last >= last1) {
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
"; giving up...\n"));
goto fail_finish;
}
other_ix /* i.e. if other-is-float */
? HOP3c(rx_origin, 1, strend)
: HOP4c(last, 1 - other->min_offset, strbeg, strend);
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
"; about to retry %s at offset %ld (rx_origin now %"IVdf")...\n",
(other_ix ? "floating" : "anchored"),
(long)(HOP3c(check_at, 1, strend) - strbeg),
rx_origin = HOP3c(s, -other->min_offset, strbeg);
other_last = HOP3c(s, 1, strend);
}
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" at offset %ld (rx_origin now %"IVdf")...\n",
(long)(s - strbeg),
(IV)(rx_origin - strbeg)
}
else {
DEBUG_OPTIMISE_MORE_r(
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
" Check-only match: offset min:%"IVdf" max:%"IVdf
" check_at:%"IVdf" rx_origin:%"IVdf" rx_origin-check_at:%"IVdf
" strend:%"IVdf"\n",
if (ml_anch && rx_origin != strbeg && rx_origin[-1] != '\n') {
char *s;
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" looking for /^/m anchor"));
/* we have failed the constraint of a \n before rx_origin.
if (s <= rx_origin ||
! ( rx_origin = (char *)memchr(rx_origin, '\n', s - rx_origin)))
{
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" Did not find /%s^%s/m...\n",
PL_colors[0], PL_colors[1]));
goto fail_finish;
/* Position contradicts check-string; either because
* check was anchored (and thus has no wiggle room),
* or check was float and rx_origin is above the float range */
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" Found /%s^%s/m, about to restart lookup for check-string with rx_origin %ld...\n",
PL_colors[0], PL_colors[1], (long)(rx_origin - strbeg)));
goto restart;
* contradict. On the other hand, the float "check" substr
* didn't contradict, so just retry the anchored "other"
* substr */
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" Found /%s^%s/m, rescanning for anchored from offset %"IVdf" (rx_origin now %"IVdf")...\n",
PL_colors[0], PL_colors[1],
(IV)(rx_origin - strbeg + prog->anchored_offset),
/* success: we don't contradict the found floating substring
* (and there's no anchored substr). */
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" Found /%s^%s/m with rx_origin %ld...\n",
PL_colors[0], PL_colors[1], (long)(rx_origin - strbeg)));
}
else {
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" (multiline anchor test skipped)\n"));
}
else
endpos= strend;
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" looking for class: start_shift: %"IVdf" check_at: %"IVdf
" rx_origin: %"IVdf" endpos: %"IVdf"\n",
(IV)start_shift, (IV)(check_at - strbeg),
reginfo);
if (!s) {
if (endpos == strend) {
- DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r( Perl_re_printf( aTHX_
" Could not match STCLASS...\n") );
goto fail;
}
- DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r( Perl_re_printf( aTHX_
" This position contradicts STCLASS...\n") );
if ((prog->intflags & PREGf_ANCH) && !ml_anch
&& !(prog->intflags & PREGf_IMPLICIT))
* an extra anchored search may get done, but in
* practice the extra fbm_instr() is likely to
* get skipped anyway. */
- DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r( Perl_re_printf( aTHX_
" about to retry anchored at offset %ld (rx_origin now %"IVdf")...\n",
(long)(other_last - strbeg),
(IV)(rx_origin - strbeg)
* but since we goto a block of code that's going to
* search for the next \n if any, its safe here */
rx_origin++;
- DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r( Perl_re_printf( aTHX_
" about to look for /%s^%s/m starting at rx_origin %ld...\n",
PL_colors[0], PL_colors[1],
(long)(rx_origin - strbeg)) );
* It's conservative: it errs on the side of doing 'goto restart',
* where there is code that does a proper char-based test */
if (rx_origin + start_shift + end_shift > strend) {
- DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r( Perl_re_printf( aTHX_
" Could not match STCLASS...\n") );
goto fail;
}
- DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r( Perl_re_printf( aTHX_
" about to look for %s substr starting at offset %ld (rx_origin now %"IVdf")...\n",
(prog->substrs->check_ix ? "floating" : "anchored"),
(long)(rx_origin + start_shift - strbeg),
/* Success !!! */
if (rx_origin != s) {
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" By STCLASS: moving %ld --> %ld\n",
(long)(rx_origin - strbeg), (long)(s - strbeg))
);
}
else {
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
" Does not contradict STCLASS...\n");
);
}
/* Fixed substring is found far enough so that the match
cannot start at strpos. */
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, " try at offset...\n"));
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_ " try at offset...\n"));
++BmUSEFUL(utf8_target ? prog->check_utf8 : prog->check_substr); /* hooray/5 */
}
else {
)))
{
/* If flags & SOMETHING - do not do it many times on the same match */
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, " ... Disabling check substring...\n"));
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_ " ... Disabling check substring...\n"));
/* XXX Does the destruction order has to change with utf8_target? */
SvREFCNT_dec(utf8_target ? prog->check_utf8 : prog->check_substr);
SvREFCNT_dec(utf8_target ? prog->check_substr : prog->check_utf8);
}
}
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
"Intuit: %sSuccessfully guessed:%s match at offset %ld\n",
PL_colors[4], PL_colors[5], (long)(rx_origin - strbeg)) );
if (prog->check_substr || prog->check_utf8) /* could be removed already */
BmUSEFUL(utf8_target ? prog->check_utf8 : prog->check_substr) += 5; /* hooray */
fail:
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "%sMatch rejected by optimizer%s\n",
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_ "%sMatch rejected by optimizer%s\n",
PL_colors[4], PL_colors[5]));
return NULL;
}
} \
} STMT_END
-#define DUMP_EXEC_POS(li,s,doutf8) \
+#define DUMP_EXEC_POS(li,s,doutf8,depth) \
dump_exec_pos(li,s,(reginfo->strend),(reginfo->strbeg), \
- startpos, doutf8)
+ startpos, doutf8, depth)
#define REXEC_FBC_EXACTISH_SCAN(COND) \
STMT_START { \
reginclass(prog, c, (U8*)s, (U8*) strend, utf8_target));
}
else {
- REXEC_FBC_CLASS_SCAN(REGINCLASS(prog, c, (U8*)s));
+ REXEC_FBC_CLASS_SCAN(REGINCLASS(prog, c, (U8*)s, 0));
}
break;
DEBUG_TRIE_EXECUTE_r(
if ( uc <= (U8*)last_start && !BITMAP_TEST(bitmap,*uc) ) {
dump_exec_pos( (char *)uc, c, strend, real_start,
- (char *)uc, utf8_target );
- PerlIO_printf( Perl_debug_log,
+ (char *)uc, utf8_target, 0 );
+ Perl_re_printf( aTHX_
" Scanning for legal start char...\n");
}
);
foldbuf, uniflags);
DEBUG_TRIE_EXECUTE_r({
dump_exec_pos( (char *)uc, c, strend,
- real_start, s, utf8_target);
- PerlIO_printf(Perl_debug_log,
+ real_start, s, utf8_target, 0);
+ Perl_re_printf( aTHX_
" Charid:%3u CP:%4"UVxf" ",
charid, uvc);
});
DEBUG_TRIE_EXECUTE_r({
if (failed)
dump_exec_pos( (char *)uc, c, strend, real_start,
- s, utf8_target );
- PerlIO_printf( Perl_debug_log,
+ s, utf8_target, 0 );
+ Perl_re_printf( aTHX_
"%sState: %4"UVxf", word=%"UVxf,
failed ? " Fail transition to " : "",
(UV)state, (UV)word);
&& (tmp=trie->trans[offset].next))
{
DEBUG_TRIE_EXECUTE_r(
- PerlIO_printf( Perl_debug_log," - legal\n"));
+ Perl_re_printf( aTHX_ " - legal\n"));
state = tmp;
break;
}
else {
DEBUG_TRIE_EXECUTE_r(
- PerlIO_printf( Perl_debug_log," - fail\n"));
+ Perl_re_printf( aTHX_ " - fail\n"));
failed = 1;
state = aho->fail[state];
}
else {
/* we must be accepting here */
DEBUG_TRIE_EXECUTE_r(
- PerlIO_printf( Perl_debug_log," - accepting\n"));
+ Perl_re_printf( aTHX_ " - accepting\n"));
failed = 1;
break;
}
if (leftmost) {
s = (char*)leftmost;
DEBUG_TRIE_EXECUTE_r({
- PerlIO_printf(
- Perl_debug_log,"Matches word #%"UVxf" at position %"IVdf". Trying full pattern...\n",
+ Perl_re_printf( aTHX_ "Matches word #%"UVxf" at position %"IVdf". Trying full pattern...\n",
(UV)accepted_word, (IV)(s - real_start)
);
});
}
s = HOPc(s,1);
DEBUG_TRIE_EXECUTE_r({
- PerlIO_printf( Perl_debug_log,"Pattern failed. Looking for new start point...\n");
+ Perl_re_printf( aTHX_ "Pattern failed. Looking for new start point...\n");
});
} else {
DEBUG_TRIE_EXECUTE_r(
- PerlIO_printf( Perl_debug_log,"No match.\n"));
+ Perl_re_printf( aTHX_ "No match.\n"));
break;
}
}
if (flags & REXEC_COPY_STR) {
#ifdef PERL_ANY_COW
if (SvCANCOW(sv)) {
- if (DEBUG_C_TEST) {
- PerlIO_printf(Perl_debug_log,
+ DEBUG_C(Perl_re_printf( aTHX_
"Copy on write: regexp capture, type %d\n",
- (int) SvTYPE(sv));
- }
+ (int) SvTYPE(sv)));
/* Create a new COW SV to share the match string and store
* in saved_copy, unless the current COW SV in saved_copy
* is valid and suitable for our purpose */
? strbeg + MgBYTEPOS(mg, sv, strbeg, strend-strbeg)
: strbeg; /* pos() not defined; use start of string */
- DEBUG_GPOS_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_GPOS_r(Perl_re_printf( aTHX_
"GPOS ganch set to strbeg[%"IVdf"]\n", (IV)(reginfo->ganch - strbeg)));
/* in the presence of \G, we may need to start looking earlier in
if (!startpos ||
((flags & REXEC_FAIL_ON_UNDERFLOW) && startpos < stringarg))
{
- DEBUG_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_r(Perl_re_printf( aTHX_
"fail: ganch-gofs before earliest possible start\n"));
return 0;
}
minlen = prog->minlen;
if ((startpos + minlen) > strend || startpos < strbeg) {
- DEBUG_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_r(Perl_re_printf( aTHX_
"Regex match can't succeed, so not even tried\n"));
return 0;
}
{
/* this should only be possible under \G */
assert(prog->intflags & PREGf_GPOS_SEEN);
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
"matched, but failing for REXEC_FAIL_ON_UNDERFLOW\n"));
goto phooey;
}
multiline = prog->extflags & RXf_PMf_MULTILINE;
if (strend - s < (minlen+(prog->check_offset_min<0?prog->check_offset_min:0))) {
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
"String too short [regexec_flags]...\n"));
goto phooey;
}
swap = prog->offs;
/* do we need a save destructor here for eval dies? */
Newxz(prog->offs, (prog->nparens + 1), regexp_paren_pair);
- DEBUG_BUFFERS_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_BUFFERS_r(Perl_re_printf( aTHX_
"rex=0x%"UVxf" saving offs: orig=0x%"UVxf" new=0x%"UVxf"\n",
PTR2UV(prog),
PTR2UV(swap),
));
}
+ if (prog->recurse_locinput)
+ Zero(prog->recurse_locinput,prog->nparens + 1, char *);
+
/* Simplest case: anchored match need be tried only once, or with
* MBOL, only at the beginning of each line.
*
);
}
DEBUG_EXECUTE_r(if (!did_match)
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"Did not find anchored character...\n")
);
}
DEBUG_EXECUTE_r(if (!did_match) {
RE_PV_QUOTED_DECL(quoted, utf8_target, PERL_DEBUG_PAD_ZERO(0),
SvPVX_const(must), RE_SV_DUMPLEN(must), 30);
- PerlIO_printf(Perl_debug_log, "Did not find %s substr %s%s...\n",
+ Perl_re_printf( aTHX_ "Did not find %s substr %s%s...\n",
((must == prog->anchored_substr || must == prog->anchored_utf8)
? "anchored" : "floating"),
quoted, RE_SV_TAIL(must));
{
RE_PV_QUOTED_DECL(quoted,utf8_target,PERL_DEBUG_PAD_ZERO(1),
s,strend-s,60);
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"Matching stclass %.*s against %s (%d bytes)\n",
(int)SvCUR(prop), SvPVX_const(prop),
quoted, (int)(strend - s));
});
if (find_byclass(prog, c, s, strend, reginfo))
goto got_it;
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "Contradicts stclass... [regexec_flags]\n"));
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_ "Contradicts stclass... [regexec_flags]\n"));
}
else {
dontbother = 0;
* the \n. */
char *checkpos= strend - len;
DEBUG_OPTIMISE_r(
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"%sChecking for float_real.%s\n",
PL_colors[4], PL_colors[5]));
if (checkpos + 1 < strbeg) {
/* can't match, even if we remove the trailing \n
* string is too short to match */
DEBUG_EXECUTE_r(
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"%sString shorter than required trailing substring, cannot match.%s\n",
PL_colors[4], PL_colors[5]));
goto phooey;
/* cant match, string is too short when the "\n" is
* included */
DEBUG_EXECUTE_r(
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"%sString does not contain required trailing substring, cannot match.%s\n",
PL_colors[4], PL_colors[5]));
goto phooey;
last= checkpos;
} else {
DEBUG_EXECUTE_r(
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"%sString does not contain required trailing substring, cannot match.%s\n",
PL_colors[4], PL_colors[5]));
goto phooey;
* pretty sure it is not anymore, so I have removed the comment
* and replaced it with this one. Yves */
DEBUG_EXECUTE_r(
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"%sString does not contain required substring, cannot match.%s\n",
PL_colors[4], PL_colors[5]
));
{
/* this should only be possible under \G */
assert(prog->intflags & PREGf_GPOS_SEEN);
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
"matched, but failing for REXEC_FAIL_ON_UNDERFLOW\n"));
goto phooey;
}
DEBUG_BUFFERS_r(
if (swap)
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"rex=0x%"UVxf" freeing offs: 0x%"UVxf"\n",
PTR2UV(prog),
PTR2UV(swap)
return 1;
phooey:
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "%sMatch failed%s\n",
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_ "%sMatch failed%s\n",
PL_colors[4], PL_colors[5]));
/* clean up; this will trigger destructors that will free all slabs
if (swap) {
/* we failed :-( roll it back */
- DEBUG_BUFFERS_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_BUFFERS_r(Perl_re_printf( aTHX_
"rex=0x%"UVxf" rolling back offs: freeing=0x%"UVxf" restoring=0x%"UVxf"\n",
PTR2UV(prog),
PTR2UV(prog->offs),
REGEXP *const rx = reginfo->prog;
regexp *const prog = ReANY(rx);
SSize_t result;
+#ifdef DEBUGGING
+ U32 depth = 0; /* used by REGCP_SET */
+#endif
RXi_GET_DECL(prog,progi);
GET_RE_DEBUG_FLAGS_DECL;
sayNO
/* this is used to determine how far from the left messages like
- 'failed...' are printed. It should be set such that messages
- are inline with the regop output that created them.
+ 'failed...' are printed in regexec.c. It should be set such that
+ messages are inline with the regop output that created them.
*/
-#define REPORT_CODE_OFF 32
+#define REPORT_CODE_OFF 29
+#define INDENT_CHARS(depth) ((depth) % 20)
+#ifdef DEBUGGING
+int
+Perl_re_exec_indentf(pTHX_ const char *fmt, U32 depth, ...)
+{
+ va_list ap;
+ int result;
+ PerlIO *f= Perl_debug_log;
+ PERL_ARGS_ASSERT_RE_EXEC_INDENTF;
+ va_start(ap, depth);
+ PerlIO_printf(f, "%*s|%4d| %*s", REPORT_CODE_OFF, "", depth, INDENT_CHARS(depth), "" );
+ result = PerlIO_vprintf(f, fmt, ap);
+ va_end(ap);
+ return result;
+}
+#endif /* DEBUGGING */
#define CHRTEST_UNINIT -1001 /* c1/c2 haven't been calculated yet */
*/
-#define DEBUG_STATE_pp(pp) \
- DEBUG_STATE_r({ \
- DUMP_EXEC_POS(locinput, scan, utf8_target); \
- PerlIO_printf(Perl_debug_log, \
- " %*s"pp" %s%s%s%s%s\n", \
- depth*2, "", \
- PL_reg_name[st->resume_state], \
- ((st==yes_state||st==mark_state) ? "[" : ""), \
- ((st==yes_state) ? "Y" : ""), \
- ((st==mark_state) ? "M" : ""), \
- ((st==yes_state||st==mark_state) ? "]" : "") \
- ); \
+#define DEBUG_STATE_pp(pp) \
+ DEBUG_STATE_r({ \
+ DUMP_EXEC_POS(locinput, scan, utf8_target,depth); \
+ Perl_re_printf( aTHX_ \
+ "%*s" pp " %s%s%s%s%s\n", \
+ INDENT_CHARS(depth), "", \
+ PL_reg_name[st->resume_state], \
+ ((st==yes_state||st==mark_state) ? "[" : ""), \
+ ((st==yes_state) ? "Y" : ""), \
+ ((st==mark_state) ? "M" : ""), \
+ ((st==yes_state||st==mark_state) ? "]" : "") \
+ ); \
});
RE_PV_QUOTED_DECL(s1, utf8_target, PERL_DEBUG_PAD_ZERO(1),
start, end - start, 60);
- PerlIO_printf(Perl_debug_log,
+ Perl_re_printf( aTHX_
"%s%s REx%s %s against %s\n",
PL_colors[4], blurb, PL_colors[5], s0, s1);
if (utf8_target||utf8_pat)
- PerlIO_printf(Perl_debug_log, "UTF-8 %s%s%s...\n",
+ Perl_re_printf( aTHX_ "UTF-8 %s%s%s...\n",
utf8_pat ? "pattern" : "",
utf8_pat && utf8_target ? " and " : "",
utf8_target ? "string" : ""
const char *loc_regeol,
const char *loc_bostr,
const char *loc_reg_starttry,
- const bool utf8_target)
+ const bool utf8_target,
+ const U32 depth
+ )
{
const int docolor = *PL_colors[0] || *PL_colors[2] || *PL_colors[4];
const int taill = (docolor ? 10 : 7); /* 3 chars for "> <" */
locinput, loc_regeol - locinput, 10, 0, 1);
const STRLEN tlen=len0+len1+len2;
- PerlIO_printf(Perl_debug_log,
- "%4"IVdf" <%.*s%.*s%s%.*s>%*s|",
+ Perl_re_printf( aTHX_
+ "%4"IVdf" <%.*s%.*s%s%.*s>%*s|%4u| ",
(IV)(locinput - loc_bostr),
len0, s0,
len1, s1,
(docolor ? "" : "> <"),
len2, s2,
(int)(tlen > 19 ? 0 : 19 - tlen),
- "");
+ "",
+ depth);
}
}
}
else { /* Does participate in folds */
AV* list = (AV*) *listp;
- if (av_tindex(list) != 1) {
+ if (av_tindex_nomg(list) != 1) {
/* If there aren't exactly two folds to this, it is
* outside the scope of this function */
}
#ifdef DEBUGGING
- PerlIO_printf(Perl_error_log, "Unhandled LB pair: LB_table[%d, %d] = %d\n",
+ Perl_re_printf( aTHX_ "Unhandled LB pair: LB_table[%d, %d] = %d\n",
before, after, LB_table[before][after]);
assert(0);
#endif
}
#ifdef DEBUGGING
- PerlIO_printf(Perl_error_log, "Unhandled WB pair: WB_table[%d, %d] = %d\n",
+ Perl_re_printf( aTHX_ "Unhandled WB pair: WB_table[%d, %d] = %d\n",
before, after, WB_table[before][after]);
assert(0);
#endif
return wb;
}
+#define EVAL_CLOSE_PAREN_IS(st,expr) \
+( \
+ ( ( st ) ) && \
+ ( ( st )->u.eval.close_paren ) && \
+ ( ( ( st )->u.eval.close_paren ) == ( (expr) + 1 ) ) \
+)
+
+#define EVAL_CLOSE_PAREN_IS_TRUE(st,expr) \
+( \
+ ( ( st ) ) && \
+ ( ( st )->u.eval.close_paren ) && \
+ ( ( expr ) ) && \
+ ( ( ( st )->u.eval.close_paren ) == ( (expr) + 1 ) ) \
+)
+
+
+#define EVAL_CLOSE_PAREN_SET(st,expr) \
+ (st)->u.eval.close_paren = ( (expr) + 1 )
+
+#define EVAL_CLOSE_PAREN_CLEAR(st) \
+ (st)->u.eval.close_paren = 0
+
/* returns -1 on failure, $+[0] on success */
STATIC SSize_t
S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
bool is_utf8_pat = reginfo->is_utf8_pat;
bool match = FALSE;
-
#ifdef DEBUGGING
GET_RE_DEBUG_FLAGS_DECL;
#endif
PERL_ARGS_ASSERT_REGMATCH;
DEBUG_OPTIMISE_r( DEBUG_EXECUTE_r({
- PerlIO_printf(Perl_debug_log,"regmatch start\n");
+ Perl_re_printf( aTHX_ "regmatch start\n");
}));
st = PL_regmatch_state;
scan = prog;
while (scan != NULL) {
- DEBUG_EXECUTE_r( {
- SV * const prop = sv_newmortal();
- regnode *rnext=regnext(scan);
- DUMP_EXEC_POS( locinput, scan, utf8_target );
- regprop(rex, prop, scan, reginfo, NULL);
-
- PerlIO_printf(Perl_debug_log,
- "%3"IVdf":%*s%s(%"IVdf")\n",
- (IV)(scan - rexi->program), depth*2, "",
- SvPVX_const(prop),
- (PL_regkind[OP(scan)] == END || !rnext) ?
- 0 : (IV)(rnext - rexi->program));
- });
next = scan + NEXT_OFF(scan);
if (next == scan)
state_num = OP(scan);
reenter_switch:
+ DEBUG_EXECUTE_r(
+ if (state_num <= REGNODE_MAX) {
+ SV * const prop = sv_newmortal();
+ regnode *rnext = regnext(scan);
+
+ DUMP_EXEC_POS( locinput, scan, utf8_target, depth );
+ regprop(rex, prop, scan, reginfo, NULL);
+ Perl_re_printf( aTHX_
+ "%*s%"IVdf":%s(%"IVdf")\n",
+ INDENT_CHARS(depth), "",
+ (IV)(scan - rexi->program),
+ SvPVX_const(prop),
+ (PL_regkind[OP(scan)] == END || !rnext) ?
+ 0 : (IV)(rnext - rexi->program));
+ }
+ );
+
to_complement = 0;
SET_nextchr;
st->u.keeper.val = rex->offs[0].start;
rex->offs[0].start = locinput - reginfo->strbeg;
PUSH_STATE_GOTO(KEEPS_next, next, locinput);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case KEEPS_next_fail:
/* rollback the start point change */
rex->offs[0].start = st->u.keeper.val;
sayNO_SILENT;
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case MEOL: /* /..$/m */
*/
if(!NEXTCHR_IS_EOS && !ANYOF_BITMAP_TEST(scan, nextchr)) {
DEBUG_EXECUTE_r(
- PerlIO_printf(Perl_debug_log,
- "%*s %sfailed to match trie start class...%s\n",
- REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5])
+ Perl_re_exec_indentf( aTHX_ "%sfailed to match trie start class...%s\n",
+ depth, PL_colors[4], PL_colors[5])
);
sayNO_SILENT;
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
}
/* FALLTHROUGH */
{
if (trie->states[ state ].wordnum) {
DEBUG_EXECUTE_r(
- PerlIO_printf(Perl_debug_log,
- "%*s %smatched empty string...%s\n",
- REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5])
+ Perl_re_exec_indentf( aTHX_ "%smatched empty string...%s\n",
+ depth, PL_colors[4], PL_colors[5])
);
if (!trie->jump)
break;
} else {
DEBUG_EXECUTE_r(
- PerlIO_printf(Perl_debug_log,
- "%*s %sfailed to match trie start class...%s\n",
- REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5])
+ Perl_re_exec_indentf( aTHX_ "%sfailed to match trie start class...%s\n",
+ depth, PL_colors[4], PL_colors[5])
);
sayNO_SILENT;
}
}
DEBUG_TRIE_EXECUTE_r({
- DUMP_EXEC_POS( (char *)uc, scan, utf8_target );
- PerlIO_printf( Perl_debug_log,
- "%*s %sState: %4"UVxf" Accepted: %c ",
- 2+depth * 2, "", PL_colors[4],
+ DUMP_EXEC_POS( (char *)uc, scan, utf8_target, depth );
+ Perl_re_exec_indentf( aTHX_
+ "%sState: %4"UVxf" Accepted: %c ",
+ depth, PL_colors[4],
(UV)state, (accepted ? 'Y' : 'N'));
});
state = 0;
}
DEBUG_TRIE_EXECUTE_r(
- PerlIO_printf( Perl_debug_log,
+ Perl_re_printf( aTHX_
"Charid:%3x CP:%4"UVxf" After State: %4"UVxf"%s\n",
charid, uvc, (UV)state, PL_colors[5] );
);
}
DEBUG_EXECUTE_r(
- PerlIO_printf( Perl_debug_log,
- "%*s %sgot %"IVdf" possible matches%s\n",
- REPORT_CODE_OFF + depth * 2, "",
+ Perl_re_exec_indentf( aTHX_ "%sgot %"IVdf" possible matches%s\n",
+ depth,
PL_colors[4], (IV)ST.accepted, PL_colors[5] );
);
goto trie_first_try; /* jump into the fail handler */
}}
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case TRIE_next_fail: /* we failed - try next alternative */
}
if (!--ST.accepted) {
DEBUG_EXECUTE_r({
- PerlIO_printf( Perl_debug_log,
- "%*s %sTRIE failed...%s\n",
- REPORT_CODE_OFF+depth*2, "",
+ Perl_re_exec_indentf( aTHX_ "%sTRIE failed...%s\n",
+ depth,
PL_colors[4],
PL_colors[5] );
});
: NEXT_OFF(ST.me));
DEBUG_EXECUTE_r({
- PerlIO_printf( Perl_debug_log,
- "%*s %sTRIE matched word #%d, continuing%s\n",
- REPORT_CODE_OFF+depth*2, "",
+ Perl_re_exec_indentf( aTHX_ "%sTRIE matched word #%d, continuing%s\n",
+ depth,
PL_colors[4],
ST.nextword,
PL_colors[5]
if (ST.accepted > 1 || has_cutgroup) {
PUSH_STATE_GOTO(TRIE_next, scan, (char*)uc);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
}
/* only one choice left - just continue */
? av_fetch(trie_words, ST.nextword - 1, 0) : NULL;
SV *sv= tmp ? sv_newmortal() : NULL;
- PerlIO_printf( Perl_debug_log,
- "%*s %sonly one match left, short-circuiting: #%d <%s>%s\n",
- REPORT_CODE_OFF+depth*2, "", PL_colors[4],
+ Perl_re_exec_indentf( aTHX_ "%sonly one match left, short-circuiting: #%d <%s>%s\n",
+ depth, PL_colors[4],
ST.nextword,
tmp ? pv_pretty(sv, SvPV_nolen_const(*tmp), SvCUR(*tmp), 0,
PL_colors[0], PL_colors[1],
locinput += UTF8SKIP(locinput);
}
else {
- if (!REGINCLASS(rex, scan, (U8*)locinput))
+ if (!REGINCLASS(rex, scan, (U8*)locinput, utf8_target))
sayNO;
locinput++;
}
#undef ST
#define ST st->u.eval
+#define CUR_EVAL cur_eval->u.eval
+
{
SV *ret;
REGEXP *re_sv;
regexp *re;
regexp_internal *rei;
regnode *startpoint;
+ U32 arg;
- case GOSTART: /* (?R) */
case GOSUB: /* /(...(?1))/ /(...(?&foo))/ */
- if (cur_eval && cur_eval->locinput==locinput) {
- if (cur_eval->u.eval.close_paren == (U32)ARG(scan))
- Perl_croak(aTHX_ "Infinite recursion in regex");
+ arg= (U32)ARG(scan);
+ if (cur_eval && cur_eval->locinput == locinput) {
if ( ++nochange_depth > max_nochange_depth )
Perl_croak(aTHX_
"Pattern subroutine nesting without pos change"
re_sv = rex_sv;
re = rex;
rei = rexi;
- if (OP(scan)==GOSUB) {
- startpoint = scan + ARG2L(scan);
- ST.close_paren = ARG(scan);
+ startpoint = scan + ARG2L(scan);
+ EVAL_CLOSE_PAREN_SET( st, arg );
+ /* Detect infinite recursion
+ *
+ * A pattern like /(?R)foo/ or /(?<x>(?&y)foo)(?<y>(?&x)bar)/
+ * or "a"=~/(.(?2))((?<=(?=(?1)).))/ could recurse forever.
+ * So we track the position in the string we are at each time
+ * we recurse and if we try to enter the same routine twice from
+ * the same position we throw an error.
+ */
+ if ( rex->recurse_locinput[arg] == locinput ) {
+ /* FIXME: we should show the regop that is failing as part
+ * of the error message. */
+ Perl_croak(aTHX_ "Infinite recursion in regex");
} else {
- startpoint = rei->program+1;
- ST.close_paren = 0;
+ ST.prev_recurse_locinput= rex->recurse_locinput[arg];
+ rex->recurse_locinput[arg]= locinput;
+
+ DEBUG_r({
+ GET_RE_DEBUG_FLAGS_DECL;
+ DEBUG_STACK_r({
+ Perl_re_exec_indentf( aTHX_
+ "entering GOSUB, prev_recurse_locinput=%p recurse_locinput[%d]=%p\n",
+ depth, ST.prev_recurse_locinput, arg, rex->recurse_locinput[arg]
+ );
+ });
+ });
}
/* Save all the positions seen so far. */
n = ARG(scan);
if (rexi->data->what[n] == 'r') { /* code from an external qr */
- newcv = (ReANY(
- (REGEXP*)(rexi->data->data[n])
- ))->qr_anoncv
- ;
+ newcv = (ReANY(
+ (REGEXP*)(rexi->data->data[n])
+ ))->qr_anoncv;
nop = (OP*)rexi->data->data[n+1];
}
else if (rexi->data->what[n] == 'l') { /* literal code */
}
nop = nop->op_next;
- DEBUG_STATE_r( PerlIO_printf(Perl_debug_log,
+ DEBUG_STATE_r( Perl_re_printf( aTHX_
" re EVAL PL_op=0x%"UVxf"\n", PTR2UV(nop)) );
rex->offs[0].end = locinput - reginfo->strbeg;
reginfo->strend, "Matching embedded");
);
startpoint = rei->program + 1;
- ST.close_paren = 0; /* only used for GOSUB */
+ EVAL_CLOSE_PAREN_CLEAR(st); /* ST.close_paren = 0;
+ * close_paren only for GOSUB */
+ ST.prev_recurse_locinput= NULL; /* only used for GOSUB */
/* Save all the seen positions so far. */
ST.cp = regcppush(rex, 0, maxopenparen);
REGCP_SET(ST.lastcp);
cur_eval = st;
/* now continue from first node in postoned RE */
PUSH_YES_STATE_GOTO(EVAL_AB, startpoint, locinput);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
}
case EVAL_AB: /* cleanup after a successful (??{A})B */
- /* note: this is called twice; first after popping B, then A */
+ DEBUG_STACK_r({
+ Perl_re_exec_indentf( aTHX_ "EVAL_AB cur_eval=%p prev_eval=%p\n",
+ depth, cur_eval, ST.prev_eval);
+ });
+
+#define SET_RECURSE_LOCINPUT(STR,VAL)\
+ if ( cur_eval && CUR_EVAL.close_paren ) {\
+ DEBUG_STACK_r({ \
+ Perl_re_exec_indentf( aTHX_ STR " GOSUB%d ce=%p recurse_locinput=%p\n",\
+ depth, \
+ CUR_EVAL.close_paren - 1,\
+ cur_eval, \
+ VAL); \
+ }); \
+ rex->recurse_locinput[CUR_EVAL.close_paren - 1] = VAL;\
+ }
+
+ SET_RECURSE_LOCINPUT("EVAL_AB[before]", CUR_EVAL.prev_recurse_locinput);
+
rex_sv = ST.prev_rex;
is_utf8_pat = reginfo->is_utf8_pat = cBOOL(RX_UTF8(rex_sv));
SET_reg_curpm(rex_sv);
reginfo->poscache_maxiter = 0;
if ( nochange_depth )
nochange_depth--;
+
+ SET_RECURSE_LOCINPUT("EVAL_AB[after]", cur_eval->locinput);
sayYES;
case EVAL_AB_fail: /* unsuccessfully ran A or B in (??{A})B */
/* note: this is called twice; first after popping B, then A */
+ DEBUG_STACK_r({
+ Perl_re_exec_indentf( aTHX_ "EVAL_AB_fail cur_eval=%p prev_eval=%p\n",
+ depth, cur_eval, ST.prev_eval);
+ });
+
+ SET_RECURSE_LOCINPUT("EVAL_AB_fail[before]", CUR_EVAL.prev_recurse_locinput);
+
rex_sv = ST.prev_rex;
is_utf8_pat = reginfo->is_utf8_pat = cBOOL(RX_UTF8(rex_sv));
SET_reg_curpm(rex_sv);
regcppop(rex, &maxopenparen);
cur_eval = ST.prev_eval;
cur_curlyx = ST.prev_curlyx;
+
/* Invalidate cache. See "invalidate" comment above. */
reginfo->poscache_maxiter = 0;
if ( nochange_depth )
nochange_depth--;
- sayNO_SILENT;
+
+ SET_RECURSE_LOCINPUT("EVAL_AB_fail[after]", cur_eval->locinput);
+ sayNO_SILENT;
#undef ST
case OPEN: /* ( */
rex->offs[n].start_tmp = locinput - reginfo->strbeg;
if (n > maxopenparen)
maxopenparen = n;
- DEBUG_BUFFERS_r(PerlIO_printf(Perl_debug_log,
+ DEBUG_BUFFERS_r(Perl_re_printf( aTHX_
"rex=0x%"UVxf" offs=0x%"UVxf": \\%"UVuf": set %"IVdf" tmp; maxopenparen=%"UVuf"\n",
PTR2UV(rex),
PTR2UV(rex->offs),
break;
/* XXX really need to log other places start/end are set too */
-#define CLOSE_CAPTURE \
- rex->offs[n].start = rex->offs[n].start_tmp; \
- rex->offs[n].end = locinput - reginfo->strbeg; \
- DEBUG_BUFFERS_r(PerlIO_printf(Perl_debug_log, \
- "rex=0x%"UVxf" offs=0x%"UVxf": \\%"UVuf": set %"IVdf"..%"IVdf"\n", \
- PTR2UV(rex), \
- PTR2UV(rex->offs), \
- (UV)n, \
- (IV)rex->offs[n].start, \
- (IV)rex->offs[n].end \
+#define CLOSE_CAPTURE \
+ rex->offs[n].start = rex->offs[n].start_tmp; \
+ rex->offs[n].end = locinput - reginfo->strbeg; \
+ DEBUG_BUFFERS_r(Perl_re_printf( aTHX_ \
+ "rex=0x%"UVxf" offs=0x%"UVxf": \\%"UVuf": set %"IVdf"..%"IVdf"\n", \
+ PTR2UV(rex), \
+ PTR2UV(rex->offs), \
+ (UV)n, \
+ (IV)rex->offs[n].start, \
+ (IV)rex->offs[n].end \
))
case CLOSE: /* ) */
if (n > rex->lastparen)
rex->lastparen = n;
rex->lastcloseparen = n;
- if (cur_eval && cur_eval->u.eval.close_paren == n) {
+ if ( EVAL_CLOSE_PAREN_IS( cur_eval, n ) )
goto fake_end;
- }
+
break;
case ACCEPT: /* (*ACCEPT) */
if (n > rex->lastparen)
rex->lastparen = n;
rex->lastcloseparen = n;
- if ( n == ARG(scan) || (cur_eval &&
- cur_eval->u.eval.close_paren == n))
+ if ( n == ARG(scan) || EVAL_CLOSE_PAREN_IS(cur_eval, n) )
break;
}
}
case INSUBP: /* (?(R)) */
n = ARG(scan);
- sw = (cur_eval && (!n || cur_eval->u.eval.close_paren == n));
+ /* this does not need to use EVAL_CLOSE_PAREN macros, as the arg
+ * of SCAN is already set up as matches a eval.close_paren */
+ sw = cur_eval && (n == 0 || CUR_EVAL.close_paren == n);
break;
case DEFINEP: /* (?(DEFINE)) */
ST.lastloc = NULL; /* this will be updated by WHILEM */
PUSH_YES_STATE_GOTO(CURLYX_end, PREVOPER(next), locinput);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
}
case CURLYX_end: /* just finished matching all of A*B */
cur_curlyx = ST.prev_curlyx;
sayYES;
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case CURLYX_end_fail: /* just failed to match all of A*B */
regcpblow(ST.cp);
cur_curlyx = ST.prev_curlyx;
sayNO;
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
ST.cache_mask = 0;
- DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
- "%*s whilem: matched %ld out of %d..%d\n",
- REPORT_CODE_OFF+depth*2, "", (long)n, min, max)
+ DEBUG_EXECUTE_r( Perl_re_exec_indentf( aTHX_ "whilem: matched %ld out of %d..%d\n",
+ depth, (long)n, min, max)
);
/* First just match a string of min A's. */
REGCP_SET(ST.lastcp);
PUSH_STATE_GOTO(WHILEM_A_pre, A, locinput);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
}
/* If degenerate A matches "", assume A done. */
if (locinput == cur_curlyx->u.curlyx.lastloc) {
- DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
- "%*s whilem: empty match detected, trying continuation...\n",
- REPORT_CODE_OFF+depth*2, "")
+ DEBUG_EXECUTE_r( Perl_re_exec_indentf( aTHX_ "whilem: empty match detected, trying continuation...\n",
+ depth)
);
goto do_whilem_B_max;
}
reginfo->poscache_size = size;
Newxz(aux->poscache, size, char);
}
- DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
+ DEBUG_EXECUTE_r( Perl_re_printf( aTHX_
"%swhilem: Detected a super-linear match, switching on caching%s...\n",
PL_colors[4], PL_colors[5])
);
mask = 1 << (offset % 8);
offset /= 8;
if (reginfo->info_aux->poscache[offset] & mask) {
- DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
- "%*s whilem: (cache) already tried at this position...\n",
- REPORT_CODE_OFF+depth*2, "")
+ DEBUG_EXECUTE_r( Perl_re_exec_indentf( aTHX_ "whilem: (cache) already tried at this position...\n",
+ depth)
);
sayNO; /* cache records failure */
}
REGCP_SET(ST.lastcp);
PUSH_YES_STATE_GOTO(WHILEM_B_min, ST.save_curlyx->u.curlyx.B,
locinput);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
}
cur_curlyx->u.curlyx.lastloc = locinput;
REGCP_SET(ST.lastcp);
PUSH_STATE_GOTO(WHILEM_A_max, A, locinput);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
}
goto do_whilem_B_max;
}
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case WHILEM_B_min: /* just matched B in a minimal match */
case WHILEM_B_max: /* just matched B in a maximal match */
cur_curlyx = ST.save_curlyx;
sayYES;
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case WHILEM_B_max_fail: /* just failed to match B in a maximal match */
cur_curlyx->u.curlyx.lastloc = ST.save_lastloc;
cur_curlyx->u.curlyx.count--;
CACHEsayNO;
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case WHILEM_A_min_fail: /* just failed to match A in a minimal match */
cur_curlyx->u.curlyx.lastloc = ST.save_lastloc;
cur_curlyx->u.curlyx.count--;
CACHEsayNO;
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case WHILEM_A_max_fail: /* just failed to match A in a maximal match */
REGCP_UNWIND(ST.lastcp);
regcppop(rex, &maxopenparen); /* Restore some previous $<digit>s? */
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
- "%*s whilem: failed, trying continuation...\n",
- REPORT_CODE_OFF+depth*2, "")
+ DEBUG_EXECUTE_r(Perl_re_exec_indentf( aTHX_ "whilem: failed, trying continuation...\n",
+ depth)
);
do_whilem_B_max:
if (cur_curlyx->u.curlyx.count >= REG_INFTY
cur_curlyx = cur_curlyx->u.curlyx.prev_curlyx;
PUSH_YES_STATE_GOTO(WHILEM_B_max, ST.save_curlyx->u.curlyx.B,
locinput);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case WHILEM_B_min_fail: /* just failed to match B in a minimal match */
CACHEsayNO;
}
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
- "%*s trying longer...\n", REPORT_CODE_OFF+depth*2, "")
+ DEBUG_EXECUTE_r(Perl_re_exec_indentf( aTHX_ "trying longer...\n", depth)
);
/* Try grabbing another A and see if it helps. */
cur_curlyx->u.curlyx.lastloc = locinput;
PUSH_STATE_GOTO(WHILEM_A_min,
/*A*/ NEXTOPER(ST.save_curlyx->u.curlyx.me) + EXTRA_STEP_2ARGS,
locinput);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
#undef ST
} else {
PUSH_STATE_GOTO(BRANCH_next, scan, locinput);
}
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case CUTGROUP: /* /(*THEN)/ */
? MUTABLE_SV(rexi->data->data[ ARG( scan ) ])
: NULL;
PUSH_STATE_GOTO(CUTGROUP_next, next, locinput);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case CUTGROUP_next_fail:
if (st->u.mark.mark_name)
sv_commit = st->u.mark.mark_name;
sayNO;
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case BRANCH_next:
sayYES;
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case BRANCH_next_fail: /* that branch failed; try the next, if any */
/* no more branches? */
if (!scan || (OP(scan) != BRANCH && OP(scan) != BRANCHJ)) {
DEBUG_EXECUTE_r({
- PerlIO_printf( Perl_debug_log,
- "%*s %sBRANCH failed...%s\n",
- REPORT_CODE_OFF+depth*2, "",
+ Perl_re_exec_indentf( aTHX_ "%sBRANCH failed...%s\n",
+ depth,
PL_colors[4],
PL_colors[5] );
});
curlym_do_A: /* execute the A in /A{m,n}B/ */
PUSH_YES_STATE_GOTO(CURLYM_A, ST.A, locinput); /* match A */
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case CURLYM_A: /* we've just matched an A */
ST.count = ST.minmod ? ARG1(ST.me) : ARG2(ST.me);
}
DEBUG_EXECUTE_r(
- PerlIO_printf(Perl_debug_log,
- "%*s CURLYM now matched %"IVdf" times, len=%"IVdf"...\n",
- (int)(REPORT_CODE_OFF+(depth*2)), "",
- (IV) ST.count, (IV)ST.alen)
+ Perl_re_exec_indentf( aTHX_ "CURLYM now matched %"IVdf" times, len=%"IVdf"...\n",
+ depth, (IV) ST.count, (IV)ST.alen)
);
- if (cur_eval && cur_eval->u.eval.close_paren &&
- cur_eval->u.eval.close_paren == (U32)ST.me->flags)
+ if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.me->flags))
goto fake_end;
{
case CURLYM_A_fail: /* just failed to match an A */
REGCP_UNWIND(ST.cp);
+
if (ST.minmod || ST.count < ARG1(ST.me) /* min*/
- || (cur_eval && cur_eval->u.eval.close_paren &&
- cur_eval->u.eval.close_paren == (U32)ST.me->flags))
+ || EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.me->flags))
sayNO;
curlym_do_B: /* execute the B in /A{m,n}B/ */
}
DEBUG_EXECUTE_r(
- PerlIO_printf(Perl_debug_log,
- "%*s CURLYM trying tail with matches=%"IVdf"...\n",
- (int)(REPORT_CODE_OFF+(depth*2)),
- "", (IV)ST.count)
+ Perl_re_exec_indentf( aTHX_ "CURLYM trying tail with matches=%"IVdf"...\n",
+ depth, (IV)ST.count)
);
if (! NEXTCHR_IS_EOS && ST.c1 != CHRTEST_VOID) {
if (! UTF8_IS_INVARIANT(nextchr) && utf8_target) {
{
/* simulate B failing */
DEBUG_OPTIMISE_r(
- PerlIO_printf(Perl_debug_log,
- "%*s CURLYM Fast bail next target=0x%"UVXf" c1=0x%"UVXf" c2=0x%"UVXf"\n",
- (int)(REPORT_CODE_OFF+(depth*2)),"",
+ Perl_re_exec_indentf( aTHX_ "CURLYM Fast bail next target=0x%"UVXf" c1=0x%"UVXf" c2=0x%"UVXf"\n",
+ depth,
valid_utf8_to_uvchr((U8 *) locinput, NULL),
valid_utf8_to_uvchr(ST.c1_utf8, NULL),
valid_utf8_to_uvchr(ST.c2_utf8, NULL))
else if (nextchr != ST.c1 && nextchr != ST.c2) {
/* simulate B failing */
DEBUG_OPTIMISE_r(
- PerlIO_printf(Perl_debug_log,
- "%*s CURLYM Fast bail next target=0x%X c1=0x%X c2=0x%X\n",
- (int)(REPORT_CODE_OFF+(depth*2)),"",
+ Perl_re_exec_indentf( aTHX_ "CURLYM Fast bail next target=0x%X c1=0x%X c2=0x%X\n",
+ depth,
(int) nextchr, ST.c1, ST.c2)
);
state_num = CURLYM_B_fail;
}
else
rex->offs[paren].end = -1;
- if (cur_eval && cur_eval->u.eval.close_paren &&
- cur_eval->u.eval.close_paren == (U32)ST.me->flags)
+
+ if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.me->flags))
{
if (ST.count)
goto fake_end;
}
PUSH_STATE_GOTO(CURLYM_B, ST.B, locinput); /* match B */
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case CURLYM_B_fail: /* just failed to match a B */
maxopenparen = ST.paren;
ST.min = ARG1(scan); /* min to match */
ST.max = ARG2(scan); /* max to match */
- if (cur_eval && cur_eval->u.eval.close_paren &&
- cur_eval->u.eval.close_paren == (U32)ST.paren) {
+ if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.paren))
+ {
ST.min=1;
ST.max=1;
}
REGCP_SET(ST.cp);
goto curly_try_B_max;
}
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case CURLY_B_min_known_fail:
assert(n == REG_INFTY || locinput == li);
}
CURLY_SETPAREN(ST.paren, ST.count);
- if (cur_eval && cur_eval->u.eval.close_paren &&
- cur_eval->u.eval.close_paren == (U32)ST.paren) {
+ if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.paren))
goto fake_end;
- }
PUSH_STATE_GOTO(CURLY_B_min_known, ST.B, locinput);
}
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case CURLY_B_min_fail:
{
curly_try_B_min:
CURLY_SETPAREN(ST.paren, ST.count);
- if (cur_eval && cur_eval->u.eval.close_paren &&
- cur_eval->u.eval.close_paren == (U32)ST.paren) {
+ if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.paren))
goto fake_end;
- }
PUSH_STATE_GOTO(CURLY_B_min, ST.B, locinput);
}
}
sayNO;
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
curly_try_B_max:
/* a successful greedy match: now try to match B */
- if (cur_eval && cur_eval->u.eval.close_paren &&
- cur_eval->u.eval.close_paren == (U32)ST.paren) {
+ if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.paren))
goto fake_end;
- }
{
bool could_match = locinput < reginfo->strend;
if (ST.c1 == CHRTEST_VOID || could_match) {
CURLY_SETPAREN(ST.paren, ST.count);
PUSH_STATE_GOTO(CURLY_B_max, ST.B, locinput);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
}
}
fake_end:
if (cur_eval) {
/* we've just finished A in /(??{A})B/; now continue with B */
-
+ SET_RECURSE_LOCINPUT("FAKE-END[before]", CUR_EVAL.prev_recurse_locinput);
st->u.eval.prev_rex = rex_sv; /* inner */
/* Save *all* the positions. */
st->u.eval.cp = regcppush(rex, 0, maxopenparen);
- rex_sv = cur_eval->u.eval.prev_rex;
+ rex_sv = CUR_EVAL.prev_rex;
is_utf8_pat = reginfo->is_utf8_pat = cBOOL(RX_UTF8(rex_sv));
SET_reg_curpm(rex_sv);
rex = ReANY(rex_sv);
rexi = RXi_GET(rex);
- cur_curlyx = cur_eval->u.eval.prev_curlyx;
+
+ st->u.eval.prev_curlyx = cur_curlyx;
+ cur_curlyx = CUR_EVAL.prev_curlyx;
REGCP_SET(st->u.eval.lastcp);
/* Restore parens of the outer rex without popping the
* savestack */
- S_regcp_restore(aTHX_ rex, cur_eval->u.eval.lastcp,
+ S_regcp_restore(aTHX_ rex, CUR_EVAL.lastcp,
&maxopenparen);
st->u.eval.prev_eval = cur_eval;
- cur_eval = cur_eval->u.eval.prev_eval;
+ cur_eval = CUR_EVAL.prev_eval;
DEBUG_EXECUTE_r(
- PerlIO_printf(Perl_debug_log, "%*s EVAL trying tail ... %"UVxf"\n",
- REPORT_CODE_OFF+depth*2, "",PTR2UV(cur_eval)););
+ Perl_re_exec_indentf( aTHX_ "EVAL trying tail ... (cur_eval=%p)\n",
+ depth, cur_eval););
if ( nochange_depth )
nochange_depth--;
+ SET_RECURSE_LOCINPUT("FAKE-END[after]", cur_eval->locinput);
+
PUSH_YES_STATE_GOTO(EVAL_AB, st->u.eval.prev_eval->u.eval.B,
locinput); /* match B */
}
if (locinput < reginfo->till) {
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
- "%sMatch possible, but length=%ld is smaller than requested=%ld, failing!%s\n",
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
+ "%sMatch possible, but length=%ld is smaller than requested=%ld, failing!%s\n",
PL_colors[4],
(long)(locinput - startpos),
(long)(reginfo->till - startpos),
case SUCCEED: /* successful SUSPEND/UNLESSM/IFMATCH/CURLYM */
DEBUG_EXECUTE_r(
- PerlIO_printf(Perl_debug_log,
- "%*s %ssubpattern success...%s\n",
- REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5]));
+ Perl_re_exec_indentf( aTHX_ "%ssubpattern success...%s\n",
+ depth, PL_colors[4], PL_colors[5]));
sayYES; /* Success! */
#undef ST
/* execute body of (?...A) */
PUSH_YES_STATE_GOTO(IFMATCH_A, NEXTOPER(NEXTOPER(scan)), newstart);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
}
if (scan->flags)
sv_yes_mark = sv_commit = MUTABLE_SV(rexi->data->data[ ARG( scan ) ]);
PUSH_STATE_GOTO(COMMIT_next, next, locinput);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case COMMIT_next_fail:
} else {
sayNO;
}
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
#define ST st->u.mark
mark_state = st;
ST.mark_loc = locinput;
PUSH_YES_STATE_GOTO(MARKPOINT_next, next, locinput);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case MARKPOINT_next:
mark_state = ST.prev_mark;
sayYES;
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case MARKPOINT_next_fail:
sv_commit = ST.mark_name;
DEBUG_EXECUTE_r({
- PerlIO_printf(Perl_debug_log,
- "%*s %ssetting cutpoint to mark:%"SVf"...%s\n",
- REPORT_CODE_OFF+depth*2, "",
+ Perl_re_exec_indentf( aTHX_ "%ssetting cutpoint to mark:%"SVf"...%s\n",
+ depth,
PL_colors[4], SVfARG(sv_commit), PL_colors[5]);
});
}
sv_yes_mark = mark_state ?
mark_state->u.mark.mark_name : NULL;
sayNO;
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
case SKIP: /* (*SKIP) */
}
no_final = 1;
sayNO;
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
#undef ST
regmatch_state *curyes = yes_state;
int curd = depth;
regmatch_slab *slab = PL_regmatch_slab;
- for (;curd > -1;cur--,curd--) {
+ for (;curd > -1 && (depth-curd < 3);cur--,curd--) {
if (cur < SLAB_FIRST(slab)) {
slab = slab->prev;
cur = SLAB_LAST(slab);
}
- PerlIO_printf(Perl_error_log, "%*s#%-3d %-10s %s\n",
- REPORT_CODE_OFF + 2 + depth * 2,"",
+ Perl_re_exec_indentf( aTHX_ "#%-3d %-10s %s\n",
+ depth,
curd, PL_reg_name[cur->resume_state],
(curyes == cur) ? "yes" : ""
);
* the terminating point.
*/
Perl_croak(aTHX_ "corrupted regexp pointers");
- /* NOTREACHED */
- sayNO;
NOT_REACHED; /* NOTREACHED */
yes:
goto reenter_switch;
}
- DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "%sMatch successful!%s\n",
+ DEBUG_EXECUTE_r(Perl_re_printf( aTHX_ "%sMatch successful!%s\n",
PL_colors[4], PL_colors[5]));
if (reginfo->info_aux_eval) {
no:
DEBUG_EXECUTE_r(
- PerlIO_printf(Perl_debug_log,
- "%*s %sfailed...%s\n",
- REPORT_CODE_OFF+depth*2, "",
+ Perl_re_exec_indentf( aTHX_ "%sfailed...%s\n",
+ depth,
PL_colors[4], PL_colors[5])
);
hardcount++;
}
} else {
- while (scan < loceol && REGINCLASS(prog, p, (U8*)scan))
+ while (scan < loceol && REGINCLASS(prog, p, (U8*)scan, 0))
scan++;
}
break;
default:
Perl_croak(aTHX_ "panic: regrepeat() called with unrecognized node type %d='%s'", OP(p), PL_reg_name[OP(p)]);
- /* NOTREACHED */
NOT_REACHED; /* NOTREACHED */
}
DEBUG_EXECUTE_r({
SV * const prop = sv_newmortal();
regprop(prog, prop, p, reginfo, NULL);
- PerlIO_printf(Perl_debug_log,
- "%*s %s can match %"IVdf" times out of %"IVdf"...\n",
- REPORT_CODE_OFF + depth*2, "", SvPVX_const(prop),(IV)c,(IV)max);
+ Perl_re_exec_indentf( aTHX_ "%s can match %"IVdf" times out of %"IVdf"...\n",
+ depth, SvPVX_const(prop),(IV)c,(IV)max);
});
});
const struct regexp_engine* engine; \
REGEXP *mother_re; /* what re is this a lightweight copy of? */ \
HV *paren_names; /* Optional hash of paren names */ \
+ /*--------------------------------------------------------*/ \
/* Information about the match that the perl core uses to */ \
/* manage things */ \
U32 extflags; /* Flags used both externally and internally */ \
U32 intflags; /* Engine Specific Internal flags */ \
void *pprivate; /* Data private to the regex engine which */ \
/* created this object. */ \
+ /*--------------------------------------------------------*/ \
/* Data about the last/current match. These are modified */ \
/* during matching */ \
U32 lastparen; /* last open paren matched */ \
U32 lastcloseparen; /* last close paren matched */ \
/* Array of offsets for (@-) and (@+) */ \
regexp_paren_pair *offs; \
+ char **recurse_locinput; /* used to detect infinite recursion, XXX: move to internal */ \
+ /*--------------------------------------------------------*/ \
/* saved or original string so \digit works forever. */ \
char *subbeg; \
SV_SAVED_COPY /* If non-NULL, SV which is COW from original */\
SSize_t subcoffset; /* suboffset equiv, but in chars (for @-/@+) */ \
/* Information about the match that isn't often used */ \
SSize_t maxlen; /* mininum possible number of chars in string to match */\
+ /*--------------------------------------------------------*/ \
/* offset from wrapped to the start of precomp */ \
PERL_BITFIELD32 pre_prefix:4; \
/* original flags used to compile the pattern, may differ */ \
/* from extflags in various ways */ \
PERL_BITFIELD32 compflags:9; \
+ /*--------------------------------------------------------*/ \
CV *qr_anoncv /* the anon sub wrapped round qr/(?{..})/ */
typedef struct regexp {
/* structures for holding and saving the state maintained by regmatch() */
#ifndef MAX_RECURSE_EVAL_NOCHANGE_DEPTH
-#define MAX_RECURSE_EVAL_NOCHANGE_DEPTH 1000
+#define MAX_RECURSE_EVAL_NOCHANGE_DEPTH 10
#endif
typedef I32 CHECKPOINT;
struct {
/* this first element must match u.yes */
struct regmatch_state *prev_yes_state;
- struct regmatch_state *prev_eval;
struct regmatch_state *prev_curlyx;
+ struct regmatch_state *prev_eval;
REGEXP *prev_rex;
CHECKPOINT cp; /* remember current savestack indexes */
CHECKPOINT lastcp;
- U32 close_paren; /* which close bracket is our end */
+ U32 close_paren; /* which close bracket is our end (+1) */
regnode *B; /* the node following us */
+ char *prev_recurse_locinput;
} eval;
struct {
} u;
} regmatch_state;
+
+
/* how many regmatch_state structs to allocate as a single slab.
* We do it in 4K blocks for efficiency. The "3" is 2 for the next/prev
* pointers, plus 1 for any mythical malloc overhead. */
/* Regops and State definitions */
-#define REGNODE_MAX 93
-#define REGMATCH_STATE_MAX 133
+#define REGNODE_MAX 92
+#define REGMATCH_STATE_MAX 132
#define END 0 /* 0000 End of program. */
#define SUCCEED 1 /* 0x01 Return from a subroutine, basically. */
#define AHOCORASICK 74 /* 0x4a Aho Corasick stclass. flags==type */
#define AHOCORASICKC 75 /* 0x4b Same as AHOCORASICK, but with embedded charclass data */
#define GOSUB 76 /* 0x4c recurse to paren arg1 at (signed) ofs arg2 */
-#define GOSTART 77 /* 0x4d recurse to start of pattern */
-#define NGROUPP 78 /* 0x4e Whether the group matched. */
-#define INSUBP 79 /* 0x4f Whether we are in a specific recurse. */
-#define DEFINEP 80 /* 0x50 Never execute directly. */
-#define ENDLIKE 81 /* 0x51 Used only for the type field of verbs */
-#define OPFAIL 82 /* 0x52 Same as (?!), but with verb arg */
-#define ACCEPT 83 /* 0x53 Accepts the current matched string, with verbar */
-#define VERB 84 /* 0x54 Used only for the type field of verbs */
-#define PRUNE 85 /* 0x55 Pattern fails at this startpoint if no-backtracking through this */
-#define MARKPOINT 86 /* 0x56 Push the current location for rollback by cut. */
-#define SKIP 87 /* 0x57 On failure skip forward (to the mark) before retrying */
-#define COMMIT 88 /* 0x58 Pattern fails outright if backtracking through this */
-#define CUTGROUP 89 /* 0x59 On failure go to the next alternation in the group */
-#define KEEPS 90 /* 0x5a $& begins here. */
-#define LNBREAK 91 /* 0x5b generic newline pattern */
-#define OPTIMIZED 92 /* 0x5c Placeholder for dump. */
-#define PSEUDO 93 /* 0x5d Pseudo opcode for internal use. */
+#define NGROUPP 77 /* 0x4d Whether the group matched. */
+#define INSUBP 78 /* 0x4e Whether we are in a specific recurse. */
+#define DEFINEP 79 /* 0x4f Never execute directly. */
+#define ENDLIKE 80 /* 0x50 Used only for the type field of verbs */
+#define OPFAIL 81 /* 0x51 Same as (?!), but with verb arg */
+#define ACCEPT 82 /* 0x52 Accepts the current matched string, with verbar */
+#define VERB 83 /* 0x53 Used only for the type field of verbs */
+#define PRUNE 84 /* 0x54 Pattern fails at this startpoint if no-backtracking through this */
+#define MARKPOINT 85 /* 0x55 Push the current location for rollback by cut. */
+#define SKIP 86 /* 0x56 On failure skip forward (to the mark) before retrying */
+#define COMMIT 87 /* 0x57 Pattern fails outright if backtracking through this */
+#define CUTGROUP 88 /* 0x58 On failure go to the next alternation in the group */
+#define KEEPS 89 /* 0x59 $& begins here. */
+#define LNBREAK 90 /* 0x5a generic newline pattern */
+#define OPTIMIZED 91 /* 0x5b Placeholder for dump. */
+#define PSEUDO 92 /* 0x5c Pseudo opcode for internal use. */
/* ------------ States ------------- */
#define TRIE_next (REGNODE_MAX + 1) /* state for TRIE */
#define TRIE_next_fail (REGNODE_MAX + 2) /* state for TRIE */
TRIE, /* AHOCORASICK */
TRIE, /* AHOCORASICKC */
GOSUB, /* GOSUB */
- GOSTART, /* GOSTART */
NGROUPP, /* NGROUPP */
INSUBP, /* INSUBP */
DEFINEP, /* DEFINEP */
EXTRA_SIZE(struct regnode_1), /* AHOCORASICK */
EXTRA_SIZE(struct regnode_charclass), /* AHOCORASICKC */
EXTRA_SIZE(struct regnode_2L), /* GOSUB */
- 0, /* GOSTART */
EXTRA_SIZE(struct regnode_1), /* NGROUPP */
EXTRA_SIZE(struct regnode_1), /* INSUBP */
EXTRA_SIZE(struct regnode_1), /* DEFINEP */
0, /* AHOCORASICK */
0, /* AHOCORASICKC */
0, /* GOSUB */
- 0, /* GOSTART */
0, /* NGROUPP */
0, /* INSUBP */
0, /* DEFINEP */
"AHOCORASICK", /* 0x4a */
"AHOCORASICKC", /* 0x4b */
"GOSUB", /* 0x4c */
- "GOSTART", /* 0x4d */
- "NGROUPP", /* 0x4e */
- "INSUBP", /* 0x4f */
- "DEFINEP", /* 0x50 */
- "ENDLIKE", /* 0x51 */
- "OPFAIL", /* 0x52 */
- "ACCEPT", /* 0x53 */
- "VERB", /* 0x54 */
- "PRUNE", /* 0x55 */
- "MARKPOINT", /* 0x56 */
- "SKIP", /* 0x57 */
- "COMMIT", /* 0x58 */
- "CUTGROUP", /* 0x59 */
- "KEEPS", /* 0x5a */
- "LNBREAK", /* 0x5b */
- "OPTIMIZED", /* 0x5c */
- "PSEUDO", /* 0x5d */
+ "NGROUPP", /* 0x4d */
+ "INSUBP", /* 0x4e */
+ "DEFINEP", /* 0x4f */
+ "ENDLIKE", /* 0x50 */
+ "OPFAIL", /* 0x51 */
+ "ACCEPT", /* 0x52 */
+ "VERB", /* 0x53 */
+ "PRUNE", /* 0x54 */
+ "MARKPOINT", /* 0x55 */
+ "SKIP", /* 0x56 */
+ "COMMIT", /* 0x57 */
+ "CUTGROUP", /* 0x58 */
+ "KEEPS", /* 0x59 */
+ "LNBREAK", /* 0x5a */
+ "OPTIMIZED", /* 0x5b */
+ "PSEUDO", /* 0x5c */
/* ------------ States ------------- */
"TRIE_next", /* REGNODE_MAX +0x01 */
"TRIE_next_fail", /* REGNODE_MAX +0x02 */
"ANCH_MBOL", /* 0x00000400 - PREGf_ANCH_MBOL */
"ANCH_SBOL", /* 0x00000800 - PREGf_ANCH_SBOL */
"ANCH_GPOS", /* 0x00001000 - PREGf_ANCH_GPOS */
+ "RECURSE_SEEN", /* 0x00002000 - PREGf_RECURSE_SEEN */
};
#endif /* DOINIT */
#ifdef DEBUGGING
-# define REG_INTFLAGS_NAME_SIZE 12
+# define REG_INTFLAGS_NAME_SIZE 13
#endif
/* The following have no fixed length. U8 so we can do strchr() on it. */
Perl_runops_standard(pTHX)
{
OP *op = PL_op;
- OP_ENTRY_PROBE(OP_NAME(op));
+ PERL_DTRACE_PROBE_OP(op);
while ((PL_op = op = op->op_ppaddr(aTHX))) {
- OP_ENTRY_PROBE(OP_NAME(op));
+ PERL_DTRACE_PROBE_OP(op);
}
PERL_ASYNC_CHECK();
d_fpclassl='undef'
d_fpgetround='undef'
d_fpos64_t='undef'
+d_freelocale='undef'
d_frexpl='undef'
d_fs_data_s='undef'
d_fseeko='undef'
d_nan='undef'
d_ndbm_h_uses_prototypes='undef'
d_nearbyint='undef'
+d_newlocale='undef'
d_nextafter='undef'
d_nexttoward='undef'
d_nice='undef'
d_union_semun='undef'
d_unordered='undef'
d_unsetenv='undef'
+d_uselocale='undef'
d_usleep='define'
d_usleepproto='undef'
d_ustat='undef'
use warnings;
skip_all('no SysV semaphores on this platform') if !$Config{d_sem};
+skip_all('SysV semaphore structures not detected')
+ if !$Config{d_semctl_semid_ds} && !$Config{d_semctl_semun};
my @warnings;
{
my @data = grep length, split /(.{1,$write_c})/s, $str;
my $filename = tempfile();
- open my $fh, '>', $filename or die;
+ open my $fh, '>', $filename or die "open: > $filename: $!";
select $fh;
binmode $fh, ':crlf'
if defined $main::use_crlf && $main::use_crlf == 1;
die "Unrecognized write: '$how_w'";
}
close $fh or die "close: $!";
- open $fh, '<', $filename or die;
+ open $fh, '<', $filename or die "open: < $filename: $!";
binmode $fh, ':crlf'
if defined $main::use_crlf && $main::use_crlf == 1;
testread($fh, $str, $read_c, $how_r, $write_c, $how_w, "file$why");
EXPECT
Assuming NOT a POSIX class since no blanks are allowed in one in regex; marked by <-- HERE in m/(?[[:digit: ] <-- HERE )/ at - line 2.
syntax error in (?[...]) in regex m/(?[[:digit: ])/ at - line 2.
+########
+# NAME [perl #126141]
+# OPTION fatal
+eval {/$_/}, print "$_ ==> ", $@ || "OK!\n" for "]]]]]]]]][\\", "]]]]][\\"
+EXPECT
+]]]]]]]]][\ ==> Unmatched [ in regex; marked by <-- HERE in m/]]]]]]]]][\ <-- HERE / at - line 2.
+]]]]][\ ==> Unmatched [ in regex; marked by <-- HERE in m/]]]]][\ <-- HERE / at - line 2.
Subroutine main::f렏 redefined at - line 7.
########
# sv.c
-sprintf "%vd", new version v1.1_0;
-use warnings 'printf' ;
-sprintf "%vd", new version v1.1_0;
-no warnings 'printf' ;
-sprintf "%vd", new version v1.1_0;
-EXPECT
-vector argument not supported with alpha versions at - line 2.
-vector argument not supported with alpha versions at - line 4.
-########
-# sv.c
my $x = "a_c";
++$x;
use warnings "numeric";
Operation "uc" returns its argument for non-Unicode code point 0x80+ at - line \d+.
Code point 0x7F+ is not Unicode, may not be portable in print at - line \d+.
Use of code point 0x80+ is deprecated; the permissible max is 0x7F+ in print at - line \d+.
+########
+# NAME [perl #127262]
+BEGIN{
+ if (ord('A') == 193) {
+ print "SKIPPED\n# ebcdic platforms generates different Malformed UTF-8 warnings.";
+ exit 0;
+ }
+{};$^H=2**400}Â
+EXPECT
+Malformed UTF-8 character (unexpected non-continuation byte 0x0a, immediately after start byte 0xc2) at - line 6.
1.02_03 fail pass pass underscore
v1.2_3 fail pass pass underscore
v1.02_03 fail pass pass underscore
-v1.2_3_4 fail fail fail underscore
-v1.2_3.4 fail fail fail underscore
-1.2_3.4 fail fail fail underscore
0_ fail fail na underscore
1_ fail fail na underscore
1_. fail fail na underscore
>%vd< >[version->new("1.002")]< >1.2<
>%vd< >[version->new("1048576.5")]< >1048576.5<
>%vd< >[version->new("50")]< >50<
->[%vd]< >[version->new(v1.1_1)]< >[] ALPHA<
>%v.3d< >"\01\02\03"< >001.002.003<
>%0v3d< >"\01\02\03"< >001.002.003<
>%v.3d< >[version::qv("1.2.3")]< >001.002.003<
ExtUtils::MakeMaker cpan/ExtUtils-MakeMaker/t/lib/MakeMaker/Test/NoXS.pm 371cdff1b2375017907cfbc9c8f4a31f5ad10582
ExtUtils::MakeMaker cpan/ExtUtils-MakeMaker/t/prereq.t 53bda2c549fd13a6b6c13a070ca6bc79883081c0
ExtUtils::MakeMaker cpan/ExtUtils-MakeMaker/t/vstrings.t 90035a2bdbf45f15b9c3196d072d7cba7e662871
+IPC::SysV cpan/IPC-SysV/lib/IPC/Msg.pm 88865a2c7a06351cf10e08addd077bbdea02fb60
+IPC::SysV cpan/IPC-SysV/lib/IPC/Semaphore.pm 04f0d11b7d0babf8e41ccc917cccecc4a3ff9050
+IPC::SysV cpan/IPC-SysV/lib/IPC/SharedMem.pm 85dea09a5bb625fc1fdda433909633fda05ea831
+IPC::SysV cpan/IPC-SysV/lib/IPC/SysV.pm 9a0d1c3dcd67321ef1322f29102a1bc7eb91c61c
+IPC::SysV cpan/IPC-SysV/t/ipcsysv.t ee2c95e846ea201afe13c9ec53b09cef62c8ac68
Math::BigRat cpan/Math-BigRat/lib/Math/BigRat.pm 6eabc68e04f67694f6fe523e64eb013fc337ca5b
Pod::Perldoc cpan/Pod-Perldoc/lib/Pod/Perldoc.pm fe0bc906fb74b69cfd3fb289316ba669d770d465
-Scalar-List-Utils cpan/Scalar-List-Utils/lib/List/Util.pm 62d2a82a811b531a3fd25cb60c4c2ef943858892
-Scalar-List-Utils cpan/Scalar-List-Utils/lib/List/Util/XS.pm 08abbe1a707927cee53e85ba85d6bd35c1c2ae50
-Scalar-List-Utils cpan/Scalar-List-Utils/lib/Scalar/Util.pm 7f1e6eb11105623200ef9cdcb881545ccb769ded
-Scalar-List-Utils cpan/Scalar-List-Utils/lib/Sub/Util.pm d87811528ae3587f04e2f09894b8c88471754386
-Scalar-List-Utils cpan/Scalar-List-Utils/ListUtil.xs ed25abc419771d6f3f12323f1f0a372f043d51b2
-Socket cpan/Socket/Socket.pm bdc42a2bd5cb560ed1120a3e6f408ed7ece14dce
-Socket cpan/Socket/Socket.xs 6102315291684e56e360ff5e0dd237c9394c49b8
-Win32API::File cpan/Win32API-File/buffers.h 02d230ac9ac7091365128161a0ed671898baefae
-Win32API::File cpan/Win32API-File/cFile.h fca7e383e76979c3ac3adf12d11d1bcd2618e489
-Win32API::File cpan/Win32API-File/cFile.pc 992421eea7782a5957b64f66764f6ffb5093bee4
-Win32API::File cpan/Win32API-File/const2perl.h 521a12d359f5efb68cf8abe1977689b640bc8b7d
-Win32API::File cpan/Win32API-File/ExtUtils/Myconst2perl.pm ce52544f49ac880e20b6171fe38f6560ed845e97
-Win32API::File cpan/Win32API-File/Makefile.PL 605d0aee31aebe84a99408f9ab5f644db57c61c6
-Win32API::File cpan/Win32API-File/t/file.t 124e64aa77e755235eb297644a87fac5388d3d78
-Win32API::File cpan/Win32API-File/t/tie.t 712ea7edd0cc805ce1c0b8172c01b03dd19b583d
-Win32API::File cpan/Win32API-File/typemap 24bff088babeadac0873e8df390d1666d9d9db4a
+Scalar-List-Utils cpan/Scalar-List-Utils/lib/List/Util.pm 3b501b7332480b34929bc4df5d48581df3307267
+Scalar-List-Utils cpan/Scalar-List-Utils/lib/List/Util/XS.pm ebd169113d3df79d31ad5535dbd7a538a8c14fd2
+Scalar-List-Utils cpan/Scalar-List-Utils/lib/Scalar/Util.pm def601405bac7a4d6690b8c4207e0f05d65eb4ca
+Scalar-List-Utils cpan/Scalar-List-Utils/lib/Sub/Util.pm 1187d6cd9bccf1264bd53b3a65ea96fad7520068
+Scalar-List-Utils cpan/Scalar-List-Utils/ListUtil.xs 6128584ecb0ae69bb21b16b22daceeffc92df9d9
+Scalar-List-Utils cpan/Scalar-List-Utils/t/product.t 99bf424804f055b99ff2a18b7dcf25bb8b6d2463
+Socket cpan/Socket/Socket.pm 98e38176d745c38282907f391c077298f5a3d0ba
+Socket cpan/Socket/Socket.xs edd4fed212785f11c5c2095a75941dad27d586d9
autodie cpan/autodie/t/mkdir.t 9e70d2282a3cc7d76a78bf8144fccba20fb37dac
-version cpan/version/lib/version.pm d0923b895d57f1d669ae36fcf85c87b16db341d1
-version vutil.c 668f17ca43e2527645674d29ba772b86330d5663
+version cpan/version/lib/version.pm ff75e2076be10bd4c05133cd979fda0b38ca8653
+version vutil.c 6d7f036a394f25a3a5b4a4a1dafd2eba4ebc67e3
-# This file is the data file for porting/podcheck.t.
+# This file is the data file for t/porting/podcheck.t.
# There are three types of lines.
# Comment lines are white-space only or begin with a '#', like this one. Any
# changes you make to the comment lines will be lost when the file is
# known instances of that message there are in the pod. -1 means that the
# program can expect any number of this type of message.
_control87(3)
+accept(2)
+access(2)
Algorithm::C3
AnyEvent
Apache::MP3
Archive::Extract
Array::Base
+atan2(3)
Attribute::Constant
autobox
B::Generate
B::Utils
basename(1)
Benchmark::Perl::Formance
+bind(2)
+BSD::Resource
ByteLoader
bzip2(1)
Carp::Always
Carp::Clan
CGI
chcp(1)
+chmod(2)
+chown(2)
Class::Accessor
Class::C3
Class::ISA
Class::Tiny
Class::Tiny::Antlers
Classic::Perl
+clearerr(3)
Clone
+closedir(2)
+connect(2)
Coro
cpan2dist(1)
CPAN::Changes::Spec
cpanp(1)
CPANPLUS
+crypt(3)
Crypt::Random
+ctime(3)
curl(1)
Dancer
Data::Alias
DB_File(3)
DBI
DBIx::Profile
+dbm(3)
+dbm_open(3)
Devel::CallParser
Devel::Callsite
Devel::Cover
Devel::PPPort
Devel::SawAmpersand
Devel::Spy
+dirfd(3)
dirname(1)
+dup(2)
Encode::Detect
Encode::Locale
Eval::WithLexicals
+execvp(3)
Exporter::Easy
ExtUtils::Constant::ProxySubs
+fchdir(2)
+fchmod(2)
+fchown(2)
+fcntl(2)
+fdopen(3)
fetch(1)
+fgrep(1)
File::chdir
File::Copy::Recursive
File::Findgrep
File::MMagic
File::ShareDir
find(1)
+flock(2)
flock(3)
+fopen(3)
+fork(2)
+fread(3)
+fseek(3)
fsync(3c)
Function::Parameters
+futimes(2)
Future
gcc(1)
+gdbm(3)
Getopt::Std
+getpgrp(2)
getpriority(2)
+getpwnam(3)
+getsockopt(2)
+gettimeofday(2)
+grep(1)
Hook::LexWrap
HTML::StripScripts
HTTP::Lite
inetd(8)
invoker
IO::Socket::IP
+ioctl(2)
IPC::Run
+IPC::Shareable
IPC::Signal
kill(3)
langinfo(3)
Lingua::KO::Romanize::Hangul
Lingua::ZH::Romanize::Pinyin
List::Gather
+listen(2)
local::lib
+lockf(3)
Log::Message
Log::Message::Config
Log::Message::Handlers
Log::Message::Item
Log::Message::Simple
+lseek(2)
LWP::ConsoleLogger
Mail::Send
Mail::SpamAssassin
Moo
Moose
MRO::Compat
+msgctl(2)
+msgget(2)
+ndbm(3)
NgxQueue
nl_langinfo(3)
Number::Format
Pod::PXML
poll(2)
prctl(2)
+printenv(1)
printf(3)
provide
pstruct
ptargrep(1)
pwd_mkdb(8)
RDF::Trine
+read(2)
Readonly
+recvfrom(2)
recvmsg(3)
+rename(2)
Role::Tiny
s2p
Scalar::Readonly
+sdbm(3)
+select(2)
+semctl(2)
+semget(2)
Semi::Semicolons
+semop(2)
sendmail(1)
+sendmsg(2)
sendmsg(3)
+sendto(2)
+setitimer(2)
setlocale(3)
+setpgid(2)
+setpgrp(2)
+setpriority(2)
sha1sum(1)
+shadow(3)
Shell
Shell::Command
sock_init(3)
Switch
tar(1)
Template::Declare
+Term::ReadKey
Term::UI
Term::UI::History
Test::Harness::TAP
Text::Template
Text::Unidecode
Time::Object
+Time::TAI64
Tk
Tk::Pod
+touch(1)
tr(1)
tty(1)
+umask(2)
Unicode::CaseFold
Unicode::Casing
Unicode::GCString
Unicode::Tussle
Unicode::Unihan
unzip(1)
+utime(2)
Version::Requirements
wait(2)
+wait4(2)
+waitpid(2)
waitpid(3)
Want
wget(1)
Win32::Locale
+write(2)
XML::LibXML
YAML
YAML::Syck
YAML::Tiny
dist/data-dumper/dumper.pm ? Should you be using L<...> instead of 1
-dist/module-corelist/lib/module/corelist.pod Verbatim line length including indents exceeds 79 by 4
-dist/module-corelist/lib/module/corelist/utils.pm Verbatim line length including indents exceeds 79 by 2
-dist/pathtools/lib/file/spec/amigaos.pm Verbatim line length including indents exceeds 79 by 1
-dist/selfloader/lib/selfloader.pm Verbatim line length including indents exceeds 79 by 13
-dist/storable/storable.pm Verbatim line length including indents exceeds 79 by 4
-dist/thread-queue/lib/thread/queue.pm Verbatim line length including indents exceeds 79 by 6
-dist/threads/lib/threads.pm Verbatim line length including indents exceeds 79 by 3
-dist/tie-file/lib/tie/file.pm Verbatim line length including indents exceeds 79 by 3
-dist/time-hires/hires.pm Apparent broken link 2
-dist/time-hires/hires.pm Verbatim line length including indents exceeds 79 by 1
-ext/amiga-arexx/arexx.pm Verbatim line length including indents exceeds 79 by 2
-ext/amiga-exec/exec.pm Verbatim line length including indents exceeds 79 by 2
+ext/amiga-exec/exec.pm Verbatim line length including indents exceeds 79 by 1
ext/devel-peek/peek.pm ? Should you be using L<...> instead of 2
ext/dynaloader/dynaloader.pm Verbatim line length including indents exceeds 79 by 1
-ext/file-find/lib/file/find.pm Verbatim line length including indents exceeds 79 by 1
-ext/file-glob/glob.pm Verbatim line length including indents exceeds 79 by 6
ext/hash-util/lib/hash/util.pm Verbatim line length including indents exceeds 79 by 2
ext/pod-html/testdir/perlpodspec-copy.pod Verbatim line length including indents exceeds 79 by 2
ext/pod-html/testdir/perlvar-copy.pod ? Should you be using L<...> instead of 3
pod/perl.pod Verbatim line length including indents exceeds 79 by 8
pod/perlandroid.pod Verbatim line length including indents exceeds 79 by 3
pod/perlbook.pod Verbatim line length including indents exceeds 79 by 1
-pod/perlcall.pod Verbatim line length including indents exceeds 79 by 2
pod/perlce.pod Verbatim line length including indents exceeds 79 by 3
-pod/perlcygwin.pod Verbatim line length including indents exceeds 79 by 20
pod/perldebguts.pod Verbatim line length including indents exceeds 79 by 27
pod/perldebtut.pod Verbatim line length including indents exceeds 79 by 3
pod/perldtrace.pod Verbatim line length including indents exceeds 79 by 7
pod/perlgit.pod Verbatim line length including indents exceeds 79 by 1
pod/perlguts.pod ? Should you be using L<...> instead of 1
-pod/perlguts.pod Verbatim line length including indents exceeds 79 by 1
pod/perlhack.pod ? Should you be using L<...> instead of 1
pod/perlhist.pod Verbatim line length including indents exceeds 79 by 1
-pod/perlhpux.pod Verbatim line length including indents exceeds 79 by 7
-pod/perlhurd.pod Verbatim line length including indents exceeds 79 by 2
+pod/perlhpux.pod Verbatim line length including indents exceeds 79 by 1
pod/perlinterp.pod ? Should you be using L<...> instead of 1
-pod/perliol.pod Verbatim line length including indents exceeds 79 by 8
-pod/perlipc.pod Verbatim line length including indents exceeds 79 by 19
-pod/perlirix.pod Verbatim line length including indents exceeds 79 by 4
-pod/perllol.pod Verbatim line length including indents exceeds 79 by 4
-pod/perlmacosx.pod Verbatim line length including indents exceeds 79 by 4
+pod/perlirix.pod Verbatim line length including indents exceeds 79 by 1
+pod/perlmacosx.pod Verbatim line length including indents exceeds 79 by 3
pod/perlmodlib.pod Verbatim line length including indents exceeds 79 by 3
-pod/perlmodstyle.pod Verbatim line length including indents exceeds 79 by 1
pod/perlmroapi.pod ? Should you be using L<...> instead of 1
-pod/perlnetware.pod Verbatim line length including indents exceeds 79 by 4
-pod/perlnewmod.pod Verbatim line length including indents exceeds 79 by 1
pod/perlos2.pod ? Should you be using L<...> instead of 2
-pod/perlos2.pod Verbatim line length including indents exceeds 79 by 21
-pod/perlos390.pod Verbatim line length including indents exceeds 79 by 11
-pod/perlperf.pod Verbatim line length including indents exceeds 79 by 122
+pod/perlos2.pod Verbatim line length including indents exceeds 79 by 5
+pod/perlos390.pod Verbatim line length including indents exceeds 79 by 2
+pod/perlperf.pod Verbatim line length including indents exceeds 79 by 114
pod/perlport.pod ? Should you be using L<...> instead of 1
pod/perlrun.pod Verbatim line length including indents exceeds 79 by 3
-pod/perlsolaris.pod Verbatim line length including indents exceeds 79 by 14
-pod/perlsymbian.pod Verbatim line length including indents exceeds 79 by 20
-pod/perltie.pod Verbatim line length including indents exceeds 79 by 13
-pod/perltru64.pod Verbatim line length including indents exceeds 79 by 5
+pod/perlsolaris.pod Verbatim line length including indents exceeds 79 by 13
+pod/perltie.pod Verbatim line length including indents exceeds 79 by 3
+pod/perltru64.pod Verbatim line length including indents exceeds 79 by 1
pod/perlwin32.pod Verbatim line length including indents exceeds 79 by 7
porting/epigraphs.pod Verbatim line length including indents exceeds 79 by 16
-porting/expand-macro.pl Verbatim line length including indents exceeds 79 by 2
porting/release_managers_guide.pod Verbatim line length including indents exceeds 79 by 1
-porting/todo.pod Verbatim line length including indents exceeds 79 by 1
-utils/c2ph Verbatim line length including indents exceeds 79 by 44
utils/encguess There is no NAME 1
lib/benchmark.pm Verbatim line length including indents exceeds 79 by 2
lib/config.pod ? Should you be using L<...> instead of -1
-lib/extutils/embed.pm Verbatim line length including indents exceeds 79 by 2
lib/perl5db.pl ? Should you be using L<...> instead of 1
if ($_[0] && ($page = $_[0][1]{'-page'})) {
my $node = $_[0][1]{'-node'};
- # If the hyperlink is to an interior node of another page, save it
- # so that we can see if we need to parse normally skipped files.
- $has_referred_to_node{$page} = 1 if $node;
+ if ($node) {
+ $_[0][1]{'-node'} = $node = do {
+ my $expand_seq = sub {
+ my (undef, $seq) = @_;
+ my $arg = join '', $seq->parse_tree->children;
+ if ($seq->name eq 'E') {
+ $arg =
+ $arg eq 'sol' ? '/' :
+ $arg eq 'verbar' ? '|' :
+ $arg eq 'lt' ? '<' :
+ $arg eq 'gt' ? '>' :
+ die "Not implemented: E<$arg>";
+ }
+ return $arg;
+ };
+ my $ptree = $self->parse_text({ -expand_seq => $expand_seq }, $node, $_[0][0]);
+ join '', $ptree->children
+ };
+
+ # If the hyperlink is to an interior node of another page, save it
+ # so that we can see if we need to parse normally skipped files.
+ $has_referred_to_node{$page} = 1;
+ }
# Ignore certain placeholder links in perldelta. Check if the
# link is page-level, and also check if to a node within the page
# could be a link target. Count how many there are of the same name.
foreach my $node ($checker->linkable_nodes) {
next FILE if ! $node; # Can be empty is like '=item *'
- if (exists $nodes{$name}{$node}) {
- $nodes{$name}{$node}++;
- }
- else {
- $nodes{$name}{$node} = 1;
- }
+ $nodes{$name}{$node}++;
# Experiments have shown that cpan search can figure out the
# target of a link even if the exact wording is incorrect, as long
# If link is only to the page-level, already have it
next if ! $node;
- # Transform pod language to what we are expecting
- $node =~ s,E<sol>,/,g;
- $node =~ s/E<verbar>/|/g;
- $node =~ s/E<lt>/</g;
- $node =~ s/E<gt>/>/g;
-
# If link is to a node that exists in the file, is ok
if ($nodes{$linked_to_page}{$node}) {
skip_all_without_unicode_tables();
}
-plan tests => 776; # Update this when adding/deleting tests.
+plan tests => 789; # Update this when adding/deleting tests.
run_tests() unless caller;
fresh_perl_is($code, "", {},
"perl [#126406] panic");
}
+ {
+ my $bug="[perl #126182]"; # test for infinite pattern recursion
+ for my $tuple (
+ [ 'q(a)=~/(.(?2))((?<=(?=(?1)).))/', "died", "look ahead left recursion fails fast" ],
+ [ 'q(aa)=~/(?R)a/', "died", "left-recursion fails fast", ],
+ [ 'q(bbaa)=~/(?&x)(?(DEFINE)(?<x>(?&y)*a)(?<y>(?&x)*b))/',
+ "died", "inter-cyclic optional left recursion dies" ],
+ [ 'q(abc) =~ /a((?1)?)c/', "died", "optional left recursion dies" ],
+ [ 'q(abc) =~ /a((?1)??)c/', "died", "min mod left recursion dies" ],
+ [ 'q(abc) =~ /a((?1)*)c/', "died", "* left recursion dies" ],
+ [ 'q(abc) =~ /a((?1)+)c/', "died", "+ left recursion dies" ],
+ [ 'q(abc) =~ /a((?1){0,3})c/', "died", "{0,3} left recursion fails fast" ],
+
+ [ 'q(aaabbb)=~/a(?R)?b/', "matched", "optional self recursion works" ],
+ [ '"((5maa-maa)(maa-3maa))" =~ /(\\\\((?:[^()]++|(?0))*+\\\\))/', "matched",
+ "recursion and possessive captures", "((5maa-maa)(maa-3maa))"],
+ [ '"((5maa-maa)(maa-3maa))" =~ /(\\\\((?:[^()]++|(?1))*+\\\\))/', "matched",
+ "recursion and possessive captures", "((5maa-maa)(maa-3maa))"],
+ [ '"((5maa-maa)(maa-3maa))" =~ /(\\\\((?:[^()]+|(?0))*\\\\))/', "matched",
+ "recursion and possessive captures", "((5maa-maa)(maa-3maa))"],
+ [ '"((5maa-maa)(maa-3maa))" =~ /(\\\\((?:[^()]+|(?1))*\\\\))/', "matched",
+ "recursion and possessive captures", "((5maa-maa)(maa-3maa))"],
+ ) {
+ my ($expr, $expect, $test_name, $cap1)= @$tuple;
+ # avoid quotes in this code!
+ my $code='
+ BEGIN{require q(test.pl);}
+ watchdog(3);
+ my $status= eval(q{ !(' . $expr . ') ? q(failed) : ' .
+ ($cap1 ? '($1 ne q['.$cap1.']) ? qq(badmatch:$1) : ' : '') .
+ ' q(matched) })
+ || ( ( $@ =~ /Infinite recursion/ ) ? qq(died) : q(strange-death) );
+ print $status;
+ ';
+ fresh_perl_is($code, $expect, {}, "$bug - $test_name" );
+ }
+ }
} # End of sub run_tests
1;
"buffer overflow in TRIE_STORE_REVCHAR");
}
+ {
+ fresh_perl_like('use warnings; s\00(?(?!00000000000000000000000000·000000)\500000000\00000000000000000000000000000000000000000000000000000·00000000000000000000000000000000\00',
+ qr/Switch \(\?\(condition\)\.\.\. not terminated/,
+ {},
+ 'No segfault [perl #126886]');
+ }
+
# !!! NOTE that tests that aren't at all likely to crash perl should go
# a ways above, above these last ones. There's a comment there that, like
# this comment, contains the word 'NOTE'
(?a-x - c - Sequence (?... not terminated
.{1}?? - c - Nested quantifiers
.{1}?+ - c - Nested quantifiers
+(?:.||)(?|)000000000@ 000000000@ y $& 000000000@ # [perl #126405]
# Keep these lines at the end of the file
# vim: softtabstop=0 noexpandtab
my @death =
(
'/[[=foo=]]/' => 'POSIX syntax [= =] is reserved for future extensions {#} m/[[=foo=]{#}]/',
- '/[[=a]=]]/' => 'POSIX syntax [= =] is reserved for future extensions {#} m/[[=a]=]{#}]/',
- '/[[.a].]]/' => 'POSIX syntax [. .] is reserved for future extensions {#} m/[[.a].]{#}]/',
'/(?<= .*)/' => 'Variable length lookbehind not implemented in regex m/(?<= .*)/',
'/(?i-l:foo)/' => 'Regexp modifier "l" may not appear after the "-" {#} m/(?i-l{#}:foo)/',
'/((x)/' => 'Unmatched ( {#} m/({#}(x)/',
+ '/{(}/' => 'Unmatched ( {#} m/{({#}}/', # [perl #127599]
"/x{$inf_p1}/" => "Quantifier in {,} bigger than $inf_m1 {#} m/x{{#}$inf_p1}/",
'/(?[[[::]]])/' => "Syntax error in (?[...]) in regex m/(?[[[::]]])/",
'/(?[[[:w:]]])/' => "Syntax error in (?[...]) in regex m/(?[[[:w:]]])/",
'/(?[[:w:]])/' => "",
+ '/[][[:alpha:]]' => "", # [perl #127581]
+ '/([.].*)[.]/' => "", # [perl #127582]
+ '/[.].*[.]/' => "", # [perl #127604]
'/(?[a])/' => 'Unexpected character {#} m/(?[a{#}])/',
'/(?[ + \t ])/' => 'Unexpected binary operator \'+\' with no preceding operand {#} m/(?[ +{#} \t ])/',
'/(?[ \cK - ( + \t ) ])/' => 'Unexpected binary operator \'+\' with no preceding operand {#} m/(?[ \cK - ( +{#} \t ) ])/',
'/((?# This is a comment in the middle of a token)?:foo)/' => 'In \'(?...)\', the \'(\' and \'?\' must be adjacent {#} m/((?# This is a comment in the middle of a token)?{#}:foo)/',
'/((?# This is a comment in the middle of a token)*FAIL)/' => 'In \'(*VERB...)\', the \'(\' and \'*\' must be adjacent {#} m/((?# This is a comment in the middle of a token)*{#}FAIL)/',
'/(?[\ &!])/' => 'Incomplete expression within \'(?[ ])\' {#} m/(?[\ &!{#}])/', # [perl #126180]
+ '/(?[\ +!])/' => 'Incomplete expression within \'(?[ ])\' {#} m/(?[\ +!{#}])/', # [perl #126180]
+ '/(?[\ -!])/' => 'Incomplete expression within \'(?[ ])\' {#} m/(?[\ -!{#}])/', # [perl #126180]
+ '/(?[\ ^!])/' => 'Incomplete expression within \'(?[ ])\' {#} m/(?[\ ^!{#}])/', # [perl #126180]
+ '/(?[\ |!])/' => 'Incomplete expression within \'(?[ ])\' {#} m/(?[\ |!{#}])/', # [perl #126180]
'/(?[()-!])/' => 'Incomplete expression within \'(?[ ])\' {#} m/(?[()-!{#}])/', # [perl #126204]
'/(?[!()])/' => 'Incomplete expression within \'(?[ ])\' {#} m/(?[!(){#}])/', # [perl #126404]
);
# These need the character 'ネ' as a marker for mark_as_utf8()
my @death_utf8 = mark_as_utf8(
- '/ネ[[=ネ=]]ネ/' => 'POSIX syntax [= =] is reserved for future extensions {#} m/ネ[[=ネ=]{#}]ネ/',
'/ネ(?<= .*)/' => 'Variable length lookbehind not implemented in regex m/ネ(?<= .*)/',
'/(?<= ネ{1000})/' => 'Lookbehind longer than 255 not implemented in regex m/(?<= ネ{1000})/',
'/ネ\o{ネ/' => 'Missing right brace on \o{ {#} m/ネ\o{{#}ネ/',
'/ネ[[:ネ:]]ネ/' => "",
- '/ネ[[=ネ=]]ネ/' => 'POSIX syntax [= =] is reserved for future extensions {#} m/ネ[[=ネ=]{#}]ネ/',
-
- '/ネ[[.ネ.]]ネ/' => 'POSIX syntax [. .] is reserved for future extensions {#} m/ネ[[.ネ.]{#}]ネ/',
-
'/[ネ-a]ネ/' => 'Invalid [] range "ネ-a" {#} m/[ネ-a{#}]ネ/',
'/ネ\p{}ネ/' => 'Empty \p{} {#} m/ネ\p{{#}}ネ/',
'/[:alpha:]\x{100}/' => 'POSIX syntax [: :] belongs inside character classes {#} m/[:alpha:]{#}\x{100}/',
'/[:zog:]\x{100}/' => 'POSIX syntax [: :] belongs inside character classes (but this one isn\'t fully valid) {#} m/[:zog:]{#}\x{100}/',
'/[.zog.]\x{100}/' => 'POSIX syntax [. .] belongs inside character classes (but this one isn\'t implemented) {#} m/[.zog.]{#}\x{100}/',
- '/[.z#g.]\x{100}/x' => "", # Runs into a comment
- '/[.z\#g.]\x{100}/x' => 'POSIX syntax [. .] belongs inside character classes (but this one isn\'t implemented) {#} m/[.z\#g.]{#}\x{100}/',
'/[a-b]/' => "",
'/(?c)\x{100}/' => 'Useless (?c) - use /gc modifier {#} m/(?c{#})\x{100}/',
'/(?-c)\x{100}/' => 'Useless (?-c) - don\'t use /gc modifier {#} m/(?-c{#})\x{100}/',
my @USER_CASELESS_PROPERTIES = (
#
# User defined properties which differ depending on /i. Second entry is
- # false regularly, true under /i
+ # false normally, true under /i
#
'IsMyUpper' => ["M", "!m" ],
);
$count += 4 * @ILLEGAL_PROPERTIES;
$count += 4 * grep {length $_ == 1} @ILLEGAL_PROPERTIES;
$count += 8 * @USER_CASELESS_PROPERTIES;
+$count += 1; # Test for pkg:IsMyLower
plan(tests => $count);
}
print "# User-defined properties with /i differences\n";
- foreach my $class (shift @USER_CASELESS_PROPERTIES) {
+ while (my $class = shift @USER_CASELESS_PROPERTIES) {
my $chars_ref = shift @USER_CASELESS_PROPERTIES;
my @in = grep {!/^!./} @$chars_ref;
my @out = map {s/^!(?=.)//; $_} grep { /^!./} @$chars_ref;
. "\n&utf8::ASCII";
}
+{ # This has to be done here and not like the others, because we have to
+ # make sure that the property is not known until after the regex is
+ # compiled. It was previously getting confused about the pkg and /i
+ # combination
+
+ my $mylower = qr/\p{pkg::IsMyLower}/i;
+
+ sub pkg::IsMyLower {
+ my $caseless = shift;
+ return "+utf8::"
+ . (($caseless)
+ ? 'Alphabetic'
+ : 'Lowercase')
+ . "\n&utf8::ASCII";
+ }
+
+ like("A", $mylower, "Not available until runtime user-defined property with pkg:: and /i works");
+
+}
+
# Verify that can use user-defined properties inside another one
sub IsSyriac1KanaMark {<<'--'}
+main::IsSyriac1
require './test.pl';
set_up_inc('../lib');
require Config; import Config;
+ require constant;
+ constant->import(constcow => *Config::{NAME});
require './charset_tools.pl';
require './loc_tools.pl';
}
-plan( tests => 269 );
+plan( tests => 270 );
$_ = 'david';
$a = s/david/rules/r;
$a = "david" =~ s/david/rules/r;
ok( $a eq 'rules', 's///r with constant' );
+#[perl #127635] failed with -DPERL_NO_COW perl build (George smoker uses flag)
+#Modification of a read-only value attempted at ../t/re/subst.t line 23.
+$a = constcow =~ s/Config/David/r;
+ok( $a eq 'David::', 's///r with COW constant' );
+
$a = "david" =~ s/david/"is"."great"/er;
ok( $a eq 'isgreat', 's///er' );
isnt(setlocale(LC_ALL), "C", "retrieving current non-C LC_ALL doesn't give 'C'");
}
-fresh_perl_is("for (qw(@locales)) {\n" . <<'EOF',
+# Skip this locale on these cywgwin versions as the returned radix character
+# length is wrong
+my @test_numeric_locales = ($^O ne 'cygwin' || version->new(($Config{'osvers'} =~ /^(\d+(?:\.\d+)+)/)[0]) gt v2.4.1)
+ ? @locales
+ : grep { $_ !~ m/ps_AF/i } @locales;
+
+fresh_perl_is("for (qw(@test_numeric_locales)) {\n" . <<'EOF',
use POSIX qw(locale_h);
use locale;
setlocale(LC_NUMERIC, "$_") or next;
retry:
switch (*s) {
default:
- if (UTF ? isIDFIRST_utf8((U8*)s) : isALNUMC(*s))
+ if (UTF) {
+ if (! isUTF8_CHAR((U8 *) s, (U8 *) PL_bufend)) {
+ ENTER;
+ SAVESPTR(PL_warnhook);
+ PL_warnhook = PERL_WARNHOOK_FATAL;
+ utf8n_to_uvchr((U8*)s, PL_bufend-s, NULL, 0);
+ LEAVE;
+ }
+ if (isIDFIRST_utf8((U8*)s)) {
+ goto keylookup;
+ }
+ }
+ else if (isALNUMC(*s)) {
goto keylookup;
- {
+ }
+ {
SV *dsv = newSVpvs_flags("", SVs_TEMP);
const char *c = UTF ? sv_uni_display(dsv, newSVpvn_flags(s,
UTF8SKIP(s),
else
/* skip plain q word */
while (t < PL_bufend && isWORDCHAR_lazy_if(t,UTF))
- t += UTF8SKIP(t);
+ t += UTF ? UTF8SKIP(t) : 1;
}
else if (isWORDCHAR_lazy_if(t,UTF)) {
- t += UTF8SKIP(t);
+ t += UTF ? UTF8SKIP(t) : 1;
while (t < PL_bufend && isWORDCHAR_lazy_if(t,UTF))
- t += UTF8SKIP(t);
+ t += UTF ? UTF8SKIP(t) : 1;
}
while (t < PL_bufend && isSPACE(*t))
t++;
*/
/*#define HAS_NEARBYINT / **/
+/* HAS_NEWLOCALE:
+ * This symbol, if defined, indicates that the newlocale routine is
+ * available to return a new locale object or modify an existing
+ * locale object.
+ */
+/* HAS_FREELOCALE:
+ * This symbol, if defined, indicates that the freelocale routine is
+ * available to deallocates the resources associated with a locale object.
+ */
+/* HAS_USELOCALE:
+ * This symbol, if defined, indicates that the uselocale routine is
+ * available to set the current locale for the calling thread.
+ */
+/*#define HAS_NEWLOCALE / **/
+/*#define HAS_FREELOCALE / **/
+/*#define HAS_USELOCALE / **/
+
/* HAS_NEXTAFTER:
* This symbol, if defined, indicates that the nextafter routine is
* available to return the next machine representable double from
#endif
/* Generated from:
- * 0459b706f70bb18d7481b187553e0719406d2c7d5c354c3a309332dfd8e66197 config_h.SH
- * 9382cd0e3b112993f14cfefe78ebe24b4b09df9d9dd199226ca7ba5e6b90f21a uconfig.sh
+ * 01a33ec4d20289fa524203757339606daef1a014ff6b693d38234495023ac9e7 config_h.SH
+ * d2f05caf5dc56031d3338c8f42e9e317ae1e53faa7b51285d0d6ebc343f8a333 uconfig.sh
* ex: set ro: */
d_fpclassl='undef'
d_fpgetround='undef'
d_fpos64_t='undef'
+d_freelocale='undef'
d_frexpl='undef'
d_fs_data_s='undef'
d_fseeko='undef'
d_nan='undef'
d_ndbm_h_uses_prototypes='undef'
d_nearbyint='undef'
+d_newlocale='undef'
d_nextafter='undef'
d_nexttoward='undef'
d_nice='undef'
d_union_semun='undef'
d_unordered='undef'
d_unsetenv='undef'
+d_uselocale='undef'
d_usleep='undef'
d_usleepproto='undef'
d_ustat='undef'
d_fpclassl='undef'
d_fpgetround='undef'
d_fpos64_t='undef'
+d_freelocale='undef'
d_frexpl='undef'
d_fs_data_s='undef'
d_fseeko='undef'
d_nan='undef'
d_ndbm_h_uses_prototypes='undef'
d_nearbyint='undef'
+d_newlocale='undef'
d_nextafter='undef'
d_nexttoward='undef'
d_nice='undef'
d_union_semun='undef'
d_unordered='undef'
d_unsetenv='undef'
+d_uselocale='undef'
d_usleep='undef'
d_usleepproto='undef'
d_ustat='undef'
CopHINTS_set(PL_curcop, PL_hints);
}
if (!SvROK(retval) || SvTYPE(SvRV(retval)) != SVt_PVHV) {
- if (SvPOK(retval))
+ if (SvPOK(retval)) {
/* If caller wants to handle missing properties, let them */
if (flags_p && *flags_p & _CORE_SWASH_INIT_RETURN_IF_UNDEF) {
"Can't find Unicode property definition \"%"SVf"\"",
SVfARG(retval));
NOT_REACHED; /* NOTREACHED */
+ }
}
} /* End of calling the module to find the swash */
while ((from_list = (AV *) hv_iternextsv(specials_inverse,
&char_to, &to_len)))
{
- if (av_tindex(from_list) > 0) {
+ if (av_tindex_nomg(from_list) > 0) {
SSize_t i;
/* We iterate over all combinations of i,j to place each code
* point on each list */
- for (i = 0; i <= av_tindex(from_list); i++) {
+ for (i = 0; i <= av_tindex_nomg(from_list); i++) {
SSize_t j;
AV* i_list = newAV();
SV** entryp = av_fetch(from_list, i, FALSE);
}
/* For DEBUG_U: UV u = valid_utf8_to_uvchr((U8*) SvPVX(*entryp), 0);*/
- for (j = 0; j <= av_tindex(from_list); j++) {
+ for (j = 0; j <= av_tindex_nomg(from_list); j++) {
entryp = av_fetch(from_list, j, FALSE);
if (entryp == NULL) {
Perl_croak(aTHX_ "panic: av_fetch() unexpectedly failed");
/* Look through list to see if this inverse mapping already is
* listed, or if there is a mapping to itself already */
- for (i = 0; i <= av_tindex(list); i++) {
+ for (i = 0; i <= av_tindex_nomg(list); i++) {
SV** entryp = av_fetch(list, i, FALSE);
SV* entry;
UV uv;
return strstr((char*)big, (char*)little);
}
-/* same as instr but allow embedded nulls. The end pointers point to 1 beyond
- * the final character desired to be checked */
+/*
+=head1 Miscellaneous Functions
+
+=for apidoc Am|char *|ninstr|char * big|char * bigend|char * little|char * little_end
+
+Find the first (leftmost) occurrence of a sequence of bytes within another
+sequence. This is the Perl version of C<strstr()>, extended to handle
+arbitrary sequences, potentially containing embedded C<NUL> characters (C<NUL>
+is what the initial C<n> in the function name stands for; some systems have an
+equivalent, C<memmem()>, but with a somewhat different API).
+
+Another way of thinking about this function is finding a needle in a haystack.
+C<big> points to the first byte in the haystack. C<big_end> points to one byte
+beyond the final byte in the haystack. C<little> points to the first byte in
+the needle. C<little_end> points to one byte beyond the final byte in the
+needle. All the parameters must be non-C<NULL>.
+
+The function returns C<NULL> if there is no occurrence of C<little> within
+C<big>. If C<little> is the empty string, C<big> is returned.
+
+Because this function operates at the byte level, and because of the inherent
+characteristics of UTF-8 (or UTF-EBCDIC), it will work properly if both the
+needle and the haystack are strings with the same UTF-8ness, but not if the
+UTF-8ness differs.
+
+=cut
+
+*/
char *
Perl_ninstr(const char *big, const char *bigend, const char *little, const char *lend)
return NULL;
}
-/* reverse of the above--find last substring */
+/*
+=head1 Miscellaneous Functions
+
+=for apidoc Am|char *|rninstr|char * big|char * bigend|char * little|char * little_end
+
+Like C<L</ninstr>>, but instead finds the final (rightmost) occurrence of a
+sequence of bytes within another sequence, returning C<NULL> if there is no
+such occurrence.
+
+=cut
+
+*/
char *
Perl_rninstr(const char *big, const char *bigend, const char *little, const char *lend)
}
#endif
-/* this is a drop-in replacement for bcopy() */
-#if (!defined(HAS_MEMCPY) && !defined(HAS_BCOPY)) || (!defined(HAS_MEMMOVE) && !defined(HAS_SAFE_MEMCPY) && !defined(HAS_SAFE_BCOPY))
-char *
-Perl_my_bcopy(const char *from, char *to, I32 len)
+/* this is a drop-in replacement for bcopy(), except for the return
+ * value, which we need to be able to emulate memcpy() */
+#if !defined(HAS_MEMCPY) || (!defined(HAS_MEMMOVE) && !defined(HAS_SAFE_MEMCPY))
+void *
+Perl_my_bcopy(const void *vfrom, void *vto, size_t len)
{
- char * const retval = to;
+#if defined(HAS_BCOPY) && defined(HAS_SAFE_BCOPY)
+ bcopy(vfrom, vto, len);
+#else
+ const unsigned char *from = (const unsigned char *)vfrom;
+ unsigned char *to = (unsigned char *)vto;
PERL_ARGS_ASSERT_MY_BCOPY;
- assert(len >= 0);
-
if (from - to >= 0) {
while (len--)
*to++ = *from++;
while (len--)
*(--to) = *(--from);
}
- return retval;
+#endif
+
+ return vto;
}
#endif
/* this is a drop-in replacement for memset() */
#ifndef HAS_MEMSET
void *
-Perl_my_memset(char *loc, I32 ch, I32 len)
+Perl_my_memset(void *vloc, int ch, size_t len)
{
- char * const retval = loc;
+ unsigned char *loc = (unsigned char *)vloc;
PERL_ARGS_ASSERT_MY_MEMSET;
- assert(len >= 0);
-
while (len--)
*loc++ = ch;
- return retval;
+ return vloc;
}
#endif
/* this is a drop-in replacement for bzero() */
#if !defined(HAS_BZERO) && !defined(HAS_MEMSET)
-char *
-Perl_my_bzero(char *loc, I32 len)
+void *
+Perl_my_bzero(void *vloc, size_t len)
{
- char * const retval = loc;
+ unsigned char *loc = (unsigned char *)vloc;
PERL_ARGS_ASSERT_MY_BZERO;
- assert(len >= 0);
-
while (len--)
*loc++ = 0;
- return retval;
+ return vloc;
}
#endif
/* this is a drop-in replacement for memcmp() */
#if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP)
-I32
-Perl_my_memcmp(const char *s1, const char *s2, I32 len)
+int
+Perl_my_memcmp(const void *vs1, const void *vs2, size_t len)
{
- const U8 *a = (const U8 *)s1;
- const U8 *b = (const U8 *)s2;
- I32 tmp;
+ const U8 *a = (const U8 *)vs1;
+ const U8 *b = (const U8 *)vs2;
+ int tmp;
PERL_ARGS_ASSERT_MY_MEMCMP;
- assert(len >= 0);
-
while (len--) {
if ((tmp = *a++ - *b++))
return tmp;
}
#endif
-#if defined(OS2) || defined(__amigaos4__)
-# if defined(__amigaos4__) && defined(pclose)
-# undef pclose
-# endif
+#if defined(OS2)
int pclose();
#ifdef HAS_FORK
int /* Cannot prototype with I32
#endif
+
+#ifdef USE_DTRACE
+
+/* log a sub call or return */
+
+void
+Perl_dtrace_probe_call(pTHX_ CV *cv, bool is_call)
+{
+ const char *func;
+ const char *file;
+ const char *stash;
+ const COP *start;
+ line_t line;
+
+ PERL_ARGS_ASSERT_DTRACE_PROBE_CALL;
+
+ if (CvNAMED(cv)) {
+ HEK *hek = CvNAME_HEK(cv);
+ func = HEK_KEY(hek);
+ }
+ else {
+ GV *gv = CvGV(cv);
+ func = GvENAME(gv);
+ }
+ start = (const COP *)CvSTART(cv);
+ file = CopFILE(start);
+ line = CopLINE(start);
+ stash = CopSTASHPV(start);
+
+ if (is_call) {
+ PERL_SUB_ENTRY(func, file, line, stash);
+ }
+ else {
+ PERL_SUB_RETURN(func, file, line, stash);
+ }
+}
+
+
+/* log a require file loading/loaded */
+
+void
+Perl_dtrace_probe_load(pTHX_ const char *name, bool is_loading)
+{
+ PERL_ARGS_ASSERT_DTRACE_PROBE_LOAD;
+
+ if (is_loading) {
+ PERL_LOADING_FILE(name);
+ }
+ else {
+ PERL_LOADED_FILE(name);
+ }
+}
+
+
+/* log an op execution */
+
+void
+Perl_dtrace_probe_op(pTHX_ const OP *op)
+{
+ PERL_ARGS_ASSERT_DTRACE_PROBE_OP;
+
+ PERL_OP_ENTRY(OP_NAME(op));
+}
+
+
+/* log a compile/run phase change */
+
+void
+Perl_dtrace_probe_phase(pTHX_ enum perl_phase phase)
+{
+ const char *ph_old = PL_phase_names[PL_phase];
+ const char *ph_new = PL_phase_names[phase];
+
+ PERL_PHASE_CHANGE(ph_new, ph_old);
+}
+
+#endif
+
/*
* ex: set ts=8 sts=4 sw=4 et:
*/
# define HS_CXT cv
#endif
+#define instr(haystack, needle) strstr(haystack, needle)
+
/*
* ex: set ts=8 sts=4 sw=4 et:
*/
Options:
-w wide; short for: type_width=45 member_width=35 offset_width=8
- -x hex; short for: offset_fmt=x offset_width=08 size_fmt=x size_width=04
+ -x hex; short for: offset_fmt=x offset_width=08 size_fmt=x \
+ size_width=04
-n do not generate perl code (default when invoked as pstruct)
-p generate perl code (default when invoked as c2ph)
listings like this:
struct tty {
- int tty.t_locker 000 4
- int tty.t_mutex_index 004 4
- struct tty * tty.t_tp_virt 008 4
- struct clist tty.t_rawq 00c 20
- int tty.t_rawq.c_cc 00c 4
- int tty.t_rawq.c_cmax 010 4
- int tty.t_rawq.c_cfx 014 4
- int tty.t_rawq.c_clx 018 4
- struct tty * tty.t_rawq.c_tp_cpu 01c 4
- struct tty * tty.t_rawq.c_tp_iop 020 4
- unsigned char * tty.t_rawq.c_buf_cpu 024 4
- unsigned char * tty.t_rawq.c_buf_iop 028 4
- struct clist tty.t_canq 02c 20
- int tty.t_canq.c_cc 02c 4
- int tty.t_canq.c_cmax 030 4
- int tty.t_canq.c_cfx 034 4
- int tty.t_canq.c_clx 038 4
- struct tty * tty.t_canq.c_tp_cpu 03c 4
- struct tty * tty.t_canq.c_tp_iop 040 4
- unsigned char * tty.t_canq.c_buf_cpu 044 4
- unsigned char * tty.t_canq.c_buf_iop 048 4
- struct clist tty.t_outq 04c 20
- int tty.t_outq.c_cc 04c 4
- int tty.t_outq.c_cmax 050 4
- int tty.t_outq.c_cfx 054 4
- int tty.t_outq.c_clx 058 4
- struct tty * tty.t_outq.c_tp_cpu 05c 4
- struct tty * tty.t_outq.c_tp_iop 060 4
- unsigned char * tty.t_outq.c_buf_cpu 064 4
- unsigned char * tty.t_outq.c_buf_iop 068 4
- (*int)() tty.t_oproc_cpu 06c 4
- (*int)() tty.t_oproc_iop 070 4
- (*int)() tty.t_stopproc_cpu 074 4
- (*int)() tty.t_stopproc_iop 078 4
- struct thread * tty.t_rsel 07c 4
+ int tty.t_locker 000 4
+ int tty.t_mutex_index 004 4
+ struct tty * tty.t_tp_virt 008 4
+ struct clist tty.t_rawq 00c 20
+ int tty.t_rawq.c_cc 00c 4
+ int tty.t_rawq.c_cmax 010 4
+ int tty.t_rawq.c_cfx 014 4
+ int tty.t_rawq.c_clx 018 4
+ struct tty * tty.t_rawq.c_tp_cpu 01c 4
+ struct tty * tty.t_rawq.c_tp_iop 020 4
+ unsigned char * tty.t_rawq.c_buf_cpu 024 4
+ unsigned char * tty.t_rawq.c_buf_iop 028 4
+ struct clist tty.t_canq 02c 20
+ int tty.t_canq.c_cc 02c 4
+ int tty.t_canq.c_cmax 030 4
+ int tty.t_canq.c_cfx 034 4
+ int tty.t_canq.c_clx 038 4
+ struct tty * tty.t_canq.c_tp_cpu 03c 4
+ struct tty * tty.t_canq.c_tp_iop 040 4
+ unsigned char * tty.t_canq.c_buf_cpu 044 4
+ unsigned char * tty.t_canq.c_buf_iop 048 4
+ struct clist tty.t_outq 04c 20
+ int tty.t_outq.c_cc 04c 4
+ int tty.t_outq.c_cmax 050 4
+ int tty.t_outq.c_cfx 054 4
+ int tty.t_outq.c_clx 058 4
+ struct tty * tty.t_outq.c_tp_cpu 05c 4
+ struct tty * tty.t_outq.c_tp_iop 060 4
+ unsigned char * tty.t_outq.c_buf_cpu 064 4
+ unsigned char * tty.t_outq.c_buf_iop 068 4
+ (*int)() tty.t_oproc_cpu 06c 4
+ (*int)() tty.t_oproc_iop 070 4
+ (*int)() tty.t_stopproc_cpu 074 4
+ (*int)() tty.t_stopproc_iop 078 4
+ struct thread * tty.t_rsel 07c 4
etc.
$ru = "\0" x &rusage'sizeof();
- syscall(&SYS_getrusage, &RUSAGE_SELF, $ru) && die "getrusage: $!";
+ syscall(&SYS_getrusage, &RUSAGE_SELF, $ru) && die "getrusage: $!";
@ru = unpack($t = &rusage'typedef(), $ru);
fields are just their own names. Plus the following accessor functions are
provided for your convenience:
- struct This takes no arguments, and is merely the number of first-level
- elements in the structure. You would use this for indexing
- into arrays of structures, perhaps like this
+ struct This takes no arguments, and is merely the number of first-
+ level elements in the structure. You would use this for
+ indexing into arrays of structures, perhaps like this
+ $usec = $u[ &user'u_utimer
+ + (&ITIMER_VIRTUAL * &itimerval'struct)
+ + &itimerval'it_value
+ + &timeval'tv_usec
+ ];
- $usec = $u[ &user'u_utimer
- + (&ITIMER_VIRTUAL * &itimerval'struct)
- + &itimerval'it_value
- + &timeval'tv_usec
- ];
+ sizeof Returns the bytes in the structure, or the member if
+ you pass it an argument, such as
- sizeof Returns the bytes in the structure, or the member if
- you pass it an argument, such as
+ &rusage'sizeof(&rusage'ru_utime)
- &rusage'sizeof(&rusage'ru_utime)
+ typedef This is the perl format definition for passing to pack and
+ unpack. If you ask for the typedef of a nothing, you get
+ the whole structure, otherwise you get that of the member
+ you ask for. Padding is taken care of, as is the magic to
+ guarantee that a union is unpacked into all its aliases.
+ Bitfields are not quite yet supported however.
- typedef This is the perl format definition for passing to pack and
- unpack. If you ask for the typedef of a nothing, you get
- the whole structure, otherwise you get that of the member
- you ask for. Padding is taken care of, as is the magic to
- guarantee that a union is unpacked into all its aliases.
- Bitfields are not quite yet supported however.
+ offsetof This function is the byte offset into the array of that
+ member. You may wish to use this for indexing directly
+ into the packed structure with vec() if you're too lazy
+ to unpack it.
- offsetof This function is the byte offset into the array of that
- member. You may wish to use this for indexing directly
- into the packed structure with vec() if you're too lazy
- to unpack it.
-
- typeof Not to be confused with the typedef accessor function, this
- one returns the C type of that field. This would allow
- you to print out a nice structured pretty print of some
- structure without knoning anything about it beforehand.
- No args to this one is a noop. Someday I'll post such
- a thing to dump out your u structure for you.
+ typeof Not to be confused with the typedef accessor function, this
+ one returns the C type of that field. This would allow
+ you to print out a nice structured pretty print of some
+ structure without knoning anything about it beforehand.
+ No args to this one is a noop. Someday I'll post such
+ a thing to dump out your u structure for you.
The way I see this being used is like basically this:
- % h2ph <some_include_file.h > /usr/lib/perl/tmp.ph
- % c2ph some_include_file.h >> /usr/lib/perl/tmp.ph
- % install
+ % h2ph <some_include_file.h > /usr/lib/perl/tmp.ph
+ % c2ph some_include_file.h >> /usr/lib/perl/tmp.ph
+ % install
It's a little tricker with c2ph because you have to get the includes right.
I can't know this for your system, but it's not usually too terribly difficult.
extra.pods : miniperl
@ @extra_pods.com
-PERLDELTA_CURRENT = [.pod]perl5238delta.pod
+PERLDELTA_CURRENT = [.pod]perl5239delta.pod
$(PERLDELTA_CURRENT) : [.pod]perldelta.pod
Copy/NoConfirm/Log $(MMS$SOURCE) $(PERLDELTA_CURRENT)
if (!str$case_blind_compare(env_tables[i],&crtlenv)) {
char *start;
int j;
- for (j = 0; environ[j]; j++) {
+ /* Start at the end, so if there is a duplicate we keep the first one. */
+ for (j = 0; environ[j]; j++);
+ for (j--; j >= 0; j--) {
if (!(start = strchr(environ[j],'='))) {
if (ckWARN(WARN_INTERNAL))
Perl_warner(aTHX_ packWARN(WARN_INTERNAL),"Ill-formed CRTL environ value \"%s\"\n",environ[j]);
/* This file is part of the "version" CPAN distribution. Please avoid
editing it in the perl core. */
-#ifndef PERL_CORE
-# define PERL_NO_GET_CONTEXT
-# include "EXTERN.h"
-# include "perl.h"
-# include "XSUB.h"
-# define NEED_my_snprintf
-# define NEED_newRV_noinc
-# define NEED_vnewSVpvf
-# define NEED_newSVpvn_flags_GLOBAL
-# define NEED_warner
-# include "ppport.h"
+#ifdef PERL_CORE
+# include "vutil.h"
#endif
-#include "vutil.h"
#define VERSION_MAX 0x7FFFFFFF
/*
-=head1 Versioning
-
=for apidoc prescan_version
Validate that a given string can be parsed as a version object, but doesn't
const char *d = s;
PERL_ARGS_ASSERT_PRESCAN_VERSION;
+ PERL_UNUSED_CONTEXT;
if (qv && isDIGIT(*d))
goto dotted_decimal_version;
/* trailing non-numeric data */
BADVERSION(s,errstr,"Invalid version format (non-numeric data)");
}
+ if (saw_decimal > 1 && d[-1] == '.') {
+ /* no trailing period allowed */
+ BADVERSION(s,errstr,"Invalid version format (trailing decimal)");
+ }
+
if (sqv)
*sqv = qv;
if ( !qv && width < 3 )
(void)hv_stores(MUTABLE_HV(hv), "width", newSViv(width));
- while (isDIGIT(*pos))
+ while (isDIGIT(*pos) || *pos == '_')
pos++;
if (!isALPHA(*pos)) {
I32 rev;
if ( !qv && s > start && saw_decimal == 1 ) {
mult *= 100;
while ( s < end ) {
+ if (*s == '_')
+ continue;
orev = rev;
rev += (*s - '0') * mult;
mult /= 10;
}
else {
while (--end >= s) {
- orev = rev;
- rev += (*end - '0') * mult;
- mult *= 10;
- if ( (PERL_ABS(orev) > PERL_ABS(rev))
- || (PERL_ABS(rev) > VERSION_MAX )) {
+ int i;
+ if (*end == '_')
+ continue;
+ i = (*end - '0');
+ if ( (mult == VERSION_MAX)
+ || (i > VERSION_MAX / mult)
+ || (i * mult > VERSION_MAX - rev))
+ {
Perl_ck_warner(aTHX_ packWARN(WARN_OVERFLOW),
"Integer overflow in version");
end = s - 1;
rev = VERSION_MAX;
vinf = 1;
}
+ else
+ rev += i * mult;
+
+ if (mult > VERSION_MAX / 10)
+ mult = VERSION_MAX;
+ else
+ mult *= 10;
}
}
}
s = last;
break;
}
- else if ( *pos == '.' )
- s = ++pos;
+ else if ( *pos == '.' ) {
+ pos++;
+ if (qv) {
+ while (*pos == '0')
+ ++pos;
+ }
+ s = pos;
+ }
else if ( *pos == '_' && isDIGIT(pos[1]) )
s = ++pos;
else if ( *pos == ',' && isDIGIT(pos[1]) )
break;
}
if ( qv ) {
- while ( isDIGIT(*pos) )
+ while ( isDIGIT(*pos) || *pos == '_')
pos++;
}
else {
Perl_new_version(pTHX_ SV *ver)
#endif
{
- dVAR;
SV * const rv = newSV(0);
PERL_ARGS_ASSERT_NEW_VERSION;
if ( ISA_VERSION_OBJ(ver) ) /* can just copy directly */
if ( mg ) { /* already a v-string */
const STRLEN len = mg->mg_len;
const char * const version = (const char*)mg->mg_ptr;
+ char *raw, *under;
+ static const char underscore[] = "_";
sv_setpvn(rv,version,len);
+ raw = SvPV_nolen(rv);
+ under = ninstr(raw, raw+len, underscore, underscore + 1);
+ if (under) {
+ Move(under + 1, under, raw + len - under - 1, char);
+ SvCUR(rv)--;
+ *SvEND(rv) = '\0';
+ }
/* this is for consistency with the pure Perl class */
if ( isDIGIT(*version) )
sv_insert(rv, 0, 0, "v", 1);
char tbuf[64];
SV *sv = SvNVX(ver) > 10e50 ? newSV(64) : 0;
char *buf;
+
+#if PERL_VERSION_GE(5,19,0)
+ if (SvPOK(ver)) {
+ /* dualvar? */
+ goto VER_PV;
+ }
+#endif
+
#ifdef USE_LOCALE_NUMERIC
- const char * const cur_numeric = setlocale(LC_NUMERIC, NULL);
- assert(cur_numeric);
-
- /* XS code can set the locale without us knowing. To protect the
- * version number parsing, which requires the radix character to be a
- * dot, update our records as to what the locale is, so that our
- * existing macro mechanism can correctly change it to a dot and back
- * if necessary. This code is extremely unlikely to be in a loop, so
- * the extra work will have a negligible performance impact. See [perl
- * #121930].
- *
- * If the current locale is a standard one, but we are expecting it to
- * be a different, underlying locale, update our records to make the
- * underlying locale this (standard) one. If the current locale is not
- * a standard one, we should be expecting a non-standard one, the same
- * one that we have recorded as the underlying locale. If not, update
- * our records. */
- if (strEQ(cur_numeric, "C") || strEQ(cur_numeric, "POSIX")) {
- if (! PL_numeric_standard) {
- new_numeric(cur_numeric);
- }
- }
- else if (PL_numeric_standard
- || ! PL_numeric_name
- || strNE(PL_numeric_name, cur_numeric))
- {
- new_numeric(cur_numeric);
- }
+ {
+ const char * const cur_numeric = setlocale(LC_NUMERIC, NULL);
+ assert(cur_numeric);
+
+ /* XS code can set the locale without us knowing. To protect the
+ * version number parsing, which requires the radix character to be a
+ * dot, update our records as to what the locale is, so that our
+ * existing macro mechanism can correctly change it to a dot and back
+ * if necessary. This code is extremely unlikely to be in a loop, so
+ * the extra work will have a negligible performance impact. See [perl
+ * #121930].
+ *
+ * If the current locale is a standard one, but we are expecting it to
+ * be a different, underlying locale, update our records to make the
+ * underlying locale this (standard) one. If the current locale is not
+ * a standard one, we should be expecting a non-standard one, the same
+ * one that we have recorded as the underlying locale. If not, update
+ * our records. */
+ if (strEQ(cur_numeric, "C") || strEQ(cur_numeric, "POSIX")) {
+ if (! PL_numeric_standard) {
+ new_numeric(cur_numeric);
+ }
+ }
+ else if (PL_numeric_standard
+ || ! PL_numeric_name
+ || strNE(PL_numeric_name, cur_numeric))
+ {
+ new_numeric(cur_numeric);
+ }
+ }
#endif
{ /* Braces needed because macro just below declares a variable */
STORE_NUMERIC_LOCAL_SET_STANDARD();
}
#endif
else if ( SvPOK(ver))/* must be a string or something like a string */
-#if PERL_VERSION_LT(5,17,2)
VER_PV:
-#endif
{
STRLEN len;
version = savepvn(SvPV(ver,len), SvCUR(ver));
{
SSize_t i, len;
I32 digit;
- int width;
bool alpha = FALSE;
SV *sv;
AV *av;
/* see if various flags exist */
if ( hv_exists(MUTABLE_HV(vs), "alpha", 5 ) )
alpha = TRUE;
- {
- SV ** svp = hv_fetchs(MUTABLE_HV(vs), "width", FALSE);
- if ( svp )
- width = SvIV(*svp);
- else
- width = 3;
- }
+ if (alpha) {
+ Perl_ck_warner(aTHX_ packWARN(WARN_NUMERIC),
+ "alpha->numify() is lossy");
+ }
/* attempt to retrieve the version array */
if ( !(av = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(vs), "version", FALSE))) ) ) {
digit = SvIV(tsv);
}
sv = Perl_newSVpvf(aTHX_ "%d.", (int)PERL_ABS(digit));
- for ( i = 1 ; i < len ; i++ )
+ for ( i = 1 ; i <= len ; i++ )
{
SV * tsv = *av_fetch(av, i, 0);
digit = SvIV(tsv);
- if ( width < 3 ) {
- const int denom = (width == 2 ? 10 : 100);
- const div_t term = div((int)PERL_ABS(digit),denom);
- Perl_sv_catpvf(aTHX_ sv, "%0*d_%d", width, term.quot, term.rem);
- }
- else {
- Perl_sv_catpvf(aTHX_ sv, "%0*d", width, (int)digit);
- }
+ Perl_sv_catpvf(aTHX_ sv, "%03d", (int)digit);
}
- if ( len > 0 )
- {
- SV * tsv = *av_fetch(av, len, 0);
- digit = SvIV(tsv);
- if ( alpha && width == 3 ) /* alpha version */
- sv_catpvs(sv,"_");
- Perl_sv_catpvf(aTHX_ sv, "%0*d", width, (int)digit);
- }
- else /* len == 0 */
- {
+ if ( len == 0 ) {
sv_catpvs(sv, "000");
}
return sv;
#endif
{
I32 i, len, digit;
- bool alpha = FALSE;
SV *sv;
AV *av;
if ( ! vs )
Perl_croak(aTHX_ "Invalid version object");
- if ( hv_exists(MUTABLE_HV(vs), "alpha", 5 ) )
- alpha = TRUE;
av = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(vs), "version", FALSE)));
len = av_len(av);
digit = SvIV(tsv);
}
sv = Perl_newSVpvf(aTHX_ "v%"IVdf, (IV)digit);
- for ( i = 1 ; i < len ; i++ ) {
+ for ( i = 1 ; i <= len ; i++ ) {
SV * tsv = *av_fetch(av, i, 0);
digit = SvIV(tsv);
Perl_sv_catpvf(aTHX_ sv, ".%"IVdf, (IV)digit);
}
- if ( len > 0 )
- {
- /* handle last digit specially */
- SV * tsv = *av_fetch(av, len, 0);
- digit = SvIV(tsv);
- if ( alpha )
- Perl_sv_catpvf(aTHX_ sv, "_%"IVdf, (IV)digit);
- else
- Perl_sv_catpvf(aTHX_ sv, ".%"IVdf, (IV)digit);
- }
-
if ( len <= 2 ) { /* short version, must be at least three */
for ( len = 2 - len; len != 0; len-- )
sv_catpvs(sv,".0");
{
SSize_t i,l,m,r;
I32 retval;
- bool lalpha = FALSE;
- bool ralpha = FALSE;
I32 left = 0;
I32 right = 0;
AV *lav, *rav;
/* get the left hand term */
lav = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(lhv), "version", FALSE)));
- if ( hv_exists(MUTABLE_HV(lhv), "alpha", 5 ) )
- lalpha = TRUE;
/* and the right hand term */
rav = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(rhv), "version", FALSE)));
- if ( hv_exists(MUTABLE_HV(rhv), "alpha", 5 ) )
- ralpha = TRUE;
l = av_len(lav);
r = av_len(rav);
i++;
}
- /* tiebreaker for alpha with identical terms */
- if ( retval == 0 && l == r && left == right && ( lalpha || ralpha ) )
- {
- if ( lalpha && !ralpha )
- {
- retval = -1;
- }
- else if ( ralpha && !lalpha)
- {
- retval = +1;
- }
- }
-
if ( l != r && retval == 0 ) /* possible match except for trailing 0's */
{
if ( l < r )
}
return retval;
}
+
+/* ex: set ro: */
# define VUTIL_REPLACE_CORE 1
-const char * Perl_scan_version2(pTHX_ const char *s, SV *rv, bool qv);
-SV * Perl_new_version2(pTHX_ SV *ver);
-SV * Perl_upg_version2(pTHX_ SV *sv, bool qv);
-SV * Perl_vstringify2(pTHX_ SV *vs);
-SV * Perl_vverify2(pTHX_ SV *vs);
-SV * Perl_vnumify2(pTHX_ SV *vs);
-SV * Perl_vnormal2(pTHX_ SV *vs);
-SV * Perl_vstringify2(pTHX_ SV *vs);
-int Perl_vcmp2(pTHX_ SV *lsv, SV *rsv);
-const char * Perl_prescan_version2(pTHX_ const char *s, bool strict, const char** errstr, bool *sqv, int *ssaw_decimal, int *swidth, bool *salpha);
+static const char * Perl_scan_version2(pTHX_ const char *s, SV *rv, bool qv);
+static SV * Perl_new_version2(pTHX_ SV *ver);
+static SV * Perl_upg_version2(pTHX_ SV *sv, bool qv);
+static SV * Perl_vstringify2(pTHX_ SV *vs);
+static SV * Perl_vverify2(pTHX_ SV *vs);
+static SV * Perl_vnumify2(pTHX_ SV *vs);
+static SV * Perl_vnormal2(pTHX_ SV *vs);
+static SV * Perl_vstringify2(pTHX_ SV *vs);
+static int Perl_vcmp2(pTHX_ SV *lsv, SV *rsv);
+static const char * Perl_prescan_version2(pTHX_ const char *s, bool strict, const char** errstr, bool *sqv, int *ssaw_decimal, int *swidth, bool *salpha);
# define SCAN_VERSION(a,b,c) Perl_scan_version2(aTHX_ a,b,c)
# define NEW_VERSION(a) Perl_new_version2(aTHX_ a)
# define RESTORE_NUMERIC_LOCAL()
# endif
#endif
+
+#ifndef LOCK_NUMERIC_STANDARD
+#define LOCK_NUMERIC_STANDARD()
+#endif
+
+#ifndef UNLOCK_NUMERIC_STANDARD
+#define UNLOCK_NUMERIC_STANDARD()
+#endif
+
+/* ex: set ro: */
/* proto member is unused in version, it is used in CORE by non version xsubs */
# define VXSXSDP(x)
#endif
-#define VXS(name) XS(VXSp(name)); XS(VXSp(name))
+
+#ifndef XS_INTERNAL
+# define XS_INTERNAL(name) static XSPROTO(name)
+#endif
+
+#define VXS(name) XS_INTERNAL(VXSp(name)); XS_INTERNAL(VXSp(name))
/* uses PUSHs, so SP must be at start, PUSHs sv on Perl stack, then returns from
xsub; this is a little more machine code/tailcall friendly than mPUSHs(foo);
VXS(universal_version)
{
- dVAR;
dXSARGS;
HV *pkg;
GV **gvp;
VXS(version_new)
{
- dVAR;
dXSARGS;
SV *vs;
SV *rv;
default:
case 0:
Perl_croak_nocontext("Usage: version::new(class, version)");
- break;
}
svarg0 = ST(0);
VXS(version_stringify)
{
- dVAR;
dXSARGS;
if (items < 1)
croak_xs_usage(cv, "lobj, ...");
VXS(version_numify)
{
- dVAR;
dXSARGS;
if (items < 1)
croak_xs_usage(cv, "lobj, ...");
VXS(version_normal)
{
- dVAR;
dXSARGS;
if (items != 1)
croak_xs_usage(cv, "ver");
VXS(version_vcmp)
{
- dVAR;
dXSARGS;
if (items < 1)
croak_xs_usage(cv, "lobj, ...");
VXS(version_boolean)
{
- dVAR;
dXSARGS;
SV *lobj;
if (items < 1)
VXS(version_noop)
{
- dVAR;
dXSARGS;
if (items < 1)
croak_xs_usage(cv, "lobj, ...");
void
S_version_check_key(pTHX_ CV * cv, const char * key, int keylen)
{
- dVAR;
dXSARGS;
if (items != 1)
croak_xs_usage(cv, "lobj");
VXS(version_qv)
{
- dVAR;
dXSARGS;
PERL_UNUSED_ARG(cv);
SP -= items;
# versioned installation can be obtained by setting INST_TOP above to a
# path that includes an arbitrary version string.
#
-#INST_VER := \5.23.8
+#INST_VER := \5.23.9
#
# Comment this out if you DON'T want your perl installation to have
ifeq ($(CCTYPE),GCC)
ifeq ($(GCCTARGET),x86_64-w64-mingw32)
WIN64 := define
-ARCHITECTURE := x64
+PROCESSOR_ARCHITECTURE := x64
endif
ifeq ($(GCCTARGET),i686-w64-mingw32)
WIN64 := undef
-ARCHITECTURE := x86
+PROCESSOR_ARCHITECTURE := x86
endif
endif
copy ..\README.tw ..\pod\perltw.pod
copy ..\README.vos ..\pod\perlvos.pod
copy ..\README.win32 ..\pod\perlwin32.pod
- copy ..\pod\perldelta.pod ..\pod\perl5238delta.pod
+ copy ..\pod\perldelta.pod ..\pod\perl5239delta.pod
$(MINIPERL) -I..\lib $(PL2BAT) $(UTILS)
$(MINIPERL) -I..\lib ..\autodoc.pl ..
$(MINIPERL) -I..\lib ..\pod\perlmodlib.PL -q ..
-if exist $(LIBDIR)\Hash rmdir /s /q $(LIBDIR)\Hash
-if exist $(LIBDIR)\HTTP rmdir /s /q $(LIBDIR)\HTTP
-if exist $(LIBDIR)\I18N rmdir /s /q $(LIBDIR)\I18N
+ -if exist $(LIBDIR)\inc rmdir /s /q $(LIBDIR)\inc
-if exist $(LIBDIR)\IO rmdir /s /q $(LIBDIR)\IO
-if exist $(LIBDIR)\IPC rmdir /s /q $(LIBDIR)\IPC
-if exist $(LIBDIR)\JSON rmdir /s /q $(LIBDIR)\JSON
-if exist $(LIBDIR)\Win32API rmdir /s /q $(LIBDIR)\Win32API
-if exist $(LIBDIR)\XS rmdir /s /q $(LIBDIR)\XS
-cd $(PODDIR) && del /f *.html *.bat roffitall \
- perl5238delta.pod perlaix.pod perlamiga.pod perlandroid.pod \
+ perl5239delta.pod perlaix.pod perlamiga.pod perlandroid.pod \
perlapi.pod perlbs2000.pod perlce.pod perlcn.pod perlcygwin.pod \
perldos.pod perlfreebsd.pod perlhaiku.pod perlhpux.pod \
perlhurd.pod perlintern.pod perlirix.pod perljp.pod perlko.pod \
# versioned installation can be obtained by setting INST_TOP above to a
# path that includes an arbitrary version string.
#
-#INST_VER = \5.23.8
+#INST_VER = \5.23.9
#
# Comment this out if you DON'T want your perl installation to have
copy ..\README.tw ..\pod\perltw.pod
copy ..\README.vos ..\pod\perlvos.pod
copy ..\README.win32 ..\pod\perlwin32.pod
- copy ..\pod\perldelta.pod ..\pod\perl5238delta.pod
+ copy ..\pod\perldelta.pod ..\pod\perl5239delta.pod
cd ..\win32
$(PERLEXE) $(PL2BAT) $(UTILS)
$(MINIPERL) -I..\lib ..\autodoc.pl ..
-if exist $(LIBDIR)\Hash rmdir /s /q $(LIBDIR)\Hash
-if exist $(LIBDIR)\HTTP rmdir /s /q $(LIBDIR)\HTTP
-if exist $(LIBDIR)\I18N rmdir /s /q $(LIBDIR)\I18N
+ -if exist $(LIBDIR)\inc rmdir /s /q $(LIBDIR)\inc
-if exist $(LIBDIR)\IO rmdir /s /q $(LIBDIR)\IO
-if exist $(LIBDIR)\IPC rmdir /s /q $(LIBDIR)\IPC
-if exist $(LIBDIR)\JSON rmdir /s /q $(LIBDIR)\JSON
-if exist $(LIBDIR)\Win32API rmdir /s /q $(LIBDIR)\Win32API
-if exist $(LIBDIR)\XS rmdir /s /q $(LIBDIR)\XS
-cd $(PODDIR) && del /f *.html *.bat roffitall \
- perl5238delta.pod perlaix.pod perlamiga.pod perlandroid.pod \
+ perl5239delta.pod perlaix.pod perlamiga.pod perlandroid.pod \
perlapi.pod perlbs2000.pod perlce.pod perlcn.pod perlcygwin.pod \
perldos.pod perlfreebsd.pod perlhaiku.pod perlhpux.pod \
perlhurd.pod perlintern.pod perlirix.pod perljp.pod perlko.pod \
d_fpclassl='undef'
d_fpgetround='undef'
d_fpos64_t='undef'
+d_freelocale='undef'
d_frexpl='undef'
d_fs_data_s='undef'
d_fseeko='undef'
d_nan='undef'
d_ndbm_h_uses_prototypes='undef'
d_nearbyint='undef'
+d_newlocale='undef'
d_nextafter='undef'
d_nexttoward='undef'
d_nice='undef'
d_union_semun='define'
d_unordered='undef'
d_unsetenv='undef'
+d_uselocale='undef'
d_usleep='undef'
d_usleepproto='undef'
d_ustat='undef'
d_fpclassl='undef'
d_fpgetround='undef'
d_fpos64_t='undef'
+d_freelocale='undef'
d_frexpl='undef'
d_fs_data_s='undef'
d_fseeko='undef'
d_ndbm='undef'
d_ndbm_h_uses_prototypes='undef'
d_nearbyint='undef'
+d_newlocale='undef'
d_nextafter='undef'
d_nexttoward='undef'
d_nice='undef'
d_union_semun='define'
d_unordered='undef'
d_unsetenv='undef'
+d_uselocale='undef'
d_usleep='undef'
d_usleepproto='undef'
d_ustat='undef'
d_fpclassl='undef'
d_fpgetround='undef'
d_fpos64_t='undef'
+d_freelocale='undef'
d_frexpl='undef'
d_fs_data_s='undef'
d_fseeko='undef'
d_ndbm='undef'
d_ndbm_h_uses_prototypes='undef'
d_nearbyint='undef'
+d_newlocale='undef'
d_nextafter='undef'
d_nexttoward='undef'
d_nice='undef'
d_union_semun='define'
d_unordered='undef'
d_unsetenv='undef'
+d_uselocale='undef'
d_usleep='undef'
d_usleepproto='undef'
d_ustat='undef'
# versioned installation can be obtained by setting INST_TOP above to a
# path that includes an arbitrary version string.
#
-#INST_VER *= \5.23.8
+#INST_VER *= \5.23.9
#
# Comment this out if you DON'T want your perl installation to have
copy ..\README.tw ..\pod\perltw.pod
copy ..\README.vos ..\pod\perlvos.pod
copy ..\README.win32 ..\pod\perlwin32.pod
- copy ..\pod\perldelta.pod ..\pod\perl5238delta.pod
+ copy ..\pod\perldelta.pod ..\pod\perl5239delta.pod
$(MINIPERL) -I..\lib $(PL2BAT) $(UTILS)
$(MINIPERL) -I..\lib ..\autodoc.pl ..
$(MINIPERL) -I..\lib ..\pod\perlmodlib.PL -q ..
-if exist $(LIBDIR)\Hash rmdir /s /q $(LIBDIR)\Hash
-if exist $(LIBDIR)\HTTP rmdir /s /q $(LIBDIR)\HTTP
-if exist $(LIBDIR)\I18N rmdir /s /q $(LIBDIR)\I18N
+ -if exist $(LIBDIR)\inc rmdir /s /q $(LIBDIR)\inc
-if exist $(LIBDIR)\IO rmdir /s /q $(LIBDIR)\IO
-if exist $(LIBDIR)\IPC rmdir /s /q $(LIBDIR)\IPC
-if exist $(LIBDIR)\JSON rmdir /s /q $(LIBDIR)\JSON
-if exist $(LIBDIR)\Win32API rmdir /s /q $(LIBDIR)\Win32API
-if exist $(LIBDIR)\XS rmdir /s /q $(LIBDIR)\XS
-cd $(PODDIR) && del /f *.html *.bat roffitall \
- perl5238delta.pod perlaix.pod perlamiga.pod perlandroid.pod \
+ perl5239delta.pod perlaix.pod perlamiga.pod perlandroid.pod \
perlapi.pod perlbs2000.pod perlce.pod perlcn.pod perlcygwin.pod \
perldos.pod perlfreebsd.pod perlhaiku.pod perlhpux.pod \
perlhurd.pod perlintern.pod perlirix.pod perljp.pod perlko.pod \
perl5236delta.pod \
perl5237delta.pod \
perl5238delta.pod \
+ perl5239delta.pod \
perl561delta.pod \
perl56delta.pod \
perl581delta.pod \
perl5236delta.man \
perl5237delta.man \
perl5238delta.man \
+ perl5239delta.man \
perl561delta.man \
perl56delta.man \
perl581delta.man \
perl5236delta.html \
perl5237delta.html \
perl5238delta.html \
+ perl5239delta.html \
perl561delta.html \
perl56delta.html \
perl581delta.html \
perl5236delta.tex \
perl5237delta.tex \
perl5238delta.tex \
+ perl5239delta.tex \
perl561delta.tex \
perl56delta.tex \
perl581delta.tex \
STMT_START { \
StartSockets(); \
if((x) == (y)) \
- errno = get_last_socket_error(); \
+ { \
+ int wsaerr = WSAGetLastError(); \
+ errno = convert_wsa_error_to_errno(wsaerr); \
+ SetLastError(wsaerr); \
+ } \
} STMT_END
#define SOCKET_TEST_ERROR(x) SOCKET_TEST(x, SOCKET_ERROR)
-static int get_last_socket_error(void);
static struct servent* win32_savecopyservent(struct servent*d,
struct servent*s,
const char *proto);
}
#endif /* ERRNO_HAS_POSIX_SUPPLEMENT */
-static int
-get_last_socket_error(void)
-{
- return convert_wsa_error_to_errno(WSAGetLastError());
-}
-
void
start_sockets(void)
{
StartSockets();
if((s = open_ifs_socket(af, type, protocol)) == INVALID_SOCKET)
- errno = get_last_socket_error();
+ {
+ int wsaerr = WSAGetLastError();
+ errno = convert_wsa_error_to_errno(wsaerr);
+ SetLastError(wsaerr);
+ }
else
s = OPEN_SOCKET(s);
return close(fd);
}
else if (err == SOCKET_ERROR) {
- err = get_last_socket_error();
+ int wsaerr = WSAGetLastError();
+ err = convert_wsa_error_to_errno(wsaerr);
if (err != ENOTSOCK) {
(void)close(fd);
errno = err;
+ SetLastError(wsaerr);
return EOF;
}
}
return fclose(pf);
}
else if (err == SOCKET_ERROR) {
- err = get_last_socket_error();
+ int wsaerr = WSAGetLastError();
+ err = convert_wsa_error_to_errno(wsaerr);
if (err != ENOTSOCK) {
(void)fclose(pf);
errno = err;
+ SetLastError(wsaerr);
return EOF;
}
}
memcpy(data, &u_long_arg, sizeof u_long_arg);
if (retval == SOCKET_ERROR) {
- int err = get_last_socket_error();
+ int wsaerr = WSAGetLastError();
+ int err = convert_wsa_error_to_errno(wsaerr);
if (err == ENOTSOCK) {
Perl_croak_nocontext("ioctl implemented only on sockets");
/* NOTREACHED */
}
errno = err;
+ SetLastError(wsaerr);
}
return retval;
}