diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1997-11-30 07:49:45 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1997-11-30 07:49:45 +0000 |
commit | eeacafe7910fb1a4f74af72f94a32acf464b6319 (patch) | |
tree | 91e47a98a8a5803678d5e634741442debc7cec27 /gnu/usr.bin | |
parent | 700df82d5de7cccb990b704f31bed3b5bc128df6 (diff) |
perl 5.004_04
Diffstat (limited to 'gnu/usr.bin')
98 files changed, 24641 insertions, 12483 deletions
diff --git a/gnu/usr.bin/perl/Configure b/gnu/usr.bin/perl/Configure index 4f17f64aac3..b32c5102afb 100644 --- a/gnu/usr.bin/perl/Configure +++ b/gnu/usr.bin/perl/Configure @@ -18,9 +18,9 @@ # archive site. Check with Archie if you don't know where that can be.) # -# $Id: Configure,v 1.2 1996/09/06 01:33:53 dm Exp $ +# $Id: Head.U,v 3.0.1.8 1995/07/25 13:40:02 ram Exp $ # -# Generated on Wed Feb 21 14:26:18 EST 1996 [metaconfig 3.0 PL60] +# Generated on Sat Feb 1 00:26:40 EST 1997 [metaconfig 3.0 PL60] cat >/tmp/c1$$ <<EOF ARGGGHHHH!!!!! @@ -58,7 +58,7 @@ esac : Proper PATH separator p_=: : On OS/2 this directory should exist if this is not floppy only system :-] -if test -d c:/.; then +if test -d c:/. -a -n "$OS2_SHELL"; then p_=\; PATH=`cmd /c "echo %PATH%" | tr '\\\\' / ` OS2_SHELL=`cmd /c "echo %OS2_SHELL%" | tr '\\\\' / | tr '[A-Z]' '[a-z]'` @@ -85,6 +85,12 @@ done PATH=.$p_$PATH export PATH +: This should not matter in scripts, but apparently it does, sometimes +case "$CDPATH" in +'') ;; +*) CDPATH='' ;; +esac + : Sanity checks # WRONG: This makes it impossible to compile perl non-interactively #if test ! -t 0; then @@ -92,24 +98,40 @@ export PATH # exit 1 #fi -: On HP-UX, large Configure scripts may exercise a bug in /bin/sh -if test -f /hp-ux -a -f /bin/ksh; then - if (PATH=.; alias -x) >/dev/null 2>&1; then - : already under /bin/ksh - else +: Test and see if we are running under ksh, either blatantly or in disguise. +if (PATH=.; alias -x) >/dev/null 2>&1; then + : running under ksh. Is this a good thing? + if test -d /usr/lpp -a -f /usr/bin/bsh -a -f /usr/bin/uname ; then + if test X`/usr/bin/uname -v` = X4 ; then + : on AIX 4, /bin/sh is really ksh, and it causes us problems. + : Avoid it cat <<'EOM' -(Feeding myself to ksh to avoid nasty sh bug in "here document" expansion.) +(Feeding myself to /usr/bin/bsh to avoid AIX 4's /bin/sh.) EOM unset ENV - exec /bin/ksh $0 "$@" + exec /usr/bin/bsh $0 "$@" fi -else + else + if test ! -f /hp-ux ; then : Warn them if they use ksh on other systems - (PATH=.; alias -x) >/dev/null 2>&1 && \ cat <<EOM (I see you are using the Korn shell. Some ksh's blow up on $me, -especially on exotic machines. If yours does, try the Bourne shell instead.) +especially on older exotic systems. If yours does, try the Bourne +shell instead.) EOM + unset ENV + fi + fi +else + : Not running under ksh. Maybe we should be? + : On HP-UX, large Configure scripts may exercise a bug in /bin/sh + if test -f /hp-ux -a -f /bin/ksh; then + cat <<'EOM' +(Feeding myself to ksh to avoid nasty sh bug in "here document" expansion.) +EOM + unset ENV + exec /bin/ksh $0 "$@" + fi fi : Configure runs within the UU subdirectory @@ -120,8 +142,8 @@ dynamic_ext='' extensions='' known_extensions='' static_ext='' +useopcode='' useposix='' -usesafe='' d_bsd='' d_eunice='' d_xenix='' @@ -150,6 +172,7 @@ find='' flex='' gcc='' grep='' +gzip='' inews='' ksh='' less='' @@ -161,7 +184,6 @@ lpr='' ls='' mail='' mailx='' -make='' mkdir='' more='' mv='' @@ -174,7 +196,6 @@ rm='' rmail='' sed='' sendmail='' -sh='' shar='' sleep='' smail='' @@ -192,6 +213,7 @@ uniq='' uuname='' vi='' zcat='' +zip='' full_sed='' libswanted='' hint='' @@ -227,6 +249,8 @@ baserev='' bin='' binexp='' installbin='' +bincompat3='' +d_bincompat3='' byteorder='' cc='' gccversion='' @@ -284,19 +308,26 @@ d_flexfnam='' d_flock='' d_fork='' d_fsetpos='' +d_ftime='' +d_gettimeod='' d_Gconvert='' d_getgrps='' +d_setgrps='' d_gethent='' aphostname='' d_gethname='' d_phostname='' d_uname='' d_getlogin='' +d_getpgid='' d_getpgrp2='' +d_bsdgetpgrp='' d_getpgrp='' d_getppid='' d_getprior='' +d_gnulibc='' d_htonl='' +d_inetaton='' d_isascii='' d_killpg='' d_link='' @@ -335,6 +366,7 @@ d_rename='' d_rmdir='' d_safebcpy='' d_safemcpy='' +d_sanemcmp='' d_select='' d_sem='' d_semctl='' @@ -347,6 +379,7 @@ d_setlocale='' d_setpgid='' d_setpgrp2='' d_bsdpgrp='' +d_bsdsetpgrp='' d_setpgrp='' d_setprior='' d_setregid='' @@ -356,6 +389,8 @@ d_setreuid='' d_setrgid='' d_setruid='' d_setsid='' +d_sfio='' +usesfio='' d_shm='' d_shmat='' d_shmatprototype='' @@ -363,11 +398,8 @@ shmattype='' d_shmctl='' d_shmdt='' d_shmget='' -d_sigsetjmp='' d_sigaction='' -d_sigintrp='' -d_sigvec='' -d_sigvectr='' +d_sigsetjmp='' d_oldsock='' d_socket='' d_sockpair='' @@ -390,6 +422,9 @@ d_strerrm='' d_strerror='' d_sysernlst='' d_syserrlst='' +d_strtod='' +d_strtol='' +d_strtoul='' d_strxfrm='' d_symlink='' d_syscall='' @@ -418,11 +453,9 @@ d_wctomb='' dlext='' cccdlflags='' ccdlflags='' -d_shrplib='' dlsrc='' ld='' lddlflags='' -shrpdir='' usedl='' fpostype='' gidtype='' @@ -459,6 +492,7 @@ d_pwcomment='' d_pwexpire='' d_pwquota='' i_pwd='' +i_sfio='' i_stddef='' i_stdlib='' i_string='' @@ -472,11 +506,13 @@ i_sysioctl='' i_syssockio='' i_sysndir='' i_sysparam='' +i_sysresrc='' i_sysselct='' i_sysstat='' i_systimes='' i_systypes='' i_sysun='' +i_syswait='' i_sgtty='' i_termio='' i_termios='' @@ -486,12 +522,18 @@ i_time='' timeincl='' i_unistd='' i_utime='' +i_values='' i_stdarg='' i_varargs='' i_varhdr='' i_vfork='' intsize='' +longsize='' +shortsize='' libc='' +libperl='' +shrpenv='' +useshrplib='' glibpth='' libpth='' loclibpth='' @@ -500,6 +542,8 @@ xlibpth='' libs='' lns='' lseektype='' +make='' +make_set_make='' d_mymalloc='' freetype='' mallocobj='' @@ -542,6 +586,7 @@ package='' spackage='' pager='' patchlevel='' +subversion='' perladmin='' perlpath='' prefix='' @@ -555,6 +600,7 @@ installscript='' scriptdir='' scriptdirexp='' selecttype='' +sh='' sig_name='' sig_num='' installsitearch='' @@ -572,13 +618,13 @@ ssizetype='' startperl='' startsh='' stdchar='' -subversion='' sysman='' uidtype='' nm_opt='' nm_so_opt='' runnm='' usenm='' +useperlio='' incpath='' mips='' mips_type='' @@ -672,8 +718,8 @@ i_whoami='' libswanted='' : set useposix=false in your hint file to disable the POSIX extension. useposix=true -: set usesafe=false in your hint if you want to skip the Safe extension. -usesafe=true +: set useopcode=false in your hint file to disable the Opcode extension. +useopcode=true : Define several unixisms. These can be used in hint files. exe_ext='' : Extra object files, if any, needed on this platform. @@ -694,9 +740,10 @@ loclibpth="/usr/local/lib /opt/local/lib /usr/gnu/lib" loclibpth="$loclibpth /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib" : general looking path for locating libraries -glibpth="/lib/pa1.1 /usr/shlib /usr/lib/large /lib /usr/lib" -glibpth="$glibpth $xlibpth /lib/large /usr/lib/small /lib/small" -glibpth="$glibpth /usr/ccs/lib /usr/ucblib /usr/shlib" +glibpth="/shlib /usr/shlib /usr/lib/pa1.1 /usr/lib/large" +glibpth="$glibpth /lib /usr/lib $xlibpth" +glibpth="$glibpth /lib/large /usr/lib/small /lib/small" +glibpth="$glibpth /usr/ccs/lib /usr/ucblib /usr/local/lib" : Private path used by Configure to find libraries. Its value : is prepended to libpth. This variable takes care of special @@ -707,7 +754,7 @@ plibpth='' defvoidused=15 : List of libraries we want. -libswanted='net socket inet nsl nm ndbm gdbm dbm db malloc dl' +libswanted='sfio net socket inet nsl nm ndbm gdbm dbm db malloc dl' libswanted="$libswanted dld ld sun m c cposix posix ndir dir crypt" libswanted="$libswanted ucb bsd BSD PW x" : We probably want to search /usr/shlib before most other libraries. @@ -717,8 +764,117 @@ glibpth="/usr/shlib $glibpth" : Do not use vfork unless overridden by a hint file. usevfork=false +: Find the basic shell for Bourne shell scripts +case "$sh" in +'') + : SYSTYPE is for some older MIPS systems. + : I do not know if it is still needed. + case "$SYSTYPE" in + *bsd*|sys5*) xxx="/$SYSTYPE/bin/sh";; + *) xxx='/bin/sh';; + esac + if test -f "$xxx"; then + sh="$xxx" + else + : Build up a list and do a single loop so we can 'break' out. + pth=`echo $PATH | sed -e "s/$p_/ /g"` + for xxx in sh bash ksh pdksh ash; do + for p in $pth; do + try="$try ${p}/${xxx}" + done + done + for xxx in $try; do + if test -f "$xxx"; then + sh="$xxx"; + echo "Your Bourne shell appears to be in $sh." + break + elif test -f "$xxx.exe"; then + sh="$xxx"; + echo "Hmm. Your Bourne shell appears to be in $sh." + break + fi + done + fi + ;; +esac + +case "$sh" in +'') cat <<EOM >&2 +$me: Fatal Error: I can't find a Bourne Shell anywhere. +Usually it's in /bin/sh. How did you even get this far? +Please contact me (Chip Salzenberg) at chip@perl.com and +we'll try to straigten this all out. +EOM + exit 1 + ;; +esac + +: see if sh knows # comments +if `$sh -c '#' >/dev/null 2>&1`; then + shsharp=true + spitshell=cat + echo " " + xcat=/bin/cat + test -f $xcat || xcat=/usr/bin/cat + echo "#!$xcat" >try + $eunicefix try + chmod +x try + ./try > today + if test -s today; then + sharpbang='#!' + else + echo "#! $xcat" > try + $eunicefix try + chmod +x try + ./try > today + if test -s today; then + sharpbang='#! ' + else + echo "Okay, let's see if #! works on this system..." + echo "It's just a comment." + sharpbang=': use ' + fi + fi +else + echo "Your $sh doesn't grok # comments--I will strip them later on." + shsharp=false + cd .. + echo "exec grep -v '^[ ]*#'" >spitshell + chmod +x spitshell + $eunicefix spitshell + spitshell=`pwd`/spitshell + cd UU + echo "I presume that if # doesn't work, #! won't work either!" + sharpbang=': use ' +fi +rm -f try today + +: figure out how to guarantee sh startup +case "$startsh" in +'') startsh=${sharpbang}${sh} ;; +*) +esac +cat >try <<EOSS +$startsh +set abc +test "$?abc" != 1 +EOSS + +chmod +x try +$eunicefix try +if ./try; then + : echo "Yup, it does." +else + echo "Hmm. '$startsh' didn't work." + echo "You may have to fix up the shell scripts to make sure sh runs them." +fi +rm -f try + : script used to extract .SH files with variable substitutions -cat >extract <<'EOS' +cat >extract <<EOS +$startsh +EOS +cat >>extract <<'EOS' CONFIG=true echo "Doing variable substitutions on .SH files..." if test -f MANIFEST; then @@ -826,7 +982,11 @@ silent='' extractsh='' override='' knowitall='' + rm -f optdef.sh +cat >optdef.sh <<EOS +$startsh +EOS : option parsing while test $# -gt 0; do @@ -887,7 +1047,7 @@ done case "$error" in true) cat >&2 <<EOM -Usage: $me [-dehrEKOSV] [-f config.sh] [-D symbol] [-D symbol=value] +Usage: $me [-dehrsEKOSV] [-f config.sh] [-D symbol] [-D symbol=value] [-U symbol] [-U symbol=] -d : use defaults for all answers. -e : go on without questioning past the production of config.sh. @@ -1014,7 +1174,7 @@ THIS PACKAGE SEEMS TO BE INCOMPLETE. You have the option of continuing the configuration process, despite the distinct possibility that your kit is damaged, by typing 'y'es. If you do, don't blame me if something goes wrong. I advise you to type 'n'o -and contact the author (doughera@lafcol.lafayette.edu). +and contact the author (chip@perl.com). EOM echo $n "Continue? [n] $c" >&4 @@ -1060,6 +1220,7 @@ esac" : now set up to do reads with possible shell escape and default assignment cat <<EOSC >myread +$startsh xxxm=\$dflt $myecho ans='!' @@ -1082,7 +1243,7 @@ while expr "X\$ans" : "X!" >/dev/null; do read answ set x \$xxxm shift - aok=''; eval "ans=\"\$answ\"" && aok=y + aok=''; eval ans="\\"\$answ\\"" && aok=y case "\$answ" in "\$ans") case "\$ans" in @@ -1155,7 +1316,10 @@ EOF : general instructions needman=true firsttime=true -user=`( (logname) 2>/dev/null || whoami) 2>&1` +user=`(logname) 2>/dev/null` +case "$user" in "") + user=`whoami 2>&1` ;; +esac if $contains "^$user\$" ../.config/instruct >/dev/null 2>&1; then firsttime=false echo " " @@ -1201,7 +1365,7 @@ If you are in a hurry, you may run 'Configure -d'. This will bypass nearly all the questions and use the computed defaults (or the previous answers if there was already a config.sh file). Type 'Configure -h' for a list of options. You may also start interactively and then answer '& -d' at any prompt to turn -on the non-interactive behaviour for the remaining of the execution. +on the non-interactive behavior for the remainder of the execution. EOH . ./myread @@ -1211,7 +1375,7 @@ Much effort has been expended to ensure that this shell script will run on any Unix system. If despite that it blows up on yours, your best bet is to edit Configure and run it again. If you can't run Configure for some reason, you'll have to generate a config.sh file by hand. Whatever problems you -have, let me (doughera@lafcol.lafayette.edu) know how I blew it. +have, let me (chip@perl.com) know how I blew it. This installation script affects things in two ways: @@ -1232,74 +1396,6 @@ EOH esac fi -: see if sh knows # comments -echo " " -echo "Checking your sh to see if it knows about # comments..." >&4 -if `sh -c '#' >/dev/null 2>&1`; then - echo "Your sh handles # comments correctly." - shsharp=true - spitshell=cat - echo " " - echo "Okay, let's see if #! works on this system..." - xcat=/bin/cat - test -f $xcat || xcat=/usr/bin/cat - echo "#!$xcat" >try - $eunicefix try - chmod +x try - ./try > today - if test -s today; then - echo "It does." - sharpbang='#!' - else - echo "#! $xcat" > try - $eunicefix try - chmod +x try - ./try > today - if test -s today; then - echo "It does." - sharpbang='#! ' - else - echo "It's just a comment." - sharpbang=': use ' - fi - fi -else - echo "Your sh doesn't grok # comments--I will strip them later on." - shsharp=false - cd .. - echo "exec grep -v '^[ ]*#'" >spitshell - chmod +x spitshell - $eunicefix spitshell - spitshell=`pwd`/spitshell - cd UU - echo "I presume that if # doesn't work, #! won't work either!" - sharpbang=': use ' -fi -rm -f try today - -: figure out how to guarantee sh startup -echo " " -echo "Checking out how to guarantee sh startup..." >&4 -case "$SYSTYPE" in -*bsd*|sys5*) startsh=$sharpbang"/$SYSTYPE/bin/sh";; -*) startsh=$sharpbang'/bin/sh';; -esac -echo "Let's see if '$startsh' works..." -cat >try <<EOSS -$startsh -set abc -test "$?abc" != 1 -EOSS - -chmod +x try -$eunicefix try -if ./try; then - echo "Yup, it does." -else -echo "Nope. You may have to fix up the shell scripts to make sure sh runs them." -fi -rm -f try - : find out where common programs are echo " " echo "Locating common programs..." >&4 @@ -1349,7 +1445,6 @@ echo expr find grep -ln ls mkdir rm @@ -1366,8 +1461,10 @@ cpp csh date egrep +gzip less line +ln more nroff perl @@ -1375,6 +1472,7 @@ pg sendmail test uname +zip " pth=`echo $PATH | sed -e "s/$p_/ /g"` pth="$pth /lib /usr/lib" @@ -1422,6 +1520,12 @@ egrep) egrep=$grep ;; esac +case "$ln" in +ln) + echo "Substituting cp for ln." + ln=$cp + ;; +esac case "$test" in test) echo "Hopefully test is built into your sh." @@ -1538,10 +1642,16 @@ if test -f config.sh; then *) echo "Fetching default answers from your old config.sh file..." >&4 tmp_n="$n" tmp_c="$c" + tmp_sh="$sh" . ./config.sh cp config.sh UU n="$tmp_n" c="$tmp_c" + : Older versions did not always set $sh. Catch re-use of such + : an old config.sh. + case "$sh" in + '') sh="$tmp_sh" ;; + esac hint=previous ;; esac @@ -1555,13 +1665,15 @@ EOM cd hints; ls -C *.sh | $sed 's/\.sh/ /g' >&4 dflt='' : Half the following guesses are probably wrong... If you have better - : tests or hints, please send them to doughera@lafcol.lafayette.edu + : tests or hints, please send them to chip@perl.com : The metaconfig authors would also appreciate a copy... $test -f /irix && osname=irix $test -f /xenix && osname=sco_xenix $test -f /dynix && osname=dynix $test -f /dnix && osname=dnix - $test -f /unicos && osname=unicos && osvers=`$uname -r` + $test -f /lynx.os && osname=lynxos + $test -f /unicos && osname=unicos && osvers=`$uname -r` + $test -f /unicosmk.ar && osname=unicosmk && osvers=`$uname -r` $test -f /bin/mips && /bin/mips && osname=mips $test -d /NextApps && set X `hostinfo | grep 'NeXT Mach.*:' | \ $sed -e 's/://' -e 's/\./_/'` && osname=next && osvers=$4 @@ -1593,7 +1705,6 @@ EOM esac;; [23]100) osname=mips ;; next*) osname=next ;; - news*) osname=news ;; i386*) if $test -f /etc/kconfig; then osname=isc @@ -1619,6 +1730,9 @@ EOM *) osvers=$tmp;; esac ;; + *dc.osx) osname=dcosx + osvers="$3" + ;; dnix) osname=dnix osvers="$3" ;; @@ -1628,6 +1742,9 @@ EOM dgux) osname=dgux osvers="$3" ;; + dynixptx*) osname=dynixptx + osvers="$3" + ;; freebsd) osname=freebsd osvers="$3" ;; genix) osname=genix ;; @@ -1639,7 +1756,7 @@ EOM *) osvers="$3" ;; esac ;; - irix) osname=irix + irix*) osname=irix case "$3" in 4*) osvers=4 ;; 5*) osvers=5 ;; @@ -1648,16 +1765,25 @@ EOM ;; linux) osname=linux case "$3" in - 1*) osvers=1 ;; *) osvers="$3" ;; esac ;; netbsd*) osname=netbsd osvers="$3" ;; + news-os) osvers="$3" + case "$3" in + 4*) osname=newsos4 ;; + *) osname=newsos ;; + esac + ;; bsd386) osname=bsd386 osvers=`$uname -r` ;; + powerux | power_ux | powermax_os | powermaxos | \ + powerunix | power_unix) osname=powerux + osvers="$3" + ;; next*) osname=next ;; solaris) osname=solaris case "$3" in @@ -1684,7 +1810,7 @@ EOM ultrix) osname=ultrix osvers="$3" ;; - osf1) case "$5" in + osf1|mls+) case "$5" in alpha) osname=dec_osf osvers=`echo "$3" | sed 's/^[vt]//'` @@ -1696,10 +1822,13 @@ EOM uts) osname=uts osvers="$3" ;; + qnx) osname=qnx + osvers="$4" + ;; $2) case "$osname" in *isc*) ;; *freebsd*) ;; - svr*) + svr*) : svr4.x or possibly later case "svr$3" in ${osname}*) @@ -1752,10 +1881,10 @@ EOM ;; esac else - if test -f /vmunix -a -f news_os.sh; then + if test -f /vmunix -a -f newsos4.sh; then (what /vmunix | ../UU/tr '[A-Z]' '[a-z]') > ../UU/kernel.what 2>&1 if $contains news-os ../UU/kernel.what >/dev/null 2>&1; then - osname=news_os + osname=newsos4 fi $rm -f ../UU/kernel.what elif test -d c:/.; then @@ -1858,6 +1987,7 @@ cd UU tmp_c="$c" cd .. cp $config_sh config.sh 2>/dev/null + chmod +w config.sh . ./config.sh cd UU cp ../config.sh . @@ -1897,13 +2027,39 @@ case "$ans" in none) osname='' ;; *) osname=`echo "$ans" | $sed -e 's/[ ][ ]*/_/g' | ./tr '[A-Z]' '[a-z]'`;; esac +echo " " +case "$osvers" in + ''|' ') + case "$hintfile" in + ''|' '|none) dflt=none ;; + *) dflt=`echo $hintfile | $sed -e 's/\.sh$//' -e 's/^[^_]*//'` + dflt=`echo $dflt | $sed -e 's/^_//' -e 's/_/./g'` + case "$dflt" in + ''|' ') dflt=none ;; + esac + ;; + esac + ;; + *) dflt="$osvers" ;; +esac +rp="Operating system version?" +. ./myread +case "$ans" in +none) osvers='' ;; +*) osvers="$ans" ;; +esac + + + : who configured the system -cf_time=`$date 2>&1` -(logname > .temp) >/dev/null 2>&1 -$test -s .temp || (whoami > .temp) >/dev/null 2>&1 -$test -s .temp || echo unknown > .temp -cf_by=`$cat .temp` -$rm -f .temp +cf_time=`LC_ALL=C; export LC_ALL; $date 2>&1` +cf_by=`(logname) 2>/dev/null` +case "$cf_by" in "") + cf_by=`(whoami) 2>/dev/null` + case "$cf_by" in "") + cf_by=unknown ;; + esac ;; +esac : determine the architecture name echo " " @@ -1911,7 +2067,8 @@ if xxx=`./loc arch blurfl $pth`; $test -f "$xxx"; then tarch=`arch`"-$osname" elif xxx=`./loc uname blurfl $pth`; $test -f "$xxx" ; then if uname -m > tmparch 2>&1 ; then - tarch=`$sed -e 's/ /_/g' -e 's/$/'"-$osname/" tmparch` + tarch=`$sed -e 's/ *$//' -e 's/ /_/g' \ + -e 's/$/'"-$osname/" tmparch` else tarch="$osname" fi @@ -1935,16 +2092,22 @@ rp='What is your architecture name' archname="$ans" myarchname="$tarch" -if [ -z "$afs" ]; then - : is AFS running? - echo " " - if test -d /afs; then - echo "AFS may be running... I'll be extra cautious then..." >&4 +: is AFS running? +echo " " +case "$afs" in +$define|true) afs=true ;; +$undef|false) afs=false ;; +*) if test -d /afs; then afs=true else - echo "AFS does not seem to be running..." >&4 - afs=false + afs=false fi + ;; +esac +if test $afs = "true"; then + echo "AFS may be running... I'll be extra cautious then..." >&4 +else + echo "AFS does not seem to be running..." >&4 fi : decide how portable to be. Allow command line overrides. @@ -1994,7 +2157,10 @@ chmod +x filexp $eunicefix filexp : now set up to get a file name -cat <<'EOSC' >getfile +cat <<EOS >getfile +$startsh +EOS +cat <<'EOSC' >>getfile tilde='' fullpath='' already='' @@ -2309,13 +2475,20 @@ baserev=5.0 echo " " echo "Getting the current patchlevel..." >&4 if $test -r ../patchlevel.h;then - patchlevel=`awk '/PATCHLEVEL/ {print $3}' < ../patchlevel.h` - subversion=`awk '/SUBVERSION/ {print $3}' < ../patchlevel.h` + patchlevel=`awk '/PATCHLEVEL/ {print $3}' ../patchlevel.h` + subversion=`awk '/SUBVERSION/ {print $3}' ../patchlevel.h` else patchlevel=0 subversion=0 fi -echo "(You have $package $baserev PL$patchlevel sub$subversion.)" +$echo $n "(You have $package" $c +case "$package" in +"*$baserev") ;; +*) $echo $n " $baserev" $c ;; +esac +$echo $n " patchlevel $patchlevel" $c +test 0 -eq "$subversion" || $echo $n " subversion $subversion" $c +echo ".)" : set the prefixup variable, to restore leading tilda escape prefixup='case "$prefixexp" in @@ -2328,19 +2501,27 @@ set archlib archlib eval $prefixit case "$archlib" in '') - case "$privlib" in - '') - dflt=`./loc . "." $prefixexp/lib /usr/local/lib /usr/lib /lib` - set dflt - eval $prefixup - ;; - *) version=`echo $baserev $patchlevel $subversion | \ - $awk '{print $1 + $2/1000.0 + $3/100000.0}'` - dflt="$privlib/$archname/$version" - ;; - esac + case "$privlib" in + '') dflt=`./loc . "." $prefixexp/lib /usr/local/lib /usr/lib /lib` + set dflt + eval $prefixup ;; -*) dflt="$archlib";; + *) if test 0 -eq "$subversion"; then + version=`LC_ALL=C; export LC_ALL; \ + echo $baserev $patchlevel | \ + $awk '{ printf "%.3f\n", $1 + $2/1000.0 }'` + else + version=`LC_ALL=C; export LC_ALL; \ + echo $baserev $patchlevel $subversion | \ + $awk '{ printf "%.5f\n", $1 + $2/1000.0 + $3/100000.0 }'` + fi + dflt="$privlib/$archname/$version" + ;; + esac + ;; +*) + dflt="$archlib" + ;; esac cat <<EOM @@ -2359,9 +2540,10 @@ archlibexp="$ansexp" if $afs; then $cat <<EOM -Since you are running AFS, I need to distinguish the directory in which -private files reside from the directory in which they are installed (and from -which they are presumably copied to the former directory by occult means). +Since you are running AFS, I need to distinguish the directory in +which architecture-dependent library files reside from the directory +in which they are installed (and from which they are presumably copied +to the former directory by occult means). EOM case "$installarchlib" in @@ -2382,7 +2564,10 @@ else fi : set up the script used to warn in case of inconsistency -cat <<'EOSC' >whoa +cat <<EOS >whoa +$startsh +EOS +cat <<'EOSC' >>whoa dflt=y echo " " echo "*** WHOA THERE!!! ***" >&4 @@ -2402,6 +2587,33 @@ $undef$define) . ./whoa; eval "$var=\$tu";; *) eval "$var=$val";; esac' +$cat <<EOM + +Perl 5.004 can be compiled for binary compatibility with 5.003. +If you decide to do so, you will be able to continue using any +extensions that were compiled for Perl 5.003. However, binary +compatibility forces Perl to expose some of its internal symbols +in the same way that 5.003 did. So you may have symbol conflicts +if you embed a binary-compatible Perl in other programs. + +EOM +case "$d_bincompat3" in +"$undef") dflt=n ;; +*) dflt=y ;; +esac +rp='Binary compatibility with Perl 5.003?' +. ./myread +case "$ans" in +y*) val="$define" ;; +*) val="$undef" ;; +esac +set d_bincompat3 +eval $setvar +case "$d_bincompat3" in +"$define") bincompat3=y ;; +*) bincompat3=n ;; +esac + : make some quick guesses about what we are up against echo " " $echo $n "Hmm... $c" @@ -2412,6 +2624,7 @@ echo exit 1 >osf1 echo exit 1 >eunice echo exit 1 >xenix echo exit 1 >venix +echo exit 1 >os2 d_bsd="$undef" $cat /usr/include/signal.h /usr/include/sys/signal.h >foo 2>/dev/null if test -f /osf_boot || $contains 'OSF/1' /usr/include/ctype.h >/dev/null 2>&1 @@ -2456,6 +2669,17 @@ EOI d_eunice="$undef" ;; esac +: Detect OS2. The p_ variable is set above in the Head.U unit. +case "$p_" in +:) ;; +*) + $cat <<'EOI' +I have the feeling something is not exactly right, however...don't tell me... +lemme think...does HAL ring a bell?...no, of course, you're only running OS/2! +EOI + echo exit 0 >os2 + ;; +esac if test -f /xenix; then echo "Actually, this looks more like a XENIX system..." echo exit 0 >xenix @@ -2478,8 +2702,8 @@ else echo "Nor is it Venix..." fi fi -chmod +x bsd usg v7 osf1 eunice xenix venix -$eunicefix bsd usg v7 osf1 eunice xenix venix +chmod +x bsd usg v7 osf1 eunice xenix venix os2 +$eunicefix bsd usg v7 osf1 eunice xenix venix os2 $rm -f foo : see if setuid scripts can be secure @@ -2551,6 +2775,7 @@ EOM fi else echo "I don't think setuid scripts are secure (no /dev/fd directory)." >&4 + echo "(That's for file descriptors, not floppy disks.)" val="$undef" fi set d_suidsafe @@ -2617,9 +2842,10 @@ sitelibexp="$ansexp" if $afs; then $cat <<EOM -Since you are running AFS, I need to distinguish the directory in which -private files reside from the directory in which they are installed (and from -which they are presumably copied to the former directory by occult means). +Since you are running AFS, I need to distinguish the directory in +which site-specific files reside from the directory in which they are +installed (and from which they are presumably copied to the former +directory by occult means). EOM case "$installsitelib" in @@ -2627,7 +2853,7 @@ EOM *) dflt="$installsitelib";; esac fn=de~ - rp='Where will private files be installed?' + rp='Where will site-specific files be installed?' . ./getfile installsitelib="$ans" else @@ -2660,9 +2886,10 @@ sitearchexp="$ansexp" if $afs; then $cat <<EOM -Since you are running AFS, I need to distinguish the directory in which -private files reside from the directory in which they are installed (and from -which they are presumably copied to the former directory by occult means). +Since you are running AFS, I need to distinguish the directory in +which site-specific architecture-dependent library files reside from +the directory in which they are installed (and from which they are +presumably copied to the former directory by occult means). EOM case "$installsitearch" in @@ -2670,7 +2897,7 @@ EOM *) dflt="$installsitearch";; esac fn=de~ - rp='Where will private files be installed?' + rp='Where will site-specific architecture-dependent files be installed?' . ./getfile installsitearch="$ans" else @@ -2693,12 +2920,13 @@ if $test ! -d "$dflt/auto"; then fi cat <<EOM -In 5.001, Perl stored architecture-dependent library files in a library +In 5.001, Perl stored architecture-dependent library files in a directory with a name such as $privlib/$archname, and this directory contained files from the standard extensions and files from any additional extensions you might have added. Starting with version 5.002, all the architecture-dependent standard extensions -will go into $archlib, +will go into a version-specific directory such as +$archlib, while locally-added extensions will go into $sitearch. @@ -2770,264 +2998,6 @@ else echo "Could not find manual pages in source form." >&4 fi -: determine where manual pages go -set man1dir man1dir none -eval $prefixit -$cat <<EOM - -$spackage has manual pages available in source form. -EOM -case "$nroff" in -nroff) - echo "However, you don't have nroff, so they're probably useless to you." - case "$man1dir" in - '') man1dir="none";; - esac;; -esac -echo "If you don't want the manual sources installed, answer 'none'." -case "$man1dir" in -' ') dflt=none - ;; -'') - lookpath="$prefixexp/man/man1 $prefixexp/man/l_man/man1" - lookpath="$lookpath $prefixexp/man/p_man/man1" - lookpath="$lookpath $prefixexp/man/u_man/man1" - lookpath="$lookpath $prefixexp/man/man.1" - : If prefix contains 'perl' then we want to keep the man pages - : under the prefix directory. Otherwise, look in a variety of - : other possible places. This is debatable, but probably a - : good compromise. Well, apparently not. - : Experience has shown people expect man1dir to be under prefix, - : so we now always put it there. Users who want other behavior - : can answer interactively or use a command line option. - : Does user have System V-style man paths. - case "$sysman" in - */?_man*) dflt=`./loc . $prefixexp/l_man/man1 $lookpath` ;; - *) dflt=`./loc . $prefixexp/man/man1 $lookpath` ;; - esac - set dflt - eval $prefixup - ;; -*) dflt="$man1dir" - ;; -esac -echo " " -fn=dn+~ -rp="Where do the main $spackage manual pages (source) go?" -. ./getfile -if $test "X$man1direxp" != "X$ansexp"; then - installman1dir='' -fi -man1dir="$ans" -man1direxp="$ansexp" -case "$man1dir" in -'') man1dir=' ' - installman1dir='';; -esac -if $afs; then - $cat <<EOM - -Since you are running AFS, I need to distinguish the directory in which -manual pages reside from the directory in which they are installed (and from -which they are presumably copied to the former directory by occult means). - -EOM - case "$installman1dir" in - '') dflt=`echo $man1direxp | sed 's#^/afs/#/afs/.#'`;; - *) dflt="$installman1dir";; - esac - fn=de~ - rp='Where will man pages be installed?' - . ./getfile - installman1dir="$ans" -else - installman1dir="$man1direxp" -fi - -: What suffix to use on installed man pages - -case "$man1dir" in -' ') - man1ext='0' - ;; -*) - rp="What suffix should be used for the main $spackage man pages?" - case "$man1ext" in - '') case "$man1dir" in - *1) dflt=1 ;; - *1p) dflt=1p ;; - *1pm) dflt=1pm ;; - *l) dflt=l;; - *n) dflt=n;; - *o) dflt=o;; - *p) dflt=p;; - *C) dflt=C;; - *L) dflt=L;; - *L1) dflt=L1;; - *) dflt=1;; - esac - ;; - *) dflt="$man1ext";; - esac - . ./myread - man1ext="$ans" - ;; -esac - -: see if we can have long filenames -echo " " -rmlist="$rmlist /tmp/cf$$" -$test -d /tmp/cf$$ || mkdir /tmp/cf$$ -first=123456789abcdef -second=/tmp/cf$$/$first -$rm -f $first $second -if (echo hi >$first) 2>/dev/null; then - if $test -f 123456789abcde; then - echo 'You cannot have filenames longer than 14 characters. Sigh.' >&4 - val="$undef" - else - if (echo hi >$second) 2>/dev/null; then - if $test -f /tmp/cf$$/123456789abcde; then - $cat <<'EOM' -That's peculiar... You can have filenames longer than 14 characters, but only -on some of the filesystems. Maybe you are using NFS. Anyway, to avoid problems -I shall consider your system cannot support long filenames at all. -EOM - val="$undef" - else - echo 'You can have filenames longer than 14 characters.' >&4 - val="$define" - fi - else - $cat <<'EOM' -How confusing! Some of your filesystems are sane enough to allow filenames -longer than 14 characters but some others like /tmp can't even think about them. -So, for now on, I shall assume your kernel does not allow them at all. -EOM - val="$undef" - fi - fi -else - $cat <<'EOM' -You can't have filenames longer than 14 chars. You can't even think about them! -EOM - val="$undef" -fi -set d_flexfnam -eval $setvar -$rm -rf /tmp/cf$$ 123456789abcde* - -: determine where library module manual pages go -set man3dir man3dir none -eval $prefixit -$cat <<EOM - -$spackage has manual pages for many of the library modules. -EOM - -case "$nroff" in -nroff) - $cat <<'EOM' -However, you don't have nroff, so they're probably useless to you. -You can use the supplied perldoc script instead. -EOM - case "$man3dir" in - '') man3dir="none";; - esac;; -esac - -case "$d_flexfnam" in -undef) - $cat <<'EOM' -However, your system can't handle the long file names like File::Basename.3. -You can use the supplied perldoc script instead. -EOM - case "$man3dir" in - '') man3dir="none";; - esac;; -esac - -echo "If you don't want the manual sources installed, answer 'none'." -: We dont use /usr/local/man/man3 because some man programs will -: only show the /usr/local/man/man3 contents, and not the system ones, -: thus man less will show the perl module less.pm, but not the system -: less command. We might also conflict with TCL man pages. -: However, something like /opt/perl/man/man3 is fine. -case "$man3dir" in -'') case "$prefix" in - *perl*) dflt=`echo $man1dir | - $sed -e 's/man1/man3/g' -e 's/man\.1/man\.3/g'` ;; - *) dflt="$privlib/man/man3" ;; - esac - ;; -' ') dflt=none;; -*) dflt="$man3dir" ;; -esac -echo " " - -fn=dn+~ -rp="Where do the $spackage library man pages (source) go?" -. ./getfile -if test "X$man3direxp" != "X$ansexp"; then - installman3dir='' -fi - -man3dir="$ans" -man3direxp="$ansexp" -case "$man3dir" in -'') man3dir=' ' - installman3dir='';; -esac -if $afs; then - $cat <<EOM - -Since you are running AFS, I need to distinguish the directory in which -manual pages reside from the directory in which they are installed (and from -which they are presumably copied to the former directory by occult means). - -EOM - case "$installman3dir" in - '') dflt=`echo $man3direxp | sed 's#^/afs/#/afs/.#'`;; - *) dflt="$installman3dir";; - esac - fn=de~ - rp='Where will man pages be installed?' - . ./getfile - installman3dir="$ans" -else - installman3dir="$man3direxp" -fi - -: What suffix to use on installed man pages - -case "$man3dir" in -' ') - man3ext='0' - ;; -*) - rp="What suffix should be used for the $spackage library man pages?" - case "$man3ext" in - '') case "$man3dir" in - *3) dflt=3 ;; - *3p) dflt=3p ;; - *3pm) dflt=3pm ;; - *l) dflt=l;; - *n) dflt=n;; - *o) dflt=o;; - *p) dflt=p;; - *C) dflt=C;; - *L) dflt=L;; - *L3) dflt=L3;; - *) dflt=3;; - esac - ;; - *) dflt="$man3ext";; - esac - . ./myread - man3ext="$ans" - ;; -esac - : see what memory models we can support case "$models" in '') @@ -3040,8 +3010,8 @@ main() { #endif } EOP - cc -o pdp11 pdp11.c >/dev/null 2>&1 - if ./pdp11 2>/dev/null; then + (cc -o pdp11 pdp11.c) >/dev/null 2>&1 + if $test -f pdp11 && ./pdp11 2>/dev/null; then dflt='unsplit split' else tans=`./loc . X /lib/small /lib/large /usr/lib/small /usr/lib/large /lib/medium /usr/lib/medium /lib/huge` @@ -3296,377 +3266,176 @@ y) fn=d/ ;; esac -: see if we have to deal with yellow pages, now NIS. -if $test -d /usr/etc/yp || $test -d /etc/yp; then - if $test -f /usr/etc/nibindd; then - echo " " - echo "I'm fairly confident you're on a NeXT." - echo " " - rp='Do you get the hosts file via NetInfo?' - dflt=y - case "$hostcat" in - nidump*) ;; - '') ;; - *) dflt=n;; - esac - . ./myread - case "$ans" in - y*) hostcat='nidump hosts .';; - *) case "$hostcat" in - nidump*) hostcat='';; - esac - ;; - esac - fi - case "$hostcat" in - nidump*) ;; - *) - case "$hostcat" in - *ypcat*) dflt=y;; - '') if $contains '^\+' /etc/passwd >/dev/null 2>&1; then - dflt=y - else - dflt=n - fi;; - *) dflt=n;; - esac - echo " " - rp='Are you getting the hosts file via yellow pages?' - . ./myread - case "$ans" in - y*) hostcat='ypcat hosts';; - *) hostcat='cat /etc/hosts';; - esac - ;; - esac -fi - -: now get the host name -echo " " -echo "Figuring out host name..." >&4 -case "$myhostname" in -'') cont=true - echo 'Maybe "hostname" will work...' - if tans=`sh -c hostname 2>&1` ; then - myhostname=$tans - phostname=hostname - cont='' - fi - ;; -*) cont='';; +: Set private lib path +case "$plibpth" in +'') if ./mips; then + plibpth="$incpath/usr/lib /usr/local/lib /usr/ccs/lib" + fi;; +esac +case "$libpth" in +' ') dlist='';; +'') dlist="$loclibpth $plibpth $glibpth";; +*) dlist="$libpth";; esac -if $test "$cont"; then - if ./xenix; then - echo 'Oh, dear. Maybe "/etc/systemid" is the key...' - if tans=`cat /etc/systemid 2>&1` ; then - myhostname=$tans - phostname='cat /etc/systemid' - echo "Whadyaknow. Xenix always was a bit strange..." - cont='' - fi - elif $test -r /etc/systemid; then - echo "(What is a non-Xenix system doing with /etc/systemid?)" - fi -fi -if $test "$cont"; then - echo 'No, maybe "uuname -l" will work...' - if tans=`sh -c 'uuname -l' 2>&1` ; then - myhostname=$tans - phostname='uuname -l' - else - echo 'Strange. Maybe "uname -n" will work...' - if tans=`sh -c 'uname -n' 2>&1` ; then - myhostname=$tans - phostname='uname -n' - else - echo 'Oh well, maybe I can mine it out of whoami.h...' - if tans=`sh -c $contains' sysname $usrinc/whoami.h' 2>&1` ; then - myhostname=`echo "$tans" | $sed 's/^.*"\(.*\)"/\1/'` - phostname="sed -n -e '"'/sysname/s/^.*\"\\(.*\\)\"/\1/{'"' -e p -e q -e '}' <$usrinc/whoami.h" - else - case "$myhostname" in - '') echo "Does this machine have an identity crisis or something?" - phostname='';; - *) - echo "Well, you said $myhostname before..." - phostname='echo $myhostname';; - esac - fi - fi - fi -fi -: you do not want to know about this -set $myhostname -myhostname=$1 - -: verify guess -if $test "$myhostname" ; then - dflt=y - rp='Your host name appears to be "'$myhostname'".'" Right?" - . ./myread - case "$ans" in - y*) ;; - *) myhostname='';; - esac -fi -: bad guess or no guess -while $test "X$myhostname" = X ; do - dflt='' - rp="Please type the (one word) name of your host:" - . ./myread - myhostname="$ans" +: Now check and see which directories actually exist, avoiding duplicates +libpth='' +for xxx in $dlist +do + if $test -d $xxx; then + case " $libpth " in + *" $xxx "*) ;; + *) libpth="$libpth $xxx";; + esac + fi done +$cat <<'EOM' -: translate upper to lower if necessary -case "$myhostname" in -*[A-Z]*) - echo "(Normalizing case in your host name)" - myhostname=`echo $myhostname | ./tr '[A-Z]' '[a-z]'` - ;; -esac +Some systems have incompatible or broken versions of libraries. Among +the directories listed in the question below, please remove any you +know not to be holding relevant libraries, and add any that are needed. +Say "none" for none. -case "$myhostname" in -*.*) - dflt=`expr "X$myhostname" : "X[^.]*\(\..*\)"` - myhostname=`expr "X$myhostname" : "X\([^.]*\)\."` - echo "(Trimming domain name from host name--host name is now $myhostname)" +EOM +case "$libpth" in +'') dflt='none';; +*) + set X $libpth + shift + dflt=${1+"$@"} ;; -*) case "$mydomain" in - '') - { - : If we use NIS, try ypmatch. - : Is there some reason why this was not done before? - test "X$hostcat" = "Xypcat hosts" && - ypmatch "$myhostname" hosts 2>/dev/null |\ - $sed -e 's/[ ]*#.*//; s/$/ /' > hosts && \ - $test -s hosts - } || { - : Extract only the relevant hosts, reducing file size, - : remove comments, insert trailing space for later use. - $hostcat | $sed -n -e "s/[ ]*#.*//; s/\$/ / - /[ ]$myhostname[ . ]/p" > hosts - } - tmp_re="[ . ]" - $test x`$awk "/[0-9].*[ ]$myhostname$tmp_re/ { sum++ } - END { print sum }" hosts` = x1 || tmp_re="[ ]" - dflt=.`$awk "/[0-9].*[ ]$myhostname$tmp_re/ {for(i=2; i<=NF;i++) print \\\$i}" \ - hosts | $sort | $uniq | \ - $sed -n -e "s/$myhostname\.\([-a-zA-Z0-9_.]\)/\1/p"` - case `$echo X$dflt` in - X*\ *) echo "(Several hosts in /etc/hosts matched hostname)" - dflt=. - ;; - .) echo "(You do not have fully-qualified names in /etc/hosts)" - ;; - esac - case "$dflt" in - .) - tans=`./loc resolv.conf X /etc /usr/etc` - if $test -f "$tans"; then - echo "(Attempting domain name extraction from $tans)" - : Why was there an Egrep here, when Sed works? - dflt=.`$sed -n -e 's/^domain[ ]*\(.*\)/\1/p' $tans \ - | ./tr '[A-Z]' '[a-z]' 2>/dev/null` - fi - ;; - esac - case "$dflt" in - .) echo "(No help from resolv.conf either -- attempting clever guess)" - dflt=.`sh -c domainname 2>/dev/null` - case "$dflt" in - '') dflt='.';; - .nis.*|.yp.*|.main.*) dflt=`echo $dflt | $sed -e 's/^\.[^.]*//'`;; - esac - ;; - esac - case "$dflt" in - .) echo "(Lost all hope -- silly guess then)" - dflt='.uucp' - ;; - esac - $rm -f hosts - ;; - *) dflt="$mydomain";; - esac;; esac -echo " " -rp="What is your domain name?" +rp="Directories to use for library searches?" . ./myread -tans="$ans" case "$ans" in -'') ;; -.*) ;; -*) tans=".$tans";; +none) libpth=' ';; +*) libpth="$ans";; esac -mydomain="$tans" -: translate upper to lower if necessary -case "$mydomain" in -*[A-Z]*) - echo "(Normalizing case in your domain name)" - mydomain=`echo $mydomain | ./tr '[A-Z]' '[a-z]'` - ;; +: Define several unixisms. Hints files or command line options +: can be used to override them. +case "$ar" in +'') ar='ar';; +esac +case "$lib_ext" in +'') lib_ext='.a';; +esac +case "$obj_ext" in +'') obj_ext='.o';; +esac +case "$path_sep" in +'') path_sep=':';; +esac +: Which makefile gets called first. This is used by make depend. +case "$firstmakefile" in +'') firstmakefile='makefile';; esac -: a little sanity check here -case "$phostname" in -'') ;; -*) - case `$phostname | ./tr '[A-Z]' '[a-z]'` in - $myhostname$mydomain|$myhostname) ;; - *) - case "$phostname" in - sed*) - echo "(That doesn't agree with your whoami.h file, by the way.)" - ;; - *) - echo "(That doesn't agree with your $phostname command, by the way.)" - ;; - esac - ;; - esac +: compute shared library extension +case "$so" in +'') + if xxx=`./loc libc.sl X $libpth`; $test -f "$xxx"; then + dflt='sl' + else + dflt='so' + fi ;; +*) dflt="$so";; esac - $cat <<EOM -I need to get your e-mail address in Internet format if possible, i.e. -something like user@host.domain. Please answer accurately since I have -no easy means to double check it. The default value provided below -is most probably close to the reality but may not be valid from outside -your organization... +On some systems, shared libraries may be available. Answer 'none' if +you want to suppress searching of shared libraries for the remaining +of this configuration. EOM -cont=x -while test "$cont"; do - case "$cf_email" in - '') dflt="$cf_by@$myhostname$mydomain";; - *) dflt="$cf_email";; - esac - rp='What is your e-mail address?' - . ./myread - cf_email="$ans" - case "$cf_email" in - *@*.*) cont='' ;; - *) - rp='Address does not look like an Internet one. Use it anyway?' - case "$fastread" in - yes) dflt=y ;; - *) dflt=n ;; +rp='What is the file extension used for shared libraries?' +. ./myread +so="$ans" + +: Looking for optional libraries +echo " " +echo "Checking for optional libraries..." >&4 +case "$libs" in +' '|'') dflt='';; +*) dflt="$libs";; +esac +case "$libswanted" in +'') libswanted='c_s';; +esac +for thislib in $libswanted; do + + if xxx=`./loc lib$thislib.$so.[0-9]'*' X $libpth`; $test -f "$xxx"; then + echo "Found -l$thislib (shared)." + case " $dflt " in + *"-l$thislib "*);; + *) dflt="$dflt -l$thislib";; esac - . ./myread - case "$ans" in - y*) cont='' ;; - *) echo " " ;; + elif xxx=`./loc lib$thislib.$so X $libpth` ; $test -f "$xxx"; then + echo "Found -l$thislib (shared)." + case " $dflt " in + *"-l$thislib "*);; + *) dflt="$dflt -l$thislib";; esac - ;; - esac + elif xxx=`./loc lib$thislib$lib_ext X $libpth`; $test -f "$xxx"; then + echo "Found -l$thislib." + case " $dflt " in + *"-l$thislib "*);; + *) dflt="$dflt -l$thislib";; + esac + elif xxx=`./loc $thislib$lib_ext X $libpth`; $test -f "$xxx"; then + echo "Found -l$thislib." + case " $dflt " in + *"-l$thislib "*);; + *) dflt="$dflt -l$thislib";; + esac + elif xxx=`./loc lib${thislib}_s$lib_ext X $libpth`; $test -f "$xxx"; then + echo "Found -l${thislib}_s." + case " $dflt " in + *"-l$thislib "*);; + *) dflt="$dflt -l${thislib}_s";; + esac + elif xxx=`./loc Slib$thislib$lib_ext X $xlibpth`; $test -f "$xxx"; then + echo "Found -l$thislib." + case " $dflt " in + *"-l$thislib "*);; + *) dflt="$dflt -l$thislib";; + esac + else + echo "No -l$thislib." + fi done - -$cat <<EOM - -If you or somebody else will be maintaining perl at your site, please -fill in the correct e-mail address here so that they may be contacted -if necessary. Currently, the "perlbug" program included with perl -will send mail to this address in addition to perlbug@perl.com. You may -enter "none" for no administrator. - -EOM -case "$perladmin" in -'') dflt="$cf_email";; -*) dflt="$perladmin";; +set X $dflt +shift +dflt="$*" +case "$libs" in +'') dflt="$dflt";; +*) dflt="$libs";; esac -rp='Perl administrator e-mail address' -. ./myread -perladmin="$ans" - -: determine where public executable scripts go -set scriptdir scriptdir -eval $prefixit -case "$scriptdir" in -'') - dflt="$bin" - : guess some guesses - $test -d /usr/share/scripts && dflt=/usr/share/scripts - $test -d /usr/share/bin && dflt=/usr/share/bin - $test -d /usr/local/script && dflt=/usr/local/script - $test -d $prefixexp/script && dflt=$prefixexp/script - set dflt - eval $prefixup - ;; -*) dflt="$scriptdir" - ;; +case "$dflt" in +' '|'') dflt='none';; esac + $cat <<EOM -Some installations have a separate directory just for executable scripts so -that they can mount it across multiple architectures but keep the scripts in -one spot. You might, for example, have a subdirectory of /usr/share for this. -Or you might just lump your scripts in with all your other executables. - -EOM -fn=d~ -rp='Where do you keep publicly executable scripts?' -. ./getfile -if $test "X$ansexp" != "X$scriptdirexp"; then - installscript='' -fi -scriptdir="$ans" -scriptdirexp="$ansexp" -if $afs; then - $cat <<EOM - -Since you are running AFS, I need to distinguish the directory in which -scripts reside from the directory in which they are installed (and from -which they are presumably copied to the former directory by occult means). +Some versions of Unix support shared libraries, which make executables smaller +but make load time slightly longer. +On some systems, mostly System V Release 3's, the shared library is included +by putting the option "-lc_s" as the last thing on the cc command line when +linking. Other systems use shared libraries by default. There may be other +libraries needed to compile $package on your machine as well. If your system +needs the "-lc_s" option, include it here. Include any other special libraries +here as well. Say "none" for none. EOM - case "$installscript" in - '') dflt=`echo $scriptdirexp | sed 's#^/afs/#/afs/.#'`;; - *) dflt="$installscript";; - esac - fn=de~ - rp='Where will public scripts be installed?' - . ./getfile - installscript="$ans" -else - installscript="$scriptdirexp" -fi - -: determine perl absolute location -case "$perlpath" in -'') perlpath=$binexp/perl ;; -esac - -: figure out how to guarantee perl startup -case "$startperl" in -'') - case "$sharpbang" in - *!) - $cat <<EOH - -I can use the #! construct to start perl on your system. This will -make startup of perl scripts faster, but may cause problems if you -want to share those scripts and perl is not in a standard place -($perlpath) on all your platforms. The alternative is to force -a shell by starting the script with a single ':' character. -EOH - dflt=$perlpath - rp='What shall I put after the #! to start up perl ("none" to not use #!)?' - . ./myread - case "$ans" in - none) startperl=": # use perl";; - *) startperl="#!$ans";; - esac - ;; - *) startperl=": # use perl" - ;; - esac - ;; +echo " " +rp="Any additional libraries?" +. ./myread +case "$ans" in +none) libs=' ';; +*) libs="$ans";; esac -echo "I'll use $startperl to start perl scripts." : see how we invoke the C preprocessor echo " " @@ -3806,61 +3575,15 @@ case "$cppstdin" in esac $rm -f testcpp.c testcpp.out -: Set private lib path -case "$plibpth" in -'') if ./mips; then - plibpth="$incpath/usr/lib /usr/local/lib /usr/ccs/lib" - fi;; -esac -case "$libpth" in -' ') dlist='';; -'') dlist="$loclibpth $plibpth $glibpth";; -*) dlist="$libpth";; -esac - -: Now check and see which directories actually exist, avoiding duplicates -libpth='' -for xxx in $dlist -do - if $test -d $xxx; then - case " $libpth " in - *" $xxx "*) ;; - *) libpth="$libpth $xxx";; - esac - fi -done -$cat <<'EOM' - -Some systems have incompatible or broken versions of libraries. Among -the directories listed in the question below, please remove any you -know not to be holding relevant libraries, and add any that are needed. -Say "none" for none. - -EOM -case "$libpth" in -'') dflt='none';; -*) - set X $libpth - shift - dflt=${1+"$@"} - ;; -esac -rp="Directories to use for library searches?" -. ./myread -case "$ans" in -none) libpth=' ';; -*) libpth="$ans";; -esac - : determine optimize, if desired, or use for debug flag also case "$optimize" in -' ') dflt='none';; +' '|$undef) dflt='none';; '') dflt='-O';; *) dflt="$optimize";; esac $cat <<EOH -Some C compilers have problems with their optimizers, by default, $package +Some C compilers have problems with their optimizers. By default, $package compiles with the -O flag to use the optimizer. Alternately, you might want to use the symbolic debugger, which uses the -g flag (on traditional Unix systems). Either flag can be specified here. To use neither flag, specify @@ -3930,8 +3653,6 @@ if ./osf1; then else set signal.h LANGUAGE_C; eval $inctest fi -set signal.h NO_PROTOTYPE; eval $inctest -set signal.h _NO_PROTO; eval $inctest case "$hint" in none|recommended) dflt="$ccflags $dflt" ;; @@ -3992,7 +3713,7 @@ EOM -*) ftry="$flag";; *) ftry="$previous $flag";; esac - if $cppstdin -DLFRULB=bar $ftry $cppminus <cpp.c \ + if $cppstdin -DLFRULB=bar $cppflags $ftry $cppminus <cpp.c \ >cpp1.out 2>/dev/null && \ $cpprun -DLFRULB=bar $ftry $cpplast <cpp.c \ >cpp2.out 2>/dev/null && \ @@ -4070,8 +3791,8 @@ rmlist="$rmlist pdp11" : coherency check echo " " -echo "Checking your choice of C compiler and flags for coherency..." >&4 -set X $cc $optimize $ccflags $ldflags try.c -o try +echo "Checking your choice of C compiler, libs, and flags for coherency..." >&4 +set X $cc $optimize $ccflags $ldflags -o try try.c $libs shift $cat >try.msg <<EOM I've tried to compile and run a simple program with: @@ -4087,22 +3808,22 @@ $cat > try.c <<'EOF' main() { exit(0); } EOF dflt=y -if sh -c "$cc $optimize $ccflags try.c -o try $ldflags" >>try.msg 2>&1; then +if sh -c "$cc $optimize $ccflags -o try try.c $ldflags $libs" >>try.msg 2>&1; then if sh -c './try' >>try.msg 2>&1; then dflt=n else echo "The program compiled OK, but exited with status $?." >>try.msg - rp="You have a problem. Shall I abort Configure" + rp="You have a problem. Shall I abort Configure (and explain the problem)" dflt=y fi else echo "I can't compile the test program." >>try.msg - rp="You have a BIG problem. Shall I abort Configure" + rp="You have a BIG problem. Shall I abort Configure (and explain the problem)" dflt=y fi case "$dflt" in y) - $cat try.msg + $cat try.msg >&4 case "$knowitall" in '') echo "(The supplied flags might be incorrect with this C compiler.)" @@ -4122,121 +3843,43 @@ n) echo "OK, that should do.";; esac $rm -f try try.* core -: compute shared library extension -case "$so" in -'') - if xxx=`./loc libc.sl X $libpth`; $test -f "$xxx"; then - dflt='sl' - else - dflt='so' - fi - ;; -*) dflt="$so";; -esac -$cat <<EOM - -On some systems, shared libraries may be available. Answer 'none' if -you want to suppress searching of shared libraries for the remaining -of this configuration. - -EOM -rp='What is the file extension used for shared libraries?' -. ./myread -so="$ans" - -: Looking for optional libraries echo " " -echo "Checking for optional libraries..." >&4 -case "$libs" in -' '|'') dflt='';; -*) dflt="$libs";; -esac -case "$libswanted" in -'') libswanted='c_s';; -esac -for thislib in $libswanted; do - - if xxx=`./loc lib$thislib.$so.[0-9]'*' X $libpth`; $test -f "$xxx"; then - echo "Found -l$thislib (shared)." - case " $dflt " in - *"-l$thislib "*);; - *) dflt="$dflt -l$thislib";; - esac - elif xxx=`./loc lib$thislib.$so X $libpth` ; $test -f "$xxx"; then - echo "Found -l$thislib (shared)." - case " $dflt " in - *"-l$thislib "*);; - *) dflt="$dflt -l$thislib";; - esac - elif xxx=`./loc lib$thislib.a X $libpth`; $test -f "$xxx"; then - echo "Found -l$thislib." - case " $dflt " in - *"-l$thislib "*);; - *) dflt="$dflt -l$thislib";; - esac - elif xxx=`./loc $thislib.a X $libpth`; $test -f "$xxx"; then - echo "Found -l$thislib." - case " $dflt " in - *"-l$thislib "*);; - *) dflt="$dflt -l$thislib";; - esac - elif xxx=`./loc lib${thislib}_s.a X $libpth`; $test -f "$xxx"; then - echo "Found -l${thislib}_s." - case " $dflt " in - *"-l$thislib "*);; - *) dflt="$dflt -l${thislib}_s";; - esac - elif xxx=`./loc Slib$thislib.a X $xlibpth`; $test -f "$xxx"; then - echo "Found -l$thislib." - case " $dflt " in - *"-l$thislib "*);; - *) dflt="$dflt -l$thislib";; - esac - else - echo "No -l$thislib." - fi -done -set X $dflt -shift -dflt="$*" -case "$libs" in -'') dflt="$dflt";; -*) dflt="$libs";; -esac -case "$dflt" in -' '|'') dflt='none';; -esac - -$cat <<EOM - -Some versions of Unix support shared libraries, which make executables smaller -but make load time slightly longer. - -On some systems, mostly newer Unix System V's, the shared library is included -by putting the option "-lc_s" as the last thing on the cc command line when -linking. Other systems use shared libraries by default. There may be other -libraries needed to compile $package on your machine as well. If your system -needs the "-lc_s" option, include it here. Include any other special libraries -here as well. Say "none" for none. +echo "Checking for GNU C Library..." >&4 +cat >gnulibc.c <<EOM +int +main() +{ + return __libc_main(); +} EOM - -echo " " -rp="Any additional libraries?" -. ./myread -case "$ans" in -none) libs=' ';; -*) libs="$ans";; -esac +if $cc $ccflags $ldflags -o gnulibc gnulibc.c $libs >/dev/null 2>&1 && \ + ./gnulibc | $contains '^GNU C Library' >/dev/null 2>&1; then + val="$define" + echo "You are using the GNU C Library" +else + val="$undef" + echo "You are not using the GNU C Library" +fi +$rm -f gnulibc* +set d_gnulibc +eval $setvar : see if nm is to be used to determine whether a symbol is defined or not case "$usenm" in '') - dflt=`egrep 'inlibc|csym' ../Configure | wc -l 2>/dev/null` - if $test $dflt -gt 20; then - dflt=y - else + case "$d_gnulibc" in + $define) dflt=n - fi + ;; + *) + dflt=`egrep 'inlibc|csym' ../Configure | wc -l 2>/dev/null` + if $test $dflt -gt 20; then + dflt=y + else + dflt=n + fi + ;; + esac ;; *) case "$usenm" in @@ -4253,6 +3896,7 @@ but that should make the symbols extraction faster. The alternative is to skip the 'nm' extraction part and to compile a small test program instead to determine whether each symbol is present. If you have a fast C compiler and/or if your 'nm' output cannot be parsed, this may be the best solution. +You shouldn't let me use 'nm' if you have the GNU C Library. EOM rp='Shall I use nm to extract C symbols from the libraries?' @@ -4270,11 +3914,13 @@ esac : nm options which may be necessary case "$nm_opt" in '') if $test -f /mach_boot; then - nm_opt='' + nm_opt='' # Mach elif $test -d /usr/ccs/lib; then - nm_opt='-p' + nm_opt='-p' # Solaris (and SunOS?) elif $test -f /dgux; then - nm_opt='-p' + nm_opt='-p' # DG-UX + elif $test -f /lib64/rld; then + nm_opt='-p' # 64-bit Irix else nm_opt='' fi;; @@ -4300,7 +3946,7 @@ echo " " case "$libc" in '') libc=unknown case "$libs" in - *-lc_s*) libc=`./loc libc_s.a $libc $libpth` + *-lc_s*) libc=`./loc libc_s$lib_ext $libc $libpth` esac ;; esac @@ -4318,13 +3964,15 @@ case "$libs" in : elif try=`./loc lib$thislib.$so X $libpth`; $test -f "$try"; then : - elif try=`./loc lib$thislib.a X $libpth`; $test -f "$try"; then + elif try=`./loc lib$thislib$lib_ext X $libpth`; $test -f "$try"; then + : + elif try=`./loc $thislib$lib_ext X $libpth`; $test -f "$try"; then : elif try=`./loc lib$thislib X $libpth`; $test -f "$try"; then : elif try=`./loc $thislib X $libpth`; $test -f "$try"; then : - elif try=`./loc Slib$thislib.a X $xlibpth`; $test -f "$try"; then + elif try=`./loc Slib$thislib$lib_ext X $xlibpth`; $test -f "$try"; then : else try='' @@ -4355,7 +4003,7 @@ unknown) eval set \$$# done $test -r $1 || set /usr/ccs/lib/libc.$so - $test -r $1 || set /lib/libsys_s.a + $test -r $1 || set /lib/libsys_s$lib_ext ;; *) set blurfl @@ -4374,25 +4022,25 @@ elif $test -r /lib/libc && $test -r /lib/clib; then fi elif $test -r "$libc" || (test -h "$libc") >/dev/null 2>&1; then echo "Your C library seems to be in $libc, as you said before." -elif $test -r $incpath/usr/lib/libc.a; then - libc=$incpath/usr/lib/libc.a; +elif $test -r $incpath/usr/lib/libc$lib_ext; then + libc=$incpath/usr/lib/libc$lib_ext; echo "Your C library seems to be in $libc. That's fine." -elif $test -r /lib/libc.a; then - libc=/lib/libc.a; +elif $test -r /lib/libc$lib_ext; then + libc=/lib/libc$lib_ext; echo "Your C library seems to be in $libc. You're normal." else - if tans=`./loc libc.a blurfl/dyick $libpth`; $test -r "$tans"; then + if tans=`./loc libc$lib_ext blurfl/dyick $libpth`; $test -r "$tans"; then : elif tans=`./loc libc blurfl/dyick $libpth`; $test -r "$tans"; then libnames="$libnames "`./loc clib blurfl/dyick $libpth` elif tans=`./loc clib blurfl/dyick $libpth`; $test -r "$tans"; then : - elif tans=`./loc Slibc.a blurfl/dyick $xlibpth`; $test -r "$tans"; then + elif tans=`./loc Slibc$lib_ext blurfl/dyick $xlibpth`; $test -r "$tans"; then : - elif tans=`./loc Mlibc.a blurfl/dyick $xlibpth`; $test -r "$tans"; then + elif tans=`./loc Mlibc$lib_ext blurfl/dyick $xlibpth`; $test -r "$tans"; then : else - tans=`./loc Llibc.a blurfl/dyick $xlibpth` + tans=`./loc Llibc$lib_ext blurfl/dyick $xlibpth` fi if $test -r "$tans"; then echo "Your C library seems to be in $tans, of all places." @@ -4455,7 +4103,7 @@ $grep fprintf libc.tmp > libc.ptf xscan='eval "<libc.ptf $com >libc.list"; $echo $n ".$c" >&4' xrun='eval "<libc.tmp $com >libc.list"; echo "done" >&4' xxx='[ADTSIW]' -if com="$sed -n -e 's/__IO//' -e 's/^.* $xxx *_[_.]*//p' -e 's/^.* $xxx //p'";\ +if com="$sed -n -e 's/__IO//' -e 's/^.* $xxx *_[_.]*//p' -e 's/^.* $xxx *//p'";\ eval $xscan;\ $contains '^fprintf$' libc.list >/dev/null 2>&1; then eval $xrun @@ -4492,6 +4140,10 @@ elif com="$sed -n -e 's/^__//' -e '/|Undef/d' -e '/|Proc/s/ .*//p'";\ eval $xscan;\ $contains '^fprintf$' libc.list >/dev/null 2>&1; then eval $xrun +elif com="$sed -n -e 's/^.*|Proc .*|Text *| *//p'";\ + eval $xscan;\ + $contains '^fprintf$' libc.list >/dev/null 2>&1; then + eval $xrun elif com="$sed -n -e '/Def. Text/s/.* \([^ ]*\)\$/\1/p'";\ eval $xscan;\ $contains '^fprintf$' libc.list >/dev/null 2>&1; then @@ -4500,6 +4152,10 @@ elif com="$sed -n -e 's/^[-0-9a-f ]*_\(.*\)=.*/\1/p'";\ eval $xscan;\ $contains '^fprintf$' libc.list >/dev/null 2>&1; then eval $xrun +elif com="$sed -n -e 's/.*\.text n\ \ \ \.//p'";\ + eval $xscan;\ + $contains '^fprintf$' libc.list >/dev/null 2>&1; then + eval $xrun else nm -p $* 2>/dev/null >libc.tmp $grep fprintf libc.tmp > libc.ptf @@ -4546,6 +4202,100 @@ fi esac $rm -f libnames libpath +: determine filename position in cpp output +echo " " +echo "Computing filename position in cpp output for #include directives..." >&4 +echo '#include <stdio.h>' > foo.c +$cat >fieldn <<EOF +$startsh +$cppstdin $cppflags $cppminus <foo.c 2>/dev/null | \ +$grep '^[ ]*#.*stdio\.h' | \ +while read cline; do + pos=1 + set \$cline + while $test \$# -gt 0; do + if $test -r \`echo \$1 | $tr -d '"'\`; then + echo "\$pos" + exit 0 + fi + shift + pos=\`expr \$pos + 1\` + done +done +EOF +chmod +x fieldn +fieldn=`./fieldn` +$rm -f foo.c fieldn +case $fieldn in +'') pos='???';; +1) pos=first;; +2) pos=second;; +3) pos=third;; +*) pos="${fieldn}th";; +esac +echo "Your cpp writes the filename in the $pos field of the line." + +: locate header file +$cat >findhdr <<EOF +$startsh +wanted=\$1 +name='' +if test -f $usrinc/\$wanted; then + echo "$usrinc/\$wanted" + exit 0 +fi +awkprg='{ print \$$fieldn }' +echo "#include <\$wanted>" > foo\$\$.c +$cppstdin $cppminus $cppflags < foo\$\$.c 2>/dev/null | \ +$grep "^[ ]*#.*\$wanted" | \ +while read cline; do + name=\`echo \$cline | $awk "\$awkprg" | $tr -d '"'\` + case "\$name" in + */\$wanted) echo "\$name"; exit 0;; + *) name='';; + esac; +done; +$rm -f foo\$\$.c; +case "\$name" in +'') exit 1;; +esac +EOF +chmod +x findhdr + +: define an alternate in-header-list? function +inhdr='echo " "; td=$define; tu=$undef; yyy=$@; +cont=true; xxf="echo \"<\$1> found.\" >&4"; +case $# in 2) xxnf="echo \"<\$1> NOT found.\" >&4";; +*) xxnf="echo \"<\$1> NOT found, ...\" >&4";; +esac; +case $# in 4) instead=instead;; *) instead="at last";; esac; +while $test "$cont"; do + xxx=`./findhdr $1` + var=$2; eval "was=\$$2"; + if $test "$xxx" && $test -r "$xxx"; + then eval $xxf; + eval "case \"\$$var\" in $undef) . ./whoa; esac"; eval "$var=\$td"; + cont=""; + else eval $xxnf; + eval "case \"\$$var\" in $define) . ./whoa; esac"; eval "$var=\$tu"; fi; + set $yyy; shift; shift; yyy=$@; + case $# in 0) cont="";; + 2) xxf="echo \"but I found <\$1> $instead.\" >&4"; + xxnf="echo \"and I did not find <\$1> either.\" >&4";; + *) xxf="echo \"but I found <\$1\> instead.\" >&4"; + xxnf="echo \"there is no <\$1>, ...\" >&4";; + esac; +done; +while $test "$yyy"; +do set $yyy; var=$2; eval "was=\$$2"; + eval "case \"\$$var\" in $define) . ./whoa; esac"; eval "$var=\$tu"; + set $yyy; shift; shift; yyy=$@; +done' + +: see if dld is available +set dld.h i_dld +eval $inhdr + : is a C symbol defined? csym='tlook=$1; case "$3" in @@ -4609,30 +4359,1194 @@ yes) esac;; esac' +: see if dlopen exists +xxx_runnm="$runnm" +runnm=false +set dlopen d_dlopen +eval $inlibc +runnm="$xxx_runnm" + +: determine which dynamic loading, if any, to compile in +echo " " +dldir="ext/DynaLoader" +case "$usedl" in +$define|y|true) + dflt='y' + usedl="$define" + ;; +$undef|n|false) + dflt='n' + usedl="$undef" + ;; +*) + dflt='n' + case "$d_dlopen" in + $define) dflt='y' ;; + esac + case "$i_dld" in + $define) dflt='y' ;; + esac + : Does a dl_xxx.xs file exist for this operating system + $test -f ../$dldir/dl_${osname}.xs && dflt='y' + ;; +esac +rp="Do you wish to use dynamic loading?" +. ./myread +usedl="$ans" +case "$ans" in +y*) usedl="$define" + case "$dlsrc" in + '') + if $test -f ../$dldir/dl_${osname}.xs ; then + dflt="$dldir/dl_${osname}.xs" + elif $test "$d_dlopen" = "$define" ; then + dflt="$dldir/dl_dlopen.xs" + elif $test "$i_dld" = "$define" ; then + dflt="$dldir/dl_dld.xs" + else + dflt='' + fi + ;; + *) dflt="$dldir/$dlsrc" + ;; + esac + echo "The following dynamic loading files are available:" + : Can not go over to $dldir because getfile has path hard-coded in. + cd ..; ls -C $dldir/dl*.xs; cd UU + rp="Source file to use for dynamic loading" + fn="fne" + . ./getfile + usedl="$define" + : emulate basename + dlsrc=`echo $ans | $sed -e 's@.*/\([^/]*\)$@\1@'` + + $cat << EOM + +Some systems may require passing special flags to $cc -c to +compile modules that will be used to create a shared library. +To use no flags, say "none". + +EOM + case "$cccdlflags" in + '') case "$gccversion" in + '') case "$osname" in + hpux) dflt='+z' ;; + next) dflt='none' ;; + svr4*|esix*) dflt='-Kpic' ;; + irix*) dflt='-KPIC' ;; + solaris) case "$ccflags" in + *-DDEBUGGING*) dflt='-KPIC' ;; + *) dflt='-Kpic' ;; + esac ;; + sunos) dflt='-pic' ;; + *) dflt='none' ;; + esac ;; + *) case "$osname/$ccflags" in + solaris/*-DDEBUGGING*) dflt='-fPIC' ;; + *) dflt='-fpic' ;; + esac ;; + esac ;; + *) dflt="$cccdlflags" ;; + esac + rp="Any special flags to pass to $cc -c to compile shared library modules?" + . ./myread + case "$ans" in + none) cccdlflags=' ' ;; + *) cccdlflags="$ans" ;; + esac + + cat << EOM + +Some systems use ld to create libraries that can be dynamically loaded, +while other systems (such as those using ELF) use $cc. + +EOM + case "$ld" in + '') $cat >try.c <<'EOM' +/* Test for whether ELF binaries are produced */ +#include <fcntl.h> +#include <stdlib.h> +main() { + char b[4]; + int i = open("a.out",O_RDONLY); + if(i == -1) + exit(1); /* fail */ + if(read(i,b,4)==4 && b[0]==127 && b[1]=='E' && b[2]=='L' && b[3]=='F') + exit(0); /* succeed (yes, it's ELF) */ + else + exit(1); /* fail */ +} +EOM + if $cc $ccflags try.c >/dev/null 2>&1 && ./a.out; then + cat <<EOM +You appear to have ELF support. I'll use $cc to build dynamic libraries. +EOM + dflt="$cc" + else + echo "I'll use ld to build dynamic libraries." + dflt='ld' + fi + rm -f try.c a.out + ;; + *) dflt="$ld" + ;; + esac + + rp="What command should be used to create dynamic libraries?" + . ./myread + ld="$ans" + + cat << EOM + +Some systems may require passing special flags to $ld to create a +library that can be dynamically loaded. If your ld flags include +-L/other/path options to locate libraries outside your loader's normal +search path, you may need to specify those -L options here as well. To +use no flags, say "none". + +EOM + case "$lddlflags" in + '') case "$osname" in + hpux) dflt='-b' ;; + linux|irix*) dflt='-shared' ;; + next) dflt='none' ;; + solaris) dflt='-G' ;; + sunos) dflt='-assert nodefinitions' ;; + svr4*|esix*) dflt="-G $ldflags" ;; + *) dflt='none' ;; + esac + ;; + *) dflt="$lddlflags" ;; + esac + +: Try to guess additional flags to pick up local libraries. +for thisflag in $ldflags; do + case "$thisflag" in + -L*) + case " $dflt " in + *" $thisflag "*) ;; + *) dflt="$dflt $thisflag" ;; + esac + ;; + esac +done + +case "$dflt" in +'') dflt='none' ;; +esac + + rp="Any special flags to pass to $ld to create a dynamically loaded library?" + . ./myread + case "$ans" in + none) lddlflags=' ' ;; + *) lddlflags="$ans" ;; + esac + + cat <<EOM + +Some systems may require passing special flags to $cc to indicate that +the resulting executable will use dynamic linking. To use no flags, +say "none". + +EOM + case "$ccdlflags" in + '') case "$osname" in + hpux) dflt='-Wl,-E' ;; + linux) dflt='-rdynamic' ;; + next) dflt='none' ;; + sunos) dflt='none' ;; + *) dflt='none' ;; + esac ;; + *) dflt="$ccdlflags" ;; + esac + rp="Any special flags to pass to $cc to use dynamic loading?" + . ./myread + case "$ans" in + none) ccdlflags=' ' ;; + *) ccdlflags="$ans" ;; + esac + ;; +*) usedl="$undef" + ld='ld' + dlsrc='dl_none.xs' + lddlflags='' + ccdlflags='' + ;; +esac + +also='' +case "$usedl" in +$undef) + # No dynamic loading being used, so don't bother even to prompt. + useshrplib='false' + ;; +*) case "$useshrplib" in + '') case "$osname" in + svr4*|dgux|dynixptx|esix|powerux) + dflt=y + also='Building a shared libperl is required for dynamic loading to work on your system.' + ;; + next*) + case "$osvers" in + 4*) dflt=y + also='Building a shared libperl is needed for MAB support.' + ;; + *) dflt=n + ;; + esac + ;; + sunos) + dflt=n + also='Building a shared libperl will definitely not work on SunOS 4.' + ;; + *) dflt=n + ;; + esac + ;; + $define|true|[Yy]*) + dflt=y + ;; + *) dflt=n + ;; + esac + $cat << EOM + +The perl executable is normally obtained by linking perlmain.c with +libperl${lib_ext}, any static extensions (usually just DynaLoader), and +any other libraries needed on this system (such as -lm, etc.). Since +your system supports dynamic loading, it is probably possible to build +a shared libperl.$so. If you will have more than one executable linked +to libperl.$so, this will significantly reduce the size of each +executable, but it may have a noticeable affect on performance. The +default is probably sensible for your system. +$also + +EOM + rp="Build a shared libperl.$so (y/n)" + . ./myread + case "$ans" in + true|$define|[Yy]*) + useshrplib='true' + # Why does next4 have to be so different? + case "${osname}${osvers}" in + next4*) xxx='DYLD_LIBRARY_PATH' ;; + *) xxx='LD_LIBRARY_PATH' ;; + esac + $cat <<EOM >&4 + +To build perl, you must add the current working directory to your +$xxx environtment variable before running make. You can do +this with + $xxx=\`pwd\`; export $xxx +for Bourne-style shells, or + setenv $xxx \`pwd\` +for Csh-style shells. You *MUST* do this before running make. + +EOM + ;; + *) useshrplib='false' ;; + esac + ;; +esac + +case "$useshrplib" in +true) + case "$libperl" in + '') + # Figure out a good name for libperl.so. Since it gets stored in + # a version-specific architecture-dependent library, the version + # number isn't really that important, except for making cc/ld happy. + # + # A name such as libperl.so.3.1 + majmin="libperl.$so.$patchlevel.$subversion" + # A name such as libperl.so.301 + majonly=`echo $patchlevel $subversion | + $awk '{printf "%d%02d", $1, $2}'` + majonly=libperl.$so.$majonly + # I'd prefer to keep the os-specific stuff here to a minimum, and + # rely on figuring it out from the naming of libc. + case "${osname}${osvers}" in + next4*) + dflt=libperl.5.$so + # XXX How handle the --version stuff for MAB? + ;; + linux*) # ld won't link with a bare -lperl otherwise. + dflt=libperl.$so + ;; + *) # Try to guess based on whether libc has major.minor. + case "$libc" in + *libc.$so.[0-9]*.[0-9]*) dflt=$majmin ;; + *libc.$so.[0-9]*) dflt=$majonly ;; + *) dflt=libperl.$so ;; + esac + ;; + esac + ;; + *) dflt=$libperl + ;; + esac + cat << EOM + +I need to select a good name for the shared libperl. If your system uses +library names with major and minor numbers, then you might want something +like $majmin. Alternatively, if your system uses a single version +number for shared libraries, then you might want to use $majonly. +Or, your system might be quite happy with a simple libperl.$so. + +Since the shared libperl will get installed into a version-specific +architecture-dependent directory, the version number of the shared perl +library probably isn't important, so the default should be o.k. + +EOM + rp='What name do you want to give to the shared libperl?' + . ./myread + libperl=$ans + echo "Ok, I'll use $libperl" + ;; +*) + libperl="libperl${lib_ext}" + ;; +esac + +# Detect old use of shrpdir via undocumented Configure -Dshrpdir +case "$shrpdir" in +'') ;; +*) $cat >&4 <<EOM +WARNING: Use of the shrpdir variable for the installation location of +the shared $libperl is not supported. It was never documented and +will not work in this version. Let me (chip@perl.com) know of any +problems this may cause. + +EOM + case "$shrpdir" in + "$archlibexp/CORE") + $cat >&4 <<EOM +But your current setting of $shrpdir is +the default anyway, so it's harmless. +EOM + ;; + *) + $cat >&4 <<EOM +Further, your current attempted setting of $shrpdir +conflicts with the value of $archlibexp/CORE +that installperl will use. +EOM + ;; + esac + ;; +esac + +# How will the perl executable find the installed shared $libperl? +# Add $xxx to ccdlflags. +# If we can't figure out a command-line option, use $shrpenv to +# set env LD_RUN_PATH. The main perl makefile uses this. +shrpdir=$archlibexp/CORE +xxx='' +tmp_shrpenv='' +if "$useshrplib"; then + case "$osname" in + aix) + # We'll set it in Makefile.SH... + ;; + solaris|netbsd) + xxx="-R $shrpdir" + ;; + freebsd) + xxx="-Wl,-R$shrpdir" + ;; + linux|irix*|dec_osf) + xxx="-Wl,-rpath,$shrpdir" + ;; + next) + # next doesn't like the default... + ;; + *) + tmp_shrpenv="env LD_RUN_PATH=$shrpdir" + ;; + esac + case "$xxx" in + '') ;; + *) + # Only add $xxx if it isn't already in ccdlflags. + case " $ccdlflags " in + *" $xxx "*) ;; + *) ccdlflags="$ccdlflags $xxx" + cat <<EOM >&4 + +Adding $xxx to the flags +passed to $ld so that the perl executable will find the +installed shared $libperl. + +EOM + ;; + esac + ;; + esac +fi +# Respect a hint or command-line value. +case "$shrpenv" in +'') shrpenv="$tmp_shrpenv" ;; +esac + +: determine where manual pages go +set man1dir man1dir none +eval $prefixit +$cat <<EOM + +$spackage has manual pages available in source form. +EOM +case "$nroff" in +nroff) + echo "However, you don't have nroff, so they're probably useless to you." + case "$man1dir" in + '') man1dir="none";; + esac;; +esac +echo "If you don't want the manual sources installed, answer 'none'." +case "$man1dir" in +' ') dflt=none + ;; +'') + lookpath="$prefixexp/man/man1 $prefixexp/man/l_man/man1" + lookpath="$lookpath $prefixexp/man/p_man/man1" + lookpath="$lookpath $prefixexp/man/u_man/man1" + lookpath="$lookpath $prefixexp/man/man.1" + : If prefix contains 'perl' then we want to keep the man pages + : under the prefix directory. Otherwise, look in a variety of + : other possible places. This is debatable, but probably a + : good compromise. Well, apparently not. + : Experience has shown people expect man1dir to be under prefix, + : so we now always put it there. Users who want other behavior + : can answer interactively or use a command line option. + : Does user have System V-style man paths. + case "$sysman" in + */?_man*) dflt=`./loc . $prefixexp/l_man/man1 $lookpath` ;; + *) dflt=`./loc . $prefixexp/man/man1 $lookpath` ;; + esac + set dflt + eval $prefixup + ;; +*) dflt="$man1dir" + ;; +esac +echo " " +fn=dn+~ +rp="Where do the main $spackage manual pages (source) go?" +. ./getfile +if $test "X$man1direxp" != "X$ansexp"; then + installman1dir='' +fi +man1dir="$ans" +man1direxp="$ansexp" +case "$man1dir" in +'') man1dir=' ' + installman1dir='';; +esac +if $afs; then + $cat <<EOM + +Since you are running AFS, I need to distinguish the directory in which +manual pages reside from the directory in which they are installed (and from +which they are presumably copied to the former directory by occult means). + +EOM + case "$installman1dir" in + '') dflt=`echo $man1direxp | sed 's#^/afs/#/afs/.#'`;; + *) dflt="$installman1dir";; + esac + fn=de~ + rp='Where will man pages be installed?' + . ./getfile + installman1dir="$ans" +else + installman1dir="$man1direxp" +fi + +: What suffix to use on installed man pages + +case "$man1dir" in +' ') + man1ext='0' + ;; +*) + rp="What suffix should be used for the main $spackage man pages?" + case "$man1ext" in + '') case "$man1dir" in + *1) dflt=1 ;; + *1p) dflt=1p ;; + *1pm) dflt=1pm ;; + *l) dflt=l;; + *n) dflt=n;; + *o) dflt=o;; + *p) dflt=p;; + *C) dflt=C;; + *L) dflt=L;; + *L1) dflt=L1;; + *) dflt=1;; + esac + ;; + *) dflt="$man1ext";; + esac + . ./myread + man1ext="$ans" + ;; +esac + +: see if we can have long filenames +echo " " +rmlist="$rmlist /tmp/cf$$" +$test -d /tmp/cf$$ || mkdir /tmp/cf$$ +first=123456789abcdef +second=/tmp/cf$$/$first +$rm -f $first $second +if (echo hi >$first) 2>/dev/null; then + if $test -f 123456789abcde; then + echo 'You cannot have filenames longer than 14 characters. Sigh.' >&4 + val="$undef" + else + if (echo hi >$second) 2>/dev/null; then + if $test -f /tmp/cf$$/123456789abcde; then + $cat <<'EOM' +That's peculiar... You can have filenames longer than 14 characters, but only +on some of the filesystems. Maybe you are using NFS. Anyway, to avoid problems +I shall consider your system cannot support long filenames at all. +EOM + val="$undef" + else + echo 'You can have filenames longer than 14 characters.' >&4 + val="$define" + fi + else + $cat <<'EOM' +How confusing! Some of your filesystems are sane enough to allow filenames +longer than 14 characters but some others like /tmp can't even think about them. +So, for now on, I shall assume your kernel does not allow them at all. +EOM + val="$undef" + fi + fi +else + $cat <<'EOM' +You can't have filenames longer than 14 chars. You can't even think about them! +EOM + val="$undef" +fi +set d_flexfnam +eval $setvar +$rm -rf /tmp/cf$$ 123456789abcde* + +: determine where library module manual pages go +set man3dir man3dir none +eval $prefixit +$cat <<EOM + +$spackage has manual pages for many of the library modules. +EOM + +case "$nroff" in +nroff) + $cat <<'EOM' +However, you don't have nroff, so they're probably useless to you. +You can use the supplied perldoc script instead. +EOM + case "$man3dir" in + '') man3dir="none";; + esac;; +esac + +case "$d_flexfnam" in +undef) + $cat <<'EOM' +However, your system can't handle the long file names like File::Basename.3. +You can use the supplied perldoc script instead. +EOM + case "$man3dir" in + '') man3dir="none";; + esac;; +esac + +echo "If you don't want the manual sources installed, answer 'none'." +: We dont use /usr/local/man/man3 because some man programs will +: only show the /usr/local/man/man3 contents, and not the system ones, +: thus man less will show the perl module less.pm, but not the system +: less command. We might also conflict with TCL man pages. +: However, something like /opt/perl/man/man3 is fine. +case "$man3dir" in +'') case "$prefix" in + *perl*) dflt=`echo $man1dir | + $sed -e 's/man1/man3/g' -e 's/man\.1/man\.3/g'` ;; + *) dflt="$privlib/man/man3" ;; + esac + ;; +' ') dflt=none;; +*) dflt="$man3dir" ;; +esac +echo " " + +fn=dn+~ +rp="Where do the $spackage library man pages (source) go?" +. ./getfile +if test "X$man3direxp" != "X$ansexp"; then + installman3dir='' +fi + +man3dir="$ans" +man3direxp="$ansexp" +case "$man3dir" in +'') man3dir=' ' + installman3dir='';; +esac +if $afs; then + $cat <<EOM + +Since you are running AFS, I need to distinguish the directory in which +manual pages reside from the directory in which they are installed (and from +which they are presumably copied to the former directory by occult means). + +EOM + case "$installman3dir" in + '') dflt=`echo $man3direxp | sed 's#^/afs/#/afs/.#'`;; + *) dflt="$installman3dir";; + esac + fn=de~ + rp='Where will man pages be installed?' + . ./getfile + installman3dir="$ans" +else + installman3dir="$man3direxp" +fi + +: What suffix to use on installed man pages + +case "$man3dir" in +' ') + man3ext='0' + ;; +*) + rp="What suffix should be used for the $spackage library man pages?" + case "$man3ext" in + '') case "$man3dir" in + *3) dflt=3 ;; + *3p) dflt=3p ;; + *3pm) dflt=3pm ;; + *l) dflt=l;; + *n) dflt=n;; + *o) dflt=o;; + *p) dflt=p;; + *C) dflt=C;; + *L) dflt=L;; + *L3) dflt=L3;; + *) dflt=3;; + esac + ;; + *) dflt="$man3ext";; + esac + . ./myread + man3ext="$ans" + ;; +esac + +: see if we have to deal with yellow pages, now NIS. +if $test -d /usr/etc/yp || $test -d /etc/yp; then + if $test -f /usr/etc/nibindd; then + echo " " + echo "I'm fairly confident you're on a NeXT." + echo " " + rp='Do you get the hosts file via NetInfo?' + dflt=y + case "$hostcat" in + nidump*) ;; + '') ;; + *) dflt=n;; + esac + . ./myread + case "$ans" in + y*) hostcat='nidump hosts .';; + *) case "$hostcat" in + nidump*) hostcat='';; + esac + ;; + esac + fi + case "$hostcat" in + nidump*) ;; + *) + case "$hostcat" in + *ypcat*) dflt=y;; + '') if $contains '^\+' /etc/passwd >/dev/null 2>&1; then + dflt=y + else + dflt=n + fi;; + *) dflt=n;; + esac + echo " " + rp='Are you getting the hosts file via yellow pages?' + . ./myread + case "$ans" in + y*) hostcat='ypcat hosts';; + *) hostcat='cat /etc/hosts';; + esac + ;; + esac +fi + +: now get the host name +echo " " +echo "Figuring out host name..." >&4 +case "$myhostname" in +'') cont=true + echo 'Maybe "hostname" will work...' + if tans=`sh -c hostname 2>&1` ; then + myhostname=$tans + phostname=hostname + cont='' + fi + ;; +*) cont='';; +esac +if $test "$cont"; then + if ./xenix; then + echo 'Oh, dear. Maybe "/etc/systemid" is the key...' + if tans=`cat /etc/systemid 2>&1` ; then + myhostname=$tans + phostname='cat /etc/systemid' + echo "Whadyaknow. Xenix always was a bit strange..." + cont='' + fi + elif $test -r /etc/systemid; then + echo "(What is a non-Xenix system doing with /etc/systemid?)" + fi +fi +if $test "$cont"; then + echo 'No, maybe "uuname -l" will work...' + if tans=`sh -c 'uuname -l' 2>&1` ; then + myhostname=$tans + phostname='uuname -l' + else + echo 'Strange. Maybe "uname -n" will work...' + if tans=`sh -c 'uname -n' 2>&1` ; then + myhostname=$tans + phostname='uname -n' + else + echo 'Oh well, maybe I can mine it out of whoami.h...' + if tans=`sh -c $contains' sysname $usrinc/whoami.h' 2>&1` ; then + myhostname=`echo "$tans" | $sed 's/^.*"\(.*\)"/\1/'` + phostname="sed -n -e '"'/sysname/s/^.*\"\\(.*\\)\"/\1/{'"' -e p -e q -e '}' <$usrinc/whoami.h" + else + case "$myhostname" in + '') echo "Does this machine have an identity crisis or something?" + phostname='';; + *) + echo "Well, you said $myhostname before..." + phostname='echo $myhostname';; + esac + fi + fi + fi +fi +: you do not want to know about this +set $myhostname +myhostname=$1 + +: verify guess +if $test "$myhostname" ; then + dflt=y + rp='Your host name appears to be "'$myhostname'".'" Right?" + . ./myread + case "$ans" in + y*) ;; + *) myhostname='';; + esac +fi + +: bad guess or no guess +while $test "X$myhostname" = X ; do + dflt='' + rp="Please type the (one word) name of your host:" + . ./myread + myhostname="$ans" +done + +: translate upper to lower if necessary +case "$myhostname" in +*[A-Z]*) + echo "(Normalizing case in your host name)" + myhostname=`echo $myhostname | ./tr '[A-Z]' '[a-z]'` + ;; +esac + +case "$myhostname" in +*.*) + dflt=`expr "X$myhostname" : "X[^.]*\(\..*\)"` + myhostname=`expr "X$myhostname" : "X\([^.]*\)\."` + echo "(Trimming domain name from host name--host name is now $myhostname)" + ;; +*) case "$mydomain" in + '') + { + : If we use NIS, try ypmatch. + : Is there some reason why this was not done before? + test "X$hostcat" = "Xypcat hosts" && + ypmatch "$myhostname" hosts 2>/dev/null |\ + $sed -e 's/[ ]*#.*//; s/$/ /' > hosts && \ + $test -s hosts + } || { + : Extract only the relevant hosts, reducing file size, + : remove comments, insert trailing space for later use. + $hostcat | $sed -n -e "s/[ ]*#.*//; s/\$/ / + /[ ]$myhostname[ . ]/p" > hosts + } + tmp_re="[ . ]" + $test x`$awk "/[0-9].*[ ]$myhostname$tmp_re/ { sum++ } + END { print sum }" hosts` = x1 || tmp_re="[ ]" + dflt=.`$awk "/[0-9].*[ ]$myhostname$tmp_re/ {for(i=2; i<=NF;i++) print \\\$i}" \ + hosts | $sort | $uniq | \ + $sed -n -e "s/$myhostname\.\([-a-zA-Z0-9_.]\)/\1/p"` + case `$echo X$dflt` in + X*\ *) echo "(Several hosts in /etc/hosts matched hostname)" + dflt=. + ;; + X.) echo "(You do not have fully-qualified names in /etc/hosts)" + ;; + esac + case "$dflt" in + .) + tans=`./loc resolv.conf X /etc /usr/etc` + if $test -f "$tans"; then + echo "(Attempting domain name extraction from $tans)" + : Why was there an Egrep here, when Sed works? + : Look for either a search or a domain directive. + dflt=.`$sed -n -e 's/ / /g' \ + -e 's/^search *\([^ ]*\).*/\1/p' $tans \ + | ./tr '[A-Z]' '[a-z]' 2>/dev/null` + case "$dflt" in + .) dflt=.`$sed -n -e 's/ / /g' \ + -e 's/^domain *\([^ ]*\).*/\1/p' $tans \ + | ./tr '[A-Z]' '[a-z]' 2>/dev/null` + ;; + esac + fi + ;; + esac + case "$dflt" in + .) echo "(No help from resolv.conf either -- attempting clever guess)" + dflt=.`sh -c domainname 2>/dev/null` + case "$dflt" in + '') dflt='.';; + .nis.*|.yp.*|.main.*) dflt=`echo $dflt | $sed -e 's/^\.[^.]*//'`;; + esac + ;; + esac + case "$dflt" in + .) echo "(Lost all hope -- silly guess then)" + dflt='.uucp' + ;; + esac + $rm -f hosts + ;; + *) dflt="$mydomain";; + esac;; +esac +echo " " +rp="What is your domain name?" +. ./myread +tans="$ans" +case "$ans" in +'') ;; +.*) ;; +*) tans=".$tans";; +esac +mydomain="$tans" + +: translate upper to lower if necessary +case "$mydomain" in +*[A-Z]*) + echo "(Normalizing case in your domain name)" + mydomain=`echo $mydomain | ./tr '[A-Z]' '[a-z]'` + ;; +esac + +: a little sanity check here +case "$phostname" in +'') ;; +*) + case `$phostname | ./tr '[A-Z]' '[a-z]'` in + $myhostname$mydomain|$myhostname) ;; + *) + case "$phostname" in + sed*) + echo "(That doesn't agree with your whoami.h file, by the way.)" + ;; + *) + echo "(That doesn't agree with your $phostname command, by the way.)" + ;; + esac + ;; + esac + ;; +esac + +$cat <<EOM + +I need to get your e-mail address in Internet format if possible, i.e. +something like user@host.domain. Please answer accurately since I have +no easy means to double check it. The default value provided below +is most probably close to the reality but may not be valid from outside +your organization... + +EOM +cont=x +while test "$cont"; do + case "$cf_email" in + '') dflt="$cf_by@$myhostname$mydomain";; + *) dflt="$cf_email";; + esac + rp='What is your e-mail address?' + . ./myread + cf_email="$ans" + case "$cf_email" in + *@*.*) cont='' ;; + *) + rp='Address does not look like an Internet one. Use it anyway?' + case "$fastread" in + yes) dflt=y ;; + *) dflt=n ;; + esac + . ./myread + case "$ans" in + y*) cont='' ;; + *) echo " " ;; + esac + ;; + esac +done + +$cat <<EOM + +If you or somebody else will be maintaining perl at your site, please +fill in the correct e-mail address here so that they may be contacted +if necessary. Currently, the "perlbug" program included with perl +will send mail to this address in addition to perlbug@perl.com. You may +enter "none" for no administrator. + +EOM +case "$perladmin" in +'') dflt="$cf_email";; +*) dflt="$perladmin";; +esac +rp='Perl administrator e-mail address' +. ./myread +perladmin="$ans" + +: figure out how to guarantee perl startup +case "$startperl" in +'') + case "$sharpbang" in + *!) + $cat <<EOH + +I can use the #! construct to start perl on your system. This will +make startup of perl scripts faster, but may cause problems if you +want to share those scripts and perl is not in a standard place +($binexp/perl) on all your platforms. The alternative is to force +a shell by starting the script with a single ':' character. + +EOH + dflt="$binexp/perl" + rp='What shall I put after the #! to start up perl ("none" to not use #!)?' + . ./myread + case "$ans" in + none) startperl=": # use perl";; + *) startperl="#!$ans" + if $test 30 -lt `echo "$ans" | wc -c`; then + $cat >&4 <<EOM + +WARNING: Some systems limit the #! command to 32 characters. +If you experience difficulty running Perl scripts with #!, try +installing Perl in a directory with a shorter pathname. + +EOM + fi ;; + esac + ;; + *) startperl=": # use perl" + ;; + esac + ;; +esac +echo "I'll use $startperl to start perl scripts." + +: figure best path for perl in scripts +case "$perlpath" in +'') + perlpath="$binexp/perl" + case "$startperl" in + *!*) ;; + *) + $cat <<EOH + +I will use the "eval 'exec'" idiom to start Perl on your system. +I can use the full path of your Perl binary for this purpose, but +doing so may cause problems if you want to share those scripts and +Perl is not always in a standard place ($binexp/perl). + +EOH + dflt="$binexp/perl" + rp="What path shall I use in \"eval 'exec'\"?" + . ./myread + perlpath="$ans" + ;; + esac + ;; +esac +case "$startperl" in +*!*) ;; +*) echo "I'll use $perlpath in \"eval 'exec'\"" ;; +esac + +: determine where public executable scripts go +set scriptdir scriptdir +eval $prefixit +case "$scriptdir" in +'') + dflt="$bin" + : guess some guesses + $test -d /usr/share/scripts && dflt=/usr/share/scripts + $test -d /usr/share/bin && dflt=/usr/share/bin + $test -d /usr/local/script && dflt=/usr/local/script + $test -d $prefixexp/script && dflt=$prefixexp/script + set dflt + eval $prefixup + ;; +*) dflt="$scriptdir" + ;; +esac +$cat <<EOM + +Some installations have a separate directory just for executable scripts so +that they can mount it across multiple architectures but keep the scripts in +one spot. You might, for example, have a subdirectory of /usr/share for this. +Or you might just lump your scripts in with all your other executables. + +EOM +fn=d~ +rp='Where do you keep publicly executable scripts?' +. ./getfile +if $test "X$ansexp" != "X$scriptdirexp"; then + installscript='' +fi +scriptdir="$ans" +scriptdirexp="$ansexp" +if $afs; then + $cat <<EOM + +Since you are running AFS, I need to distinguish the directory in which +scripts reside from the directory in which they are installed (and from +which they are presumably copied to the former directory by occult means). + +EOM + case "$installscript" in + '') dflt=`echo $scriptdirexp | sed 's#^/afs/#/afs/.#'`;; + *) dflt="$installscript";; + esac + fn=de~ + rp='Where will public scripts be installed?' + . ./getfile + installscript="$ans" +else + installscript="$scriptdirexp" +fi + +cat <<EOM + +Previous version of $package used the standard IO mechanisms as defined in +<stdio.h>. Versions 5.003_02 and later of perl allow alternate IO +mechanisms via a "PerlIO" abstraction, but the stdio mechanism is still +the default and is the only supported mechanism. This abstraction +layer can use AT&T's sfio (if you already have sfio installed) or +fall back on standard IO. This PerlIO abstraction layer is +experimental and may cause problems with some extension modules. + +If this doesn't make any sense to you, just accept the default 'n'. +EOM +case "$useperlio" in +$define|true|[yY]*) dflt='y';; +*) dflt='n';; +esac +rp='Use the experimental PerlIO abstraction layer?' +. ./myread +case "$ans" in +y|Y) + val="$define" + ;; +*) + echo "Ok, doing things the stdio way" + val="$undef" + ;; +esac +set useperlio +eval $setvar + : Check how to convert floats to strings. echo " " echo "Checking for an efficient way to convert floats to strings." $cat >try.c <<'EOP' #ifdef TRY_gconvert #define Gconvert(x,n,t,b) gconvert((x),(n),(t),(b)) +char *myname = "gconvert"; #endif #ifdef TRY_gcvt #define Gconvert(x,n,t,b) gcvt((x),(n),(b)) +char *myname = "gcvt"; #endif #ifdef TRY_sprintf #define Gconvert(x,n,t,b) sprintf((b),"%.*g",(n),(x)) +char *myname = "sprintf"; #endif -main() { + +#include <stdio.h> + +int +checkit(expect, got) +char *expect; +char *got; +{ + if (strcmp(expect, got)) { + printf("%s oddity: Expected %s, got %s\n", + myname, expect, got); + exit(1); + } +} + +int +main() +{ char buf[64]; + buf[63] = '\0'; + + /* This must be 1st test on (which?) platform */ + /* Alan Burlison <AlanBurlsin@unn.unisys.com> */ + Gconvert(0.1, 8, 0, buf); + checkit("0.1", buf); + Gconvert(1.0, 8, 0, buf); - if (buf[0] != '1' || buf[1] != '\0') - exit(1); + checkit("1", buf); + Gconvert(0.0, 8, 0, buf); - if (buf[0] != '0' || buf[1] != '\0') - exit(1); + checkit("0", buf); + Gconvert(-1.0, 8, 0, buf); - if (buf[0] != '-' || buf[1] != '1' || buf[2] != '\0') - exit(1); + checkit("-1", buf); + + /* Some Linux gcvt's give 1.e+5 here. */ + Gconvert(100000.0, 8, 0, buf); + checkit("100000", buf); + + /* Some Linux gcvt's give -1.e+5 here. */ + Gconvert(-100000.0, 8, 0, buf); + checkit("-100000", buf); + exit(0); } EOP @@ -4650,11 +5564,10 @@ for xxx_convert in $xxx_list; do try.c $libs > /dev/null 2>&1 ; then echo "$xxx_convert" found. >&4 if ./try; then - echo "Good, $xxx_convert drops a trailing decimal point." echo "I'll use $xxx_convert to convert floats into a string." >&4 break; else - echo "But $xxx_convert keeps a trailing decimal point". + echo "...But $xxx_convert didn't work as I expected." fi else echo "$xxx_convert NOT found." >&4 @@ -4673,66 +5586,6 @@ h_fcntl=false : Initialize h_sysfile h_sysfile=false -: determine filename position in cpp output -echo " " -echo "Computing filename position in cpp output for #include directives..." >&4 -echo '#include <stdio.h>' > foo.c -$cat >fieldn <<EOF -$startsh -$cppstdin $cppflags $cppminus <foo.c 2>/dev/null | \ -$grep '^[ ]*#.*stdio\.h' | \ -while read cline; do - pos=1 - set \$cline - while $test \$# -gt 0; do - if $test -r \`echo \$1 | $tr -d '"'\`; then - echo "\$pos" - exit 0 - fi - shift - pos=\`expr \$pos + 1\` - done -done -EOF -chmod +x fieldn -fieldn=`./fieldn` -$rm -f foo.c fieldn -case $fieldn in -'') pos='???';; -1) pos=first;; -2) pos=second;; -3) pos=third;; -*) pos="${fieldn}th";; -esac -echo "Your cpp writes the filename in the $pos field of the line." - -: locate header file -$cat >findhdr <<EOF -$startsh -wanted=\$1 -name='' -if test -f $usrinc/\$wanted; then - echo "$usrinc/\$wanted" - exit 0 -fi -awkprg='{ print \$$fieldn }' -echo "#include <\$wanted>" > foo\$\$.c -$cppstdin $cppminus $cppflags < foo\$\$.c 2>/dev/null | \ -$grep "^[ ]*#.*\$wanted" | \ -while read cline; do - name=\`echo \$cline | $awk "\$awkprg" | $tr -d '"'\` - case "\$name" in - */\$wanted) echo "\$name"; exit 0;; - *) name='';; - esac; -done; -$rm -f foo\$\$.c; -case "\$name" in -'') exit 1;; -esac -EOF -chmod +x findhdr - : access call always available on UNIX set access d_access eval $inlibc @@ -4810,81 +5663,189 @@ eval $inlibc set bcopy d_bcopy eval $inlibc +: see if this is a unistd.h system +set unistd.h i_unistd +eval $inhdr + +: see if getpgrp exists +set getpgrp d_getpgrp +eval $inlibc + +echo "Checking to see which flavor of getpgrp is in use . . . " +case "$d_getpgrp" in +"$define") + echo " " + $cat >set.c <<EOP +#$i_unistd I_UNISTD +#include <sys/types.h> +#ifdef I_UNISTD +# include <unistd.h> +#endif +main() +{ + if (getuid() == 0) { + printf("(I see you are running Configure as super-user...)\n"); + setuid(1); + } +#ifdef TRY_BSD_PGRP + if (getpgrp(1) == 0) + exit(0); +#else + if (getpgrp() > 0) + exit(0); +#endif + exit(1); +} +EOP + if $cc -DTRY_BSD_PGRP $ccflags $ldflags -o set set.c $libs >/dev/null 2>&1 && ./set; then + echo "You have to use getpgrp(pid) instead of getpgrp()." >&4 + val="$define" + elif $cc $ccflags $ldflags -o set set.c $libs >/dev/null 2>&1 && ./set; then + echo "You have to use getpgrp() instead of getpgrp(pid)." >&4 + val="$undef" + else + echo "I can't seem to compile and run the test program." + if ./usg; then + xxx="a USG one, i.e. you use getpgrp()." + else + # SVR4 systems can appear rather BSD-ish. + case "$i_unistd" in + $undef) + xxx="a BSD one, i.e. you use getpgrp(pid)." + val="$define" + ;; + $define) + xxx="probably a USG one, i.e. you use getpgrp()." + val="$undef" + ;; + esac + fi + echo "Assuming your getpgrp is $xxx" >&4 + fi + ;; +*) val="$undef";; +esac +set d_bsdgetpgrp +eval $setvar +$rm -f set set.c + : see if setpgrp exists set setpgrp d_setpgrp eval $inlibc -: see which flavor of setpgrp is in use +echo "Checking to see which flavor of setpgrp is in use . . . " case "$d_setpgrp" in "$define") echo " " $cat >set.c <<EOP +#$i_unistd I_UNISTD +#include <sys/types.h> +#ifdef I_UNISTD +# include <unistd.h> +#endif main() { if (getuid() == 0) { printf("(I see you are running Configure as super-user...)\n"); setuid(1); } +#ifdef TRY_BSD_PGRP if (-1 == setpgrp(1, 1)) - exit(1); - exit(0); + exit(0); +#else + if (setpgrp() != -1) + exit(0); +#endif + exit(1); } EOP - if $cc $ccflags $ldflags -o set set.c $libs >/dev/null 2>&1; then - ./set 2>/dev/null - case $? in - 0) echo "You have to use setpgrp() instead of setpgrp(pid, pgrp)." >&4 - val="$undef";; - *) echo "You have to use setpgrp(pid, pgrp) instead of setpgrp()." >&4 - val="$define";; - esac + if $cc -DTRY_BSD_PGRP $ccflags $ldflags -o set set.c $libs >/dev/null 2>&1 && ./set; then + echo 'You have to use setpgrp(pid,pgrp) instead of setpgrp().' >&4 + val="$define" + elif $cc $ccflags $ldflags -o set set.c $libs >/dev/null 2>&1 && ./set; then + echo 'You have to use setpgrp() instead of setpgrp(pid,pgrp).' >&4 + val="$undef" else + echo "I can't seem to compile and run the test program." if ./usg; then - xxx="USG one, i.e. you use setpgrp()." - val="$undef" + xxx="a USG one, i.e. you use setpgrp()." else - xxx="BSD one, i.e. you use setpgrp(pid, pgrp)." - val="$define" + # SVR4 systems can appear rather BSD-ish. + case "$i_unistd" in + $undef) + xxx="a BSD one, i.e. you use setpgrp(pid,pgrp)." + val="$define" + ;; + $define) + xxx="probably a USG one, i.e. you use setpgrp()." + val="$undef" + ;; + esac fi - echo "Assuming your setpgrp is a $xxx" >&4 + echo "Assuming your setpgrp is $xxx" >&4 fi ;; *) val="$undef";; esac -set d_bsdpgrp +set d_bsdsetpgrp eval $setvar +d_bsdpgrp=$d_bsdsetpgrp $rm -f set set.c - : see if bzero exists set bzero d_bzero eval $inlibc -: check for length of integer +: check for lengths of integral types echo " " case "$intsize" in '') echo "Checking to see how big your integers are..." >&4 - $cat >try.c <<'EOCP' + $cat >intsize.c <<'EOCP' #include <stdio.h> main() { - printf("%d\n", sizeof(int)); + printf("intsize=%d;\n", sizeof(int)); + printf("longsize=%d;\n", sizeof(long)); + printf("shortsize=%d;\n", sizeof(short)); + fflush(stdout); exit(0); } EOCP - if $cc $ccflags try.c -o try >/dev/null 2>&1 && ./try > /dev/null; then - intsize=`./try` +# If $libs contains -lsfio, and sfio is mis-configured, then it +# sometimes (apparently) runs and exits with a 0 status, but with no +# output!. Thus we check with test -s whether we actually got any +# output. I think it has to do with sfio's use of _exit vs. exit, +# but I don't know for sure. --Andy Dougherty 1/27/97. + if $cc $optimize $ccflags $ldflags -o intsize intsize.c $libs >/dev/null 2>&1 && + ./intsize > intsize.out 2>/dev/null && test -s intsize.out ; then + eval `$cat intsize.out` echo "Your integers are $intsize bytes long." + echo "Your long integers are $longsize bytes long." + echo "Your short integers are $shortsize bytes long." else - dflt='4' - echo "(I can't seem to compile the test program. Guessing...)" + $cat >&4 <<EOM + +Help! I can't compile and run the intsize test program: please enlighten me! +(This is probably a misconfiguration in your system or libraries, and +you really ought to fix it. Still, I'll try anyway.) + +EOM + dflt=4 rp="What is the size of an integer (in bytes)?" . ./myread intsize="$ans" + dflt=$intsize + rp="What is the size of a long integer (in bytes)?" + . ./myread + longsize="$ans" + dflt=2 + rp="What is the size of a short integer (in bytes)?" + . ./myread + shortsize="$ans" fi ;; esac -$rm -f try.c try +$rm -f intsize intsize.[co] intsize.out : see if signal is declared as pointer to function returning int or void echo " " @@ -5130,19 +6091,19 @@ if set crypt val -f d_crypt; eval $csym; $val; then val="$define" cryptlib='' else - cryptlib=`./loc Slibcrypt.a "" $xlibpth` + cryptlib=`./loc Slibcrypt$lib_ext "" $xlibpth` if $test -z "$cryptlib"; then - cryptlib=`./loc Mlibcrypt.a "" $xlibpth` + cryptlib=`./loc Mlibcrypt$lib_ext "" $xlibpth` else cryptlib=-lcrypt fi if $test -z "$cryptlib"; then - cryptlib=`./loc Llibcrypt.a "" $xlibpth` + cryptlib=`./loc Llibcrypt$lib_ext "" $xlibpth` else cryptlib=-lcrypt fi if $test -z "$cryptlib"; then - cryptlib=`./loc libcrypt.a "" $libpth` + cryptlib=`./loc libcrypt$lib_ext "" $libpth` else cryptlib=-lcrypt fi @@ -5158,47 +6119,20 @@ eval $setvar : get csh whereabouts case "$csh" in -'csh') val="$undef" ;; -*) val="$define" ;; +'csh') val="$undef" ;; +*) val="$define" ;; esac set d_csh eval $setvar -full_csh=$csh +: Respect a hint or command line value for full_csh. +case "$full_csh" in +'') full_csh=$csh ;; +esac : see if cuserid exists set cuserid d_cuserid eval $inlibc -: define an alternate in-header-list? function -inhdr='echo " "; td=$define; tu=$undef; yyy=$@; -cont=true; xxf="echo \"<\$1> found.\" >&4"; -case $# in 2) xxnf="echo \"<\$1> NOT found.\" >&4";; -*) xxnf="echo \"<\$1> NOT found, ...\" >&4";; -esac; -case $# in 4) instead=instead;; *) instead="at last";; esac; -while $test "$cont"; do - xxx=`./findhdr $1` - var=$2; eval "was=\$$2"; - if $test "$xxx" && $test -r "$xxx"; - then eval $xxf; - eval "case \"\$$var\" in $undef) . ./whoa; esac"; eval "$var=\$td"; - cont=""; - else eval $xxnf; - eval "case \"\$$var\" in $define) . ./whoa; esac"; eval "$var=\$tu"; fi; - set $yyy; shift; shift; yyy=$@; - case $# in 0) cont="";; - 2) xxf="echo \"but I found <\$1> $instead.\" >&4"; - xxnf="echo \"and I did not find <\$1> either.\" >&4";; - *) xxf="echo \"but I found <\$1\> instead.\" >&4"; - xxnf="echo \"there is no <\$1>, ...\" >&4";; - esac; -done; -while $test "$yyy"; -do set $yyy; var=$2; eval "was=\$$2"; - eval "case \"\$$var\" in $define) . ./whoa; esac"; eval "$var=\$tu"; - set $yyy; shift; shift; yyy=$@; -done' - : see if this is a limits.h system set limits.h i_limits eval $inhdr @@ -5313,261 +6247,6 @@ set dlerror d_dlerror eval $inlibc runnm="$xxx_runnm" -: see if dld is available -set dld.h i_dld -eval $inhdr - -: see if dlopen exists -xxx_runnm="$runnm" -runnm=false -set dlopen d_dlopen -eval $inlibc -runnm="$xxx_runnm" - -: determine which dynamic loading, if any, to compile in -echo " " -dldir="ext/DynaLoader" -case "$usedl" in -$define|y|true) - dflt='y' - usedl="$define" - ;; -$undef|n|false) - dflt='n' - usedl="$undef" - ;; -*) - dflt='n' - case "$d_dlopen" in - $define) dflt='y' ;; - esac - case "$i_dld" in - $define) dflt='y' ;; - esac - : Does a dl_xxx.xs file exist for this operating system - $test -f ../$dldir/dl_${osname}.xs && dflt='y' - ;; -esac -rp="Do you wish to use dynamic loading?" -. ./myread -usedl="$ans" -case "$ans" in -y*) usedl="$define" - case "$dlsrc" in - '') - if $test -f ../$dldir/dl_${osname}.xs ; then - dflt="$dldir/dl_${osname}.xs" - elif $test "$d_dlopen" = "$define" ; then - dflt="$dldir/dl_dlopen.xs" - elif $test "$i_dld" = "$define" ; then - dflt="$dldir/dl_dld.xs" - else - dflt='' - fi - ;; - *) dflt="$dldir/$dlsrc" - ;; - esac - echo "The following dynamic loading files are available:" - : Can not go over to $dldir because getfile has path hard-coded in. - cd ..; ls -C $dldir/dl*.xs; cd UU - rp="Source file to use for dynamic loading" - fn="fne" - . ./getfile - usedl="$define" - : emulate basename - dlsrc=`echo $ans | $sed -e 's@.*/\([^/]*\)$@\1@'` - - $cat << EOM - -Some systems may require passing special flags to $cc -c to -compile modules that will be used to create a shared library. -To use no flags, say "none". - -EOM - case "$cccdlflags" in - '') case "$gccversion" in - '') case "$osname" in - hpux) dflt='+z' ;; - next) dflt='none' ;; - solaris|svr4*|esix*) dflt='-Kpic' ;; - sunos) dflt='-pic' ;; - *) dflt='none' ;; - esac ;; - *) dflt='-fpic' ;; - esac ;; - *) dflt="$cccdlflags" ;; - esac - rp="Any special flags to pass to $cc -c to compile shared library modules?" - . ./myread - case "$ans" in - none) cccdlflags=' ' ;; - *) cccdlflags="$ans" ;; - esac - - cat << EOM - -Some systems use ld to create libraries that can be dynamically loaded, -while other systems (such as those using ELF) use $cc. - -EOM - case "$ld" in - '') $cat >try.c <<'EOM' -/* Test for whether ELF binaries are produced */ -#include <fcntl.h> -#include <stdlib.h> -main() { - char b[4]; - int i = open("a.out",O_RDONLY); - if(i == -1) - exit(1); /* fail */ - if(read(i,b,4)==4 && b[0]==127 && b[1]=='E' && b[2]=='L' && b[3]=='F') - exit(0); /* succeed (yes, it's ELF) */ - else - exit(1); /* fail */ -} -EOM - if $cc $ccflags try.c >/dev/null 2>&1 && ./a.out; then - cat <<EOM -You appear to have ELF support. I'll use $cc to build dynamic libraries. -EOM - dflt="$cc" - else - echo "I'll use ld to build dynamic libraries." - dflt='ld' - fi - rm -f try.c a.out - ;; - *) dflt="$ld" - ;; - esac - - rp="What command should be used to create dynamic libraries?" - . ./myread - ld="$ans" - - cat << EOM - -Some systems may require passing special flags to $ld to create a -library that can be dynamically loaded. If your ld flags include --L/other/path options to locate libraries outside your loader's normal -search path, you may need to specify those -L options here as well. To -use no flags, say "none". - -EOM - case "$lddlflags" in - '') case "$osname" in - hpux) dflt='-b' ;; - linux) dflt='-shared' ;; - next) dflt='none' ;; - solaris) dflt='-G' ;; - sunos) dflt='-assert nodefinitions' ;; - svr4*|esix*) dflt="-G $ldflags" ;; - *) dflt='none' ;; - esac - ;; - *) dflt="$lddlflags" ;; - esac - -: Try to guess additional flags to pick up local libraries. -for thisflag in $ldflags; do - case "$thisflag" in - -L*) - case " $dflt " in - *" $thisflag "*) ;; - *) dflt="$dflt $thisflag" ;; - esac - ;; - esac -done - -case "$dflt" in -'') dflt='none' ;; -esac - - rp="Any special flags to pass to $ld to create a dynamically loaded library?" - . ./myread - case "$ans" in - none) lddlflags=' ' ;; - *) lddlflags="$ans" ;; - esac - - cat <<EOM - -Some systems may require passing special flags to $cc to indicate that -the resulting executable will use dynamic linking. To use no flags, -say "none". - -EOM - case "$ccdlflags" in - '') case "$osname" in - hpux) dflt='-Wl,-E' ;; - linux) dflt='-rdynamic' ;; - next) dflt='none' ;; - sunos) dflt='none' ;; - *) dflt='none' ;; - esac ;; - *) dflt="$ccdlflags" ;; - esac - rp="Any special flags to pass to $cc to use dynamic loading?" - . ./myread - case "$ans" in - none) ccdlflags=' ' ;; - *) ccdlflags="$ans" ;; - esac - ;; -*) usedl="$undef" - ld='ld' - dlsrc='dl_none.xs' - lddlflags='' - ccdlflags='' - ;; -esac - -val="$undef" -case "$osname" in -esix*|svr4*) - case "$usedl" in - $define) - $cat <<EOM - -System V Release 4 systems can support dynamic loading -only if libperl is created as a shared library. - -EOM - val="$define" - ;; - esac ;; -esac -set d_shrplib; eval $setvar -case "$d_shrplib" in -$define) - cat <<EOM >&4 - -Be sure to add the perl source directory to the LD_LIBRARY_PATH -environment variable before running make: - LD_LIBRARY_PATH=`cd ..;pwd`; export LD_LIBRARY_PATH -or - setenv LD_LIBRARY_PATH `cd ..;pwd` - -EOM -;; -esac -case "$d_shrplib" in -$define) - case "$shrpdir" in - "") dflt="$archlib/CORE";; - *) dflt="$shrpdir";; - esac - rp="What directory should we install the shared libperl into?" - fn="d~" - . ./getfile - shrpdir="$ans" - ;; -*) shrpdir='none' - ;; -esac - : see if dlfcn is available set dlfcn.h i_dlfcn eval $inhdr @@ -5630,26 +6309,31 @@ main() #endif handle = dlopen("./dyna.$dlext", mode) ; if (handle == NULL) { - printf ("1\n") ; - exit(0); + printf ("1\n") ; + fflush (stdout) ; + exit(0); } symbol = dlsym(handle, "fred") ; if (symbol == NULL) { - /* try putting a leading underscore */ - symbol = dlsym(handle, "_fred") ; - if (symbol == NULL) { - printf ("2\n") ; - exit(0); - } - printf ("3\n") ; + /* try putting a leading underscore */ + symbol = dlsym(handle, "_fred") ; + if (symbol == NULL) { + printf ("2\n") ; + fflush (stdout) ; + exit(0); + } + printf ("3\n") ; } else - printf ("4\n") ; - exit(0); + printf ("4\n") ; + fflush (stdout) ; + exit(0); } EOM + : Call the object file tmp-dyna.o in case dlext=o. if $cc $ccflags $cccdlflags -c dyna.c > /dev/null 2>&1 && - $ld $lddlflags -o dyna.$dlext dyna.o > /dev/null 2>&1 && + mv dyna${obj_ext} tmp-dyna${obj_ext} > /dev/null 2>&1 && + $ld $lddlflags -o dyna.$dlext tmp-dyna${obj_ext} > /dev/null 2>&1 && $cc $ccflags $ldflags $cccdlflags $ccdlflags fred.c -o fred $libs > /dev/null 2>&1; then xxx=`./fred` case $xxx in @@ -5667,7 +6351,7 @@ EOM ;; esac -$rm -f fred fred.? dyna.$dlext dyna.? +$rm -f fred fred.? dyna.$dlext dyna.? tmp-dyna.? set d_dlsymun eval $setvar @@ -5697,7 +6381,7 @@ main() { EOCP : check sys/file.h first to get FREAD on Sun if $test `./findhdr sys/file.h` && \ - $cc $cppflags "-DI_SYS_FILE" open3.c -o open3 >/dev/null 2>&1 ; then + $cc $ccflags "-DI_SYS_FILE" -o open3 $ldflags open3.c $libs >/dev/null 2>&1 ; then h_sysfile=true; echo "<sys/file.h> defines the O_* constants..." >&4 if ./open3; then @@ -5708,7 +6392,7 @@ if $test `./findhdr sys/file.h` && \ val="$undef" fi elif $test `./findhdr fcntl.h` && \ - $cc "-DI_FCNTL" open3.c -o open3 >/dev/null 2>&1 ; then + $cc $ccflags "-DI_FCNTL" -o open3 $ldflags open3.c $libs >/dev/null 2>&1 ; then h_fcntl=true; echo "<fcntl.h> defines the O_* constants..." >&4 if ./open3; then @@ -5873,7 +6557,7 @@ EOCP *) echo "However, your read() returns '$status' on EOF??";; esac val="$define" - if test "$status" -eq "$rd_nodata"; then + if test "$status" = "$rd_nodata"; then echo "WARNING: you can't distinguish between EOF and no data!" val="$undef" fi @@ -5943,8 +6627,8 @@ eval $inlibc set getlogin d_getlogin eval $inlibc -: see if getpgrp exists -set getpgrp d_getpgrp +: see if getpgid exists +set getpgid d_getpgid eval $inlibc : see if getpgrp2 exists @@ -5959,6 +6643,25 @@ eval $inlibc set getpriority d_getprior eval $inlibc +: see if gettimeofday or ftime exists +set gettimeofday d_gettimeod +eval $inlibc +case "$d_gettimeod" in +"$undef") + set ftime d_ftime + eval $inlibc + ;; +*) + val="$undef"; set d_ftime; eval $setvar + ;; +esac +case "$d_gettimeod$d_ftime" in +"$undef$undef") + echo " " + echo 'No ftime() nor gettimeofday() -- timing may be less accurate.' >&4 + ;; +esac + : see if this is a netinet/in.h or sys/in.h system set netinet/in.h i_niin sys/in.h i_sysin eval $inhdr @@ -6052,6 +6755,10 @@ set d_strchr; eval $setvar val="$vali" set d_index; eval $setvar +: check whether inet_aton exists +set inet_aton d_inetaton +eval $inlibc + : Look for isascii echo " " $cat >isascii.c <<'EOCP' @@ -6362,13 +7069,59 @@ eval $inlibc set rmdir d_rmdir eval $inlibc +: see if memory.h is available. +val='' +set memory.h val +eval $inhdr + +: See if it conflicts with string.h +case "$val" in +$define) + case "$strings" in + '') ;; + *) + $cppstdin $cppflags $cppminus < $strings > mem.h + if $contains 'memcpy' mem.h >/dev/null 2>&1; then + echo " " + echo "We won't be including <memory.h>." + val="$undef" + fi + $rm -f mem.h + ;; + esac +esac +set i_memory +eval $setvar + : can bcopy handle overlapping blocks? val="$undef" case "$d_bcopy" in "$define") echo " " echo "Checking to see if your bcopy() can do overlapping copies..." >&4 - $cat >foo.c <<'EOCP' + $cat >foo.c <<EOCP +#$i_memory I_MEMORY +#$i_stdlib I_STDLIB +#$i_string I_STRING +#$i_unistd I_UNISTD +EOCP + $cat >>foo.c <<'EOCP' +#include <stdio.h> + +#ifdef I_MEMORY +# include <memory.h> +#endif +#ifdef I_STDLIB +# include <stdlib.h> +#endif +#ifdef I_STRING +# include <string.h> +#else +# include <strings.h> +#endif +#ifdef I_UNISTD +# include <unistd.h> /* Needed for NetBSD */ +#endif main() { char buf[128], abc[128]; @@ -6377,6 +7130,8 @@ int len; int off; int align; +/* Copy "abcde..." string to char abc[] so that gcc doesn't + try to store the string in read-only memory. */ bcopy("abcdefghijklmnopqrstuvwxyz0123456789", abc, 36); for (align = 7; align >= 0; align--) { @@ -6394,15 +7149,22 @@ for (align = 7; align >= 0; align--) { exit(0); } EOCP - if $cc $ccflags $ldflags foo.c -o safebcpy $libs >/dev/null 2>&1; then + if $cc $optimize $ccflags $ldflags foo.c \ + -o safebcpy $libs >/dev/null 2>&1; then if ./safebcpy 2>/dev/null; then echo "Yes, it can." val="$define" else echo "It can't, sorry." + case "$d_memmove" in + "$define") echo "But that's Ok since you have memmove()." ;; + esac fi else echo "(I can't compile the test program, so we'll assume not...)" + case "$d_memmove" in + "$define") echo "But that's Ok since you have memmove()." ;; + esac fi ;; esac @@ -6416,7 +7178,29 @@ case "$d_memcpy" in "$define") echo " " echo "Checking to see if your memcpy() can do overlapping copies..." >&4 - $cat >foo.c <<'EOCP' + $cat >foo.c <<EOCP +#$i_memory I_MEMORY +#$i_stdlib I_STDLIB +#$i_string I_STRING +#$i_unistd I_UNISTD +EOCP + $cat >>foo.c <<'EOCP' +#include <stdio.h> + +#ifdef I_MEMORY +# include <memory.h> +#endif +#ifdef I_STDLIB +# include <stdlib.h> +#endif +#ifdef I_STRING +# include <string.h> +#else +# include <strings.h> +#endif +#ifdef I_UNISTD +# include <unistd.h> /* Needed for NetBSD */ +#endif main() { char buf[128], abc[128]; @@ -6425,6 +7209,8 @@ int len; int off; int align; +/* Copy "abcde..." string to char abc[] so that gcc doesn't + try to store the string in read-only memory. */ memcpy(abc, "abcdefghijklmnopqrstuvwxyz0123456789", 36); for (align = 7; align >= 0; align--) { @@ -6442,15 +7228,22 @@ for (align = 7; align >= 0; align--) { exit(0); } EOCP - if $cc $ccflags $ldflags foo.c -o safemcpy $libs >/dev/null 2>&1; then + if $cc $optimize $ccflags $ldflags foo.c \ + -o safemcpy $libs >/dev/null 2>&1; then if ./safemcpy 2>/dev/null; then echo "Yes, it can." val="$define" else echo "It can't, sorry." + case "$d_memmove" in + "$define") echo "But that's Ok since you have memmove()." ;; + esac fi else echo "(I can't compile the test program, so we'll assume not...)" + case "$d_memmove" in + "$define") echo "But that's Ok since you have memmove()." ;; + esac fi ;; esac @@ -6458,6 +7251,61 @@ $rm -f foo.* safemcpy core set d_safemcpy eval $setvar +: can memcmp be trusted to compare relative magnitude? +val="$undef" +case "$d_memcmp" in +"$define") + echo " " + echo "Checking to see if your memcmp() can compare relative magnitude..." >&4 + $cat >foo.c <<EOCP +#$i_memory I_MEMORY +#$i_stdlib I_STDLIB +#$i_string I_STRING +#$i_unistd I_UNISTD +EOCP + $cat >>foo.c <<'EOCP' +#include <stdio.h> + +#ifdef I_MEMORY +# include <memory.h> +#endif +#ifdef I_STDLIB +# include <stdlib.h> +#endif +#ifdef I_STRING +# include <string.h> +#else +# include <strings.h> +#endif +#ifdef I_UNISTD +# include <unistd.h> /* Needed for NetBSD */ +#endif +main() +{ +char a = -1; +char b = 0; +if ((a < b) && memcmp(&a, &b, 1) < 0) + exit(1); +exit(0); +} +EOCP + if $cc $optimize $ccflags $ldflags foo.c \ + -o sanemcmp $libs >/dev/null 2>&1; then + if ./sanemcmp 2>/dev/null; then + echo "Yes, it can." + val="$define" + else + echo "No, it can't (it uses signed chars)." + fi + else + echo "(I can't compile the test program, so we'll assume not...)" + fi + ;; +esac +$rm -f foo.* sanemcmp core +set d_sanemcmp +eval $setvar + : see if select exists set select d_select eval $inlibc @@ -6543,6 +7391,59 @@ eval $inlibc set setsid d_setsid eval $inlibc +: see if sfio.h is available +set sfio.h i_sfio +eval $inhdr + + +: see if sfio library is available +case "$i_sfio" in +$define) + val='' + set sfreserve val + eval $inlibc + ;; +*) + val="$undef" + ;; +esac +: Ok, but do we want to use it. +case "$val" in +$define) + case "$usesfio" in + true|$define|[yY]*) dflt='y';; + *) dflt='n';; + esac + echo "$package can use the sfio library, but it is experimental." + rp="You seem to have sfio available, do you want to try using it?" + . ./myread + case "$ans" in + y|Y) ;; + *) echo "Ok, avoiding sfio this time. I'll use stdio instead." + val="$undef" + : Remove sfio from list of libraries to use + set `echo X $libs | $sed -e 's/-lsfio / /' -e 's/-lsfio$//'` + shift + libs="$*" + echo "libs = $libs" >&4 + ;; + esac + ;; +*) case "$usesfio" in + true|$define|[yY]*) + echo "Sorry, cannot find sfio on this machine" >&4 + echo "Ignoring your setting of usesfio=$usesfio" >&4 + ;; + esac + ;; +esac +set d_sfio +eval $setvar +case "$d_sfio" in +$define) usesfio='true';; +*) usesfio='false';; +esac + : see if shmctl exists set shmctl d_shmctl eval $inlibc @@ -6605,34 +7506,44 @@ fi set d_shm eval $setvar -: see if sigvector exists -- since sigvec will match the substring echo " " -if set sigvector val -f d_sigvectr; eval $csym; $val; then - echo 'sigvector() found--you must be running HP-UX.' >&4 - val="$define"; set d_sigvectr; eval $setvar - val="$define"; set d_sigvec; eval $setvar +: see if we have sigaction +if set sigaction val -f d_sigaction; eval $csym; $val; then + echo 'sigaction() found.' >&4 + val="$define" else -: try the original name - d_sigvectr="$undef" - if set sigvec val -f d_sigvec; eval $csym; $val; then - echo 'sigvec() found.' >&4 - val="$define"; set d_sigvec; eval $setvar - else - echo 'sigvec() not found--race conditions with signals may occur.' >&4 - val="$undef"; set d_sigvec; eval $setvar - fi + echo 'sigaction NOT found.' >&4 + val="$undef" fi -: see if we have sigaction -set sigaction d_sigaction -eval $inlibc +$cat > set.c <<'EOP' +/* Solaris 2.5_x86 with SunWorks Pro C 3.0.1 doesn't have a complete + sigaction structure if compiled with cc -Xc. This compile test + will fail then. <doughera@lafcol.lafayette.edu> +*/ +#include <stdio.h> +#include <sys/types.h> +#include <signal.h> +main() +{ + struct sigaction act, oact; +} +EOP +if $cc $ccflags $ldflags -o set set.c $libs >/dev/null 2>&1; then + : +else + echo "But you don't seem to have a useable struct sigaction." >&4 + val="$undef" +fi +set d_sigaction; eval $setvar +$rm -f set set.o set.c : see if sigsetjmp exists echo " " case "$d_sigsetjmp" in '') - $cat >set.c <<EOP + $cat >set.c <<'EOP' #include <setjmp.h> sigjmp_buf env; int set = 1; @@ -6645,25 +7556,26 @@ main() exit(1); } EOP - if $cc $ccflags $ldflags set.c -o set $libs >/dev/null 2>&1; then + if $cc $ccflags $ldflags -o set set.c $libs > /dev/null 2>&1 ; then if ./set >/dev/null 2>&1; then echo "POSIX sigsetjmp found." >&4 val="$define" else - $cat <<EOM + $cat >&4 <<EOM Uh-Oh! You have POSIX sigsetjmp and siglongjmp, but they do not work properly!! +I'll ignore them. EOM val="$undef" fi else - echo "Sigsetjmp not found." >&4 + echo "sigsetjmp not found." >&4 val="$undef" fi ;; *) val="$d_sigsetjmp" case "$d_sigsetjmp" in $define) echo "POSIX sigsetjmp found." >&4;; - $undef) echo "Sigsetjmp not found." >&4;; + $undef) echo "sigsetjmp not found." >&4;; esac ;; esac @@ -6692,10 +7604,10 @@ else : we will have to assume that it supports the 4.2 BSD interface d_oldsock="$undef" else - echo "You don't have Berkeley networking in libc.a..." >&4 - if test -f /usr/lib/libnet.a; then - ( (nm $nm_opt /usr/lib/libnet.a | eval $nm_extract) || \ - ar t /usr/lib/libnet.a) 2>/dev/null >> libc.list + echo "You don't have Berkeley networking in libc$lib_ext..." >&4 + if test -f /usr/lib/libnet$lib_ext; then + ( (nm $nm_opt /usr/lib/libnet$lib_ext | eval $nm_extract) || \ + ar t /usr/lib/libnet$lib_ext) 2>/dev/null >> libc.list if $contains socket libc.list >/dev/null 2>&1; then echo "...but the Wollongong group seems to have hacked it in." >&4 socketlib="-lnet" @@ -6708,7 +7620,7 @@ else d_oldsock="$define" fi else - echo "or even in libnet.a, which is peculiar." >&4 + echo "or even in libnet$lib_ext, which is peculiar." >&4 d_socket="$undef" d_oldsock="$undef" fi @@ -6790,7 +7702,7 @@ $cat >try.c <<EOP #include <stdio.h> #define FILE_ptr(fp) $stdio_ptr #define FILE_cnt(fp) $stdio_cnt -main() { +main() { FILE *fp = fopen("try.c", "r"); char c = getc(fp); if ( @@ -6832,6 +7744,7 @@ esac set d_stdio_cnt_lval eval $setvar + : see if _base is also standard val="$undef" case "$d_stdstdio" in @@ -6840,7 +7753,7 @@ $define) #include <stdio.h> #define FILE_base(fp) $stdio_base #define FILE_bufsiz(fp) $stdio_bufsiz -main() { +main() { FILE *fp = fopen("try.c", "r"); char c = getc(fp); if ( @@ -6853,7 +7766,7 @@ main() { EOP if $cc $ccflags $ldflags -o try try.c $libs > /dev/null 2>&1; then if ./try; then - echo "Even its _base field acts std." + echo "And its _base field acts std." val="$define" else echo "But its _base field isn't std." @@ -6932,6 +7845,18 @@ else d_strerrm='"unknown"' fi +: see if strtod exists +set strtod d_strtod +eval $inlibc + +: see if strtol exists +set strtol d_strtol +eval $inlibc + +: see if strtoul exists +set strtoul d_strtoul +eval $inlibc + : see if strxfrm exists set strxfrm d_strxfrm eval $inlibc @@ -7235,7 +8160,7 @@ EOCP dflt=`./try` else dflt='8' - echo"(I can't seem to compile the test program...)" + echo "(I can't seem to compile the test program...)" fi ;; *) dflt="$alignbytes" @@ -7246,25 +8171,6 @@ rp="Doubles must be aligned on a how-many-byte boundary?" alignbytes="$ans" $rm -f try.c try -: Define several unixisms. Hints files or command line options -: can be used to override them. -case "$ar" in -'') ar='ar';; -esac -case "$lib_ext" in -'') lib_ext='.a';; -esac -case "$obj_ext" in -'') obj_ext='.o';; -esac -case "$path_sep" in -'') path_sep=':';; -esac -: Which makefile gets called first. This is used by make depend. -case "$firstmakefile" in -'') firstmakefile='makefile';; -esac - : check for ordering of bytes in a long case "$byteorder" in '') @@ -7361,6 +8267,55 @@ set db.h i_db eval $inhdr case "$i_db" in +$define) + : Check db version. We can not use version 2. + echo " " + echo "Checking Berkeley DB version ..." >&4 + $cat >try.c <<EOCP +#$d_const HASCONST +#ifndef HASCONST +#define const +#endif +#include <sys/types.h> +#include <stdio.h> +#include <db.h> +main() +{ +#ifdef DB_VERSION_MAJOR /* DB version >= 2: not yet. */ + printf("You have Berkeley DB Version %d.%d\n", + DB_VERSION_MAJOR, DB_VERSION_MINOR); + printf("Perl currently only supports up to version 1.86.\n"); + exit(2); +#else +#if defined(_DB_H_) && defined(BTREEMAGIC) && defined(HASHMAGIC) + exit(0); /* DB version < 2: the coast is clear. */ +#else + exit(1); /* <db.h> not Berkeley DB? */ +#endif +#endif +} +EOCP + if $cc $optimize $ccflags $ldflags -o try try.c $libs && ./try; then + echo 'Looks OK. (Perl supports up to version 1.86).' >&4 + else + echo "I can't use Berkeley DB with your <db.h>. I'll disable Berkeley DB." >&4 + i_db=$undef + case " $libs " in + *"-ldb "*) + : Remove db from list of libraries to use + echo "Removing unusable -ldb from library list" >&4 + set `echo X $libs | $sed -e 's/-ldb / /' -e 's/-ldb$//'` + shift + libs="$*" + echo "libs = $libs" >&4 + ;; + esac + fi + $rm -f try.* + ;; +esac + +case "$i_db" in define) : Check the return type needed for hash echo " " @@ -7390,13 +8345,15 @@ EOCP db_hashtype='u_int32_t' fi else - echo "I can't seem to compile the test program." >&4 - db_hashtype=int + : XXX Maybe we should just give up here. + db_hashtype=u_int32_t + echo "Help: I can't seem to compile the db test program." >&4 + echo "Something's wrong, but I'll assume you use $db_hashtype." >&4 fi $rm -f try.* echo "Your version of Berkeley DB uses $db_hashtype for hash." ;; -*) db_hashtype=int +*) db_hashtype=u_int32_t ;; esac @@ -7430,13 +8387,15 @@ EOCP db_prefixtype='size_t' fi else - echo "I can't seem to compile the test program." >&4 - db_prefixtype='int' + db_prefixtype='size_t' + : XXX Maybe we should just give up here. + echo "Help: I can't seem to compile the db test program." >&4 + echo "Something's wrong, but I'll assume you use $db_prefixtype." >&4 fi $rm -f try.* echo "Your version of Berkeley DB uses $db_prefixtype for prefix." ;; -*) db_prefixtype='int' +*) db_prefixtype='size_t' ;; esac @@ -7456,9 +8415,9 @@ case "$voidflags" in '') $cat >try.c <<'EOCP' #if TRY & 1 -void main() { +void sub() { #else -main() { +sub() { #endif extern void moo(); /* function returning void */ void (*goo)(); /* ptr to func returning void */ @@ -7476,8 +8435,9 @@ main() { #endif exit(0); } +main() { sub(); } EOCP - if $cc -c -DTRY=$defvoidused try.c >.out 2>&1 ; then + if $cc $ccflags -c -DTRY=$defvoidused try.c >.out 2>&1 ; then voidflags=$defvoidused echo "It appears to support void to the level $package wants ($defvoidused)." if $contains warning .out >/dev/null 2>&1; then @@ -7486,16 +8446,16 @@ EOCP fi else echo "Hmm, your compiler has some difficulty with void. Checking further..." >&4 - if $cc -c -DTRY=1 try.c >/dev/null 2>&1 ; then + if $cc $ccflags -c -DTRY=1 try.c >/dev/null 2>&1; then echo "It supports 1..." - if $cc -c -DTRY=3 try.c >/dev/null 2>&1 ; then + if $cc $ccflags -c -DTRY=3 try.c >/dev/null 2>&1; then echo "It also supports 2..." - if $cc -c -DTRY=7 try.c >/dev/null 2>&1 ; then + if $cc $ccflags -c -DTRY=7 try.c >/dev/null 2>&1; then voidflags=7 echo "And it supports 4 but not 8 definitely." else echo "It doesn't support 4..." - if $cc -c -DTRY=11 try.c >/dev/null 2>&1 ; then + if $cc $ccflags -c -DTRY=11 try.c >/dev/null 2>&1; then voidflags=11 echo "But it supports 8." else @@ -7505,11 +8465,11 @@ echo "Hmm, your compiler has some difficulty with void. Checking further..." >&4 fi else echo "It does not support 2..." - if $cc -c -DTRY=13 try.c >/dev/null 2>&1 ; then + if $cc $ccflags -c -DTRY=13 try.c >/dev/null 2>&1; then voidflags=13 echo "But it supports 4 and 8." else - if $cc -c -DTRY=5 try.c >/dev/null 2>&1 ; then + if $cc $ccflags -c -DTRY=5 try.c >/dev/null 2>&1; then voidflags=5 echo "And it supports 4 but has not heard about 8." else @@ -7570,20 +8530,24 @@ gidtype="$ans" set getgroups d_getgrps eval $inlibc -: Find type of 2nd arg to getgroups +: see if setgroups exists +set setgroups d_setgrps +eval $inlibc + +: Find type of 2nd arg to 'getgroups()' and 'setgroups()' echo " " -case "$d_getgrps" in -'define') +case "$d_getgrps$d_setgrps" in +*define*) case "$groupstype" in '') dflt="$gidtype" ;; *) dflt="$groupstype" ;; esac $cat <<EOM -What is the type of the second argument to getgroups()? Usually this -is the same as group ids, $gidtype, but not always. +What is the type of the second argument to getgroups() and setgroups()? +Usually this is the same as group ids, $gidtype, but not always. EOM - rp='What type is the second argument to getgroups()?' + rp='What type is the second argument to getgroups() and setgroups()?' . ./myread groupstype="$ans" ;; @@ -7599,6 +8563,42 @@ rp="What type is lseek's offset on this system declared as?" . ./myread lseektype="$ans" +echo " " +case "$make" in +'') + make=`./loc make make $pth` + case "$make" in + /*) echo make is in $make. ;; + ?:[\\/]*) echo make is in $make. ;; + *) echo "I don't know where 'make' is, and my life depends on it." >&4 + echo "Go find a make program or fix your PATH setting!" >&4 + exit 1 + ;; + esac + ;; +*) echo make is in $make. ;; +esac + +$echo $n "Checking if your $make program sets \$(MAKE)... $c" >&4 +case "$make_set_make" in +'') + $sed 's/^X //' > testmake.mak << 'EOF' +Xall: +X @echo 'ac_maketemp="$(MAKE)"' +EOF + : GNU make sometimes prints "make[1]: Entering...", which would confuse us. + case "`$make -f testmake.mak 2>/dev/null`" in + *ac_maketemp=*) make_set_make='#' ;; + *) make_set_make="MAKE=$make" ;; + esac + $rm -f testmake.mak + ;; +esac +case "$make_set_make" in +'#') echo "Yup, it does." >&4 ;; +*) echo "Nope, it doesn't." >&4 ;; +esac + : see what type is used for mode_t set mode_t modetype int stdio.h sys/types.h eval $typedef @@ -7656,8 +8656,18 @@ echo " " case "$randbits" in '') echo "Checking to see how many bits your rand function produces..." >&4 - $cat >try.c <<'EOCP' + $cat >try.c <<EOCP +#$i_unistd I_UNISTD +#$i_stdlib I_STDLIB #include <stdio.h> +#ifdef I_UNISTD +# include <unistd.h> +#endif +#ifdef I_STDLIB +# include <stdlib.h> +#endif +EOCP + $cat >>try.c <<'EOCP' main() { register int i; @@ -7671,9 +8681,10 @@ main() for (i = 0; max; i++) max /= 2; printf("%d\n",i); + fflush(stdout); } EOCP - if $cc try.c -o try >/dev/null 2>&1 ; then + if $cc $ccflags $ldflags -o try try.c $libs >/dev/null 2>&1 ; then dflt=`try` else dflt='?' @@ -7687,7 +8698,7 @@ esac rp='How many bits does your rand() function produce?' . ./myread randbits="$ans" -$rm -f try.c try +$rm -f try.c try.o try : see if ar generates random libraries by itself echo " " @@ -7700,14 +8711,14 @@ EOP $cc $ccflags -c bar1.c >/dev/null 2>&1 $cc $ccflags -c bar2.c >/dev/null 2>&1 $cc $ccflags -c foo.c >/dev/null 2>&1 -ar rc bar.a bar2.o bar1.o >/dev/null 2>&1 -if $cc $ccflags $ldflags -o foobar foo.o bar.a $libs > /dev/null 2>&1 && +ar rc bar$lib_ext bar2.o bar1.o >/dev/null 2>&1 +if $cc $ccflags $ldflags -o foobar foo.o bar$lib_ext $libs > /dev/null 2>&1 && ./foobar >/dev/null 2>&1; then echo "ar appears to generate random libraries itself." orderlib=false ranlib=":" -elif ar ts bar.a >/dev/null 2>&1 && - $cc $ccflags $ldflags -o foobar foo.o bar.a $libs > /dev/null 2>&1 && +elif ar ts bar$lib_ext >/dev/null 2>&1 && + $cc $ccflags $ldflags -o foobar foo.o bar$lib_ext $libs > /dev/null 2>&1 && ./foobar >/dev/null 2>&1; then echo "a table of contents needs to be added with 'ar ts'." orderlib=false @@ -7834,11 +8845,10 @@ $cat >fd_set.c <<EOCP #endif #ifdef I_SYS_TIME #include <sys/time.h> -#else +#endif #ifdef I_SYS_SELECT #include <sys/select.h> #endif -#endif main() { fd_set fds; @@ -7929,11 +8939,10 @@ EOM #endif #ifdef I_SYS_TIME #include <sys/time.h> -#else +#endif #ifdef I_SYS_SELECT #include <sys/select.h> #endif -#endif main() { int width; @@ -7998,13 +9007,59 @@ $cat > signal.c <<'EOP' #include <sys/types.h> #include <signal.h> int main() { -#ifdef NSIG -printf("NSIG %d\n", NSIG); -#else -#ifdef _NSIG -printf("NSIG %d\n", _NSIG); + +/* Strange style to avoid deeply-nested #if/#else/#endif */ +#ifndef NSIG +# ifdef _NSIG +# define NSIG (_NSIG) +# endif +#endif + +#ifndef NSIG +# ifdef SIGMAX +# define NSIG (SIGMAX+1) +# endif #endif + +#ifndef NSIG +# ifdef SIG_MAX +# define NSIG (SIG_MAX+1) +# endif +#endif + +#ifndef NSIG +# ifdef MAXSIG +# define NSIG (MAXSIG+1) +# endif +#endif + +#ifndef NSIG +# ifdef MAX_SIG +# define NSIG (MAX_SIG+1) +# endif +#endif + +#ifndef NSIG +# ifdef SIGARRAYSIZE +# define NSIG (SIGARRAYSIZE+1) /* Not sure of the +1 */ +# endif +#endif + +#ifndef NSIG +# ifdef _sys_nsig +# define NSIG (_sys_nsig) /* Solaris 2.5 */ +# endif +#endif + +/* Default to some arbitrary number that's big enough to get most + of the common signals. +*/ +#ifndef NSIG +# define NSIG 50 #endif + +printf("NSIG %d\n", NSIG); + EOP echo $xxx | $tr ' ' '\012' | $sort | $uniq | $awk ' { @@ -8051,7 +9106,7 @@ EOP $cat >signal_cmd <<EOS $startsh $test -s signal.lst && exit 0 -if $cc $ccflags signal.c -o signal $ldflags >/dev/null 2>&1; then +if $cc $ccflags $ldflags signal.c -o signal >/dev/null 2>&1; then ./signal | $sort -n +1 | $uniq | $awk -f signal.awk >signal.lst else echo "(I can't seem be able to compile the test program -- Guessing)" @@ -8063,7 +9118,7 @@ else 0) set HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM;; esac echo \$@ | $tr ' ' '\012' | \ - $awk '{ printf $1; printf " %d\n", ++s; }' >signal.lst + $awk '{ printf \$1; printf " %d\n", ++s; }' >signal.lst fi $rm -f signal.c signal signal.o EOS @@ -8132,25 +9187,36 @@ main() printf("int\n"); else printf("long\n"); + fflush(stdout); + exit(0); } EOM echo " " -if $cc $ccflags $ldflags -o ssize ssize.c $libs > /dev/null 2>&1 ; then - ssizetype=`./ssize` +# If $libs contains -lsfio, and sfio is mis-configured, then it +# sometimes (apparently) runs and exits with a 0 status, but with no +# output!. Thus we check with test -s whether we actually got any +# output. I think it has to do with sfio's use of _exit vs. exit, +# but I don't know for sure. --Andy Dougherty 1/27/97. +if $cc $optimize $ccflags $ldflags -o ssize ssize.c $libs > /dev/null 2>&1 && + ./ssize > ssize.out 2>/dev/null && test -s ssize.out ; then + ssizetype=`$cat ssize.out` echo "I'll be using $ssizetype for functions returning a byte count." >&4 else - echo "(I can't compile the test program--please enlighten me!)" - $cat <<EOM + $cat >&4 <<EOM + +Help! I can't compile and run the ssize_t test program: please enlighten me! +(This is probably a misconfiguration in your system or libraries, and +you really ought to fix it. Still, I'll try anyway.) I need a type that is the same size as $sizetype, but is guaranteed to -be signed. Common values are int and long. +be signed. Common values are ssize_t, int and long. EOM rp="What signed type is the same size as $sizetype?" . ./myread ssizetype="$ans" fi -$rm -f ssize ssize.[co] +$rm -f ssize ssize.[co] ssize.out : see what type of char stdio uses. echo " " @@ -8296,30 +9362,6 @@ eval $inhdr set math.h i_math eval $inhdr -: see if memory.h is available. -val='' -set memory.h val -eval $inhdr - -: See if it conflicts with string.h -case "$val" in -$define) - case "$strings" in - '') ;; - *) - $cppstdin $cppflags $cppminus < $strings > mem.h - if $contains 'memcpy' mem.h >/dev/null 2>&1; then - echo " " - echo "We won't be including <memory.h>." - val="$undef" - fi - $rm -f mem.h - ;; - esac -esac -set i_memory -eval $setvar - : see if ndbm.h is available set ndbm.h t_ndbm eval $inhdr @@ -8658,6 +9700,10 @@ eval $setvar set sys/param.h i_sysparam eval $inhdr +: see if sys/resource.h has to be included +set sys/resource.h i_sysresrc +eval $inhdr + : see if sys/stat.h is available set sys/stat.h i_sysstat eval $inhdr @@ -8670,14 +9716,18 @@ eval $inhdr set sys/un.h i_sysun eval $inhdr -: see if this is a unistd.h system -set unistd.h i_unistd +: see if this is a syswait system +set sys/wait.h i_syswait eval $inhdr : see if this is an utime system set utime.h i_utime eval $inhdr +: see if this is a values.h system +set values.h i_values +eval $inhdr + : see if this is a vfork system case "$d_vfork" in "$define") @@ -8720,19 +9770,22 @@ known_extensions='' : some additional extensions into the source tree and expect them : to be built. for xxx in * ; do - if $test -f $xxx/$xxx.xs; then - known_extensions="$known_extensions $xxx" + case "$xxx" in + DynaLoader) ;; + *) if $test -f $xxx/$xxx.xs; then + known_extensions="$known_extensions $xxx" else - if $test -d $xxx; then - cd $xxx - for yyy in * ; do - if $test -f $yyy/$yyy.xs; then - known_extensions="$known_extensions $xxx/$yyy" - fi - done - cd .. - fi - fi + if $test -d $xxx; then + cd $xxx + for yyy in * ; do + if $test -f $yyy/$yyy.xs; then + known_extensions="$known_extensions $xxx/$yyy" + fi + done + cd .. + fi + fi ;; + esac done set X $known_extensions shift @@ -8763,7 +9816,7 @@ for xxx in $known_extensions ; do true|define|y) avail_ext="$avail_ext $xxx" ;; esac ;; - SAFE) case "$usesafe" in + Opcode) case "$useopcode" in true|define|y) avail_ext="$avail_ext $xxx" ;; esac ;; @@ -8912,10 +9965,10 @@ echo "Creating config.sh..." >&4 $spitshell <<EOT >config.sh $startsh # -# This file was produced by running the Configure script. It holds all the -# definitions figured out by Configure. Should you modify one of these values, -# do not forget to propagate your changes by running "Configure -der". You may -# instead choose to run each of the .SH files by yourself, or "Configure -S". +# This file was produced by running the Configure script. It holds all +# the definitions figured out by Configure. Should you modify any of +# these values, do not forget to propagate your changes by running +# "Configure -S"; or, equivalently, you may run each .SH file yourself. # # Configuration time: $cf_time @@ -8945,6 +9998,7 @@ awk='$awk' baserev='$baserev' bash='$bash' bin='$bin' +bincompat3='$bincompat3' binexp='$binexp' bison='$bison' byacc='$byacc' @@ -8984,8 +10038,11 @@ d_archlib='$d_archlib' d_attribut='$d_attribut' d_bcmp='$d_bcmp' d_bcopy='$d_bcopy' +d_bincompat3='$d_bincompat3' d_bsd='$d_bsd' +d_bsdgetpgrp='$d_bsdgetpgrp' d_bsdpgrp='$d_bsdpgrp' +d_bsdsetpgrp='$d_bsdsetpgrp' d_bzero='$d_bzero' d_casti32='$d_casti32' d_castneg='$d_castneg' @@ -9020,16 +10077,22 @@ d_flock='$d_flock' d_fork='$d_fork' d_fpathconf='$d_fpathconf' d_fsetpos='$d_fsetpos' +d_ftime='$d_ftime' d_getgrps='$d_getgrps' +d_setgrps='$d_setgrps' d_gethent='$d_gethent' d_gethname='$d_gethname' d_getlogin='$d_getlogin' +d_getpgid='$d_getpgid' d_getpgrp2='$d_getpgrp2' d_getpgrp='$d_getpgrp' d_getppid='$d_getppid' d_getprior='$d_getprior' +d_gettimeod='$d_gettimeod' +d_gnulibc='$d_gnulibc' d_htonl='$d_htonl' d_index='$d_index' +d_inetaton='$d_inetaton' d_isascii='$d_isascii' d_killpg='$d_killpg' d_link='$d_link' @@ -9075,6 +10138,7 @@ d_rewinddir='$d_rewinddir' d_rmdir='$d_rmdir' d_safebcpy='$d_safebcpy' d_safemcpy='$d_safemcpy' +d_sanemcmp='$d_sanemcmp' d_seekdir='$d_seekdir' d_select='$d_select' d_sem='$d_sem' @@ -9096,18 +10160,15 @@ d_setreuid='$d_setreuid' d_setrgid='$d_setrgid' d_setruid='$d_setruid' d_setsid='$d_setsid' +d_sfio='$d_sfio' d_shm='$d_shm' d_shmat='$d_shmat' d_shmatprototype='$d_shmatprototype' d_shmctl='$d_shmctl' d_shmdt='$d_shmdt' d_shmget='$d_shmget' -d_shrplib='$d_shrplib' d_sigaction='$d_sigaction' -d_sigintrp='$d_sigintrp' d_sigsetjmp='$d_sigsetjmp' -d_sigvec='$d_sigvec' -d_sigvectr='$d_sigvectr' d_socket='$d_socket' d_sockpair='$d_sockpair' d_statblks='$d_statblks' @@ -9120,6 +10181,9 @@ d_strcoll='$d_strcoll' d_strctcpy='$d_strctcpy' d_strerrm='$d_strerrm' d_strerror='$d_strerror' +d_strtod='$d_strtod' +d_strtol='$d_strtol' +d_strtoul='$d_strtoul' d_strxfrm='$d_strxfrm' d_suidsafe='$d_suidsafe' d_symlink='$d_symlink' @@ -9178,6 +10242,7 @@ glibpth='$glibpth' grep='$grep' groupcat='$groupcat' groupstype='$groupstype' +gzip='$gzip' h_fcntl='$h_fcntl' h_sysfile='$h_sysfile' hint='$hint' @@ -9203,6 +10268,7 @@ i_neterrno='$i_neterrno' i_niin='$i_niin' i_pwd='$i_pwd' i_rpcsvcdbm='$i_rpcsvcdbm' +i_sfio='$i_sfio' i_sgtty='$i_sgtty' i_stdarg='$i_stdarg' i_stddef='$i_stddef' @@ -9215,6 +10281,7 @@ i_sysin='$i_sysin' i_sysioctl='$i_sysioctl' i_sysndir='$i_sysndir' i_sysparam='$i_sysparam' +i_sysresrc='$i_sysresrc' i_sysselct='$i_sysselct' i_syssockio='$i_syssockio' i_sysstat='$i_sysstat' @@ -9223,11 +10290,13 @@ i_systimek='$i_systimek' i_systimes='$i_systimes' i_systypes='$i_systypes' i_sysun='$i_sysun' +i_syswait='$i_syswait' i_termio='$i_termio' i_termios='$i_termios' i_time='$i_time' i_unistd='$i_unistd' i_utime='$i_utime' +i_values='$i_values' i_varargs='$i_varargs' i_varhdr='$i_varhdr' i_vfork='$i_vfork' @@ -9251,6 +10320,7 @@ ldflags='$ldflags' less='$less' lib_ext='$lib_ext' libc='$libc' +libperl='$libperl' libpth='$libpth' libs='$libs' libswanted='$libswanted' @@ -9261,6 +10331,7 @@ ln='$ln' lns='$lns' locincpth='$locincpth' loclibpth='$loclibpth' +longsize='$longsize' lp='$lp' lpr='$lpr' ls='$ls' @@ -9268,6 +10339,7 @@ lseektype='$lseektype' mail='$mail' mailx='$mailx' make='$make' +make_set_make='$make_set_make' mallocobj='$mallocobj' mallocsrc='$mallocsrc' malloctype='$malloctype' @@ -9334,7 +10406,8 @@ sh='$sh' shar='$shar' sharpbang='$sharpbang' shmattype='$shmattype' -shrpdir='$shrpdir' +shortsize='$shortsize' +shrpenv='$shrpenv' shsharp='$shsharp' sig_name='$sig_name' sig_num='$sig_num' @@ -9382,8 +10455,11 @@ uniq='$uniq' usedl='$usedl' usemymalloc='$usemymalloc' usenm='$usenm' +useopcode='$useopcode' +useperlio='$useperlio' useposix='$useposix' -usesafe='$usesafe' +usesfio='$usesfio' +useshrplib='$useshrplib' usevfork='$usevfork' usrinc='$usrinc' uuname='$uuname' @@ -9391,6 +10467,7 @@ vi='$vi' voidflags='$voidflags' xlibpth='$xlibpth' zcat='$zcat' +zip='$zip' EOT : add special variables diff --git a/gnu/usr.bin/perl/EXTERN.h b/gnu/usr.bin/perl/EXTERN.h index dedd37958c1..228ed524065 100644 --- a/gnu/usr.bin/perl/EXTERN.h +++ b/gnu/usr.bin/perl/EXTERN.h @@ -1,6 +1,6 @@ /* EXTERN.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -15,12 +15,32 @@ */ #undef EXT #undef dEXT +#undef EXTCONST +#undef dEXTCONST #if defined(VMS) && !defined(__GNUC__) # define EXT globalref # define dEXT globaldef {"$GLOBAL_RW_VARS"} noshare +# define EXTCONST globalref +# define dEXTCONST globaldef {"$GLOBAL_RO_VARS"} readonly #else -# define EXT extern -# define dEXT +# if (defined(_MSC_VER) && defined(_WIN32)) || (defined(__BORLANDC__) && defined(__WIN32__)) +# ifdef PERLDLL +# define EXT extern __declspec(dllexport) +# define dEXT +# define EXTCONST extern __declspec(dllexport) const +# define dEXTCONST const +# else +# define EXT extern __declspec(dllimport) +# define dEXT +# define EXTCONST extern __declspec(dllimport) const +# define dEXTCONST const +# endif +# else +# define EXT extern +# define dEXT +# define EXTCONST extern const +# define dEXTCONST const +# endif #endif #undef INIT diff --git a/gnu/usr.bin/perl/INSTALL b/gnu/usr.bin/perl/INSTALL index 3274ddbb7e7..488a1ce870a 100644 --- a/gnu/usr.bin/perl/INSTALL +++ b/gnu/usr.bin/perl/INSTALL @@ -4,7 +4,7 @@ Install - Build and Installation guide for perl5. =head1 SYNOPSIS -The basic steps to build and install perl5 are: +The basic steps to build and install perl5 on a Unix system are: rm -f config.sh sh Configure @@ -12,43 +12,98 @@ The basic steps to build and install perl5 are: make test make install + # You may also wish to add these: + (cd /usr/include && h2ph *.h sys/*.h) + (installhtml --help) + (cd pod && make tex && <process the latex files>) + Each of these is explained in further detail below. +For information on non-Unix systems, see the section on +L<"Porting information"> below. + +For information on what's new in this release, see the +pod/perldelta.pod file. For more detailed information about specific +changes, see the Changes file. + +=head1 DESCRIPTION + +This document is written in pod format as an easy way to indicate its +structure. The pod format is described in pod/perlpod.pod, but you can +read it as is with any pager or editor. Headings and items are marked +by lines beginning with '='. The other mark-up used is + + B<text> embolden text, used for switches, programs or commands + C<code> literal code + L<name> A link (cross reference) to name + You should probably at least skim through this entire document before -proceeding. Special notes specific to this release are identified -by B<NOTE>. +proceeding. + +If you're building Perl on a non-Unix system, you should also read +the README file specific to your operating system, since this may +provide additional or different instructions for building Perl. + +If there is a hint file for your system (in the hints/ directory) you +should also read that hint file for specific information for your +system. (Unixware users should use the svr4.sh hint file.) + +=head1 Space Requirements -=head1 BUILDING PERL5 +The complete perl5 source tree takes up about 7 MB of disk space. The +complete tree after completing make takes roughly 15 MB, though the +actual total is likely to be quite system-dependent. The installation +directories need something on the order of 7 MB, though again that +value is system-dependent. -=head1 Start with a Fresh Distribution. +=head1 Start with a Fresh Distribution If you have built perl before, you should clean out the build directory with the command make realclean - + The results of a Configure run are stored in the config.sh file. If you are upgrading from a previous version of perl, or if you change systems or compilers or make other significant changes, or if you are -experiencing difficulties building perl, you should probably I<not> +experiencing difficulties building perl, you should probably not re-use your old config.sh. Simply remove it or rename it, e.g. mv config.sh config.sh.old -Then run Configure. +If you wish to use your old config.sh, be especially attentive to the +version and architecture-specific questions and answers. For example, +the default directory for architecture-dependent library modules +includes the version name. By default, Configure will reuse your old +name (e.g. /opt/perl/lib/i86pc-solaris/5.003) even if you're running +Configure for a different version, e.g. 5.004. Yes, Configure should +probably check and correct for this, but it doesn't, presently. +Similarly, if you used a shared libperl.so (see below) with version +numbers, you will probably want to adjust them as well. + +Also, be careful to check your architecture name. Some Linux systems +(such as Debian) use i386, while others may use i486 or i586. If you +pick up a precompiled binary, it might not use the same name. + +In short, if you wish to use your old config.sh, I recommend running +Configure interactively rather than blindly accepting the defaults. -=head1 Run Configure. +=head1 Run Configure Configure will figure out various things about your system. Some things Configure will figure out for itself, other things it will ask -you about. To accept the default, just press C<RETURN>. The default -is almost always ok. +you about. To accept the default, just press RETURN. The default +is almost always ok. At any Configure prompt, you can type &-d +and Configure will use the defaults from then on. After it runs, Configure will perform variable substitution on all the -F<*.SH> files and offer to run B<make depend>. +*.SH files and offer to run make depend. -Configure supports a number of useful options. Run B<Configure -h> -to get a listing. To compile with gcc, for example, you can run +Configure supports a number of useful options. Run B<Configure -h> to +get a listing. See the Porting/Glossary file for a complete list of +Configure variables you can set and their definitions. + +To compile with gcc, for example, you should run sh Configure -Dcc=gcc @@ -58,11 +113,6 @@ compiler) so that the hints files can set appropriate defaults. If you want to use your old config.sh but override some of the items with command line options, you need to use B<Configure -O>. -If you are willing to accept all the defaults, and you want terse -output, you can run - - sh Configure -des - By default, for most systems, perl will be installed in /usr/local/{bin, lib, man}. You can specify a different 'prefix' for the default installation directory, when Configure prompts you or by @@ -74,39 +124,80 @@ e.g. If your prefix contains the string "perl", then the directories are simplified. For example, if you use prefix=/opt/perl, then Configure will suggest /opt/perl/lib instead of -/usr/local/lib/perl5/. +/opt/perl/lib/perl5/. -By default, Configure will compile perl to use dynamic loading, if +NOTE: You must not specify an installation directory that is below +your perl source directory. If you do, installperl will attempt +infinite recursion. + +By default, Configure will compile perl to use dynamic loading if your system supports it. If you want to force perl to be compiled -statically, you can either choose this when Configure prompts you or by -using the Configure command line option -Uusedl. +statically, you can either choose this when Configure prompts you or +you can use the Configure command line option -Uusedl. + +If you are willing to accept all the defaults, and you want terse +output, you can run + + sh Configure -des + +For my Solaris system, I usually use + + sh Configure -Dprefix=/opt/perl -Doptimize='-xpentium -xO4' -des + +=head2 GNU-style configure + +If you prefer the GNU-style configure command line interface, you can +use the supplied configure command, e.g. + + CC=gcc ./configure + +The configure script emulates a few of the more common configure +options. Try + + ./configure --help + +for a listing. + +Cross compiling is not supported. + +For systems that do not distinguish the files "Configure" and +"configure", Perl includes a copy of configure named +configure.gnu. =head2 Extensions By default, Configure will offer to build every extension which appears to be supported. For example, Configure will offer to build GDBM_File only if it is able to find the gdbm library. (See examples below.) -DynaLoader, Fcntl and FileHandle are always built by default. -Configure does not contain code to test for POSIX compliance, so POSIX -is always built by default as well. If you wish to skip POSIX, you can -set the Configure variable useposix=false either in a hint file or from -the Configure command line. Similarly, the Safe extension is always -built by default, but you can skip it by setting the Configure variable -usesafe=false either in a hint file for from the command line. +DynaLoader, Fcntl, and IO are always built by default. Configure does +not contain code to test for POSIX compliance, so POSIX is always built +by default as well. If you wish to skip POSIX, you can set the +Configure variable useposix=false either in a hint file or from the +Configure command line. Similarly, the Opcode extension is always built +by default, but you can skip it by setting the Configure variable +useopcode=false either in a hint file for from the command line. + +You can learn more about each of these extensions by consulting the +documentation in the individual .pm modules, located under the +ext/ subdirectory. + +Even if you do not have dynamic loading, you must still build the +DynaLoader extension; you should just build the stub dl_none.xs +version. (Configure will suggest this as the default.) In summary, here are the Configure command-line variables you can set to turn off each extension: DB_File i_db - DynaLoader (Must always be included) + DynaLoader (Must always be included as a static extension) Fcntl (Always included by default) - FileHandle (Always included by default) GDBM_File i_gdbm + IO (Always included by default) NDBM_File i_ndbm ODBM_File i_dbm POSIX useposix SDBM_File (Always included by default) - Safe usesafe + Opcode useopcode Socket d_socket Thus to skip the NDBM_File extension, you can use @@ -117,67 +208,56 @@ Again, this is taken care of automatically if you don't have the ndbm library. Of course, you may always run Configure interactively and select only -the Extensions you want. +the extensions you want. + +Note: The DB_File module will only work with version 1.x of +Berkeley DB. Once Berkeley DB version 2 is released, DB_File will be +upgraded to work with it. Configure will automatically detect this +for you and refuse to try to build DB_File with version 2. Finally, if you have dynamic loading (most modern Unix systems do) remember that these extensions do not increase the size of your perl executable, nor do they impact start-up time, so you probably might as well build all the ones that will work on your system. -=head2 GNU-style configure - -If you prefer the GNU-style B<configure> command line interface, you can -use the supplied B<configure> command, e.g. - - CC=gcc ./configure - -The B<configure> script emulates several of the more common configure -options. Try - - ./configure --help - -for a listing. - -Cross compiling is currently not supported. - =head2 Including locally-installed libraries Perl5 comes with interfaces to number of database extensions, including dbm, ndbm, gdbm, and Berkeley db. For each extension, if Configure can find the appropriate header files and libraries, it will automatically include that extension. The gdbm and db libraries -are B<not> included with perl. See the library documentation for +are not included with perl. See the library documentation for how to obtain the libraries. -I<Note:> If your database header (.h) files are not in a +Note: If your database header (.h) files are not in a directory normally searched by your C compiler, then you will need to -include the appropriate B<-I/your/directory> option when prompted by +include the appropriate -I/your/directory option when prompted by Configure. If your database library (.a) files are not in a directory normally searched by your C compiler and linker, then you will need to -include the appropriate B<-L/your/directory> option when prompted by +include the appropriate -L/your/directory option when prompted by Configure. See the examples below. =head2 Examples =over 4 -=item gdbm in /usr/local. +=item gdbm in /usr/local Suppose you have gdbm and want Configure to find it and build the -GDBM_File extension. This examples assumes you have F<gdbm.h> -installed in F</usr/local/include/gdbm.h> and F<libgdbm.a> installed in -F</usr/local/lib/libgdbm.a>. Configure should figure all the +GDBM_File extension. This examples assumes you have gdbm.h +installed in /usr/local/include/gdbm.h and libgdbm.a installed in +/usr/local/lib/libgdbm.a. Configure should figure all the necessary steps out automatically. Specifically, when Configure prompts you for flags for -your C compiler, you should include C<-I/usr/local/include>. +your C compiler, you should include -I/usr/local/include. When Configure prompts you for linker flags, you should include -C<-L/usr/local/lib>. +-L/usr/local/lib. If you are using dynamic loading, then when Configure prompts you for linker flags for dynamic loading, you should again include -C<-L/usr/local/lib>. +-L/usr/local/lib. Again, this should all happen automatically. If you want to accept the defaults for all the questions and have Configure print out only terse @@ -194,11 +274,11 @@ This should actually work if you have gdbm installed in any of Suppose you have gdbm installed in some place other than /usr/local/, but you still want Configure to find it. To be specific, assume you -have F</usr/you/include/gdbm.h> and F</usr/you/lib/libgdbm.a>. You -still have to add B<-I/usr/you/include> to cc flags, but you have to take -an extra step to help Configure find F<libgdbm.a>. Specifically, when +have /usr/you/include/gdbm.h and /usr/you/lib/libgdbm.a. You +still have to add -I/usr/you/include to cc flags, but you have to take +an extra step to help Configure find libgdbm.a. Specifically, when Configure prompts you for library directories, you have to add -F</usr/you/lib> to the list. +/usr/you/lib to the list. It is possible to specify this from the command line too (all on one line): @@ -207,13 +287,13 @@ line): -Dlocincpth="/usr/you/include" \ -Dloclibpth="/usr/you/lib" -C<locincpth> is a space-separated list of include directories to search. -Configure will automatically add the appropriate B<-I> directives. +locincpth is a space-separated list of include directories to search. +Configure will automatically add the appropriate -I directives. -C<loclibpth> is a space-separated list of library directories to search. -Configure will automatically add the appropriate B<-L> directives. If -you have some libraries under F</usr/local/> and others under -F</usr/you>, then you have to include both, namely +loclibpth is a space-separated list of library directories to search. +Configure will automatically add the appropriate -L directives. If +you have some libraries under /usr/local/ and others under +/usr/you, then you have to include both, namely sh Configure -des \ -Dlocincpth="/usr/you/include /usr/local/include" \ @@ -221,17 +301,22 @@ F</usr/you>, then you have to include both, namely =back -=head2 Installation Directories. +=head2 Installation Directories The installation directories can all be changed by answering the appropriate questions in Configure. For convenience, all the installation questions are near the beginning of Configure. +I highly recommend running Configure interactively to be sure it puts +everything where you want it. At any point during the Configure +process, you can answer a question with &-d and Configure +will use the defaults from then on. + By default, Configure uses the following directories for library files (archname is a string like sun4-sunos, determined by Configure) - /usr/local/lib/perl5/archname/5.002 + /usr/local/lib/perl5/archname/5.004 /usr/local/lib/perl5/ /usr/local/lib/perl5/site_perl/archname /usr/local/lib/perl5/site_perl @@ -243,17 +328,29 @@ and the following directories for manual pages: (Actually, Configure recognizes the SVR3-style /usr/local/man/l_man/man1 directories, if present, and uses those -instead.) The module man pages are stuck in that strange spot so that +instead.) + +The module man pages are stuck in that strange spot so that they don't collide with other man pages stored in /usr/local/man/man3, and so that Perl's man pages don't hide system man pages. On some systems, B<man less> would end up calling up Perl's less.pm module man -page, rather than the B<less> program. +page, rather than the less program. (This default location will likely +change to /usr/local/man/man3 in a future release of perl.) + +Note: Many users prefer to store the module man pages in +/usr/local/man/man3. You can do this from the command line with + + sh Configure -Dman3dir=/usr/local/man/man3 + +Some users also prefer to use a .3pm suffix. You can do that with + + sh Configure -Dman3ext=3pm If you specify a prefix that contains the string "perl", then the -directory structure is simplified. For example, if you Configure -with -Dprefix=/opt/perl, then the defaults are +directory structure is simplified. For example, if you Configure with +-Dprefix=/opt/perl, then the defaults are - /opt/perl/lib/archname/5.002 + /opt/perl/lib/archname/5.004 /opt/perl/lib /opt/perl/lib/site_perl/archname /opt/perl/lib/site_perl @@ -269,14 +366,14 @@ intended to be used for installing local or site-wide extensions. Perl will automatically look in these directories. Previously, most sites just put their local extensions in with the standard distribution. -In order to support using things like #!/usr/local/bin/perl5.002 after +In order to support using things like #!/usr/local/bin/perl5.004 after a later version is released, architecture-dependent libraries are stored in a version-specific directory, such as -/usr/local/lib/perl5/archname/5.002/. In 5.000 and 5.001, these files -were just stored in /usr/local/lib/perl5/archname/. If you will not be -using 5.001 binaries, you can delete the standard extensions from the -/usr/local/lib/perl5/archname/ directory. Locally-added extensions can -be moved to the site_perl and site_perl/archname directories. +/usr/local/lib/perl5/archname/5.004/. In Perl 5.000 and 5.001, these +files were just stored in /usr/local/lib/perl5/archname/. If you will +not be using 5.001 binaries, you can delete the standard extensions from +the /usr/local/lib/perl5/archname/ directory. Locally-added extensions +can be moved to the site_perl and site_perl/archname directories. Again, these are just the defaults, and can be changed as you run Configure. @@ -287,19 +384,17 @@ Configure distinguishes between the directory in which perl (and its associated files) should be installed and the directory in which it will eventually reside. For most sites, these two are the same; for sites that use AFS, this distinction is handled automatically. -However, sites that use software such as B<depot> to manage software +However, sites that use software such as depot to manage software packages may also wish to install perl into a different directory and use that management software to move perl to its final destination. This section describes how to do this. Someday, Configure may support -an option C<-Dinstallprefix=/foo> to simplify this. +an option -Dinstallprefix=/foo to simplify this. -Suppose you want to install perl under the F</tmp/perl5> directory. -You can edit F<config.sh> and change all the install* variables to -point to F</tmp/perl5> instead of F</usr/local/wherever>. You could -also set them all from the Configure command line. Or, you can -automate this process by placing the following lines in a file -F<config.over> B<before> you run Configure (replace /tmp/perl5 by a -directory of your choice): +Suppose you want to install perl under the /tmp/perl5 directory. You +can edit config.sh and change all the install* variables to point to +/tmp/perl5 instead of /usr/local/wherever. Or, you can automate this +process by placing the following lines in a file config.over before you +run Configure (replace /tmp/perl5 by a directory of your choice): installprefix=/tmp/perl5 test -d $installprefix || mkdir $installprefix @@ -312,7 +407,6 @@ directory of your choice): installscript=`echo $installscript | sed "s!$prefix!$installprefix!"` installsitelib=`echo $installsitelib | sed "s!$prefix!$installprefix!"` installsitearch=`echo $installsitearch | sed "s!$prefix!$installprefix!"` - shrpdir=`echo $shrpdir | sed "s!$prefix!$installprefix!"` Then, you can Configure and install in the usual way: @@ -334,11 +428,334 @@ installed on multiple systems. Here's one way to do that: make test make install cd /tmp/perl5 + # Edit lib/<archname>/<version>/Config.pm to change all the + # install* variables back to reflect where everything will + # really be installed. tar cvf ../perl5-archive.tar . # Then, on each machine where you want to install perl, cd /usr/local # Or wherever you specified as $prefix tar xvf perl5-archive.tar +=head2 Configure-time Options + +There are several different ways to Configure and build perl for your +system. For most users, the defaults are sensible and will work. +Some users, however, may wish to further customize perl. Here are +some of the main things you can change. + +=head2 Binary Compatibility With Earlier Versions of Perl 5 + +If you have dynamically loaded extensions that you built under +perl 5.003 and that you wish to continue to use with perl 5.004, then you +need to ensure that 5.004 remains binary compatible with 5.003. + +Starting with Perl 5.003, all functions in the Perl C source code have +been protected by default by the prefix Perl_ (or perl_) so that you +may link with third-party libraries without fear of namespace +collisions. This change broke compatibility with version 5.002, so +installing 5.003 or 5.004 over 5.002 or earlier will force you to +re-build and install all of your dynamically loadable extensions. +(The standard extensions supplied with Perl are handled +automatically). You can turn off this namespace protection by adding +-DNO_EMBED to your ccflags variable in config.sh. + +Perl 5.003's namespace protection was incomplete, but this has +been fixed in 5.004. However, some sites may need to maintain +complete binary compatibility with Perl 5.003. If you are building +Perl for such a site, then when Configure asks if you want binary +compatibility, answer "y". + +On the other hand, if you are embedding perl into another application +and want the maximum namespace protection, then you probably ought to +answer "n" when Configure asks if you want binary compatibility, or +disable it from the Configure command line with + + sh Configure -Ud_bincompat3 + +The default answer of "y" to maintain binary compatibility is probably +appropriate for almost everyone. + +In a related issue, old extensions may possibly be affected by the +changes in the Perl language in the current release. Please see +pod/perldelta.pod for a description of what's changed. + +=head2 Selecting File IO mechanisms + +Previous versions of perl used the standard IO mechanisms as defined in +stdio.h. Versions 5.003_02 and later of perl allow alternate IO +mechanisms via a "PerlIO" abstraction, but the stdio mechanism is still +the default and is the only supported mechanism. + +This PerlIO abstraction can be enabled either on the Configure command +line with + + sh Configure -Duseperlio + +or interactively at the appropriate Configure prompt. + +If you choose to use the PerlIO abstraction layer, there are two +(experimental) possibilities for the underlying IO calls. These have been +tested to some extent on some platforms, but are not guaranteed to work +everywhere. + +=over 4 + +=item 1. + +AT&T's "sfio". This has superior performance to stdio.h in many +cases, and is extensible by the use of "discipline" modules. Sfio +currently only builds on a subset of the UNIX platforms perl supports. +Because the data structures are completely different from stdio, perl +extension modules or external libraries may not work. This +configuration exists to allow these issues to be worked on. + +This option requires the 'sfio' package to have been built and installed. +A (fairly old) version of sfio is in CPAN, and work is in progress to make +it more easily buildable by adding Configure support. + +You select this option by + + sh Configure -Duseperlio -Dusesfio + +If you have already selected -Duseperlio, and if Configure detects +that you have sfio, then sfio will be the default suggested by +Configure. + +Note: On some systems, sfio's iffe configuration script fails +to detect that you have an atexit function (or equivalent). +Apparently, this is a problem at least for some versions of Linux +and SunOS 4. + +You can test if you have this problem by trying the following shell +script. (You may have to add some extra cflags and libraries. A +portable version of this may eventually make its way into Configure.) + + #!/bin/sh + cat > try.c <<'EOCP' + #include <stdio.h> + main() { printf("42\n"); } + EOCP + cc -o try try.c -lsfio + val=`./try` + if test X$val = X42; then + echo "Your sfio looks ok" + else + echo "Your sfio has the exit problem." + fi + +If you have this problem, the fix is to go back to your sfio sources +and correct iffe's guess about atexit (or whatever is appropriate for +your platform.) + +There also might be a more recent release of Sfio that fixes your +problem. + +=item 2. + +Normal stdio IO, but with all IO going through calls to the PerlIO +abstraction layer. This configuration can be used to check that perl and +extension modules have been correctly converted to use the PerlIO +abstraction. + +This configuration should work on all platforms (but might not). + +You select this option via: + + sh Configure -Duseperlio -Uusesfio + +If you have already selected -Duseperlio, and if Configure does not +detect sfio, then this will be the default suggested by Configure. + +=back + +=head2 Building a shared libperl.so Perl library + +Currently, for most systems, the main perl executable is built by +linking the "perl library" libperl.a with perlmain.o, your static +extensions (usually just DynaLoader.a) and various extra libraries, +such as -lm. + +On some systems that support dynamic loading, it may be possible to +replace libperl.a with a shared libperl.so. If you anticipate building +several different perl binaries (e.g. by embedding libperl into +different programs, or by using the optional compiler extension), then +you might wish to build a shared libperl.so so that all your binaries +can share the same library. + +The disadvantages are that there may be a significant performance +penalty associated with the shared libperl.so, and that the overall +mechanism is still rather fragile with respect to different versions +and upgrades. + +In terms of performance, on my test system (Solaris 2.5_x86) the perl +test suite took roughly 15% longer to run with the shared libperl.so. +Your system and typical applications may well give quite different +results. + +The default name for the shared library is typically something like +libperl.so.3.2 (for Perl 5.003_02) or libperl.so.302 or simply +libperl.so. Configure tries to guess a sensible naming convention +based on your C library name. Since the library gets installed in a +version-specific architecture-dependent directory, the exact name +isn't very important anyway, as long as your linker is happy. + +For some systems (mostly SVR4), building a shared libperl is required +for dynamic loading to work, and hence is already the default. + +You can elect to build a shared libperl by + + sh Configure -Duseshrplib + +To actually build perl, you must add the current working directory to your +LD_LIBRARY_PATH environment variable before running make. You can do +this with + + LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH + +for Bourne-style shells, or + + setenv LD_LIBRARY_PATH `pwd` + +for Csh-style shells. You *MUST* do this before running make. +Folks running NeXT OPENSTEP must substitute DYLD_LIBRARY_PATH for +LD_LIBRARY_PATH above. + +There is also an potential problem with the shared perl library if you +want to have more than one "flavor" of the same version of perl (e.g. +with and without -DDEBUGGING). For example, suppose you build and +install a standard Perl 5.004 with a shared library. Then, suppose you +try to build Perl 5.004 with -DDEBUGGING enabled, but everything else +the same, including all the installation directories. How can you +ensure that your newly built perl will link with your newly built +libperl.so.4 rather with the installed libperl.so.4? The answer is +that you might not be able to. The installation directory is encoded +in the perl binary with the LD_RUN_PATH environment variable (or +equivalent ld command-line option). On Solaris, you can override that +with LD_LIBRARY_PATH; on Linux you can't. On Digital Unix, you can +override LD_LIBRARY_PATH by setting the _RLD_ROOT environment variable +to point to the perl build directory. + +The only reliable answer is that you should specify a different +directory for the architecture-dependent library for your -DDEBUGGING +version of perl. You can do this by changing all the *archlib* +variables in config.sh, namely archlib, archlib_exp, and +installarchlib, to point to your new architecture-dependent library. + +=head2 Malloc Issues + +Perl relies heavily on malloc(3) to grow data structures as needed, so +perl's performance can be noticeably affected by the performance of +the malloc function on your system. + +The perl source is shipped with a version of malloc that is very fast +but somewhat wasteful of space. On the other hand, your system's +malloc() function is probably a bit slower but also a bit more frugal. + +For many uses, speed is probably the most important consideration, so +the default behavior (for most systems) is to use the malloc supplied +with perl. However, if you will be running very large applications +(e.g. Tk or PDL) or if your system already has an excellent malloc, or +if you are experiencing difficulties with extensions that use +third-party libraries that call malloc, then you might wish to use +your system's malloc. (Or, you might wish to explore the experimental +malloc flags discussed below.) + +To build without perl's malloc, you can use the Configure command + + sh Configure -Uusemymalloc + +or you can answer 'n' at the appropriate interactive Configure prompt. + +=head2 Malloc Performance Flags + +If you are using Perl's malloc, you may add one or +more of the following items to your cflags config.sh variable +to change its behavior in potentially useful ways. You can find out +more about these flags by reading the malloc.c source. +In a future version of perl, these might be enabled by default. + +=over 4 + +=item -DPERL_EMERGENCY_SBRK + +If PERL_EMERGENCY_SBRK is defined, running out of memory need not be a +fatal error: a memory pool can allocated by assigning to the special +variable $^M. See perlvar(1) for more details. + +=item -DPACK_MALLOC + +If PACK_MALLOC is defined, malloc.c uses a slightly different +algorithm for small allocations (up to 64 bytes long). Such small +allocations are quite common in typical Perl scripts. + +The expected memory savings (with 8-byte alignment in $alignbytes) is +about 20% for typical Perl usage. The expected slowdown due to the +additional malloc overhead is in fractions of a percent. (It is hard +to measure because of the effect of the saved memory on speed). + +=item -DTWO_POT_OPTIMIZE + +If TWO_POT_OPTIMIZE is defined, malloc.c uses a slightly different +algorithm for large allocations that are close to a power of two +(starting with 16K). Such allocations are typical for big hashes and +special-purpose scripts, especially image processing. If you will be +manipulating very large blocks with sizes close to powers of two, it +might be wise to define this macro. + +The expected saving of memory is 0-100% (100% in applications which +require most memory in such 2**n chunks). The expected slowdown is +negligible. + +=back + +=head2 Building a debugging perl + +You can run perl scripts under the perl debugger at any time with +B<perl -d your_script>. If, however, you want to debug perl itself, +you probably want to do + + sh Configure -Doptimize='-g' + +This will do two independent things: First, it will force compilation +to use cc -g so that you can use your system's debugger on the +executable. (Note: Your system may actually require something like +cc -g2. Check you man pages for cc(1) and also any hint file for your +system.) Second, it will add -DDEBUGGING to your ccflags variable in +config.sh so that you can use B<perl -D> to access perl's internal +state. (Note: Configure will only add -DDEBUGGING by +default if you are not reusing your old config.sh. If you want to +reuse your old config.sh, then you can just edit it and change the +optimize and ccflags variables by hand and then propagate your changes +as shown in L<"Propagating your changes to config.sh"> below.) + +You can actually specify -g and -DDEBUGGING independently, but usually +it's convenient to have both. + +If you are using a shared libperl, see the warnings about multiple +versions of perl under L<Building a shared libperl.so Perl library>. + +=head2 Other Compiler Flags + +For most users, all of the Configure defaults are fine. However, +you can change a number of factors in the way perl is built +by adding appropriate -D directives to your ccflags variable in +config.sh. + +For example, you can replace the rand() and srand() functions in the +perl source by any other random number generator by a trick such as the +following: + + sh Configure -Dccflags='-Drand=random -Dsrand=srandom' + +or by adding -Drand=random and -Dsrand=srandom to your ccflags +at the appropriate Configure prompt. (Note: Although this worked for +me, it might not work for you if your system's header files give +different prototypes for rand() and random() or srand() and srandom().) + +You should also run Configure interactively to verify that a hint file +doesn't inadvertently override your ccflags setting. (Hints files +shouldn't do that, but some might.) + =head2 What if it doesn't work? =over 4 @@ -350,15 +767,15 @@ Configure interactively so that you can check (and correct) its guesses. All the installation questions have been moved to the top, so you don't -have to wait for them. Once you've handled them (and your C compiler & -flags) you can type '&-d' at the next Configure prompt and Configure +have to wait for them. Once you've handled them (and your C compiler and +flags) you can type &-d at the next Configure prompt and Configure will use the defaults from then on. If you find yourself trying obscure command line incantations and config.over tricks, I recommend you run Configure interactively instead. You'll probably save yourself time in the long run. -=item Hint files. +=item Hint files The perl distribution includes a number of system-specific hints files in the hints/ directory. If one of them matches your system, Configure @@ -366,7 +783,7 @@ will offer to use that hint file. Several of the hint files contain additional important information. If you have any problems, it is a good idea to read the relevant hint -file for further information. See F<hints/solaris_2.sh> for an +file for further information. See hints/solaris_2.sh for an extensive example. =item *** WHOA THERE!!! *** @@ -398,24 +815,31 @@ Now, Configure will find your gdbm library and will issue a message: The previous value for $i_gdbm on this machine was "undef"! Keep the previous value? [y] -In this case, you do I<not> want to keep the previous value, so you -should answer 'n'. (You'll also have to manuually add GDBM_File to +In this case, you do not want to keep the previous value, so you +should answer 'n'. (You'll also have to manually add GDBM_File to the list of dynamic extensions to build.) =item Changing Compilers If you change compilers or make other significant changes, you should -probably I<not> re-use your old config.sh. Simply remove it or +probably not re-use your old config.sh. Simply remove it or rename it, e.g. mv config.sh config.sh.old. Then rerun Configure with the options you want to use. -This is a common source of problems. If you change from B<cc> to -B<gcc>, you should almost always remove your old config.sh. +This is a common source of problems. If you change from cc to +gcc, you should almost always remove your old config.sh. + +=item Propagating your changes to config.sh + +If you make any changes to config.sh, you should propagate +them to all the .SH files by running -=item Propagating your changes + sh Configure -S -If you later make any changes to F<config.sh>, you should propagate -them to all the .SH files by running B<sh Configure -S>. +You will then have to rebuild by running + + make depend + make =item config.over @@ -423,48 +847,64 @@ You can also supply a shell script config.over to over-ride Configure's guesses. It will get loaded up at the very end, just before config.sh is created. You have to be careful with this, however, as Configure does no checking that your changes make sense. See the section on -changing the installation directory for an example. +L<"Changing the installation directory"> for an example. =item config.h -Many of the system dependencies are contained in F<config.h>. -F<Configure> builds F<config.h> by running the F<config_h.SH> script. -The values for the variables are taken from F<config.sh>. +Many of the system dependencies are contained in config.h. +Configure builds config.h by running the config_h.SH script. +The values for the variables are taken from config.sh. -If there are any problems, you can edit F<config.h> directly. Beware, -though, that the next time you run B<Configure>, your changes will be +If there are any problems, you can edit config.h directly. Beware, +though, that the next time you run Configure, your changes will be lost. =item cflags If you have any additional changes to make to the C compiler command -line, they can be made in F<cflags.SH>. For instance, to turn off the -optimizer on F<toke.c>, find the line in the switch structure for -F<toke.c> and put the command C<optimize='-g'> before the C<;;>. You -can also edit F<cflags> directly, but beware that your changes will be -lost the next time you run B<Configure>. +line, they can be made in cflags.SH. For instance, to turn off the +optimizer on toke.c, find the line in the switch structure for +toke.c and put the command optimize='-g' before the ;; . You +can also edit cflags directly, but beware that your changes will be +lost the next time you run Configure. -To change the C flags for all the files, edit F<config.sh> -and change either C<$ccflags> or C<$optimize>, -and then re-run B<sh Configure -S ; make depend>. +To change the C flags for all the files, edit config.sh +and change either $ccflags or $optimize, +and then re-run -=item No sh. + sh Configure -S + make depend + +=item No sh If you don't have sh, you'll have to copy the sample file config_H to config.h and edit the config.h to reflect your system's peculiarities. You'll probably also have to extensively modify the extension building mechanism. +=item Porting information + +Specific information for the OS/2, Plan9, VMS and Win32 ports is in the +corresponding README files and subdirectories. Additional information, +including a glossary of all those config.sh variables, is in the Porting +subdirectory. + +Ports for other systems may also be available. You should check out +http://www.perl.com/CPAN/ports for current information on ports to +various other operating systems. + =back =head1 make depend This will look for all the includes. -The output is stored in F<makefile>. The only difference between -F<Makefile> and F<makefile> is the dependencies at the bottom of -F<makefile>. If you have to make any changes, you should edit -F<makefile>, not F<Makefile> since the Unix B<make> command reads -F<makefile> first. +The output is stored in makefile. The only difference between +Makefile and makefile is the dependencies at the bottom of +makefile. If you have to make any changes, you should edit +makefile, not Makefile since the Unix make command reads +makefile first. (On non-Unix systems, the output may be stored in +a different file. Check the value of $firstmakefile in your config.sh +if in doubt.) Configure will offer to do this step for you, so it isn't listed explicitly above. @@ -474,138 +914,322 @@ explicitly above. This will attempt to make perl in the current directory. If you can't compile successfully, try some of the following ideas. +If none of them help, and careful reading of the error message and +the relevant manual pages on your system doesn't help, you can +send a message to either the comp.lang.perl.misc newsgroup or to +perlbug@perl.com with an accurate description of your problem. +See L<"Reporting Problems"> below. =over 4 -=item * +=item hints If you used a hint file, try reading the comments in the hint file for further tips and information. -=item * +=item extensions -If you can't compile successfully, try adding a C<-DCRIPPLED_CC> flag. -(Just because you get no errors doesn't mean it compiled right!) -This simplifies some complicated expressions for compilers that -get indigestion easily. If that has no effect, try turning off -optimization. If you have missing routines, you probably need to -add some library or other, or you need to undefine some feature that -Configure thought was there but is defective or incomplete. - -=item * - -Some compilers will not compile or optimize the larger files without -some extra switches to use larger jump offsets or allocate larger -internal tables. You can customize the switches for each file in -F<cflags>. It's okay to insert rules for specific files into -F<makefile> since a default rule only takes effect in the absence of a -specific rule. - -=item * - -If you can successfully build F<miniperl>, but the process crashes +If you can successfully build miniperl, but the process crashes during the building of extensions, you should run make minitest to test your version of miniperl. -=item * +=item locale -Some additional things that have been reported for either perl4 or perl5: +If you have any locale-related environment variables set, try +unsetting them. I have some reports that some versions of IRIX hang +while running B<./miniperl configpm> with locales other than the C +locale. See the discussion under L<make test> below about locales. -Genix may need to use libc rather than libc_s, or #undef VARARGS. +=item malloc duplicates -NCR Tower 32 (OS 2.01.01) may need -W2,-Sl,2000 and #undef MKDIR. +If you get duplicates upon linking for malloc et al, add -DHIDEMYMALLOC +or -DEMBEDMYMALLOC to your ccflags variable in config.sh. -UTS may need one or more of B<-DCRIPPLED_CC>, B<-K> or B<-g>, and undef LSTAT. +=item varargs -If you get syntax errors on '(', try -DCRIPPLED_CC. +If you get varargs problems with gcc, be sure that gcc is installed +correctly. When using gcc, you should probably have i_stdarg='define' +and i_varargs='undef' in config.sh. The problem is usually solved by +running fixincludes correctly. If you do change config.sh, don't +forget to propagate your changes (see +L<"Propagating your changes to config.sh"> below). +See also the L<"vsprintf"> item below. -Machines with half-implemented dbm routines will need to #undef I_ODBM +=item croak -SCO prior to 3.2.4 may be missing dbmclose(). An upgrade to 3.2.4 -that includes libdbm.nfs (which includes dbmclose()) may be available. +If you get error messages such as the following (the exact line +numbers will vary in different versions of perl): -If you get duplicates upon linking for malloc et al, say -DHIDEMYMALLOC. + util.c: In function `Perl_croak': + util.c:962: number of arguments doesn't match prototype + proto.h:45: prototype declaration -If you get duplicate function definitions (a perl function has the -same name as another function on your system) try -DEMBED. +it might well be a symptom of the gcc "varargs problem". See the +previous L<"varargs"> item. -If you get varags problems with gcc, be sure that gcc is installed -correctly. When using gcc, you should probably have i_stdarg='define' -and i_varags='undef' in config.sh. The problem is usually solved -by running fixincludes correctly. +=item Solaris and SunOS dynamic loading If you have problems with dynamic loading using gcc on SunOS or Solaris, and you are using GNU as and GNU ld, you may need to add -B<-B/bin/> (for SunOS) or B<-B/usr/ccs/bin> (for Solaris) to your +-B/bin/ (for SunOS) or -B/usr/ccs/bin/ (for Solaris) to your $ccflags, $ldflags, and $lddlflags so that the system's versions of as -and ld are used. +and ld are used. Note that the trailing '/' is required. +Alternatively, you can use the GCC_EXEC_PREFIX +environment variable to ensure that Sun's as and ld are used. Consult +your gcc documentation for further information on the -B option and +the GCC_EXEC_PREFIX variable. + +One convenient way to ensure you are not using GNU as and ld is to +invoke Configure with + + sh Configure -Dcc='gcc -B/usr/ccs/bin/' + +for Solaris systems. For a SunOS system, you must use -B/bin/ +instead. + +Alternatively, recent versions of GNU ld reportedly work if you +include C<-Wl,-export-dynamic> in the ccdlflags variable in +config.sh. + +=item ld.so.1: ./perl: fatal: relocation error: + +If you get this message on SunOS or Solaris, and you're using gcc, +it's probably the GNU as or GNU ld problem in the previous item +L<"Solaris and SunOS dynamic loading">. + +=item LD_LIBRARY_PATH If you run into dynamic loading problems, check your setting of -the LD_LIBRARY_PATH environment variable. Perl should build +the LD_LIBRARY_PATH environment variable. If you're creating a static +Perl library (libperl.a rather than libperl.so) it should build fine with LD_LIBRARY_PATH unset, though that may depend on details of your local set-up. +=item dlopen: stub interception failed + +The primary cause of the 'dlopen: stub interception failed' message is +that the LD_LIBRARY_PATH environment variable includes a directory +which is a symlink to /usr/lib (such as /lib). + +The reason this causes a problem is quite subtle. The file libdl.so.1.0 +actually *only* contains functions which generate 'stub interception +failed' errors! The runtime linker intercepts links to +"/usr/lib/libdl.so.1.0" and links in internal implementation of those +functions instead. [Thanks to Tim Bunce for this explanation.] + +=item nm extraction + If Configure seems to be having trouble finding library functions, try not using nm extraction. You can do this from the command line with sh Configure -Uusenm +or by answering the nm extraction question interactively. +If you have previously run Configure, you should not reuse your old +config.sh. + +=item vsprintf + +If you run into problems with vsprintf in compiling util.c, the +problem is probably that Configure failed to detect your system's +version of vsprintf(). Check whether your system has vprintf(). +(Virtually all modern Unix systems do.) Then, check the variable +d_vprintf in config.sh. If your system has vprintf, it should be: + + d_vprintf='define' + +If Configure guessed wrong, it is likely that Configure guessed wrong +on a number of other common functions too. You are probably better off +re-running Configure without using nm extraction (see previous item). + +=item do_aspawn + +If you run into problems relating to do_aspawn or do_spawn, the +problem is probably that Configure failed to detect your system's +fork() function. Follow the procedure in the previous items +on L<"vsprintf"> and L<"nm extraction">. + +=item __inet_* errors + +If you receive unresolved symbol errors during Perl build and/or test +referring to __inet_* symbols, check to see whether BIND 8.1 is +installed. It installs a /usr/local/include/arpa/inet.h that refers to +these symbols. Versions of BIND later than 8.1 do not install inet.h +in that location and avoid the errors. You should probably update to a +newer version of BIND. If you can't, you can either link with the +updated resolver library provided with BIND 8.1 or rename +/usr/local/bin/arpa/inet.h during the Perl build and test process to +avoid the problem. + +=item Optimizer + +If you can't compile successfully, try turning off your compiler's +optimizer. Edit config.sh and change the line + + optimize='-O' + +to something like + + optimize=' ' + +then propagate your changes with B<sh Configure -S> and rebuild +with B<make depend; make>. + +=item CRIPPLED_CC + +If you still can't compile successfully, try adding a -DCRIPPLED_CC +flag. (Just because you get no errors doesn't mean it compiled right!) +This simplifies some complicated expressions for compilers that get +indigestion easily. + +=item Missing functions + +If you have missing routines, you probably need to add some library or +other, or you need to undefine some feature that Configure thought was +there but is defective or incomplete. Look through config.h for +likely suspects. + +=item toke.c + +Some compilers will not compile or optimize the larger files (such as +toke.c) without some extra switches to use larger jump offsets or +allocate larger internal tables. You can customize the switches for +each file in cflags. It's okay to insert rules for specific files into +makefile since a default rule only takes effect in the absence of a +specific rule. + +=item Missing dbmclose + +SCO prior to 3.2.4 may be missing dbmclose(). An upgrade to 3.2.4 +that includes libdbm.nfs (which includes dbmclose()) may be available. + +=item Note (probably harmless): No library found for -lsomething + +If you see such a message during the building of an extension, but +the extension passes its tests anyway (see L<"make test"> below), +then don't worry about the warning message. The extension +Makefile.PL goes looking for various libraries needed on various +systems; few systems will need all the possible libraries listed. +For example, a system may have -lcposix or -lposix, but it's +unlikely to have both, so most users will see warnings for the one +they don't have. The phrase 'probably harmless' is intended to +reassure you that nothing unusual is happening, and the build +process is continuing. + +On the other hand, if you are building GDBM_File and you get the +message + + Note (probably harmless): No library found for -lgdbm + +then it's likely you're going to run into trouble somewhere along +the line, since it's hard to see how you can use the GDBM_File +extension without the -lgdbm library. + +It is true that, in principle, Configure could have figured all of +this out, but Configure and the extension building process are not +quite that tightly coordinated. + +=item sh: ar: not found + +This is a message from your shell telling you that the command 'ar' +was not found. You need to check your PATH environment variable to +make sure that it includes the directory with the 'ar' command. This +is a common problem on Solaris, where 'ar' is in the /usr/ccs/bin +directory. + +=item db-recno failure on tests 51, 53 and 55 + +Old versions of the DB library (including the DB library which comes +with FreeBSD 2.1) had broken handling of recno databases with modified +bval settings. Upgrade your DB library or OS. + +=item Miscellaneous + +Some additional things that have been reported for either perl4 or perl5: + +Genix may need to use libc rather than libc_s, or #undef VARARGS. + +NCR Tower 32 (OS 2.01.01) may need -W2,-Sl,2000 and #undef MKDIR. + +UTS may need one or more of -DCRIPPLED_CC, -K or -g, and undef LSTAT. + +If you get syntax errors on '(', try -DCRIPPLED_CC. + +Machines with half-implemented dbm routines will need to #undef I_ODBM + =back =head1 make test -This will run the regression tests on the perl you just made. If it -doesn't say "All tests successful" then something went wrong. See the -file F<t/README> in the F<t> subdirectory. Note that you can't run it -in background if this disables opening of /dev/tty. If B<make test> -bombs out, just B<cd> to the F<t> directory and run B<TEST> by hand -to see if it makes any difference. -If individual tests bomb, you can run them by hand, e.g., +This will run the regression tests on the perl you just made (you +should run plain 'make' before 'make test' otherwise you won't have a +complete build). If 'make test' doesn't say "All tests successful" +then something went wrong. See the file t/README in the t subdirectory. + +Note that you can't run the tests in background if this disables +opening of /dev/tty. You can use 'make test-notty' in that case but +a few tty tests will be skipped. + +If make test bombs out, just cd to the t directory and run ./TEST +by hand to see if it makes any difference. If individual tests +bomb, you can run them by hand, e.g., ./perl op/groups.t -B<Note>: one possible reason for errors is that some external programs +Another way to get more detailed information about failed tests and +individual subtests is to cd to the t directory and run + + ./perl harness + +(this assumes that most basic tests succeed, since harness uses +complicated constructs). + +You should also read the individual tests to see if there are any helpful +comments that apply to your system. + +Note: One possible reason for errors is that some external programs may be broken due to the combination of your environment and the way -C<make test> exercises them. This may happen for example if you have -one or more of these environment variables set: -C<LC_ALL LC_CTYPE LANG>. In certain UNIXes especially the non-English -locales are known to cause programs to exhibit mysterious errors. +B<make test> exercises them. For example, this may happen if you have +one or more of these environment variables set: LC_ALL LC_CTYPE +LC_COLLATE LANG. In some versions of UNIX, the non-English locales +are known to cause programs to exhibit mysterious errors. + If you have any of the above environment variables set, please try -C<setenv LC_ALL C> or <LC_ALL=C;export LC_ALL>, for C<csh>-style and -C<Bourne>-style shells, respectively, from the command line and then -retry C<make test>. If the tests then succeed, you may have a broken -program that is confusing the testing. Please run the troublesome test -by hand as shown above and see whether you can locate the program. -Look for things like: -C<exec, `backquoted command`, system, open("|...")> or C<open("...|")>. -All these mean that Perl is trying to run some external program. -=head1 INSTALLING PERL5 + + setenv LC_ALL C + +(for C shell) or + + LC_ALL=C;export LC_ALL + +for Bourne or Korn shell) from the command line and then retry +make test. If the tests then succeed, you may have a broken program that +is confusing the testing. Please run the troublesome test by hand as +shown above and see whether you can locate the program. Look for +things like: exec, `backquoted command`, system, open("|...") or +open("...|"). All these mean that Perl is trying to run some +external program. =head1 make install This will put perl into the public directory you specified to -B<Configure>; by default this is F</usr/local/bin>. It will also try +Configure; by default this is /usr/local/bin. It will also try to put the man pages in a reasonable place. It will not nroff the man -page, however. You may need to be root to run B<make install>. If you +pages, however. You may need to be root to run B<make install>. If you are not root, you must own the directories in question and you should ignore any messages about chown not working. -B<NOTE:> In the 5.002 release, you will see some harmless error -messages and warnings from pod2man. You may safely ignore them. (Yes, -they should be fixed, but they didn't seem important enough to warrant -holding up the entire 5.002 release.) - If you want to see exactly what will happen without installing anything, you can run ./perl installperl -n ./perl installman -n -B<make install> will install the following: +make install will install the following: perl, perl5.nnn where nnn is the current release number. This @@ -618,12 +1242,16 @@ B<make install> will install the following: c2ph, pstruct Scripts for handling C structures in header files. s2p sed-to-perl translator find2perl find-to-perl translator + h2ph Extract constants and simple macros from C headers h2xs Converts C .h header files to Perl extensions. perlbug Tool to report bugs in Perl. perldoc Tool to read perl's pod documentation. + pl2pm Convert Perl 4 .pl files to Perl 5 .pm modules pod2html, Converters from perl's pod documentation format - pod2latex, and to other useful formats. - pod2man + pod2latex, to other useful formats. + pod2man, and + pod2text + splain Describe Perl warnings and errors library files in $privlib and $archlib specified to Configure, usually under /usr/local/lib/perl5/. @@ -640,104 +1268,177 @@ $sitearch listed in config.sh. Usually, these are something like where $archname is something like sun4-sunos. These directories will be used for installing extensions. -Perl's *.h header files and the libperl.a library are also -installed under $archlib so that any user may later build new -extensions even if the Perl source is no longer available. - -The libperl.a library is only needed for building new -extensions and linking them statically into a new perl executable. -If you will not be doing that, then you may safely delete -$archlib/libperl.a after perl is installed. - -make install may also offer to install perl in a "standard" location. - -Most of the documentation in the pod/ directory is also available -in HTML and LaTeX format. Type - - cd pod; make html; cd .. - -to generate the html versions, and - - cd pod; make tex; cd .. - -to generate the LaTeX versions. - -=head1 Coexistence with earlier versions of perl5. - -You can safely install the current version of perl5 and still run -scripts under the old binaries. Instead of starting your script with -#!/usr/local/bin/perl, just start it with #!/usr/local/bin/perl5.001 -(or whatever version you want to run.) - -The architecture-dependent files are stored in a version-specific -directory (such as F</usr/local/lib/perl5/sun4-sunos/5.002>) so that -they are still accessible. I<Note:> perl5.000 and perl5.001 did not -put their architecture-dependent libraries in a version-specific -directory. They are simply in F</usr/local/lib/perl5/$archname>. If -you will not be using 5.000 or 5.001, you may safely remove those -files. - -The standard library files in F</usr/local/lib/perl5> -should be useable by all versions of perl5. +Perl's *.h header files and the libperl.a library are also installed +under $archlib so that any user may later build new extensions, run the +optional Perl compiler, or embed the perl interpreter into another +program even if the Perl source is no longer available. + +=head1 Coexistence with earlier versions of perl5 + +You can safely install the current version of perl5 and still run scripts +under the old binaries for versions 5.003 and later ONLY. Instead of +starting your script with #!/usr/local/bin/perl, just start it with +#!/usr/local/bin/perl5.003 (or whatever version you want to run.) +If you want to retain a version of Perl 5 prior to 5.003, you'll +need to install the current version in a separate directory tree, +since some of the architecture-independent library files have changed +in incompatible ways. + +The old architecture-dependent files are stored in a version-specific +directory (such as /usr/local/lib/perl5/sun4-sunos/5.003) so that they +will still be accessible even after a later version is installed. +(Note: Perl 5.000 and 5.001 did not put their architecture-dependent +libraries in a version-specific directory. They are simply in +/usr/local/lib/perl5/$archname. If you will not be using 5.000 or +5.001, you may safely remove those files.) + +In general, the standard library files in /usr/local/lib/perl5 should +be usable by all versions of perl5. However, the diagnostics.pm module +uses the /usr/local/lib/perl5/pod/perldiag.pod documentation file, so +the C<use diagnostics;> pragma and the splain script will only identify +and explain any warnings or errors that the most recently-installed +version of perl can generate. Most extensions will probably not need to be recompiled to use with a newer version of perl. If you do run into problems, and you want to continue to use the old version of perl along with your extension, simply move those extension files to the appropriate version directory, such as -F</usr/local/lib/perl/archname/5.002>. Then perl5.002 will find your -files in the 5.002 directory, and newer versions of perl will find your +/usr/local/lib/perl/archname/5.003. Then Perl 5.003 will find your +files in the 5.003 directory, and newer versions of perl will find your newer extension in the site_perl directory. -Some users may prefer to keep all versions of perl in completely +Many users prefer to keep all versions of perl in completely separate directories. One convenient way to do this is by using a separate prefix for each version, such as - sh Configure -Dprefix=/opt/perl5.002 + sh Configure -Dprefix=/opt/perl5.004 -and adding /opt/perl5.002/bin to the shell PATH variable. Such users +and adding /opt/perl5.004/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. -B<NOTE>: Starting with 5.002_01, all functions in the perl C source -code are protected by default by the prefix Perl_ (or perl_) so that -you may link with third-party libraries without fear of namespace -collisons. This breaks compatability with the initially released -version of 5.002, so once you install 5.002_01 (or higher) you will -need to re-build and install all of your dynamically loadable -extensions. (The standard extensions supplied with Perl are handled -automatically). You can turn off this namespace protection by adding --DNO_EMBED to your ccflags variable in config.sh. This is a one-time -change. In the future, we certainly hope that most extensions won't -need to be recompiled for use with a newer version of perl. +If you are installing a development subversion, you probably ought to +seriously consider using a separate directory, since development +subversions may not have all the compatibility wrinkles ironed out +yet. =head1 Coexistence with perl4 You can safely install perl5 even if you want to keep perl4 around. -By default, the perl5 libraries go into F</usr/local/lib/perl5/>, so -they don't override the perl4 libraries in F</usr/local/lib/perl/>. +By default, the perl5 libraries go into /usr/local/lib/perl5/, so +they don't override the perl4 libraries in /usr/local/lib/perl/. In your /usr/local/bin directory, you should have a binary named -F<perl4.036>. That will not be touched by the perl5 installation +perl4.036. That will not be touched by the perl5 installation process. Most perl4 scripts should run just fine under perl5. However, if you have any scripts that require perl4, you can replace -the C<#!> line at the top of them by C<#!/usr/local/bin/perl4.036> +the #! line at the top of them by #!/usr/local/bin/perl4.036 (or whatever the appropriate pathname is). See pod/perltrap.pod for possible problems running perl4 scripts under perl5. +=head1 cd /usr/include; h2ph *.h sys/*.h + +Some perl scripts need to be able to obtain information from +the system header files. This command will convert the most commonly used +header files in /usr/include into files that can be easily interpreted +by perl. These files will be placed in the architectural library directory +you specified to Configure; by default this is +/usr/local/lib/perl5/ARCH/VERSION, where ARCH is your architecture +(such as sun4-solaris) and VERSION is the version of perl you are +building (for example, 5.004). + +Note: Due to differences in the C and perl languages, the +conversion of the header files is not perfect. You will probably have +to hand-edit some of the converted files to get them to parse +correctly. For example, h2ph breaks spectacularly on type casting and +certain structures. + +=head1 installhtml --help + +Some sites may wish to make perl documentation available in HTML +format. The installhtml utility can be used to convert pod +documentation into linked HTML files and install them. + +The following command-line is an example of one used to convert +perl documentation: + + ./installhtml \ + --podroot=. \ + --podpath=lib:ext:pod:vms \ + --recurse \ + --htmldir=/perl/nmanual \ + --htmlroot=/perl/nmanual \ + --splithead=pod/perlipc \ + --splititem=pod/perlfunc \ + --libpods=perlfunc:perlguts:perlvar:perlrun:perlop \ + --verbose + +See the documentation in installhtml for more details. It can take +many minutes to execute a large installation and you should expect to +see warnings like "no title", "unexpected directive" and "cannot +resolve" as the files are processed. We are aware of these problems +(and would welcome patches for them). + +You may find it helpful to run installhtml twice. That should reduce +the number of "cannot resolve" warnings. + +=head1 cd pod && make tex && (process the latex files) + +Some sites may also wish to make the documentation in the pod/ directory +available in TeX format. Type + + (cd pod && make tex && <process the latex files>) + +=head1 Reporting Problems + +If you have difficulty building perl, and none of the advice in this +file helps, and careful reading of the error message and the relevant +manual pages on your system doesn't help either, then you should send a +message to either the comp.lang.perl.misc newsgroup or to +perlbug@perl.com with an accurate description of your problem. + +Please include the output of the ./myconfig shell script +that comes with the distribution. Alternatively, you can use the +perlbug program that comes with the perl distribution, +but you need to have perl compiled and installed before you can use it. + +You might also find helpful information in the Porting +directory of the perl distribution. + =head1 DOCUMENTATION Read the manual entries before running perl. The main documentation is in the pod/ subdirectory and should have been installed during the build process. Type B<man perl> to get started. Alternatively, you -can type B<perldoc perl> to use the supplied B<perldoc> script. This +can type B<perldoc perl> to use the supplied perldoc script. This is sometimes useful for finding things in the library modules. +Under UNIX, you can produce a documentation book in postscript form, +along with its table of contents, by going to the pod/ subdirectory +and running (either): + + ./roffitall -groff # If you have GNU groff installed + ./roffitall -psroff # If you have psroff + +This will leave you with two postscript files ready to be printed. +(You may need to fix the roffitall command to use your local troff +set-up.) + +Note that you must have performed the installation already before +running the above, since the script collects the installed files to +generate the documentation. + =head1 AUTHOR -Andy Dougherty <doughera@lafcol.lafayette.edu>, borrowing I<very> heavily -from the original README by Larry Wall. +Original author: Andy Dougherty doughera@lafcol.lafayette.edu , +borrowing very heavily from the original README by Larry Wall, +with lots of helpful feedback and additions from the +perl5-porters@perl.org folks. + +If you have problems or questions, please see L<"Reporting Problems"> +above. =head1 LAST MODIFIED -19 March 1996 +$Id: INSTALL,v 1.28 1997/10/10 16:50:59 doughera Released $ diff --git a/gnu/usr.bin/perl/INTERN.h b/gnu/usr.bin/perl/INTERN.h index d89d2e68a44..ba71c2f7adf 100644 --- a/gnu/usr.bin/perl/INTERN.h +++ b/gnu/usr.bin/perl/INTERN.h @@ -1,6 +1,6 @@ /* INTERN.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -15,12 +15,18 @@ */ #undef EXT #undef dEXT +#undef EXTCONST +#undef dEXTCONST #if defined(VMS) && !defined(__GNUC__) # define EXT globaldef {"$GLOBAL_RW_VARS"} noshare # define dEXT globaldef {"$GLOBAL_RW_VARS"} noshare +# define EXTCONST globaldef {"$GLOBAL_RO_VARS"} readonly +# define dEXTCONST globaldef {"$GLOBAL_RO_VARS"} readonly #else # define EXT # define dEXT +# define EXTCONST const +# define dEXTCONST const #endif #undef INIT diff --git a/gnu/usr.bin/perl/MANIFEST b/gnu/usr.bin/perl/MANIFEST index e493f4e7c76..26a54094aff 100644 --- a/gnu/usr.bin/perl/MANIFEST +++ b/gnu/usr.bin/perl/MANIFEST @@ -1,26 +1,46 @@ Artistic The "Artistic License" -Changes Differences from previous versions. -Changes.Conf Recent changes in the Configure & build process +Changes Differences from previous version +Changes5.000 Differences between 4.x and 5.000 +Changes5.001 Differences between 5.000 and 5.001 +Changes5.002 Differences between 5.001 and 5.002 +Changes5.003 Differences between 5.002 and 5.003 configure Crude emulation of GNU configure +configure.gnu Copy of configure (for case-insensitive systems) Configure Portability tool Copying The GNU General Public License EXTERN.h Included before foreign .h files -INSTALL Detailed installation instructions. +INSTALL Detailed installation instructions INTERN.h Included before domestic .h files MANIFEST This list of files Makefile.SH A script that generates Makefile +Porting/Glossary Glossary of config.sh variables +Porting/makerel Release making utility +Porting/patchls Flexible patch file listing utility +Porting/pumpkin.pod Guidelines and hints for Perl maintainers README The Instructions -README.vms Notes about VMS +README.amiga Notes about AmigaOS port +README.cygwin32 Notes about Cygwin32 port +README.os2 Notes about OS/2 port +README.plan9 Notes about Plan9 port +README.qnx Notes about QNX port +README.vms Notes about VMS port +README.win32 Notes about Win32 port Todo The Wishlist XSUB.h Include file for extension subroutines av.c Array value code av.h Array value header cflags.SH A script that emits C compilation flags per file +compat3.sym List of symbols for binary-compatibility with 5.003 config_H Sample config.h config_h.SH Produces config.h configpm Produces lib/Config.pm cop.h Control operator header cv.h Code value header +cygwin32/cw32imp.h Cygwin32 port +cygwin32/gcc2 Cygwin32 port +cygwin32/ld2 Cygwin32 port +cygwin32/perlgcc Cygwin32 port +cygwin32/perlld Cygwin32 port deb.c Debugging routines doio.c I/O operations doop.c Support code for various operations @@ -28,6 +48,24 @@ dosish.h Some defines for MS/DOSish machines dump.c Debugging output eg/ADB An adb wrapper to put in your crash dir eg/README Intro to example perl scripts +eg/cgi/RunMeFirst Setup script for CGI examples +eg/cgi/clickable_image.cgi CGI example +eg/cgi/cookie.cgi CGI example +eg/cgi/crash.cgi CGI example +eg/cgi/customize.cgi CGI example +eg/cgi/diff_upload.cgi CGI example +eg/cgi/file_upload.cgi CGI example +eg/cgi/frameset.cgi CGI example +eg/cgi/index.html Index page for CGI examples +eg/cgi/internal_links.cgi CGI example +eg/cgi/javascript.cgi CGI example +eg/cgi/monty.cgi CGI example +eg/cgi/multiple_forms.cgi CGI example +eg/cgi/nph-clock.cgi CGI example +eg/cgi/popup.cgi CGI example +eg/cgi/save_state.cgi CGI example +eg/cgi/tryit.cgi CGI example +eg/cgi/wilogo.gif.uu Small image for CGI examples eg/changes A program to list recently changed files eg/client A sample client eg/down A program to do things to subdirectories @@ -82,27 +120,36 @@ ext/DynaLoader/DynaLoader.pm Dynamic Loader perl module ext/DynaLoader/Makefile.PL Dynamic Loader makefile writer ext/DynaLoader/README Dynamic Loader notes and intro ext/DynaLoader/dl_aix.xs AIX implementation +ext/DynaLoader/dl_cygwin32.xs Cygwin32 implementation ext/DynaLoader/dl_dld.xs GNU dld style implementation ext/DynaLoader/dl_dlopen.xs BSD/SunOS4&5 dlopen() style implementation ext/DynaLoader/dl_hpux.xs HP-UX implementation ext/DynaLoader/dl_next.xs Next implementation ext/DynaLoader/dl_none.xs Stub implementation -ext/DynaLoader/dl_os2.xs OS/2 implementation ext/DynaLoader/dl_vms.xs VMS implementation ext/DynaLoader/dlutils.c Dynamic loader utilities for dl_*.xs files ext/Fcntl/Fcntl.pm Fcntl extension Perl module ext/Fcntl/Fcntl.xs Fcntl extension external subroutines ext/Fcntl/Makefile.PL Fcntl extension makefile writer -ext/FileHandle/FileHandle.pm FileHandle extension Perl module -ext/FileHandle/FileHandle.xs FileHandle extension external subroutines -ext/FileHandle/Makefile.PL FileHandle extension makefile writer ext/GDBM_File/GDBM_File.pm GDBM extension Perl module ext/GDBM_File/GDBM_File.xs GDBM extension external subroutines ext/GDBM_File/Makefile.PL GDBM extension makefile writer ext/GDBM_File/typemap GDBM extension interface types +ext/IO/IO.pm Top-level interface to IO::* classes +ext/IO/IO.xs IO extension external subroutines +ext/IO/Makefile.PL IO extension makefile writer +ext/IO/README IO extension maintenance notice +ext/IO/lib/IO/File.pm IO::File extension Perl module +ext/IO/lib/IO/Handle.pm IO::Handle extension Perl module +ext/IO/lib/IO/Pipe.pm IO::Pipe extension Perl module +ext/IO/lib/IO/Seekable.pm IO::Seekable extension Perl module +ext/IO/lib/IO/Select.pm IO::Select extension Perl module +ext/IO/lib/IO/Socket.pm IO::Socket extension Perl module ext/NDBM_File/Makefile.PL NDBM extension makefile writer ext/NDBM_File/NDBM_File.pm NDBM extension Perl module ext/NDBM_File/NDBM_File.xs NDBM extension external subroutines +ext/NDBM_File/hints/dec_osf.pl Hint for NDBM_File for named architecture +ext/NDBM_File/hints/dynixptx.pl Hint for NDBM_File for named architecture ext/NDBM_File/hints/solaris.pl Hint for NDBM_File for named architecture ext/NDBM_File/hints/svr4.pl Hint for NDBM_File for named architecture ext/NDBM_File/typemap NDBM extension interface types @@ -110,14 +157,22 @@ ext/ODBM_File/Makefile.PL ODBM extension makefile writer ext/ODBM_File/ODBM_File.pm ODBM extension Perl module ext/ODBM_File/ODBM_File.xs ODBM extension external subroutines ext/ODBM_File/hints/dec_osf.pl Hint for ODBM_File for named architecture +ext/ODBM_File/hints/hpux.pl Hint for ODBM_File for named architecture ext/ODBM_File/hints/sco.pl Hint for ODBM_File for named architecture ext/ODBM_File/hints/solaris.pl Hint for ODBM_File for named architecture ext/ODBM_File/hints/svr4.pl Hint for ODBM_File for named architecture +ext/ODBM_File/hints/ultrix.pl Hint for ODBM_File for named architecture ext/ODBM_File/typemap ODBM extension interface types +ext/Opcode/Makefile.PL Opcode extension makefile writer +ext/Opcode/Opcode.pm Opcode extension Perl module +ext/Opcode/Opcode.xs Opcode extension external subroutines +ext/Opcode/Safe.pm Safe extension Perl module +ext/Opcode/ops.pm "Pragma" form of Opcode extension Perl module ext/POSIX/Makefile.PL POSIX extension makefile writer ext/POSIX/POSIX.pm POSIX extension Perl module ext/POSIX/POSIX.pod POSIX extension documentation ext/POSIX/POSIX.xs POSIX extension external subroutines +ext/POSIX/hints/next_3.pl Hint for POSIX for named architecture ext/POSIX/typemap POSIX extension interface types ext/SDBM_File/Makefile.PL SDBM extension makefile writer ext/SDBM_File/SDBM_File.pm SDBM extension Perl module @@ -142,20 +197,15 @@ ext/SDBM_File/sdbm/makefile.sdbm SDBM kit ext/SDBM_File/sdbm/pair.c SDBM kit ext/SDBM_File/sdbm/pair.h SDBM kit ext/SDBM_File/sdbm/readme.ms SDBM kit -ext/SDBM_File/sdbm/readme.ps SDBM kit ext/SDBM_File/sdbm/sdbm.3 SDBM kit ext/SDBM_File/sdbm/sdbm.c SDBM kit ext/SDBM_File/sdbm/sdbm.h SDBM kit ext/SDBM_File/sdbm/tune.h SDBM kit ext/SDBM_File/sdbm/util.c SDBM kit ext/SDBM_File/typemap SDBM extension interface types -ext/Safe/Makefile.PL Safe extension makefile writer -ext/Safe/Safe.pm Safe extension Perl module -ext/Safe/Safe.xs Safe extension external subroutines ext/Socket/Makefile.PL Socket extension makefile writer ext/Socket/Socket.pm Socket extension Perl module ext/Socket/Socket.xs Socket extension external subroutines -ext/util/extliblist Used by extension Makefile.PL to make lib lists ext/util/make_ext Used by Makefile to execute extension Makefiles ext/util/mkbootstrap Turns ext/*/*_BS into bootstrap info form.h Public declarations for the above @@ -178,17 +228,20 @@ h2pl/tcbreak2 cbreak test routine using .pl handy.h Handy definitions hints/3b1.sh Hints for named architecture hints/3b1cc Hints for named architecture -hints/README.hints Notes about hints. +hints/README.hints Notes about hints hints/aix.sh Hints for named architecture hints/altos486.sh Hints for named architecture +hints/amigaos.sh Hints for named architecture hints/apollo.sh Hints for named architecture -hints/aux.sh Hints for named architecture +hints/aux_3.sh Hints for named architecture +hints/broken-db.msg Warning message for systems with broken DB library hints/bsdos.sh Hints for named architecture hints/convexos.sh Hints for named architecture hints/cxux.sh Hints for named architecture +hints/cygwin32.sh Hints for named architecture +hints/dcosx.sh Hints for named architecture hints/dec_osf.sh Hints for named architecture hints/dgux.sh Hints for named architecture -hints/dnix.sh Hints for named architecture hints/dynix.sh Hints for named architecture hints/dynixptx.sh Hints for named architecture hints/epix.sh Hints for named architecture @@ -202,10 +255,12 @@ hints/i386.sh Hints for named architecture hints/irix_4.sh Hints for named architecture hints/irix_5.sh Hints for named architecture hints/irix_6.sh Hints for named architecture -hints/irix_6_2.sh Hints for named architecture +hints/irix_6_0.sh Hints for named architecture +hints/irix_6_1.sh Hints for named architecture hints/isc.sh Hints for named architecture hints/isc_2.sh Hints for named architecture hints/linux.sh Hints for named architecture +hints/lynxos.sh Hints for named architecture hints/machten.sh Hints for named architecture hints/machten_2.sh Hints for named architecture hints/mips.sh Hints for named architecture @@ -213,11 +268,15 @@ hints/mpc.sh Hints for named architecture hints/mpeix.sh Hints for named architecture hints/ncr_tower.sh Hints for named architecture hints/netbsd.sh Hints for named architecture +hints/newsos4.sh Hints for named architecture hints/next_3.sh Hints for named architecture hints/next_3_0.sh Hints for named architecture +hints/next_4.sh Hints for named architecture hints/opus.sh Hints for named architecture hints/os2.sh Hints for named architecture +hints/os390.sh Hints for named architecture hints/powerux.sh Hints for named architecture +hints/qnx.sh Hints for named architecture hints/sco.sh Hints for named architecture hints/sco_2_3_0.sh Hints for named architecture hints/sco_2_3_1.sh Hints for named architecture @@ -232,61 +291,89 @@ hints/svr4.sh Hints for named architecture hints/ti1500.sh Hints for named architecture hints/titanos.sh Hints for named architecture hints/ultrix_4.sh Hints for named architecture +hints/umips.sh Hints for named architecture hints/unicos.sh Hints for named architecture +hints/unicosmk.sh Hints for named architecture hints/unisysdynix.sh Hints for named architecture hints/utekv.sh Hints for named architecture hints/uts.sh Hints for named architecture hv.c Hash value code hv.h Hash value header -installman Perl script to install man pages for pods. +installhtml Perl script to install html files for pods +installman Perl script to install man pages for pods installperl Perl script to do "make install" dirty work interp.sym Interpreter specific symbols to hide in a struct keywords.h The keyword numbers keywords.pl Program to write keywords.h lib/AnyDBM_File.pm Perl module to emulate dbmopen lib/AutoLoader.pm Autoloader base class -lib/AutoSplit.pm A module to split up autoload functions -lib/Benchmark.pm A module to time pieces of code and such +lib/AutoSplit.pm Split up autoload functions +lib/Benchmark.pm Measure execution time +lib/Bundle/CPAN.pm The CPAN bundle +lib/CGI.pm Web server interface ("Common Gateway Interface") +lib/CGI/Apache.pm Support for Apache's Perl module +lib/CGI/Carp.pm Log server errors with helpful context +lib/CGI/Fast.pm Support for FastCGI (persistent server process) +lib/CGI/Push.pm Support for server push +lib/CGI/Switch.pm Simple interface for multiple server types +lib/CPAN.pm Interface to Comprehensive Perl Archive Network +lib/CPAN/FirstTime.pm Utility for creating CPAN config files +lib/CPAN/Nox.pm Runs CPAN while avoiding compiled extensions lib/Carp.pm Error message base class +lib/Class/Struct.pm Declare struct-like datatypes as Perl classes lib/Cwd.pm Various cwd routines (getcwd, fastcwd, chdir) lib/Devel/SelfStubber.pm Generate stubs for SelfLoader.pm lib/DirHandle.pm like FileHandle only for directories lib/English.pm Readable aliases for short variables lib/Env.pm Map environment into ordinary variables lib/Exporter.pm Exporter base class +lib/ExtUtils/Command.pm Utilities for Make on non-UNIX platforms +lib/ExtUtils/Embed.pm Utilities for embedding Perl in C programs lib/ExtUtils/Install.pm Handles 'make install' on extensions lib/ExtUtils/Liblist.pm Locates libraries lib/ExtUtils/MM_OS2.pm MakeMaker methods for OS/2 lib/ExtUtils/MM_Unix.pm MakeMaker base class for Unix -lib/ExtUtils/MM_VMS.pm MakeMaker methods for VMS. +lib/ExtUtils/MM_VMS.pm MakeMaker methods for VMS +lib/ExtUtils/MM_Win32.pm MakeMaker methods for Win32 lib/ExtUtils/MakeMaker.pm Write Makefiles for extensions lib/ExtUtils/Manifest.pm Utilities to write MANIFEST files lib/ExtUtils/Mkbootstrap.pm Writes a bootstrap file (see MakeMaker) lib/ExtUtils/Mksymlists.pm Writes a linker options file for extensions -lib/ExtUtils/testlib.pm Fixes up @INC to use just-built extension +lib/ExtUtils/testlib.pm Fixes up @INC to use just-built extension lib/ExtUtils/typemap Extension interface types lib/ExtUtils/xsubpp External subroutine preprocessor -lib/File/Basename.pm A module to emulate the basename program +lib/File/Basename.pm Emulate the basename program lib/File/CheckTree.pm Perl module supporting wholesale file mode validation +lib/File/Compare.pm Emulation of cmp command lib/File/Copy.pm Emulation of cp command +lib/File/DosGlob.pm Win32 DOS-globbing module lib/File/Find.pm Routines to do a find -lib/File/Path.pm A module to do things like `mkdir -p' and `rm -r' +lib/File/Path.pm Do things like `mkdir -p' and `rm -r' +lib/File/stat.pm By-name interface to Perl's builtin stat lib/FileCache.pm Keep more files open than the system permits -lib/Getopt/Long.pm A module to fetch command options (GetOptions) -lib/Getopt/Std.pm A module to fetch command options (getopt, getopts) +lib/FileHandle.pm Backward-compatible front end to IO extension +lib/FindBin.pm Find name of currently executing program +lib/Getopt/Long.pm Fetch command options (GetOptions) +lib/Getopt/Std.pm Fetch command options (getopt, getopts) lib/I18N/Collate.pm Routines to do strxfrm-based collation lib/IPC/Open2.pm Open a two-ended pipe lib/IPC/Open3.pm Open a three-ended pipe! lib/Math/BigFloat.pm An arbitrary precision floating-point arithmetic package lib/Math/BigInt.pm An arbitrary precision integer arithmetic package lib/Math/Complex.pm A Complex package -lib/Net/Ping.pm Ping methods +lib/Math/Trig.pm A simple interface to complex trigonometry +lib/Net/Ping.pm Hello, anybody home? +lib/Net/hostent.pm By-name interface to Perl's builtin gethost* +lib/Net/netent.pm By-name interface to Perl's builtin getnet* +lib/Net/protoent.pm By-name interface to Perl's builtin getproto* +lib/Net/servent.pm By-name interface to Perl's builtin getserv* lib/Pod/Functions.pm used by pod/splitpod +lib/Pod/Html.pm Convert POD data to HTML lib/Pod/Text.pm Convert POD data to formatted ASCII text -lib/Search/Dict.pm A module to do binary search on dictionaries -lib/SelectSaver.pm A module to enforce proper select scoping -lib/SelfLoader.pm A module to load functions only on demand. -lib/Shell.pm A module to make AUTOLOADed system() calls +lib/Search/Dict.pm Perform binary search on dictionaries +lib/SelectSaver.pm Enforce proper select scoping +lib/SelfLoader.pm Load functions only on demand +lib/Shell.pm Make AUTOLOADed system() calls lib/Symbol.pm Symbol table manipulation routines lib/Sys/Hostname.pm Hostname methods lib/Sys/Syslog.pm Perl module supporting syslogging @@ -300,18 +387,28 @@ lib/Text/Soundex.pm Perl module to implement Soundex lib/Text/Tabs.pm Do expand and unexpand lib/Text/Wrap.pm Paragraph formatter lib/Tie/Hash.pm Base class for tied hashes +lib/Tie/RefHash.pm Base class for tied hashes with references as keys lib/Tie/Scalar.pm Base class for tied scalars lib/Tie/SubstrHash.pm Compact hash for known key, value and table size lib/Time/Local.pm Reverse translation of localtime, gmtime +lib/Time/gmtime.pm By-name interface to Perl's builtin gmtime +lib/Time/localtime.pm By-name interface to Perl's builtin localtime +lib/Time/tm.pm Internal object for Time::{gm,local}time +lib/UNIVERSAL.pm Base class for ALL classes +lib/User/grent.pm By-name interface to Perl's builtin getgr* +lib/User/pwent.pm By-name interface to Perl's builtin getpw* lib/abbrev.pl An abbreviation table builder lib/assert.pl assertion and panic with stack trace +lib/autouse.pm Load and call a function only when it's used +lib/base.pm Establish IS-A relationship at compile time lib/bigfloat.pl An arbitrary precision floating point package lib/bigint.pl An arbitrary precision integer arithmetic package lib/bigrat.pl An arbitrary precision rational arithmetic package +lib/blib.pm For "use blib" lib/cacheout.pl Manages output filehandles when you need too many -lib/chat2.inter A chat2 with interaction -lib/chat2.pl Randal's famous expect-ish routines +lib/chat2.pl Obsolete ipc library (use Comm.pm etc instead) lib/complete.pl A command completion subroutine +lib/constant.pm For "use constant" lib/ctime.pl A ctime workalike lib/diagnostics.pm Print verbose diagnostics lib/dotsh.pl Code to "dot" in a shell script @@ -321,7 +418,7 @@ lib/fastcwd.pl a faster but more dangerous getcwd lib/find.pl A find emulator--used by find2perl lib/finddepth.pl A depth-first find emulator--used by find2perl lib/flush.pl Routines to do single flush -lib/ftp.pl FTP code +lib/ftp.pl FTP code (obsolete, use Net::FTP instead) lib/getcwd.pl A getcwd() emulator lib/getopt.pl Perl library supporting option parsing lib/getopts.pl Perl library supporting option parsing @@ -330,16 +427,16 @@ lib/importenv.pl Perl routine to get environment into variables lib/integer.pm For "use integer" lib/less.pm For "use less" lib/lib.pm For "use lib" +lib/locale.pm For "use locale" lib/look.pl A "look" equivalent lib/newgetopt.pl A perl library supporting long option parsing -lib/open2.pl Open a two-ended pipe -lib/open3.pl Open a three-ended pipe -lib/overload.pm Module for overloading perl operators. +lib/open2.pl Open a two-ended pipe (uses IPC::Open2) +lib/open3.pl Open a three-ended pipe (uses IPC::Open3) +lib/overload.pm Module for overloading perl operators lib/perl5db.pl Perl debugging routines lib/pwd.pl Routines to keep track of PWD environment variable lib/shellwords.pl Perl library to split into words with shell quoting lib/sigtrap.pm For trapping an abort and giving traceback -lib/splain Standalone program to print verbose diagnostics. lib/stat.pl Perl library supporting stat function lib/strict.pm For "use strict" lib/subs.pm Declare overriding subs @@ -359,50 +456,117 @@ minimod.pl Writes lib/ExtUtils/Miniperl.pm miniperlmain.c Basic perl w/o dynamic loading or extensions mv-if-diff Script to mv a file if it changed myconfig Prints summary of the current configuration +nostdio.h Cause compile error on stdio calls op.c Opcode syntax tree code op.h Opcode syntax tree header opcode.h Automatically generated opcode header opcode.pl Opcode header generatore -os2/diff.configure Patches to Configure -os2/diff.db_file patch to DB_File +os2/Changes Changelog for OS/2 port os2/Makefile.SHs Shared library generation for OS/2 -os2/POSIX.mkfifo POSIX.xs patch. -os2/README OS/2 port info. -os2/README.old previous OS/2 port info, partially relevant. -os2/notes Notes for perl maintainer +os2/OS2/ExtAttr/Changes EA access module +os2/OS2/ExtAttr/ExtAttr.pm EA access module +os2/OS2/ExtAttr/ExtAttr.xs EA access module +os2/OS2/ExtAttr/MANIFEST EA access module +os2/OS2/ExtAttr/Makefile.PL EA access module +os2/OS2/ExtAttr/myea.h EA access module +os2/OS2/ExtAttr/t/os2_ea.t EA access module +os2/OS2/ExtAttr/typemap EA access module +os2/OS2/PrfDB/Changes System database access module +os2/OS2/PrfDB/MANIFEST System database access module +os2/OS2/PrfDB/Makefile.PL System database access module +os2/OS2/PrfDB/PrfDB.pm System database access module +os2/OS2/PrfDB/PrfDB.xs System database access module +os2/OS2/PrfDB/t/os2_prfdb.t System database access module +os2/OS2/PrfDB/typemap System database access module +os2/OS2/Process/MANIFEST system() constants in a module +os2/OS2/Process/Makefile.PL system() constants in a module +os2/OS2/Process/Process.pm system() constants in a module +os2/OS2/Process/Process.xs system() constants in a module +os2/OS2/REXX/Changes DLL access module +os2/OS2/REXX/MANIFEST DLL access module +os2/OS2/REXX/Makefile.PL DLL access module +os2/OS2/REXX/REXX.pm DLL access module +os2/OS2/REXX/REXX.xs DLL access module +os2/OS2/REXX/t/rx_cmprt.t DLL access module +os2/OS2/REXX/t/rx_dllld.t DLL access module +os2/OS2/REXX/t/rx_objcall.t DLL access module +os2/OS2/REXX/t/rx_sql.test DLL access module +os2/OS2/REXX/t/rx_tiesql.test DLL access module +os2/OS2/REXX/t/rx_tievar.t DLL access module +os2/OS2/REXX/t/rx_tieydb.t DLL access module +os2/OS2/REXX/t/rx_varset.t DLL access module +os2/OS2/REXX/t/rx_vrexx.t DLL access module +os2/POSIX.mkfifo POSIX.xs patch +os2/diff.configure Patches to Configure +os2/dl_os2.c Addon for dl_open +os2/dlfcn.h Addon for dl_open os2/os2.c Additional code for OS/2 os2/os2ish.h Header for OS/2 os2/perl2cmd.pl Corrects installed binaries under OS/2 patchlevel.h The current patch level of perl perl.c main() perl.h Global declarations -perl_exp.SH Creates list of exported symbols for AIX. +perl_exp.SH Creates list of exported symbols for AIX +perlio.c C code for PerlIO abstraction +perlio.h Interface to PerlIO abstraction +perlio.sym Symbols for PerlIO abstraction +perlsdio.h Fake stdio using perlio +perlsfio.h Prototype sfio mapping for PerlIO perlsh A poor man's perl shell perly.c A byacc'ed perly.y perly.c.diff Fixup perly.c to allow recursion perly.fixer A program to remove yacc stack limitations perly.h The header file for perly.c perly.y Yacc grammar for perl +plan9/aperl Shell to make Perl error messages Acme-friendly +plan9/arpa/inet.h Plan9 port: replacement C header file +plan9/buildinfo Plan9 port: configuration information +plan9/config.plan9 Plan9 port: config.h template +plan9/exclude Plan9 port: tests to skip +plan9/fndvers Plan9 port: update Perl version in config.plan9 +plan9/genconfig.pl Plan9 port: generate config.sh +plan9/mkfile Plan9 port: Mk driver for build +plan9/myconfig.plan9 Plan9 port: script to print config summary +plan9/perlplan9.doc Plan9 port: Plan9-specific formatted documentation +plan9/perlplan9.pod Plan9 port: Plan9-specific pod documentation +plan9/plan9.c Plan9 port: Plan9-specific C routines +plan9/plan9ish.h Plan9 port: Plan9-specific C header file +plan9/setup.rc Plan9 port: script for easy build+install +plan9/versnum Plan9 port: script to print version number pod/Makefile Make pods into something else pod/buildtoc generate perltoc.pod +pod/checkpods.PL Tool to check for common errors in pods pod/perl.pod Top level perl man page +pod/perlapio.pod IO API info pod/perlbook.pod Book info pod/perlbot.pod Object-oriented Bag o' Tricks pod/perlcall.pod Callback info pod/perldata.pod Data structure info pod/perldebug.pod Debugger info +pod/perldelta.pod Changes since last version pod/perldiag.pod Diagnostic info pod/perldsc.pod Data Structures Cookbook pod/perlembed.pod Embedding info +pod/perlfaq.pod Frequently Asked Questions, Top Level +pod/perlfaq1.pod Frequently Asked Questions, Part 1 +pod/perlfaq2.pod Frequently Asked Questions, Part 2 +pod/perlfaq3.pod Frequently Asked Questions, Part 3 +pod/perlfaq4.pod Frequently Asked Questions, Part 4 +pod/perlfaq5.pod Frequently Asked Questions, Part 5 +pod/perlfaq6.pod Frequently Asked Questions, Part 6 +pod/perlfaq7.pod Frequently Asked Questions, Part 7 +pod/perlfaq8.pod Frequently Asked Questions, Part 8 +pod/perlfaq9.pod Frequently Asked Questions, Part 9 pod/perlform.pod Format info pod/perlfunc.pod Function info pod/perlguts.pod Internals info pod/perlipc.pod IPC info -pod/perllol.pod How to use lists of lists. -pod/perlmod.pod Module info +pod/perllocale.pod Locale support info +pod/perllol.pod How to use lists of lists +pod/perlmod.pod Module mechanism info +pod/perlmodlib.pod Module policy info pod/perlobj.pod Object info pod/perlop.pod Operator info -pod/perlovl.pod Overloading info pod/perlpod.pod Pod info pod/perlre.pod Regular expression info pod/perlref.pod References info @@ -413,6 +577,7 @@ pod/perlsub.pod Subroutine info pod/perlsyn.pod Syntax info pod/perltie.pod Tieing an object class into a simple variable pod/perltoc.pod Table of Contents info +pod/perltoot.pod Tom's object-oriented tutorial pod/perltrap.pod Trap info pod/perlvar.pod Variable info pod/perlxs.pod XS api info @@ -420,8 +585,9 @@ pod/perlxstut.pod XS tutorial pod/pod2html.PL Precursor for translator to turn pod into HTML pod/pod2latex.PL Precursor for translator to turn pod into LaTeX pod/pod2man.PL Precursor for translator to turn pod into manpage -pod/pod2text.PL Precursor for translator to turn pod into text +pod/pod2text.PL Precursor for translator to turn pod into text pod/roffitall troff the whole man page set +pod/rofftoc Generate a table of contents in troff format pod/splitman Splits perlfunc into multiple man pages pod/splitpod Splits perlfunc into multiple pod pages pp.c Push/Pop code @@ -430,6 +596,8 @@ pp_ctl.c Push/Pop code for control flow pp_hot.c Push/Pop code for heavily used opcodes pp_sys.c Push/Pop code for system interaction proto.h Prototypes +qnx/ar QNX implementation of "ar" utility +qnx/cpp QNX implementation of preprocessor filter regcomp.c Regular expression compiler regcomp.h Private declarations for above regexec.c Regular expression evaluator @@ -453,13 +621,17 @@ t/cmd/subval.t See if subroutine values work t/cmd/switch.t See if switch optimizations work t/cmd/while.t See if while loops work t/comp/cmdopt.t See if command optimization works +t/comp/colon.t See if colons are parsed correctly t/comp/cpp.aux main file for cpp.t t/comp/cpp.t See if C preprocessor works t/comp/decl.t See if declarations work t/comp/multiline.t See if multiline strings work t/comp/package.t See if packages work +t/comp/proto.t See if function prototypes work +t/comp/redef.t See if we get correct warnings on redefined subs t/comp/script.t See if script invokation works t/comp/term.t See if more terms work +t/comp/use.t See if pragmas work t/harness Finer diagnostics from test suite t/io/argv.t See if ARGV stuff works t/io/dup.t See if >& works right @@ -467,32 +639,73 @@ t/io/fs.t See if directory manipulations work t/io/inplace.t See if inplace editing works t/io/pipe.t See if secure pipes work t/io/print.t See if print commands work +t/io/read.t See if read works t/io/tell.t See if file seeking works +t/lib/abbrev.t See if Text::Abbrev works t/lib/anydbm.t See if AnyDBM_File works +t/lib/autoloader.t See if AutoLoader works +t/lib/basename.t See if File::Basename works t/lib/bigint.t See if bigint.pl works t/lib/bigintpm.t See if BigInt.pm works +t/lib/checktree.t See if File::CheckTree works +t/lib/complex.t See if Math::Complex works t/lib/db-btree.t See if DB_File works t/lib/db-hash.t See if DB_File works t/lib/db-recno.t See if DB_File works t/lib/dirhand.t See if DirHandle works +t/lib/dosglob.t See if File::DosGlob works t/lib/english.t See if English works +t/lib/env.t See if Env works +t/lib/filecache.t See if FileCache works +t/lib/filecopy.t See if File::Copy works +t/lib/filefind.t See if File::Find works t/lib/filehand.t See if FileHandle works +t/lib/filepath.t See if File::Path works +t/lib/findbin.t See if FindBin works t/lib/gdbm.t See if GDBM_File works +t/lib/getopt.t See if Getopt::Std and Getopt::Long works +t/lib/hostname.t See if Sys::Hostname works +t/lib/io_dup.t See if dup()-related methods from IO work +t/lib/io_pipe.t See if pipe()-related methods from IO work +t/lib/io_sel.t See if select()-related methods from IO work +t/lib/io_sock.t See if INET socket-related methods from IO work +t/lib/io_taint.t See if the untaint method from IO works +t/lib/io_tell.t See if seek()/tell()-related methods from IO work +t/lib/io_udp.t See if UDP socket-related methods from IO work +t/lib/io_xs.t See if XSUB methods from IO work t/lib/ndbm.t See if NDBM_File works t/lib/odbm.t See if ODBM_File works +t/lib/opcode.t See if Opcode works +t/lib/open2.t See if IPC::Open2 works +t/lib/open3.t See if IPC::Open3 works +t/lib/ops.t See if Opcode works +t/lib/parsewords.t See if Text::ParseWords works t/lib/posix.t See if POSIX works -t/lib/safe.t See if Safe works +t/lib/safe1.t See if Safe works +t/lib/safe2.t See if Safe works t/lib/sdbm.t See if SDBM_File works +t/lib/searchdict.t See if Search::Dict works +t/lib/selectsaver.t See if SelectSaver works t/lib/socket.t See if Socket works t/lib/soundex.t See if Soundex works +t/lib/symbol.t See if Symbol works +t/lib/texttabs.t See if Text::Tabs works +t/lib/textwrap.t See if Text::Wrap works +t/lib/timelocal.t See if Time::Local works +t/lib/trig.t See if Math::Trig works t/op/append.t See if . works +t/op/arith.t See if arithmetic works t/op/array.t See if array operations work +t/op/assignwarn.t See if OP= operators warn correctly for undef targets t/op/auto.t See if autoincrement et all work +t/op/bop.t See if bitops work t/op/chop.t See if chop works +t/op/closure.t See if closures work +t/op/cmp.t See if the various string and numeric compare work t/op/cond.t See if conditional expressions work t/op/delete.t See if delete works t/op/do.t See if subroutines work -t/op/each.t See if associative iterators work +t/op/each.t See if hash iterators work t/op/eval.t See if eval operator works t/op/exec.t See if exec and system work t/op/exp.t See if math functions work @@ -501,30 +714,34 @@ t/op/fork.t See if fork works t/op/glob.t See if <*> works t/op/goto.t See if goto works t/op/groups.t See if $( works +t/op/gv.t See if typeglobs work +t/op/inc.t See if inc/dec of integers near 32 bit limit work t/op/index.t See if index works t/op/int.t See if int works t/op/join.t See if join works t/op/list.t See if array lists work t/op/local.t See if local works t/op/magic.t See if magic variables work +t/op/method.t See if method calls work t/op/misc.t See if miscellaneous bugs have been fixed t/op/mkdir.t See if mkdir works t/op/my.t See if lexical scoping works t/op/oct.t See if oct and hex work t/op/ord.t See if ord works -t/op/overload.t See if operator overload works t/op/pack.t See if pack and unpack work t/op/pat.t See if esoteric patterns work t/op/push.t See if push and pop work t/op/quotemeta.t See if quotemeta works t/op/rand.t See if rand works t/op/range.t See if .. works -t/op/re_tests Input file for op.regexp +t/op/re_tests Regular expressions for regexp.t t/op/read.t See if read() works t/op/readdir.t See if readdir() works +t/op/recurse.t See if deep recursion works t/op/ref.t See if refs and objects work t/op/regexp.t See if regular expressions work t/op/repeat.t See if x operator works +t/op/runlevel.t See if die() works from perl_call_*() t/op/sleep.t See if sleep works t/op/sort.t See if sort works t/op/split.t See if split works @@ -533,34 +750,57 @@ t/op/stat.t See if stat works t/op/study.t See if study works t/op/subst.t See if substitution works t/op/substr.t See if substr works +t/op/sysio.t See if sysread and syswrite work +t/op/taint.t See if tainting works +t/op/tie.t See if tie/untie functions work t/op/time.t See if time functions work t/op/undef.t See if undef works +t/op/universal.t See if UNIVERSAL class works t/op/unshift.t See if unshift works t/op/vec.t See if vectors work t/op/write.t See if write works -t/re_tests Regular expressions for regexp.t +t/pragma/constant.t See if compile-time constants work +t/pragma/locale.t See if locale support (i18n and l10n) works +t/pragma/overload.t See if operator overloading works +t/pragma/strict-refs Tests of "use strict 'refs'" for strict.t +t/pragma/strict-subs Tests of "use strict 'subs'" for strict.t +t/pragma/strict-vars Tests of "use strict 'vars'" for strict.t +t/pragma/strict.t See if strictures work +t/pragma/subs.t See if subroutine pseudo-importation works +t/pragma/warn-1global Tests of global warnings for warning.t +t/pragma/warning.t See if warning controls work taint.c Tainting code toke.c The tokener +universal.c The default UNIVERSAL package methods unixish.h Defines that are assumed on Unix util.c Utility routines -util.h Public declarations for the above -utils/Makefile Extract the utility scripts. +util.h Dummy header +utils/Makefile Extract the utility scripts utils/c2ph.PL program to translate dbx stabs to perl utils/h2ph.PL A thing to turn C .h files into perl .ph files utils/h2xs.PL Program to make .xs files from C header files utils/perlbug.PL A simple tool to submit a bug report utils/perldoc.PL A simple tool to find & display perl's documentation utils/pl2pm.PL A pl to pm translator -vms/Makefile VMS port +utils/splain.PL Stand-alone version of diagnostics.pm vms/config.vms default config.h for VMS vms/descrip.mms MM[SK] description file for build +vms/ext/DCLsym/0README.txt ReadMe file for VMS::DCLsym +vms/ext/DCLsym/DCLsym.pm Perl access to CLI symbols +vms/ext/DCLsym/DCLsym.xs Perl access to CLI symbols +vms/ext/DCLsym/Makefile.PL MakeMaker driver for VMS::DCLsym +vms/ext/DCLsym/test.pl regression tests for VMS::DCLsym vms/ext/Filespec.pm VMS-Unix file syntax interconversion vms/ext/Stdio/0README.txt ReadMe file for VMS::Stdio vms/ext/Stdio/Makefile.PL MakeMaker driver for VMS::Stdio vms/ext/Stdio/Stdio.pm VMS options to stdio routines vms/ext/Stdio/Stdio.xs VMS options to stdio routines vms/ext/Stdio/test.pl regression tests for VMS::Stdio -vms/fndvers.com parse Perl version from patchlevel.h +vms/ext/XSSymSet.pm manage linker symbols when building extensions +vms/ext/filespec.t See if VMS::Filespec funtions work +vms/ext/vmsish.pm Control VMS-specific behavior of Perl core +vms/ext/vmsish.t Tests for vmsish.pm +vms/fndvers.com parse Perl version from patchlevel.h vms/gen_shrfls.pl generate options files and glue for shareable image vms/genconfig.pl retcon config.sh from config.h vms/genopt.com hack to write options files in case of broken makes @@ -577,22 +817,57 @@ vms/vms.c VMS-specific C code for Perl core vms/vms_yfix.pl convert Unix perly.[ch] to VMS perly_[ch].vms vms/vmsish.h VMS-specific C header for Perl core vms/writemain.pl Generate perlmain.c from miniperlmain.c+extensions +win32/Makefile Win32 makefile for NMAKE (Visual C++ build) +win32/TEST Win32 port +win32/autosplit.pl Win32 port +win32/bin/network.pl Win32 port +win32/bin/pl2bat.pl wrap perl scripts into batch files +win32/bin/runperl.pl run perl script via batch file namesake +win32/bin/search.pl Win32 port +win32/bin/webget.pl Win32 port +win32/bin/www.pl Win32 port +win32/config.bc Win32 base line config.sh (Borland C++ build) +win32/config.vc Win32 base line config.sh (Visual C++ build) +win32/config_H.bc Win32 config header (Borland C++ build) +win32/config_H.vc Win32 config header (Visual C++ build) +win32/config_h.PL Perl code to convert Win32 config.sh to config.h +win32/config_sh.PL Perl code to update Win32 config.sh from Makefile +win32/dl_win32.xs Win32 port +win32/genxsdef.pl Win32 port +win32/include/arpa/inet.h Win32 port +win32/include/dirent.h Win32 port +win32/include/netdb.h Win32 port +win32/include/sys/socket.h Win32 port +win32/makedef.pl Win32 port +win32/makefile.mk Win32 makefile for DMAKE (BC++, VC++ builds) +win32/makemain.pl Win32 port +win32/makeperldef.pl Win32 port +win32/perlglob.c Win32 port +win32/perllib.c Win32 port +win32/pod.mak Win32 port +win32/runperl.c Win32 port +win32/splittree.pl Win32 port +win32/win32.c Win32 port +win32/win32.h Win32 port +win32/win32io.c Win32 port +win32/win32io.h Win32 port +win32/win32iop.h Win32 port +win32/win32sck.c Win32 port writemain.SH Generate perlmain.c from miniperlmain.c+extensions x2p/EXTERN.h Same as above x2p/INTERN.h Same as above x2p/Makefile.SH Precursor to Makefile x2p/a2p.c Output of a2p.y run through byacc x2p/a2p.h Global declarations -x2p/a2p.man Manual page for awk to perl translator +x2p/a2p.pod Pod for awk to perl translator x2p/a2p.y A yacc grammer for awk x2p/a2py.c Awk compiler, sort of x2p/cflags.SH A script that emits C compilation flags per file x2p/find2perl.PL A find to perl translator -x2p/handy.h Handy definitions -x2p/hash.c Associative arrays again +x2p/hash.c Hashes again x2p/hash.h Public declarations for the above +x2p/proto.h Dummy header x2p/s2p.PL Sed to perl translator -x2p/s2p.man Manual page for sed to perl translator x2p/str.c String handling package x2p/str.h Public declarations for the above x2p/util.c Utility routines diff --git a/gnu/usr.bin/perl/Makefile.SH b/gnu/usr.bin/perl/Makefile.SH index 7eaa4e46dd5..f2a4a9fbc70 100644 --- a/gnu/usr.bin/perl/Makefile.SH +++ b/gnu/usr.bin/perl/Makefile.SH @@ -1,3 +1,4 @@ +#! /bin/sh case $CONFIG in '') if test -f config.sh; then TOP=.; @@ -22,24 +23,42 @@ case "$d_dosuid" in *) suidperl='';; esac -shrpenv="" -case "$d_shrplib" in -*define*) - patchlevel=`egrep '^#define[ ]+PATCHLEVEL' patchlevel.h \ - | awk '{print $3}'` - case "$patchlevel" in - *[0-9]) plibsuf=.$so.$patchlevel;; - *) plibsuf=.$so;; - esac - if test "x$plibext" != "x" ; then plibsuf=$plibext d_shrplib=custom ; fi - case "$shrpdir" in - /usr/lib) ;; - "") ;; - *) shrpenv="env LD_RUN_PATH=$shrpdir";; - esac - pldlflags="$cccdlflags";; -*) plibsuf=$lib_ext - pldlflags="";; +linklibperl='$(LIBPERL)' +shrpldflags='$(LDDLFLAGS)' +case "$useshrplib" in +true) + pldlflags="$cccdlflags" + # NeXT-4 specific stuff. Can't we do this in the hint file? + case "${osname}${osvers}" in + next4*) + ld=libtool + lddlflags="-dynamic -undefined warning -framework System \ + -compatibility_version 1 -current_version $patchlevel \ + -prebind -seg1addr 0x27000000 -install_name \$(shrpdir)/\$@" + ;; + sunos*|freebsd[23]*|netbsd*) + linklibperl="-lperl" + ;; + aix*) + shrpldflags="-H512 -T512 -bhalt:4 -bM:SRE -bE:perl.exp" + case "$osvers" in + 3*) + shrpldflags="$shrpldflags -e _nostart $ldflags $libs $cryptlib" + ;; + *) + shrpldflags="$shrpldflags -b noentry $ldflags $libs $cryptlib" + ;; + esac + aixinstdir=`pwd | sed 's/\/UU$//'` + linklibperl="-L $archlibexp/CORE -L $aixinstdir -lperl" + ;; + hpux10*) + linklibperl="-L `pwd | sed 's/\/UU$//'` -Wl,+b$archlibexp/CORE -lperl" + ;; + esac + ;; +*) pldlflags='' + ;; esac : Prepare dependency lists for Makefile. @@ -51,30 +70,20 @@ for f in $dynamic_ext; do done static_list=' ' -static_ai_list=' ' for f in $static_ext; do base=`echo "$f" | sed 's/.*\///'` static_list="$static_list lib/auto/$f/$base\$(LIB_EXT)" - if test -f ext/$f/AutoInit.c; then - static_ai_list="$static_ai_list ext/$f/AutoInit.c" - fi - if test -f ext/$f/AutoInit.pl; then - static_ai_list="$static_ai_list ext/$f/AutoInit.pl" - fi done echo "Extracting Makefile (with variable substitutions)" -$spitshell >Makefile <<'!NO!SUBS!' +$spitshell >Makefile <<!GROK!THIS! # Makefile.SH # This file is derived from Makefile.SH. Any changes made here will # be lost the next time you run Configure. -# Makefile is used to generate makefile. The only difference -# is that makefile has the dependencies filled in at the end. +# Makefile is used to generate $firstmakefile. The only difference +# is that $firstmakefile has the dependencies filled in at the end. # # -!NO!SUBS! - -$spitshell >>Makefile <<!GROK!THIS! # I now supply perly.c with the kits, so don't remake perly.c without byacc BYACC = $byacc CC = $cc @@ -97,6 +106,7 @@ ranlib = $ranlib # installman commandline. bin = $installbin scriptdir = $scriptdir +shrpdir = $archlibexp/CORE privlib = $installprivlib man1dir = $man1dir man1ext = $man1ext @@ -106,16 +116,17 @@ man3ext = $man3ext # The following are used to build and install shared libraries for # dynamic loading. LDDLFLAGS = $lddlflags +SHRPLDFLAGS = $shrpldflags CCDLFLAGS = $ccdlflags DLSUFFIX = .$dlext PLDLFLAGS = $pldlflags -PLIBSUF = $plibsuf +LIBPERL = $libperl +LLIBPERL= $linklibperl SHRPENV = $shrpenv dynamic_ext = $dynamic_list static_ext = $static_list ext = \$(dynamic_ext) \$(static_ext) -static_ext_autoinit = $static_ai_list DYNALOADER = lib/auto/DynaLoader/DynaLoader\$(LIB_EXT) libs = $libs $cryptlib @@ -124,8 +135,9 @@ public = perl $suidperl utilities translators shellflags = $shellflags -## To use an alternate make, set \$altmake in config.sh. -MAKE = ${altmake-make} +# This is set to MAKE=$make if your $make command doesn't +# do it for you. +$make_set_make # These variables will be used in a future version to make # the make file more portable to non-unix systems. @@ -142,12 +154,15 @@ ARCHOBJS = $archobjs .SUFFIXES: .c \$(OBJ_EXT) +# grrr +SHELL = $sh + !GROK!THIS! ## In the following dollars and backticks do not need the extra backslash. $spitshell >>Makefile <<'!NO!SUBS!' -CCCMD = `sh $(shellflags) cflags $(perllib) $@` +CCCMD = `sh $(shellflags) cflags $(LIBPERL) $@` private = preplibrary lib/ExtUtils/Miniperl.pm lib/Config.pm @@ -157,7 +172,7 @@ sh = Makefile.SH cflags.SH config_h.SH makeaperl.SH makedepend.SH \ makedir.SH perl_exp.SH writemain.SH shextract = Makefile cflags config.h makeaperl makedepend \ - makedir perl_exp writemain + makedir perl.exp writemain # Files to be built with variable substitution after miniperl is # available. Dependencies handled manually below (for now). @@ -171,41 +186,37 @@ addedbyconf = UU $(shextract) $(plextract) pstruct h1 = EXTERN.h INTERN.h XSUB.h av.h config.h cop.h cv.h dosish.h h2 = embed.h form.h gv.h handy.h hv.h keywords.h mg.h op.h h3 = opcode.h patchlevel.h perl.h perly.h pp.h proto.h regcomp.h -h4 = regexp.h scope.h sv.h unixish.h util.h +h4 = regexp.h scope.h sv.h unixish.h util.h perlio.h h = $(h1) $(h2) $(h3) $(h4) c1 = $(mallocsrc) av.c scope.c op.c doop.c doio.c dump.c hv.c mg.c c2 = perl.c perly.c pp.c pp_hot.c pp_ctl.c pp_sys.c regcomp.c regexec.c -c3 = gv.c sv.c taint.c toke.c util.c deb.c run.c globals.c +c3 = gv.c sv.c taint.c toke.c util.c deb.c run.c universal.c globals.c perlio.c c = $(c1) $(c2) $(c3) miniperlmain.c perlmain.c obj1 = $(mallocobj) gv$(OBJ_EXT) toke$(OBJ_EXT) perly$(OBJ_EXT) op$(OBJ_EXT) regcomp$(OBJ_EXT) dump$(OBJ_EXT) util$(OBJ_EXT) mg$(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) taint$(OBJ_EXT) deb$(OBJ_EXT) globals$(OBJ_EXT) - +obj3 = doop$(OBJ_EXT) doio$(OBJ_EXT) regexec$(OBJ_EXT) taint$(OBJ_EXT) deb$(OBJ_EXT) universal$(OBJ_EXT) globals$(OBJ_EXT) perlio$(OBJ_EXT) + obj = $(obj1) $(obj2) $(obj3) $(ARCHOBJS) # Once perl has been Configure'd and built ok you build different # perl variants (Debugging, Embedded, Multiplicity etc) by saying: -# make clean; make perllib=libperl<type>.a +# make clean; make LIBPERL=libperl<type>.a # where <type> is some combination of 'd' and(or) 'e' or 'm'. # See cflags to understand how this works. # -# Eventually some form of 'make-a-perl' script will automate this -# together with linking a perl executable with any desired -# static modules. -perllib = libperl$(PLIBSUF) +# This mechanism is getting clunky and might not even work any more. +# EMBEDDING is on by default, and MULTIPLICITY doesn't work. +# lintflags = -hbvxac -# grrr -SHELL = /bin/sh - .c$(OBJ_EXT): $(CCCMD) $(PLDLFLAGS) $*.c -all: makefile miniperl $(private) $(plextract) $(public) $(dynamic_ext) +all: $(FIRSTMAKEFILE) miniperl $(private) $(plextract) $(public) $(dynamic_ext) @echo " "; echo " Everything is up to date." translators: miniperl lib/Config.pm FORCE @@ -223,22 +234,10 @@ utilities: miniperl lib/Config.pm FORCE FORCE: @sh -c true -# The $& notation tells Sequent machines that it can do a parallel make, -# and is harmless otherwise. -# The miniperl -w -MExporter line is a basic cheap test to catch errors -# before make goes on to run preplibrary and then MakeMaker on extensions. -# This is very handy because later errors are often caused by miniperl -# build problems but that's not obvious to the novice. -# The Module used here must not depend on Config or any extensions. - -miniperl: $& miniperlmain$(OBJ_EXT) $(perllib) - $(CC) $(LARGE) $(CLDFLAGS) -o miniperl miniperlmain$(OBJ_EXT) $(perllib) $(libs) - @./miniperl -w -Ilib -MExporter -e 0 || $(MAKE) minitest - miniperlmain$(OBJ_EXT): miniperlmain.c $(CCCMD) $(PLDLFLAGS) $*.c -perlmain.c: miniperlmain.c config.sh makefile $(static_ext_autoinit) +perlmain.c: miniperlmain.c config.sh $(FIRSTMAKEFILE) sh writemain $(DYNALOADER) $(static_ext) > tmp sh mv-if-diff tmp perlmain.c @@ -251,54 +250,83 @@ perlmain$(OBJ_EXT): perlmain.c ext.libs: $(static_ext) -@test -f ext.libs || touch ext.libs -perl: $& perlmain$(OBJ_EXT) $(perllib) $(DYNALOADER) $(static_ext) ext.libs - $(SHRPENV) $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o perl perlmain$(OBJ_EXT) $(perllib) $(DYNALOADER) $(static_ext) `cat ext.libs` $(libs) - -pureperl: $& perlmain$(OBJ_EXT) $(perllib) $(DYNALOADER) $(static_ext) ext.libs - purify $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o pureperl perlmain$(OBJ_EXT) $(perllib) $(DYNALOADER) $(static_ext) `cat ext.libs` $(libs) - -quantperl: $& perlmain$(OBJ_EXT) $(perllib) $(DYNALOADER) $(static_ext) ext.libs - quantify $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o quantperl perlmain$(OBJ_EXT) $(perllib) $(DYNALOADER) $(static_ext) `cat ext.libs` $(libs) - -$(perllib): $& perl$(OBJ_EXT) $(obj) !NO!SUBS! -case "$d_shrplib" in -*define*) -$spitshell >>Makefile <<'!NO!SUBS!' - $(LD) $(LDDLFLAGS) -o $@ perl$(OBJ_EXT) $(obj) -!NO!SUBS! -;; -custom) -if test -r $osname/Makefile.SHs ; then - . $osname/Makefile.SHs - $spitshell >>Makefile <<!GROK!THIS! +# How to build libperl. This is still rather convoluted. +# Load up custom Makefile.SH fragment for shared loading and executables: +if test -r $osname/Makefile.SHs ; then + . $osname/Makefile.SHs + $spitshell >>Makefile <<!GROK!THIS! Makefile: $osname/Makefile.SHs - !GROK!THIS! else - echo "Could not find $osname/Makefile.SH! Skipping target \$(perllib) in Makefile!" -fi -;; -*) -$spitshell >>Makefile <<'!NO!SUBS!' - rm -f $(perllib) - $(AR) rcu $(perllib) perl$(OBJ_EXT) $(obj) - @$(ranlib) $(perllib) + $spitshell >>Makefile <<'!NO!SUBS!' +$(LIBPERL): $& perl$(OBJ_EXT) $(obj) !NO!SUBS! -;; -esac + case "$useshrplib" in + true) + $spitshell >>Makefile <<'!NO!SUBS!' + $(LD) $(SHRPLDFLAGS) -o $@ perl$(OBJ_EXT) $(obj) +!NO!SUBS! + case "$osname" in + aix) + $spitshell >>Makefile <<'!NO!SUBS!' + mv $@ libperl$(OBJ_EXT) + $(AR) qv $(LIBPERL) libperl$(OBJ_EXT) +!NO!SUBS! + ;; + esac + ;; + *) + $spitshell >>Makefile <<'!NO!SUBS!' + rm -f $(LIBPERL) + $(AR) rcu $(LIBPERL) perl$(OBJ_EXT) $(obj) + @$(ranlib) $(LIBPERL) +!NO!SUBS! + ;; + esac + $spitshell >>Makefile <<'!NO!SUBS!' -$spitshell >>Makefile <<'!NO!SUBS!' +# How to build executables. + +# The $& notation tells Sequent machines that it can do a parallel make, +# and is harmless otherwise. +# The miniperl -w -MExporter line is a basic cheap test to catch errors +# before make goes on to run preplibrary and then MakeMaker on extensions. +# This is very handy because later errors are often caused by miniperl +# build problems but that's not obvious to the novice. +# The Module used here must not depend on Config or any extensions. + +miniperl: $& miniperlmain$(OBJ_EXT) $(LIBPERL) + $(CC) $(LARGE) $(CLDFLAGS) -o miniperl miniperlmain$(OBJ_EXT) $(LLIBPERL) $(libs) + @./miniperl -w -Ilib -MExporter -e 0 || $(MAKE) minitest + +perl: $& perlmain$(OBJ_EXT) $(LIBPERL) $(DYNALOADER) $(static_ext) ext.libs + $(SHRPENV) $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o perl perlmain$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs) + +pureperl: $& perlmain$(OBJ_EXT) $(LIBPERL) $(DYNALOADER) $(static_ext) ext.libs + $(SHRPENV) purify $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o pureperl perlmain$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs) + +purecovperl: $& perlmain$(OBJ_EXT) $(LIBPERL) $(DYNALOADER) $(static_ext) ext.libs + $(SHRPENV) purecov $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o purecovperl perlmain$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs) + +quantperl: $& perlmain$(OBJ_EXT) $(LIBPERL) $(DYNALOADER) $(static_ext) ext.libs + $(SHRPENV) quantify $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o quantperl perlmain$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs) # This version, if specified in Configure, does ONLY those scripts which need # set-id emulation. Suidperl must be setuid root. It contains the "taint" # checks as well as the special code to validate that the script in question # has been invoked correctly. -suidperl: $& sperl$(OBJ_EXT) perlmain$(OBJ_EXT) $(perllib) $(DYNALOADER) $(static_ext) ext.libs - $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o suidperl perlmain$(OBJ_EXT) sperl$(OBJ_EXT) $(perllib) $(DYNALOADER) $(static_ext) `cat ext.libs` $(libs) +suidperl: $& sperl$(OBJ_EXT) perlmain$(OBJ_EXT) $(LIBPERL) $(DYNALOADER) $(static_ext) ext.libs + $(SHRPENV) $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o suidperl perlmain$(OBJ_EXT) sperl$(OBJ_EXT) $(DYNALOADER) $(static_ext) $(LLIBPERL) `cat ext.libs` $(libs) + +!NO!SUBS! + +fi + +$spitshell >>Makefile <<'!NO!SUBS!' sperl$(OBJ_EXT): perl.c perly.h patchlevel.h $(h) $(RMS) sperl.c @@ -316,7 +344,9 @@ preplibrary: miniperl lib/Config.pm $(plextract) autosplit_lib_modules(@ARGV)' lib/*.pm lib/*/*.pm # Take care to avoid modifying lib/Config.pm without reason -lib/Config.pm: config.sh miniperl +# (If trying to create a new port and having problems with the configpm script, +# try 'make minitest' and/or commenting out the tests at the end of configpm.) +lib/Config.pm: config.sh miniperl configpm ./miniperl configpm tmp sh mv-if-diff tmp lib/Config.pm @@ -334,9 +364,18 @@ install.perl: all installperl install.man: all installman ./perl installman -# Not implemented yet. -#install.html: all installhtml -# ./perl installhtml +# XXX Experimental. Hardwired values, but useful for testing. +# Eventually Configure could ask for some of these values. +install.html: all installhtml + ./perl installhtml \ + --podroot=. --podpath=. --recurse \ + --htmldir=$(privlib)/html \ + --htmlroot=$(privlib)/html \ + --splithead=pod/perlipc \ + --splititem=pod/perlfunc \ + --libpods=perlfunc:perlguts:perlvar:perlrun:perlop \ + --verbose + # I now supply perly.c with the kits, so the following section is # used only if you force byacc to run by saying @@ -346,12 +385,16 @@ install.man: all installman # normally shouldn't remake perly.[ch]. run_byacc: FORCE - @ echo 'Expect' 130 shift/reduce and 1 reduce/reduce conflict + @ echo 'Expect' 113 shift/reduce and 1 reduce/reduce conflict $(BYACC) -d perly.y + chmod 664 perly.c sh $(shellflags) ./perly.fixer y.tab.c perly.c - mv y.tab.h perly.h - echo 'extern YYSTYPE yylval;' >>perly.h - - perl vms/vms_yfix.pl perly.c perly.h vms/perly_c.vms vms/perly_h.vms + sed -e 's/fprintf *( *stderr *,/PerlIO_printf(Perl_debug_log,/g' \ + -e 's/y\.tab/perly/g' perly.c >perly.tmp && mv perly.tmp perly.c + echo 'extern YYSTYPE yylval;' >>y.tab.h + cmp -s y.tab.h perly.h && rm -f y.tab.h || mv y.tab.h perly.h + chmod 664 vms/perly_c.vms vms/perly_h.vms + perl vms/vms_yfix.pl perly.c perly.h vms/perly_c.vms vms/perly_h.vms # We don't want to regenerate perly.c and perly.h, but they might # appear out-of-date after a patch is applied or a new distribution is @@ -386,33 +429,48 @@ regen_headers: FORCE # DynaLoader may be needed for extensions that use Makefile.PL. $(DYNALOADER): miniperl preplibrary FORCE - @sh ext/util/make_ext static $@ LIBPERL_A=$(perllib) + @sh ext/util/make_ext static $@ MAKE=$(MAKE) LIBPERL_A=$(LIBPERL) d_dummy $(dynamic_ext): miniperl preplibrary $(DYNALOADER) FORCE - @sh ext/util/make_ext dynamic $@ LIBPERL_A=$(perllib) + @sh ext/util/make_ext dynamic $@ MAKE=$(MAKE) LIBPERL_A=$(LIBPERL) s_dummy $(static_ext): miniperl preplibrary $(DYNALOADER) FORCE - @sh ext/util/make_ext static $@ LIBPERL_A=$(perllib) + @sh ext/util/make_ext static $@ MAKE=$(MAKE) LIBPERL_A=$(LIBPERL) + +clean: _tidy _mopup -clean: +realclean: _cleaner _mopup + @echo "Note that make realclean does not delete config.sh" + +clobber: _cleaner _mopup + rm -f config.sh cppstdin + +distclean: clobber + +# Do not 'make _mopup' directly. +_mopup: rm -f *$(OBJ_EXT) *$(LIB_EXT) all perlmain.c rm -f perl.exp ext.libs - -rm perl.export perl.dll perl.libexp perl.map perl.def + -rm -f perl.export perl.dll perl.libexp perl.map perl.def + rm -f perl suidperl miniperl $(LIBPERL) + +# Do not 'make _tidy' directly. +_tidy: -cd pod; $(MAKE) clean -cd utils; $(MAKE) clean -cd x2p; $(MAKE) clean -@for x in $(DYNALOADER) $(dynamic_ext) $(static_ext) ; do \ - sh ext/util/make_ext clean $$x ; \ + sh ext/util/make_ext clean $$x MAKE=$(MAKE) ; \ done - rm -f perl suidperl miniperl $(perllib) -realclean: clean +# Do not 'make _cleaner' directly. +_cleaner: -cd os2; rm -f Makefile -cd pod; $(MAKE) realclean -cd utils; $(MAKE) realclean -cd x2p; $(MAKE) realclean -@for x in $(DYNALOADER) $(dynamic_ext) $(static_ext) ; do \ - sh ext/util/make_ext realclean $$x ; \ + sh ext/util/make_ext realclean $$x MAKE=$(MAKE) ; \ done rm -f *.orig */*.orig *~ */*~ core t/core t/c t/perl rm -rf $(addedbyconf) @@ -422,12 +480,6 @@ realclean: clean rm -f lib/.exists rm -f h2ph.man pstruct rm -rf .config - @echo "Note that make realclean does not delete config.sh" - -clobber: realclean - rm -f config.sh cppstdin - -distclean: clobber # The following lint has practically everything turned on. Unfortunately, # you have to wade through a lot of mumbo jumbo that can't be suppressed. @@ -437,19 +489,24 @@ distclean: clobber lint: perly.c $(c) lint $(lintflags) $(defs) perly.c $(c) > perl.fuzz -# Need to unset during recursion to go out of loop +# Need to unset during recursion to go out of loop. +# The README below ensures that the dependency list is never empty and +# that when MAKEDEPEND is empty $(FIRSTMAKEFILE) doesn't need rebuilding. -MAKEDEPEND = makedepend +MAKEDEPEND = Makefile makedepend -$(FIRSTMAKEFILE): Makefile $(MAKEDEPEND) +$(FIRSTMAKEFILE): README $(MAKEDEPEND) $(MAKE) depend MAKEDEPEND= -config.h: config.sh - /bin/sh config_h.SH +config.h: config_h.SH config.sh + $(SHELL) config_h.SH + +perl.exp: perl_exp.SH config.sh + $(SHELL) perl_exp.SH # When done, touch perlmain.c so that it doesn't get remade each time. depend: makedepend - sh ./makedepend + sh ./makedepend MAKE=$(MAKE) - test -s perlmain.c && touch perlmain.c cd x2p; $(MAKE) depend @@ -457,14 +514,30 @@ depend: makedepend makedepend: makedepend.SH config.sh sh ./makedepend.SH -test: miniperl perl preplibrary $(dynamic_ext) - - cd t && chmod +x TEST */*.t - - cd t && (rm -f perl$(EXE_EXT); $(LNS) ../perl$(EXE_EXT) perl$(EXE_EXT)) && ./perl TEST </dev/tty +test-prep: miniperl perl preplibrary $(dynamic_ext) + cd t && (rm -f perl$(EXE_EXT); $(LNS) ../perl$(EXE_EXT) perl$(EXE_EXT)) + +test check: test-prep + cd t && ./perl TEST </dev/tty +# For testing without a tty or controling terminal. See t/op/stat.t +test-notty: test-prep + cd t && PERL_SKIP_TTY_TEST=1 ./perl TEST + +# Can't depend on lib/Config.pm because that might be where miniperl +# is crashing. minitest: miniperl - - cd t && chmod +x TEST */*.t + @echo "You may see some irrelevant test failures if you have been unable" + @echo "to build lib/Config.pm." - cd t && (rm -f perl$(EXE_EXT); $(LNS) ../miniperl$(EXE_EXT) perl$(EXE_EXT)) \ - && ./perl TEST base/*.t comp/*.t cmd/*.t io/*.t op/*.t </dev/tty + && ./perl TEST base/*.t comp/*.t cmd/*.t io/*.t op/*.t pragma/*.t </dev/tty + +# Handy way to run perlbug -ok without having to install and run the +# installed perlbug. We don't re-run the tests here - we trust the user. +# Please *don't* use this unless all tests pass. +# If you want to report test failures, just use "perlbug -Ilib". +ok: + ./perl -Ilib utils/perlbug -ok -s '(UNINSTALLED)' clist: $(c) echo $(c) | tr ' ' '\012' >.clist @@ -478,6 +551,12 @@ shlist: $(sh) pllist: $(pl) echo $(pl) | tr ' ' '\012' >.pllist +Makefile: Makefile.SH ./config.sh + $(SHELL) Makefile.SH + +distcheck: FORCE + perl '-MExtUtils::Manifest=&fullcheck' -e 'fullcheck()' + # AUTOMATICALLY GENERATED MAKE DEPENDENCIES--PUT NOTHING BELOW THIS LINE # If this runs make out of memory, delete /usr/include lines. !NO!SUBS! diff --git a/gnu/usr.bin/perl/Makefile.bsd-wrapper b/gnu/usr.bin/perl/Makefile.bsd-wrapper index 689807ed3cd..db7de3465cb 100644 --- a/gnu/usr.bin/perl/Makefile.bsd-wrapper +++ b/gnu/usr.bin/perl/Makefile.bsd-wrapper @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.bsd-wrapper,v 1.12 1997/07/24 21:12:14 kstailey Exp $ +# $OpenBSD: Makefile.bsd-wrapper,v 1.13 1997/11/30 07:48:01 millert Exp $ # # Build wrapper for Perl 5.003. # @@ -9,22 +9,69 @@ LNDIR= /usr/bin/lndir H2PH= /usr/bin/h2ph -MAN= x2p/a2p.man x2p/s2p.man pod/perl.man pod/perlbook.man \ - pod/perlbot.man pod/perlcall.man pod/perldata.man \ - pod/perldebug.man pod/perldiag.man pod/perldsc.man \ - pod/perlembed.man pod/perlform.man pod/perlfunc.man \ - pod/perlguts.man pod/perlipc.man pod/perllol.man \ - pod/perlmod.man pod/perlobj.man pod/perlop.man \ - pod/perlovl.man pod/perlpod.man pod/perlre.man \ - pod/perlref.man pod/perlrun.man pod/perlsec.man \ - pod/perlstyle.man pod/perlsub.man pod/perlsyn.man \ - pod/perltie.man pod/perltoc.man pod/perltrap.man \ - pod/perlvar.man pod/perlxs.man pod/perlxstut.man +# Pod (plain old documentation) files. These get turned into man pages. +# We treat those pod files that don't end in .pod as a special case +POD= pod/perl.pod pod/perlapio.pod pod/perlbook.pod pod/perlbot.pod \ + pod/perlcall.pod pod/perldata.pod pod/perldebug.pod \ + pod/perldelta.pod pod/perldiag.pod pod/perldsc.pod \ + pod/perlembed.pod pod/perlfaq.pod pod/perlfaq1.pod \ + pod/perlfaq2.pod pod/perlfaq3.pod pod/perlfaq4.pod \ + pod/perlfaq5.pod pod/perlfaq6.pod pod/perlfaq7.pod \ + pod/perlfaq8.pod pod/perlfaq9.pod pod/perlform.pod \ + pod/perlfunc.pod pod/perlguts.pod pod/perlipc.pod \ + pod/perllocale.pod pod/perllol.pod pod/perlmod.pod \ + pod/perlmodlib.pod pod/perlobj.pod pod/perlop.pod \ + pod/perlovl.pod pod/perlpod.pod pod/perlre.pod \ + pod/perlref.pod pod/perlrun.pod pod/perlsec.pod \ + pod/perlstyle.pod pod/perlsub.pod pod/perlsyn.pod \ + pod/perltie.pod pod/perltoc.pod pod/perltoot.pod \ + pod/perltrap.pod pod/perlvar.pod pod/perlxs.pod \ + pod/perlxstut.pod x2p/a2p.pod +# Don't install these for now (need special install to do / > ::) +# lib/Devel/SelfStubber.pm lib/IPC/Open2.pm lib/IPC/Open3.pm \ +# lib/Net/Ping.pm lib/Net/hostent.pm lib/Net/netent.pm \ +# lib/Net/protoent.pm lib/Net/servent.pm lib/ExtUtils/Install.pm \ +# lib/ExtUtils/Liblist.pm lib/ExtUtils/MM_OS2.pm \ +# lib/ExtUtils/MM_Unix.pm lib/ExtUtils/MM_VMS.pm \ +# lib/ExtUtils/MakeMaker.pm lib/ExtUtils/Manifest.pm \ +# lib/ExtUtils/Mkbootstrap.pm lib/ExtUtils/Mksymlists.pm \ +# lib/ExtUtils/testlib.pm lib/ExtUtils/Command.pm \ +# lib/ExtUtils/Embed.pm lib/ExtUtils/MM_Win32.pm \ +# lib/File/Basename.pm lib/File/CheckTree.pm lib/File/Copy.pm \ +# lib/File/Find.pm lib/File/Path.pm lib/File/Compare.pm \ +# lib/File/DosGlob.pm lib/File/stat.pm lib/Getopt/Long.pm \ +# lib/Getopt/Std.pm lib/I18N/Collate.pm lib/Math/BigFloat.pm \ +# lib/Math/BigInt.pm lib/Math/Complex.pm lib/Math/Trig.pm \ +# lib/Pod/Functions.pm lib/Pod/Text.pm lib/Pod/Html.pm \ +# lib/Search/Dict.pm lib/Sys/Hostname.pm lib/Sys/Syslog.pm \ +# lib/Term/Cap.pm lib/Term/Complete.pm lib/Term/ReadLine.pm \ +# lib/Test/Harness.pm lib/Text/Abbrev.pm lib/Text/ParseWords.pm \ +# lib/Text/Soundex.pm lib/Text/Tabs.pm lib/Text/Wrap.pm \ +# lib/Tie/Hash.pm lib/Tie/Scalar.pm lib/Tie/SubstrHash.pm \ +# lib/Tie/RefHash.pm lib/Time/Local.pm lib/Time/gmtime.pm \ +# lib/Time/localtime.pm lib/Time/tm.pm lib/AnyDBM_File.pm \ +# lib/AutoLoader.pm lib/AutoSplit.pm lib/Benchmark.pm \ +# lib/Carp.pm lib/Cwd.pm lib/DirHandle.pm lib/English.pm \ +# lib/Env.pm lib/Exporter.pm lib/FileCache.pm lib/SelectSaver.pm \ +# lib/SelfLoader.pm lib/Shell.pm lib/Symbol.pm \ +# lib/diagnostics.pm lib/integer.pm lib/less.pm lib/lib.pm \ +# lib/overload.pm lib/sigtrap.pm lib/strict.pm lib/subs.pm \ +# lib/vars.pm lib/Bundle/CPAN.pm lib/CGI/Apache.pm \ +# lib/CGI/Carp.pm lib/CGI/Fast.pm lib/CGI/Push.pm \ +# lib/CGI/Switch.pm lib/CGI.pm lib/CPAN.pm lib/CPAN/FirstTime.pm \ +# lib/CPAN/Nox.pm lib/Class/Struct.pm lib/FileHandle.pm \ +# lib/FindBin.pm lib/UNIVERSAL.pm lib/User/grent.pm \ +# lib/User/pwent.pm lib/autouse.pm lib/base.pm lib/blib.pm \ +# lib/constant.pm lib/locale.pm .include <bsd.own.mk> .ifndef NOMAN -MANALL= ${MAN:S/.man$/.cat1/g} +MANALL= ${POD:S/.pod$/.cat1/g:S/.pm$/.cat3p/g} \ + utils/c2ph.cat1 utils/h2ph.cat1 utils/h2xs.cat1 \ + utils/perldoc.cat1 utils/perlbug.cat1 utils/pl2pm.cat1 \ + utils/splain.cat1 x2p/s2p.cat1 pod/pod2man.cat1 \ + pod/pod2html.cat1 utils/pstruct.cat1 lib/ExtUtils/xsubpp.cat1 .else MANALL= .endif @@ -37,16 +84,20 @@ INST_PROG='/usr/bin/install -cs' INST_PROG='/usr/bin/install -c' .endif -.SUFFIXES: .man .cat1 +.SUFFIXES: .pod .pm .cat1 cat3p -.man.cat1: - @echo "${NROFF} -mandoc ${.IMPSRC} > ${.TARGET}" - @${NROFF} -mandoc ${.IMPSRC} > ${.TARGET} || (rm -f ${.TARGET}; false) +.pod.cat1: + @echo "./perl -I./lib ./pod/pod2man --section=1 --official ${.IMPSRC} | ${NROFF} -man > ${.TARGET}" + ./perl -I$./lib ./pod/pod2man --section=1 --official ${.IMPSRC} | ${NROFF} -man > ${.TARGET} || (rm -f ${.TARGET}; false) +# XXX - '/' needs to become :: when installed (need own maninstall target?) +.pm.cat3p: + @echo "./perl -I./lib ./pod/pod2man --section=3p --official ${.IMPSRC} | ${NROFF} -man > ${.TARGET}" + ./perl -I./lib ./pod/pod2man --section=1 --official ${.IMPSRC} | ${NROFF} -man > ${.TARGET} || (rm -f ${.TARGET}; false) GENERATED= config.sh Makefile cflags config.h makeaperl makedepend \ makedir perl.exp writemain x2p/Makefile x2p/cflags -CLEANFILES= config.sh ${MANALL} +CLEANFILES= config.sh ${MAN} ${MANALL} .BEGIN: @if [ ${.CURDIR} != ${.OBJDIR} ]; then ${LNDIR} -s -e obj -e obj.${MACHINE_ARCH} -e Makefile.bsd-wrapper ${.CURDIR}; fi @@ -88,6 +139,54 @@ x2p/Makefile: x2p/cflags: (cd ${.OBJDIR}/x2p; /bin/sh cflags.SH) +utils/c2ph.cat1: utils/c2ph + @echo "./perl -I./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET}" + ./perl -I$./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET} || (rm -f ${.TARGET}; false) + +utils/h2ph.cat1: utils/h2ph + @echo "./perl -I./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET}" + ./perl -I$./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET} || (rm -f ${.TARGET}; false) + +utils/h2xs.cat1: utils/h2xs + @echo "./perl -I./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET}" + ./perl -I$./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET} || (rm -f ${.TARGET}; false) + +utils/perldoc.cat1: utils/perldoc + @echo "./perl -I./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET}" + ./perl -I$./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET} || (rm -f ${.TARGET}; false) + +utils/perlbug.cat1: utils/perlbug + @echo "./perl -I./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET}" + ./perl -I$./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET} || (rm -f ${.TARGET}; false) + +utils/pl2pm.cat1: utils/pl2pm + @echo "./perl -I./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET}" + ./perl -I$./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET} || (rm -f ${.TARGET}; false) + +utils/splain.cat1: utils/splain + @echo "./perl -I./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET}" + ./perl -I$./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET} || (rm -f ${.TARGET}; false) + +x2p/s2p.cat1: x2p/s2p + @echo "./perl -I./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET}" + ./perl -I$./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET} || (rm -f ${.TARGET}; false) + +pod/pod2man.cat1: pod/pod2man + @echo "./perl -I./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET}" + ./perl -I$./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET} || (rm -f ${.TARGET}; false) + +pod/pod2html.cat1: pod/pod2html + @echo "./perl -I./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET}" + ./perl -I$./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET} || (rm -f ${.TARGET}; false) + +utils/pstruct.cat1: utils/pstruct + @echo "./perl -I./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET}" + ./perl -I$./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET} || (rm -f ${.TARGET}; false) + +lib/ExtUtils/xsubpp.cat1: lib/ExtUtils/xsubpp + @echo "./perl -I./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET}" + ./perl -I$./lib ./pod/pod2man --section=1 --official ${.ALLSRC} | ${NROFF} -man > ${.TARGET} || (rm -f ${.TARGET}; false) + .ifdef NOMAN maninstall: @echo NOMAN is set @@ -95,7 +194,7 @@ maninstall: install: ${MANALL} maninstall (cd ${.OBJDIR}; INSTALL=${INSTALL} INSTALL_COPY=${INSTALL_COPY} \ - INSTALL_STRIP=${INSTALL_STRIP} ${MAKE} install) + INSTALL_STRIP=${INSTALL_STRIP} ${MAKE} install.perl) (cd ${DESTDIR}/usr/include; ${H2PH} *.h arpa/*.h machine/*.h net/*.h \ protocols/*.h sys/*.h) -chmod -R a+rX ${DESTDIR}/usr/lib/perl5 diff --git a/gnu/usr.bin/perl/README b/gnu/usr.bin/perl/README index 0a7ab1ce967..83b9ab578f9 100644 --- a/gnu/usr.bin/perl/README +++ b/gnu/usr.bin/perl/README @@ -1,7 +1,7 @@ Perl Kit, Version 5.0 - Copyright 1989-1996, Larry Wall + Copyright 1989-1997, Larry Wall All rights reserved. This program is free software; you can redistribute it and/or modify @@ -62,20 +62,21 @@ in MANIFEST. Installation -1) Detailed instructions are in the file INSTALL. In brief, the -following should work on most systems: +1) Detailed instructions are in the file INSTALL which you should read. +In brief, the following should work on most systems: rm -f config.sh sh Configure make make test make install -For most systems, it should be safe to accept all the Configure -defaults. +For most systems, it should be safe to accept all the Configure defaults. +(It is recommended that you accept the defaults the first time you build +or if you have any problems building.) 2) Read the manual entries before running perl. 3) IMPORTANT! Help save the world! Communicate any problems and suggested -patches to me, lwall@sems.com (Larry Wall), so we can +patches to me, larry@wall.org (Larry Wall), so we can keep the world in sync. If you have a problem, there's someone else out there who either has had or will have the same problem. It's usually helpful if you send the output of the "myconfig" script diff --git a/gnu/usr.bin/perl/README.vms b/gnu/usr.bin/perl/README.vms index ba0ba190fd7..4b8c29d3458 100644 --- a/gnu/usr.bin/perl/README.vms +++ b/gnu/usr.bin/perl/README.vms @@ -1,3 +1,383 @@ +Last Revised 11-September-1997 by Dan Sugalski <sugalsd@lbcc.cc.or.us> +Originally by Charles Bailey <bailey@newman.upenn.edu> + +* Intro + +The VMS port of Perl is as functionally complete as any other Perl port +(and as complete as the ports on some Unix systems). The Perl binaries +provide all the Perl system calls that are either available under VMS or +reasonably emulated. There are some incompatibilites in process handling +(e.g the fork/exec model for creating subprocesses doesn't do what you +might expect under Unix), mainly because VMS and Unix handle processes and +sub-processes very differently. + +There are still some unimplemented system functions, and of coursse we +could use modules implementing useful VMS system services, so if you'd like +to lend a hand we'd love to have you. Join the Perl Porting Team Now! + +The current sources and build procedures have been tested on a VAX using +VaxC and Dec C, and on an AXP using Dec C. If you run into problems with +other compilers, please let us know. + +There are issues with varions versions of Dec C, so if you're not running a +relatively modern version, check the Dec C issues section later on in this +document. + +* Other required software + +In addition to VMS, you'll need: + 1) A C compiler. Dec C for AXP, or VAX C, Dec C, or gcc for the + VAX. + 2) A make tool. Dec's MMS (v2.6 or later), or MadGoat's free MMS + analog MMK (available from ftp.madgoat.com/madgoat) both work + just fine. Gnu Make might work, but it's been so long since + anyone's tested it that we're not sure. MMK's free, though, so + go ahead and use that. + + +If you want to include socket support, you'll need a TCP stack and either +Dec C, or socket libraries. See the Socket Support topic for more details. + +* Compiling Perl + +>From the top level of the Perl source directory, do this: + +MMS/DESCRIP=[.VMS]DESCRIP.MMS + +If you're on an Alpha, add /Macro=("__AXP__=1","decc=1") +If you're using Dec C as your C compiler (you are on all alphas), add +/Macro=("decc=1") +If Vac C is your default C compiler and you want to use Dec C, add +/Macro=("CC=CC/DECC") (Don't forget the /macro=("decc=1") +If Dec C is your default C compiler and you want to use Vax C, add +/Macro=("CC=CC/VAXC") +If you want Socket support and are using the SOCKETSHR socket library, add +/Macro=("SOCKETSHR_SOCKETS=1") +If you want Socket support and are using the Dec C RTL socket interface +(You must be using Dec C for this), add /Macro=("DECC_SOCKETS=1") + +If you have multiple /macro= items, combine them together in one /Macro=() +switch, with all the options inside the parentheses separated by commas. + +Samples: + +VMS AXP, with Socketshr sockets: + +$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("decc=1","__AXP__=1","SOCKETSHR_SOCKETS=1") + +VMS AXP with no sockets + +$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("decc=1","__AXP__=1") + +VMS AXP with the Dec C RTL sockets + +$MMS/DESCRIP=[.VMS]/Macro=("decc=1","__AXP__=1","DECC_SOCKETS=1") + +VMS VAX with default system compiler, no sockets + +$MMS/DESCRIP=[.VMS]DESCRIP.MMS + +VMS VAX with Dec C compiler, no sockets + +$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("CC=CC/DECC","decc=1") + +VMS VAX with Dec C compiler, Dec C RTL sockets + +$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("CC=CC/DECC","decc=1","DECC_SOCKETS=1") + +VMS VAX with Dec C compiler, Socketshr sockets + +$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("CC=CC/DECC","decc=1","SOCKETSHR_SOCKETS=1") + +Using Dec C is recommended over Vax C. The compiler is newer, and +supported. (Vax C was decommisioned around 1993) Various older versions had +some gotchas, so if you're using a version older than 5.2, check the Dec C +Issues section. + +We'll also point out that Dec C will get you at least a ten-fold increase +in line-oriented IO over Vax C. The optimizer is amazingly better, too. If +you can use Dec C, then you *really*, *really* should. + + +Once you issue your MMS command, sit back and wait. Perl should build and +link without a problem. If it doesn't, check the Gotchas to watch out for +section. If that doesn't help, send some mail to the VMSPERL mailing list. +Instructions are in the Mailing Lists section. + +* Testing Perl + +Once Perl has built cleanly, you need to test it to make sure things work. +This step is very important--there are always things that can go wrong +somehow and get you a dysfunctional Perl. + +Testing is very easy, though, as there's a full test suite in the perl +distribution. To run the tests, enter the *exact* MMS line you used to +compile Perl and add the word "test" to the end, like this: + +Compile Command: + +$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("__AXP__=1","decc=1","DECCRTL_SOCKETS=1") + +Test Command: + +$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("__AXP__=1","decc=1","DECCRTL_SOCKETS=1") test + +MMS will run all the tests. This may take some time, as there are a lot of +tests. If any tests fail, there will be a note made on-screen. At the end +of all the tests, a summary of the tests, the number passed and failed, and +the time taken will be displayed. + +If any tests fail, it means something's wrong with Perl. If the test suite +hangs (some tests can take upwards of two or three minutes, or more if +you're on an especially slow machine, depending on you machine speed, so +don't be hasty), then the test *after* the last one displayed failed. Don't +install Perl unless you're confident that you're OK. Regardless of how +confident you are, make a bug report to the VMSPerl mailing list. + +If one or more tests fail, you can get more info on the failure by issuing +this command sequence: + +$ SET DEFAULT [.T] +$ @[-.VMS]TEST .typ -v [.subdir]test.T + +where ".typ" is the file type of the Perl images you just built (if you +didn't do anything special, use .EXE), and "[.subdir]test.T" is the test +that failed. For example, with a normal Perl build, if the test indicated +that [.op]time failed, then you'd do this: + +$ SET DEFAULT [.T] +$ @[-.VMS]TEST .EXE -v [.OP]TIME.T + +When you send in a bug report for failed tests, please include the output +from this command, which is run from the main source directory: + +MCR []MINIPERL "-V" + +Note that "-V" really is a capital V in double quotes. This will dump out a +couple of screens worth of config info, and can help us diagnose the problem. + +* Cleaning up and starting fresh + +If you need to recompile from scratch, you have to make sure you clean up +first. There's a procedure to do it--enter the *exact* MMS line you used to +compile and add "realclean" at the end, like this: + +Compile Command: + +$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("__AXP__=1","decc=1","DECCRTL_SOCKETS=1") + +Cleanup Command: + +$MMS/DESCRIP=[.VMS]DESCRIP.MMS/Macro=("__AXP__=1","decc=1","DECCRTL_SOCKETS=1") realclean + +If you don't do this, things may behave erratically. They might not, too, +so it's best to be sure and do it. + +* Installing Perl + +There are several steps you need to take to get Perl installed and +running. At some point we'll have a working install in DESCRIP.MMS, but for +right now the procedure's manual, and goes like this. + +1) Create a directory somewhere and define the concealed logical PERL_ROOT +to point to it. For example, DEFINE/TRANS=(CONC,TERM) PERL_ROOT dka200:[perl.] + +2) Copy perl.exe into PERL_ROOT:[000000] + +3) Copy everything in [.LIB] and [.UTILS] (including all the +subdirectories!) to PERL_ROOT:[LIB] and PERL_ROOT:[UTILS]. + +4) Either copy PERLSHR.EXE to SYS$SHARE, or to somewhere globally accessble +and define the logical PERLSHR to point to it (DEFINE PERLSHR +PERL_ROOT:[000000]PERLSHR.EXE or something like that). The PerlShr image +should have W:RE protections on it. (Just W:E triggers increased security in +the image activator. Not a huge problem, but Perl will need to have any +other shared image it accesses INSTALLed. It's a huge pain, so don't unless +you know what you're doing) + +5) Either define the symbol PERL somewhere, such as +SYS$MANAGER:SYLOGIN.COM, to be "PERL :== $PERL_ROOT:[000000]PERL.EXE", or +install Perl into DCLTABLES.EXE )Check out the section "Installing Perl +into DCLTABLES" for more info), or put the image in a directory that's in +your DCL$PATH (if you're using VMS 6.2 or higher). + +6) Optionally define the command PERLDOC as +PERLDOC :== $PERL_ROOT:[000000]PERL PERL_ROOT:[LIB.POD]PERLDOC.COM -T + +7) Optionally define the command PERLBUG (the Perl bug report generator) as +PERLBUG :== $PERL_ROOT:[000000]PERL PERL_ROOT:[LIB]PERLBUG.COM" + +* Installing Perl into DCLTABLES + +Courtesy of Brad Hughes: + +Put the following, modified to reflect where your .exe is, in PERL.CLD: + +define verb perl +image perl_root:[exe]perl.exe +cliflags (foreign) + +and then + +$ set command perl /table=sys$common:[syslib]dcltables.exe - + /output=sys$common:[syslib]dcltables.exe +$ install replace sys$common:[syslib]dcltables.exe + +and you don't need perl :== $perl_root:[exe]perl.exe. + +* Changing compile-time things + +Most of the user-definable features of Perl are enabled or disabled in +[.VMS]CONFIG.VMS. There's code in there to Do The Right Thing, but that may +end up being the wrong thing for you. Make sure you understand what you're +doing, since changes here can get you a busted perl. + +Odds are that there's nothing here to change, unless you're on a version of +VMS later than 6.2 and Dec C later than 5.6. Even if you are, the correct +values will still be chosen, most likely. Poking around here should be +unnecessary. + +The one exception is the various *DIR install locations. Changing those +requires changes in genconfig.pl as well. Be really careful if you need to +change these,a s they can cause some fairly subtle problems. + +* Extra things in the Perl distribution + +In addition to the standard stuff that gets installed, there are two +optional extensions, DCLSYM and STDIO, that are handy. Instructions for +these two modules are in [.VMS.EXT.DCLSYM] and [.VMS.EXT.STDIO], +respectively. + +* Socket Support + +Perl includes a number of functions for IP sockets, which are available if +you choose to compile Perl with socket support. (See the section Compiling +Perl for more info on selecting a socket stack) Since IP networking is an +optional addition to VMS, there are several different IP stacks +available. How well integrated they are into the system depends on the +stack, your version of VMS, and the version of your C compiler. + +The most portable solution uses the SOCKETSHR library. In combination with +either UCX or NetLib, this supports all the major TCP stacks (Multinet, +Pathways, TCPWare, UCX, and CMU) on all versions of VMS Perl runs on, with +all the compilers on both VAX and Alpha. The socket interface is also +consistent across versions of VMS and C compilers. It has a problem with +UDP sockets when used with Multinet, though, so you should be aware of +that. + +The other solution available is to use the socket routines built into Dec +C. Which routines are available depend on the version of VMS you're +running, and require proper UCX emulation by your TCP/IP vendor. +Relatively current versions of Multinet, TCPWare, Pathway, and UCX all +provide the required libraries--check your manuals or release notes to see +if your version is new enough. + +* Reporting Bugs + +If you come across what you think might be a bug in Perl, please report +it. There's a script in PERL_ROOT:[UTILS], perlbug, that walks you through +the process of creating a bug report. This script includes details of your +installation, and is very handy. Completed bug reports should go to +PERLBUG@PERL.COM. + +* Gotchas to watch out for + +Probably the single biggest gotcha in compiling Perl is giving the wrong +switches to MMS/MMK when you build. If Perl's building oddly, double-check +your switches. If you're on a VAX, be sure to add a /Macro=("decc=1") if +you're using Dec C, and if you're on an alpha and using MMS, you'll need a +/Macro=("__AXP__=1") + +The next big gotcha is directory depth. Perl can create directories four +and five levels deep during the build, so you don't have to be too deep to +start to hit the RMS 8 level point. It's best to do a +$DEFINE/TRANS=(CONC,TERM) PERLSRC disk:[dir.dir.dir.perldir.]" (note the +trailing period) and $SET DEFAULT PERLSRC:[000000] before building. Perl +modules can be just as bad (or worse), so watch out for them, too. + +Finally, the third thing that bites people is leftover pieces from a failed +build. If things go wrong, make sure you do a "(MMK|MMS|make) realclean" +before you rebuild. + +* Dec C issues + +Note to DECC users: Some early versions (pre-5.2, some pre-4. If you're Dec +C 5.x or higher, with current patches if anym you're fine) of the DECCRTL +contained a few bugs which affect Perl performance: + - Newlines are lost on I/O through pipes, causing lines to run together. + This shows up as RMS RTB errors when reading from a pipe. You can + work around this by having one process write data to a file, and + then having the other read the file, instead of the pipe. This is + fixed in version 4 of DECC. + - The modf() routine returns a non-integral value for some values above + INT_MAX; the Perl "int" operator will return a non-integral value in + these cases. This is fixed in version 4 of DECC. + - On the AXP, if SYSNAM privilege is enabled, the CRTL chdir() routine + changes the process default device and directory permanently, even + though the call specified that the change should not persist after + Perl exited. This is fixed by DEC CSC patch AXPACRT04_061. + +* Mailing Lists + +There are several mailing lists available to the Perl porter. For VMS +specific issues (including both Perl questions and installation problems) +there is the VMSPERL mailing list. It's usually a low-volume (10-12 +messages a week) mailing list. + +The subscription address is VMSPERL-REQUEST@NEWMAN.UPENN.EDU. Send a mail +message with just the words SUBSCRIBE VMSPERL in the body of the message. + +The VMSPERL mailing list address is VMSPERL@NEWMAN.UPENN.EDU. Any mail +sent there gets echoed to all subscribers of the list. + +The Perl5-Porters list is for anyone involved in porting Perl to a +platform. This includes you, if you want to participate. It's a high-volume +list (60-100 messages a day during active development times), so be sure +you want to be there. The subscription address is +Perl5-Porters-request@perl.org. Send a message with just the word SUBSCRIBE +in the body. The posting address is Perl5-Porters@perl.org. + +* Acknowledgements + +A real big thanks needs to go to Charles Bailey +<bailey@newman.upenn.edu>, who is ultimately responsible for Perl 5.004 +running on VMS. Without him, nothing the rest of us have done would be at +all important. + +There are, of course, far too many people involved in the porting and testing +of Perl to mention everyone who deserves it, so please forgive us if we've +missed someone. That said, special thanks are due to the following: + Tim Adye <T.J.Adye@rl.ac.uk> + for the VMS emulations of getpw*() + David Denholm <denholm@conmat.phys.soton.ac.uk> + for extensive testing and provision of pipe and SocketShr code, + Mark Pizzolato <mark@infocomm.com> + for the getredirection() code + Rich Salz <rsalz@bbn.com> + for readdir() and related routines + Peter Prymmer <pvhp@lns62.lns.cornell.edu) + for extensive testing, as well as development work on + configuration and documentation for VMS Perl, + Dan Sugalski <sugalsd@stargate.lbcc.cc.or.us> + for extensive contributions to recent version support, + development of VMS-specific extensions, and dissemination + of information about VMS Perl, + the Stanford Synchrotron Radiation Laboratory and the + Laboratory of Nuclear Studies at Cornell University for + the the opportunity to test and develop for the AXP, +and to the entire VMSperl group for useful advice and suggestions. In +addition the perl5-porters deserve credit for their creativity and +willingness to work with the VMS newcomers. Finally, the greatest debt of +gratitude is due to Larry Wall <larry@wall.org>, for having the ideas which +have made our sleepless nights possible. + +Thanks, +The VMSperl group + + +--------------------------------------------------------------------------- +[Here's the pre-5.004_04 version of README.vms, for the record.] + Last revised: 19-Jan-1996 by Charles Bailey bailey@genetics.upenn.edu The VMS port of Perl is still under development. At this time, the Perl @@ -292,10 +672,10 @@ of to the Perl bug reporting address, perlbug@perl.com. * For more information -If you're interested in more information on Perl in general, consult the Usenet -newsgroups comp.lang.perl.announce and comp.lang.perl.misc. The FAQ for these -groups provides pointers to other online sources of information, as well as -books describing Perl in depth. +If you're interested in more information on Perl in general, you may wish to +consult the Usenet newsgroups comp.lang.perl.announce and comp.lang.perl.misc. +The FAQ for these groups provides pointers to other online sources of +information, as well as books describing Perl in depth. If you're interested in up-to-date information on Perl development and internals, you might want to subscribe to the perl5-porters mailing list. You @@ -305,11 +685,12 @@ subscribe perl5-porters This is a high-volume list at the moment (>50 messages/day). If you're interested in ongoing information about the VMS port, you can -subscribe to the VMSperl mailing list by sending a request to -bailey@genetics.upenn.edu (it's to a human, not a list server - this is a small -operation at the moment). And, as always, we welcome any help or code you'd +subscribe to the VMSPerl mailing list by sending a request to +vmsperl-request@genetics.upenn.edu, containing the single line +subscribe VMSPerl +as the body of the message. And, as always, we welcome any help or code you'd like to offer - you can send mail to bailey@genetics.upenn.edu or directly to -the VMSperl list at vmsperl@genetics.upenn.edu. +the VMSPerl list at vmsperl@genetics.upenn.edu. Finally, if you'd like to try out the latest changes to VMS Perl, you can retrieve a test distribution kit by anonymous ftp from genetics.upenn.edu, in @@ -341,14 +722,17 @@ missed someone. That said, special thanks are due to the following: for the getredirection() code Rich Salz <rsalz@bbn.com> for readdir() and related routines - Richard Dyson <dyson@blaze.physics.uiowa.edu> and - Kent Covert <kacovert@miavx1.acs.muohio.edu> - for additional testing on the AXP. + Peter Prymmer <pvhp@lns62.lns.cornell.edu) + for extensive testing, as well as development work on + configuration and documentation for VMS Perl, + the Stanford Synchrotron Radiation Laboratory and the + Laboratory of Nuclear Studies at Cornell University for + the the opportunity to test and develop for the AXP, and to the entire VMSperl group for useful advice and suggestions. In addition the perl5-porters, especially Andy Dougherty <doughera@lafcol.lafayette.edu> and Tim Bunce <Tim.Bunce@ig.co.uk>, deserve credit for their creativity and willingness to work with the VMS newcomers. Finally, the greatest debt of -gratitude is due to Larry Wall <lwall@sems.com>, for having the ideas which +gratitude is due to Larry Wall <larry@wall.org>, for having the ideas which have made our sleepless nights possible. Thanks, diff --git a/gnu/usr.bin/perl/Todo b/gnu/usr.bin/perl/Todo index 114a488691e..627045c9520 100644 --- a/gnu/usr.bin/perl/Todo +++ b/gnu/usr.bin/perl/Todo @@ -5,27 +5,22 @@ Tie Modules ShiftSplice Defines shift et al in terms of splice method Would be nice to have - Profiler pack "(stuff)*" Contiguous bitfields in pack/unpack lexperl Bundled perl preprocessor Use posix calls internally where possible - const variables gettimeofday - bytecompiler format BOTTOM - $obj->can("method") to probe method inheritance -iprefix. -i rename file only when successfully changed All ARGV input should act like <> - Multiple levels of warning report HANDLE [formats]. - tie(FILEHANDLE, ...) - __DATA__ support in perlmain to rerun debugger - make 'r' print return value like gdb 'fini' - regression tests using __WARN__ and __DIE__ hooks + regression tests using __DIE__ hook + reference to compiled regexp + lexically scoped functions: my sub foo { ... } + lvalue functions Possible pragmas debugger @@ -43,25 +38,20 @@ Optimizations Shrink opcode tables via multiple implementations selected in peep Cache hash value? (Not a win, according to Guido) Optimize away @_ where possible - sfio? "one pass" global destruction Optimize sort by { $a <=> $b } Rewrite regexp parser for better integrated optimization + LRU cache of regexp: foreach $pat (@pats) { foo() if /$pat/ } Vague possibilities ref function in list context - Populate %SIG at startup if appropriate data prettyprint function? (or is it, as I suspect, a lib routine?) make tr/// return histogram in list context? - undef wantarray in void context Loop control on do{} et al Explicit switch statements - perl to C translator - multi-thread scheduling built-in globbing compile to real threaded code structured types - paren counting in tokener to queue remote expectations autocroak? Modifiable $1 et al substr EXPR,OFFSET,LENGTH,STRING diff --git a/gnu/usr.bin/perl/XSUB.h b/gnu/usr.bin/perl/XSUB.h index af452ea5d77..0b82a270b46 100644 --- a/gnu/usr.bin/perl/XSUB.h +++ b/gnu/usr.bin/perl/XSUB.h @@ -38,19 +38,22 @@ #ifdef XS_VERSION # define XS_VERSION_BOOTCHECK \ - STMT_START { \ - char vn[255], *module = SvPV(ST(0),na); \ - if (items >= 2) /* version supplied as bootstrap arg */ \ - Sv=ST(1); \ - else { /* read version from module::VERSION */ \ - sprintf(vn,"%s::VERSION", module); \ - Sv = perl_get_sv(vn, FALSE); /* XXX GV_ADDWARN */ \ - } \ - if (Sv && (!SvOK(Sv) || strNE(XS_VERSION, SvPV(Sv,na))) ) \ - croak("%s object version %s does not match %s.pm $VERSION %s", \ - module,XS_VERSION, module,(Sv && SvOK(Sv))?SvPV(Sv,na):"(undef)");\ + STMT_START { \ + char *vn = "", *module = SvPV(ST(0),na); \ + if (items >= 2) /* version supplied as bootstrap arg */ \ + Sv = ST(1); \ + else { \ + /* XXX GV_ADDWARN */ \ + Sv = perl_get_sv(form("%s::%s", module, \ + vn = "XS_VERSION"), FALSE); \ + if (!Sv || !SvOK(Sv)) \ + Sv = perl_get_sv(form("%s::%s", module, \ + vn = "VERSION"), FALSE); \ + } \ + if (Sv && (!SvOK(Sv) || strNE(XS_VERSION, SvPV(Sv, na)))) \ + croak("%s object version %s does not match $%s::%s %_", \ + module, XS_VERSION, module, vn, Sv); \ } STMT_END #else # define XS_VERSION_BOOTCHECK #endif - diff --git a/gnu/usr.bin/perl/av.c b/gnu/usr.bin/perl/av.c index b27ec762a63..4a87eaf2b51 100644 --- a/gnu/usr.bin/perl/av.c +++ b/gnu/usr.bin/perl/av.c @@ -1,6 +1,6 @@ /* av.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -15,15 +15,15 @@ #include "EXTERN.h" #include "perl.h" -static void av_reify _((AV* av)); - -static void +void av_reify(av) AV* av; { I32 key; SV* sv; - + + if (AvREAL(av)) + return; key = AvMAX(av) + 1; while (key > AvFILL(av) + 1) AvARRAY(av)[--key] = &sv_undef; @@ -33,6 +33,9 @@ AV* av; if (sv != &sv_undef) (void)SvREFCNT_inc(sv); } + key = AvARRAY(av) - AvALLOC(av); + while (key) + AvALLOC(av)[--key] = &sv_undef; AvREAL_on(av); } @@ -94,7 +97,7 @@ I32 key; #endif ary = AvALLOC(av) + AvMAX(av) + 1; tmp = newmax - AvMAX(av); - if (av == stack) { /* Oops, grew stack (via av_store()?) */ + if (av == curstack) { /* Oops, grew stack (via av_store()?) */ stack_sp = AvALLOC(av) + (stack_sp - stack_base); stack_base = AvALLOC(av); stack_max = stack_base + newmax; @@ -153,12 +156,19 @@ I32 lval; return av_store(av,key,sv); } if (AvARRAY(av)[key] == &sv_undef) { + emptyness: if (lval) { sv = NEWSV(6,0); return av_store(av,key,sv); } return 0; } + else if (AvREIFY(av) + && (!AvARRAY(av)[key] /* eg. @_ could have freed elts */ + || SvTYPE(AvARRAY(av)[key]) == SVTYPEMASK)) { + AvARRAY(av)[key] = &sv_undef; /* 1/2 reify */ + goto emptyness; + } return &AvARRAY(av)[key]; } @@ -172,10 +182,13 @@ SV *val; if (!av) return 0; + if (!val) + val = &sv_undef; if (SvRMAGICAL(av)) { if (mg_find((SV*)av,'P')) { - mg_copy((SV*)av, val, 0, key); + if (val != &sv_undef) + mg_copy((SV*)av, val, 0, key); return 0; } } @@ -185,18 +198,16 @@ SV *val; if (key < 0) return 0; } - if (!val) - val = &sv_undef; - + if (SvREADONLY(av) && key >= AvFILL(av)) + croak(no_modify); + if (!AvREAL(av) && AvREIFY(av)) + av_reify(av); if (key > AvMAX(av)) av_extend(av,key); - if (AvREIFY(av)) - av_reify(av); - ary = AvARRAY(av); if (AvFILL(av) < key) { if (!AvREAL(av)) { - if (av == stack && key > stack_sp - stack_base) + if (av == curstack && key > stack_sp - stack_base) stack_sp = stack_base + key; /* XPUSH in disguise */ do ary[++AvFILL(av)] = &sv_undef; @@ -242,17 +253,19 @@ register SV **strp; av = (AV*)NEWSV(8,0); sv_upgrade((SV *) av,SVt_PVAV); - New(4,ary,size+1,SV*); - AvALLOC(av) = ary; AvFLAGS(av) = AVf_REAL; - SvPVX(av) = (char*)ary; - AvFILL(av) = size - 1; - AvMAX(av) = size - 1; - for (i = 0; i < size; i++) { - assert (*strp); - ary[i] = NEWSV(7,0); - sv_setsv(ary[i], *strp); - strp++; + if (size) { /* `defined' was returning undef for size==0 anyway. */ + New(4,ary,size,SV*); + AvALLOC(av) = ary; + SvPVX(av) = (char*)ary; + AvFILL(av) = size - 1; + AvMAX(av) = size - 1; + for (i = 0; i < size; i++) { + assert (*strp); + ary[i] = NEWSV(7,0); + sv_setsv(ary[i], *strp); + strp++; + } } return av; } @@ -289,6 +302,11 @@ register AV *av; register I32 key; SV** ary; +#ifdef DEBUGGING + if (SvREFCNT(av) <= 0) { + warn("Attempt to clear deleted array"); + } +#endif if (!av || AvMAX(av) < 0) return; /*SUPPRESS 560*/ @@ -306,6 +324,9 @@ register AV *av; SvPVX(av) = (char*)AvALLOC(av); } AvFILL(av) = -1; + + if (SvRMAGICAL(av)) + mg_clear((SV*)av); } void @@ -322,10 +343,6 @@ register AV *av; while (key) SvREFCNT_dec(AvARRAY(av)[--key]); } - if (key = AvARRAY(av) - AvALLOC(av)) { - AvMAX(av) += key; - SvPVX(av) = (char*)AvALLOC(av); - } Safefree(AvALLOC(av)); AvALLOC(av) = 0; SvPVX(av) = 0; @@ -354,6 +371,8 @@ register AV *av; if (!av || AvFILL(av) < 0) return &sv_undef; + if (SvREADONLY(av)) + croak(no_modify); retval = AvARRAY(av)[AvFILL(av)]; AvARRAY(av)[AvFILL(av)--] = &sv_undef; if (SvSMAGICAL(av)) @@ -371,12 +390,10 @@ register I32 num; if (!av || num <= 0) return; - if (!AvREAL(av)) { - if (AvREIFY(av)) - av_reify(av); - else - croak("Can't unshift"); - } + if (SvREADONLY(av)) + croak(no_modify); + if (!AvREAL(av) && AvREIFY(av)) + av_reify(av); i = AvARRAY(av) - AvALLOC(av); if (i) { if (i > num) @@ -414,6 +431,8 @@ register AV *av; if (!av || AvFILL(av) < 0) return &sv_undef; + if (SvREADONLY(av)) + croak(no_modify); retval = *AvARRAY(av); if (AvREAL(av)) *AvARRAY(av) = &sv_undef; diff --git a/gnu/usr.bin/perl/av.h b/gnu/usr.bin/perl/av.h index 93dcc0cfdc9..a8dc60b4cde 100644 --- a/gnu/usr.bin/perl/av.h +++ b/gnu/usr.bin/perl/av.h @@ -1,6 +1,6 @@ /* av.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -8,7 +8,7 @@ */ struct xpvav { - char* xav_array; /* pointer to malloced string */ + char* xav_array; /* pointer to first array element */ SSize_t xav_fill; SSize_t xav_max; IV xof_off; /* ptr is incremented by offset */ @@ -16,7 +16,7 @@ struct xpvav { MAGIC* xmg_magic; /* magic for scalar array */ HV* xmg_stash; /* class package */ - SV** xav_alloc; + SV** xav_alloc; /* pointer to malloced string */ SV* xav_arylen; U8 xav_flags; }; @@ -44,5 +44,5 @@ struct xpvav { #define AvREUSED_on(av) (AvFLAGS(av) |= AVf_REUSED) #define AvREUSED_off(av) (AvFLAGS(av) &= ~AVf_REUSED) -#define AvREALISH(av) AvFLAGS(av) /* REAL or REIFY -- shortcut */ +#define AvREALISH(av) (AvFLAGS(av) & (AVf_REAL|AVf_REIFY)) diff --git a/gnu/usr.bin/perl/cflags.SH b/gnu/usr.bin/perl/cflags.SH index 9dc5c90127b..39e96cc1ee1 100644 --- a/gnu/usr.bin/perl/cflags.SH +++ b/gnu/usr.bin/perl/cflags.SH @@ -21,6 +21,7 @@ echo "Extracting cflags (with variable substitutions)" : Move anything that needs config subs from !NO!SUBS! section to !GROK!THIS!. : Protect any dollar signs and backticks that you do not want interpreted : by putting a backslash in front. You may delete these comments. +rm -f cflags $spitshell >cflags <<!GROK!THIS! $startsh !GROK!THIS! @@ -122,8 +123,8 @@ for file do optimize="$optdebug" fi - echo "$cc -c $ccflags $optimize $perltype $large $split" - eval "$also "'"$cc -c $ccflags $optimize $perltype $large $split"' + echo "$cc -c -DPERL_CORE $ccflags $optimize $perltype $large $split" + eval "$also "'"$cc -DPERL_CORE -c $ccflags $optimize $perltype $large $split"' . $TOP/config.sh diff --git a/gnu/usr.bin/perl/compat3.sym b/gnu/usr.bin/perl/compat3.sym new file mode 100644 index 00000000000..db53dd67bef --- /dev/null +++ b/gnu/usr.bin/perl/compat3.sym @@ -0,0 +1,46 @@ +# Global symbols that should handled differently when Perl 5.004 is +# compiled for binary compatibility with version 5.003. + +# Variables from "interp.sym" that _should_ be hidden. + +curcop +curcopdb +envgv +siggv +tainting + +# Variables from "global.sym" that should _not_ be hidden. + +Error +block_type +comppad_name_floor +debug +nice_chunk +nice_chunk_size +no_myglob +no_symref +no_wrongref +pad_reset_pending +padix_floor +regflags +warn_uninit + +# Functions from "global.sym" that should _not_ be hidden. + +SvIV +SvNV +SvTRUE +SvUV +boot_core_UNIVERSAL +do_undump +safecalloc +safefree +safemalloc +saferealloc +safexcalloc +safexfree +safexmalloc +safexrealloc +save_iv +sv_pvn +yydestruct diff --git a/gnu/usr.bin/perl/config.sh.OpenBSD b/gnu/usr.bin/perl/config.sh.OpenBSD index ff3c466e4fc..29a64525a16 100644 --- a/gnu/usr.bin/perl/config.sh.OpenBSD +++ b/gnu/usr.bin/perl/config.sh.OpenBSD @@ -1,13 +1,13 @@ #!/bin/sh -# $OpenBSD: config.sh.OpenBSD,v 1.10 1997/03/13 09:39:52 maja Exp $ +# $OpenBSD: config.sh.OpenBSD,v 1.11 1997/11/30 07:48:21 millert Exp $ # -# This file was produced by running the Configure script. It holds all the -# definitions figured out by Configure. Should you modify one of these values, -# do not forget to propagate your changes by running "Configure -der". You may -# instead choose to run each of the .SH files by yourself, or "Configure -S". +# This file was produced by running the Configure script. It holds all +# the definitions figured out by Configure. Should you modify any of +# these values, do not forget to propagate your changes by running +# "Configure -S"; or, equivalently, you may run each .SH file yourself. # -# Configuration time: Sun Aug 18 18:11:40 PDT 1996 +# Configuration time: Tue Nov 25 19:39:46 MST 1997 # Configured by: root # Target system: openbsd @@ -38,8 +38,8 @@ afs='false' alignbytes='' aphostname='' ar='ar' -archlib="/usr/lib/perl5/`arch |cut -f2 -d.`-openbsd/5.003" -archlibexp="/usr/lib/perl5/`arch |cut -f2 -d.`-openbsd/5.003" +archlib="/usr/lib/perl5/`arch |cut -f2 -d.`-openbsd/5.00404" +archlibexp="/usr/lib/perl5/`arch |cut -f2 -d.`-openbsd/5.00404" archname="`arch |cut -f2 -d.`-openbsd" archobjs='' awk='awk' @@ -54,12 +54,12 @@ c='' castflags='0' cat='cat' cc='cc' -cccdlflags='-DPIC -fpic' +cccdlflags='-DPIC -fPIC ' ccdlflags=' ' ccflags='' cf_by='root' cf_email='root@localhost' -cf_time='Sun Aug 18 18:11:40 PDT 1996' +cf_time='Tue Nov 25 19:39:46 MST 1997' chgrp='' chmod='' chown='' @@ -86,7 +86,9 @@ d_attribut='define' d_bcmp='define' d_bcopy='define' d_bsd='define' +d_bsdgetpgrp='undef' d_bsdpgrp='define' +d_bsdsetpgrp='define' d_bzero='define' d_casti32='define' d_castneg='define' @@ -105,7 +107,7 @@ d_dirnamlen='define' if [ $_dynaload -ne 0 ]; then d_dlerror='define' d_dlopen='define' - d_dlsymun='' + d_dlsymun='define' else d_dlerror='undef' d_dlopen='undef' @@ -127,16 +129,22 @@ d_flock='define' d_fork='define' d_fpathconf='define' d_fsetpos='define' +d_ftime='undef' d_getgrps='define' +d_setgrps='define' d_gethent='undef' d_gethname='undef' d_getlogin='define' +d_getpgid='define' d_getpgrp2='undef' d_getpgrp='define' d_getppid='define' d_getprior='define' +d_gettimeod='define' +d_gnulibc='undef' d_htonl='define' d_index='undef' +d_inetaton='define' d_isascii='define' d_killpg='define' d_link='define' @@ -182,6 +190,7 @@ d_rewinddir='define' d_rmdir='define' d_safebcpy='define' d_safemcpy='define' +d_sanemcmp='define' d_seekdir='define' d_select='define' d_sem='define' @@ -203,18 +212,15 @@ d_setreuid='undef' d_setrgid='undef' d_setruid='undef' d_setsid='define' +d_sfio='undef' d_shm='define' d_shmat='define' d_shmatprototype='define' d_shmctl='define' d_shmdt='define' d_shmget='define' -d_shrplib='undef' d_sigaction='define' -d_sigintrp='' d_sigsetjmp='define' -d_sigvec='define' -d_sigvectr='undef' d_socket='define' d_sockpair='define' d_statblks='define' @@ -227,6 +233,9 @@ d_strcoll='define' d_strctcpy='define' d_strerrm='strerror(e)' d_strerror='define' +d_strtod='define' +d_strtol='define' +d_strtoul='define' d_strxfrm='define' d_suidsafe='define' d_symlink='define' @@ -244,7 +253,7 @@ d_truncate='define' d_tzname='define' d_umask='define' d_uname='define' -d_vfork='undef' +d_vfork='define' d_void_closedir='undef' d_voidsig='define' d_voidtty='' @@ -263,7 +272,7 @@ direntrytype='struct dirent' if [ $_dynaload -ne 0 ]; then dlext='so' dlsrc='dl_dlopen.xs' - dynamic_ext='DB_File Fcntl FileHandle POSIX SDBM_File Safe Socket' + dynamic_ext='DB_File Fcntl IO NDBM_File Opcode POSIX SDBM_File Socket' else dlext='' dlsrc='dl_none.xs' @@ -276,7 +285,7 @@ emacs='' eunicefix=':' exe_ext='' expr='expr' -extensions='DB_File Fcntl FileHandle POSIX SDBM_File Safe Socket' +extensions='DB_File Fcntl IO NDBM_File Opcode POSIX SDBM_File Socket' find='find' firstmakefile='makefile' flex='' @@ -287,7 +296,7 @@ full_sed='/usr/bin/sed' gcc='' gccversion='2.7.2.1' gidtype='gid_t' -glibpth='/usr/shlib /lib/pa1.1 /usr/lib/large /lib /usr/lib /usr/lib/386 /lib/386 /lib/large /usr/lib/small /lib/small /usr/ccs/lib /usr/ucblib /usr/shlib ' +glibpth='/usr/shlib /shlib /usr/lib/pa1.1 /usr/lib/large /lib /usr/lib /usr/lib/386 /lib/386 /lib/large /usr/lib/small /lib/small /usr/ccs/lib /usr/ucblib ' grep='grep' groupcat='' groupstype='gid_t' @@ -320,6 +329,7 @@ i_neterrno='undef' i_niin='define' i_pwd='define' i_rpcsvcdbm='undef' +i_sfio='undef' i_sgtty='undef' i_stdarg='define' i_stddef='define' @@ -332,6 +342,7 @@ i_sysin='undef' i_sysioctl='define' i_sysndir='undef' i_sysparam='define' +i_sysresrc='define' i_sysselct='define' i_syssockio='' i_sysstat='define' @@ -340,17 +351,19 @@ i_systimek='undef' i_systimes='define' i_systypes='define' i_sysun='define' +i_syswait='define' i_termio='undef' i_termios='define' i_time='undef' i_unistd='define' i_utime='define' i_varargs='undef' +i_values='undef' i_varhdr='stdarg.h' i_vfork='undef' incpath='' inews='' -installarchlib="/usr/lib/perl5/`arch |cut -f2 -d.`-openbsd/5.003" +installarchlib="/usr/lib/perl5/`arch |cut -f2 -d.`-openbsd/5.00404" installbin='/usr/bin' installman1dir='' installman3dir='' @@ -359,7 +372,7 @@ installscript='/usr/bin' installsitearch="/usr/lib/perl5/site_perl/`arch |cut -f2 -d.`-openbsd" installsitelib='/usr/lib/perl5/site_perl' intsize='4' -known_extensions='DB_File Fcntl FileHandle GDBM_File NDBM_File ODBM_File POSIX SDBM_File Safe Socket' +known_extensions='DB_File Fcntl GDBM_File IO NDBM_File ODBM_File Opcode POSIX SDBM_File Socket' ksh='' large='' ld='ld' @@ -367,10 +380,11 @@ lddlflags='-Bforcearchive -Bshareable ' ldflags='' less='less' lib_ext='.a' -libc='/usr/lib/libc.so.12.6' +libc='/usr/lib/libc.a' +libperl='libperl.a' libpth='/usr/lib' libs='-lm -lc' -libswanted='net socket inet nsl nm ndbm gdbm dbm db malloc dl dld ld sun m c cposix posix ndir dir crypt ucb bsd BSD PW x' +libswanted='sfio net socket inet nsl nm ndbm gdbm dbm db malloc dl dld ld sun m c cposix posix ndir dir crypt ucb bsd BSD PW x' line='line' lint='' lkflags='' @@ -378,13 +392,20 @@ ln='ln' lns='/bin/ln -s' locincpth='' loclibpth='' + +case "`arch |cut -f2 -d.`" in +"alpha") longsize='8';; +*) longsize='4';; +esac + lp='' lpr='' ls='ls' lseektype='off_t' mail='' mailx='' -make='' +make='/usr/bin/make' +make_set_make='#' mallocobj='' mallocsrc='' malloctype='void *' @@ -419,9 +440,9 @@ orderlib='false' osname='openbsd' osvers="`uname -r`" package='perl5' -pager='/usr/bin/more' +pager='/usr/bin/less' passcat='' -patchlevel='3' +patchlevel='4' path_sep=':' perl='perl' perladmin='root@localhost' @@ -447,11 +468,12 @@ scriptdirexp='/usr/bin' sed='sed' selecttype='fd_set *' sendmail='sendmail' -sh='' +sh='/bin/sh' shar='' sharpbang='#!' shmattype='char *' -shrpdir='none' +shortsize='2' +shrpenv='' shsharp='true' sig_name='ZERO HUP INT QUIT ILL TRAP ABRT EMT FPE KILL BUS SEGV SYS PIPE ALRM TERM URG STOP TSTP CONT CHLD TTIN TTOU IO XCPU XFSZ VTALRM PROF WINCH INFO USR1 USR2 IOT ' sig_num='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 6 ' @@ -482,8 +504,8 @@ stdio_cnt='((fp)->_cnt)' stdio_ptr='((fp)->_ptr)' strings='/usr/include/string.h' submit='' -subversion='0' -sysman='/usr/man/man1' +subversion='4' +sysman='/usr/share/man/man1' tail='' tar='' tbl='' @@ -504,17 +526,17 @@ fi usemymalloc='n' usenm='true' useposix='true' -usesafe='true' -usevfork='false' +usesfio='false' +useshrplib='false' +usevfork='true' usrinc='/usr/include' uuname='' vi='' voidflags='15' xlibpth='' zcat='' -PATCHLEVEL=3 -SUBVERSION=0 -LOCAL_PATCH_COUNT=\ +PATCHLEVEL=4 +SUBVERSION=4 CONFIG=true # Variables propagated from previous config.sh file. pp_sys_cflags='ccflags="$ccflags -DHAS_TELLDIR_PROTOTYPE"' diff --git a/gnu/usr.bin/perl/config_H b/gnu/usr.bin/perl/config_H index f0cd0cacfab..8d320cb5e10 100644 --- a/gnu/usr.bin/perl/config_H +++ b/gnu/usr.bin/perl/config_H @@ -11,12 +11,12 @@ * that running config_h.SH again will wipe out any changes you've made. * For a more permanent change edit config.sh and rerun config_h.SH. * - * $Id: config_H,v 1.1 1996/08/19 10:11:36 downsj Exp $ + * $Id: config_H,v 1.2 1997/11/30 07:48:22 millert Exp $ */ -/* Configuration time: Mon Mar 18 23:11:24 EST 1996 - * Configured by: bailey - * Target system: sunos agave.humgen.upenn.edu 5.4 generic_101945-13 sun4m sparc +/* Configuration time: Wed Sep 11 15:24:25 EDT 1996 + * Configured by: doughera + * Target system: sunos fractal 5.5 generic i86pc i386 i86pc */ #ifndef _config_h_ @@ -28,15 +28,31 @@ */ #define MEM_ALIGNBYTES 4 /**/ +/* ARCHNAME: + * This symbol holds a string representing the architecture name. + * It may be used to construct an architecture-dependant pathname + * where library files may be held under a private library, for + * instance. + */ +#define ARCHNAME "unknown" /**/ + /* BIN: * This symbol holds the path of the bin directory where the package will * be installed. Program must be prepared to deal with ~name substitution. */ -#define BIN "/usr/local/bin" /**/ +/* BIN_EXP: + * 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 "/opt/perl/bin" /**/ +#define BIN_EXP "/opt/perl/bin" /**/ /* CAT2: * This macro catenates 2 tokens together. */ +/* STRINGIFY: + * This macro surrounds its token with double quotes. + */ #if 42 == 1 #define CAT2(a,b)a/**/b #define CAT3(a,b,c)a/**/b/**/c @@ -86,7 +102,7 @@ * This symbol indicates the C compiler can check for function attributes, * such as printf formats. This is normally only supported by GNU cc. */ -/*#define HASATTRIBUTE /**/ +/*#define HASATTRIBUTE / **/ #ifndef HASATTRIBUTE #define __attribute__(_arg_) #endif @@ -95,19 +111,19 @@ * This symbol is defined if the bcmp() routine is available to * compare blocks of memory. */ -/*#define HAS_BCMP /**/ +#define HAS_BCMP /**/ /* HAS_BCOPY: * This symbol is defined if the bcopy() routine is available to * copy blocks of memory. */ -/*#define HAS_BCOPY /**/ +#define HAS_BCOPY /**/ /* HAS_BZERO: * This symbol is defined if the bzero() routine is available to * set a memory block to 0. */ -/*#define HAS_BZERO /**/ +#define HAS_BZERO /**/ /* CASTI32: * This symbol is defined if the C compiler can cast negative @@ -146,13 +162,13 @@ * This symbol, if defined, indicates that the chsize routine is available * to truncate files. You might need a -lx to get this routine. */ -/*#define HAS_CHSIZE /**/ +/*#define HAS_CHSIZE / **/ /* VOID_CLOSEDIR: * This symbol, if defined, indicates that the closedir() routine * does not return a value. */ -/*#define VOID_CLOSEDIR /**/ +/*#define VOID_CLOSEDIR / **/ /* HASCONST: * This symbol, if defined, indicates that this C compiler knows about @@ -238,7 +254,7 @@ * This symbol, if defined, indicates that the flock routine is * available to do file locking. */ -/*#define HAS_FLOCK /**/ +/*#define HAS_FLOCK / **/ /* HAS_FORK: * This symbol, if defined, indicates that the fork routine is @@ -252,12 +268,29 @@ */ #define HAS_FSETPOS /**/ +/* HAS_GETTIMEOFDAY: + * This symbol, if defined, indicates that the gettimeofday() system + * call is available for a sub-second accuracy clock. Usually, the file + * <sys/resource.h> needs to be included (see I_SYS_RESOURCE). + * The type "Timeval" should be used to refer to "struct timeval". + */ +/*#define HAS_GETTIMEOFDAY / **/ +#ifdef HAS_GETTIMEOFDAY +#define Timeval struct timeval /* Structure used by gettimeofday() */ +#endif + /* HAS_GETGROUPS: * This symbol, if defined, indicates that the getgroups() routine is * available to get the list of process groups. If unavailable, multiple * groups are probably not supported. */ +/* HAS_SETGROUPS: + * This symbol, if defined, indicates that the setgroups() routine is + * available to set the list of process groups. If unavailable, multiple + * groups are probably not supported. + */ #define HAS_GETGROUPS /**/ +#define HAS_SETGROUPS /**/ /* HAS_GETHOSTENT: * This symbol, if defined, indicates that the gethostent routine is @@ -278,17 +311,11 @@ */ #define HAS_GETLOGIN /**/ -/* HAS_GETPGRP: - * This symbol, if defined, indicates that the getpgrp routine is - * available to get the current process group. - */ -#define HAS_GETPGRP /**/ - /* HAS_GETPGRP2: * This symbol, if defined, indicates that the getpgrp2() (as in DG/UX) * routine is available to get the current process group. */ -/*#define HAS_GETPGRP2 /**/ +/*#define HAS_GETPGRP2 / **/ /* HAS_GETPPID: * This symbol, if defined, indicates that the getppid routine is @@ -300,7 +327,7 @@ * This symbol, if defined, indicates that the getpriority routine is * available to get a process's priority. */ -/*#define HAS_GETPRIORITY /**/ +#define HAS_GETPRIORITY /**/ /* HAS_HTONL: * This symbol, if defined, indicates that the htonl() routine (and @@ -338,7 +365,7 @@ * to kill process groups. If unavailable, you probably should use kill * with a negative process number. */ -/*#define HAS_KILLPG /**/ +#define HAS_KILLPG /**/ /* HAS_LINK: * This symbol, if defined, indicates that the link routine is @@ -529,7 +556,7 @@ * probably use memmove() or memcpy(). If neither is defined, roll your * own version. */ -/*#define HAS_SAFE_BCOPY /**/ +#define HAS_SAFE_BCOPY /**/ /* HAS_SAFE_MEMCPY: * This symbol, if defined, indicates that the memcpy routine is available @@ -537,7 +564,14 @@ * probably use memmove() or memcpy(). If neither is defined, roll your * own version. */ -/*#define HAS_SAFE_MEMCPY /**/ +/*#define HAS_SAFE_MEMCPY / **/ + +/* HAS_SANE_MEMCMP: + * This symbol, if defined, indicates that the memcmp routine is available + * and can be used to compare relative magnitudes of chars with their high + * bits set. If it is not defined, roll your own version. + */ +/*#define HAS_SANE_MEMCMP / **/ /* HAS_SELECT: * This symbol, if defined, indicates that the select routine is @@ -569,7 +603,7 @@ * available to change stderr or stdout from block-buffered or unbuffered * to a line-buffered mode. */ -/*#define HAS_SETLINEBUF /**/ +#define HAS_SETLINEBUF /**/ /* HAS_SETLOCALE: * This symbol, if defined, indicates that the setlocale routine is @@ -577,35 +611,17 @@ */ #define HAS_SETLOCALE /**/ -/* HAS_SETPGID: - * This symbol, if defined, indicates that the setpgid routine is - * available to set process group ID. - */ -#define HAS_SETPGID /**/ - -/* HAS_SETPGRP: - * This symbol, if defined, indicates that the setpgrp routine is - * available to set the current process group. - */ -/* USE_BSDPGRP: - * This symbol, if defined, indicates that the BSD notion of process - * group is to be used. For instance, you have to say setpgrp(pid, pgrp) - * instead of the USG setpgrp(). - */ -#define HAS_SETPGRP /**/ -/*#define USE_BSDPGRP /**/ - /* HAS_SETPGRP2: * This symbol, if defined, indicates that the setpgrp2() (as in DG/UX) * routine is available to set the current process group. */ -/*#define HAS_SETPGRP2 /**/ +/*#define HAS_SETPGRP2 / **/ /* HAS_SETPRIORITY: * This symbol, if defined, indicates that the setpriority routine is * available to set a process's priority. */ -/*#define HAS_SETPRIORITY /**/ +#define HAS_SETPRIORITY /**/ /* HAS_SETREGID: * This symbol, if defined, indicates that the setregid routine is @@ -617,8 +633,8 @@ * available to change the real, effective and saved gid of the current * process. */ -/*#define HAS_SETREGID /**/ -/*#define HAS_SETRESGID /**/ +#define HAS_SETREGID /**/ +/*#define HAS_SETRESGID / **/ /* HAS_SETREUID: * This symbol, if defined, indicates that the setreuid routine is @@ -630,20 +646,20 @@ * available to change the real, effective and saved uid of the current * process. */ -/*#define HAS_SETREUID /**/ -/*#define HAS_SETRESUID /**/ +#define HAS_SETREUID /**/ +/*#define HAS_SETRESUID / **/ /* HAS_SETRGID: * This symbol, if defined, indicates that the setrgid routine is available * to change the real gid of the current program. */ -/*#define HAS_SETRGID /**/ +/*#define HAS_SETRGID / **/ /* HAS_SETRUID: * This symbol, if defined, indicates that the setruid routine is available * to change the real uid of the current program. */ -/*#define HAS_SETRUID /**/ +/*#define HAS_SETRUID / **/ /* HAS_SETSID: * This symbol, if defined, indicates that the setsid routine is @@ -701,18 +717,6 @@ * and FILE_cnt(fp) macros will also be defined and should be used * to access these fields. */ -/* USE_STDIO_BASE: - * This symbol is defined if the _base field (or similar) of the - * stdio FILE structure can be used to access the stdio buffer for - * a file handle. If this is defined, then the FILE_base(fp) macro - * will also be defined and should be used to access this field. - * Also, the FILE_bufsiz(fp) macro will be defined and should be used - * to determine the number of bytes in the buffer. USE_STDIO_BASE - * will never be defined unless USE_STDIO_PTR is. - */ -#define USE_STDIO_PTR /**/ -#define USE_STDIO_BASE /**/ - /* FILE_ptr: * This macro is used to access the _ptr field (or equivalent) of the * FILE structure pointed to by its argument. This macro will always be @@ -731,6 +735,7 @@ * This symbol is defined if the FILE_cnt macro can be used as an * lvalue. */ +#define USE_STDIO_PTR /**/ #ifdef USE_STDIO_PTR #define FILE_ptr(fp) ((fp)->_ptr) #define STDIO_PTR_LVALUE /**/ @@ -738,6 +743,15 @@ #define STDIO_CNT_LVALUE /**/ #endif +/* USE_STDIO_BASE: + * This symbol is defined if the _base field (or similar) of the + * stdio FILE structure can be used to access the stdio buffer for + * a file handle. If this is defined, then the FILE_base(fp) macro + * will also be defined and should be used to access this field. + * Also, the FILE_bufsiz(fp) macro will be defined and should be used + * to determine the number of bytes in the buffer. USE_STDIO_BASE + * will never be defined unless USE_STDIO_PTR is. + */ /* FILE_base: * This macro is used to access the _base field (or equivalent) of the * FILE structure pointed to by its argument. This macro will always be @@ -749,6 +763,7 @@ * structure pointed to its argument. This macro will always be defined * if USE_STDIO_BASE is defined. */ +#define USE_STDIO_BASE /**/ #ifdef USE_STDIO_BASE #define FILE_base(fp) ((fp)->_base) #define FILE_bufsiz(fp) ((fp)->_cnt + (fp)->_ptr - (fp)->_base) @@ -764,7 +779,7 @@ * functions are available for string searching. */ #define HAS_STRCHR /**/ -/*#define HAS_INDEX /**/ +/*#define HAS_INDEX / **/ /* HAS_STRCOLL: * This symbol, if defined, indicates that the strcoll routine is @@ -798,6 +813,24 @@ #define HAS_SYS_ERRLIST /**/ #define Strerror(e) strerror(e) +/* HAS_STRTOD: + * This symbol, if defined, indicates that the strtod routine is + * available to provide better numeric string conversion than atof(). + */ +#define HAS_STRTOD /**/ + +/* HAS_STRTOL: + * This symbol, if defined, indicates that the strtol routine is available + * to provide better numeric string conversion than atoi() and friends. + */ +#define HAS_STRTOL /**/ + +/* HAS_STRTOUL: + * This symbol, if defined, indicates that the strtoul routine is + * available to provide conversion of strings to unsigned long. + */ +#define HAS_STRTOUL /**/ + /* HAS_STRXFRM: * This symbol, if defined, indicates that the strxfrm() routine is * available to transform strings. @@ -875,7 +908,7 @@ /* HAS_VFORK: * This symbol, if defined, indicates that vfork() exists. */ -/*#define HAS_VFORK /**/ +/*#define HAS_VFORK / **/ /* Signal_t: * This symbol's value is either "void" or "int", corresponding to the @@ -906,12 +939,12 @@ * symbol. */ #define HAS_VPRINTF /**/ -/*#define USE_CHAR_VSPRINTF /**/ +/*#define USE_CHAR_VSPRINTF / **/ /* HAS_WAIT4: * This symbol, if defined, indicates that wait4() exists. */ -/*#define HAS_WAIT4 /**/ +#define HAS_WAIT4 /**/ /* HAS_WAITPID: * This symbol, if defined, indicates that the waitpid routine is @@ -949,14 +982,14 @@ /* Groups_t: * This symbol holds the type used for the second argument to - * getgroups(). Usually, this is the same of gidtype, but + * [gs]etgroups(). Usually, this is the same of gidtype, but * sometimes it isn't. It can be int, ushort, uid_t, etc... * It may be necessary to include <sys/types.h> to get any * typedef'ed information. This is only required if you have - * getgroups(). + * getgroups() or setgroups(). */ -#ifdef HAS_GETGROUPS -#define Groups_t gid_t /* Type for 2nd arg to getgroups() */ +#if defined(HAS_GETGROUPS) || defined(HAS_SETGROUPS) +#define Groups_t gid_t /* Type for 2nd arg to [gs]etgroups() */ #endif /* DB_Prefix_t: @@ -989,7 +1022,7 @@ * portably declare your directory entries. */ #define I_DIRENT /**/ -/*#define DIRNAMLEN /**/ +/*#define DIRNAMLEN / **/ #define Direntry_t struct dirent /* I_DLFCN: @@ -1033,7 +1066,7 @@ * This symbol, if defined, indicates to the C program that it should * include <memory.h>. */ -/*#define I_MEMORY /**/ +/*#define I_MEMORY / **/ /* I_NDBM: * This symbol, if defined, indicates that <ndbm.h> exists and should @@ -1045,7 +1078,7 @@ * This symbol, if defined, indicates that <net/errno.h> exists and * should be included. */ -/*#define I_NET_ERRNO /**/ +/*#define I_NET_ERRNO / **/ /* I_NETINET_IN: * This symbol, if defined, indicates to the C program that it should @@ -1082,11 +1115,11 @@ * contains pw_comment. */ #define I_PWD /**/ -/*#define PWQUOTA /**/ +/*#define PWQUOTA / **/ #define PWAGE /**/ -/*#define PWCHANGE /**/ -/*#define PWCLASS /**/ -/*#define PWEXPIRE /**/ +/*#define PWCHANGE / **/ +/*#define PWCLASS / **/ +/*#define PWEXPIRE / **/ #define PWCOMMENT /**/ /* I_STDDEF: @@ -1111,13 +1144,13 @@ * This symbol, if defined, indicates to the C program that it should * include <sys/dir.h>. */ -/*#define I_SYS_DIR /**/ +/*#define I_SYS_DIR / **/ /* I_SYS_FILE: * This symbol, if defined, indicates to the C program that it should * include <sys/file.h> to get definition of R_OK and friends. */ -/*#define I_SYS_FILE /**/ +/*#define I_SYS_FILE / **/ /* I_SYS_IOCTL: * This symbol, if defined, indicates that <sys/ioctl.h> exists and should @@ -1129,7 +1162,7 @@ * This symbol, if defined, indicates to the C program that it should * include <sys/ndir.h>. */ -/*#define I_SYS_NDIR /**/ +/*#define I_SYS_NDIR / **/ /* I_SYS_PARAM: * This symbol, if defined, indicates to the C program that it should @@ -1137,6 +1170,12 @@ */ #define I_SYS_PARAM /**/ +/* I_SYS_RESOURCE: + * This symbol, if defined, indicates to the C program that it should + * include <sys/resource.h>. + */ +#define I_SYS_RESOURCE /**/ + /* I_SYS_SELECT: * This symbol, if defined, indicates to the C program that it should * include <sys/select.h> in order to get definition of struct timeval. @@ -1161,6 +1200,12 @@ */ #define I_SYS_UN /**/ +/* I_SYS_WAIT: + * This symbol, if defined, indicates to the C program that it should + * include <sys/wait.h>. + */ +#define I_SYS_WAIT /**/ + /* I_TERMIO: * This symbol, if defined, indicates that the program should include * <termio.h> rather than <sgtty.h>. There are also differences in @@ -1177,9 +1222,9 @@ * <sgtty.h> rather than <termio.h>. There are also differences in * the ioctl() calls that depend on the value of this symbol. */ -/*#define I_TERMIO /**/ +/*#define I_TERMIO / **/ #define I_TERMIOS /**/ -/*#define I_SGTTY /**/ +/*#define I_SGTTY / **/ /* I_TIME: * This symbol, if defined, indicates to the C program that it should @@ -1193,9 +1238,9 @@ * This symbol, if defined, indicates to the C program that it should * include <sys/time.h> with KERNEL defined. */ -/*#define I_TIME /**/ +/*#define I_TIME / **/ #define I_SYS_TIME /**/ -/*#define I_SYS_TIME_KERNEL /**/ +/*#define I_SYS_TIME_KERNEL / **/ /* I_UNISTD: * This symbol, if defined, indicates to the C program that it should @@ -1209,11 +1254,38 @@ */ #define I_UTIME /**/ +/* I_STDARG: + * This symbol, if defined, indicates that <stdarg.h> exists and should + * be included. + */ +/* I_VARARGS: + * This symbol, if defined, indicates to the C program that it should + * include <varargs.h>. + */ +#define I_STDARG /**/ +/*#define I_VARARGS / **/ + /* I_VFORK: * This symbol, if defined, indicates to the C program that it should * include vfork.h. */ -/*#define I_VFORK /**/ +/*#define I_VFORK / **/ + +/* INTSIZE: + * This symbol contains the value of sizeof(int) so that the C + * preprocessor can make decisions based on it. + */ +/* LONGSIZE: + * This symbol contains the value of sizeof(long) so that the C + * preprocessor can make decisions based on it. + */ +/* SHORTSIZE: + * This symbol contains the value of sizeof(short) so that the C + * preprocessor can make decisions based on it. + */ +#define INTSIZE 4 /**/ +#define LONGSIZE 4 /**/ +#define SHORTSIZE 2 /**/ /* Off_t: * This symbol holds the type used to declare offsets in the kernel. @@ -1230,6 +1302,33 @@ */ #define Mode_t mode_t /* file mode parameter for system calls */ +/* VAL_O_NONBLOCK: + * This symbol is to be used during open() or fcntl(F_SETFL) to turn on + * non-blocking I/O for the file descriptor. Note that there is no way + * back, i.e. you cannot turn it blocking again this way. If you wish to + * alternatively switch between blocking and non-blocking, use the + * ioctl(FIOSNBIO) call instead, but that is not supported by all devices. + */ +/* VAL_EAGAIN: + * This symbol holds the errno error code set by read() when no data was + * present on the non-blocking file descriptor. + */ +/* RD_NODATA: + * This symbol holds the return code from read() when no data is present + * on the non-blocking file descriptor. Be careful! If EOF_NONBLOCK is + * not defined, then you can't distinguish between no data and EOF by + * issuing a read(). You'll have to find another way to tell for sure! + */ +/* EOF_NONBLOCK: + * This symbol, if defined, indicates to the C program that a read() on + * a non-blocking file descriptor will return 0 on EOF, and not the value + * held in RD_NODATA (-1 usually, in that case!). + */ +#define VAL_O_NONBLOCK O_NONBLOCK +#define VAL_EAGAIN EAGAIN +#define RD_NODATA -1 +#define EOF_NONBLOCK + /* CAN_PROTOTYPE: * If defined, this macro indicates that the C compiler can handle * function prototypes. @@ -1254,14 +1353,6 @@ */ #define RANDBITS 15 /**/ -/* SCRIPTDIR: - * This symbol holds the name of the directory in which the user wants - * to put publicly executable scripts for the package in question. It - * is often a directory that is mounted across diverse architectures. - * Programs must be prepared to deal with ~name expansion. - */ -#define SCRIPTDIR "/usr/local/script" /**/ - /* Select_fd_set_t: * This symbol holds the type used for the 2nd, 3rd, and 4th * arguments to select. Usually, this is 'fd_set *', if HAS_FD_SET @@ -1301,34 +1392,62 @@ */ #define Uid_t uid_t /* UID type */ -/* VMS: - * This symbol, if defined, indicates that the program is running under - * VMS. It is currently only set in conjunction with the EUNICE symbol. - */ -/*#define VMS /**/ - /* LOC_SED: * This symbol holds the complete pathname to the sed program. */ #define LOC_SED "/bin/sed" /**/ +/* OSNAME: + * This symbol contains the name of the operating system, as determined + * by Configure. You shouldn't rely on it too much; the specific + * feature tests from Configure are generally more reliable. + */ +#define OSNAME "solaris" /**/ + +/* ARCHLIB: + * This variable, if defined, holds the name of the directory in + * which the user wants to put architecture-dependent public + * library files for perl5. It is most often a local directory + * such as /usr/local/lib. Programs using this variable must be + * prepared to deal with filename expansion. If ARCHLIB is the + * same as PRIVLIB, it is not defined, since presumably the + * program already searches PRIVLIB. + */ /* ARCHLIB_EXP: * 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_EXP "/usr/local/lib/perl5/i86pc-solaris/5.002" /**/ +#define ARCHLIB "/opt/perl/lib/i86pc-solaris/5.00305" /**/ +#define ARCHLIB_EXP "/opt/perl/lib/i86pc-solaris/5.00305" /**/ -/* OSNAME: - * This symbol contains the name of the operating system, as determined - * by Configure. +/* BINCOMPAT3: + * This symbol, if defined, indicates that Perl 5.004 should be + * binary-compatible with Perl 5.003. */ -#define OSNAME "solaris" /**/ +#define BINCOMPAT3 /**/ /* BYTEORDER: - * This symbol hold the hexadecimal constant defined in byteorder, + * This symbol holds the hexadecimal constant defined in byteorder, * i.e. 0x1234 or 0x4321, etc... - */ + * On NeXT 4 (and greater), you can build "Fat" Multiple Architecture + * Binaries (MAB) on either big endian or little endian machines. + * The endian-ness is available at compile-time. This only matters + * for perl, where the config.h can be generated and installed on + * one system, and used by a different architecture to build an + * extension. Older versions of NeXT that might not have + * defined either *_ENDIAN__ were all on Motorola 680x0 series, + * so the default case (for NeXT) is big endian to catch them. + * This might matter for NeXT 3.0. + */ +#ifndef NeXT #define BYTEORDER 0x1234 /* large digits for MSB */ +#else /* NeXT */ +#ifdef __LITTLE_ENDIAN__ +#define BYTEORDER 0x1234 +#else /* __BIG_ENDIAN__ */ +#define BYTEORDER 0x4321 +#endif /* ENDIAN CHECK */ +#endif /* NeXT */ /* CSH: * This symbol, if defined, indicates that the C-shell exists. @@ -1342,7 +1461,7 @@ * makes sense if you *have* dlsym, which we will presume is the * case if you're using dl_dlopen.xs. */ -/*#define DLSYM_NEEDS_UNDERSCORE /* */ +/*#define DLSYM_NEEDS_UNDERSCORE / **/ /* SETUID_SCRIPTS_ARE_SECURE_NOW: * This symbol, if defined, indicates that the bug that prevents @@ -1362,7 +1481,7 @@ * file descriptor of the script to be executed. */ #define SETUID_SCRIPTS_ARE_SECURE_NOW /**/ -/*#define DOSUID /**/ +/*#define DOSUID / **/ /* Gconvert: * This preprocessor macro is defined to convert a floating point @@ -1381,26 +1500,85 @@ */ #define Gconvert(x,n,t,b) gconvert((x),(n),(t),(b)) +/* HAS_GETPGID: + * This symbol, if defined, indicates to the C program that + * the getpgid(pid) function is available to get the + * process group id. + */ +#define HAS_GETPGID /**/ + +/* HAS_GETPGRP: + * This symbol, if defined, indicates that the getpgrp routine is + * available to get the current process group. + */ +/* USE_BSD_GETPGRP: + * This symbol, if defined, indicates that getpgrp needs one + * arguments whereas USG one needs none. + */ +#define HAS_GETPGRP /**/ +/*#define USE_BSD_GETPGRP / **/ + +/* HAS_INET_ATON: + * This symbol, if defined, indicates to the C program that the + * inet_aton() function is available to parse IP address "dotted-quad" + * strings. + */ +#define HAS_INET_ATON /**/ + +/* HAS_SETPGID: + * This symbol, if defined, indicates to the C program that + * the setpgid(pid, gpid) function is available to set the + * process group id. + */ +#define HAS_SETPGID /**/ + +/* HAS_SETPGRP: + * This symbol, if defined, indicates that the setpgrp routine is + * available to set the current process group. + */ +/* USE_BSD_SETPGRP: + * This symbol, if defined, indicates that setpgrp needs two + * arguments whereas USG one needs none. See also HAS_SETPGID + * for a POSIX interface. + */ +/* USE_BSDPGRP: + * This symbol, if defined, indicates that the BSD notion of process + * group is to be used. For instance, you have to say setpgrp(pid, pgrp) + * instead of the USG setpgrp(). This should be obsolete since + * there are systems which have BSD-ish setpgrp but USG-ish getpgrp. + */ +#define HAS_SETPGRP /**/ +/*#define USE_BSD_SETPGRP / **/ +/*#define USE_BSDPGRP / **/ + +/* USE_SFIO: + * This symbol, if defined, indicates that sfio should + * be used. + */ +/*#define USE_SFIO / **/ + /* Sigjmp_buf: - * This is the buffer type to be used with Sigsetjmp and Siglongjmp. + * This is the buffer type to be used with Sigsetjmp and Siglongjmp. */ /* Sigsetjmp: - * This macro is used in the same way as sigsetjmp(), but will invoke - * traditional setjmp() if sigsetjmp isn't available. + * This macro is used in the same way as sigsetjmp(), but will invoke + * traditional setjmp() if sigsetjmp isn't available. + * See HAS_SIGSETJMP. */ /* Siglongjmp: - * This macro is used in the same way as siglongjmp(), but will invoke - * traditional longjmp() if siglongjmp isn't available. + * This macro is used in the same way as siglongjmp(), but will invoke + * traditional longjmp() if siglongjmp isn't available. + * See HAS_SIGSETJMP. */ #define HAS_SIGSETJMP /**/ #ifdef HAS_SIGSETJMP #define Sigjmp_buf sigjmp_buf -#define Sigsetjmp(buf,save_mask) sigsetjmp(buf,save_mask) -#define Siglongjmp(buf,retval) siglongjmp(buf,retval) +#define Sigsetjmp(buf,save_mask) sigsetjmp((buf),(save_mask)) +#define Siglongjmp(buf,retval) siglongjmp((buf),(retval)) #else #define Sigjmp_buf jmp_buf -#define Sigsetjmp(buf,save_mask) setjmp(buf) -#define Siglongjmp(buf,retval) longjmp(buf,retval) +#define Sigsetjmp(buf,save_mask) setjmp((buf)) +#define Siglongjmp(buf,retval) longjmp((buf),(retval)) #endif /* USE_DYNAMIC_LOADING: @@ -1417,7 +1595,7 @@ * This symbol, if defined, indicates that <rpcsvc/dbm.h> exists and * should be included. */ -/*#define I_DBM /**/ +/*#define I_DBM / **/ #define I_RPCSVC_DBM /**/ /* I_LOCALE: @@ -1426,28 +1604,25 @@ */ #define I_LOCALE /**/ +/* I_SFIO: + * This symbol, if defined, indicates to the C program that it should + * include <sfio.h>. + */ +/*#define I_SFIO / **/ + /* I_SYS_STAT: * This symbol, if defined, indicates to the C program that it should * include <sys/stat.h>. */ #define I_SYS_STAT /**/ -/* I_STDARG: - * This symbol, if defined, indicates that <stdarg.h> exists and should - * be included. - */ -/* I_VARARGS: +/* I_VALUES: * This symbol, if defined, indicates to the C program that it should - * include <varargs.h>. + * include <values.h> to get definition of symbols like MINFLOAT or + * MAXLONG, i.e. machine dependant limitations. Probably, you + * should use <limits.h> instead, if it is available. */ -#define I_STDARG /**/ -/*#define I_VARARGS /**/ - -/* INTSIZE: - * This symbol contains the size of an int, so that the C preprocessor - * can make decisions based on it. - */ -#define INTSIZE 4 /**/ +#define I_VALUES /**/ /* Free_t: * This variable contains the return type of free(). It is usually @@ -1464,45 +1639,42 @@ */ #define MYMALLOC /**/ -/* VAL_O_NONBLOCK: - * This symbol is to be used during open() or fcntl(F_SETFL) to turn on - * non-blocking I/O for the file descriptor. Note that there is no way - * back, i.e. you cannot turn it blocking again this way. If you wish to - * alternatively switch between blocking and non-blocking, use the - * ioctl(FIOSNBIO) call instead, but that is not supported by all devices. +/* OLDARCHLIB: + * This variable, if defined, holds the name of the directory in + * which the user has perl5.000 or perl5.001 architecture-dependent + * public library files for perl5. For the most part, these + * files will work with 5.002 (and later), but that is not + * guaranteed. */ -/* VAL_EAGAIN: - * This symbol holds the errno error code set by read() when no data was - * present on the non-blocking file descriptor. - */ -/* RD_NODATA: - * This symbol holds the return code from read() when no data is present - * on the non-blocking file descriptor. Be careful! If EOF_NONBLOCK is - * not defined, then you can't distinguish between no data and EOF by - * issuing a read(). You'll have to find another way to tell for sure! - */ -/* EOF_NONBLOCK: - * This symbol, if defined, indicates to the C program that a read() on - * a non-blocking file descriptor will return 0 on EOF, and not the value - * held in RD_NODATA (-1 usually, in that case!). - */ -#define VAL_O_NONBLOCK O_NONBLOCK -#define VAL_EAGAIN EAGAIN -#define RD_NODATA -1 -#define EOF_NONBLOCK - /* OLDARCHLIB_EXP: * This symbol contains the ~name expanded version of OLDARCHLIB, to be * used in programs that are not prepared to deal with ~ expansion at * run-time. */ -/*#define OLDARCHLIB_EXP "" /**/ +/*#define OLDARCHLIB "" / **/ +/*#define OLDARCHLIB_EXP "" / **/ +/* PRIVLIB: + * This symbol contains the name of the private library for this package. + * The library is private in the sense that it needn't be in anyone's + * execution path, but it should be accessible by the world. The program + * should be prepared to do ~ expansion. + */ /* PRIVLIB_EXP: * 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_EXP "/usr/local/lib/perl5" /**/ +#define PRIVLIB "/opt/perl/lib" /**/ +#define PRIVLIB_EXP "/opt/perl/lib" /**/ + +/* SH_PATH: + * This symbol contains the full pathname to the shell used on this + * on this system to execute Bourne shell scripts. Usually, this will be + * /bin/sh, though it's possible that some systems will have /bin/ksh, + * /bin/pdksh, /bin/ash, /bin/bash, or even something such as + * D:/bin/sh.exe. + */ +#define SH_PATH "/bin/sh" /**/ /* SIG_NAME: * This symbol contains a list of signal names in order of @@ -1532,27 +1704,54 @@ * The last element is 0, corresponding to the 0 at the end of * the sig_name list. */ -#define SIG_NAME "ZERO","HUP","INT","QUIT","ILL","TRAP","ABRT","EMT","FPE","KILL","BUS","SEGV","SYS","PIPE","ALRM","TERM","USR1","USR2","CHLD","PWR","WINCH","URG","IO","STOP","TSTP","CONT","TTIN","TTOU","VTALRM","PROF","XCPU","XFSZ","WAITING","LWP","FREEZE","THAW","RTMIN","NUM37","NUM38","NUM39","NUM40","NUM41","NUM42","RTMAX","IOT","CLD","POLL",0 /**/ -#define SIG_NUM 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,6,18,22,0 /**/ +#define SIG_NAME "ZERO","HUP","INT","QUIT","ILL","TRAP","ABRT","EMT","FPE","KILL","BUS","SEGV","SYS","PIPE","ALRM","TERM","USR1","USR2","CHLD","PWR","WINCH","URG","IO","STOP","TSTP","CONT","TTIN","TTOU","VTALRM","PROF","XCPU","XFSZ","WAITING","LWP","FREEZE","THAW","CANCEL","RTMIN","NUM38","NUM39","NUM40","NUM41","NUM42","NUM43","RTMAX","IOT","CLD","POLL",0 /**/ +#define SIG_NUM 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,6,18,22,0 /**/ +/* SITEARCH: + * This symbol contains the name of the private library for this package. + * The library is private in the sense that it needn't be in anyone's + * execution path, but it should be accessible by the world. The program + * should be prepared to do ~ expansion. + * The standard distribution will put nothing in this directory. + * Individual sites may place their own extensions and modules in + * this directory. + */ /* SITEARCH_EXP: * 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_EXP "/usr/local/lib/perl5/site_perl/i86pc-solaris" /**/ +#define SITEARCH "/opt/perl/lib/site_perl/i86pc-solaris" /**/ +#define SITEARCH_EXP "/opt/perl/lib/site_perl/i86pc-solaris" /**/ +/* SITELIB: + * This symbol contains the name of the private library for this package. + * The library is private in the sense that it needn't be in anyone's + * execution path, but it should be accessible by the world. The program + * should be prepared to do ~ expansion. + * The standard distribution will put nothing in this directory. + * Individual sites may place their own extensions and modules in + * this directory. + */ /* SITELIB_EXP: * This symbol contains the ~name expanded version of SITELIB, to be used * in programs that are not prepared to deal with ~ expansion at run-time. */ -#define SITELIB_EXP "/usr/local/lib/perl5/site_perl" /**/ +#define SITELIB "/opt/perl/lib/site_perl" /**/ +#define SITELIB_EXP "/opt/perl/lib/site_perl" /**/ /* STARTPERL: * This variable contains the string to put in front of a perl * script to make sure (one hopes) that it runs with perl and not * some shell. */ -#define STARTPERL "#!/usr/local/bin/perl" /**/ +#define STARTPERL "#!/opt/perl/bin/perl" /**/ + +/* USE_PERLIO: + * This symbol, if defined, indicates that the PerlIO abstraction should + * be used throughout. If not defined, stdio should be + * used in a fully backward compatible manner. + */ +/*#define USE_PERLIO / **/ /* VOIDFLAGS: * This symbol indicates how much support of the void type is given by this diff --git a/gnu/usr.bin/perl/config_h.SH b/gnu/usr.bin/perl/config_h.SH index f4ecea0faa1..cfae03ad990 100644 --- a/gnu/usr.bin/perl/config_h.SH +++ b/gnu/usr.bin/perl/config_h.SH @@ -15,7 +15,7 @@ case "$0" in */*) cd `expr X$0 : 'X\(.*\)/'` ;; esac echo "Extracting config.h (with variable substitutions)" -sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' +sed <<!GROK!THIS! >config.h -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un-def!#undef!' /* * This file was produced by running the config_h.SH script, which * gets its values from config.sh, which is generally produced by @@ -39,18 +39,51 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' /* MEM_ALIGNBYTES: * This symbol contains the number of bytes required to align a * double. Usual values are 2, 4 and 8. + * On NeXT starting with 3.2, you can build "Fat" Multiple Architecture + * Binaries (MAB) for targets with varying alignment. This only matters + * for perl, where the config.h can be generated and installed on one + * system, and used by a different architecture to build an extension. + * The default is eight, for safety. */ +#ifndef NeXT #define MEM_ALIGNBYTES $alignbytes /**/ +#else /* NeXT */ +#ifdef __m68k__ +#define MEM_ALIGNBYTES 2 +#else +#ifdef __i386__ +#define MEM_ALIGNBYTES 4 +#else /* __hppa__, __sparc__ and default for unknown architectures */ +#define MEM_ALIGNBYTES 8 +#endif /* __i386__ */ +#endif /* __m68k__ */ +#endif /* NeXT */ + +/* ARCHNAME: + * This symbol holds a string representing the architecture name. + * It may be used to construct an architecture-dependant pathname + * where library files may be held under a private library, for + * instance. + */ +#define ARCHNAME "$archname" /**/ /* BIN: * This symbol holds the path of the bin directory where the package will * be installed. Program must be prepared to deal with ~name substitution. */ +/* BIN_EXP: + * 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 "$bin" /**/ +#define BIN_EXP "$binexp" /**/ /* CAT2: * This macro catenates 2 tokens together. */ +/* STRINGIFY: + * This macro surrounds its token with double quotes. + */ #if $cpp_stuff == 1 #define CAT2(a,b)a/**/b #define CAT3(a,b,c)a/**/b/**/c @@ -266,12 +299,29 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' */ #$d_fsetpos HAS_FSETPOS /**/ +/* HAS_GETTIMEOFDAY: + * This symbol, if defined, indicates that the gettimeofday() system + * call is available for a sub-second accuracy clock. Usually, the file + * <sys/resource.h> needs to be included (see I_SYS_RESOURCE). + * The type "Timeval" should be used to refer to "struct timeval". + */ +#$d_gettimeod HAS_GETTIMEOFDAY /**/ +#ifdef HAS_GETTIMEOFDAY +#define Timeval struct timeval /* Structure used by gettimeofday() */ +#endif + /* HAS_GETGROUPS: * This symbol, if defined, indicates that the getgroups() routine is * available to get the list of process groups. If unavailable, multiple * groups are probably not supported. */ +/* HAS_SETGROUPS: + * This symbol, if defined, indicates that the setgroups() routine is + * available to set the list of process groups. If unavailable, multiple + * groups are probably not supported. + */ #$d_getgrps HAS_GETGROUPS /**/ +#$d_setgrps HAS_SETGROUPS /**/ /* HAS_GETHOSTENT: * This symbol, if defined, indicates that the gethostent routine is @@ -292,12 +342,6 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' */ #$d_getlogin HAS_GETLOGIN /**/ -/* HAS_GETPGRP: - * This symbol, if defined, indicates that the getpgrp routine is - * available to get the current process group. - */ -#$d_getpgrp HAS_GETPGRP /**/ - /* HAS_GETPGRP2: * This symbol, if defined, indicates that the getpgrp2() (as in DG/UX) * routine is available to get the current process group. @@ -553,6 +597,13 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' */ #$d_safemcpy HAS_SAFE_MEMCPY /**/ +/* HAS_SANE_MEMCMP: + * This symbol, if defined, indicates that the memcmp routine is available + * and can be used to compare relative magnitudes of chars with their high + * bits set. If it is not defined, roll your own version. + */ +#$d_sanemcmp HAS_SANE_MEMCMP /**/ + /* HAS_SELECT: * This symbol, if defined, indicates that the select routine is * available to select active file descriptors. If the timeout field @@ -591,24 +642,6 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' */ #$d_setlocale HAS_SETLOCALE /**/ -/* HAS_SETPGID: - * This symbol, if defined, indicates that the setpgid routine is - * available to set process group ID. - */ -#$d_setpgid HAS_SETPGID /**/ - -/* HAS_SETPGRP: - * This symbol, if defined, indicates that the setpgrp routine is - * available to set the current process group. - */ -/* USE_BSDPGRP: - * This symbol, if defined, indicates that the BSD notion of process - * group is to be used. For instance, you have to say setpgrp(pid, pgrp) - * instead of the USG setpgrp(). - */ -#$d_setpgrp HAS_SETPGRP /**/ -#$d_bsdpgrp USE_BSDPGRP /**/ - /* HAS_SETPGRP2: * This symbol, if defined, indicates that the setpgrp2() (as in DG/UX) * routine is available to set the current process group. @@ -715,18 +748,6 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' * and FILE_cnt(fp) macros will also be defined and should be used * to access these fields. */ -/* USE_STDIO_BASE: - * This symbol is defined if the _base field (or similar) of the - * stdio FILE structure can be used to access the stdio buffer for - * a file handle. If this is defined, then the FILE_base(fp) macro - * will also be defined and should be used to access this field. - * Also, the FILE_bufsiz(fp) macro will be defined and should be used - * to determine the number of bytes in the buffer. USE_STDIO_BASE - * will never be defined unless USE_STDIO_PTR is. - */ -#$d_stdstdio USE_STDIO_PTR /**/ -#$d_stdiobase USE_STDIO_BASE /**/ - /* FILE_ptr: * This macro is used to access the _ptr field (or equivalent) of the * FILE structure pointed to by its argument. This macro will always be @@ -745,6 +766,7 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' * This symbol is defined if the FILE_cnt macro can be used as an * lvalue. */ +#$d_stdstdio USE_STDIO_PTR /**/ #ifdef USE_STDIO_PTR #define FILE_ptr(fp) $stdio_ptr #$d_stdio_ptr_lval STDIO_PTR_LVALUE /**/ @@ -752,6 +774,15 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' #$d_stdio_cnt_lval STDIO_CNT_LVALUE /**/ #endif +/* USE_STDIO_BASE: + * This symbol is defined if the _base field (or similar) of the + * stdio FILE structure can be used to access the stdio buffer for + * a file handle. If this is defined, then the FILE_base(fp) macro + * will also be defined and should be used to access this field. + * Also, the FILE_bufsiz(fp) macro will be defined and should be used + * to determine the number of bytes in the buffer. USE_STDIO_BASE + * will never be defined unless USE_STDIO_PTR is. + */ /* FILE_base: * This macro is used to access the _base field (or equivalent) of the * FILE structure pointed to by its argument. This macro will always be @@ -763,6 +794,7 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' * structure pointed to its argument. This macro will always be defined * if USE_STDIO_BASE is defined. */ +#$d_stdiobase USE_STDIO_BASE /**/ #ifdef USE_STDIO_BASE #define FILE_base(fp) $stdio_base #define FILE_bufsiz(fp) $stdio_bufsiz @@ -812,6 +844,24 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' #$d_syserrlst HAS_SYS_ERRLIST /**/ #define Strerror(e) $d_strerrm +/* HAS_STRTOD: + * This symbol, if defined, indicates that the strtod routine is + * available to provide better numeric string conversion than atof(). + */ +#$d_strtod HAS_STRTOD /**/ + +/* HAS_STRTOL: + * This symbol, if defined, indicates that the strtol routine is available + * to provide better numeric string conversion than atoi() and friends. + */ +#$d_strtol HAS_STRTOL /**/ + +/* HAS_STRTOUL: + * This symbol, if defined, indicates that the strtoul routine is + * available to provide conversion of strings to unsigned long. + */ +#$d_strtoul HAS_STRTOUL /**/ + /* HAS_STRXFRM: * This symbol, if defined, indicates that the strxfrm() routine is * available to transform strings. @@ -963,14 +1013,14 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' /* Groups_t: * This symbol holds the type used for the second argument to - * getgroups(). Usually, this is the same of gidtype, but + * [gs]etgroups(). Usually, this is the same of gidtype, but * sometimes it isn't. It can be int, ushort, uid_t, etc... * It may be necessary to include <sys/types.h> to get any * typedef'ed information. This is only required if you have - * getgroups(). + * getgroups() or setgroups(). */ -#ifdef HAS_GETGROUPS -#define Groups_t $groupstype /* Type for 2nd arg to getgroups() */ +#if defined(HAS_GETGROUPS) || defined(HAS_SETGROUPS) +#define Groups_t $groupstype /* Type for 2nd arg to [gs]etgroups() */ #endif /* DB_Prefix_t: @@ -1151,6 +1201,12 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' */ #$i_sysparam I_SYS_PARAM /**/ +/* I_SYS_RESOURCE: + * This symbol, if defined, indicates to the C program that it should + * include <sys/resource.h>. + */ +#$i_sysresrc I_SYS_RESOURCE /**/ + /* I_SYS_SELECT: * This symbol, if defined, indicates to the C program that it should * include <sys/select.h> in order to get definition of struct timeval. @@ -1175,6 +1231,12 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' */ #$i_sysun I_SYS_UN /**/ +/* I_SYS_WAIT: + * This symbol, if defined, indicates to the C program that it should + * include <sys/wait.h>. + */ +#$i_syswait I_SYS_WAIT /**/ + /* I_TERMIO: * This symbol, if defined, indicates that the program should include * <termio.h> rather than <sgtty.h>. There are also differences in @@ -1223,12 +1285,39 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' */ #$i_utime I_UTIME /**/ +/* I_STDARG: + * This symbol, if defined, indicates that <stdarg.h> exists and should + * be included. + */ +/* I_VARARGS: + * This symbol, if defined, indicates to the C program that it should + * include <varargs.h>. + */ +#$i_stdarg I_STDARG /**/ +#$i_varargs I_VARARGS /**/ + /* I_VFORK: * This symbol, if defined, indicates to the C program that it should * include vfork.h. */ #$i_vfork I_VFORK /**/ +/* INTSIZE: + * This symbol contains the value of sizeof(int) so that the C + * preprocessor can make decisions based on it. + */ +/* LONGSIZE: + * This symbol contains the value of sizeof(long) so that the C + * preprocessor can make decisions based on it. + */ +/* SHORTSIZE: + * This symbol contains the value of sizeof(short) so that the C + * preprocessor can make decisions based on it. + */ +#define INTSIZE $intsize /**/ +#define LONGSIZE $longsize /**/ +#define SHORTSIZE $shortsize /**/ + /* Off_t: * This symbol holds the type used to declare offsets in the kernel. * It can be int, long, off_t, etc... It may be necessary to include @@ -1244,6 +1333,33 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' */ #define Mode_t $modetype /* file mode parameter for system calls */ +/* VAL_O_NONBLOCK: + * This symbol is to be used during open() or fcntl(F_SETFL) to turn on + * non-blocking I/O for the file descriptor. Note that there is no way + * back, i.e. you cannot turn it blocking again this way. If you wish to + * alternatively switch between blocking and non-blocking, use the + * ioctl(FIOSNBIO) call instead, but that is not supported by all devices. + */ +/* VAL_EAGAIN: + * This symbol holds the errno error code set by read() when no data was + * present on the non-blocking file descriptor. + */ +/* RD_NODATA: + * This symbol holds the return code from read() when no data is present + * on the non-blocking file descriptor. Be careful! If EOF_NONBLOCK is + * not defined, then you can't distinguish between no data and EOF by + * issuing a read(). You'll have to find another way to tell for sure! + */ +/* EOF_NONBLOCK: + * This symbol, if defined, indicates to the C program that a read() on + * a non-blocking file descriptor will return 0 on EOF, and not the value + * held in RD_NODATA (-1 usually, in that case!). + */ +#define VAL_O_NONBLOCK $o_nonblock +#define VAL_EAGAIN $eagain +#define RD_NODATA $rd_nodata +#$d_eofnblk EOF_NONBLOCK + /* CAN_PROTOTYPE: * If defined, this macro indicates that the C compiler can handle * function prototypes. @@ -1268,14 +1384,6 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' */ #define RANDBITS $randbits /**/ -/* SCRIPTDIR: - * This symbol holds the name of the directory in which the user wants - * to put publicly executable scripts for the package in question. It - * is often a directory that is mounted across diverse architectures. - * Programs must be prepared to deal with ~name expansion. - */ -#define SCRIPTDIR "$scriptdir" /**/ - /* Select_fd_set_t: * This symbol holds the type used for the 2nd, 3rd, and 4th * arguments to select. Usually, this is 'fd_set *', if HAS_FD_SET @@ -1315,34 +1423,62 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' */ #define Uid_t $uidtype /* UID type */ -/* VMS: - * This symbol, if defined, indicates that the program is running under - * VMS. It is currently only set in conjunction with the EUNICE symbol. - */ -#$d_eunice VMS /**/ - /* LOC_SED: * This symbol holds the complete pathname to the sed program. */ #define LOC_SED "$full_sed" /**/ +/* OSNAME: + * This symbol contains the name of the operating system, as determined + * by Configure. You shouldn't rely on it too much; the specific + * feature tests from Configure are generally more reliable. + */ +#define OSNAME "$osname" /**/ + +/* ARCHLIB: + * This variable, if defined, holds the name of the directory in + * which the user wants to put architecture-dependent public + * library files for $package. It is most often a local directory + * such as /usr/local/lib. Programs using this variable must be + * prepared to deal with filename expansion. If ARCHLIB is the + * same as PRIVLIB, it is not defined, since presumably the + * program already searches PRIVLIB. + */ /* ARCHLIB_EXP: * 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. */ +#$d_archlib ARCHLIB "$archlib" /**/ #$d_archlib ARCHLIB_EXP "$archlibexp" /**/ -/* OSNAME: - * This symbol contains the name of the operating system, as determined - * by Configure. +/* BINCOMPAT3: + * This symbol, if defined, indicates that Perl 5.004 should be + * binary-compatible with Perl 5.003. */ -#define OSNAME "$osname" /**/ +#$d_bincompat3 BINCOMPAT3 /**/ /* BYTEORDER: - * This symbol hold the hexadecimal constant defined in byteorder, + * This symbol holds the hexadecimal constant defined in byteorder, * i.e. 0x1234 or 0x4321, etc... - */ + * On NeXT 3.2 (and greater), you can build "Fat" Multiple Architecture + * Binaries (MAB) on either big endian or little endian machines. + * The endian-ness is available at compile-time. This only matters + * for perl, where the config.h can be generated and installed on + * one system, and used by a different architecture to build an + * extension. Older versions of NeXT that might not have + * defined either *_ENDIAN__ were all on Motorola 680x0 series, + * so the default case (for NeXT) is big endian to catch them. + * This might matter for NeXT 3.0. + */ +#ifndef NeXT #define BYTEORDER 0x$byteorder /* large digits for MSB */ +#else /* NeXT */ +#ifdef __LITTLE_ENDIAN__ +#define BYTEORDER 0x1234 +#else /* __BIG_ENDIAN__ */ +#define BYTEORDER 0x4321 +#endif /* ENDIAN CHECK */ +#endif /* NeXT */ /* CSH: * This symbol, if defined, indicates that the C-shell exists. @@ -1356,7 +1492,7 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' * makes sense if you *have* dlsym, which we will presume is the * case if you're using dl_dlopen.xs. */ -#$d_dlsymun DLSYM_NEEDS_UNDERSCORE /* */ +#$d_dlsymun DLSYM_NEEDS_UNDERSCORE /**/ /* SETUID_SCRIPTS_ARE_SECURE_NOW: * This symbol, if defined, indicates that the bug that prevents @@ -1395,26 +1531,85 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' */ #define Gconvert(x,n,t,b) $d_Gconvert +/* HAS_GETPGID: + * This symbol, if defined, indicates to the C program that + * the getpgid(pid) function is available to get the + * process group id. + */ +#$d_getpgid HAS_GETPGID /**/ + +/* HAS_GETPGRP: + * This symbol, if defined, indicates that the getpgrp routine is + * available to get the current process group. + */ +/* USE_BSD_GETPGRP: + * This symbol, if defined, indicates that getpgrp needs one + * arguments whereas USG one needs none. + */ +#$d_getpgrp HAS_GETPGRP /**/ +#$d_bsdgetpgrp USE_BSD_GETPGRP /**/ + +/* HAS_INET_ATON: + * This symbol, if defined, indicates to the C program that the + * inet_aton() function is available to parse IP address "dotted-quad" + * strings. + */ +#$d_inetaton HAS_INET_ATON /**/ + +/* HAS_SETPGID: + * This symbol, if defined, indicates to the C program that + * the setpgid(pid, gpid) function is available to set the + * process group id. + */ +#$d_setpgid HAS_SETPGID /**/ + +/* HAS_SETPGRP: + * This symbol, if defined, indicates that the setpgrp routine is + * available to set the current process group. + */ +/* USE_BSD_SETPGRP: + * This symbol, if defined, indicates that setpgrp needs two + * arguments whereas USG one needs none. See also HAS_SETPGID + * for a POSIX interface. + */ +/* USE_BSDPGRP: + * This symbol, if defined, indicates that the BSD notion of process + * group is to be used. For instance, you have to say setpgrp(pid, pgrp) + * instead of the USG setpgrp(). This should be obsolete since + * there are systems which have BSD-ish setpgrp but USG-ish getpgrp. + */ +#$d_setpgrp HAS_SETPGRP /**/ +#$d_bsdsetpgrp USE_BSD_SETPGRP /**/ +#$d_bsdpgrp USE_BSDPGRP /**/ + +/* USE_SFIO: + * This symbol, if defined, indicates that sfio should + * be used. + */ +#$d_sfio USE_SFIO /**/ + /* Sigjmp_buf: - * This is the buffer type to be used with Sigsetjmp and Siglongjmp. + * This is the buffer type to be used with Sigsetjmp and Siglongjmp. */ /* Sigsetjmp: - * This macro is used in the same way as sigsetjmp(), but will invoke - * traditional setjmp() if sigsetjmp isn't available. + * This macro is used in the same way as sigsetjmp(), but will invoke + * traditional setjmp() if sigsetjmp isn't available. + * See HAS_SIGSETJMP. */ /* Siglongjmp: - * This macro is used in the same way as siglongjmp(), but will invoke - * traditional longjmp() if siglongjmp isn't available. + * This macro is used in the same way as siglongjmp(), but will invoke + * traditional longjmp() if siglongjmp isn't available. + * See HAS_SIGSETJMP. */ #$d_sigsetjmp HAS_SIGSETJMP /**/ #ifdef HAS_SIGSETJMP #define Sigjmp_buf sigjmp_buf -#define Sigsetjmp(buf,save_mask) sigsetjmp(buf,save_mask) -#define Siglongjmp(buf,retval) siglongjmp(buf,retval) +#define Sigsetjmp(buf,save_mask) sigsetjmp((buf),(save_mask)) +#define Siglongjmp(buf,retval) siglongjmp((buf),(retval)) #else #define Sigjmp_buf jmp_buf -#define Sigsetjmp(buf,save_mask) setjmp(buf) -#define Siglongjmp(buf,retval) longjmp(buf,retval) +#define Sigsetjmp(buf,save_mask) setjmp((buf)) +#define Siglongjmp(buf,retval) longjmp((buf),(retval)) #endif /* USE_DYNAMIC_LOADING: @@ -1440,28 +1635,25 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' */ #$i_locale I_LOCALE /**/ +/* I_SFIO: + * This symbol, if defined, indicates to the C program that it should + * include <sfio.h>. + */ +#$i_sfio I_SFIO /**/ + /* I_SYS_STAT: * This symbol, if defined, indicates to the C program that it should * include <sys/stat.h>. */ #$i_sysstat I_SYS_STAT /**/ -/* I_STDARG: - * This symbol, if defined, indicates that <stdarg.h> exists and should - * be included. - */ -/* I_VARARGS: +/* I_VALUES: * This symbol, if defined, indicates to the C program that it should - * include <varargs.h>. + * include <values.h> to get definition of symbols like MINFLOAT or + * MAXLONG, i.e. machine dependant limitations. Probably, you + * should use <limits.h> instead, if it is available. */ -#$i_stdarg I_STDARG /**/ -#$i_varargs I_VARARGS /**/ - -/* INTSIZE: - * This symbol contains the size of an int, so that the C preprocessor - * can make decisions based on it. - */ -#define INTSIZE $intsize /**/ +#$i_values I_VALUES /**/ /* Free_t: * This variable contains the return type of free(). It is usually @@ -1478,46 +1670,43 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' */ #$d_mymalloc MYMALLOC /**/ -/* VAL_O_NONBLOCK: - * This symbol is to be used during open() or fcntl(F_SETFL) to turn on - * non-blocking I/O for the file descriptor. Note that there is no way - * back, i.e. you cannot turn it blocking again this way. If you wish to - * alternatively switch between blocking and non-blocking, use the - * ioctl(FIOSNBIO) call instead, but that is not supported by all devices. - */ -/* VAL_EAGAIN: - * This symbol holds the errno error code set by read() when no data was - * present on the non-blocking file descriptor. - */ -/* RD_NODATA: - * This symbol holds the return code from read() when no data is present - * on the non-blocking file descriptor. Be careful! If EOF_NONBLOCK is - * not defined, then you can't distinguish between no data and EOF by - * issuing a read(). You'll have to find another way to tell for sure! - */ -/* EOF_NONBLOCK: - * This symbol, if defined, indicates to the C program that a read() on - * a non-blocking file descriptor will return 0 on EOF, and not the value - * held in RD_NODATA (-1 usually, in that case!). +/* OLDARCHLIB: + * This variable, if defined, holds the name of the directory in + * which the user has perl5.000 or perl5.001 architecture-dependent + * public library files for $package. For the most part, these + * files will work with 5.002 (and later), but that is not + * guaranteed. */ -#define VAL_O_NONBLOCK $o_nonblock -#define VAL_EAGAIN $eagain -#define RD_NODATA $rd_nodata -#$d_eofnblk EOF_NONBLOCK - /* OLDARCHLIB_EXP: * This symbol contains the ~name expanded version of OLDARCHLIB, to be * used in programs that are not prepared to deal with ~ expansion at * run-time. */ +#$d_oldarchlib OLDARCHLIB "$oldarchlib" /**/ #$d_oldarchlib OLDARCHLIB_EXP "$oldarchlibexp" /**/ +/* PRIVLIB: + * This symbol contains the name of the private library for this package. + * The library is private in the sense that it needn't be in anyone's + * execution path, but it should be accessible by the world. The program + * should be prepared to do ~ expansion. + */ /* PRIVLIB_EXP: * 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 "$privlib" /**/ #define PRIVLIB_EXP "$privlibexp" /**/ +/* SH_PATH: + * This symbol contains the full pathname to the shell used on this + * on this system to execute Bourne shell scripts. Usually, this will be + * /bin/sh, though it's possible that some systems will have /bin/ksh, + * /bin/pdksh, /bin/ash, /bin/bash, or even something such as + * D:/bin/sh.exe. + */ +#define SH_PATH "$sh" /**/ + /* SIG_NAME: * This symbol contains a list of signal names in order of * signal number. This is intended @@ -1549,16 +1738,36 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' #define SIG_NAME "`echo $sig_name | sed 's/ /","/g'`",0 /**/ #define SIG_NUM `echo $sig_num 0 | sed 's/ /,/g'` /**/ +/* SITEARCH: + * This symbol contains the name of the private library for this package. + * The library is private in the sense that it needn't be in anyone's + * execution path, but it should be accessible by the world. The program + * should be prepared to do ~ expansion. + * The standard distribution will put nothing in this directory. + * Individual sites may place their own extensions and modules in + * this directory. + */ /* SITEARCH_EXP: * 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 "$sitearch" /**/ #define SITEARCH_EXP "$sitearchexp" /**/ +/* SITELIB: + * This symbol contains the name of the private library for this package. + * The library is private in the sense that it needn't be in anyone's + * execution path, but it should be accessible by the world. The program + * should be prepared to do ~ expansion. + * The standard distribution will put nothing in this directory. + * Individual sites may place their own extensions and modules in + * this directory. + */ /* SITELIB_EXP: * This symbol contains the ~name expanded version of SITELIB, to be used * in programs that are not prepared to deal with ~ expansion at run-time. */ +#define SITELIB "$sitelib" /**/ #define SITELIB_EXP "$sitelibexp" /**/ /* STARTPERL: @@ -1568,6 +1777,13 @@ sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' */ #define STARTPERL "$startperl" /**/ +/* USE_PERLIO: + * This symbol, if defined, indicates that the PerlIO abstraction should + * be used throughout. If not defined, stdio should be + * used in a fully backward compatible manner. + */ +#$useperlio USE_PERLIO /**/ + /* VOIDFLAGS: * This symbol indicates how much support of the void type is given by this * compiler. What various bits mean: diff --git a/gnu/usr.bin/perl/configpm b/gnu/usr.bin/perl/configpm index af1e716be6e..0c6a9650728 100644 --- a/gnu/usr.bin/perl/configpm +++ b/gnu/usr.bin/perl/configpm @@ -6,7 +6,7 @@ $config_pm = $ARGV[0] || 'lib/Config.pm'; # list names to put first (and hence lookup fastest) @fast = qw(archname osname osvers prefix libs libpth dynamic_ext static_ext extensions dlsrc so - sig_name cc ccflags cppflags + sig_name sig_num cc ccflags cppflags privlibexp archlibexp installprivlib installarchlib sharpbang startsh shsharp ); @@ -26,7 +26,7 @@ use Exporter (); \@EXPORT_OK = qw(myconfig config_sh config_vars); \$] == $myver - or die "Perl lib version ($myver) doesn't match executable version (\$])\\n"; + or die "Perl lib version ($myver) doesn't match executable version (\$])"; # This file was created by configpm when Perl was built. Any changes # made to this file will be lost the next time perl is built. @@ -39,19 +39,23 @@ ENDOFBEG @non_v=(); @v_fast=(); @v_others=(); +$in_v = 0; while (<>) { next if m:^#!/bin/sh:; # Catch CONFIG=true and PATCHLEVEL=n line from Configure. s/^(\w+)=(true|\d+)\s*$/$1='$2'\n/; - unless (m/^(\w+)='(.*)'\s*$/){ + unless ($in_v or m/^(\w+)='(.*\n)/){ push(@non_v, "#$_"); # not a name='value' line next; } - $name = $1; + if ($in_v) { $val .= $_; } + else { ($name,$val) = ($1,$2); } + $in_v = $val !~ /'\n/; + next if $in_v; if ($extensions{$name}) { s,/,::,g } - if (!$fast{$name}){ push(@v_others, $_); next; } - push(@v_fast,$_); + if (!$fast{$name}){ push(@v_others, "$name='$val"); next; } + push(@v_fast,"$name='$val"); } foreach(@non_v){ print CONFIG $_ } @@ -66,8 +70,8 @@ print CONFIG "\n", print CONFIG "my \$summary = <<'!END!';\n"; open(MYCONFIG,"<myconfig") || die "open myconfig failed: $!"; -1 while( ($_=<MYCONFIG>) !~ /^Summary of/); -do { print CONFIG $_ } until ($_ = <MYCONFIG>) =~ /^\s*$/; +1 while defined($_ = <MYCONFIG>) && !/^Summary of/; +do { print CONFIG $_ } until !defined($_ = <MYCONFIG>) || /^\s*$/; close(MYCONFIG); print CONFIG "\n!END!\n", <<'EOT'; @@ -75,7 +79,8 @@ my $summary_expanded = 0; sub myconfig { return $summary if $summary_expanded; - $summary =~ s/\$(\w+)/$Config{$1}/ge; + $summary =~ s{\$(\w+)} + { my $c = $Config{$1}; defined($c) ? $c : 'undef' }ge; $summary_expanded = 1; $summary; } @@ -85,14 +90,21 @@ EOT print CONFIG <<'ENDOFEND'; -tie %Config, Config; -sub TIEHASH { bless {} } sub FETCH { - # check for cached value (which maybe undef so we use exists not defined) + # check for cached value (which may be undef so we use exists not defined) return $_[0]->{$_[1]} if (exists $_[0]->{$_[1]}); - - my($value); # search for the item in the big $config_sh string - return undef unless (($value) = $config_sh =~ m/^$_[1]='(.*)'\s*$/m); + + # Search for it in the big string + my($value, $start, $marker); + $marker = "$_[1]='"; + # return undef unless (($value) = $config_sh =~ m/^$_[1]='(.*)'\s*$/m); + $start = index($config_sh, "\n$marker"); + return undef if ( ($start == -1) && # in case it's first + (substr($config_sh, 0, length($marker)) ne $marker) ); + if ($start == -1) { $start = length($marker) } + else { $start += length($marker) + 1 } + $value = substr($config_sh, $start, + index($config_sh, qq('\n), $start) - $start); $value = undef if $value eq 'undef'; # So we can say "if $Config{'foo'}". $_[0]->{$_[1]} = $value; # cache it @@ -103,19 +115,23 @@ my $prevpos = 0; sub FIRSTKEY { $prevpos = 0; - my($key) = $config_sh =~ m/^(.*?)=/; - $key; + # my($key) = $config_sh =~ m/^(.*?)=/; + substr($config_sh, 0, index($config_sh, '=') ); + # $key; } sub NEXTKEY { - my $pos = index($config_sh, "\n", $prevpos) + 1; + my $pos = index($config_sh, qq('\n), $prevpos) + 2; my $len = index($config_sh, "=", $pos) - $pos; $prevpos = $pos; $len > 0 ? substr($config_sh, $pos, $len) : undef; } sub EXISTS { - exists($_[0]->{$_[1]}) or $config_sh =~ m/^$_[1]=/m; + # exists($_[0]->{$_[1]}) or $config_sh =~ m/^$_[1]=/m; + exists($_[0]->{$_[1]}) or + index($config_sh, "\n$_[1]='") != -1 or + substr($config_sh, 0, length($_[1])+2) eq "$_[1]='"; } sub STORE { die "\%Config::Config is read-only\n" } @@ -126,14 +142,49 @@ sub CLEAR { &STORE } sub config_sh { $config_sh } + +sub config_re { + my $re = shift; + my @matches = ($config_sh =~ /^$re=.*\n/mg); + @matches ? (print @matches) : print "$re: not found\n"; +} + sub config_vars { foreach(@_){ + config_re($_), next if /\W/; my $v=(exists $Config{$_}) ? $Config{$_} : 'UNKNOWN'; $v='undef' unless defined $v; print "$_='$v';\n"; } } +ENDOFEND + +if ($^O eq 'os2') { + print CONFIG <<'ENDOFSET'; +my %preconfig; +if ($OS2::is_aout) { + my ($value, $v) = $config_sh =~ m/^used_aout='(.*)'\s*$/m; + for (split ' ', $value) { + ($v) = $config_sh =~ m/^aout_$_='(.*)'\s*$/m; + $preconfig{$_} = $v eq 'undef' ? undef : $v; + } +} +sub TIEHASH { bless {%preconfig} } +ENDOFSET +} else { + print CONFIG <<'ENDOFSET'; +sub TIEHASH { bless {} } +ENDOFSET +} + +print CONFIG <<'ENDOFTAIL'; + +# avoid Config..Exporter..UNIVERSAL search for DESTROY then AUTOLOAD +sub DESTROY { } + +tie %Config, 'Config'; + 1; __END__ @@ -166,7 +217,7 @@ Shell variables from the F<config.sh> file (written by Configure) are stored in the readonly-variable C<%Config>, indexed by their names. Values stored in config.sh as 'undef' are returned as undefined -values. The perl C<exists> function can be used to check is a +values. The perl C<exists> function can be used to check if a named variable exists. =over 4 @@ -198,17 +249,23 @@ See also C<-V:name> in L<perlrun/Switches>. Here's a more sophisticated example of using %Config: use Config; + use strict; + + my %sig_num; + my @sig_name; + unless($Config{sig_name} && $Config{sig_num}) { + die "No sigs?"; + } else { + my @names = split ' ', $Config{sig_name}; + @sig_num{@names} = split ' ', $Config{sig_num}; + foreach (@names) { + $sig_name[$sig_num{$_}] ||= $_; + } + } - defined $Config{sig_name} || die "No sigs?"; - foreach $name (split(' ', $Config{sig_name})) { - $signo{$name} = $i; - $signame[$i] = $name; - $i++; - } - - print "signal #17 = $signame[17]\n"; - if ($signo{ALRM}) { - print "SIGALRM is $signo{ALRM}\n"; + print "signal #17 = $sig_name[17]\n"; + if ($sig_num{ALRM}) { + print "SIGALRM is $sig_num{ALRM}\n"; } =head1 WARNING @@ -229,7 +286,7 @@ outside of it. =cut -ENDOFEND +ENDOFTAIL close(CONFIG); diff --git a/gnu/usr.bin/perl/configure b/gnu/usr.bin/perl/configure index 6eeeb54c57f..fa01c454514 100644 --- a/gnu/usr.bin/perl/configure +++ b/gnu/usr.bin/perl/configure @@ -1,6 +1,6 @@ #! /bin/sh # -# $Id: configure,v 1.1 1996/08/19 10:11:33 downsj Exp $ +# $Id: configure,v 1.2 1997/11/30 07:48:25 millert Exp $ # # GNU configure-like front end to metaconfig's Configure. # @@ -16,14 +16,26 @@ # include this script in your own package. # # $Log: configure,v $ -# Revision 1.1 1996/08/19 10:11:33 downsj -# Initial revision +# Revision 1.2 1997/11/30 07:48:25 millert +# perl 5.004_04 # # Revision 3.0.1.1 1995/07/25 14:16:21 ram # patch56: created # (exit $?0) || exec sh $0 $argv:q + +case "$0" in +*configure) + if cmp $0 `echo $0 | sed -e s/configure/Configure/` >/dev/null; then + echo "Your configure and Configure scripts seem to be identical." + echo "This can happen on filesystems that aren't fully case sensitive." + echo "You'll have to explicitly extract Configure and run that." + exit 1 + fi + ;; +esac + opts='' verbose='' create='-e' @@ -37,6 +49,7 @@ It emulates the following GNU configure options (must be fully spelled out): --help --no-create --prefix=PREFIX + --cache-file (ignored) --quiet --silent --verbose @@ -55,6 +68,9 @@ EOM opts="$opts $arg" shift ;; + --cache-file=*) + shift # Just ignore it. + ;; --quiet|--silent) exec >/dev/null 2>&1 shift diff --git a/gnu/usr.bin/perl/cop.h b/gnu/usr.bin/perl/cop.h index b5033090d97..baedc5a52d1 100644 --- a/gnu/usr.bin/perl/cop.h +++ b/gnu/usr.bin/perl/cop.h @@ -1,6 +1,6 @@ /* cop.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -47,13 +47,25 @@ struct block_sub { (void)SvREFCNT_inc(cx->blk_sub.dfoutgv) #define POPSUB(cx) \ - if (cx->blk_sub.hasargs) { /* put back old @_ */ \ - GvAV(defgv) = cx->blk_sub.savearray; \ + { struct block_sub cxsub; \ + POPSUB1(cx); \ + POPSUB2(); } + +#define POPSUB1(cx) \ + cxsub = cx->blk_sub; /* because DESTROY may clobber *cx */ + +#define POPSUB2() \ + if (cxsub.hasargs) { \ + /* put back old @_ */ \ + SvREFCNT_dec(GvAV(defgv)); \ + GvAV(defgv) = cxsub.savearray; \ + /* destroy arg array */ \ + av_clear(cxsub.argarray); \ + AvREAL_off(cxsub.argarray); \ } \ - if (cx->blk_sub.cv) { \ - if (!(CvDEPTH(cx->blk_sub.cv) = cx->blk_sub.olddepth)) { \ - SvREFCNT_dec((SV*)cx->blk_sub.cv); \ - } \ + if (cxsub.cv) { \ + if (!(CvDEPTH(cxsub.cv) = cxsub.olddepth)) \ + SvREFCNT_dec(cxsub.cv); \ } #define POPFORMAT(cx) \ @@ -90,6 +102,7 @@ struct block_loop { OP * last_op; SV ** itervar; SV * itersave; + SV * iterlval; AV * iterary; I32 iterix; }; @@ -100,12 +113,29 @@ struct block_loop { cx->blk_loop.redo_op = cLOOP->op_redoop; \ cx->blk_loop.next_op = cLOOP->op_nextop; \ cx->blk_loop.last_op = cLOOP->op_lastop; \ - cx->blk_loop.itervar = ivar; \ - if (ivar) \ - cx->blk_loop.itersave = *cx->blk_loop.itervar; + if (cx->blk_loop.itervar = (ivar)) \ + cx->blk_loop.itersave = SvREFCNT_inc(*cx->blk_loop.itervar);\ + cx->blk_loop.iterlval = Nullsv; \ + cx->blk_loop.iterary = Nullav; \ + cx->blk_loop.iterix = -1; #define POPLOOP(cx) \ - newsp = stack_base + cx->blk_loop.resetsp; + { struct block_loop cxloop; \ + POPLOOP1(cx); \ + POPLOOP2(); } + +#define POPLOOP1(cx) \ + cxloop = cx->blk_loop; /* because DESTROY may clobber *cx */ \ + newsp = stack_base + cxloop.resetsp; + +#define POPLOOP2() \ + SvREFCNT_dec(cxloop.iterlval); \ + if (cxloop.itervar) { \ + SvREFCNT_dec(*cxloop.itervar); \ + *cxloop.itervar = cxloop.itersave; \ + } \ + if (cxloop.iterary && cxloop.iterary != curstack) \ + SvREFCNT_dec(cxloop.iterary); /* context common to subroutines, evals and loops */ struct block { @@ -144,7 +174,7 @@ struct block { cx->blk_oldretsp = retstack_ix, \ cx->blk_oldpm = curpm, \ cx->blk_gimme = gimme; \ - DEBUG_l( fprintf(stderr,"Entering block %ld, type %s\n", \ + DEBUG_l( PerlIO_printf(PerlIO_stderr(), "Entering block %ld, type %s\n", \ (long)cxstack_ix, block_type[t]); ) /* Exit a block (RETURN and LAST). */ @@ -156,7 +186,7 @@ struct block { retstack_ix = cx->blk_oldretsp, \ pm = cx->blk_oldpm, \ gimme = cx->blk_gimme; \ - DEBUG_l( fprintf(stderr,"Leaving block %ld, type %s\n", \ + DEBUG_l( PerlIO_printf(PerlIO_stderr(), "Leaving block %ld, type %s\n", \ (long)cxstack_ix+1,block_type[cx->cx_type]); ) /* Continue a block elsewhere (NEXT and REDO). */ @@ -171,47 +201,53 @@ struct subst { I32 sbu_iters; I32 sbu_maxiters; I32 sbu_safebase; - I32 sbu_once; I32 sbu_oldsave; + bool sbu_once; + bool sbu_rxtainted; char * sbu_orig; SV * sbu_dstr; SV * sbu_targ; char * sbu_s; char * sbu_m; char * sbu_strend; - char * sbu_subbase; + void * sbu_rxres; REGEXP * sbu_rx; }; #define sb_iters cx_u.cx_subst.sbu_iters #define sb_maxiters cx_u.cx_subst.sbu_maxiters #define sb_safebase cx_u.cx_subst.sbu_safebase -#define sb_once cx_u.cx_subst.sbu_once #define sb_oldsave cx_u.cx_subst.sbu_oldsave +#define sb_once cx_u.cx_subst.sbu_once +#define sb_rxtainted cx_u.cx_subst.sbu_rxtainted #define sb_orig cx_u.cx_subst.sbu_orig #define sb_dstr cx_u.cx_subst.sbu_dstr #define sb_targ cx_u.cx_subst.sbu_targ #define sb_s cx_u.cx_subst.sbu_s #define sb_m cx_u.cx_subst.sbu_m #define sb_strend cx_u.cx_subst.sbu_strend -#define sb_subbase cx_u.cx_subst.sbu_subbase +#define sb_rxres cx_u.cx_subst.sbu_rxres #define sb_rx cx_u.cx_subst.sbu_rx #define PUSHSUBST(cx) CXINC, cx = &cxstack[cxstack_ix], \ cx->sb_iters = iters, \ cx->sb_maxiters = maxiters, \ cx->sb_safebase = safebase, \ - cx->sb_once = once, \ cx->sb_oldsave = oldsave, \ + cx->sb_once = once, \ + cx->sb_rxtainted = rxtainted, \ cx->sb_orig = orig, \ cx->sb_dstr = dstr, \ cx->sb_targ = targ, \ cx->sb_s = s, \ cx->sb_m = m, \ cx->sb_strend = strend, \ + cx->sb_rxres = Null(void*), \ cx->sb_rx = rx, \ - cx->cx_type = CXt_SUBST + cx->cx_type = CXt_SUBST; \ + rxres_save(&cx->sb_rxres, rx) -#define POPSUBST(cx) cxstack_ix-- +#define POPSUBST(cx) cx = &cxstack[cxstack_ix--]; \ + rxres_free(&cx->sb_rxres) struct context { I32 cx_type; /* what kind of context this is */ @@ -232,9 +268,10 @@ struct context { /* "gimme" values */ #define G_SCALAR 0 #define G_ARRAY 1 +#define G_VOID 128 /* skip this bit when adding flags below */ /* extra flags for perl_call_* routines */ #define G_DISCARD 2 /* Call FREETMPS. */ #define G_EVAL 4 /* Assume eval {} around subroutine call. */ #define G_NOARGS 8 /* Don't construct a @_ array. */ -#define G_KEEPERR 16 /* Append errors to $@ rather than overwriting it */ +#define G_KEEPERR 16 /* Append errors to $@, don't overwrite it */ diff --git a/gnu/usr.bin/perl/cv.h b/gnu/usr.bin/perl/cv.h index b08cf5c1d06..262d44c6357 100644 --- a/gnu/usr.bin/perl/cv.h +++ b/gnu/usr.bin/perl/cv.h @@ -1,12 +1,14 @@ /* cv.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. * */ +/* This structure much match the beginning of XPVFM */ + struct xpvcv { char * xpv_pv; /* pointer to malloced string */ STRLEN xpv_cur; /* length of xp_pv as a C string */ @@ -47,6 +49,9 @@ struct xpvcv { #define CVf_CLONED 0x02 /* a clone of one of those */ #define CVf_ANON 0x04 /* CvGV() can't be trusted */ #define CVf_OLDSTYLE 0x08 +#define CVf_UNIQUE 0x10 /* can't be cloned */ +#define CVf_NODEBUG 0x20 /* no DB::sub indirection for this CV + (esp. useful for special XSUBs) */ #define CvCLONE(cv) (CvFLAGS(cv) & CVf_CLONE) #define CvCLONE_on(cv) (CvFLAGS(cv) |= CVf_CLONE) @@ -63,3 +68,11 @@ struct xpvcv { #define CvOLDSTYLE(cv) (CvFLAGS(cv) & CVf_OLDSTYLE) #define CvOLDSTYLE_on(cv) (CvFLAGS(cv) |= CVf_OLDSTYLE) #define CvOLDSTYLE_off(cv) (CvFLAGS(cv) &= ~CVf_OLDSTYLE) + +#define CvUNIQUE(cv) (CvFLAGS(cv) & CVf_UNIQUE) +#define CvUNIQUE_on(cv) (CvFLAGS(cv) |= CVf_UNIQUE) +#define CvUNIQUE_off(cv) (CvFLAGS(cv) &= ~CVf_UNIQUE) + +#define CvNODEBUG(cv) (CvFLAGS(cv) & CVf_NODEBUG) +#define CvNODEBUG_on(cv) (CvFLAGS(cv) |= CVf_NODEBUG) +#define CvNODEBUG_off(cv) (CvFLAGS(cv) &= ~CVf_NODEBUG) diff --git a/gnu/usr.bin/perl/deb.c b/gnu/usr.bin/perl/deb.c index f518b19ad24..8058d1a3b39 100644 --- a/gnu/usr.bin/perl/deb.c +++ b/gnu/usr.bin/perl/deb.c @@ -1,6 +1,6 @@ /* deb.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -30,24 +30,24 @@ deb(pat,a1,a2,a3,a4,a5,a6,a7,a8) register I32 i; GV* gv = curcop->cop_filegv; - fprintf(stderr,"(%s:%ld)\t", + PerlIO_printf(Perl_debug_log, "(%s:%ld)\t", SvTYPE(gv) == SVt_PVGV ? SvPVX(GvSV(gv)) : "<free>", (long)curcop->cop_line); for (i=0; i<dlevel; i++) - fprintf(stderr,"%c%c ",debname[i],debdelim[i]); - fprintf(stderr,pat,a1,a2,a3,a4,a5,a6,a7,a8); + PerlIO_printf(Perl_debug_log, "%c%c ",debname[i],debdelim[i]); + PerlIO_printf(Perl_debug_log, pat,a1,a2,a3,a4,a5,a6,a7,a8); } #else /* !defined(I_STDARG) && !defined(I_VARARGS) */ # ifdef I_STDARG void -deb(char *pat, ...) +deb(const char *pat, ...) # else /*VARARGS1*/ void deb(pat, va_alist) - char *pat; + const char *pat; va_dcl # endif { @@ -55,18 +55,18 @@ deb(pat, va_alist) register I32 i; GV* gv = curcop->cop_filegv; - fprintf(stderr,"(%s:%ld)\t", + PerlIO_printf(Perl_debug_log, "(%s:%ld)\t", SvTYPE(gv) == SVt_PVGV ? SvPVX(GvSV(gv)) : "<free>", (long)curcop->cop_line); for (i=0; i<dlevel; i++) - fprintf(stderr,"%c%c ",debname[i],debdelim[i]); + PerlIO_printf(Perl_debug_log, "%c%c ",debname[i],debdelim[i]); # ifdef I_STDARG va_start(args, pat); # else va_start(args); # endif - (void) vfprintf(stderr,pat,args); + (void) PerlIO_vprintf(Perl_debug_log,pat,args); va_end( args ); } #endif /* !defined(I_STDARG) && !defined(I_VARARGS) */ @@ -82,13 +82,13 @@ deb_growlevel() I32 debstackptrs() { - fprintf(stderr, "%8lx %8lx %8ld %8ld %8ld\n", - (unsigned long)stack, (unsigned long)stack_base, + PerlIO_printf(Perl_debug_log, "%8lx %8lx %8ld %8ld %8ld\n", + (unsigned long)curstack, (unsigned long)stack_base, (long)*markstack_ptr, (long)(stack_sp-stack_base), (long)(stack_max-stack_base)); - fprintf(stderr, "%8lx %8lx %8ld %8ld %8ld\n", - (unsigned long)mainstack, (unsigned long)AvARRAY(stack), - (long)mainstack, (long)AvFILL(stack), (long)AvMAX(stack)); + PerlIO_printf(Perl_debug_log, "%8lx %8lx %8ld %8ld %8ld\n", + (unsigned long)mainstack, (unsigned long)AvARRAY(curstack), + (long)mainstack, (long)AvFILL(curstack), (long)AvMAX(curstack)); return 0; } @@ -106,25 +106,25 @@ debstack() if (*markscan >= i) break; - fprintf(stderr, i ? " => ... " : " => "); + PerlIO_printf(Perl_debug_log, i ? " => ... " : " => "); if (stack_base[0] != &sv_undef || stack_sp < stack_base) - fprintf(stderr, " [STACK UNDERFLOW!!!]\n"); + PerlIO_printf(Perl_debug_log, " [STACK UNDERFLOW!!!]\n"); do { ++i; if (markscan <= markstack_ptr && *markscan < i) { do { ++markscan; - putc('*', stderr); + PerlIO_putc(Perl_debug_log, '*'); } while (markscan <= markstack_ptr && *markscan < i); - fprintf(stderr, " "); + PerlIO_printf(Perl_debug_log, " "); } if (i > top) break; - fprintf(stderr, "%-4s ", SvPEEK(stack_base[i])); + PerlIO_printf(Perl_debug_log, "%-4s ", SvPEEK(stack_base[i])); } while (1); - fprintf(stderr, "\n"); + PerlIO_printf(Perl_debug_log, "\n"); return 0; } #else diff --git a/gnu/usr.bin/perl/doio.c b/gnu/usr.bin/perl/doio.c index f28da95521d..00e2e758859 100644 --- a/gnu/usr.bin/perl/doio.c +++ b/gnu/usr.bin/perl/doio.c @@ -1,6 +1,6 @@ /* doio.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -34,7 +34,11 @@ #endif #ifdef I_UTIME -#include <utime.h> +# ifdef _MSC_VER +# include <sys/utime.h> +# else +# include <utime.h> +# endif #endif #ifdef I_FCNTL #include <fcntl.h> @@ -43,6 +47,15 @@ #include <sys/file.h> #endif +#if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX) +#include <signal.h> +#endif + +/* XXX If this causes problems, set i_unistd=undef in the hint file. */ +#ifdef I_UNISTD +# include <unistd.h> +#endif + #if defined(HAS_SOCKET) && !defined(VMS) /* VMS handles sockets via vmsish.h */ # include <sys/socket.h> # include <netdb.h> @@ -53,6 +66,15 @@ # endif #endif +/* Put this after #includes because <unistd.h> defines _XOPEN_*. */ +#ifndef Sock_size_t +# if _XOPEN_VERSION >= 5 || defined(_XOPEN_SOURCE_EXTENDED) || defined(__GLIBC__) +# define Sock_size_t Size_t +# else +# define Sock_size_t int +# endif +#endif + bool do_open(gv,name,len,as_raw,rawmode,rawperm,supplied_fp) GV *gv; @@ -60,21 +82,21 @@ register char *name; I32 len; int as_raw; int rawmode, rawperm; -FILE *supplied_fp; +PerlIO *supplied_fp; { register IO *io = GvIOn(gv); - FILE *saveifp = Nullfp; - FILE *saveofp = Nullfp; + PerlIO *saveifp = Nullfp; + PerlIO *saveofp = Nullfp; char savetype = ' '; int writing = 0; - FILE *fp; + PerlIO *fp; int fd; int result; forkprocess = 1; /* assume true if no fork */ if (IoIFP(io)) { - fd = fileno(IoIFP(io)); + fd = PerlIO_fileno(IoIFP(io)); if (IoTYPE(io) == '-') result = 0; else if (fd <= maxsysfd) { @@ -87,16 +109,16 @@ FILE *supplied_fp; result = my_pclose(IoIFP(io)); else if (IoIFP(io) != IoOFP(io)) { if (IoOFP(io)) { - result = fclose(IoOFP(io)); - fclose(IoIFP(io)); /* clear stdio, fd already closed */ + result = PerlIO_close(IoOFP(io)); + PerlIO_close(IoIFP(io)); /* clear stdio, fd already closed */ } else - result = fclose(IoIFP(io)); + result = PerlIO_close(IoIFP(io)); } else - result = fclose(IoIFP(io)); + result = PerlIO_close(IoIFP(io)); if (result == EOF && fd > maxsysfd) - fprintf(stderr,"Warning: unable to close filehandle %s properly.\n", + PerlIO_printf(PerlIO_stderr(), "Warning: unable to close filehandle %s properly.\n", GvENAME(gv)); IoOFP(io) = IoIFP(io) = Nullfp; } @@ -109,9 +131,16 @@ FILE *supplied_fp; if (fd == -1) fp = NULL; else { - fp = fdopen(fd, ((result == 0) ? "r" - : (result == 1) ? "w" - : "r+")); + char *fpmode; + if (result == 0) + fpmode = "r"; +#ifdef O_APPEND + else if (rawmode & O_APPEND) + fpmode = (result == 1) ? "a" : "a+"; +#endif + else + fpmode = (result == 1) ? "w" : "r+"; + fp = PerlIO_fdopen(fd, fpmode); if (!fp) close(fd); } @@ -183,7 +212,7 @@ FILE *supplied_fp; goto say_false; } if (IoIFP(thatio)) { - fd = fileno(IoIFP(thatio)); + fd = PerlIO_fileno(IoIFP(thatio)); if (IoTYPE(thatio) == 's') IoTYPE(io) = 's'; } @@ -192,20 +221,21 @@ FILE *supplied_fp; } if (dodup) fd = dup(fd); - if (!(fp = fdopen(fd,mode))) + if (!(fp = PerlIO_fdopen(fd,mode))) { if (dodup) close(fd); + } } } else { /*SUPPRESS 530*/ for (; isSPACE(*name); name++) ; if (strEQ(name,"-")) { - fp = stdout; + fp = PerlIO_stdout(); IoTYPE(io) = '-'; } else { - fp = fopen(name,mode); + fp = PerlIO_open(name,mode); } } } @@ -216,11 +246,11 @@ FILE *supplied_fp; if (*name == '&') goto duplicity; if (strEQ(name,"-")) { - fp = stdin; + fp = PerlIO_stdin(); IoTYPE(io) = '-'; } else - fp = fopen(name,mode); + fp = PerlIO_open(name,mode); } else if (name[len-1] == '|') { name[--len] = '\0'; @@ -239,11 +269,11 @@ FILE *supplied_fp; /*SUPPRESS 530*/ for (; isSPACE(*name); name++) ; if (strEQ(name,"-")) { - fp = stdin; + fp = PerlIO_stdin(); IoTYPE(io) = '-'; } else - fp = fopen(name,"r"); + fp = PerlIO_open(name,"r"); } } if (!fp) { @@ -253,8 +283,8 @@ FILE *supplied_fp; } if (IoTYPE(io) && IoTYPE(io) != '|' && IoTYPE(io) != '-') { - if (Fstat(fileno(fp),&statbuf) < 0) { - (void)fclose(fp); + if (Fstat(PerlIO_fileno(fp),&statbuf) < 0) { + (void)PerlIO_close(fp); goto say_false; } if (S_ISSOCK(statbuf.st_mode)) @@ -267,52 +297,53 @@ FILE *supplied_fp; !statbuf.st_mode #endif ) { - int buflen = sizeof tokenbuf; - if (getsockname(fileno(fp), (struct sockaddr *)tokenbuf, &buflen) >= 0 - || errno != ENOTSOCK) + Sock_size_t buflen = sizeof tokenbuf; + if (getsockname(PerlIO_fileno(fp), (struct sockaddr *)tokenbuf, + &buflen) >= 0 + || errno != ENOTSOCK) IoTYPE(io) = 's'; /* some OS's return 0 on fstat()ed socket */ /* but some return 0 for streams too, sigh */ } #endif } if (saveifp) { /* must use old fp? */ - fd = fileno(saveifp); + fd = PerlIO_fileno(saveifp); if (saveofp) { - Fflush(saveofp); /* emulate fclose() */ + PerlIO_flush(saveofp); /* emulate PerlIO_close() */ if (saveofp != saveifp) { /* was a socket? */ - fclose(saveofp); + PerlIO_close(saveofp); if (fd > 2) Safefree(saveofp); } } - if (fd != fileno(fp)) { + if (fd != PerlIO_fileno(fp)) { int pid; SV *sv; - dup2(fileno(fp), fd); - sv = *av_fetch(fdpid,fileno(fp),TRUE); + dup2(PerlIO_fileno(fp), fd); + sv = *av_fetch(fdpid,PerlIO_fileno(fp),TRUE); (void)SvUPGRADE(sv, SVt_IV); pid = SvIVX(sv); SvIVX(sv) = 0; sv = *av_fetch(fdpid,fd,TRUE); (void)SvUPGRADE(sv, SVt_IV); SvIVX(sv) = pid; - fclose(fp); + PerlIO_close(fp); } fp = saveifp; - clearerr(fp); + PerlIO_clearerr(fp); } #if defined(HAS_FCNTL) && defined(F_SETFD) - fd = fileno(fp); + fd = PerlIO_fileno(fp); fcntl(fd,F_SETFD,fd > maxsysfd); #endif IoIFP(io) = fp; if (writing) { if (IoTYPE(io) == 's' || (IoTYPE(io) == '>' && S_ISCHR(statbuf.st_mode)) ) { - if (!(IoOFP(io) = fdopen(fileno(fp),"w"))) { - fclose(fp); + if (!(IoOFP(io) = PerlIO_fdopen(PerlIO_fileno(fp),"w"))) { + PerlIO_close(fp); IoIFP(io) = Nullfp; goto say_false; } @@ -329,7 +360,7 @@ say_false: return FALSE; } -FILE * +PerlIO * nextargv(gv) register GV *gv; { @@ -344,7 +375,7 @@ register GV *gv; if (!argvoutgv) argvoutgv = gv_fetchpv("ARGVOUT",TRUE,SVt_PVIO); if (filemode & (S_ISUID|S_ISGID)) { - Fflush(IoIFP(GvIOn(argvoutgv))); /* chmod must follow last write */ + PerlIO_flush(IoIFP(GvIOn(argvoutgv))); /* chmod must follow last write */ #ifdef HAS_FCHMOD (void)fchmod(lastfd,filemode); #else @@ -408,7 +439,7 @@ register GV *gv; (void)unlink(SvPVX(sv)); (void)rename(oldname,SvPVX(sv)); do_open(gv,SvPVX(sv),SvCUR(sv),FALSE,0,0,Nullfp); -#endif /* MSDOS */ +#endif /* DOSISH */ #else (void)UNLINK(SvPVX(sv)); if (link(oldname,SvPVX(sv)) < 0) { @@ -421,13 +452,15 @@ register GV *gv; #endif } else { -#ifndef DOSISH +#if !defined(DOSISH) && !defined(AMIGAOS) +# ifndef VMS /* Don't delete; use automatic file versioning */ if (UNLINK(oldname) < 0) { warn("Can't rename %s to %s: %s, skipping file", oldname, SvPVX(sv), Strerror(errno) ); do_close(gv,FALSE); continue; } +# endif #else croak("Can't do inplace edit without backup"); #endif @@ -443,12 +476,15 @@ register GV *gv; continue; } setdefout(argvoutgv); - lastfd = fileno(IoIFP(GvIOp(argvoutgv))); + lastfd = PerlIO_fileno(IoIFP(GvIOp(argvoutgv))); (void)Fstat(lastfd,&statbuf); #ifdef HAS_FCHMOD (void)fchmod(lastfd,filemode); #else +# if !(defined(WIN32) && defined(__BORLANDC__)) + /* Borland runtime creates a readonly file! */ (void)chmod(oldname,filemode); +# endif #endif if (fileuid != statbuf.st_uid || filegid != statbuf.st_gid) { #ifdef HAS_FCHOWN @@ -463,7 +499,7 @@ register GV *gv; return IoIFP(GvIOp(gv)); } else - fprintf(stderr,"Can't open %s: %s\n",SvPV(sv, na), Strerror(errno)); + PerlIO_printf(PerlIO_stderr(), "Can't open %s: %s\n",SvPV(sv, na), Strerror(errno)); } if (inplace) { (void)do_close(argvoutgv,FALSE); @@ -498,15 +534,15 @@ GV *wgv; if (pipe(fd) < 0) goto badexit; - IoIFP(rstio) = fdopen(fd[0], "r"); - IoOFP(wstio) = fdopen(fd[1], "w"); + IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"); + IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"); IoIFP(wstio) = IoOFP(wstio); IoTYPE(rstio) = '<'; IoTYPE(wstio) = '>'; if (!IoIFP(rstio) || !IoOFP(wstio)) { - if (IoIFP(rstio)) fclose(IoIFP(rstio)); + if (IoIFP(rstio)) PerlIO_close(IoIFP(rstio)); else close(fd[0]); - if (IoOFP(wstio)) fclose(IoOFP(wstio)); + if (IoOFP(wstio)) PerlIO_close(IoOFP(wstio)); else close(fd[1]); goto badexit; } @@ -520,13 +556,14 @@ badexit: } #endif +/* explicit renamed to avoid C++ conflict -- kja */ bool #ifndef CAN_PROTOTYPE -do_close(gv,explicit) +do_close(gv,not_implicit) GV *gv; -bool explicit; +bool not_implicit; #else -do_close(GV *gv, bool explicit) +do_close(GV *gv, bool not_implicit) #endif /* CAN_PROTOTYPE */ { bool retval; @@ -540,12 +577,12 @@ do_close(GV *gv, bool explicit) } io = GvIO(gv); if (!io) { /* never opened */ - if (dowarn && explicit) + if (dowarn && not_implicit) warn("Close on unopened file <%s>",GvENAME(gv)); return FALSE; } retval = io_close(io); - if (explicit) { + if (not_implicit) { IoLINES(io) = 0; IoPAGE(io) = 0; IoLINES_LEFT(io) = IoPAGE_LEN(io); @@ -564,18 +601,18 @@ IO* io; if (IoIFP(io)) { if (IoTYPE(io) == '|') { status = my_pclose(IoIFP(io)); - retval = (status == 0); - statusvalue = FIXSTATUS(status); + STATUS_NATIVE_SET(status); + retval = (STATUS_POSIX == 0); } else if (IoTYPE(io) == '-') retval = TRUE; else { if (IoOFP(io) && IoOFP(io) != IoIFP(io)) { /* a socket */ - retval = (fclose(IoOFP(io)) != EOF); - fclose(IoIFP(io)); /* clear stdio, fd already closed */ + retval = (PerlIO_close(IoOFP(io)) != EOF); + PerlIO_close(IoIFP(io)); /* clear stdio, fd already closed */ } else - retval = (fclose(IoIFP(io)) != EOF); + retval = (PerlIO_close(IoIFP(io)) != EOF); } IoOFP(io) = IoIFP(io) = Nullfp; } @@ -597,20 +634,20 @@ GV *gv; while (IoIFP(io)) { -#ifdef USE_STDIO_PTR /* (the code works without this) */ - if (FILE_cnt(IoIFP(io)) > 0) /* cheat a little, since */ - return FALSE; /* this is the most usual case */ -#endif + if (PerlIO_has_cntptr(IoIFP(io))) { /* (the code works without this) */ + if (PerlIO_get_cnt(IoIFP(io)) > 0) /* cheat a little, since */ + return FALSE; /* this is the most usual case */ + } - ch = getc(IoIFP(io)); + ch = PerlIO_getc(IoIFP(io)); if (ch != EOF) { - (void)ungetc(ch, IoIFP(io)); + (void)PerlIO_ungetc(IoIFP(io),ch); return FALSE; } -#if defined(USE_STDIO_PTR) && defined(STDIO_CNT_LVALUE) - if (FILE_cnt(IoIFP(io)) < -1) - FILE_cnt(IoIFP(io)) = -1; -#endif + if (PerlIO_has_cntptr(IoIFP(io)) && PerlIO_canset_cnt(IoIFP(io))) { + if (PerlIO_get_cnt(IoIFP(io)) < -1) + PerlIO_set_cnt(IoIFP(io),-1); + } if (op->op_flags & OPf_SPECIAL) { /* not necessarily a real EOF yet? */ if (!nextargv(argvgv)) /* get another fp handy */ return TRUE; @@ -626,22 +663,15 @@ do_tell(gv) GV *gv; { register IO *io; + register PerlIO *fp; - if (!gv) - goto phooey; - - io = GvIO(gv); - if (!io || !IoIFP(io)) - goto phooey; - + if (gv && (io = GvIO(gv)) && (fp = IoIFP(io))) { #ifdef ULTRIX_STDIO_BOTCH - if (feof(IoIFP(io))) - (void)fseek (IoIFP(io), 0L, 2); /* ultrix 1.2 workaround */ + if (PerlIO_eof(fp)) + (void)PerlIO_seek(fp, 0L, 2); /* ultrix 1.2 workaround */ #endif - - return ftell(IoIFP(io)); - -phooey: + return PerlIO_tell(fp); + } if (dowarn) warn("tell() on unopened file"); SETERRNO(EBADF,RMS$_IFI); @@ -655,37 +685,46 @@ long pos; int whence; { register IO *io; + register PerlIO *fp; - if (!gv) - goto nuts; - - io = GvIO(gv); - if (!io || !IoIFP(io)) - goto nuts; - + if (gv && (io = GvIO(gv)) && (fp = IoIFP(io))) { #ifdef ULTRIX_STDIO_BOTCH - if (feof(IoIFP(io))) - (void)fseek (IoIFP(io), 0L, 2); /* ultrix 1.2 workaround */ + if (PerlIO_eof(fp)) + (void)PerlIO_seek(fp, 0L, 2); /* ultrix 1.2 workaround */ #endif - - return fseek(IoIFP(io), pos, whence) >= 0; - -nuts: + return PerlIO_seek(fp, pos, whence) >= 0; + } if (dowarn) warn("seek() on unopened file"); SETERRNO(EBADF,RMS$_IFI); return FALSE; } +long +do_sysseek(gv, pos, whence) +GV *gv; +long pos; +int whence; +{ + register IO *io; + register PerlIO *fp; + + if (gv && (io = GvIO(gv)) && (fp = IoIFP(io))) + return lseek(PerlIO_fileno(fp), pos, whence); + if (dowarn) + warn("sysseek() on unopened file"); + SETERRNO(EBADF,RMS$_IFI); + return -1L; +} + #if !defined(HAS_TRUNCATE) && !defined(HAS_CHSIZE) && defined(F_FREESP) /* code courtesy of William Kucharski */ #define HAS_CHSIZE -I32 chsize(fd, length) +I32 my_chsize(fd, length) I32 fd; /* file descriptor */ Off_t length; /* length to set file to */ { - extern long lseek(); struct flock fl; struct stat filebuf; @@ -729,60 +768,10 @@ Off_t length; /* length to set file to */ } #endif /* F_FREESP */ -I32 -looks_like_number(sv) -SV *sv; -{ - register char *s; - register char *send; - - if (!SvPOK(sv)) { - STRLEN len; - if (!SvPOKp(sv)) - return TRUE; - s = SvPV(sv, len); - send = s + len; - } - else { - s = SvPVX(sv); - send = s + SvCUR(sv); - } - while (isSPACE(*s)) - s++; - if (s >= send) - return FALSE; - if (*s == '+' || *s == '-') - s++; - while (isDIGIT(*s)) - s++; - if (s == send) - return TRUE; - if (*s == '.') - s++; - else if (s == SvPVX(sv)) - return FALSE; - while (isDIGIT(*s)) - s++; - if (s == send) - return TRUE; - if (*s == 'e' || *s == 'E') { - s++; - if (*s == '+' || *s == '-') - s++; - while (isDIGIT(*s)) - s++; - } - while (isSPACE(*s)) - s++; - if (s >= send) - return TRUE; - return FALSE; -} - bool do_print(sv,fp) register SV *sv; -FILE *fp; +PerlIO *fp; { register char *tmps; STRLEN len; @@ -794,13 +783,13 @@ FILE *fp; if (SvGMAGICAL(sv)) mg_get(sv); if (SvIOK(sv) && SvIVX(sv) != 0) { - fprintf(fp, ofmt, (double)SvIVX(sv)); - return !ferror(fp); + PerlIO_printf(fp, ofmt, (double)SvIVX(sv)); + return !PerlIO_error(fp); } if ( (SvNOK(sv) && SvNVX(sv) != 0.0) || (looks_like_number(sv) && sv_2nv(sv) != 0.0) ) { - fprintf(fp, ofmt, SvNVX(sv)); - return !ferror(fp); + PerlIO_printf(fp, ofmt, SvNVX(sv)); + return !PerlIO_error(fp); } } switch (SvTYPE(sv)) { @@ -812,17 +801,17 @@ FILE *fp; if (SvIOK(sv)) { if (SvGMAGICAL(sv)) mg_get(sv); - fprintf(fp, "%ld", (long)SvIVX(sv)); - return !ferror(fp); + PerlIO_printf(fp, "%ld", (long)SvIVX(sv)); + return !PerlIO_error(fp); } /* FALL THROUGH */ default: tmps = SvPV(sv, len); break; } - if (len && (fwrite1(tmps,1,len,fp) == 0 || ferror(fp))) + if (len && (PerlIO_write(fp,tmps,len) == 0 || PerlIO_error(fp))) return FALSE; - return TRUE; + return !PerlIO_error(fp); } I32 @@ -842,7 +831,7 @@ dARGS statgv = tmpgv; sv_setpv(statname,""); laststype = OP_STAT; - return (laststatval = Fstat(fileno(IoIFP(io)), &statcache)); + return (laststatval = Fstat(PerlIO_fileno(IoIFP(io)), &statcache)); } else { if (tmpgv == defgv) @@ -953,6 +942,8 @@ do_execfree() } } +#if !defined(OS2) && !defined(WIN32) + bool do_exec(cmd) char *cmd; @@ -1012,7 +1003,7 @@ char *cmd; break; } doshell: - execl("/bin/sh","sh","-c",cmd,(char*)0); + execl(sh_path, "sh", "-c", cmd, (char*)0); return FALSE; } } @@ -1042,6 +1033,8 @@ char *cmd; return FALSE; } +#endif /* OS2 || WIN32 */ + I32 apply(type,mark,sp) I32 type; @@ -1056,9 +1049,10 @@ register SV **sp; if (tainting) { while (++mark <= sp) { - MAGIC *mg; - if (SvMAGICAL(*mark) && (mg = mg_find(*mark, 't')) && mg->mg_len & 1) - tainted = TRUE; + if (SvTAINTED(*mark)) { + TAINT; + break; + } } mark = oldmark; } @@ -1091,6 +1085,8 @@ register SV **sp; #ifdef HAS_KILL case OP_KILL: TAINT_PROPER("kill"); + if (mark == sp) + break; s = SvPVx(*++mark, na); tot = sp - mark; if (isUPPER(*s)) { @@ -1188,8 +1184,13 @@ register SV **sp; #endif Zero(&utbuf, sizeof utbuf, char); +#ifdef BIG_TIME + utbuf.actime = (Time_t)SvNVx(*++mark); /* time accessed */ + utbuf.modtime = (Time_t)SvNVx(*++mark); /* time modified */ +#else utbuf.actime = SvIVx(*++mark); /* time accessed */ utbuf.modtime = SvIVx(*++mark); /* time modified */ +#endif tot = sp - mark; while (++mark <= sp) { if (utime(SvPVx(*mark, na),&utbuf)) @@ -1236,7 +1237,7 @@ register struct stat *statbufp; */ return (bit & statbufp->st_mode) ? TRUE : FALSE; -#else /* ! MSDOS */ +#else /* ! DOSISH */ if ((effective ? euid : uid) == 0) { /* root is special */ if (bit == S_IXUSR) { if (statbufp->st_mode & 0111 || S_ISDIR(statbufp->st_mode)) @@ -1257,7 +1258,7 @@ register struct stat *statbufp; else if (statbufp->st_mode & bit >> 6) return TRUE; /* ok as "other" */ return FALSE; -#endif /* ! MSDOS */ +#endif /* ! DOSISH */ } #endif /* ! VMS */ @@ -1332,6 +1333,9 @@ SV **sp; char *a; I32 id, n, cmd, infosize, getinfo; I32 ret = -1; +#ifdef __linux__ /* XXX Need metaconfig test */ + union semun unsemds; +#endif id = SvIVx(*++mark); n = (optype == OP_SEMCTL) ? SvIVx(*++mark) : 0; @@ -1361,7 +1365,21 @@ SV **sp; else if (cmd == GETALL || cmd == SETALL) { struct semid_ds semds; +#ifdef __linux__ /* XXX Need metaconfig test */ +/* linux (and Solaris2?) uses : + int semctl (int semid, int semnum, int cmd, union semun arg) + union semun { + int val; + struct semid_ds *buf; + ushort *array; + }; +*/ + union semun semun; + semun.buf = &semds; + if (semctl(id, 0, IPC_STAT, semun) == -1) +#else if (semctl(id, 0, IPC_STAT, &semds) == -1) +#endif return -1; getinfo = (cmd == GETALL); infosize = semds.sem_nsems * sizeof(short); @@ -1388,13 +1406,13 @@ SV **sp; { a = SvPV(astr, len); if (len != infosize) - croak("Bad arg length for %s, is %d, should be %d", - op_desc[optype], len, infosize); + croak("Bad arg length for %s, is %lu, should be %ld", + op_desc[optype], (unsigned long)len, (long)infosize); } } else { - I32 i = SvIV(astr); + IV i = SvIV(astr); a = (char *)i; /* ouch */ } SETERRNO(0,0); @@ -1407,7 +1425,12 @@ SV **sp; #endif #ifdef HAS_SEM case OP_SEMCTL: +#ifdef __linux__ /* XXX Need metaconfig test */ + unsemds.buf = (struct semid_ds *)a; + ret = semctl(id, n, cmd, unsemds); +#else ret = semctl(id, n, cmd, (struct semid_ds *)a); +#endif break; #endif #ifdef HAS_SHM diff --git a/gnu/usr.bin/perl/doop.c b/gnu/usr.bin/perl/doop.c index c906db70d11..571a9aa70db 100644 --- a/gnu/usr.bin/perl/doop.c +++ b/gnu/usr.bin/perl/doop.c @@ -1,6 +1,6 @@ /* doop.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -18,14 +18,6 @@ #include <signal.h> #endif -#ifdef BUGGY_MSC - #pragma function(memcmp) -#endif /* BUGGY_MSC */ - -#ifdef BUGGY_MSC - #pragma intrinsic(memcmp) -#endif /* BUGGY_MSC */ - I32 do_trans(sv,arg) SV *sv; @@ -150,196 +142,18 @@ register SV **sp; void do_sprintf(sv,len,sarg) -register SV *sv; -register I32 len; -register SV **sarg; +SV *sv; +I32 len; +SV **sarg; { - register char *s; - register char *t; - register char *f; - bool dolong; -#ifdef HAS_QUAD - bool doquad; -#endif /* HAS_QUAD */ - char ch; - register char *send; - register SV *arg; - char *xs; - I32 xlen; - I32 pre; - I32 post; - double value; - STRLEN arglen; - - sv_setpv(sv,""); - len--; /* don't count pattern string */ - t = s = SvPV(*sarg, arglen); /* XXX Don't know t is writeable */ - send = s + arglen; - sarg++; - for ( ; ; len--) { - - /*SUPPRESS 560*/ - if (len <= 0 || !(arg = *sarg++)) - arg = &sv_no; - - /*SUPPRESS 530*/ - for ( ; t < send && *t != '%'; t++) ; - if (t >= send) - break; /* end of run_format string, ignore extra args */ - f = t; - *buf = '\0'; - xs = buf; -#ifdef HAS_QUAD - doquad = -#endif /* HAS_QUAD */ - dolong = FALSE; - pre = post = 0; - for (t++; t < send; t++) { - switch (*t) { - default: - ch = *(++t); - *t = '\0'; - (void)sprintf(xs,f); - len++, sarg--; - xlen = strlen(xs); - break; - case 'n': case '*': - croak("Use of %c in printf format not supported", *t); - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case '.': case '#': case '-': case '+': case ' ': - continue; - case 'l': -#ifdef HAS_QUAD - if (dolong) { - dolong = FALSE; - doquad = TRUE; - } else -#endif - dolong = TRUE; - continue; - case 'c': - ch = *(++t); - *t = '\0'; - xlen = SvIV(arg); - if (strEQ(f,"%c")) { /* some printfs fail on null chars */ - *xs = xlen; - xs[1] = '\0'; - xlen = 1; - } - else { - (void)sprintf(xs,f,xlen); - xlen = strlen(xs); - } - break; - case 'D': - dolong = TRUE; - /* FALL THROUGH */ - case 'd': - ch = *(++t); - *t = '\0'; -#ifdef HAS_QUAD - if (doquad) - (void)sprintf(buf,s,(Quad_t)SvNV(arg)); - else -#endif - if (dolong) - (void)sprintf(xs,f,(long)SvNV(arg)); - else - (void)sprintf(xs,f,SvIV(arg)); - xlen = strlen(xs); - break; - case 'X': case 'O': - dolong = TRUE; - /* FALL THROUGH */ - case 'x': case 'o': case 'u': - ch = *(++t); - *t = '\0'; - value = SvNV(arg); -#ifdef HAS_QUAD - if (doquad) - (void)sprintf(buf,s,(unsigned Quad_t)value); - else -#endif - if (dolong) - (void)sprintf(xs,f,U_L(value)); - else - (void)sprintf(xs,f,U_I(value)); - xlen = strlen(xs); - break; - case 'E': case 'e': case 'f': case 'G': case 'g': - ch = *(++t); - *t = '\0'; - (void)sprintf(xs,f,SvNV(arg)); - xlen = strlen(xs); - break; - case 's': - ch = *(++t); - *t = '\0'; - xs = SvPV(arg, arglen); - xlen = (I32)arglen; - if (strEQ(f,"%s")) { /* some printfs fail on >128 chars */ - break; /* so handle simple cases */ - } - else if (f[1] == '-') { - char *mp = strchr(f, '.'); - I32 min = atoi(f+2); - - if (mp) { - I32 max = atoi(mp+1); - - if (xlen > max) - xlen = max; - } - if (xlen < min) - post = min - xlen; - break; - } - else if (isDIGIT(f[1])) { - char *mp = strchr(f, '.'); - I32 min = atoi(f+1); - - if (mp) { - I32 max = atoi(mp+1); - - if (xlen > max) - xlen = max; - } - if (xlen < min) - pre = min - xlen; - break; - } - strcpy(tokenbuf+64,f); /* sprintf($s,...$s...) */ - *t = ch; - (void)sprintf(buf,tokenbuf+64,xs); - xs = buf; - xlen = strlen(xs); - break; - } - /* end of switch, copy results */ - *t = ch; - if (xs == buf && xlen >= sizeof(buf)) { /* Ooops! */ - fputs("panic: sprintf overflow - memory corrupted!\n",stderr); - my_exit(1); - } - SvGROW(sv, SvCUR(sv) + (f - s) + xlen + 1 + pre + post); - sv_catpvn(sv, s, f - s); - if (pre) { - repeatcpy(SvPVX(sv) + SvCUR(sv), " ", 1, pre); - SvCUR(sv) += pre; - } - sv_catpvn(sv, xs, xlen); - if (post) { - repeatcpy(SvPVX(sv) + SvCUR(sv), " ", 1, post); - SvCUR(sv) += post; - } - s = t; - break; /* break from for loop */ - } - } - sv_catpvn(sv, s, t - s); + STRLEN patlen; + char *pat = SvPV(*sarg, patlen); + bool do_taint = FALSE; + + sv_vsetpvfn(sv, pat, patlen, Null(va_list*), sarg + 1, len - 1, &do_taint); SvSETMAGIC(sv); + if (do_taint) + SvTAINTED_on(sv); } void @@ -494,11 +308,11 @@ register SV *sv; ++count; } else { - if (len < rslen) + if (len < rslen - 1) goto nope; len -= rslen - 1; s -= rslen - 1; - if (bcmp(s, rsptr, rslen)) + if (memNE(s, rsptr, rslen)) goto nope; count += rslen; } @@ -527,17 +341,32 @@ SV *right; register char *dc; STRLEN leftlen; STRLEN rightlen; - register char *lc = SvPV(left, leftlen); - register char *rc = SvPV(right, rightlen); + register char *lc; + register char *rc; register I32 len; I32 lensave; + char *lsave; + char *rsave; - dc = SvPV_force(sv,na); + if (sv != left || (optype != OP_BIT_AND && !SvOK(sv) && !SvGMAGICAL(sv))) + sv_setpvn(sv, "", 0); /* avoid undef warning on |= and ^= */ + lsave = lc = SvPV(left, leftlen); + rsave = rc = SvPV(right, rightlen); len = leftlen < rightlen ? leftlen : rightlen; lensave = len; - if (SvCUR(sv) < len) { - dc = SvGROW(sv,len + 1); - (void)memzero(dc + SvCUR(sv), len - SvCUR(sv) + 1); + if (SvOK(sv) || SvTYPE(sv) > SVt_PVMG) { + dc = SvPV_force(sv, na); + if (SvCUR(sv) < len) { + dc = SvGROW(sv, len + 1); + (void)memzero(dc + SvCUR(sv), len - SvCUR(sv) + 1); + } + } + else { + I32 needlen = ((optype == OP_BIT_AND) + ? len : (leftlen > rightlen ? leftlen : rightlen)); + Newz(801, dc, needlen + 1, char); + (void)sv_usepvn(sv, dc, needlen); + dc = SvPVX(sv); /* sv_usepvn() calls Renew() */ } SvCUR_set(sv, len); (void)SvPOK_only(sv); @@ -588,9 +417,6 @@ SV *right; } #endif { - char *lsave = lc; - char *rsave = rc; - switch (optype) { case OP_BIT_AND: while (len--) @@ -614,6 +440,7 @@ SV *right; break; } } + SvTAINT(sv); } OP * @@ -622,24 +449,45 @@ dARGS { dSP; HV *hv = (HV*)POPs; - I32 i; register HE *entry; - char *tmps; SV *tmpstr; + I32 gimme = GIMME_V; I32 dokeys = (op->op_type == OP_KEYS); I32 dovalues = (op->op_type == OP_VALUES); if (op->op_type == OP_RV2HV || op->op_type == OP_PADHV) dokeys = dovalues = TRUE; - if (!hv) + if (!hv) { + if (op->op_flags & OPf_MOD) { /* lvalue */ + dTARGET; /* make sure to clear its target here */ + if (SvTYPE(TARG) == SVt_PVLV) + LvTARG(TARG) = Nullsv; + PUSHs(TARG); + } RETURN; + } (void)hv_iterinit(hv); /* always reset iterator regardless */ - if (GIMME != G_ARRAY) { + if (gimme == G_VOID) + RETURN; + + if (gimme == G_SCALAR) { + I32 i; dTARGET; + if (op->op_flags & OPf_MOD) { /* lvalue */ + if (SvTYPE(TARG) < SVt_PVLV) { + sv_upgrade(TARG, SVt_PVLV); + sv_magic(TARG, Nullsv, 'k', Nullch, 0); + } + LvTYPE(TARG) = 'k'; + LvTARG(TARG) = (SV*)hv; + PUSHs(TARG); + RETURN; + } + if (!SvRMAGICAL(hv) || !mg_find((SV*)hv,'P')) i = HvKEYS(hv); else { @@ -659,23 +507,18 @@ dARGS PUTBACK; /* hv_iternext and hv_iterval might clobber stack_sp */ while (entry = hv_iternext(hv)) { SPAGAIN; - if (dokeys) { - tmps = hv_iterkey(entry,&i); /* won't clobber stack_sp */ - if (!i) - tmps = ""; - XPUSHs(sv_2mortal(newSVpv(tmps,i))); - } + if (dokeys) + XPUSHs(hv_iterkeysv(entry)); /* won't clobber stack_sp */ if (dovalues) { - tmpstr = NEWSV(45,0); + tmpstr = sv_newmortal(); PUTBACK; sv_setsv(tmpstr,hv_iterval(hv,entry)); + DEBUG_H(sv_setpvf(tmpstr, "%lu%%%d=%lu", + (unsigned long)HeHASH(entry), + HvMAX(hv)+1, + (unsigned long)(HeHASH(entry) & HvMAX(hv)))); SPAGAIN; - DEBUG_H( { - sprintf(buf,"%d%%%d=%d\n",entry->hent_hash, - HvMAX(hv)+1,entry->hent_hash & HvMAX(hv)); - sv_setpv(tmpstr,buf); - } ) - XPUSHs(sv_2mortal(tmpstr)); + XPUSHs(tmpstr); } PUTBACK; } diff --git a/gnu/usr.bin/perl/dosish.h b/gnu/usr.bin/perl/dosish.h index e40e358b75a..1b251ef3104 100644 --- a/gnu/usr.bin/perl/dosish.h +++ b/gnu/usr.bin/perl/dosish.h @@ -1,11 +1,84 @@ #define ABORT() abort(); -#define BIT_BUCKET "\dev\nul" -#define PERL_SYS_INIT(c,v) +#ifndef SH_PATH +#define SH_PATH "/bin/sh" +#endif + +#ifdef DJGPP +# define BIT_BUCKET "nul" +# define OP_BINARY O_BINARY +void Perl_DJGPP_init(); +# define PERL_SYS_INIT(argcp, argvp) STMT_START { \ + Perl_DJGPP_init(); } STMT_END +#else /* DJGPP */ +# ifdef WIN32 +# define PERL_SYS_INIT(c,v) Perl_win32_init(c,v) +# define BIT_BUCKET "nul" +# else +# define PERL_SYS_INIT(c,v) +# define BIT_BUCKET "\\dev\\nul" /* "wanna be like, umm, Newlined, or somethin?" */ +# endif +#endif /* DJGPP */ + #define PERL_SYS_TERM() -#define dXSUB_SYS int dummy +#define dXSUB_SYS #define TMPPATH "plXXXXXX" +#ifdef WIN32 +#define HAS_UTIME +#define HAS_KILL +#endif + +/* + * 5.003_07 and earlier keyed on #ifdef MSDOS for determining if we were + * running on DOS, *and* if we had to cope with 16 bit memory addressing + * constraints, *and* we need to have memory allocated as unsigned long. + * + * with the advent of *real* compilers for DOS, they are not locked together. + * MSDOS means "I am running on MSDOS". HAS_64K_LIMIT means "I have + * 16 bit memory addressing constraints". + * + * if you need the last, try #DEFINE MEM_SIZE unsigned long. + */ +#ifdef MSDOS + #ifndef DJGPP + #define HAS_64K_LIMIT + #endif +#endif + +/* USEMYBINMODE + * This symbol, if defined, indicates that the program should + * use the routine my_binmode(FILE *fp, char iotype) to insure + * that a file is in "binary" mode -- that is, that no translation + * of bytes occurs on read or write operations. + */ +#undef USEMYBINMODE + +/* USE_STAT_RDEV: + * This symbol is defined if this system has a stat structure declaring + * st_rdev + */ +#define USE_STAT_RDEV /**/ + +/* ACME_MESS: + * This symbol, if defined, indicates that error messages should be + * should be generated in a format that allows the use of the Acme + * GUI/editor's autofind feature. + */ +#undef ACME_MESS /**/ + +/* ALTERNATE_SHEBANG: + * This symbol, if defined, contains a "magic" string which may be used + * as the first line of a Perl program designed to be executed directly + * by name, instead of the standard Unix #!. If ALTERNATE_SHEBANG + * begins with a character other then #, then Perl will only treat + * it as a command line if if finds the string "perl" in the first + * word; otherwise it's treated as the first line of code in the script. + * (IOW, Perl won't hand off to another interpreter via an alternate + * shebang sequence that might be legal Perl code.) + */ +/* #define ALTERNATE_SHEBANG "#!" / **/ + /* * fwrite1() should be a routine with the same calling sequence as fwrite(), * but which outputs all of the bytes requested as a single stream (unlike @@ -14,8 +87,19 @@ */ #define fwrite1 fwrite -#define Stat(fname,bufptr) stat((fname),(bufptr)) #define Fstat(fd,bufptr) fstat((fd),(bufptr)) #define Fflush(fp) fflush(fp) +#define Mkdir(path,mode) mkdir((path),(mode)) -#define my_getenv(var) getenv(var) +#ifndef WIN32 +# define Stat(fname,bufptr) stat((fname),(bufptr)) +#else +# define Stat(fname,bufptr) win32_stat((fname),(bufptr)) +# define my_getenv(var) getenv(var) +/* + * the following are standard library calls (stdio in particular) + * that is being redirected to the perl DLL. This is needed for + * Dynaloading any modules that called stdio functions + */ +# include <win32iop.h> +#endif /* WIN32 */ diff --git a/gnu/usr.bin/perl/dump.c b/gnu/usr.bin/perl/dump.c index 19300e1fa86..9bd51acc008 100644 --- a/gnu/usr.bin/perl/dump.c +++ b/gnu/usr.bin/perl/dump.c @@ -1,6 +1,6 @@ /* dump.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -22,16 +22,16 @@ dump_all() } #else /* Rest of file is for DEBUGGING */ +#ifdef I_STDARG +static void dump(char *pat, ...); +#else static void dump(); +#endif void dump_all() { -#ifdef HAS_SETLINEBUF - setlinebuf(stderr); -#else - setvbuf(stderr, Nullch, _IOLBF, 0); -#endif + PerlIO_setlinebuf(Perl_debug_log); if (main_root) dump_op(main_root); dump_packsubs(defstash); @@ -47,14 +47,14 @@ HV* stash; if (!HvARRAY(stash)) return; for (i = 0; i <= (I32) HvMAX(stash); i++) { - for (entry = HvARRAY(stash)[i]; entry; entry = entry->hent_next) { - GV *gv = (GV*)entry->hent_val; + for (entry = HvARRAY(stash)[i]; entry; entry = HeNEXT(entry)) { + GV *gv = (GV*)HeVAL(entry); HV *hv; - if (GvCV(gv)) + if (GvCVu(gv)) dump_sub(gv); if (GvFORM(gv)) dump_form(gv); - if (entry->hent_key[entry->hent_klen-1] == ':' && + if (HeKEY(entry)[HeKLEN(entry)-1] == ':' && (hv = GvHV(gv)) && HvNAME(hv) && hv != defstash) dump_packsubs(hv); /* nested package */ } @@ -67,7 +67,7 @@ GV* gv; { SV *sv = sv_newmortal(); - gv_fullname(sv,gv); + gv_fullname3(sv, gv, Nullch); dump("\nSUB %s = ", SvPVX(sv)); if (CvXSUB(GvCV(gv))) dump("(xsub 0x%x %d)\n", @@ -85,7 +85,7 @@ GV* gv; { SV *sv = sv_newmortal(); - gv_fullname(sv,gv); + gv_fullname3(sv, gv, Nullch); dump("\nFORMAT %s = ", SvPVX(sv)); if (CvROOT(GvFORM(gv))) dump_op(CvROOT(GvFORM(gv))); @@ -103,22 +103,20 @@ void dump_op(op) register OP *op; { - SV *tmpsv; - dump("{\n"); if (op->op_seq) - fprintf(stderr, "%-4d", op->op_seq); + PerlIO_printf(Perl_debug_log, "%-4d", op->op_seq); else - fprintf(stderr, " "); + PerlIO_printf(Perl_debug_log, " "); dump("TYPE = %s ===> ", op_name[op->op_type]); if (op->op_next) { if (op->op_seq) - fprintf(stderr, "%d\n", op->op_next->op_seq); + PerlIO_printf(Perl_debug_log, "%d\n", op->op_next->op_seq); else - fprintf(stderr, "(%d)\n", op->op_next->op_seq); + PerlIO_printf(Perl_debug_log, "(%d)\n", op->op_next->op_seq); } else - fprintf(stderr, "DONE\n"); + PerlIO_printf(Perl_debug_log, "DONE\n"); dumplvl++; if (op->op_targ) { if (op->op_type == OP_NULL) @@ -130,52 +128,57 @@ register OP *op; dump("ADDR = 0x%lx => 0x%lx\n",op, op->op_next); #endif if (op->op_flags) { - *buf = '\0'; - if (op->op_flags & OPf_KNOW) { - if (op->op_flags & OPf_LIST) - (void)strcat(buf,"LIST,"); - else - (void)strcat(buf,"SCALAR,"); + SV *tmpsv = newSVpv("", 0); + switch (op->op_flags & OPf_WANT) { + case OPf_WANT_VOID: + sv_catpv(tmpsv, ",VOID"); + break; + case OPf_WANT_SCALAR: + sv_catpv(tmpsv, ",SCALAR"); + break; + case OPf_WANT_LIST: + sv_catpv(tmpsv, ",LIST"); + break; + default: + sv_catpv(tmpsv, ",UNKNOWN"); + break; } - else - (void)strcat(buf,"UNKNOWN,"); if (op->op_flags & OPf_KIDS) - (void)strcat(buf,"KIDS,"); + sv_catpv(tmpsv, ",KIDS"); if (op->op_flags & OPf_PARENS) - (void)strcat(buf,"PARENS,"); + sv_catpv(tmpsv, ",PARENS"); if (op->op_flags & OPf_STACKED) - (void)strcat(buf,"STACKED,"); + sv_catpv(tmpsv, ",STACKED"); if (op->op_flags & OPf_REF) - (void)strcat(buf,"REF,"); + sv_catpv(tmpsv, ",REF"); if (op->op_flags & OPf_MOD) - (void)strcat(buf,"MOD,"); + sv_catpv(tmpsv, ",MOD"); if (op->op_flags & OPf_SPECIAL) - (void)strcat(buf,"SPECIAL,"); - if (*buf) - buf[strlen(buf)-1] = '\0'; - dump("FLAGS = (%s)\n",buf); + sv_catpv(tmpsv, ",SPECIAL"); + dump("FLAGS = (%s)\n", SvCUR(tmpsv) ? SvPVX(tmpsv) + 1 : ""); + SvREFCNT_dec(tmpsv); } if (op->op_private) { - *buf = '\0'; + SV *tmpsv = newSVpv("", 0); if (op->op_type == OP_AASSIGN) { if (op->op_private & OPpASSIGN_COMMON) - (void)strcat(buf,"COMMON,"); + sv_catpv(tmpsv, ",COMMON"); } else if (op->op_type == OP_SASSIGN) { if (op->op_private & OPpASSIGN_BACKWARDS) - (void)strcat(buf,"BACKWARDS,"); + sv_catpv(tmpsv, ",BACKWARDS"); } else if (op->op_type == OP_TRANS) { if (op->op_private & OPpTRANS_SQUASH) - (void)strcat(buf,"SQUASH,"); + sv_catpv(tmpsv, ",SQUASH"); if (op->op_private & OPpTRANS_DELETE) - (void)strcat(buf,"DELETE,"); + sv_catpv(tmpsv, ",DELETE"); if (op->op_private & OPpTRANS_COMPLEMENT) - (void)strcat(buf,"COMPLEMENT,"); + sv_catpv(tmpsv, ",COMPLEMENT"); } else if (op->op_type == OP_REPEAT) { if (op->op_private & OPpREPEAT_DOLIST) - (void)strcat(buf,"DOLIST,"); + sv_catpv(tmpsv, ",DOLIST"); } else if (op->op_type == OP_ENTERSUB || op->op_type == OP_RV2SV || @@ -185,45 +188,59 @@ register OP *op; op->op_type == OP_AELEM || op->op_type == OP_HELEM ) { - if (op->op_private & OPpENTERSUB_AMPER) - (void)strcat(buf,"AMPER,"); - if (op->op_private & OPpENTERSUB_DB) - (void)strcat(buf,"DB,"); - if (op->op_private & OPpDEREF_AV) - (void)strcat(buf,"AV,"); - if (op->op_private & OPpDEREF_HV) - (void)strcat(buf,"HV,"); - if (op->op_private & HINT_STRICT_REFS) - (void)strcat(buf,"STRICT_REFS,"); + if (op->op_type == OP_ENTERSUB) { + if (op->op_private & OPpENTERSUB_AMPER) + sv_catpv(tmpsv, ",AMPER"); + if (op->op_private & OPpENTERSUB_DB) + sv_catpv(tmpsv, ",DB"); + } + switch (op->op_private & OPpDEREF) { + case OPpDEREF_SV: + sv_catpv(tmpsv, ",SV"); + break; + case OPpDEREF_AV: + sv_catpv(tmpsv, ",AV"); + break; + case OPpDEREF_HV: + sv_catpv(tmpsv, ",HV"); + break; + } + if (op->op_type == OP_AELEM || op->op_type == OP_HELEM) { + if (op->op_private & OPpLVAL_DEFER) + sv_catpv(tmpsv, ",LVAL_DEFER"); + } + else { + if (op->op_private & HINT_STRICT_REFS) + sv_catpv(tmpsv, ",STRICT_REFS"); + } } else if (op->op_type == OP_CONST) { if (op->op_private & OPpCONST_BARE) - (void)strcat(buf,"BARE,"); + sv_catpv(tmpsv, ",BARE"); } else if (op->op_type == OP_FLIP) { if (op->op_private & OPpFLIP_LINENUM) - (void)strcat(buf,"LINENUM,"); + sv_catpv(tmpsv, ",LINENUM"); } else if (op->op_type == OP_FLOP) { if (op->op_private & OPpFLIP_LINENUM) - (void)strcat(buf,"LINENUM,"); + sv_catpv(tmpsv, ",LINENUM"); } if (op->op_flags & OPf_MOD && op->op_private & OPpLVAL_INTRO) - (void)strcat(buf,"INTRO,"); - if (*buf) { - buf[strlen(buf)-1] = '\0'; - dump("PRIVATE = (%s)\n",buf); - } + sv_catpv(tmpsv, ",INTRO"); + if (SvCUR(tmpsv)) + dump("PRIVATE = (%s)\n", SvPVX(tmpsv) + 1); + SvREFCNT_dec(tmpsv); } switch (op->op_type) { case OP_GVSV: case OP_GV: if (cGVOP->op_gv) { + SV *tmpsv = NEWSV(0,0); ENTER; - tmpsv = NEWSV(0,0); SAVEFREESV(tmpsv); - gv_fullname(tmpsv,cGVOP->op_gv); + gv_fullname3(tmpsv, cGVOP->op_gv, Nullch); dump("GV = %s\n", SvPV(tmpsv, na)); LEAVE; } @@ -243,31 +260,31 @@ register OP *op; case OP_ENTERLOOP: dump("REDO ===> "); if (cLOOP->op_redoop) - fprintf(stderr, "%d\n", cLOOP->op_redoop->op_seq); + PerlIO_printf(Perl_debug_log, "%d\n", cLOOP->op_redoop->op_seq); else - fprintf(stderr, "DONE\n"); + PerlIO_printf(Perl_debug_log, "DONE\n"); dump("NEXT ===> "); if (cLOOP->op_nextop) - fprintf(stderr, "%d\n", cLOOP->op_nextop->op_seq); + PerlIO_printf(Perl_debug_log, "%d\n", cLOOP->op_nextop->op_seq); else - fprintf(stderr, "DONE\n"); + PerlIO_printf(Perl_debug_log, "DONE\n"); dump("LAST ===> "); if (cLOOP->op_lastop) - fprintf(stderr, "%d\n", cLOOP->op_lastop->op_seq); + PerlIO_printf(Perl_debug_log, "%d\n", cLOOP->op_lastop->op_seq); else - fprintf(stderr, "DONE\n"); + PerlIO_printf(Perl_debug_log, "DONE\n"); break; case OP_COND_EXPR: dump("TRUE ===> "); if (cCONDOP->op_true) - fprintf(stderr, "%d\n", cCONDOP->op_true->op_seq); + PerlIO_printf(Perl_debug_log, "%d\n", cCONDOP->op_true->op_seq); else - fprintf(stderr, "DONE\n"); + PerlIO_printf(Perl_debug_log, "DONE\n"); dump("FALSE ===> "); if (cCONDOP->op_false) - fprintf(stderr, "%d\n", cCONDOP->op_false->op_seq); + PerlIO_printf(Perl_debug_log, "%d\n", cCONDOP->op_false->op_seq); else - fprintf(stderr, "DONE\n"); + PerlIO_printf(Perl_debug_log, "DONE\n"); break; case OP_MAPWHILE: case OP_GREPWHILE: @@ -275,9 +292,9 @@ register OP *op; case OP_AND: dump("OTHER ===> "); if (cLOGOP->op_other) - fprintf(stderr, "%d\n", cLOGOP->op_other->op_seq); + PerlIO_printf(Perl_debug_log, "%d\n", cLOGOP->op_other->op_seq); else - fprintf(stderr, "DONE\n"); + PerlIO_printf(Perl_debug_log, "DONE\n"); break; case OP_PUSHRE: case OP_MATCH: @@ -303,16 +320,16 @@ register GV *gv; SV *sv; if (!gv) { - fprintf(stderr,"{}\n"); + PerlIO_printf(Perl_debug_log, "{}\n"); return; } sv = sv_newmortal(); dumplvl++; - fprintf(stderr,"{\n"); - gv_fullname(sv,gv); + PerlIO_printf(Perl_debug_log, "{\n"); + gv_fullname3(sv, gv, Nullch); dump("GV_NAME = %s", SvPVX(sv)); if (gv != GvEGV(gv)) { - gv_efullname(sv,GvEGV(gv)); + gv_efullname3(sv, GvEGV(gv), Nullch); dump("-> %s", SvPVX(sv)); } dump("\n"); @@ -337,7 +354,11 @@ register PMOP *pm; else ch = '/'; if (pm->op_pmregexp) - dump("PMf_PRE %c%s%c\n",ch,pm->op_pmregexp->precomp,ch); + dump("PMf_PRE %c%s%c%s\n", + ch, pm->op_pmregexp->precomp, ch, + (pm->op_private & OPpRUNTIME) ? " (RUNTIME)" : ""); + else + dump("PMf_PRE (RUNTIME)\n"); if (pm->op_type != OP_PUSHRE && pm->op_pmreplroot) { dump("PMf_REPL = "); dump_op(pm->op_pmreplroot); @@ -346,38 +367,37 @@ register PMOP *pm; dump("PMf_SHORT = %s\n",SvPEEK(pm->op_pmshort)); } if (pm->op_pmflags) { - *buf = '\0'; + SV *tmpsv = newSVpv("", 0); if (pm->op_pmflags & PMf_USED) - (void)strcat(buf,"USED,"); + sv_catpv(tmpsv, ",USED"); if (pm->op_pmflags & PMf_ONCE) - (void)strcat(buf,"ONCE,"); + sv_catpv(tmpsv, ",ONCE"); if (pm->op_pmflags & PMf_SCANFIRST) - (void)strcat(buf,"SCANFIRST,"); + sv_catpv(tmpsv, ",SCANFIRST"); if (pm->op_pmflags & PMf_ALL) - (void)strcat(buf,"ALL,"); + sv_catpv(tmpsv, ",ALL"); if (pm->op_pmflags & PMf_SKIPWHITE) - (void)strcat(buf,"SKIPWHITE,"); - if (pm->op_pmflags & PMf_FOLD) - (void)strcat(buf,"FOLD,"); + sv_catpv(tmpsv, ",SKIPWHITE"); if (pm->op_pmflags & PMf_CONST) - (void)strcat(buf,"CONST,"); + sv_catpv(tmpsv, ",CONST"); if (pm->op_pmflags & PMf_KEEP) - (void)strcat(buf,"KEEP,"); + sv_catpv(tmpsv, ",KEEP"); if (pm->op_pmflags & PMf_GLOBAL) - (void)strcat(buf,"GLOBAL,"); - if (pm->op_pmflags & PMf_RUNTIME) - (void)strcat(buf,"RUNTIME,"); + sv_catpv(tmpsv, ",GLOBAL"); + if (pm->op_pmflags & PMf_CONTINUE) + sv_catpv(tmpsv, ",CONTINUE"); if (pm->op_pmflags & PMf_EVAL) - (void)strcat(buf,"EVAL,"); - if (*buf) - buf[strlen(buf)-1] = '\0'; - dump("PMFLAGS = (%s)\n",buf); + sv_catpv(tmpsv, ",EVAL"); + dump("PMFLAGS = (%s)\n", SvCUR(tmpsv) ? SvPVX(tmpsv) + 1 : ""); + SvREFCNT_dec(tmpsv); } dumplvl--; dump("}\n"); } + +#if !defined(I_STDARG) && !defined(I_VARARGS) /* VARARGS1 */ static void dump(arg1,arg2,arg3,arg4,arg5) char *arg1; @@ -386,7 +406,36 @@ long arg2, arg3, arg4, arg5; I32 i; for (i = dumplvl*4; i; i--) - (void)putc(' ',stderr); - fprintf(stderr,arg1, arg2, arg3, arg4, arg5); + (void)PerlIO_putc(Perl_debug_log,' '); + PerlIO_printf(Perl_debug_log, arg1, arg2, arg3, arg4, arg5); } + +#else + +#ifdef I_STDARG +static void +dump(char *pat,...) +#else +/*VARARGS0*/ +static void +dump(pat,va_alist) + char *pat; + va_dcl +#endif +{ + I32 i; + va_list args; + +#ifdef I_STDARG + va_start(args, pat); +#else + va_start(args); +#endif + for (i = dumplvl*4; i; i--) + (void)PerlIO_putc(Perl_debug_log,' '); + PerlIO_vprintf(Perl_debug_log,pat,args); + va_end(args); +} +#endif + #endif diff --git a/gnu/usr.bin/perl/eg/ADB b/gnu/usr.bin/perl/eg/ADB index d724eec66bf..bbf07509ccf 100644 --- a/gnu/usr.bin/perl/eg/ADB +++ b/gnu/usr.bin/perl/eg/ADB @@ -1,6 +1,6 @@ #!/usr/bin/perl -# $RCSfile: ADB,v $$Revision: 1.1 $$Date: 1996/08/19 10:11:52 $ +# $RCSfile: ADB,v $$Revision: 1.2 $$Date: 1997/11/30 07:49:35 $ # This script is only useful when used in your crash directory. diff --git a/gnu/usr.bin/perl/eg/README b/gnu/usr.bin/perl/eg/README index 87cfc334f14..15eb6551a37 100644 --- a/gnu/usr.bin/perl/eg/README +++ b/gnu/usr.bin/perl/eg/README @@ -13,7 +13,7 @@ of a system to check on and report various kinds of anomalies. If you machine doesn't support #!, the first thing you'll want to do is replace the #! with a couple of lines that look like this: - eval "exec /usr/bin/perl -S $0 $*" + eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' if $running_under_some_shell; being sure to include any flags that were on the #! line. A supplied script diff --git a/gnu/usr.bin/perl/eg/changes b/gnu/usr.bin/perl/eg/changes index e1c90870bbb..6396e2c3932 100644 --- a/gnu/usr.bin/perl/eg/changes +++ b/gnu/usr.bin/perl/eg/changes @@ -1,6 +1,6 @@ #!/usr/bin/perl -P -# $RCSfile: changes,v $$Revision: 1.1 $$Date: 1996/08/19 10:11:52 $ +# $RCSfile: changes,v $$Revision: 1.2 $$Date: 1997/11/30 07:49:37 $ ($dir, $days) = @ARGV; $dir = '/' if $dir eq ''; diff --git a/gnu/usr.bin/perl/eg/dus b/gnu/usr.bin/perl/eg/dus index 78062f82a4d..463290fe569 100644 --- a/gnu/usr.bin/perl/eg/dus +++ b/gnu/usr.bin/perl/eg/dus @@ -1,6 +1,6 @@ #!/usr/bin/perl -# $RCSfile: dus,v $$Revision: 1.1 $$Date: 1996/08/19 10:11:53 $ +# $RCSfile: dus,v $$Revision: 1.2 $$Date: 1997/11/30 07:49:37 $ # This script does a du -s on any directories in the current directory that # are not mount points for another filesystem. diff --git a/gnu/usr.bin/perl/eg/findcp b/gnu/usr.bin/perl/eg/findcp index 3236ce37faa..b7831c5cee5 100644 --- a/gnu/usr.bin/perl/eg/findcp +++ b/gnu/usr.bin/perl/eg/findcp @@ -1,6 +1,6 @@ #!/usr/bin/perl -# $RCSfile: findcp,v $$Revision: 1.1 $$Date: 1996/08/19 10:11:53 $ +# $RCSfile: findcp,v $$Revision: 1.2 $$Date: 1997/11/30 07:49:38 $ # This is a wrapper around the find command that pretends find has a switch # of the form -cp host:destination. It presumes your find implements -ls. diff --git a/gnu/usr.bin/perl/eg/findtar b/gnu/usr.bin/perl/eg/findtar index bf76d669aa5..48e3b22aece 100644 --- a/gnu/usr.bin/perl/eg/findtar +++ b/gnu/usr.bin/perl/eg/findtar @@ -1,6 +1,6 @@ #!/usr/bin/perl -# $RCSfile: findtar,v $$Revision: 1.1 $$Date: 1996/08/19 10:11:53 $ +# $RCSfile: findtar,v $$Revision: 1.2 $$Date: 1997/11/30 07:49:39 $ # findtar takes find-style arguments and spits out a tarfile on stdout. # It won't work unless your find supports -ls and your tar the I flag. diff --git a/gnu/usr.bin/perl/eg/muck.man b/gnu/usr.bin/perl/eg/muck.man index e39b363fb90..05c52853e53 100644 --- a/gnu/usr.bin/perl/eg/muck.man +++ b/gnu/usr.bin/perl/eg/muck.man @@ -1,4 +1,4 @@ -.\" $RCSfile: muck.man,v $$Revision: 1.1 $$Date: 1996/08/19 10:11:53 $ +.\" $RCSfile: muck.man,v $$Revision: 1.2 $$Date: 1997/11/30 07:49:39 $ .TH MUCK 1 "10 Jan 1989" .SH NAME muck \- make usage checker diff --git a/gnu/usr.bin/perl/eg/myrup b/gnu/usr.bin/perl/eg/myrup index 4ce90689d5d..61ca8b072ce 100644 --- a/gnu/usr.bin/perl/eg/myrup +++ b/gnu/usr.bin/perl/eg/myrup @@ -1,6 +1,6 @@ #!/usr/bin/perl -# $RCSfile: myrup,v $$Revision: 1.1 $$Date: 1996/08/19 10:11:53 $ +# $RCSfile: myrup,v $$Revision: 1.2 $$Date: 1997/11/30 07:49:40 $ # This was a customization of ruptime requested by someone here who wanted # to be able to find the least loaded machine easily. It uses the diff --git a/gnu/usr.bin/perl/eg/nih b/gnu/usr.bin/perl/eg/nih index dae2bbdb8bd..50bf016954d 100644 --- a/gnu/usr.bin/perl/eg/nih +++ b/gnu/usr.bin/perl/eg/nih @@ -1,10 +1,11 @@ -eval "exec /usr/bin/perl -Spi.bak $0 $*" +eval 'exec /usr/bin/perl -Spi.bak $0 ${1+"$@"}' if $running_under_some_shell; -# $RCSfile: nih,v $$Revision: 1.1 $$Date: 1996/08/19 10:11:53 $ +# $RCSfile: nih,v $$Revision: 1.2 $$Date: 1997/11/30 07:49:41 $ # This script makes #! scripts directly executable on machines that don't # support #!. It edits in place any scripts mentioned on the command line. -s|^#!(.*)|#!$1\neval "exec $1 -S \$0 \$*"\n\tif \$running_under_some_shell;| +s[^#!(.*)] + [#!$1\neval 'exec $1 -S \$0 \${1+"\$@"}'\n\tif \$running_under_some_shell;] if $. == 1; diff --git a/gnu/usr.bin/perl/eg/relink b/gnu/usr.bin/perl/eg/relink index 693e933d10a..c0d6de3afdd 100644 --- a/gnu/usr.bin/perl/eg/relink +++ b/gnu/usr.bin/perl/eg/relink @@ -2,11 +2,11 @@ 'di'; 'ig00'; # -# $RCSfile: relink,v $$Revision: 1.1 $$Date: 1996/08/19 10:11:53 $ +# $RCSfile: relink,v $$Revision: 1.2 $$Date: 1997/11/30 07:49:41 $ # # $Log: relink,v $ -# Revision 1.1 1996/08/19 10:11:53 downsj -# Initial revision +# Revision 1.2 1997/11/30 07:49:41 millert +# perl 5.004_04 # ($op = shift) || die "Usage: relink perlexpr [filenames]\n"; diff --git a/gnu/usr.bin/perl/eg/rename b/gnu/usr.bin/perl/eg/rename index 7dd0591b8f9..f041b08d870 100644 --- a/gnu/usr.bin/perl/eg/rename +++ b/gnu/usr.bin/perl/eg/rename @@ -2,11 +2,11 @@ 'di'; 'ig00'; # -# $RCSfile: rename,v $$Revision: 1.1 $$Date: 1996/08/19 10:11:54 $ +# $RCSfile: rename,v $$Revision: 1.2 $$Date: 1997/11/30 07:49:42 $ # # $Log: rename,v $ -# Revision 1.1 1996/08/19 10:11:54 downsj -# Initial revision +# Revision 1.2 1997/11/30 07:49:42 millert +# perl 5.004_04 # ($op = shift) || die "Usage: rename perlexpr [filenames]\n"; diff --git a/gnu/usr.bin/perl/eg/rmfrom b/gnu/usr.bin/perl/eg/rmfrom index 19e283fcdc8..bfd5b835f0f 100644 --- a/gnu/usr.bin/perl/eg/rmfrom +++ b/gnu/usr.bin/perl/eg/rmfrom @@ -1,6 +1,6 @@ #!/usr/bin/perl -n -# $RCSfile: rmfrom,v $$Revision: 1.1 $$Date: 1996/08/19 10:11:54 $ +# $RCSfile: rmfrom,v $$Revision: 1.2 $$Date: 1997/11/30 07:49:42 $ # A handy (but dangerous) script to put after a find ... -print. diff --git a/gnu/usr.bin/perl/eg/shmkill b/gnu/usr.bin/perl/eg/shmkill index 3477f3297d5..958f9fca995 100644 --- a/gnu/usr.bin/perl/eg/shmkill +++ b/gnu/usr.bin/perl/eg/shmkill @@ -1,6 +1,6 @@ #!/usr/bin/perl -# $RCSfile: shmkill,v $$Revision: 1.1 $$Date: 1996/08/19 10:11:54 $ +# $RCSfile: shmkill,v $$Revision: 1.2 $$Date: 1997/11/30 07:49:43 $ # A script to call from crontab periodically when people are leaving shared # memory sitting around unattached. diff --git a/gnu/usr.bin/perl/eg/wrapsuid b/gnu/usr.bin/perl/eg/wrapsuid index 8de9c6e7e49..879eac8773d 100644 --- a/gnu/usr.bin/perl/eg/wrapsuid +++ b/gnu/usr.bin/perl/eg/wrapsuid @@ -2,11 +2,11 @@ 'di'; 'ig00'; # -# $Header: /cvs/OpenBSD/src/gnu/usr.bin/perl/eg/Attic/wrapsuid,v 1.1 1996/08/19 10:11:54 downsj Exp $ +# $Header: /cvs/OpenBSD/src/gnu/usr.bin/perl/eg/Attic/wrapsuid,v 1.2 1997/11/30 07:49:44 millert Exp $ # # $Log: wrapsuid,v $ -# Revision 1.1 1996/08/19 10:11:54 downsj -# Initial revision +# Revision 1.2 1997/11/30 07:49:44 millert +# perl 5.004_04 # # Revision 1.1 90/08/11 13:51:29 lwall # Initial revision diff --git a/gnu/usr.bin/perl/embed.h b/gnu/usr.bin/perl/embed.h index bfd73bd7f6d..51e5f406e7a 100644 --- a/gnu/usr.bin/perl/embed.h +++ b/gnu/usr.bin/perl/embed.h @@ -1,4 +1,7 @@ -/* This file is derived from global.sym and interp.sym */ +/* !!!!!!! DO NOT EDIT THIS FILE !!!!!!! + This file is built by embed.pl from global.sym, interp.sym, + and compat3.sym. Any changes made here will be lost! +*/ /* (Doing namespace management portably in C is really gross.) */ @@ -12,1378 +15,1647 @@ # define EMBED 1 #endif +/* Hide global symbols? */ + #ifdef EMBED -/* globals we need to hide from the world */ -#define AMG_names Perl_AMG_names -#define No Perl_No -#define Sv Perl_Sv -#define Xpv Perl_Xpv -#define Yes Perl_Yes -#define abs_amg Perl_abs_amg -#define add_amg Perl_add_amg -#define add_ass_amg Perl_add_ass_amg -#define additem Perl_additem +#define AMG_names Perl_AMG_names +#define Gv_AMupdate Perl_Gv_AMupdate +#define No Perl_No +#define Sv Perl_Sv +#define Xpv Perl_Xpv +#define Yes Perl_Yes +#define abs_amg Perl_abs_amg +#define add_amg Perl_add_amg +#define add_ass_amg Perl_add_ass_amg +#define additem Perl_additem +#define amagic_call Perl_amagic_call #define amagic_generation Perl_amagic_generation -#define an Perl_an -#define atan2_amg Perl_atan2_amg -#define band_amg Perl_band_amg -#define bool__amg Perl_bool__amg -#define bor_amg Perl_bor_amg -#define buf Perl_buf -#define bufend Perl_bufend -#define bufptr Perl_bufptr -#define bxor_amg Perl_bxor_amg -#define check Perl_check -#define compiling Perl_compiling -#define compl_amg Perl_compl_amg -#define compcv Perl_compcv -#define comppad Perl_comppad -#define comppad_name Perl_comppad_name +#define an Perl_an +#define append_elem Perl_append_elem +#define append_list Perl_append_list +#define apply Perl_apply +#define assertref Perl_assertref +#define atan2_amg Perl_atan2_amg +#define av_clear Perl_av_clear +#define av_extend Perl_av_extend +#define av_fake Perl_av_fake +#define av_fetch Perl_av_fetch +#define av_fill Perl_av_fill +#define av_len Perl_av_len +#define av_make Perl_av_make +#define av_pop Perl_av_pop +#define av_push Perl_av_push +#define av_reify Perl_av_reify +#define av_shift Perl_av_shift +#define av_store Perl_av_store +#define av_undef Perl_av_undef +#define av_unshift Perl_av_unshift +#define band_amg Perl_band_amg +#define bind_match Perl_bind_match +#define block_end Perl_block_end +#define block_gimme Perl_block_gimme +#define block_start Perl_block_start +#define bool__amg Perl_bool__amg +#define bor_amg Perl_bor_amg +#define bufend Perl_bufend +#define bufptr Perl_bufptr +#define bxor_amg Perl_bxor_amg +#define call_list Perl_call_list +#define cando Perl_cando +#define cast_ulong Perl_cast_ulong +#define check Perl_check +#define check_uni Perl_check_uni +#define checkcomma Perl_checkcomma +#define ck_aelem Perl_ck_aelem +#define ck_anoncode Perl_ck_anoncode +#define ck_bitop Perl_ck_bitop +#define ck_concat Perl_ck_concat +#define ck_delete Perl_ck_delete +#define ck_eof Perl_ck_eof +#define ck_eval Perl_ck_eval +#define ck_exec Perl_ck_exec +#define ck_exists Perl_ck_exists +#define ck_ftst Perl_ck_ftst +#define ck_fun Perl_ck_fun +#define ck_fun_locale Perl_ck_fun_locale +#define ck_glob Perl_ck_glob +#define ck_grep Perl_ck_grep +#define ck_gvconst Perl_ck_gvconst +#define ck_index Perl_ck_index +#define ck_lengthconst Perl_ck_lengthconst +#define ck_lfun Perl_ck_lfun +#define ck_listiob Perl_ck_listiob +#define ck_match Perl_ck_match +#define ck_null Perl_ck_null +#define ck_repeat Perl_ck_repeat +#define ck_require Perl_ck_require +#define ck_retarget Perl_ck_retarget +#define ck_rfun Perl_ck_rfun +#define ck_rvconst Perl_ck_rvconst +#define ck_scmp Perl_ck_scmp +#define ck_select Perl_ck_select +#define ck_shift Perl_ck_shift +#define ck_sort Perl_ck_sort +#define ck_spair Perl_ck_spair +#define ck_split Perl_ck_split +#define ck_subr Perl_ck_subr +#define ck_svconst Perl_ck_svconst +#define ck_trunc Perl_ck_trunc +#define collation_ix Perl_collation_ix +#define collation_name Perl_collation_name +#define collation_standard Perl_collation_standard +#define collxfrm_base Perl_collxfrm_base +#define collxfrm_mult Perl_collxfrm_mult +#define compcv Perl_compcv +#define compiling Perl_compiling +#define compl_amg Perl_compl_amg +#define comppad Perl_comppad +#define comppad_name Perl_comppad_name #define comppad_name_fill Perl_comppad_name_fill -#define concat_amg Perl_concat_amg -#define concat_ass_amg Perl_concat_ass_amg -#define cop_seqmax Perl_cop_seqmax -#define cos_amg Perl_cos_amg -#define cryptseen Perl_cryptseen -#define cshlen Perl_cshlen -#define cshname Perl_cshname -#define curcop Perl_curcop -#define curinterp Perl_curinterp -#define curpad Perl_curpad -#define dc Perl_dc -#define dec_amg Perl_dec_amg -#define di Perl_di -#define div_amg Perl_div_amg -#define div_ass_amg Perl_div_ass_amg -#define ds Perl_ds -#define egid Perl_egid -#define envgv Perl_envgv -#define eq_amg Perl_eq_amg -#define error_count Perl_error_count -#define euid Perl_euid -#define evalseq Perl_evalseq -#define exp_amg Perl_exp_amg -#define expect Perl_expect -#define expectterm Perl_expectterm -#define fallback_amg Perl_fallback_amg -#define filter_add Perl_filter_add -#define filter_del Perl_filter_del -#define filter_read Perl_filter_read -#define fold Perl_fold -#define freq Perl_freq -#define ge_amg Perl_ge_amg -#define gid Perl_gid -#define gt_amg Perl_gt_amg -#define hexdigit Perl_hexdigit -#define hints Perl_hints -#define in_my Perl_in_my -#define inc_amg Perl_inc_amg -#define io_close Perl_io_close -#define know_next Perl_know_next -#define last_lop Perl_last_lop -#define last_lop_op Perl_last_lop_op -#define last_uni Perl_last_uni -#define le_amg Perl_le_amg -#define lex_state Perl_lex_state -#define lex_defer Perl_lex_defer -#define lex_expect Perl_lex_expect -#define lex_brackets Perl_lex_brackets -#define lex_formbrack Perl_lex_formbrack -#define lex_fakebrack Perl_lex_fakebrack -#define lex_casemods Perl_lex_casemods -#define lex_dojoin Perl_lex_dojoin -#define lex_starts Perl_lex_starts -#define lex_stuff Perl_lex_stuff -#define lex_repl Perl_lex_repl -#define lex_op Perl_lex_op -#define lex_inpat Perl_lex_inpat -#define lex_inwhat Perl_lex_inwhat -#define lex_brackstack Perl_lex_brackstack -#define lex_casestack Perl_lex_casestack -#define linestr Perl_linestr -#define log_amg Perl_log_amg -#define lshift_amg Perl_lshift_amg -#define lshift_ass_amg Perl_lshift_ass_amg -#define lt_amg Perl_lt_amg -#define markstack Perl_markstack -#define markstack_max Perl_markstack_max -#define markstack_ptr Perl_markstack_ptr -#define maxo Perl_maxo -#define max_intro_pending Perl_max_intro_pending -#define min_intro_pending Perl_min_intro_pending -#define mod_amg Perl_mod_amg -#define mod_ass_amg Perl_mod_ass_amg -#define mult_amg Perl_mult_amg -#define mult_ass_amg Perl_mult_ass_amg -#define multi_close Perl_multi_close -#define multi_end Perl_multi_end -#define multi_open Perl_multi_open -#define multi_start Perl_multi_start -#define na Perl_na -#define ncmp_amg Perl_ncmp_amg -#define nextval Perl_nextval -#define nexttype Perl_nexttype -#define nexttoke Perl_nexttoke -#define ne_amg Perl_ne_amg -#define neg_amg Perl_neg_amg -#define nexttype Perl_nexttype -#define nextval Perl_nextval -#define no_aelem Perl_no_aelem -#define no_dir_func Perl_no_dir_func -#define no_func Perl_no_func -#define no_helem Perl_no_helem -#define no_mem Perl_no_mem -#define no_modify Perl_no_modify -#define no_security Perl_no_security -#define no_sock_func Perl_no_sock_func -#define no_usym Perl_no_usym -#define nointrp Perl_nointrp -#define nomem Perl_nomem -#define nomemok Perl_nomemok -#define nomethod_amg Perl_nomethod_amg -#define not_amg Perl_not_amg -#define numer_amg Perl_numer_amg -#define oldbufptr Perl_oldbufptr -#define oldoldbufptr Perl_oldoldbufptr -#define op Perl_op -#define op_desc Perl_op_desc -#define op_name Perl_op_name -#define op_seqmax Perl_op_seqmax -#define opargs Perl_opargs -#define origalen Perl_origalen -#define origenviron Perl_origenviron -#define osname Perl_osname -#define padix Perl_padix -#define patleave Perl_patleave -#define pow_amg Perl_pow_amg -#define pow_ass_amg Perl_pow_ass_amg -#define ppaddr Perl_ppaddr -#define profiledata Perl_profiledata -#define provide_ref Perl_provide_ref -#define qrt_amg Perl_qrt_amg -#define rcsid Perl_rcsid -#define reall_srchlen Perl_reall_srchlen -#define regarglen Perl_regarglen -#define regbol Perl_regbol -#define regcode Perl_regcode -#define regdummy Perl_regdummy -#define regendp Perl_regendp -#define regeol Perl_regeol -#define regfold Perl_regfold -#define reginput Perl_reginput -#define regkind Perl_regkind -#define reglastparen Perl_reglastparen -#define regmyendp Perl_regmyendp -#define regmyp_size Perl_regmyp_size -#define regmystartp Perl_regmystartp -#define regnarrate Perl_regnarrate -#define regnaughty Perl_regnaughty -#define regnpar Perl_regnpar -#define regparse Perl_regparse -#define regprecomp Perl_regprecomp -#define regprev Perl_regprev -#define regsawback Perl_regsawback -#define regsize Perl_regsize -#define regstartp Perl_regstartp -#define regtill Perl_regtill -#define regxend Perl_regxend -#define repeat_amg Perl_repeat_amg -#define repeat_ass_amg Perl_repeat_ass_amg -#define retstack Perl_retstack -#define retstack_ix Perl_retstack_ix -#define retstack_max Perl_retstack_max -#define rsfp Perl_rsfp -#define rsfp_filters Perl_rsfp_filters -#define rshift_amg Perl_rshift_amg -#define rshift_ass_amg Perl_rshift_ass_amg -#define save_pptr Perl_save_pptr -#define savestack Perl_savestack -#define savestack_ix Perl_savestack_ix -#define savestack_max Perl_savestack_max -#define saw_return Perl_saw_return -#define scmp_amg Perl_scmp_amg -#define scopestack Perl_scopestack -#define scopestack_ix Perl_scopestack_ix -#define scopestack_max Perl_scopestack_max -#define scrgv Perl_scrgv -#define seq_amg Perl_seq_amg -#define sge_amg Perl_sge_amg -#define sgt_amg Perl_sgt_amg -#define sig_name Perl_sig_name -#define sig_num Perl_sig_num -#define siggv Perl_siggv -#define sighandler Perl_sighandler -#define simple Perl_simple -#define sin_amg Perl_sin_amg -#define sle_amg Perl_sle_amg -#define slt_amg Perl_slt_amg -#define sne_amg Perl_sne_amg -#define stack Perl_stack -#define stack_base Perl_stack_base -#define stack_max Perl_stack_max -#define stack_sp Perl_stack_sp -#define statbuf Perl_statbuf -#define string_amg Perl_string_amg -#define sub_generation Perl_sub_generation -#define subline Perl_subline -#define subname Perl_subname -#define subtr_amg Perl_subtr_amg -#define subtr_ass_amg Perl_subtr_ass_amg -#define sv_no Perl_sv_no -#define sv_undef Perl_sv_undef -#define sv_yes Perl_sv_yes -#define tainting Perl_tainting -#define thisexpr Perl_thisexpr -#define timesbuf Perl_timesbuf -#define tokenbuf Perl_tokenbuf -#define uid Perl_uid -#define varies Perl_varies -#define vert Perl_vert -#define vtbl_amagic Perl_vtbl_amagic -#define vtbl_amagicelem Perl_vtbl_amagicelem -#define vtbl_arylen Perl_vtbl_arylen -#define vtbl_bm Perl_vtbl_bm -#define vtbl_dbline Perl_vtbl_dbline -#define vtbl_env Perl_vtbl_env -#define vtbl_envelem Perl_vtbl_envelem -#define vtbl_glob Perl_vtbl_glob -#define vtbl_isa Perl_vtbl_isa -#define vtbl_isaelem Perl_vtbl_isaelem -#define vtbl_mglob Perl_vtbl_mglob -#define vtbl_pack Perl_vtbl_pack -#define vtbl_packelem Perl_vtbl_packelem -#define vtbl_pos Perl_vtbl_pos -#define vtbl_sig Perl_vtbl_sig -#define vtbl_sigelem Perl_vtbl_sigelem -#define vtbl_substr Perl_vtbl_substr -#define vtbl_sv Perl_vtbl_sv -#define vtbl_taint Perl_vtbl_taint -#define vtbl_uvar Perl_vtbl_uvar -#define vtbl_vec Perl_vtbl_vec -#define warn_nl Perl_warn_nl -#define warn_nosemi Perl_warn_nosemi -#define warn_reserved Perl_warn_reserved -#define watchaddr Perl_watchaddr -#define watchok Perl_watchok -#define yychar Perl_yychar -#define yycheck Perl_yycheck -#define yydebug Perl_yydebug -#define yydefred Perl_yydefred -#define yydgoto Perl_yydgoto -#define yyerrflag Perl_yyerrflag -#define yygindex Perl_yygindex -#define yylen Perl_yylen -#define yylhs Perl_yylhs -#define yylval Perl_yylval -#define yyname Perl_yyname -#define yynerrs Perl_yynerrs -#define yyrindex Perl_yyrindex -#define yyrule Perl_yyrule -#define yysindex Perl_yysindex -#define yytable Perl_yytable -#define yyval Perl_yyval -#define Gv_AMupdate Perl_Gv_AMupdate -#define amagic_call Perl_amagic_call -#define append_elem Perl_append_elem -#define append_list Perl_append_list -#define apply Perl_apply -#define assertref Perl_assertref -#define av_clear Perl_av_clear -#define av_extend Perl_av_extend -#define av_fake Perl_av_fake -#define av_fetch Perl_av_fetch -#define av_fill Perl_av_fill -#define av_len Perl_av_len -#define av_make Perl_av_make -#define av_pop Perl_av_pop -#define av_push Perl_av_push -#define av_shift Perl_av_shift -#define av_store Perl_av_store -#define av_undef Perl_av_undef -#define av_unshift Perl_av_unshift -#define bind_match Perl_bind_match -#define block_end Perl_block_end -#define block_start Perl_block_start -#define calllist Perl_calllist -#define cando Perl_cando -#define cast_ulong Perl_cast_ulong -#define check_uni Perl_check_uni -#define checkcomma Perl_checkcomma -#define chsize Perl_chsize -#define ck_aelem Perl_ck_aelem -#define ck_concat Perl_ck_concat -#define ck_delete Perl_ck_delete -#define ck_eof Perl_ck_eof -#define ck_eval Perl_ck_eval -#define ck_exec Perl_ck_exec -#define ck_formline Perl_ck_formline -#define ck_ftst Perl_ck_ftst -#define ck_fun Perl_ck_fun -#define ck_glob Perl_ck_glob -#define ck_grep Perl_ck_grep -#define ck_gvconst Perl_ck_gvconst -#define ck_index Perl_ck_index -#define ck_lengthconst Perl_ck_lengthconst -#define ck_lfun Perl_ck_lfun -#define ck_listiob Perl_ck_listiob -#define ck_match Perl_ck_match -#define ck_null Perl_ck_null -#define ck_repeat Perl_ck_repeat -#define ck_require Perl_ck_require -#define ck_retarget Perl_ck_retarget -#define ck_rfun Perl_ck_rfun -#define ck_rvconst Perl_ck_rvconst -#define ck_select Perl_ck_select -#define ck_shift Perl_ck_shift -#define ck_sort Perl_ck_sort -#define ck_spair Perl_ck_spair -#define ck_split Perl_ck_split -#define ck_subr Perl_ck_subr -#define ck_svconst Perl_ck_svconst -#define ck_trunc Perl_ck_trunc -#define convert Perl_convert -#define cpytill Perl_cpytill -#define croak Perl_croak -#define cv_clone Perl_cv_clone -#define cv_undef Perl_cv_undef -#define cx_dump Perl_cx_dump -#define cxinc Perl_cxinc -#define deb Perl_deb -#define deb_growlevel Perl_deb_growlevel -#define debop Perl_debop -#define debprofdump Perl_debprofdump -#define debstack Perl_debstack -#define debstackptrs Perl_debstackptrs -#define deprecate Perl_deprecate -#define die Perl_die -#define die_where Perl_die_where -#define do_aexec Perl_do_aexec -#define do_chomp Perl_do_chomp -#define do_chop Perl_do_chop -#define do_close Perl_do_close -#define do_eof Perl_do_eof -#define do_exec Perl_do_exec -#define do_execfree Perl_do_execfree -#define do_ipcctl Perl_do_ipcctl -#define do_ipcget Perl_do_ipcget -#define do_join Perl_do_join -#define do_kv Perl_do_kv -#define do_msgrcv Perl_do_msgrcv -#define do_msgsnd Perl_do_msgsnd -#define do_open Perl_do_open -#define do_pipe Perl_do_pipe -#define do_print Perl_do_print -#define do_readline Perl_do_readline -#define do_seek Perl_do_seek -#define do_semop Perl_do_semop -#define do_shmio Perl_do_shmio -#define do_sprintf Perl_do_sprintf -#define do_tell Perl_do_tell -#define do_trans Perl_do_trans -#define do_vecset Perl_do_vecset -#define do_vop Perl_do_vop -#define doeval Perl_doeval -#define dofindlabel Perl_dofindlabel -#define dopoptoeval Perl_dopoptoeval -#define dounwind Perl_dounwind -#define dowantarray Perl_dowantarray -#define dump_all Perl_dump_all -#define dump_eval Perl_dump_eval -#define dump_fds Perl_dump_fds -#define dump_form Perl_dump_form -#define dump_gv Perl_dump_gv -#define dump_mstats Perl_dump_mstats -#define dump_op Perl_dump_op -#define dump_packsubs Perl_dump_packsubs -#define dump_pm Perl_dump_pm -#define dump_sub Perl_dump_sub -#define fbm_compile Perl_fbm_compile -#define fbm_instr Perl_fbm_instr -#define fetch_gv Perl_fetch_gv -#define fetch_io Perl_fetch_io -#define filter_add Perl_filter_add -#define filter_del Perl_filter_del -#define filter_read Perl_filter_read -#define fold_constants Perl_fold_constants -#define force_ident Perl_force_ident -#define force_list Perl_force_list -#define force_next Perl_force_next -#define force_word Perl_force_word -#define free_tmps Perl_free_tmps +#define concat_amg Perl_concat_amg +#define concat_ass_amg Perl_concat_ass_amg +#define convert Perl_convert +#define cop_seqmax Perl_cop_seqmax +#define cos_amg Perl_cos_amg +#define croak Perl_croak +#define cryptseen Perl_cryptseen +#define cshlen Perl_cshlen +#define cshname Perl_cshname +#define curinterp Perl_curinterp +#define curpad Perl_curpad +#define cv_ckproto Perl_cv_ckproto +#define cv_clone Perl_cv_clone +#define cv_const_sv Perl_cv_const_sv +#define cv_undef Perl_cv_undef +#define cx_dump Perl_cx_dump +#define cxinc Perl_cxinc +#define dc Perl_dc +#define deb Perl_deb +#define deb_growlevel Perl_deb_growlevel +#define debop Perl_debop +#define debprofdump Perl_debprofdump +#define debstack Perl_debstack +#define debstackptrs Perl_debstackptrs +#define dec_amg Perl_dec_amg +#define delimcpy Perl_delimcpy +#define deprecate Perl_deprecate +#define di Perl_di +#define die Perl_die +#define die_where Perl_die_where +#define div_amg Perl_div_amg +#define div_ass_amg Perl_div_ass_amg +#define do_aexec Perl_do_aexec +#define do_chomp Perl_do_chomp +#define do_chop Perl_do_chop +#define do_close Perl_do_close +#define do_eof Perl_do_eof +#define do_exec Perl_do_exec +#define do_execfree Perl_do_execfree +#define do_ipcctl Perl_do_ipcctl +#define do_ipcget Perl_do_ipcget +#define do_join Perl_do_join +#define do_kv Perl_do_kv +#define do_msgrcv Perl_do_msgrcv +#define do_msgsnd Perl_do_msgsnd +#define do_open Perl_do_open +#define do_pipe Perl_do_pipe +#define do_print Perl_do_print +#define do_readline Perl_do_readline +#define do_seek Perl_do_seek +#define do_semop Perl_do_semop +#define do_shmio Perl_do_shmio +#define do_sprintf Perl_do_sprintf +#define do_sysseek Perl_do_sysseek +#define do_tell Perl_do_tell +#define do_trans Perl_do_trans +#define do_vecset Perl_do_vecset +#define do_vop Perl_do_vop +#define doeval Perl_doeval +#define dofindlabel Perl_dofindlabel +#define dopoptoeval Perl_dopoptoeval +#define dounwind Perl_dounwind +#define dowantarray Perl_dowantarray +#define ds Perl_ds +#define dump_all Perl_dump_all +#define dump_eval Perl_dump_eval +#define dump_fds Perl_dump_fds +#define dump_form Perl_dump_form +#define dump_gv Perl_dump_gv +#define dump_mstats Perl_dump_mstats +#define dump_op Perl_dump_op +#define dump_packsubs Perl_dump_packsubs +#define dump_pm Perl_dump_pm +#define dump_sub Perl_dump_sub +#define egid Perl_egid +#define eq_amg Perl_eq_amg +#define error_count Perl_error_count +#define euid Perl_euid +#define evalseq Perl_evalseq +#define exp_amg Perl_exp_amg +#define expect Perl_expect +#define expectterm Perl_expectterm +#define fallback_amg Perl_fallback_amg +#define fbm_compile Perl_fbm_compile +#define fbm_instr Perl_fbm_instr +#define fetch_gv Perl_fetch_gv +#define fetch_io Perl_fetch_io +#define filter_add Perl_filter_add +#define filter_del Perl_filter_del +#define filter_read Perl_filter_read +#define fold Perl_fold +#define fold_constants Perl_fold_constants +#define fold_locale Perl_fold_locale +#define force_ident Perl_force_ident +#define force_list Perl_force_list +#define force_next Perl_force_next +#define force_word Perl_force_word +#define form Perl_form +#define free_tmps Perl_free_tmps +#define freq Perl_freq +#define ge_amg Perl_ge_amg #define gen_constant_list Perl_gen_constant_list -#define gp_free Perl_gp_free -#define gp_ref Perl_gp_ref -#define gv_AVadd Perl_gv_AVadd -#define gv_HVadd Perl_gv_HVadd -#define gv_IOadd Perl_gv_IOadd -#define gv_check Perl_gv_check -#define gv_efullname Perl_gv_efullname -#define gv_fetchfile Perl_gv_fetchfile -#define gv_fetchmeth Perl_gv_fetchmeth -#define gv_fetchmethod Perl_gv_fetchmethod -#define gv_fetchpv Perl_gv_fetchpv -#define gv_fullname Perl_gv_fullname -#define gv_init Perl_gv_init -#define gv_stashpv Perl_gv_stashpv -#define gv_stashsv Perl_gv_stashsv -#define he_delayfree Perl_he_delayfree -#define he_free Perl_he_free -#define he_root Perl_he_root -#define hoistmust Perl_hoistmust -#define hv_clear Perl_hv_clear -#define hv_delete Perl_hv_delete -#define hv_exists Perl_hv_exists -#define hv_fetch Perl_hv_fetch -#define hv_iterinit Perl_hv_iterinit -#define hv_iterkey Perl_hv_iterkey -#define hv_iternext Perl_hv_iternext -#define hv_iternextsv Perl_hv_iternextsv -#define hv_iterval Perl_hv_iterval -#define hv_magic Perl_hv_magic -#define hv_stashpv Perl_hv_stashpv -#define hv_store Perl_hv_store -#define hv_undef Perl_hv_undef -#define ibcmp Perl_ibcmp -#define ingroup Perl_ingroup -#define instr Perl_instr -#define intuit_more Perl_intuit_more -#define invert Perl_invert -#define jmaybe Perl_jmaybe -#define keyword Perl_keyword -#define leave_scope Perl_leave_scope -#define lex_end Perl_lex_end -#define lex_start Perl_lex_start -#define linklist Perl_linklist -#define list Perl_list -#define listkids Perl_listkids -#define localize Perl_localize +#define gid Perl_gid +#define gp_free Perl_gp_free +#define gp_ref Perl_gp_ref +#define gt_amg Perl_gt_amg +#define gv_AVadd Perl_gv_AVadd +#define gv_HVadd Perl_gv_HVadd +#define gv_IOadd Perl_gv_IOadd +#define gv_autoload4 Perl_gv_autoload4 +#define gv_check Perl_gv_check +#define gv_efullname Perl_gv_efullname +#define gv_efullname3 Perl_gv_efullname3 +#define gv_fetchfile Perl_gv_fetchfile +#define gv_fetchmeth Perl_gv_fetchmeth +#define gv_fetchmethod Perl_gv_fetchmethod +#define gv_fetchmethod_autoload Perl_gv_fetchmethod_autoload +#define gv_fetchpv Perl_gv_fetchpv +#define gv_fullname Perl_gv_fullname +#define gv_fullname3 Perl_gv_fullname3 +#define gv_init Perl_gv_init +#define gv_stashpv Perl_gv_stashpv +#define gv_stashpvn Perl_gv_stashpvn +#define gv_stashsv Perl_gv_stashsv +#define he_root Perl_he_root +#define hexdigit Perl_hexdigit +#define hints Perl_hints +#define hoistmust Perl_hoistmust +#define hv_clear Perl_hv_clear +#define hv_delayfree_ent Perl_hv_delayfree_ent +#define hv_delete Perl_hv_delete +#define hv_delete_ent Perl_hv_delete_ent +#define hv_exists Perl_hv_exists +#define hv_exists_ent Perl_hv_exists_ent +#define hv_fetch Perl_hv_fetch +#define hv_fetch_ent Perl_hv_fetch_ent +#define hv_free_ent Perl_hv_free_ent +#define hv_iterinit Perl_hv_iterinit +#define hv_iterkey Perl_hv_iterkey +#define hv_iterkeysv Perl_hv_iterkeysv +#define hv_iternext Perl_hv_iternext +#define hv_iternextsv Perl_hv_iternextsv +#define hv_iterval Perl_hv_iterval +#define hv_ksplit Perl_hv_ksplit +#define hv_magic Perl_hv_magic +#define hv_stashpv Perl_hv_stashpv +#define hv_store Perl_hv_store +#define hv_store_ent Perl_hv_store_ent +#define hv_undef Perl_hv_undef +#define ibcmp Perl_ibcmp +#define ibcmp_locale Perl_ibcmp_locale +#define in_my Perl_in_my +#define inc_amg Perl_inc_amg +#define ingroup Perl_ingroup +#define instr Perl_instr +#define intro_my Perl_intro_my +#define intuit_more Perl_intuit_more +#define invert Perl_invert +#define io_close Perl_io_close +#define jmaybe Perl_jmaybe +#define keyword Perl_keyword +#define know_next Perl_know_next +#define last_lop Perl_last_lop +#define last_lop_op Perl_last_lop_op +#define last_uni Perl_last_uni +#define le_amg Perl_le_amg +#define leave_scope Perl_leave_scope +#define lex_brackets Perl_lex_brackets +#define lex_brackstack Perl_lex_brackstack +#define lex_casemods Perl_lex_casemods +#define lex_casestack Perl_lex_casestack +#define lex_defer Perl_lex_defer +#define lex_dojoin Perl_lex_dojoin +#define lex_end Perl_lex_end +#define lex_expect Perl_lex_expect +#define lex_fakebrack Perl_lex_fakebrack +#define lex_formbrack Perl_lex_formbrack +#define lex_inpat Perl_lex_inpat +#define lex_inwhat Perl_lex_inwhat +#define lex_op Perl_lex_op +#define lex_repl Perl_lex_repl +#define lex_start Perl_lex_start +#define lex_starts Perl_lex_starts +#define lex_state Perl_lex_state +#define lex_stuff Perl_lex_stuff +#define linestr Perl_linestr +#define linklist Perl_linklist +#define list Perl_list +#define listkids Perl_listkids +#define localize Perl_localize +#define log_amg Perl_log_amg #define looks_like_number Perl_looks_like_number -#define magic_clearenv Perl_magic_clearenv -#define magic_clearpack Perl_magic_clearpack +#define lshift_amg Perl_lshift_amg +#define lshift_ass_amg Perl_lshift_ass_amg +#define lt_amg Perl_lt_amg +#define magic_clear_all_env Perl_magic_clear_all_env +#define magic_clearenv Perl_magic_clearenv +#define magic_clearpack Perl_magic_clearpack +#define magic_clearsig Perl_magic_clearsig #define magic_existspack Perl_magic_existspack -#define magic_get Perl_magic_get -#define magic_getarylen Perl_magic_getarylen -#define magic_getglob Perl_magic_getglob -#define magic_getpack Perl_magic_getpack -#define magic_getpos Perl_magic_getpos -#define magic_gettaint Perl_magic_gettaint -#define magic_getuvar Perl_magic_getuvar -#define magic_len Perl_magic_len -#define magic_nextpack Perl_magic_nextpack -#define magic_set Perl_magic_set -#define magic_setamagic Perl_magic_setamagic -#define magic_setarylen Perl_magic_setarylen -#define magic_setbm Perl_magic_setbm -#define magic_setdbline Perl_magic_setdbline -#define magic_setenv Perl_magic_setenv -#define magic_setglob Perl_magic_setglob -#define magic_setisa Perl_magic_setisa -#define magic_setmglob Perl_magic_setmglob -#define magic_setpack Perl_magic_setpack -#define magic_setpos Perl_magic_setpos -#define magic_setsig Perl_magic_setsig -#define magic_setsubstr Perl_magic_setsubstr -#define magic_settaint Perl_magic_settaint -#define magic_setuvar Perl_magic_setuvar -#define magic_setvec Perl_magic_setvec -#define magic_wipepack Perl_magic_wipepack -#define magicname Perl_magicname -#define markstack_grow Perl_markstack_grow -#define mess Perl_mess -#define mg_clear Perl_mg_clear -#define mg_copy Perl_mg_copy -#define mg_find Perl_mg_find -#define mg_free Perl_mg_free -#define mg_get Perl_mg_get -#define mg_len Perl_mg_len -#define mg_magical Perl_mg_magical -#define mg_set Perl_mg_set -#define mod Perl_mod -#define modkids Perl_modkids -#define moreswitches Perl_moreswitches -#define mstats Perl_mstats -#define my Perl_my -#define my_bcopy Perl_my_bcopy -#define my_bzero Perl_my_bzero -#define my_exit Perl_my_exit -#define my_htonl Perl_my_htonl -#define my_lstat Perl_my_lstat -#define my_memcmp Perl_my_memcmp -#define my_ntohl Perl_my_ntohl -#define my_pclose Perl_my_pclose -#define my_popen Perl_my_popen -#define my_setenv Perl_my_setenv -#define my_stat Perl_my_stat -#define my_swap Perl_my_swap -#define my_unexec Perl_my_unexec -#define newANONHASH Perl_newANONHASH -#define newANONLIST Perl_newANONLIST -#define newANONSUB Perl_newANONSUB -#define newASSIGNOP Perl_newASSIGNOP -#define newAV Perl_newAV -#define newAVREF Perl_newAVREF -#define newBINOP Perl_newBINOP -#define newCONDOP Perl_newCONDOP -#define newCVREF Perl_newCVREF -#define newFORM Perl_newFORM -#define newFOROP Perl_newFOROP -#define newGVOP Perl_newGVOP -#define newGVREF Perl_newGVREF -#define newGVgen Perl_newGVgen -#define newHV Perl_newHV -#define newHVREF Perl_newHVREF -#define newIO Perl_newIO -#define newLISTOP Perl_newLISTOP -#define newLOGOP Perl_newLOGOP -#define newLOOPEX Perl_newLOOPEX -#define newLOOPOP Perl_newLOOPOP -#define newNULLLIST Perl_newNULLLIST -#define newOP Perl_newOP -#define newPMOP Perl_newPMOP -#define newPROG Perl_newPROG -#define newPVOP Perl_newPVOP -#define newRANGE Perl_newRANGE -#define newRV Perl_newRV -#define newSLICEOP Perl_newSLICEOP -#define newSTATEOP Perl_newSTATEOP -#define newSUB Perl_newSUB -#define newSV Perl_newSV -#define newSVOP Perl_newSVOP -#define newSVREF Perl_newSVREF -#define newSViv Perl_newSViv -#define newSVnv Perl_newSVnv -#define newSVpv Perl_newSVpv -#define newSVrv Perl_newSVrv -#define newSVsv Perl_newSVsv -#define newUNOP Perl_newUNOP -#define newWHILEOP Perl_newWHILEOP -#define newXS Perl_newXS -#define newXSUB Perl_newXSUB -#define nextargv Perl_nextargv -#define ninstr Perl_ninstr -#define no_fh_allowed Perl_no_fh_allowed -#define no_op Perl_no_op -#define oopsAV Perl_oopsAV -#define oopsCV Perl_oopsCV -#define oopsHV Perl_oopsHV -#define op_free Perl_op_free -#define package Perl_package -#define pad_alloc Perl_pad_alloc -#define pad_allocmy Perl_pad_allocmy -#define pad_findmy Perl_pad_findmy -#define pad_free Perl_pad_free -#define pad_leavemy Perl_pad_leavemy -#define pad_reset Perl_pad_reset -#define pad_sv Perl_pad_sv -#define pad_swipe Perl_pad_swipe -#define peep Perl_peep -#define pidgone Perl_pidgone -#define pmflag Perl_pmflag -#define pmruntime Perl_pmruntime -#define pmtrans Perl_pmtrans -#define pop_return Perl_pop_return -#define pop_scope Perl_pop_scope -#define pp_aassign Perl_pp_aassign -#define pp_abs Perl_pp_abs -#define pp_accept Perl_pp_accept -#define pp_add Perl_pp_add -#define pp_aelem Perl_pp_aelem -#define pp_aelemfast Perl_pp_aelemfast -#define pp_alarm Perl_pp_alarm -#define pp_and Perl_pp_and -#define pp_andassign Perl_pp_andassign -#define pp_anoncode Perl_pp_anoncode -#define pp_anonhash Perl_pp_anonhash -#define pp_anonlist Perl_pp_anonlist -#define pp_aslice Perl_pp_aslice -#define pp_atan2 Perl_pp_atan2 -#define pp_av2arylen Perl_pp_av2arylen -#define pp_backtick Perl_pp_backtick -#define pp_bind Perl_pp_bind -#define pp_binmode Perl_pp_binmode -#define pp_bit_and Perl_pp_bit_and -#define pp_bit_or Perl_pp_bit_or -#define pp_bit_xor Perl_pp_bit_xor -#define pp_bless Perl_pp_bless -#define pp_caller Perl_pp_caller -#define pp_chdir Perl_pp_chdir -#define pp_chmod Perl_pp_chmod -#define pp_chomp Perl_pp_chomp -#define pp_chop Perl_pp_chop -#define pp_chown Perl_pp_chown -#define pp_chr Perl_pp_chr -#define pp_chroot Perl_pp_chroot -#define pp_close Perl_pp_close -#define pp_closedir Perl_pp_closedir -#define pp_complement Perl_pp_complement -#define pp_concat Perl_pp_concat -#define pp_cond_expr Perl_pp_cond_expr -#define pp_connect Perl_pp_connect -#define pp_const Perl_pp_const -#define pp_cos Perl_pp_cos -#define pp_crypt Perl_pp_crypt -#define pp_cswitch Perl_pp_cswitch -#define pp_dbmclose Perl_pp_dbmclose -#define pp_dbmopen Perl_pp_dbmopen -#define pp_dbstate Perl_pp_dbstate -#define pp_defined Perl_pp_defined -#define pp_delete Perl_pp_delete -#define pp_die Perl_pp_die -#define pp_divide Perl_pp_divide -#define pp_dofile Perl_pp_dofile -#define pp_dump Perl_pp_dump -#define pp_each Perl_pp_each -#define pp_egrent Perl_pp_egrent -#define pp_ehostent Perl_pp_ehostent -#define pp_enetent Perl_pp_enetent -#define pp_enter Perl_pp_enter -#define pp_entereval Perl_pp_entereval -#define pp_enteriter Perl_pp_enteriter -#define pp_enterloop Perl_pp_enterloop -#define pp_entersub Perl_pp_entersub -#define pp_entersubr Perl_pp_entersubr -#define pp_entertry Perl_pp_entertry -#define pp_enterwrite Perl_pp_enterwrite -#define pp_eof Perl_pp_eof -#define pp_eprotoent Perl_pp_eprotoent -#define pp_epwent Perl_pp_epwent -#define pp_eq Perl_pp_eq -#define pp_eservent Perl_pp_eservent -#define pp_evalonce Perl_pp_evalonce -#define pp_exec Perl_pp_exec -#define pp_exists Perl_pp_exists -#define pp_exit Perl_pp_exit -#define pp_exp Perl_pp_exp -#define pp_fcntl Perl_pp_fcntl -#define pp_fileno Perl_pp_fileno -#define pp_flip Perl_pp_flip -#define pp_flock Perl_pp_flock -#define pp_flop Perl_pp_flop -#define pp_fork Perl_pp_fork -#define pp_formline Perl_pp_formline -#define pp_ftatime Perl_pp_ftatime -#define pp_ftbinary Perl_pp_ftbinary -#define pp_ftblk Perl_pp_ftblk -#define pp_ftchr Perl_pp_ftchr -#define pp_ftctime Perl_pp_ftctime -#define pp_ftdir Perl_pp_ftdir -#define pp_fteexec Perl_pp_fteexec -#define pp_fteowned Perl_pp_fteowned -#define pp_fteread Perl_pp_fteread -#define pp_ftewrite Perl_pp_ftewrite -#define pp_ftfile Perl_pp_ftfile -#define pp_ftis Perl_pp_ftis -#define pp_ftlink Perl_pp_ftlink -#define pp_ftmtime Perl_pp_ftmtime -#define pp_ftpipe Perl_pp_ftpipe -#define pp_ftrexec Perl_pp_ftrexec -#define pp_ftrowned Perl_pp_ftrowned -#define pp_ftrread Perl_pp_ftrread -#define pp_ftrwrite Perl_pp_ftrwrite -#define pp_ftsgid Perl_pp_ftsgid -#define pp_ftsize Perl_pp_ftsize -#define pp_ftsock Perl_pp_ftsock -#define pp_ftsuid Perl_pp_ftsuid -#define pp_ftsvtx Perl_pp_ftsvtx -#define pp_fttext Perl_pp_fttext -#define pp_fttty Perl_pp_fttty -#define pp_ftzero Perl_pp_ftzero -#define pp_ge Perl_pp_ge -#define pp_gelem Perl_pp_gelem -#define pp_getc Perl_pp_getc -#define pp_getlogin Perl_pp_getlogin -#define pp_getpeername Perl_pp_getpeername -#define pp_getpgrp Perl_pp_getpgrp -#define pp_getppid Perl_pp_getppid -#define pp_getpriority Perl_pp_getpriority -#define pp_getsockname Perl_pp_getsockname -#define pp_ggrent Perl_pp_ggrent -#define pp_ggrgid Perl_pp_ggrgid -#define pp_ggrnam Perl_pp_ggrnam -#define pp_ghbyaddr Perl_pp_ghbyaddr -#define pp_ghbyname Perl_pp_ghbyname -#define pp_ghostent Perl_pp_ghostent -#define pp_glob Perl_pp_glob -#define pp_gmtime Perl_pp_gmtime -#define pp_gnbyaddr Perl_pp_gnbyaddr -#define pp_gnbyname Perl_pp_gnbyname -#define pp_gnetent Perl_pp_gnetent -#define pp_goto Perl_pp_goto -#define pp_gpbyname Perl_pp_gpbyname -#define pp_gpbynumber Perl_pp_gpbynumber -#define pp_gprotoent Perl_pp_gprotoent -#define pp_gpwent Perl_pp_gpwent -#define pp_gpwnam Perl_pp_gpwnam -#define pp_gpwuid Perl_pp_gpwuid -#define pp_grepstart Perl_pp_grepstart -#define pp_grepwhile Perl_pp_grepwhile -#define pp_gsbyname Perl_pp_gsbyname -#define pp_gsbyport Perl_pp_gsbyport -#define pp_gservent Perl_pp_gservent -#define pp_gsockopt Perl_pp_gsockopt -#define pp_gt Perl_pp_gt -#define pp_gv Perl_pp_gv -#define pp_gvsv Perl_pp_gvsv -#define pp_helem Perl_pp_helem -#define pp_hex Perl_pp_hex -#define pp_hslice Perl_pp_hslice -#define pp_i_add Perl_pp_i_add -#define pp_i_divide Perl_pp_i_divide -#define pp_i_eq Perl_pp_i_eq -#define pp_i_ge Perl_pp_i_ge -#define pp_i_gt Perl_pp_i_gt -#define pp_i_le Perl_pp_i_le -#define pp_i_lt Perl_pp_i_lt -#define pp_i_modulo Perl_pp_i_modulo -#define pp_i_multiply Perl_pp_i_multiply -#define pp_i_ncmp Perl_pp_i_ncmp -#define pp_i_ne Perl_pp_i_ne -#define pp_i_negate Perl_pp_i_negate -#define pp_i_subtract Perl_pp_i_subtract -#define pp_index Perl_pp_index -#define pp_indread Perl_pp_indread -#define pp_int Perl_pp_int -#define pp_interp Perl_pp_interp -#define pp_ioctl Perl_pp_ioctl -#define pp_iter Perl_pp_iter -#define pp_join Perl_pp_join -#define pp_keys Perl_pp_keys -#define pp_kill Perl_pp_kill -#define pp_last Perl_pp_last -#define pp_lc Perl_pp_lc -#define pp_lcfirst Perl_pp_lcfirst -#define pp_le Perl_pp_le -#define pp_leave Perl_pp_leave -#define pp_leaveeval Perl_pp_leaveeval -#define pp_leaveloop Perl_pp_leaveloop -#define pp_leavesub Perl_pp_leavesub -#define pp_leavetry Perl_pp_leavetry -#define pp_leavewrite Perl_pp_leavewrite -#define pp_left_shift Perl_pp_left_shift -#define pp_length Perl_pp_length -#define pp_lineseq Perl_pp_lineseq -#define pp_link Perl_pp_link -#define pp_list Perl_pp_list -#define pp_listen Perl_pp_listen -#define pp_localtime Perl_pp_localtime -#define pp_log Perl_pp_log -#define pp_lslice Perl_pp_lslice -#define pp_lstat Perl_pp_lstat -#define pp_lt Perl_pp_lt -#define pp_map Perl_pp_map -#define pp_mapstart Perl_pp_mapstart -#define pp_mapwhile Perl_pp_mapwhile -#define pp_match Perl_pp_match -#define pp_method Perl_pp_method -#define pp_mkdir Perl_pp_mkdir -#define pp_modulo Perl_pp_modulo -#define pp_msgctl Perl_pp_msgctl -#define pp_msgget Perl_pp_msgget -#define pp_msgrcv Perl_pp_msgrcv -#define pp_msgsnd Perl_pp_msgsnd -#define pp_multiply Perl_pp_multiply -#define pp_ncmp Perl_pp_ncmp -#define pp_ne Perl_pp_ne -#define pp_negate Perl_pp_negate -#define pp_next Perl_pp_next -#define pp_nextstate Perl_pp_nextstate -#define pp_not Perl_pp_not -#define pp_nswitch Perl_pp_nswitch -#define pp_null Perl_pp_null -#define pp_oct Perl_pp_oct -#define pp_open Perl_pp_open -#define pp_open_dir Perl_pp_open_dir -#define pp_or Perl_pp_or -#define pp_orassign Perl_pp_orassign -#define pp_ord Perl_pp_ord -#define pp_pack Perl_pp_pack -#define pp_padany Perl_pp_padany -#define pp_padav Perl_pp_padav -#define pp_padhv Perl_pp_padhv -#define pp_padsv Perl_pp_padsv -#define pp_pipe_op Perl_pp_pipe_op -#define pp_pop Perl_pp_pop -#define pp_pos Perl_pp_pos -#define pp_postdec Perl_pp_postdec -#define pp_postinc Perl_pp_postinc -#define pp_pow Perl_pp_pow -#define pp_predec Perl_pp_predec -#define pp_preinc Perl_pp_preinc -#define pp_print Perl_pp_print -#define pp_prototype Perl_pp_prototype -#define pp_prtf Perl_pp_prtf -#define pp_push Perl_pp_push -#define pp_pushmark Perl_pp_pushmark -#define pp_pushre Perl_pp_pushre -#define pp_quotemeta Perl_pp_quotemeta -#define pp_rand Perl_pp_rand -#define pp_range Perl_pp_range -#define pp_rcatline Perl_pp_rcatline -#define pp_read Perl_pp_read -#define pp_readdir Perl_pp_readdir -#define pp_readline Perl_pp_readline -#define pp_readlink Perl_pp_readlink -#define pp_recv Perl_pp_recv -#define pp_redo Perl_pp_redo -#define pp_ref Perl_pp_ref -#define pp_refgen Perl_pp_refgen -#define pp_regcmaybe Perl_pp_regcmaybe -#define pp_regcomp Perl_pp_regcomp -#define pp_rename Perl_pp_rename -#define pp_repeat Perl_pp_repeat -#define pp_require Perl_pp_require -#define pp_reset Perl_pp_reset -#define pp_return Perl_pp_return -#define pp_reverse Perl_pp_reverse -#define pp_rewinddir Perl_pp_rewinddir -#define pp_right_shift Perl_pp_right_shift -#define pp_rindex Perl_pp_rindex -#define pp_rmdir Perl_pp_rmdir -#define pp_rv2av Perl_pp_rv2av -#define pp_rv2cv Perl_pp_rv2cv -#define pp_rv2gv Perl_pp_rv2gv -#define pp_rv2hv Perl_pp_rv2hv -#define pp_rv2sv Perl_pp_rv2sv -#define pp_sassign Perl_pp_sassign -#define pp_scalar Perl_pp_scalar -#define pp_schomp Perl_pp_schomp -#define pp_schop Perl_pp_schop -#define pp_scmp Perl_pp_scmp -#define pp_scope Perl_pp_scope -#define pp_seek Perl_pp_seek -#define pp_seekdir Perl_pp_seekdir -#define pp_select Perl_pp_select -#define pp_semctl Perl_pp_semctl -#define pp_semget Perl_pp_semget -#define pp_semop Perl_pp_semop -#define pp_send Perl_pp_send -#define pp_seq Perl_pp_seq -#define pp_setpgrp Perl_pp_setpgrp -#define pp_setpriority Perl_pp_setpriority -#define pp_sge Perl_pp_sge -#define pp_sgrent Perl_pp_sgrent -#define pp_sgt Perl_pp_sgt -#define pp_shift Perl_pp_shift -#define pp_shmctl Perl_pp_shmctl -#define pp_shmget Perl_pp_shmget -#define pp_shmread Perl_pp_shmread -#define pp_shmwrite Perl_pp_shmwrite -#define pp_shostent Perl_pp_shostent -#define pp_shutdown Perl_pp_shutdown -#define pp_sin Perl_pp_sin -#define pp_sle Perl_pp_sle -#define pp_sleep Perl_pp_sleep -#define pp_slt Perl_pp_slt -#define pp_sne Perl_pp_sne -#define pp_snetent Perl_pp_snetent -#define pp_socket Perl_pp_socket -#define pp_sockpair Perl_pp_sockpair -#define pp_sort Perl_pp_sort -#define pp_splice Perl_pp_splice -#define pp_split Perl_pp_split -#define pp_sprintf Perl_pp_sprintf -#define pp_sprotoent Perl_pp_sprotoent -#define pp_spwent Perl_pp_spwent -#define pp_sqrt Perl_pp_sqrt -#define pp_srand Perl_pp_srand -#define pp_srefgen Perl_pp_srefgen -#define pp_sselect Perl_pp_sselect -#define pp_sservent Perl_pp_sservent -#define pp_ssockopt Perl_pp_ssockopt -#define pp_stat Perl_pp_stat -#define pp_stringify Perl_pp_stringify -#define pp_stub Perl_pp_stub -#define pp_study Perl_pp_study -#define pp_subst Perl_pp_subst -#define pp_substcont Perl_pp_substcont -#define pp_substr Perl_pp_substr -#define pp_subtract Perl_pp_subtract -#define pp_symlink Perl_pp_symlink -#define pp_syscall Perl_pp_syscall -#define pp_sysopen Perl_pp_sysopen -#define pp_sysread Perl_pp_sysread -#define pp_system Perl_pp_system -#define pp_syswrite Perl_pp_syswrite -#define pp_tell Perl_pp_tell -#define pp_telldir Perl_pp_telldir -#define pp_tie Perl_pp_tie -#define pp_tied Perl_pp_tied -#define pp_time Perl_pp_time -#define pp_tms Perl_pp_tms -#define pp_trans Perl_pp_trans -#define pp_truncate Perl_pp_truncate -#define pp_uc Perl_pp_uc -#define pp_ucfirst Perl_pp_ucfirst -#define pp_umask Perl_pp_umask -#define pp_undef Perl_pp_undef -#define pp_unlink Perl_pp_unlink -#define pp_unpack Perl_pp_unpack -#define pp_unshift Perl_pp_unshift -#define pp_unstack Perl_pp_unstack -#define pp_untie Perl_pp_untie -#define pp_utime Perl_pp_utime -#define pp_values Perl_pp_values -#define pp_vec Perl_pp_vec -#define pp_wait Perl_pp_wait -#define pp_waitpid Perl_pp_waitpid -#define pp_wantarray Perl_pp_wantarray -#define pp_warn Perl_pp_warn -#define pp_xor Perl_pp_xor -#define pregcomp Perl_pregcomp -#define pregexec Perl_pregexec -#define pregfree Perl_pregfree -#define prepend_elem Perl_prepend_elem -#define push_return Perl_push_return -#define push_scope Perl_push_scope -#define q Perl_q -#define ref Perl_ref -#define refkids Perl_refkids -#define regdump Perl_regdump -#define regnext Perl_regnext -#define regprop Perl_regprop -#define repeatcpy Perl_repeatcpy -#define rninstr Perl_rninstr -#define runops Perl_runops -#define same_dirent Perl_same_dirent -#define save_I32 Perl_save_I32 -#define save_aptr Perl_save_aptr -#define save_ary Perl_save_ary -#define save_clearsv Perl_save_clearsv -#define save_delete Perl_save_delete -#define save_destructor Perl_save_destructor -#define save_freeop Perl_save_freeop -#define save_freepv Perl_save_freepv -#define save_freesv Perl_save_freesv -#define save_hash Perl_save_hash -#define save_hptr Perl_save_hptr -#define save_int Perl_save_int -#define save_item Perl_save_item -#define save_list Perl_save_list -#define save_long Perl_save_long -#define save_nogv Perl_save_nogv -#define save_pptr Perl_save_pptr -#define save_scalar Perl_save_scalar -#define save_sptr Perl_save_sptr -#define save_svref Perl_save_svref -#define savepv Perl_savepv -#define savepvn Perl_savepvn -#define savestack_grow Perl_savestack_grow -#define sawparens Perl_sawparens -#define scalar Perl_scalar -#define scalarkids Perl_scalarkids -#define scalarseq Perl_scalarseq -#define scalarvoid Perl_scalarvoid -#define scan_const Perl_scan_const -#define scan_formline Perl_scan_formline -#define scan_heredoc Perl_scan_heredoc -#define scan_hex Perl_scan_hex -#define scan_ident Perl_scan_ident +#define magic_freedefelem Perl_magic_freedefelem +#define magic_get Perl_magic_get +#define magic_getarylen Perl_magic_getarylen +#define magic_getdefelem Perl_magic_getdefelem +#define magic_getglob Perl_magic_getglob +#define magic_getpack Perl_magic_getpack +#define magic_getpos Perl_magic_getpos +#define magic_getsig Perl_magic_getsig +#define magic_gettaint Perl_magic_gettaint +#define magic_getuvar Perl_magic_getuvar +#define magic_len Perl_magic_len +#define magic_nextpack Perl_magic_nextpack +#define magic_set Perl_magic_set +#define magic_set_all_env Perl_magic_set_all_env +#define magic_setamagic Perl_magic_setamagic +#define magic_setarylen Perl_magic_setarylen +#define magic_setbm Perl_magic_setbm +#define magic_setcollxfrm Perl_magic_setcollxfrm +#define magic_setdbline Perl_magic_setdbline +#define magic_setdefelem Perl_magic_setdefelem +#define magic_setenv Perl_magic_setenv +#define magic_setfm Perl_magic_setfm +#define magic_setglob Perl_magic_setglob +#define magic_setisa Perl_magic_setisa +#define magic_setmglob Perl_magic_setmglob +#define magic_setnkeys Perl_magic_setnkeys +#define magic_setpack Perl_magic_setpack +#define magic_setpos Perl_magic_setpos +#define magic_setsig Perl_magic_setsig +#define magic_setsubstr Perl_magic_setsubstr +#define magic_settaint Perl_magic_settaint +#define magic_setuvar Perl_magic_setuvar +#define magic_setvec Perl_magic_setvec +#define magic_wipepack Perl_magic_wipepack +#define magicname Perl_magicname +#define markstack Perl_markstack +#define markstack_grow Perl_markstack_grow +#define markstack_max Perl_markstack_max +#define markstack_ptr Perl_markstack_ptr +#define max_intro_pending Perl_max_intro_pending +#define maxo Perl_maxo +#define mem_collxfrm Perl_mem_collxfrm +#define mess Perl_mess +#define mg_clear Perl_mg_clear +#define mg_copy Perl_mg_copy +#define mg_find Perl_mg_find +#define mg_free Perl_mg_free +#define mg_get Perl_mg_get +#define mg_len Perl_mg_len +#define mg_magical Perl_mg_magical +#define mg_set Perl_mg_set +#define min_intro_pending Perl_min_intro_pending +#define mod Perl_mod +#define mod_amg Perl_mod_amg +#define mod_ass_amg Perl_mod_ass_amg +#define modkids Perl_modkids +#define moreswitches Perl_moreswitches +#define mstats Perl_mstats +#define mult_amg Perl_mult_amg +#define mult_ass_amg Perl_mult_ass_amg +#define multi_close Perl_multi_close +#define multi_end Perl_multi_end +#define multi_open Perl_multi_open +#define multi_start Perl_multi_start +#define my Perl_my +#define my_bcopy Perl_my_bcopy +#define my_bzero Perl_my_bzero +#define my_chsize Perl_my_chsize +#define my_exit Perl_my_exit +#define my_failure_exit Perl_my_failure_exit +#define my_htonl Perl_my_htonl +#define my_lstat Perl_my_lstat +#define my_memcmp Perl_my_memcmp +#define my_memset Perl_my_memset +#define my_ntohl Perl_my_ntohl +#define my_pclose Perl_my_pclose +#define my_popen Perl_my_popen +#define my_setenv Perl_my_setenv +#define my_stat Perl_my_stat +#define my_swap Perl_my_swap +#define my_unexec Perl_my_unexec +#define na Perl_na +#define ncmp_amg Perl_ncmp_amg +#define ne_amg Perl_ne_amg +#define neg_amg Perl_neg_amg +#define newANONHASH Perl_newANONHASH +#define newANONLIST Perl_newANONLIST +#define newANONSUB Perl_newANONSUB +#define newASSIGNOP Perl_newASSIGNOP +#define newAV Perl_newAV +#define newAVREF Perl_newAVREF +#define newBINOP Perl_newBINOP +#define newCONDOP Perl_newCONDOP +#define newCVREF Perl_newCVREF +#define newFORM Perl_newFORM +#define newFOROP Perl_newFOROP +#define newGVOP Perl_newGVOP +#define newGVREF Perl_newGVREF +#define newGVgen Perl_newGVgen +#define newHV Perl_newHV +#define newHVREF Perl_newHVREF +#define newIO Perl_newIO +#define newLISTOP Perl_newLISTOP +#define newLOGOP Perl_newLOGOP +#define newLOOPEX Perl_newLOOPEX +#define newLOOPOP Perl_newLOOPOP +#define newNULLLIST Perl_newNULLLIST +#define newOP Perl_newOP +#define newPMOP Perl_newPMOP +#define newPROG Perl_newPROG +#define newPVOP Perl_newPVOP +#define newRANGE Perl_newRANGE +#define newRV Perl_newRV +#define newSLICEOP Perl_newSLICEOP +#define newSTATEOP Perl_newSTATEOP +#define newSUB Perl_newSUB +#define newSV Perl_newSV +#define newSVOP Perl_newSVOP +#define newSVREF Perl_newSVREF +#define newSViv Perl_newSViv +#define newSVnv Perl_newSVnv +#define newSVpv Perl_newSVpv +#define newSVpvf Perl_newSVpvf +#define newSVrv Perl_newSVrv +#define newSVsv Perl_newSVsv +#define newUNOP Perl_newUNOP +#define newWHILEOP Perl_newWHILEOP +#define newXS Perl_newXS +#define newXSUB Perl_newXSUB +#define nextargv Perl_nextargv +#define nexttoke Perl_nexttoke +#define nexttype Perl_nexttype +#define nextval Perl_nextval +#define ninstr Perl_ninstr +#define no_aelem Perl_no_aelem +#define no_dir_func Perl_no_dir_func +#define no_fh_allowed Perl_no_fh_allowed +#define no_func Perl_no_func +#define no_helem Perl_no_helem +#define no_mem Perl_no_mem +#define no_modify Perl_no_modify +#define no_op Perl_no_op +#define no_security Perl_no_security +#define no_sock_func Perl_no_sock_func +#define no_usym Perl_no_usym +#define nointrp Perl_nointrp +#define nomem Perl_nomem +#define nomemok Perl_nomemok +#define nomethod_amg Perl_nomethod_amg +#define not_amg Perl_not_amg +#define numer_amg Perl_numer_amg +#define numeric_local Perl_numeric_local +#define numeric_name Perl_numeric_name +#define numeric_standard Perl_numeric_standard +#define oldbufptr Perl_oldbufptr +#define oldoldbufptr Perl_oldoldbufptr +#define oopsAV Perl_oopsAV +#define oopsCV Perl_oopsCV +#define oopsHV Perl_oopsHV +#define op Perl_op +#define op_desc Perl_op_desc +#define op_free Perl_op_free +#define op_name Perl_op_name +#define op_seqmax Perl_op_seqmax +#define opargs Perl_opargs +#define origalen Perl_origalen +#define origenviron Perl_origenviron +#define osname Perl_osname +#define package Perl_package +#define pad_alloc Perl_pad_alloc +#define pad_allocmy Perl_pad_allocmy +#define pad_findmy Perl_pad_findmy +#define pad_free Perl_pad_free +#define pad_leavemy Perl_pad_leavemy +#define pad_reset Perl_pad_reset +#define pad_sv Perl_pad_sv +#define pad_swipe Perl_pad_swipe +#define padix Perl_padix +#define patleave Perl_patleave +#define peep Perl_peep +#define pidgone Perl_pidgone +#define pidstatus Perl_pidstatus +#define pmflag Perl_pmflag +#define pmruntime Perl_pmruntime +#define pmtrans Perl_pmtrans +#define pop_return Perl_pop_return +#define pop_scope Perl_pop_scope +#define pow_amg Perl_pow_amg +#define pow_ass_amg Perl_pow_ass_amg +#define pp_aassign Perl_pp_aassign +#define pp_abs Perl_pp_abs +#define pp_accept Perl_pp_accept +#define pp_add Perl_pp_add +#define pp_aelem Perl_pp_aelem +#define pp_aelemfast Perl_pp_aelemfast +#define pp_alarm Perl_pp_alarm +#define pp_and Perl_pp_and +#define pp_andassign Perl_pp_andassign +#define pp_anoncode Perl_pp_anoncode +#define pp_anonhash Perl_pp_anonhash +#define pp_anonlist Perl_pp_anonlist +#define pp_aslice Perl_pp_aslice +#define pp_atan2 Perl_pp_atan2 +#define pp_av2arylen Perl_pp_av2arylen +#define pp_backtick Perl_pp_backtick +#define pp_bind Perl_pp_bind +#define pp_binmode Perl_pp_binmode +#define pp_bit_and Perl_pp_bit_and +#define pp_bit_or Perl_pp_bit_or +#define pp_bit_xor Perl_pp_bit_xor +#define pp_bless Perl_pp_bless +#define pp_caller Perl_pp_caller +#define pp_chdir Perl_pp_chdir +#define pp_chmod Perl_pp_chmod +#define pp_chomp Perl_pp_chomp +#define pp_chop Perl_pp_chop +#define pp_chown Perl_pp_chown +#define pp_chr Perl_pp_chr +#define pp_chroot Perl_pp_chroot +#define pp_close Perl_pp_close +#define pp_closedir Perl_pp_closedir +#define pp_complement Perl_pp_complement +#define pp_concat Perl_pp_concat +#define pp_cond_expr Perl_pp_cond_expr +#define pp_connect Perl_pp_connect +#define pp_const Perl_pp_const +#define pp_cos Perl_pp_cos +#define pp_crypt Perl_pp_crypt +#define pp_cswitch Perl_pp_cswitch +#define pp_dbmclose Perl_pp_dbmclose +#define pp_dbmopen Perl_pp_dbmopen +#define pp_dbstate Perl_pp_dbstate +#define pp_defined Perl_pp_defined +#define pp_delete Perl_pp_delete +#define pp_die Perl_pp_die +#define pp_divide Perl_pp_divide +#define pp_dofile Perl_pp_dofile +#define pp_dump Perl_pp_dump +#define pp_each Perl_pp_each +#define pp_egrent Perl_pp_egrent +#define pp_ehostent Perl_pp_ehostent +#define pp_enetent Perl_pp_enetent +#define pp_enter Perl_pp_enter +#define pp_entereval Perl_pp_entereval +#define pp_enteriter Perl_pp_enteriter +#define pp_enterloop Perl_pp_enterloop +#define pp_entersub Perl_pp_entersub +#define pp_entersubr Perl_pp_entersubr +#define pp_entertry Perl_pp_entertry +#define pp_enterwrite Perl_pp_enterwrite +#define pp_eof Perl_pp_eof +#define pp_eprotoent Perl_pp_eprotoent +#define pp_epwent Perl_pp_epwent +#define pp_eq Perl_pp_eq +#define pp_eservent Perl_pp_eservent +#define pp_evalonce Perl_pp_evalonce +#define pp_exec Perl_pp_exec +#define pp_exists Perl_pp_exists +#define pp_exit Perl_pp_exit +#define pp_exp Perl_pp_exp +#define pp_fcntl Perl_pp_fcntl +#define pp_fileno Perl_pp_fileno +#define pp_flip Perl_pp_flip +#define pp_flock Perl_pp_flock +#define pp_flop Perl_pp_flop +#define pp_fork Perl_pp_fork +#define pp_formline Perl_pp_formline +#define pp_ftatime Perl_pp_ftatime +#define pp_ftbinary Perl_pp_ftbinary +#define pp_ftblk Perl_pp_ftblk +#define pp_ftchr Perl_pp_ftchr +#define pp_ftctime Perl_pp_ftctime +#define pp_ftdir Perl_pp_ftdir +#define pp_fteexec Perl_pp_fteexec +#define pp_fteowned Perl_pp_fteowned +#define pp_fteread Perl_pp_fteread +#define pp_ftewrite Perl_pp_ftewrite +#define pp_ftfile Perl_pp_ftfile +#define pp_ftis Perl_pp_ftis +#define pp_ftlink Perl_pp_ftlink +#define pp_ftmtime Perl_pp_ftmtime +#define pp_ftpipe Perl_pp_ftpipe +#define pp_ftrexec Perl_pp_ftrexec +#define pp_ftrowned Perl_pp_ftrowned +#define pp_ftrread Perl_pp_ftrread +#define pp_ftrwrite Perl_pp_ftrwrite +#define pp_ftsgid Perl_pp_ftsgid +#define pp_ftsize Perl_pp_ftsize +#define pp_ftsock Perl_pp_ftsock +#define pp_ftsuid Perl_pp_ftsuid +#define pp_ftsvtx Perl_pp_ftsvtx +#define pp_fttext Perl_pp_fttext +#define pp_fttty Perl_pp_fttty +#define pp_ftzero Perl_pp_ftzero +#define pp_ge Perl_pp_ge +#define pp_gelem Perl_pp_gelem +#define pp_getc Perl_pp_getc +#define pp_getlogin Perl_pp_getlogin +#define pp_getpeername Perl_pp_getpeername +#define pp_getpgrp Perl_pp_getpgrp +#define pp_getppid Perl_pp_getppid +#define pp_getpriority Perl_pp_getpriority +#define pp_getsockname Perl_pp_getsockname +#define pp_ggrent Perl_pp_ggrent +#define pp_ggrgid Perl_pp_ggrgid +#define pp_ggrnam Perl_pp_ggrnam +#define pp_ghbyaddr Perl_pp_ghbyaddr +#define pp_ghbyname Perl_pp_ghbyname +#define pp_ghostent Perl_pp_ghostent +#define pp_glob Perl_pp_glob +#define pp_gmtime Perl_pp_gmtime +#define pp_gnbyaddr Perl_pp_gnbyaddr +#define pp_gnbyname Perl_pp_gnbyname +#define pp_gnetent Perl_pp_gnetent +#define pp_goto Perl_pp_goto +#define pp_gpbyname Perl_pp_gpbyname +#define pp_gpbynumber Perl_pp_gpbynumber +#define pp_gprotoent Perl_pp_gprotoent +#define pp_gpwent Perl_pp_gpwent +#define pp_gpwnam Perl_pp_gpwnam +#define pp_gpwuid Perl_pp_gpwuid +#define pp_grepstart Perl_pp_grepstart +#define pp_grepwhile Perl_pp_grepwhile +#define pp_gsbyname Perl_pp_gsbyname +#define pp_gsbyport Perl_pp_gsbyport +#define pp_gservent Perl_pp_gservent +#define pp_gsockopt Perl_pp_gsockopt +#define pp_gt Perl_pp_gt +#define pp_gv Perl_pp_gv +#define pp_gvsv Perl_pp_gvsv +#define pp_helem Perl_pp_helem +#define pp_hex Perl_pp_hex +#define pp_hslice Perl_pp_hslice +#define pp_i_add Perl_pp_i_add +#define pp_i_divide Perl_pp_i_divide +#define pp_i_eq Perl_pp_i_eq +#define pp_i_ge Perl_pp_i_ge +#define pp_i_gt Perl_pp_i_gt +#define pp_i_le Perl_pp_i_le +#define pp_i_lt Perl_pp_i_lt +#define pp_i_modulo Perl_pp_i_modulo +#define pp_i_multiply Perl_pp_i_multiply +#define pp_i_ncmp Perl_pp_i_ncmp +#define pp_i_ne Perl_pp_i_ne +#define pp_i_negate Perl_pp_i_negate +#define pp_i_subtract Perl_pp_i_subtract +#define pp_index Perl_pp_index +#define pp_indread Perl_pp_indread +#define pp_int Perl_pp_int +#define pp_interp Perl_pp_interp +#define pp_ioctl Perl_pp_ioctl +#define pp_iter Perl_pp_iter +#define pp_join Perl_pp_join +#define pp_keys Perl_pp_keys +#define pp_kill Perl_pp_kill +#define pp_last Perl_pp_last +#define pp_lc Perl_pp_lc +#define pp_lcfirst Perl_pp_lcfirst +#define pp_le Perl_pp_le +#define pp_leave Perl_pp_leave +#define pp_leaveeval Perl_pp_leaveeval +#define pp_leaveloop Perl_pp_leaveloop +#define pp_leavesub Perl_pp_leavesub +#define pp_leavetry Perl_pp_leavetry +#define pp_leavewrite Perl_pp_leavewrite +#define pp_left_shift Perl_pp_left_shift +#define pp_length Perl_pp_length +#define pp_lineseq Perl_pp_lineseq +#define pp_link Perl_pp_link +#define pp_list Perl_pp_list +#define pp_listen Perl_pp_listen +#define pp_localtime Perl_pp_localtime +#define pp_log Perl_pp_log +#define pp_lslice Perl_pp_lslice +#define pp_lstat Perl_pp_lstat +#define pp_lt Perl_pp_lt +#define pp_map Perl_pp_map +#define pp_mapstart Perl_pp_mapstart +#define pp_mapwhile Perl_pp_mapwhile +#define pp_match Perl_pp_match +#define pp_method Perl_pp_method +#define pp_mkdir Perl_pp_mkdir +#define pp_modulo Perl_pp_modulo +#define pp_msgctl Perl_pp_msgctl +#define pp_msgget Perl_pp_msgget +#define pp_msgrcv Perl_pp_msgrcv +#define pp_msgsnd Perl_pp_msgsnd +#define pp_multiply Perl_pp_multiply +#define pp_ncmp Perl_pp_ncmp +#define pp_ne Perl_pp_ne +#define pp_negate Perl_pp_negate +#define pp_next Perl_pp_next +#define pp_nextstate Perl_pp_nextstate +#define pp_not Perl_pp_not +#define pp_nswitch Perl_pp_nswitch +#define pp_null Perl_pp_null +#define pp_oct Perl_pp_oct +#define pp_open Perl_pp_open +#define pp_open_dir Perl_pp_open_dir +#define pp_or Perl_pp_or +#define pp_orassign Perl_pp_orassign +#define pp_ord Perl_pp_ord +#define pp_pack Perl_pp_pack +#define pp_padany Perl_pp_padany +#define pp_padav Perl_pp_padav +#define pp_padhv Perl_pp_padhv +#define pp_padsv Perl_pp_padsv +#define pp_pipe_op Perl_pp_pipe_op +#define pp_pop Perl_pp_pop +#define pp_pos Perl_pp_pos +#define pp_postdec Perl_pp_postdec +#define pp_postinc Perl_pp_postinc +#define pp_pow Perl_pp_pow +#define pp_predec Perl_pp_predec +#define pp_preinc Perl_pp_preinc +#define pp_print Perl_pp_print +#define pp_prototype Perl_pp_prototype +#define pp_prtf Perl_pp_prtf +#define pp_push Perl_pp_push +#define pp_pushmark Perl_pp_pushmark +#define pp_pushre Perl_pp_pushre +#define pp_quotemeta Perl_pp_quotemeta +#define pp_rand Perl_pp_rand +#define pp_range Perl_pp_range +#define pp_rcatline Perl_pp_rcatline +#define pp_read Perl_pp_read +#define pp_readdir Perl_pp_readdir +#define pp_readline Perl_pp_readline +#define pp_readlink Perl_pp_readlink +#define pp_recv Perl_pp_recv +#define pp_redo Perl_pp_redo +#define pp_ref Perl_pp_ref +#define pp_refgen Perl_pp_refgen +#define pp_regcmaybe Perl_pp_regcmaybe +#define pp_regcomp Perl_pp_regcomp +#define pp_rename Perl_pp_rename +#define pp_repeat Perl_pp_repeat +#define pp_require Perl_pp_require +#define pp_reset Perl_pp_reset +#define pp_return Perl_pp_return +#define pp_reverse Perl_pp_reverse +#define pp_rewinddir Perl_pp_rewinddir +#define pp_right_shift Perl_pp_right_shift +#define pp_rindex Perl_pp_rindex +#define pp_rmdir Perl_pp_rmdir +#define pp_rv2av Perl_pp_rv2av +#define pp_rv2cv Perl_pp_rv2cv +#define pp_rv2gv Perl_pp_rv2gv +#define pp_rv2hv Perl_pp_rv2hv +#define pp_rv2sv Perl_pp_rv2sv +#define pp_sassign Perl_pp_sassign +#define pp_scalar Perl_pp_scalar +#define pp_schomp Perl_pp_schomp +#define pp_schop Perl_pp_schop +#define pp_scmp Perl_pp_scmp +#define pp_scope Perl_pp_scope +#define pp_seek Perl_pp_seek +#define pp_seekdir Perl_pp_seekdir +#define pp_select Perl_pp_select +#define pp_semctl Perl_pp_semctl +#define pp_semget Perl_pp_semget +#define pp_semop Perl_pp_semop +#define pp_send Perl_pp_send +#define pp_seq Perl_pp_seq +#define pp_setpgrp Perl_pp_setpgrp +#define pp_setpriority Perl_pp_setpriority +#define pp_sge Perl_pp_sge +#define pp_sgrent Perl_pp_sgrent +#define pp_sgt Perl_pp_sgt +#define pp_shift Perl_pp_shift +#define pp_shmctl Perl_pp_shmctl +#define pp_shmget Perl_pp_shmget +#define pp_shmread Perl_pp_shmread +#define pp_shmwrite Perl_pp_shmwrite +#define pp_shostent Perl_pp_shostent +#define pp_shutdown Perl_pp_shutdown +#define pp_sin Perl_pp_sin +#define pp_sle Perl_pp_sle +#define pp_sleep Perl_pp_sleep +#define pp_slt Perl_pp_slt +#define pp_sne Perl_pp_sne +#define pp_snetent Perl_pp_snetent +#define pp_socket Perl_pp_socket +#define pp_sockpair Perl_pp_sockpair +#define pp_sort Perl_pp_sort +#define pp_splice Perl_pp_splice +#define pp_split Perl_pp_split +#define pp_sprintf Perl_pp_sprintf +#define pp_sprotoent Perl_pp_sprotoent +#define pp_spwent Perl_pp_spwent +#define pp_sqrt Perl_pp_sqrt +#define pp_srand Perl_pp_srand +#define pp_srefgen Perl_pp_srefgen +#define pp_sselect Perl_pp_sselect +#define pp_sservent Perl_pp_sservent +#define pp_ssockopt Perl_pp_ssockopt +#define pp_stat Perl_pp_stat +#define pp_stringify Perl_pp_stringify +#define pp_stub Perl_pp_stub +#define pp_study Perl_pp_study +#define pp_subst Perl_pp_subst +#define pp_substcont Perl_pp_substcont +#define pp_substr Perl_pp_substr +#define pp_subtract Perl_pp_subtract +#define pp_symlink Perl_pp_symlink +#define pp_syscall Perl_pp_syscall +#define pp_sysopen Perl_pp_sysopen +#define pp_sysread Perl_pp_sysread +#define pp_sysseek Perl_pp_sysseek +#define pp_system Perl_pp_system +#define pp_syswrite Perl_pp_syswrite +#define pp_tell Perl_pp_tell +#define pp_telldir Perl_pp_telldir +#define pp_tie Perl_pp_tie +#define pp_tied Perl_pp_tied +#define pp_time Perl_pp_time +#define pp_tms Perl_pp_tms +#define pp_trans Perl_pp_trans +#define pp_truncate Perl_pp_truncate +#define pp_uc Perl_pp_uc +#define pp_ucfirst Perl_pp_ucfirst +#define pp_umask Perl_pp_umask +#define pp_undef Perl_pp_undef +#define pp_unlink Perl_pp_unlink +#define pp_unpack Perl_pp_unpack +#define pp_unshift Perl_pp_unshift +#define pp_unstack Perl_pp_unstack +#define pp_untie Perl_pp_untie +#define pp_utime Perl_pp_utime +#define pp_values Perl_pp_values +#define pp_vec Perl_pp_vec +#define pp_wait Perl_pp_wait +#define pp_waitpid Perl_pp_waitpid +#define pp_wantarray Perl_pp_wantarray +#define pp_warn Perl_pp_warn +#define pp_xor Perl_pp_xor +#define ppaddr Perl_ppaddr +#define pregcomp Perl_pregcomp +#define pregexec Perl_pregexec +#define pregfree Perl_pregfree +#define prepend_elem Perl_prepend_elem +#define profiledata Perl_profiledata +#define psig_name Perl_psig_name +#define psig_ptr Perl_psig_ptr +#define push_return Perl_push_return +#define push_scope Perl_push_scope +#define q Perl_q +#define rcsid Perl_rcsid +#define reall_srchlen Perl_reall_srchlen +#define ref Perl_ref +#define refkids Perl_refkids +#define regarglen Perl_regarglen +#define regbol Perl_regbol +#define regcode Perl_regcode +#define regdummy Perl_regdummy +#define regdump Perl_regdump +#define regendp Perl_regendp +#define regeol Perl_regeol +#define reginput Perl_reginput +#define regkind Perl_regkind +#define reglastparen Perl_reglastparen +#define regmyendp Perl_regmyendp +#define regmyp_size Perl_regmyp_size +#define regmystartp Perl_regmystartp +#define regnarrate Perl_regnarrate +#define regnaughty Perl_regnaughty +#define regnext Perl_regnext +#define regnpar Perl_regnpar +#define regparse Perl_regparse +#define regprecomp Perl_regprecomp +#define regprev Perl_regprev +#define regprop Perl_regprop +#define regsawback Perl_regsawback +#define regsize Perl_regsize +#define regstartp Perl_regstartp +#define regtill Perl_regtill +#define regxend Perl_regxend +#define repeat_amg Perl_repeat_amg +#define repeat_ass_amg Perl_repeat_ass_amg +#define repeatcpy Perl_repeatcpy +#define retstack Perl_retstack +#define retstack_ix Perl_retstack_ix +#define retstack_max Perl_retstack_max +#define rninstr Perl_rninstr +#define rsfp Perl_rsfp +#define rsfp_filters Perl_rsfp_filters +#define rshift_amg Perl_rshift_amg +#define rshift_ass_amg Perl_rshift_ass_amg +#define rsignal Perl_rsignal +#define rsignal_restore Perl_rsignal_restore +#define rsignal_save Perl_rsignal_save +#define rsignal_state Perl_rsignal_state +#define runops Perl_runops +#define rxres_free Perl_rxres_free +#define rxres_restore Perl_rxres_restore +#define rxres_save Perl_rxres_save +#define same_dirent Perl_same_dirent +#define save_I16 Perl_save_I16 +#define save_I32 Perl_save_I32 +#define save_aptr Perl_save_aptr +#define save_ary Perl_save_ary +#define save_clearsv Perl_save_clearsv +#define save_delete Perl_save_delete +#define save_destructor Perl_save_destructor +#define save_freeop Perl_save_freeop +#define save_freepv Perl_save_freepv +#define save_freesv Perl_save_freesv +#define save_gp Perl_save_gp +#define save_hash Perl_save_hash +#define save_hptr Perl_save_hptr +#define save_int Perl_save_int +#define save_item Perl_save_item +#define save_list Perl_save_list +#define save_long Perl_save_long +#define save_nogv Perl_save_nogv +#define save_pptr Perl_save_pptr +#define save_scalar Perl_save_scalar +#define save_sptr Perl_save_sptr +#define save_svref Perl_save_svref +#define savepv Perl_savepv +#define savepvn Perl_savepvn +#define savestack Perl_savestack +#define savestack_grow Perl_savestack_grow +#define savestack_ix Perl_savestack_ix +#define savestack_max Perl_savestack_max +#define saw_return Perl_saw_return +#define sawparens Perl_sawparens +#define scalar Perl_scalar +#define scalarkids Perl_scalarkids +#define scalarseq Perl_scalarseq +#define scalarvoid Perl_scalarvoid +#define scan_const Perl_scan_const +#define scan_formline Perl_scan_formline +#define scan_heredoc Perl_scan_heredoc +#define scan_hex Perl_scan_hex +#define scan_ident Perl_scan_ident #define scan_inputsymbol Perl_scan_inputsymbol -#define scan_num Perl_scan_num -#define scan_oct Perl_scan_oct -#define scan_pat Perl_scan_pat -#define scan_prefix Perl_scan_prefix -#define scan_str Perl_scan_str -#define scan_subst Perl_scan_subst -#define scan_trans Perl_scan_trans -#define scan_word Perl_scan_word -#define scope Perl_scope -#define screaminstr Perl_screaminstr -#define setdefout Perl_setdefout -#define setenv_getix Perl_setenv_getix -#define sighandler Perl_sighandler -#define skipspace Perl_skipspace -#define stack_grow Perl_stack_grow -#define start_subparse Perl_start_subparse -#define sublex_done Perl_sublex_done -#define sublex_start Perl_sublex_start -#define sv_2bool Perl_sv_2bool -#define sv_2cv Perl_sv_2cv -#define sv_2io Perl_sv_2io -#define sv_2iv Perl_sv_2iv -#define sv_2mortal Perl_sv_2mortal -#define sv_2nv Perl_sv_2nv -#define sv_2pv Perl_sv_2pv -#define sv_add_arena Perl_sv_add_arena -#define sv_backoff Perl_sv_backoff -#define sv_bless Perl_sv_bless -#define sv_catpv Perl_sv_catpv -#define sv_catpvn Perl_sv_catpvn -#define sv_catsv Perl_sv_catsv -#define sv_chop Perl_sv_chop -#define sv_clean_all Perl_sv_clean_all -#define sv_clean_objs Perl_sv_clean_objs -#define sv_clear Perl_sv_clear -#define sv_cmp Perl_sv_cmp -#define sv_dec Perl_sv_dec -#define sv_dump Perl_sv_dump -#define sv_eq Perl_sv_eq -#define sv_free Perl_sv_free -#define sv_free_arenas Perl_sv_free_arenas -#define sv_gets Perl_sv_gets -#define sv_grow Perl_sv_grow -#define sv_inc Perl_sv_inc -#define sv_insert Perl_sv_insert -#define sv_isa Perl_sv_isa -#define sv_isobject Perl_sv_isobject -#define sv_len Perl_sv_len -#define sv_magic Perl_sv_magic -#define sv_mortalcopy Perl_sv_mortalcopy -#define sv_newmortal Perl_sv_newmortal -#define sv_newref Perl_sv_newref -#define sv_peek Perl_sv_peek -#define sv_pvn_force Perl_sv_pvn_force -#define sv_ref Perl_sv_ref -#define sv_reftype Perl_sv_reftype -#define sv_replace Perl_sv_replace -#define sv_report_used Perl_sv_report_used -#define sv_reset Perl_sv_reset -#define sv_setiv Perl_sv_setiv -#define sv_setnv Perl_sv_setnv -#define sv_setptrobj Perl_sv_setptrobj -#define sv_setpv Perl_sv_setpv -#define sv_setpvn Perl_sv_setpvn -#define sv_setref_iv Perl_sv_setref_iv -#define sv_setref_nv Perl_sv_setref_nv -#define sv_setref_pv Perl_sv_setref_pv -#define sv_setref_pvn Perl_sv_setref_pvn -#define sv_setsv Perl_sv_setsv -#define sv_unmagic Perl_sv_unmagic -#define sv_unref Perl_sv_unref -#define sv_upgrade Perl_sv_upgrade -#define sv_usepvn Perl_sv_usepvn -#define taint_env Perl_taint_env -#define taint_not Perl_taint_not -#define taint_proper Perl_taint_proper +#define scan_num Perl_scan_num +#define scan_oct Perl_scan_oct +#define scan_pat Perl_scan_pat +#define scan_prefix Perl_scan_prefix +#define scan_str Perl_scan_str +#define scan_subst Perl_scan_subst +#define scan_trans Perl_scan_trans +#define scan_word Perl_scan_word +#define scmp_amg Perl_scmp_amg +#define scope Perl_scope +#define scopestack Perl_scopestack +#define scopestack_ix Perl_scopestack_ix +#define scopestack_max Perl_scopestack_max +#define screaminstr Perl_screaminstr +#define scrgv Perl_scrgv +#define seq_amg Perl_seq_amg +#define setdefout Perl_setdefout +#define setenv_getix Perl_setenv_getix +#define sge_amg Perl_sge_amg +#define sgt_amg Perl_sgt_amg +#define sh_path Perl_sh_path +#define share_hek Perl_share_hek +#define sharepvn Perl_sharepvn +#define sig_name Perl_sig_name +#define sig_num Perl_sig_num +#define sighandler Perl_sighandler +#define simple Perl_simple +#define sin_amg Perl_sin_amg +#define skipspace Perl_skipspace +#define sle_amg Perl_sle_amg +#define slt_amg Perl_slt_amg +#define sne_amg Perl_sne_amg +#define sqrt_amg Perl_sqrt_amg +#define stack_base Perl_stack_base +#define stack_grow Perl_stack_grow +#define stack_max Perl_stack_max +#define stack_sp Perl_stack_sp +#define start_subparse Perl_start_subparse +#define statbuf Perl_statbuf +#define string_amg Perl_string_amg +#define sub_crush_depth Perl_sub_crush_depth +#define sub_generation Perl_sub_generation +#define subline Perl_subline +#define subname Perl_subname +#define subtr_amg Perl_subtr_amg +#define subtr_ass_amg Perl_subtr_ass_amg +#define sv_2bool Perl_sv_2bool +#define sv_2cv Perl_sv_2cv +#define sv_2io Perl_sv_2io +#define sv_2iv Perl_sv_2iv +#define sv_2mortal Perl_sv_2mortal +#define sv_2nv Perl_sv_2nv +#define sv_2pv Perl_sv_2pv +#define sv_2uv Perl_sv_2uv +#define sv_add_arena Perl_sv_add_arena +#define sv_backoff Perl_sv_backoff +#define sv_bless Perl_sv_bless +#define sv_catpv Perl_sv_catpv +#define sv_catpvf Perl_sv_catpvf +#define sv_catpvn Perl_sv_catpvn +#define sv_catsv Perl_sv_catsv +#define sv_chop Perl_sv_chop +#define sv_clean_all Perl_sv_clean_all +#define sv_clean_objs Perl_sv_clean_objs +#define sv_clear Perl_sv_clear +#define sv_cmp Perl_sv_cmp +#define sv_cmp_locale Perl_sv_cmp_locale +#define sv_collxfrm Perl_sv_collxfrm +#define sv_dec Perl_sv_dec +#define sv_derived_from Perl_sv_derived_from +#define sv_dump Perl_sv_dump +#define sv_eq Perl_sv_eq +#define sv_free Perl_sv_free +#define sv_free_arenas Perl_sv_free_arenas +#define sv_gets Perl_sv_gets +#define sv_grow Perl_sv_grow +#define sv_inc Perl_sv_inc +#define sv_insert Perl_sv_insert +#define sv_isa Perl_sv_isa +#define sv_isobject Perl_sv_isobject +#define sv_len Perl_sv_len +#define sv_magic Perl_sv_magic +#define sv_mortalcopy Perl_sv_mortalcopy +#define sv_newmortal Perl_sv_newmortal +#define sv_newref Perl_sv_newref +#define sv_no Perl_sv_no +#define sv_peek Perl_sv_peek +#define sv_pvn_force Perl_sv_pvn_force +#define sv_ref Perl_sv_ref +#define sv_reftype Perl_sv_reftype +#define sv_replace Perl_sv_replace +#define sv_report_used Perl_sv_report_used +#define sv_reset Perl_sv_reset +#define sv_setiv Perl_sv_setiv +#define sv_setnv Perl_sv_setnv +#define sv_setptrobj Perl_sv_setptrobj +#define sv_setpv Perl_sv_setpv +#define sv_setpvf Perl_sv_setpvf +#define sv_setpviv Perl_sv_setpviv +#define sv_setpvn Perl_sv_setpvn +#define sv_setref_iv Perl_sv_setref_iv +#define sv_setref_nv Perl_sv_setref_nv +#define sv_setref_pv Perl_sv_setref_pv +#define sv_setref_pvn Perl_sv_setref_pvn +#define sv_setsv Perl_sv_setsv +#define sv_setuv Perl_sv_setuv +#define sv_taint Perl_sv_taint +#define sv_tainted Perl_sv_tainted +#define sv_undef Perl_sv_undef +#define sv_unmagic Perl_sv_unmagic +#define sv_unref Perl_sv_unref +#define sv_untaint Perl_sv_untaint +#define sv_upgrade Perl_sv_upgrade +#define sv_usepvn Perl_sv_usepvn +#define sv_vcatpvfn Perl_sv_vcatpvfn +#define sv_vsetpvfn Perl_sv_vsetpvfn +#define sv_yes Perl_sv_yes +#define taint_env Perl_taint_env +#define taint_proper Perl_taint_proper +#define thisexpr Perl_thisexpr +#define timesbuf Perl_timesbuf +#define tokenbuf Perl_tokenbuf #define too_few_arguments Perl_too_few_arguments #define too_many_arguments Perl_too_many_arguments -#define unlnk Perl_unlnk -#define utilize Perl_utilize -#define wait4pid Perl_wait4pid -#define warn Perl_warn -#define watch Perl_watch -#define whichsig Perl_whichsig -#define xiv_arenaroot Perl_xiv_arenaroot -#define xiv_root Perl_xiv_root -#define xnv_root Perl_xnv_root -#define xpv_root Perl_xpv_root -#define xrv_root Perl_xrv_root -#define yyerror Perl_yyerror -#define yylex Perl_yylex -#define yyparse Perl_yyparse -#define yywarn Perl_yywarn +#define uid Perl_uid +#define unlnk Perl_unlnk +#define unshare_hek Perl_unshare_hek +#define unsharepvn Perl_unsharepvn +#define utilize Perl_utilize +#define varies Perl_varies +#define vert Perl_vert +#define vivify_defelem Perl_vivify_defelem +#define vivify_ref Perl_vivify_ref +#define vtbl_amagic Perl_vtbl_amagic +#define vtbl_amagicelem Perl_vtbl_amagicelem +#define vtbl_arylen Perl_vtbl_arylen +#define vtbl_bm Perl_vtbl_bm +#define vtbl_collxfrm Perl_vtbl_collxfrm +#define vtbl_dbline Perl_vtbl_dbline +#define vtbl_defelem Perl_vtbl_defelem +#define vtbl_env Perl_vtbl_env +#define vtbl_envelem Perl_vtbl_envelem +#define vtbl_fm Perl_vtbl_fm +#define vtbl_glob Perl_vtbl_glob +#define vtbl_isa Perl_vtbl_isa +#define vtbl_isaelem Perl_vtbl_isaelem +#define vtbl_mglob Perl_vtbl_mglob +#define vtbl_nkeys Perl_vtbl_nkeys +#define vtbl_pack Perl_vtbl_pack +#define vtbl_packelem Perl_vtbl_packelem +#define vtbl_pos Perl_vtbl_pos +#define vtbl_sig Perl_vtbl_sig +#define vtbl_sigelem Perl_vtbl_sigelem +#define vtbl_substr Perl_vtbl_substr +#define vtbl_sv Perl_vtbl_sv +#define vtbl_taint Perl_vtbl_taint +#define vtbl_uvar Perl_vtbl_uvar +#define vtbl_vec Perl_vtbl_vec +#define wait4pid Perl_wait4pid +#define warn Perl_warn +#define warn_nl Perl_warn_nl +#define warn_nosemi Perl_warn_nosemi +#define warn_reserved Perl_warn_reserved +#define watch Perl_watch +#define watchaddr Perl_watchaddr +#define watchok Perl_watchok +#define whichsig Perl_whichsig +#define xiv_arenaroot Perl_xiv_arenaroot +#define xiv_root Perl_xiv_root +#define xnv_root Perl_xnv_root +#define xpv_root Perl_xpv_root +#define xrv_root Perl_xrv_root +#define yychar Perl_yychar +#define yycheck Perl_yycheck +#define yydebug Perl_yydebug +#define yydefred Perl_yydefred +#define yydgoto Perl_yydgoto +#define yyerrflag Perl_yyerrflag +#define yyerror Perl_yyerror +#define yygindex Perl_yygindex +#define yylen Perl_yylen +#define yylex Perl_yylex +#define yylhs Perl_yylhs +#define yylval Perl_yylval +#define yyname Perl_yyname +#define yynerrs Perl_yynerrs +#define yyparse Perl_yyparse +#define yyrindex Perl_yyrindex +#define yyrule Perl_yyrule +#define yysindex Perl_yysindex +#define yytable Perl_yytable +#define yyval Perl_yyval +#define yywarn Perl_yywarn + +/* Hide global symbols that 5.003 revealed? */ + +#ifndef BINCOMPAT3 + +#define Error Perl_Error +#define SvIV Perl_SvIV +#define SvNV Perl_SvNV +#define SvTRUE Perl_SvTRUE +#define SvUV Perl_SvUV +#define block_type Perl_block_type +#define boot_core_UNIVERSAL Perl_boot_core_UNIVERSAL +#define comppad_name_floor Perl_comppad_name_floor +#define debug Perl_debug +#define do_undump Perl_do_undump +#define nice_chunk Perl_nice_chunk +#define nice_chunk_size Perl_nice_chunk_size +#define no_myglob Perl_no_myglob +#define no_symref Perl_no_symref +#define no_wrongref Perl_no_wrongref +#define pad_reset_pending Perl_pad_reset_pending +#define padix_floor Perl_padix_floor +#define regflags Perl_regflags +#define safecalloc Perl_safecalloc +#define safefree Perl_safefree +#define safemalloc Perl_safemalloc +#define saferealloc Perl_saferealloc +#define safexcalloc Perl_safexcalloc +#define safexfree Perl_safexfree +#define safexmalloc Perl_safexmalloc +#define safexrealloc Perl_safexrealloc +#define save_iv Perl_save_iv +#define sv_pvn Perl_sv_pvn +#define warn_uninit Perl_warn_uninit +#define yydestruct Perl_yydestruct + +#endif /* !BINCOMPAT3 */ #endif /* EMBED */ -/* Put interpreter specific symbols into a struct? */ +/* Put interpreter-specific symbols into a struct? */ #ifdef MULTIPLICITY -#define Argv (curinterp->IArgv) -#define Cmd (curinterp->ICmd) -#define DBgv (curinterp->IDBgv) -#define DBline (curinterp->IDBline) -#define DBsignal (curinterp->IDBsignal) -#define DBsingle (curinterp->IDBsingle) -#define DBsub (curinterp->IDBsub) -#define DBtrace (curinterp->IDBtrace) -#define allgvs (curinterp->Iallgvs) -#define ampergv (curinterp->Iampergv) -#define argvgv (curinterp->Iargvgv) -#define argvoutgv (curinterp->Iargvoutgv) -#define basetime (curinterp->Ibasetime) -#define beginav (curinterp->Ibeginav) -#define bodytarget (curinterp->Ibodytarget) -#define cddir (curinterp->Icddir) -#define chopset (curinterp->Ichopset) -#define copline (curinterp->Icopline) -#define curblock (curinterp->Icurblock) -#define curcop (curinterp->Icurcop) -#define curcsv (curinterp->Icurcsv) -#define curpm (curinterp->Icurpm) -#define curstash (curinterp->Icurstash) -#define curstname (curinterp->Icurstname) -#define cxstack (curinterp->Icxstack) -#define cxstack_ix (curinterp->Icxstack_ix) -#define cxstack_max (curinterp->Icxstack_max) -#define dbargs (curinterp->Idbargs) -#define debdelim (curinterp->Idebdelim) -#define debname (curinterp->Idebname) -#define debstash (curinterp->Idebstash) -#define debug (curinterp->Idebug) -#define defgv (curinterp->Idefgv) -#define defoutgv (curinterp->Idefoutgv) -#define defstash (curinterp->Idefstash) -#define delaymagic (curinterp->Idelaymagic) -#define diehook (curinterp->Idiehook) -#define dirty (curinterp->Idirty) -#define dlevel (curinterp->Idlevel) -#define dlmax (curinterp->Idlmax) -#define do_undump (curinterp->Ido_undump) -#define doextract (curinterp->Idoextract) -#define doswitches (curinterp->Idoswitches) -#define dowarn (curinterp->Idowarn) -#define dumplvl (curinterp->Idumplvl) -#define e_fp (curinterp->Ie_fp) -#define e_tmpname (curinterp->Ie_tmpname) -#define endav (curinterp->Iendav) -#define envgv (curinterp->Ienvgv) -#define errgv (curinterp->Ierrgv) -#define eval_root (curinterp->Ieval_root) -#define eval_start (curinterp->Ieval_start) -#define fdpid (curinterp->Ifdpid) -#define filemode (curinterp->Ifilemode) -#define firstgv (curinterp->Ifirstgv) -#define forkprocess (curinterp->Iforkprocess) -#define formfeed (curinterp->Iformfeed) -#define formtarget (curinterp->Iformtarget) -#define gensym (curinterp->Igensym) -#define in_eval (curinterp->Iin_eval) -#define incgv (curinterp->Iincgv) -#define inplace (curinterp->Iinplace) -#define last_in_gv (curinterp->Ilast_in_gv) -#define lastfd (curinterp->Ilastfd) -#define lastretstr (curinterp->Ilastretstr) -#define lastscream (curinterp->Ilastscream) -#define lastsize (curinterp->Ilastsize) -#define lastspbase (curinterp->Ilastspbase) -#define laststatval (curinterp->Ilaststatval) -#define laststype (curinterp->Ilaststype) -#define leftgv (curinterp->Ileftgv) -#define lineary (curinterp->Ilineary) -#define localizing (curinterp->Ilocalizing) -#define main_cv (curinterp->Imain_cv) -#define main_root (curinterp->Imain_root) -#define main_start (curinterp->Imain_start) -#define mainstack (curinterp->Imainstack) -#define maxscream (curinterp->Imaxscream) -#define maxsysfd (curinterp->Imaxsysfd) -#define minus_F (curinterp->Iminus_F) -#define minus_a (curinterp->Iminus_a) -#define minus_c (curinterp->Iminus_c) -#define minus_l (curinterp->Iminus_l) -#define minus_n (curinterp->Iminus_n) -#define minus_p (curinterp->Iminus_p) -#define multiline (curinterp->Imultiline) -#define mystack_base (curinterp->Imystack_base) -#define mystack_mark (curinterp->Imystack_mark) -#define mystack_max (curinterp->Imystack_max) -#define mystack_sp (curinterp->Imystack_sp) -#define mystrk (curinterp->Imystrk) -#define nrs (curinterp->Inrs) -#define ofmt (curinterp->Iofmt) -#define ofs (curinterp->Iofs) -#define ofslen (curinterp->Iofslen) -#define oldlastpm (curinterp->Ioldlastpm) -#define oldname (curinterp->Ioldname) -#define op_mask (curinterp->Iop_mask) -#define origargc (curinterp->Iorigargc) -#define origargv (curinterp->Iorigargv) -#define origfilename (curinterp->Iorigfilename) -#define ors (curinterp->Iors) -#define orslen (curinterp->Iorslen) -#define pad (curinterp->Ipad) -#define padname (curinterp->Ipadname) -#define parsehook (curinterp->Iparsehook) -#define patchlevel (curinterp->Ipatchlevel) -#define perldb (curinterp->Iperldb) +#define Argv (curinterp->IArgv) +#define Cmd (curinterp->ICmd) +#define DBgv (curinterp->IDBgv) +#define DBline (curinterp->IDBline) +#define DBsignal (curinterp->IDBsignal) +#define DBsingle (curinterp->IDBsingle) +#define DBsub (curinterp->IDBsub) +#define DBtrace (curinterp->IDBtrace) +#define allgvs (curinterp->Iallgvs) +#define ampergv (curinterp->Iampergv) +#define argvgv (curinterp->Iargvgv) +#define argvoutgv (curinterp->Iargvoutgv) +#define basetime (curinterp->Ibasetime) +#define beginav (curinterp->Ibeginav) +#define bodytarget (curinterp->Ibodytarget) +#define cddir (curinterp->Icddir) +#define chopset (curinterp->Ichopset) +#define copline (curinterp->Icopline) +#define curblock (curinterp->Icurblock) +#define curcop (curinterp->Icurcop) +#define curcopdb (curinterp->Icurcopdb) +#define curcsv (curinterp->Icurcsv) +#define curpm (curinterp->Icurpm) +#define curstack (curinterp->Icurstack) +#define curstash (curinterp->Icurstash) +#define curstname (curinterp->Icurstname) +#define cxstack (curinterp->Icxstack) +#define cxstack_ix (curinterp->Icxstack_ix) +#define cxstack_max (curinterp->Icxstack_max) +#define dbargs (curinterp->Idbargs) +#define debdelim (curinterp->Idebdelim) +#define debname (curinterp->Idebname) +#define debstash (curinterp->Idebstash) +#define defgv (curinterp->Idefgv) +#define defoutgv (curinterp->Idefoutgv) +#define defstash (curinterp->Idefstash) +#define delaymagic (curinterp->Idelaymagic) +#define diehook (curinterp->Idiehook) +#define dirty (curinterp->Idirty) +#define dlevel (curinterp->Idlevel) +#define dlmax (curinterp->Idlmax) +#define doextract (curinterp->Idoextract) +#define doswitches (curinterp->Idoswitches) +#define dowarn (curinterp->Idowarn) +#define dumplvl (curinterp->Idumplvl) +#define e_fp (curinterp->Ie_fp) +#define e_tmpname (curinterp->Ie_tmpname) +#define endav (curinterp->Iendav) +#define envgv (curinterp->Ienvgv) +#define errgv (curinterp->Ierrgv) +#define eval_root (curinterp->Ieval_root) +#define eval_start (curinterp->Ieval_start) +#define fdpid (curinterp->Ifdpid) +#define filemode (curinterp->Ifilemode) +#define firstgv (curinterp->Ifirstgv) +#define forkprocess (curinterp->Iforkprocess) +#define formfeed (curinterp->Iformfeed) +#define formtarget (curinterp->Iformtarget) +#define gensym (curinterp->Igensym) +#define in_eval (curinterp->Iin_eval) +#define incgv (curinterp->Iincgv) +#define inplace (curinterp->Iinplace) +#define last_in_gv (curinterp->Ilast_in_gv) +#define lastfd (curinterp->Ilastfd) +#define lastretstr (curinterp->Ilastretstr) +#define lastscream (curinterp->Ilastscream) +#define lastsize (curinterp->Ilastsize) +#define lastspbase (curinterp->Ilastspbase) +#define laststatval (curinterp->Ilaststatval) +#define laststype (curinterp->Ilaststype) +#define leftgv (curinterp->Ileftgv) +#define lineary (curinterp->Ilineary) +#define localizing (curinterp->Ilocalizing) +#define localpatches (curinterp->Ilocalpatches) +#define main_cv (curinterp->Imain_cv) +#define main_root (curinterp->Imain_root) +#define main_start (curinterp->Imain_start) +#define mainstack (curinterp->Imainstack) +#define maxscream (curinterp->Imaxscream) +#define maxsysfd (curinterp->Imaxsysfd) +#define mess_sv (curinterp->Imess_sv) +#define minus_F (curinterp->Iminus_F) +#define minus_a (curinterp->Iminus_a) +#define minus_c (curinterp->Iminus_c) +#define minus_l (curinterp->Iminus_l) +#define minus_n (curinterp->Iminus_n) +#define minus_p (curinterp->Iminus_p) +#define multiline (curinterp->Imultiline) +#define mystack_base (curinterp->Imystack_base) +#define mystack_mark (curinterp->Imystack_mark) +#define mystack_max (curinterp->Imystack_max) +#define mystack_sp (curinterp->Imystack_sp) +#define mystrk (curinterp->Imystrk) +#define nrs (curinterp->Inrs) +#define ofmt (curinterp->Iofmt) +#define ofs (curinterp->Iofs) +#define ofslen (curinterp->Iofslen) +#define oldlastpm (curinterp->Ioldlastpm) +#define oldname (curinterp->Ioldname) +#define op_mask (curinterp->Iop_mask) +#define origargc (curinterp->Iorigargc) +#define origargv (curinterp->Iorigargv) +#define origfilename (curinterp->Iorigfilename) +#define ors (curinterp->Iors) +#define orslen (curinterp->Iorslen) +#define parsehook (curinterp->Iparsehook) +#define patchlevel (curinterp->Ipatchlevel) #define perl_destruct_level (curinterp->Iperl_destruct_level) -#define pidstatus (curinterp->Ipidstatus) -#define preambled (curinterp->Ipreambled) -#define preambleav (curinterp->Ipreambleav) -#define preprocess (curinterp->Ipreprocess) -#define restartop (curinterp->Irestartop) -#define rightgv (curinterp->Irightgv) -#define rs (curinterp->Irs) -#define runlevel (curinterp->Irunlevel) -#define sawampersand (curinterp->Isawampersand) -#define sawi (curinterp->Isawi) -#define sawstudy (curinterp->Isawstudy) -#define sawvec (curinterp->Isawvec) -#define screamfirst (curinterp->Iscreamfirst) -#define screamnext (curinterp->Iscreamnext) -#define secondgv (curinterp->Isecondgv) -#define siggv (curinterp->Isiggv) -#define signalstack (curinterp->Isignalstack) -#define sortcop (curinterp->Isortcop) -#define sortstack (curinterp->Isortstack) -#define sortstash (curinterp->Isortstash) -#define splitstr (curinterp->Isplitstr) -#define stack (curinterp->Istack) -#define statcache (curinterp->Istatcache) -#define statgv (curinterp->Istatgv) -#define statname (curinterp->Istatname) -#define statusvalue (curinterp->Istatusvalue) -#define stdingv (curinterp->Istdingv) -#define strchop (curinterp->Istrchop) -#define sv_count (curinterp->Isv_count) -#define sv_objcount (curinterp->Isv_objcount) -#define sv_root (curinterp->Isv_root) -#define sv_arenaroot (curinterp->Isv_arenaroot) -#define tainted (curinterp->Itainted) -#define tainting (curinterp->Itainting) -#define tmps_floor (curinterp->Itmps_floor) -#define tmps_ix (curinterp->Itmps_ix) -#define tmps_max (curinterp->Itmps_max) -#define tmps_stack (curinterp->Itmps_stack) -#define top_env (curinterp->Itop_env) -#define toptarget (curinterp->Itoptarget) -#define unsafe (curinterp->Iunsafe) -#define warnhook (curinterp->Iwarnhook) +#define perldb (curinterp->Iperldb) +#define preambleav (curinterp->Ipreambleav) +#define preambled (curinterp->Ipreambled) +#define preprocess (curinterp->Ipreprocess) +#define restartop (curinterp->Irestartop) +#define rightgv (curinterp->Irightgv) +#define rs (curinterp->Irs) +#define runlevel (curinterp->Irunlevel) +#define sawampersand (curinterp->Isawampersand) +#define sawstudy (curinterp->Isawstudy) +#define sawvec (curinterp->Isawvec) +#define screamfirst (curinterp->Iscreamfirst) +#define screamnext (curinterp->Iscreamnext) +#define secondgv (curinterp->Isecondgv) +#define siggv (curinterp->Isiggv) +#define signalstack (curinterp->Isignalstack) +#define sortcop (curinterp->Isortcop) +#define sortstack (curinterp->Isortstack) +#define sortstash (curinterp->Isortstash) +#define splitstr (curinterp->Isplitstr) +#define start_env (curinterp->Istart_env) +#define statcache (curinterp->Istatcache) +#define statgv (curinterp->Istatgv) +#define statname (curinterp->Istatname) +#define statusvalue (curinterp->Istatusvalue) +#define statusvalue_vms (curinterp->Istatusvalue_vms) +#define stdingv (curinterp->Istdingv) +#define strchop (curinterp->Istrchop) +#define strtab (curinterp->Istrtab) +#define sv_arenaroot (curinterp->Isv_arenaroot) +#define sv_count (curinterp->Isv_count) +#define sv_objcount (curinterp->Isv_objcount) +#define sv_root (curinterp->Isv_root) +#define tainted (curinterp->Itainted) +#define tainting (curinterp->Itainting) +#define tmps_floor (curinterp->Itmps_floor) +#define tmps_ix (curinterp->Itmps_ix) +#define tmps_max (curinterp->Itmps_max) +#define tmps_stack (curinterp->Itmps_stack) +#define top_env (curinterp->Itop_env) +#define toptarget (curinterp->Itoptarget) +#define unsafe (curinterp->Iunsafe) +#define warnhook (curinterp->Iwarnhook) -#else /* not multiple, so translate interpreter symbols the other way... */ +#else /* !MULTIPLICITY */ -#define IArgv Argv -#define ICmd Cmd -#define IDBgv DBgv -#define IDBline DBline -#define IDBsignal DBsignal -#define IDBsingle DBsingle -#define IDBsub DBsub -#define IDBtrace DBtrace -#define Iallgvs allgvs -#define Iampergv ampergv -#define Iargvgv argvgv -#define Iargvoutgv argvoutgv -#define Ibasetime basetime -#define Ibeginav beginav -#define Ibodytarget bodytarget -#define Icddir cddir -#define Ichopset chopset -#define Icopline copline -#define Icurblock curblock -#define Icurcop curcop -#define Icurcsv curcsv -#define Icurpm curpm -#define Icurstash curstash -#define Icurstname curstname -#define Icxstack cxstack -#define Icxstack_ix cxstack_ix -#define Icxstack_max cxstack_max -#define Idbargs dbargs -#define Idebdelim debdelim -#define Idebname debname -#define Idebstash debstash -#define Idebug debug -#define Idefgv defgv -#define Idefoutgv defoutgv -#define Idefstash defstash -#define Idelaymagic delaymagic -#define Idiehook diehook -#define Idirty dirty -#define Idlevel dlevel -#define Idlmax dlmax -#define Ido_undump do_undump -#define Idoextract doextract -#define Idoswitches doswitches -#define Idowarn dowarn -#define Idumplvl dumplvl -#define Ie_fp e_fp -#define Ie_tmpname e_tmpname -#define Iendav endav -#define Ienvgv envgv -#define Ierrgv errgv -#define Ieval_root eval_root -#define Ieval_start eval_start -#define Ifdpid fdpid -#define Ifilemode filemode -#define Ifirstgv firstgv -#define Iforkprocess forkprocess -#define Iformfeed formfeed -#define Iformtarget formtarget -#define Igensym gensym -#define Iin_eval in_eval -#define Iincgv incgv -#define Iinplace inplace -#define Ilast_in_gv last_in_gv -#define Ilastfd lastfd -#define Ilastretstr lastretstr -#define Ilastscream lastscream -#define Ilastsize lastsize -#define Ilastspbase lastspbase -#define Ilaststatval laststatval -#define Ilaststype laststype -#define Ileftgv leftgv -#define Ilineary lineary -#define Ilocalizing localizing -#define Imain_cv main_cv -#define Imain_root main_root -#define Imain_start main_start -#define Imainstack mainstack -#define Imaxscream maxscream -#define Imaxsysfd maxsysfd -#define Iminus_F minus_F -#define Iminus_a minus_a -#define Iminus_c minus_c -#define Iminus_l minus_l -#define Iminus_n minus_n -#define Iminus_p minus_p -#define Imultiline multiline -#define Imystack_base mystack_base -#define Imystack_mark mystack_mark -#define Imystack_max mystack_max -#define Imystack_sp mystack_sp -#define Imystrk mystrk -#define Inrs nrs -#define Iofmt ofmt -#define Iofs ofs -#define Iofslen ofslen -#define Ioldlastpm oldlastpm -#define Ioldname oldname -#define Iop_mask op_mask -#define Iorigargc origargc -#define Iorigargv origargv -#define Iorigfilename origfilename -#define Iors ors -#define Iorslen orslen -#define Ipad pad -#define Ipadname padname -#define Iparsehook parsehook -#define Ipatchlevel patchlevel -#define Iperldb perldb +#define IArgv Argv +#define ICmd Cmd +#define IDBgv DBgv +#define IDBline DBline +#define IDBsignal DBsignal +#define IDBsingle DBsingle +#define IDBsub DBsub +#define IDBtrace DBtrace +#define Iallgvs allgvs +#define Iampergv ampergv +#define Iargvgv argvgv +#define Iargvoutgv argvoutgv +#define Ibasetime basetime +#define Ibeginav beginav +#define Ibodytarget bodytarget +#define Icddir cddir +#define Ichopset chopset +#define Icopline copline +#define Icurblock curblock +#define Icurcop curcop +#define Icurcopdb curcopdb +#define Icurcsv curcsv +#define Icurpm curpm +#define Icurstack curstack +#define Icurstash curstash +#define Icurstname curstname +#define Icxstack cxstack +#define Icxstack_ix cxstack_ix +#define Icxstack_max cxstack_max +#define Idbargs dbargs +#define Idebdelim debdelim +#define Idebname debname +#define Idebstash debstash +#define Idefgv defgv +#define Idefoutgv defoutgv +#define Idefstash defstash +#define Idelaymagic delaymagic +#define Idiehook diehook +#define Idirty dirty +#define Idlevel dlevel +#define Idlmax dlmax +#define Idoextract doextract +#define Idoswitches doswitches +#define Idowarn dowarn +#define Idumplvl dumplvl +#define Ie_fp e_fp +#define Ie_tmpname e_tmpname +#define Iendav endav +#define Ienvgv envgv +#define Ierrgv errgv +#define Ieval_root eval_root +#define Ieval_start eval_start +#define Ifdpid fdpid +#define Ifilemode filemode +#define Ifirstgv firstgv +#define Iforkprocess forkprocess +#define Iformfeed formfeed +#define Iformtarget formtarget +#define Igensym gensym +#define Iin_eval in_eval +#define Iincgv incgv +#define Iinplace inplace +#define Ilast_in_gv last_in_gv +#define Ilastfd lastfd +#define Ilastretstr lastretstr +#define Ilastscream lastscream +#define Ilastsize lastsize +#define Ilastspbase lastspbase +#define Ilaststatval laststatval +#define Ilaststype laststype +#define Ileftgv leftgv +#define Ilineary lineary +#define Ilocalizing localizing +#define Ilocalpatches localpatches +#define Imain_cv main_cv +#define Imain_root main_root +#define Imain_start main_start +#define Imainstack mainstack +#define Imaxscream maxscream +#define Imaxsysfd maxsysfd +#define Imess_sv mess_sv +#define Iminus_F minus_F +#define Iminus_a minus_a +#define Iminus_c minus_c +#define Iminus_l minus_l +#define Iminus_n minus_n +#define Iminus_p minus_p +#define Imultiline multiline +#define Imystack_base mystack_base +#define Imystack_mark mystack_mark +#define Imystack_max mystack_max +#define Imystack_sp mystack_sp +#define Imystrk mystrk +#define Inrs nrs +#define Iofmt ofmt +#define Iofs ofs +#define Iofslen ofslen +#define Ioldlastpm oldlastpm +#define Ioldname oldname +#define Iop_mask op_mask +#define Iorigargc origargc +#define Iorigargv origargv +#define Iorigfilename origfilename +#define Iors ors +#define Iorslen orslen +#define Iparsehook parsehook +#define Ipatchlevel patchlevel #define Iperl_destruct_level perl_destruct_level -#define Ipidstatus pidstatus -#define Ipreambled preambled -#define Ipreambleav preambleav -#define Ipreprocess preprocess -#define Irestartop restartop -#define Irightgv rightgv -#define Irs rs -#define Irunlevel runlevel -#define Isawampersand sawampersand -#define Isawi sawi -#define Isawstudy sawstudy -#define Isawvec sawvec -#define Iscreamfirst screamfirst -#define Iscreamnext screamnext -#define Isecondgv secondgv -#define Isiggv siggv -#define Isignalstack signalstack -#define Isortcop sortcop -#define Isortstack sortstack -#define Isortstash sortstash -#define Isplitstr splitstr -#define Istack stack -#define Istatcache statcache -#define Istatgv statgv -#define Istatname statname -#define Istatusvalue statusvalue -#define Istdingv stdingv -#define Istrchop strchop -#define Isv_count sv_count -#define Isv_objcount sv_objcount -#define Isv_root sv_root -#define Isv_arenaroot sv_arenaroot -#define Itainted tainted -#define Itainting tainting -#define Itmps_floor tmps_floor -#define Itmps_ix tmps_ix -#define Itmps_max tmps_max -#define Itmps_stack tmps_stack -#define Itop_env top_env -#define Itoptarget toptarget -#define Iunsafe unsafe -#define Iwarnhook warnhook +#define Iperldb perldb +#define Ipreambleav preambleav +#define Ipreambled preambled +#define Ipreprocess preprocess +#define Irestartop restartop +#define Irightgv rightgv +#define Irs rs +#define Irunlevel runlevel +#define Isawampersand sawampersand +#define Isawstudy sawstudy +#define Isawvec sawvec +#define Iscreamfirst screamfirst +#define Iscreamnext screamnext +#define Isecondgv secondgv +#define Isiggv siggv +#define Isignalstack signalstack +#define Isortcop sortcop +#define Isortstack sortstack +#define Isortstash sortstash +#define Isplitstr splitstr +#define Istart_env start_env +#define Istatcache statcache +#define Istatgv statgv +#define Istatname statname +#define Istatusvalue statusvalue +#define Istatusvalue_vms statusvalue_vms +#define Istdingv stdingv +#define Istrchop strchop +#define Istrtab strtab +#define Isv_arenaroot sv_arenaroot +#define Isv_count sv_count +#define Isv_objcount sv_objcount +#define Isv_root sv_root +#define Itainted tainted +#define Itainting tainting +#define Itmps_floor tmps_floor +#define Itmps_ix tmps_ix +#define Itmps_max tmps_max +#define Itmps_stack tmps_stack +#define Itop_env top_env +#define Itoptarget toptarget +#define Iunsafe unsafe +#define Iwarnhook warnhook + +/* Hide interpreter-specific symbols? */ + +#ifdef EMBED + +#define curcop Perl_curcop +#define curcopdb Perl_curcopdb +#define envgv Perl_envgv +#define siggv Perl_siggv +#define tainting Perl_tainting + +/* Hide interpreter symbols that 5.003 revealed? */ + +#ifndef BINCOMPAT3 + +#define Argv Perl_Argv +#define Cmd Perl_Cmd +#define DBgv Perl_DBgv +#define DBline Perl_DBline +#define DBsignal Perl_DBsignal +#define DBsingle Perl_DBsingle +#define DBsub Perl_DBsub +#define DBtrace Perl_DBtrace +#define allgvs Perl_allgvs +#define ampergv Perl_ampergv +#define argvgv Perl_argvgv +#define argvoutgv Perl_argvoutgv +#define basetime Perl_basetime +#define beginav Perl_beginav +#define bodytarget Perl_bodytarget +#define cddir Perl_cddir +#define chopset Perl_chopset +#define copline Perl_copline +#define curblock Perl_curblock +#define curcsv Perl_curcsv +#define curpm Perl_curpm +#define curstack Perl_curstack +#define curstash Perl_curstash +#define curstname Perl_curstname +#define cxstack Perl_cxstack +#define cxstack_ix Perl_cxstack_ix +#define cxstack_max Perl_cxstack_max +#define dbargs Perl_dbargs +#define debdelim Perl_debdelim +#define debname Perl_debname +#define debstash Perl_debstash +#define defgv Perl_defgv +#define defoutgv Perl_defoutgv +#define defstash Perl_defstash +#define delaymagic Perl_delaymagic +#define diehook Perl_diehook +#define dirty Perl_dirty +#define dlevel Perl_dlevel +#define dlmax Perl_dlmax +#define doextract Perl_doextract +#define doswitches Perl_doswitches +#define dowarn Perl_dowarn +#define dumplvl Perl_dumplvl +#define e_fp Perl_e_fp +#define e_tmpname Perl_e_tmpname +#define endav Perl_endav +#define errgv Perl_errgv +#define eval_root Perl_eval_root +#define eval_start Perl_eval_start +#define fdpid Perl_fdpid +#define filemode Perl_filemode +#define firstgv Perl_firstgv +#define forkprocess Perl_forkprocess +#define formfeed Perl_formfeed +#define formtarget Perl_formtarget +#define gensym Perl_gensym +#define in_eval Perl_in_eval +#define incgv Perl_incgv +#define inplace Perl_inplace +#define last_in_gv Perl_last_in_gv +#define lastfd Perl_lastfd +#define lastretstr Perl_lastretstr +#define lastscream Perl_lastscream +#define lastsize Perl_lastsize +#define lastspbase Perl_lastspbase +#define laststatval Perl_laststatval +#define laststype Perl_laststype +#define leftgv Perl_leftgv +#define lineary Perl_lineary +#define localizing Perl_localizing +#define localpatches Perl_localpatches +#define main_cv Perl_main_cv +#define main_root Perl_main_root +#define main_start Perl_main_start +#define mainstack Perl_mainstack +#define maxscream Perl_maxscream +#define maxsysfd Perl_maxsysfd +#define mess_sv Perl_mess_sv +#define minus_F Perl_minus_F +#define minus_a Perl_minus_a +#define minus_c Perl_minus_c +#define minus_l Perl_minus_l +#define minus_n Perl_minus_n +#define minus_p Perl_minus_p +#define multiline Perl_multiline +#define mystack_base Perl_mystack_base +#define mystack_mark Perl_mystack_mark +#define mystack_max Perl_mystack_max +#define mystack_sp Perl_mystack_sp +#define mystrk Perl_mystrk +#define nrs Perl_nrs +#define ofmt Perl_ofmt +#define ofs Perl_ofs +#define ofslen Perl_ofslen +#define oldlastpm Perl_oldlastpm +#define oldname Perl_oldname +#define op_mask Perl_op_mask +#define origargc Perl_origargc +#define origargv Perl_origargv +#define origfilename Perl_origfilename +#define ors Perl_ors +#define orslen Perl_orslen +#define parsehook Perl_parsehook +#define patchlevel Perl_patchlevel +#define perl_destruct_level Perl_perl_destruct_level +#define perldb Perl_perldb +#define preambleav Perl_preambleav +#define preambled Perl_preambled +#define preprocess Perl_preprocess +#define restartop Perl_restartop +#define rightgv Perl_rightgv +#define rs Perl_rs +#define runlevel Perl_runlevel +#define sawampersand Perl_sawampersand +#define sawstudy Perl_sawstudy +#define sawvec Perl_sawvec +#define screamfirst Perl_screamfirst +#define screamnext Perl_screamnext +#define secondgv Perl_secondgv +#define signalstack Perl_signalstack +#define sortcop Perl_sortcop +#define sortstack Perl_sortstack +#define sortstash Perl_sortstash +#define splitstr Perl_splitstr +#define start_env Perl_start_env +#define statcache Perl_statcache +#define statgv Perl_statgv +#define statname Perl_statname +#define statusvalue Perl_statusvalue +#define statusvalue_vms Perl_statusvalue_vms +#define stdingv Perl_stdingv +#define strchop Perl_strchop +#define strtab Perl_strtab +#define sv_arenaroot Perl_sv_arenaroot +#define sv_count Perl_sv_count +#define sv_objcount Perl_sv_objcount +#define sv_root Perl_sv_root +#define tainted Perl_tainted +#define tmps_floor Perl_tmps_floor +#define tmps_ix Perl_tmps_ix +#define tmps_max Perl_tmps_max +#define tmps_stack Perl_tmps_stack +#define top_env Perl_top_env +#define toptarget Perl_toptarget +#define unsafe Perl_unsafe +#define warnhook Perl_warnhook + +#endif /* !BINCOMPAT3 */ + +#endif /* EMBED */ #endif /* MULTIPLICITY */ diff --git a/gnu/usr.bin/perl/embed.pl b/gnu/usr.bin/perl/embed.pl index e5423dde3cc..266a33e7e0a 100644 --- a/gnu/usr.bin/perl/embed.pl +++ b/gnu/usr.bin/perl/embed.pl @@ -1,9 +1,53 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w -open(EM, ">embed.h") || die "Can't create embed.h: $!\n"; +require 5.003; + +sub readsyms (\%$) { + my ($syms, $file) = @_; + %$syms = (); + local (*FILE, $_); + open(FILE, "< $file") + or die "embed.pl: Can't open $file: $!\n"; + while (<FILE>) { + s/[ \t]*#.*//; # Delete comments. + if (/^\s*(\S+)\s*$/) { + $$syms{$1} = 1; + } + } + close(FILE); +} + +readsyms %global, 'global.sym'; +readsyms %interp, 'interp.sym'; +readsyms %compat3, 'compat3.sym'; + +sub hide ($$) { + my ($from, $to) = @_; + my $t = int(length($from) / 8); + "#define $from" . "\t" x ($t < 3 ? 3 - $t : 1) . "$to\n"; +} +sub embed ($) { + my ($sym) = @_; + hide($sym, "Perl_$sym"); +} +sub multon ($) { + my ($sym) = @_; + hide($sym, "(curinterp->I$sym)"); +} +sub multoff ($) { + my ($sym) = @_; + hide("I$sym", $sym); +} + +unlink 'embed.h'; +open(EM, '> embed.h') + or die "Can't create embed.h: $!\n"; print EM <<'END'; -/* This file is derived from global.sym and interp.sym */ +/* !!!!!!! DO NOT EDIT THIS FILE !!!!!!! + This file is built by embed.pl from global.sym, interp.sym, + and compat3.sym. Any changes made here will be lost! +*/ /* (Doing namespace management portably in C is really gross.) */ @@ -17,61 +61,84 @@ print EM <<'END'; # define EMBED 1 #endif +/* Hide global symbols? */ + #ifdef EMBED -/* globals we need to hide from the world */ END -open(GL, "<global.sym") || die "Can't open global.sym: $!\n"; - -while(<GL>) { - s/[ \t]*#.*//; # Delete comments. - next unless /\S/; - s/(.*)/#define $1\t\tPerl_$1/; - s/(................\t)\t/$1/; - print EM $_; +for $sym (sort keys %global) { + print EM embed($sym) unless $compat3{$sym}; } -close(GL) || warn "Can't close global.sym: $!\n"; +print EM <<'END'; + +/* Hide global symbols that 5.003 revealed? */ + +#ifndef BINCOMPAT3 + +END + +for $sym (sort keys %global) { + print EM embed($sym) if $compat3{$sym}; +} print EM <<'END'; +#endif /* !BINCOMPAT3 */ + #endif /* EMBED */ -/* Put interpreter specific symbols into a struct? */ +/* Put interpreter-specific symbols into a struct? */ #ifdef MULTIPLICITY END -open(INT, "<interp.sym") || die "Can't open interp.sym: $!\n"; -while (<INT>) { - s/[ \t]*#.*//; # Delete comments. - next unless /\S/; - s/(.*)/#define $1\t\t(curinterp->I$1)/; - s/(................\t)\t/$1/; - print EM $_; +for $sym (sort keys %interp) { + print EM multon($sym); } -close(INT) || warn "Can't close interp.sym: $!\n"; print EM <<'END'; -#else /* not multiple, so translate interpreter symbols the other way... */ +#else /* !MULTIPLICITY */ END -open(INT, "<interp.sym") || die "Can't open interp.sym: $!\n"; -while (<INT>) { - s/[ \t]*#.*//; # Delete comments. - next unless /\S/; - s/(.*)/#define I$1\t\t$1/; - s/(................\t)\t/$1/; - print EM $_; +for $sym (sort keys %interp) { + print EM multoff($sym); +} + +print EM <<'END'; + +/* Hide interpreter-specific symbols? */ + +#ifdef EMBED + +END + +for $sym (sort keys %interp) { + print EM embed($sym) if $compat3{$sym}; } -close(INT) || warn "Can't close interp.sym: $!\n"; print EM <<'END'; +/* Hide interpreter symbols that 5.003 revealed? */ + +#ifndef BINCOMPAT3 + +END + +for $sym (sort keys %interp) { + print EM embed($sym) unless $compat3{$sym}; +} + +print EM <<'END'; + +#endif /* !BINCOMPAT3 */ + +#endif /* EMBED */ + #endif /* MULTIPLICITY */ END diff --git a/gnu/usr.bin/perl/form.h b/gnu/usr.bin/perl/form.h index 531cc72294a..5e74c613fad 100644 --- a/gnu/usr.bin/perl/form.h +++ b/gnu/usr.bin/perl/form.h @@ -1,6 +1,6 @@ /* form.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. diff --git a/gnu/usr.bin/perl/global.sym b/gnu/usr.bin/perl/global.sym index 70d07c0034e..864be817570 100644 --- a/gnu/usr.bin/perl/global.sym +++ b/gnu/usr.bin/perl/global.sym @@ -3,6 +3,7 @@ # Variables AMG_names +Error No Sv Xpv @@ -15,19 +16,25 @@ amagic_generation an atan2_amg band_amg +block_type bool__amg bor_amg -buf bufend bufptr bxor_amg check +collation_ix +collation_name +collation_standard +collxfrm_base +collxfrm_mult +compcv compiling compl_amg -compcv comppad comppad_name comppad_name_fill +comppad_name_floor concat_amg concat_ass_amg cop_seqmax @@ -35,17 +42,17 @@ cos_amg cryptseen cshlen cshname -curcop curinterp curpad dc +debug dec_amg di div_amg div_ass_amg +do_undump ds egid -envgv eq_amg error_count euid @@ -54,10 +61,8 @@ exp_amg expect expectterm fallback_amg -filter_add -filter_del -filter_read fold +fold_locale freq ge_amg gid @@ -72,22 +77,22 @@ last_lop last_lop_op last_uni le_amg -lex_state -lex_defer -lex_expect lex_brackets -lex_formbrack -lex_fakebrack +lex_brackstack lex_casemods +lex_casestack +lex_defer lex_dojoin -lex_starts -lex_stuff -lex_repl -lex_op +lex_expect +lex_fakebrack +lex_formbrack lex_inpat lex_inwhat -lex_brackstack -lex_casestack +lex_op +lex_repl +lex_starts +lex_state +lex_stuff linestr log_amg lshift_amg @@ -96,8 +101,8 @@ lt_amg markstack markstack_max markstack_ptr -maxo max_intro_pending +maxo min_intro_pending mod_amg mod_ass_amg @@ -109,27 +114,33 @@ multi_open multi_start na ncmp_amg -nextval -nexttype -nexttoke ne_amg neg_amg +nexttoke nexttype nextval +nice_chunk +nice_chunk_size no_aelem no_dir_func no_func no_helem no_mem no_modify +no_myglob no_security no_sock_func +no_symref no_usym +no_wrongref nointrp nomem nomemok nomethod_amg not_amg +numeric_local +numeric_name +numeric_standard numer_amg oldbufptr oldoldbufptr @@ -141,14 +152,17 @@ opargs origalen origenviron osname +pad_reset_pending padix +padix_floor patleave +pidstatus pow_amg pow_ass_amg ppaddr profiledata -provide_ref -qrt_amg +psig_name +psig_ptr rcsid reall_srchlen regarglen @@ -157,7 +171,7 @@ regcode regdummy regendp regeol -regfold +regflags reginput regkind reglastparen @@ -184,7 +198,6 @@ rsfp rsfp_filters rshift_amg rshift_ass_amg -save_pptr savestack savestack_ix savestack_max @@ -197,16 +210,15 @@ scrgv seq_amg sge_amg sgt_amg +sh_path sig_name sig_num -siggv -sighandler simple sin_amg sle_amg slt_amg sne_amg -stack +sqrt_amg stack_base stack_max stack_sp @@ -220,24 +232,29 @@ subtr_ass_amg sv_no sv_undef sv_yes -tainting thisexpr timesbuf tokenbuf uid varies vert +vivify_defelem +vivify_ref vtbl_amagic vtbl_amagicelem vtbl_arylen vtbl_bm +vtbl_collxfrm vtbl_dbline +vtbl_defelem vtbl_env vtbl_envelem +vtbl_fm vtbl_glob vtbl_isa vtbl_isaelem vtbl_mglob +vtbl_nkeys vtbl_pack vtbl_packelem vtbl_pos @@ -251,6 +268,7 @@ vtbl_vec warn_nl warn_nosemi warn_reserved +warn_uninit watchaddr watchok yychar @@ -274,6 +292,10 @@ yyval # Functions Gv_AMupdate +SvTRUE +SvIV +SvUV +SvNV amagic_call append_elem append_list @@ -288,28 +310,33 @@ av_len av_make av_pop av_push +av_reify av_shift av_store av_undef av_unshift bind_match block_end +block_gimme block_start -calllist +boot_core_UNIVERSAL +call_list cando cast_ulong check_uni checkcomma -chsize ck_aelem +ck_anoncode +ck_bitop ck_concat ck_delete ck_eof ck_eval ck_exec -ck_formline +ck_exists ck_ftst ck_fun +ck_fun_locale ck_glob ck_grep ck_gvconst @@ -324,6 +351,7 @@ ck_require ck_retarget ck_rfun ck_rvconst +ck_scmp ck_select ck_shift ck_sort @@ -333,9 +361,10 @@ ck_subr ck_svconst ck_trunc convert -cpytill croak +cv_ckproto cv_clone +cv_const_sv cv_undef cx_dump cxinc @@ -345,6 +374,7 @@ debop debprofdump debstack debstackptrs +delimcpy deprecate die die_where @@ -369,6 +399,7 @@ do_seek do_semop do_shmio do_sprintf +do_sysseek do_tell do_trans do_vecset @@ -400,6 +431,7 @@ force_ident force_list force_next force_word +form free_tmps gen_constant_list gp_free @@ -407,36 +439,49 @@ gp_ref gv_AVadd gv_HVadd gv_IOadd +gv_autoload4 gv_check gv_efullname +gv_efullname3 gv_fetchfile gv_fetchmeth gv_fetchmethod +gv_fetchmethod_autoload gv_fetchpv gv_fullname +gv_fullname3 gv_init gv_stashpv +gv_stashpvn gv_stashsv -he_delayfree -he_free he_root hoistmust hv_clear +hv_delayfree_ent hv_delete +hv_delete_ent hv_exists +hv_exists_ent hv_fetch +hv_fetch_ent +hv_free_ent hv_iterinit hv_iterkey +hv_iterkeysv hv_iternext hv_iternextsv hv_iterval +hv_ksplit hv_magic hv_stashpv hv_store +hv_store_ent hv_undef ibcmp +ibcmp_locale ingroup instr +intro_my intuit_more invert jmaybe @@ -450,13 +495,18 @@ listkids localize looks_like_number magic_clearenv +magic_clear_all_env magic_clearpack +magic_clearsig magic_existspack +magic_freedefelem magic_get magic_getarylen +magic_getdefelem magic_getglob magic_getpack magic_getpos +magic_getsig magic_gettaint magic_getuvar magic_len @@ -465,11 +515,15 @@ magic_set magic_setamagic magic_setarylen magic_setbm +magic_setcollxfrm magic_setdbline +magic_setdefelem magic_setenv +magic_setfm magic_setglob magic_setisa magic_setmglob +magic_setnkeys magic_setpack magic_setpos magic_setsig @@ -477,9 +531,11 @@ magic_setsubstr magic_settaint magic_setuvar magic_setvec +magic_set_all_env magic_wipepack magicname markstack_grow +mem_collxfrm mess mg_clear mg_copy @@ -496,10 +552,13 @@ mstats my my_bcopy my_bzero +my_chsize my_exit +my_failure_exit my_htonl my_lstat my_memcmp +my_memset my_ntohl my_pclose my_popen @@ -544,6 +603,7 @@ newSVREF newSViv newSVnv newSVpv +newSVpvf newSVrv newSVsv newUNOP @@ -893,6 +953,7 @@ pp_symlink pp_syscall pp_sysopen pp_sysread +pp_sysseek pp_system pp_syswrite pp_tell @@ -934,8 +995,24 @@ regnext regprop repeatcpy rninstr +rsignal +rsignal_save +rsignal_state +rsignal_restore runops +rxres_free +rxres_restore +rxres_save +safecalloc +safemalloc +safefree +saferealloc +safexcalloc +safexmalloc +safexfree +safexrealloc same_dirent +save_I16 save_I32 save_aptr save_ary @@ -945,10 +1022,12 @@ save_destructor save_freeop save_freepv save_freesv +save_gp save_hash save_hptr save_int save_item +save_iv save_list save_long save_nogv @@ -982,12 +1061,13 @@ scope screaminstr setdefout setenv_getix +share_hek +sharepvn sighandler skipspace stack_grow start_subparse -sublex_done -sublex_start +sub_crush_depth sv_2bool sv_2cv sv_2io @@ -995,9 +1075,11 @@ sv_2iv sv_2mortal sv_2nv sv_2pv +sv_2uv sv_add_arena sv_backoff sv_bless +sv_catpvf sv_catpv sv_catpvn sv_catsv @@ -1006,7 +1088,10 @@ sv_clean_all sv_clean_objs sv_clear sv_cmp +sv_cmp_locale +sv_collxfrm sv_dec +sv_derived_from sv_dump sv_eq sv_free @@ -1023,32 +1108,42 @@ sv_mortalcopy sv_newmortal sv_newref sv_peek +sv_pvn sv_pvn_force sv_ref sv_reftype sv_replace sv_report_used sv_reset +sv_setpvf sv_setiv sv_setnv sv_setptrobj sv_setpv +sv_setpviv sv_setpvn sv_setref_iv sv_setref_nv sv_setref_pv sv_setref_pvn sv_setsv +sv_setuv +sv_taint +sv_tainted sv_unmagic sv_unref +sv_untaint sv_upgrade sv_usepvn +sv_vcatpvfn +sv_vsetpvfn taint_env -taint_not taint_proper too_few_arguments too_many_arguments unlnk +unshare_hek +unsharepvn utilize wait4pid warn @@ -1060,6 +1155,7 @@ xnv_root xpv_root xrv_root yyerror +yydestruct yylex yyparse yywarn diff --git a/gnu/usr.bin/perl/gv.c b/gnu/usr.bin/perl/gv.c index dc6d2e5a919..fff3bcfa876 100644 --- a/gnu/usr.bin/perl/gv.c +++ b/gnu/usr.bin/perl/gv.c @@ -1,6 +1,6 @@ /* gv.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -19,7 +19,7 @@ #include "EXTERN.h" #include "perl.h" -extern char rcsid[]; +EXT char rcsid[]; GV * gv_AVadd(gv) @@ -58,15 +58,28 @@ GV * gv_fetchfile(name) char *name; { - char tmpbuf[1200]; + char smallbuf[256]; + char *tmpbuf; + STRLEN tmplen; GV *gv; - sprintf(tmpbuf,"::_<%s", name); - gv = gv_fetchpv(tmpbuf, TRUE, SVt_PVGV); + tmplen = strlen(name) + 2; + if (tmplen < sizeof smallbuf) + tmpbuf = smallbuf; + else + New(603, tmpbuf, tmplen + 1, char); + tmpbuf[0] = '_'; + tmpbuf[1] = '<'; + strcpy(tmpbuf + 2, name); + gv = *(GV**)hv_fetch(defstash, tmpbuf, tmplen, TRUE); + if (!isGV(gv)) + gv_init(gv, defstash, tmpbuf, tmplen, FALSE); + if (tmpbuf != smallbuf) + Safefree(tmpbuf); sv_setpv(GvSV(gv), name); - if (*name == '/' && (instr(name,"/lib/") || instr(name,".pm"))) + if (*name == '/' && (instr(name, "/lib/") || instr(name, ".pm"))) GvMULTI_on(gv); - if (perldb) + if (PERLDB_LINE) hv_magic(GvHVn(gv_AVadd(gv)), gv, 'L'); return gv; } @@ -81,12 +94,11 @@ int multi; { register GP *gp; - sv_upgrade(gv, SVt_PVGV); + sv_upgrade((SV*)gv, SVt_PVGV); if (SvLEN(gv)) Safefree(SvPVX(gv)); - Newz(602,gp, 1, GP); + Newz(602, gp, 1, GP); GvGP(gv) = gp_ref(gp); - GvREFCNT(gv) = 1; GvSV(gv) = NEWSV(72,0); GvLINE(gv) = curcop->cop_line; GvFILEGV(gv) = curcop->cop_filegv; @@ -128,37 +140,60 @@ I32 level; GV* topgv; GV* gv; GV** gvp; - HV* lastchance; CV* cv; if (!stash) return 0; - if (level > 100) + if ((level > 100) || (level < -100)) croak("Recursive inheritance detected"); - gvp = (GV**)hv_fetch(stash, name, len, TRUE); - DEBUG_o( deb("Looking for method %s in package %s\n",name,HvNAME(stash)) ); - topgv = *gvp; - if (SvTYPE(topgv) != SVt_PVGV) - gv_init(topgv, stash, name, len, TRUE); - - if (cv=GvCV(topgv)) { - if (GvCVGEN(topgv) >= sub_generation) - return topgv; /* valid cached inheritance */ - if (!GvCVGEN(topgv)) { /* not an inheritance cache */ - return topgv; - } - else { - /* stale cached entry, just junk it */ - GvCV(topgv) = cv = 0; + + gvp = (GV**)hv_fetch(stash, name, len, (level >= 0)); + if (!gvp) + topgv = Nullgv; + else { + topgv = *gvp; + if (SvTYPE(topgv) != SVt_PVGV) + gv_init(topgv, stash, name, len, TRUE); + if (cv = GvCV(topgv)) { + /* If genuine method or valid cache entry, use it */ + if (!GvCVGEN(topgv) || GvCVGEN(topgv) >= sub_generation) + return topgv; + /* Stale cached entry: junk it */ + SvREFCNT_dec(cv); + GvCV(topgv) = cv = Nullcv; GvCVGEN(topgv) = 0; } } - /* if cv is still set, we have to free it if we find something to cache */ - gvp = (GV**)hv_fetch(stash,"ISA",3,FALSE); - if (gvp && (gv = *gvp) != (GV*)&sv_undef && (av = GvAV(gv))) { + gvp = (GV**)hv_fetch(stash, "ISA", 3, FALSE); + av = (gvp && (gv = *gvp) && gv != (GV*)&sv_undef) ? GvAV(gv) : Nullav; + + /* create and re-create @.*::SUPER::ISA on demand */ + if (!av || !SvMAGIC(av)) { + char* packname = HvNAME(stash); + STRLEN packlen = strlen(packname); + + if (packlen >= 7 && strEQ(packname + packlen - 7, "::SUPER")) { + HV* basestash; + + packlen -= 7; + basestash = gv_stashpvn(packname, packlen, TRUE); + gvp = (GV**)hv_fetch(basestash, "ISA", 3, FALSE); + if (gvp && (gv = *gvp) != (GV*)&sv_undef && (av = GvAV(gv))) { + gvp = (GV**)hv_fetch(stash, "ISA", 3, TRUE); + if (!gvp || !(gv = *gvp)) + croak("Cannot create %s::ISA", HvNAME(stash)); + if (SvTYPE(gv) != SVt_PVGV) + gv_init(gv, stash, "ISA", 3, TRUE); + SvREFCNT_dec(GvAV(gv)); + GvAV(gv) = (AV*)SvREFCNT_inc(av); + } + } + } + + if (av) { SV** svp = AvARRAY(av); I32 items = AvFILL(av) + 1; while (items--) { @@ -170,30 +205,37 @@ I32 level; SvPVX(sv), HvNAME(stash)); continue; } - gv = gv_fetchmeth(basestash, name, len, level + 1); - if (gv) { - if (cv) { /* junk old undef */ - assert(SvREFCNT(topgv) > 1); - SvREFCNT_dec(topgv); - SvREFCNT_dec(cv); - } - GvCV(topgv) = GvCV(gv); /* cache the CV */ - GvCVGEN(topgv) = sub_generation; /* valid for now */ - return gv; - } + gv = gv_fetchmeth(basestash, name, len, + (level >= 0) ? level + 1 : level - 1); + if (gv) + goto gotcha; } } - if (!level) { - if (lastchance = gv_stashpv("UNIVERSAL", FALSE)) { - if (gv = gv_fetchmeth(lastchance, name, len, level + 1)) { - if (cv) { /* junk old undef */ - assert(SvREFCNT(topgv) > 1); - SvREFCNT_dec(topgv); - SvREFCNT_dec(cv); + /* if at top level, try UNIVERSAL */ + + if (level == 0 || level == -1) { + HV* lastchance; + + if (lastchance = gv_stashpvn("UNIVERSAL", 9, FALSE)) { + if (gv = gv_fetchmeth(lastchance, name, len, + (level >= 0) ? level + 1 : level - 1)) { + gotcha: + /* + * Cache method in topgv if: + * 1. topgv has no synonyms (else inheritance crosses wires) + * 2. method isn't a stub (else AUTOLOAD fails spectacularly) + */ + if (topgv && + GvREFCNT(topgv) == 1 && + (cv = GvCV(gv)) && + (CvROOT(cv) || CvXSUB(cv))) + { + if (cv = GvCV(topgv)) + SvREFCNT_dec(cv); + GvCV(topgv) = (CV*)SvREFCNT_inc(GvCV(gv)); + GvCVGEN(topgv) = sub_generation; } - GvCV(topgv) = GvCV(gv); /* cache the CV */ - GvCVGEN(topgv) = sub_generation; /* valid for now */ return gv; } } @@ -207,88 +249,116 @@ gv_fetchmethod(stash, name) HV* stash; char* name; { + return gv_fetchmethod_autoload(stash, name, TRUE); +} + +GV * +gv_fetchmethod_autoload(stash, name, autoload) +HV* stash; +char* name; +I32 autoload; +{ register char *nend; char *nsplit = 0; GV* gv; for (nend = name; *nend; nend++) { - if (*nend == ':' || *nend == '\'') + if (*nend == '\'') nsplit = nend; + else if (*nend == ':' && *(nend + 1) == ':') + nsplit = ++nend; } if (nsplit) { - char ch; char *origname = name; name = nsplit + 1; - ch = *nsplit; if (*nsplit == ':') --nsplit; - *nsplit = '\0'; - if (strEQ(origname,"SUPER")) { - /* Degenerate case ->SUPER::method should really lookup in original stash */ - SV *tmpstr = sv_2mortal(newSVpv(HvNAME(curcop->cop_stash),0)); - sv_catpvn(tmpstr, "::SUPER", 7); - stash = gv_stashpv(SvPV(tmpstr,na),TRUE); - *nsplit = ch; - DEBUG_o( deb("Treating %s as %s::%s\n",origname,HvNAME(stash),name) ); - } else { - stash = gv_stashpv(origname,TRUE); - *nsplit = ch; + if ((nsplit - origname) == 5 && strnEQ(origname, "SUPER", 5)) { + /* ->SUPER::method should really be looked up in original stash */ + SV *tmpstr = sv_2mortal(newSVpvf("%s::SUPER", + HvNAME(curcop->cop_stash))); + stash = gv_stashpvn(SvPVX(tmpstr), SvCUR(tmpstr), TRUE); + DEBUG_o( deb("Treating %s as %s::%s\n", + origname, HvNAME(stash), name) ); } + else + stash = gv_stashpvn(origname, nsplit - origname, TRUE); } - gv = gv_fetchmeth(stash, name, nend - name, 0); + gv = gv_fetchmeth(stash, name, nend - name, 0); if (!gv) { - /* Failed obvious case - look for SUPER as last element of stash's name */ - char *packname = HvNAME(stash); - STRLEN len = strlen(packname); - if (len >= 7 && strEQ(packname+len-7,"::SUPER")) { - /* Now look for @.*::SUPER::ISA */ - GV** gvp = (GV**)hv_fetch(stash,"ISA",3,FALSE); - if (!gvp || (gv = *gvp) == (GV*)&sv_undef || !GvAV(gv)) { - /* No @ISA in package ending in ::SUPER - drop suffix - and see if there is an @ISA there - */ - HV *basestash; - char ch = packname[len-7]; - AV *av; - packname[len-7] = '\0'; - basestash = gv_stashpv(packname, TRUE); - packname[len-7] = ch; - gvp = (GV**)hv_fetch(basestash,"ISA",3,FALSE); - if (gvp && (gv = *gvp) != (GV*)&sv_undef && (av = GvAV(gv))) { - /* Okay found @ISA after dropping the SUPER, alias it */ - SV *tmpstr = sv_2mortal(newSVpv(HvNAME(stash),0)); - sv_catpvn(tmpstr, "::ISA", 5); - gv = gv_fetchpv(SvPV(tmpstr,na),TRUE,SVt_PVGV); - if (gv) { - GvAV(gv) = (AV*)SvREFCNT_inc(av); - /* ... and re-try lookup */ - gv = gv_fetchmeth(stash, name, nend - name, 0); - } else { - croak("Cannot create %s::ISA",HvNAME(stash)); - } - } - } - } + if (strEQ(name,"import")) + gv = (GV*)&sv_yes; + else if (autoload) + gv = gv_autoload4(stash, name, nend - name, TRUE); } - - if (!gv) { - CV* cv; - - if (strEQ(name,"import") || strEQ(name,"unimport")) - gv = &sv_yes; - else if (strNE(name, "AUTOLOAD")) { - gv = gv_fetchmeth(stash, "AUTOLOAD", 8, 0); - if (gv && (cv = GvCV(gv))) { /* One more chance... */ - SV *tmpstr = sv_2mortal(newSVpv(HvNAME(stash),0)); - sv_catpvn(tmpstr,"::", 2); - sv_catpvn(tmpstr, name, nend - name); - sv_setsv(GvSV(CvGV(cv)), tmpstr); - if (tainting) - sv_unmagic(GvSV(CvGV(cv)), 't'); + else if (autoload) { + CV* cv = GvCV(gv); + if (!CvROOT(cv) && !CvXSUB(cv)) { + GV* stubgv; + GV* autogv; + + if (CvANON(cv)) + stubgv = gv; + else { + stubgv = CvGV(cv); + if (GvCV(stubgv) != cv) /* orphaned import */ + stubgv = gv; } + autogv = gv_autoload4(GvSTASH(stubgv), + GvNAME(stubgv), GvNAMELEN(stubgv), TRUE); + if (autogv) + gv = autogv; } } + + return gv; +} + +GV* +gv_autoload4(stash, name, len, method) +HV* stash; +char* name; +STRLEN len; +I32 method; +{ + static char autoload[] = "AUTOLOAD"; + static STRLEN autolen = 8; + GV* gv; + CV* cv; + HV* varstash; + GV* vargv; + SV* varsv; + + if (len == autolen && strnEQ(name, autoload, autolen)) + return Nullgv; + if (!(gv = gv_fetchmeth(stash, autoload, autolen, FALSE))) + return Nullgv; + cv = GvCV(gv); + + /* + * Inheriting AUTOLOAD for non-methods works ... for now. + */ + if (dowarn && !method && (GvCVGEN(gv) || GvSTASH(gv) != stash)) + warn( + "Use of inherited AUTOLOAD for non-method %s::%.*s() is deprecated", + HvNAME(stash), (int)len, name); + + /* + * Given &FOO::AUTOLOAD, set $FOO::AUTOLOAD to desired function name. + * The subroutine's original name may not be "AUTOLOAD", so we don't + * use that, but for lack of anything better we will use the sub's + * original package to look up $AUTOLOAD. + */ + varstash = GvSTASH(CvGV(cv)); + vargv = *(GV**)hv_fetch(varstash, autoload, autolen, TRUE); + if (!isGV(vargv)) + gv_init(vargv, varstash, autoload, autolen, FALSE); + varsv = GvSV(vargv); + sv_setpv(varsv, HvNAME(stash)); + sv_catpvn(varsv, "::", 2); + sv_catpvn(varsv, name, len); + SvTAINTED_off(varsv); return gv; } @@ -297,15 +367,31 @@ gv_stashpv(name,create) char *name; I32 create; { - char tmpbuf[1234]; + return gv_stashpvn(name, strlen(name), create); +} + +HV* +gv_stashpvn(name,namelen,create) +char *name; +U32 namelen; +I32 create; +{ + char smallbuf[256]; + char *tmpbuf; HV *stash; GV *tmpgv; - /* Use strncpy to avoid bug in VMS sprintf */ - /* sprintf(tmpbuf,"%.*s::",1200,name); */ - strncpy(tmpbuf, name, 1200); - tmpbuf[1200] = '\0'; /* just in case . . . */ - strcat(tmpbuf, "::"); - tmpgv = gv_fetchpv(tmpbuf,create, SVt_PVHV); + + if (namelen + 3 < sizeof smallbuf) + tmpbuf = smallbuf; + else + New(606, tmpbuf, namelen + 3, char); + Copy(name,tmpbuf,namelen,char); + tmpbuf[namelen++] = ':'; + tmpbuf[namelen++] = ':'; + tmpbuf[namelen] = '\0'; + tmpgv = gv_fetchpv(tmpbuf, create, SVt_PVHV); + if (tmpbuf != smallbuf) + Safefree(tmpbuf); if (!tmpgv) return 0; if (!GvHV(tmpgv)) @@ -321,7 +407,10 @@ gv_stashsv(sv,create) SV *sv; I32 create; { - return gv_stashpv(SvPV(sv,na), create); + register char *ptr; + STRLEN len; + ptr = SvPV(sv,len); + return gv_stashpvn(ptr, len, create); } @@ -337,7 +426,7 @@ I32 sv_type; I32 len; register char *namend; HV *stash = 0; - bool global = FALSE; + U32 add_gvflags = 0; char *tmpbuf; if (*name == '*' && isALPHA(name[1])) /* accidental stringify on a GV? */ @@ -349,7 +438,7 @@ I32 sv_type; { if (!stash) stash = defstash; - if (!SvREFCNT(stash)) /* symbol table under destruction */ + if (!stash || !SvREFCNT(stash)) /* symbol table under destruction */ return Nullgv; len = namend - name; @@ -384,7 +473,7 @@ I32 sv_type; namend++; name = namend; if (!*name) - return gv ? gv : *hv_fetch(defstash, "main::", 6, TRUE); + return gv ? gv : (GV*)*hv_fetch(defstash, "main::", 6, TRUE); } } len = namend - name; @@ -395,6 +484,8 @@ I32 sv_type; if (!stash) { if (isIDFIRST(*name)) { + bool global = FALSE; + if (isUPPER(*name)) { if (*name > 'I') { if (*name == 'S' && ( @@ -419,6 +510,7 @@ I32 sv_type; } else if (*name == '_' && !name[1]) global = TRUE; + if (global) stash = defstash; else if ((COP*)curcop == &compiling) { @@ -445,7 +537,7 @@ I32 sv_type; sv_type == SVt_PVAV ? '@' : sv_type == SVt_PVHV ? '%' : '$', name); - if (GvCV(*gvp)) + if (GvCVu(*gvp)) warn("(Did you mean &%s instead?)\n", name); stash = 0; } @@ -465,6 +557,10 @@ I32 sv_type; warn("Global symbol \"%s\" requires explicit package name", name); ++error_count; stash = curstash ? curstash : defstash; /* avoid core dumps */ + add_gvflags = ((sv_type == SVt_PV) ? GVf_IMPORTED_SV + : (sv_type == SVt_PVAV) ? GVf_IMPORTED_AV + : (sv_type == SVt_PVHV) ? GVf_IMPORTED_HV + : 0); } else return Nullgv; @@ -491,6 +587,7 @@ I32 sv_type; warn("Had to create %s unexpectedly", nambeg); gv_init(gv, stash, name, len, add & 2); gv_init_sv(gv, sv_type); + GvFLAGS(gv) |= add_gvflags; /* set up magic where warranted */ switch (*name) { @@ -518,15 +615,15 @@ I32 sv_type; { char *pname; av_push(av, newSVpv(pname = "NDBM_File",0)); - gv_stashpv(pname, TRUE); + gv_stashpvn(pname, 9, TRUE); av_push(av, newSVpv(pname = "DB_File",0)); - gv_stashpv(pname, TRUE); + gv_stashpvn(pname, 7, TRUE); av_push(av, newSVpv(pname = "GDBM_File",0)); - gv_stashpv(pname, TRUE); + gv_stashpvn(pname, 9, TRUE); av_push(av, newSVpv(pname = "SDBM_File",0)); - gv_stashpv(pname, TRUE); + gv_stashpvn(pname, 9, TRUE); av_push(av, newSVpv(pname = "ODBM_File",0)); - gv_stashpv(pname, TRUE); + gv_stashpvn(pname, 9, TRUE); } } break; @@ -542,11 +639,19 @@ I32 sv_type; case 'S': if (strEQ(name, "SIG")) { HV *hv; + I32 i; siggv = gv; GvMULTI_on(siggv); hv = GvHVn(siggv); hv_magic(hv, siggv, 'S'); - + for(i=1;sig_name[i];i++) { + SV ** init; + init=hv_fetch(hv,sig_name[i],strlen(sig_name[i]),1); + if(init) + sv_setsv(*init,&sv_undef); + psig_ptr[i] = 0; + psig_name[i] = 0; + } /* initialize signal stack */ signalstack = newAV(); AvREAL_off(signalstack); @@ -582,6 +687,14 @@ I32 sv_type; sv_setpv(GvSV(gv),chopset); goto magicalize; + case '?': + if (len > 1) + break; +#ifdef COMPLEX_STATUS + sv_upgrade(GvSV(gv), SVt_PVLV); +#endif + goto magicalize; + case '#': case '*': if (dowarn && len == 1 && sv_type == SVt_PV) @@ -589,7 +702,6 @@ I32 sv_type; /* FALL THROUGH */ case '[': case '!': - case '?': case '^': case '~': case '=': @@ -628,6 +740,7 @@ I32 sv_type; case '7': case '8': case '9': + case '\023': ro_magicalize: SvREADONLY_on(GvSV(gv)); magicalize: @@ -647,10 +760,11 @@ I32 sv_type; break; case ']': if (len == 1) { - SV *sv; - sv = GvSV(gv); + SV *sv = GvSV(gv); sv_upgrade(sv, SVt_PVNV); sv_setpv(sv, patchlevel); + (void)sv_2nv(sv); + SvREADONLY_on(sv); } break; } @@ -658,38 +772,50 @@ I32 sv_type; } void -gv_fullname(sv,gv) +gv_fullname3(sv, gv, prefix) SV *sv; GV *gv; +char *prefix; { HV *hv = GvSTASH(gv); - - if (!hv) + if (!hv) { + SvOK_off(sv); return; - sv_setpv(sv, sv == (SV*)gv ? "*" : ""); + } + sv_setpv(sv, prefix ? prefix : ""); sv_catpv(sv,HvNAME(hv)); sv_catpvn(sv,"::", 2); sv_catpvn(sv,GvNAME(gv),GvNAMELEN(gv)); } void -gv_efullname(sv,gv) +gv_efullname3(sv, gv, prefix) SV *sv; GV *gv; +char *prefix; { - GV* egv = GvEGV(gv); - HV *hv; - + GV *egv = GvEGV(gv); if (!egv) egv = gv; - hv = GvSTASH(egv); - if (!hv) - return; + gv_fullname3(sv, egv, prefix); +} - sv_setpv(sv, sv == (SV*)gv ? "*" : ""); - sv_catpv(sv,HvNAME(hv)); - sv_catpvn(sv,"::", 2); - sv_catpvn(sv,GvNAME(egv),GvNAMELEN(egv)); +/* XXX compatibility with versions <= 5.003. */ +void +gv_fullname(sv,gv) +SV *sv; +GV *gv; +{ + gv_fullname3(sv, gv, sv == (SV*)gv ? "*" : ""); +} + +/* XXX compatibility with versions <= 5.003. */ +void +gv_efullname(sv,gv) +SV *sv; +GV *gv; +{ + gv_efullname3(sv, gv, sv == (SV*)gv ? "*" : ""); } IO * @@ -702,7 +828,9 @@ newIO() sv_upgrade((SV *)io,SVt_PVIO); SvREFCNT(io) = 1; SvOBJECT_on(io); - iogv = gv_fetchpv("FileHandle::", TRUE, SVt_PVHV); + iogv = gv_fetchpv("FileHandle::", FALSE, SVt_PVHV); + if (!iogv) + iogv = gv_fetchpv("IO::Handle::", TRUE, SVt_PVHV); SvSTASH(io) = (HV*)SvREFCNT_inc(GvHV(iogv)); return io; } @@ -720,15 +848,15 @@ HV* stash; if (!HvARRAY(stash)) return; for (i = 0; i <= (I32) HvMAX(stash); i++) { - for (entry = HvARRAY(stash)[i]; entry; entry = entry->hent_next) { - if (entry->hent_key[entry->hent_klen-1] == ':' && - (gv = (GV*)entry->hent_val) && (hv = GvHV(gv)) && HvNAME(hv)) + for (entry = HvARRAY(stash)[i]; entry; entry = HeNEXT(entry)) { + if (HeKEY(entry)[HeKLEN(entry)-1] == ':' && + (gv = (GV*)HeVAL(entry)) && (hv = GvHV(gv)) && HvNAME(hv)) { if (hv != defstash) gv_check(hv); /* nested package */ } - else if (isALPHA(*entry->hent_key)) { - gv = (GV*)entry->hent_val; + else if (isALPHA(*HeKEY(entry))) { + gv = (GV*)HeVAL(entry); if (GvMULTI(gv)) continue; curcop->cop_line = GvLINE(gv); @@ -736,7 +864,7 @@ HV* stash; curcop->cop_filegv = filegv; if (filegv && GvMULTI(filegv)) /* Filename began with slash */ continue; - warn("Identifier \"%s::%s\" used only once: possible typo", + warn("Name \"%s::%s\" used only once: possible typo", HvNAME(stash), GvNAME(gv)); } } @@ -747,8 +875,8 @@ GV * newGVgen(pack) char *pack; { - (void)sprintf(tokenbuf,"%s::_GEN_%ld",pack,(long)gensym++); - return gv_fetchpv(tokenbuf,TRUE, SVt_PVGV); + return gv_fetchpv(form("%s::_GEN_%ld", pack, (long)gensym++), + TRUE, SVt_PVGV); } /* hopefully this is only called on local symbol table entries */ @@ -758,8 +886,19 @@ gp_ref(gp) GP* gp; { gp->gp_refcnt++; + if (gp->gp_cv) { + if (gp->gp_cvgen) { + /* multi-named GPs cannot be used for method cache */ + SvREFCNT_dec(gp->gp_cv); + gp->gp_cv = Nullcv; + gp->gp_cvgen = 0; + } + else { + /* Adding a new name to a subroutine invalidates method cache */ + sub_generation++; + } + } return gp; - } void @@ -775,6 +914,10 @@ GV* gv; warn("Attempt to free unreferenced glob pointers"); return; } + if (gp->gp_cv) { + /* Deleting the name of a subroutine invalidates method cache */ + sub_generation++; + } if (--gp->gp_refcnt > 0) { if (gp->gp_egv == gv) gp->gp_egv = 0; @@ -785,8 +928,7 @@ GV* gv; SvREFCNT_dec(gp->gp_av); SvREFCNT_dec(gp->gp_hv); SvREFCNT_dec(gp->gp_io); - if ((cv = gp->gp_cv) && !GvCVGEN(gv)) - SvREFCNT_dec(cv); + SvREFCNT_dec(gp->gp_cv); SvREFCNT_dec(gp->gp_form); Safefree(gp); @@ -830,14 +972,14 @@ HV* stash; CV* cv; MAGIC* mg=mg_find((SV*)stash,'c'); AMT *amtp=mg ? (AMT*)mg->mg_ptr: NULL; + AMT amt; - if (mg && (amtp=((AMT*)(mg->mg_ptr)))->was_ok_am == amagic_generation && - amtp->was_ok_sub == sub_generation) - return HV_AMAGIC(stash)? TRUE: FALSE; - gvp=(GV**)hv_fetch(stash,"OVERLOAD",8,FALSE); - if (amtp && amtp->table) { + if (mg && amtp->was_ok_am == amagic_generation + && amtp->was_ok_sub == sub_generation) + return AMT_AMAGIC(amtp); + if (amtp && AMT_AMAGIC(amtp)) { /* Have table. */ int i; - for (i=1;i<NofAMmeth*2;i++) { + for (i=1; i<NofAMmeth; i++) { if (amtp->table[i]) { SvREFCNT_dec(amtp->table[i]); } @@ -847,38 +989,33 @@ HV* stash; DEBUG_o( deb("Recalcing overload magic in package %s\n",HvNAME(stash)) ); + amt.was_ok_am = amagic_generation; + amt.was_ok_sub = sub_generation; + amt.fallback = AMGfallNO; + amt.flags = 0; + +#ifdef OVERLOAD_VIA_HASH + gvp=(GV**)hv_fetch(stash,"OVERLOAD",8,FALSE); /* A shortcut */ if (gvp && ((gv = *gvp) != (GV*)&sv_undef && (hv = GvHV(gv)))) { int filled=0; int i; char *cp; - AMT amt; SV* sv; SV** svp; -/* if (*(svp)==(SV*)amagic_generation && *(svp+1)==(SV*)sub_generation) { - DEBUG_o( deb("Overload magic in package %s up-to-date\n",HvNAME(stash)) -); - return HV_AMAGIC(stash)? TRUE: FALSE; - }*/ - - amt.was_ok_am=amagic_generation; - amt.was_ok_sub=sub_generation; - amt.fallback=AMGfallNO; - /* Work with "fallback" key, which we assume to be first in AMG_names */ - if ((cp=((char**)(*AMG_names))[0]) && - (svp=(SV**)hv_fetch(hv,cp,strlen(cp),FALSE)) && (sv = *svp)) { + if (( cp = (char *)AMG_names[0] ) && + (svp = (SV**)hv_fetch(hv,cp,strlen(cp),FALSE)) && (sv = *svp)) { if (SvTRUE(sv)) amt.fallback=AMGfallYES; else if (SvOK(sv)) amt.fallback=AMGfallNEVER; } - - for (i=1;i<NofAMmeth*2;i++) { - cv=0; - - if ( (cp=((char**)(*AMG_names))[i]) ) { - svp=(SV**)hv_fetch(hv,cp,strlen(cp),FALSE); - if (svp && ((sv = *svp) != (GV*)&sv_undef)) { + for (i = 1; i < NofAMmeth; i++) { + cv = 0; + cp = (char *)AMG_names[i]; + + svp = (SV**)hv_fetch(hv, cp, strlen(cp), FALSE); + if (svp && ((sv = *svp) != &sv_undef)) { switch (SvTYPE(sv)) { default: if (!SvROK(sv)) { @@ -893,35 +1030,92 @@ HV* stash; /* FALL THROUGH */ case SVt_PVHV: case SVt_PVAV: - die("Not a subroutine reference in %%OVERLOAD"); + croak("Not a subroutine reference in overload table"); return FALSE; case SVt_PVCV: - cv = (CV*)sv; - break; + cv = (CV*)sv; + break; case SVt_PVGV: - if (!(cv = GvCV((GV*)sv))) - cv = sv_2cv(sv, &stash, &gv, TRUE); - break; + if (!(cv = GvCVu((GV*)sv))) + cv = sv_2cv(sv, &stash, &gv, TRUE); + break; } if (cv) filled=1; else { - die("Method for operation %s not found in package %.256s during blessing\n", + croak("Method for operation %s not found in package %.256s during blessing\n", cp,HvNAME(stash)); return FALSE; } } - } - amt.table[i]=(CV*)SvREFCNT_inc(cv); +#else + { + int filled = 0; + int i; + const char *cp; + SV* sv = NULL; + SV** svp; + + /* Work with "fallback" key, which we assume to be first in AMG_names */ + + if ( cp = AMG_names[0] ) { + /* Try to find via inheritance. */ + gv = gv_fetchmeth(stash, "()", 2, -1); /* A cookie: "()". */ + if (gv) sv = GvSV(gv); + + if (!gv) goto no_table; + else if (SvTRUE(sv)) amt.fallback=AMGfallYES; + else if (SvOK(sv)) amt.fallback=AMGfallNEVER; + } + + for (i = 1; i < NofAMmeth; i++) { + SV *cookie = sv_2mortal(newSVpvf("(%s", cp = AMG_names[i])); + DEBUG_o( deb("Checking overloading of `%s' in package `%.256s'\n", + cp, HvNAME(stash)) ); + /* don't fill the cache while looking up! */ + gv = gv_fetchmeth(stash, SvPVX(cookie), SvCUR(cookie), -1); + cv = 0; + if(gv && (cv = GvCV(gv))) { + if (GvNAMELEN(CvGV(cv)) == 3 && strEQ(GvNAME(CvGV(cv)), "nil") + && strEQ(HvNAME(GvSTASH(CvGV(cv))), "overload")) { + /* GvSV contains the name of the method. */ + GV *ngv; + + DEBUG_o( deb("Resolving method `%.256s' for overloaded `%s' in package `%.256s'\n", + SvPV(GvSV(gv), na), cp, HvNAME(stash)) ); + if (!SvPOK(GvSV(gv)) + || !(ngv = gv_fetchmethod_autoload(stash, SvPVX(GvSV(gv)), + FALSE))) + { + /* Can be an import stub (created by `can'). */ + if (GvCVGEN(gv)) { + croak("Stub found while resolving method `%.256s' overloading `%s' in package `%.256s'", + (SvPOK(GvSV(gv)) ? SvPVX(GvSV(gv)) : "???" ), + cp, HvNAME(stash)); + } else + croak("Cannot resolve method `%.256s' overloading `%s' in package `%.256s'", + (SvPOK(GvSV(gv)) ? SvPVX(GvSV(gv)) : "???" ), + cp, HvNAME(stash)); + } + cv = GvCV(gv = ngv); + } + DEBUG_o( deb("Overloading `%s' in package `%.256s' via `%.256s::%.256s' \n", + cp, HvNAME(stash), HvNAME(GvSTASH(CvGV(cv))), + GvNAME(CvGV(cv))) ); + filled = 1; + } +#endif + amt.table[i]=(CV*)SvREFCNT_inc(cv); } - sv_magic((SV*)stash, 0, 'c', (char*)&amt, sizeof(amt)); if (filled) { -/* HV_badAMAGIC_off(stash);*/ - HV_AMAGIC_on(stash); + AMT_AMAGIC_on(&amt); + sv_magic((SV*)stash, 0, 'c', (char*)&amt, sizeof(AMT)); return TRUE; } } -/*HV_badAMAGIC_off(stash);*/ - HV_AMAGIC_off(stash); + /* Here we have no table: */ + no_table: + AMT_AMAGIC_off(&amt); + sv_magic((SV*)stash, 0, 'c', (char*)&amt, sizeof(AMTS)); return FALSE; } @@ -944,7 +1138,9 @@ int flags; HV* stash; if (!(AMGf_noleft & flags) && SvAMAGIC(left) && (mg = mg_find((SV*)(stash=SvSTASH(SvRV(left))),'c')) - && (ocvp = cvp = ((oamtp=amtp=(AMT*)mg->mg_ptr)->table)) + && (ocvp = cvp = (AMT_AMAGIC((AMT*)mg->mg_ptr) + ? (oamtp = amtp = (AMT*)mg->mg_ptr)->table + : NULL)) && ((cv = cvp[off=method+assignshift]) || (assign && amtp->fallback > AMGfallNEVER && /* fallback to * usual method */ @@ -977,16 +1173,20 @@ int flags; case string_amg: (void)((cv = cvp[off=numer_amg]) || (cv = cvp[off=bool__amg])); break; + case not_amg: + (void)((cv = cvp[off=bool__amg]) + || (cv = cvp[off=numer_amg]) + || (cv = cvp[off=string_amg])); + postpr = 1; + break; case copy_amg: { SV* ref=SvRV(left); - if (!SvROK(ref) && SvTYPE(ref) <= SVt_PVMG) { /* Just to be - * extra - * causious, - * maybe in some - * additional - * cases sv_setsv - * is safe too */ + if (!SvROK(ref) && SvTYPE(ref) <= SVt_PVMG) { + /* + * Just to be extra cautious. Maybe in some + * additional cases sv_setsv is safe, too. + */ SV* newref = newSVsv(ref); SvOBJECT_on(newref); SvSTASH(newref) = (HV*)SvREFCNT_inc(SvSTASH(ref)); @@ -1031,7 +1231,9 @@ int flags; if (!cv) goto not_found; } else if (!(AMGf_noright & flags) && SvAMAGIC(right) && (mg = mg_find((SV*)(stash=SvSTASH(SvRV(right))),'c')) - && (cvp = ((amtp=(AMT*)mg->mg_ptr)->table)) + && (cvp = (AMT_AMAGIC((AMT*)mg->mg_ptr) + ? (amtp = (AMT*)mg->mg_ptr)->table + : NULL)) && (cv = cvp[off=method])) { /* Method for right * argument found */ lr=1; @@ -1041,7 +1243,7 @@ int flags; && !(flags & AMGf_unary)) { /* We look for substitution for * comparison operations and - * concatendation */ + * concatenation */ if (method==concat_amg || method==concat_ass_amg || method==repeat_amg || method==repeat_ass_amg) { return NULL; /* Delegate operation to string conversion */ @@ -1068,15 +1270,18 @@ int flags; goto not_found; } } else { - not_found: /* No method found, either report or die */ + not_found: /* No method found, either report or croak */ if (ocvp && (cv=ocvp[nomethod_amg])) { /* Call report method */ notfound = 1; lr = -1; } else if (cvp && (cv=cvp[nomethod_amg])) { notfound = 1; lr = 1; } else { - if (off==-1) off=method; - sprintf(buf, "Operation `%s': no method found,\n\tleft argument %s%.256s,\n\tright argument %s%.256s", - ((char**)AMG_names)[method + assignshift], + SV *msg; + if (off==-1) off=method; + msg = sv_2mortal(newSVpvf( + "Operation `%s': no method found,%sargument %s%s%s%s", + AMG_names[method + assignshift], + (flags & AMGf_unary ? " " : "\n\tleft "), SvAMAGIC(left)? "in overloaded package ": "has no overloaded magic", @@ -1084,27 +1289,30 @@ int flags; HvNAME(SvSTASH(SvRV(left))): "", SvAMAGIC(right)? - "in overloaded package ": - "has no overloaded magic", + ",\n\tright argument in overloaded package ": + (flags & AMGf_unary + ? "" + : ",\n\tright argument has no overloaded magic"), SvAMAGIC(right)? HvNAME(SvSTASH(SvRV(right))): - ""); + "")); if (amtp && amtp->fallback >= AMGfallYES) { - DEBUG_o( deb(buf) ); + DEBUG_o( deb("%s", SvPVX(msg)) ); } else { - die(buf); + croak("%_", msg); } return NULL; } } } if (!notfound) { - DEBUG_o( deb("Overloaded operator `%s'%s%s%s:\n\tmethod%s found%s in package %.256s%s\n", - ((char**)AMG_names)[off], + DEBUG_o( deb( + "Overloaded operator `%s'%s%s%s:\n\tmethod%s found%s in package %s%s\n", + AMG_names[off], method+assignshift==off? "" : " (initially `", method+assignshift==off? "" : - ((char**)AMG_names)[method+assignshift], + AMG_names[method+assignshift], method+assignshift==off? "" : "')", flags & AMGf_unary? "" : lr==1 ? " for right argument": " for left argument", @@ -1123,24 +1331,28 @@ int flags; dSP; BINOP myop; SV* res; + bool oldcatch = CATCH_GET; + CATCH_SET(TRUE); Zero(&myop, 1, BINOP); myop.op_last = (OP *) &myop; myop.op_next = Nullop; - myop.op_flags = OPf_KNOW|OPf_STACKED; + myop.op_flags = OPf_WANT_SCALAR | OPf_STACKED; ENTER; SAVESPTR(op); op = (OP *) &myop; + if (PERLDB_SUB && curstash != debstash) + op->op_private |= OPpENTERSUB_DB; PUTBACK; pp_pushmark(); EXTEND(sp, notfound + 5); PUSHs(lr>0? right: left); PUSHs(lr>0? left: right); - PUSHs( assign ? &sv_undef : (lr>0? &sv_yes: &sv_no)); + PUSHs( lr > 0 ? &sv_yes : ( assign ? &sv_undef : &sv_no )); if (notfound) { - PUSHs( sv_2mortal(newSVpv(((char**)AMG_names)[method + assignshift],0)) ); + PUSHs( sv_2mortal(newSVpv((char *)AMG_names[method + assignshift],0)) ); } PUSHs((SV*)cv); PUTBACK; @@ -1152,11 +1364,7 @@ int flags; res=POPs; PUTBACK; - - if (notfound) { - /* sv_2mortal(res); */ - return NULL; - } + CATCH_SET(oldcatch); if (postpr) { int ans; @@ -1181,12 +1389,14 @@ int flags; ans=SvIV(res)!=0; break; case inc_amg: case dec_amg: - SvSetSV(left,res); return res; break; + SvSetSV(left,res); return left; + case not_amg: + ans=!SvOK(res); break; } - return ans? &sv_yes: &sv_no; + return boolSV(ans); } else if (method==copy_amg) { if (!SvROK(res)) { - die("Copy method did not return a reference"); + croak("Copy method did not return a reference"); } return SvREFCNT_inc(SvRV(res)); } else { diff --git a/gnu/usr.bin/perl/gv.h b/gnu/usr.bin/perl/gv.h index b823fa59474..804007519e7 100644 --- a/gnu/usr.bin/perl/gv.h +++ b/gnu/usr.bin/perl/gv.h @@ -1,6 +1,6 @@ /* gv.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -13,7 +13,7 @@ struct gp { struct io * gp_io; /* filehandle value */ CV * gp_form; /* format value */ AV * gp_av; /* array value */ - HV * gp_hv; /* associative array value */ + HV * gp_hv; /* hash value */ GV * gp_egv; /* effective gv, if *glob */ CV * gp_cv; /* subroutine value */ U32 gp_cvgen; /* generational validity of cached gv_cv */ @@ -43,6 +43,9 @@ struct gp { #define GvFORM(gv) (GvGP(gv)->gp_form) #define GvAV(gv) (GvGP(gv)->gp_av) +/* This macro is deprecated. Do not use! */ +#define GvREFCNT_inc(gv) ((GV*)SvREFCNT_inc(gv)) /* DO NOT USE */ + #ifdef MICROPORT /* Microport 2.4 hack */ AV *GvAVn(); #else @@ -62,6 +65,7 @@ HV *GvHVn(); #define GvCV(gv) (GvGP(gv)->gp_cv) #define GvCVGEN(gv) (GvGP(gv)->gp_cvgen) +#define GvCVu(gv) (GvGP(gv)->gp_cvgen ? Nullcv : GvGP(gv)->gp_cv) #define GvLASTEXPR(gv) (GvGP(gv)->gp_lastexpr) diff --git a/gnu/usr.bin/perl/handy.h b/gnu/usr.bin/perl/handy.h index aa4107eca55..379fab8b04e 100644 --- a/gnu/usr.bin/perl/handy.h +++ b/gnu/usr.bin/perl/handy.h @@ -1,6 +1,6 @@ /* handy.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -20,9 +20,23 @@ #define Null(type) ((type)NULL) #define Nullch Null(char*) -#define Nullfp Null(FILE*) +#define Nullfp Null(PerlIO*) #define Nullsv Null(SV*) +#ifdef TRUE +#undef TRUE +#endif +#ifdef FALSE +#undef FALSE +#endif +#define TRUE (1) +#define FALSE (0) + + +/* XXX Configure ought to have a test for a boolean type, if I can + just figure out all the headers such a test needs. + Andy Dougherty August 1996 +*/ /* bool is built-in for g++-2.6.3, which might be used for an extension. If the extension includes <_G_config.h> before this file then _G_HAVE_BOOL will be properly set. If, however, the extension includes @@ -37,6 +51,19 @@ # endif #endif +/* The NeXT dynamic loader headers will not build with the bool macro + So declare them now to clear confusion. +*/ +#ifdef NeXT +# undef FALSE +# undef TRUE + typedef enum bool { FALSE = 0, TRUE = 1 } bool; +# define ENUM_BOOL 1 +# ifndef HAS_BOOL +# define HAS_BOOL 1 +# endif /* !HAS_BOOL */ +#endif /* NeXT */ + #ifndef HAS_BOOL # ifdef UTS # define bool int @@ -45,30 +72,69 @@ # endif #endif -#ifdef TRUE -#undef TRUE -#endif -#ifdef FALSE -#undef FALSE -#endif -#define TRUE (1) -#define FALSE (0) +/* XXX A note on the perl source internal type system. The + original intent was that I32 be *exactly* 32 bits. + + Currently, we only guarantee that I32 is *at least* 32 bits. + Specifically, if int is 64 bits, then so is I32. (This is the case + for the Cray.) This has the advantage of meshing nicely with + standard library calls (where we pass an I32 and the library is + expecting an int), but the disadvantage that an I32 is not 32 bits. + Andy Dougherty August 1996 + + In the future, we may perhaps want to think about something like + #if INTSIZE == 4 + typedef I32 int; + #else + # if LONGSIZE == 4 + typedef I32 long; + # else + # if SHORTSIZE == 4 + typedef I32 short; + # else + typedef I32 int; + # endif + # endif + #endif + For the moment, these are mentioned here so metaconfig will + construct Configure to figure out the various sizes. +*/ typedef char I8; typedef unsigned char U8; +/* I8_MAX and I8_MIN constants are not defined, as I8 is an ambiguous type. + Please search CHAR_MAX in perl.h for further details. */ +#define U8_MAX PERL_UCHAR_MAX +#define U8_MIN PERL_UCHAR_MIN typedef short I16; typedef unsigned short U16; +#define I16_MAX PERL_SHORT_MAX +#define I16_MIN PERL_SHORT_MIN +#define U16_MAX PERL_USHORT_MAX +#define U16_MIN PERL_USHORT_MIN #if BYTEORDER > 0x4321 typedef int I32; typedef unsigned int U32; +# define I32_MAX PERL_INT_MAX +# define I32_MIN PERL_INT_MIN +# define U32_MAX PERL_UINT_MAX +# define U32_MIN PERL_UINT_MIN #else typedef long I32; typedef unsigned long U32; +# define I32_MAX PERL_LONG_MAX +# define I32_MIN PERL_LONG_MIN +# define U32_MAX PERL_ULONG_MAX +# define U32_MIN PERL_ULONG_MIN #endif -#define Ctl(ch) (ch & 037) +#define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */ +#define TYPE_DIGITS(T) BIT_DIGITS(sizeof(T) * 8) +#define TYPE_CHARS(T) (TYPE_DIGITS(T) + 2) /* sign, NUL */ + +#define Ctl(ch) ((ch) & 037) #define strNE(s1,s2) (strcmp(s1,s2)) #define strEQ(s1,s2) (!strcmp(s1,s2)) @@ -79,46 +145,97 @@ typedef unsigned short U16; #define strnNE(s1,s2,l) (strncmp(s1,s2,l)) #define strnEQ(s1,s2,l) (!strncmp(s1,s2,l)) +#ifdef HAS_MEMCMP +# define memNE(s1,s2,l) (memcmp(s1,s2,l)) +# define memEQ(s1,s2,l) (!memcmp(s1,s2,l)) +#else +# define memNE(s1,s2,l) (bcmp(s1,s2,l)) +# define memEQ(s1,s2,l) (!bcmp(s1,s2,l)) +#endif + +/* + * Character classes. + * + * Unfortunately, the introduction of locales means that we + * can't trust isupper(), etc. to tell the truth. And when + * it comes to /\w+/ with tainting enabled, we *must* be able + * to trust our character classes. + * + * Therefore, the default tests in the text of Perl will be + * independent of locale. Any code that wants to depend on + * the current locale will use the tests that begin with "lc". + */ + #ifdef HAS_SETLOCALE /* XXX Is there a better test for this? */ # ifndef CTYPE256 # define CTYPE256 # endif #endif -#ifdef USE_NEXT_CTYPE -#define isALNUM(c) (NXIsAlpha((unsigned int)c) || NXIsDigit((unsigned int)c) || c == '_') -#define isIDFIRST(c) (NXIsAlpha((unsigned int)c) || c == '_') -#define isALPHA(c) NXIsAlpha((unsigned int)c) -#define isSPACE(c) NXIsSpace((unsigned int)c) -#define isDIGIT(c) NXIsDigit((unsigned int)c) -#define isUPPER(c) NXIsUpper((unsigned int)c) -#define isLOWER(c) NXIsLower((unsigned int)c) -#define toUPPER(c) NXToUpper((unsigned int)c) -#define toLOWER(c) NXToLower((unsigned int)c) -#else /* USE_NEXT_CTYPE */ -#if defined(CTYPE256) || (!defined(isascii) && !defined(HAS_ISASCII)) -#define isALNUM(c) (isalpha((unsigned char)(c)) || isdigit((unsigned char)(c)) || c == '_') -#define isIDFIRST(c) (isalpha((unsigned char)(c)) || (c) == '_') -#define isALPHA(c) isalpha((unsigned char)(c)) -#define isSPACE(c) isspace((unsigned char)(c)) -#define isDIGIT(c) isdigit((unsigned char)(c)) -#define isUPPER(c) isupper((unsigned char)(c)) -#define isLOWER(c) islower((unsigned char)(c)) -#define toUPPER(c) toupper((unsigned char)(c)) -#define toLOWER(c) tolower((unsigned char)(c)) -#else -#define isALNUM(c) (isascii(c) && (isalpha(c) || isdigit(c) || c == '_')) -#define isIDFIRST(c) (isascii(c) && (isalpha(c) || (c) == '_')) -#define isALPHA(c) (isascii(c) && isalpha(c)) -#define isSPACE(c) (isascii(c) && isspace(c)) -#define isDIGIT(c) (isascii(c) && isdigit(c)) -#define isUPPER(c) (isascii(c) && isupper(c)) -#define isLOWER(c) (isascii(c) && islower(c)) -#define toUPPER(c) toupper(c) -#define toLOWER(c) tolower(c) -#endif +#define isALNUM(c) (isALPHA(c) || isDIGIT(c) || (c) == '_') +#define isIDFIRST(c) (isALPHA(c) || (c) == '_') +#define isALPHA(c) (isUPPER(c) || isLOWER(c)) +#define isSPACE(c) \ + ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) =='\r' || (c) == '\f') +#define isDIGIT(c) ((c) >= '0' && (c) <= '9') +#define isUPPER(c) ((c) >= 'A' && (c) <= 'Z') +#define isLOWER(c) ((c) >= 'a' && (c) <= 'z') +#define isPRINT(c) (((c) > 32 && (c) < 127) || isSPACE(c)) +#define toUPPER(c) (isLOWER(c) ? (c) - ('a' - 'A') : (c)) +#define toLOWER(c) (isUPPER(c) ? (c) + ('a' - 'A') : (c)) + +#ifdef USE_NEXT_CTYPE + +# define isALNUM_LC(c) \ + (NXIsAlpha((unsigned int)(c)) || NXIsDigit((unsigned int)(c)) || \ + (char)(c) == '_') +# define isIDFIRST_LC(c) \ + (NXIsAlpha((unsigned int)(c)) || (char)(c) == '_') +# define isALPHA_LC(c) NXIsAlpha((unsigned int)(c)) +# define isSPACE_LC(c) NXIsSpace((unsigned int)(c)) +# define isDIGIT_LC(c) NXIsDigit((unsigned int)(c)) +# define isUPPER_LC(c) NXIsUpper((unsigned int)(c)) +# define isLOWER_LC(c) NXIsLower((unsigned int)(c)) +# define isPRINT_LC(c) NXIsPrint((unsigned int)(c)) +# define toUPPER_LC(c) NXToUpper((unsigned int)(c)) +# define toLOWER_LC(c) NXToLower((unsigned int)(c)) + +#else /* !USE_NEXT_CTYPE */ +# if defined(CTYPE256) || (!defined(isascii) && !defined(HAS_ISASCII)) + +# define isALNUM_LC(c) \ + (isalpha((unsigned char)(c)) || \ + isdigit((unsigned char)(c)) || (char)(c) == '_') +# define isIDFIRST_LC(c) (isalpha((unsigned char)(c)) || (char)(c) == '_') +# define isALPHA_LC(c) isalpha((unsigned char)(c)) +# define isSPACE_LC(c) isspace((unsigned char)(c)) +# define isDIGIT_LC(c) isdigit((unsigned char)(c)) +# define isUPPER_LC(c) isupper((unsigned char)(c)) +# define isLOWER_LC(c) islower((unsigned char)(c)) +# define isPRINT_LC(c) isprint((unsigned char)(c)) +# define toUPPER_LC(c) toupper((unsigned char)(c)) +# define toLOWER_LC(c) tolower((unsigned char)(c)) + +# else + +# define isALNUM_LC(c) \ + (isascii(c) && (isalpha(c) || isdigit(c) || (c) == '_')) +# define isIDFIRST_LC(c) (isascii(c) && (isalpha(c) || (c) == '_')) +# define isALPHA_LC(c) (isascii(c) && isalpha(c)) +# define isSPACE_LC(c) (isascii(c) && isspace(c)) +# define isDIGIT_LC(c) (isascii(c) && isdigit(c)) +# define isUPPER_LC(c) (isascii(c) && isupper(c)) +# define isLOWER_LC(c) (isascii(c) && islower(c)) +# define isPRINT_LC(c) (isascii(c) && isprint(c)) +# define toUPPER_LC(c) toupper(c) +# define toLOWER_LC(c) tolower(c) + +# endif #endif /* USE_NEXT_CTYPE */ +/* This conversion works both ways, strangely enough. */ +#define toCTRL(c) (toUPPER(c) ^ 64) + /* Line numbers are unsigned, 16 bits. */ typedef U16 line_t; #ifdef lint @@ -127,62 +244,68 @@ typedef U16 line_t; #define NOLINE ((line_t) 65535) #endif +/* XXX LEAKTEST doesn't really work in perl5. There are direct calls to + safemalloc() in the source, so LEAKTEST won't pick them up. + Further, if you try LEAKTEST, you'll also end up calling + Safefree, which might call safexfree() on some things that weren't + malloced with safexmalloc. The correct "fix" to this, if anyone + is interested, is to ensure that all calls go through the New and + Renew macros. + --Andy Dougherty August 1996 +*/ + #ifndef lint #ifndef LEAKTEST -#ifndef safemalloc -char *safemalloc _((MEM_SIZE)); -char *saferealloc _((char *, MEM_SIZE)); -void safefree _((char *)); -#endif -#ifndef MSDOS -#define New(x,v,n,t) (v = (t*)safemalloc((MEM_SIZE)((n) * sizeof(t)))) -#define Newc(x,v,n,t,c) (v = (c*)safemalloc((MEM_SIZE)((n) * sizeof(t)))) -#define Newz(x,v,n,t) (v = (t*)safemalloc((MEM_SIZE)((n) * sizeof(t)))), \ - memzero((char*)(v), (n) * sizeof(t)) -#define Renew(v,n,t) (v = (t*)saferealloc((char*)(v),(MEM_SIZE)((n)*sizeof(t)))) -#define Renewc(v,n,t,c) (v = (c*)saferealloc((char*)(v),(MEM_SIZE)((n)*sizeof(t)))) -#else -#define New(x,v,n,t) (v = (t*)safemalloc(((unsigned long)(n) * sizeof(t)))) -#define Newc(x,v,n,t,c) (v = (c*)safemalloc(((unsigned long)(n) * sizeof(t)))) -#define Newz(x,v,n,t) (v = (t*)safemalloc(((unsigned long)(n) * sizeof(t)))), \ - memzero((char*)(v), (n) * sizeof(t)) -#define Renew(v,n,t) (v = (t*)saferealloc((char*)(v),((unsigned long)(n)*sizeof(t)))) -#define Renewc(v,n,t,c) (v = (c*)saferealloc((char*)(v),((unsigned long)(n)*sizeof(t)))) -#endif /* MSDOS */ -#define Safefree(d) safefree((char*)d) -#define NEWSV(x,len) newSV(len) + +#define New(x,v,n,t) (v = (t*)safemalloc((MEM_SIZE)((n)*sizeof(t)))) +#define Newc(x,v,n,t,c) (v = (c*)safemalloc((MEM_SIZE)((n)*sizeof(t)))) +#define Newz(x,v,n,t) (v = (t*)safemalloc((MEM_SIZE)((n)*sizeof(t)))), \ + memzero((char*)(v), (n)*sizeof(t)) +#define Renew(v,n,t) \ + (v = (t*)saferealloc((Malloc_t)(v),(MEM_SIZE)((n)*sizeof(t)))) +#define Renewc(v,n,t,c) \ + (v = (c*)saferealloc((Malloc_t)(v),(MEM_SIZE)((n)*sizeof(t)))) +#define Safefree(d) safefree((Malloc_t)(d)) +#define NEWSV(x,len) newSV(len) + #else /* LEAKTEST */ -char *safexmalloc(); -char *safexrealloc(); -void safexfree(); -#define New(x,v,n,t) (v = (t*)safexmalloc(x,(MEM_SIZE)((n) * sizeof(t)))) -#define Newc(x,v,n,t,c) (v = (c*)safexmalloc(x,(MEM_SIZE)((n) * sizeof(t)))) -#define Newz(x,v,n,t) (v = (t*)safexmalloc(x,(MEM_SIZE)((n) * sizeof(t)))), \ - memzero((char*)(v), (n) * sizeof(t)) -#define Renew(v,n,t) (v = (t*)safexrealloc((char*)(v),(MEM_SIZE)((n)*sizeof(t)))) -#define Renewc(v,n,t,c) (v = (c*)safexrealloc((char*)(v),(MEM_SIZE)((n)*sizeof(t)))) -#define Safefree(d) safexfree((char*)d) -#define NEWSV(x,len) newSV(x,len) -#define MAXXCOUNT 1200 + +#define New(x,v,n,t) (v = (t*)safexmalloc((x),(MEM_SIZE)((n)*sizeof(t)))) +#define Newc(x,v,n,t,c) (v = (c*)safexmalloc((x),(MEM_SIZE)((n)*sizeof(t)))) +#define Newz(x,v,n,t) (v = (t*)safexmalloc((x),(MEM_SIZE)((n)*sizeof(t)))), \ + memzero((char*)(v), (n)*sizeof(t)) +#define Renew(v,n,t) \ + (v = (t*)safexrealloc((Malloc_t)(v),(MEM_SIZE)((n)*sizeof(t)))) +#define Renewc(v,n,t,c) \ + (v = (c*)safexrealloc((Malloc_t)(v),(MEM_SIZE)((n)*sizeof(t)))) +#define Safefree(d) safexfree((Malloc_t)d) +#define NEWSV(x,len) newSV(x,len) + +#define MAXXCOUNT 1400 long xcount[MAXXCOUNT]; long lastxcount[MAXXCOUNT]; + #endif /* LEAKTEST */ -#define Move(s,d,n,t) (void)memmove((char*)(d),(char*)(s), (n) * sizeof(t)) -#define Copy(s,d,n,t) (void)memcpy((char*)(d),(char*)(s), (n) * sizeof(t)) -#define Zero(d,n,t) (void)memzero((char*)(d), (n) * sizeof(t)) + +#define Move(s,d,n,t) (void)memmove((char*)(d),(char*)(s), (n) * sizeof(t)) +#define Copy(s,d,n,t) (void)memcpy((char*)(d),(char*)(s), (n) * sizeof(t)) +#define Zero(d,n,t) (void)memzero((char*)(d), (n) * sizeof(t)) + #else /* lint */ -#define New(x,v,n,s) (v = Null(s *)) -#define Newc(x,v,n,s,c) (v = Null(s *)) -#define Newz(x,v,n,s) (v = Null(s *)) -#define Renew(v,n,s) (v = Null(s *)) + +#define New(x,v,n,s) (v = Null(s *)) +#define Newc(x,v,n,s,c) (v = Null(s *)) +#define Newz(x,v,n,s) (v = Null(s *)) +#define Renew(v,n,s) (v = Null(s *)) #define Move(s,d,n,t) #define Copy(s,d,n,t) #define Zero(d,n,t) -#define Safefree(d) d = d +#define Safefree(d) (d) = (d) + #endif /* lint */ #ifdef USE_STRUCT_COPY -#define StructCopy(s,d,t) *((t*)(d)) = *((t*)(s)) +#define StructCopy(s,d,t) (*((t*)(d)) = *((t*)(s))) #else #define StructCopy(s,d,t) Copy(s,d,1,t) #endif diff --git a/gnu/usr.bin/perl/hv.c b/gnu/usr.bin/perl/hv.c index d9cbe52337f..4eaae0f08ce 100644 --- a/gnu/usr.bin/perl/hv.c +++ b/gnu/usr.bin/perl/hv.c @@ -1,6 +1,6 @@ /* hv.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -25,7 +25,7 @@ new_he() HE* he; if (he_root) { he = he_root; - he_root = (HE*)he->hent_next; + he_root = HeNEXT(he); return he; } return more_he(); @@ -35,7 +35,7 @@ static void del_he(p) HE* p; { - p->hent_next = (HE*)he_root; + HeNEXT(p) = (HE*)he_root; he_root = p; } @@ -48,13 +48,41 @@ more_he() he = he_root; heend = &he[1008 / sizeof(HE) - 1]; while (he < heend) { - he->hent_next = (HE*)(he + 1); + HeNEXT(he) = (HE*)(he + 1); he++; } - he->hent_next = 0; + HeNEXT(he) = 0; return new_he(); } +static HEK * +save_hek(str, len, hash) +char *str; +I32 len; +U32 hash; +{ + char *k; + register HEK *hek; + + New(54, k, HEK_BASESIZE + len + 1, char); + hek = (HEK*)k; + Copy(str, HEK_KEY(hek), len, char); + *(HEK_KEY(hek) + len) = '\0'; + HEK_LEN(hek) = len; + HEK_HASH(hek) = hash; + return hek; +} + +void +unshare_hek(hek) +HEK *hek; +{ + unsharepvn(HEK_KEY(hek),HEK_LEN(hek),HEK_HASH(hek)); +} + +/* (klen == HEf_SVKEY) is special for MAGICAL hv entries, meaning key slot + * contains an SV* */ + SV** hv_fetch(hv,key,klen,lval) HV *hv; @@ -63,9 +91,7 @@ U32 klen; I32 lval; { register XPVHV* xhv; - register char *s; - register I32 i; - register I32 hash; + register U32 hash; register HE *entry; SV *sv; @@ -93,29 +119,25 @@ I32 lval; return 0; } - i = klen; - hash = 0; - s = key; - while (i--) - hash = hash * 33 + *s++; + PERL_HASH(hash, key, klen); entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; - for (; entry; entry = entry->hent_next) { - if (entry->hent_hash != hash) /* strings can't be equal */ + for (; entry; entry = HeNEXT(entry)) { + if (HeHASH(entry) != hash) /* strings can't be equal */ continue; - if (entry->hent_klen != klen) + if (HeKLEN(entry) != klen) continue; - if (bcmp(entry->hent_key,key,klen)) /* is this it? */ + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ continue; - return &entry->hent_val; + return &HeVAL(entry); } #ifdef DYNAMIC_ENV_FETCH /* %ENV lookup? If so, try to fetch the value now */ if (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME)) { char *gotenv; - gotenv = my_getenv(key); - if (gotenv != NULL) { + if ((gotenv = ENV_getenv(key)) != Nullch) { sv = newSVpv(gotenv,strlen(gotenv)); + SvTAINTED_on(sv); return hv_store(hv,key,klen,sv,hash); } } @@ -127,6 +149,85 @@ I32 lval; return 0; } +/* returns a HE * structure with the all fields set */ +/* note that hent_val will be a mortal sv for MAGICAL hashes */ +HE * +hv_fetch_ent(hv,keysv,lval,hash) +HV *hv; +SV *keysv; +I32 lval; +register U32 hash; +{ + register XPVHV* xhv; + register char *key; + STRLEN klen; + register HE *entry; + SV *sv; + + if (!hv) + return 0; + + if (SvRMAGICAL(hv) && mg_find((SV*)hv,'P')) { + static HE mh; + + sv = sv_newmortal(); + keysv = sv_2mortal(newSVsv(keysv)); + mg_copy((SV*)hv, sv, (char*)keysv, HEf_SVKEY); + if (!HeKEY_hek(&mh)) { + char *k; + New(54, k, HEK_BASESIZE + sizeof(SV*), char); + HeKEY_hek(&mh) = (HEK*)k; + } + HeSVKEY_set(&mh, keysv); + HeVAL(&mh) = sv; + return &mh; + } + + xhv = (XPVHV*)SvANY(hv); + if (!xhv->xhv_array) { + if (lval +#ifdef DYNAMIC_ENV_FETCH /* if it's an %ENV lookup, we may get it on the fly */ + || (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME)) +#endif + ) + Newz(503,xhv->xhv_array, sizeof(HE*) * (xhv->xhv_max + 1), char); + else + return 0; + } + + key = SvPV(keysv, klen); + + if (!hash) + PERL_HASH(hash, key, klen); + + entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; + for (; entry; entry = HeNEXT(entry)) { + if (HeHASH(entry) != hash) /* strings can't be equal */ + continue; + if (HeKLEN(entry) != klen) + continue; + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ + continue; + return entry; + } +#ifdef DYNAMIC_ENV_FETCH /* %ENV lookup? If so, try to fetch the value now */ + if (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME)) { + char *gotenv; + + if ((gotenv = ENV_getenv(key)) != Nullch) { + sv = newSVpv(gotenv,strlen(gotenv)); + SvTAINTED_on(sv); + return hv_store_ent(hv,keysv,sv,hash); + } + } +#endif + if (lval) { /* gonna assign to this, so it better be there */ + sv = NEWSV(61,0); + return hv_store_ent(hv,keysv,sv,hash); + } + return 0; +} + SV** hv_store(hv,key,klen,val,hash) HV *hv; @@ -136,7 +237,6 @@ SV *val; register U32 hash; { register XPVHV* xhv; - register char *s; register I32 i; register HE *entry; register HE **oentry; @@ -147,46 +247,120 @@ register U32 hash; xhv = (XPVHV*)SvANY(hv); if (SvMAGICAL(hv)) { mg_copy((SV*)hv, val, key, klen); -#ifndef OVERLOAD - if (!xhv->xhv_array) - return 0; -#else - if (!xhv->xhv_array && (SvMAGIC(hv)->mg_type != 'A' - || SvMAGIC(hv)->mg_moremagic)) - return 0; + if (!xhv->xhv_array + && (SvMAGIC(hv)->mg_moremagic + || (SvMAGIC(hv)->mg_type != 'E' +#ifdef OVERLOAD + && SvMAGIC(hv)->mg_type != 'A' #endif /* OVERLOAD */ + ))) + return 0; + } + if (!hash) + PERL_HASH(hash, key, klen); + + if (!xhv->xhv_array) + Newz(505, xhv->xhv_array, sizeof(HE**) * (xhv->xhv_max + 1), char); + + oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; + i = 1; + + for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) { + if (HeHASH(entry) != hash) /* strings can't be equal */ + continue; + if (HeKLEN(entry) != klen) + continue; + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ + continue; + SvREFCNT_dec(HeVAL(entry)); + HeVAL(entry) = val; + return &HeVAL(entry); + } + + entry = new_he(); + if (HvSHAREKEYS(hv)) + HeKEY_hek(entry) = share_hek(key, klen, hash); + else /* gotta do the real thing */ + HeKEY_hek(entry) = save_hek(key, klen, hash); + HeVAL(entry) = val; + HeNEXT(entry) = *oentry; + *oentry = entry; + + xhv->xhv_keys++; + if (i) { /* initial entry? */ + ++xhv->xhv_fill; + if (xhv->xhv_keys > xhv->xhv_max) + hsplit(hv); } - if (!hash) { - i = klen; - s = key; - while (i--) - hash = hash * 33 + *s++; + + return &HeVAL(entry); +} + +HE * +hv_store_ent(hv,keysv,val,hash) +HV *hv; +SV *keysv; +SV *val; +register U32 hash; +{ + register XPVHV* xhv; + register char *key; + STRLEN klen; + register I32 i; + register HE *entry; + register HE **oentry; + + if (!hv) + return 0; + + xhv = (XPVHV*)SvANY(hv); + if (SvMAGICAL(hv)) { + bool save_taint = tainted; + if (tainting) + tainted = SvTAINTED(keysv); + keysv = sv_2mortal(newSVsv(keysv)); + mg_copy((SV*)hv, val, (char*)keysv, HEf_SVKEY); + TAINT_IF(save_taint); + if (!xhv->xhv_array + && (SvMAGIC(hv)->mg_moremagic + || (SvMAGIC(hv)->mg_type != 'E' +#ifdef OVERLOAD + && SvMAGIC(hv)->mg_type != 'A' +#endif /* OVERLOAD */ + ))) + return Nullhe; } + key = SvPV(keysv, klen); + + if (!hash) + PERL_HASH(hash, key, klen); + if (!xhv->xhv_array) Newz(505, xhv->xhv_array, sizeof(HE**) * (xhv->xhv_max + 1), char); oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; i = 1; - for (entry = *oentry; entry; i=0, entry = entry->hent_next) { - if (entry->hent_hash != hash) /* strings can't be equal */ + for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) { + if (HeHASH(entry) != hash) /* strings can't be equal */ continue; - if (entry->hent_klen != klen) + if (HeKLEN(entry) != klen) continue; - if (bcmp(entry->hent_key,key,klen)) /* is this it? */ + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ continue; - SvREFCNT_dec(entry->hent_val); - entry->hent_val = val; - return &entry->hent_val; + SvREFCNT_dec(HeVAL(entry)); + HeVAL(entry) = val; + return entry; } entry = new_he(); - entry->hent_klen = klen; - entry->hent_key = savepvn(key,klen); - entry->hent_val = val; - entry->hent_hash = hash; - entry->hent_next = *oentry; + if (HvSHAREKEYS(hv)) + HeKEY_hek(entry) = share_hek(key, klen, hash); + else /* gotta do the real thing */ + HeKEY_hek(entry) = save_hek(key, klen, hash); + HeVAL(entry) = val; + HeNEXT(entry) = *oentry; *oentry = entry; xhv->xhv_keys++; @@ -196,7 +370,7 @@ register U32 hash; hsplit(hv); } - return &entry->hent_val; + return entry; } SV * @@ -207,9 +381,8 @@ U32 klen; I32 flags; { register XPVHV* xhv; - register char *s; register I32 i; - register I32 hash; + register U32 hash; register HE *entry; register HE **oentry; SV *sv; @@ -219,6 +392,9 @@ I32 flags; if (SvRMAGICAL(hv)) { sv = *hv_fetch(hv, key, klen, TRUE); mg_clear(sv); + if (mg_find(sv, 's')) { + return Nullsv; /* %SIG elements cannot be deleted */ + } if (mg_find(sv, 'p')) { sv_unmagic(sv, 'p'); /* No longer an element */ return sv; @@ -227,33 +403,92 @@ I32 flags; xhv = (XPVHV*)SvANY(hv); if (!xhv->xhv_array) return Nullsv; - i = klen; - hash = 0; - s = key; - while (i--) - hash = hash * 33 + *s++; + + PERL_HASH(hash, key, klen); oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; entry = *oentry; i = 1; - for (; entry; i=0, oentry = &entry->hent_next, entry = *oentry) { - if (entry->hent_hash != hash) /* strings can't be equal */ + for (; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) { + if (HeHASH(entry) != hash) /* strings can't be equal */ continue; - if (entry->hent_klen != klen) + if (HeKLEN(entry) != klen) continue; - if (bcmp(entry->hent_key,key,klen)) /* is this it? */ + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ continue; - *oentry = entry->hent_next; + *oentry = HeNEXT(entry); if (i && !*oentry) xhv->xhv_fill--; if (flags & G_DISCARD) sv = Nullsv; else - sv = sv_mortalcopy(entry->hent_val); + sv = sv_mortalcopy(HeVAL(entry)); if (entry == xhv->xhv_eiter) - entry->hent_klen = -1; + HvLAZYDEL_on(hv); else - he_free(entry); + hv_free_ent(hv, entry); + --xhv->xhv_keys; + return sv; + } + return Nullsv; +} + +SV * +hv_delete_ent(hv,keysv,flags,hash) +HV *hv; +SV *keysv; +I32 flags; +U32 hash; +{ + register XPVHV* xhv; + register I32 i; + register char *key; + STRLEN klen; + register HE *entry; + register HE **oentry; + SV *sv; + + if (!hv) + return Nullsv; + if (SvRMAGICAL(hv)) { + entry = hv_fetch_ent(hv, keysv, TRUE, hash); + sv = HeVAL(entry); + mg_clear(sv); + if (mg_find(sv, 'p')) { + sv_unmagic(sv, 'p'); /* No longer an element */ + return sv; + } + } + xhv = (XPVHV*)SvANY(hv); + if (!xhv->xhv_array) + return Nullsv; + + key = SvPV(keysv, klen); + + if (!hash) + PERL_HASH(hash, key, klen); + + oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; + entry = *oentry; + i = 1; + for (; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) { + if (HeHASH(entry) != hash) /* strings can't be equal */ + continue; + if (HeKLEN(entry) != klen) + continue; + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ + continue; + *oentry = HeNEXT(entry); + if (i && !*oentry) + xhv->xhv_fill--; + if (flags & G_DISCARD) + sv = Nullsv; + else + sv = sv_mortalcopy(HeVAL(entry)); + if (entry == xhv->xhv_eiter) + HvLAZYDEL_on(hv); + else + hv_free_ent(hv, entry); --xhv->xhv_keys; return sv; } @@ -267,9 +502,7 @@ char *key; U32 klen; { register XPVHV* xhv; - register char *s; - register I32 i; - register I32 hash; + register U32 hash; register HE *entry; SV *sv; @@ -289,19 +522,62 @@ U32 klen; if (!xhv->xhv_array) return 0; - i = klen; - hash = 0; - s = key; - while (i--) - hash = hash * 33 + *s++; + PERL_HASH(hash, key, klen); + + entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; + for (; entry; entry = HeNEXT(entry)) { + if (HeHASH(entry) != hash) /* strings can't be equal */ + continue; + if (HeKLEN(entry) != klen) + continue; + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ + continue; + return TRUE; + } + return FALSE; +} + + +bool +hv_exists_ent(hv,keysv,hash) +HV *hv; +SV *keysv; +U32 hash; +{ + register XPVHV* xhv; + register char *key; + STRLEN klen; + register HE *entry; + SV *sv; + + if (!hv) + return 0; + + if (SvRMAGICAL(hv)) { + if (mg_find((SV*)hv,'P')) { + sv = sv_newmortal(); + keysv = sv_2mortal(newSVsv(keysv)); + mg_copy((SV*)hv, sv, (char*)keysv, HEf_SVKEY); + magic_existspack(sv, mg_find(sv, 'p')); + return SvTRUE(sv); + } + } + + xhv = (XPVHV*)SvANY(hv); + if (!xhv->xhv_array) + return 0; + + key = SvPV(keysv, klen); + if (!hash) + PERL_HASH(hash, key, klen); entry = ((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; - for (; entry; entry = entry->hent_next) { - if (entry->hent_hash != hash) /* strings can't be equal */ + for (; entry; entry = HeNEXT(entry)) { + if (HeHASH(entry) != hash) /* strings can't be equal */ continue; - if (entry->hent_klen != klen) + if (HeKLEN(entry) != klen) continue; - if (bcmp(entry->hent_key,key,klen)) /* is this it? */ + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ continue; return TRUE; } @@ -357,16 +633,94 @@ HV *hv; continue; b = a+oldsize; for (oentry = a, entry = *a; entry; entry = *oentry) { - if ((entry->hent_hash & newsize) != i) { - *oentry = entry->hent_next; - entry->hent_next = *b; + if ((HeHASH(entry) & newsize) != i) { + *oentry = HeNEXT(entry); + HeNEXT(entry) = *b; if (!*b) xhv->xhv_fill++; *b = entry; continue; } else - oentry = &entry->hent_next; + oentry = &HeNEXT(entry); + } + if (!*a) /* everything moved */ + xhv->xhv_fill--; + } +} + +void +hv_ksplit(hv, newmax) +HV *hv; +IV newmax; +{ + register XPVHV* xhv = (XPVHV*)SvANY(hv); + I32 oldsize = (I32) xhv->xhv_max + 1; /* sic(k) */ + register I32 newsize; + register I32 i; + register I32 j; + register HE **a; + register HE *entry; + register HE **oentry; + + newsize = (I32) newmax; /* possible truncation here */ + if (newsize != newmax || newmax <= oldsize) + return; + while ((newsize & (1 + ~newsize)) != newsize) { + newsize &= ~(newsize & (1 + ~newsize)); /* get proper power of 2 */ + } + if (newsize < newmax) + newsize *= 2; + if (newsize < newmax) + return; /* overflow detection */ + + a = (HE**)xhv->xhv_array; + if (a) { + nomemok = TRUE; +#ifdef STRANGE_MALLOC + Renew(a, newsize, HE*); +#else + i = newsize * sizeof(HE*); + j = MALLOC_OVERHEAD; + while (j - MALLOC_OVERHEAD < i) + j += j; + j -= MALLOC_OVERHEAD; + j /= sizeof(HE*); + assert(j >= newsize); + New(2, a, j, HE*); + Copy(xhv->xhv_array, a, oldsize, HE*); + if (oldsize >= 64 && !nice_chunk) { + nice_chunk = (char*)xhv->xhv_array; + nice_chunk_size = oldsize * sizeof(HE*) * 2 - MALLOC_OVERHEAD; + } + else + Safefree(xhv->xhv_array); +#endif + nomemok = FALSE; + Zero(&a[oldsize], newsize-oldsize, HE*); /* zero 2nd half*/ + } + else { + Newz(0, a, newsize, HE*); + } + xhv->xhv_max = --newsize; + xhv->xhv_array = (char*)a; + if (!xhv->xhv_fill) /* skip rest if no entries */ + return; + + for (i=0; i<oldsize; i++,a++) { + if (!*a) /* non-existent */ + continue; + for (oentry = a, entry = *a; entry; entry = *oentry) { + if ((j = (HeHASH(entry) & newsize)) != i) { + j -= i; + *oentry = HeNEXT(entry); + if (!(HeNEXT(entry) = a[j])) + xhv->xhv_fill++; + a[j] = entry; + continue; + } + else + oentry = &HeNEXT(entry); } if (!*a) /* everything moved */ xhv->xhv_fill--; @@ -384,6 +738,9 @@ newHV() xhv = (XPVHV*)SvANY(hv); SvPOK_off(hv); SvNOK_off(hv); +#ifndef NODEFAULT_SHAREKEYS + HvSHAREKEYS_on(hv); /* key-sharing on by default */ +#endif xhv->xhv_max = 7; /* start with 8 buckets */ xhv->xhv_fill = 0; xhv->xhv_pmroot = 0; @@ -392,25 +749,45 @@ newHV() } void -he_free(hent) -register HE *hent; +hv_free_ent(hv, entry) +HV *hv; +register HE *entry; { - if (!hent) + if (!entry) return; - SvREFCNT_dec(hent->hent_val); - Safefree(hent->hent_key); - del_he(hent); + if (isGV(HeVAL(entry)) && GvCVu(HeVAL(entry)) && HvNAME(hv)) + sub_generation++; /* may be deletion of method from stash */ + SvREFCNT_dec(HeVAL(entry)); + if (HeKLEN(entry) == HEf_SVKEY) { + SvREFCNT_dec(HeKEY_sv(entry)); + Safefree(HeKEY_hek(entry)); + } + else if (HvSHAREKEYS(hv)) + unshare_hek(HeKEY_hek(entry)); + else + Safefree(HeKEY_hek(entry)); + del_he(entry); } void -he_delayfree(hent) -register HE *hent; +hv_delayfree_ent(hv, entry) +HV *hv; +register HE *entry; { - if (!hent) + if (!entry) return; - sv_2mortal(hent->hent_val); /* free between statements */ - Safefree(hent->hent_key); - del_he(hent); + if (isGV(HeVAL(entry)) && GvCVu(HeVAL(entry)) && HvNAME(hv)) + sub_generation++; /* may be deletion of method from stash */ + sv_2mortal(HeVAL(entry)); /* free between statements */ + if (HeKLEN(entry) == HEf_SVKEY) { + sv_2mortal(HeKEY_sv(entry)); + Safefree(HeKEY_hek(entry)); + } + else if (HvSHAREKEYS(hv)) + unshare_hek(HeKEY_hek(entry)); + else + Safefree(HeKEY_hek(entry)); + del_he(entry); } void @@ -436,8 +813,8 @@ hfreeentries(hv) HV *hv; { register HE **array; - register HE *hent; - register HE *ohent = Null(HE*); + register HE *entry; + register HE *oentry = Null(HE*); I32 riter; I32 max; @@ -449,17 +826,17 @@ HV *hv; riter = 0; max = HvMAX(hv); array = HvARRAY(hv); - hent = array[0]; + entry = array[0]; for (;;) { - if (hent) { - ohent = hent; - hent = hent->hent_next; - he_free(ohent); + if (entry) { + oentry = entry; + entry = HeNEXT(entry); + hv_free_ent(hv, oentry); } - if (!hent) { + if (!entry) { if (++riter > max) break; - hent = array[riter]; + entry = array[riter]; } } (void)hv_iterinit(hv); @@ -480,7 +857,7 @@ HV *hv; HvNAME(hv) = 0; } xhv->xhv_array = 0; - xhv->xhv_max = 7; /* it's a normal associative array */ + xhv->xhv_max = 7; /* it's a normal hash */ xhv->xhv_fill = 0; xhv->xhv_keys = 0; @@ -492,13 +869,24 @@ I32 hv_iterinit(hv) HV *hv; { - register XPVHV* xhv = (XPVHV*)SvANY(hv); - HE *entry = xhv->xhv_eiter; - if (entry && entry->hent_klen < 0) /* was deleted earlier? */ - he_free(entry); + register XPVHV* xhv; + HE *entry; + + if (!hv) + croak("Bad hash"); + xhv = (XPVHV*)SvANY(hv); + entry = xhv->xhv_eiter; +#ifdef DYNAMIC_ENV_FETCH /* set up %ENV for iteration */ + if (HvNAME(hv) && strEQ(HvNAME(hv), ENV_HV_NAME)) + prime_env_iter(); +#endif + if (entry && HvLAZYDEL(hv)) { /* was deleted earlier? */ + HvLAZYDEL_off(hv); + hv_free_ent(hv, entry); + } xhv->xhv_riter = -1; xhv->xhv_eiter = Null(HE*); - return xhv->xhv_fill; + return xhv->xhv_fill; /* should be xhv->xhv_keys? May change later */ } HE * @@ -511,31 +899,36 @@ HV *hv; MAGIC* mg; if (!hv) - croak("Bad associative array"); + croak("Bad hash"); xhv = (XPVHV*)SvANY(hv); oldentry = entry = xhv->xhv_eiter; if (SvRMAGICAL(hv) && (mg = mg_find((SV*)hv,'P'))) { SV *key = sv_newmortal(); if (entry) { - sv_usepvn(key, entry->hent_key, entry->hent_klen); - entry->hent_key = 0; + sv_setsv(key, HeSVKEY_force(entry)); + SvREFCNT_dec(HeSVKEY(entry)); /* get rid of previous key */ } else { - xhv->xhv_eiter = entry = new_he(); + char *k; + HEK *hek; + + xhv->xhv_eiter = entry = new_he(); /* one HE per MAGICAL hash */ Zero(entry, 1, HE); + Newz(54, k, HEK_BASESIZE + sizeof(SV*), char); + hek = (HEK*)k; + HeKEY_hek(entry) = hek; + HeKLEN(entry) = HEf_SVKEY; } magic_nextpack((SV*) hv,mg,key); if (SvOK(key)) { - STRLEN len; - entry->hent_key = SvPV_force(key, len); - entry->hent_klen = len; - SvPOK_off(key); - SvPVX(key) = 0; - return entry; + /* force key to stay around until next time */ + HeSVKEY_set(entry, SvREFCNT_inc(key)); + return entry; /* beware, hent_val is not set */ } - if (entry->hent_val) - SvREFCNT_dec(entry->hent_val); + if (HeVAL(entry)) + SvREFCNT_dec(HeVAL(entry)); + Safefree(HeKEY_hek(entry)); del_he(entry); xhv->xhv_eiter = Null(HE*); return Null(HE*); @@ -543,21 +936,21 @@ HV *hv; if (!xhv->xhv_array) Newz(506,xhv->xhv_array, sizeof(HE*) * (xhv->xhv_max + 1), char); - do { - if (entry) - entry = entry->hent_next; - if (!entry) { - ++xhv->xhv_riter; - if (xhv->xhv_riter > xhv->xhv_max) { - xhv->xhv_riter = -1; - break; - } - entry = ((HE**)xhv->xhv_array)[xhv->xhv_riter]; + if (entry) + entry = HeNEXT(entry); + while (!entry) { + ++xhv->xhv_riter; + if (xhv->xhv_riter > xhv->xhv_max) { + xhv->xhv_riter = -1; + break; } - } while (!entry); + entry = ((HE**)xhv->xhv_array)[xhv->xhv_riter]; + } - if (oldentry && oldentry->hent_klen < 0) /* was deleted earlier? */ - he_free(oldentry); + if (oldentry && HvLAZYDEL(hv)) { /* was deleted earlier? */ + HvLAZYDEL_off(hv); + hv_free_ent(hv, oldentry); + } xhv->xhv_eiter = entry; return entry; @@ -568,8 +961,28 @@ hv_iterkey(entry,retlen) register HE *entry; I32 *retlen; { - *retlen = entry->hent_klen; - return entry->hent_key; + if (HeKLEN(entry) == HEf_SVKEY) { + STRLEN len; + char *p = SvPV(HeKEY_sv(entry), len); + *retlen = len; + return p; + } + else { + *retlen = HeKLEN(entry); + return HeKEY(entry); + } +} + +/* unlike hv_iterval(), this always returns a mortal copy of the key */ +SV * +hv_iterkeysv(entry) +register HE *entry; +{ + if (HeKLEN(entry) == HEf_SVKEY) + return sv_mortalcopy(HeKEY_sv(entry)); + else + return sv_2mortal(newSVpv((HeKLEN(entry) ? HeKEY(entry) : ""), + HeKLEN(entry))); } SV * @@ -580,11 +993,13 @@ register HE *entry; if (SvRMAGICAL(hv)) { if (mg_find((SV*)hv,'P')) { SV* sv = sv_newmortal(); - mg_copy((SV*)hv, sv, entry->hent_key, entry->hent_klen); + if (HeKLEN(entry) == HEf_SVKEY) + mg_copy((SV*)hv, sv, (char*)HeKEY_sv(entry), HEf_SVKEY); + else mg_copy((SV*)hv, sv, HeKEY(entry), HeKLEN(entry)); return sv; } } - return entry->hent_val; + return HeVAL(entry); } SV * @@ -608,3 +1023,112 @@ int how; { sv_magic((SV*)hv, (SV*)gv, how, Nullch, 0); } + +char* +sharepvn(sv, len, hash) +char* sv; +I32 len; +U32 hash; +{ + return HEK_KEY(share_hek(sv, len, hash)); +} + +/* possibly free a shared string if no one has access to it + * len and hash must both be valid for str. + */ +void +unsharepvn(str, len, hash) +char* str; +I32 len; +U32 hash; +{ + register XPVHV* xhv; + register HE *entry; + register HE **oentry; + register I32 i = 1; + I32 found = 0; + + /* what follows is the moral equivalent of: + if ((Svp = hv_fetch(strtab, tmpsv, FALSE, hash))) { + if (--*Svp == Nullsv) + hv_delete(strtab, str, len, G_DISCARD, hash); + } */ + xhv = (XPVHV*)SvANY(strtab); + /* assert(xhv_array != 0) */ + oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; + for (entry = *oentry; entry; i=0, oentry = &HeNEXT(entry), entry = *oentry) { + if (HeHASH(entry) != hash) /* strings can't be equal */ + continue; + if (HeKLEN(entry) != len) + continue; + if (memNE(HeKEY(entry),str,len)) /* is this it? */ + continue; + found = 1; + if (--HeVAL(entry) == Nullsv) { + *oentry = HeNEXT(entry); + if (i && !*oentry) + xhv->xhv_fill--; + Safefree(HeKEY_hek(entry)); + del_he(entry); + --xhv->xhv_keys; + } + break; + } + + if (!found) + warn("Attempt to free non-existent shared string"); +} + +/* get a (constant) string ptr from the global string table + * string will get added if it is not already there. + * len and hash must both be valid for str. + */ +HEK * +share_hek(str, len, hash) +char *str; +I32 len; +register U32 hash; +{ + register XPVHV* xhv; + register HE *entry; + register HE **oentry; + register I32 i = 1; + I32 found = 0; + + /* what follows is the moral equivalent of: + + if (!(Svp = hv_fetch(strtab, str, len, FALSE))) + hv_store(strtab, str, len, Nullsv, hash); + */ + xhv = (XPVHV*)SvANY(strtab); + /* assert(xhv_array != 0) */ + oentry = &((HE**)xhv->xhv_array)[hash & (I32) xhv->xhv_max]; + for (entry = *oentry; entry; i=0, entry = HeNEXT(entry)) { + if (HeHASH(entry) != hash) /* strings can't be equal */ + continue; + if (HeKLEN(entry) != len) + continue; + if (memNE(HeKEY(entry),str,len)) /* is this it? */ + continue; + found = 1; + break; + } + if (!found) { + entry = new_he(); + HeKEY_hek(entry) = save_hek(str, len, hash); + HeVAL(entry) = Nullsv; + HeNEXT(entry) = *oentry; + *oentry = entry; + xhv->xhv_keys++; + if (i) { /* initial entry? */ + ++xhv->xhv_fill; + if (xhv->xhv_keys > xhv->xhv_max) + hsplit(strtab); + } + } + + ++HeVAL(entry); /* use value slot as REFCNT */ + return HeKEY_hek(entry); +} + + diff --git a/gnu/usr.bin/perl/hv.h b/gnu/usr.bin/perl/hv.h index 49703632b86..20af4eab578 100644 --- a/gnu/usr.bin/perl/hv.h +++ b/gnu/usr.bin/perl/hv.h @@ -1,6 +1,6 @@ /* hv.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -8,13 +8,18 @@ */ typedef struct he HE; +typedef struct hek HEK; struct he { HE *hent_next; - char *hent_key; + HEK *hent_hek; SV *hent_val; - U32 hent_hash; - I32 hent_klen; +}; + +struct hek { + U32 hek_hash; + I32 hek_len; + char hek_key[1]; }; struct xpvhv { @@ -32,6 +37,21 @@ struct xpvhv { char *xhv_name; /* name, if a symbol table */ }; +#define PERL_HASH(hash,str,len) \ + STMT_START { \ + register char *s_PeRlHaSh = str; \ + register I32 i_PeRlHaSh = len; \ + register U32 hash_PeRlHaSh = 0; \ + while (i_PeRlHaSh--) \ + hash_PeRlHaSh = hash_PeRlHaSh * 33 + *s_PeRlHaSh++; \ + (hash) = hash_PeRlHaSh; \ + } STMT_END + + +/* these hash entry flags ride on hent_klen (for use only in magic/tied HVs) */ +#define HEf_SVKEY -2 /* hent_key is a SV* */ + + #define Nullhv Null(HV*) #define HvARRAY(hv) ((HE**)((XPVHV*) SvANY(hv))->xhv_array) #define HvFILL(hv) ((XPVHV*) SvANY(hv))->xhv_fill @@ -42,6 +62,14 @@ struct xpvhv { #define HvPMROOT(hv) ((XPVHV*) SvANY(hv))->xhv_pmroot #define HvNAME(hv) ((XPVHV*) SvANY(hv))->xhv_name +#define HvSHAREKEYS(hv) (SvFLAGS(hv) & SVphv_SHAREKEYS) +#define HvSHAREKEYS_on(hv) (SvFLAGS(hv) |= SVphv_SHAREKEYS) +#define HvSHAREKEYS_off(hv) (SvFLAGS(hv) &= ~SVphv_SHAREKEYS) + +#define HvLAZYDEL(hv) (SvFLAGS(hv) & SVphv_LAZYDEL) +#define HvLAZYDEL_on(hv) (SvFLAGS(hv) |= SVphv_LAZYDEL) +#define HvLAZYDEL_off(hv) (SvFLAGS(hv) &= ~SVphv_LAZYDEL) + #ifdef OVERLOAD /* Maybe amagical: */ @@ -58,3 +86,34 @@ struct xpvhv { */ #endif /* OVERLOAD */ + +#define Nullhe Null(HE*) +#define HeNEXT(he) (he)->hent_next +#define HeKEY_hek(he) (he)->hent_hek +#define HeKEY(he) HEK_KEY(HeKEY_hek(he)) +#define HeKEY_sv(he) (*(SV**)HeKEY(he)) +#define HeKLEN(he) HEK_LEN(HeKEY_hek(he)) +#define HeVAL(he) (he)->hent_val +#define HeHASH(he) HEK_HASH(HeKEY_hek(he)) +#define HePV(he,lp) ((HeKLEN(he) == HEf_SVKEY) ? \ + SvPV(HeKEY_sv(he),lp) : \ + (((lp = HeKLEN(he)) >= 0) ? \ + HeKEY(he) : Nullch)) + +#define HeSVKEY(he) ((HeKEY(he) && \ + HeKLEN(he) == HEf_SVKEY) ? \ + HeKEY_sv(he) : Nullsv) + +#define HeSVKEY_force(he) (HeKEY(he) ? \ + ((HeKLEN(he) == HEf_SVKEY) ? \ + HeKEY_sv(he) : \ + sv_2mortal(newSVpv(HeKEY(he), \ + HeKLEN(he)))) : \ + &sv_undef) +#define HeSVKEY_set(he,sv) ((HeKLEN(he) = HEf_SVKEY), (HeKEY_sv(he) = sv)) + +#define Nullhek Null(HEK*) +#define HEK_BASESIZE STRUCT_OFFSET(HEK, hek_key[0]) +#define HEK_HASH(hek) (hek)->hek_hash +#define HEK_LEN(hek) (hek)->hek_len +#define HEK_KEY(hek) (hek)->hek_key diff --git a/gnu/usr.bin/perl/installman b/gnu/usr.bin/perl/installman index 38bd0af10e8..4d74bcfea22 100644 --- a/gnu/usr.bin/perl/installman +++ b/gnu/usr.bin/perl/installman @@ -56,36 +56,69 @@ runpod2man('pod', $man1dir, $man1ext); # Install the pods for library modules. runpod2man('lib', $man3dir, $man3ext); +# Install the pods embedded in the installed scripts +runpod2man('utils', $man1dir, $man1ext, 'c2ph'); +runpod2man('utils', $man1dir, $man1ext, 'h2ph'); +runpod2man('utils', $man1dir, $man1ext, 'h2xs'); +runpod2man('utils', $man1dir, $man1ext, 'perldoc'); +runpod2man('utils', $man1dir, $man1ext, 'perlbug'); +runpod2man('utils', $man1dir, $man1ext, 'pl2pm'); +runpod2man('utils', $man1dir, $man1ext, 'splain'); +runpod2man('x2p', $man1dir, $man1ext, 's2p'); +runpod2man('x2p', $man1dir, $man1ext, 'a2p.pod'); +runpod2man('pod', $man1dir, $man1ext, 'pod2man'); +runpod2man('pod', $man1dir, $man1ext, 'pod2html'); + +# It would probably be better to have this page linked +# to the c2ph man page. Or, this one could say ".so man1/c2ph.1", +# but then it would have to pay attention to $man1dir and $man1ext. +runpod2man('utils', $man1dir, $man1ext, 'pstruct'); + +runpod2man('lib/ExtUtils', $man1dir, $man1ext, 'xsubpp'); + sub runpod2man { - my($poddir, $mandir, $manext) = @_; + # $script is script name if we are installing a manpage embedded + # in a script, undef otherwise + my($poddir, $mandir, $manext, $script) = @_; + + my($downdir); # can't just use .. when installing xsubpp manpage + + $downdir = $poddir; + $downdir =~ s:[^/]+:..:g; my($builddir) = Cwd::getcwd(); if ($mandir eq ' ' or $mandir eq '') { - print STDERR "Skipping installation of $poddir man pages.\n"; + print STDERR "Skipping installation of ", + ($script ? "$poddir/$script man page" : "$poddir man pages"), ".\n"; return; } + print STDERR "chdir $poddir\n"; chdir $poddir || die "Unable to cd to $poddir directory!\n$!\n"; # We insist on using the current version of pod2man in case there # are enhancements or changes from previous installed versions. # The error message doesn't include the '..' because the user # won't be aware that we've chdir to $poddir. - -r "../pod/pod2man" || die "Executable pod/pod2man not found.\n"; + -r "$downdir/pod/pod2man" || die "Executable pod/pod2man not found.\n"; # We want to be sure to use the current perl. We can't rely on # the installed perl because it might not be actually installed # yet. (The user may have set the $install* Configure variables # to point to some temporary home, from which the executable gets # installed by occult means.) - $pod2man = "../perl -I ../lib ../pod/pod2man --section=$manext --official"; + $pod2man = "$downdir/perl -I $downdir/lib $downdir/pod/pod2man --section=$manext --official"; - mkpath($mandir, 1, 0777); # In File::Path + mkpath($mandir, 1, 0777) unless $notify; # In File::Path # Make a list of all the .pm and .pod files in the directory. We will # always run pod2man from the lib directory and feed it the full pathname # of the pod. This might be useful for pod2man someday. - @modpods = (); - find(\&lsmodpods, '.'); + if ($script) { + @modpods = ($script); + } else { + @modpods = (); + find(\&lsmodpods, '.'); + } foreach $mod (@modpods) { $manpage = $mod; my $tmp; @@ -96,7 +129,7 @@ sub runpod2man { # Convert name from File/Basename.pm to File::Basename.3 format, # if necessary. $manpage =~ s#\.p(m|od)$##; - if ($^O eq 'os2') { + if ($^O eq 'os2' || $^O eq 'amigaos') { $manpage =~ s#/#.#g; } else { $manpage =~ s#/#::#g; @@ -111,6 +144,7 @@ sub runpod2man { } } chdir "$builddir" || die "Unable to cd back to $builddir directory!\n$!\n"; + print STDERR "chdir $builddir\n"; } sub lsmodpods { @@ -154,7 +188,7 @@ next unless -e $name; chmod 0777, $name if $^O eq 'os2'; print STDERR " unlink $name\n"; ( CORE::unlink($name) and ++$cnt - or warn "Couldn't unlink $name: $!\n" ) unless $nonono; + or warn "Couldn't unlink $name: $!\n" ) unless $notify; } return $cnt; } diff --git a/gnu/usr.bin/perl/installperl b/gnu/usr.bin/perl/installperl index 60eb69b081c..1aea39e7e92 100644 --- a/gnu/usr.bin/perl/installperl +++ b/gnu/usr.bin/perl/installperl @@ -1,14 +1,26 @@ #!./perl -# $OpenBSD: installperl,v 1.5 1997/07/24 21:12:15 kstailey Exp $ +# $OpenBSD: installperl,v 1.6 1997/07/24 21:18:44 kstailey Exp $ # # This is hacked up, in order to support DESTDIR and INSTALL_STRIP. # -BEGIN { @INC=('./lib', '../lib') } +BEGIN { + require 5.004; + @INC = 'lib'; + $ENV{PERL5LIB} = 'lib'; +} + use File::Find; -use File::Path qw(mkpath); +use File::Compare; +use File::Copy (); +use File::Path (); use Config; -use subs qw(unlink rename link chmod); +use subs qw(unlink link chmod cmd); + +# override the ones in the rest of the script +sub mkpath { + File::Path::mkpath(@_) unless $nonono; +} $mainperldir = "/usr/bin"; $exe_ext = $Config{exe_ext}; @@ -21,18 +33,21 @@ while (@ARGV) { umask 022; -@scripts = qw(cppstdin - utils/c2ph utils/h2ph utils/h2xs utils/pstruct - utils/perlbug utils/perldoc +@scripts = qw( utils/c2ph utils/h2ph utils/h2xs + utils/perlbug utils/perldoc utils/pl2pm utils/splain x2p/s2p x2p/find2perl pod/pod2man pod/pod2html pod/pod2latex pod/pod2text); -# pod documentation now handled by separate installman script. -# These two are archaic leftovers. -#@manpages = qw(x2p/a2p.man x2p/s2p.man); - @pods = (<pod/*.pod>); +%archpms = (Config => 1, FileHandle => 1, overload => 1); +find(sub { + if ("$File::Find::dir/$_" =~ m{^ext/[^/]+/(.*)\.pm$}) { + (my $pm = $1) =~ s{^lib/}{}; + $archpms{$pm} = 1; + } + }, 'ext'); + $ver = $]; $release = substr($ver,0,3); # Not used presently. $patchlevel = substr($ver,3,2); @@ -41,9 +56,9 @@ die "Patchlevel of perl ($patchlevel)", if $patchlevel != $Config{'PATCHLEVEL'}; $installdest = $ENV{"DESTDIR"}; +$installdest =~ s:/+$::; if ($installdest ne '') { - # Fetch some frequently-used items from %Config, prefixing them with - # DESTDIR. + # Fetch some frequently-used items from %Config, prefixing with DESTDIR. $installbin = "$installdest/$Config{installbin}"; $installscript = "$installdest/$Config{installscript}"; $installprivlib = "$installdest/$Config{installprivlib}"; @@ -54,18 +69,18 @@ if ($installdest ne '') { # Also whack $mainperldir. $mainperldir = "$installdest/$mainperldir"; } else { - # Fetch some frequently-used items from %Config. + # Fetch some frequently-used items from %Config $installbin = $Config{installbin}; $installscript = $Config{installscript}; $installprivlib = $Config{installprivlib}; $installarchlib = $Config{installarchlib}; $installsitelib = $Config{installsitelib}; $installsitearch = $Config{installsitearch}; + $installman1dir = $Config{installman1dir}; } + $man1ext = $Config{man1ext}; -# Did we build libperl as a shared library? -$d_shrplib = $Config{d_shrplib}; -$shrpdir = $Config{shrpdir}; +$libperl = $Config{libperl}; # Shared library and dynamic loading suffixes. $so = $Config{so}; $dlext = $Config{dlext}; @@ -79,8 +94,8 @@ if ($d_dosuid && $>) { die "You must run as root to install suidperl\n"; } $installbin || die "No installbin directory in config.sh\n"; -d $installbin || mkpath($installbin, 1, 0777); --d $installbin || die "$installbin is not a directory\n"; --w $installbin || die "$installbin is not writable by you\n" +-d $installbin || $nonono || die "$installbin is not a directory\n"; +-w $installbin || $nonono || die "$installbin is not writable by you\n" unless $installbin =~ m#^/afs/# || $nonono; -x 'perl' . $exe_ext || die "perl isn't executable!\n"; @@ -89,91 +104,28 @@ if ($d_dosuid && $>) { die "You must run as root to install suidperl\n"; } -x 't/TEST' || warn "WARNING: You've never run 'make test'!!!", " (Installing anyway.)\n"; -if ($d_shrplib) { - if (!<libperl*.$so*>) { - warn "WARNING: Can't find libperl*.$so* to install into $shrpdir.", - " (Installing other things anyway.)\n"; - } else { - mkpath($shrpdir, 1, 0777); - -w $shrpdir || $nonono || die "$shrpdir is not writable by you\n"; - &cmd("cp libperl*.$so* $shrpdir"); - } -} - # First we install the version-numbered executables. -$installcmd = $ENV{"INSTALL"} +if (defined($ENV{"INSTALL"})) { + $installcmd = $ENV{"INSTALL"} . " " . $ENV{"INSTALL_COPY"} . " " . $ENV{"INSTALL_STRIP"}; - -&safe_unlink("$installbin/perl$ver$exe_ext"); -&cmd("$installcmd perl$exe_ext $installbin/perl$ver$exe_ext"); - -&safe_unlink("$installbin/sperl$ver$exe_ext"); -if ($d_dosuid) { - &cmd("cp suidperl$exe_ext $installbin/sperl$ver$exe_ext"); - &chmod(04711, "$installbin/sperl$ver$exe_ext"); -} - -exit 0 if $versiononly; - -# Make links to ordinary names if installbin directory isn't current directory. - -if (! &samepath($installbin, '.')) { - &safe_unlink("$installbin/perl$exe_ext", "$installbin/suidperl$exe_ext"); - &link("$installbin/perl$ver$exe_ext", "$installbin/perl$exe_ext"); - &link("$installbin/sperl$ver$exe_ext", "$installbin/suidperl$exe_ext") - if $d_dosuid; -} - -if (! &samepath($installbin, 'x2p')) { - &safe_unlink("$installbin/a2p$exe_ext"); - &cmd("$installcmd x2p/a2p$exe_ext $installbin"); - &chmod(0755, "$installbin/a2p$exe_ext"); +} else { + $installcmd = "cp"; } -# Install scripts. - -mkpath($installscript, 1, 0777); +safe_unlink("$installbin/perl$ver$exe_ext"); +cmd("$installcmd perl$exe_ext $installbin/perl$ver$exe_ext"); +#copy("perl$exe_ext", "$installbin/perl$ver$exe_ext"); +chmod(0755, "$installbin/perl$ver$exe_ext"); -for (@scripts) { - if (-f $_) { # cppstdin might not exist on this system. - &cmd("cp $_ $installscript"); - s#.*/##; &chmod(0755, "$installscript/$_"); - } -} - -# Install pod pages. Where? I guess in $installprivlib/pod. -mkpath("${installprivlib}/pod", 1, 0777); -foreach $file (@pods) { - # $file is a name like pod/perl.pod - cp_if_diff($file, "${installprivlib}/${file}"); +safe_unlink("$installbin/sperl$ver$exe_ext"); +if ($d_dosuid) { + cmd("$installcmd suidperl$exe_ext $installbin/sperl$ver$exe_ext"); + #copy("suidperl$exe_ext", "$installbin/sperl$ver$exe_ext"); + chmod(04711, "$installbin/sperl$ver$exe_ext"); } -# Install old man pages. - -#if ($installman1dir ne '') { -# mkpath($installman1dir, 1, 0777); -# -# if (! &samepath($installman1dir, '.')) { -# for (@manpages) { -# ($new = $_) =~ s/man$/$man1ext/; -# $new =~ s#.*/##; -# print STDERR " Installing $installman1dir/$new\n"; -# next if $nonono; -# open(MI,$_) || warn "Can't open $_: $!\n"; -# open(MO,">$installman1dir/$new") || -# warn "Can't install $installman1dir/$new: $!\n"; -# print MO ".ds RP Release $release Patchlevel $patchlevel\n"; -# while (<MI>) { -# print MO; -# } -# close MI; -# close MO; -# } -# } -#} - # Install library files. $do_installarchlib = $do_installprivlib = 0; @@ -184,8 +136,9 @@ mkpath($installsitelib, 1, 0777) if ($installsitelib); mkpath($installsitearch, 1, 0777) if ($installsitearch); if (chdir "lib") { - $do_installarchlib = ! &samepath($installarchlib, '.'); - $do_installprivlib = ! &samepath($installprivlib, '.'); + $do_installarchlib = ! samepath($installarchlib, '.'); + $do_installprivlib = ! samepath($installprivlib, '.'); + $do_installprivlib = 0 if $versiononly && !($installprivlib =~ m/\Q$]/); if ($do_installarchlib || $do_installprivlib) { find(\&installlib, '.'); @@ -198,73 +151,163 @@ else { # Install header files and libraries. mkpath("$installarchlib/CORE", 1, 0777); -foreach $file (<*.h libperl*.*>) { - cp_if_diff($file,"$installarchlib/CORE/$file"); - &chmod(0444,"$installarchlib/CORE/$file"); -} +@corefiles = <*.h libperl*.*>; # AIX needs perl.exp installed as well. -cp_if_diff("perl.exp" ,"$installarchlib/CORE/perl.exp") if ($^O eq 'aix'); - +push(@corefiles,'perl.exp') if $^O eq 'aix'; # If they have built sperl.o... -cp_if_diff("sperl.o" ,"$installarchlib/CORE/sperl.o") if (-f 'sperl.o'); - +push(@corefiles,'sperl.o') if -f 'sperl.o'; +foreach $file (@corefiles) { + # HP-UX (at least) needs to maintain execute permissions + # on dynamically-loadable libraries. So we do it for all. + copy_if_diff($file,"$installarchlib/CORE/$file") + and chmod($file =~ /\.(so|\Q$dlext\E)$/ ? 0555 : 0444, + "$installarchlib/CORE/$file"); +} # Offer to install perl in a "standard" location $mainperl_is_instperl = 0; -if (-w $mainperldir && ! &samepath($mainperldir, $installbin) && !$nonono) { - # First make sure $mainperldir/perl is not already the same as - # the perl we just installed - if (-x "$mainperldir/perl$exe_ext") { +if (!$versiononly && !$nonono && -t STDIN && -t STDERR + && -w $mainperldir && ! samepath($mainperldir, $installbin)) { + local($usrbinperl) = "$mainperldir/perl$exe_ext"; + local($instperl) = "$installbin/perl$exe_ext"; + local($expinstperl) = "$binexp/perl$exe_ext"; + + # First make sure $usrbinperl is not already the same as the perl we + # just installed. + if (-x $usrbinperl) { # Try to be clever about mainperl being a symbolic link # to binexp/perl if binexp and installbin are different. $mainperl_is_instperl = - &samepath("$mainperldir/perl$exe_ext", "$installbin/perl$exe_ext") || + samepath($usrbinperl, $instperl) || + samepath($usrbinperl, $expinstperl) || (($binexp ne $installbin) && - (-l "$mainperldir/perl$exe_ext") && - ((readlink "$mainperldir/perl$exe_ext") eq "$binexp/perl$exe_ext")); + (-l $usrbinperl) && + ((readlink $usrbinperl) eq $expinstperl)); } if ((! $mainperl_is_instperl) && - (&yn("Many scripts expect perl to be installed as " . - "$mainperldir/perl.\n" . - "Do you wish to have $mainperldir/perl be the same as\n" . - "$binexp/perl? [y] "))) + (yn("Many scripts expect perl to be installed as $usrbinperl.\n" . + "Do you wish to have $usrbinperl be the same as\n" . + "$expinstperl? [y] "))) { - unlink("$mainperldir/perl$exe_ext"); - eval 'link("$installbin/perl$exe_ext", "$mainperldir/perl$exe_ext")' || - eval 'symlink("$binexp/perl$exe_ext", "$mainperldir/perl$exe_ext")' || - &cmd("cp $installbin/perl$exe_ext $mainperldir$exe_ext"); + unlink($usrbinperl); + eval { CORE::link $instperl, $usrbinperl } || + eval { symlink $expinstperl, $usrbinperl } || + copy($instperl, $usrbinperl); $mainperl_is_instperl = 1; } } +# Make links to ordinary names if installbin directory isn't current directory. + +if (! $versiononly && ! samepath($installbin, '.')) { + safe_unlink("$installbin/perl$exe_ext", "$installbin/suidperl$exe_ext"); + link("$installbin/perl$ver$exe_ext", "$installbin/perl$exe_ext"); + link("$installbin/sperl$ver$exe_ext", "$installbin/suidperl$exe_ext") + if $d_dosuid; +} + +if (!$versiononly && ! samepath($installbin, 'x2p')) { + safe_unlink("$installbin/a2p$exe_ext"); + copy("x2p/a2p$exe_ext", "$installbin/a2p$exe_ext"); + chmod(0755, "$installbin/a2p$exe_ext"); +} + +# cppstdin is just a script, but it is architecture-dependent, so +# it can't safely be shared. Place it in $installbin. +# Note that Configure doesn't build cppstin if it isn't needed, so +# we skip this if cppstdin doesn't exist. +if (! $versiononly && (-f 'cppstdin') && (! samepath($installbin, '.'))) { + safe_unlink("$installbin/cppstdin"); + copy("cppstdin", "$installbin/cppstdin"); + chmod(0755, "$installbin/cppstdin"); +} + +# Install scripts. + +mkpath($installscript, 1, 0777); + +if (! $versiononly) { + for (@scripts) { + (my $base = $_) =~ s#.*/##; + copy($_, "$installscript/$base"); + chmod(0755, "$installscript/$base"); + } +} + +# pstruct should be a link to c2ph + +if (! $versiononly) { + safe_unlink("$installscript/pstruct"); + link("$installscript/c2ph","$installscript/pstruct"); +} + +# Install pod pages. Where? I guess in $installprivlib/pod. + +if (! $versiononly || !($installprivlib =~ m/\Q$]/)) { + mkpath("${installprivlib}/pod", 1, 0777); + + # If Perl 5.003's perldiag.pod is there, rename it. + if (open POD, "${installprivlib}/pod/perldiag.pod") { + read POD, $_, 4000; + close POD; + # Some of Perl 5.003's diagnostic messages ended with periods. + if (/^=.*\.$/m) { + my ($from, $to) = ("${installprivlib}/pod/perldiag.pod", + "${installprivlib}/pod/perldiag-5.003.pod"); + print STDERR " rename $from $to"; + rename($from, $to) + or warn "Couldn't rename $from to $to: $!\n" + unless $nonono; + } + } + + foreach $file (@pods) { + # $file is a name like pod/perl.pod + copy_if_diff($file, "${installprivlib}/${file}"); + } + + # Link perldiag.pod into archlib + my ($from, $to) = ("${installprivlib}/pod/perldiag.pod", + "${installarchlib}/pod/perldiag.pod"); + if (compare($from, $to) || $nonono) { + mkpath("${installarchlib}/pod", 1, 0777); + unlink($to); + link($from, $to); + } +} + # Check to make sure there aren't other perls around in installer's # path. This is probably UNIX-specific. Check all absolute directories # in the path except for where public executables are supposed to live. # Also skip $mainperl if the user opted to have it be a link to the # installed perl. -$dirsep = ($^O eq 'os2') ? ';' : ':' ; -($path = $ENV{"PATH"}) =~ s:\\:/:g ; -@path = split(/$dirsep/, $path); -@otherperls = (); -for (@path) { - next unless m,^/,; - next if ($_ eq $binexp); - # Use &samepath here because some systems have other dirs linked - # to $mainperldir (like SunOS) - next if ($mainperl_is_instperl && &samepath($_, $mainperldir)); - push(@otherperls, "$_/perl$exe_ext") - if (-x "$_/perl$exe_ext" && ! -d "$_/perl$exe_ext"); -} -if (@otherperls) { - print STDERR "\nWarning: perl appears in your path in the following " . - "locations beyond where\nwe just installed it:\n"; - for (@otherperls) { - print STDERR " ", $_, "\n"; +if (!$versiononly) { + + $dirsep = ($^O eq 'os2') ? ';' : ':' ; + ($path = $ENV{"PATH"}) =~ s:\\:/:g ; + @path = split(/$dirsep/, $path); + @otherperls = (); + for (@path) { + next unless m,^/,; + # Use &samepath here because some systems have other dirs linked + # to $mainperldir (like SunOS) + next if samepath($_, $binexp); + next if ($mainperl_is_instperl && samepath($_, $mainperldir)); + push(@otherperls, "$_/perl$exe_ext") + if (-x "$_/perl$exe_ext" && ! -d "$_/perl$exe_ext"); + } + if (@otherperls) { + print STDERR "\nWarning: perl appears in your path in the following " . + "locations beyond where\nwe just installed it:\n"; + for (@otherperls) { + print STDERR " ", $_, "\n"; + } + print STDERR "\n"; } - print STDERR "\n"; + } print STDERR " Installation complete\n"; @@ -298,37 +341,28 @@ sub unlink { } sub safe_unlink { - local(@names) = @_; - + return if $nonono; + local @names = @_; foreach $name (@names) { next unless -e $name; - next if $nonono; chmod 0777, $name if $^O eq 'os2'; print STDERR " unlink $name\n"; next if CORE::unlink($name); warn "Couldn't unlink $name: $!\n"; if ($! =~ /busy/i) { print STDERR " mv $name $name.old\n"; - &rename($name, "$name.old") || warn "Couldn't rename $name: $!\n"; + safe_rename($name, "$name.old") + or warn "Couldn't rename $name: $!\n"; } } } -sub cmd { - local($cmd) = @_; - print STDERR " $cmd\n"; - unless ($nonono) { - system $cmd; - warn "Command failed!!!\n" if $?; - } -} - -sub rename { +sub safe_rename { local($from,$to) = @_; if (-f $to and not unlink($to)) { my($i); for ($i = 1; $i < 50; $i++) { - last if CORE::rename($to, "$to.$i"); + last if rename($to, "$to.$i"); } warn("Cannot rename to `$to.$i': $!"), return 0 if $i >= 50; # Give up! @@ -338,15 +372,33 @@ sub rename { } sub link { - local($from,$to) = @_; + my($from,$to) = @_; + my($success) = 0; print STDERR " ln $from $to\n"; eval { - CORE::link($from,$to) || warn "Couldn't link $from to $to: $!\n" unless $nonono; + CORE::link($from, $to) + ? $success++ + : ($from =~ m#^/afs/# || $to =~ m#^/afs/#) + ? die "AFS" # okay inside eval {} + : warn "Couldn't link $from to $to: $!\n" + unless $nonono; }; if ($@) { - system( $cp, $from, $to ) - && warn "Couldn't copy $from to $to: $!\n" unless $nonono; + File::Copy::copy($from, $to) + ? $success++ + : warn "Couldn't copy $from to $to: $!\n" + unless $nonono; + } + $success; +} + +sub cmd { + my($cmd) = @_; + print STDERR " $cmd\n"; + unless ($nonono) { + system $cmd; + warn "Command failed!!!\n" if $?; } } @@ -354,8 +406,18 @@ sub chmod { local($mode,$name) = @_; printf STDERR " chmod %o %s\n", $mode, $name; - CORE::chmod($mode,$name) || warn sprintf("Couldn't chmod %o %s: $!\n",$mode,$name) - unless $nonono; + CORE::chmod($mode,$name) + || warn sprintf("Couldn't chmod %o %s: $!\n", $mode, $name) + unless $nonono; +} + +sub copy { + my($from,$to) = @_; + + print STDERR " cp $from $to\n"; + File::Copy::copy($from, $to) + || warn "Couldn't copy $from to $to: $!\n" + unless $nonono; } sub samepath { @@ -375,8 +437,14 @@ sub samepath { sub installlib { my $dir = $File::Find::dir; $dir =~ s#^\.(?![^/])/?##; + local($depth) = $dir ? "lib/$dir" : "lib"; my $name = $_; + + if ($name eq 'CVS' && -d $name) { + $File::Find::prune = 1; + return; + } # ignore patch backups and the .exists files. return if $name =~ m{\.orig$|~$|^\.exists}; @@ -384,7 +452,8 @@ sub installlib { $name = "$dir/$name" if $dir ne ''; my $installlib = $installprivlib; - if ((substr($dir, 0, 4) eq 'auto') || ($name eq 'Config.pm')) { + if ($dir =~ /^auto/ || + ($name =~ /^(.*)\.(?:pm|pod)$/ && $archpms{$1})) { $installlib = $installarchlib; return unless $do_installarchlib; } else { @@ -392,27 +461,22 @@ sub installlib { } if (-f $_) { - if (/\.al$/ || /\.ix$/) { + if (/\.(?:al|ix)$/ && !($dir =~ m[^auto/(.*)$] && $archpms{$1})) { $installlib = $installprivlib; #We're installing *.al and *.ix files into $installprivlib, #but we have to delete old *.al and *.ix files from the 5.000 #distribution: #This might not work because $archname might have changed. - &unlink("$installarchlib/$name"); + unlink("$installarchlib/$name"); } - system "cmp", "-s", $_, "$installlib/$name"; - if ($?) { - &unlink("$installlib/$name"); + if (compare($_, "$installlib/$name") || $nonono) { + unlink("$installlib/$name"); mkpath("$installlib/$dir", 1, 0777); - cp_if_diff($_, "$installlib/$name"); # HP-UX (at least) needs to maintain execute permissions # on dynamically-loaded libraries. - if ($name =~ /\.(so|$dlext)$/o) { - &chmod(0555, "$installlib/$name"); - } - else { - &chmod(0444, "$installlib/$name"); - } + copy_if_diff($_, "$installlib/$name") + and chmod($name =~ /\.(so|$dlext)$/o ? 0555 : 0444, + "$installlib/$name"); } } elsif (-d $_) { mkpath("$installlib/$name", 1, 0777); @@ -427,18 +491,22 @@ sub installlib { # and then try to link against the installed libperl.a, you might # get an error message to the effect that the symbol table is older # than the library. -sub cp_if_diff { +# Return true if copying occurred. + +sub copy_if_diff { my($from,$to)=@_; -f $from || die "$0: $from not found"; - system "cmp", "-s", $from, $to; - if ($?) { - my ($atime, $mtime); - unlink($to); # In case we don't have write permissions. - cmd("cp $from $to"); - # Restore timestamps if it's a .a library. - if ($to =~ /\.a$/) { - ($atime, $mtime) = (stat $from)[8,9]; + if (compare($from, $to) || $nonono) { + safe_unlink($to); # In case we don't have write permissions. + if ($nonono) { + $from = $depth . "/" . $from if $depth; + } + copy($from, $to); + # Restore timestamps if it's a .a library or for OS/2. + if (!$nonono && ($^O eq 'os2' || $to =~ /\.a$/)) { + my ($atime, $mtime) = (stat $from)[8,9]; utime $atime, $mtime, $to; } + 1; } } diff --git a/gnu/usr.bin/perl/interp.sym b/gnu/usr.bin/perl/interp.sym index 801eb41fd9a..753f53dc45c 100644 --- a/gnu/usr.bin/perl/interp.sym +++ b/gnu/usr.bin/perl/interp.sym @@ -18,8 +18,10 @@ chopset copline curblock curcop +curcopdb curcsv curpm +curstack curstash curstname cxstack @@ -29,7 +31,6 @@ dbargs debdelim debname debstash -debug defgv defoutgv defstash @@ -38,7 +39,6 @@ diehook dirty dlevel dlmax -do_undump doextract doswitches dowarn @@ -71,12 +71,14 @@ laststype leftgv lineary localizing +localpatches main_cv main_root main_start mainstack maxscream maxsysfd +mess_sv minus_F minus_a minus_c @@ -101,13 +103,10 @@ origargv origfilename ors orslen -pad -padname parsehook patchlevel perldb perl_destruct_level -pidstatus preambled preambleav preprocess @@ -116,7 +115,6 @@ rightgv rs runlevel sawampersand -sawi sawstudy sawvec screamfirst @@ -128,13 +126,15 @@ sortcop sortstack sortstash splitstr -stack +start_env statcache statgv statname statusvalue +statusvalue_vms stdingv strchop +strtab sv_count sv_objcount sv_root diff --git a/gnu/usr.bin/perl/keywords.h b/gnu/usr.bin/perl/keywords.h index 8cb2748d75b..2be133b7480 100644 --- a/gnu/usr.bin/perl/keywords.h +++ b/gnu/usr.bin/perl/keywords.h @@ -1,245 +1,247 @@ #define KEY_NULL 0 -#define KEY___LINE__ 1 -#define KEY___FILE__ 2 -#define KEY___DATA__ 3 -#define KEY___END__ 4 -#define KEY_AUTOLOAD 5 -#define KEY_BEGIN 6 -#define KEY_CORE 7 -#define KEY_DESTROY 8 -#define KEY_END 9 -#define KEY_EQ 10 -#define KEY_GE 11 -#define KEY_GT 12 -#define KEY_LE 13 -#define KEY_LT 14 -#define KEY_NE 15 -#define KEY_abs 16 -#define KEY_accept 17 -#define KEY_alarm 18 -#define KEY_and 19 -#define KEY_atan2 20 -#define KEY_bind 21 -#define KEY_binmode 22 -#define KEY_bless 23 -#define KEY_caller 24 -#define KEY_chdir 25 -#define KEY_chmod 26 -#define KEY_chomp 27 -#define KEY_chop 28 -#define KEY_chown 29 -#define KEY_chr 30 -#define KEY_chroot 31 -#define KEY_close 32 -#define KEY_closedir 33 -#define KEY_cmp 34 -#define KEY_connect 35 -#define KEY_continue 36 -#define KEY_cos 37 -#define KEY_crypt 38 -#define KEY_dbmclose 39 -#define KEY_dbmopen 40 -#define KEY_defined 41 -#define KEY_delete 42 -#define KEY_die 43 -#define KEY_do 44 -#define KEY_dump 45 -#define KEY_each 46 -#define KEY_else 47 -#define KEY_elsif 48 -#define KEY_endgrent 49 -#define KEY_endhostent 50 -#define KEY_endnetent 51 -#define KEY_endprotoent 52 -#define KEY_endpwent 53 -#define KEY_endservent 54 -#define KEY_eof 55 -#define KEY_eq 56 -#define KEY_eval 57 -#define KEY_exec 58 -#define KEY_exists 59 -#define KEY_exit 60 -#define KEY_exp 61 -#define KEY_fcntl 62 -#define KEY_fileno 63 -#define KEY_flock 64 -#define KEY_for 65 -#define KEY_foreach 66 -#define KEY_fork 67 -#define KEY_format 68 -#define KEY_formline 69 -#define KEY_ge 70 -#define KEY_getc 71 -#define KEY_getgrent 72 -#define KEY_getgrgid 73 -#define KEY_getgrnam 74 -#define KEY_gethostbyaddr 75 -#define KEY_gethostbyname 76 -#define KEY_gethostent 77 -#define KEY_getlogin 78 -#define KEY_getnetbyaddr 79 -#define KEY_getnetbyname 80 -#define KEY_getnetent 81 -#define KEY_getpeername 82 -#define KEY_getpgrp 83 -#define KEY_getppid 84 -#define KEY_getpriority 85 -#define KEY_getprotobyname 86 -#define KEY_getprotobynumber 87 -#define KEY_getprotoent 88 -#define KEY_getpwent 89 -#define KEY_getpwnam 90 -#define KEY_getpwuid 91 -#define KEY_getservbyname 92 -#define KEY_getservbyport 93 -#define KEY_getservent 94 -#define KEY_getsockname 95 -#define KEY_getsockopt 96 -#define KEY_glob 97 -#define KEY_gmtime 98 -#define KEY_goto 99 -#define KEY_grep 100 -#define KEY_gt 101 -#define KEY_hex 102 -#define KEY_if 103 -#define KEY_index 104 -#define KEY_int 105 -#define KEY_ioctl 106 -#define KEY_join 107 -#define KEY_keys 108 -#define KEY_kill 109 -#define KEY_last 110 -#define KEY_lc 111 -#define KEY_lcfirst 112 -#define KEY_le 113 -#define KEY_length 114 -#define KEY_link 115 -#define KEY_listen 116 -#define KEY_local 117 -#define KEY_localtime 118 -#define KEY_log 119 -#define KEY_lstat 120 -#define KEY_lt 121 -#define KEY_m 122 -#define KEY_map 123 -#define KEY_mkdir 124 -#define KEY_msgctl 125 -#define KEY_msgget 126 -#define KEY_msgrcv 127 -#define KEY_msgsnd 128 -#define KEY_my 129 -#define KEY_ne 130 -#define KEY_next 131 -#define KEY_no 132 -#define KEY_not 133 -#define KEY_oct 134 -#define KEY_open 135 -#define KEY_opendir 136 -#define KEY_or 137 -#define KEY_ord 138 -#define KEY_pack 139 -#define KEY_package 140 -#define KEY_pipe 141 -#define KEY_pop 142 -#define KEY_pos 143 -#define KEY_print 144 -#define KEY_printf 145 -#define KEY_prototype 146 -#define KEY_push 147 -#define KEY_q 148 -#define KEY_qq 149 -#define KEY_quotemeta 150 -#define KEY_qw 151 -#define KEY_qx 152 -#define KEY_rand 153 -#define KEY_read 154 -#define KEY_readdir 155 -#define KEY_readline 156 -#define KEY_readlink 157 -#define KEY_readpipe 158 -#define KEY_recv 159 -#define KEY_redo 160 -#define KEY_ref 161 -#define KEY_rename 162 -#define KEY_require 163 -#define KEY_reset 164 -#define KEY_return 165 -#define KEY_reverse 166 -#define KEY_rewinddir 167 -#define KEY_rindex 168 -#define KEY_rmdir 169 -#define KEY_s 170 -#define KEY_scalar 171 -#define KEY_seek 172 -#define KEY_seekdir 173 -#define KEY_select 174 -#define KEY_semctl 175 -#define KEY_semget 176 -#define KEY_semop 177 -#define KEY_send 178 -#define KEY_setgrent 179 -#define KEY_sethostent 180 -#define KEY_setnetent 181 -#define KEY_setpgrp 182 -#define KEY_setpriority 183 -#define KEY_setprotoent 184 -#define KEY_setpwent 185 -#define KEY_setservent 186 -#define KEY_setsockopt 187 -#define KEY_shift 188 -#define KEY_shmctl 189 -#define KEY_shmget 190 -#define KEY_shmread 191 -#define KEY_shmwrite 192 -#define KEY_shutdown 193 -#define KEY_sin 194 -#define KEY_sleep 195 -#define KEY_socket 196 -#define KEY_socketpair 197 -#define KEY_sort 198 -#define KEY_splice 199 -#define KEY_split 200 -#define KEY_sprintf 201 -#define KEY_sqrt 202 -#define KEY_srand 203 -#define KEY_stat 204 -#define KEY_study 205 -#define KEY_sub 206 -#define KEY_substr 207 -#define KEY_symlink 208 -#define KEY_syscall 209 -#define KEY_sysopen 210 -#define KEY_sysread 211 -#define KEY_system 212 -#define KEY_syswrite 213 -#define KEY_tell 214 -#define KEY_telldir 215 -#define KEY_tie 216 -#define KEY_tied 217 -#define KEY_time 218 -#define KEY_times 219 -#define KEY_tr 220 -#define KEY_truncate 221 -#define KEY_uc 222 -#define KEY_ucfirst 223 -#define KEY_umask 224 -#define KEY_undef 225 -#define KEY_unless 226 -#define KEY_unlink 227 -#define KEY_unpack 228 -#define KEY_unshift 229 -#define KEY_untie 230 -#define KEY_until 231 -#define KEY_use 232 -#define KEY_utime 233 -#define KEY_values 234 -#define KEY_vec 235 -#define KEY_wait 236 -#define KEY_waitpid 237 -#define KEY_wantarray 238 -#define KEY_warn 239 -#define KEY_while 240 -#define KEY_write 241 -#define KEY_x 242 -#define KEY_xor 243 -#define KEY_y 244 +#define KEY___FILE__ 1 +#define KEY___LINE__ 2 +#define KEY___PACKAGE__ 3 +#define KEY___DATA__ 4 +#define KEY___END__ 5 +#define KEY_AUTOLOAD 6 +#define KEY_BEGIN 7 +#define KEY_CORE 8 +#define KEY_DESTROY 9 +#define KEY_END 10 +#define KEY_EQ 11 +#define KEY_GE 12 +#define KEY_GT 13 +#define KEY_LE 14 +#define KEY_LT 15 +#define KEY_NE 16 +#define KEY_abs 17 +#define KEY_accept 18 +#define KEY_alarm 19 +#define KEY_and 20 +#define KEY_atan2 21 +#define KEY_bind 22 +#define KEY_binmode 23 +#define KEY_bless 24 +#define KEY_caller 25 +#define KEY_chdir 26 +#define KEY_chmod 27 +#define KEY_chomp 28 +#define KEY_chop 29 +#define KEY_chown 30 +#define KEY_chr 31 +#define KEY_chroot 32 +#define KEY_close 33 +#define KEY_closedir 34 +#define KEY_cmp 35 +#define KEY_connect 36 +#define KEY_continue 37 +#define KEY_cos 38 +#define KEY_crypt 39 +#define KEY_dbmclose 40 +#define KEY_dbmopen 41 +#define KEY_defined 42 +#define KEY_delete 43 +#define KEY_die 44 +#define KEY_do 45 +#define KEY_dump 46 +#define KEY_each 47 +#define KEY_else 48 +#define KEY_elsif 49 +#define KEY_endgrent 50 +#define KEY_endhostent 51 +#define KEY_endnetent 52 +#define KEY_endprotoent 53 +#define KEY_endpwent 54 +#define KEY_endservent 55 +#define KEY_eof 56 +#define KEY_eq 57 +#define KEY_eval 58 +#define KEY_exec 59 +#define KEY_exists 60 +#define KEY_exit 61 +#define KEY_exp 62 +#define KEY_fcntl 63 +#define KEY_fileno 64 +#define KEY_flock 65 +#define KEY_for 66 +#define KEY_foreach 67 +#define KEY_fork 68 +#define KEY_format 69 +#define KEY_formline 70 +#define KEY_ge 71 +#define KEY_getc 72 +#define KEY_getgrent 73 +#define KEY_getgrgid 74 +#define KEY_getgrnam 75 +#define KEY_gethostbyaddr 76 +#define KEY_gethostbyname 77 +#define KEY_gethostent 78 +#define KEY_getlogin 79 +#define KEY_getnetbyaddr 80 +#define KEY_getnetbyname 81 +#define KEY_getnetent 82 +#define KEY_getpeername 83 +#define KEY_getpgrp 84 +#define KEY_getppid 85 +#define KEY_getpriority 86 +#define KEY_getprotobyname 87 +#define KEY_getprotobynumber 88 +#define KEY_getprotoent 89 +#define KEY_getpwent 90 +#define KEY_getpwnam 91 +#define KEY_getpwuid 92 +#define KEY_getservbyname 93 +#define KEY_getservbyport 94 +#define KEY_getservent 95 +#define KEY_getsockname 96 +#define KEY_getsockopt 97 +#define KEY_glob 98 +#define KEY_gmtime 99 +#define KEY_goto 100 +#define KEY_grep 101 +#define KEY_gt 102 +#define KEY_hex 103 +#define KEY_if 104 +#define KEY_index 105 +#define KEY_int 106 +#define KEY_ioctl 107 +#define KEY_join 108 +#define KEY_keys 109 +#define KEY_kill 110 +#define KEY_last 111 +#define KEY_lc 112 +#define KEY_lcfirst 113 +#define KEY_le 114 +#define KEY_length 115 +#define KEY_link 116 +#define KEY_listen 117 +#define KEY_local 118 +#define KEY_localtime 119 +#define KEY_log 120 +#define KEY_lstat 121 +#define KEY_lt 122 +#define KEY_m 123 +#define KEY_map 124 +#define KEY_mkdir 125 +#define KEY_msgctl 126 +#define KEY_msgget 127 +#define KEY_msgrcv 128 +#define KEY_msgsnd 129 +#define KEY_my 130 +#define KEY_ne 131 +#define KEY_next 132 +#define KEY_no 133 +#define KEY_not 134 +#define KEY_oct 135 +#define KEY_open 136 +#define KEY_opendir 137 +#define KEY_or 138 +#define KEY_ord 139 +#define KEY_pack 140 +#define KEY_package 141 +#define KEY_pipe 142 +#define KEY_pop 143 +#define KEY_pos 144 +#define KEY_print 145 +#define KEY_printf 146 +#define KEY_prototype 147 +#define KEY_push 148 +#define KEY_q 149 +#define KEY_qq 150 +#define KEY_quotemeta 151 +#define KEY_qw 152 +#define KEY_qx 153 +#define KEY_rand 154 +#define KEY_read 155 +#define KEY_readdir 156 +#define KEY_readline 157 +#define KEY_readlink 158 +#define KEY_readpipe 159 +#define KEY_recv 160 +#define KEY_redo 161 +#define KEY_ref 162 +#define KEY_rename 163 +#define KEY_require 164 +#define KEY_reset 165 +#define KEY_return 166 +#define KEY_reverse 167 +#define KEY_rewinddir 168 +#define KEY_rindex 169 +#define KEY_rmdir 170 +#define KEY_s 171 +#define KEY_scalar 172 +#define KEY_seek 173 +#define KEY_seekdir 174 +#define KEY_select 175 +#define KEY_semctl 176 +#define KEY_semget 177 +#define KEY_semop 178 +#define KEY_send 179 +#define KEY_setgrent 180 +#define KEY_sethostent 181 +#define KEY_setnetent 182 +#define KEY_setpgrp 183 +#define KEY_setpriority 184 +#define KEY_setprotoent 185 +#define KEY_setpwent 186 +#define KEY_setservent 187 +#define KEY_setsockopt 188 +#define KEY_shift 189 +#define KEY_shmctl 190 +#define KEY_shmget 191 +#define KEY_shmread 192 +#define KEY_shmwrite 193 +#define KEY_shutdown 194 +#define KEY_sin 195 +#define KEY_sleep 196 +#define KEY_socket 197 +#define KEY_socketpair 198 +#define KEY_sort 199 +#define KEY_splice 200 +#define KEY_split 201 +#define KEY_sprintf 202 +#define KEY_sqrt 203 +#define KEY_srand 204 +#define KEY_stat 205 +#define KEY_study 206 +#define KEY_sub 207 +#define KEY_substr 208 +#define KEY_symlink 209 +#define KEY_syscall 210 +#define KEY_sysopen 211 +#define KEY_sysread 212 +#define KEY_sysseek 213 +#define KEY_system 214 +#define KEY_syswrite 215 +#define KEY_tell 216 +#define KEY_telldir 217 +#define KEY_tie 218 +#define KEY_tied 219 +#define KEY_time 220 +#define KEY_times 221 +#define KEY_tr 222 +#define KEY_truncate 223 +#define KEY_uc 224 +#define KEY_ucfirst 225 +#define KEY_umask 226 +#define KEY_undef 227 +#define KEY_unless 228 +#define KEY_unlink 229 +#define KEY_unpack 230 +#define KEY_unshift 231 +#define KEY_untie 232 +#define KEY_until 233 +#define KEY_use 234 +#define KEY_utime 235 +#define KEY_values 236 +#define KEY_vec 237 +#define KEY_wait 238 +#define KEY_waitpid 239 +#define KEY_wantarray 240 +#define KEY_warn 241 +#define KEY_while 242 +#define KEY_write 243 +#define KEY_x 244 +#define KEY_xor 245 +#define KEY_y 246 diff --git a/gnu/usr.bin/perl/keywords.pl b/gnu/usr.bin/perl/keywords.pl index 086a10956ab..aebb3ee2e7c 100644 --- a/gnu/usr.bin/perl/keywords.pl +++ b/gnu/usr.bin/perl/keywords.pl @@ -1,5 +1,6 @@ #!/usr/bin/perl +unlink "keywords.h"; open(KW, ">keywords.h") || die "Can't create keywords.h: $!\n"; select KW; @@ -24,8 +25,9 @@ sub tab { __END__ NULL -__LINE__ __FILE__ +__LINE__ +__PACKAGE__ __DATA__ __END__ AUTOLOAD @@ -235,6 +237,7 @@ symlink syscall sysopen sysread +sysseek system syswrite tell diff --git a/gnu/usr.bin/perl/makeaperl.SH b/gnu/usr.bin/perl/makeaperl.SH index 6af94195d01..16b74350e01 100644 --- a/gnu/usr.bin/perl/makeaperl.SH +++ b/gnu/usr.bin/perl/makeaperl.SH @@ -17,10 +17,11 @@ case "$0" in */*) cd `expr X$0 : 'X\(.*\)/'` ;; esac echo "Extracting makeaperl (with variable substitutions)" +rm -f makeaperl $spitshell >makeaperl <<!GROK!THIS! $startperl - eval 'exec perl -S \$0 "\$@"' - if 0; + eval 'exec $perlpath -S \$0 \${1+"\$@"}' + if \$running_under_some_shell; !GROK!THIS! $spitshell >>makeaperl <<'!NO!SUBS!' diff --git a/gnu/usr.bin/perl/makedepend.SH b/gnu/usr.bin/perl/makedepend.SH index acd9d7ecef3..7a89fa98210 100644 --- a/gnu/usr.bin/perl/makedepend.SH +++ b/gnu/usr.bin/perl/makedepend.SH @@ -1,3 +1,4 @@ +#! /bin/sh case $CONFIG in '') if test -f config.sh; then TOP=.; @@ -16,17 +17,23 @@ esac case "$0" in */*) cd `expr X$0 : 'X\(.*\)/'` ;; esac + echo "Extracting makedepend (with variable substitutions)" rm -f makedepend $spitshell >makedepend <<!GROK!THIS! $startsh # makedepend.SH # -## To use an alternate make, set \$altmake in config.sh. -MAKE=${altmake-make} +MAKE=$make !GROK!THIS! $spitshell >>makedepend <<'!NO!SUBS!' +# This script should be called with +# sh ./makedepend MAKE=$(MAKE) +case "$1" in + MAKE=*) eval $1 ;; +esac + export PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh \$0; kill \$\$) case $CONFIG in @@ -53,17 +60,24 @@ export PATH $cat /dev/null >.deptmp $rm -f *.c.c c/*.c.c if test -f Makefile; then + rm -f $firstmakefile cp Makefile $firstmakefile + # On QNX, 'cp' preserves timestamp, so $firstmakefile appears + # to be out of date. I don't know if OS/2 has touch, so do this: + case "$osname" in + os2) ;; + *) $touch $firstmakefile ;; + esac fi mf=$firstmakefile if test -f $mf; then defrule=`<$mf sed -n \ - -e '/^\.c\(\$(OBJ_EXT)\|\.o\):.*;/{' \ + -e '/^\.c\$(OBJ_EXT):.*;/{' \ -e 's/\$\*\.c//' \ -e 's/^[^;]*;[ ]*//p' \ -e q \ -e '}' \ - -e '/^\.c\(\$(OBJ_EXT)\|\.o\): *$/{' \ + -e '/^\.c\$(OBJ_EXT): *$/{' \ -e N \ -e 's/\$\*\.c//' \ -e 's/^.*\n[ ]*//p' \ @@ -104,6 +118,7 @@ for file in `$cat .clist`; do $cppstdin $finc -I/usr/local/include -I. $cppflags $cppminus <UU/$file.c | $sed \ -e '/^#.*<stdin>/d' \ + -e '/^#.*"-"/d' \ -e 's#\.[0-9][0-9]*\.c#'"$file.c#" \ -e 's/^[ ]*#[ ]*line/#/' \ -e '/^# *[0-9][0-9]* *[".\/]/!d' \ @@ -119,21 +134,27 @@ $sed <$mf >$mf.new -e '1,/^# AUTOMATICALLY/!d' $MAKE shlist || ($echo "Searching for .SH files..."; \ $echo *.SH | $tr ' ' '\012' | $egrep -v '\*' >.shlist) -# Now extract the dependency on makedepend.SH -# (it should reside in the main Makefile): +# Now extract the dependencies on makedepend.SH and Makefile.SH +# (they should reside in the main Makefile): mv .shlist .shlist.old $egrep -v '^makedepend\.SH' <.shlist.old >.shlist +mv .shlist .shlist.old +$egrep -v '^Makefile\.SH' <.shlist.old >.shlist +mv .shlist .shlist.old +$egrep -v '^perl_exp\.SH' <.shlist.old >.shlist +mv .shlist .shlist.old +$egrep -v '^config_h\.SH' <.shlist.old >.shlist rm .shlist.old if $test -s .deptmp; then for file in `cat .shlist`; do $echo `$expr X$file : 'X\(.*\).SH'`: $file $TOP/config.sh \; \ - /bin/sh $file >> .deptmp + $sh $file >> .deptmp done $echo "Updating $mf..." $echo "# If this runs make out of memory, delete /usr/include lines." \ >> $mf.new - $sed 's|^\(.*\(\$(OBJ_EXT)\|\.o\):\) *\(.*/.*\.c\) *$|\1 \3; '"$defrule \2|" .deptmp \ + $sed 's|^\(.*\$(OBJ_EXT):\) *\(.*/.*\.c\) *$|\1 \2; '"$defrule \2|" .deptmp \ >>$mf.new else $MAKE hlist || ($echo "Searching for .h files..."; \ @@ -155,11 +176,12 @@ else $sed -f .hsed >> $mf.new for file in `$cat .shlist`; do $echo `$expr X$file : 'X\(.*\).SH'`: $file $TOP/config.sh \; \ - /bin/sh $file >> $mf.new + $sh $file >> $mf.new done fi $rm -f $mf.old $cp $mf $mf.old +$rm -f $mf $cp $mf.new $mf $rm $mf.new $echo "# WARNING: Put nothing here or make depend will gobble it up!" >> $mf diff --git a/gnu/usr.bin/perl/malloc.c b/gnu/usr.bin/perl/malloc.c index 581cbd37550..e8e9ca3eb12 100644 --- a/gnu/usr.bin/perl/malloc.c +++ b/gnu/usr.bin/perl/malloc.c @@ -2,10 +2,14 @@ * */ +#if defined(PERL_CORE) && !defined(DEBUGGING_MSTATS) +# define DEBUGGING_MSTATS +#endif + #ifndef lint -#ifdef DEBUGGING -#define RCHECK -#endif +# if defined(DEBUGGING) && !defined(NO_RCHECK) +# define RCHECK +# endif /* * malloc.c (Caltech) 2/21/82 * Chris Kingsley, kingsley@cit-20. @@ -14,6 +18,7 @@ * number of different sizes, and keeps free lists of each size. Blocks that * don't exactly fit are passed up to the next larger size. In this * implementation, the available sizes are 2^n-4 (or 2^n-12) bytes long. + * If PACK_MALLOC is defined, small blocks are 2^n bytes long. * This is designed for use in a program that uses vast quantities of memory, * but bombs when it runs out. */ @@ -21,13 +26,26 @@ #include "EXTERN.h" #include "perl.h" +#ifdef DEBUGGING +#undef DEBUG_m +#define DEBUG_m(a) if (debug & 128) a +#endif + /* I don't much care whether these are defined in sys/types.h--LAW */ #define u_char unsigned char #define u_int unsigned int #define u_short unsigned short +/* 286 and atarist like big chunks, which gives too much overhead. */ +#if (defined(RCHECK) || defined(I286) || defined(atarist)) && defined(PACK_MALLOC) +#undef PACK_MALLOC +#endif + + /* + * The description below is applicable if PACK_MALLOC is not defined. + * * The overhead on a block is at least 4 bytes. When free, this space * contains a pointer to the next free block, and the bottom two bits must * be zero. When in use, the first byte is set to MAGIC, and the second @@ -55,7 +73,7 @@ union overhead { #define ov_rmagic ovu.ovu_rmagic }; -#ifdef debug +#ifdef DEBUGGING static void botch _((char *s)); #endif static void morecore _((int bucket)); @@ -64,11 +82,150 @@ static int findbucket _((union overhead *freep, int srchlen)); #define MAGIC 0xff /* magic # on accounting info */ #define RMAGIC 0x55555555 /* magic # on range info */ #ifdef RCHECK -#define RSLOP sizeof (u_int) +# define RSLOP sizeof (u_int) +# ifdef TWO_POT_OPTIMIZE +# define MAX_SHORT_BUCKET 12 +# else +# define MAX_SHORT_BUCKET 13 +# endif #else -#define RSLOP 0 +# define RSLOP 0 #endif +#ifdef PACK_MALLOC +/* + * In this case it is assumed that if we do sbrk() in 2K units, we + * will get 2K aligned blocks. The bucket number of the given subblock is + * on the boundary of 2K block which contains the subblock. + * Several following bytes contain the magic numbers for the subblocks + * in the block. + * + * Sizes of chunks are powers of 2 for chunks in buckets <= + * MAX_PACKED, after this they are (2^n - sizeof(union overhead)) (to + * get alignment right). + * + * We suppose that starts of all the chunks in a 2K block are in + * different 2^n-byte-long chunks. If the top of the last chunk is + * aligned on a boundary of 2K block, this means that + * sizeof(union overhead)*"number of chunks" < 2^n, or + * sizeof(union overhead)*2K < 4^n, or n > 6 + log2(sizeof()/2)/2, if a + * chunk of size 2^n - overhead is used. Since this rules out n = 7 + * for 8 byte alignment, we specialcase allocation of the first of 16 + * 128-byte-long chunks. + * + * Note that with the above assumption we automatically have enough + * place for MAGIC at the start of 2K block. Note also that we + * overlay union overhead over the chunk, thus the start of the chunk + * is immediately overwritten after freeing. + */ +# define MAX_PACKED 6 +# define MAX_2_POT_ALGO ((1<<(MAX_PACKED + 1)) - M_OVERHEAD) +# define TWOK_MASK ((1<<11) - 1) +# define TWOK_MASKED(x) ((u_int)(x) & ~TWOK_MASK) +# define TWOK_SHIFT(x) ((u_int)(x) & TWOK_MASK) +# define OV_INDEXp(block) ((u_char*)(TWOK_MASKED(block))) +# define OV_INDEX(block) (*OV_INDEXp(block)) +# define OV_MAGIC(block,bucket) (*(OV_INDEXp(block) + \ + (TWOK_SHIFT(block)>>(bucket + 3)) + \ + (bucket > MAX_NONSHIFT ? 1 : 0))) +# define CHUNK_SHIFT 0 + +static u_char n_blks[11 - 3] = {224, 120, 62, 31, 16, 8, 4, 2}; +static u_short blk_shift[11 - 3] = {256, 128, 64, 32, + 16*sizeof(union overhead), + 8*sizeof(union overhead), + 4*sizeof(union overhead), + 2*sizeof(union overhead), +# define MAX_NONSHIFT 2 /* Shift 64 greater than chunk 32. */ +}; + +#else /* !PACK_MALLOC */ + +# define OV_MAGIC(block,bucket) (block)->ov_magic +# define OV_INDEX(block) (block)->ov_index +# define CHUNK_SHIFT 1 +#endif /* !PACK_MALLOC */ + +# define M_OVERHEAD (sizeof(union overhead) + RSLOP) + +/* + * Big allocations are often of the size 2^n bytes. To make them a + * little bit better, make blocks of size 2^n+pagesize for big n. + */ + +#ifdef TWO_POT_OPTIMIZE + +# ifndef PERL_PAGESIZE +# define PERL_PAGESIZE 4096 +# endif +# ifndef FIRST_BIG_TWO_POT +# define FIRST_BIG_TWO_POT 14 /* 16K */ +# endif +# define FIRST_BIG_BLOCK (1<<FIRST_BIG_TWO_POT) /* 16K */ +/* If this value or more, check against bigger blocks. */ +# define FIRST_BIG_BOUND (FIRST_BIG_BLOCK - M_OVERHEAD) +/* If less than this value, goes into 2^n-overhead-block. */ +# define LAST_SMALL_BOUND ((FIRST_BIG_BLOCK>>1) - M_OVERHEAD) + +#endif /* TWO_POT_OPTIMIZE */ + +#if defined(PERL_EMERGENCY_SBRK) && defined(PERL_CORE) + +#ifndef BIG_SIZE +# define BIG_SIZE (1<<16) /* 64K */ +#endif + +static char *emergency_buffer; +static MEM_SIZE emergency_buffer_size; + +static char * +emergency_sbrk(size) + MEM_SIZE size; +{ + if (size >= BIG_SIZE) { + /* Give the possibility to recover: */ + die("Out of memory during request for %i bytes", size); + /* croak may eat too much memory. */ + } + + if (!emergency_buffer) { + /* First offense, give a possibility to recover by dieing. */ + /* No malloc involved here: */ + GV **gvp = (GV**)hv_fetch(defstash, "^M", 2, 0); + SV *sv; + char *pv; + + if (!gvp) gvp = (GV**)hv_fetch(defstash, "\015", 1, 0); + if (!gvp || !(sv = GvSV(*gvp)) || !SvPOK(sv) + || (SvLEN(sv) < (1<<11) - M_OVERHEAD)) + return (char *)-1; /* Now die die die... */ + + /* Got it, now detach SvPV: */ + pv = SvPV(sv, na); + /* Check alignment: */ + if (((u_int)(pv - M_OVERHEAD)) & ((1<<11) - 1)) { + PerlIO_puts(PerlIO_stderr(),"Bad alignment of $^M!\n"); + return (char *)-1; /* die die die */ + } + + emergency_buffer = pv - M_OVERHEAD; + emergency_buffer_size = SvLEN(sv) + M_OVERHEAD; + SvPOK_off(sv); + SvREADONLY_on(sv); + die("Out of memory!"); /* croak may eat too much memory. */ + } + else if (emergency_buffer_size >= size) { + emergency_buffer_size -= size; + return emergency_buffer + emergency_buffer_size; + } + + return (char *)-1; /* poor guy... */ +} + +#else /* !(defined(TWO_POT_OPTIMIZE) && defined(PERL_CORE)) */ +# define emergency_sbrk(size) -1 +#endif /* !(defined(TWO_POT_OPTIMIZE) && defined(PERL_CORE)) */ + /* * nextf[i] is the pointer to the next free block of size 2^(i+3). The * smallest allocatable block is 8 bytes. The overhead information @@ -76,7 +233,13 @@ static int findbucket _((union overhead *freep, int srchlen)); */ #define NBUCKETS 30 static union overhead *nextf[NBUCKETS]; + +#ifdef USE_PERL_SBRK +#define sbrk(a) Perl_sbrk(a) +char * Perl_sbrk _((int size)); +#else extern char *sbrk(); +#endif #ifdef DEBUGGING_MSTATS /* @@ -84,17 +247,18 @@ extern char *sbrk(); * for a given block size. */ static u_int nmalloc[NBUCKETS]; -#include <stdio.h> +static u_int goodsbrk; +static u_int sbrk_slack; +static u_int start_slack; #endif -#ifdef debug -#define ASSERT(p) if (!(p)) botch("p"); else +#ifdef DEBUGGING +#define ASSERT(p) if (!(p)) botch(STRINGIFY(p)); else static void botch(s) char *s; { - - printf("assertion botched: %s\n", s); + PerlIO_printf(PerlIO_stderr(), "assertion botched: %s\n", s); abort(); } #else @@ -109,22 +273,23 @@ malloc(nbytes) register int bucket = 0; register MEM_SIZE shiftr; -#ifdef safemalloc -#ifdef DEBUGGING +#if defined(DEBUGGING) || defined(RCHECK) MEM_SIZE size = nbytes; #endif -#ifdef MSDOS +#ifdef PERL_CORE +#ifdef HAS_64K_LIMIT if (nbytes > 0xffff) { - fprintf(stderr, "Allocation too large: %lx\n", (long)nbytes); + PerlIO_printf(PerlIO_stderr(), + "Allocation too large: %lx\n", (long)nbytes); my_exit(1); } -#endif /* MSDOS */ +#endif /* HAS_64K_LIMIT */ #ifdef DEBUGGING if ((long)nbytes < 0) - croak("panic: malloc"); + croak("panic: malloc"); #endif -#endif /* safemalloc */ +#endif /* PERL_CORE */ /* * Convert amount of memory requested into @@ -132,8 +297,19 @@ malloc(nbytes) * which satisfies request. Account for * space used per block for accounting. */ - nbytes += sizeof (union overhead) + RSLOP; - nbytes = (nbytes + 3) &~ 3; +#ifdef PACK_MALLOC + if (nbytes == 0) + nbytes = 1; + else if (nbytes > MAX_2_POT_ALGO) +#endif + { +#ifdef TWO_POT_OPTIMIZE + if (nbytes >= FIRST_BIG_BOUND) + nbytes -= PERL_PAGESIZE; +#endif + nbytes += M_OVERHEAD; + nbytes = (nbytes + 3) &~ 3; + } shiftr = (nbytes - 1) >> 2; /* apart from this loop, this is O(1) */ while (shiftr >>= 1) @@ -145,9 +321,9 @@ malloc(nbytes) if (nextf[bucket] == NULL) morecore(bucket); if ((p = (union overhead *)nextf[bucket]) == NULL) { -#ifdef safemalloc +#ifdef PERL_CORE if (!nomemok) { - fputs("Out of memory!\n", stderr); + PerlIO_puts(PerlIO_stderr(),"Out of memory!\n"); my_exit(1); } #else @@ -155,34 +331,34 @@ malloc(nbytes) #endif } -#ifdef safemalloc - DEBUG_m(fprintf(stderr,"0x%lx: (%05d) malloc %ld bytes\n", - (unsigned long)(p+1),an++,(long)size)); -#endif /* safemalloc */ +#ifdef PERL_CORE + DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05lu) malloc %ld bytes\n", + (unsigned long)(p+1),(unsigned long)(an++),(long)size)); +#endif /* PERL_CORE */ /* remove from linked list */ #ifdef RCHECK if (*((int*)p) & (sizeof(union overhead) - 1)) - fprintf(stderr,"Corrupt malloc ptr 0x%lx at 0x%lx\n", + PerlIO_printf(PerlIO_stderr(), "Corrupt malloc ptr 0x%lx at 0x%lx\n", (unsigned long)*((int*)p),(unsigned long)p); #endif nextf[bucket] = p->ov_next; - p->ov_magic = MAGIC; - p->ov_index= bucket; -#ifdef DEBUGGING_MSTATS - nmalloc[bucket]++; + OV_MAGIC(p, bucket) = MAGIC; +#ifndef PACK_MALLOC + OV_INDEX(p) = bucket; #endif #ifdef RCHECK /* * Record allocated size of block and * bound space with magic numbers. */ + nbytes = (size + M_OVERHEAD + 3) &~ 3; if (nbytes <= 0x10000) p->ov_size = nbytes - 1; p->ov_rmagic = RMAGIC; *((u_int *)((caddr_t)p + nbytes - RSLOP)) = RMAGIC; #endif - return ((Malloc_t)(p + 1)); + return ((Malloc_t)(p + CHUNK_SHIFT)); } /* @@ -195,10 +371,14 @@ morecore(bucket) register union overhead *op; register int rnu; /* 2^rnu bytes will be requested */ register int nblks; /* become nblks blocks of the desired size */ - register MEM_SIZE siz; + register MEM_SIZE siz, needed; + int slack = 0; if (nextf[bucket]) return; + if (bucket == (sizeof(MEM_SIZE)*8 - 3)) { + croak("Allocation too large"); + } /* * Insure memory is allocated * on a page boundary. Should @@ -206,12 +386,17 @@ morecore(bucket) */ #ifndef atarist /* on the atari we dont have to worry about this */ op = (union overhead *)sbrk(0); -#ifndef I286 - if ((int)op & 0x3ff) - (void)sbrk(1024 - ((int)op & 0x3ff)); -#else +# ifndef I286 + if ((UV)op & (0x7FF >> CHUNK_SHIFT)) { + slack = (0x800 >> CHUNK_SHIFT) - ((UV)op & (0x7FF >> CHUNK_SHIFT)); + (void)sbrk(slack); +# if defined(DEBUGGING_MSTATS) + sbrk_slack += slack; +# endif + } +# else /* The sbrk(0) call on the I286 always returns the next segment */ -#endif +# endif #endif /* atarist */ #if !(defined(I286) || defined(atarist)) @@ -223,19 +408,31 @@ morecore(bucket) rnu = (bucket <= 11) ? 14 : bucket + 3; #endif nblks = 1 << (rnu - (bucket + 3)); /* how many blocks to get */ - if (rnu < bucket) - rnu = bucket; - op = (union overhead *)sbrk(1L << rnu); + needed = (MEM_SIZE)1 << rnu; +#ifdef TWO_POT_OPTIMIZE + needed += (bucket >= (FIRST_BIG_TWO_POT - 3) ? PERL_PAGESIZE : 0); +#endif + op = (union overhead *)sbrk(needed); /* no more room! */ - if ((int)op == -1) + if (op == (union overhead *)-1) { + op = (union overhead *)emergency_sbrk(needed); + if (op == (union overhead *)-1) return; + } +#ifdef DEBUGGING_MSTATS + goodsbrk += needed; +#endif /* * Round up to minimum allocation size boundary * and deduct from block count to reflect. */ #ifndef I286 - if ((int)op & 7) { - op = (union overhead *)(((MEM_SIZE)op + 8) &~ 7); +# ifdef PACK_MALLOC + if ((UV)op & 0x7FF) + croak("panic: Off-page sbrk"); +# endif + if ((UV)op & 7) { + op = (union overhead *)(((UV)op + 8) & ~7); nblks--; } #else @@ -245,12 +442,39 @@ morecore(bucket) * Add new memory allocated to that on * free list for this hash bucket. */ - nextf[bucket] = op; siz = 1 << (bucket + 3); +#ifdef PACK_MALLOC + *(u_char*)op = bucket; /* Fill index. */ + if (bucket <= MAX_PACKED - 3) { + op = (union overhead *) ((char*)op + blk_shift[bucket]); + nblks = n_blks[bucket]; +# ifdef DEBUGGING_MSTATS + start_slack += blk_shift[bucket]; +# endif + } else if (bucket <= 11 - 1 - 3) { + op = (union overhead *) ((char*)op + blk_shift[bucket]); + /* nblks = n_blks[bucket]; */ + siz -= sizeof(union overhead); + } else op++; /* One chunk per block. */ +#endif /* !PACK_MALLOC */ + nextf[bucket] = op; +#ifdef DEBUGGING_MSTATS + nmalloc[bucket] += nblks; +#endif while (--nblks > 0) { op->ov_next = (union overhead *)((caddr_t)op + siz); op = (union overhead *)((caddr_t)op + siz); } + /* Not all sbrks return zeroed memory.*/ + op->ov_next = (union overhead *)NULL; +#ifdef PACK_MALLOC + if (bucket == 7 - 3) { /* Special case, explanation is above. */ + union overhead *n_op = nextf[7 - 3]->ov_next; + nextf[7 - 3] = (union overhead *)((caddr_t)nextf[7 - 3] + - sizeof(union overhead)); + nextf[7 - 3]->ov_next = n_op; + } +#endif /* !PACK_MALLOC */ } Free_t @@ -260,18 +484,29 @@ free(mp) register MEM_SIZE size; register union overhead *op; char *cp = (char*)mp; - -#ifdef safemalloc - DEBUG_m(fprintf(stderr,"0x%lx: (%05d) free\n",(unsigned long)cp,an++)); -#endif /* safemalloc */ - - if (cp == NULL) - return; - op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); -#ifdef debug - ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */ -#else - if (op->ov_magic != MAGIC) { +#ifdef PACK_MALLOC + u_char bucket; +#endif + +#ifdef PERL_CORE + DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05lu) free\n",(unsigned long)cp,(unsigned long)(an++))); +#endif /* PERL_CORE */ + + if (cp == NULL) + return; + op = (union overhead *)((caddr_t)cp + - sizeof (union overhead) * CHUNK_SHIFT); +#ifdef PACK_MALLOC + bucket = OV_INDEX(op); +#endif + if (OV_MAGIC(op, bucket) != MAGIC) { + static int bad_free_warn = -1; + if (bad_free_warn == -1) { + char *pbf = getenv("PERL_BADFREE"); + bad_free_warn = (pbf) ? atoi(pbf) : 1; + } + if (!bad_free_warn) + return; #ifdef RCHECK warn("%s free() ignored", op->ov_rmagic == RMAGIC - 1 ? "Duplicate" : "Bad"); @@ -280,20 +515,16 @@ free(mp) #endif return; /* sanity */ } -#endif #ifdef RCHECK ASSERT(op->ov_rmagic == RMAGIC); - if (op->ov_index <= 13) + if (OV_INDEX(op) <= MAX_SHORT_BUCKET) ASSERT(*(u_int *)((caddr_t)op + op->ov_size + 1 - RSLOP) == RMAGIC); op->ov_rmagic = RMAGIC - 1; #endif - ASSERT(op->ov_index < NBUCKETS); - size = op->ov_index; + ASSERT(OV_INDEX(op) < NBUCKETS); + size = OV_INDEX(op); op->ov_next = nextf[size]; nextf[size] = op; -#ifdef DEBUGGING_MSTATS - nmalloc[size]--; -#endif } /* @@ -321,29 +552,31 @@ realloc(mp, nbytes) int was_alloced = 0; char *cp = (char*)mp; -#ifdef safemalloc #ifdef DEBUGGING MEM_SIZE size = nbytes; #endif -#ifdef MSDOS +#ifdef PERL_CORE +#ifdef HAS_64K_LIMIT if (nbytes > 0xffff) { - fprintf(stderr, "Reallocation too large: %lx\n", size); + PerlIO_printf(PerlIO_stderr(), + "Reallocation too large: %lx\n", size); my_exit(1); } -#endif /* MSDOS */ +#endif /* HAS_64K_LIMIT */ if (!cp) return malloc(nbytes); #ifdef DEBUGGING if ((long)nbytes < 0) croak("panic: realloc"); #endif -#endif /* safemalloc */ +#endif /* PERL_CORE */ - op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); - if (op->ov_magic == MAGIC) { - was_alloced++; - i = op->ov_index; + op = (union overhead *)((caddr_t)cp + - sizeof (union overhead) * CHUNK_SHIFT); + i = OV_INDEX(op); + if (OV_MAGIC(op, i) == MAGIC) { + was_alloced = 1; } else { /* * Already free, doing "compaction". @@ -360,23 +593,43 @@ realloc(mp, nbytes) (i = findbucket(op, reall_srchlen)) < 0) i = 0; } - onb = (1L << (i + 3)) - sizeof (*op) - RSLOP; - /* avoid the copy if same size block */ + onb = (1L << (i + 3)) - +#ifdef PACK_MALLOC + (i <= (MAX_PACKED - 3) ? 0 : M_OVERHEAD) +#else + M_OVERHEAD +#endif +#ifdef TWO_POT_OPTIMIZE + + (i >= (FIRST_BIG_TWO_POT - 3) ? PERL_PAGESIZE : 0) +#endif + ; + /* + * avoid the copy if same size block. + * We are not agressive with boundary cases. Note that it is + * possible for small number of cases give false negative if + * both new size and old one are in the bucket for + * FIRST_BIG_TWO_POT, but the new one is near the lower end. + */ if (was_alloced && - nbytes <= onb && nbytes > (onb >> 1) - sizeof(*op) - RSLOP) { + nbytes <= onb && (nbytes > ( (onb >> 1) - M_OVERHEAD ) +#ifdef TWO_POT_OPTIMIZE + || (i == (FIRST_BIG_TWO_POT - 3) + && nbytes >= LAST_SMALL_BOUND ) +#endif + )) { #ifdef RCHECK /* * Record new allocated size of block and * bound space with magic numbers. */ - if (op->ov_index <= 13) { + if (OV_INDEX(op) <= MAX_SHORT_BUCKET) { /* * Convert amount of memory requested into * closest block size stored in hash buckets * which satisfies request. Account for * space used per block for accounting. */ - nbytes += sizeof (union overhead) + RSLOP; + nbytes += M_OVERHEAD; nbytes = (nbytes + 3) &~ 3; op->ov_size = nbytes - 1; *((u_int *)((caddr_t)op + nbytes - RSLOP)) = RMAGIC; @@ -393,15 +646,15 @@ realloc(mp, nbytes) free(cp); } -#ifdef safemalloc +#ifdef PERL_CORE #ifdef DEBUGGING if (debug & 128) { - fprintf(stderr,"0x%lx: (%05d) rfree\n",(unsigned long)res,an++); - fprintf(stderr,"0x%lx: (%05d) realloc %ld bytes\n", - (unsigned long)res,an++,(long)size); + PerlIO_printf(Perl_debug_log, "0x%lx: (%05lu) rfree\n",(unsigned long)res,(unsigned long)(an++)); + PerlIO_printf(Perl_debug_log, "0x%lx: (%05lu) realloc %ld bytes\n", + (unsigned long)res,(unsigned long)(an++),(long)size); } #endif -#endif /* safemalloc */ +#endif /* PERL_CORE */ return ((Malloc_t)res); } @@ -429,6 +682,20 @@ findbucket(freep, srchlen) return (-1); } +Malloc_t +calloc(elements, size) + register MEM_SIZE elements; + register MEM_SIZE size; +{ + long sz = elements * size; + Malloc_t p = malloc(sz); + + if (p) { + memset((void*)p, 0, sz); + } + return p; +} + #ifdef DEBUGGING_MSTATS /* * mstats - print out statistics about malloc @@ -443,7 +710,7 @@ dump_mstats(s) { register int i, j; register union overhead *p; - int topbucket=0, totfree=0, totused=0; + int topbucket=0, totfree=0, total=0; u_int nfree[NBUCKETS]; for (i=0; i < NBUCKETS; i++) { @@ -451,22 +718,23 @@ dump_mstats(s) ; nfree[i] = j; totfree += nfree[i] * (1 << (i + 3)); - totused += nmalloc[i] * (1 << (i + 3)); - if (nfree[i] || nmalloc[i]) + total += nmalloc[i] * (1 << (i + 3)); + if (nmalloc[i]) topbucket = i; } if (s) - fprintf(stderr, "Memory allocation statistics %s (buckets 8..%d)\n", + PerlIO_printf(PerlIO_stderr(), "Memory allocation statistics %s (buckets 8..%d)\n", s, (1 << (topbucket + 3)) ); - fprintf(stderr, " %7d free: ", totfree); + PerlIO_printf(PerlIO_stderr(), "%8d free:", totfree); for (i=0; i <= topbucket; i++) { - fprintf(stderr, (i<5)?" %5d":" %3d", nfree[i]); + PerlIO_printf(PerlIO_stderr(), (i<5 || i==7)?" %5d": (i<9)?" %3d":" %d", nfree[i]); } - fprintf(stderr, "\n %7d used: ", totused); + PerlIO_printf(PerlIO_stderr(), "\n%8d used:", total - totfree); for (i=0; i <= topbucket; i++) { - fprintf(stderr, (i<5)?" %5d":" %3d", nmalloc[i]); + PerlIO_printf(PerlIO_stderr(), (i<5 || i==7)?" %5d": (i<9)?" %3d":" %d", nmalloc[i] - nfree[i]); } - fprintf(stderr, "\n"); + PerlIO_printf(PerlIO_stderr(), "\nTotal sbrk(): %8d. Odd ends: sbrk(): %7d, malloc(): %7d bytes.\n", + goodsbrk + sbrk_slack, sbrk_slack, start_slack); } #else void @@ -476,3 +744,81 @@ dump_mstats(s) } #endif #endif /* lint */ + + +#ifdef USE_PERL_SBRK + +# ifdef NeXT +# define PERL_SBRK_VIA_MALLOC +# endif + +# ifdef PERL_SBRK_VIA_MALLOC +# if defined(HIDEMYMALLOC) || defined(EMBEDMYMALLOC) +# undef malloc +# else +# include "Error: -DPERL_SBRK_VIA_MALLOC needs -D(HIDE|EMBED)MYMALLOC" +# endif + +/* it may seem schizophrenic to use perl's malloc and let it call system */ +/* malloc, the reason for that is only the 3.2 version of the OS that had */ +/* frequent core dumps within nxzonefreenolock. This sbrk routine put an */ +/* end to the cores */ + +# define SYSTEM_ALLOC(a) malloc(a) + +# endif /* PERL_SBRK_VIA_MALLOC */ + +static IV Perl_sbrk_oldchunk; +static long Perl_sbrk_oldsize; + +# define PERLSBRK_32_K (1<<15) +# define PERLSBRK_64_K (1<<16) + +char * +Perl_sbrk(size) +int size; +{ + IV got; + int small, reqsize; + + if (!size) return 0; +#ifdef PERL_CORE + reqsize = size; /* just for the DEBUG_m statement */ +#endif +#ifdef PACK_MALLOC + size = (size + 0x7ff) & ~0x7ff; +#endif + if (size <= Perl_sbrk_oldsize) { + got = Perl_sbrk_oldchunk; + Perl_sbrk_oldchunk += size; + Perl_sbrk_oldsize -= size; + } else { + if (size >= PERLSBRK_32_K) { + small = 0; + } else { +#ifndef PERL_CORE + reqsize = size; +#endif + size = PERLSBRK_64_K; + small = 1; + } + got = (IV)SYSTEM_ALLOC(size); +#ifdef PACK_MALLOC + got = (got + 0x7ff) & ~0x7ff; +#endif + if (small) { + /* Chunk is small, register the rest for future allocs. */ + Perl_sbrk_oldchunk = got + reqsize; + Perl_sbrk_oldsize = size - reqsize; + } + } + +#ifdef PERL_CORE + DEBUG_m(PerlIO_printf(Perl_debug_log, "sbrk malloc size %ld (reqsize %ld), left size %ld, give addr 0x%lx\n", + size, reqsize, Perl_sbrk_oldsize, got)); +#endif + + return (void *)got; +} + +#endif /* ! defined USE_PERL_SBRK */ diff --git a/gnu/usr.bin/perl/mg.c b/gnu/usr.bin/perl/mg.c index 5e649bb9b98..ee87d47859b 100644 --- a/gnu/usr.bin/perl/mg.c +++ b/gnu/usr.bin/perl/mg.c @@ -1,6 +1,6 @@ /* mg.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -15,11 +15,16 @@ #include "EXTERN.h" #include "perl.h" -/* Omit -- it causes too much grief on mixed systems. +/* XXX If this causes problems, set i_unistd=undef in the hint file. */ #ifdef I_UNISTD # include <unistd.h> #endif -*/ + +#if defined(HAS_GETGROUPS) || defined(HAS_SETGROUPS) +# ifndef NGROUPS +# define NGROUPS 32 +# endif +#endif /* * Use the "DESTRUCTOR" scope cleanup to reinstate magic. @@ -33,15 +38,13 @@ typedef struct magic_state MGS; static void restore_magic _((void *p)); -static MGS * -save_magic(sv) +static void +save_magic(mgs, sv) +MGS* mgs; SV* sv; { - MGS* mgs; - assert(SvMAGICAL(sv)); - mgs = (MGS*)safemalloc(sizeof(MGS)); mgs->mgs_sv = sv; mgs->mgs_flags = SvMAGICAL(sv) | SvREADONLY(sv); SAVEDESTRUCTOR(restore_magic, mgs); @@ -49,15 +52,13 @@ SV* sv; SvMAGICAL_off(sv); SvREADONLY_off(sv); SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT; - - return mgs; } static void restore_magic(p) void* p; { - MGS *mgs = (MGS*)p; + MGS* mgs = (MGS*)p; SV* sv = mgs->mgs_sv; if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) @@ -69,8 +70,6 @@ void* p; if (SvGMAGICAL(sv)) SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK); } - - Safefree(mgs); } @@ -96,12 +95,13 @@ int mg_get(sv) SV* sv; { - MGS* mgs; + MGS mgs; MAGIC* mg; MAGIC** mgp; + int mgp_valid = 0; ENTER; - mgs = save_magic(sv); + save_magic(&mgs, sv); mgp = &SvMAGIC(sv); while ((mg = *mgp) != 0) { @@ -109,12 +109,17 @@ SV* sv; if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) { (*vtbl->svt_get)(sv, mg); /* Ignore this magic if it's been deleted */ - if (*mgp == mg && (mg->mg_flags & MGf_GSKIP)) - mgs->mgs_flags = 0; + if ((mg == (mgp_valid ? *mgp : SvMAGIC(sv))) && + (mg->mg_flags & MGf_GSKIP)) + mgs.mgs_flags = 0; } /* Advance to next magic (complicated by possible deletion) */ - if (*mgp == mg) + if (mg == (mgp_valid ? *mgp : SvMAGIC(sv))) { mgp = &mg->mg_moremagic; + mgp_valid = 1; + } + else + mgp = &SvMAGIC(sv); /* Re-establish pointer after sv_upgrade */ } LEAVE; @@ -125,19 +130,19 @@ int mg_set(sv) SV* sv; { - MGS* mgs; + MGS mgs; MAGIC* mg; MAGIC* nextmg; ENTER; - mgs = save_magic(sv); + save_magic(&mgs, sv); for (mg = SvMAGIC(sv); mg; mg = nextmg) { MGVTBL* vtbl = mg->mg_virtual; nextmg = mg->mg_moremagic; /* it may delete itself */ if (mg->mg_flags & MGf_GSKIP) { mg->mg_flags &= ~MGf_GSKIP; /* setting requires another read */ - mgs->mgs_flags = 0; + mgs.mgs_flags = 0; } if (vtbl && vtbl->svt_set) (*vtbl->svt_set)(sv, mg); @@ -158,8 +163,10 @@ SV* sv; for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) { MGVTBL* vtbl = mg->mg_virtual; if (vtbl && vtbl->svt_len) { + MGS mgs; + ENTER; - save_magic(sv); + save_magic(&mgs, sv); /* omit MGf_GSKIP -- not changed here */ len = (*vtbl->svt_len)(sv, mg); LEAVE; @@ -175,10 +182,11 @@ int mg_clear(sv) SV* sv; { + MGS mgs; MAGIC* mg; ENTER; - save_magic(sv); + save_magic(&mgs, sv); for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) { MGVTBL* vtbl = mg->mg_virtual; @@ -210,7 +218,7 @@ mg_copy(sv, nsv, key, klen) SV* sv; SV* nsv; char *key; -STRLEN klen; +I32 klen; { int count = 0; MAGIC* mg; @@ -235,7 +243,10 @@ SV* sv; if (vtbl && vtbl->svt_free) (*vtbl->svt_free)(sv, mg); if (mg->mg_ptr && mg->mg_type != 'g') - Safefree(mg->mg_ptr); + if (mg->mg_len >= 0) + Safefree(mg->mg_ptr); + else if (mg->mg_len == HEf_SVKEY) + SvREFCNT_dec((SV*)mg->mg_ptr); if (mg->mg_flags & MGf_REFCOUNTED) SvREFCNT_dec(mg->mg_obj); Safefree(mg); @@ -256,49 +267,47 @@ MAGIC *mg; register I32 paren; register char *s; register I32 i; + register REGEXP *rx; char *t; switch (*mg->mg_ptr) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '&': - if (curpm) { + if (curpm && (rx = curpm->op_pmregexp)) { paren = atoi(mg->mg_ptr); getparen: - if (curpm->op_pmregexp && - paren <= curpm->op_pmregexp->nparens && - (s = curpm->op_pmregexp->startp[paren]) && - (t = curpm->op_pmregexp->endp[paren]) ) { + if (paren <= rx->nparens && + (s = rx->startp[paren]) && + (t = rx->endp[paren])) + { i = t - s; if (i >= 0) return i; } } return 0; - break; case '+': - if (curpm) { - paren = curpm->op_pmregexp->lastparen; - if (!paren) - return 0; - goto getparen; + if (curpm && (rx = curpm->op_pmregexp)) { + paren = rx->lastparen; + if (paren) + goto getparen; } return 0; - break; case '`': - if (curpm) { - if (curpm->op_pmregexp && - (s = curpm->op_pmregexp->subbeg) ) { - i = curpm->op_pmregexp->startp[0] - s; + if (curpm && (rx = curpm->op_pmregexp)) { + if ((s = rx->subbeg) && rx->startp[0]) { + i = rx->startp[0] - s; if (i >= 0) return i; } } return 0; case '\'': - if (curpm) { - if (curpm->op_pmregexp && - (s = curpm->op_pmregexp->endp[0]) ) { - return (STRLEN) (curpm->op_pmregexp->subend - s); + if (curpm && (rx = curpm->op_pmregexp)) { + if (rx->subend && (s = rx->endp[0])) { + i = rx->subend - s; + if (i >= 0) + return i; } } return 0; @@ -323,6 +332,7 @@ MAGIC *mg; register I32 paren; register char *s; register I32 i; + register REGEXP *rx; char *t; switch (*mg->mg_ptr) { @@ -330,7 +340,7 @@ MAGIC *mg; sv_setsv(sv, bodytarget); break; case '\004': /* ^D */ - sv_setiv(sv,(I32)(debug & 32767)); + sv_setiv(sv, (IV)(debug & 32767)); break; case '\005': /* ^E */ #ifdef VMS @@ -339,57 +349,86 @@ MAGIC *mg; # include <starlet.h> char msg[255]; $DESCRIPTOR(msgdsc,msg); - sv_setnv(sv,(double)vaxc$errno); + sv_setnv(sv,(double) vaxc$errno); if (sys$getmsg(vaxc$errno,&msgdsc.dsc$w_length,&msgdsc,0,0) & 1) sv_setpvn(sv,msgdsc.dsc$a_pointer,msgdsc.dsc$w_length); else sv_setpv(sv,""); } #else - sv_setnv(sv,(double)errno); +#ifdef OS2 + if (!(_emx_env & 0x200)) { /* Under DOS */ + sv_setnv(sv, (double)errno); + sv_setpv(sv, errno ? Strerror(errno) : ""); + } else { + if (errno != errno_isOS2) + Perl_rc = _syserrno(); + sv_setnv(sv, (double)Perl_rc); + sv_setpv(sv, os2error(Perl_rc)); + } +#else + sv_setnv(sv, (double)errno); sv_setpv(sv, errno ? Strerror(errno) : ""); #endif +#endif SvNOK_on(sv); /* what a wonderful hack! */ break; case '\006': /* ^F */ - sv_setiv(sv,(I32)maxsysfd); + sv_setiv(sv, (IV)maxsysfd); break; case '\010': /* ^H */ - sv_setiv(sv,(I32)hints); + sv_setiv(sv, (IV)hints); break; case '\t': /* ^I */ if (inplace) sv_setpv(sv, inplace); else - sv_setsv(sv,&sv_undef); + sv_setsv(sv, &sv_undef); break; case '\017': /* ^O */ - sv_setpv(sv,osname); + sv_setpv(sv, osname); break; case '\020': /* ^P */ - sv_setiv(sv,(I32)perldb); + sv_setiv(sv, (IV)perldb); + break; + case '\023': /* ^S */ + if (lex_state != LEX_NOTPARSING) + SvOK_off(sv); + else if (in_eval) + sv_setiv(sv, 1); + else + sv_setiv(sv, 0); break; case '\024': /* ^T */ - sv_setiv(sv,(I32)basetime); +#ifdef BIG_TIME + sv_setnv(sv, basetime); +#else + sv_setiv(sv, (IV)basetime); +#endif break; case '\027': /* ^W */ - sv_setiv(sv,(I32)dowarn); + sv_setiv(sv, (IV)dowarn); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '&': - if (curpm) { - paren = atoi(GvENAME(mg->mg_obj)); + if (curpm && (rx = curpm->op_pmregexp)) { + paren = atoi(GvENAME((GV*)mg->mg_obj)); getparen: - if (curpm->op_pmregexp && - paren <= curpm->op_pmregexp->nparens && - (s = curpm->op_pmregexp->startp[paren]) && - (t = curpm->op_pmregexp->endp[paren]) ) { + if (paren <= rx->nparens && + (s = rx->startp[paren]) && + (t = rx->endp[paren])) + { i = t - s; + getrx: if (i >= 0) { - MAGIC *tmg; + bool was_tainted; + if (tainting) { + was_tainted = tainted; + tainted = FALSE; + } sv_setpvn(sv,s,i); - if (tainting && (tmg = mg_find(sv,'t'))) - tmg->mg_len = 0; /* guarantee $1 untainted */ + if (tainting) + tainted = was_tainted || rx->exec_tainted; break; } } @@ -397,32 +436,27 @@ MAGIC *mg; sv_setsv(sv,&sv_undef); break; case '+': - if (curpm) { - paren = curpm->op_pmregexp->lastparen; + if (curpm && (rx = curpm->op_pmregexp)) { + paren = rx->lastparen; if (paren) goto getparen; } sv_setsv(sv,&sv_undef); break; case '`': - if (curpm) { - if (curpm->op_pmregexp && - (s = curpm->op_pmregexp->subbeg) ) { - i = curpm->op_pmregexp->startp[0] - s; - if (i >= 0) { - sv_setpvn(sv,s,i); - break; - } + if (curpm && (rx = curpm->op_pmregexp)) { + if ((s = rx->subbeg) && rx->startp[0]) { + i = rx->startp[0] - s; + goto getrx; } } sv_setsv(sv,&sv_undef); break; case '\'': - if (curpm) { - if (curpm->op_pmregexp && - (s = curpm->op_pmregexp->endp[0]) ) { - sv_setpvn(sv,s, curpm->op_pmregexp->subend - s); - break; + if (curpm && (rx = curpm->op_pmregexp)) { + if (rx->subend && (s = rx->endp[0])) { + i = rx->subend - s; + goto getrx; } } sv_setsv(sv,&sv_undef); @@ -430,12 +464,16 @@ MAGIC *mg; case '.': #ifndef lint if (GvIO(last_in_gv)) { - sv_setiv(sv,(I32)IoLINES(GvIO(last_in_gv))); + sv_setiv(sv, (IV)IoLINES(GvIO(last_in_gv))); } #endif break; case '?': - sv_setiv(sv,(I32)statusvalue); + sv_setiv(sv, (IV)STATUS_CURRENT); +#ifdef COMPLEX_STATUS + LvTARGOFF(sv) = statusvalue; + LvTARGLEN(sv) = statusvalue_vms; +#endif break; case '^': s = IoTOP_NAME(GvIOp(defoutgv)); @@ -454,13 +492,13 @@ MAGIC *mg; break; #ifndef lint case '=': - sv_setiv(sv,(I32)IoPAGE_LEN(GvIOp(defoutgv))); + sv_setiv(sv, (IV)IoPAGE_LEN(GvIOp(defoutgv))); break; case '-': - sv_setiv(sv,(I32)IoLINES_LEFT(GvIOp(defoutgv))); + sv_setiv(sv, (IV)IoLINES_LEFT(GvIOp(defoutgv))); break; case '%': - sv_setiv(sv,(I32)IoPAGE(GvIOp(defoutgv))); + sv_setiv(sv, (IV)IoPAGE(GvIOp(defoutgv))); break; #endif case ':': @@ -468,10 +506,10 @@ MAGIC *mg; case '/': break; case '[': - sv_setiv(sv,(I32)curcop->cop_arybase); + sv_setiv(sv, (IV)curcop->cop_arybase); break; case '|': - sv_setiv(sv, (IoFLAGS(GvIOp(defoutgv)) & IOf_FLUSH) != 0 ); + sv_setiv(sv, (IV)(IoFLAGS(GvIOp(defoutgv)) & IOf_FLUSH) != 0 ); break; case ',': sv_setpvn(sv,ofs,ofslen); @@ -484,43 +522,45 @@ MAGIC *mg; break; case '!': #ifdef VMS - sv_setnv(sv,(double)((errno == EVMSERR) ? vaxc$errno : errno)); + sv_setnv(sv, (double)((errno == EVMSERR) ? vaxc$errno : errno)); + sv_setpv(sv, errno ? Strerror(errno) : ""); #else - sv_setnv(sv,(double)errno); + { + int saveerrno = errno; + sv_setnv(sv, (double)errno); +#ifdef OS2 + if (errno == errno_isOS2) sv_setpv(sv, os2error(Perl_rc)); + else #endif sv_setpv(sv, errno ? Strerror(errno) : ""); + errno = saveerrno; + } +#endif SvNOK_on(sv); /* what a wonderful hack! */ break; case '<': - sv_setiv(sv,(I32)uid); + sv_setiv(sv, (IV)uid); break; case '>': - sv_setiv(sv,(I32)euid); + sv_setiv(sv, (IV)euid); break; case '(': - s = buf; - (void)sprintf(s,"%d",(int)gid); + sv_setiv(sv, (IV)gid); + sv_setpvf(sv, "%Vd", (IV)gid); goto add_groups; case ')': - s = buf; - (void)sprintf(s,"%d",(int)egid); + sv_setiv(sv, (IV)egid); + sv_setpvf(sv, "%Vd", (IV)egid); add_groups: - while (*s) s++; #ifdef HAS_GETGROUPS -#ifndef NGROUPS -#define NGROUPS 32 -#endif { Groups_t gary[NGROUPS]; - i = getgroups(NGROUPS,gary); - while (--i >= 0) { - (void)sprintf(s," %ld", (long)gary[i]); - while (*s) s++; - } + while (--i >= 0) + sv_catpvf(sv, " %Vd", (IV)gary[i]); } #endif - sv_setpv(sv,buf); + SvIOK_on(sv); /* what a wonderful hack! */ break; case '*': break; @@ -548,34 +588,74 @@ SV* sv; MAGIC* mg; { register char *s; - STRLEN len; + char *ptr; + STRLEN len, klen; I32 i; + s = SvPV(sv,len); - my_setenv(mg->mg_ptr,s); + ptr = MgPV(mg,klen); + my_setenv(ptr, s); + #ifdef DYNAMIC_ENV_FETCH /* We just undefd an environment var. Is a replacement */ /* waiting in the wings? */ if (!len) { - SV **envsvp; - if (envsvp = hv_fetch(GvHVn(envgv),mg->mg_ptr,mg->mg_len,FALSE)) - s = SvPV(*envsvp,len); + SV **valp; + if ((valp = hv_fetch(GvHVn(envgv), ptr, klen, FALSE))) + s = SvPV(*valp, len); } #endif + +#if !defined(OS2) && !defined(AMIGAOS) && !defined(WIN32) /* And you'll never guess what the dog had */ /* in its mouth... */ if (tainting) { - if (s && strEQ(mg->mg_ptr,"PATH")) { + MgTAINTEDDIR_off(mg); +#ifdef VMS + if (s && klen == 8 && strEQ(ptr, "DCL$PATH")) { + char pathbuf[256], eltbuf[256], *cp, *elt = s; + struct stat sbuf; + int i = 0, j = 0; + + do { /* DCL$PATH may be a search list */ + while (1) { /* as may dev portion of any element */ + if ( ((cp = strchr(elt,'[')) || (cp = strchr(elt,'<'))) ) { + if ( *(cp+1) == '.' || *(cp+1) == '-' || + cando_by_name(S_IWUSR,0,elt) ) { + MgTAINTEDDIR_on(mg); + return 0; + } + } + if ((cp = strchr(elt, ':')) != Nullch) + *cp = '\0'; + if (my_trnlnm(elt, eltbuf, j++)) + elt = eltbuf; + else + break; + } + j = 0; + } while (my_trnlnm(s, pathbuf, i++) && (elt = pathbuf)); + } +#endif /* VMS */ + if (s && klen == 4 && strEQ(ptr,"PATH")) { char *strend = s + len; while (s < strend) { - s = cpytill(tokenbuf,s,strend,':',&i); + struct stat st; + s = delimcpy(tokenbuf, tokenbuf + sizeof tokenbuf, + s, strend, ':', &i); s++; - if (*tokenbuf != '/' - || (Stat(tokenbuf,&statbuf) && (statbuf.st_mode & 2)) ) + if (i >= sizeof tokenbuf /* too long -- assume the worst */ + || *tokenbuf != '/' + || (Stat(tokenbuf, &st) == 0 && (st.st_mode & 2)) ) { MgTAINTEDDIR_on(mg); + return 0; + } } } } +#endif /* neither OS2 nor AMIGAOS nor WIN32 */ + return 0; } @@ -584,52 +664,116 @@ magic_clearenv(sv,mg) SV* sv; MAGIC* mg; { - my_setenv(mg->mg_ptr,Nullch); + my_setenv(MgPV(mg,na),Nullch); return 0; } -#ifdef HAS_SIGACTION -/* set up reliable signal() clone */ - -typedef void (*Sigfunc) _((int)); - -static -Sigfunc rsignal(signo,handler) -int signo; -Sigfunc handler; +int +magic_set_all_env(sv,mg) +SV* sv; +MAGIC* mg; { - struct sigaction act,oact; - - act.sa_handler = handler; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; -#ifdef SIGALRM - if (signo == SIGALRM) { +#if defined(VMS) + die("Can't make list assignment to %%ENV on this system"); #else - if (0) { -#endif -#ifdef SA_INTERRUPT - act.sa_flags |= SA_INTERRUPT; /* SunOS */ -#endif - } else { -#ifdef SA_RESTART - act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */ -#endif + if (localizing) { + HE* entry; + magic_clear_all_env(sv,mg); + hv_iterinit((HV*)sv); + while (entry = hv_iternext((HV*)sv)) { + I32 keylen; + my_setenv(hv_iterkey(entry, &keylen), + SvPV(hv_iterval((HV*)sv, entry), na)); + } } - if (sigaction(signo, &act, &oact) < 0) - return(SIG_ERR); - else - return(oact.sa_handler); +#endif + return 0; } +int +magic_clear_all_env(sv,mg) +SV* sv; +MAGIC* mg; +{ +#if defined(VMS) + die("Can't make list assignment to %%ENV on this system"); #else +#ifdef WIN32 + char *envv = GetEnvironmentStrings(); + char *cur = envv; + STRLEN len; + while (*cur) { + char *end = strchr(cur,'='); + if (end && end != cur) { + *end = '\0'; + my_setenv(cur,Nullch); + *end = '='; + cur += strlen(end+1)+1; + } + else if ((len = strlen(cur))) + cur += len+1; + } + FreeEnvironmentStrings(envv); +#else + I32 i; -/* ah well, so much for reliability */ - -#define rsignal(x,y) signal(x,y) + if (environ == origenviron) + New(901, environ, 1, char*); + else + for (i = 0; environ[i]; i++) + Safefree(environ[i]); + environ[0] = Nullch; #endif +#endif + return 0; +} +int +magic_getsig(sv,mg) +SV* sv; +MAGIC* mg; +{ + I32 i; + /* Are we fetching a signal entry? */ + i = whichsig(MgPV(mg,na)); + if (i) { + if(psig_ptr[i]) + sv_setsv(sv,psig_ptr[i]); + else { + Sighandler_t sigstate = rsignal_state(i); + + /* cache state so we don't fetch it again */ + if(sigstate == SIG_IGN) + sv_setpv(sv,"IGNORE"); + else + sv_setsv(sv,&sv_undef); + psig_ptr[i] = SvREFCNT_inc(sv); + SvTEMP_off(sv); + } + } + return 0; +} +int +magic_clearsig(sv,mg) +SV* sv; +MAGIC* mg; +{ + I32 i; + /* Are we clearing a signal entry? */ + i = whichsig(MgPV(mg,na)); + if (i) { + if(psig_ptr[i]) { + SvREFCNT_dec(psig_ptr[i]); + psig_ptr[i]=0; + } + if(psig_name[i]) { + SvREFCNT_dec(psig_name[i]); + psig_name[i]=0; + } + } + return 0; +} int magic_setsig(sv,mg) @@ -640,7 +784,7 @@ MAGIC* mg; I32 i; SV** svp; - s = mg->mg_ptr; + s = MgPV(mg,na); if (*s == '_') { if (strEQ(s,"__DIE__")) svp = &diehook; @@ -663,10 +807,16 @@ MAGIC* mg; warn("No such signal: SIG%s", s); return 0; } + SvREFCNT_dec(psig_name[i]); + SvREFCNT_dec(psig_ptr[i]); + psig_ptr[i] = SvREFCNT_inc(sv); + SvTEMP_off(sv); /* Make sure it doesn't go away on us */ + psig_name[i] = newSVpv(s, strlen(s)); + SvREADONLY_on(psig_name[i]); } if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) { if (i) - (void)rsignal(i,sighandler); + (void)rsignal(i, sighandler); else *svp = SvREFCNT_inc(sv); return 0; @@ -674,23 +824,26 @@ MAGIC* mg; s = SvPV_force(sv,na); if (strEQ(s,"IGNORE")) { if (i) - (void)rsignal(i,SIG_IGN); + (void)rsignal(i, SIG_IGN); else *svp = 0; } else if (strEQ(s,"DEFAULT") || !*s) { if (i) - (void)rsignal(i,SIG_DFL); + (void)rsignal(i, SIG_DFL); else *svp = 0; } else { - if (!strchr(s,':') && !strchr(s,'\'')) { - sprintf(tokenbuf, "main::%s",s); - sv_setpv(sv,tokenbuf); - } + /* + * We should warn if HINT_STRICT_REFS, but without + * access to a known hint bit in a known OP, we can't + * tell whether HINT_STRICT_REFS is in force or not. + */ + if (!strchr(s,':') && !strchr(s,'\'')) + sv_setpv(sv, form("main::%s", s)); if (i) - (void)rsignal(i,sighandler); + (void)rsignal(i, sighandler); else *svp = SvREFCNT_inc(sv); } @@ -720,6 +873,18 @@ MAGIC* mg; } #endif /* OVERLOAD */ +int +magic_setnkeys(sv,mg) +SV* sv; +MAGIC* mg; +{ + if (LvTARG(sv)) { + hv_ksplit((HV*)LvTARG(sv), SvIV(sv)); + LvTARG(sv) = Nullsv; /* Don't allow a ref to reassign this. */ + } + return 0; +} + static int magic_methpack(sv,mg,meth) SV* sv; @@ -733,8 +898,12 @@ char *meth; PUSHMARK(sp); EXTEND(sp, 2); PUSHs(mg->mg_obj); - if (mg->mg_ptr) - PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len))); + if (mg->mg_ptr) { + if (mg->mg_len >= 0) + PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len))); + else if (mg->mg_len == HEf_SVKEY) + PUSHs((SV*)mg->mg_ptr); + } else if (mg->mg_type == 'p') PUSHs(sv_2mortal(newSViv(mg->mg_len))); PUTBACK; @@ -768,8 +937,12 @@ MAGIC* mg; PUSHMARK(sp); EXTEND(sp, 3); PUSHs(mg->mg_obj); - if (mg->mg_ptr) - PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len))); + if (mg->mg_ptr) { + if (mg->mg_len >= 0) + PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len))); + else if (mg->mg_len == HEf_SVKEY) + PUSHs((SV*)mg->mg_ptr); + } else if (mg->mg_type == 'p') PUSHs(sv_2mortal(newSViv(mg->mg_len))); PUSHs(sv); @@ -849,7 +1022,8 @@ MAGIC* mg; gv = DBline; i = SvTRUE(sv); - svp = av_fetch(GvAV(gv),atoi(mg->mg_ptr), FALSE); + svp = av_fetch(GvAV(gv), + atoi(MgPV(mg,na)), FALSE); if (svp && SvIOKp(*svp) && (o = (OP*)SvSTASH(*svp))) o->op_private = i; else @@ -927,6 +1101,7 @@ MAGIC* mg; else if (pos > len) pos = len; mg->mg_len = pos; + mg->mg_flags &= ~MGf_MINMATCH; return 0; } @@ -936,7 +1111,13 @@ magic_getglob(sv,mg) SV* sv; MAGIC* mg; { - gv_efullname(sv,((GV*)sv));/* a gv value, be nice */ + if (SvFAKE(sv)) { /* FAKE globs can get coerced */ + SvFAKE_off(sv); + gv_efullname3(sv,((GV*)sv), "*"); + SvFAKE_on(sv); + } + else + gv_efullname3(sv,((GV*)sv), "*"); /* a gv value, be nice */ return 0; } @@ -957,14 +1138,8 @@ MAGIC* mg; if (sv == (SV*)gv) return 0; if (GvGP(sv)) - gp_free(sv); + gp_free((GV*)sv); GvGP(sv) = gp_ref(GvGP(gv)); - if (!GvAV(gv)) - gv_AVadd(gv); - if (!GvHV(gv)) - gv_HVadd(gv); - if (!GvIOp(gv)) - GvIOp(gv) = newIO(); return 0; } @@ -984,10 +1159,8 @@ magic_gettaint(sv,mg) SV* sv; MAGIC* mg; { - if (mg->mg_len & 1) - tainted = TRUE; - else if (mg->mg_len & 2 && mg->mg_obj == sv) /* kludge */ - tainted = TRUE; + TAINT_IF((mg->mg_len & 1) || + (mg->mg_len & 2) && mg->mg_obj == sv); /* kludge */ return 0; } @@ -1019,6 +1192,97 @@ MAGIC* mg; } int +magic_getdefelem(sv,mg) +SV* sv; +MAGIC* mg; +{ + SV *targ = Nullsv; + if (LvTARGLEN(sv)) { + if (mg->mg_obj) { + HV* hv = (HV*)LvTARG(sv); + HE* he = hv_fetch_ent(hv, mg->mg_obj, FALSE, 0); + if (he) + targ = HeVAL(he); + } + else { + AV* av = (AV*)LvTARG(sv); + if ((I32)LvTARGOFF(sv) <= AvFILL(av)) + targ = AvARRAY(av)[LvTARGOFF(sv)]; + } + if (targ && targ != &sv_undef) { + /* somebody else defined it for us */ + SvREFCNT_dec(LvTARG(sv)); + LvTARG(sv) = SvREFCNT_inc(targ); + LvTARGLEN(sv) = 0; + SvREFCNT_dec(mg->mg_obj); + mg->mg_obj = Nullsv; + mg->mg_flags &= ~MGf_REFCOUNTED; + } + } + else + targ = LvTARG(sv); + sv_setsv(sv, targ ? targ : &sv_undef); + return 0; +} + +int +magic_setdefelem(sv,mg) +SV* sv; +MAGIC* mg; +{ + if (LvTARGLEN(sv)) + vivify_defelem(sv); + if (LvTARG(sv)) { + sv_setsv(LvTARG(sv), sv); + SvSETMAGIC(LvTARG(sv)); + } + return 0; +} + +int +magic_freedefelem(sv,mg) +SV* sv; +MAGIC* mg; +{ + SvREFCNT_dec(LvTARG(sv)); + return 0; +} + +void +vivify_defelem(sv) +SV* sv; +{ + MAGIC* mg; + SV* value; + + if (!LvTARGLEN(sv) || !(mg = mg_find(sv, 'y'))) + return; + if (mg->mg_obj) { + HV* hv = (HV*)LvTARG(sv); + HE* he = hv_fetch_ent(hv, mg->mg_obj, TRUE, 0); + if (!he || (value = HeVAL(he)) == &sv_undef) + croak(no_helem, SvPV(mg->mg_obj, na)); + } + else { + AV* av = (AV*)LvTARG(sv); + if ((I32)LvTARGLEN(sv) < 0 && (I32)LvTARGOFF(sv) > AvFILL(av)) + LvTARG(sv) = Nullsv; /* array can't be extended */ + else { + SV** svp = av_fetch(av, LvTARGOFF(sv), TRUE); + if (!svp || (value = *svp) == &sv_undef) + croak(no_aelem, (I32)LvTARGOFF(sv)); + } + } + (void)SvREFCNT_inc(value); + SvREFCNT_dec(LvTARG(sv)); + LvTARG(sv) = value; + LvTARGLEN(sv) = 0; + SvREFCNT_dec(mg->mg_obj); + mg->mg_obj = Nullsv; + mg->mg_flags &= ~MGf_REFCOUNTED; +} + +int magic_setmglob(sv,mg) SV* sv; MAGIC* mg; @@ -1039,6 +1303,16 @@ MAGIC* mg; } int +magic_setfm(sv,mg) +SV* sv; +MAGIC* mg; +{ + sv_unmagic(sv, 'f'); + SvCOMPILED_off(sv); + return 0; +} + +int magic_setuvar(sv,mg) SV* sv; MAGIC* mg; @@ -1050,6 +1324,25 @@ MAGIC* mg; return 0; } +#ifdef USE_LOCALE_COLLATE +int +magic_setcollxfrm(sv,mg) +SV* sv; +MAGIC* mg; +{ + /* + * René Descartes said "I think not." + * and vanished with a faint plop. + */ + if (mg->mg_ptr) { + Safefree(mg->mg_ptr); + mg->mg_ptr = NULL; + mg->mg_len = -1; + } + return 0; +} +#endif /* USE_LOCALE_COLLATE */ + int magic_set(sv,mg) SV* sv; @@ -1070,7 +1363,8 @@ MAGIC* mg; #ifdef VMS set_vaxc_errno(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); #else - SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv),4); /* will anyone ever use this? */ + /* will anyone ever use this? */ + SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), 4); #endif break; case '\006': /* ^F */ @@ -1096,17 +1390,14 @@ MAGIC* mg; osname = Nullch; break; case '\020': /* ^P */ - i = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv); - if (i != perldb) { - if (perldb) - oldlastpm = curpm; - else - curpm = oldlastpm; - } - perldb = i; + perldb = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv); break; case '\024': /* ^T */ +#ifdef BIG_TIME + basetime = (Time_t)(SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv)); +#else basetime = (Time_t)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); +#endif break; case '\027': /* ^W */ dowarn = (bool)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); @@ -1116,7 +1407,7 @@ MAGIC* mg; if (localizing == 1) save_sptr((SV**)&last_in_gv); } - else if (SvOK(sv)) + else if (SvOK(sv) && GvIO(last_in_gv)) IoLINES(GvIOp(last_in_gv)) = (long)SvIV(sv); break; case '^': @@ -1141,9 +1432,18 @@ MAGIC* mg; IoPAGE(GvIOp(defoutgv)) = (long)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); break; case '|': - IoFLAGS(GvIOp(defoutgv)) &= ~IOf_FLUSH; - if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) != 0) { - IoFLAGS(GvIOp(defoutgv)) |= IOf_FLUSH; + { + IO *io = GvIOp(defoutgv); + if ((SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) == 0) + IoFLAGS(io) &= ~IOf_FLUSH; + else { + if (!(IoFLAGS(io) & IOf_FLUSH)) { + PerlIO *ofp = IoOFP(io); + if (ofp) + (void)PerlIO_flush(ofp); + IoFLAGS(io) |= IOf_FLUSH; + } + } } break; case '*': @@ -1159,7 +1459,12 @@ MAGIC* mg; case '\\': if (ors) Safefree(ors); - ors = savepv(SvPV(sv,orslen)); + if (SvOK(sv) || SvGMAGICAL(sv)) + ors = savepv(SvPV(sv,orslen)); + else { + ors = Nullch; + orslen = 0; + } break; case ',': if (ofs) @@ -1175,10 +1480,23 @@ MAGIC* mg; compiling.cop_arybase = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv); break; case '?': - statusvalue = FIXSTATUS(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); +#ifdef COMPLEX_STATUS + if (localizing == 2) { + statusvalue = LvTARGOFF(sv); + statusvalue_vms = LvTARGLEN(sv); + } + else +#endif +#ifdef VMSISH_STATUS + if (VMSISH_STATUS) + STATUS_NATIVE_SET((U32)(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv))); + else +#endif + STATUS_POSIX_SET(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)); break; case '!': - SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv),SvIV(sv) == EVMSERR ? 4 : vaxc$errno); /* will anyone ever use this? */ + SETERRNO(SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv), + (SvIV(sv) == EVMSERR) ? 4 : vaxc$errno); break; case '<': uid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv); @@ -1262,7 +1580,30 @@ MAGIC* mg; tainting |= (uid && (euid != uid || egid != gid)); break; case ')': +#ifdef HAS_SETGROUPS + { + char *p = SvPV(sv, na); + Groups_t gary[NGROUPS]; + + SET_NUMERIC_STANDARD(); + while (isSPACE(*p)) + ++p; + egid = I_V(atof(p)); + for (i = 0; i < NGROUPS; ++i) { + while (*p && !isSPACE(*p)) + ++p; + while (isSPACE(*p)) + ++p; + if (!*p) + break; + gary[i] = I_V(atof(p)); + } + if (i) + (void)setgroups(i, gary); + } +#else /* HAS_SETGROUPS */ egid = SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv); +#endif /* HAS_SETGROUPS */ if (delaymagic) { delaymagic |= DM_EGID; break; /* don't do magic till later */ @@ -1297,15 +1638,28 @@ MAGIC* mg; s += strlen(s); /* See if all the arguments are contiguous in memory */ for (i = 1; i < origargc; i++) { - if (origargv[i] == s + 1) + if (origargv[i] == s + 1 +#ifdef OS2 + || origargv[i] == s + 2 +#endif + ) s += strlen(++s); /* this one is ok too */ + else + break; } - if (origenviron[0] == s + 1) { /* can grab env area too? */ - my_setenv("NoNeSuCh", Nullch); + /* can grab env area too? */ + if (origenviron && (origenviron[0] == s + 1 +#ifdef OS2 + || (origenviron[0] == s + 9 && (s += 8)) +#endif + )) { + my_setenv("NoNe SuCh", Nullch); /* force copy of environment */ for (i = 0; origenviron[i]; i++) if (origenviron[i] == s + 1) s += strlen(++s); + else + break; } origalen = s - origargv[0]; } @@ -1313,9 +1667,11 @@ MAGIC* mg; i = len; if (i >= origalen) { i = origalen; - SvCUR_set(sv, i); - *SvEND(sv) = '\0'; + /* don't allow system to limit $0 seen by script */ + /* SvCUR_set(sv, i); *SvEND(sv) = '\0'; */ Copy(s, origargv[0], i, char); + s = origargv[0]+i; + *s = '\0'; } else { Copy(s, origargv[0], i, char); @@ -1352,6 +1708,21 @@ char *sig; return 0; } +static SV* sig_sv; + +static void +unwind_handler_stack(p) + void *p; +{ + U32 flags = *(U32*)p; + + if (flags & 1) + savestack_ix -= 5; /* Unprotect save in progress. */ + /* cxstack_ix-- Not needed, die already unwound it. */ + if (flags & 64) + SvREFCNT_dec(sig_sv); +} + Signal_t sighandler(sig) int sig; @@ -1359,44 +1730,76 @@ int sig; dSP; GV *gv; HV *st; - SV *sv; + SV *sv, *tSv = Sv; CV *cv; AV *oldstack; - char *signame; - -#ifdef OS2 /* or anybody else who requires SIG_ACK */ - signal(sig, SIG_ACK); -#endif - - signame = sig_name[sig]; - cv = sv_2cv(*hv_fetch(GvHVn(siggv),signame,strlen(signame), - TRUE), - &st, &gv, TRUE); - if (!cv || !CvROOT(cv) && - *signame == 'C' && instr(signame,"LD")) { - - if (signame[1] == 'H') - cv = sv_2cv(*hv_fetch(GvHVn(siggv),"CLD",3,TRUE), - &st, &gv, TRUE); - else - cv = sv_2cv(*hv_fetch(GvHVn(siggv),"CHLD",4,TRUE), - &st, &gv, TRUE); - /* gag */ + OP *myop = op; + U32 flags = 0; + I32 o_save_i = savestack_ix, type; + CONTEXT *cx; + XPV *tXpv = Xpv; + + if (savestack_ix + 15 <= savestack_max) + flags |= 1; + if (cxstack_ix < cxstack_max - 2) + flags |= 2; + if (markstack_ptr < markstack_max - 2) + flags |= 4; + if (retstack_ix < retstack_max - 2) + flags |= 8; + if (scopestack_ix < scopestack_max - 3) + flags |= 16; + + if (flags & 2) { /* POPBLOCK may decrease cxstack too early. */ + cxstack_ix++; /* Protect from overwrite. */ + cx = &cxstack[cxstack_ix]; + type = cx->cx_type; /* Can be during partial write. */ + cx->cx_type = CXt_NULL; /* Make it safe for unwind. */ + } + if (!psig_ptr[sig]) + die("Signal SIG%s received, but no signal handler set.\n", + sig_name[sig]); + + /* Max number of items pushed there is 3*n or 4. We cannot fix + infinity, so we fix 4 (in fact 5): */ + if (flags & 1) { + savestack_ix += 5; /* Protect save in progress. */ + o_save_i = savestack_ix; + SAVEDESTRUCTOR(unwind_handler_stack, (void*)&flags); + } + if (flags & 4) + markstack_ptr++; /* Protect mark. */ + if (flags & 8) { + retstack_ix++; + retstack[retstack_ix] = NULL; } + if (flags & 16) + scopestack_ix += 1; + /* sv_2cv is too complicated, try a simpler variant first: */ + if (!SvROK(psig_ptr[sig]) || !(cv = (CV*)SvRV(psig_ptr[sig])) + || SvTYPE(cv) != SVt_PVCV) + cv = sv_2cv(psig_ptr[sig],&st,&gv,TRUE); + if (!cv || !CvROOT(cv)) { if (dowarn) warn("SIG%s handler \"%s\" not defined.\n", - signame, GvENAME(gv) ); + sig_name[sig], GvENAME(gv) ); return; } - oldstack = stack; - if (stack != signalstack) + oldstack = curstack; + if (curstack != signalstack) AvFILL(signalstack) = 0; - SWITCHSTACK(stack, signalstack); + SWITCHSTACK(curstack, signalstack); - sv = sv_newmortal(); - sv_setpv(sv,signame); + if(psig_name[sig]) { + sv = SvREFCNT_inc(psig_name[sig]); + flags |= 64; + sig_sv = sv; + } else { + sv = sv_newmortal(); + sv_setpv(sv,sig_name[sig]); + } PUSHMARK(sp); PUSHs(sv); PUTBACK; @@ -1404,6 +1807,23 @@ int sig; perl_call_sv((SV*)cv, G_DISCARD); SWITCHSTACK(signalstack, oldstack); - + if (flags & 1) + savestack_ix -= 8; /* Unprotect save in progress. */ + if (flags & 2) { + cxstack[cxstack_ix].cx_type = type; + cxstack_ix -= 1; + } + if (flags & 4) + markstack_ptr--; + if (flags & 8) + retstack_ix--; + if (flags & 16) + scopestack_ix -= 1; + if (flags & 64) + SvREFCNT_dec(sv); + op = myop; /* Apparently not needed... */ + + Sv = tSv; /* Restore global temporaries. */ + Xpv = tXpv; return; } diff --git a/gnu/usr.bin/perl/mg.h b/gnu/usr.bin/perl/mg.h index ab24eb03abb..c4647465572 100644 --- a/gnu/usr.bin/perl/mg.h +++ b/gnu/usr.bin/perl/mg.h @@ -1,6 +1,6 @@ /* mg.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -32,5 +32,10 @@ struct magic { #define MGf_MINMATCH 1 -#define MgTAINTEDDIR(mg) (mg->mg_flags & MGf_TAINTEDDIR) -#define MgTAINTEDDIR_on(mg) (mg->mg_flags |= MGf_TAINTEDDIR) +#define MgTAINTEDDIR(mg) (mg->mg_flags & MGf_TAINTEDDIR) +#define MgTAINTEDDIR_on(mg) (mg->mg_flags |= MGf_TAINTEDDIR) +#define MgTAINTEDDIR_off(mg) (mg->mg_flags &= ~MGf_TAINTEDDIR) + +#define MgPV(mg,lp) (((lp = (mg)->mg_len) == HEf_SVKEY) ? \ + SvPV((SV*)((mg)->mg_ptr),lp) : \ + (mg)->mg_ptr) diff --git a/gnu/usr.bin/perl/minimod.pl b/gnu/usr.bin/perl/minimod.pl index b9b70715b20..82760ee63d0 100644 --- a/gnu/usr.bin/perl/minimod.pl +++ b/gnu/usr.bin/perl/minimod.pl @@ -40,7 +40,7 @@ $tail=<<'EOF!TAIL'; END while (<MINI>) { - print; + print unless /dXSUB_SYS/; } close MINI; @@ -65,7 +65,9 @@ sub writemain{ my ($tail1,$tail2) = ( $tail =~ /\A(.*\n)(\s*\}.*)\Z/s ); print $tail1; - print " char *file = __FILE__;\n"; + print "\tchar *file = __FILE__;\n"; + print "\tdXSUB_SYS;\n" if $] > 5.002; + foreach $_ (@exts){ my($pname) = canon('/', $_); my($mname, $cname, $ccode); diff --git a/gnu/usr.bin/perl/miniperlmain.c b/gnu/usr.bin/perl/miniperlmain.c index bc81e997372..402f2ef065e 100644 --- a/gnu/usr.bin/perl/miniperlmain.c +++ b/gnu/usr.bin/perl/miniperlmain.c @@ -2,6 +2,10 @@ * "The Road goes ever on and on, down from the door where it began." */ +#ifdef OEMVS +#pragma runopts(HEAP(1M,32K,ANYWHERE,KEEP,8K,4K)) +#endif + #ifdef __cplusplus extern "C" { #endif @@ -33,20 +37,20 @@ char **env; PERL_SYS_INIT(&argc,&argv); - perl_init_i18nl14n(1); + perl_init_i18nl10n(1); if (!do_undump) { my_perl = perl_alloc(); if (!my_perl) exit(1); perl_construct( my_perl ); + perl_destruct_level = 0; } exitstatus = perl_parse( my_perl, xs_init, argc, argv, (char **) NULL ); - if (exitstatus) - exit( exitstatus ); - - exitstatus = perl_run( my_perl ); + if (!exitstatus) { + exitstatus = perl_run( my_perl ); + } perl_destruct( my_perl ); perl_free( my_perl ); diff --git a/gnu/usr.bin/perl/myconfig b/gnu/usr.bin/perl/myconfig index 9038197aafa..86da2edce87 100644 --- a/gnu/usr.bin/perl/myconfig +++ b/gnu/usr.bin/perl/myconfig @@ -21,21 +21,23 @@ $spitshell <<!GROK!THIS! Summary of my $package ($baserev patchlevel $PATCHLEVEL subversion $SUBVERSION) configuration: Platform: - osname=$osname, osver=$osvers, archname=$archname + osname=$osname, osvers=$osvers, archname=$archname uname='$myuname' hint=$hint, useposix=$useposix, d_sigaction=$d_sigaction + bincompat3=$bincompat3 useperlio=$useperlio d_sfio=$d_sfio Compiler: cc='$cc', optimize='$optimize', gccversion=$gccversion cppflags='$cppflags' ccflags ='$ccflags' stdchar='$stdchar', d_stdstdio=$d_stdstdio, usevfork=$usevfork voidflags=$voidflags, castflags=$castflags, d_casti32=$d_casti32, d_castneg=$d_castneg - intsize=$intsize, alignbytes=$alignbytes, usemymalloc=$usemymalloc, randbits=$randbits + intsize=$intsize, alignbytes=$alignbytes, usemymalloc=$usemymalloc, prototype=$prototype Linker and Libraries: ld='$ld', ldflags ='$ldflags' libpth=$libpth libs=$libs libc=$libc, so=$so + useshrplib=$useshrplib, libperl=$libperl Dynamic Linking: dlsrc=$dlsrc, dlext=$dlext, d_dlsymun=$d_dlsymun, ccdlflags='$ccdlflags' cccdlflags='$cccdlflags', lddlflags='$lddlflags' diff --git a/gnu/usr.bin/perl/op.c b/gnu/usr.bin/perl/op.c index d56ed9ad8d4..8e8811da934 100644 --- a/gnu/usr.bin/perl/op.c +++ b/gnu/usr.bin/perl/op.c @@ -1,6 +1,6 @@ /* op.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -26,8 +26,10 @@ * think the expression is of the right type: croak actually does a Siglongjmp. */ #define CHECKOP(type,op) \ - ((op_mask && op_mask[type]) \ - ? (croak("%s trapped by operation mask", op_desc[type]), (OP*)op) \ + ((op_mask && op_mask[type]) \ + ? ( op_free((OP*)op), \ + croak("%s trapped by operation mask", op_desc[type]), \ + Nullop ) \ : (*check[type])((OP*)op)) #else #define CHECKOP(type,op) (*check[type])(op) @@ -37,19 +39,20 @@ static I32 list_assignment _((OP *op)); static OP *bad_type _((I32 n, char *t, char *name, OP *kid)); static OP *modkids _((OP *op, I32 type)); static OP *no_fh_allowed _((OP *op)); +static bool scalar_mod_type _((OP *op, I32 type)); static OP *scalarboolean _((OP *op)); static OP *too_few_arguments _((OP *op, char* name)); static OP *too_many_arguments _((OP *op, char* name)); static void null _((OP* op)); -static PADOFFSET pad_findlex _((char* name, PADOFFSET newoff, I32 seq, +static PADOFFSET pad_findlex _((char* name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix)); static char* -CvNAME(cv) -CV* cv; +gv_ename(gv) +GV* gv; { SV* tmpsv = sv_newmortal(); - gv_efullname(tmpsv, CvGV(cv)); + gv_efullname3(tmpsv, gv, Nullch); return SvPV(tmpsv,na); } @@ -57,9 +60,8 @@ static OP * no_fh_allowed(op) OP *op; { - sprintf(tokenbuf,"Missing comma after first argument to %s function", - op_desc[op->op_type]); - yyerror(tokenbuf); + yyerror(form("Missing comma after first argument to %s function", + op_desc[op->op_type])); return op; } @@ -68,8 +70,7 @@ too_few_arguments(op, name) OP* op; char* name; { - sprintf(tokenbuf,"Not enough arguments for %s", name); - yyerror(tokenbuf); + yyerror(form("Not enough arguments for %s", name)); return op; } @@ -78,8 +79,7 @@ too_many_arguments(op, name) OP *op; char* name; { - sprintf(tokenbuf,"Too many arguments for %s", name); - yyerror(tokenbuf); + yyerror(form("Too many arguments for %s", name)); return op; } @@ -90,9 +90,8 @@ char *t; char *name; OP *kid; { - sprintf(tokenbuf, "Type of arg %d to %s must be %s (not %s)", - (int) n, name, t, op_desc[kid->op_type]); - yyerror(tokenbuf); + yyerror(form("Type of arg %d to %s must be %s (not %s)", + (int)n, name, t, op_desc[kid->op_type])); return op; } @@ -102,11 +101,10 @@ OP *op; { int type = op->op_type; if (type != OP_AELEM && type != OP_HELEM) { - sprintf(tokenbuf, "Can't use subscript on %s", op_desc[type]); - yyerror(tokenbuf); - if (type == OP_RV2HV || type == OP_ENTERSUB) + yyerror(form("Can't use subscript on %s", op_desc[type])); + if (type == OP_ENTERSUB || type == OP_RV2HV || type == OP_PADHV) warn("(Did you mean $ or @ instead of %c?)\n", - type == OP_RV2HV ? '%' : '&'); + type == OP_ENTERSUB ? '&' : '%'); } } @@ -120,10 +118,26 @@ char *name; SV *sv; if (!(isALPHA(name[1]) || name[1] == '_' && (int)strlen(name) > 2)) { - if (!isprint(name[1])) - sprintf(name+1, "^%c", name[1] ^ 64); /* XXX is tokenbuf, really */ + if (!isPRINT(name[1])) { + name[3] = '\0'; + name[2] = toCTRL(name[1]); + name[1] = '^'; + } croak("Can't use global %s in \"my\"",name); } + if (dowarn && AvFILL(comppad_name) >= 0) { + SV **svp = AvARRAY(comppad_name); + for (off = AvFILL(comppad_name); off > comppad_name_floor; off--) { + if ((sv = svp[off]) + && sv != &sv_undef + && SvIVX(sv) == 999999999 /* var is in open scope */ + && strEQ(name, SvPVX(sv))) + { + warn("\"my\" variable %s masks earlier declaration in same scope", name); + break; + } + } + } off = pad_alloc(OP_PADSV, SVs_PADMY); sv = NEWSV(1102,0); sv_upgrade(sv, SVt_PVNV); @@ -147,11 +161,11 @@ static PADOFFSET pad_findlex(name, newoff, seq, startcv, cx_ix) char *name; PADOFFSET newoff; -I32 seq; +U32 seq; CV* startcv; I32 cx_ix; #else -pad_findlex(char *name, PADOFFSET newoff, I32 seq, CV* startcv, I32 cx_ix) +pad_findlex(char *name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix) #endif { CV *cv; @@ -162,9 +176,10 @@ pad_findlex(char *name, PADOFFSET newoff, I32 seq, CV* startcv, I32 cx_ix) int saweval; for (cv = startcv; cv; cv = CvOUTSIDE(cv)) { - AV* curlist = CvPADLIST(cv); - SV** svp = av_fetch(curlist, 0, FALSE); + AV *curlist = CvPADLIST(cv); + SV **svp = av_fetch(curlist, 0, FALSE); AV *curname; + if (!svp || *svp == &sv_undef) continue; curname = (AV*)*svp; @@ -173,24 +188,63 @@ pad_findlex(char *name, PADOFFSET newoff, I32 seq, CV* startcv, I32 cx_ix) if ((sv = svp[off]) && sv != &sv_undef && seq <= SvIVX(sv) && - seq > (I32)SvNVX(sv) && + seq > I_32(SvNVX(sv)) && strEQ(SvPVX(sv), name)) { - I32 depth = CvDEPTH(cv) ? CvDEPTH(cv) : 1; - AV *oldpad = (AV*)*av_fetch(curlist, depth, FALSE); - SV *oldsv = *av_fetch(oldpad, off, TRUE); + I32 depth; + AV *oldpad; + SV *oldsv; + + depth = CvDEPTH(cv); + if (!depth) { + if (newoff) { + if (SvFAKE(sv)) + continue; + return 0; /* don't clone from inactive stack frame */ + } + depth = 1; + } + oldpad = (AV*)*av_fetch(curlist, depth, FALSE); + oldsv = *av_fetch(oldpad, off, TRUE); if (!newoff) { /* Not a mere clone operation. */ - SV *sv = NEWSV(1103,0); + SV *namesv = NEWSV(1103,0); newoff = pad_alloc(OP_PADSV, SVs_PADMY); - sv_upgrade(sv, SVt_PVNV); - sv_setpv(sv, name); - av_store(comppad_name, newoff, sv); - SvNVX(sv) = (double)curcop->cop_seq; - SvIVX(sv) = 999999999; /* A ref, intro immediately */ - SvFLAGS(sv) |= SVf_FAKE; + sv_upgrade(namesv, SVt_PVNV); + sv_setpv(namesv, name); + av_store(comppad_name, newoff, namesv); + SvNVX(namesv) = (double)curcop->cop_seq; + SvIVX(namesv) = 999999999; /* A ref, intro immediately */ + SvFAKE_on(namesv); /* A ref, not a real var */ + if (CvANON(compcv) || SvTYPE(compcv) == SVt_PVFM) { + /* "It's closures all the way down." */ + CvCLONE_on(compcv); + if (cv == startcv) { + if (CvANON(compcv)) + oldsv = Nullsv; /* no need to keep ref */ + } + else { + CV *bcv; + for (bcv = startcv; + bcv && bcv != cv && !CvCLONE(bcv); + bcv = CvOUTSIDE(bcv)) { + if (CvANON(bcv)) + CvCLONE_on(bcv); + else { + if (dowarn && !CvUNIQUE(cv)) + warn( + "Variable \"%s\" may be unavailable", + name); + break; + } + } + } + } + else if (!CvUNIQUE(compcv)) { + if (dowarn && !SvFAKE(sv) && !CvUNIQUE(cv)) + warn("Variable \"%s\" will not stay shared", name); + } } av_store(comppad, newoff, SvREFCNT_inc(oldsv)); - CvCLONE_on(compcv); return newoff; } } @@ -212,10 +266,14 @@ pad_findlex(char *name, PADOFFSET newoff, I32 seq, CV* startcv, I32 cx_ix) } break; case CXt_EVAL: - if (cx->blk_eval.old_op_type != OP_ENTEREVAL && - cx->blk_eval.old_op_type != OP_ENTERTRY) - return 0; /* require must have its own scope */ - saweval = i; + switch (cx->blk_eval.old_op_type) { + case OP_ENTEREVAL: + saweval = i; + break; + case OP_REQUIRE: + /* require must have its own scope */ + return 0; + } break; case CXt_SUB: if (!saweval) @@ -238,26 +296,34 @@ pad_findmy(name) char *name; { I32 off; + I32 pendoff = 0; SV *sv; SV **svp = AvARRAY(comppad_name); - I32 seq = cop_seqmax; + U32 seq = cop_seqmax; /* The one we're looking for is probably just before comppad_name_fill. */ for (off = AvFILL(comppad_name); off > 0; off--) { if ((sv = svp[off]) && sv != &sv_undef && - seq <= SvIVX(sv) && - seq > (I32)SvNVX(sv) && + (!SvIVX(sv) || + (seq <= SvIVX(sv) && + seq > I_32(SvNVX(sv)))) && strEQ(SvPVX(sv), name)) { - return (PADOFFSET)off; + if (SvIVX(sv)) + return (PADOFFSET)off; + pendoff = off; /* this pending def. will override import */ } } /* See if it's in a nested scope */ off = pad_findlex(name, 0, seq, CvOUTSIDE(compcv), cxstack_ix); - if (off) + if (off) { + /* If there is a pending local definition, this new alias must die */ + if (pendoff) + SvIVX(AvARRAY(comppad_name)[off]) = seq; return off; + } return 0; } @@ -301,14 +367,26 @@ U32 tmptype; retval = AvFILL(comppad); } else { - do { - sv = *av_fetch(comppad, ++padix, TRUE); - } while (SvFLAGS(sv) & (SVs_PADTMP|SVs_PADMY)); + SV **names = AvARRAY(comppad_name); + SSize_t names_fill = AvFILL(comppad_name); + for (;;) { + /* + * "foreach" index vars temporarily become aliases to non-"my" + * values. Thus we must skip, not just pad values that are + * marked as current pad values, but also those with names. + */ + if (++padix <= names_fill && + (sv = names[padix]) && sv != &sv_undef) + continue; + sv = *av_fetch(comppad, padix, TRUE); + if (!(SvFLAGS(sv) & (SVs_PADTMP|SVs_PADMY))) + break; + } retval = padix; } SvFLAGS(sv) |= tmptype; curpad = AvARRAY(comppad); - DEBUG_X(fprintf(stderr, "Pad alloc %ld for %s\n", (long) retval, op_name[optype])); + DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad alloc %ld for %s\n", (long) retval, op_name[optype])); return (PADOFFSET)retval; } @@ -322,7 +400,7 @@ pad_sv(PADOFFSET po) { if (!po) croak("panic: pad_sv po"); - DEBUG_X(fprintf(stderr, "Pad sv %d\n", po)); + DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad sv %lu\n", (unsigned long)po)); return curpad[po]; /* eventually we'll turn this into a macro */ } @@ -340,8 +418,8 @@ pad_free(PADOFFSET po) croak("panic: pad_free curpad"); if (!po) croak("panic: pad_free po"); - DEBUG_X(fprintf(stderr, "Pad free %d\n", po)); - if (curpad[po] && curpad[po] != &sv_undef) + DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad free %lu\n", (unsigned long)po)); + if (curpad[po] && !SvIMMORTAL(curpad[po])) SvPADTMP_off(curpad[po]); if ((I32)po < padix) padix = po - 1; @@ -359,7 +437,7 @@ pad_swipe(PADOFFSET po) croak("panic: pad_swipe curpad"); if (!po) croak("panic: pad_swipe po"); - DEBUG_X(fprintf(stderr, "Pad swipe %d\n", po)); + DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad swipe %lu\n", (unsigned long)po)); SvPADTMP_off(curpad[po]); curpad[po] = NEWSV(1107,0); SvPADTMP_on(curpad[po]); @@ -374,10 +452,10 @@ pad_reset() if (AvARRAY(comppad) != curpad) croak("panic: pad_reset curpad"); - DEBUG_X(fprintf(stderr, "Pad reset\n")); + DEBUG_X(PerlIO_printf(Perl_debug_log, "Pad reset\n")); if (!tainting) { /* Can't mix tainted and non-tainted temporaries. */ for (po = AvMAX(comppad); po > padix_floor; po--) { - if (curpad[po] && curpad[po] != &sv_undef) + if (curpad[po] && !SvIMMORTAL(curpad[po])) SvPADTMP_off(curpad[po]); } padix = padix_floor; @@ -393,7 +471,7 @@ OP *op; { register OP *kid, *nextkid; - if (!op) + if (!op || op->op_seq == (U16)-1) return; if (op->op_flags & OPf_KIDS) { @@ -410,12 +488,18 @@ OP *op; case OP_ENTEREVAL: op->op_targ = 0; /* Was holding hints. */ break; + default: + if (!(op->op_flags & OPf_REF) || (check[op->op_type] != ck_ftst)) + break; + /* FALL THROUGH */ case OP_GVSV: case OP_GV: + case OP_AELEMFAST: SvREFCNT_dec(cGVOP->op_gv); break; case OP_NEXTSTATE: case OP_DBSTATE: + Safefree(cCOP->cop_label); SvREFCNT_dec(cCOP->cop_filegv); break; case OP_CONST: @@ -439,8 +523,6 @@ OP *op; pregfree(cPMOP->op_pmregexp); SvREFCNT_dec(cPMOP->op_pmshort); break; - default: - break; } if (op->op_targ > 0) @@ -524,11 +606,11 @@ OP *op; OP *kid; /* assumes no premature commitment */ - if (!op || (op->op_flags & OPf_KNOW) || error_count) + if (!op || (op->op_flags & OPf_WANT) || error_count + || op->op_type == OP_RETURN) return op; - op->op_flags &= ~OPf_LIST; - op->op_flags |= OPf_KNOW; + op->op_flags = (op->op_flags & ~OPf_WANT) | OPf_WANT_SCALAR; switch (op->op_type) { case OP_REPEAT: @@ -559,8 +641,16 @@ OP *op; break; case OP_LEAVE: case OP_LEAVETRY: - scalar(cLISTOP->op_first); - /* FALL THROUGH */ + kid = cLISTOP->op_first; + scalar(kid); + while (kid = kid->op_sibling) { + if (kid->op_sibling) + scalarvoid(kid); + else + scalar(kid); + } + curcop = &compiling; + break; case OP_SCOPE: case OP_LINESEQ: case OP_LIST: @@ -584,17 +674,19 @@ OP *op; char* useless = 0; SV* sv; - if (!op || error_count) - return op; - if (op->op_flags & OPf_LIST) + /* assumes no premature commitment */ + if (!op || (op->op_flags & OPf_WANT) == OPf_WANT_LIST || error_count + || op->op_type == OP_RETURN) return op; - op->op_flags |= OPf_KNOW; + op->op_flags = (op->op_flags & ~OPf_WANT) | OPf_WANT_VOID; switch (op->op_type) { default: if (!(opargs[op->op_type] & OA_FOLDCONST)) break; + /* FALL THROUGH */ + case OP_REPEAT: if (op->op_flags & OPf_STACKED) break; /* FALL THROUGH */ @@ -621,8 +713,6 @@ OP *op; case OP_AELEM: case OP_AELEMFAST: case OP_ASLICE: - case OP_VALUES: - case OP_KEYS: case OP_HELEM: case OP_HSLICE: case OP_UNPACK: @@ -713,46 +803,47 @@ OP *op; op->op_ppaddr = ppaddr[OP_PREDEC]; break; - case OP_REPEAT: - scalarvoid(cBINOP->op_first); - useless = op_desc[op->op_type]; - break; - case OP_OR: case OP_AND: case OP_COND_EXPR: for (kid = cUNOP->op_first->op_sibling; kid; kid = kid->op_sibling) scalarvoid(kid); break; + case OP_NULL: if (op->op_targ == OP_NEXTSTATE || op->op_targ == OP_DBSTATE) curcop = ((COP*)op); /* for warning below */ if (op->op_flags & OPf_STACKED) break; + /* FALL THROUGH */ case OP_ENTERTRY: case OP_ENTER: case OP_SCALAR: if (!(op->op_flags & OPf_KIDS)) break; + /* FALL THROUGH */ case OP_SCOPE: case OP_LEAVE: case OP_LEAVETRY: case OP_LEAVELOOP: - op->op_private |= OPpLEAVE_VOID; case OP_LINESEQ: case OP_LIST: for (kid = cLISTOP->op_first; kid; kid = kid->op_sibling) scalarvoid(kid); break; + case OP_ENTEREVAL: + scalarkids(op); + break; + case OP_REQUIRE: + /* all requires must return a boolean value */ + op->op_flags &= ~OPf_WANT; + return scalar(op); case OP_SPLIT: if ((kid = ((LISTOP*)op)->op_first) && kid->op_type == OP_PUSHRE) { if (!kPMOP->op_pmreplroot) deprecate("implicit split to @_"); } break; - case OP_DELETE: - op->op_private |= OPpLEAVE_VOID; - break; } if (useless && dowarn) warn("Useless use of %s in void context", useless); @@ -778,10 +869,11 @@ OP *op; OP *kid; /* assumes no premature commitment */ - if (!op || (op->op_flags & OPf_KNOW) || error_count) + if (!op || (op->op_flags & OPf_WANT) || error_count + || op->op_type == OP_RETURN) return op; - op->op_flags |= (OPf_KNOW | OPf_LIST); + op->op_flags = (op->op_flags & ~OPf_WANT) | OPf_WANT_LIST; switch (op->op_type) { case OP_FLOP: @@ -809,8 +901,16 @@ OP *op; break; case OP_LEAVE: case OP_LEAVETRY: - list(cLISTOP->op_first); - /* FALL THROUGH */ + kid = cLISTOP->op_first; + list(kid); + while (kid = kid->op_sibling) { + if (kid->op_sibling) + scalarvoid(kid); + else + list(kid); + } + curcop = &compiling; + break; case OP_SCOPE: case OP_LINESEQ: for (kid = cLISTOP->op_first; kid; kid = kid->op_sibling) { @@ -821,6 +921,10 @@ OP *op; } curcop = &compiling; break; + case OP_REQUIRE: + /* all requires must return a boolean value */ + op->op_flags &= ~OPf_WANT; + return scalar(op); } return op; } @@ -875,12 +979,14 @@ I32 type; { OP *kid; SV *sv; - char mtype; if (!op || error_count) return op; switch (op->op_type) { + case OP_UNDEF: + modcount++; + return op; case OP_CONST: if (!(op->op_private & (OPpCONST_ARYBASE))) goto nomod; @@ -897,6 +1003,10 @@ I32 type; else croak("That use of $[ is unsupported"); break; + case OP_STUB: + if (op->op_flags & OPf_PARENS) + break; + goto nomod; case OP_ENTERSUB: if ((type == OP_UNDEF || type == OP_REFGEN) && !(op->op_flags & OPf_STACKED)) { @@ -912,10 +1022,9 @@ I32 type; /* grep, foreach, subcalls, refgen */ if (type == OP_GREPSTART || type == OP_ENTERSUB || type == OP_REFGEN) break; - sprintf(tokenbuf, "Can't modify %s in %s", - op_desc[op->op_type], - type ? op_desc[type] : "local"); - yyerror(tokenbuf); + yyerror(form("Can't modify %s in %s", + op_desc[op->op_type], + type ? op_desc[type] : "local")); return op; case OP_PREINC: @@ -950,12 +1059,16 @@ I32 type; case OP_RV2AV: case OP_RV2HV: + if (!type && cUNOP->op_first->op_type != OP_GV) + croak("Can't localize through a reference"); if (type == OP_REFGEN && op->op_flags & OPf_PARENS) { modcount = 10000; return op; /* Treat \(@foo) like ordinary list. */ } /* FALL THROUGH */ case OP_RV2GV: + if (scalar_mod_type(op, type)) + goto nomod; ref(cUNOP->op_first, op->op_type); /* FALL THROUGH */ case OP_AASSIGN: @@ -969,10 +1082,9 @@ I32 type; break; case OP_RV2SV: if (!type && cUNOP->op_first->op_type != OP_GV) - croak("Can't localize a reference"); + croak("Can't localize through a reference"); ref(cUNOP->op_first, op->op_type); /* FALL THROUGH */ - case OP_UNDEF: case OP_GV: case OP_AV2ARYLEN: case OP_SASSIGN: @@ -983,6 +1095,10 @@ I32 type; case OP_PADAV: case OP_PADHV: modcount = 10000; + if (type == OP_REFGEN && op->op_flags & OPf_PARENS) + return op; /* Treat \(@foo) like ordinary list. */ + if (scalar_mod_type(op, type)) + goto nomod; /* FALL THROUGH */ case OP_PADSV: modcount++; @@ -994,21 +1110,16 @@ I32 type; case OP_PUSHMARK: break; + case OP_KEYS: + if (type != OP_SASSIGN) + goto nomod; + /* FALL THROUGH */ case OP_POS: - mtype = '.'; - goto makelv; case OP_VEC: - mtype = 'v'; - goto makelv; case OP_SUBSTR: - mtype = 'x'; - makelv: pad_free(op->op_targ); op->op_targ = pad_alloc(op->op_type, SVs_PADMY); - sv = PAD_SV(op->op_targ); - sv_upgrade(sv, SVt_PVLV); - sv_magic(sv, Nullsv, mtype, Nullch, 0); - curpad[op->op_targ] = sv; + assert(SvTYPE(PAD_SV(op->op_targ)) == SVt_NULL); if (op->op_flags & OPf_KIDS) mod(cBINOP->op_first->op_sibling, type); break; @@ -1016,6 +1127,9 @@ I32 type; case OP_AELEM: case OP_HELEM: ref(cBINOP->op_first, op->op_type); + if (type == OP_ENTERSUB && + !(op->op_private & (OPpLVAL_INTRO | OPpDEREF))) + op->op_private |= OPpLVAL_DEFER; modcount++; break; @@ -1052,6 +1166,52 @@ I32 type; return op; } +static bool +scalar_mod_type(op, type) +OP *op; +I32 type; +{ + switch (type) { + case OP_SASSIGN: + if (op->op_type == OP_RV2GV) + return FALSE; + /* FALL THROUGH */ + case OP_PREINC: + case OP_PREDEC: + case OP_POSTINC: + case OP_POSTDEC: + case OP_I_PREINC: + case OP_I_PREDEC: + case OP_I_POSTINC: + case OP_I_POSTDEC: + case OP_POW: + case OP_MULTIPLY: + case OP_DIVIDE: + case OP_MODULO: + case OP_REPEAT: + case OP_ADD: + case OP_SUBTRACT: + case OP_I_MULTIPLY: + case OP_I_DIVIDE: + case OP_I_MODULO: + case OP_I_ADD: + case OP_I_SUBTRACT: + case OP_LEFT_SHIFT: + case OP_RIGHT_SHIFT: + case OP_BIT_AND: + case OP_BIT_XOR: + case OP_BIT_OR: + case OP_CONCAT: + case OP_SUBST: + case OP_TRANS: + case OP_ANDASSIGN: /* may work later */ + case OP_ORASSIGN: /* may work later */ + return TRUE; + default: + return FALSE; + } +} + OP * refkids(op, type) OP *op; @@ -1095,8 +1255,10 @@ I32 type; ref(cUNOP->op_first, op->op_type); /* FALL THROUGH */ case OP_PADSV: - if (type == OP_RV2AV || type == OP_RV2HV) { - op->op_private |= (type == OP_RV2AV ? OPpDEREF_AV : OPpDEREF_HV); + if (type == OP_RV2SV || type == OP_RV2AV || type == OP_RV2HV) { + op->op_private |= (type == OP_RV2AV ? OPpDEREF_AV + : type == OP_RV2HV ? OPpDEREF_HV + : OPpDEREF_SV); op->op_flags |= OPf_MOD; } break; @@ -1123,8 +1285,10 @@ I32 type; case OP_AELEM: case OP_HELEM: ref(cBINOP->op_first, op->op_type); - if (type == OP_RV2AV || type == OP_RV2HV) { - op->op_private |= (type == OP_RV2AV ? OPpDEREF_AV : OPpDEREF_HV); + if (type == OP_RV2SV || type == OP_RV2AV || type == OP_RV2HV) { + op->op_private |= (type == OP_RV2AV ? OPpDEREF_AV + : type == OP_RV2HV ? OPpDEREF_HV + : OPpDEREF_SV); op->op_flags |= OPf_MOD; } break; @@ -1164,8 +1328,7 @@ OP *op; type != OP_PADHV && type != OP_PUSHMARK) { - sprintf(tokenbuf, "Can't declare %s in my", op_desc[op->op_type]); - yyerror(tokenbuf); + yyerror(form("Can't declare %s in my", op_desc[op->op_type])); return op; } op->op_flags |= OPf_MOD; @@ -1190,6 +1353,20 @@ OP *right; { OP *op; + if (dowarn && + (left->op_type == OP_RV2AV || + left->op_type == OP_RV2HV || + left->op_type == OP_PADAV || + left->op_type == OP_PADHV)) { + char *desc = op_desc[(right->op_type == OP_SUBST || + right->op_type == OP_TRANS) + ? right->op_type : OP_MATCH]; + char *sample = ((left->op_type == OP_RV2AV || + left->op_type == OP_PADAV) + ? "@array" : "%hash"); + warn("Applying %s to %s will act on scalar(%s)", desc, sample, sample); + } + if (right->op_type == OP_MATCH || right->op_type == OP_SUBST || right->op_type == OP_TRANS) { @@ -1224,7 +1401,7 @@ scope(o) OP *o; { if (o) { - if (o->op_flags & OPf_PARENS || perldb || tainting) { + if (o->op_flags & OPf_PARENS || PERLDB_NOOPT || tainting) { o = prepend_elem(OP_LINESEQ, newOP(OP_ENTER, 0), o); o->op_type = OP_LEAVE; o->op_ppaddr = ppaddr[OP_LEAVE]; @@ -1248,37 +1425,42 @@ OP *o; } int -block_start() +block_start(full) +int full; { int retval = savestack_ix; - comppad_name_fill = AvFILL(comppad_name); - SAVEINT(min_intro_pending); - SAVEINT(max_intro_pending); + SAVEI32(comppad_name_floor); + if (full) { + if ((comppad_name_fill = AvFILL(comppad_name)) > 0) + comppad_name_floor = comppad_name_fill; + else + comppad_name_floor = 0; + } + SAVEI32(min_intro_pending); + SAVEI32(max_intro_pending); min_intro_pending = 0; - SAVEINT(comppad_name_fill); - SAVEINT(padix_floor); + SAVEI32(comppad_name_fill); + SAVEI32(padix_floor); padix_floor = padix; pad_reset_pending = FALSE; - SAVEINT(hints); + SAVEI32(hints); hints &= ~HINT_BLOCK_SCOPE; return retval; } OP* -block_end(line, floor, seq) -int line; -int floor; +block_end(floor, seq) +I32 floor; OP* seq; { int needblockscope = hints & HINT_BLOCK_SCOPE; OP* retval = scalarseq(seq); - if (copline > (line_t)line) - copline = line; LEAVE_SCOPE(floor); pad_reset_pending = FALSE; if (needblockscope) hints |= HINT_BLOCK_SCOPE; /* propagate out */ pad_leavemy(comppad_name_fill); + cop_seqmax++; return retval; } @@ -1287,23 +1469,32 @@ newPROG(op) OP *op; { if (in_eval) { - eval_root = newUNOP(OP_LEAVEEVAL, 0, op); + eval_root = newUNOP(OP_LEAVEEVAL, ((in_eval & 4) ? OPf_SPECIAL : 0), op); eval_start = linklist(eval_root); eval_root->op_next = 0; peep(eval_start); } else { - if (!op) { - main_start = 0; + if (!op) return; - } main_root = scope(sawparens(scalarvoid(op))); curcop = &compiling; main_start = LINKLIST(main_root); main_root->op_next = 0; peep(main_start); - main_cv = compcv; compcv = 0; + + /* Register with debugger */ + if (PERLDB_INTER) { + CV *cv = perl_get_cv("DB::postponed", FALSE); + if (cv) { + dSP; + PUSHMARK(sp); + XPUSHs((SV*)compiling.cop_filegv); + PUTBACK; + perl_call_sv((SV*)cv, G_DISCARD); + } + } } } @@ -1362,6 +1553,16 @@ register OP *o; if (!(opargs[type] & OA_FOLDCONST)) goto nope; + switch (type) { + case OP_SPRINTF: + case OP_UCFIRST: + case OP_LCFIRST: + case OP_UC: + case OP_LC: + if (o->op_private & OPpLOCALE) + goto nope; + } + if (error_count) goto nope; /* Don't try to run w/ errors */ @@ -1388,7 +1589,7 @@ register OP *o; } op_free(o); if (type == OP_RV2GV) - return newGVOP(OP_GV, 0, sv); + return newGVOP(OP_GV, 0, (GV*)sv); else { if ((SvFLAGS(sv) & (SVf_IOK|SVf_NOK|SVf_POK)) == SVf_NOK) { IV iv = SvIV(sv); @@ -1396,6 +1597,8 @@ register OP *o; SvREFCNT_dec(sv); sv = newSViv(iv); } + else + SvIOK_off(sv); /* undo SvIV() damage */ } return newSVOP(OP_CONST, 0, sv); } @@ -1405,34 +1608,17 @@ register OP *o; return o; if (!(hints & HINT_INTEGER)) { - int vars = 0; - if (type == OP_DIVIDE || !(o->op_flags & OPf_KIDS)) return o; for (curop = ((UNOP*)o)->op_first; curop; curop = curop->op_sibling) { if (curop->op_type == OP_CONST) { - if (SvIOK(((SVOP*)curop)->op_sv)) { - if (SvIVX(((SVOP*)curop)->op_sv) <= 0 && vars++) - return o; /* negatives truncate wrong way, alas */ + if (SvIOK(((SVOP*)curop)->op_sv)) continue; - } return o; } if (opargs[curop->op_type] & OA_RETINTEGER) continue; - if (curop->op_type == OP_PADSV || curop->op_type == OP_RV2SV) { - if (vars++) - return o; - if (((o->op_type == OP_LT || o->op_type == OP_GE) && - curop == ((BINOP*)o)->op_first ) || - ((o->op_type == OP_GT || o->op_type == OP_LE) && - curop == ((BINOP*)o)->op_last )) - { - /* Allow "$i < 100" and variants to integerize */ - continue; - } - } return o; } o->op_ppaddr = ppaddr[++(o->op_type)]; @@ -1481,7 +1667,7 @@ OP* op; if (!op || op->op_type != OP_LIST) op = newLISTOP(OP_LIST, 0, op, Nullop); else - op->op_flags &= ~(OPf_KNOW|OPf_LIST); + op->op_flags &= ~OPf_WANT; if (!(opargs[type] & OA_MARK)) null(cLISTOP->op_first); @@ -1811,6 +1997,9 @@ I32 flags; pmop->op_flags = flags; pmop->op_private = 0 | (flags >> 8); + if (hints & HINT_LOCALE) + pmop->op_pmpermflags = (pmop->op_pmflags |= PMf_LOCALE); + /* link into pm list */ if (type != OP_TRANS && curstash) { pmop->op_pmnext = HvPMROOT(curstash); @@ -1832,6 +2021,7 @@ OP *repl; if (op->op_type == OP_TRANS) return pmtrans(op, expr, repl); + hints |= HINT_BLOCK_SCOPE; pm = (PMOP*)op; if (expr->op_type == OP_CONST) { @@ -2011,7 +2201,7 @@ OP *op; char *name; sv = cSVOP->op_sv; name = SvPV(sv, len); - curstash = gv_stashpv(name,TRUE); + curstash = gv_stashpvn(name,len,TRUE); sv_setpvn(curstname, name, len); op_free(op); } @@ -2024,9 +2214,10 @@ OP *op; } void -utilize(aver, floor, id, arg) +utilize(aver, floor, version, id, arg) int aver; I32 floor; +OP *version; OP *id; OP *arg; { @@ -2034,17 +2225,47 @@ OP *arg; OP *meth; OP *rqop; OP *imop; + OP *veop; if (id->op_type != OP_CONST) croak("Module name must be constant"); + veop = Nullop; + + if(version != Nullop) { + SV *vesv = ((SVOP*)version)->op_sv; + + if (arg == Nullop && !SvNIOK(vesv)) { + arg = version; + } + else { + OP *pack; + OP *meth; + + if (version->op_type != OP_CONST || !SvNIOK(vesv)) + croak("Version number must be constant number"); + + /* Make copy of id so we don't free it twice */ + pack = newSVOP(OP_CONST, 0, newSVsv(((SVOP*)id)->op_sv)); + + /* Fake up a method call to VERSION */ + meth = newSVOP(OP_CONST, 0, newSVpv("VERSION", 7)); + veop = convert(OP_ENTERSUB, OPf_STACKED|OPf_SPECIAL, + append_elem(OP_LIST, + prepend_elem(OP_LIST, pack, list(version)), + newUNOP(OP_METHOD, 0, meth))); + } + } + /* Fake up an import/unimport */ if (arg && arg->op_type == OP_STUB) imop = arg; /* no import on explicit () */ + else if(SvNIOK(((SVOP*)id)->op_sv)) { + imop = Nullop; /* use 5.0; */ + } else { /* Make copy of id so we don't free it twice */ pack = newSVOP(OP_CONST, 0, newSVsv(((SVOP*)id)->op_sv)); - meth = newSVOP(OP_CONST, 0, aver ? newSVpv("import", 6) @@ -2064,7 +2285,9 @@ OP *arg; newSVOP(OP_CONST, 0, newSVpv("BEGIN", 5)), Nullop, append_elem(OP_LINESEQ, - newSTATEOP(0, Nullch, rqop), + append_elem(OP_LINESEQ, + newSTATEOP(0, Nullch, rqop), + newSTATEOP(0, Nullch, veop)), newSTATEOP(0, Nullch, imop) )); copline = NOLINE; @@ -2212,7 +2435,7 @@ OP *right; tmpop->op_sibling = Nullop; /* don't free split */ right->op_next = tmpop->op_next; /* fix starting loc */ op_free(op); /* blow off assign */ - right->op_flags &= ~(OPf_KNOW|OPf_LIST); + right->op_flags &= ~OPf_WANT; /* "I don't know and I don't care." */ return right; } @@ -2256,25 +2479,11 @@ I32 flags; char *label; OP *op; { + U32 seq = intro_my(); register COP *cop; - /* Introduce my variables. */ - if (min_intro_pending) { - SV **svp = AvARRAY(comppad_name); - I32 i; - SV *sv; - for (i = min_intro_pending; i <= max_intro_pending; i++) { - if ((sv = svp[i]) && sv != &sv_undef && !SvIVX(sv)) { - SvIVX(sv) = 999999999; /* Don't know scope end yet. */ - SvNVX(sv) = (double)cop_seqmax; - } - } - min_intro_pending = 0; - comppad_name_fill = max_intro_pending; /* Needn't search higher */ - } - Newz(1101, cop, 1, COP); - if (perldb && curcop->cop_line && curstash != debstash) { + if (PERLDB_LINE && curcop->cop_line && curstash != debstash) { cop->op_type = OP_DBSTATE; cop->op_ppaddr = ppaddr[ OP_DBSTATE ]; } @@ -2284,13 +2493,16 @@ OP *op; } cop->op_flags = flags; cop->op_private = 0 | (flags >> 8); +#ifdef NATIVE_HINTS + cop->op_private |= NATIVE_HINTS; +#endif cop->op_next = (OP*)cop; if (label) { cop->cop_label = label; hints |= HINT_BLOCK_SCOPE; } - cop->cop_seq = cop_seqmax++; + cop->cop_seq = seq; cop->cop_arybase = curcop->cop_arybase; if (copline == NOLINE) @@ -2299,10 +2511,10 @@ OP *op; cop->cop_line = copline; copline = NOLINE; } - cop->cop_filegv = SvREFCNT_inc(curcop->cop_filegv); + cop->cop_filegv = (GV*)SvREFCNT_inc(curcop->cop_filegv); cop->cop_stash = curstash; - if (perldb && curstash != debstash) { + if (PERLDB_LINE && curstash != debstash) { SV **svp = av_fetch(GvAV(curcop->cop_filegv),(I32)cop->cop_line, FALSE); if (svp && *svp != &sv_undef && !SvIOK(*svp)) { (void)SvIOK_on(*svp); @@ -2314,6 +2526,29 @@ OP *op; return prepend_elem(OP_LINESEQ, (OP*)cop, op); } +/* "Introduce" my variables to visible status. */ +U32 +intro_my() +{ + SV **svp; + SV *sv; + I32 i; + + if (! min_intro_pending) + return cop_seqmax; + + svp = AvARRAY(comppad_name); + for (i = min_intro_pending; i <= max_intro_pending; i++) { + if ((sv = svp[i]) && sv != &sv_undef && !SvIVX(sv)) { + SvIVX(sv) = 999999999; /* Don't know scope end yet. */ + SvNVX(sv) = (double)cop_seqmax; + } + } + min_intro_pending = 0; + comppad_name_fill = max_intro_pending; /* Needn't search higher */ + return cop_seqmax++; +} + OP * newLOGOP(type, flags, first, other) I32 type; @@ -2361,6 +2596,36 @@ OP* other; else scalar(other); } + else if (dowarn && (first->op_flags & OPf_KIDS)) { + OP *k1 = ((UNOP*)first)->op_first; + OP *k2 = k1->op_sibling; + OPCODE warnop = 0; + switch (first->op_type) + { + case OP_NULL: + if (k2 && k2->op_type == OP_READLINE + && (k2->op_flags & OPf_STACKED) + && (k1->op_type == OP_RV2SV || k1->op_type == OP_PADSV)) + warnop = k2->op_type; + break; + + case OP_SASSIGN: + if (k1->op_type == OP_READDIR + || k1->op_type == OP_GLOB + || k1->op_type == OP_EACH) + warnop = k1->op_type; + break; + } + if (warnop) { + line_t oldline = curcop->cop_line; + curcop->cop_line = copline; + warn("Value of %s%s can be \"0\"; test with defined()", + op_desc[warnop], + ((warnop == OP_READLINE || warnop == OP_GLOB) + ? " construct" : "() operator")); + curcop->cop_line = oldline; + } + } if (!other) return first; @@ -2389,36 +2654,36 @@ OP* other; } OP * -newCONDOP(flags, first, true, false) +newCONDOP(flags, first, trueop, falseop) I32 flags; OP* first; -OP* true; -OP* false; +OP* trueop; +OP* falseop; { CONDOP *condop; OP *op; - if (!false) - return newLOGOP(OP_AND, 0, first, true); - if (!true) - return newLOGOP(OP_OR, 0, first, false); + if (!falseop) + return newLOGOP(OP_AND, 0, first, trueop); + if (!trueop) + return newLOGOP(OP_OR, 0, first, falseop); scalarboolean(first); if (first->op_type == OP_CONST) { if (SvTRUE(((SVOP*)first)->op_sv)) { op_free(first); - op_free(false); - return true; + op_free(falseop); + return trueop; } else { op_free(first); - op_free(true); - return false; + op_free(trueop); + return falseop; } } else if (first->op_type == OP_WANTARRAY) { - list(true); - scalar(false); + list(trueop); + scalar(falseop); } Newz(1101, condop, 1, CONDOP); @@ -2426,20 +2691,20 @@ OP* false; condop->op_ppaddr = ppaddr[OP_COND_EXPR]; condop->op_first = first; condop->op_flags = flags | OPf_KIDS; - condop->op_true = LINKLIST(true); - condop->op_false = LINKLIST(false); + condop->op_true = LINKLIST(trueop); + condop->op_false = LINKLIST(falseop); condop->op_private = 1 | (flags >> 8); /* establish postfix order */ condop->op_next = LINKLIST(first); first->op_next = (OP*)condop; - first->op_sibling = true; - true->op_sibling = false; + first->op_sibling = trueop; + trueop->op_sibling = falseop; op = newUNOP(OP_NULL, 0, (OP*)condop); - true->op_next = op; - false->op_next = op; + trueop->op_next = op; + falseop->op_next = op; return op; } @@ -2506,8 +2771,11 @@ OP *block; if (expr) { if (once && expr->op_type == OP_CONST && !SvTRUE(((SVOP*)expr)->op_sv)) return block; /* do {} while 0 does once */ - else if (expr->op_type == OP_READLINE || expr->op_type == OP_GLOB) - expr = newASSIGNOP(0, newSVREF(newGVOP(OP_GV, 0, defgv)), 0, expr); + if (expr->op_type == OP_READLINE || expr->op_type == OP_GLOB + || (expr->op_type == OP_NULL && expr->op_targ == OP_GLOB)) { + expr = newUNOP(OP_DEFINED, 0, + newASSIGNOP(0, newSVREF(newGVOP(OP_GV, 0, defgv)), 0, expr) ); + } } listop = append_elem(OP_LINESEQ, block, newOP(OP_UNSTACK, 0)); @@ -2528,10 +2796,11 @@ OP *block; } OP * -newWHILEOP(flags, debuggable, loop, expr, block, cont) +newWHILEOP(flags, debuggable, loop, whileline, expr, block, cont) I32 flags; I32 debuggable; LOOP *loop; +I32 whileline; OP *expr; OP *block; OP *cont; @@ -2542,7 +2811,8 @@ OP *cont; OP *op; OP *condop; - if (expr && (expr->op_type == OP_READLINE || expr->op_type == OP_GLOB)) { + if (expr && (expr->op_type == OP_READLINE || expr->op_type == OP_GLOB + || (expr->op_type == OP_NULL && expr->op_targ == OP_GLOB))) { expr = newUNOP(OP_DEFINED, 0, newASSIGNOP(0, newSVREF(newGVOP(OP_GV, 0, defgv)), 0, expr) ); } @@ -2552,8 +2822,14 @@ OP *cont; if (cont) next = LINKLIST(cont); - if (expr) + if (expr) { cont = append_elem(OP_LINESEQ, cont, newOP(OP_UNSTACK, 0)); + if ((line_t)whileline != NOLINE) { + copline = whileline; + cont = append_elem(OP_LINESEQ, cont, + newSTATEOP(0, Nullch, Nullop)); + } + } listop = append_list(OP_LINESEQ, (LISTOP*)block, (LISTOP*)cont); redo = LINKLIST(listop); @@ -2611,10 +2887,10 @@ newFOROP(I32 flags,char *label,line_t forline,OP *sv,OP *expr,OP *block,OP *cont #endif /* CAN_PROTOTYPE */ { LOOP *loop; + OP *wop; int padoff = 0; I32 iterflags = 0; - copline = forline; if (sv) { if (sv->op_type == OP_RV2SV) { /* symbol table variable */ sv->op_type = OP_RV2GV; @@ -2631,7 +2907,7 @@ newFOROP(I32 flags,char *label,line_t forline,OP *sv,OP *expr,OP *block,OP *cont else { sv = newGVOP(OP_GV, 0, defgv); } - if (expr->op_type == OP_RV2AV) { + if (expr->op_type == OP_RV2AV || expr->op_type == OP_PADAV) { expr = scalar(ref(expr, OP_ITER)); iterflags |= OPf_STACKED; } @@ -2641,8 +2917,9 @@ newFOROP(I32 flags,char *label,line_t forline,OP *sv,OP *expr,OP *block,OP *cont assert(!loop->op_next); Renew(loop, 1, LOOP); loop->op_targ = padoff; - return newSTATEOP(0, label, newWHILEOP(flags, 1, loop, - newOP(OP_ITER, 0), block, cont)); + wop = newWHILEOP(flags, 1, loop, forline, newOP(OP_ITER, 0), block, cont); + copline = forline; + return newSTATEOP(0, label, wop); } OP* @@ -2684,60 +2961,135 @@ CV *cv; CvROOT(cv) = Nullop; LEAVE; } + SvPOK_off((SV*)cv); /* forget prototype */ + CvFLAGS(cv) = 0; SvREFCNT_dec(CvGV(cv)); CvGV(cv) = Nullgv; SvREFCNT_dec(CvOUTSIDE(cv)); CvOUTSIDE(cv) = Nullcv; if (CvPADLIST(cv)) { - I32 i = AvFILL(CvPADLIST(cv)); - while (i >= 0) { - SV** svp = av_fetch(CvPADLIST(cv), i--, FALSE); - if (svp) - SvREFCNT_dec(*svp); + /* may be during global destruction */ + if (SvREFCNT(CvPADLIST(cv))) { + I32 i = AvFILL(CvPADLIST(cv)); + while (i >= 0) { + SV** svp = av_fetch(CvPADLIST(cv), i--, FALSE); + SV* sv = svp ? *svp : Nullsv; + if (!sv) + continue; + if (sv == (SV*)comppad_name) + comppad_name = Nullav; + else if (sv == (SV*)comppad) { + comppad = Nullav; + curpad = Null(SV**); + } + SvREFCNT_dec(sv); + } + SvREFCNT_dec((SV*)CvPADLIST(cv)); } - SvREFCNT_dec((SV*)CvPADLIST(cv)); CvPADLIST(cv) = Nullav; } } -CV * -cv_clone(proto) +#ifdef DEBUG_CLOSURES +static void +cv_dump(cv) +CV* cv; +{ + CV *outside = CvOUTSIDE(cv); + AV* padlist = CvPADLIST(cv); + AV* pad_name; + AV* pad; + SV** pname; + SV** ppad; + I32 ix; + + PerlIO_printf(Perl_debug_log, "\tCV=0x%lx (%s), OUTSIDE=0x%lx (%s)\n", + cv, + (CvANON(cv) ? "ANON" + : (cv == main_cv) ? "MAIN" + : CvUNIQUE(outside) ? "UNIQUE" + : CvGV(cv) ? GvNAME(CvGV(cv)) : "UNDEFINED"), + outside, + (!outside ? "null" + : CvANON(outside) ? "ANON" + : (outside == main_cv) ? "MAIN" + : CvUNIQUE(outside) ? "UNIQUE" + : CvGV(outside) ? GvNAME(CvGV(outside)) : "UNDEFINED")); + + if (!padlist) + return; + + pad_name = (AV*)*av_fetch(padlist, 0, FALSE); + pad = (AV*)*av_fetch(padlist, 1, FALSE); + pname = AvARRAY(pad_name); + ppad = AvARRAY(pad); + + for (ix = 1; ix <= AvFILL(pad_name); ix++) { + if (SvPOK(pname[ix])) + PerlIO_printf(Perl_debug_log, "\t%4d. 0x%lx (%s\"%s\" %ld-%ld)\n", + ix, ppad[ix], + SvFAKE(pname[ix]) ? "FAKE " : "", + SvPVX(pname[ix]), + (long)I_32(SvNVX(pname[ix])), + (long)SvIVX(pname[ix])); + } +} +#endif /* DEBUG_CLOSURES */ + +static CV * +cv_clone2(proto, outside) CV* proto; +CV* outside; { AV* av; I32 ix; AV* protopadlist = CvPADLIST(proto); AV* protopad_name = (AV*)*av_fetch(protopadlist, 0, FALSE); AV* protopad = (AV*)*av_fetch(protopadlist, 1, FALSE); - SV** svp = AvARRAY(protopad); + SV** pname = AvARRAY(protopad_name); + SV** ppad = AvARRAY(protopad); + I32 fname = AvFILL(protopad_name); + I32 fpad = AvFILL(protopad); AV* comppadlist; CV* cv; + assert(!CvUNIQUE(proto)); + ENTER; SAVESPTR(curpad); SAVESPTR(comppad); + SAVESPTR(comppad_name); SAVESPTR(compcv); cv = compcv = (CV*)NEWSV(1104,0); - sv_upgrade((SV *)cv, SVt_PVCV); + sv_upgrade((SV *)cv, SvTYPE(proto)); CvCLONED_on(cv); + if (CvANON(proto)) + CvANON_on(cv); CvFILEGV(cv) = CvFILEGV(proto); - CvGV(cv) = SvREFCNT_inc(CvGV(proto)); + CvGV(cv) = (GV*)SvREFCNT_inc(CvGV(proto)); CvSTASH(cv) = CvSTASH(proto); CvROOT(cv) = CvROOT(proto); CvSTART(cv) = CvSTART(proto); - if (CvOUTSIDE(proto)) - CvOUTSIDE(cv) = (CV*)SvREFCNT_inc((SV*)CvOUTSIDE(proto)); + if (outside) + CvOUTSIDE(cv) = (CV*)SvREFCNT_inc(outside); + + if (SvPOK(proto)) + sv_setpvn((SV*)cv, SvPVX(proto), SvCUR(proto)); + + comppad_name = newAV(); + for (ix = fname; ix >= 0; ix--) + av_store(comppad_name, ix, SvREFCNT_inc(pname[ix])); comppad = newAV(); comppadlist = newAV(); AvREAL_off(comppadlist); - av_store(comppadlist, 0, SvREFCNT_inc((SV*)protopad_name)); + av_store(comppadlist, 0, (SV*)comppad_name); av_store(comppadlist, 1, (SV*)comppad); CvPADLIST(cv) = comppadlist; - av_extend(comppad, AvFILL(protopad)); + av_fill(comppad, AvFILL(protopad)); curpad = AvARRAY(comppad); av = newAV(); /* will be @_ */ @@ -2745,70 +3097,190 @@ CV* proto; av_store(comppad, 0, (SV*)av); AvFLAGS(av) = AVf_REIFY; - svp = AvARRAY(protopad_name); - for ( ix = AvFILL(protopad); ix > 0; ix--) { - SV *sv; - if (svp[ix] != &sv_undef) { - char *name = SvPVX(svp[ix]); /* XXX */ - if (SvFLAGS(svp[ix]) & SVf_FAKE) { /* lexical from outside? */ - I32 off = pad_findlex(name,ix,curcop->cop_seq, CvOUTSIDE(proto), - cxstack_ix); - if (off != ix) + for (ix = fpad; ix > 0; ix--) { + SV* namesv = (ix <= fname) ? pname[ix] : Nullsv; + if (namesv && namesv != &sv_undef) { + char *name = SvPVX(namesv); /* XXX */ + if (SvFLAGS(namesv) & SVf_FAKE) { /* lexical from outside? */ + I32 off = pad_findlex(name, ix, SvIVX(namesv), + CvOUTSIDE(cv), cxstack_ix); + if (!off) + curpad[ix] = SvREFCNT_inc(ppad[ix]); + else if (off != ix) croak("panic: cv_clone: %s", name); } else { /* our own lexical */ - if (*name == '@') - av_store(comppad, ix, sv = (SV*)newAV()); + SV* sv; + if (*name == '&') { + /* anon code -- we'll come back for it */ + sv = SvREFCNT_inc(ppad[ix]); + } + else if (*name == '@') + sv = (SV*)newAV(); else if (*name == '%') - av_store(comppad, ix, sv = (SV*)newHV()); + sv = (SV*)newHV(); else - av_store(comppad, ix, sv = NEWSV(0,0)); - SvPADMY_on(sv); + sv = NEWSV(0,0); + if (!SvPADBUSY(sv)) + SvPADMY_on(sv); + curpad[ix] = sv; } } else { - av_store(comppad, ix, sv = NEWSV(0,0)); + SV* sv = NEWSV(0,0); SvPADTMP_on(sv); + curpad[ix] = sv; + } + } + + /* Now that vars are all in place, clone nested closures. */ + + for (ix = fpad; ix > 0; ix--) { + SV* namesv = (ix <= fname) ? pname[ix] : Nullsv; + if (namesv + && namesv != &sv_undef + && !(SvFLAGS(namesv) & SVf_FAKE) + && *SvPVX(namesv) == '&' + && CvCLONE(ppad[ix])) + { + CV *kid = cv_clone2((CV*)ppad[ix], cv); + SvREFCNT_dec(ppad[ix]); + CvCLONE_on(kid); + SvPADMY_on(kid); + curpad[ix] = (SV*)kid; } } +#ifdef DEBUG_CLOSURES + PerlIO_printf(Perl_debug_log, "Cloned inside:\n"); + cv_dump(outside); + PerlIO_printf(Perl_debug_log, " from:\n"); + cv_dump(proto); + PerlIO_printf(Perl_debug_log, " to:\n"); + cv_dump(cv); +#endif + LEAVE; return cv; } CV * +cv_clone(proto) +CV* proto; +{ + return cv_clone2(proto, CvOUTSIDE(proto)); +} + +void +cv_ckproto(cv, gv, p) +CV* cv; +GV* gv; +char* p; +{ + if ((!p != !SvPOK(cv)) || (p && strNE(p, SvPVX(cv)))) { + SV* msg = sv_newmortal(); + SV* name = Nullsv; + + if (gv) + gv_efullname3(name = sv_newmortal(), gv, Nullch); + sv_setpv(msg, "Prototype mismatch:"); + if (name) + sv_catpvf(msg, " sub %_", name); + if (SvPOK(cv)) + sv_catpvf(msg, " (%s)", SvPVX(cv)); + sv_catpv(msg, " vs "); + if (p) + sv_catpvf(msg, "(%s)", p); + else + sv_catpv(msg, "none"); + warn("%_", msg); + } +} + +SV * +cv_const_sv(cv) +CV* cv; +{ + OP *o; + SV *sv; + + if (!cv || !SvPOK(cv) || SvCUR(cv)) + return Nullsv; + + sv = Nullsv; + for (o = CvSTART(cv); o; o = o->op_next) { + OPCODE type = o->op_type; + + if (type == OP_NEXTSTATE || type == OP_NULL || type == OP_PUSHMARK) + continue; + if (type == OP_LEAVESUB || type == OP_RETURN) + break; + if (sv) + return Nullsv; + if (type == OP_CONST) + sv = ((SVOP*)o)->op_sv; + else if (type == OP_PADSV) { + AV* pad = (AV*)(AvARRAY(CvPADLIST(cv))[1]); + sv = pad ? AvARRAY(pad)[o->op_targ] : Nullsv; + if (!sv || (!SvREADONLY(sv) && SvREFCNT(sv) > 1)) + return Nullsv; + } + else + return Nullsv; + } + if (sv) + SvREADONLY_on(sv); + return sv; +} + +CV * newSUB(floor,op,proto,block) I32 floor; OP *op; OP *proto; OP *block; { + char *name = op ? SvPVx(cSVOP->op_sv, na) : Nullch; + GV *gv = gv_fetchpv(name ? name : "__ANON__", GV_ADDMULTI, SVt_PVCV); + char *ps = proto ? SvPVx(((SVOP*)proto)->op_sv, na) : Nullch; register CV *cv; - char *name = op ? SvPVx(cSVOP->op_sv, na) : "__ANON__"; - GV* gv = gv_fetchpv(name, GV_ADDMULTI, SVt_PVCV); - AV* av; - char *s; I32 ix; if (op) - sub_generation++; - if (cv = GvCV(gv)) { - if (GvCVGEN(gv)) - cv = 0; /* just a cached method */ - else if (CvROOT(cv) || CvXSUB(cv) || GvASSUMECV(gv)) { - if (dowarn) { /* already defined (or promised)? */ + SAVEFREEOP(op); + if (proto) + SAVEFREEOP(proto); + + if (!name || GvCVGEN(gv)) + cv = Nullcv; + else if (cv = GvCV(gv)) { + cv_ckproto(cv, gv, ps); + /* already defined (or promised)? */ + if (CvROOT(cv) || CvXSUB(cv) || GvASSUMECV(gv)) { + SV* const_sv; + if (!block) { + /* just a "sub foo;" when &foo is already defined */ + SAVEFREESV(compcv); + goto done; + } + /* ahem, death to those who redefine active sort subs */ + if (curstack == sortstack && sortcop == CvSTART(cv)) + croak("Can't redefine active sort subroutine %s", name); + const_sv = cv_const_sv(cv); + if (const_sv || dowarn) { line_t oldline = curcop->cop_line; - curcop->cop_line = copline; - warn("Subroutine %s redefined",name); + warn(const_sv ? "Constant subroutine %s redefined" + : "Subroutine %s redefined", name); curcop->cop_line = oldline; } SvREFCNT_dec(cv); - cv = 0; + cv = Nullcv; } } if (cv) { /* must reuse cv if autoloaded */ cv_undef(cv); + CvFLAGS(cv) = CvFLAGS(compcv); CvOUTSIDE(cv) = CvOUTSIDE(compcv); CvOUTSIDE(compcv) = 0; CvPADLIST(cv) = CvPADLIST(compcv); @@ -2819,99 +3291,152 @@ OP *block; } else { cv = compcv; + if (name) { + GvCV(gv) = cv; + GvCVGEN(gv) = 0; + sub_generation++; + } } - GvCV(gv) = cv; - GvCVGEN(gv) = 0; + CvGV(cv) = (GV*)SvREFCNT_inc(gv); CvFILEGV(cv) = curcop->cop_filegv; - CvGV(cv) = SvREFCNT_inc(gv); CvSTASH(cv) = curstash; - if (proto) { - char *p = SvPVx(((SVOP*)proto)->op_sv, na); - if (SvPOK(cv) && strNE(SvPV((SV*)cv,na), p)) - warn("Prototype mismatch: (%s) vs (%s)", SvPV((SV*)cv, na), p); - sv_setpv((SV*)cv, p); - op_free(proto); - } + if (ps) + sv_setpv((SV*)cv, ps); if (error_count) { op_free(block); block = Nullop; + if (name) { + char *s = strrchr(name, ':'); + s = s ? s+1 : name; + if (strEQ(s, "BEGIN")) { + char *not_safe = + "BEGIN not safe after errors--compilation aborted"; + if (in_eval & 4) + croak(not_safe); + else { + /* force display of errors found but not reported */ + sv_catpv(GvSV(errgv), not_safe); + croak("%s", SvPVx(GvSV(errgv), na)); + } + } + } } if (!block) { - CvROOT(cv) = 0; - op_free(op); copline = NOLINE; LEAVE_SCOPE(floor); return cv; } - av = newAV(); /* Will be @_ */ - av_extend(av, 0); - av_store(comppad, 0, (SV*)av); - AvFLAGS(av) = AVf_REIFY; + if (AvFILL(comppad_name) < AvFILL(comppad)) + av_store(comppad_name, AvFILL(comppad), Nullsv); - for (ix = AvFILL(comppad); ix > 0; ix--) { - if (!SvPADMY(curpad[ix])) - SvPADTMP_on(curpad[ix]); + if (CvCLONE(cv)) { + SV **namep = AvARRAY(comppad_name); + for (ix = AvFILL(comppad); ix > 0; ix--) { + SV *namesv; + + if (SvIMMORTAL(curpad[ix])) + continue; + /* + * The only things that a clonable function needs in its + * pad are references to outer lexicals and anonymous subs. + * The rest are created anew during cloning. + */ + if (!((namesv = namep[ix]) != Nullsv && + namesv != &sv_undef && + (SvFAKE(namesv) || + *SvPVX(namesv) == '&'))) + { + SvREFCNT_dec(curpad[ix]); + curpad[ix] = Nullsv; + } + } } + else { + AV *av = newAV(); /* Will be @_ */ + av_extend(av, 0); + av_store(comppad, 0, (SV*)av); + AvFLAGS(av) = AVf_REIFY; - if (AvFILL(comppad_name) < AvFILL(comppad)) - av_store(comppad_name, AvFILL(comppad), Nullsv); + for (ix = AvFILL(comppad); ix > 0; ix--) { + if (SvIMMORTAL(curpad[ix])) + continue; + if (!SvPADMY(curpad[ix])) + SvPADTMP_on(curpad[ix]); + } + } CvROOT(cv) = newUNOP(OP_LEAVESUB, 0, scalarseq(block)); CvSTART(cv) = LINKLIST(CvROOT(cv)); CvROOT(cv)->op_next = 0; peep(CvSTART(cv)); - if (s = strrchr(name,':')) - s++; - else - s = name; - if (strEQ(s, "BEGIN") && !error_count) { - line_t oldline = compiling.cop_line; - SV *oldrs = rs; - ENTER; - SAVESPTR(compiling.cop_filegv); - SAVEI32(perldb); - if (!beginav) - beginav = newAV(); - av_push(beginav, (SV *)cv); - DEBUG_x( dump_sub(gv) ); - rs = SvREFCNT_inc(nrs); - GvCV(gv) = 0; - calllist(beginav); - SvREFCNT_dec(rs); - rs = oldrs; - curcop = &compiling; - curcop->cop_line = oldline; /* might have recursed to yylex */ - LEAVE; - } - else if (strEQ(s, "END") && !error_count) { - if (!endav) - endav = newAV(); - av_unshift(endav, 1); - av_store(endav, 0, SvREFCNT_inc(cv)); - } - if (perldb && curstash != debstash) { - SV *sv; - SV *tmpstr = sv_newmortal(); + if (name) { + char *s; + + if (PERLDB_SUBLINE && curstash != debstash) { + SV *sv = NEWSV(0,0); + SV *tmpstr = sv_newmortal(); + static GV *db_postponed; + CV *cv; + HV *hv; + + sv_setpvf(sv, "%_:%ld-%ld", + GvSV(curcop->cop_filegv), + (long)subline, (long)curcop->cop_line); + gv_efullname3(tmpstr, gv, Nullch); + hv_store(GvHV(DBsub), SvPVX(tmpstr), SvCUR(tmpstr), sv, 0); + if (!db_postponed) { + db_postponed = gv_fetchpv("DB::postponed", GV_ADDMULTI, SVt_PVHV); + } + hv = GvHVn(db_postponed); + if (HvFILL(hv) > 0 && hv_exists(hv, SvPVX(tmpstr), SvCUR(tmpstr)) + && (cv = GvCV(db_postponed))) { + dSP; + PUSHMARK(sp); + XPUSHs(tmpstr); + PUTBACK; + perl_call_sv((SV*)cv, G_DISCARD); + } + } - sprintf(buf,"%s:%ld",SvPVX(GvSV(curcop->cop_filegv)), (long)subline); - sv = newSVpv(buf,0); - sv_catpv(sv,"-"); - sprintf(buf,"%ld",(long)curcop->cop_line); - sv_catpv(sv,buf); - gv_efullname(tmpstr,gv); - hv_store(GvHV(DBsub), SvPVX(tmpstr), SvCUR(tmpstr), sv, 0); + if ((s = strrchr(name,':'))) + s++; + else + s = name; + if (strEQ(s, "BEGIN")) { + I32 oldscope = scopestack_ix; + ENTER; + SAVESPTR(compiling.cop_filegv); + SAVEI16(compiling.cop_line); + SAVEI32(perldb); + save_svref(&rs); + sv_setsv(rs, nrs); + + if (!beginav) + beginav = newAV(); + DEBUG_x( dump_sub(gv) ); + av_push(beginav, (SV *)cv); + GvCV(gv) = 0; + call_list(oldscope, beginav); + + curcop = &compiling; + LEAVE; + } + else if (strEQ(s, "END") && !error_count) { + if (!endav) + endav = newAV(); + av_unshift(endav, 1); + av_store(endav, 0, (SV *)cv); + GvCV(gv) = 0; + } } - op_free(op); + + done: copline = NOLINE; LEAVE_SCOPE(floor); - if (!op) { - GvCV(gv) = 0; /* Will remember in SVOP instead. */ - CvANON_on(cv); - } return cv; } @@ -2936,19 +3461,19 @@ char *name; void (*subaddr) _((CV*)); char *filename; { + GV *gv = gv_fetchpv(name ? name : "__ANON__", GV_ADDMULTI, SVt_PVCV); register CV *cv; - GV *gv = gv_fetchpv((name ? name : "__ANON__"), GV_ADDMULTI, SVt_PVCV); - char *s; - - if (name) - sub_generation++; - if (cv = GvCV(gv)) { - if (GvCVGEN(gv)) - cv = 0; /* just a cached method */ - else if (CvROOT(cv) || CvXSUB(cv)) { /* already defined? */ + + if (cv = (name ? GvCV(gv) : Nullcv)) { + if (GvCVGEN(gv)) { + /* just a cached method */ + SvREFCNT_dec(cv); + cv = 0; + } + else if (CvROOT(cv) || CvXSUB(cv) || GvASSUMECV(gv)) { + /* already defined (or promised) */ if (dowarn) { line_t oldline = curcop->cop_line; - curcop->cop_line = copline; warn("Subroutine %s redefined",name); curcop->cop_line = oldline; @@ -2957,40 +3482,45 @@ char *filename; cv = 0; } } - if (cv) { /* must reuse cv if autoloaded */ - assert(SvREFCNT(CvGV(cv)) > 1); - SvREFCNT_dec(CvGV(cv)); - } + + if (cv) /* must reuse cv if autoloaded */ + cv_undef(cv); else { cv = (CV*)NEWSV(1105,0); sv_upgrade((SV *)cv, SVt_PVCV); + if (name) { + GvCV(gv) = cv; + GvCVGEN(gv) = 0; + sub_generation++; + } } - GvCV(gv) = cv; - CvGV(cv) = SvREFCNT_inc(gv); - GvCVGEN(gv) = 0; + CvGV(cv) = (GV*)SvREFCNT_inc(gv); CvFILEGV(cv) = gv_fetchfile(filename); CvXSUB(cv) = subaddr; - if (!name) - s = "__ANON__"; - else if (s = strrchr(name,':')) - s++; + + if (name) { + char *s = strrchr(name,':'); + if (s) + s++; + else + s = name; + if (strEQ(s, "BEGIN")) { + if (!beginav) + beginav = newAV(); + av_push(beginav, (SV *)cv); + GvCV(gv) = 0; + } + else if (strEQ(s, "END")) { + if (!endav) + endav = newAV(); + av_unshift(endav, 1); + av_store(endav, 0, (SV *)cv); + GvCV(gv) = 0; + } + } else - s = name; - if (strEQ(s, "BEGIN")) { - if (!beginav) - beginav = newAV(); - av_push(beginav, SvREFCNT_inc(gv)); - } - else if (strEQ(s, "END")) { - if (!endav) - endav = newAV(); - av_unshift(endav, 1); - av_store(endav, 0, SvREFCNT_inc(gv)); - } - if (!name) { - GvCV(gv) = 0; /* Will remember elsewhere instead. */ CvANON_on(cv); - } + return cv; } @@ -3023,11 +3553,11 @@ OP *block; } cv = compcv; GvFORM(gv) = cv; - CvGV(cv) = SvREFCNT_inc(gv); + CvGV(cv) = (GV*)SvREFCNT_inc(gv); CvFILEGV(cv) = curcop->cop_filegv; for (ix = AvFILL(comppad); ix > 0; ix--) { - if (!SvPADMY(curpad[ix])) + if (!SvPADMY(curpad[ix]) && !SvIMMORTAL(curpad[ix])) SvPADTMP_on(curpad[ix]); } @@ -3035,7 +3565,6 @@ OP *block; CvSTART(cv) = LINKLIST(CvROOT(cv)); CvROOT(cv)->op_next = 0; peep(CvSTART(cv)); - FmLINES(cv) = 0; op_free(op); copline = NOLINE; LEAVE_SCOPE(floor); @@ -3181,6 +3710,35 @@ OP *o; /* Check routines. */ OP * +ck_anoncode(op) +OP *op; +{ + PADOFFSET ix; + SV* name; + + name = NEWSV(1106,0); + sv_upgrade(name, SVt_PVNV); + sv_setpvn(name, "&", 1); + SvIVX(name) = -1; + SvNVX(name) = 1; + ix = pad_alloc(op->op_type, SVs_PADMY); + av_store(comppad_name, ix, name); + av_store(comppad, ix, cSVOP->op_sv); + SvPADMY_on(cSVOP->op_sv); + cSVOP->op_sv = Nullsv; + cSVOP->op_targ = ix; + return op; +} + +OP * +ck_bitop(op) +OP *op; +{ + op->op_private = hints; + return op; +} + +OP * ck_concat(op) OP *op; { @@ -3196,7 +3754,8 @@ OP *op; if (op->op_flags & OPf_KIDS) { OP* newop; OP* kid; - op = modkids(ck_fun(op), op->op_type); + OPCODE type = op->op_type; + op = modkids(ck_fun(op), type); kid = cUNOP->op_first; newop = kUNOP->op_first->op_sibling; if (newop && @@ -3219,10 +3778,14 @@ ck_delete(op) OP *op; { op = ck_fun(op); + op->op_private = 0; if (op->op_flags & OPf_KIDS) { OP *kid = cUNOP->op_first; - if (kid->op_type != OP_HELEM) - croak("%s argument is not a HASH element", op_desc[op->op_type]); + if (kid->op_type == OP_HSLICE) + op->op_private |= OPpSLICE; + else if (kid->op_type != OP_HELEM) + croak("%s argument is not a HASH element or slice", + op_desc[op->op_type]); null(kid); } return op; @@ -3238,7 +3801,7 @@ OP *op; if (cLISTOP->op_first->op_type == OP_STUB) { op_free(op); op = newUNOP(type, OPf_SPECIAL, - newGVOP(OP_GV, 0, gv_fetchpv("main'ARGV", TRUE, SVt_PVAV))); + newGVOP(OP_GV, 0, gv_fetchpv("main::ARGV", TRUE, SVt_PVAV))); } return ck_fun(op); } @@ -3304,6 +3867,20 @@ OP *op; } OP * +ck_exists(op) +OP *op; +{ + op = ck_fun(op); + if (op->op_flags & OPf_KIDS) { + OP *kid = cUNOP->op_first; + if (kid->op_type != OP_HELEM) + croak("%s argument is not a HASH element", op_desc[op->op_type]); + null(kid); + } + return op; +} + +OP * ck_gvconst(o) register OP *o; { @@ -3321,9 +3898,31 @@ register OP *op; op->op_private |= (hints & HINT_STRICT_REFS); if (kid->op_type == OP_CONST) { - int iscv = (op->op_type==OP_RV2CV)*2; - GV *gv = 0; + char *name; + int iscv; + GV *gv; + + name = SvPV(kid->op_sv, na); + if ((hints & HINT_STRICT_REFS) && (kid->op_private & OPpCONST_BARE)) { + char *badthing = Nullch; + switch (op->op_type) { + case OP_RV2SV: + badthing = "a SCALAR"; + break; + case OP_RV2AV: + badthing = "an ARRAY"; + break; + case OP_RV2HV: + badthing = "a HASH"; + break; + } + if (badthing) + croak( + "Can't use bareword (\"%s\") as %s ref while \"strict refs\" in use", + name, badthing); + } kid->op_type = OP_GV; + iscv = (op->op_type == OP_RV2CV) * 2; for (gv = 0; !gv; iscv++) { /* * This is a little tricky. We only want to add the symbol if we @@ -3333,7 +3932,7 @@ register OP *op; * or we get possible typo warnings. OPpCONST_ENTERED says * whether the lexer already added THIS instance of this symbol. */ - gv = gv_fetchpv(SvPVx(kid->op_sv, na), + gv = gv_fetchpv(name, iscv | !(kid->op_private & OPpCONST_ENTERED), iscv ? SVt_PVCV @@ -3352,13 +3951,6 @@ register OP *op; } OP * -ck_formline(op) -OP *op; -{ - return ck_fun(op); -} - -OP * ck_ftst(op) OP *op; { @@ -3380,7 +3972,7 @@ OP *op; else { op_free(op); if (type == OP_FTTTY) - return newGVOP(type, OPf_REF, gv_fetchpv("main'STDIN", TRUE, + return newGVOP(type, OPf_REF, gv_fetchpv("main::STDIN", TRUE, SVt_PVIO)); else return newUNOP(type, 0, newSVREF(newGVOP(OP_GV, 0, defgv))); @@ -3440,8 +4032,8 @@ OP *op; OP *newop = newAVREF(newGVOP(OP_GV, 0, gv_fetchpv(name, TRUE, SVt_PVAV) )); if (dowarn) - warn("Array @%s missing the @ in argument %d of %s()", - name, numargs, op_desc[type]); + warn("Array @%s missing the @ in argument %ld of %s()", + name, (long)numargs, op_desc[type]); op_free(kid); kid = newop; kid->op_sibling = sibl; @@ -3458,8 +4050,8 @@ OP *op; OP *newop = newHVREF(newGVOP(OP_GV, 0, gv_fetchpv(name, TRUE, SVt_PVHV) )); if (dowarn) - warn("Hash %%%s missing the %% in argument %d of %s()", - name, numargs, op_desc[type]); + warn("Hash %%%s missing the %% in argument %ld of %s()", + name, (long)numargs, op_desc[type]); op_free(kid); kid = newop; kid->op_sibling = sibl; @@ -3530,7 +4122,32 @@ OP * ck_glob(op) OP *op; { - GV *gv = newGVgen("main"); + GV *gv; + + if ((op->op_flags & OPf_KIDS) && !cLISTOP->op_first->op_sibling) + append_elem(OP_GLOB, op, newSVREF(newGVOP(OP_GV, 0, defgv))); + + if (!((gv = gv_fetchpv("glob", FALSE, SVt_PVCV)) && GvIMPORTED_CV(gv))) + gv = gv_fetchpv("CORE::GLOBAL::glob", FALSE, SVt_PVCV); + + if (gv && GvIMPORTED_CV(gv)) { + static int glob_index; + + append_elem(OP_GLOB, op, + newSVOP(OP_CONST, 0, newSViv(glob_index++))); + op->op_type = OP_LIST; + op->op_ppaddr = ppaddr[OP_LIST]; + ((LISTOP*)op)->op_first->op_type = OP_PUSHMARK; + ((LISTOP*)op)->op_first->op_ppaddr = ppaddr[OP_PUSHMARK]; + op = newUNOP(OP_ENTERSUB, OPf_STACKED, + append_elem(OP_LIST, op, + scalar(newUNOP(OP_RV2CV, 0, + newGVOP(OP_GV, 0, gv))))); + op = newUNOP(OP_NULL, 0, ck_subr(op)); + op->op_targ = OP_GLOB; /* hint at what it used to be */ + return op; + } + gv = newGVgen("main"); gv_IOadd(gv); append_elem(OP_GLOB, op, newGVOP(OP_GV, 0, gv)); scalarkids(op); @@ -3596,7 +4213,7 @@ OP *op; if (op->op_flags & OPf_KIDS) { OP *kid = cLISTOP->op_first->op_sibling; /* get past pushmark */ if (kid && kid->op_type == OP_CONST) - fbm_compile(((SVOP*)kid)->op_sv, 0); + fbm_compile(((SVOP*)kid)->op_sv); } return ck_fun(op); } @@ -3613,14 +4230,16 @@ OP * ck_lfun(op) OP *op; { - return modkids(ck_fun(op), op->op_type); + OPCODE type = op->op_type; + return modkids(ck_fun(op), type); } OP * ck_rfun(op) OP *op; { - return refkids(ck_fun(op), op->op_type); + OPCODE type = op->op_type; + return refkids(ck_fun(op), type); } OP * @@ -3651,15 +4270,50 @@ OP *op; if (!kid) append_elem(op->op_type, op, newSVREF(newGVOP(OP_GV, 0, defgv)) ); - return listkids(op); + op = listkids(op); + + op->op_private = 0; +#ifdef USE_LOCALE + if (hints & HINT_LOCALE) + op->op_private |= OPpLOCALE; +#endif + + return op; +} + +OP * +ck_fun_locale(op) +OP *op; +{ + op = ck_fun(op); + + op->op_private = 0; +#ifdef USE_LOCALE + if (hints & HINT_LOCALE) + op->op_private |= OPpLOCALE; +#endif + + return op; +} + +OP * +ck_scmp(op) +OP *op; +{ + op->op_private = 0; +#ifdef USE_LOCALE + if (hints & HINT_LOCALE) + op->op_private |= OPpLOCALE; +#endif + + return op; } OP * ck_match(op) OP *op; { - cPMOP->op_pmflags |= PMf_RUNTIME; - cPMOP->op_pmpermflags |= PMf_RUNTIME; + op->op_private |= OPpRUNTIME; return op; } @@ -3745,8 +4399,9 @@ OP *op; op_free(op); return newUNOP(type, 0, scalar(newUNOP(OP_RV2AV, 0, - scalar(newGVOP(OP_GV, 0, - gv_fetchpv((subline ? "_" : "ARGV"), TRUE, SVt_PVAV) ))))); + scalar(newGVOP(OP_GV, 0, subline + ? defgv + : gv_fetchpv("ARGV", TRUE, SVt_PVAV) ))))); } return scalar(modkids(ck_fun(op), type)); } @@ -3755,6 +4410,12 @@ OP * ck_sort(op) OP *op; { + op->op_private = 0; +#ifdef USE_LOCALE + if (hints & HINT_LOCALE) + op->op_private |= OPpLOCALE; +#endif + if (op->op_flags & OPf_STACKED) { OP *kid = cLISTOP->op_first->op_sibling; /* get past pushmark */ OP *k; @@ -3791,6 +4452,7 @@ OP *op; op->op_flags |= OPf_SPECIAL; } } + return op; } @@ -3862,6 +4524,7 @@ OP *op; OP *cvop; char *proto = 0; CV *cv = 0; + GV *namegv = 0; int optional = 0; I32 arg = 0; @@ -3872,19 +4535,21 @@ OP *op; null(cvop); /* disable rv2cv */ tmpop = (SVOP*)((UNOP*)cvop)->op_first; if (tmpop->op_type == OP_GV) { - cv = GvCV(tmpop->op_sv); - if (cv && SvPOK(cv) && !(op->op_private & OPpENTERSUB_AMPER)) - proto = SvPV((SV*)cv,na); + cv = GvCVu(tmpop->op_sv); + if (cv && SvPOK(cv) && !(op->op_private & OPpENTERSUB_AMPER)) { + namegv = CvANON(cv) ? (GV*)tmpop->op_sv : CvGV(cv); + proto = SvPV((SV*)cv, na); + } } } op->op_private |= (hints & HINT_STRICT_REFS); - if (perldb && curstash != debstash) + if (PERLDB_SUB && curstash != debstash) op->op_private |= OPpENTERSUB_DB; while (o != cvop) { if (proto) { switch (*proto) { case '\0': - return too_many_arguments(op, CvNAME(cv)); + return too_many_arguments(op, gv_ename(namegv)); case ';': optional = 1; proto++; @@ -3903,7 +4568,7 @@ OP *op; proto++; arg++; if (o->op_type != OP_REFGEN && o->op_type != OP_UNDEF) - bad_type(arg, "block", CvNAME(cv), o); + bad_type(arg, "block", gv_ename(namegv), o); break; case '*': proto++; @@ -3924,23 +4589,23 @@ OP *op; switch (*proto++) { case '*': if (o->op_type != OP_RV2GV) - bad_type(arg, "symbol", CvNAME(cv), o); + bad_type(arg, "symbol", gv_ename(namegv), o); goto wrapref; case '&': if (o->op_type != OP_RV2CV) - bad_type(arg, "sub", CvNAME(cv), o); + bad_type(arg, "sub", gv_ename(namegv), o); goto wrapref; case '$': if (o->op_type != OP_RV2SV && o->op_type != OP_PADSV) - bad_type(arg, "scalar", CvNAME(cv), o); + bad_type(arg, "scalar", gv_ename(namegv), o); goto wrapref; case '@': if (o->op_type != OP_RV2AV && o->op_type != OP_PADAV) - bad_type(arg, "array", CvNAME(cv), o); + bad_type(arg, "array", gv_ename(namegv), o); goto wrapref; case '%': if (o->op_type != OP_RV2HV && o->op_type != OP_PADHV) - bad_type(arg, "hash", CvNAME(cv), o); + bad_type(arg, "hash", gv_ename(namegv), o); wrapref: { OP* kid = o; @@ -3953,10 +4618,13 @@ OP *op; default: goto oops; } break; + case ' ': + proto++; + continue; default: oops: croak("Malformed prototype for %s: %s", - CvNAME(cv),SvPV((SV*)cv,na)); + gv_ename(namegv), SvPV((SV*)cv, na)); } } else @@ -3965,8 +4633,9 @@ OP *op; prev = o; o = o->op_sibling; } - if (proto && !optional && *proto == '$') - return too_few_arguments(op, CvNAME(cv)); + if (proto && !optional && + (*proto && *proto != '@' && *proto != '%' && *proto != ';')) + return too_few_arguments(op, gv_ename(namegv)); return op; } @@ -4032,9 +4701,9 @@ register OP* o; o->op_seq = op_seqmax++; break; case OP_STUB: - if ((o->op_flags & (OPf_KNOW|OPf_LIST)) != (OPf_KNOW|OPf_LIST)) { + if ((o->op_flags & OPf_WANT) != OPf_WANT_LIST) { o->op_seq = op_seqmax++; - break; /* Scalar stub must produce undef. List stub is noop */ + break; /* Scalar stub must produce undef. List stub is noop */ } goto nothin; case OP_NULL: @@ -4054,7 +4723,7 @@ register OP* o; case OP_GV: if (o->op_next->op_type == OP_RV2SV) { - if (!(o->op_next->op_private & (OPpDEREF_HV|OPpDEREF_AV))) { + if (!(o->op_next->op_private & OPpDEREF)) { null(o->op_next); o->op_private |= o->op_next->op_private & OPpLVAL_INTRO; o->op_next = o->op_next->op_next; @@ -4069,7 +4738,7 @@ register OP* o; (op = pop->op_next) && pop->op_next->op_type == OP_AELEM && !(pop->op_next->op_private & - (OPpDEREF_HV|OPpDEREF_AV|OPpLVAL_INTRO)) && + (OPpLVAL_INTRO|OPpLVAL_DEFER|OPpDEREF)) && (i = SvIV(((SVOP*)pop)->op_sv) - compiling.cop_arybase) <= 255 && i >= 0) @@ -4083,7 +4752,7 @@ register OP* o; o->op_type = OP_AELEMFAST; o->op_ppaddr = ppaddr[OP_AELEMFAST]; o->op_private = (U8)i; - GvAVn((GV*)(((SVOP*)o)->op_sv)); + GvAVn(((GVOP*)o)->op_gv); } } o->op_seq = op_seqmax++; diff --git a/gnu/usr.bin/perl/op.h b/gnu/usr.bin/perl/op.h index 304099bd8ff..d58f825beea 100644 --- a/gnu/usr.bin/perl/op.h +++ b/gnu/usr.bin/perl/op.h @@ -1,6 +1,6 @@ /* op.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -41,11 +41,20 @@ typedef U32 PADOFFSET; U8 op_flags; \ U8 op_private; -#define GIMME (op->op_flags & OPf_KNOW ? op->op_flags & OPf_LIST : dowantarray()) +#define OP_GIMME(op,dfl) \ + (((op)->op_flags & OPf_WANT) == OPf_WANT_VOID ? G_VOID : \ + ((op)->op_flags & OPf_WANT) == OPf_WANT_SCALAR ? G_SCALAR : \ + ((op)->op_flags & OPf_WANT) == OPf_WANT_LIST ? G_ARRAY : \ + dfl) + +#define GIMME_V OP_GIMME(op, block_gimme()) /* Public flags */ -#define OPf_LIST 1 /* Do operator in list context. */ -#define OPf_KNOW 2 /* Context is known. */ + +#define OPf_WANT 3 /* Mask for "want" bits: */ +#define OPf_WANT_VOID 1 /* Want nothing */ +#define OPf_WANT_SCALAR 2 /* Want single value */ +#define OPf_WANT_LIST 3 /* Want list of any length */ #define OPf_KIDS 4 /* There is a firstborn child. */ #define OPf_PARENS 8 /* This operator was parenthesized. */ /* (Or block needs explicit scope entry.) */ @@ -63,6 +72,13 @@ typedef U32 PADOFFSET; /* On flipflop, we saw ... instead of .. */ /* On UNOPs, saw bare parens, e.g. eof(). */ /* On OP_ENTERSUB || OP_NULL, saw a "do". */ + /* On OP_(ENTER|LEAVE)EVAL, don't clear $@ */ + +/* old names; don't use in new code, but don't break them, either */ +#define OPf_LIST 1 +#define OPf_KNOW 2 +#define GIMME \ + (op->op_flags & OPf_KNOW ? op->op_flags & OPf_LIST : dowantarray()) /* Private for lvalues */ #define OPpLVAL_INTRO 128 /* Lvalue must be localized */ @@ -73,6 +89,9 @@ typedef U32 PADOFFSET; /* Private for OP_SASSIGN */ #define OPpASSIGN_BACKWARDS 64 /* Left & right switched. */ +/* Private for OP_MATCH and OP_SUBST{,CONST} */ +#define OPpRUNTIME 64 /* Pattern coming in on the stack */ + /* Private for OP_TRANS */ #define OPpTRANS_SQUASH 16 #define OPpTRANS_DELETE 32 @@ -82,11 +101,16 @@ typedef U32 PADOFFSET; #define OPpREPEAT_DOLIST 64 /* List replication. */ /* Private for OP_ENTERSUB, OP_RV2?V, OP_?ELEM */ - /* (lower bits carry hints) */ -#define OPpENTERSUB_AMPER 8 /* Used & form to call. */ +#define OPpDEREF (32|64) /* Want ref to something: */ +#define OPpDEREF_AV 32 /* Want ref to AV. */ +#define OPpDEREF_HV 64 /* Want ref to HV. */ +#define OPpDEREF_SV (32|64) /* Want ref to SV. */ + /* OP_ENTERSUB only */ #define OPpENTERSUB_DB 16 /* Debug subroutine. */ -#define OPpDEREF_AV 32 /* Want ref to AV. */ -#define OPpDEREF_HV 64 /* Want ref to HV. */ +#define OPpENTERSUB_AMPER 8 /* Used & form to call. */ + /* OP_?ELEM only */ +#define OPpLVAL_DEFER 16 /* Defer creation of array/hash elem */ + /* for OP_RV2?V, lower bits carry hints */ /* Private for OP_CONST */ #define OPpCONST_ENTERED 16 /* Has been entered as symbol. */ @@ -99,8 +123,11 @@ typedef U32 PADOFFSET; /* Private for OP_LIST */ #define OPpLIST_GUESSED 64 /* Guessed that pushmark was needed. */ -/* Private for OP_LEAVE and friends */ -#define OPpLEAVE_VOID 64 /* No need to copy out values. */ +/* Private for OP_DELETE */ +#define OPpSLICE 64 /* Operating on a list of keys */ + +/* Private for OP_SORT, OP_PRTF, OP_SPRINTF, string cmp'n, and case changers */ +#define OPpLOCALE 64 /* Use locale */ struct op { BASEOP @@ -161,12 +188,12 @@ struct pmop { #define PMf_CONST 0x0040 /* subst replacement is constant */ #define PMf_KEEP 0x0080 /* keep 1st runtime pattern forever */ #define PMf_GLOBAL 0x0100 /* pattern had a g modifier */ -#define PMf_RUNTIME 0x0200 /* pattern coming in on the stack */ +#define PMf_CONTINUE 0x0200 /* don't reset pos() if //g fails */ #define PMf_EVAL 0x0400 /* evaluating replacement as expr */ #define PMf_WHITE 0x0800 /* pattern is \s+ */ #define PMf_MULTILINE 0x1000 /* assume multiple lines */ #define PMf_SINGLELINE 0x2000 /* assume single line */ -#define PMf_UNUSED 0x4000 /* (unused) */ +#define PMf_LOCALE 0x4000 /* use locale for character types */ #define PMf_EXTENDED 0x8000 /* chuck embedded whitespace */ struct svop { diff --git a/gnu/usr.bin/perl/opcode.h b/gnu/usr.bin/perl/opcode.h index b13849d8aa3..d962c1dae7f 100644 --- a/gnu/usr.bin/perl/opcode.h +++ b/gnu/usr.bin/perl/opcode.h @@ -212,145 +212,146 @@ typedef enum { OP_PRTF, /* 205 */ OP_PRINT, /* 206 */ OP_SYSOPEN, /* 207 */ - OP_SYSREAD, /* 208 */ - OP_SYSWRITE, /* 209 */ - OP_SEND, /* 210 */ - OP_RECV, /* 211 */ - OP_EOF, /* 212 */ - OP_TELL, /* 213 */ - OP_SEEK, /* 214 */ - OP_TRUNCATE, /* 215 */ - OP_FCNTL, /* 216 */ - OP_IOCTL, /* 217 */ - OP_FLOCK, /* 218 */ - OP_SOCKET, /* 219 */ - OP_SOCKPAIR, /* 220 */ - OP_BIND, /* 221 */ - OP_CONNECT, /* 222 */ - OP_LISTEN, /* 223 */ - OP_ACCEPT, /* 224 */ - OP_SHUTDOWN, /* 225 */ - OP_GSOCKOPT, /* 226 */ - OP_SSOCKOPT, /* 227 */ - OP_GETSOCKNAME, /* 228 */ - OP_GETPEERNAME, /* 229 */ - OP_LSTAT, /* 230 */ - OP_STAT, /* 231 */ - OP_FTRREAD, /* 232 */ - OP_FTRWRITE, /* 233 */ - OP_FTREXEC, /* 234 */ - OP_FTEREAD, /* 235 */ - OP_FTEWRITE, /* 236 */ - OP_FTEEXEC, /* 237 */ - OP_FTIS, /* 238 */ - OP_FTEOWNED, /* 239 */ - OP_FTROWNED, /* 240 */ - OP_FTZERO, /* 241 */ - OP_FTSIZE, /* 242 */ - OP_FTMTIME, /* 243 */ - OP_FTATIME, /* 244 */ - OP_FTCTIME, /* 245 */ - OP_FTSOCK, /* 246 */ - OP_FTCHR, /* 247 */ - OP_FTBLK, /* 248 */ - OP_FTFILE, /* 249 */ - OP_FTDIR, /* 250 */ - OP_FTPIPE, /* 251 */ - OP_FTLINK, /* 252 */ - OP_FTSUID, /* 253 */ - OP_FTSGID, /* 254 */ - OP_FTSVTX, /* 255 */ - OP_FTTTY, /* 256 */ - OP_FTTEXT, /* 257 */ - OP_FTBINARY, /* 258 */ - OP_CHDIR, /* 259 */ - OP_CHOWN, /* 260 */ - OP_CHROOT, /* 261 */ - OP_UNLINK, /* 262 */ - OP_CHMOD, /* 263 */ - OP_UTIME, /* 264 */ - OP_RENAME, /* 265 */ - OP_LINK, /* 266 */ - OP_SYMLINK, /* 267 */ - OP_READLINK, /* 268 */ - OP_MKDIR, /* 269 */ - OP_RMDIR, /* 270 */ - OP_OPEN_DIR, /* 271 */ - OP_READDIR, /* 272 */ - OP_TELLDIR, /* 273 */ - OP_SEEKDIR, /* 274 */ - OP_REWINDDIR, /* 275 */ - OP_CLOSEDIR, /* 276 */ - OP_FORK, /* 277 */ - OP_WAIT, /* 278 */ - OP_WAITPID, /* 279 */ - OP_SYSTEM, /* 280 */ - OP_EXEC, /* 281 */ - OP_KILL, /* 282 */ - OP_GETPPID, /* 283 */ - OP_GETPGRP, /* 284 */ - OP_SETPGRP, /* 285 */ - OP_GETPRIORITY, /* 286 */ - OP_SETPRIORITY, /* 287 */ - OP_TIME, /* 288 */ - OP_TMS, /* 289 */ - OP_LOCALTIME, /* 290 */ - OP_GMTIME, /* 291 */ - OP_ALARM, /* 292 */ - OP_SLEEP, /* 293 */ - OP_SHMGET, /* 294 */ - OP_SHMCTL, /* 295 */ - OP_SHMREAD, /* 296 */ - OP_SHMWRITE, /* 297 */ - OP_MSGGET, /* 298 */ - OP_MSGCTL, /* 299 */ - OP_MSGSND, /* 300 */ - OP_MSGRCV, /* 301 */ - OP_SEMGET, /* 302 */ - OP_SEMCTL, /* 303 */ - OP_SEMOP, /* 304 */ - OP_REQUIRE, /* 305 */ - OP_DOFILE, /* 306 */ - OP_ENTEREVAL, /* 307 */ - OP_LEAVEEVAL, /* 308 */ - OP_ENTERTRY, /* 309 */ - OP_LEAVETRY, /* 310 */ - OP_GHBYNAME, /* 311 */ - OP_GHBYADDR, /* 312 */ - OP_GHOSTENT, /* 313 */ - OP_GNBYNAME, /* 314 */ - OP_GNBYADDR, /* 315 */ - OP_GNETENT, /* 316 */ - OP_GPBYNAME, /* 317 */ - OP_GPBYNUMBER, /* 318 */ - OP_GPROTOENT, /* 319 */ - OP_GSBYNAME, /* 320 */ - OP_GSBYPORT, /* 321 */ - OP_GSERVENT, /* 322 */ - OP_SHOSTENT, /* 323 */ - OP_SNETENT, /* 324 */ - OP_SPROTOENT, /* 325 */ - OP_SSERVENT, /* 326 */ - OP_EHOSTENT, /* 327 */ - OP_ENETENT, /* 328 */ - OP_EPROTOENT, /* 329 */ - OP_ESERVENT, /* 330 */ - OP_GPWNAM, /* 331 */ - OP_GPWUID, /* 332 */ - OP_GPWENT, /* 333 */ - OP_SPWENT, /* 334 */ - OP_EPWENT, /* 335 */ - OP_GGRNAM, /* 336 */ - OP_GGRGID, /* 337 */ - OP_GGRENT, /* 338 */ - OP_SGRENT, /* 339 */ - OP_EGRENT, /* 340 */ - OP_GETLOGIN, /* 341 */ - OP_SYSCALL, /* 342 */ + OP_SYSSEEK, /* 208 */ + OP_SYSREAD, /* 209 */ + OP_SYSWRITE, /* 210 */ + OP_SEND, /* 211 */ + OP_RECV, /* 212 */ + OP_EOF, /* 213 */ + OP_TELL, /* 214 */ + OP_SEEK, /* 215 */ + OP_TRUNCATE, /* 216 */ + OP_FCNTL, /* 217 */ + OP_IOCTL, /* 218 */ + OP_FLOCK, /* 219 */ + OP_SOCKET, /* 220 */ + OP_SOCKPAIR, /* 221 */ + OP_BIND, /* 222 */ + OP_CONNECT, /* 223 */ + OP_LISTEN, /* 224 */ + OP_ACCEPT, /* 225 */ + OP_SHUTDOWN, /* 226 */ + OP_GSOCKOPT, /* 227 */ + OP_SSOCKOPT, /* 228 */ + OP_GETSOCKNAME, /* 229 */ + OP_GETPEERNAME, /* 230 */ + OP_LSTAT, /* 231 */ + OP_STAT, /* 232 */ + OP_FTRREAD, /* 233 */ + OP_FTRWRITE, /* 234 */ + OP_FTREXEC, /* 235 */ + OP_FTEREAD, /* 236 */ + OP_FTEWRITE, /* 237 */ + OP_FTEEXEC, /* 238 */ + OP_FTIS, /* 239 */ + OP_FTEOWNED, /* 240 */ + OP_FTROWNED, /* 241 */ + OP_FTZERO, /* 242 */ + OP_FTSIZE, /* 243 */ + OP_FTMTIME, /* 244 */ + OP_FTATIME, /* 245 */ + OP_FTCTIME, /* 246 */ + OP_FTSOCK, /* 247 */ + OP_FTCHR, /* 248 */ + OP_FTBLK, /* 249 */ + OP_FTFILE, /* 250 */ + OP_FTDIR, /* 251 */ + OP_FTPIPE, /* 252 */ + OP_FTLINK, /* 253 */ + OP_FTSUID, /* 254 */ + OP_FTSGID, /* 255 */ + OP_FTSVTX, /* 256 */ + OP_FTTTY, /* 257 */ + OP_FTTEXT, /* 258 */ + OP_FTBINARY, /* 259 */ + OP_CHDIR, /* 260 */ + OP_CHOWN, /* 261 */ + OP_CHROOT, /* 262 */ + OP_UNLINK, /* 263 */ + OP_CHMOD, /* 264 */ + OP_UTIME, /* 265 */ + OP_RENAME, /* 266 */ + OP_LINK, /* 267 */ + OP_SYMLINK, /* 268 */ + OP_READLINK, /* 269 */ + OP_MKDIR, /* 270 */ + OP_RMDIR, /* 271 */ + OP_OPEN_DIR, /* 272 */ + OP_READDIR, /* 273 */ + OP_TELLDIR, /* 274 */ + OP_SEEKDIR, /* 275 */ + OP_REWINDDIR, /* 276 */ + OP_CLOSEDIR, /* 277 */ + OP_FORK, /* 278 */ + OP_WAIT, /* 279 */ + OP_WAITPID, /* 280 */ + OP_SYSTEM, /* 281 */ + OP_EXEC, /* 282 */ + OP_KILL, /* 283 */ + OP_GETPPID, /* 284 */ + OP_GETPGRP, /* 285 */ + OP_SETPGRP, /* 286 */ + OP_GETPRIORITY, /* 287 */ + OP_SETPRIORITY, /* 288 */ + OP_TIME, /* 289 */ + OP_TMS, /* 290 */ + OP_LOCALTIME, /* 291 */ + OP_GMTIME, /* 292 */ + OP_ALARM, /* 293 */ + OP_SLEEP, /* 294 */ + OP_SHMGET, /* 295 */ + OP_SHMCTL, /* 296 */ + OP_SHMREAD, /* 297 */ + OP_SHMWRITE, /* 298 */ + OP_MSGGET, /* 299 */ + OP_MSGCTL, /* 300 */ + OP_MSGSND, /* 301 */ + OP_MSGRCV, /* 302 */ + OP_SEMGET, /* 303 */ + OP_SEMCTL, /* 304 */ + OP_SEMOP, /* 305 */ + OP_REQUIRE, /* 306 */ + OP_DOFILE, /* 307 */ + OP_ENTEREVAL, /* 308 */ + OP_LEAVEEVAL, /* 309 */ + OP_ENTERTRY, /* 310 */ + OP_LEAVETRY, /* 311 */ + OP_GHBYNAME, /* 312 */ + OP_GHBYADDR, /* 313 */ + OP_GHOSTENT, /* 314 */ + OP_GNBYNAME, /* 315 */ + OP_GNBYADDR, /* 316 */ + OP_GNETENT, /* 317 */ + OP_GPBYNAME, /* 318 */ + OP_GPBYNUMBER, /* 319 */ + OP_GPROTOENT, /* 320 */ + OP_GSBYNAME, /* 321 */ + OP_GSBYPORT, /* 322 */ + OP_GSERVENT, /* 323 */ + OP_SHOSTENT, /* 324 */ + OP_SNETENT, /* 325 */ + OP_SPROTOENT, /* 326 */ + OP_SSERVENT, /* 327 */ + OP_EHOSTENT, /* 328 */ + OP_ENETENT, /* 329 */ + OP_EPROTOENT, /* 330 */ + OP_ESERVENT, /* 331 */ + OP_GPWNAM, /* 332 */ + OP_GPWUID, /* 333 */ + OP_GPWENT, /* 334 */ + OP_SPWENT, /* 335 */ + OP_EPWENT, /* 336 */ + OP_GGRNAM, /* 337 */ + OP_GGRGID, /* 338 */ + OP_GGRENT, /* 339 */ + OP_SGRENT, /* 340 */ + OP_EGRENT, /* 341 */ + OP_GETLOGIN, /* 342 */ + OP_SYSCALL, /* 343 */ OP_max } opcode; -#define MAXO 343 +#define MAXO 344 #ifndef DOINIT EXT char *op_name[]; @@ -564,6 +565,7 @@ EXT char *op_name[] = { "prtf", "print", "sysopen", + "sysseek", "sysread", "syswrite", "send", @@ -838,9 +840,9 @@ EXT char *op_desc[] = { "keys", "delete", "exists operator", - "associative array deref", - "associative array elem", - "associative array slice", + "hash deref", + "hash elem", + "hash slice", "unpack", "pack", "split", @@ -914,6 +916,7 @@ EXT char *op_desc[] = { "printf", "print", "sysopen", + "sysseek", "sysread", "syswrite", "send", @@ -1052,14 +1055,17 @@ EXT char *op_desc[] = { }; #endif +OP * ck_anoncode _((OP* op)); +OP * ck_bitop _((OP* op)); OP * ck_concat _((OP* op)); OP * ck_delete _((OP* op)); OP * ck_eof _((OP* op)); OP * ck_eval _((OP* op)); OP * ck_exec _((OP* op)); -OP * ck_formline _((OP* op)); +OP * ck_exists _((OP* op)); OP * ck_ftst _((OP* op)); OP * ck_fun _((OP* op)); +OP * ck_fun_locale _((OP* op)); OP * ck_glob _((OP* op)); OP * ck_grep _((OP* op)); OP * ck_index _((OP* op)); @@ -1072,6 +1078,7 @@ OP * ck_repeat _((OP* op)); OP * ck_require _((OP* op)); OP * ck_rfun _((OP* op)); OP * ck_rvconst _((OP* op)); +OP * ck_scmp _((OP* op)); OP * ck_select _((OP* op)); OP * ck_shift _((OP* op)); OP * ck_sort _((OP* op)); @@ -1289,6 +1296,7 @@ OP * pp_leavewrite _((void)); OP * pp_prtf _((void)); OP * pp_print _((void)); OP * pp_sysopen _((void)); +OP * pp_sysseek _((void)); OP * pp_sysread _((void)); OP * pp_syswrite _((void)); OP * pp_send _((void)); @@ -1637,6 +1645,7 @@ EXT OP * (*ppaddr[])() = { pp_prtf, pp_print, pp_sysopen, + pp_sysseek, pp_sysread, pp_syswrite, pp_send, @@ -1776,9 +1785,9 @@ EXT OP * (*ppaddr[])() = { #endif #ifndef DOINIT -EXT OP * (*check[])(); +EXT OP * (*check[]) _((OP *op)); #else -EXT OP * (*check[])() = { +EXT OP * (*check[]) _((OP *op)) = { ck_null, /* null */ ck_null, /* stub */ ck_fun, /* scalar */ @@ -1797,7 +1806,7 @@ EXT OP * (*check[])() = { ck_rvconst, /* rv2sv */ ck_null, /* av2arylen */ ck_rvconst, /* rv2cv */ - ck_null, /* anoncode */ + ck_anoncode, /* anoncode */ ck_null, /* prototype */ ck_spair, /* refgen */ ck_null, /* srefgen */ @@ -1845,8 +1854,8 @@ EXT OP * (*check[])() = { ck_null, /* i_subtract */ ck_concat, /* concat */ ck_fun, /* stringify */ - ck_null, /* left_shift */ - ck_null, /* right_shift */ + ck_bitop, /* left_shift */ + ck_bitop, /* right_shift */ ck_null, /* lt */ ck_null, /* i_lt */ ck_null, /* gt */ @@ -1861,20 +1870,20 @@ EXT OP * (*check[])() = { ck_null, /* i_ne */ ck_null, /* ncmp */ ck_null, /* i_ncmp */ - ck_null, /* slt */ - ck_null, /* sgt */ - ck_null, /* sle */ - ck_null, /* sge */ + ck_scmp, /* slt */ + ck_scmp, /* sgt */ + ck_scmp, /* sle */ + ck_scmp, /* sge */ ck_null, /* seq */ ck_null, /* sne */ - ck_null, /* scmp */ - ck_null, /* bit_and */ - ck_null, /* bit_xor */ - ck_null, /* bit_or */ + ck_scmp, /* scmp */ + ck_bitop, /* bit_and */ + ck_bitop, /* bit_xor */ + ck_bitop, /* bit_or */ ck_null, /* negate */ ck_null, /* i_negate */ ck_null, /* not */ - ck_null, /* complement */ + ck_bitop, /* complement */ ck_fun, /* atan2 */ ck_fun, /* sin */ ck_fun, /* cos */ @@ -1892,15 +1901,15 @@ EXT OP * (*check[])() = { ck_fun, /* vec */ ck_index, /* index */ ck_index, /* rindex */ - ck_fun, /* sprintf */ - ck_formline, /* formline */ + ck_fun_locale, /* sprintf */ + ck_fun, /* formline */ ck_fun, /* ord */ ck_fun, /* chr */ ck_fun, /* crypt */ - ck_fun, /* ucfirst */ - ck_fun, /* lcfirst */ - ck_fun, /* uc */ - ck_fun, /* lc */ + ck_fun_locale, /* ucfirst */ + ck_fun_locale, /* lcfirst */ + ck_fun_locale, /* uc */ + ck_fun_locale, /* lc */ ck_fun, /* quotemeta */ ck_rvconst, /* rv2av */ ck_null, /* aelemfast */ @@ -1910,7 +1919,7 @@ EXT OP * (*check[])() = { ck_fun, /* values */ ck_fun, /* keys */ ck_delete, /* delete */ - ck_delete, /* exists */ + ck_exists, /* exists */ ck_rvconst, /* rv2hv */ ck_null, /* helem */ ck_null, /* hslice */ @@ -1987,6 +1996,7 @@ EXT OP * (*check[])() = { ck_listiob, /* prtf */ ck_listiob, /* print */ ck_fun, /* sysopen */ + ck_fun, /* sysseek */ ck_fun, /* sysread */ ck_fun, /* syswrite */ ck_fun, /* send */ @@ -2154,7 +2164,7 @@ EXT U32 opargs[] = { 0x0000098c, /* ref */ 0x00009104, /* bless */ 0x00000008, /* backtick */ - 0x00001108, /* glob */ + 0x00009908, /* glob */ 0x00000008, /* readline */ 0x00000008, /* rcatline */ 0x00000104, /* regcmaybe */ @@ -2195,8 +2205,8 @@ EXT U32 opargs[] = { 0x0000111e, /* i_subtract */ 0x0000110e, /* concat */ 0x0000010e, /* stringify */ - 0x0000111e, /* left_shift */ - 0x0000111e, /* right_shift */ + 0x0000110e, /* left_shift */ + 0x0000110e, /* right_shift */ 0x00001136, /* lt */ 0x00001116, /* i_lt */ 0x00001136, /* gt */ @@ -2234,24 +2244,24 @@ EXT U32 opargs[] = { 0x0000098e, /* log */ 0x0000098e, /* sqrt */ 0x0000098e, /* int */ - 0x0000099c, /* hex */ - 0x0000099c, /* oct */ + 0x0000098e, /* hex */ + 0x0000098e, /* oct */ 0x0000098e, /* abs */ 0x0000099c, /* length */ 0x0009110c, /* substr */ 0x0001111c, /* vec */ 0x0009111c, /* index */ 0x0009111c, /* rindex */ - 0x0000210d, /* sprintf */ + 0x0000210f, /* sprintf */ 0x00002105, /* formline */ 0x0000099e, /* ord */ 0x0000098e, /* chr */ 0x0000110e, /* crypt */ - 0x0000010e, /* ucfirst */ - 0x0000010e, /* lcfirst */ - 0x0000010e, /* uc */ - 0x0000010e, /* lc */ - 0x0000010e, /* quotemeta */ + 0x0000098e, /* ucfirst */ + 0x0000098e, /* lcfirst */ + 0x0000098e, /* uc */ + 0x0000098e, /* lc */ + 0x0000098e, /* quotemeta */ 0x00000048, /* rv2av */ 0x00001304, /* aelemfast */ 0x00001304, /* aelem */ @@ -2259,7 +2269,7 @@ EXT U32 opargs[] = { 0x00000408, /* each */ 0x00000408, /* values */ 0x00000408, /* keys */ - 0x00000104, /* delete */ + 0x00000100, /* delete */ 0x00000114, /* exists */ 0x00000048, /* rv2hv */ 0x00001404, /* helem */ @@ -2337,6 +2347,7 @@ EXT U32 opargs[] = { 0x00002e15, /* prtf */ 0x00002e15, /* print */ 0x00911604, /* sysopen */ + 0x00011604, /* sysseek */ 0x0091761d, /* sysread */ 0x0091161d, /* syswrite */ 0x0091161d, /* send */ diff --git a/gnu/usr.bin/perl/opcode.pl b/gnu/usr.bin/perl/opcode.pl index fddf6462a94..a5659333726 100644 --- a/gnu/usr.bin/perl/opcode.pl +++ b/gnu/usr.bin/perl/opcode.pl @@ -1,5 +1,6 @@ #!/usr/bin/perl +unlink "opcode.h"; open(OC, ">opcode.h") || die "Can't create opcode.h: $!\n"; select OC; @@ -114,9 +115,9 @@ END print <<END; #ifndef DOINIT -EXT OP * (*check[])(); +EXT OP * (*check[]) _((OP *op)); #else -EXT OP * (*check[])() = { +EXT OP * (*check[]) _((OP *op)) = { END for (@ops) { @@ -213,7 +214,7 @@ rv2gv ref-to-glob cast ck_rvconst ds rv2sv scalar deref ck_rvconst ds av2arylen array length ck_null is rv2cv subroutine deref ck_rvconst d -anoncode anonymous subroutine ck_null 0 +anoncode anonymous subroutine ck_anoncode 0 prototype subroutine prototype ck_null s S refgen reference constructor ck_spair m L srefgen scalar ref constructor ck_null fs S @@ -223,7 +224,8 @@ bless bless ck_fun s S S? # Pushy I/O. backtick backticks ck_null t -glob glob ck_glob t S S +# glob defaults its first arg to $_ +glob glob ck_glob t S? S? readline <HANDLE> ck_null t rcatline append I/O operator ck_null t @@ -278,8 +280,8 @@ i_subtract integer subtraction ck_null ifst S S concat concatenation ck_concat fst S S stringify string ck_fun fst S -left_shift left bitshift ck_null ifst S S -right_shift right bitshift ck_null ifst S S +left_shift left bitshift ck_bitop fst S S +right_shift right bitshift ck_bitop fst S S lt numeric lt ck_null Iifs S S i_lt integer lt ck_null ifs S S @@ -296,22 +298,22 @@ i_ne integer ne ck_null ifs S S ncmp spaceship operator ck_null Iifst S S i_ncmp integer spaceship ck_null ifst S S -slt string lt ck_null ifs S S -sgt string gt ck_null ifs S S -sle string le ck_null ifs S S -sge string ge ck_null ifs S S +slt string lt ck_scmp ifs S S +sgt string gt ck_scmp ifs S S +sle string le ck_scmp ifs S S +sge string ge ck_scmp ifs S S seq string eq ck_null ifs S S sne string ne ck_null ifs S S -scmp string comparison ck_null ifst S S +scmp string comparison ck_scmp ifst S S -bit_and bitwise and ck_null fst S S -bit_xor bitwise xor ck_null fst S S -bit_or bitwise or ck_null fst S S +bit_and bitwise and ck_bitop fst S S +bit_xor bitwise xor ck_bitop fst S S +bit_or bitwise or ck_bitop fst S S negate negate ck_null Ifst S i_negate integer negate ck_null ifst S not not ck_null ifs S -complement 1's complement ck_null fst S +complement 1's complement ck_bitop fst S # High falutin' math. @@ -324,9 +326,11 @@ exp exp ck_fun fstu S? log log ck_fun fstu S? sqrt sqrt ck_fun fstu S? +# Lowbrow math. + int int ck_fun fstu S? -hex hex ck_fun istu S? -oct oct ck_fun istu S? +hex hex ck_fun fstu S? +oct oct ck_fun fstu S? abs abs ck_fun fstu S? # String stuff. @@ -338,16 +342,16 @@ vec vec ck_fun ist S S S index index ck_index ist S S S? rindex rindex ck_index ist S S S? -sprintf sprintf ck_fun mst S L -formline formline ck_formline ms S L +sprintf sprintf ck_fun_locale mfst S L +formline formline ck_fun ms S L ord ord ck_fun ifstu S? chr chr ck_fun fstu S? crypt crypt ck_fun fst S S -ucfirst upper case first ck_fun fst S -lcfirst lower case first ck_fun fst S -uc upper case ck_fun fst S -lc lower case ck_fun fst S -quotemeta quote metachars ck_fun fst S +ucfirst upper case first ck_fun_locale fstu S? +lcfirst lower case first ck_fun_locale fstu S? +uc upper case ck_fun_locale fstu S? +lc lower case ck_fun_locale fstu S? +quotemeta quote metachars ck_fun fstu S? # Arrays. @@ -356,16 +360,16 @@ aelemfast known array element ck_null s A S aelem array element ck_null s A S aslice array slice ck_null m A L -# Associative arrays. +# Hashes. each each ck_fun t H values values ck_fun t H keys keys ck_fun t H -delete delete ck_delete s S -exists exists operator ck_delete is S -rv2hv associative array deref ck_rvconst dt -helem associative array elem ck_null s H S -hslice associative array slice ck_null m H L +delete delete ck_delete 0 S +exists exists operator ck_exists is S +rv2hv hash deref ck_rvconst dt +helem hash elem ck_null s H S +hslice hash slice ck_null m H L # Explosives and implosives. @@ -468,6 +472,7 @@ prtf printf ck_listiob ims F? L print print ck_listiob ims F? L sysopen sysopen ck_fun s F S S S? +sysseek sysseek ck_fun s F S S sysread sysread ck_fun imst F R S S? syswrite syswrite ck_fun imst F S S S? @@ -477,6 +482,7 @@ recv recv ck_fun imst F R S S eof eof ck_eof is F? tell tell ck_fun st F? seek seek ck_fun s F S S +# truncate really behaves as if it had both "S S" and "F S" truncate truncate ck_trunc is S S fcntl fcntl ck_fun st F S S diff --git a/gnu/usr.bin/perl/patchlevel.h b/gnu/usr.bin/perl/patchlevel.h index 5d4b324d7e1..2adaed5f721 100644 --- a/gnu/usr.bin/perl/patchlevel.h +++ b/gnu/usr.bin/perl/patchlevel.h @@ -1,9 +1,9 @@ -#define PATCHLEVEL 3 -#define SUBVERSION 0 +#define PATCHLEVEL 4 +#define SUBVERSION 4 /* local_patches -- list of locally applied less-than-subversion patches. - If you're distributing such a patch, please give it a name and a + If you're distributing such a patch, please give it a tag name and a one-line description, placed just before the last NULL in the array below. If your patch fixes a bug in the perlbug database, please mention the bugid. If your patch *IS* dependent on a prior patch, @@ -17,7 +17,7 @@ --- patchlevel.h <date here> *** 38,43 *** --- 38,44 --- - ,"FOO1235 - some patch" + ,"MAINT_TRIAL_1 - 5.00x_0x maintenance release trial 1" ,"BAR3141 - another patch" ,"BAZ2718 - and another patch" + ,"MINE001 - my new patch" @@ -36,10 +36,12 @@ This will prevent patch from choking if someone has previously applied different patches than you. */ +/* The following line and terminating '};' are read by perlbug.PL. Don't alter. */ static char *local_patches[] = { NULL ,NULL }; -#define LOCAL_PATCH_COUNT \ +/* Initial space prevents this variable from being inserted in config.sh */ +# define LOCAL_PATCH_COUNT \ (sizeof(local_patches)/sizeof(local_patches[0])-2) diff --git a/gnu/usr.bin/perl/perl.c b/gnu/usr.bin/perl/perl.c index a4be9745685..f9cc65302a8 100644 --- a/gnu/usr.bin/perl/perl.c +++ b/gnu/usr.bin/perl/perl.c @@ -1,6 +1,6 @@ /* perl.c * - * Copyright (c) 1987-1996 Larry Wall + * Copyright (c) 1987-1997 Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -15,13 +15,16 @@ #include "perl.h" #include "patchlevel.h" -/* Omit -- it causes too much grief on mixed systems. +/* XXX If this causes problems, set i_unistd=undef in the hint file. */ #ifdef I_UNISTD #include <unistd.h> #endif -*/ -dEXT char rcsid[] = "perl.c\nPatch level: ###\n"; +#if !defined(STANDARD_C) && !defined(HAS_GETENV_PROTOTYPE) +char *getenv _((char *)); /* Usually in <stdlib.h> */ +#endif + +dEXTCONST char rcsid[] = "perl.c\nPatch level: ###\n"; #ifdef IAMSUID #ifndef DOSUID @@ -35,8 +38,33 @@ dEXT char rcsid[] = "perl.c\nPatch level: ###\n"; #endif #endif +#define I_REINIT \ + STMT_START { \ + chopset = " \n-"; \ + copline = NOLINE; \ + curcop = &compiling; \ + curcopdb = NULL; \ + cxstack_ix = -1; \ + cxstack_max = 128; \ + dbargs = 0; \ + dlmax = 128; \ + laststatval = -1; \ + laststype = OP_STAT; \ + maxscream = -1; \ + maxsysfd = MAXSYSFD; \ + statname = Nullsv; \ + tmps_floor = -1; \ + tmps_ix = -1; \ + op_mask = NULL; \ + dlmax = 128; \ + laststatval = -1; \ + laststype = OP_STAT; \ + mess_sv = Nullsv; \ + } STMT_END + static void find_beginning _((void)); -static void incpush _((char *)); +static void forbid_setid _((char *)); +static void incpush _((char *, int)); static void init_ids _((void)); static void init_debugger _((void)); static void init_lexer _((void)); @@ -45,6 +73,8 @@ static void init_perllib _((void)); static void init_postdump_symbols _((int, char **, char **)); static void init_predump_symbols _((void)); static void init_stacks _((void)); +static void my_exit_jump _((void)) __attribute__((noreturn)); +static void nuke_stacks _((void)); static void open_script _((char *, bool, SV *)); static void usage _((char *)); static void validate_suid _((char *, char*)); @@ -77,19 +107,23 @@ register PerlInterpreter *sv_interp; linestr = NEWSV(65,80); sv_upgrade(linestr,SVt_PVIV); - SvREADONLY_on(&sv_undef); + if (!SvREADONLY(&sv_undef)) { + SvREADONLY_on(&sv_undef); - sv_setpv(&sv_no,No); - SvNV(&sv_no); - SvREADONLY_on(&sv_no); + sv_setpv(&sv_no,No); + SvNV(&sv_no); + SvREADONLY_on(&sv_no); - sv_setpv(&sv_yes,Yes); - SvNV(&sv_yes); - SvREADONLY_on(&sv_yes); + sv_setpv(&sv_yes,Yes); + SvNV(&sv_yes); + SvREADONLY_on(&sv_yes); + } nrs = newSVpv("\n", 1); rs = SvREFCNT_inc(nrs); + pidstatus = newHV(); + #ifdef MSDOS /* * There is no way we can refer to them from Perl so close them to save @@ -102,35 +136,39 @@ register PerlInterpreter *sv_interp; } #ifdef MULTIPLICITY - chopset = " \n-"; - copline = NOLINE; - curcop = &compiling; - dbargs = 0; - dlmax = 128; - laststatval = -1; - laststype = OP_STAT; - maxscream = -1; - maxsysfd = MAXSYSFD; - rsfp = Nullfp; - statname = Nullsv; - tmps_floor = -1; + I_REINIT; + perl_destruct_level = 1; +#else + if(perl_destruct_level > 0) + I_REINIT; #endif init_ids(); + lex_state = LEX_NOTPARSING; + start_env.je_prev = NULL; + start_env.je_ret = -1; + start_env.je_mustcatch = TRUE; + top_env = &start_env; + STATUS_ALL_SUCCESS; + + SET_NUMERIC_STANDARD(); #if defined(SUBVERSION) && SUBVERSION > 0 - sprintf(patchlevel, "%7.5f", 5.0 + (PATCHLEVEL / 1000.0) - + (SUBVERSION / 100000.0)); + sprintf(patchlevel, "%7.5f", (double) 5 + + ((double) PATCHLEVEL / (double) 1000) + + ((double) SUBVERSION / (double) 100000)); #else - sprintf(patchlevel, "%5.3f", 5.0 + (PATCHLEVEL / 1000.0)); + sprintf(patchlevel, "%5.3f", (double) 5 + + ((double) PATCHLEVEL / (double) 1000)); #endif #if defined(LOCAL_PATCH_COUNT) - Ilocalpatches = local_patches; /* For possible -v */ + localpatches = local_patches; /* For possible -v */ #endif + PerlIO_init(); /* Hook to IO system */ + fdpid = newAV(); /* for remembering popen pids by fd */ - pidstatus = newHV();/* for remembering status of dead pids */ init_stacks(); ENTER; @@ -151,22 +189,29 @@ register PerlInterpreter *sv_interp; #ifdef DEBUGGING { char *s; - if (s = getenv("PERL_DESTRUCT_LEVEL")) - destruct_level = atoi(s); + if (s = getenv("PERL_DESTRUCT_LEVEL")) { + int i = atoi(s); + if (destruct_level < i) + destruct_level = i; + } } #endif LEAVE; FREETMPS; - if (sv_objcount) { - /* We must account for everything. First the syntax tree. */ - if (main_root) { - curpad = AvARRAY(comppad); - op_free(main_root); - main_root = 0; - } + /* We must account for everything. */ + + /* Destroy the main CV and syntax tree */ + if (main_root) { + curpad = AvARRAY(comppad); + op_free(main_root); + main_root = Nullop; } + main_start = Nullop; + SvREFCNT_dec(main_cv); + main_cv = Nullcv; + if (sv_objcount) { /* * Try to destruct global references. We do this first so that the @@ -178,6 +223,14 @@ register PerlInterpreter *sv_interp; sv_clean_objs(); } + /* unhook hooks which will soon be, or use, destroyed data */ + SvREFCNT_dec(warnhook); + warnhook = Nullsv; + SvREFCNT_dec(diehook); + diehook = Nullsv; + SvREFCNT_dec(parsehook); + parsehook = Nullsv; + if (destruct_level == 0){ DEBUG_P(debprofdump()); @@ -185,8 +238,126 @@ register PerlInterpreter *sv_interp; /* The exit() function will do everything that needs doing. */ return; } - + + /* loosen bonds of global variables */ + + if(rsfp) { + (void)PerlIO_close(rsfp); + rsfp = Nullfp; + } + + /* Filters for program text */ + SvREFCNT_dec(rsfp_filters); + rsfp_filters = Nullav; + + /* switches */ + preprocess = FALSE; + minus_n = FALSE; + minus_p = FALSE; + minus_l = FALSE; + minus_a = FALSE; + minus_F = FALSE; + doswitches = FALSE; + dowarn = FALSE; + doextract = FALSE; + sawampersand = FALSE; /* must save all match strings */ + sawstudy = FALSE; /* do fbm_instr on all strings */ + sawvec = FALSE; + unsafe = FALSE; + + Safefree(inplace); + inplace = Nullch; + + Safefree(e_tmpname); + e_tmpname = Nullch; + + if (e_fp) { + PerlIO_close(e_fp); + e_fp = Nullfp; + } + + /* magical thingies */ + + Safefree(ofs); /* $, */ + ofs = Nullch; + + Safefree(ors); /* $\ */ + ors = Nullch; + + SvREFCNT_dec(nrs); /* $\ helper */ + nrs = Nullsv; + + multiline = 0; /* $* */ + + SvREFCNT_dec(statname); + statname = Nullsv; + statgv = Nullgv; + + /* defgv, aka *_ should be taken care of elsewhere */ + +#if 0 /* just about all regexp stuff, seems to be ok */ + + /* shortcuts to regexp stuff */ + leftgv = Nullgv; + ampergv = Nullgv; + + SAVEFREEOP(curpm); + SAVEFREEOP(oldlastpm); /* for saving regexp context during debugger */ + + regprecomp = NULL; /* uncompiled string. */ + regparse = NULL; /* Input-scan pointer. */ + regxend = NULL; /* End of input for compile */ + regnpar = 0; /* () count. */ + regcode = NULL; /* Code-emit pointer; ®dummy = don't. */ + regsize = 0; /* Code size. */ + regnaughty = 0; /* How bad is this pattern? */ + regsawback = 0; /* Did we see \1, ...? */ + + reginput = NULL; /* String-input pointer. */ + regbol = NULL; /* Beginning of input, for ^ check. */ + regeol = NULL; /* End of input, for $ check. */ + regstartp = (char **)NULL; /* Pointer to startp array. */ + regendp = (char **)NULL; /* Ditto for endp. */ + reglastparen = 0; /* Similarly for lastparen. */ + regtill = NULL; /* How far we are required to go. */ + regflags = 0; /* are we folding, multilining? */ + regprev = (char)NULL; /* char before regbol, \n if none */ + +#endif /* if 0 */ + + /* clean up after study() */ + SvREFCNT_dec(lastscream); + lastscream = Nullsv; + Safefree(screamfirst); + screamfirst = 0; + Safefree(screamnext); + screamnext = 0; + + /* startup and shutdown function lists */ + SvREFCNT_dec(beginav); + SvREFCNT_dec(endav); + beginav = Nullav; + endav = Nullav; + + /* temp stack during pp_sort() */ + SvREFCNT_dec(sortstack); + sortstack = Nullav; + + /* shortcuts just get cleared */ + envgv = Nullgv; + siggv = Nullgv; + incgv = Nullgv; + errgv = Nullgv; + argvgv = Nullgv; + argvoutgv = Nullgv; + stdingv = Nullgv; + last_in_gv = Nullgv; + + /* reset so print() ends up where we expect */ + setdefout(Nullgv); + /* Prepare to destruct main symbol table. */ + hv = defstash; defstash = 0; SvREFCNT_dec(hv); @@ -194,26 +365,84 @@ register PerlInterpreter *sv_interp; FREETMPS; if (destruct_level >= 2) { if (scopestack_ix != 0) - warn("Unbalanced scopes: %d more ENTERs than LEAVEs\n", scopestack_ix); + warn("Unbalanced scopes: %ld more ENTERs than LEAVEs\n", + (long)scopestack_ix); if (savestack_ix != 0) - warn("Unbalanced saves: %d more saves than restores\n", savestack_ix); + warn("Unbalanced saves: %ld more saves than restores\n", + (long)savestack_ix); if (tmps_floor != -1) - warn("Unbalanced tmps: %d more allocs than frees\n", tmps_floor + 1); + warn("Unbalanced tmps: %ld more allocs than frees\n", + (long)tmps_floor + 1); if (cxstack_ix != -1) - warn("Unbalanced context: %d more PUSHes than POPs\n", cxstack_ix + 1); + warn("Unbalanced context: %ld more PUSHes than POPs\n", + (long)cxstack_ix + 1); } /* Now absolutely destruct everything, somehow or other, loops or no. */ last_sv_count = 0; + SvFLAGS(strtab) |= SVTYPEMASK; /* don't clean out strtab now */ while (sv_count != 0 && sv_count != last_sv_count) { last_sv_count = sv_count; sv_clean_all(); } + SvFLAGS(strtab) &= ~SVTYPEMASK; + SvFLAGS(strtab) |= SVt_PVHV; + + /* Destruct the global string table. */ + { + /* Yell and reset the HeVAL() slots that are still holding refcounts, + * so that sv_free() won't fail on them. + */ + I32 riter; + I32 max; + HE *hent; + HE **array; + + riter = 0; + max = HvMAX(strtab); + array = HvARRAY(strtab); + hent = array[0]; + for (;;) { + if (hent) { + warn("Unbalanced string table refcount: (%d) for \"%s\"", + HeVAL(hent) - Nullsv, HeKEY(hent)); + HeVAL(hent) = Nullsv; + hent = HeNEXT(hent); + } + if (!hent) { + if (++riter > max) + break; + hent = array[riter]; + } + } + } + SvREFCNT_dec(strtab); + if (sv_count != 0) - warn("Scalars leaked: %d\n", sv_count); + warn("Scalars leaked: %ld\n", (long)sv_count); + sv_free_arenas(); + + /* No SVs have survived, need to clean out */ + linestr = NULL; + pidstatus = Nullhv; + if (origfilename) + Safefree(origfilename); + nuke_stacks(); + hints = 0; /* Reset hints. Should hints be per-interpreter ? */ DEBUG_P(debprofdump()); + + /* As the absolutely last thing, free the non-arena SV for mess() */ + + if (mess_sv) { + /* we know that type >= SVt_PV */ + SvOOK_off(mess_sv); + Safefree(SvPVX(mess_sv)); + Safefree(SvANY(mess_sv)); + Safefree(mess_sv); + mess_sv = Nullsv; + } } void @@ -224,9 +453,6 @@ PerlInterpreter *sv_interp; return; Safefree(sv_interp); } -#if !defined(STANDARD_C) && !defined(HAS_GETENV_PROTOTYPE) -char *getenv _((char *)); /* Usually in <stdlib.h> */ -#endif int perl_parse(sv_interp, xsinit, argc, argv, env) @@ -241,7 +467,10 @@ char **env; char *scriptname = NULL; VOL bool dosearch = FALSE; char *validarg = ""; + I32 oldscope; AV* comppadlist; + dJMPENV; + int ret; #ifdef SETUID_SCRIPTS_ARE_SECURE_NOW #ifdef IAMSUID @@ -254,6 +483,11 @@ setuid perl scripts securely.\n"); if (!(curinterp = sv_interp)) return 255; +#if defined(NeXT) && defined(__DYNAMIC__) + _dyld_lookup_and_bind + ("__environ", (unsigned long *) &environ_pointer, NULL); +#endif /* environ */ + origargv = argv; origargc = argc; #ifndef VMS /* VMS doesn't have environ array */ @@ -273,24 +507,36 @@ setuid perl scripts securely.\n"); return 0; } - if (main_root) + if (main_root) { + curpad = AvARRAY(comppad); op_free(main_root); - main_root = 0; + main_root = Nullop; + } + main_start = Nullop; + SvREFCNT_dec(main_cv); + main_cv = Nullcv; - switch (Sigsetjmp(top_env,1)) { + time(&basetime); + oldscope = scopestack_ix; + + JMPENV_PUSH(ret); + switch (ret) { case 1: -#ifdef VMS - statusvalue = 255; -#else - statusvalue = 1; -#endif + STATUS_ALL_FAILURE; + /* FALL THROUGH */ case 2: + /* my_exit() was called */ + while (scopestack_ix > oldscope) + LEAVE; + FREETMPS; curstash = defstash; if (endav) - calllist(endav); - return(statusvalue); /* my_exit() was called */ + call_list(oldscope, endav); + JMPENV_POP; + return STATUS_NATIVE_EXPORT; case 3: - fprintf(stderr, "panic: top_env\n"); + JMPENV_POP; + PerlIO_printf(PerlIO_stderr(), "panic: top_env\n"); return 1; } @@ -298,6 +544,7 @@ setuid perl scripts securely.\n"); sv = newSVpv("",0); /* first used for -I flags */ SAVEFREESV(sv); init_main_stash(); + for (argc--,argv++; argc > 0; argc--,argv++) { if (argv[0][0] != '-' || !argv[0][1]) break; @@ -324,7 +571,6 @@ setuid perl scripts securely.\n"); case 'n': case 'p': case 's': - case 'T': case 'u': case 'U': case 'v': @@ -333,6 +579,11 @@ setuid perl scripts securely.\n"); goto reswitch; break; + case 'T': + tainting = TRUE; + s++; + goto reswitch; + case 'e': if (euid != uid || egid != gid) croak("No -e allowed in setuid scripts"); @@ -343,40 +594,47 @@ setuid perl scripts securely.\n"); fd = mkstemp(e_tmpname); if (fd == -1) croak("Can't mkstemp()"); - e_fp = fdopen(fd,"w"); + e_fp = PerlIO_fdopen(fd,"w"); if (!e_fp) { - close(fd); + (void)close(fd); croak("Cannot open temporary file"); } } - if (argv[1]) { - fputs(argv[1],e_fp); + if (*++s) + PerlIO_puts(e_fp,s); + else if (argv[1]) { + PerlIO_puts(e_fp,argv[1]); argc--,argv++; } - (void)putc('\n', e_fp); + else + croak("No code specified for -e"); + (void)PerlIO_putc(e_fp,'\n'); break; - case 'I': - taint_not("-I"); - sv_catpv(sv,"-"); - sv_catpv(sv,s); - sv_catpv(sv," "); - if (*++s) { - av_push(GvAVn(incgv),newSVpv(s,0)); - } - else if (argv[1]) { - av_push(GvAVn(incgv),newSVpv(argv[1],0)); - sv_catpv(sv,argv[1]); + case 'I': /* -I handled both here and in moreswitches() */ + forbid_setid("-I"); + if (!*++s && (s=argv[1]) != Nullch) { argc--,argv++; - sv_catpv(sv," "); } + while (s && isSPACE(*s)) + ++s; + if (s && *s) { + char *e, *p; + for (e = s; *e && !isSPACE(*e); e++) ; + p = savepvn(s, e-s); + incpush(p, TRUE); + sv_catpv(sv,"-I"); + sv_catpv(sv,p); + sv_catpv(sv," "); + Safefree(p); + } /* XXX else croak? */ break; case 'P': - taint_not("-P"); + forbid_setid("-P"); preprocess = TRUE; s++; goto reswitch; case 'S': - taint_not("-S"); + forbid_setid("-S"); dosearch = TRUE; s++; goto reswitch; @@ -385,7 +643,48 @@ setuid perl scripts securely.\n"); preambleav = newAV(); av_push(preambleav, newSVpv("use Config qw(myconfig config_vars)",0)); if (*++s != ':') { - Sv = newSVpv("print myconfig(),'@INC: '.\"@INC\\n\"",0); + Sv = newSVpv("print myconfig();",0); +#ifdef VMS + sv_catpv(Sv,"print \"\\nCharacteristics of this PERLSHR image: \\n\","); +#else + sv_catpv(Sv,"print \"\\nCharacteristics of this binary (from libperl): \\n\","); +#endif +#if defined(DEBUGGING) || defined(NO_EMBED) || defined(MULTIPLICITY) + sv_catpv(Sv,"\" Compile-time options:"); +# ifdef DEBUGGING + sv_catpv(Sv," DEBUGGING"); +# endif +# ifdef NO_EMBED + sv_catpv(Sv," NO_EMBED"); +# endif +# ifdef MULTIPLICITY + sv_catpv(Sv," MULTIPLICITY"); +# endif + sv_catpv(Sv,"\\n\","); +#endif +#if defined(LOCAL_PATCH_COUNT) + if (LOCAL_PATCH_COUNT > 0) { + int i; + sv_catpv(Sv,"\" Locally applied patches:\\n\","); + for (i = 1; i <= LOCAL_PATCH_COUNT; i++) { + if (localpatches[i]) + sv_catpvf(Sv,"\" \\t%s\\n\",",localpatches[i]); + } + } +#endif + sv_catpvf(Sv,"\" Built under %s\\n\"",OSNAME); +#ifdef __DATE__ +# ifdef __TIME__ + sv_catpvf(Sv,",\" Compiled at %s %s\\n\"",__DATE__,__TIME__); +# else + sv_catpvf(Sv,",\" Compiled on %s\\n\"",__DATE__); +# endif +#endif + sv_catpv(Sv, "; \ +$\"=\"\\n \"; \ +@env = map { \"$_=\\\"$ENV{$_}\\\"\" } sort grep {/^PERL/} keys %ENV; \ +print \" \\%ENV:\\n @env\\n\" if @env; \ +print \" \\@INC:\\n @INC\\n\";"); } else { Sv = newSVpv("config_vars(qw(",0); @@ -402,29 +701,64 @@ setuid perl scripts securely.\n"); if (*s) cddir = savepv(s); break; - case '-': - argc--,argv++; - goto switch_end; case 0: break; + case '-': + if (!*++s || isSPACE(*s)) { + argc--,argv++; + goto switch_end; + } + /* catch use of gnu style long options */ + if (strEQ(s, "version")) { + s = "v"; + goto reswitch; + } + if (strEQ(s, "help")) { + s = "h"; + goto reswitch; + } + s--; + /* FALL THROUGH */ default: - croak("Unrecognized switch: -%s",s); + croak("Unrecognized switch: -%s (-h will show valid options)",s); } } switch_end: + + if (!tainting && (s = getenv("PERL5OPT"))) { + while (s && *s) { + while (isSPACE(*s)) + s++; + if (*s == '-') { + s++; + if (isSPACE(*s)) + continue; + } + if (!*s) + break; + if (!strchr("DIMUdmw", *s)) + croak("Illegal switch in PERL5OPT: -%c", *s); + s = moreswitches(s); + } + } + if (!scriptname) scriptname = argv[0]; if (e_fp) { - if (Fflush(e_fp) || ferror(e_fp) || fclose(e_fp)) + if (PerlIO_flush(e_fp) || PerlIO_error(e_fp) || PerlIO_close(e_fp)) { +#ifndef MULTIPLICITY + warn("Did you forget to compile with -DMULTIPLICITY?"); +#endif croak("Can't write to temp file for -e: %s", Strerror(errno)); + } e_fp = Nullfp; argc++,argv--; scriptname = e_tmpname; } else if (scriptname == Nullch) { #ifdef MSDOS - if ( isatty(fileno(stdin)) ) - moreswitches("v"); + if ( isatty(PerlIO_fileno(PerlIO_stdin())) ) + moreswitches("h"); #endif scriptname = "-"; } @@ -438,15 +772,14 @@ setuid perl scripts securely.\n"); if (doextract) find_beginning(); - compcv = (CV*)NEWSV(1104,0); + main_cv = compcv = (CV*)NEWSV(1104,0); sv_upgrade((SV *)compcv, SVt_PVCV); + CvUNIQUE_on(compcv); - pad = newAV(); - comppad = pad; + comppad = newAV(); av_push(comppad, Nullsv); curpad = AvARRAY(comppad); - padname = newAV(); - comppad_name = padname; + comppad_name = newAV(); comppad_name_fill = 0; min_intro_pending = 0; padix = 0; @@ -457,9 +790,10 @@ setuid perl scripts securely.\n"); av_store(comppadlist, 1, (SV*)comppad); CvPADLIST(compcv) = comppadlist; + boot_core_UNIVERSAL(); if (xsinit) (*xsinit)(); /* in case linked C routines want magical variables */ -#ifdef VMS +#if defined(VMS) || defined(WIN32) init_os_extras(); #endif @@ -503,13 +837,14 @@ setuid perl scripts securely.\n"); LEAVE; FREETMPS; -#ifdef DEBUGGING_MSTATS +#ifdef MYMALLOC if ((s=getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2) dump_mstats("after compilation:"); #endif ENTER; restartop = 0; + JMPENV_POP; return 0; } @@ -517,44 +852,60 @@ int perl_run(sv_interp) PerlInterpreter *sv_interp; { + I32 oldscope; + dJMPENV; + int ret; + if (!(curinterp = sv_interp)) return 255; - switch (Sigsetjmp(top_env,1)) { + + oldscope = scopestack_ix; + + JMPENV_PUSH(ret); + switch (ret) { case 1: cxstack_ix = -1; /* start context stack again */ break; case 2: + /* my_exit() was called */ + while (scopestack_ix > oldscope) + LEAVE; + FREETMPS; curstash = defstash; if (endav) - calllist(endav); - FREETMPS; -#ifdef DEBUGGING_MSTATS + call_list(oldscope, endav); +#ifdef MYMALLOC if (getenv("PERL_DEBUG_MSTATS")) dump_mstats("after execution: "); #endif - return(statusvalue); /* my_exit() was called */ + JMPENV_POP; + return STATUS_NATIVE_EXPORT; case 3: if (!restartop) { - fprintf(stderr, "panic: restartop\n"); + PerlIO_printf(PerlIO_stderr(), "panic: restartop\n"); FREETMPS; + JMPENV_POP; return 1; } - if (stack != mainstack) { + if (curstack != mainstack) { dSP; - SWITCHSTACK(stack, mainstack); + SWITCHSTACK(curstack, mainstack); } break; } + DEBUG_r(PerlIO_printf(Perl_debug_log, "%s $` $& $' support.\n", + sawampersand ? "Enabling" : "Omitting")); + if (!restartop) { DEBUG_x(dump_all()); - DEBUG(fprintf(stderr,"\nEXECUTING...\n\n")); + DEBUG(PerlIO_printf(Perl_debug_log, "\nEXECUTING...\n\n")); if (minus_c) { - fprintf(stderr,"%s syntax OK\n", origfilename); + PerlIO_printf(PerlIO_stderr(), "%s syntax OK\n", origfilename); my_exit(0); } - if (perldb && DBsingle) + if (PERLDB_SINGLE && DBsingle) sv_setiv(DBsingle, 1); } @@ -566,32 +917,16 @@ PerlInterpreter *sv_interp; runops(); } else if (main_start) { + CvDEPTH(main_cv) = 1; op = main_start; runops(); } my_exit(0); + /* NOTREACHED */ return 0; } -void -my_exit(status) -U32 status; -{ - register CONTEXT *cx; - I32 gimme; - SV **newsp; - - statusvalue = FIXSTATUS(status); - if (cxstack_ix >= 0) { - if (cxstack_ix > 0) - dounwind(0); - POPBLOCK(cx,curpm); - LEAVE; - } - Siglongjmp(top_env, 2); -} - SV* perl_get_sv(name, create) char* name; @@ -635,13 +970,13 @@ char* name; I32 create; { GV* gv = gv_fetchpv(name, create, SVt_PVCV); - if (create && !GvCV(gv)) - return newSUB(start_subparse(), + if (create && !GvCVu(gv)) + return newSUB(start_subparse(FALSE, 0), newSVOP(OP_CONST, 0, newSVpv(name,0)), Nullop, Nullop); if (gv) - return GvCV(gv); + return GvCVu(gv); return Nullcv; } @@ -697,39 +1032,50 @@ I32 flags; /* See G_* flags in cop.h */ { LOGOP myop; /* fake syntax tree node */ SV** sp = stack_sp; - I32 oldmark = TOPMARK; + I32 oldmark; I32 retval; - Sigjmp_buf oldtop; I32 oldscope; - + static CV *DBcv; + bool oldcatch = CATCH_GET; + dJMPENV; + int ret; + OP* oldop = op; + if (flags & G_DISCARD) { ENTER; SAVETMPS; } + Zero(&myop, 1, LOGOP); + myop.op_next = Nullop; + if (!(flags & G_NOARGS)) + myop.op_flags |= OPf_STACKED; + myop.op_flags |= ((flags & G_VOID) ? OPf_WANT_VOID : + (flags & G_ARRAY) ? OPf_WANT_LIST : + OPf_WANT_SCALAR); SAVESPTR(op); op = (OP*)&myop; - Zero(op, 1, LOGOP); + EXTEND(stack_sp, 1); *++stack_sp = sv; + oldmark = TOPMARK; oldscope = scopestack_ix; - if (!(flags & G_NOARGS)) - myop.op_flags = OPf_STACKED; - myop.op_next = Nullop; - myop.op_flags |= OPf_KNOW; - if (flags & G_ARRAY) - myop.op_flags |= OPf_LIST; + if (PERLDB_SUB && curstash != debstash + /* Handle first BEGIN of -d. */ + && (DBcv || (DBcv = GvCV(DBsub))) + /* Try harder, since this may have been a sighandler, thus + * curstash may be meaningless. */ + && (SvTYPE(sv) != SVt_PVCV || CvSTASH((CV*)sv) != debstash)) + op->op_private |= OPpENTERSUB_DB; if (flags & G_EVAL) { - Copy(top_env, oldtop, 1, Sigjmp_buf); - cLOGOP->op_other = op; markstack_ptr--; /* we're trying to emulate pp_entertry() here */ { register CONTEXT *cx; - I32 gimme = GIMME; + I32 gimme = GIMME_V; ENTER; SAVETMPS; @@ -747,31 +1093,27 @@ I32 flags; /* See G_* flags in cop.h */ } markstack_ptr++; - restart: - switch (Sigsetjmp(top_env,1)) { + JMPENV_PUSH(ret); + switch (ret) { case 0: break; case 1: -#ifdef VMS - statusvalue = 255; /* XXX I don't think we use 1 anymore. */ -#else - statusvalue = 1; -#endif + STATUS_ALL_FAILURE; /* FALL THROUGH */ case 2: /* my_exit() was called */ curstash = defstash; FREETMPS; - Copy(oldtop, top_env, 1, Sigjmp_buf); + JMPENV_POP; if (statusvalue) croak("Callback called exit"); - my_exit(statusvalue); + my_exit_jump(); /* NOTREACHED */ case 3: if (restartop) { op = restartop; restartop = 0; - goto restart; + break; } stack_sp = stack_base + oldmark; if (flags & G_ARRAY) @@ -783,6 +1125,8 @@ I32 flags; /* See G_* flags in cop.h */ goto cleanup; } } + else + CATCH_SET(TRUE); if (op == (OP*)&myop) op = pp_entersub(); @@ -807,18 +1151,22 @@ I32 flags; /* See G_* flags in cop.h */ curpm = newpm; LEAVE; } - Copy(oldtop, top_env, 1, Sigjmp_buf); + JMPENV_POP; } + else + CATCH_SET(oldcatch); + if (flags & G_DISCARD) { stack_sp = stack_base + oldmark; retval = 0; FREETMPS; LEAVE; } + op = oldop; return retval; } -/* Eval a string. */ +/* Eval a string. The G_EVAL flag is always assumed. */ I32 perl_eval_sv(sv, flags) @@ -829,9 +1177,11 @@ I32 flags; /* See G_* flags in cop.h */ SV** sp = stack_sp; I32 oldmark = sp - stack_base; I32 retval; - Sigjmp_buf oldtop; I32 oldscope; - + dJMPENV; + int ret; + OP* oldop = op; + if (flags & G_DISCARD) { ENTER; SAVETMPS; @@ -847,37 +1197,34 @@ I32 flags; /* See G_* flags in cop.h */ if (!(flags & G_NOARGS)) myop.op_flags = OPf_STACKED; myop.op_next = Nullop; - myop.op_flags |= OPf_KNOW; - if (flags & G_ARRAY) - myop.op_flags |= OPf_LIST; - - Copy(top_env, oldtop, 1, Sigjmp_buf); - -restart: - switch (Sigsetjmp(top_env,1)) { + myop.op_type = OP_ENTEREVAL; + myop.op_flags |= ((flags & G_VOID) ? OPf_WANT_VOID : + (flags & G_ARRAY) ? OPf_WANT_LIST : + OPf_WANT_SCALAR); + if (flags & G_KEEPERR) + myop.op_flags |= OPf_SPECIAL; + + JMPENV_PUSH(ret); + switch (ret) { case 0: break; case 1: -#ifdef VMS - statusvalue = 255; /* XXX I don't think we use 1 anymore. */ -#else - statusvalue = 1; -#endif + STATUS_ALL_FAILURE; /* FALL THROUGH */ case 2: /* my_exit() was called */ curstash = defstash; FREETMPS; - Copy(oldtop, top_env, 1, Sigjmp_buf); + JMPENV_POP; if (statusvalue) croak("Callback called exit"); - my_exit(statusvalue); + my_exit_jump(); /* NOTREACHED */ case 3: if (restartop) { op = restartop; restartop = 0; - goto restart; + break; } stack_sp = stack_base + oldmark; if (flags & G_ARRAY) @@ -894,20 +1241,43 @@ restart: if (op) runops(); retval = stack_sp - (stack_base + oldmark); - if ((flags & G_EVAL) && !(flags & G_KEEPERR)) + if (!(flags & G_KEEPERR)) sv_setpv(GvSV(errgv),""); cleanup: - Copy(oldtop, top_env, 1, Sigjmp_buf); + JMPENV_POP; if (flags & G_DISCARD) { stack_sp = stack_base + oldmark; retval = 0; FREETMPS; LEAVE; } + op = oldop; return retval; } +SV* +perl_eval_pv(p, croak_on_error) +char* p; +I32 croak_on_error; +{ + dSP; + SV* sv = newSVpv(p, 0); + + PUSHMARK(sp); + perl_eval_sv(sv, G_SCALAR); + SvREFCNT_dec(sv); + + SPAGAIN; + sv = POPs; + PUTBACK; + + if (croak_on_error && SvTRUE(GvSV(errgv))) + croak(SvPVx(GvSV(errgv), na)); + + return sv; +} + /* Require a module. */ void @@ -933,76 +1303,45 @@ I32 namlen; sv_magic(GvSV(gv), (SV*)gv, 0, name, namlen); } -#if defined(DOSISH) -# define PERLLIB_SEP ';' -#else -# if defined(VMS) -# define PERLLIB_SEP '|' -# else -# define PERLLIB_SEP ':' -# endif -#endif - -static void -incpush(p) -char *p; -{ - char *s; - - if (!p) - return; - - /* Break at all separators */ - while (*p) { - /* First, skip any consecutive separators */ - while ( *p == PERLLIB_SEP ) { - /* Uncomment the next line for PATH semantics */ - /* av_push(GvAVn(incgv), newSVpv(".", 1)); */ - p++; - } - if ( (s = strchr(p, PERLLIB_SEP)) != Nullch ) { - av_push(GvAVn(incgv), newSVpv(p, (STRLEN)(s - p))); - p = s + 1; - } else { - av_push(GvAVn(incgv), newSVpv(p, 0)); - break; - } - } -} - static void usage(name) /* XXX move this out into a module ? */ char *name; { /* This message really ought to be max 23 lines. * Removed -h because the user already knows that opton. Others? */ + + static char *usage[] = { +"-0[octal] specify record separator (\\0, if no argument)", +"-a autosplit mode with -n or -p (splits $_ into @F)", +"-c check syntax only (runs BEGIN and END blocks)", +"-d[:debugger] run scripts under debugger", +"-D[number/list] set debugging flags (argument is a bit mask or flags)", +"-e 'command' one line of script. Several -e's allowed. Omit [programfile].", +"-F/pattern/ split() pattern for autosplit (-a). The //'s are optional.", +"-i[extension] edit <> files in place (make backup if extension supplied)", +"-Idirectory specify @INC/#include directory (may be used more than once)", +"-l[octal] enable line ending processing, specifies line terminator", +"-[mM][-]module.. executes `use/no module...' before executing your script.", +"-n assume 'while (<>) { ... }' loop around your script", +"-p assume loop like -n but print line also like sed", +"-P run script through C preprocessor before compilation", +"-s enable some switch parsing for switches after script name", +"-S look for the script using PATH environment variable", +"-T turn on tainting checks", +"-u dump core after parsing script", +"-U allow unsafe operations", +"-v print version number and patchlevel of perl", +"-V[:variable] print perl configuration information", +"-w TURN WARNINGS ON FOR COMPILATION OF YOUR SCRIPT. Recommended.", +"-x[directory] strip off text before #!perl line and perhaps cd to directory", +"\n", +NULL +}; + char **p = usage; + printf("\nUsage: %s [switches] [--] [programfile] [arguments]", name); - printf("\n -0[octal] specify record separator (\\0, if no argument)"); - printf("\n -a autosplit mode with -n or -p (splits $_ into @F)"); - printf("\n -c check syntax only (runs BEGIN and END blocks)"); - printf("\n -d[:debugger] run scripts under debugger"); - printf("\n -D[number/list] set debugging flags (argument is a bit mask or flags)"); - printf("\n -e 'command' one line of script. Several -e's allowed. Omit [programfile]."); - printf("\n -F/pattern/ split() pattern for autosplit (-a). The //'s are optional."); - printf("\n -i[extension] edit <> files in place (make backup if extension supplied)"); - printf("\n -Idirectory specify @INC/#include directory (may be used more then once)"); - printf("\n -l[octal] enable line ending processing, specifies line teminator"); - printf("\n -[mM][-]module.. executes `use/no module...' before executing your script."); - printf("\n -n assume 'while (<>) { ... }' loop arround your script"); - printf("\n -p assume loop like -n but print line also like sed"); - printf("\n -P run script through C preprocessor before compilation"); -#ifdef OS2 - printf("\n -R enable REXX variable pool"); -#endif - printf("\n -s enable some switch parsing for switches after script name"); - printf("\n -S look for the script using PATH environment variable"); - printf("\n -T turn on tainting checks"); - printf("\n -u dump core after parsing script"); - printf("\n -U allow unsafe operations"); - printf("\n -v print version number and patchlevel of perl"); - printf("\n -V[:variable] print perl configuration information"); - printf("\n -w TURN WARNINGS ON FOR COMPILATION OF YOUR SCRIPT."); - printf("\n -x[directory] strip off text before #!perl line and perhaps cd to directory\n"); + while (*p) + printf("\n %s", *p++); } /* This routine handles any switches that can be given during run */ @@ -1041,21 +1380,20 @@ char *s; s++; return s; case 'd': - taint_not("-d"); + forbid_setid("-d"); s++; if (*s == ':' || *s == '=') { - sprintf(buf, "use Devel::%s;", ++s); + my_setenv("PERL5DB", form("use Devel::%s;", ++s)); s += strlen(s); - my_setenv("PERL5DB",buf); } if (!perldb) { - perldb = TRUE; + perldb = PERLDB_ALL; init_debugger(); } return s; case 'D': #ifdef DEBUGGING - taint_not("-D"); + forbid_setid("-D"); if (isALPHA(s[1])) { static char debopts[] = "psltocPmfrxuLHXD"; char *d; @@ -1083,20 +1421,25 @@ char *s; inplace = savepv(s+1); /*SUPPRESS 530*/ for (s = inplace; *s && !isSPACE(*s); s++) ; - *s = '\0'; - break; - case 'I': - taint_not("-I"); - if (*++s) { - char *e; + if (*s) + *s++ = '\0'; + return s; + case 'I': /* -I handled both here and in parse_perl() */ + forbid_setid("-I"); + ++s; + while (*s && isSPACE(*s)) + ++s; + if (*s) { + char *e, *p; for (e = s; *e && !isSPACE(*e); e++) ; - av_push(GvAVn(incgv),newSVpv(s,e-s)); - if (*e) - return e; + p = savepvn(s, e-s); + incpush(p, TRUE); + Safefree(p); + s = e; } else croak("No space allowed after -I"); - break; + return s; case 'l': minus_l = TRUE; s++; @@ -1110,18 +1453,19 @@ char *s; } else { if (RsPARA(nrs)) { - ors = savepvn("\n\n", 2); + ors = "\n\n"; orslen = 2; } else ors = SvPV(nrs, orslen); + ors = savepvn(ors, orslen); } return s; case 'M': - taint_not("-M"); /* XXX ? */ + forbid_setid("-M"); /* XXX ? */ /* FALL THROUGH */ case 'm': - taint_not("-m"); /* XXX ? */ + forbid_setid("-m"); /* XXX ? */ if (*++s) { char *start; char *use = "use "; @@ -1161,12 +1505,13 @@ char *s; s++; return s; case 's': - taint_not("-s"); + forbid_setid("-s"); doswitches = TRUE; s++; return s; case 'T': - tainting = TRUE; + if (!tainting) + croak("Too late for \"-T\" option"); s++; return s; case 'u': @@ -1179,61 +1524,35 @@ char *s; return s; case 'v': #if defined(SUBVERSION) && SUBVERSION > 0 - printf("\nThis is perl, version 5.%03d_%02d", PATCHLEVEL, SUBVERSION); + printf("\nThis is perl, version 5.%03d_%02d built for %s", + PATCHLEVEL, SUBVERSION, ARCHNAME); #else - printf("\nThis is perl, version %s",patchlevel); -#endif - -#if defined(DEBUGGING) || defined(EMBED) || defined(MULTIPLICITY) - fputs(" with", stdout); -#ifdef DEBUGGING - fputs(" DEBUGGING", stdout); -#endif -#ifdef EMBED - fputs(" EMBED", stdout); + printf("\nThis is perl, version %s built for %s", + patchlevel, ARCHNAME); #endif -#ifdef MULTIPLICITY - fputs(" MULTIPLICITY", stdout); -#endif -#endif - #if defined(LOCAL_PATCH_COUNT) - if (LOCAL_PATCH_COUNT > 0) - { int i; - fputs("\n\tLocally applied patches:\n", stdout); - for (i = 1; i <= LOCAL_PATCH_COUNT; i++) { - if (Ilocalpatches[i]) - fprintf(stdout, "\t %s\n", Ilocalpatches[i]); - } - } -#endif - printf("\n\tbuilt under %s",OSNAME); -#ifdef __DATE__ -# ifdef __TIME__ - printf(" at %s %s",__DATE__,__TIME__); -# else - printf(" on %s",__DATE__); -# endif + if (LOCAL_PATCH_COUNT > 0) + printf("\n(with %d registered patch%s, see perl -V for more detail)", + LOCAL_PATCH_COUNT, (LOCAL_PATCH_COUNT!=1) ? "es" : ""); #endif - fputs("\n\t+ suidperl security patch", stdout); - fputs("\n\nCopyright 1987-1996, Larry Wall\n",stdout); + + printf("\n\nCopyright 1987-1997, Larry Wall\n"); #ifdef MSDOS - fputs("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n", - stdout); + printf("\nMS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n"); +#endif +#ifdef DJGPP + printf("djgpp v2 port (jpl5003c) by Hirofumi Watanabe, 1996\n"); #endif #ifdef OS2 - fputs("OS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n" - "Version 5 port Copyright (c) 1994-1995, Andreas Kaiser\n", stdout); + printf("\n\nOS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n" + "Version 5 port Copyright (c) 1994-1997, Andreas Kaiser, Ilya Zakharevich\n"); #endif #ifdef atarist - fputs("atariST series port, ++jrb bammi@cadence.com\n", stdout); + printf("atariST series port, ++jrb bammi@cadence.com\n"); #endif - fputs("\n\ + printf("\n\ Perl may be copied only under the terms of either the Artistic License or the\n\ -GNU General Public License, which may be found in the Perl 5.0 source kit.\n\n",stdout); -#ifdef MSDOS - usage(origargv[0]); -#endif +GNU General Public License, which may be found in the Perl 5.0 source kit.\n\n"); exit(0); case 'w': dowarn = TRUE; @@ -1249,6 +1568,10 @@ GNU General Public License, which may be found in the Perl 5.0 source kit.\n\n", case '\n': case '\t': break; +#ifdef ALTERNATE_SHEBANG + case 'S': /* OS/2 needs -S on "extproc" line. */ + break; +#endif case 'P': if (preprocess) return s+1; @@ -1267,23 +1590,28 @@ void my_unexec() { #ifdef UNEXEC + SV* prog; + SV* file; int status; extern int etext; - sprintf (buf, "%s.perldump", origfilename); - sprintf (tokenbuf, "%s/perl", BIN); + prog = newSVpv(BIN_EXP); + sv_catpv(prog, "/perl"); + file = newSVpv(origfilename); + sv_catpv(file, ".perldump"); - status = unexec(buf, tokenbuf, &etext, sbrk(0), 0); + status = unexec(SvPVX(file), SvPVX(prog), &etext, sbrk(0), 0); if (status) - fprintf(stderr, "unexec of %s into %s failed!\n", tokenbuf, buf); + PerlIO_printf(PerlIO_stderr(), "unexec of %s into %s failed!\n", + SvPVX(prog), SvPVX(file)); exit(status); #else # ifdef VMS # include <lib$routines.h> lib$signal(SS$_DEBUG); /* ssdef.h #included from vmsish.h */ -#else +# else ABORT(); /* for use with undump */ -#endif +# endif #endif } @@ -1291,6 +1619,15 @@ static void init_main_stash() { GV *gv; + + /* Note that strtab is a rather special HV. Assumptions are made + about not iterating on it, and not adding tie magic to it. + It is properly deallocated in perl_destruct() */ + strtab = newHV(); + HvSHAREKEYS_off(strtab); /* mandatory */ + Newz(506,((XPVHV*)SvANY(strtab))->xhv_array, + sizeof(HE*) * (((XPVHV*)SvANY(strtab))->xhv_max + 1), char); + curstash = defstash = newHV(); curstname = newSVpv("main",4); gv = gv_fetchpv("main::",TRUE, SVt_PVHV); @@ -1303,6 +1640,9 @@ init_main_stash() defgv = gv_fetchpv("_",TRUE, SVt_PVAV); errgv = gv_HVadd(gv_fetchpv("@", TRUE, SVt_PV)); GvMULTI_on(errgv); + (void)form("%240s",""); /* Preallocate temp - for immediate signals. */ + sv_grow(GvSV(errgv), 240); /* Preallocate - for immediate signals. */ + sv_setpvn(GvSV(errgv), "", 0); curstash = defstash; compiling.cop_stash = defstash; debstash = GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV)); @@ -1327,52 +1667,141 @@ SV *sv; I32 len; int retval; #if defined(DOSISH) && !defined(OS2) && !defined(atarist) -#define SEARCH_EXTS ".bat", ".cmd", NULL +# define SEARCH_EXTS ".bat", ".cmd", NULL +# define MAX_EXT_LEN 4 +#endif +#ifdef OS2 +# define SEARCH_EXTS ".cmd", ".btm", ".bat", ".pl", NULL +# define MAX_EXT_LEN 4 #endif #ifdef VMS # define SEARCH_EXTS ".pl", ".com", NULL +# define MAX_EXT_LEN 4 #endif /* additional extensions to try in each dir if scriptname not found */ #ifdef SEARCH_EXTS char *ext[] = { SEARCH_EXTS }; - int extidx = (strchr(scriptname,'.')) ? -1 : 0; /* has ext already */ + int extidx = 0, i = 0; + char *curext = Nullch; +#else +# define MAX_EXT_LEN 0 #endif -#ifdef VMS - if (dosearch && !strpbrk(scriptname,":[</") && (my_getenv("DCL$PATH"))) { - int idx = 0; + /* + * If dosearch is true and if scriptname does not contain path + * delimiters, search the PATH for scriptname. + * + * If SEARCH_EXTS is also defined, will look for each + * scriptname{SEARCH_EXTS} whenever scriptname is not found + * while searching the PATH. + * + * Assuming SEARCH_EXTS is C<".foo",".bar",NULL>, PATH search + * proceeds as follows: + * If DOSISH: + * + look for ./scriptname{,.foo,.bar} + * + search the PATH for scriptname{,.foo,.bar} + * + * If !DOSISH: + * + look *only* in the PATH for scriptname{,.foo,.bar} (note + * this will not look in '.' if it's not in the PATH) + */ - while (my_trnlnm("DCL$PATH",tokenbuf,idx++)) { - strcat(tokenbuf,scriptname); +#ifdef VMS + if (dosearch) { + int hasdir, idx = 0, deftypes = 1; + bool seen_dot = 1; + + hasdir = (strpbrk(scriptname,":[</") != Nullch) ; + /* The first time through, just add SEARCH_EXTS to whatever we + * already have, so we can check for default file types. */ + while (deftypes || + (!hasdir && my_trnlnm("DCL$PATH",tokenbuf,idx++)) ) + { + if (deftypes) { + deftypes = 0; + *tokenbuf = '\0'; + } + if ((strlen(tokenbuf) + strlen(scriptname) + + MAX_EXT_LEN) >= sizeof tokenbuf) + continue; /* don't search dir with too-long name */ + strcat(tokenbuf, scriptname); #else /* !VMS */ - if (dosearch && !strchr(scriptname, '/') && (s = getenv("PATH"))) { - bufend = s + strlen(s); - while (*s) { -#ifndef DOSISH - s = cpytill(tokenbuf,s,bufend,':',&len); -#else -#ifdef atarist - for (len = 0; *s && *s != ',' && *s != ';'; tokenbuf[len++] = *s++); - tokenbuf[len] = '\0'; -#else - for (len = 0; *s && *s != ';'; tokenbuf[len++] = *s++); - tokenbuf[len] = '\0'; +#ifdef DOSISH + if (strEQ(scriptname, "-")) + dosearch = 0; + if (dosearch) { /* Look in '.' first. */ + char *cur = scriptname; +#ifdef SEARCH_EXTS + if ((curext = strrchr(scriptname,'.'))) /* possible current ext */ + while (ext[i]) + if (strEQ(ext[i++],curext)) { + extidx = -1; /* already has an ext */ + break; + } + do { #endif + DEBUG_p(PerlIO_printf(Perl_debug_log, + "Looking for %s\n",cur)); + if (Stat(cur,&statbuf) >= 0) { + dosearch = 0; + scriptname = cur; +#ifdef SEARCH_EXTS + break; #endif - if (*s) - s++; -#ifndef DOSISH - if (len && tokenbuf[len-1] != '/') -#else -#ifdef atarist - if (len && ((tokenbuf[len-1] != '\\') && (tokenbuf[len-1] != '/'))) -#else - if (len && tokenbuf[len-1] != '\\') + } +#ifdef SEARCH_EXTS + if (cur == scriptname) { + len = strlen(scriptname); + if (len+MAX_EXT_LEN+1 >= sizeof(tokenbuf)) + break; + cur = strcpy(tokenbuf, scriptname); + } + } while (extidx >= 0 && ext[extidx] /* try an extension? */ + && strcpy(tokenbuf+len, ext[extidx++])); #endif + } +#endif + + if (dosearch && !strchr(scriptname, '/') +#ifdef DOSISH + && !strchr(scriptname, '\\') #endif - (void)strcat(tokenbuf+len,"/"); - (void)strcat(tokenbuf+len,scriptname); + && (s = getenv("PATH"))) { + bool seen_dot = 0; + + bufend = s + strlen(s); + while (s < bufend) { +#if defined(atarist) || defined(DOSISH) + for (len = 0; *s +# ifdef atarist + && *s != ',' +# endif + && *s != ';'; len++, s++) { + if (len < sizeof tokenbuf) + tokenbuf[len] = *s; + } + if (len < sizeof tokenbuf) + tokenbuf[len] = '\0'; +#else /* ! (atarist || DOSISH) */ + s = delimcpy(tokenbuf, tokenbuf + sizeof tokenbuf, s, bufend, + ':', + &len); +#endif /* ! (atarist || DOSISH) */ + if (s < bufend) + s++; + if (len + 1 + strlen(scriptname) + MAX_EXT_LEN >= sizeof tokenbuf) + continue; /* don't search dir with too-long name */ + if (len +#if defined(atarist) || defined(DOSISH) + && tokenbuf[len - 1] != '/' + && tokenbuf[len - 1] != '\\' +#endif + ) + tokenbuf[len++] = '/'; + if (len == 2 && tokenbuf[0] == '.') + seen_dot = 1; + (void)strcpy(tokenbuf + len, scriptname); #endif /* !VMS */ #ifdef SEARCH_EXTS @@ -1381,7 +1810,7 @@ SV *sv; extidx = 0; do { #endif - DEBUG_p(fprintf(stderr,"Looking for %s\n",tokenbuf)); + DEBUG_p(PerlIO_printf(Perl_debug_log, "Looking for %s\n",tokenbuf)); retval = Stat(tokenbuf,&statbuf); #ifdef SEARCH_EXTS } while ( retval < 0 /* not there */ @@ -1392,15 +1821,28 @@ SV *sv; if (retval < 0) continue; if (S_ISREG(statbuf.st_mode) - && cando(S_IRUSR,TRUE,&statbuf) && cando(S_IXUSR,TRUE,&statbuf)) { + && cando(S_IRUSR,TRUE,&statbuf) +#ifndef DOSISH + && cando(S_IXUSR,TRUE,&statbuf) +#endif + ) + { xfound = tokenbuf; /* bingo! */ break; } if (!xfailed) xfailed = savepv(tokenbuf); } +#ifndef DOSISH + if (!xfound && !seen_dot && !xfailed && (Stat(scriptname,&statbuf) < 0)) +#endif + seen_dot = 1; /* Disable message. */ if (!xfound) - croak("Can't execute %s", xfailed ? xfailed : scriptname ); + croak("Can't %s %s%s%s", + (xfailed ? "execute" : "find"), + (xfailed ? xfailed : scriptname), + (xfailed ? "" : " on PATH"), + (xfailed || seen_dot) ? "" : ", '.' not in PATH"); if (xfailed) Safefree(xfailed); scriptname = xfound; @@ -1421,22 +1863,26 @@ SV *sv; if (strEQ(origfilename,"-")) scriptname = ""; if (fdscript >= 0) { - rsfp = fdopen(fdscript,"r"); + rsfp = PerlIO_fdopen(fdscript,"r"); #if defined(HAS_FCNTL) && defined(F_SETFD) - fcntl(fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */ + if (rsfp) + fcntl(PerlIO_fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */ #endif } else if (preprocess) { - char *cpp = CPPSTDIN; + char *cpp_cfg = CPPSTDIN; + SV *cpp = NEWSV(0,0); + SV *cmd = NEWSV(0,0); + + if (strEQ(cpp_cfg, "cppstdin")) + sv_catpvf(cpp, "%s/", BIN_EXP); + sv_catpv(cpp, cpp_cfg); - if (strEQ(cpp,"cppstdin")) - sprintf(tokenbuf, "%s/%s", SCRIPTDIR, cpp); - else - sprintf(tokenbuf, "%s", cpp); sv_catpv(sv,"-I"); sv_catpv(sv,PRIVLIB_EXP); + #ifdef MSDOS - (void)sprintf(buf, "\ + sv_setpvf(cmd, "\ sed %s -e \"/^[^#]/b\" \ -e \"/^#[ ]*include[ ]/b\" \ -e \"/^#[ ]*define[ ]/b\" \ @@ -1448,10 +1894,10 @@ sed %s -e \"/^[^#]/b\" \ -e \"/^#[ ]*undef[ ]/b\" \ -e \"/^#[ ]*endif/b\" \ -e \"s/^#.*//\" \ - %s | %s -C %s %s", + %s | %_ -C %_ %s", (doextract ? "-e \"1,/^#/d\n\"" : ""), #else - (void)sprintf(buf, "\ + sv_setpvf(cmd, "\ %s %s -e '/^[^#]/b' \ -e '/^#[ ]*include[ ]/b' \ -e '/^#[ ]*define[ ]/b' \ @@ -1463,7 +1909,7 @@ sed %s -e \"/^[^#]/b\" \ -e '/^#[ ]*undef[ ]/b' \ -e '/^#[ ]*endif/b' \ -e 's/^[ ]*#.*//' \ - %s | %s -C %s %s", + %s | %_ -C %_ %s", #ifdef LOC_SED LOC_SED, #else @@ -1471,7 +1917,7 @@ sed %s -e \"/^[^#]/b\" \ #endif (doextract ? "-e '1,/^#/d\n'" : ""), #endif - scriptname, tokenbuf, SvPV(sv, na), CPPMINUS); + scriptname, cpp, sv, CPPMINUS); doextract = FALSE; #ifdef IAMSUID /* actually, this is caught earlier */ if (euid != uid && !euid) { /* if running suidperl */ @@ -1492,25 +1938,31 @@ sed %s -e \"/^[^#]/b\" \ croak("Can't do seteuid!\n"); } #endif /* IAMSUID */ - rsfp = my_popen(buf,"r"); + rsfp = my_popen(SvPVX(cmd), "r"); + SvREFCNT_dec(cmd); + SvREFCNT_dec(cpp); } else if (!*scriptname) { - taint_not("program input from stdin"); - rsfp = stdin; + forbid_setid("program input from stdin"); + rsfp = PerlIO_stdin(); } else { - rsfp = fopen(scriptname,"r"); + rsfp = PerlIO_open(scriptname,"r"); #if defined(HAS_FCNTL) && defined(F_SETFD) - fcntl(fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */ + if (rsfp) + fcntl(PerlIO_fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */ #endif } - if ((FILE*)rsfp == Nullfp) { + if (e_tmpname) { + e_fp = rsfp; + } + if (!rsfp) { #ifdef DOSUID #ifndef IAMSUID /* in case script is not readable before setuid */ if (euid && Stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 && statbuf.st_mode & (S_ISUID|S_ISGID)) { - (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel); - execv(buf, origargv); /* try again */ + /* try again */ + execv(form("%s/sperl%s", BIN_EXP, patchlevel), origargv); croak("Can't do setuid\n"); } #endif @@ -1548,9 +2000,9 @@ char *scriptname; */ #ifdef DOSUID - char *s; + char *s, *s2; - if (Fstat(fileno(rsfp),&statbuf) < 0) /* normal stat is insecure */ + if (Fstat(PerlIO_fileno(rsfp),&statbuf) < 0) /* normal stat is insecure */ croak("Can't stat script \"%s\"",origfilename); if (fdscript < 0 && statbuf.st_mode & (S_ISUID|S_ISGID)) { I32 len; @@ -1590,15 +2042,15 @@ char *scriptname; croak("Permission denied"); /* testing full pathname here */ if (tmpstatbuf.st_dev != statbuf.st_dev || tmpstatbuf.st_ino != statbuf.st_ino) { - (void)fclose(rsfp); + (void)PerlIO_close(rsfp); if (rsfp = my_popen("/bin/mail root","w")) { /* heh, heh */ - fprintf(rsfp, -"User %d tried to run dev %d ino %d in place of dev %d ino %d!\n\ -(Filename of set-id script was %s, uid %d gid %d.)\n\nSincerely,\nperl\n", - uid,tmpstatbuf.st_dev, tmpstatbuf.st_ino, - statbuf.st_dev, statbuf.st_ino, + PerlIO_printf(rsfp, +"User %ld tried to run dev %ld ino %ld in place of dev %ld ino %ld!\n\ +(Filename of set-id script was %s, uid %ld gid %ld.)\n\nSincerely,\nperl\n", + (long)uid,(long)tmpstatbuf.st_dev, (long)tmpstatbuf.st_ino, + (long)statbuf.st_dev, (long)statbuf.st_ino, SvPVX(GvSV(curcop->cop_filegv)), - statbuf.st_uid, statbuf.st_gid); + (long)statbuf.st_uid, (long)statbuf.st_gid); (void)my_pclose(rsfp); } croak("Permission denied\n"); @@ -1625,13 +2077,15 @@ char *scriptname; croak("Setuid/gid script is writable by world"); doswitches = FALSE; /* -s is insecure in suid */ curcop->cop_line++; - if (fgets(tokenbuf,sizeof tokenbuf, rsfp) == Nullch || - strnNE(tokenbuf,"#!",2) ) /* required even on Sys V */ + if (sv_gets(linestr, rsfp, 0) == Nullch || + strnNE(SvPV(linestr,na),"#!",2) ) /* required even on Sys V */ croak("No #! line"); - s = tokenbuf+2; + s = SvPV(linestr,na)+2; if (*s == ' ') s++; while (!isSPACE(*s)) s++; - if (strnNE(s-4,"perl",4) && strnNE(s-9,"perl",4)) /* sanity check */ + for (s2 = s; (s2 > SvPV(linestr,na)+2 && + (isDIGIT(s2[-1]) || strchr("._-", s2[-1]))); s2--) ; + if (strnNE(s2-4,"perl",4) && strnNE(s-9,"perl",4)) /* sanity check */ croak("Not a perl script"); while (*s == ' ' || *s == '\t') s++; /* @@ -1653,10 +2107,10 @@ FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n"); #endif /* IAMSUID */ if (euid) { /* oops, we're not the setuid root perl */ - (void)fclose(rsfp); + (void)PerlIO_close(rsfp); #ifndef IAMSUID - (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel); - execv(buf, origargv); /* try again */ + /* try again */ + execv(form("%s/sperl%s", BIN_EXP, patchlevel), origargv); #endif croak("Can't do setuid\n"); } @@ -1728,25 +2182,23 @@ FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n"); /* We absolutely must clear out any saved ids here, so we */ /* exec the real perl, substituting fd script for scriptname. */ /* (We pass script name as "subdir" of fd, which perl will grok.) */ - rewind(rsfp); + PerlIO_rewind(rsfp); + lseek(PerlIO_fileno(rsfp),(Off_t)0,0); /* just in case rewind didn't */ for (which = 1; origargv[which] && origargv[which] != scriptname; which++) ; if (!origargv[which]) croak("Permission denied"); - (void)sprintf(buf, "/dev/fd/%d/%.127s", fileno(rsfp), origargv[which]); - origargv[which] = buf; - + origargv[which] = savepv(form("/dev/fd/%d/%s", + PerlIO_fileno(rsfp), origargv[which])); #if defined(HAS_FCNTL) && defined(F_SETFD) - fcntl(fileno(rsfp),F_SETFD,0); /* ensure no close-on-exec */ + fcntl(PerlIO_fileno(rsfp),F_SETFD,0); /* ensure no close-on-exec */ #endif - - (void)sprintf(tokenbuf, "%s/perl%s", BIN, patchlevel); - execv(tokenbuf, origargv); /* try again */ + execv(form("%s/perl%s", BIN_EXP, patchlevel), origargv); /* try again */ croak("Can't do setuid\n"); #endif /* IAMSUID */ #else /* !DOSUID */ if (euid != uid || egid != gid) { /* (suidperl doesn't exist, in fact) */ #ifndef SETUID_SCRIPTS_ARE_SECURE_NOW - Fstat(fileno(rsfp),&statbuf); /* may be either wrapped or real suid */ + Fstat(PerlIO_fileno(rsfp),&statbuf); /* may be either wrapped or real suid */ if ((euid != uid && euid == statbuf.st_uid && statbuf.st_mode & S_ISUID) || (egid != gid && egid == statbuf.st_gid && statbuf.st_mode & S_ISGID) @@ -1763,21 +2215,25 @@ FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n"); static void find_beginning() { - register char *s; + register char *s, *s2; /* skip forward in input to the real script? */ - taint_not("-x"); + forbid_setid("-x"); while (doextract) { if ((s = sv_gets(linestr, rsfp, 0)) == Nullch) croak("No Perl script found in input\n"); - if (*s == '#' && s[1] == '!' && instr(s,"perl")) { - ungetc('\n',rsfp); /* to keep line count right */ + if (*s == '#' && s[1] == '!' && (s = instr(s,"perl"))) { + PerlIO_ungetc(rsfp, '\n'); /* to keep line count right */ doextract = FALSE; - if (s = instr(s,"perl -")) { - s += 6; - /*SUPPRESS 530*/ - while (s = moreswitches(s)) ; + while (*s && !(isSPACE (*s) || *s == '#')) s++; + s2 = s; + while (*s == ' ' || *s == '\t') s++; + if (*s++ == '-') { + while (isDIGIT(s2[-1]) || strchr("-._", s2[-1])) s2--; + if (strnEQ(s2-4,"perl",4)) + /*SUPPRESS 530*/ + while (s = moreswitches(s)) ; } if (cddir && chdir(cddir) < 0) croak("Can't chdir to %s",cddir); @@ -1800,6 +2256,16 @@ init_ids() } static void +forbid_setid(s) +char *s; +{ + if (euid != uid) + croak("No %s allowed while running setuid", s); + if (egid != gid) + croak("No %s allowed while running setgid", s); +} + +static void init_debugger() { curstash = debstash; @@ -1820,31 +2286,15 @@ init_debugger() static void init_stacks() { - stack = newAV(); - mainstack = stack; /* remember in case we switch stacks */ - AvREAL_off(stack); /* not a real array */ - av_extend(stack,127); + curstack = newAV(); + mainstack = curstack; /* remember in case we switch stacks */ + AvREAL_off(curstack); /* not a real array */ + av_extend(curstack,127); - stack_base = AvARRAY(stack); + stack_base = AvARRAY(curstack); stack_sp = stack_base; stack_max = stack_base + 127; - New(54,markstack,64,I32); - markstack_ptr = markstack; - markstack_max = markstack + 64; - - New(54,scopestack,32,I32); - scopestack_ix = 0; - scopestack_max = 32; - - New(54,savestack,128,ANY); - savestack_ix = 0; - savestack_max = 128; - - New(54,retstack,16,OP*); - retstack_ix = 0; - retstack_max = 16; - cxstack_max = 8192 / sizeof(CONTEXT) - 2; /* Use most of 8K. */ New(50,cxstack,cxstack_max + 1,CONTEXT); cxstack_ix = -1; @@ -1857,14 +2307,63 @@ init_stacks() New(51,debname,128,char); New(52,debdelim,128,char); } ) + + /* + * The following stacks almost certainly should be per-interpreter, + * but for now they're not. XXX + */ + + if (markstack) { + markstack_ptr = markstack; + } else { + New(54,markstack,64,I32); + markstack_ptr = markstack; + markstack_max = markstack + 64; + } + + if (scopestack) { + scopestack_ix = 0; + } else { + New(54,scopestack,32,I32); + scopestack_ix = 0; + scopestack_max = 32; + } + + if (savestack) { + savestack_ix = 0; + } else { + New(54,savestack,128,ANY); + savestack_ix = 0; + savestack_max = 128; + } + + if (retstack) { + retstack_ix = 0; + } else { + New(54,retstack,16,OP*); + retstack_ix = 0; + retstack_max = 16; + } +} + +static void +nuke_stacks() +{ + Safefree(cxstack); + Safefree(tmps_stack); + DEBUG( { + Safefree(debname); + Safefree(debdelim); + } ) } -static FILE *tmpfp; /* moved outside init_lexer() because of UNICOS bug */ +static PerlIO *tmpfp; /* moved outside init_lexer() because of UNICOS bug */ + static void init_lexer() { tmpfp = rsfp; - + rsfp = Nullfp; lex_start(linestr); rsfp = tmpfp; subname = newSVpv("main",4); @@ -1880,14 +2379,14 @@ init_predump_symbols() stdingv = gv_fetchpv("STDIN",TRUE, SVt_PVIO); GvMULTI_on(stdingv); - IoIFP(GvIOp(stdingv)) = stdin; + IoIFP(GvIOp(stdingv)) = PerlIO_stdin(); tmpgv = gv_fetchpv("stdin",TRUE, SVt_PV); GvMULTI_on(tmpgv); GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(stdingv)); tmpgv = gv_fetchpv("STDOUT",TRUE, SVt_PVIO); GvMULTI_on(tmpgv); - IoOFP(GvIOp(tmpgv)) = IoIFP(GvIOp(tmpgv)) = stdout; + IoOFP(GvIOp(tmpgv)) = IoIFP(GvIOp(tmpgv)) = PerlIO_stdout(); setdefout(tmpgv); tmpgv = gv_fetchpv("stdout",TRUE, SVt_PV); GvMULTI_on(tmpgv); @@ -1895,14 +2394,15 @@ init_predump_symbols() othergv = gv_fetchpv("STDERR",TRUE, SVt_PVIO); GvMULTI_on(othergv); - IoOFP(GvIOp(othergv)) = IoIFP(GvIOp(othergv)) = stderr; + IoOFP(GvIOp(othergv)) = IoIFP(GvIOp(othergv)) = PerlIO_stderr(); tmpgv = gv_fetchpv("stderr",TRUE, SVt_PV); GvMULTI_on(tmpgv); GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(othergv)); statname = NEWSV(66,0); /* last filename we did stat on */ - osname = savepv(OSNAME); + if (!osname) + osname = savepv(OSNAME); } static void @@ -1940,13 +2440,11 @@ register char **env; sv_setpvn(bodytarget, "", 0); formtarget = bodytarget; - tainted = 1; + TAINT; if (tmpgv = gv_fetchpv("0",TRUE, SVt_PV)) { sv_setpv(GvSV(tmpgv),origfilename); magicname("0", "0", 1); } - if (tmpgv = gv_fetchpv("\024",TRUE, SVt_PV)) - time(&basetime); if (tmpgv = gv_fetchpv("\030",TRUE, SVt_PV)) sv_setpv(GvSV(tmpgv),origargv[0]); if (argvgv = gv_fetchpv("ARGV",TRUE, SVt_PVAV)) { @@ -1961,7 +2459,7 @@ register char **env; HV *hv; GvMULTI_on(envgv); hv = GvHVn(envgv); - hv_clear(hv); + hv_magic(hv, envgv, 'E'); #ifndef VMS /* VMS doesn't have environ array */ /* Note that if the supplied env parameter is actually a copy of the global environ then it may now point to free'd memory @@ -1970,29 +2468,31 @@ register char **env; */ if (!env) env = environ; - if (env != environ) { + if (env != environ) environ[0] = Nullch; - hv_magic(hv, envgv, 'E'); - } for (; *env; env++) { if (!(s = strchr(*env,'='))) continue; *s++ = '\0'; +#ifdef WIN32 + (void)strupr(*env); +#endif sv = newSVpv(s--,0); - sv_magic(sv, sv, 'e', *env, s - *env); (void)hv_store(hv, *env, s - *env, sv, 0); *s = '='; +#if defined(__BORLANDC__) && defined(USE_WIN32_RTL_ENV) + /* Sins of the RTL. See note in my_setenv(). */ + (void)putenv(savepv(*env)); +#endif } #endif #ifdef DYNAMIC_ENV_FETCH HvNAME(hv) = savepv(ENV_HV_NAME); #endif - hv_magic(hv, envgv, 'E'); } - tainted = 0; + TAINT_NOT; if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV)) - sv_setiv(GvSV(tmpgv),(I32)getpid()); - + sv_setiv(GvSV(tmpgv), (IV)getpid()); } static void @@ -2000,86 +2500,208 @@ init_perllib() { char *s; if (!tainting) { +#ifndef VMS s = getenv("PERL5LIB"); if (s) - incpush(s); + incpush(s, TRUE); else - incpush(getenv("PERLLIB")); + incpush(getenv("PERLLIB"), FALSE); +#else /* VMS */ + /* Treat PERL5?LIB as a possible search list logical name -- the + * "natural" VMS idiom for a Unix path string. We allow each + * element to be a set of |-separated directories for compatibility. + */ + char buf[256]; + int idx = 0; + if (my_trnlnm("PERL5LIB",buf,0)) + do { incpush(buf,TRUE); } while (my_trnlnm("PERL5LIB",buf,++idx)); + else + while (my_trnlnm("PERLLIB",buf,idx++)) incpush(buf,FALSE); +#endif /* VMS */ } +/* Use the ~-expanded versions of APPLLIB (undocumented), + ARCHLIB PRIVLIB SITEARCH SITELIB and OLDARCHLIB +*/ #ifdef APPLLIB_EXP - incpush(APPLLIB_EXP); + incpush(APPLLIB_EXP, FALSE); #endif #ifdef ARCHLIB_EXP - incpush(ARCHLIB_EXP); + incpush(ARCHLIB_EXP, FALSE); #endif #ifndef PRIVLIB_EXP #define PRIVLIB_EXP "/usr/local/lib/perl5:/usr/local/lib/perl" #endif - incpush(PRIVLIB_EXP); + incpush(PRIVLIB_EXP, FALSE); #ifdef SITEARCH_EXP - incpush(SITEARCH_EXP); + incpush(SITEARCH_EXP, FALSE); #endif #ifdef SITELIB_EXP - incpush(SITELIB_EXP); + incpush(SITELIB_EXP, FALSE); #endif #ifdef OLDARCHLIB_EXP /* 5.00[01] compatibility */ - incpush(OLDARCHLIB_EXP); + incpush(OLDARCHLIB_EXP, FALSE); #endif if (!tainting) - incpush("."); + incpush(".", FALSE); +} + +#if defined(DOSISH) +# define PERLLIB_SEP ';' +#else +# if defined(VMS) +# define PERLLIB_SEP '|' +# else +# define PERLLIB_SEP ':' +# endif +#endif +#ifndef PERLLIB_MANGLE +# define PERLLIB_MANGLE(s,n) (s) +#endif + +static void +incpush(p, addsubdirs) +char *p; +int addsubdirs; +{ + SV *subdir = Nullsv; + static char *archpat_auto; + + if (!p) + return; + + if (addsubdirs) { + subdir = newSV(0); + if (!archpat_auto) { + STRLEN len = (sizeof(ARCHNAME) + strlen(patchlevel) + + sizeof("//auto")); + New(55, archpat_auto, len, char); + sprintf(archpat_auto, "/%s/%s/auto", ARCHNAME, patchlevel); +#ifdef VMS + for (len = sizeof(ARCHNAME) + 2; + archpat_auto[len] != '\0' && archpat_auto[len] != '/'; len++) + if (archpat_auto[len] == '.') archpat_auto[len] = '_'; +#endif + } + } + + /* Break at all separators */ + while (p && *p) { + SV *libdir = newSV(0); + char *s; + + /* skip any consecutive separators */ + while ( *p == PERLLIB_SEP ) { + /* Uncomment the next line for PATH semantics */ + /* av_push(GvAVn(incgv), newSVpv(".", 1)); */ + p++; + } + + if ( (s = strchr(p, PERLLIB_SEP)) != Nullch ) { + sv_setpvn(libdir, PERLLIB_MANGLE(p, (STRLEN)(s - p)), + (STRLEN)(s - p)); + p = s + 1; + } + else { + sv_setpv(libdir, PERLLIB_MANGLE(p, 0)); + p = Nullch; /* break out */ + } + + /* + * BEFORE pushing libdir onto @INC we may first push version- and + * archname-specific sub-directories. + */ + if (addsubdirs) { + struct stat tmpstatbuf; +#ifdef VMS + char *unix; + STRLEN len; + + if ((unix = tounixspec_ts(SvPV(libdir,na),Nullch)) != Nullch) { + len = strlen(unix); + while (unix[len-1] == '/') len--; /* Cosmetic */ + sv_usepvn(libdir,unix,len); + } + else + PerlIO_printf(PerlIO_stderr(), + "Failed to unixify @INC element \"%s\"\n", + SvPV(libdir,na)); +#endif + /* .../archname/version if -d .../archname/version/auto */ + sv_setsv(subdir, libdir); + sv_catpv(subdir, archpat_auto); + if (Stat(SvPVX(subdir), &tmpstatbuf) >= 0 && + S_ISDIR(tmpstatbuf.st_mode)) + av_push(GvAVn(incgv), + newSVpv(SvPVX(subdir), SvCUR(subdir) - sizeof "auto")); + + /* .../archname if -d .../archname/auto */ + sv_insert(subdir, SvCUR(libdir) + sizeof(ARCHNAME), + strlen(patchlevel) + 1, "", 0); + if (Stat(SvPVX(subdir), &tmpstatbuf) >= 0 && + S_ISDIR(tmpstatbuf.st_mode)) + av_push(GvAVn(incgv), + newSVpv(SvPVX(subdir), SvCUR(subdir) - sizeof "auto")); + } + + /* finally push this lib directory on the end of @INC */ + av_push(GvAVn(incgv), libdir); + } + + SvREFCNT_dec(subdir); } void -calllist(list) +call_list(oldscope, list) +I32 oldscope; AV* list; { - Sigjmp_buf oldtop; - STRLEN len; line_t oldline = curcop->cop_line; - - Copy(top_env, oldtop, 1, Sigjmp_buf); + STRLEN len; + dJMPENV; + int ret; while (AvFILL(list) >= 0) { CV *cv = (CV*)av_shift(list); SAVEFREESV(cv); - switch (Sigsetjmp(top_env,1)) { + JMPENV_PUSH(ret); + switch (ret) { case 0: { SV* atsv = GvSV(errgv); PUSHMARK(stack_sp); perl_call_sv((SV*)cv, G_EVAL|G_DISCARD); (void)SvPV(atsv, len); if (len) { - Copy(oldtop, top_env, 1, Sigjmp_buf); + JMPENV_POP; curcop = &compiling; curcop->cop_line = oldline; if (list == beginav) sv_catpv(atsv, "BEGIN failed--compilation aborted"); else sv_catpv(atsv, "END failed--cleanup aborted"); + while (scopestack_ix > oldscope) + LEAVE; croak("%s", SvPVX(atsv)); } } break; case 1: -#ifdef VMS - statusvalue = 255; /* XXX I don't think we use 1 anymore. */ -#else - statusvalue = 1; -#endif + STATUS_ALL_FAILURE; /* FALL THROUGH */ case 2: /* my_exit() was called */ + while (scopestack_ix > oldscope) + LEAVE; + FREETMPS; curstash = defstash; if (endav) - calllist(endav); - FREETMPS; - Copy(oldtop, top_env, 1, Sigjmp_buf); + call_list(oldscope, endav); + JMPENV_POP; curcop = &compiling; curcop->cop_line = oldline; if (statusvalue) { @@ -2088,22 +2710,87 @@ AV* list; else croak("END failed--cleanup aborted"); } - my_exit(statusvalue); + my_exit_jump(); /* NOTREACHED */ - return; case 3: if (!restartop) { - fprintf(stderr, "panic: restartop\n"); + PerlIO_printf(PerlIO_stderr(), "panic: restartop\n"); FREETMPS; break; } - Copy(oldtop, top_env, 1, Sigjmp_buf); + JMPENV_POP; curcop = &compiling; curcop->cop_line = oldline; - Siglongjmp(top_env, 3); + JMPENV_JUMP(3); } + JMPENV_POP; } +} - Copy(oldtop, top_env, 1, Sigjmp_buf); +void +my_exit(status) +U32 status; +{ + switch (status) { + case 0: + STATUS_ALL_SUCCESS; + break; + case 1: + STATUS_ALL_FAILURE; + break; + default: + STATUS_NATIVE_SET(status); + break; + } + my_exit_jump(); } +void +my_failure_exit() +{ +#ifdef VMS + if (vaxc$errno & 1) { + if (STATUS_NATIVE & 1) /* fortuitiously includes "-1" */ + STATUS_NATIVE_SET(44); + } + else { + if (!vaxc$errno && errno) /* unlikely */ + STATUS_NATIVE_SET(44); + else + STATUS_NATIVE_SET(vaxc$errno); + } +#else + if (errno & 255) + STATUS_POSIX_SET(errno); + else if (STATUS_POSIX == 0) + STATUS_POSIX_SET(255); +#endif + my_exit_jump(); +} + +static void +my_exit_jump() +{ + register CONTEXT *cx; + I32 gimme; + SV **newsp; + + if (e_tmpname) { + if (e_fp) { + PerlIO_close(e_fp); + e_fp = Nullfp; + } + (void)UNLINK(e_tmpname); + Safefree(e_tmpname); + e_tmpname = Nullch; + } + + if (cxstack_ix >= 0) { + if (cxstack_ix > 0) + dounwind(0); + POPBLOCK(cx,curpm); + LEAVE; + } + + JMPENV_JUMP(2); +} diff --git a/gnu/usr.bin/perl/perl.h b/gnu/usr.bin/perl/perl.h index bfb921034c8..fefceeda816 100644 --- a/gnu/usr.bin/perl/perl.h +++ b/gnu/usr.bin/perl/perl.h @@ -1,6 +1,6 @@ /* perl.h * - * Copyright (c) 1987-1994, Larry Wall + * Copyright (c) 1987-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -10,6 +10,25 @@ #define H_PERL 1 #define OVERLOAD +#ifdef PERL_FOR_X2P +/* + * This file is being used for x2p stuff. + * Above symbol is defined via -D in 'x2p/Makefile.SH' + * Decouple x2p stuff from some of perls more extreme eccentricities. + */ +#undef EMBED +#undef NO_EMBED +#define NO_EMBED +#undef MULTIPLICITY +#undef USE_STDIO +#define USE_STDIO +#endif /* PERL_FOR_X2P */ + +#define VOIDUSED 1 +#include "config.h" + +#include "embed.h" + /* * STMT_START { statements; } STMT_END; * can be used as a single statement, as in @@ -18,7 +37,7 @@ * Trying to select a version that gives no warnings... */ #if !(defined(STMT_START) && defined(STMT_END)) -# if defined(__GNUC__) && !defined(__STRICT_ANSI__) +# if defined(__GNUC__) && !defined(__STRICT_ANSI__) && !defined(__cplusplus) # define STMT_START (void)( /* gcc supports ``({ STATEMENTS; })'' */ # define STMT_END ) # else @@ -33,10 +52,15 @@ # endif #endif -#include "embed.h" - -#define VOIDUSED 1 -#include "config.h" +/* + * SOFT_CAST can be used for args to prototyped functions to retain some + * type checking; it only casts if the compiler does not know prototypes. + */ +#if defined(CAN_PROTOTYPE) && defined(DEBUGGING_COMPILE) +#define SOFT_CAST(type) +#else +#define SOFT_CAST(type) (type) +#endif #ifndef BYTEORDER # define BYTEORDER 0x1234 @@ -56,7 +80,7 @@ */ /* define this once if either system, instead of cluttering up the src */ -#if defined(MSDOS) || defined(atarist) +#if defined(MSDOS) || defined(atarist) || defined(WIN32) #define DOSISH 1 #endif @@ -64,6 +88,10 @@ # define STANDARD_C 1 #endif +#if defined(__cplusplus) || defined(WIN32) +# define DONT_DECLARE_STD 1 +#endif + #if defined(HASVOLATILE) || defined(STANDARD_C) # ifdef __cplusplus # define VOL // to temporarily suppress warnings @@ -74,47 +102,117 @@ # define VOL #endif -#define TAINT_IF(c) (tainted |= (c)) -#define TAINT_NOT (tainted = 0) -#define TAINT_PROPER(s) if (tainting) taint_proper(no_security, s) -#define TAINT_ENV() if (tainting) taint_env() +#define TAINT (tainted = TRUE) +#define TAINT_NOT (tainted = FALSE) +#define TAINT_IF(c) if (c) { tainted = TRUE; } +#define TAINT_ENV() if (tainting) { taint_env(); } +#define TAINT_PROPER(s) if (tainting) { taint_proper(no_security, s); } -#ifdef USE_BSDPGRP -# ifdef HAS_GETPGRP -# define BSD_GETPGRP(pid) getpgrp((pid)) -# endif -# ifdef HAS_SETPGRP -# define BSD_SETPGRP(pid, pgrp) setpgrp((pid), (pgrp)) -# endif +/* XXX All process group stuff is handled in pp_sys.c. Should these + defines move there? If so, I could simplify this a lot. --AD 9/96. +*/ +/* Process group stuff changed from traditional BSD to POSIX. + perlfunc.pod documents the traditional BSD-style syntax, so we'll + try to preserve that, if possible. +*/ +#ifdef HAS_SETPGID +# define BSD_SETPGRP(pid, pgrp) setpgid((pid), (pgrp)) #else -# ifdef HAS_GETPGRP2 -# define BSD_GETPGRP(pid) getpgrp2((pid)) -# ifndef HAS_GETPGRP -# define HAS_GETPGRP -# endif -# endif -# ifdef HAS_SETPGRP2 -# define BSD_SETPGRP(pid, pgrp) setpgrp2((pid), (pgrp)) -# ifndef HAS_SETPGRP -# define HAS_SETPGRP -# endif +# if defined(HAS_SETPGRP) && defined(USE_BSD_SETPGRP) +# define BSD_SETPGRP(pid, pgrp) setpgrp((pid), (pgrp)) +# else +# ifdef HAS_SETPGRP2 /* DG/UX */ +# define BSD_SETPGRP(pid, pgrp) setpgrp2((pid), (pgrp)) +# endif +# endif +#endif +#if defined(BSD_SETPGRP) && !defined(HAS_SETPGRP) +# define HAS_SETPGRP /* Well, effectively it does . . . */ +#endif + +/* getpgid isn't POSIX, but at least Solaris and Linux have it, and it makes + our life easier :-) so we'll try it. +*/ +#ifdef HAS_GETPGID +# define BSD_GETPGRP(pid) getpgid((pid)) +#else +# if defined(HAS_GETPGRP) && defined(USE_BSD_GETPGRP) +# define BSD_GETPGRP(pid) getpgrp((pid)) +# else +# ifdef HAS_GETPGRP2 /* DG/UX */ +# define BSD_GETPGRP(pid) getpgrp2((pid)) +# endif +# endif +#endif +#if defined(BSD_GETPGRP) && !defined(HAS_GETPGRP) +# define HAS_GETPGRP /* Well, effectively it does . . . */ +#endif + +/* These are not exact synonyms, since setpgrp() and getpgrp() may + have different behaviors, but perl.h used to define USE_BSDPGRP + (prior to 5.003_05) so some extension might depend on it. +*/ +#if defined(USE_BSD_SETPGRP) || defined(USE_BSD_GETPGRP) +# ifndef USE_BSDPGRP +# define USE_BSDPGRP +# endif +#endif + +#ifndef _TYPES_ /* If types.h defines this it's easy. */ +# ifndef major /* Does everyone's types.h define this? */ +# include <sys/types.h> # endif #endif -#include <stdio.h> +#ifdef __cplusplus +# ifndef I_STDARG +# define I_STDARG 1 +# endif +#endif + +#ifdef I_STDARG +# include <stdarg.h> +#else +# ifdef I_VARARGS +# include <varargs.h> +# endif +#endif + +#include "perlio.h" + #ifdef USE_NEXT_CTYPE + +#if NX_CURRENT_COMPILER_RELEASE >= 400 +#include <objc/NXCType.h> +#else /* NX_CURRENT_COMPILER_RELEASE < 400 */ #include <appkit/NXCType.h> -#else +#endif /* NX_CURRENT_COMPILER_RELEASE >= 400 */ + +#else /* !USE_NEXT_CTYPE */ #include <ctype.h> +#endif /* USE_NEXT_CTYPE */ + +#ifdef METHOD /* Defined by OSF/1 v3.0 by ctype.h */ +#undef METHOD #endif #ifdef I_LOCALE -#include <locale.h> +# include <locale.h> #endif -#ifdef METHOD /* Defined by OSF/1 v3.0 by ctype.h */ -#undef METHOD -#endif +#if !defined(NO_LOCALE) && defined(HAS_SETLOCALE) +# define USE_LOCALE +# if !defined(NO_LOCALE_COLLATE) && defined(LC_COLLATE) \ + && defined(HAS_STRXFRM) +# define USE_LOCALE_COLLATE +# endif +# if !defined(NO_LOCALE_CTYPE) && defined(LC_CTYPE) +# define USE_LOCALE_CTYPE +# endif +# if !defined(NO_LOCALE_NUMERIC) && defined(LC_NUMERIC) +# define USE_LOCALE_NUMERIC +# endif +#endif /* !NO_LOCALE && HAS_SETLOCALE */ #include <setjmp.h> @@ -129,25 +227,46 @@ /* Use all the "standard" definitions? */ #if defined(STANDARD_C) && defined(I_STDLIB) # include <stdlib.h> -#endif /* STANDARD_C */ +#endif + +/* This comes after <stdlib.h> so we don't try to change the standard + * library prototypes; we'll use our own in proto.h instead. */ -/* Maybe this comes after <stdlib.h> so we don't try to change - the standard library prototypes?. We'll use our own in - proto.h instead. I guess. The patch had no explanation. -*/ #ifdef MYMALLOC + # ifdef HIDEMYMALLOC -# define malloc Mymalloc +# define malloc Mymalloc +# define calloc Mycalloc # define realloc Myremalloc -# define free Myfree +# define free Myfree # endif -# define safemalloc malloc +# ifdef EMBEDMYMALLOC +# define malloc Perl_malloc +# define calloc Perl_calloc +# define realloc Perl_realloc +# define free Perl_free +# endif + +# undef safemalloc +# undef safecalloc +# undef saferealloc +# undef safefree +# define safemalloc malloc +# define safecalloc calloc # define saferealloc realloc -# define safefree free -#endif +# define safefree free + +#endif /* MYMALLOC */ #define MEM_SIZE Size_t +#if defined(STANDARD_C) && defined(I_STDDEF) +# include <stddef.h> +# define STRUCT_OFFSET(s,m) offsetof(s,m) +#else +# define STRUCT_OFFSET(s,m) (Size_t)(&(((s *)0)->m)) +#endif + #if defined(I_STRING) || defined(__cplusplus) # include <string.h> #else @@ -159,10 +278,6 @@ #define strrchr rindex #endif -#if defined(mips) && defined(ultrix) && !defined(__STDC__) -# undef HAS_MEMCMP -#endif - #ifdef I_MEMORY # include <memory.h> #endif @@ -189,60 +304,71 @@ extern char *memset _((char*, int, int)); # endif # endif -# define memzero(d,l) memset(d,0,l) #else -# ifndef memzero -# ifdef HAS_BZERO -# define memzero(d,l) bzero(d,l) +# define memset(d,c,l) my_memset(d,c,l) +#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) +# else +# if defined(HAS_MEMCPY) && defined(HAS_SAFE_MEMCPY) +# define memmove(d,s,l) memcpy(d,s,l) # else -# define memzero(d,l) my_bzero(d,l) +# define memmove(d,s,l) my_bcopy(s,d,l) # endif # endif -#endif /* HAS_MEMSET */ +#endif + +#if defined(mips) && defined(ultrix) && !defined(__STDC__) +# undef HAS_MEMCMP +#endif -#ifdef HAS_MEMCMP +#if defined(HAS_MEMCMP) && defined(HAS_SANE_MEMCMP) # if !defined(STANDARD_C) && !defined(I_STRING) && !defined(I_MEMORY) # ifndef memcmp extern int memcmp _((char*, char*, int)); # endif # endif +# ifdef BUGGY_MSC + # pragma function(memcmp) +# endif #else # ifndef memcmp # define memcmp my_memcmp # endif -#endif /* HAS_MEMCMP */ - -/* XXX we prefer bcmp slightly for comparisons that don't care about ordering */ -#ifndef HAS_BCMP -# ifndef bcmp -# define bcmp(s1,s2,l) memcmp(s1,s2,l) -# endif -#endif /* HAS_BCMP */ +#endif /* HAS_MEMCMP && HAS_SANE_MEMCMP */ -#if !defined(HAS_MEMMOVE) && !defined(memmove) -# if defined(HAS_BCOPY) && defined(HAS_SAFE_BCOPY) -# define memmove(d,s,l) bcopy(s,d,l) +#ifndef memzero +# ifdef HAS_MEMSET +# define memzero(d,l) memset(d,0,l) # else -# if defined(HAS_MEMCPY) && defined(HAS_SAFE_MEMCPY) -# define memmove(d,s,l) memcpy(d,s,l) +# ifdef HAS_BZERO +# define memzero(d,l) bzero(d,l) # else -# define memmove(d,s,l) my_bcopy(s,d,l) +# define memzero(d,l) my_bzero(d,l) # endif # endif #endif -#ifndef _TYPES_ /* If types.h defines this it's easy. */ -# ifndef major /* Does everyone's types.h define this? */ -# include <sys/types.h> +#ifndef HAS_BCMP +# ifndef bcmp +# define bcmp(s1,s2,l) memcmp(s1,s2,l) # endif -#endif +#endif /* !HAS_BCMP */ #ifdef I_NETINET_IN # include <netinet/in.h> #endif +#if defined(SF_APPEND) && defined(USE_SFIO) && defined(I_SFIO) +/* <sfio.h> defines SF_APPEND and <sys/stat.h> might define SF_APPEND + * (the neo-BSD seem to do this). */ +# undef SF_APPEND +#endif + #ifdef I_SYS_STAT -#include <sys/stat.h> +# include <sys/stat.h> #endif /* The stat macros for Amdahl UTS, Unisoft System V/88 (and derivatives @@ -277,10 +403,8 @@ # endif #endif -#ifndef MSDOS -# if defined(HAS_TIMES) && defined(I_SYS_TIMES) +#if defined(HAS_TIMES) && defined(I_SYS_TIMES) # include <sys/times.h> -# endif #endif #if defined(HAS_STRERROR) && (!defined(HAS_MKDIR) || !defined(HAS_RMDIR)) @@ -299,27 +423,28 @@ # include <net/errno.h> # endif #endif -#ifndef VMS -# define FIXSTATUS(sts) (U_L((sts) & 0xffff)) -# define SHIFTSTATUS(sts) ((sts) >> 8) -# define SETERRNO(errcode,vmserrcode) errno = (errcode) + +#ifdef VMS +# define SETERRNO(errcode,vmserrcode) \ + STMT_START { \ + set_errno(errcode); \ + set_vaxc_errno(vmserrcode); \ + } STMT_END #else -# define FIXSTATUS(sts) (U_L(sts)) -# define SHIFTSTATUS(sts) (sts) -# define SETERRNO(errcode,vmserrcode) STMT_START {set_errno(errcode); set_vaxc_errno(vmserrcode);} STMT_END +# define SETERRNO(errcode,vmserrcode) errno = (errcode) #endif -#ifndef MSDOS -# ifndef errno +#ifndef errno extern int errno; /* ANSI allows errno to be an lvalue expr */ -# endif #endif #ifdef HAS_STRERROR # ifdef VMS char *strerror _((int,...)); # else +#ifndef DONT_DECLARE_STD char *strerror _((int)); +#endif # endif # ifndef Strerror # define Strerror strerror @@ -493,29 +618,231 @@ # define SLOPPYDIVIDE #endif -#if defined(cray) || defined(convex) || defined (uts) || BYTEORDER > 0xffff -# define HAS_QUAD -#endif - #ifdef UV #undef UV #endif -#ifdef HAS_QUAD -# ifdef cray -# define Quad_t int +/* XXX QUAD stuff is not currently supported on most systems. + Specifically, perl internals don't support long long. Among + the many problems is that some compilers support long long, + but the underlying library functions (such as sprintf) don't. + Some things do work (such as quad pack/unpack on convex); + also some systems use long long for the fpos_t typedef. That + seems to work too. + + The IV type is supposed to be long enough to hold any integral + value or a pointer. + --Andy Dougherty August 1996 +*/ + +#ifdef cray +# define Quad_t int +#else +# ifdef convex +# define Quad_t long long # else -# if defined(convex) || defined (uts) -# define Quad_t long long -# else +# if BYTEORDER > 0xFFFF # define Quad_t long # endif # endif +#endif + +#ifdef Quad_t +# define HAS_QUAD typedef Quad_t IV; typedef unsigned Quad_t UV; +# define IV_MAX PERL_QUAD_MAX +# define IV_MIN PERL_QUAD_MIN +# define UV_MAX PERL_UQUAD_MAX +# define UV_MIN PERL_UQUAD_MIN #else typedef long IV; typedef unsigned long UV; +# define IV_MAX PERL_LONG_MAX +# define IV_MIN PERL_LONG_MIN +# define UV_MAX PERL_ULONG_MAX +# define UV_MIN PERL_ULONG_MIN +#endif + +/* Previously these definitions used hardcoded figures. + * It is hoped these formula are more portable, although + * no data one way or another is presently known to me. + * The "PERL_" names are used because these calculated constants + * do not meet the ANSI requirements for LONG_MAX, etc., which + * need to be constants acceptable to #if - kja + * define PERL_LONG_MAX 2147483647L + * define PERL_LONG_MIN (-LONG_MAX - 1) + * define PERL ULONG_MAX 4294967295L + */ + +#ifdef I_LIMITS /* Needed for cast_xxx() functions below. */ +# include <limits.h> +#else +#ifdef I_VALUES +# include <values.h> +#endif +#endif + +/* + * Try to figure out max and min values for the integral types. THE CORRECT + * SOLUTION TO THIS MESS: ADAPT enquire.c FROM GCC INTO CONFIGURE. The + * following hacks are used if neither limits.h or values.h provide them: + * U<TYPE>_MAX: for types >= int: ~(unsigned TYPE)0 + * for types < int: (unsigned TYPE)~(unsigned)0 + * The argument to ~ must be unsigned so that later signed->unsigned + * conversion can't modify the value's bit pattern (e.g. -0 -> +0), + * and it must not be smaller than int because ~ does integral promotion. + * <type>_MAX: (<type>) (U<type>_MAX >> 1) + * <type>_MIN: -<type>_MAX - <is_twos_complement_architecture: (3 & -1) == 3>. + * The latter is a hack which happens to work on some machines but + * does *not* catch any random system, or things like integer types + * with NaN if that is possible. + * + * All of the types are explicitly cast to prevent accidental loss of + * numeric range, and in the hope that they will be less likely to confuse + * over-eager optimizers. + * + */ + +#define PERL_UCHAR_MIN ((unsigned char)0) + +#ifdef UCHAR_MAX +# define PERL_UCHAR_MAX ((unsigned char)UCHAR_MAX) +#else +# ifdef MAXUCHAR +# define PERL_UCHAR_MAX ((unsigned char)MAXUCHAR) +# else +# define PERL_UCHAR_MAX ((unsigned char)~(unsigned)0) +# endif +#endif + +/* + * CHAR_MIN and CHAR_MAX are not included here, as the (char) type may be + * ambiguous. It may be equivalent to (signed char) or (unsigned char) + * depending on local options. Until Configure detects this (or at least + * detects whether the "signed" keyword is available) the CHAR ranges + * will not be included. UCHAR functions normally. + * - kja + */ + +#define PERL_USHORT_MIN ((unsigned short)0) + +#ifdef USHORT_MAX +# define PERL_USHORT_MAX ((unsigned short)USHORT_MAX) +#else +# ifdef MAXUSHORT +# define PERL_USHORT_MAX ((unsigned short)MAXUSHORT) +# else +# define PERL_USHORT_MAX ((unsigned short)~(unsigned)0) +# endif +#endif + +#ifdef SHORT_MAX +# define PERL_SHORT_MAX ((short)SHORT_MAX) +#else +# ifdef MAXSHORT /* Often used in <values.h> */ +# define PERL_SHORT_MAX ((short)MAXSHORT) +# else +# define PERL_SHORT_MAX ((short) (PERL_USHORT_MAX >> 1)) +# endif +#endif + +#ifdef SHORT_MIN +# define PERL_SHORT_MIN ((short)SHORT_MIN) +#else +# ifdef MINSHORT +# define PERL_SHORT_MIN ((short)MINSHORT) +# else +# define PERL_SHORT_MIN (-PERL_SHORT_MAX - ((3 & -1) == 3)) +# endif +#endif + +#ifdef UINT_MAX +# define PERL_UINT_MAX ((unsigned int)UINT_MAX) +#else +# ifdef MAXUINT +# define PERL_UINT_MAX ((unsigned int)MAXUINT) +# else +# define PERL_UINT_MAX (~(unsigned int)0) +# endif +#endif + +#define PERL_UINT_MIN ((unsigned int)0) + +#ifdef INT_MAX +# define PERL_INT_MAX ((int)INT_MAX) +#else +# ifdef MAXINT /* Often used in <values.h> */ +# define PERL_INT_MAX ((int)MAXINT) +# else +# define PERL_INT_MAX ((int)(PERL_UINT_MAX >> 1)) +# endif +#endif + +#ifdef INT_MIN +# define PERL_INT_MIN ((int)INT_MIN) +#else +# ifdef MININT +# define PERL_INT_MIN ((int)MININT) +# else +# define PERL_INT_MIN (-PERL_INT_MAX - ((3 & -1) == 3)) +# endif +#endif + +#ifdef ULONG_MAX +# define PERL_ULONG_MAX ((unsigned long)ULONG_MAX) +#else +# ifdef MAXULONG +# define PERL_ULONG_MAX ((unsigned long)MAXULONG) +# else +# define PERL_ULONG_MAX (~(unsigned long)0) +# endif +#endif + +#define PERL_ULONG_MIN ((unsigned long)0L) + +#ifdef LONG_MAX +# define PERL_LONG_MAX ((long)LONG_MAX) +#else +# ifdef MAXLONG /* Often used in <values.h> */ +# define PERL_LONG_MAX ((long)MAXLONG) +# else +# define PERL_LONG_MAX ((long) (PERL_ULONG_MAX >> 1)) +# endif +#endif + +#ifdef LONG_MIN +# define PERL_LONG_MIN ((long)LONG_MIN) +#else +# ifdef MINLONG +# define PERL_LONG_MIN ((long)MINLONG) +# else +# define PERL_LONG_MIN (-PERL_LONG_MAX - ((3 & -1) == 3)) +# endif +#endif + +#ifdef HAS_QUAD + +# ifdef UQUAD_MAX +# define PERL_UQUAD_MAX ((UV)UQUAD_MAX) +# else +# define PERL_UQUAD_MAX (~(UV)0) +# endif + +# define PERL_UQUAD_MIN ((UV)0) + +# ifdef QUAD_MAX +# define PERL_QUAD_MAX ((IV)QUAD_MAX) +# else +# define PERL_QUAD_MAX ((IV) (PERL_UQUAD_MAX >> 1)) +# endif + +# ifdef QUAD_MIN +# define PERL_QUAD_MIN ((IV)QUAD_MIN) +# else +# define PERL_QUAD_MIN (-PERL_QUAD_MAX - ((3 & -1) == 3)) +# endif + #endif typedef MEM_SIZE STRLEN; @@ -535,14 +862,16 @@ typedef struct loop LOOP; typedef struct Outrec Outrec; typedef struct interpreter PerlInterpreter; -typedef struct ff FF; +#ifndef __BORLANDC__ +typedef struct ff FF; /* XXX not defined anywhere, should go? */ +#endif typedef struct sv SV; typedef struct av AV; typedef struct hv HV; typedef struct cv CV; typedef struct regexp REGEXP; typedef struct gp GP; -typedef struct sv GV; +typedef struct gv GV; typedef struct io IO; typedef struct context CONTEXT; typedef struct block BLOCK; @@ -551,6 +880,7 @@ typedef struct magic MAGIC; typedef struct xrv XRV; typedef struct xpv XPV; typedef struct xpviv XPVIV; +typedef struct xpvuv XPVUV; typedef struct xpvnv XPVNV; typedef struct xpvmg XPVMG; typedef struct xpvlv XPVLV; @@ -581,12 +911,71 @@ typedef I32 (*filter_t) _((int, SV *, int)); # if defined(VMS) # include "vmsish.h" # else -# include "unixish.h" +# if defined(PLAN9) +# include "./plan9/plan9ish.h" +# else +# include "unixish.h" +# endif # endif #endif - -#ifndef HAS_PAUSE -#define pause() sleep((32767<<16)+32767) + +#ifdef VMS +# define STATUS_NATIVE statusvalue_vms +# define STATUS_NATIVE_EXPORT \ + ((I32)statusvalue_vms == -1 ? 44 : statusvalue_vms) +# define STATUS_NATIVE_SET(n) \ + STMT_START { \ + statusvalue_vms = (n); \ + if ((I32)statusvalue_vms == -1) \ + statusvalue = -1; \ + else if (statusvalue_vms & STS$M_SUCCESS) \ + statusvalue = 0; \ + else if ((statusvalue_vms & STS$M_SEVERITY) == 0) \ + statusvalue = 1 << 8; \ + else \ + statusvalue = (statusvalue_vms & STS$M_SEVERITY) << 8; \ + } STMT_END +# define STATUS_POSIX statusvalue +# ifdef VMSISH_STATUS +# define STATUS_CURRENT (VMSISH_STATUS ? STATUS_NATIVE : STATUS_POSIX) +# else +# define STATUS_CURRENT STATUS_POSIX +# endif +# define STATUS_POSIX_SET(n) \ + STMT_START { \ + statusvalue = (n); \ + if (statusvalue != -1) { \ + statusvalue &= 0xFFFF; \ + statusvalue_vms = statusvalue ? 44 : 1; \ + } \ + else statusvalue_vms = -1; \ + } STMT_END +# define STATUS_ALL_SUCCESS (statusvalue = 0, statusvalue_vms = 1) +# define STATUS_ALL_FAILURE (statusvalue = 1, statusvalue_vms = 44) +#else +# define STATUS_NATIVE STATUS_POSIX +# define STATUS_NATIVE_EXPORT STATUS_POSIX +# define STATUS_NATIVE_SET STATUS_POSIX_SET +# define STATUS_POSIX statusvalue +# define STATUS_POSIX_SET(n) \ + STMT_START { \ + statusvalue = (n); \ + if (statusvalue != -1) \ + statusvalue &= 0xFFFF; \ + } STMT_END +# define STATUS_CURRENT STATUS_POSIX +# define STATUS_ALL_SUCCESS (statusvalue = 0) +# define STATUS_ALL_FAILURE (statusvalue = 1) +#endif + +/* Some unistd.h's give a prototype for pause() even though + HAS_PAUSE ends up undefined. This causes the #define + below to be rejected by the compmiler. Sigh. +*/ +#ifdef HAS_PAUSE +#define Pause pause +#else +#define Pause() sleep((32767<<16)+32767) #endif #ifndef IOCPARM_LEN @@ -607,6 +996,11 @@ union any { void (*any_dptr) _((void*)); }; +/* Work around some cygwin32 problems with importing global symbols */ +#if defined(CYGWIN32) && defined(DLLIMPORT) +# include "cw32imp.h" +#endif + #include "regexp.h" #include "sv.h" #include "util.h" @@ -689,7 +1083,13 @@ EXT char Error[1]; #define U_I(what) ((unsigned int)(what)) #define U_L(what) ((U32)(what)) #else +# ifdef __cplusplus + extern "C" { +# endif U32 cast_ulong _((double)); +# ifdef __cplusplus + } +# endif #define U_S(what) ((U16)cast_ulong((double)(what))) #define U_I(what) ((unsigned int)cast_ulong((double)(what))) #define U_L(what) (cast_ulong((double)(what))) @@ -700,11 +1100,17 @@ U32 cast_ulong _((double)); #define I_V(what) ((IV)(what)) #define U_V(what) ((UV)(what)) #else +# ifdef __cplusplus + extern "C" { +# endif I32 cast_i32 _((double)); -#define I_32(what) (cast_i32((double)(what))) IV cast_iv _((double)); -#define I_V(what) (cast_iv((double)(what))) UV cast_uv _((double)); +# ifdef __cplusplus + } +# endif +#define I_32(what) (cast_i32((double)(what))) +#define I_V(what) (cast_iv((double)(what))) #define U_V(what) (cast_uv((double)(what))) #endif @@ -730,6 +1136,9 @@ Gid_t getegid _((void)); #endif #ifdef DEBUGGING +#ifndef Perl_debug_log +#define Perl_debug_log PerlIO_stderr() +#endif #define YYDEBUG 1 #define DEB(a) a #define DEBUG(a) if (debug) a @@ -740,7 +1149,7 @@ Gid_t getegid _((void)); #define DEBUG_o(a) if (debug & 16) a #define DEBUG_c(a) if (debug & 32) a #define DEBUG_P(a) if (debug & 64) a -#define DEBUG_m(a) if (debug & 128) a +#define DEBUG_m(a) if (curinterp && debug & 128) a #define DEBUG_f(a) if (debug & 256) a #define DEBUG_r(a) if (debug & 512) a #define DEBUG_x(a) if (debug & 1024) a @@ -771,12 +1180,14 @@ Gid_t getegid _((void)); #endif #define YYMAXDEPTH 300 +#ifndef assert /* <assert.h> might have been included somehow */ #define assert(what) DEB( { \ if (!(what)) { \ croak("Assertion failed: file \"%s\", line %d", \ __FILE__, __LINE__); \ exit(1); \ }}) +#endif struct ufuncs { I32 (*uf_val)_((IV, SV*)); @@ -785,7 +1196,7 @@ struct ufuncs { }; /* Fix these up for __STDC__ */ -#ifndef __cplusplus +#ifndef DONT_DECLARE_STD char *mktemp _((char*)); double atof _((const char*)); #endif @@ -807,7 +1218,10 @@ char *strcpy(), *strcat(); # endif double exp _((double)); double log _((double)); + double log10 _((double)); double sqrt _((double)); + double frexp _((double,int*)); + double ldexp _((double,int)); double modf _((double,double*)); double sin _((double)); double cos _((double)); @@ -819,9 +1233,17 @@ char *strcpy(), *strcat(); #endif #ifndef __cplusplus +#ifdef __NeXT__ /* or whatever catches all NeXTs */ +char *crypt (); /* Maybe more hosts will need the unprototyped version */ +#else char *crypt _((const char*, const char*)); +#endif +#ifndef DONT_DECLARE_STD +#ifndef getenv char *getenv _((const char*)); +#endif Off_t lseek _((int,Off_t,int)); +#endif char *getlogin _((void)); #endif @@ -845,6 +1267,14 @@ I32 unlnk _((char*)); # endif #endif +typedef Signal_t (*Sighandler_t) _((int)); + +#ifdef HAS_SIGACTION +typedef struct sigaction Sigsave_t; +#else +typedef Sighandler_t Sigsave_t; +#endif + #define SCAN_DEF 0 #define SCAN_TR 1 #define SCAN_REPL 2 @@ -853,9 +1283,6 @@ I32 unlnk _((char*)); # ifndef register # define register # endif -# ifdef MYMALLOC -# define DEBUGGING_MSTATS -# endif # define PAD_SV(po) pad_sv(po) #else # define PAD_SV(po) curpad[po] @@ -867,9 +1294,20 @@ I32 unlnk _((char*)); /* global state */ EXT PerlInterpreter * curinterp; /* currently running interpreter */ -#ifndef VMS /* VMS doesn't use environ array */ +/* VMS doesn't use environ array and NeXT has problems with crt0.o globals */ +#if !defined(VMS) && !(defined(NeXT) && defined(__DYNAMIC__)) +#ifndef DONT_DECLARE_STD extern char ** environ; /* environment variables supplied via exec */ #endif +#else +# if defined(NeXT) && defined(__DYNAMIC__) + +# include <mach-o/dyld.h> +EXT char *** environ_pointer; +# define environ (*environ_pointer) +# endif +#endif /* environ processing */ + EXT int uid; /* current real user id */ EXT int euid; /* current effective user id */ EXT int gid; /* current real group id */ @@ -882,9 +1320,11 @@ EXT U32 evalseq; /* eval sequence number */ EXT U32 sub_generation; /* inc to force methods to be looked up again */ EXT char ** origenviron; EXT U32 origalen; +EXT HV * pidstatus; /* pid-to-status mappings for waitpid */ EXT U32 * profiledata; EXT int maxo INIT(MAXO);/* Number of ops */ EXT char * osname; /* operating system */ +EXT char * sh_path INIT(SH_PATH); /* full path of shell */ EXT XPV* xiv_arenaroot; /* list of allocated xiv areas */ EXT IV ** xiv_root; /* free xiv list--shared by interpreters */ @@ -925,7 +1365,6 @@ EXT SV ** curpad; /* temp space */ EXT SV * Sv; EXT XPV * Xpv; -EXT char buf[2048]; /* should be longer than PATH_MAX */ EXT char tokenbuf[256]; EXT struct stat statbuf; #ifdef HAS_TIMES @@ -939,43 +1378,43 @@ EXT short * ds; EXT char * dc; /* handy constants */ -EXT char * Yes INIT("1"); -EXT char * No INIT(""); -EXT char * hexdigit INIT("0123456789abcdef0123456789ABCDEFx"); -EXT char * patleave INIT("\\.^$@dDwWsSbB+*?|()-nrtfeaxc0123456789[{]}"); -EXT char * vert INIT("|"); +EXTCONST char * Yes INIT("1"); +EXTCONST char * No INIT(""); +EXTCONST char * hexdigit INIT("0123456789abcdef0123456789ABCDEFx"); +EXTCONST char * patleave INIT("\\.^$@dDwWsSbB+*?|()-nrtfeaxc0123456789[{]}"); +EXTCONST char * vert INIT("|"); -EXT char warn_uninit[] +EXTCONST char warn_uninit[] INIT("Use of uninitialized value"); -EXT char warn_nosemi[] +EXTCONST char warn_nosemi[] INIT("Semicolon seems to be missing"); -EXT char warn_reserved[] +EXTCONST char warn_reserved[] INIT("Unquoted string \"%s\" may clash with future reserved word"); -EXT char warn_nl[] +EXTCONST char warn_nl[] INIT("Unsuccessful %s on filename containing newline"); -EXT char no_wrongref[] +EXTCONST char no_wrongref[] INIT("Can't use %s ref as %s ref"); -EXT char no_symref[] +EXTCONST char no_symref[] INIT("Can't use string (\"%.32s\") as %s ref while \"strict refs\" in use"); -EXT char no_usym[] +EXTCONST char no_usym[] INIT("Can't use an undefined value as %s reference"); -EXT char no_aelem[] +EXTCONST char no_aelem[] INIT("Modification of non-creatable array value attempted, subscript %d"); -EXT char no_helem[] +EXTCONST char no_helem[] INIT("Modification of non-creatable hash value attempted, subscript \"%s\""); -EXT char no_modify[] +EXTCONST char no_modify[] INIT("Modification of a read-only value attempted"); -EXT char no_mem[] +EXTCONST char no_mem[] INIT("Out of memory!\n"); -EXT char no_security[] +EXTCONST char no_security[] INIT("Insecure dependency in %s%s"); -EXT char no_sock_func[] +EXTCONST char no_sock_func[] INIT("Unsupported socket function \"%s\" called"); -EXT char no_dir_func[] +EXTCONST char no_dir_func[] INIT("Unsupported directory function \"%s\" called"); -EXT char no_func[] +EXTCONST char no_func[] INIT("The %s function is unimplemented"); -EXT char no_myglob[] +EXTCONST char no_myglob[] INIT("\"my\" variable %s can't be in a package"); EXT SV sv_undef; @@ -989,13 +1428,58 @@ EXT SV sv_yes; #ifdef DOINIT EXT char *sig_name[] = { SIG_NAME }; EXT int sig_num[] = { SIG_NUM }; +EXT SV * psig_ptr[sizeof(sig_num)/sizeof(*sig_num)]; +EXT SV * psig_name[sizeof(sig_num)/sizeof(*sig_num)]; #else EXT char *sig_name[]; EXT int sig_num[]; +EXT SV * psig_ptr[]; +EXT SV * psig_name[]; +#endif + +/* fast case folding tables */ + +#ifdef DOINIT +EXTCONST unsigned char fold[] = { + 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, 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', 91, 92, 93, 94, 95, + 96, 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255 +}; +#else +EXTCONST unsigned char fold[]; #endif #ifdef DOINIT -EXT unsigned char fold[] = { /* fast case folding table */ +EXT unsigned char fold_locale[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -1030,11 +1514,11 @@ EXT unsigned char fold[] = { /* fast case folding table */ 248, 249, 250, 251, 252, 253, 254, 255 }; #else -EXT unsigned char fold[]; +EXT unsigned char fold_locale[]; #endif #ifdef DOINIT -EXT unsigned char freq[] = { /* letter frequencies for mixed English/C */ +EXTCONST unsigned char freq[] = { /* letter frequencies for mixed English/C */ 1, 2, 84, 151, 154, 155, 156, 157, 165, 246, 250, 3, 158, 7, 18, 29, 40, 51, 62, 73, 85, 96, 107, 118, @@ -1069,12 +1553,12 @@ EXT unsigned char freq[] = { /* letter frequencies for mixed English/C */ 138, 139, 141, 142, 143, 144, 145, 146 }; #else -EXT unsigned char freq[]; +EXTCONST unsigned char freq[]; #endif #ifdef DEBUGGING #ifdef DOINIT -EXT char* block_type[] = { +EXTCONST char* block_type[] = { "NULL", "SUB", "EVAL", @@ -1083,7 +1567,7 @@ EXT char* block_type[] = { "BLOCK", }; #else -EXT char* block_type[]; +EXTCONST char* block_type[]; #endif #endif @@ -1094,6 +1578,8 @@ EXT char* block_type[]; #include "perly.h" +#define LEX_NOTPARSING 11 /* borrowed from toke.c */ + typedef enum { XOPERATOR, XTERM, @@ -1125,7 +1611,7 @@ EXT YYSTYPE nextval[5]; /* value of next token, if any */ EXT I32 nexttype[5]; /* type of next token */ EXT I32 nexttoke; -EXT FILE * VOL rsfp INIT(Nullfp); +EXT PerlIO * VOL rsfp INIT(Nullfp); EXT SV * linestr; EXT char * bufptr; EXT char * oldbufptr; @@ -1148,6 +1634,7 @@ EXT CV * compcv; /* currently compiling subroutine */ EXT AV * comppad; /* storage for lexically scoped temporaries */ EXT AV * comppad_name; /* variable names for "my" variables */ EXT I32 comppad_name_fill;/* last "introduced" variable offset */ +EXT I32 comppad_name_floor;/* start of vars in innermost block */ EXT I32 min_intro_pending;/* start of vars to introduce */ EXT I32 max_intro_pending;/* end of vars to introduce */ EXT I32 padix; /* max used index in current "register" pad */ @@ -1174,6 +1661,7 @@ EXT U32 hints; /* various compilation flags */ #define HINT_BLOCK_SCOPE 0x00000100 #define HINT_STRICT_SUBS 0x00000200 #define HINT_STRICT_VARS 0x00000400 +#define HINT_LOCALE 0x00000800 /**************************************************************************/ /* This regexp stuff is global since it always happens within 1 expr eval */ @@ -1198,6 +1686,9 @@ EXT char * regtill; /* How far we are required to go. */ EXT U16 regflags; /* are we folding, multilining? */ EXT char regprev; /* char before regbol, \n if none */ +EXT bool do_undump; /* -u or dump seen? */ +EXT VOL U32 debug; + /***********************************************/ /* Global only to current interpreter instance */ /***********************************************/ @@ -1245,17 +1736,14 @@ IEXT bool Idowarn; IEXT bool Idoextract; IEXT bool Isawampersand; /* must save all match strings */ IEXT bool Isawstudy; /* do fbm_instr on all strings */ -IEXT bool Isawi; /* study must assume case insensitive */ IEXT bool Isawvec; IEXT bool Iunsafe; -IEXT bool Ido_undump; /* -u or dump seen? */ IEXT char * Iinplace; IEXT char * Ie_tmpname; -IEXT FILE * Ie_fp; -IEXT VOL U32 Idebug; +IEXT PerlIO * Ie_fp; IEXT U32 Iperldb; /* This value may be raised by extensions for testing purposes */ -IEXT int Iperl_destruct_level; /* 0=none, 1=full, 2=full with checks */ +IEXT int Iperl_destruct_level IINIT(0); /* 0=none, 1=full, 2=full with checks */ /* magical thingies */ IEXT Time_t Ibasetime; /* $^T */ @@ -1268,8 +1756,11 @@ IEXT char * Iors; /* $\ */ IEXT STRLEN Iorslen; IEXT char * Iofmt; /* $# */ IEXT I32 Imaxsysfd IINIT(MAXSYSFD); /* top fd to pass to subprocesses */ -IEXT int Imultiline; /* $*--do strings hold >1 line? */ -IEXT U32 Istatusvalue; /* $? */ +IEXT int Imultiline; /* $*--do strings hold >1 line? */ +IEXT I32 Istatusvalue; /* $? */ +#ifdef VMS +IEXT U32 Istatusvalue_vms; +#endif IEXT struct stat Istatcache; /* _ */ IEXT GV * Istatgv; @@ -1313,8 +1804,7 @@ IEXT HV * Idebstash; /* symbol table for perldb package */ IEXT SV * Icurstname; /* name of current package */ IEXT AV * Ibeginav; /* names of BEGIN subroutines */ IEXT AV * Iendav; /* names of END subroutines */ -IEXT AV * Ipad; /* storage for lexically scoped temporaries */ -IEXT AV * Ipadname; /* variable names for "my" variables */ +IEXT HV * Istrtab; /* shared string table */ /* memory management */ IEXT SV ** Itmps_stack; @@ -1333,7 +1823,6 @@ IEXT int Iforkprocess; /* so do_open |- can return proc# */ /* subprocess state */ IEXT AV * Ifdpid; /* keep fd-to-pid mappings for my_popen */ -IEXT HV * Ipidstatus; /* keep pid-to-status mappings for waitpid */ /* internal state */ IEXT VOL int Iin_eval; /* trap "fatal" errors? */ @@ -1360,15 +1849,17 @@ IEXT OP * Ieval_start; /* runtime control stuff */ IEXT COP * VOL Icurcop IINIT(&compiling); +IEXT COP * Icurcopdb IINIT(NULL); IEXT line_t Icopline IINIT(NOLINE); IEXT CONTEXT * Icxstack; IEXT I32 Icxstack_ix IINIT(-1); IEXT I32 Icxstack_max IINIT(128); -IEXT Sigjmp_buf Itop_env; +IEXT JMPENV Istart_env; /* empty startup sigjmp() environment */ +IEXT JMPENV * Itop_env; /* ptr. to current sigjmp() environment */ IEXT I32 Irunlevel; /* stack stuff */ -IEXT AV * Istack; /* THE STACK */ +IEXT AV * Icurstack; /* THE STACK */ IEXT AV * Imainstack; /* the stack when nothing funny is happening */ IEXT SV ** Imystack_base; /* stack->array_ary */ IEXT SV ** Imystack_sp; /* stack pointer now */ @@ -1400,6 +1891,7 @@ IEXT bool Ipreambled; IEXT AV * Ipreambleav; IEXT int Ilaststatval IINIT(-1); IEXT I32 Ilaststype IINIT(OP_STAT); +IEXT SV * Imess_sv; #undef IEXT #undef IINIT @@ -1418,20 +1910,6 @@ struct interpreter { extern "C" { #endif -#ifdef __cplusplus -# ifndef I_STDARG -# define I_STDARG 1 -# endif -#endif - -#ifdef I_STDARG -# include <stdarg.h> -#else -# ifdef I_VARARGS -# include <varargs.h> -# endif -#endif - #include "proto.h" #ifdef EMBED @@ -1449,17 +1927,22 @@ extern "C" { /* The following must follow proto.h */ #ifdef DOINIT + EXT MGVTBL vtbl_sv = {magic_get, magic_set, magic_len, 0, 0}; -EXT MGVTBL vtbl_env = {0, 0, 0, 0, 0}; +EXT MGVTBL vtbl_env = {0, magic_set_all_env, + 0, magic_clear_all_env, + 0}; EXT MGVTBL vtbl_envelem = {0, magic_setenv, 0, magic_clearenv, 0}; EXT MGVTBL vtbl_sig = {0, 0, 0, 0, 0}; -EXT MGVTBL vtbl_sigelem = {0, magic_setsig, - 0, 0, 0}; +EXT MGVTBL vtbl_sigelem = {magic_getsig, + magic_setsig, + 0, magic_clearsig, + 0}; EXT MGVTBL vtbl_pack = {0, 0, 0, magic_wipepack, 0}; EXT MGVTBL vtbl_packelem = {magic_getpack, @@ -1469,7 +1952,8 @@ EXT MGVTBL vtbl_packelem = {magic_getpack, EXT MGVTBL vtbl_dbline = {0, magic_setdbline, 0, 0, 0}; EXT MGVTBL vtbl_isa = {0, magic_setisa, - 0, 0, 0}; + 0, magic_setisa, + 0}; EXT MGVTBL vtbl_isaelem = {0, magic_setisa, 0, 0, 0}; EXT MGVTBL vtbl_arylen = {magic_getarylen, @@ -1480,6 +1964,8 @@ EXT MGVTBL vtbl_glob = {magic_getglob, 0, 0, 0}; EXT MGVTBL vtbl_mglob = {0, magic_setmglob, 0, 0, 0}; +EXT MGVTBL vtbl_nkeys = {0, magic_setnkeys, + 0, 0, 0}; EXT MGVTBL vtbl_taint = {magic_gettaint,magic_settaint, 0, 0, 0}; EXT MGVTBL vtbl_substr = {0, magic_setsubstr, @@ -1491,9 +1977,19 @@ EXT MGVTBL vtbl_pos = {magic_getpos, 0, 0, 0}; EXT MGVTBL vtbl_bm = {0, magic_setbm, 0, 0, 0}; +EXT MGVTBL vtbl_fm = {0, magic_setfm, + 0, 0, 0}; EXT MGVTBL vtbl_uvar = {magic_getuvar, magic_setuvar, 0, 0, 0}; +EXT MGVTBL vtbl_defelem = {magic_getdefelem,magic_setdefelem, + 0, 0, magic_freedefelem}; + +#ifdef USE_LOCALE_COLLATE +EXT MGVTBL vtbl_collxfrm = {0, + magic_setcollxfrm, + 0, 0, 0}; +#endif #ifdef OVERLOAD EXT MGVTBL vtbl_amagic = {0, magic_setamagic, @@ -1502,7 +1998,8 @@ EXT MGVTBL vtbl_amagicelem = {0, magic_setamagic, 0, 0, magic_setamagic}; #endif /* OVERLOAD */ -#else +#else /* !DOINIT */ + EXT MGVTBL vtbl_sv; EXT MGVTBL vtbl_env; EXT MGVTBL vtbl_envelem; @@ -1516,72 +2013,92 @@ EXT MGVTBL vtbl_isaelem; EXT MGVTBL vtbl_arylen; EXT MGVTBL vtbl_glob; EXT MGVTBL vtbl_mglob; +EXT MGVTBL vtbl_nkeys; EXT MGVTBL vtbl_taint; EXT MGVTBL vtbl_substr; EXT MGVTBL vtbl_vec; EXT MGVTBL vtbl_pos; EXT MGVTBL vtbl_bm; +EXT MGVTBL vtbl_fm; EXT MGVTBL vtbl_uvar; +EXT MGVTBL vtbl_defelem; + +#ifdef USE_LOCALE_COLLATE +EXT MGVTBL vtbl_collxfrm; +#endif #ifdef OVERLOAD EXT MGVTBL vtbl_amagic; EXT MGVTBL vtbl_amagicelem; #endif /* OVERLOAD */ -#endif +#endif /* !DOINIT */ #ifdef OVERLOAD + EXT long amagic_generation; -#define NofAMmeth 29 +#define NofAMmeth 58 #ifdef DOINIT -EXT char * AMG_names[NofAMmeth][2] = { - {"fallback","abs"}, - {"bool", "nomethod"}, - {"\"\"", "0+"}, - {"+","+="}, - {"-","-="}, - {"*", "*="}, - {"/", "/="}, - {"%", "%="}, - {"**", "**="}, - {"<<", "<<="}, - {">>", ">>="}, - {"&", "&="}, - {"|", "|="}, - {"^", "^="}, - {"<", "<="}, - {">", ">="}, - {"==", "!="}, - {"<=>", "cmp"}, - {"lt", "le"}, - {"gt", "ge"}, - {"eq", "ne"}, - {"!", "~"}, - {"++", "--"}, - {"atan2", "cos"}, - {"sin", "exp"}, - {"log", "sqrt"}, - {"x","x="}, - {".",".="}, - {"=","neg"} +EXTCONST char * AMG_names[NofAMmeth] = { + "fallback", "abs", /* "fallback" should be the first. */ + "bool", "nomethod", + "\"\"", "0+", + "+", "+=", + "-", "-=", + "*", "*=", + "/", "/=", + "%", "%=", + "**", "**=", + "<<", "<<=", + ">>", ">>=", + "&", "&=", + "|", "|=", + "^", "^=", + "<", "<=", + ">", ">=", + "==", "!=", + "<=>", "cmp", + "lt", "le", + "gt", "ge", + "eq", "ne", + "!", "~", + "++", "--", + "atan2", "cos", + "sin", "exp", + "log", "sqrt", + "x", "x=", + ".", ".=", + "=", "neg" }; #else -EXT char * AMG_names[NofAMmeth][2]; +EXTCONST char * AMG_names[NofAMmeth]; #endif /* def INITAMAGIC */ -struct am_table { +struct am_table { long was_ok_sub; long was_ok_am; - CV* table[NofAMmeth*2]; + U32 flags; + CV* table[NofAMmeth]; long fallback; }; +struct am_table_short { + long was_ok_sub; + long was_ok_am; + U32 flags; +}; typedef struct am_table AMT; +typedef struct am_table_short AMTS; #define AMGfallNEVER 1 #define AMGfallNO 2 #define AMGfallYES 3 +#define AMTf_AMAGIC 1 +#define AMT_AMAGIC(amt) ((amt)->flags & AMTf_AMAGIC) +#define AMT_AMAGIC_on(amt) ((amt)->flags |= AMTf_AMAGIC) +#define AMT_AMAGIC_off(amt) ((amt)->flags &= ~AMTf_AMAGIC) + enum { fallback_amg, abs_amg, bool__amg, nomethod_amg, @@ -1613,6 +2130,96 @@ enum { concat_amg, concat_ass_amg, copy_amg, neg_amg }; + +/* + * some compilers like to redefine cos et alia as faster + * (and less accurate?) versions called F_cos et cetera (Quidquid + * latine dictum sit, altum viditur.) This trick collides with + * the Perl overloading (amg). The following #defines fool both. + */ + +#ifdef _FASTMATH +# ifdef atan2 +# define F_atan2_amg atan2_amg +# endif +# ifdef cos +# define F_cos_amg cos_amg +# endif +# ifdef exp +# define F_exp_amg exp_amg +# endif +# ifdef log +# define F_log_amg log_amg +# endif +# ifdef pow +# define F_pow_amg pow_amg +# endif +# ifdef sin +# define F_sin_amg sin_amg +# endif +# ifdef sqrt +# define F_sqrt_amg sqrt_amg +# endif +#endif /* _FASTMATH */ + #endif /* OVERLOAD */ +#define PERLDB_ALL 0xff +#define PERLDBf_SUB 0x01 /* Debug sub enter/exit. */ +#define PERLDBf_LINE 0x02 /* Keep line #. */ +#define PERLDBf_NOOPT 0x04 /* Switch off optimizations. */ +#define PERLDBf_INTER 0x08 /* Preserve more data for + later inspections. */ +#define PERLDBf_SUBLINE 0x10 /* Keep subr source lines. */ +#define PERLDBf_SINGLE 0x20 /* Start with single-step on. */ + +#define PERLDB_SUB (perldb && (perldb & PERLDBf_SUB)) +#define PERLDB_LINE (perldb && (perldb & PERLDBf_LINE)) +#define PERLDB_NOOPT (perldb && (perldb & PERLDBf_NOOPT)) +#define PERLDB_INTER (perldb && (perldb & PERLDBf_INTER)) +#define PERLDB_SUBLINE (perldb && (perldb & PERLDBf_SUBLINE)) +#define PERLDB_SINGLE (perldb && (perldb & PERLDBf_SINGLE)) + +#ifdef USE_LOCALE_COLLATE +EXT U32 collation_ix; /* Collation generation index */ +EXT char * collation_name; /* Name of current collation */ +EXT bool collation_standard INIT(TRUE); /* Assume simple collation */ +EXT Size_t collxfrm_base; /* Basic overhead in *xfrm() */ +EXT Size_t collxfrm_mult INIT(2); /* Expansion factor in *xfrm() */ +#endif /* USE_LOCALE_COLLATE */ + +#ifdef USE_LOCALE_NUMERIC + +EXT char * numeric_name; /* Name of current numeric locale */ +EXT bool numeric_standard INIT(TRUE); /* Assume simple numerics */ +EXT bool numeric_local INIT(TRUE); /* Assume local numerics */ + +#define SET_NUMERIC_STANDARD() \ + STMT_START { \ + if (! numeric_standard) \ + perl_set_numeric_standard(); \ + } STMT_END + +#define SET_NUMERIC_LOCAL() \ + STMT_START { \ + if (! numeric_local) \ + perl_set_numeric_local(); \ + } STMT_END + +#else /* !USE_LOCALE_NUMERIC */ + +#define SET_NUMERIC_STANDARD() /**/ +#define SET_NUMERIC_LOCAL() /**/ + +#endif /* !USE_LOCALE_NUMERIC */ + +#if !defined(PERLIO_IS_STDIO) && defined(HAS_ATTRIBUTE) +/* + * Now we have __attribute__ out of the way + * Remap printf + */ +#define printf PerlIO_stdoutf +#endif + #endif /* Include guard */ + diff --git a/gnu/usr.bin/perl/perl_exp.SH b/gnu/usr.bin/perl/perl_exp.SH index 2e7bb20e082..06b587f9ef9 100644 --- a/gnu/usr.bin/perl/perl_exp.SH +++ b/gnu/usr.bin/perl/perl_exp.SH @@ -1,32 +1,84 @@ #!/bin/sh - +# # Written: Nov 1994 Wayne Scott (wscott@ichips.intel.com) - +# # Create the export list for perl. # Needed by AIX to do dynamic linking. +# +# This simple program relys on 'global.sym' and other *.sym files +# being up to date with all of the global symbols that a dynamic +# link library might want to access. +# +# Most symbols have a Perl_ prefix because that's what embed.h sticks +# in front of them. Variations depend on binary compatibility with +# Perl 5.003. +# -# This simple program relys on 'global.sym' being up to date -# with all of the global symbols that a dynamicly link library -# might want to access. - -# All symbols have a Perl_ prefix because that's what embed.h -# sticks in front of them. +case $CONFIG in +'') + if test -f config.sh; then TOP=.; + elif test -f ../config.sh; then TOP=..; + elif test -f ../../config.sh; then TOP=../..; + elif test -f ../../../config.sh; then TOP=../../..; + elif test -f ../../../../config.sh; then TOP=../../../..; + else + echo "Can't find config.sh."; exit 1 + fi + . $TOP/config.sh + ;; +esac +: This forces SH files to create target in same directory as SH file. +: This is so that make depend always knows where to find SH derivatives. +case "$0" in +*/*) cd `expr X$0 : 'X\(.*\)/'` ;; +esac echo "Extracting perl.exp" +rm -f perl.exp echo "#!" > perl.exp -sed -n '/^[A-Za-z]/ s/^/Perl_/p' global.sym >> perl.exp +case "$bincompat3" in +y*) + global=/tmp/exp$$g + interp=/tmp/exp$$i + compat3=/tmp/exp$$c + grep '^[A-Za-z]' global.sym | sort >$global + grep '^[A-Za-z]' interp.sym | sort >$interp + grep '^[A-Za-z]' compat3.sym | sort >$compat3 + comm -23 $global $compat3 | sed 's/^/Perl_/' >> perl.exp + comm -12 $interp $compat3 | sed 's/^/Perl_/' >> perl.exp + comm -12 $global $compat3 >> perl.exp + comm -23 $interp $compat3 >> perl.exp + rm -f $global $interp $compat3 + ;; +*) + sed -n '/^[A-Za-z]/ s/^/Perl_/p' global.sym interp.sym >> perl.exp + ;; +esac + +# +# If we use the PerlIO abstraction layer, add its symbols +# + +if [ $useperlio = "define" ] +then + grep '^[A-Za-z]' perlio.sym >> perl.exp +fi -# also add symbols from interp.sym -# They are only needed if -DMULTIPLICITY is not set but it -# doesn't hurt to include them anyway. -sed -n '/^[A-Za-z]/ p' interp.sym >> perl.exp +# +# Extra globals not included above (including a few that might +# not actually be defined, but there's no harm in that). +# -# extra globals not included above. cat <<END >> perl.exp +perl_init_i18nl10n perl_init_i18nl14n -perl_init_ext +perl_new_collate +perl_new_ctype +perl_new_numeric +perl_set_numeric_local +perl_set_numeric_standard perl_alloc perl_construct perl_destruct @@ -41,8 +93,15 @@ perl_call_argv perl_call_pv perl_call_method perl_call_sv -perl_requirepv -safemalloc -saferealloc -safefree +perl_eval_pv +perl_eval_sv +perl_require_pv +Mymalloc +Mycalloc +Myremalloc +Myfree +Perl_malloc +Perl_calloc +Perl_realloc +Perl_free END diff --git a/gnu/usr.bin/perl/perlsh b/gnu/usr.bin/perl/perlsh index 2b2cccd0641..63662d6c6a1 100644 --- a/gnu/usr.bin/perl/perlsh +++ b/gnu/usr.bin/perl/perlsh @@ -8,7 +8,7 @@ $/ = "\n\n"; # set paragraph mode $SHlinesep = "\n"; -while ($SHcmd = <>) { +while (defined($SHcmd = <>)) { $/ = $SHlinesep; eval $SHcmd; print $@ || "\n"; $SHlinesep = $/; $/ = ''; diff --git a/gnu/usr.bin/perl/perly.c b/gnu/usr.bin/perl/perly.c index 9ecf6d2063e..ae6a0da922a 100644 --- a/gnu/usr.bin/perl/perly.c +++ b/gnu/usr.bin/perl/perly.c @@ -12,1094 +12,1044 @@ dep() deprecate("\"do\" to call subroutines"); } +#line 16 "perly.c" #define YYERRCODE 256 short yylhs[] = { -1, - 31, 0, 5, 3, 6, 6, 6, 7, 7, 7, - 7, 21, 21, 21, 21, 21, 21, 11, 11, 11, - 9, 9, 9, 9, 30, 30, 8, 8, 8, 8, - 8, 8, 8, 8, 10, 10, 25, 25, 29, 29, - 1, 1, 1, 1, 2, 2, 32, 32, 28, 28, - 4, 33, 33, 34, 13, 13, 13, 12, 12, 12, - 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 22, 22, 23, 23, 23, 20, - 15, 16, 17, 18, 19, 24, 24, 24, 24, + 45, 0, 9, 7, 10, 8, 11, 11, 11, 12, + 12, 12, 12, 24, 24, 24, 24, 24, 24, 15, + 15, 15, 14, 14, 42, 42, 13, 13, 13, 13, + 13, 13, 13, 26, 26, 27, 27, 28, 29, 30, + 31, 32, 44, 44, 1, 1, 1, 1, 3, 38, + 38, 46, 4, 5, 6, 39, 40, 40, 41, 41, + 47, 47, 49, 48, 16, 16, 16, 25, 25, 25, + 36, 36, 36, 36, 36, 36, 36, 50, 36, 37, + 37, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 33, 33, 34, + 34, 34, 2, 2, 43, 23, 18, 19, 20, 21, + 22, 35, 35, 35, 35, }; short yylen[] = { 2, - 0, 2, 4, 0, 0, 2, 2, 2, 1, 2, - 3, 1, 1, 3, 3, 3, 3, 0, 2, 6, - 6, 6, 4, 4, 0, 2, 7, 7, 5, 5, - 8, 7, 10, 3, 0, 1, 0, 1, 0, 1, - 1, 1, 1, 1, 4, 3, 5, 5, 0, 1, - 0, 3, 2, 5, 3, 3, 1, 2, 3, 1, - 3, 5, 6, 3, 5, 2, 4, 4, 1, 1, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 5, 3, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 3, 2, 3, 2, 4, 3, - 4, 1, 5, 1, 4, 5, 4, 1, 1, 1, - 5, 6, 5, 6, 5, 4, 5, 1, 1, 3, - 4, 3, 2, 2, 4, 5, 4, 5, 1, 2, - 2, 1, 2, 2, 2, 1, 3, 1, 3, 4, - 4, 6, 1, 1, 0, 1, 0, 1, 2, 2, - 2, 2, 2, 2, 2, 1, 1, 1, 1, + 0, 2, 4, 0, 4, 0, 0, 2, 2, 2, + 1, 2, 3, 1, 1, 3, 3, 3, 3, 0, + 2, 6, 7, 7, 0, 2, 8, 8, 10, 9, + 8, 11, 3, 0, 1, 0, 1, 1, 1, 1, + 1, 1, 0, 1, 1, 1, 1, 1, 4, 1, + 0, 5, 0, 0, 0, 1, 0, 1, 1, 1, + 3, 2, 0, 7, 3, 3, 1, 2, 3, 1, + 3, 5, 6, 3, 5, 2, 4, 0, 5, 1, + 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 5, 3, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 3, 2, 3, 2, 4, + 3, 4, 1, 5, 1, 4, 5, 4, 1, 1, + 1, 5, 6, 5, 6, 5, 4, 5, 1, 1, + 3, 4, 3, 2, 2, 4, 5, 4, 5, 4, + 5, 1, 2, 2, 1, 2, 2, 2, 1, 3, + 1, 3, 4, 4, 6, 1, 1, 0, 1, 0, + 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, + 2, 1, 1, 1, 1, }; short yydefred[] = { 1, - 0, 5, 0, 40, 51, 51, 0, 51, 6, 41, - 7, 9, 0, 42, 43, 44, 0, 0, 0, 53, - 0, 12, 4, 143, 0, 0, 118, 0, 138, 0, - 51, 51, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7, 0, 44, 55, 53, 0, 53, 8, 45, + 9, 11, 0, 46, 47, 48, 0, 0, 0, 62, + 63, 14, 4, 156, 0, 0, 129, 0, 151, 0, + 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 163, 164, 0, + 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, + 0, 0, 119, 121, 0, 0, 0, 0, 157, 50, + 0, 56, 0, 61, 0, 7, 172, 175, 174, 173, + 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, + 4, 4, 0, 0, 0, 0, 0, 146, 0, 0, + 0, 0, 76, 0, 170, 0, 135, 0, 0, 0, + 0, 0, 166, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 109, 0, 167, 168, 169, 171, 0, + 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, - 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, - 0, 108, 110, 0, 0, 0, 144, 0, 46, 0, - 52, 0, 5, 156, 159, 158, 157, 0, 0, 0, + 0, 0, 0, 101, 102, 0, 0, 0, 0, 0, + 0, 0, 0, 13, 0, 49, 58, 0, 0, 0, + 74, 0, 0, 78, 0, 0, 0, 0, 0, 0, + 0, 4, 150, 152, 0, 0, 0, 0, 0, 0, + 0, 111, 0, 133, 0, 0, 108, 26, 0, 0, + 19, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 154, 0, 124, - 0, 0, 0, 0, 0, 0, 150, 0, 0, 0, - 0, 66, 0, 133, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 98, 0, 151, 152, 153, 155, - 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 90, 91, 0, 0, 0, 0, - 0, 0, 0, 0, 11, 45, 50, 0, 0, 0, - 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 36, 0, 137, 139, - 0, 0, 0, 0, 0, 0, 100, 0, 122, 0, - 0, 0, 97, 26, 0, 0, 0, 0, 0, 0, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 69, 0, 70, - 0, 0, 0, 0, 0, 0, 0, 120, 0, 48, - 47, 54, 3, 0, 141, 0, 68, 101, 0, 29, - 0, 30, 0, 0, 0, 23, 0, 24, 0, 0, - 0, 140, 149, 67, 0, 125, 0, 127, 0, 99, - 0, 0, 0, 0, 0, 0, 0, 107, 0, 105, - 0, 116, 0, 121, 65, 0, 0, 0, 0, 19, - 0, 0, 0, 0, 0, 62, 126, 128, 115, 0, - 113, 0, 0, 106, 0, 111, 117, 103, 142, 27, - 28, 21, 0, 22, 0, 32, 0, 114, 112, 63, - 0, 0, 31, 0, 0, 20, 33, + 0, 80, 0, 0, 81, 0, 0, 0, 0, 0, + 0, 0, 131, 0, 0, 60, 59, 52, 0, 3, + 0, 154, 0, 0, 112, 0, 41, 0, 42, 0, + 0, 0, 0, 165, 0, 0, 35, 40, 0, 0, + 0, 153, 162, 77, 0, 136, 0, 138, 0, 110, + 0, 0, 0, 0, 0, 140, 0, 0, 0, 118, + 0, 116, 0, 127, 0, 132, 0, 75, 0, 79, + 0, 0, 0, 0, 0, 0, 0, 0, 72, 137, + 139, 126, 0, 124, 0, 0, 141, 117, 0, 122, + 128, 114, 64, 155, 6, 0, 0, 0, 0, 0, + 0, 0, 0, 125, 123, 73, 7, 27, 28, 0, + 0, 23, 24, 0, 31, 0, 0, 0, 21, 0, + 0, 0, 30, 5, 0, 29, 0, 0, 32, 0, + 22, }; short yydgoto[] = { 1, - 9, 10, 83, 17, 86, 3, 11, 12, 66, 195, - 266, 67, 202, 69, 70, 71, 72, 73, 74, 75, - 197, 122, 203, 88, 187, 77, 241, 178, 13, 142, - 2, 14, 15, 16, + 9, 66, 10, 18, 95, 17, 86, 337, 89, 326, + 3, 11, 12, 68, 342, 261, 70, 71, 72, 73, + 74, 75, 76, 267, 78, 268, 257, 259, 262, 270, + 258, 260, 113, 197, 91, 79, 236, 81, 83, 178, + 248, 142, 265, 13, 2, 14, 15, 16, 85, 254, }; short yysindex[] = { 0, - 0, 0, -82, 0, 0, 0, -52, 0, 0, 0, - 0, 0, 853, 0, 0, 0, -80, -256, -19, 0, - -245, 0, 0, 0, 19, 19, 0, 20, 0, 2177, - 0, 0, -2, 1, 28, 41, 133, 2177, 27, 33, - 52, 19, 1028, 2177, 1303, -210, 19, 2177, 965, 1359, - 2177, 2177, 2177, 2177, 2177, 1415, 0, 2177, 2177, 1478, - 19, 19, 19, 19, -225, 0, 71, 209, 1535, -49, - -30, 0, 0, 8, 101, 42, 0, 30, 0, -112, - 0, 2177, 0, 0, 0, 0, 0, 2177, 127, 2177, - 1535, 30, -112, 2177, 30, 2177, 30, 2177, 30, 2177, - 30, 1712, 128, 1535, 139, 1768, 965, 0, 141, 0, - 1485, -14, 1485, 65, -42, 2177, 0, 71, 0, 71, - -49, 0, 2177, 0, 1485, 334, 334, 334, -47, -47, - 92, -26, 334, 334, 0, 63, 0, 0, 0, 0, - 30, 0, 2177, 2177, 2177, 2177, 2177, 2177, 2177, 2177, - 2177, 2177, 2177, 2177, 2177, 2177, 2177, 2177, 2177, 2177, - 2177, 2177, 2177, 2177, 0, 0, -27, 2177, 2177, 2177, - 2177, 2177, 2177, 1824, 0, 0, 0, -48, 137, -92, - 0, 2177, 221, 2177, 30, -191, 151, -225, -22, -225, - -12, -147, 7, -147, 138, 5, 0, 2177, 0, 0, - 9, -39, 160, 2177, 1887, 2121, 0, 77, 0, 71, - 2177, 113, 0, 0, 1535, -191, -191, -191, -191, -86, - 0, -20, 395, 1485, 1566, 461, -88, 1535, 4122, 1064, - 679, 364, 1120, 728, 334, 334, 2177, 0, 2177, 0, - 174, 89, 51, 98, 55, 118, 57, 0, 11, 0, - 0, 0, 0, 175, 0, 2177, 0, 0, 30, 0, - 30, 0, 30, 30, 178, 0, 30, 0, 2177, 30, - 15, 0, 0, 0, 22, 0, 25, 0, 29, 0, - 152, 2177, 94, 2177, 59, 177, 2177, 0, 96, 0, - 97, 0, 102, 0, 0, 1190, -225, -225, -147, 0, - 2177, -147, 176, -225, 30, 0, 0, 0, 0, 205, - 0, 3039, 111, 0, 206, 0, 0, 0, 0, 0, - 0, 0, 37, 0, 1712, 0, -225, 0, 0, 0, - 30, 208, 0, -147, 30, 0, 0, + 0, 0, -120, 0, 0, 0, -50, 0, 0, 0, + 0, 0, 661, 0, 0, 0, -240, -238, -29, 0, + 0, 0, 0, 0, -32, -32, 0, -8, 0, 2115, + 0, 0, -4, 31, 32, 35, -35, 2115, 56, 57, + 61, 1037, 981, -32, 1100, 1364, -218, 0, 0, -32, + 2115, 2115, 2115, 2115, 2115, 2115, 1420, 0, 2115, 2115, + 1476, -32, -32, -32, -32, 2115, -205, 0, 201, 306, + -63, -62, 0, 0, -24, 67, 45, 65, 0, 0, + -15, 0, -149, 0, -144, 0, 0, 0, 0, 0, + 2115, 80, 2115, 841, -15, -149, 0, 0, 0, 0, + 0, 0, 85, 306, 86, 1535, 981, 0, 841, 0, + -63, 65, 0, 2115, 0, 88, 0, 841, -28, 4, + -51, 2115, 0, 65, 340, 340, 340, -76, -76, 49, + -31, 340, 340, 0, -82, 0, 0, 0, 0, 841, + -15, 0, 2115, 2115, 2115, 2115, 2115, 2115, 2115, 2115, + 2115, 2115, 2115, 2115, 2115, 2115, 2115, 2115, 2115, 2115, + 2115, 2115, 2115, 0, 0, 48, 2115, 2115, 2115, 2115, + 2115, 2115, 1710, 0, 2115, 0, 0, -43, -116, 241, + 0, 2115, 1193, 0, -15, 2115, 2115, 2115, 2115, 106, + 1769, 0, 0, 0, -23, 20, 104, 2115, 65, 1825, + 1881, 0, 36, 0, 2115, 62, 0, 0, -232, -232, + 0, -232, -232, -134, 0, -46, 1131, 841, 689, 316, + 859, 306, 3778, 1980, 3652, 1299, 480, 396, 340, 340, + 2115, 0, 1944, 2115, 0, 128, -58, 22, -56, 24, + 33, 28, 0, -19, 306, 0, 0, 0, 2115, 0, + 134, 0, 2115, 2115, 0, -232, 0, 142, 0, 148, + -232, 149, 150, 0, 153, 201, 0, 0, 154, 138, + 2115, 0, 0, 0, -7, 0, 2, 0, 16, 0, + 70, 2115, 73, 2115, 30, 0, 18, 101, 2115, 0, + 75, 0, 78, 0, 81, 0, 151, 0, 1247, 0, + 90, 90, 90, 90, 2115, 90, 2115, 167, 0, 0, + 0, 0, 103, 0, 3869, 84, 0, 0, 170, 0, + 0, 0, 0, 0, 0, -205, -205, -207, -207, 176, + -205, 168, 90, 0, 0, 0, 0, 0, 0, 90, + 192, 0, 0, 90, 0, 1769, -205, 402, 0, 2115, + -205, 207, 0, 0, 208, 0, 90, 90, 0, -207, + 0, }; short yyrindex[] = { 0, - 0, 0, 297, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 265, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2156, -17, 0, + 0, 2675, 2720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2253, 505, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2847, 2935, + 0, 0, 0, 0, 0, 0, 79, 0, -3, 108, + 2774, 2860, 0, 0, 2034, 121, 0, 140, 0, 0, + 0, 0, -33, 0, 0, 0, 0, 0, 0, 0, + 2203, 0, 0, 3504, 0, 145, 0, 0, 0, 0, + 0, 0, 0, 3772, 0, 0, 252, 0, 3551, 541, + 602, 2270, 0, 0, 0, 442, 0, 3587, 2774, 0, + 0, 2203, 0, 2324, 3010, 3049, 3096, 2911, 2972, 2439, + 0, 3147, 3193, 0, 0, 0, 0, 0, 0, 3633, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 107, 0, -35, 10, 53, 3109, - 3156, 0, 0, 2298, 1976, 0, 0, 0, 0, -23, - 0, 230, 0, 0, 0, 0, 0, 2385, 0, 0, - 1004, 0, 168, 253, 0, 0, 0, 0, 0, 0, - 0, 254, 0, 2242, 0, 0, 274, 0, 2032, 0, - 3844, 3109, 3902, 0, 0, 2385, 0, 2440, 452, 2554, - 572, 0, 0, 0, 3981, 3274, 3312, 3421, 3200, 3237, - 2661, 0, 3560, 3596, 0, 0, 0, 0, 0, 0, - 0, 0, 2714, 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, 909, - 0, 274, 0, 2385, 0, 39, 0, 107, 0, 107, - 0, 170, 0, 170, 0, 262, 0, 0, 0, 0, - 0, 288, 0, 0, 0, 0, 0, 0, 0, 2805, - 0, 2757, 0, 0, 2650, 49, 58, 61, 64, 365, - 0, 0, -31, 4018, 4028, 3719, 630, 2995, 0, 1623, - 4106, 4096, 4064, 3756, 3640, 3683, 0, 0, 0, 0, + 0, 0, 0, 0, 2522, 0, 0, 0, 0, 925, + 0, 252, 0, 0, 0, 263, 0, 0, 0, 0, + 223, 0, 0, 0, 0, 282, 0, 0, 2576, 0, + 0, 0, 0, 0, 0, 2624, 0, 0, -1, 26, + 0, 27, 51, 718, 0, 0, 3752, 1576, 1632, 3368, + 3413, 3799, 0, -38, 3710, 3678, 3060, 3459, 3285, 3332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3835, 0, 0, 0, 273, 0, + 0, 0, 0, 2203, 0, 59, 0, 0, 0, 0, + 293, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 277, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 274, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 107, 107, 170, 0, - 0, 170, 0, 107, 0, 0, 0, 0, 0, 0, - 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 300, 0, 107, 0, 0, 0, - 0, 0, 0, 170, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 296, 0, 0, 0, + 0, 0, 0, 0, 2380, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 79, 79, 186, 186, 0, + 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 300, 79, 925, 0, 0, + 79, 0, 0, 0, 0, 0, 0, 0, 0, 186, + 0, }; short yygindex[] = { 0, - 0, 0, 0, 506, -13, 255, 0, 0, 0, 18, - -180, 839, -11, 4398, 2162, 0, 0, 0, 0, 0, - 342, -57, -174, 1032, 90, 0, 0, 267, 0, -172, - 0, 0, 0, 0, + 0, 0, 0, 349, 328, 0, -48, 0, 679, 378, + -84, 0, 0, 0, -298, -13, 4075, 2485, 0, 0, + 0, 0, 0, 363, 908, 0, 0, 233, -168, 38, + 72, 196, -77, -175, 999, 0, 0, 0, 0, 290, + 0, -249, 0, 0, 0, 0, 0, 0, 0, 0, }; -#define YYTABLESIZE 4682 -short yytable[] = { 65, - 80, 68, 168, 79, 273, 57, 20, 254, 61, 80, - 250, 82, 80, 268, 212, 260, 208, 262, 261, 95, - 97, 99, 101, 57, 179, 206, 80, 80, 263, 110, - 181, 80, 253, 115, 150, 49, 124, 94, 283, 81, - 96, 170, 23, 168, 132, 270, 116, 267, 136, 272, - 13, 294, 141, 83, 61, 305, 83, 57, 209, 90, - 172, 80, 306, 239, 176, 307, 105, 98, 13, 308, - 83, 83, 106, 169, 23, 150, 170, 331, 184, 38, - 100, 188, 186, 190, 189, 192, 191, 194, 193, 16, - 196, 107, 171, 60, 201, 237, 60, 38, 17, 49, - 175, 14, 148, 149, 15, 83, 25, 16, 169, 289, - 60, 60, 315, 291, 143, 293, 17, 313, 322, 14, - 23, 324, 15, 23, 320, 321, 257, 214, 264, 265, - 173, 326, 216, 217, 218, 219, 220, 221, 222, 25, - 174, 23, 25, 25, 25, 60, 25, 177, 25, 25, - 23, 25, 23, 336, 333, 213, 242, 243, 244, 245, - 246, 247, 249, 23, 251, 25, 182, 198, 61, 18, - 25, 258, 102, 4, 5, 6, 78, 7, 8, 199, - 205, 288, 211, 4, 5, 6, 271, 7, 8, 207, - 290, 259, 275, 277, 279, 252, 269, 25, 154, 281, - 274, 280, 18, 282, 19, 18, 18, 18, 149, 18, - 292, 18, 18, 287, 18, 295, 163, 301, 311, 164, - 316, 317, 165, 166, 167, 285, 318, 286, 18, 25, - 238, 25, 25, 18, 325, 329, 57, 57, 57, 57, - 80, 80, 80, 80, 309, 297, 330, 298, 335, 299, - 300, 148, 149, 302, 148, 149, 304, 186, 57, 57, - 18, 255, 80, 80, 256, 167, 80, 148, 149, 314, - 310, 148, 149, 148, 149, 84, 144, 145, 146, 147, - 85, 148, 149, 157, 83, 83, 83, 83, 145, 323, - 49, 327, 18, 37, 18, 18, 2, 328, 148, 149, - 148, 149, 148, 149, 148, 149, 83, 83, 148, 149, - 83, 168, 35, 68, 147, 148, 149, 334, 148, 149, - 13, 337, 148, 149, 60, 60, 60, 60, 148, 39, - 148, 149, 39, 39, 39, 37, 39, 180, 39, 39, - 35, 39, 332, 150, 148, 149, 60, 60, 148, 149, - 148, 149, 148, 149, 76, 39, 148, 149, 303, 185, - 39, 0, 25, 25, 25, 25, 25, 25, 0, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 148, 149, 0, 25, 25, 39, 25, 25, - 25, 148, 149, 0, 0, 25, 25, 25, 25, 25, - 0, 0, 25, 25, 0, 56, 0, 0, 56, 25, - 0, 148, 149, 25, 0, 25, 25, 0, 0, 39, - 0, 0, 39, 56, 168, 18, 18, 18, 18, 18, - 18, 0, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 148, 149, 0, 18, 18, - 0, 18, 18, 18, 168, 0, 150, 56, 18, 18, - 18, 18, 18, 0, 0, 18, 18, 0, 0, 0, - 148, 149, 18, 0, 0, 0, 18, 0, 18, 18, - 144, 145, 146, 147, 156, 168, 150, 156, 156, 156, - 0, 156, 143, 156, 156, 143, 156, 0, 148, 149, - 0, 151, 148, 149, 0, 152, 153, 154, 155, 143, - 143, 18, 0, 21, 143, 156, 0, 150, 156, 158, - 159, 160, 161, 0, 162, 163, 0, 0, 164, 0, - 0, 165, 166, 167, 0, 0, 92, 93, 0, 0, - 0, 0, 143, 0, 143, 136, 0, 0, 136, 0, - 0, 168, 39, 39, 39, 39, 39, 39, 0, 39, - 39, 39, 136, 136, 0, 39, 0, 136, 39, 39, - 39, 39, 0, 0, 143, 39, 39, 156, 39, 39, - 39, 0, 0, 150, 0, 39, 39, 39, 39, 39, - 0, 0, 39, 39, 0, 136, 0, 136, 0, 39, - 0, 0, 0, 39, 157, 39, 39, 157, 157, 157, - 0, 157, 102, 157, 157, 102, 157, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 136, 0, 102, - 102, 0, 0, 0, 102, 157, 56, 56, 56, 56, - 0, 164, 0, 0, 165, 166, 167, 0, 152, 153, - 154, 155, 0, 0, 0, 0, 0, 0, 56, 0, - 0, 0, 0, 0, 102, 161, 0, 162, 163, 0, - 74, 164, 0, 74, 165, 166, 167, 0, 0, 152, - 153, 154, 155, 0, 0, 0, 0, 74, 74, 0, - 0, 0, 74, 158, 159, 160, 161, 157, 162, 163, - 0, 0, 164, 0, 0, 165, 166, 167, 156, 156, - 156, 156, 156, 0, 156, 156, 156, 0, 0, 0, - 156, 0, 74, 143, 143, 143, 143, 0, 0, 0, - 0, 156, 143, 156, 156, 156, 143, 143, 143, 143, - 156, 156, 156, 156, 156, 143, 143, 156, 156, 143, - 143, 143, 143, 143, 156, 143, 143, 0, 156, 143, - 156, 156, 143, 143, 143, 163, 0, 0, 164, 168, - 0, 165, 166, 167, 0, 0, 136, 136, 136, 136, - 0, 0, 0, 0, 0, 136, 0, 0, 0, 136, - 136, 136, 136, 0, 0, 0, 0, 0, 136, 136, - 0, 150, 136, 136, 136, 136, 136, 0, 136, 136, - 0, 0, 136, 0, 0, 136, 136, 136, 168, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 157, 157, - 157, 157, 157, 0, 157, 157, 157, 0, 0, 0, - 157, 0, 0, 102, 102, 102, 102, 0, 0, 0, - 150, 157, 102, 157, 157, 157, 102, 102, 102, 102, - 157, 157, 157, 157, 157, 102, 102, 157, 157, 102, - 102, 102, 102, 102, 157, 102, 102, 0, 157, 102, - 157, 157, 102, 102, 102, 51, 118, 120, 61, 63, - 47, 0, 56, 0, 64, 59, 0, 58, 0, 0, - 0, 74, 74, 74, 74, 0, 0, 0, 0, 0, - 74, 57, 0, 0, 74, 74, 62, 74, 0, 0, - 120, 0, 0, 74, 74, 0, 120, 74, 74, 74, - 74, 74, 0, 74, 0, 0, 0, 0, 0, 0, - 0, 39, 0, 60, 39, 39, 39, 0, 39, 0, - 39, 39, 0, 39, 120, 0, 0, 0, 0, 0, - 0, 210, 0, 152, 153, 154, 155, 39, 0, 0, - 0, 0, 39, 0, 0, 23, 0, 0, 52, 160, - 161, 0, 162, 163, 0, 0, 164, 0, 0, 165, - 166, 167, 0, 0, 0, 0, 0, 51, 0, 39, - 61, 63, 47, 0, 56, 0, 64, 59, 0, 58, - 0, 0, 0, 0, 154, 155, 0, 0, 0, 0, - 0, 0, 120, 0, 0, 0, 0, 0, 62, 0, - 0, 39, 163, 0, 39, 164, 0, 0, 165, 166, - 167, 0, 0, 0, 135, 0, 0, 135, 0, 0, - 0, 0, 0, 0, 0, 60, 0, 89, 0, 0, - 51, 135, 135, 61, 63, 47, 0, 56, 0, 64, - 59, 0, 58, 108, 0, 0, 0, 0, 117, 0, - 123, 0, 0, 0, 0, 0, 0, 23, 0, 0, - 52, 62, 137, 138, 139, 140, 135, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 22, 24, - 25, 26, 27, 28, 0, 29, 30, 31, 60, 0, - 0, 32, 0, 0, 33, 34, 35, 36, 0, 0, - 0, 37, 38, 0, 39, 40, 41, 0, 204, 0, - 0, 42, 43, 44, 45, 46, 0, 0, 48, 49, - 23, 0, 0, 52, 168, 50, 0, 0, 0, 53, - 0, 54, 55, 0, 39, 39, 39, 39, 39, 39, - 0, 39, 39, 39, 0, 0, 0, 39, 0, 0, - 39, 39, 39, 39, 0, 0, 150, 39, 39, 0, - 39, 39, 39, 0, 0, 0, 0, 39, 39, 39, - 39, 39, 0, 0, 39, 39, 0, 0, 0, 0, - 168, 39, 0, 0, 0, 39, 0, 39, 39, 0, - 0, 119, 25, 26, 27, 28, 85, 29, 30, 31, - 319, 0, 0, 32, 0, 0, 0, 0, 0, 0, - 0, 0, 150, 0, 38, 0, 39, 40, 41, 0, - 0, 0, 157, 42, 43, 44, 45, 46, 0, 0, - 48, 49, 0, 0, 0, 0, 0, 50, 0, 0, - 0, 53, 0, 54, 55, 135, 135, 135, 135, 0, - 168, 0, 0, 0, 109, 25, 26, 27, 28, 0, - 29, 30, 31, 0, 0, 0, 32, 135, 135, 0, - 0, 0, 0, 0, 0, 0, 0, 38, 0, 39, - 40, 41, 150, 0, 0, 0, 42, 43, 44, 45, - 46, 0, 0, 48, 49, 0, 0, 0, 0, 0, - 50, 0, 0, 0, 53, 51, 54, 55, 61, 63, - 47, 0, 56, 0, 64, 59, 0, 58, 152, 153, - 154, 155, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 114, 0, 159, 160, 161, 62, 162, 163, 0, - 0, 164, 0, 0, 165, 166, 167, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 51, 0, 60, 61, 63, 47, 0, 56, 0, - 64, 59, 0, 58, 152, 153, 154, 155, 0, 0, +#define YYTABLESIZE 4359 +short yytable[] = { 69, + 62, 180, 93, 62, 102, 93, 251, 203, 20, 206, + 207, 201, 283, 181, 167, 246, 80, 272, 82, 93, + 93, 296, 269, 149, 93, 57, 149, 169, 171, 84, + 343, 93, 121, 309, 290, 97, 292, 15, 122, 18, + 149, 149, 310, 131, 204, 149, 149, 135, 186, 187, + 188, 189, 190, 191, 93, 15, 311, 18, 317, 168, + 170, 361, 169, 273, 147, 148, 38, 16, 340, 341, + 98, 99, 141, 149, 100, 149, 338, 339, 25, 23, + 291, 345, 293, 62, 38, 16, 295, 233, 316, 57, + 23, 17, 195, 196, 168, 105, 106, 353, 172, 37, + 107, 356, 308, 174, 39, 149, 173, 23, 175, 17, + 177, 25, 179, 319, 25, 25, 25, 37, 25, 182, + 25, 25, 15, 25, 192, 294, 193, 200, 202, 209, + 210, 212, 213, 214, 215, 216, 330, 25, 234, 205, + 249, 62, 25, 271, 274, 4, 5, 6, 70, 7, + 8, 70, 282, 237, 238, 239, 240, 241, 242, 244, + 280, 130, 312, 148, 130, 70, 70, 289, 196, 25, + 231, 297, 256, 210, 298, 210, 300, 266, 130, 130, + 67, 355, 301, 130, 275, 20, 277, 279, 302, 303, + 304, 281, 305, 318, 306, 334, 307, 314, 67, 320, + 70, 25, 321, 25, 25, 322, 19, 333, 335, 323, + 336, 130, 325, 130, 147, 148, 344, 285, 20, 287, + 288, 20, 20, 20, 87, 20, 346, 20, 20, 88, + 20, 350, 67, 93, 93, 93, 93, 166, 147, 148, + 147, 148, 93, 130, 20, 147, 148, 357, 358, 20, + 147, 148, 348, 51, 149, 149, 149, 149, 93, 93, + 101, 93, 93, 149, 2, 147, 148, 57, 313, 149, + 149, 149, 149, 147, 148, 196, 20, 147, 148, 149, + 149, 34, 149, 149, 149, 149, 149, 149, 149, 147, + 148, 149, 160, 256, 149, 149, 149, 43, 147, 148, + 43, 43, 43, 36, 43, 232, 43, 43, 20, 43, + 20, 20, 147, 148, 147, 148, 147, 148, 147, 148, + 147, 148, 161, 43, 147, 148, 147, 148, 43, 147, + 148, 158, 69, 39, 25, 25, 25, 25, 25, 25, + 34, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 36, 43, 21, 25, 25, 96, + 25, 25, 25, 25, 25, 250, 147, 148, 156, 25, + 25, 25, 25, 25, 25, 77, 211, 25, 332, 70, + 70, 70, 70, 352, 263, 185, 25, 43, 25, 25, + 43, 0, 130, 130, 130, 130, 167, 147, 148, 147, + 148, 130, 0, 0, 70, 70, 167, 130, 130, 130, + 130, 67, 67, 67, 67, 0, 0, 130, 130, 0, + 130, 130, 130, 130, 130, 130, 130, 0, 149, 130, + 167, 0, 130, 130, 130, 0, 67, 67, 149, 0, + 0, 20, 20, 20, 20, 20, 20, 0, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 0, 149, 0, 20, 20, 0, 20, 20, 20, + 20, 20, 143, 144, 145, 146, 20, 20, 20, 20, + 20, 20, 156, 0, 20, 156, 167, 0, 0, 0, + 0, 0, 0, 20, 0, 20, 20, 147, 148, 156, + 156, 0, 0, 0, 156, 0, 4, 5, 6, 0, + 7, 8, 0, 0, 0, 0, 0, 0, 149, 0, + 43, 43, 43, 43, 43, 43, 354, 43, 43, 43, + 0, 0, 156, 43, 156, 0, 43, 43, 43, 43, + 0, 0, 0, 43, 43, 0, 43, 43, 43, 43, + 43, 0, 0, 0, 0, 43, 43, 43, 43, 43, + 43, 0, 0, 43, 156, 0, 0, 0, 0, 0, + 167, 0, 43, 172, 43, 43, 172, 172, 172, 0, + 172, 156, 172, 172, 156, 172, 150, 0, 0, 0, + 0, 0, 151, 152, 153, 154, 0, 0, 156, 156, + 0, 0, 149, 156, 172, 155, 157, 158, 159, 160, + 161, 162, 0, 0, 163, 0, 0, 164, 165, 166, + 0, 162, 0, 0, 163, 0, 0, 164, 165, 166, + 0, 156, 0, 156, 173, 0, 0, 173, 173, 173, + 0, 173, 113, 173, 173, 113, 173, 0, 163, 0, + 0, 164, 165, 166, 0, 0, 0, 0, 0, 113, + 113, 0, 0, 156, 113, 173, 172, 4, 5, 6, + 0, 7, 8, 0, 0, 0, 0, 0, 0, 327, + 328, 329, 0, 331, 153, 154, 0, 0, 0, 0, + 0, 67, 0, 52, 113, 0, 62, 64, 50, 0, + 57, 162, 65, 60, 163, 59, 0, 164, 165, 166, + 347, 0, 0, 156, 156, 156, 156, 349, 0, 58, + 108, 351, 156, 117, 63, 0, 0, 173, 156, 156, + 156, 156, 0, 0, 359, 360, 0, 0, 156, 156, + 0, 156, 156, 156, 156, 156, 156, 156, 0, 0, + 156, 61, 0, 156, 156, 156, 0, 0, 66, 176, + 0, 66, 0, 0, 0, 0, 151, 152, 153, 154, + 0, 0, 0, 184, 0, 0, 66, 0, 0, 167, + 0, 0, 0, 23, 161, 162, 53, 0, 163, 0, + 0, 164, 165, 166, 0, 0, 0, 172, 172, 172, + 172, 172, 0, 172, 172, 172, 0, 0, 0, 172, + 66, 149, 156, 156, 156, 156, 0, 0, 0, 208, + 172, 156, 172, 172, 172, 172, 172, 156, 156, 156, + 156, 172, 172, 172, 172, 172, 172, 156, 156, 172, + 156, 156, 156, 156, 156, 156, 156, 0, 172, 156, + 172, 172, 156, 156, 156, 0, 247, 0, 173, 173, + 173, 173, 173, 255, 173, 173, 173, 0, 0, 0, + 173, 0, 0, 113, 113, 113, 113, 0, 0, 0, + 0, 173, 113, 173, 173, 173, 173, 173, 113, 113, + 113, 113, 173, 173, 173, 173, 173, 173, 113, 113, + 173, 113, 113, 113, 113, 113, 113, 113, 0, 173, + 113, 173, 173, 113, 113, 113, 22, 24, 25, 26, + 27, 28, 0, 29, 30, 31, 0, 0, 0, 32, + 0, 167, 33, 34, 35, 36, 0, 0, 0, 37, + 38, 0, 39, 40, 41, 42, 43, 0, 0, 167, + 112, 44, 45, 46, 47, 48, 49, 43, 124, 51, + 43, 43, 43, 149, 43, 0, 43, 43, 54, 43, + 55, 56, 0, 0, 0, 151, 0, 153, 154, 0, + 0, 149, 0, 43, 0, 0, 0, 0, 43, 66, + 66, 66, 66, 161, 162, 0, 0, 163, 112, 0, + 164, 165, 166, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 52, 66, 43, 62, 64, 50, 0, + 57, 199, 65, 60, 92, 59, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 62, 162, 163, 0, 0, 164, 52, 0, - 165, 166, 167, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 51, 0, 60, - 61, 63, 47, 0, 56, 131, 64, 59, 0, 58, + 0, 114, 115, 0, 63, 0, 0, 43, 123, 0, + 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 136, 137, 138, 139, 0, 0, 0, 0, 0, 52, + 0, 61, 62, 64, 50, 0, 57, 0, 65, 60, + 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 151, 0, 0, 0, 152, 153, 154, 155, 62, 0, - 0, 23, 0, 0, 52, 0, 0, 156, 158, 159, - 160, 161, 0, 162, 163, 0, 0, 164, 0, 0, - 165, 166, 167, 0, 0, 60, 0, 0, 0, 0, - 51, 0, 0, 61, 63, 47, 0, 56, 0, 64, - 59, 0, 58, 0, 0, 0, 0, 0, 0, 0, + 63, 0, 0, 23, 0, 198, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 52, 62, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, - 25, 26, 27, 28, 0, 29, 30, 31, 60, 0, - 135, 32, 0, 0, 0, 168, 0, 0, 0, 0, - 0, 0, 38, 0, 39, 40, 41, 0, 0, 0, - 0, 42, 43, 44, 45, 46, 0, 157, 48, 49, - 0, 0, 0, 52, 0, 50, 0, 150, 0, 53, - 0, 54, 55, 0, 0, 24, 25, 26, 27, 28, - 0, 29, 30, 31, 0, 168, 0, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 61, 0, 153, + 154, 0, 52, 0, 0, 62, 64, 50, 0, 57, + 0, 65, 60, 0, 59, 161, 162, 153, 0, 163, + 0, 0, 164, 165, 166, 0, 112, 0, 0, 23, + 0, 112, 53, 63, 162, 0, 0, 163, 0, 0, + 164, 165, 166, 0, 0, 0, 0, 0, 0, 0, + 43, 43, 43, 43, 43, 43, 0, 43, 43, 43, + 61, 0, 0, 43, 0, 0, 43, 43, 43, 43, + 0, 0, 0, 43, 43, 0, 43, 43, 43, 43, + 43, 0, 0, 0, 0, 43, 43, 43, 43, 43, + 43, 167, 23, 43, 0, 53, 0, 0, 0, 0, + 0, 0, 43, 252, 43, 43, 253, 110, 25, 26, + 27, 28, 88, 29, 30, 31, 0, 0, 0, 32, + 0, 0, 0, 149, 0, 156, 0, 0, 0, 0, + 38, 0, 39, 40, 41, 42, 43, 0, 0, 0, + 0, 44, 45, 46, 47, 48, 49, 0, 0, 51, + 0, 0, 0, 167, 0, 0, 0, 324, 54, 0, + 55, 56, 0, 24, 25, 26, 27, 28, 0, 29, + 30, 31, 0, 0, 0, 32, 0, 0, 0, 156, + 0, 0, 0, 0, 0, 149, 38, 0, 39, 40, + 41, 42, 43, 0, 0, 0, 0, 44, 45, 46, + 47, 48, 49, 0, 0, 51, 0, 167, 0, 0, + 0, 0, 0, 0, 54, 0, 55, 56, 0, 0, + 0, 0, 0, 0, 0, 0, 116, 25, 26, 27, + 28, 0, 29, 30, 31, 0, 0, 0, 32, 149, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, + 0, 39, 40, 41, 42, 43, 0, 0, 0, 167, + 44, 45, 46, 47, 48, 49, 52, 0, 51, 62, + 64, 50, 0, 57, 0, 65, 60, 54, 59, 55, + 56, 0, 0, 0, 0, 0, 0, 151, 152, 153, + 154, 149, 120, 0, 0, 0, 0, 63, 0, 0, + 0, 157, 158, 159, 160, 161, 162, 0, 0, 163, + 0, 0, 164, 165, 166, 0, 0, 0, 0, 0, + 0, 0, 52, 0, 61, 62, 64, 50, 0, 57, + 130, 65, 60, 0, 59, 0, 0, 0, 0, 0, + 0, 0, 0, 150, 0, 0, 0, 0, 0, 151, + 152, 153, 154, 63, 0, 0, 0, 0, 0, 53, + 0, 0, 155, 157, 158, 159, 160, 161, 162, 0, + 0, 163, 0, 0, 164, 165, 166, 0, 52, 0, + 61, 62, 64, 50, 0, 57, 0, 65, 60, 0, + 59, 0, 0, 0, 0, 0, 0, 150, 0, 0, + 0, 0, 0, 151, 152, 153, 154, 0, 0, 63, + 0, 0, 0, 0, 0, 53, 155, 157, 158, 159, + 160, 161, 162, 0, 0, 163, 0, 0, 164, 165, + 166, 0, 0, 0, 0, 0, 61, 52, 134, 0, + 62, 64, 50, 0, 57, 194, 65, 60, 0, 59, + 0, 0, 0, 0, 0, 151, 152, 153, 154, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, + 0, 53, 160, 161, 162, 0, 0, 163, 0, 0, + 164, 165, 166, 0, 0, 0, 87, 0, 0, 87, + 24, 25, 26, 27, 28, 61, 29, 30, 31, 0, + 0, 0, 32, 87, 87, 0, 0, 0, 87, 0, + 0, 0, 0, 38, 0, 39, 40, 41, 42, 43, + 0, 0, 0, 0, 44, 45, 46, 47, 48, 49, + 53, 0, 51, 0, 0, 0, 0, 0, 87, 0, + 0, 54, 88, 55, 56, 88, 24, 25, 26, 27, + 28, 0, 29, 30, 31, 0, 0, 0, 32, 88, + 88, 0, 0, 0, 88, 0, 0, 0, 0, 38, + 0, 39, 40, 41, 42, 43, 0, 0, 0, 0, + 44, 45, 46, 47, 48, 49, 0, 0, 51, 0, + 0, 0, 0, 0, 88, 0, 0, 54, 0, 55, + 56, 0, 24, 25, 26, 27, 28, 0, 29, 30, + 31, 0, 52, 0, 32, 62, 64, 50, 0, 57, + 243, 65, 60, 0, 59, 38, 0, 39, 40, 41, + 42, 43, 0, 0, 0, 0, 44, 45, 46, 47, + 48, 49, 0, 63, 51, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 0, 55, 56, 0, 0, 0, + 0, 24, 25, 26, 27, 28, 0, 29, 30, 31, + 61, 52, 0, 32, 62, 64, 50, 0, 57, 0, + 65, 60, 0, 59, 38, 0, 39, 40, 41, 42, + 43, 0, 0, 0, 0, 44, 45, 46, 47, 48, + 49, 0, 63, 51, 0, 53, 0, 0, 0, 0, + 0, 0, 54, 0, 55, 56, 0, 87, 87, 87, + 87, 0, 0, 0, 0, 0, 87, 52, 0, 61, + 62, 64, 50, 87, 57, 276, 65, 60, 0, 59, + 0, 0, 87, 87, 0, 87, 87, 87, 87, 87, + 0, 0, 0, 0, 0, 0, 0, 0, 63, 0, + 0, 0, 0, 0, 53, 0, 0, 0, 0, 0, + 0, 0, 0, 88, 88, 88, 88, 0, 0, 0, + 0, 0, 88, 52, 0, 61, 62, 64, 50, 0, + 57, 278, 65, 60, 0, 59, 0, 0, 88, 88, + 0, 88, 88, 88, 88, 88, 0, 0, 0, 0, + 0, 0, 0, 0, 63, 0, 0, 0, 0, 0, + 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 25, 26, 27, + 28, 61, 29, 30, 31, 0, 52, 0, 32, 62, + 64, 50, 0, 57, 286, 65, 60, 0, 59, 38, + 0, 39, 40, 41, 42, 43, 0, 0, 0, 0, + 44, 45, 46, 47, 48, 49, 53, 63, 51, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 55, + 56, 0, 0, 0, 22, 24, 25, 26, 27, 28, + 0, 29, 30, 31, 61, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, - 39, 40, 41, 0, 0, 0, 0, 42, 43, 44, - 45, 46, 0, 0, 48, 49, 168, 150, 0, 0, - 0, 50, 0, 82, 0, 53, 82, 54, 55, 0, + 39, 40, 41, 42, 43, 0, 0, 0, 0, 44, + 45, 46, 47, 48, 49, 0, 0, 51, 0, 53, + 167, 0, 0, 0, 115, 0, 54, 115, 55, 56, 0, 24, 25, 26, 27, 28, 0, 29, 30, 31, - 82, 82, 0, 32, 0, 82, 0, 0, 150, 0, - 0, 0, 0, 0, 38, 0, 39, 40, 41, 0, - 0, 0, 0, 42, 43, 44, 45, 46, 0, 0, - 48, 49, 0, 0, 0, 82, 0, 50, 0, 0, - 0, 53, 0, 54, 55, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 24, 25, 26, 27, 28, 0, - 29, 30, 31, 0, 51, 0, 32, 61, 63, 47, - 0, 56, 0, 64, 59, 0, 58, 38, 0, 39, - 40, 41, 0, 0, 0, 0, 42, 43, 44, 45, - 46, 154, 155, 48, 49, 62, 0, 0, 0, 0, - 50, 0, 0, 0, 53, 0, 54, 55, 162, 163, - 0, 0, 164, 0, 0, 165, 166, 167, 0, 0, - 51, 0, 60, 61, 63, 47, 0, 56, 200, 64, - 59, 0, 58, 0, 0, 151, 0, 0, 0, 152, - 153, 154, 155, 0, 0, 0, 0, 0, 0, 0, - 0, 62, 156, 158, 159, 160, 161, 52, 162, 163, - 0, 0, 164, 0, 0, 165, 166, 167, 0, 0, - 152, 0, 154, 155, 0, 0, 51, 0, 60, 61, - 63, 47, 0, 56, 248, 64, 59, 0, 58, 162, - 163, 0, 0, 164, 0, 0, 165, 166, 167, 0, - 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, - 0, 0, 0, 52, 82, 82, 82, 82, 0, 0, - 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 60, 0, 82, 82, 0, 51, - 82, 82, 61, 63, 47, 0, 56, 276, 64, 59, - 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, - 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 22, 24, 25, - 26, 27, 28, 0, 29, 30, 31, 60, 0, 0, - 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 38, 0, 39, 40, 41, 0, 0, 0, 0, - 42, 43, 44, 45, 46, 0, 0, 48, 49, 0, - 0, 0, 52, 0, 50, 0, 119, 0, 53, 119, - 54, 55, 0, 0, 24, 25, 26, 27, 28, 0, - 29, 30, 31, 119, 119, 0, 32, 0, 119, 0, - 0, 0, 0, 0, 0, 0, 0, 38, 0, 39, - 40, 41, 0, 0, 0, 0, 42, 43, 44, 45, - 46, 0, 0, 48, 49, 0, 119, 0, 119, 0, - 50, 0, 143, 0, 53, 143, 54, 55, 0, 0, - 24, 25, 26, 27, 28, 0, 29, 30, 31, 143, - 143, 0, 32, 0, 143, 0, 0, 0, 119, 0, - 0, 0, 0, 38, 0, 39, 40, 41, 0, 0, - 0, 0, 42, 43, 44, 45, 46, 0, 0, 48, - 49, 0, 143, 0, 143, 0, 50, 0, 0, 0, - 53, 0, 54, 55, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 24, 25, 26, 27, 28, 0, 29, - 30, 31, 0, 51, 143, 32, 61, 63, 47, 0, - 56, 278, 64, 59, 0, 58, 38, 0, 39, 40, - 41, 0, 0, 0, 0, 42, 43, 44, 45, 46, - 0, 0, 48, 49, 62, 0, 87, 87, 0, 50, - 0, 0, 0, 53, 0, 54, 55, 0, 103, 0, - 0, 0, 0, 87, 112, 0, 0, 0, 87, 51, - 121, 60, 61, 63, 47, 0, 56, 0, 64, 59, - 0, 58, 87, 87, 87, 87, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 62, 0, 0, 0, 0, 0, 52, 119, 119, 119, - 119, 0, 0, 0, 0, 0, 119, 0, 0, 0, - 119, 119, 119, 119, 0, 0, 0, 60, 121, 119, - 119, 0, 0, 119, 119, 119, 119, 119, 0, 119, - 119, 0, 130, 119, 0, 130, 119, 119, 119, 0, - 0, 0, 0, 129, 0, 0, 129, 0, 0, 130, - 130, 0, 52, 143, 143, 143, 143, 0, 0, 0, - 129, 129, 143, 0, 0, 129, 143, 143, 143, 143, - 0, 0, 0, 0, 0, 143, 143, 0, 240, 143, - 143, 143, 143, 143, 130, 143, 143, 0, 104, 143, - 0, 104, 143, 143, 143, 129, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 104, 104, 0, 0, 0, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 129, 0, 24, 25, 26, - 27, 28, 0, 29, 30, 31, 0, 0, 104, 32, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 38, 0, 39, 40, 41, 0, 0, 0, 0, 42, - 43, 44, 45, 46, 0, 0, 48, 49, 0, 0, - 0, 0, 0, 50, 0, 145, 0, 53, 145, 54, - 55, 0, 0, 24, 25, 26, 27, 28, 0, 29, - 30, 31, 145, 145, 0, 32, 0, 145, 0, 0, - 0, 0, 0, 0, 0, 0, 38, 0, 39, 40, - 41, 0, 0, 0, 0, 42, 43, 44, 45, 46, - 0, 0, 48, 49, 0, 0, 0, 145, 0, 50, - 131, 0, 0, 53, 0, 54, 55, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 131, 131, 0, - 0, 0, 131, 0, 0, 0, 0, 145, 0, 0, - 0, 0, 0, 130, 130, 130, 130, 0, 0, 0, - 0, 0, 0, 0, 129, 129, 129, 129, 0, 0, - 131, 0, 131, 129, 0, 130, 130, 129, 129, 129, - 129, 0, 0, 0, 0, 0, 129, 129, 0, 0, - 129, 129, 129, 129, 129, 0, 129, 129, 0, 0, - 129, 0, 131, 129, 129, 129, 0, 0, 0, 104, - 104, 104, 104, 0, 0, 0, 0, 0, 104, 0, - 0, 0, 104, 104, 104, 104, 0, 0, 0, 0, - 0, 104, 104, 0, 146, 104, 104, 104, 104, 104, - 0, 104, 104, 0, 0, 104, 0, 0, 104, 104, - 104, 146, 146, 0, 0, 0, 146, 0, 0, 0, + 0, 115, 115, 32, 0, 0, 115, 0, 0, 0, + 0, 0, 149, 0, 38, 0, 39, 40, 41, 42, + 43, 0, 0, 0, 0, 44, 45, 46, 47, 48, + 49, 0, 0, 51, 115, 0, 115, 0, 0, 0, + 0, 0, 54, 0, 55, 56, 0, 24, 25, 26, + 27, 28, 0, 29, 30, 31, 0, 52, 0, 32, + 62, 64, 50, 0, 57, 0, 65, 60, 0, 59, + 38, 0, 39, 40, 41, 42, 43, 0, 0, 0, + 0, 44, 45, 46, 47, 48, 49, 0, 63, 51, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, + 55, 56, 0, 0, 0, 0, 142, 0, 0, 142, + 24, 25, 26, 27, 28, 61, 29, 30, 31, 0, + 0, 0, 32, 142, 142, 0, 0, 0, 142, 0, + 0, 0, 0, 38, 0, 39, 40, 41, 42, 43, + 0, 0, 0, 0, 44, 45, 46, 47, 48, 49, + 53, 0, 51, 158, 0, 0, 158, 0, 142, 0, + 0, 54, 0, 55, 56, 0, 0, 0, 0, 0, + 158, 158, 0, 0, 0, 158, 151, 152, 153, 154, + 0, 0, 0, 0, 0, 0, 0, 0, 142, 0, + 0, 158, 159, 160, 161, 162, 0, 0, 163, 0, + 0, 164, 165, 166, 0, 158, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 115, 115, 115, 115, 0, + 159, 0, 0, 0, 115, 0, 0, 0, 0, 0, + 115, 115, 115, 115, 0, 158, 0, 159, 159, 0, + 115, 115, 159, 115, 115, 115, 115, 115, 115, 115, + 0, 0, 115, 0, 0, 115, 115, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 159, 0, 159, 0, 144, 0, 0, 0, 0, 0, + 0, 24, 25, 26, 27, 28, 0, 29, 30, 31, + 0, 144, 144, 32, 0, 0, 144, 0, 0, 0, + 0, 0, 159, 0, 38, 0, 39, 40, 41, 42, + 43, 0, 0, 0, 0, 44, 45, 46, 47, 48, + 49, 0, 0, 51, 144, 0, 144, 0, 0, 0, + 94, 0, 54, 94, 55, 56, 0, 142, 142, 142, + 142, 0, 0, 0, 0, 0, 142, 94, 94, 0, + 0, 0, 142, 142, 142, 142, 144, 0, 0, 0, + 0, 0, 142, 142, 0, 142, 142, 142, 142, 142, + 142, 142, 0, 0, 142, 0, 0, 142, 142, 142, + 0, 0, 94, 0, 158, 158, 158, 158, 0, 107, + 0, 0, 107, 158, 0, 0, 0, 0, 0, 158, + 158, 158, 158, 0, 0, 0, 107, 107, 0, 158, + 158, 107, 158, 158, 158, 158, 158, 158, 158, 90, + 90, 158, 0, 0, 158, 158, 158, 0, 0, 0, + 0, 103, 0, 0, 0, 0, 0, 111, 90, 119, + 0, 107, 0, 0, 90, 0, 0, 0, 0, 0, + 0, 159, 159, 159, 159, 0, 90, 90, 90, 90, + 159, 0, 0, 0, 0, 0, 159, 159, 159, 159, + 0, 107, 68, 0, 0, 68, 159, 159, 0, 159, + 159, 159, 159, 159, 159, 159, 0, 0, 159, 68, + 68, 159, 159, 159, 68, 0, 0, 0, 0, 0, + 0, 111, 0, 0, 0, 144, 144, 144, 144, 0, + 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, + 144, 144, 144, 144, 68, 0, 71, 0, 0, 0, + 144, 144, 0, 144, 144, 144, 144, 144, 144, 144, + 0, 0, 144, 71, 71, 144, 144, 144, 71, 0, + 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, + 235, 94, 94, 94, 94, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 106, 0, 71, 106, 71, 0, + 0, 0, 0, 0, 264, 0, 94, 94, 0, 94, + 0, 106, 106, 0, 0, 0, 106, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 146, 0, 146, 0, 0, 0, + 107, 107, 107, 107, 0, 145, 106, 0, 145, 107, + 0, 0, 0, 0, 0, 107, 107, 107, 107, 0, + 0, 0, 145, 145, 0, 107, 107, 145, 107, 107, + 107, 107, 107, 107, 107, 0, 106, 107, 0, 0, + 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, + 158, 0, 0, 158, 0, 0, 0, 145, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 158, 158, 0, + 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 68, 68, 68, 68, 0, 0, 0, + 0, 0, 68, 0, 0, 0, 0, 0, 68, 68, + 68, 68, 158, 0, 113, 0, 0, 113, 68, 68, + 0, 68, 68, 68, 68, 68, 68, 68, 0, 0, + 68, 113, 113, 68, 68, 68, 113, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 71, 71, 71, + 71, 0, 0, 0, 0, 0, 71, 0, 0, 0, + 0, 0, 71, 71, 71, 71, 113, 0, 0, 0, + 0, 0, 71, 71, 0, 71, 71, 71, 71, 71, + 71, 71, 0, 0, 71, 0, 0, 71, 71, 71, + 0, 0, 0, 0, 0, 106, 106, 106, 106, 0, + 120, 0, 0, 120, 106, 0, 0, 0, 0, 0, + 106, 106, 106, 106, 0, 0, 0, 120, 120, 0, + 106, 106, 120, 106, 106, 106, 106, 106, 106, 106, + 0, 0, 106, 0, 0, 106, 106, 106, 0, 0, 0, 0, 0, 0, 0, 0, 145, 145, 145, 145, - 0, 0, 0, 0, 0, 145, 0, 0, 0, 145, - 145, 145, 145, 0, 0, 0, 146, 0, 145, 145, - 0, 0, 145, 145, 145, 145, 145, 0, 145, 145, - 59, 0, 145, 59, 0, 145, 145, 145, 0, 0, - 0, 96, 0, 0, 96, 0, 0, 59, 59, 0, - 0, 131, 131, 131, 131, 0, 0, 0, 96, 96, - 131, 0, 0, 96, 131, 131, 131, 131, 0, 0, - 0, 0, 0, 131, 131, 0, 0, 131, 131, 131, - 131, 131, 59, 131, 131, 0, 0, 131, 0, 0, - 131, 131, 131, 96, 58, 0, 0, 58, 0, 0, + 0, 103, 120, 0, 103, 145, 0, 0, 0, 0, + 0, 145, 145, 145, 145, 0, 0, 0, 103, 103, + 0, 145, 145, 103, 145, 145, 145, 145, 145, 145, + 145, 0, 0, 145, 0, 0, 145, 145, 145, 0, + 0, 158, 158, 158, 158, 0, 0, 0, 0, 0, + 158, 0, 0, 103, 0, 0, 158, 158, 158, 158, + 0, 0, 104, 0, 0, 104, 158, 158, 0, 158, + 158, 158, 158, 158, 158, 158, 0, 0, 158, 104, + 104, 158, 158, 158, 104, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 113, 113, 113, 113, 0, + 98, 0, 0, 98, 113, 0, 0, 0, 0, 0, + 113, 113, 113, 113, 104, 0, 0, 98, 98, 0, + 113, 113, 98, 113, 113, 113, 113, 113, 113, 113, + 0, 0, 113, 0, 0, 113, 113, 113, 0, 99, + 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, + 89, 0, 98, 89, 0, 0, 99, 99, 0, 0, + 0, 99, 0, 0, 0, 0, 0, 89, 89, 0, + 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, + 0, 120, 120, 120, 120, 0, 100, 0, 0, 100, + 120, 99, 0, 0, 0, 0, 120, 120, 120, 120, + 0, 0, 89, 100, 100, 0, 120, 120, 100, 120, + 120, 120, 120, 120, 120, 120, 0, 0, 120, 0, + 0, 120, 120, 120, 0, 0, 0, 0, 0, 0, + 0, 0, 103, 103, 103, 103, 0, 96, 100, 0, + 96, 103, 0, 0, 0, 0, 0, 103, 103, 103, + 103, 0, 0, 0, 96, 96, 0, 103, 103, 96, + 103, 103, 103, 103, 103, 103, 103, 0, 0, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 58, 58, 0, 0, 0, 58, 0, 0, 0, - 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, - 95, 0, 0, 0, 0, 0, 58, 0, 0, 0, - 0, 0, 0, 0, 95, 95, 0, 0, 0, 95, - 0, 0, 0, 0, 0, 146, 146, 146, 146, 0, - 0, 0, 0, 0, 146, 0, 58, 0, 146, 146, - 146, 146, 0, 0, 0, 61, 0, 146, 146, 95, - 0, 146, 146, 146, 146, 146, 0, 146, 146, 0, - 0, 146, 61, 61, 146, 146, 146, 61, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, - 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, - 145, 0, 0, 0, 0, 61, 0, 61, 0, 0, - 0, 0, 0, 0, 145, 145, 0, 0, 0, 145, + 0, 0, 0, 97, 0, 0, 97, 0, 0, 96, + 0, 0, 0, 104, 104, 104, 104, 0, 0, 0, + 97, 97, 104, 0, 0, 97, 0, 0, 104, 104, + 104, 104, 0, 0, 0, 0, 0, 0, 104, 104, + 0, 104, 104, 104, 104, 104, 104, 104, 0, 0, + 104, 98, 98, 98, 98, 97, 0, 0, 0, 0, + 98, 0, 0, 0, 0, 0, 98, 98, 98, 98, + 0, 0, 0, 0, 0, 0, 98, 98, 0, 98, + 98, 98, 98, 98, 98, 98, 0, 0, 0, 0, + 99, 99, 99, 99, 0, 95, 0, 0, 95, 99, + 0, 89, 89, 89, 89, 99, 99, 99, 99, 0, + 89, 0, 95, 95, 0, 99, 99, 95, 99, 99, + 99, 99, 99, 99, 99, 0, 89, 89, 0, 89, + 89, 89, 89, 89, 0, 0, 0, 100, 100, 100, + 100, 0, 83, 0, 0, 83, 100, 95, 0, 0, + 0, 0, 100, 100, 100, 100, 0, 0, 0, 83, + 83, 0, 100, 100, 83, 100, 100, 100, 100, 100, + 100, 100, 0, 0, 0, 0, 0, 0, 84, 0, + 0, 84, 0, 0, 0, 0, 0, 0, 96, 96, + 96, 96, 0, 0, 83, 84, 84, 96, 0, 0, + 84, 0, 0, 96, 96, 96, 96, 0, 0, 0, + 0, 0, 0, 96, 96, 0, 96, 96, 96, 96, + 96, 96, 96, 85, 0, 0, 85, 0, 0, 0, + 84, 0, 0, 0, 97, 97, 97, 97, 0, 0, + 85, 85, 0, 97, 0, 85, 0, 0, 0, 97, + 97, 97, 97, 0, 0, 0, 0, 0, 0, 97, + 97, 0, 97, 97, 97, 97, 97, 97, 97, 86, + 0, 0, 86, 0, 0, 85, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 86, 0, 0, + 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 59, 59, 59, 59, 0, 0, 61, 0, 0, - 0, 0, 96, 96, 96, 96, 0, 0, 0, 145, - 0, 96, 0, 59, 59, 96, 96, 96, 96, 0, - 0, 0, 0, 0, 96, 96, 0, 0, 96, 96, - 96, 96, 96, 0, 96, 96, 0, 0, 96, 0, - 0, 96, 96, 96, 0, 132, 0, 0, 132, 0, - 0, 0, 0, 0, 0, 58, 58, 58, 58, 0, - 0, 0, 132, 132, 58, 0, 0, 132, 58, 58, - 58, 58, 0, 0, 0, 0, 0, 58, 58, 0, - 0, 58, 58, 58, 58, 58, 0, 58, 58, 0, - 0, 58, 0, 0, 58, 58, 58, 132, 95, 95, - 95, 95, 0, 0, 0, 71, 0, 95, 71, 0, + 0, 0, 0, 0, 148, 0, 0, 148, 0, 0, + 0, 86, 0, 0, 0, 0, 95, 95, 95, 95, + 0, 148, 148, 0, 0, 95, 148, 0, 0, 0, 0, 95, 95, 95, 95, 0, 0, 0, 0, 0, - 95, 95, 71, 71, 95, 95, 95, 95, 95, 0, - 95, 95, 0, 0, 95, 0, 0, 95, 95, 95, - 0, 0, 0, 0, 0, 0, 61, 61, 61, 61, - 0, 0, 0, 0, 0, 61, 0, 71, 0, 61, - 61, 61, 61, 0, 0, 0, 0, 0, 61, 61, - 0, 157, 61, 61, 61, 61, 61, 0, 61, 61, - 0, 0, 61, 0, 0, 61, 61, 61, 145, 145, - 145, 145, 0, 0, 0, 0, 0, 145, 0, 168, - 0, 145, 145, 145, 145, 0, 0, 0, 0, 0, - 145, 145, 0, 0, 145, 145, 145, 145, 145, 102, - 145, 145, 102, 0, 145, 0, 0, 145, 145, 145, - 0, 150, 0, 0, 0, 0, 102, 102, 0, 0, - 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 109, 0, 0, 109, - 0, 102, 0, 0, 0, 0, 132, 132, 132, 132, - 0, 0, 0, 109, 109, 132, 0, 0, 109, 132, - 132, 132, 132, 0, 0, 0, 0, 0, 132, 132, - 0, 0, 132, 132, 132, 132, 132, 0, 132, 132, - 92, 0, 132, 92, 0, 132, 132, 132, 109, 0, - 0, 0, 0, 0, 0, 0, 0, 92, 92, 0, - 0, 0, 92, 0, 0, 0, 71, 71, 71, 71, - 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, - 93, 0, 0, 0, 0, 0, 0, 0, 71, 71, - 0, 0, 92, 0, 93, 93, 0, 0, 0, 93, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 87, 0, 0, 87, 0, 151, - 0, 0, 0, 152, 153, 154, 155, 0, 0, 93, - 0, 87, 87, 0, 0, 0, 87, 158, 159, 160, - 161, 0, 162, 163, 0, 0, 164, 0, 0, 165, - 166, 167, 88, 0, 0, 88, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 87, 0, 0, 88, - 88, 0, 0, 0, 88, 0, 0, 0, 0, 0, - 102, 102, 102, 102, 0, 0, 0, 0, 0, 102, - 0, 0, 0, 102, 102, 102, 102, 0, 0, 0, - 0, 0, 102, 102, 88, 0, 102, 102, 102, 102, - 102, 0, 102, 102, 0, 0, 102, 0, 0, 102, - 102, 102, 0, 0, 0, 0, 0, 109, 109, 109, - 109, 0, 0, 0, 0, 0, 109, 0, 0, 0, - 109, 109, 109, 109, 0, 0, 0, 0, 0, 109, - 109, 0, 0, 109, 109, 109, 109, 109, 0, 109, - 109, 89, 0, 109, 89, 0, 109, 109, 109, 0, - 0, 92, 92, 92, 92, 0, 0, 0, 89, 89, - 92, 0, 0, 89, 92, 92, 92, 92, 0, 0, - 0, 0, 0, 92, 92, 0, 0, 92, 92, 92, - 92, 92, 0, 92, 92, 0, 0, 92, 93, 93, - 93, 93, 0, 89, 0, 0, 0, 93, 0, 0, - 0, 93, 93, 93, 93, 0, 0, 0, 0, 0, - 93, 93, 0, 0, 93, 93, 93, 93, 93, 0, - 93, 93, 0, 0, 93, 87, 87, 87, 87, 0, - 0, 0, 0, 0, 87, 0, 0, 0, 87, 87, - 87, 87, 0, 0, 0, 0, 0, 87, 87, 0, - 0, 87, 87, 87, 87, 87, 0, 87, 87, 0, - 0, 0, 0, 88, 88, 88, 88, 0, 0, 0, - 0, 0, 88, 0, 0, 0, 88, 88, 88, 88, - 85, 0, 0, 85, 0, 88, 88, 0, 0, 88, - 88, 88, 88, 88, 0, 88, 88, 85, 85, 0, - 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 86, 0, 0, 86, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 85, 86, 86, 0, 0, 0, 86, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 84, 0, 0, 84, 0, 0, 0, 0, 86, 0, - 0, 0, 89, 89, 89, 89, 0, 84, 84, 0, - 0, 89, 84, 0, 0, 89, 89, 89, 89, 0, - 0, 0, 0, 0, 89, 89, 0, 0, 89, 89, - 89, 89, 89, 72, 89, 89, 72, 0, 0, 0, - 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, - 72, 72, 0, 0, 0, 72, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, - 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 72, 73, 73, 0, 0, - 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 75, 0, 0, 75, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 73, 0, 75, 75, 0, 0, 0, 75, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 85, 85, 85, 85, 0, 0, 0, 0, 0, - 85, 0, 0, 0, 85, 85, 85, 85, 75, 0, - 0, 0, 0, 85, 85, 0, 0, 85, 85, 85, - 85, 85, 0, 85, 85, 0, 0, 86, 86, 86, - 86, 0, 0, 0, 0, 0, 86, 0, 0, 0, - 86, 86, 86, 86, 123, 0, 0, 123, 0, 86, - 86, 0, 0, 86, 86, 86, 86, 86, 0, 86, - 86, 123, 123, 0, 0, 0, 123, 0, 0, 0, - 0, 84, 84, 84, 84, 0, 0, 0, 0, 0, - 84, 0, 0, 0, 84, 84, 84, 84, 0, 0, - 0, 0, 0, 84, 84, 0, 123, 84, 84, 84, - 84, 84, 94, 84, 84, 94, 0, 0, 0, 0, - 0, 0, 0, 0, 72, 72, 72, 72, 0, 94, - 94, 0, 0, 72, 94, 0, 0, 72, 72, 72, - 72, 0, 0, 0, 0, 0, 72, 72, 0, 0, - 72, 72, 72, 72, 72, 0, 72, 72, 0, 0, - 73, 73, 73, 73, 94, 0, 0, 0, 0, 73, - 0, 0, 0, 73, 73, 73, 73, 0, 0, 0, - 0, 0, 73, 73, 0, 0, 73, 73, 73, 73, - 73, 134, 73, 0, 134, 0, 0, 75, 75, 75, - 75, 0, 0, 0, 0, 0, 75, 0, 134, 134, - 75, 75, 0, 134, 0, 0, 0, 0, 0, 75, - 75, 0, 0, 75, 75, 75, 75, 75, 76, 75, - 0, 76, 0, 0, 0, 0, 0, 0, 77, 0, - 0, 77, 0, 134, 0, 76, 76, 0, 0, 0, - 76, 0, 0, 0, 0, 77, 77, 0, 0, 0, - 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 78, 0, 0, 78, 0, 0, - 76, 0, 0, 0, 0, 123, 123, 123, 123, 0, - 77, 78, 78, 0, 123, 0, 78, 0, 123, 123, - 0, 0, 0, 0, 0, 0, 79, 123, 123, 79, - 0, 123, 123, 123, 123, 123, 81, 0, 0, 81, - 0, 0, 0, 79, 79, 0, 78, 0, 79, 0, - 0, 0, 0, 81, 81, 0, 0, 0, 81, 0, - 0, 0, 0, 94, 94, 94, 94, 0, 0, 284, - 0, 0, 94, 0, 157, 0, 94, 94, 79, 0, - 0, 0, 0, 0, 0, 94, 94, 0, 81, 94, - 94, 94, 94, 94, 0, 0, 0, 0, 0, 0, - 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, + 0, 95, 95, 0, 95, 95, 95, 95, 95, 95, + 95, 147, 0, 0, 147, 0, 148, 0, 0, 0, + 0, 0, 0, 83, 83, 83, 83, 0, 147, 147, + 0, 0, 83, 147, 0, 0, 0, 0, 83, 83, + 83, 83, 0, 0, 0, 0, 0, 134, 83, 83, + 134, 83, 83, 83, 83, 83, 83, 83, 0, 84, + 84, 84, 84, 147, 134, 134, 0, 0, 84, 134, + 0, 0, 0, 0, 84, 84, 84, 84, 0, 0, + 0, 0, 0, 0, 84, 84, 0, 84, 84, 84, + 84, 84, 84, 105, 0, 0, 105, 0, 0, 134, + 0, 0, 0, 0, 85, 85, 85, 85, 0, 0, + 105, 105, 0, 85, 0, 105, 0, 0, 0, 85, + 85, 0, 85, 0, 0, 0, 0, 0, 0, 85, + 85, 0, 85, 85, 85, 85, 85, 85, 90, 0, + 0, 90, 0, 0, 0, 105, 0, 0, 0, 0, + 86, 86, 86, 86, 0, 90, 90, 0, 0, 86, + 90, 0, 167, 0, 0, 86, 86, 0, 0, 0, + 92, 0, 0, 92, 0, 86, 86, 0, 86, 86, + 86, 86, 86, 86, 0, 0, 0, 92, 92, 0, + 90, 0, 92, 0, 149, 148, 148, 148, 148, 0, + 0, 0, 0, 0, 148, 0, 0, 0, 0, 0, + 148, 148, 91, 0, 0, 91, 0, 0, 0, 0, + 148, 148, 92, 148, 148, 148, 148, 148, 0, 91, + 91, 0, 143, 0, 91, 143, 0, 0, 0, 0, + 0, 0, 147, 147, 147, 147, 0, 0, 0, 143, + 143, 147, 0, 0, 0, 284, 0, 147, 147, 82, + 156, 0, 82, 0, 91, 0, 0, 147, 147, 0, + 147, 147, 147, 147, 147, 0, 82, 82, 134, 134, + 134, 134, 0, 0, 143, 0, 0, 134, 167, 0, + 0, 0, 0, 134, 134, 69, 0, 0, 69, 0, + 0, 0, 0, 134, 134, 0, 134, 134, 134, 134, + 134, 82, 69, 69, 0, 0, 0, 0, 0, 0, + 149, 0, 0, 0, 105, 105, 105, 105, 0, 0, + 0, 0, 0, 105, 0, 0, 0, 0, 0, 105, + 105, 0, 0, 0, 0, 0, 0, 69, 0, 105, + 105, 156, 105, 105, 105, 105, 105, 0, 151, 152, + 153, 154, 0, 0, 0, 0, 0, 0, 0, 90, + 90, 90, 90, 0, 159, 160, 161, 162, 90, 167, + 163, 0, 0, 164, 165, 166, 0, 0, 0, 0, + 0, 0, 0, 0, 90, 90, 0, 90, 90, 90, + 90, 92, 92, 92, 92, 0, 0, 0, 0, 0, + 92, 149, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 92, 92, 0, 92, + 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 91, 91, 91, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 143, 143, 143, 143, 0, 91, 91, + 0, 91, 0, 0, 0, 0, 0, 0, 150, 0, + 0, 0, 0, 0, 151, 152, 153, 154, 143, 143, + 82, 82, 82, 82, 0, 0, 0, 155, 157, 158, + 159, 160, 161, 162, 0, 0, 163, 0, 0, 164, + 165, 166, 0, 0, 0, 82, 82, 0, 0, 0, + 0, 0, 0, 0, 94, 0, 69, 69, 69, 69, + 0, 0, 104, 0, 0, 0, 109, 0, 0, 118, + 0, 0, 0, 0, 0, 0, 125, 126, 127, 128, + 129, 69, 69, 132, 133, 0, 0, 0, 0, 0, + 140, 0, 0, 0, 0, 0, 0, 0, 0, 150, + 0, 0, 0, 0, 0, 151, 152, 153, 154, 0, + 0, 0, 0, 0, 0, 0, 0, 183, 0, 157, + 158, 159, 160, 161, 162, 0, 0, 163, 0, 0, + 164, 165, 166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 150, 0, 0, 0, 0, 0, - 0, 0, 134, 134, 134, 134, 0, 0, 0, 0, - 0, 134, 0, 0, 0, 134, 134, 0, 0, 0, - 0, 0, 0, 0, 134, 134, 0, 0, 134, 134, - 134, 134, 134, 0, 0, 0, 0, 0, 0, 76, - 76, 76, 76, 0, 0, 0, 0, 0, 76, 77, - 77, 77, 77, 76, 0, 0, 0, 0, 77, 0, - 0, 76, 76, 0, 0, 76, 76, 76, 76, 76, - 0, 77, 77, 0, 0, 77, 77, 77, 77, 77, - 0, 0, 0, 0, 0, 78, 78, 78, 78, 0, - 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 78, 78, 0, - 0, 78, 78, 78, 78, 78, 0, 79, 79, 79, - 79, 0, 0, 0, 0, 0, 79, 81, 81, 81, - 81, 0, 0, 0, 0, 0, 81, 0, 0, 79, - 79, 0, 0, 79, 79, 79, 79, 0, 0, 81, - 81, 0, 151, 81, 81, 81, 152, 153, 154, 155, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, - 158, 159, 160, 161, 0, 162, 163, 91, 0, 164, - 0, 0, 165, 166, 167, 104, 0, 0, 0, 0, - 111, 113, 0, 0, 0, 0, 0, 125, 126, 127, - 128, 129, 130, 0, 0, 133, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, + 0, 0, 0, 0, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 215, 0, 0, 0, 0, 0, 0, 0, 223, 224, - 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 296, 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, 312, + 0, 0, 0, 0, 0, 0, 0, 0, 315, }; short yycheck[] = { 13, - 257, 13, 91, 17, 44, 41, 59, 182, 36, 41, - 59, 257, 44, 194, 41, 188, 59, 190, 41, 33, - 34, 35, 36, 59, 82, 40, 58, 59, 41, 43, - 88, 63, 125, 45, 123, 59, 50, 40, 59, 59, - 40, 91, 123, 91, 56, 41, 257, 41, 60, 41, - 41, 41, 278, 41, 36, 41, 44, 93, 116, 40, - 91, 93, 41, 91, 78, 41, 40, 40, 59, 41, - 58, 59, 40, 123, 123, 123, 91, 41, 92, 41, - 40, 95, 94, 97, 96, 99, 98, 101, 100, 41, - 102, 40, 123, 41, 106, 123, 44, 59, 41, 123, - 59, 41, 294, 295, 41, 93, 0, 59, 123, 59, - 58, 59, 287, 59, 44, 59, 59, 59, 299, 59, - 123, 302, 59, 123, 297, 298, 184, 141, 276, 277, - 123, 304, 144, 145, 146, 147, 148, 149, 150, 33, - 40, 123, 36, 37, 38, 93, 40, 260, 42, 43, - 123, 45, 123, 334, 327, 93, 168, 169, 170, 171, - 172, 173, 174, 123, 178, 59, 40, 40, 36, 0, - 64, 185, 40, 266, 267, 268, 257, 270, 271, 41, - 40, 93, 91, 266, 267, 268, 198, 270, 271, 125, - 93, 41, 204, 205, 206, 59, 59, 91, 287, 211, - 41, 125, 33, 91, 257, 36, 37, 38, 295, 40, - 93, 42, 43, 40, 45, 41, 305, 40, 125, 308, - 125, 125, 311, 312, 313, 237, 125, 239, 59, 123, - 258, 125, 126, 64, 59, 125, 272, 273, 274, 275, - 272, 273, 274, 275, 93, 259, 41, 261, 41, 263, - 264, 294, 295, 267, 294, 295, 270, 269, 294, 295, - 91, 41, 294, 295, 44, 313, 298, 294, 295, 93, - 282, 294, 295, 294, 295, 257, 272, 273, 274, 275, - 262, 294, 295, 63, 272, 273, 274, 275, 59, 301, - 123, 305, 123, 41, 125, 126, 0, 93, 294, 295, - 294, 295, 294, 295, 294, 295, 294, 295, 294, 295, - 298, 91, 59, 325, 41, 294, 295, 331, 294, 295, - 59, 335, 294, 295, 272, 273, 274, 275, 41, 33, - 294, 295, 36, 37, 38, 59, 40, 83, 42, 43, - 41, 45, 325, 123, 294, 295, 294, 295, 294, 295, - 294, 295, 294, 295, 13, 59, 294, 295, 269, 93, - 64, -1, 256, 257, 258, 259, 260, 261, -1, 263, - 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 294, 295, -1, 279, 280, 91, 282, 283, - 284, 294, 295, -1, -1, 289, 290, 291, 292, 293, - -1, -1, 296, 297, -1, 41, -1, -1, 44, 303, - -1, 294, 295, 307, -1, 309, 310, -1, -1, 123, - -1, -1, 126, 59, 91, 256, 257, 258, 259, 260, - 261, -1, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 294, 295, -1, 279, 280, - -1, 282, 283, 284, 91, -1, 123, 93, 289, 290, - 291, 292, 293, -1, -1, 296, 297, -1, -1, -1, - 294, 295, 303, -1, -1, -1, 307, -1, 309, 310, - 272, 273, 274, 275, 33, 91, 123, 36, 37, 38, - -1, 40, 41, 42, 43, 44, 45, -1, 294, 295, - -1, 281, 294, 295, -1, 285, 286, 287, 288, 58, - 59, 6, -1, 8, 63, 64, -1, 123, 298, 299, - 300, 301, 302, -1, 304, 305, -1, -1, 308, -1, - -1, 311, 312, 313, -1, -1, 31, 32, -1, -1, - -1, -1, 91, -1, 93, 41, -1, -1, 44, -1, - -1, 91, 256, 257, 258, 259, 260, 261, -1, 263, - 264, 265, 58, 59, -1, 269, -1, 63, 272, 273, - 274, 275, -1, -1, 123, 279, 280, 126, 282, 283, - 284, -1, -1, 123, -1, 289, 290, 291, 292, 293, - -1, -1, 296, 297, -1, 91, -1, 93, -1, 303, - -1, -1, -1, 307, 33, 309, 310, 36, 37, 38, - -1, 40, 41, 42, 43, 44, 45, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 123, -1, 58, - 59, -1, -1, -1, 63, 64, 272, 273, 274, 275, - -1, 308, -1, -1, 311, 312, 313, -1, 285, 286, - 287, 288, -1, -1, -1, -1, -1, -1, 294, -1, - -1, -1, -1, -1, 93, 302, -1, 304, 305, -1, - 41, 308, -1, 44, 311, 312, 313, -1, -1, 285, - 286, 287, 288, -1, -1, -1, -1, 58, 59, -1, - -1, -1, 63, 299, 300, 301, 302, 126, 304, 305, - -1, -1, 308, -1, -1, 311, 312, 313, 257, 258, - 259, 260, 261, -1, 263, 264, 265, -1, -1, -1, - 269, -1, 93, 272, 273, 274, 275, -1, -1, -1, - -1, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, -1, 307, 308, - 309, 310, 311, 312, 313, 305, -1, -1, 308, 91, - -1, 311, 312, 313, -1, -1, 272, 273, 274, 275, - -1, -1, -1, -1, -1, 281, -1, -1, -1, 285, - 286, 287, 288, -1, -1, -1, -1, -1, 294, 295, - -1, 123, 298, 299, 300, 301, 302, -1, 304, 305, - -1, -1, 308, -1, -1, 311, 312, 313, 91, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 257, 258, - 259, 260, 261, -1, 263, 264, 265, -1, -1, -1, + 36, 86, 41, 36, 40, 44, 182, 59, 59, 41, + 93, 40, 59, 91, 91, 59, 257, 41, 257, 58, + 59, 41, 191, 41, 63, 59, 44, 91, 91, 59, + 329, 40, 46, 41, 93, 40, 93, 41, 257, 41, + 58, 59, 41, 57, 122, 63, 123, 61, 97, 98, + 99, 100, 101, 102, 93, 59, 41, 59, 41, 123, + 123, 360, 91, 44, 297, 298, 41, 41, 276, 277, + 40, 40, 278, 91, 40, 93, 326, 327, 0, 123, + 59, 331, 59, 36, 59, 59, 59, 40, 59, 123, + 123, 41, 106, 107, 123, 40, 40, 347, 123, 41, + 40, 351, 271, 59, 41, 123, 40, 123, 44, 59, + 260, 33, 257, 289, 36, 37, 38, 59, 40, 40, + 42, 43, 59, 45, 40, 93, 41, 40, 125, 143, + 144, 145, 146, 147, 148, 149, 305, 59, 91, 91, + 257, 36, 64, 192, 41, 266, 267, 268, 41, 270, + 271, 44, 91, 167, 168, 169, 170, 171, 172, 173, + 125, 41, 93, 298, 44, 58, 59, 40, 182, 91, + 123, 249, 186, 187, 41, 189, 254, 191, 58, 59, + 41, 350, 41, 63, 198, 0, 200, 201, 41, 41, + 41, 205, 40, 93, 41, 93, 59, 125, 59, 125, + 93, 123, 125, 125, 126, 125, 257, 41, 125, 59, + 41, 91, 123, 93, 297, 298, 41, 231, 33, 233, + 234, 36, 37, 38, 257, 40, 59, 42, 43, 262, + 45, 40, 93, 272, 273, 274, 275, 314, 297, 298, + 297, 298, 281, 123, 59, 297, 298, 41, 41, 64, + 297, 298, 337, 123, 272, 273, 274, 275, 297, 298, + 296, 300, 301, 281, 0, 297, 298, 123, 282, 287, + 288, 289, 290, 297, 298, 289, 91, 297, 298, 297, + 298, 59, 300, 301, 302, 303, 304, 305, 306, 297, + 298, 309, 41, 307, 312, 313, 314, 33, 297, 298, + 36, 37, 38, 41, 40, 258, 42, 43, 123, 45, + 125, 126, 297, 298, 297, 298, 297, 298, 297, 298, + 297, 298, 41, 59, 297, 298, 297, 298, 64, 297, + 298, 59, 346, 41, 256, 257, 258, 259, 260, 261, + 41, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 59, 91, 8, 279, 280, 32, + 282, 283, 284, 285, 286, 125, 297, 298, 63, 291, + 292, 293, 294, 295, 296, 13, 144, 299, 307, 272, + 273, 274, 275, 346, 189, 96, 308, 123, 310, 311, + 126, -1, 272, 273, 274, 275, 91, 297, 298, 297, + 298, 281, -1, -1, 297, 298, 91, 287, 288, 289, + 290, 272, 273, 274, 275, -1, -1, 297, 298, -1, + 300, 301, 302, 303, 304, 305, 306, -1, 123, 309, + 91, -1, 312, 313, 314, -1, 297, 298, 123, -1, + -1, 256, 257, 258, 259, 260, 261, -1, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, -1, 123, -1, 279, 280, -1, 282, 283, 284, + 285, 286, 272, 273, 274, 275, 291, 292, 293, 294, + 295, 296, 41, -1, 299, 44, 91, -1, -1, -1, + -1, -1, -1, 308, -1, 310, 311, 297, 298, 58, + 59, -1, -1, -1, 63, -1, 266, 267, 268, -1, + 270, 271, -1, -1, -1, -1, -1, -1, 123, -1, + 256, 257, 258, 259, 260, 261, 125, 263, 264, 265, + -1, -1, 91, 269, 93, -1, 272, 273, 274, 275, + -1, -1, -1, 279, 280, -1, 282, 283, 284, 285, + 286, -1, -1, -1, -1, 291, 292, 293, 294, 295, + 296, -1, -1, 299, 123, -1, -1, -1, -1, -1, + 91, -1, 308, 33, 310, 311, 36, 37, 38, -1, + 40, 41, 42, 43, 44, 45, 281, -1, -1, -1, + -1, -1, 287, 288, 289, 290, -1, -1, 58, 59, + -1, -1, 123, 63, 64, 300, 301, 302, 303, 304, + 305, 306, -1, -1, 309, -1, -1, 312, 313, 314, + -1, 306, -1, -1, 309, -1, -1, 312, 313, 314, + -1, 91, -1, 93, 33, -1, -1, 36, 37, 38, + -1, 40, 41, 42, 43, 44, 45, -1, 309, -1, + -1, 312, 313, 314, -1, -1, -1, -1, -1, 58, + 59, -1, -1, 123, 63, 64, 126, 266, 267, 268, + -1, 270, 271, -1, -1, -1, -1, -1, -1, 302, + 303, 304, -1, 306, 289, 290, -1, -1, -1, -1, + -1, 13, -1, 33, 93, -1, 36, 37, 38, -1, + 40, 306, 42, 43, 309, 45, -1, 312, 313, 314, + 333, -1, -1, 272, 273, 274, 275, 340, -1, 59, + 42, 344, 281, 45, 64, -1, -1, 126, 287, 288, + 289, 290, -1, -1, 357, 358, -1, -1, 297, 298, + -1, 300, 301, 302, 303, 304, 305, 306, -1, -1, + 309, 91, -1, 312, 313, 314, -1, -1, 41, 81, + -1, 44, -1, -1, -1, -1, 287, 288, 289, 290, + -1, -1, -1, 95, -1, -1, 59, -1, -1, 91, + -1, -1, -1, 123, 305, 306, 126, -1, 309, -1, + -1, 312, 313, 314, -1, -1, -1, 257, 258, 259, + 260, 261, -1, 263, 264, 265, -1, -1, -1, 269, + 93, 123, 272, 273, 274, 275, -1, -1, -1, 141, + 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, -1, 308, 309, + 310, 311, 312, 313, 314, -1, 178, -1, 257, 258, + 259, 260, 261, 185, 263, 264, 265, -1, -1, -1, 269, -1, -1, 272, 273, 274, 275, -1, -1, -1, - 123, 280, 281, 282, 283, 284, 285, 286, 287, 288, + -1, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, -1, 307, 308, - 309, 310, 311, 312, 313, 33, 48, 49, 36, 37, - 38, -1, 40, -1, 42, 43, -1, 45, -1, -1, - -1, 272, 273, 274, 275, -1, -1, -1, -1, -1, - 281, 59, -1, -1, 285, 286, 64, 288, -1, -1, - 82, -1, -1, 294, 295, -1, 88, 298, 299, 300, - 301, 302, -1, 304, -1, -1, -1, -1, -1, -1, - -1, 33, -1, 91, 36, 37, 38, -1, 40, -1, - 42, 43, -1, 45, 116, -1, -1, -1, -1, -1, - -1, 123, -1, 285, 286, 287, 288, 59, -1, -1, - -1, -1, 64, -1, -1, 123, -1, -1, 126, 301, - 302, -1, 304, 305, -1, -1, 308, -1, -1, 311, - 312, 313, -1, -1, -1, -1, -1, 33, -1, 91, - 36, 37, 38, -1, 40, -1, 42, 43, -1, 45, - -1, -1, -1, -1, 287, 288, -1, -1, -1, -1, - -1, -1, 184, -1, -1, -1, -1, -1, 64, -1, - -1, 123, 305, -1, 126, 308, -1, -1, 311, 312, - 313, -1, -1, -1, 41, -1, -1, 44, -1, -1, - -1, -1, -1, -1, -1, 91, -1, 26, -1, -1, - 33, 58, 59, 36, 37, 38, -1, 40, -1, 42, - 43, -1, 45, 42, -1, -1, -1, -1, 47, -1, - 49, -1, -1, -1, -1, -1, -1, 123, -1, -1, - 126, 64, 61, 62, 63, 64, 93, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 256, 257, - 258, 259, 260, 261, -1, 263, 264, 265, 91, -1, - -1, 269, -1, -1, 272, 273, 274, 275, -1, -1, - -1, 279, 280, -1, 282, 283, 284, -1, 107, -1, - -1, 289, 290, 291, 292, 293, -1, -1, 296, 297, - 123, -1, -1, 126, 91, 303, -1, -1, -1, 307, - -1, 309, 310, -1, 256, 257, 258, 259, 260, 261, - -1, 263, 264, 265, -1, -1, -1, 269, -1, -1, - 272, 273, 274, 275, -1, -1, 123, 279, 280, -1, - 282, 283, 284, -1, -1, -1, -1, 289, 290, 291, - 292, 293, -1, -1, 296, 297, -1, -1, -1, -1, - 91, 303, -1, -1, -1, 307, -1, 309, 310, -1, - -1, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 41, -1, -1, 269, -1, -1, -1, -1, -1, -1, - -1, -1, 123, -1, 280, -1, 282, 283, 284, -1, - -1, -1, 63, 289, 290, 291, 292, 293, -1, -1, - 296, 297, -1, -1, -1, -1, -1, 303, -1, -1, - -1, 307, -1, 309, 310, 272, 273, 274, 275, -1, - 91, -1, -1, -1, 257, 258, 259, 260, 261, -1, - 263, 264, 265, -1, -1, -1, 269, 294, 295, -1, - -1, -1, -1, -1, -1, -1, -1, 280, -1, 282, - 283, 284, 123, -1, -1, -1, 289, 290, 291, 292, - 293, -1, -1, 296, 297, -1, -1, -1, -1, -1, - 303, -1, -1, -1, 307, 33, 309, 310, 36, 37, - 38, -1, 40, -1, 42, 43, -1, 45, 285, 286, - 287, 288, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 59, -1, 300, 301, 302, 64, 304, 305, -1, - -1, 308, -1, -1, 311, 312, 313, -1, -1, -1, + 299, 300, 301, 302, 303, 304, 305, 306, -1, 308, + 309, 310, 311, 312, 313, 314, 256, 257, 258, 259, + 260, 261, -1, 263, 264, 265, -1, -1, -1, 269, + -1, 91, 272, 273, 274, 275, -1, -1, -1, 279, + 280, -1, 282, 283, 284, 285, 286, -1, -1, 91, + 43, 291, 292, 293, 294, 295, 296, 33, 51, 299, + 36, 37, 38, 123, 40, -1, 42, 43, 308, 45, + 310, 311, -1, -1, -1, 287, -1, 289, 290, -1, + -1, 123, -1, 59, -1, -1, -1, -1, 64, 272, + 273, 274, 275, 305, 306, -1, -1, 309, 91, -1, + 312, 313, 314, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 33, 297, 91, 36, 37, 38, -1, + 40, 114, 42, 43, 26, 45, -1, -1, -1, 122, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 33, -1, 91, 36, 37, 38, -1, 40, -1, - 42, 43, -1, 45, 285, 286, 287, 288, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 64, 304, 305, -1, -1, 308, 126, -1, - 311, 312, 313, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 33, -1, 91, - 36, 37, 38, -1, 40, 41, 42, 43, -1, 45, + -1, 43, 44, -1, 64, -1, -1, 123, 50, -1, + 126, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 62, 63, 64, 65, -1, -1, -1, -1, -1, 33, + -1, 91, 36, 37, 38, -1, 40, -1, 42, 43, + -1, 45, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 281, -1, -1, -1, 285, 286, 287, 288, 64, -1, - -1, 123, -1, -1, 126, -1, -1, 298, 299, 300, - 301, 302, -1, 304, 305, -1, -1, 308, -1, -1, - 311, 312, 313, -1, -1, 91, -1, -1, -1, -1, - 33, -1, -1, 36, 37, 38, -1, 40, -1, 42, - 43, -1, 45, -1, -1, -1, -1, -1, -1, -1, + 64, -1, -1, 123, -1, 107, 126, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 126, 64, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 257, - 258, 259, 260, 261, -1, 263, 264, 265, 91, -1, - 93, 269, -1, -1, -1, 91, -1, -1, -1, -1, - -1, -1, 280, -1, 282, 283, 284, -1, -1, -1, - -1, 289, 290, 291, 292, 293, -1, 63, 296, 297, - -1, -1, -1, 126, -1, 303, -1, 123, -1, 307, - -1, 309, 310, -1, -1, 257, 258, 259, 260, 261, - -1, 263, 264, 265, -1, 91, -1, 269, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 280, -1, - 282, 283, 284, -1, -1, -1, -1, 289, 290, 291, - 292, 293, -1, -1, 296, 297, 91, 123, -1, -1, - -1, 303, -1, 41, -1, 307, 44, 309, 310, -1, + -1, -1, -1, -1, -1, -1, -1, 91, -1, 289, + 290, -1, 33, -1, -1, 36, 37, 38, -1, 40, + -1, 42, 43, -1, 45, 305, 306, 289, -1, 309, + -1, -1, 312, 313, 314, -1, 249, -1, -1, 123, + -1, 254, 126, 64, 306, -1, -1, 309, -1, -1, + 312, 313, 314, -1, -1, -1, -1, -1, -1, -1, + 256, 257, 258, 259, 260, 261, -1, 263, 264, 265, + 91, -1, -1, 269, -1, -1, 272, 273, 274, 275, + -1, -1, -1, 279, 280, -1, 282, 283, 284, 285, + 286, -1, -1, -1, -1, 291, 292, 293, 294, 295, + 296, 91, 123, 299, -1, 126, -1, -1, -1, -1, + -1, -1, 308, 41, 310, 311, 44, 257, 258, 259, + 260, 261, 262, 263, 264, 265, -1, -1, -1, 269, + -1, -1, -1, 123, -1, 63, -1, -1, -1, -1, + 280, -1, 282, 283, 284, 285, 286, -1, -1, -1, + -1, 291, 292, 293, 294, 295, 296, -1, -1, 299, + -1, -1, -1, 91, -1, -1, -1, 41, 308, -1, + 310, 311, -1, 257, 258, 259, 260, 261, -1, 263, + 264, 265, -1, -1, -1, 269, -1, -1, -1, 63, + -1, -1, -1, -1, -1, 123, 280, -1, 282, 283, + 284, 285, 286, -1, -1, -1, -1, 291, 292, 293, + 294, 295, 296, -1, -1, 299, -1, 91, -1, -1, + -1, -1, -1, -1, 308, -1, 310, 311, -1, -1, + -1, -1, -1, -1, -1, -1, 257, 258, 259, 260, + 261, -1, 263, 264, 265, -1, -1, -1, 269, 123, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 280, + -1, 282, 283, 284, 285, 286, -1, -1, -1, 91, + 291, 292, 293, 294, 295, 296, 33, -1, 299, 36, + 37, 38, -1, 40, -1, 42, 43, 308, 45, 310, + 311, -1, -1, -1, -1, -1, -1, 287, 288, 289, + 290, 123, 59, -1, -1, -1, -1, 64, -1, -1, + -1, 301, 302, 303, 304, 305, 306, -1, -1, 309, + -1, -1, 312, 313, 314, -1, -1, -1, -1, -1, + -1, -1, 33, -1, 91, 36, 37, 38, -1, 40, + 41, 42, 43, -1, 45, -1, -1, -1, -1, -1, + -1, -1, -1, 281, -1, -1, -1, -1, -1, 287, + 288, 289, 290, 64, -1, -1, -1, -1, -1, 126, + -1, -1, 300, 301, 302, 303, 304, 305, 306, -1, + -1, 309, -1, -1, 312, 313, 314, -1, 33, -1, + 91, 36, 37, 38, -1, 40, -1, 42, 43, -1, + 45, -1, -1, -1, -1, -1, -1, 281, -1, -1, + -1, -1, -1, 287, 288, 289, 290, -1, -1, 64, + -1, -1, -1, -1, -1, 126, 300, 301, 302, 303, + 304, 305, 306, -1, -1, 309, -1, -1, 312, 313, + 314, -1, -1, -1, -1, -1, 91, 33, 93, -1, + 36, 37, 38, -1, 40, 41, 42, 43, -1, 45, + -1, -1, -1, -1, -1, 287, 288, 289, 290, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 64, -1, + -1, 126, 304, 305, 306, -1, -1, 309, -1, -1, + 312, 313, 314, -1, -1, -1, 41, -1, -1, 44, + 257, 258, 259, 260, 261, 91, 263, 264, 265, -1, + -1, -1, 269, 58, 59, -1, -1, -1, 63, -1, + -1, -1, -1, 280, -1, 282, 283, 284, 285, 286, + -1, -1, -1, -1, 291, 292, 293, 294, 295, 296, + 126, -1, 299, -1, -1, -1, -1, -1, 93, -1, + -1, 308, 41, 310, 311, 44, 257, 258, 259, 260, + 261, -1, 263, 264, 265, -1, -1, -1, 269, 58, + 59, -1, -1, -1, 63, -1, -1, -1, -1, 280, + -1, 282, 283, 284, 285, 286, -1, -1, -1, -1, + 291, 292, 293, 294, 295, 296, -1, -1, 299, -1, + -1, -1, -1, -1, 93, -1, -1, 308, -1, 310, + 311, -1, 257, 258, 259, 260, 261, -1, 263, 264, + 265, -1, 33, -1, 269, 36, 37, 38, -1, 40, + 41, 42, 43, -1, 45, 280, -1, 282, 283, 284, + 285, 286, -1, -1, -1, -1, 291, 292, 293, 294, + 295, 296, -1, 64, 299, -1, -1, -1, -1, -1, + -1, -1, -1, 308, -1, 310, 311, -1, -1, -1, -1, 257, 258, 259, 260, 261, -1, 263, 264, 265, - 58, 59, -1, 269, -1, 63, -1, -1, 123, -1, - -1, -1, -1, -1, 280, -1, 282, 283, 284, -1, - -1, -1, -1, 289, 290, 291, 292, 293, -1, -1, - 296, 297, -1, -1, -1, 93, -1, 303, -1, -1, - -1, 307, -1, 309, 310, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 257, 258, 259, 260, 261, -1, - 263, 264, 265, -1, 33, -1, 269, 36, 37, 38, - -1, 40, -1, 42, 43, -1, 45, 280, -1, 282, - 283, 284, -1, -1, -1, -1, 289, 290, 291, 292, - 293, 287, 288, 296, 297, 64, -1, -1, -1, -1, - 303, -1, -1, -1, 307, -1, 309, 310, 304, 305, - -1, -1, 308, -1, -1, 311, 312, 313, -1, -1, - 33, -1, 91, 36, 37, 38, -1, 40, 41, 42, - 43, -1, 45, -1, -1, 281, -1, -1, -1, 285, - 286, 287, 288, -1, -1, -1, -1, -1, -1, -1, - -1, 64, 298, 299, 300, 301, 302, 126, 304, 305, - -1, -1, 308, -1, -1, 311, 312, 313, -1, -1, - 285, -1, 287, 288, -1, -1, 33, -1, 91, 36, - 37, 38, -1, 40, 41, 42, 43, -1, 45, 304, - 305, -1, -1, 308, -1, -1, 311, 312, 313, -1, - -1, -1, -1, -1, -1, -1, -1, 64, -1, -1, - -1, -1, -1, 126, 272, 273, 274, 275, -1, -1, - -1, -1, -1, 281, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 91, -1, 294, 295, -1, 33, - 298, 299, 36, 37, 38, -1, 40, 41, 42, 43, - -1, 45, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 126, - 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 256, 257, 258, - 259, 260, 261, -1, 263, 264, 265, 91, -1, -1, - 269, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 280, -1, 282, 283, 284, -1, -1, -1, -1, - 289, 290, 291, 292, 293, -1, -1, 296, 297, -1, - -1, -1, 126, -1, 303, -1, 41, -1, 307, 44, - 309, 310, -1, -1, 257, 258, 259, 260, 261, -1, - 263, 264, 265, 58, 59, -1, 269, -1, 63, -1, - -1, -1, -1, -1, -1, -1, -1, 280, -1, 282, - 283, 284, -1, -1, -1, -1, 289, 290, 291, 292, - 293, -1, -1, 296, 297, -1, 91, -1, 93, -1, - 303, -1, 41, -1, 307, 44, 309, 310, -1, -1, - 257, 258, 259, 260, 261, -1, 263, 264, 265, 58, - 59, -1, 269, -1, 63, -1, -1, -1, 123, -1, - -1, -1, -1, 280, -1, 282, 283, 284, -1, -1, - -1, -1, 289, 290, 291, 292, 293, -1, -1, 296, - 297, -1, 91, -1, 93, -1, 303, -1, -1, -1, - 307, -1, 309, 310, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 257, 258, 259, 260, 261, -1, 263, - 264, 265, -1, 33, 123, 269, 36, 37, 38, -1, - 40, 41, 42, 43, -1, 45, 280, -1, 282, 283, - 284, -1, -1, -1, -1, 289, 290, 291, 292, 293, - -1, -1, 296, 297, 64, -1, 25, 26, -1, 303, - -1, -1, -1, 307, -1, 309, 310, -1, 37, -1, - -1, -1, -1, 42, 43, -1, -1, -1, 47, 33, - 49, 91, 36, 37, 38, -1, 40, -1, 42, 43, - -1, 45, 61, 62, 63, 64, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 64, -1, -1, -1, -1, -1, 126, 272, 273, 274, - 275, -1, -1, -1, -1, -1, 281, -1, -1, -1, - 285, 286, 287, 288, -1, -1, -1, 91, 107, 294, - 295, -1, -1, 298, 299, 300, 301, 302, -1, 304, - 305, -1, 41, 308, -1, 44, 311, 312, 313, -1, - -1, -1, -1, 41, -1, -1, 44, -1, -1, 58, - 59, -1, 126, 272, 273, 274, 275, -1, -1, -1, - 58, 59, 281, -1, -1, 63, 285, 286, 287, 288, - -1, -1, -1, -1, -1, 294, 295, -1, 167, 298, - 299, 300, 301, 302, 93, 304, 305, -1, 41, 308, - -1, 44, 311, 312, 313, 93, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 58, 59, -1, -1, -1, - 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 123, -1, 257, 258, 259, - 260, 261, -1, 263, 264, 265, -1, -1, 91, 269, - 93, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 280, -1, 282, 283, 284, -1, -1, -1, -1, 289, - 290, 291, 292, 293, -1, -1, 296, 297, -1, -1, - -1, -1, -1, 303, -1, 41, -1, 307, 44, 309, - 310, -1, -1, 257, 258, 259, 260, 261, -1, 263, - 264, 265, 58, 59, -1, 269, -1, 63, -1, -1, - -1, -1, -1, -1, -1, -1, 280, -1, 282, 283, - 284, -1, -1, -1, -1, 289, 290, 291, 292, 293, - -1, -1, 296, 297, -1, -1, -1, 93, -1, 303, - 41, -1, -1, 307, -1, 309, 310, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 58, 59, -1, - -1, -1, 63, -1, -1, -1, -1, 123, -1, -1, + 91, 33, -1, 269, 36, 37, 38, -1, 40, -1, + 42, 43, -1, 45, 280, -1, 282, 283, 284, 285, + 286, -1, -1, -1, -1, 291, 292, 293, 294, 295, + 296, -1, 64, 299, -1, 126, -1, -1, -1, -1, + -1, -1, 308, -1, 310, 311, -1, 272, 273, 274, + 275, -1, -1, -1, -1, -1, 281, 33, -1, 91, + 36, 37, 38, 288, 40, 41, 42, 43, -1, 45, + -1, -1, 297, 298, -1, 300, 301, 302, 303, 304, + -1, -1, -1, -1, -1, -1, -1, -1, 64, -1, + -1, -1, -1, -1, 126, -1, -1, -1, -1, -1, -1, -1, -1, 272, 273, 274, 275, -1, -1, -1, - -1, -1, -1, -1, 272, 273, 274, 275, -1, -1, - 91, -1, 93, 281, -1, 294, 295, 285, 286, 287, - 288, -1, -1, -1, -1, -1, 294, 295, -1, -1, - 298, 299, 300, 301, 302, -1, 304, 305, -1, -1, - 308, -1, 123, 311, 312, 313, -1, -1, -1, 272, - 273, 274, 275, -1, -1, -1, -1, -1, 281, -1, - -1, -1, 285, 286, 287, 288, -1, -1, -1, -1, - -1, 294, 295, -1, 41, 298, 299, 300, 301, 302, - -1, 304, 305, -1, -1, 308, -1, -1, 311, 312, - 313, 58, 59, -1, -1, -1, 63, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 91, -1, 93, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 272, 273, 274, 275, - -1, -1, -1, -1, -1, 281, -1, -1, -1, 285, - 286, 287, 288, -1, -1, -1, 123, -1, 294, 295, - -1, -1, 298, 299, 300, 301, 302, -1, 304, 305, - 41, -1, 308, 44, -1, 311, 312, 313, -1, -1, - -1, 41, -1, -1, 44, -1, -1, 58, 59, -1, - -1, 272, 273, 274, 275, -1, -1, -1, 58, 59, - 281, -1, -1, 63, 285, 286, 287, 288, -1, -1, - -1, -1, -1, 294, 295, -1, -1, 298, 299, 300, - 301, 302, 93, 304, 305, -1, -1, 308, -1, -1, - 311, 312, 313, 93, 41, -1, -1, 44, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 58, 59, -1, -1, -1, 63, -1, -1, -1, - -1, -1, -1, 123, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, - 44, -1, -1, -1, -1, -1, 93, -1, -1, -1, - -1, -1, -1, -1, 58, 59, -1, -1, -1, 63, + -1, -1, 281, 33, -1, 91, 36, 37, 38, -1, + 40, 41, 42, 43, -1, 45, -1, -1, 297, 298, + -1, 300, 301, 302, 303, 304, -1, -1, -1, -1, + -1, -1, -1, -1, 64, -1, -1, -1, -1, -1, + 126, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 257, 258, 259, 260, + 261, 91, 263, 264, 265, -1, 33, -1, 269, 36, + 37, 38, -1, 40, 41, 42, 43, -1, 45, 280, + -1, 282, 283, 284, 285, 286, -1, -1, -1, -1, + 291, 292, 293, 294, 295, 296, 126, 64, 299, -1, + -1, -1, -1, -1, -1, -1, -1, 308, -1, 310, + 311, -1, -1, -1, 256, 257, 258, 259, 260, 261, + -1, 263, 264, 265, 91, -1, -1, 269, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 280, -1, + 282, 283, 284, 285, 286, -1, -1, -1, -1, 291, + 292, 293, 294, 295, 296, -1, -1, 299, -1, 126, + 91, -1, -1, -1, 41, -1, 308, 44, 310, 311, + -1, 257, 258, 259, 260, 261, -1, 263, 264, 265, + -1, 58, 59, 269, -1, -1, 63, -1, -1, -1, + -1, -1, 123, -1, 280, -1, 282, 283, 284, 285, + 286, -1, -1, -1, -1, 291, 292, 293, 294, 295, + 296, -1, -1, 299, 91, -1, 93, -1, -1, -1, + -1, -1, 308, -1, 310, 311, -1, 257, 258, 259, + 260, 261, -1, 263, 264, 265, -1, 33, -1, 269, + 36, 37, 38, -1, 40, -1, 42, 43, -1, 45, + 280, -1, 282, 283, 284, 285, 286, -1, -1, -1, + -1, 291, 292, 293, 294, 295, 296, -1, 64, 299, + -1, -1, -1, -1, -1, -1, -1, -1, 308, -1, + 310, 311, -1, -1, -1, -1, 41, -1, -1, 44, + 257, 258, 259, 260, 261, 91, 263, 264, 265, -1, + -1, -1, 269, 58, 59, -1, -1, -1, 63, -1, + -1, -1, -1, 280, -1, 282, 283, 284, 285, 286, + -1, -1, -1, -1, 291, 292, 293, 294, 295, 296, + 126, -1, 299, 41, -1, -1, 44, -1, 93, -1, + -1, 308, -1, 310, 311, -1, -1, -1, -1, -1, + 58, 59, -1, -1, -1, 63, 287, 288, 289, 290, + -1, -1, -1, -1, -1, -1, -1, -1, 123, -1, + -1, 302, 303, 304, 305, 306, -1, -1, 309, -1, + -1, 312, 313, 314, -1, 93, -1, -1, -1, -1, -1, -1, -1, -1, -1, 272, 273, 274, 275, -1, - -1, -1, -1, -1, 281, -1, 123, -1, 285, 286, - 287, 288, -1, -1, -1, 41, -1, 294, 295, 93, - -1, 298, 299, 300, 301, 302, -1, 304, 305, -1, - -1, 308, 58, 59, 311, 312, 313, 63, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 123, - -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, - 44, -1, -1, -1, -1, 91, -1, 93, -1, -1, - -1, -1, -1, -1, 58, 59, -1, -1, -1, 63, + 41, -1, -1, -1, 281, -1, -1, -1, -1, -1, + 287, 288, 289, 290, -1, 123, -1, 58, 59, -1, + 297, 298, 63, 300, 301, 302, 303, 304, 305, 306, + -1, -1, 309, -1, -1, 312, 313, 314, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 272, 273, 274, 275, -1, -1, 123, -1, -1, - -1, -1, 272, 273, 274, 275, -1, -1, -1, 93, - -1, 281, -1, 294, 295, 285, 286, 287, 288, -1, - -1, -1, -1, -1, 294, 295, -1, -1, 298, 299, - 300, 301, 302, -1, 304, 305, -1, -1, 308, -1, - -1, 311, 312, 313, -1, 41, -1, -1, 44, -1, - -1, -1, -1, -1, -1, 272, 273, 274, 275, -1, - -1, -1, 58, 59, 281, -1, -1, 63, 285, 286, - 287, 288, -1, -1, -1, -1, -1, 294, 295, -1, - -1, 298, 299, 300, 301, 302, -1, 304, 305, -1, - -1, 308, -1, -1, 311, 312, 313, 93, 272, 273, - 274, 275, -1, -1, -1, 41, -1, 281, 44, -1, - -1, 285, 286, 287, 288, -1, -1, -1, -1, -1, - 294, 295, 58, 59, 298, 299, 300, 301, 302, -1, - 304, 305, -1, -1, 308, -1, -1, 311, 312, 313, - -1, -1, -1, -1, -1, -1, 272, 273, 274, 275, - -1, -1, -1, -1, -1, 281, -1, 93, -1, 285, - 286, 287, 288, -1, -1, -1, -1, -1, 294, 295, - -1, 63, 298, 299, 300, 301, 302, -1, 304, 305, - -1, -1, 308, -1, -1, 311, 312, 313, 272, 273, - 274, 275, -1, -1, -1, -1, -1, 281, -1, 91, - -1, 285, 286, 287, 288, -1, -1, -1, -1, -1, - 294, 295, -1, -1, 298, 299, 300, 301, 302, 41, - 304, 305, 44, -1, 308, -1, -1, 311, 312, 313, - -1, 123, -1, -1, -1, -1, 58, 59, -1, -1, - -1, 63, -1, -1, -1, -1, -1, -1, -1, -1, + 91, -1, 93, -1, 41, -1, -1, -1, -1, -1, + -1, 257, 258, 259, 260, 261, -1, 263, 264, 265, + -1, 58, 59, 269, -1, -1, 63, -1, -1, -1, + -1, -1, 123, -1, 280, -1, 282, 283, 284, 285, + 286, -1, -1, -1, -1, 291, 292, 293, 294, 295, + 296, -1, -1, 299, 91, -1, 93, -1, -1, -1, + 41, -1, 308, 44, 310, 311, -1, 272, 273, 274, + 275, -1, -1, -1, -1, -1, 281, 58, 59, -1, + -1, -1, 287, 288, 289, 290, 123, -1, -1, -1, + -1, -1, 297, 298, -1, 300, 301, 302, 303, 304, + 305, 306, -1, -1, 309, -1, -1, 312, 313, 314, + -1, -1, 93, -1, 272, 273, 274, 275, -1, 41, + -1, -1, 44, 281, -1, -1, -1, -1, -1, 287, + 288, 289, 290, -1, -1, -1, 58, 59, -1, 297, + 298, 63, 300, 301, 302, 303, 304, 305, 306, 25, + 26, 309, -1, -1, 312, 313, 314, -1, -1, -1, + -1, 37, -1, -1, -1, -1, -1, 43, 44, 45, + -1, 93, -1, -1, 50, -1, -1, -1, -1, -1, + -1, 272, 273, 274, 275, -1, 62, 63, 64, 65, + 281, -1, -1, -1, -1, -1, 287, 288, 289, 290, + -1, 123, 41, -1, -1, 44, 297, 298, -1, 300, + 301, 302, 303, 304, 305, 306, -1, -1, 309, 58, + 59, 312, 313, 314, 63, -1, -1, -1, -1, -1, + -1, 107, -1, -1, -1, 272, 273, 274, 275, -1, + -1, -1, -1, -1, 281, -1, -1, -1, -1, -1, + 287, 288, 289, 290, 93, -1, 41, -1, -1, -1, + 297, 298, -1, 300, 301, 302, 303, 304, 305, 306, + -1, -1, 309, 58, 59, 312, 313, 314, 63, -1, + -1, -1, -1, -1, 123, -1, -1, -1, -1, -1, + 166, 272, 273, 274, 275, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 41, -1, 91, 44, 93, -1, + -1, -1, -1, -1, 190, -1, 297, 298, -1, 300, + -1, 58, 59, -1, -1, -1, 63, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 123, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 41, -1, -1, 44, - -1, 93, -1, -1, -1, -1, 272, 273, 274, 275, - -1, -1, -1, 58, 59, 281, -1, -1, 63, 285, - 286, 287, 288, -1, -1, -1, -1, -1, 294, 295, - -1, -1, 298, 299, 300, 301, 302, -1, 304, 305, - 41, -1, 308, 44, -1, 311, 312, 313, 93, -1, + 272, 273, 274, 275, -1, 41, 93, -1, 44, 281, + -1, -1, -1, -1, -1, 287, 288, 289, 290, -1, + -1, -1, 58, 59, -1, 297, 298, 63, 300, 301, + 302, 303, 304, 305, 306, -1, 123, 309, -1, -1, + 312, 313, 314, -1, -1, -1, -1, -1, -1, -1, + 41, -1, -1, 44, -1, -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, 59, -1, - -1, -1, 63, -1, -1, -1, 272, 273, 274, 275, - -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, - 44, -1, -1, -1, -1, -1, -1, -1, 294, 295, - -1, -1, 93, -1, 58, 59, -1, -1, -1, 63, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 41, -1, -1, 44, -1, 281, - -1, -1, -1, 285, 286, 287, 288, -1, -1, 93, - -1, 58, 59, -1, -1, -1, 63, 299, 300, 301, - 302, -1, 304, 305, -1, -1, 308, -1, -1, 311, - 312, 313, 41, -1, -1, 44, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 93, -1, -1, 58, - 59, -1, -1, -1, 63, -1, -1, -1, -1, -1, - 272, 273, 274, 275, -1, -1, -1, -1, -1, 281, - -1, -1, -1, 285, 286, 287, 288, -1, -1, -1, - -1, -1, 294, 295, 93, -1, 298, 299, 300, 301, - 302, -1, 304, 305, -1, -1, 308, -1, -1, 311, - 312, 313, -1, -1, -1, -1, -1, 272, 273, 274, - 275, -1, -1, -1, -1, -1, 281, -1, -1, -1, - 285, 286, 287, 288, -1, -1, -1, -1, -1, 294, - 295, -1, -1, 298, 299, 300, 301, 302, -1, 304, - 305, 41, -1, 308, 44, -1, 311, 312, 313, -1, - -1, 272, 273, 274, 275, -1, -1, -1, 58, 59, - 281, -1, -1, 63, 285, 286, 287, 288, -1, -1, - -1, -1, -1, 294, 295, -1, -1, 298, 299, 300, - 301, 302, -1, 304, 305, -1, -1, 308, 272, 273, - 274, 275, -1, 93, -1, -1, -1, 281, -1, -1, - -1, 285, 286, 287, 288, -1, -1, -1, -1, -1, - 294, 295, -1, -1, 298, 299, 300, 301, 302, -1, - 304, 305, -1, -1, 308, 272, 273, 274, 275, -1, - -1, -1, -1, -1, 281, -1, -1, -1, 285, 286, - 287, 288, -1, -1, -1, -1, -1, 294, 295, -1, - -1, 298, 299, 300, 301, 302, -1, 304, 305, -1, + -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 272, 273, 274, 275, -1, -1, -1, - -1, -1, 281, -1, -1, -1, 285, 286, 287, 288, - 41, -1, -1, 44, -1, 294, 295, -1, -1, 298, - 299, 300, 301, 302, -1, 304, 305, 58, 59, -1, + -1, -1, 281, -1, -1, -1, -1, -1, 287, 288, + 289, 290, 93, -1, 41, -1, -1, 44, 297, 298, + -1, 300, 301, 302, 303, 304, 305, 306, -1, -1, + 309, 58, 59, 312, 313, 314, 63, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 272, 273, 274, + 275, -1, -1, -1, -1, -1, 281, -1, -1, -1, + -1, -1, 287, 288, 289, 290, 93, -1, -1, -1, + -1, -1, 297, 298, -1, 300, 301, 302, 303, 304, + 305, 306, -1, -1, 309, -1, -1, 312, 313, 314, + -1, -1, -1, -1, -1, 272, 273, 274, 275, -1, + 41, -1, -1, 44, 281, -1, -1, -1, -1, -1, + 287, 288, 289, 290, -1, -1, -1, 58, 59, -1, + 297, 298, 63, 300, 301, 302, 303, 304, 305, 306, + -1, -1, 309, -1, -1, 312, 313, 314, -1, -1, + -1, -1, -1, -1, -1, -1, 272, 273, 274, 275, + -1, 41, 93, -1, 44, 281, -1, -1, -1, -1, + -1, 287, 288, 289, 290, -1, -1, -1, 58, 59, + -1, 297, 298, 63, 300, 301, 302, 303, 304, 305, + 306, -1, -1, 309, -1, -1, 312, 313, 314, -1, + -1, 272, 273, 274, 275, -1, -1, -1, -1, -1, + 281, -1, -1, 93, -1, -1, 287, 288, 289, 290, + -1, -1, 41, -1, -1, 44, 297, 298, -1, 300, + 301, 302, 303, 304, 305, 306, -1, -1, 309, 58, + 59, 312, 313, 314, 63, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 272, 273, 274, 275, -1, + 41, -1, -1, 44, 281, -1, -1, -1, -1, -1, + 287, 288, 289, 290, 93, -1, -1, 58, 59, -1, + 297, 298, 63, 300, 301, 302, 303, 304, 305, 306, + -1, -1, 309, -1, -1, 312, 313, 314, -1, 41, + -1, -1, 44, -1, -1, -1, -1, -1, -1, -1, + 41, -1, 93, 44, -1, -1, 58, 59, -1, -1, + -1, 63, -1, -1, -1, -1, -1, 58, 59, -1, -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 41, -1, -1, 44, + -1, 272, 273, 274, 275, -1, 41, -1, -1, 44, + 281, 93, -1, -1, -1, -1, 287, 288, 289, 290, + -1, -1, 93, 58, 59, -1, 297, 298, 63, 300, + 301, 302, 303, 304, 305, 306, -1, -1, 309, -1, + -1, 312, 313, 314, -1, -1, -1, -1, -1, -1, + -1, -1, 272, 273, 274, 275, -1, 41, 93, -1, + 44, 281, -1, -1, -1, -1, -1, 287, 288, 289, + 290, -1, -1, -1, 58, 59, -1, 297, 298, 63, + 300, 301, 302, 303, 304, 305, 306, -1, -1, 309, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 93, 58, 59, -1, -1, -1, 63, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 41, -1, -1, 44, -1, -1, -1, -1, 93, -1, - -1, -1, 272, 273, 274, 275, -1, 58, 59, -1, - -1, 281, 63, -1, -1, 285, 286, 287, 288, -1, - -1, -1, -1, -1, 294, 295, -1, -1, 298, 299, - 300, 301, 302, 41, 304, 305, 44, -1, -1, -1, - -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, - 58, 59, -1, -1, -1, 63, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 41, - -1, -1, 44, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 93, 58, 59, -1, -1, + -1, -1, -1, 41, -1, -1, 44, -1, -1, 93, + -1, -1, -1, 272, 273, 274, 275, -1, -1, -1, + 58, 59, 281, -1, -1, 63, -1, -1, 287, 288, + 289, 290, -1, -1, -1, -1, -1, -1, 297, 298, + -1, 300, 301, 302, 303, 304, 305, 306, -1, -1, + 309, 272, 273, 274, 275, 93, -1, -1, -1, -1, + 281, -1, -1, -1, -1, -1, 287, 288, 289, 290, + -1, -1, -1, -1, -1, -1, 297, 298, -1, 300, + 301, 302, 303, 304, 305, 306, -1, -1, -1, -1, + 272, 273, 274, 275, -1, 41, -1, -1, 44, 281, + -1, 272, 273, 274, 275, 287, 288, 289, 290, -1, + 281, -1, 58, 59, -1, 297, 298, 63, 300, 301, + 302, 303, 304, 305, 306, -1, 297, 298, -1, 300, + 301, 302, 303, 304, -1, -1, -1, 272, 273, 274, + 275, -1, 41, -1, -1, 44, 281, 93, -1, -1, + -1, -1, 287, 288, 289, 290, -1, -1, -1, 58, + 59, -1, 297, 298, 63, 300, 301, 302, 303, 304, + 305, 306, -1, -1, -1, -1, -1, -1, 41, -1, + -1, 44, -1, -1, -1, -1, -1, -1, 272, 273, + 274, 275, -1, -1, 93, 58, 59, 281, -1, -1, + 63, -1, -1, 287, 288, 289, 290, -1, -1, -1, + -1, -1, -1, 297, 298, -1, 300, 301, 302, 303, + 304, 305, 306, 41, -1, -1, 44, -1, -1, -1, + 93, -1, -1, -1, 272, 273, 274, 275, -1, -1, + 58, 59, -1, 281, -1, 63, -1, -1, -1, 287, + 288, 289, 290, -1, -1, -1, -1, -1, -1, 297, + 298, -1, 300, 301, 302, 303, 304, 305, 306, 41, + -1, -1, 44, -1, -1, 93, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 58, 59, -1, -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 41, -1, -1, 44, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 93, -1, 58, 59, -1, -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 272, 273, 274, 275, -1, -1, -1, -1, -1, - 281, -1, -1, -1, 285, 286, 287, 288, 93, -1, - -1, -1, -1, 294, 295, -1, -1, 298, 299, 300, - 301, 302, -1, 304, 305, -1, -1, 272, 273, 274, - 275, -1, -1, -1, -1, -1, 281, -1, -1, -1, - 285, 286, 287, 288, 41, -1, -1, 44, -1, 294, - 295, -1, -1, 298, 299, 300, 301, 302, -1, 304, - 305, 58, 59, -1, -1, -1, 63, -1, -1, -1, - -1, 272, 273, 274, 275, -1, -1, -1, -1, -1, - 281, -1, -1, -1, 285, 286, 287, 288, -1, -1, - -1, -1, -1, 294, 295, -1, 93, 298, 299, 300, - 301, 302, 41, 304, 305, 44, -1, -1, -1, -1, - -1, -1, -1, -1, 272, 273, 274, 275, -1, 58, - 59, -1, -1, 281, 63, -1, -1, 285, 286, 287, - 288, -1, -1, -1, -1, -1, 294, 295, -1, -1, - 298, 299, 300, 301, 302, -1, 304, 305, -1, -1, - 272, 273, 274, 275, 93, -1, -1, -1, -1, 281, - -1, -1, -1, 285, 286, 287, 288, -1, -1, -1, - -1, -1, 294, 295, -1, -1, 298, 299, 300, 301, - 302, 41, 304, -1, 44, -1, -1, 272, 273, 274, - 275, -1, -1, -1, -1, -1, 281, -1, 58, 59, - 285, 286, -1, 63, -1, -1, -1, -1, -1, 294, - 295, -1, -1, 298, 299, 300, 301, 302, 41, 304, - -1, 44, -1, -1, -1, -1, -1, -1, 41, -1, - -1, 44, -1, 93, -1, 58, 59, -1, -1, -1, - 63, -1, -1, -1, -1, 58, 59, -1, -1, -1, - 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, 44, -1, -1, - 93, -1, -1, -1, -1, 272, 273, 274, 275, -1, - 93, 58, 59, -1, 281, -1, 63, -1, 285, 286, - -1, -1, -1, -1, -1, -1, 41, 294, 295, 44, - -1, 298, 299, 300, 301, 302, 41, -1, -1, 44, - -1, -1, -1, 58, 59, -1, 93, -1, 63, -1, - -1, -1, -1, 58, 59, -1, -1, -1, 63, -1, - -1, -1, -1, 272, 273, 274, 275, -1, -1, 58, - -1, -1, 281, -1, 63, -1, 285, 286, 93, -1, - -1, -1, -1, -1, -1, 294, 295, -1, 93, 298, - 299, 300, 301, 302, -1, -1, -1, -1, -1, -1, - -1, -1, 91, -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, 123, -1, -1, -1, -1, -1, - -1, -1, 272, 273, 274, 275, -1, -1, -1, -1, - -1, 281, -1, -1, -1, 285, 286, -1, -1, -1, - -1, -1, -1, -1, 294, 295, -1, -1, 298, 299, - 300, 301, 302, -1, -1, -1, -1, -1, -1, 272, - 273, 274, 275, -1, -1, -1, -1, -1, 281, 272, - 273, 274, 275, 286, -1, -1, -1, -1, 281, -1, - -1, 294, 295, -1, -1, 298, 299, 300, 301, 302, - -1, 294, 295, -1, -1, 298, 299, 300, 301, 302, - -1, -1, -1, -1, -1, 272, 273, 274, 275, -1, + -1, 93, -1, -1, -1, -1, 272, 273, 274, 275, + -1, 58, 59, -1, -1, 281, 63, -1, -1, -1, + -1, 287, 288, 289, 290, -1, -1, -1, -1, -1, + -1, 297, 298, -1, 300, 301, 302, 303, 304, 305, + 306, 41, -1, -1, 44, -1, 93, -1, -1, -1, + -1, -1, -1, 272, 273, 274, 275, -1, 58, 59, + -1, -1, 281, 63, -1, -1, -1, -1, 287, 288, + 289, 290, -1, -1, -1, -1, -1, 41, 297, 298, + 44, 300, 301, 302, 303, 304, 305, 306, -1, 272, + 273, 274, 275, 93, 58, 59, -1, -1, 281, 63, + -1, -1, -1, -1, 287, 288, 289, 290, -1, -1, + -1, -1, -1, -1, 297, 298, -1, 300, 301, 302, + 303, 304, 305, 41, -1, -1, 44, -1, -1, 93, + -1, -1, -1, -1, 272, 273, 274, 275, -1, -1, + 58, 59, -1, 281, -1, 63, -1, -1, -1, 287, + 288, -1, 290, -1, -1, -1, -1, -1, -1, 297, + 298, -1, 300, 301, 302, 303, 304, 305, 41, -1, + -1, 44, -1, -1, -1, 93, -1, -1, -1, -1, + 272, 273, 274, 275, -1, 58, 59, -1, -1, 281, + 63, -1, 91, -1, -1, 287, 288, -1, -1, -1, + 41, -1, -1, 44, -1, 297, 298, -1, 300, 301, + 302, 303, 304, 305, -1, -1, -1, 58, 59, -1, + 93, -1, 63, -1, 123, 272, 273, 274, 275, -1, -1, -1, -1, -1, 281, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 294, 295, -1, - -1, 298, 299, 300, 301, 302, -1, 272, 273, 274, - 275, -1, -1, -1, -1, -1, 281, 272, 273, 274, - 275, -1, -1, -1, -1, -1, 281, -1, -1, 294, - 295, -1, -1, 298, 299, 300, 301, -1, -1, 294, - 295, -1, 281, 298, 299, 300, 285, 286, 287, 288, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 298, - 299, 300, 301, 302, -1, 304, 305, 30, -1, 308, - -1, -1, 311, 312, 313, 38, -1, -1, -1, -1, - 43, 44, -1, -1, -1, -1, -1, 50, 51, 52, - 53, 54, 55, -1, -1, 58, 59, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 90, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 287, 288, 41, -1, -1, 44, -1, -1, -1, -1, + 297, 298, 93, 300, 301, 302, 303, 304, -1, 58, + 59, -1, 41, -1, 63, 44, -1, -1, -1, -1, + -1, -1, 272, 273, 274, 275, -1, -1, -1, 58, + 59, 281, -1, -1, -1, 58, -1, 287, 288, 41, + 63, -1, 44, -1, 93, -1, -1, 297, 298, -1, + 300, 301, 302, 303, 304, -1, 58, 59, 272, 273, + 274, 275, -1, -1, 93, -1, -1, 281, 91, -1, + -1, -1, -1, 287, 288, 41, -1, -1, 44, -1, + -1, -1, -1, 297, 298, -1, 300, 301, 302, 303, + 304, 93, 58, 59, -1, -1, -1, -1, -1, -1, + 123, -1, -1, -1, 272, 273, 274, 275, -1, -1, + -1, -1, -1, 281, -1, -1, -1, -1, -1, 287, + 288, -1, -1, -1, -1, -1, -1, 93, -1, 297, + 298, 63, 300, 301, 302, 303, 304, -1, 287, 288, + 289, 290, -1, -1, -1, -1, -1, -1, -1, 272, + 273, 274, 275, -1, 303, 304, 305, 306, 281, 91, + 309, -1, -1, 312, 313, 314, -1, -1, -1, -1, + -1, -1, -1, -1, 297, 298, -1, 300, 301, 302, + 303, 272, 273, 274, 275, -1, -1, -1, -1, -1, + 281, 123, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 297, 298, -1, 300, + 301, 302, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 272, 273, 274, 275, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 272, 273, 274, 275, -1, 297, 298, + -1, 300, -1, -1, -1, -1, -1, -1, 281, -1, + -1, -1, -1, -1, 287, 288, 289, 290, 297, 298, + 272, 273, 274, 275, -1, -1, -1, 300, 301, 302, + 303, 304, 305, 306, -1, -1, 309, -1, -1, 312, + 313, 314, -1, -1, -1, 297, 298, -1, -1, -1, + -1, -1, -1, -1, 30, -1, 272, 273, 274, 275, + -1, -1, 38, -1, -1, -1, 42, -1, -1, 45, + -1, -1, -1, -1, -1, -1, 52, 53, 54, 55, + 56, 297, 298, 59, 60, -1, -1, -1, -1, -1, + 66, -1, -1, -1, -1, -1, -1, -1, -1, 281, + -1, -1, -1, -1, -1, 287, 288, 289, 290, -1, + -1, -1, -1, -1, -1, -1, -1, 93, -1, 301, + 302, 303, 304, 305, 306, -1, -1, 309, -1, -1, + 312, 313, 314, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 143, -1, -1, -1, -1, -1, -1, -1, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, - 163, 164, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 163, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 175, -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, @@ -1107,16 +1057,16 @@ short yycheck[] = { 13, -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, 256, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 253, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 284, + -1, -1, -1, -1, -1, -1, -1, -1, 284, }; #define YYFINAL 1 #ifndef YYDEBUG #define YYDEBUG 0 #endif -#define YYMAXTOKEN 313 +#define YYMAXTOKEN 314 #if YYDEBUG char *yyname[] = { "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, @@ -1129,9 +1079,9 @@ char *yyname[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"WORD","METHOD","FUNCMETH","THING", "PMFUNC","PRIVATEREF","FUNC0SUB","UNIOPSUB","LSTOPSUB","LABEL","FORMAT","SUB", "ANONSUB","PACKAGE","USE","WHILE","UNTIL","IF","UNLESS","ELSE","ELSIF", -"CONTINUE","FOR","LOOPEX","DOTDOT","FUNC0","FUNC1","FUNC","RELOP","EQOP", -"MULOP","ADDOP","DOLSHARP","DO","LOCAL","HASHBRACK","NOAMP","OROP","ANDOP", -"NOTOP","LSTOP","ASSIGNOP","OROR","ANDAND","BITOROP","BITANDOP","UNIOP", +"CONTINUE","FOR","LOOPEX","DOTDOT","FUNC0","FUNC1","FUNC","UNIOP","LSTOP", +"RELOP","EQOP","MULOP","ADDOP","DOLSHARP","DO","HASHBRACK","NOAMP","LOCAL","MY", +"OROP","ANDOP","NOTOP","ASSIGNOP","OROR","ANDAND","BITOROP","BITANDOP", "SHIFTOP","MATCHOP","UMINUS","REFGEN","POWOP","PREINC","PREDEC","POSTINC", "POSTDEC","ARROW", }; @@ -1141,6 +1091,8 @@ char *yyrule[] = { "prog : $$1 lineseq", "block : '{' remember lineseq '}'", "remember :", +"mblock : '{' mremember lineseq '}'", +"mremember :", "lineseq :", "lineseq : lineseq decl", "lineseq : lineseq line", @@ -1153,44 +1105,52 @@ char *yyrule[] = { "sideff : expr IF expr", "sideff : expr UNLESS expr", "sideff : expr WHILE expr", -"sideff : expr UNTIL expr", +"sideff : expr UNTIL iexpr", "else :", -"else : ELSE block", -"else : ELSIF '(' expr ')' block else", -"cond : IF '(' expr ')' block else", -"cond : UNLESS '(' expr ')' block else", -"cond : IF block block else", -"cond : UNLESS block block else", +"else : ELSE mblock", +"else : ELSIF '(' mexpr ')' mblock else", +"cond : IF '(' remember mexpr ')' mblock else", +"cond : UNLESS '(' remember miexpr ')' mblock else", "cont :", "cont : CONTINUE block", -"loop : label WHILE '(' texpr ')' block cont", -"loop : label UNTIL '(' expr ')' block cont", -"loop : label WHILE block block cont", -"loop : label UNTIL block block cont", -"loop : label FOR scalar '(' expr ')' block cont", -"loop : label FOR '(' expr ')' block cont", -"loop : label FOR '(' nexpr ';' texpr ';' nexpr ')' block", +"loop : label WHILE '(' remember mtexpr ')' mblock cont", +"loop : label UNTIL '(' remember miexpr ')' mblock cont", +"loop : label FOR MY remember my_scalar '(' mexpr ')' mblock cont", +"loop : label FOR scalar '(' remember mexpr ')' mblock cont", +"loop : label FOR '(' remember mexpr ')' mblock cont", +"loop : label FOR '(' remember mnexpr ';' mtexpr ';' mnexpr ')' mblock", "loop : label block cont", "nexpr :", "nexpr : sideff", "texpr :", "texpr : expr", +"iexpr : expr", +"mexpr : expr", +"mnexpr : nexpr", +"mtexpr : texpr", +"miexpr : iexpr", "label :", "label : LABEL", "decl : format", "decl : subrout", "decl : package", "decl : use", -"format : FORMAT startsub WORD block", -"format : FORMAT startsub block", -"subrout : SUB startsub WORD proto block", -"subrout : SUB startsub WORD proto ';'", +"format : FORMAT startformsub formname block", +"formname : WORD", +"formname :", +"subrout : SUB startsub subname proto subbody", +"startsub :", +"startanonsub :", +"startformsub :", +"subname : WORD", "proto :", "proto : THING", -"startsub :", +"subbody : block", +"subbody : ';'", "package : PACKAGE WORD ';'", "package : PACKAGE ';'", -"use : USE startsub WORD listexpr ';'", +"$$2 :", +"use : USE startsub $$2 WORD WORD listexpr ';'", "expr : expr ANDOP expr", "expr : expr OROP expr", "expr : argexpr", @@ -1204,7 +1164,8 @@ char *yyrule[] = { "listop : FUNCMETH indirob '(' listexprcom ')'", "listop : LSTOP listexpr", "listop : FUNC '(' listexprcom ')'", -"listop : LSTOPSUB startsub block listexpr", +"$$3 :", +"listop : LSTOPSUB startanonsub block $$3 listexpr", "method : METHOD", "method : scalar", "term : term ASSIGNOP term", @@ -1230,14 +1191,14 @@ char *yyrule[] = { "term : term POSTDEC", "term : PREINC term", "term : PREDEC term", -"term : LOCAL term", +"term : local term", "term : '(' expr ')'", "term : '(' ')'", "term : '[' expr ']'", "term : '[' ']'", "term : HASHBRACK expr ';' '}'", "term : HASHBRACK ';' '}'", -"term : ANONSUB startsub proto block", +"term : ANONSUB startanonsub proto block", "term : scalar", "term : star '{' expr ';' '}'", "term : star", @@ -1265,6 +1226,8 @@ char *yyrule[] = { "term : DO WORD '(' expr ')'", "term : DO scalar '(' ')'", "term : DO scalar '(' expr ')'", +"term : term ARROW '(' ')'", +"term : term ARROW '(' expr ')'", "term : LOOPEX", "term : LOOPEX term", "term : NOTOP argexpr", @@ -1286,6 +1249,9 @@ char *yyrule[] = { "listexprcom :", "listexprcom : expr", "listexprcom : expr ','", +"local : LOCAL", +"local : MY", +"my_scalar : scalar", "amper : '&' indirob", "scalar : '$' indirob", "ary : '@' indirob", @@ -1318,9 +1284,9 @@ int yyerrflag; int yychar; YYSTYPE yyval; YYSTYPE yylval; -#line 571 "perly.y" +#line 631 "perly.y" /* PROGRAM */ -#line 1394 "y.tab.c" +#line 1360 "perly.c" #define YYABORT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab @@ -1412,7 +1378,7 @@ yyloop: yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; - fprintf(stderr, "yydebug: state %d, reading %d (%s)\n", yystate, + PerlIO_printf(Perl_debug_log, "yydebug: state %d, reading %d (%s)\n", yystate, yychar, yys); } #endif @@ -1422,7 +1388,7 @@ yyloop: { #if YYDEBUG if (yydebug) - fprintf(stderr, "yydebug: state %d, shifting to state %d\n", + PerlIO_printf(Perl_debug_log, "yydebug: state %d, shifting to state %d\n", yystate, yytable[yyn]); #endif if (yyssp >= yyss + yystacksize - 1) @@ -1477,7 +1443,7 @@ yyinrecovery: { #if YYDEBUG if (yydebug) - fprintf(stderr, + PerlIO_printf(Perl_debug_log, "yydebug: state %d, error recovery shifting to state %d\n", *yyssp, yytable[yyn]); #endif @@ -1507,7 +1473,7 @@ yyinrecovery: { #if YYDEBUG if (yydebug) - fprintf(stderr, + PerlIO_printf(Perl_debug_log, "yydebug: error recovery discarding state %d\n", *yyssp); #endif @@ -1526,7 +1492,7 @@ yyinrecovery: yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; - fprintf(stderr, + PerlIO_printf(Perl_debug_log, "yydebug: state %d, error recovery discards token %d (%s)\n", yystate, yychar, yys); } @@ -1537,7 +1503,7 @@ yyinrecovery: yyreduce: #if YYDEBUG if (yydebug) - fprintf(stderr, "yydebug: state %d, reducing by rule %d (%s)\n", + PerlIO_printf(Perl_debug_log, "yydebug: state %d, reducing by rule %d (%s)\n", yystate, yyn, yyrule[yyn]); #endif yym = yylen[yyn]; @@ -1545,7 +1511,7 @@ yyreduce: switch (yyn) { case 1: -#line 84 "perly.y" +#line 86 "perly.y" { #if defined(YYDEBUG) && defined(DEBUGGING) yydebug = (debug & 1); @@ -1554,38 +1520,50 @@ case 1: } break; case 2: -#line 91 "perly.y" +#line 93 "perly.y" { newPROG(yyvsp[0].opval); } break; case 3: -#line 95 "perly.y" -{ yyval.opval = block_end(yyvsp[-3].ival,yyvsp[-2].ival,yyvsp[-1].opval); } +#line 97 "perly.y" +{ if (copline > (line_t)yyvsp[-3].ival) + copline = yyvsp[-3].ival; + yyval.opval = block_end(yyvsp[-2].ival, yyvsp[-1].opval); } break; case 4: -#line 99 "perly.y" -{ yyval.ival = block_start(); } +#line 103 "perly.y" +{ yyval.ival = block_start(TRUE); } break; case 5: -#line 103 "perly.y" -{ yyval.opval = Nullop; } +#line 107 "perly.y" +{ if (copline > (line_t)yyvsp[-3].ival) + copline = yyvsp[-3].ival; + yyval.opval = block_end(yyvsp[-2].ival, yyvsp[-1].opval); } break; case 6: -#line 105 "perly.y" -{ yyval.opval = yyvsp[-1].opval; } +#line 113 "perly.y" +{ yyval.ival = block_start(FALSE); } break; case 7: -#line 107 "perly.y" +#line 117 "perly.y" +{ yyval.opval = Nullop; } +break; +case 8: +#line 119 "perly.y" +{ yyval.opval = yyvsp[-1].opval; } +break; +case 9: +#line 121 "perly.y" { yyval.opval = append_list(OP_LINESEQ, (LISTOP*)yyvsp[-1].opval, (LISTOP*)yyvsp[0].opval); pad_reset_pending = TRUE; if (yyvsp[-1].opval && yyvsp[0].opval) hints |= HINT_BLOCK_SCOPE; } break; -case 8: -#line 114 "perly.y" +case 10: +#line 128 "perly.y" { yyval.opval = newSTATEOP(0, yyvsp[-1].pval, yyvsp[0].opval); } break; -case 10: -#line 117 "perly.y" +case 12: +#line 131 "perly.y" { if (yyvsp[-1].pval != Nullch) { yyval.opval = newSTATEOP(0, yyvsp[-1].pval, newOP(OP_NULL, 0)); } @@ -1595,467 +1573,501 @@ case 10: } expect = XSTATE; } break; -case 11: -#line 126 "perly.y" +case 13: +#line 140 "perly.y" { yyval.opval = newSTATEOP(0, yyvsp[-2].pval, yyvsp[-1].opval); expect = XSTATE; } break; -case 12: -#line 131 "perly.y" -{ yyval.opval = Nullop; } -break; -case 13: -#line 133 "perly.y" -{ yyval.opval = yyvsp[0].opval; } -break; case 14: -#line 135 "perly.y" -{ yyval.opval = newLOGOP(OP_AND, 0, yyvsp[0].opval, yyvsp[-2].opval); } +#line 145 "perly.y" +{ yyval.opval = Nullop; } break; case 15: -#line 137 "perly.y" -{ yyval.opval = newLOGOP(OP_OR, 0, yyvsp[0].opval, yyvsp[-2].opval); } +#line 147 "perly.y" +{ yyval.opval = yyvsp[0].opval; } break; case 16: -#line 139 "perly.y" -{ yyval.opval = newLOOPOP(OPf_PARENS, 1, scalar(yyvsp[0].opval), yyvsp[-2].opval); } +#line 149 "perly.y" +{ yyval.opval = newLOGOP(OP_AND, 0, yyvsp[0].opval, yyvsp[-2].opval); } break; case 17: -#line 141 "perly.y" -{ yyval.opval = newLOOPOP(OPf_PARENS, 1, invert(scalar(yyvsp[0].opval)), yyvsp[-2].opval);} +#line 151 "perly.y" +{ yyval.opval = newLOGOP(OP_OR, 0, yyvsp[0].opval, yyvsp[-2].opval); } break; case 18: -#line 145 "perly.y" -{ yyval.opval = Nullop; } +#line 153 "perly.y" +{ yyval.opval = newLOOPOP(OPf_PARENS, 1, scalar(yyvsp[0].opval), yyvsp[-2].opval); } break; case 19: -#line 147 "perly.y" -{ yyval.opval = scope(yyvsp[0].opval); } +#line 155 "perly.y" +{ yyval.opval = newLOOPOP(OPf_PARENS, 1, yyvsp[0].opval, yyvsp[-2].opval);} break; case 20: -#line 149 "perly.y" -{ copline = yyvsp[-5].ival; - yyval.opval = newSTATEOP(0, 0, - newCONDOP(0, yyvsp[-3].opval, scope(yyvsp[-1].opval), yyvsp[0].opval)); - hints |= HINT_BLOCK_SCOPE; } +#line 159 "perly.y" +{ yyval.opval = Nullop; } break; case 21: -#line 156 "perly.y" -{ copline = yyvsp[-5].ival; - yyval.opval = newCONDOP(0, yyvsp[-3].opval, scope(yyvsp[-1].opval), yyvsp[0].opval); } +#line 161 "perly.y" +{ yyval.opval = scope(yyvsp[0].opval); } break; case 22: -#line 159 "perly.y" +#line 163 "perly.y" { copline = yyvsp[-5].ival; - yyval.opval = newCONDOP(0, - invert(scalar(yyvsp[-3].opval)), scope(yyvsp[-1].opval), yyvsp[0].opval); } + yyval.opval = newSTATEOP(0, Nullch, + newCONDOP(0, yyvsp[-3].opval, scope(yyvsp[-1].opval), yyvsp[0].opval)); + hints |= HINT_BLOCK_SCOPE; } break; case 23: -#line 163 "perly.y" -{ copline = yyvsp[-3].ival; - deprecate("if BLOCK BLOCK"); - yyval.opval = newCONDOP(0, scope(yyvsp[-2].opval), scope(yyvsp[-1].opval), yyvsp[0].opval); } +#line 170 "perly.y" +{ copline = yyvsp[-6].ival; + yyval.opval = block_end(yyvsp[-4].ival, + newCONDOP(0, yyvsp[-3].opval, scope(yyvsp[-1].opval), yyvsp[0].opval)); } break; case 24: -#line 167 "perly.y" -{ copline = yyvsp[-3].ival; - deprecate("unless BLOCK BLOCK"); - yyval.opval = newCONDOP(0, invert(scalar(scope(yyvsp[-2].opval))), - scope(yyvsp[-1].opval), yyvsp[0].opval); } +#line 174 "perly.y" +{ copline = yyvsp[-6].ival; + yyval.opval = block_end(yyvsp[-4].ival, + newCONDOP(0, yyvsp[-3].opval, scope(yyvsp[-1].opval), yyvsp[0].opval)); } break; case 25: -#line 174 "perly.y" +#line 180 "perly.y" { yyval.opval = Nullop; } break; case 26: -#line 176 "perly.y" +#line 182 "perly.y" { yyval.opval = scope(yyvsp[0].opval); } break; case 27: -#line 180 "perly.y" -{ copline = yyvsp[-5].ival; - yyval.opval = newSTATEOP(0, yyvsp[-6].pval, - newWHILEOP(0, 1, (LOOP*)Nullop, - yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval) ); } +#line 186 "perly.y" +{ copline = yyvsp[-6].ival; + yyval.opval = block_end(yyvsp[-4].ival, + newSTATEOP(0, yyvsp[-7].pval, + newWHILEOP(0, 1, (LOOP*)Nullop, + yyvsp[-6].ival, yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval))); } break; case 28: -#line 185 "perly.y" -{ copline = yyvsp[-5].ival; - yyval.opval = newSTATEOP(0, yyvsp[-6].pval, - newWHILEOP(0, 1, (LOOP*)Nullop, - invert(scalar(yyvsp[-3].opval)), yyvsp[-1].opval, yyvsp[0].opval) ); } +#line 192 "perly.y" +{ copline = yyvsp[-6].ival; + yyval.opval = block_end(yyvsp[-4].ival, + newSTATEOP(0, yyvsp[-7].pval, + newWHILEOP(0, 1, (LOOP*)Nullop, + yyvsp[-6].ival, yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval))); } break; case 29: -#line 190 "perly.y" -{ copline = yyvsp[-3].ival; - yyval.opval = newSTATEOP(0, yyvsp[-4].pval, - newWHILEOP(0, 1, (LOOP*)Nullop, - scope(yyvsp[-2].opval), yyvsp[-1].opval, yyvsp[0].opval) ); } +#line 198 "perly.y" +{ yyval.opval = block_end(yyvsp[-6].ival, + newFOROP(0, yyvsp[-9].pval, yyvsp[-8].ival, yyvsp[-5].opval, yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval)); } break; case 30: -#line 195 "perly.y" -{ copline = yyvsp[-3].ival; - yyval.opval = newSTATEOP(0, yyvsp[-4].pval, - newWHILEOP(0, 1, (LOOP*)Nullop, - invert(scalar(scope(yyvsp[-2].opval))), yyvsp[-1].opval, yyvsp[0].opval)); } +#line 201 "perly.y" +{ yyval.opval = block_end(yyvsp[-4].ival, + newFOROP(0, yyvsp[-8].pval, yyvsp[-7].ival, mod(yyvsp[-6].opval, OP_ENTERLOOP), + yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval)); } break; case 31: -#line 200 "perly.y" -{ yyval.opval = newFOROP(0, yyvsp[-7].pval, yyvsp[-6].ival, mod(yyvsp[-5].opval, OP_ENTERLOOP), - yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval); } +#line 205 "perly.y" +{ yyval.opval = block_end(yyvsp[-4].ival, + newFOROP(0, yyvsp[-7].pval, yyvsp[-6].ival, Nullop, yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval)); } break; case 32: -#line 203 "perly.y" -{ yyval.opval = newFOROP(0, yyvsp[-6].pval, yyvsp[-5].ival, Nullop, yyvsp[-3].opval, yyvsp[-1].opval, yyvsp[0].opval); } +#line 209 "perly.y" +{ OP *forop = append_elem(OP_LINESEQ, + scalar(yyvsp[-6].opval), + newWHILEOP(0, 1, (LOOP*)Nullop, + yyvsp[-9].ival, scalar(yyvsp[-4].opval), + yyvsp[0].opval, scalar(yyvsp[-2].opval))); + copline = yyvsp[-9].ival; + yyval.opval = block_end(yyvsp[-7].ival, newSTATEOP(0, yyvsp[-10].pval, forop)); } break; case 33: -#line 206 "perly.y" -{ copline = yyvsp[-8].ival; - yyval.opval = append_elem(OP_LINESEQ, - newSTATEOP(0, yyvsp[-9].pval, scalar(yyvsp[-6].opval)), - newSTATEOP(0, yyvsp[-9].pval, - newWHILEOP(0, 1, (LOOP*)Nullop, - scalar(yyvsp[-4].opval), yyvsp[0].opval, scalar(yyvsp[-2].opval)) )); } +#line 217 "perly.y" +{ yyval.opval = newSTATEOP(0, yyvsp[-2].pval, + newWHILEOP(0, 1, (LOOP*)Nullop, + NOLINE, Nullop, yyvsp[-1].opval, yyvsp[0].opval)); } break; case 34: -#line 213 "perly.y" -{ yyval.opval = newSTATEOP(0, - yyvsp[-2].pval, newWHILEOP(0, 1, (LOOP*)Nullop, - Nullop, yyvsp[-1].opval, yyvsp[0].opval)); } -break; -case 35: -#line 219 "perly.y" +#line 223 "perly.y" { yyval.opval = Nullop; } break; -case 37: -#line 224 "perly.y" +case 36: +#line 228 "perly.y" { (void)scan_num("1"); yyval.opval = yylval.opval; } break; +case 38: +#line 233 "perly.y" +{ yyval.opval = invert(scalar(yyvsp[0].opval)); } +break; case 39: -#line 229 "perly.y" -{ yyval.pval = Nullch; } +#line 237 "perly.y" +{ yyval.opval = yyvsp[0].opval; intro_my(); } +break; +case 40: +#line 241 "perly.y" +{ yyval.opval = yyvsp[0].opval; intro_my(); } break; case 41: -#line 234 "perly.y" -{ yyval.ival = 0; } +#line 245 "perly.y" +{ yyval.opval = yyvsp[0].opval; intro_my(); } break; case 42: -#line 236 "perly.y" -{ yyval.ival = 0; } +#line 249 "perly.y" +{ yyval.opval = yyvsp[0].opval; intro_my(); } break; case 43: -#line 238 "perly.y" -{ yyval.ival = 0; } -break; -case 44: -#line 240 "perly.y" -{ yyval.ival = 0; } +#line 253 "perly.y" +{ yyval.pval = Nullch; } break; case 45: -#line 244 "perly.y" -{ newFORM(yyvsp[-2].ival, yyvsp[-1].opval, yyvsp[0].opval); } +#line 258 "perly.y" +{ yyval.ival = 0; } break; case 46: -#line 246 "perly.y" -{ newFORM(yyvsp[-1].ival, Nullop, yyvsp[0].opval); } +#line 260 "perly.y" +{ yyval.ival = 0; } break; case 47: -#line 250 "perly.y" -{ newSUB(yyvsp[-3].ival, yyvsp[-2].opval, yyvsp[-1].opval, yyvsp[0].opval); } +#line 262 "perly.y" +{ yyval.ival = 0; } break; case 48: -#line 252 "perly.y" -{ newSUB(yyvsp[-3].ival, yyvsp[-2].opval, yyvsp[-1].opval, Nullop); expect = XSTATE; } +#line 264 "perly.y" +{ yyval.ival = 0; } break; case 49: -#line 256 "perly.y" -{ yyval.opval = Nullop; } +#line 268 "perly.y" +{ newFORM(yyvsp[-2].ival, yyvsp[-1].opval, yyvsp[0].opval); } +break; +case 50: +#line 271 "perly.y" +{ yyval.opval = yyvsp[0].opval; } break; case 51: -#line 261 "perly.y" -{ yyval.ival = start_subparse(); } +#line 272 "perly.y" +{ yyval.opval = Nullop; } break; case 52: -#line 265 "perly.y" -{ package(yyvsp[-1].opval); } +#line 276 "perly.y" +{ newSUB(yyvsp[-3].ival, yyvsp[-2].opval, yyvsp[-1].opval, yyvsp[0].opval); } break; case 53: -#line 267 "perly.y" -{ package(Nullop); } +#line 280 "perly.y" +{ yyval.ival = start_subparse(FALSE, 0); } break; case 54: -#line 271 "perly.y" -{ utilize(yyvsp[-4].ival, yyvsp[-3].ival, yyvsp[-2].opval, yyvsp[-1].opval); } +#line 284 "perly.y" +{ yyval.ival = start_subparse(FALSE, CVf_ANON); } break; case 55: -#line 275 "perly.y" -{ yyval.opval = newLOGOP(OP_AND, 0, yyvsp[-2].opval, yyvsp[0].opval); } +#line 288 "perly.y" +{ yyval.ival = start_subparse(TRUE, 0); } break; case 56: -#line 277 "perly.y" +#line 291 "perly.y" +{ char *name = SvPVx(((SVOP*)yyvsp[0].opval)->op_sv, na); + if (strEQ(name, "BEGIN") || strEQ(name, "END")) + CvUNIQUE_on(compcv); + yyval.opval = yyvsp[0].opval; } +break; +case 57: +#line 298 "perly.y" +{ yyval.opval = Nullop; } +break; +case 59: +#line 302 "perly.y" +{ yyval.opval = yyvsp[0].opval; } +break; +case 60: +#line 303 "perly.y" +{ yyval.opval = Nullop; expect = XSTATE; } +break; +case 61: +#line 307 "perly.y" +{ package(yyvsp[-1].opval); } +break; +case 62: +#line 309 "perly.y" +{ package(Nullop); } +break; +case 63: +#line 313 "perly.y" +{ CvUNIQUE_on(compcv); /* It's a BEGIN {} */ } +break; +case 64: +#line 315 "perly.y" +{ utilize(yyvsp[-6].ival, yyvsp[-5].ival, yyvsp[-3].opval, yyvsp[-2].opval, yyvsp[-1].opval); } +break; +case 65: +#line 319 "perly.y" +{ yyval.opval = newLOGOP(OP_AND, 0, yyvsp[-2].opval, yyvsp[0].opval); } +break; +case 66: +#line 321 "perly.y" { yyval.opval = newLOGOP(yyvsp[-1].ival, 0, yyvsp[-2].opval, yyvsp[0].opval); } break; -case 58: -#line 282 "perly.y" +case 68: +#line 326 "perly.y" { yyval.opval = yyvsp[-1].opval; } break; -case 59: -#line 284 "perly.y" +case 69: +#line 328 "perly.y" { yyval.opval = append_elem(OP_LIST, yyvsp[-2].opval, yyvsp[0].opval); } break; -case 61: -#line 289 "perly.y" +case 71: +#line 333 "perly.y" { yyval.opval = convert(yyvsp[-2].ival, OPf_STACKED, prepend_elem(OP_LIST, newGVREF(yyvsp[-2].ival,yyvsp[-1].opval), yyvsp[0].opval) ); } break; -case 62: -#line 292 "perly.y" +case 72: +#line 336 "perly.y" { yyval.opval = convert(yyvsp[-4].ival, OPf_STACKED, prepend_elem(OP_LIST, newGVREF(yyvsp[-4].ival,yyvsp[-2].opval), yyvsp[-1].opval) ); } break; -case 63: -#line 295 "perly.y" +case 73: +#line 339 "perly.y" { yyval.opval = convert(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, - prepend_elem(OP_LIST, yyvsp[-5].opval, yyvsp[-1].opval), + prepend_elem(OP_LIST, scalar(yyvsp[-5].opval), yyvsp[-1].opval), newUNOP(OP_METHOD, 0, yyvsp[-3].opval))); } break; -case 64: -#line 300 "perly.y" +case 74: +#line 344 "perly.y" { yyval.opval = convert(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, prepend_elem(OP_LIST, yyvsp[-1].opval, yyvsp[0].opval), newUNOP(OP_METHOD, 0, yyvsp[-2].opval))); } break; -case 65: -#line 305 "perly.y" +case 75: +#line 349 "perly.y" { yyval.opval = convert(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, prepend_elem(OP_LIST, yyvsp[-3].opval, yyvsp[-1].opval), newUNOP(OP_METHOD, 0, yyvsp[-4].opval))); } break; -case 66: -#line 310 "perly.y" +case 76: +#line 354 "perly.y" { yyval.opval = convert(yyvsp[-1].ival, 0, yyvsp[0].opval); } break; -case 67: -#line 312 "perly.y" +case 77: +#line 356 "perly.y" { yyval.opval = convert(yyvsp[-3].ival, 0, yyvsp[-1].opval); } break; -case 68: -#line 314 "perly.y" +case 78: +#line 358 "perly.y" +{ yyvsp[0].opval = newANONSUB(yyvsp[-1].ival, 0, yyvsp[0].opval); } +break; +case 79: +#line 360 "perly.y" { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED, - append_elem(OP_LIST, - prepend_elem(OP_LIST, newANONSUB(yyvsp[-2].ival, 0, yyvsp[-1].opval), yyvsp[0].opval), - yyvsp[-3].opval)); } + append_elem(OP_LIST, + prepend_elem(OP_LIST, yyvsp[-2].opval, yyvsp[0].opval), yyvsp[-4].opval)); } break; -case 71: -#line 325 "perly.y" +case 82: +#line 370 "perly.y" { yyval.opval = newASSIGNOP(OPf_STACKED, yyvsp[-2].opval, yyvsp[-1].ival, yyvsp[0].opval); } break; -case 72: -#line 327 "perly.y" +case 83: +#line 372 "perly.y" { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); } break; -case 73: -#line 329 "perly.y" +case 84: +#line 374 "perly.y" { if (yyvsp[-1].ival != OP_REPEAT) scalar(yyvsp[-2].opval); yyval.opval = newBINOP(yyvsp[-1].ival, 0, yyvsp[-2].opval, scalar(yyvsp[0].opval)); } break; -case 74: -#line 333 "perly.y" +case 85: +#line 378 "perly.y" { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); } break; -case 75: -#line 335 "perly.y" +case 86: +#line 380 "perly.y" { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); } break; -case 76: -#line 337 "perly.y" +case 87: +#line 382 "perly.y" { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); } break; -case 77: -#line 339 "perly.y" +case 88: +#line 384 "perly.y" { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); } break; -case 78: -#line 341 "perly.y" +case 89: +#line 386 "perly.y" { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); } break; -case 79: -#line 343 "perly.y" +case 90: +#line 388 "perly.y" { yyval.opval = newBINOP(yyvsp[-1].ival, 0, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval)); } break; -case 80: -#line 345 "perly.y" +case 91: +#line 390 "perly.y" { yyval.opval = newRANGE(yyvsp[-1].ival, scalar(yyvsp[-2].opval), scalar(yyvsp[0].opval));} break; -case 81: -#line 347 "perly.y" +case 92: +#line 392 "perly.y" { yyval.opval = newLOGOP(OP_AND, 0, yyvsp[-2].opval, yyvsp[0].opval); } break; -case 82: -#line 349 "perly.y" +case 93: +#line 394 "perly.y" { yyval.opval = newLOGOP(OP_OR, 0, yyvsp[-2].opval, yyvsp[0].opval); } break; -case 83: -#line 351 "perly.y" +case 94: +#line 396 "perly.y" { yyval.opval = newCONDOP(0, yyvsp[-4].opval, yyvsp[-2].opval, yyvsp[0].opval); } break; -case 84: -#line 353 "perly.y" +case 95: +#line 398 "perly.y" { yyval.opval = bind_match(yyvsp[-1].ival, yyvsp[-2].opval, yyvsp[0].opval); } break; -case 85: -#line 356 "perly.y" +case 96: +#line 401 "perly.y" { yyval.opval = newUNOP(OP_NEGATE, 0, scalar(yyvsp[0].opval)); } break; -case 86: -#line 358 "perly.y" +case 97: +#line 403 "perly.y" { yyval.opval = yyvsp[0].opval; } break; -case 87: -#line 360 "perly.y" +case 98: +#line 405 "perly.y" { yyval.opval = newUNOP(OP_NOT, 0, scalar(yyvsp[0].opval)); } break; -case 88: -#line 362 "perly.y" +case 99: +#line 407 "perly.y" { yyval.opval = newUNOP(OP_COMPLEMENT, 0, scalar(yyvsp[0].opval));} break; -case 89: -#line 364 "perly.y" +case 100: +#line 409 "perly.y" { yyval.opval = newUNOP(OP_REFGEN, 0, mod(yyvsp[0].opval,OP_REFGEN)); } break; -case 90: -#line 366 "perly.y" +case 101: +#line 411 "perly.y" { yyval.opval = newUNOP(OP_POSTINC, 0, mod(scalar(yyvsp[-1].opval), OP_POSTINC)); } break; -case 91: -#line 369 "perly.y" +case 102: +#line 414 "perly.y" { yyval.opval = newUNOP(OP_POSTDEC, 0, mod(scalar(yyvsp[-1].opval), OP_POSTDEC)); } break; -case 92: -#line 372 "perly.y" +case 103: +#line 417 "perly.y" { yyval.opval = newUNOP(OP_PREINC, 0, mod(scalar(yyvsp[0].opval), OP_PREINC)); } break; -case 93: -#line 375 "perly.y" +case 104: +#line 420 "perly.y" { yyval.opval = newUNOP(OP_PREDEC, 0, mod(scalar(yyvsp[0].opval), OP_PREDEC)); } break; -case 94: -#line 378 "perly.y" +case 105: +#line 423 "perly.y" { yyval.opval = localize(yyvsp[0].opval,yyvsp[-1].ival); } break; -case 95: -#line 380 "perly.y" +case 106: +#line 425 "perly.y" { yyval.opval = sawparens(yyvsp[-1].opval); } break; -case 96: -#line 382 "perly.y" +case 107: +#line 427 "perly.y" { yyval.opval = sawparens(newNULLLIST()); } break; -case 97: -#line 384 "perly.y" +case 108: +#line 429 "perly.y" { yyval.opval = newANONLIST(yyvsp[-1].opval); } break; -case 98: -#line 386 "perly.y" +case 109: +#line 431 "perly.y" { yyval.opval = newANONLIST(Nullop); } break; -case 99: -#line 388 "perly.y" +case 110: +#line 433 "perly.y" { yyval.opval = newANONHASH(yyvsp[-2].opval); } break; -case 100: -#line 390 "perly.y" +case 111: +#line 435 "perly.y" { yyval.opval = newANONHASH(Nullop); } break; -case 101: -#line 392 "perly.y" +case 112: +#line 437 "perly.y" { yyval.opval = newANONSUB(yyvsp[-2].ival, yyvsp[-1].opval, yyvsp[0].opval); } break; -case 102: -#line 394 "perly.y" +case 113: +#line 439 "perly.y" { yyval.opval = yyvsp[0].opval; } break; -case 103: -#line 396 "perly.y" +case 114: +#line 441 "perly.y" { yyval.opval = newBINOP(OP_GELEM, 0, newGVREF(0,yyvsp[-4].opval), yyvsp[-2].opval); } break; -case 104: -#line 398 "perly.y" +case 115: +#line 443 "perly.y" { yyval.opval = yyvsp[0].opval; } break; -case 105: -#line 400 "perly.y" +case 116: +#line 445 "perly.y" { yyval.opval = newBINOP(OP_AELEM, 0, oopsAV(yyvsp[-3].opval), scalar(yyvsp[-1].opval)); } break; -case 106: -#line 402 "perly.y" +case 117: +#line 447 "perly.y" { yyval.opval = newBINOP(OP_AELEM, 0, ref(newAVREF(yyvsp[-4].opval),OP_RV2AV), scalar(yyvsp[-1].opval));} break; -case 107: -#line 406 "perly.y" +case 118: +#line 451 "perly.y" { assertref(yyvsp[-3].opval); yyval.opval = newBINOP(OP_AELEM, 0, ref(newAVREF(yyvsp[-3].opval),OP_RV2AV), scalar(yyvsp[-1].opval));} break; -case 108: -#line 410 "perly.y" +case 119: +#line 455 "perly.y" { yyval.opval = yyvsp[0].opval; } break; -case 109: -#line 412 "perly.y" +case 120: +#line 457 "perly.y" { yyval.opval = yyvsp[0].opval; } break; -case 110: -#line 414 "perly.y" +case 121: +#line 459 "perly.y" { yyval.opval = newUNOP(OP_AV2ARYLEN, 0, ref(yyvsp[0].opval, OP_AV2ARYLEN));} break; -case 111: -#line 416 "perly.y" +case 122: +#line 461 "perly.y" { yyval.opval = newBINOP(OP_HELEM, 0, oopsHV(yyvsp[-4].opval), jmaybe(yyvsp[-2].opval)); expect = XOPERATOR; } break; -case 112: -#line 419 "perly.y" +case 123: +#line 464 "perly.y" { yyval.opval = newBINOP(OP_HELEM, 0, ref(newHVREF(yyvsp[-5].opval),OP_RV2HV), jmaybe(yyvsp[-2].opval)); expect = XOPERATOR; } break; -case 113: -#line 424 "perly.y" +case 124: +#line 469 "perly.y" { assertref(yyvsp[-4].opval); yyval.opval = newBINOP(OP_HELEM, 0, ref(newHVREF(yyvsp[-4].opval),OP_RV2HV), jmaybe(yyvsp[-2].opval)); expect = XOPERATOR; } break; -case 114: -#line 429 "perly.y" +case 125: +#line 474 "perly.y" { yyval.opval = newSLICEOP(0, yyvsp[-1].opval, yyvsp[-4].opval); } break; -case 115: -#line 431 "perly.y" +case 126: +#line 476 "perly.y" { yyval.opval = newSLICEOP(0, yyvsp[-1].opval, Nullop); } break; -case 116: -#line 433 "perly.y" +case 127: +#line 478 "perly.y" { yyval.opval = prepend_elem(OP_ASLICE, newOP(OP_PUSHMARK, 0), newLISTOP(OP_ASLICE, 0, list(yyvsp[-1].opval), ref(yyvsp[-3].opval, OP_ASLICE))); } break; -case 117: -#line 439 "perly.y" +case 128: +#line 484 "perly.y" { yyval.opval = prepend_elem(OP_HSLICE, newOP(OP_PUSHMARK, 0), newLISTOP(OP_HSLICE, 0, @@ -2063,38 +2075,38 @@ case 117: ref(oopsHV(yyvsp[-4].opval), OP_HSLICE))); expect = XOPERATOR; } break; -case 118: -#line 446 "perly.y" +case 129: +#line 491 "perly.y" { yyval.opval = yyvsp[0].opval; } break; -case 119: -#line 448 "perly.y" +case 130: +#line 493 "perly.y" { yyval.opval = newUNOP(OP_ENTERSUB, 0, scalar(yyvsp[0].opval)); } break; -case 120: -#line 450 "perly.y" +case 131: +#line 495 "perly.y" { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar(yyvsp[-2].opval)); } break; -case 121: -#line 452 "perly.y" +case 132: +#line 497 "perly.y" { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, yyvsp[-1].opval, scalar(yyvsp[-3].opval))); } break; -case 122: -#line 455 "perly.y" +case 133: +#line 500 "perly.y" { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, yyvsp[0].opval, scalar(yyvsp[-1].opval))); } break; -case 123: -#line 458 "perly.y" +case 134: +#line 503 "perly.y" { yyval.opval = newUNOP(OP_DOFILE, 0, scalar(yyvsp[0].opval)); } break; -case 124: -#line 460 "perly.y" +case 135: +#line 505 "perly.y" { yyval.opval = newUNOP(OP_NULL, OPf_SPECIAL, scope(yyvsp[0].opval)); } break; -case 125: -#line 462 "perly.y" +case 136: +#line 507 "perly.y" { yyval.opval = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED, prepend_elem(OP_LIST, @@ -2103,8 +2115,8 @@ case 125: scalar(yyvsp[-2].opval) )),Nullop)); dep();} break; -case 126: -#line 470 "perly.y" +case 137: +#line 515 "perly.y" { yyval.opval = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED, append_elem(OP_LIST, @@ -2114,139 +2126,162 @@ case 126: scalar(yyvsp[-3].opval) )))); dep();} break; -case 127: -#line 479 "perly.y" +case 138: +#line 524 "perly.y" { yyval.opval = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED, prepend_elem(OP_LIST, scalar(newCVREF(0,scalar(yyvsp[-2].opval))), Nullop)); dep();} break; -case 128: -#line 483 "perly.y" +case 139: +#line 528 "perly.y" { yyval.opval = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED, prepend_elem(OP_LIST, yyvsp[-1].opval, scalar(newCVREF(0,scalar(yyvsp[-3].opval))))); dep();} break; -case 129: -#line 488 "perly.y" +case 140: +#line 533 "perly.y" +{ yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED, + newCVREF(0, scalar(yyvsp[-3].opval))); } +break; +case 141: +#line 536 "perly.y" +{ yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED, + append_elem(OP_LIST, yyvsp[-1].opval, + newCVREF(0, scalar(yyvsp[-4].opval)))); } +break; +case 142: +#line 540 "perly.y" { yyval.opval = newOP(yyvsp[0].ival, OPf_SPECIAL); hints |= HINT_BLOCK_SCOPE; } break; -case 130: -#line 491 "perly.y" +case 143: +#line 543 "perly.y" { yyval.opval = newLOOPEX(yyvsp[-1].ival,yyvsp[0].opval); } break; -case 131: -#line 493 "perly.y" +case 144: +#line 545 "perly.y" { yyval.opval = newUNOP(OP_NOT, 0, scalar(yyvsp[0].opval)); } break; -case 132: -#line 495 "perly.y" +case 145: +#line 547 "perly.y" { yyval.opval = newOP(yyvsp[0].ival, 0); } break; -case 133: -#line 497 "perly.y" +case 146: +#line 549 "perly.y" { yyval.opval = newUNOP(yyvsp[-1].ival, 0, yyvsp[0].opval); } break; -case 134: -#line 499 "perly.y" +case 147: +#line 551 "perly.y" { yyval.opval = newUNOP(yyvsp[-1].ival, 0, yyvsp[0].opval); } break; -case 135: -#line 501 "perly.y" +case 148: +#line 553 "perly.y" { yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, yyvsp[0].opval, scalar(yyvsp[-1].opval))); } break; -case 136: -#line 504 "perly.y" +case 149: +#line 556 "perly.y" { yyval.opval = newOP(yyvsp[0].ival, 0); } break; -case 137: -#line 506 "perly.y" +case 150: +#line 558 "perly.y" { yyval.opval = newOP(yyvsp[-2].ival, 0); } break; -case 138: -#line 508 "perly.y" -{ yyval.opval = newUNOP(OP_ENTERSUB, 0, +case 151: +#line 560 "perly.y" +{ yyval.opval = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar(yyvsp[0].opval)); } break; -case 139: -#line 511 "perly.y" +case 152: +#line 563 "perly.y" { yyval.opval = newOP(yyvsp[-2].ival, OPf_SPECIAL); } break; -case 140: -#line 513 "perly.y" +case 153: +#line 565 "perly.y" { yyval.opval = newUNOP(yyvsp[-3].ival, 0, yyvsp[-1].opval); } break; -case 141: -#line 515 "perly.y" +case 154: +#line 567 "perly.y" { yyval.opval = pmruntime(yyvsp[-3].opval, yyvsp[-1].opval, Nullop); } break; -case 142: -#line 517 "perly.y" +case 155: +#line 569 "perly.y" { yyval.opval = pmruntime(yyvsp[-5].opval, yyvsp[-3].opval, yyvsp[-1].opval); } break; -case 145: -#line 523 "perly.y" +case 158: +#line 575 "perly.y" { yyval.opval = Nullop; } break; -case 146: -#line 525 "perly.y" +case 159: +#line 577 "perly.y" { yyval.opval = yyvsp[0].opval; } break; -case 147: -#line 529 "perly.y" +case 160: +#line 581 "perly.y" { yyval.opval = Nullop; } break; -case 148: -#line 531 "perly.y" +case 161: +#line 583 "perly.y" { yyval.opval = yyvsp[0].opval; } break; -case 149: -#line 533 "perly.y" +case 162: +#line 585 "perly.y" { yyval.opval = yyvsp[-1].opval; } break; -case 150: -#line 537 "perly.y" +case 163: +#line 588 "perly.y" +{ yyval.ival = 0; } +break; +case 164: +#line 589 "perly.y" +{ yyval.ival = 1; } +break; +case 165: +#line 593 "perly.y" +{ in_my = 0; yyval.opval = my(yyvsp[0].opval); } +break; +case 166: +#line 597 "perly.y" { yyval.opval = newCVREF(yyvsp[-1].ival,yyvsp[0].opval); } break; -case 151: -#line 541 "perly.y" +case 167: +#line 601 "perly.y" { yyval.opval = newSVREF(yyvsp[0].opval); } break; -case 152: -#line 545 "perly.y" +case 168: +#line 605 "perly.y" { yyval.opval = newAVREF(yyvsp[0].opval); } break; -case 153: -#line 549 "perly.y" +case 169: +#line 609 "perly.y" { yyval.opval = newHVREF(yyvsp[0].opval); } break; -case 154: -#line 553 "perly.y" +case 170: +#line 613 "perly.y" { yyval.opval = newAVREF(yyvsp[0].opval); } break; -case 155: -#line 557 "perly.y" +case 171: +#line 617 "perly.y" { yyval.opval = newGVREF(0,yyvsp[0].opval); } break; -case 156: -#line 561 "perly.y" +case 172: +#line 621 "perly.y" { yyval.opval = scalar(yyvsp[0].opval); } break; -case 157: -#line 563 "perly.y" +case 173: +#line 623 "perly.y" { yyval.opval = scalar(yyvsp[0].opval); } break; -case 158: -#line 565 "perly.y" +case 174: +#line 625 "perly.y" { yyval.opval = scope(yyvsp[0].opval); } break; -case 159: -#line 568 "perly.y" +case 175: +#line 628 "perly.y" { yyval.opval = yyvsp[0].opval; } break; -#line 2236 "y.tab.c" +#line 2271 "perly.c" } yyssp -= yym; yystate = *yyssp; @@ -2256,7 +2291,7 @@ break; { #if YYDEBUG if (yydebug) - fprintf(stderr, + PerlIO_printf(Perl_debug_log, "yydebug: after reduction, shifting from state 0 to state %d\n", YYFINAL); #endif @@ -2272,7 +2307,7 @@ break; yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; - fprintf(stderr, "yydebug: state %d, reading %d (%s)\n", + PerlIO_printf(Perl_debug_log, "yydebug: state %d, reading %d (%s)\n", YYFINAL, yychar, yys); } #endif @@ -2287,7 +2322,7 @@ break; yystate = yydgoto[yym]; #if YYDEBUG if (yydebug) - fprintf(stderr, + PerlIO_printf(Perl_debug_log, "yydebug: after reduction, shifting from state %d to state %d\n", *yyssp, yystate); #endif diff --git a/gnu/usr.bin/perl/perly.c.diff b/gnu/usr.bin/perl/perly.c.diff index 3b3c04ecf88..b4aec9d5981 100644 --- a/gnu/usr.bin/perl/perly.c.diff +++ b/gnu/usr.bin/perl/perly.c.diff @@ -1,82 +1,84 @@ -*** perly.c.orig Wed Feb 14 15:29:04 1996 ---- perly.c Wed Feb 14 15:29:05 1996 +Index: perly.c *************** -*** 12,82 **** - deprecate("\"do\" to call subroutines"); +*** 13,82 **** } -- #line 29 "perly.y" -- typedef union { -- I32 ival; -- char *pval; -- OP *opval; -- GV *gvval; -- } YYSTYPE; -- #line 23 "y.tab.c" -- #define WORD 257 -- #define METHOD 258 -- #define FUNCMETH 259 -- #define THING 260 -- #define PMFUNC 261 -- #define PRIVATEREF 262 -- #define FUNC0SUB 263 -- #define UNIOPSUB 264 -- #define LSTOPSUB 265 -- #define LABEL 266 -- #define FORMAT 267 -- #define SUB 268 -- #define ANONSUB 269 -- #define PACKAGE 270 -- #define USE 271 -- #define WHILE 272 -- #define UNTIL 273 -- #define IF 274 -- #define UNLESS 275 -- #define ELSE 276 -- #define ELSIF 277 -- #define CONTINUE 278 -- #define FOR 279 -- #define LOOPEX 280 -- #define DOTDOT 281 -- #define FUNC0 282 -- #define FUNC1 283 -- #define FUNC 284 -- #define RELOP 285 -- #define EQOP 286 -- #define MULOP 287 -- #define ADDOP 288 -- #define DOLSHARP 289 -- #define DO 290 -- #define LOCAL 291 -- #define HASHBRACK 292 -- #define NOAMP 293 -- #define OROP 294 -- #define ANDOP 295 -- #define NOTOP 296 -- #define LSTOP 297 -- #define ASSIGNOP 298 -- #define OROR 299 -- #define ANDAND 300 -- #define BITOROP 301 -- #define BITANDOP 302 -- #define UNIOP 303 -- #define SHIFTOP 304 -- #define MATCHOP 305 -- #define UMINUS 306 -- #define REFGEN 307 -- #define POWOP 308 -- #define PREINC 309 -- #define PREDEC 310 -- #define POSTINC 311 -- #define POSTDEC 312 -- #define ARROW 313 +! #line 29 "perly.y" +! typedef union { +! I32 ival; +! char *pval; +! OP *opval; +! GV *gvval; +! } YYSTYPE; +! #line 23 "y.tab.c" +! #define WORD 257 +! #define METHOD 258 +! #define FUNCMETH 259 +! #define THING 260 +! #define PMFUNC 261 +! #define PRIVATEREF 262 +! #define FUNC0SUB 263 +! #define UNIOPSUB 264 +! #define LSTOPSUB 265 +! #define LABEL 266 +! #define FORMAT 267 +! #define SUB 268 +! #define ANONSUB 269 +! #define PACKAGE 270 +! #define USE 271 +! #define WHILE 272 +! #define UNTIL 273 +! #define IF 274 +! #define UNLESS 275 +! #define ELSE 276 +! #define ELSIF 277 +! #define CONTINUE 278 +! #define FOR 279 +! #define LOOPEX 280 +! #define DOTDOT 281 +! #define FUNC0 282 +! #define FUNC1 283 +! #define FUNC 284 +! #define UNIOP 285 +! #define LSTOP 286 +! #define RELOP 287 +! #define EQOP 288 +! #define MULOP 289 +! #define ADDOP 290 +! #define DOLSHARP 291 +! #define DO 292 +! #define HASHBRACK 293 +! #define NOAMP 294 +! #define LOCAL 295 +! #define MY 296 +! #define OROP 297 +! #define ANDOP 298 +! #define NOTOP 299 +! #define ASSIGNOP 300 +! #define OROR 301 +! #define ANDAND 302 +! #define BITOROP 303 +! #define BITANDOP 304 +! #define SHIFTOP 305 +! #define MATCHOP 306 +! #define UMINUS 307 +! #define REFGEN 308 +! #define POWOP 309 +! #define PREINC 310 +! #define PREDEC 311 +! #define POSTINC 312 +! #define POSTDEC 313 +! #define ARROW 314 + #define YYERRCODE 256 + short yylhs[] = { -1, +--- 13,17 ---- + } + +! #line 16 "perly.c" #define YYERRCODE 256 short yylhs[] = { -1, - 31, 0, 5, 3, 6, 6, 6, 7, 7, 7, ---- 12,17 ---- *************** -*** 1381,1393 **** - int yynerrs; +*** 1348,1358 **** int yyerrflag; int yychar; - short *yyssp; @@ -86,14 +88,12 @@ - short yyss[YYSTACKSIZE]; - YYSTYPE yyvs[YYSTACKSIZE]; - #define yystacksize YYSTACKSIZE - #line 571 "perly.y" + #line 631 "perly.y" /* PROGRAM */ - #line 1394 "y.tab.c" ---- 1316,1323 ---- +--- 1283,1288 ---- *************** -*** 1394,1407 **** ---- 1324,1382 ---- - #define YYABORT goto yyabort +*** 1361,1372 **** +--- 1291,1347 ---- #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab + @@ -138,7 +138,7 @@ register char *yys; extern char *getenv(); + #endif - ++ + struct ysv *ysave = (struct ysv*)safemalloc(sizeof(struct ysv)); + SAVEDESTRUCTOR(yydestruct, ysave); + ysave->oldyydebug = yydebug; @@ -147,15 +147,13 @@ + ysave->oldyychar = yychar; + ysave->oldyyval = yyval; + ysave->oldyylval = yylval; -+ + + #if YYDEBUG if (yys = getenv("YYDEBUG")) { - yyn = *yys; *************** -*** 1414,1419 **** ---- 1389,1402 ---- - yyerrflag = 0; +*** 1381,1384 **** +--- 1356,1367 ---- yychar = (-1); + /* @@ -168,27 +166,21 @@ + yyssp = yyss; yyvsp = yyvs; - *yyssp = yystate = 0; *************** -*** 1429,1435 **** - yys = 0; +*** 1396,1400 **** if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; ! printf("yydebug: state %d, reading %d (%s)\n", yystate, yychar, yys); } - #endif ---- 1412,1418 ---- - yys = 0; +--- 1379,1383 ---- if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; ! fprintf(stderr, "yydebug: state %d, reading %d (%s)\n", yystate, yychar, yys); } - #endif *************** -*** 1439,1450 **** - { +*** 1406,1415 **** #if YYDEBUG if (yydebug) ! printf("yydebug: state %d, shifting to state %d\n", @@ -199,9 +191,7 @@ ! goto yyoverflow; } *++yyssp = yystate = yytable[yyn]; - *++yyvsp = yylval; ---- 1422,1447 ---- - { +--- 1389,1412 ---- #if YYDEBUG if (yydebug) ! fprintf(stderr, "yydebug: state %d, shifting to state %d\n", @@ -226,10 +216,8 @@ ! yyvsp = yyvs + yypv_index; } *++yyssp = yystate = yytable[yyn]; - *++yyvsp = yylval; *************** -*** 1480,1491 **** - { +*** 1447,1456 **** #if YYDEBUG if (yydebug) ! printf("yydebug: state %d, error recovery shifting\ @@ -240,9 +228,7 @@ ! goto yyoverflow; } *++yyssp = yystate = yytable[yyn]; - *++yyvsp = yylval; ---- 1477,1503 ---- - { +--- 1444,1468 ---- #if YYDEBUG if (yydebug) ! fprintf(stderr, @@ -268,19 +254,15 @@ ! yyvsp = yyvs + yypv_index; } *++yyssp = yystate = yytable[yyn]; - *++yyvsp = yylval; *************** -*** 1495,1502 **** - { +*** 1462,1467 **** #if YYDEBUG if (yydebug) ! printf("yydebug: error recovery discarding state %d\n", ! *yyssp); #endif if (yyssp <= yyss) goto yyabort; - --yyssp; ---- 1507,1515 ---- - { +--- 1474,1480 ---- #if YYDEBUG if (yydebug) ! fprintf(stderr, @@ -288,19 +270,15 @@ ! *yyssp); #endif if (yyssp <= yyss) goto yyabort; - --yyssp; *************** -*** 1513,1520 **** - yys = 0; +*** 1480,1485 **** if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; ! printf("yydebug: state %d, error recovery discards token %d (%s)\n", ! yystate, yychar, yys); } #endif - yychar = (-1); ---- 1526,1534 ---- - yys = 0; +--- 1493,1499 ---- if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; ! fprintf(stderr, @@ -308,36 +286,28 @@ ! yystate, yychar, yys); } #endif - yychar = (-1); *************** -*** 1523,1529 **** - yyreduce: +*** 1490,1494 **** #if YYDEBUG if (yydebug) ! printf("yydebug: state %d, reducing by rule %d (%s)\n", yystate, yyn, yyrule[yyn]); #endif - yym = yylen[yyn]; ---- 1537,1543 ---- - yyreduce: +--- 1504,1508 ---- #if YYDEBUG if (yydebug) ! fprintf(stderr, "yydebug: state %d, reducing by rule %d (%s)\n", yystate, yyn, yyrule[yyn]); #endif - yym = yylen[yyn]; *************** -*** 2242,2249 **** - { +*** 2278,2283 **** #if YYDEBUG if (yydebug) ! printf("yydebug: after reduction, shifting from state 0 to\ ! state %d\n", YYFINAL); #endif yystate = YYFINAL; - *++yyssp = YYFINAL; ---- 2256,2264 ---- - { +--- 2292,2298 ---- #if YYDEBUG if (yydebug) ! fprintf(stderr, @@ -345,27 +315,21 @@ ! YYFINAL); #endif yystate = YYFINAL; - *++yyssp = YYFINAL; *************** -*** 2257,2263 **** - yys = 0; +*** 2293,2297 **** if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; ! printf("yydebug: state %d, reading %d (%s)\n", YYFINAL, yychar, yys); } - #endif ---- 2272,2278 ---- - yys = 0; +--- 2308,2312 ---- if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; ! fprintf(stderr, "yydebug: state %d, reading %d (%s)\n", YYFINAL, yychar, yys); } - #endif *************** -*** 2272,2291 **** - yystate = yydgoto[yym]; +*** 2308,2317 **** #if YYDEBUG if (yydebug) ! printf("yydebug: after reduction, shifting from state %d \ @@ -376,17 +340,7 @@ ! goto yyoverflow; } *++yyssp = yystate; - *++yyvsp = yyval; - goto yyloop; - yyoverflow: -! yyerror("yacc stack overflow"); - yyabort: -! return (1); - yyaccept: -! return (0); - } ---- 2287,2321 ---- - yystate = yydgoto[yym]; +--- 2323,2347 ---- #if YYDEBUG if (yydebug) ! fprintf(stderr, @@ -412,7 +366,17 @@ ! yyvsp = yyvs + yypv_index; } *++yyssp = yystate; - *++yyvsp = yyval; +*************** +*** 2319,2326 **** + goto yyloop; + yyoverflow: +! yyerror("yacc stack overflow"); + yyabort: +! return (1); + yyaccept: +! return (0); + } +--- 2349,2356 ---- goto yyloop; yyoverflow: ! yyerror("Out of memory for yacc stack"); diff --git a/gnu/usr.bin/perl/perly.fixer b/gnu/usr.bin/perl/perly.fixer index 98296a72fd2..156881657f0 100644 --- a/gnu/usr.bin/perl/perly.fixer +++ b/gnu/usr.bin/perl/perly.fixer @@ -5,8 +5,9 @@ # # However, if the user wishes to use byacc, or wishes to try another # compiler compiler (e.g. bison or yacc), this script will get run. +# See makefile run_byacc target for more details. # -# Currently, only byacc version 1.8 is supported. +# Currently, only byacc version 1.8 is fully supported. # # Hacks to make it work with Interactive's SysVr3 Version 2.2 # doughera@lafvax.lafayette.edu (Andy Dougherty) 3/23/91 @@ -44,7 +45,15 @@ fi plan="unknown" -# Below, we check for various yaccpar outputs. +echo "" +echo "Warning: the yacc you have used is not directly supported by perl." +echo "The perly.fixer script will attempt to make some changes to the generated" +echo "file. The changes may be incomplete and that might lead to problems later" +echo "(especially with complex scripts). You may need to apply the changes" +echo "embedded in perl.fixer (and/or perly.c.dif*) by hand." +echo "" + +# Below, we check for various characteristic yaccpar outputs. # Test for BSD 4.3 version. # Also tests for the SunOS 4.0.2 version @@ -73,13 +82,15 @@ if *\( *\+\+yy_ps *>= *&yys\[ *YYMAXDEPTH *\] *\)' $input >$tmp 2>/dev/null fi fi +# ------ + case "$plan" in ################################################################## # The SunOS 4.0.2 version has the comparison fixed already. # Also added are out of memory checks (makes porting the generated # code easier) For most systems, it can't hurt. -- TD "bsd43") - echo "Patching perly.c to allow dynamic yacc stack allocation" + echo "Attempting to path perly.c to allow dynamic yacc stack allocation" echo "Assuming bsd4.3 yaccpar" cat >$tmp <<'END' /YYSTYPE[ ]*yyv\[ *YYMAXDEPTH *\];/c\ @@ -128,11 +139,15 @@ short *maxyyps; /yacc stack overflow.*}/d /yacc stack overflow/,/}/d END - sed -f $tmp <$input >$output ;; + if sed -f $tmp <$input >$output + then echo "The edit seems to have been applied okay." + else echo "The edit seems to have failed!" + fi + ;; ####################################################### "isc") # Interactive Systems 2.2 version - echo "Patching perly.c to allow dynamic yacc stack allocation" + echo "Attempting to path perly.c to allow dynamic yacc stack allocation" echo "Assuming Interactive SysVr3 2.2 yaccpar" # Easier to simply put whole script here than to modify the # bsd script with sed. @@ -178,11 +193,20 @@ int *maxyyps; \ }\ \ if (yyv == NULL || yys == NULL) END - sed -f $tmp < $input > $output ;; + if sed -f $tmp < $input > $output + then echo "The edit seems to have been applied okay." + else echo "The edit seems to have failed!" + fi + ;; ###################################################### # Plan still unknown - *) sed -e 's/Received token/ *** Received token/' $input >$output; + *) + echo "Unable to patch perly.c to allow dynamic yacc stack allocation (plan=$plan)" + # just do minimal change to write $output from $input + sed -e 's/Received token/ *** Received token/' $input >$output + ;; esac +echo "" rm -rf $tmp $input diff --git a/gnu/usr.bin/perl/perly.h b/gnu/usr.bin/perl/perly.h index 56eaf7e2a46..99077270011 100644 --- a/gnu/usr.bin/perl/perly.h +++ b/gnu/usr.bin/perl/perly.h @@ -26,35 +26,36 @@ #define FUNC0 282 #define FUNC1 283 #define FUNC 284 -#define RELOP 285 -#define EQOP 286 -#define MULOP 287 -#define ADDOP 288 -#define DOLSHARP 289 -#define DO 290 -#define LOCAL 291 -#define HASHBRACK 292 -#define NOAMP 293 -#define OROP 294 -#define ANDOP 295 -#define NOTOP 296 -#define LSTOP 297 -#define ASSIGNOP 298 -#define OROR 299 -#define ANDAND 300 -#define BITOROP 301 -#define BITANDOP 302 -#define UNIOP 303 -#define SHIFTOP 304 -#define MATCHOP 305 -#define UMINUS 306 -#define REFGEN 307 -#define POWOP 308 -#define PREINC 309 -#define PREDEC 310 -#define POSTINC 311 -#define POSTDEC 312 -#define ARROW 313 +#define UNIOP 285 +#define LSTOP 286 +#define RELOP 287 +#define EQOP 288 +#define MULOP 289 +#define ADDOP 290 +#define DOLSHARP 291 +#define DO 292 +#define HASHBRACK 293 +#define NOAMP 294 +#define LOCAL 295 +#define MY 296 +#define OROP 297 +#define ANDOP 298 +#define NOTOP 299 +#define ASSIGNOP 300 +#define OROR 301 +#define ANDAND 302 +#define BITOROP 303 +#define BITANDOP 304 +#define SHIFTOP 305 +#define MATCHOP 306 +#define UMINUS 307 +#define REFGEN 308 +#define POWOP 309 +#define PREINC 310 +#define PREDEC 311 +#define POSTINC 312 +#define POSTDEC 313 +#define ARROW 314 typedef union { I32 ival; char *pval; diff --git a/gnu/usr.bin/perl/perly.y b/gnu/usr.bin/perl/perly.y index 96a35e1c0ec..6313061934f 100644 --- a/gnu/usr.bin/perl/perly.y +++ b/gnu/usr.bin/perl/perly.y @@ -1,6 +1,6 @@ /* perly.y * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -9,7 +9,7 @@ /* * 'I see,' laughed Strider. 'I look foul and feel fair. Is that it? - * All that is gold does not glitter, not all those that wander are lost.' + * All that is gold does not glitter, not all those who wander are lost.' */ %{ @@ -41,22 +41,24 @@ dep() %token <ival> FORMAT SUB ANONSUB PACKAGE USE %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR %token <ival> LOOPEX DOTDOT -%token <ival> FUNC0 FUNC1 FUNC +%token <ival> FUNC0 FUNC1 FUNC UNIOP LSTOP %token <ival> RELOP EQOP MULOP ADDOP -%token <ival> DOLSHARP DO LOCAL HASHBRACK NOAMP +%token <ival> DOLSHARP DO HASHBRACK NOAMP +%token LOCAL MY -%type <ival> prog decl format remember startsub '&' -%type <opval> block lineseq line loop cond nexpr else argexpr +%type <ival> prog decl local format startsub startanonsub startformsub +%type <ival> remember mremember '&' +%type <opval> block mblock lineseq line loop cond else %type <opval> expr term scalar ary hsh arylen star amper sideff -%type <opval> listexpr listexprcom indirob -%type <opval> texpr listop method proto +%type <opval> argexpr nexpr texpr iexpr mexpr mnexpr mtexpr miexpr +%type <opval> listexpr listexprcom indirob listop method +%type <opval> formname subname proto subbody cont my_scalar %type <pval> label -%type <opval> cont %left <ival> OROP %left ANDOP %right NOTOP -%nonassoc <ival> LSTOP +%nonassoc LSTOP LSTOPSUB %left ',' %right <ival> ASSIGNOP %right '?' ':' @@ -67,7 +69,7 @@ dep() %left <ival> BITANDOP %nonassoc EQOP %nonassoc RELOP -%nonassoc <ival> UNIOP +%nonassoc UNIOP UNIOPSUB %left <ival> SHIFTOP %left ADDOP %left MULOP @@ -92,11 +94,23 @@ prog : /* NULL */ ; block : '{' remember lineseq '}' - { $$ = block_end($1,$2,$3); } + { if (copline > (line_t)$1) + copline = $1; + $$ = block_end($2, $3); } ; -remember: /* NULL */ /* start a lexical scope */ - { $$ = block_start(); } +remember: /* NULL */ /* start a full lexical scope */ + { $$ = block_start(TRUE); } + ; + +mblock : '{' mremember lineseq '}' + { if (copline > (line_t)$1) + copline = $1; + $$ = block_end($2, $3); } + ; + +mremember: /* NULL */ /* start a partial lexical scope */ + { $$ = block_start(FALSE); } ; lineseq : /* NULL */ @@ -137,37 +151,29 @@ sideff : error { $$ = newLOGOP(OP_OR, 0, $3, $1); } | expr WHILE expr { $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1); } - | expr UNTIL expr - { $$ = newLOOPOP(OPf_PARENS, 1, invert(scalar($3)), $1);} + | expr UNTIL iexpr + { $$ = newLOOPOP(OPf_PARENS, 1, $3, $1);} ; else : /* NULL */ { $$ = Nullop; } - | ELSE block + | ELSE mblock { $$ = scope($2); } - | ELSIF '(' expr ')' block else + | ELSIF '(' mexpr ')' mblock else { copline = $1; - $$ = newSTATEOP(0, 0, - newCONDOP(0, $3, scope($5), $6)); + $$ = newSTATEOP(0, Nullch, + newCONDOP(0, $3, scope($5), $6)); hints |= HINT_BLOCK_SCOPE; } ; -cond : IF '(' expr ')' block else - { copline = $1; - $$ = newCONDOP(0, $3, scope($5), $6); } - | UNLESS '(' expr ')' block else +cond : IF '(' remember mexpr ')' mblock else { copline = $1; - $$ = newCONDOP(0, - invert(scalar($3)), scope($5), $6); } - | IF block block else + $$ = block_end($3, + newCONDOP(0, $4, scope($6), $7)); } + | UNLESS '(' remember miexpr ')' mblock else { copline = $1; - deprecate("if BLOCK BLOCK"); - $$ = newCONDOP(0, scope($2), scope($3), $4); } - | UNLESS block block else - { copline = $1; - deprecate("unless BLOCK BLOCK"); - $$ = newCONDOP(0, invert(scalar(scope($2))), - scope($3), $4); } + $$ = block_end($3, + newCONDOP(0, $4, scope($6), $7)); } ; cont : /* NULL */ @@ -176,43 +182,41 @@ cont : /* NULL */ { $$ = scope($2); } ; -loop : label WHILE '(' texpr ')' block cont - { copline = $2; - $$ = newSTATEOP(0, $1, - newWHILEOP(0, 1, (LOOP*)Nullop, - $4, $6, $7) ); } - | label UNTIL '(' expr ')' block cont - { copline = $2; - $$ = newSTATEOP(0, $1, - newWHILEOP(0, 1, (LOOP*)Nullop, - invert(scalar($4)), $6, $7) ); } - | label WHILE block block cont +loop : label WHILE '(' remember mtexpr ')' mblock cont { copline = $2; - $$ = newSTATEOP(0, $1, - newWHILEOP(0, 1, (LOOP*)Nullop, - scope($3), $4, $5) ); } - | label UNTIL block block cont + $$ = block_end($4, + newSTATEOP(0, $1, + newWHILEOP(0, 1, (LOOP*)Nullop, + $2, $5, $7, $8))); } + | label UNTIL '(' remember miexpr ')' mblock cont { copline = $2; - $$ = newSTATEOP(0, $1, - newWHILEOP(0, 1, (LOOP*)Nullop, - invert(scalar(scope($3))), $4, $5)); } - | label FOR scalar '(' expr ')' block cont - { $$ = newFOROP(0, $1, $2, mod($3, OP_ENTERLOOP), - $5, $7, $8); } - | label FOR '(' expr ')' block cont - { $$ = newFOROP(0, $1, $2, Nullop, $4, $6, $7); } - | label FOR '(' nexpr ';' texpr ';' nexpr ')' block + $$ = block_end($4, + newSTATEOP(0, $1, + newWHILEOP(0, 1, (LOOP*)Nullop, + $2, $5, $7, $8))); } + | label FOR MY remember my_scalar '(' mexpr ')' mblock cont + { $$ = block_end($4, + newFOROP(0, $1, $2, $5, $7, $9, $10)); } + | label FOR scalar '(' remember mexpr ')' mblock cont + { $$ = block_end($5, + newFOROP(0, $1, $2, mod($3, OP_ENTERLOOP), + $6, $8, $9)); } + | label FOR '(' remember mexpr ')' mblock cont + { $$ = block_end($4, + newFOROP(0, $1, $2, Nullop, $5, $7, $8)); } + | label FOR '(' remember mnexpr ';' mtexpr ';' mnexpr ')' mblock /* basically fake up an initialize-while lineseq */ - { copline = $2; - $$ = append_elem(OP_LINESEQ, - newSTATEOP(0, $1, scalar($4)), - newSTATEOP(0, $1, + { OP *forop = append_elem(OP_LINESEQ, + scalar($5), newWHILEOP(0, 1, (LOOP*)Nullop, - scalar($6), $10, scalar($8)) )); } + $2, scalar($7), + $11, scalar($9))); + copline = $2; + $$ = block_end($4, newSTATEOP(0, $1, forop)); } | label block cont /* a block is a loop that happens once */ - { $$ = newSTATEOP(0, - $1, newWHILEOP(0, 1, (LOOP*)Nullop, - Nullop, $2, $3)); } + { $$ = newSTATEOP(0, $1, + newWHILEOP(0, 1, (LOOP*)Nullop, + NOLINE, Nullop, $2, $3)); } ; nexpr : /* NULL */ @@ -225,6 +229,26 @@ texpr : /* NULL means true */ | expr ; +iexpr : expr + { $$ = invert(scalar($1)); } + ; + +mexpr : expr + { $$ = $1; intro_my(); } + ; + +mnexpr : nexpr + { $$ = $1; intro_my(); } + ; + +mtexpr : texpr + { $$ = $1; intro_my(); } + ; + +miexpr : iexpr + { $$ = $1; intro_my(); } + ; + label : /* empty */ { $$ = Nullch; } | LABEL @@ -240,25 +264,43 @@ decl : format { $$ = 0; } ; -format : FORMAT startsub WORD block +format : FORMAT startformsub formname block { newFORM($2, $3, $4); } - | FORMAT startsub block - { newFORM($2, Nullop, $3); } ; -subrout : SUB startsub WORD proto block +formname: WORD { $$ = $1; } + | /* NULL */ { $$ = Nullop; } + ; + +subrout : SUB startsub subname proto subbody { newSUB($2, $3, $4, $5); } - | SUB startsub WORD proto ';' - { newSUB($2, $3, $4, Nullop); expect = XSTATE; } + ; + +startsub: /* NULL */ /* start a regular subroutine scope */ + { $$ = start_subparse(FALSE, 0); } + ; + +startanonsub: /* NULL */ /* start an anonymous subroutine scope */ + { $$ = start_subparse(FALSE, CVf_ANON); } + ; + +startformsub: /* NULL */ /* start a format subroutine scope */ + { $$ = start_subparse(TRUE, 0); } + ; + +subname : WORD { char *name = SvPVx(((SVOP*)$1)->op_sv, na); + if (strEQ(name, "BEGIN") || strEQ(name, "END")) + CvUNIQUE_on(compcv); + $$ = $1; } ; proto : /* NULL */ { $$ = Nullop; } | THING ; - -startsub: /* NULL */ /* start a subroutine scope */ - { $$ = start_subparse(); } + +subbody : block { $$ = $1; } + | ';' { $$ = Nullop; expect = XSTATE; } ; package : PACKAGE WORD ';' @@ -267,8 +309,10 @@ package : PACKAGE WORD ';' { package(Nullop); } ; -use : USE startsub WORD listexpr ';' - { utilize($1, $2, $3, $4); } +use : USE startsub + { CvUNIQUE_on(compcv); /* It's a BEGIN {} */ } + WORD WORD listexpr ';' + { utilize($1, $2, $4, $5, $6); } ; expr : expr ANDOP expr @@ -294,7 +338,7 @@ listop : LSTOP indirob argexpr | term ARROW method '(' listexprcom ')' { $$ = convert(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, - prepend_elem(OP_LIST, $1, $5), + prepend_elem(OP_LIST, scalar($1), $5), newUNOP(OP_METHOD, 0, $3))); } | METHOD indirob listexpr { $$ = convert(OP_ENTERSUB, OPf_STACKED, @@ -310,11 +354,12 @@ listop : LSTOP indirob argexpr { $$ = convert($1, 0, $2); } | FUNC '(' listexprcom ')' { $$ = convert($1, 0, $3); } - | LSTOPSUB startsub block listexpr %prec LSTOP + | LSTOPSUB startanonsub block + { $3 = newANONSUB($2, 0, $3); } + listexpr %prec LSTOP { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, - append_elem(OP_LIST, - prepend_elem(OP_LIST, newANONSUB($2, 0, $3), $4), - $1)); } + append_elem(OP_LIST, + prepend_elem(OP_LIST, $3, $5), $1)); } ; method : METHOD @@ -374,7 +419,7 @@ term : term ASSIGNOP term | PREDEC term { $$ = newUNOP(OP_PREDEC, 0, mod(scalar($2), OP_PREDEC)); } - | LOCAL term %prec UNIOP + | local term %prec UNIOP { $$ = localize($2,$1); } | '(' expr ')' { $$ = sawparens($2); } @@ -388,7 +433,7 @@ term : term ASSIGNOP term { $$ = newANONHASH($2); } | HASHBRACK ';' '}' %prec '(' { $$ = newANONHASH(Nullop); } - | ANONSUB startsub proto block %prec '(' + | ANONSUB startanonsub proto block %prec '(' { $$ = newANONSUB($2, $3, $4); } | scalar %prec '(' { $$ = $1; } @@ -484,6 +529,13 @@ term : term ASSIGNOP term prepend_elem(OP_LIST, $4, scalar(newCVREF(0,scalar($2))))); dep();} + | term ARROW '(' ')' %prec '(' + { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, + newCVREF(0, scalar($1))); } + | term ARROW '(' expr ')' %prec '(' + { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, + append_elem(OP_LIST, $4, + newCVREF(0, scalar($1)))); } | LOOPEX { $$ = newOP($1, OPf_SPECIAL); hints |= HINT_BLOCK_SCOPE; } @@ -505,7 +557,7 @@ term : term ASSIGNOP term | FUNC0 '(' ')' { $$ = newOP($1, 0); } | FUNC0SUB - { $$ = newUNOP(OP_ENTERSUB, 0, + { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); } | FUNC1 '(' ')' { $$ = newOP($1, OPf_SPECIAL); } @@ -533,6 +585,14 @@ listexprcom: /* NULL */ { $$ = $1; } ; +local : LOCAL { $$ = 0; } + | MY { $$ = 1; } + ; + +my_scalar: scalar + { in_my = 0; $$ = my($1); } + ; + amper : '&' indirob { $$ = newCVREF($1,$2); } ; diff --git a/gnu/usr.bin/perl/pp.c b/gnu/usr.bin/perl/pp.c index 54433af2925..3513dda13d8 100644 --- a/gnu/usr.bin/perl/pp.c +++ b/gnu/usr.bin/perl/pp.c @@ -1,6 +1,6 @@ /* pp.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -15,16 +15,101 @@ #include "EXTERN.h" #include "perl.h" -static void doencodes _((SV *sv, char *s, I32 len)); +/* + * The compiler on Concurrent CX/UX systems has a subtle bug which only + * seems to show up when compiling pp.c - it generates the wrong double + * precision constant value for (double)UV_MAX when used inline in the body + * of the code below, so this makes a static variable up front (which the + * compiler seems to get correct) and uses it in place of UV_MAX below. + */ +#ifdef CXUX_BROKEN_CONSTANT_CONVERT +static double UV_MAX_cxux = ((double)UV_MAX); +#endif + +/* + * Types used in bitwise operations. + * + * Normally we'd just use IV and UV. However, some hardware and + * software combinations (e.g. Alpha and current OSF/1) don't have a + * floating-point type to use for NV that has adequate bits to fully + * hold an IV/UV. (In other words, sizeof(long) == sizeof(double).) + * + * It just so happens that "int" is the right size almost everywhere. + */ +typedef int IBW; +typedef unsigned UBW; + +/* + * Mask used after bitwise operations. + * + * There is at least one realm (Cray word machines) that doesn't + * have an integral type (except char) small enough to be represented + * in a double without loss; that is, it has no 32-bit type. + */ +#if BYTEORDER > 0xFFFF && defined(_CRAY) && !defined(_CRAYMPP) +# define BW_BITS 32 +# define BW_MASK ((1 << BW_BITS) - 1) +# define BW_SIGN (1 << (BW_BITS - 1)) +# define BWi(i) (((i) & BW_SIGN) ? ((i) | ~BW_MASK) : ((i) & BW_MASK)) +# define BWu(u) ((u) & BW_MASK) +#else +# define BWi(i) (i) +# define BWu(u) (u) +#endif + +/* + * Offset for integer pack/unpack. + * + * On architectures where I16 and I32 aren't really 16 and 32 bits, + * which for now are all Crays, pack and unpack have to play games. + */ + +/* + * These values are required for portability of pack() output. + * If they're not right on your machine, then pack() and unpack() + * wouldn't work right anyway; you'll need to apply the Cray hack. + * (I'd like to check them with #if, but you can't use sizeof() in + * the preprocessor.) + */ +#define SIZE16 2 +#define SIZE32 4 + +#if BYTEORDER > 0xFFFF && defined(_CRAY) && !defined(_CRAYMPP) +# if BYTEORDER == 0x12345678 +# define OFF16(p) (char*)(p) +# define OFF32(p) (char*)(p) +# else +# if BYTEORDER == 0x87654321 +# define OFF16(p) ((char*)(p) + (sizeof(U16) - SIZE16)) +# define OFF32(p) ((char*)(p) + (sizeof(U32) - SIZE32)) +# else + }}}} bad cray byte order +# endif +# endif +# define COPY16(s,p) (*(p) = 0, Copy(s, OFF16(p), SIZE16, char)) +# define COPY32(s,p) (*(p) = 0, Copy(s, OFF32(p), SIZE32, char)) +# define CAT16(sv,p) sv_catpvn(sv, OFF16(p), SIZE16) +# define CAT32(sv,p) sv_catpvn(sv, OFF32(p), SIZE32) +#else +# define COPY16(s,p) Copy(s, p, SIZE16, char) +# define COPY32(s,p) Copy(s, p, SIZE32, char) +# define CAT16(sv,p) sv_catpvn(sv, (char*)(p), SIZE16) +# define CAT32(sv,p) sv_catpvn(sv, (char*)(p), SIZE32) +#endif + +static void doencodes _((SV* sv, char* s, I32 len)); +static SV* refto _((SV* sv)); +static U32 seed _((void)); + +static bool srand_called = FALSE; /* variations on pp_null */ PP(pp_stub) { dSP; - if (GIMME != G_ARRAY) { + if (GIMME_V == G_SCALAR) XPUSHs(&sv_undef); - } RETURN; } @@ -63,25 +148,27 @@ PP(pp_padav) PP(pp_padhv) { dSP; dTARGET; + I32 gimme; + XPUSHs(TARG); if (op->op_private & OPpLVAL_INTRO) SAVECLEARSV(curpad[op->op_targ]); if (op->op_flags & OPf_REF) RETURN; - if (GIMME == G_ARRAY) { /* array wanted */ + gimme = GIMME_V; + if (gimme == G_ARRAY) { RETURNOP(do_kv(ARGS)); } - else { + else if (gimme == G_SCALAR) { SV* sv = sv_newmortal(); - if (HvFILL((HV*)TARG)) { - sprintf(buf, "%d/%d", HvFILL((HV*)TARG), HvMAX((HV*)TARG)+1); - sv_setpv(sv, buf); - } + if (HvFILL((HV*)TARG)) + sv_setpvf(sv, "%ld/%ld", + (long)HvFILL((HV*)TARG), (long)HvMAX((HV*)TARG) + 1); else sv_setiv(sv, 0); SETs(sv); - RETURN; } + RETURN; } PP(pp_padany) @@ -98,7 +185,13 @@ PP(pp_rv2gv) if (SvROK(sv)) { wasref: sv = SvRV(sv); - if (SvTYPE(sv) != SVt_PVGV) + if (SvTYPE(sv) == SVt_PVIO) { + GV *gv = (GV*) sv_newmortal(); + gv_init(gv, 0, "", 0, 0); + GvIOp(gv) = (IO *)sv; + (void)SvREFCNT_inc(sv); + sv = (SV*) gv; + } else if (SvTYPE(sv) != SVt_PVGV) DIE("Not a GLOB reference"); } else { @@ -114,6 +207,8 @@ PP(pp_rv2gv) if (op->op_flags & OPf_REF || op->op_private & HINT_STRICT_REFS) DIE(no_usym, "a symbol"); + if (dowarn) + warn(warn_uninit); RETSETUNDEF; } sym = SvPV(sv, na); @@ -122,28 +217,8 @@ PP(pp_rv2gv) sv = (SV*)gv_fetchpv(sym, TRUE, SVt_PVGV); } } - if (op->op_private & OPpLVAL_INTRO) { - GP *ogp = GvGP(sv); - - SSCHECK(3); - SSPUSHPTR(SvREFCNT_inc(sv)); - SSPUSHPTR(ogp); - SSPUSHINT(SAVEt_GP); - - if (op->op_flags & OPf_SPECIAL) { - GvGP(sv)->gp_refcnt++; /* will soon be assigned */ - GvINTRO_on(sv); - } - else { - GP *gp; - Newz(602,gp, 1, GP); - GvGP(sv) = gp; - GvREFCNT(sv) = 1; - GvSV(sv) = NEWSV(72,0); - GvLINE(sv) = curcop->cop_line; - GvEGV(sv) = sv; - } - } + if (op->op_private & OPpLVAL_INTRO) + save_gp((GV*)sv, !(op->op_flags & OPf_SPECIAL)); SETs(sv); RETURN; } @@ -163,7 +238,7 @@ PP(pp_rv2sv) } } else { - GV *gv = sv; + GV *gv = (GV*)sv; char *sym; if (SvTYPE(gv) != SVt_PVGV) { @@ -176,20 +251,22 @@ PP(pp_rv2sv) if (op->op_flags & OPf_REF || op->op_private & HINT_STRICT_REFS) DIE(no_usym, "a SCALAR"); + if (dowarn) + warn(warn_uninit); RETSETUNDEF; } sym = SvPV(sv, na); if (op->op_private & HINT_STRICT_REFS) DIE(no_symref, sym, "a SCALAR"); - gv = (SV*)gv_fetchpv(sym, TRUE, SVt_PV); + gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PV); } sv = GvSV(gv); } if (op->op_flags & OPf_MOD) { if (op->op_private & OPpLVAL_INTRO) sv = save_scalar((GV*)TOPs); - else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV)) - provide_ref(op, sv); + else if (op->op_private & OPpDEREF) + vivify_ref(sv, op->op_private & OPpDEREF); } SETs(sv); RETURN; @@ -214,7 +291,12 @@ PP(pp_pos) dSP; dTARGET; dPOPss; if (op->op_flags & OPf_MOD) { - LvTYPE(TARG) = '<'; + if (SvTYPE(TARG) < SVt_PVLV) { + sv_upgrade(TARG, SVt_PVLV); + sv_magic(TARG, Nullsv, '.', Nullch, 0); + } + + LvTYPE(TARG) = '.'; LvTARG(TARG) = sv; PUSHs(TARG); /* no SvSETMAGIC */ RETURN; @@ -242,8 +324,11 @@ PP(pp_rv2cv) /* We usually try to add a non-existent subroutine in case of AUTOLOAD. */ /* (But not in defined().) */ CV *cv = sv_2cv(TOPs, &stash, &gv, !(op->op_flags & OPf_SPECIAL)); - - if (!cv) + if (cv) { + if (CvCLONE(cv)) + cv = (CV*)sv_2mortal((SV*)cv_clone(cv)); + } + else cv = (CV*)&sv_undef; SETs((SV*)cv); RETURN; @@ -259,10 +344,8 @@ PP(pp_prototype) ret = &sv_undef; cv = sv_2cv(TOPs, &stash, &gv, FALSE); - if (cv && SvPOK(cv)) { - char *p = SvPVX(cv); - ret = sv_2mortal(newSVpv(p ? p : "", SvLEN(cv))); - } + if (cv && SvPOK(cv)) + ret = sv_2mortal(newSVpv(SvPVX(cv), SvCUR(cv))); SETs(ret); RETURN; } @@ -270,60 +353,59 @@ PP(pp_prototype) PP(pp_anoncode) { dSP; - CV* cv = (CV*)cSVOP->op_sv; - EXTEND(SP,1); - + CV* cv = (CV*)curpad[op->op_targ]; if (CvCLONE(cv)) cv = (CV*)sv_2mortal((SV*)cv_clone(cv)); - + EXTEND(SP,1); PUSHs((SV*)cv); RETURN; } PP(pp_srefgen) { - dSP; dTOPss; - SV* rv; - rv = sv_newmortal(); - sv_upgrade(rv, SVt_RV); - if (SvPADTMP(sv)) - sv = newSVsv(sv); - else { - SvTEMP_off(sv); - (void)SvREFCNT_inc(sv); - } - SvRV(rv) = sv; - SvROK_on(rv); - SETs(rv); + dSP; + *SP = refto(*SP); RETURN; } PP(pp_refgen) { dSP; dMARK; - SV* sv; - SV* rv; if (GIMME != G_ARRAY) { MARK[1] = *SP; SP = MARK + 1; } - while (MARK < SP) { - sv = *++MARK; - rv = sv_newmortal(); - sv_upgrade(rv, SVt_RV); - if (SvPADTMP(sv)) - sv = newSVsv(sv); - else { - SvTEMP_off(sv); - (void)SvREFCNT_inc(sv); - } - SvRV(rv) = sv; - SvROK_on(rv); - *MARK = rv; - } + EXTEND_MORTAL(SP - MARK); + while (++MARK <= SP) + *MARK = refto(*MARK); RETURN; } +static SV* +refto(sv) +SV* sv; +{ + SV* rv; + + if (SvTYPE(sv) == SVt_PVLV && LvTYPE(sv) == 'y') { + if (LvTARGLEN(sv)) + vivify_defelem(sv); + if (!(sv = LvTARG(sv))) + sv = &sv_undef; + } + else if (SvPADTMP(sv)) + sv = newSVsv(sv); + else { + SvTEMP_off(sv); + (void)SvREFCNT_inc(sv); + } + rv = sv_newmortal(); + sv_upgrade(rv, SVt_RV); + SvRV(rv) = sv; + SvROK_on(rv); + return rv; +} + PP(pp_ref) { dSP; dTARGET; @@ -331,6 +413,10 @@ PP(pp_ref) char *pv; sv = POPs; + + if (sv && SvGMAGICAL(sv)) + mg_get(sv); + if (!sv || !SvROK(sv)) RETPUSHNO; @@ -354,6 +440,68 @@ PP(pp_bless) RETURN; } +PP(pp_gelem) +{ + GV *gv; + SV *sv; + SV *ref; + char *elem; + dSP; + + sv = POPs; + elem = SvPV(sv, na); + gv = (GV*)POPs; + ref = Nullsv; + sv = Nullsv; + switch (elem ? *elem : '\0') + { + case 'A': + if (strEQ(elem, "ARRAY")) + ref = (SV*)GvAV(gv); + break; + case 'C': + if (strEQ(elem, "CODE")) + ref = (SV*)GvCVu(gv); + break; + case 'F': + if (strEQ(elem, "FILEHANDLE")) /* XXX deprecate in 5.005 */ + ref = (SV*)GvIOp(gv); + break; + case 'G': + if (strEQ(elem, "GLOB")) + ref = (SV*)gv; + break; + case 'H': + if (strEQ(elem, "HASH")) + ref = (SV*)GvHV(gv); + break; + case 'I': + if (strEQ(elem, "IO")) + ref = (SV*)GvIOp(gv); + break; + case 'N': + if (strEQ(elem, "NAME")) + sv = newSVpv(GvNAME(gv), GvNAMELEN(gv)); + break; + case 'P': + if (strEQ(elem, "PACKAGE")) + sv = newSVpv(HvNAME(GvSTASH(gv)), 0); + break; + case 'S': + if (strEQ(elem, "SCALAR")) + ref = GvSV(gv); + break; + } + if (ref) + sv = newRV(ref); + if (sv) + sv_2mortal(sv); + else + sv = &sv_undef; + XPUSHs(sv); + RETURN; +} + /* Pattern matching */ PP(pp_study) @@ -364,13 +512,12 @@ PP(pp_study) register I32 ch; register I32 *sfirst; register I32 *snext; - I32 retval; STRLEN len; - s = (unsigned char*)(SvPV(sv, len)); - pos = len; - if (sv == lastscream) - SvSCREAM_off(sv); + if (sv == lastscream) { + if (SvSCREAM(sv)) + RETPUSHYES; + } else { if (lastscream) { SvSCREAM_off(lastscream); @@ -378,10 +525,11 @@ PP(pp_study) } lastscream = SvREFCNT_inc(sv); } - if (pos <= 0) { - retval = 0; - goto ret; - } + + s = (unsigned char*)(SvPV(sv, len)); + pos = len; + if (pos <= 0) + RETPUSHNO; if (pos > maxscream) { if (maxscream < 0) { maxscream = pos + 80; @@ -411,21 +559,11 @@ PP(pp_study) else snext[pos] = -pos; sfirst[ch] = pos; - - /* If there were any case insensitive searches, we must assume they - * all are. This speeds up insensitive searches much more than - * it slows down sensitive ones. - */ - if (sawi) - sfirst[fold[ch]] = pos; } SvSCREAM_on(sv); sv_magic(sv, Nullsv, 'g', Nullch, 0); /* piggyback on m//g magic */ - retval = 1; - ret: - XPUSHs(sv_2mortal(newSViv((I32)retval))); - RETURN; + RETPUSHYES; } PP(pp_trans) @@ -491,11 +629,11 @@ PP(pp_defined) RETPUSHNO; switch (SvTYPE(sv)) { case SVt_PVAV: - if (AvMAX(sv) >= 0 || SvRMAGICAL(sv)) + if (AvMAX(sv) >= 0 || SvGMAGICAL(sv)) RETPUSHYES; break; case SVt_PVHV: - if (HvARRAY(sv) || SvRMAGICAL(sv)) + if (HvARRAY(sv) || SvGMAGICAL(sv)) RETPUSHYES; break; case SVt_PVCV: @@ -516,8 +654,10 @@ PP(pp_undef) dSP; SV *sv; - if (!op->op_private) + if (!op->op_private) { + EXTEND(SP, 1); RETPUSHUNDEF; + } sv = POPs; if (!sv) @@ -540,16 +680,21 @@ PP(pp_undef) hv_undef((HV*)sv); break; case SVt_PVCV: - cv_undef((CV*)sv); - sub_generation++; + if (cv_const_sv((CV*)sv)) + warn("Constant subroutine %s undefined", + CvANON((CV*)sv) ? "(anonymous)" : GvENAME(CvGV((CV*)sv))); + /* FALL THROUGH */ + case SVt_PVFM: + { GV* gv = (GV*)SvREFCNT_inc(CvGV((CV*)sv)); + cv_undef((CV*)sv); + CvGV((CV*)sv) = gv; } /* let user-undef'd sub keep its identity */ break; case SVt_PVGV: - if (SvFAKE(sv)) { - sv_setsv(sv, &sv_undef); - break; - } + if (SvFAKE(sv)) + sv_setsv(sv, &sv_undef); + break; default: - if (SvPOK(sv) && SvLEN(sv)) { + if (SvTYPE(sv) >= SVt_PV && SvPVX(sv) && SvLEN(sv)) { (void)SvOOK_off(sv); Safefree(SvPVX(sv)); SvPV_set(sv, Nullch); @@ -565,9 +710,13 @@ PP(pp_undef) PP(pp_predec) { dSP; - if (SvIOK(TOPs)) { + if (SvREADONLY(TOPs) || SvTYPE(TOPs) > SVt_PVLV) + croak(no_modify); + if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) && + SvIVX(TOPs) != IV_MIN) + { --SvIVX(TOPs); - SvFLAGS(TOPs) &= ~(SVf_NOK|SVf_POK|SVp_NOK|SVp_POK); + SvFLAGS(TOPs) &= ~(SVp_NOK|SVp_POK); } else sv_dec(TOPs); @@ -578,10 +727,14 @@ PP(pp_predec) PP(pp_postinc) { dSP; dTARGET; + if (SvREADONLY(TOPs) || SvTYPE(TOPs) > SVt_PVLV) + croak(no_modify); sv_setsv(TARG, TOPs); - if (SvIOK(TOPs)) { + if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) && + SvIVX(TOPs) != IV_MAX) + { ++SvIVX(TOPs); - SvFLAGS(TOPs) &= ~(SVf_NOK|SVf_POK|SVp_NOK|SVp_POK); + SvFLAGS(TOPs) &= ~(SVp_NOK|SVp_POK); } else sv_inc(TOPs); @@ -595,10 +748,14 @@ PP(pp_postinc) PP(pp_postdec) { dSP; dTARGET; + if(SvREADONLY(TOPs) || SvTYPE(TOPs) > SVt_PVLV) + croak(no_modify); sv_setsv(TARG, TOPs); - if (SvIOK(TOPs)) { + if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) && + SvIVX(TOPs) != IV_MIN) + { --SvIVX(TOPs); - SvFLAGS(TOPs) &= ~(SVf_NOK|SVf_POK|SVp_NOK|SVp_POK); + SvFLAGS(TOPs) &= ~(SVp_NOK|SVp_POK); } else sv_dec(TOPs); @@ -633,25 +790,24 @@ PP(pp_divide) { dSP; dATARGET; tryAMAGICbin(div,opASSIGN); { - dPOPnv; - if (value == 0.0) + dPOPPOPnnrl; + double value; + if (right == 0.0) DIE("Illegal division by zero"); #ifdef SLOPPYDIVIDE /* insure that 20./5. == 4. */ { - double x; - I32 k; - x = POPn; - if ((double)I_32(x) == x && - (double)I_32(value) == value && - (k = I_32(x)/I_32(value))*I_32(value) == I_32(x)) { + IV k; + if ((double)I_V(left) == left && + (double)I_V(right) == right && + (k = I_V(left)/I_V(right))*I_V(right) == I_V(left)) { value = k; } else { - value = x/value; + value = left / right; } } #else - value = POPn / value; + value = left / right; #endif PUSHn( value ); RETURN; @@ -662,21 +818,47 @@ PP(pp_modulo) { dSP; dATARGET; tryAMAGICbin(mod,opASSIGN); { - register unsigned long tmpulong; - register long tmplong; - I32 value; + UV left; + UV right; + bool left_neg; + bool right_neg; + UV ans; + + if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)) { + IV i = SvIVX(POPs); + right = (right_neg = (i < 0)) ? -i : i; + } + else { + double n = POPn; + right = U_V((right_neg = (n < 0)) ? -n : n); + } - tmpulong = (unsigned long) POPn; - if (tmpulong == 0L) - DIE("Illegal modulus zero"); - value = TOPn; - if (value >= 0.0) - value = (I32)(((unsigned long)value) % tmpulong); + if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs)) { + IV i = SvIVX(POPs); + left = (left_neg = (i < 0)) ? -i : i; + } else { - tmplong = (long)value; - value = (I32)(tmpulong - ((-tmplong - 1) % tmpulong)) - 1; + double n = POPn; + left = U_V((left_neg = (n < 0)) ? -n : n); } - SETi(value); + + if (!right) + DIE("Illegal modulus zero"); + + ans = left % right; + if ((left_neg != right_neg) && ans) + ans = right - ans; + if (right_neg) { + /* XXX may warn: unary minus operator applied to unsigned type */ + /* could change -foo to be (~foo)+1 instead */ + if (ans <= -(UV)IV_MAX) + sv_setiv(TARG, (IV) -ans); + else + sv_setnv(TARG, -(double)ans); + } + else + sv_setuv(TARG, ans); + PUSHTARG; RETURN; } } @@ -720,16 +902,17 @@ PP(pp_repeat) } SvSetSV(TARG, tmpstr); SvPV_force(TARG, len); - if (count >= 1) { - SvGROW(TARG, (count * len) + 1); - if (count > 1) + if (count != 1) { + if (count < 1) + SvCUR_set(TARG, 0); + else { + SvGROW(TARG, (count * len) + 1); repeatcpy(SvPVX(TARG) + len, SvPVX(TARG), len, count - 1); - SvCUR(TARG) *= count; + SvCUR(TARG) *= count; + } *SvEND(TARG) = '\0'; - (void)SvPOK_only(TARG); } - else - sv_setsv(TARG, &sv_no); + (void)SvPOK_only(TARG); PUSHTARG; } RETURN; @@ -740,7 +923,7 @@ PP(pp_subtract) { dSP; dATARGET; tryAMAGICbin(subtr,opASSIGN); { - dPOPTOPnnrl; + dPOPTOPnnrl_ul; SETn( left - right ); RETURN; } @@ -750,9 +933,18 @@ PP(pp_left_shift) { dSP; dATARGET; tryAMAGICbin(lshift,opASSIGN); { - dPOPTOPiirl; - SETi( left << right ); - RETURN; + IBW shift = POPi; + if (op->op_private & HINT_INTEGER) { + IBW i = TOPi; + i = BWi(i) << shift; + SETi(BWi(i)); + } + else { + UBW u = TOPu; + u <<= shift; + SETu(BWu(u)); + } + RETURN; } } @@ -760,8 +952,17 @@ PP(pp_right_shift) { dSP; dATARGET; tryAMAGICbin(rshift,opASSIGN); { - dPOPTOPiirl; - SETi( left >> right ); + IBW shift = POPi; + if (op->op_private & HINT_INTEGER) { + IBW i = TOPi; + i = BWi(i) >> shift; + SETi(BWi(i)); + } + else { + UBW u = TOPu; + u >>= shift; + SETu(BWu(u)); + } RETURN; } } @@ -771,7 +972,7 @@ PP(pp_lt) dSP; tryAMAGICbinSET(lt,0); { dPOPnv; - SETs((TOPn < value) ? &sv_yes : &sv_no); + SETs(boolSV(TOPn < value)); RETURN; } } @@ -781,7 +982,7 @@ PP(pp_gt) dSP; tryAMAGICbinSET(gt,0); { dPOPnv; - SETs((TOPn > value) ? &sv_yes : &sv_no); + SETs(boolSV(TOPn > value)); RETURN; } } @@ -791,7 +992,7 @@ PP(pp_le) dSP; tryAMAGICbinSET(le,0); { dPOPnv; - SETs((TOPn <= value) ? &sv_yes : &sv_no); + SETs(boolSV(TOPn <= value)); RETURN; } } @@ -801,7 +1002,7 @@ PP(pp_ge) dSP; tryAMAGICbinSET(ge,0); { dPOPnv; - SETs((TOPn >= value) ? &sv_yes : &sv_no); + SETs(boolSV(TOPn >= value)); RETURN; } } @@ -811,7 +1012,7 @@ PP(pp_ne) dSP; tryAMAGICbinSET(ne,0); { dPOPnv; - SETs((TOPn != value) ? &sv_yes : &sv_no); + SETs(boolSV(TOPn != value)); RETURN; } } @@ -823,12 +1024,16 @@ PP(pp_ncmp) dPOPTOPnnrl; I32 value; - if (left > right) - value = 1; + if (left == right) + value = 0; else if (left < right) value = -1; - else - value = 0; + else if (left > right) + value = 1; + else { + SETs(&sv_undef); + RETURN; + } SETi(value); RETURN; } @@ -839,7 +1044,10 @@ PP(pp_slt) dSP; tryAMAGICbinSET(slt,0); { dPOPTOPssrl; - SETs( sv_cmp(left, right) < 0 ? &sv_yes : &sv_no ); + int cmp = ((op->op_private & OPpLOCALE) + ? sv_cmp_locale(left, right) + : sv_cmp(left, right)); + SETs(boolSV(cmp < 0)); RETURN; } } @@ -849,7 +1057,10 @@ PP(pp_sgt) dSP; tryAMAGICbinSET(sgt,0); { dPOPTOPssrl; - SETs( sv_cmp(left, right) > 0 ? &sv_yes : &sv_no ); + int cmp = ((op->op_private & OPpLOCALE) + ? sv_cmp_locale(left, right) + : sv_cmp(left, right)); + SETs(boolSV(cmp > 0)); RETURN; } } @@ -859,7 +1070,10 @@ PP(pp_sle) dSP; tryAMAGICbinSET(sle,0); { dPOPTOPssrl; - SETs( sv_cmp(left, right) <= 0 ? &sv_yes : &sv_no ); + int cmp = ((op->op_private & OPpLOCALE) + ? sv_cmp_locale(left, right) + : sv_cmp(left, right)); + SETs(boolSV(cmp <= 0)); RETURN; } } @@ -869,7 +1083,20 @@ PP(pp_sge) dSP; tryAMAGICbinSET(sge,0); { dPOPTOPssrl; - SETs( sv_cmp(left, right) >= 0 ? &sv_yes : &sv_no ); + int cmp = ((op->op_private & OPpLOCALE) + ? sv_cmp_locale(left, right) + : sv_cmp(left, right)); + SETs(boolSV(cmp >= 0)); + RETURN; + } +} + +PP(pp_seq) +{ + dSP; tryAMAGICbinSET(seq,0); + { + dPOPTOPssrl; + SETs(boolSV(sv_eq(left, right))); RETURN; } } @@ -879,7 +1106,7 @@ PP(pp_sne) dSP; tryAMAGICbinSET(sne,0); { dPOPTOPssrl; - SETs( !sv_eq(left, right) ? &sv_yes : &sv_no ); + SETs(boolSV(!sv_eq(left, right))); RETURN; } } @@ -889,19 +1116,28 @@ PP(pp_scmp) dSP; dTARGET; tryAMAGICbin(scmp,0); { dPOPTOPssrl; - SETi( sv_cmp(left, right) ); + int cmp = ((op->op_private & OPpLOCALE) + ? sv_cmp_locale(left, right) + : sv_cmp(left, right)); + SETi( cmp ); RETURN; } } -PP(pp_bit_and) { +PP(pp_bit_and) +{ dSP; dATARGET; tryAMAGICbin(band,opASSIGN); { dPOPTOPssrl; if (SvNIOKp(left) || SvNIOKp(right)) { - unsigned long value = U_L(SvNV(left)); - value = value & U_L(SvNV(right)); - SETn((double)value); + if (op->op_private & HINT_INTEGER) { + IBW value = SvIV(left) & SvIV(right); + SETi(BWi(value)); + } + else { + UBW value = SvUV(left) & SvUV(right); + SETu(BWu(value)); + } } else { do_vop(op->op_type, TARG, left, right); @@ -917,9 +1153,14 @@ PP(pp_bit_xor) { dPOPTOPssrl; if (SvNIOKp(left) || SvNIOKp(right)) { - unsigned long value = U_L(SvNV(left)); - value = value ^ U_L(SvNV(right)); - SETn((double)value); + if (op->op_private & HINT_INTEGER) { + IBW value = (USE_LEFT(left) ? SvIV(left) : 0) ^ SvIV(right); + SETi(BWi(value)); + } + else { + UBW value = (USE_LEFT(left) ? SvUV(left) : 0) ^ SvUV(right); + SETu(BWu(value)); + } } else { do_vop(op->op_type, TARG, left, right); @@ -935,9 +1176,14 @@ PP(pp_bit_or) { dPOPTOPssrl; if (SvNIOKp(left) || SvNIOKp(right)) { - unsigned long value = U_L(SvNV(left)); - value = value | U_L(SvNV(right)); - SETn((double)value); + if (op->op_private & HINT_INTEGER) { + IBW value = (USE_LEFT(left) ? SvIV(left) : 0) | SvIV(right); + SETi(BWi(value)); + } + else { + UBW value = (USE_LEFT(left) ? SvUV(left) : 0) | SvUV(right); + SETu(BWu(value)); + } } else { do_vop(op->op_type, TARG, left, right); @@ -954,12 +1200,14 @@ PP(pp_negate) dTOPss; if (SvGMAGICAL(sv)) mg_get(sv); - if (SvNIOKp(sv)) + if (SvIOKp(sv) && !SvNOKp(sv) && !SvPOKp(sv) && SvIVX(sv) != IV_MIN) + SETi(-SvIVX(sv)); + else if (SvNIOKp(sv)) SETn(-SvNV(sv)); else if (SvPOKp(sv)) { STRLEN len; char *s = SvPV(sv, len); - if (isALPHA(*s) || *s == '_') { + if (isIDFIRST(*s)) { sv_setpvn(TARG, "-", 1); sv_catsv(TARG, sv); } @@ -982,7 +1230,7 @@ PP(pp_not) #ifdef OVERLOAD dSP; tryAMAGICunSET(not); #endif /* OVERLOAD */ - *stack_sp = SvTRUE(*stack_sp) ? &sv_no : &sv_yes; + *stack_sp = boolSV(!SvTRUE(*stack_sp)); return NORMAL; } @@ -991,18 +1239,20 @@ PP(pp_complement) dSP; dTARGET; tryAMAGICun(compl); { dTOPss; - register I32 anum; - if (SvNIOKp(sv)) { - IV iv = ~SvIV(sv); - if (iv < 0) - SETn( (double) ~U_L(SvNV(sv)) ); - else - SETi( iv ); + if (op->op_private & HINT_INTEGER) { + IBW value = ~SvIV(sv); + SETi(BWi(value)); + } + else { + UBW value = ~SvUV(sv); + SETu(BWu(value)); + } } else { register char *tmps; register long *tmpl; + register I32 anum; STRLEN len; SvSetSV(TARG, sv); @@ -1055,6 +1305,8 @@ PP(pp_i_modulo) dSP; dATARGET; tryAMAGICbin(mod,opASSIGN); { dPOPTOPiirl; + if (!right) + DIE("Illegal modulus zero"); SETi( left % right ); RETURN; } @@ -1085,7 +1337,7 @@ PP(pp_i_lt) dSP; tryAMAGICbinSET(lt,0); { dPOPTOPiirl; - SETs((left < right) ? &sv_yes : &sv_no); + SETs(boolSV(left < right)); RETURN; } } @@ -1095,7 +1347,7 @@ PP(pp_i_gt) dSP; tryAMAGICbinSET(gt,0); { dPOPTOPiirl; - SETs((left > right) ? &sv_yes : &sv_no); + SETs(boolSV(left > right)); RETURN; } } @@ -1105,7 +1357,7 @@ PP(pp_i_le) dSP; tryAMAGICbinSET(le,0); { dPOPTOPiirl; - SETs((left <= right) ? &sv_yes : &sv_no); + SETs(boolSV(left <= right)); RETURN; } } @@ -1115,7 +1367,7 @@ PP(pp_i_ge) dSP; tryAMAGICbinSET(ge,0); { dPOPTOPiirl; - SETs((left >= right) ? &sv_yes : &sv_no); + SETs(boolSV(left >= right)); RETURN; } } @@ -1125,7 +1377,7 @@ PP(pp_i_eq) dSP; tryAMAGICbinSET(eq,0); { dPOPTOPiirl; - SETs((left == right) ? &sv_yes : &sv_no); + SETs(boolSV(left == right)); RETURN; } } @@ -1135,7 +1387,7 @@ PP(pp_i_ne) dSP; tryAMAGICbinSET(ne,0); { dPOPTOPiirl; - SETs((left != right) ? &sv_yes : &sv_no); + SETs(boolSV(left != right)); RETURN; } } @@ -1211,6 +1463,10 @@ PP(pp_rand) value = POPn; if (value == 0.0) value = 1.0; + if (!srand_called) { + (void)srand((unsigned)seed()); + srand_called = TRUE; + } #if RANDBITS == 31 value = rand() * value / 2147483648.0; #else @@ -1231,20 +1487,69 @@ PP(pp_rand) PP(pp_srand) { dSP; - I32 anum; - Time_t when; - - if (MAXARG < 1) { - (void)time(&when); - anum = when; - } + UV anum; + if (MAXARG < 1) + anum = seed(); else - anum = POPi; - (void)srand(anum); + anum = POPu; + (void)srand((unsigned)anum); + srand_called = TRUE; EXTEND(SP, 1); RETPUSHYES; } +static U32 +seed() +{ + /* + * This is really just a quick hack which grabs various garbage + * values. It really should be a real hash algorithm which + * spreads the effect of every input bit onto every output bit, + * if someone who knows about such tings would bother to write it. + * Might be a good idea to add that function to CORE as well. + * No numbers below come from careful analysis or anyting here, + * except they are primes and SEED_C1 > 1E6 to get a full-width + * value from (tv_sec * SEED_C1 + tv_usec). The multipliers should + * probably be bigger too. + */ +#if RANDBITS > 16 +# define SEED_C1 1000003 +#define SEED_C4 73819 +#else +# define SEED_C1 25747 +#define SEED_C4 20639 +#endif +#define SEED_C2 3 +#define SEED_C3 269 +#define SEED_C5 26107 + + U32 u; +#ifdef VMS +# include <starlet.h> + /* when[] = (low 32 bits, high 32 bits) of time since epoch + * in 100-ns units, typically incremented ever 10 ms. */ + unsigned int when[2]; + _ckvmssts(sys$gettim(when)); + u = (U32)SEED_C1 * when[0] + (U32)SEED_C2 * when[1]; +#else +# ifdef HAS_GETTIMEOFDAY + struct timeval when; + gettimeofday(&when,(struct timezone *) 0); + u = (U32)SEED_C1 * when.tv_sec + (U32)SEED_C2 * when.tv_usec; +# else + Time_t when; + (void)time(&when); + u = (U32)SEED_C1 * when; +# endif +#endif + u += SEED_C3 * (U32)getpid(); + u += SEED_C4 * (U32)(UV)stack_sp; +#ifndef PLAN9 /* XXX Plan9 assembler chokes on this; fix needed */ + u += SEED_C5 * (U32)(UV)&when; +#endif + return u; +} + PP(pp_exp) { dSP; dTARGET; tryAMAGICun(exp); @@ -1263,8 +1568,10 @@ PP(pp_log) { double value; value = POPn; - if (value <= 0.0) + if (value <= 0.0) { + SET_NUMERIC_STANDARD(); DIE("Can't take log of %g", value); + } value = log(value); XPUSHn(value); RETURN; @@ -1277,8 +1584,10 @@ PP(pp_sqrt) { double value; value = POPn; - if (value < 0.0) + if (value < 0.0) { + SET_NUMERIC_STANDARD(); DIE("Can't take sqrt of %g", value); + } value = sqrt(value); XPUSHn(value); RETURN; @@ -1288,15 +1597,28 @@ PP(pp_sqrt) PP(pp_int) { dSP; dTARGET; - double value; - value = POPn; - if (value >= 0.0) - (void)modf(value, &value); - else { - (void)modf(-value, &value); - value = -value; + { + double value = TOPn; + IV iv; + + if (SvIOKp(TOPs) && !SvNOKp(TOPs) && !SvPOKp(TOPs)) { + iv = SvIVX(TOPs); + SETi(iv); + } + else { + if (value >= 0.0) + (void)modf(value, &value); + else { + (void)modf(-value, &value); + value = -value; + } + iv = I_V(value); + if (iv == value) + SETi(iv); + else + SETn(value); + } } - XPUSHn(value); RETURN; } @@ -1304,37 +1626,39 @@ PP(pp_abs) { dSP; dTARGET; tryAMAGICun(abs); { - double value; - value = POPn; - - if (value < 0.0) - value = -value; + double value = TOPn; + IV iv; - XPUSHn(value); - RETURN; + if (SvIOKp(TOPs) && !SvNOKp(TOPs) && !SvPOKp(TOPs) && + (iv = SvIVX(TOPs)) != IV_MIN) { + if (iv < 0) + iv = -iv; + SETi(iv); + } + else { + if (value < 0.0) + value = -value; + SETn(value); + } } + RETURN; } PP(pp_hex) { dSP; dTARGET; char *tmps; - unsigned long value; I32 argtype; tmps = POPp; - value = scan_hex(tmps, 99, &argtype); - if ((IV)value >= 0) - XPUSHi(value); - else - XPUSHn(U_V(value)); + XPUSHu(scan_hex(tmps, 99, &argtype)); RETURN; } PP(pp_oct) { dSP; dTARGET; - unsigned long value; + UV value; I32 argtype; char *tmps; @@ -1347,10 +1671,7 @@ PP(pp_oct) value = scan_hex(++tmps, 99, &argtype); else value = scan_oct(tmps, 99, &argtype); - if ((IV)value >= 0) - XPUSHi(value); - else - XPUSHn(U_V(value)); + XPUSHu(value); RETURN; } @@ -1371,44 +1692,76 @@ PP(pp_substr) STRLEN curlen; I32 pos; I32 rem; + I32 fail; I32 lvalue = op->op_flags & OPf_MOD; char *tmps; I32 arybase = curcop->cop_arybase; if (MAXARG > 2) len = POPi; - pos = POPi - arybase; + pos = POPi; sv = POPs; tmps = SvPV(sv, curlen); - if (pos < 0) - pos += curlen + arybase; - if (pos < 0 || pos > curlen) { - if (dowarn || lvalue) + if (pos >= arybase) { + pos -= arybase; + rem = curlen-pos; + fail = rem; + if (MAXARG > 2) { + if (len < 0) { + rem += len; + if (rem < 0) + rem = 0; + } + else if (rem > len) + rem = len; + } + } + else { + pos += curlen; + if (MAXARG < 3) + rem = curlen; + else if (len >= 0) { + rem = pos+len; + if (rem > (I32)curlen) + rem = curlen; + } + else { + rem = curlen+len; + if (rem < pos) + rem = pos; + } + if (pos < 0) + pos = 0; + fail = rem; + rem -= pos; + } + if (fail < 0) { + if (dowarn || lvalue) warn("substr outside of string"); RETPUSHUNDEF; } else { - if (MAXARG < 3) - len = curlen; - else if (len < 0) { - len += curlen - pos; - if (len < 0) - len = 0; - } tmps += pos; - rem = curlen - pos; /* rem=how many bytes left*/ - if (rem > len) - rem = len; sv_setpvn(TARG, tmps, rem); if (lvalue) { /* it's an lvalue! */ - if (!SvGMAGICAL(sv)) - (void)SvPOK_only(sv); + if (!SvGMAGICAL(sv)) { + if (SvROK(sv)) { + SvPV_force(sv,na); + if (dowarn) + warn("Attempt to use reference as lvalue in substr"); + } + if (SvOK(sv)) /* is it defined ? */ + (void)SvPOK_only(sv); + else + sv_setpvn(sv,"",0); /* avoid lexical reincarnation */ + } + if (SvTYPE(TARG) < SVt_PVLV) { sv_upgrade(TARG, SVt_PVLV); sv_magic(TARG, Nullsv, 'x', Nullch, 0); } - LvTYPE(TARG) = 's'; + LvTYPE(TARG) = 'x'; LvTARG(TARG) = sv; LvTARGOFF(TARG) = pos; LvTARGLEN(TARG) = rem; @@ -1487,7 +1840,7 @@ PP(pp_vec) } } - sv_setiv(TARG, (I32)retnum); + sv_setiv(TARG, (IV)retnum); PUSHs(TARG); RETURN; } @@ -1564,7 +1917,14 @@ PP(pp_rindex) PP(pp_sprintf) { dSP; dMARK; dORIGMARK; dTARGET; +#ifdef USE_LOCALE_NUMERIC + if (op->op_private & OPpLOCALE) + SET_NUMERIC_LOCAL(); + else + SET_NUMERIC_STANDARD(); +#endif do_sprintf(TARG, SP-MARK, MARK+1); + TAINT_IF(SvTAINTED(TARG)); SP = ORIGMARK; PUSHTARG; RETURN; @@ -1636,8 +1996,15 @@ PP(pp_ucfirst) SETs(sv); } s = SvPV_force(sv, na); - if (isLOWER(*s)) - *s = toUPPER(*s); + if (*s) { + if (op->op_private & OPpLOCALE) { + TAINT; + SvTAINTED_on(sv); + *s = toUPPER_LC(*s); + } + else + *s = toUPPER(*s); + } RETURN; } @@ -1655,8 +2022,15 @@ PP(pp_lcfirst) SETs(sv); } s = SvPV_force(sv, na); - if (isUPPER(*s)) - *s = toLOWER(*s); + if (*s) { + if (op->op_private & OPpLOCALE) { + TAINT; + SvTAINTED_on(sv); + *s = toLOWER_LC(*s); + } + else + *s = toLOWER(*s); + } SETs(sv); RETURN; @@ -1667,7 +2041,6 @@ PP(pp_uc) dSP; SV *sv = TOPs; register char *s; - register char *send; STRLEN len; if (!SvPADTMP(sv)) { @@ -1676,12 +2049,21 @@ PP(pp_uc) sv = TARG; SETs(sv); } + s = SvPV_force(sv, len); - send = s + len; - while (s < send) { - if (isLOWER(*s)) - *s = toUPPER(*s); - s++; + if (len) { + register char *send = s + len; + + if (op->op_private & OPpLOCALE) { + TAINT; + SvTAINTED_on(sv); + for (; s < send; s++) + *s = toUPPER_LC(*s); + } + else { + for (; s < send; s++) + *s = toUPPER(*s); + } } RETURN; } @@ -1691,7 +2073,6 @@ PP(pp_lc) dSP; SV *sv = TOPs; register char *s; - register char *send; STRLEN len; if (!SvPADTMP(sv)) { @@ -1700,12 +2081,21 @@ PP(pp_lc) sv = TARG; SETs(sv); } + s = SvPV_force(sv, len); - send = s + len; - while (s < send) { - if (isUPPER(*s)) - *s = toLOWER(*s); - s++; + if (len) { + register char *send = s + len; + + if (op->op_private & OPpLOCALE) { + TAINT; + SvTAINTED_on(sv); + for (; s < send; s++) + *s = toLOWER_LC(*s); + } + else { + for (; s < send; s++) + *s = toLOWER(*s); + } } RETURN; } @@ -1789,27 +2179,23 @@ PP(pp_each) dSP; dTARGET; HV *hash = (HV*)POPs; HE *entry; - I32 i; - char *tmps; + I32 gimme = GIMME_V; PUTBACK; - entry = hv_iternext(hash); /* might clobber stack_sp */ + entry = hv_iternext(hash); /* might clobber stack_sp */ SPAGAIN; EXTEND(SP, 2); if (entry) { - tmps = hv_iterkey(entry, &i); /* won't clobber stack_sp */ - if (!i) - tmps = ""; - PUSHs(sv_2mortal(newSVpv(tmps, i))); - if (GIMME == G_ARRAY) { + PUSHs(hv_iterkeysv(entry)); /* won't clobber stack_sp */ + if (gimme == G_ARRAY) { PUTBACK; - sv_setsv(TARG, hv_iterval(hash, entry)); /* might clobber stack_sp */ + sv_setsv(TARG, hv_iterval(hash, entry)); /* might hit stack_sp */ SPAGAIN; PUSHs(TARG); } } - else if (GIMME == G_SCALAR) + else if (gimme == G_SCALAR) RETPUSHUNDEF; RETURN; @@ -1828,20 +2214,39 @@ PP(pp_keys) PP(pp_delete) { dSP; + I32 gimme = GIMME_V; + I32 discard = (gimme == G_VOID) ? G_DISCARD : 0; SV *sv; - SV *tmpsv = POPs; - HV *hv = (HV*)POPs; - char *tmps; - STRLEN len; - if (SvTYPE(hv) != SVt_PVHV) { - DIE("Not a HASH reference"); + HV *hv; + + if (op->op_private & OPpSLICE) { + dMARK; dORIGMARK; + hv = (HV*)POPs; + if (SvTYPE(hv) != SVt_PVHV) + DIE("Not a HASH reference"); + while (++MARK <= SP) { + sv = hv_delete_ent(hv, *MARK, discard, 0); + *MARK = sv ? sv : &sv_undef; + } + if (discard) + SP = ORIGMARK; + else if (gimme == G_SCALAR) { + MARK = ORIGMARK; + *++MARK = *SP; + SP = MARK; + } + } + else { + SV *keysv = POPs; + hv = (HV*)POPs; + if (SvTYPE(hv) != SVt_PVHV) + DIE("Not a HASH reference"); + sv = hv_delete_ent(hv, keysv, discard, 0); + if (!sv) + sv = &sv_undef; + if (!discard) + PUSHs(sv); } - tmps = SvPV(tmpsv, len); - sv = hv_delete(hv, tmps, len, - op->op_private & OPpLEAVE_VOID ? G_DISCARD : 0); - if (!sv) - RETPUSHUNDEF; - PUSHs(sv); RETURN; } @@ -1850,13 +2255,11 @@ PP(pp_exists) dSP; SV *tmpsv = POPs; HV *hv = (HV*)POPs; - char *tmps; STRLEN len; if (SvTYPE(hv) != SVt_PVHV) { DIE("Not a HASH reference"); } - tmps = SvPV(tmpsv, len); - if (hv_exists(hv, tmps, len)) + if (hv_exists_ent(hv, tmpsv, 0)) RETPUSHYES; RETPUSHNO; } @@ -1864,23 +2267,22 @@ PP(pp_exists) PP(pp_hslice) { dSP; dMARK; dORIGMARK; - register SV **svp; + register HE *he; register HV *hv = (HV*)POPs; register I32 lval = op->op_flags & OPf_MOD; if (SvTYPE(hv) == SVt_PVHV) { while (++MARK <= SP) { - STRLEN keylen; - char *key = SvPV(*MARK, keylen); + SV *keysv = *MARK; - svp = hv_fetch(hv, key, keylen, lval); + he = hv_fetch_ent(hv, keysv, lval, 0); if (lval) { - if (!svp || *svp == &sv_undef) - DIE(no_helem, key); + if (!he || HeVAL(he) == &sv_undef) + DIE(no_helem, SvPV(keysv, na)); if (op->op_private & OPpLVAL_INTRO) - save_svref(svp); + save_svref(&HeVAL(he)); } - *MARK = svp ? *svp : &sv_undef; + *MARK = he ? HeVAL(he) : &sv_undef; } } if (GIMME != G_ARRAY) { @@ -1954,7 +2356,7 @@ PP(pp_lslice) if (ix >= max || !(*lelem = firstrelem[ix])) *lelem = &sv_undef; } - if (!is_something_there && (SvOKp(*lelem) || SvGMAGICAL(*lelem))) + if (!is_something_there && (SvOK(*lelem) || SvGMAGICAL(*lelem))) is_something_there = TRUE; } if (is_something_there) @@ -1966,29 +2368,27 @@ PP(pp_lslice) PP(pp_anonlist) { - dSP; dMARK; + dSP; dMARK; dORIGMARK; I32 items = SP - MARK; - SP = MARK; - XPUSHs((SV*)sv_2mortal((SV*)av_make(items, MARK+1))); + SV *av = sv_2mortal((SV*)av_make(items, MARK+1)); + SP = ORIGMARK; /* av_make() might realloc stack_sp */ + XPUSHs(av); RETURN; } PP(pp_anonhash) { dSP; dMARK; dORIGMARK; - STRLEN len; HV* hv = (HV*)sv_2mortal((SV*)newHV()); while (MARK < SP) { SV* key = *++MARK; - char *tmps; SV *val = NEWSV(46, 0); if (MARK < SP) sv_setsv(val, *++MARK); - else + else if (dowarn) warn("Odd number of elements in hash list"); - tmps = SvPV(key,len); - (void)hv_store(hv,tmps,len,val,0); + (void)hv_store_ent(hv,key,val,0); } SP = ORIGMARK; XPUSHs((SV*)hv); @@ -2012,11 +2412,13 @@ PP(pp_splice) SP++; if (++MARK < SP) { - offset = SvIVx(*MARK); + offset = i = SvIVx(*MARK); if (offset < 0) offset += AvFILL(ary) + 1; else offset -= curcop->cop_arybase; + if (offset < 0) + DIE(no_aelem, i); if (++MARK < SP) { length = SvIVx(*MARK++); if (length < 0) @@ -2029,12 +2431,6 @@ PP(pp_splice) offset = 0; length = AvMAX(ary) + 1; } - if (offset < 0) { - length += offset; - offset = 0; - if (length < 0) - length = 0; - } if (offset > AvFILL(ary) + 1) offset = AvFILL(ary) + 1; after = AvFILL(ary) + 1 - (offset + length); @@ -2049,6 +2445,12 @@ PP(pp_splice) newlen = SP - MARK; diff = newlen - length; + if (newlen && !AvREAL(ary)) { + if (AvREIFY(ary)) + av_reify(ary); + else + assert(AvREAL(ary)); /* would leak, so croak */ + } if (diff < 0) { /* shrinking the area */ if (newlen) { @@ -2061,15 +2463,20 @@ PP(pp_splice) MEXTEND(MARK, length); Copy(AvARRAY(ary)+offset, MARK, length, SV*); if (AvREAL(ary)) { - for (i = length, dst = MARK; i; i--) - sv_2mortal(*dst++); /* free them eventualy */ + EXTEND_MORTAL(length); + for (i = length, dst = MARK; i; i--) { + if (!SvIMMORTAL(*dst)) + sv_2mortal(*dst); /* free them eventualy */ + dst++; + } } MARK += length - 1; } else { *MARK = AvARRAY(ary)[offset+length-1]; if (AvREAL(ary)) { - sv_2mortal(*MARK); + if (!SvIMMORTAL(*MARK)) + sv_2mortal(*MARK); for (i = length - 1, dst = &AvARRAY(ary)[offset]; i > 0; i--) SvREFCNT_dec(*dst++); /* free them now */ } @@ -2155,8 +2562,12 @@ PP(pp_splice) if (length) { Copy(tmparyval, MARK, length, SV*); if (AvREAL(ary)) { - for (i = length, dst = MARK; i; i--) - sv_2mortal(*dst++); /* free them eventualy */ + EXTEND_MORTAL(length); + for (i = length, dst = MARK; i; i--) { + if (!SvIMMORTAL(*dst)) + sv_2mortal(*dst); /* free them eventualy */ + dst++; + } } Safefree(tmparyval); } @@ -2165,7 +2576,8 @@ PP(pp_splice) else if (length--) { *MARK = tmparyval[length]; if (AvREAL(ary)) { - sv_2mortal(*MARK); + if (!SvIMMORTAL(*MARK)) + sv_2mortal(*MARK); while (length-- > 0) SvREFCNT_dec(tmparyval[length]); } @@ -2200,7 +2612,7 @@ PP(pp_pop) dSP; AV *av = (AV*)POPs; SV *sv = av_pop(av); - if (sv != &sv_undef && AvREAL(av)) + if (!SvIMMORTAL(sv) && AvREAL(av)) (void)sv_2mortal(sv); PUSHs(sv); RETURN; @@ -2214,7 +2626,7 @@ PP(pp_shift) EXTEND(SP, 1); if (!sv) RETPUSHUNDEF; - if (sv != &sv_undef && AvREAL(av)) + if (!SvIMMORTAL(sv) && AvREAL(av)) (void)sv_2mortal(sv); PUSHs(sv); RETURN; @@ -2264,7 +2676,7 @@ PP(pp_reverse) if (SP - MARK > 1) do_join(TARG, &sv_no, MARK, SP); else - sv_setsv(TARG, *SP); + sv_setsv(TARG, (SP > MARK) ? *SP : GvSV(defgv)); up = SvPV_force(TARG, len); if (len > 1) { down = SvPVX(TARG) + len - 1; @@ -2281,12 +2693,43 @@ PP(pp_reverse) RETURN; } +static SV * +mul128(sv, m) + SV *sv; + U8 m; +{ + STRLEN len; + char *s = SvPV(sv, len); + char *t; + U32 i = 0; + + if (!strnEQ(s, "0000", 4)) { /* need to grow sv */ + SV *new = newSVpv("0000000000", 10); + + sv_catsv(new, sv); + SvREFCNT_dec(sv); /* free old sv */ + sv = new; + s = SvPV(sv, len); + } + t = s + len - 1; + while (!*t) /* trailing '\0'? */ + t--; + while (t > s) { + i = ((*t - '0') << 7) + m; + *(t--) = '0' + (i % 10); + m = i / 10; + } + return (sv); +} + /* Explosives and implosives. */ PP(pp_unpack) { dSP; dPOPPOPssrl; + SV **oldsp = sp; + I32 gimme = GIMME_V; SV *sv; STRLEN llen; STRLEN rlen; @@ -2319,8 +2762,9 @@ PP(pp_unpack) register U32 culong; double cdouble; static char* bitcount = 0; + int commas = 0; - if (GIMME != G_ARRAY) { /* arrange to do first one only */ + if (gimme != G_ARRAY) { /* arrange to do first one only */ /*SUPPRESS 530*/ for (patend = pat; !isALPHA(*patend) || *patend == 'x'; patend++) ; if (strchr("aAbBhHP", *patend) || *pat == '%') { @@ -2333,7 +2777,9 @@ PP(pp_unpack) } while (pat < patend) { reparse: - datumtype = *pat++; + datumtype = *pat++ & 0xFF; + if (isSPACE(datumtype)) + continue; if (pat >= patend) len = 1; else if (*pat == '*') { @@ -2349,6 +2795,10 @@ PP(pp_unpack) len = (datumtype != '@'); switch(datumtype) { default: + croak("Invalid type in unpack: '%c'", (int)datumtype); + case ',': /* grandfather in commas but with a warning */ + if (commas++ == 0 && dowarn) + warn("Invalid type in unpack: '%c'", (int)datumtype); break; case '%': if (len == 1 && pat[-1] != '1') @@ -2508,12 +2958,13 @@ PP(pp_unpack) } else { EXTEND(SP, len); + EXTEND_MORTAL(len); while (len-- > 0) { aint = *s++; if (aint >= 128) /* fake up signed chars */ aint -= 256; sv = NEWSV(36, 0); - sv_setiv(sv, (I32)aint); + sv_setiv(sv, (IV)aint); PUSHs(sv_2mortal(sv)); } } @@ -2530,32 +2981,34 @@ PP(pp_unpack) } else { EXTEND(SP, len); + EXTEND_MORTAL(len); while (len-- > 0) { auint = *s++ & 255; sv = NEWSV(37, 0); - sv_setiv(sv, (I32)auint); + sv_setiv(sv, (IV)auint); PUSHs(sv_2mortal(sv)); } } break; case 's': - along = (strend - s) / sizeof(I16); + along = (strend - s) / SIZE16; if (len > along) len = along; if (checksum) { while (len-- > 0) { - Copy(s, &ashort, 1, I16); - s += sizeof(I16); + COPY16(s, &ashort); + s += SIZE16; culong += ashort; } } else { EXTEND(SP, len); + EXTEND_MORTAL(len); while (len-- > 0) { - Copy(s, &ashort, 1, I16); - s += sizeof(I16); + COPY16(s, &ashort); + s += SIZE16; sv = NEWSV(38, 0); - sv_setiv(sv, (I32)ashort); + sv_setiv(sv, (IV)ashort); PUSHs(sv_2mortal(sv)); } } @@ -2563,13 +3016,13 @@ PP(pp_unpack) case 'v': case 'n': case 'S': - along = (strend - s) / sizeof(U16); + along = (strend - s) / SIZE16; if (len > along) len = along; if (checksum) { while (len-- > 0) { - Copy(s, &aushort, 1, U16); - s += sizeof(U16); + COPY16(s, &aushort); + s += SIZE16; #ifdef HAS_NTOHS if (datumtype == 'n') aushort = ntohs(aushort); @@ -2583,9 +3036,10 @@ PP(pp_unpack) } else { EXTEND(SP, len); + EXTEND_MORTAL(len); while (len-- > 0) { - Copy(s, &aushort, 1, U16); - s += sizeof(U16); + COPY16(s, &aushort); + s += SIZE16; sv = NEWSV(39, 0); #ifdef HAS_NTOHS if (datumtype == 'n') @@ -2595,7 +3049,7 @@ PP(pp_unpack) if (datumtype == 'v') aushort = vtohs(aushort); #endif - sv_setiv(sv, (I32)aushort); + sv_setiv(sv, (IV)aushort); PUSHs(sv_2mortal(sv)); } } @@ -2616,11 +3070,12 @@ PP(pp_unpack) } else { EXTEND(SP, len); + EXTEND_MORTAL(len); while (len-- > 0) { Copy(s, &aint, 1, int); s += sizeof(int); sv = NEWSV(40, 0); - sv_setiv(sv, (I32)aint); + sv_setiv(sv, (IV)aint); PUSHs(sv_2mortal(sv)); } } @@ -2641,23 +3096,24 @@ PP(pp_unpack) } else { EXTEND(SP, len); + EXTEND_MORTAL(len); while (len-- > 0) { Copy(s, &auint, 1, unsigned int); s += sizeof(unsigned int); sv = NEWSV(41, 0); - sv_setiv(sv, (I32)auint); + sv_setuv(sv, (UV)auint); PUSHs(sv_2mortal(sv)); } } break; case 'l': - along = (strend - s) / sizeof(I32); + along = (strend - s) / SIZE32; if (len > along) len = along; if (checksum) { while (len-- > 0) { - Copy(s, &along, 1, I32); - s += sizeof(I32); + COPY32(s, &along); + s += SIZE32; if (checksum > 32) cdouble += (double)along; else @@ -2666,11 +3122,12 @@ PP(pp_unpack) } else { EXTEND(SP, len); + EXTEND_MORTAL(len); while (len-- > 0) { - Copy(s, &along, 1, I32); - s += sizeof(I32); + COPY32(s, &along); + s += SIZE32; sv = NEWSV(42, 0); - sv_setiv(sv, (I32)along); + sv_setiv(sv, (IV)along); PUSHs(sv_2mortal(sv)); } } @@ -2678,13 +3135,13 @@ PP(pp_unpack) case 'V': case 'N': case 'L': - along = (strend - s) / sizeof(U32); + along = (strend - s) / SIZE32; if (len > along) len = along; if (checksum) { while (len-- > 0) { - Copy(s, &aulong, 1, U32); - s += sizeof(U32); + COPY32(s, &aulong); + s += SIZE32; #ifdef HAS_NTOHL if (datumtype == 'N') aulong = ntohl(aulong); @@ -2701,10 +3158,10 @@ PP(pp_unpack) } else { EXTEND(SP, len); + EXTEND_MORTAL(len); while (len-- > 0) { - Copy(s, &aulong, 1, U32); - s += sizeof(U32); - sv = NEWSV(43, 0); + COPY32(s, &aulong); + s += SIZE32; #ifdef HAS_NTOHL if (datumtype == 'N') aulong = ntohl(aulong); @@ -2713,7 +3170,8 @@ PP(pp_unpack) if (datumtype == 'V') aulong = vtohl(aulong); #endif - sv_setnv(sv, (double)aulong); + sv = NEWSV(43, 0); + sv_setuv(sv, (UV)aulong); PUSHs(sv_2mortal(sv)); } } @@ -2723,6 +3181,7 @@ PP(pp_unpack) if (len > along) len = along; EXTEND(SP, len); + EXTEND_MORTAL(len); while (len-- > 0) { if (sizeof(char*) > strend - s) break; @@ -2736,6 +3195,47 @@ PP(pp_unpack) PUSHs(sv_2mortal(sv)); } break; + case 'w': + EXTEND(SP, len); + EXTEND_MORTAL(len); + { + UV auv = 0; + U32 bytes = 0; + + while ((len > 0) && (s < strend)) { + auv = (auv << 7) | (*s & 0x7f); + if (!(*s++ & 0x80)) { + bytes = 0; + sv = NEWSV(40, 0); + sv_setuv(sv, auv); + PUSHs(sv_2mortal(sv)); + len--; + auv = 0; + } + else if (++bytes >= sizeof(UV)) { /* promote to string */ + char *t; + + sv = newSVpvf("%.*Vu", (int)TYPE_DIGITS(UV), auv); + while (s < strend) { + sv = mul128(sv, *s & 0x7f); + if (!(*s++ & 0x80)) { + bytes = 0; + break; + } + } + t = SvPV(sv, na); + while (*t == '0') + t++; + sv_chop(sv, t); + PUSHs(sv_2mortal(sv)); + len--; + auv = 0; + } + } + if ((s >= strend) && bytes) + croak("Unterminated compressed integer"); + } + break; case 'P': EXTEND(SP, 1); if (sizeof(char*) > strend - s) @@ -2752,6 +3252,7 @@ PP(pp_unpack) #ifdef HAS_QUAD case 'q': EXTEND(SP, len); + EXTEND_MORTAL(len); while (len-- > 0) { if (s + sizeof(Quad_t) > strend) aquad = 0; @@ -2760,12 +3261,16 @@ PP(pp_unpack) s += sizeof(Quad_t); } sv = NEWSV(42, 0); - sv_setiv(sv, (IV)aquad); + if (aquad >= IV_MIN && aquad <= IV_MAX) + sv_setiv(sv, (IV)aquad); + else + sv_setnv(sv, (double)aquad); PUSHs(sv_2mortal(sv)); } break; case 'Q': EXTEND(SP, len); + EXTEND_MORTAL(len); while (len-- > 0) { if (s + sizeof(unsigned Quad_t) > strend) auquad = 0; @@ -2774,7 +3279,10 @@ PP(pp_unpack) s += sizeof(unsigned Quad_t); } sv = NEWSV(43, 0); - sv_setiv(sv, (IV)auquad); + if (aquad <= UV_MAX) + sv_setuv(sv, (UV)auquad); + else + sv_setnv(sv, (double)auquad); PUSHs(sv_2mortal(sv)); } break; @@ -2794,6 +3302,7 @@ PP(pp_unpack) } else { EXTEND(SP, len); + EXTEND_MORTAL(len); while (len-- > 0) { Copy(s, &afloat, 1, float); s += sizeof(float); @@ -2817,6 +3326,7 @@ PP(pp_unpack) } else { EXTEND(SP, len); + EXTEND_MORTAL(len); while (len-- > 0) { Copy(s, &adouble, 1, double); s += sizeof(double); @@ -2829,6 +3339,8 @@ PP(pp_unpack) case 'u': along = (strend - s) * 3 / 4; sv = NEWSV(42, along); + if (along) + SvPOK_on(sv); while (s < strend && *s > ' ' && *s < 'a') { I32 a, b, c, d; char hunk[4]; @@ -2891,15 +3403,17 @@ PP(pp_unpack) } else { if (checksum < 32) { - along = (1 << checksum) - 1; - culong &= (U32)along; + aulong = (1 << checksum) - 1; + culong &= aulong; } - sv_setnv(sv, (double)culong); + sv_setuv(sv, (UV)culong); } XPUSHs(sv_2mortal(sv)); checksum = 0; } } + if (sp == oldsp && gimme == G_SCALAR) + PUSHs(&sv_undef); RETURN; } @@ -2930,6 +3444,85 @@ register I32 len; sv_catpvn(sv, "\n", 1); } +static SV * +is_an_int(s, l) + char *s; + STRLEN l; +{ + SV *result = newSVpv("", l); + char *result_c = SvPV(result, na); /* convenience */ + char *out = result_c; + bool skip = 1; + bool ignore = 0; + + while (*s) { + switch (*s) { + case ' ': + break; + case '+': + if (!skip) { + SvREFCNT_dec(result); + return (NULL); + } + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + skip = 0; + if (!ignore) { + *(out++) = *s; + } + break; + case '.': + ignore = 1; + break; + default: + SvREFCNT_dec(result); + return (NULL); + } + s++; + } + *(out++) = '\0'; + SvCUR_set(result, out - result_c); + return (result); +} + +static int +div128(pnum, done) + SV *pnum; /* must be '\0' terminated */ + bool *done; +{ + STRLEN len; + char *s = SvPV(pnum, len); + int m = 0; + int r = 0; + char *t = s; + + *done = 1; + while (*t) { + int i; + + i = m * 10 + (*t - '0'); + m = i & 0x7F; + r = (i >> 7); /* r < 10 */ + if (r) { + *done = 0; + } + *(t++) = '0' + r; + } + *(t++) = '\0'; + SvCUR_set(pnum, (STRLEN) (t - s)); + return (m); +} + + PP(pp_pack) { dSP; dMARK; dORIGMARK; dTARGET; @@ -2959,13 +3552,16 @@ PP(pp_pack) char *aptr; float afloat; double adouble; + int commas = 0; items = SP - MARK; MARK++; sv_setpvn(cat, "", 0); while (pat < patend) { #define NEXTFROM (items-- > 0 ? *MARK++ : &sv_no) - datumtype = *pat++; + datumtype = *pat++ & 0xFF; + if (isSPACE(datumtype)) + continue; if (*pat == '*') { len = strchr("@Xxu", datumtype) ? 0 : items; pat++; @@ -2979,6 +3575,10 @@ PP(pp_pack) len = 1; switch(datumtype) { default: + croak("Invalid type in pack: '%c'", (int)datumtype); + case ',': /* grandfather in commas but with a warning */ + if (commas++ == 0 && dowarn) + warn("Invalid type in pack: '%c'", (int)datumtype); break; case '%': DIE("%% may only be used in unpack"); @@ -3181,7 +3781,7 @@ PP(pp_pack) #ifdef HAS_HTONS ashort = htons(ashort); #endif - sv_catpvn(cat, (char*)&ashort, sizeof(I16)); + CAT16(cat, &ashort); } break; case 'v': @@ -3191,7 +3791,7 @@ PP(pp_pack) #ifdef HAS_HTOVS ashort = htovs(ashort); #endif - sv_catpvn(cat, (char*)&ashort, sizeof(I16)); + CAT16(cat, &ashort); } break; case 'S': @@ -3199,16 +3799,86 @@ PP(pp_pack) while (len-- > 0) { fromstr = NEXTFROM; ashort = (I16)SvIV(fromstr); - sv_catpvn(cat, (char*)&ashort, sizeof(I16)); + CAT16(cat, &ashort); } break; case 'I': while (len-- > 0) { fromstr = NEXTFROM; - auint = U_I(SvNV(fromstr)); + auint = SvUV(fromstr); sv_catpvn(cat, (char*)&auint, sizeof(unsigned int)); } break; + case 'w': + while (len-- > 0) { + fromstr = NEXTFROM; + adouble = floor(SvNV(fromstr)); + + if (adouble < 0) + croak("Cannot compress negative numbers"); + + if ( +#ifdef BW_BITS + adouble <= BW_MASK +#else +#ifdef CXUX_BROKEN_CONSTANT_CONVERT + adouble <= UV_MAX_cxux +#else + adouble <= UV_MAX +#endif +#endif + ) + { + char buf[1 + sizeof(UV)]; + char *in = buf + sizeof(buf); + UV auv = U_V(adouble);; + + do { + *--in = (auv & 0x7f) | 0x80; + auv >>= 7; + } while (auv); + buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */ + sv_catpvn(cat, in, (buf + sizeof(buf)) - in); + } + else if (SvPOKp(fromstr)) { /* decimal string arithmetics */ + char *from, *result, *in; + SV *norm; + STRLEN len; + bool done; + + /* Copy string and check for compliance */ + from = SvPV(fromstr, len); + if ((norm = is_an_int(from, len)) == NULL) + croak("can compress only unsigned integer"); + + New('w', result, len, char); + in = result + len; + done = FALSE; + while (!done) + *--in = div128(norm, &done) | 0x80; + result[len - 1] &= 0x7F; /* clear continue bit */ + sv_catpvn(cat, in, (result + len) - in); + Safefree(result); + SvREFCNT_dec(norm); /* free norm */ + } + else if (SvNOKp(fromstr)) { + char buf[sizeof(double) * 2]; /* 8/7 <= 2 */ + char *in = buf + sizeof(buf); + + do { + double next = floor(adouble / 128); + *--in = (unsigned char)(adouble - (next * 128)) | 0x80; + if (--in < buf) /* this cannot happen ;-) */ + croak ("Cannot compress integer"); + adouble = next; + } while (adouble > 0); + buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */ + sv_catpvn(cat, in, (buf + sizeof(buf)) - in); + } + else + croak("Cannot compress non integer"); + } + break; case 'i': while (len-- > 0) { fromstr = NEXTFROM; @@ -3219,35 +3889,35 @@ PP(pp_pack) case 'N': while (len-- > 0) { fromstr = NEXTFROM; - aulong = U_L(SvNV(fromstr)); + aulong = SvUV(fromstr); #ifdef HAS_HTONL aulong = htonl(aulong); #endif - sv_catpvn(cat, (char*)&aulong, sizeof(U32)); + CAT32(cat, &aulong); } break; case 'V': while (len-- > 0) { fromstr = NEXTFROM; - aulong = U_L(SvNV(fromstr)); + aulong = SvUV(fromstr); #ifdef HAS_HTOVL aulong = htovl(aulong); #endif - sv_catpvn(cat, (char*)&aulong, sizeof(U32)); + CAT32(cat, &aulong); } break; case 'L': while (len-- > 0) { fromstr = NEXTFROM; - aulong = U_L(SvNV(fromstr)); - sv_catpvn(cat, (char*)&aulong, sizeof(U32)); + aulong = SvUV(fromstr); + CAT32(cat, &aulong); } break; case 'l': while (len-- > 0) { fromstr = NEXTFROM; along = SvIV(fromstr); - sv_catpvn(cat, (char*)&along, sizeof(I32)); + CAT32(cat, &along); } break; #ifdef HAS_QUAD @@ -3272,7 +3942,21 @@ PP(pp_pack) case 'p': while (len-- > 0) { fromstr = NEXTFROM; - aptr = SvPV_force(fromstr, na); /* XXX Error if TEMP? */ + if (fromstr == &sv_undef) + aptr = NULL; + else { + /* XXX better yet, could spirit away the string to + * a safe spot and hang on to it until the result + * of pack() (and all copies of the result) are + * gone. + */ + if (dowarn && (SvTEMP(fromstr) || SvPADTMP(fromstr))) + warn("Attempt to pack pointer to temporary value"); + if (SvPOK(fromstr) || SvNIOK(fromstr)) + aptr = SvPV(fromstr,na); + else + aptr = SvPV_force(fromstr,na); + } sv_catpvn(cat, (char*)&aptr, sizeof(char*)); } break; @@ -3314,7 +3998,8 @@ PP(pp_split) STRLEN len; register char *s = SvPV(sv, len); char *strend = s + len; - register PMOP *pm = (PMOP*)POPs; + register PMOP *pm; + register REGEXP *rx; register SV *dstr; register char *m; I32 iters = 0; @@ -3324,13 +4009,22 @@ PP(pp_split) I32 origlimit = limit; I32 realarray = 0; I32 base; - AV *oldstack = stack; - register REGEXP *rx = pm->op_pmregexp; - I32 gimme = GIMME; + AV *oldstack = curstack; + I32 gimme = GIMME_V; I32 oldsave = savestack_ix; +#ifdef DEBUGGING + Copy(&LvTARGOFF(POPs), &pm, 1, PMOP*); +#else + pm = (PMOP*)POPs; +#endif if (!pm || !s) DIE("panic: do_split"); + rx = pm->op_pmregexp; + + TAINT_IF((pm->op_pmflags & PMf_LOCALE) && + (pm->op_pmflags & (PMf_WHITE | PMf_SKIPWHITE))); + if (pm->op_pmreplroot) ary = GvAVn((GV*)pm->op_pmreplroot); else if (gimme != G_ARRAY) @@ -3347,13 +4041,19 @@ PP(pp_split) av_extend(ary,0); av_clear(ary); /* temporarily switch stacks */ - SWITCHSTACK(stack, ary); + SWITCHSTACK(curstack, ary); } base = SP - stack_base; orig = s; if (pm->op_pmflags & PMf_SKIPWHITE) { - while (isSPACE(*s)) - s++; + if (pm->op_pmflags & PMf_LOCALE) { + while (isSPACE_LC(*s)) + s++; + } + else { + while (isSPACE(*s)) + s++; + } } if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) { SAVEINT(multiline); @@ -3364,17 +4064,25 @@ PP(pp_split) limit = maxiters + 2; if (pm->op_pmflags & PMf_WHITE) { while (--limit) { - /*SUPPRESS 530*/ - for (m = s; m < strend && !isSPACE(*m); m++) ; + m = s; + while (m < strend && + !((pm->op_pmflags & PMf_LOCALE) + ? isSPACE_LC(*m) : isSPACE(*m))) + ++m; if (m >= strend) break; + dstr = NEWSV(30, m-s); sv_setpvn(dstr, s, m-s); if (!realarray) sv_2mortal(dstr); XPUSHs(dstr); - /*SUPPRESS 530*/ - for (s = m + 1; s < strend && isSPACE(*s); s++) ; + + s = m + 1; + while (s < strend && + ((pm->op_pmflags & PMf_LOCALE) + ? isSPACE_LC(*s) : isSPACE(*s))) + ++s; } } else if (strEQ("^", rx->precomp)) { @@ -3392,23 +4100,13 @@ PP(pp_split) s = m; } } - else if (pm->op_pmshort) { + else if (pm->op_pmshort && !rx->nparens) { i = SvCUR(pm->op_pmshort); if (i == 1) { - I32 fold = (pm->op_pmflags & PMf_FOLD); i = *SvPVX(pm->op_pmshort); - if (fold && isUPPER(i)) - i = toLOWER(i); while (--limit) { - if (fold) { - for ( m = s; - m < strend && *m != i && - (!isUPPER(*m) || toLOWER(*m) != i); - m++) /*SUPPRESS 530*/ - ; - } - else /*SUPPRESS 530*/ - for (m = s; m < strend && *m != i; m++) ; + /*SUPPRESS 530*/ + for (m = s; m < strend && *m != i; m++) ; if (m >= strend) break; dstr = NEWSV(30, m-s); @@ -3438,7 +4136,9 @@ PP(pp_split) else { maxiters += (strend - s) * rx->nparens; while (s < strend && --limit && - pregexec(rx, s, strend, orig, 1, Nullsv, TRUE) ) { + pregexec(rx, s, strend, orig, 1, Nullsv, TRUE)) + { + TAINT_IF(rx->exec_tainted); if (rx->subbase && rx->subbase != orig) { m = s; @@ -3486,11 +4186,16 @@ PP(pp_split) iters++; } else if (!origlimit) { - while (iters > 0 && SvCUR(TOPs) == 0) + while (iters > 0 && (!TOPs || !SvANY(TOPs) || SvCUR(TOPs) == 0)) iters--, SP--; } if (realarray) { SWITCHSTACK(ary, oldstack); + if (SvSMAGICAL(ary)) { + PUTBACK; + mg_set((SV*)ary); + SPAGAIN; + } if (gimme == G_ARRAY) { EXTEND(SP, iters); Copy(AvARRAY(ary), SP + 1, iters, SV*); diff --git a/gnu/usr.bin/perl/pp.h b/gnu/usr.bin/perl/pp.h index 44a3ebeb723..3c3bdcf9c07 100644 --- a/gnu/usr.bin/perl/pp.h +++ b/gnu/usr.bin/perl/pp.h @@ -1,6 +1,6 @@ /* pp.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -55,24 +55,26 @@ #define POPp (SvPVx(POPs, na)) #define POPn (SvNVx(POPs)) #define POPi ((IV)SvIVx(POPs)) +#define POPu ((UV)SvUVx(POPs)) #define POPl ((long)SvIVx(POPs)) #define TOPs (*sp) #define TOPp (SvPV(TOPs, na)) #define TOPn (SvNV(TOPs)) #define TOPi ((IV)SvIV(TOPs)) +#define TOPu ((UV)SvUV(TOPs)) #define TOPl ((long)SvIV(TOPs)) /* Go to some pains in the rare event that we must extend the stack. */ -#define EXTEND(p,n) STMT_START { if (stack_max - p < (n)) { \ - sp = stack_grow(sp,p, (int) (n)); \ +#define EXTEND(p,n) STMT_START { if (stack_max - p < (n)) { \ + sp = stack_grow(sp,p, (int) (n)); \ } } STMT_END /* Same thing, but update mark register too. */ -#define MEXTEND(p,n) STMT_START {if (stack_max - p < (n)) { \ - int markoff = mark - stack_base; \ - sp = stack_grow(sp,p,(int) (n)); \ - mark = stack_base + markoff; \ +#define MEXTEND(p,n) STMT_START {if (stack_max - p < (n)) { \ + int markoff = mark - stack_base; \ + sp = stack_grow(sp,p,(int) (n)); \ + mark = stack_base + markoff; \ } } STMT_END #define PUSHs(s) (*++sp = (s)) @@ -80,22 +82,21 @@ #define PUSHp(p,l) STMT_START { sv_setpvn(TARG, (p), (l)); PUSHTARG; } STMT_END #define PUSHn(n) STMT_START { sv_setnv(TARG, (double)(n)); PUSHTARG; } STMT_END #define PUSHi(i) STMT_START { sv_setiv(TARG, (IV)(i)); PUSHTARG; } STMT_END +#define PUSHu(u) STMT_START { sv_setuv(TARG, (UV)(u)); PUSHTARG; } STMT_END #define XPUSHs(s) STMT_START { EXTEND(sp,1); (*++sp = (s)); } STMT_END #define XPUSHTARG STMT_START { SvSETMAGIC(TARG); XPUSHs(TARG); } STMT_END #define XPUSHp(p,l) STMT_START { sv_setpvn(TARG, (p), (l)); XPUSHTARG; } STMT_END #define XPUSHn(n) STMT_START { sv_setnv(TARG, (double)(n)); XPUSHTARG; } STMT_END #define XPUSHi(i) STMT_START { sv_setiv(TARG, (IV)(i)); XPUSHTARG; } STMT_END +#define XPUSHu(u) STMT_START { sv_setuv(TARG, (UV)(u)); XPUSHTARG; } STMT_END #define SETs(s) (*sp = s) #define SETTARG STMT_START { SvSETMAGIC(TARG); SETs(TARG); } STMT_END #define SETp(p,l) STMT_START { sv_setpvn(TARG, (p), (l)); SETTARG; } STMT_END #define SETn(n) STMT_START { sv_setnv(TARG, (double)(n)); SETTARG; } STMT_END #define SETi(i) STMT_START { sv_setiv(TARG, (IV)(i)); SETTARG; } STMT_END - -#ifdef OVERLOAD -#define SETsv(sv) STMT_START { sv_setsv(TARG, (sv)); SETTARG; } STMT_END -#endif /* OVERLOAD */ +#define SETu(u) STMT_START { sv_setuv(TARG, (UV)(u)); SETTARG; } STMT_END #define dTOPss SV *sv = TOPs #define dPOPss SV *sv = POPs @@ -103,14 +104,35 @@ #define dPOPnv double value = POPn #define dTOPiv IV value = TOPi #define dPOPiv IV value = POPi - -#define dPOPPOPssrl SV *right = POPs; SV *left = POPs -#define dPOPPOPnnrl double right = POPn; double left = POPn -#define dPOPPOPiirl IV right = POPi; IV left = POPi - -#define dPOPTOPssrl SV *right = POPs; SV *left = TOPs -#define dPOPTOPnnrl double right = POPn; double left = TOPn -#define dPOPTOPiirl IV right = POPi; IV left = TOPi +#define dTOPuv UV value = TOPu +#define dPOPuv UV value = POPu + +#define dPOPXssrl(X) SV *right = POPs; SV *left = CAT2(X,s) +#define dPOPXnnrl(X) double right = POPn; double left = CAT2(X,n) +#define dPOPXiirl(X) IV right = POPi; IV left = CAT2(X,i) + +#define USE_LEFT(sv) \ + (SvOK(sv) || SvGMAGICAL(sv) || !(op->op_flags & OPf_STACKED)) +#define dPOPXnnrl_ul(X) \ + double right = POPn; \ + SV *leftsv = CAT2(X,s); \ + double left = USE_LEFT(leftsv) ? SvNV(leftsv) : 0.0 +#define dPOPXiirl_ul(X) \ + IV right = POPi; \ + SV *leftsv = CAT2(X,s); \ + IV left = USE_LEFT(leftsv) ? SvIV(leftsv) : 0 + +#define dPOPPOPssrl dPOPXssrl(POP) +#define dPOPPOPnnrl dPOPXnnrl(POP) +#define dPOPPOPnnrl_ul dPOPXnnrl_ul(POP) +#define dPOPPOPiirl dPOPXiirl(POP) +#define dPOPPOPiirl_ul dPOPXiirl_ul(POP) + +#define dPOPTOPssrl dPOPXssrl(TOP) +#define dPOPTOPnnrl dPOPXnnrl(TOP) +#define dPOPTOPnnrl_ul dPOPXnnrl_ul(TOP) +#define dPOPTOPiirl dPOPXiirl(TOP) +#define dPOPTOPiirl_ul dPOPXiirl_ul(TOP) #define RETPUSHYES RETURNX(PUSHs(&sv_yes)) #define RETPUSHNO RETURNX(PUSHs(&sv_no)) @@ -127,7 +149,13 @@ stack_base = AvARRAY(t); \ stack_max = stack_base + AvMAX(t); \ sp = stack_sp = stack_base + AvFILL(t); \ - stack = t; + curstack = t; + +#define EXTEND_MORTAL(n) \ + STMT_START { \ + if (tmps_ix + (n) >= tmps_max) \ + Renew(tmps_stack, tmps_max = tmps_ix + (n) + 1, SV*); \ + } STMT_END #ifdef OVERLOAD @@ -169,10 +197,13 @@ } \ } STMT_END -#define tryAMAGICun(meth) tryAMAGICunW(meth,SETsv) +#define tryAMAGICun tryAMAGICunSET #define tryAMAGICunSET(meth) tryAMAGICunW(meth,SETs) #define opASSIGN (op->op_flags & OPf_STACKED) +#define SETsv(sv) STMT_START { \ + if (opASSIGN) { sv_setsv(TARG, (sv)); SETTARG; } \ + else SETs(sv); } STMT_END /* newSVsv does not behave as advertised, so we copy missing * information by hand */ diff --git a/gnu/usr.bin/perl/pp_ctl.c b/gnu/usr.bin/perl/pp_ctl.c index e57e88a1679..516e41e5b1c 100644 --- a/gnu/usr.bin/perl/pp_ctl.c +++ b/gnu/usr.bin/perl/pp_ctl.c @@ -1,6 +1,6 @@ /* pp_ctl.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -23,16 +23,20 @@ #define WORD_ALIGN sizeof(U16) #endif +#define DOCATCH(o) ((CATCH_GET == TRUE) ? docatch(o) : (o)) + +static OP *docatch _((OP *o)); static OP *doeval _((int gimme)); -static OP *dofindlabel _((OP *op, char *label, OP **opstack)); +static OP *dofindlabel _((OP *op, char *label, OP **opstack, OP **oplimit)); static void doparseform _((SV *sv)); static I32 dopoptoeval _((I32 startingblock)); static I32 dopoptolabel _((char *label)); static I32 dopoptoloop _((I32 startingblock)); static I32 dopoptosub _((I32 startingblock)); static void save_lines _((AV *array, SV *sv)); -static int sortcmp _((const void *, const void *)); static int sortcv _((const void *, const void *)); +static int sortcmp _((const void *, const void *)); +static int sortcmp_locale _((const void *, const void *)); static I32 sortcxix; @@ -46,10 +50,14 @@ PP(pp_wantarray) if (cxix < 0) RETPUSHUNDEF; - if (cxstack[cxix].blk_gimme == G_ARRAY) + switch (cxstack[cxix].blk_gimme) { + case G_ARRAY: RETPUSHYES; - else + case G_SCALAR: RETPUSHNO; + default: + RETPUSHUNDEF; + } } PP(pp_regcmaybe) @@ -86,7 +94,7 @@ PP(pp_regcomp) { pm->op_pmflags |= PMf_WHITE; if (pm->op_pmflags & PMf_KEEP) { - pm->op_pmflags &= ~PMf_RUNTIME; /* no point compiling again */ + pm->op_private &= ~OPpRUNTIME; /* no point compiling again */ hoistmust(pm); cLOGOP->op_first->op_next = op->op_next; } @@ -104,14 +112,15 @@ PP(pp_substcont) char *orig = cx->sb_orig; register REGEXP *rx = cx->sb_rx; + rxres_restore(&cx->sb_rxres, rx); + if (cx->sb_iters++) { if (cx->sb_iters > cx->sb_maxiters) DIE("Substitution loop"); + if (!cx->sb_rxtainted) + cx->sb_rxtainted = SvTAINTED(TOPs); sv_catsv(dstr, POPs); - if (rx->subbase) - Safefree(rx->subbase); - rx->subbase = cx->sb_subbase; /* Are we done */ if (cx->sb_once || !pregexec(rx, s, cx->sb_strend, orig, @@ -120,6 +129,8 @@ PP(pp_substcont) SV *targ = cx->sb_targ; sv_catpvn(dstr, s, cx->sb_strend - s); + TAINT_IF(cx->sb_rxtainted || rx->exec_tainted); + (void)SvOOK_off(targ); Safefree(SvPVX(targ)); SvPVX(targ) = SvPVX(dstr); @@ -127,9 +138,10 @@ PP(pp_substcont) SvLEN_set(targ, SvLEN(dstr)); SvPVX(dstr) = 0; sv_free(dstr); - (void)SvPOK_only(targ); SvSETMAGIC(targ); + SvTAINT(targ); + PUSHs(sv_2mortal(newSViv((I32)cx->sb_iters - 1))); LEAVE_SCOPE(cx->sb_oldsave); POPSUBST(cx); @@ -146,12 +158,76 @@ PP(pp_substcont) cx->sb_m = m = rx->startp[0]; sv_catpvn(dstr, s, m-s); cx->sb_s = rx->endp[0]; - cx->sb_subbase = rx->subbase; - - rx->subbase = Nullch; /* so recursion works */ + cx->sb_rxtainted |= rx->exec_tainted; + rxres_save(&cx->sb_rxres, rx); RETURNOP(pm->op_pmreplstart); } +void +rxres_save(rsp, rx) +void **rsp; +REGEXP *rx; +{ + UV *p = (UV*)*rsp; + U32 i; + + if (!p || p[1] < rx->nparens) { + i = 6 + rx->nparens * 2; + if (!p) + New(501, p, i, UV); + else + Renew(p, i, UV); + *rsp = (void*)p; + } + + *p++ = (UV)rx->subbase; + rx->subbase = Nullch; + + *p++ = rx->nparens; + + *p++ = (UV)rx->subbeg; + *p++ = (UV)rx->subend; + for (i = 0; i <= rx->nparens; ++i) { + *p++ = (UV)rx->startp[i]; + *p++ = (UV)rx->endp[i]; + } +} + +void +rxres_restore(rsp, rx) +void **rsp; +REGEXP *rx; +{ + UV *p = (UV*)*rsp; + U32 i; + + Safefree(rx->subbase); + rx->subbase = (char*)(*p); + *p++ = 0; + + rx->nparens = *p++; + + rx->subbeg = (char*)(*p++); + rx->subend = (char*)(*p++); + for (i = 0; i <= rx->nparens; ++i) { + rx->startp[i] = (char*)(*p++); + rx->endp[i] = (char*)(*p++); + } +} + +void +rxres_free(rsp) +void **rsp; +{ + UV *p = (UV*)*rsp; + + if (p) { + Safefree((char*)(*p)); + Safefree(p); + *rsp = Null(void*); + } +} + PP(pp_formline) { dSP; dMARK; dORIGMARK; @@ -174,7 +250,7 @@ PP(pp_formline) bool gotsome; STRLEN len; - if (!SvCOMPILED(form)) { + if (!SvMAGICAL(form) || !SvCOMPILED(form)) { SvREADONLY_off(form); doparseform(form); } @@ -212,9 +288,9 @@ PP(pp_formline) case FF_END: name = "END"; break; } if (arg >= 0) - fprintf(stderr, "%-16s%ld\n", name, (long) arg); + PerlIO_printf(PerlIO_stderr(), "%-16s%ld\n", name, (long) arg); else - fprintf(stderr, "%-16s\n", name); + PerlIO_printf(PerlIO_stderr(), "%-16s\n", name); } ) switch (*fpc++) { case FF_LINEMARK: @@ -376,6 +452,8 @@ PP(pp_formline) } gotsome = TRUE; value = SvNV(sv); + /* Formats aren't yet marked for locales, so assume "yes". */ + SET_NUMERIC_LOCAL(); if (arg & 256) { sprintf(t, "%#*.*f", (int) fieldsize, (int) arg & 255, value); } else { @@ -450,7 +528,7 @@ PP(pp_grepstart) if (stack_base + *markstack_ptr == sp) { (void)POPMARK; - if (GIMME != G_ARRAY) + if (GIMME_V == G_SCALAR) XPUSHs(&sv_no); RETURNOP(op->op_next->op_next); } @@ -513,6 +591,7 @@ PP(pp_mapwhile) /* All done yet? */ if (markstack_ptr[-1] > *markstack_ptr) { I32 items; + I32 gimme = GIMME_V; (void)POPMARK; /* pop top */ LEAVE; /* exit outer scope */ @@ -520,12 +599,12 @@ PP(pp_mapwhile) items = --*markstack_ptr - markstack_ptr[-1]; (void)POPMARK; /* pop dst */ SP = stack_base + POPMARK; /* pop original mark */ - if (GIMME != G_ARRAY) { + if (gimme == G_SCALAR) { dTARGET; XPUSHi(items); - RETURN; } - SP += items; + else if (gimme == G_ARRAY) + SP += items; RETURN; } else { @@ -574,7 +653,7 @@ PP(pp_sort) if (!(cv && CvROOT(cv))) { if (gv) { SV *tmpstr = sv_newmortal(); - gv_efullname(tmpstr, gv); + gv_efullname3(tmpstr, gv, Nullch); if (cv && CvXSUB(cv)) DIE("Xsub \"%s\" called in sort", SvPVX(tmpstr)); DIE("Undefined sort subroutine \"%s\" called", @@ -590,7 +669,7 @@ PP(pp_sort) sortcop = CvSTART(cv); SAVESPTR(CvROOT(cv)->op_ppaddr); CvROOT(cv)->op_ppaddr = ppaddr[OP_NULL]; - + SAVESPTR(curpad); curpad = AvARRAY((AV*)AvARRAY(CvPADLIST(cv))[1]); } @@ -604,10 +683,9 @@ PP(pp_sort) while (MARK < SP) { /* This may or may not shift down one here. */ /*SUPPRESS 560*/ if (*up = *++MARK) { /* Weed out nulls. */ - if (!SvPOK(*up)) + SvTEMP_off(*up); + if (!sortcop && !SvPOK(*up)) (void)sv_2pv(*up, &na); - else - SvTEMP_off(*up); up++; } } @@ -617,17 +695,19 @@ PP(pp_sort) AV *oldstack; CONTEXT *cx; SV** newsp; + bool oldcatch = CATCH_GET; SAVETMPS; SAVESPTR(op); - oldstack = stack; + oldstack = curstack; if (!sortstack) { sortstack = newAV(); AvREAL_off(sortstack); av_extend(sortstack, 32); } - SWITCHSTACK(stack, sortstack); + CATCH_SET(TRUE); + SWITCHSTACK(curstack, sortstack); if (sortstash != stash) { firstgv = gv_fetchpv("a", TRUE, SVt_PV); secondgv = gv_fetchpv("b", TRUE, SVt_PV); @@ -636,20 +716,31 @@ PP(pp_sort) SAVESPTR(GvSV(firstgv)); SAVESPTR(GvSV(secondgv)); - PUSHBLOCK(cx, CXt_LOOP, stack_base); + + PUSHBLOCK(cx, CXt_NULL, stack_base); + if (!(op->op_flags & OPf_SPECIAL)) { + bool hasargs = FALSE; + cx->cx_type = CXt_SUB; + cx->blk_gimme = G_SCALAR; + PUSHSUB(cx); + if (!CvDEPTH(cv)) + (void)SvREFCNT_inc(cv); /* in preparation for POPSUB */ + } sortcxix = cxstack_ix; qsort((char*)(myorigmark+1), max, sizeof(SV*), sortcv); POPBLOCK(cx,curpm); SWITCHSTACK(sortstack, oldstack); + CATCH_SET(oldcatch); } LEAVE; } else { if (max > 1) { MEXTEND(SP, 20); /* Can't afford stack realloc on signal. */ - qsort((char*)(ORIGMARK+1), max, sizeof(SV*), sortcmp); + qsort((char*)(ORIGMARK+1), max, sizeof(SV*), + (op->op_private & OPpLOCALE) ? sortcmp_locale : sortcmp); } } stack_sp = ORIGMARK + max; @@ -682,6 +773,7 @@ PP(pp_flip) sv_setiv(PAD_SV(cUNOP->op_first->op_targ), 1); if (op->op_flags & OPf_SPECIAL) { sv_setiv(targ, 1); + SETs(targ); RETURN; } else { @@ -707,14 +799,16 @@ PP(pp_flop) I32 max; if (SvNIOKp(left) || !SvPOKp(left) || - (looks_like_number(left) && *SvPVX(left) != '0') ) { + (looks_like_number(left) && *SvPVX(left) != '0') ) + { i = SvIV(left); max = SvIV(right); - if (max > i) + if (max >= i) { + EXTEND_MORTAL(max - i + 1); EXTEND(SP, max - i + 1); + } while (i <= max) { - sv = sv_mortalcopy(&sv_no); - sv_setiv(sv,i++); + sv = sv_2mortal(newSViv(i++)); PUSHs(sv); } } @@ -774,14 +868,18 @@ char *label; if (dowarn) warn("Exiting eval via %s", op_name[op->op_type]); break; + case CXt_NULL: + if (dowarn) + warn("Exiting pseudo-block via %s", op_name[op->op_type]); + return -1; case CXt_LOOP: if (!cx->blk_loop.label || strNE(label, cx->blk_loop.label) ) { - DEBUG_l(deb("(Skipping label #%d %s)\n", - i, cx->blk_loop.label)); + DEBUG_l(deb("(Skipping label #%ld %s)\n", + (long)i, cx->blk_loop.label)); continue; } - DEBUG_l( deb("(Found label #%d %s)\n", i, label)); + DEBUG_l( deb("(Found label #%ld %s)\n", (long)i, label)); return i; } } @@ -791,16 +889,29 @@ char *label; I32 dowantarray() { + I32 gimme = block_gimme(); + return (gimme == G_VOID) ? G_SCALAR : gimme; +} + +I32 +block_gimme() +{ I32 cxix; cxix = dopoptosub(cxstack_ix); if (cxix < 0) - return G_SCALAR; + return G_VOID; - if (cxstack[cxix].blk_gimme == G_ARRAY) - return G_ARRAY; - else + switch (cxstack[cxix].blk_gimme) { + case G_VOID: + return G_VOID; + case G_SCALAR: return G_SCALAR; + case G_ARRAY: + return G_ARRAY; + default: + croak("panic: bad gimme: %d\n", cxstack[cxix].blk_gimme); + } } static I32 @@ -816,7 +927,7 @@ I32 startingblock; continue; case CXt_EVAL: case CXt_SUB: - DEBUG_l( deb("(Found sub #%d)\n", i)); + DEBUG_l( deb("(Found sub #%ld)\n", (long)i)); return i; } } @@ -835,7 +946,7 @@ I32 startingblock; default: continue; case CXt_EVAL: - DEBUG_l( deb("(Found eval #%d)\n", i)); + DEBUG_l( deb("(Found eval #%ld)\n", (long)i)); return i; } } @@ -853,7 +964,7 @@ I32 startingblock; switch (cx->cx_type) { case CXt_SUBST: if (dowarn) - warn("Exiting substitition via %s", op_name[op->op_type]); + warn("Exiting substitution via %s", op_name[op->op_type]); break; case CXt_SUB: if (dowarn) @@ -863,8 +974,12 @@ I32 startingblock; if (dowarn) warn("Exiting eval via %s", op_name[op->op_type]); break; + case CXt_NULL: + if (dowarn) + warn("Exiting pseudo-block via %s", op_name[op->op_type]); + return -1; case CXt_LOOP: - DEBUG_l( deb("(Found loop #%d)\n", i)); + DEBUG_l( deb("(Found loop #%ld)\n", (long)i)); return i; } } @@ -880,11 +995,14 @@ I32 cxix; I32 optype; while (cxstack_ix > cxix) { - cx = &cxstack[cxstack_ix--]; - DEBUG_l(fprintf(stderr, "Unwinding block %ld, type %s\n", (long) cxstack_ix+1, - block_type[cx->cx_type])); + cx = &cxstack[cxstack_ix]; + DEBUG_l(PerlIO_printf(Perl_debug_log, "Unwinding block %ld, type %s\n", + (long) cxstack_ix+1, block_type[cx->cx_type])); /* Note: we don't need to restore the base context info till the end. */ switch (cx->cx_type) { + case CXt_SUBST: + POPSUBST(cx); + continue; /* not break */ case CXt_SUB: POPSUB(cx); break; @@ -894,53 +1012,13 @@ I32 cxix; case CXt_LOOP: POPLOOP(cx); break; - case CXt_SUBST: + case CXt_NULL: break; } + cxstack_ix--; } } -#ifdef I_STDARG -OP * -die(char* pat, ...) -#else -/*VARARGS0*/ -OP * -die(pat, va_alist) - char *pat; - va_dcl -#endif -{ - va_list args; - char *message; - int oldrunlevel = runlevel; - int was_in_eval = in_eval; - HV *stash; - GV *gv; - CV *cv; - -#ifdef I_STDARG - va_start(args, pat); -#else - va_start(args); -#endif - message = mess(pat, &args); - va_end(args); - if (diehook && (cv = sv_2cv(diehook, &stash, &gv, 0)) && !CvDEPTH(cv)) { - dSP; - - PUSHMARK(sp); - EXTEND(sp, 1); - PUSHs(sv_2mortal(newSVpv(message,0))); - PUTBACK; - perl_call_sv((SV*)cv, G_DISCARD); - } - restartop = die_where(message); - if ((!restartop && was_in_eval) || oldrunlevel > 1) - Siglongjmp(top_env, 3); - return restartop; -} - OP * die_where(message) char *message; @@ -980,7 +1058,7 @@ char *message; POPBLOCK(cx,curpm); if (cx->cx_type != CXt_EVAL) { - fprintf(stderr, "panic: die %s", message); + PerlIO_printf(PerlIO_stderr(), "panic: die %s", message); my_exit(1); } POPEVAL(cx); @@ -991,28 +1069,17 @@ char *message; LEAVE; - if (optype == OP_REQUIRE) - DIE("%s", SvPVx(GvSV(errgv), na)); + if (optype == OP_REQUIRE) { + char* msg = SvPVx(GvSV(errgv), na); + DIE("%s", *msg ? msg : "Compilation failed in require"); + } return pop_return(); } } - fputs(message, stderr); - (void)Fflush(stderr); - if (e_tmpname) { - if (e_fp) { - fclose(e_fp); - e_fp = Nullfp; - } - (void)UNLINK(e_tmpname); - Safefree(e_tmpname); - e_tmpname = Nullch; - } - statusvalue = SHIFTSTATUS(statusvalue); -#ifdef VMS - my_exit((U32)vaxc$errno?vaxc$errno:errno?errno:statusvalue?statusvalue:SS$_ABORT); -#else - my_exit((I32)((errno&255)?errno:((statusvalue&255)?statusvalue:255))); -#endif + PerlIO_printf(PerlIO_stderr(), "%s",message); + PerlIO_flush(PerlIO_stderr()); + my_failure_exit(); + /* NOTREACHED */ return 0; } @@ -1064,6 +1131,7 @@ PP(pp_caller) register I32 cxix = dopoptosub(cxstack_ix); register CONTEXT *cx; I32 dbcxix; + I32 gimme; SV *sv; I32 count = 0; @@ -1107,7 +1175,7 @@ PP(pp_caller) RETURN; if (cx->cx_type == CXt_SUB) { /* So is cxstack[dbcxix]. */ sv = NEWSV(49, 0); - gv_efullname(sv, CvGV(cxstack[cxix].blk_sub.cv)); + gv_efullname3(sv, CvGV(cxstack[cxix].blk_sub.cv), Nullch); PUSHs(sv_2mortal(sv)); PUSHs(sv_2mortal(newSViv((I32)cx->blk_sub.hasargs))); } @@ -1115,7 +1183,11 @@ PP(pp_caller) PUSHs(sv_2mortal(newSVpv("(eval)",0))); PUSHs(sv_2mortal(newSViv(0))); } - PUSHs(sv_2mortal(newSViv((I32)cx->blk_gimme))); + gimme = (I32)cx->blk_gimme; + if (gimme == G_VOID) + PUSHs(&sv_undef); + else + PUSHs(sv_2mortal(newSViv(gimme & G_ARRAY))); if (cx->cx_type == CXt_EVAL) { if (cx->blk_eval.old_op_type == OP_ENTEREVAL) { PUSHs(cx->blk_eval.cur_text); @@ -1155,8 +1227,8 @@ sortcv(a, b) const void *a; const void *b; { - SV **str1 = (SV **) a; - SV **str2 = (SV **) b; + SV * const *str1 = (SV * const *)a; + SV * const *str2 = (SV * const *)b; I32 oldsaveix = savestack_ix; I32 oldscopeix = scopestack_ix; I32 result; @@ -1182,33 +1254,15 @@ sortcmp(a, b) const void *a; const void *b; { - register SV *str1 = *(SV **) a; - register SV *str2 = *(SV **) b; - I32 retval; - - if (!SvPOKp(str1)) { - if (!SvPOKp(str2)) - return 0; - else - return -1; - } - if (!SvPOKp(str2)) - return 1; + return sv_cmp(*(SV * const *)a, *(SV * const *)b); +} - if (SvCUR(str1) < SvCUR(str2)) { - /*SUPPRESS 560*/ - if (retval = memcmp(SvPVX(str1), SvPVX(str2), SvCUR(str1))) - return retval; - else - return -1; - } - /*SUPPRESS 560*/ - else if (retval = memcmp(SvPVX(str1), SvPVX(str2), SvCUR(str2))) - return retval; - else if (SvCUR(str1) == SvCUR(str2)) - return 0; - else - return 1; +static int +sortcmp_locale(a, b) +const void *a; +const void *b; +{ + return sv_cmp_locale(*(SV * const *)a, *(SV * const *)b); } PP(pp_reset) @@ -1258,7 +1312,7 @@ PP(pp_dbstate) SAVETMPS; SAVEI32(debug); - SAVESPTR(stack_sp); + SAVESTACK_POS(); debug = 0; hasargs = 0; sp = stack_sp; @@ -1285,7 +1339,7 @@ PP(pp_enteriter) { dSP; dMARK; register CONTEXT *cx; - I32 gimme = GIMME; + I32 gimme = GIMME_V; SV **svp; ENTER; @@ -1302,14 +1356,11 @@ PP(pp_enteriter) PUSHBLOCK(cx, CXt_LOOP, SP); PUSHLOOP(cx, svp, MARK); - if (op->op_flags & OPf_STACKED) { - AV* av = (AV*)POPs; - cx->blk_loop.iterary = av; - cx->blk_loop.iterix = -1; - } + if (op->op_flags & OPf_STACKED) + cx->blk_loop.iterary = (AV*)SvREFCNT_inc(POPs); else { - cx->blk_loop.iterary = stack; - AvFILL(stack) = sp - stack_base; + cx->blk_loop.iterary = curstack; + AvFILL(curstack) = sp - stack_base; cx->blk_loop.iterix = MARK - stack_base; } @@ -1320,7 +1371,7 @@ PP(pp_enterloop) { dSP; register CONTEXT *cx; - I32 gimme = GIMME; + I32 gimme = GIMME_V; ENTER; SAVETMPS; @@ -1336,6 +1387,7 @@ PP(pp_leaveloop) { dSP; register CONTEXT *cx; + struct block_loop cxloop; I32 gimme; SV **newsp; PMOP *newpm; @@ -1343,27 +1395,33 @@ PP(pp_leaveloop) POPBLOCK(cx,newpm); mark = newsp; - POPLOOP(cx); - if (gimme == G_SCALAR) { - if (op->op_private & OPpLEAVE_VOID) - ; - else { - if (mark < SP) - *++newsp = sv_mortalcopy(*SP); - else - *++newsp = &sv_undef; - } + POPLOOP1(cx); /* Delay POPLOOP2 until stack values are safe */ + + TAINT_NOT; + if (gimme == G_VOID) + ; /* do nothing */ + else if (gimme == G_SCALAR) { + if (mark < SP) + *++newsp = sv_mortalcopy(*SP); + else + *++newsp = &sv_undef; } else { - while (mark < SP) + while (mark < SP) { *++newsp = sv_mortalcopy(*++mark); + TAINT_NOT; /* Each item is independent */ + } } - curpm = newpm; /* Don't pop $1 et al till now */ - sp = newsp; + SP = newsp; + PUTBACK; + + POPLOOP2(); /* Stack values are safe: release loop vars ... */ + curpm = newpm; /* ... and pop $1 et al */ + LEAVE; LEAVE; - RETURN; + return NORMAL; } PP(pp_return) @@ -1371,16 +1429,18 @@ PP(pp_return) dSP; dMARK; I32 cxix; register CONTEXT *cx; + struct block_sub cxsub; + bool popsub2 = FALSE; I32 gimme; SV **newsp; PMOP *newpm; I32 optype = 0; - if (stack == sortstack) { - if (cxstack_ix == sortcxix || dopoptosub(cxstack_ix) < sortcxix) { + if (curstack == sortstack) { + if (cxstack_ix == sortcxix || dopoptosub(cxstack_ix) <= sortcxix) { if (cxstack_ix > sortcxix) dounwind(sortcxix); - AvARRAY(stack)[1] = *SP; + AvARRAY(curstack)[1] = *SP; stack_sp = stack_base + 1; return 0; } @@ -1395,13 +1455,15 @@ PP(pp_return) POPBLOCK(cx,newpm); switch (cx->cx_type) { case CXt_SUB: - POPSUB(cx); + POPSUB1(cx); /* Delay POPSUB2 until stack values are safe */ + popsub2 = TRUE; break; case CXt_EVAL: POPEVAL(cx); if (optype == OP_REQUIRE && (MARK == SP || (gimme == G_SCALAR && !SvTRUE(*SP))) ) { + /* Unassume the success we assumed earlier. */ char *name = cx->blk_eval.old_name; (void)hv_delete(GvHVn(incgv), name, strlen(name), G_DISCARD); DIE("%s did not return a true value", name); @@ -1409,22 +1471,31 @@ PP(pp_return) break; default: DIE("panic: return"); - break; } + TAINT_NOT; if (gimme == G_SCALAR) { if (MARK < SP) - *++newsp = sv_mortalcopy(*SP); + *++newsp = (popsub2 && SvTEMP(*SP)) + ? *SP : sv_mortalcopy(*SP); else *++newsp = &sv_undef; } - else { - while (MARK < SP) - *++newsp = sv_mortalcopy(*++MARK); + else if (gimme == G_ARRAY) { + while (++MARK <= SP) { + *++newsp = (popsub2 && SvTEMP(*MARK)) + ? *MARK : sv_mortalcopy(*MARK); + TAINT_NOT; /* Each item is independent */ + } } - curpm = newpm; /* Don't pop $1 et al till now */ stack_sp = newsp; + /* Stack values are safe: */ + if (popsub2) { + POPSUB2(); /* release CV and @_ ... */ + } + curpm = newpm; /* ... and pop $1 et al */ + LEAVE; return pop_return(); } @@ -1434,6 +1505,9 @@ PP(pp_last) dSP; I32 cxix; register CONTEXT *cx; + struct block_loop cxloop; + struct block_sub cxsub; + I32 pop2 = 0; I32 gimme; I32 optype; OP *nextop; @@ -1457,38 +1531,55 @@ PP(pp_last) POPBLOCK(cx,newpm); switch (cx->cx_type) { case CXt_LOOP: - POPLOOP(cx); - nextop = cx->blk_loop.last_op->op_next; - LEAVE; + POPLOOP1(cx); /* Delay POPLOOP2 until stack values are safe */ + pop2 = CXt_LOOP; + nextop = cxloop.last_op->op_next; break; - case CXt_EVAL: - POPEVAL(cx); + case CXt_SUB: + POPSUB1(cx); /* Delay POPSUB2 until stack values are safe */ + pop2 = CXt_SUB; nextop = pop_return(); break; - case CXt_SUB: - POPSUB(cx); + case CXt_EVAL: + POPEVAL(cx); nextop = pop_return(); break; default: DIE("panic: last"); - break; } + TAINT_NOT; if (gimme == G_SCALAR) { - if (mark < SP) - *++newsp = sv_mortalcopy(*SP); + if (MARK < SP) + *++newsp = ((pop2 == CXt_SUB) && SvTEMP(*SP)) + ? *SP : sv_mortalcopy(*SP); else *++newsp = &sv_undef; } - else { - while (mark < SP) - *++newsp = sv_mortalcopy(*++mark); + else if (gimme == G_ARRAY) { + while (++MARK <= SP) { + *++newsp = ((pop2 == CXt_SUB) && SvTEMP(*MARK)) + ? *MARK : sv_mortalcopy(*MARK); + TAINT_NOT; /* Each item is independent */ + } } - curpm = newpm; /* Don't pop $1 et al till now */ - sp = newsp; + SP = newsp; + PUTBACK; + + /* Stack values are safe: */ + switch (pop2) { + case CXt_LOOP: + POPLOOP2(); /* release loop vars ... */ + LEAVE; + break; + case CXt_SUB: + POPSUB2(); /* release CV and @_ ... */ + break; + } + curpm = newpm; /* ... and pop $1 et al */ LEAVE; - RETURNOP(nextop); + return nextop; } PP(pp_next) @@ -1544,19 +1635,27 @@ PP(pp_redo) static OP* lastgotoprobe; static OP * -dofindlabel(op,label,opstack) +dofindlabel(op,label,opstack,oplimit) OP *op; char *label; OP **opstack; +OP **oplimit; { OP *kid; OP **ops = opstack; + static char too_deep[] = "Target of goto is too deeply nested"; + if (ops >= oplimit) + croak(too_deep); if (op->op_type == OP_LEAVE || op->op_type == OP_SCOPE || op->op_type == OP_LEAVELOOP || op->op_type == OP_LEAVETRY) - *ops++ = cUNOP->op_first; + { + *ops++ = cUNOP->op_first; + if (ops >= oplimit) + croak(too_deep); + } *ops = 0; if (op->op_flags & OPf_KIDS) { /* First try all the kids at this level, since that's likeliest. */ @@ -1568,15 +1667,12 @@ OP **opstack; for (kid = cUNOP->op_first; kid; kid = kid->op_sibling) { if (kid == lastgotoprobe) continue; - if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) { - if (ops > opstack && - (ops[-1]->op_type == OP_NEXTSTATE || - ops[-1]->op_type == OP_DBSTATE)) - *ops = kid; - else - *ops++ = kid; - } - if (op = dofindlabel(kid,label,ops)) + if ((kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) && + (ops == opstack || + (ops[-1]->op_type != OP_NEXTSTATE && + ops[-1]->op_type != OP_DBSTATE))) + *ops++ = kid; + if (op = dofindlabel(kid, label, ops, oplimit)) return op; } } @@ -1596,7 +1692,8 @@ PP(pp_goto) OP *retop = 0; I32 ix; register CONTEXT *cx; - OP *enterops[64]; +#define GOTO_DEPTH 64 + OP *enterops[GOTO_DEPTH]; char *label; int do_dump = (op->op_type == OP_DUMP); @@ -1616,7 +1713,7 @@ PP(pp_goto) if (!CvROOT(cv) && !CvXSUB(cv)) { if (CvGV(cv)) { SV *tmpstr = sv_newmortal(); - gv_efullname(tmpstr, CvGV(cv)); + gv_efullname3(tmpstr, CvGV(cv), Nullch); DIE("Goto undefined subroutine &%s",SvPVX(tmpstr)); } DIE("Goto undefined subroutine"); @@ -1634,8 +1731,11 @@ PP(pp_goto) AV* av = cx->blk_sub.argarray; items = AvFILL(av) + 1; - Copy(AvARRAY(av), ++stack_sp, items, SV*); + stack_sp++; + EXTEND(stack_sp, items); /* @_ could have been extended. */ + Copy(AvARRAY(av), stack_sp, items, SV*); stack_sp += items; + SvREFCNT_dec(GvAV(defgv)); GvAV(defgv) = cx->blk_sub.savearray; AvREAL_off(av); av_clear(av); @@ -1661,6 +1761,7 @@ PP(pp_goto) sp = stack_base + items; } else { + stack_sp--; /* There is no cv arg. */ (void)(*CvXSUB(cv))(cv); } LEAVE; @@ -1676,8 +1777,7 @@ PP(pp_goto) (void)SvREFCNT_inc(cv); else { /* save temporaries on recursion? */ if (CvDEPTH(cv) == 100 && dowarn) - warn("Deep recursion on subroutine \"%s\"", - GvENAME(CvGV(cv))); + sub_crush_depth(cv); if (CvDEPTH(cv) > AvFILL(padlist)) { AV *newpad = newAV(); SV **oldpad = AvARRAY(svp[CvDEPTH(cv)-1]); @@ -1686,8 +1786,10 @@ PP(pp_goto) for ( ;ix > 0; ix--) { if (svp[ix] != &sv_undef) { char *name = SvPVX(svp[ix]); - if (SvFLAGS(svp[ix]) & SVf_FAKE) { - /* outer lexical? */ + if ((SvFLAGS(svp[ix]) & SVf_FAKE) + || *name == '&') + { + /* outer lexical or anon code */ av_store(newpad, ix, SvREFCNT_inc(oldpad[ix]) ); } @@ -1725,7 +1827,7 @@ PP(pp_goto) cx->blk_sub.savearray = GvAV(defgv); cx->blk_sub.argarray = av; - GvAV(defgv) = cx->blk_sub.argarray; + GvAV(defgv) = (AV*)SvREFCNT_inc(av); ++mark; if (items >= AvMAX(av) + 1) { @@ -1750,6 +1852,15 @@ PP(pp_goto) mark++; } } + if (PERLDB_SUB && curstash != debstash) { + /* + * We do not care about using sv to call CV; + * it's for informational purposes only. + */ + SV *sv = GvSV(DBsub); + save_item(sv); + gv_efullname3(sv, CvGV(cv), Nullch); + } RETURNOP(CvSTART(cv)); } } @@ -1773,9 +1884,6 @@ PP(pp_goto) for (ix = cxstack_ix; ix >= 0; ix--) { cx = &cxstack[ix]; switch (cx->cx_type) { - case CXt_SUB: - gotoprobe = CvROOT(cx->blk_sub.cv); - break; case CXt_EVAL: gotoprobe = eval_root; /* XXX not good for nested eval */ break; @@ -1790,14 +1898,22 @@ PP(pp_goto) else gotoprobe = main_root; break; + case CXt_SUB: + if (CvDEPTH(cx->blk_sub.cv)) { + gotoprobe = CvROOT(cx->blk_sub.cv); + break; + } + /* FALL THROUGH */ + case CXt_NULL: + DIE("Can't \"goto\" outside a block"); default: if (ix) DIE("panic: goto"); - else - gotoprobe = main_root; + gotoprobe = main_root; break; } - retop = dofindlabel(gotoprobe, label, enterops); + retop = dofindlabel(gotoprobe, label, + enterops, enterops + GOTO_DEPTH); if (retop) break; lastgotoprobe = gotoprobe; @@ -1824,6 +1940,11 @@ PP(pp_goto) OP *oldop = op; for (ix = 1; enterops[ix]; ix++) { op = enterops[ix]; + /* Eventually we may want to stack the needed arguments + * for each op. For now, we punt on the hard ones. */ + if (op->op_type == OP_ENTERITER) + DIE("Can't \"goto\" into the middle of a foreach loop", + label); (*op->op_ppaddr)(); } op = oldop; @@ -1843,9 +1964,9 @@ PP(pp_goto) do_undump = FALSE; } - if (stack == signalstack) { + if (curstack == signalstack) { restartop = retop; - Siglongjmp(top_env, 3); + JMPENV_JUMP(3); } RETURNOP(retop); @@ -1858,8 +1979,13 @@ PP(pp_exit) if (MAXARG < 1) anum = 0; - else + else { anum = SvIVx(POPs); +#ifdef VMSISH_EXIT + if (anum == 1 && VMSISH_EXIT) + anum = 0; +#endif + } my_exit(anum); PUSHs(&sv_undef); RETURN; @@ -1934,29 +2060,74 @@ SV *sv; } static OP * +docatch(o) +OP *o; +{ + int ret; + I32 oldrunlevel = runlevel; + OP *oldop = op; + dJMPENV; + + op = o; +#ifdef DEBUGGING + assert(CATCH_GET == TRUE); + DEBUG_l(deb("(Setting up local jumplevel, runlevel = %ld)\n", (long)runlevel+1)); +#endif + JMPENV_PUSH(ret); + switch (ret) { + default: /* topmost level handles it */ + JMPENV_POP; + runlevel = oldrunlevel; + op = oldop; + JMPENV_JUMP(ret); + /* NOTREACHED */ + case 3: + if (!restartop) { + PerlIO_printf(PerlIO_stderr(), "panic: restartop\n"); + break; + } + op = restartop; + restartop = 0; + /* FALL THROUGH */ + case 0: + runops(); + break; + } + JMPENV_POP; + runlevel = oldrunlevel; + op = oldop; + return Nullop; +} + +static OP * doeval(gimme) int gimme; { dSP; OP *saveop = op; HV *newstash; + CV *caller; AV* comppadlist; in_eval = 1; + PUSHMARK(SP); + /* set up a scratch pad */ - SAVEINT(padix); + SAVEI32(padix); SAVESPTR(curpad); SAVESPTR(comppad); SAVESPTR(comppad_name); - SAVEINT(comppad_name_fill); - SAVEINT(min_intro_pending); - SAVEINT(max_intro_pending); + SAVEI32(comppad_name_fill); + SAVEI32(min_intro_pending); + SAVEI32(max_intro_pending); + caller = compcv; SAVESPTR(compcv); compcv = (CV*)NEWSV(1104,0); sv_upgrade((SV *)compcv, SVt_PVCV); + CvUNIQUE_on(compcv); comppad = newAV(); comppad_name = newAV(); @@ -1971,6 +2142,10 @@ int gimme; av_store(comppadlist, 0, (SV*)comppad_name); av_store(comppadlist, 1, (SV*)comppad); CvPADLIST(compcv) = comppadlist; + + if (saveop->op_type != OP_REQUIRE) + CvOUTSIDE(compcv) = (CV*)SvREFCNT_inc(caller); + SAVEFREESV(compcv); /* make sure we compile in the right package */ @@ -1992,7 +2167,10 @@ int gimme; curcop->cop_arybase = 0; SvREFCNT_dec(rs); rs = newSVpv("\n", 1); - sv_setpv(GvSV(errgv),""); + if (saveop->op_flags & OPf_SPECIAL) + in_eval |= 4; + else + sv_setpv(GvSV(errgv),""); if (yyparse() || error_count || !eval_root) { SV **newsp; I32 gimme; @@ -2004,13 +2182,16 @@ int gimme; op_free(eval_root); eval_root = Nullop; } + SP = stack_base + POPMARK; /* pop original mark */ POPBLOCK(cx,curpm); POPEVAL(cx); pop_return(); lex_end(); LEAVE; - if (optype == OP_REQUIRE) - DIE("%s", SvPVx(GvSV(errgv), na)); + if (optype == OP_REQUIRE) { + char* msg = SvPVx(GvSV(errgv), na); + DIE("%s", *msg ? msg : "Compilation failed in require"); + } SvREFCNT_dec(rs); rs = SvREFCNT_inc(nrs); RETPUSHUNDEF; @@ -2019,15 +2200,33 @@ int gimme; rs = SvREFCNT_inc(nrs); compiling.cop_line = 0; SAVEFREEOP(eval_root); - if (gimme & G_ARRAY) + if (gimme & G_VOID) + scalarvoid(eval_root); + else if (gimme & G_ARRAY) list(eval_root); else scalar(eval_root); DEBUG_x(dump_eval()); + /* Register with debugger: */ + if (PERLDB_INTER && saveop->op_type == OP_REQUIRE) { + CV *cv = perl_get_cv("DB::postponed", FALSE); + if (cv) { + dSP; + PUSHMARK(sp); + XPUSHs((SV*)compiling.cop_filegv); + PUTBACK; + perl_call_sv((SV*)cv, G_DISCARD); + } + } + /* compiled okay, so do it */ + CvDEPTH(compcv) = 1; + + SP = stack_base + POPMARK; /* pop original mark */ + op = saveop; /* The caller may need it. */ RETURNOP(eval_start); } @@ -2037,13 +2236,15 @@ PP(pp_require) register CONTEXT *cx; SV *sv; char *name; - char *tmpname; + char *tryname; + SV *namesv = Nullsv; SV** svp; I32 gimme = G_SCALAR; - FILE *tryrsfp = 0; + PerlIO *tryrsfp = 0; sv = POPs; if (SvNIOKp(sv) && !SvPOKp(sv)) { + SET_NUMERIC_STANDARD(); if (atof(patchlevel) + 0.00000999 < SvNV(sv)) DIE("Perl %s required--this is only version %s, stopped", SvPV(sv,na),patchlevel); @@ -2060,59 +2261,77 @@ PP(pp_require) /* prepare to compile file */ - tmpname = savepv(name); - if (*tmpname == '/' || - (*tmpname == '.' && - (tmpname[1] == '/' || - (tmpname[1] == '.' && tmpname[2] == '/'))) + if (*name == '/' || + (*name == '.' && + (name[1] == '/' || + (name[1] == '.' && name[2] == '/'))) #ifdef DOSISH - || (tmpname[0] && tmpname[1] == ':') + || (name[0] && name[1] == ':') +#endif +#ifdef WIN32 + || (name[0] == '\\' && name[1] == '\\') /* UNC path */ #endif #ifdef VMS - || (strchr(tmpname,':') || ((*tmpname == '[' || *tmpname == '<') && - (tmpname[1] == '-' || tmpname[1] == ']' || tmpname[1] == '>'))) + || (strchr(name,':') || ((*name == '[' || *name == '<') && + (isALNUM(name[1]) || strchr("$-_]>",name[1])))) #endif ) { - tryrsfp = fopen(tmpname,"r"); + tryname = name; + tryrsfp = PerlIO_open(name,"r"); } else { AV *ar = GvAVn(incgv); I32 i; - - for (i = 0; i <= AvFILL(ar); i++) { #ifdef VMS - if (tounixpath_ts(SvPVx(*av_fetch(ar, i, TRUE), na),buf) == NULL) - continue; - strcat(buf,name); + char *unixname; + if ((unixname = tounixspec(name, Nullch)) != Nullch) +#endif + { + namesv = NEWSV(806, 0); + for (i = 0; i <= AvFILL(ar); i++) { + char *dir = SvPVx(*av_fetch(ar, i, TRUE), na); +#ifdef VMS + char *unixdir; + if ((unixdir = tounixpath(dir, Nullch)) == Nullch) + continue; + sv_setpv(namesv, unixdir); + sv_catpv(namesv, unixname); #else - (void)sprintf(buf, "%s/%s", - SvPVx(*av_fetch(ar, i, TRUE), na), name); + sv_setpvf(namesv, "%s/%s", dir, name); #endif - tryrsfp = fopen(buf, "r"); - if (tryrsfp) { - char *s = buf; - - if (*s == '.' && s[1] == '/') - s += 2; - Safefree(tmpname); - tmpname = savepv(s); - break; + tryname = SvPVX(namesv); + tryrsfp = PerlIO_open(tryname, "r"); + if (tryrsfp) { + if (tryname[0] == '.' && tryname[1] == '/') + tryname += 2; + break; + } } } } SAVESPTR(compiling.cop_filegv); - compiling.cop_filegv = gv_fetchfile(tmpname); - Safefree(tmpname); - tmpname = Nullch; + compiling.cop_filegv = gv_fetchfile(tryrsfp ? tryname : name); + SvREFCNT_dec(namesv); if (!tryrsfp) { if (op->op_type == OP_REQUIRE) { - sprintf(tokenbuf,"Can't locate %s in @INC", name); - if (instr(tokenbuf,".h ")) - strcat(tokenbuf," (change .h to .ph maybe?)"); - if (instr(tokenbuf,".ph ")) - strcat(tokenbuf," (did you run h2ph?)"); - DIE("%s",tokenbuf); + SV *msg = sv_2mortal(newSVpvf("Can't locate %s in @INC", name)); + SV *dirmsgsv = NEWSV(0, 0); + AV *ar = GvAVn(incgv); + I32 i; + if (instr(SvPVX(msg), ".h ")) + sv_catpv(msg, " (change .h to .ph maybe?)"); + if (instr(SvPVX(msg), ".ph ")) + sv_catpv(msg, " (did you run h2ph?)"); + sv_catpv(msg, " (@INC contains:"); + for (i = 0; i <= AvFILL(ar); i++) { + char *dir = SvPVx(*av_fetch(ar, i, TRUE), na); + sv_setpvf(dirmsgsv, " %s", dir); + sv_catsv(msg, dirmsgsv); + } + sv_catpvn(msg, ")", 1); + SvREFCNT_dec(dirmsgsv); + DIE("%_", msg); } RETPUSHUNDEF; @@ -2145,7 +2364,7 @@ PP(pp_require) compiling.cop_line = 0; PUTBACK; - return doeval(G_SCALAR); + return DOCATCH(doeval(G_SCALAR)); } PP(pp_dofile) @@ -2158,9 +2377,11 @@ PP(pp_entereval) dSP; register CONTEXT *cx; dPOPss; - I32 gimme = GIMME; - char tmpbuf[32]; + I32 gimme = GIMME_V, was = sub_generation; + char tmpbuf[TYPE_DIGITS(long) + 12]; + char *safestr; STRLEN len; + OP *ret; if (!SvPV(sv,len) || !len) RETPUSHUNDEF; @@ -2173,10 +2394,16 @@ PP(pp_entereval) /* switch to eval mode */ SAVESPTR(compiling.cop_filegv); - sprintf(tmpbuf, "_<(eval %d)", ++evalseq); + sprintf(tmpbuf, "_<(eval %lu)", (unsigned long)++evalseq); compiling.cop_filegv = gv_fetchfile(tmpbuf+2); compiling.cop_line = 1; - SAVEDELETE(defstash, savepv(tmpbuf), strlen(tmpbuf)); + /* XXX For C<eval "...">s within BEGIN {} blocks, this ends up + deleting the eval's FILEGV from the stash before gv_check() runs + (i.e. before run-time proper). To work around the coredump that + ensues, we always turn GvMULTI_on for any globals that were + introduced within evals. See force_ident(). GSAR 96-10-12 */ + safestr = savepv(tmpbuf); + SAVEDELETE(defstash, safestr, strlen(safestr)); SAVEI32(hints); hints = op->op_targ; @@ -2186,10 +2413,15 @@ PP(pp_entereval) /* prepare to compile string */ - if (perldb && curstash != debstash) + if (PERLDB_LINE && curstash != debstash) save_lines(GvAV(compiling.cop_filegv), linestr); PUTBACK; - return doeval(gimme); + ret = doeval(gimme); + if (PERLDB_INTER && was != sub_generation /* Some subs defined here. */ + && ret != op->op_next) { /* Successive compilation. */ + strcpy(safestr, "_<(eval )"); /* Anything fake and short. */ + } + return DOCATCH(ret); } PP(pp_leaveeval) @@ -2201,53 +2433,89 @@ PP(pp_leaveeval) I32 gimme; register CONTEXT *cx; OP *retop; + U8 save_flags = op -> op_flags; I32 optype; POPBLOCK(cx,newpm); POPEVAL(cx); retop = pop_return(); - if (gimme == G_SCALAR) { - if (op->op_private & OPpLEAVE_VOID) - MARK = newsp; + TAINT_NOT; + if (gimme == G_VOID) + MARK = newsp; + else if (gimme == G_SCALAR) { + MARK = newsp + 1; + if (MARK <= SP) { + if (SvFLAGS(TOPs) & SVs_TEMP) + *MARK = TOPs; + else + *MARK = sv_mortalcopy(TOPs); + } else { - MARK = newsp + 1; - if (MARK <= SP) { - if (SvFLAGS(TOPs) & SVs_TEMP) - *MARK = TOPs; - else - *MARK = sv_mortalcopy(TOPs); - } - else { - MEXTEND(mark,0); - *MARK = &sv_undef; - } + MEXTEND(mark,0); + *MARK = &sv_undef; } - SP = MARK; } else { - for (mark = newsp + 1; mark <= SP; mark++) - if (!(SvFLAGS(TOPs) & SVs_TEMP)) + /* in case LEAVE wipes old return values */ + for (mark = newsp + 1; mark <= SP; mark++) { + if (!(SvFLAGS(*mark) & SVs_TEMP)) { *mark = sv_mortalcopy(*mark); - /* in case LEAVE wipes old return values */ + TAINT_NOT; /* Each item is independent */ + } + } } curpm = newpm; /* Don't pop $1 et al till now */ - if (optype != OP_ENTEREVAL) { - char *name = cx->blk_eval.old_name; + /* + * Closures mentioned at top level of eval cannot be referenced + * again, and their presence indirectly causes a memory leak. + * (Note that the fact that compcv and friends are still set here + * is, AFAIK, an accident.) --Chip + */ + if (AvFILL(comppad_name) >= 0) { + SV **svp = AvARRAY(comppad_name); + I32 ix; + for (ix = AvFILL(comppad_name); ix >= 0; ix--) { + SV *sv = svp[ix]; + if (sv && sv != &sv_undef && *SvPVX(sv) == '&') { + SvREFCNT_dec(sv); + svp[ix] = &sv_undef; + + sv = curpad[ix]; + if (CvCLONE(sv)) { + SvREFCNT_dec(CvOUTSIDE(sv)); + CvOUTSIDE(sv) = Nullcv; + } + else { + SvREFCNT_dec(sv); + sv = NEWSV(0,0); + SvPADTMP_on(sv); + curpad[ix] = sv; + } + } + } + } - if (!(gimme == G_SCALAR ? SvTRUE(*sp) : sp > newsp)) { - /* Unassume the success we assumed earlier. */ - (void)hv_delete(GvHVn(incgv), name, strlen(name), G_DISCARD); +#ifdef DEBUGGING + assert(CvDEPTH(compcv) == 1); +#endif + CvDEPTH(compcv) = 0; - if (optype == OP_REQUIRE) - retop = die("%s did not return a true value", name); - } + if (optype == OP_REQUIRE && + !(gimme == G_SCALAR ? SvTRUE(*sp) : sp > newsp)) + { + /* Unassume the success we assumed earlier. */ + char *name = cx->blk_eval.old_name; + (void)hv_delete(GvHVn(incgv), name, strlen(name), G_DISCARD); + retop = die("%s did not return a true value", name); } lex_end(); LEAVE; - sv_setpv(GvSV(errgv),""); + + if (!(save_flags & OPf_SPECIAL)) + sv_setpv(GvSV(errgv),""); RETURNOP(retop); } @@ -2256,7 +2524,7 @@ PP(pp_entertry) { dSP; register CONTEXT *cx; - I32 gimme = GIMME; + I32 gimme = GIMME_V; ENTER; SAVETMPS; @@ -2268,7 +2536,8 @@ PP(pp_entertry) in_eval = 1; sv_setpv(GvSV(errgv),""); - RETURN; + PUTBACK; + return DOCATCH(op->op_next); } PP(pp_leavetry) @@ -2285,29 +2554,31 @@ PP(pp_leavetry) POPEVAL(cx); pop_return(); - if (gimme == G_SCALAR) { - if (op->op_private & OPpLEAVE_VOID) - MARK = newsp; + TAINT_NOT; + if (gimme == G_VOID) + SP = newsp; + else if (gimme == G_SCALAR) { + MARK = newsp + 1; + if (MARK <= SP) { + if (SvFLAGS(TOPs) & (SVs_PADTMP|SVs_TEMP)) + *MARK = TOPs; + else + *MARK = sv_mortalcopy(TOPs); + } else { - MARK = newsp + 1; - if (MARK <= SP) { - if (SvFLAGS(TOPs) & (SVs_PADTMP|SVs_TEMP)) - *MARK = TOPs; - else - *MARK = sv_mortalcopy(TOPs); - } - else { - MEXTEND(mark,0); - *MARK = &sv_undef; - } + MEXTEND(mark,0); + *MARK = &sv_undef; } SP = MARK; } else { - for (mark = newsp + 1; mark <= SP; mark++) - if (!(SvFLAGS(TOPs) & (SVs_PADTMP|SVs_TEMP))) + /* in case LEAVE wipes old return values */ + for (mark = newsp + 1; mark <= SP; mark++) { + if (!(SvFLAGS(*mark) & (SVs_PADTMP|SVs_TEMP))) { *mark = sv_mortalcopy(*mark); - /* in case LEAVE wipes old return values */ + TAINT_NOT; /* Each item is independent */ + } + } } curpm = newpm; /* Don't pop $1 et al till now */ @@ -2334,7 +2605,10 @@ SV *sv; register I32 arg; bool ischop; - New(804, fops, (send - s)*3+2, U16); /* Almost certainly too long... */ + if (len == 0) + croak("Null picture in formline"); + + New(804, fops, (send - s)*3+10, U16); /* Almost certainly too long... */ fpc = fops; if (s < send) { @@ -2367,13 +2641,12 @@ SV *sv; skipspaces++; arg -= skipspaces; if (arg) { - if (postspace) { + if (postspace) *fpc++ = FF_SPACE; - postspace = FALSE; - } *fpc++ = FF_LITERAL; *fpc++ = arg; } + postspace = FALSE; if (s <= send) skipspaces--; if (skipspaces) { @@ -2489,5 +2762,6 @@ SV *sv; } Copy(fops, s, arg, U16); Safefree(fops); + sv_magic(sv, Nullsv, 'f', Nullch, 0); SvCOMPILED_on(sv); } diff --git a/gnu/usr.bin/perl/pp_hot.c b/gnu/usr.bin/perl/pp_hot.c index 8fe39f37f7b..e1f4476dda8 100644 --- a/gnu/usr.bin/perl/pp_hot.c +++ b/gnu/usr.bin/perl/pp_hot.c @@ -1,6 +1,6 @@ /* pp_hot.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -76,64 +76,6 @@ PP(pp_gv) RETURN; } -PP(pp_gelem) -{ - GV *gv; - SV *sv; - SV *ref; - char *elem; - dSP; - - sv = POPs; - elem = SvPV(sv, na); - gv = (GV*)POPs; - ref = Nullsv; - sv = Nullsv; - switch (elem ? *elem : '\0') - { - case 'A': - if (strEQ(elem, "ARRAY")) - ref = (SV*)GvAV(gv); - break; - case 'C': - if (strEQ(elem, "CODE")) - ref = (SV*)GvCV(gv); - break; - case 'F': - if (strEQ(elem, "FILEHANDLE")) - ref = (SV*)GvIOp(gv); - break; - case 'G': - if (strEQ(elem, "GLOB")) - ref = (SV*)gv; - break; - case 'H': - if (strEQ(elem, "HASH")) - ref = (SV*)GvHV(gv); - break; - case 'N': - if (strEQ(elem, "NAME")) - sv = newSVpv(GvNAME(gv), GvNAMELEN(gv)); - break; - case 'P': - if (strEQ(elem, "PACKAGE")) - sv = newSVpv(HvNAME(GvSTASH(gv)), 0); - break; - case 'S': - if (strEQ(elem, "SCALAR")) - ref = GvSV(gv); - break; - } - if (ref) - sv = newRV(ref); - if (sv) - sv_2mortal(sv); - else - sv = &sv_undef; - XPUSHs(sv); - RETURN; -} - PP(pp_and) { dSP; @@ -154,13 +96,9 @@ PP(pp_sassign) SV *temp; temp = left; left = right; right = temp; } - if (tainting && tainted && (!SvGMAGICAL(left) || !SvSMAGICAL(left) || - !((mg = mg_find(left, 't')) && mg->mg_len & 1))) - { + if (tainting && tainted && !SvTAINTED(left)) TAINT_NOT; - } - SvSetSV(right, left); - SvSETMAGIC(right); + SvSetMagicSV(right, left); SETs(right); RETURN; } @@ -185,16 +123,6 @@ PP(pp_unstack) return NORMAL; } -PP(pp_seq) -{ - dSP; tryAMAGICbinSET(seq,0); - { - dPOPTOPssrl; - SETs( sv_eq(left, right) ? &sv_yes : &sv_no ); - RETURN; - } -} - PP(pp_concat) { dSP; dATARGET; tryAMAGICbin(concat,opASSIGN); @@ -208,12 +136,15 @@ PP(pp_concat) } else if (SvGMAGICAL(TARG)) mg_get(TARG); - else if (!SvOK(TARG)) { - s = SvPV_force(TARG, len); + else if (!SvOK(TARG) && SvTYPE(TARG) <= SVt_PVMG) { sv_setpv(TARG, ""); /* Suppress warning. */ + s = SvPV_force(TARG, len); } s = SvPV(right,len); - sv_catpvn(TARG,s,len); + if (SvOK(TARG)) + sv_catpvn(TARG,s,len); + else + sv_setpvn(TARG,s,len); /* suppress warning */ SETTARG; RETURN; } @@ -226,8 +157,8 @@ PP(pp_padsv) if (op->op_flags & OPf_MOD) { if (op->op_private & OPpLVAL_INTRO) SAVECLEARSV(curpad[op->op_targ]); - else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV)) - provide_ref(op, curpad[op->op_targ]); + else if (op->op_private & OPpDEREF) + vivify_ref(curpad[op->op_targ], op->op_private & OPpDEREF); } RETURN; } @@ -243,7 +174,7 @@ PP(pp_eq) dSP; tryAMAGICbinSET(eq,0); { dPOPnv; - SETs((TOPn == value) ? &sv_yes : &sv_no); + SETs(boolSV(TOPn == value)); RETURN; } } @@ -251,9 +182,13 @@ PP(pp_eq) PP(pp_preinc) { dSP; - if (SvIOK(TOPs)) { + if (SvREADONLY(TOPs) || SvTYPE(TOPs) > SVt_PVLV) + croak(no_modify); + if (SvIOK(TOPs) && !SvNOK(TOPs) && !SvPOK(TOPs) && + SvIVX(TOPs) != IV_MAX) + { ++SvIVX(TOPs); - SvFLAGS(TOPs) &= ~(SVf_NOK|SVf_POK|SVp_NOK|SVp_POK); + SvFLAGS(TOPs) &= ~(SVp_NOK|SVp_POK); } else sv_inc(TOPs); @@ -276,7 +211,7 @@ PP(pp_add) { dSP; dATARGET; tryAMAGICbin(add,opASSIGN); { - dPOPTOPnnrl; + dPOPTOPnnrl_ul; SETn( left + right ); RETURN; } @@ -304,7 +239,19 @@ PP(pp_join) PP(pp_pushre) { dSP; +#ifdef DEBUGGING + /* + * We ass_u_me that LvTARGOFF() comes first, and that two STRLENs + * will be enough to hold an OP*. + */ + SV* sv = sv_newmortal(); + sv_upgrade(sv, SVt_PVLV); + LvTYPE(sv) = '/'; + Copy(&op, &LvTARGOFF(sv), 1, OP*); + XPUSHs(sv); +#else XPUSHs((SV*)op); +#endif RETURN; } @@ -315,16 +262,36 @@ PP(pp_print) dSP; dMARK; dORIGMARK; GV *gv; IO *io; - register FILE *fp; + register PerlIO *fp; + MAGIC *mg; if (op->op_flags & OPf_STACKED) gv = (GV*)*++MARK; else gv = defoutgv; + if (SvMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) { + if (MARK == ORIGMARK) { + EXTEND(SP, 1); + ++MARK; + Move(MARK, MARK + 1, (SP - MARK) + 1, SV*); + ++SP; + } + PUSHMARK(MARK - 1); + *MARK = mg->mg_obj; + PUTBACK; + ENTER; + perl_call_method("PRINT", G_SCALAR); + LEAVE; + SPAGAIN; + MARK = ORIGMARK + 1; + *MARK = *SP; + SP = MARK; + RETURN; + } if (!(io = GvIO(gv))) { if (dowarn) { SV* sv = sv_newmortal(); - gv_fullname(sv,gv); + gv_fullname3(sv, gv, Nullch); warn("Filehandle %s never opened", SvPV(sv,na)); } @@ -334,7 +301,7 @@ PP(pp_print) else if (!(fp = IoOFP(io))) { if (dowarn) { SV* sv = sv_newmortal(); - gv_fullname(sv,gv); + gv_fullname3(sv, gv, Nullch); if (IoIFP(io)) warn("Filehandle %s opened only for input", SvPV(sv,na)); else @@ -351,7 +318,7 @@ PP(pp_print) break; MARK++; if (MARK <= SP) { - if (fwrite1(ofs, 1, ofslen, fp) == 0 || ferror(fp)) { + if (PerlIO_write(fp, ofs, ofslen) == 0 || PerlIO_error(fp)) { MARK--; break; } @@ -369,11 +336,11 @@ PP(pp_print) goto just_say_no; else { if (orslen) - if (fwrite1(ors, 1, orslen, fp) == 0 || ferror(fp)) + if (PerlIO_write(fp, ors, orslen) == 0 || PerlIO_error(fp)) goto just_say_no; if (IoFLAGS(io) & IOf_FLUSH) - if (Fflush(fp) == EOF) + if (PerlIO_flush(fp) == EOF) goto just_say_no; } } @@ -390,7 +357,6 @@ PP(pp_print) PP(pp_rv2av) { dSP; dPOPss; - AV *av; if (SvROK(sv)) { @@ -398,8 +364,6 @@ PP(pp_rv2av) av = (AV*)SvRV(sv); if (SvTYPE(av) != SVt_PVAV) DIE("Not an ARRAY reference"); - if (op->op_private & OPpLVAL_INTRO) - av = (AV*)save_svref((SV**)sv); if (op->op_flags & OPf_REF) { PUSHs((SV*)av); RETURN; @@ -414,6 +378,8 @@ PP(pp_rv2av) } } else { + GV *gv; + if (SvTYPE(sv) != SVt_PVGV) { char *sym; @@ -426,6 +392,8 @@ PP(pp_rv2av) if (op->op_flags & OPf_REF || op->op_private & HINT_STRICT_REFS) DIE(no_usym, "an ARRAY"); + if (dowarn) + warn(warn_uninit); if (GIMME == G_ARRAY) RETURN; RETPUSHUNDEF; @@ -433,11 +401,13 @@ PP(pp_rv2av) sym = SvPV(sv,na); if (op->op_private & HINT_STRICT_REFS) DIE(no_symref, sym, "an ARRAY"); - sv = (SV*)gv_fetchpv(sym, TRUE, SVt_PVAV); + gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PVAV); + } else { + gv = (GV*)sv; } - av = GvAVn(sv); + av = GvAVn(gv); if (op->op_private & OPpLVAL_INTRO) - av = save_ary(sv); + av = save_ary(gv); if (op->op_flags & OPf_REF) { PUSHs((SV*)av); RETURN; @@ -461,9 +431,7 @@ PP(pp_rv2av) PP(pp_rv2hv) { - dSP; dTOPss; - HV *hv; if (SvROK(sv)) { @@ -471,8 +439,6 @@ PP(pp_rv2hv) hv = (HV*)SvRV(sv); if (SvTYPE(hv) != SVt_PVHV) DIE("Not a HASH reference"); - if (op->op_private & OPpLVAL_INTRO) - hv = (HV*)save_svref((SV**)sv); if (op->op_flags & OPf_REF) { SETs((SV*)hv); RETURN; @@ -487,6 +453,8 @@ PP(pp_rv2hv) } } else { + GV *gv; + if (SvTYPE(sv) != SVt_PVGV) { char *sym; @@ -499,6 +467,8 @@ PP(pp_rv2hv) if (op->op_flags & OPf_REF || op->op_private & HINT_STRICT_REFS) DIE(no_usym, "a HASH"); + if (dowarn) + warn(warn_uninit); if (GIMME == G_ARRAY) { SP--; RETURN; @@ -508,11 +478,13 @@ PP(pp_rv2hv) sym = SvPV(sv,na); if (op->op_private & HINT_STRICT_REFS) DIE(no_symref, sym, "a HASH"); - sv = (SV*)gv_fetchpv(sym, TRUE, SVt_PVHV); + gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PVHV); + } else { + gv = (GV*)sv; } - hv = GvHVn(sv); + hv = GvHVn(gv); if (op->op_private & OPpLVAL_INTRO) - hv = save_hash(sv); + hv = save_hash(gv); if (op->op_flags & OPf_REF) { SETs((SV*)hv); RETURN; @@ -526,10 +498,9 @@ PP(pp_rv2hv) } else { dTARGET; - if (HvFILL(hv)) { - sprintf(buf, "%d/%d", HvFILL(hv), HvMAX(hv)+1); - sv_setpv(TARG, buf); - } + if (HvFILL(hv)) + sv_setpvf(TARG, "%ld/%ld", + (long)HvFILL(hv), (long)HvMAX(hv) + 1); else sv_setiv(TARG, 0); SETTARG; @@ -551,6 +522,7 @@ PP(pp_aassign) register SV *sv; register AV *ary; + I32 gimme; HV *hash; I32 i; int magic; @@ -564,8 +536,10 @@ PP(pp_aassign) if (op->op_private & OPpASSIGN_COMMON) { for (relem = firstrelem; relem <= lastrelem; relem++) { /*SUPPRESS 560*/ - if (sv = *relem) + if (sv = *relem) { + TAINT_NOT; /* Each item is independent */ *relem = sv_mortalcopy(sv); + } } } @@ -574,7 +548,7 @@ PP(pp_aassign) ary = Null(AV*); hash = Null(HV*); while (lelem <= lastlelem) { - tainted = 0; /* Each item stands on its own, taintwise. */ + TAINT_NOT; /* Each item stands on its own, taintwise. */ sv = *lelem++; switch (SvTYPE(sv)) { case SVt_PVAV: @@ -582,20 +556,25 @@ PP(pp_aassign) magic = SvMAGICAL(ary) != 0; av_clear(ary); + av_extend(ary, lastrelem - relem); i = 0; while (relem <= lastrelem) { /* gobble up all the rest */ + SV **didstore; sv = NEWSV(28,0); assert(*relem); sv_setsv(sv,*relem); *(relem++) = sv; - (void)av_store(ary,i++,sv); - if (magic) - mg_set(sv); - tainted = 0; + didstore = av_store(ary,i++,sv); + if (magic) { + if (SvSMAGICAL(sv)) + mg_set(sv); + if (!didstore) + SvREFCNT_dec(sv); + } + TAINT_NOT; } break; case SVt_PVHV: { - char *tmps; SV *tmpstr; hash = (HV*)sv; @@ -604,20 +583,26 @@ PP(pp_aassign) while (relem < lastrelem) { /* gobble up all the rest */ STRLEN len; + HE *didstore; if (*relem) sv = *(relem++); else sv = &sv_no, relem++; - tmps = SvPV(sv, len); tmpstr = NEWSV(29,0); if (*relem) sv_setsv(tmpstr,*relem); /* value */ *(relem++) = tmpstr; - (void)hv_store(hash,tmps,len,tmpstr,0); - if (magic) - mg_set(tmpstr); - tainted = 0; + didstore = hv_store_ent(hash,sv,tmpstr,0); + if (magic) { + if (SvSMAGICAL(tmpstr)) + mg_set(tmpstr); + if (!didstore) + SvREFCNT_dec(tmpstr); + } + TAINT_NOT; } + if (relem == lastrelem && dowarn) + warn("Odd number of elements in hash list"); } break; default: @@ -704,20 +689,25 @@ PP(pp_aassign) tainting |= (uid && (euid != uid || egid != gid)); } delaymagic = 0; - if (GIMME == G_ARRAY) { + + gimme = GIMME_V; + if (gimme == G_VOID) + SP = firstrelem - 1; + else if (gimme == G_SCALAR) { + dTARGET; + SP = firstrelem; + SETi(lastrelem - firstrelem + 1); + } + else { if (ary || hash) SP = lastrelem; else SP = firstrelem + (lastlelem - firstlelem); - RETURN; - } - else { - dTARGET; - SP = firstrelem; - - SETi(lastrelem - firstrelem + 1); - RETURN; + lelem = firstlelem + (relem - firstrelem); + while (relem <= SP) + *relem++ = (lelem <= lastlelem) ? *lelem++ : &sv_undef; } + RETURN; } PP(pp_match) @@ -735,6 +725,7 @@ PP(pp_match) STRLEN len; I32 minmatch = 0; I32 oldsave = savestack_ix; + I32 update_minmatch = 1; if (op->op_flags & OPf_STACKED) TARG = POPs; @@ -746,6 +737,7 @@ PP(pp_match) strend = s + len; if (!s) DIE("panic: do_match"); + TAINT_NOT; if (pm->op_pmflags & PMf_USED) { if (gimme == G_ARRAY) @@ -765,12 +757,14 @@ PP(pp_match) if (mg && mg->mg_len >= 0) { rx->endp[0] = rx->startp[0] = s + mg->mg_len; minmatch = (mg->mg_flags & MGf_MINMATCH); + update_minmatch = 0; } } } if (!rx->nparens && !global) gimme = G_SCALAR; /* accidental array context? */ - safebase = (gimme == G_ARRAY) || global; + safebase = (((gimme == G_ARRAY) || global || !rx->nparens) + && !sawampersand); if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) { SAVEINT(multiline); multiline = pm->op_pmflags & PMf_MULTILINE; @@ -779,9 +773,10 @@ PP(pp_match) play_it_again: if (global && rx->startp[0]) { t = s = rx->endp[0]; - if (s > strend) + if ((s + rx->minlen) > strend) goto nope; - minmatch = (s == rx->startp[0]); + if (update_minmatch++) + minmatch = (s == rx->startp[0]); } if (pm->op_pmshort) { if (pm->op_pmflags & PMf_SCANFIRST) { @@ -808,15 +803,10 @@ play_it_again: s = t; } else if (!multiline) { - if (*SvPVX(pm->op_pmshort) != *s || - bcmp(SvPVX(pm->op_pmshort), s, pm->op_pmslen) ) { - if (pm->op_pmflags & PMf_FOLD) { - if (ibcmp((U8*)SvPVX(pm->op_pmshort), (U8*)s, pm->op_pmslen) ) - goto nope; - } - else - goto nope; - } + if (*SvPVX(pm->op_pmshort) != *s + || (pm->op_pmslen > 1 + && memNE(SvPVX(pm->op_pmshort), s, pm->op_pmslen))) + goto nope; } if (!rx->naughty && --BmUSEFUL(pm->op_pmshort) < 0) { SvREFCNT_dec(pm->op_pmshort); @@ -824,8 +814,8 @@ play_it_again: } } if (pregexec(rx, s, strend, truebase, minmatch, - SvSCREAM(TARG) ? TARG : Nullsv, - safebase)) { + SvSCREAM(TARG) ? TARG : Nullsv, safebase)) + { curpm = pm; if (pm->op_pmflags & PMf_ONCE) pm->op_pmflags |= PMf_USED; @@ -836,6 +826,7 @@ play_it_again: /*NOTREACHED*/ gotcha: + TAINT_IF(rx->exec_tainted); if (gimme == G_ARRAY) { I32 iters, i, len; @@ -845,6 +836,7 @@ play_it_again: else i = 0; EXTEND(SP, iters + i); + EXTEND_MORTAL(iters + i); for (i = !i; i <= iters; i++) { PUSHs(sv_newmortal()); /*SUPPRESS 560*/ @@ -855,6 +847,7 @@ play_it_again: } if (global) { truebase = rx->subbeg; + strend = rx->subend; if (rx->startp[0] && rx->startp[0] == rx->endp[0]) ++rx->endp[0]; goto play_it_again; @@ -872,24 +865,25 @@ play_it_again: mg = mg_find(TARG, 'g'); } if (rx->startp[0]) { - mg->mg_len = rx->endp[0] - truebase; + mg->mg_len = rx->endp[0] - rx->subbeg; if (rx->startp[0] == rx->endp[0]) mg->mg_flags |= MGf_MINMATCH; else mg->mg_flags &= ~MGf_MINMATCH; } - else - mg->mg_len = -1; } LEAVE_SCOPE(oldsave); RETPUSHYES; } yup: + TAINT_IF(rx->exec_tainted); ++BmUSEFUL(pm->op_pmshort); curpm = pm; if (pm->op_pmflags & PMf_ONCE) pm->op_pmflags |= PMf_USED; + Safefree(rx->subbase); + rx->subbase = Nullch; if (global) { rx->subbeg = truebase; rx->subend = strend; @@ -900,8 +894,6 @@ yup: if (sawampersand) { char *tmps; - if (rx->subbase) - Safefree(rx->subbase); tmps = rx->subbase = savepvn(t, strend-t); rx->subbeg = tmps; rx->subend = tmps + (strend-t); @@ -916,7 +908,7 @@ nope: ++BmUSEFUL(pm->op_pmshort); ret_no: - if (global) { + if (global && !(pm->op_pmflags & PMf_CONTINUE)) { if (SvTYPE(TARG) >= SVt_PVMG && SvMAGIC(TARG)) { MAGIC* mg = mg_find(TARG, 'g'); if (mg) @@ -936,10 +928,24 @@ do_readline() register SV *sv; STRLEN tmplen = 0; STRLEN offset; - FILE *fp; + PerlIO *fp; register IO *io = GvIO(last_in_gv); register I32 type = op->op_type; + I32 gimme = GIMME_V; + MAGIC *mg; + if (SvMAGICAL(last_in_gv) && (mg = mg_find((SV*)last_in_gv, 'q'))) { + PUSHMARK(SP); + XPUSHs(mg->mg_obj); + PUTBACK; + ENTER; + perl_call_method("READLINE", gimme); + LEAVE; + SPAGAIN; + if (gimme == G_SCALAR) + SvSetMagicSV_nosteal(TARG, TOPs); + RETURN; + } fp = Nullfp; if (io) { fp = IoIFP(io); @@ -976,7 +982,7 @@ do_readline() char *rstr = rslt + sizeof(unsigned short int), *begin, *end, *cp; char tmpfnam[L_tmpnam] = "SYS$SCRATCH:"; $DESCRIPTOR(dfltdsc,"SYS$DISK:[]*.*;"); - FILE *tmpfp; + PerlIO *tmpfp; STRLEN i; struct dsc$descriptor_s wilddsc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0}; @@ -1006,7 +1012,7 @@ do_readline() break; } } - if ((tmpfp = fopen(tmpfnam,"w+","fop=dlt")) != NULL) { + if ((tmpfp = PerlIO_open(tmpfnam,"w+","fop=dlt")) != NULL) { ok = ((wilddsc.dsc$a_pointer = tovmsspec(SvPVX(tmpglob),vmsspec)) != NULL); if (ok) wilddsc.dsc$w_length = (unsigned short int) strlen(wilddsc.dsc$a_pointer); while (ok && ((sts = lib$find_file(&wilddsc,&rsdsc,&cxt, @@ -1016,7 +1022,7 @@ do_readline() *(end++) = '\n'; *end = '\0'; for (cp = rstr; *cp; cp++) *cp = _tolower(*cp); if (hasdir) { - if (isunix) trim_unixpath(rstr,SvPVX(tmpglob)); + if (isunix) trim_unixpath(rstr,SvPVX(tmpglob),1); begin = rstr; } else { @@ -1024,7 +1030,7 @@ do_readline() while (*(--begin) != ']' && *begin != '>') ; ++begin; } - ok = (fputs(begin,tmpfp) != EOF); + ok = (PerlIO_puts(tmpfp,begin) != EOF); } if (cxt) (void)lib$find_file_end(&cxt); if (ok && sts != RMS$_NMF && @@ -1033,23 +1039,30 @@ do_readline() if (!(sts & 1)) { SETERRNO((sts == RMS$_SYN ? EINVAL : EVMSERR),sts); } - fclose(tmpfp); + PerlIO_close(tmpfp); fp = NULL; } else { - rewind(tmpfp); + PerlIO_rewind(tmpfp); IoTYPE(io) = '<'; IoIFP(io) = fp = tmpfp; + IoFLAGS(io) &= ~IOf_UNTAINT; /* maybe redundant */ } } } #else /* !VMS */ #ifdef DOSISH +#ifdef OS2 + sv_setpv(tmpcmd, "for a in "); + sv_catsv(tmpcmd, tmpglob); + sv_catpv(tmpcmd, "; do echo \"$a\\0\\c\"; done |"); +#else sv_setpv(tmpcmd, "perlglob "); sv_catsv(tmpcmd, tmpglob); sv_catpv(tmpcmd, " |"); -#else -#ifdef CSH +#endif /* !OS2 */ +#else /* !DOSISH */ +#if defined(CSH) sv_setpvn(tmpcmd, cshname, cshlen); sv_catpv(tmpcmd, " -cf 'set nonomatch; glob "); sv_catsv(tmpcmd, tmpglob); @@ -1063,7 +1076,7 @@ do_readline() sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\n\\n\\n\\n'|"); #endif #endif /* !CSH */ -#endif /* !MSDOS */ +#endif /* !DOSISH */ (void)do_open(last_in_gv, SvPVX(tmpcmd), SvCUR(tmpcmd), FALSE, 0, 0, Nullfp); fp = IoIFP(io); @@ -1077,18 +1090,16 @@ do_readline() if (!fp) { if (dowarn && io && !(IoFLAGS(io) & IOf_START)) warn("Read on closed filehandle <%s>", GvENAME(last_in_gv)); - if (GIMME == G_SCALAR) { + if (gimme == G_SCALAR) { (void)SvOK_off(TARG); PUSHTARG; } RETURN; } - if (GIMME == G_ARRAY) { - sv = sv_2mortal(NEWSV(57, 80)); - offset = 0; - } - else { + if (gimme == G_SCALAR) { sv = TARG; + if (SvROK(sv)) + sv_unref(sv); (void)SvUPGRADE(sv, SVt_PV); tmplen = SvLEN(sv); /* remember if already alloced */ if (!tmplen) @@ -1098,9 +1109,13 @@ do_readline() else offset = 0; } + else { + sv = sv_2mortal(NEWSV(57, 80)); + offset = 0; + } for (;;) { if (!sv_gets(sv, fp, offset)) { - clearerr(fp); + PerlIO_clearerr(fp); if (IoFLAGS(io) & IOf_ARGV) { fp = nextargv(last_in_gv); if (fp) @@ -1109,20 +1124,23 @@ do_readline() IoFLAGS(io) |= IOf_START; } else if (type == OP_GLOB) { - (void)do_close(last_in_gv, FALSE); + if (do_close(last_in_gv, FALSE) & ~0xFF) + warn("internal error: glob failed"); } - if (GIMME == G_SCALAR) { + if (gimme == G_SCALAR) { (void)SvOK_off(TARG); PUSHTARG; } RETURN; } + /* This should not be marked tainted if the fp is marked clean */ + if (!(IoFLAGS(io) & IOf_UNTAINT)) { + TAINT; + SvTAINTED_on(sv); + } IoLINES(io)++; + SvSETMAGIC(sv); XPUSHs(sv); - if (tainting) { - tainted = TRUE; - SvTAINT(sv); /* Anything from the outside world...*/ - } if (type == OP_GLOB) { char *tmps; @@ -1142,7 +1160,7 @@ do_readline() continue; } } - if (GIMME == G_ARRAY) { + if (gimme == G_ARRAY) { if (SvLEN(sv) - SvCUR(sv) > 20) { SvLEN_set(sv, SvCUR(sv)+1); Renew(SvPVX(sv), SvLEN(sv), char); @@ -1150,7 +1168,7 @@ do_readline() sv = sv_2mortal(NEWSV(58, 80)); continue; } - else if (!tmplen && SvLEN(sv) - SvCUR(sv) > 80) { + else if (gimme == G_SCALAR && !tmplen && SvLEN(sv) - SvCUR(sv) > 80) { /* try to reclaim a bit of scalar space (only on 1st alloc) */ if (SvCUR(sv) < 60) SvLEN_set(sv, 80); @@ -1166,19 +1184,14 @@ PP(pp_enter) { dSP; register CONTEXT *cx; - I32 gimme; - - /* - * We don't just use the GIMME macro here because it assumes there's - * already a context, which ain't necessarily so at initial startup. - */ + I32 gimme = OP_GIMME(op, -1); - if (op->op_flags & OPf_KNOW) - gimme = op->op_flags & OPf_LIST; - else if (cxstack_ix >= 0) - gimme = cxstack[cxstack_ix].blk_gimme; - else - gimme = G_SCALAR; + if (gimme == -1) { + if (cxstack_ix >= 0) + gimme = cxstack[cxstack_ix].blk_gimme; + else + gimme = G_SCALAR; + } ENTER; @@ -1191,25 +1204,41 @@ PP(pp_enter) PP(pp_helem) { dSP; - SV** svp; + HE* he; SV *keysv = POPs; - STRLEN keylen; - char *key = SvPV(keysv, keylen); HV *hv = (HV*)POPs; - I32 lval = op->op_flags & OPf_MOD; + U32 lval = op->op_flags & OPf_MOD; + U32 defer = op->op_private & OPpLVAL_DEFER; if (SvTYPE(hv) != SVt_PVHV) RETPUSHUNDEF; - svp = hv_fetch(hv, key, keylen, lval); + he = hv_fetch_ent(hv, keysv, lval && !defer, 0); if (lval) { - if (!svp || *svp == &sv_undef) - DIE(no_helem, key); - if (op->op_private & OPpLVAL_INTRO) - save_svref(svp); - else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV)) - provide_ref(op, *svp); + if (!he || HeVAL(he) == &sv_undef) { + SV* lv; + SV* key2; + if (!defer) + DIE(no_helem, SvPV(keysv, na)); + lv = sv_newmortal(); + sv_upgrade(lv, SVt_PVLV); + LvTYPE(lv) = 'y'; + sv_magic(lv, key2 = newSVsv(keysv), 'y', Nullch, 0); + SvREFCNT_dec(key2); /* sv_magic() increments refcount */ + LvTARG(lv) = SvREFCNT_inc(hv); + LvTARGLEN(lv) = 1; + PUSHs(lv); + RETURN; + } + if (op->op_private & OPpLVAL_INTRO) { + if (HvNAME(hv) && isGV(HeVAL(he))) + save_gp((GV*)HeVAL(he), !(op->op_flags & OPf_SPECIAL)); + else + save_svref(&HeVAL(he)); + } + else if (op->op_private & OPpDEREF) + vivify_ref(HeVAL(he), op->op_private & OPpDEREF); } - PUSHs(svp ? *svp : &sv_undef); + PUSHs(he ? HeVAL(he) : &sv_undef); RETURN; } @@ -1229,35 +1258,38 @@ PP(pp_leave) POPBLOCK(cx,newpm); - if (op->op_flags & OPf_KNOW) - gimme = op->op_flags & OPf_LIST; - else if (cxstack_ix >= 0) - gimme = cxstack[cxstack_ix].blk_gimme; - else - gimme = G_SCALAR; + gimme = OP_GIMME(op, -1); + if (gimme == -1) { + if (cxstack_ix >= 0) + gimme = cxstack[cxstack_ix].blk_gimme; + else + gimme = G_SCALAR; + } - if (gimme == G_SCALAR) { - if (op->op_private & OPpLEAVE_VOID) - SP = newsp; + TAINT_NOT; + if (gimme == G_VOID) + SP = newsp; + else if (gimme == G_SCALAR) { + MARK = newsp + 1; + if (MARK <= SP) + if (SvFLAGS(TOPs) & (SVs_PADTMP|SVs_TEMP)) + *MARK = TOPs; + else + *MARK = sv_mortalcopy(TOPs); else { - MARK = newsp + 1; - if (MARK <= SP) - if (SvFLAGS(TOPs) & (SVs_PADTMP|SVs_TEMP)) - *MARK = TOPs; - else - *MARK = sv_mortalcopy(TOPs); - else { - MEXTEND(mark,0); - *MARK = &sv_undef; - } - SP = MARK; + MEXTEND(mark,0); + *MARK = &sv_undef; } + SP = MARK; } - else { - for (mark = newsp + 1; mark <= SP; mark++) - if (!(SvFLAGS(*mark) & (SVs_PADTMP|SVs_TEMP))) + else if (gimme == G_ARRAY) { + /* in case LEAVE wipes old return values */ + for (mark = newsp + 1; mark <= SP; mark++) { + if (!(SvFLAGS(*mark) & (SVs_PADTMP|SVs_TEMP))) { *mark = sv_mortalcopy(*mark); - /* in case LEAVE wipes old return values */ + TAINT_NOT; /* Each item is independent */ + } + } } curpm = newpm; /* Don't pop $1 et al till now */ @@ -1270,27 +1302,45 @@ PP(pp_iter) { dSP; register CONTEXT *cx; - SV *sv; + SV* sv; AV* av; EXTEND(sp, 1); cx = &cxstack[cxstack_ix]; if (cx->cx_type != CXt_LOOP) DIE("panic: pp_iter"); + av = cx->blk_loop.iterary; - if (av == stack && cx->blk_loop.iterix >= cx->blk_oldsp) + if (cx->blk_loop.iterix >= (av == curstack ? cx->blk_oldsp : AvFILL(av))) RETPUSHNO; - if (cx->blk_loop.iterix >= AvFILL(av)) - RETPUSHNO; + SvREFCNT_dec(*cx->blk_loop.itervar); - if (sv = AvARRAY(av)[++cx->blk_loop.iterix]) { + if (sv = AvARRAY(av)[++cx->blk_loop.iterix]) SvTEMP_off(sv); - *cx->blk_loop.itervar = sv; - } else - *cx->blk_loop.itervar = &sv_undef; + sv = &sv_undef; + if (av != curstack && SvIMMORTAL(sv)) { + SV *lv = cx->blk_loop.iterlval; + if (lv && SvREFCNT(lv) > 1) { + SvREFCNT_dec(lv); + lv = Nullsv; + } + if (lv) + SvREFCNT_dec(LvTARG(lv)); + else { + lv = cx->blk_loop.iterlval = NEWSV(26, 0); + sv_upgrade(lv, SVt_PVLV); + LvTYPE(lv) = 'y'; + sv_magic(lv, Nullsv, 'y', Nullch, 0); + } + LvTARG(lv) = SvREFCNT_inc(av); + LvTARGOFF(lv) = cx->blk_loop.iterix; + LvTARGLEN(lv) = -1; + sv = (SV*)lv; + } + *cx->blk_loop.itervar = SvREFCNT_inc(sv); RETPUSHYES; } @@ -1310,6 +1360,7 @@ PP(pp_subst) I32 maxiters; register I32 i; bool once; + bool rxtainted; char *orig; I32 safebase; register REGEXP *rx = pm->op_pmregexp; @@ -1317,17 +1368,22 @@ PP(pp_subst) int force_on_match = 0; I32 oldsave = savestack_ix; - if (pm->op_pmflags & PMf_CONST) /* known replacement string? */ - dstr = POPs; + /* known replacement string? */ + dstr = (pm->op_pmflags & PMf_CONST) ? POPs : Nullsv; if (op->op_flags & OPf_STACKED) TARG = POPs; else { TARG = GvSV(defgv); EXTEND(SP,1); } + if (SvREADONLY(TARG) + || (SvTYPE(TARG) > SVt_PVLV + && !(SvTYPE(TARG) == SVt_PVGV && SvFAKE(TARG)))) + croak(no_modify); s = SvPV(TARG, len); - if (!SvPOKp(TARG) || SvREADONLY(TARG) || (SvTYPE(TARG) == SVt_PVGV)) + if (!SvPOKp(TARG) || SvTYPE(TARG) == SVt_PVGV) force_on_match = 1; + TAINT_NOT; force_it: if (!pm || !s) @@ -1340,7 +1396,7 @@ PP(pp_subst) pm = curpm; rx = pm->op_pmregexp; } - safebase = ((!rx || !rx->nparens) && !sawampersand); + safebase = (!rx->nparens && !sawampersand); if (pm->op_pmflags & (PMf_MULTILINE|PMf_SINGLELINE)) { SAVEINT(multiline); multiline = pm->op_pmflags & PMf_MULTILINE; @@ -1367,139 +1423,122 @@ PP(pp_subst) s = m; } else if (!multiline) { - if (*SvPVX(pm->op_pmshort) != *s || - bcmp(SvPVX(pm->op_pmshort), s, pm->op_pmslen) ) { - if (pm->op_pmflags & PMf_FOLD) { - if (ibcmp((U8*)SvPVX(pm->op_pmshort), (U8*)s, pm->op_pmslen) ) - goto nope; - } - else - goto nope; - } + if (*SvPVX(pm->op_pmshort) != *s + || (pm->op_pmslen > 1 + && memNE(SvPVX(pm->op_pmshort), s, pm->op_pmslen))) + goto nope; } if (!rx->naughty && --BmUSEFUL(pm->op_pmshort) < 0) { SvREFCNT_dec(pm->op_pmshort); pm->op_pmshort = Nullsv; /* opt is being useless */ } } + + /* only replace once? */ once = !(rpm->op_pmflags & PMf_GLOBAL); - if (rpm->op_pmflags & PMf_CONST) { /* known replacement string? */ - c = SvPV(dstr, clen); - if (clen <= rx->minlen) { - /* can do inplace substitution */ - if (pregexec(rx, s, strend, orig, 0, - SvSCREAM(TARG) ? TARG : Nullsv, safebase)) { - if (force_on_match) { - force_on_match = 0; - s = SvPV_force(TARG, len); - goto force_it; + + /* known replacement string? */ + c = dstr ? SvPV(dstr, clen) : Nullch; + + /* can do inplace substitution? */ + if (c && clen <= rx->minlen && safebase) { + if (! pregexec(rx, s, strend, orig, 0, + SvSCREAM(TARG) ? TARG : Nullsv, safebase)) { + PUSHs(&sv_no); + LEAVE_SCOPE(oldsave); + RETURN; + } + if (force_on_match) { + force_on_match = 0; + s = SvPV_force(TARG, len); + goto force_it; + } + d = s; + curpm = pm; + SvSCREAM_off(TARG); /* disable possible screamer */ + if (once) { + rxtainted = rx->exec_tainted; + m = rx->startp[0]; + d = rx->endp[0]; + s = orig; + if (m - s > strend - d) { /* faster to shorten from end */ + if (clen) { + Copy(c, m, clen, char); + m += clen; } - if (rx->subbase) /* oops, no we can't */ - goto long_way; - d = s; - curpm = pm; - SvSCREAM_off(TARG); /* disable possible screamer */ - if (once) { - m = rx->startp[0]; - d = rx->endp[0]; - s = orig; - if (m - s > strend - d) { /* faster to shorten from end */ - if (clen) { - Copy(c, m, clen, char); - m += clen; - } - i = strend - d; - if (i > 0) { - Move(d, m, i, char); - m += i; - } - *m = '\0'; - SvCUR_set(TARG, m - s); - (void)SvPOK_only(TARG); - SvSETMAGIC(TARG); - PUSHs(&sv_yes); - LEAVE_SCOPE(oldsave); - RETURN; - } - /*SUPPRESS 560*/ - else if (i = m - s) { /* faster from front */ - d -= clen; - m = d; - sv_chop(TARG, d-i); - s += i; - while (i--) - *--d = *--s; - if (clen) - Copy(c, m, clen, char); - (void)SvPOK_only(TARG); - SvSETMAGIC(TARG); - PUSHs(&sv_yes); - LEAVE_SCOPE(oldsave); - RETURN; - } - else if (clen) { - d -= clen; - sv_chop(TARG, d); - Copy(c, d, clen, char); - (void)SvPOK_only(TARG); - SvSETMAGIC(TARG); - PUSHs(&sv_yes); - LEAVE_SCOPE(oldsave); - RETURN; - } - else { - sv_chop(TARG, d); - (void)SvPOK_only(TARG); - SvSETMAGIC(TARG); - PUSHs(&sv_yes); - LEAVE_SCOPE(oldsave); - RETURN; - } - /* NOTREACHED */ + i = strend - d; + if (i > 0) { + Move(d, m, i, char); + m += i; } - do { - if (iters++ > maxiters) - DIE("Substitution loop"); - m = rx->startp[0]; - /*SUPPRESS 560*/ - if (i = m - s) { - if (s != d) - Move(s, d, i, char); - d += i; - } - if (clen) { - Copy(c, d, clen, char); - d += clen; - } - s = rx->endp[0]; - } while (pregexec(rx, s, strend, orig, s == m, - Nullsv, TRUE)); /* (don't match same null twice) */ - if (s != d) { - i = strend - s; - SvCUR_set(TARG, d - SvPVX(TARG) + i); - Move(s, d, i+1, char); /* include the Null */ + *m = '\0'; + SvCUR_set(TARG, m - s); + } + /*SUPPRESS 560*/ + else if (i = m - s) { /* faster from front */ + d -= clen; + m = d; + sv_chop(TARG, d-i); + s += i; + while (i--) + *--d = *--s; + if (clen) + Copy(c, m, clen, char); + } + else if (clen) { + d -= clen; + sv_chop(TARG, d); + Copy(c, d, clen, char); + } + else { + sv_chop(TARG, d); + } + TAINT_IF(rxtainted); + PUSHs(&sv_yes); + } + else { + rxtainted = 0; + do { + if (iters++ > maxiters) + DIE("Substitution loop"); + rxtainted |= rx->exec_tainted; + m = rx->startp[0]; + /*SUPPRESS 560*/ + if (i = m - s) { + if (s != d) + Move(s, d, i, char); + d += i; } - (void)SvPOK_only(TARG); - SvSETMAGIC(TARG); - PUSHs(sv_2mortal(newSViv((I32)iters))); - LEAVE_SCOPE(oldsave); - RETURN; + if (clen) { + Copy(c, d, clen, char); + d += clen; + } + s = rx->endp[0]; + } while (pregexec(rx, s, strend, orig, s == m, + Nullsv, TRUE)); /* don't match same null twice */ + if (s != d) { + i = strend - s; + SvCUR_set(TARG, d - SvPVX(TARG) + i); + Move(s, d, i+1, char); /* include the NUL */ } - PUSHs(&sv_no); - LEAVE_SCOPE(oldsave); - RETURN; + TAINT_IF(rxtainted); + PUSHs(sv_2mortal(newSViv((I32)iters))); } + (void)SvPOK_only(TARG); + SvSETMAGIC(TARG); + SvTAINT(TARG); + LEAVE_SCOPE(oldsave); + RETURN; } - else - c = Nullch; + if (pregexec(rx, s, strend, orig, 0, - SvSCREAM(TARG) ? TARG : Nullsv, safebase)) { - long_way: + SvSCREAM(TARG) ? TARG : Nullsv, safebase)) { if (force_on_match) { force_on_match = 0; s = SvPV_force(TARG, len); goto force_it; } + rxtainted = rx->exec_tainted; dstr = NEWSV(25, sv_len(TARG)); sv_setpvn(dstr, m, s-m); curpm = pm; @@ -1511,6 +1550,7 @@ PP(pp_subst) do { if (iters++ > maxiters) DIE("Substitution loop"); + rxtainted |= rx->exec_tainted; if (rx->subbase && rx->subbase != orig) { m = s; s = orig; @@ -1525,10 +1565,11 @@ PP(pp_subst) sv_catpvn(dstr, c, clen); if (once) break; - } while (pregexec(rx, s, strend, orig, s == m, Nullsv, - safebase)); + } while (pregexec(rx, s, strend, orig, s == m, Nullsv, safebase)); sv_catpvn(dstr, s, strend - s); + TAINT_IF(rxtainted); + (void)SvOOK_off(TARG); Safefree(SvPVX(TARG)); SvPVX(TARG) = SvPVX(dstr); @@ -1539,16 +1580,17 @@ PP(pp_subst) (void)SvPOK_only(TARG); SvSETMAGIC(TARG); + SvTAINT(TARG); PUSHs(sv_2mortal(newSViv((I32)iters))); LEAVE_SCOPE(oldsave); RETURN; } - PUSHs(&sv_no); - LEAVE_SCOPE(oldsave); - RETURN; + goto ret_no; nope: ++BmUSEFUL(pm->op_pmshort); + +ret_no: PUSHs(&sv_no); LEAVE_SCOPE(oldsave); RETURN; @@ -1566,18 +1608,19 @@ PP(pp_grepwhile) /* All done yet? */ if (stack_base + *markstack_ptr > sp) { I32 items; + I32 gimme = GIMME_V; LEAVE; /* exit outer scope */ (void)POPMARK; /* pop src */ items = --*markstack_ptr - markstack_ptr[-1]; (void)POPMARK; /* pop dst */ SP = stack_base + POPMARK; /* pop original mark */ - if (GIMME != G_ARRAY) { + if (gimme == G_SCALAR) { dTARGET; XPUSHi(items); - RETURN; } - SP += items; + else if (gimme == G_ARRAY) + SP += items; RETURN; } else { @@ -1602,40 +1645,36 @@ PP(pp_leavesub) PMOP *newpm; I32 gimme; register CONTEXT *cx; + struct block_sub cxsub; POPBLOCK(cx,newpm); - POPSUB(cx); - + POPSUB1(cx); /* Delay POPSUB2 until stack values are safe */ + + TAINT_NOT; if (gimme == G_SCALAR) { MARK = newsp + 1; if (MARK <= SP) - if (SvFLAGS(TOPs) & SVs_TEMP) - *MARK = TOPs; - else - *MARK = sv_mortalcopy(TOPs); + *MARK = SvTEMP(TOPs) ? TOPs : sv_mortalcopy(TOPs); else { - MEXTEND(mark,0); + MEXTEND(MARK, 0); *MARK = &sv_undef; } SP = MARK; } - else { - for (mark = newsp + 1; mark <= SP; mark++) - if (!(SvFLAGS(*mark) & SVs_TEMP)) - *mark = sv_mortalcopy(*mark); - /* in case LEAVE wipes old return values */ - } - - if (cx->blk_sub.hasargs) { /* You don't exist; go away. */ - AV* av = cx->blk_sub.argarray; - - av_clear(av); - AvREAL_off(av); + else if (gimme == G_ARRAY) { + for (MARK = newsp + 1; MARK <= SP; MARK++) { + if (!SvTEMP(*MARK)) { + *MARK = sv_mortalcopy(*MARK); + TAINT_NOT; /* Each item is independent */ + } + } } - curpm = newpm; /* Don't pop $1 et al till now */ + PUTBACK; + + POPSUB2(); /* Stack values are safe: release CV and @_ ... */ + curpm = newpm; /* ... and pop $1 et al */ LEAVE; - PUTBACK; return pop_return(); } @@ -1647,6 +1686,7 @@ PP(pp_entersub) register CV *cv; register CONTEXT *cx; I32 gimme; + bool hasargs = (op->op_flags & OPf_STACKED) != 0; if (!sv) DIE("Not a CODE reference"); @@ -1655,11 +1695,19 @@ PP(pp_entersub) if (!SvROK(sv)) { char *sym; - if (sv == &sv_yes) /* unfound import, ignore */ + if (sv == &sv_yes) { /* unfound import, ignore */ + if (hasargs) + SP = stack_base + POPMARK; RETURN; - if (!SvOK(sv)) + } + if (SvGMAGICAL(sv)) { + mg_get(sv); + sym = SvPOKp(sv) ? SvPVX(sv) : Nullch; + } + else + sym = SvPV(sv, na); + if (!sym) DIE(no_usym, "a subroutine"); - sym = SvPV(sv,na); if (op->op_private & HINT_STRICT_REFS) DIE(no_symref, sym, "a subroutine"); cv = perl_get_cv(sym, TRUE); @@ -1676,7 +1724,7 @@ PP(pp_entersub) cv = (CV*)sv; break; case SVt_PVGV: - if (!(cv = GvCV((GV*)sv))) + if (!(cv = GvCVu((GV*)sv))) cv = sv_2cv(sv, &stash, &gv, TRUE); break; } @@ -1689,46 +1737,49 @@ PP(pp_entersub) DIE("Not a CODE reference"); if (!CvROOT(cv) && !CvXSUB(cv)) { - if (gv = CvGV(cv)) { - SV *tmpstr; - GV *ngv; - if (SvFAKE(cv) && GvCV(gv) != cv) { /* autoloaded stub? */ - cv = GvCV(gv); - if (SvTYPE(sv) == SVt_PVGV) { - SvREFCNT_dec(GvCV((GV*)sv)); - GvCV((GV*)sv) = (CV*)SvREFCNT_inc((SV*)cv); - } - goto retry; - } - tmpstr = sv_newmortal(); - gv_efullname(tmpstr, gv); - ngv = gv_fetchmethod(GvESTASH(gv), "AUTOLOAD"); - if (ngv && ngv != gv && (cv = GvCV(ngv))) { /* One more chance... */ - gv = ngv; - sv_setsv(GvSV(CvGV(cv)), tmpstr); /* Set CV's $AUTOLOAD */ - if (tainting) - sv_unmagic(GvSV(CvGV(cv)), 't'); - goto retry; - } - else - DIE("Undefined subroutine &%s called",SvPVX(tmpstr)); + GV* autogv; + SV* subname; + + /* anonymous or undef'd function leaves us no recourse */ + if (CvANON(cv) || !(gv = CvGV(cv))) + DIE("Undefined subroutine called"); + /* autoloaded stub? */ + if (cv != GvCV(gv)) { + cv = GvCV(gv); + goto retry; + } + /* should call AUTOLOAD now? */ + if ((autogv = gv_autoload4(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv), + FALSE))) + { + cv = GvCV(autogv); + goto retry; } - DIE("Undefined subroutine called"); + /* sorry */ + subname = sv_newmortal(); + gv_efullname3(subname, gv, Nullch); + DIE("Undefined subroutine &%s called", SvPVX(subname)); } - gimme = GIMME; - if ((op->op_private & OPpENTERSUB_DB) && !CvXSUB(cv)) { + gimme = GIMME_V; + if ((op->op_private & OPpENTERSUB_DB) && GvCV(DBsub) && !CvNODEBUG(cv)) { + SV *oldsv = sv; sv = GvSV(DBsub); save_item(sv); - if (CvFLAGS(cv) & (CVf_ANON | CVf_CLONED)) { - /* GV is potentially non-unique */ + gv = CvGV(cv); + if ( (CvFLAGS(cv) & (CVf_ANON | CVf_CLONED)) + || strEQ(GvNAME(gv), "END") + || ((GvCV(gv) != cv) && /* Could be imported, and old sub redefined. */ + !( (SvTYPE(oldsv) == SVt_PVGV) && (GvCV((GV*)oldsv) == cv) + && (gv = (GV*)oldsv) ))) { /* Use GV from the stack as a fallback. */ + /* GV is potentially non-unique, or contain different CV. */ sv_setsv(sv, newRV((SV*)cv)); } else { - gv = CvGV(cv); - gv_efullname(sv,gv); + gv_efullname3(sv, gv, Nullch); } cv = GvCV(DBsub); + if (CvXSUB(cv)) curcopdb = curcop; if (!cv) DIE("No DBsub routine"); } @@ -1738,6 +1789,7 @@ PP(pp_entersub) I32 (*fp3)_((int,int,int)); dMARK; register I32 items = SP - MARK; + /* We dont worry to copy from @_. */ while (sp > mark) { sp[1] = sp[0]; sp--; @@ -1753,6 +1805,30 @@ PP(pp_entersub) I32 markix = TOPMARK; PUTBACK; + + if (!hasargs) { + /* Need to copy @_ to stack. Alternative may be to + * switch stack to @_, and copy return values + * back. This would allow popping @_ in XSUB, e.g.. XXXX */ + AV* av = GvAV(defgv); + I32 items = AvFILL(av) + 1; + + if (items) { + /* Mark is at the end of the stack. */ + EXTEND(sp, items); + Copy(AvARRAY(av), sp + 1, items, SV*); + sp += items; + PUTBACK ; + } + } + if (curcopdb) { /* We assume that the first + XSUB in &DB::sub is the + called one. */ + SAVESPTR(curcop); + curcop = curcopdb; + curcopdb = NULL; + } + /* Do we need to open block here? XXXX */ (void)(*CvXSUB(cv))(cv); /* Enforce some sanity in scalar context. */ @@ -1770,7 +1846,6 @@ PP(pp_entersub) else { dMARK; register I32 items = SP - MARK; - I32 hasargs = (op->op_flags & OPf_STACKED) != 0; AV* padlist = CvPADLIST(cv); SV** svp = AvARRAY(padlist); push_return(op->op_next); @@ -1780,8 +1855,9 @@ PP(pp_entersub) if (CvDEPTH(cv) < 2) (void)SvREFCNT_inc(cv); else { /* save temporaries on recursion? */ - if (CvDEPTH(cv) == 100 && dowarn) - warn("Deep recursion on subroutine \"%s\"",GvENAME(CvGV(cv))); + if (CvDEPTH(cv) == 100 && dowarn + && !(PERLDB_SUB && cv == GvCV(DBsub))) + sub_crush_depth(cv); if (CvDEPTH(cv) > AvFILL(padlist)) { AV *av; AV *newpad = newAV(); @@ -1791,9 +1867,10 @@ PP(pp_entersub) for ( ;ix > 0; ix--) { if (svp[ix] != &sv_undef) { char *name = SvPVX(svp[ix]); - if (SvFLAGS(svp[ix]) & SVf_FAKE) { /* outer lexical? */ - av_store(newpad, ix, - SvREFCNT_inc(oldpad[ix]) ); + if ((SvFLAGS(svp[ix]) & SVf_FAKE) /* outer lexical? */ + || *name == '&') /* anonymous code? */ + { + av_store(newpad, ix, SvREFCNT_inc(oldpad[ix])); } else { /* our own lexical */ if (*name == '@') @@ -1831,7 +1908,7 @@ PP(pp_entersub) } cx->blk_sub.savearray = GvAV(defgv); cx->blk_sub.argarray = av; - GvAV(defgv) = cx->blk_sub.argarray; + GvAV(defgv) = (AV*)SvREFCNT_inc(av); ++MARK; if (items > AvMAX(av) + 1) { @@ -1860,44 +1937,85 @@ PP(pp_entersub) } } +void +sub_crush_depth(cv) +CV* cv; +{ + if (CvANON(cv)) + warn("Deep recursion on anonymous subroutine"); + else { + SV* tmpstr = sv_newmortal(); + gv_efullname3(tmpstr, CvGV(cv), Nullch); + warn("Deep recursion on subroutine \"%s\"", SvPVX(tmpstr)); + } +} + PP(pp_aelem) { dSP; SV** svp; I32 elem = POPi; - AV *av = (AV*)POPs; - I32 lval = op->op_flags & OPf_MOD; + AV* av = (AV*)POPs; + U32 lval = op->op_flags & OPf_MOD; + U32 defer = (op->op_private & OPpLVAL_DEFER) && (elem > AvFILL(av)); if (elem > 0) elem -= curcop->cop_arybase; if (SvTYPE(av) != SVt_PVAV) RETPUSHUNDEF; - svp = av_fetch(av, elem, lval); + svp = av_fetch(av, elem, lval && !defer); if (lval) { - if (!svp || *svp == &sv_undef) - DIE(no_aelem, elem); + if (!svp || *svp == &sv_undef) { + SV* lv; + if (!defer) + DIE(no_aelem, elem); + lv = sv_newmortal(); + sv_upgrade(lv, SVt_PVLV); + LvTYPE(lv) = 'y'; + sv_magic(lv, Nullsv, 'y', Nullch, 0); + LvTARG(lv) = SvREFCNT_inc(av); + LvTARGOFF(lv) = elem; + LvTARGLEN(lv) = 1; + PUSHs(lv); + RETURN; + } if (op->op_private & OPpLVAL_INTRO) save_svref(svp); - else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV)) - provide_ref(op, *svp); + else if (op->op_private & OPpDEREF) + vivify_ref(*svp, op->op_private & OPpDEREF); } PUSHs(svp ? *svp : &sv_undef); RETURN; } void -provide_ref(op, sv) -OP* op; +vivify_ref(sv, to_what) SV* sv; +U32 to_what; { if (SvGMAGICAL(sv)) mg_get(sv); if (!SvOK(sv)) { if (SvREADONLY(sv)) croak(no_modify); - (void)SvUPGRADE(sv, SVt_RV); - SvRV(sv) = (op->op_private & OPpDEREF_HV ? - (SV*)newHV() : (SV*)newAV()); + if (SvTYPE(sv) < SVt_RV) + sv_upgrade(sv, SVt_RV); + else if (SvTYPE(sv) >= SVt_PV) { + (void)SvOOK_off(sv); + Safefree(SvPVX(sv)); + SvLEN(sv) = SvCUR(sv) = 0; + } + switch (to_what) { + case OPpDEREF_SV: + SvRV(sv) = newSV(0); + break; + case OPpDEREF_AV: + SvRV(sv) = (SV*)newAV(); + break; + case OPpDEREF_HV: + SvRV(sv) = (SV*)newHV(); + break; + } SvROK_on(sv); SvSETMAGIC(sv); } @@ -1909,60 +2027,72 @@ PP(pp_method) SV* sv; SV* ob; GV* gv; - SV* nm; + HV* stash; + char* name; + char* packname; + STRLEN packlen; + + if (SvROK(TOPs)) { + sv = SvRV(TOPs); + if (SvTYPE(sv) == SVt_PVCV) { + SETs(sv); + RETURN; + } + } - nm = TOPs; + name = SvPV(TOPs, na); sv = *(stack_base + TOPMARK + 1); - gv = 0; if (SvGMAGICAL(sv)) mg_get(sv); if (SvROK(sv)) ob = (SV*)SvRV(sv); else { GV* iogv; - char* packname = 0; + packname = Nullch; if (!SvOK(sv) || - !(packname = SvPV(sv, na)) || + !(packname = SvPV(sv, packlen)) || !(iogv = gv_fetchpv(packname, FALSE, SVt_PVIO)) || !(ob=(SV*)GvIO(iogv))) { - char *name = SvPV(nm, na); - HV *stash; - if (!packname || !isALPHA(*packname)) -DIE("Can't call method \"%s\" without a package or object reference", name); - if (!(stash = gv_stashpv(packname, FALSE))) { - if (gv_stashpv("UNIVERSAL", FALSE)) - stash = gv_stashpv(packname, TRUE); - else - DIE("Can't call method \"%s\" in empty package \"%s\"", - name, packname); - } - gv = gv_fetchmethod(stash,name); - if (!gv) - DIE("Can't locate object method \"%s\" via package \"%s\"", - name, packname); - SETs(gv); - RETURN; + if (!packname || !isIDFIRST(*packname)) + DIE("Can't call method \"%s\" without a package or object reference", name); + stash = gv_stashpvn(packname, packlen, TRUE); + goto fetch; } - *(stack_base + TOPMARK + 1) = sv_2mortal(newRV(iogv)); + *(stack_base + TOPMARK + 1) = sv_2mortal(newRV((SV*)iogv)); } - if (!ob || !SvOBJECT(ob)) { - char *name = SvPV(nm, na); + if (!ob || !SvOBJECT(ob)) DIE("Can't call method \"%s\" on unblessed reference", name); - } - if (!gv) { /* nothing cached */ - char *name = SvPV(nm, na); - gv = gv_fetchmethod(SvSTASH(ob),name); - if (!gv) - DIE("Can't locate object method \"%s\" via package \"%s\"", - name, HvNAME(SvSTASH(ob))); - } + stash = SvSTASH(ob); + + fetch: + gv = gv_fetchmethod(stash, name); + if (!gv) { + char* leaf = name; + char* sep = Nullch; + char* p; - SETs(gv); + for (p = name; *p; p++) { + if (*p == '\'') + sep = p, leaf = p + 1; + else if (*p == ':' && *(p + 1) == ':') + sep = p, leaf = p + 2; + } + if (!sep || ((sep - name) == 5 && strnEQ(name, "SUPER", 5))) { + packname = HvNAME(sep ? curcop->cop_stash : stash); + packlen = strlen(packname); + } + else { + packname = name; + packlen = sep - name; + } + DIE("Can't locate object method \"%s\" via package \"%.*s\"", + leaf, (int)packlen, packname); + } + SETs(isGV(gv) ? (SV*)GvCV(gv) : (SV*)gv); RETURN; } - diff --git a/gnu/usr.bin/perl/pp_sys.c b/gnu/usr.bin/perl/pp_sys.c index ba1f105a06b..d574b2e8528 100644 --- a/gnu/usr.bin/perl/pp_sys.c +++ b/gnu/usr.bin/perl/pp_sys.c @@ -1,6 +1,6 @@ /* pp_sys.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -17,21 +17,17 @@ #include "EXTERN.h" #include "perl.h" -/* XXX Omit this -- it causes too much grief on mixed systems. - Next time, I should force broken systems to unset i_unistd in - hint files. -*/ -#if 0 -# ifdef I_UNISTD -# include <unistd.h> -# endif +/* XXX If this causes problems, set i_unistd=undef in the hint file. */ +#ifdef I_UNISTD +# include <unistd.h> #endif -/* Put this after #includes because fork and vfork prototypes may - conflict. -*/ -#ifndef HAS_VFORK -# define vfork fork +#ifdef I_SYS_WAIT +# include <sys/wait.h> +#endif + +#ifdef I_SYS_RESOURCE +# include <sys/resource.h> #endif #if defined(HAS_SOCKET) && !defined(VMS) /* VMS handles sockets via vmsish.h */ @@ -46,11 +42,9 @@ #ifdef HAS_SELECT #ifdef I_SYS_SELECT -#ifndef I_SYS_TIME #include <sys/select.h> #endif #endif -#endif #ifdef HOST_NOT_FOUND extern int h_errno; @@ -77,7 +71,11 @@ extern int h_errno; #endif #ifdef I_UTIME -#include <utime.h> +# ifdef _MSC_VER +# include <sys/utime.h> +# else +# include <utime.h> +# endif #endif #ifdef I_FCNTL #include <fcntl.h> @@ -86,25 +84,111 @@ extern int h_errno; #include <sys/file.h> #endif +/* Put this after #includes because fork and vfork prototypes may conflict. */ +#ifndef HAS_VFORK +# define vfork fork +#endif + +/* Put this after #includes because <unistd.h> defines _XOPEN_*. */ +#ifndef Sock_size_t +# if _XOPEN_VERSION >= 5 || defined(_XOPEN_SOURCE_EXTENDED) || defined(__GLIBC__) +# define Sock_size_t Size_t +# else +# define Sock_size_t int +# endif +#endif + #if !defined(HAS_MKDIR) || !defined(HAS_RMDIR) static int dooneliner _((char *cmd, char *filename)); #endif + +#ifdef HAS_CHSIZE +# ifdef my_chsize /* Probably #defined to Perl_my_chsize in embed.h */ +# undef my_chsize +# endif +# define my_chsize chsize +#endif + +#ifdef HAS_FLOCK +# define FLOCK flock +#else /* no flock() */ + + /* fcntl.h might not have been included, even if it exists, because + the current Configure only sets I_FCNTL if it's needed to pick up + the *_OK constants. Make sure it has been included before testing + the fcntl() locking constants. */ +# if defined(HAS_FCNTL) && !defined(I_FCNTL) +# include <fcntl.h> +# endif + +# if defined(HAS_FCNTL) && defined(F_SETLK) && defined (F_SETLKW) +# define FLOCK fcntl_emulate_flock +# define FCNTL_EMULATE_FLOCK +# else /* no flock() or fcntl(F_SETLK,...) */ +# ifdef HAS_LOCKF +# define FLOCK lockf_emulate_flock +# define LOCKF_EMULATE_FLOCK +# endif /* lockf */ +# endif /* no flock() or fcntl(F_SETLK,...) */ + +# ifdef FLOCK + static int FLOCK _((int, int)); + + /* + * These are the flock() constants. Since this sytems doesn't have + * flock(), the values of the constants are probably not available. + */ +# ifndef LOCK_SH +# define LOCK_SH 1 +# endif +# ifndef LOCK_EX +# define LOCK_EX 2 +# endif +# ifndef LOCK_NB +# define LOCK_NB 4 +# endif +# ifndef LOCK_UN +# define LOCK_UN 8 +# endif +# endif /* emulating flock() */ + +#endif /* no flock() */ + +#ifndef MAXPATHLEN +# ifdef PATH_MAX +# define MAXPATHLEN PATH_MAX +# else +# define MAXPATHLEN 1024 +# endif +#endif + +#define ZBTLEN 10 +static char zero_but_true[ZBTLEN + 1] = "0 but true"; + /* Pushy I/O. */ PP(pp_backtick) { dSP; dTARGET; - FILE *fp; + PerlIO *fp; char *tmps = POPp; + I32 gimme = GIMME_V; + TAINT_PROPER("``"); fp = my_popen(tmps, "r"); if (fp) { - sv_setpv(TARG, ""); /* note that this preserves previous buffer */ - if (GIMME == G_SCALAR) { + if (gimme == G_VOID) { + while (PerlIO_read(fp, tokenbuf, sizeof tokenbuf) > 0) + /*SUPPRESS 530*/ + ; + } + else if (gimme == G_SCALAR) { + sv_setpv(TARG, ""); /* note that this preserves previous buffer */ while (sv_gets(TARG, fp, SvCUR(TARG)) != Nullch) /*SUPPRESS 530*/ ; XPUSHs(TARG); + SvTAINTED_on(TARG); } else { SV *sv; @@ -120,13 +204,15 @@ PP(pp_backtick) SvLEN_set(sv, SvCUR(sv)+1); Renew(SvPVX(sv), SvLEN(sv), char); } + SvTAINTED_on(sv); } } - statusvalue = FIXSTATUS(my_pclose(fp)); + STATUS_NATIVE_SET(my_pclose(fp)); + TAINT; /* "I believe that this is not gratuitous!" */ } else { - statusvalue = -1; - if (GIMME == G_SCALAR) + STATUS_NATIVE_SET(-1); + if (gimme == G_SCALAR) RETPUSHUNDEF; } @@ -138,6 +224,17 @@ PP(pp_glob) OP *result; ENTER; +#ifndef VMS + if (tainting) { + /* + * The external globbing program may use things we can't control, + * so for security reasons we must assume the worst. + */ + TAINT; + taint_proper(no_security, "glob"); + } +#endif /* !VMS */ + SAVESPTR(last_in_gv); /* We don't want this to be permanent. */ last_in_gv = (GV*)*stack_sp--; @@ -147,7 +244,7 @@ PP(pp_glob) #ifndef CSH *SvPVX(rs) = '\n'; #endif /* !CSH */ -#endif /* !MSDOS */ +#endif /* !DOSISH */ result = do_readline(); LEAVE; @@ -229,16 +326,18 @@ PP(pp_open) if (MAXARG > 1) sv = POPs; - else if (SvTYPE(TOPs) == SVt_PVGV) - sv = GvSV(TOPs); - else + if (!isGV(TOPs)) DIE(no_usym, "filehandle"); + if (MAXARG <= 1) + sv = GvSV(TOPs); gv = (GV*)POPs; + if (!isGV(gv)) + DIE(no_usym, "filehandle"); + if (GvIOp(gv)) + IoFLAGS(GvIOp(gv)) &= ~IOf_UNTAINT; tmps = SvPV(sv, len); - if (do_open(gv, tmps, len, FALSE, 0, 0, Nullfp)) { - IoLINES(GvIOp(gv)) = 0; + if (do_open(gv, tmps, len, FALSE, 0, 0, Nullfp)) PUSHi( (I32)forkprocess ); - } else if (forkprocess == 0) /* we are a new child */ PUSHi(0); else @@ -256,7 +355,7 @@ PP(pp_close) else gv = (GV*)POPs; EXTEND(SP, 1); - PUSHs( do_close(gv, TRUE) ? &sv_yes : &sv_no ); + PUSHs(boolSV(do_close(gv, TRUE))); RETURN; } @@ -289,16 +388,16 @@ PP(pp_pipe_op) if (pipe(fd) < 0) goto badexit; - IoIFP(rstio) = fdopen(fd[0], "r"); - IoOFP(wstio) = fdopen(fd[1], "w"); + IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"); + IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"); IoIFP(wstio) = IoOFP(wstio); IoTYPE(rstio) = '<'; IoTYPE(wstio) = '>'; if (!IoIFP(rstio) || !IoOFP(wstio)) { - if (IoIFP(rstio)) fclose(IoIFP(rstio)); + if (IoIFP(rstio)) PerlIO_close(IoIFP(rstio)); else close(fd[0]); - if (IoOFP(wstio)) fclose(IoOFP(wstio)); + if (IoOFP(wstio)) PerlIO_close(IoOFP(wstio)); else close(fd[1]); goto badexit; } @@ -317,13 +416,13 @@ PP(pp_fileno) dSP; dTARGET; GV *gv; IO *io; - FILE *fp; + PerlIO *fp; if (MAXARG < 1) RETPUSHUNDEF; gv = (GV*)POPs; if (!gv || !(io = GvIO(gv)) || !(fp = IoIFP(io))) RETPUSHUNDEF; - PUSHi(fileno(fp)); + PUSHi(PerlIO_fileno(fp)); RETURN; } @@ -352,7 +451,7 @@ PP(pp_binmode) dSP; GV *gv; IO *io; - FILE *fp; + PerlIO *fp; if (MAXARG < 1) RETPUSHUNDEF; @@ -361,23 +460,42 @@ PP(pp_binmode) EXTEND(SP, 1); if (!(io = GvIO(gv)) || !(fp = IoIFP(io))) - RETSETUNDEF; + RETPUSHUNDEF; #ifdef DOSISH #ifdef atarist - if (!Fflush(fp) && (fp->_flag |= _IOBIN)) + if (!PerlIO_flush(fp) && (fp->_flag |= _IOBIN)) RETPUSHYES; else RETPUSHUNDEF; #else - if (setmode(fileno(fp), OP_BINARY) != -1) + if (setmode(PerlIO_fileno(fp), OP_BINARY) != -1) { +#if defined(WIN32) && defined(__BORLANDC__) + /* The translation mode of the stream is maintained independent + * of the translation mode of the fd in the Borland RTL (heavy + * digging through their runtime sources reveal). User has to + * set the mode explicitly for the stream (though they don't + * document this anywhere). GSAR 97-5-24 + */ + PerlIO_seek(fp,0L,0); + fp->flags |= _F_BIN; +#endif RETPUSHYES; + } else RETPUSHUNDEF; #endif #else +#if defined(USEMYBINMODE) + if (my_binmode(fp,IoTYPE(io)) != NULL) + RETPUSHYES; + else + RETPUSHUNDEF; +#else RETPUSHYES; #endif +#endif + } PP(pp_tie) @@ -391,6 +509,7 @@ PP(pp_tie) SV **mark = stack_base + ++*markstack_ptr; /* reuse in entersub */ I32 markoff = mark - stack_base - 1; char *methname; + bool oldcatch = CATCH_GET; varsv = mark[0]; if (SvTYPE(varsv) == SVt_PVHV) @@ -403,26 +522,30 @@ PP(pp_tie) methname = "TIESCALAR"; stash = gv_stashsv(mark[1], FALSE); - if (!stash || !(gv = gv_fetchmethod(stash, methname)) || !GvCV(gv)) + if (!stash || !(gv = gv_fetchmethod(stash, methname))) DIE("Can't locate object method \"%s\" via package \"%s\"", methname, SvPV(mark[1],na)); Zero(&myop, 1, BINOP); myop.op_last = (OP *) &myop; myop.op_next = Nullop; - myop.op_flags = OPf_KNOW|OPf_STACKED; + myop.op_flags = OPf_WANT_SCALAR | OPf_STACKED; + CATCH_SET(TRUE); ENTER; SAVESPTR(op); op = (OP *) &myop; + if (PERLDB_SUB && curstash != debstash) + op->op_private |= OPpENTERSUB_DB; - XPUSHs(gv); + XPUSHs((SV*)GvCV(gv)); PUTBACK; if (op = pp_entersub()) runops(); SPAGAIN; + CATCH_SET(oldcatch); sv = TOPs; if (sv_isobject(sv)) { if (SvTYPE(varsv) == SVt_PVHV || SvTYPE(varsv) == SVt_PVAV) { @@ -443,11 +566,29 @@ PP(pp_tie) PP(pp_untie) { dSP; - if (SvTYPE(TOPs) == SVt_PVHV || SvTYPE(TOPs) == SVt_PVAV) - sv_unmagic(TOPs, 'P'); + SV * sv ; + + sv = POPs; + + if (dowarn) { + MAGIC * mg ; + if (SvMAGICAL(sv)) { + if (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV) + mg = mg_find(sv, 'P') ; + else + mg = mg_find(sv, 'q') ; + + if (mg && SvREFCNT(SvRV(mg->mg_obj)) > 1) + warn("untie attempted while %lu inner references still exist", + (unsigned long)SvREFCNT(SvRV(mg->mg_obj)) - 1 ) ; + } + } + + if (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV) + sv_unmagic(sv, 'P'); else - sv_unmagic(TOPs, 'q'); - RETSETYES; + sv_unmagic(sv, 'q'); + RETPUSHYES; } PP(pp_tied) @@ -481,28 +622,32 @@ PP(pp_dbmopen) GV *gv; BINOP myop; SV *sv; + bool oldcatch = CATCH_GET; hv = (HV*)POPs; sv = sv_mortalcopy(&sv_no); sv_setpv(sv, "AnyDBM_File"); stash = gv_stashsv(sv, FALSE); - if (!stash || !(gv = gv_fetchmethod(stash, "TIEHASH")) || !GvCV(gv)) { + if (!stash || !(gv = gv_fetchmethod(stash, "TIEHASH"))) { PUTBACK; perl_require_pv("AnyDBM_File.pm"); SPAGAIN; - if (!(gv = gv_fetchmethod(stash, "TIEHASH")) || !GvCV(gv)) + if (!(gv = gv_fetchmethod(stash, "TIEHASH"))) DIE("No dbm on this machine"); } Zero(&myop, 1, BINOP); myop.op_last = (OP *) &myop; myop.op_next = Nullop; - myop.op_flags = OPf_KNOW|OPf_STACKED; + myop.op_flags = OPf_WANT_SCALAR | OPf_STACKED; + CATCH_SET(TRUE); ENTER; SAVESPTR(op); op = (OP *) &myop; + if (PERLDB_SUB && curstash != debstash) + op->op_private |= OPpENTERSUB_DB; PUTBACK; pp_pushmark(); @@ -514,7 +659,7 @@ PP(pp_dbmopen) else PUSHs(sv_2mortal(newSViv(O_RDWR))); PUSHs(right); - PUSHs(gv); + PUSHs((SV*)GvCV(gv)); PUTBACK; if (op = pp_entersub()) @@ -531,7 +676,7 @@ PP(pp_dbmopen) PUSHs(left); PUSHs(sv_2mortal(newSViv(O_RDONLY))); PUSHs(right); - PUSHs(gv); + PUSHs((SV*)GvCV(gv)); PUTBACK; if (op = pp_entersub()) @@ -539,6 +684,7 @@ PP(pp_dbmopen) SPAGAIN; } + CATCH_SET(oldcatch); if (sv_isobject(TOPs)) sv_magic((SV*)hv, TOPs, 'P', Nullch, 0); LEAVE; @@ -588,7 +734,7 @@ PP(pp_sselect) } #if BYTEORDER == 0x1234 || BYTEORDER == 0x12345678 -#ifdef __linux__ +#if defined(__linux__) || defined(OS2) growsize = sizeof(fd_set); #else growsize = maxlen; /* little endians can use vecs directly */ @@ -710,12 +856,14 @@ PP(pp_select) if (! hv) XPUSHs(&sv_undef); else { - GV **gvp = hv_fetch(hv, GvNAME(egv), GvNAMELEN(egv), FALSE); - if (gvp && *gvp == egv) - gv_efullname(TARG, defoutgv); - else - sv_setsv(TARG, sv_2mortal(newRV(egv))); - XPUSHTARG; + GV **gvp = (GV**)hv_fetch(hv, GvNAME(egv), GvNAMELEN(egv), FALSE); + if (gvp && *gvp == egv) { + gv_efullname3(TARG, defoutgv, Nullch); + XPUSHTARG; + } + else { + XPUSHs(sv_2mortal(newRV((SV*)egv))); + } } if (newdefout) { @@ -731,6 +879,7 @@ PP(pp_getc) { dSP; dTARGET; GV *gv; + MAGIC *mg; if (MAXARG <= 0) gv = stdingv; @@ -738,11 +887,25 @@ PP(pp_getc) gv = (GV*)POPs; if (!gv) gv = argvgv; + + if (SvMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) { + I32 gimme = GIMME_V; + PUSHMARK(SP); + XPUSHs(mg->mg_obj); + PUTBACK; + ENTER; + perl_call_method("GETC", gimme); + LEAVE; + SPAGAIN; + if (gimme == G_SCALAR) + SvSetMagicSV_nosteal(TARG, TOPs); + RETURN; + } if (!gv || do_eof(gv)) /* make sure we have fp with something */ RETPUSHUNDEF; - TAINT_IF(1); + TAINT; sv_setpv(TARG, " "); - *SvPVX(TARG) = getc(IoIFP(GvIOp(gv))); /* should never be EOF */ + *SvPVX(TARG) = PerlIO_getc(IoIFP(GvIOp(gv))); /* should never be EOF */ PUSHTARG; RETURN; } @@ -759,7 +922,7 @@ GV *gv; OP *retop; { register CONTEXT *cx; - I32 gimme = GIMME; + I32 gimme = GIMME_V; AV* padlist = CvPADLIST(cv); SV** svp = AvARRAY(padlist); @@ -802,17 +965,18 @@ PP(pp_enterwrite) fgv = gv; cv = GvFORM(fgv); - if (!cv) { if (fgv) { SV *tmpsv = sv_newmortal(); - gv_efullname(tmpsv, gv); + gv_efullname3(tmpsv, fgv, Nullch); DIE("Undefined format \"%s\" called",SvPVX(tmpsv)); } DIE("Not a format reference"); } - IoFLAGS(io) &= ~IOf_DIDTOP; + if (CvCLONE(cv)) + cv = (CV*)sv_2mortal((SV*)cv_clone(cv)); + IoFLAGS(io) &= ~IOf_DIDTOP; return doform(cv,gv,op->op_next); } @@ -821,13 +985,13 @@ PP(pp_leavewrite) dSP; GV *gv = cxstack[cxstack_ix].blk_sub.gv; register IO *io = GvIOp(gv); - FILE *ofp = IoOFP(io); - FILE *fp; + PerlIO *ofp = IoOFP(io); + PerlIO *fp; SV **newsp; I32 gimme; register CONTEXT *cx; - DEBUG_f(fprintf(stderr,"left=%ld, todo=%ld\n", + DEBUG_f(PerlIO_printf(Perl_debug_log, "left=%ld, todo=%ld\n", (long)IoLINES_LEFT(io), (long)FmLINES(formtarget))); if (IoLINES_LEFT(io) < FmLINES(formtarget) && formtarget != toptarget) @@ -836,16 +1000,16 @@ PP(pp_leavewrite) CV *cv; if (!IoTOP_GV(io)) { GV *topgv; - char tmpbuf[256]; + SV *topname; if (!IoTOP_NAME(io)) { if (!IoFMT_NAME(io)) IoFMT_NAME(io) = savepv(GvNAME(gv)); - sprintf(tmpbuf, "%s_TOP", IoFMT_NAME(io)); - topgv = gv_fetchpv(tmpbuf,FALSE, SVt_PVFM); + topname = sv_2mortal(newSVpvf("%s_TOP", IoFMT_NAME(io))); + topgv = gv_fetchpv(SvPVX(topname), FALSE, SVt_PVFM); if ((topgv && GvFORM(topgv)) || !gv_fetchpv("top",FALSE,SVt_PVFM)) - IoTOP_NAME(io) = savepv(tmpbuf); + IoTOP_NAME(io) = savepv(SvPVX(topname)); else IoTOP_NAME(io) = savepv("top"); } @@ -868,13 +1032,13 @@ PP(pp_leavewrite) s++; } if (s) { - fwrite1(SvPVX(formtarget), s - SvPVX(formtarget), 1, ofp); + PerlIO_write(ofp, SvPVX(formtarget), s - SvPVX(formtarget)); sv_chop(formtarget, s); FmLINES(formtarget) -= IoLINES_LEFT(io); } } if (IoLINES_LEFT(io) >= 0 && IoPAGE(io) > 0) - fwrite1(SvPVX(formfeed), SvCUR(formfeed), 1, ofp); + PerlIO_write(ofp, SvPVX(formfeed), SvCUR(formfeed)); IoLINES_LEFT(io) = IoPAGE_LEN(io); IoPAGE(io)++; formtarget = toptarget; @@ -885,9 +1049,11 @@ PP(pp_leavewrite) cv = GvFORM(fgv); if (!cv) { SV *tmpsv = sv_newmortal(); - gv_efullname(tmpsv, fgv); + gv_efullname3(tmpsv, fgv, Nullch); DIE("Undefined top format \"%s\" called",SvPVX(tmpsv)); } + if (CvCLONE(cv)) + cv = (CV*)sv_2mortal((SV*)cv_clone(cv)); return doform(cv,gv,op); } @@ -911,15 +1077,15 @@ PP(pp_leavewrite) if (dowarn) warn("page overflow"); } - if (!fwrite1(SvPVX(formtarget), 1, SvCUR(formtarget), ofp) || - ferror(fp)) + if (!PerlIO_write(ofp, SvPVX(formtarget), SvCUR(formtarget)) || + PerlIO_error(fp)) PUSHs(&sv_no); else { FmLINES(formtarget) = 0; SvCUR_set(formtarget, 0); *SvEND(formtarget) = '\0'; if (IoFLAGS(io) & IOf_FLUSH) - (void)Fflush(fp); + (void)PerlIO_flush(fp); PUSHs(&sv_yes); } } @@ -933,16 +1099,39 @@ PP(pp_prtf) dSP; dMARK; dORIGMARK; GV *gv; IO *io; - FILE *fp; - SV *sv = NEWSV(0,0); + PerlIO *fp; + SV *sv; + MAGIC *mg; if (op->op_flags & OPf_STACKED) gv = (GV*)*++MARK; else gv = defoutgv; + + if (SvMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) { + if (MARK == ORIGMARK) { + EXTEND(SP, 1); + ++MARK; + Move(MARK, MARK + 1, (SP - MARK) + 1, SV*); + ++SP; + } + PUSHMARK(MARK - 1); + *MARK = mg->mg_obj; + PUTBACK; + ENTER; + perl_call_method("PRINTF", G_SCALAR); + LEAVE; + SPAGAIN; + MARK = ORIGMARK + 1; + *MARK = *SP; + SP = MARK; + RETURN; + } + + sv = NEWSV(0,0); if (!(io = GvIO(gv))) { if (dowarn) { - gv_fullname(sv,gv); + gv_fullname3(sv, gv, Nullch); warn("Filehandle %s never opened", SvPV(sv,na)); } SETERRNO(EBADF,RMS$_IFI); @@ -950,7 +1139,7 @@ PP(pp_prtf) } else if (!(fp = IoOFP(io))) { if (dowarn) { - gv_fullname(sv,gv); + gv_fullname3(sv, gv, Nullch); if (IoIFP(io)) warn("Filehandle %s opened only for input", SvPV(sv,na)); else @@ -960,12 +1149,18 @@ PP(pp_prtf) goto just_say_no; } else { +#ifdef USE_LOCALE_NUMERIC + if (op->op_private & OPpLOCALE) + SET_NUMERIC_LOCAL(); + else + SET_NUMERIC_STANDARD(); +#endif do_sprintf(sv, SP - MARK, MARK + 1); if (!do_print(sv, fp)) goto just_say_no; if (IoFLAGS(io) & IOf_FLUSH) - if (Fflush(fp) == EOF) + if (PerlIO_flush(fp) == EOF) goto just_say_no; } SvREFCNT_dec(sv); @@ -1015,15 +1210,35 @@ PP(pp_sysread) GV *gv; IO *io; char *buffer; - int length; - int bufsize; + SSize_t length; + Sock_size_t bufsize; SV *bufsv; STRLEN blen; + MAGIC *mg; gv = (GV*)*++MARK; + if ((op->op_type == OP_READ || op->op_type == OP_SYSREAD) && + SvMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) + { + SV *sv; + + PUSHMARK(MARK-1); + *MARK = mg->mg_obj; + ENTER; + perl_call_method("READ", G_SCALAR); + LEAVE; + SPAGAIN; + sv = POPs; + SP = ORIGMARK; + PUSHs(sv); + RETURN; + } + if (!gv) goto say_undef; bufsv = *++MARK; + if (! SvOK(bufsv)) + sv_setpvn(bufsv, "", 0); buffer = SvPV_force(bufsv, blen); length = SvIVx(*++MARK); if (length < 0) @@ -1038,20 +1253,27 @@ PP(pp_sysread) goto say_undef; #ifdef HAS_SOCKET if (op->op_type == OP_RECV) { - bufsize = sizeof buf; + char namebuf[MAXPATHLEN]; +#if defined(VMS_DO_SOCKETS) && defined(DECCRTL_SOCKETS) + bufsize = sizeof (struct sockaddr_in); +#else + bufsize = sizeof namebuf; +#endif buffer = SvGROW(bufsv, length+1); - length = recvfrom(fileno(IoIFP(io)), buffer, length, offset, - (struct sockaddr *)buf, &bufsize); + /* 'offset' means 'flags' here */ + length = recvfrom(PerlIO_fileno(IoIFP(io)), buffer, length, offset, + (struct sockaddr *)namebuf, &bufsize); if (length < 0) RETPUSHUNDEF; SvCUR_set(bufsv, length); *SvEND(bufsv) = '\0'; (void)SvPOK_only(bufsv); SvSETMAGIC(bufsv); - if (tainting) - sv_magic(bufsv, Nullsv, 't', Nullch, 0); + /* This should not be marked tainted if the fp is marked clean */ + if (!(IoFLAGS(io) & IOf_UNTAINT)) + SvTAINTED_on(bufsv); SP = ORIGMARK; - sv_setpvn(TARG, buf, bufsize); + sv_setpvn(TARG, namebuf, bufsize); PUSHs(TARG); RETURN; } @@ -1059,28 +1281,43 @@ PP(pp_sysread) if (op->op_type == OP_RECV) DIE(no_sock_func, "recv"); #endif + if (offset < 0) { + if (-offset > blen) + DIE("Offset outside string"); + offset += blen; + } + bufsize = SvCUR(bufsv); buffer = SvGROW(bufsv, length+offset+1); + if (offset > bufsize) { /* Zero any newly allocated space */ + Zero(buffer+bufsize, offset-bufsize, char); + } if (op->op_type == OP_SYSREAD) { - length = read(fileno(IoIFP(io)), buffer+offset, length); + length = read(PerlIO_fileno(IoIFP(io)), buffer+offset, length); } else #ifdef HAS_SOCKET__bad_code_maybe if (IoTYPE(io) == 's') { - bufsize = sizeof buf; - length = recvfrom(fileno(IoIFP(io)), buffer+offset, length, 0, - (struct sockaddr *)buf, &bufsize); + char namebuf[MAXPATHLEN]; +#if defined(VMS_DO_SOCKETS) && defined(DECCRTL_SOCKETS) + bufsize = sizeof (struct sockaddr_in); +#else + bufsize = sizeof namebuf; +#endif + length = recvfrom(PerlIO_fileno(IoIFP(io)), buffer+offset, length, 0, + (struct sockaddr *)namebuf, &bufsize); } else #endif - length = fread(buffer+offset, 1, length, IoIFP(io)); + length = PerlIO_read(IoIFP(io), buffer+offset, length); if (length < 0) goto say_undef; SvCUR_set(bufsv, length+offset); *SvEND(bufsv) = '\0'; (void)SvPOK_only(bufsv); SvSETMAGIC(bufsv); - if (tainting) - sv_magic(bufsv, Nullsv, 't', Nullch, 0); + /* This should not be marked tainted if the fp is marked clean */ + if (!(IoFLAGS(io) & IOf_UNTAINT)) + SvTAINTED_on(bufsv); SP = ORIGMARK; PUSHi(length); RETURN; @@ -1126,24 +1363,31 @@ PP(pp_send) } } else if (op->op_type == OP_SYSWRITE) { - if (MARK < SP) + if (MARK < SP) { offset = SvIVx(*++MARK); - else + if (offset < 0) { + if (-offset > blen) + DIE("Offset outside string"); + offset += blen; + } else if (offset >= blen && blen > 0) + DIE("Offset outside string"); + } else offset = 0; if (length > blen - offset) length = blen - offset; - length = write(fileno(IoIFP(io)), buffer+offset, length); + length = write(PerlIO_fileno(IoIFP(io)), buffer+offset, length); } #ifdef HAS_SOCKET else if (SP > MARK) { char *sockbuf; STRLEN mlen; sockbuf = SvPVx(*++MARK, mlen); - length = sendto(fileno(IoIFP(io)), buffer, blen, length, + length = sendto(PerlIO_fileno(IoIFP(io)), buffer, blen, length, (struct sockaddr *)sockbuf, mlen); } else - length = send(fileno(IoIFP(io)), buffer, blen, length); + length = send(PerlIO_fileno(IoIFP(io)), buffer, blen, length); + #else else DIE(no_sock_func, "send"); @@ -1173,7 +1417,7 @@ PP(pp_eof) gv = last_in_gv; else gv = last_in_gv = (GV*)POPs; - PUSHs(!gv || do_eof(gv) ? &sv_yes : &sv_no); + PUSHs(boolSV(!gv || do_eof(gv))); RETURN; } @@ -1192,13 +1436,25 @@ PP(pp_tell) PP(pp_seek) { + return pp_sysseek(ARGS); +} + +PP(pp_sysseek) +{ dSP; GV *gv; int whence = POPi; long offset = POPl; gv = last_in_gv = (GV*)POPs; - PUSHs( do_seek(gv, offset, whence) ? &sv_yes : &sv_no ); + if (op->op_type == OP_SEEK) + PUSHs(boolSV(do_seek(gv, offset, whence))); + else { + long n = do_sysseek(gv, offset, whence); + PUSHs((n < 0) ? &sv_undef + : sv_2mortal(n ? newSViv((IV)n) + : newSVpv(zero_but_true, ZBTLEN))); + } RETURN; } @@ -1211,34 +1467,49 @@ PP(pp_truncate) SETERRNO(0,0); #if defined(HAS_TRUNCATE) || defined(HAS_CHSIZE) || defined(F_FREESP) -#ifdef HAS_TRUNCATE - if (op->op_flags & OPf_SPECIAL) { - tmpgv = gv_fetchpv(POPp,FALSE, SVt_PVIO); - if (!GvIO(tmpgv) || !IoIFP(GvIOp(tmpgv)) || - ftruncate(fileno(IoIFP(GvIOn(tmpgv))), len) < 0) - result = 0; - } - else if (truncate(POPp, len) < 0) - result = 0; -#else if (op->op_flags & OPf_SPECIAL) { - tmpgv = gv_fetchpv(POPp,FALSE, SVt_PVIO); + tmpgv = gv_fetchpv(POPp, FALSE, SVt_PVIO); + do_ftruncate: + TAINT_PROPER("truncate"); if (!GvIO(tmpgv) || !IoIFP(GvIOp(tmpgv)) || - chsize(fileno(IoIFP(GvIOn(tmpgv))), len) < 0) +#ifdef HAS_TRUNCATE + ftruncate(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), len) < 0) +#else + my_chsize(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), len) < 0) +#endif result = 0; } else { - int tmpfd; + SV *sv = POPs; + char *name; + + if (SvTYPE(sv) == SVt_PVGV) { + tmpgv = (GV*)sv; /* *main::FRED for example */ + goto do_ftruncate; + } + else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) { + tmpgv = (GV*) SvRV(sv); /* \*main::FRED for example */ + goto do_ftruncate; + } - if ((tmpfd = open(POPp, 0)) < 0) + name = SvPV(sv, na); + TAINT_PROPER("truncate"); +#ifdef HAS_TRUNCATE + if (truncate(name, len) < 0) result = 0; - else { - if (chsize(tmpfd, len) < 0) +#else + { + int tmpfd; + if ((tmpfd = open(name, O_RDWR)) < 0) result = 0; - close(tmpfd); + else { + if (my_chsize(tmpfd, len) < 0) + result = 0; + close(tmpfd); + } } - } #endif + } if (result) RETPUSHYES; @@ -1262,7 +1533,7 @@ PP(pp_ioctl) unsigned int func = U_I(POPn); int optype = op->op_type; char *s; - int retval; + IV retval; GV *gv = (GV*)POPs; IO *io = GvIOn(gv); @@ -1273,45 +1544,38 @@ PP(pp_ioctl) if (SvPOK(argsv) || !SvNIOK(argsv)) { STRLEN len; + STRLEN need; s = SvPV_force(argsv, len); - retval = IOCPARM_LEN(func); - if (len < retval) { - s = Sv_Grow(argsv, retval+1); - SvCUR_set(argsv, retval); + need = IOCPARM_LEN(func); + if (len < need) { + s = Sv_Grow(argsv, need + 1); + SvCUR_set(argsv, need); } s[SvCUR(argsv)] = 17; /* a little sanity check here */ } else { retval = SvIV(argsv); -#ifdef DOSISH - s = (char*)(long)retval; /* ouch */ -#else s = (char*)retval; /* ouch */ -#endif } TAINT_PROPER(optype == OP_IOCTL ? "ioctl" : "fcntl"); if (optype == OP_IOCTL) #ifdef HAS_IOCTL - retval = ioctl(fileno(IoIFP(io)), func, s); + retval = ioctl(PerlIO_fileno(IoIFP(io)), func, s); #else DIE("ioctl is not implemented"); #endif else -#if defined(DOSISH) && !defined(OS2) - DIE("fcntl is not implemented"); +#ifdef HAS_FCNTL +#if defined(OS2) && defined(__EMX__) + retval = fcntl(PerlIO_fileno(IoIFP(io)), func, (int)s); +#else + retval = fcntl(PerlIO_fileno(IoIFP(io)), func, s); +#endif #else -# ifdef HAS_FCNTL -# if defined(OS2) && defined(__EMX__) - retval = fcntl(fileno(IoIFP(io)), func, (int)s); -# else - retval = fcntl(fileno(IoIFP(io)), func, s); -# endif -# else DIE("fcntl is not implemented"); -# endif #endif if (SvPOK(argsv)) { @@ -1328,7 +1592,7 @@ PP(pp_ioctl) PUSHi(retval); } else { - PUSHp("0 but true", 10); + PUSHp(zero_but_true, ZBTLEN); } RETURN; } @@ -1339,13 +1603,9 @@ PP(pp_flock) I32 value; int argtype; GV *gv; - FILE *fp; - -#if !defined(HAS_FLOCK) && defined(HAS_LOCKF) -# define flock lockf_emulate_flock -#endif + PerlIO *fp; -#if defined(HAS_FLOCK) || defined(flock) +#ifdef FLOCK argtype = POPi; if (MAXARG <= 0) gv = last_in_gv; @@ -1356,7 +1616,8 @@ PP(pp_flock) else fp = Nullfp; if (fp) { - value = (I32)(flock(fileno(fp), argtype) >= 0); + (void)PerlIO_flush(fp); + value = (I32)(FLOCK(PerlIO_fileno(fp), argtype) >= 0); } else value = 0; @@ -1395,12 +1656,12 @@ PP(pp_socket) fd = socket(domain, type, protocol); if (fd < 0) RETPUSHUNDEF; - IoIFP(io) = fdopen(fd, "r"); /* stdio gets confused about sockets */ - IoOFP(io) = fdopen(fd, "w"); + IoIFP(io) = PerlIO_fdopen(fd, "r"); /* stdio gets confused about sockets */ + IoOFP(io) = PerlIO_fdopen(fd, "w"); IoTYPE(io) = 's'; if (!IoIFP(io) || !IoOFP(io)) { - if (IoIFP(io)) fclose(IoIFP(io)); - if (IoOFP(io)) fclose(IoOFP(io)); + if (IoIFP(io)) PerlIO_close(IoIFP(io)); + if (IoOFP(io)) PerlIO_close(IoOFP(io)); if (!IoIFP(io) && !IoOFP(io)) close(fd); RETPUSHUNDEF; } @@ -1439,18 +1700,18 @@ PP(pp_sockpair) TAINT_PROPER("socketpair"); if (socketpair(domain, type, protocol, fd) < 0) RETPUSHUNDEF; - IoIFP(io1) = fdopen(fd[0], "r"); - IoOFP(io1) = fdopen(fd[0], "w"); + IoIFP(io1) = PerlIO_fdopen(fd[0], "r"); + IoOFP(io1) = PerlIO_fdopen(fd[0], "w"); IoTYPE(io1) = 's'; - IoIFP(io2) = fdopen(fd[1], "r"); - IoOFP(io2) = fdopen(fd[1], "w"); + IoIFP(io2) = PerlIO_fdopen(fd[1], "r"); + IoOFP(io2) = PerlIO_fdopen(fd[1], "w"); IoTYPE(io2) = 's'; if (!IoIFP(io1) || !IoOFP(io1) || !IoIFP(io2) || !IoOFP(io2)) { - if (IoIFP(io1)) fclose(IoIFP(io1)); - if (IoOFP(io1)) fclose(IoOFP(io1)); + if (IoIFP(io1)) PerlIO_close(IoIFP(io1)); + if (IoOFP(io1)) PerlIO_close(IoOFP(io1)); if (!IoIFP(io1) && !IoOFP(io1)) close(fd[0]); - if (IoIFP(io2)) fclose(IoIFP(io2)); - if (IoOFP(io2)) fclose(IoOFP(io2)); + if (IoIFP(io2)) PerlIO_close(IoIFP(io2)); + if (IoOFP(io2)) PerlIO_close(IoOFP(io2)); if (!IoIFP(io2) && !IoOFP(io2)) close(fd[1]); RETPUSHUNDEF; } @@ -1476,7 +1737,7 @@ PP(pp_bind) addr = SvPV(addrsv, len); TAINT_PROPER("bind"); - if (bind(fileno(IoIFP(io)), (struct sockaddr *)addr, len) >= 0) + if (bind(PerlIO_fileno(IoIFP(io)), (struct sockaddr *)addr, len) >= 0) RETPUSHYES; else RETPUSHUNDEF; @@ -1506,7 +1767,7 @@ PP(pp_connect) addr = SvPV(addrsv, len); TAINT_PROPER("connect"); - if (connect(fileno(IoIFP(io)), (struct sockaddr *)addr, len) >= 0) + if (connect(PerlIO_fileno(IoIFP(io)), (struct sockaddr *)addr, len) >= 0) RETPUSHYES; else RETPUSHUNDEF; @@ -1532,7 +1793,7 @@ PP(pp_listen) if (!io || !IoIFP(io)) goto nuts; - if (listen(fileno(IoIFP(io)), backlog) >= 0) + if (listen(PerlIO_fileno(IoIFP(io)), backlog) >= 0) RETPUSHYES; else RETPUSHUNDEF; @@ -1556,7 +1817,7 @@ PP(pp_accept) register IO *nstio; register IO *gstio; struct sockaddr saddr; /* use a struct to avoid alignment problems */ - int len = sizeof saddr; + Sock_size_t len = sizeof saddr; int fd; ggv = (GV*)POPs; @@ -1575,15 +1836,15 @@ PP(pp_accept) if (IoIFP(nstio)) do_close(ngv, FALSE); - fd = accept(fileno(IoIFP(gstio)), (struct sockaddr *)&saddr, &len); + fd = accept(PerlIO_fileno(IoIFP(gstio)), (struct sockaddr *)&saddr, &len); if (fd < 0) goto badexit; - IoIFP(nstio) = fdopen(fd, "r"); - IoOFP(nstio) = fdopen(fd, "w"); + IoIFP(nstio) = PerlIO_fdopen(fd, "r"); + IoOFP(nstio) = PerlIO_fdopen(fd, "w"); IoTYPE(nstio) = 's'; if (!IoIFP(nstio) || !IoOFP(nstio)) { - if (IoIFP(nstio)) fclose(IoIFP(nstio)); - if (IoOFP(nstio)) fclose(IoOFP(nstio)); + if (IoIFP(nstio)) PerlIO_close(IoIFP(nstio)); + if (IoOFP(nstio)) PerlIO_close(IoOFP(nstio)); if (!IoIFP(nstio) && !IoOFP(nstio)) close(fd); goto badexit; } @@ -1615,7 +1876,7 @@ PP(pp_shutdown) if (!io || !IoIFP(io)) goto nuts; - PUSHi( shutdown(fileno(IoIFP(io)), how) >= 0 ); + PUSHi( shutdown(PerlIO_fileno(IoIFP(io)), how) >= 0 ); RETURN; nuts: @@ -1648,7 +1909,7 @@ PP(pp_ssockopt) unsigned int lvl; GV *gv; register IO *io; - int aint; + Sock_size_t len; if (optype == OP_GSOCKOPT) sv = sv_2mortal(NEWSV(22, 257)); @@ -1662,31 +1923,33 @@ PP(pp_ssockopt) if (!io || !IoIFP(io)) goto nuts; - fd = fileno(IoIFP(io)); + fd = PerlIO_fileno(IoIFP(io)); switch (optype) { case OP_GSOCKOPT: SvGROW(sv, 257); (void)SvPOK_only(sv); SvCUR_set(sv,256); *SvEND(sv) ='\0'; - aint = SvCUR(sv); - if (getsockopt(fd, lvl, optname, SvPVX(sv), &aint) < 0) + len = SvCUR(sv); + if (getsockopt(fd, lvl, optname, SvPVX(sv), &len) < 0) goto nuts2; - SvCUR_set(sv,aint); + SvCUR_set(sv, len); *SvEND(sv) ='\0'; PUSHs(sv); break; case OP_SSOCKOPT: { - STRLEN len = 0; - char *buf = 0; - if (SvPOKp(sv)) - buf = SvPV(sv, len); + char *buf; + int aint; + if (SvPOKp(sv)) { + buf = SvPV(sv, na); + len = na; + } else if (SvOK(sv)) { aint = (int)SvIV(sv); buf = (char*)&aint; len = sizeof(int); } - if (setsockopt(fd, lvl, optname, buf, (int)len) < 0) + if (setsockopt(fd, lvl, optname, buf, len) < 0) goto nuts2; PUSHs(&sv_yes); } @@ -1724,28 +1987,45 @@ PP(pp_getpeername) int fd; GV *gv = (GV*)POPs; register IO *io = GvIOn(gv); - int aint; + Sock_size_t len; if (!io || !IoIFP(io)) goto nuts; sv = sv_2mortal(NEWSV(22, 257)); (void)SvPOK_only(sv); - SvCUR_set(sv,256); + len = 256; + SvCUR_set(sv, len); *SvEND(sv) ='\0'; - aint = SvCUR(sv); - fd = fileno(IoIFP(io)); + fd = PerlIO_fileno(IoIFP(io)); switch (optype) { case OP_GETSOCKNAME: - if (getsockname(fd, (struct sockaddr *)SvPVX(sv), &aint) < 0) + if (getsockname(fd, (struct sockaddr *)SvPVX(sv), &len) < 0) goto nuts2; break; case OP_GETPEERNAME: - if (getpeername(fd, (struct sockaddr *)SvPVX(sv), &aint) < 0) + if (getpeername(fd, (struct sockaddr *)SvPVX(sv), &len) < 0) goto nuts2; +#if defined(VMS_DO_SOCKETS) && defined (DECCRTL_SOCKETS) + { + static const char nowhere[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + /* If the call succeeded, make sure we don't have a zeroed port/addr */ + if (((struct sockaddr *)SvPVX(sv))->sa_family == AF_INET && + !memcmp((char *)SvPVX(sv) + sizeof(u_short), nowhere, + sizeof(u_short) + sizeof(struct in_addr))) { + goto nuts2; + } + } +#endif break; } - SvCUR_set(sv,aint); +#ifdef BOGUS_GETNAME_RETURN + /* Interactive Unix, getpeername() and getsockname() + does not return valid namelen */ + if (len == BOGUS_GETNAME_RETURN) + len = sizeof(struct sockaddr); +#endif + SvCUR_set(sv, len); *SvEND(sv) ='\0'; PUSHs(sv); RETURN; @@ -1773,6 +2053,7 @@ PP(pp_stat) { dSP; GV *tmpgv; + I32 gimme; I32 max = 13; if (op->op_flags & OPf_REF) { @@ -1782,13 +2063,10 @@ PP(pp_stat) laststype = OP_STAT; statgv = tmpgv; sv_setpv(statname, ""); - if (!GvIO(tmpgv) || !IoIFP(GvIOp(tmpgv)) || - Fstat(fileno(IoIFP(GvIOn(tmpgv))), &statcache) < 0) { - max = 0; - laststatval = -1; - } + laststatval = (GvIO(tmpgv) && IoIFP(GvIOp(tmpgv)) + ? Fstat(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), &statcache) : -1); } - else if (laststatval < 0) + if (laststatval < 0) max = 0; } else { @@ -1817,25 +2095,36 @@ PP(pp_stat) } } - EXTEND(SP, 13); - if (GIMME != G_ARRAY) { - if (max) - RETPUSHYES; - else - RETPUSHUNDEF; + gimme = GIMME_V; + if (gimme != G_ARRAY) { + if (gimme != G_VOID) + XPUSHs(boolSV(max)); + RETURN; } if (max) { + EXTEND(SP, max); + EXTEND_MORTAL(max); PUSHs(sv_2mortal(newSViv((I32)statcache.st_dev))); PUSHs(sv_2mortal(newSViv((I32)statcache.st_ino))); PUSHs(sv_2mortal(newSViv((I32)statcache.st_mode))); PUSHs(sv_2mortal(newSViv((I32)statcache.st_nlink))); PUSHs(sv_2mortal(newSViv((I32)statcache.st_uid))); PUSHs(sv_2mortal(newSViv((I32)statcache.st_gid))); +#ifdef USE_STAT_RDEV PUSHs(sv_2mortal(newSViv((I32)statcache.st_rdev))); +#else + PUSHs(sv_2mortal(newSVpv("", 0))); +#endif PUSHs(sv_2mortal(newSViv((I32)statcache.st_size))); +#ifdef BIG_TIME + PUSHs(sv_2mortal(newSVnv((U32)statcache.st_atime))); + PUSHs(sv_2mortal(newSVnv((U32)statcache.st_mtime))); + PUSHs(sv_2mortal(newSVnv((U32)statcache.st_ctime))); +#else PUSHs(sv_2mortal(newSViv((I32)statcache.st_atime))); PUSHs(sv_2mortal(newSViv((I32)statcache.st_mtime))); PUSHs(sv_2mortal(newSViv((I32)statcache.st_ctime))); +#endif #ifdef USE_STAT_BLOCKS PUSHs(sv_2mortal(newSViv((I32)statcache.st_blksize))); PUSHs(sv_2mortal(newSViv((I32)statcache.st_blocks))); @@ -2113,16 +2402,20 @@ PP(pp_fttty) dSP; int fd; GV *gv; - char *tmps; - if (op->op_flags & OPf_REF) { + char *tmps = Nullch; + + if (op->op_flags & OPf_REF) gv = cGVOP->op_gv; - tmps = ""; - } + else if (isGV(TOPs)) + gv = (GV*)POPs; + else if (SvROK(TOPs) && isGV(SvRV(TOPs))) + gv = (GV*)SvRV(POPs); else gv = gv_fetchpv(tmps = POPp, FALSE, SVt_PVIO); + if (GvIO(gv) && IoIFP(GvIOp(gv))) - fd = fileno(IoIFP(GvIOp(gv))); - else if (isDIGIT(*tmps)) + fd = PerlIO_fileno(IoIFP(GvIOp(gv))); + else if (tmps && isDIGIT(*tmps)) fd = atoi(tmps); else RETPUSHUNDEF; @@ -2148,11 +2441,21 @@ PP(pp_fttext) STDCHAR tbuf[512]; register STDCHAR *s; register IO *io; - SV *sv; + register SV *sv; + GV *gv; - if (op->op_flags & OPf_REF) { + if (op->op_flags & OPf_REF) + gv = cGVOP->op_gv; + else if (isGV(TOPs)) + gv = (GV*)POPs; + else if (SvROK(TOPs) && isGV(SvRV(TOPs))) + gv = (GV*)SvRV(POPs); + else + gv = Nullgv; + + if (gv) { EXTEND(SP, 1); - if (cGVOP->op_gv == defgv) { + if (gv == defgv) { if (statgv) io = GvIO(statgv); else { @@ -2161,30 +2464,34 @@ PP(pp_fttext) } } else { - statgv = cGVOP->op_gv; + statgv = gv; + laststatval = -1; sv_setpv(statname, ""); io = GvIO(statgv); } if (io && IoIFP(io)) { -#ifdef FILE_base - Fstat(fileno(IoIFP(io)), &statcache); + if (! PerlIO_has_base(IoIFP(io))) + DIE("-T and -B not implemented on filehandles"); + laststatval = Fstat(PerlIO_fileno(IoIFP(io)), &statcache); + if (laststatval < 0) + RETPUSHUNDEF; if (S_ISDIR(statcache.st_mode)) /* handle NFS glitch */ if (op->op_type == OP_FTTEXT) RETPUSHNO; else RETPUSHYES; - if (FILE_cnt(IoIFP(io)) <= 0) { - i = getc(IoIFP(io)); + if (PerlIO_get_cnt(IoIFP(io)) <= 0) { + i = PerlIO_getc(IoIFP(io)); if (i != EOF) - (void)ungetc(i, IoIFP(io)); + (void)PerlIO_ungetc(IoIFP(io),i); } - if (FILE_cnt(IoIFP(io)) <= 0) /* null file is anything */ + if (PerlIO_get_cnt(IoIFP(io)) <= 0) /* null file is anything */ RETPUSHYES; - len = FILE_bufsiz(IoIFP(io)); - s = FILE_base(IoIFP(io)); -#else - DIE("-T and -B not implemented on filehandles"); -#endif + len = PerlIO_get_bufsiz(IoIFP(io)); + s = (STDCHAR *) PerlIO_get_base(IoIFP(io)); + /* sfio can have large buffers - limit to 512 */ + if (len > 512) + len = 512; } else { if (dowarn) @@ -2196,9 +2503,10 @@ PP(pp_fttext) } else { sv = POPs; + really_filename: statgv = Nullgv; + laststatval = -1; sv_setpv(statname, SvPV(sv, na)); - really_filename: #ifdef HAS_OPEN3 i = open(SvPV(sv, na), O_RDONLY, 0); #else @@ -2209,7 +2517,9 @@ PP(pp_fttext) warn(warn_nl, "open"); RETPUSHUNDEF; } - Fstat(i, &statcache); + laststatval = Fstat(i, &statcache); + if (laststatval < 0) + RETPUSHUNDEF; len = read(i, tbuf, 512); (void)close(i); if (len <= 0) { @@ -2348,13 +2658,15 @@ PP(pp_rename) #ifdef HAS_RENAME anum = rename(tmps, tmps2); #else - if (same_dirent(tmps2, tmps)) /* can always rename to same name */ - anum = 1; - else { - if (euid || Stat(tmps2, &statbuf) < 0 || !S_ISDIR(statbuf.st_mode)) - (void)UNLINK(tmps2); - if (!(anum = link(tmps, tmps2))) - anum = UNLINK(tmps); + if (!(anum = Stat(tmps, &statbuf))) { + if (same_dirent(tmps2, tmps)) /* can always rename to same name */ + anum = 1; + else { + if (euid || Stat(tmps2, &statbuf) < 0 || !S_ISDIR(statbuf.st_mode)) + (void)UNLINK(tmps2); + if (!(anum = link(tmps, tmps2))) + anum = UNLINK(tmps); + } } #endif SETi( anum >= 0 ); @@ -2394,7 +2706,12 @@ PP(pp_readlink) dSP; dTARGET; #ifdef HAS_SYMLINK char *tmps; + char buf[MAXPATHLEN]; int len; + +#ifndef INCOMPLETE_TAINTS + TAINT; +#endif tmps = POPp; len = readlink(tmps, buf, sizeof buf); EXTEND(SP, 1); @@ -2414,54 +2731,68 @@ dooneliner(cmd, filename) char *cmd; char *filename; { - char mybuf[8192]; - char *s, - *save_filename = filename; + char *save_filename = filename; + char *cmdline; + char *s; + PerlIO *myfp; int anum = 1; - FILE *myfp; - strcpy(mybuf, cmd); - strcat(mybuf, " "); - for (s = mybuf+strlen(mybuf); *filename; ) { + New(666, cmdline, strlen(cmd) + (strlen(filename) * 2) + 10, char); + strcpy(cmdline, cmd); + strcat(cmdline, " "); + for (s = cmdline + strlen(cmdline); *filename; ) { *s++ = '\\'; *s++ = *filename++; } strcpy(s, " 2>&1"); - myfp = my_popen(mybuf, "r"); + myfp = my_popen(cmdline, "r"); + Safefree(cmdline); + if (myfp) { - *mybuf = '\0'; - s = fgets(mybuf, sizeof mybuf, myfp); + SV *tmpsv = sv_newmortal(); + /* Need to save/restore 'rs' ?? */ + s = sv_gets(tmpsv, myfp, 0); (void)my_pclose(myfp); if (s != Nullch) { - for (errno = 1; errno < sys_nerr; errno++) { + int e; + for (e = 1; #ifdef HAS_SYS_ERRLIST - if (instr(mybuf, sys_errlist[errno])) /* you don't see this */ - return 0; + e <= sys_nerr +#endif + ; e++) + { + /* you don't see this */ + char *errmsg = +#ifdef HAS_SYS_ERRLIST + sys_errlist[e] #else - char *errmsg; /* especially if it isn't there */ - - if (instr(mybuf, - (errmsg = strerror(errno)) ? errmsg : "NoErRoR")) - return 0; + strerror(e) #endif + ; + if (!errmsg) + break; + if (instr(s, errmsg)) { + SETERRNO(e,0); + return 0; + } } SETERRNO(0,0); #ifndef EACCES #define EACCES EPERM #endif - if (instr(mybuf, "cannot make")) + if (instr(s, "cannot make")) SETERRNO(EEXIST,RMS$_FEX); - else if (instr(mybuf, "existing file")) + else if (instr(s, "existing file")) SETERRNO(EEXIST,RMS$_FEX); - else if (instr(mybuf, "ile exists")) + else if (instr(s, "ile exists")) SETERRNO(EEXIST,RMS$_FEX); - else if (instr(mybuf, "non-exist")) + else if (instr(s, "non-exist")) SETERRNO(ENOENT,RMS$_FNF); - else if (instr(mybuf, "does not exist")) + else if (instr(s, "does not exist")) SETERRNO(ENOENT,RMS$_FNF); - else if (instr(mybuf, "not empty")) + else if (instr(s, "not empty")) SETERRNO(EBUSY,SS$_DEVOFFLINE); - else if (instr(mybuf, "cannot access")) + else if (instr(s, "cannot access")) SETERRNO(EACCES,RMS$_PRV); else SETERRNO(EPERM,RMS$_PRV); @@ -2494,7 +2825,7 @@ PP(pp_mkdir) TAINT_PROPER("mkdir"); #ifdef HAS_MKDIR - SETi( mkdir(tmps, mode) >= 0 ); + SETi( Mkdir(tmps, mode) >= 0 ); #else SETi( dooneliner("mkdir", tmps) ); oldumask = umask(0); @@ -2557,6 +2888,7 @@ PP(pp_readdir) register Direntry_t *dp; GV *gv = (GV*)POPs; register IO *io = GvIOn(gv); + SV *sv; if (!io || !IoDIRP(io)) goto nope; @@ -2565,20 +2897,28 @@ PP(pp_readdir) /*SUPPRESS 560*/ while (dp = (Direntry_t *)readdir(IoDIRP(io))) { #ifdef DIRNAMLEN - XPUSHs(sv_2mortal(newSVpv(dp->d_name, dp->d_namlen))); + sv = newSVpv(dp->d_name, dp->d_namlen); #else - XPUSHs(sv_2mortal(newSVpv(dp->d_name, 0))); + sv = newSVpv(dp->d_name, 0); #endif +#ifndef INCOMPLETE_TAINTS + SvTAINTED_on(sv); +#endif + XPUSHs(sv_2mortal(sv)); } } else { if (!(dp = (Direntry_t *)readdir(IoDIRP(io)))) goto nope; #ifdef DIRNAMLEN - XPUSHs(sv_2mortal(newSVpv(dp->d_name, dp->d_namlen))); + sv = newSVpv(dp->d_name, dp->d_namlen); #else - XPUSHs(sv_2mortal(newSVpv(dp->d_name, 0))); + sv = newSVpv(dp->d_name, 0); +#endif +#ifndef INCOMPLETE_TAINTS + SvTAINTED_on(sv); #endif + XPUSHs(sv_2mortal(sv)); } RETURN; @@ -2696,19 +3036,19 @@ nope: PP(pp_fork) { +#ifdef HAS_FORK dSP; dTARGET; int childpid; GV *tmpgv; EXTEND(SP, 1); -#ifdef HAS_FORK childpid = fork(); if (childpid < 0) RETSETUNDEF; if (!childpid) { /*SUPPRESS 560*/ if (tmpgv = gv_fetchpv("$", TRUE, SVt_PV)) - sv_setiv(GvSV(tmpgv), (I32)getpid()); + sv_setiv(GvSV(tmpgv), (IV)getpid()); hv_clear(pidstatus); /* no kids, so don't wait for 'em */ } PUSHi(childpid); @@ -2720,19 +3060,14 @@ PP(pp_fork) PP(pp_wait) { +#if !defined(DOSISH) || defined(OS2) dSP; dTARGET; int childpid; int argflags; - I32 value; - EXTEND(SP, 1); -#ifdef HAS_WAIT - childpid = wait(&argflags); - if (childpid > 0) - pidgone(childpid, argflags); - value = (I32)childpid; - statusvalue = FIXSTATUS(argflags); - PUSHi(value); + childpid = wait4pid(-1, &argflags, 0); + STATUS_NATIVE_SET((childpid > 0) ? argflags : -1); + XPUSHi(childpid); RETURN; #else DIE(no_func, "Unsupported function wait"); @@ -2741,19 +3076,17 @@ PP(pp_wait) PP(pp_waitpid) { +#if !defined(DOSISH) || defined(OS2) dSP; dTARGET; int childpid; int optype; int argflags; - I32 value; -#ifdef HAS_WAIT optype = POPi; childpid = TOPi; childpid = wait4pid(childpid, &argflags, optype); - value = (I32)childpid; - statusvalue = FIXSTATUS(argflags); - SETi(value); + STATUS_NATIVE_SET((childpid > 0) ? argflags : -1); + SETi(childpid); RETURN; #else DIE(no_func, "Unsupported function wait"); @@ -2767,10 +3100,8 @@ PP(pp_system) int childpid; int result; int status; - Signal_t (*ihand)(); /* place to save signal during system() */ - Signal_t (*qhand)(); /* place to save signal during system() */ + Sigsave_t ihand,qhand; /* place to save signals during system() */ -#if defined(HAS_FORK) && !defined(VMS) && !defined(OS2) if (SP - MARK == 1) { if (tainting) { char *junk = SvPV(TOPs, na); @@ -2778,6 +3109,7 @@ PP(pp_system) TAINT_PROPER("system"); } } +#if (defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(OS2) while ((childpid = vfork()) == -1) { if (errno != EAGAIN) { value = -1; @@ -2788,22 +3120,17 @@ PP(pp_system) sleep(5); } if (childpid > 0) { - ihand = signal(SIGINT, SIG_IGN); - qhand = signal(SIGQUIT, SIG_IGN); + rsignal_save(SIGINT, SIG_IGN, &ihand); + rsignal_save(SIGQUIT, SIG_IGN, &qhand); do { result = wait4pid(childpid, &status, 0); } while (result == -1 && errno == EINTR); - (void)signal(SIGINT, ihand); - (void)signal(SIGQUIT, qhand); - statusvalue = FIXSTATUS(status); - if (result < 0) - value = -1; - else { - value = (I32)((unsigned int)status & 0xffff); - } + (void)rsignal_restore(SIGINT, &ihand); + (void)rsignal_restore(SIGQUIT, &qhand); + STATUS_NATIVE_SET(result == -1 ? -1 : status); do_execfree(); /* free any memory child malloced on vfork */ SP = ORIGMARK; - PUSHi(value); + PUSHi(STATUS_CURRENT); RETURN; } if (op->op_flags & OPf_STACKED) { @@ -2826,10 +3153,10 @@ PP(pp_system) else { value = (I32)do_spawn(SvPVx(sv_mortalcopy(*SP), na)); } - statusvalue = FIXSTATUS(value); + STATUS_NATIVE_SET(value); do_execfree(); SP = ORIGMARK; - PUSHi(value); + PUSHi(STATUS_CURRENT); #endif /* !FORK or VMS */ RETURN; } @@ -2905,7 +3232,7 @@ PP(pp_getpgrp) #ifdef BSD_GETPGRP value = (I32)BSD_GETPGRP(pid); #else - if (pid != 0) + if (pid != 0 && pid != getpid()) DIE("POSIX getpgrp can't take an argument"); value = (I32)getpgrp(); #endif @@ -2935,9 +3262,8 @@ PP(pp_setpgrp) #ifdef BSD_SETPGRP SETi( BSD_SETPGRP(pid, pgrp) >= 0 ); #else - if ((pgrp != 0) || (pid != 0)) { + if ((pgrp != 0 && pgrp != getpid()) || (pid != 0 && pid != getpid())) DIE("POSIX setpgrp can't take an argument"); - } SETi( setpgrp() >= 0 ); #endif /* USE_BSDPGRP */ RETURN; @@ -2984,19 +3310,35 @@ PP(pp_setpriority) PP(pp_time) { dSP; dTARGET; +#ifdef BIG_TIME + XPUSHn( time(Null(Time_t*)) ); +#else XPUSHi( time(Null(Time_t*)) ); +#endif RETURN; } +/* XXX The POSIX name is CLK_TCK; it is to be preferred + to HZ. Probably. For now, assume that if the system + defines HZ, it does so correctly. (Will this break + on VMS?) + Probably we ought to use _sysconf(_SC_CLK_TCK), if + it's supported. --AD 9/96. +*/ + #ifndef HZ -#define HZ 60 +# ifdef CLK_TCK +# define HZ CLK_TCK +# else +# define HZ 60 +# endif #endif PP(pp_tms) { dSP; -#if defined(MSDOS) || !defined(HAS_TIMES) +#ifndef HAS_TIMES DIE("times not implemented"); #else EXTEND(SP, 4); @@ -3007,8 +3349,6 @@ PP(pp_tms) (void)times((tbuffer_t *)×buf); /* time.h uses different name for */ /* struct tms, though same data */ /* is returned. */ -#undef HZ -#define HZ CLK_TCK #endif PUSHs(sv_2mortal(newSVnv(((double)timesbuf.tms_utime)/HZ))); @@ -3018,7 +3358,7 @@ PP(pp_tms) PUSHs(sv_2mortal(newSVnv(((double)timesbuf.tms_cstime)/HZ))); } RETURN; -#endif /* MSDOS */ +#endif /* HAS_TIMES */ } PP(pp_localtime) @@ -3038,7 +3378,11 @@ PP(pp_gmtime) if (MAXARG < 1) (void)time(&when); else +#ifdef BIG_TIME + when = (Time_t)SvNVx(POPs); +#else when = (Time_t)SvIVx(POPs); +#endif if (op->op_type == OP_LOCALTIME) tmbuf = localtime(&when); @@ -3046,20 +3390,21 @@ PP(pp_gmtime) tmbuf = gmtime(&when); EXTEND(SP, 9); + EXTEND_MORTAL(9); if (GIMME != G_ARRAY) { dTARGET; - char mybuf[30]; + SV *tsv; if (!tmbuf) RETPUSHUNDEF; - sprintf(mybuf, "%s %s %2d %02d:%02d:%02d %d", - dayname[tmbuf->tm_wday], - monname[tmbuf->tm_mon], - tmbuf->tm_mday, - tmbuf->tm_hour, - tmbuf->tm_min, - tmbuf->tm_sec, - tmbuf->tm_year + 1900); - PUSHp(mybuf, strlen(mybuf)); + tsv = newSVpvf("%s %s %2d %02d:%02d:%02d %d", + dayname[tmbuf->tm_wday], + monname[tmbuf->tm_mon], + tmbuf->tm_mday, + tmbuf->tm_hour, + tmbuf->tm_min, + tmbuf->tm_sec, + tmbuf->tm_year + 1900); + PUSHs(sv_2mortal(tsv)); } else if (tmbuf) { PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_sec))); @@ -3101,7 +3446,7 @@ PP(pp_sleep) (void)time(&lasttime); if (MAXARG < 1) - pause(); + Pause(); else { duration = POPi; sleep((unsigned int)duration); @@ -3208,7 +3553,7 @@ PP(pp_semctl) PUSHi(anum); } else { - PUSHp("0 but true",10); + PUSHp(zero_but_true, ZBTLEN); } RETURN; #else @@ -3285,7 +3630,7 @@ PP(pp_ghostent) #ifdef HOST_NOT_FOUND if (!hent) - statusvalue = FIXSTATUS(h_errno); + STATUS_NATIVE_SET(h_errno); #endif if (GIMME != G_ARRAY) { @@ -3311,10 +3656,10 @@ PP(pp_ghostent) sv_catpvn(sv, " ", 1); } PUSHs(sv = sv_mortalcopy(&sv_no)); - sv_setiv(sv, (I32)hent->h_addrtype); + sv_setiv(sv, (IV)hent->h_addrtype); PUSHs(sv = sv_mortalcopy(&sv_no)); len = hent->h_length; - sv_setiv(sv, (I32)len); + sv_setiv(sv, (IV)len); #ifdef h_addr for (elem = hent->h_addr_list; elem && *elem; elem++) { XPUSHs(sv = sv_mortalcopy(&sv_no)); @@ -3377,7 +3722,7 @@ PP(pp_gnetent) PUSHs(sv = sv_newmortal()); if (nent) { if (which == OP_GNBYNAME) - sv_setiv(sv, (I32)nent->n_net); + sv_setiv(sv, (IV)nent->n_net); else sv_setpv(sv, nent->n_name); } @@ -3388,15 +3733,15 @@ PP(pp_gnetent) PUSHs(sv = sv_mortalcopy(&sv_no)); sv_setpv(sv, nent->n_name); PUSHs(sv = sv_mortalcopy(&sv_no)); - for (elem = nent->n_aliases; *elem; elem++) { + for (elem = nent->n_aliases; elem && *elem; elem++) { sv_catpv(sv, *elem); if (elem[1]) sv_catpvn(sv, " ", 1); } PUSHs(sv = sv_mortalcopy(&sv_no)); - sv_setiv(sv, (I32)nent->n_addrtype); + sv_setiv(sv, (IV)nent->n_addrtype); PUSHs(sv = sv_mortalcopy(&sv_no)); - sv_setiv(sv, (I32)nent->n_net); + sv_setiv(sv, (IV)nent->n_net); } RETURN; @@ -3447,7 +3792,7 @@ PP(pp_gprotoent) PUSHs(sv = sv_newmortal()); if (pent) { if (which == OP_GPBYNAME) - sv_setiv(sv, (I32)pent->p_proto); + sv_setiv(sv, (IV)pent->p_proto); else sv_setpv(sv, pent->p_name); } @@ -3458,13 +3803,13 @@ PP(pp_gprotoent) PUSHs(sv = sv_mortalcopy(&sv_no)); sv_setpv(sv, pent->p_name); PUSHs(sv = sv_mortalcopy(&sv_no)); - for (elem = pent->p_aliases; *elem; elem++) { + for (elem = pent->p_aliases; elem && *elem; elem++) { sv_catpv(sv, *elem); if (elem[1]) sv_catpvn(sv, " ", 1); } PUSHs(sv = sv_mortalcopy(&sv_no)); - sv_setiv(sv, (I32)pent->p_proto); + sv_setiv(sv, (IV)pent->p_proto); } RETURN; @@ -3514,8 +3859,11 @@ PP(pp_gservent) } else if (which == OP_GSBYPORT) { char *proto = POPp; - int port = POPi; + unsigned short port = POPu; +#ifdef HAS_HTONS + port = htons(port); +#endif sent = getservbyport(port, proto); } else @@ -3527,9 +3875,9 @@ PP(pp_gservent) if (sent) { if (which == OP_GSBYNAME) { #ifdef HAS_NTOHS - sv_setiv(sv, (I32)ntohs(sent->s_port)); + sv_setiv(sv, (IV)ntohs(sent->s_port)); #else - sv_setiv(sv, (I32)(sent->s_port)); + sv_setiv(sv, (IV)(sent->s_port)); #endif } else @@ -3542,16 +3890,16 @@ PP(pp_gservent) PUSHs(sv = sv_mortalcopy(&sv_no)); sv_setpv(sv, sent->s_name); PUSHs(sv = sv_mortalcopy(&sv_no)); - for (elem = sent->s_aliases; *elem; elem++) { + for (elem = sent->s_aliases; elem && *elem; elem++) { sv_catpv(sv, *elem); if (elem[1]) sv_catpvn(sv, " ", 1); } PUSHs(sv = sv_mortalcopy(&sv_no)); #ifdef HAS_NTOHS - sv_setiv(sv, (I32)ntohs(sent->s_port)); + sv_setiv(sv, (IV)ntohs(sent->s_port)); #else - sv_setiv(sv, (I32)(sent->s_port)); + sv_setiv(sv, (IV)(sent->s_port)); #endif PUSHs(sv = sv_mortalcopy(&sv_no)); sv_setpv(sv, sent->s_proto); @@ -3693,7 +4041,7 @@ PP(pp_gpwent) PUSHs(sv = sv_newmortal()); if (pwent) { if (which == OP_GPWNAM) - sv_setiv(sv, (I32)pwent->pw_uid); + sv_setiv(sv, (IV)pwent->pw_uid); else sv_setpv(sv, pwent->pw_name); } @@ -3706,15 +4054,15 @@ PP(pp_gpwent) PUSHs(sv = sv_mortalcopy(&sv_no)); sv_setpv(sv, pwent->pw_passwd); PUSHs(sv = sv_mortalcopy(&sv_no)); - sv_setiv(sv, (I32)pwent->pw_uid); + sv_setiv(sv, (IV)pwent->pw_uid); PUSHs(sv = sv_mortalcopy(&sv_no)); - sv_setiv(sv, (I32)pwent->pw_gid); + sv_setiv(sv, (IV)pwent->pw_gid); PUSHs(sv = sv_mortalcopy(&sv_no)); #ifdef PWCHANGE - sv_setiv(sv, (I32)pwent->pw_change); + sv_setiv(sv, (IV)pwent->pw_change); #else #ifdef PWQUOTA - sv_setiv(sv, (I32)pwent->pw_quota); + sv_setiv(sv, (IV)pwent->pw_quota); #else #ifdef PWAGE sv_setpv(sv, pwent->pw_age); @@ -3731,13 +4079,16 @@ PP(pp_gpwent) #endif PUSHs(sv = sv_mortalcopy(&sv_no)); sv_setpv(sv, pwent->pw_gecos); +#ifndef INCOMPLETE_TAINTS + SvTAINTED_on(sv); +#endif PUSHs(sv = sv_mortalcopy(&sv_no)); sv_setpv(sv, pwent->pw_dir); PUSHs(sv = sv_mortalcopy(&sv_no)); sv_setpv(sv, pwent->pw_shell); #ifdef PWEXPIRE PUSHs(sv = sv_mortalcopy(&sv_no)); - sv_setiv(sv, (I32)pwent->pw_expire); + sv_setiv(sv, (IV)pwent->pw_expire); #endif } RETURN; @@ -3749,7 +4100,7 @@ PP(pp_gpwent) PP(pp_spwent) { dSP; -#ifdef HAS_PASSWD +#if defined(HAS_PASSWD) && !defined(CYGWIN32) setpwent(); RETPUSHYES; #else @@ -3807,7 +4158,7 @@ PP(pp_ggrent) PUSHs(sv = sv_newmortal()); if (grent) { if (which == OP_GGRNAM) - sv_setiv(sv, (I32)grent->gr_gid); + sv_setiv(sv, (IV)grent->gr_gid); else sv_setpv(sv, grent->gr_name); } @@ -3820,9 +4171,9 @@ PP(pp_ggrent) PUSHs(sv = sv_mortalcopy(&sv_no)); sv_setpv(sv, grent->gr_passwd); PUSHs(sv = sv_mortalcopy(&sv_no)); - sv_setiv(sv, (I32)grent->gr_gid); + sv_setiv(sv, (IV)grent->gr_gid); PUSHs(sv = sv_mortalcopy(&sv_no)); - for (elem = grent->gr_mem; *elem; elem++) { + for (elem = grent->gr_mem; elem && *elem; elem++) { sv_catpv(sv, *elem); if (elem[1]) sv_catpvn(sv, " ", 1); @@ -3886,9 +4237,10 @@ PP(pp_syscall) if (tainting) { while (++MARK <= SP) { - if (SvGMAGICAL(*MARK) && SvSMAGICAL(*MARK) && - (mg = mg_find(*MARK, 't')) && mg->mg_len & 1) - tainted = TRUE; + if (SvTAINTED(*MARK)) { + TAINT; + break; + } } MARK = ORIGMARK; TAINT_PROPER("syscall"); @@ -3970,7 +4322,42 @@ PP(pp_syscall) #endif } -#if !defined(HAS_FLOCK) && defined(HAS_LOCKF) +#ifdef FCNTL_EMULATE_FLOCK + +/* XXX Emulate flock() with fcntl(). + What's really needed is a good file locking module. +*/ + +static int +fcntl_emulate_flock(fd, operation) +int fd; +int operation; +{ + struct flock flock; + + switch (operation & ~LOCK_NB) { + case LOCK_SH: + flock.l_type = F_RDLCK; + break; + case LOCK_EX: + flock.l_type = F_WRLCK; + break; + case LOCK_UN: + flock.l_type = F_UNLCK; + break; + default: + errno = EINVAL; + return -1; + } + flock.l_whence = SEEK_SET; + flock.l_start = flock.l_len = 0L; + + return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &flock); +} + +#endif /* FCNTL_EMULATE_FLOCK */ + +#ifdef LOCKF_EMULATE_FLOCK /* XXX Emulate flock() with lockf(). This is just to increase portability of scripts. The calls are not completely @@ -3978,12 +4365,9 @@ PP(pp_syscall) locking module. */ -/* We might need <unistd.h> because it sometimes defines the lockf() - constants. Unfortunately, <unistd.h> causes troubles on some mixed - (BSD/POSIX) systems, such as SunOS 4.1.3. We could just try including - <unistd.h> here in this part of the file, but that might - conflict with various other #defines and includes above, such as - #define vfork fork above. +/* The lockf() constants might have been defined in <unistd.h>. + Unfortunately, <unistd.h> causes troubles on some mixed + (BSD/POSIX) systems, such as SunOS 4.1.3. Further, the lockf() constants aren't POSIX, so they might not be visible if we're compiling with _POSIX_SOURCE defined. Thus, we'll @@ -4003,28 +4387,23 @@ PP(pp_syscall) # define F_TEST 3 /* Test a region for other processes locks */ # endif -/* These are the flock() constants. Since this sytems doesn't have - flock(), the values of the constants are probably not available. -*/ -# ifndef LOCK_SH -# define LOCK_SH 1 -# endif -# ifndef LOCK_EX -# define LOCK_EX 2 -# endif -# ifndef LOCK_NB -# define LOCK_NB 4 -# endif -# ifndef LOCK_UN -# define LOCK_UN 8 -# endif - -int +static int lockf_emulate_flock (fd, operation) int fd; int operation; { int i; + int save_errno; + Off_t pos; + + /* flock locks entire file so for lockf we need to do the same */ + save_errno = errno; + pos = lseek(fd, (Off_t)0, SEEK_CUR); /* get pos to restore later */ + if (pos > 0) /* is seekable and needs to be repositioned */ + if (lseek(fd, (Off_t)0, SEEK_SET) < 0) + pos = -1; /* seek failed, so don't seek back afterwards */ + errno = save_errno; + switch (operation) { /* LOCK_SH - get a shared lock */ @@ -4044,8 +4423,9 @@ int operation; errno = EWOULDBLOCK; break; - /* LOCK_UN - unlock */ + /* LOCK_UN - unlock (non-blocking is a no-op) */ case LOCK_UN: + case LOCK_UN|LOCK_NB: i = lockf (fd, F_ULOCK, 0); break; @@ -4055,6 +4435,11 @@ int operation; errno = EINVAL; break; } + + if (pos > 0) /* need to restore position of the handle */ + lseek(fd, pos, SEEK_SET); /* ignore error here */ + return (i); } -#endif + +#endif /* LOCKF_EMULATE_FLOCK */ diff --git a/gnu/usr.bin/perl/proto.h b/gnu/usr.bin/perl/proto.h index 542d5663fdc..463b4989227 100644 --- a/gnu/usr.bin/perl/proto.h +++ b/gnu/usr.bin/perl/proto.h @@ -8,7 +8,7 @@ #endif #ifdef OVERLOAD SV* amagic_call _((SV* left,SV* right,int method,int dir)); -bool Gv_AMupdate _((HV* stash)); +bool Gv_AMupdate _((HV* stash)); #endif /* OVERLOAD */ OP* append_elem _((I32 optype, OP* head, OP* tail)); OP* append_list _((I32 optype, LISTOP* first, LISTOP* last)); @@ -23,36 +23,40 @@ I32 av_len _((AV* ar)); AV* av_make _((I32 size, SV** svp)); SV* av_pop _((AV* ar)); void av_push _((AV* ar, SV* val)); +void av_reify _((AV* ar)); SV* av_shift _((AV* ar)); SV** av_store _((AV* ar, I32 key, SV* val)); void av_undef _((AV* ar)); void av_unshift _((AV* ar, I32 num)); OP* bind_match _((I32 type, OP* left, OP* pat)); -OP* block_end _((int line, int floor, OP* seq)); -int block_start _((void)); -void calllist _((AV* list)); +OP* block_end _((I32 floor, OP* seq)); +I32 block_gimme _((void)); +int block_start _((int full)); +void boot_core_UNIVERSAL _((void)); +void call_list _((I32 oldscope, AV* list)); I32 cando _((I32 bit, I32 effective, struct stat* statbufp)); #ifndef CASTNEGFLOAT U32 cast_ulong _((double f)); #endif #if !defined(HAS_TRUNCATE) && !defined(HAS_CHSIZE) && defined(F_FREESP) -I32 chsize _((int fd, Off_t length)); +I32 my_chsize _((int fd, Off_t length)); #endif -OP * ck_gvconst _((OP * o)); -OP * ck_retarget _((OP *op)); +OP* ck_gvconst _((OP* o)); +OP* ck_retarget _((OP* op)); OP* convert _((I32 optype, I32 flags, OP* op)); -char* cpytill _((char* to, char* from, char* fromend, int delim, I32* retlen)); -void croak _((char* pat,...)) __attribute__((format(printf,1,2),noreturn)); +void croak _((const char* pat,...)) __attribute__((noreturn)); +void cv_ckproto _((CV* cv, GV* gv, char* p)); CV* cv_clone _((CV* proto)); +SV* cv_const_sv _((CV* cv)); void cv_undef _((CV* cv)); #ifdef DEBUGGING void cx_dump _((CONTEXT* cs)); #endif -SV * filter_add _((filter_t funcp, SV *datasv)); +SV* filter_add _((filter_t funcp, SV* datasv)); void filter_del _((filter_t funcp)); -I32 filter_read _((int idx, SV *buffer, int maxlen)); +I32 filter_read _((int idx, SV* buffer, int maxlen)); I32 cxinc _((void)); -void deb _((char* pat,...)) __attribute__((format(printf,1,2))); +void deb _((const char* pat,...)) __attribute__((format(printf,1,2))); void deb_growlevel _((void)); I32 debop _((OP* op)); I32 debstackptrs _((void)); @@ -60,13 +64,15 @@ I32 debstackptrs _((void)); void debprofdump _((void)); #endif I32 debstack _((void)); +char* delimcpy _((char* to, char* toend, char* from, char* fromend, + int delim, I32* retlen)); void deprecate _((char* s)); -OP* die _((char* pat,...)) __attribute__((format(printf,1,2))); +OP* die _((const char* pat,...)); OP* die_where _((char* message)); void dounwind _((I32 cxix)); bool do_aexec _((SV* really, SV** mark, SV** sp)); void do_chop _((SV* asv, SV* sv)); -bool do_close _((GV* gv, bool explicit)); +bool do_close _((GV* gv, bool not_implicit)); bool do_eof _((GV* gv)); bool do_exec _((char* cmd)); void do_execfree _((void)); @@ -81,10 +87,10 @@ I32 do_msgrcv _((SV** mark, SV** sp)); I32 do_msgsnd _((SV** mark, SV** sp)); #endif bool do_open _((GV* gv, char* name, I32 len, - int as_raw, int rawmode, int rawperm, FILE* supplied_fp)); + int as_raw, int rawmode, int rawperm, PerlIO* supplied_fp)); void do_pipe _((SV* sv, GV* rgv, GV* wgv)); -bool do_print _((SV* sv, FILE* fp)); -OP * do_readline _((void)); +bool do_print _((SV* sv, PerlIO* fp)); +OP* do_readline _((void)); I32 do_chomp _((SV* sv)); bool do_seek _((GV* gv, long pos, int whence)); #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM) @@ -92,6 +98,7 @@ I32 do_semop _((SV** mark, SV** sp)); I32 do_shmio _((I32 optype, SV** mark, SV** sp)); #endif void do_sprintf _((SV* sv, I32 len, SV** sarg)); +long do_sysseek _((GV* gv, long pos, int whence)); long do_tell _((GV* gv)); I32 do_trans _((SV* sv, OP* arg)); void do_vecset _((SV* sv)); @@ -111,10 +118,11 @@ void dump_op _((OP* arg)); void dump_pm _((PMOP* pm)); void dump_packsubs _((HV* stash)); void dump_sub _((GV* gv)); -void fbm_compile _((SV* sv, I32 iflag)); +void fbm_compile _((SV* sv)); char* fbm_instr _((unsigned char* big, unsigned char* bigend, SV* littlesv)); OP* force_list _((OP* arg)); -OP* fold_constants _((OP * arg)); +OP* fold_constants _((OP* arg)); +char* form _((const char* pat, ...)); void free_tmps _((void)); OP* gen_constant_list _((OP* op)); void gp_free _((GV* gv)); @@ -122,33 +130,46 @@ GP* gp_ref _((GP* gp)); GV* gv_AVadd _((GV* gv)); GV* gv_HVadd _((GV* gv)); GV* gv_IOadd _((GV* gv)); +GV* gv_autoload4 _((HV* stash, char* name, STRLEN len, I32 method)); void gv_check _((HV* stash)); void gv_efullname _((SV* sv, GV* gv)); +void gv_efullname3 _((SV* sv, GV* gv, char* prefix)); GV* gv_fetchfile _((char* name)); GV* gv_fetchmeth _((HV* stash, char* name, STRLEN len, I32 level)); GV* gv_fetchmethod _((HV* stash, char* name)); +GV* gv_fetchmethod_autoload _((HV* stash, char* name, I32 autoload)); GV* gv_fetchpv _((char* name, I32 add, I32 sv_type)); void gv_fullname _((SV* sv, GV* gv)); -void gv_init _((GV *gv, HV *stash, char *name, STRLEN len, int multi)); +void gv_fullname3 _((SV* sv, GV* gv, char* prefix)); +void gv_init _((GV* gv, HV* stash, char* name, STRLEN len, int multi)); HV* gv_stashpv _((char* name, I32 create)); +HV* gv_stashpvn _((char* name, U32 namelen, I32 create)); HV* gv_stashsv _((SV* sv, I32 create)); -void he_delayfree _((HE* hent)); -void he_free _((HE* hent)); void hoistmust _((PMOP* pm)); void hv_clear _((HV* tb)); +void hv_delayfree_ent _((HV* hv, HE* entry)); SV* hv_delete _((HV* tb, char* key, U32 klen, I32 flags)); +SV* hv_delete_ent _((HV* tb, SV* key, I32 flags, U32 hash)); bool hv_exists _((HV* tb, char* key, U32 klen)); +bool hv_exists_ent _((HV* tb, SV* key, U32 hash)); SV** hv_fetch _((HV* tb, char* key, U32 klen, I32 lval)); +HE* hv_fetch_ent _((HV* tb, SV* key, I32 lval, U32 hash)); +void hv_free_ent _((HV* hv, HE* entry)); I32 hv_iterinit _((HV* tb)); char* hv_iterkey _((HE* entry, I32* retlen)); +SV* hv_iterkeysv _((HE* entry)); HE* hv_iternext _((HV* tb)); -SV * hv_iternextsv _((HV* hv, char** key, I32* retlen)); +SV* hv_iternextsv _((HV* hv, char** key, I32* retlen)); SV* hv_iterval _((HV* tb, HE* entry)); +void hv_ksplit _((HV* hv, IV newmax)); void hv_magic _((HV* hv, GV* gv, int how)); SV** hv_store _((HV* tb, char* key, U32 klen, SV* val, U32 hash)); +HE* hv_store_ent _((HV* tb, SV* key, SV* val, U32 hash)); void hv_undef _((HV* tb)); -I32 ibcmp _((U8* a, U8* b, I32 len)); +I32 ibcmp _((char* a, char* b, I32 len)); +I32 ibcmp_locale _((char* a, char* b, I32 len)); I32 ingroup _((I32 testgid, I32 effective)); +U32 intro_my _((void)); char* instr _((char* big, char* little)); bool io_close _((IO* io)); OP* invert _((OP* cmd)); @@ -156,20 +177,25 @@ OP* jmaybe _((OP* arg)); I32 keyword _((char* d, I32 len)); void leave_scope _((I32 base)); void lex_end _((void)); -void lex_start _((SV *line)); +void lex_start _((SV* line)); OP* linklist _((OP* op)); OP* list _((OP* o)); OP* listkids _((OP* o)); OP* localize _((OP* arg, I32 lexical)); I32 looks_like_number _((SV* sv)); int magic_clearenv _((SV* sv, MAGIC* mg)); +int magic_clear_all_env _((SV* sv, MAGIC* mg)); int magic_clearpack _((SV* sv, MAGIC* mg)); -int magic_existspack _((SV* sv, MAGIC* mg)); +int magic_clearsig _((SV* sv, MAGIC* mg)); +int magic_existspack _((SV* sv, MAGIC* mg)); +int magic_freedefelem _((SV* sv, MAGIC* mg)); int magic_get _((SV* sv, MAGIC* mg)); int magic_getarylen _((SV* sv, MAGIC* mg)); -int magic_getpack _((SV* sv, MAGIC* mg)); +int magic_getdefelem _((SV* sv, MAGIC* mg)); int magic_getglob _((SV* sv, MAGIC* mg)); +int magic_getpack _((SV* sv, MAGIC* mg)); int magic_getpos _((SV* sv, MAGIC* mg)); +int magic_getsig _((SV* sv, MAGIC* mg)); int magic_gettaint _((SV* sv, MAGIC* mg)); int magic_getuvar _((SV* sv, MAGIC* mg)); U32 magic_len _((SV* sv, MAGIC* mg)); @@ -181,10 +207,16 @@ int magic_setamagic _((SV* sv, MAGIC* mg)); int magic_setarylen _((SV* sv, MAGIC* mg)); int magic_setbm _((SV* sv, MAGIC* mg)); int magic_setdbline _((SV* sv, MAGIC* mg)); +#ifdef USE_LOCALE_COLLATE +int magic_setcollxfrm _((SV* sv, MAGIC* mg)); +#endif +int magic_setdefelem _((SV* sv, MAGIC* mg)); int magic_setenv _((SV* sv, MAGIC* mg)); +int magic_setfm _((SV* sv, MAGIC* mg)); int magic_setisa _((SV* sv, MAGIC* mg)); int magic_setglob _((SV* sv, MAGIC* mg)); int magic_setmglob _((SV* sv, MAGIC* mg)); +int magic_setnkeys _((SV* sv, MAGIC* mg)); int magic_setpack _((SV* sv, MAGIC* mg)); int magic_setpos _((SV* sv, MAGIC* mg)); int magic_setsig _((SV* sv, MAGIC* mg)); @@ -192,21 +224,17 @@ int magic_setsubstr _((SV* sv, MAGIC* mg)); int magic_settaint _((SV* sv, MAGIC* mg)); int magic_setuvar _((SV* sv, MAGIC* mg)); int magic_setvec _((SV* sv, MAGIC* mg)); +int magic_set_all_env _((SV* sv, MAGIC* mg)); int magic_wipepack _((SV* sv, MAGIC* mg)); void magicname _((char* sym, char* name, I32 namlen)); int main _((int argc, char** argv, char** env)); -#if !defined(STANDARD_C) -Malloc_t malloc _((MEM_SIZE nbytes)); -#endif -#if defined(MYMALLOC) && defined(HIDEMYMALLOC) -extern Malloc_t malloc _((MEM_SIZE nbytes)); -extern Malloc_t realloc _((Malloc_t, MEM_SIZE)); -extern Free_t free _((Malloc_t)); -#endif void markstack_grow _((void)); -char* mess _((char* pat, va_list* args)); +#ifdef USE_LOCALE_COLLATE +char* mem_collxfrm _((const char* s, STRLEN len, STRLEN* xlen)); +#endif +char* mess _((const char* pat, va_list* args)); int mg_clear _((SV* sv)); -int mg_copy _((SV *, SV *, char *, STRLEN)); +int mg_copy _((SV* , SV* , char* , I32)); MAGIC* mg_find _((SV* sv, int type)); int mg_free _((SV* sv)); int mg_get _((SV* sv)); @@ -215,18 +243,24 @@ void mg_magical _((SV* sv)); int mg_set _((SV* sv)); OP* mod _((OP* op, I32 type)); char* moreswitches _((char* s)); -OP * my _(( OP *)); +OP* my _((OP* op)); +#if !defined(HAS_BCOPY) || !defined(HAS_SAFE_BCOPY) char* my_bcopy _((char* from, char* to, I32 len)); +#endif #if !defined(HAS_BZERO) && !defined(HAS_MEMSET) char* my_bzero _((char* loc, I32 len)); #endif void my_exit _((U32 status)) __attribute__((noreturn)); +void my_failure_exit _((void)) __attribute__((noreturn)); I32 my_lstat _((void)); -#ifndef HAS_MEMCMP -I32 my_memcmp _((unsigned char* s1, unsigned char* s2, I32 len)); +#if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP) +I32 my_memcmp _((char* s1, char* s2, I32 len)); #endif -I32 my_pclose _((FILE* ptr)); -FILE* my_popen _((char* cmd, char* mode)); +#if !defined(HAS_MEMSET) +void* my_memset _((char* loc, I32 ch, I32 len)); +#endif +I32 my_pclose _((PerlIO* ptr)); +PerlIO* my_popen _((char* cmd, char* mode)); void my_setenv _((char* nam, char* val)); I32 my_stat _((void)); #ifdef MYSWAP @@ -252,16 +286,16 @@ OP* newRANGE _((I32 flags, OP* left, OP* right)); OP* newSLICEOP _((I32 flags, OP* subscript, OP* list)); OP* newSTATEOP _((I32 flags, char* label, OP* o)); CV* newSUB _((I32 floor, OP* op, OP* proto, OP* block)); -CV* newXS _((char *name, void (*subaddr)(CV* cv), char *filename)); +CV* newXS _((char* name, void (*subaddr)(CV* cv), char* filename)); #ifdef DEPRECATED -CV* newXSUB _((char *name, I32 ix, I32 (*subaddr)(int,int,int), char *filename)); +CV* newXSUB _((char* name, I32 ix, I32 (*subaddr)(int,int,int), char* filename)); #endif AV* newAV _((void)); OP* newAVREF _((OP* o)); OP* newBINOP _((I32 type, I32 flags, OP* first, OP* last)); OP* newCVREF _((I32 flags, OP* o)); OP* newGVOP _((I32 type, I32 flags, GV* gv)); -GV* newGVgen _((char *pack)); +GV* newGVgen _((char* pack)); OP* newGVREF _((I32 type, OP* o)); OP* newHVREF _((OP* o)); HV* newHV _((void)); @@ -280,13 +314,15 @@ OP* newSVOP _((I32 type, I32 flags, SV* sv)); SV* newSViv _((IV i)); SV* newSVnv _((double n)); SV* newSVpv _((char* s, STRLEN len)); +SV* newSVpvf _((const char* pat, ...)); SV* newSVrv _((SV* rv, char* classname)); SV* newSVsv _((SV* old)); OP* newUNOP _((I32 type, I32 flags, OP* first)); -OP * newWHILEOP _((I32 flags, I32 debuggable, LOOP* loop, OP* expr, OP* block, OP* cont)); -FILE* nextargv _((GV* gv)); +OP* newWHILEOP _((I32 flags, I32 debuggable, LOOP* loop, + I32 whileline, OP* expr, OP* block, OP* cont)); +PerlIO* nextargv _((GV* gv)); char* ninstr _((char* big, char* bigend, char* little, char* lend)); -OP * oopsCV _((OP* o)); +OP* oopsCV _((OP* o)); void op_free _((OP* arg)); void package _((OP* op)); PADOFFSET pad_alloc _((I32 optype, U32 tmptype)); @@ -307,13 +343,20 @@ I32 perl_call_pv _((char* subname, I32 flags)); I32 perl_call_sv _((SV* sv, I32 flags)); void perl_construct _((PerlInterpreter* sv_interp)); void perl_destruct _((PerlInterpreter* sv_interp)); +SV* perl_eval_pv _((char* p, I32 croak_on_error)); I32 perl_eval_sv _((SV* sv, I32 flags)); void perl_free _((PerlInterpreter* sv_interp)); SV* perl_get_sv _((char* name, I32 create)); AV* perl_get_av _((char* name, I32 create)); HV* perl_get_hv _((char* name, I32 create)); CV* perl_get_cv _((char* name, I32 create)); +int perl_init_i18nl10n _((int printwarn)); int perl_init_i18nl14n _((int printwarn)); +void perl_new_collate _((char* newcoll)); +void perl_new_ctype _((char* newctype)); +void perl_new_numeric _((char* newcoll)); +void perl_set_numeric_local _((void)); +void perl_set_numeric_standard _((void)); int perl_parse _((PerlInterpreter* sv_interp, void(*xsinit)(void), int argc, char** argv, char** env)); void perl_require_pv _((char* pv)); #define perl_requirepv perl_require_pv @@ -325,7 +368,6 @@ OP* pmtrans _((OP* op, OP* expr, OP* repl)); OP* pop_return _((void)); void pop_scope _((void)); OP* prepend_elem _((I32 optype, OP* head, OP* tail)); -void provide_ref _((OP* op, SV* sv)); void push_return _((OP* op)); void push_scope _((void)); regexp* pregcomp _((char* exp, char* xend, PMOP* pm)); @@ -335,24 +377,17 @@ void regdump _((regexp* r)); I32 pregexec _((regexp* prog, char* stringarg, char* strend, char* strbeg, I32 minend, SV* screamer, I32 safebase)); void pregfree _((struct regexp* r)); char* regnext _((char* p)); -char* regprop _((char* op)); +void regprop _((SV* sv, char* op)); void repeatcpy _((char* to, char* from, I32 len, I32 count)); char* rninstr _((char* big, char* bigend, char* little, char* lend)); +Sighandler_t rsignal _((int, Sighandler_t)); +int rsignal_restore _((int, Sigsave_t*)); +int rsignal_save _((int, Sighandler_t, Sigsave_t*)); +Sighandler_t rsignal_state _((int)); int runops _((void)); -#ifndef safemalloc -void safefree _((char* where)); -char* safemalloc _((MEM_SIZE size)); -#ifndef MSDOS -char* saferealloc _((char* where, MEM_SIZE size)); -#else -char* saferealloc _((char* where, unsigned long size)); -#endif -#endif -#ifdef LEAKTEST -void safexfree _((char* where)); -char* safexmalloc _((I32 x, MEM_SIZE size)); -char* safexrealloc _((char* where, MEM_SIZE size)); -#endif +void rxres_free _((void** rsp)); +void rxres_restore _((void** rsp, REGEXP* rx)); +void rxres_save _((void** rsp, REGEXP* rx)); #ifndef HAS_RENAME I32 same_dirent _((char* a, char* b)); #endif @@ -369,16 +404,19 @@ void save_destructor _((void (*f)(void*), void* p)); void save_freesv _((SV* sv)); void save_freeop _((OP* op)); void save_freepv _((char* pv)); +void save_gp _((GV* gv, I32 empty)); HV* save_hash _((GV* gv)); void save_hptr _((HV** hptr)); +void save_I16 _((I16* intp)); void save_I32 _((I32* intp)); void save_int _((int* intp)); void save_item _((SV* item)); +void save_iv _((IV* iv)); void save_list _((SV** sarg, I32 maxsarg)); -void save_long _((long *longp)); +void save_long _((long* longp)); void save_nogv _((GV* gv)); SV* save_scalar _((GV* gv)); -void save_pptr _((char **pptr)); +void save_pptr _((char** pptr)); void save_sptr _((SV** sptr)); SV* save_svref _((SV** sptr)); OP* sawparens _((OP* o)); @@ -386,18 +424,21 @@ OP* scalar _((OP* o)); OP* scalarkids _((OP* op)); OP* scalarseq _((OP* o)); OP* scalarvoid _((OP* op)); -unsigned long scan_hex _((char* start, I32 len, I32* retlen)); +UV scan_hex _((char* start, I32 len, I32* retlen)); char* scan_num _((char* s)); -unsigned long scan_oct _((char* start, I32 len, I32* retlen)); +UV scan_oct _((char* start, I32 len, I32* retlen)); OP* scope _((OP* o)); char* screaminstr _((SV* bigsv, SV* littlesv)); #ifndef VMS I32 setenv_getix _((char* nam)); #endif -void setdefout _((GV *gv)); +void setdefout _((GV* gv)); +char* sharepvn _((char* sv, I32 len, U32 hash)); +HEK* share_hek _((char* sv, I32 len, U32 hash)); Signal_t sighandler _((int sig)); SV** stack_grow _((SV** sp, SV**p, int n)); -int start_subparse _((void)); +I32 start_subparse _((I32 is_format, U32 flags)); +void sub_crush_depth _((CV* cv)); bool sv_2bool _((SV* sv)); CV* sv_2cv _((SV* sv, HV** st, GV** gvp, I32 lref)); IO* sv_2io _((SV* sv)); @@ -405,9 +446,11 @@ IV sv_2iv _((SV* sv)); SV* sv_2mortal _((SV* sv)); double sv_2nv _((SV* sv)); char* sv_2pv _((SV* sv, STRLEN* lp)); +UV sv_2uv _((SV* sv)); void sv_add_arena _((char* ptr, U32 size, U32 flags)); int sv_backoff _((SV* sv)); SV* sv_bless _((SV* sv, HV* stash)); +void sv_catpvf _((SV* sv, const char* pat, ...)); void sv_catpv _((SV* sv, char* ptr)); void sv_catpvn _((SV* sv, char* ptr, STRLEN len)); void sv_catsv _((SV* dsv, SV* ssv)); @@ -416,12 +459,17 @@ void sv_clean_all _((void)); void sv_clean_objs _((void)); void sv_clear _((SV* sv)); I32 sv_cmp _((SV* sv1, SV* sv2)); +I32 sv_cmp_locale _((SV* sv1, SV* sv2)); +#ifdef USE_LOCALE_COLLATE +char* sv_collxfrm _((SV* sv, STRLEN* nxp)); +#endif void sv_dec _((SV* sv)); void sv_dump _((SV* sv)); +bool sv_derived_from _((SV* sv, char* name)); I32 sv_eq _((SV* sv1, SV* sv2)); void sv_free _((SV* sv)); void sv_free_arenas _((void)); -char* sv_gets _((SV* sv, FILE* fp, I32 append)); +char* sv_gets _((SV* sv, PerlIO* fp, I32 append)); #ifndef DOSISH char* sv_grow _((SV* sv, I32 newlen)); #else @@ -436,37 +484,73 @@ void sv_magic _((SV* sv, SV* obj, int how, char* name, I32 namlen)); SV* sv_mortalcopy _((SV* oldsv)); SV* sv_newmortal _((void)); SV* sv_newref _((SV* sv)); -char * sv_peek _((SV* sv)); -char * sv_pvn_force _((SV* sv, STRLEN* lp)); +char* sv_peek _((SV* sv)); +char* sv_pvn_force _((SV* sv, STRLEN* lp)); char* sv_reftype _((SV* sv, int ob)); void sv_replace _((SV* sv, SV* nsv)); void sv_report_used _((void)); void sv_reset _((char* s, HV* stash)); +void sv_setpvf _((SV* sv, const char* pat, ...)); void sv_setiv _((SV* sv, IV num)); +void sv_setpviv _((SV* sv, IV num)); +void sv_setuv _((SV* sv, UV num)); void sv_setnv _((SV* sv, double num)); -SV* sv_setref_iv _((SV *rv, char *classname, IV iv)); -SV* sv_setref_nv _((SV *rv, char *classname, double nv)); -SV* sv_setref_pv _((SV *rv, char *classname, void* pv)); -SV* sv_setref_pvn _((SV *rv, char *classname, char* pv, I32 n)); -void sv_setpv _((SV* sv, char* ptr)); -void sv_setpvn _((SV* sv, char* ptr, STRLEN len)); +SV* sv_setref_iv _((SV* rv, char* classname, IV iv)); +SV* sv_setref_nv _((SV* rv, char* classname, double nv)); +SV* sv_setref_pv _((SV* rv, char* classname, void* pv)); +SV* sv_setref_pvn _((SV* rv, char* classname, char* pv, I32 n)); +void sv_setpv _((SV* sv, const char* ptr)); +void sv_setpvn _((SV* sv, const char* ptr, STRLEN len)); void sv_setsv _((SV* dsv, SV* ssv)); +void sv_taint _((SV* sv)); +bool sv_tainted _((SV* sv)); int sv_unmagic _((SV* sv, int type)); void sv_unref _((SV* sv)); +void sv_untaint _((SV* sv)); bool sv_upgrade _((SV* sv, U32 mt)); void sv_usepvn _((SV* sv, char* ptr, STRLEN len)); +void sv_vcatpvfn _((SV* sv, const char* pat, STRLEN patlen, + va_list* args, SV** svargs, I32 svmax, + bool *used_locale)); +void sv_vsetpvfn _((SV* sv, const char* pat, STRLEN patlen, + va_list* args, SV** svargs, I32 svmax, + bool *used_locale)); void taint_env _((void)); -void taint_not _((char *s)); -void taint_proper _((char* f, char* s)); +void taint_proper _((const char* f, char* s)); #ifdef UNLINK_ALL_VERSIONS I32 unlnk _((char* f)); #endif -void utilize _((int aver, I32 floor, OP* id, OP* arg)); +void unsharepvn _((char* sv, I32 len, U32 hash)); +void unshare_hek _((HEK* hek)); +void utilize _((int aver, I32 floor, OP* version, OP* id, OP* arg)); +void vivify_defelem _((SV* sv)); +void vivify_ref _((SV* sv, U32 to_what)); I32 wait4pid _((int pid, int* statusp, int flags)); -void warn _((char* pat,...)) __attribute__((format(printf,1,2))); -void watch _((char **addr)); +void warn _((const char* pat,...)); +void watch _((char** addr)); I32 whichsig _((char* sig)); int yyerror _((char* s)); int yylex _((void)); int yyparse _((void)); int yywarn _((char* s)); + +#if defined(MYMALLOC) || !defined(STANDARD_C) +Malloc_t malloc _((MEM_SIZE nbytes)); +Malloc_t calloc _((MEM_SIZE elements, MEM_SIZE size)); +Malloc_t realloc _((Malloc_t where, MEM_SIZE nbytes)); +Free_t free _((Malloc_t where)); +#endif + +#ifndef MYMALLOC +Malloc_t safemalloc _((MEM_SIZE nbytes)); +Malloc_t safecalloc _((MEM_SIZE elements, MEM_SIZE size)); +Malloc_t saferealloc _((Malloc_t where, MEM_SIZE nbytes)); +Free_t safefree _((Malloc_t where)); +#endif + +#ifdef LEAKTEST +Malloc_t safexmalloc _((I32 x, MEM_SIZE size)); +Malloc_t safexcalloc _((I32 x, MEM_SIZE elements, MEM_SIZE size)); +Malloc_t safexrealloc _((Malloc_t where, MEM_SIZE size)); +void safexfree _((Malloc_t where)); +#endif diff --git a/gnu/usr.bin/perl/regcomp.c b/gnu/usr.bin/perl/regcomp.c index d120eb7bdfc..d99d6c7d062 100644 --- a/gnu/usr.bin/perl/regcomp.c +++ b/gnu/usr.bin/perl/regcomp.c @@ -43,7 +43,7 @@ * **** Alterations to Henry's code are... **** - **** Copyright (c) 1991-1994, Larry Wall + **** Copyright (c) 1991-1997, Larry Wall **** **** You may distribute under the terms of either the GNU General Public **** License or the Artistic License, as specified in the README file. @@ -107,8 +107,9 @@ static char *regnode _((char)); static char *regpiece _((I32 *)); static void reginsert _((char, char *)); static void regoptail _((char *, char *)); -static void regset _((char *, I32, I32)); +static void regset _((char *, I32)); static void regtail _((char *, char *)); +static char* regwhite _((char *, char *)); static char* nextchar _((void)); /* @@ -132,7 +133,6 @@ char* exp; char* xend; PMOP* pm; { - I32 fold = pm->op_pmflags & PMf_FOLD; register regexp *r; register char *scan; register SV *longish; @@ -146,17 +146,25 @@ PMOP* pm; I32 minlen = 0; I32 sawplus = 0; I32 sawopen = 0; +#define MAX_REPEAT_DEPTH 12 + struct { + char *opcode; + I32 count; + } repeat_stack[MAX_REPEAT_DEPTH]; + I32 repeat_depth = 0; + I32 repeat_count = 1; /* We start unmultiplied. */ if (exp == NULL) croak("NULL regexp argument"); - /* First pass: determine size, legality. */ + regprecomp = savepvn(exp, xend - exp); regflags = pm->op_pmflags; + regsawback = 0; + + /* First pass: determine size, legality. */ regparse = exp; regxend = xend; - regprecomp = savepvn(exp,xend-exp); regnaughty = 0; - regsawback = 0; regnpar = 1; regsize = 0L; regcode = ®dummy; @@ -171,17 +179,18 @@ PMOP* pm; if (regsize >= 32767L) /* Probably could be 65535L. */ FAIL("regexp too big"); - /* Allocate space. */ + /* Allocate space and initialize. */ Newc(1001, r, sizeof(regexp) + (unsigned)regsize, char, regexp); if (r == NULL) FAIL("regexp out of space"); - - /* Second pass: emit code. */ - r->prelen = xend-exp; + r->prelen = xend - exp; r->precomp = regprecomp; r->subbeg = r->subbase = NULL; - regnaughty = 0; + + /* Second pass: emit code. */ regparse = exp; + regxend = xend; + regnaughty = 0; regnpar = 1; regcode = r->program; regc((char)MAGIC); @@ -190,7 +199,6 @@ PMOP* pm; /* Dig out information for optimizations. */ pm->op_pmflags = regflags; - fold = pm->op_pmflags & PMf_FOLD; r->regstart = Nullsv; /* Worst-case defaults. */ r->reganch = 0; r->regmust = Nullsv; @@ -216,36 +224,41 @@ PMOP* pm; /* Starting-point info. */ again: - if (OP(first) == EXACTLY) { + if (OP(first) == EXACT) { r->regstart = newSVpv(OPERAND(first)+1,*OPERAND(first)); - if (SvCUR(r->regstart) > !(sawstudy|fold)) - fbm_compile(r->regstart,fold); - else - sv_upgrade(r->regstart, SVt_PVBM); + if (SvCUR(r->regstart) > !sawstudy) + fbm_compile(r->regstart); + (void)SvUPGRADE(r->regstart, SVt_PVBM); } else if (strchr(simple+2,OP(first))) r->regstclass = first; - else if (OP(first) == BOUND || OP(first) == NBOUND) + else if (regkind[(U8)OP(first)] == BOUND || + regkind[(U8)OP(first)] == NBOUND) r->regstclass = first; else if (regkind[(U8)OP(first)] == BOL) { - r->reganch = ROPT_ANCH; + r->reganch |= ROPT_ANCH_BOL; + first = NEXTOPER(first); + goto again; + } + else if (OP(first) == GPOS) { + r->reganch |= ROPT_ANCH_GPOS; first = NEXTOPER(first); - goto again; + goto again; } else if ((OP(first) == STAR && regkind[(U8)OP(NEXTOPER(first))] == ANY) && !(r->reganch & ROPT_ANCH) ) { /* turn .* into ^.* with an implied $*=1 */ - r->reganch = ROPT_ANCH | ROPT_IMPLICIT; + r->reganch |= ROPT_ANCH_BOL | ROPT_IMPLICIT; first = NEXTOPER(first); - goto again; + goto again; } if (sawplus && (!sawopen || !regsawback)) r->reganch |= ROPT_SKIP; /* x+ must match 1st of run */ - DEBUG_r(fprintf(stderr,"first %d next %d offset %d\n", - OP(first), OP(NEXTOPER(first)), first - scan)); + DEBUG_r(PerlIO_printf(Perl_debug_log, "first %d next %d offset %ld\n", + OP(first), OP(NEXTOPER(first)), (long)(first - scan))); /* * If there's something expensive in the r.e., find the * longest literal string that must appear and make it the @@ -280,13 +293,13 @@ PMOP* pm; scan = regnext(scan); continue; } - if (OP(scan) == EXACTLY) { + if (OP(scan) == EXACT) { char *t; first = scan; - while (OP(t = regnext(scan)) == CLOSE) + while ((t = regnext(scan)) && OP(t) == CLOSE) scan = t; - minlen += *OPERAND(first); + minlen += *OPERAND(first) * repeat_count; if (curback - backish == len) { sv_catpvn(longish, OPERAND(first)+1, *OPERAND(first)); @@ -305,22 +318,57 @@ PMOP* pm; curback += *OPERAND(first); } else if (strchr(varies,OP(scan))) { - curback = -30000; + int tcount; + char *next; + + if (repeat_depth < MAX_REPEAT_DEPTH + && ((OP(scan) == PLUS + && (tcount = 1) + && (next = NEXTOPER(scan))) + || (regkind[(U8)OP(scan)] == CURLY + && (tcount = ARG1(scan)) + && (next = NEXTOPER(scan)+4)))) + { + /* We treat (abc)+ as (abc)(abc)*. */ + + /* Mark the place to return back. */ + repeat_stack[repeat_depth].opcode = regnext(scan); + repeat_stack[repeat_depth].count = repeat_count; + repeat_depth++; + repeat_count *= tcount; + + /* Go deeper: */ + scan = next; + continue; + } + else { + curback = -30000; + len = 0; + if (SvCUR(longish) > SvCUR(longest)) { + sv_setsv(longest,longish); + backest = backish; + } + sv_setpvn(longish,"",0); + } + } + else if (strchr(simple,OP(scan))) { + curback++; + minlen += repeat_count; len = 0; if (SvCUR(longish) > SvCUR(longest)) { sv_setsv(longest,longish); backest = backish; } sv_setpvn(longish,"",0); - if (OP(scan) == PLUS && strchr(simple,OP(NEXTOPER(scan)))) - minlen++; - else if (regkind[(U8)OP(scan)] == CURLY && - strchr(simple,OP(NEXTOPER(scan)+4))) - minlen += ARG1(scan); } - else if (strchr(simple,OP(scan))) { - curback++; - minlen++; + scan = regnext(scan); + if (!scan) { /* Go up PLUS or CURLY. */ + if (!repeat_depth--) + croak("panic: re scan"); + scan = repeat_stack[repeat_depth].opcode; + repeat_count = repeat_stack[repeat_depth].count; + /* Need to submit the longest string found: */ + curback = -30000; len = 0; if (SvCUR(longish) > SvCUR(longest)) { sv_setsv(longest,longish); @@ -328,13 +376,12 @@ PMOP* pm; } sv_setpvn(longish,"",0); } - scan = regnext(scan); } /* Prefer earlier on tie, unless we can tail match latter */ - if (SvCUR(longish) + (regkind[(U8)OP(first)] == EOL) > - SvCUR(longest)) + if (SvCUR(longish) + (first && regkind[(U8)OP(first)] == EOL) + > SvCUR(longest)) { sv_setsv(longest,longish); backest = backish; @@ -342,26 +389,22 @@ PMOP* pm; else sv_setpvn(longish,"",0); if (SvCUR(longest) - && - (!r->regstart - || - !fbm_instr((unsigned char*) SvPVX(r->regstart), - (unsigned char *) SvPVX(r->regstart) - + SvCUR(r->regstart), - longest) - ) - ) + && (!r->regstart + || !fbm_instr((unsigned char*) SvPVX(r->regstart), + (unsigned char *) (SvPVX(r->regstart) + + SvCUR(r->regstart)), + longest))) { r->regmust = longest; if (backest < 0) backest = -1; r->regback = backest; - if (SvCUR(longest) > !(sawstudy || fold || - regkind[(U8)OP(first)]==EOL)) - fbm_compile(r->regmust,fold); + if (SvCUR(longest) > !(sawstudy || + (first && regkind[(U8)OP(first)] == EOL))) + fbm_compile(r->regmust); (void)SvUPGRADE(r->regmust, SVt_PVBM); BmUSEFUL(r->regmust) = 100; - if (regkind[(U8)OP(first)] == EOL && SvCUR(longish)) + if (first && regkind[(U8)OP(first)] == EOL && SvCUR(longish)) SvTAIL_on(r->regmust); } else { @@ -371,7 +414,6 @@ PMOP* pm; SvREFCNT_dec(longish); } - r->do_folding = fold; r->nparens = regnpar - 1; r->minlen = minlen; Newz(1002, r->startp, regnpar, char*); @@ -415,7 +457,7 @@ I32 *flagp; break; case '$': case '@': - croak("Sequence (?%c...) not implemented", paren); + croak("Sequence (?%c...) not implemented", (int)paren); break; case '#': while (*regparse && *regparse != ')') @@ -425,9 +467,12 @@ I32 *flagp; nextchar(); *flagp = TRYAGAIN; return NULL; + case 0: + croak("Sequence (? incomplete"); + break; default: --regparse; - while (*regparse && strchr("iogmsx", *regparse)) + while (*regparse && strchr("iogcmsx", *regparse)) pmflag(®flags, *regparse++); if (*regparse != ')') croak("Sequence (?%c...) not recognized", *regparse); @@ -655,6 +700,10 @@ I32 *flagp; *flagp = flags; return(ret); } + + if (!(flags&HASWIDTH) && op != '?') + FAIL("regexp *+ operand could be empty"); /* else may core dump */ + nextchar(); *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH); @@ -770,10 +819,16 @@ tryagain: croak("internal urp in regexp at /%s/", regparse); /* Supposed to be caught earlier. */ break; + case '{': + if (!regcurly(regparse)) { + regparse++; + goto defchar; + } + /* FALL THROUGH */ case '?': case '+': case '*': - FAIL("?+* follows nothing in regexp"); + FAIL("?+*{} follows nothing in regexp"); break; case '\\': switch (*++regparse) { @@ -783,7 +838,7 @@ tryagain: nextchar(); break; case 'G': - ret = regnode(GBOL); + ret = regnode(GPOS); *flagp |= SIMPLE; nextchar(); break; @@ -793,32 +848,32 @@ tryagain: nextchar(); break; case 'w': - ret = regnode(ALNUM); + ret = regnode((regflags & PMf_LOCALE) ? ALNUML : ALNUM); *flagp |= HASWIDTH|SIMPLE; nextchar(); break; case 'W': - ret = regnode(NALNUM); + ret = regnode((regflags & PMf_LOCALE) ? NALNUML : NALNUM); *flagp |= HASWIDTH|SIMPLE; nextchar(); break; case 'b': - ret = regnode(BOUND); + ret = regnode((regflags & PMf_LOCALE) ? BOUNDL : BOUND); *flagp |= SIMPLE; nextchar(); break; case 'B': - ret = regnode(NBOUND); + ret = regnode((regflags & PMf_LOCALE) ? NBOUNDL : NBOUND); *flagp |= SIMPLE; nextchar(); break; case 's': - ret = regnode(SPACE); + ret = regnode((regflags & PMf_LOCALE) ? SPACEL : SPACE); *flagp |= HASWIDTH|SIMPLE; nextchar(); break; case 'S': - ret = regnode(NSPACE); + ret = regnode((regflags & PMf_LOCALE) ? NSPACEL : NSPACE); *flagp |= HASWIDTH|SIMPLE; nextchar(); break; @@ -851,7 +906,9 @@ tryagain: goto defchar; else { regsawback = 1; - ret = reganode(REF, num); + ret = reganode((regflags & PMf_FOLD) + ? ((regflags & PMf_LOCALE) ? REFFL : REFF) + : REF, num); *flagp |= HASWIDTH; while (isDIGIT(*regparse)) regparse++; @@ -887,13 +944,18 @@ tryagain: regparse++; defchar: - ret = regnode(EXACTLY); + ret = regnode((regflags & PMf_FOLD) + ? ((regflags & PMf_LOCALE) ? EXACTFL : EXACTF) + : EXACT); regc(0); /* save spot for len */ for (len = 0, p = regparse - 1; len < 127 && p < regxend; len++) { oldp = p; + + if (regflags & PMf_EXTENDED) + p = regwhite(p, regxend); switch (*p) { case '^': case '$': @@ -948,10 +1010,8 @@ tryagain: break; case 'c': p++; - ender = *p++; - if (isLOWER(ender)) - ender = toUPPER(ender); - ender ^= 64; + ender = UCHARAT(p++); + ender = toCTRL(ender); break; case '0': case '1': case '2': case '3':case '4': case '5': case '6': case '7': case '8':case '9': @@ -974,24 +1034,12 @@ tryagain: break; } break; - case '#': - if (regflags & PMf_EXTENDED) { - while (p < regxend && *p != '\n') p++; - } - /* FALL THROUGH */ - case ' ': case '\t': case '\n': case '\r': case '\f': case '\v': - if (regflags & PMf_EXTENDED) { - p++; - len--; - continue; - } - /* FALL THROUGH */ default: ender = *p++; break; } - if (regflags & PMf_FOLD && isUPPER(ender)) - ender = toLOWER(ender); + if (regflags & PMf_EXTENDED) + p = regwhite(p, regxend); if (ISMULT2(p)) { /* Back off on ?+*. */ if (len) p = oldp; @@ -1022,25 +1070,40 @@ tryagain: return(ret); } +static char * +regwhite(p, e) +char *p; +char *e; +{ + while (p < e) { + if (isSPACE(*p)) + ++p; + else if (*p == '#') { + do { + p++; + } while (p < e && *p != '\n'); + } + else + break; + } + return p; +} + static void -regset(bits,def,c) -char *bits; -I32 def; +regset(opnd, c) +char *opnd; register I32 c; { - if (regcode == ®dummy) - return; - c &= 255; - if (def) - bits[c >> 3] &= ~(1 << (c & 7)); - else - bits[c >> 3] |= (1 << (c & 7)); + if (opnd == ®dummy) + return; + c &= 0xFF; + opnd[1 + (c >> 3)] |= (1 << (c & 7)); } static char * regclass() { - register char *bits; + register char *opnd; register I32 class; register I32 lastclass = 1234; register I32 range = 0; @@ -1049,16 +1112,21 @@ regclass() I32 numlen; ret = regnode(ANYOF); + opnd = regcode; + for (class = 0; class < 33; class++) + regc(0); if (*regparse == '^') { /* Complement of range. */ regnaughty++; regparse++; - def = 0; - } else { - def = 255; + if (opnd != ®dummy) + *opnd |= ANYOF_INVERT; + } + if (opnd != ®dummy) { + if (regflags & PMf_FOLD) + *opnd |= ANYOF_FOLD; + if (regflags & PMf_LOCALE) + *opnd |= ANYOF_LOCALE; } - bits = regcode; - for (class = 0; class < 32; class++) - regc(def); if (*regparse == ']' || *regparse == '-') goto skipcond; /* allow 1st char to be ] or - */ while (regparse < regxend && *regparse != ']') { @@ -1068,39 +1136,63 @@ regclass() class = UCHARAT(regparse++); switch (class) { case 'w': - for (class = 0; class < 256; class++) - if (isALNUM(class)) - regset(bits,def,class); + if (regflags & PMf_LOCALE) { + if (opnd != ®dummy) + *opnd |= ANYOF_ALNUML; + } + else { + for (class = 0; class < 256; class++) + if (isALNUM(class)) + regset(opnd, class); + } lastclass = 1234; continue; case 'W': - for (class = 0; class < 256; class++) - if (!isALNUM(class)) - regset(bits,def,class); + if (regflags & PMf_LOCALE) { + if (opnd != ®dummy) + *opnd |= ANYOF_NALNUML; + } + else { + for (class = 0; class < 256; class++) + if (!isALNUM(class)) + regset(opnd, class); + } lastclass = 1234; continue; case 's': - for (class = 0; class < 256; class++) - if (isSPACE(class)) - regset(bits,def,class); + if (regflags & PMf_LOCALE) { + if (opnd != ®dummy) + *opnd |= ANYOF_SPACEL; + } + else { + for (class = 0; class < 256; class++) + if (isSPACE(class)) + regset(opnd, class); + } lastclass = 1234; continue; case 'S': - for (class = 0; class < 256; class++) - if (!isSPACE(class)) - regset(bits,def,class); + if (regflags & PMf_LOCALE) { + if (opnd != ®dummy) + *opnd |= ANYOF_NSPACEL; + } + else { + for (class = 0; class < 256; class++) + if (!isSPACE(class)) + regset(opnd, class); + } lastclass = 1234; continue; case 'd': for (class = '0'; class <= '9'; class++) - regset(bits,def,class); + regset(opnd, class); lastclass = 1234; continue; case 'D': for (class = 0; class < '0'; class++) - regset(bits,def,class); + regset(opnd, class); for (class = '9' + 1; class < 256; class++) - regset(bits,def,class); + regset(opnd, class); lastclass = 1234; continue; case 'n': @@ -1129,10 +1221,8 @@ regclass() regparse += numlen; break; case 'c': - class = *regparse++; - if (isLOWER(class)) - class = toUPPER(class); - class ^= 64; + class = UCHARAT(regparse++); + class = toCTRL(class); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': @@ -1155,11 +1245,8 @@ regclass() continue; /* do it next time */ } } - for ( ; lastclass <= class; lastclass++) { - regset(bits,def,lastclass); - if (regflags & PMf_FOLD && isUPPER(lastclass)) - regset(bits,def,toLOWER(lastclass)); - } + for ( ; lastclass <= class; lastclass++) + regset(opnd, lastclass); lastclass = class; } if (*regparse != ']') @@ -1432,16 +1519,16 @@ register char *s; #ifdef DEBUGGING /* - - regdump - dump a regexp onto stderr in vaguely comprehensible form + - regdump - dump a regexp onto Perl_debug_log in vaguely comprehensible form */ void regdump(r) regexp *r; { register char *s; - register char op = EXACTLY; /* Arbitrary non-END op. */ + register char op = EXACT; /* Arbitrary non-END op. */ register char *next; - + SV *sv = sv_newmortal(); s = r->program + 1; while (op != END) { /* While that wasn't END last time... */ @@ -1450,61 +1537,71 @@ regexp *r; s++; #endif op = OP(s); - fprintf(stderr,"%2d%s", s-r->program, regprop(s)); /* Where, what. */ + /* where, what */ + regprop(sv, s); + PerlIO_printf(Perl_debug_log, "%2ld%s", (long)(s - r->program), SvPVX(sv)); next = regnext(s); s += regarglen[(U8)op]; if (next == NULL) /* Next ptr. */ - fprintf(stderr,"(0)"); + PerlIO_printf(Perl_debug_log, "(0)"); else - fprintf(stderr,"(%d)", (s-r->program)+(next-s)); + PerlIO_printf(Perl_debug_log, "(%ld)", (long)(s-r->program)+(next-s)); s += 3; if (op == ANYOF) { - s += 32; + s += 33; } - if (op == EXACTLY) { + if (regkind[(U8)op] == EXACT) { /* Literal string, where present. */ s++; - (void)putc(' ', stderr); - (void)putc('<', stderr); + (void)PerlIO_putc(Perl_debug_log, ' '); + (void)PerlIO_putc(Perl_debug_log, '<'); while (*s != '\0') { - (void)putc(*s, stderr); + (void)PerlIO_putc(Perl_debug_log,*s); s++; } - (void)putc('>', stderr); + (void)PerlIO_putc(Perl_debug_log, '>'); s++; } - (void)putc('\n', stderr); + (void)PerlIO_putc(Perl_debug_log, '\n'); } /* Header fields of interest. */ if (r->regstart) - fprintf(stderr,"start `%s' ", SvPVX(r->regstart)); - if (r->regstclass) - fprintf(stderr,"stclass `%s' ", regprop(r->regstclass)); - if (r->reganch & ROPT_ANCH) - fprintf(stderr,"anchored "); + PerlIO_printf(Perl_debug_log, "start `%s' ", SvPVX(r->regstart)); + if (r->regstclass) { + regprop(sv, r->regstclass); + PerlIO_printf(Perl_debug_log, "stclass `%s' ", SvPVX(sv)); + } + if (r->reganch & ROPT_ANCH) { + PerlIO_printf(Perl_debug_log, "anchored"); + if (r->reganch & ROPT_ANCH_BOL) + PerlIO_printf(Perl_debug_log, "(BOL)"); + if (r->reganch & ROPT_ANCH_GPOS) + PerlIO_printf(Perl_debug_log, "(GPOS)"); + PerlIO_putc(Perl_debug_log, ' '); + } if (r->reganch & ROPT_SKIP) - fprintf(stderr,"plus "); + PerlIO_printf(Perl_debug_log, "plus "); if (r->reganch & ROPT_IMPLICIT) - fprintf(stderr,"implicit "); + PerlIO_printf(Perl_debug_log, "implicit "); if (r->regmust != NULL) - fprintf(stderr,"must have \"%s\" back %ld ", SvPVX(r->regmust), + PerlIO_printf(Perl_debug_log, "must have \"%s\" back %ld ", SvPVX(r->regmust), (long) r->regback); - fprintf(stderr, "minlen %ld ", (long) r->minlen); - fprintf(stderr,"\n"); + PerlIO_printf(Perl_debug_log, "minlen %ld ", (long) r->minlen); + PerlIO_printf(Perl_debug_log, "\n"); } /* - regprop - printable representation of opcode */ -char * -regprop(op) +void +regprop(sv, op) +SV *sv; char *op; { register char *p = 0; - (void) strcpy(buf, ":"); - + sv_setpv(sv, ":"); switch (OP(op)) { case BOL: p = "BOL"; @@ -1536,8 +1633,14 @@ char *op; case BRANCH: p = "BRANCH"; break; - case EXACTLY: - p = "EXACTLY"; + case EXACT: + p = "EXACT"; + break; + case EXACTF: + p = "EXACTF"; + break; + case EXACTFL: + p = "EXACTFL"; break; case NOTHING: p = "NOTHING"; @@ -1548,48 +1651,38 @@ char *op; case END: p = "END"; break; - case ALNUM: - p = "ALNUM"; - break; - case NALNUM: - p = "NALNUM"; - break; case BOUND: p = "BOUND"; break; + case BOUNDL: + p = "BOUNDL"; + break; case NBOUND: p = "NBOUND"; break; - case SPACE: - p = "SPACE"; - break; - case NSPACE: - p = "NSPACE"; - break; - case DIGIT: - p = "DIGIT"; - break; - case NDIGIT: - p = "NDIGIT"; + case NBOUNDL: + p = "NBOUNDL"; break; case CURLY: - (void)sprintf(buf+strlen(buf), "CURLY {%d,%d}", ARG1(op),ARG2(op)); - p = NULL; + sv_catpvf(sv, "CURLY {%d,%d}", ARG1(op), ARG2(op)); break; case CURLYX: - (void)sprintf(buf+strlen(buf), "CURLYX {%d,%d}", ARG1(op),ARG2(op)); - p = NULL; + sv_catpvf(sv, "CURLYX {%d,%d}", ARG1(op), ARG2(op)); break; case REF: - (void)sprintf(buf+strlen(buf), "REF%d", ARG1(op)); - p = NULL; + sv_catpvf(sv, "REF%d", ARG1(op)); + break; + case REFF: + sv_catpvf(sv, "REFF%d", ARG1(op)); + break; + case REFFL: + sv_catpvf(sv, "REFFL%d", ARG1(op)); break; case OPEN: - (void)sprintf(buf+strlen(buf), "OPEN%d", ARG1(op)); - p = NULL; + sv_catpvf(sv, "OPEN%d", ARG1(op)); break; case CLOSE: - (void)sprintf(buf+strlen(buf), "CLOSE%d", ARG1(op)); + sv_catpvf(sv, "CLOSE%d", ARG1(op)); p = NULL; break; case STAR: @@ -1601,8 +1694,8 @@ char *op; case MINMOD: p = "MINMOD"; break; - case GBOL: - p = "GBOL"; + case GPOS: + p = "GPOS"; break; case UNLESSM: p = "UNLESSM"; @@ -1616,12 +1709,41 @@ char *op; case WHILEM: p = "WHILEM"; break; + case DIGIT: + p = "DIGIT"; + break; + case NDIGIT: + p = "NDIGIT"; + break; + case ALNUM: + p = "ALNUM"; + break; + case NALNUM: + p = "NALNUM"; + break; + case SPACE: + p = "SPACE"; + break; + case NSPACE: + p = "NSPACE"; + break; + case ALNUML: + p = "ALNUML"; + break; + case NALNUML: + p = "NALNUML"; + break; + case SPACEL: + p = "SPACEL"; + break; + case NSPACEL: + p = "NSPACEL"; + break; default: FAIL("corrupted regexp opcode"); } - if (p != NULL) - (void) strcat(buf, p); - return(buf); + if (p) + sv_catpv(sv, p); } #endif /* DEBUGGING */ diff --git a/gnu/usr.bin/perl/regcomp.h b/gnu/usr.bin/perl/regcomp.h index b2d9b846f7b..5915086390d 100644 --- a/gnu/usr.bin/perl/regcomp.h +++ b/gnu/usr.bin/perl/regcomp.h @@ -48,41 +48,51 @@ */ /* definition number opnd? meaning */ -#define END 0 /* no End of program. */ -#define BOL 1 /* no Match "" at beginning of line. */ -#define MBOL 2 /* no Same, assuming multiline. */ -#define SBOL 3 /* no Same, assuming singleline. */ -#define EOL 4 /* no Match "" at end of line. */ -#define MEOL 5 /* no Same, assuming multiline. */ -#define SEOL 6 /* no Same, assuming singleline. */ -#define ANY 7 /* no Match any one character (except newline). */ -#define SANY 8 /* no Match any one character. */ -#define ANYOF 9 /* sv Match character in (or not in) this class. */ +#define END 0 /* no End of program. */ +#define BOL 1 /* no Match "" at beginning of line. */ +#define MBOL 2 /* no Same, assuming multiline. */ +#define SBOL 3 /* no Same, assuming singleline. */ +#define EOL 4 /* no Match "" at end of line. */ +#define MEOL 5 /* no Same, assuming multiline. */ +#define SEOL 6 /* no Same, assuming singleline. */ +#define ANY 7 /* no Match any one character (except newline). */ +#define SANY 8 /* no Match any one character. */ +#define ANYOF 9 /* sv Match character in (or not in) this class. */ #define CURLY 10 /* sv Match this simple thing {n,m} times. */ #define CURLYX 11 /* sv Match this complex thing {n,m} times. */ #define BRANCH 12 /* node Match this alternative, or the next... */ #define BACK 13 /* no Match "", "next" ptr points backward. */ -#define EXACTLY 14 /* sv Match this string (preceded by length). */ -#define NOTHING 15 /* no Match empty string. */ -#define STAR 16 /* node Match this (simple) thing 0 or more times. */ -#define PLUS 17 /* node Match this (simple) thing 1 or more times. */ -#define ALNUM 18 /* no Match any alphanumeric character */ -#define NALNUM 19 /* no Match any non-alphanumeric character */ +#define EXACT 14 /* sv Match this string (preceded by length). */ +#define EXACTF 15 /* sv Match this string, folded (prec. by length). */ +#define EXACTFL 16 /* sv Match this string, folded in locale (w/len). */ +#define NOTHING 17 /* no Match empty string. */ +#define STAR 18 /* node Match this (simple) thing 0 or more times. */ +#define PLUS 19 /* node Match this (simple) thing 1 or more times. */ #define BOUND 20 /* no Match "" at any word boundary */ -#define NBOUND 21 /* no Match "" at any word non-boundary */ -#define SPACE 22 /* no Match any whitespace character */ -#define NSPACE 23 /* no Match any non-whitespace character */ -#define DIGIT 24 /* no Match any numeric character */ -#define NDIGIT 25 /* no Match any non-numeric character */ -#define REF 26 /* num Match some already matched string */ +#define BOUNDL 21 /* no Match "" at any word boundary */ +#define NBOUND 22 /* no Match "" at any word non-boundary */ +#define NBOUNDL 23 /* no Match "" at any word non-boundary */ +#define REF 24 /* num Match already matched string */ +#define REFF 25 /* num Match already matched string, folded */ +#define REFFL 26 /* num Match already matched string, folded in loc. */ #define OPEN 27 /* num Mark this point in input as start of #n. */ #define CLOSE 28 /* num Analogous to OPEN. */ #define MINMOD 29 /* no Next operator is not greedy. */ -#define GBOL 30 /* no Matches where last m//g left off. */ +#define GPOS 30 /* no Matches where last m//g left off. */ #define IFMATCH 31 /* no Succeeds if the following matches. */ #define UNLESSM 32 /* no Fails if the following matches. */ #define SUCCEED 33 /* no Return from a subroutine, basically. */ #define WHILEM 34 /* no Do curly processing and see if rest matches. */ +#define ALNUM 35 /* no Match any alphanumeric character */ +#define ALNUML 36 /* no Match any alphanumeric char in locale */ +#define NALNUM 37 /* no Match any non-alphanumeric character */ +#define NALNUML 38 /* no Match any non-alphanumeric char in locale */ +#define SPACE 39 /* no Match any whitespace character */ +#define SPACEL 40 /* no Match any whitespace char in locale */ +#define NSPACE 41 /* no Match any non-whitespace character */ +#define NSPACEL 42 /* no Match any non-whitespace char in locale */ +#define DIGIT 43 /* no Match any numeric character */ +#define NDIGIT 44 /* no Match any non-numeric character */ /* * Opcode notes: @@ -109,7 +119,13 @@ #ifndef DOINIT EXT char regarglen[]; #else -EXT char regarglen[] = {0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0}; +EXT char regarglen[] = { + 0,0,0,0,0,0,0,0,0,0, + /*CURLY*/ 4, /*CURLYX*/ 4, + 0,0,0,0,0,0,0,0,0,0,0,0, + /*REF*/ 2, 2, 2, /*OPEN*/ 2, /*CLOSE*/ 2, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +}; #endif #ifndef DOINIT @@ -130,27 +146,37 @@ EXT char regkind[] = { CURLY, BRANCH, BACK, - EXACTLY, + EXACT, + EXACT, + EXACT, NOTHING, STAR, PLUS, - ALNUM, - NALNUM, + BOUND, BOUND, NBOUND, - SPACE, - NSPACE, - DIGIT, - NDIGIT, + NBOUND, + REF, + REF, REF, OPEN, CLOSE, MINMOD, - BOL, + GPOS, BRANCH, BRANCH, END, - WHILEM + WHILEM, + ALNUM, + ALNUM, + NALNUM, + NALNUM, + SPACE, + SPACE, + NSPACE, + NSPACE, + DIGIT, + NDIGIT, }; #endif @@ -158,14 +184,21 @@ EXT char regkind[] = { #ifndef DOINIT EXT char varies[]; #else -EXT char varies[] = {BRANCH,BACK,STAR,PLUS,CURLY,CURLYX,REF,WHILEM,0}; +EXT char varies[] = { + BRANCH, BACK, STAR, PLUS, CURLY, CURLYX, REF, REFF, REFFL, WHILEM, 0 +}; #endif /* The following always have a length of 1. */ #ifndef DOINIT EXT char simple[]; #else -EXT char simple[] = {ANY,SANY,ANYOF,ALNUM,NALNUM,SPACE,NSPACE,DIGIT,NDIGIT,0}; +EXT char simple[] = { + ANY, SANY, ANYOF, + ALNUM, ALNUML, NALNUM, NALNUML, + SPACE, SPACEL, NSPACE, NSPACEL, + DIGIT, NDIGIT, 0 +}; #endif EXT char regdummy; @@ -222,6 +255,16 @@ EXT char regdummy; #define MAGIC 0234 +/* Flags for first parameter byte of ANYOF */ +#define ANYOF_INVERT 0x40 +#define ANYOF_FOLD 0x20 +#define ANYOF_LOCALE 0x10 +#define ANYOF_ISA 0x0F +#define ANYOF_ALNUML 0x08 +#define ANYOF_NALNUML 0x04 +#define ANYOF_SPACEL 0x02 +#define ANYOF_NSPACEL 0x01 + /* * Utility definitions. */ diff --git a/gnu/usr.bin/perl/regexec.c b/gnu/usr.bin/perl/regexec.c index 6a29d7f0320..c640d6758d5 100644 --- a/gnu/usr.bin/perl/regexec.c +++ b/gnu/usr.bin/perl/regexec.c @@ -42,7 +42,7 @@ * **** Alterations to Henry's code are... **** - **** Copyright (c) 1991-1994, Larry Wall + **** Copyright (c) 1991-1997, Larry Wall **** **** You may distribute under the terms of either the GNU General Public **** License or the Artistic License, as specified in the README file. @@ -82,10 +82,10 @@ static CURCUR* regcc; typedef I32 CHECKPOINT; -CHECKPOINT regcppush _((I32 parenfloor)); -char * regcppop _((void)); +static CHECKPOINT regcppush _((I32 parenfloor)); +static char * regcppop _((void)); -CHECKPOINT +static CHECKPOINT regcppush(parenfloor) I32 parenfloor; { @@ -107,7 +107,7 @@ I32 parenfloor; return retval; } -char* +static char * regcppop() { I32 i = SSPOPINT; @@ -134,6 +134,36 @@ regcppop() return input; } +/* After a successful match in WHILEM, we want to restore paren matches + * that have been overwritten by a failed match attempt in the process + * of reaching this success. We do this by restoring regstartp[i] + * wherever regendp[i] has not changed; if OPEN is changed to modify + * regendp[], the '== endp' test below should be changed to match. + * This corrects the error of: + * 0 > length [ "foobar" =~ / ( (foo) | (bar) )* /x ]->[1] + */ +static void +regcppartblow(base) +I32 base; +{ + I32 i = SSPOPINT; + U32 paren; + char *startp; + char *endp; + assert(i == SAVEt_REGCONTEXT); + i = SSPOPINT; + /* input, lastparen, size */ + SSPOPPTR; SSPOPINT; SSPOPINT; + for (i -= 3; i > 0; i -= 3) { + paren = (U32)SSPOPINT; + startp = (char *) SSPOPPTR; + endp = (char *) SSPOPPTR; + if (paren <= *reglastparen && regendp[paren] == endp) + regstartp[paren] = startp; + } + assert(savestack_ix == base); +} + #define regcpblow(cp) leave_scope(cp) /* @@ -147,6 +177,9 @@ regcppop() static I32 regmatch _((char *prog)); static I32 regrepeat _((char *p, I32 max)); static I32 regtry _((regexp *prog, char *startpos)); +static bool reginclass _((char *p, I32 c)); + +static bool regtainted; /* tainted information used? */ /* - pregexec - match a regexp against a string @@ -162,7 +195,6 @@ SV *screamer; I32 safebase; /* no need to remember string in subbase */ { register char *s; - register I32 i; register char *c; register char *startpos = stringarg; register I32 tmp; @@ -192,28 +224,21 @@ I32 safebase; /* no need to remember string in subbase */ if (!multiline && regprev == '\n') regprev = '\0'; /* force ^ to NOT match */ } + regprecomp = prog->precomp; - regnpar = prog->nparens; /* Check validity of program. */ if (UCHARAT(prog->program) != MAGIC) { FAIL("corrupted regexp program"); } - if (prog->do_folding) { - i = strend - startpos; - New(1101,c,i+1,char); - Copy(startpos, c, i+1, char); - startpos = c; - strend = startpos + i; - for (s = startpos; s < strend; s++) - if (isUPPER(*s)) - *s = toLOWER(*s); - } + regnpar = prog->nparens; + regtainted = FALSE; /* If there is a "must appear" string, look for it. */ s = startpos; if (prog->regmust != Nullsv && - (!(prog->reganch & ROPT_ANCH) + !(prog->reganch & ROPT_ANCH_GPOS) && + (!(prog->reganch & ROPT_ANCH_BOL) || (multiline && prog->regback >= 0)) ) { if (stringarg == strbeg && screamer) { @@ -256,11 +281,13 @@ I32 safebase; /* no need to remember string in subbase */ regtill = startpos+minend; /* Simplest case: anchored match need be tried only once. */ - /* [unless multiline is set] */ + /* [unless only anchor is BOL and multiline is set] */ if (prog->reganch & ROPT_ANCH) { if (regtry(prog, startpos)) goto got_it; - else if (multiline || (prog->reganch & ROPT_IMPLICIT)) { + else if (!(prog->reganch & ROPT_ANCH_GPOS) && + (multiline || (prog->reganch & ROPT_IMPLICIT))) + { if (minlen) dontbother = minlen - 1; strend -= dontbother; @@ -281,19 +308,19 @@ I32 safebase; /* no need to remember string in subbase */ if (prog->regstart) { if (prog->reganch & ROPT_SKIP) { /* we have /x+whatever/ */ /* it must be a one character string */ - i = SvPVX(prog->regstart)[0]; + char ch = SvPVX(prog->regstart)[0]; while (s < strend) { - if (*s == i) { + if (*s == ch) { if (regtry(prog, s)) goto got_it; s++; - while (s < strend && *s == i) + while (s < strend && *s == ch) s++; } s++; } } - else if (SvPOK(prog->regstart) == 3) { + else if (SvTYPE(prog->regstart) == SVt_PVBM) { /* We know what string it must start with. */ while ((s = fbm_instr((unsigned char*)s, (unsigned char*)strend, prog->regstart)) != NULL) @@ -303,7 +330,7 @@ I32 safebase; /* no need to remember string in subbase */ s++; } } - else { + else { /* Optimized fbm_instr: */ c = SvPVX(prog->regstart); while ((s = ninstr(s, strend, c, c + SvCUR(prog->regstart))) != NULL) { @@ -327,8 +354,7 @@ I32 safebase; /* no need to remember string in subbase */ case ANYOF: c = OPERAND(c); while (s < strend) { - i = UCHARAT(s); - if (!(c[i >> 3] & (1 << (i&7)))) { + if (reginclass(c, *s)) { if (tmp && regtry(prog, s)) goto got_it; else @@ -339,18 +365,16 @@ I32 safebase; /* no need to remember string in subbase */ s++; } break; + case BOUNDL: + regtainted = TRUE; + /* FALL THROUGH */ case BOUND: if (minlen) dontbother++,strend--; - if (s != startpos) { - i = s[-1]; - tmp = isALNUM(i); - } - else - tmp = isALNUM(regprev); /* assume not alphanumeric */ + tmp = (s != startpos) ? UCHARAT(s - 1) : regprev; + tmp = ((OP(c) == BOUND ? isALNUM(tmp) : isALNUM_LC(tmp)) != 0); while (s < strend) { - i = *s; - if (tmp != isALNUM(i)) { + if (tmp == !(OP(c) == BOUND ? isALNUM(*s) : isALNUM_LC(*s))) { tmp = !tmp; if (regtry(prog, s)) goto got_it; @@ -360,18 +384,16 @@ I32 safebase; /* no need to remember string in subbase */ if ((minlen || tmp) && regtry(prog,s)) goto got_it; break; + case NBOUNDL: + regtainted = TRUE; + /* FALL THROUGH */ case NBOUND: if (minlen) dontbother++,strend--; - if (s != startpos) { - i = s[-1]; - tmp = isALNUM(i); - } - else - tmp = isALNUM(regprev); /* assume not alphanumeric */ + tmp = (s != startpos) ? UCHARAT(s - 1) : regprev; + tmp = ((OP(c) == NBOUND ? isALNUM(tmp) : isALNUM_LC(tmp)) != 0); while (s < strend) { - i = *s; - if (tmp != isALNUM(i)) + if (tmp == !(OP(c) == NBOUND ? isALNUM(*s) : isALNUM_LC(*s))) tmp = !tmp; else if (regtry(prog, s)) goto got_it; @@ -382,8 +404,21 @@ I32 safebase; /* no need to remember string in subbase */ break; case ALNUM: while (s < strend) { - i = *s; - if (isALNUM(i)) { + if (isALNUM(*s)) { + if (tmp && regtry(prog, s)) + goto got_it; + else + tmp = doevery; + } + else + tmp = 1; + s++; + } + break; + case ALNUML: + regtainted = TRUE; + while (s < strend) { + if (isALNUM_LC(*s)) { if (tmp && regtry(prog, s)) goto got_it; else @@ -396,8 +431,21 @@ I32 safebase; /* no need to remember string in subbase */ break; case NALNUM: while (s < strend) { - i = *s; - if (!isALNUM(i)) { + if (!isALNUM(*s)) { + if (tmp && regtry(prog, s)) + goto got_it; + else + tmp = doevery; + } + else + tmp = 1; + s++; + } + break; + case NALNUML: + regtainted = TRUE; + while (s < strend) { + if (!isALNUM_LC(*s)) { if (tmp && regtry(prog, s)) goto got_it; else @@ -421,6 +469,20 @@ I32 safebase; /* no need to remember string in subbase */ s++; } break; + case SPACEL: + regtainted = TRUE; + while (s < strend) { + if (isSPACE_LC(*s)) { + if (tmp && regtry(prog, s)) + goto got_it; + else + tmp = doevery; + } + else + tmp = 1; + s++; + } + break; case NSPACE: while (s < strend) { if (!isSPACE(*s)) { @@ -434,6 +496,20 @@ I32 safebase; /* no need to remember string in subbase */ s++; } break; + case NSPACEL: + regtainted = TRUE; + while (s < strend) { + if (!isSPACE_LC(*s)) { + if (tmp && regtry(prog, s)) + goto got_it; + else + tmp = doevery; + } + else + tmp = 1; + s++; + } + break; case DIGIT: while (s < strend) { if (isDIGIT(*s)) { @@ -480,38 +556,35 @@ got_it: strend += dontbother; /* uncheat */ prog->subbeg = strbeg; prog->subend = strend; - if ((!safebase && (prog->nparens || sawampersand)) || prog->do_folding) { - i = strend - startpos + (stringarg - strbeg); - if (safebase) { /* no need for $digit later */ - s = strbeg; - prog->subend = s+i; - } - else if (strbeg != prog->subbase) { - s = savepvn(strbeg,i); /* so $digit will work later */ - if (prog->subbase) + prog->exec_tainted = regtainted; + + /* make sure $`, $&, $', and $digit will work later */ + if (strbeg != prog->subbase) { + if (safebase) { + if (prog->subbase) { Safefree(prog->subbase); - prog->subbeg = prog->subbase = s; - prog->subend = s+i; + prog->subbase = Nullch; + } } else { - prog->subbeg = s = prog->subbase; - prog->subend = s+i; - } - s += (stringarg - strbeg); - for (i = 0; i <= prog->nparens; i++) { - if (prog->endp[i]) { - prog->startp[i] = s + (prog->startp[i] - startpos); - prog->endp[i] = s + (prog->endp[i] - startpos); + I32 i = strend - startpos + (stringarg - strbeg); + s = savepvn(strbeg, i); + Safefree(prog->subbase); + prog->subbase = s; + prog->subbeg = prog->subbase; + prog->subend = prog->subbase + i; + s = prog->subbase + (stringarg - strbeg); + for (i = 0; i <= prog->nparens; i++) { + if (prog->endp[i]) { + prog->startp[i] = s + (prog->startp[i] - startpos); + prog->endp[i] = s + (prog->endp[i] - startpos); + } } } - if (prog->do_folding) - Safefree(startpos); } return 1; phooey: - if (prog->do_folding) - Safefree(startpos); return 0; } @@ -576,13 +649,14 @@ char *prog; register I32 ln; /* len or last */ register char *s; /* operand or save */ register char *locinput = reginput; + register I32 c1, c2; /* case fold search */ int minmod = 0; #ifdef DEBUGGING static int regindent = 0; regindent++; #endif - nextchar = *locinput; + nextchar = UCHARAT(locinput); scan = prog; while (scan != NULL) { #ifdef DEBUGGING @@ -590,8 +664,11 @@ char *prog; #define sayNO goto no #define saySAME(x) if (x) goto yes; else goto no if (regnarrate) { - fprintf(stderr, "%*s%2d%-8.8s\t<%.10s>\n", regindent*2, "", - scan - regprogram, regprop(scan), locinput); + SV *prop = sv_newmortal(); + regprop(prop, scan); + PerlIO_printf(Perl_debug_log, "%*s%2ld%-8.8s\t<%.10s>\n", + regindent*2, "", (long)(scan - regprogram), + SvPVX(prop), locinput); } #else #define sayYES return 1 @@ -629,7 +706,7 @@ char *prog; if (locinput == regbol && regprev == '\n') break; sayNO; - case GBOL: + case GPOS: if (locinput == regbol) break; sayNO; @@ -653,87 +730,136 @@ char *prog; case SANY: if (!nextchar && locinput >= regeol) sayNO; - nextchar = *++locinput; + nextchar = UCHARAT(++locinput); break; case ANY: if (!nextchar && locinput >= regeol || nextchar == '\n') sayNO; - nextchar = *++locinput; + nextchar = UCHARAT(++locinput); break; - case EXACTLY: + case EXACT: s = OPERAND(scan); ln = *s++; /* Inline the first character, for speed. */ - if (*s != nextchar) + if (UCHARAT(s) != nextchar) sayNO; if (regeol - locinput < ln) sayNO; - if (ln > 1 && bcmp(s, locinput, ln) != 0) + if (ln > 1 && memNE(s, locinput, ln)) sayNO; locinput += ln; - nextchar = *locinput; + nextchar = UCHARAT(locinput); + break; + case EXACTFL: + regtainted = TRUE; + /* FALL THROUGH */ + case EXACTF: + s = OPERAND(scan); + ln = *s++; + /* Inline the first character, for speed. */ + if (UCHARAT(s) != nextchar && + UCHARAT(s) != ((OP(scan) == EXACTF) + ? fold : fold_locale)[nextchar]) + sayNO; + if (regeol - locinput < ln) + sayNO; + if (ln > 1 && (OP(scan) == EXACTF + ? ibcmp(s, locinput, ln) + : ibcmp_locale(s, locinput, ln))) + sayNO; + locinput += ln; + nextchar = UCHARAT(locinput); break; case ANYOF: s = OPERAND(scan); if (nextchar < 0) nextchar = UCHARAT(locinput); - if (s[nextchar >> 3] & (1 << (nextchar&7))) + if (!reginclass(s, nextchar)) sayNO; if (!nextchar && locinput >= regeol) sayNO; - nextchar = *++locinput; + nextchar = UCHARAT(++locinput); break; + case ALNUML: + regtainted = TRUE; + /* FALL THROUGH */ case ALNUM: if (!nextchar) sayNO; - if (!isALNUM(nextchar)) + if (!(OP(scan) == ALNUM + ? isALNUM(nextchar) : isALNUM_LC(nextchar))) sayNO; - nextchar = *++locinput; + nextchar = UCHARAT(++locinput); break; + case NALNUML: + regtainted = TRUE; + /* FALL THROUGH */ case NALNUM: if (!nextchar && locinput >= regeol) sayNO; - if (isALNUM(nextchar)) + if (OP(scan) == NALNUM + ? isALNUM(nextchar) : isALNUM_LC(nextchar)) sayNO; - nextchar = *++locinput; + nextchar = UCHARAT(++locinput); break; - case NBOUND: + case BOUNDL: + case NBOUNDL: + regtainted = TRUE; + /* FALL THROUGH */ case BOUND: - if (locinput == regbol) /* was last char in word? */ - ln = isALNUM(regprev); - else - ln = isALNUM(locinput[-1]); - n = isALNUM(nextchar); /* is next char in word? */ - if ((ln == n) == (OP(scan) == BOUND)) + case NBOUND: + /* was last char in word? */ + ln = (locinput != regbol) ? UCHARAT(locinput - 1) : regprev; + if (OP(scan) == BOUND || OP(scan) == NBOUND) { + ln = isALNUM(ln); + n = isALNUM(nextchar); + } + else { + ln = isALNUM_LC(ln); + n = isALNUM_LC(nextchar); + } + if (((!ln) == (!n)) == (OP(scan) == BOUND || OP(scan) == BOUNDL)) sayNO; break; + case SPACEL: + regtainted = TRUE; + /* FALL THROUGH */ case SPACE: if (!nextchar && locinput >= regeol) sayNO; - if (!isSPACE(nextchar)) + if (!(OP(scan) == SPACE + ? isSPACE(nextchar) : isSPACE_LC(nextchar))) sayNO; - nextchar = *++locinput; + nextchar = UCHARAT(++locinput); break; + case NSPACEL: + regtainted = TRUE; + /* FALL THROUGH */ case NSPACE: if (!nextchar) sayNO; - if (isSPACE(nextchar)) + if (OP(scan) == SPACE + ? isSPACE(nextchar) : isSPACE_LC(nextchar)) sayNO; - nextchar = *++locinput; + nextchar = UCHARAT(++locinput); break; case DIGIT: if (!isDIGIT(nextchar)) sayNO; - nextchar = *++locinput; + nextchar = UCHARAT(++locinput); break; case NDIGIT: if (!nextchar && locinput >= regeol) sayNO; if (isDIGIT(nextchar)) sayNO; - nextchar = *++locinput; + nextchar = UCHARAT(++locinput); break; + case REFFL: + regtainted = TRUE; + /* FALL THROUGH */ case REF: + case REFF: n = ARG1(scan); /* which paren pair */ s = regstartp[n]; if (!s) @@ -743,15 +869,22 @@ char *prog; if (s == regendp[n]) break; /* Inline the first character, for speed. */ - if (*s != nextchar) + if (UCHARAT(s) != nextchar && + (OP(scan) == REF || + (UCHARAT(s) != ((OP(scan) == REFF + ? fold : fold_locale)[nextchar])))) sayNO; ln = regendp[n] - s; if (locinput + ln > regeol) sayNO; - if (ln > 1 && bcmp(s, locinput, ln) != 0) + if (ln > 1 && (OP(scan) == REF + ? memNE(s, locinput, ln) + : (OP(scan) == REFF + ? ibcmp(s, locinput, ln) + : ibcmp_locale(s, locinput, ln)))) sayNO; locinput += ln; - nextchar = *locinput; + nextchar = UCHARAT(locinput); break; case NOTHING: @@ -800,19 +933,20 @@ char *prog; * that we can try again after backing off. */ + CHECKPOINT cp; CURCUR* cc = regcc; n = cc->cur + 1; /* how many we know we matched */ reginput = locinput; #ifdef DEBUGGING if (regnarrate) - fprintf(stderr, "%*s %d %lx\n", regindent*2, "", - n, (long)cc); + PerlIO_printf(Perl_debug_log, "%*s %ld %lx\n", regindent*2, "", + (long)n, (long)cc); #endif /* If degenerate scan matches "", assume scan done. */ - if (locinput == cc->lastloc) { + if (locinput == cc->lastloc && n >= cc->min) { regcc = cc->oldcc; ln = regcc->cur; if (regmatch(cc->next)) @@ -838,8 +972,12 @@ char *prog; if (cc->minmod) { regcc = cc->oldcc; ln = regcc->cur; - if (regmatch(cc->next)) + cp = regcppush(cc->parenfloor); + if (regmatch(cc->next)) { + regcppartblow(cp); sayYES; /* All done. */ + } + regcppop(); regcc->cur = ln; regcc = cc; @@ -850,8 +988,12 @@ char *prog; reginput = locinput; cc->cur = n; cc->lastloc = locinput; - if (regmatch(cc->scan)) + cp = regcppush(cc->parenfloor); + if (regmatch(cc->scan)) { + regcppartblow(cp); sayYES; + } + regcppop(); cc->cur = n - 1; sayNO; } @@ -859,11 +1001,13 @@ char *prog; /* Prefer scan over next for maximal matching. */ if (n < cc->max) { /* More greed allowed? */ - regcppush(cc->parenfloor); + cp = regcppush(cc->parenfloor); cc->cur = n; cc->lastloc = locinput; - if (regmatch(cc->scan)) + if (regmatch(cc->scan)) { + regcppartblow(cp); sayYES; + } regcppop(); /* Restore some previous $<digit>s? */ reginput = locinput; } @@ -929,10 +1073,17 @@ char *prog; n = 32767; scan = NEXTOPER(scan); repeat: - if (OP(next) == EXACTLY) - nextchar = *(OPERAND(next)+1); + if (regkind[(U8)OP(next)] == EXACT) { + c1 = UCHARAT(OPERAND(next) + 1); + if (OP(next) == EXACTF) + c2 = fold[c1]; + else if (OP(next) == EXACTFL) + c2 = fold_locale[c1]; + else + c2 = c1; + } else - nextchar = -1000; + c1 = c2 = -1000; reginput = locinput; if (minmod) { minmod = 0; @@ -940,9 +1091,13 @@ char *prog; sayNO; while (n >= ln || (n == 32767 && ln > 0)) { /* ln overflow ? */ /* If it could work, try it. */ - if (nextchar == -1000 || *reginput == nextchar) + if (c1 == -1000 || + UCHARAT(reginput) == c1 || + UCHARAT(reginput) == c2) + { if (regmatch(next)) sayYES; + } /* Couldn't or didn't -- back up. */ reginput = locinput + ln; if (regrepeat(scan, 1)) { @@ -960,9 +1115,13 @@ char *prog; ln = n; /* why back off? */ while (n >= ln) { /* If it could work, try it. */ - if (nextchar == -1000 || *reginput == nextchar) + if (c1 == -1000 || + UCHARAT(reginput) == c1 || + UCHARAT(reginput) == c2) + { if (regmatch(next)) sayYES; + } /* Couldn't or didn't -- back up. */ n--; reginput = locinput + n; @@ -986,7 +1145,8 @@ char *prog; sayNO; break; default: - fprintf(stderr, "%x %d\n",(unsigned)scan,scan[1]); + PerlIO_printf(PerlIO_stderr(), "%lx %d\n", + (unsigned long)scan, scan[1]); FAIL("regexp memory corruption"); } scan = next; @@ -1043,34 +1203,64 @@ I32 max; case SANY: scan = loceol; break; - case EXACTLY: /* length of string is 1 */ - opnd++; - while (scan < loceol && *opnd == *scan) + case EXACT: /* length of string is 1 */ + c = UCHARAT(++opnd); + while (scan < loceol && UCHARAT(scan) == c) + scan++; + break; + case EXACTF: /* length of string is 1 */ + c = UCHARAT(++opnd); + while (scan < loceol && + (UCHARAT(scan) == c || UCHARAT(scan) == fold[c])) + scan++; + break; + case EXACTFL: /* length of string is 1 */ + regtainted = TRUE; + c = UCHARAT(++opnd); + while (scan < loceol && + (UCHARAT(scan) == c || UCHARAT(scan) == fold_locale[c])) scan++; break; case ANYOF: - c = UCHARAT(scan); - while (scan < loceol && !(opnd[c >> 3] & (1 << (c & 7)))) { + while (scan < loceol && reginclass(opnd, *scan)) scan++; - c = UCHARAT(scan); - } break; case ALNUM: while (scan < loceol && isALNUM(*scan)) scan++; break; + case ALNUML: + regtainted = TRUE; + while (scan < loceol && isALNUM_LC(*scan)) + scan++; + break; case NALNUM: while (scan < loceol && !isALNUM(*scan)) scan++; break; + case NALNUML: + regtainted = TRUE; + while (scan < loceol && !isALNUM_LC(*scan)) + scan++; + break; case SPACE: while (scan < loceol && isSPACE(*scan)) scan++; break; + case SPACEL: + regtainted = TRUE; + while (scan < loceol && isSPACE_LC(*scan)) + scan++; + break; case NSPACE: while (scan < loceol && !isSPACE(*scan)) scan++; break; + case NSPACEL: + regtainted = TRUE; + while (scan < loceol && !isSPACE_LC(*scan)) + scan++; + break; case DIGIT: while (scan < loceol && isDIGIT(*scan)) scan++; @@ -1090,6 +1280,48 @@ I32 max; } /* + - regclass - determine if a character falls into a character class + */ + +static bool +reginclass(p, c) +register char *p; +register I32 c; +{ + char flags = *p; + bool match = FALSE; + + c &= 0xFF; + if (p[1 + (c >> 3)] & (1 << (c & 7))) + match = TRUE; + else if (flags & ANYOF_FOLD) { + I32 cf; + if (flags & ANYOF_LOCALE) { + regtainted = TRUE; + cf = fold_locale[c]; + } + else + cf = fold[c]; + if (p[1 + (cf >> 3)] & (1 << (cf & 7))) + match = TRUE; + } + + if (!match && (flags & ANYOF_ISA)) { + regtainted = TRUE; + + if (((flags & ANYOF_ALNUML) && isALNUM_LC(c)) || + ((flags & ANYOF_NALNUML) && !isALNUM_LC(c)) || + ((flags & ANYOF_SPACEL) && isSPACE_LC(c)) || + ((flags & ANYOF_NSPACEL) && !isSPACE_LC(c))) + { + match = TRUE; + } + } + + return match ^ ((flags & ANYOF_INVERT) != 0); +} + +/* - regnext - dig the "next" pointer out of a node * * [Note, when REGALIGN is defined there are two places in regmatch() diff --git a/gnu/usr.bin/perl/regexp.h b/gnu/usr.bin/perl/regexp.h index 018312ec243..684851c548d 100644 --- a/gnu/usr.bin/perl/regexp.h +++ b/gnu/usr.bin/perl/regexp.h @@ -26,10 +26,12 @@ typedef struct regexp { char *subend; /* end of subbase */ U16 naughty; /* how exponential is this pattern? */ char reganch; /* Internal use only. */ - char do_folding; /* do case-insensitive match? */ + char exec_tainted; /* Tainted information used by regexec? */ char program[1]; /* Unwarranted chumminess with compiler. */ } regexp; -#define ROPT_ANCH 1 -#define ROPT_SKIP 2 -#define ROPT_IMPLICIT 4 +#define ROPT_ANCH 3 +#define ROPT_ANCH_BOL 1 +#define ROPT_ANCH_GPOS 2 +#define ROPT_SKIP 4 +#define ROPT_IMPLICIT 8 diff --git a/gnu/usr.bin/perl/run.c b/gnu/usr.bin/perl/run.c index 7c09f8f58bd..0ce2b9ffed0 100644 --- a/gnu/usr.bin/perl/run.c +++ b/gnu/usr.bin/perl/run.c @@ -1,6 +1,6 @@ /* run.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -27,6 +27,8 @@ runops() { runlevel++; while ( op = (*op->op_ppaddr)() ) ; + + TAINT_NOT; return 0; } @@ -47,13 +49,15 @@ runops() { do { if (debug) { if (watchaddr != 0 && *watchaddr != watchok) - fprintf(stderr, "WARNING: %lx changed from %lx to %lx\n", + PerlIO_printf(Perl_debug_log, "WARNING: %lx changed from %lx to %lx\n", (long)watchaddr, (long)watchok, (long)*watchaddr); DEBUG_s(debstack()); DEBUG_t(debop(op)); DEBUG_P(debprof(op)); } } while ( op = (*op->op_ppaddr)() ); + + TAINT_NOT; return 0; } @@ -65,23 +69,23 @@ OP *op; deb("%s", op_name[op->op_type]); switch (op->op_type) { case OP_CONST: - fprintf(stderr, "(%s)", SvPEEK(cSVOP->op_sv)); + PerlIO_printf(Perl_debug_log, "(%s)", SvPEEK(cSVOP->op_sv)); break; case OP_GVSV: case OP_GV: if (cGVOP->op_gv) { sv = NEWSV(0,0); - gv_fullname(sv, cGVOP->op_gv); - fprintf(stderr, "(%s)", SvPV(sv, na)); + gv_fullname3(sv, cGVOP->op_gv, Nullch); + PerlIO_printf(Perl_debug_log, "(%s)", SvPV(sv, na)); SvREFCNT_dec(sv); } else - fprintf(stderr, "(NULL)"); + PerlIO_printf(Perl_debug_log, "(NULL)"); break; default: break; } - fprintf(stderr, "\n"); + PerlIO_printf(Perl_debug_log, "\n"); return 0; } @@ -91,7 +95,7 @@ char **addr; { watchaddr = addr; watchok = *addr; - fprintf(stderr, "WATCHING, %lx is currently %lx\n", + PerlIO_printf(Perl_debug_log, "WATCHING, %lx is currently %lx\n", (long)watchaddr, (long)watchok); } @@ -107,12 +111,13 @@ OP* op; void debprofdump() { - U32 i; + unsigned i; if (!profiledata) return; for (i = 0; i < MAXO; i++) { if (profiledata[i]) - fprintf(stderr, "%d\t%lu\n", i, profiledata[i]); + PerlIO_printf(Perl_debug_log, + "%u\t%lu\n", i, (unsigned long)profiledata[i]); } } diff --git a/gnu/usr.bin/perl/scope.c b/gnu/usr.bin/perl/scope.c index 3f4860990d7..3006f1adc35 100644 --- a/gnu/usr.bin/perl/scope.c +++ b/gnu/usr.bin/perl/scope.c @@ -1,6 +1,6 @@ /* scope.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -22,7 +22,7 @@ SV** p; int n; { stack_sp = sp; - av_extend(stack, (p - stack_base) + (n) + 128); + av_extend(curstack, (p - stack_base) + (n) + 128); return stack_sp; } @@ -107,19 +107,14 @@ free_tmps() } } -SV * -save_scalar(gv) -GV *gv; +static SV * +save_scalar_at(sptr) +SV **sptr; { register SV *sv; - SV *osv = GvSV(gv); - - SSCHECK(3); - SSPUSHPTR(gv); - SSPUSHPTR(osv); - SSPUSHINT(SAVEt_SV); + SV *osv = *sptr; - sv = GvSV(gv) = NEWSV(0,0); + sv = *sptr = NEWSV(0,0); if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv) && SvTYPE(osv) != SVt_PVGV) { sv_upgrade(sv, SvTYPE(osv)); if (SvGMAGICAL(osv)) { @@ -143,88 +138,105 @@ GV *gv; return sv; } -#ifdef INLINED_ELSEWHERE -void -save_gp(gv) +SV * +save_scalar(gv) GV *gv; { - register GP *gp; - GP *ogp = GvGP(gv); - SSCHECK(3); - SSPUSHPTR(SvREFCNT_inc(gv)); - SSPUSHPTR(ogp); - SSPUSHINT(SAVEt_GP); - - Newz(602,gp, 1, GP); - GvGP(gv) = gp; - GvREFCNT(gv) = 1; - GvSV(gv) = NEWSV(72,0); - GvLINE(gv) = curcop->cop_line; - GvEGV(gv) = gv; + SSPUSHPTR(gv); + SSPUSHPTR(GvSV(gv)); + SSPUSHINT(SAVEt_SV); + return save_scalar_at(&GvSV(gv)); } -#endif SV* save_svref(sptr) SV **sptr; { - register SV *sv; - SV *osv = *sptr; - SSCHECK(3); - SSPUSHPTR(*sptr); SSPUSHPTR(sptr); + SSPUSHPTR(*sptr); SSPUSHINT(SAVEt_SVREF); + return save_scalar_at(sptr); +} - sv = *sptr = NEWSV(0,0); - if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv) && SvTYPE(osv) != SVt_PVGV) { - sv_upgrade(sv, SvTYPE(osv)); - if (SvGMAGICAL(osv)) { - MAGIC* mg; - bool oldtainted = tainted; - mg_get(osv); - if (tainting && tainted && (mg = mg_find(osv, 't'))) { - SAVESPTR(mg->mg_obj); - mg->mg_obj = osv; - } - SvFLAGS(osv) |= (SvFLAGS(osv) & - (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT; - tainted = oldtainted; - } - SvMAGIC(sv) = SvMAGIC(osv); - SvFLAGS(sv) |= SvMAGICAL(osv); - localizing = 1; - SvSETMAGIC(sv); - localizing = 0; +void +save_gp(gv, empty) +GV *gv; +I32 empty; +{ + SSCHECK(6); + SSPUSHIV((IV)SvLEN(gv)); + SvLEN(gv) = 0; /* forget that anything was allocated here */ + SSPUSHIV((IV)SvCUR(gv)); + SSPUSHPTR(SvPVX(gv)); + SvPOK_off(gv); + SSPUSHPTR(SvREFCNT_inc(gv)); + SSPUSHPTR(GvGP(gv)); + SSPUSHINT(SAVEt_GP); + + if (empty) { + register GP *gp; + Newz(602, gp, 1, GP); + GvGP(gv) = gp_ref(gp); + GvSV(gv) = NEWSV(72,0); + GvLINE(gv) = curcop->cop_line; + GvEGV(gv) = gv; + } + else { + gp_ref(GvGP(gv)); + GvINTRO_on(gv); } - return sv; } AV * save_ary(gv) GV *gv; { + AV *oav, *av; + SSCHECK(3); SSPUSHPTR(gv); - SSPUSHPTR(GvAVn(gv)); + SSPUSHPTR(oav = GvAVn(gv)); SSPUSHINT(SAVEt_AV); GvAV(gv) = Null(AV*); - return GvAVn(gv); + av = GvAVn(gv); + if (SvMAGIC(oav)) { + SvMAGIC(av) = SvMAGIC(oav); + SvFLAGS(av) |= SvMAGICAL(oav); + SvMAGICAL_off(oav); + SvMAGIC(oav) = 0; + localizing = 1; + SvSETMAGIC((SV*)av); + localizing = 0; + } + return av; } HV * save_hash(gv) GV *gv; { + HV *ohv, *hv; + SSCHECK(3); SSPUSHPTR(gv); - SSPUSHPTR(GvHVn(gv)); + SSPUSHPTR(ohv = GvHVn(gv)); SSPUSHINT(SAVEt_HV); GvHV(gv) = Null(HV*); - return GvHVn(gv); + hv = GvHVn(gv); + if (SvMAGIC(ohv)) { + SvMAGIC(hv) = SvMAGIC(ohv); + SvFLAGS(hv) |= SvMAGICAL(ohv); + SvMAGICAL_off(ohv); + SvMAGIC(ohv) = 0; + localizing = 1; + SvSETMAGIC((SV*)hv); + localizing = 0; + } + return hv; } void @@ -272,6 +284,16 @@ I32 *intp; } void +save_I16(intp) +I16 *intp; +{ + SSCHECK(3); + SSPUSHINT(*intp); + SSPUSHPTR(intp); + SSPUSHINT(SAVEt_I16); +} + +void save_iv(ivp) IV *ivp; { @@ -437,26 +459,13 @@ I32 base; case SAVEt_SV: /* scalar reference */ value = (SV*)SSPOPPTR; gv = (GV*)SSPOPPTR; - sv = GvSV(gv); - if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv) && - SvTYPE(sv) != SVt_PVGV) - { - (void)SvUPGRADE(value, SvTYPE(sv)); - SvMAGIC(value) = SvMAGIC(sv); - SvFLAGS(value) |= SvMAGICAL(sv); - SvMAGICAL_off(sv); - SvMAGIC(sv) = 0; - } - SvREFCNT_dec(sv); - GvSV(gv) = value; - localizing = 2; - SvSETMAGIC(value); - localizing = 0; - break; + ptr = &GvSV(gv); + goto restore_sv; case SAVEt_SVREF: /* scalar reference */ + value = (SV*)SSPOPPTR; ptr = SSPOPPTR; + restore_sv: sv = *(SV**)ptr; - value = (SV*)SSPOPPTR; if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv) && SvTYPE(sv) != SVt_PVGV) { @@ -466,6 +475,14 @@ I32 base; SvMAGICAL_off(sv); SvMAGIC(sv) = 0; } + else if (SvTYPE(value) >= SVt_PVMG && SvMAGIC(value) && + SvTYPE(value) != SVt_PVGV) + { + SvFLAGS(value) |= (SvFLAGS(value) & + (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT; + SvMAGICAL_off(value); + SvMAGIC(value) = 0; + } SvREFCNT_dec(sv); *(SV**)ptr = value; localizing = 2; @@ -475,14 +492,38 @@ I32 base; case SAVEt_AV: /* array reference */ av = (AV*)SSPOPPTR; gv = (GV*)SSPOPPTR; - SvREFCNT_dec(GvAV(gv)); + if (GvAV(gv)) { + AV *goner = GvAV(gv); + SvMAGIC(av) = SvMAGIC(goner); + SvFLAGS(av) |= SvMAGICAL(goner); + SvMAGICAL_off(goner); + SvMAGIC(goner) = 0; + SvREFCNT_dec(goner); + } GvAV(gv) = av; + if (SvMAGICAL(av)) { + localizing = 2; + SvSETMAGIC((SV*)av); + localizing = 0; + } break; case SAVEt_HV: /* hash reference */ hv = (HV*)SSPOPPTR; gv = (GV*)SSPOPPTR; - SvREFCNT_dec(GvHV(gv)); + if (GvHV(gv)) { + HV *goner = GvHV(gv); + SvMAGIC(hv) = SvMAGIC(goner); + SvFLAGS(hv) |= SvMAGICAL(goner); + SvMAGICAL_off(goner); + SvMAGIC(goner) = 0; + SvREFCNT_dec(goner); + } GvHV(gv) = hv; + if (SvMAGICAL(hv)) { + localizing = 2; + SvSETMAGIC((SV*)hv); + localizing = 0; + } break; case SAVEt_INT: /* int reference */ ptr = SSPOPPTR; @@ -496,6 +537,10 @@ I32 base; ptr = SSPOPPTR; *(I32*)ptr = (I32)SSPOPINT; break; + case SAVEt_I16: /* I16 reference */ + ptr = SSPOPPTR; + *(I16*)ptr = (I16)SSPOPINT; + break; case SAVEt_IV: /* IV reference */ ptr = SSPOPPTR; *(IV*)ptr = (IV)SSPOPIV; @@ -518,13 +563,19 @@ I32 base; break; case SAVEt_NSTAB: gv = (GV*)SSPOPPTR; - (void)sv_clear(gv); + (void)sv_clear((SV*)gv); break; - case SAVEt_GP: /* scalar reference */ + case SAVEt_GP: /* scalar reference */ ptr = SSPOPPTR; gv = (GV*)SSPOPPTR; gp_free(gv); GvGP(gv) = (GP*)ptr; + if (SvPOK(gv) && SvLEN(gv) > 0) { + Safefree(SvPVX(gv)); + } + SvPVX(gv) = (char *)SSPOPPTR; + SvCUR(gv) = (STRLEN)SSPOPIV; + SvLEN(gv) = (STRLEN)SSPOPIV; SvREFCNT_dec(gv); break; case SAVEt_FREESV: @@ -533,7 +584,8 @@ I32 base; break; case SAVEt_FREEOP: ptr = SSPOPPTR; - curpad = AvARRAY(comppad); + if (comppad) + curpad = AvARRAY(comppad); op_free((OP*)ptr); break; case SAVEt_FREEPV: @@ -543,7 +595,8 @@ I32 base; case SAVEt_CLEARSV: ptr = (void*)&curpad[SSPOPLONG]; sv = *(SV**)ptr; - if (SvREFCNT(sv) <= 1) { /* Can clear pad variable in place. */ + /* Can clear pad variable in place? */ + if (SvREFCNT(sv) <= 1 && !SvOBJECT(sv)) { if (SvTHINKFIRST(sv)) { if (SvREADONLY(sv)) croak("panic: leave_scope clearsv"); @@ -563,13 +616,15 @@ I32 base; hv_clear((HV*)sv); break; case SVt_PVCV: - sub_generation++; - cv_undef((CV*)sv); + croak("panic: leave_scope pad code"); + case SVt_RV: + case SVt_IV: + case SVt_NV: + (void)SvOK_off(sv); break; default: - if (SvPOK(sv) && SvLEN(sv)) - (void)SvOOK_off(sv); (void)SvOK_off(sv); + (void)SvOOK_off(sv); break; } } @@ -601,6 +656,12 @@ I32 base; savestack_ix -= delta; /* regexp must have croaked */ } break; + case SAVEt_STACK_POS: /* Position on Perl stack */ + { + I32 delta = SSPOPINT; + stack_sp = stack_base + delta; + } + break; default: croak("panic: leave_scope inconsistency"); } @@ -608,93 +669,96 @@ I32 base; } #ifdef DEBUGGING + void cx_dump(cx) CONTEXT* cx; { - fprintf(stderr, "CX %d = %s\n", cx - cxstack, block_type[cx->cx_type]); + PerlIO_printf(Perl_debug_log, "CX %ld = %s\n", (long)(cx - cxstack), block_type[cx->cx_type]); if (cx->cx_type != CXt_SUBST) { - fprintf(stderr, "BLK_OLDSP = %ld\n", (long)cx->blk_oldsp); - fprintf(stderr, "BLK_OLDCOP = 0x%lx\n", (long)cx->blk_oldcop); - fprintf(stderr, "BLK_OLDMARKSP = %ld\n", (long)cx->blk_oldmarksp); - fprintf(stderr, "BLK_OLDSCOPESP = %ld\n", (long)cx->blk_oldscopesp); - fprintf(stderr, "BLK_OLDRETSP = %ld\n", (long)cx->blk_oldretsp); - fprintf(stderr, "BLK_OLDPM = 0x%lx\n", (long)cx->blk_oldpm); - fprintf(stderr, "BLK_GIMME = %s\n", cx->blk_gimme ? "LIST" : "SCALAR"); + PerlIO_printf(Perl_debug_log, "BLK_OLDSP = %ld\n", (long)cx->blk_oldsp); + PerlIO_printf(Perl_debug_log, "BLK_OLDCOP = 0x%lx\n", (long)cx->blk_oldcop); + PerlIO_printf(Perl_debug_log, "BLK_OLDMARKSP = %ld\n", (long)cx->blk_oldmarksp); + PerlIO_printf(Perl_debug_log, "BLK_OLDSCOPESP = %ld\n", (long)cx->blk_oldscopesp); + PerlIO_printf(Perl_debug_log, "BLK_OLDRETSP = %ld\n", (long)cx->blk_oldretsp); + PerlIO_printf(Perl_debug_log, "BLK_OLDPM = 0x%lx\n", (long)cx->blk_oldpm); + PerlIO_printf(Perl_debug_log, "BLK_GIMME = %s\n", cx->blk_gimme ? "LIST" : "SCALAR"); } switch (cx->cx_type) { case CXt_NULL: case CXt_BLOCK: break; case CXt_SUB: - fprintf(stderr, "BLK_SUB.CV = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "BLK_SUB.CV = 0x%lx\n", (long)cx->blk_sub.cv); - fprintf(stderr, "BLK_SUB.GV = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "BLK_SUB.GV = 0x%lx\n", (long)cx->blk_sub.gv); - fprintf(stderr, "BLK_SUB.DFOUTGV = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "BLK_SUB.DFOUTGV = 0x%lx\n", (long)cx->blk_sub.dfoutgv); - fprintf(stderr, "BLK_SUB.OLDDEPTH = %ld\n", + PerlIO_printf(Perl_debug_log, "BLK_SUB.OLDDEPTH = %ld\n", (long)cx->blk_sub.olddepth); - fprintf(stderr, "BLK_SUB.HASARGS = %d\n", + PerlIO_printf(Perl_debug_log, "BLK_SUB.HASARGS = %d\n", (int)cx->blk_sub.hasargs); break; case CXt_EVAL: - fprintf(stderr, "BLK_EVAL.OLD_IN_EVAL = %ld\n", + PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_IN_EVAL = %ld\n", (long)cx->blk_eval.old_in_eval); - fprintf(stderr, "BLK_EVAL.OLD_OP_TYPE = %s (%s)\n", + PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_OP_TYPE = %s (%s)\n", op_name[cx->blk_eval.old_op_type], op_desc[cx->blk_eval.old_op_type]); - fprintf(stderr, "BLK_EVAL.OLD_NAME = %s\n", + PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_NAME = %s\n", cx->blk_eval.old_name); - fprintf(stderr, "BLK_EVAL.OLD_EVAL_ROOT = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "BLK_EVAL.OLD_EVAL_ROOT = 0x%lx\n", (long)cx->blk_eval.old_eval_root); break; case CXt_LOOP: - fprintf(stderr, "BLK_LOOP.LABEL = %s\n", + PerlIO_printf(Perl_debug_log, "BLK_LOOP.LABEL = %s\n", cx->blk_loop.label); - fprintf(stderr, "BLK_LOOP.RESETSP = %ld\n", + PerlIO_printf(Perl_debug_log, "BLK_LOOP.RESETSP = %ld\n", (long)cx->blk_loop.resetsp); - fprintf(stderr, "BLK_LOOP.REDO_OP = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "BLK_LOOP.REDO_OP = 0x%lx\n", (long)cx->blk_loop.redo_op); - fprintf(stderr, "BLK_LOOP.NEXT_OP = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "BLK_LOOP.NEXT_OP = 0x%lx\n", (long)cx->blk_loop.next_op); - fprintf(stderr, "BLK_LOOP.LAST_OP = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "BLK_LOOP.LAST_OP = 0x%lx\n", (long)cx->blk_loop.last_op); - fprintf(stderr, "BLK_LOOP.ITERIX = %ld\n", + PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERIX = %ld\n", (long)cx->blk_loop.iterix); - fprintf(stderr, "BLK_LOOP.ITERARY = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERARY = 0x%lx\n", (long)cx->blk_loop.iterary); - fprintf(stderr, "BLK_LOOP.ITERVAR = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERVAR = 0x%lx\n", (long)cx->blk_loop.itervar); if (cx->blk_loop.itervar) - fprintf(stderr, "BLK_LOOP.ITERSAVE = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERSAVE = 0x%lx\n", (long)cx->blk_loop.itersave); + PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERLVAL = 0x%lx\n", + (long)cx->blk_loop.iterlval); break; case CXt_SUBST: - fprintf(stderr, "SB_ITERS = %ld\n", + PerlIO_printf(Perl_debug_log, "SB_ITERS = %ld\n", (long)cx->sb_iters); - fprintf(stderr, "SB_MAXITERS = %ld\n", + PerlIO_printf(Perl_debug_log, "SB_MAXITERS = %ld\n", (long)cx->sb_maxiters); - fprintf(stderr, "SB_SAFEBASE = %ld\n", + PerlIO_printf(Perl_debug_log, "SB_SAFEBASE = %ld\n", (long)cx->sb_safebase); - fprintf(stderr, "SB_ONCE = %ld\n", + PerlIO_printf(Perl_debug_log, "SB_ONCE = %ld\n", (long)cx->sb_once); - fprintf(stderr, "SB_ORIG = %s\n", + PerlIO_printf(Perl_debug_log, "SB_ORIG = %s\n", cx->sb_orig); - fprintf(stderr, "SB_DSTR = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "SB_DSTR = 0x%lx\n", (long)cx->sb_dstr); - fprintf(stderr, "SB_TARG = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "SB_TARG = 0x%lx\n", (long)cx->sb_targ); - fprintf(stderr, "SB_S = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "SB_S = 0x%lx\n", (long)cx->sb_s); - fprintf(stderr, "SB_M = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "SB_M = 0x%lx\n", (long)cx->sb_m); - fprintf(stderr, "SB_STREND = 0x%lx\n", + PerlIO_printf(Perl_debug_log, "SB_STREND = 0x%lx\n", (long)cx->sb_strend); - fprintf(stderr, "SB_SUBBASE = 0x%lx\n", - (long)cx->sb_subbase); + PerlIO_printf(Perl_debug_log, "SB_RXRES = 0x%lx\n", + (long)cx->sb_rxres); break; } } diff --git a/gnu/usr.bin/perl/scope.h b/gnu/usr.bin/perl/scope.h index 8845e7cfec0..debe1f88a7f 100644 --- a/gnu/usr.bin/perl/scope.h +++ b/gnu/usr.bin/perl/scope.h @@ -20,6 +20,8 @@ #define SAVEt_DELETE 19 #define SAVEt_DESTRUCTOR 20 #define SAVEt_REGCONTEXT 21 +#define SAVEt_STACK_POS 22 +#define SAVEt_I16 23 #define SSCHECK(need) if (savestack_ix + need > savestack_max) savestack_grow() #define SSPUSHINT(i) (savestack[savestack_ix++].any_i32 = (I32)(i)) @@ -43,16 +45,77 @@ #define LEAVE pop_scope() #define LEAVE_SCOPE(old) if (savestack_ix > old) leave_scope(old) -#define SAVEINT(i) save_int((int*)(&i)); -#define SAVEIV(i) save_iv((IV*)(&i)); -#define SAVEI32(i) save_I32((I32*)(&i)); -#define SAVELONG(l) save_long((long*)(&l)); -#define SAVESPTR(s) save_sptr((SV**)(&s)) -#define SAVEPPTR(s) save_pptr((char**)(&s)) -#define SAVEFREESV(s) save_freesv((SV*)(s)) -#define SAVEFREEOP(o) save_freeop((OP*)(o)) -#define SAVEFREEPV(p) save_freepv((char*)(p)) -#define SAVECLEARSV(sv) save_clearsv((SV**)(&sv)) -#define SAVEDELETE(h,k,l) save_delete((HV*)(h), (char*)(k), (I32)l) -#define SAVEDESTRUCTOR(f,p) save_destructor(f,(void*)p) +/* + * Not using SOFT_CAST on SAVEFREESV and SAVEFREESV + * because these are used for several kinds of pointer values + */ +#define SAVEI16(i) save_I16(SOFT_CAST(I16*)&(i)) +#define SAVEI32(i) save_I32(SOFT_CAST(I32*)&(i)) +#define SAVEINT(i) save_int(SOFT_CAST(int*)&(i)) +#define SAVEIV(i) save_iv(SOFT_CAST(IV*)&(i)) +#define SAVELONG(l) save_long(SOFT_CAST(long*)&(l)) +#define SAVESPTR(s) save_sptr((SV**)&(s)) +#define SAVEPPTR(s) save_pptr(SOFT_CAST(char**)&(s)) +#define SAVEFREESV(s) save_freesv((SV*)(s)) +#define SAVEFREEOP(o) save_freeop(SOFT_CAST(OP*)(o)) +#define SAVEFREEPV(p) save_freepv(SOFT_CAST(char*)(p)) +#define SAVECLEARSV(sv) save_clearsv(SOFT_CAST(SV**)&(sv)) +#define SAVEDELETE(h,k,l) \ + save_delete(SOFT_CAST(HV*)(h), SOFT_CAST(char*)(k), (I32)(l)) +#define SAVEDESTRUCTOR(f,p) \ + save_destructor(SOFT_CAST(void(*)_((void*)))(f),SOFT_CAST(void*)(p)) +#define SAVESTACK_POS() STMT_START { \ + SSCHECK(2); \ + SSPUSHINT(stack_sp - stack_base); \ + SSPUSHINT(SAVEt_STACK_POS); \ + } STMT_END + +/* A jmpenv packages the state required to perform a proper non-local jump. + * Note that there is a start_env initialized when perl starts, and top_env + * points to this initially, so top_env should always be non-null. + * + * Existence of a non-null top_env->je_prev implies it is valid to call + * longjmp() at that runlevel (we make sure start_env.je_prev is always + * null to ensure this). + * + * je_mustcatch, when set at any runlevel to TRUE, means eval ops must + * establish a local jmpenv to handle exception traps. Care must be taken + * to restore the previous value of je_mustcatch before exiting the + * stack frame iff JMPENV_PUSH was not called in that stack frame. + * GSAR 97-03-27 + */ + +struct jmpenv { + struct jmpenv * je_prev; + Sigjmp_buf je_buf; + int je_ret; /* return value of last setjmp() */ + bool je_mustcatch; /* longjmp()s must be caught locally */ +}; + +typedef struct jmpenv JMPENV; + +#define dJMPENV JMPENV cur_env +#define JMPENV_PUSH(v) \ + STMT_START { \ + cur_env.je_prev = top_env; \ + cur_env.je_ret = Sigsetjmp(cur_env.je_buf, 1); \ + top_env = &cur_env; \ + cur_env.je_mustcatch = FALSE; \ + (v) = cur_env.je_ret; \ + } STMT_END +#define JMPENV_POP \ + STMT_START { top_env = cur_env.je_prev; } STMT_END +#define JMPENV_JUMP(v) \ + STMT_START { \ + if (top_env->je_prev) \ + Siglongjmp(top_env->je_buf, (v)); \ + if ((v) == 2) \ + exit(STATUS_NATIVE_EXPORT); \ + PerlIO_printf(PerlIO_stderr(), "panic: top_env\n"); \ + exit(1); \ + } STMT_END + +#define CATCH_GET (top_env->je_mustcatch) +#define CATCH_SET(v) (top_env->je_mustcatch = (v)) + diff --git a/gnu/usr.bin/perl/sv.c b/gnu/usr.bin/perl/sv.c index a1f1d607157..d9596cb90f6 100644 --- a/gnu/usr.bin/perl/sv.c +++ b/gnu/usr.bin/perl/sv.c @@ -1,6 +1,6 @@ /* sv.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -36,16 +36,17 @@ #endif #endif -#if defined(USE_STDIO_PTR) && defined(STDIO_PTR_LVALUE) && defined(STDIO_CNT_LVALUE) +#if defined(USE_STDIO_PTR) && defined(STDIO_PTR_LVALUE) && defined(STDIO_CNT_LVALUE) && !defined(__QNX__) # define FAST_SV_GETS #endif +static IV asIV _((SV* sv)); +static UV asUV _((SV* sv)); static SV *more_sv _((void)); static XPVIV *more_xiv _((void)); static XPVNV *more_xnv _((void)); static XPV *more_xpv _((void)); static XRV *more_xrv _((void)); -static SV *new_sv _((void)); static XPVIV *new_xiv _((void)); static XPVNV *new_xnv _((void)); static XPV *new_xpv _((void)); @@ -55,13 +56,95 @@ static void del_xnv _((XPVNV* p)); static void del_xpv _((XPV* p)); static void del_xrv _((XRV* p)); static void sv_mortalgrow _((void)); - static void sv_unglob _((SV* sv)); +typedef void (*SVFUNC) _((SV*)); + #ifdef PURIFY -#define new_SV() sv = (SV*)safemalloc(sizeof(SV)) -#define del_SV(p) free((char*)p) +#define new_SV(p) \ + do { \ + (p) = (SV*)safemalloc(sizeof(SV)); \ + reg_add(p); \ + } while (0) + +#define del_SV(p) \ + do { \ + reg_remove(p); \ + free((char*)(p)); \ + } while (0) + +static SV **registry; +static I32 regsize; + +#define REGHASH(sv,size) ((((U32)(sv)) >> 2) % (size)) + +#define REG_REPLACE(sv,a,b) \ + do { \ + void* p = sv->sv_any; \ + I32 h = REGHASH(sv, regsize); \ + I32 i = h; \ + while (registry[i] != (a)) { \ + if (++i >= regsize) \ + i = 0; \ + if (i == h) \ + die("SV registry bug"); \ + } \ + registry[i] = (b); \ + } while (0) + +#define REG_ADD(sv) REG_REPLACE(sv,Nullsv,sv) +#define REG_REMOVE(sv) REG_REPLACE(sv,sv,Nullsv) + +static void +reg_add(sv) +SV* sv; +{ + if (sv_count >= (regsize >> 1)) + { + SV **oldreg = registry; + I32 oldsize = regsize; + + regsize = regsize ? ((regsize << 2) + 1) : 2037; + registry = (SV**)safemalloc(regsize * sizeof(SV*)); + memzero(registry, regsize * sizeof(SV*)); + + if (oldreg) { + I32 i; + + for (i = 0; i < oldsize; ++i) { + SV* oldsv = oldreg[i]; + if (oldsv) + REG_ADD(oldsv); + } + Safefree(oldreg); + } + } + + REG_ADD(sv); + ++sv_count; +} + +static void +reg_remove(sv) +SV* sv; +{ + REG_REMOVE(sv); + --sv_count; +} + +static void +visit(f) +SVFUNC f; +{ + I32 i; + + for (i = 0; i < regsize; ++i) { + SV* sv = registry[i]; + if (sv) + (*f)(sv); + } +} void sv_add_arena(ptr, size, flags) @@ -73,39 +156,40 @@ U32 flags; free(ptr); } -#else +#else /* ! PURIFY */ + +/* + * "A time to plant, and a time to uproot what was planted..." + */ + +#define plant_SV(p) \ + do { \ + SvANY(p) = (void *)sv_root; \ + SvFLAGS(p) = SVTYPEMASK; \ + sv_root = (p); \ + --sv_count; \ + } while (0) -#define new_SV() \ - if (sv_root) { \ - sv = sv_root; \ - sv_root = (SV*)SvANY(sv); \ +#define uproot_SV(p) \ + do { \ + (p) = sv_root; \ + sv_root = (SV*)SvANY(p); \ ++sv_count; \ - } \ - else \ - sv = more_sv(); + } while (0) -static SV* -new_sv() -{ - SV* sv; - if (sv_root) { - sv = sv_root; - sv_root = (SV*)SvANY(sv); - ++sv_count; - return sv; - } - return more_sv(); -} +#define new_SV(p) \ + if (sv_root) \ + uproot_SV(p); \ + else \ + (p) = more_sv() #ifdef DEBUGGING + #define del_SV(p) \ if (debug & 32768) \ del_sv(p); \ - else { \ - SvANY(p) = (void *)sv_root; \ - sv_root = p; \ - --sv_count; \ - } + else \ + plant_SV(p) static void del_sv(p) @@ -127,17 +211,14 @@ SV* p; return; } } - SvANY(p) = (void *) sv_root; - sv_root = p; - --sv_count; + plant_SV(p); } -#else -#define del_SV(p) \ - SvANY(p) = (void *)sv_root; \ - sv_root = p; \ - --sv_count; -#endif +#else /* ! DEBUGGING */ + +#define del_SV(p) plant_SV(p) + +#endif /* DEBUGGING */ void sv_add_arena(ptr, size, flags) @@ -172,101 +253,113 @@ U32 flags; static SV* more_sv() { + register SV* sv; + if (nice_chunk) { sv_add_arena(nice_chunk, nice_chunk_size, 0); nice_chunk = Nullch; } - else - sv_add_arena(safemalloc(1008), 1008, 0); - return new_sv(); + else { + char *chunk; /* must use New here to match call to */ + New(704,chunk,1008,char); /* Safefree() in sv_free_arenas() */ + sv_add_arena(chunk, 1008, 0); + } + uproot_SV(sv); + return sv; } -#endif -void -sv_report_used() +static void +visit(f) +SVFUNC f; { SV* sva; SV* sv; register SV* svend; - for (sva = sv_arenaroot; sva; sva = (SV *) SvANY(sva)) { - sv = sva + 1; + for (sva = sv_arenaroot; sva; sva = (SV*)SvANY(sva)) { svend = &sva[SvREFCNT(sva)]; - while (sv < svend) { - if (SvTYPE(sv) != SVTYPEMASK) { - fprintf(stderr, "****\n"); - sv_dump(sv); - } - ++sv; + for (sv = sva + 1; sv < svend; ++sv) { + if (SvTYPE(sv) != SVTYPEMASK) + (*f)(sv); } } } +#endif /* PURIFY */ + +static void +do_report_used(sv) +SV* sv; +{ + if (SvTYPE(sv) != SVTYPEMASK) { + /* XXX Perhaps this ought to go to Perl_debug_log, if DEBUGGING. */ + PerlIO_printf(PerlIO_stderr(), "****\n"); + sv_dump(sv); + } +} + void -sv_clean_objs() +sv_report_used() +{ + visit(do_report_used); +} + +static void +do_clean_objs(sv) +SV* sv; { - SV* sva; - register SV* sv; - register SV* svend; SV* rv; -#ifndef DISABLE_DESTRUCTOR_KLUDGE - register GV* gv; - for (sva = sv_arenaroot; sva; sva = (SV *) SvANY(sva)) { - gv = sva + 1; - svend = &sva[SvREFCNT(sva)]; - while (gv < svend) { - if (SvTYPE(gv) == SVt_PVGV && (sv = GvSV(gv)) && - SvROK(sv) && SvOBJECT(rv = SvRV(sv))) - { - DEBUG_D((fprintf(stderr, "Cleaning object ref:\n "), - sv_dump(sv));) - SvROK_off(sv); - SvRV(sv) = 0; - SvREFCNT_dec(rv); - } - ++gv; - } + if (SvROK(sv) && SvOBJECT(rv = SvRV(sv))) { + DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning object ref:\n "), sv_dump(sv));) + SvROK_off(sv); + SvRV(sv) = 0; + SvREFCNT_dec(rv); } - if (!sv_objcount) - return; + + /* XXX Might want to check arrays, etc. */ +} + +#ifndef DISABLE_DESTRUCTOR_KLUDGE +static void +do_clean_named_objs(sv) +SV* sv; +{ + if (SvTYPE(sv) == SVt_PVGV && GvSV(sv)) + do_clean_objs(GvSV(sv)); +} #endif - for (sva = sv_arenaroot; sva; sva = (SV *) SvANY(sva)) { - sv = sva + 1; - svend = &sva[SvREFCNT(sva)]; - while (sv < svend) { - if (SvROK(sv) && SvOBJECT(rv = SvRV(sv))) { - DEBUG_D((fprintf(stderr, "Cleaning object ref:\n "), - sv_dump(sv));) - SvROK_off(sv); - SvRV(sv) = 0; - SvREFCNT_dec(rv); - } - /* XXX Might want to check arrays, etc. */ - ++sv; - } - } + +static bool in_clean_objs = FALSE; + +void +sv_clean_objs() +{ + in_clean_objs = TRUE; +#ifndef DISABLE_DESTRUCTOR_KLUDGE + visit(do_clean_named_objs); +#endif + visit(do_clean_objs); + in_clean_objs = FALSE; +} + +static void +do_clean_all(sv) +SV* sv; +{ + DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning loops:\n "), sv_dump(sv));) + SvFLAGS(sv) |= SVf_BREAK; + SvREFCNT_dec(sv); } +static bool in_clean_all = FALSE; + void sv_clean_all() { - SV* sva; - register SV* sv; - register SV* svend; - - for (sva = sv_arenaroot; sva; sva = (SV*) SvANY(sva)) { - sv = sva + 1; - svend = &sva[SvREFCNT(sva)]; - while (sv < svend) { - if (SvTYPE(sv) != SVTYPEMASK) { - DEBUG_D((fprintf(stderr, "Cleaning loops:\n "), sv_dump(sv));) - SvFLAGS(sv) |= SVf_BREAK; - SvREFCNT_dec(sv); - } - ++sv; - } - } + in_clean_all = TRUE; + visit(do_clean_all); + in_clean_all = FALSE; } void @@ -284,8 +377,11 @@ sv_free_arenas() svanext = (SV*) SvANY(svanext); if (!SvFAKE(sva)) - Safefree(sva); + Safefree((void *)sva); } + + sv_arenaroot = 0; + sv_root = 0; } static XPVIV* @@ -575,7 +671,6 @@ U32 mt; stash = 0; break; case SVt_PV: - nv = 0.0; pv = SvPVX(sv); cur = SvCUR(sv); len = SvLEN(sv); @@ -590,7 +685,6 @@ U32 mt; mt = SVt_PVNV; break; case SVt_PVIV: - nv = 0.0; pv = SvPVX(sv); cur = SvCUR(sv); len = SvLEN(sv); @@ -601,7 +695,6 @@ U32 mt; del_XPVIV(SvANY(sv)); break; case SVt_PVNV: - nv = SvNVX(sv); pv = SvPVX(sv); cur = SvCUR(sv); len = SvLEN(sv); @@ -693,8 +786,8 @@ U32 mt; if (pv) Safefree(pv); SvPVX(sv) = 0; - AvMAX(sv) = 0; - AvFILL(sv) = 0; + AvMAX(sv) = -1; + AvFILL(sv) = -1; SvIVX(sv) = 0; SvNVX(sv) = 0.0; SvMAGIC(sv) = magic; @@ -792,28 +885,30 @@ char * sv_peek(sv) register SV *sv; { - char *t = tokenbuf; + SV *t = sv_newmortal(); + STRLEN prevlen; int unref = 0; + sv_setpvn(t, "", 0); retry: if (!sv) { - strcpy(t, "VOID"); + sv_catpv(t, "VOID"); goto finish; } else if (sv == (SV*)0x55555555 || SvTYPE(sv) == 'U') { - strcpy(t, "WILD"); + sv_catpv(t, "WILD"); goto finish; } else if (sv == &sv_undef || sv == &sv_no || sv == &sv_yes) { if (sv == &sv_undef) { - strcpy(t, "SV_UNDEF"); + sv_catpv(t, "SV_UNDEF"); if (!(SvFLAGS(sv) & (SVf_OK|SVf_OOK|SVs_OBJECT| SVs_GMG|SVs_SMG|SVs_RMG)) && SvREADONLY(sv)) goto finish; } else if (sv == &sv_no) { - strcpy(t, "SV_NO"); + sv_catpv(t, "SV_NO"); if (!(SvFLAGS(sv) & (SVf_ROK|SVf_OOK|SVs_OBJECT| SVs_GMG|SVs_SMG|SVs_RMG)) && !(~SvFLAGS(sv) & (SVf_POK|SVf_NOK|SVf_READONLY| @@ -823,7 +918,7 @@ register SV *sv; goto finish; } else { - strcpy(t, "SV_YES"); + sv_catpv(t, "SV_YES"); if (!(SvFLAGS(sv) & (SVf_ROK|SVf_OOK|SVs_OBJECT| SVs_GMG|SVs_SMG|SVs_RMG)) && !(~SvFLAGS(sv) & (SVf_POK|SVf_NOK|SVf_READONLY| @@ -833,17 +928,18 @@ register SV *sv; SvNVX(sv) == 1.0) goto finish; } - t += strlen(t); - *t++ = ':'; + sv_catpv(t, ":"); } else if (SvREFCNT(sv) == 0) { - *t++ = '('; + sv_catpv(t, "("); unref++; } if (SvROK(sv)) { - *t++ = '\\'; - if (t - tokenbuf + unref > 10) { - strcpy(tokenbuf + unref + 3,"..."); + sv_catpv(t, "\\"); + if (SvCUR(t) + unref > 10) { + SvCUR(t) = unref + 3; + *SvEND(t) = '\0'; + sv_catpv(t, "..."); goto finish; } sv = (SV*)SvRV(sv); @@ -851,86 +947,85 @@ register SV *sv; } switch (SvTYPE(sv)) { default: - strcpy(t,"FREED"); + sv_catpv(t, "FREED"); goto finish; case SVt_NULL: - strcpy(t,"UNDEF"); - return tokenbuf; + sv_catpv(t, "UNDEF"); + goto finish; case SVt_IV: - strcpy(t,"IV"); + sv_catpv(t, "IV"); break; case SVt_NV: - strcpy(t,"NV"); + sv_catpv(t, "NV"); break; case SVt_RV: - strcpy(t,"RV"); + sv_catpv(t, "RV"); break; case SVt_PV: - strcpy(t,"PV"); + sv_catpv(t, "PV"); break; case SVt_PVIV: - strcpy(t,"PVIV"); + sv_catpv(t, "PVIV"); break; case SVt_PVNV: - strcpy(t,"PVNV"); + sv_catpv(t, "PVNV"); break; case SVt_PVMG: - strcpy(t,"PVMG"); + sv_catpv(t, "PVMG"); break; case SVt_PVLV: - strcpy(t,"PVLV"); + sv_catpv(t, "PVLV"); break; case SVt_PVAV: - strcpy(t,"AV"); + sv_catpv(t, "AV"); break; case SVt_PVHV: - strcpy(t,"HV"); + sv_catpv(t, "HV"); break; case SVt_PVCV: if (CvGV(sv)) - sprintf(t, "CV(%s)", GvNAME(CvGV(sv))); + sv_catpvf(t, "CV(%s)", GvNAME(CvGV(sv))); else - strcpy(t, "CV()"); + sv_catpv(t, "CV()"); goto finish; case SVt_PVGV: - strcpy(t,"GV"); + sv_catpv(t, "GV"); break; case SVt_PVBM: - strcpy(t,"BM"); + sv_catpv(t, "BM"); break; case SVt_PVFM: - strcpy(t,"FM"); + sv_catpv(t, "FM"); break; case SVt_PVIO: - strcpy(t,"IO"); + sv_catpv(t, "IO"); break; } - t += strlen(t); if (SvPOKp(sv)) { if (!SvPVX(sv)) - strcpy(t, "(null)"); + sv_catpv(t, "(null)"); if (SvOOK(sv)) - sprintf(t,"(%ld+\"%.127s\")",(long)SvIVX(sv),SvPVX(sv)); + sv_catpvf(t, "(%ld+\"%.127s\")",(long)SvIVX(sv),SvPVX(sv)); else - sprintf(t,"(\"%.127s\")",SvPVX(sv)); + sv_catpvf(t, "(\"%.127s\")",SvPVX(sv)); + } + else if (SvNOKp(sv)) { + SET_NUMERIC_STANDARD(); + sv_catpvf(t, "(%g)",SvNVX(sv)); } - else if (SvNOKp(sv)) - sprintf(t,"(%g)",SvNVX(sv)); else if (SvIOKp(sv)) - sprintf(t,"(%ld)",(long)SvIVX(sv)); + sv_catpvf(t, "(%ld)",(long)SvIVX(sv)); else - strcpy(t,"()"); + sv_catpv(t, "()"); finish: if (unref) { - t += strlen(t); while (unref--) - *t++ = ')'; - *t = '\0'; + sv_catpv(t, ")"); } - return tokenbuf; + return SvPV(t, na); } #endif @@ -961,12 +1056,12 @@ unsigned long newlen; { register char *s; -#ifdef MSDOS +#ifdef HAS_64K_LIMIT if (newlen >= 0x10000) { - fprintf(stderr, "Allocation too large: %lx\n", newlen); + PerlIO_printf(Perl_debug_log, "Allocation too large: %lx\n", newlen); my_exit(1); } -#endif /* MSDOS */ +#endif /* HAS_64K_LIMIT */ if (SvROK(sv)) sv_unref(sv); if (SvTYPE(sv) < SVt_PV) { @@ -1027,7 +1122,7 @@ IV i; case SVt_PVFM: case SVt_PVIO: croak("Can't coerce %s to integer in %s", sv_reftype(sv,0), - op_name[op->op_type]); + op_desc[op->op_type]); } (void)SvIOK_only(sv); /* validate number */ SvIVX(sv) = i; @@ -1035,6 +1130,17 @@ IV i; } void +sv_setuv(sv,u) +register SV *sv; +UV u; +{ + if (u <= IV_MAX) + sv_setiv(sv, u); + else + sv_setnv(sv, (double)u); +} + +void sv_setnv(sv,num) register SV *sv; double num; @@ -1089,20 +1195,38 @@ SV *sv; char tmpbuf[64]; char *d = tmpbuf; char *s; - int i; + char *limit = tmpbuf + sizeof(tmpbuf) - 8; + /* each *s can expand to 4 chars + "...\0", + i.e. need room for 8 chars */ - for (s = SvPVX(sv), i = 50; *s && i; s++,i--) { - int ch = *s; - if (ch & 128 && !isprint(ch)) { + for (s = SvPVX(sv); *s && d < limit; s++) { + int ch = *s & 0xFF; + if (ch & 128 && !isPRINT_LC(ch)) { *d++ = 'M'; *d++ = '-'; ch &= 127; } - if (isprint(ch)) + if (ch == '\n') { + *d++ = '\\'; + *d++ = 'n'; + } + else if (ch == '\r') { + *d++ = '\\'; + *d++ = 'r'; + } + else if (ch == '\f') { + *d++ = '\\'; + *d++ = 'f'; + } + else if (ch == '\\') { + *d++ = '\\'; + *d++ = '\\'; + } + else if (isPRINT_LC(ch)) *d++ = ch; else { *d++ = '^'; - *d++ = ch ^ 64; + *d++ = toCTRL(ch); } } if (*s) { @@ -1135,14 +1259,13 @@ register SV *sv; else return (IV) U_V(SvNVX(sv)); } - if (SvPOKp(sv) && SvLEN(sv)) { - if (dowarn && !looks_like_number(sv)) - not_a_number(sv); - return (IV)atol(SvPVX(sv)); + if (SvPOKp(sv) && SvLEN(sv)) + return asIV(sv); + if (!SvROK(sv)) { + if (dowarn && !localizing && !(SvFLAGS(sv) & SVs_PADTMP)) + warn(warn_uninit); + return 0; } - if (!SvROK(sv)) { - return 0; - } } if (SvTHINKFIRST(sv)) { if (SvROK(sv)) { @@ -1160,11 +1283,8 @@ register SV *sv; else return (IV) U_V(SvNVX(sv)); } - if (SvPOKp(sv) && SvLEN(sv)) { - if (dowarn && !looks_like_number(sv)) - not_a_number(sv); - return (IV)atol(SvPVX(sv)); - } + if (SvPOKp(sv) && SvLEN(sv)) + return asIV(sv); if (dowarn) warn(warn_uninit); return 0; @@ -1173,7 +1293,7 @@ register SV *sv; switch (SvTYPE(sv)) { case SVt_NULL: sv_upgrade(sv, SVt_IV); - return SvIVX(sv); + break; case SVt_PV: sv_upgrade(sv, SVt_PVIV); break; @@ -1186,24 +1306,91 @@ register SV *sv; if (SvNVX(sv) < 0.0) SvIVX(sv) = I_V(SvNVX(sv)); else - SvIVX(sv) = (IV) U_V(SvNVX(sv)); + SvUVX(sv) = U_V(SvNVX(sv)); } else if (SvPOKp(sv) && SvLEN(sv)) { - if (dowarn && !looks_like_number(sv)) - not_a_number(sv); (void)SvIOK_on(sv); - SvIVX(sv) = (IV)atol(SvPVX(sv)); + SvIVX(sv) = asIV(sv); } else { if (dowarn && !localizing && !(SvFLAGS(sv) & SVs_PADTMP)) warn(warn_uninit); return 0; } - DEBUG_c(fprintf(stderr,"0x%lx 2iv(%ld)\n", + DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%lx 2iv(%ld)\n", (unsigned long)sv,(long)SvIVX(sv))); return SvIVX(sv); } +UV +sv_2uv(sv) +register SV *sv; +{ + if (!sv) + return 0; + if (SvGMAGICAL(sv)) { + mg_get(sv); + if (SvIOKp(sv)) + return SvUVX(sv); + if (SvNOKp(sv)) + return U_V(SvNVX(sv)); + if (SvPOKp(sv) && SvLEN(sv)) + return asUV(sv); + if (!SvROK(sv)) { + if (dowarn && !localizing && !(SvFLAGS(sv) & SVs_PADTMP)) + warn(warn_uninit); + return 0; + } + } + if (SvTHINKFIRST(sv)) { + if (SvROK(sv)) { +#ifdef OVERLOAD + SV* tmpstr; + if (SvAMAGIC(sv) && (tmpstr=AMG_CALLun(sv, numer))) + return SvUV(tmpstr); +#endif /* OVERLOAD */ + return (UV)SvRV(sv); + } + if (SvREADONLY(sv)) { + if (SvNOKp(sv)) { + return U_V(SvNVX(sv)); + } + if (SvPOKp(sv) && SvLEN(sv)) + return asUV(sv); + if (dowarn) + warn(warn_uninit); + return 0; + } + } + switch (SvTYPE(sv)) { + case SVt_NULL: + sv_upgrade(sv, SVt_IV); + break; + case SVt_PV: + sv_upgrade(sv, SVt_PVIV); + break; + case SVt_NV: + sv_upgrade(sv, SVt_PVNV); + break; + } + if (SvNOKp(sv)) { + (void)SvIOK_on(sv); + SvUVX(sv) = U_V(SvNVX(sv)); + } + else if (SvPOKp(sv) && SvLEN(sv)) { + (void)SvIOK_on(sv); + SvUVX(sv) = asUV(sv); + } + else { + if (dowarn && !localizing && !(SvFLAGS(sv) & SVs_PADTMP)) + warn(warn_uninit); + return 0; + } + DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%lx 2uv(%lu)\n", + (unsigned long)sv,SvUVX(sv))); + return SvUVX(sv); +} + double sv_2nv(sv) register SV *sv; @@ -1217,11 +1404,14 @@ register SV *sv; if (SvPOKp(sv) && SvLEN(sv)) { if (dowarn && !SvIOKp(sv) && !looks_like_number(sv)) not_a_number(sv); + SET_NUMERIC_STANDARD(); return atof(SvPVX(sv)); } if (SvIOKp(sv)) return (double)SvIVX(sv); if (!SvROK(sv)) { + if (dowarn && !localizing && !(SvFLAGS(sv) & SVs_PADTMP)) + warn(warn_uninit); return 0; } } @@ -1238,6 +1428,7 @@ register SV *sv; if (SvPOKp(sv) && SvLEN(sv)) { if (dowarn && !SvIOKp(sv) && !looks_like_number(sv)) not_a_number(sv); + SET_NUMERIC_STANDARD(); return atof(SvPVX(sv)); } if (SvIOKp(sv)) @@ -1252,7 +1443,9 @@ register SV *sv; sv_upgrade(sv, SVt_PVNV); else sv_upgrade(sv, SVt_NV); - DEBUG_c(fprintf(stderr,"0x%lx num(%g)\n",(unsigned long)sv,SvNVX(sv))); + DEBUG_c(SET_NUMERIC_STANDARD()); + DEBUG_c(PerlIO_printf(Perl_debug_log, + "0x%lx num(%g)\n",(unsigned long)sv,SvNVX(sv))); } else if (SvTYPE(sv) < SVt_PVNV) sv_upgrade(sv, SVt_PVNV); @@ -1264,6 +1457,7 @@ register SV *sv; else if (SvPOKp(sv) && SvLEN(sv)) { if (dowarn && !SvIOKp(sv) && !looks_like_number(sv)) not_a_number(sv); + SET_NUMERIC_STANDARD(); SvNVX(sv) = atof(SvPVX(sv)); } else { @@ -1272,10 +1466,127 @@ register SV *sv; return 0.0; } SvNOK_on(sv); - DEBUG_c(fprintf(stderr,"0x%lx 2nv(%g)\n",(unsigned long)sv,SvNVX(sv))); + DEBUG_c(SET_NUMERIC_STANDARD()); + DEBUG_c(PerlIO_printf(Perl_debug_log, + "0x%lx 2nv(%g)\n",(unsigned long)sv,SvNVX(sv))); return SvNVX(sv); } +static IV +asIV(sv) +SV *sv; +{ + I32 numtype = looks_like_number(sv); + double d; + + if (numtype == 1) + return atol(SvPVX(sv)); + if (!numtype && dowarn) + not_a_number(sv); + SET_NUMERIC_STANDARD(); + d = atof(SvPVX(sv)); + if (d < 0.0) + return I_V(d); + else + return (IV) U_V(d); +} + +static UV +asUV(sv) +SV *sv; +{ + I32 numtype = looks_like_number(sv); + +#ifdef HAS_STRTOUL + if (numtype == 1) + return strtoul(SvPVX(sv), Null(char**), 10); +#endif + if (!numtype && dowarn) + not_a_number(sv); + SET_NUMERIC_STANDARD(); + return U_V(atof(SvPVX(sv))); +} + +I32 +looks_like_number(sv) +SV *sv; +{ + register char *s; + register char *send; + register char *sbegin; + I32 numtype; + STRLEN len; + + if (SvPOK(sv)) { + sbegin = SvPVX(sv); + len = SvCUR(sv); + } + else if (SvPOKp(sv)) + sbegin = SvPV(sv, len); + else + return 1; + send = sbegin + len; + + s = sbegin; + while (isSPACE(*s)) + s++; + if (*s == '+' || *s == '-') + s++; + + /* next must be digit or '.' */ + if (isDIGIT(*s)) { + do { + s++; + } while (isDIGIT(*s)); + if (*s == '.') { + s++; + while (isDIGIT(*s)) /* optional digits after "." */ + s++; + } + } + else if (*s == '.') { + s++; + /* no digits before '.' means we need digits after it */ + if (isDIGIT(*s)) { + do { + s++; + } while (isDIGIT(*s)); + } + else + return 0; + } + else + return 0; + + /* + * we return 1 if the number can be converted to _integer_ with atol() + * and 2 if you need (int)atof(). + */ + numtype = 1; + + /* we can have an optional exponent part */ + if (*s == 'e' || *s == 'E') { + numtype = 2; + s++; + if (*s == '+' || *s == '-') + s++; + if (isDIGIT(*s)) { + do { + s++; + } while (isDIGIT(*s)); + } + else + return 0; + } + while (isSPACE(*s)) + s++; + if (s >= send) + return numtype; + if (len == 10 && memEQ(sbegin, "0 but true", 10)) + return 1; + return 0; +} + char * sv_2pv(sv, lp) register SV *sv; @@ -1283,6 +1594,7 @@ STRLEN *lp; { register char *s; int olderrno; + SV *tsv; if (!sv) { *lp = 0; @@ -1296,13 +1608,18 @@ STRLEN *lp; } if (SvIOKp(sv)) { (void)sprintf(tokenbuf,"%ld",(long)SvIVX(sv)); + tsv = Nullsv; goto tokensave; } if (SvNOKp(sv)) { + SET_NUMERIC_STANDARD(); Gconvert(SvNVX(sv), DBL_DIG, 0, tokenbuf); + tsv = Nullsv; goto tokensave; } if (!SvROK(sv)) { + if (dowarn && !localizing && !(SvFLAGS(sv) & SVs_PADTMP)) + warn(warn_uninit); *lp = 0; return ""; } @@ -1334,14 +1651,15 @@ STRLEN *lp; case SVt_PVCV: s = "CODE"; break; case SVt_PVGV: s = "GLOB"; break; case SVt_PVFM: s = "FORMATLINE"; break; - case SVt_PVIO: s = "FILEHANDLE"; break; + case SVt_PVIO: s = "IO"; break; default: s = "UNKNOWN"; break; } + tsv = NEWSV(0,0); if (SvOBJECT(sv)) - sprintf(tokenbuf, "%s=%s(0x%lx)", - HvNAME(SvSTASH(sv)), s, (unsigned long)sv); + sv_setpvf(tsv, "%s=%s", HvNAME(SvSTASH(sv)), s); else - sprintf(tokenbuf, "%s(0x%lx)", s, (unsigned long)sv); + sv_setpv(tsv, s); + sv_catpvf(tsv, "(0x%lx)", (unsigned long)sv); goto tokensaveref; } *lp = strlen(s); @@ -1349,11 +1667,14 @@ STRLEN *lp; } if (SvREADONLY(sv)) { if (SvNOKp(sv)) { + SET_NUMERIC_STANDARD(); Gconvert(SvNVX(sv), DBL_DIG, 0, tokenbuf); + tsv = Nullsv; goto tokensave; } if (SvIOKp(sv)) { (void)sprintf(tokenbuf,"%ld",(long)SvIVX(sv)); + tsv = Nullsv; goto tokensave; } if (dowarn) @@ -1375,7 +1696,10 @@ STRLEN *lp; (void)strcpy(s,"0"); else #endif /*apollo*/ + { + SET_NUMERIC_STANDARD(); Gconvert(SvNVX(sv), DBL_DIG, 0, s); + } errno = olderrno; #ifdef FIXNEGATIVEZERO if (*s == '-' && s[1] == '0' && !s[2]) @@ -1384,18 +1708,21 @@ STRLEN *lp; while (*s) s++; #ifdef hcx if (s[-1] == '.') - s--; + *--s = '\0'; #endif } else if (SvIOKp(sv)) { + U32 oldIOK = SvIOK(sv); if (SvTYPE(sv) < SVt_PVIV) sv_upgrade(sv, SVt_PVIV); - SvGROW(sv, 11); - s = SvPVX(sv); olderrno = errno; /* some Xenix systems wipe out errno here */ - (void)sprintf(s,"%ld",(long)SvIVX(sv)); + sv_setpviv(sv, SvIVX(sv)); errno = olderrno; - while (*s) s++; + s = SvEND(sv); + if (oldIOK) + SvIOK_on(sv); + else + SvIOKp_on(sv); } else { if (dowarn && !localizing && !(SvFLAGS(sv) & SVs_PADTMP)) @@ -1403,11 +1730,10 @@ STRLEN *lp; *lp = 0; return ""; } - *s = '\0'; *lp = s - SvPVX(sv); SvCUR_set(sv, *lp); SvPOK_on(sv); - DEBUG_c(fprintf(stderr,"0x%lx 2pv(%s)\n",(unsigned long)sv,SvPVX(sv))); + DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%lx 2pv(%s)\n",(unsigned long)sv,SvPVX(sv))); return SvPVX(sv); tokensave: @@ -1415,24 +1741,37 @@ STRLEN *lp; /* Sneaky stuff here */ tokensaveref: - sv = sv_newmortal(); - *lp = strlen(tokenbuf); - sv_setpvn(sv, tokenbuf, *lp); - return SvPVX(sv); + if (!tsv) + tsv = newSVpv(tokenbuf, 0); + sv_2mortal(tsv); + *lp = SvCUR(tsv); + return SvPVX(tsv); } else { STRLEN len; - + char *t; + + if (tsv) { + sv_2mortal(tsv); + t = SvPVX(tsv); + len = SvCUR(tsv); + } + else { + t = tokenbuf; + len = strlen(tokenbuf); + } #ifdef FIXNEGATIVEZERO - if (*tokenbuf == '-' && tokenbuf[1] == '0' && !tokenbuf[2]) - strcpy(tokenbuf,"0"); + if (len == 2 && t[0] == '-' && t[1] == '0') { + t = "0"; + len = 1; + } #endif (void)SvUPGRADE(sv, SVt_PV); - len = *lp = strlen(tokenbuf); + *lp = len; s = SvGROW(sv, len + 1); SvCUR_set(sv, len); - (void)strcpy(s, tokenbuf); - /* NO SvPOK_on(sv) here! */ + (void)strcpy(s, t); + SvPOKp_on(sv); return s; } } @@ -1523,22 +1862,20 @@ register SV *sstr; (void)SvOK_off(dstr); return; case SVt_IV: - if (dtype <= SVt_PV) { + if (dtype != SVt_IV && dtype < SVt_PVIV) { if (dtype < SVt_IV) sv_upgrade(dstr, SVt_IV); else if (dtype == SVt_NV) sv_upgrade(dstr, SVt_PVNV); - else if (dtype <= SVt_PV) + else sv_upgrade(dstr, SVt_PVIV); } break; case SVt_NV: - if (dtype <= SVt_PVIV) { + if (dtype != SVt_NV && dtype < SVt_PVNV) { if (dtype < SVt_NV) sv_upgrade(dstr, SVt_NV); - else if (dtype == SVt_PVIV) - sv_upgrade(dstr, SVt_PVNV); - else if (dtype <= SVt_PV) + else sv_upgrade(dstr, SVt_PVNV); } break; @@ -1558,6 +1895,7 @@ register SV *sstr; } break; case SVt_PV: + case SVt_PVFM: if (dtype < SVt_PV) sv_upgrade(dstr, SVt_PV); break; @@ -1571,7 +1909,7 @@ register SV *sstr; break; case SVt_PVLV: - sv_upgrade(dstr, SVt_PVNV); + sv_upgrade(dstr, SVt_PVLV); break; case SVt_PVAV: @@ -1598,9 +1936,14 @@ register SV *sstr; GvNAMELEN(dstr) = len; SvFAKE_on(dstr); /* can coerce to non-glob */ } + /* ahem, death to those who redefine active sort subs */ + else if (curstack == sortstack + && GvCV(dstr) && sortcop == CvSTART(GvCV(dstr))) + croak("Can't redefine active sort subroutine %s", + GvNAME(dstr)); (void)SvOK_off(dstr); GvINTRO_off(dstr); /* one-shot flag */ - gp_free(dstr); + gp_free((GV*)dstr); GvGP(dstr) = gp_ref(GvGP(sstr)); SvTAINT(dstr); if (curcop->cop_stash != GvSTASH(dstr)) @@ -1611,10 +1954,16 @@ register SV *sstr; /* FALL THROUGH */ default: + if (SvGMAGICAL(sstr)) { + mg_get(sstr); + if (SvTYPE(sstr) != stype) { + stype = SvTYPE(sstr); + if (stype == SVt_PVGV && dtype <= SVt_PVGV) + goto glob_assign; + } + } if (dtype < stype) sv_upgrade(dstr, stype); - if (SvGMAGICAL(sstr)) - mg_get(sstr); } sflags = SvFLAGS(sstr); @@ -1631,11 +1980,10 @@ register SV *sstr; GvGP(dstr)->gp_refcnt--; GvINTRO_off(dstr); /* one-shot flag */ Newz(602,gp, 1, GP); - GvGP(dstr) = gp; - GvREFCNT(dstr) = 1; + GvGP(dstr) = gp_ref(gp); GvSV(dstr) = NEWSV(72,0); GvLINE(dstr) = curcop->cop_line; - GvEGV(dstr) = dstr; + GvEGV(dstr) = (GV*)dstr; } GvMULTI_on(dstr); switch (SvTYPE(sref)) { @@ -1658,23 +2006,44 @@ register SV *sstr; GvIMPORTED_HV_on(dstr); break; case SVt_PVCV: - if (intro) + if (intro) { + if (GvCVGEN(dstr) && GvCV(dstr) != (CV*)sref) { + SvREFCNT_dec(GvCV(dstr)); + GvCV(dstr) = Nullcv; + GvCVGEN(dstr) = 0; /* Switch off cacheness. */ + sub_generation++; + } SAVESPTR(GvCV(dstr)); - else { + } + else + dref = (SV*)GvCV(dstr); + if (GvCV(dstr) != (CV*)sref) { CV* cv = GvCV(dstr); if (cv) { - dref = (SV*)cv; - if (dowarn && sref != dref && - !GvCVGEN((GV*)dstr) && - (CvROOT(cv) || CvXSUB(cv)) ) - warn("Subroutine %s redefined", - GvENAME((GV*)dstr)); - SvFAKE_on(cv); + if (!GvCVGEN((GV*)dstr) && + (CvROOT(cv) || CvXSUB(cv))) + { + /* ahem, death to those who redefine + * active sort subs */ + if (curstack == sortstack && + sortcop == CvSTART(cv)) + croak( + "Can't redefine active sort subroutine %s", + GvENAME((GV*)dstr)); + if (cv_const_sv(cv)) + warn("Constant subroutine %s redefined", + GvENAME((GV*)dstr)); + else if (dowarn) + warn("Subroutine %s redefined", + GvENAME((GV*)dstr)); + } + cv_ckproto(cv, (GV*)dstr, + SvPOK(sref) ? SvPVX(sref) : Nullch); } - } - if (GvCV(dstr) != (CV*)sref) { GvCV(dstr) = (CV*)sref; + GvCVGEN(dstr) = 0; /* Switch off cacheness. */ GvASSUMECV_on(dstr); + sub_generation++; } if (curcop->cop_stash != GvSTASH(dstr)) GvIMPORTED_CV_on(dstr); @@ -1704,6 +2073,7 @@ register SV *sstr; return; } if (SvPVX(dstr)) { + (void)SvOOK_off(dstr); /* backoff */ Safefree(SvPVX(dstr)); SvLEN(dstr)=SvCUR(dstr)=0; } @@ -1796,10 +2166,11 @@ register SV *sstr; void sv_setpvn(sv,ptr,len) register SV *sv; -register char *ptr; +register const char *ptr; register STRLEN len; { - assert(len >= 0); + assert(len >= 0); /* STRLEN is probably unsigned, so this may + elicit a warning, but it won't hurt. */ if (SvTHINKFIRST(sv)) { if (SvREADONLY(sv) && curcop != &compiling) croak(no_modify); @@ -1827,7 +2198,7 @@ register STRLEN len; void sv_setpv(sv,ptr) register SV *sv; -register char *ptr; +register const char *ptr; { register STRLEN len; @@ -1980,7 +2351,7 @@ STRLEN len; { register SV *sv; - new_SV(); + new_SV(sv); SvANY(sv) = 0; SvREFCNT(sv) = 1; SvFLAGS(sv) = 0; @@ -1991,6 +2362,8 @@ STRLEN len; return sv; } +/* name is assumed to contain an SV* if (name && namelen == HEf_SVKEY) */ + void sv_magic(sv, obj, how, name, namlen) register SV *sv; @@ -2001,7 +2374,7 @@ I32 namlen; { MAGIC* mg; - if (SvREADONLY(sv) && curcop != &compiling && !strchr("gB", how)) + if (SvREADONLY(sv) && curcop != &compiling && !strchr("gBf", how)) croak(no_modify); if (SvMAGICAL(sv) || (how == 't' && SvTYPE(sv) >= SVt_PVMG)) { if (SvMAGIC(sv) && (mg = mg_find(sv, how))) { @@ -2026,8 +2399,12 @@ I32 namlen; } mg->mg_type = how; mg->mg_len = namlen; - if (name && namlen >= 0) - mg->mg_ptr = savepvn(name, namlen); + if (name) + if (namlen >= 0) + mg->mg_ptr = savepvn(name, namlen); + else if (namlen == HEf_SVKEY) + mg->mg_ptr = (char*)SvREFCNT_inc((SV*)name); + switch (how) { case 0: mg->mg_virtual = &vtbl_sv; @@ -2049,6 +2426,9 @@ I32 namlen; case 'E': mg->mg_virtual = &vtbl_env; break; + case 'f': + mg->mg_virtual = &vtbl_fm; + break; case 'e': mg->mg_virtual = &vtbl_envelem; break; @@ -2061,6 +2441,9 @@ I32 namlen; case 'i': mg->mg_virtual = &vtbl_isaelem; break; + case 'k': + mg->mg_virtual = &vtbl_nkeys; + break; case 'L': SvRMAGICAL_on(sv); mg->mg_virtual = 0; @@ -2068,6 +2451,11 @@ I32 namlen; case 'l': mg->mg_virtual = &vtbl_dbline; break; +#ifdef USE_LOCALE_COLLATE + case 'o': + mg->mg_virtual = &vtbl_collxfrm; + break; +#endif /* USE_LOCALE_COLLATE */ case 'P': mg->mg_virtual = &vtbl_pack; break; @@ -2094,6 +2482,9 @@ I32 namlen; case 'x': mg->mg_virtual = &vtbl_substr; break; + case 'y': + mg->mg_virtual = &vtbl_defelem; + break; case '*': mg->mg_virtual = &vtbl_glob; break; @@ -2134,7 +2525,10 @@ int type; if (vtbl && vtbl->svt_free) (*vtbl->svt_free)(sv, mg); if (mg->mg_ptr && mg->mg_type != 'g') - Safefree(mg->mg_ptr); + if (mg->mg_len >= 0) + Safefree(mg->mg_ptr); + else if (mg->mg_len == HEf_SVKEY) + SvREFCNT_dec((SV*)mg->mg_ptr); if (mg->mg_flags & MGf_REFCOUNTED) SvREFCNT_dec(mg->mg_obj); Safefree(mg); @@ -2259,8 +2653,10 @@ register SV *nsv; } SvREFCNT(sv) = 0; sv_clear(sv); + assert(!SvREFCNT(sv)); StructCopy(nsv,sv,SV); SvREFCNT(sv) = refcnt; + SvFLAGS(nsv) |= SVTYPEMASK; /* Mark as freed */ del_SV(nsv); } @@ -2272,30 +2668,35 @@ register SV *sv; assert(SvREFCNT(sv) == 0); if (SvOBJECT(sv)) { - dSP; - GV* destructor; - if (defstash) { /* Still have a symbol table? */ - destructor = gv_fetchmethod(SvSTASH(sv), "DESTROY"); + dSP; + GV* destructor; ENTER; SAVEFREESV(SvSTASH(sv)); - if (destructor && GvCV(destructor)) { + + destructor = gv_fetchmethod(SvSTASH(sv), "DESTROY"); + if (destructor) { SV ref; Zero(&ref, 1, SV); sv_upgrade(&ref, SVt_RV); - SAVEI32(SvREFCNT(sv)); SvRV(&ref) = SvREFCNT_inc(sv); SvROK_on(&ref); + SvREFCNT(&ref) = 1; /* Fake, but otherwise + creating+destructing a ref + leads to disaster. */ EXTEND(SP, 2); PUSHMARK(SP); PUSHs(&ref); PUTBACK; - perl_call_sv((SV*)destructor, G_DISCARD|G_EVAL|G_KEEPERR); + perl_call_sv((SV*)GvCV(destructor), + G_DISCARD|G_EVAL|G_KEEPERR); del_XRV(SvANY(&ref)); + SvREFCNT(sv)--; } + LEAVE; } else @@ -2305,12 +2706,21 @@ register SV *sv; if (SvTYPE(sv) != SVt_PVIO) --sv_objcount; /* XXX Might want something more general */ } + if (SvREFCNT(sv)) { + if (in_clean_objs) + croak("DESTROY created new reference to dead object"); + /* DESTROY gave object new lease on life */ + return; + } } if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) mg_free(sv); switch (SvTYPE(sv)) { case SVt_PVIO: - io_close((IO*)sv); + if (IoIFP(sv) != PerlIO_stdin() && + IoIFP(sv) != PerlIO_stdout() && + IoIFP(sv) != PerlIO_stderr()) + io_close((IO*)sv); Safefree(IoTOP_NAME(sv)); Safefree(IoFMT_NAME(sv)); Safefree(IoBOTTOM_NAME(sv)); @@ -2328,7 +2738,7 @@ register SV *sv; av_undef((AV*)sv); break; case SVt_PVGV: - gp_free(sv); + gp_free((GV*)sv); Safefree(GvNAME(sv)); /* FALL THROUGH */ case SVt_PVLV: @@ -2342,7 +2752,7 @@ register SV *sv; case SVt_RV: if (SvROK(sv)) SvREFCNT_dec(SvRV(sv)); - else if (SvPVX(sv)) + else if (SvPVX(sv) && SvLEN(sv)) Safefree(SvPVX(sv)); break; /* @@ -2428,6 +2838,8 @@ SV *sv; if (SvREFCNT(sv) == 0) { if (SvFLAGS(sv) & SVf_BREAK) return; + if (in_clean_all) /* All is fair */ + return; warn("Attempt to free unreferenced scalar"); return; } @@ -2440,7 +2852,8 @@ SV *sv; } #endif sv_clear(sv); - del_SV(sv); + if (! SvREFCNT(sv)) + del_SV(sv); } STRLEN @@ -2485,59 +2898,146 @@ register SV *str2; if (cur1 != cur2) return 0; - return !bcmp(pv1, pv2, cur1); + return memEQ(pv1, pv2, cur1); } I32 -sv_cmp(str1,str2) +sv_cmp(str1, str2) register SV *str1; register SV *str2; { + STRLEN cur1 = 0; + char *pv1 = str1 ? SvPV(str1, cur1) : NULL; + STRLEN cur2 = 0; + char *pv2 = str2 ? SvPV(str2, cur2) : NULL; I32 retval; - char *pv1; - STRLEN cur1; - char *pv2; - STRLEN cur2; - - if (!str1) { - pv1 = ""; - cur1 = 0; - } - else - pv1 = SvPV(str1, cur1); - - if (!str2) { - pv2 = ""; - cur2 = 0; - } - else - pv2 = SvPV(str2, cur2); if (!cur1) return cur2 ? -1 : 0; + if (!cur2) return 1; - if (cur1 < cur2) { - /*SUPPRESS 560*/ - if (retval = memcmp((void*)pv1, (void*)pv2, cur1)) - return retval < 0 ? -1 : 1; - else - return -1; - } - /*SUPPRESS 560*/ - else if (retval = memcmp((void*)pv1, (void*)pv2, cur2)) + retval = memcmp((void*)pv1, (void*)pv2, cur1 < cur2 ? cur1 : cur2); + + if (retval) return retval < 0 ? -1 : 1; - else if (cur1 == cur2) + + if (cur1 == cur2) return 0; else - return 1; + return cur1 < cur2 ? -1 : 1; +} + +I32 +sv_cmp_locale(sv1, sv2) +register SV *sv1; +register SV *sv2; +{ +#ifdef USE_LOCALE_COLLATE + + char *pv1, *pv2; + STRLEN len1, len2; + I32 retval; + + if (collation_standard) + goto raw_compare; + + len1 = 0; + pv1 = sv1 ? sv_collxfrm(sv1, &len1) : NULL; + len2 = 0; + pv2 = sv2 ? sv_collxfrm(sv2, &len2) : NULL; + + if (!pv1 || !len1) { + if (pv2 && len2) + return -1; + else + goto raw_compare; + } + else { + if (!pv2 || !len2) + return 1; + } + + retval = memcmp((void*)pv1, (void*)pv2, len1 < len2 ? len1 : len2); + + if (retval) + return retval < 0 ? -1 : 1; + + /* + * When the result of collation is equality, that doesn't mean + * that there are no differences -- some locales exclude some + * characters from consideration. So to avoid false equalities, + * we use the raw string as a tiebreaker. + */ + + raw_compare: + /* FALL THROUGH */ + +#endif /* USE_LOCALE_COLLATE */ + + return sv_cmp(sv1, sv2); +} + +#ifdef USE_LOCALE_COLLATE +/* + * Any scalar variable may carry an 'o' magic that contains the + * scalar data of the variable transformed to such a format that + * a normal memory comparison can be used to compare the data + * according to the locale settings. + */ +char * +sv_collxfrm(sv, nxp) + SV *sv; + STRLEN *nxp; +{ + MAGIC *mg; + + mg = SvMAGICAL(sv) ? mg_find(sv, 'o') : NULL; + if (!mg || !mg->mg_ptr || *(U32*)mg->mg_ptr != collation_ix) { + char *s, *xf; + STRLEN len, xlen; + + if (mg) + Safefree(mg->mg_ptr); + s = SvPV(sv, len); + if ((xf = mem_collxfrm(s, len, &xlen))) { + if (SvREADONLY(sv)) { + SAVEFREEPV(xf); + *nxp = xlen; + return xf + sizeof(collation_ix); + } + if (! mg) { + sv_magic(sv, 0, 'o', 0, 0); + mg = mg_find(sv, 'o'); + assert(mg); + } + mg->mg_ptr = xf; + mg->mg_len = xlen; + } + else { + if (mg) { + mg->mg_ptr = NULL; + mg->mg_len = -1; + } + } + } + if (mg && mg->mg_ptr) { + *nxp = mg->mg_len; + return mg->mg_ptr + sizeof(collation_ix); + } + else { + *nxp = 0; + return NULL; + } } +#endif /* USE_LOCALE_COLLATE */ + char * sv_gets(sv,fp,append) register SV *sv; -register FILE *fp; +register PerlIO *fp; I32 append; { char *rsptr; @@ -2547,16 +3047,6 @@ I32 append; register I32 cnt; I32 i; -#ifdef FAST_SV_GETS - /* - * We're going to steal some values from the stdio struct - * and put EVERYTHING in the innermost loop into registers. - */ - register STDCHAR *ptr; - STRLEN bpx; - I32 shortbuffered; -#endif - if (SvTHINKFIRST(sv)) { if (SvREADONLY(sv) && curcop != &compiling) croak(no_modify); @@ -2565,6 +3055,7 @@ I32 append; } if (!SvUPGRADE(sv, SVt_PV)) return 0; + SvSCREAM_off(sv); if (RsSNARF(rs)) { rsptr = NULL; @@ -2580,23 +3071,49 @@ I32 append; if (RsPARA(rs)) { /* have to do this both before and after */ do { /* to make sure file boundaries work right */ - if (feof(fp)) + if (PerlIO_eof(fp)) return 0; - i = getc(fp); + i = PerlIO_getc(fp); if (i != '\n') { if (i == -1) return 0; - ungetc(i,fp); + PerlIO_ungetc(fp,i); break; } } while (i != EOF); } -#ifdef FAST_SV_GETS + /* See if we know enough about I/O mechanism to cheat it ! */ + + /* This used to be #ifdef test - it is made run-time test for ease + of abstracting out stdio interface. One call should be cheap + enough here - and may even be a macro allowing compile + time optimization. + */ + + if (PerlIO_fast_gets(fp)) { + + /* + * We're going to steal some values from the stdio struct + * and put EVERYTHING in the innermost loop into registers. + */ + register STDCHAR *ptr; + STRLEN bpx; + I32 shortbuffered; + +#if defined(VMS) && defined(PERLIO_IS_STDIO) + /* An ungetc()d char is handled separately from the regular + * buffer, so we getc() it back out and stuff it in the buffer. + */ + i = PerlIO_getc(fp); + if (i == EOF) return 0; + *(--((*fp)->_ptr)) = (unsigned char) i; + (*fp)->_cnt++; +#endif /* Here is some breathtakingly efficient cheating */ - cnt = FILE_cnt(fp); /* get count into register */ + cnt = PerlIO_get_cnt(fp); /* get count into register */ (void)SvPOK_only(sv); /* validate pointer */ if (SvLEN(sv) - append <= cnt + 1) { /* make sure we have the room */ if (cnt > 80 && SvLEN(sv) > append) { @@ -2605,24 +3122,32 @@ I32 append; } else { shortbuffered = 0; - SvGROW(sv, append+cnt+2);/* (remembering cnt can be -1) */ + /* remember that cnt can be negative */ + SvGROW(sv, append + (cnt <= 0 ? 2 : (cnt + 1))); } } else shortbuffered = 0; bp = (STDCHAR*)SvPVX(sv) + append; /* move these two too to registers */ - ptr = FILE_ptr(fp); + ptr = (STDCHAR*)PerlIO_get_ptr(fp); + DEBUG_P(PerlIO_printf(Perl_debug_log, + "Screamer: entering, ptr=%ld, cnt=%ld\n",(long)ptr,(long)cnt)); + DEBUG_P(PerlIO_printf(Perl_debug_log, + "Screamer: entering: FILE * thinks ptr=%ld, cnt=%ld, base=%ld\n", + (long)PerlIO_get_ptr(fp), (long)PerlIO_get_cnt(fp), + (long)(PerlIO_has_base(fp) ? PerlIO_get_base(fp) : 0))); for (;;) { screamer: if (cnt > 0) { if (rslen) { - while (--cnt >= 0) { /* this | eat */ + while (cnt > 0) { /* this | eat */ + cnt--; if ((*bp++ = *ptr++) == rslast) /* really | dust */ goto thats_all_folks; /* screams | sed :-) */ } } else { - memcpy((char*)bp, (char*)ptr, cnt); /* this | eat */ + Copy(ptr, bp, cnt, char); /* this | eat */ bp += cnt; /* screams | dust */ ptr += cnt; /* louder | sed :-) */ cnt = 0; @@ -2639,11 +3164,25 @@ I32 append; continue; } - FILE_cnt(fp) = cnt; /* deregisterize cnt and ptr */ - FILE_ptr(fp) = ptr; - i = _filbuf(fp); /* get more characters */ - cnt = FILE_cnt(fp); - ptr = FILE_ptr(fp); /* reregisterize cnt and ptr */ + DEBUG_P(PerlIO_printf(Perl_debug_log, + "Screamer: going to getc, ptr=%ld, cnt=%ld\n",(long)ptr,(long)cnt)); + PerlIO_set_ptrcnt(fp, ptr, cnt); /* deregisterize cnt and ptr */ + DEBUG_P(PerlIO_printf(Perl_debug_log, + "Screamer: pre: FILE * thinks ptr=%ld, cnt=%ld, base=%ld\n", + (long)PerlIO_get_ptr(fp), (long)PerlIO_get_cnt(fp), + (long)(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0))); + /* This used to call 'filbuf' in stdio form, but as that behaves like + getc when cnt <= 0 we use PerlIO_getc here to avoid introducing + another abstraction. */ + i = PerlIO_getc(fp); /* get more characters */ + DEBUG_P(PerlIO_printf(Perl_debug_log, + "Screamer: post: FILE * thinks ptr=%ld, cnt=%ld, base=%ld\n", + (long)PerlIO_get_ptr(fp), (long)PerlIO_get_cnt(fp), + (long)(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0))); + cnt = PerlIO_get_cnt(fp); + ptr = (STDCHAR*)PerlIO_get_ptr(fp); /* reregisterize cnt and ptr */ + DEBUG_P(PerlIO_printf(Perl_debug_log, + "Screamer: after getc, ptr=%ld, cnt=%ld\n",(long)ptr,(long)cnt)); if (i == EOF) /* all done for ever? */ goto thats_really_all_folks; @@ -2653,7 +3192,7 @@ I32 append; SvGROW(sv, bpx + cnt + 2); bp = (STDCHAR*)SvPVX(sv) + bpx; /* unbox after relocation */ - *bp++ = i; /* store character from _filbuf */ + *bp++ = i; /* store character from PerlIO_getc */ if (rslen && (STDCHAR)i == rslast) /* all done for now? */ goto thats_all_folks; @@ -2661,58 +3200,77 @@ I32 append; thats_all_folks: if ((rslen > 1 && (bp - (STDCHAR*)SvPVX(sv) < rslen)) || - bcmp((char*)bp - rslen, rsptr, rslen)) - goto screamer; /* go back to the fray */ + memNE((char*)bp - rslen, rsptr, rslen)) + goto screamer; /* go back to the fray */ thats_really_all_folks: if (shortbuffered) cnt += shortbuffered; - FILE_cnt(fp) = cnt; /* put these back or we're in trouble */ - FILE_ptr(fp) = ptr; + DEBUG_P(PerlIO_printf(Perl_debug_log, + "Screamer: quitting, ptr=%ld, cnt=%ld\n",(long)ptr,(long)cnt)); + PerlIO_set_ptrcnt(fp, ptr, cnt); /* put these back or we're in trouble */ + DEBUG_P(PerlIO_printf(Perl_debug_log, + "Screamer: end: FILE * thinks ptr=%ld, cnt=%ld, base=%ld\n", + (long)PerlIO_get_ptr(fp), (long)PerlIO_get_cnt(fp), + (long)(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0))); *bp = '\0'; - SvCUR_set(sv, bp - (STDCHAR*)SvPVX(sv)); /* set length */ - -#else /* SV_FAST_GETS */ - - /*The big, slow, and stupid way */ - + SvCUR_set(sv, bp - (STDCHAR*)SvPVX(sv)); /* set length */ + DEBUG_P(PerlIO_printf(Perl_debug_log, + "Screamer: done, len=%ld, string=|%.*s|\n", + (long)SvCUR(sv),(int)SvCUR(sv),SvPVX(sv))); + } + else { + /*The big, slow, and stupid way */ STDCHAR buf[8192]; -screamer: +screamer2: if (rslen) { register STDCHAR *bpe = buf + sizeof(buf); bp = buf; - while ((i = getc(fp)) != EOF && (*bp++ = i) != rslast && bp < bpe) + while ((i = PerlIO_getc(fp)) != EOF && (*bp++ = i) != rslast && bp < bpe) ; /* keep reading */ cnt = bp - buf; } else { - cnt = fread((char*)buf, 1, sizeof(buf), fp); - i = cnt ? (U8)buf[cnt - 1] : EOF; + cnt = PerlIO_read(fp,(char*)buf, sizeof(buf)); + /* Accomodate broken VAXC compiler, which applies U8 cast to + * both args of ?: operator, causing EOF to change into 255 + */ + if (cnt) { i = (U8)buf[cnt - 1]; } else { i = EOF; } } if (append) - sv_catpvn(sv, buf, cnt); + sv_catpvn(sv, (char *) buf, cnt); else - sv_setpvn(sv, buf, cnt); + sv_setpvn(sv, (char *) buf, cnt); if (i != EOF && /* joy */ (!rslen || SvCUR(sv) < rslen || - bcmp(SvPVX(sv) + SvCUR(sv) - rslen, rsptr, rslen))) + memNE(SvPVX(sv) + SvCUR(sv) - rslen, rsptr, rslen))) { append = -1; - goto screamer; + /* + * If we're reading from a TTY and we get a short read, + * indicating that the user hit his EOF character, we need + * to notice it now, because if we try to read from the TTY + * again, the EOF condition will disappear. + * + * The comparison of cnt to sizeof(buf) is an optimization + * that prevents unnecessary calls to feof(). + * + * - jik 9/25/96 + */ + if (!(cnt < sizeof(buf) && PerlIO_eof(fp))) + goto screamer2; } } -#endif /* SV_FAST_GETS */ - if (RsPARA(rs)) { /* have to do this both before and after */ while (i != EOF) { /* to make sure file boundaries work right */ - i = getc(fp); + i = PerlIO_getc(fp); if (i != '\n') { - ungetc(i,fp); + PerlIO_ungetc(fp,i); break; } } @@ -2721,6 +3279,7 @@ screamer: return (SvCUR(sv) - append) ? SvPVX(sv) : Nullch; } + void sv_inc(sv) register SV *sv; @@ -2743,14 +3302,18 @@ register SV *sv; if (SvGMAGICAL(sv)) mg_get(sv); flags = SvFLAGS(sv); - if (flags & SVp_IOK) { - (void)SvIOK_only(sv); - ++SvIVX(sv); - return; - } if (flags & SVp_NOK) { - SvNVX(sv) += 1.0; (void)SvNOK_only(sv); + SvNVX(sv) += 1.0; + return; + } + if (flags & SVp_IOK) { + if (SvIVX(sv) == IV_MAX) + sv_setnv(sv, (double)IV_MAX + 1.0); + else { + (void)SvIOK_only(sv); + ++SvIVX(sv); + } return; } if (!(flags & SVp_POK) || !*SvPVX(sv)) { @@ -2764,7 +3327,8 @@ register SV *sv; while (isALPHA(*d)) d++; while (isDIGIT(*d)) d++; if (*d) { - sv_setnv(sv,atof(SvPVX(sv)) + 1.0); /* punt */ + SET_NUMERIC_STANDARD(); + sv_setnv(sv,atof(SvPVX(sv)) + 1.0); /* punt */ return; } d--; @@ -2813,16 +3377,20 @@ register SV *sv; if (SvGMAGICAL(sv)) mg_get(sv); flags = SvFLAGS(sv); - if (flags & SVp_IOK) { - (void)SvIOK_only(sv); - --SvIVX(sv); - return; - } if (flags & SVp_NOK) { SvNVX(sv) -= 1.0; (void)SvNOK_only(sv); return; } + if (flags & SVp_IOK) { + if (SvIVX(sv) == IV_MIN) + sv_setnv(sv, (double)IV_MIN - 1.0); + else { + (void)SvIOK_only(sv); + --SvIVX(sv); + } + return; + } if (!(flags & SVp_POK)) { if ((flags & SVTYPEMASK) < SVt_PVNV) sv_upgrade(sv, SVt_NV); @@ -2830,7 +3398,8 @@ register SV *sv; (void)SvNOK_only(sv); return; } - sv_setnv(sv,atof(SvPVX(sv)) - 1.0); + SET_NUMERIC_STANDARD(); + sv_setnv(sv,atof(SvPVX(sv)) - 1.0); /* punt */ } /* Make a string that will exist for the duration of the expression @@ -2841,7 +3410,7 @@ register SV *sv; static void sv_mortalgrow() { - tmps_max += 128; + tmps_max += (tmps_max < 512) ? 128 : 512; Renew(tmps_stack, tmps_max, SV*); } @@ -2851,7 +3420,7 @@ SV *oldstr; { register SV *sv; - new_SV(); + new_SV(sv); SvANY(sv) = 0; SvREFCNT(sv) = 1; SvFLAGS(sv) = 0; @@ -2868,7 +3437,7 @@ sv_newmortal() { register SV *sv; - new_SV(); + new_SV(sv); SvANY(sv) = 0; SvREFCNT(sv) = 1; SvFLAGS(sv) = SVs_TEMP; @@ -2902,7 +3471,7 @@ STRLEN len; { register SV *sv; - new_SV(); + new_SV(sv); SvANY(sv) = 0; SvREFCNT(sv) = 1; SvFLAGS(sv) = 0; @@ -2912,13 +3481,42 @@ STRLEN len; return sv; } +#ifdef I_STDARG +SV * +newSVpvf(const char* pat, ...) +#else +/*VARARGS0*/ +SV * +newSVpvf(pat, va_alist) +const char *pat; +va_dcl +#endif +{ + register SV *sv; + va_list args; + + new_SV(sv); + SvANY(sv) = 0; + SvREFCNT(sv) = 1; + SvFLAGS(sv) = 0; +#ifdef I_STDARG + va_start(args, pat); +#else + va_start(args); +#endif + sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + va_end(args); + return sv; +} + + SV * newSVnv(n) double n; { register SV *sv; - new_SV(); + new_SV(sv); SvANY(sv) = 0; SvREFCNT(sv) = 1; SvFLAGS(sv) = 0; @@ -2932,7 +3530,7 @@ IV i; { register SV *sv; - new_SV(); + new_SV(sv); SvANY(sv) = 0; SvREFCNT(sv) = 1; SvFLAGS(sv) = 0; @@ -2946,7 +3544,7 @@ SV *ref; { register SV *sv; - new_SV(); + new_SV(sv); SvANY(sv) = 0; SvREFCNT(sv) = 1; SvFLAGS(sv) = 0; @@ -2957,6 +3555,19 @@ SV *ref; return sv; } +#ifdef CRIPPLED_CC +SV * +newRV_noinc(ref) +SV *ref; +{ + register SV *sv; + + sv = newRV(ref); + SvREFCNT_dec(ref); + return sv; +} +#endif /* CRIPPLED_CC */ + /* make an exact duplicate of old */ SV * @@ -2971,7 +3582,7 @@ register SV *old; warn("semi-panic: attempt to dup freed string"); return Nullsv; } - new_SV(); + new_SV(sv); SvANY(sv) = 0; SvREFCNT(sv) = 1; SvFLAGS(sv) = 0; @@ -3023,24 +3634,22 @@ HV *stash; for (i = 0; i <= (I32) HvMAX(stash); i++) { for (entry = HvARRAY(stash)[i]; entry; - entry = entry->hent_next) { - if (!todo[(U8)*entry->hent_key]) + entry = HeNEXT(entry)) { + if (!todo[(U8)*HeKEY(entry)]) continue; - gv = (GV*)entry->hent_val; + gv = (GV*)HeVAL(entry); sv = GvSV(gv); (void)SvOK_off(sv); if (SvTYPE(sv) >= SVt_PV) { SvCUR_set(sv, 0); - SvTAINT(sv); if (SvPVX(sv) != Nullch) *SvPVX(sv) = '\0'; + SvTAINT(sv); } if (GvAV(gv)) { av_clear(GvAV(gv)); } - if (GvHV(gv)) { - if (HvNAME(GvHV(gv))) - continue; + if (GvHV(gv) && !HvNAME(GvHV(gv))) { hv_clear(GvHV(gv)); #ifndef VMS /* VMS has no environ array */ if (gv == envgv) @@ -3052,6 +3661,40 @@ HV *stash; } } +IO* +sv_2io(sv) +SV *sv; +{ + IO* io; + GV* gv; + + switch (SvTYPE(sv)) { + case SVt_PVIO: + io = (IO*)sv; + break; + case SVt_PVGV: + gv = (GV*)sv; + io = GvIO(gv); + if (!io) + croak("Bad filehandle: %s", GvNAME(gv)); + break; + default: + if (!SvOK(sv)) + croak(no_usym, "filehandle"); + if (SvROK(sv)) + return sv_2io(SvRV(sv)); + gv = gv_fetchpv(SvPV(sv,na), FALSE, SVt_PVIO); + if (gv) + io = GvIO(gv); + else + io = 0; + if (!io) + croak("Bad filehandle: %s", SvPV(sv,na)); + break; + } + return io; +} + CV * sv_2cv(sv, st, gvp, lref) SV *sv; @@ -3099,20 +3742,20 @@ I32 lref; return Nullcv; *st = GvESTASH(gv); fix_gv: - if (lref && !GvCV(gv)) { + if (lref && !GvCVu(gv)) { SV *tmpsv; ENTER; tmpsv = NEWSV(704,0); - gv_efullname(tmpsv, gv); - newSUB(start_subparse(), + gv_efullname3(tmpsv, gv, Nullch); + newSUB(start_subparse(FALSE, 0), newSVOP(OP_CONST, 0, tmpsv), Nullop, Nullop); LEAVE; - if (!GvCV(gv)) + if (!GvCVu(gv)) croak("Unable to create sub named \"%s\"", SvPV(sv,na)); } - return GvCV(gv); + return GvCVu(gv); } } @@ -3146,30 +3789,40 @@ register SV *sv; } } } -#endif /* SvTRUE */ +#endif /* !SvTRUE */ #ifndef SvIV -IV SvIV(Sv) -register SV *Sv; +IV +SvIV(sv) +register SV *sv; { - if (SvIOK(Sv)) - return SvIVX(Sv); - return sv_2iv(Sv); + if (SvIOK(sv)) + return SvIVX(sv); + return sv_2iv(sv); } -#endif /* SvIV */ +#endif /* !SvIV */ +#ifndef SvUV +UV +SvUV(sv) +register SV *sv; +{ + if (SvIOK(sv)) + return SvUVX(sv); + return sv_2uv(sv); +} +#endif /* !SvUV */ #ifndef SvNV -double SvNV(Sv) -register SV *Sv; +double +SvNV(sv) +register SV *sv; { - if (SvNOK(Sv)) - return SvNVX(Sv); - if (SvIOK(Sv)) - return (double)SvIVX(Sv); - return sv_2nv(Sv); + if (SvNOK(sv)) + return SvNVX(sv); + return sv_2nv(sv); } -#endif /* SvNV */ +#endif /* !SvNV */ #ifdef CRIPPLED_CC char * @@ -3225,7 +3878,7 @@ STRLEN *lp; if (!SvPOK(sv)) { SvPOK_on(sv); /* validate pointer */ SvTAINT(sv); - DEBUG_c(fprintf(stderr,"0x%lx 2pv(%s)\n", + DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%lx 2pv(%s)\n", (unsigned long)sv,SvPVX(sv))); } } @@ -3269,6 +3922,10 @@ int sv_isobject(sv) SV *sv; { + if (!sv) + return 0; + if (SvGMAGICAL(sv)) + mg_get(sv); if (!SvROK(sv)) return 0; sv = (SV*)SvRV(sv); @@ -3282,6 +3939,10 @@ sv_isa(sv, name) SV *sv; char *name; { + if (!sv) + return 0; + if (SvGMAGICAL(sv)) + mg_get(sv); if (!SvROK(sv)) return 0; sv = (SV*)SvRV(sv); @@ -3298,7 +3959,7 @@ char *classname; { SV *sv; - new_SV(); + new_SV(sv); SvANY(sv) = 0; SvREFCNT(sv) = 0; SvFLAGS(sv) = 0; @@ -3369,19 +4030,23 @@ HV* stash; if (SvFLAGS(ref) & (SVs_OBJECT|SVf_READONLY)) { if (SvREADONLY(ref)) croak(no_modify); - if (SvOBJECT(ref) && SvTYPE(ref) != SVt_PVIO) - --sv_objcount; + if (SvOBJECT(ref)) { + if (SvTYPE(ref) != SVt_PVIO) + --sv_objcount; + SvREFCNT_dec(SvSTASH(ref)); + } } SvOBJECT_on(ref); - ++sv_objcount; + if (SvTYPE(ref) != SVt_PVIO) + ++sv_objcount; (void)SvUPGRADE(ref, SVt_PVMG); SvSTASH(ref) = (HV*)SvREFCNT_inc(stash); #ifdef OVERLOAD - SvAMAGIC_off(sv); - if (Gv_AMG(stash)) { - SvAMAGIC_on(sv); - } + if (Gv_AMG(stash)) + SvAMAGIC_on(sv); + else + SvAMAGIC_off(sv); #endif /* OVERLOAD */ return sv; @@ -3394,7 +4059,7 @@ SV* sv; assert(SvTYPE(sv) == SVt_PVGV); SvFAKE_off(sv); if (GvGP(sv)) - gp_free(sv); + gp_free((GV*)sv); sv_unmagic(sv, '*'); Safefree(GvNAME(sv)); GvMULTI_off(sv); @@ -3416,116 +4081,769 @@ SV* sv; sv_2mortal(rv); /* Schedule for freeing later */ } +void +sv_taint(sv) +SV *sv; +{ + sv_magic((sv), Nullsv, 't', Nullch, 0); +} + +void +sv_untaint(sv) +SV *sv; +{ + if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) { + MAGIC *mg = mg_find(sv, 't'); + if (mg) + mg->mg_len &= ~1; + } +} + +bool +sv_tainted(sv) +SV *sv; +{ + if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) { + MAGIC *mg = mg_find(sv, 't'); + if (mg && ((mg->mg_len & 1) || (mg->mg_len & 2) && mg->mg_obj == sv)) + return TRUE; + } + return FALSE; +} + +void +sv_setpviv(sv, iv) +SV *sv; +IV iv; +{ + STRLEN len; + char buf[TYPE_DIGITS(UV)]; + char *ptr = buf + sizeof(buf); + int sign; + UV uv; + char *p; + + sv_setpvn(sv, "", 0); + if (iv >= 0) { + uv = iv; + sign = 0; + } else { + uv = -iv; + sign = 1; + } + do { + *--ptr = '0' + (uv % 10); + } while (uv /= 10); + len = (buf + sizeof(buf)) - ptr; + /* taking advantage of SvCUR(sv) == 0 */ + SvGROW(sv, sign + len + 1); + p = SvPVX(sv); + if (sign) + *p++ = '-'; + memcpy(p, ptr, len); + p += len; + *p = '\0'; + SvCUR(sv) = p - SvPVX(sv); +} + +#ifdef I_STDARG +void +sv_setpvf(SV *sv, const char* pat, ...) +#else +/*VARARGS0*/ +void +sv_setpvf(sv, pat, va_alist) + SV *sv; + const char *pat; + va_dcl +#endif +{ + va_list args; +#ifdef I_STDARG + va_start(args, pat); +#else + va_start(args); +#endif + sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + va_end(args); +} + +#ifdef I_STDARG +void +sv_catpvf(SV *sv, const char* pat, ...) +#else +/*VARARGS0*/ +void +sv_catpvf(sv, pat, va_alist) + SV *sv; + const char *pat; + va_dcl +#endif +{ + va_list args; +#ifdef I_STDARG + va_start(args, pat); +#else + va_start(args); +#endif + sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + va_end(args); +} + +void +sv_vsetpvfn(sv, pat, patlen, args, svargs, svmax, used_locale) + SV *sv; + const char *pat; + STRLEN patlen; + va_list *args; + SV **svargs; + I32 svmax; + bool *used_locale; +{ + sv_setpvn(sv, "", 0); + sv_vcatpvfn(sv, pat, patlen, args, svargs, svmax, used_locale); +} + +void +sv_vcatpvfn(sv, pat, patlen, args, svargs, svmax, used_locale) + SV *sv; + const char *pat; + STRLEN patlen; + va_list *args; + SV **svargs; + I32 svmax; + bool *used_locale; +{ + char *p; + char *q; + char *patend; + STRLEN origlen; + I32 svix = 0; + static char nullstr[] = "(null)"; + + /* no matter what, this is a string now */ + (void)SvPV_force(sv, origlen); + + /* special-case "", "%s", and "%_" */ + if (patlen == 0) + return; + if (patlen == 2 && pat[0] == '%') { + switch (pat[1]) { + case 's': + if (args) { + char *s = va_arg(*args, char*); + sv_catpv(sv, s ? s : nullstr); + } + else if (svix < svmax) + sv_catsv(sv, *svargs); + return; + case '_': + if (args) { + sv_catsv(sv, va_arg(*args, SV*)); + return; + } + /* See comment on '_' below */ + break; + } + } + + patend = (char*)pat + patlen; + for (p = (char*)pat; p < patend; p = q) { + bool alt = FALSE; + bool left = FALSE; + char fill = ' '; + char plus = 0; + char intsize = 0; + STRLEN width = 0; + STRLEN zeros = 0; + bool has_precis = FALSE; + STRLEN precis = 0; + + char esignbuf[4]; + STRLEN esignlen = 0; + + char *eptr = Nullch; + STRLEN elen = 0; + char ebuf[TYPE_DIGITS(int) * 2 + 16]; /* large enough for "%#.#f" */ + + static char *efloatbuf = Nullch; + static STRLEN efloatsize = 0; + + char c; + int i; + unsigned base; + IV iv; + UV uv; + double nv; + STRLEN have; + STRLEN need; + STRLEN gap; + + for (q = p; q < patend && *q != '%'; ++q) ; + if (q > p) { + sv_catpvn(sv, p, q - p); + p = q; + } + if (q++ >= patend) + break; + + /* FLAGS */ + + while (*q) { + switch (*q) { + case ' ': + case '+': + plus = *q++; + continue; + + case '-': + left = TRUE; + q++; + continue; + + case '0': + fill = *q++; + continue; + + case '#': + alt = TRUE; + q++; + continue; + + default: + break; + } + break; + } + + /* WIDTH */ + + switch (*q) { + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + width = 0; + while (isDIGIT(*q)) + width = width * 10 + (*q++ - '0'); + break; + + case '*': + if (args) + i = va_arg(*args, int); + else + i = (svix < svmax) ? SvIVx(svargs[svix++]) : 0; + left |= (i < 0); + width = (i < 0) ? -i : i; + q++; + break; + } + + /* PRECISION */ + + if (*q == '.') { + q++; + if (*q == '*') { + if (args) + i = va_arg(*args, int); + else + i = (svix < svmax) ? SvIVx(svargs[svix++]) : 0; + precis = (i < 0) ? 0 : i; + q++; + } + else { + precis = 0; + while (isDIGIT(*q)) + precis = precis * 10 + (*q++ - '0'); + } + has_precis = TRUE; + } + + /* SIZE */ + + switch (*q) { + case 'l': +#if 0 /* when quads have better support within Perl */ + if (*(q + 1) == 'l') { + intsize = 'q'; + q += 2; + break; + } +#endif + /* FALL THROUGH */ + case 'h': + case 'V': + intsize = *q++; + break; + } + + /* CONVERSION */ + + switch (c = *q++) { + + /* STRINGS */ + + case '%': + eptr = q - 1; + elen = 1; + goto string; + + case 'c': + if (args) + c = va_arg(*args, int); + else + c = (svix < svmax) ? SvIVx(svargs[svix++]) : 0; + eptr = &c; + elen = 1; + goto string; + + case 's': + if (args) { + eptr = va_arg(*args, char*); + if (eptr) + elen = strlen(eptr); + else { + eptr = nullstr; + elen = sizeof nullstr - 1; + } + } + else if (svix < svmax) + eptr = SvPVx(svargs[svix++], elen); + goto string; + + case '_': + /* + * The "%_" hack might have to be changed someday, + * if ISO or ANSI decide to use '_' for something. + * So we keep it hidden from users' code. + */ + if (!args) + goto unknown; + eptr = SvPVx(va_arg(*args, SV*), elen); + + string: + if (has_precis && elen > precis) + elen = precis; + break; + + /* INTEGERS */ + + case 'p': + if (args) + uv = (UV)va_arg(*args, void*); + else + uv = (svix < svmax) ? (UV)svargs[svix++] : 0; + base = 16; + goto integer; + + case 'D': + intsize = 'l'; + /* FALL THROUGH */ + case 'd': + case 'i': + if (args) { + switch (intsize) { + case 'h': iv = (short)va_arg(*args, int); break; + default: iv = va_arg(*args, int); break; + case 'l': iv = va_arg(*args, long); break; + case 'V': iv = va_arg(*args, IV); break; + } + } + else { + iv = (svix < svmax) ? SvIVx(svargs[svix++]) : 0; + switch (intsize) { + case 'h': iv = (short)iv; break; + default: iv = (int)iv; break; + case 'l': iv = (long)iv; break; + case 'V': break; + } + } + if (iv >= 0) { + uv = iv; + if (plus) + esignbuf[esignlen++] = plus; + } + else { + uv = -iv; + esignbuf[esignlen++] = '-'; + } + base = 10; + goto integer; + + case 'U': + intsize = 'l'; + /* FALL THROUGH */ + case 'u': + base = 10; + goto uns_integer; + + case 'O': + intsize = 'l'; + /* FALL THROUGH */ + case 'o': + base = 8; + goto uns_integer; + + case 'X': + case 'x': + base = 16; + + uns_integer: + if (args) { + switch (intsize) { + case 'h': uv = (unsigned short)va_arg(*args, unsigned); break; + default: uv = va_arg(*args, unsigned); break; + case 'l': uv = va_arg(*args, unsigned long); break; + case 'V': uv = va_arg(*args, UV); break; + } + } + else { + uv = (svix < svmax) ? SvUVx(svargs[svix++]) : 0; + switch (intsize) { + case 'h': uv = (unsigned short)uv; break; + default: uv = (unsigned)uv; break; + case 'l': uv = (unsigned long)uv; break; + case 'V': break; + } + } + + integer: + eptr = ebuf + sizeof ebuf; + switch (base) { + unsigned dig; + case 16: + p = (c == 'X') ? "0123456789ABCDEF" : "0123456789abcdef"; + do { + dig = uv & 15; + *--eptr = p[dig]; + } while (uv >>= 4); + if (alt) { + esignbuf[esignlen++] = '0'; + esignbuf[esignlen++] = c; /* 'x' or 'X' */ + } + break; + case 8: + do { + dig = uv & 7; + *--eptr = '0' + dig; + } while (uv >>= 3); + if (alt && *eptr != '0') + *--eptr = '0'; + break; + default: /* it had better be ten or less */ + do { + dig = uv % base; + *--eptr = '0' + dig; + } while (uv /= base); + break; + } + elen = (ebuf + sizeof ebuf) - eptr; + if (has_precis && precis > elen) + zeros = precis - elen; + break; + + /* FLOATING POINT */ + + case 'F': + c = 'f'; /* maybe %F isn't supported here */ + /* FALL THROUGH */ + case 'e': case 'E': + case 'f': + case 'g': case 'G': + + /* This is evil, but floating point is even more evil */ + + if (args) + nv = va_arg(*args, double); + else + nv = (svix < svmax) ? SvNVx(svargs[svix++]) : 0.0; + + need = 0; + if (c != 'e' && c != 'E') { + i = PERL_INT_MIN; + (void)frexp(nv, &i); + if (i == PERL_INT_MIN) + die("panic: frexp"); + if (i > 0) + need = BIT_DIGITS(i); + } + need += has_precis ? precis : 6; /* known default */ + if (need < width) + need = width; + + need += 20; /* fudge factor */ + if (efloatsize < need) { + Safefree(efloatbuf); + efloatsize = need + 20; /* more fudge */ + New(906, efloatbuf, efloatsize, char); + } + + eptr = ebuf + sizeof ebuf; + *--eptr = '\0'; + *--eptr = c; + if (has_precis) { + base = precis; + do { *--eptr = '0' + (base % 10); } while (base /= 10); + *--eptr = '.'; + } + if (width) { + base = width; + do { *--eptr = '0' + (base % 10); } while (base /= 10); + } + if (fill == '0') + *--eptr = fill; + if (left) + *--eptr = '-'; + if (plus) + *--eptr = plus; + if (alt) + *--eptr = '#'; + *--eptr = '%'; + + (void)sprintf(efloatbuf, eptr, nv); + + eptr = efloatbuf; + elen = strlen(efloatbuf); + +#ifdef LC_NUMERIC + /* + * User-defined locales may include arbitrary characters. + * And, unfortunately, some system may alloc the "C" locale + * to be overridden by a malicious user. + */ + if (used_locale) + *used_locale = TRUE; +#endif /* LC_NUMERIC */ + + break; + + /* SPECIAL */ + + case 'n': + i = SvCUR(sv) - origlen; + if (args) { + switch (intsize) { + case 'h': *(va_arg(*args, short*)) = i; break; + default: *(va_arg(*args, int*)) = i; break; + case 'l': *(va_arg(*args, long*)) = i; break; + case 'V': *(va_arg(*args, IV*)) = i; break; + } + } + else if (svix < svmax) + sv_setuv(svargs[svix++], (UV)i); + continue; /* not "break" */ + + /* UNKNOWN */ + + default: + unknown: + if (!args && dowarn && + (op->op_type == OP_PRTF || op->op_type == OP_SPRINTF)) { + SV *msg = sv_newmortal(); + sv_setpvf(msg, "Invalid conversion in %s: ", + (op->op_type == OP_PRTF) ? "printf" : "sprintf"); + if (c) + sv_catpvf(msg, isPRINT(c) ? "\"%%%c\"" : "\"%%\\%03o\"", + c & 0xFF); + else + sv_catpv(msg, "end of string"); + warn("%_", msg); /* yes, this is reentrant */ + } + + /* output mangled stuff ... */ + if (c == '\0') + --q; + eptr = p; + elen = q - p; + + /* ... right here, because formatting flags should not apply */ + SvGROW(sv, SvCUR(sv) + elen + 1); + p = SvEND(sv); + memcpy(p, eptr, elen); + p += elen; + *p = '\0'; + SvCUR(sv) = p - SvPVX(sv); + continue; /* not "break" */ + } + + have = esignlen + zeros + elen; + need = (have > width ? have : width); + gap = need - have; + + SvGROW(sv, SvCUR(sv) + need + 1); + p = SvEND(sv); + if (esignlen && fill == '0') { + for (i = 0; i < esignlen; i++) + *p++ = esignbuf[i]; + } + if (gap && !left) { + memset(p, fill, gap); + p += gap; + } + if (esignlen && fill != '0') { + for (i = 0; i < esignlen; i++) + *p++ = esignbuf[i]; + } + if (zeros) { + for (i = zeros; i; i--) + *p++ = '0'; + } + if (elen) { + memcpy(p, eptr, elen); + p += elen; + } + if (gap && left) { + memset(p, ' ', gap); + p += gap; + } + *p = '\0'; + SvCUR(sv) = p - SvPVX(sv); + } +} + #ifdef DEBUGGING void sv_dump(sv) SV* sv; { - char tmpbuf[1024]; - char *d = tmpbuf; + SV *d = sv_newmortal(); + char *s; U32 flags; U32 type; if (!sv) { - fprintf(stderr, "SV = 0\n"); + PerlIO_printf(Perl_debug_log, "SV = 0\n"); return; } flags = SvFLAGS(sv); type = SvTYPE(sv); - sprintf(d, "(0x%lx)\n REFCNT = %ld\n FLAGS = (", - (unsigned long)SvANY(sv), (long)SvREFCNT(sv)); - d += strlen(d); - if (flags & SVs_PADBUSY) strcat(d, "PADBUSY,"); - if (flags & SVs_PADTMP) strcat(d, "PADTMP,"); - if (flags & SVs_PADMY) strcat(d, "PADMY,"); - if (flags & SVs_TEMP) strcat(d, "TEMP,"); - if (flags & SVs_OBJECT) strcat(d, "OBJECT,"); - if (flags & SVs_GMG) strcat(d, "GMG,"); - if (flags & SVs_SMG) strcat(d, "SMG,"); - if (flags & SVs_RMG) strcat(d, "RMG,"); - d += strlen(d); - - if (flags & SVf_IOK) strcat(d, "IOK,"); - if (flags & SVf_NOK) strcat(d, "NOK,"); - if (flags & SVf_POK) strcat(d, "POK,"); - if (flags & SVf_ROK) strcat(d, "ROK,"); - if (flags & SVf_OOK) strcat(d, "OOK,"); - if (flags & SVf_FAKE) strcat(d, "FAKE,"); - if (flags & SVf_READONLY) strcat(d, "READONLY,"); - d += strlen(d); - - if (flags & SVp_IOK) strcat(d, "pIOK,"); - if (flags & SVp_NOK) strcat(d, "pNOK,"); - if (flags & SVp_POK) strcat(d, "pPOK,"); - if (flags & SVp_SCREAM) strcat(d, "SCREAM,"); - d += strlen(d); - if (d[-1] == ',') - d--; - *d++ = ')'; - *d = '\0'; + sv_setpvf(d, "(0x%lx)\n REFCNT = %ld\n FLAGS = (", + (unsigned long)SvANY(sv), (long)SvREFCNT(sv)); + if (flags & SVs_PADBUSY) sv_catpv(d, "PADBUSY,"); + if (flags & SVs_PADTMP) sv_catpv(d, "PADTMP,"); + if (flags & SVs_PADMY) sv_catpv(d, "PADMY,"); + if (flags & SVs_TEMP) sv_catpv(d, "TEMP,"); + if (flags & SVs_OBJECT) sv_catpv(d, "OBJECT,"); + if (flags & SVs_GMG) sv_catpv(d, "GMG,"); + if (flags & SVs_SMG) sv_catpv(d, "SMG,"); + if (flags & SVs_RMG) sv_catpv(d, "RMG,"); + + if (flags & SVf_IOK) sv_catpv(d, "IOK,"); + if (flags & SVf_NOK) sv_catpv(d, "NOK,"); + if (flags & SVf_POK) sv_catpv(d, "POK,"); + if (flags & SVf_ROK) sv_catpv(d, "ROK,"); + if (flags & SVf_OOK) sv_catpv(d, "OOK,"); + if (flags & SVf_FAKE) sv_catpv(d, "FAKE,"); + if (flags & SVf_READONLY) sv_catpv(d, "READONLY,"); + +#ifdef OVERLOAD + if (flags & SVf_AMAGIC) sv_catpv(d, "OVERLOAD,"); +#endif /* OVERLOAD */ + if (flags & SVp_IOK) sv_catpv(d, "pIOK,"); + if (flags & SVp_NOK) sv_catpv(d, "pNOK,"); + if (flags & SVp_POK) sv_catpv(d, "pPOK,"); + if (flags & SVp_SCREAM) sv_catpv(d, "SCREAM,"); + + switch (type) { + case SVt_PVCV: + case SVt_PVFM: + if (CvANON(sv)) sv_catpv(d, "ANON,"); + if (CvUNIQUE(sv)) sv_catpv(d, "UNIQUE,"); + if (CvCLONE(sv)) sv_catpv(d, "CLONE,"); + if (CvCLONED(sv)) sv_catpv(d, "CLONED,"); + if (CvNODEBUG(sv)) sv_catpv(d, "NODEBUG,"); + break; + case SVt_PVHV: + if (HvSHAREKEYS(sv)) sv_catpv(d, "SHAREKEYS,"); + if (HvLAZYDEL(sv)) sv_catpv(d, "LAZYDEL,"); + break; + case SVt_PVGV: + if (GvINTRO(sv)) sv_catpv(d, "INTRO,"); + if (GvMULTI(sv)) sv_catpv(d, "MULTI,"); + if (GvASSUMECV(sv)) sv_catpv(d, "ASSUMECV,"); + if (GvIMPORTED(sv)) { + sv_catpv(d, "IMPORT"); + if (GvIMPORTED(sv) == GVf_IMPORTED) + sv_catpv(d, "ALL,"); + else { + sv_catpv(d, "("); + if (GvIMPORTED_SV(sv)) sv_catpv(d, " SV"); + if (GvIMPORTED_AV(sv)) sv_catpv(d, " AV"); + if (GvIMPORTED_HV(sv)) sv_catpv(d, " HV"); + if (GvIMPORTED_CV(sv)) sv_catpv(d, " CV"); + sv_catpv(d, " ),"); + } + } + } + + if (*(SvEND(d) - 1) == ',') + SvPVX(d)[--SvCUR(d)] = '\0'; + sv_catpv(d, ")"); + s = SvPVX(d); - fprintf(stderr, "SV = "); + PerlIO_printf(Perl_debug_log, "SV = "); switch (type) { case SVt_NULL: - fprintf(stderr,"NULL%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "NULL%s\n", s); return; case SVt_IV: - fprintf(stderr,"IV%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "IV%s\n", s); break; case SVt_NV: - fprintf(stderr,"NV%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "NV%s\n", s); break; case SVt_RV: - fprintf(stderr,"RV%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "RV%s\n", s); break; case SVt_PV: - fprintf(stderr,"PV%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "PV%s\n", s); break; case SVt_PVIV: - fprintf(stderr,"PVIV%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "PVIV%s\n", s); break; case SVt_PVNV: - fprintf(stderr,"PVNV%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "PVNV%s\n", s); break; case SVt_PVBM: - fprintf(stderr,"PVBM%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "PVBM%s\n", s); break; case SVt_PVMG: - fprintf(stderr,"PVMG%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "PVMG%s\n", s); break; case SVt_PVLV: - fprintf(stderr,"PVLV%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "PVLV%s\n", s); break; case SVt_PVAV: - fprintf(stderr,"PVAV%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "PVAV%s\n", s); break; case SVt_PVHV: - fprintf(stderr,"PVHV%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "PVHV%s\n", s); break; case SVt_PVCV: - fprintf(stderr,"PVCV%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "PVCV%s\n", s); break; case SVt_PVGV: - fprintf(stderr,"PVGV%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "PVGV%s\n", s); break; case SVt_PVFM: - fprintf(stderr,"PVFM%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "PVFM%s\n", s); break; case SVt_PVIO: - fprintf(stderr,"PVIO%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "PVIO%s\n", s); break; default: - fprintf(stderr,"UNKNOWN%s\n", tmpbuf); + PerlIO_printf(Perl_debug_log, "UNKNOWN%s\n", s); return; } if (type >= SVt_PVIV || type == SVt_IV) - fprintf(stderr, " IV = %ld\n", (long)SvIVX(sv)); - if (type >= SVt_PVNV || type == SVt_NV) - fprintf(stderr, " NV = %.*g\n", DBL_DIG, SvNVX(sv)); + PerlIO_printf(Perl_debug_log, " IV = %ld\n", (long)SvIVX(sv)); + if (type >= SVt_PVNV || type == SVt_NV) { + SET_NUMERIC_STANDARD(); + PerlIO_printf(Perl_debug_log, " NV = %.*g\n", DBL_DIG, SvNVX(sv)); + } if (SvROK(sv)) { - fprintf(stderr, " RV = 0x%lx\n", (long)SvRV(sv)); + PerlIO_printf(Perl_debug_log, " RV = 0x%lx\n", (long)SvRV(sv)); sv_dump(SvRV(sv)); return; } @@ -3533,103 +4851,110 @@ SV* sv; return; if (type <= SVt_PVLV) { if (SvPVX(sv)) - fprintf(stderr, " PV = 0x%lx \"%s\"\n CUR = %ld\n LEN = %ld\n", + PerlIO_printf(Perl_debug_log, " PV = 0x%lx \"%s\"\n CUR = %ld\n LEN = %ld\n", (long)SvPVX(sv), SvPVX(sv), (long)SvCUR(sv), (long)SvLEN(sv)); else - fprintf(stderr, " PV = 0\n"); + PerlIO_printf(Perl_debug_log, " PV = 0\n"); } if (type >= SVt_PVMG) { if (SvMAGIC(sv)) { - fprintf(stderr, " MAGIC = 0x%lx\n", (long)SvMAGIC(sv)); + PerlIO_printf(Perl_debug_log, " MAGIC = 0x%lx\n", (long)SvMAGIC(sv)); } if (SvSTASH(sv)) - fprintf(stderr, " STASH = %s\n", HvNAME(SvSTASH(sv))); + PerlIO_printf(Perl_debug_log, " STASH = \"%s\"\n", HvNAME(SvSTASH(sv))); } switch (type) { case SVt_PVLV: - fprintf(stderr, " TYPE = %c\n", LvTYPE(sv)); - fprintf(stderr, " TARGOFF = %ld\n", (long)LvTARGOFF(sv)); - fprintf(stderr, " TARGLEN = %ld\n", (long)LvTARGLEN(sv)); - fprintf(stderr, " TARG = 0x%lx\n", (long)LvTARG(sv)); + PerlIO_printf(Perl_debug_log, " TYPE = %c\n", LvTYPE(sv)); + PerlIO_printf(Perl_debug_log, " TARGOFF = %ld\n", (long)LvTARGOFF(sv)); + PerlIO_printf(Perl_debug_log, " TARGLEN = %ld\n", (long)LvTARGLEN(sv)); + PerlIO_printf(Perl_debug_log, " TARG = 0x%lx\n", (long)LvTARG(sv)); sv_dump(LvTARG(sv)); break; case SVt_PVAV: - fprintf(stderr, " ARRAY = 0x%lx\n", (long)AvARRAY(sv)); - fprintf(stderr, " ALLOC = 0x%lx\n", (long)AvALLOC(sv)); - fprintf(stderr, " FILL = %ld\n", (long)AvFILL(sv)); - fprintf(stderr, " MAX = %ld\n", (long)AvMAX(sv)); - fprintf(stderr, " ARYLEN = 0x%lx\n", (long)AvARYLEN(sv)); + PerlIO_printf(Perl_debug_log, " ARRAY = 0x%lx\n", (long)AvARRAY(sv)); + PerlIO_printf(Perl_debug_log, " ALLOC = 0x%lx\n", (long)AvALLOC(sv)); + PerlIO_printf(Perl_debug_log, " FILL = %ld\n", (long)AvFILL(sv)); + PerlIO_printf(Perl_debug_log, " MAX = %ld\n", (long)AvMAX(sv)); + PerlIO_printf(Perl_debug_log, " ARYLEN = 0x%lx\n", (long)AvARYLEN(sv)); flags = AvFLAGS(sv); - d = tmpbuf; - if (flags & AVf_REAL) strcat(d, "REAL,"); - if (flags & AVf_REIFY) strcat(d, "REIFY,"); - if (flags & AVf_REUSED) strcat(d, "REUSED,"); - if (*d) - d[strlen(d)-1] = '\0'; - fprintf(stderr, " FLAGS = (%s)\n", d); + sv_setpv(d, ""); + if (flags & AVf_REAL) sv_catpv(d, ",REAL"); + if (flags & AVf_REIFY) sv_catpv(d, ",REIFY"); + if (flags & AVf_REUSED) sv_catpv(d, ",REUSED"); + PerlIO_printf(Perl_debug_log, " FLAGS = (%s)\n", + SvCUR(d) ? SvPVX(d) + 1 : ""); break; case SVt_PVHV: - fprintf(stderr, " ARRAY = 0x%lx\n",(long)HvARRAY(sv)); - fprintf(stderr, " KEYS = %ld\n", (long)HvKEYS(sv)); - fprintf(stderr, " FILL = %ld\n", (long)HvFILL(sv)); - fprintf(stderr, " MAX = %ld\n", (long)HvMAX(sv)); - fprintf(stderr, " RITER = %ld\n", (long)HvRITER(sv)); - fprintf(stderr, " EITER = 0x%lx\n",(long) HvEITER(sv)); + PerlIO_printf(Perl_debug_log, " ARRAY = 0x%lx\n",(long)HvARRAY(sv)); + PerlIO_printf(Perl_debug_log, " KEYS = %ld\n", (long)HvKEYS(sv)); + PerlIO_printf(Perl_debug_log, " FILL = %ld\n", (long)HvFILL(sv)); + PerlIO_printf(Perl_debug_log, " MAX = %ld\n", (long)HvMAX(sv)); + PerlIO_printf(Perl_debug_log, " RITER = %ld\n", (long)HvRITER(sv)); + PerlIO_printf(Perl_debug_log, " EITER = 0x%lx\n",(long) HvEITER(sv)); if (HvPMROOT(sv)) - fprintf(stderr, " PMROOT = 0x%lx\n",(long)HvPMROOT(sv)); + PerlIO_printf(Perl_debug_log, " PMROOT = 0x%lx\n",(long)HvPMROOT(sv)); if (HvNAME(sv)) - fprintf(stderr, " NAME = \"%s\"\n", HvNAME(sv)); + PerlIO_printf(Perl_debug_log, " NAME = \"%s\"\n", HvNAME(sv)); break; - case SVt_PVFM: case SVt_PVCV: - fprintf(stderr, " STASH = 0x%lx\n", (long)CvSTASH(sv)); - fprintf(stderr, " START = 0x%lx\n", (long)CvSTART(sv)); - fprintf(stderr, " ROOT = 0x%lx\n", (long)CvROOT(sv)); - fprintf(stderr, " XSUB = 0x%lx\n", (long)CvXSUB(sv)); - fprintf(stderr, " XSUBANY = %ld\n", (long)CvXSUBANY(sv).any_i32); - fprintf(stderr, " FILEGV = 0x%lx\n", (long)CvFILEGV(sv)); - fprintf(stderr, " DEPTH = %ld\n", (long)CvDEPTH(sv)); - fprintf(stderr, " PADLIST = 0x%lx\n", (long)CvPADLIST(sv)); - fprintf(stderr, " OUTSIDE = 0x%lx\n", (long)CvOUTSIDE(sv)); + if (SvPOK(sv)) + PerlIO_printf(Perl_debug_log, " PROTOTYPE = \"%s\"\n", SvPV(sv,na)); + /* FALL THROUGH */ + case SVt_PVFM: + PerlIO_printf(Perl_debug_log, " STASH = 0x%lx\n", (long)CvSTASH(sv)); + PerlIO_printf(Perl_debug_log, " START = 0x%lx\n", (long)CvSTART(sv)); + PerlIO_printf(Perl_debug_log, " ROOT = 0x%lx\n", (long)CvROOT(sv)); + PerlIO_printf(Perl_debug_log, " XSUB = 0x%lx\n", (long)CvXSUB(sv)); + PerlIO_printf(Perl_debug_log, " XSUBANY = %ld\n", (long)CvXSUBANY(sv).any_i32); + PerlIO_printf(Perl_debug_log, " GV = 0x%lx", (long)CvGV(sv)); + if (CvGV(sv) && GvNAME(CvGV(sv))) { + PerlIO_printf(Perl_debug_log, " \"%s\"\n", GvNAME(CvGV(sv))); + } else { + PerlIO_printf(Perl_debug_log, "\n"); + } + PerlIO_printf(Perl_debug_log, " FILEGV = 0x%lx\n", (long)CvFILEGV(sv)); + PerlIO_printf(Perl_debug_log, " DEPTH = %ld\n", (long)CvDEPTH(sv)); + PerlIO_printf(Perl_debug_log, " PADLIST = 0x%lx\n", (long)CvPADLIST(sv)); + PerlIO_printf(Perl_debug_log, " OUTSIDE = 0x%lx\n", (long)CvOUTSIDE(sv)); if (type == SVt_PVFM) - fprintf(stderr, " LINES = %ld\n", (long)FmLINES(sv)); + PerlIO_printf(Perl_debug_log, " LINES = %ld\n", (long)FmLINES(sv)); break; case SVt_PVGV: - fprintf(stderr, " NAME = %s\n", GvNAME(sv)); - fprintf(stderr, " NAMELEN = %ld\n", (long)GvNAMELEN(sv)); - fprintf(stderr, " STASH = 0x%lx\n", (long)GvSTASH(sv)); - fprintf(stderr, " GP = 0x%lx\n", (long)GvGP(sv)); - fprintf(stderr, " SV = 0x%lx\n", (long)GvSV(sv)); - fprintf(stderr, " REFCNT = %ld\n", (long)GvREFCNT(sv)); - fprintf(stderr, " IO = 0x%lx\n", (long)GvIOp(sv)); - fprintf(stderr, " FORM = 0x%lx\n", (long)GvFORM(sv)); - fprintf(stderr, " AV = 0x%lx\n", (long)GvAV(sv)); - fprintf(stderr, " HV = 0x%lx\n", (long)GvHV(sv)); - fprintf(stderr, " CV = 0x%lx\n", (long)GvCV(sv)); - fprintf(stderr, " CVGEN = 0x%lx\n", (long)GvCVGEN(sv)); - fprintf(stderr, " LASTEXPR = %ld\n", (long)GvLASTEXPR(sv)); - fprintf(stderr, " LINE = %ld\n", (long)GvLINE(sv)); - fprintf(stderr, " FLAGS = 0x%x\n", (int)GvFLAGS(sv)); - fprintf(stderr, " STASH = 0x%lx\n", (long)GvSTASH(sv)); - fprintf(stderr, " EGV = 0x%lx\n", (long)GvEGV(sv)); + PerlIO_printf(Perl_debug_log, " NAME = \"%s\"\n", GvNAME(sv)); + PerlIO_printf(Perl_debug_log, " NAMELEN = %ld\n", (long)GvNAMELEN(sv)); + PerlIO_printf(Perl_debug_log, " STASH = \"%s\"\n", HvNAME(GvSTASH(sv))); + PerlIO_printf(Perl_debug_log, " GP = 0x%lx\n", (long)GvGP(sv)); + PerlIO_printf(Perl_debug_log, " SV = 0x%lx\n", (long)GvSV(sv)); + PerlIO_printf(Perl_debug_log, " REFCNT = %ld\n", (long)GvREFCNT(sv)); + PerlIO_printf(Perl_debug_log, " IO = 0x%lx\n", (long)GvIOp(sv)); + PerlIO_printf(Perl_debug_log, " FORM = 0x%lx\n", (long)GvFORM(sv)); + PerlIO_printf(Perl_debug_log, " AV = 0x%lx\n", (long)GvAV(sv)); + PerlIO_printf(Perl_debug_log, " HV = 0x%lx\n", (long)GvHV(sv)); + PerlIO_printf(Perl_debug_log, " CV = 0x%lx\n", (long)GvCV(sv)); + PerlIO_printf(Perl_debug_log, " CVGEN = 0x%lx\n", (long)GvCVGEN(sv)); + PerlIO_printf(Perl_debug_log, " LASTEXPR = %ld\n", (long)GvLASTEXPR(sv)); + PerlIO_printf(Perl_debug_log, " LINE = %ld\n", (long)GvLINE(sv)); + PerlIO_printf(Perl_debug_log, " FILEGV = 0x%lx\n", (long)GvFILEGV(sv)); + PerlIO_printf(Perl_debug_log, " EGV = 0x%lx\n", (long)GvEGV(sv)); break; case SVt_PVIO: - fprintf(stderr, " IFP = 0x%lx\n", (long)IoIFP(sv)); - fprintf(stderr, " OFP = 0x%lx\n", (long)IoOFP(sv)); - fprintf(stderr, " DIRP = 0x%lx\n", (long)IoDIRP(sv)); - fprintf(stderr, " LINES = %ld\n", (long)IoLINES(sv)); - fprintf(stderr, " PAGE = %ld\n", (long)IoPAGE(sv)); - fprintf(stderr, " PAGE_LEN = %ld\n", (long)IoPAGE_LEN(sv)); - fprintf(stderr, " LINES_LEFT = %ld\n", (long)IoLINES_LEFT(sv)); - fprintf(stderr, " TOP_NAME = %s\n", IoTOP_NAME(sv)); - fprintf(stderr, " TOP_GV = 0x%lx\n", (long)IoTOP_GV(sv)); - fprintf(stderr, " FMT_NAME = %s\n", IoFMT_NAME(sv)); - fprintf(stderr, " FMT_GV = 0x%lx\n", (long)IoFMT_GV(sv)); - fprintf(stderr, " BOTTOM_NAME = %s\n", IoBOTTOM_NAME(sv)); - fprintf(stderr, " BOTTOM_GV = 0x%lx\n", (long)IoBOTTOM_GV(sv)); - fprintf(stderr, " SUBPROCESS = %ld\n", (long)IoSUBPROCESS(sv)); - fprintf(stderr, " TYPE = %c\n", IoTYPE(sv)); - fprintf(stderr, " FLAGS = 0x%lx\n", (long)IoFLAGS(sv)); + PerlIO_printf(Perl_debug_log, " IFP = 0x%lx\n", (long)IoIFP(sv)); + PerlIO_printf(Perl_debug_log, " OFP = 0x%lx\n", (long)IoOFP(sv)); + PerlIO_printf(Perl_debug_log, " DIRP = 0x%lx\n", (long)IoDIRP(sv)); + PerlIO_printf(Perl_debug_log, " LINES = %ld\n", (long)IoLINES(sv)); + PerlIO_printf(Perl_debug_log, " PAGE = %ld\n", (long)IoPAGE(sv)); + PerlIO_printf(Perl_debug_log, " PAGE_LEN = %ld\n", (long)IoPAGE_LEN(sv)); + PerlIO_printf(Perl_debug_log, " LINES_LEFT = %ld\n", (long)IoLINES_LEFT(sv)); + PerlIO_printf(Perl_debug_log, " TOP_NAME = \"%s\"\n", IoTOP_NAME(sv)); + PerlIO_printf(Perl_debug_log, " TOP_GV = 0x%lx\n", (long)IoTOP_GV(sv)); + PerlIO_printf(Perl_debug_log, " FMT_NAME = \"%s\"\n", IoFMT_NAME(sv)); + PerlIO_printf(Perl_debug_log, " FMT_GV = 0x%lx\n", (long)IoFMT_GV(sv)); + PerlIO_printf(Perl_debug_log, " BOTTOM_NAME = \"%s\"\n", IoBOTTOM_NAME(sv)); + PerlIO_printf(Perl_debug_log, " BOTTOM_GV = 0x%lx\n", (long)IoBOTTOM_GV(sv)); + PerlIO_printf(Perl_debug_log, " SUBPROCESS = %ld\n", (long)IoSUBPROCESS(sv)); + PerlIO_printf(Perl_debug_log, " TYPE = %c\n", IoTYPE(sv)); + PerlIO_printf(Perl_debug_log, " FLAGS = 0x%lx\n", (long)IoFLAGS(sv)); break; } } @@ -3640,38 +4965,3 @@ SV* sv; { } #endif - -IO* -sv_2io(sv) -SV *sv; -{ - IO* io; - GV* gv; - - switch (SvTYPE(sv)) { - case SVt_PVIO: - io = (IO*)sv; - break; - case SVt_PVGV: - gv = (GV*)sv; - io = GvIO(gv); - if (!io) - croak("Bad filehandle: %s", GvNAME(gv)); - break; - default: - if (!SvOK(sv)) - croak(no_usym, "filehandle"); - if (SvROK(sv)) - return sv_2io(SvRV(sv)); - gv = gv_fetchpv(SvPV(sv,na), FALSE, SVt_PVIO); - if (gv) - io = GvIO(gv); - else - io = 0; - if (!io) - croak("Bad filehandle: %s", SvPV(sv,na)); - break; - } - return io; -} - diff --git a/gnu/usr.bin/perl/sv.h b/gnu/usr.bin/perl/sv.h index c586de4e02a..cf180613814 100644 --- a/gnu/usr.bin/perl/sv.h +++ b/gnu/usr.bin/perl/sv.h @@ -1,6 +1,6 @@ /* sv.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -126,13 +126,10 @@ struct io { #define SVpfm_COMPILED 0x80000000 #define SVpbm_VALID 0x80000000 -#define SVpbm_CASEFOLD 0x40000000 -#define SVpbm_TAIL 0x20000000 +#define SVpbm_TAIL 0x40000000 -#ifdef OVERLOAD -#define SVpgv_AM 0x40000000 -/* #define SVpgv_badAM 0x20000000 */ -#endif /* OVERLOAD */ +#define SVphv_SHAREKEYS 0x20000000 /* keys live on shared string table */ +#define SVphv_LAZYDEL 0x40000000 /* entry in xhv_eiter must be deleted */ struct xrv { SV * xrv_rv; /* pointer to another SV */ @@ -151,6 +148,13 @@ struct xpviv { IV xiv_iv; /* integer value or pv offset */ }; +struct xpvuv { + char * xpv_pv; /* pointer to malloced string */ + STRLEN xpv_cur; /* length of xpv_pv as a C string */ + STRLEN xpv_len; /* allocated size */ + UV xuv_uv; /* unsigned value or pv offset */ +}; + struct xpvnv { char * xpv_pv; /* pointer to malloced string */ STRLEN xpv_cur; /* length of xpv_pv as a C string */ @@ -214,6 +218,8 @@ struct xpvbm { U8 xbm_rare; /* rarest character in string */ }; +/* This structure much match XPVCV */ + struct xpvfm { char * xpv_pv; /* pointer to malloced string */ STRLEN xpv_cur; /* length of xpv_pv as a C string */ @@ -233,6 +239,8 @@ struct xpvfm { long xcv_depth; /* >= 2 indicates recursive call */ AV * xcv_padlist; CV * xcv_outside; + U8 xcv_flags; + I32 xfm_lines; }; @@ -245,8 +253,8 @@ struct xpvio { MAGIC* xmg_magic; /* linked list of magicalness */ HV* xmg_stash; /* class package */ - FILE * xio_ifp; /* ifp and ofp are normally the same */ - FILE * xio_ofp; /* but sockets need separate streams */ + PerlIO * xio_ifp; /* ifp and ofp are normally the same */ + PerlIO * xio_ofp; /* but sockets need separate streams */ DIR * xio_dirp; /* for opendir, readdir, etc */ long xio_lines; /* $. */ long xio_page; /* $% */ @@ -267,6 +275,7 @@ struct xpvio { #define IOf_START 2 /* check for null ARGV and substitute '-' */ #define IOf_FLUSH 4 /* this fp wants a flush after write op */ #define IOf_DIDTOP 8 /* just did top of form */ +#define IOf_UNTAINT 16 /* consider this fp (and it's data) "safe" */ /* The following macros define implementation-independent predicates on SVs. */ @@ -398,10 +407,6 @@ struct xpvio { #define SvTAIL_on(sv) (SvFLAGS(sv) |= SVpbm_TAIL) #define SvTAIL_off(sv) (SvFLAGS(sv) &= ~SVpbm_TAIL) -#define SvCASEFOLD(sv) (SvFLAGS(sv) & SVpbm_CASEFOLD) -#define SvCASEFOLD_on(sv) (SvFLAGS(sv) |= SVpbm_CASEFOLD) -#define SvCASEFOLD_off(sv) (SvFLAGS(sv) &= ~SVpbm_CASEFOLD) - #define SvVALID(sv) (SvFLAGS(sv) & SVpbm_VALID) #define SvVALID_on(sv) (SvFLAGS(sv) |= SVpbm_VALID) #define SvVALID_off(sv) (SvFLAGS(sv) &= ~SVpbm_VALID) @@ -411,6 +416,8 @@ struct xpvio { #define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv #define SvIVXx(sv) SvIVX(sv) +#define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv +#define SvUVXx(sv) SvUVX(sv) #define SvNVX(sv) ((XPVNV*)SvANY(sv))->xnv_nv #define SvNVXx(sv) SvNVX(sv) #define SvPVX(sv) ((XPV*) SvANY(sv))->xpv_pv @@ -470,11 +477,16 @@ struct xpvio { #define IoTYPE(sv) ((XPVIO*) SvANY(sv))->xio_type #define IoFLAGS(sv) ((XPVIO*) SvANY(sv))->xio_flags -#define SvTAINT(sv) if (tainting && tainted) sv_magic(sv, Nullsv, 't', Nullch, 0) +#define SvTAINTED(sv) (SvMAGICAL(sv) && sv_tainted(sv)) +#define SvTAINTED_on(sv) STMT_START{ if(tainting){sv_taint(sv);} }STMT_END +#define SvTAINTED_off(sv) STMT_START{ if(tainting){sv_untaint(sv);} }STMT_END + +#define SvTAINT(sv) STMT_START{ if(tainted){SvTAINTED_on(sv);} }STMT_END #ifdef CRIPPLED_CC IV SvIV _((SV* sv)); +UV SvUV _((SV* sv)); double SvNV _((SV* sv)); #define SvPV_force(sv, lp) sv_pvn_force(sv, &lp) #define SvPV(sv, lp) sv_pvn(sv, &lp) @@ -482,6 +494,7 @@ char *sv_pvn _((SV *, STRLEN *)); I32 SvTRUE _((SV *)); #define SvIVx(sv) SvIV(sv) +#define SvUVx(sv) SvUV(sv) #define SvNVx(sv) SvNV(sv) #define SvPVx(sv, lp) sv_pvn(sv, &lp) #define SvPVx_force(sv, lp) sv_pvn_force(sv, &lp) @@ -489,14 +502,25 @@ I32 SvTRUE _((SV *)); #else /* !CRIPPLED_CC */ +#undef SvIV #define SvIV(sv) (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) +#undef SvUV +#define SvUV(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv)) + +#undef SvNV #define SvNV(sv) (SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv)) -#define SvPV(sv, lp) (SvPOK(sv) ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv(sv, &lp)) +#undef SvPV +#define SvPV(sv, lp) \ + (SvPOK(sv) ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv(sv, &lp)) -#define SvPV_force(sv, lp) ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force(sv, &lp)) +#undef SvPV_force +#define SvPV_force(sv, lp) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force(sv, &lp)) +#undef SvTRUE #define SvTRUE(sv) ( \ !sv \ ? 0 \ @@ -515,20 +539,54 @@ I32 SvTRUE _((SV *)); : sv_2bool(sv) ) #define SvIVx(sv) ((Sv = (sv)), SvIV(Sv)) +#define SvUVx(sv) ((Sv = (sv)), SvUV(Sv)) #define SvNVx(sv) ((Sv = (sv)), SvNV(Sv)) #define SvPVx(sv, lp) ((Sv = (sv)), SvPV(Sv, lp)) #define SvTRUEx(sv) ((Sv = (sv)), SvTRUE(Sv)) #endif /* CRIPPLED_CC */ +#define newRV_inc(sv) newRV(sv) +#ifdef CRIPPLED_CC +SV *newRV_noinc _((SV *)); +#else +#define newRV_noinc(sv) ((Sv = newRV(sv)), --SvREFCNT(SvRV(Sv)), Sv) +#endif + /* the following macro updates any magic values this sv is associated with */ #define SvSETMAGIC(x) if (SvSMAGICAL(x)) mg_set(x) -#define SvSetSV(dst,src) if (dst != src) sv_setsv(dst,src) +#define SvSetSV_and(dst,src,finally) \ + if ((dst) != (src)) { \ + sv_setsv(dst, src); \ + finally; \ + } +#define SvSetSV_nosteal_and(dst,src,finally) \ + if ((dst) != (src)) { \ + U32 tMpF = SvFLAGS(src) & SVs_TEMP; \ + SvTEMP_off(src); \ + sv_setsv(dst, src); \ + SvFLAGS(src) |= tMpF; \ + finally; \ + } + +#define SvSetSV(dst,src) \ + SvSetSV_and(dst,src,/*nothing*/;) +#define SvSetSV_nosteal(dst,src) \ + SvSetSV_nosteal_and(dst,src,/*nothing*/;) + +#define SvSetMagicSV(dst,src) \ + SvSetSV_and(dst,src,SvSETMAGIC(dst)) +#define SvSetMagicSV_nosteal(dst,src) \ + SvSetSV_nosteal_and(dst,src,SvSETMAGIC(dst)) #define SvPEEK(sv) sv_peek(sv) +#define SvIMMORTAL(sv) ((sv)==&sv_undef || (sv)==&sv_yes || (sv)==&sv_no) + +#define boolSV(b) ((b) ? &sv_yes : &sv_no) + #define isGV(sv) (SvTYPE(sv) == SVt_PVGV) #ifndef DOSISH diff --git a/gnu/usr.bin/perl/taint.c b/gnu/usr.bin/perl/taint.c index 6c64b39fc77..6776272782c 100644 --- a/gnu/usr.bin/perl/taint.c +++ b/gnu/usr.bin/perl/taint.c @@ -8,37 +8,26 @@ #include "perl.h" void -taint_not(s) -char *s; -{ - if (euid != uid) - croak("No %s allowed while running setuid", s); - if (egid != gid) - croak("No %s allowed while running setgid", s); -} - -void taint_proper(f, s) -char *f; +const char *f; char *s; { - if (tainting) { - DEBUG_u(fprintf(stderr,"%s %d %d %d\n",s,tainted,uid, euid)); - if (tainted) { - char *ug = 0; - if (euid != uid) - ug = " while running setuid"; - else if (egid != gid) - ug = " while running setgid"; - else if (tainting) - ug = " while running with -T switch"; - if (ug) { - if (!unsafe) - croak(f, s, ug); - else if (dowarn) - warn(f, s, ug); - } - } + char *ug; + + DEBUG_u(PerlIO_printf(Perl_debug_log, + "%s %d %d %d\n", s, tainted, uid, euid)); + + if (tainted) { + if (euid != uid) + ug = " while running setuid"; + else if (egid != gid) + ug = " while running setgid"; + else + ug = " while running with -T switch"; + if (!unsafe) + croak(f, s, ug); + else if (dowarn) + warn(f, s, ug); } } @@ -46,26 +35,74 @@ void taint_env() { SV** svp; + MAGIC* mg; + char** e; + static char* misc_env[] = { + "IFS", /* most shells' inter-field separators */ + "CDPATH", /* ksh dain bramage #1 */ + "ENV", /* ksh dain bramage #2 */ + "BASH_ENV", /* bash dain bramage -- I guess it's contagious */ + NULL + }; - if (tainting) { - MAGIC *mg = 0; - svp = hv_fetch(GvHVn(envgv),"PATH",4,FALSE); - if (!svp || *svp == &sv_undef || - ((mg = mg_find(*svp, 't')) && mg->mg_len & 1)) - { - tainted = TRUE; - if (mg && MgTAINTEDDIR(mg)) - taint_proper("Insecure directory in %s%s", "$ENV{PATH}"); - else - taint_proper("Insecure %s%s", "$ENV{PATH}"); +#ifdef VMS + int i = 0; + char name[10 + TYPE_DIGITS(int)] = "DCL$PATH"; + + while (1) { + if (i) + (void)sprintf(name,"DCL$PATH;%d", i); + svp = hv_fetch(GvHVn(envgv), name, strlen(name), FALSE); + if (!svp || *svp == &sv_undef) + break; + if (SvTAINTED(*svp)) { + TAINT; + taint_proper("Insecure %s%s", "$ENV{DCL$PATH}"); } - svp = hv_fetch(GvHVn(envgv),"IFS",3,FALSE); - if (svp && *svp != &sv_undef && - (mg = mg_find(*svp, 't')) && mg->mg_len & 1) - { - tainted = TRUE; - taint_proper("Insecure %s%s", "$ENV{IFS}"); + if ((mg = mg_find(*svp, 'e')) && MgTAINTEDDIR(mg)) { + TAINT; + taint_proper("Insecure directory in %s%s", "$ENV{DCL$PATH}"); } + i++; } -} +#endif /* VMS */ + svp = hv_fetch(GvHVn(envgv),"PATH",4,FALSE); + if (svp && *svp) { + if (SvTAINTED(*svp)) { + TAINT; + taint_proper("Insecure %s%s", "$ENV{PATH}"); + } + if ((mg = mg_find(*svp, 'e')) && MgTAINTEDDIR(mg)) { + TAINT; + taint_proper("Insecure directory in %s%s", "$ENV{PATH}"); + } + } + +#ifndef VMS + /* tainted $TERM is okay if it contains no metachars */ + svp = hv_fetch(GvHVn(envgv),"TERM",4,FALSE); + if (svp && *svp && SvTAINTED(*svp)) { + bool was_tainted = tainted; + char *t = SvPV(*svp, na); + char *e = t + na; + tainted = was_tainted; + if (t < e && isALNUM(*t)) + t++; + while (t < e && (isALNUM(*t) || *t == '-' || *t == ':')) + t++; + if (t < e) { + TAINT; + taint_proper("Insecure $ENV{%s}%s", "TERM"); + } + } +#endif /* !VMS */ + + for (e = misc_env; *e; e++) { + svp = hv_fetch(GvHVn(envgv), *e, strlen(*e), FALSE); + if (svp && *svp != &sv_undef && SvTAINTED(*svp)) { + TAINT; + taint_proper("Insecure $ENV{%s}%s", *e); + } + } +} diff --git a/gnu/usr.bin/perl/toke.c b/gnu/usr.bin/perl/toke.c index 5a43c097b5c..b2e8aac6d3e 100644 --- a/gnu/usr.bin/perl/toke.c +++ b/gnu/usr.bin/perl/toke.c @@ -1,6 +1,6 @@ /* toke.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -16,18 +16,21 @@ static void check_uni _((void)); static void force_next _((I32 type)); +static char *force_version _((char *start)); static char *force_word _((char *start, int token, int check_keyword, int allow_pack, int allow_tick)); static SV *q _((SV *sv)); static char *scan_const _((char *start)); static char *scan_formline _((char *s)); static char *scan_heredoc _((char *s)); -static char *scan_ident _((char *s, char *send, char *dest, I32 ck_uni)); +static char *scan_ident _((char *s, char *send, char *dest, STRLEN destlen, + I32 ck_uni)); static char *scan_inputsymbol _((char *start)); static char *scan_pat _((char *start)); static char *scan_str _((char *start)); static char *scan_subst _((char *start)); static char *scan_trans _((char *start)); -static char *scan_word _((char *s, char *dest, int allow_package, STRLEN *slp)); +static char *scan_word _((char *s, char *dest, STRLEN destlen, + int allow_package, STRLEN *slp)); static char *skipspace _((char *s)); static void checkcomma _((char *s, char *name, char *what)); static void force_ident _((char *s, int kind)); @@ -39,27 +42,43 @@ static void missingterm _((char *s)); static void no_op _((char *what, char *s)); static void set_csh _((void)); static I32 sublex_done _((void)); +static I32 sublex_push _((void)); static I32 sublex_start _((void)); #ifdef CRIPPLED_CC static int uni _((I32 f, char *s)); #endif -static char * filter_gets _((SV *sv, FILE *fp)); +static char * filter_gets _((SV *sv, PerlIO *fp, STRLEN append)); static void restore_rsfp _((void *f)); +static char ident_too_long[] = "Identifier too long"; + +static char *linestart; /* beg. of most recently read line */ + +static char pending_ident; /* pending identifier lookup */ + +static struct { + I32 super_state; /* lexer state to save */ + I32 sub_inwhat; /* "lex_inwhat" to use */ + OP *sub_op; /* "lex_op" to use */ +} sublex_info; + /* The following are arranged oddly so that the guard on the switch statement * can get by with a single comparison (if the compiler is smart enough). */ -#define LEX_NORMAL 9 -#define LEX_INTERPNORMAL 8 -#define LEX_INTERPCASEMOD 7 -#define LEX_INTERPSTART 6 -#define LEX_INTERPEND 5 -#define LEX_INTERPENDMAYBE 4 -#define LEX_INTERPCONCAT 3 -#define LEX_INTERPCONST 2 -#define LEX_FORMLINE 1 -#define LEX_KNOWNEXT 0 +/* #define LEX_NOTPARSING 11 is done in perl.h. */ + +#define LEX_NORMAL 10 +#define LEX_INTERPNORMAL 9 +#define LEX_INTERPCASEMOD 8 +#define LEX_INTERPPUSH 7 +#define LEX_INTERPSTART 6 +#define LEX_INTERPEND 5 +#define LEX_INTERPENDMAYBE 4 +#define LEX_INTERPCONCAT 3 +#define LEX_INTERPCONST 2 +#define LEX_FORMLINE 1 +#define LEX_KNOWNEXT 0 #ifdef I_FCNTL #include <fcntl.h> @@ -68,6 +87,12 @@ static void restore_rsfp _((void *f)); #include <sys/file.h> #endif +/* XXX If this causes problems, set i_unistd=undef in the hint file. */ +#ifdef I_UNISTD +# include <unistd.h> /* Needed for execv() */ +#endif + + #ifdef ff_next #undef ff_next #endif @@ -138,12 +163,11 @@ no_op(what, s) char *what; char *s; { - char tmpbuf[128]; char *oldbp = bufptr; - bool is_first = (oldbufptr == SvPVX(linestr)); + bool is_first = (oldbufptr == linestart); + bufptr = s; - sprintf(tmpbuf, "%s found where operator expected", what); - yywarn(tmpbuf); + yywarn(form("%s found where operator expected", what)); if (is_first) warn("\t(Missing semicolon on previous line?)\n"); else if (oldoldbufptr && isIDFIRST(*oldoldbufptr)) { @@ -172,7 +196,7 @@ char *s; } else if (multi_close < 32 || multi_close == 127) { *tmpbuf = '^'; - tmpbuf[1] = multi_close ^ 64; + tmpbuf[1] = toCTRL(multi_close); s = "\\n"; tmpbuf[2] = '\0'; s = tmpbuf; @@ -207,19 +231,20 @@ SV *line; char *s; STRLEN len; - SAVEINT(lex_dojoin); - SAVEINT(lex_brackets); - SAVEINT(lex_fakebrack); - SAVEINT(lex_casemods); - SAVEINT(lex_starts); - SAVEINT(lex_state); + SAVEI32(lex_dojoin); + SAVEI32(lex_brackets); + SAVEI32(lex_fakebrack); + SAVEI32(lex_casemods); + SAVEI32(lex_starts); + SAVEI32(lex_state); SAVESPTR(lex_inpat); - SAVEINT(lex_inwhat); - SAVEINT(curcop->cop_line); + SAVEI32(lex_inwhat); + SAVEI16(curcop->cop_line); SAVEPPTR(bufptr); SAVEPPTR(bufend); SAVEPPTR(oldbufptr); SAVEPPTR(oldoldbufptr); + SAVEPPTR(linestart); SAVESPTR(linestr); SAVEPPTR(lex_brackstack); SAVEPPTR(lex_casestack); @@ -256,7 +281,7 @@ SV *line; sv_catpvn(linestr, "\n;", 2); } SvTEMP_off(linestr); - oldoldbufptr = oldbufptr = bufptr = SvPVX(linestr); + oldoldbufptr = oldbufptr = bufptr = linestart = SvPVX(linestr); bufend = bufptr + SvCUR(linestr); SvREFCNT_dec(rs); rs = newSVpv("\n", 1); @@ -266,18 +291,19 @@ SV *line; void lex_end() { + doextract = FALSE; } static void restore_rsfp(f) void *f; { - FILE *fp = (FILE*)f; + PerlIO *fp = (PerlIO*)f; - if (rsfp == stdin) - clearerr(rsfp); + if (rsfp == PerlIO_stdin()) + PerlIO_clearerr(rsfp); else if (rsfp && (rsfp != fp)) - fclose(rsfp); + PerlIO_close(rsfp); rsfp = fp; } @@ -332,6 +358,7 @@ register char *s; return s; } for (;;) { + STRLEN prevlen; while (s < bufend && isSPACE(*s)) s++; if (s < bufend && *s == '#') { @@ -342,33 +369,38 @@ register char *s; } if (s < bufend || !rsfp || lex_state != LEX_NORMAL) return s; - if ((s = filter_gets(linestr, rsfp)) == Nullch) { + if ((s = filter_gets(linestr, rsfp, (prevlen = SvCUR(linestr)))) == Nullch) { if (minus_n || minus_p) { - sv_setpv(linestr,minus_p ? ";}continue{print" : ""); + sv_setpv(linestr,minus_p ? + ";}continue{print or die qq(-p destination: $!\\n)" : + ""); sv_catpv(linestr,";}"); minus_n = minus_p = 0; } else sv_setpv(linestr,";"); - oldoldbufptr = oldbufptr = bufptr = s = SvPVX(linestr); + oldoldbufptr = oldbufptr = bufptr = s = linestart = SvPVX(linestr); bufend = SvPVX(linestr) + SvCUR(linestr); if (preprocess && !in_eval) (void)my_pclose(rsfp); - else if ((FILE*)rsfp == stdin) - clearerr(stdin); + else if ((PerlIO*)rsfp == PerlIO_stdin()) + PerlIO_clearerr(rsfp); else - (void)fclose(rsfp); + (void)PerlIO_close(rsfp); + if (e_fp == rsfp) + e_fp = Nullfp; rsfp = Nullfp; return s; } - oldoldbufptr = oldbufptr = bufptr = s; - bufend = bufptr + SvCUR(linestr); + linestart = bufptr = s + prevlen; + bufend = s + SvCUR(linestr); + s = bufptr; incline(s); - if (perldb && curstash != debstash) { + if (PERLDB_LINE && curstash != debstash) { SV *sv = NEWSV(85,0); sv_upgrade(sv, SVt_PVMG); - sv_setsv(sv,linestr); + sv_setpvn(sv,bufptr,bufend-bufptr); av_store(GvAV(curcop->cop_filegv),(I32)curcop->cop_line,sv); } } @@ -422,10 +454,15 @@ char *s; #define LOP(f,x) return lop(f,x,s) static I32 -lop(f,x,s) +lop +#ifdef CAN_PROTOTYPE + (I32 f, expectation x, char *s) +#else + (f,x,s) I32 f; expectation x; char *s; +#endif /* CAN_PROTOTYPE */ { yylval.ival = f; CLINE; @@ -474,7 +511,7 @@ int allow_tick; (allow_pack && *s == ':') || (allow_tick && *s == '\'') ) { - s = scan_word(s, tokenbuf, allow_pack, &len); + s = scan_word(s, tokenbuf, sizeof tokenbuf, allow_pack, &len); if (check_keyword && keyword(tokenbuf, len)) return start; if (token == METHOD) { @@ -505,7 +542,10 @@ int kind; force_next(WORD); if (kind) { op->op_private = OPpCONST_ENTERED; - gv_fetchpv(s, TRUE, + /* XXX see note in pp_entereval() for why we forgo typo + warnings if the symbol must be introduced in an eval. + GSAR 96-10-12 */ + gv_fetchpv(s, in_eval ? GV_ADDMULTI : TRUE, kind == '$' ? SVt_PV : kind == '@' ? SVt_PVAV : kind == '%' ? SVt_PVHV : @@ -515,6 +555,34 @@ int kind; } } +static char * +force_version(s) +char *s; +{ + OP *version = Nullop; + + s = skipspace(s); + + /* default VERSION number -- GBARR */ + + if(isDIGIT(*s)) { + char *d; + int c; + for( d=s, c = 1; isDIGIT(*d) || *d == '_' || (*d == '.' && c--); d++); + if((*d == ';' || isSPACE(*d)) && *(skipspace(d)) != ',') { + s = scan_num(s); + /* real VERSION number -- GBARR */ + version = yylval.opval; + } + } + + /* NOTE: The parser sees the package name and the VERSION swapped */ + nextval[nexttoke].opval = version; + force_next(WORD); + + return (s); +} + static SV * q(sv) SV *sv; @@ -560,24 +628,49 @@ sublex_start() return THING; } if (op_type == OP_CONST || op_type == OP_READLINE) { - yylval.opval = (OP*)newSVOP(op_type, 0, q(lex_stuff)); + SV *sv = q(lex_stuff); + STRLEN len; + char *p = SvPV(sv, len); + yylval.opval = (OP*)newSVOP(op_type, 0, newSVpv(p, len)); + SvREFCNT_dec(sv); lex_stuff = Nullsv; return THING; } + sublex_info.super_state = lex_state; + sublex_info.sub_inwhat = op_type; + sublex_info.sub_op = lex_op; + lex_state = LEX_INTERPPUSH; + + expect = XTERM; + if (lex_op) { + yylval.opval = lex_op; + lex_op = Nullop; + return PMFUNC; + } + else + return FUNC; +} + +static I32 +sublex_push() +{ push_scope(); - SAVEINT(lex_dojoin); - SAVEINT(lex_brackets); - SAVEINT(lex_fakebrack); - SAVEINT(lex_casemods); - SAVEINT(lex_starts); - SAVEINT(lex_state); + + lex_state = sublex_info.super_state; + SAVEI32(lex_dojoin); + SAVEI32(lex_brackets); + SAVEI32(lex_fakebrack); + SAVEI32(lex_casemods); + SAVEI32(lex_starts); + SAVEI32(lex_state); SAVESPTR(lex_inpat); - SAVEINT(lex_inwhat); - SAVEINT(curcop->cop_line); + SAVEI32(lex_inwhat); + SAVEI16(curcop->cop_line); SAVEPPTR(bufptr); SAVEPPTR(oldbufptr); SAVEPPTR(oldoldbufptr); + SAVEPPTR(linestart); SAVESPTR(linestr); SAVEPPTR(lex_brackstack); SAVEPPTR(lex_casestack); @@ -585,7 +678,7 @@ sublex_start() linestr = lex_stuff; lex_stuff = Nullsv; - bufend = bufptr = oldbufptr = oldoldbufptr = SvPVX(linestr); + bufend = bufptr = oldbufptr = oldoldbufptr = linestart = SvPVX(linestr); bufend += SvCUR(linestr); SAVEFREESV(linestr); @@ -602,21 +695,13 @@ sublex_start() lex_state = LEX_INTERPCONCAT; curcop->cop_line = multi_start; - lex_inwhat = op_type; - if (op_type == OP_MATCH || op_type == OP_SUBST) - lex_inpat = lex_op; + lex_inwhat = sublex_info.sub_inwhat; + if (lex_inwhat == OP_MATCH || lex_inwhat == OP_SUBST) + lex_inpat = sublex_info.sub_op; else - lex_inpat = 0; + lex_inpat = Nullop; - expect = XTERM; - force_next('('); - if (lex_op) { - yylval.opval = lex_op; - lex_op = Nullop; - return PMFUNC; - } - else - return FUNC; + return '('; } static I32 @@ -637,7 +722,7 @@ sublex_done() if (lex_repl && (lex_inwhat == OP_SUBST || lex_inwhat == OP_TRANS)) { linestr = lex_repl; lex_inpat = 0; - bufend = bufptr = oldbufptr = oldoldbufptr = SvPVX(linestr); + bufend = bufptr = oldbufptr = oldoldbufptr = linestart = SvPVX(linestr); bufend += SvCUR(linestr); SAVEFREESV(linestr); lex_dojoin = FALSE; @@ -758,10 +843,8 @@ char *start; continue; case 'c': s++; - *d = *s++; - if (isLOWER(*d)) - *d = toUPPER(*d); - *d++ ^= 64; + len = *s++; + *d++ = toCTRL(len); continue; case 'b': *d++ = '\b'; @@ -846,7 +929,7 @@ register char *s; char seen[256]; unsigned char un_char = 0, last_un_char; char *send = strchr(s,']'); - char tmpbuf[512]; + char tmpbuf[sizeof tokenbuf * 4]; if (!send) /* has to be an expression */ return TRUE; @@ -871,7 +954,7 @@ register char *s; case '$': weight -= seen[un_char] * 10; if (isALNUM(s[1])) { - scan_ident(s,send,tmpbuf,FALSE); + scan_ident(s, send, tmpbuf, sizeof tmpbuf, FALSE); if ((int)strlen(tmpbuf) > 1 && gv_fetchpv(tmpbuf,FALSE, SVt_PV)) weight -= 100; else @@ -941,17 +1024,17 @@ char *start; GV *gv; { char *s = start + (*start == '$'); - char tmpbuf[1024]; + char tmpbuf[sizeof tokenbuf]; STRLEN len; GV* indirgv; if (gv) { if (GvIO(gv)) return 0; - if (!GvCV(gv)) + if (!GvCVu(gv)) gv = 0; } - s = scan_word(s, tmpbuf, TRUE, &len); + s = scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len); if (*start == '$') { if (gv || last_lop_op == OP_PRINT || isUPPER(*tokenbuf)) return 0; @@ -962,11 +1045,13 @@ GV *gv; } if (!keyword(tmpbuf, len)) { indirgv = gv_fetchpv(tmpbuf,FALSE, SVt_PVCV); - if (indirgv && GvCV(indirgv)) + if (indirgv && GvCVu(indirgv)) return 0; /* filehandle or package name makes it a method */ - if (!gv || GvIO(indirgv) || gv_stashpv(tmpbuf, FALSE)) { + if (!gv || GvIO(indirgv) || gv_stashpvn(tmpbuf, len, FALSE)) { s = skipspace(s); + if ((bufend - s) >= 2 && *s == '=' && *(s+1) == '>') + return 0; /* no assumptions -- "=>" quotes bearword */ nextval[nexttoke].opval = (OP*)newSVOP(OP_CONST, 0, newSVpv(tmpbuf,0)); @@ -1029,7 +1114,7 @@ filter_add(funcp, datasv) die("Can't upgrade filter_add data to SVt_PVIO"); IoDIRP(datasv) = (DIR*)funcp; /* stash funcp into spare field */ if (filter_debug) - warn("filter_add func %lx (%s)", funcp, SvPV(datasv,na)); + warn("filter_add func %p (%s)", funcp, SvPV(datasv,na)); av_unshift(rsfp_filters, 1); av_store(rsfp_filters, 0, datasv) ; return(datasv); @@ -1042,7 +1127,7 @@ filter_del(funcp) filter_t funcp; { if (filter_debug) - warn("filter_del func %lx", funcp); + warn("filter_del func %p", funcp); if (!rsfp_filters || AvFILL(rsfp_filters)<0) return; /* if filter is on top of stack (usual case) just pop it off */ @@ -1081,8 +1166,8 @@ filter_read(idx, buf_sv, maxlen) /* ensure buf_sv is large enough */ SvGROW(buf_sv, old_len + maxlen) ; - if ((len = fread(SvPVX(buf_sv) + old_len, 1, maxlen, rsfp)) <= 0){ - if (ferror(rsfp)) + if ((len = PerlIO_read(rsfp, SvPVX(buf_sv) + old_len, maxlen)) <= 0){ + if (PerlIO_error(rsfp)) return -1; /* error */ else return 0 ; /* end of file */ @@ -1091,7 +1176,7 @@ filter_read(idx, buf_sv, maxlen) } else { /* Want a line */ if (sv_gets(buf_sv, rsfp, SvCUR(buf_sv)) == NULL) { - if (ferror(rsfp)) + if (PerlIO_error(rsfp)) return -1; /* error */ else return 0 ; /* end of file */ @@ -1108,7 +1193,7 @@ filter_read(idx, buf_sv, maxlen) /* Get function pointer hidden within datasv */ funcp = (filter_t)IoDIRP(datasv); if (filter_debug) - warn("filter_read %d: via function %lx (%s)\n", + warn("filter_read %d: via function %p (%s)\n", idx, funcp, SvPV(datasv,na)); /* Call function. The function is expected to */ /* call "FILTER_READ(idx+1, buf_sv)" first. */ @@ -1117,20 +1202,22 @@ filter_read(idx, buf_sv, maxlen) } static char * -filter_gets(sv,fp) +filter_gets(sv,fp, append) register SV *sv; -register FILE *fp; +register PerlIO *fp; +STRLEN append; { if (rsfp_filters) { - SvCUR_set(sv, 0); /* start with empty line */ + if (!append) + SvCUR_set(sv, 0); /* start with empty line */ if (FILTER_READ(0, sv, 0) > 0) return ( SvPVX(sv) ) ; else return Nullch ; } else - return (sv_gets(sv, fp, 0)) ; + return (sv_gets(sv, fp, append)); } @@ -1140,7 +1227,7 @@ register FILE *fp; { "OPERATOR", "TERM", "REF", "STATE", "BLOCK", "TERMBLOCK" }; #endif -extern int yychar; /* last token */ +EXT int yychar; /* last token */ int yylex() @@ -1150,6 +1237,57 @@ yylex() register I32 tmp; STRLEN len; + if (pending_ident) { + char pit = pending_ident; + pending_ident = 0; + + if (in_my) { + if (strchr(tokenbuf,':')) + croak(no_myglob,tokenbuf); + yylval.opval = newOP(OP_PADANY, 0); + yylval.opval->op_targ = pad_allocmy(tokenbuf); + return PRIVATEREF; + } + + if (!strchr(tokenbuf,':') && (tmp = pad_findmy(tokenbuf))) { + if (last_lop_op == OP_SORT && + tokenbuf[0] == '$' && + (tokenbuf[1] == 'a' || tokenbuf[1] == 'b') + && !tokenbuf[2]) + { + for (d = in_eval ? oldoldbufptr : linestart; + d < bufend && *d != '\n'; + d++) + { + if (strnEQ(d,"<=>",3) || strnEQ(d,"cmp",3)) { + croak("Can't use \"my %s\" in sort comparison", + tokenbuf); + } + } + } + + yylval.opval = newOP(OP_PADANY, 0); + yylval.opval->op_targ = tmp; + return PRIVATEREF; + } + + /* Force them to make up their mind on "@foo". */ + if (pit == '@' && lex_state != LEX_NORMAL && !lex_brackets) { + GV *gv = gv_fetchpv(tokenbuf+1, FALSE, SVt_PVAV); + if (!gv || ((tokenbuf[0] == '@') ? !GvAV(gv) : !GvHV(gv))) + yyerror(form("In string, %s now must be written as \\%s", + tokenbuf, tokenbuf)); + } + + yylval.opval = (OP*)newSVOP(OP_CONST, 0, newSVpv(tokenbuf+1, 0)); + yylval.opval->op_private = OPpCONST_ENTERED; + gv_fetchpv(tokenbuf+1, in_eval ? GV_ADDMULTI : TRUE, + ((tokenbuf[0] == '$') ? SVt_PV + : (tokenbuf[0] == '@') ? SVt_PVAV + : SVt_PVHV)); + return WORD; + } + switch (lex_state) { #ifdef COMMENTARY case LEX_NORMAL: /* Some compilers will produce faster */ @@ -1199,7 +1337,7 @@ yylex() return ')'; } if (lex_casemods > 10) { - char* newlb = (char*)realloc(lex_casestack, lex_casemods + 2); + char* newlb = Renew(lex_casestack, lex_casemods + 2, char); if (newlb != lex_casestack) { SAVEFREEPV(newlb); lex_casestack = newlb; @@ -1233,6 +1371,9 @@ yylex() return yylex(); } + case LEX_INTERPPUSH: + return sublex_push(); + case LEX_INTERPSTART: if (bufptr == bufend) return sublex_done(); @@ -1254,9 +1395,7 @@ yylex() s = bufptr; Aop(OP_CONCAT); } - else - return yylex(); - break; + return yylex(); case LEX_INTERPENDMAYBE: if (intuit_more(bufptr)) { @@ -1320,19 +1459,20 @@ yylex() oldoldbufptr = oldbufptr; oldbufptr = s; DEBUG_p( { - fprintf(stderr,"### Tokener expecting %s at %s\n", exp_name[expect], s); + PerlIO_printf(PerlIO_stderr(), "### Tokener expecting %s at %s\n", exp_name[expect], s); } ) retry: switch (*s) { default: - warn("Unrecognized character \\%03o ignored", *s++ & 255); - goto retry; + croak("Unrecognized character \\%03o", *s & 255); case 4: case 26: goto fake_eof; /* emulate EOF on ^D or ^Z */ case 0: if (!rsfp) { + last_uni = 0; + last_lop = 0; if (lex_brackets) yyerror("Missing right bracket"); TOKEN(0); @@ -1360,25 +1500,37 @@ yylex() sv_catpv(linestr, "LINE: while (<>) {"); if (minus_l) sv_catpv(linestr,"chomp;"); - if (minus_a){ - if (minus_F){ - char tmpbuf1[50]; - if ( splitstr[0] == '/' || - splitstr[0] == '\'' || - splitstr[0] == '"' ) - sprintf( tmpbuf1, "@F=split(%s);", splitstr ); - else - sprintf( tmpbuf1, "@F=split('%s');", splitstr ); - sv_catpv(linestr,tmpbuf1); + if (minus_a) { + GV* gv = gv_fetchpv("::F", TRUE, SVt_PVAV); + if (gv) + GvIMPORTED_AV_on(gv); + if (minus_F) { + if (strchr("/'\"", *splitstr) + && strchr(splitstr + 1, *splitstr)) + sv_catpvf(linestr, "@F=split(%s);", splitstr); + else { + char delim; + s = "'~#\200\1'"; /* surely one char is unused...*/ + while (s[1] && strchr(splitstr, *s)) s++; + delim = *s; + sv_catpvf(linestr, "@F=split(%s%c", + "q" + (delim == '\''), delim); + for (s = splitstr; *s; s++) { + if (*s == '\\') + sv_catpvn(linestr, "\\", 1); + sv_catpvn(linestr, s, 1); + } + sv_catpvf(linestr, "%c);", delim); + } } else sv_catpv(linestr,"@F=split(' ');"); } } sv_catpv(linestr, "\n"); - oldoldbufptr = oldbufptr = s = SvPVX(linestr); + oldoldbufptr = oldbufptr = s = linestart = SvPVX(linestr); bufend = SvPVX(linestr) + SvCUR(linestr); - if (perldb && curstash != debstash) { + if (PERLDB_LINE && curstash != debstash) { SV *sv = NEWSV(85,0); sv_upgrade(sv, SVt_PVMG); @@ -1388,26 +1540,28 @@ yylex() goto retry; } do { - if ((s = filter_gets(linestr, rsfp)) == Nullch) { + if ((s = filter_gets(linestr, rsfp, 0)) == Nullch) { fake_eof: if (rsfp) { if (preprocess && !in_eval) (void)my_pclose(rsfp); - else if ((FILE*)rsfp == stdin) - clearerr(stdin); + else if ((PerlIO *)rsfp == PerlIO_stdin()) + PerlIO_clearerr(rsfp); else - (void)fclose(rsfp); + (void)PerlIO_close(rsfp); + if (e_fp == rsfp) + e_fp = Nullfp; rsfp = Nullfp; } if (!in_eval && (minus_n || minus_p)) { sv_setpv(linestr,minus_p ? ";}continue{print" : ""); sv_catpv(linestr,";}"); - oldoldbufptr = oldbufptr = s = SvPVX(linestr); + oldoldbufptr = oldbufptr = s = linestart = SvPVX(linestr); bufend = SvPVX(linestr) + SvCUR(linestr); minus_n = minus_p = 0; goto retry; } - oldoldbufptr = oldbufptr = s = SvPVX(linestr); + oldoldbufptr = oldbufptr = s = linestart = SvPVX(linestr); sv_setpv(linestr,""); TOKEN(';'); /* not infinite loop because rsfp is NULL now */ } @@ -1418,15 +1572,15 @@ yylex() /* Incest with pod. */ if (*s == '=' && strnEQ(s, "=cut", 4)) { sv_setpv(linestr, ""); - oldoldbufptr = oldbufptr = s = SvPVX(linestr); + oldoldbufptr = oldbufptr = s = linestart = SvPVX(linestr); bufend = SvPVX(linestr) + SvCUR(linestr); doextract = FALSE; } } incline(s); } while (doextract); - oldoldbufptr = oldbufptr = bufptr = s; - if (perldb && curstash != debstash) { + oldoldbufptr = oldbufptr = bufptr = linestart = s; + if (PERLDB_LINE && curstash != debstash) { SV *sv = NEWSV(85,0); sv_upgrade(sv, SVt_PVMG); @@ -1439,25 +1593,84 @@ yylex() s++; if (*s == ':' && s[1] != ':') /* for csh execing sh scripts */ s++; - if (!in_eval && *s == '#' && s[1] == '!') { + d = Nullch; + if (!in_eval) { + if (*s == '#' && *(s+1) == '!') + d = s + 2; +#ifdef ALTERNATE_SHEBANG + else { + static char as[] = ALTERNATE_SHEBANG; + if (*s == as[0] && strnEQ(s, as, sizeof(as) - 1)) + d = s + (sizeof(as) - 1); + } +#endif /* ALTERNATE_SHEBANG */ + } + if (d) { + char *ipath; + char *ipathend; + + while (isSPACE(*d)) + d++; + ipath = d; + while (*d && !isSPACE(*d)) + d++; + ipathend = d; + +#ifdef ARG_ZERO_IS_SCRIPT + if (ipathend > ipath) { + /* + * HP-UX (at least) sets argv[0] to the script name, + * which makes $^X incorrect. And Digital UNIX and Linux, + * at least, set argv[0] to the basename of the Perl + * interpreter. So, having found "#!", we'll set it right. + */ + SV *x = GvSV(gv_fetchpv("\030", TRUE, SVt_PV)); + assert(SvPOK(x) || SvGMAGICAL(x)); + if (sv_eq(x, GvSV(curcop->cop_filegv))) { + sv_setpvn(x, ipath, ipathend - ipath); + SvSETMAGIC(x); + } + TAINT_NOT; /* $^X is always tainted, but that's OK */ + } +#endif /* ARG_ZERO_IS_SCRIPT */ + + /* + * Look for options. + */ d = instr(s,"perl -"); if (!d) d = instr(s,"perl"); +#ifdef ALTERNATE_SHEBANG + /* + * If the ALTERNATE_SHEBANG on this system starts with a + * character that can be part of a Perl expression, then if + * we see it but not "perl", we're probably looking at the + * start of Perl code, not a request to hand off to some + * other interpreter. Similarly, if "perl" is there, but + * not in the first 'word' of the line, we assume the line + * contains the start of the Perl program. + */ + if (d && *s != '#') { + char *c = ipath; + while (*c && !strchr("; \t\r\n\f\v#", *c)) + c++; + if (c < d) + d = Nullch; /* "perl" not in first word; ignore */ + else + *s = '#'; /* Don't try to parse shebang line */ + } +#endif /* ALTERNATE_SHEBANG */ if (!d && + *s == '#' && + ipathend > ipath && !minus_c && !instr(s,"indir") && instr(origargv[0],"perl")) { char **newargv; - char *cmd; - s += 2; - if (*s == ' ') - s++; - cmd = s; - while (s < bufend && !isSPACE(*s)) - s++; - *s++ = '\0'; + *ipathend = '\0'; + s = ipathend + 1; while (s < bufend && isSPACE(*s)) s++; if (s < bufend) { @@ -1470,30 +1683,38 @@ yylex() } else newargv = origargv; - newargv[0] = cmd; - execv(cmd,newargv); - croak("Can't exec %s", cmd); + newargv[0] = ipath; + execv(ipath, newargv); + croak("Can't exec %s", ipath); } if (d) { - int oldpdb = perldb; - int oldn = minus_n; - int oldp = minus_p; + U32 oldpdb = perldb; + bool oldn = minus_n; + bool oldp = minus_p; while (*d && !isSPACE(*d)) d++; - while (*d == ' ') d++; + while (*d == ' ' || *d == '\t') d++; if (*d++ == '-') { - while (d = moreswitches(d)) ; - if (perldb && !oldpdb || + do { + if (*d == 'M' || *d == 'm') { + char *m = d; + while (*d && !isSPACE(*d)) d++; + croak("Too late for \"-%.*s\" option", + (int)(d - m), m); + } + d = moreswitches(d); + } while (d); + if (PERLDB_LINE && !oldpdb || ( minus_n || minus_p ) && !(oldn || oldp) ) /* if we have already added "LINE: while (<>) {", we must not do it again */ { sv_setpv(linestr, ""); - oldoldbufptr = oldbufptr = s = SvPVX(linestr); + oldoldbufptr = oldbufptr = s = linestart = SvPVX(linestr); bufend = SvPVX(linestr) + SvCUR(linestr); preambled = FALSE; - if (perldb) + if (PERLDB_LINE) (void)gv_fetchfile(origfilename); goto retry; } @@ -1507,7 +1728,11 @@ yylex() return yylex(); } goto retry; - case ' ': case '\t': case '\f': case '\r': case 013: + case '\r': + warn("Illegal character \\%03o (carriage return)", '\r'); + croak( + "(Maybe you didn't strip carriage returns after a network transfer?)\n"); + case ' ': case '\t': case '\f': case 013: s++; goto retry; case '#': @@ -1542,7 +1767,7 @@ yylex() if (strnEQ(s,"=>",2)) { if (dowarn) warn("Ambiguous use of -%c => resolved to \"-%c\" =>", - tmp, tmp); + (int)tmp, (int)tmp); s = force_word(bufptr,WORD,FALSE,FALSE,FALSE); OPERATOR('-'); /* unary minus */ } @@ -1577,7 +1802,7 @@ yylex() case 'A': gv_fetchpv("\024",TRUE, SVt_PV); FTST(OP_FTATIME); case 'C': gv_fetchpv("\024",TRUE, SVt_PV); FTST(OP_FTCTIME); default: - croak("Unrecognized file test: -%c", tmp); + croak("Unrecognized file test: -%c", (int)tmp); break; } } @@ -1628,7 +1853,7 @@ yylex() case '*': if (expect != XOPERATOR) { - s = scan_ident(s, bufend, tokenbuf, TRUE); + s = scan_ident(s, bufend, tokenbuf, sizeof tokenbuf, TRUE); expect = XOPERATOR; force_ident(tokenbuf, '*'); if (!*tokenbuf) @@ -1643,35 +1868,19 @@ yylex() Mop(OP_MULTIPLY); case '%': - if (expect != XOPERATOR) { - s = scan_ident(s, bufend, tokenbuf + 1, TRUE); - if (tokenbuf[1]) { - expect = XOPERATOR; - tokenbuf[0] = '%'; - if (in_my) { - if (strchr(tokenbuf,':')) - croak(no_myglob,tokenbuf); - nextval[nexttoke].opval = newOP(OP_PADANY, 0); - nextval[nexttoke].opval->op_targ = pad_allocmy(tokenbuf); - force_next(PRIVATEREF); - TERM('%'); - } - if (!strchr(tokenbuf,':')) { - if (tmp = pad_findmy(tokenbuf)) { - nextval[nexttoke].opval = newOP(OP_PADANY, 0); - nextval[nexttoke].opval->op_targ = tmp; - force_next(PRIVATEREF); - TERM('%'); - } - } - force_ident(tokenbuf + 1, *tokenbuf); - } - else - PREREF('%'); - TERM('%'); + if (expect == XOPERATOR) { + ++s; + Mop(OP_MODULO); + } + tokenbuf[0] = '%'; + s = scan_ident(s, bufend, tokenbuf + 1, sizeof tokenbuf - 1, TRUE); + if (!tokenbuf[1]) { + if (s == bufend) + yyerror("Final % should be \\% or %name"); + PREREF('%'); } - ++s; - Mop(OP_MODULO); + pending_ident = '%'; + TERM('%'); case '^': s++; @@ -1725,7 +1934,7 @@ yylex() leftbracket: s++; if (lex_brackets > 100) { - char* newlb = (char*)realloc(lex_brackstack, lex_brackets + 1); + char* newlb = Renew(lex_brackstack, lex_brackets + 1, char); if (newlb != lex_brackstack) { SAVEFREEPV(newlb); lex_brackstack = newlb; @@ -1742,21 +1951,33 @@ yylex() else lex_brackstack[lex_brackets++] = XOPERATOR; OPERATOR(HASHBRACK); - break; case XOPERATOR: while (s < bufend && (*s == ' ' || *s == '\t')) s++; - if (s < bufend && isALPHA(*s)) { - d = scan_word(s, tokenbuf, FALSE, &len); + d = s; + tokenbuf[0] = '\0'; + if (d < bufend && *d == '-') { + tokenbuf[0] = '-'; + d++; + while (d < bufend && (*d == ' ' || *d == '\t')) + d++; + } + if (d < bufend && isIDFIRST(*d)) { + d = scan_word(d, tokenbuf + 1, sizeof tokenbuf - 1, + FALSE, &len); while (d < bufend && (*d == ' ' || *d == '\t')) d++; if (*d == '}') { + char minus = (tokenbuf[0] == '-'); if (dowarn && - (keyword(tokenbuf, len) || - perl_get_cv(tokenbuf, FALSE) )) + (keyword(tokenbuf + 1, len) || + (minus && len == 1 && isALPHA(tokenbuf[1])) || + perl_get_cv(tokenbuf + 1, FALSE) )) warn("Ambiguous use of {%s} resolved to {\"%s\"}", - tokenbuf, tokenbuf); - s = force_word(s,WORD,FALSE,TRUE,FALSE); + tokenbuf + !minus, tokenbuf + !minus); + s = force_word(s + minus, WORD, FALSE, TRUE, FALSE); + if (minus) + force_next('-'); } } /* FALL THROUGH */ @@ -1777,19 +1998,73 @@ yylex() s = skipspace(s); if (*s == '}') OPERATOR(HASHBRACK); - if (isALPHA(*s)) { - for (t = s; t < bufend && isALNUM(*t); t++) ; + /* This hack serves to disambiguate a pair of curlies + * as being a block or an anon hash. Normally, expectation + * determines that, but in cases where we're not in a + * position to expect anything in particular (like inside + * eval"") we have to resolve the ambiguity. This code + * covers the case where the first term in the curlies is a + * quoted string. Most other cases need to be explicitly + * disambiguated by prepending a `+' before the opening + * curly in order to force resolution as an anon hash. + * + * XXX should probably propagate the outer expectation + * into eval"" to rely less on this hack, but that could + * potentially break current behavior of eval"". + * GSAR 97-07-21 + */ + t = s; + if (*s == '\'' || *s == '"' || *s == '`') { + /* common case: get past first string, handling escapes */ + for (t++; t < bufend && *t != *s;) + if (*t++ == '\\' && (*t == '\\' || *t == *s)) + t++; + t++; } - else if (*s == '\'' || *s == '"') { - t = strchr(s+1,*s); - if (!t++) - t = s; + else if (*s == 'q') { + if (++t < bufend + && (!isALNUM(*t) + || ((*t == 'q' || *t == 'x') && ++t < bufend + && !isALNUM(*t)))) { + char *tmps; + char open, close, term; + I32 brackets = 1; + + while (t < bufend && isSPACE(*t)) + t++; + term = *t; + open = term; + if (term && (tmps = strchr("([{< )]}> )]}>",term))) + term = tmps[5]; + close = term; + if (open == close) + for (t++; t < bufend; t++) { + if (*t == '\\' && t+1 < bufend && open != '\\') + t++; + else if (*t == open) + break; + } + else + for (t++; t < bufend; t++) { + if (*t == '\\' && t+1 < bufend) + t++; + else if (*t == close && --brackets <= 0) + break; + else if (*t == open) + brackets++; + } + } + t++; + } + else if (isALPHA(*s)) { + for (t++; t < bufend && isALNUM(*t); t++) ; } - else - t = s; while (t < bufend && isSPACE(*t)) t++; - if ((*t == ',' && !isLOWER(*s)) || (*t == '=' && t[1] == '>')) + /* if comma follows first term, call it an anon hash */ + /* XXX it could be a comma expression with loop modifiers */ + if (t < bufend && ((*t == ',' && (*s == 'q' || !isLOWER(*s))) + || (*t == '=' && t[1] == '>'))) OPERATOR(HASHBRACK); if (expect == XREF) expect = XTERM; @@ -1820,7 +2095,9 @@ yylex() bufptr = s; return yylex(); /* ignore fake brackets */ } - if (*s != '[' && *s != '{' && (*s != '-' || s[1] != '>')) + if (*s == '-' && s[1] == '>') + lex_state = LEX_INTERPENDMAYBE; + else if (*s != '[' && *s != '{') lex_state = LEX_INTERPEND; } } @@ -1838,7 +2115,7 @@ yylex() AOPERATOR(ANDAND); s--; if (expect == XOPERATOR) { - if (dowarn && isALPHA(*s) && bufptr == SvPVX(linestr)) { + if (dowarn && isALPHA(*s) && bufptr == linestart) { curcop->cop_line--; warn(warn_nosemi); curcop->cop_line++; @@ -1846,7 +2123,7 @@ yylex() BAop(OP_BIT_AND); } - s = scan_ident(s-1, bufend, tokenbuf, TRUE); + s = scan_ident(s - 1, bufend, tokenbuf, sizeof tokenbuf, TRUE); if (*tokenbuf) { expect = XOPERATOR; force_ident(tokenbuf, '&'); @@ -1873,10 +2150,10 @@ yylex() if (tmp == '~') PMop(OP_MATCH); if (dowarn && tmp && isSPACE(*s) && strchr("+-*/%.^&|<",tmp)) - warn("Reversed %c= operator",tmp); + warn("Reversed %c= operator",(int)tmp); s--; if (expect == XSTATE && isALPHA(tmp) && - (s == SvPVX(linestr)+1 || s[-2] == '\n') ) + (s == linestart+1 || s[-2] == '\n') ) { if (in_eval && !rsfp) { d = bufend; @@ -1954,184 +2231,147 @@ yylex() Rop(OP_GT); case '$': - if (s[1] == '#' && (isALPHA(s[2]) || strchr("_{$:", s[2]))) { - s = scan_ident(s+1, bufend, tokenbuf+1, FALSE); - if (expect == XOPERATOR) { - if (lex_formbrack && lex_brackets == lex_formbrack) { - expect = XTERM; - depcom(); - return ','; /* grandfather non-comma-format format */ - } - else - no_op("Array length",s); - } - else if (!tokenbuf[1]) - PREREF(DOLSHARP); - if (!strchr(tokenbuf+1,':')) { - tokenbuf[0] = '@'; - if (tmp = pad_findmy(tokenbuf)) { - nextval[nexttoke].opval = newOP(OP_PADANY, 0); - nextval[nexttoke].opval->op_targ = tmp; - expect = XOPERATOR; - force_next(PRIVATEREF); - TOKEN(DOLSHARP); - } - } - expect = XOPERATOR; - force_ident(tokenbuf+1, *tokenbuf); - TOKEN(DOLSHARP); - } - s = scan_ident(s, bufend, tokenbuf+1, FALSE); + CLINE; + if (expect == XOPERATOR) { if (lex_formbrack && lex_brackets == lex_formbrack) { expect = XTERM; depcom(); - return ','; /* grandfather non-comma-format format */ + return ','; /* grandfather non-comma-format format */ } - else - no_op("Scalar",s); } - if (tokenbuf[1]) { - expectation oldexpect = expect; - /* This kludge not intended to be bulletproof. */ - if (tokenbuf[1] == '[' && !tokenbuf[2]) { - yylval.opval = newSVOP(OP_CONST, 0, - newSViv((IV)compiling.cop_arybase)); - yylval.opval->op_private = OPpCONST_ARYBASE; - TERM(THING); - } - tokenbuf[0] = '$'; - if (dowarn) { - char *t; - if (*s == '[' && oldexpect != XREF) { - for (t = s+1; isSPACE(*t) || isALNUM(*t) || *t == '$'; t++) ; + if (s[1] == '#' && (isALPHA(s[2]) || strchr("_{$:", s[2]))) { + if (expect == XOPERATOR) + no_op("Array length", bufptr); + tokenbuf[0] = '@'; + s = scan_ident(s + 1, bufend, tokenbuf + 1, sizeof tokenbuf - 1, + FALSE); + if (!tokenbuf[1]) + PREREF(DOLSHARP); + expect = XOPERATOR; + pending_ident = '#'; + TOKEN(DOLSHARP); + } + + if (expect == XOPERATOR) + no_op("Scalar", bufptr); + tokenbuf[0] = '$'; + s = scan_ident(s, bufend, tokenbuf + 1, sizeof tokenbuf - 1, FALSE); + if (!tokenbuf[1]) { + if (s == bufend) + yyerror("Final $ should be \\$ or $name"); + PREREF('$'); + } + + /* This kludge not intended to be bulletproof. */ + if (tokenbuf[1] == '[' && !tokenbuf[2]) { + yylval.opval = newSVOP(OP_CONST, 0, + newSViv((IV)compiling.cop_arybase)); + yylval.opval->op_private = OPpCONST_ARYBASE; + TERM(THING); + } + + d = s; + if (lex_state == LEX_NORMAL) + s = skipspace(s); + + if ((expect != XREF || oldoldbufptr == last_lop) && intuit_more(s)) { + char *t; + if (*s == '[') { + tokenbuf[0] = '@'; + if (dowarn) { + for(t = s + 1; + isSPACE(*t) || isALNUM(*t) || *t == '$'; + t++) ; if (*t++ == ',') { bufptr = skipspace(bufptr); - while (t < bufend && *t != ']') t++; + while (t < bufend && *t != ']') + t++; warn("Multidimensional syntax %.*s not supported", - t-bufptr+1, bufptr); + (t - bufptr) + 1, bufptr); } } - if (*s == '{' && strEQ(tokenbuf, "$SIG") && - (t = strchr(s,'}')) && (t = strchr(t,'='))) { - char tmpbuf[1024]; + } + else if (*s == '{') { + tokenbuf[0] = '%'; + if (dowarn && strEQ(tokenbuf+1, "SIG") && + (t = strchr(s, '}')) && (t = strchr(t, '='))) + { + char tmpbuf[sizeof tokenbuf]; STRLEN len; for (t++; isSPACE(*t); t++) ; if (isIDFIRST(*t)) { - t = scan_word(t, tmpbuf, TRUE, &len); + t = scan_word(t, tmpbuf, sizeof tmpbuf, TRUE, &len); if (*t != '(' && perl_get_cv(tmpbuf, FALSE)) warn("You need to quote \"%s\"", tmpbuf); } } } - expect = XOPERATOR; - if (lex_state == LEX_NORMAL && isSPACE(*s)) { - bool islop = (last_lop == oldoldbufptr); - s = skipspace(s); - if (!islop || last_lop_op == OP_GREPSTART) - expect = XOPERATOR; - else if (strchr("$@\"'`q", *s)) - expect = XTERM; /* e.g. print $fh "foo" */ - else if (strchr("&*<%", *s) && isIDFIRST(s[1])) - expect = XTERM; /* e.g. print $fh &sub */ - else if (isDIGIT(*s)) - expect = XTERM; /* e.g. print $fh 3 */ - else if (*s == '.' && isDIGIT(s[1])) - expect = XTERM; /* e.g. print $fh .3 */ - else if (strchr("/?-+", *s) && !isSPACE(s[1])) - expect = XTERM; /* e.g. print $fh -1 */ - else if (*s == '<' && s[1] == '<' && !isSPACE(s[2])) - expect = XTERM; /* print $fh <<"EOF" */ - } - if (in_my) { - if (strchr(tokenbuf,':')) - croak(no_myglob,tokenbuf); - nextval[nexttoke].opval = newOP(OP_PADANY, 0); - nextval[nexttoke].opval->op_targ = pad_allocmy(tokenbuf); - force_next(PRIVATEREF); - } - else if (!strchr(tokenbuf,':')) { - if (oldexpect != XREF || oldoldbufptr == last_lop) { - if (intuit_more(s)) { - if (*s == '[') - tokenbuf[0] = '@'; - else if (*s == '{') - tokenbuf[0] = '%'; + } + + expect = XOPERATOR; + if (lex_state == LEX_NORMAL && isSPACE(*d)) { + bool islop = (last_lop == oldoldbufptr); + if (!islop || last_lop_op == OP_GREPSTART) + expect = XOPERATOR; + else if (strchr("$@\"'`q", *s)) + expect = XTERM; /* e.g. print $fh "foo" */ + else if (strchr("&*<%", *s) && isIDFIRST(s[1])) + expect = XTERM; /* e.g. print $fh &sub */ + else if (isIDFIRST(*s)) { + char tmpbuf[sizeof tokenbuf]; + scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len); + if (tmp = keyword(tmpbuf, len)) { + /* binary operators exclude handle interpretations */ + switch (tmp) { + case -KEY_x: + case -KEY_eq: + case -KEY_ne: + case -KEY_gt: + case -KEY_lt: + case -KEY_ge: + case -KEY_le: + case -KEY_cmp: + break; + default: + expect = XTERM; /* e.g. print $fh length() */ + break; } } - if (tmp = pad_findmy(tokenbuf)) { - if (!tokenbuf[2] && *tokenbuf =='$' && - tokenbuf[1] <= 'b' && tokenbuf[1] >= 'a') - { - for (d = in_eval ? oldoldbufptr : SvPVX(linestr); - d < bufend && *d != '\n'; - d++) - { - if (strnEQ(d,"<=>",3) || strnEQ(d,"cmp",3)) { - croak("Can't use \"my %s\" in sort comparison", - tokenbuf); - } - } - } - nextval[nexttoke].opval = newOP(OP_PADANY, 0); - nextval[nexttoke].opval->op_targ = tmp; - force_next(PRIVATEREF); + else { + GV *gv = gv_fetchpv(tmpbuf, FALSE, SVt_PVCV); + if (gv && GvCVu(gv)) + expect = XTERM; /* e.g. print $fh subr() */ } - else - force_ident(tokenbuf+1, *tokenbuf); } - else - force_ident(tokenbuf+1, *tokenbuf); - } - else { - if (s == bufend) - yyerror("Final $ should be \\$ or $name"); - PREREF('$'); - } + else if (isDIGIT(*s)) + expect = XTERM; /* e.g. print $fh 3 */ + else if (*s == '.' && isDIGIT(s[1])) + expect = XTERM; /* e.g. print $fh .3 */ + else if (strchr("/?-+", *s) && !isSPACE(s[1])) + expect = XTERM; /* e.g. print $fh -1 */ + else if (*s == '<' && s[1] == '<' && !isSPACE(s[2])) + expect = XTERM; /* print $fh <<"EOF" */ + } + pending_ident = '$'; TOKEN('$'); case '@': - s = scan_ident(s, bufend, tokenbuf+1, FALSE); if (expect == XOPERATOR) - no_op("Array",s); - if (tokenbuf[1]) { - GV* gv; - - tokenbuf[0] = '@'; - expect = XOPERATOR; - if (in_my) { - if (strchr(tokenbuf,':')) - croak(no_myglob,tokenbuf); - nextval[nexttoke].opval = newOP(OP_PADANY, 0); - nextval[nexttoke].opval->op_targ = pad_allocmy(tokenbuf); - force_next(PRIVATEREF); - TERM('@'); - } - else if (!strchr(tokenbuf,':')) { - if (intuit_more(s)) { - if (*s == '{') - tokenbuf[0] = '%'; - } - if (tmp = pad_findmy(tokenbuf)) { - nextval[nexttoke].opval = newOP(OP_PADANY, 0); - nextval[nexttoke].opval->op_targ = tmp; - force_next(PRIVATEREF); - TERM('@'); - } - } - - /* Force them to make up their mind on "@foo". */ - if (lex_state != LEX_NORMAL && !lex_brackets && - ( !(gv = gv_fetchpv(tokenbuf+1, FALSE, SVt_PVAV)) || - (*tokenbuf == '@' - ? !GvAV(gv) - : !GvHV(gv) ))) - { - char tmpbuf[1024]; - sprintf(tmpbuf, "Literal @%s now requires backslash",tokenbuf+1); - yyerror(tmpbuf); - } + no_op("Array", s); + tokenbuf[0] = '@'; + s = scan_ident(s, bufend, tokenbuf + 1, sizeof tokenbuf - 1, FALSE); + if (!tokenbuf[1]) { + if (s == bufend) + yyerror("Final @ should be \\@ or @name"); + PREREF('@'); + } + if (lex_state == LEX_NORMAL) + s = skipspace(s); + if ((expect != XREF || oldoldbufptr == last_lop) && intuit_more(s)) { + if (*s == '{') + tokenbuf[0] = '%'; /* Warn about @ where they meant $. */ if (dowarn) { @@ -2147,13 +2387,8 @@ yylex() } } } - force_ident(tokenbuf+1, *tokenbuf); - } - else { - if (s == bufend) - yyerror("Final @ should be \\@ or @name"); - PREREF('@'); } + pending_ident = '@'; TERM('@'); case '/': /* may either be division or pattern */ @@ -2170,7 +2405,7 @@ yylex() case '.': if (lex_formbrack && lex_brackets == lex_formbrack && s[1] == '\n' && - (s == SvPVX(linestr) || s[-1] == '\n') ) { + (s == linestart || s[-1] == '\n') ) { lex_formbrack = 0; expect = XSTATE; goto rightbracket; @@ -2292,17 +2527,35 @@ yylex() keylookup: bufptr = s; - s = scan_word(s, tokenbuf, FALSE, &len); - - if (*s == ':' && s[1] == ':' && strNE(tokenbuf, "CORE")) + s = scan_word(s, tokenbuf, sizeof tokenbuf, FALSE, &len); + + /* Some keywords can be followed by any delimiter, including ':' */ + tmp = (len == 1 && strchr("msyq", tokenbuf[0]) || + len == 2 && ((tokenbuf[0] == 't' && tokenbuf[1] == 'r') || + (tokenbuf[0] == 'q' && + strchr("qwx", tokenbuf[1])))); + + /* x::* is just a word, unless x is "CORE" */ + if (!tmp && *s == ':' && s[1] == ':' && strNE(tokenbuf, "CORE")) goto just_a_word; + d = s; + while (d < bufend && isSPACE(*d)) + d++; /* no comments skipped here, or s### is misparsed */ + + /* Is this a label? */ + if (!tmp && expect == XSTATE + && d < bufend && *d == ':' && *(d + 1) != ':') { + s = d + 1; + yylval.pval = savepv(tokenbuf); + CLINE; + TOKEN(LABEL); + } + + /* Check for keywords */ tmp = keyword(tokenbuf, len); /* Is this a word before a => operator? */ - d = s; - while (d < bufend && (*d == ' ' || *d == '\t')) - d++; /* no comments skipped here, or s### is misparsed */ if (strnEQ(d,"=>",2)) { CLINE; if (dowarn && (tmp || perl_get_cv(tokenbuf, FALSE))) @@ -2332,35 +2585,26 @@ yylex() default: /* not a keyword */ just_a_word: { GV *gv; + SV *sv; char lastchar = (bufptr == oldoldbufptr ? 0 : bufptr[-1]); /* Get the rest if it looks like a package qualifier */ if (*s == '\'' || *s == ':' && s[1] == ':') { - s = scan_word(s, tokenbuf + len, TRUE, &len); + s = scan_word(s, tokenbuf + len, sizeof tokenbuf - len, + TRUE, &len); if (!len) croak("Bad name after %s::", tokenbuf); } - /* Do special processing at start of statement. */ - - if (expect == XSTATE) { - while (isSPACE(*s)) s++; - if (*s == ':') { /* It's a label. */ - yylval.pval = savepv(tokenbuf); - s++; - CLINE; - TOKEN(LABEL); - } - } - else if (expect == XOPERATOR) { - if (bufptr == SvPVX(linestr)) { + if (expect == XOPERATOR) { + if (bufptr == linestart) { curcop->cop_line--; warn(warn_nosemi); curcop->cop_line++; } else - no_op("Bare word",s); + no_op("Bareword",s); } /* Look for a subroutine with this name in current package. */ @@ -2396,7 +2640,7 @@ yylex() /* (But it's an indir obj regardless for sort.) */ if ((last_lop_op == OP_SORT || - (!immediate_paren && (!gv || !GvCV(gv))) ) && + (!immediate_paren && (!gv || !GvCVu(gv))) ) && (last_lop_op != OP_MAPSTART && last_lop_op != OP_GREPSTART)){ expect = (last_lop == oldoldbufptr) ? XTERM : XOPERATOR; goto bareword; @@ -2409,6 +2653,13 @@ yylex() s = skipspace(s); if (*s == '(') { CLINE; + if (gv && GvCVu(gv)) { + for (d = s + 1; *d == ' ' || *d == '\t'; d++) ; + if (*d == ')' && (sv = cv_const_sv(GvCV(gv)))) { + s = d + 1; + goto its_constant; + } + } nextval[nexttoke].opval = yylval.opval; expect = XOPERATOR; force_next(WORD); @@ -2418,7 +2669,7 @@ yylex() /* If followed by var or block, call it a method (unless sub) */ - if ((*s == '$' || *s == '{') && (!gv || !GvCV(gv))) { + if ((*s == '$' || *s == '{') && (!gv || !GvCVu(gv))) { last_lop = oldbufptr; last_lop_op = OP_METHOD; PREBLOCK(METHOD); @@ -2431,20 +2682,23 @@ yylex() /* Not a method, so call it a subroutine (if defined) */ - if (gv && GvCV(gv)) { - CV* cv = GvCV(gv); - if (*s == '(') { - nextval[nexttoke].opval = yylval.opval; - expect = XTERM; - force_next(WORD); - yylval.ival = 0; - TOKEN('&'); - } + if (gv && GvCVu(gv)) { + CV* cv; if (lastchar == '-') warn("Ambiguous use of -%s resolved as -&%s()", tokenbuf, tokenbuf); last_lop = oldbufptr; last_lop_op = OP_ENTERSUB; + /* Check for a constant sub */ + cv = GvCV(gv); + if ((sv = cv_const_sv(cv))) { + its_constant: + SvREFCNT_dec(((SVOP*)yylval.opval)->op_sv); + ((SVOP*)yylval.opval)->op_sv = SvREFCNT_inc(sv); + yylval.opval->op_private = 0; + TOKEN(WORD); + } + /* Resolve to GV now. */ op_free(yylval.opval); yylval.opval = newCVREF(0, newGVOP(OP_GV, 0, gv)); @@ -2470,6 +2724,7 @@ yylex() if (hints & HINT_STRICT_SUBS && lastchar != '-' && strnNE(s,"->",2) && + last_lop_op != OP_TRUNCATE && /* S/F prototype in opcode.pl */ last_lop_op != OP_ACCEPT && last_lop_op != OP_PIPE_OP && last_lop_op != OP_SOCKPAIR) @@ -2499,15 +2754,22 @@ yylex() TOKEN(WORD); } + case KEY___FILE__: + yylval.opval = (OP*)newSVOP(OP_CONST, 0, + newSVsv(GvSV(curcop->cop_filegv))); + TERM(THING); + case KEY___LINE__: - case KEY___FILE__: { - if (tokenbuf[2] == 'L') - (void)sprintf(tokenbuf,"%ld",(long)curcop->cop_line); - else - strcpy(tokenbuf, SvPVX(GvSV(curcop->cop_filegv))); - yylval.opval = (OP*)newSVOP(OP_CONST, 0, newSVpv(tokenbuf,0)); + yylval.opval = (OP*)newSVOP(OP_CONST, 0, + newSVpvf("%ld", (long)curcop->cop_line)); + TERM(THING); + + case KEY___PACKAGE__: + yylval.opval = (OP*)newSVOP(OP_CONST, 0, + (curstash + ? newSVsv(curstname) + : &sv_undef)); TERM(THING); - } case KEY___DATA__: case KEY___END__: { @@ -2515,25 +2777,25 @@ yylex() /*SUPPRESS 560*/ if (rsfp && (!in_eval || tokenbuf[2] == 'D')) { - char dname[256]; char *pname = "main"; if (tokenbuf[2] == 'D') pname = HvNAME(curstash ? curstash : defstash); - sprintf(dname,"%s::DATA", pname); - gv = gv_fetchpv(dname,TRUE, SVt_PVIO); + gv = gv_fetchpv(form("%s::DATA", pname), TRUE, SVt_PVIO); GvMULTI_on(gv); if (!GvIO(gv)) GvIOp(gv) = newIO(); IoIFP(GvIOp(gv)) = rsfp; #if defined(HAS_FCNTL) && defined(F_SETFD) { - int fd = fileno(rsfp); + int fd = PerlIO_fileno(rsfp); fcntl(fd,F_SETFD,fd >= 3); } #endif + /* Mark this internal pseudo-handle as clean */ + IoFLAGS(GvIOp(gv)) |= IOf_UNTAINT; if (preprocess) IoTYPE(GvIOp(gv)) = '|'; - else if ((FILE*)rsfp == stdin) + else if ((PerlIO*)rsfp == PerlIO_stdin()) IoTYPE(GvIOp(gv)) = '-'; else IoTYPE(GvIOp(gv)) = '<'; @@ -2556,7 +2818,7 @@ yylex() if (*s == ':' && s[1] == ':') { s += 2; d = s; - s = scan_word(s, tokenbuf, FALSE, &len); + s = scan_word(s, tokenbuf, sizeof tokenbuf, FALSE, &len); tmp = keyword(tokenbuf, len); if (tmp < 0) tmp = -tmp; @@ -2724,10 +2986,16 @@ yylex() case KEY_for: case KEY_foreach: yylval.ival = curcop->cop_line; - while (s < bufend && isSPACE(*s)) - s++; - if (isIDFIRST(*s)) - croak("Missing $ on loop variable"); + s = skipspace(s); + if (isIDFIRST(*s)) { + char *p = s; + if ((bufend - p) >= 3 && + strnEQ(p, "my", 2) && isSPACE(*(p + 2))) + p += 2; + p = skipspace(p); + if (isIDFIRST(*p)) + croak("Missing $ on loop variable"); + } OPERATOR(FOR); case KEY_formline: @@ -2786,10 +3054,10 @@ yylex() FUN0(OP_GPWENT); case KEY_getpwnam: - FUN1(OP_GPWNAM); + UNI(OP_GPWNAM); case KEY_getpwuid: - FUN1(OP_GPWUID); + UNI(OP_GPWUID); case KEY_getpeername: UNI(OP_GETPEERNAME); @@ -2831,10 +3099,10 @@ yylex() FUN0(OP_GGRENT); case KEY_getgrnam: - FUN1(OP_GGRNAM); + UNI(OP_GGRNAM); case KEY_getgrgid: - FUN1(OP_GGRGID); + UNI(OP_GGRGID); case KEY_getlogin: FUN0(OP_GETLOGIN); @@ -2879,7 +3147,6 @@ yylex() UNI(OP_LCFIRST); case KEY_local: - yylval.ival = 0; OPERATOR(LOCAL); case KEY_length: @@ -2930,8 +3197,7 @@ yylex() case KEY_my: in_my = TRUE; - yylval.ival = 1; - OPERATOR(LOCAL); + OPERATOR(MY); case KEY_next: s = force_word(s,WORD,TRUE,FALSE,FALSE); @@ -2944,6 +3210,7 @@ yylex() if (expect != XSTATE) yyerror("\"no\" not allowed in expression"); s = force_word(s,WORD,FALSE,TRUE,FALSE); + s = force_version(s); yylval.ival = 0; OPERATOR(USE); @@ -3019,6 +3286,19 @@ yylex() s = scan_str(s); if (!s) missingterm((char*)0); + if (dowarn && SvLEN(lex_stuff)) { + d = SvPV_force(lex_stuff, len); + for (; len; --len, ++d) { + if (*d == ',') { + warn("Possible attempt to separate words with commas"); + break; + } + if (*d == '#') { + warn("Possible attempt to put comments in qw() list"); + break; + } + } + } force_next(')'); nextval[nexttoke].opval = (OP*)newSVOP(OP_CONST, 0, q(lex_stuff)); lex_stuff = Nullsv; @@ -3059,7 +3339,7 @@ yylex() *tokenbuf = '\0'; s = force_word(s,WORD,TRUE,TRUE,FALSE); if (isIDFIRST(*tokenbuf)) - gv_stashpv(tokenbuf, TRUE); + gv_stashpvn(tokenbuf, strlen(tokenbuf), TRUE); else if (*s == '<') yyerror("<> should be quotes"); UNI(OP_REQUIRE); @@ -3150,16 +3430,16 @@ yylex() LOP(OP_SETPRIORITY,XTERM); case KEY_sethostent: - FUN1(OP_SHOSTENT); + UNI(OP_SHOSTENT); case KEY_setnetent: - FUN1(OP_SNETENT); + UNI(OP_SNETENT); case KEY_setservent: - FUN1(OP_SSERVENT); + UNI(OP_SSERVENT); case KEY_setprotoent: - FUN1(OP_SPROTOENT); + UNI(OP_SPROTOENT); case KEY_setpwent: FUN0(OP_SPWENT); @@ -3243,9 +3523,9 @@ yylex() s = skipspace(s); if (isIDFIRST(*s) || *s == '\'' || *s == ':') { - char tmpbuf[128]; + char tmpbuf[sizeof tokenbuf]; expect = XBLOCK; - d = scan_word(s, tmpbuf, TRUE, &len); + d = scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len); if (strchr(tmpbuf, ':')) sv_setpv(subname, tmpbuf); else { @@ -3270,6 +3550,8 @@ yylex() /* Look for a prototype */ if (*s == '(') { + char *p; + s = scan_str(s); if (!s) { if (lex_stuff) @@ -3277,6 +3559,16 @@ yylex() lex_stuff = Nullsv; croak("Prototype not terminated"); } + /* strip spaces */ + d = SvPVX(lex_stuff); + tmp = 0; + for (p = d; *p; ++p) { + if (!isSPACE(*p)) + d[tmp++] = *p; + } + d[tmp] = '\0'; + SvCUR(lex_stuff) = tmp; + nexttoke++; nextval[1] = nextval[0]; nexttype[1] = nexttype[0]; @@ -3309,6 +3601,9 @@ yylex() case KEY_sysopen: LOP(OP_SYSOPEN,XTERM); + case KEY_sysseek: + LOP(OP_SYSSEEK,XTERM); + case KEY_sysread: LOP(OP_SYSREAD,XTERM); @@ -3383,7 +3678,18 @@ yylex() case KEY_use: if (expect != XSTATE) yyerror("\"use\" not allowed in expression"); - s = force_word(s,WORD,FALSE,TRUE,FALSE); + s = skipspace(s); + if(isDIGIT(*s)) { + s = force_version(s); + if(*s == ';' || (s = skipspace(s), *s == ';')) { + nextval[nexttoke].opval = Nullop; + force_next(WORD); + } + } + else { + s = force_word(s,WORD,FALSE,TRUE,FALSE); + s = force_version(s); + } yylval.ival = 1; OPERATOR(USE); @@ -3440,8 +3746,9 @@ I32 len; switch (*d) { case '_': if (d[1] == '_') { - if (strEQ(d,"__LINE__")) return -KEY___LINE__; if (strEQ(d,"__FILE__")) return -KEY___FILE__; + if (strEQ(d,"__LINE__")) return -KEY___LINE__; + if (strEQ(d,"__PACKAGE__")) return -KEY___PACKAGE__; if (strEQ(d,"__DATA__")) return KEY___DATA__; if (strEQ(d,"__END__")) return KEY___END__; } @@ -3668,7 +3975,7 @@ I32 len; case 4: if (strEQ(d,"grep")) return KEY_grep; if (strEQ(d,"goto")) return KEY_goto; - if (strEQ(d,"glob")) return -KEY_glob; + if (strEQ(d,"glob")) return KEY_glob; break; case 6: if (strEQ(d,"gmtime")) return -KEY_gmtime; @@ -3947,10 +4254,11 @@ I32 len; if (strEQ(d,"system")) return -KEY_system; break; case 7: - if (strEQ(d,"sysopen")) return -KEY_sysopen; - if (strEQ(d,"sysread")) return -KEY_sysread; if (strEQ(d,"symlink")) return -KEY_symlink; if (strEQ(d,"syscall")) return -KEY_syscall; + if (strEQ(d,"sysopen")) return -KEY_sysopen; + if (strEQ(d,"sysread")) return -KEY_sysread; + if (strEQ(d,"sysseek")) return -KEY_sysseek; break; case 8: if (strEQ(d,"syswrite")) return -KEY_syswrite; @@ -4062,7 +4370,7 @@ char *what; } if (*w) for (; *w && isSPACE(*w); w++) ; - if (!*w || !strchr(";|})]oa!=", *w)) /* an advisory hack only... */ + if (!*w || !strchr(";|})]oaiuw!=", *w)) /* an advisory hack only... */ warn("%s (...) interpreted as function",name); } while (s < bufend && isSPACE(*s)) @@ -4090,14 +4398,18 @@ char *what; } static char * -scan_word(s, dest, allow_package, slp) +scan_word(s, dest, destlen, allow_package, slp) register char *s; char *dest; +STRLEN destlen; int allow_package; STRLEN *slp; { register char *d = dest; + register char *e = d + destlen - 3; /* two-character token, ending NUL */ for (;;) { + if (d >= e) + croak(ident_too_long); if (isALNUM(*s)) *d++ = *s++; else if (*s == '\'' && allow_package && isIDFIRST(s[1])) { @@ -4118,13 +4430,15 @@ STRLEN *slp; } static char * -scan_ident(s,send,dest,ck_uni) +scan_ident(s, send, dest, destlen, ck_uni) register char *s; register char *send; char *dest; +STRLEN destlen; I32 ck_uni; { register char *d; + register char *e; char *bracket = 0; char funny = *s++; @@ -4133,12 +4447,18 @@ I32 ck_uni; if (isSPACE(*s)) s = skipspace(s); d = dest; + e = d + destlen - 3; /* two-character token, ending NUL */ if (isDIGIT(*s)) { - while (isDIGIT(*s)) + while (isDIGIT(*s)) { + if (d >= e) + croak(ident_too_long); *d++ = *s++; + } } else { for (;;) { + if (d >= e) + croak(ident_too_long); if (isALNUM(*s)) *d++ = *s++; else if (*s == '\'' && isIDFIRST(s[1])) { @@ -4162,8 +4482,13 @@ I32 ck_uni; return s; } if (*s == '$' && s[1] && - (isALPHA(s[1]) || strchr("$_{", s[1]) || strnEQ(s+1,"::",2)) ) - return s; + (isALNUM(s[1]) || strchr("${", s[1]) || strnEQ(s+1,"::",2)) ) + { + if (isDIGIT(s[1]) && lex_state == LEX_INTERPNORMAL) + deprecate("\"$$<digit>\" to mean \"${$}<digit>\""); + else + return s; + } if (*s == '{') { bracket = s; s++; @@ -4174,20 +4499,26 @@ I32 ck_uni; *d = *s++; d[1] = '\0'; if (*d == '^' && *s && (isUPPER(*s) || strchr("[\\]^_?", *s))) { - *d = *s++ ^ 64; + *d = toCTRL(*s); + s++; } if (bracket) { if (isSPACE(s[-1])) { - while (s < send && (*s == ' ' || *s == '\t')) s++; - *d = *s; + while (s < send) { + char ch = *s++; + if (ch != ' ' && ch != '\t') { + *d = ch; + break; + } + } } - if (isALPHA(*d) || *d == '_') { + if (isIDFIRST(*d)) { d++; while (isALNUM(*s) || *s == ':') *d++ = *s++; *d = '\0'; while (s < send && (*s == ' ' || *s == '\t')) s++; - if ((*s == '[' || *s == '{')) { + if ((*s == '[' || (*s == '{' && strNE(dest, "sub")))) { if (dowarn && keyword(dest, d - dest)) { char *brack = *s == '[' ? "[...]" : "{...}"; warn("Ambiguous use of %c{%s%s} resolved to %c%s%s", @@ -4205,7 +4536,7 @@ I32 ck_uni; lex_state = LEX_INTERPEND; if (funny == '#') funny = '@'; - if (dowarn && + if (dowarn && lex_state == LEX_NORMAL && (keyword(dest, d - dest) || perl_get_cv(dest, FALSE))) warn("Ambiguous use of %c{%s} resolved to %c%s", funny, dest, funny, dest); @@ -4224,12 +4555,12 @@ void pmflag(pmfl,ch) U16* pmfl; int ch; { - if (ch == 'i') { - sawi = TRUE; + if (ch == 'i') *pmfl |= PMf_FOLD; - } else if (ch == 'g') *pmfl |= PMf_GLOBAL; + else if (ch == 'c') + *pmfl |= PMf_CONTINUE; else if (ch == 'o') *pmfl |= PMf_KEEP; else if (ch == 'm') @@ -4254,14 +4585,14 @@ char *start; lex_stuff = Nullsv; croak("Search pattern not terminated"); } + pm = (PMOP*)newPMOP(OP_MATCH, 0); if (multi_open == '?') pm->op_pmflags |= PMf_ONCE; - - while (*s && strchr("iogmsx", *s)) + while (*s && strchr("iogcmsx", *s)) pmflag(&pm->op_pmflags,*s++); - pm->op_pmpermflags = pm->op_pmflags; + lex_op = (OP*)pm; yylval.ival = OP_MATCH; return s; @@ -4273,6 +4604,7 @@ char *start; { register char *s; register PMOP *pm; + I32 first_start; I32 es = 0; yylval.ival = OP_NULL; @@ -4289,6 +4621,7 @@ char *start; if (s[-1] == multi_open) s--; + first_start = multi_start; s = scan_str(s); if (!s) { if (lex_stuff) @@ -4299,9 +4632,10 @@ char *start; lex_repl = Nullsv; croak("Substitution replacement not terminated"); } + multi_start = first_start; /* so whole substitution is taken together */ pm = (PMOP*)newPMOP(OP_SUBST, 0); - while (*s && strchr("iogmsex", *s)) { + while (*s && strchr("iogcmsex", *s)) { if (*s == 'e') { s++; es++; @@ -4339,8 +4673,6 @@ register PMOP *pm; ) { if (!(pm->op_pmregexp->reganch & ROPT_ANCH)) pm->op_pmflags |= PMf_SCANFIRST; - else if (pm->op_pmflags & PMf_FOLD) - return; pm->op_pmshort = SvREFCNT_inc(pm->op_pmregexp->regstart); pm->op_pmslen = SvCUR(pm->op_pmshort); } @@ -4358,9 +4690,11 @@ register PMOP *pm; return; } } - if (!pm->op_pmshort || /* promote the better string */ - ((pm->op_pmflags & PMf_SCANFIRST) && - (SvCUR(pm->op_pmshort) < SvCUR(pm->op_pmregexp->regmust)) )){ + /* promote the better string */ + if ((!pm->op_pmshort && + !(pm->op_pmregexp->reganch & ROPT_ANCH_GPOS)) || + ((pm->op_pmflags & PMf_SCANFIRST) && + (SvCUR(pm->op_pmshort) < SvCUR(pm->op_pmregexp->regmust)))) { SvREFCNT_dec(pm->op_pmshort); /* ok if null */ pm->op_pmshort = pm->op_pmregexp->regmust; pm->op_pmslen = SvCUR(pm->op_pmshort); @@ -4434,20 +4768,23 @@ register char *s; SV *tmpstr; char term; register char *d; + register char *e; char *peek; + int outer = (rsfp && !lex_inwhat); s += 2; d = tokenbuf; - if (!rsfp) + e = tokenbuf + sizeof tokenbuf - 1; + if (!outer) *d++ = '\n'; for (peek = s; *peek == ' ' || *peek == '\t'; peek++) ; if (*peek && strchr("`'\"",*peek)) { s = peek; term = *s++; - s = cpytill(d,s,bufend,term,&len); + s = delimcpy(d, e, s, bufend, term, &len); + d += len; if (s < bufend) s++; - d += len; } else { if (*s == '\\') @@ -4456,14 +4793,18 @@ register char *s; term = '"'; if (!isALNUM(*s)) deprecate("bare << to mean <<\"\""); - while (isALNUM(*s)) - *d++ = *s++; - } /* assuming tokenbuf won't clobber */ + for (; isALNUM(*s); s++) { + if (d < e) + *d++ = *s; + } + } + if (d >= tokenbuf + sizeof tokenbuf - 1) + croak("Delimiter for here document is too long"); *d++ = '\n'; *d = '\0'; len = d - tokenbuf; d = "\n"; - if (rsfp || !(d=ninstr(s,bufend,d,d+1))) + if (outer || !(d=ninstr(s,bufend,d,d+1))) herewas = newSVpv(s,bufend-s); else s--, herewas = newSVpv(s,d-s); @@ -4484,10 +4825,10 @@ register char *s; multi_start = curcop->cop_line; multi_open = multi_close = '<'; term = *tokenbuf; - if (!rsfp) { + if (!outer) { d = s; while (s < bufend && - (*s != term || bcmp(s,tokenbuf,len) != 0) ) { + (*s != term || memNE(s,tokenbuf,len)) ) { if (*s++ == '\n') curcop->cop_line++; } @@ -4499,19 +4840,19 @@ register char *s; s += len - 1; sv_catpvn(herewas,s,bufend-s); sv_setsv(linestr,herewas); - oldoldbufptr = oldbufptr = bufptr = s = SvPVX(linestr); + oldoldbufptr = oldbufptr = bufptr = s = linestart = SvPVX(linestr); bufend = SvPVX(linestr) + SvCUR(linestr); } else sv_setpvn(tmpstr,"",0); /* avoid "uninitialized" warning */ while (s >= bufend) { /* multiple line string? */ - if (!rsfp || - !(oldoldbufptr = oldbufptr = s = filter_gets(linestr, rsfp))) { + if (!outer || + !(oldoldbufptr = oldbufptr = s = linestart = filter_gets(linestr, rsfp, 0))) { curcop->cop_line = multi_start; missingterm(tokenbuf); } curcop->cop_line++; - if (perldb && curstash != debstash) { + if (PERLDB_LINE && curstash != debstash) { SV *sv = NEWSV(88,0); sv_upgrade(sv, SVt_PVMG); @@ -4520,7 +4861,7 @@ register char *s; (I32)curcop->cop_line,sv); } bufend = SvPVX(linestr) + SvCUR(linestr); - if (*s == term && bcmp(s,tokenbuf,len) == 0) { + if (*s == term && memEQ(s,tokenbuf,len)) { s = bufend - 1; *s = ' '; sv_catsv(linestr,herewas); @@ -4549,15 +4890,17 @@ char *start; { register char *s = start; register char *d; + register char *e; I32 len; d = tokenbuf; - s = cpytill(d, s+1, bufend, '>', &len); - if (s < bufend) - s++; - else + e = tokenbuf + sizeof tokenbuf; + s = delimcpy(d, e, s + 1, bufend, '>', &len); + if (len >= sizeof tokenbuf) + croak("Excessively long <> operator"); + if (s >= bufend) croak("Unterminated <> operator"); - + s++; if (*d == '$' && d[1]) d++; while (*d && (isALNUM(*d) || *d == '\'' || *d == ':')) d++; @@ -4646,13 +4989,13 @@ char *start; for (; s < bufend; s++,to++) { if (*s == '\n' && !rsfp) curcop->cop_line++; - if (*s == '\\' && s+1 < bufend && term != '\\') { - if (s[1] == term) + if (*s == '\\' && s+1 < bufend) { + if ((s[1] == multi_open) || (s[1] == multi_close)) s++; else *to++ = *s++; } - else if (*s == term && --brackets <= 0) + else if (*s == multi_close && --brackets <= 0) break; else if (*s == multi_open) brackets++; @@ -4665,13 +5008,13 @@ char *start; if (s < bufend) break; /* string ends on this line? */ if (!rsfp || - !(oldoldbufptr = oldbufptr = s = filter_gets(linestr, rsfp))) { + !(oldoldbufptr = oldbufptr = s = linestart = filter_gets(linestr, rsfp, 0))) { sv_free(sv); curcop->cop_line = multi_start; return Nullch; } curcop->cop_line++; - if (perldb && curstash != debstash) { + if (PERLDB_LINE && curstash != debstash) { SV *sv = NEWSV(88,0); sv_upgrade(sv, SVt_PVMG); @@ -4700,19 +5043,22 @@ char *start; { register char *s = start; register char *d; - I32 tryi32; + register char *e; + I32 tryiv; double value; SV *sv; I32 floatit; char *lastub = 0; + static char number_too_long[] = "Number too long"; switch (*s) { default: croak("panic: scan_num"); case '0': { - U32 i; + UV u; I32 shift; + bool overflowed = FALSE; if (s[1] == 'x') { shift = 4; @@ -4722,8 +5068,10 @@ char *start; goto decimal; else shift = 3; - i = 0; + u = 0; for (;;) { + UV n, b; + switch (*s) { default: goto out; @@ -4736,31 +5084,34 @@ char *start; /* FALL THROUGH */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': - i <<= shift; - i += *s++ & 15; - break; + b = *s++ & 15; + goto digit; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': if (shift != 4) goto out; - i <<= 4; - i += (*s++ & 7) + 9; + b = (*s++ & 7) + 9; + digit: + n = u << shift; + if (!overflowed && (n >> shift) != u) { + warn("Integer overflow in %s number", + (shift == 4) ? "hex" : "octal"); + overflowed = TRUE; + } + u = n | b; break; } } out: sv = NEWSV(92,0); - tryi32 = i; - if (tryi32 == i && tryi32 >= 0) - sv_setiv(sv,tryi32); - else - sv_setnv(sv,(double)i); + sv_setuv(sv, u); } break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': decimal: d = tokenbuf; + e = tokenbuf + sizeof tokenbuf - 6; /* room for various punctuation */ floatit = FALSE; while (isDIGIT(*s) || *s == '_') { if (*s == '_') { @@ -4768,19 +5119,22 @@ char *start; warn("Misplaced _ in number"); lastub = ++s; } - else + else { + if (d >= e) + croak(number_too_long); *d++ = *s++; + } } if (dowarn && lastub && s - lastub != 3) warn("Misplaced _ in number"); if (*s == '.' && s[1] != '.') { floatit = TRUE; *d++ = *s++; - while (isDIGIT(*s) || *s == '_') { - if (*s == '_') - s++; - else - *d++ = *s++; + for (; isDIGIT(*s) || *s == '_'; s++) { + if (d >= e) + croak(number_too_long); + if (*s != '_') + *d++ = *s; } } if (*s && strchr("eE",*s) && strchr("+-0123456789",s[1])) { @@ -4789,17 +5143,21 @@ char *start; *d++ = 'e'; /* At least some Mach atof()s don't grok 'E' */ if (*s == '+' || *s == '-') *d++ = *s++; - while (isDIGIT(*s)) + while (isDIGIT(*s)) { + if (d >= e) + croak(number_too_long); *d++ = *s++; + } } *d = '\0'; sv = NEWSV(92,0); + SET_NUMERIC_STANDARD(); value = atof(tokenbuf); - tryi32 = I_32(value); - if (!floatit && (double)tryi32 == value) - sv_setiv(sv,tryi32); + tryiv = I_V(value); + if (!floatit && (double)tryiv == value) + sv_setiv(sv, tryiv); else - sv_setnv(sv,value); + sv_setnv(sv, value); break; } @@ -4844,8 +5202,8 @@ register char *s; } s = eol; if (rsfp) { - s = filter_gets(linestr, rsfp); - oldoldbufptr = oldbufptr = bufptr = SvPVX(linestr); + s = filter_gets(linestr, rsfp, 0); + oldoldbufptr = oldbufptr = bufptr = linestart = SvPVX(linestr); bufend = bufptr + SvCUR(linestr); if (!s) { s = bufptr; @@ -4887,10 +5245,12 @@ set_csh() #endif } -int -start_subparse() +I32 +start_subparse(is_format, flags) +I32 is_format; +U32 flags; { - int oldsavestack_ix = savestack_ix; + I32 oldsavestack_ix = savestack_ix; CV* outsidecv = compcv; AV* comppadlist; @@ -4899,18 +5259,19 @@ start_subparse() } save_I32(&subline); save_item(subname); - SAVEINT(padix); + SAVEI32(padix); SAVESPTR(curpad); SAVESPTR(comppad); SAVESPTR(comppad_name); SAVESPTR(compcv); - SAVEINT(comppad_name_fill); - SAVEINT(min_intro_pending); - SAVEINT(max_intro_pending); - SAVEINT(pad_reset_pending); + SAVEI32(comppad_name_fill); + SAVEI32(min_intro_pending); + SAVEI32(max_intro_pending); + SAVEI32(pad_reset_pending); compcv = (CV*)NEWSV(1104,0); - sv_upgrade((SV *)compcv, SVt_PVCV); + sv_upgrade((SV *)compcv, is_format ? SVt_PVFM : SVt_PVCV); + CvFLAGS(compcv) |= flags; comppad = newAV(); comppad_name = newAV(); @@ -4947,55 +5308,69 @@ int yyerror(s) char *s; { - char tmpbuf[258]; - char *tname = tmpbuf; - - if (bufptr > oldoldbufptr && bufptr - oldoldbufptr < 200 && + char *where = NULL; + char *context = NULL; + int contlen = -1; + SV *msg; + + if (!yychar || (yychar == ';' && !rsfp)) + where = "at EOF"; + else if (bufptr > oldoldbufptr && bufptr - oldoldbufptr < 200 && oldoldbufptr != oldbufptr && oldbufptr != bufptr) { while (isSPACE(*oldoldbufptr)) oldoldbufptr++; - sprintf(tname,"near \"%.*s\"",bufptr - oldoldbufptr, oldoldbufptr); + context = oldoldbufptr; + contlen = bufptr - oldoldbufptr; } else if (bufptr > oldbufptr && bufptr - oldbufptr < 200 && oldbufptr != bufptr) { while (isSPACE(*oldbufptr)) oldbufptr++; - sprintf(tname,"near \"%.*s\"",bufptr - oldbufptr, oldbufptr); + context = oldbufptr; + contlen = bufptr - oldbufptr; } else if (yychar > 255) - tname = "next token ???"; - else if (!yychar || (yychar == ';' && !rsfp)) - (void)strcpy(tname,"at EOF"); + where = "next token ???"; else if ((yychar & 127) == 127) { if (lex_state == LEX_NORMAL || (lex_state == LEX_KNOWNEXT && lex_defer == LEX_NORMAL)) - (void)strcpy(tname,"at end of line"); + where = "at end of line"; else if (lex_inpat) - (void)strcpy(tname,"within pattern"); + where = "within pattern"; + else + where = "within string"; + } + else { + SV *where_sv = sv_2mortal(newSVpv("next char ", 0)); + if (yychar < 32) + sv_catpvf(where_sv, "^%c", toCTRL(yychar)); + else if (isPRINT_LC(yychar)) + sv_catpvf(where_sv, "%c", yychar); else - (void)strcpy(tname,"within string"); + sv_catpvf(where_sv, "\\%03o", yychar & 255); + where = SvPVX(where_sv); } - else if (yychar < 32) - (void)sprintf(tname,"next char ^%c",yychar+64); + msg = sv_2mortal(newSVpv(s, 0)); + sv_catpvf(msg, " at %_ line %ld, ", + GvSV(curcop->cop_filegv), (long)curcop->cop_line); + if (context) + sv_catpvf(msg, "near \"%.*s\"\n", contlen, context); else - (void)sprintf(tname,"next char %c",yychar); - (void)sprintf(buf, "%s at %s line %d, %s\n", - s,SvPVX(GvSV(curcop->cop_filegv)),curcop->cop_line,tname); - if (curcop->cop_line == multi_end && multi_start < multi_end) { - sprintf(buf+strlen(buf), - " (Might be a runaway multi-line %c%c string starting on line %ld)\n", - multi_open,multi_close,(long)multi_start); + sv_catpvf(msg, "%s\n", where); + if (multi_start < multi_end && (U32)(curcop->cop_line - multi_end) <= 1) { + sv_catpvf(msg, + " (Might be a runaway multi-line %c%c string starting on line %ld)\n", + (int)multi_open,(int)multi_close,(long)multi_start); multi_end = 0; } if (in_eval & 2) - warn("%s",buf); + warn("%_", msg); else if (in_eval) - sv_catpv(GvSV(errgv),buf); + sv_catsv(GvSV(errgv), msg); else - fputs(buf,stderr); + PerlIO_write(PerlIO_stderr(), SvPVX(msg), SvCUR(msg)); if (++error_count >= 10) - croak("%s has too many errors.\n", - SvPVX(GvSV(curcop->cop_filegv))); + croak("%_ has too many errors.\n", GvSV(curcop->cop_filegv)); in_my = 0; return 0; } diff --git a/gnu/usr.bin/perl/unixish.h b/gnu/usr.bin/perl/unixish.h index 2f5f44bfacf..a13e2bd86a5 100644 --- a/gnu/usr.bin/perl/unixish.h +++ b/gnu/usr.bin/perl/unixish.h @@ -9,44 +9,77 @@ * This symbol, if defined, indicates that the ioctl() routine is * available to set I/O characteristics */ -#define HAS_IOCTL /**/ +#define HAS_IOCTL / **/ /* HAS_UTIME: * This symbol, if defined, indicates that the routine utime() is * available to update the access and modification times of files. */ -#define HAS_UTIME /**/ +#define HAS_UTIME / **/ /* HAS_GROUP * This symbol, if defined, indicates that the getgrnam(), * getgrgid(), and getgrent() routines are available to * get group entries. */ -#define HAS_GROUP /**/ +#define HAS_GROUP / **/ /* HAS_PASSWD * This symbol, if defined, indicates that the getpwnam(), * getpwuid(), and getpwent() routines are available to * get password entries. */ -#define HAS_PASSWD /**/ +#define HAS_PASSWD / **/ #define HAS_KILL #define HAS_WAIT +/* USEMYBINMODE + * This symbol, if defined, indicates that the program should + * use the routine my_binmode(FILE *fp, char iotype) to insure + * that a file is in "binary" mode -- that is, that no translation + * of bytes occurs on read or write operations. + */ +#undef USEMYBINMODE + +/* USE_STAT_RDEV: + * This symbol is defined if this system has a stat structure declaring + * st_rdev + */ +#define USE_STAT_RDEV / **/ + +/* ACME_MESS: + * This symbol, if defined, indicates that error messages should be + * should be generated in a format that allows the use of the Acme + * GUI/editor's autofind feature. + */ +#undef ACME_MESS /**/ + /* UNLINK_ALL_VERSIONS: * This symbol, if defined, indicates that the program should arrange * to remove all versions of a file if unlink() is called. This is * probably only relevant for VMS. */ -/* #define UNLINK_ALL_VERSIONS /**/ +/* #define UNLINK_ALL_VERSIONS / **/ /* VMS: * This symbol, if defined, indicates that the program is running under * VMS. It is currently automatically set by cpps running under VMS, * and is included here for completeness only. */ -/* #define VMS /**/ +/* #define VMS / **/ + +/* ALTERNATE_SHEBANG: + * This symbol, if defined, contains a "magic" string which may be used + * as the first line of a Perl program designed to be executed directly + * by name, instead of the standard Unix #!. If ALTERNATE_SHEBANG + * begins with a character other then #, then Perl will only treat + * it as a command line if if finds the string "perl" in the first + * word; otherwise it's treated as the first line of code in the script. + * (IOW, Perl won't hand off to another interpreter via an alternate + * shebang sequence that might be legal Perl code.) + */ +/* #define ALTERNATE_SHEBANG "#!" / **/ #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX) # include <signal.h> @@ -60,11 +93,6 @@ #endif #define ABORT() kill(getpid(),SIGABRT); -#define BIT_BUCKET "/dev/null" -#define PERL_SYS_INIT(c,v) -#define PERL_SYS_TERM() -#define dXSUB_SYS int dummy - /* * fwrite1() should be a routine with the same calling sequence as fwrite(), * but which outputs all of the bytes requested as a single stream (unlike @@ -76,6 +104,21 @@ #define Stat(fname,bufptr) stat((fname),(bufptr)) #define Fstat(fd,bufptr) fstat((fd),(bufptr)) #define Fflush(fp) fflush(fp) +#define Mkdir(path,mode) mkdir((path),(mode)) + +#ifndef PERL_SYS_INIT +#ifdef PERL_SCO5 +/* this should be set in a hint file, not here */ +# define PERL_SYS_INIT(c,v) fpsetmask(0) +#else +# define PERL_SYS_INIT(c,v) +#endif +#endif -#define my_getenv(var) getenv(var) +#ifndef PERL_SYS_TERM +#define PERL_SYS_TERM() +#endif + +#define BIT_BUCKET "/dev/null" +#define dXSUB_SYS diff --git a/gnu/usr.bin/perl/util.c b/gnu/usr.bin/perl/util.c index a11d98fe612..819ab4ec347 100644 --- a/gnu/usr.bin/perl/util.c +++ b/gnu/usr.bin/perl/util.c @@ -1,6 +1,6 @@ /* util.c * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -19,20 +19,19 @@ #include <signal.h> #endif -/* Omit this -- it causes too much grief on mixed systems. +#ifndef SIG_ERR +# define SIG_ERR ((Sighandler_t) -1) +#endif + +/* XXX If this causes problems, set i_unistd=undef in the hint file. */ #ifdef I_UNISTD # include <unistd.h> #endif -*/ #ifdef I_VFORK # include <vfork.h> #endif -#ifdef I_LIMITS /* Needed for cast_xxx() functions below. */ -# include <limits.h> -#endif - /* Put this after #includes because fork and vfork prototypes may conflict. */ @@ -47,52 +46,53 @@ # include <sys/file.h> #endif +#ifdef I_SYS_WAIT +# include <sys/wait.h> +#endif + #define FLUSH #ifdef LEAKTEST static void xstat _((void)); #endif -#ifndef safemalloc +#ifndef MYMALLOC /* paranoid version of malloc */ /* NOTE: Do not call the next three routines directly. Use the macros * in handy.h, so that we can easily redefine everything to do tracking of * allocated hunks back to the original New to track down any memory leaks. + * XXX This advice seems to be widely ignored :-( --AD August 1996. */ -char * +Malloc_t safemalloc(size) -#ifdef MSDOS -unsigned long size; -#else MEM_SIZE size; -#endif /* MSDOS */ { - char *ptr; -#ifdef MSDOS + Malloc_t ptr; +#ifdef HAS_64K_LIMIT if (size > 0xffff) { - fprintf(stderr, "Allocation too large: %lx\n", size) FLUSH; + PerlIO_printf(PerlIO_stderr(), "Allocation too large: %lx\n", size) FLUSH; my_exit(1); } -#endif /* MSDOS */ +#endif /* HAS_64K_LIMIT */ #ifdef DEBUGGING if ((long)size < 0) croak("panic: malloc"); #endif ptr = malloc(size?size:1); /* malloc(0) is NASTY on our system */ #if !(defined(I286) || defined(atarist)) - DEBUG_m(fprintf(stderr,"0x%x: (%05d) malloc %ld bytes\n",ptr,an++,(long)size)); + DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%x: (%05d) malloc %ld bytes\n",ptr,an++,(long)size)); #else - DEBUG_m(fprintf(stderr,"0x%lx: (%05d) malloc %ld bytes\n",ptr,an++,(long)size)); + DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) malloc %ld bytes\n",ptr,an++,(long)size)); #endif if (ptr != Nullch) return ptr; else if (nomemok) return Nullch; else { - fputs(no_mem,stderr) FLUSH; + PerlIO_puts(PerlIO_stderr(),no_mem) FLUSH; my_exit(1); } /*NOTREACHED*/ @@ -100,26 +100,23 @@ MEM_SIZE size; /* paranoid version of realloc */ -char * +Malloc_t saferealloc(where,size) -char *where; -#ifndef MSDOS +Malloc_t where; MEM_SIZE size; -#else -unsigned long size; -#endif /* MSDOS */ { - char *ptr; + Malloc_t ptr; #if !defined(STANDARD_C) && !defined(HAS_REALLOC_PROTOTYPE) - char *realloc(); + Malloc_t realloc(); #endif /* !defined(STANDARD_C) && !defined(HAS_REALLOC_PROTOTYPE) */ -#ifdef MSDOS - if (size > 0xffff) { - fprintf(stderr, "Reallocation too large: %lx\n", size) FLUSH; - my_exit(1); - } -#endif /* MSDOS */ +#ifdef HAS_64K_LIMIT + if (size > 0xffff) { + PerlIO_printf(PerlIO_stderr(), + "Reallocation too large: %lx\n", size) FLUSH; + my_exit(1); + } +#endif /* HAS_64K_LIMIT */ if (!where) croak("Null realloc"); #ifdef DEBUGGING @@ -130,13 +127,13 @@ unsigned long size; #if !(defined(I286) || defined(atarist)) DEBUG_m( { - fprintf(stderr,"0x%x: (%05d) rfree\n",where,an++); - fprintf(stderr,"0x%x: (%05d) realloc %ld bytes\n",ptr,an++,(long)size); + PerlIO_printf(Perl_debug_log, "0x%x: (%05d) rfree\n",where,an++); + PerlIO_printf(Perl_debug_log, "0x%x: (%05d) realloc %ld bytes\n",ptr,an++,(long)size); } ) #else DEBUG_m( { - fprintf(stderr,"0x%lx: (%05d) rfree\n",where,an++); - fprintf(stderr,"0x%lx: (%05d) realloc %ld bytes\n",ptr,an++,(long)size); + PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) rfree\n",where,an++); + PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) realloc %ld bytes\n",ptr,an++,(long)size); } ) #endif @@ -145,7 +142,7 @@ unsigned long size; else if (nomemok) return Nullch; else { - fputs(no_mem,stderr) FLUSH; + PerlIO_puts(PerlIO_stderr(),no_mem) FLUSH; my_exit(1); } /*NOTREACHED*/ @@ -153,14 +150,14 @@ unsigned long size; /* safe version of free */ -void +Free_t safefree(where) -char *where; +Malloc_t where; { #if !(defined(I286) || defined(atarist)) - DEBUG_m( fprintf(stderr,"0x%x: (%05d) free\n",where,an++)); + DEBUG_m( PerlIO_printf(Perl_debug_log, "0x%x: (%05d) free\n",where,an++)); #else - DEBUG_m( fprintf(stderr,"0x%lx: (%05d) free\n",where,an++)); + DEBUG_m( PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) free\n",where,an++)); #endif if (where) { /*SUPPRESS 701*/ @@ -168,18 +165,58 @@ char *where; } } -#endif /* !safemalloc */ +/* safe version of calloc */ + +Malloc_t +safecalloc(count, size) +MEM_SIZE count; +MEM_SIZE size; +{ + Malloc_t ptr; + +#ifdef HAS_64K_LIMIT + if (size * count > 0xffff) { + PerlIO_printf(PerlIO_stderr(), + "Allocation too large: %lx\n", size * count) FLUSH; + my_exit(1); + } +#endif /* HAS_64K_LIMIT */ +#ifdef DEBUGGING + if ((long)size < 0 || (long)count < 0) + croak("panic: calloc"); +#endif + size *= count; + ptr = malloc(size?size:1); /* malloc(0) is NASTY on our system */ +#if !(defined(I286) || defined(atarist)) + DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%x: (%05d) calloc %ld x %ld bytes\n",ptr,an++,(long)count,(long)size)); +#else + DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%lx: (%05d) calloc %ld x %ld bytes\n",ptr,an++,(long)count,(long)size)); +#endif + if (ptr != Nullch) { + memset((void*)ptr, 0, size); + return ptr; + } + else if (nomemok) + return Nullch; + else { + PerlIO_puts(PerlIO_stderr(),no_mem) FLUSH; + my_exit(1); + } + /*NOTREACHED*/ +} + +#endif /* !MYMALLOC */ #ifdef LEAKTEST #define ALIGN sizeof(long) -char * +Malloc_t safexmalloc(x,size) I32 x; MEM_SIZE size; { - register char *where; + register Malloc_t where; where = safemalloc(size + ALIGN); xcount[x]++; @@ -188,18 +225,18 @@ MEM_SIZE size; return where + ALIGN; } -char * +Malloc_t safexrealloc(where,size) -char *where; +Malloc_t where; MEM_SIZE size; { - register char *new = saferealloc(where - ALIGN, size + ALIGN); + register Malloc_t new = saferealloc(where - ALIGN, size + ALIGN); return new + ALIGN; } void safexfree(where) -char *where; +Malloc_t where; { I32 x; @@ -211,6 +248,22 @@ char *where; safefree(where); } +Malloc_t +safexcalloc(x,count,size) +I32 x; +MEM_SIZE count; +MEM_SIZE size; +{ + register Malloc_t where; + + where = safexmalloc(x, size * count + ALIGN); + xcount[x]++; + memset((void*)where + ALIGN, 0, size * count); + where[0] = x % 100; + where[1] = x / 100; + return where + ALIGN; +} + static void xstat() { @@ -218,7 +271,7 @@ xstat() for (i = 0; i < MAXXCOUNT; i++) { if (xcount[i] > lastxcount[i]) { - fprintf(stderr,"%2d %2d\t%ld\n", i / 100, i % 100, xcount[i]); + PerlIO_printf(PerlIO_stderr(),"%2d %2d\t%ld\n", i / 100, i % 100, xcount[i]); lastxcount[i] = xcount[i]; } } @@ -229,28 +282,34 @@ xstat() /* copy a string up to some (non-backslashed) delimiter, if any */ char * -cpytill(to,from,fromend,delim,retlen) +delimcpy(to, toend, from, fromend, delim, retlen) register char *to; +register char *toend; register char *from; register char *fromend; register int delim; I32 *retlen; { - char *origto = to; - - for (; from < fromend; from++,to++) { + register I32 tolen; + for (tolen = 0; from < fromend; from++, tolen++) { if (*from == '\\') { if (from[1] == delim) from++; - else if (from[1] == '\\') - *to++ = *from++; + else { + if (to < toend) + *to++ = *from; + tolen++; + from++; + } } else if (*from == delim) break; - *to = *from; + if (to < toend) + *to++ = *from; } - *to = '\0'; - *retlen = to - origto; + if (to < toend) + *to = '\0'; + *retlen = tolen; return from; } @@ -353,9 +412,137 @@ char *lend; return Nullch; } -/* Initialize locale (and the fold[] array).*/ +/* + * Set up for a new ctype locale. + */ +void +perl_new_ctype(newctype) + char *newctype; +{ +#ifdef USE_LOCALE_CTYPE + + int i; + + for (i = 0; i < 256; i++) { + if (isUPPER_LC(i)) + fold_locale[i] = toLOWER_LC(i); + else if (isLOWER_LC(i)) + fold_locale[i] = toUPPER_LC(i); + else + fold_locale[i] = i; + } + +#endif /* USE_LOCALE_CTYPE */ +} + +/* + * Set up for a new collation locale. + */ +void +perl_new_collate(newcoll) + char *newcoll; +{ +#ifdef USE_LOCALE_COLLATE + + if (! newcoll) { + if (collation_name) { + ++collation_ix; + Safefree(collation_name); + collation_name = NULL; + collation_standard = TRUE; + collxfrm_base = 0; + collxfrm_mult = 2; + } + return; + } + + if (! collation_name || strNE(collation_name, newcoll)) { + ++collation_ix; + Safefree(collation_name); + collation_name = savepv(newcoll); + collation_standard = (strEQ(newcoll, "C") || strEQ(newcoll, "POSIX")); + + { + /* 2: at most so many chars ('a', 'b'). */ + /* 50: surely no system expands a char more. */ +#define XFRMBUFSIZE (2 * 50) + char xbuf[XFRMBUFSIZE]; + Size_t fa = strxfrm(xbuf, "a", XFRMBUFSIZE); + Size_t fb = strxfrm(xbuf, "ab", XFRMBUFSIZE); + SSize_t mult = fb - fa; + if (mult < 1) + croak("strxfrm() gets absurd"); + collxfrm_base = (fa > mult) ? (fa - mult) : 0; + collxfrm_mult = mult; + } + } + +#endif /* USE_LOCALE_COLLATE */ +} + +/* + * Set up for a new numeric locale. + */ +void +perl_new_numeric(newnum) + char *newnum; +{ +#ifdef USE_LOCALE_NUMERIC + + if (! newnum) { + if (numeric_name) { + Safefree(numeric_name); + numeric_name = NULL; + numeric_standard = TRUE; + numeric_local = TRUE; + } + return; + } + + if (! numeric_name || strNE(numeric_name, newnum)) { + Safefree(numeric_name); + numeric_name = savepv(newnum); + numeric_standard = (strEQ(newnum, "C") || strEQ(newnum, "POSIX")); + numeric_local = TRUE; + } + +#endif /* USE_LOCALE_NUMERIC */ +} + +void +perl_set_numeric_standard() +{ +#ifdef USE_LOCALE_NUMERIC + + if (! numeric_standard) { + setlocale(LC_NUMERIC, "C"); + numeric_standard = TRUE; + numeric_local = FALSE; + } + +#endif /* USE_LOCALE_NUMERIC */ +} + +void +perl_set_numeric_local() +{ +#ifdef USE_LOCALE_NUMERIC + + if (! numeric_local) { + setlocale(LC_NUMERIC, numeric_name); + numeric_standard = FALSE; + numeric_local = TRUE; + } + +#endif /* USE_LOCALE_NUMERIC */ +} + + +/* + * Initialize locale awareness. + */ int -perl_init_i18nl14n(printwarn) +perl_init_i18nl10n(printwarn) int printwarn; { int ok = 1; @@ -364,41 +551,298 @@ perl_init_i18nl14n(printwarn) * 0 = fallback to C locale, * -1 = fallback to C locale failed */ -#if defined(HAS_SETLOCALE) && defined(LC_CTYPE) - char * lang = getenv("LANG"); - char * lc_all = getenv("LC_ALL"); - char * lc_ctype = getenv("LC_CTYPE"); - int i; - if (setlocale(LC_CTYPE, "") == NULL && (lc_all || lc_ctype || lang)) { - if (printwarn) { - fprintf(stderr, "warning: setlocale(LC_CTYPE, \"\") failed.\n"); - fprintf(stderr, - "warning: LC_ALL = \"%s\", LC_CTYPE = \"%s\", LANG = \"%s\",\n", - lc_all ? lc_all : "(null)", - lc_ctype ? lc_ctype : "(null)", - lang ? lang : "(null)" - ); - fprintf(stderr, "warning: falling back to the \"C\" locale.\n"); +#ifdef USE_LOCALE + +#ifdef USE_LOCALE_CTYPE + char *curctype = NULL; +#endif /* USE_LOCALE_CTYPE */ +#ifdef USE_LOCALE_COLLATE + char *curcoll = NULL; +#endif /* USE_LOCALE_COLLATE */ +#ifdef USE_LOCALE_NUMERIC + char *curnum = NULL; +#endif /* USE_LOCALE_NUMERIC */ + char *lc_all = getenv("LC_ALL"); + char *lang = getenv("LANG"); + bool setlocale_failure = FALSE; + +#ifdef LOCALE_ENVIRON_REQUIRED + + /* + * Ultrix setlocale(..., "") fails if there are no environment + * variables from which to get a locale name. + */ + + bool done = FALSE; + +#ifdef LC_ALL + if (lang) { + if (setlocale(LC_ALL, "")) + done = TRUE; + else + setlocale_failure = TRUE; + } + if (!setlocale_failure) +#endif /* LC_ALL */ + { +#ifdef USE_LOCALE_CTYPE + if (! (curctype = setlocale(LC_CTYPE, + (!done && (lang || getenv("LC_CTYPE"))) + ? "" : Nullch))) + setlocale_failure = TRUE; +#endif /* USE_LOCALE_CTYPE */ +#ifdef USE_LOCALE_COLLATE + if (! (curcoll = setlocale(LC_COLLATE, + (!done && (lang || getenv("LC_COLLATE"))) + ? "" : Nullch))) + setlocale_failure = TRUE; +#endif /* USE_LOCALE_COLLATE */ +#ifdef USE_LOCALE_NUMERIC + if (! (curnum = setlocale(LC_NUMERIC, + (!done && (lang || getenv("LC_NUMERIC"))) + ? "" : Nullch))) + setlocale_failure = TRUE; +#endif /* USE_LOCALE_NUMERIC */ + } + +#else /* !LOCALE_ENVIRON_REQUIRED */ + +#ifdef LC_ALL + + if (! setlocale(LC_ALL, "")) + setlocale_failure = TRUE; + else { +#ifdef USE_LOCALE_CTYPE + curctype = setlocale(LC_CTYPE, Nullch); +#endif /* USE_LOCALE_CTYPE */ +#ifdef USE_LOCALE_COLLATE + curcoll = setlocale(LC_COLLATE, Nullch); +#endif /* USE_LOCALE_COLLATE */ +#ifdef USE_LOCALE_NUMERIC + curnum = setlocale(LC_NUMERIC, Nullch); +#endif /* USE_LOCALE_NUMERIC */ + } + +#else /* !LC_ALL */ + +#ifdef USE_LOCALE_CTYPE + if (! (curctype = setlocale(LC_CTYPE, ""))) + setlocale_failure = TRUE; +#endif /* USE_LOCALE_CTYPE */ +#ifdef USE_LOCALE_COLLATE + if (! (curcoll = setlocale(LC_COLLATE, ""))) + setlocale_failure = TRUE; +#endif /* USE_LOCALE_COLLATE */ +#ifdef USE_LOCALE_NUMERIC + if (! (curnum = setlocale(LC_NUMERIC, ""))) + setlocale_failure = TRUE; +#endif /* USE_LOCALE_NUMERIC */ + +#endif /* LC_ALL */ + +#endif /* !LOCALE_ENVIRON_REQUIRED */ + + if (setlocale_failure) { + char *p; + bool locwarn = (printwarn > 1 || + printwarn && + (!(p = getenv("PERL_BADLANG")) || atoi(p))); + + if (locwarn) { +#ifdef LC_ALL + + PerlIO_printf(PerlIO_stderr(), + "perl: warning: Setting locale failed.\n"); + +#else /* !LC_ALL */ + + PerlIO_printf(PerlIO_stderr(), + "perl: warning: Setting locale failed for the categories:\n\t"); +#ifdef USE_LOCALE_CTYPE + if (! curctype) + PerlIO_printf(PerlIO_stderr(), "LC_CTYPE "); +#endif /* USE_LOCALE_CTYPE */ +#ifdef USE_LOCALE_COLLATE + if (! curcoll) + PerlIO_printf(PerlIO_stderr(), "LC_COLLATE "); +#endif /* USE_LOCALE_COLLATE */ +#ifdef USE_LOCALE_NUMERIC + if (! curnum) + PerlIO_printf(PerlIO_stderr(), "LC_NUMERIC "); +#endif /* USE_LOCALE_NUMERIC */ + PerlIO_printf(PerlIO_stderr(), "\n"); + +#endif /* LC_ALL */ + + PerlIO_printf(PerlIO_stderr(), + "perl: warning: Please check that your locale settings:\n"); + + PerlIO_printf(PerlIO_stderr(), + "\tLC_ALL = %c%s%c,\n", + lc_all ? '"' : '(', + lc_all ? lc_all : "unset", + lc_all ? '"' : ')'); + + { + char **e; + for (e = environ; *e; e++) { + if (strnEQ(*e, "LC_", 3) + && strnNE(*e, "LC_ALL=", 7) + && (p = strchr(*e, '='))) + PerlIO_printf(PerlIO_stderr(), "\t%.*s = \"%s\",\n", + (int)(p - *e), *e, p + 1); + } + } + + PerlIO_printf(PerlIO_stderr(), + "\tLANG = %c%s%c\n", + lang ? '"' : '(', + lang ? lang : "unset", + lang ? '"' : ')'); + + PerlIO_printf(PerlIO_stderr(), + " are supported and installed on your system.\n"); } - ok = 0; - if (setlocale(LC_CTYPE, "C") == NULL) + +#ifdef LC_ALL + + if (setlocale(LC_ALL, "C")) { + if (locwarn) + PerlIO_printf(PerlIO_stderr(), + "perl: warning: Falling back to the standard locale (\"C\").\n"); + ok = 0; + } + else { + if (locwarn) + PerlIO_printf(PerlIO_stderr(), + "perl: warning: Failed to fall back to the standard locale (\"C\").\n"); ok = -1; - } + } - for (i = 0; i < 256; i++) { - if (isUPPER(i)) fold[i] = toLOWER(i); - else if (isLOWER(i)) fold[i] = toUPPER(i); - else fold[i] = i; +#else /* ! LC_ALL */ + + if (0 +#ifdef USE_LOCALE_CTYPE + || !(curctype || setlocale(LC_CTYPE, "C")) +#endif /* USE_LOCALE_CTYPE */ +#ifdef USE_LOCALE_COLLATE + || !(curcoll || setlocale(LC_COLLATE, "C")) +#endif /* USE_LOCALE_COLLATE */ +#ifdef USE_LOCALE_NUMERIC + || !(curnum || setlocale(LC_NUMERIC, "C")) +#endif /* USE_LOCALE_NUMERIC */ + ) + { + if (locwarn) + PerlIO_printf(PerlIO_stderr(), + "perl: warning: Cannot fall back to the standard locale (\"C\").\n"); + ok = -1; + } + +#endif /* ! LC_ALL */ + +#ifdef USE_LOCALE_CTYPE + curctype = setlocale(LC_CTYPE, Nullch); +#endif /* USE_LOCALE_CTYPE */ +#ifdef USE_LOCALE_COLLATE + curcoll = setlocale(LC_COLLATE, Nullch); +#endif /* USE_LOCALE_COLLATE */ +#ifdef USE_LOCALE_NUMERIC + curnum = setlocale(LC_NUMERIC, Nullch); +#endif /* USE_LOCALE_NUMERIC */ } -#endif + +#ifdef USE_LOCALE_CTYPE + perl_new_ctype(curctype); +#endif /* USE_LOCALE_CTYPE */ + +#ifdef USE_LOCALE_COLLATE + perl_new_collate(curcoll); +#endif /* USE_LOCALE_COLLATE */ + +#ifdef USE_LOCALE_NUMERIC + perl_new_numeric(curnum); +#endif /* USE_LOCALE_NUMERIC */ + +#endif /* USE_LOCALE */ + return ok; } +/* Backwards compatibility. */ +int +perl_init_i18nl14n(printwarn) + int printwarn; +{ + return perl_init_i18nl10n(printwarn); +} + +#ifdef USE_LOCALE_COLLATE + +/* + * mem_collxfrm() is a bit like strxfrm() but with two important + * differences. First, it handles embedded NULs. Second, it allocates + * a bit more memory than needed for the transformed data itself. + * The real transformed data begins at offset sizeof(collationix). + * Please see sv_collxfrm() to see how this is used. + */ +char * +mem_collxfrm(s, len, xlen) + const char *s; + STRLEN len; + STRLEN *xlen; +{ + char *xbuf; + STRLEN xalloc, xin, xout; + + /* the first sizeof(collationix) bytes are used by sv_collxfrm(). */ + /* the +1 is for the terminating NUL. */ + + xalloc = sizeof(collation_ix) + collxfrm_base + (collxfrm_mult * len) + 1; + New(171, xbuf, xalloc, char); + if (! xbuf) + goto bad; + + *(U32*)xbuf = collation_ix; + xout = sizeof(collation_ix); + for (xin = 0; xin < len; ) { + SSize_t xused; + + for (;;) { + xused = strxfrm(xbuf + xout, s + xin, xalloc - xout); + if (xused == -1) + goto bad; + if (xused < xalloc - xout) + break; + xalloc = (2 * xalloc) + 1; + Renew(xbuf, xalloc, char); + if (! xbuf) + goto bad; + } + + xin += strlen(s + xin) + 1; + xout += xused; + + /* Embedded NULs are understood but silently skipped + * because they make no sense in locale collation. */ + } + + xbuf[xout] = '\0'; + *xlen = xout - sizeof(collation_ix); + return xbuf; + + bad: + Safefree(xbuf); + *xlen = 0; + return NULL; +} + +#endif /* USE_LOCALE_COLLATE */ + void -fbm_compile(sv, iflag) +fbm_compile(sv) SV *sv; -I32 iflag; { register unsigned char *s; register unsigned char *table; @@ -418,52 +862,24 @@ I32 iflag; i = 0; while (s >= (unsigned char*)(SvPVX(sv))) { - if (table[*s] == len) { -#ifndef pdp11 - if (iflag) - table[*s] = table[fold[*s]] = i; -#else - if (iflag) { - I32 j; - j = fold[*s]; - table[j] = i; - table[*s] = i; - } -#endif /* pdp11 */ - else - table[*s] = i; - } + if (table[*s] == len) + table[*s] = i; s--,i++; } sv_upgrade(sv, SVt_PVBM); - sv_magic(sv, Nullsv, 'B', Nullch, 0); /* deep magic */ + sv_magic(sv, Nullsv, 'B', Nullch, 0); /* deep magic */ SvVALID_on(sv); s = (unsigned char*)(SvPVX(sv)); /* deeper magic */ - if (iflag) { - register U32 tmp, foldtmp; - SvCASEFOLD_on(sv); - for (i = 0; i < len; i++) { - tmp=freq[s[i]]; - foldtmp=freq[fold[s[i]]]; - if (tmp < frequency && foldtmp < frequency) { - rarest = i; - /* choose most frequent among the two */ - frequency = (tmp > foldtmp) ? tmp : foldtmp; - } - } - } - else { - for (i = 0; i < len; i++) { - if (freq[s[i]] < frequency) { - rarest = i; - frequency = freq[s[i]]; - } + for (i = 0; i < len; i++) { + if (freq[s[i]] < frequency) { + rarest = i; + frequency = freq[s[i]]; } } BmRARE(sv) = s[rarest]; BmPREVIOUS(sv) = rarest; - DEBUG_r(fprintf(stderr,"rarest char %c at %d\n",BmRARE(sv),BmPREVIOUS(sv))); + DEBUG_r(PerlIO_printf(Perl_debug_log, "rarest char %c at %d\n",BmRARE(sv),BmPREVIOUS(sv))); } char * @@ -493,91 +909,50 @@ SV *littlestr; if (littlelen > bigend - big) return Nullch; little = (unsigned char*)SvPVX(littlestr); - if (SvCASEFOLD(littlestr)) { /* oops, fake it */ - big = bigend - littlelen; /* just start near end */ - if (bigend[-1] == '\n' && little[littlelen-1] != '\n') - big--; - } - else { - s = bigend - littlelen; - if (*s == *little && bcmp((char*)s,(char*)little,littlelen)==0) - return (char*)s; /* how sweet it is */ - else if (bigend[-1] == '\n' && little[littlelen-1] != '\n' - && s > big) { - s--; - if (*s == *little && bcmp((char*)s,(char*)little,littlelen)==0) - return (char*)s; - } - return Nullch; + s = bigend - littlelen; + if (*s == *little && memEQ((char*)s,(char*)little,littlelen)) + return (char*)s; /* how sweet it is */ + else if (bigend[-1] == '\n' && little[littlelen-1] != '\n' + && s > big) { + s--; + if (*s == *little && memEQ((char*)s,(char*)little,littlelen)) + return (char*)s; } + return Nullch; } table = (unsigned char*)(SvPVX(littlestr) + littlelen + 1); if (--littlelen >= bigend - big) return Nullch; s = big + littlelen; oldlittle = little = table - 2; - if (SvCASEFOLD(littlestr)) { /* case insensitive? */ - if (s < bigend) { - top1: - /*SUPPRESS 560*/ - if (tmp = table[*s]) { + if (s < bigend) { + top2: + /*SUPPRESS 560*/ + if (tmp = table[*s]) { #ifdef POINTERRIGOR - if (bigend - s > tmp) { - s += tmp; - goto top1; - } + if (bigend - s > tmp) { + s += tmp; + goto top2; + } #else - if ((s += tmp) < bigend) - goto top1; + if ((s += tmp) < bigend) + goto top2; #endif - return Nullch; - } - else { - tmp = littlelen; /* less expensive than calling strncmp() */ - olds = s; - while (tmp--) { - if (*--s == *--little || fold[*s] == *little) - continue; - s = olds + 1; /* here we pay the price for failure */ - little = oldlittle; - if (s < bigend) /* fake up continue to outer loop */ - goto top1; - return Nullch; - } - return (char *)s; - } + return Nullch; } - } - else { - if (s < bigend) { - top2: - /*SUPPRESS 560*/ - if (tmp = table[*s]) { -#ifdef POINTERRIGOR - if (bigend - s > tmp) { - s += tmp; - goto top2; - } -#else - if ((s += tmp) < bigend) + else { + tmp = littlelen; /* less expensive than calling strncmp() */ + olds = s; + while (tmp--) { + if (*--s == *--little) + continue; + s = olds + 1; /* here we pay the price for failure */ + little = oldlittle; + if (s < bigend) /* fake up continue to outer loop */ goto top2; -#endif return Nullch; } - else { - tmp = littlelen; /* less expensive than calling strncmp() */ - olds = s; - while (tmp--) { - if (*--s == *--little) - continue; - s = olds + 1; /* here we pay the price for failure */ - little = oldlittle; - if (s < bigend) /* fake up continue to outer loop */ - goto top2; - return Nullch; - } - return (char *)s; - } + return (char *)s; } } return Nullch; @@ -610,96 +985,66 @@ SV *littlestr; return Nullch; } #ifdef POINTERRIGOR - if (SvCASEFOLD(littlestr)) { /* case insignificant? */ - do { - if (big[pos-previous] != first && big[pos-previous] != fold[first]) - continue; - for (x=big+pos+1-previous,s=little; s < littleend; /**/ ) { - if (x >= bigend) - return Nullch; - if (*s++ != *x++ && fold[*(s-1)] != *(x-1)) { - s--; - break; - } - } - if (s == littleend) - return (char *)(big+pos-previous); - } while ( - pos += screamnext[pos] /* does this goof up anywhere? */ - ); - } - else { - do { - if (big[pos-previous] != first) - continue; - for (x=big+pos+1-previous,s=little; s < littleend; /**/ ) { - if (x >= bigend) - return Nullch; - if (*s++ != *x++) { - s--; - break; - } + do { + if (big[pos-previous] != first) + continue; + for (x=big+pos+1-previous,s=little; s < littleend; /**/ ) { + if (x >= bigend) + return Nullch; + if (*s++ != *x++) { + s--; + break; } - if (s == littleend) - return (char *)(big+pos-previous); - } while ( pos += screamnext[pos] ); - } + } + if (s == littleend) + return (char *)(big+pos-previous); + } while ( pos += screamnext[pos] ); #else /* !POINTERRIGOR */ big -= previous; - if (SvCASEFOLD(littlestr)) { /* case insignificant? */ - do { - if (big[pos] != first && big[pos] != fold[first]) - continue; - for (x=big+pos+1,s=little; s < littleend; /**/ ) { - if (x >= bigend) - return Nullch; - if (*s++ != *x++ && fold[*(s-1)] != *(x-1)) { - s--; - break; - } - } - if (s == littleend) - return (char *)(big+pos); - } while ( - pos += screamnext[pos] /* does this goof up anywhere? */ - ); - } - else { - do { - if (big[pos] != first) - continue; - for (x=big+pos+1,s=little; s < littleend; /**/ ) { - if (x >= bigend) - return Nullch; - if (*s++ != *x++) { - s--; - break; - } + do { + if (big[pos] != first) + continue; + for (x=big+pos+1,s=little; s < littleend; /**/ ) { + if (x >= bigend) + return Nullch; + if (*s++ != *x++) { + s--; + break; } - if (s == littleend) - return (char *)(big+pos); - } while ( - pos += screamnext[pos] - ); - } + } + if (s == littleend) + return (char *)(big+pos); + } while ( pos += screamnext[pos] ); #endif /* POINTERRIGOR */ return Nullch; } I32 -ibcmp(a,b,len) -register U8 *a; -register U8 *b; +ibcmp(s1, s2, len) +char *s1, *s2; register I32 len; { + register U8 *a = (U8 *)s1; + register U8 *b = (U8 *)s2; while (len--) { - if (*a == *b) { - a++,b++; - continue; - } - if (fold[*a++] == *b++) - continue; - return 1; + if (*a != *b && *a != fold[*b]) + return 1; + a++,b++; + } + return 0; +} + +I32 +ibcmp_locale(s1, s2, len) +char *s1, *s2; +register I32 len; +{ + register U8 *a = (U8 *)s1; + register U8 *b = (U8 *)s2; + while (len--) { + if (*a != *b && *a != fold_locale[*b]) + return 1; + a++,b++; } return 0; } @@ -732,226 +1077,150 @@ register I32 len; return newaddr; } -#if !defined(I_STDARG) && !defined(I_VARARGS) +/* the SV for form() and mess() is not kept in an arena */ -/* - * Fallback on the old hackers way of doing varargs - */ +static SV * +mess_alloc() +{ + SV *sv; + XPVMG *any; + + /* Create as PVMG now, to avoid any upgrading later */ + New(905, sv, 1, SV); + Newz(905, any, 1, XPVMG); + SvFLAGS(sv) = SVt_PVMG; + SvANY(sv) = (void*)any; + SvREFCNT(sv) = 1 << 30; /* practically infinite */ + return sv; +} -/*VARARGS1*/ +#ifdef I_STDARG char * -mess(pat,a1,a2,a3,a4) -char *pat; -long a1, a2, a3, a4; +form(const char* pat, ...) +#else +/*VARARGS0*/ +char * +form(pat, va_alist) + const char *pat; + va_dcl +#endif { - char *s; - char *s_start; - I32 usermess = strEQ(pat,"%s"); - SV *tmpstr; + va_list args; +#ifdef I_STDARG + va_start(args, pat); +#else + va_start(args); +#endif + if (!mess_sv) + mess_sv = mess_alloc(); + sv_vsetpvfn(mess_sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + va_end(args); + return SvPVX(mess_sv); +} - s = s_start = buf; - if (usermess) { - tmpstr = sv_newmortal(); - sv_setpv(tmpstr, (char*)a1); - *s++ = SvPVX(tmpstr)[SvCUR(tmpstr)-1]; - } - else { - (void)sprintf(s,pat,a1,a2,a3,a4); - s += strlen(s); - } +char * +mess(pat, args) + const char *pat; + va_list *args; +{ + SV *sv; + static char dgd[] = " during global destruction.\n"; - if (s[-1] != '\n') { + if (!mess_sv) + mess_sv = mess_alloc(); + sv = mess_sv; + sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); + if (!SvCUR(sv) || *(SvEND(sv) - 1) != '\n') { if (dirty) - strcpy(s, " during global destruction.\n"); + sv_catpv(sv, dgd); else { - if (curcop->cop_line) { - (void)sprintf(s," at %s line %ld", - SvPVX(GvSV(curcop->cop_filegv)), (long)curcop->cop_line); - s += strlen(s); - } - if (GvIO(last_in_gv) && - IoLINES(GvIOp(last_in_gv)) ) { - (void)sprintf(s,", <%s> %s %ld", - last_in_gv == argvgv ? "" : GvENAME(last_in_gv), - strEQ(rs,"\n") ? "line" : "chunk", - (long)IoLINES(GvIOp(last_in_gv))); - s += strlen(s); + if (curcop->cop_line) + sv_catpvf(sv, " at %_ line %ld", + GvSV(curcop->cop_filegv), (long)curcop->cop_line); + if (GvIO(last_in_gv) && IoLINES(GvIOp(last_in_gv))) { + bool line_mode = (RsSIMPLE(rs) && + SvLEN(rs) == 1 && *SvPVX(rs) == '\n'); + sv_catpvf(sv, ", <%s> %s %ld", + last_in_gv == argvgv ? "" : GvNAME(last_in_gv), + line_mode ? "line" : "chunk", + (long)IoLINES(GvIOp(last_in_gv))); } - (void)strcpy(s,".\n"); - s += 2; + sv_catpv(sv, ".\n"); } - if (usermess) - sv_catpv(tmpstr,buf+1); - } - - if (s - s_start >= sizeof(buf)) { /* Ooops! */ - if (usermess) - fputs(SvPVX(tmpstr), stderr); - else - fputs(buf, stderr); - fputs("panic: message overflow - memory corrupted!\n",stderr); - my_exit(1); } - if (usermess) - return SvPVX(tmpstr); - else - return buf; + return SvPVX(sv); } -/*VARARGS1*/ -void croak(pat,a1,a2,a3,a4) -char *pat; -long a1, a2, a3, a4; -{ - char *tmps; - char *message; - HV *stash; - GV *gv; - CV *cv; - - message = mess(pat,a1,a2,a3,a4); - if (diehook && (cv = sv_2cv(diehook, &stash, &gv, 0)) && !CvDEPTH(cv)) { - dSP; - - PUSHMARK(sp); - EXTEND(sp, 1); - PUSHs(sv_2mortal(newSVpv(message,0))); - PUTBACK; - perl_call_sv((SV*)cv, G_DISCARD); - } - if (in_eval) { - restartop = die_where(message); - Siglongjmp(top_env, 3); - } - fputs(message,stderr); - (void)Fflush(stderr); - if (e_tmpname) { - if (e_fp) { - fclose(e_fp); - e_fp = Nullfp; - } - (void)UNLINK(e_tmpname); - Safefree(e_tmpname); - e_tmpname = Nullch; - } - statusvalue = SHIFTSTATUS(statusvalue); -#ifdef VMS - my_exit((U32)vaxc$errno?vaxc$errno:errno?errno:statusvalue?statusvalue:SS$_ABORT); +#ifdef I_STDARG +OP * +die(const char* pat, ...) #else - my_exit((U32)((errno&255)?errno:((statusvalue&255)?statusvalue:255))); +/*VARARGS0*/ +OP * +die(pat, va_alist) + const char *pat; + va_dcl #endif -} - -/*VARARGS1*/ -void warn(pat,a1,a2,a3,a4) -char *pat; -long a1, a2, a3, a4; { + va_list args; char *message; - SV *sv; + I32 oldrunlevel = runlevel; + int was_in_eval = in_eval; HV *stash; GV *gv; CV *cv; - message = mess(pat,a1,a2,a3,a4); - if (warnhook && (cv = sv_2cv(warnhook, &stash, &gv, 0)) && !CvDEPTH(cv)) { - dSP; - - PUSHMARK(sp); - EXTEND(sp, 1); - PUSHs(sv_2mortal(newSVpv(message,0))); - PUTBACK; - perl_call_sv((SV*)cv, G_DISCARD); + /* We have to switch back to mainstack or die_where may try to pop + * the eval block from the wrong stack if die is being called from a + * signal handler. - dkindred@cs.cmu.edu */ + if (curstack != mainstack) { + dSP; + SWITCHSTACK(curstack, mainstack); } - else { - fputs(message,stderr); -#ifdef LEAKTEST - DEBUG_L(xstat()); -#endif - (void)Fflush(stderr); - } -} - -#else /* !defined(I_STDARG) && !defined(I_VARARGS) */ #ifdef I_STDARG -char * -mess(char *pat, va_list *args) -#else -/*VARARGS0*/ -char * -mess(pat, args) - char *pat; - va_list *args; -#endif -{ - char *s; - char *s_start; - SV *tmpstr; - I32 usermess; -#ifndef HAS_VPRINTF -#ifdef USE_CHAR_VSPRINTF - char *vsprintf(); + va_start(args, pat); #else - I32 vsprintf(); -#endif + va_start(args); #endif + message = mess(pat, &args); + va_end(args); - s = s_start = buf; - usermess = strEQ(pat, "%s"); - if (usermess) { - tmpstr = sv_newmortal(); - sv_setpv(tmpstr, va_arg(*args, char *)); - *s++ = SvPVX(tmpstr)[SvCUR(tmpstr)-1]; - } - else { - (void) vsprintf(s,pat,*args); - s += strlen(s); - } - va_end(*args); - - if (s[-1] != '\n') { - if (dirty) - strcpy(s, " during global destruction.\n"); - else { - if (curcop->cop_line) { - (void)sprintf(s," at %s line %ld", - SvPVX(GvSV(curcop->cop_filegv)), (long)curcop->cop_line); - s += strlen(s); - } - if (GvIO(last_in_gv) && IoLINES(GvIOp(last_in_gv))) { - bool line_mode = (RsSIMPLE(rs) && - SvLEN(rs) == 1 && *SvPVX(rs) == '\n'); - (void)sprintf(s,", <%s> %s %ld", - last_in_gv == argvgv ? "" : GvNAME(last_in_gv), - line_mode ? "line" : "chunk", - (long)IoLINES(GvIOp(last_in_gv))); - s += strlen(s); - } - (void)strcpy(s,".\n"); - s += 2; + if (diehook) { + /* sv_2cv might call croak() */ + SV *olddiehook = diehook; + ENTER; + SAVESPTR(diehook); + diehook = Nullsv; + cv = sv_2cv(olddiehook, &stash, &gv, 0); + LEAVE; + if (cv && !CvDEPTH(cv) && (CvROOT(cv) || CvXSUB(cv))) { + dSP; + SV *msg; + + ENTER; + msg = newSVpv(message, 0); + SvREADONLY_on(msg); + SAVEFREESV(msg); + + PUSHMARK(sp); + XPUSHs(msg); + PUTBACK; + perl_call_sv((SV*)cv, G_DISCARD); + + LEAVE; } - if (usermess) - sv_catpv(tmpstr,buf+1); } - if (s - s_start >= sizeof(buf)) { /* Ooops! */ - if (usermess) - fputs(SvPVX(tmpstr), stderr); - else - fputs(buf, stderr); - fputs("panic: message overflow - memory corrupted!\n",stderr); - my_exit(1); - } - if (usermess) - return SvPVX(tmpstr); - else - return buf; + restartop = die_where(message); + if ((!restartop && was_in_eval) || oldrunlevel > 1) + JMPENV_JUMP(3); + return restartop; } #ifdef I_STDARG void -croak(char* pat, ...) +croak(const char* pat, ...) #else /*VARARGS0*/ void @@ -973,45 +1242,47 @@ croak(pat, va_alist) #endif message = mess(pat, &args); va_end(args); - if (diehook && (cv = sv_2cv(diehook, &stash, &gv, 0)) && !CvDEPTH(cv)) { - dSP; - - PUSHMARK(sp); - EXTEND(sp, 1); - PUSHs(sv_2mortal(newSVpv(message,0))); - PUTBACK; - perl_call_sv((SV*)cv, G_DISCARD); + if (diehook) { + /* sv_2cv might call croak() */ + SV *olddiehook = diehook; + ENTER; + SAVESPTR(diehook); + diehook = Nullsv; + cv = sv_2cv(olddiehook, &stash, &gv, 0); + LEAVE; + if (cv && !CvDEPTH(cv) && (CvROOT(cv) || CvXSUB(cv))) { + dSP; + SV *msg; + + ENTER; + msg = newSVpv(message, 0); + SvREADONLY_on(msg); + SAVEFREESV(msg); + + PUSHMARK(sp); + XPUSHs(msg); + PUTBACK; + perl_call_sv((SV*)cv, G_DISCARD); + + LEAVE; + } } if (in_eval) { restartop = die_where(message); - Siglongjmp(top_env, 3); - } - fputs(message,stderr); - (void)Fflush(stderr); - if (e_tmpname) { - if (e_fp) { - fclose(e_fp); - e_fp = Nullfp; - } - (void)UNLINK(e_tmpname); - Safefree(e_tmpname); - e_tmpname = Nullch; + JMPENV_JUMP(3); } - statusvalue = SHIFTSTATUS(statusvalue); -#ifdef VMS - my_exit((U32)(vaxc$errno?vaxc$errno:(statusvalue?statusvalue:44))); -#else - my_exit((U32)((errno&255)?errno:((statusvalue&255)?statusvalue:255))); -#endif + PerlIO_puts(PerlIO_stderr(),message); + (void)PerlIO_flush(PerlIO_stderr()); + my_failure_exit(); } void #ifdef I_STDARG -warn(char* pat,...) +warn(const char* pat,...) #else /*VARARGS0*/ warn(pat,va_alist) - char *pat; + const char *pat; va_dcl #endif { @@ -1029,26 +1300,41 @@ warn(pat,va_alist) message = mess(pat, &args); va_end(args); - if (warnhook && (cv = sv_2cv(warnhook, &stash, &gv, 0)) && !CvDEPTH(cv)) { - dSP; - - PUSHMARK(sp); - EXTEND(sp, 1); - PUSHs(sv_2mortal(newSVpv(message,0))); - PUTBACK; - perl_call_sv((SV*)cv, G_DISCARD); + if (warnhook) { + /* sv_2cv might call warn() */ + SV *oldwarnhook = warnhook; + ENTER; + SAVESPTR(warnhook); + warnhook = Nullsv; + cv = sv_2cv(oldwarnhook, &stash, &gv, 0); + LEAVE; + if (cv && !CvDEPTH(cv) && (CvROOT(cv) || CvXSUB(cv))) { + dSP; + SV *msg; + + ENTER; + msg = newSVpv(message, 0); + SvREADONLY_on(msg); + SAVEFREESV(msg); + + PUSHMARK(sp); + XPUSHs(msg); + PUTBACK; + perl_call_sv((SV*)cv, G_DISCARD); + + LEAVE; + return; + } } - else { - fputs(message,stderr); + PerlIO_puts(PerlIO_stderr(),message); #ifdef LEAKTEST - DEBUG_L(xstat()); + DEBUG_L(xstat()); #endif - (void)Fflush(stderr); - } + (void)PerlIO_flush(PerlIO_stderr()); } -#endif /* !defined(I_STDARG) && !defined(I_VARARGS) */ #ifndef VMS /* VMS' my_setenv() is in VMS.c */ +#ifndef WIN32 void my_setenv(nam,val) char *nam, *val; @@ -1069,6 +1355,7 @@ char *nam, *val; environ = tmpenv; /* tell exec where it is now */ } if (!val) { + Safefree(environ[i]); while (environ[i]) { environ[i] = environ[i+1]; i++; @@ -1095,6 +1382,74 @@ char *nam, *val; #endif /* MSDOS */ } +#else /* if WIN32 */ + +void +my_setenv(nam,val) +char *nam, *val; +{ + +#ifdef USE_WIN32_RTL_ENV + + register char *envstr; + STRLEN namlen = strlen(nam); + STRLEN vallen; + char *oldstr = environ[setenv_getix(nam)]; + + /* putenv() has totally broken semantics in both the Borland + * and Microsoft CRTLs. They either store the passed pointer in + * the environment without making a copy, or make a copy and don't + * free it. And on top of that, they dont free() old entries that + * are being replaced/deleted. This means the caller must + * free any old entries somehow, or we end up with a memory + * leak every time my_setenv() is called. One might think + * one could directly manipulate environ[], like the UNIX code + * above, but direct changes to environ are not allowed when + * calling putenv(), since the RTLs maintain an internal + * *copy* of environ[]. Bad, bad, *bad* stink. + * GSAR 97-06-07 + */ + + if (!val) { + if (!oldstr) + return; + val = ""; + vallen = 0; + } + else + vallen = strlen(val); + New(904, envstr, namlen + vallen + 3, char); + (void)sprintf(envstr,"%s=%s",nam,val); + (void)putenv(envstr); + if (oldstr) + Safefree(oldstr); +#ifdef _MSC_VER + Safefree(envstr); /* MSVCRT leaks without this */ +#endif + +#else /* !USE_WIN32_RTL_ENV */ + + /* The sane way to deal with the environment. + * Has these advantages over putenv() & co.: + * * enables us to store a truly empty value in the + * environment (like in UNIX). + * * we don't have to deal with RTL globals, bugs and leaks. + * * Much faster. + * Why you may want to enable USE_WIN32_RTL_ENV: + * * environ[] and RTL functions will not reflect changes, + * which might be an issue if extensions want to access + * the env. via RTL. This cuts both ways, since RTL will + * not see changes made by extensions that call the Win32 + * functions directly, either. + * GSAR 97-06-07 + */ + SetEnvironmentVariable(nam,val); + +#endif +} + +#endif /* WIN32 */ + I32 setenv_getix(nam) char *nam; @@ -1102,11 +1457,18 @@ char *nam; register I32 i, len = strlen(nam); for (i = 0; environ[i]; i++) { - if (strnEQ(environ[i],nam,len) && environ[i][len] == '=') + if ( +#ifdef WIN32 + strnicmp(environ[i],nam,len) == 0 +#else + strnEQ(environ[i],nam,len) +#endif + && environ[i][len] == '=') break; /* strnEQ must come first to avoid */ } /* potential SEGV's */ return i; } + #endif /* !VMS */ #ifdef UNLINK_ALL_VERSIONS @@ -1144,6 +1506,21 @@ register I32 len; } #endif +#ifndef HAS_MEMSET +void * +my_memset(loc,ch,len) +register char *loc; +register I32 ch; +register I32 len; +{ + char *retval = loc; + + while (len--) + *loc++ = ch; + return retval; +} +#endif + #if !defined(HAS_BZERO) && !defined(HAS_MEMSET) char * my_bzero(loc,len) @@ -1158,22 +1535,24 @@ register I32 len; } #endif -#ifndef HAS_MEMCMP +#if !defined(HAS_MEMCMP) || !defined(HAS_SANE_MEMCMP) I32 my_memcmp(s1,s2,len) -register unsigned char *s1; -register unsigned char *s2; +char *s1; +char *s2; register I32 len; { + register U8 *a = (U8 *)s1; + register U8 *b = (U8 *)s2; register I32 tmp; while (len--) { - if (tmp = *s1++ - *s2++) + if (tmp = *a++ - *b++) return tmp; } return 0; } -#endif /* HAS_MEMCMP */ +#endif /* !HAS_MEMCMP || !HAS_SANE_MEMCMP */ #if defined(I_STDARG) || defined(I_VARARGS) #ifndef HAS_VPRINTF @@ -1184,7 +1563,9 @@ char * int #endif vsprintf(dest, pat, args) -char *dest, *pat, *args; +char *dest; +const char *pat; +char *args; { FILE fakebuf; @@ -1203,14 +1584,6 @@ char *dest, *pat, *args; #endif } -int -vfprintf(fd, pat, args) -FILE *fd; -char *pat, *args; -{ - _doprnt(pat, args, fd); - return 0; /* wrong, but perl doesn't use the return value */ -} #endif /* HAS_VPRINTF */ #endif /* I_VARARGS || I_STDARGS */ @@ -1364,9 +1737,9 @@ VTOH(vtohs,short) VTOH(vtohl,long) #endif -#if !defined(DOSISH) && !defined(VMS) /* VMS' my_popen() is in - VMS.c, same with OS/2. */ -FILE * + /* VMS' my_popen() is in VMS.c, same with OS/2. */ +#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) +PerlIO * my_popen(cmd,mode) char *cmd; char *mode; @@ -1377,15 +1750,18 @@ char *mode; SV *sv; I32 doexec = strNE(cmd,"-"); +#ifdef OS2 + if (doexec) { + return my_syspopen(cmd,mode); + } +#endif if (pipe(p) < 0) return Nullfp; this = (*mode == 'w'); that = !this; - if (tainting) { - if (doexec) { - taint_env(); - taint_proper("Insecure %s%s", "EXEC"); - } + if (doexec && tainting) { + taint_env(); + taint_proper("Insecure %s%s", "EXEC"); } while ((pid = (doexec?vfork():fork())) < 0) { if (errno != EAGAIN) { @@ -1421,7 +1797,7 @@ char *mode; } /*SUPPRESS 560*/ if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV)) - sv_setiv(GvSV(tmpgv),(I32)getpid()); + sv_setiv(GvSV(tmpgv), (IV)getpid()); forkprocess = 0; hv_clear(pidstatus); /* we have no children */ return Nullfp; @@ -1439,17 +1815,19 @@ char *mode; (void)SvUPGRADE(sv,SVt_IV); SvIVX(sv) = pid; forkprocess = pid; - return fdopen(p[this], mode); + return PerlIO_fdopen(p[this], mode); } #else -#if defined(atarist) +#if defined(atarist) || defined(DJGPP) FILE *popen(); -FILE * +PerlIO * my_popen(cmd,mode) char *cmd; char *mode; { - return popen(cmd, mode); + /* Needs work for PerlIO ! */ + /* used 0 for 2nd parameter to PerlIO-exportFILE; apparently not used */ + return popen(PerlIO_exportFILE(cmd, 0), mode); } #endif @@ -1462,12 +1840,12 @@ char *s; int fd; struct stat tmpstatbuf; - fprintf(stderr,"%s", s); + PerlIO_printf(PerlIO_stderr(),"%s", s); for (fd = 0; fd < 32; fd++) { if (Fstat(fd,&tmpstatbuf) >= 0) - fprintf(stderr," %d",fd); + PerlIO_printf(PerlIO_stderr()," %d",fd); } - fprintf(stderr,"\n"); + PerlIO_printf(PerlIO_stderr(),"\n"); } #endif @@ -1483,15 +1861,23 @@ int newfd; close(newfd); return fcntl(oldfd, F_DUPFD, newfd); #else - int fdtmp[256]; +#define DUP2_MAX_FDS 256 + int fdtmp[DUP2_MAX_FDS]; I32 fdx = 0; int fd; if (oldfd == newfd) return oldfd; close(newfd); - while ((fd = dup(oldfd)) != newfd && fd >= 0) /* good enough for low fd's */ + /* good enough for low fd's... */ + while ((fd = dup(oldfd)) != newfd && fd >= 0) { + if (fdx >= DUP2_MAX_FDS) { + close(fd); + fd = -1; + break; + } fdtmp[fdx++] = fd; + } while (fdx > 0) close(fdtmp[--fdx]); return fd; @@ -1499,34 +1885,167 @@ int newfd; } #endif -#if !defined(DOSISH) && !defined(VMS) /* VMS' my_popen() is in VMS.c */ + +#ifdef HAS_SIGACTION + +Sighandler_t +rsignal(signo, handler) +int signo; +Sighandler_t handler; +{ + struct sigaction act, oact; + + act.sa_handler = handler; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; +#ifdef SA_RESTART + act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */ +#endif + if (sigaction(signo, &act, &oact) == -1) + return SIG_ERR; + else + return oact.sa_handler; +} + +Sighandler_t +rsignal_state(signo) +int signo; +{ + struct sigaction oact; + + if (sigaction(signo, (struct sigaction *)NULL, &oact) == -1) + return SIG_ERR; + else + return oact.sa_handler; +} + +int +rsignal_save(signo, handler, save) +int signo; +Sighandler_t handler; +Sigsave_t *save; +{ + struct sigaction act; + + act.sa_handler = handler; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; +#ifdef SA_RESTART + act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */ +#endif + return sigaction(signo, &act, save); +} + +int +rsignal_restore(signo, save) +int signo; +Sigsave_t *save; +{ + return sigaction(signo, save, (struct sigaction *)NULL); +} + +#else /* !HAS_SIGACTION */ + +Sighandler_t +rsignal(signo, handler) +int signo; +Sighandler_t handler; +{ + return signal(signo, handler); +} + +static int sig_trapped; + +static +Signal_t +sig_trap(signo) +int signo; +{ + sig_trapped++; +} + +Sighandler_t +rsignal_state(signo) +int signo; +{ + Sighandler_t oldsig; + + sig_trapped = 0; + oldsig = signal(signo, sig_trap); + signal(signo, oldsig); + if (sig_trapped) + kill(getpid(), signo); + return oldsig; +} + +int +rsignal_save(signo, handler, save) +int signo; +Sighandler_t handler; +Sigsave_t *save; +{ + *save = signal(signo, handler); + return (*save == SIG_ERR) ? -1 : 0; +} + +int +rsignal_restore(signo, save) +int signo; +Sigsave_t *save; +{ + return (signal(signo, *save) == SIG_ERR) ? -1 : 0; +} + +#endif /* !HAS_SIGACTION */ + + /* VMS' my_pclose() is in VMS.c; same with OS/2 */ +#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) I32 my_pclose(ptr) -FILE *ptr; +PerlIO *ptr; { - Signal_t (*hstat)(), (*istat)(), (*qstat)(); + Sigsave_t hstat, istat, qstat; int status; SV **svp; int pid; + bool close_failed; + int saved_errno; +#ifdef VMS + int saved_vaxc_errno; +#endif - svp = av_fetch(fdpid,fileno(ptr),TRUE); + svp = av_fetch(fdpid,PerlIO_fileno(ptr),TRUE); pid = (int)SvIVX(*svp); SvREFCNT_dec(*svp); *svp = &sv_undef; - fclose(ptr); +#ifdef OS2 + if (pid == -1) { /* Opened by popen. */ + return my_syspclose(ptr); + } +#endif + if ((close_failed = (PerlIO_close(ptr) == EOF))) { + saved_errno = errno; +#ifdef VMS + saved_vaxc_errno = vaxc$errno; +#endif + } #ifdef UTS if(kill(pid, 0) < 0) { return(pid); } /* HOM 12/23/91 */ #endif - hstat = signal(SIGHUP, SIG_IGN); - istat = signal(SIGINT, SIG_IGN); - qstat = signal(SIGQUIT, SIG_IGN); + rsignal_save(SIGHUP, SIG_IGN, &hstat); + rsignal_save(SIGINT, SIG_IGN, &istat); + rsignal_save(SIGQUIT, SIG_IGN, &qstat); do { pid = wait4pid(pid, &status, 0); } while (pid == -1 && errno == EINTR); - signal(SIGHUP, hstat); - signal(SIGINT, istat); - signal(SIGQUIT, qstat); - return(pid < 0 ? pid : status); + rsignal_restore(SIGHUP, &hstat); + rsignal_restore(SIGINT, &istat); + rsignal_restore(SIGQUIT, &qstat); + if (close_failed) { + SETERRNO(saved_errno, saved_vaxc_errno); + return -1; + } + return(pid < 0 ? pid : status == 0 ? 0 : (errno = 0, status)); } #endif /* !DOSISH */ @@ -1539,7 +2058,7 @@ int flags; { SV *sv; SV** svp; - char spid[16]; + char spid[TYPE_CHARS(int)]; if (!pid) return -1; @@ -1566,11 +2085,17 @@ int flags; } } #ifdef HAS_WAITPID +# ifdef HAS_WAITPID_RUNTIME + if (!HAS_WAITPID_RUNTIME) + goto hard_way; +# endif return waitpid(pid,statusp,flags); -#else -#ifdef HAS_WAIT4 +#endif +#if !defined(HAS_WAITPID) && defined(HAS_WAIT4) return wait4((pid==-1)?0:pid,statusp,flags,Null(struct rusage *)); -#else +#endif +#if !defined(HAS_WAITPID) && !defined(HAS_WAIT4) || defined(HAS_WAITPID_RUNTIME) + hard_way: { I32 result; if (flags) @@ -1584,7 +2109,6 @@ int flags; return result; } #endif -#endif } #endif /* !DOSISH */ @@ -1595,7 +2119,7 @@ int pid; int status; { register SV *sv; - char spid[16]; + char spid[TYPE_CHARS(int)]; sprintf(spid, "%d", pid); sv = *hv_fetch(pidstatus,spid,strlen(spid),TRUE); @@ -1604,13 +2128,23 @@ int status; return; } -#if defined(atarist) || defined(OS2) +#if defined(atarist) || defined(OS2) || defined(DJGPP) int pclose(); +#ifdef HAS_FORK +int /* Cannot prototype with I32 + in os2ish.h. */ +my_syspclose(ptr) +#else I32 my_pclose(ptr) -FILE *ptr; +#endif +PerlIO *ptr; { - return pclose(ptr); + /* Needs work for PerlIO ! */ + FILE *f = PerlIO_findFILE(ptr); + I32 result = pclose(f); + PerlIO_releaseFILE(ptr,f); + return result; } #endif @@ -1660,29 +2194,6 @@ double f; #ifndef CASTI32 -/* Look for MAX and MIN integral values. If we can't find them, - we'll use 32-bit two's complement defaults. -*/ -#ifndef LONG_MAX -# ifdef MAXLONG /* Often used in <values.h> */ -# define LONG_MAX MAXLONG -# else -# define LONG_MAX 2147483647L -# endif -#endif - -#ifndef LONG_MIN -# define LONG_MIN (-LONG_MAX - 1) -#endif - -#ifndef ULONG_MAX -# ifdef MAXULONG -# define LONG_MAX MAXULONG -# else -# define ULONG_MAX 4294967295L -# endif -#endif - /* Unfortunately, on some systems the cast_uv() function doesn't work with the system-supplied definition of ULONG_MAX. The comparison (f >= ULONG_MAX) always comes out true. It must be a @@ -1693,18 +2204,24 @@ double f; ccflags. --Andy Dougherty <doughera@lafcol.lafayette.edu> */ -#ifndef MY_ULONG_MAX -# define MY_ULONG_MAX ((UV)LONG_MAX * (UV)2 + (UV)1) + +/* Code modified to prefer proper named type ranges, I32, IV, or UV, instead + of LONG_(MIN/MAX). + -- Kenneth Albanowski <kjahds@kjahds.com> +*/ + +#ifndef MY_UV_MAX +# define MY_UV_MAX ((UV)IV_MAX * (UV)2 + (UV)1) #endif I32 cast_i32(f) double f; { - if (f >= LONG_MAX) - return (I32) LONG_MAX; - if (f <= LONG_MIN) - return (I32) LONG_MIN; + if (f >= I32_MAX) + return (I32) I32_MAX; + if (f <= I32_MIN) + return (I32) I32_MIN; return (I32) f; } @@ -1712,10 +2229,10 @@ IV cast_iv(f) double f; { - if (f >= LONG_MAX) - return (IV) LONG_MAX; - if (f <= LONG_MIN) - return (IV) LONG_MIN; + if (f >= IV_MAX) + return (IV) IV_MAX; + if (f <= IV_MIN) + return (IV) IV_MIN; return (IV) f; } @@ -1723,8 +2240,8 @@ UV cast_uv(f) double f; { - if (f >= MY_ULONG_MAX) - return (UV) MY_ULONG_MAX; + if (f >= MY_UV_MAX) + return (UV) MY_UV_MAX; return (UV) f; } @@ -1740,10 +2257,7 @@ char *b; char *fb = strrchr(b,'/'); struct stat tmpstatbuf1; struct stat tmpstatbuf2; -#ifndef MAXPATHLEN -#define MAXPATHLEN 1024 -#endif - char tmpbuf[MAXPATHLEN+1]; + SV *tmpsv = sv_newmortal(); if (fa) fa++; @@ -1756,34 +2270,39 @@ char *b; if (strNE(a,b)) return FALSE; if (fa == a) - strcpy(tmpbuf,"."); + sv_setpv(tmpsv, "."); else - strncpy(tmpbuf, a, fa - a); - if (Stat(tmpbuf, &tmpstatbuf1) < 0) + sv_setpvn(tmpsv, a, fa - a); + if (Stat(SvPVX(tmpsv), &tmpstatbuf1) < 0) return FALSE; if (fb == b) - strcpy(tmpbuf,"."); + sv_setpv(tmpsv, "."); else - strncpy(tmpbuf, b, fb - b); - if (Stat(tmpbuf, &tmpstatbuf2) < 0) + sv_setpvn(tmpsv, b, fb - b); + if (Stat(SvPVX(tmpsv), &tmpstatbuf2) < 0) return FALSE; return tmpstatbuf1.st_dev == tmpstatbuf2.st_dev && tmpstatbuf1.st_ino == tmpstatbuf2.st_ino; } #endif /* !HAS_RENAME */ -unsigned long +UV scan_oct(start, len, retlen) char *start; I32 len; I32 *retlen; { register char *s = start; - register unsigned long retval = 0; + register UV retval = 0; + bool overflowed = FALSE; while (len && *s >= '0' && *s <= '7') { - retval <<= 3; - retval |= *s++ - '0'; + register UV n = retval << 3; + if (!overflowed && (n >> 3) != retval) { + warn("Integer overflow in octal number"); + overflowed = TRUE; + } + retval = n | (*s++ - '0'); len--; } if (dowarn && len && (*s == '8' || *s == '9')) @@ -1792,21 +2311,40 @@ I32 *retlen; return retval; } -unsigned long +UV scan_hex(start, len, retlen) char *start; I32 len; I32 *retlen; { register char *s = start; - register unsigned long retval = 0; + register UV retval = 0; + bool overflowed = FALSE; char *tmp; while (len-- && *s && (tmp = strchr(hexdigit, *s))) { - retval <<= 4; - retval |= (tmp - hexdigit) & 15; + register UV n = retval << 4; + if (!overflowed && (n >> 4) != retval) { + warn("Integer overflow in hex number"); + overflowed = TRUE; + } + retval = n | (tmp - hexdigit) & 15; s++; } *retlen = s - start; return retval; } + + +#ifdef HUGE_VAL +/* + * This hack is to force load of "huge" support from libm.a + * So it is in perl for (say) POSIX to use. + * Needed for SunOS with Sun's 'acc' for example. + */ +double +Perl_huge() +{ + return HUGE_VAL; +} +#endif diff --git a/gnu/usr.bin/perl/util.h b/gnu/usr.bin/perl/util.h index df518467342..7dcf9ceab51 100644 --- a/gnu/usr.bin/perl/util.h +++ b/gnu/usr.bin/perl/util.h @@ -1,6 +1,6 @@ /* util.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. diff --git a/gnu/usr.bin/perl/writemain.SH b/gnu/usr.bin/perl/writemain.SH index 4884a387a17..c4283830854 100644 --- a/gnu/usr.bin/perl/writemain.SH +++ b/gnu/usr.bin/perl/writemain.SH @@ -21,6 +21,7 @@ echo "Extracting writemain (with variable substitutions)" : Move anything that needs config subs from !NO!SUBS! section to !GROK!THIS!. : Protect any dollar signs and backticks that you do not want interpreted : by putting a backslash in front. You may delete these comments. +rm -f writemain $spitshell >writemain <<!GROK!THIS! $startsh !GROK!THIS! @@ -69,11 +70,12 @@ cat << 'EOP' static void xs_init() { - dXSUB_SYS; EOP if test X"$args" != "X" ; then echo " char *file = __FILE__;" + echo " dXSUB_SYS;" + ai='' for ext in $args ; do @@ -83,7 +85,6 @@ if test X"$args" != "X" ; then mname=`echo $ext | sed 's!/!::!g'` cname=`echo $mname | sed 's!:!_!g'` - echo " {" if test "$ext" = "DynaLoader"; then : Must NOT install 'DynaLoader::boot_DynaLoader' as 'bootstrap'! : boot_DynaLoader is called directly in DynaLoader.pm @@ -91,7 +92,6 @@ if test X"$args" != "X" ; then else echo " newXS(\"${mname}::bootstrap\", boot_${cname}, file);" fi - echo " }" done fi |