#!/bin/sh # # This is my patch _01 to perl5.003. # # This patch contains the last few months' worth of bugfixes and # additions, since the patch to version 5.003 was deliberately kept # small. A summary of major revisions and additions can be found # in the diff of the Changes file from the standard distribution, # which is the first diff in the patch below. # # The detailed changes to each file are described at the head of the diff # for that file, on lines beginning with #~, so you can extract the # comments by saying perl -ne 'print if /^(?:#~|diff)/'. # # This patch is a series of context diffs, since some people have # mentioned that their copy of patch can't handle unidiffs. # Please apply it to a clean copy of perl5.003 using patch -p1 -N. # Before applying the patch, please execute the following commands, # or their moral equivalent; you may feed this patch to /bin/sh in # order to do so. # # Enjoy. # # Charles Bailey # July 31, 1996 # The code for the Safe extension has been subsumed into the Opcode extension, # though the calling sequence hasn't changed rm -rf ext/Safe rm -f t/lib/safe.t # Removed due to copyright notice. Text documentation is supplied. rm -f ext/SDBM_File/sdbm/readme.ps # Changes subsumed into new version of DB_File rm -f os2/diff.db_file # Moved to main source directory as README.os2 rm -f os2/README exit 0 ## Start of patch ## #~ Note major changes for releases 5.002_01 through 5.003_01 diff -Pcr perl5_003/Changes perl5_003_01/Changes *** perl5_003/Changes Mon Mar 25 01:04:00 1996 --- perl5_003_01/Changes Tue Jul 30 17:03:35 1996 *************** *** 1,3 **** --- 1,280 ---- + Please note: This file provides a summary of significant changes + between versions and sub-versions of Perl, not a complete list + of each modification. If you'd like more detailed information, + please consult the comments in the patches on which the relevant + release of Perl is based. (Patches can be found on any CPAN + site, in the .../src/5.0 directory for full version releases, + or in the .../src/5/0/unsupported directory for sub-version + releases.) + + + ---------------- + Version 5.003_01 + ---------------- + + Version 5.003_01 contains bugfixes and additions accumulated since + version 5.002_01, since the patch to version 5.003 was deliberately + kept simple. In addition to numerous small bugfixes in the core, + library files, and documentation, this patch contains several + significant revisions, summarized below: + + o Visible Changes to Core Functionality + + - A port to Plan9 has been started, and changes are integrated into + the standard distribution. As of this release, the Perl core + and several common extensions are working. + + - A set of basic methods in the UNIVERSAL class have been added to + the Perl core. Since UNIVERSAL is an implicit member of every + class's @ISA, the methods can be called via any object. + + - A mandatory warning has been added for 'declarations' of lexical + variables using the "my" operator which mask an existing lexical + variable declared in the same scope, making the previous variable + inaccessible by its name. + + - The "use" and "require" operators have been extended to allow + checking of the required module's version. The "use" operator + can now be used for an immediate version check of Perl itself. + + - A new "strict" pragma, "strict untie", has been added, which + produces an error if a tied value is untied when other references + exist to the internal object implementing the tie. + + - Barewords used as associative array keys (i.e. when specifying + an associative array element like $foo{__BAR} or on the left + side of the => operator) may now begin with an underscore as + well as an alphabetic character. + + - Some of the configuration information previously produced by the + -v switch has been moved to the -V switch, in order to keep -v + output concise. + + o Changes in Core Internals + + - Symbol table and method lookups have been made faster. + + - Perl subroutines which just return a constant value are now + optimized at compile time into inline constants. + + - Management of keys for associative arrays has been improved to + conserve space when the same keys are reused frequently, and + to pass true Perl values to tie functions, instead of stringified + representations. + + - Messages normally output to stderr may be directed to another + stream when Perl is built. This allows some platforms to + present diagnostic output in a separate window from normal + program results. + + - A bug which caused suiperl to fail silently, albeit securely, + in version 5.003 on some systems has been fixed. + + - Management of Unix-style signal handlers via the %SIG associative + array has been made safer. + + - Several global C symbols have been renamed to eliminate collisions + with system C header files or libraries on some platforms. + Unfortunately, this means that dynamic extensions compiled under + previous versions of Perl will need to be rebuilt for Perl + 5.003_01. We're in the process of cleaning up Perl's C + namespace to make it easier to link Perl with other binaries, + so this will probably happen again between now and version 5.004. + After that, we'll do our best to maintain binary compatibility + between versions. + + - An alternate allocation strategy has been added to Perl's + optional private memory management routines. This strategy, + which may be selected when Perl is built, is designed to + conserve memory in programs which allocate many small + chunks of memory with sizes near a power of 2, as is often + the case in Perl programs. + + - Several memory leaks in the creation and destruction of + multiple interpreters have been fixed. + + o Changes in the Standard Library and Utilities + + - The Opcode extension, which allows you to control a program's + access to Perl operations, has been added to the standard + distribution. This extends the work begun in the original + Safe extension, and subsumes it. The Safe interface is still + available. + + - The IO extension, which provides a set of classes for object- + oriented handling of common I/O tasks, has been added to the + standard distribution. The IO classes will form the basis + for future development of Perl's I/O interface, and will + subsume the FileHandle class in the near future. The default + class to which all Perl I/O handles belong is now IO::Handle, + rather than FileHandle. + + - The ExtUtils::Embed library module, which provides a set + of utility function to help in embedding Perl in other + applications, has been added to the standard distribution. + + - The Fatal library module, which provides a simple interface + for creating "do-or-die" equivalents of existing functions, + has been added to the standard distribution. + + - The FindBin library module, which determines the full path + to the currently executing program, has been added to the + standard distribution. + + - The DB_File extension, and the Getopt::Long, Test::Harness, + Text::Tabs, Text::Wrap, Time::Local and sigtrap library modules + have been updated to the authors' latest versions. + + - The Carp library module now considers the @ISA chain when + determining the caller's package for inclusion in error messages. + + - The h2xs, perlbug, and xsubpp utilities have been updated. + + - The standard Perl debugger has been updated, and the information + provided to the debugger when an XSUB is called has been improved, + making it possible for alternate debuggers (such as Devel::DProf) + to do a better job of tracking XSUB calls. + + - The pod documentation formatting tools in the standard distribution + can now handle characters in the input stream whose high bit is set. + + - The cperl-mode EMACS editing mode has been updated. + + o Changes in Documentation + + - Typographic and formatting errors have been corrected in the pod + documentation for the core and standard library files + + - Explanations of several core operators have been improved + + - The perldebug, perlembed, perlipc, perlsec, and perltrap documents + extensively revised. + + o Changes in OS-specific and Build-time Support + + - Support for the NeXT platform has been extended through + NeXTSTEP/OPENSTEP 4.0, and now includes the ability to create MABs. + + - Support for OS/2 has been extended as well, and now includes + options for building a.out binaries. + + - Support for VMS has also been extended, incorporating improved + processing of file specification strings, optional suppression of + carriage control interpretation for record-structured files, + improved support for the -S command line switch, a number of + VMS-specific bugfixes, and significantly improved performance + in line-oriented reading of files. + + - Several hints files have been added or updated: aux.sh (updated), + convexos.sh (updated), irix_4.sh (updated), irix_5.sh (updated), + irix_6_2.sh (updated), next_3.sh (updated), next_3_2.sh (new), + next_3_3.sh (new), next_4.sh (new), os2/sh (updated), + sco.sh (updated), and solaris_2.sh (updated). + + - The test driver for the regression tests now reports when a set + of tests have been skipped (presumable because the operation + they're designed to test isn't supported on the current system). + + ------------- + Version 5.003 + ------------- + + ***> IMPORTANT NOTICE: <*** + The main reason for this release was to fix a security bug affecting + suidperl on some systems. If you build suidperl on your system, it + is strongly recommended that you replace any existing copies with + version 5.003 or later immediately. + + The changes in 5.003 have been held to a minimum, in the hope that this + will simplify installation and testing at sites which may be affected + by the security hole in suidperl. In brief, 5.003 does the following: + + - Plugs security hole in suidperl mechanism on affected systems + + - MakeMaker was also updated to version 5.34, and extension Makefile.PLs + were modified to match it. + + - The following hints files were updated: bsdos.sh, hpux.sh, linux.sh, + machten.sh, solaris_2.sh + + - A fix was added to installperl to insure that file permissions were + set correctly for the installed C header files. + + - t/op/stat.t was modified to work around MachTen's belief that /dev/null + is a terminal device. + + - Incorporation of Perl version information into the VMS' version of + config.h was changed to make it compatible with the older VAXC. + + - Minor fixes were made to VMS-specific C code, and the routine + VMS::Filespec::rmsexpand was added. + + ---------------- + Version 5.002_01 + ---------------- + + - The EMBED namespace changes are now used by default, in order to better + segregate Perl's C global symbols from those belonging to embedding + applications or to libraries. This makes it necessary to rebuild dynamic + extensions built under previous versions of Perl without the EMBED option. + The default use of EMBED can be overridden by placing -DNO_EMBED on the + cc command line. + + The EMBED change is the beginning of a general cleanup of C global + symbols used by Perl, so binary compatibility with previously + compiled dynamic extensions may be broken again in the next few + releases. + + - Several bugs in the core were fixed, including the following: + - made sure FILE * for -e temp file was closed only once + - improved form of single-statement macro definitions to keep + as many ccs as possible happy + - fixed file tests to insure that signed values were used when + computing differences between times. + - fixed toke.c so implicit loop isn't doubled when perl is + invoked with both the -p and -n switches + + - The new SUBVERSION number has been included in the default value for + architecture-specific library directories, so development and + production architecture-dependent libraries can coexist. + + - Two new magic variables, $^E and $^O, have been added. $^E contains the + OS-specific equivalent of $!. $^O contains the name of the operating + system, in order to make it easily available to Perl code whose behavior + differs according to its environment. The standard library files have + been converted to use $^O in preference to $Config{'osname'}. + + - A mechanism was added to allow listing of locally applied patches + in the output of perl -v. + + - Miscellaneous minor corrections and updates were made to the documentation. + + - Extensive updates were made to the OS/2 and VMS ports + + - The following hints file were updated: bsdos.sh, dynixptx.sh, + irix_6_2.sh, linux.sh, os2.sh + + - Several changes were made to standard library files: + - reduced use of English.pm and $`, $', and $& in library modules, + since these degrade module loading and evaluation of regular expressions, + respectively. + - File/Basename.pm: Added path separator to dirname('.') + - File/Copy.pm: Added support for VMS and OS/2 system-level copy + - MakeMaker updated to v5.26 + - Symbol.pm now accepts old (') and new (::) package delimiters + - Sys/Syslog.pm uses Sys::Hostname only when necessary + - chat2.pl picks up necessary constants from socket.ph + - syslog.pl: Corrected thinko 'Socket' --> 'Syslog' + - xsubpp updated to v1.935 + + + - The perlbug utility is now more cautious about sending mail, in order + to reduce the chance of accidentally send a bug report by giving the + wrong response to a prompt. + + - The -m switch has been added to perldoc, causing it to display the + Perl code in target file as well as any documentation. + ------------- Version 5.002 ------------- #~ Added MAB support for Next #~ Correct recognition of irix 6 #~ Use C locale when obtaining Perl version for arch-dependent dir names #~ Insure that config.sh is writeable #~ Improve test for broken gconvert() #~ Set cc and ld switches properly for shared libraries under linux and irix #~ Correct dynamic loading test so that $dlext=o doesn't break it diff -Pcr perl5_003/Configure perl5_003_01/Configure *** perl5_003/Configure Mon Mar 25 01:04:01 1996 --- perl5_003_01/Configure Thu Jul 18 16:01:50 1996 *************** *** 231,236 **** --- 231,237 ---- gccversion='' ccflags='' cppflags='' + mab='' ldflags='' lkflags='' locincpth='' *************** *** 1638,1644 **** *) osvers="$3" ;; esac ;; ! irix) osname=irix case "$3" in 4*) osvers=4 ;; 5*) osvers=5 ;; --- 1639,1645 ---- *) osvers="$3" ;; esac ;; ! irix*) osname=irix case "$3" in 4*) osvers=4 ;; 5*) osvers=5 ;; *************** *** 1857,1862 **** --- 1858,1864 ---- tmp_c="$c" cd .. cp $config_sh config.sh 2>/dev/null + chmod +w config.sh . ./config.sh cd UU cp ../config.sh . *************** *** 2331,2337 **** set dflt eval $prefixup ;; ! *) version=`echo $baserev $patchlevel $subversion | \ $awk '{print $1 + $2/1000.0 + $3/100000.0}'` dflt="$privlib/$archname/$version" ;; --- 2333,2340 ---- set dflt eval $prefixup ;; ! *) version=`LC_ALL=C;export LC_ALL;\ ! echo $baserev $patchlevel $subversion | \ $awk '{print $1 + $2/1000.0 + $3/100000.0}'` dflt="$privlib/$archname/$version" ;; *************** *** 4621,4626 **** --- 4624,4633 ---- #endif main() { char buf[64]; + /* This test must come first. */ + Gconvert(0.1, 8, 0, buf); + if (buf[0] != '.' || buf[1] != '1' || buf[2] != '\0') + exit(1); Gconvert(1.0, 8, 0, buf); if (buf[0] != '1' || buf[1] != '\0') exit(1); *************** *** 5388,5393 **** --- 5395,5401 ---- hpux) dflt='+z' ;; next) dflt='none' ;; solaris|svr4*|esix*) dflt='-Kpic' ;; + irix*) dflt='-KPIC' ;; sunos) dflt='-pic' ;; *) dflt='none' ;; esac ;; *************** *** 5455,5461 **** case "$lddlflags" in '') case "$osname" in hpux) dflt='-b' ;; ! linux) dflt='-shared' ;; next) dflt='none' ;; solaris) dflt='-G' ;; sunos) dflt='-assert nodefinitions' ;; --- 5463,5469 ---- case "$lddlflags" in '') case "$osname" in hpux) dflt='-b' ;; ! linux|irix*) dflt='-shared' ;; next) dflt='none' ;; solaris) dflt='-G' ;; sunos) dflt='-assert nodefinitions' ;; *************** *** 5646,5652 **** } EOM if $cc $ccflags $cccdlflags -c dyna.c > /dev/null 2>&1 && ! $ld $lddlflags -o dyna.$dlext dyna.o > /dev/null 2>&1 && $cc $ccflags $ldflags $cccdlflags $ccdlflags fred.c -o fred $libs > /dev/null 2>&1; then xxx=`./fred` case $xxx in --- 5654,5661 ---- } EOM if $cc $ccflags $cccdlflags -c dyna.c > /dev/null 2>&1 && ! mv dyna.o tmp-dyna.o > /dev/null 2>&1 && ! $ld $lddlflags -o dyna.$dlext tmp-dyna.o > /dev/null 2>&1 && $cc $ccflags $ldflags $cccdlflags $ccdlflags fred.c -o fred $libs > /dev/null 2>&1; then xxx=`./fred` case $xxx in *************** *** 5664,5670 **** ;; esac ! $rm -f fred fred.? dyna.$dlext dyna.? set d_dlsymun eval $setvar --- 5673,5679 ---- ;; esac ! $rm -f fred fred.? dyna.$dlext dyna.? tmp-dyna.? set d_dlsymun eval $setvar *************** *** 9262,9267 **** --- 9271,9277 ---- lpr='$lpr' ls='$ls' lseektype='$lseektype' + mab='$mab' mail='$mail' mailx='$mailx' make='$make' #~ Point non-Unix users to OS-specific READMEs #~ Use correct -B values for gcc under Solaris #~ Include minor pod format fixes #~ Mention h2ph #~ Revise notes about multiple versions coexisting diff -Pcr perl5_003/INSTALL perl5_003_01/INSTALL *** perl5_003/INSTALL Mon Jun 24 16:07:53 1996 --- perl5_003_01/INSTALL Wed Jul 10 11:51:42 1996 *************** *** 18,24 **** proceeding. Special notes specific to this release are identified by B. ! =head1 BUILDING PERL5 =head1 Start with a Fresh Distribution. --- 18,31 ---- proceeding. Special notes specific to this release are identified by B. ! 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. ! ! =head1 DESCRIPTION ! ! The following is the procedures you need to follow in order to successfully ! build perl. =head1 Start with a Fresh Distribution. *************** *** 351,357 **** 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 will use the defaults from then on. If you find yourself trying obscure command line incantations and --- 358,364 ---- 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 C<&-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 *************** *** 539,545 **** 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 $ccflags, $ldflags, and $lddlflags so that the system's versions of as and ld are used. --- 546,552 ---- 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 $ccflags, $ldflags, and $lddlflags so that the system's versions of as and ld are used. *************** *** 583,588 **** --- 590,596 ---- Look for things like: C or C. All these mean that Perl is trying to run some external program. + =head1 INSTALLING PERL5 =head1 make install *************** *** 662,673 **** 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) so that --- 670,701 ---- to generate the LaTeX versions. + =head1 cd /usr/include; h2ph *.h sys/*.h + + Some of the perl library files need to be able to obtain information from + the system header files. This command will convert the most commonly used + header files in F into files that can be easily interpreted + by perl. These files will be placed in architectural library directory + you specified to B; by default this is + F, where B is your architecture + (such as C) and B is the version of perl you are + building (for example, C<5.003>). + + B Due to differences in the C and perl languages, the conversion of + the header files in not perfect. You may have to hand edit some of the + converted files to get them to parse correctly. For example, it breaks + spectacularly on type casting and certain structures. + =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.002 and later ONLY. 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.) ! If you want to retain a version of perl5 prior to perl5.002, 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 architecture-dependent files are stored in a version-specific directory (such as F) so that *************** *** 678,684 **** files. The standard library files in F ! should be useable by all versions of perl5. 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 --- 706,712 ---- files. The standard library files in F ! should be useable by all versions of perl5 since perl5.002. 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 *************** *** 740,743 **** =head1 LAST MODIFIED ! 19 March 1996 --- 768,771 ---- =head1 LAST MODIFIED ! 07 July 1996 #~ Update to reflect current contents of kit diff -Pcr perl5_003/MANIFEST perl5_003_01/MANIFEST *** perl5_003/MANIFEST Mon Mar 25 01:04:56 1996 --- perl5_003_01/MANIFEST Mon Jul 29 19:41:20 1996 *************** *** 10,16 **** MANIFEST This list of files Makefile.SH A script that generates Makefile README The Instructions ! README.vms Notes about VMS Todo The Wishlist XSUB.h Include file for extension subroutines av.c Array value code --- 10,18 ---- MANIFEST This list of files Makefile.SH A script that generates Makefile README The Instructions ! README.os2 Notes about OS/2 port ! README.plan9 Notes about Plan9 port ! README.vms Notes about VMS port Todo The Wishlist XSUB.h Include file for extension subroutines av.c Array value code *************** *** 87,93 **** 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 --- 89,95 ---- 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 (non-a.out) 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 *************** *** 100,105 **** --- 102,116 ---- 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/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 *************** *** 114,119 **** --- 125,135 ---- 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/typemap ODBM extension interface types + 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/Opcode/Makefile.PL Opcode extension makefile writer ext/POSIX/Makefile.PL POSIX extension makefile writer ext/POSIX/POSIX.pm POSIX extension Perl module ext/POSIX/POSIX.pod POSIX extension documentation *************** *** 142,157 **** 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 --- 158,169 ---- *************** *** 215,220 **** --- 227,235 ---- hints/netbsd.sh Hints for named architecture hints/next_3.sh Hints for named architecture hints/next_3_0.sh Hints for named architecture + hints/next_3_2.sh Hints for named architecture + hints/next_3_3.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/powerux.sh Hints for named architecture *************** *** 254,259 **** --- 269,275 ---- lib/English.pm Readable aliases for short variables lib/Env.pm Map environment into ordinary variables lib/Exporter.pm Exporter base class + 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 *************** *** 266,277 **** --- 282,295 ---- 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/Fatal.pm Make do-or-die equivalents of functions lib/File/Basename.pm A module to emulate the basename program lib/File/CheckTree.pm Perl module supporting wholesale file mode validation lib/File/Copy.pm Emulation of cp command lib/File/Find.pm Routines to do a find lib/File/Path.pm A module to do things like `mkdir -p' and `rm -r' lib/FileCache.pm Keep more files open than the system permits + lib/FindBin.pm Find name of currently executing program lib/Getopt/Long.pm A module to fetch command options (GetOptions) lib/Getopt/Std.pm A module to fetch command options (getopt, getopts) lib/I18N/Collate.pm Routines to do strxfrm-based collation *************** *** 364,373 **** 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/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.c Additional code for OS/2 --- 382,391 ---- opcode.h Automatically generated opcode header opcode.pl Opcode header generatore os2/diff.configure Patches to Configure ! os2/dl_os2.c Addon for dl_open ! os2/dlfcn.h Addon for dl_open os2/Makefile.SHs Shared library generation for OS/2 os2/POSIX.mkfifo POSIX.xs patch. os2/README.old previous OS/2 port info, partially relevant. os2/notes Notes for perl maintainer os2/os2.c Additional code for OS/2 *************** *** 383,388 **** --- 401,420 ---- 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 pod/Makefile Make pods into something else pod/buildtoc generate perltoc.pod pod/perl.pod Top level perl man page *************** *** 477,487 **** t/lib/dirhand.t See if DirHandle works t/lib/english.t See if English works t/lib/filehand.t See if FileHandle works t/lib/gdbm.t See if GDBM_File works t/lib/ndbm.t See if NDBM_File works t/lib/odbm.t See if ODBM_File works t/lib/posix.t See if POSIX works ! t/lib/safe.t See if Safe works t/lib/sdbm.t See if SDBM_File works t/lib/socket.t See if Socket works t/lib/soundex.t See if Soundex works --- 509,528 ---- t/lib/dirhand.t See if DirHandle works t/lib/english.t See if English works t/lib/filehand.t See if FileHandle 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_sock.t See if INET socket-related methods from IO work + 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/gdbm.t See if GDBM_File works 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/ops.t See if Opcode works t/lib/posix.t See if POSIX 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/socket.t See if Socket works t/lib/soundex.t See if Soundex works *************** *** 533,538 **** --- 574,580 ---- 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/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/unshift.t See if unshift works *************** *** 541,546 **** --- 583,589 ---- t/re_tests Regular expressions for regexp.t 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 *************** *** 560,565 **** --- 603,609 ---- 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/ext/filespec.t See if VMS::Filespec funtions work 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 #~ Set shared library version number correctly on NeXT #~ Updates to OS/2 support #~ Correct typo in perl.exp #~ Add universal.c #~ Add configpm dependency to Config.pm #~ Remove chmod from test target -- last modification of source tree diff -Pcr perl5_003/Makefile.SH perl5_003_01/Makefile.SH *** perl5_003/Makefile.SH Mon Mar 25 01:04:55 1996 --- perl5_003_01/Makefile.SH Thu Jul 11 12:28:50 1996 *************** *** 25,43 **** 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="";; esac --- 25,49 ---- shrpenv="" case "$d_shrplib" in *define*) + pldlflags="$cccdlflags" patchlevel=`egrep '^#define[ ]+PATCHLEVEL' patchlevel.h \ | awk '{print $3}'` ! if test -z "$isnext_4" ! then ! case "$patchlevel" in ! *[0-9]) plibsuf=.$so.$patchlevel;; ! *) plibsuf=.$so;; ! esac ! case "$shrpdir" in ! /usr/lib) ;; ! "") ;; ! *) shrpenv="env LD_RUN_PATH=$shrpdir";; ! esac ! else ! # NeXT uses $patchlevel to set the current version of the dynamic ! # library produced later. And the Major release number in the name ! plibsuf=.5.$so ! fi;; *) plibsuf=$lib_ext pldlflags="";; esac *************** *** 51,80 **** 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!' # 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. # # - !NO!SUBS! - - $spitshell >>Makefile <Makefile < tmp sh mv-if-diff tmp perlmain.c perlmain$(OBJ_EXT): perlmain.c ! $(CCCMD) $(PLDLFLAGS) $*.c # The file ext.libs is a list of libraries that must be linked in # for static extensions, e.g. -lm -lgdbm, etc. The individual --- 231,248 ---- # The Module used here must not depend on Config or any extensions. miniperl: $& miniperlmain$(OBJ_EXT) $(perllib) ! $(CC) $(LARGE) $(MAB) $(CLDFLAGS) -o miniperl miniperlmain$(OBJ_EXT) $(perllib) $(libs) @./miniperl -w -Ilib -MExporter -e 0 || $(MAKE) minitest miniperlmain$(OBJ_EXT): miniperlmain.c ! $(CCCMD) $(MAB) $(PLDLFLAGS) $*.c ! perlmain.c: miniperlmain.c config.sh $(FIRSTMAKEFILE) sh writemain $(DYNALOADER) $(static_ext) > tmp sh mv-if-diff tmp perlmain.c perlmain$(OBJ_EXT): perlmain.c ! $(CCCMD) $(MAB) $(PLDLFLAGS) $*.c # The file ext.libs is a list of libraries that must be linked in # for static extensions, e.g. -lm -lgdbm, etc. The individual *************** *** 252,273 **** -@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 --- 251,285 ---- -@test -f ext.libs || touch ext.libs perl: $& perlmain$(OBJ_EXT) $(perllib) $(DYNALOADER) $(static_ext) ext.libs ! $(SHRPENV) $(CC) $(LARGE) $(MAB) $(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) $(MAB) $(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) $(MAB) $(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*) + if test -z "$isnext_4" + then $spitshell >>Makefile <<'!NO!SUBS!' $(LD) $(LDDLFLAGS) -o $@ perl$(OBJ_EXT) $(obj) !NO!SUBS! + else + $spitshell >>Makefile <>Makefile <<'!NO!SUBS!' + libtool -dynamic -undefined warning -framework System \ + -compatibility_version 1 -current_version $$version \ + -prebind -seg1addr 0x27000000 -install_name $(shrpdir)/$@ \ + -o $@ perl.o $(obj) + !NO!SUBS! + fi ;; custom) if test -r $osname/Makefile.SHs ; then *************** *** 282,292 **** --- 294,311 ---- fi ;; *) + if test -z "$isnext_4" + then $spitshell >>Makefile <<'!NO!SUBS!' rm -f $(perllib) $(AR) rcu $(perllib) perl$(OBJ_EXT) $(obj) @$(ranlib) $(perllib) !NO!SUBS! + else + $spitshell >>Makefile <<'!NO!SUBS!' + libtool -static -o $(perllib) perl.o $(obj) + !NO!SUBS! + fi ;; esac *************** *** 298,309 **** # 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) sperl$(OBJ_EXT): perl.c perly.h patchlevel.h $(h) $(RMS) sperl.c $(LNS) perl.c sperl.c ! $(CCCMD) -DIAMSUID sperl.c $(RMS) sperl.c # We have to call our ./makedir because Ultrix 4.3 make can't handle the line --- 317,328 ---- # has been invoked correctly. suidperl: $& sperl$(OBJ_EXT) perlmain$(OBJ_EXT) $(perllib) $(DYNALOADER) $(static_ext) ext.libs ! $(CC) $(LARGE) $(MAB) $(CLDFLAGS) $(CCDLFLAGS) -o suidperl perlmain$(OBJ_EXT) sperl$(OBJ_EXT) $(perllib) $(DYNALOADER) $(static_ext) `cat ext.libs` $(libs) sperl$(OBJ_EXT): perl.c perly.h patchlevel.h $(h) $(RMS) sperl.c $(LNS) perl.c sperl.c ! $(CCCMD) $(MAB) -DIAMSUID sperl.c $(RMS) sperl.c # We have to call our ./makedir because Ultrix 4.3 make can't handle the line *************** *** 316,322 **** autosplit_lib_modules(@ARGV)' lib/*.pm lib/*/*.pm # Take care to avoid modifying lib/Config.pm without reason ! lib/Config.pm: config.sh miniperl ./miniperl configpm tmp sh mv-if-diff tmp lib/Config.pm --- 335,341 ---- autosplit_lib_modules(@ARGV)' lib/*.pm lib/*/*.pm # Take care to avoid modifying lib/Config.pm without reason ! lib/Config.pm: config.sh miniperl configpm ./miniperl configpm tmp sh mv-if-diff tmp lib/Config.pm *************** *** 349,354 **** --- 368,374 ---- @ echo 'Expect' 130 shift/reduce and 1 reduce/reduce conflict $(BYACC) -d perly.y sh $(shellflags) ./perly.fixer y.tab.c perly.c + sed -e s/stderr/Perl_debug_log/g perly.c >perly.tmp && mv perly.tmp 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 *************** *** 445,451 **** $(MAKE) depend MAKEDEPEND= config.h: config.sh ! /bin/sh config_h.SH # When done, touch perlmain.c so that it doesn't get remade each time. depend: makedepend --- 465,474 ---- $(MAKE) depend MAKEDEPEND= config.h: 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 *************** *** 458,468 **** 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 + + ======================================================== + + Notes on the patch: + ~~~~~~~~~~~~~~~~~~~ + patches should be applied as + patch -p0 <..... + All the diff.* files and POSIX.mkfifo should be applied. + + Additional files are available on + ftp://ftp.math.ohio-state.edu/pub/users/ilya/os2 + including patched pdksh and gnumake, needed for build. + + + Target: + ~~~~~~~ + + This is not supposed to make a perfect Perl on OS/2. This patch is + concerned only with perfect _build_ of Perl on OS/2. Some good + features from Andreas Kaiser port missed this port. However, most of + the features are available in different form. + + !!! Note that [gs]etpriority functions in this port are compatible + !!! with *nix, not with ak's port!!! + + The priorities are absolute, go from 32 to -95, lower is quickier. 0 + is default, + + Notes on build on OS/2: + ~~~~~~~~~~~~~~~~~~~~~~~ + The change of C code in this patch is based on the ak port of 5.001+. + + a) Make sure your sort is not the broken OS/2 one, and that you have /tmp + on the build partition. + + b) when extracting perl5.*.tar.gz you need to extract perl5.*/Configure + separately, since by default perl5.001m/configure may overwrite it; + like this: + tar vzxf perl5.004.tar.gz --case-sensitive perl5.004/Configure + + c) Necessary manual intervention when compiling on OS/2: + + Need to put perl.dll on LIBPATH after it is created. + + d) Compile summary: + ~~~~~~~~~~~~~~~ + !!! At the end of this README is independent description of the build + !!! process by Rocco Caputo. + + # Look for hints/os2.sh and correct what is different on your system + # I have rather spartan configuration. + + # Prefix means where to install: + sh Configure -des -D prefix=f:/perl5.005 + # Ignore the message about missing `ln', and about `c' option + # to tr. + make + # Will probably die after build of miniperl (unless you have DLL + # from previous compile). Need to move DLL where it belongs + # + # Somehow with 5.002b3 I needed to type another make after pod2man + make + # some warnings in POSIX.c + make test + # some tests fail, 9 or 10 on my system (see the list at end). + # + # before this you should create subdirs bin and lib in the + # prefix directory (f:/perl5.005 above): + # + # To run finer tests, cd t && perl harness + make install + + e) At the end of August GNU make and pdksh were too buggy for compile. + Both maintainers have patches that make it possible to compile perl. + The binaries are included in + ftp://ftp.math.ohio-state.edu/pub/users/ilya/os2 + patches are available too. + Note that the pdksh5.2.4 broke builds with -Zexe option because of a + changed order of executable extensions. A patch is sent to + maintainer. The version 5.2.5alpha was OK for the build, + + !!!!!!!!!!!!!!!!! + If you see that some '/' became '\' in pdksh 5.2.3, you did not apply + my patches! + Same with segfaults in Make 3.74. + !!!!!!!!!!!!!!!!! + + Problems reported: + + a) one of the latest tr is broken, get an old one :-( + 1.11 works. (On compuserver?) + b) You need a link386. + c) Get rid of invalid perl.dll on your LIBPATH. + + Note the EMX does not support en_us locale (most nobody does ;-). Some + TCP/IP update could have installed it to your config.sys. You need to + delete it until EMX is updated to support this newest discovery by IBM. + + + Send comments to ilya@math.ohio-state.edu. + + ====================================================== + Requires 0.9b (well, provision are made to make it build under 0.9a6, + but they are not tested, please inform me on success). + (earlier than 0.9b ttyname was not present, it is hard to maintain this + difference automatically, though I try). + ====================================================== + + Building with a.out style is supported by the `perl_' target of make. + Dynamic extensions are not possible with perl_.exe, since boot code + should return the retvalue on stack, the address of which is not known + to the extension. + + The reason why compiling with a.out style executables leads to problems + with dynamic extensions is: + a) OS/2 does not export symbols from executables; + b) Thus if extension needs to import symbols from an application + the symbols for the application should reside in a .dll. + c) You cannot export data from a .dll compiled with a.out style. + On the other hand, aout-style compiled extension enjoys all the + (dis)advantages of fork(). + + Check A.OUT compile with the following make targets: + + aout_test + aout_install + aout_clean + + ====================================================== + Tests which fail with OMF compile: + + io/fs.t: 2-5, 7-11, 18 as they should. + io/pipe: all, since open("|-") is not working (works with perl_.exe). + lib/"all the dbm".t: 1 test should fail (file permission). + op/fork all fail, as they should (except with perl_.exe) + op/stat 3 20 35 as they should, 39 (-t on /dev/null) ???? Sometimes 4 + - timing problem ???? + + Sometimes I have seen segfault in socket ????, only if run with Testing tools. + + A lot of `bad free'... in databases, bug in DB confirmed on other + platforms. + + Fail: Total 30 subtests (if stat:4 fails) in 10 scripts (one of 10 + is socket, which runs OK standalone). With newer configs I could not + reproduce most the crashes. + + ======================================================= + + Changes to calls to external programs: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Due to a popular demand the perl + external program calling has been changed. _If_ perl needs to call an + external program _via shell_, the X:/bin/sh.exe will be called. The + name of the shell is not overridable, except the drive letter. + + Thus means that you need to pickup some copy of a sh.exe as well (I use one + from pdksh). The drive X: above is set up automatically during the + build, is settable in runtime from $ENV{PERL_SH_DRIVE}. + + Reasons: a consensus on perl5-porters was that perl should use one + non-overridable shell per platform. The obvious choices for OS/2 are cmd.exe + and sh.exe. Having perl build itself would be impossible with cmd.exe as + a shell, thus I picked up sh.exe. Thus assures almost 100% compatibility + with the scripts coming from *nix. + + Disadvantages: sh.exe calls external programs via fork/exec, and there is + _no_ functioning exec on OS/2. exec is emulated by EMX by asyncroneous call + while the caller waits for child completion (to pretend that pid did + not change). This means that 1 _extra_ copy of sh.exe is made active via + fork/exec, which may lead to some resources taken from the system. + + The long-term solution proposed on p5-p is to have a directive + use OS2::Cmd; + which will override system(), exec(), ``, and open(,' |'). With current + perl you may override only system(), readpipe() - the explicit version + of ``, and maybe exec(). The code will substitute a one-argument system + by CORE::system('cmd.exe', '/c', shift). + + If you have some working code for OS2::Cmd.pm, please send it to me, + I will include it into distribution. I have no need for such a module, so + cannot test it. + + =================================================== + + OS/2 extensions + ~~~~~~~~~~~~~~~ + Since binaries cannot go into perl distribution, no extensions are + included. They are available in .../os2/ilyaz directory of CPAN, as + well as in my directory + ftp://ftp.math.ohio-state.edu/pub/users/ilya/os2 + + I include 3 extensions by Andread Kaiser, OS2::REXX, OS2::UPM, and OS2::FTP, + into my ftp directory, mirrored on CPAN. I made + some minor changes needed to compile them by standard tools. I cannot + test UPM and FTP, so I will appreciate your feedback. Other extensions + there are OS2::ExtAttribs, OS2::PrfDB for tied access to EAs and .INI + files - and maybe some other extensions at the time you read it. + + Note that OS2 perl defines 2 pseudo-extension functions + OS2::Copy::copy and DynaLoader::mod2fname. + + The -R switch of older perl is deprecated. If you need to call a REXX code + which needs access to variables, include the call into a REXX compartment + created by + REXX_call {...block...}; + + Two new functions are supported by REXX code, + REXX_eval 'string'; + REXX_eval_with 'string', REXX_function_name => \&perl_sub_reference; + + If you have some other extensions you want to share, send the code to me. + Two jump to mind: tied access to EA's, and tied access to system databases. + + ================================================================== + == == + == User report [my comments in brackets, IZ] == + == == + ================================================================== + + Starting in x:/usr/src, using 4OS2/32 2.5 as the command interpreter on + OS/2 2.30 with FixPak-17. DAX is installed, but this shouldn't be a + factor. Drive X is a TVFS virtual drive pointing to several physical + HPFS drives. + + >>> Make sure that no copies or perl are currently running. Miniperl + may fail during the build because it will find an older version + of perl.dll loaded in memory. + + Close any running perl scripts. + Shut down anything that might run perl scripts, like cron. + `emxload -l` to check for loaded versions of perl. + `emxload -u perl.exe` to unload them. + + >>> Pre-load some common utilities: + + emxload -e sh.exe make.exe ls.exe tr.exe id.exe sed.exe + SET GCCLOAD=30 (number of minutes to hold the compiler) + [grep egrep fgrep cat rm uniq basename uniq sort - are not bad too.] + The theory is that it's faster to demand-load the development tools + from virtual memory than it is to re-load and re-link them all the + time. This is definitely true with my system because swapfile.dat + is on a faster drive than my development environment. + + ls, tr, and id represent the GNU file, text, and shell utilities. + These may not be needed, but it makes sure that their respective + DLLs are in memory. + + >>> Unpack the perl 5_002_01 archive onto an HPFS partition. + + tar vxzf perl5_002_01.tar-gz + cd perl5.002_01 + + [Do not forget to extract Configure as described above.] + + >>> Read the README, keeping a copy open in another session for reference. + + start /c /fg less os2/README + + >>> Apply the OS/2 patches included with 5.002_01, as per the README. + + for %m in (os2\diff.*) patch -p0 < %m + patch -p0 < os2\POSIX.mkfifo + + [The patch below is already applied.] + + >>> You may need to apply this patch if you plan to run a non-standard + Configure (that is, if you defy the README). This patch will ensure + that Makefile inherits the libraries specified during Configure. + People running standard perl builds can probably ignore this patch. + + *** os2\Makefile.SHs Mon Mar 25 02:05:00 1996 + --- os2\Makefile.SHs.new Fri May 24 10:37:10 1996 + *************** + *** 9,15 **** + emximp -o perl.imp perl5.def + + perl.dll: $(obj) perl5.def perl$(OBJ_EXT) + ! $(LD) $(LDDLFLAGS) -o $@ perl$(OBJ_EXT) $(obj) -lsocket perl5.def + + perl5.def: perl.linkexp + echo "LIBRARY 'Perl' INITINSTANCE TERMINSTANCE" > $@ + --- 9,15 ---- + emximp -o perl.imp perl5.def + + perl.dll: $(obj) perl5.def perl$(OBJ_EXT) + ! $(LD) $(LDDLFLAGS) -o $@ perl$(OBJ_EXT) $(obj) $(libs) perl5.def + + perl5.def: perl.linkexp + echo "LIBRARY 'Perl' INITINSTANCE TERMINSTANCE" > $@ + *************** + *** 49,55 **** + cat perl.exports perl.map | sort | uniq -d | sed -e 's/\w\+/ "\0"/' > perl.linkexp + + perl.map: $(obj) perl$(OBJ_EXT) miniperlmain$(OBJ_EXT) + ! $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o dummy.exe miniperlmain$(OBJ_EXT) perl$(OBJ_EXT) $(obj) -lsocket -lm -Zmap -Zlinker /map + awk '{if ($$3 == "") print $$2}' perl.map + rm dummy.exe dummy.map + + --- 49,55 ---- + cat perl.exports perl.map | sort | uniq -d | sed -e 's/\w\+/ "\0"/' > perl.linkexp + + perl.map: $(obj) perl$(OBJ_EXT) miniperlmain$(OBJ_EXT) + ! $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o dummy.exe miniperlmain$(OBJ_EXT) perl$(OBJ_EXT) $(obj) $(libs) -Zmap -Zlinker /map + awk '{if ($$3 == "") print $$2}' perl.map + rm dummy.exe dummy.map + + >>> Apply the patches from Ilya's perl5.002_01 binary distribution: + + touch os2/dlfcn.h os2/dl_os2.c + patch -p1 < f:\perllib\README.fix1 + + >>> Run Configure. Most people can run it by following the README: + + sh Configure -des -D prefix=f:/usr/local + + Advanced perl users (experienced C programmers, recommended) can run + the interactive Configure and answer the questions. When in doubt + about an answer, check the EMX headers and documentation. Pick the + default answer if that doesn't help: + + sh Configure + + [Yet more advanced users just specify the answers on the command line + of Configure, like I did with prefix.] + + Note: You may need to wrap an answer in quotes if it contains + spaces. For example, "-lsocket -lm". + + Note: If you want to add some options to a long default, you can + use $* to include the default in your answer: "$* -DDEBUGGING". + + Configure warnings and errors, and possible work-arounds: + + I don't know where 'ln' is.... + (ignored; OS/2 doesn't have a ln command) + + nm didn't seem to work right. Trying emxomfar instead... + (nothing to worry about) + + The recommended value for $d_shrplib on this machine was "define"! + (kept the recommended value: y) + + Directory f:/usr/lib/perl5/os2/5.00201/CORE doesn't exist. + (created the directory from another window with + \usr\bin\mkdir -p f:/usr/lib/perl5/os2/5.00201/CORE + and then answered: y. Your directory may look different.) + + [Ignore this as well, install script will create it for you.] + + The recommended value for $i_dlfcn on this machine was "define"! + (kept the recommended value: y) + + The recommended value for $d_fork on this machine was "undef"! + (kept the recommended value: y) + + Figuring out the flag used by open() for non-blocking I/O... + Seems like we can use O_NONBLOCK. + This seems to be used for informative purposes only. + The errors that follow this (including a SIGPIPE) don't seem + to affect perl at all. These were safely ignored. + + What pager is used on your system? [/usr/ucb/more] + Had to answer "/usr/bin/less.exe" because Configure wants a + leading / (unix full path). Need to edit config.sh later with + the real full path to the pager, including the drive letter. + + [Apparently this setting is never used, so it is safe to ignore it.] + + Hmm... F:/USR/BIN/sed: Unterminated `s' command + Perl built fine even with this error, so it seems safe to + ignore. + + Things I did different from the defaults. Most (if not all) of these + are optional changes. They're listed here to show how good Configure + is at detecting the system setup. + + [I add the options to put it on command line of Configure, see below.] + + Selected 'none' for the man1 location. + (I prefer the pod2html version.) + [-D man1dir=none] + Selected 'none' for the man3 location. + (I prefer the pod2html version.) + [-D man3dir=none] + Changed the hostname and domain. + (I wanted to override a dynamic PPP address. This only + matters if other people will be using your perl build.) + [-D myhostname=my_host_name -D mydomain=.foo.org] + Fixed the e-mail address. + (Put in a known working e-mail address. This only matters + if other people will be using your perl build.) + [-D cf_email=root@myhostname.uucp] + Added some directories to the library search path. + [-D "libpth=f:/emx/lib/st f:/emx/lib"] + Added -g to the optimizer/debugger flags. + [-D optimize=-g] + Added "-lgdbm -ldb -lcrypt -lbsd" to the additional libraries. + [ -D "libs=-lsocket -lcrypt -lgdbm" + the rest of libraries will not be used] + + >>> Advanced users may want to edit config.sh when prompted by Configure. + Most (all?) of these changes aren't really necessary: + + d_getprior='define' + d_setprior='define' + (getpriority and setpriority are included in os2.c, but + Configure doesn't know to look there.) + [fixed already] + pager='f:/usr/bin/less.exe' + (Correcting Configure's insistence on a leading slash.) + bin_sh='f:/usr/bin/sh.exe' + (If Configure detects sh.exe somewhere else first. Example: + it saw sh.exe at /bin/sh.exe on my TVFS drive, but I want + perl to look for it on the physical F drive.) + aout_ccflags='... existing flags... -DDEBUGGING' + aout_cppflags='... existing flags... -DDEBUGGING' + (If you want to include DEBUGGING for the aout version.) + [Do not do it, -D optimize=-g will automatically add these flags.] + + >>> Allow Configure to make the build scripts. + + >>> Allow Configure to run `make depend`. Ignore the following warning: + + perl.h:861: warning: `DEBUGGING_MSTATS' redefined + [corrected now] + + >>> Rename any existing perl.dll, preventing anything from loading it and + saving a known working copy in case something goes wrong: + + mv /usr/lib/perl.dll /usr/lib/ilya-perl.dll + + >>> Run `make`, and ignore the following warnings: + + perl.h:861: warning: `DEBUGGING_MSTATS' redefined + [corrected now] + invalid preprocessing directive name + emxomf warning: Cycle detected by make_type + LINK386 : warning L4071: application type not specified; assuming WINDOWCOMPAT + Warning (will try anyway): No library found for -lposix + Warning (will try anyway): No library found for -lcposix + POSIX.c:203: warning: `mkfifo' redefined + POSIX.c:4603: warning: assignment makes pointer from integer without a cast + + >>> If `make` dies while "Making DynaLoader (static)", you'll need to + put miniperl in the OS/2 paths. This step is only necessary if `make` + can't find miniperl: + [I would be interested if somebody confirmes this.] + + cp perl.dll /usr/lib (where /usr/lib is in your LIBPATH) + cp miniperl.exe /usr/bin (where /usr/bin is in your PATH) + make (ignore the errors in the previous step) + + This should run to completion. + + >>> Test the build: + + make test + + These tests fail: + + io/fs..........FAILED on test 2 + + "OS/2 is not unix". Test 2 checks the link() command, which + is not supported by OS/2. + + io/pipe........f:/usr/bin/sh.exe: -c requires an argument + f:/usr/bin/sh.exe: -c requires an argument + The Unsupported function fork function is unimplemented at + io/pipe.t line 26. + FAILED on test 1 + + More "OS/2 is not unix" errors. Read ahead to find out + why fork() fails. + + op/exec........FAILED on test 4 + + if (system "true") {print "not ok 4\n";} else \ + {print "ok 4\n";} + + This fails for me, but changing it to read like this works: + + if (system '\usr\bin\true.cmd') {print "not ok 4\n";} \ + else {print "ok 4\n";} + + So you can count this as another "OS/2 is not unix". + + op/fork........The Unsupported function fork function is \ + unimplemented at op/fork.t line 8. + FAILED on test 1 + + The dynamically-loaded version of perl currently doesn't + support fork(). This is a known behavior of EMX. + + op/magic....... + Process terminated by SIGINT + ok + + The test passed even with the SIGINT message. I don't + know why, but I won't argue. + + op/stat........ls: /dev: No such file or directory + f:/usr/bin/sh.exe: ln: not found + ls: perl: No such file or directory + FAILED on test 3 + + "OS/2 is not unix". We don't have the ln command. + + lib/anydbm.....Bad free() ignored at lib/anydbm.t line 51. + Bad free() ignored at lib/anydbm.t line 51. + Bad free() ignored at lib/anydbm.t line 51. + Bad free() ignored during global destruction. + Bad free() ignored during global destruction. + Bad free() ignored during global destruction. + FAILED on test 2 + + Test 2 looks at the file permissions for a database. "OS/2 + is not unix" so the permissions aren't exactly what this test + expects. + + lib/db-btree...Bad free() ignored at lib/db-btree.t line 109. + Bad free() ignored at lib/db-btree.t line 221. + Bad free() ignored at lib/db-btree.t line 337. + Bad free() ignored at lib/db-btree.t line 349. + Bad free() ignored at lib/db-btree.t line 349. + Bad free() ignored at lib/db-btree.t line 399. + Bad free() ignored at lib/db-btree.t line 400. + Bad free() ignored at lib/db-btree.t line 401. + FAILED on test 20 + + Another file permissions test fails. + + lib/db-hash....Bad free() ignored at lib/db-hash.t line 101. + Bad free() ignored at lib/db-hash.t line 101. + Bad free() ignored at lib/db-hash.t line 101. + Bad free() ignored at lib/db-hash.t line 239. + Bad free() ignored at lib/db-hash.t line 239. + Bad free() ignored at lib/db-hash.t line 239. + Bad free() ignored at lib/db-hash.t line 253. + Bad free() ignored at lib/db-hash.t line 253. + Bad free() ignored at lib/db-hash.t line 253. + FAILED on test 16 + + Another file permissions test fails. + + lib/db-recno...Bad free() ignored at lib/db-recno.t line 138. + Bad free() ignored at lib/db-recno.t line 138. + FAILED on test 18 + + Another file permissions test fails. + + lib/gdbm.......FAILED on test 2 + + Another file permissions test fails. + + lib/sdbm.......FAILED on test 2 + + Another file permissions test fails. + + Failed 11/94 tests, 88.30% okay. + + All of which are known differences with unix or documented + behaviors in EMX. I re-run the test with Ilya's version, + and the same tests fail. This new build is a success. + [Note that bad free() mentioned above are bugs in the Berkeley + DB. They just are more visible under OS/2 with perl free(), because of + "rigid" function name resolution. + To get finer tests, cd to ./t and run + perl harness + ] + + (Actually, Ilya's perl release fails an extra test because I don't + have sed in f:\emx.add. This shows how important it is to configure + and build perl yourself instead of grabbing pre-built binaries.) + [Hmm, should not happen... There is no mentions of full_sed under ./t + directory...] + + >>> Cross your fingers and install it: + + make install + + Warnings encountered and workarounds presented.: + + WARNING: You've never run 'make test'!!! (Installing anyway.) + (Lies! All lies! At least it still installs.) + + WARNING: Can't find libperl*.dll* to install into \ + f:/usr/lib/perl5/os2/5.00201/CORE. (Installing other things anyway.) + (Safe to ignore. The important one, libperl.lib, gets copied.) + + Couldn't copy f:/usr/bin/perl5.00201.exe to f:/usr/bin/perl.exe: \ + No such file or directory + cp /usr/bin/perl5.00201.exe /usr/bin/perl.exe + + Couldn't copy f:/usr/bin/perl.exe to /usr/bin/perl.exe: No such \ + file or directory + (I think this one is safe to ignore since the two directories + point to the same place.) + + >>> Laugh maniacally because you just built and installed your own copy + of perl, with all the paths set "just so" and with whatever little + psychotic modifications you've always wanted but were afraid to add. + + ----------------------------------------------------------------------------- + + Development tools and versions: + + EMX 0.9b with emxfix04 applied. + + `ls --version` reports: 'GNU file utilities 3.12' + `tr --version` reports: 'tr - GNU textutils 1.14' + `id --version` reports: 'id - GNU sh-utils 1.12' + + `sed --version` reports: 'GNU sed version 2.05' + `awk --version` reports: 'Gnu Awk (gawk) 2.15, patchlevel 6' + `grep --version` reports an illegal option and: 'GNU grep version 2.0' + (this includes egrep) + + `sort --version` reports: 'sort - GNU textutils 1.14' + `uniq --version` reports: 'uniq - GNU textutils 1.14' + `find --version` reports: 'GNU find version 4.1' + + KSH_VERSION='@(#)PD KSH v5.2.4 96/01/17' + (Ilya's patched version.) + + `make --version` reports: 'GNU Make version 3.74' + (Ilya's patched version.) + + `emxrev` reports: + EMX : revision = 42 + EMXIO : revision = 40 + EMXLIBC : revision = 40 + EMXLIBCM : revision = 43 + EMXLIBCS : revision = 43 + EMXWRAP : revision = 40 + + ----------------------------------------------------------------------------- + + Rocco + + #~ New for Plan9 support diff -Pcr perl5_003/README.plan9 perl5_003_01/README.plan9 *** perl5_003/README.plan9 Wed Dec 31 19:00:00 1969 --- perl5_003_01/README.plan9 Wed Jul 17 19:05:02 1996 *************** *** 0 **** --- 1,27 ---- + WELCOME to Plan 9 Perl, brave soul! + This is a preliminary alpha version of Plan 9 Perl. Still to be implemented are MakeMaker and DynaLoader. Many perl commands are missing or currently behave in an inscrutable manner. These gaps will, with perserverance and a modicum of luck, be remedied in the near future.To install this software: + + 1. Create the source directories and libraries for perl by running the plan9/setup.rc command (i.e., located in the plan9 subdirectory). Note: the setup routine assumes that you haven't dearchived these files into /sys/src/cmd/perl. After running setup.rc you may delete the copy of the source you originally detarred, as source code has now been installed in /sys/src/cmd/perl. If you plan on installing perl binaries for all architectures, run "setup.rc -a". + After + 2. Making sure that you have adequate privileges to build system software, from /sys/src/cmd/perl/5.00301 run: + mk install + If you wish to install perl versions for all architectures (68020, mips, sparc and 386) run: + mk installall + + 3. Wait. The build process will take a *long* time because perl bootstraps itself. A 75MHz Pentium, 16MB RAM machine takes roughly 30 minutes to build the distribution from scratch. + + INSTALLING DOCUMENTATION + This perl distribution comes with a tremendous amount of documentation. To add these to the built-in manuals that come with Plan 9, from /sys/src/cmd/perl/5.00301 run: + mk man + To begin your reading, start with: + man perl + This is a good introduction and will direct you towards other man pages that may interest you. For information specific to Plan 9 Perl, try: + man perlplan9 + + (Note: "mk man" may produce some extraneous noise. Fear not.) + + Direct questions, comments, and the unlikely bug report (ahem) direct comments toward: + lutherh@stratcom.com + + Luther Huffman + Strategic Computer Solutions, Inc. #~ Change global symbol 'stack' to avoid collision with other code #~ Add warning for multiple attampts to delete an AV. diff -Pcr perl5_003/av.c perl5_003_01/av.c *** perl5_003/av.c Tue Jan 30 20:33:11 1996 --- perl5_003_01/av.c Fri Jul 5 18:01:23 1996 *************** *** 94,100 **** #endif ary = AvALLOC(av) + AvMAX(av) + 1; tmp = newmax - AvMAX(av); ! if (av == stack) { /* Oops, grew stack (via av_store()?) */ stack_sp = AvALLOC(av) + (stack_sp - stack_base); stack_base = AvALLOC(av); stack_max = stack_base + newmax; --- 94,100 ---- #endif ary = AvALLOC(av) + AvMAX(av) + 1; tmp = newmax - AvMAX(av); ! 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; *************** *** 196,202 **** ary = AvARRAY(av); if (AvFILL(av) < key) { if (!AvREAL(av)) { ! if (av == stack && key > stack_sp - stack_base) stack_sp = stack_base + key; /* XPUSH in disguise */ do ary[++AvFILL(av)] = &sv_undef; --- 196,202 ---- ary = AvARRAY(av); if (AvFILL(av) < key) { if (!AvREAL(av)) { ! if (av == curstack && key > stack_sp - stack_base) stack_sp = stack_base + key; /* XPUSH in disguise */ do ary[++AvFILL(av)] = &sv_undef; *************** *** 289,294 **** --- 289,299 ---- 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*/ #~ Remove old version of target before creating new one diff -Pcr perl5_003/cflags.SH perl5_003_01/cflags.SH *** perl5_003/cflags.SH Sat Jan 20 00:53:39 1996 --- perl5_003_01/cflags.SH Thu Jul 11 12:25:13 1996 *************** *** 21,26 **** --- 21,27 ---- : 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 <config.h -e 's!^#undef!/\*#define!' -e 's!^#un-def!#undef!' /* * This file was produced by running the config_h.SH script, which *************** *** 25,31 **** * 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.U,v 3.0.1.4 1995/09/25 09:10:49 ram Exp $ */ /* Configuration time: $cf_time --- 34,40 ---- * 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.SH,v 1.2 1996/07/05 23:49:13 gerti Exp $ */ /* Configuration time: $cf_time *************** *** 1342,1348 **** --- 1351,1367 ---- * This symbol hold the hexadecimal constant defined in byteorder, * i.e. 0x1234 or 0x4321, etc... */ + #ifndef NeXT #define BYTEORDER 0x$byteorder /* large digits for MSB */ + #else /* NeXT */ + + #ifdef __BIG_ENDIAN__ + #define BYTEORDER 0x4321 + #else /* __LITTLE_ENDIAN__ */ + #define BYTEORDER 0x1234 + #endif /* ENDIAN CHECK */ + + #endif /* !NeXT */ /* CSH: * This symbol, if defined, indicates that the C-shell exists. *************** *** 1567,1572 **** --- 1586,1596 ---- * some shell. */ #define STARTPERL "$startperl" /**/ + + /* BIN_SH: + * This variable contains the path to the shell. + */ + #define BIN_SH "$bin_sh" /**/ /* VOIDFLAGS: * This symbol indicates how much support of the void type is given by this #~ Output line number in die message for version mismatch #~ Add config_re subroutine #~ Preload aout-specific values in OS/2 aout Perl #~ Change end-of-block token diff -Pcr perl5_003/configpm perl5_003_01/configpm *** perl5_003/configpm Tue Feb 27 15:47:38 1996 --- perl5_003_01/configpm Mon Jul 15 13:38:04 1996 *************** *** 26,32 **** \@EXPORT_OK = qw(myconfig config_sh config_vars); \$] == $myver ! or die "Perl lib version ($myver) doesn't match executable version (\$])\\n"; # 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. --- 26,32 ---- \@EXPORT_OK = qw(myconfig config_sh config_vars); \$] == $myver ! 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. *************** *** 85,92 **** print CONFIG <<'ENDOFEND'; - tie %Config, Config; - sub TIEHASH { bless {} } sub FETCH { # check for cached value (which maybe undef so we use exists not defined) return $_[0]->{$_[1]} if (exists $_[0]->{$_[1]}); --- 85,90 ---- *************** *** 126,139 **** --- 124,169 ---- 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'; + + tie %Config, 'Config'; + 1; __END__ *************** *** 229,235 **** =cut ! ENDOFEND close(CONFIG); --- 259,265 ---- =cut ! ENDOFTAIL close(CONFIG); #~ Increment refcount on @_ when passed through to another sub, #~ so it's not freed twiceon return. diff -Pcr perl5_003/cop.h perl5_003_01/cop.h *** perl5_003/cop.h Sun Jan 28 01:19:07 1996 --- perl5_003_01/cop.h Fri Jul 5 18:01:26 1996 *************** *** 52,57 **** --- 52,60 ---- } \ if (cx->blk_sub.cv) { \ if (!(CvDEPTH(cx->blk_sub.cv) = cx->blk_sub.olddepth)) { \ + if (cx->blk_sub.hasargs) { \ + SvREFCNT_inc((SV*)cx->blk_sub.argarray); \ + } \ SvREFCNT_dec((SV*)cx->blk_sub.cv); \ } \ } #~ Add configurable destination for debug messages diff -Pcr perl5_003/deb.c perl5_003_01/deb.c *** perl5_003/deb.c Thu Jan 19 19:06:23 1995 --- perl5_003_01/deb.c Thu Jul 4 14:47:45 1996 *************** *** 30,41 **** register I32 i; GV* gv = curcop->cop_filegv; ! fprintf(stderr,"(%s:%ld)\t", SvTYPE(gv) == SVt_PVGV ? SvPVX(GvSV(gv)) : "", (long)curcop->cop_line); for (i=0; icop_filegv; ! fprintf(Perl_debug_log,"(%s:%ld)\t", SvTYPE(gv) == SVt_PVGV ? SvPVX(GvSV(gv)) : "", (long)curcop->cop_line); for (i=0; icop_filegv; ! fprintf(stderr,"(%s:%ld)\t", SvTYPE(gv) == SVt_PVGV ? SvPVX(GvSV(gv)) : "", (long)curcop->cop_line); for (i=0; icop_filegv; ! fprintf(Perl_debug_log,"(%s:%ld)\t", SvTYPE(gv) == SVt_PVGV ? SvPVX(GvSV(gv)) : "", (long)curcop->cop_line); for (i=0; i= i) break; ! fprintf(stderr, i ? " => ... " : " => "); if (stack_base[0] != &sv_undef || stack_sp < stack_base) ! fprintf(stderr, " [STACK UNDERFLOW!!!]\n"); do { ++i; if (markscan <= markstack_ptr && *markscan < i) { do { ++markscan; ! putc('*', stderr); } while (markscan <= markstack_ptr && *markscan < i); ! fprintf(stderr, " "); } if (i > top) break; ! fprintf(stderr, "%-4s ", SvPEEK(stack_base[i])); } while (1); ! fprintf(stderr, "\n"); return 0; } #else --- 106,130 ---- if (*markscan >= i) break; ! fprintf(Perl_debug_log, i ? " => ... " : " => "); if (stack_base[0] != &sv_undef || stack_sp < stack_base) ! fprintf(Perl_debug_log, " [STACK UNDERFLOW!!!]\n"); do { ++i; if (markscan <= markstack_ptr && *markscan < i) { do { ++markscan; ! putc('*', Perl_debug_log); } while (markscan <= markstack_ptr && *markscan < i); ! fprintf(Perl_debug_log, " "); } if (i > top) break; ! fprintf(Perl_debug_log, "%-4s ", SvPEEK(stack_base[i])); } while (1); ! fprintf(Perl_debug_log, "\n"); return 0; } #else #~ Add curlies to nested expression for clarity #~ Rename keyword 'explicit' to eliminate C++ collision #~ Rename chsize() function to avoid collision with libc on some systems #~ Use macro for shell name as part of OS/2 support #~ Support 64-bit times diff -Pcr perl5_003/doio.c perl5_003_01/doio.c *** perl5_003/doio.c Tue Feb 27 16:29:23 1996 --- perl5_003_01/doio.c Sat Jul 20 19:56:18 1996 *************** *** 192,200 **** } if (dodup) fd = dup(fd); ! if (!(fp = fdopen(fd,mode))) if (dodup) close(fd); } } else { --- 192,201 ---- } if (dodup) fd = dup(fd); ! if (!(fp = fdopen(fd,mode))) { if (dodup) close(fd); + } } } else { *************** *** 520,532 **** } #endif bool #ifndef CAN_PROTOTYPE ! do_close(gv,explicit) GV *gv; ! bool explicit; #else ! do_close(GV *gv, bool explicit) #endif /* CAN_PROTOTYPE */ { bool retval; --- 521,534 ---- } #endif + /* explicit renamed to avoid C++ conflict -- kja */ bool #ifndef CAN_PROTOTYPE ! do_close(gv,not_implicit) GV *gv; ! bool not_implicit; #else ! do_close(GV *gv, bool not_implicit) #endif /* CAN_PROTOTYPE */ { bool retval; *************** *** 540,551 **** } io = GvIO(gv); if (!io) { /* never opened */ ! if (dowarn && explicit) warn("Close on unopened file <%s>",GvENAME(gv)); return FALSE; } retval = io_close(io); ! if (explicit) { IoLINES(io) = 0; IoPAGE(io) = 0; IoLINES_LEFT(io) = IoPAGE_LEN(io); --- 542,553 ---- } io = GvIO(gv); if (!io) { /* never opened */ ! if (dowarn && not_implicit) warn("Close on unopened file <%s>",GvENAME(gv)); return FALSE; } retval = io_close(io); ! if (not_implicit) { IoLINES(io) = 0; IoPAGE(io) = 0; IoLINES_LEFT(io) = IoPAGE_LEN(io); *************** *** 681,687 **** /* code courtesy of William Kucharski */ #define HAS_CHSIZE ! I32 chsize(fd, length) I32 fd; /* file descriptor */ Off_t length; /* length to set file to */ { --- 683,689 ---- /* code courtesy of William Kucharski */ #define HAS_CHSIZE ! I32 my_chsize(fd, length) I32 fd; /* file descriptor */ Off_t length; /* length to set file to */ { *************** *** 1012,1018 **** break; } doshell: ! execl("/bin/sh","sh","-c",cmd,(char*)0); return FALSE; } } --- 1014,1020 ---- break; } doshell: ! execl(SH_PATH, "sh", "-c", cmd, (char*)0); return FALSE; } } *************** *** 1188,1195 **** --- 1190,1202 ---- #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)) #~ Fix length test so chomp won't clip strings shorter than $/ #~ Incorporate shared hash key support diff -Pcr perl5_003/doop.c perl5_003_01/doop.c *** perl5_003/doop.c Fri Jan 26 18:58:10 1996 --- perl5_003_01/doop.c Tue Jun 18 21:52:39 1996 *************** *** 494,500 **** ++count; } else { ! if (len < rslen) goto nope; len -= rslen - 1; s -= rslen - 1; --- 494,500 ---- ++count; } else { ! if (len < rslen - 1) goto nope; len -= rslen - 1; s -= rslen - 1; *************** *** 622,630 **** { dSP; HV *hv = (HV*)POPs; - I32 i; register HE *entry; - char *tmps; SV *tmpstr; I32 dokeys = (op->op_type == OP_KEYS); I32 dovalues = (op->op_type == OP_VALUES); --- 622,628 ---- *************** *** 638,643 **** --- 636,642 ---- (void)hv_iterinit(hv); /* always reset iterator regardless */ if (GIMME != G_ARRAY) { + I32 i; dTARGET; if (!SvRMAGICAL(hv) || !mg_find((SV*)hv,'P')) *************** *** 659,679 **** 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 (dovalues) { tmpstr = NEWSV(45,0); PUTBACK; sv_setsv(tmpstr,hv_iterval(hv,entry)); 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)); } --- 658,674 ---- PUTBACK; /* hv_iternext and hv_iterval might clobber stack_sp */ while (entry = hv_iternext(hv)) { SPAGAIN; ! if (dokeys) ! XPUSHs(hv_iterkeysv(entry)); /* won't clobber stack_sp */ if (dovalues) { tmpstr = NEWSV(45,0); PUTBACK; sv_setsv(tmpstr,hv_iterval(hv,entry)); SPAGAIN; DEBUG_H( { ! sprintf(buf,"%d%%%d=%d\n", HeHASH(entry), ! HvMAX(hv)+1, HeHASH(entry) & HvMAX(hv)); ! sv_setpv(tmpstr,buf); } ) XPUSHs(sv_2mortal(tmpstr)); } #~ Supply OS-specific values for macros added as part of Plan9 and VMS support diff -Pcr perl5_003/dosish.h perl5_003_01/dosish.h *** perl5_003/dosish.h Mon Mar 25 01:04:03 1996 --- perl5_003_01/dosish.h Thu Jul 25 16:12:47 1996 *************** *** 6,11 **** --- 6,32 ---- #define dXSUB_SYS int dummy #define TMPPATH "plXXXXXX" + /* 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 /**/ + /* * 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 #~ Use varargs prototype for dump() #~ Use configurable destination for "error" output #~ Incorporate shared hash key support diff -Pcr perl5_003/dump.c perl5_003_01/dump.c *** perl5_003/dump.c Sun Jan 28 00:15:09 1996 --- perl5_003_01/dump.c Fri Jun 21 11:22:14 1996 *************** *** 22,36 **** } #else /* Rest of file is for DEBUGGING */ static void dump(); void dump_all() { #ifdef HAS_SETLINEBUF ! setlinebuf(stderr); #else ! setvbuf(stderr, Nullch, _IOLBF, 0); #endif if (main_root) dump_op(main_root); --- 22,48 ---- } #else /* Rest of file is for DEBUGGING */ + #ifdef I_STDARG + static void dump(char *pat, ...); + #else + # if defined(I_VARARGS) + /*VARARGS0*/ + static void + dump(pat, va_alist) + char *pat; + va_dcl + # else static void dump(); + # endif + #endif void dump_all() { #ifdef HAS_SETLINEBUF ! setlinebuf(Perl_debug_log); #else ! setvbuf(Perl_debug_log, Nullch, _IOLBF, 0); #endif if (main_root) dump_op(main_root); *************** *** 47,60 **** 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; HV *hv; if (GvCV(gv)) dump_sub(gv); if (GvFORM(gv)) dump_form(gv); ! if (entry->hent_key[entry->hent_klen-1] == ':' && (hv = GvHV(gv)) && HvNAME(hv) && hv != defstash) dump_packsubs(hv); /* nested package */ } --- 59,72 ---- if (!HvARRAY(stash)) return; for (i = 0; i <= (I32) HvMAX(stash); i++) { ! for (entry = HvARRAY(stash)[i]; entry; entry = HeNEXT(entry)) { ! GV *gv = (GV*)HeVAL(entry); HV *hv; if (GvCV(gv)) dump_sub(gv); if (GvFORM(gv)) dump_form(gv); ! if (HeKEY(entry)[HeKLEN(entry)-1] == ':' && (hv = GvHV(gv)) && HvNAME(hv) && hv != defstash) dump_packsubs(hv); /* nested package */ } *************** *** 107,124 **** dump("{\n"); if (op->op_seq) ! fprintf(stderr, "%-4d", op->op_seq); else ! fprintf(stderr, " "); 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); else ! fprintf(stderr, "(%d)\n", op->op_next->op_seq); } else ! fprintf(stderr, "DONE\n"); dumplvl++; if (op->op_targ) { if (op->op_type == OP_NULL) --- 119,136 ---- dump("{\n"); if (op->op_seq) ! fprintf(Perl_debug_log, "%-4d", op->op_seq); else ! fprintf(Perl_debug_log, " "); dump("TYPE = %s ===> ", op_name[op->op_type]); if (op->op_next) { if (op->op_seq) ! fprintf(Perl_debug_log, "%d\n", op->op_next->op_seq); else ! fprintf(Perl_debug_log, "(%d)\n", op->op_next->op_seq); } else ! fprintf(Perl_debug_log, "DONE\n"); dumplvl++; if (op->op_targ) { if (op->op_type == OP_NULL) *************** *** 243,273 **** case OP_ENTERLOOP: dump("REDO ===> "); if (cLOOP->op_redoop) ! fprintf(stderr, "%d\n", cLOOP->op_redoop->op_seq); else ! fprintf(stderr, "DONE\n"); dump("NEXT ===> "); if (cLOOP->op_nextop) ! fprintf(stderr, "%d\n", cLOOP->op_nextop->op_seq); else ! fprintf(stderr, "DONE\n"); dump("LAST ===> "); if (cLOOP->op_lastop) ! fprintf(stderr, "%d\n", cLOOP->op_lastop->op_seq); else ! fprintf(stderr, "DONE\n"); break; case OP_COND_EXPR: dump("TRUE ===> "); if (cCONDOP->op_true) ! fprintf(stderr, "%d\n", cCONDOP->op_true->op_seq); else ! fprintf(stderr, "DONE\n"); dump("FALSE ===> "); if (cCONDOP->op_false) ! fprintf(stderr, "%d\n", cCONDOP->op_false->op_seq); else ! fprintf(stderr, "DONE\n"); break; case OP_MAPWHILE: case OP_GREPWHILE: --- 255,285 ---- case OP_ENTERLOOP: dump("REDO ===> "); if (cLOOP->op_redoop) ! fprintf(Perl_debug_log, "%d\n", cLOOP->op_redoop->op_seq); else ! fprintf(Perl_debug_log, "DONE\n"); dump("NEXT ===> "); if (cLOOP->op_nextop) ! fprintf(Perl_debug_log, "%d\n", cLOOP->op_nextop->op_seq); else ! fprintf(Perl_debug_log, "DONE\n"); dump("LAST ===> "); if (cLOOP->op_lastop) ! fprintf(Perl_debug_log, "%d\n", cLOOP->op_lastop->op_seq); else ! fprintf(Perl_debug_log, "DONE\n"); break; case OP_COND_EXPR: dump("TRUE ===> "); if (cCONDOP->op_true) ! fprintf(Perl_debug_log, "%d\n", cCONDOP->op_true->op_seq); else ! fprintf(Perl_debug_log, "DONE\n"); dump("FALSE ===> "); if (cCONDOP->op_false) ! fprintf(Perl_debug_log, "%d\n", cCONDOP->op_false->op_seq); else ! fprintf(Perl_debug_log, "DONE\n"); break; case OP_MAPWHILE: case OP_GREPWHILE: *************** *** 275,283 **** case OP_AND: dump("OTHER ===> "); if (cLOGOP->op_other) ! fprintf(stderr, "%d\n", cLOGOP->op_other->op_seq); else ! fprintf(stderr, "DONE\n"); break; case OP_PUSHRE: case OP_MATCH: --- 287,295 ---- case OP_AND: dump("OTHER ===> "); if (cLOGOP->op_other) ! fprintf(Perl_debug_log, "%d\n", cLOGOP->op_other->op_seq); else ! fprintf(Perl_debug_log, "DONE\n"); break; case OP_PUSHRE: case OP_MATCH: *************** *** 303,314 **** SV *sv; if (!gv) { ! fprintf(stderr,"{}\n"); return; } sv = sv_newmortal(); dumplvl++; ! fprintf(stderr,"{\n"); gv_fullname(sv,gv); dump("GV_NAME = %s", SvPVX(sv)); if (gv != GvEGV(gv)) { --- 315,326 ---- SV *sv; if (!gv) { ! fprintf(Perl_debug_log,"{}\n"); return; } sv = sv_newmortal(); dumplvl++; ! fprintf(Perl_debug_log,"{\n"); gv_fullname(sv,gv); dump("GV_NAME = %s", SvPVX(sv)); if (gv != GvEGV(gv)) { *************** *** 378,383 **** --- 390,397 ---- dump("}\n"); } + + #if !defined(I_STDARG) && !defined(I_VARARGS) /* VARARGS1 */ static void dump(arg1,arg2,arg3,arg4,arg5) char *arg1; *************** *** 386,392 **** I32 i; for (i = dumplvl*4; i; i--) (void)putc(' ',stderr); ! fprintf(stderr,arg1, arg2, arg3, arg4, arg5); } #endif --- 400,438 ---- I32 i; for (i = dumplvl*4; i; i--) + (void)putc(' ',Perl_debug_log); + fprintf(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; + #ifndef HAS_VPRINTF + int vfprintf(); + #endif + + #ifdef I_STDARG + va_start(args, pat); + #else + va_start(args); + #endif + for (i = dumplvl*4; i; i--) (void)putc(' ',stderr); ! vfprintf(Perl_debug_log,pat,args); ! va_end(args); } + #endif + #endif #~ Update to v1.24 diff -Pcr perl5_003/emacs/cperl-mode.el perl5_003_01/emacs/cperl-mode.el *** perl5_003/emacs/cperl-mode.el Mon Feb 12 14:49:43 1996 --- perl5_003_01/emacs/cperl-mode.el Fri Jul 5 13:47:35 1996 *************** *** 27,33 **** ;;; Corrections made by Ilya Zakharevich ilya@math.mps.ohio-state.edu ;;; XEmacs changes by Peter Arius arius@informatik.uni-erlangen.de ! ;; $Id: cperl-mode.el,v 1.20 1996/02/09 03:40:01 ilya Exp ilya $ ;;; To use this mode put the following into your .emacs file: --- 27,33 ---- ;;; Corrections made by Ilya Zakharevich ilya@math.mps.ohio-state.edu ;;; XEmacs changes by Peter Arius arius@informatik.uni-erlangen.de ! ;; $Id: cperl-mode.el,v 1.24 1996/07/04 02:14:27 ilya Exp ilya $ ;;; To use this mode put the following into your .emacs file: *************** *** 245,250 **** --- 245,286 ---- ;;; pod sections which are broken because of whitespace before =blah ;;; - just observe the fontification. + ;;;; After 1.20 + ;;; Anonymous subs are indented with respect to the level of + ;;; indentation of `sub' now. + ;;; {} is recognized as hash after `bless' and `return'. + ;;; Anonymous subs are split by `cperl-linefeed' as well. + ;;; Electric parens embrace a region if present. + ;;; To make `cperl-auto-newline' useful, + ;;; `cperl-auto-newline-after-colon' is introduced. + ;;; `cperl-electric-parens' is now t or nul. The old meaning is moved to + ;;; `cperl-electric-parens-string'. + ;;; `cperl-toggle-auto-newline' introduced, put on C-c C-a. + ;;; `cperl-toggle-abbrev' introduced, put on C-c C-k. + ;;; `cperl-toggle-electric' introduced, put on C-c C-e. + ;;; Beginning-of-defun-regexp was not anchored. + + ;;;; After 1.21 + ;;; Auto-newline grants `cperl-extra-newline-before-brace' if "{" is typed + ;;; after ")". + ;;; {} is recognized as expression after `tr' and friends. + + ;;;; After 1.22 + ;;; Entry Hierarchy added to imenu. Very primitive so far. + ;;; One needs newer `imenu-go'.el. A patch to `imenu' is needed as well. + ;;; Writes its own TAGS files. + ;;; Class viewer based on TAGS files. Does not trace @ISA so far. + ;;; 19.31: Problems with scan for PODs corrected. + ;;; First POD header correctly fontified. + ;;; I needed (setq imenu-use-keymap-menu t) to get good imenu in 19.31. + ;;; Apparently it makes a lot of hierarchy code obsolete... + + ;;;; After 1.23 + ;;; Tags filler now scans *.xs as well. + ;;; The info from *.xs scan is used by the hierarchy viewer. + ;;; Hierarchy viewer documented. + ;;; Bug in 19.31 imenu documented. + (defvar cperl-extra-newline-before-brace nil "*Non-nil means that if, elsif, while, until, else, for, foreach and do constructs look like: *************** *** 284,290 **** (defvar cperl-auto-newline nil "*Non-nil means automatically newline before and after braces, ! and after colons and semicolons, inserted in CPerl code.") (defvar cperl-tab-always-indent t "*Non-nil means TAB in CPerl mode should always reindent the current line, --- 320,333 ---- (defvar cperl-auto-newline nil "*Non-nil means automatically newline before and after braces, ! and after colons and semicolons, inserted in CPerl code. The following ! \\[cperl-electric-backspace] will remove the inserted whitespace. ! Insertion after colons requires both this variable and ! `cperl-auto-newline-after-colon' set.") ! ! (defvar cperl-auto-newline-after-colon nil ! "*Non-nil means automatically newline even after colons. ! Subject to `cperl-auto-newline' setting.") (defvar cperl-tab-always-indent t "*Non-nil means TAB in CPerl mode should always reindent the current line, *************** *** 298,306 **** "*Non-nil (and non-null) means { after $ in CPerl buffers should be preceeded by ` '. Can be overwritten by `cperl-hairy' if nil.") ! (defvar cperl-electric-parens "" ! "*List of parentheses that should be electric in CPerl, or null. ! Can be overwritten by `cperl-hairy' to \"({[<\" if not 'null.") (defvar cperl-electric-linefeed nil "*If true, LFD should be hairy in CPerl, otherwise C-c LFD is hairy. --- 341,364 ---- "*Non-nil (and non-null) means { after $ in CPerl buffers should be preceeded by ` '. Can be overwritten by `cperl-hairy' if nil.") ! (defvar cperl-electric-parens-string "({[<" ! "*String of parentheses that should be electric in CPerl.") ! ! (defvar cperl-electric-parens nil ! "*Non-nil (and non-null) means parentheses should be electric in CPerl. ! Can be overwritten by `cperl-hairy' if nil.") ! (defvar cperl-electric-parens-mark ! (and window-system ! (or (and (boundp 'transient-mark-mode) ; For Emacs ! transient-mark-mode) ! (and (boundp 'zmacs-regions) ; For XEmacs ! zmacs-regions))) ! "*Not-nil means that electric parens look for active mark. ! Default is yes if there is visual feedback on mark.") ! ! (defvar cperl-electric-parens-mark (and window-system transient-mark-mode) ! "*Not-nil means that electric parens look for active mark. ! Default is yes if there is visual feedback on mark.") (defvar cperl-electric-linefeed nil "*If true, LFD should be hairy in CPerl, otherwise C-c LFD is hairy. *************** *** 343,348 **** --- 401,410 ---- "*Not-nil means look for pod and here-docs sections during startup. You can always make lookup from menu or using \\[cperl-find-pods-heres].") + (defvar cperl-imenu-addback nil + "*Not-nil means add backreferences to generated `imenu's. + May require patched `imenu' and `imenu-go'.") + ;;; Short extra-docs. *************** *** 353,362 **** and/or ftp://ftp.math.ohio-state.edu/pub/users/ilya/perl ! Get support packages font-lock-extra.el, imenu-go.el from the same place. ! \(Look for other files there too... ;-) Get a patch for imenu.el in 19.29. ! Note that for 19.30 you should use choose-color.el *instead* of ! font-lock-extra.el (and you will not get smart highlighting in C :-(). Note that to enable Compile choices in the menu you need to install mode-compile.el. --- 415,425 ---- and/or ftp://ftp.math.ohio-state.edu/pub/users/ilya/perl ! Get support packages choose-color.el (or font-lock-extra.el before ! 19.30), imenu-go.el from the same place. \(Look for other files there ! too... ;-) Get a patch for imenu.el in 19.29. Note that for 19.30 and ! later you should use choose-color.el *instead* of font-lock-extra.el ! \(and you will not get smart highlighting in C :-(). Note that to enable Compile choices in the menu you need to install mode-compile.el. *************** *** 365,372 **** http://www.metronet.com:70/9/perlinfo/perl5/manual/perl5-info.tar.gz \(may be quite obsolete, but still useful). ! If you use imenu-go, run imenu on perl5-info buffer (you can do it from ! CPerl menu). Before reporting (non-)problems look in the problem section on what I know about them.") --- 428,441 ---- http://www.metronet.com:70/9/perlinfo/perl5/manual/perl5-info.tar.gz \(may be quite obsolete, but still useful). ! If you use imenu-go, run imenu on perl5-info buffer (you can do it ! from CPerl menu). If many files are related, generate TAGS files from ! Tools/Tags submenu in CPerl menu. ! ! If some class structure is too complicated, use Tools/Hierarchy-view ! from CPerl menu, or hierarchic view of imenu. The second one is very ! rudimental, the first one requires generation of TAGS from ! CPerl/Tools/Tags menu beforehand. Before reporting (non-)problems look in the problem section on what I know about them.") *************** *** 374,381 **** (defvar cperl-problems 'please-ignore-this-line "Emacs has a _very_ restricted syntax parsing engine. ! It may be corrected on the level of C ocde, please look in the ! `non-problems' section if you want to volonteer. CPerl mode tries to corrects some Emacs misunderstandings, however, for effeciency reasons the degree of correction is different for --- 443,450 ---- (defvar cperl-problems 'please-ignore-this-line "Emacs has a _very_ restricted syntax parsing engine. ! It may be corrected on the level of C code, please look in the ! `non-problems' section if you want to volunteer. CPerl mode tries to corrects some Emacs misunderstandings, however, for effeciency reasons the degree of correction is different for *************** *** 435,440 **** --- 504,513 ---- a) sub in $mypackage::sub may be highlighted. b) -z in [a-z] may be highlighted. c) if your regexp contains a keyword (like \"s\"), it may be highlighted. + + + Imenu in 19.31 is broken. Set `imenu-use-keymap-menu' to t, and remove + `car' before `imenu-choose-buffer-index' in `imenu'. ") *************** *** 452,463 **** (setq del-back-ch (aref del-back-ch 0))) (if (cperl-xemacs-p) ! ;; "Active regions" are on: use region only if active ! ;; "Active regions" are off: use region unconditionally ! (defun cperl-use-region-p () ! (if zmacs-regions (mark) t)) (defun cperl-use-region-p () ! (if transient-mark-mode mark-active t))) (defsubst cperl-enable-font-lock () (or (cperl-xemacs-p) window-system)) --- 525,539 ---- (setq del-back-ch (aref del-back-ch 0))) (if (cperl-xemacs-p) ! (progn ! ;; "Active regions" are on: use region only if active ! ;; "Active regions" are off: use region unconditionally ! (defun cperl-use-region-p () ! (if zmacs-regions (mark) t)) ! (defun cperl-mark-active () (mark))) (defun cperl-use-region-p () ! (if transient-mark-mode mark-active t)) ! (defun cperl-mark-active () mark-active)) (defsubst cperl-enable-font-lock () (or (cperl-xemacs-p) window-system)) *************** *** 482,487 **** --- 558,567 ---- 'lazy-lock) "Text property which inhibits refontification.") + (defsubst cperl-put-do-not-fontify (from to) + (put-text-property (max (point-min) (1- from)) + to cperl-do-not-fontify t)) + ;;; Probably it is too late to set these guys already, but it can help later: *************** *** 525,534 **** (define-key cperl-mode-map ":" 'cperl-electric-terminator) (define-key cperl-mode-map "\C-j" 'newline-and-indent) (define-key cperl-mode-map "\C-c\C-j" 'cperl-linefeed) (define-key cperl-mode-map "\e\C-q" 'cperl-indent-exp) ; Usually not bound ;;(define-key cperl-mode-map "\M-q" 'cperl-fill-paragraph) ;;(define-key cperl-mode-map "\e;" 'cperl-indent-for-comment) ! (define-key cperl-mode-map "\177" 'backward-delete-char-untabify) (define-key cperl-mode-map "\t" 'cperl-indent-command) (if (cperl-xemacs-p) ;; don't clobber the backspace binding: --- 605,617 ---- (define-key cperl-mode-map ":" 'cperl-electric-terminator) (define-key cperl-mode-map "\C-j" 'newline-and-indent) (define-key cperl-mode-map "\C-c\C-j" 'cperl-linefeed) + (define-key cperl-mode-map "\C-c\C-a" 'cperl-toggle-auto-newline) + (define-key cperl-mode-map "\C-c\C-k" 'cperl-toggle-abbrev) + (define-key cperl-mode-map "\C-c\C-e" 'cperl-toggle-electric) (define-key cperl-mode-map "\e\C-q" 'cperl-indent-exp) ; Usually not bound ;;(define-key cperl-mode-map "\M-q" 'cperl-fill-paragraph) ;;(define-key cperl-mode-map "\e;" 'cperl-indent-for-comment) ! (define-key cperl-mode-map "\177" 'cperl-electric-backspace) (define-key cperl-mode-map "\t" 'cperl-indent-command) (if (cperl-xemacs-p) ;; don't clobber the backspace binding: *************** *** 585,605 **** "----" ("Tools" ["Imenu" imenu (fboundp 'imenu)] ["Imenu on info" cperl-imenu-on-info (featurep 'imenu)] ("Tags" ! ["Create tags for current file" cperl-etags t] ! ["Add tags for current file" (cperl-etags t) t] ! ["Create tags for Perl files in directory" (cperl-etags nil t) t] ! ["Add tags for Perl files in directory" (cperl-etags t t) t] ["Create tags for Perl files in (sub)directories" ! (cperl-etags nil 'recursive) t] ["Add tags for Perl files in (sub)directories" ! (cperl-etags t 'recursive) t]) ! ["Recalculate PODs" cperl-find-pods-heres t] ["Define word at point" imenu-go-find-at-position (fboundp 'imenu-go-find-at-position)] ["Help on function" cperl-info-on-command t] ["Help on function at point" cperl-info-on-current-command t]) ("Indent styles..." ["GNU" (cperl-set-style "GNU") t] ["C++" (cperl-set-style "C++") t] --- 668,706 ---- "----" ("Tools" ["Imenu" imenu (fboundp 'imenu)] + ["Class Hierarchy from TAGS" cperl-tags-hier-init t] + ;;["Update classes" (cperl-tags-hier-init t) tags-table-list] ["Imenu on info" cperl-imenu-on-info (featurep 'imenu)] ("Tags" ! ;;; ["Create tags for current file" cperl-etags t] ! ;;; ["Add tags for current file" (cperl-etags t) t] ! ;;; ["Create tags for Perl files in directory" (cperl-etags nil t) t] ! ;;; ["Add tags for Perl files in directory" (cperl-etags t t) t] ! ;;; ["Create tags for Perl files in (sub)directories" ! ;;; (cperl-etags nil 'recursive) t] ! ;;; ["Add tags for Perl files in (sub)directories" ! ;;; (cperl-etags t 'recursive) t]) ! ;;;; cperl-write-tags (&optional file erase recurse dir inbuffer) ! ["Create tags for current file" (cperl-write-tags nil t) t] ! ["Add tags for current file" (cperl-write-tags) t] ! ["Create tags for Perl files in directory" ! (cperl-write-tags nil t nil t) t] ! ["Add tags for Perl files in directory" ! (cperl-write-tags nil nil nil t) t] ["Create tags for Perl files in (sub)directories" ! (cperl-write-tags nil t t t) t] ["Add tags for Perl files in (sub)directories" ! (cperl-write-tags nil nil t t) t]) ! ["Recalculate PODs and HEREs" cperl-find-pods-heres t] ["Define word at point" imenu-go-find-at-position (fboundp 'imenu-go-find-at-position)] ["Help on function" cperl-info-on-command t] ["Help on function at point" cperl-info-on-current-command t]) + ("Toggle..." + ["Auto newline" cperl-toggle-auto-newline t] + ["Electric parens" cperl-toggle-electric t] + ["Electric keywords" cperl-toggle-abbrev t] + ) ("Indent styles..." ["GNU" (cperl-set-style "GNU") t] ["C++" (cperl-set-style "C++") t] *************** *** 669,676 **** \"paren\" to avoid the expansion. The processing of < is special, since most the time you mean \"less\". Cperl mode tries to guess whether you want to type pair <>, and inserts is if it ! appropriate. You can set `cperl-electric-parens' to the string that contains the parenths from the above list you want to be electrical. CPerl mode provides expansion of the Perl control constructs: if, else, elsif, unless, while, until, for, and foreach. --- 770,780 ---- \"paren\" to avoid the expansion. The processing of < is special, since most the time you mean \"less\". Cperl mode tries to guess whether you want to type pair <>, and inserts is if it ! appropriate. You can set `cperl-electric-parens-string' to the string that contains the parenths from the above list you want to be electrical. + Electricity of parenths is controlled by `cperl-electric-parens'. + You may also set `cperl-electric-parens-mark' to have electric parens + look for active mark and \"embrace\" a region if possible.' CPerl mode provides expansion of the Perl control constructs: if, else, elsif, unless, while, until, for, and foreach. *************** *** 706,719 **** Setting the variable `cperl-font-lock' to t switches on font-lock-mode, `cperl-electric-lbrace-space' to t switches on ! electric space between $ and {, `cperl-electric-parens' is the string ! that contains parentheses that should be electric in CPerl, setting ! `cperl-electric-keywords' enables electric expansion of control ! structures in CPerl. `cperl-electric-linefeed' governs which one of ! two linefeed behavior is preferable. You can enable all these options ! simultaneously (recommended mode of use) by setting `cperl-hairy' to ! t. In this case you can switch separate options off by setting them ! to `null'. If your site has perl5 documentation in info format, you can use commands \\[cperl-info-on-current-command] and \\[cperl-info-on-command] to access it. --- 810,826 ---- Setting the variable `cperl-font-lock' to t switches on font-lock-mode, `cperl-electric-lbrace-space' to t switches on ! electric space between $ and {, `cperl-electric-parens-string' is the ! string that contains parentheses that should be electric in CPerl (see ! also `cperl-electric-parens-mark' and `cperl-electric-parens'), ! setting `cperl-electric-keywords' enables electric expansion of ! control structures in CPerl. `cperl-electric-linefeed' governs which ! one of two linefeed behavior is preferable. You can enable all these ! options simultaneously (recommended mode of use) by setting ! `cperl-hairy' to t. In this case you can switch separate options off ! by setting them to `null'. Note that one may undo the extra whitespace ! inserted by semis and braces in `auto-newline'-mode by consequent ! \\[cperl-electric-backspace]. If your site has perl5 documentation in info format, you can use commands \\[cperl-info-on-current-command] and \\[cperl-info-on-command] to access it. *************** *** 732,738 **** regardless of where in the line point is when the TAB command is used. `cperl-auto-newline' Non-nil means automatically newline before and after braces, ! and after colons and semicolons, inserted in Perl code. `cperl-indent-level' Indentation of Perl statements within surrounding block. The surrounding block's indentation is the indentation --- 839,851 ---- regardless of where in the line point is when the TAB command is used. `cperl-auto-newline' Non-nil means automatically newline before and after braces, ! and after colons and semicolons, inserted in Perl code. The following ! \\[cperl-electric-backspace] will remove the inserted whitespace. ! Insertion after colons requires both this variable and ! `cperl-auto-newline-after-colon' set. ! `cperl-auto-newline-after-colon' ! Non-nil means automatically newline even after colons. ! Subject to `cperl-auto-newline' setting. `cperl-indent-level' Indentation of Perl statements within surrounding block. The surrounding block's indentation is the indentation *************** *** 825,831 **** (make-local-variable 'comment-start-skip) (setq comment-start-skip "#+ *") (make-local-variable 'defun-prompt-regexp) ! (setq defun-prompt-regexp "[ \t]*sub\\s +\\([^ \t\n{;]+\\)\\s *") (make-local-variable 'comment-indent-function) (setq comment-indent-function 'cperl-comment-indent) (make-local-variable 'parse-sexp-ignore-comments) --- 938,944 ---- (make-local-variable 'comment-start-skip) (setq comment-start-skip "#+ *") (make-local-variable 'defun-prompt-regexp) ! (setq defun-prompt-regexp "^[ \t]*sub\\s +\\([^ \t\n{;]+\\)\\s *") (make-local-variable 'comment-indent-function) (setq comment-indent-function 'cperl-comment-indent) (make-local-variable 'parse-sexp-ignore-comments) *************** *** 938,944 **** (defun cperl-electric-brace (arg &optional only-before) "Insert character and correct line's indentation. If ONLY-BEFORE and `cperl-auto-newline', will insert newline before the ! place (even in empty line), but not after." (interactive "P") (let (insertpos) (if (and (not arg) ; No args, end (of empty line or auto) --- 1051,1059 ---- (defun cperl-electric-brace (arg &optional only-before) "Insert character and correct line's indentation. If ONLY-BEFORE and `cperl-auto-newline', will insert newline before the ! place (even in empty line), but not after. If after \")\" and the inserted ! char is \"{\", insert extra newline before only if ! `cperl-extra-newline-before-brace'." (interactive "P") (let (insertpos) (if (and (not arg) ; No args, end (of empty line or auto) *************** *** 947,952 **** --- 1062,1074 ---- (save-excursion (skip-chars-backward " \t") (bolp))) + (and (eq last-command-char ?\{) ; Do not insert newline + ;; if after ")" and `cperl-extra-newline-before-brace' + ;; is nil, do not insert extra newline. + (not cperl-extra-newline-before-brace) + (save-excursion + (skip-chars-backward " \t") + (eq (preceding-char) ?\)))) (if cperl-auto-newline (progn (cperl-indent-line) (newline) t) nil))) (progn *************** *** 973,990 **** (defun cperl-electric-lbrace (arg) "Insert character, correct line's indentation, correct quoting by space." (interactive "P") ! (let (pos after (cperl-auto-newline cperl-auto-newline)) (and (cperl-val 'cperl-electric-lbrace-space) (eq (preceding-char) ?$) (save-excursion (skip-chars-backward "$") (looking-at "\\(\\$\\$\\)*\\$\\([^\\$]\\|$\\)")) (insert ? )) ! (if (cperl-after-expr-p) nil (setq cperl-auto-newline nil)) (cperl-electric-brace arg) ! (and (eq last-command-char ?{) (memq last-command-char ! (append (cperl-val 'cperl-electric-parens "" "([{<") nil)) (setq last-command-char ?} pos (point)) (progn (cperl-electric-brace arg t) (goto-char pos))))) --- 1095,1123 ---- (defun cperl-electric-lbrace (arg) "Insert character, correct line's indentation, correct quoting by space." (interactive "P") ! (let (pos after ! (cperl-auto-newline cperl-auto-newline) ! (other-end (if (and cperl-electric-parens-mark ! (cperl-mark-active) ! (> (mark) (point))) ! (save-excursion ! (goto-char (mark)) ! (point-marker)) ! nil))) (and (cperl-val 'cperl-electric-lbrace-space) (eq (preceding-char) ?$) (save-excursion (skip-chars-backward "$") (looking-at "\\(\\$\\$\\)*\\$\\([^\\$]\\|$\\)")) (insert ? )) ! (if (cperl-after-expr-p nil "{};)") nil (setq cperl-auto-newline nil)) (cperl-electric-brace arg) ! (and (cperl-val 'cperl-electric-parens) ! (eq last-command-char ?{) (memq last-command-char ! (append cperl-electric-parens-string nil)) ! (or (if other-end (goto-char (marker-position other-end))) ! t) (setq last-command-char ?} pos (point)) (progn (cperl-electric-brace arg t) (goto-char pos))))) *************** *** 992,1000 **** (defun cperl-electric-paren (arg) "Insert a matching pair of parentheses." (interactive "P") ! (let ((beg (save-excursion (beginning-of-line) (point)))) ! (if (and (memq last-command-char ! (append (cperl-val 'cperl-electric-parens "" "([{<") nil)) (>= (save-excursion (cperl-to-comment-or-eol) (point)) (point)) ;;(not (save-excursion (search-backward "#" beg t))) (if (eq last-command-char ?<) --- 1125,1141 ---- (defun cperl-electric-paren (arg) "Insert a matching pair of parentheses." (interactive "P") ! (let ((beg (save-excursion (beginning-of-line) (point))) ! (other-end (if (and cperl-electric-parens-mark ! (cperl-mark-active) ! (> (mark) (point))) ! (save-excursion ! (goto-char (mark)) ! (point-marker)) ! nil))) ! (if (and (cperl-val 'cperl-electric-parens) ! (memq last-command-char ! (append cperl-electric-parens-string nil)) (>= (save-excursion (cperl-to-comment-or-eol) (point)) (point)) ;;(not (save-excursion (search-backward "#" beg t))) (if (eq last-command-char ?<) *************** *** 1002,1007 **** --- 1143,1149 ---- 1)) (progn (insert last-command-char) + (if other-end (goto-char (marker-position other-end))) (insert (cdr (assoc last-command-char '((?{ .?}) (?[ . ?]) (?( . ?)) *************** *** 1012,1018 **** (defun cperl-electric-keyword () "Insert a construction appropriate after a keyword." ! (let ((beg (save-excursion (beginning-of-line) (point)))) (and (save-excursion (backward-sexp 1) (cperl-after-expr-p nil "{};:")) --- 1154,1161 ---- (defun cperl-electric-keyword () "Insert a construction appropriate after a keyword." ! (let ((beg (save-excursion (beginning-of-line) (point))) ! (dollar (eq (preceding-char) ?$))) (and (save-excursion (backward-sexp 1) (cperl-after-expr-p nil "{};:")) *************** *** 1024,1029 **** --- 1167,1173 ---- (save-excursion (or (not (re-search-backward "^=" nil t)) (looking-at "=cut"))) (progn + (and dollar (insert " $")) (cperl-indent-line) ;;(insert " () {\n}") (cond *************** *** 1039,1045 **** ) (or (looking-at "[ \t]\\|$") (insert " ")) (cperl-indent-line) ! (search-backward ")") (cperl-putback-char del-back-ch))))) (defun cperl-electric-else () --- 1183,1191 ---- ) (or (looking-at "[ \t]\\|$") (insert " ")) (cperl-indent-line) ! (if dollar (progn (search-backward "$") ! (forward-char 1)) ! (search-backward ")")) (cperl-putback-char del-back-ch))))) (defun cperl-electric-else () *************** *** 1081,1087 **** (pos (point)) start) (if (and ; Check if we need to split: ; i.e., on a boundary and inside "{...}" - ;;(not (search-backward "\\(^\\|[^$\\\\]\\)#" beg t)) (save-excursion (cperl-to-comment-or-eol) (>= (point) pos)) (or (save-excursion --- 1227,1232 ---- *************** *** 1093,1113 **** (save-excursion (and (eq (car (parse-partial-sexp pos end -1)) -1) ! (looking-at "[ \t]*\\($\\|#\\)") ! ;;(setq finish (point-marker)) (progn (backward-sexp 1) (setq start (point-marker)) ! (<= start pos)) ! ;;(looking-at "[^{}\n]*}[ \t]*$") ; Will fail if there are intervening {}'s ! ;;(search-backward "{" beg t) ! ;;(looking-at "{[^{}\n]*}[ \t]*$") ! ))) ! ;;(or (looking-at "[ \t]*}") ; and on a boundary of statements ! ;; (save-excursion ! ;; (skip-chars-backward " \t") ! ;; (forward-char -1) ! ;; (looking-at "[{;]")))) (progn (skip-chars-backward " \t") (or (memq (preceding-char) (append ";{" nil)) --- 1238,1248 ---- (save-excursion (and (eq (car (parse-partial-sexp pos end -1)) -1) ! (looking-at "[,; \t]*\\($\\|#\\)") ; Comma to allow anon subr (progn (backward-sexp 1) (setq start (point-marker)) ! (<= start pos))))) (progn (skip-chars-backward " \t") (or (memq (preceding-char) (append ";{" nil)) *************** *** 1115,1122 **** (insert "\n") (forward-line -1) (cperl-indent-line) - ;;(end-of-line) - ;;(search-backward "{" beg) (goto-char start) (or (looking-at "{[ \t]*$") ; If there is a statement ; before, move it to separate line --- 1250,1255 ---- *************** *** 1127,1133 **** (forward-line 1) ; We are on the target line (cperl-indent-line) (beginning-of-line) ! (or (looking-at "[ \t]*}[ \t]*$") ; If there is a statement ; after, move it to separate line (progn (end-of-line) --- 1260,1266 ---- (forward-line 1) ; We are on the target line (cperl-indent-line) (beginning-of-line) ! (or (looking-at "[ \t]*}[,; \t]*$") ; If there is a statement ; after, move it to separate line (progn (end-of-line) *************** *** 1157,1163 **** (defun cperl-electric-terminator (arg) "Insert character and correct line's indentation." (interactive "P") ! (let (insertpos (end (point))) (if (and (not arg) (eolp) (not (save-excursion (beginning-of-line) --- 1290,1299 ---- (defun cperl-electric-terminator (arg) "Insert character and correct line's indentation." (interactive "P") ! (let (insertpos (end (point)) ! (auto (and cperl-auto-newline ! (or (not (eq last-command-char ?:)) ! cperl-auto-newline-after-colon)))) (if (and (not arg) (eolp) (not (save-excursion (beginning-of-line) *************** *** 1180,1205 **** (let ((pps (parse-partial-sexp (point) end))) (or (nth 3 pps) (nth 4 pps) (nth 5 pps)))))))) (progn - (if cperl-auto-newline - (setq insertpos (point))) (insert last-command-char) (cperl-indent-line) ! (if cperl-auto-newline (progn (newline) (cperl-indent-line))) (save-excursion ! (if insertpos (progn (goto-char insertpos) ! (search-forward (make-string ! 1 last-command-char)) ! (setq insertpos (1- (point))))) ! (delete-char -1)))) (if insertpos (save-excursion (goto-char insertpos) (self-insert-command (prefix-numeric-value arg))) (self-insert-command (prefix-numeric-value arg))))) (defun cperl-inside-parens-p () (condition-case () (save-excursion --- 1316,1362 ---- (let ((pps (parse-partial-sexp (point) end))) (or (nth 3 pps) (nth 4 pps) (nth 5 pps)))))))) (progn (insert last-command-char) + (forward-char -1) + (if auto (setq insertpos (point-marker))) + (forward-char 1) (cperl-indent-line) ! (if auto (progn (newline) (cperl-indent-line))) + ;; (save-excursion + ;; (if insertpos (progn (goto-char (marker-position insertpos)) + ;; (search-forward (make-string + ;; 1 last-command-char)) + ;; (setq insertpos (1- (point))))) + ;; (delete-char -1)))) (save-excursion ! (if insertpos (goto-char (marker-position insertpos)) ! (forward-char -1)) ! (delete-char 1)))) (if insertpos (save-excursion (goto-char insertpos) (self-insert-command (prefix-numeric-value arg))) (self-insert-command (prefix-numeric-value arg))))) + (defun cperl-electric-backspace (arg) + "Backspace-untabify, or remove the whitespace inserted by an electric key." + (interactive "p") + (if (and cperl-auto-newline + (memq last-command '(cperl-electric-semi + cperl-electric-terminator + cperl-electric-lbrace)) + (memq (preceding-char) '(? ?\t ?\n))) + (let (p) + (if (eq last-command 'cperl-electric-lbrace) + (skip-chars-forward " \t\n")) + (setq p (point)) + (skip-chars-backward " \t\n") + (delete-region (point) p)) + (backward-delete-char-untabify arg))) + (defun cperl-inside-parens-p () (condition-case () (save-excursion *************** *** 1211,1217 **** (error nil))) (defun cperl-indent-command (&optional whole-exp) - (interactive "P") "Indent current line as Perl code, or in some cases insert a tab character. If `cperl-tab-always-indent' is non-nil (the default), always indent current line. Otherwise, indent the current line only if point is at the left margin --- 1368,1373 ---- *************** *** 1221,1226 **** --- 1377,1383 ---- means indent rigidly all the lines of the expression starting after point so that this line becomes properly indented. The relative indentation among the lines of the expression are preserved." + (interactive "P") (if whole-exp ;; If arg, always indent this line as Perl ;; and shift remaining lines of expression the same amount. *************** *** 1334,1340 **** (and (eq (char-syntax (preceding-char)) ?w) (progn (backward-sexp) ! (or (looking-at "\\sw+[ \t\n\f]*[{#]") ; Method call syntax (progn (skip-chars-backward " \t\n\f") (and (eq (char-syntax (preceding-char)) ?w) --- 1491,1499 ---- (and (eq (char-syntax (preceding-char)) ?w) (progn (backward-sexp) ! ;; Need take into account `bless', `return', `tr',... ! (or (and (looking-at "\\sw+[ \t\n\f]*[{#]") ; Method call syntax ! (not (looking-at "\\(bless\\|return\\|qw\\|tr\\|[smy]\\)\\>"))) (progn (skip-chars-backward " \t\n\f") (and (eq (char-syntax (preceding-char)) ?w) *************** *** 1535,1551 **** (progn (if (eq (preceding-char) ?\)) (forward-sexp -1)) ! ;; Get initial indentation of the line we are on. ! ;; If line starts with label, calculate label indentation ! (if (save-excursion ! (beginning-of-line) ! (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_]*:[^:]")) ! (if (> (current-indentation) cperl-min-label-indent) ! (- (current-indentation) cperl-label-offset) ! (cperl-calculate-indent ! (if (and parse-start (<= parse-start (point))) ! parse-start))) ! (current-indentation)))))))))))) (defvar cperl-indent-alist '((string nil) --- 1694,1728 ---- (progn (if (eq (preceding-char) ?\)) (forward-sexp -1)) ! ;; In the case it starts a subroutine, indent with ! ;; respect to `sub', not with respect to the the ! ;; first thing on the line, say in the case of ! ;; anonymous sub in a hash. ! ;; ! (skip-chars-backward " \t") ! (if (and (eq (preceding-char) ?b) ! (progn ! (forward-word -1) ! (looking-at "sub\\>")) ! (setq old-indent ! (nth 1 ! (parse-partial-sexp ! (save-excursion (beginning-of-line) (point)) ! (point))))) ! (progn (goto-char (1+ old-indent)) ! (skip-chars-forward " \t") ! (current-column)) ! ;; Get initial indentation of the line we are on. ! ;; If line starts with label, calculate label indentation ! (if (save-excursion ! (beginning-of-line) ! (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_]*:[^:]")) ! (if (> (current-indentation) cperl-min-label-indent) ! (- (current-indentation) cperl-label-offset) ! (cperl-calculate-indent ! (if (and parse-start (<= parse-start (point))) ! parse-start))) ! (current-indentation))))))))))))) (defvar cperl-indent-alist '((string nil) *************** *** 1782,1788 **** (let (face head-face here-face b e bb tag err (cperl-pod-here-fontify (eval cperl-pod-here-fontify)) (case-fold-search nil) (inhibit-read-only t) (buffer-undo-list t) ! (modified (buffer-modified-p))) (unwind-protect (progn (save-excursion --- 1959,1966 ---- (let (face head-face here-face b e bb tag err (cperl-pod-here-fontify (eval cperl-pod-here-fontify)) (case-fold-search nil) (inhibit-read-only t) (buffer-undo-list t) ! (modified (buffer-modified-p)) ! (after-change-functions nil)) (unwind-protect (progn (save-excursion *************** *** 1800,1827 **** (message "=cut is not preceeded by a pod section") (setq err (point))) (beginning-of-line) (setq b (point) bb b) (or (re-search-forward "\n\n=cut\\>" max 'toend) (message "Cannot find the end of a pod section")) ! (beginning-of-line 4) (setq e (point)) (put-text-property b e 'in-pod t) (goto-char b) (while (re-search-forward "\n\n[ \t]" e t) (beginning-of-line) (put-text-property b (point) 'syntax-type 'pod) ! (put-text-property (max (point-min) (1- b)) ! (point) cperl-do-not-fontify t) (if cperl-pod-here-fontify (put-text-property b (point) 'face face)) (re-search-forward "\n\n[^ \t\f]" e 'toend) (beginning-of-line) (setq b (point))) (put-text-property (point) e 'syntax-type 'pod) ! (put-text-property (max (point-min) (1- (point))) ! e cperl-do-not-fontify t) (if cperl-pod-here-fontify (progn (put-text-property (point) e 'face face) (goto-char bb) (while (re-search-forward ;; One paragraph "\n\n=[a-zA-Z0-9]+\\>[ \t]*\\(\\(\n?[^\n]\\)+\\)$" --- 1978,2013 ---- (message "=cut is not preceeded by a pod section") (setq err (point))) (beginning-of-line) + (setq b (point) bb b) (or (re-search-forward "\n\n=cut\\>" max 'toend) (message "Cannot find the end of a pod section")) ! (beginning-of-line 3) (setq e (point)) (put-text-property b e 'in-pod t) (goto-char b) (while (re-search-forward "\n\n[ \t]" e t) (beginning-of-line) (put-text-property b (point) 'syntax-type 'pod) ! (cperl-put-do-not-fontify b (point)) ! ;;(put-text-property (max (point-min) (1- b)) ! ;; (point) cperl-do-not-fontify t) (if cperl-pod-here-fontify (put-text-property b (point) 'face face)) (re-search-forward "\n\n[^ \t\f]" e 'toend) (beginning-of-line) (setq b (point))) (put-text-property (point) e 'syntax-type 'pod) ! (cperl-put-do-not-fontify (point) e) ! ;;(put-text-property (max (point-min) (1- (point))) ! ;; e cperl-do-not-fontify t) (if cperl-pod-here-fontify (progn (put-text-property (point) e 'face face) (goto-char bb) + (if (looking-at + "=[a-zA-Z0-9]+\\>[ \t]*\\(\\(\n?[^\n]\\)+\\)$") + (put-text-property + (match-beginning 1) (match-end 1) + 'face head-face)) (while (re-search-forward ;; One paragraph "\n\n=[a-zA-Z0-9]+\\>[ \t]*\\(\\(\n?[^\n]\\)+\\)$" *************** *** 1847,1856 **** (progn (put-text-property (match-beginning 0) (match-end 0) 'face font-lock-reference-face) ! (put-text-property (max (point-min) (1- b)) ! (min (point-mox) ! (1+ (match-end 0))) ! cperl-do-not-fontify t) (put-text-property b (match-beginning 0) 'face here-face))) (put-text-property b (match-beginning 0) --- 2033,2043 ---- (progn (put-text-property (match-beginning 0) (match-end 0) 'face font-lock-reference-face) ! (cperl-put-do-not-fontify b (match-end 0)) ! ;;(put-text-property (max (point-min) (1- b)) ! ;; (min (point-max) ! ;; (1+ (match-end 0))) ! ;; cperl-do-not-fontify t) (put-text-property b (match-beginning 0) 'face here-face))) (put-text-property b (match-beginning 0) *************** *** 2104,2119 **** (defvar imenu-example--function-name-regexp-perl "^\\([ \t]*\\(sub\\|package\\)[ \t\n]+\\([a-zA-Z_0-9:']+\\)[ \t]*\\|=head\\([12]\\)[ \t]+\\([^\n]+\\)$\\)") (defun imenu-example--create-perl-index (&optional regexp) (require 'cl) (let ((index-alist '()) (index-pack-alist '()) (index-pod-alist '()) (index-unsorted-alist '()) (i-s-f (default-value 'imenu-sort-function)) packages ends-ranges p (prev-pos 0) char fchar index index1 name (end-range 0) package) (goto-char (point-min)) (imenu-progress-message prev-pos 0) ;; Search for the function ! (save-match-data (while (re-search-forward (or regexp imenu-example--function-name-regexp-perl) nil t) --- 2291,2327 ---- (defvar imenu-example--function-name-regexp-perl "^\\([ \t]*\\(sub\\|package\\)[ \t\n]+\\([a-zA-Z_0-9:']+\\)[ \t]*\\|=head\\([12]\\)[ \t]+\\([^\n]+\\)$\\)") + (defun cperl-imenu-addback (lst &optional isback name) + ;; We suppose that the lst is a DAG, unless the first element only + ;; loops back, and ISBACK is set. Thus this function cannot be + ;; applied twice without ISBACK set. + (cond ((not cperl-imenu-addback) lst) + (t + (or name + (setq name "+++BACK+++")) + (mapcar (function (lambda (elt) + (if (and (listp elt) (listp (cdr elt))) + (progn + ;; In the other order it goes up + ;; one level only ;-( + (setcdr elt (cons (cons name lst) + (cdr elt))) + (cperl-imenu-addback (cdr elt) t name) + )))) + (if isback (cdr lst) lst)) + lst))) + (defun imenu-example--create-perl-index (&optional regexp) (require 'cl) (let ((index-alist '()) (index-pack-alist '()) (index-pod-alist '()) (index-unsorted-alist '()) (i-s-f (default-value 'imenu-sort-function)) + (index-meth-alist '()) meth packages ends-ranges p (prev-pos 0) char fchar index index1 name (end-range 0) package) (goto-char (point-min)) (imenu-progress-message prev-pos 0) ;; Search for the function ! (progn ;;save-match-data (while (re-search-forward (or regexp imenu-example--function-name-regexp-perl) nil t) *************** *** 2125,2131 **** (goto-char (match-beginning 2)) (setq fchar (following-char)) ) ! (setq char (following-char)) (setq p (point)) (while (and ends-ranges (>= p (car ends-ranges))) ;; delete obsolete entries --- 2333,2339 ---- (goto-char (match-beginning 2)) (setq fchar (following-char)) ) ! (setq char (following-char) meth nil) (setq p (point)) (while (and ends-ranges (>= p (car ends-ranges))) ;; delete obsolete entries *************** *** 2133,2159 **** (setq package (or (car packages) "") end-range (or (car ends-ranges) 0)) (if (eq fchar ?p) ! (progn ! (setq name (buffer-substring (match-beginning 3) (match-end 3)) ! package (concat name "::") ! name (concat "package " name) ! end-range ! (save-excursion ! (parse-partial-sexp (point) (point-max) -1) (point)) ! ends-ranges (cons end-range ends-ranges) ! packages (cons package packages)))) ;; ) ;; Skip this function name if it is a prototype declaration. (if (and (eq fchar ?s) (eq char ?\;)) nil (if (eq fchar ?p) nil (setq name (buffer-substring (match-beginning 3) (match-end 3))) ! (if (or (> p end-range) (string-match "[:']" name)) nil ! (setq name (concat package name)))) ! (setq index (imenu-example--name-and-position)) (setcar index name) (if (eq fchar ?p) (push index index-pack-alist) (push index index-alist)) (push index index-unsorted-alist))) (t ; Pod section ;; (beginning-of-line) --- 2341,2370 ---- (setq package (or (car packages) "") end-range (or (car ends-ranges) 0)) (if (eq fchar ?p) ! (setq name (buffer-substring (match-beginning 3) (match-end 3)) ! package (concat name "::") ! name (concat "package " name) ! end-range ! (save-excursion ! (parse-partial-sexp (point) (point-max) -1) (point)) ! ends-ranges (cons end-range ends-ranges) ! packages (cons package packages))) ;; ) ;; Skip this function name if it is a prototype declaration. (if (and (eq fchar ?s) (eq char ?\;)) nil + (setq index (imenu-example--name-and-position)) (if (eq fchar ?p) nil (setq name (buffer-substring (match-beginning 3) (match-end 3))) ! (cond ((string-match "[:']" name) ! (setq meth t)) ! ((> p end-range) nil) ! (t ! (setq name (concat package name) meth t)))) (setcar index name) (if (eq fchar ?p) (push index index-pack-alist) (push index index-alist)) + (if meth (push index index-meth-alist)) (push index index-unsorted-alist))) (t ; Pod section ;; (beginning-of-line) *************** *** 2171,2190 **** (sort index-alist (default-value 'imenu-sort-function)) (nreverse index-alist))) (and index-pod-alist ! (push (cons (imenu-create-submenu-name "+POD headers+") (nreverse index-pod-alist)) index-alist)) (and index-pack-alist ! (push (cons (imenu-create-submenu-name "+Packages+") (nreverse index-pack-alist)) index-alist)) (and (or index-pack-alist index-pod-alist (default-value 'imenu-sort-function)) index-unsorted-alist ! (push (cons (imenu-create-submenu-name "+Unsorted List+") (nreverse index-unsorted-alist)) index-alist)) ! index-alist)) (defvar cperl-compilation-error-regexp-alist ;; This look like a paranoiac regexp: could anybody find a better one? (which WORK). --- 2382,2434 ---- (sort index-alist (default-value 'imenu-sort-function)) (nreverse index-alist))) (and index-pod-alist ! (push (cons "+POD headers+..." (nreverse index-pod-alist)) index-alist)) + (and (or index-pack-alist index-meth-alist) + (let ((lst index-pack-alist) hier-list pack elt group name) + ;; Remove "package ", reverse and uniquify. + (while lst + (setq elt (car lst) lst (cdr lst) name (substring (car elt) 8)) + (if (assoc name hier-list) nil + (setq hier-list (cons (cons name (cdr elt)) hier-list)))) + (setq lst index-meth-alist) + (while lst + (setq elt (car lst) lst (cdr lst)) + (string-match "\\(::\\|'\\)[_a-zA-Z0-9]+$" (car elt)) + (setq pack (substring (car elt) 0 (match-beginning 0))) + (if (setq group (assoc pack hier-list)) + (if (listp (cdr group)) + ;; Have some functions already + (setcdr group (cons (cons (substring + (car elt) + (+ 2 (match-beginning 0))) + (cdr elt)) + (cdr group))) + (setcdr group (list (cons (substring + (car elt) + (+ 2 (match-beginning 0))) + (cdr elt))))) + (setq hier-list + (cons (cons pack (list (cons (substring + (car elt) + (+ 2 (match-beginning 0))) + (cdr elt)))) + hier-list)))) + (push (cons "+Hierarchy+..." + hier-list) + index-alist))) (and index-pack-alist ! (push (cons "+Packages+..." (nreverse index-pack-alist)) index-alist)) (and (or index-pack-alist index-pod-alist (default-value 'imenu-sort-function)) index-unsorted-alist ! (push (cons "+Unsorted List+..." (nreverse index-unsorted-alist)) index-alist)) ! (cperl-imenu-addback index-alist))) (defvar cperl-compilation-error-regexp-alist ;; This look like a paranoiac regexp: could anybody find a better one? (which WORK). *************** *** 2881,2883 **** --- 3125,3514 ---- (setq res (apply 'call-process cmd nil nil nil args)) (or (eq res 0) (message "etags returned \"%s\"" res)))) + + (defun cperl-toggle-auto-newline () + "Toggle the state of `cperl-auto-newline'." + (interactive) + (setq cperl-auto-newline (not cperl-auto-newline)) + (message "Newlines will %sbe auto-inserted now." + (if cperl-auto-newline "" "not "))) + + (defun cperl-toggle-abbrev () + "Toggle the state of automatic keyword expansion in CPerl mode." + (interactive) + (abbrev-mode (if abbrev-mode 0 1)) + (message "Perl control structure will %sbe auto-inserted now." + (if abbrev-mode "" "not "))) + + + (defun cperl-toggle-electric () + "Toggle the state of parentheses doubling in CPerl mode." + (interactive) + (setq cperl-electric-parens (if (cperl-val 'cperl-electric-parens) 'null t)) + (message "Parentheses will %sbe auto-doubled now." + (if (cperl-val 'cperl-electric-parens) "" "not "))) + + ;;;; Tags file creation. + + (defvar cperl-tmp-buffer " *cperl-tmp*") + + (defun cperl-setup-tmp-buf () + (set-buffer (get-buffer-create cperl-tmp-buffer)) + (set-syntax-table cperl-mode-syntax-table) + (buffer-disable-undo) + (auto-fill-mode 0)) + + (defun cperl-xsub-scan () + (require 'cl) + (let ((index-alist '()) + (prev-pos 0) index index1 name package prefix) + (goto-char (point-min)) + (imenu-progress-message prev-pos 0) + ;; Search for the function + (progn ;;save-match-data + (while (re-search-forward + "^\\([ \t]*MODULE\\>[^\n]*\\\\|\\([a-zA-Z_][a-zA-Z_0-9]*\\)(\\|[ \t]*BOOT:\\)" + nil t) + (imenu-progress-message prev-pos) + (cond + ((match-beginning 2) ; SECTION + (setq package (buffer-substring (match-beginning 2) (match-end 2))) + (goto-char (match-beginning 0)) + (skip-chars-forward " \t") + (forward-char 1) + (if (looking-at "[^\n]*\\") + (setq prefix (buffer-substring (match-beginning 1) (match-end 1))) + (setq prefix nil))) + ((not package) nil) ; C language section + ((match-beginning 3) ; XSUB + (goto-char (1+ (match-beginning 3))) + (setq index (imenu-example--name-and-position)) + (setq name (buffer-substring (match-beginning 3) (match-end 3))) + (if (and prefix (string-match (concat "^" prefix) name)) + (setq name (substring name (length prefix)))) + (setq meth nil) + (cond ((string-match "::" name) nil) + (t + (setq index1 (cons (concat package "::" name) (cdr index))) + (push index1 index-alist))) + (setcar index name) + (push index index-alist)) + (t ; BOOT: section + ;; (beginning-of-line) + (setq index (imenu-example--name-and-position)) + (setcar index (concat package "::BOOT:")) + (push index index-alist))))) + (imenu-progress-message prev-pos 100) + ;;(setq index-alist + ;; (if (default-value 'imenu-sort-function) + ;; (sort index-alist (default-value 'imenu-sort-function)) + ;; (nreverse index-alist))) + index-alist)) + + (defun cperl-find-tags (file xs) + (let (ind (b (get-buffer cperl-tmp-buffer)) lst elt pos ret) + (save-excursion + (if b (set-buffer b) + (cperl-setup-tmp-buf)) + (erase-buffer) + (setq file (car (insert-file-contents file))) + (message "Scanning file %s..." file) + (if xs + (setq lst (cperl-xsub-scan)) + (setq ind (imenu-example--create-perl-index)) + (setq lst (cdr (assoc "+Unsorted List+..." ind)))) + (setq lst + (mapcar + (function + (lambda (elt) + (cond ((string-match "^[_a-zA-Z]" (car elt)) + (goto-char (cdr elt)) + (list (car elt) + (point) (count-lines 1 (point)) + (buffer-substring (progn + (skip-chars-forward + ":_a-zA-Z0-9") + (or (eolp) (forward-char 1)) + (point)) + (progn + (beginning-of-line) + (point)))))))) + lst)) + (erase-buffer) + (while lst + (setq elt (car lst) lst (cdr lst)) + (if elt + (progn + (insert (elt elt 3) + 127 + (if (string-match "^package " (car elt)) + (substring (car elt) 8) + (car elt) ) + 1 + (number-to-string (elt elt 1)) + "," + (number-to-string (elt elt 2)) + "\n") + (if (and (string-match "^[_a-zA-Z]+::" (car elt)) + (string-match "^sub[ \t]+\\([_a-zA-Z]+\\)[^:_a-zA-Z]" + (elt elt 3))) + ;; Need to insert the name without package as well + (setq lst (cons (cons (substring (elt elt 3) + (match-beginning 1) + (match-end 1)) + (cdr elt)) + lst)))))) + (setq pos (point)) + (goto-char 1) + (insert "\f\n" file "," (number-to-string (1- pos)) "\n") + (setq ret (buffer-substring 1 (point-max))) + (erase-buffer) + (message "Scanning file %s finished" file) + ret))) + + (defun cperl-write-tags (&optional file erase recurse dir inbuffer) + ;; If INBUFFER, do not select buffer, and do not save + ;; If ERASE is `ignore', do not erase, and do not try to delete old info. + (if file nil + (setq file (if dir default-directory (buffer-file-name))) + (if (and (not dir) (buffer-modified-p)) (error "Save buffer first!"))) + (let ((tags-file-name "TAGS") + (case-fold-search (eq system-type 'emx)) + xs) + (save-excursion + (cond (inbuffer nil) ; Already there + ((file-exists-p tags-file-name) + (visit-tags-table-buffer tags-file-name)) + (t (set-buffer (find-file-noselect tags-file-name)))) + (cond + (dir + (cond ((eq erase 'ignore)) + (erase + (erase-buffer) + (setq erase 'ignore))) + (let ((files + (directory-files file t (if recurse nil "\\.[Pp][Llm]$") t))) + (mapcar (function (lambda (file) + (cond + ((string-match "/\\.\\.?$" file) nil) + ((not (file-directory-p file)) + (if (string-match "\\.\\([Pp][Llm]\\|xs\\)$" file) + (cperl-write-tags file erase recurse nil t))) + ((not recurse) nil) + (t (cperl-write-tags file erase recurse t t))))) + files)) + ) + (t + (setq xs (string-match "\\.xs$" file)) + (cond ((eq erase 'ignore) nil) + (erase (erase-buffer)) + (t + (goto-char 1) + (if (search-forward (concat "\f\n" file ",") nil t) + (progn + (search-backward "\f\n") + (delete-region (point) + (progn + (forward-char 1) + (search-forward "\f\n" nil 'toend) + (point))) + (goto-char 1))))) + (insert (cperl-find-tags file xs)))) + (if inbuffer nil ; Delegate to the caller + (save-buffer 0) ; No backup + (initialize-new-tags-table))))) + + (defvar cperl-tags-hier-regexp-list + "^\\(\\(package\\)\\>\\|sub\\>[^\n]+::\\|[a-zA-Z_][a-zA-Z_0-9:]*(\C-?[^\n]+::\\|[ \t]*BOOT:\C-?[^\n]+::\\)") + + (defvar cperl-hierarchy '(() ()) + "Global hierarchy of classes") + + (defun cperl-tags-hier-fill () + ;; Suppose we are in a tag table cooked by cperl. + (goto-char 1) + (let (type pack name pos line chunk ord cons1 file str info fileind) + (while (re-search-forward cperl-tags-hier-regexp-list nil t) + (setq pos (match-beginning 0) + pack (match-beginning 2)) + (beginning-of-line) + (if (looking-at "\\([^\n]+\\)\C-?\\([^\n]+\\)\C-a\\([0-9]+\\),\\([0-9]+\\)") + (progn + (setq ;;str (buffer-substring (match-beginning 1) (match-end 1)) + name (buffer-substring (match-beginning 2) (match-end 2)) + ;;pos (buffer-substring (match-beginning 3) (match-end 3)) + line (buffer-substring (match-beginning 4) (match-end 4)) + ord (if pack 1 0) + info (etags-snarf-tag) ; Moves to beginning of the next line + file (file-of-tag) + fileind (format "%s:%s" file line)) + ;; Move back + (forward-char -1) + ;; Make new member of hierarchy name ==> file ==> pos if needed + (if (setq cons1 (assoc name (nth ord cperl-hierarchy))) + ;; Name known + (setcdr cons1 (cons (cons fileind (vector file info)) + (cdr cons1))) + ;; First occurence of the name, start alist + (setq cons1 (cons name (list (cons fileind (vector file info))))) + (if pack + (setcar (cdr cperl-hierarchy) + (cons cons1 (nth 1 cperl-hierarchy))) + (setcar cperl-hierarchy + (cons cons1 (car cperl-hierarchy))))))) + (end-of-line)))) + + (defun cperl-tags-hier-init (&optional update) + "Show hierarchical menu of classes and methods. + Finds info about classes by a scan of loaded TAGS files. + Supposes that the TAGS files contain fully qualified function names. + One may build such TAGS files from CPerl mode menu." + (interactive) + (require 'etags) + (require 'imenu) + (if (or update (null (nth 2 cperl-hierarchy))) + (let (pack name cons1 to l1 l2 l3 l4 + (remover (function (lambda (elt) ; (name (file1...) (file2..)) + (or (nthcdr 2 elt) + ;; Only in one file + (setcdr elt (cdr (nth 1 elt)))))))) + ;; (setq cperl-hierarchy '(() () ())) ; Would write into '() later! + (setq cperl-hierarchy (list l1 l2 l3)) + (or tags-table-list + (call-interactively 'visit-tags-table)) + (message "Updating list of classes...") + (mapcar + (function + (lambda (tagsfile) + (set-buffer (get-file-buffer tagsfile)) + (cperl-tags-hier-fill))) + tags-table-list) + (mapcar remover (car cperl-hierarchy)) + (mapcar remover (nth 1 cperl-hierarchy)) + (setq to (list nil (cons "Packages: " (nth 1 cperl-hierarchy)) + (cons "Methods: " (car cperl-hierarchy)))) + (cperl-tags-treeify to 1) + (setcar (nthcdr 2 cperl-hierarchy) + (cperl-menu-to-keymap (cons '("+++UPDATE+++" . -999) (cdr to)))) + (message "Updating list of classes: done, requesting display...") + ;;(cperl-imenu-addback (nth 2 cperl-hierarchy)) + )) + (or (nth 2 cperl-hierarchy) + (error "No items found")) + (setq update + ;;; (imenu-choose-buffer-index "Packages: " (nth 2 cperl-hierarchy)) + (if window-system + (x-popup-menu t (nth 2 cperl-hierarchy)) + (require 'tmm) + (tmm-prompt t (nth 2 cperl-hierarchy)))) + (if (and update (listp update)) + (progn (while (cdr update) (setq update (cdr update))) + (setq update (car update)))) ; Get the last from the list + (if (vectorp update) + (progn + (find-file (elt update 0)) + (etags-goto-tag-location (elt update 1)))) + (if (eq update -999) (cperl-tags-hier-init t))) + + (defun cperl-tags-treeify (to level) + ;; cadr of to is read-write. On start it is a cons + (let* ((regexp (concat "^\\(" (mapconcat + 'identity + (make-list level "[_a-zA-Z0-9]+") + "::") + "\\)\\(::\\)?")) + (packages (cdr (nth 1 to))) + (methods (cdr (nth 2 to))) + l1 head tail cons1 cons2 ord writeto packs recurse + root-packages root-functions ms many_ms same_name ps + (move-deeper + (function + (lambda (elt) + (cond ((and (string-match regexp (car elt)) + (or (eq ord 1) (match-end 2))) + (setq head (substring (car elt) 0 (match-end 1)) + tail (if (match-end 2) (substring (car elt) + (match-end 2))) + recurse t) + (if (setq cons1 (assoc head writeto)) nil + ;; Need to init new head + (setcdr writeto (cons (list head (list "Packages: ") + (list "Methods: ")) + (cdr writeto))) + (setq cons1 (nth 1 writeto))) + (setq cons2 (nth ord cons1)) ; Either packs or meths + (setcdr cons2 (cons elt (cdr cons2)))) + ((eq ord 2) + (setq root-functions (cons elt root-functions))) + (t + (setq root-packages (cons elt root-packages)))))))) + (setcdr to l1) ; Init to dynamic space + (setq writeto to) + (setq ord 1) + (mapcar move-deeper packages) + (setq ord 2) + (mapcar move-deeper methods) + (if recurse + (mapcar (function (lambda (elt) + (cperl-tags-treeify elt (1+ level)))) + (cdr to))) + ;; Now add back functions removed from display + (mapcar (function (lambda (elt) + (setcdr to (cons elt (cdr to))))) + root-functions) + ;; Now add back packages removed from display + (mapcar (function (lambda (elt) + (setcdr to (cons (cons (concat "package " (car elt)) + (cdr elt)) + (cdr to))))) + root-packages) + ;;Now clean up leaders with one child only + (mapcar (function (lambda (elt) + (if (not (and (listp (cdr elt)) + (eq (length elt) 2))) nil + (setcar elt (car (nth 1 elt))) + (setcdr elt (cdr (nth 1 elt)))))) + (cdr to)) + )) + + ;;;(x-popup-menu t + ;;; '(keymap "Name1" + ;;; ("Ret1" "aa") + ;;; ("Head1" "ab" + ;;; keymap "Name2" + ;;; ("Tail1" "x") ("Tail2" "y")))) + + (defun cperl-list-fold (list name limit) + (let (list1 list2 elt1 (num 0)) + (if (<= (length list) limit) list + (setq list1 nil list2 nil) + (while list + (setq num (1+ num) + elt1 (car list) + list (cdr list)) + (if (<= num imenu-max-items) + (setq list2 (cons elt1 list2)) + (setq list1 (cons (cons name + (nreverse list2)) + list1) + list2 (list elt1) + num 1))) + (nreverse (cons (cons name + (nreverse list2)) + list1))))) + + (defun cperl-menu-to-keymap (menu &optional name) + (let (list) + (cons 'keymap + (mapcar + (function + (lambda (elt) + (cond ((listp (cdr elt)) + (setq list (cperl-list-fold + (cdr elt) (car elt) imenu-max-items)) + (cons nil + (cons (car elt) + (cperl-menu-to-keymap list)))) + (t + (list (cdr elt) (car elt)))))) + (cperl-list-fold menu "Root" imenu-max-items))))) #~ Add banner warning to discourage direct changes to embed.h #~ Incorporate new symbols and name changes to reduce C namespace collisions diff -Pcr perl5_003/embed.h perl5_003_01/embed.h *** perl5_003/embed.h Mon Mar 25 01:04:04 1996 --- perl5_003_01/embed.h Wed Jul 17 11:12:12 1996 *************** *** 1,4 **** ! /* This file is derived from global.sym and interp.sym */ /* (Doing namespace management portably in C is really gross.) */ --- 1,7 ---- ! /* !!!!!!! DO NOT EDIT THIS FILE !!!!!!! ! This file is derived from global.sym and interp.sym ! Any changes made here will be lost ! */ /* (Doing namespace management portably in C is really gross.) */ *************** *** 41,46 **** --- 44,50 ---- #define comppad Perl_comppad #define comppad_name Perl_comppad_name #define comppad_name_fill Perl_comppad_name_fill + #define comppad_name_floor Perl_comppad_name_floor #define concat_amg Perl_concat_amg #define concat_ass_amg Perl_concat_ass_amg #define cop_seqmax Perl_cop_seqmax *************** *** 49,54 **** --- 53,59 ---- #define cshlen Perl_cshlen #define cshname Perl_cshname #define curcop Perl_curcop + #define curcopdb Perl_curcopdb #define curinterp Perl_curinterp #define curpad Perl_curpad #define dc Perl_dc *************** *** 161,166 **** --- 166,173 ---- #define ppaddr Perl_ppaddr #define profiledata Perl_profiledata #define provide_ref Perl_provide_ref + #define psig_ptr Perl_psig_ptr + #define psig_name Perl_psig_name #define qrt_amg Perl_qrt_amg #define rcsid Perl_rcsid #define reall_srchlen Perl_reall_srchlen *************** *** 172,178 **** #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 --- 179,185 ---- #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 *************** *** 219,225 **** #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 --- 226,231 ---- *************** *** 310,316 **** #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 --- 316,321 ---- *************** *** 426,431 **** --- 431,437 ---- #define gv_fullname Perl_gv_fullname #define gv_init Perl_gv_init #define gv_stashpv Perl_gv_stashpv + #define gv_stashpvn Perl_gv_stashpvn #define gv_stashsv Perl_gv_stashsv #define he_delayfree Perl_he_delayfree #define he_free Perl_he_free *************** *** 433,448 **** --- 439,459 ---- #define hoistmust Perl_hoistmust #define hv_clear Perl_hv_clear #define hv_delete Perl_hv_delete + #define hv_delete_ent Perl_hv_delete_ent #define hv_exists Perl_hv_exists + #define hv_exists_ent Perl_hv_exists_ent #define hv_fetch Perl_hv_fetch + #define hv_fetch_ent Perl_hv_fetch_ent #define hv_iterinit Perl_hv_iterinit #define hv_iterkey Perl_hv_iterkey + #define hv_iterkeysv Perl_hv_iterkeysv #define hv_iternext Perl_hv_iternext #define hv_iternextsv Perl_hv_iternextsv #define hv_iterval Perl_hv_iterval #define hv_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 ingroup Perl_ingroup *************** *** 461,472 **** --- 472,485 ---- #define looks_like_number Perl_looks_like_number #define magic_clearenv Perl_magic_clearenv #define magic_clearpack Perl_magic_clearpack + #define magic_clearsig Perl_magic_clearsig #define magic_existspack Perl_magic_existspack #define magic_get Perl_magic_get #define magic_getarylen Perl_magic_getarylen #define magic_getglob Perl_magic_getglob #define magic_getpack Perl_magic_getpack #define magic_getpos Perl_magic_getpos + #define magic_getsig Perl_magic_getsig #define magic_gettaint Perl_magic_gettaint #define magic_getuvar Perl_magic_getuvar #define magic_len Perl_magic_len *************** *** 506,511 **** --- 519,525 ---- #define my Perl_my #define my_bcopy Perl_my_bcopy #define my_bzero Perl_my_bzero + #define my_chsize Perl_my_chsize #define my_exit Perl_my_exit #define my_htonl Perl_my_htonl #define my_lstat Perl_my_lstat *************** *** 992,997 **** --- 1006,1012 ---- #define screaminstr Perl_screaminstr #define setdefout Perl_setdefout #define setenv_getix Perl_setenv_getix + #define sharepvn Perl_sharepvn #define sighandler Perl_sighandler #define skipspace Perl_skipspace #define stack_grow Perl_stack_grow *************** *** 1059,1064 **** --- 1074,1080 ---- #define too_few_arguments Perl_too_few_arguments #define too_many_arguments Perl_too_many_arguments #define unlnk Perl_unlnk + #define unsharepvn Perl_unsharepvn #define utilize Perl_utilize #define wait4pid Perl_wait4pid #define warn Perl_warn *************** *** 1080,1085 **** --- 1096,1109 ---- #ifdef MULTIPLICITY + /* Undefine symbols that were defined by EMBED. Somewhat ugly */ + + #undef curcop + #undef envgv + #undef siggv + #undef stack + #undef tainting + #define Argv (curinterp->IArgv) #define Cmd (curinterp->ICmd) #define DBgv (curinterp->IDBgv) *************** *** 1100,1107 **** --- 1124,1133 ---- #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) *************** *** 1153,1158 **** --- 1179,1185 ---- #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) *************** *** 1183,1190 **** #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) --- 1210,1215 ---- *************** *** 1210,1222 **** #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) --- 1235,1247 ---- #define sortstack (curinterp->Isortstack) #define sortstash (curinterp->Isortstash) #define splitstr (curinterp->Isplitstr) #define statcache (curinterp->Istatcache) #define statgv (curinterp->Istatgv) #define statname (curinterp->Istatname) #define statusvalue (curinterp->Istatusvalue) #define stdingv (curinterp->Istdingv) #define strchop (curinterp->Istrchop) + #define strtab (curinterp->Istrtab) #define sv_count (curinterp->Isv_count) #define sv_objcount (curinterp->Isv_objcount) #define sv_root (curinterp->Isv_root) *************** *** 1254,1261 **** --- 1279,1288 ---- #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 *************** *** 1307,1312 **** --- 1334,1340 ---- #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 *************** *** 1337,1344 **** #define Iorigfilename origfilename #define Iors ors #define Iorslen orslen - #define Ipad pad - #define Ipadname padname #define Iparsehook parsehook #define Ipatchlevel patchlevel #define Iperldb perldb --- 1365,1370 ---- *************** *** 1364,1376 **** #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 --- 1390,1402 ---- #define Isortstack sortstack #define Isortstash sortstash #define Isplitstr splitstr #define Istatcache statcache #define Istatgv statgv #define Istatname statname #define Istatusvalue statusvalue #define Istdingv stdingv #define Istrchop strchop + #define Istrtab strtab #define Isv_count sv_count #define Isv_objcount sv_objcount #define Isv_root sv_root #~ Add banner warning to embed.h to discourage direct changes #~ Insure that symbols aren't defined once with EMBVED prefix and #~ again in MULTIPLICITY block diff -Pcr perl5_003/embed.pl perl5_003_01/embed.pl *** perl5_003/embed.pl Mon Mar 25 01:04:04 1996 --- perl5_003_01/embed.pl Thu Jul 4 14:36:06 1996 *************** *** 3,9 **** open(EM, ">embed.h") || die "Can't create embed.h: $!\n"; print EM <<'END'; ! /* This file is derived from global.sym and interp.sym */ /* (Doing namespace management portably in C is really gross.) */ --- 3,12 ---- open(EM, ">embed.h") || die "Can't create embed.h: $!\n"; print EM <<'END'; ! /* !!!!!!! DO NOT EDIT THIS FILE !!!!!!! ! This file is derived from global.sym and interp.sym ! Any changes made here will be lost ! */ /* (Doing namespace management portably in C is really gross.) */ *************** *** 41,46 **** --- 44,57 ---- /* Put interpreter specific symbols into a struct? */ #ifdef MULTIPLICITY + + /* Undefine symbols that were defined by EMBED. Somewhat ugly */ + + #undef curcop + #undef envgv + #undef siggv + #undef stack + #undef tainting END #~ Update to version 1.02 diff -Pcr perl5_003/ext/DB_File/DB_File.pm perl5_003_01/ext/DB_File/DB_File.pm *** perl5_003/ext/DB_File/DB_File.pm Mon Feb 12 14:50:03 1996 --- perl5_003_01/ext/DB_File/DB_File.pm Fri Jul 5 18:47:36 1996 *************** *** 1,181 **** # DB_File.pm -- Perl 5 interface to Berkeley DB # # written by Paul Marquess (pmarquess@bfsec.bt.co.uk) ! # last modified 14th November 1995 ! # version 1.01 package DB_File::HASHINFO ; use strict; - use vars qw(%elements); use Carp; ! sub TIEHASH { ! bless {} ; } ! %elements = ( 'bsize' => 0, ! 'ffactor' => 0, ! 'nelem' => 0, ! 'cachesize' => 0, ! 'hash' => 0, ! 'lorder' => 0 ! ) ; sub FETCH { ! return $_[0]{$_[1]} if defined $elements{$_[1]} ; ! croak "DB_File::HASHINFO::FETCH - Unknown element '$_[1]'" ; } sub STORE { ! if ( defined $elements{$_[1]} ) { ! $_[0]{$_[1]} = $_[2] ; return ; } ! croak "DB_File::HASHINFO::STORE - Unknown element '$_[1]'" ; } sub DELETE { ! if ( defined $elements{$_[1]} ) { ! delete ${$_[0]}{$_[1]} ; return ; } ! croak "DB_File::HASHINFO::DELETE - Unknown element '$_[1]'" ; } ! ! sub DESTROY {undef %{$_[0]} } ! sub FIRSTKEY { croak "DB_File::HASHINFO::FIRSTKEY is not implemented" } ! sub NEXTKEY { croak "DB_File::HASHINFO::NEXTKEY is not implemented" } ! sub EXISTS { croak "DB_File::HASHINFO::EXISTS is not implemented" } ! sub CLEAR { croak "DB_File::HASHINFO::CLEAR is not implemented" } ! ! package DB_File::BTREEINFO ; ! ! use strict; ! use vars qw(%elements); ! use Carp; ! ! sub TIEHASH { ! bless {} ; ! } ! %elements = ( 'flags' => 0, ! 'cachesize' => 0, ! 'maxkeypage' => 0, ! 'minkeypage' => 0, ! 'psize' => 0, ! 'compare' => 0, ! 'prefix' => 0, ! 'lorder' => 0 ! ) ; ! ! sub FETCH ! { ! return $_[0]{$_[1]} if defined $elements{$_[1]} ; ! ! croak "DB_File::BTREEINFO::FETCH - Unknown element '$_[1]'" ; } ! ! sub STORE { ! if ( defined $elements{$_[1]} ) ! { ! $_[0]{$_[1]} = $_[2] ; ! return ; ! } ! ! croak "DB_File::BTREEINFO::STORE - Unknown element '$_[1]'" ; ! } ! sub DELETE ! { ! if ( defined $elements{$_[1]} ) ! { ! delete ${$_[0]}{$_[1]} ; ! return ; ! } ! ! croak "DB_File::BTREEINFO::DELETE - Unknown element '$_[1]'" ; } ! ! sub DESTROY {undef %{$_[0]} } ! sub FIRSTKEY { croak "DB_File::BTREEINFO::FIRSTKEY is not implemented" } ! sub NEXTKEY { croak "DB_File::BTREEINFO::NEXTKEY is not implemented" } ! sub EXISTS { croak "DB_File::BTREEINFO::EXISTS is not implemented" } ! sub CLEAR { croak "DB_File::BTREEINFO::CLEAR is not implemented" } package DB_File::RECNOINFO ; ! use strict; ! use vars qw(%elements); ! use Carp; sub TIEHASH { ! bless {} ; } ! %elements = ( 'bval' => 0, ! 'cachesize' => 0, ! 'psize' => 0, ! 'flags' => 0, ! 'lorder' => 0, ! 'reclen' => 0, ! 'bfname' => 0 ! ) ; ! sub FETCH ! { ! return $_[0]{$_[1]} if defined $elements{$_[1]} ; ! croak "DB_File::RECNOINFO::FETCH - Unknown element '$_[1]'" ; ! } ! sub STORE { ! if ( defined $elements{$_[1]} ) ! { ! $_[0]{$_[1]} = $_[2] ; ! return ; ! } ! ! croak "DB_File::RECNOINFO::STORE - Unknown element '$_[1]'" ; ! } ! sub DELETE ! { ! if ( defined $elements{$_[1]} ) ! { ! delete ${$_[0]}{$_[1]} ; ! return ; ! } ! ! croak "DB_File::RECNOINFO::DELETE - Unknown element '$_[1]'" ; } - sub DESTROY {undef %{$_[0]} } - sub FIRSTKEY { croak "DB_File::RECNOINFO::FIRSTKEY is not implemented" } - sub NEXTKEY { croak "DB_File::RECNOINFO::NEXTKEY is not implemented" } - sub EXISTS { croak "DB_File::BTREEINFO::EXISTS is not implemented" } - sub CLEAR { croak "DB_File::BTREEINFO::CLEAR is not implemented" } - - - package DB_File ; use strict; --- 1,143 ---- # DB_File.pm -- Perl 5 interface to Berkeley DB # # written by Paul Marquess (pmarquess@bfsec.bt.co.uk) ! # last modified 28th June 1996 ! # version 1.02 package DB_File::HASHINFO ; use strict; use Carp; + require Tie::Hash; + @DB_File::HASHINFO::ISA = qw(Tie::Hash); ! sub new { ! my $pkg = shift ; ! my %x ; ! tie %x, $pkg ; ! bless \%x, $pkg ; } ! sub TIEHASH ! { ! my $pkg = shift ; ! ! bless { 'bsize' => undef, ! 'ffactor' => undef, ! 'nelem' => undef, ! 'cachesize' => undef, ! 'hash' => undef, ! 'lorder' => undef, ! }, $pkg ; ! } sub FETCH { ! my $self = shift ; ! my $key = shift ; ! ! return $self->{$key} if exists $self->{$key} ; ! my $pkg = ref $self ; ! croak "${pkg}::FETCH - Unknown element '$key'" ; } sub STORE { ! my $self = shift ; ! my $key = shift ; ! my $value = shift ; ! ! if ( exists $self->{$key} ) { ! $self->{$key} = $value ; return ; } ! my $pkg = ref $self ; ! croak "${pkg}::STORE - Unknown element '$key'" ; } sub DELETE { ! my $self = shift ; ! my $key = shift ; ! ! if ( exists $self->{$key} ) { ! delete $self->{$key} ; return ; } ! my $pkg = ref $self ; ! croak "DB_File::HASHINFO::DELETE - Unknown element '$key'" ; } ! sub EXISTS { ! my $self = shift ; ! my $key = shift ; ! exists $self->{$key} ; } ! sub NotHere { ! my $pkg = shift ; ! my $method = shift ; ! croak "${pkg} does not define the method ${method}" ; } ! sub DESTROY { undef %{$_[0]} } ! sub FIRSTKEY { my $self = shift ; $self->NotHere(ref $self, "FIRSTKEY") } ! sub NEXTKEY { my $self = shift ; $self->NotHere(ref $self, "NEXTKEY") } ! sub CLEAR { my $self = shift ; $self->NotHere(ref $self, "CLEAR") } package DB_File::RECNOINFO ; ! use strict ; ! ! @DB_File::RECNOINFO::ISA = qw(DB_File::HASHINFO) ; sub TIEHASH { ! my $pkg = shift ; ! ! bless { 'bval' => undef, ! 'cachesize' => undef, ! 'psize' => undef, ! 'flags' => undef, ! 'lorder' => undef, ! 'reclen' => undef, ! 'bfname' => "", ! }, $pkg ; } ! package DB_File::BTREEINFO ; ! use strict ; + @DB_File::BTREEINFO::ISA = qw(DB_File::HASHINFO) ; ! sub TIEHASH { ! my $pkg = shift ; ! bless { 'flags' => undef, ! 'cachesize' => undef, ! 'maxkeypage' => undef, ! 'minkeypage' => undef, ! 'psize' => undef, ! 'compare' => undef, ! 'prefix' => undef, ! 'lorder' => undef, ! }, $pkg ; } package DB_File ; use strict; *************** *** 183,194 **** use Carp; ! $VERSION = "1.01" ; #typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE; ! $DB_BTREE = TIEHASH DB_File::BTREEINFO ; ! $DB_HASH = TIEHASH DB_File::HASHINFO ; ! $DB_RECNO = TIEHASH DB_File::RECNOINFO ; require Tie::Hash; require Exporter; --- 145,160 ---- use Carp; ! $VERSION = "1.02" ; #typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE; ! #$DB_BTREE = TIEHASH DB_File::BTREEINFO ; ! #$DB_HASH = TIEHASH DB_File::HASHINFO ; ! #$DB_RECNO = TIEHASH DB_File::RECNOINFO ; ! ! $DB_BTREE = new DB_File::BTREEINFO ; ! $DB_HASH = new DB_File::HASHINFO ; ! $DB_RECNO = new DB_File::RECNOINFO ; require Tie::Hash; require Exporter; *************** *** 197,202 **** --- 163,169 ---- @ISA = qw(Tie::Hash Exporter DynaLoader); @EXPORT = qw( $DB_BTREE $DB_HASH $DB_RECNO + BTREEMAGIC BTREEVERSION DB_LOCK *************** *** 225,230 **** --- 192,198 ---- R_SETCURSOR R_SNAPSHOT __R_UNUSED + ); sub AUTOLOAD { *************** *** 251,256 **** --- 219,261 ---- # Preloaded methods go here. Autoload methods go after __END__, and are # processed by the autosplit program. + + sub get_dup + { + croak "Usage: \$db->get_dup(key [,flag])\n" + unless @_ == 2 or @_ == 3 ; + + my $db = shift ; + my $key = shift ; + my $flag = shift ; + my $value ; + my $origkey = $key ; + my $wantarray = wantarray ; + my @values = () ; + my $counter = 0 ; + + # get the first value associated with the key, $key + $db->seq($key, $value, R_CURSOR()) ; + + if ( $key eq $origkey) { + + while (1) { + # save the value or count matches + if ($wantarray) + { push (@values, $value) ; push(@values, 1) if $flag } + else + { ++ $counter } + + # iterate through the database until either EOF + # or a different key is encountered. + last if $db->seq($key, $value, R_NEXT()) != 0 or $key ne $origkey ; + } + } + + $wantarray ? @values : $counter ; + } + + 1; __END__ *************** *** 263,280 **** =head1 SYNOPSIS use DB_File ; ! [$X =] tie %hash, DB_File, $filename [, $flags, $mode, $DB_HASH] ; [$X =] tie %hash, DB_File, $filename, $flags, $mode, $DB_BTREE ; [$X =] tie @array, DB_File, $filename, $flags, $mode, $DB_RECNO ; $status = $X->del($key [, $flags]) ; $status = $X->put($key, $value [, $flags]) ; $status = $X->get($key, $value [, $flags]) ; ! $status = $X->seq($key, $value [, $flags]) ; $status = $X->sync([$flags]) ; $status = $X->fd ; untie %hash ; untie @array ; --- 268,294 ---- =head1 SYNOPSIS use DB_File ; + use Fcntl ; + + [$X =] tie %hash, 'DB_File', [$filename, $flags, $mode, $DB_HASH] ; + [$X =] tie %hash, 'DB_File', $filename, $flags, $mode, $DB_BTREE ; + [$X =] tie @array, 'DB_File', $filename, $flags, $mode, $DB_RECNO ; ! [$X =] tie %hash, DB_File, $filename [, $flags, $mode, $DB_HASH ] ; [$X =] tie %hash, DB_File, $filename, $flags, $mode, $DB_BTREE ; [$X =] tie @array, DB_File, $filename, $flags, $mode, $DB_RECNO ; $status = $X->del($key [, $flags]) ; $status = $X->put($key, $value [, $flags]) ; $status = $X->get($key, $value [, $flags]) ; ! $status = $X->seq($key, $value , $flags) ; $status = $X->sync([$flags]) ; $status = $X->fd ; + $count = $X->get_dup($key) ; + @list = $X->get_dup($key) ; + %list = $X->get_dup($key, 1) ; + untie %hash ; untie @array ; *************** *** 282,288 **** B is a module which allows Perl programs to make use of the facilities provided by Berkeley DB. If you intend to use this ! module you should really have a copy of the Berkeley DB manualpage at hand. The interface defined here mirrors the Berkeley DB interface closely. --- 296,302 ---- B is a module which allows Perl programs to make use of the facilities provided by Berkeley DB. If you intend to use this ! module you should really have a copy of the Berkeley DB manual page at hand. The interface defined here mirrors the Berkeley DB interface closely. *************** *** 294,302 **** =over 5 ! =item DB_HASH ! This database type allows arbitrary key/data pairs to be stored in data files. This is equivalent to the functionality provided by other hashing packages like DBM, NDBM, ODBM, GDBM, and SDBM. Remember though, the files created using DB_HASH are not compatible with any of the --- 308,316 ---- =over 5 ! =item B ! This database type allows arbitrary key/value pairs to be stored in data files. This is equivalent to the functionality provided by other hashing packages like DBM, NDBM, ODBM, GDBM, and SDBM. Remember though, the files created using DB_HASH are not compatible with any of the *************** *** 307,322 **** hashing algorithm it is possible to write your own in Perl and have B use it instead. ! =item DB_BTREE ! The btree format allows arbitrary key/data pairs to be stored in a sorted, balanced binary tree. As with the DB_HASH format, it is possible to provide a user defined Perl routine to perform the comparison of keys. By default, though, the keys are stored in lexical order. ! =item DB_RECNO DB_RECNO allows both fixed-length and variable-length flat text files to be manipulated using the same key/value pair interface as in DB_HASH --- 321,341 ---- hashing algorithm it is possible to write your own in Perl and have B use it instead. ! When opening an existing database, you may omit the final three arguments ! to C; they default to O_RDWR, 0644, and $DB_HASH. If you're ! creating a new file, you need to specify at least the C<$flags> ! argument, which must include O_CREAT. ! =item B ! ! The btree format allows arbitrary key/value pairs to be stored in a sorted, balanced binary tree. As with the DB_HASH format, it is possible to provide a user defined Perl routine to perform the comparison of keys. By default, though, the keys are stored in lexical order. ! =item B DB_RECNO allows both fixed-length and variable-length flat text files to be manipulated using the same key/value pair interface as in DB_HASH *************** *** 333,342 **** associative array (for DB_HASH & DB_BTREE file types) or an ordinary array (for the DB_RECNO file type). ! In addition to the tie() interface, it is also possible to use most of ! the functions provided in the Berkeley DB API. ! =head2 Differences with Berkeley DB Berkeley DB uses the function dbopen() to open or create a database. Below is the C prototype for dbopen(). --- 352,362 ---- associative array (for DB_HASH & DB_BTREE file types) or an ordinary array (for the DB_RECNO file type). ! In addition to the tie() interface, it is also possible to access most ! of the functions provided in the Berkeley DB API directly. ! See L<"Using the Berkeley DB API Directly">. ! =head2 Opening a Berkeley DB Database File Berkeley DB uses the function dbopen() to open or create a database. Below is the C prototype for dbopen(). *************** *** 352,386 **** specific interface method. This interface is handled slightly differently in B. Here is ! an equivalent call using B. ! tie %array, DB_File, $filename, $flags, $mode, $DB_HASH ; The C, C and C parameters are the direct equivalent of their dbopen() counterparts. The final parameter $DB_HASH performs the function of both the C and C parameters in dbopen(). ! In the example above $DB_HASH is actually a reference to a hash ! object. B has three of these pre-defined references. Apart ! from $DB_HASH, there is also $DB_BTREE and $DB_RECNO. The keys allowed in each of these pre-defined references is limited to the names used in the equivalent C structure. So, for example, the $DB_HASH reference will only allow keys called C, C, ! C, C, C and C. ! To change one of these elements, just assign to it like this ! $DB_HASH->{cachesize} = 10000 ; ! =head2 RECNO ! In order to make RECNO more compatible with Perl the array offset for all ! RECNO arrays begins at 0 rather than 1 as in Berkeley DB. =head2 In Memory Databases --- 372,655 ---- specific interface method. This interface is handled slightly differently in B. Here is ! an equivalent call using B: ! tie %array, 'DB_File', $filename, $flags, $mode, $DB_HASH ; The C, C and C parameters are the direct equivalent of their dbopen() counterparts. The final parameter $DB_HASH performs the function of both the C and C parameters in dbopen(). ! In the example above $DB_HASH is actually a pre-defined reference to a ! hash object. B has three of these pre-defined references. ! Apart from $DB_HASH, there is also $DB_BTREE and $DB_RECNO. The keys allowed in each of these pre-defined references is limited to the names used in the equivalent C structure. So, for example, the $DB_HASH reference will only allow keys called C, C, ! C, C, C and C. ! To change one of these elements, just assign to it like this: ! $DB_HASH->{'cachesize'} = 10000 ; + The three predefined variables $DB_HASH, $DB_BTREE and $DB_RECNO are + usually adequate for most applications. If you do need to create extra + instances of these objects, constructors are available for each file + type. + + Here are examples of the constructors and the valid options available + for DB_HASH, DB_BTREE and DB_RECNO respectively. + + $a = new DB_File::HASHINFO ; + $a->{'bsize'} ; + $a->{'cachesize'} ; + $a->{'ffactor'}; + $a->{'hash'} ; + $a->{'lorder'} ; + $a->{'nelem'} ; + + $b = new DB_File::BTREEINFO ; + $b->{'flags'} ; + $b->{'cachesize'} ; + $b->{'maxkeypage'} ; + $b->{'minkeypage'} ; + $b->{'psize'} ; + $b->{'compare'} ; + $b->{'prefix'} ; + $b->{'lorder'} ; + + $c = new DB_File::RECNOINFO ; + $c->{'bval'} ; + $c->{'cachesize'} ; + $c->{'psize'} ; + $c->{'flags'} ; + $c->{'lorder'} ; + $c->{'reclen'} ; + $c->{'bfname'} ; + + The values stored in the hashes above are mostly the direct equivalent + of their C counterpart. Like their C counterparts, all are set to a + default set of values - that means you don't have to set I of the + values when you only want to change one. Here is an example: + + $a = new DB_File::HASHINFO ; + $a->{'cachesize'} = 12345 ; + tie %y, 'DB_File', "filename", $flags, 0777, $a ; + + A few of the values need extra discussion here. When used, the C + equivalent of the keys C, C and C store pointers + to C functions. In B these keys are used to store references + to Perl subs. Below are templates for each of the subs: ! sub hash ! { ! my ($data) = @_ ; ! ... ! # return the hash value for $data ! return $hash ; ! } ! ! sub compare ! { ! my ($key, $key2) = @_ ; ! ... ! # return 0 if $key1 eq $key2 ! # -1 if $key1 lt $key2 ! # 1 if $key1 gt $key2 ! return (-1 , 0 or 1) ; ! } ! ! sub prefix ! { ! my ($key, $key2) = @_ ; ! ... ! # return number of bytes of $key2 which are ! # necessary to determine that it is greater than $key1 ! return $bytes ; ! } ! ! See L<"Using BTREE"> for an example of using the C + =head2 Default Parameters ! It is possible to omit some or all of the final 4 parameters in the ! call to C and let them take default values. As DB_HASH is the most ! common file format used, the call: ! ! tie %A, "DB_File", "filename" ; ! ! is equivalent to: ! ! tie %A, "DB_File", "filename", O_CREAT|O_RDWR, 0640, $DB_HASH ; ! ! It is also possible to omit the filename parameter as well, so the ! call: ! ! tie %A, "DB_File" ; ! ! is equivalent to: ! ! tie %A, "DB_File", undef, O_CREAT|O_RDWR, 0640, $DB_HASH ; ! ! See L<"In Memory Databases"> for a discussion on the use of C ! in place of a filename. ! ! =head2 Handling duplicate keys in BTREE databases ! ! The BTREE file type in Berkeley DB optionally allows a single key to be ! associated with an arbitrary number of values. This option is enabled by ! setting the flags element of C<$DB_BTREE> to R_DUP when creating the ! database. ! ! There are some difficulties in using the tied hash interface if you ! want to manipulate a BTREE database with duplicate keys. Consider this ! code: ! ! use DB_File ; ! use Fcntl ; ! ! $filename = "tree" ; ! unlink $filename ; ! ! # Enable duplicate records ! $DB_BTREE->{'flags'} = R_DUP ; ! ! tie %h, "DB_File", $filename, O_RDWR|O_CREAT, 0640, $DB_BTREE ! or die "Cannot open $filename: $!\n"; ! ! # Add some key/value pairs to the file ! $h{'Wall'} = 'Larry' ; ! $h{'Wall'} = 'Brick' ; # Note the duplicate key ! $h{'Smith'} = 'John' ; ! $h{'mouse'} = 'mickey' ; ! ! # iterate through the associative array ! # and print each key/value pair. ! foreach (keys %h) ! { print "$_ -> $h{$_}\n" } ! ! Here is the output: ! ! Smith -> John ! Wall -> Larry ! Wall -> Larry ! mouse -> mickey ! ! As you can see 2 records have been successfully created with key C ! - the only thing is, when they are retrieved from the database they ! both I to have the same value, namely C. The problem is ! caused by the way that the associative array interface works. ! Basically, when the associative array interface is used to fetch the ! value associated with a given key, it will only ever retrieve the first ! value. ! ! Although it may not be immediately obvious from the code above, the ! associative array interface can be used to write values with duplicate ! keys, but it cannot be used to read them back from the database. ! ! The way to get around this problem is to use the Berkeley DB API method ! called C. This method allows sequential access to key/value ! pairs. See L<"Using the Berkeley DB API Directly"> for details of both ! the C method and the API in general. ! ! Here is the script above rewritten using the C API method. ! ! use DB_File ; ! use Fcntl ; ! ! $filename = "tree" ; ! unlink $filename ; ! ! # Enable duplicate records ! $DB_BTREE->{'flags'} = R_DUP ; ! ! $x = tie %h, "DB_File", $filename, O_RDWR|O_CREAT, 0640, $DB_BTREE ! or die "Cannot open $filename: $!\n"; ! ! # Add some key/value pairs to the file ! $h{'Wall'} = 'Larry' ; ! $h{'Wall'} = 'Brick' ; # Note the duplicate key ! $h{'Smith'} = 'John' ; ! $h{'mouse'} = 'mickey' ; ! ! # Point to the first record in the btree ! $x->seq($key, $value, R_FIRST) ; ! ! # now iterate through the rest of the btree ! # and print each key/value pair. ! print "$key -> $value\n" ; ! while ( $x->seq($key, $value, R_NEXT) == 0) ! { print "$key -> $value\n" } ! ! undef $x ; ! untie %h ; ! ! that prints: ! ! Smith -> John ! Wall -> Brick ! Wall -> Larry ! mouse -> mickey ! ! This time we have got all the key/value pairs, including both the ! values associated with the key C. ! ! C comes with a utility method, called C, to assist in ! reading duplicate values from BTREE databases. The method can take the ! following forms: ! ! $count = $x->get_dup($key) ; ! @list = $x->get_dup($key) ; ! %list = $x->get_dup($key, 1) ; ! ! In a scalar context the method returns the number of values associated ! with the key, C<$key>. ! ! In list context, it returns all the values which match C<$key>. Note ! that the values returned will be in an apparently random order. ! ! If the second parameter is present and evaluates TRUE, the method ! returns an associative array whose keys correspond to the the values ! from the BTREE and whose values are all C<1>. ! ! So assuming the database created above, we can use C like ! this: ! ! $cnt = $x->get_dups("Wall") ; ! print "Wall occurred $cnt times\n" ; ! ! %hash = $x->get_dups("Wall", 1) ; ! print "Larry is there\n" if $hash{'Larry'} ; ! ! @list = $x->get_dups("Wall") ; ! print "Wall => [@list]\n" ; ! ! @list = $x->get_dups("Smith") ; ! print "Smith => [@list]\n" ; ! ! @list = $x->get_dups("Dog") ; ! print "Dog => [@list]\n" ; ! ! ! and it will print: ! ! Wall occurred 2 times ! Larry is there ! Wall => [Brick Larry] ! Smith => [John] ! Dog => [] + =head2 RECNO + + In order to make RECNO more compatible with Perl the array offset for + all RECNO arrays begins at 0 rather than 1 as in Berkeley DB. + + As with normal Perl arrays, a RECNO array can be accessed using + negative indexes. The index -1 refers to the last element of the array, + -2 the second last, and so on. Attempting to access an element before + the start of the array will raise a fatal run-time error. =head2 In Memory Databases *************** *** 389,453 **** uses C instead of NULL to provide this functionality. ! =head2 Using the Berkeley DB Interface Directly As well as accessing Berkeley DB using a tied hash or array, it is also ! possible to make direct use of most of the functions defined in the Berkeley DB documentation. ! To do this you need to remember the return value from the tie. ! ! $db = tie %hash, DB_File, "filename" Once you have done that, you can access the Berkeley DB API functions ! directly. $db->put($key, $value, R_NOOVERWRITE) ; ! All the functions defined in L are available except for ! close() and dbopen() itself. The B interface to these ! functions have been implemented to mirror the the way Berkeley DB ! works. In particular note that all the functions return only a status ! value. Whenever a Berkeley DB function returns data via one of its ! parameters, the B equivalent does exactly the same. ! All the constants defined in L are also available. ! Below is a list of the functions available. =over 5 ! =item get ! Same as in C except that the flags parameter is optional. ! Remember the value associated with the key you request is returned in ! the $value parameter. ! =item put ! As usual the flags parameter is optional. ! If you use either the R_IAFTER or R_IBEFORE flags, the key parameter will have the record number of the inserted key/value pair set. ! =item del ! The flags parameter is optional. ! =item fd ! As in I. ! =item seq ! The flags parameter is optional. ! Both the key and value parameters will be set. ! =item sync ! The flags parameter is optional. =back --- 658,812 ---- uses C instead of NULL to provide this functionality. ! =head2 Using the Berkeley DB API Directly As well as accessing Berkeley DB using a tied hash or array, it is also ! possible to make direct use of most of the API functions defined in the Berkeley DB documentation. + To do this you need to store a copy of the object returned from the tie. ! $db = tie %hash, "DB_File", "filename" ; Once you have done that, you can access the Berkeley DB API functions ! as B methods directly like this: $db->put($key, $value, R_NOOVERWRITE) ; ! B If you have saved a copy of the object returned from ! C, the underlying database file will I be closed until both ! the tied variable is untied and all copies of the saved object are ! destroyed. ! ! use DB_File ; ! $db = tie %hash, "DB_File", "filename" ! or die "Cannot tie filename: $!" ; ! ... ! undef $db ; ! untie %hash ; ! ! All the functions defined in L are available except for ! close() and dbopen() itself. The B method interface to the ! supported functions have been implemented to mirror the way Berkeley DB ! works whenever possible. In particular note that: ! ! =over 5 ! ! =item * ! ! The methods return a status value. All return 0 on success. ! All return -1 to signify an error and set C<$!> to the exact ! error code. The return code 1 generally (but not always) means that the ! key specified did not exist in the database. ! ! Other return codes are defined. See below and in the Berkeley DB ! documentation for details. The Berkeley DB documentation should be used ! as the definitive source. ! =item * ! Whenever a Berkeley DB function returns data via one of its parameters, ! the equivalent B method does exactly the same. ! ! =item * ! ! If you are careful, it is possible to mix API calls with the tied ! hash/array interface in the same piece of code. Although only a few of ! the methods used to implement the tied interface currently make use of ! the cursor, you should always assume that the cursor has been changed ! any time the tied hash/array interface is used. As an example, this ! code will probably not do what you expect: ! ! $X = tie %x, 'DB_File', $filename, O_RDWR|O_CREAT, 0777, $DB_BTREE ! or die "Cannot tie $filename: $!" ; ! ! # Get the first key/value pair and set the cursor ! $X->seq($key, $value, R_FIRST) ; ! ! # this line will modify the cursor ! $count = scalar keys %x ; ! ! # Get the second key/value pair. ! # oops, it didn't, it got the last key/value pair! ! $X->seq($key, $value, R_NEXT) ; ! ! The code above can be rearranged to get around the problem, like this: ! ! $X = tie %x, 'DB_File', $filename, O_RDWR|O_CREAT, 0777, $DB_BTREE ! or die "Cannot tie $filename: $!" ; ! ! # this line will modify the cursor ! $count = scalar keys %x ; ! ! # Get the first key/value pair and set the cursor ! $X->seq($key, $value, R_FIRST) ; ! ! # Get the second key/value pair. ! # worked this time. ! $X->seq($key, $value, R_NEXT) ; ! ! =back ! ! All the constants defined in L for use in the flags parameters ! in the methods defined below are also available. Refer to the Berkeley ! DB documentation for the precise meaning of the flags values. ! ! Below is a list of the methods available. =over 5 ! =item C<$status = $X-Eget($key, $value [, $flags]) ;> ! ! Given a key (C<$key>) this method reads the value associated with it ! from the database. The value read from the database is returned in the ! C<$value> parameter. ! ! If the key does not exist the method returns 1. ! No flags are currently defined for this method. ! =item C<$status = $X-Eput($key, $value [, $flags]) ;> ! Stores the key/value pair in the database. ! If you use either the R_IAFTER or R_IBEFORE flags, the C<$key> parameter will have the record number of the inserted key/value pair set. ! Valid flags are R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE and ! R_SETCURSOR. ! =item C<$status = $X-Edel($key [, $flags]) ;> ! Removes all key/value pairs with key C<$key> from the database. ! A return code of 1 means that the requested key was not in the ! database. ! R_CURSOR is the only valid flag at present. ! =item C<$status = $X-Efd ;> ! Returns the file descriptor for the underlying database. ! See L<"Locking Databases"> for an example of how to make use of the ! C method to lock your database. ! =item C<$status = $X-Eseq($key, $value, $flags) ;> ! ! This interface allows sequential retrieval from the database. See ! L for full details. ! ! Both the C<$key> and C<$value> parameters will be set to the key/value ! pair read from the database. ! ! The flags parameter is mandatory. The valid flag values are R_CURSOR, ! R_FIRST, R_LAST, R_NEXT and R_PREV. ! ! =item C<$status = $X-Esync([$flags]) ;> ! ! Flushes any cached buffers to disk. ! ! R_RECNOSYNC is the only valid flag at present. =back *************** *** 460,515 **** use DB_File ; use Fcntl ; ! ! tie %h, "DB_File", "hashed", O_RDWR|O_CREAT, 0640, $DB_HASH ; ! # Add a key/value pair to the file $h{"apple"} = "orange" ; ! # Check for existence of a key print "Exists\n" if $h{"banana"} ; ! # Delete delete $h{"apple"} ; ! untie %h ; =head2 Using BTREE ! Here is sample of code which used BTREE. Just to make life more ! interesting the default comparision function will not be used. Instead a Perl sub, C, will be used to do a case insensitive comparison. use DB_File ; use Fcntl ; ! sub Compare { my ($key1, $key2) = @_ ; ! "\L$key1" cmp "\L$key2" ; } ! ! $DB_BTREE->{compare} = 'Compare' ; ! ! tie %h, 'DB_File', "tree", O_RDWR|O_CREAT, 0640, $DB_BTREE ; ! # Add a key/value pair to the file $h{'Wall'} = 'Larry' ; $h{'Smith'} = 'John' ; $h{'mouse'} = 'mickey' ; $h{'duck'} = 'donald' ; ! # Delete delete $h{"duck"} ; ! # Cycle through the keys printing them in order. # Note it is not necessary to sort the keys as # the btree will have kept them in order automatically. foreach (keys %h) { print "$_\n" } ! untie %h ; Here is the output from the code above. --- 819,876 ---- use DB_File ; use Fcntl ; ! ! tie %h, "DB_File", "hashed", O_RDWR|O_CREAT, 0640, $DB_HASH ! or die "Cannot open file 'hashed': $!\n"; ! # Add a key/value pair to the file $h{"apple"} = "orange" ; ! # Check for existence of a key print "Exists\n" if $h{"banana"} ; ! # Delete delete $h{"apple"} ; ! untie %h ; =head2 Using BTREE ! Here is a sample of code which uses BTREE. Just to make life more ! interesting the default comparison function will not be used. Instead a Perl sub, C, will be used to do a case insensitive comparison. use DB_File ; use Fcntl ; ! sub Compare { my ($key1, $key2) = @_ ; ! "\L$key1" cmp "\L$key2" ; } ! ! $DB_BTREE->{'compare'} = 'Compare' ; ! ! tie %h, "DB_File", "tree", O_RDWR|O_CREAT, 0640, $DB_BTREE ! or die "Cannot open file 'tree': $!\n" ; ! # Add a key/value pair to the file $h{'Wall'} = 'Larry' ; $h{'Smith'} = 'John' ; $h{'mouse'} = 'mickey' ; $h{'duck'} = 'donald' ; ! # Delete delete $h{"duck"} ; ! # Cycle through the keys printing them in order. # Note it is not necessary to sort the keys as # the btree will have kept them in order automatically. foreach (keys %h) { print "$_\n" } ! untie %h ; Here is the output from the code above. *************** *** 521,541 **** =head2 Using RECNO use DB_File ; use Fcntl ; ! ! $DB_RECNO->{psize} = 3000 ; ! ! tie @h, DB_File, "text", O_RDWR|O_CREAT, 0640, $DB_RECNO ; ! # Add a key/value pair to the file $h[0] = "orange" ; ! # Check for existence of a key print "Exists\n" if $h[1] ; - - untie @h ; =head2 Locking Databases --- 882,904 ---- =head2 Using RECNO + Here is a simple example that uses RECNO. + use DB_File ; use Fcntl ; ! ! $DB_RECNO->{'psize'} = 3000 ; ! ! tie @h, "DB_File", "text", O_RDWR|O_CREAT, 0640, $DB_RECNO ! or die "Cannot open file 'text': $!\n" ; ! # Add a key/value pair to the file $h[0] = "orange" ; ! # Check for existence of a key print "Exists\n" if $h[1] ; + untie @h ; =head2 Locking Databases *************** *** 588,596 **** --- 951,961 ---- print "$$: Write lock granted\n"; $db{$key} = $value; + $db->sync; sleep 10; flock(DB_FH, LOCK_UN); + undef $db; untie %db; close(DB_FH); print "$$: Updated db to $key=$value\n"; *************** *** 631,641 **** The return value from TIEHASH wasn't set to NULL when dbopen returned an error. =head1 WARNINGS ! If you happen find any other functions defined in the source for this ! module that have not been mentioned in this document -- beware. I may ! drop them at a moments notice. If you cannot find any, then either you didn't look very hard or the moment has passed and I have dropped them. --- 996,1023 ---- The return value from TIEHASH wasn't set to NULL when dbopen returned an error. + =item 1.02 + + Merged OS2 specific code into DB_File.xs + + Removed some redundant code in DB_File.xs. + + Documentation update. + + Allow negative subscripts with RECNO interface. + + Changed the default flags from O_RDWR to O_CREAT|O_RDWR. + + The example code which showed how to lock a database needed a call to + C added. Without it the resultant database file was empty. + + Added get_dups method. + =head1 WARNINGS ! If you happen to find any other functions defined in the source for ! this module that have not been mentioned in this document -- beware. I ! may drop them at a moments notice. If you cannot find any, then either you didn't look very hard or the moment has passed and I have dropped them. *************** *** 656,661 **** --- 1038,1047 ---- host F in F. It is I under the GPL. + If you are running IRIX, then get Berkeley DB from + F. It has the patches necessary to + compile properly on IRIX 5.3. + =head1 SEE ALSO L, L, L, L, L *************** *** 666,673 **** =head1 AUTHOR The DB_File interface was written by Paul Marquess ! . Questions about the DB system itself may be addressed to Keith Bostic ! . =cut --- 1052,1059 ---- =head1 AUTHOR The DB_File interface was written by Paul Marquess ! Epmarquess@bfsec.bt.co.ukE. Questions about the DB system itself may be addressed to Keith Bostic ! Ebostic@cs.berkeley.eduE. =cut #~ Update to version 1.02 diff -Pcr perl5_003/ext/DB_File/DB_File.xs perl5_003_01/ext/DB_File/DB_File.xs *** perl5_003/ext/DB_File/DB_File.xs Sat Jan 20 00:55:34 1996 --- perl5_003_01/ext/DB_File/DB_File.xs Fri Jul 5 18:45:21 1996 *************** *** 3,10 **** DB_File.xs -- Perl 5 interface to Berkeley DB written by Paul Marquess (pmarquess@bfsec.bt.co.uk) ! last modified 14th November 1995 ! version 1.01 All comments/suggestions/problems are welcome --- 3,10 ---- DB_File.xs -- Perl 5 interface to Berkeley DB written by Paul Marquess (pmarquess@bfsec.bt.co.uk) ! last modified 26th June 1996 ! version 1.02 All comments/suggestions/problems are welcome *************** *** 17,22 **** --- 17,27 ---- 1.01 - Fixed a SunOS core dump problem. The return value from TIEHASH wasn't set to NULL when dbopen returned an error. + 1.02 - Use ALIAS to define TIEARRAY. + Removed some redundant commented code. + Merged OS2 code into the main distribution. + Allow negative subscripts with RECNO interface. + Changed the default flags to O_CREAT|O_RDWR */ #include "EXTERN.h" *************** *** 45,51 **** } ; ! /* #define TRACE */ #define db_DESTROY(db) ((db->dbp)->close)(db->dbp) #define db_DELETE(db, key, flags) ((db->dbp)->del)(db->dbp, &key, flags) --- 50,56 ---- } ; ! /* #define TRACE */ #define db_DESTROY(db) ((db->dbp)->close)(db->dbp) #define db_DELETE(db, key, flags) ((db->dbp)->del)(db->dbp, &key, flags) *************** *** 61,74 **** #define db_sync(db, flags) ((db->dbp)->sync)(db->dbp, flags) ! #define OutputValue(arg, name) \ ! { if (RETVAL == 0) sv_setpvn(arg, name.data, name.size) ; } #define OutputKey(arg, name) \ { if (RETVAL == 0) \ { \ ! if (db->type != DB_RECNO) \ sv_setpvn(arg, name.data, name.size); \ else \ sv_setiv(arg, (I32)*(I32*)name.data - 1); \ } \ --- 66,83 ---- #define db_sync(db, flags) ((db->dbp)->sync)(db->dbp, flags) ! #define OutputValue(arg, name) \ ! { if (RETVAL == 0) { \ ! sv_setpvn(arg, name.data, name.size) ; \ ! } \ ! } #define OutputKey(arg, name) \ { if (RETVAL == 0) \ { \ ! if (db->type != DB_RECNO) { \ sv_setpvn(arg, name.data, name.size); \ + } \ else \ sv_setiv(arg, (I32)*(I32*)name.data - 1); \ } \ *************** *** 235,241 **** printf (" lorder = %d\n", recno.lorder) ; printf (" reclen = %d\n", recno.reclen) ; printf (" bval = %d\n", recno.bval) ; ! printf (" bfname = %s\n", recno.bfname) ; } PrintBtree(btree) --- 244,250 ---- printf (" lorder = %d\n", recno.lorder) ; printf (" reclen = %d\n", recno.reclen) ; printf (" bval = %d\n", recno.bval) ; ! printf (" bfname = %d [%s]\n", recno.bfname, recno.bfname) ; } PrintBtree(btree) *************** *** 278,283 **** --- 287,313 ---- return (RETVAL) ; } + static recno_t + GetRecnoKey(db, value) + DB_File db ; + I32 value ; + { + if (value < 0) { + /* Get the length of the array */ + I32 length = GetArrayLength(db->dbp) ; + + /* check for attempt to write before start of array */ + if (length + value + 1 <= 0) + croak("Modification of non-creatable array value attempted, subscript %d", value) ; + + value = length + value + 1 ; + } + else + ++ value ; + + return value ; + } + static DB_File ParseOpenInfo(name, flags, mode, sv, string) char * name ; *************** *** 291,298 **** union INFO info ; DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ; void * openinfo = NULL ; - /* DBTYPE type = DB_HASH ; */ RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ; RETVAL->type = DB_HASH ; --- 321,328 ---- union INFO info ; DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ; void * openinfo = NULL ; + /* Default to HASH */ RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ; RETVAL->type = DB_HASH ; *************** *** 415,421 **** } svp = hv_fetch(action, "bfname", 6, FALSE); ! info.recno.bfname = (char *) svp ? SvPV(*svp,na) : 0; PrintRecno(info) ; } --- 445,454 ---- } svp = hv_fetch(action, "bfname", 6, FALSE); ! if (svp) { ! char * ptr = SvPV(*svp,na) ; ! info.recno.bfname = (char*) na ? ptr : 0 ; ! } PrintRecno(info) ; } *************** *** 424,440 **** } ! RETVAL->dbp = dbopen(name, flags, mode, RETVAL->type, openinfo) ; ! ! #if 0 ! /* kludge mode on: RETVAL->type for DB_RECNO is set to DB_BTREE ! so remember a DB_RECNO by saving the address ! of one of it's internal routines ! */ ! if (RETVAL->dbp && type == DB_RECNO) ! DB_recno_close = RETVAL->dbp->close ; ! #endif return (RETVAL) ; } --- 457,470 ---- } ! /* OS2 Specific Code */ ! #ifdef OS2 ! #ifdef __EMX__ ! flags |= O_BINARY; ! #endif /* __EMX__ */ ! #endif /* OS2 */ + RETVAL->dbp = dbopen(name, flags, mode, RETVAL->type, openinfo) ; return (RETVAL) ; } *************** *** 695,704 **** DB_File ! db_TIEHASH(dbtype, name=undef, flags=O_RDWR, mode=0640, type=DB_HASH) char * dbtype int flags int mode CODE: { char * name = (char *) NULL ; --- 725,735 ---- DB_File ! db_TIEHASH(dbtype, name=undef, flags=O_CREAT|O_RDWR, mode=0640, type=DB_HASH) char * dbtype int flags int mode + ALIAS: TIEARRAY = 1 CODE: { char * name = (char *) NULL ; *************** *** 716,724 **** } OUTPUT: RETVAL - - BOOT: - newXS("DB_File::TIEARRAY", XS_DB_File_db_TIEHASH, file); int db_DESTROY(db) --- 747,752 ---- #~ Update to version 1.02 diff -Pcr perl5_003/ext/DB_File/Makefile.PL perl5_003_01/ext/DB_File/Makefile.PL *** perl5_003/ext/DB_File/Makefile.PL Sun Jun 23 22:06:40 1996 --- perl5_003_01/ext/DB_File/Makefile.PL Fri Jul 5 18:45:33 1996 *************** *** 1,11 **** ! use ExtUtils::MakeMaker; WriteMakefile( ! NAME => 'DB_File', ! LIBS => ["-L/usr/local/lib -ldb"], ! MAN3PODS => ' ', # Pods will be built by installman. ! #INC => '-I/usr/local/include', VERSION_FROM => 'DB_File.pm', ! XSPROTOARG => '-noprototypes', # XXX remove later? ! ); --- 1,16 ---- ! use ExtUtils::MakeMaker 5.16 ; ! use Config ; ! ! # OS2 is a special case, so check for it now. ! my $OS2 = "-DOS2" if $Config{'osname'} eq 'os2' ; WriteMakefile( ! NAME => 'DB_File', ! LIBS => ["-L/usr/local/lib -ldb"], ! MAN3PODS => ' ', # Pods will be built by installman. ! #INC => '-I/usr/local/include', VERSION_FROM => 'DB_File.pm', ! XSPROTOARG => '-noprototypes', ! DEFINE => "$OS2", ! ); #~ Update to version 1.02 diff -Pcr perl5_003/ext/DB_File/typemap perl5_003_01/ext/DB_File/typemap *** perl5_003/ext/DB_File/typemap Sat Jan 20 00:55:41 1996 --- perl5_003_01/ext/DB_File/typemap Fri Jul 5 18:45:31 1996 *************** *** 1,8 **** # typemap for Perl 5 interface to Berkeley DB # # written by Paul Marquess (pmarquess@bfsec.bt.co.uk) ! # last modified 23rd June 1994 ! # version 0.1 # #################################### DB SECTION # --- 1,8 ---- # typemap for Perl 5 interface to Berkeley DB # # written by Paul Marquess (pmarquess@bfsec.bt.co.uk) ! # last modified 28th June 1996 ! # version 0.2 # #################################### DB SECTION # *************** *** 15,29 **** INPUT T_dbtkeydatum ! if (db->type != DB_RECNO) ! { $var.data = SvPV($arg, na); $var.size = (int)na; } ! else ! { ! Value = SvIV($arg) ; ! ++ Value ; $var.data = & Value; $var.size = (int)sizeof(recno_t); } --- 15,26 ---- INPUT T_dbtkeydatum ! if (db->type != DB_RECNO) { $var.data = SvPV($arg, na); $var.size = (int)na; } ! else { ! Value = GetRecnoKey(db, SvIV($arg)) ; $var.data = & Value; $var.size = (int)sizeof(recno_t); } #~ Use explicit dependency to select XS file, and suffix rules from there diff -Pcr perl5_003/ext/DynaLoader/Makefile.PL perl5_003_01/ext/DynaLoader/Makefile.PL *** perl5_003/ext/DynaLoader/Makefile.PL Sun Jun 23 22:07:51 1996 --- perl5_003_01/ext/DynaLoader/Makefile.PL Mon Jun 17 15:09:19 1996 *************** *** 1,21 **** use ExtUtils::MakeMaker; WriteMakefile( ! NAME => 'DynaLoader', LINKTYPE => 'static', DEFINE => '-DLIBC="$(LIBC)"', MAN3PODS => ' ', # Pods will be built by installman. SKIP => [qw(dynamic dynamic_lib dynamic_bs)], XSPROTOARG => '-noprototypes', # XXX remove later? VERSION_FROM => 'DynaLoader.pm', ! clean => {FILES => 'DynaLoader.c'}, ); sub MY::postamble { ' ! DynaLoader.c: $(DLSRC) ! $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $(DLSRC) >tmp && mv tmp $@ # Perform very simple tests just to check for major gaffs. # We can\'t do much more for platforms we are not executing on. --- 1,21 ---- use ExtUtils::MakeMaker; WriteMakefile( ! NAME => 'DynaLoader', LINKTYPE => 'static', DEFINE => '-DLIBC="$(LIBC)"', MAN3PODS => ' ', # Pods will be built by installman. SKIP => [qw(dynamic dynamic_lib dynamic_bs)], XSPROTOARG => '-noprototypes', # XXX remove later? VERSION_FROM => 'DynaLoader.pm', ! clean => {FILES => 'DynaLoader.c DynaLoader.xs'}, ); sub MY::postamble { ' ! DynaLoader.xs: $(DLSRC) ! $(CP) $? $@ # Perform very simple tests just to check for major gaffs. # We can\'t do much more for platforms we are not executing on. #~ Add NeXTSTEP/OPENSTEP 4 support diff -Pcr perl5_003/ext/DynaLoader/dl_next.xs perl5_003_01/ext/DynaLoader/dl_next.xs *** perl5_003/ext/DynaLoader/dl_next.xs Thu Oct 19 20:13:39 1995 --- perl5_003_01/ext/DynaLoader/dl_next.xs Thu Jul 11 12:26:01 1996 *************** *** 31,39 **** --- 31,42 ---- */ + #if NS_TARGET_MAJOR >= 4 + #else /* include these before perl headers */ #include #include + #endif #include "EXTERN.h" #include "perl.h" *************** *** 47,61 **** static char * dl_last_error = (char *) 0; static AV *dl_resolve_using = Nullav; ! NXStream * ! OpenError() { return NXOpenMemory( (char *) 0, 0, NX_WRITEONLY); } ! void ! TransferError( s) ! NXStream *s; { char *buffer; int len, maxlen; --- 50,154 ---- static char * dl_last_error = (char *) 0; static AV *dl_resolve_using = Nullav; ! static char *dlerror() ! { ! return dl_last_error; ! } ! ! int dlclose(handle) /* stub only */ ! void *handle; ! { ! return 0; ! } ! ! #if NS_TARGET_MAJOR >= 4 ! #import ! ! enum dyldErrorSource ! { ! OFImage, ! }; ! ! static void TranslateError ! (const char *path, enum dyldErrorSource type, int number) ! { ! char errorBuffer[128]; ! unsigned int index; ! static char *OFIErrorStrings[] = ! { ! "%s(%d): Object Image Load Failure\n", ! "%s(%d): Object Image Load Success\n", ! "%s(%d): Not an recognisable object file\n", ! "%s(%d): No valid architecture\n", ! "%s(%d): Object image has an invalid format\n", ! "%s(%d): Invalid access (permissions?)\n", ! "%s(%d): Unknown error code from NSCreateObjectFileImageFromFile\n", ! }; ! #define NUM_OFI_ERRORS (sizeof(OFIErrorStrings) / sizeof(OFIErrorStrings[0])) ! ! if ( dl_last_error ) { ! safefree(dl_last_error); ! } ! switch (type) ! { ! case OFImage: ! index = number; ! if (index > NUM_OFI_ERRORS - 1) ! index = NUM_OFI_ERRORS - 1; ! sprintf(errorBuffer, OFIErrorStrings[index], path, number); ! break; ! ! default: ! sprintf(errorBuffer, "%s(%d): Totally unknown error type %d\n", ! path, number, type); ! break; ! } ! dl_last_error = safemalloc(strlen(errorBuffer)+1); ! strcpy(dl_last_error, errorBuffer); ! } ! ! static char *dlopen(char *path, int mode /* mode is ignored */) ! { ! int dyld_result; ! NSObjectFileImage ofile; ! NSModule handle = NULL; ! ! dyld_result = NSCreateObjectFileImageFromFile(path, &ofile); ! if (dyld_result != NSObjectFileImageSuccess) ! TranslateError(path, OFImage, dyld_result); ! else ! { ! // NSLinkModule will cause the run to abort on any link error's ! // not very friendly but the error recovery functionality is limited. ! handle = NSLinkModule(ofile, path, TRUE); ! } ! ! return handle; ! } ! ! void * ! dlsym(handle, symbol) ! void *handle; ! char *symbol; ! { ! void *addr; ! ! if (NSIsSymbolNameDefined(symbol)) ! addr = NSAddressOfSymbol(NSLookupAndBindSymbol(symbol)); ! else ! addr = NULL; ! ! return addr; ! } ! ! #else /* NS_TARGET_MAJOR <= 3 */ ! ! static NXStream *OpenError(void) { return NXOpenMemory( (char *) 0, 0, NX_WRITEONLY); } ! static void TransferError(NXStream *s) { char *buffer; int len, maxlen; *************** *** 68,91 **** strcpy(dl_last_error, buffer); } ! void ! CloseError( s) ! NXStream *s; { if ( s ) { NXCloseMemory( s, NX_FREEBUFFER); } } ! char *dlerror() ! { ! return dl_last_error; ! } ! ! char * ! dlopen(path, mode) ! char * path; ! int mode; /* mode is ignored */ { int rld_success; NXStream *nxerr; --- 161,174 ---- strcpy(dl_last_error, buffer); } ! static void CloseError(NXStream *s) { if ( s ) { NXCloseMemory( s, NX_FREEBUFFER); } } ! static char *dlopen(char *path, int mode /* mode is ignored */) { int rld_success; NXStream *nxerr; *************** *** 120,132 **** return result; } - int - dlclose(handle) /* stub only */ - void *handle; - { - return 0; - } - void * dlsym(handle, symbol) void *handle; --- 203,208 ---- *************** *** 144,149 **** --- 220,227 ---- return (void*) symref; } + #endif /* NS_TARGET_MAJOR >= 4 */ + /* ----- code from dl_dlopen.xs below here ----- */ *************** *** 182,187 **** --- 260,269 ---- void * libhandle char * symbolname CODE: + #if NS_TARGET_MAJOR >= 4 + char symbolname_buf[1024]; + symbolname = dl_add_underscore(symbolname, symbolname_buf); + #endif DLDEBUG(2,fprintf(stderr,"dl_find_symbol(handle=%x, symbol=%s)\n", libhandle, symbolname)); RETVAL = dlsym(libhandle, symbolname); #~ Add cast to malloc to calm cc when system headers decalre int malloc() diff -Pcr perl5_003/ext/DynaLoader/dlutils.c perl5_003_01/ext/DynaLoader/dlutils.c *** perl5_003/ext/DynaLoader/dlutils.c Thu Oct 19 20:13:53 1995 --- perl5_003_01/ext/DynaLoader/dlutils.c Wed Jul 3 17:45:45 1996 *************** *** 75,81 **** if (LastError) LastError = (char*)saferealloc(LastError, len) ; else ! LastError = safemalloc(len) ; /* Copy message into LastError (including terminating null char) */ strncpy(LastError, message, len) ; --- 75,81 ---- if (LastError) LastError = (char*)saferealloc(LastError, len) ; else ! LastError = (char *) safemalloc(len) ; /* Copy message into LastError (including terminating null char) */ strncpy(LastError, message, len) ; #~ Close file only once during object destruction. diff -Pcr perl5_003/ext/FileHandle/FileHandle.pm perl5_003_01/ext/FileHandle/FileHandle.pm *** perl5_003/ext/FileHandle/FileHandle.pm Mon Mar 25 01:04:05 1996 --- perl5_003_01/ext/FileHandle/FileHandle.pm Wed Jul 24 10:05:27 1996 *************** *** 252,258 **** sub DESTROY { my ($fh) = @_; ! close($fh); } ################################################ --- 252,270 ---- sub DESTROY { my ($fh) = @_; ! ! # During global object destruction, this function may be called ! # on FILEHANDLEs as well as on the GLOBs that contains them. ! # Thus the following trickery. If only the CORE file operators ! # could deal with FILEHANDLEs, it wouldn't be necessary... ! ! if ($fh =~ /=FILEHANDLE\(/) { ! local *TMP = $fh; ! close(TMP) if fileno(TMP); ! } ! else { ! close($fh) if fileno($fh); ! } } ################################################ #~ Don't repeat inclusion of stdio.h #~ Use Fflush() macro to allow for OS-specific overrides diff -Pcr perl5_003/ext/FileHandle/FileHandle.xs perl5_003_01/ext/FileHandle/FileHandle.xs *** perl5_003/ext/FileHandle/FileHandle.xs Mon Feb 12 14:50:47 1996 --- perl5_003_01/ext/FileHandle/FileHandle.xs Sat Jul 27 14:16:53 1996 *************** *** 1,7 **** #include "EXTERN.h" #include "perl.h" #include "XSUB.h" - #include typedef int SysRet; typedef FILE * InputStream; --- 1,6 ---- *************** *** 137,143 **** OutputStream handle CODE: if (handle) ! RETVAL = fflush(handle); else { RETVAL = -1; errno = EINVAL; --- 136,142 ---- OutputStream handle CODE: if (handle) ! RETVAL = Fflush(handle); else { RETVAL = -1; errno = EINVAL; #~ Quote string argument in example -- necessary if using strict subs diff -Pcr perl5_003/ext/GDBM_File/GDBM_File.pm perl5_003_01/ext/GDBM_File/GDBM_File.pm *** perl5_003/ext/GDBM_File/GDBM_File.pm Mon Feb 12 14:51:00 1996 --- perl5_003_01/ext/GDBM_File/GDBM_File.pm Mon Jul 15 13:35:30 1996 *************** *** 7,13 **** =head1 SYNOPSIS use GDBM_File ; ! tie %hash, GDBM_File, $filename, &GDBM_WRCREAT, 0640); # Use the %hash array. untie %hash ; --- 7,13 ---- =head1 SYNOPSIS use GDBM_File ; ! tie %hash, 'GDBM_File', $filename, &GDBM_WRCREAT, 0640); # Use the %hash array. untie %hash ; #~ Add IO extension diff -Pcr perl5_003/ext/IO/IO.pm perl5_003_01/ext/IO/IO.pm *** perl5_003/ext/IO/IO.pm Wed Dec 31 19:00:00 1969 --- perl5_003_01/ext/IO/IO.pm Mon Jul 8 16:45:36 1996 *************** *** 0 **** --- 1,12 ---- + # + + package IO; + + use IO::Handle; + use IO::Seekable; + use IO::File; + use IO::Pipe; + use IO::Socket; + + 1; + #~ Add IO extension diff -Pcr perl5_003/ext/IO/IO.xs perl5_003_01/ext/IO/IO.xs *** perl5_003/ext/IO/IO.xs Wed Dec 31 19:00:00 1969 --- perl5_003_01/ext/IO/IO.xs Sat Jul 27 14:17:48 1996 *************** *** 0 **** --- 1,208 ---- + #include "EXTERN.h" + #include "perl.h" + #include "XSUB.h" + #ifdef I_UNISTD + # include + #endif + + typedef int SysRet; + typedef FILE * InputStream; + typedef FILE * OutputStream; + + static int + not_here(s) + char *s; + { + croak("%s not implemented on this architecture", s); + return -1; + } + + static bool + constant(name, pval) + char *name; + IV *pval; + { + switch (*name) { + case '_': + if (strEQ(name, "_IOFBF")) + #ifdef _IOFBF + { *pval = _IOFBF; return TRUE; } + #else + return FALSE; + #endif + if (strEQ(name, "_IOLBF")) + #ifdef _IOLBF + { *pval = _IOLBF; return TRUE; } + #else + return FALSE; + #endif + if (strEQ(name, "_IONBF")) + #ifdef _IONBF + { *pval = _IONBF; return TRUE; } + #else + return FALSE; + #endif + break; + case 'S': + if (strEQ(name, "SEEK_SET")) + #ifdef SEEK_SET + { *pval = SEEK_SET; return TRUE; } + #else + return FALSE; + #endif + if (strEQ(name, "SEEK_CUR")) + #ifdef SEEK_CUR + { *pval = SEEK_CUR; return TRUE; } + #else + return FALSE; + #endif + if (strEQ(name, "SEEK_END")) + #ifdef SEEK_END + { *pval = SEEK_END; return TRUE; } + #else + return FALSE; + #endif + if (strEQ(name, "SEEK_EOF")) + #ifdef SEEK_EOF + { *pval = SEEK_EOF; return TRUE; } + #else + return FALSE; + #endif + break; + } + + return FALSE; + } + + + MODULE = IO PACKAGE = IO::Seekable PREFIX = f + + SV * + fgetpos(handle) + InputStream handle + CODE: + #ifdef HAS_FGETPOS + if (handle) { + Fpos_t pos; + fgetpos(handle, &pos); + ST(0) = sv_2mortal(newSVpv((char*)&pos, sizeof(Fpos_t))); + } + else { + ST(0) = &sv_undef; + errno = EINVAL; + } + #else + ST(0) = (SV *) not_here("IO::Seekable::fgetpos"); + #endif + + SysRet + fsetpos(handle, pos) + InputStream handle + SV * pos + CODE: + #ifdef HAS_FSETPOS + if (handle) + RETVAL = fsetpos(handle, (Fpos_t*)SvPVX(pos)); + else { + RETVAL = -1; + errno = EINVAL; + } + #else + RETVAL = (SysRet) not_here("IO::Seekable::fsetpos"); + #endif + OUTPUT: + RETVAL + + MODULE = IO PACKAGE = IO::File PREFIX = f + + OutputStream + new_tmpfile(packname = "IO::File") + char * packname + CODE: + RETVAL = tmpfile(); + OUTPUT: + RETVAL + + MODULE = IO PACKAGE = IO::Handle PREFIX = f + + SV * + constant(name) + char * name + CODE: + IV i; + if (constant(name, &i)) + ST(0) = sv_2mortal(newSViv(i)); + else + ST(0) = &sv_undef; + + int + ungetc(handle, c) + InputStream handle + int c + CODE: + if (handle) + RETVAL = ungetc(c, handle); + else { + RETVAL = -1; + errno = EINVAL; + } + OUTPUT: + RETVAL + + int + ferror(handle) + InputStream handle + CODE: + if (handle) + RETVAL = ferror(handle); + else { + RETVAL = -1; + errno = EINVAL; + } + OUTPUT: + RETVAL + + SysRet + fflush(handle) + OutputStream handle + CODE: + if (handle) + RETVAL = Fflush(handle); + else { + RETVAL = -1; + errno = EINVAL; + } + OUTPUT: + RETVAL + + void + setbuf(handle, buf) + OutputStream handle + char * buf = SvPOK(ST(1)) ? sv_grow(ST(1), BUFSIZ) : 0; + CODE: + if (handle) + setbuf(handle, buf); + + + + SysRet + setvbuf(handle, buf, type, size) + OutputStream handle + char * buf = SvPOK(ST(1)) ? sv_grow(ST(1), SvIV(ST(3))) : 0; + int type + int size + CODE: + #ifdef _IOFBF /* Should be HAS_SETVBUF once Configure tests for that */ + if (handle) + RETVAL = setvbuf(handle, buf, type, size); + else { + RETVAL = -1; + errno = EINVAL; + } + #else + RETVAL = (SysRet) not_here("IO::Handle::setvbuf"); + #endif /* _IOFBF */ + OUTPUT: + RETVAL + + #~ Add IO extension diff -Pcr perl5_003/ext/IO/Makefile.PL perl5_003_01/ext/IO/Makefile.PL *** perl5_003/ext/IO/Makefile.PL Wed Dec 31 19:00:00 1969 --- perl5_003_01/ext/IO/Makefile.PL Tue Jul 9 12:05:14 1996 *************** *** 0 **** --- 1,7 ---- + use ExtUtils::MakeMaker; + WriteMakefile( + NAME => 'IO', + MAN3PODS => ' ', # Pods will be built by installman. + XSPROTOARG => '-noprototypes', # XXX remove later? + VERSION_FROM => 'lib/IO/Handle.pm', + ); #~ Add IO extension diff -Pcr perl5_003/ext/IO/lib/IO/File.pm perl5_003_01/ext/IO/lib/IO/File.pm *** perl5_003/ext/IO/lib/IO/File.pm Wed Dec 31 19:00:00 1969 --- perl5_003_01/ext/IO/lib/IO/File.pm Mon Jul 8 16:45:22 1996 *************** *** 0 **** --- 1,144 ---- + # + + package IO::File; + + =head1 NAME + + IO::File - supply object methods for filehandles + + =head1 SYNOPSIS + + use IO::File; + + $fh = new IO::File; + if ($fh->open "< file") { + print <$fh>; + $fh->close; + } + + $fh = new IO::File "> FOO"; + if (defined $fh) { + print $fh "bar\n"; + $fh->close; + } + + $fh = new IO::File "file", "r"; + if (defined $fh) { + print <$fh>; + undef $fh; # automatically closes the file + } + + $fh = new IO::File "file", O_WRONLY|O_APPEND; + if (defined $fh) { + print $fh "corge\n"; + undef $fh; # automatically closes the file + } + + $pos = $fh->getpos; + $fh->setpos $pos; + + $fh->setvbuf($buffer_var, _IOLBF, 1024); + + autoflush STDOUT 1; + + =head1 DESCRIPTION + + C creates a C, which is a reference to a + newly created symbol (see the C package). If it receives any + parameters, they are passed to C; if the open fails, + the C object is destroyed. Otherwise, it is returned to + the caller. + + C accepts one parameter or two. With one parameter, + it is just a front end for the built-in C function. With two + parameters, the first parameter is a filename that may include + whitespace or other special characters, and the second parameter is + the open mode in either Perl form (">", "+<", etc.) or POSIX form + ("w", "r+", etc.). + + =head1 SEE ALSO + + L, + L, + L<"IO::Handle"> + L<"IO::Seekable"> + + =head1 HISTORY + + Derived from FileHandle.pm by Graham Barr + + =head1 REVISION + + $Revision: 1.3 $ + + =cut + + require 5.000; + use vars qw($VERSION @EXPORT @EXPORT_OK $AUTOLOAD); + use Carp; + use Symbol; + use English; + use SelectSaver; + use IO::Handle qw(_open_mode_string); + use IO::Seekable; + + require Exporter; + require DynaLoader; + + @ISA = qw(IO::Handle IO::Seekable Exporter DynaLoader); + + $VERSION = sprintf("%d.%02d", q$Revision: 1.3 $ =~ /(\d+)\.(\d+)/); + + @EXPORT = @IO::Seekable::EXPORT; + + ################################################ + ## If the Fcntl extension is available, + ## export its constants. + ## + + sub import { + my $pkg = shift; + my $callpkg = caller; + Exporter::export $pkg, $callpkg; + eval { + require Fcntl; + Exporter::export 'Fcntl', $callpkg; + }; + }; + + + ################################################ + ## Constructor + ## + + sub new { + @_ >= 1 && @_ <= 3 or croak 'usage: new IO::File [FILENAME [,MODE]]'; + my $class = shift; + my $fh = $class->SUPER::new(); + if (@_) { + $fh->open(@_) + or return undef; + } + $fh; + } + + ################################################ + ## Open + ## + + sub open { + @_ >= 2 && @_ <= 4 or croak 'usage: $fh->open(FILENAME [,MODE [,PERMS]])'; + my ($fh, $file) = @_; + if (@_ > 2) { + my ($mode, $perms) = @_[2, 3]; + if ($mode =~ /^\d+$/) { + defined $perms or $perms = 0666; + return sysopen($fh, $file, $mode, $perms); + } + $file = "./" . $file unless $file =~ m#^/#; + $file = _open_mode_string($mode) . " $file\0"; + } + open($fh, $file); + } + + 1; #~ Add IO extension diff -Pcr perl5_003/ext/IO/lib/IO/Handle.pm perl5_003_01/ext/IO/lib/IO/Handle.pm *** perl5_003/ext/IO/lib/IO/Handle.pm Wed Dec 31 19:00:00 1969 --- perl5_003_01/ext/IO/lib/IO/Handle.pm Mon Jul 8 16:45:22 1996 *************** *** 0 **** --- 1,514 ---- + # + + package IO::Handle; + + =head1 NAME + + IO::Handle - supply object methods for filehandles + + =head1 SYNOPSIS + + use IO::Handle; + + $fh = new IO::Handle; + if ($fh->open "< file") { + print <$fh>; + $fh->close; + } + + $fh = new IO::Handle "> FOO"; + if (defined $fh) { + print $fh "bar\n"; + $fh->close; + } + + $fh = new IO::Handle "file", "r"; + if (defined $fh) { + print <$fh>; + undef $fh; # automatically closes the file + } + + $fh = new IO::Handle "file", O_WRONLY|O_APPEND; + if (defined $fh) { + print $fh "corge\n"; + undef $fh; # automatically closes the file + } + + $pos = $fh->getpos; + $fh->setpos $pos; + + $fh->setvbuf($buffer_var, _IOLBF, 1024); + + autoflush STDOUT 1; + + =head1 DESCRIPTION + + C creates a C, which is a reference to a + newly created symbol (see the C package). If it receives any + parameters, they are passed to C; if the open fails, + the C object is destroyed. Otherwise, it is returned to + the caller. + + C creates a C like C does. + It requires two parameters, which are passed to C; + if the fdopen fails, the C object is destroyed. + Otherwise, it is returned to the caller. + + C accepts one parameter or two. With one parameter, + it is just a front end for the built-in C function. With two + parameters, the first parameter is a filename that may include + whitespace or other special characters, and the second parameter is + the open mode in either Perl form (">", "+<", etc.) or POSIX form + ("w", "r+", etc.). + + C is like C except that its first parameter + is not a filename but rather a file handle name, a IO::Handle object, + or a file descriptor number. + + C is like C found in C, that is it is the + opposite of read. The wrapper for the perl C function is + called C. + + C returns true if the object is currently a valid + file descriptor. + + If the C functions fgetpos() and fsetpos() are available, then + C returns an opaque value that represents the + current position of the IO::Handle, and C uses + that value to return to a previously visited position. + + If the C function setvbuf() is available, then C + sets the buffering policy for the IO::Handle. The calling sequence + for the Perl function is the same as its C counterpart, including the + macros C<_IOFBF>, C<_IOLBF>, and C<_IONBF>, except that the buffer + parameter specifies a scalar variable to use as a buffer. WARNING: A + variable used as a buffer by C must not be + modified in any way until the IO::Handle is closed or until + C is called again, or memory corruption may + result! + + See L for complete descriptions of each of the following + supported C methods, which are just front ends for the + corresponding built-in functions: + + close + fileno + getc + gets + eof + read + truncate + stat + + See L for complete descriptions of each of the following + supported C methods: + + autoflush + output_field_separator + output_record_separator + input_record_separator + input_line_number + format_page_number + format_lines_per_page + format_lines_left + format_name + format_top_name + format_line_break_characters + format_formfeed + format_write + + Furthermore, for doing normal I/O you might need these: + + =over + + =item $fh->print + + See L. + + =item $fh->printf + + See L. + + =item $fh->getline + + This works like <$fh> described in L + except that it's more readable and can be safely called in an + array context but still returns just one line. + + =item $fh->getlines + + This works like <$fh> when called in an array context to + read all the remaining lines in a file, except that it's more readable. + It will also croak() if accidentally called in a scalar context. + + =back + + =head1 + + The reference returned from new is a GLOB reference. Some modules that + inherit from C may want to keep object related variables + in the hash table part of the GLOB. In an attempt to prevent modules + trampling on each other I propose the that any such module should prefix + its variables with its own name separated by _'s. For example the IO::Socket + module keeps a C variable in 'io_socket_timeout'. + + =head1 SEE ALSO + + L, + L, + L + + =head1 BUGS + + Due to backwards compatibility, all filehandles resemble objects + of class C, or actually classes derived from that class. + They actually aren't. Which means you can't derive your own + class from C and inherit those methods. + + =head1 HISTORY + + Derived from FileHandle.pm by Graham Barr + + =cut + + require 5.000; + use vars qw($VERSION @EXPORT_OK $AUTOLOAD); + use Carp; + use Symbol; + use SelectSaver; + + require Exporter; + @ISA = qw(Exporter); + + ## + ## TEMPORARY workaround as perl expects handles to be objects + ## + @FileHandle::ISA = qw(IO::Handle); + + + $VERSION = sprintf("%d.%02d", q$Revision: 1.8 $ =~ /(\d+)\.(\d+)/); + + @EXPORT_OK = qw( + autoflush + output_field_separator + output_record_separator + input_record_separator + input_line_number + format_page_number + format_lines_per_page + format_lines_left + format_name + format_top_name + format_line_break_characters + format_formfeed + format_write + + print + printf + getline + getlines + + SEEK_SET + SEEK_CUR + SEEK_END + _IOFBF + _IOLBF + _IONBF + + _open_mode_string + ); + + + ################################################ + ## Interaction with the XS. + ## + + require DynaLoader; + @IO::ISA = qw(DynaLoader); + bootstrap IO $VERSION; + + sub AUTOLOAD { + if ($AUTOLOAD =~ /::(_?[a-z])/) { + $AutoLoader::AUTOLOAD = $AUTOLOAD; + goto &AutoLoader::AUTOLOAD + } + my $constname = $AUTOLOAD; + $constname =~ s/.*:://; + my $val = constant($constname); + defined $val or croak "$constname is not a valid IO::Handle macro"; + *$AUTOLOAD = sub { $val }; + goto &$AUTOLOAD; + } + + + ################################################ + ## Constructors, destructors. + ## + + sub new { + @_ == 1 or croak 'usage: new IO::Handle'; + my $class = ref($_[0]) || $_[0]; + my $fh = gensym; + bless $fh, $class; + } + + sub new_from_fd { + @_ == 3 or croak 'usage: new_from_fd IO::Handle FD, MODE'; + my $class = shift; + my $fh = gensym; + IO::Handle::fdopen($fh, @_) + or return undef; + bless $fh, $class; + $fh->_ref_fd; + $fh; + } + + # FileHandle::DESTROY use to call close(). This creates a problem + # if 2 Handle objects have the same fd. sv_clear will call io close + # when the refcount in the xpvio becomes zero. + # + # It is defined as empty to stop AUTOLOAD being called :-) + + sub DESTROY { } + + ################################################ + ## Open and close. + ## + + sub _open_mode_string { + my ($mode) = @_; + $mode =~ /^\+?(<|>>?)$/ + or $mode =~ s/^r(\+?)$/$1/ + or $mode =~ s/^a(\+?)$/$1>>/ + or croak "IO::Handle: bad open mode: $mode"; + $mode; + } + + sub fdopen { + @_ == 3 or croak 'usage: $fh->fdopen(FD, MODE)'; + my ($fh, $fd, $mode) = @_; + local(*GLOB); + + if (ref($fd) && "".$fd =~ /GLOB\(/o) { + # It's a glob reference; Alias it as we cannot get name of anon GLOBs + my $n = qualify(*GLOB); + *GLOB = *{*$fd}; + $fd = $n; + } elsif ($fd =~ m#^\d+$#) { + # It's an FD number; prefix with "=". + $fd = "=$fd"; + } + + open($fh, _open_mode_string($mode) . '&' . $fd) + ? $fh : undef; + } + + sub close { + @_ == 1 or croak 'usage: $fh->close()'; + my($fh) = @_; + my $r = close($fh); + + # This may seem as though it should be in IO::Pipe, but the + # object gets blessed out of IO::Pipe when reader/writer is called + waitpid(${*$fh}{'io_pipe_pid'},0) + if(defined ${*$fh}{'io_pipe_pid'}); + + $r; + } + + ################################################ + ## Normal I/O functions. + ## + + # fcntl + # flock + # ioctl + # select + # sysread + # syswrite + + sub opened { + @_ == 1 or croak 'usage: $fh->opened()'; + defined fileno($_[0]); + } + + sub fileno { + @_ == 1 or croak 'usage: $fh->fileno()'; + fileno($_[0]); + } + + sub getc { + @_ == 1 or croak 'usage: $fh->getc()'; + getc($_[0]); + } + + sub gets { + @_ == 1 or croak 'usage: $fh->gets()'; + my ($handle) = @_; + scalar <$handle>; + } + + sub eof { + @_ == 1 or croak 'usage: $fh->eof()'; + eof($_[0]); + } + + sub print { + @_ or croak 'usage: $fh->print([ARGS])'; + my $this = shift; + print $this @_; + } + + sub printf { + @_ >= 2 or croak 'usage: $fh->printf(FMT,[ARGS])'; + my $this = shift; + printf $this @_; + } + + sub getline { + @_ == 1 or croak 'usage: $fh->getline'; + my $this = shift; + return scalar <$this>; + } + + sub getlines { + @_ == 1 or croak 'usage: $fh->getline()'; + my $this = shift; + wantarray or + croak "Can't call IO::Handle::getlines in a scalar context, use IO::Handle::getline"; + return <$this>; + } + + sub truncate { + @_ == 2 or croak 'usage: $fh->truncate(LEN)'; + truncate($_[0], $_[1]); + } + + sub read { + @_ == 3 || @_ == 4 or croak '$fh->read(BUF, LEN [, OFFSET])'; + read($_[0], $_[1], $_[2], $_[3] || 0); + } + + sub write { + @_ == 3 || @_ == 4 or croak '$fh->write(BUF, LEN [, OFFSET])'; + local($\) = ""; + print { $_[0] } substr($_[1], $_[3] || 0, $_[2]); + } + + sub stat { + @_ == 1 or croak 'usage: $fh->stat()'; + stat($_[0]); + } + + ################################################ + ## State modification functions. + ## + + sub autoflush { + my $old = new SelectSaver qualify($_[0], caller); + my $prev = $|; + $| = @_ > 1 ? $_[1] : 1; + $prev; + } + + sub output_field_separator { + my $old = new SelectSaver qualify($_[0], caller); + my $prev = $,; + $, = $_[1] if @_ > 1; + $prev; + } + + sub output_record_separator { + my $old = new SelectSaver qualify($_[0], caller); + my $prev = $\; + $\ = $_[1] if @_ > 1; + $prev; + } + + sub input_record_separator { + my $old = new SelectSaver qualify($_[0], caller); + my $prev = $/; + $/ = $_[1] if @_ > 1; + $prev; + } + + sub input_line_number { + my $old = new SelectSaver qualify($_[0], caller); + my $prev = $.; + $. = $_[1] if @_ > 1; + $prev; + } + + sub format_page_number { + my $old = new SelectSaver qualify($_[0], caller); + my $prev = $%; + $% = $_[1] if @_ > 1; + $prev; + } + + sub format_lines_per_page { + my $old = new SelectSaver qualify($_[0], caller); + my $prev = $=; + $= = $_[1] if @_ > 1; + $prev; + } + + sub format_lines_left { + my $old = new SelectSaver qualify($_[0], caller); + my $prev = $-; + $- = $_[1] if @_ > 1; + $prev; + } + + sub format_name { + my $old = new SelectSaver qualify($_[0], caller); + my $prev = $~; + $~ = qualify($_[1], caller) if @_ > 1; + $prev; + } + + sub format_top_name { + my $old = new SelectSaver qualify($_[0], caller); + my $prev = $^; + $^ = qualify($_[1], caller) if @_ > 1; + $prev; + } + + sub format_line_break_characters { + my $old = new SelectSaver qualify($_[0], caller); + my $prev = $:; + $: = $_[1] if @_ > 1; + $prev; + } + + sub format_formfeed { + my $old = new SelectSaver qualify($_[0], caller); + my $prev = $^L; + $^L = $_[1] if @_ > 1; + $prev; + } + + sub formline { + my $fh = shift; + my $picture = shift; + local($^A) = $^A; + local($\) = ""; + formline($picture, @_); + print $fh $^A; + } + + sub format_write { + @_ < 3 || croak 'usage: $fh->write( [FORMAT_NAME] )'; + if (@_ == 2) { + my ($fh, $fmt) = @_; + my $oldfmt = $fh->format_name($fmt); + write($fh); + $fh->format_name($oldfmt); + } else { + write($_[0]); + } + } + + + 1; #~ Add IO extension diff -Pcr perl5_003/ext/IO/lib/IO/Pipe.pm perl5_003_01/ext/IO/lib/IO/Pipe.pm *** perl5_003/ext/IO/lib/IO/Pipe.pm Wed Dec 31 19:00:00 1969 --- perl5_003_01/ext/IO/lib/IO/Pipe.pm Mon Jul 8 16:45:22 1996 *************** *** 0 **** --- 1,177 ---- + # + + package IO::Pipe; + + =head1 NAME + + IO::pipe - supply object methods for pipes + + =head1 SYNOPSIS + + use IO::Pipe; + + $pipe = new IO::Pipe; + + if($pid = fork()) { # Parent + $pipe->reader(); + + while(<$pipe> { + .... + } + + } + elsif(defined $pid) { # Child + $pipe->writer(); + + print $pipe .... + } + + or + + $pipe = new IO::Pipe; + + $pipe->reader(qw(ls -l)); + + while(<$pipe>) { + .... + } + + =head1 DESCRIPTION + + C creates a C, which is a reference to a + newly created symbol (see the C package). C + optionally takes two arguments, which should be objects blessed into + C, or a subclass thereof. These two objects will be used + for the system call to C. If no arguments are given then then + method C is called on the new C object. + + These two handles are held in the array part of the GLOB untill either + C or C is called. + + =over + + =item $fh->reader([ARGS]) + + The object is re-blessed into a sub-class of C, and becomes a + handle at the reading end of the pipe. If C are given then C + is called and C are passed to exec. + + =item $fh->writer([ARGS]) + + The object is re-blessed into a sub-class of C, and becomes a + handle at the writing end of the pipe. If C are given then C + is called and C are passed to exec. + + =item $fh->handles + + This method is called during construction by C + on the newly created C object. It returns an array of two objects + blessed into C, or a subclass thereof. + + =back + + =head1 SEE ALSO + + L + + =head1 AUTHOR + + Graham Barr + + =head1 REVISION + + $Revision: 1.4 $ + + =head1 COPYRIGHT + + Copyright (c) 1995 Graham Barr. All rights reserved. This program is free + software; you can redistribute it and/or modify it under the same terms + as Perl itself. + + =cut + + require 5.000; + use vars qw($VERSION); + use Carp; + use Symbol; + require IO::Handle; + + $VERSION = sprintf("%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/); + + sub new { + @_ == 1 || @_ == 3 or croak 'usage: new IO::Pipe([$READFH, $WRITEFH])'; + + my $me = bless gensym(), shift; + + my($readfh,$writefh) = @_ ? @_ : $me->handles; + + pipe($readfh, $writefh) + or return undef; + + @{*$me} = ($readfh, $writefh); + + $me; + } + + sub handles { + @_ == 1 or croak 'usage: $pipe->handles()'; + (IO::Handle->new(), IO::Handle->new()); + } + + sub _doit { + my $me = shift; + my $rw = shift; + + my $pid = fork(); + + if($pid) { # Parent + return $pid; + } + elsif(defined $pid) { # Child + my $fh = $rw ? $me->reader() : $me->writer(); + my $io = $rw ? \*STDIN : \*STDOUT; + + bless $io, "IO::Handle"; + $io->fdopen($fh, $rw ? "r" : "w"); + exec @_ or + croak "IO::Pipe: Cannot exec: $!"; + } + else { + croak "IO::Pipe: Cannot fork: $!"; + } + + # NOT Reached + } + + sub reader { + @_ >= 1 or croak 'usage: $pipe->reader()'; + my $me = shift; + my $fh = ${*$me}[0]; + my $pid = $me->_doit(0,@_) + if(@_); + + bless $me, ref($fh); + *{*$me} = *{*$fh}; # Alias self to handle + ${*$me}{'io_pipe_pid'} = $pid + if defined $pid; + + $me; + } + + sub writer { + @_ >= 1 or croak 'usage: $pipe->writer()'; + my $me = shift; + my $fh = ${*$me}[1]; + my $pid = $me->_doit(1,@_) + if(@_); + + bless $me, ref($fh); + *{*$me} = *{*$fh}; # Alias self to handle + ${*$me}{'io_pipe_pid'} = $pid + if defined $pid; + + $me; + } + + 1; + #~ Add IO extension diff -Pcr perl5_003/ext/IO/lib/IO/Seekable.pm perl5_003_01/ext/IO/lib/IO/Seekable.pm *** perl5_003/ext/IO/lib/IO/Seekable.pm Wed Dec 31 19:00:00 1969 --- perl5_003_01/ext/IO/lib/IO/Seekable.pm Mon Jul 8 16:45:23 1996 *************** *** 0 **** --- 1,71 ---- + # + + package IO::Seekable; + + =head1 NAME + + IO::Seekable - supply seek based methods for I/O objects + + =head1 DESCRIPTION + + C does not have a constuctor of its own as is intended to + be inherited by other C based objects. It provides methods + which allow seeking of the file descriptors. + + If the C functions fgetpos() and fsetpos() are available, then + C returns an opaque value that represents the + current position of the IO::File, and C uses + that value to return to a previously visited position. + + See L for complete descriptions of each of the following + supported C methods, which are just front ends for the + corresponding built-in functions: + + clearerr + seek + tell + + =head1 SEE ALSO + + L, + L, + L<"IO::Handle"> + L<"IO::File"> + + =head1 HISTORY + + Derived from FileHandle.pm by Graham Barr + + =head1 REVISION + + $Revision: 1.4 $ + + =cut + + require 5.000; + use Carp; + use vars qw($VERSION @EXPORT @ISA); + use IO::Handle qw(SEEK_SET SEEK_CUR SEEK_END); + require Exporter; + + @EXPORT = qw(SEEK_SET SEEK_CUR SEEK_END); + @ISA = qw(Exporter); + + $VERSION = sprintf("%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/); + + sub clearerr { + @_ == 1 or croak 'usage: $fh->clearerr()'; + seek($_[0], 0, SEEK_CUR); + } + + sub seek { + @_ == 3 or croak 'usage: $fh->seek(POS, WHENCE)'; + seek($_[0], $_[1], $_[2]); + } + + sub tell { + @_ == 1 or croak 'usage: $fh->tell()'; + tell($_[0]); + } + + 1; #~ Add IO extension diff -Pcr perl5_003/ext/IO/lib/IO/Select.pm perl5_003_01/ext/IO/lib/IO/Select.pm *** perl5_003/ext/IO/lib/IO/Select.pm Wed Dec 31 19:00:00 1969 --- perl5_003_01/ext/IO/lib/IO/Select.pm Mon Jul 8 16:45:23 1996 *************** *** 0 **** --- 1,280 ---- + # IO::Select.pm + + package IO::Select; + + =head1 NAME + + IO::Select - OO interface to the system select call + + =head1 SYNOPSYS + + use IO::Select; + + $s = IO::Select->new(); + + $s->add(\*STDIN); + $s->add($some_handle); + + @ready = $s->can_read($timeout); + + @ready = IO::Select->new(@handles)->read(0); + + =head1 DESCRIPTION + + The C package implements an object approach to the system C is a static method, that is you call it with the package name + like C. C, C and C are either C or + C objects. C is optional and has the same effect as + before. + + The result will be an array of 3 elements, each a reference to an array + which will hold the handles that are ready for reading, writing and have + error conditions respectively. Upon error an empty array is returned. + + =back + + =head1 EXAMPLE + + Here is a short example which shows how C could be used + to write a server which communicates with several sockets while also + listening for more connections on a listen socket + + use IO::Select; + use IO::Socket; + + $lsn = new IO::Socket::INET(Listen => 1, LocalPort => 8080); + $sel = new IO::Select( $lsn ); + + while(@ready = $sel->can_read) { + foreach $fh (@ready) { + if($fh == $lsn) { + # Create a new socket + $new = $lsn->accept; + $sel->add($new); + } + else { + # Process socket + + # Maybe we have finished with the socket + $sel->remove($fh); + $fh->close; + } + } + } + + =head1 AUTHOR + + Graham Barr + + =head1 REVISION + + $Revision: 1.2 $ + + =head1 COPYRIGHT + + Copyright (c) 1995 Graham Barr. All rights reserved. This program is free + software; you can redistribute it and/or modify it under the same terms + as Perl itself. + + =cut + + use strict; + use vars qw($VERSION @ISA); + require Exporter; + + $VERSION = sprintf("%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/); + + @ISA = qw(Exporter); # This is only so we can do version checking + + sub new + { + my $self = shift; + my $type = ref($self) || $self; + + my $vec = bless [''], $type; + + $vec->add(@_) + if @_; + + $vec; + } + + sub add + { + my $vec = shift; + my $f; + + foreach $f (@_) + { + my $fn = $f =~ /^\d+$/ ? $f : fileno($f); + next + unless defined $fn; + vec($vec->[0],$fn++,1) = 1; + $vec->[$fn] = $f; + } + } + + sub remove + { + my $vec = shift; + my $f; + + foreach $f (@_) + { + my $fn = $f =~ /^\d+$/ ? $f : fileno($f); + next + unless defined $fn; + vec($vec->[0],$fn++,1) = 0; + $vec->[$fn] = undef; + } + } + + sub can_read + { + my $vec = shift; + my $timeout = shift; + + my $r = $vec->[0]; + + select($r,undef,undef,$timeout) > 0 + ? _handles($vec, $r) + : (); + } + + sub can_write + { + my $vec = shift; + my $timeout = shift; + + my $w = $vec->[0]; + + select(undef,$w,undef,$timeout) > 0 + ? _handles($vec, $w) + : (); + } + + sub has_error + { + my $vec = shift; + my $timeout = shift; + + my $e = $vec->[0]; + + select(undef,undef,$e,$timeout) > 0 + ? _handles($vec, $e) + : (); + } + + sub _max + { + my($a,$b,$c) = @_; + $a > $b + ? $a > $c + ? $a + : $c + : $b > $c + ? $b + : $c; + } + + sub select + { + shift + if defined $_[0] && !ref($_[0]); + + my($r,$w,$e,$t) = @_; + my @result = (); + + my $rb = defined $r ? $r->[0] : undef; + my $wb = defined $w ? $e->[0] : undef; + my $eb = defined $e ? $w->[0] : undef; + + if(select($rb,$wb,$eb,$t) > 0) + { + my @r = (); + my @w = (); + my @e = (); + my $i = _max(defined $r ? scalar(@$r) : 0, + defined $w ? scalar(@$w) : 0, + defined $e ? scalar(@$e) : 0); + + for( ; $i > 0 ; $i--) + { + my $j = $i - 1; + push(@r, $r->[$i]) + if defined $r->[$i] && vec($rb, $j, 1); + push(@w, $w->[$i]) + if defined $w->[$i] && vec($wb, $j, 1); + push(@e, $e->[$i]) + if defined $e->[$i] && vec($eb, $j, 1); + } + + @result = (\@r, \@w, \@e); + } + @result; + } + + sub _handles + { + my $vec = shift; + my $bits = shift; + my @h = (); + my $i; + + for($i = scalar(@$vec) - 1 ; $i > 0 ; $i--) + { + next unless defined $vec->[$i]; + push(@h, $vec->[$i]) + if vec($bits,$i - 1,1); + } + + @h; + } + + 1; #~ Add IO extension diff -Pcr perl5_003/ext/IO/lib/IO/Socket.pm perl5_003_01/ext/IO/lib/IO/Socket.pm *** perl5_003/ext/IO/lib/IO/Socket.pm Wed Dec 31 19:00:00 1969 --- perl5_003_01/ext/IO/lib/IO/Socket.pm Thu Jul 18 14:03:32 1996 *************** *** 0 **** --- 1,563 ---- + # + + package IO::Socket; + + =head1 NAME + + IO::Socket - supply object methods for sockets + + =head1 SYNOPSIS + + use IO::Socket; + + =head1 DESCRIPTION + + C provides an object interface to creating and using sockets. It + is built upon the L interface and inherits all the methods defined + by L. + + C only defines methods for those operations which are common to all + types of socket. Operations which are specified to a socket in a particular + domain have methods defined in sub classes of C + + See L for complete descriptions of each of the following + supported C methods, which are just front ends for the + corresponding built-in functions: + + socket + socketpair + bind + listen + accept + send + recv + peername (getpeername) + sockname (getsockname) + + Some methods take slightly different arguments to those defined in L + in attempt to make the interface more flexible. These are + + =item accept([PKG]) + + perform the system call C on the socket and return a new object. The + new object will be created in the same class as the listen socket, unless + C is specified. This object can be used to communicate with the client + that was trying to connect. In a scalar context the new socket is returned, + or undef upon failure. In an array context a two-element array is returned + containing the new socket and the peer address, the list will + be empty upon failure. + + Additional methods that are provided are + + =item timeout([VAL]) + + Set or get the timeout value associated with this socket. If called without + any arguments then the current setting is returned. If called with an argument + the current setting is changed and the previous value returned. + + =item sockopt(OPT [, VAL]) + + Unified method to both set and get options in the SOL_SOCKET level. If called + with one argument then getsockopt is called, otherwise setsockopt is called + + =cut + + + require 5.000; + + use Config; + use IO::Handle; + use Socket 1.3; + use Carp; + use strict; + use vars qw(@ISA @EXPORT_OK $VERSION); + use Exporter; + + @ISA = qw(IO::Handle); + + # This one will turn 1.2 => 1.02 and 1.2.3 => 1.0203 and so on ... + $VERSION = do{my @r=(q$Revision: 1.8$=~/(\d+)/g);sprintf "%d."."%02d"x$#r,@r}; + + sub import { + my $pkg = shift; + my $callpkg = caller; + Exporter::export 'Socket', $callpkg, @_; + } + + sub new { + my($class,%arg) = @_; + my $fh = $class->SUPER::new(); + + ${*$fh}{'io_socket_timeout'} = delete $arg{Timeout}; + + return scalar(%arg) ? $fh->configure(\%arg) + : $fh; + } + + sub configure { + croak 'IO::Socket: Cannot configure a generic socket'; + } + + sub socket { + @_ == 4 or croak 'usage: $fh->socket(DOMAIN, TYPE, PROTOCOL)'; + my($fh,$domain,$type,$protocol) = @_; + + socket($fh,$domain,$type,$protocol) or + return undef; + + ${*$fh}{'io_socket_type'} = $type; + $fh; + } + + sub socketpair { + @_ == 4 || croak 'usage: IO::Socket->pair(DOMAIN, TYPE, PROTOCOL)'; + my($class,$domain,$type,$protocol) = @_; + my $fh1 = $class->new(); + my $fh2 = $class->new(); + + socketpair($fh1,$fh1,$domain,$type,$protocol) or + return (); + + ${*$fh1}{'io_socket_type'} = ${*$fh2}{'io_socket_type'} = $type; + + ($fh1,$fh2); + } + + sub connect { + @_ == 2 || @_ == 3 or croak 'usage: $fh->connect(NAME) or $fh->connect(PORT, ADDR)'; + my $fh = shift; + my $addr = @_ == 1 ? shift : sockaddr_in(@_); + my $timeout = ${*$fh}{'io_socket_timeout'}; + local($SIG{ALRM}) = $timeout ? sub { undef $fh; } + : $SIG{ALRM} || 'DEFAULT'; + + eval { + croak 'connect: Bad address' + if(@_ == 2 && !defined $_[1]); + + if($timeout) { + defined $Config{d_alarm} && defined alarm($timeout) or + $timeout = 0; + } + + my $ok = eval { connect($fh, $addr) }; + + alarm(0) + if($timeout); + + croak "connect: timeout" + unless defined $fh; + + undef $fh unless $ok; + + }; + $fh; + } + + sub bind { + @_ == 2 || @_ == 3 or croak 'usage: $fh->bind(NAME) or $fh->bind(PORT, ADDR)'; + my $fh = shift; + my $addr = @_ == 1 ? shift : sockaddr_in(@_); + + return bind($fh, $addr) ? $fh + : undef; + } + + sub listen { + @_ >= 1 && @_ <= 2 or croak 'usage: $fh->listen([QUEUE])'; + my($fh,$queue) = @_; + $queue = 5 + unless $queue && $queue > 0; + + return listen($fh, $queue) ? $fh + : undef; + } + + sub accept { + @_ == 1 || @_ == 2 or croak 'usage $fh->accept([PKG])'; + my $fh = shift; + my $pkg = shift || $fh; + my $timeout = ${*$fh}{'io_socket_timeout'}; + my $new = $pkg->new(Timeout => $timeout); + my $peer = undef; + + eval { + if($timeout) { + my $fdset = ""; + vec($fdset, $fh->fileno,1) = 1; + croak "accept: timeout" + unless select($fdset,undef,undef,$timeout); + } + $peer = accept($new,$fh); + }; + + return wantarray ? defined $peer ? ($new, $peer) + : () + : defined $peer ? $new + : undef; + } + + sub sockname { + @_ == 1 or croak 'usage: $fh->sockname()'; + getsockname($_[0]); + } + + sub peername { + @_ == 1 or croak 'usage: $fh->peername()'; + my($fh) = @_; + getpeername($fh) + || ${*$fh}{'io_socket_peername'} + || undef; + } + + sub send { + @_ >= 2 && @_ <= 4 or croak 'usage: $fh->send(BUF, [FLAGS, [TO]])'; + my $fh = $_[0]; + my $flags = $_[2] || 0; + my $peer = $_[3] || $fh->peername; + + croak 'send: Cannot determine peer address' + unless($peer); + + my $r = send($fh, $_[1], $flags, $peer); + + # remember who we send to, if it was sucessful + ${*$fh}{'io_socket_peername'} = $peer + if(@_ == 4 && defined $r); + + $r; + } + + sub recv { + @_ == 3 || @_ == 4 or croak 'usage: $fh->recv(BUF, LEN [, FLAGS])'; + my $sock = $_[0]; + my $len = $_[2]; + my $flags = $_[3] || 0; + + # remember who we recv'd from + ${*$sock}{'io_socket_peername'} = recv($sock, $_[1]='', $len, $flags); + } + + + sub setsockopt { + @_ == 4 or croak '$fh->setsockopt(LEVEL, OPTNAME)'; + setsockopt($_[0],$_[1],$_[2],$_[3]); + } + + my $intsize = length(pack("i",0)); + + sub getsockopt { + @_ == 3 or croak '$fh->getsockopt(LEVEL, OPTNAME)'; + my $r = getsockopt($_[0],$_[1],$_[2]); + # Just a guess + $r = unpack("i", $r) + if(defined $r && length($r) == $intsize); + $r; + } + + sub sockopt { + my $fh = shift; + @_ == 1 ? $fh->getsockopt(SOL_SOCKET,@_) + : $fh->setsockopt(SOL_SOCKET,@_); + } + + sub timeout { + @_ == 1 || @_ == 2 or croak 'usage: $fh->timeout([VALUE])'; + my($fh,$val) = @_; + my $r = ${*$fh}{'io_socket_timeout'} || undef; + + ${*$fh}{'io_socket_timeout'} = 0 + $val + if(@_ == 2); + + $r; + } + + sub socktype { + @_ == 1 or croak '$fh->socktype()'; + ${*{$_[0]}}{'io_socket_type'} || undef; + } + + =head1 SUB-CLASSES + + =cut + + ## + ## AF_INET + ## + + package IO::Socket::INET; + + use strict; + use vars qw(@ISA $VERSION); + use Socket; + use Carp; + use Exporter; + + @ISA = qw(IO::Socket); + + my %socket_type = ( tcp => SOCK_STREAM, + udp => SOCK_DGRAM, + ); + + =head2 IO::Socket::INET + + C provides a constructor to create an AF_INET domain socket + and some related methods. The constructor can take the following options + + PeerAddr Remote host address + PeerPort Remote port or service + LocalPort Local host bind port + LocalAddr Local host bind address + Proto Protocol name (eg tcp udp etc) + Type Socket type (SOCK_STREAM etc) + Listen Queue size for listen + Timeout Timeout value for various operations + + If Listen is defined then a listen socket is created, else if the socket + type, which is derived from the protocol, is SOCK_STREAM then a connect + is called + + Only one of C or C needs to be specified, one will be assumed + from the other. + + =head2 METHODS + + =item sockaddr() + + Return the address part of the sockaddr structure for the socket + + =item sockport() + + Return the port number that the socket is using on the local host + + =item sockhost() + + Return the address part of the sockaddr structure for the socket in a + text form xx.xx.xx.xx + + =item peeraddr(), peerport(), peerhost() + + Same as for the sock* functions, but returns the data about the peer + host instead of the local host. + + =cut + + + sub _sock_info { + my($addr,$port,$proto) = @_; + my @proto = (); + my @serv = (); + + $port = $1 + if(defined $addr && $addr =~ s,:([\w\(\)/]+)$,,); + + if(defined $proto) { + @proto = $proto =~ m,\D, ? getprotobyname($proto) + : getprotobynumber($proto); + + $proto = $proto[2] || undef; + } + + if(defined $port) { + $port =~ s,\((\d+)\)$,,; + + my $defport = $1 || undef; + my $pnum = ($port =~ m,^(\d+)$,)[0]; + + @serv= getservbyname($port, $proto[0] || "") + if($port =~ m,\D,); + + $port = $pnum || $serv[2] || $defport || undef; + + $proto = (getprotobyname($serv[3]))[2] || undef + if @serv && !$proto; + } + + return ($addr || undef, + $port || undef, + $proto || undef + ); + } + + sub configure { + my($fh,$arg) = @_; + my($lport,$rport,$laddr,$raddr,$proto,$type); + + + ($laddr,$lport,$proto) = _sock_info($arg->{LocalAddr}, + $arg->{LocalPort}, + $arg->{Proto}); + + $laddr = defined $laddr ? inet_aton($laddr) + : INADDR_ANY; + + unless(exists $arg->{Listen}) { + ($raddr,$rport,$proto) = _sock_info($arg->{PeerAddr}, + $arg->{PeerPort}, + $proto); + } + + croak 'IO::Socket: Cannot determine protocol' + unless($proto); + + my $pname = (getprotobynumber($proto))[0]; + $type = $arg->{Type} || $socket_type{$pname}; + + $fh->socket(AF_INET, $type, $proto) or + return undef; + + $fh->bind($lport || 0, $laddr) or + return undef; + + if(exists $arg->{Listen}) { + $fh->listen($arg->{Listen} || 5) or + return undef; + } + else { + croak "IO::Socket: Cannot determine remote port" + unless($rport || $type == SOCK_DGRAM); + + if($type == SOCK_STREAM || defined $raddr) { + croak "IO::Socket: Bad peer address" + unless defined $raddr; + + $fh->connect($rport,inet_aton($raddr)) or + return undef; + } + } + + $fh; + } + + sub sockaddr { + @_ == 1 or croak 'usage: $fh->sockaddr()'; + my($fh) = @_; + (sockaddr_in($fh->sockname))[1]; + } + + sub sockport { + @_ == 1 or croak 'usage: $fh->sockport()'; + my($fh) = @_; + (sockaddr_in($fh->sockname))[0]; + } + + sub sockhost { + @_ == 1 or croak 'usage: $fh->sockhost()'; + my($fh) = @_; + inet_ntoa($fh->sockaddr); + } + + sub peeraddr { + @_ == 1 or croak 'usage: $fh->peeraddr()'; + my($fh) = @_; + (sockaddr_in($fh->peername))[1]; + } + + sub peerport { + @_ == 1 or croak 'usage: $fh->peerport()'; + my($fh) = @_; + (sockaddr_in($fh->peername))[0]; + } + + sub peerhost { + @_ == 1 or croak 'usage: $fh->peerhost()'; + my($fh) = @_; + inet_ntoa($fh->peeraddr); + } + + ## + ## AF_UNIX + ## + + package IO::Socket::UNIX; + + use strict; + use vars qw(@ISA $VERSION); + use Socket; + use Carp; + use Exporter; + + @ISA = qw(IO::Socket); + + =head2 IO::Socket::UNIX + + C provides a constructor to create an AF_UNIX domain socket + and some related methods. The constructor can take the following options + + Type Type of socket (eg SOCK_STREAM or SOCK_DGRAM) + Local Path to local fifo + Peer Path to peer fifo + Listen Create a listen socket + + =head2 METHODS + + =item hostpath() + + Returns the pathname to the fifo at the local end + + =item peerpath() + + Returns the pathanme to the fifo at the peer end + + =cut + + sub configure { + my($fh,$arg) = @_; + my($bport,$cport); + + my $type = $arg->{Type} || SOCK_STREAM; + + $fh->socket(AF_UNIX, $type, 0) or + return undef; + + if(exists $arg->{Local}) { + my $addr = sockaddr_un($arg->{Local}); + $fh->bind($addr) or + return undef; + } + if(exists $arg->{Listen}) { + $fh->listen($arg->{Listen} || 5) or + return undef; + } + elsif(exists $arg->{Peer}) { + my $addr = sockaddr_un($arg->{Peer}); + $fh->connect($addr) or + return undef; + } + + $fh; + } + + sub hostpath { + @_ == 1 or croak 'usage: $fh->hostpath()'; + (sockaddr_un($_[0]->hostname))[0]; + } + + sub peerpath { + @_ == 1 or croak 'usage: $fh->peerpath()'; + (sockaddr_un($_[0]->peername))[0]; + } + + =head1 AUTHOR + + Graham Barr + + =head1 REVISION + + $Revision: 1.8 $ + + The VERSION is derived from the revision turning each number after the + first dot into a 2 digit number so + + Revision 1.8 => VERSION 1.08 + Revision 1.2.3 => VERSION 1.0203 + + =head1 COPYRIGHT + + Copyright (c) 1995 Graham Barr. All rights reserved. This program is free + software; you can redistribute it and/or modify it under the same terms + as Perl itself. + + =cut + + 1; # Keep require happy #~ Quote string argument in example -- necessary if using strict subs diff -Pcr perl5_003/ext/NDBM_File/NDBM_File.pm perl5_003_01/ext/NDBM_File/NDBM_File.pm *** perl5_003/ext/NDBM_File/NDBM_File.pm Mon Jun 24 16:07:53 1996 --- perl5_003_01/ext/NDBM_File/NDBM_File.pm Mon Jul 15 13:35:34 1996 *************** *** 28,34 **** use NDBM_File; ! tie(%h,NDBM_File,'Op.dbmx', O_RDWR|O_CREAT, 0640); untie %h; --- 28,34 ---- use NDBM_File; ! tie(%h, 'NDBM_File', 'Op.dbmx', O_RDWR|O_CREAT, 0640); untie %h; #~ Quote string argument in example -- necessary if using strict subs diff -Pcr perl5_003/ext/ODBM_File/ODBM_File.pm perl5_003_01/ext/ODBM_File/ODBM_File.pm *** perl5_003/ext/ODBM_File/ODBM_File.pm Wed Feb 14 21:40:21 1996 --- perl5_003_01/ext/ODBM_File/ODBM_File.pm Mon Jul 15 13:35:38 1996 *************** *** 24,30 **** use ODBM_File; ! tie(%h,ODBM_File,'Op.dbmx', O_RDWR|O_CREAT, 0640); untie %h; --- 24,30 ---- use ODBM_File; ! tie(%h, 'ODBM_File', 'Op.dbmx', O_RDWR|O_CREAT, 0640); untie %h; #~ Add Opcode extension diff -Pcr perl5_003/ext/Opcode/Makefile.PL perl5_003_01/ext/Opcode/Makefile.PL *** perl5_003/ext/Opcode/Makefile.PL Wed Dec 31 19:00:00 1969 --- perl5_003_01/ext/Opcode/Makefile.PL Tue Jun 18 15:04:01 1996 *************** *** 0 **** --- 1,6 ---- + use ExtUtils::MakeMaker; + WriteMakefile( + NAME => 'Opcode', + VERSION_FROM => 'Opcode.pm', + MAN3PODS => ' ' + ); #~ Add Opcode extension diff -Pcr perl5_003/ext/Opcode/Opcode.pm perl5_003_01/ext/Opcode/Opcode.pm *** perl5_003/ext/Opcode/Opcode.pm Wed Dec 31 19:00:00 1969 --- perl5_003_01/ext/Opcode/Opcode.pm Tue Jun 18 14:59:41 1996 *************** *** 0 **** --- 1,564 ---- + package Opcode; + + require 5.002; + + use vars qw($VERSION @ISA @EXPORT_OK); + + $VERSION = "1.01"; + + use strict; + use Carp; + use Exporter (); + use DynaLoader (); + @ISA = qw(Exporter DynaLoader); + + BEGIN { + @EXPORT_OK = qw( + opset ops_to_opset + opset_to_ops opset_to_hex invert_opset + empty_opset full_opset + opdesc opcodes opmask define_optag + opmask_add verify_opset opdump + ); + } + + use subs @EXPORT_OK; + + bootstrap Opcode $VERSION; + + _init_optags(); + + + *ops_to_opset = \&opset; # alias for old name + + + sub opset_to_hex ($) { + return "(invalid opset)" unless verify_opset($_[0]); + unpack("h*",$_[0]); + } + + sub opdump (;$) { + my $pat = shift; + # handy utility: perl -MOpcode=opdump -e 'opdump File' + foreach(opset_to_ops(full_opset)) { + my $op = sprintf " %12s %s\n", $_, opdesc($_); + next if defined $pat and $op !~ m/$pat/i; + print $op; + } + } + + + + sub _init_optags { + my(%all, %seen); + @all{opset_to_ops(full_opset)} = (); # keys only + + local($/) = "\n=cut"; # skip to optags definition section + ; + $/ = "\n="; # now read in 'pod section' chunks + while() { + next unless m/^item\s+(:\w+)/; + my $tag = $1; + + # Split into lines, keep only indented lines + my @lines = grep { m/^\s/ } split(/\n/); + foreach (@lines) { s/--.*// } # delete comments + my @ops = map { split ' ' } @lines; # get op words + + foreach(@ops) { + warn "$tag - $_ already tagged in $seen{$_}\n" if $seen{$_}; + $seen{$_} = $tag; + delete $all{$_}; + } + # opset will croak on invalid names + define_optag($tag, opset(@ops)); + } + close(DATA); + warn "Untagged opnames: ".join(' ',keys %all)."\n" if %all; + } + + + 1; + + __DATA__ + + =head1 NAME + + Opcode - Disable named opcodes when compiling perl code + + =head1 SYNOPSIS + + use Opcode; + + + =head1 DESCRIPTION + + Perl code is always compiled into an internal format before execution. + + Evaluating perl code (e.g. via "eval" or "do 'file'") causes + the code to be compiled into an internal format and then, + provided there was no error in the compilation, executed. + The internal format is based on many distinct I. + + By default no opmask is in effect and any code can be compiled. + + The Opcode module allow you to define an I to be in + effect when perl I compiles any code. Attempting to compile code + which contains a masked opcode will cause the compilation to fail + with an error. The code will not be executed. + + =head1 NOTE + + The Opcode module is not usually used directly. See the ops pragma and + Safe modules for more typical uses. + + =head1 WARNING + + The authors make B, implied or otherwise, about the + suitability of this software for safety or security purposes. + + The authors shall not in any case be liable for special, incidental, + consequential, indirect or other similar damages arising from the use + of this software. + + Your mileage will vary. If in any doubt B. + + + =head1 Operator Names and Operator Lists + + The canonical list of operator names is the contents of the array + op_name defined and initialised in file F of the Perl + source distribution (and installed into the perl library). + + Each operator has both a terse name (its opname) and a more verbose or + recognisable descriptive name. The opdesc function can be used to + return a list of descriptions for a list of operators. + + Many of the functions and methods listed below take a list of + operators as parameters. Most operator lists can be made up of several + types of element. Each element can be one of + + =over 8 + + =item an operator name (opname) + + Operator names are typically small lowercase words like enterloop, + leaveloop, last, next, redo etc. Sometimes they are rather cryptic + like gv2cv, i_ncmp and ftsvtx. + + =item an operator tag name (optag) + + Operator tags can be used to refer to groups (or sets) of operators. + Tag names always being with a colon. The Opcode module defines several + optags and the user can define others using the define_optag function. + + =item a negated opname or optag + + An opname or optag can be prefixed with an exclamation mark, e.g., !mkdir. + Negating an opname or optag means remove the corresponding ops from the + accumulated set of ops at that point. + + =item an operator set (opset) + + An I as a binary string of approximately 43 bytes which holds a + set or zero or more operators. + + The opset and opset_to_ops functions can be used to convert from + a list of operators to an opset and I. + + Wherever a list of operators can be given you can use one or more opsets. + See also Manipulating Opsets below. + + =back + + + =head1 Opcode Functions + + The Opcode package contains functions for manipulating operator names + tags and sets. All are available for export by the package. + + =over 8 + + =item opcodes + + In a scalar context opcodes returns the number of opcodes in this + version of perl (around 340 for perl5.002). + + In a list context it returns a list of all the operator names. + (Not yet implemented, use @names = opset_to_ops(full_opset).) + + =item opset (OP, ...) + + Returns an opset containing the listed operators. + + =item opset_to_ops (OPSET) + + Returns a list of operator names corresponding to those operators in + the set. + + =item opset_to_hex (OPSET) + + Returns a string representation of an opset. Can be handy for debugging. + + =item full_opset + + Returns an opset which includes all operators. + + =item empty_opset + + Returns an opset which contains no operators. + + =item invert_opset (OPSET) + + Returns an opset which is the inverse set of the one supplied. + + =item verify_opset (OPSET, ...) + + Returns true if the supplied opset looks like a valid opset (is the + right length etc) otherwise it returns false. If an optional second + parameter is true then verify_opset will croak on an invalid opset + instead of returning false. + + Most of the other Opcode functions call verify_opset automatically + and will croak if given an invalid opset. + + =item define_optag (OPTAG, OPSET) + + Define OPTAG as a symbolic name for OPSET. Optag names always start + with a colon C<:>. + + The optag name used must not be defined already (define_optag will + croak if it is already defined). Optag names are global to the perl + process and optag definitions cannot be altered or deleted once + defined. + + It is strongly recommended that applications using Opcode should use a + leading capital letter on their tag names since lowercase names are + reserved for use by the Opcode module. If using Opcode within a module + you should prefix your tags names with the name of your module to + ensure uniqueness and thus avoid clashes with other modules. + + =item opmask_add (OPSET) + + Adds the supplied opset to the current opmask. Note that there is + currently I mechanism for unmasking ops once they have been masked. + This is intentional. + + =item opmask + + Returns an opset corresponding to the current opmask. + + =item opdesc (OP, ...) + + This takes a list of operator names and returns the corresponding list + of operator descriptions. + + =item opdump (PAT) + + Dumps to STDOUT a two column list of op names and op descriptions. + If an optional pattern is given then only lines which match the + (case insensitive) pattern will be output. + + It's designed to be used as a handy command line utility: + + perl -MOpcode=opdump -e opdump + perl -MOpcode=opdump -e 'opdump Eval' + + =back + + =head1 Manipulating Opsets + + Opsets may be manipulated using the perl bit vector operators & (and), | (or), + ^ (xor) and ~ (negate/invert). + + However you should never rely on the numerical position of any opcode + within the opset. In other words both sides of a bit vector operator + should be opsets returned from Opcode functions. + + Also, since the number of opcodes in your current version of perl might + not be an exact multiple of eight, there may be unused bits in the last + byte of an upset. This should not cause any problems (Opcode functions + ignore those extra bits) but it does mean that using the ~ operator + will typically not produce the same 'physical' opset 'string' as the + invert_opset function. + + + =head1 TO DO (maybe) + + $bool = opset_eq($opset1, $opset2) true if opsets are logically eqiv + + $yes = opset_can($opset, @ops) true if $opset has all @ops set + + @diff = opset_diff($opset1, $opset2) => ('foo', '!bar', ...) + + =cut + + # the =cut above is used by _init_optags() to get here quickly + + =head1 Predefined Opcode Tags + + =over 5 + + =item :base_core + + null stub scalar pushmark wantarray const defined undef + + rv2sv sassign + + rv2av aassign aelem aelemfast aslice av2arylen + + rv2hv helem hslice each values keys exists delete + + preinc i_preinc predec i_predec postinc i_postinc postdec i_postdec + int hex oct abs pow multiply i_multiply divide i_divide + modulo i_modulo add i_add subtract i_subtract + + left_shift right_shift bit_and bit_xor bit_or negate i_negate + not complement + + lt i_lt gt i_gt le i_le ge i_ge eq i_eq ne i_ne ncmp i_ncmp + slt sgt sle sge seq sne scmp + + substr vec stringify study pos length index rindex ord chr + + ucfirst lcfirst uc lc quotemeta trans chop schop chomp schomp + + match split + + list lslice splice push pop shift unshift reverse + + cond_expr flip flop andassign orassign and or xor + + warn die lineseq nextstate unstack scope enter leave + + rv2cv anoncode prototype + + entersub leavesub return method -- XXX loops via recursion? + + leaveeval -- needed for Safe to operate, is safe without entereval + + =item :base_mem + + These memory related ops are not included in :base_core because they + can easily be used to implement a resource attack (e.g., consume all + available memory). + + concat repeat join range + + anonlist anonhash + + Note that despite the existance of this optag a memory resource attack + may still be possible using only :base_core ops. + + Disabling these ops is a I heavy handed way to attempt to prevent + a memory resource attack. It's probable that a specific memory limit + mechanism will be added to perl in the near future. + + =item :base_loop + + These loop ops are not included in :base_core because they can easily be + used to implement a resource attack (e.g., consume all available CPU time). + + grepstart grepwhile + mapstart mapwhile + enteriter iter + enterloop leaveloop + last next redo + goto + + =item :base_io + + These ops enable I (rather than filename) based input and + output. These are safe on the assumption that only pre-existing + filehandles are available for use. To create new filehandles other ops + such as open would need to be enabled. + + readline rcatline getc read + + formline enterwrite leavewrite + + print sysread syswrite send recv eof tell seek + + readdir telldir seekdir rewinddir + + =item :base_orig + + These are a hotchpotch of opcodes still waiting to be considered + + gvsv gv gelem + + padsv padav padhv padany + + rv2gv refgen srefgen ref + + bless -- could be used to change ownership of objects (reblessing) + + glob + + pushre regcmaybe regcomp subst substcont + + sprintf prtf -- can core dump + + crypt + + tie untie + + dbmopen dbmclose + sselect select + pipe_op sockpair + + getppid getpgrp setpgrp getpriority setpriority localtime gmtime + + entertry leavetry -- can be used to 'hide' fatal errors + + =item :base_math + + These ops are not included in :base_core because of the risk of them being + used to generate floating point exceptions (which would have to be caught + using a $SIG{FPE} handler). + + atan2 sin cos exp log sqrt + + These ops are not included in :base_core because they have an effect + beyond the scope of the compartment. + + rand srand + + =item :default + + A handy tag name for a I default set of ops. (The current ops + allowed are unstable while development continues. It will change.) + + :base_core :base_mem :base_loop :base_io :base_orig + + If safety matters to you (and why else would you be using the Opcode module?) + then you should not rely on the definition of this, or indeed any other, optag! + + + =item :filesys_read + + stat lstat readlink + + ftatime ftblk ftchr ftctime ftdir fteexec fteowned fteread + ftewrite ftfile ftis ftlink ftmtime ftpipe ftrexec ftrowned + ftrread ftsgid ftsize ftsock ftsuid fttty ftzero ftrwrite ftsvtx + + fttext ftbinary + + fileno + + =item :sys_db + + ghbyname ghbyaddr ghostent shostent ehostent -- hosts + gnbyname gnbyaddr gnetent snetent enetent -- networks + gpbyname gpbynumber gprotoent sprotoent eprotoent -- protocols + gsbyname gsbyport gservent sservent eservent -- services + + gpwnam gpwuid gpwent spwent epwent getlogin -- users + ggrnam ggrgid ggrent sgrent egrent -- groups + + =item :browse + + A handy tag name for a I default set of ops beyond the + :default optag. Like :default (and indeed all the other optags) its + current definition is unstable while development continues. It will change. + + The :browse tag represents the next step beyond :default. It it a + superset of the :default ops and adds :filesys_read the :sys_db. + The intent being that scripts can access more (possibly sensitive) + information about your system but not be able to change it. + + :default :filesys_read :sys_db + + =item :filesys_open + + sysopen open close + umask binmode + + open_dir closedir -- other dir ops are in :base_io + + =item :filesys_write + + link unlink rename symlink truncate + + mkdir rmdir + + utime chmod chown + + fcntl -- not strictly filesys related, but possibly as dangerous? + + =item :subprocess + + backtick system + + fork + + wait waitpid + + =item :ownprocess + + exec exit kill + + time tms -- could be used for timing attacks (paranoid?) + + =item :others + + This tag holds groups of assorted specialist opcodes that don't warrant + having optags defined for them. + + SystemV Interprocess Communications: + + msgctl msgget msgrcv msgsnd + + semctl semget semop + + shmctl shmget shmread shmwrite + + =item :still_to_be_decided + + chdir + flock ioctl + + socket getpeername ssockopt + bind connect listen accept shutdown gsockopt getsockname + + sleep alarm -- changes global timer state and signal handling + sort -- assorted problems including core dumps + tied -- can be used to access object implementing a tie + pack unpack -- can be used to create/use memory pointers + + entereval -- can be used to hide code from initial compile + require dofile + + caller -- get info about calling environment and args + + reset + + dbstate -- perl -d version of nextstate(ment) opcode + + =item :dangerous + + This tag is simply a bucket for opcodes that are unlikely to be used via + a tag name but need to be tagged for completness and documentation. + + syscall dump chroot + + + =back + + =head1 SEE ALSO + + ops(3) -- perl pragma interface to Opcode module. + + Safe(3) -- Opcode and namespace limited execution compartments + + =head1 AUTHORS + + Originally designed and implemented by Malcolm Beattie, + mbeattie@sable.ox.ac.uk as part of Safe version 1. + + Split out from Safe module version 1, named opcode tags and other + changes added by Tim Bunce . + + =cut + #~ Add Opcode extension diff -Pcr perl5_003/ext/Opcode/Opcode.xs perl5_003_01/ext/Opcode/Opcode.xs *** perl5_003/ext/Opcode/Opcode.xs Wed Dec 31 19:00:00 1969 --- perl5_003_01/ext/Opcode/Opcode.xs Tue Jun 18 15:12:05 1996 *************** *** 0 **** --- 1,471 ---- + #include "EXTERN.h" + #include "perl.h" + #include "XSUB.h" + + /* maxo shouldn't differ from MAXO but leave room anyway (see BOOT:) */ + #define OP_MASK_BUF_SIZE (MAXO + 100) + + static HV *op_named_bits; /* cache shared for whole process */ + static SV *opset_all; /* mask with all bits set */ + static IV opset_len; /* length of opmasks in bytes */ + static int opcode_debug = 0; + + static SV *new_opset _((SV *old_opset)); + static int verify_opset _((SV *opset, int fatal)); + static void set_opset_bits _((char *bitmap, SV *bitspec, int on, char *opname)); + static void put_op_bitspec _((char *optag, STRLEN len, SV *opset)); + static SV *get_op_bitspec _((char *opname, STRLEN len, int fatal)); + + + /* Initialise our private op_named_bits HV. + * It is first loaded with the name and number of each perl operator. + * Then the builtin tags :none and :all are added. + * Opcode.pm loads the standard optags from __DATA__ + */ + + static void + op_names_init() + { + int i; + STRLEN len; + char *opname; + char *bitmap; + + op_named_bits = newHV(); + for(i=0; i < maxo; ++i) { + hv_store(op_named_bits, op_name[i],strlen(op_name[i]), + Sv=newSViv(i), 0); + SvREADONLY_on(Sv); + } + + put_op_bitspec(":none",0, sv_2mortal(new_opset(Nullsv))); + + opset_all = new_opset(Nullsv); + bitmap = SvPV(opset_all, len); + i = len-1; /* deal with last byte specially, see below */ + while(i-- > 0) + bitmap[i] = 0xFF; + /* Take care to set the right number of bits in the last byte */ + bitmap[len-1] = ~(~0 << (maxo & 0x07)); + put_op_bitspec(":all",0, opset_all); /* don't mortalise */ + } + + + /* Store a new tag definition. Always a mask. + * The tag must not already be defined. + * SV *mask is copied not referenced. + */ + + static void + put_op_bitspec(optag, len, mask) + char *optag; + STRLEN len; + SV *mask; + { + SV **svp; + verify_opset(mask,1); + if (!len) + len = strlen(optag); + svp = hv_fetch(op_named_bits, optag, len, 1); + if (SvOK(*svp)) + croak("Opcode tag \"%s\" already defined", optag); + sv_setsv(*svp, mask); + SvREADONLY_on(*svp); + } + + + + /* Fetch a 'bits' entry for an opname or optag (IV/PV). + * Note that we return the actual entry for speed. + * Always sv_mortalcopy() if returing it to user code. + */ + + static SV * + get_op_bitspec(opname, len, fatal) + char *opname; + STRLEN len; + int fatal; + { + SV **svp; + if (!len) + len = strlen(opname); + svp = hv_fetch(op_named_bits, opname, len, 0); + if (!svp || !SvOK(*svp)) { + if (!fatal) + return Nullsv; + if (*opname == ':') + croak("Unknown operator tag \"%s\"", opname); + if (*opname == '!') /* XXX here later, or elsewhere? */ + croak("Can't negate operators here (\"%s\")", opname); + if (isALPHA(*opname)) + croak("Unknown operator name \"%s\"", opname); + croak("Unknown operator prefix \"%s\"", opname); + } + return *svp; + } + + + + static SV * + new_opset(old_opset) + SV *old_opset; + { + SV *opset; + if (old_opset) { + verify_opset(old_opset,1); + opset = newSVsv(old_opset); + } + else { + opset = newSV(opset_len); + Zero(SvPVX(opset), opset_len, char); + SvCUR_set(opset, opset_len); + (void)SvPOK_only(opset); + } + /* not mortalised here */ + return opset; + } + + + static int + verify_opset(opset, fatal) + SV *opset; + int fatal; + { + char *err = Nullch; + if (!SvOK(opset)) err = "undefined"; + else if (!SvPOK(opset)) err = "wrong type"; + else if (SvCUR(opset) != opset_len) err = "wrong size"; + if (err && fatal) { + croak("Invalid opset: %s", err); + } + return !err; + } + + + static void + set_opset_bits(bitmap, bitspec, on, opname) + char *bitmap; + SV *bitspec; + int on; + char *opname; + { + if (SvIOK(bitspec)) { + int myopcode = SvIV(bitspec); + int offset = myopcode >> 3; + int bit = myopcode & 0x07; + if (myopcode >= maxo || myopcode < 0) + croak("panic: opcode \"%s\" value %d is invalid", opname, myopcode); + if (opcode_debug >= 2) + warn("set_opset_bits bit %2d (off=%d, bit=%d) %s on\n", + myopcode, offset, bit, opname, (on)?"on":"off"); + if (on) + bitmap[offset] |= 1 << bit; + else + bitmap[offset] &= ~(1 << bit); + } + else if (SvPOK(bitspec) && SvCUR(bitspec) == opset_len) { + + STRLEN len; + char *specbits = SvPV(bitspec, len); + if (opcode_debug >= 2) + warn("set_opset_bits opset %s %s\n", opname, (on)?"on":"off"); + if (on) + while(len-- > 0) bitmap[len] |= specbits[len]; + else + while(len-- > 0) bitmap[len] &= ~specbits[len]; + } + else + croak("panic: invalid bitspec for \"%s\" (type %d)", + opname, SvTYPE(bitspec)); + } + + + static void + opmask_add(opset) /* THE ONLY FUNCTION TO EDIT op_mask ITSELF */ + SV *opset; + { + int i,j; + char *bitmask; + STRLEN len; + int myopcode = 0; + + verify_opset(opset,1); /* croaks on bad opset */ + + if (!op_mask) /* caller must ensure op_mask exists */ + croak("Can't add to uninitialised op_mask"); + + /* OPCODES ALREADY MASKED ARE NEVER UNMASKED. See opmask_addlocal() */ + + bitmask = SvPV(opset, len); + for (i=0; i < opset_len; i++) { + U16 bits = bitmask[i]; + if (!bits) { /* optimise for sparse masks */ + myopcode += 8; + continue; + } + for (j=0; j < 8 && myopcode < maxo; ) + op_mask[myopcode++] |= bits & (1 << j++); + } + } + + static void + opmask_addlocal(opset, op_mask_buf) /* Localise op_mask then opmask_add() */ + SV *opset; + char *op_mask_buf; + { + char *orig_op_mask = op_mask; + SAVEPPTR(op_mask); + if (opcode_debug >= 2) + SAVEDESTRUCTOR((void(*)_((void*)))warn,"op_mask restored"); + op_mask = &op_mask_buf[0]; + if (orig_op_mask) + Copy(orig_op_mask, op_mask, maxo, char); + else + Zero(op_mask, maxo, char); + opmask_add(opset); + } + + + + MODULE = Opcode PACKAGE = Opcode + + PROTOTYPES: ENABLE + + BOOT: + assert(maxo < OP_MASK_BUF_SIZE); + opset_len = (maxo / 8) + 1; + if (opcode_debug >= 1) + warn("opset_len %d\n", opset_len); + op_names_init(); + + + void + _safe_call_sv(package, mask, codesv) + char * package + SV * mask + SV * codesv + PPCODE: + char op_mask_buf[OP_MASK_BUF_SIZE]; + GV *gv; + + ENTER; + + opmask_addlocal(mask, op_mask_buf); + + save_aptr(&endav); + endav = (AV*)sv_2mortal((SV*)newAV()); /* ignore END blocks for now */ + + save_hptr(&defstash); /* save current default stack */ + /* the assignment to global defstash changes our sense of 'main' */ + defstash = gv_stashpv(package, GV_ADDWARN); /* should exist already */ + + /* defstash must itself contain a main:: so we'll add that now */ + /* take care with the ref counts (was cause of long standing bug) */ + /* XXX I'm still not sure if this is right, GV_ADDWARN should warn! */ + gv = gv_fetchpv("main::", GV_ADDWARN, SVt_PVHV); + sv_free((SV*)GvHV(gv)); + GvHV(gv) = (HV*)SvREFCNT_inc(defstash); + + PUSHMARK(sp); + perl_call_sv(codesv, GIMME|G_EVAL|G_KEEPERR); /* use callers context */ + SPAGAIN; /* for the PUTBACK added by xsubpp */ + LEAVE; + + + int + verify_opset(opset, fatal = 0) + SV *opset + int fatal + + + void + invert_opset(opset) + SV *opset + CODE: + { + char *bitmap; + STRLEN len = opset_len; + opset = new_opset(opset); /* verify and clone opset */ + bitmap = SvPVX(opset); + while(len-- > 0) + bitmap[len] = ~bitmap[len]; + /* take care of extra bits beyond maxo in last byte */ + bitmap[opset_len-1] &= ~(0xFF << (maxo & 0x0F)); + } + ST(0) = opset; + + + void + opset_to_ops(opset, desc = 0) + SV *opset + int desc + PPCODE: + { + STRLEN len; + int i, j, myopcode; + char *bitmap = SvPV(opset, len); + char **names = (desc) ? op_desc : op_name; + verify_opset(opset,1); + for (myopcode=0, i=0; i < opset_len; i++) { + U16 bits = bitmap[i]; + for (j=0; j < 8 && myopcode < maxo; j++, myopcode++) { + if ( bits & (1 << j) ) + XPUSHs(sv_2mortal(newSVpv(names[myopcode], 0))); + } + } + } + + + void + opset(...) + CODE: + int i, j; + SV *bitspec, *opset; + char *bitmap; + STRLEN len, on; + opset = new_opset(Nullsv); + bitmap = SvPVX(opset); + for (i = 0; i < items; i++) { + char *opname; + on = 1; + if (verify_opset(ST(i),0)) { + opname = "(opset)"; + bitspec = ST(i); + } + else { + opname = SvPV(ST(i), len); + if (*opname == '!') { on=0; ++opname;--len; } + bitspec = get_op_bitspec(opname, len, 1); + } + set_opset_bits(bitmap, bitspec, on, opname); + } + ST(0) = opset; + + + #define PERMITING (ix == 0 || ix == 1) + #define ONLY_THESE (ix == 0 || ix == 2) + + void + permit_only(safe, ...) + SV *safe + ALIAS: + permit = 1 + deny_only = 2 + deny = 3 + CODE: + int i, on; + SV *bitspec, *mask; + char *bitmap, *opname; + STRLEN len; + + if (!SvROK(safe) || !SvOBJECT(SvRV(safe)) || SvTYPE(SvRV(safe))!=SVt_PVHV) + croak("Not a Safe object"); + mask = *hv_fetch((HV*)SvRV(safe), "Mask",4, 1); + if (ONLY_THESE) /* *_only = new mask, else edit current */ + sv_setsv(mask, new_opset(PERMITING ? opset_all : Nullsv)); + else verify_opset(mask,1); /* croaks */ + bitmap = SvPVX(mask); + for (i = 1; i < items; i++) { + on = PERMITING ? 0 : 1; /* deny = mask bit on */ + if (verify_opset(ST(i),0)) { /* it's a valid mask */ + opname = "(opset)"; + bitspec = ST(i); + } + else { /* it's an opname/optag */ + opname = SvPV(ST(i), len); + /* invert if op has ! prefix (only one allowed) */ + if (*opname == '!') { on = !on; ++opname; --len; } + bitspec = get_op_bitspec(opname, len, 1); /* croaks */ + } + set_opset_bits(bitmap, bitspec, on, opname); + } + ST(0) = &sv_yes; + + + + void + opdesc(...) + PPCODE: + int i, myopcode; + STRLEN len; + SV **args; + /* copy args to a scratch area since we may push output values onto */ + /* the stack faster than we read values off it if masks are used. */ + args = (SV**)SvPVX(sv_2mortal(newSVpv((char*)&ST(0), items*sizeof(SV*)))); + for (i = 0; i < items; i++) { + char *opname = SvPV(args[i], len); + SV *bitspec = get_op_bitspec(opname, len, 1); + if (SvIOK(bitspec)) { + myopcode = SvIV(bitspec); + if (myopcode < 0 || myopcode >= maxo) + croak("panic: opcode %d (%s) out of range",myopcode,opname); + XPUSHs(sv_2mortal(newSVpv(op_desc[myopcode], 0))); + } + else if (SvPOK(bitspec) && SvCUR(bitspec) == opset_len) { + int b, j; + char *bitmap = SvPV(bitspec,na); + myopcode = 0; + for (b=0; b < opset_len; b++) { + U16 bits = bitmap[b]; + for (j=0; j < 8 && myopcode < maxo; j++, myopcode++) + if (bits & (1 << j)) + XPUSHs(sv_2mortal(newSVpv(op_desc[myopcode], 0))); + } + } + else + croak("panic: invalid bitspec for \"%s\" (type %d)", + opname, SvTYPE(bitspec)); + } + + + void + define_optag(optagsv, mask) + SV *optagsv + SV *mask + CODE: + STRLEN len; + char *optag = SvPV(optagsv, len); + put_op_bitspec(optag, len, mask); /* croaks */ + ST(0) = &sv_yes; + + + void + empty_opset() + CODE: + ST(0) = sv_2mortal(new_opset(Nullsv)); + + void + full_opset() + CODE: + ST(0) = sv_2mortal(new_opset(opset_all)); + + void + opmask_add(opset) + SV *opset + PREINIT: + if (!op_mask) + Newz(0, op_mask, maxo, char); + + void + opcodes() + PPCODE: + if (GIMME == G_ARRAY) { + croak("opcodes in list context not yet implemented"); /* XXX */ + } + else { + XPUSHs(sv_2mortal(newSViv(maxo))); + } + + void + opmask() + CODE: + ST(0) = sv_2mortal(new_opset(Nullsv)); + if (op_mask) { + char *bitmap = SvPVX(ST(0)); + int myopcode; + for(myopcode=0; myopcode < maxo; ++myopcode) { + if (op_mask[myopcode]) + bitmap[myopcode >> 3] |= 1 << (myopcode & 0x07); + } + } + #~ New Opcode extension subsumes Safe diff -Pcr perl5_003/ext/Opcode/Safe.pm perl5_003_01/ext/Opcode/Safe.pm *** perl5_003/ext/Opcode/Safe.pm Wed Dec 31 19:00:00 1969 --- perl5_003_01/ext/Opcode/Safe.pm Tue Jun 18 15:18:18 1996 *************** *** 0 **** --- 1,555 ---- + package Safe; + + require 5.002; + + use strict; + use Carp; + + use vars qw($VERSION); + + $VERSION = "2.06"; + + use Opcode 1.01, qw( + opset opset_to_ops opmask_add + empty_opset full_opset invert_opset verify_opset + opdesc opcodes opmask define_optag opset_to_hex + ); + + *ops_to_opset = \&opset; # Temporary alias for old Penguins + + + my $default_root = 0; + my $default_share = ['*_']; #, '*main::']; + + sub new { + my($class, $root, $mask) = @_; + my $obj = {}; + bless $obj, $class; + + if (defined($root)) { + croak "Can't use \"$root\" as root name" + if $root =~ /^main\b/ or $root !~ /^\w[:\w]*$/; + $obj->{Root} = $root; + $obj->{Erase} = 0; + } + else { + $obj->{Root} = "Safe::Root".$default_root++; + $obj->{Erase} = 1; + } + + # use permit/deny methods instead till interface issues resolved + # XXX perhaps new Safe 'Root', mask => $mask, foo => bar, ...; + croak "Mask parameter to new no longer supported" if defined $mask; + $obj->permit_only(':default'); + + # We must share $_ and @_ with the compartment or else ops such + # as split, length and so on won't default to $_ properly, nor + # will passing argument to subroutines work (via @_). In fact, + # for reasons I don't completely understand, we need to share + # the whole glob *_ rather than $_ and @_ separately, otherwise + # @_ in non default packages within the compartment don't work. + $obj->share_from('main', $default_share); + return $obj; + } + + sub DESTROY { + my $obj = shift; + $obj->erase if $obj->{Erase}; + } + + sub erase { + my $obj= shift; + my $pkg = $obj->root(); + my ($stem, $leaf); + + no strict 'refs'; + $pkg = "main::$pkg\::"; # expand to full symbol table name + ($stem, $leaf) = $pkg =~ m/(.*::)(\w+::)$/; + + # The 'my $foo' is needed! Without it you get an + # 'Attempt to free unreferenced scalar' warning! + my $stem_symtab = *{$stem}{HASH}; + + #warn "erase($pkg) stem=$stem, leaf=$leaf"; + #warn " stem_symtab hash ".scalar(%$stem_symtab)."\n"; + # ", join(', ', %$stem_symtab),"\n"; + + delete $stem_symtab->{$leaf}; + + # my $leaf_glob = $stem_symtab->{$leaf}; + # my $leaf_symtab = *{$leaf_glob}{HASH}; + # warn " leaf_symtab ", join(', ', %$leaf_symtab),"\n"; + # %$leaf_symtab = (); + #delete $leaf_symtab->{'__ANON__'}; + #delete $leaf_symtab->{'foo'}; + #delete $leaf_symtab->{'main::'}; + # my $foo = undef ${"$stem\::"}{"$leaf\::"}; + + $obj->share_from('main', $default_share); + 1; + } + + + sub reinit { + my $obj= shift; + $obj->erase; + $obj->share_redo; + } + + sub root { + my $obj = shift; + croak("Safe root method now read-only") if @_; + return $obj->{Root}; + } + + + sub mask { + my $obj = shift; + return $obj->{Mask} unless @_; + $obj->deny_only(@_); + } + + # v1 compatibility methods + sub trap { shift->deny(@_) } + sub untrap { shift->permit(@_) } + + sub deny { + my $obj = shift; + $obj->{Mask} |= opset(@_); + } + sub deny_only { + my $obj = shift; + $obj->{Mask} = opset(@_); + } + + sub permit { + my $obj = shift; + # XXX needs testing + $obj->{Mask} &= invert_opset opset(@_); + } + sub permit_only { + my $obj = shift; + $obj->{Mask} = invert_opset opset(@_); + } + + + sub dump_mask { + my $obj = shift; + print opset_to_hex($obj->{Mask}),"\n"; + } + + + + sub share { + my($obj, @vars) = @_; + $obj->share_from(scalar(caller), \@vars); + } + + sub share_from { + my $obj = shift; + my $pkg = shift; + my $vars = shift; + my $no_record = shift || 0; + my $root = $obj->root(); + my ($var, $arg); + croak("vars not an array ref") unless ref $vars eq 'ARRAY'; + no strict 'refs'; + # Check that 'from' package actually exists + croak("Package \"$pkg\" does not exist") + unless keys %{"$pkg\::"}; + foreach $arg (@$vars) { + # catch some $safe->share($var) errors: + croak("'$arg' not a valid symbol table name") + unless $arg =~ /^[\$\@%*&]?\w[\w:]*$/ + or $arg =~ /^\$\W$/; + ($var = $arg) =~ s/^(\W)//; # get type char + # warn "share_from $pkg $1 $var"; + *{$root."::$var"} = ($1 eq '$') ? \${$pkg."::$var"} + : ($1 eq '@') ? \@{$pkg."::$var"} + : ($1 eq '%') ? \%{$pkg."::$var"} + : ($1 eq '*') ? *{$pkg."::$var"} + : ($1 eq '&') ? \&{$pkg."::$var"} + : (!$1) ? \&{$pkg."::$var"} + : croak(qq(Can't share "$1$var" of unknown type)); + } + $obj->share_record($pkg, $vars) unless $no_record or !$vars; + } + + sub share_record { + my $obj = shift; + my $pkg = shift; + my $vars = shift; + my $shares = \%{$obj->{Shares} ||= {}}; + # Record shares using keys of $obj->{Shares}. See reinit. + @{$shares}{@$vars} = ($pkg) x @$vars if @$vars; + } + sub share_redo { + my $obj = shift; + my $shares = \%{$obj->{Shares} ||= {}}; + my($var, $pkg); + while(($var, $pkg) = each %$shares) { + # warn "share_redo $pkg\:: $var"; + $obj->share_from($pkg, [ $var ], 1); + } + } + sub share_forget { + delete shift->{Shares}; + } + + sub varglob { + my ($obj, $var) = @_; + no strict 'refs'; + return *{$obj->root()."::$var"}; + } + + + sub reval { + my ($obj, $expr, $strict) = @_; + my $root = $obj->{Root}; + + # Create anon sub ref in root of compartment. + # Uses a closure (on $expr) to pass in the code to be executed. + # (eval on one line to keep line numbers as expected by caller) + my $evalcode = sprintf('package %s; sub { eval $expr; }', $root); + my $evalsub; + + if ($strict) { use strict; $evalsub = eval $evalcode; } + else { no strict; $evalsub = eval $evalcode; } + + return Opcode::_safe_call_sv($root, $obj->{Mask}, $evalsub); + } + + sub rdo { + my ($obj, $file) = @_; + my $root = $obj->{Root}; + + my $evalsub = eval + sprintf('package %s; sub { do $file }', $root); + return Opcode::_safe_call_sv($root, $obj->{Mask}, $evalsub); + } + + + 1; + + __DATA__ + + =head1 NAME + + Safe - Compile and execute code in restricted compartments + + =head1 SYNOPSIS + + use Safe; + + $compartment = new Safe; + + $compartment->permit(qw(time sort :browse)); + + $result = $compartment->reval($unsafe_code); + + =head1 DESCRIPTION + + The Safe extension module allows the creation of compartments + in which perl code can be evaluated. Each compartment has + + =over 8 + + =item a new namespace + + The "root" of the namespace (i.e. "main::") is changed to a + different package and code evaluated in the compartment cannot + refer to variables outside this namespace, even with run-time + glob lookups and other tricks. + + Code which is compiled outside the compartment can choose to place + variables into (or I variables with) the compartment's namespace + and only that data will be visible to code evaluated in the + compartment. + + By default, the only variables shared with compartments are the + "underscore" variables $_ and @_ (and, technically, the less frequently + used %_, the _ filehandle and so on). This is because otherwise perl + operators which default to $_ will not work and neither will the + assignment of arguments to @_ on subroutine entry. + + =item an operator mask + + Each compartment has an associated "operator mask". Recall that + perl code is compiled into an internal format before execution. + Evaluating perl code (e.g. via "eval" or "do 'file'") causes + the code to be compiled into an internal format and then, + provided there was no error in the compilation, executed. + Code evaulated in a compartment compiles subject to the + compartment's operator mask. Attempting to evaulate code in a + compartment which contains a masked operator will cause the + compilation to fail with an error. The code will not be executed. + + The default operator mask for a newly created compartment is + the ':default' optag. + + It is important that you read the L module documentation + for more information. Especially for details definitions of opnames, + optags and opsets. + + Since it is only at the compilation stage that the operator mask + applies, controlled access to potentially unsafe operations can + be achieved by having a handle to a wrapper subroutine (written + outside the compartment) placed into the compartment. For example, + + $cpt = new Safe; + sub wrapper { + # vet arguments and perform potentially unsafe operations + } + $cpt->share('&wrapper'); + + =back + + + =head1 WARNING + + The authors make B, implied or otherwise, about the + suitability of this software for safety or security purposes. + + The authors shall not in any case be liable for special, incidental, + consequential, indirect or other similar damages arising from the use + of this software. + + Your mileage will vary. If in any doubt B. + + + =head2 RECENT CHANGES + + The interface to the Safe module has changed quite dramatically since + version 1 (as supplied with Perl5.002). Study these pages carefully if + you have code written to use Safe version 1 because you will need to + makes changes. + + + =head2 Methods in class Safe + + To create a new compartment, use + + $cpt = new Safe; + + Optional argument is (NAMESPACE), where NAMESPACE is the root namespace + to use for the compartment (defaults to "Safe::Root0", incremented for + each new compartment). + + Note that version 1.00 of the Safe module supported a second optional + parameter, MASK. That functionality has been withdrawn pending deeper + consideration. Use the permit and deny methods described below. + + The following methods can then be used on the compartment + object returned by the above constructor. The object argument + is implicit in each case. + + + =over 8 + + =item permit (OP, ...) + + Permit the listed operators to be used when compiling code in the + compartment (in I to any operators already permitted). + + =item permit_only (OP, ...) + + Permit I the listed operators to be used when compiling code in + the compartment (I other operators are permitted). + + =item deny (OP, ...) + + Deny the listed operators from being used when compiling code in the + compartment (other operators may still be permitted). + + =item deny_only (OP, ...) + + Deny I the listed operators from being used when compiling code + in the compartment (I other operators will be permitted). + + =item trap (OP, ...) + + =item untrap (OP, ...) + + The trap and untrap methods are synonyms for deny and permit + respectfully. + + =item share (NAME, ...) + + This shares the variable(s) in the argument list with the compartment. + This is almost identical to exporting variables using the L + module. + + Each NAME must be the B of a variable, typically with the leading + type identifier included. A bareword is treated as a function name. + + Examples of legal names are '$foo' for a scalar, '@foo' for an + array, '%foo' for a hash, '&foo' or 'foo' for a subroutine and '*foo' + for a glob (i.e. all symbol table entries associated with "foo", + including scalar, array, hash, sub and filehandle). + + Each NAME is assumed to be in the calling package. See share_from + for an alternative method (which share uses). + + =item share_from (PACKAGE, ARRAYREF) + + This method is similar to share() but allows you to explicitly name the + package that symbols should be shared from. The symbol names (including + type characters) are supplied as an array reference. + + $safe->share_from('main', [ '$foo', '%bar', 'func' ]); + + + =item varglob (VARNAME) + + This returns a glob reference for the symbol table entry of VARNAME in + the package of the compartment. VARNAME must be the B of a + variable without any leading type marker. For example, + + $cpt = new Safe 'Root'; + $Root::foo = "Hello world"; + # Equivalent version which doesn't need to know $cpt's package name: + ${$cpt->varglob('foo')} = "Hello world"; + + + =item reval (STRING) + + This evaluates STRING as perl code inside the compartment. + + The code can only see the compartment's namespace (as returned by the + B method). The compartment's root package appears to be the + C package to the code inside the compartment. + + Any attempt by the code in STRING to use an operator which is not permitted + by the compartment will cause an error (at run-time of the main program + but at compile-time for the code in STRING). The error is of the form + "%s trapped by operation mask operation...". + + If an operation is trapped in this way, then the code in STRING will + not be executed. If such a trapped operation occurs or any other + compile-time or return error, then $@ is set to the error message, just + as with an eval(). + + If there is no error, then the method returns the value of the last + expression evaluated, or a return statement may be used, just as with + subroutines and B. The context (list or scalar) is determined + by the caller as usual. + + This behaviour differs from the beta distribution of the Safe extension + where earlier versions of perl made it hard to mimic the return + behaviour of the eval() command and the context was always scalar. + + Some points to note: + + If the entereval op is permitted then the code can use eval "..." to + 'hide' code which might use denied ops. This is not a major problem + since when the code tries to execute the eval it will fail because the + opmask is still in effect. However this technique would allow clever, + and possibly harmful, code to 'probe' the boundaries of what is + possible. + + Any string eval which is executed by code executing in a compartment, + or by code called from code executing in a compartment, will be eval'd + in the namespace of the compartment. This is potentially a serious + problem. + + Consider a function foo() in package pkg compiled outside a compartment + but shared with it. Assume the compartment has a root package called + 'Root'. If foo() contains an eval statement like eval '$baz = 1' then, + normally, $pkg::foo will be set to 1. If foo() is called from the + compartment (by whatever means) then instead of setting $pkg::foo, the + eval will actually set $Root::pkg::foo. + + This can easily be demonstrated by using a module, such as the Socket + module, which uses eval "..." as part of an AUTOLOAD function. You can + 'use' the module outside the compartment and share an (autoloaded) + function with the compartment. If an autoload is triggered by code in + the compartment, or by any code anywhere that is called by any means + from the compartment, then the eval in the Socket module's AUTOLOAD + function happens in the namespace of the compartment. Any variables + created or used by the eval'd code are now under the control of + the code in the compartment. + + A similar effect applies to I runtime symbol lookups in code + called from a compartment but not compiled within it. + + + + =item rdo (FILENAME) + + This evaluates the contents of file FILENAME inside the compartment. + See above documentation on the B method for further details. + + =item root (NAMESPACE) + + This method returns the name of the package that is the root of the + compartment's namespace. + + Note that this behaviour differs from version 1.00 of the Safe module + where the root module could be used to change the namespace. That + functionality has been withdrawn pending deeper consideration. + + =item mask (MASK) + + This is a get-or-set method for the compartment's operator mask. + + With no MASK argument present, it returns the current operator mask of + the compartment. + + With the MASK argument present, it sets the operator mask for the + compartment (equivalent to calling the deny_only method). + + =back + + + =head2 Some Safety Issues + + This section is currently just an outline of some of the things code in + a compartment might do (intentionally or unintentionally) which can + have an effect outside the compartment. + + =over 8 + + =item Memory + + Consuming all (or nearly all) available memory. + + =item CPU + + Causing infinite loops etc. + + =item Snooping + + Copying private information out of your system. Even something as + simple as your user name is of value to others. Much useful information + could be gleaned from your environment variables for example. + + =item Signals + + Causing signals (especially SIGFPE and SIGALARM) to affect your process. + + Setting up a signal handler will need to be carefully considered + and controlled. What mask is in effect when a signal handler + gets called? If a user can get an imported function to get an + exception and call the user's signal handler, does that user's + restricted mask get re-instated before the handler is called? + Does an imported handler get called with its original mask or + the user's one? + + =item State Changes + + Ops such as chdir obviously effect the process as a whole and not just + the code in the compartment. Ops such as rand and srand have a similar + but more subtle effect. + + =back + + =head2 AUTHOR + + Originally designed and implemented by Malcolm Beattie, + mbeattie@sable.ox.ac.uk. + + Reworked to use the Opcode module and other changes added by Tim Bunce + . + + =cut + #~ Add Opcode extension diff -Pcr perl5_003/ext/Opcode/ops.pm perl5_003_01/ext/Opcode/ops.pm *** perl5_003/ext/Opcode/ops.pm Wed Dec 31 19:00:00 1969 --- perl5_003_01/ext/Opcode/ops.pm Tue Jun 18 15:07:53 1996 *************** *** 0 **** --- 1,45 ---- + package ops; + + use Opcode qw(opmask_add opset invert_opset); + + sub import { + shift; + # Not that unimport is the prefered form since import's don't + # accumulate well owing to the 'only ever add opmask' rule. + # E.g., perl -Mops=:set1 -Mops=:setb is unlikely to do as expected. + opmask_add(invert_opset opset(@_)); + } + + sub unimport { + shift; + opmask_add(opset(@_)); + } + + 1; + + __END__ + + =head1 NAME + + ops - Perl pragma to restrict unsafe operations when compiling + + =head1 SYNOPSIS + + perl -Mops=:default ... # only allow reasonably safe operations + + perl -M-ops=system ... # disable the 'system' opcode + + =head1 DESCRIPTION + + Since the ops pragma currently has an irreversable global effect, it is + only of significant practical use with the C<-M> option on the command line. + + See the L module for information about opcodes, optags, opmasks + and important information about safety. + + =head1 SEE ALSO + + Opcode(3), Safe(3), perlrun(3) + + =cut + #~ Correct order of arguments in setcc documentation diff -Pcr perl5_003/ext/POSIX/POSIX.pod perl5_003_01/ext/POSIX/POSIX.pod *** perl5_003/ext/POSIX/POSIX.pod Mon Jan 29 19:24:16 1996 --- perl5_003_01/ext/POSIX/POSIX.pod Tue Jun 18 20:28:03 1996 *************** *** 1393,1399 **** Set a value in the c_cc field of a termios object. The c_cc field is an array so an index must be specified. ! $termios->setcc( 1, &POSIX::VEOF ); =item setcflag --- 1393,1399 ---- Set a value in the c_cc field of a termios object. The c_cc field is an array so an index must be specified. ! $termios->setcc( &POSIX::VEOF, 1 ); =item setcflag #~ Quote string argument in example -- necessary if using strict subs diff -Pcr perl5_003/ext/SDBM_File/SDBM_File.pm perl5_003_01/ext/SDBM_File/SDBM_File.pm *** perl5_003/ext/SDBM_File/SDBM_File.pm Wed Feb 14 21:40:28 1996 --- perl5_003_01/ext/SDBM_File/SDBM_File.pm Mon Jul 15 13:35:42 1996 *************** *** 24,30 **** use SDBM_File; ! tie(%h,SDBM_File,'Op.dbmx', O_RDWR|O_CREAT, 0640); untie %h; --- 24,30 ---- use SDBM_File; ! tie(%h, 'SDBM_File', 'Op.dbmx', O_RDWR|O_CREAT, 0640); untie %h; #~ Change name in Makefile.PL for clarity diff -Pcr perl5_003/ext/SDBM_File/sdbm/Makefile.PL perl5_003_01/ext/SDBM_File/sdbm/Makefile.PL *** perl5_003/ext/SDBM_File/sdbm/Makefile.PL Sun Jun 23 22:11:45 1996 --- perl5_003_01/ext/SDBM_File/sdbm/Makefile.PL Mon Jun 17 15:09:35 1996 *************** *** 1,13 **** use ExtUtils::MakeMaker; WriteMakefile( ! 'NAME' => 'SDBM_File', ! 'LINKTYPE' => 'static', ! 'DEFINE' => '-DSDBM -DDUFF', ! 'SKIP' => [qw(static static_lib dynamic dynamic_lib)], ! 'clean' ! => {'FILES' => 'dbu libsdbm.a dbd dba dbe x-dbu *.dir *.pag'}, ! 'H' => [qw(tune.h sdbm.h pair.h $(PERL_INC)/config.h)], ! 'C' => [qw(sdbm.c pair.c hash.c)] ); --- 1,12 ---- use ExtUtils::MakeMaker; WriteMakefile( ! NAME => 'SDBM_File/sdbm', # doesn't matter what the name is here ! LINKTYPE => 'static', ! DEFINE => '-DSDBM -DDUFF', ! SKIP => [qw(static static_lib dynamic dynamic_lib)], ! clean => {'FILES' => 'dbu libsdbm.a dbd dba dbe x-dbu *.dir *.pag'}, ! H => [qw(tune.h sdbm.h pair.h $(PERL_INC)/config.h)], ! C => [qw(sdbm.c pair.c hash.c)] ); #~ Correct CODE block declaration diff -Pcr perl5_003/ext/Socket/Socket.xs perl5_003_01/ext/Socket/Socket.xs *** perl5_003/ext/Socket/Socket.xs Mon Jan 22 20:42:22 1996 --- perl5_003_01/ext/Socket/Socket.xs Thu Jul 25 15:26:49 1996 *************** *** 649,655 **** void unpack_sockaddr_un(sun_sv) SV * sun_sv ! PPCODE: { #ifdef I_SYS_UN STRLEN sockaddrlen; --- 649,655 ---- void unpack_sockaddr_un(sun_sv) SV * sun_sv ! CODE: { #ifdef I_SYS_UN STRLEN sockaddrlen; #~ Add symbols for shared hash keys and improved signal handling #~ Rename symbols to avoid collisions with other headers or libraries diff -Pcr perl5_003/global.sym perl5_003_01/global.sym *** perl5_003/global.sym Mon Mar 25 01:04:07 1996 --- perl5_003_01/global.sym Wed Jul 17 11:09:00 1996 *************** *** 28,33 **** --- 28,34 ---- comppad comppad_name comppad_name_fill + comppad_name_floor concat_amg concat_ass_amg cop_seqmax *************** *** 36,41 **** --- 37,43 ---- cshlen cshname curcop + curcopdb curinterp curpad dc *************** *** 148,153 **** --- 150,157 ---- ppaddr profiledata provide_ref + psig_ptr + psig_name qrt_amg rcsid reall_srchlen *************** *** 206,212 **** sle_amg slt_amg sne_amg - stack stack_base stack_max stack_sp --- 210,215 ---- *************** *** 300,306 **** cast_ulong check_uni checkcomma - chsize ck_aelem ck_concat ck_delete --- 303,308 ---- *************** *** 416,421 **** --- 418,424 ---- gv_fullname gv_init gv_stashpv + gv_stashpvn gv_stashsv he_delayfree he_free *************** *** 423,438 **** --- 426,446 ---- hoistmust hv_clear hv_delete + hv_delete_ent hv_exists + hv_exists_ent hv_fetch + hv_fetch_ent hv_iterinit hv_iterkey + hv_iterkeysv hv_iternext hv_iternextsv hv_iterval hv_magic hv_stashpv hv_store + hv_store_ent hv_undef ibcmp ingroup *************** *** 451,462 **** --- 459,472 ---- looks_like_number magic_clearenv magic_clearpack + magic_clearsig magic_existspack magic_get magic_getarylen magic_getglob magic_getpack magic_getpos + magic_getsig magic_gettaint magic_getuvar magic_len *************** *** 496,501 **** --- 506,512 ---- my my_bcopy my_bzero + my_chsize my_exit my_htonl my_lstat *************** *** 982,987 **** --- 993,999 ---- screaminstr setdefout setenv_getix + sharepvn sighandler skipspace stack_grow *************** *** 1049,1054 **** --- 1061,1067 ---- too_few_arguments too_many_arguments unlnk + unsharepvn utilize wait4pid warn #~ Add casts where necessary to accomodate new GV type #~ Speed up symbol table access and method lookup diff -Pcr perl5_003/gv.c perl5_003_01/gv.c *** perl5_003/gv.c Mon Mar 25 01:04:07 1996 --- perl5_003_01/gv.c Tue Jun 18 21:59:13 1996 *************** *** 81,87 **** { register GP *gp; ! sv_upgrade(gv, SVt_PVGV); if (SvLEN(gv)) Safefree(SvPVX(gv)); Newz(602,gp, 1, GP); --- 81,87 ---- { register GP *gp; ! sv_upgrade((SV*)gv, SVt_PVGV); if (SvLEN(gv)) Safefree(SvPVX(gv)); Newz(602,gp, 1, GP); *************** *** 185,191 **** } 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); --- 185,191 ---- } if (!level) { ! if (lastchance = gv_stashpvn("UNIVERSAL", 9, FALSE)) { if (gv = gv_fetchmeth(lastchance, name, len, level + 1)) { if (cv) { /* junk old undef */ assert(SvREFCNT(topgv) > 1); *************** *** 227,237 **** /* 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; } } --- 227,237 ---- /* 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_stashpvn(SvPVX(tmpstr),SvCUR(tmpstr),TRUE); *nsplit = ch; DEBUG_o( deb("Treating %s as %s::%s\n",origname,HvNAME(stash),name) ); } else { ! stash = gv_stashpvn(origname, nsplit - origname, TRUE); *nsplit = ch; } } *************** *** 241,247 **** /* 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)) { --- 241,247 ---- /* Failed obvious case - look for SUPER as last element of stash's name */ char *packname = HvNAME(stash); STRLEN len = strlen(packname); ! if ((len -= 7) >= 0 && strEQ(packname+len,"::SUPER")) { /* Now look for @.*::SUPER::ISA */ GV** gvp = (GV**)hv_fetch(stash,"ISA",3,FALSE); if (!gvp || (gv = *gvp) == (GV*)&sv_undef || !GvAV(gv)) { *************** *** 249,259 **** 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 */ --- 249,259 ---- and see if there is an @ISA there */ HV *basestash; ! char ch = packname[len]; AV *av; ! packname[len] = '\0'; ! basestash = gv_stashpvn(packname, len, TRUE); ! packname[len] = 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 */ *************** *** 276,282 **** 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... */ --- 276,282 ---- CV* cv; if (strEQ(name,"import") || strEQ(name,"unimport")) ! gv = (GV*)&sv_yes; else if (strNE(name, "AUTOLOAD")) { gv = gv_fetchmeth(stash, "AUTOLOAD", 8, 0); if (gv && (cv = GvCV(gv))) { /* One more chance... */ *************** *** 297,310 **** char *name; I32 create; { ! char tmpbuf[1234]; 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 (!tmpgv) return 0; --- 297,327 ---- char *name; I32 create; { ! return gv_stashpvn(name, strlen(name), create); ! } ! ! HV* ! gv_stashpvn(name,namelen,create) ! char *name; ! U32 namelen; ! I32 create; ! { ! char tmpbuf[1203]; HV *stash; GV *tmpgv; ! ! if (namelen > 1200) { ! namelen = 1200; ! #ifdef VMS ! warn("Weird package name \"%s\" truncated", name); ! #else ! warn("Weird package name \"%.*s...\" truncated", namelen, name); ! #endif ! } ! Copy(name,tmpbuf,namelen,char); ! tmpbuf[namelen++] = ':'; ! tmpbuf[namelen++] = ':'; ! tmpbuf[namelen] = '\0'; tmpgv = gv_fetchpv(tmpbuf,create, SVt_PVHV); if (!tmpgv) return 0; *************** *** 321,327 **** SV *sv; I32 create; { ! return gv_stashpv(SvPV(sv,na), create); } --- 338,347 ---- SV *sv; I32 create; { ! register char *ptr; ! STRLEN len; ! ptr = SvPV(sv,len); ! return gv_stashpvn(ptr, len, create); } *************** *** 349,355 **** { if (!stash) stash = defstash; ! if (!SvREFCNT(stash)) /* symbol table under destruction */ return Nullgv; len = namend - name; --- 369,375 ---- { if (!stash) stash = defstash; ! if (!stash || !SvREFCNT(stash)) /* symbol table under destruction */ return Nullgv; len = namend - name; *************** *** 384,390 **** namend++; name = namend; if (!*name) ! return gv ? gv : *hv_fetch(defstash, "main::", 6, TRUE); } } len = namend - name; --- 404,410 ---- namend++; name = namend; if (!*name) ! return gv ? gv : (GV*)*hv_fetch(defstash, "main::", 6, TRUE); } } len = namend - name; *************** *** 518,532 **** { char *pname; av_push(av, newSVpv(pname = "NDBM_File",0)); ! gv_stashpv(pname, TRUE); av_push(av, newSVpv(pname = "DB_File",0)); ! gv_stashpv(pname, TRUE); av_push(av, newSVpv(pname = "GDBM_File",0)); ! gv_stashpv(pname, TRUE); av_push(av, newSVpv(pname = "SDBM_File",0)); ! gv_stashpv(pname, TRUE); av_push(av, newSVpv(pname = "ODBM_File",0)); ! gv_stashpv(pname, TRUE); } } break; --- 538,552 ---- { char *pname; av_push(av, newSVpv(pname = "NDBM_File",0)); ! gv_stashpvn(pname, 9, TRUE); av_push(av, newSVpv(pname = "DB_File",0)); ! gv_stashpvn(pname, 7, TRUE); av_push(av, newSVpv(pname = "GDBM_File",0)); ! gv_stashpvn(pname, 9, TRUE); av_push(av, newSVpv(pname = "SDBM_File",0)); ! gv_stashpvn(pname, 9, TRUE); av_push(av, newSVpv(pname = "ODBM_File",0)); ! gv_stashpvn(pname, 9, TRUE); } } break; *************** *** 542,552 **** case 'S': if (strEQ(name, "SIG")) { HV *hv; siggv = gv; GvMULTI_on(siggv); hv = GvHVn(siggv); hv_magic(hv, siggv, 'S'); ! /* initialize signal stack */ signalstack = newAV(); AvREAL_off(signalstack); --- 562,580 ---- 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); *************** *** 702,708 **** sv_upgrade((SV *)io,SVt_PVIO); SvREFCNT(io) = 1; SvOBJECT_on(io); ! iogv = gv_fetchpv("FileHandle::", TRUE, SVt_PVHV); SvSTASH(io) = (HV*)SvREFCNT_inc(GvHV(iogv)); return io; } --- 730,736 ---- sv_upgrade((SV *)io,SVt_PVIO); SvREFCNT(io) = 1; SvOBJECT_on(io); ! iogv = gv_fetchpv("IO::Handle::", TRUE, SVt_PVHV); SvSTASH(io) = (HV*)SvREFCNT_inc(GvHV(iogv)); return io; } *************** *** 720,734 **** 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)) { if (hv != defstash) gv_check(hv); /* nested package */ } ! else if (isALPHA(*entry->hent_key)) { ! gv = (GV*)entry->hent_val; if (GvMULTI(gv)) continue; curcop->cop_line = GvLINE(gv); --- 748,762 ---- if (!HvARRAY(stash)) return; for (i = 0; i <= (I32) HvMAX(stash); i++) { ! 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(*HeKEY(entry))) { ! gv = (GV*)HeVAL(entry); if (GvMULTI(gv)) continue; curcop->cop_line = GvLINE(gv); *************** *** 736,742 **** curcop->cop_filegv = filegv; if (filegv && GvMULTI(filegv)) /* Filename began with slash */ continue; ! warn("Identifier \"%s::%s\" used only once: possible typo", HvNAME(stash), GvNAME(gv)); } } --- 764,770 ---- curcop->cop_filegv = filegv; if (filegv && GvMULTI(filegv)) /* Filename began with slash */ continue; ! warn("Name \"%s::%s\" used only once: possible typo", HvNAME(stash), GvNAME(gv)); } } *************** *** 854,859 **** --- 882,888 ---- AMT amt; SV* sv; SV** svp; + GV** gvp; /* if (*(svp)==(SV*)amagic_generation && *(svp+1)==(SV*)sub_generation) { DEBUG_o( deb("Overload magic in package %s up-to-date\n",HvNAME(stash)) *************** *** 878,884 **** if ( (cp=((char**)(*AMG_names))[i]) ) { svp=(SV**)hv_fetch(hv,cp,strlen(cp),FALSE); ! if (svp && ((sv = *svp) != (GV*)&sv_undef)) { switch (SvTYPE(sv)) { default: if (!SvROK(sv)) { --- 907,913 ---- if ( (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)) { *************** *** 977,982 **** --- 1006,1017 ---- 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); *************** *** 1132,1137 **** --- 1167,1174 ---- ENTER; SAVESPTR(op); op = (OP *) &myop; + if (perldb && curstash != debstash) + op->op_private |= OPpENTERSUB_DB; PUTBACK; pp_pushmark(); *************** *** 1182,1187 **** --- 1219,1226 ---- case inc_amg: case dec_amg: SvSetSV(left,res); return res; break; + case not_amg: + ans=!SvOK(res); break; } return ans? &sv_yes: &sv_no; } else if (method==copy_amg) { #~ Add cast for GV type diff -Pcr perl5_003/gv.h perl5_003_01/gv.h *** perl5_003/gv.h Fri Feb 23 22:07:17 1996 --- perl5_003_01/gv.h Tue Jun 18 20:41:19 1996 *************** *** 42,47 **** --- 42,48 ---- #define GvFORM(gv) (GvGP(gv)->gp_form) #define GvAV(gv) (GvGP(gv)->gp_av) + #define GvREFCNT_inc(gv) ((GV*)SvREFCNT_inc(gv)) #ifdef MICROPORT /* Microport 2.4 hack */ AV *GvAVn(); #~ Move up definitions of TRUE/FALSE #~ Include bool typedef on NeXT #~ Add calloc prototypes diff -Pcr perl5_003/handy.h perl5_003_01/handy.h *** perl5_003/handy.h Wed Jun 7 19:47:10 1995 --- perl5_003_01/handy.h Thu Jul 11 12:25:26 1996 *************** *** 23,28 **** --- 23,37 ---- #define Nullfp Null(FILE*) #define Nullsv Null(SV*) + #ifdef TRUE + #undef TRUE + #endif + #ifdef FALSE + #undef FALSE + #endif + #define TRUE (1) + #define FALSE (0) + /* 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,42 **** --- 46,64 ---- # 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,59 **** # endif #endif - #ifdef TRUE - #undef TRUE - #endif - #ifdef FALSE - #undef FALSE - #endif - #define TRUE (1) - #define FALSE (0) - typedef char I8; typedef unsigned char U8; --- 67,72 ---- *************** *** 133,138 **** --- 146,152 ---- char *safemalloc _((MEM_SIZE)); char *saferealloc _((char *, MEM_SIZE)); void safefree _((char *)); + char *safecalloc _((MEM_SIZE, MEM_SIZE)); #endif #ifndef MSDOS #define New(x,v,n,t) (v = (t*)safemalloc((MEM_SIZE)((n) * sizeof(t)))) *************** *** 155,160 **** --- 169,175 ---- char *safexmalloc(); char *safexrealloc(); void safexfree(); + char *safexcalloc(); #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)))), \ #~ Recognize gcc binaries with version in name diff -Pcr perl5_003/hints/aux.sh perl5_003_01/hints/aux.sh *** perl5_003/hints/aux.sh Wed Jun 7 19:47:19 1995 --- perl5_003_01/hints/aux.sh Fri Jul 5 17:35:09 1996 *************** *** 6,12 **** # Fri May 5 10:59:43 EDT 1995 case "$cc" in ! gcc) optimize='-O2' ccflags="$ccflags -D_POSIX_SOURCE" echo "Setting hints for GNU CC." ;; --- 6,12 ---- # Fri May 5 10:59:43 EDT 1995 case "$cc" in ! *gcc*) optimize='-O2' ccflags="$ccflags -D_POSIX_SOURCE" echo "Setting hints for GNU CC." ;; #~ Recognize recent versions > 10.2 diff -Pcr perl5_003/hints/convexos.sh perl5_003_01/hints/convexos.sh *** perl5_003/hints/convexos.sh Thu Jan 19 18:59:10 1995 --- perl5_003_01/hints/convexos.sh Wed Jul 10 11:46:40 1996 *************** *** 15,20 **** # a mixed system, so we undef d_getpgrp. # Andy Dougherty doughera@lafcol.lafayette.edu # ! case "$osvers" in ! 10.2) d_getpgrp='undef' ;; ! esac --- 15,21 ---- # a mixed system, so we undef d_getpgrp. # Andy Dougherty doughera@lafcol.lafayette.edu # ! if [ "$osvers" -ge 10.2 ] ! then ! d_getpgrp='undef' ;; ! fi #~ Recognize gcc binaries with version in name diff -Pcr perl5_003/hints/irix_4.sh perl5_003_01/hints/irix_4.sh *** perl5_003/hints/irix_4.sh Wed Jun 7 19:47:33 1995 --- perl5_003_01/hints/irix_4.sh Fri Jul 5 17:35:11 1996 *************** *** 7,13 **** d_charsprf=undef case "$cc" in ! *gcc) ccflags="$ccflags -D_BSD_TYPES" ;; *) ccflags="$ccflags -ansiposix -signed" ;; esac --- 7,13 ---- d_charsprf=undef case "$cc" in ! *gcc*) ccflags="$ccflags -D_BSD_TYPES" ;; *) ccflags="$ccflags -ansiposix -signed" ;; esac #~ Recognize gcc binaries with version in name diff -Pcr perl5_003/hints/irix_5.sh perl5_003_01/hints/irix_5.sh *** perl5_003/hints/irix_5.sh Mon Jan 22 20:42:34 1996 --- perl5_003_01/hints/irix_5.sh Fri Jul 5 17:35:13 1996 *************** *** 11,17 **** i_time='define' case "$cc" in ! *gcc) ccflags="$ccflags -D_BSD_TYPES" ;; *) ccflags="$ccflags -D_POSIX_SOURCE -ansiposix -D_BSD_TYPES -Olimit 3000" ;; esac --- 11,17 ---- i_time='define' case "$cc" in ! *gcc*) ccflags="$ccflags -D_BSD_TYPES" ;; *) ccflags="$ccflags -D_POSIX_SOURCE -ansiposix -D_BSD_TYPES -Olimit 3000" ;; esac #~ Eliminate hints now correctly handled by Configure diff -Pcr perl5_003/hints/irix_6_2.sh perl5_003_01/hints/irix_6_2.sh *** perl5_003/hints/irix_6_2.sh Mon Mar 25 01:04:08 1996 --- perl5_003_01/hints/irix_6_2.sh Wed Jul 10 11:55:14 1996 *************** *** 1,28 **** # irix_6_2.sh ! # from Krishna Sethuraman, krishna@sgi.com ! # Date: Tue Aug 22 00:38:26 PDT 1995 ! # removed -ansiposix and -D_POSIX_SOURCE cuz it was choking - # Perl built with this hints file under IRIX 6.2 passes - # all tests (`make test'). - - ld=ld - i_time='define' - cc="cc -32" ccflags="$ccflags -D_BSD_TYPES -D_BSD_TIME -Olimit 3000" - #ccflags="$ccflags -Olimit 3000" # this line builds perl but not tk (beta 8) - lddlflags="-32 -shared" - # Configure would suggest the default -Kpic, which won't work for SGI. - # Configure will respect this blank hint value instead. - cccdlflags=' ' # We don't want these libraries. Anyone know why? set `echo X "$libswanted "|sed -e 's/ socket / /' -e 's/ nsl / /' -e 's/ dl / /'` shift libswanted="$*" # Don't need sun crypt bsd PW under 6.2. You *may* need to link # with these if you want to run perl built under 6.2 on a 5.3 machine # (I haven't checked) ! #set `echo X "$libswanted "|sed -e 's/ sun / /' -e 's/ crypt / /' -e 's/ bsd / /' -e 's/ PW / /'` ! #shift ! #libswanted="$*" --- 1,17 ---- # irix_6_2.sh ! # original from Krishna Sethuraman, krishna@sgi.com ! # Configure has been made smarter, so this is shorter than it once was. ccflags="$ccflags -D_BSD_TYPES -D_BSD_TIME -Olimit 3000" # We don't want these libraries. Anyone know why? set `echo X "$libswanted "|sed -e 's/ socket / /' -e 's/ nsl / /' -e 's/ dl / /'` shift libswanted="$*" + # Don't need sun crypt bsd PW under 6.2. You *may* need to link # with these if you want to run perl built under 6.2 on a 5.3 machine # (I haven't checked) ! set `echo X "$libswanted "|sed -e 's/ sun / /' -e 's/ crypt / /' -e 's/ bsd / /' -e 's/ PW / /'` ! shift ! libswanted="$*" #~ Update cc and ld flags, and add MAB support diff -Pcr perl5_003/hints/next_3.sh perl5_003_01/hints/next_3.sh *** perl5_003/hints/next_3.sh Wed Jun 7 19:47:47 1995 --- perl5_003_01/hints/next_3.sh Thu Jul 11 12:26:05 1996 *************** *** 10,20 **** ldflags='-u libsys_s' libswanted='dbm gdbm db' ! lddlflags='-r' # Give cccdlflags an empty value since Configure will detect we are # using GNU cc and try to specify -fpic for cccdlflags. cccdlflags=' ' i_utime='undef' groupstype='int' direntrytype='struct direct' --- 10,24 ---- ldflags='-u libsys_s' libswanted='dbm gdbm db' ! lddlflags='-nostdlib -r' # Give cccdlflags an empty value since Configure will detect we are # using GNU cc and try to specify -fpic for cccdlflags. cccdlflags=' ' + mab='-arch m68k -arch i386 -arch hppa -arch sparc' + archname='next-fat' + ld='cc' + i_utime='undef' groupstype='int' direntrytype='struct direct' *************** *** 36,41 **** # # There where reports that the compiler on HPPA machines # fails with the -O flag on pp.c. - if [ `arch` = "hppa" ]; then pp_cflags='optimize="-g"' - fi --- 40,43 ---- #~ Add hints file for NeXT 3.2 diff -Pcr perl5_003/hints/next_3_2.sh perl5_003_01/hints/next_3_2.sh *** perl5_003/hints/next_3_2.sh Wed Dec 31 19:00:00 1969 --- perl5_003_01/hints/next_3_2.sh Fri Jul 5 15:34:09 1996 *************** *** 0 **** --- 1,64 ---- + # This file has been put together by Anno Siegel + # and Andreas Koenig . Comments, questions, and + # improvements welcome! + # + # These hints are intended for NeXT 3.2. + + # From about perl5.002beta1h perl became unstable on the + # NeXT. Intermittent coredumps were frequent on 3.2 OS. There were + # reports, that the developer version of 3.3 didn't have problems, so it + # seemed pretty obvious that we had to work around an malloc bug in 3.2. + # This hints file reflects a patch to perl5.002_01 that introduces a + # home made sbrk routine (remember, NeXT's sbrk _never_ worked). This + # sbrk makes it possible to run perl with its own malloc. Thanks to + # Ilya who showed me the way to his sbrk for OS/2!! + # andreas koenig, 1996-06-16 + + ccflags='-DUSE_NEXT_CTYPE -DUSE_PERL_SBRK -DHIDEMYMALLOC' + POSIX_cflags='ccflags="-posix $ccflags"' + ldflags='-u libsys_s' + libswanted='dbm gdbm db' + + lddlflags='-r' + # Give cccdlflags an empty value since Configure will detect we are + # using GNU cc and try to specify -fpic for cccdlflags. + cccdlflags=' ' + + i_utime='undef' + groupstype='int' + direntrytype='struct direct' + d_strcoll='undef' + + # the simple program `for ($i=1;$i<38771;$i++){$t{$i}=123}' fails + # with Larry's malloc on NS 3.2 due to broken sbrk() + ###################################################################### + # above comment should stay here, but is not longer of importance # + # with -DUSE_PERL_SBRK and -DHIDEMYMALLOC we can now say 'yes' to # + # usemymalloc. We call this hintsfile next_3_2.sh, so folks with 3.3 # + # can decide what they prefer. Actually folks with 3.3 "user" version# + # will also need this hintsfile, but how can I discern which 3.3 it # + # is? # + ###################################################################### + usemymalloc='y' + + d_uname='define' + d_setpgid='define' + d_setsid='define' + d_tcgetpgrp='define' + d_tcsetpgrp='define' + + # + # On some NeXT machines, the timestamp put by ranlib is not correct, and + # this may cause useless recompiles. Fix that by adding a sleep before + # running ranlib. The '5' is an empirical number that's "long enough." + # + ranlib='sleep 5; /bin/ranlib' + + + # + # There where reports that the compiler on HPPA machines + # fails with the -O flag on pp.c. + # + if [ `arch` = "hppa" ]; then + pp_cflags='optimize="-g"' + fi #~ Add hints file for NeXT 3.3 diff -Pcr perl5_003/hints/next_3_3.sh perl5_003_01/hints/next_3_3.sh *** perl5_003/hints/next_3_3.sh Wed Dec 31 19:00:00 1969 --- perl5_003_01/hints/next_3_3.sh Fri Jul 5 15:34:11 1996 *************** *** 0 **** --- 1,69 ---- + # This file has been put together by Anno Siegel + # and Andreas Koenig . Comments, questions, and + # improvements welcome! + # + + # These hints are intended for NeXT 3.3. If you're running the 3.3 + # "user" version of the NeXT OS, you should not change the malloc + # related hints (USE_PERL_SBRK, HIDEMYMALLOC, usemymalloc). If you're + # running the 3.3 "dev" version of the OS, I do not know what to + # recommend (I have no 3.3 dev). + + # From about perl5.002beta1h perl became unstable on the + # NeXT. Intermittent coredumps were frequent on 3.2 OS. There were + # reports, that the developer version of 3.3 didn't have problems, so it + # seemed pretty obvious that we had to work around an malloc bug in 3.2. + # This hints file reflects a patch to perl5.002_01 that introduces a + # home made sbrk routine (remember, NeXT's sbrk _never_ worked). This + # sbrk makes it possible to run perl with its own malloc. Thanks to + # Ilya who showed me the way to his sbrk for OS/2!! + # andreas koenig, 1996-06-16 + + ccflags='-DUSE_NEXT_CTYPE -DUSE_PERL_SBRK -DHIDEMYMALLOC' + POSIX_cflags='ccflags="-posix $ccflags"' + ldflags='-u libsys_s' + libswanted='dbm gdbm db' + + lddlflags='-r' + # Give cccdlflags an empty value since Configure will detect we are + # using GNU cc and try to specify -fpic for cccdlflags. + cccdlflags=' ' + + i_utime='undef' + groupstype='int' + direntrytype='struct direct' + d_strcoll='undef' + + # the simple program `for ($i=1;$i<38771;$i++){$t{$i}=123}' fails + # with Larry's malloc on NS 3.2 due to broken sbrk() + ###################################################################### + # above comment should stay here, but is not longer of importance # + # with -DUSE_PERL_SBRK and -DHIDEMYMALLOC we can now say 'yes' to # + # usemymalloc. We call this hintsfile next_3_2.sh, so folks with 3.3 # + # can decide what they prefer. Actually folks with 3.3 "user" version# + # will also need this hintsfile, but how can I discern which 3.3 it # + # is? # + ###################################################################### + usemymalloc='y' + + d_uname='define' + d_setpgid='define' + d_setsid='define' + d_tcgetpgrp='define' + d_tcsetpgrp='define' + + # + # On some NeXT machines, the timestamp put by ranlib is not correct, and + # this may cause useless recompiles. Fix that by adding a sleep before + # running ranlib. The '5' is an empirical number that's "long enough." + # + ranlib='sleep 5; /bin/ranlib' + + + # + # There where reports that the compiler on HPPA machines + # fails with the -O flag on pp.c. + # + if [ `arch` = "hppa" ]; then + pp_cflags='optimize="-g"' + fi #~ Add hints file for NeXT 4.0 diff -Pcr perl5_003/hints/next_4.sh perl5_003_01/hints/next_4.sh *** perl5_003/hints/next_4.sh Wed Dec 31 19:00:00 1969 --- perl5_003_01/hints/next_4.sh Thu Jul 11 12:26:09 1996 *************** *** 0 **** --- 1,55 ---- + # Posix support has been removed from NextStep, expect test/POSIX to fail + # + # IMPORTANT: before you run 'make', you need to enter one of these two + # lines (depending on your shell): + # DYLD_LIBRARY_PATH=`pwd`; export DYLD_LIBRARY_PATH + # or + # setenv DYLD_LIBRARY_PATH `pwd` + # + useposix='undef' + + altmake='gnumake' + libpth='/lib /usr/lib' + libswanted=' ' + libc='/NextLibrary/Frameworks/System.framework/System' + + isnext_4='define' + mab='-arch m68k -arch i386 -arch sparc' + ldflags='-dynamic -prebind' + lddlflags='-dynamic -bundle -undefined suppress' + ccflags='-dynamic -fno-common -DUSE_NEXT_CTYPE' + cccdlflags='none' + ld='cc' + optimize='-g -O' + + d_shrplib='define' + dlext='bundle' + so='dylib' + + prefix='/usr/local/OPENSTEP' + #archlib='/usr/lib/perl5' + #archlibexp='/usr/lib/perl5' + archname='OPENSTEP-Mach' + + d_strcoll='undef' + i_dbm='define' + i_utime='undef' + groupstype='int' + direntrytype='struct direct' + + # the simple program `for ($i=1;$i<38771;$i++){$t{$i}=123}' fails + # with Larry's malloc on NS 3.2 due to broken sbrk() + usemymalloc='n' + clocktype='int' + + # + # On some NeXT machines, the timestamp put by ranlib is not correct, and + # this may cause useless recompiles. Fix that by adding a sleep before + # running ranlib. The '5' is an empirical number that's "long enough." + # (Thanks to Andreas Koenig ) + ranlib='sleep 5; /bin/ranlib' + # + # There where reports that the compiler on HPPA machines + # fails with the -O flag on pp.c. + # But since there is no HPPA for OPENSTEP... + # pp_cflags='optimize="-g"' #~ Insure execution by shell #~ Locate shell binary for BIN_SH cpp macro #~ Include a.out support #~ Account for home-grown process priority functions diff -Pcr perl5_003/hints/os2.sh perl5_003_01/hints/os2.sh *** perl5_003/hints/os2.sh Mon Mar 25 01:04:09 1996 --- perl5_003_01/hints/os2.sh Tue Jun 18 21:17:45 1996 *************** *** 1,3 **** --- 1,4 ---- + #! /bin/sh # hints/os2.sh # This file reflects the tireless work of # Ilya Zakharevich *************** *** 5,11 **** # Trimmed and comments added by # Andy Dougherty # Exactly what is required beyond a standard OS/2 installation? ! # There are notes about "patched pdksh" I don't understand. # Note that symbol extraction code gives wrong answers (sometimes?) on # gethostent and setsid. --- 6,12 ---- # Trimmed and comments added by # Andy Dougherty # Exactly what is required beyond a standard OS/2 installation? ! # There are notes about "patched pdksh" I do not understand. # Note that symbol extraction code gives wrong answers (sometimes?) on # gethostent and setsid. *************** *** 13,18 **** --- 14,22 ---- # Note that during the .obj compile you need to move the perl.dll file # to LIBPATH :-( + bin_sh=`../UU/loc sh.exe /bin c:/bin d:/bin e:/bin f:/bin g:/bin h:/bin /bin` + echo "####### Shell found at $bin_sh #############" >&4 + #osname="OS/2" sysman=`../UU/loc . /man/man1 c:/man/man1 c:/usr/man/man1 d:/man/man1 d:/usr/man/man1 e:/man/man1 e:/usr/man/man1 f:/man/man1 f:/usr/man/man1 g:/man/man1 g:/usr/man/man1 /usr/man/man1` cc='gcc' *************** *** 30,46 **** firstmakefile='GNUmakefile' exe_ext='.exe' if [ "$emxaout" != "" ]; then ! d_shrplib='undef' ! obj_ext='.o' ! lib_ext='.a' ! ar='ar' ! plibext='.a' ! d_fork='define' ! lddlflags='-Zdll' ! ldflags='-Zexe' ! ccflags='-DDOSISH -DNO_SYS_ALLOC -DOS2=2 -DEMBED -I. -DPACK_MALLOC' ! use_clib='c' else d_shrplib='define' obj_ext='.obj' --- 34,72 ---- firstmakefile='GNUmakefile' exe_ext='.exe' + # We provide it + i_dlfcn='define' + + aout_d_shrplib='undef' + aout_obj_ext='.o' + aout_lib_ext='.a' + aout_ar='ar' + aout_plibext='.a' + aout_d_fork='define' + aout_lddlflags='-Zdll' + aout_ldflags='-Zexe' + aout_ccflags='-DDOSISH -DPERL_IS_AOUT -DOS2=2 -DEMBED -I. -DPACK_MALLOC -DDEBUGGING_MSTATS' + aout_cppflags='-DDOSISH -DPERL_IS_AOUT -DOS2=2 -DEMBED -I. -DPACK_MALLOC =DDEBUGGING_MSTATS' + aout_use_clib='c' + aout_usedl='undef' + aout_archobjs="os2.o dl_os2.o" + + # variable which have different values for aout compile + used_aout='d_shrplib plibext lib_ext obj_ext ar plibext d_fork lddlflags ldflags ccflags use_clib usedl archobjs cppflags' + if [ "$emxaout" != "" ]; then ! d_shrplib="$aout_d_shrplib" ! obj_ext="$aout_obj_ext" ! lib_ext="$aout_lib_ext" ! ar="$aout_ar" ! plibext="$aout_plibext" ! d_fork="$aout_d_fork" ! lddlflags="$aout_lddlflags" ! ldflags="$aout_ldflags" ! ccflags="$aout_ccflags" ! cppflags="$aout_cppflags" ! use_clib="$aout_use_clib" ! usedl="$aout_usedl" else d_shrplib='define' obj_ext='.obj' *************** *** 51,58 **** lddlflags='-Zdll -Zomf -Zcrtdll' # Recursive regmatch may eat 2.5M of stack alone. ldflags='-Zexe -Zomf -Zcrtdll -Zstack 32000' ! ccflags='-Zomf -DDOSISH -DOS2=2 -DEMBED -I. -DPACK_MALLOC' use_clib='c_import' fi # To get into config.sh (should start at the beginning of line) --- 77,85 ---- lddlflags='-Zdll -Zomf -Zcrtdll' # Recursive regmatch may eat 2.5M of stack alone. ldflags='-Zexe -Zomf -Zcrtdll -Zstack 32000' ! ccflags='-Zomf -DDOSISH -DOS2=2 -DEMBED -I. -DPACK_MALLOC -DDEBUGGING_MSTATS' use_clib='c_import' + usedl='define' fi # To get into config.sh (should start at the beginning of line) *************** *** 70,87 **** # [Maybe we should just remove c from $libswanted ?] libs='-lsocket -lm' ! archobjs="os2$obj_ext" # Run files without extension with sh - feature of patched ksh # [???] ! NOHASHBANG=sh # Same with newer ksh EXECSHELL=sh cccdlflags='-Zdll' ! dlsrc='dl_os2.xs' ld='gcc' - usedl='define' #cppflags='-DDOSISH -DOS2=2 -DEMBED -I.' --- 97,113 ---- # [Maybe we should just remove c from $libswanted ?] libs='-lsocket -lm' ! archobjs="os2$obj_ext dl_os2$obj_ext" # Run files without extension with sh - feature of patched ksh # [???] ! # NOHASHBANG=sh # Same with newer ksh EXECSHELL=sh cccdlflags='-Zdll' ! dlsrc='dl_dlopen.xs' ld='gcc' #cppflags='-DDOSISH -DOS2=2 -DEMBED -I.' *************** *** 123,135 **** nm_opt='-p' ! ####### All the rest is commented ! # I do not have these: ! #dynamic_ext='Fcntl GDBM_File SDBM_File POSIX Socket UPM REXXCALL' ! #dynamic_ext='Fcntl POSIX Socket SDBM_File Devel/DProf' ! #extensions='Fcntl GDBM_File SDBM_File POSIX Socket UPM REXXCALL' ! #extensions='Fcntl SDBM_File POSIX Socket Devel/DProf' # The next two are commented. pdksh handles #! # sharpbang='extproc ' --- 149,160 ---- nm_opt='-p' ! ####### We define these functions ourselves ! ! d_getprior='define' ! d_setprior='define' ! ####### All the rest is commented # The next two are commented. pdksh handles #! # sharpbang='extproc ' #~ Recognize gcc binaries with version in name diff -Pcr perl5_003/hints/sco.sh perl5_003_01/hints/sco.sh *** perl5_003/hints/sco.sh Tue Feb 13 12:28:07 1996 --- perl5_003_01/hints/sco.sh Fri Jul 5 17:35:15 1996 *************** *** 30,36 **** xlibpth='' case "$cc" in ! gcc) ccflags="$ccflags -U M_XENIX" optimize="$optimize -O2" ;; --- 30,36 ---- xlibpth='' case "$cc" in ! *gcc*) ccflags="$ccflags -U M_XENIX" optimize="$optimize -O2" ;; #~ Correct note on GCC_EXEC_PREFIX diff -Pcr perl5_003/hints/solaris_2.sh perl5_003_01/hints/solaris_2.sh *** perl5_003/hints/solaris_2.sh Mon Jun 24 16:07:54 1996 --- perl5_003_01/hints/solaris_2.sh Sun Jul 7 20:01:51 1996 *************** *** 3,9 **** # Andy Dougherty # Based on input from lots of folks, especially # Dean Roehrich ! # See man vfork. usevfork=false --- 3,9 ---- # Andy Dougherty # Based on input from lots of folks, especially # Dean Roehrich ! # See man vfork. usevfork=false *************** *** 152,158 **** NOTE: You are using GNU as(1). GNU as(1) will not build Perl. You must arrange to use /usr/ccs/bin/as, perhaps by setting ! GCC_EXEC_PREFIX or by including -B/usr/ccs/bin in your cc command. END ;; --- 152,158 ---- NOTE: You are using GNU as(1). GNU as(1) will not build Perl. You must arrange to use /usr/ccs/bin/as, perhaps by setting ! GCC_EXEC_PREFIX or by including -B/usr/ccs/bin/ in your cc command. END ;; *************** *** 166,172 **** NOTE: You are using GNU ld(1). GNU ld(1) will not build Perl. You must arrange to use /usr/ccs/bin/ld, perhaps by setting ! GCC_EXEC_PREFIX or by including -B/usr/ccs/bin in your cc command. END ;; --- 166,172 ---- NOTE: You are using GNU ld(1). GNU ld(1) will not build Perl. You must arrange to use /usr/ccs/bin/ld, perhaps by setting ! GCC_EXEC_PREFIX or by including -B/usr/ccs/bin/ in your cc command. END ;; #~ Add shared hash key support #~ Protect %SIG elements from deletion diff -Pcr perl5_003/hv.c perl5_003_01/hv.c *** perl5_003/hv.c Tue Jan 30 20:33:23 1996 --- perl5_003_01/hv.c Tue Jun 18 21:46:13 1996 *************** *** 25,31 **** HE* he; if (he_root) { he = he_root; ! he_root = (HE*)he->hent_next; return he; } return more_he(); --- 25,31 ---- HE* he; if (he_root) { he = he_root; ! he_root = HeNEXT(he); return he; } return more_he(); *************** *** 35,41 **** del_he(p) HE* p; { ! p->hent_next = (HE*)he_root; he_root = p; } --- 35,41 ---- del_he(p) HE* p; { ! HeNEXT(p) = (HE*)he_root; he_root = p; } *************** *** 48,60 **** he = he_root; heend = &he[1008 / sizeof(HE) - 1]; while (he < heend) { ! he->hent_next = (HE*)(he + 1); he++; } ! he->hent_next = 0; return new_he(); } SV** hv_fetch(hv,key,klen,lval) HV *hv; --- 48,63 ---- he = he_root; heend = &he[1008 / sizeof(HE) - 1]; while (he < heend) { ! HeNEXT(he) = (HE*)(he + 1); he++; } ! HeNEXT(he) = 0; return new_he(); } + /* (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,71 **** I32 lval; { register XPVHV* xhv; ! register char *s; ! register I32 i; ! register I32 hash; register HE *entry; SV *sv; --- 66,72 ---- I32 lval; { register XPVHV* xhv; ! register U32 hash; register HE *entry; SV *sv; *************** *** 93,113 **** return 0; } ! i = klen; ! hash = 0; ! s = key; ! while (i--) ! hash = hash * 33 + *s++; 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 */ continue; ! if (entry->hent_klen != klen) continue; ! if (bcmp(entry->hent_key,key,klen)) /* is this it? */ continue; ! return &entry->hent_val; } #ifdef DYNAMIC_ENV_FETCH /* %ENV lookup? If so, try to fetch the value now */ if (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME)) { --- 94,110 ---- return 0; } ! 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 (bcmp(HeKEY(entry),key,klen)) /* is this it? */ continue; ! 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)) { *************** *** 127,132 **** --- 124,208 ---- 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; + + xhv = (XPVHV*)SvANY(hv); + + if (SvRMAGICAL(hv) && mg_find((SV*)hv,'P')) { + if (!(entry = xhv->xhv_eiter)) { + xhv->xhv_eiter = entry = new_he(); /* only one HE per MAGICAL hash */ + Zero(entry, 1, HE); + HeKLEN(entry) = HEf_SVKEY; /* hent_key is holding an SV* */ + } + else if ((sv = HeSVKEY(entry))) + SvREFCNT_dec(sv); + sv = sv_newmortal(); + mg_copy((SV*)hv, sv, (char*)keysv, HEf_SVKEY); + HeVAL(entry) = sv; + HeKEY(entry) = (char*)SvREFCNT_inc(keysv); + return entry; + } + + key = SvPV(keysv, klen); + + if (!hash) + PERL_HASH(hash, key, klen); + + 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; + } + + 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 (bcmp(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; + + gotenv = my_getenv(key); + if (gotenv != NULL) { + sv = newSVpv(gotenv,strlen(gotenv)); + 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,142 **** register U32 hash; { register XPVHV* xhv; - register char *s; register I32 i; register HE *entry; register HE **oentry; --- 212,217 ---- *************** *** 156,192 **** return 0; #endif /* OVERLOAD */ } ! if (!hash) { ! i = klen; ! s = key; ! while (i--) ! hash = hash * 33 + *s++; } 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 */ continue; ! if (entry->hent_klen != klen) continue; ! if (bcmp(entry->hent_key,key,klen)) /* is this it? */ continue; ! SvREFCNT_dec(entry->hent_val); ! entry->hent_val = val; ! return &entry->hent_val; } 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; *oentry = entry; xhv->xhv_keys++; --- 231,340 ---- return 0; #endif /* OVERLOAD */ } ! 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 (bcmp(HeKEY(entry),key,klen)) /* is this it? */ ! continue; ! SvREFCNT_dec(HeVAL(entry)); ! HeVAL(entry) = val; ! return &HeVAL(entry); ! } ! ! entry = new_he(); ! HeKLEN(entry) = klen; ! if (HvSHAREKEYS(hv)) ! HeKEY(entry) = sharepvn(key, klen, hash); ! else /* gotta do the real thing */ ! HeKEY(entry) = savepvn(key,klen); ! HeVAL(entry) = val; ! HeHASH(entry) = hash; ! HeNEXT(entry) = *oentry; ! *oentry = entry; ! ! xhv->xhv_keys++; ! if (i) { /* initial entry? */ ! ++xhv->xhv_fill; ! if (xhv->xhv_keys > xhv->xhv_max) ! hsplit(hv); ! } ! ! 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)) { ! mg_copy((SV*)hv, val, (char*)keysv, HEf_SVKEY); ! #ifndef OVERLOAD ! if (!xhv->xhv_array) ! return Nullhe; ! #else ! if (!xhv->xhv_array && (SvMAGIC(hv)->mg_type != 'A' ! || SvMAGIC(hv)->mg_moremagic)) ! return Nullhe; ! #endif /* OVERLOAD */ } + 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 = HeNEXT(entry)) { ! if (HeHASH(entry) != hash) /* strings can't be equal */ continue; ! if (HeKLEN(entry) != klen) continue; ! if (bcmp(HeKEY(entry),key,klen)) /* is this it? */ continue; ! SvREFCNT_dec(HeVAL(entry)); ! HeVAL(entry) = val; ! return entry; } entry = new_he(); ! HeKLEN(entry) = klen; ! if (HvSHAREKEYS(hv)) ! HeKEY(entry) = sharepvn(key, klen, hash); ! else /* gotta do the real thing */ ! HeKEY(entry) = savepvn(key,klen); ! HeVAL(entry) = val; ! HeHASH(entry) = hash; ! HeNEXT(entry) = *oentry; *oentry = entry; xhv->xhv_keys++; *************** *** 196,202 **** hsplit(hv); } ! return &entry->hent_val; } SV * --- 344,350 ---- hsplit(hv); } ! return entry; } SV * *************** *** 207,215 **** I32 flags; { register XPVHV* xhv; - register char *s; register I32 i; ! register I32 hash; register HE *entry; register HE **oentry; SV *sv; --- 355,362 ---- I32 flags; { register XPVHV* xhv; register I32 i; ! register U32 hash; register HE *entry; register HE **oentry; SV *sv; *************** *** 219,224 **** --- 366,374 ---- 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,259 **** xhv = (XPVHV*)SvANY(hv); if (!xhv->xhv_array) return Nullsv; ! i = klen; ! hash = 0; ! s = key; ! while (i--) ! hash = hash * 33 + *s++; 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 */ continue; ! if (entry->hent_klen != klen) continue; ! if (bcmp(entry->hent_key,key,klen)) /* is this it? */ continue; ! *oentry = entry->hent_next; if (i && !*oentry) xhv->xhv_fill--; if (flags & G_DISCARD) sv = Nullsv; else ! sv = sv_mortalcopy(entry->hent_val); if (entry == xhv->xhv_eiter) ! entry->hent_klen = -1; else ! he_free(entry); --xhv->xhv_keys; return sv; } --- 377,468 ---- xhv = (XPVHV*)SvANY(hv); if (!xhv->xhv_array) return Nullsv; ! ! 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 (bcmp(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) ! HeKLEN(entry) = HEf_LAZYDEL; else ! he_free(entry, HvSHAREKEYS(hv)); ! --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 (bcmp(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) ! HeKLEN(entry) = HEf_LAZYDEL; ! else ! he_free(entry, HvSHAREKEYS(hv)); --xhv->xhv_keys; return sv; } *************** *** 267,275 **** U32 klen; { register XPVHV* xhv; ! register char *s; ! register I32 i; ! register I32 hash; register HE *entry; SV *sv; --- 476,482 ---- U32 klen; { register XPVHV* xhv; ! register U32 hash; register HE *entry; SV *sv; *************** *** 289,307 **** if (!xhv->xhv_array) return 0; ! i = klen; ! hash = 0; ! s = key; ! while (i--) ! hash = hash * 33 + *s++; 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 */ continue; ! if (entry->hent_klen != klen) continue; ! if (bcmp(entry->hent_key,key,klen)) /* is this it? */ continue; return TRUE; } --- 496,556 ---- if (!xhv->xhv_array) return 0; ! 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 (bcmp(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(); ! 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 = HeNEXT(entry)) { ! if (HeHASH(entry) != hash) /* strings can't be equal */ continue; ! if (HeKLEN(entry) != klen) continue; ! if (bcmp(HeKEY(entry),key,klen)) /* is this it? */ continue; return TRUE; } *************** *** 357,372 **** 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 (!*b) xhv->xhv_fill++; *b = entry; continue; } else ! oentry = &entry->hent_next; } if (!*a) /* everything moved */ xhv->xhv_fill--; --- 606,621 ---- continue; b = a+oldsize; for (oentry = a, entry = *a; entry; entry = *oentry) { ! if ((HeHASH(entry) & newsize) != i) { ! *oentry = HeNEXT(entry); ! HeNEXT(entry) = *b; if (!*b) xhv->xhv_fill++; *b = entry; continue; } else ! oentry = &HeNEXT(entry); } if (!*a) /* everything moved */ xhv->xhv_fill--; *************** *** 384,389 **** --- 633,641 ---- 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,415 **** } void ! he_free(hent) register HE *hent; { if (!hent) return; ! SvREFCNT_dec(hent->hent_val); ! Safefree(hent->hent_key); del_he(hent); } void ! he_delayfree(hent) register HE *hent; { if (!hent) return; ! sv_2mortal(hent->hent_val); /* free between statements */ ! Safefree(hent->hent_key); del_he(hent); } --- 644,679 ---- } void ! he_free(hent, shared) register HE *hent; + I32 shared; { if (!hent) return; ! SvREFCNT_dec(HeVAL(hent)); ! if (HeKLEN(hent) == HEf_SVKEY) ! SvREFCNT_dec((SV*)HeKEY(hent)); ! else if (shared) ! unsharepvn(HeKEY(hent), HeKLEN(hent), HeHASH(hent)); ! else ! Safefree(HeKEY(hent)); del_he(hent); } void ! he_delayfree(hent, shared) register HE *hent; + I32 shared; { if (!hent) return; ! sv_2mortal(HeVAL(hent)); /* free between statements */ ! if (HeKLEN(hent) == HEf_SVKEY) ! sv_2mortal((SV*)HeKEY(hent)); ! else if (shared) ! unsharepvn(HeKEY(hent), HeKLEN(hent), HeHASH(hent)); ! else ! Safefree(HeKEY(hent)); del_he(hent); } *************** *** 440,445 **** --- 704,710 ---- register HE *ohent = Null(HE*); I32 riter; I32 max; + I32 shared; if (!hv) return; *************** *** 450,460 **** max = HvMAX(hv); array = HvARRAY(hv); hent = array[0]; for (;;) { if (hent) { ohent = hent; ! hent = hent->hent_next; ! he_free(ohent); } if (!hent) { if (++riter > max) --- 715,726 ---- max = HvMAX(hv); array = HvARRAY(hv); hent = array[0]; + shared = HvSHAREKEYS(hv); for (;;) { if (hent) { ohent = hent; ! hent = HeNEXT(hent); ! he_free(ohent, shared); } if (!hent) { if (++riter > max) *************** *** 494,501 **** { register XPVHV* xhv = (XPVHV*)SvANY(hv); HE *entry = xhv->xhv_eiter; ! if (entry && entry->hent_klen < 0) /* was deleted earlier? */ ! he_free(entry); xhv->xhv_riter = -1; xhv->xhv_eiter = Null(HE*); return xhv->xhv_fill; --- 760,767 ---- { register XPVHV* xhv = (XPVHV*)SvANY(hv); HE *entry = xhv->xhv_eiter; ! if (entry && HeKLEN(entry) == HEf_LAZYDEL) /* was deleted earlier? */ ! he_free(entry, HvSHAREKEYS(hv)); xhv->xhv_riter = -1; xhv->xhv_eiter = Null(HE*); return xhv->xhv_fill; *************** *** 517,541 **** 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; ! } else { ! xhv->xhv_eiter = entry = new_he(); Zero(entry, 1, HE); } 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; } ! if (entry->hent_val) ! SvREFCNT_dec(entry->hent_val); del_he(entry); xhv->xhv_eiter = Null(HE*); return Null(HE*); --- 783,803 ---- if (SvRMAGICAL(hv) && (mg = mg_find((SV*)hv,'P'))) { SV *key = sv_newmortal(); ! if (entry) ! sv_setsv(key, HeSVKEY_force(entry)); else { ! xhv->xhv_eiter = entry = new_he(); /* only one HE per MAGICAL hash */ Zero(entry, 1, HE); + HeKLEN(entry) = HEf_SVKEY; } magic_nextpack((SV*) hv,mg,key); if (SvOK(key)) { ! SvREFCNT_dec(HeSVKEY(entry)); ! HeKEY(entry) = (char*)SvREFCNT_inc(key); ! return entry; /* beware, hent_val is not set */ } ! if (HeVAL(entry)) ! SvREFCNT_dec(HeVAL(entry)); del_he(entry); xhv->xhv_eiter = Null(HE*); return Null(HE*); *************** *** 543,563 **** 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]; } ! } while (!entry); ! if (oldentry && oldentry->hent_klen < 0) /* was deleted earlier? */ ! he_free(oldentry); xhv->xhv_eiter = entry; return entry; --- 805,823 ---- if (!xhv->xhv_array) Newz(506,xhv->xhv_array, sizeof(HE*) * (xhv->xhv_max + 1), char); ! if (entry) ! entry = HeNEXT(entry); ! while (!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 (oldentry && HeKLEN(oldentry) == HEf_LAZYDEL) /* was deleted earlier? */ ! he_free(oldentry, HvSHAREKEYS(hv)); xhv->xhv_eiter = entry; return entry; *************** *** 568,575 **** register HE *entry; I32 *retlen; { ! *retlen = entry->hent_klen; ! return entry->hent_key; } SV * --- 828,852 ---- register HE *entry; I32 *retlen; { ! if (HeKLEN(entry) == HEf_SVKEY) { ! return SvPV((SV*)HeKEY(entry), *(STRLEN*)retlen); ! } ! 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((SV*)HeKEY(entry)); ! else ! return sv_2mortal(newSVpv((HeKLEN(entry) ? HeKEY(entry) : ""), ! HeKLEN(entry))); } SV * *************** *** 580,590 **** if (SvRMAGICAL(hv)) { if (mg_find((SV*)hv,'P')) { SV* sv = sv_newmortal(); ! mg_copy((SV*)hv, sv, entry->hent_key, entry->hent_klen); return sv; } } ! return entry->hent_val; } SV * --- 857,867 ---- if (SvRMAGICAL(hv)) { if (mg_find((SV*)hv,'P')) { SV* sv = sv_newmortal(); ! mg_copy((SV*)hv, sv, HeKEY(entry), HeKLEN(entry)); return sv; } } ! return HeVAL(entry); } SV * *************** *** 608,610 **** --- 885,988 ---- { sv_magic((SV*)hv, (SV*)gv, how, Nullch, 0); } + + /* 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. + */ + char * + sharepvn(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 (bcmp(HeKEY(entry),str,len)) /* is this it? */ + continue; + found = 1; + break; + } + if (!found) { + entry = new_he(); + HeKLEN(entry) = len; + HeKEY(entry) = savepvn(str,len); + HeVAL(entry) = Nullsv; + HeHASH(entry) = hash; + 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(entry); + } + + /* 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; + 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, 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 (bcmp(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(entry)); + del_he(entry); + --xhv->xhv_keys; + } + break; + } + + if (!found) + warn("Attempt to free non-existent shared string"); + } + #~ Add shared hash key support diff -Pcr perl5_003/hv.h perl5_003_01/hv.h *** perl5_003/hv.h Tue Oct 18 12:20:08 1994 --- perl5_003_01/hv.h Thu Jun 20 09:12:08 1996 *************** *** 32,37 **** --- 32,54 ---- 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 */ + + #define HEf_LAZYDEL -1 /* entry must be deleted during next iter step */ + #define HEf_SVKEY -2 /* hent_key is a SV* (only for magic/tied HVs) */ + + #define Nullhv Null(HV*) #define HvARRAY(hv) ((HE**)((XPVHV*) SvANY(hv))->xhv_array) #define HvFILL(hv) ((XPVHV*) SvANY(hv))->xhv_fill *************** *** 42,47 **** --- 59,68 ---- #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) + #ifdef OVERLOAD /* Maybe amagical: */ *************** *** 58,60 **** --- 79,101 ---- */ #endif /* OVERLOAD */ + + #define Nullhe Null(HE*) + #define HeNEXT(he) (he)->hent_next + #define HeKEY(he) (he)->hent_key + #define HeKLEN(he) (he)->hent_klen + #define HeVAL(he) (he)->hent_val + #define HeHASH(he) (he)->hent_hash + #define HePV(he) ((he)->hent_klen == HEf_SVKEY) ? \ + SvPV((SV*)((he)->hent_key),na) : \ + (he)->hent_key)) + #define HeSVKEY(he) (((he)->hent_key && \ + (he)->hent_klen == HEf_SVKEY) ? \ + (SV*)((he)->hent_key) : Nullsv) + + #define HeSVKEY_force(he) ((he)->hent_key ? \ + (((he)->hent_klen == HEf_SVKEY) ? \ + (SV*)((he)->hent_key) : \ + sv_2mortal(newSVpv((he)->hent_key, \ + (he)->hent_klen))) : \ + &sv_undef) #~ Put cppstdin in architecture-dependent directory #~ Make sure file permissions are set correctly on CORE headers and libperl diff -Pcr perl5_003/installperl perl5_003_01/installperl *** perl5_003/installperl Mon Jun 24 16:08:25 1996 --- perl5_003_01/installperl Fri Jul 5 17:40:23 1996 *************** *** 16,23 **** umask 022; ! @scripts = qw(cppstdin ! utils/c2ph utils/h2ph utils/h2xs utils/pstruct utils/perlbug utils/perldoc x2p/s2p x2p/find2perl pod/pod2man pod/pod2html pod/pod2latex pod/pod2text); --- 16,22 ---- umask 022; ! @scripts = qw( utils/c2ph utils/h2ph utils/h2xs utils/pstruct utils/perlbug utils/perldoc x2p/s2p x2p/find2perl pod/pod2man pod/pod2html pod/pod2latex pod/pod2text); *************** *** 109,123 **** &chmod(0755, "$installbin/a2p$exe_ext"); } # Install scripts. mkpath($installscript, 1, 0777); 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. --- 108,130 ---- &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 ((-f cppstdin) && (! &samepath($installbin, '.'))) { + &safe_unlink("$installbin/cppstdin"); + &cmd("cp cppstdin $installbin/cppstdin"); + &chmod(0755, "$installbin/cppstdin"); + } + # Install scripts. mkpath($installscript, 1, 0777); for (@scripts) { ! &cmd("cp $_ $installscript"); ! s#.*/##; &chmod(0755, "$installscript/$_"); } # Install pod pages. Where? I guess in $installprivlib/pod. *************** *** 175,190 **** # 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"); ! } # AIX needs perl.exp installed as well. ! cp_if_diff("perl.exp" ,"$installarchlib/CORE/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'); ! # Offer to install perl in a "standard" location --- 182,196 ---- # Install header files and libraries. mkpath("$installarchlib/CORE", 1, 0777); ! @corefiles = <*.h libperl*.*>; # AIX needs perl.exp installed as well. ! push(@corefiles,'perl.exp') if $^O eq 'aix'; # If they have built sperl.o... ! push(@corefiles,'sperl.o') if -f 'sperl.o'; ! foreach $file (@corefiles) { ! cp_if_diff($file,"$installarchlib/CORE/$file"); ! &chmod($file =~ /^libperl/ ? 0555 : 0444,"$installarchlib/CORE/$file"); ! } # Offer to install perl in a "standard" location #~ Adjust per-interpreter symbols diff -Pcr perl5_003/interp.sym perl5_003_01/interp.sym *** perl5_003/interp.sym Fri Jan 26 18:55:16 1996 --- perl5_003_01/interp.sym Fri Jul 5 19:13:37 1996 *************** *** 18,25 **** --- 18,27 ---- copline curblock curcop + curcopdb curcsv curpm + curstack curstash curstname cxstack *************** *** 71,76 **** --- 73,79 ---- leftgv lineary localizing + localpatches main_cv main_root main_start *************** *** 101,108 **** origfilename ors orslen - pad - padname parsehook patchlevel perldb --- 104,109 ---- *************** *** 128,140 **** sortstack sortstash splitstr - stack statcache statgv statname statusvalue stdingv strchop sv_count sv_objcount sv_root --- 129,141 ---- sortstack sortstash splitstr statcache statgv statname statusvalue stdingv strchop + strtab sv_count sv_objcount sv_root #~ Quote string argument in example -- necessary if using strict subs diff -Pcr perl5_003/lib/AnyDBM_File.pm perl5_003_01/lib/AnyDBM_File.pm *** perl5_003/lib/AnyDBM_File.pm Wed Jun 7 19:48:04 1995 --- perl5_003_01/lib/AnyDBM_File.pm Mon Jul 15 13:35:56 1996 *************** *** 39,46 **** Having multiple DBM implementations makes it trivial to copy database formats: use POSIX; use NDBM_File; use DB_File; ! tie %newhash, DB_File, $new_filename, O_CREAT|O_RDWR; ! tie %oldhash, NDBM_File, $old_filename, 1, 0; %newhash = %oldhash; =head2 DBM Comparisons --- 39,46 ---- Having multiple DBM implementations makes it trivial to copy database formats: use POSIX; use NDBM_File; use DB_File; ! tie %newhash, 'DB_File', $new_filename, O_CREAT|O_RDWR; ! tie %oldhash, 'NDBM_File', $old_filename, 1, 0; %newhash = %oldhash; =head2 DBM Comparisons #~ Update documentation diff -Pcr perl5_003/lib/AutoLoader.pm perl5_003_01/lib/AutoLoader.pm *** perl5_003/lib/AutoLoader.pm Mon Feb 12 14:53:59 1996 --- perl5_003_01/lib/AutoLoader.pm Thu Jul 11 12:17:27 1996 *************** *** 15,22 **** =head1 DESCRIPTION ! This module tells its users that functions in the FOOBAR package are to be ! autoloaded from F. See L. =cut --- 15,73 ---- =head1 DESCRIPTION ! This module tells its users that functions in the FOOBAR package are ! to be autoloaded from F. See ! L and L. ! ! =head2 __END__ ! ! The module using the autoloader should have the special marker C<__END__> ! prior to the actual subroutine declarations. All code that is before the ! marker will be loaded and compiled when the module is used. At the marker, ! perl will cease reading and parsing. See also the B module, a ! utility that automatically splits a module into a collection of files for ! autoloading. ! ! When a subroutine not yet in memory is called, the C function ! attempts to locate it in a directory relative to the location of the module ! file itself. As an example, assume F is located in ! F. The autoloader will look for perl ! subroutines for this package in F. ! The C<.al> file is named using the subroutine name, sans package. ! ! =head2 Package Lexicals ! ! Package lexicals declared with C in the main block of a package using ! the B will not be visible to auto-loaded functions, due to the ! fact that the given scope ends at the C<__END__> marker. A module using such ! variables as package globals will not work properly under the B. ! ! The C pragma (see L) may be used in such situations ! as an alternative to explicitly qualifying all globals with the package ! namespace. Variables pre-declared with this pragma will be visible to any ! autoloaded routines (but will not be invisible outside the package, ! unfortunately). ! ! =head2 AutoLoader vs. SelfLoader ! ! The B is a counterpart to the B module. Both delay ! the loading of subroutines, but the B accomplishes the goal via ! the C<__DATA__> marker rather than C<__END__>. While this avoids the use of ! a hierarchy of disk files and the associated open/close for each routine ! loaded, the B suffers a disadvantage in the one-time parsing of ! the lines after C<__DATA__>, after which routines are cached. B ! can also handle multiple packages in a file. ! ! B only reads code as it is requested, and in many cases should be ! faster, but requires a machanism like B be used to create the ! individual files. ! ! =head1 CAVEAT ! ! On systems with restrictions on file name length, the file corresponding to a ! subroutine may have a shorter name that the routine itself. This can lead to ! conflicting file names. The I package warns of these potential ! conflicts when used to split a module. =cut #~ Update documentation diff -Pcr perl5_003/lib/AutoSplit.pm perl5_003_01/lib/AutoSplit.pm *** perl5_003/lib/AutoSplit.pm Mon Mar 25 01:04:11 1996 --- perl5_003_01/lib/AutoSplit.pm Thu Jul 11 12:21:48 1996 *************** *** 16,29 **** =head1 SYNOPSIS ! perl -e 'use AutoSplit; autosplit_modules(@ARGV)' ... =head1 DESCRIPTION This function will split up your program into files that the AutoLoader ! module can handle. Normally only used to build autoloading Perl library ! modules, especially extensions (like POSIX). You should look at how ! they're built out for details. =cut --- 16,96 ---- =head1 SYNOPSIS ! perl -e 'use AutoSplit; autosplit_lib_modules(@ARGV)' ... ! ! use AutoSplit; autosplit($file, $dir, $keep, $check, $modtime); ! ! for perl versions 5.002 and later: ! ! perl -MAutoSplit -e 'autosplit($ARGV[0], $ARGV[1], $k, $chk, $modtime)' ... =head1 DESCRIPTION This function will split up your program into files that the AutoLoader ! module can handle. It is used by both the standard perl libraries and by ! the MakeMaker utility, to automatically configure libraries for autoloading. ! ! The C interface splits the specified file into a hierarchy ! rooted at the directory C<$dir>. It creates directories as needed to reflect ! class hierarchy, and creates the file F. This file acts as ! both forward declaration of all package routines, and as timestamp for the ! last update of the hierarchy. ! ! The remaining three arguments to C govern other options to the ! autosplitter. If the third argument, I<$keep>, is false, then any pre-existing ! C<.al> files in the autoload directory are removed if they are no longer ! part of the module (obsoleted functions). The fourth argument, I<$check>, ! instructs C to check the module currently being split to ensure ! that it does include a C specification for the AutoLoader module, and ! skips the module if AutoLoader is not detected. Lastly, the I<$modtime> ! argument specifies that C is to check the modification time of the ! module against that of the C file, and only split the module ! if it is newer. ! ! Typical use of AutoSplit in the perl MakeMaker utility is via the command-line ! with: ! ! perl -e 'use AutoSplit; autosplit($ARGV[0], $ARGV[1], 0, 1, 1)' ! ! Defined as a Make macro, it is invoked with file and directory arguments; ! C will split the specified file into the specified directory and ! delete obsolete C<.al> files, after checking first that the module does use ! the AutoLoader, and ensuring that the module is not already currently split ! in its current form (the modtime test). ! ! The C form is used in the building of perl. It takes ! as input a list of files (modules) that are assumed to reside in a directory ! B relative to the current directory. Each file is sent to the ! autosplitter one at a time, to be split into the directory B. ! ! In both usages of the autosplitter, only subroutines defined following the ! perl special marker I<__END__> are split out into separate files. Some ! routines may be placed prior to this marker to force their immediate loading ! and parsing. ! ! =head1 CAVEATS ! ! Currently, C cannot handle multiple package specifications ! within one file. ! ! =head1 DIAGNOSTICS ! ! C will inform the user if it is necessary to create the top-level ! directory specified in the invocation. It is preferred that the script or ! installation process that invokes C have created the full directory ! path ahead of time. This warning may indicate that the module is being split ! into an incorrect path. ! ! C will warn the user of all subroutines whose name causes potential ! file naming conflicts on machines with drastically limited (8 characters or ! less) file name length. Since the subroutine name is used as the file name, ! these warnings can aid in portability to such systems. ! ! Warnings are issued and the file skipped if C cannot locate either ! the I<__END__> marker or a "package Name;"-style specification. ! ! C will also emit general diagnostics for inability to create ! directories or files. =cut *************** *** 53,59 **** # This function is used during perl building/installation ! # ./miniperl -e 'use AutoSplit; autosplit_modules(@ARGV)' ... sub autosplit_lib_modules{ my(@modules) = @_; # list of Module names --- 120,126 ---- # This function is used during perl building/installation ! # ./miniperl -e 'use AutoSplit; autosplit_lib_modules(@ARGV)' ... sub autosplit_lib_modules{ my(@modules) = @_; # list of Module names #~ Eliminate $& to avoid runtime penalty #~ Consider @ISA when tracing call stack diff -Pcr perl5_003/lib/Carp.pm perl5_003_01/lib/Carp.pm *** perl5_003/lib/Carp.pm Wed Jan 31 13:56:10 1996 --- perl5_003_01/lib/Carp.pm Thu Jul 25 15:24:34 1996 *************** *** 47,53 **** if ($require) { $sub = "require $eval"; } else { ! $eval =~ s/[\\\']/\\$&/g; if ($MaxEvalLen && length($eval) > $MaxEvalLen) { substr($eval,$MaxEvalLen) = '...'; } --- 47,53 ---- if ($require) { $sub = "require $eval"; } else { ! $eval =~ s/([\\\'])/\\$1/g; if ($MaxEvalLen && length($eval) > $MaxEvalLen) { substr($eval,$MaxEvalLen) = '...'; } *************** *** 66,85 **** sub shortmess { # Short-circuit &longmess if called via multiple packages my $error = $_[0]; # Instead of "shift" ! my ($curpack) = caller(1); my $extra = $CarpLevel; my $i = 2; my ($pack,$file,$line); while (($pack,$file,$line) = caller($i++)) { ! if ($pack ne $curpack) { ! if ($extra-- > 0) { ! $curpack = $pack; ! } ! else { ! return "$error at $file line $line\n"; ! } } } goto &longmess; } --- 66,105 ---- sub shortmess { # Short-circuit &longmess if called via multiple packages my $error = $_[0]; # Instead of "shift" ! my ($prevpack) = caller(1); my $extra = $CarpLevel; my $i = 2; my ($pack,$file,$line); + my %isa = ($prevpack,1); + + @isa{@{"${prevpack}::ISA"}} = () + if(defined @{"${prevpack}::ISA"}); + while (($pack,$file,$line) = caller($i++)) { ! if(defined @{$pack . "::ISA"}) { ! my @i = @{$pack . "::ISA"}; ! my %i; ! @i{@i} = (); ! @isa{@i,$pack} = () ! if(exists $i{$prevpack} || exists $isa{$pack}); ! } ! ! next ! if(exists $isa{$pack}); ! ! if ($extra-- > 0) { ! %isa = ($pack,1); ! @isa{@{$pack . "::ISA"}} = () ! if(defined @{$pack . "::ISA"}); ! } ! else { ! return "$error at $file line $line\n"; } } + continue { + $prevpack = $pack; + } + goto &longmess; } #~ Don't reduce '/' to empty string #~ Improved support for Win32 diff -Pcr perl5_003/lib/Cwd.pm perl5_003_01/lib/Cwd.pm *** perl5_003/lib/Cwd.pm Mon Mar 25 01:04:12 1996 --- perl5_003_01/lib/Cwd.pm Wed May 15 19:17:04 1996 *************** *** 121,127 **** $cwd = "$dir/$cwd"; closedir(PARENT); } while ($dir); ! chop($cwd); # drop the trailing / $cwd; } --- 121,127 ---- $cwd = "$dir/$cwd"; closedir(PARENT); } while ($dir); ! chop($cwd) unless $cwd eq '/'; # drop the trailing / $cwd; } *************** *** 246,257 **** *fastcwd = \&_vms_cwd; *fastgetcwd = \&_vms_cwd; } ! elsif ($^O eq 'NT') { ! *getcwd = \&cwd; ! *fastgetcwd = \&cwd; } elsif ($^O eq 'os2') { *cwd = \&_os2_cwd; *getcwd = \&_os2_cwd; *fastgetcwd = \&_os2_cwd; --- 246,260 ---- *fastcwd = \&_vms_cwd; *fastgetcwd = \&_vms_cwd; } ! elsif ($^O eq 'NT' or $^O eq 'MSWin32') { ! # We assume that &_NT_cwd is defined as an XSUB or in the core. ! *getcwd = \&_NT_cwd; ! *fastcwd = \&_NT_cwd; ! *fastgetcwd = \&_NT_cwd; } elsif ($^O eq 'os2') { + *cwd = \&_os2_cwd; *getcwd = \&_os2_cwd; *fastgetcwd = \&_os2_cwd; #~ Add version check option diff -Pcr perl5_003/lib/Exporter.pm perl5_003_01/lib/Exporter.pm *** perl5_003/lib/Exporter.pm Mon Feb 12 14:54:12 1996 --- perl5_003_01/lib/Exporter.pm Tue Jun 18 22:03:00 1996 *************** *** 91,96 **** --- 91,102 ---- @imports = @exports; last; } + # We need a way to emulate 'use Foo ()' but still + # allow an easy version check: "use Foo 1.23, ''"; + if (@imports == 2 and !$imports[1]) { + @imports = (); + last; + } } elsif ($sym !~ s/^&// || !$exports{$sym}) { warn qq["$sym" is not exported by the $pkg module]; $oops++; *************** *** 176,184 **** sub require_version { my($self, $wanted) = @_; my $pkg = ref $self || $self; ! my $version = ${"${pkg}::VERSION"} || "(undef)"; ! Carp::croak("$pkg $wanted required--this is only version $version") ! if $version < $wanted; $version; } --- 182,194 ---- sub require_version { my($self, $wanted) = @_; my $pkg = ref $self || $self; ! my $version = ${"${pkg}::VERSION"}; ! if (!$version or $version < $wanted) { ! $version ||= "(undef)"; ! my $file = $INC{"$pkg.pm"}; ! $file &&= " ($file)"; ! Carp::croak("$pkg $wanted required--this is only version $version$file") ! } $version; } #~ Add ExtUtils::Embed diff -Pcr perl5_003/lib/ExtUtils/Embed.pm perl5_003_01/lib/ExtUtils/Embed.pm *** perl5_003/lib/ExtUtils/Embed.pm Wed Dec 31 19:00:00 1969 --- perl5_003_01/lib/ExtUtils/Embed.pm Sun Jul 21 19:26:02 1996 *************** *** 0 **** --- 1,473 ---- + # $Id: Embed.pm,v 1.17 1996/07/02 13:48:17 dougm Exp $ + require 5.002; + + package ExtUtils::Embed; + require Exporter; + require FileHandle; + use Config; + use Getopt::Std; + + #Only when we need them + #require ExtUtils::MakeMaker; + #require ExtUtils::Liblist; + + use vars qw(@ISA @EXPORT $VERSION + @Extensions $Verbose $lib_ext + $opt_o $opt_s + ); + use strict; + + $VERSION = sprintf("%d.%02d", q$Revision: 1.17 $ =~ /(\d+)\.(\d+)/); + #for the namespace change + $Devel::embed::VERSION = "99.99"; + + sub Version { $VERSION; } + + @ISA = qw(Exporter); + @EXPORT = qw(&xsinit &ldopts + &ccopts &ccflags &ccdlflags &perl_inc + &xsi_header &xsi_protos &xsi_body); + + #let's have Miniperl borrow from us instead + #require ExtUtils::Miniperl; + #*canon = \&ExtUtils::Miniperl::canon; + + $Verbose = 0; + $lib_ext = $Config{lib_ext} || '.a'; + + sub xsinit { + my($file, $std, $mods) = @_; + my($fh,@mods,%seen); + $file ||= "perlxsi.c"; + + if (@_) { + @mods = @$mods if $mods; + } + else { + getopts('o:s:'); + $file = $opt_o if defined $opt_o; + $std = $opt_s if defined $opt_s; + @mods = @ARGV; + } + $std = 1 unless scalar @mods; + + if ($file eq "STDOUT") { + $fh = \*STDOUT; + } + else { + $fh = new FileHandle "> $file"; + } + + push(@mods, static_ext()) if defined $std; + @mods = grep(!$seen{$_}++, @mods); + + print $fh &xsi_header(); + print $fh "EXTERN_C void xs_init _((void));\n\n"; + print $fh &xsi_protos(@mods); + + print $fh "\nEXTERN_C void\nxs_init()\n{\n"; + print $fh &xsi_body(@mods); + print $fh "}\n"; + + } + + sub xsi_header { + return < + #include + + #ifdef __cplusplus + } + # ifndef EXTERN_C + # define EXTERN_C extern "C" + # endif + #else + # ifndef EXTERN_C + # define EXTERN_C extern + # endif + #endif + + EOF + } + + sub xsi_protos { + my(@exts) = @_; + my(@retval,%seen); + + foreach $_ (@exts){ + my($pname) = canon('/', $_); + my($mname, $cname); + ($mname = $pname) =~ s!/!::!g; + ($cname = $pname) =~ s!/!__!g; + my($ccode) = "EXTERN_C void boot_${cname} _((CV* cv));\n"; + next if $seen{$ccode}++; + push(@retval, $ccode); + } + return join '', @retval; + } + + sub xsi_body { + my(@exts) = @_; + my($pname,@retval,%seen); + my($dl) = canon('/','DynaLoader'); + push(@retval, "\tdXSUB_SYS;\n") if $] > 5.002; + push(@retval, "\tchar *file = __FILE__;\n\n"); + + foreach $_ (@exts){ + my($pname) = canon('/', $_); + my($mname, $cname, $ccode); + ($mname = $pname) =~ s!/!::!g; + ($cname = $pname) =~ s!/!__!g; + if ($pname eq $dl){ + # Must NOT install 'DynaLoader::boot_DynaLoader' as 'bootstrap'! + # boot_DynaLoader is called directly in DynaLoader.pm + $ccode = "\t/* DynaLoader is a special case */\n\tnewXS(\"${mname}::boot_${cname}\", boot_${cname}, file);\n"; + push(@retval, $ccode) unless $seen{$ccode}++; + } else { + $ccode = "\tnewXS(\"${mname}::bootstrap\", boot_${cname}, file);\n"; + push(@retval, $ccode) unless $seen{$ccode}++; + } + } + return join '', @retval; + } + + sub static_ext { + unless (scalar @Extensions) { + @Extensions = sort split /\s+/, $Config{static_ext}; + unshift @Extensions, qw(DynaLoader); + } + @Extensions; + } + + sub ldopts { + require ExtUtils::MakeMaker; + require ExtUtils::Liblist; + my($std,$mods,$link_args,$path) = @_; + my(@mods,@link_args,@argv); + my($dllib,$config_libs,@potential_libs,@path); + local($") = ' ' unless $" eq ' '; + my $MM = bless {} => 'MY'; + if (scalar @_) { + @link_args = @$link_args if $link_args; + @mods = @$mods if $mods; + } + else { + @argv = @ARGV; + #hmm + while($_ = shift @argv) { + /^-std$/ && do { $std = 1; next; }; + /^--$/ && do { @link_args = @argv; last; }; + /^-I(.*)/ && do { $path = $1 || shift @argv; next; }; + push(@mods, $_); + } + } + $std = 1 unless scalar @link_args; + @path = $path ? split(/:/, $path) : @INC; + + push(@potential_libs, @link_args) if scalar @link_args; + push(@potential_libs, $Config{libs}) if defined $std; + + push(@mods, static_ext()) if $std; + + my($mod,@ns,$root,$sub,$extra,$archive,@archives); + print STDERR "Searching (@path) for archives\n" if $Verbose; + foreach $mod (@mods) { + @ns = split('::', $mod); + $sub = $ns[-1]; + $root = $MM->catdir(@ns); + + print STDERR "searching for '$sub${lib_ext}'\n" if $Verbose; + foreach (@path) { + next unless -e ($archive = $MM->catdir($_,"auto",$root,"$sub$lib_ext")); + push @archives, $archive; + if(-e ($extra = $MM->catdir($_,"auto",$root,"extralibs.ld"))) { + local(*FH); + if(open(FH, $extra)) { + my($libs) = ; chomp $libs; + push @potential_libs, split /\s+/, $libs; + } + else { + warn "Couldn't open '$extra'"; + } + } + last; + } + } + #print STDERR "\@potential_libs = @potential_libs\n"; + + my($extralibs, $bsloadlibs, $ldloadlibs, $ld_run_path) = + $MM->ext(join ' ', + $MM->catdir("-L$Config{archlib}", "CORE"), " -lperl", + @potential_libs); + + my $ld_or_bs = $bsloadlibs || $ldloadlibs; + print STDERR "bs: $bsloadlibs ** ld: $ldloadlibs" if $Verbose; + my $linkage = "$Config{ldflags} @archives $ld_or_bs"; + print STDERR "ldopts: '$linkage'\n" if $Verbose; + + return $linkage if scalar @_; + print "$linkage\n"; + } + + sub ccflags { + print " $Config{ccflags} "; + } + + sub ccdlflags { + print " $Config{ccdlflags} "; + } + + sub perl_inc { + print " -I $Config{archlib}/CORE "; + } + + sub ccopts { + ccflags; + ccdlflags; + perl_inc; + } + + sub canon { + my($as, @ext) = @_; + foreach(@ext) { + # might be X::Y or lib/auto/X/Y/Y.a + next if s!::!/!g; + s:^(lib|ext)/(auto/)?::; + s:/\w+\.\w+$::; + } + grep(s:/:$as:, @ext) if ($as ne '/'); + @ext; + } + + __END__ + + =head1 NAME + + ExtUtils::Embed - Utilities for embedding Perl in C/C++ applications + + =head1 SYNOPSIS + + + perl -MExtUtils::Embed -e xsinit + perl -MExtUtils::Embed -e ldopts + + =head1 DESCRIPTION + + ExtUtils::Embed provides utility functions for embedding a Perl interpreter + and extensions in your C/C++ applications. + Typically, an application B will invoke ExtUtils::Embed + functions while building your application. + + =head1 @EXPORT + + ExtUtils::Embed exports the following functions: + + L, L, L, L, L, + L, L, L, L + + =head1 FUNCTIONS + + =item xsinit() + + Generate C/C++ code for the XS intializer function. + + When invoked as C<`perl -MExtUtils::Embed -e xsinit --`> + the following options are recognized: + + B<-o> (Defaults to B) + + B<-o STDOUT> will print to STDOUT. + + B<-std> (Write code for extensions that are linked with the current Perl.) + + Any additional arguments are expected to be names of modules + to generate code for. + + When invoked with parameters the following are accepted and optional: + + C + + Where, + + B<$filename> is equivalent to the B<-o> option. + + B<$std> is boolean, equivalent to the B<-std> option. + + B<[@modules]> is an array ref, same as additional arguments mentioned above. + + =item Examples + + + perl -MExtUtils::Embed -e xsinit -- -o xsinit.c Socket + + + This will generate code with an B function that glues the perl B function + to the C B function and writes it to a file named "xsinit.c". + + Note that B is a special case where it must call B directly. + + perl -MExtUtils::Embed -e xsinit + + + This will generate code for linking with B and + each static extension found in B<$Config{static_ext}>. + The code is written to the default file name B. + + + perl -MExtUtils::Embed -e xsinit -- -o xsinit.c -std DBI DBD::Oracle + + + Here, code is written for all the currently linked extensions along with code + for B and B. + + If you have a working B then there is rarely any need to statically link in any + other extensions. + + =item ldopts() + + Output arguments for linking the Perl library and extensions to your + application. + + When invoked as C<`perl -MExtUtils::Embed -e ldopts --`> + the following options are recognized: + + B<-std> + + Output arguments for linking the Perl library and any extensions linked + with the current Perl. + + B<-I> + + Search path for ModuleName.a archives. + Default path is B<@INC>. + Library archives are expected to be found as + B + For example, when looking for B relative to a search path, + we should find B + + When looking for B relative to a search path, + we should find B + + Keep in mind, you can always supply B + as an additional linker argument. + + B<--> + + Additional linker arguments to be considered. + + Any additional arguments found before the B<--> token + are expected to be names of modules to generate code for. + + When invoked with parameters the following are accepted and optional: + + C + + Where, + + B<$std> is boolean, equivalent to the B<-std> option. + + B<[@modules]> is equivalent to additional arguments found before the B<--> token. + + B<[@link_args]> is equivalent to arguments found after the B<--> token. + + B<$path> is equivalent to the B<-I> option. + + In addition, when ldopts is called with parameters, it will return the argument string + rather than print it to STDOUT. + + =item Examples + + + perl -MExtUtils::Embed -e ldopts + + + This will print arguments for linking with B, B and + extensions found in B<$Config{static_ext}>. This includes libraries + found in B<$Config{libs}> and the first ModuleName.a library + for each extension that is found by searching B<@INC> or the path + specifed by the B<-I> option. + In addition, when ModuleName.a is found, additional linker arguments + are picked up from the B file in the same directory. + + + perl -MExtUtils::Embed -e ldopts -- -std Socket + + + This will do the same as the above example, along with printing additional arguments for linking with the B extension. + + + perl -MExtUtils::Embed -e ldopts -- DynaLoader + + + This will print arguments for linking with just the B extension + and B. + + + perl -MExtUtils::Embed -e ldopts -- -std Msql -- -L/usr/msql/lib -lmsql + + + Any arguments after the second '--' token are additional linker + arguments that will be examined for potential conflict. If there is no + conflict, the additional arguments will be part of the output. + + + =item perl_inc() + + For including perl header files this function simply prints: + + -I $Config{archlib}/CORE + + So, rather than having to say: + + perl -MConfig -e 'print "-I $Config{archlib}/CORE"' + + Just say: + + perl -MExtUtils::Embed -e perl_inc + + =item ccflags(), ccdlflags() + + These functions simply print $Config{ccflags} and $Config{ccdlflags} + + =item ccopts() + + This function combines perl_inc(), ccflags() and ccdlflags() into one. + + =item xsi_header() + + This function simply returns a string defining the same B macro as + B along with #including B and B. + + =item xsi_protos(@modules) + + This function returns a string of B prototypes for each @modules. + + =item xsi_body(@modules) + + This function returns a string of calls to B that glue the module B + function to B for each @modules. + + B uses the xsi_* functions to generate most of it's code. + + =head1 EXAMPLES + + For examples on how to use B for building C/C++ applications + with embedded perl, see the eg/ directory and the I man page. + + =head1 SEE ALSO + + the I man page + + =head1 AUTHOR + + Doug MacEachern + + Based on ideas from Tim Bunce and + B by Andreas Koenig and Tim Bunce. + + =cut + #~ NeXT-specific support diff -Pcr perl5_003/lib/ExtUtils/Liblist.pm perl5_003_01/lib/ExtUtils/Liblist.pm *** perl5_003/lib/ExtUtils/Liblist.pm Sun Jun 23 20:52:37 1996 --- perl5_003_01/lib/ExtUtils/Liblist.pm Thu Jul 11 12:31:00 1996 *************** *** 2,8 **** # Broken out of MakeMaker from version 4.11 ! $ExtUtils::Liblist::VERSION = substr q$Revision: 1.19 $, 10; use Config; use Cwd 'cwd'; --- 2,8 ---- # Broken out of MakeMaker from version 4.11 ! $ExtUtils::Liblist::VERSION = substr q$Revision: 1.20 $, 10; use Config; use Cwd 'cwd'; *************** *** 135,149 **** # Do not add it into the list if it is already linked in # with the main perl executable. ! # We have to special-case the NeXT, because all the math ! # is also in libsys_s unless ($in_perl || ! ($^O eq 'next' && $thislib eq 'm') ){ push(@extralibs, "-l$thislib"); } # We might be able to load this archive file dynamically ! if ( $Config{'dlsrc'} =~ /dl_next|dl_dld/){ # We push -l$thislib instead of $fullname because # it avoids hardwiring a fixed path into the .bs file. # Mkbootstrap will automatically add dl_findfile() to --- 135,152 ---- # Do not add it into the list if it is already linked in # with the main perl executable. ! # We have to special-case the NeXT, because math and ndbm ! # are both in libsys_s unless ($in_perl || ! ($Config{'osname'} eq 'next' && ! ($thislib eq 'm' || $thislib eq 'ndbm')) ){ push(@extralibs, "-l$thislib"); } # We might be able to load this archive file dynamically ! if ( ($Config{'dlsrc'} =~ /dl_next/ && $Config{'osvers'} lt '4_0') ! || ($Config{'dlsrc'} =~ /dl_dld/) ) ! { # We push -l$thislib instead of $fullname because # it avoids hardwiring a fixed path into the .bs file. # Mkbootstrap will automatically add dl_findfile() to #~ Use negative substr position argument for efficiency #~ SelfLoad most routines so they're not loaded if overridden #~ Add MAB support for NeXT #~ Store INST_*DIR macros in $self hash, so they can be used in overrides #~ Skip all symlinks, not just directories, in libscan #~ Use case-insensitive pattern when trimming $striplibpath #~ Substitute '.' for empty components of PATH #~ Remove $(INST_STATIC) only if we rebuild it diff -Pcr perl5_003/lib/ExtUtils/MM_Unix.pm perl5_003_01/lib/ExtUtils/MM_Unix.pm *** perl5_003/lib/ExtUtils/MM_Unix.pm Mon Jun 24 16:14:28 1996 --- perl5_003_01/lib/ExtUtils/MM_Unix.pm Wed Jul 24 13:28:53 1996 *************** *** 1,7 **** package ExtUtils::MM_Unix; ! $VERSION = substr q$Revision: 1.101 $, 10; ! # $Id: MM_Unix.pm,v 1.101 1996/06/23 20:51:18 k Exp k $ require Exporter; use Config; --- 1,7 ---- package ExtUtils::MM_Unix; ! $VERSION = substr q$Revision: 1.105 $, 10; ! # $Id: MM_Unix.pm,v 1.105 1996/07/08 20:51:18 k Exp k $ require Exporter; use Config; *************** *** 97,108 **** my @args = @_; for (@args) { # append a slash to each argument unless it has one there ! $_ .= "/" unless substr($_,length($_)-1,1) eq "/"; } my $result = join('', @args); # remove a trailing slash unless we are root ! substr($result,length($result)-1,1) = "" ! if length($result) > 1 && substr($result,length($result)-1,1) eq "/"; $result; } --- 97,108 ---- my @args = @_; for (@args) { # append a slash to each argument unless it has one there ! $_ .= "/" if $_ eq '' or substr($_,-1) ne "/"; } my $result = join('', @args); # remove a trailing slash unless we are root ! substr($result,-1) = "" ! if length($result) > 1 && substr($result,-1) eq "/"; $result; } *************** *** 227,236 **** package ExtUtils::MM_Unix; ! #use SelfLoader; 1; ! #__DATA__ =head2 SelfLoaded methods --- 227,237 ---- package ExtUtils::MM_Unix; ! use SelfLoader; 1; ! ! __DATA__ =head2 SelfLoaded methods *************** *** 249,255 **** my(@m); push @m, ' .c$(OBJ_EXT): ! $(CCCMD) $(CCCDLFLAGS) -I$(PERL_INC) $(DEFINE) $*.c .C$(OBJ_EXT): $(CCCMD) $(CCCDLFLAGS) -I$(PERL_INC) $(DEFINE) $*.C --- 250,256 ---- my(@m); push @m, ' .c$(OBJ_EXT): ! $(CCCMD) $(MAB) $(CCCDLFLAGS) -I$(PERL_INC) $(DEFINE) $*.c .C$(OBJ_EXT): $(CCCMD) $(CCCDLFLAGS) -I$(PERL_INC) $(DEFINE) $*.C *************** *** 564,579 **** # Where is the Config information that we are using/depend on CONFIGDEP = \$(PERL_ARCHLIB)/Config.pm \$(PERL_INC)/config.h - }; - my @parentdir = split(/::/, $self->{PARENT_NAME}); - push @m, q{ # Where to put things: ! INST_LIBDIR = }. $self->catdir('$(INST_LIB)',@parentdir) .q{ ! INST_ARCHLIBDIR = }. $self->catdir('$(INST_ARCHLIB)',@parentdir) .q{ ! INST_AUTODIR = }. $self->catdir('$(INST_LIB)','auto','$(FULLEXT)') .q{ ! INST_ARCHAUTODIR = }. $self->catdir('$(INST_ARCHLIB)','auto','$(FULLEXT)') .q{ }; if ($self->has_link_code()) { --- 565,577 ---- # Where is the Config information that we are using/depend on CONFIGDEP = \$(PERL_ARCHLIB)/Config.pm \$(PERL_INC)/config.h # Where to put things: ! INST_LIBDIR = $self->{INST_LIBDIR} ! INST_ARCHLIBDIR = $self->{INST_ARCHLIBDIR} ! INST_AUTODIR = $self->{INST_AUTODIR} ! INST_ARCHAUTODIR = $self->{INST_ARCHAUTODIR} }; if ($self->has_link_code()) { *************** *** 991,997 **** } $ldfrom = "-all $ldfrom -none" if ($^O eq 'dec_osf'); push(@m,' LD_RUN_PATH="$(LD_RUN_PATH)" $(LD) -o $@ $(LDDLFLAGS) '.$ldfrom. ! ' $(OTHERLDFLAGS) $(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) $(EXPORT_LIST)'); push @m, ' $(CHMOD) 755 $@ '; --- 989,995 ---- } $ldfrom = "-all $ldfrom -none" if ($^O eq 'dec_osf'); push(@m,' LD_RUN_PATH="$(LD_RUN_PATH)" $(LD) -o $@ $(LDDLFLAGS) '.$ldfrom. ! ' $(OTHERLDFLAGS) $(MAB) $(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) $(EXPORT_LIST)'); push @m, ' $(CHMOD) 755 $@ '; *************** *** 1149,1156 **** foreach $name ($self->lsdir($self->curdir)){ next if $name eq $self->curdir or $name eq $self->updir or $ignore{$name}; next unless $self->libscan($name); if (-d $name){ - next if -l $name; # We do not support symlinks at all $dir{$name} = $name if (-f $self->catfile($name,"Makefile.PL")); } elsif ($name =~ /\.xs$/){ my($c); ($c = $name) =~ s/\.xs$/.c/; --- 1147,1154 ---- foreach $name ($self->lsdir($self->curdir)){ next if $name eq $self->curdir or $name eq $self->updir or $ignore{$name}; next unless $self->libscan($name); + next if -l $name; # We do not support symlinks at all if (-d $name){ $dir{$name} = $name if (-f $self->catfile($name,"Makefile.PL")); } elsif ($name =~ /\.xs$/){ my($c); ($c = $name) =~ s/\.xs$/.c/; *************** *** 1224,1230 **** } my($path, $prefix) = ($File::Find::name, '$(INST_LIBDIR)'); my($striplibpath,$striplibname); ! $prefix = '$(INST_LIB)' if (($striplibpath = $path) =~ s:^(\W*)lib\W:$1:); ($striplibname,$striplibpath) = fileparse($striplibpath); my($inst) = $self->catfile($prefix,$striplibpath,$striplibname); local($_) = $inst; # for backwards compatibility --- 1222,1228 ---- } my($path, $prefix) = ($File::Find::name, '$(INST_LIBDIR)'); my($striplibpath,$striplibname); ! $prefix = '$(INST_LIB)' if (($striplibpath = $path) =~ s:^(\W*)lib\W:$1:i); ($striplibname,$striplibpath) = fileparse($striplibpath); my($inst) = $self->catfile($prefix,$striplibpath,$striplibname); local($_) = $inst; # for backwards compatibility *************** *** 1476,1481 **** --- 1474,1486 ---- $self->{INST_ARCHLIB} ||= $self->catdir($self->curdir,"blib","arch"); $self->{INST_BIN} ||= $self->catdir($self->curdir,'blib','bin'); + # We need to set up INST_LIBDIR before init_libscan() for VMS + my @parentdir = split(/::/, $self->{PARENT_NAME}); + $self->{INST_LIBDIR} = $self->catdir('$(INST_LIB)',@parentdir); + $self->{INST_ARCHLIBDIR} = $self->catdir('$(INST_ARCHLIB)',@parentdir); + $self->{INST_AUTODIR} = $self->catdir('$(INST_LIB)','auto','$(FULLEXT)'); + $self->{INST_ARCHAUTODIR} = $self->catdir('$(INST_ARCHLIB)','auto','$(FULLEXT)'); + # INST_EXE is deprecated, should go away March '97 $self->{INST_EXE} ||= $self->catdir($self->curdir,'blib','script'); $self->{INST_SCRIPT} ||= $self->catdir($self->curdir,'blib','script'); *************** *** 1965,1970 **** --- 1970,1976 ---- $linkcmd = join ' ', "\$(CC)", grep($_, @Config{qw(large split ldflags ccdlflags)}); $linkcmd =~ s/\s+/ /g; + $linkcmd =~ s,(perl\.exp),\$(PERL_INC)/$1,; # Which *.a files could we make use of... local(%static); *************** *** 2366,2371 **** --- 2372,2379 ---- my $path = $ENV{PATH}; $path =~ s:\\:/:g if $Is_OS2; my @path = split $path_sep, $path; + foreach(@path) { $_ = '.' if $_ eq '' } + @path; } =item perl_script *************** *** 2601,2614 **** my(@m); push(@m, <<'END'); $(INST_STATIC): $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)/.exists - $(RM_RF) $@ END # If this extension has it's own library (eg SDBM_File) # then copy that to $(INST_STATIC) and add $(OBJECT) into it. push(@m, "\t$self->{CP} \$(MYEXTLIB) \$\@\n") if $self->{MYEXTLIB}; push @m, ! q{ $(AR) $(AR_STATIC_ARGS) $@ $(OBJECT) && $(RANLIB) $@ }.$self->{NOECHO}.q{echo "$(EXTRALIBS)" > $(INST_ARCHAUTODIR)/extralibs.ld $(CHMOD) 755 $@ }; --- 2609,2622 ---- my(@m); push(@m, <<'END'); $(INST_STATIC): $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)/.exists END # If this extension has it's own library (eg SDBM_File) # then copy that to $(INST_STATIC) and add $(OBJECT) into it. push(@m, "\t$self->{CP} \$(MYEXTLIB) \$\@\n") if $self->{MYEXTLIB}; push @m, ! q{ $(RM_RF) $@ ! $(AR) $(AR_STATIC_ARGS) $@ $(OBJECT) && $(RANLIB) $@ }.$self->{NOECHO}.q{echo "$(EXTRALIBS)" > $(INST_ARCHAUTODIR)/extralibs.ld $(CHMOD) 755 $@ }; *************** *** 3102,3108 **** ' .xs$(OBJ_EXT): $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $*.xs >xstmp.c && mv xstmp.c $*.c ! $(CCCMD) $(CCCDLFLAGS) -I$(PERL_INC) $(DEFINE) $*.c '; } --- 3110,3116 ---- ' .xs$(OBJ_EXT): $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $*.xs >xstmp.c && mv xstmp.c $*.c ! $(CCCMD) $(MAB) $(CCCDLFLAGS) -I$(PERL_INC) $(DEFINE) $*.c '; } #~ Fixed bugs in path cleanup functions #~ Correct sort routine in find_perl(), and reduce log messages for $Verbose=1 #~ Eliminate @ from NOOP macro; it's already supplied by NOECHO #~ Eliminate redundant \t from UMASK_NULL #~ Don't conflate /Include qualifiers; it's not necessary #~ Separate directory from non-directory macros, and clean up directories #~ Store INST_*DIR macros in $self hash, so they can be used in path fixups #~ Improve timestamp handling in pm_to_blib #~ Use $(NOECHO) macro throughout, to allow for easier override #~ Eliminate repeated declaration or my() variable. diff -Pcr perl5_003/lib/ExtUtils/MM_VMS.pm perl5_003_01/lib/ExtUtils/MM_VMS.pm *** perl5_003/lib/ExtUtils/MM_VMS.pm Mon Jun 24 17:56:22 1996 --- perl5_003_01/lib/ExtUtils/MM_VMS.pm Wed Jul 24 13:33:31 1996 *************** *** 6,12 **** # Author: Charles Bailey bailey@genetics.upenn.edu package ExtUtils::MM_VMS; ! $ExtUtils::MM_VMS::Revision=$ExtUtils::MM_VMS::Revision = '5.35 (23-Jun-1996)'; unshift @MM::ISA, 'ExtUtils::MM_VMS'; use Config; --- 6,12 ---- # Author: Charles Bailey bailey@genetics.upenn.edu package ExtUtils::MM_VMS; ! $ExtUtils::MM_VMS::Revision=$ExtUtils::MM_VMS::Revision = '5.36 (10-Jul-1996)'; unshift @MM::ISA, 'ExtUtils::MM_VMS'; use Config; *************** *** 92,98 **** } } elsif ((($prefix,$name) = ($path =~ m#^\$\(([^\)]+)\)(.+)#)) && $self->{$prefix}) { ! my($vmspre) = vmspath($self->{$prefix}) || ''; # is it a dir or just a name? $fixedpath = ($vmspre ? $vmspre : $self->{$prefix}) . $name; $fixedpath = vmspath($fixedpath) if $force_path; } --- 92,98 ---- } } elsif ((($prefix,$name) = ($path =~ m#^\$\(([^\)]+)\)(.+)#)) && $self->{$prefix}) { ! my($vmspre) = vmspath($self->eliminate_macros("\$($prefix)")) || ''; # is it a dir or just a name? $fixedpath = ($vmspre ? $vmspre : $self->{$prefix}) . $name; $fixedpath = vmspath($fixedpath) if $force_path; } *************** *** 123,131 **** my($spath,$sdir) = ($path,$dir); $spath =~ s/.dir$//; $sdir =~ s/.dir$//; $sdir = $self->eliminate_macros($sdir) unless $sdir =~ /^[\w\-]+$/; ! $rslt = vmspath($self->eliminate_macros($spath)."/$sdir"); } - else { $rslt = vmspath($dir); } print "catdir(",join(',',@_[1..$#_]),") = |$rslt|\n" if $Verbose >= 3; $rslt; } --- 123,134 ---- my($spath,$sdir) = ($path,$dir); $spath =~ s/.dir$//; $sdir =~ s/.dir$//; $sdir = $self->eliminate_macros($sdir) unless $sdir =~ /^[\w\-]+$/; ! $rslt = $self->fixpath($self->eliminate_macros($spath)."/$sdir",1); ! } ! else { ! if ($dir =~ /^\$\([^\)]+\)$/) { $rslt = $dir; } ! else { $rslt = vmspath($dir); } } print "catdir(",join(',',@_[1..$#_]),") = |$rslt|\n" if $Verbose >= 3; $rslt; } *************** *** 317,328 **** =cut ! sub find_perl{ my($self, $ver, $names, $dirs, $trace) = @_; my($name,$dir,$vmsfile,@sdirs,@snames,@cand); # Check in relative directories first, so we pick up the current # version of Perl if we're running MakeMaker as part of the main build. ! @sdirs = sort { my($absb) = file_name_is_absolute($a); my($absb) = file_name_is_absolute($b); if ($absa && $absb) { return $a cmp $b } else { return $absa ? 1 : ($absb ? -1 : ($a cmp $b)); } --- 320,331 ---- =cut ! sub find_perl { my($self, $ver, $names, $dirs, $trace) = @_; my($name,$dir,$vmsfile,@sdirs,@snames,@cand); # Check in relative directories first, so we pick up the current # version of Perl if we're running MakeMaker as part of the main build. ! @sdirs = sort { my($absa) = file_name_is_absolute($a); my($absb) = file_name_is_absolute($b); if ($absa && $absb) { return $a cmp $b } else { return $absa ? 1 : ($absb ? -1 : ($a cmp $b)); } *************** *** 334,340 **** my($bb) = $b =~ m!([^:>\]/]+)$!; substr($ba,0,1) cmp substr($bb,0,1) or -1*(length($ba) <=> length($bb)) } @$names; ! if ($trace){ print "Looking for perl $ver by these names:\n"; print "\t@snames,\n"; print "in these dirs:\n"; --- 337,343 ---- my($bb) = $b =~ m!([^:>\]/]+)$!; substr($ba,0,1) cmp substr($bb,0,1) or -1*(length($ba) <=> length($bb)) } @$names; ! if ($trace >= 2){ print "Looking for perl $ver by these names:\n"; print "\t@snames,\n"; print "in these dirs:\n"; *************** *** 483,489 **** sub init_others { my($self) = @_; ! $self->{NOOP} = "\t@ Continue"; $self->{FIRST_MAKEFILE} ||= 'Descrip.MMS'; $self->{MAKE_APERL_FILE} ||= 'Makeaperl.MMS'; $self->{MAKEFILE} ||= $self->{FIRST_MAKEFILE}; --- 486,492 ---- sub init_others { my($self) = @_; ! $self->{NOOP} = 'Continue'; $self->{FIRST_MAKEFILE} ||= 'Descrip.MMS'; $self->{MAKE_APERL_FILE} ||= 'Makeaperl.MMS'; $self->{MAKEFILE} ||= $self->{FIRST_MAKEFILE}; *************** *** 494,500 **** $self->{CHMOD} = '$(PERL) -e "chmod @ARGV"'; # expect Unix syntax from MakeMaker $self->{CP} = 'Copy/NoConfirm'; $self->{MV} = 'Rename/NoConfirm'; ! $self->{UMASK_NULL} = "\t!"; &ExtUtils::MM_Unix::init_others; } --- 497,503 ---- $self->{CHMOD} = '$(PERL) -e "chmod @ARGV"'; # expect Unix syntax from MakeMaker $self->{CP} = 'Copy/NoConfirm'; $self->{MV} = 'Rename/NoConfirm'; ! $self->{UMASK_NULL} = '! '; &ExtUtils::MM_Unix::init_others; } *************** *** 526,542 **** } $self->{LDFROM} = join(' ',map($self->fixpath($_),split(/,?\s+/,$self->{LDFROM}))); - if ($self->{'INC'} && $self->{INC} !~ m!/Include=!i) { - my(@val) = ( '/Include=(' ); - my(@includes) = split(/\s+/,$self->{INC}); - my($plural); - foreach (@includes) { - s/^-I//; - push @val,', ' if $plural++; - push @val,$self->fixpath($_,1); - } - $self->{INC} = join('',@val,')'); - } # Fix up directory specs $self->{ROOTEXT} = $self->{ROOTEXT} ? $self->fixpath($self->{ROOTEXT},1) --- 529,534 ---- *************** *** 593,600 **** ]; for $tmp (qw/ ! FULLEXT BASEEXT PARENT_NAME DLBASE VERSION_FROM INC DEFINE OBJECT ! LDFROM LINKTYPE / ) { next unless defined $self->{$tmp}; push @m, "$tmp = $self->{$tmp}\n"; --- 585,598 ---- ]; for $tmp (qw/ ! FULLEXT VERSION_FROM OBJECT LDFROM ! / ) { ! next unless defined $self->{$tmp}; ! push @m, "$tmp = ",$self->fixpath($self->{$tmp}),"\n"; ! } ! ! for $tmp (qw/ ! BASEEXT PARENT_NAME DLBASE INC DEFINE LINKTYPE / ) { next unless defined $self->{$tmp}; push @m, "$tmp = $self->{$tmp}\n"; *************** *** 644,655 **** CONFIGDEP = \$(PERL_ARCHLIB)Config.pm, \$(PERL_INC)config.h \$(VERSION_FROM) # Where to put things: ! INST_LIBDIR = ",($self->{'INST_LIBDIR'} = $self->catdir($self->{INST_LIB},$self->{ROOTEXT}))," ! INST_ARCHLIBDIR = ",($self->{'INST_ARCHLIBDIR'} = $self->catdir($self->{INST_ARCHLIB},$self->{ROOTEXT}))," ! INST_AUTODIR = ",($self->{'INST_AUTODIR'} = $self->catdir($self->{INST_LIB},'auto',$self->{FULLEXT})),' ! INST_ARCHAUTODIR = ',($self->{'INST_ARCHAUTODIR'} = $self->catdir($self->{INST_ARCHLIB},'auto',$self->{FULLEXT})),' ! '; if ($self->has_link_code()) { push @m,' --- 642,653 ---- CONFIGDEP = \$(PERL_ARCHLIB)Config.pm, \$(PERL_INC)config.h \$(VERSION_FROM) # Where to put things: ! INST_LIBDIR = $self->{INST_LIBDIR} ! INST_ARCHLIBDIR = $self->{INST_ARCHLIBDIR} ! INST_AUTODIR = $self->{INST_AUTODIR} ! INST_ARCHAUTODIR = $self->{INST_ARCHAUTODIR} ! "; if ($self->has_link_code()) { push @m,' *************** *** 686,692 **** =cut ! sub const_loadlibs{ my($self) = @_; my (@m); push @m, " --- 684,690 ---- =cut ! sub const_loadlibs { my($self) = @_; my (@m); push @m, " *************** *** 733,741 **** Bypass shell script and produce qualifiers for CC directly (but warn user if a shell script for this extension exists). Fold multiple ! /Defines into one, and do the same with /Includes, since some C ! compilers pay attention to only one instance of these qualifiers ! on the command line. =cut --- 731,738 ---- Bypass shell script and produce qualifiers for CC directly (but warn user if a shell script for this extension exists). Fold multiple ! /Defines into one, since some C compilers pay attention to only one ! instance of this qualifier on the command line. =cut *************** *** 780,789 **** $incstr .= ', '.$self->fixpath($_,1); } } ! if ($quals =~ m:(.*)/include=\(?([^\(\/\)\s]+)\)?(.*):i) { ! $quals = "$1$incstr,$2)$3"; ! } ! else { $quals .= "$incstr)"; } $optimize = '/Debug/NoOptimize' if ($self->{OPTIMIZE} =~ /-g/ or $self->{OPTIMIZE} =~ m!/Debug!i); --- 777,783 ---- $incstr .= ', '.$self->fixpath($_,1); } } ! $quals .= "$incstr)"; $optimize = '/Debug/NoOptimize' if ($self->{OPTIMIZE} =~ /-g/ or $self->{OPTIMIZE} =~ m!/Debug!i); *************** *** 851,875 **** my(@files) = @{$self->{PM_TO_BLIB}}; push @m, q{ # As always, keep under DCL's 255-char limit ! pm_to_blib : $(TO_INST_PM) ! },$self->{NOECHO},q{$(PERL) -e "print '},shift(@files),q{ },shift(@files),q{'" >.MM_tmp }; $line = ''; # avoid uninitialized var warning while ($from = shift(@files),$to = shift(@files)) { $line .= " $from $to"; if (length($line) > 128) { ! push(@m,"\t$self->{NOECHO}\$(PERL) -e \"print '$line'\" >>.MM_tmp\n"); $line = ''; } } ! push(@m,"\t$self->{NOECHO}\$(PERL) -e \"print '$line'\" >>.MM_tmp\n") if $line; push(@m,q[ $(PERL) "-I$(PERL_LIB)" "-MExtUtils::Install" -e "pm_to_blib({split(' ',)},'].$autodir.q[')" <.MM_tmp]); push(@m,qq[ ! $self->{NOECHO}Delete/NoLog/NoConfirm .MM_tmp; ! $self->{NOECHO}\$(TOUCH) pm_to_blib.ts ]); join('',@m); --- 845,875 ---- my(@files) = @{$self->{PM_TO_BLIB}}; push @m, q{ + + # Dummy target to match Unix target name; we use pm_to_blib.ts as + # timestamp file to avoid repeated invocations under VMS + pm_to_blib : pm_to_blib.ts + $(NOECHO) $(NOOP) + # As always, keep under DCL's 255-char limit ! pm_to_blib.ts : $(TO_INST_PM) ! $(NOECHO) $(PERL) -e "print '},shift(@files),q{ },shift(@files),q{'" >.MM_tmp }; $line = ''; # avoid uninitialized var warning while ($from = shift(@files),$to = shift(@files)) { $line .= " $from $to"; if (length($line) > 128) { ! push(@m,"\t\$(NOECHO) \$(PERL) -e \"print '$line'\" >>.MM_tmp\n"); $line = ''; } } ! push(@m,"\t\$(NOECHO) \$(PERL) -e \"print '$line'\" >>.MM_tmp\n") if $line; push(@m,q[ $(PERL) "-I$(PERL_LIB)" "-MExtUtils::Install" -e "pm_to_blib({split(' ',)},'].$autodir.q[')" <.MM_tmp]); push(@m,qq[ ! \$(NOECHO) Delete/NoLog/NoConfirm .MM_tmp; ! \$(NOECHO) \$(TOUCH) pm_to_blib.ts ]); join('',@m); *************** *** 1036,1041 **** --- 1036,1042 ---- RM_RF = $self->{RM_RF} UMASK_NULL = $self->{UMASK_NULL} NOOP = $self->{NOOP} + NOECHO = $self->{NOECHO} MKPATH = Create/Directory EQUALIZE_TIMESTAMP = \$(PERL) -we "open F,qq{>\$ARGV[1]};close F;utime(0,(stat(\$ARGV[0]))[9]+1,\$ARGV[1])" !. ($self->{PARENT} ? '' : *************** *** 1130,1156 **** my(@m); push @m, ' all :: pure_all manifypods ! $(NOOP) pure_all :: config pm_to_blib subdirs linkext ! $(NOOP) subdirs :: $(MYEXTLIB) ! $(NOOP) config :: $(MAKEFILE) $(INST_LIBDIR).exists ! $(NOOP) config :: $(INST_ARCHAUTODIR).exists ! $(NOOP) config :: $(INST_AUTODIR).exists ! $(NOOP) '; push @m, q{ config :: Version_check ! $(NOOP) } unless $self->{PARENT} or ($self->{PERL_SRC} && $self->{INSTALLDIRS} eq "perl") or $self->{NO_VC}; --- 1131,1157 ---- my(@m); push @m, ' all :: pure_all manifypods ! $(NOECHO) $(NOOP) pure_all :: config pm_to_blib subdirs linkext ! $(NOECHO) $(NOOP) subdirs :: $(MYEXTLIB) ! $(NOECHO) $(NOOP) config :: $(MAKEFILE) $(INST_LIBDIR).exists ! $(NOECHO) $(NOOP) config :: $(INST_ARCHAUTODIR).exists ! $(NOECHO) $(NOOP) config :: $(INST_AUTODIR).exists ! $(NOECHO) $(NOOP) '; push @m, q{ config :: Version_check ! $(NOECHO) $(NOOP) } unless $self->{PARENT} or ($self->{PERL_SRC} && $self->{INSTALLDIRS} eq "perl") or $self->{NO_VC}; *************** *** 1159,1172 **** if (%{$self->{MAN1PODS}}) { push @m, q[ config :: $(INST_MAN1DIR).exists ! $(NOOP) ]; push @m, $self->dir_target(qw[$(INST_MAN1DIR)]); } if (%{$self->{MAN3PODS}}) { push @m, q[ config :: $(INST_MAN3DIR).exists ! $(NOOP) ]; push @m, $self->dir_target(qw[$(INST_MAN3DIR)]); } --- 1160,1173 ---- if (%{$self->{MAN1PODS}}) { push @m, q[ config :: $(INST_MAN1DIR).exists ! $(NOECHO) $(NOOP) ]; push @m, $self->dir_target(qw[$(INST_MAN1DIR)]); } if (%{$self->{MAN3PODS}}) { push @m, q[ config :: $(INST_MAN3DIR).exists ! $(NOECHO) $(NOOP) ]; push @m, $self->dir_target(qw[$(INST_MAN3DIR)]); } *************** *** 1182,1188 **** push @m, q{ Version_check : ! },$self->{NOECHO},q{$(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" - "-MExtUtils::MakeMaker=Version_check" -e "&Version_check('$(MM_VERSION)')" }; --- 1183,1189 ---- push @m, q{ Version_check : ! $(NOECHO) $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" - "-MExtUtils::MakeMaker=Version_check" -e "&Version_check('$(MM_VERSION)')" }; *************** *** 1210,1221 **** unless ($self->{SKIPHASH}{'dynamic'}) { push(@m,' dynamic :: rtls.opt $(INST_ARCHAUTODIR)$(BASEEXT).opt ! $(NOOP) '); if ($srcdir) { my($popt) = $self->catfile($srcdir,'perlshr.opt'); my($lopt) = $self->catfile($srcdir,'crtl.opt'); ! push(@m,"# Depend on $(BASEEXT).opt to insure we copy here *after* autogenerating (wrong) rtls.opt in Mksymlists rtls.opt : $popt $lopt \$(BASEEXT).opt Copy/Log $popt Sys\$Disk:[]rtls.opt Append/Log $lopt Sys\$Disk:[]rtls.opt --- 1211,1222 ---- unless ($self->{SKIPHASH}{'dynamic'}) { push(@m,' dynamic :: rtls.opt $(INST_ARCHAUTODIR)$(BASEEXT).opt ! $(NOECHO) $(NOOP) '); if ($srcdir) { my($popt) = $self->catfile($srcdir,'perlshr.opt'); my($lopt) = $self->catfile($srcdir,'crtl.opt'); ! push(@m,"# Depend on \$(BASEEXT).opt to insure we copy here *after* autogenerating (wrong) rtls.opt in Mksymlists rtls.opt : $popt $lopt \$(BASEEXT).opt Copy/Log $popt Sys\$Disk:[]rtls.opt Append/Log $lopt Sys\$Disk:[]rtls.opt *************** *** 1232,1238 **** push(@m,' static :: $(INST_ARCHAUTODIR)$(BASEEXT).opt ! $(NOOP) ') unless $self->{SKIPHASH}{'static'}; push(@m,' --- 1233,1239 ---- push(@m,' static :: $(INST_ARCHAUTODIR)$(BASEEXT).opt ! $(NOECHO) $(NOOP) ') unless $self->{SKIPHASH}{'static'}; push(@m,' *************** *** 1272,1278 **** "; push @m, ' $(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt rtls.opt $(INST_ARCHAUTODIR).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP) ! ',$self->{NOECHO},'$(MKPATH) $(INST_ARCHAUTODIR) Link $(LDFLAGS) /Shareable=$(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,rtls.opt/Option,$(PERL_INC)perlshr_attr.opt/Option '; --- 1273,1280 ---- "; push @m, ' $(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt rtls.opt $(INST_ARCHAUTODIR).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP) ! $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR) ! $(NOECHO) If F$TrnLNm("PerlShr").eqs."" Then Define/NoLog/User PerlShr Sys$Share:PerlShr.Exe Link $(LDFLAGS) /Shareable=$(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,rtls.opt/Option,$(PERL_INC)perlshr_attr.opt/Option '; *************** *** 1298,1310 **** # we use touch to prevent make continually trying to remake it. # The DynaLoader only reads a non-empty file. $(BOOTSTRAP) : $(MAKEFILE) '."$self->{BOOTDEP}".' $(INST_ARCHAUTODIR).exists ! '.$self->{NOECHO}.'Write Sys$Output "Running mkbootstrap for $(NAME) ($(BSLOADLIBS))" ! '.$self->{NOECHO}.'$(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" - -e "use ExtUtils::Mkbootstrap; Mkbootstrap(\'$(BASEEXT)\',\'$(BSLOADLIBS)\');" ! '.$self->{NOECHO}.' $(TOUCH) $(MMS$TARGET) $(INST_BOOT) : $(BOOTSTRAP) $(INST_ARCHAUTODIR).exists ! '.$self->{NOECHO}.'$(RM_RF) $(INST_BOOT) - $(CP) $(BOOTSTRAP) $(INST_BOOT) '; } --- 1300,1312 ---- # we use touch to prevent make continually trying to remake it. # The DynaLoader only reads a non-empty file. $(BOOTSTRAP) : $(MAKEFILE) '."$self->{BOOTDEP}".' $(INST_ARCHAUTODIR).exists ! $(NOECHO) Write Sys$Output "Running mkbootstrap for $(NAME) ($(BSLOADLIBS))" ! $(NOECHO) $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" - -e "use ExtUtils::Mkbootstrap; Mkbootstrap(\'$(BASEEXT)\',\'$(BSLOADLIBS)\');" ! $(NOECHO) $(TOUCH) $(MMS$TARGET) $(INST_BOOT) : $(BOOTSTRAP) $(INST_ARCHAUTODIR).exists ! $(NOECHO) $(RM_RF) $(INST_BOOT) - $(CP) $(BOOTSTRAP) $(INST_BOOT) '; } *************** *** 1321,1327 **** return ' $(INST_STATIC) : ! $(NOOP) ' unless ($self->{OBJECT} or @{$self->{C} || []} or $self->{MYEXTLIB}); my(@m); --- 1323,1329 ---- return ' $(INST_STATIC) : ! $(NOECHO) $(NOOP) ' unless ($self->{OBJECT} or @{$self->{C} || []} or $self->{MYEXTLIB}); my(@m); *************** *** 1338,1344 **** push(@m,' If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET) Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST) ! ',$self->{NOECHO},'$(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR)extralibs.ld\';print F qq[$(EXTRALIBS)\n];close F;" '); push @m, $self->dir_target('$(INST_ARCHAUTODIR)'); join('',@m); --- 1340,1346 ---- push(@m,' If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET) Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST) ! $(NOECHO) $(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR)extralibs.ld\';print F qq[$(EXTRALIBS)\n];close F;" '); push @m, $self->dir_target('$(INST_ARCHAUTODIR)'); join('',@m); *************** *** 1358,1365 **** # # push(@m, " # $inst : $dist \$(MAKEFILE) ${instdir}.exists \$(INST_ARCHAUTODIR).exists ! # ",' ',$self->{NOECHO},'$(RM_F) $(MMS$TARGET) ! # ',$self->{NOECHO},'$(CP) ',"$dist $inst",' # $(CHMOD) 644 $(MMS$TARGET) # '); # push(@m, ' $(AUTOSPLITFILE) $(MMS$TARGET) ', --- 1360,1367 ---- # # push(@m, " # $inst : $dist \$(MAKEFILE) ${instdir}.exists \$(INST_ARCHAUTODIR).exists ! # ",' $(NOECHO) $(RM_F) $(MMS$TARGET) ! # $(NOECHO) $(CP) ',"$dist $inst",' # $(CHMOD) 644 $(MMS$TARGET) # '); # push(@m, ' $(AUTOSPLITFILE) $(MMS$TARGET) ', *************** *** 1380,1386 **** sub manifypods { my($self, %attribs) = @_; ! return "\nmanifypods :\n\t\$(NOOP)\n" unless %{$self->{MAN3PODS}} or %{$self->{MAN1PODS}}; my($dist); my($pod2man_exe); if (defined $self->{PERL_SRC}) { --- 1382,1388 ---- sub manifypods { my($self, %attribs) = @_; ! return "\nmanifypods :\n\t\$(NOECHO) \$(NOOP)\n" unless %{$self->{MAN3PODS}} or %{$self->{MAN1PODS}}; my($dist); my($pod2man_exe); if (defined $self->{PERL_SRC}) { *************** *** 1436,1442 **** foreach $plfile (sort keys %{$self->{PL_FILES}}) { push @m, " all :: $self->{PL_FILES}->{$plfile} ! \$(NOOP) $self->{PL_FILES}->{$plfile} :: $plfile ",' $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" '," $plfile --- 1438,1444 ---- foreach $plfile (sort keys %{$self->{PL_FILES}}) { push @m, " all :: $self->{PL_FILES}->{$plfile} ! \$(NOECHO) \$(NOOP) $self->{PL_FILES}->{$plfile} :: $plfile ",' $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" '," $plfile *************** *** 1470,1476 **** EXE_FILES = @{$self->{EXE_FILES}} all :: @to ! \$(NOOP) realclean :: "; --- 1472,1478 ---- EXE_FILES = @{$self->{EXE_FILES}} all :: @to ! \$(NOECHO) \$(NOOP) realclean :: "; *************** *** 1541,1547 **** push( @m, ' If F$Search("'.$vmsdir.'$(MAKEFILE)") Then \\',"\n\t", '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS) clean`;"',"\n"); } ! push @m, ' $(RM_F) *.Map *.Dmp *.Lis *.cpp *.$(DLEXT) *$(OBJ_EXT) *$(LIB_EXT) *.Opt $(BOOTSTRAP) $(BASEEXT).bso '; my(@otherfiles) = values %{$self->{XS}}; # .c files from *.xs files --- 1543,1549 ---- push( @m, ' If F$Search("'.$vmsdir.'$(MAKEFILE)") Then \\',"\n\t", '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS) clean`;"',"\n"); } ! push @m, ' $(RM_F) *.Map *.Dmp *.Lis *.cpp *.$(DLEXT) *$(OBJ_EXT) *$(LIB_EXT) *.Opt $(BOOTSTRAP) $(BASEEXT).bso .MM_Tmp '; my(@otherfiles) = values %{$self->{XS}}; # .c files from *.xs files *************** *** 1558,1564 **** } else { $line .= " $file"; } } ! push @m, "\t\$(RM_RF) $line\n" if line; push(@m, " $attribs{POSTOP}\n") if $attribs{POSTOP}; join('', @m); } --- 1560,1566 ---- } else { $line .= " $file"; } } ! push @m, "\t\$(RM_RF) $line\n" if $line; push(@m, " $attribs{POSTOP}\n") if $attribs{POSTOP}; join('', @m); } *************** *** 1630,1636 **** my($self) = @_; ' distclean :: realclean distcheck ! $(NOOP) distcheck : $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&fullcheck\'; fullcheck()" --- 1632,1638 ---- my($self) = @_; ' distclean :: realclean distcheck ! $(NOECHO) $(NOOP) distcheck : $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&fullcheck\'; fullcheck()" *************** *** 1654,1663 **** my($self) = @_; q[ dist : $(DIST_DEFAULT) ! ].$self->{NOECHO}.q[$(PERL) -le "print 'Warning: $m older than $vf' if -e ($vf = '$(VERSION_FROM)') && -M $vf < -M ($m = '$(MAKEFILE)'" zipdist : $(DISTVNAME).zip ! $(NOOP) $(DISTVNAME).zip : distdir $(PREOP) --- 1656,1665 ---- my($self) = @_; q[ dist : $(DIST_DEFAULT) ! $(NOECHO) $(PERL) -le "print 'Warning: $m older than $vf' if -e ($vf = '$(VERSION_FROM)') && -M $vf < -M ($m = '$(MAKEFILE)'" zipdist : $(DISTVNAME).zip ! $(NOECHO) $(NOOP) $(DISTVNAME).zip : distdir $(PREOP) *************** *** 1744,1827 **** push @m, q[ install :: all pure_install doc_install ! $(NOOP) install_perl :: all pure_perl_install doc_perl_install ! $(NOOP) install_site :: all pure_site_install doc_site_install ! $(NOOP) install_ :: install_site ! ],$self->{NOECHO},q[Write Sys$Output "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site" pure_install :: pure_$(INSTALLDIRS)_install ! $(NOOP) doc_install :: doc_$(INSTALLDIRS)_install ! ],$self->{NOECHO},q[Write Sys$Output "Appending installation info to $(INST_ARCHLIB)perllocal.pod" pure__install : pure_site_install ! ],$self->{NOECHO},q[Write Sys$Output "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site" doc__install : doc_site_install ! ],$self->{NOECHO},q[Write Sys$Output "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site" # This hack brought to you by DCL's 255-character command line limit pure_perl_install :: ! ].$self->{NOECHO}.q[$(PERL) -e "print 'read ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[ '" >.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print 'write ].$self->catfile('$(INSTALLARCHLIB)','auto','$(FULLEXT)','.packlist').q[ '" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_LIB) $(INSTALLPRIVLIB) '" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLARCHLIB) '" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp $(MOD_INSTALL) <.MM_tmp ! ].$self->{NOECHO}.q[Delete/NoLog/NoConfirm .MM_tmp; ! ].$self->{NOECHO}.q[$(WARN_IF_OLD_PACKLIST) ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q[ # Likewise pure_site_install :: ! ].$self->{NOECHO}.q[$(PERL) -e "print 'read ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q[ '" >.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print 'write ].$self->catfile('$(INSTALLSITEARCH)','auto','$(FULLEXT)','.packlist').q[ '" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_LIB) $(INSTALLSITELIB) '" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLSITEARCH) '" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp $(MOD_INSTALL) <.MM_tmp ! ].$self->{NOECHO}.q[Delete/NoLog/NoConfirm .MM_tmp; ! ].$self->{NOECHO}.q[$(WARN_IF_OLD_PACKLIST) ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[ # Ditto doc_perl_install :: ! ].$self->{NOECHO}.q[$(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLPRIVLIB)|'" >.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|'" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|'" >>.MM_tmp ! ],@docfiles,q[ $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[ ! ].$self->{NOECHO}.q[Delete/NoLog/NoConfirm .MM_tmp; # And again doc_site_install :: ! ].$self->{NOECHO}.q[$(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLSITELIB)|'" >.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|'" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|'" >>.MM_tmp ! ],@docfiles,q[ $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[ ! ].$self->{NOECHO}.q[Delete/NoLog/NoConfirm .MM_tmp; ]; push @m, q[ uninstall :: uninstall_from_$(INSTALLDIRS)dirs ! $(NOOP) uninstall_from_perldirs :: ! ].$self->{NOECHO}.q[$(UNINSTALL) ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[ uninstall_from_sitedirs :: ! ].$self->{NOECHO}.q[$(UNINSTALL) ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist')."\n"; join('',@m); } --- 1746,1839 ---- push @m, q[ install :: all pure_install doc_install ! $(NOECHO) $(NOOP) install_perl :: all pure_perl_install doc_perl_install ! $(NOECHO) $(NOOP) install_site :: all pure_site_install doc_site_install ! $(NOECHO) $(NOOP) install_ :: install_site ! $(NOECHO) Write Sys$Output "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site" pure_install :: pure_$(INSTALLDIRS)_install ! $(NOECHO) $(NOOP) doc_install :: doc_$(INSTALLDIRS)_install ! $(NOECHO) Write Sys$Output "Appending installation info to $(INST_ARCHLIB)perllocal.pod" pure__install : pure_site_install ! $(NOECHO) Write Sys$Output "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site" doc__install : doc_site_install ! $(NOECHO} Write Sys$Output "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site" # This hack brought to you by DCL's 255-character command line limit pure_perl_install :: ! $(NOECHO) $(PERL) -e "print 'read ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[ '" >.MM_tmp ! $(NOECHO) $(PERL) -e "print 'write ].$self->catfile('$(INSTALLARCHLIB)','auto','$(FULLEXT)','.packlist').q[ '" >>.MM_tmp ! $(NOECHO) $(PERL) -e "print '$(INST_LIB) $(INSTALLPRIVLIB) '" >>.MM_tmp ! $(NOECHO) $(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLARCHLIB) '" >>.MM_tmp ! $(NOECHO) $(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp ! $(NOECHO) $(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp ! $(NOECHO) $(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp ! $(NOECHO) $(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp $(MOD_INSTALL) <.MM_tmp ! $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp; ! $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q[ # Likewise pure_site_install :: ! $(NOECHO) $(PERL) -e "print 'read ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q[ '" >.MM_tmp ! $(NOECHO) $(PERL) -e "print 'write ].$self->catfile('$(INSTALLSITEARCH)','auto','$(FULLEXT)','.packlist').q[ '" >>.MM_tmp ! $(NOECHO) $(PERL) -e "print '$(INST_LIB) $(INSTALLSITELIB) '" >>.MM_tmp ! $(NOECHO) $(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLSITEARCH) '" >>.MM_tmp ! $(NOECHO) $(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp ! $(NOECHO) $(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp ! $(NOECHO) $(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp ! $(NOECHO) $(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp $(MOD_INSTALL) <.MM_tmp ! $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp; ! $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[ # Ditto doc_perl_install :: ! $(NOECHO) $(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLPRIVLIB)|'" >.MM_tmp ! $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|'" >>.MM_tmp ! $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|'" >>.MM_tmp ! ],@docfiles, ! q[ $(NOECHO) $(PERL) -e "print q[@ARGV=split('|',);]" >.MM2_tmp ! $(NOECHO) $(PERL) -e "print q[print '=head3',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];]" >>.MM2_tmp ! $(NOECHO) $(PERL) -e "print q[while(($key=shift) && ($val=shift)) ]" >>.MM2_tmp ! $(NOECHO) $(PERL) -e "print q[{print qq[=item *\\n\\nC<$key: $val>\\n\\n];}print qq[=back\\n\\n];]" >>.MM2_tmp ! $(NOECHO) $(PERL) .MM2_tmp <.MM_tmp >>].$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[ ! $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;,.MM2_tmp; # And again doc_site_install :: ! $(NOECHO) $(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLSITELIB)|'" >.MM_tmp ! $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|'" >>.MM_tmp ! $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|'" >>.MM_tmp ! ],@docfiles, ! q[ $(NOECHO) $(PERL) -e "print q[@ARGV=split('|',);]" >.MM2_tmp ! $(NOECHO) $(PERL) -e "print q[print '=head3',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];]" >>.MM2_tmp ! $(NOECHO) $(PERL) -e "print q[while(($key=shift) && ($val=shift)) ]" >>.MM2_tmp ! $(NOECHO) $(PERL) -e "print q[{print qq[=item *\\n\\nC<$key: $val>\\n\\n];}print qq[=back\\n\\n];]" >>.MM2_tmp ! $(NOECHO) $(PERL) .MM2_tmp <.MM_tmp >>].$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[ ! $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;,.MM2_tmp; ]; push @m, q[ uninstall :: uninstall_from_$(INSTALLDIRS)dirs ! $(NOECHO) $(NOOP) uninstall_from_perldirs :: ! $(NOECHO) $(UNINSTALL) ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[ uninstall_from_sitedirs :: ! $(NOECHO) $(UNINSTALL) ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist')."\n"; join('',@m); } *************** *** 1866,1876 **** # An out of date config.h is not fatal but complains loudly! #$(PERL_INC)config.h : $(PERL_SRC)config.sh $(PERL_INC)config.h : $(PERL_VMS)config.vms ! ],$self->{NOECHO},q[Write Sys$Error "Warning: $(PERL_INC)config.h out of date with $(PERL_VMS)config.vms" #$(PERL_ARCHLIB)Config.pm : $(PERL_SRC)config.sh $(PERL_ARCHLIB)Config.pm : $(PERL_VMS)config.vms $(PERL_VMS)genconfig.pl ! ],$self->{NOECHO},q[Write Sys$Error "$(PERL_ARCHLIB)Config.pm may be out of date with config.vms or genconfig.pl" olddef = F$Environment("Default") Set Default $(PERL_SRC) $(MMS)],$mmsquals,q[ $(MMS$TARGET) --- 1878,1888 ---- # An out of date config.h is not fatal but complains loudly! #$(PERL_INC)config.h : $(PERL_SRC)config.sh $(PERL_INC)config.h : $(PERL_VMS)config.vms ! $(NOECHO) Write Sys$Error "Warning: $(PERL_INC)config.h out of date with $(PERL_VMS)config.vms" #$(PERL_ARCHLIB)Config.pm : $(PERL_SRC)config.sh $(PERL_ARCHLIB)Config.pm : $(PERL_VMS)config.vms $(PERL_VMS)genconfig.pl ! $(NOECHO) Write Sys$Error "$(PERL_ARCHLIB)Config.pm may be out of date with config.vms or genconfig.pl" olddef = F$Environment("Default") Set Default $(PERL_SRC) $(MMS)],$mmsquals,q[ $(MMS$TARGET) *************** *** 1904,1916 **** # We take a very conservative approach here, but it\'s worth it. # We move $(MAKEFILE) to $(MAKEFILE)_old here to avoid gnu make looping. $(MAKEFILE) : Makefile.PL $(CONFIGDEP) ! ],$self->{NOECHO},q[Write Sys$Output "$(MAKEFILE) out-of-date with respect to $(MMS$SOURCE_LIST)" ! ],$self->{NOECHO},q[Write Sys$Output "Cleaning current config before rebuilding $(MAKEFILE) ..." - $(MV) $(MAKEFILE) $(MAKEFILE)_old - $(MMS) $(USEMAKEFILE)$(MAKEFILE)_old clean $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL ],join(' ',map(qq["$_"],@ARGV)),q[ ! ],$self->{NOECHO},q[Write Sys$Output "$(MAKEFILE) has been rebuilt." ! ],$self->{NOECHO},q[Write Sys$Output "Please run $(MMS) to build the extension." ]; join('',@m); --- 1916,1928 ---- # We take a very conservative approach here, but it\'s worth it. # We move $(MAKEFILE) to $(MAKEFILE)_old here to avoid gnu make looping. $(MAKEFILE) : Makefile.PL $(CONFIGDEP) ! $(NOECHO) Write Sys$Output "$(MAKEFILE) out-of-date with respect to $(MMS$SOURCE_LIST)" ! $(NOECHO) Write Sys$Output "Cleaning current config before rebuilding $(MAKEFILE) ..." - $(MV) $(MAKEFILE) $(MAKEFILE)_old - $(MMS) $(USEMAKEFILE)$(MAKEFILE)_old clean $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL ],join(' ',map(qq["$_"],@ARGV)),q[ ! $(NOECHO) Write Sys$Output "$(MAKEFILE) has been rebuilt." ! $(NOECHO) Write Sys$Output "Please run $(MMS) to build the extension." ]; join('',@m); *************** *** 1933,1942 **** TESTDB_SW = -d test :: \$(TEST_TYPE) ! \$(NOOP) testdb :: testdb_\$(LINKTYPE) ! \$(NOOP) "; foreach(@{$self->{DIR}}){ --- 1945,1954 ---- TESTDB_SW = -d test :: \$(TEST_TYPE) ! \$(NOECHO) \$(NOOP) testdb :: testdb_\$(LINKTYPE) ! \$(NOECHO) \$(NOOP) "; foreach(@{$self->{DIR}}){ *************** *** 1944,1957 **** push(@m, ' If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir ',"'$vmsdir'", '; print `$(MMS) $(PASTHRU2) test`'."\n"); } ! push(@m, "\t$self->{NOECHO}Write Sys\$Output \"No tests defined for \$(NAME) extension.\"\n") unless $tests or -f "test.pl" or @{$self->{DIR}}; push(@m, "\n"); push(@m, "test_dynamic :: pure_all\n"); push(@m, $self->test_via_harness('$(FULLPERL)', $tests)) if $tests; push(@m, $self->test_via_script('$(FULLPERL)', 'test.pl')) if -f "test.pl"; ! push(@m, " \$(NOOP)\n") if (!$tests && ! -f "test.pl"); push(@m, "\n"); push(@m, "testdb_dynamic :: pure_all\n"); --- 1956,1969 ---- push(@m, ' If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir ',"'$vmsdir'", '; print `$(MMS) $(PASTHRU2) test`'."\n"); } ! push(@m, "\t\$(NOECHO) Write Sys\$Output \"No tests defined for \$(NAME) extension.\"\n") unless $tests or -f "test.pl" or @{$self->{DIR}}; push(@m, "\n"); push(@m, "test_dynamic :: pure_all\n"); push(@m, $self->test_via_harness('$(FULLPERL)', $tests)) if $tests; push(@m, $self->test_via_script('$(FULLPERL)', 'test.pl')) if -f "test.pl"; ! push(@m, "\t\$(NOECHO) \$(NOOP)\n") if (!$tests && ! -f "test.pl"); push(@m, "\n"); push(@m, "testdb_dynamic :: pure_all\n"); *************** *** 1971,1978 **** push(@m, "\n"); } else { ! push @m, "test_static :: test_dynamic\n\t$self->{NOECHO}\$(NOOP)\n\n"; ! push @m, "testdb_static :: testdb_dynamic\n\t$self->{NOECHO}\$(NOOP)\n"; } join('',@m); --- 1983,1990 ---- push(@m, "\n"); } else { ! push @m, "test_static :: test_dynamic\n\t\$(NOECHO) \$(NOOP)\n\n"; ! push @m, "testdb_static :: testdb_dynamic\n\t\$(NOECHO) \$(NOOP)\n"; } join('',@m); *************** *** 2027,2034 **** unless ($self->{MAKEAPERL}) { push @m, q{ $(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) ! },$self->{NOECHO},q{Write Sys$Output "Writing ""$(MMS$TARGET)"" for this $(MAP_TARGET)" ! },$self->{NOECHO},q{$(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" \ Makefile.PL DIR=}, $dir, q{ \ MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \ MAKEAPERL=1 NORECURS=1 --- 2039,2046 ---- unless ($self->{MAKEAPERL}) { push @m, q{ $(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) ! $(NOECHO) Write Sys$Output "Writing ""$(MMS$TARGET)"" for this $(MAP_TARGET)" ! $(NOECHO) $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" \ Makefile.PL DIR=}, $dir, q{ \ MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \ MAKEAPERL=1 NORECURS=1 *************** *** 2043,2049 **** } ! my($linkcmd,@staticopts,@staticpkgs,$extralist,$target,$targdir,$libperldir); # The front matter of the linkcommand... $linkcmd = join ' ', $Config{'ld'}, --- 2055,2061 ---- } ! my($linkcmd,@staticopts,@staticpkgs,$extralist,$targdir,$libperldir); # The front matter of the linkcommand... $linkcmd = join ' ', $Config{'ld'}, *************** *** 2179,2215 **** $(MAP_LINKCMD)/Shareable=$(MMS$TARGET) $(MAP_OPTS), $(MAP_EXTRA), $(MAP_LIBPERL) ',"${libperldir}Perlshr_Attr.Opt",' $(MAP_TARGET) : $(MAP_SHRTARGET) ',"${tmp}perlmain\$(OBJ_EXT) ${tmp}PerlShr.Opt",' $(MAP_LINKCMD) ',"${tmp}perlmain\$(OBJ_EXT)",', PerlShr.Opt/Option ! ',$self->{NOECHO},'Write Sys$Output "To install the new ""$(MAP_TARGET)"" binary, say" ! ',$self->{NOECHO},'Write Sys$Output " $(MMS)$(USEMAKEFILE)$(MAKEFILE) inst_perl $(USEMACROS)MAP_TARGET=$(MAP_TARGET)$(ENDMACRO)" ! ',$self->{NOECHO},'Write Sys$Output "To remove the intermediate files, say ! ',$self->{NOECHO},'Write Sys$Output " $(MMS)$(USEMAKEFILE)$(MAKEFILE) map_clean" '; push @m,' ',"${tmp}perlmain.c",' : $(MAKEFILE) ! ',$self->{NOECHO},'$(PERL) $(MAP_PERLINC) -e "use ExtUtils::Miniperl; writemain(qw|',@staticpkgs,'|)" >$(MMS$TARGET) '; push @m, q[ # More from the 255-char line length limit doc_inst_perl : ! ].$self->{NOECHO}.q[$(PERL) -e "print 'Perl binary $(MAP_TARGET)|'" >.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print 'MAP_STATIC|$(MAP_STATIC)|'" >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -pl040 -e " " ].$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'),q[ >>.MM_tmp ! ].$self->{NOECHO}.q[$(PERL) -e "print 'MAP_LIBPERL|$(MAP_LIBPERL)|'" >>.MM_tmp $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[ ! ].$self->{NOECHO}.q[Delete/NoLog/NoConfirm .MM_tmp; ]; push @m, " inst_perl : pure_inst_perl doc_inst_perl ! \$(NOOP) pure_inst_perl : \$(MAP_TARGET) $self->{CP} \$(MAP_SHRTARGET) ",$self->fixpath($Config{'installbin'},1)," $self->{CP} \$(MAP_TARGET) ",$self->fixpath($Config{'installbin'},1)," clean :: map_clean ! \$(NOOP) map_clean : \$(RM_F) ${tmp}perlmain\$(OBJ_EXT) ${tmp}perlmain.c \$(MAKEFILE) --- 2191,2227 ---- $(MAP_LINKCMD)/Shareable=$(MMS$TARGET) $(MAP_OPTS), $(MAP_EXTRA), $(MAP_LIBPERL) ',"${libperldir}Perlshr_Attr.Opt",' $(MAP_TARGET) : $(MAP_SHRTARGET) ',"${tmp}perlmain\$(OBJ_EXT) ${tmp}PerlShr.Opt",' $(MAP_LINKCMD) ',"${tmp}perlmain\$(OBJ_EXT)",', PerlShr.Opt/Option ! $(NOECHO) Write Sys$Output "To install the new ""$(MAP_TARGET)"" binary, say" ! $(NOECHO) Write Sys$Output " $(MMS)$(USEMAKEFILE)$(MAKEFILE) inst_perl $(USEMACROS)MAP_TARGET=$(MAP_TARGET)$(ENDMACRO)" ! $(NOECHO) Write Sys$Output "To remove the intermediate files, say ! $(NOECHO) Write Sys$Output " $(MMS)$(USEMAKEFILE)$(MAKEFILE) map_clean" '; push @m,' ',"${tmp}perlmain.c",' : $(MAKEFILE) ! $(NOECHO) $(PERL) $(MAP_PERLINC) -e "use ExtUtils::Miniperl; writemain(qw|',@staticpkgs,'|)" >$(MMS$TARGET) '; push @m, q[ # More from the 255-char line length limit doc_inst_perl : ! $(NOECHO) $(PERL) -e "print 'Perl binary $(MAP_TARGET)|'" >.MM_tmp ! $(NOECHO) $(PERL) -e "print 'MAP_STATIC|$(MAP_STATIC)|'" >>.MM_tmp ! $(NOECHO) $(PERL) -pl040 -e " " ].$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'),q[ >>.MM_tmp ! $(NOECHO) $(PERL) -e "print 'MAP_LIBPERL|$(MAP_LIBPERL)|'" >>.MM_tmp $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[ ! $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp; ]; push @m, " inst_perl : pure_inst_perl doc_inst_perl ! \$(NOECHO) \$(NOOP) pure_inst_perl : \$(MAP_TARGET) $self->{CP} \$(MAP_SHRTARGET) ",$self->fixpath($Config{'installbin'},1)," $self->{CP} \$(MAP_TARGET) ",$self->fixpath($Config{'installbin'},1)," clean :: map_clean ! \$(NOECHO) \$(NOOP) map_clean : \$(RM_F) ${tmp}perlmain\$(OBJ_EXT) ${tmp}perlmain.c \$(MAKEFILE) #~ Add MAB support for NeXT #~ Minimize methods loaded at startup, and SelfLoad the rest as needed #~ Eliminate colliding declarations of my() variables diff -Pcr perl5_003/lib/ExtUtils/MakeMaker.pm perl5_003_01/lib/ExtUtils/MakeMaker.pm *** perl5_003/lib/ExtUtils/MakeMaker.pm Sun Jun 23 20:52:43 1996 --- perl5_003_01/lib/ExtUtils/MakeMaker.pm Thu Jul 11 12:27:02 1996 *************** *** 2,11 **** package ExtUtils::MakeMaker; ! $Version = $VERSION = "5.34"; $Version_OK = "5.17"; # Makefiles older than $Version_OK will die # (Will be checked from MakeMaker version 4.13 onwards) ! ($Revision = substr(q$Revision: 1.202 $, 10)) =~ s/\s+$//; --- 2,11 ---- package ExtUtils::MakeMaker; ! $Version = $VERSION = "5.36"; $Version_OK = "5.17"; # Makefiles older than $Version_OK will die # (Will be checked from MakeMaker version 4.13 onwards) ! ($Revision = substr(q$Revision: 1.206 $, 10)) =~ s/\s+$//; *************** *** 152,158 **** sub ExtUtils::MakeMaker::prompt ; 1; ! #__DATA__ package ExtUtils::MakeMaker; sub WriteMakefile { --- 152,160 ---- sub ExtUtils::MakeMaker::prompt ; 1; ! ! __DATA__ ! package ExtUtils::MakeMaker; sub WriteMakefile { *************** *** 297,303 **** @Get_from_Config = qw( ar cc cccdlflags ccdlflags dlext dlsrc ld lddlflags ldflags libc ! lib_ext obj_ext ranlib sitelibexp sitearchexp so ); my $item; --- 299,305 ---- @Get_from_Config = qw( ar cc cccdlflags ccdlflags dlext dlsrc ld lddlflags ldflags libc ! lib_ext mab obj_ext ranlib sitelibexp sitearchexp so ); my $item; *************** *** 411,424 **** $self->{Correct_relativ_directories}=0; } ! my $class = ++$PACKNAME; { # no strict; ! print "Blessing Object into class [$class]\n" if $Verbose>=2; ! mv_all_methods("MY",$class); ! bless $self, $class; push @Parent, $self; ! @{"$class\:\:ISA"} = 'MM'; } if (defined $Parent[-2]){ --- 413,426 ---- $self->{Correct_relativ_directories}=0; } ! my $newclass = ++$PACKNAME; { # no strict; ! print "Blessing Object into class [$newclass]\n" if $Verbose>=2; ! mv_all_methods("MY",$newclass); ! bless $self, $newclass; push @Parent, $self; ! @{"$newclass\:\:ISA"} = 'MM'; } if (defined $Parent[-2]){ *************** *** 430,436 **** $self->{$key} = $self->catdir("..",$self->{$key}) unless $self->file_name_is_absolute($self->{$key}); } ! $self->{PARENT}->{CHILDREN}->{$class} = $self if $self->{PARENT}; } else { parse_args($self,@ARGV); } --- 432,438 ---- $self->{$key} = $self->catdir("..",$self->{$key}) unless $self->file_name_is_absolute($self->{$key}); } ! $self->{PARENT}->{CHILDREN}->{$newclass} = $self if $self->{PARENT}; } else { parse_args($self,@ARGV); } #~ Move documentation to end #~ Avoid once-used warnings diff -Pcr perl5_003/lib/ExtUtils/Mkbootstrap.pm perl5_003_01/lib/ExtUtils/Mkbootstrap.pm *** perl5_003/lib/ExtUtils/Mkbootstrap.pm Mon Mar 25 01:04:20 1996 --- perl5_003_01/lib/ExtUtils/Mkbootstrap.pm Fri Jun 21 18:49:53 1996 *************** *** 1,47 **** package ExtUtils::Mkbootstrap; use Config; use Exporter; @ISA=('Exporter'); @EXPORT='&Mkbootstrap'; - $Version=2.0; # just to start somewhere sub Mkbootstrap { - - =head1 NAME - - ExtUtils::Mkbootstrap - make a bootstrap file for use by DynaLoader - - =head1 SYNOPSIS - - C - - =head1 DESCRIPTION - - Mkbootstrap typically gets called from an extension Makefile. - - There is no C<*.bs> file supplied with the extension. Instead a - C<*_BS> file which has code for the special cases, like posix for - berkeley db on the NeXT. - - This file will get parsed, and produce a maybe empty - C<@DynaLoader::dl_resolve_using> array for the current architecture. - That will be extended by $BSLOADLIBS, which was computed by - ExtUtils::Liblist::ext(). If this array still is empty, we do nothing, - else we write a .bs file with an C<@DynaLoader::dl_resolve_using> - array. - - The C<*_BS> file can put some code into the generated C<*.bs> file by - placing it in C<$bscode>. This is a handy 'escape' mechanism that may - prove useful in complex situations. - - If @DynaLoader::dl_resolve_using contains C<-L*> or C<-l*> entries then - Mkbootstrap will automatically add a dl_findfile() call to the - generated C<*.bs> file. - - =cut - my($baseext, @bsloadlibs)=@_; - @bsloadlibs = grep($_, @bsloadlibs); # strip empty libs print STDOUT " bsloadlibs=@bsloadlibs\n" if $Verbose; --- 1,15 ---- package ExtUtils::Mkbootstrap; + + $VERSION = substr q$Revision: 1.11 $, 10; + # $Id: Mkbootstrap.pm,v 1.11 1996/05/31 08:23:54 k Exp k $ + use Config; use Exporter; @ISA=('Exporter'); @EXPORT='&Mkbootstrap'; sub Mkbootstrap { my($baseext, @bsloadlibs)=@_; @bsloadlibs = grep($_, @bsloadlibs); # strip empty libs print STDOUT " bsloadlibs=@bsloadlibs\n" if $Verbose; *************** *** 58,63 **** --- 26,33 ---- if (-f "${baseext}_BS"){ $_ = "${baseext}_BS"; package DynaLoader; # execute code as if in DynaLoader + local($osname, $dlsrc) = (); # avoid warnings + ($osname, $dlsrc) = @Config::Config{qw(osname dlsrc)}; $bscode = ""; unshift @INC, "."; require $_; *************** *** 95,97 **** --- 65,103 ---- } } + 1; + + __END__ + + =head1 NAME + + ExtUtils::Mkbootstrap - make a bootstrap file for use by DynaLoader + + =head1 SYNOPSIS + + C + + =head1 DESCRIPTION + + Mkbootstrap typically gets called from an extension Makefile. + + There is no C<*.bs> file supplied with the extension. Instead a + C<*_BS> file which has code for the special cases, like posix for + berkeley db on the NeXT. + + This file will get parsed, and produce a maybe empty + C<@DynaLoader::dl_resolve_using> array for the current architecture. + That will be extended by $BSLOADLIBS, which was computed by + ExtUtils::Liblist::ext(). If this array still is empty, we do nothing, + else we write a .bs file with an C<@DynaLoader::dl_resolve_using> + array. + + The C<*_BS> file can put some code into the generated C<*.bs> file by + placing it in C<$bscode>. This is a handy 'escape' mechanism that may + prove useful in complex situations. + + If @DynaLoader::dl_resolve_using contains C<-L*> or C<-l*> entries then + Mkbootstrap will automatically add a dl_findfile() call to the + generated C<*.bs> file. + + =cut #~ Add version variable diff -Pcr perl5_003/lib/ExtUtils/testlib.pm perl5_003_01/lib/ExtUtils/testlib.pm *** perl5_003/lib/ExtUtils/testlib.pm Mon Mar 25 01:04:32 1996 --- perl5_003_01/lib/ExtUtils/testlib.pm Fri Jun 21 18:50:58 1996 *************** *** 1,4 **** --- 1,7 ---- package ExtUtils::testlib; + $VERSION = substr q$Revision: 1.11 $, 10; + # $Id: testlib.pm,v 1.11 1996/05/31 08:27:07 k Exp $ + use lib qw(blib/arch blib/lib); 1; __END__ #~ Update to version 1.937 #~ Cosmetic changes for easier EMACS editing #~ First pass at correcting return type for void XSUBs diff -Pcr perl5_003/lib/ExtUtils/xsubpp perl5_003_01/lib/ExtUtils/xsubpp *** perl5_003/lib/ExtUtils/xsubpp Mon Mar 25 01:04:37 1996 --- perl5_003_01/lib/ExtUtils/xsubpp Thu Jul 11 10:20:32 1996 *************** *** 76,82 **** =cut # Global Constants ! $XSUBPP_version = "1.935"; require 5.002; use vars '$cplusplus'; --- 76,82 ---- =cut # Global Constants ! $XSUBPP_version = "1.937"; require 5.002; use vars '$cplusplus'; *************** *** 183,189 **** $type = TidyType($type) ; $type_kind{$type} = $kind ; # prototype defaults to '$' ! $proto = '$' unless $proto ; warn("Warning: File '$typemap' Line $. '$line' Invalid prototype '$proto'\n") unless ValidProtoString($proto) ; $proto_letter{$type} = C_string($proto) ; --- 183,189 ---- $type = TidyType($type) ; $type_kind{$type} = $kind ; # prototype defaults to '$' ! $proto = "\$" unless $proto ; warn("Warning: File '$typemap' Line $. '$line' Invalid prototype '$proto'\n") unless ValidProtoString($proto) ; $proto_letter{$type} = C_string($proto) ; *************** *** 570,576 **** { my ($type) = @_ ; ! $proto_letter{$type} or '$' ; } sub check_cpp { --- 570,576 ---- { my ($type) = @_ ; ! $proto_letter{$type} or "\$" ; } sub check_cpp { *************** *** 608,614 **** print < provides a way to conveniently replace functions which normally + return a false value when they fail with equivalents which halt execution + if they are not successful. This lets you use these functions without + having to test their return values explicitly on each call. Errors are + reported via C, so you can trap them using C<$SIG{__DIE__}> if you + wish to take some action before the program exits. + + The do-or-die equivalents are set up simply by calling Fatal's C + routine, passing it the names of the functions to be replaced. You may + wrap both user-defined functions and CORE operators in this way. + + =head1 AUTHOR + + Lionel.Cons@cern.ch #~ Relax reversibility of fileparse() from same string to same file #~ Don't return VMS default directory from fileparse() if it's not in input #~ Add VERSION #~ Correct documentation and remove redundant comments #~ Fix handling of MSDOS file syntax #~ Correct recognition of MacOS name, so it doesn't collide with MachTen #~ Eliminate use of &` to avoid runtime penalty #~ Don't convert single-char path (root dir) into empty string diff -Pcr perl5_003/lib/File/Basename.pm perl5_003_01/lib/File/Basename.pm *** perl5_003/lib/File/Basename.pm Mon Mar 25 01:04:37 1996 --- perl5_003_01/lib/File/Basename.pm Wed Jul 10 11:27:39 1996 *************** *** 61,68 **** C<@suffixlist>, you can remove file types or versions for examination. You are guaranteed that if you concatenate B, B, and ! B together in that order, the result will be identical to the ! input file specification. =back --- 61,68 ---- C<@suffixlist>, you can remove file types or versions for examination. You are guaranteed that if you concatenate B, B, and ! B together in that order, the result will denote the same ! file as the input file specification. =back *************** *** 70,82 **** Using UNIX file syntax: ! ($base,$path,$type) = fileparse('/virgil/aeneid/draft.book7', '\.book\d+'); would yield $base eq 'draft' ! $path eq '/virgil/aeneid', $tail eq '.book7' Similarly, using VMS syntax: --- 70,82 ---- Using UNIX file syntax: ! ($base,$path,$type) = fileparse('/virgil/aeneid/draft.book7', '\.book\d+'); would yield $base eq 'draft' ! $path eq '/virgil/aeneid/', $tail eq '.book7' Similarly, using VMS syntax: *************** *** 101,107 **** The dirname() routine returns the directory portion of the input file specification. When using VMS or MacOS syntax, this is identical to the second element of the list produced by calling fileparse() with the same ! input file specification. When using UNIX or MSDOS syntax, the return value conforms to the behavior of the UNIX shell command dirname(1). This is usually the same as the behavior of fileparse(), but differs in some cases. For example, for the input file specification F, fileparse() --- 101,109 ---- The dirname() routine returns the directory portion of the input file specification. When using VMS or MacOS syntax, this is identical to the second element of the list produced by calling fileparse() with the same ! input file specification. (Under VMS, if there is no directory information ! in the input file specification, then the current default device and ! directory are returned.) When using UNIX or MSDOS syntax, the return value conforms to the behavior of the UNIX shell command dirname(1). This is usually the same as the behavior of fileparse(), but differs in some cases. For example, for the input file specification F, fileparse() *************** *** 114,119 **** --- 116,125 ---- require Exporter; @ISA = qw(Exporter); @EXPORT = qw(fileparse fileparse_set_fstype basename dirname); + #use strict; + #use vars qw($VERSION $Fileparse_fstype); + $VERSION = "2.3"; + # fileparse_set_fstype() - specify OS-based rules used in future # calls to routines in this package *************** *** 129,190 **** # fileparse() - parse file specification # ! # calling sequence: ! # ($filename,$prefix,$tail) = &basename_pat($filespec,@excludelist); ! # where $filespec is the file specification to be parsed, and ! # @excludelist is a list of patterns which should be removed ! # from the end of $filename. ! # $filename is the part of $filespec after $prefix (i.e. the ! # name of the file). The elements of @excludelist ! # are compared to $filename, and if an ! # $prefix is the path portion $filespec, up to and including ! # the end of the last directory name ! # $tail any characters removed from $filename because they ! # matched an element of @excludelist. ! # ! # fileparse() first removes the directory specification from $filespec, ! # according to the syntax of the OS (code is provided below to handle ! # VMS, Unix, MSDOS and MacOS; you can pick the one you want using ! # fileparse_set_fstype(), or you can accept the default, which is ! # based on the information in the builtin variable $^O). It then compares ! # each element of @excludelist to $filename, and if that element is a ! # suffix of $filename, it is removed from $filename and prepended to ! # $tail. By specifying the elements of @excludelist in the right order, ! # you can 'nibble back' $filename to extract the portion of interest ! # to you. ! # ! # For example, on a system running Unix, ! # ($base,$path,$type) = fileparse('/virgil/aeneid/draft.book7', ! # '\.book\d+'); ! # would yield $base == 'draft', ! # $path == '/virgil/aeneid/' (note trailing slash) ! # $tail == '.book7'. ! # Similarly, on a system running VMS, ! # ($name,$dir,$type) = fileparse('Doc_Root:[Help]Rhetoric.Rnh','\..*'); ! # would yield $name == 'Rhetoric'; ! # $dir == 'Doc_Root:[Help]', and ! # $type == '.Rnh'. ! # ! # Version 2.2 13-Oct-1994 Charles Bailey bailey@genetics.upenn.edu sub fileparse { my($fullname,@suffices) = @_; my($fstype) = $Fileparse_fstype; ! my($dirpath,$tail,$suffix); if ($fstype =~ /^VMS/i) { if ($fullname =~ m#/#) { $fstype = '' } # We're doing Unix emulation else { ($dirpath,$basename) = ($fullname =~ /(.*[:>\]])?(.*)/); - $dirpath = $ENV{'DEFAULT'} unless $dirpath; } } if ($fstype =~ /^MSDOS/i) { ! ($dirpath,$basename) = ($fullname =~ /(.*\\)?(.*)/); ! $dirpath = '.\\' unless $dirpath; } ! elsif ($fstype =~ /^MAC/i) { ($dirpath,$basename) = ($fullname =~ /(.*:)?(.*)/); } elsif ($fstype !~ /^VMS/i) { # default to Unix --- 135,159 ---- # fileparse() - parse file specification # ! # Version 2.3 4-Jul-1996 Charles Bailey bailey@genetics.upenn.edu sub fileparse { my($fullname,@suffices) = @_; my($fstype) = $Fileparse_fstype; ! my($dirpath,$tail,$suffix,$basename); if ($fstype =~ /^VMS/i) { if ($fullname =~ m#/#) { $fstype = '' } # We're doing Unix emulation else { ($dirpath,$basename) = ($fullname =~ /(.*[:>\]])?(.*)/); } } if ($fstype =~ /^MSDOS/i) { ! ($dirpath,$basename) = ($fullname =~ /(.*[:\\])?(.*)/); ! $dirpath .= '.\\' unless $dirpath =~ /\\$/; } ! elsif ($fstype =~ /^MacOS/i) { ($dirpath,$basename) = ($fullname =~ /(.*:)?(.*)/); } elsif ($fstype !~ /^VMS/i) { # default to Unix *************** *** 195,203 **** if (@suffices) { $tail = ''; foreach $suffix (@suffices) { ! if ($basename =~ /($suffix)$/) { ! $tail = $1 . $tail; ! $basename = $`; } } } --- 164,172 ---- if (@suffices) { $tail = ''; foreach $suffix (@suffices) { ! if ($basename =~ /([\x00-\xff]*?)($suffix)$/) { ! $tail = $2 . $tail; ! $basename = $1; } } } *************** *** 213,219 **** my($name) = shift; (fileparse($name, map("\Q$_\E",@_)))[0]; } ! # dirname() - returns device and directory portion of file specification # Behavior matches that of Unix dirname(1) exactly for Unix and MSDOS --- 182,188 ---- my($name) = shift; (fileparse($name, map("\Q$_\E",@_)))[0]; } ! # dirname() - returns device and directory portion of file specification # Behavior matches that of Unix dirname(1) exactly for Unix and MSDOS *************** *** 228,247 **** if ($fstype =~ /VMS/i) { if ($_[0] =~ m#/#) { $fstype = '' } ! else { return $dirname } } if ($fstype =~ /MacOS/i) { return $dirname } elsif ($fstype =~ /MSDOS/i) { if ( $dirname =~ /:\\$/) { return $dirname } chop $dirname; ! $dirname =~ s:[^\\]+$:: unless $basename; ! $dirname = '.' unless $dirname; } else { ! if ( $dirname eq '/') { return $dirname } chop $dirname; ! $dirname =~ s:[^/]+$:: unless $basename; ! $dirname = '.' unless $dirname; } $dirname; --- 197,217 ---- if ($fstype =~ /VMS/i) { if ($_[0] =~ m#/#) { $fstype = '' } ! else { return $dirname || $ENV{DEFAULT} } } if ($fstype =~ /MacOS/i) { return $dirname } elsif ($fstype =~ /MSDOS/i) { if ( $dirname =~ /:\\$/) { return $dirname } chop $dirname; ! $dirname =~ s:[^\\]+$:: unless length($basename); ! $dirname = '.' unless length($dirname); } else { ! if ( $dirname =~ m:^/+$:) { return '/'; } chop $dirname; ! $dirname =~ s:[^/]+$:: unless length($basename); ! $dirname =~ s:/+$:: ; ! $dirname = '.' unless length($dirname); } $dirname; #~ Change handling of $\ to avoid uninitializd variable warning when #~ it was undefined diff -Pcr perl5_003/lib/File/Copy.pm perl5_003_01/lib/File/Copy.pm *** perl5_003/lib/File/Copy.pm Mon Mar 25 01:04:42 1996 --- perl5_003_01/lib/File/Copy.pm Mon Jul 15 15:22:03 1996 *************** *** 31,43 **** my $from = shift; my $to = shift; - my $recsep = $\; my $closefrom=0; my $closeto=0; my ($size, $status, $r, $buf); local(*FROM, *TO); ! ! $\ = ''; if (ref(\$from) eq 'GLOB') { *FROM = $from; --- 31,41 ---- my $from = shift; my $to = shift; my $closefrom=0; my $closeto=0; my ($size, $status, $r, $buf); local(*FROM, *TO); ! local($\) = ''; if (ref(\$from) eq 'GLOB') { *FROM = $from; *************** *** 81,87 **** goto fail_inner unless(defined($r)); close(TO) || goto fail_open2 if $closeto; close(FROM) || goto fail_open1 if $closefrom; ! $\ = $recsep; return 1; # All of these contortions try to preserve error messages... --- 79,85 ---- goto fail_inner unless(defined($r)); close(TO) || goto fail_open2 if $closeto; close(FROM) || goto fail_open1 if $closefrom; ! # Use this idiom to avoid uninitialized value warning. return 1; # All of these contortions try to preserve error messages... *************** *** 100,106 **** $! = $status unless $!; } fail_open1: - $\ = $recsep; return 0; } --- 98,103 ---- #~ Clip off '\dir' suffix under Win32 #~ Fix inversion in recording return values from fileparse() diff -Pcr perl5_003/lib/File/Find.pm perl5_003_01/lib/File/Find.pm *** perl5_003/lib/File/Find.pm Mon Mar 25 01:04:43 1996 --- perl5_003_01/lib/File/Find.pm Tue Jun 18 20:33:04 1996 *************** *** 82,88 **** &$wanted; my $fixtopdir = $topdir; $fixtopdir =~ s,/$,, ; ! $fixtopdir =~ s/\.dir$// if $Is_VMS; ; &finddir($wanted,$fixtopdir,$topnlink); } else { --- 82,89 ---- &$wanted; my $fixtopdir = $topdir; $fixtopdir =~ s,/$,, ; ! $fixtopdir =~ s/\.dir$// if $Is_VMS; ! $fixtopdir =~ s/\\dir$// if $Is_NT; &finddir($wanted,$fixtopdir,$topnlink); } else { *************** *** 90,96 **** } } else { ! unless (($dir,$_) = File::Basename::fileparse($topdir)) { ($dir,$_) = ('.', $topdir); } $name = $topdir; --- 91,97 ---- } } else { ! unless (($_,$dir) = File::Basename::fileparse($topdir)) { ($dir,$_) = ('.', $topdir); } $name = $topdir; *************** *** 142,147 **** --- 143,149 ---- if (!$prune && chdir $_) { $name =~ s/\.dir$// if $Is_VMS; + $name =~ s/\\dir$// if $Is_NT; &finddir($wanted,$name,$nlink); chdir '..'; } *************** *** 167,172 **** --- 169,175 ---- my $fixtopdir = $topdir; $fixtopdir =~ s,/$,, ; $fixtopdir =~ s/\.dir$// if $Is_VMS; + $fixtopdir =~ s/\\dir$// if $Is_NT; &finddepthdir($wanted,$fixtopdir,$topnlink); ($dir,$_) = ($fixtopdir,'.'); $name = $fixtopdir; *************** *** 177,183 **** } } else { ! unless (($dir,$_) = File::Basename::fileparse($topdir)) { ($dir,$_) = ('.', $topdir); } chdir $dir && &$wanted; --- 180,186 ---- } } else { ! unless (($_,$dir) = File::Basename::fileparse($topdir)) { ($dir,$_) = ('.', $topdir); } chdir $dir && &$wanted; *************** *** 225,230 **** --- 228,234 ---- if (chdir $_) { $name =~ s/\.dir$// if $Is_VMS; + $name =~ s/\\dir$// if $Is_NT; &finddepthdir($wanted,$name,$nlink); chdir '..'; } *************** *** 247,255 **** $Is_VMS = 1; $dont_use_nlink = 1; } $dont_use_nlink = 1 if $^O eq 'os2'; - $dont_use_nlink = 1 if $^O =~ m:^mswin32$:i ; 1; --- 251,262 ---- $Is_VMS = 1; $dont_use_nlink = 1; } + if ($^O =~ m:^mswin32:i) { + $Is_NT = 1; + $dont_use_nlink = 1; + } $dont_use_nlink = 1 if $^O eq 'os2'; 1; #~ Add FindBin library module diff -Pcr perl5_003/lib/FindBin.pm perl5_003_01/lib/FindBin.pm *** perl5_003/lib/FindBin.pm Wed Dec 31 19:00:00 1969 --- perl5_003_01/lib/FindBin.pm Fri Jun 21 15:27:09 1996 *************** *** 0 **** --- 1,232 ---- + # FindBin.pm + # + # Copyright (c) 1995 Graham Barr & Nick Ing-Simmons. All rights reserved. + # This program is free software; you can redistribute it and/or modify it + # under the same terms as Perl itself. + + =head1 NAME + + FindBin - Locate directory of original perl script + + =head1 SYNOPSIS + + use FindBin; + BEGIN { unshift(@INC,"$FindBin::Bin/../lib") } + + or + + use FindBin qw($Bin); + BEGIN { unshift(@INC,"$Bin/../lib") } + + =head1 DESCRIPTION + + Locates the full path to the script bin directory to allow the use + of paths relative to the bin directory. + + This allows a user to setup a directory tree for some software with + directories /bin and /lib and then the above example will allow + the use of modules in the lib directory without knowing where the software + tree is installed. + + If perl is invoked using the -e option or the perl script is read from + C then FindBin sets both C<$Bin> and C<$RealBin> to the current + directory. + + =head1 EXPORTABLE VARIABLES + + $Bin - path to bin directory from where script was invoked + $Script - basename of script from which perl was invoked + $RealBin - $Bin with all links resolved + $RealScript - $Script with all links resolved + + =head1 KNOWN BUGS + + if perl is invoked as + + perl filename + + and I does not have executable rights and a program called I + exists in the users C<$ENV{PATH}> which satisfies both -x and -T then FindBin + assumes that it was invoked via the C<$ENV{PATH}>. + + Workaround is to invoke perl as + + perl ./filename + + =head1 AUTHORS + + Graham Barr + Nick Ing-Simmons + + =head1 COPYRIGHT + + Copyright (c) 1995 Graham Barr & Nick Ing-Simmons. All rights reserved. + This program is free software; you can redistribute it and/or modify it + under the same terms as Perl itself. + + =head1 REVISION + + $Revision: 1.4 $ + + =cut + + package FindBin; + use Carp; + require 5.000; + require Exporter; + use Cwd qw(getcwd); + + @EXPORT_OK = qw($Bin $Script $RealBin $RealScript $Dir $RealDir); + %EXPORT_TAGS = (ALL => [qw($Bin $Script $RealBin $RealScript $Dir $RealDir)]); + @ISA = qw(Exporter); + + $VERSION = $VERSION = sprintf("%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/); + + # Taken from Cwd.pm It is really getcwd with an optional + # parameter instead of '.' + # + # another way would be: + # + #sub abs_path + #{ + # my $cwd = getcwd(); + # chdir(shift || '.'); + # my $realpath = getcwd(); + # chdir($cwd); + # $realpath; + #} + + sub abs_path + { + my $start = shift || '.'; + my($dotdots, $cwd, @pst, @cst, $dir, @tst); + + unless (@cst = stat( $start )) + { + warn "stat($start): $!"; + return ''; + } + $cwd = ''; + $dotdots = $start; + do + { + $dotdots .= '/..'; + @pst = @cst; + unless (opendir(PARENT, $dotdots)) + { + warn "opendir($dotdots): $!"; + return ''; + } + unless (@cst = stat($dotdots)) + { + warn "stat($dotdots): $!"; + closedir(PARENT); + return ''; + } + if ($pst[0] == $cst[0] && $pst[1] == $cst[1]) + { + $dir = ''; + } + else + { + do + { + unless (defined ($dir = readdir(PARENT))) + { + warn "readdir($dotdots): $!"; + closedir(PARENT); + return ''; + } + $tst[0] = $pst[0]+1 unless (@tst = lstat("$dotdots/$dir")) + } + while ($dir eq '.' || $dir eq '..' || $tst[0] != $pst[0] || + $tst[1] != $pst[1]); + } + $cwd = "$dir/$cwd"; + closedir(PARENT); + } while ($dir); + chop($cwd); # drop the trailing / + $cwd; + } + + + BEGIN + { + *Dir = \$Bin; + *RealDir = \$RealBin; + + if($0 eq '-e' || $0 eq '-') + { + # perl invoked with -e or script is on C + + $Script = $RealScript = $0; + $Bin = $RealBin = getcwd(); + } + else + { + my $script = $0; + + if ($^O eq 'VMS') + { + ($Bin,$Script) = VMS::Filespec::rmsexpand($0) =~ /(.*\])(.*)/; + ($RealBin,$RealScript) = ($Bin,$Script); + } + else + { + unless($script =~ m#/# && -f $script) + { + my $dir; + + foreach $dir (split(/:/,$ENV{PATH})) + { + if(-x "$dir/$script") + { + $script = "$dir/$script"; + + if (-f $0) + { + # $script has been found via PATH but perl could have + # been invoked as 'perl file'. Do a dumb check to see + # if $script is a perl program, if not then $script = $0 + # + # well we actually only check that it is an ASCII file + # we know its executable so it is probably a script + # of some sort. + + $script = $0 unless(-T $script); + } + last; + } + } + } + + croak("Cannot find current script '$0'") unless(-f $script); + + # Ensure $script contains the complete path incase we C + + $script = getcwd() . "/" . $script unless($script =~ m,^/,); + + ($Bin,$Script) = $script =~ m,^(.*?)/+([^/]+)$,; + + # Resolve $script if it is a link + while(1) + { + my $linktext = readlink($script); + + ($RealBin,$RealScript) = $script =~ m,^(.*?)/+([^/]+)$,; + last unless defined $linktext; + + $script = ($linktext =~ m,^/,) + ? $linktext + : $RealBin . "/" . $linktext; + } + + # Get absolute paths to directories + $Bin = abs_path($Bin) if($Bin); + $RealBin = abs_path($RealBin) if($RealBin); + } + } + } + + 1; # Keep require happy + #~ Update to version 2.3 diff -Pcr perl5_003/lib/Getopt/Long.pm perl5_003_01/lib/Getopt/Long.pm *** perl5_003/lib/Getopt/Long.pm Mon Mar 25 01:04:44 1996 --- perl5_003_01/lib/Getopt/Long.pm Wed Jul 10 10:46:03 1996 *************** *** 1,11 **** # GetOpt::Long.pm -- POSIX compatible options parsing ! # RCS Status : $Id: GetoptLong.pm,v 2.1 1996/02/02 20:24:35 jv Exp $ # Author : Johan Vromans # Created On : Tue Sep 11 15:00:12 1990 # Last Modified By: Johan Vromans ! # Last Modified On: Fri Feb 2 21:24:32 1996 ! # Update Count : 347 # Status : Released package Getopt::Long; --- 1,11 ---- # GetOpt::Long.pm -- POSIX compatible options parsing ! # RCS Status : $Id: GetoptLong.pm,v 2.3 1996-04-05 21:03:05+02 jv Exp $ # Author : Johan Vromans # Created On : Tue Sep 11 15:00:12 1990 # Last Modified By: Johan Vromans ! # Last Modified On: Fri Apr 5 21:02:52 1996 ! # Update Count : 433 # Status : Released package Getopt::Long; *************** *** 14,20 **** @ISA = qw(Exporter); @EXPORT = qw(&GetOptions $REQUIRE_ORDER $PERMUTE $RETURN_IN_ORDER); ! $VERSION = sprintf("%d.%02d", q$Revision: 2.1 $ =~ /(\d+)\.(\d+)/); use strict; =head1 NAME --- 14,23 ---- @ISA = qw(Exporter); @EXPORT = qw(&GetOptions $REQUIRE_ORDER $PERMUTE $RETURN_IN_ORDER); ! $VERSION = sprintf("%d.%02d", '$Revision: 2.3 $ ' =~ /(\d+)\.(\d+)/); ! use vars qw($autoabbrev $getopt_compat $ignorecase $bundling $order ! $error $debug $REQUIRE_ORDER $PERMUTE $RETURN_IN_ORDER ! $VERSION $major_version $minor_version); use strict; =head1 NAME *************** *** 32,40 **** GetOptions(). This function adheres to the POSIX syntax for command line options, with GNU extensions. In general, this means that options have long names instead of single letters, and are introduced with a ! double dash "--". There is no bundling of command line options, as was ! the case with the more traditional single-letter approach. For ! example, the UNIX "ps" command can be given the command line "option" -vax --- 35,44 ---- GetOptions(). This function adheres to the POSIX syntax for command line options, with GNU extensions. In general, this means that options have long names instead of single letters, and are introduced with a ! double dash "--". Support for bundling of command line options, as was ! the case with the more traditional single-letter approach, is provided ! but not enabled by default. For example, the UNIX "ps" command can be ! given the command line "option" -vax *************** *** 366,374 **** $RETURN_IN_ORDER is not supported by GetOptions(). ! =item $Getopt::Long::ignorecase ! Ignore case when matching options. Default is 1. =item $Getopt::Long::VERSION --- 370,408 ---- $RETURN_IN_ORDER is not supported by GetOptions(). ! =item $Getopt::Long::bundling ! Setting this variable to a non-zero value will allow single-character ! options to be bundled. To distinguish bundles from long option names, ! long options must be introduced with B<--> and single-character ! options (and bundles) with B<->. For example, ! ! ps -vax --vax ! ! would be equivalent to ! ! ps -v -a -x --vax ! ! provided "vax", "v", "a" and "x" have been defined to be valid ! options. ! ! Bundled options can also include a value in the bundle; this value has ! to be the last part of the bundle, e.g. ! ! scale -h24 -w80 ! ! is equivalent to ! ! scale -h 24 -w 80 ! ! B Using option bundling can easily lead to unexpected results, ! especially when mixing long options and bundles. Caveat emptor. ! ! =item $Getopt::Long::ignorecase ! ! Ignore case when matching options. Default is 1. When bundling is in ! effect, case is ignored on single-character options only if ! $Getopt::Long::ignorecase is greater than 1. =item $Getopt::Long::VERSION *************** *** 396,406 **** ################ Introduction ################ # - # This package implements an extended getopt function. This function - # adheres to the new syntax (long option names, no bundling). It tries - # to implement the better functionality of traditional, GNU and POSIX - # getopt functions. - # # This program is Copyright 1990,1996 by Johan Vromans. # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License --- 430,435 ---- *************** *** 416,465 **** # the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. - ################ History ################ - # - # 13-Jan-1996 Johan Vromans - # Generalized the linkage interface. - # Eliminated the linkage argument. - # Add code references as a possible value for the option linkage. - # Add option specifier <> to have a call-back for non-options. - # - # 26-Dec-1995 Johan Vromans - # Import from netgetopt.pl. - # Turned into a decent module. - # Added linkage argument. - ################ Configuration Section ################ # Values for $order. See GNU getopt.c for details. ! ($Getopt::Long::REQUIRE_ORDER, ! $Getopt::Long::PERMUTE, ! $Getopt::Long::RETURN_IN_ORDER) = (0..2); my $gen_prefix; # generic prefix (option starters) # Handle POSIX compliancy. if ( defined $ENV{"POSIXLY_CORRECT"} ) { ! $gen_prefix = "(--|-)"; ! $Getopt::Long::autoabbrev = 0; # no automatic abbrev of options ! $Getopt::Long::getopt_compat = 0; # disallow '+' to start options ! $Getopt::Long::order = $Getopt::Long::REQUIRE_ORDER; } else { ! $gen_prefix = "(--|-|\\+)"; ! $Getopt::Long::autoabbrev = 1; # automatic abbrev of options ! $Getopt::Long::getopt_compat = 1; # allow '+' to start options ! $Getopt::Long::order = $Getopt::Long::PERMUTE; } # Other configurable settings. ! $Getopt::Long::debug = 0; # for debugging ! $Getopt::Long::error = 0; # error tally ! $Getopt::Long::ignorecase = 1; # ignore case when matching options ! ($Getopt::Long::version, ! $Getopt::Long::major_version, ! $Getopt::Long::minor_version) = '$Revision: 2.1 $ ' =~ /: ((\d+)\.(\d+))/; ! $Getopt::Long::version .= '*' if length('$Locker: $ ') > 12; ################ Subroutines ################ --- 445,478 ---- # the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, # MA 02139, USA. ################ Configuration Section ################ # Values for $order. See GNU getopt.c for details. ! ($REQUIRE_ORDER, $PERMUTE, $RETURN_IN_ORDER) = (0..2); my $gen_prefix; # generic prefix (option starters) # Handle POSIX compliancy. if ( defined $ENV{"POSIXLY_CORRECT"} ) { ! $gen_prefix = "--|-"; ! $autoabbrev = 0; # no automatic abbrev of options ! $bundling = 0; # no bundling of single letter switches ! $getopt_compat = 0; # disallow '+' to start options ! $order = $REQUIRE_ORDER; } else { ! $gen_prefix = "--|-|\\+"; ! $autoabbrev = 1; # automatic abbrev of options ! $bundling = 0; # bundling off by default ! $getopt_compat = 1; # allow '+' to start options ! $order = $PERMUTE; } # Other configurable settings. ! $debug = 0; # for debugging ! $error = 0; # error tally ! $ignorecase = 1; # ignore case when matching options ! ($major_version, $minor_version) = $VERSION =~ /^(\d+)\.(\d+)/; ################ Subroutines ################ *************** *** 467,492 **** my @optionlist = @_; # local copy of the option descriptions my $argend = '--'; # option list terminator ! my %opctl; # table of arg.specs my $pkg = (caller)[0]; # current context # Needed if linkage is omitted. my %aliases; # alias table my @ret = (); # accum for non-options my %linkage; # linkage my $userlinkage; # user supplied HASH - my $debug = $Getopt::Long::debug; # convenience my $genprefix = $gen_prefix; # so we can call the same module more # than once in differing environments ! $Getopt::Long::error = 0; ! print STDERR ("GetOptions $Getopt::Long::version", ! " [GetOpt::Long $Getopt::Long::VERSION] -- ", "called from package \"$pkg\".\n", ! " autoabbrev=$Getopt::Long::autoabbrev". ! ",getopt_compat=$Getopt::Long::getopt_compat", ",genprefix=\"$genprefix\"", ! ",order=$Getopt::Long::order", ! ",ignorecase=$Getopt::Long::ignorecase", ".\n") if $debug; --- 480,506 ---- my @optionlist = @_; # local copy of the option descriptions my $argend = '--'; # option list terminator ! my %opctl; # table of arg.specs (long and abbrevs) ! my %bopctl; # table of arg.specs (bundles) my $pkg = (caller)[0]; # current context # Needed if linkage is omitted. my %aliases; # alias table my @ret = (); # accum for non-options my %linkage; # linkage my $userlinkage; # user supplied HASH my $genprefix = $gen_prefix; # so we can call the same module more # than once in differing environments ! $error = 0; ! print STDERR ('GetOptions $Revision: 2.3 $ ', ! "[GetOpt::Long $Getopt::Long::VERSION] -- ", "called from package \"$pkg\".\n", ! " autoabbrev=$autoabbrev". ! ",bundling=$bundling", ! ",getopt_compat=$getopt_compat", ",genprefix=\"$genprefix\"", ! ",order=$order", ! ",ignorecase=$ignorecase", ".\n") if $debug; *************** *** 507,517 **** # Verify correctness of optionlist. %opctl = (); while ( @optionlist > 0 ) { my $opt = shift (@optionlist); # Strip leading prefix so people can specify "-foo=i" if they like. ! $opt = $' if $opt =~ /^($genprefix)+/; if ( $opt eq '<>' ) { if ( (defined $userlinkage) --- 521,532 ---- # Verify correctness of optionlist. %opctl = (); + %bopctl = (); while ( @optionlist > 0 ) { my $opt = shift (@optionlist); # Strip leading prefix so people can specify "-foo=i" if they like. ! $opt = $2 if $opt =~ /^($genprefix)+([\x00-\xff]*)/; if ( $opt eq '<>' ) { if ( (defined $userlinkage) *************** *** 523,557 **** unless ( @optionlist > 0 && ref($optionlist[0]) && ref($optionlist[0]) eq 'CODE' ) { warn ("Option spec <> requires a reference to a subroutine\n"); ! $Getopt::Long::error++; next; } $linkage{'<>'} = shift (@optionlist); next; } - $opt =~ tr/A-Z/a-z/ if $Getopt::Long::ignorecase; if ( $opt !~ /^(\w+[-\w|]*)?(!|[=:][infse]@?)?$/ ) { warn ("Error in option spec: \"", $opt, "\"\n"); ! $Getopt::Long::error++; next; } my ($o, $c, $a) = ($1, $2); if ( ! defined $o ) { # empty -> '-' option ! $opctl{$o = ''} = defined $c ? $c : ''; } else { # Handle alias names my @o = split (/\|/, $o); $o = $o[0]; foreach ( @o ) { ! if ( defined $c && $c eq '!' ) { ! $opctl{"no$_"} = $c; ! $c = ''; } - $opctl{$_} = defined $c ? $c : ''; if ( defined $a ) { # Note alias. $aliases{$_} = $a; --- 538,589 ---- unless ( @optionlist > 0 && ref($optionlist[0]) && ref($optionlist[0]) eq 'CODE' ) { warn ("Option spec <> requires a reference to a subroutine\n"); ! $error++; next; } $linkage{'<>'} = shift (@optionlist); next; } if ( $opt !~ /^(\w+[-\w|]*)?(!|[=:][infse]@?)?$/ ) { warn ("Error in option spec: \"", $opt, "\"\n"); ! $error++; next; } my ($o, $c, $a) = ($1, $2); + $c = '' unless defined $c; if ( ! defined $o ) { # empty -> '-' option ! $opctl{$o = ''} = $c; } else { # Handle alias names my @o = split (/\|/, $o); $o = $o[0]; + $o = lc ($o) + if $ignorecase > 1 + || ($ignorecase + && ($bundling ? length($o) > 1 : 1)); + foreach ( @o ) { ! if ( $bundling && length($_) == 1 ) { ! $_ = lc ($_) if $ignorecase > 1; ! if ( $c eq '!' ) { ! $opctl{"no$_"} = $c; ! warn ("Ignoring '!' modifier for short option $_\n"); ! $c = ''; ! } ! $bopctl{$_} = $c; ! } ! else { ! $_ = lc ($_) if $ignorecase; ! if ( $c eq '!' ) { ! $opctl{"no$_"} = $c; ! $c = ''; ! } ! $opctl{$_} = $c; } if ( defined $a ) { # Note alias. $aliases{$_} = $a; *************** *** 584,597 **** if ( @optionlist > 0 && ref($optionlist[0]) ) { print STDERR ("=> link \"$o\" to $optionlist[0]\n") if $debug; ! if ( ref($optionlist[0]) eq 'SCALAR' ! || ref($optionlist[0]) eq 'ARRAY' ! || ref($optionlist[0]) eq 'CODE' ) { $linkage{$o} = shift (@optionlist); } else { warn ("Invalid option linkage for \"", $opt, "\"\n"); ! $Getopt::Long::error++; } } else { --- 616,627 ---- if ( @optionlist > 0 && ref($optionlist[0]) ) { print STDERR ("=> link \"$o\" to $optionlist[0]\n") if $debug; ! if ( ref($optionlist[0]) =~ /^(SCALAR|ARRAY|CODE)$/ ) { $linkage{$o} = shift (@optionlist); } else { warn ("Invalid option linkage for \"", $opt, "\"\n"); ! $error++; } } else { *************** *** 599,605 **** # Make sure a valid perl identifier results. my $ov = $o; $ov =~ s/\W/_/g; ! if ( $c && $c =~ /@/ ) { print STDERR ("=> link \"$o\" to \@$pkg","::opt_$ov\n") if $debug; eval ("\$linkage{\$o} = \\\@".$pkg."::opt_$ov;"); --- 629,635 ---- # Make sure a valid perl identifier results. my $ov = $o; $ov =~ s/\W/_/g; ! if ( defined($c) && $c =~ /@/ ) { print STDERR ("=> link \"$o\" to \@$pkg","::opt_$ov\n") if $debug; eval ("\$linkage{\$o} = \\\@".$pkg."::opt_$ov;"); *************** *** 613,624 **** } # Bail out if errors found. ! return 0 if $Getopt::Long::error; ! # Sort the possible option names. ! my @opctl = sort(keys (%opctl)) if $Getopt::Long::autoabbrev; ! # Show if debugging. if ( $debug ) { my ($arrow, $k, $v); $arrow = "=> "; --- 643,654 ---- } # Bail out if errors found. ! return 0 if $error; ! # Sort the possible long option names. ! my @opctl = sort(keys (%opctl)) if $autoabbrev; ! # Show the options tables if debugging. if ( $debug ) { my ($arrow, $k, $v); $arrow = "=> "; *************** *** 626,635 **** print STDERR ($arrow, "\$opctl{\"$k\"} = \"$v\"\n"); $arrow = " "; } } my $opt; # current option ! my $arg; # current option value my $array; # current option is array typed # Process argument list --- 656,670 ---- print STDERR ($arrow, "\$opctl{\"$k\"} = \"$v\"\n"); $arrow = " "; } + $arrow = "=> "; + while ( ($k,$v) = each(%bopctl) ) { + print STDERR ($arrow, "\$bopctl{\"$k\"} = \"$v\"\n"); + $arrow = " "; + } } my $opt; # current option ! my $arg; # current option value, if any my $array; # current option is array typed # Process argument list *************** *** 639,647 **** #### Get next argument #### $opt = shift (@ARGV); $arg = undef; - my $optarg = undef; $array = 0; print STDERR ("=> option \"", $opt, "\"\n") if $debug; --- 674,685 ---- #### Get next argument #### + my $starter; # option starter string, e.g. '-' or '--' + my $rest = undef; # remainder from unbundling + my $optarg = undef; # value supplied with --opt=value + $opt = shift (@ARGV); $arg = undef; $array = 0; print STDERR ("=> option \"", $opt, "\"\n") if $debug; *************** *** 651,668 **** if ( $opt eq $argend ) { # Finish. Push back accumulated arguments and return. unshift (@ARGV, @ret) ! if $Getopt::Long::order == $Getopt::Long::PERMUTE; ! return ($Getopt::Long::error == 0); } ! if ( $opt =~ /^$genprefix/ ) { # Looks like an option. ! $opt = $'; # option name (w/o prefix) ! # If it is a long opt, it may include the value. ! if (($& eq "--" || ($Getopt::Long::getopt_compat && $& eq "+")) ! && $opt =~ /^([^=]+)=/ ) { $opt = $1; ! $optarg = $'; print STDERR ("=> option \"", $opt, "\", optarg = \"$optarg\"\n") if $debug; } --- 689,709 ---- if ( $opt eq $argend ) { # Finish. Push back accumulated arguments and return. unshift (@ARGV, @ret) ! if $order == $PERMUTE; ! return ($error == 0); } ! if ( $opt =~ /^($genprefix)([\x00-\xff]*)/ ) { # Looks like an option. ! $opt = $2; # option name (w/o prefix) ! $starter = $1; # option starter ! ! # If it is a long option, it may include the value. ! if (($starter eq "--" ! || ($getopt_compat && $starter eq "+")) ! && $opt =~ /^([^=]+)=([\x00-\xff]*)/ ) { $opt = $1; ! $optarg = $2; print STDERR ("=> option \"", $opt, "\", optarg = \"$optarg\"\n") if $debug; } *************** *** 670,682 **** } # Not an option. Save it if we $PERMUTE and don't have a <>. ! elsif ( $Getopt::Long::order == $Getopt::Long::PERMUTE ) { # Try non-options call-back. my $cb; if ( (defined ($cb = $linkage{'<>'})) ) { &$cb($opt); } else { push (@ret, $opt); } next; --- 711,725 ---- } # Not an option. Save it if we $PERMUTE and don't have a <>. ! elsif ( $order == $PERMUTE ) { # Try non-options call-back. my $cb; if ( (defined ($cb = $linkage{'<>'})) ) { &$cb($opt); } else { + print STDERR ("=> saving \"$opt\" ", + "(not an option, may permute)\n") if $debug; push (@ret, $opt); } next; *************** *** 686,714 **** else { # Push this one back and exit. unshift (@ARGV, $opt); ! return ($Getopt::Long::error == 0); } #### Look it up ### ! $opt =~ tr/A-Z/a-z/ if $Getopt::Long::ignorecase; ! ! my $tryopt = $opt; ! if ( $Getopt::Long::autoabbrev ) { ! my $pat; # Turn option name into pattern. ! ($pat = $opt) =~ s/(\W)/\\$1/g; # Look up in option names. my @hits = grep (/^$pat/, @opctl); ! print STDERR ("=> ", 0+@hits, " hits (@hits) with \"$pat\" ", ! "out of ", 0+@opctl, "\n") if $debug; # Check for ambiguous results. unless ( (@hits <= 1) || (grep ($_ eq $opt, @hits) == 1) ) { print STDERR ("Option ", $opt, " is ambiguous (", join(", ", @hits), ")\n"); ! $Getopt::Long::error++; next; } --- 729,769 ---- else { # Push this one back and exit. unshift (@ARGV, $opt); ! return ($error == 0); } #### Look it up ### ! my $tryopt = $opt; # option to try ! my $optbl = \%opctl; # table to look it up (long names) + if ( $bundling && $starter eq '-' ) { + # Unbundle single letter option. + $rest = substr ($tryopt, 1); + $tryopt = substr ($tryopt, 0, 1); + $tryopt = lc ($tryopt) if $ignorecase > 1; + print STDERR ("=> $starter$tryopt unbundled from ", + "$starter$tryopt$rest\n") if $debug; + $rest = undef unless $rest ne ''; + $optbl = \%bopctl; # look it up in the short names table + } + + # Try auto-abbreviation. + elsif ( $autoabbrev ) { + # Downcase if allowed. + $tryopt = $opt = lc ($opt) if $ignorecase; # Turn option name into pattern. ! my $pat = quotemeta ($opt); # Look up in option names. my @hits = grep (/^$pat/, @opctl); ! print STDERR ("=> ", scalar(@hits), " hits (@hits) with \"$pat\" ", ! "out of ", scalar(@opctl), "\n") if $debug; # Check for ambiguous results. unless ( (@hits <= 1) || (grep ($_ eq $opt, @hits) == 1) ) { print STDERR ("Option ", $opt, " is ambiguous (", join(", ", @hits), ")\n"); ! $error++; next; } *************** *** 720,731 **** } } ! my $type; ! unless ( defined ( $type = $opctl{$tryopt} ) ) { ! print STDERR ("Unknown option: ", $opt, "\n"); ! $Getopt::Long::error++; next; } $opt = $tryopt; print STDERR ("=> found \"$type\" for ", $opt, "\n") if $debug; --- 775,788 ---- } } ! # Check validity by fetching the info. ! my $type = $optbl->{$tryopt}; ! unless ( defined $type ) { ! warn ("Unknown option: ", $opt, "\n"); ! $error++; next; } + # Apparently valid. $opt = $tryopt; print STDERR ("=> found \"$type\" for ", $opt, "\n") if $debug; *************** *** 735,741 **** if ( $type eq '' || $type eq '!' ) { if ( defined $optarg ) { print STDERR ("Option ", $opt, " does not take an argument\n"); ! $Getopt::Long::error++; } elsif ( $type eq '' ) { $arg = 1; # supply explicit value --- 792,798 ---- if ( $type eq '' || $type eq '!' ) { if ( defined $optarg ) { print STDERR ("Option ", $opt, " does not take an argument\n"); ! $error++; } elsif ( $type eq '' ) { $arg = 1; # supply explicit value *************** *** 744,749 **** --- 801,808 ---- substr ($opt, 0, 2) = ''; # strip NO prefix $arg = 0; # supply explicit value } + # When unbundling, unshift the rest with the starter. + unshift (@ARGV, $starter.$rest) if defined $rest; next; } *************** *** 752,763 **** ($mand, $type, $array) = $type =~ /^(.)(.)(@?)$/; # Check if there is an option argument available. ! if ( defined $optarg ? ($optarg eq '') : (@ARGV <= 0) ) { ! # Complain if this option needs an argument. if ( $mand eq "=" ) { print STDERR ("Option ", $opt, " requires an argument\n"); ! $Getopt::Long::error++; } if ( $mand eq ":" ) { $arg = $type eq "s" ? '' : 0; --- 811,822 ---- ($mand, $type, $array) = $type =~ /^(.)(.)(@?)$/; # Check if there is an option argument available. ! if ( defined $optarg ? ($optarg eq '') ! : !(defined $rest || @ARGV > 0) ) { # Complain if this option needs an argument. if ( $mand eq "=" ) { print STDERR ("Option ", $opt, " requires an argument\n"); ! $error++; } if ( $mand eq ":" ) { $arg = $type eq "s" ? '' : 0; *************** *** 766,772 **** } # Get (possibly optional) argument. ! $arg = defined $optarg ? $optarg : shift (@ARGV); #### Check if the argument is valid for this option #### --- 825,832 ---- } # Get (possibly optional) argument. ! $arg = (defined $rest ? $rest ! : (defined $optarg ? $optarg : shift (@ARGV))); #### Check if the argument is valid for this option #### *************** *** 775,782 **** next if $mand eq "="; # An optional string takes almost anything. ! next if defined $optarg; ! next if $arg eq "-"; # Check for option or option list terminator. if ($arg eq $argend || --- 835,842 ---- next if $mand eq "="; # An optional string takes almost anything. ! next if defined $optarg || defined $rest; ! next if $arg eq "-"; # ?? # Check for option or option list terminator. if ($arg eq $argend || *************** *** 794,805 **** if ( defined $optarg || $mand eq "=" ) { print STDERR ("Value \"", $arg, "\" invalid for option ", $opt, " (number expected)\n"); ! $Getopt::Long::error++; undef $arg; # don't assign it } else { # Push back. ! unshift (@ARGV, $arg); # Supply default value. $arg = 0; } --- 854,867 ---- if ( defined $optarg || $mand eq "=" ) { print STDERR ("Value \"", $arg, "\" invalid for option ", $opt, " (number expected)\n"); ! $error++; undef $arg; # don't assign it + # Push back. + unshift (@ARGV, $starter.$rest) if defined $rest; } else { # Push back. ! unshift (@ARGV, defined $rest ? $starter.$rest : $arg); # Supply default value. $arg = 0; } *************** *** 812,823 **** if ( defined $optarg || $mand eq "=" ) { print STDERR ("Value \"", $arg, "\" invalid for option ", $opt, " (real number expected)\n"); ! $Getopt::Long::error++; undef $arg; # don't assign it } else { # Push back. ! unshift (@ARGV, $arg); # Supply default value. $arg = 0.0; } --- 874,887 ---- if ( defined $optarg || $mand eq "=" ) { print STDERR ("Value \"", $arg, "\" invalid for option ", $opt, " (real number expected)\n"); ! $error++; undef $arg; # don't assign it + # Push back. + unshift (@ARGV, $starter.$rest) if defined $rest; } else { # Push back. ! unshift (@ARGV, defined $rest ? $starter.$rest : $arg); # Supply default value. $arg = 0.0; } *************** *** 877,891 **** } # Finish. ! if ( $Getopt::Long::order == $Getopt::Long::PERMUTE ) { # Push back accumulated arguments unshift (@ARGV, @ret) if @ret > 0; } ! return ($Getopt::Long::error == 0); } ################ Package return ################ ! # Returning 1 is so boring... ! $Getopt::Long::major_version * 1000 + $Getopt::Long::minor_version; --- 941,956 ---- } # Finish. ! if ( $order == $PERMUTE ) { # Push back accumulated arguments + print STDERR ("=> restoring \"", join('" "', @ret), "\"\n") + if $debug && @ret > 0; unshift (@ARGV, @ret) if @ret > 0; } ! return ($error == 0); } ################ Package return ################ ! 1; #~ Eliminate $& to avoid runtime penalty diff -Pcr perl5_003/lib/IPC/Open2.pm perl5_003_01/lib/IPC/Open2.pm *** perl5_003/lib/IPC/Open2.pm Mon Jan 29 17:49:57 1996 --- perl5_003_01/lib/IPC/Open2.pm Wed May 1 17:10:17 1996 *************** *** 80,87 **** # force unqualified filehandles into callers' package local($package) = caller; ! $dad_rdr =~ s/^[^']+$/$package'$&/ unless ref $dad_rdr; ! $dad_wtr =~ s/^[^']+$/$package'$&/ unless ref $dad_wtr; local($kid_rdr) = ++$fh; local($kid_wtr) = ++$fh; --- 80,87 ---- # force unqualified filehandles into callers' package local($package) = caller; ! $dad_rdr =~ s/^([^']+$)/$package'$1/ unless ref $dad_rdr; ! $dad_wtr =~ s/^([^']+$)/$package'$1/ unless ref $dad_wtr; local($kid_rdr) = ++$fh; local($kid_wtr) = ++$fh; #~ Eliminate $& to avoid runtime penalty diff -Pcr perl5_003/lib/IPC/Open3.pm perl5_003_01/lib/IPC/Open3.pm *** perl5_003/lib/IPC/Open3.pm Mon Jan 29 17:50:03 1996 --- perl5_003_01/lib/IPC/Open3.pm Wed May 1 17:10:19 1996 *************** *** 83,91 **** # force unqualified filehandles into callers' package my($package) = caller; ! $dad_wtr =~ s/^[^:]+$/$package\:\:$&/ unless ref $dad_wtr; ! $dad_rdr =~ s/^[^:]+$/$package\:\:$&/ unless ref $dad_rdr; ! $dad_err =~ s/^[^:]+$/$package\:\:$&/ unless ref $dad_err; my($kid_rdr) = ++$fh; my($kid_wtr) = ++$fh; --- 83,91 ---- # force unqualified filehandles into callers' package my($package) = caller; ! $dad_wtr =~ s/^([^:]+$)/$package\:\:$1/ unless ref $dad_wtr; ! $dad_rdr =~ s/^([^:]+$)/$package\:\:$1/ unless ref $dad_rdr; ! $dad_err =~ s/^([^:]+$)/$package\:\:$1/ unless ref $dad_err; my($kid_rdr) = ++$fh; my($kid_wtr) = ++$fh; #~ Extend to handle 8-bit characters in input diff -Pcr perl5_003/lib/Pod/Text.pm perl5_003_01/lib/Pod/Text.pm *** perl5_003/lib/Pod/Text.pm Mon Mar 25 01:04:47 1996 --- perl5_003_01/lib/Pod/Text.pm Thu Jul 4 14:50:29 1996 *************** *** 357,365 **** sub init_noremap { die "unmatched init" if $mapready++; ! if ( /[\200-\377]/ ) { ! warn "hit bit char in input stream"; ! } } sub clear_noremap { --- 357,364 ---- sub init_noremap { die "unmatched init" if $mapready++; ! #mask off high bit characters in input stream ! s/([\200-\377])/"E<".ord($1).">"/ge; } sub clear_noremap { *************** *** 370,382 **** # otherwise the interative \w<> processing would have # been hosed by the E s { ! E< ! ( [A-Za-z]+ ) > } { do { ! defined $HTML_Escapes{$1} ! ? do { $HTML_Escapes{$1} } : do { warn "Unknown escape: $& in $_"; "E<$1>"; --- 369,387 ---- # otherwise the interative \w<> processing would have # been hosed by the E s { ! E< ! ( ! ( \d+ ) ! | ( [A-Za-z]+ ) ! ) > } { do { ! defined $2 ! ? chr($2) ! : ! defined $HTML_Escapes{$3} ! ? do { $HTML_Escapes{$3} } : do { warn "Unknown escape: $& in $_"; "E<$1>"; #~ Update docs diff -Pcr perl5_003/lib/SelfLoader.pm perl5_003_01/lib/SelfLoader.pm *** perl5_003/lib/SelfLoader.pm Mon Jan 22 20:43:10 1996 --- perl5_003_01/lib/SelfLoader.pm Thu Jul 11 12:22:46 1996 *************** *** 119,235 **** =head1 DESCRIPTION This module tells its users that functions in the FOOBAR package are to be ! autoloaded from after the __DATA__ token. See also L. =head2 The __DATA__ token ! The __DATA__ token tells the perl compiler that the perl code ! for compilation is finished. Everything after the __DATA__ token is available for reading via the filehandle FOOBAR::DATA, ! where FOOBAR is the name of the current package when the __DATA__ ! token is reached. This works just the same as __END__ does in ! package 'main', but for other modules data after __END__ is not ! automatically retreivable , whereas data after __DATA__ is. ! The __DATA__ token is not recognized in versions of perl prior to 5.001m. ! Note that it is possible to have __DATA__ tokens in the same package ! in multiple files, and that the last __DATA__ token in a given package that is encountered by the compiler is the one accessible ! by the filehandle. This also applies to __END__ and main, i.e. if ! the 'main' program has an __END__, but a module 'require'd (_not_ 'use'd) ! by that program has a 'package main;' declaration followed by an '__DATA__', ! then the DATA filehandle is set to access the data after the __DATA__ ! in the module, _not_ the data after the __END__ token in the 'main' program, since the compiler encounters the 'require'd file later. =head2 SelfLoader autoloading ! The SelfLoader works by the user placing the __DATA__ ! token _after_ perl code which needs to be compiled and ! run at 'require' time, but _before_ subroutine declarations that can be loaded in later - usually because they may never be called. ! The SelfLoader will read from the FOOBAR::DATA filehandle to ! load in the data after __DATA__, and load in any subroutine when it is called. The costs are the one-time parsing of the ! data after __DATA__, and a load delay for the _first_ call of any autoloaded function. The benefits (hopefully) are a speeded up compilation phase, with no need to load functions which are never used. ! The SelfLoader will stop reading from __DATA__ if ! it encounters the __END__ token - just as you would expect. ! If the __END__ token is present, and is followed by the ! token DATA, then the SelfLoader leaves the FOOBAR::DATA filehandle open on the line after that token. ! The SelfLoader exports the AUTOLOAD subroutine to the ! package using the SelfLoader, and this loads the called subroutine when it is first called. There is no advantage to putting subroutines which will _always_ ! be called after the __DATA__ token. =head2 Autoloading and package lexicals A 'my $pack_lexical' statement makes the variable $pack_lexical ! local _only_ to the file up to the __DATA__ token. Subroutines declared elsewhere _cannot_ see these types of variables, just as if you declared subroutines in the package but in another file, they cannot see these variables. So specifically, autoloaded functions cannot see package ! lexicals (this applies to both the SelfLoader and the Autoloader). =head2 SelfLoader and AutoLoader ! The SelfLoader can replace the AutoLoader - just change 'use AutoLoader' ! to 'use SelfLoader' (though note that the SelfLoader exports the AUTOLOAD function - but if you have your own AUTOLOAD and are using the AutoLoader too, you probably know what you're doing), ! and the __END__ token to __DATA__. You will need perl version 5.001m or later to use this (version 5.001 with all patches up to patch m). ! There is no need to inherit from the SelfLoader. ! The SelfLoader works similarly to the AutoLoader, but picks up the ! subs from after the __DATA__ instead of in the 'lib/auto' directory. There is a maintainance gain in not needing to run AutoSplit on the module at installation, and a runtime gain in not needing to keep opening and closing files to load subs. There is a runtime loss in needing ! to parse the code after the __DATA__. =head2 __DATA__, __END__, and the FOOBAR::DATA filehandle. This section is only relevant if you want to use ! the FOOBAR::DATA together with the SelfLoader. ! Data after the __DATA__ token in a module is read using the ! FOOBAR::DATA filehandle. __END__ can still be used to denote the end ! of the __DATA__ section if followed by the token DATA - this is supported ! by the SelfLoader. The FOOBAR::DATA filehandle is left open if an __END__ ! followed by a DATA is found, with the filehandle positioned at the start ! of the line after the __END__ token. If no __END__ token is present, ! or an __END__ token with no DATA token on the same line, then the filehandle ! is closed. ! ! The SelfLoader reads from wherever the current ! position of the FOOBAR::DATA filehandle is, until the ! EOF or __END__. This means that if you want to use that filehandle (and ONLY if you want to), you should either 1. Put all your subroutine declarations immediately after ! the __DATA__ token and put your own data after those ! declarations, using the __END__ token to mark the end ! of subroutine declarations. You must also ensure that the SelfLoader reads first by calling 'SelfLoader->load_stubs();', or by using a function which is selfloaded; or ! 2. You should read the FOOBAR::DATA filehandle first, leaving the handle open and positioned at the first line of subroutine declarations. --- 119,241 ---- =head1 DESCRIPTION This module tells its users that functions in the FOOBAR package are to be ! autoloaded from after the C<__DATA__> token. See also ! L. =head2 The __DATA__ token ! The C<__DATA__> token tells the perl compiler that the perl code ! for compilation is finished. Everything after the C<__DATA__> token is available for reading via the filehandle FOOBAR::DATA, ! where FOOBAR is the name of the current package when the C<__DATA__> ! token is reached. This works just the same as C<__END__> does in ! package 'main', but for other modules data after C<__END__> is not ! automatically retreivable , whereas data after C<__DATA__> is. ! The C<__DATA__> token is not recognized in versions of perl prior to 5.001m. ! Note that it is possible to have C<__DATA__> tokens in the same package ! in multiple files, and that the last C<__DATA__> token in a given package that is encountered by the compiler is the one accessible ! by the filehandle. This also applies to C<__END__> and main, i.e. if ! the 'main' program has an C<__END__>, but a module 'require'd (_not_ 'use'd) ! by that program has a 'package main;' declaration followed by an 'C<__DATA__>', ! then the C filehandle is set to access the data after the C<__DATA__> ! in the module, _not_ the data after the C<__END__> token in the 'main' program, since the compiler encounters the 'require'd file later. =head2 SelfLoader autoloading ! The B works by the user placing the C<__DATA__> ! token I perl code which needs to be compiled and ! run at 'require' time, but I subroutine declarations that can be loaded in later - usually because they may never be called. ! The B will read from the FOOBAR::DATA filehandle to ! load in the data after C<__DATA__>, and load in any subroutine when it is called. The costs are the one-time parsing of the ! data after C<__DATA__>, and a load delay for the _first_ call of any autoloaded function. The benefits (hopefully) are a speeded up compilation phase, with no need to load functions which are never used. ! The B will stop reading from C<__DATA__> if ! it encounters the C<__END__> token - just as you would expect. ! If the C<__END__> token is present, and is followed by the ! token DATA, then the B leaves the FOOBAR::DATA filehandle open on the line after that token. ! The B exports the C subroutine to the ! package using the B, and this loads the called subroutine when it is first called. There is no advantage to putting subroutines which will _always_ ! be called after the C<__DATA__> token. =head2 Autoloading and package lexicals A 'my $pack_lexical' statement makes the variable $pack_lexical ! local _only_ to the file up to the C<__DATA__> token. Subroutines declared elsewhere _cannot_ see these types of variables, just as if you declared subroutines in the package but in another file, they cannot see these variables. So specifically, autoloaded functions cannot see package ! lexicals (this applies to both the B and the Autoloader). ! The C pragma provides an alternative to defining package-level ! globals that will be visible to autoloaded routines. See the documentation ! on B in the pragma section of L. =head2 SelfLoader and AutoLoader ! The B can replace the AutoLoader - just change 'use AutoLoader' ! to 'use SelfLoader' (though note that the B exports the AUTOLOAD function - but if you have your own AUTOLOAD and are using the AutoLoader too, you probably know what you're doing), ! and the C<__END__> token to C<__DATA__>. You will need perl version 5.001m or later to use this (version 5.001 with all patches up to patch m). ! There is no need to inherit from the B. ! The B works similarly to the AutoLoader, but picks up the ! subs from after the C<__DATA__> instead of in the 'lib/auto' directory. There is a maintainance gain in not needing to run AutoSplit on the module at installation, and a runtime gain in not needing to keep opening and closing files to load subs. There is a runtime loss in needing ! to parse the code after the C<__DATA__>. Details of the B and ! another view of these distinctions can be found in that module's ! documentation. =head2 __DATA__, __END__, and the FOOBAR::DATA filehandle. This section is only relevant if you want to use ! the C together with the B. ! Data after the C<__DATA__> token in a module is read using the ! FOOBAR::DATA filehandle. C<__END__> can still be used to denote the end ! of the C<__DATA__> section if followed by the token DATA - this is supported ! by the B. The C filehandle is left open if an ! C<__END__> followed by a DATA is found, with the filehandle positioned at ! the start of the line after the C<__END__> token. If no C<__END__> token is ! present, or an C<__END__> token with no DATA token on the same line, then ! the filehandle is closed. ! ! The B reads from wherever the current ! position of the C filehandle is, until the ! EOF or C<__END__>. This means that if you want to use that filehandle (and ONLY if you want to), you should either 1. Put all your subroutine declarations immediately after ! the C<__DATA__> token and put your own data after those ! declarations, using the C<__END__> token to mark the end ! of subroutine declarations. You must also ensure that the B reads first by calling 'SelfLoader->load_stubs();', or by using a function which is selfloaded; or ! 2. You should read the C filehandle first, leaving the handle open and positioned at the first line of subroutine declarations. *************** *** 255,262 **** adding the statement 'SelfLoader->load_stubs();' to the module to do this. ! The alternative is to put the stubs in before the __DATA__ token BEFORE ! releasing the module, and for this purpose the Devel::SelfStubber module is available. However this does require the extra step of ensuring that the stubs are in the module. If this is done I strongly recommend that this is done BEFORE releasing the module - it should NOT be done --- 261,268 ---- adding the statement 'SelfLoader->load_stubs();' to the module to do this. ! The alternative is to put the stubs in before the C<__DATA__> token BEFORE ! releasing the module, and for this purpose the C module is available. However this does require the extra step of ensuring that the stubs are in the module. If this is done I strongly recommend that this is done BEFORE releasing the module - it should NOT be done *************** *** 265,274 **** =head1 Multiple packages and fully qualified subroutine names Subroutines in multiple packages within the same file are supported - but you ! should note that this requires exporting the SelfLoader::AUTOLOAD to every package which requires it. This is done automatically by the ! SelfLoader when it first loads the subs into the cache, but you should ! really specify it in the initialization before the __DATA__ by putting a 'use SelfLoader' statement in each package. Fully qualified subroutine names are also supported. For example, --- 271,280 ---- =head1 Multiple packages and fully qualified subroutine names Subroutines in multiple packages within the same file are supported - but you ! should note that this requires exporting the C to every package which requires it. This is done automatically by the ! B when it first loads the subs into the cache, but you should ! really specify it in the initialization before the C<__DATA__> by putting a 'use SelfLoader' statement in each package. Fully qualified subroutine names are also supported. For example, *************** *** 278,285 **** package baz; sub dob {32} ! will all be loaded correctly by the SelfLoader, and the SelfLoader will ensure that the packages 'foo' and 'baz' correctly have the ! SelfLoader AUTOLOAD method when the data after __DATA__ is first parsed. =cut --- 284,292 ---- package baz; sub dob {32} ! will all be loaded correctly by the B, and the B will ensure that the packages 'foo' and 'baz' correctly have the ! B C method when the data after C<__DATA__> is first ! parsed. =cut #~ Incorporate new "use " syntax diff -Pcr perl5_003/lib/Symbol.pm perl5_003_01/lib/Symbol.pm *** perl5_003/lib/Symbol.pm Mon Jun 24 16:07:54 1996 --- perl5_003_01/lib/Symbol.pm Sun Jul 7 20:02:46 1996 *************** *** 46,52 **** =cut ! BEGIN { require 5.002; } require Exporter; @ISA = qw(Exporter); --- 46,52 ---- =cut ! use 5.002; require Exporter; @ISA = qw(Exporter); #~ Fix VMS test to eliminate void context warning diff -Pcr perl5_003/lib/Sys/Hostname.pm perl5_003_01/lib/Sys/Hostname.pm *** perl5_003/lib/Sys/Hostname.pm Mon Mar 25 01:04:48 1996 --- perl5_003_01/lib/Sys/Hostname.pm Tue May 14 21:53:41 1996 *************** *** 39,45 **** if ($^O eq 'VMS') { # method 2 - no sockets ==> return DECnet node name ! eval {gethostbyname('me')}; if ($@) { return $host = $ENV{'SYS$NODE'}; } # method 3 - has someone else done the job already? It's common for the --- 39,45 ---- if ($^O eq 'VMS') { # method 2 - no sockets ==> return DECnet node name ! eval {my($test) = gethostbyname('me')}; # returns 'me' on most systems if ($@) { return $host = $ENV{'SYS$NODE'}; } # method 3 - has someone else done the job already? It's common for the #~ Correct documentation for calling sequence of syslog() function #~ Move call to hostname() into connect() function, and eliminate domain suffix diff -Pcr perl5_003/lib/Sys/Syslog.pm perl5_003_01/lib/Sys/Syslog.pm *** perl5_003/lib/Sys/Syslog.pm Mon Mar 25 01:04:48 1996 --- perl5_003_01/lib/Sys/Syslog.pm Tue Jun 18 20:30:13 1996 *************** *** 23,29 **** use Sys::Syslog; openlog $ident, $logopt, $facility; ! syslog $priority, $mask, $format, @args; $oldmask = setlogmask $mask_priority; closelog; --- 23,29 ---- use Sys::Syslog; openlog $ident, $logopt, $facility; ! syslog $priority, $format, @args; $oldmask = setlogmask $mask_priority; closelog; *************** *** 43,51 **** I<$logopt> contains one or more of the words I, I, I, I. I<$facility> specifies the part of the system ! =item syslog $priority, $mask, $format, @args ! If I<$priority> and I<$mask> permit, logs I<($format, @args)> printed as by C, with the addition that I<%m> is replaced with C<"$!"> (the latest error message). --- 43,51 ---- I<$logopt> contains one or more of the words I, I, I, I. I<$facility> specifies the part of the system ! =item syslog $priority, $format, @args ! If I<$priority> permits, logs I<($format, @args)> printed as by C, with the addition that I<%m> is replaced with C<"$!"> (the latest error message). *************** *** 89,96 **** =cut - $host = hostname() unless $host; # set $Syslog::host to change - require 'syslog.ph'; $maskpri = &LOG_UPTO(&LOG_DEBUG); --- 89,94 ---- *************** *** 201,207 **** sub connect { unless ($host) { require Sys::Hostname; ! $host = Sys::Hostname::hostname(); } my $udp = getprotobyname('udp'); my $syslog = getservbyname('syslog','udp'); --- 199,206 ---- sub connect { unless ($host) { require Sys::Hostname; ! my($host_uniq) = Sys::Hostname::hostname(); ! ($host) = $host_uniq =~ /(\w+)/; } my $udp = getprotobyname('udp'); my $syslog = getservbyname('syslog','udp'); #~ Incorporate new "use " syntax #~ Update to version 1.12, providing improved "skipped" message and #~ first-pass Unix support for Devel::CoreStack diff -Pcr perl5_003/lib/Test/Harness.pm perl5_003_01/lib/Test/Harness.pm *** perl5_003/lib/Test/Harness.pm Mon Feb 12 14:55:52 1996 --- perl5_003_01/lib/Test/Harness.pm Tue Jul 9 12:22:00 1996 *************** *** 1,13 **** package Test::Harness; use Exporter; use Benchmark; use Config; use FileHandle; ! use vars qw($VERSION $verbose $switches); ! require 5.002; ! $VERSION = "1.07"; @ISA=('Exporter'); @EXPORT= qw(&runtests); --- 1,14 ---- package Test::Harness; + use 5.002; use Exporter; use Benchmark; use Config; use FileHandle; ! use vars qw($VERSION $verbose $switches $have_devel_corestack); ! $have_devel_corestack = 0; ! $VERSION = "1.12"; @ISA=('Exporter'); @EXPORT= qw(&runtests); *************** *** 41,80 **** if( $verbose ){ print $_; } ! unless (/^\s*\#/) { ! if (/^1\.\.([0-9]+)/) { ! $max = $1; ! $totmax += $max; ! $files++; ! $next = 1; ! } elsif ($max && /^(not\s+)?ok\b/) { ! my $this = $next; ! if (/^not ok\s*(\d*)/){ ! $this = $1 if $1 > 0; ! push @failed, $this; ! } elsif (/^ok\s*(\d*)/) { ! $this = $1 if $1 > 0; ! $ok++; ! $totok++; ! } ! if ($this > $next) { ! # warn "Test output counter mismatch [test $this]\n"; ! # no need to warn probably ! push @failed, $next..$this-1; ! } elsif ($this < $next) { ! #we have seen more "ok" lines than the number suggests ! warn "Aborting test: output counter mismatch [test $this answered when test $next expected]\n"; ! last; ! } ! $next = $this + 1; } } } $fh->close; # must close to reap child resource values my $wstatus = $?; ! my $estatus = $wstatus >> 8; ! if ($ok == $max && $next == $max+1 && ! $estatus) { ! print "ok\n"; $good++; } elsif ($max) { if ($next <= $max) { --- 42,93 ---- if( $verbose ){ print $_; } ! if (/^1\.\.([0-9]+)/) { ! $max = $1; ! $totmax += $max; ! $files++; ! $next = 1; ! } elsif ($max && /^(not\s+)?ok\b/) { ! my $this = $next; ! if (/^not ok\s*(\d*)/){ ! $this = $1 if $1 > 0; ! push @failed, $this; ! } elsif (/^ok\s*(\d*)/) { ! $this = $1 if $1 > 0; ! $ok++; ! $totok++; } + if ($this > $next) { + # warn "Test output counter mismatch [test $this]\n"; + # no need to warn probably + push @failed, $next..$this-1; + } elsif ($this < $next) { + #we have seen more "ok" lines than the number suggests + warn "Confused test output: test $this answered after test ", $next-1, "\n"; + $next = $this; + } + $next = $this + 1; } } $fh->close; # must close to reap child resource values my $wstatus = $?; ! my $estatus = $^O eq 'VMS' ? $wstatus : $wstatus >> 8; ! if ($^O eq 'VMS' ? !($wstatus & 1) : $wstatus) { ! print "dubious\n\tTest returned status $estatus (wstat $wstatus)\n"; ! if (corestatus($wstatus)) { # until we have a wait module ! if ($have_devel_corestack) { ! Devel::CoreStack::stack($^X); ! } else { ! print "\ttest program seems to have generated a core\n"; ! } ! } ! $bad++; ! } elsif ($ok == $max && $next == $max+1) { ! if ($max) { ! print "ok\n"; ! } else { ! print "skipping test on this platform\n"; ! } $good++; } elsif ($max) { if ($next <= $max) { *************** *** 83,98 **** if (@failed) { print canonfailed($max,@failed); } else { ! print "Don't know which tests failed for some reason\n"; } $bad++; } elsif ($next == 0) { print "FAILED before any test output arrived\n"; $bad++; } - if ($wstatus) { - print "\tTest returned status $estatus (wstat $wstatus)\n"; - } } my $t_total = timediff(new Benchmark, $t_start); --- 96,108 ---- if (@failed) { print canonfailed($max,@failed); } else { ! print "Don't know which tests failed: got $ok ok, expected $max\n"; } $bad++; } elsif ($next == 0) { print "FAILED before any test output arrived\n"; $bad++; } } my $t_total = timediff(new Benchmark, $t_start); *************** *** 102,108 **** die "FAILED--no tests were run for some reason.\n"; } elsif ($totmax==0) { my $blurb = $total==1 ? "script" : "scripts"; ! die "FAILED--$total test $blurb could be run, alas -- no output ever seen\n"; } else { $pct = sprintf("%.2f", $good / $total * 100); my $subpct = sprintf " %d/%d subtests failed, %.2f%% okay.", --- 112,118 ---- die "FAILED--no tests were run for some reason.\n"; } elsif ($totmax==0) { my $blurb = $total==1 ? "script" : "scripts"; ! die "FAILED--$total test $blurb could be run, alas--no output ever seen\n"; } else { $pct = sprintf("%.2f", $good / $total * 100); my $subpct = sprintf " %d/%d subtests failed, %.2f%% okay.", *************** *** 116,121 **** --- 126,150 ---- printf("Files=%d, Tests=%d, %s\n", $files, $totmax, timestr($t_total, 'nop')); } + sub corestatus { + my($st) = @_; + my($ret); + + eval {require 'wait.ph'}; + if ($@) { + SWITCH: { + $ret = ($st & 0200); # Tim says, this is for 90% + } + } else { + $ret = WCOREDUMP($st); + } + + eval {require Devel::CoreStack}; + $have_devel_corestack++ unless $@; + + $ret; + } + sub canonfailed ($@) { my($max,@failed) = @_; my %seen; *************** *** 165,186 **** Perl test scripts print to standard output C<"ok N"> for each single test, where C is an increasing sequence of integers. The first line ! output by a standard test scxript is C<"1..M"> with C being the number of tests that should be run within the test ! script. Test::Harness::runscripts(@tests) runs all the testscripts named as arguments and checks standard output for the expected C<"ok N"> strings. ! After all tests have been performed, runscripts() prints some performance statistics that are computed by the Benchmark module. =head2 The test script output Any output from the testscript to standard error is ignored and bypassed, thus will be seen by the user. Lines written to standard ! output that look like perl comments (start with C) are ! discarded. Lines containing C are interpreted as ! feedback for runtests(). It is tolerated if the test numbers after C are omitted. In this case Test::Harness maintains temporarily its own counter until the --- 194,214 ---- Perl test scripts print to standard output C<"ok N"> for each single test, where C is an increasing sequence of integers. The first line ! output by a standard test script is C<"1..M"> with C being the number of tests that should be run within the test ! script. Test::Harness::runtests(@tests) runs all the testscripts named as arguments and checks standard output for the expected C<"ok N"> strings. ! After all tests have been performed, runtests() prints some performance statistics that are computed by the Benchmark module. =head2 The test script output Any output from the testscript to standard error is ignored and bypassed, thus will be seen by the user. Lines written to standard ! output containing C are interpreted as feedback for ! runtests(). All other lines are discarded. It is tolerated if the test numbers after C are omitted. In this case Test::Harness maintains temporarily its own counter until the *************** *** 201,212 **** Failed 3/6 tests, 50.00% okay The global variable $Test::Harness::verbose is exportable and can be ! used to let runscripts() display the standard output of the script without altering the behavior otherwise. =head1 EXPORT ! C<&runscripts> is exported by Test::Harness per default. =head1 DIAGNOSTICS --- 229,240 ---- Failed 3/6 tests, 50.00% okay The global variable $Test::Harness::verbose is exportable and can be ! used to let runtests() display the standard output of the script without altering the behavior otherwise. =head1 EXPORT ! C<&runtests> is exported by Test::Harness per default. =head1 DIAGNOSTICS #~ Allow for "0" as a word diff -Pcr perl5_003/lib/Text/ParseWords.pm perl5_003_01/lib/Text/ParseWords.pm *** perl5_003/lib/Text/ParseWords.pm Mon Mar 25 01:04:52 1996 --- perl5_003_01/lib/Text/ParseWords.pm Wed May 1 15:03:41 1996 *************** *** 92,98 **** local(@words,$snippet,$field,$_); $_ = join('', @lines); ! while ($_) { $field = ''; for (;;) { $snippet = ''; --- 92,98 ---- local(@words,$snippet,$field,$_); $_ = join('', @lines); ! while (length($_)) { $field = ''; for (;;) { $snippet = ''; *************** *** 111,121 **** $snippet = $1; $snippet = "\\$snippet" if ($keep); } ! elsif (!$_ || s/^$delim//) { last; } else { ! while ($_ && !(/^$delim/ || /^['"\\]/)) { $snippet .= substr($_, 0, 1); substr($_, 0, 1) = ''; } --- 111,121 ---- $snippet = $1; $snippet = "\\$snippet" if ($keep); } ! elsif (!length($_) || s/^$delim//) { last; } else { ! while (length($_) && !(/^$delim/ || /^['"\\]/)) { $snippet .= substr($_, 0, 1); substr($_, 0, 1) = ''; } #~ Update to version 96.051501 diff -Pcr perl5_003/lib/Text/Tabs.pm perl5_003_01/lib/Text/Tabs.pm *** perl5_003/lib/Text/Tabs.pm Mon Jan 22 20:45:13 1996 --- perl5_003_01/lib/Text/Tabs.pm Mon Jul 8 13:11:09 1996 *************** *** 1,43 **** - # - # expand and unexpand tabs as per the unix expand and - # unexpand programs. - # - # expand and unexpand operate on arrays of lines. Do not - # feed strings that contain newlines to them. - # - # David Muir Sharnoff - # - # Version: 9/21/95 - # - - =head1 NAME - - Text::Tabs -- expand and unexpand tabs - - =head1 SYNOPSIS - - use Text::Tabs; - - #$tabstop = 8; # Defaults - print expand("Hello\tworld"); - print unexpand("Hello, world"); - $tabstop = 4; - print join("\n",expand(split(/\n/, - "Hello\tworld,\nit's a nice day.\n" - ))); - - =head1 DESCRIPTION - - This module expands and unexpands tabs into spaces, as per the unix expand - and unexpand programs. Either function should be passed an array of strings - (newlines may I be included, and should be used to split an incoming - string into separate elements.) which will be processed and returned. - - =head1 AUTHOR - - David Muir Sharnoff - - =cut package Text::Tabs; --- 1,3 ---- *************** *** 46,62 **** @ISA = (Exporter); @EXPORT = qw(expand unexpand $tabstop); ! $tabstop = 8; sub expand { my @l = @_; for $_ (@l) { ! 1 while s/^([^\t]*)(\t+)/ ! $1 . (" " x ! ($tabstop * length($2) ! - (length($1) % $tabstop))) ! /e; } return @l if wantarray; return @l[0]; --- 6,30 ---- @ISA = (Exporter); @EXPORT = qw(expand unexpand $tabstop); ! use vars qw($VERSION $tabstop $debug); ! $VERSION = 96.051501; ! ! use strict; ! ! BEGIN { ! $tabstop = 8; ! $debug = 0; ! } sub expand { my @l = @_; for $_ (@l) { ! 1 while s/(^|\n)([^\t\n]*)(\t+)/ ! $1. $2 . (" " x ! ($tabstop * length($3) ! - (length($2) % $tabstop))) ! /sex; } return @l if wantarray; return @l[0]; *************** *** 64,80 **** sub unexpand { ! my @l = &expand(@_); my @e; for $x (@l) { ! @e = split(/(.{$tabstop})/,$x); ! for $_ (@e) { ! s/ +$/\t/; } ! $x = join('',@e); } return @l if wantarray; return @l[0]; } 1; --- 32,97 ---- sub unexpand { ! my @l = @_; my @e; + my $x; + my $line; + my @lines; + my $lastbit; for $x (@l) { ! @lines = split("\n", $x, -1); ! for $line (@lines) { ! $line = expand($line); ! @e = split(/(.{$tabstop})/,$line,-1); ! $lastbit = pop(@e); ! $lastbit = '' unless defined $lastbit; ! $lastbit = "\t" ! if $lastbit eq " "x$tabstop; ! for $_ (@e) { ! if ($debug) { ! my $x = $_; ! $x =~ s/\t/^I\t/gs; ! print "sub on '$x'\n"; ! } ! s/ +$/\t/; ! } ! $line = join('',@e, $lastbit); } ! $x = join("\n", @lines); } return @l if wantarray; return @l[0]; } 1; + __END__ + + + =head1 NAME + + Text::Tabs -- expand and unexpand tabs per the unix expand(1) and unexpand(1) + + =head1 SYNOPSIS + + use Text::Tabs; + + $tabstop = 4; + @lines_without_tabs = expand(@lines_with_tabs); + @lines_with_tabs = unexpand(@lines_without_tabs); + + =head1 DESCRIPTION + + Text::Tabs does about what the unix utilities expand(1) and unexpand(1) + do. Given a line with tabs in it, expand will replace the tabs with + the appropriate number of spaces. Given a line with or without tabs in + it, unexpand will add tabs when it can save bytes by doing so. Invisible + compression with plain ascii! + + =head1 BUGS + + expand doesn't handle newlines very quickly -- do not feed it an + entire document in one string. Instead feed it an array of lines. + + =head1 AUTHOR + + David Muir Sharnoff #~ Update to version 96.041801 diff -Pcr perl5_003/lib/Text/Wrap.pm perl5_003_01/lib/Text/Wrap.pm *** perl5_003/lib/Text/Wrap.pm Mon Jan 22 20:45:16 1996 --- perl5_003_01/lib/Text/Wrap.pm Fri Jul 5 18:05:23 1996 *************** *** 1,68 **** - package Text::Wrap; - # - # This is a very simple paragraph formatter. It formats one - # paragraph at a time by wrapping and indenting text. - # - # Usage: - # - # use Text::Wrap; - # - # print wrap($initial_tab,$subsequent_tab,@text); - # - # You can also set the number of columns to wrap before: - # - # $Text::Wrap::columns = 135; # <= width of screen - # - # use Text::Wrap qw(wrap $columns); - # $columns = 70; - # - # - # The first line will be printed with $initial_tab prepended. All - # following lines will have $subsequent_tab prepended. - # - # Example: - # - # print wrap("\t","","This is a bit of text that ..."); - # - # David Muir Sharnoff - # Version: 9/21/95 - # - - =head1 NAME - - Text::Wrap -- wrap text into a paragraph - - =head1 SYNOPSIS - - use Text::Wrap; - - $Text::Wrap::columns = 20; # Default - print wrap("\t","",Hello, world, it's a nice day, isn't it?"); - - =head1 DESCRIPTION - - This module is a simple paragraph formatter that wraps text into a paragraph - and indents each line. The single exported function, wrap(), takes three - arguments. The first is included before the first output line, and the - second argument is included before each subsequest output line. The third - argument is the text to be wrapped. - - =head1 AUTHOR - - David Muir Sharnoff - - =cut - require Exporter; @ISA = (Exporter); @EXPORT = qw(wrap); @EXPORT_OK = qw($columns); BEGIN { ! $Text::Wrap::columns = 76; # <= screen width } use Text::Tabs; --- 1,19 ---- package Text::Wrap; require Exporter; @ISA = (Exporter); @EXPORT = qw(wrap); @EXPORT_OK = qw($columns); + $VERSION = 96.041801; + + use vars qw($VERSION $columns $debug); + use strict; + BEGIN { ! $columns = 76; # <= screen width ! $debug = 0; } use Text::Tabs; *************** *** 72,93 **** { my ($ip, $xp, @t) = @_; ! my $r; my $t = expand(join(" ",@t)); my $lead = $ip; ! my $ll = $Text::Wrap::columns - length(expand($lead)) - 1; ! if ($t =~ s/^([^\n]{0,$ll})\s//) { ! $r .= unexpand($lead . $1 . "\n"); $lead = $xp; ! my $ll = $Text::Wrap::columns - length(expand($lead)) - 1; ! while ($t =~ s/^([^\n]{0,$ll})\s//) { ! $r .= unexpand($lead . $1 . "\n"); } } die "couldn't wrap '$t'" if length($t) > $ll; ! $r .= $t; return $r; } 1; --- 23,101 ---- { my ($ip, $xp, @t) = @_; ! my $r = ""; my $t = expand(join(" ",@t)); my $lead = $ip; ! my $ll = $columns - length(expand($lead)) - 1; ! my $nl = ""; ! ! # remove up to a line length of things that aren't ! # new lines and tabs. ! ! if ($t =~ s/^([^\n]{0,$ll})(\s|\Z(?!\n))//xm) { ! ! # accept it. ! $r .= unexpand($lead . $1); ! ! # recompute the leader $lead = $xp; ! $ll = $columns - length(expand($lead)) - 1; ! $nl = $2; ! ! # repeat the above until there's none left ! while ($t and $t =~ s/^([^\n]{0,$ll})(\s|\Z(?!\n))//xm) { ! print "\$2 is '$2'\n" if $debug; ! $nl = $2; ! $r .= unexpand("\n" . $lead . $1); } + $r .= $nl; } + die "couldn't wrap '$t'" if length($t) > $ll; ! ! print "-----------$r---------\n" if $debug; ! ! print "Finish up with '$lead', '$t'\n" if $debug; ! ! $r .= $lead . $t if $t ne ""; ! ! print "-----------$r---------\n" if $debug;; return $r; } 1; + __DATA__ + + =head1 NAME + + Text::Wrap - line wrapping to form simple paragraphs + + =head1 SYNOPSIS + + use Text::Wrap + + print wrap($initial_tab, $subsequent_tab, @text); + + use Text::Wrap qw(wrap $columns); + + $columns = 132; + + =head1 DESCRIPTION + + Text::Wrap is a very simple paragraph formatter. It formats a + single paragraph at a time by breaking lines at word boundries. + Indentation is controlled for the first line ($initial_tab) and + all subsquent lines ($subsequent_tab) independently. $Text::Wrap::columns + should be set to the full width of your output device. + + =head1 EXAMPLE + + print wrap("\t","","This is a bit of text that forms + a normal book-style paragraph"); + + =head1 AUTHOR + + David Muir Sharnoff + + =cut #~ Quote string argument in example -- necessary if using strict subs diff -Pcr perl5_003/lib/Tie/Hash.pm perl5_003_01/lib/Tie/Hash.pm *** perl5_003/lib/Tie/Hash.pm Mon Feb 12 14:47:45 1996 --- perl5_003_01/lib/Tie/Hash.pm Mon Jul 15 13:35:48 1996 *************** *** 26,33 **** package main; ! tie %new_hash, NewHash; ! tie %new_std_hash, NewStdHash; =head1 DESCRIPTION --- 26,33 ---- package main; ! tie %new_hash, 'NewHash'; ! tie %new_std_hash, 'NewStdHash'; =head1 DESCRIPTION #~ Quote string argument in example -- necessary if using strict subs diff -Pcr perl5_003/lib/Tie/Scalar.pm perl5_003_01/lib/Tie/Scalar.pm *** perl5_003/lib/Tie/Scalar.pm Mon Feb 12 14:47:50 1996 --- perl5_003_01/lib/Tie/Scalar.pm Mon Jul 15 13:35:51 1996 *************** *** 26,33 **** package main; ! tie $new_scalar, NewScalar; ! tie $new_std_scalar, NewStdScalar; =head1 DESCRIPTION --- 26,33 ---- package main; ! tie $new_scalar, 'NewScalar'; ! tie $new_std_scalar, 'NewStdScalar'; =head1 DESCRIPTION #~ Quote string argument in example -- necessary if using strict subs diff -Pcr perl5_003/lib/Tie/SubstrHash.pm perl5_003_01/lib/Tie/SubstrHash.pm *** perl5_003/lib/Tie/SubstrHash.pm Mon Feb 12 14:47:54 1996 --- perl5_003_01/lib/Tie/SubstrHash.pm Mon Jul 15 13:35:54 1996 *************** *** 8,14 **** require Tie::SubstrHash; ! tie %myhash, Tie::SubstrHash, $key_len, $value_len, $table_size; =head1 DESCRIPTION --- 8,14 ---- require Tie::SubstrHash; ! tie %myhash, 'Tie::SubstrHash', $key_len, $value_len, $table_size; =head1 DESCRIPTION #~ Fix bugs in initialization for some timezones diff -Pcr perl5_003/lib/Time/Local.pm perl5_003_01/lib/Time/Local.pm *** perl5_003/lib/Time/Local.pm Mon Jan 22 20:45:20 1996 --- perl5_003_01/lib/Time/Local.pm Thu Jul 4 12:36:46 1996 *************** *** 39,66 **** =cut ! @epoch = localtime(0); ! $tzmin = $epoch[2] * 60 + $epoch[1]; # minutes east of GMT ! if ($tzmin > 0) { ! $tzmin = 24 * 60 - $tzmin; # minutes west of GMT ! $tzmin -= 24 * 60 if $epoch[5] == 70; # account for the date line ! } ! $SEC = 1; ! $MIN = 60 * $SEC; ! $HR = 60 * $MIN; ! $DAYS = 24 * $HR; ! $YearFix = ((gmtime(946684800))[5] == 100) ? 100 : 0; sub timegm { $ym = pack(C2, @_[5,4]); $cheat = $cheat{$ym} || &cheat; return -1 if $cheat<0; ! $cheat + $_[0] * $SEC + $_[1] * $MIN + $_[2] * $HR + ($_[3]-1) * $DAYS; } sub timelocal { ! $time = &timegm + $tzmin*$MIN; return -1 if $cheat<0; @test = localtime($time); $time -= $HR if $test[2] != $_[2]; --- 39,82 ---- =cut ! BEGIN { ! @epoch = localtime(0); ! ! $SEC = 1; ! $MIN = 60 * $SEC; ! $HR = 60 * $MIN; ! $DAY = 24 * $HR; ! $YearFix = ((gmtime(946684800))[5] == 100) ? 100 : 0; ! ! my $t = time; ! my @lt = localtime($t); ! my @gt = gmtime($t); ! $tzsec = ($gt[1] - $lt[1]) * $MIN + ($gt[2] - $lt[2]) * $HR; ! ! my($lday,$gday) = ($lt[7],$gt[7]); ! if($lt[5] > $gt[5]) { ! $tzsec -= $DAY; ! } ! elsif($gt[5] > $lt[5]) { ! $tzsec += $DAY; ! } ! else { ! $tzsec += ($gt[7] - $lt[7]) * $DAY; ! } ! ! $tzsec += $HR if($lt[8]); ! } sub timegm { $ym = pack(C2, @_[5,4]); $cheat = $cheat{$ym} || &cheat; return -1 if $cheat<0; ! $cheat + $_[0] * $SEC + $_[1] * $MIN + $_[2] * $HR + ($_[3]-1) * $DAY; } sub timelocal { ! $time = &timegm + $tzsec; return -1 if $cheat<0; @test = localtime($time); $time -= $HR if $test[2] != $_[2]; *************** *** 69,74 **** --- 85,92 ---- sub cheat { $year = $_[5]; + $year -= 1900 + if $year > 1900; $month = $_[4]; croak "Month out of range 0..11 in timelocal.pl" if $month > 11 || $month < 0; *************** *** 85,91 **** $year += $YearFix if $year < $epoch[5]; $lastguess = ""; while ($diff = $year - $g[5]) { ! $guess += $diff * (363 * $DAYS); @g = gmtime($guess); if (($thisguess = "@g") eq $lastguess){ return -1; #date beyond this machine's integer limit --- 103,109 ---- $year += $YearFix if $year < $epoch[5]; $lastguess = ""; while ($diff = $year - $g[5]) { ! $guess += $diff * (363 * $DAY); @g = gmtime($guess); if (($thisguess = "@g") eq $lastguess){ return -1; #date beyond this machine's integer limit *************** *** 93,99 **** $lastguess = $thisguess; } while ($diff = $month - $g[4]) { ! $guess += $diff * (27 * $DAYS); @g = gmtime($guess); if (($thisguess = "@g") eq $lastguess){ return -1; #date beyond this machine's integer limit --- 111,117 ---- $lastguess = $thisguess; } while ($diff = $month - $g[4]) { ! $guess += $diff * (27 * $DAY); @g = gmtime($guess); if (($thisguess = "@g") eq $lastguess){ return -1; #date beyond this machine's integer limit *************** *** 105,111 **** return -1; #date beyond this machine's integer limit } $g[3]--; ! $guess -= $g[0] * $SEC + $g[1] * $MIN + $g[2] * $HR + $g[3] * $DAYS; $cheat{$ym} = $guess; } --- 123,129 ---- return -1; #date beyond this machine's integer limit } $g[3]--; ! $guess -= $g[0] * $SEC + $g[1] * $MIN + $g[2] * $HR + $g[3] * $DAY; $cheat{$ym} = $guess; } #~ Use ~-expanded version of privlib diff -Pcr perl5_003/lib/diagnostics.pm perl5_003_01/lib/diagnostics.pm *** perl5_003/lib/diagnostics.pm Mon Mar 25 01:04:12 1996 --- perl5_003_01/lib/diagnostics.pm Wed Jul 10 13:26:26 1996 *************** *** 4,13 **** use Config; if ($^O eq 'VMS') { ! $diagnostics::PODFILE = VMS::Filespec::unixify($Config{'privlib'}) . '/pod/perldiag.pod'; } ! else { $diagnostics::PODFILE= $Config{privlib} . "/pod/perldiag.pod"; } package diagnostics; require 5.001; --- 4,13 ---- use Config; if ($^O eq 'VMS') { ! $diagnostics::PODFILE = VMS::Filespec::unixify($Config{'privlibexp'}) . '/pod/perldiag.pod'; } ! else { $diagnostics::PODFILE= $Config{privlibexp} . "/pod/perldiag.pod"; } package diagnostics; require 5.001; #~ Eliminate $`,$' to avoid runtime penalty diff -Pcr perl5_003/lib/dotsh.pl perl5_003_01/lib/dotsh.pl *** perl5_003/lib/dotsh.pl Mon Oct 30 18:46:24 1995 --- perl5_003_01/lib/dotsh.pl Wed May 1 17:10:21 1996 *************** *** 53,60 **** open (_SH_ENV, "/tmp/_sh_env$$") || die "Could not open /tmp/_sh_env$$!\n"; while (<_SH_ENV>) { chop; ! /=/; ! $ENV{$`} = $'; } close (_SH_ENV); system "rm -f /tmp/_sh_env$$"; --- 53,60 ---- open (_SH_ENV, "/tmp/_sh_env$$") || die "Could not open /tmp/_sh_env$$!\n"; while (<_SH_ENV>) { chop; ! m/^([^=]*)=(.*)/s; ! $ENV{$1} = $2; } close (_SH_ENV); system "rm -f /tmp/_sh_env$$"; #~ Turn off optional warnings #~ Eliminate $' to avoid runtime penalty diff -Pcr perl5_003/lib/dumpvar.pl perl5_003_01/lib/dumpvar.pl *** perl5_003/lib/dumpvar.pl Mon Feb 12 14:56:09 1996 --- perl5_003_01/lib/dumpvar.pl Fri Jul 5 18:30:30 1996 *************** *** 25,30 **** --- 25,31 ---- sub main::dumpValue { local %address; + local $^W=0; (print "undef\n"), return unless defined $_[0]; (print &stringify($_[0]), "\n"), return unless ref $_[0]; dumpvar::unwrap($_[0],0); *************** *** 222,229 **** sub matchvar { $_[0] eq $_[1] or ! ($_[1] =~ /^([!~])(.)/) and ! ($1 eq '!') ^ (eval {($_[2] . "::" . $_[0]) =~ /$2$'/}); } sub compactDump { --- 223,230 ---- sub matchvar { $_[0] eq $_[1] or ! ($_[1] =~ /^([!~])(.)([\x00-\xff]*)/) and ! ($1 eq '!') ^ (eval {($_[2] . "::" . $_[0]) =~ /$2$3/}); } sub compactDump { *************** *** 319,325 **** sub main::dumpvar { my ($package,@vars) = @_; ! local(%address,$key,$val); $package .= "::" unless $package =~ /::$/; *stab = *{"main::"}; while ($package =~ /(\w+?::)/g){ --- 320,326 ---- sub main::dumpvar { my ($package,@vars) = @_; ! local(%address,$key,$val,$^W); $package .= "::" unless $package =~ /::$/; *stab = *{"main::"}; while ($package =~ /(\w+?::)/g){ #~ Use newer File::Find to eliminate duplicate code diff -Pcr perl5_003/lib/find.pl perl5_003_01/lib/find.pl *** perl5_003/lib/find.pl Tue Oct 18 12:36:08 1994 --- perl5_003_01/lib/find.pl Tue Jun 18 20:00:39 1996 *************** *** 29,108 **** # # Set the variable $dont_use_nlink if you're using AFS, since AFS cheats. ! sub find { ! chop($cwd = `pwd`); ! foreach $topdir (@_) { ! (($topdev,$topino,$topmode,$topnlink) = stat($topdir)) ! || (warn("Can't stat $topdir: $!\n"), next); ! if (-d _) { ! if (chdir($topdir)) { ! ($dir,$_) = ($topdir,'.'); ! $name = $topdir; ! &wanted; ! ($fixtopdir = $topdir) =~ s,/$,, ; ! &finddir($fixtopdir,$topnlink); ! } ! else { ! warn "Can't cd to $topdir: $!\n"; ! } ! } ! else { ! unless (($dir,$_) = $topdir =~ m#^(.*/)(.*)$#) { ! ($dir,$_) = ('.', $topdir); ! } ! $name = $topdir; ! chdir $dir && &wanted; ! } ! chdir $cwd; ! } ! } ! ! sub finddir { ! local($dir,$nlink) = @_; ! local($dev,$ino,$mode,$subcount); ! local($name); ! ! # Get the list of files in the current directory. ! ! opendir(DIR,'.') || (warn "Can't open $dir: $!\n", return); ! local(@filenames) = readdir(DIR); ! closedir(DIR); ! if ($nlink == 2 && !$dont_use_nlink) { # This dir has no subdirectories. ! for (@filenames) { ! next if $_ eq '.'; ! next if $_ eq '..'; ! $name = "$dir/$_"; ! $nlink = 0; ! &wanted; ! } ! } ! else { # This dir has subdirectories. ! $subcount = $nlink - 2; ! for (@filenames) { ! next if $_ eq '.'; ! next if $_ eq '..'; ! $nlink = $prune = 0; ! $name = "$dir/$_"; ! &wanted; ! if ($subcount > 0 || $dont_use_nlink) { # Seen all the subdirs? ! # Get link count and check for directoriness. ! ! ($dev,$ino,$mode,$nlink) = lstat($_) unless $nlink; ! ! if (-d _) { ! ! # It really is a directory, so do it recursively. ! ! if (!$prune && chdir $_) { ! &finddir($name,$nlink); ! chdir '..'; ! } ! --$subcount; ! } ! } ! } ! } } 1; --- 29,42 ---- # # Set the variable $dont_use_nlink if you're using AFS, since AFS cheats. ! use File::Find (); ! *name = *File::Find::name; ! *prune = *File::Find::prune; ! *dir = *File::Find::dir; ! sub find { ! &File::Find::find(\&wanted, @_); } + 1; #~ Use newer File::Find to eliminate duplicate code diff -Pcr perl5_003/lib/finddepth.pl perl5_003_01/lib/finddepth.pl *** perl5_003/lib/finddepth.pl Tue Oct 18 12:36:11 1994 --- perl5_003_01/lib/finddepth.pl Tue Jun 18 20:00:42 1996 *************** *** 27,105 **** # ($prune = 1); # } - sub finddepth { - chop($cwd = `pwd`); - foreach $topdir (@_) { - (($topdev,$topino,$topmode,$topnlink) = stat($topdir)) - || (warn("Can't stat $topdir: $!\n"), next); - if (-d _) { - if (chdir($topdir)) { - ($fixtopdir = $topdir) =~ s,/$,, ; - &finddepthdir($fixtopdir,$topnlink); - ($dir,$_) = ($fixtopdir,'.'); - $name = $fixtopdir; - &wanted; - } - else { - warn "Can't cd to $topdir: $!\n"; - } - } - else { - unless (($dir,$_) = $topdir =~ m#^(.*/)(.*)$#) { - ($dir,$_) = ('.', $topdir); - } - chdir $dir && &wanted; - } - chdir $cwd; - } - } - - sub finddepthdir { - local($dir,$nlink) = @_; - local($dev,$ino,$mode,$subcount); - local($name); - - # Get the list of files in the current directory. - - opendir(DIR,'.') || warn "Can't open $dir: $!\n"; - local(@filenames) = readdir(DIR); - closedir(DIR); ! if ($nlink == 2) { # This dir has no subdirectories. ! for (@filenames) { ! next if $_ eq '.'; ! next if $_ eq '..'; ! $name = "$dir/$_"; ! $nlink = 0; ! &wanted; ! } ! } ! else { # This dir has subdirectories. ! $subcount = $nlink - 2; ! for (@filenames) { ! next if $_ eq '.'; ! next if $_ eq '..'; ! $nlink = $prune = 0; ! $name = "$dir/$_"; ! if ($subcount > 0) { # Seen all the subdirs? ! # Get link count and check for directoriness. ! ($dev,$ino,$mode,$nlink) = lstat($_) unless $nlink; ! ! if (-d _) { ! ! # It really is a directory, so do it recursively. ! ! if (!$prune && chdir $_) { ! &finddepthdir($name,$nlink); ! chdir '..'; ! } ! --$subcount; ! } ! } ! &wanted; ! } ! } } 1; --- 27,41 ---- # ($prune = 1); # } ! use File::Find (); ! *name = *File::Find::name; ! *prune = *File::Find::prune; ! *dir = *File::Find::dir; ! sub finddepth { ! &File::Find::finddepth(\&wanted, @_); } + 1; #~ Escape literal "@" in string diff -Pcr perl5_003/lib/ftp.pl perl5_003_01/lib/ftp.pl *** perl5_003/lib/ftp.pl Wed Jun 7 19:49:23 1995 --- perl5_003_01/lib/ftp.pl Wed May 1 15:00:50 1996 *************** *** 245,251 **** local( $remote_user, $remote_password ) = @_; if( $proxy ){ ! &ftp'send( "USER $remote_user@$site" ); } else { &ftp'send( "USER $remote_user" ); --- 245,251 ---- local( $remote_user, $remote_password ) = @_; if( $proxy ){ ! &ftp'send( "USER $remote_user\@$site" ); } else { &ftp'send( "USER $remote_user" ); #~ Allow for directory named "0" diff -Pcr perl5_003/lib/getcwd.pl perl5_003_01/lib/getcwd.pl *** perl5_003/lib/getcwd.pl Wed Jun 7 19:49:27 1995 --- perl5_003_01/lib/getcwd.pl Tue May 14 21:42:17 1996 *************** *** 54,60 **** } $cwd = "$dir/$cwd"; closedir(getcwd'PARENT); #'); ! } while ($dir); chop($cwd); $cwd; } --- 54,60 ---- } $cwd = "$dir/$cwd"; closedir(getcwd'PARENT); #'); ! } while ($dir ne ''); chop($cwd); $cwd; } #~ Handle empty strings gracefully #~ Look for architecture-specific directory with or without version #~ Update reference to FindBin in documentation diff -Pcr perl5_003/lib/lib.pm perl5_003_01/lib/lib.pm *** perl5_003/lib/lib.pm Mon Feb 26 13:08:56 1996 --- perl5_003_01/lib/lib.pm Mon Jun 3 13:21:06 1996 *************** *** 11,20 **** sub import { shift; foreach (reverse @_) { unshift(@INC, $_); # Put a corresponding archlib directory infront of $_ if it # looks like $_ has an archlib directory below it. ! unshift(@INC, "$_/$archname") if -d "$_/$archname/auto"; } } --- 11,25 ---- sub import { shift; foreach (reverse @_) { + unless (defined $_ and $_ ne '') { + require Carp; + Carp::carp("Empty or undefined compile time value given"); # at foo.pl line ... + } unshift(@INC, $_); # Put a corresponding archlib directory infront of $_ if it # looks like $_ has an archlib directory below it. ! unshift(@INC, "$_/$archname/$]") if -d "$_/$archname/$]/auto"; ! unshift(@INC, "$_/$archname") if -d "$_/$archname/auto"; } } *************** *** 118,124 **** =head1 SEE ALSO ! AddINC - optional module which deals with paths relative to the source file. =head1 AUTHOR --- 123,129 ---- =head1 SEE ALSO ! FindBin - optional module which deals with paths relative to the source file. =head1 AUTHOR #~ Update to version 1.16 diff -Pcr perl5_003/lib/newgetopt.pl perl5_003_01/lib/newgetopt.pl *** perl5_003/lib/newgetopt.pl Mon Feb 12 14:56:18 1996 --- perl5_003_01/lib/newgetopt.pl Thu May 9 17:30:28 1996 *************** *** 1,6 **** # newgetopt.pl -- new options parsing. # Now just a wrapper around the Getopt::Long module. ! # $Id: newgetopt.pl,v 1.15 1995/12/26 14:57:33 jv Exp $ { package newgetopt; --- 1,6 ---- # newgetopt.pl -- new options parsing. # Now just a wrapper around the Getopt::Long module. ! # $Id: newgetopt.pl,v 1.16 1996/03/16 11:46:08 jv Exp $ { package newgetopt; *************** *** 15,26 **** --- 15,28 ---- $getopt_compat = 0; # disallow '+' to start options $option_start = "(--|-)"; $order = $REQUIRE_ORDER; + $bundling = 0; } else { $autoabbrev = 1; # automatic abbrev of options $getopt_compat = 1; # allow '+' to start options $option_start = "(--|-|\\+)"; $order = $PERMUTE; + $bundling = 0; } # Other configurable settings. *************** *** 45,50 **** --- 47,54 ---- if defined $newgetopt::option_start; $Getopt::Long::order = $newgetopt::order if defined $newgetopt::order; + $Getopt::Long::bundling = $newgetopt::bundling + if defined $newgetopt::bundling; $Getopt::Long::ignorecase = $newgetopt::ignorecase if defined $newgetopt::ignorecase; #~ Eliminate use of $& to avoid runtime penalty diff -Pcr perl5_003/lib/open2.pl perl5_003_01/lib/open2.pl *** perl5_003/lib/open2.pl Tue Oct 18 12:36:44 1994 --- perl5_003_01/lib/open2.pl Wed May 1 17:10:26 1996 *************** *** 28,35 **** # force unqualified filehandles into callers' package local($package) = caller; ! $dad_rdr =~ s/^[^']+$/$package'$&/; ! $dad_wtr =~ s/^[^']+$/$package'$&/; local($kid_rdr) = ++$fh; local($kid_wtr) = ++$fh; --- 28,35 ---- # force unqualified filehandles into callers' package local($package) = caller; ! $dad_rdr =~ s/^([^']+$)/$package'$1/; ! $dad_wtr =~ s/^([^']+$)/$package'$1/; local($kid_rdr) = ++$fh; local($kid_wtr) = ++$fh; #~ Eliminate use of $& to avoid runtime penalty diff -Pcr perl5_003/lib/open3.pl perl5_003_01/lib/open3.pl *** perl5_003/lib/open3.pl Tue Oct 18 12:36:47 1994 --- perl5_003_01/lib/open3.pl Wed May 1 17:10:28 1996 *************** *** 46,54 **** # force unqualified filehandles into callers' package local($package) = caller; ! $dad_wtr =~ s/^[^']+$/$package'$&/; ! $dad_rdr =~ s/^[^']+$/$package'$&/; ! $dad_err =~ s/^[^']+$/$package'$&/; local($kid_rdr) = ++$fh; local($kid_wtr) = ++$fh; --- 46,54 ---- # force unqualified filehandles into callers' package local($package) = caller; ! $dad_wtr =~ s/^([^']+$)/$package'$1/; ! $dad_rdr =~ s/^([^']+$)/$package'$1/; ! $dad_err =~ s/^([^']+$)/$package'$1/; local($kid_rdr) = ++$fh; local($kid_wtr) = ++$fh; #~ Drop support for null package name or package "0" #~ Document fallbacks for logical negation diff -Pcr perl5_003/lib/overload.pm perl5_003_01/lib/overload.pm *** perl5_003/lib/overload.pm Mon Jan 22 20:43:23 1996 --- perl5_003_01/lib/overload.pm Tue Jun 18 20:41:37 1996 *************** *** 26,43 **** } sub Overloaded { ! defined ($package = ref $_[0]) and defined %{$package . "::OVERLOAD"}; } sub OverloadedStringify { ! defined ($package = ref $_[0]) and defined %{$package . "::OVERLOAD"} and exists $ {$package . "::OVERLOAD"}{'""'} and defined &{$ {$package . "::OVERLOAD"}{'""'}}; } sub Method { ! defined ($package = ref $_[0]) and defined %{$package . "::OVERLOAD"} and $ {$package . "::OVERLOAD"}{$_[1]}; } --- 26,43 ---- } sub Overloaded { ! ($package = ref $_[0]) and defined %{$package . "::OVERLOAD"}; } sub OverloadedStringify { ! ($package = ref $_[0]) and defined %{$package . "::OVERLOAD"} and exists $ {$package . "::OVERLOAD"}{'""'} and defined &{$ {$package . "::OVERLOAD"}{'""'}}; } sub Method { ! ($package = ref $_[0]) and defined %{$package . "::OVERLOAD"} and $ {$package . "::OVERLOAD"}{$_[1]}; } *************** *** 186,192 **** "&", "^", "|", "neg", "!", "~", "C" stands for unary minus. If the method for C is not ! specified, it can be autogenerated using the method for subtraction. =item * I --- 186,194 ---- "&", "^", "|", "neg", "!", "~", "C" stands for unary minus. If the method for C is not ! specified, it can be autogenerated using the method for ! subtraction. If the method for "C" is not specified, it can be ! autogenerated using the methods for "C", or "C<\"\">", or "C<0+>". =item * I *************** *** 360,365 **** --- 362,372 ---- =item I can be expressed in terms of subtraction. + + =item I + + C and C can be expressed in terms of boolean conversion, or + string or numerical conversion. =item I #~ Update to version 0.95: use SHELL environment variable, add option #~ for status message on return from sub, improved reporting of AUTOLOAD, #~ listing of package versions, improved ReadLine support diff -Pcr perl5_003/lib/perl5db.pl perl5_003_01/lib/perl5db.pl *** perl5_003/lib/perl5db.pl Mon Feb 12 14:56:26 1996 --- perl5_003_01/lib/perl5db.pl Fri Jul 5 18:30:27 1996 *************** *** 2,8 **** # Debugger for Perl 5.00x; perl5db.pl patch level: ! $header = 'perl5db.pl patch level 0.94'; # Enhanced by ilya@math.ohio-state.edu (Ilya Zakharevich) # Latest version available: ftp://ftp.math.ohio-state.edu/pub/users/ilya/perl --- 2,9 ---- # Debugger for Perl 5.00x; perl5db.pl patch level: ! $VERSION = 0.95; ! $header = "perl5db.pl patch level $VERSION"; # Enhanced by ilya@math.ohio-state.edu (Ilya Zakharevich) # Latest version available: ftp://ftp.math.ohio-state.edu/pub/users/ilya/perl *************** *** 63,68 **** --- 64,88 ---- # information into db.out. (If you interrupt it, you would better # reset LineInfo to something "interactive"!) # + # Changes: 0.95: v command shows versions. + + ################################################################## + # Changelog: + + # A lot of things changed after 0.94. First of all, core now informs + # debugger about entry into XSUBs, overloaded operators, tied operations, + # BEGIN and END. Handy with `O f=2'. + + # This can make debugger a little bit too verbose, please be patient + # and report your problems promptly. + + # Now the option frame has 3 values: 0,1,2. + + # Note that if DESTROY returns a reference to the object (or object), + # the deletion of data may be postponed until the next function call, + # due to the need to examine the return value. + + #################################################################### # Needed for the statement after exec(): *************** *** 91,96 **** --- 111,118 ---- $trace = $signal = $single = 0; # Uninitialized warning suppression # (local $^W cannot help - other packages!). + $doret = -2; + $frame = 0; @stack = (0); $option{PrintRet} = 1; *************** *** 140,145 **** --- 162,170 ---- # These guys may be defined in $ENV{PERL5DB} : $rl = 1 unless defined $rl; + $warnLevel = 1 unless defined $warnLevel; + $dieLevel = 1 unless defined $dieLevel; + $signalLevel = 1 unless defined $signalLevel; warnLevel($warnLevel); dieLevel($dieLevel); signalLevel($signalLevel); *************** *** 201,207 **** } # Around a bug: ! if (defined $ENV{OS2_SHELL} and $emacs) { # In OS/2 $console = undef; } --- 226,232 ---- } # Around a bug: ! if (defined $ENV{OS2_SHELL} and ($emacs or $ENV{WINDOWID})) { # In OS/2 $console = undef; } *************** *** 270,283 **** # EOE } &save; - if ($doret) { - $doret = 0; - if ($option{PrintRet}) { - print $OUT "$retctx context return from $lastsub:", - ($retctx eq 'list') ? "\n" : " " ; - dumpit( ($retctx eq 'list') ? \@ret : $ret ); - } - } ($package, $filename, $line) = caller; $filename_ini = $filename; $usercontext = '($@, $!, $,, $/, $\, $^W) = @saved;' . --- 295,300 ---- *************** *** 373,378 **** --- 390,397 ---- } } next CMD; }; + $cmd =~ /^v$/ && do { + list_versions(); next CMD}; $cmd =~ s/^X\b/V $package/; $cmd =~ /^V$/ && do { $cmd = "V $package"; }; *************** *** 383,388 **** --- 402,408 ---- do 'dumpvar.pl' unless defined &main::dumpvar; if (defined &main::dumpvar) { local $frame = 0; + local $doret = -2; &main::dumpvar($packname,@vars); } else { print $OUT "dumpvar.pl not available.\n"; *************** *** 614,620 **** last CMD; }; $cmd =~ /^r$/ && do { $stack[$#stack] |= 1; ! $doret = 1; last CMD; }; $cmd =~ /^R$/ && do { print $OUT "Warning: a lot of settings and command-line options may be lost!\n"; --- 634,640 ---- last CMD; }; $cmd =~ /^r$/ && do { $stack[$#stack] |= 1; ! $doret = $option{PrintRet} ? $#stack - 1 : -2; last CMD; }; $cmd =~ /^R$/ && do { print $OUT "Warning: a lot of settings and command-line options may be lost!\n"; *************** *** 747,754 **** $cmd = $hist[$i] . "\n"; print $OUT $cmd; redo CMD; }; ! $cmd =~ /^$sh$sh\s*/ && do { ! &system($'); next CMD; }; $cmd =~ /^$rc([^$rc].*)$/ && do { $pat = "^$1"; --- 767,774 ---- $cmd = $hist[$i] . "\n"; print $OUT $cmd; redo CMD; }; ! $cmd =~ /^$sh$sh\s*([\x00-\xff]]*)/ && do { ! &system($1); next CMD; }; $cmd =~ /^$rc([^$rc].*)$/ && do { $pat = "^$1"; *************** *** 766,773 **** $cmd =~ /^$sh$/ && do { &system($ENV{SHELL}||"/bin/sh"); next CMD; }; ! $cmd =~ /^$sh\s*/ && do { ! &system($ENV{SHELL}||"/bin/sh","-c",$'); next CMD; }; $cmd =~ /^H\b\s*(-(\d+))?/ && do { $end = $2?($#hist-$2):0; --- 786,793 ---- $cmd =~ /^$sh$/ && do { &system($ENV{SHELL}||"/bin/sh"); next CMD; }; ! $cmd =~ /^$sh\s*([\x00-\xff]*)/ && do { ! &system($ENV{SHELL}||"/bin/sh","-c",$1); next CMD; }; $cmd =~ /^H\b\s*(-(\d+))?/ && do { $end = $2?($#hist-$2):0; *************** *** 864,886 **** # BEGIN {warn 4} sub sub { ! print $LINEINFO ' ' x $#stack, "entering $sub\n" if $frame; push(@stack, $single); $single &= 1; $single |= 4 if $#stack == $deep; if (wantarray) { @ret = &$sub; $single |= pop(@stack); ! $retctx = "list"; ! $lastsub = $sub; ! print $LINEINFO ' ' x $#stack, "exited $sub\n" if $frame; @ret; } else { $ret = &$sub; $single |= pop(@stack); ! $retctx = "scalar"; ! $lastsub = $sub; ! print $LINEINFO ' ' x $#stack, "exited $sub\n" if $frame; $ret; } } --- 884,910 ---- # BEGIN {warn 4} sub sub { ! my ($al, $ret, @ret) = ""; ! if ($sub =~ /::AUTOLOAD$/) { ! $al = " for $ {$` . '::AUTOLOAD'}"; ! } ! print $LINEINFO ' ' x $#stack, "entering $sub$al\n" if $frame; push(@stack, $single); $single &= 1; $single |= 4 if $#stack == $deep; if (wantarray) { @ret = &$sub; $single |= pop(@stack); ! print ($OUT "list context return from $sub:\n"), dumpit( \@ret ), ! $doret = -2 if $doret eq $#stack; ! print $LINEINFO ' ' x $#stack, "exited $sub$al\n" if $frame > 1; @ret; } else { $ret = &$sub; $single |= pop(@stack); ! print ($OUT "scalar context return from $sub: "), dumpit( $ret ), ! $doret = -2 if $doret eq $#stack; ! print $LINEINFO ' ' x $#stack, "exited $sub$al\n" if $frame > 1; $ret; } } *************** *** 927,939 **** sub dumpit { local ($savout) = select($OUT); ! do 'dumpvar.pl' unless defined &main::dumpValue; if (defined &main::dumpValue) { - local $frame = 0; &main::dumpValue(shift); } else { print $OUT "dumpvar.pl not available.\n"; } select ($savout); } --- 951,971 ---- sub dumpit { local ($savout) = select($OUT); ! my $osingle = $single; ! my $otrace = $trace; ! $single = $trace = 0; ! local $frame = 0; ! local $doret = -2; ! unless (defined &main::dumpValue) { ! do 'dumpvar.pl'; ! } if (defined &main::dumpValue) { &main::dumpValue(shift); } else { print $OUT "dumpvar.pl not available.\n"; } + $single = $osingle; + $trace = $otrace; select ($savout); } *************** *** 972,978 **** sub setterm { local $frame = 0; ! eval "require Term::ReadLine;" or die $@; if ($notty) { if ($tty) { open(IN,"<$tty") or die "Cannot open TTY `$TTY' for read: $!"; --- 1004,1012 ---- sub setterm { local $frame = 0; ! local $doret = -2; ! local @stack = @stack; # Prevent growth by failing `use'. ! eval { require Term::ReadLine } or die $@; if ($notty) { if ($tty) { open(IN,"<$tty") or die "Cannot open TTY `$TTY' for read: $!"; *************** *** 1017,1022 **** --- 1051,1057 ---- return $got; } local $frame = 0; + local $doret = -2; $term->readline(@_); } *************** *** 1036,1042 **** } else { $val = $option{$opt}; } ! $val =~ s/[\\\']/\\$&/g; printf $OUT "%20s = '%s'\n", $opt, $val; } --- 1071,1077 ---- } else { $val = $option{$opt}; } ! $val =~ s/([\\\'])/\\$1/g; printf $OUT "%20s = '%s'\n", $opt, $val; } *************** *** 1070,1076 **** print $OUT "Unknown option `$opt'\n" unless $matches; print $OUT "Ambiguous option `$opt'\n" if $matches > 1; $option{$option} = $val if $matches == 1 and defined $val; ! eval "local \$frame = 0; require '$optionRequire{$option}'" if $matches == 1 and defined $optionRequire{$option} and defined $val; $ {$optionVars{$option}} = $val if $matches == 1 --- 1105,1112 ---- print $OUT "Unknown option `$opt'\n" unless $matches; print $OUT "Ambiguous option `$opt'\n" if $matches > 1; $option{$option} = $val if $matches == 1 and defined $val; ! eval "local \$frame = 0; local \$doret = -2; ! require '$optionRequire{$option}'" if $matches == 1 and defined $optionRequire{$option} and defined $val; $ {$optionVars{$option}} = $val if $matches == 1 *************** *** 1091,1097 **** for $i (0 .. $#list) { $val = $list[$i]; $val =~ s/\\/\\\\/g; ! $val =~ s/[\0-\37\177\200-\377]/"\\0x" . unpack('H2',$&)/eg; $ENV{"$ {stem}_$i"} = $val; } } --- 1127,1133 ---- for $i (0 .. $#list) { $val = $list[$i]; $val =~ s/\\/\\\\/g; ! $val =~ s/([\0-\37\177\200-\377])/"\\0x" . unpack('H2',$1)/eg; $ENV{"$ {stem}_$i"} = $val; } } *************** *** 1200,1205 **** --- 1236,1263 ---- $lineinfo; } + sub list_versions { + my %version; + my $file; + for (keys %INC) { + $file = $_; + s,\.p[lm]$,,i ; + s,/,::,g ; + s/^perl5db$/DB/; + if (defined $ { $_ . '::VERSION' }) { + $version{$file} = "$ { $_ . '::VERSION' } from "; + } + $version{$file} .= $INC{$file}; + } + do 'dumpvar.pl' unless defined &main::dumpValue; + if (defined &main::dumpValue) { + local $frame = 0; + &main::dumpValue(\%version); + } else { + print $OUT "dumpvar.pl not available.\n"; + } + } + sub sethelp { $help = " T Stack trace. *************** *** 1275,1280 **** --- 1333,1339 ---- ||dbcmd Same as |dbcmd but DB::OUT is temporarilly select()ed as well. \= [alias value] Define a command alias, or list current aliases. command Execute as a perl statement in current package. + v Show versions of loaded modules. R Pure-man-restart of debugger, debugger state and command-line options are lost. h [db_command] Get help [on a specific debugger command], enter |h to page. *************** *** 1288,1295 **** - or . List previous/current line s [expr] Single step [in expr] w [line] List around line n [expr] Next, steps over subs f filename View source in file Repeat last n or s ! /pattern/ Search forward r Return from subroutine ! ?pattern? Search backward c [line] Continue until line Debugger controls: L List break pts & actions O [...] Set debugger options t [expr] Toggle trace [trace expr] < command Command for before prompt b [ln] [c] Set breakpoint --- 1347,1354 ---- - or . List previous/current line s [expr] Single step [in expr] w [line] List around line n [expr] Next, steps over subs f filename View source in file Repeat last n or s ! /pattern/ ?patt? Search forw/backw r Return from subroutine ! v Show versions of modules c [line] Continue until line Debugger controls: L List break pts & actions O [...] Set debugger options t [expr] Toggle trace [trace expr] < command Command for before prompt b [ln] [c] Set breakpoint *************** *** 1312,1317 **** --- 1371,1377 ---- sub diesignal { local $frame = 0; + local $doret = -2; $SIG{'ABRT'} = DEFAULT; kill 'ABRT', $$ if $panic++; print $DB::OUT "Got $_[0]!\n"; # in the case cannot continue *************** *** 1324,1329 **** --- 1384,1390 ---- sub dbwarn { local $frame = 0; + local $doret = -2; local $SIG{__WARN__} = ''; require Carp; #&warn("Entering dbwarn\n"); *************** *** 1338,1343 **** --- 1399,1405 ---- sub dbdie { local $frame = 0; + local $doret = -2; local $SIG{__DIE__} = ''; local $SIG{__WARN__} = ''; my $i = 0; my $ineval = 0; my $sub; *************** *** 1423,1438 **** $window = 10; $preview = 3; $sub = ''; - #$SIG{__WARN__} = "DB::dbwarn"; - #$SIG{__DIE__} = 'DB::dbdie'; - #$SIG{SEGV} = "DB::diesignal"; - #$SIG{BUS} = "DB::diesignal"; $SIG{INT} = "DB::catch"; ! #$SIG{FPE} = "DB::catch"; ! #warn "SIGFPE installed"; ! $warnLevel = 1 unless defined $warnLevel; ! $dieLevel = 1 unless defined $dieLevel; ! $signalLevel = 1 unless defined $signalLevel; $db_stop = 0; # Compiler warning $db_stop = 1 << 30; --- 1485,1495 ---- $window = 10; $preview = 3; $sub = ''; $SIG{INT} = "DB::catch"; ! # This may be enabled to debug debugger: ! #$warnLevel = 1 unless defined $warnLevel; ! #$dieLevel = 1 unless defined $dieLevel; ! #$signalLevel = 1 unless defined $signalLevel; $db_stop = 0; # Compiler warning $db_stop = 1 << 30; #~ Greatly expand options for setting handlers diff -Pcr perl5_003/lib/sigtrap.pm perl5_003_01/lib/sigtrap.pm *** perl5_003/lib/sigtrap.pm Mon Jan 22 20:43:30 1996 --- perl5_003_01/lib/sigtrap.pm Wed May 1 14:41:08 1996 *************** *** 2,39 **** =head1 NAME ! sigtrap - Perl pragma to enable stack backtrace on unexpected signals ! ! =head1 SYNOPSIS ! ! use sigtrap; ! use sigtrap qw(BUS SEGV PIPE SYS ABRT TRAP); ! ! =head1 DESCRIPTION ! ! The C pragma initializes some default signal handlers that print ! a stack dump of your Perl program, then sends itself a SIGABRT. This ! provides a nice starting point if something horrible goes wrong. ! ! By default, handlers are installed for the ABRT, BUS, EMT, FPE, ILL, PIPE, ! QUIT, SEGV, SYS, TERM, and TRAP signals. ! ! See L. =cut ! require Carp; sub import { ! my $pack = shift; ! my @sigs = @_; ! @sigs or @sigs = qw(QUIT ILL TRAP ABRT EMT FPE BUS SEGV SYS PIPE TERM); ! foreach $sig (@sigs) { ! $SIG{$sig} = 'sigtrap::trap'; } } ! sub trap { package DB; # To get subroutine args. $SIG{'ABRT'} = DEFAULT; kill 'ABRT', $$ if $panic++; --- 2,82 ---- =head1 NAME ! sigtrap - Perl pragma to enable simple signal handling =cut ! use Carp; ! ! $VERSION = 1.01; ! $Verbose ||= 0; sub import { ! my $pkg = shift; ! my $handler = \&handler_traceback; ! my $saw_sig = 0; ! my $untrapped = 0; ! local $_; ! ! Arg_loop: ! while (@_) { ! $_ = shift; ! if (/^[A-Z][A-Z0-9]*$/) { ! $saw_sig++; ! unless ($untrapped and $SIG{$_} and $SIG{$_} ne 'DEFAULT') { ! print "Installing handler $handler for $_\n" if $Verbose; ! $SIG{$_} = $handler; ! } ! } ! elsif ($_ eq 'normal-signals') { ! unshift @_, qw(HUP INT PIPE TERM); ! } ! elsif ($_ eq 'error-signals') { ! unshift @_, qw(ABRT BUS EMT FPE ILL QUIT SEGV SYS TRAP); ! } ! elsif ($_ eq 'old-interface-signals') { ! unshift @_, qw(ABRT BUS EMT FPE ILL PIPE QUIT SEGV SYS TERM TRAP); ! } ! elsif ($_ eq 'stack-trace') { ! $handler = \&handler_traceback; ! } ! elsif ($_ eq 'die') { ! $handler = \&handler_die; ! } ! elsif ($_ eq 'handler') { ! @_ or croak "No argument specified after 'handler'"; ! $handler = shift; ! unless (ref $handler or $handler eq 'IGNORE' ! or $handler eq 'DEFAULT') { ! require Symbol; ! $handler = Symbol::qualify($handler, (caller)[0]); ! } ! } ! elsif ($_ eq 'untrapped') { ! $untrapped = 1; ! } ! elsif ($_ eq 'any') { ! $untrapped = 0; ! } ! elsif ($_ =~ /^\d/) { ! $VERSION >= $_ or croak "sigtrap.pm version $_ required," ! . " but this is only version $VERSION"; ! } ! else { ! croak "Unrecognized argument $_"; ! } ! } ! unless ($saw_sig) { ! @_ = qw(old-interface-signals); ! goto Arg_loop; } } ! sub handler_die { ! croak "Caught a SIG$_[0]"; ! } ! ! sub handler_traceback { package DB; # To get subroutine args. $SIG{'ABRT'} = DEFAULT; kill 'ABRT', $$ if $panic++; *************** *** 77,79 **** --- 120,279 ---- } 1; + + __END__ + + =head1 SYNOPSIS + + use sigtrap; + use sigtrap qw(stack-trace old-interface-signals); # equivalent + use sigtrap qw(BUS SEGV PIPE ABRT); + use sigtrap qw(die INT QUIT); + use sigtrap qw(die normal-signals); + use sigtrap qw(die untrapped normal-signals); + use sigtrap qw(die untrapped normal-signals + stack-trace any error-signals); + use sigtrap 'handler' => \&my_handler, 'normal-signals'; + use sigtrap qw(handler my_handler normal-signals + stack-trace error-signals); + + =head1 DESCRIPTION + + The B pragma is a simple interface to installing signal + handlers. You can have it install one of two handlers supplied by + B itself (one which provides a Perl stack trace and one which + simply Cs), or alternately you can supply your own handler for it + to install. It can be told only to install a handler for signals which + are either untrapped or ignored. It has a couple of lists of signals to + trap, plus you can supply your own list of signals. + + The arguments passed to the C statement which invokes B + are processed in order. When a signal name or the name of one of + B's signal lists is encountered a handler is immediately + installed, when an option is encountered it affects subsequently + installed handlers. + + =head1 OPTIONS + + =head2 SIGNAL HANDLERS + + These options affect which handler will be used for subsequently + installed signals. + + =over + + =item B + + The handler used for subsequently installed signals will output a Perl + stack trace to STDERR and then tries to dump core. This is the default + signal handler. + + =item B + + The handler used for subsequently installed signals calls C + (actually C) with a message indicating which signal was caught. + + =item B I + + I will be used as the handler for subsequently installed + signals. I can be any value which is valid as an + assignment to an element of C<%SIG>. + + =back + + =head2 SIGNAL LISTS + + B has two built-in lists of signals to trap. They are: + + =over + + =item B + + These are the signals which a program might normally expect to encounter + and which by default cause it to terminate. They are HUP, INT, PIPE and + TERM. + + =item B + + These signals usually indicate a serious problem with the Perl + interpreter or with your script. They are ABRT, BUS, EMT, FPE, ILL, + QUIT, SEGV, SYS and TRAP. + + =item B + + These are the signals which were trapped by default by the old + B interface, they are ABRT, BUS, EMT, FPE, ILL, PIPE, QUIT, + SEGV, SYS, TERM, and TRAP. If no signals or signals lists are passed to + B this list is used. + + =back + + =head2 OTHER + + =item B + + This token tells B only to install handlers for subsequently + listed signals which aren't already trapped or ignored. + + =item B + + This token tells B to install handlers for all subsequently + listed signals. This is the default behavior. + + =item I + + Any argument which looks like a signals name (that is, + C) is taken as a signal name and indicates that + B should install a handler for it. + + =item I + + Require that at least version I of B is being used. + + =back + + =head1 EXAMPLES + + Provide a stack trace for the old-interface-signals: + + use sigtrap; + + Ditto: + + use sigtrap qw(stack-trace old-interface-signals); + + Provide a stack trace on the 4 listed signals only: + + use sigtrap qw(BUS SEGV PIPE ABRT); + + Die on INT or QUIT: + + use sigtrap qw(die INT QUIT); + + Die on HUP, INT, PIPE or TERM: + + use sigtrap qw(die normal-signals); + + Die on HUP, INT, PIPE or TERM, except don't change the behavior for + signals which are already trapped or ignored: + + use sigtrap qw(die untrapped normal-signals); + + Die on receipt one of an of the B which is currently + B, provide a stack trace on receipt of B of the + B: + + use sigtrap qw(die untrapped normal-signals + stack-trace any error-signals); + + Install my_handler() as the handler for the B: + + use sigtrap 'handler', \&my_handler, 'normal-signals'; + + Install my_handler() as the handler for the normal-signals, provide a + Perl stack trace on receipt of one of the error-signals: + + use sigtrap qw(handler my_handler normal-signals + stack-trace error-signals); + + =cut #~ Use ~-expanded version of privlib #~ Add VMS support diff -Pcr perl5_003/lib/splain perl5_003_01/lib/splain *** perl5_003/lib/splain Mon Jan 22 20:43:32 1996 --- perl5_003_01/lib/splain Wed Jul 10 13:27:38 1996 *************** *** 3,9 **** if 0; use Config; ! $diagnostics::PODFILE= $Config{privlib} . "/pod/perldiag.pod"; package diagnostics; require 5.001; --- 3,13 ---- if 0; use Config; ! if ($^O eq 'VMS') { ! $diagnostics::PODFILE = VMS::Filespec::unixify($Config{'privlibexp'}) . ! '/pod/perldiag.pod'; ! } ! else { $diagnostics::PODFILE= $Config{privlibexp} . "/pod/perldiag.pod"; } package diagnostics; require 5.001; #~ Add strict untie diff -Pcr perl5_003/lib/strict.pm perl5_003_01/lib/strict.pm *** perl5_003/lib/strict.pm Mon Jan 22 20:43:34 1996 --- perl5_003_01/lib/strict.pm Mon Jul 15 13:35:58 1996 *************** *** 11,16 **** --- 11,17 ---- use strict "vars"; use strict "refs"; use strict "subs"; + use strict "untie"; use strict; no strict "vars"; *************** *** 19,26 **** If no import list is supplied, all possible restrictions are assumed. (This is the safest mode to operate in, but is sometimes too strict for ! casual programming.) Currently, there are three possible things to be ! strict about: "subs", "vars", and "refs". =over 6 --- 20,27 ---- If no import list is supplied, all possible restrictions are assumed. (This is the safest mode to operate in, but is sometimes too strict for ! casual programming.) Currently, there are four possible things to be ! strict about: "subs", "vars", "refs", and "untie". =over 6 *************** *** 65,70 **** --- 66,89 ---- + =item C + + This generates a runtime error if any references to the object returned + by C (or C) still exist when C is called. Note that + to get this strict behaviour, the C statement must + be in the same scope as the C. See L, + L, L and L. + + use strict 'untie'; + $a = tie %a, 'SOME_PKG'; + $b = tie %b, 'SOME_PKG'; + $b = 0; + tie %c, PKG; + $c = tied %c; + untie %a ; # blows up, $a is a valid object reference. + untie %b; # ok, $b is not a reference to the object. + untie %c ; # blows up, $c is a valid object reference. + =back See L. *************** *** 78,95 **** $bits |= 0x00000002 if $sememe eq 'refs'; $bits |= 0x00000200 if $sememe eq 'subs'; $bits |= 0x00000400 if $sememe eq 'vars'; } $bits; } sub import { shift; ! $^H |= bits(@_ ? @_ : qw(refs subs vars)); } sub unimport { shift; ! $^H &= ~ bits(@_ ? @_ : qw(refs subs vars)); } 1; --- 97,115 ---- $bits |= 0x00000002 if $sememe eq 'refs'; $bits |= 0x00000200 if $sememe eq 'subs'; $bits |= 0x00000400 if $sememe eq 'vars'; + $bits |= 0x00000800 if $sememe eq 'untie'; } $bits; } sub import { shift; ! $^H |= bits(@_ ? @_ : qw(refs subs vars untie)); } sub unimport { shift; ! $^H &= ~ bits(@_ ? @_ : qw(refs subs vars untie)); } 1; #~ Add explanation of common usage diff -Pcr perl5_003/lib/vars.pm perl5_003_01/lib/vars.pm *** perl5_003/lib/vars.pm Fri Feb 2 14:31:24 1996 --- perl5_003_01/lib/vars.pm Thu Jul 11 12:22:48 1996 *************** *** 14,19 **** --- 14,26 ---- in the list, allowing you to use them under "use strict", and disabling any typo warnings. + Packages such as the B and B that delay loading + of subroutines within packages can create problems with package lexicals + defined using C. While the B pragma cannot duplicate the + effect of package lexicals (total transparency outside of the package), + it can act as an acceptable substitute by pre-declaring global symbols, + ensuring their availability to to the later-loaded routines. + See L. =cut #~ Delete old copy before generating new one diff -Pcr perl5_003/makeaperl.SH perl5_003_01/makeaperl.SH *** perl5_003/makeaperl.SH Mon Jan 22 20:40:10 1996 --- perl5_003_01/makeaperl.SH Thu Jul 11 12:25:29 1996 *************** *** 17,22 **** --- 17,23 ---- */*) cd `expr X$0 : 'X\(.*\)/'` ;; esac echo "Extracting makeaperl (with variable substitutions)" + rm -f makeaperl $spitshell >makeaperl <makedepend <.deptmp $rm -f *.c.c c/*.c.c if test -f Makefile; then + rm -f $firstmakefile cp Makefile $firstmakefile fi mf=$firstmakefile *************** *** 128,134 **** 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 done $echo "Updating $mf..." $echo "# If this runs make out of memory, delete /usr/include lines." \ --- 133,139 ---- 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 done $echo "Updating $mf..." $echo "# If this runs make out of memory, delete /usr/include lines." \ *************** *** 155,165 **** $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 done fi $rm -f $mf.old $cp $mf $mf.old $cp $mf.new $mf $rm $mf.new $echo "# WARNING: Put nothing here or make depend will gobble it up!" >> $mf --- 160,171 ---- $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 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 #~ Add PACK_MALLOC option #~ Improve OS/2 and NeXT support, including sbrk() replacement #~ Allow for redirection of diagnostic messages #~ Add calloc() function diff -Pcr perl5_003/malloc.c perl5_003_01/malloc.c *** perl5_003/malloc.c Sun Jan 28 02:18:22 1996 --- perl5_003_01/malloc.c Fri Jul 5 15:36:36 1996 *************** *** 14,19 **** --- 14,20 ---- * 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. */ *************** *** 27,33 **** --- 28,42 ---- #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 *************** *** 69,74 **** --- 78,144 ---- #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) ((int)x & ~TWOK_MASK) + # define TWOK_SHIFT(x) ((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. */ + }; + + # ifdef DEBUGGING_MSTATS + static u_int sbrk_slack; + static u_int start_slack; + # endif + + #else /* !PACK_MALLOC */ + + # define OV_MAGIC(block,bucket) (block)->ov_magic + # define OV_INDEX(block) (block)->ov_index + # define CHUNK_SHIFT 1 + #endif /* !PACK_MALLOC */ + + # define M_OVERHEAD (sizeof(union overhead) + RSLOP) + /* * 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,82 **** --- 146,158 ---- */ #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 /* *************** *** 132,139 **** * which satisfies request. Account for * space used per block for accounting. */ ! nbytes += sizeof (union overhead) + RSLOP; ! nbytes = (nbytes + 3) &~ 3; shiftr = (nbytes - 1) >> 2; /* apart from this loop, this is O(1) */ while (shiftr >>= 1) --- 208,223 ---- * which satisfies request. Account for * space used per block for accounting. */ ! #ifdef PACK_MALLOC ! if (nbytes > MAX_2_POT_ALGO) { ! #endif ! nbytes += M_OVERHEAD; ! nbytes = (nbytes + 3) &~ 3; ! #ifdef PACK_MALLOC ! } else if (nbytes == 0) { ! nbytes = 1; ! } ! #endif shiftr = (nbytes - 1) >> 2; /* apart from this loop, this is O(1) */ while (shiftr >>= 1) *************** *** 156,162 **** } #ifdef safemalloc ! DEBUG_m(fprintf(stderr,"0x%lx: (%05d) malloc %ld bytes\n", (unsigned long)(p+1),an++,(long)size)); #endif /* safemalloc */ --- 240,246 ---- } #ifdef safemalloc ! DEBUG_m(fprintf(Perl_debug_log,"0x%lx: (%05d) malloc %ld bytes\n", (unsigned long)(p+1),an++,(long)size)); #endif /* safemalloc */ *************** *** 167,174 **** (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]++; #endif --- 251,260 ---- (unsigned long)*((int*)p),(unsigned long)p); #endif nextf[bucket] = p->ov_next; ! OV_MAGIC(p, bucket) = MAGIC; ! #ifndef PACK_MALLOC ! OV_INDEX(p) = bucket; ! #endif #ifdef DEBUGGING_MSTATS nmalloc[bucket]++; #endif *************** *** 182,188 **** p->ov_rmagic = RMAGIC; *((u_int *)((caddr_t)p + nbytes - RSLOP)) = RMAGIC; #endif ! return ((Malloc_t)(p + 1)); } /* --- 268,274 ---- p->ov_rmagic = RMAGIC; *((u_int *)((caddr_t)p + nbytes - RSLOP)) = RMAGIC; #endif ! return ((Malloc_t)(p + CHUNK_SHIFT)); } /* *************** *** 196,201 **** --- 282,288 ---- register int rnu; /* 2^rnu bytes will be requested */ register int nblks; /* become nblks blocks of the desired size */ register MEM_SIZE siz; + int slack = 0; if (nextf[bucket]) return; *************** *** 206,217 **** */ #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 /* The sbrk(0) call on the I286 always returns the next segment */ ! #endif #endif /* atarist */ #if !(defined(I286) || defined(atarist)) --- 293,312 ---- */ #ifndef atarist /* on the atari we dont have to worry about this */ op = (union overhead *)sbrk(0); ! # ifndef I286 ! # ifdef PACK_MALLOC ! if ((int)op & 0x7ff) ! (void)sbrk(slack = 2048 - ((int)op & 0x7ff)); ! # else if ((int)op & 0x3ff) ! (void)sbrk(slack = 1024 - ((int)op & 0x3ff)); ! # endif ! # if defined(DEBUGGING_MSTATS) && defined(PACK_MALLOC) ! sbrk_slack += slack; ! # endif ! # else /* The sbrk(0) call on the I286 always returns the next segment */ ! # endif #endif /* atarist */ #if !(defined(I286) || defined(atarist)) *************** *** 223,230 **** 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); /* no more room! */ if ((int)op == -1) --- 318,325 ---- rnu = (bucket <= 11) ? 14 : bucket + 3; #endif nblks = 1 << (rnu - (bucket + 3)); /* how many blocks to get */ ! /* if (rnu < bucket) ! rnu = bucket; Why anyone needs this? */ op = (union overhead *)sbrk(1L << rnu); /* no more room! */ if ((int)op == -1) *************** *** 234,239 **** --- 329,338 ---- * and deduct from block count to reflect. */ #ifndef I286 + # ifdef PACK_MALLOC + if ((int)op & 0x7ff) + croak("panic: Off-page sbrk"); + # endif if ((int)op & 7) { op = (union overhead *)(((MEM_SIZE)op + 8) &~ 7); nblks--; *************** *** 245,256 **** * Add new memory allocated to that on * free list for this hash bucket. */ - nextf[bucket] = op; siz = 1 << (bucket + 3); while (--nblks > 0) { op->ov_next = (union overhead *)((caddr_t)op + siz); op = (union overhead *)((caddr_t)op + siz); } } Free_t --- 344,381 ---- * Add new memory allocated to that on * free list for this hash bucket. */ 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; while (--nblks > 0) { op->ov_next = (union overhead *)((caddr_t)op + siz); op = (union overhead *)((caddr_t)op + siz); } + #if defined(USE_PERL_SBRK) || defined(OS2) + /* all real sbrks return zeroe-d memory, perl's sbrk doesn't guarantee this */ + op->ov_next = (union overhead *)NULL; + #endif + #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,277 **** 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 RCHECK warn("%s free() ignored", op->ov_rmagic == RMAGIC - 1 ? "Duplicate" : "Bad"); --- 385,416 ---- register MEM_SIZE size; register union overhead *op; char *cp = (char*)mp; + #ifdef PACK_MALLOC + u_char bucket; + #endif #ifdef safemalloc ! DEBUG_m(fprintf(Perl_debug_log,"0x%lx: (%05d) free\n",(unsigned long)cp,an++)); #endif /* safemalloc */ ! if (cp == NULL) ! return; ! op = (union overhead *)((caddr_t)cp ! - sizeof (union overhead) * CHUNK_SHIFT); ! #ifdef PACK_MALLOC ! bucket = OV_INDEX(op); ! #endif #ifdef debug ! ASSERT(OV_MAGIC(op, bucket) == MAGIC); /* make sure it was in use */ #else ! if (OV_MAGIC(op, bucket) != MAGIC) { ! static 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"); *************** *** 283,294 **** #endif #ifdef RCHECK ASSERT(op->ov_rmagic == RMAGIC); ! if (op->ov_index <= 13) 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; op->ov_next = nextf[size]; nextf[size] = op; #ifdef DEBUGGING_MSTATS --- 422,433 ---- #endif #ifdef RCHECK ASSERT(op->ov_rmagic == RMAGIC); ! if (OV_INDEX(op) <= 13) ASSERT(*(u_int *)((caddr_t)op + op->ov_size + 1 - RSLOP) == RMAGIC); op->ov_rmagic = RMAGIC - 1; #endif ! ASSERT(OV_INDEX(op) < NBUCKETS); ! size = OV_INDEX(op); op->ov_next = nextf[size]; nextf[size] = op; #ifdef DEBUGGING_MSTATS *************** *** 340,349 **** #endif #endif /* safemalloc */ ! op = (union overhead *)((caddr_t)cp - sizeof (union overhead)); ! if (op->ov_magic == MAGIC) { was_alloced++; - i = op->ov_index; } else { /* * Already free, doing "compaction". --- 479,489 ---- #endif #endif /* safemalloc */ ! op = (union overhead *)((caddr_t)cp ! - sizeof (union overhead) * CHUNK_SHIFT); ! i = OV_INDEX(op); ! if (OV_MAGIC(op, i) == MAGIC) { was_alloced++; } else { /* * Already free, doing "compaction". *************** *** 360,382 **** (i = findbucket(op, reall_srchlen)) < 0) i = 0; } ! onb = (1L << (i + 3)) - sizeof (*op) - RSLOP; /* avoid the copy if same size block */ if (was_alloced && ! nbytes <= onb && nbytes > (onb >> 1) - sizeof(*op) - RSLOP) { #ifdef RCHECK /* * Record new allocated size of block and * bound space with magic numbers. */ ! if (op->ov_index <= 13) { /* * 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 = (nbytes + 3) &~ 3; op->ov_size = nbytes - 1; *((u_int *)((caddr_t)op + nbytes - RSLOP)) = RMAGIC; --- 500,528 ---- (i = findbucket(op, reall_srchlen)) < 0) i = 0; } ! onb = (1L << (i + 3)) - ! #ifdef PACK_MALLOC ! (i <= (MAX_PACKED - 3) ? 0 : M_OVERHEAD) ! #else ! M_OVERHEAD ! #endif ! ; /* avoid the copy if same size block */ if (was_alloced && ! nbytes <= onb && nbytes > (onb >> 1) - M_OVERHEAD) { #ifdef RCHECK /* * Record new allocated size of block and * bound space with magic numbers. */ ! if (OV_INDEX(op) <= 13) { /* * 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 += M_OVERHEAD; nbytes = (nbytes + 3) &~ 3; op->ov_size = nbytes - 1; *((u_int *)((caddr_t)op + nbytes - RSLOP)) = RMAGIC; *************** *** 429,434 **** --- 575,594 ---- 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 *************** *** 467,472 **** --- 627,638 ---- fprintf(stderr, (i<5)?" %5d":" %3d", nmalloc[i]); } fprintf(stderr, "\n"); + #ifdef PACK_MALLOC + if (sbrk_slack || start_slack) { + fprintf(stderr, "Odd ends: %7d bytes from sbrk(), %7d from malloc.\n", + sbrk_slack, start_slack); + } + #endif } #else void *************** *** 476,478 **** --- 642,717 ---- } #endif #endif /* lint */ + + + #ifdef USE_PERL_SBRK + + #ifdef NeXT + #ifdef HIDEMYMALLOC + #undef malloc + #else + #include "Error: -DUSE_PERL_SBRK on the NeXT requires -DHIDEMYMALLOC" + #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) + + #else + + /* OS/2 comes to mind ... */ + + #endif + + + 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 safemalloc + reqsize = size; /* just for the DEBUG_m statement */ + #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 safemalloc + reqsize = size; + #endif + size = PERLSBRK_64_K; + small = 1; + } + got = (IV)SYSTEM_ALLOC(size); + if (small) { + /* Chunk is small, register the rest for future allocs. */ + Perl_sbrk_oldchunk = got + reqsize; + Perl_sbrk_oldsize = size - reqsize; + } + } + + #ifdef safemalloc + DEBUG_m(fprintf(stderr,"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 */ #~ Use safefree() instead of Safefree to free memory allocated by safemalloc() #~ Add support for shared hash keys #~ Add $^E support for OS/2 #~ Add support for 64-bit time values #~ Add cast for new GV type #~ Don't allow errors in setting string $! to change $! #~ Restart system calls on all signals where possible #~ Add support for imporved %SIG management #~ Don't reset global $. unless we're reading a file diff -Pcr perl5_003/mg.c perl5_003_01/mg.c *** perl5_003/mg.c Mon Mar 25 01:04:56 1996 --- perl5_003_01/mg.c Fri Jul 5 18:20:30 1996 *************** *** 70,76 **** SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK); } ! Safefree(mgs); } --- 70,76 ---- SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK|SVf_POK); } ! safefree((void *)mgs); } *************** *** 210,216 **** SV* sv; SV* nsv; char *key; ! STRLEN klen; { int count = 0; MAGIC* mg; --- 210,216 ---- SV* sv; SV* nsv; char *key; ! I32 klen; { int count = 0; MAGIC* mg; *************** *** 235,241 **** 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_flags & MGf_REFCOUNTED) SvREFCNT_dec(mg->mg_obj); Safefree(mg); --- 235,244 ---- if (vtbl && vtbl->svt_free) (*vtbl->svt_free)(sv, mg); if (mg->mg_ptr && mg->mg_type != 'g') ! 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); *************** *** 346,354 **** --- 349,362 ---- sv_setpv(sv,""); } #else + #ifdef OS2 + 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 */ *************** *** 370,376 **** --- 378,388 ---- sv_setiv(sv,(I32)perldb); break; case '\024': /* ^T */ + #ifdef BIG_TIME + sv_setnv(sv,basetime); + #else sv_setiv(sv,(I32)basetime); + #endif break; case '\027': /* ^W */ sv_setiv(sv,(I32)dowarn); *************** *** 378,384 **** 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)); getparen: if (curpm->op_pmregexp && paren <= curpm->op_pmregexp->nparens && --- 390,396 ---- case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '&': if (curpm) { ! paren = atoi(GvENAME((GV*)mg->mg_obj)); getparen: if (curpm->op_pmregexp && paren <= curpm->op_pmregexp->nparens && *************** *** 485,494 **** --- 497,515 ---- case '!': #ifdef VMS sv_setnv(sv,(double)((errno == EVMSERR) ? vaxc$errno : errno)); + sv_setpv(sv, errno ? Strerror(errno) : ""); #else + { + 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 '<': *************** *** 548,570 **** MAGIC* mg; { register char *s; STRLEN len; I32 i; s = SvPV(sv,len); ! my_setenv(mg->mg_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); } #endif /* And you'll never guess what the dog had */ /* in its mouth... */ if (tainting) { ! if (s && strEQ(mg->mg_ptr,"PATH")) { char *strend = s + len; while (s < strend) { --- 569,593 ---- MAGIC* mg; { register char *s; + char *ptr; STRLEN len; I32 i; s = SvPV(sv,len); ! ptr = (mg->mg_len == HEf_SVKEY) ? SvPV((SV*)mg->mg_ptr, na) : mg->mg_ptr; ! my_setenv(ptr, s); #ifdef DYNAMIC_ENV_FETCH /* We just undefd an environment var. Is a replacement */ /* waiting in the wings? */ if (!len) { ! HE *envhe; ! if (envhe = hv_fetch_ent(GvHVn(envgv),HeSVKEY((HE*)(mg->mg_ptr)),FALSE,0)) ! s = SvPV(HeVAL(envhe),len); } #endif /* And you'll never guess what the dog had */ /* in its mouth... */ if (tainting) { ! if (s && strEQ(ptr,"PATH")) { char *strend = s + len; while (s < strend) { *************** *** 584,590 **** SV* sv; MAGIC* mg; { ! my_setenv(mg->mg_ptr,Nullch); return 0; } --- 607,614 ---- SV* sv; MAGIC* mg; { ! my_setenv(((mg->mg_len == HEf_SVKEY) ? ! SvPV((SV*)mg->mg_ptr, na) : mg->mg_ptr),Nullch); return 0; } *************** *** 603,621 **** act.sa_handler = handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; - #ifdef SIGALRM - if (signo == SIGALRM) { - #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 (sigaction(signo, &act, &oact) < 0) return(SIG_ERR); else --- 627,635 ---- 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) < 0) return(SIG_ERR); else *************** *** 630,635 **** --- 644,707 ---- #endif + static sig_trapped; + static + Signal_t + sig_trap(signo) + int signo; + { + sig_trapped++; + } + int + magic_getsig(sv,mg) + SV* sv; + MAGIC* mg; + { + I32 i; + /* Are we fetching a signal entry? */ + i = whichsig(mg->mg_ptr); + if (i) { + if(psig_ptr[i]) + sv_setsv(sv,psig_ptr[i]); + else { + void (*origsig)(int); + /* get signal state without losing signals */ + sig_trapped=0; + origsig = rsignal(i,sig_trap); + rsignal(i,origsig); + if(sig_trapped) + kill(getpid(),i); + /* cache state so we don't fetch it again */ + if(origsig == 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(mg->mg_ptr); + 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,646 **** I32 i; SV** svp; ! s = mg->mg_ptr; if (*s == '_') { if (strEQ(s,"__DIE__")) svp = &diehook; --- 712,718 ---- I32 i; SV** svp; ! s = (mg->mg_len == HEf_SVKEY) ? SvPV((SV*)mg->mg_ptr, na) : mg->mg_ptr; if (*s == '_') { if (strEQ(s,"__DIE__")) svp = &diehook; *************** *** 663,668 **** --- 735,748 ---- warn("No such signal: SIG%s", s); return 0; } + if(psig_ptr[i]) + SvREFCNT_dec(psig_ptr[i]); + psig_ptr[i] = SvREFCNT_inc(sv); + if(psig_name[i]) + SvREFCNT_dec(psig_name[i]); + psig_name[i] = newSVpv(mg->mg_ptr,strlen(mg->mg_ptr)); + SvTEMP_off(sv); /* Make sure it doesn't go away on us */ + SvREADONLY_on(psig_name[i]); } if (SvTYPE(sv) == SVt_PVGV || SvROK(sv)) { if (i) *************** *** 733,740 **** PUSHMARK(sp); EXTEND(sp, 2); PUSHs(mg->mg_obj); ! if (mg->mg_ptr) ! PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len))); else if (mg->mg_type == 'p') PUSHs(sv_2mortal(newSViv(mg->mg_len))); PUTBACK; --- 813,824 ---- PUSHMARK(sp); EXTEND(sp, 2); PUSHs(mg->mg_obj); ! 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,775 **** PUSHMARK(sp); EXTEND(sp, 3); PUSHs(mg->mg_obj); ! if (mg->mg_ptr) ! PUSHs(sv_2mortal(newSVpv(mg->mg_ptr, mg->mg_len))); else if (mg->mg_type == 'p') PUSHs(sv_2mortal(newSViv(mg->mg_len))); PUSHs(sv); --- 852,863 ---- PUSHMARK(sp); EXTEND(sp, 3); PUSHs(mg->mg_obj); ! 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); *************** *** 957,963 **** if (sv == (SV*)gv) return 0; if (GvGP(sv)) ! gp_free(sv); GvGP(sv) = gp_ref(GvGP(gv)); if (!GvAV(gv)) gv_AVadd(gv); --- 1045,1051 ---- if (sv == (SV*)gv) return 0; if (GvGP(sv)) ! gp_free((GV*)sv); GvGP(sv) = gp_ref(GvGP(gv)); if (!GvAV(gv)) gv_AVadd(gv); *************** *** 1106,1112 **** --- 1194,1204 ---- perldb = i; 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,1122 **** if (localizing == 1) save_sptr((SV**)&last_in_gv); } ! else if (SvOK(sv)) IoLINES(GvIOp(last_in_gv)) = (long)SvIV(sv); break; case '^': --- 1208,1214 ---- if (localizing == 1) save_sptr((SV**)&last_in_gv); } ! else if (SvOK(sv) && GvIO(last_in_gv)) IoLINES(GvIOp(last_in_gv)) = (long)SvIV(sv); break; case '^': *************** *** 1362,1402 **** SV *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 */ ! } if (!cv || !CvROOT(cv)) { if (dowarn) warn("SIG%s handler \"%s\" not defined.\n", ! signame, GvENAME(gv) ); return; } ! oldstack = stack; ! if (stack != signalstack) AvFILL(signalstack) = 0; ! SWITCHSTACK(stack, signalstack); ! sv = sv_newmortal(); ! sv_setpv(sv,signame); PUSHMARK(sp); PUSHs(sv); PUTBACK; --- 1454,1479 ---- SV *sv; CV *cv; AV *oldstack; ! cv = sv_2cv(psig_ptr[sig],&st,&gv,TRUE); if (!cv || !CvROOT(cv)) { if (dowarn) warn("SIG%s handler \"%s\" not defined.\n", ! sig_name[sig], GvENAME(gv) ); return; } ! oldstack = curstack; ! if (curstack != signalstack) AvFILL(signalstack) = 0; ! SWITCHSTACK(curstack, signalstack); ! if(psig_name[sig]) ! sv = SvREFCNT_inc(psig_name[sig]); ! else { ! sv = sv_newmortal(); ! sv_setpv(sv,sig_name[sig]); ! } PUSHMARK(sp); PUSHs(sv); PUTBACK; #~ Correct count in i18nl10n #~ Insure that perl_destruct() and perl_free() are called before exiting diff -Pcr perl5_003/miniperlmain.c perl5_003_01/miniperlmain.c *** perl5_003/miniperlmain.c Mon Mar 25 01:04:57 1996 --- perl5_003_01/miniperlmain.c Thu Jul 18 11:15:28 1996 *************** *** 33,39 **** PERL_SYS_INIT(&argc,&argv); ! perl_init_i18nl14n(1); if (!do_undump) { my_perl = perl_alloc(); --- 33,39 ---- PERL_SYS_INIT(&argc,&argv); ! perl_init_i18nl10n(1); if (!do_undump) { my_perl = perl_alloc(); *************** *** 43,52 **** } exitstatus = perl_parse( my_perl, xs_init, argc, argv, (char **) NULL ); ! if (exitstatus) ! exit( exitstatus ); ! ! exitstatus = perl_run( my_perl ); perl_destruct( my_perl ); perl_free( my_perl ); --- 43,51 ---- } exitstatus = perl_parse( my_perl, xs_init, argc, argv, (char **) NULL ); ! if (!exitstatus) { ! exitstatus = perl_run( my_perl ); ! } perl_destruct( my_perl ); perl_free( my_perl ); #~ Correct typo osver --> osvers diff -Pcr perl5_003/myconfig perl5_003_01/myconfig *** perl5_003/myconfig Mon Mar 25 01:04:59 1996 --- perl5_003_01/myconfig Wed Jul 10 20:40:12 1996 *************** *** 21,27 **** Summary of my $package ($baserev patchlevel $PATCHLEVEL subversion $SUBVERSION) configuration: Platform: ! osname=$osname, osver=$osvers, archname=$archname uname='$myuname' hint=$hint, useposix=$useposix, d_sigaction=$d_sigaction Compiler: --- 21,27 ---- Summary of my $package ($baserev patchlevel $PATCHLEVEL subversion $SUBVERSION) configuration: Platform: ! osname=$osname, osvers=$osvers, archname=$archname uname='$myuname' hint=$hint, useposix=$useposix, d_sigaction=$d_sigaction Compiler: #~ Add warning for duplicate my() declaration in same scope #~ Allow redirection of debug/error messages #~ Add op_seq flag used by compiler #~ Add support for new GV type #~ Add comment indicating potential fix for memory leak when free OP_ANONCODE; #~ however, this fix breaks eval of anon sub in closure #~ Carry G_KEEPERR setting down from perl_call_sv() into nested evals #~ Remove problematic integer optimization of order comparisons #~ Add shared hash key support #~ Add optional version check to "use" #~ Rename newCONDOP() parameters to avoid collisions with systtem headers #~ Call imported "glob" function from "<*.*>"-style expansion #~ Use defgv directly for arg-less "shift" within sub #~ Permit spaces in prototype specifications diff -Pcr perl5_003/op.c perl5_003_01/op.c *** perl5_003/op.c Sun Jun 23 20:35:03 1996 --- perl5_003_01/op.c Sat Jul 6 09:43:23 1996 *************** *** 124,129 **** --- 124,142 ---- sprintf(name+1, "^%c", name[1] ^ 64); /* XXX is tokenbuf, really */ croak("Can't use global %s in \"my\"",name); } + if (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); *************** *** 308,314 **** } SvFLAGS(sv) |= tmptype; curpad = AvARRAY(comppad); ! DEBUG_X(fprintf(stderr, "Pad alloc %ld for %s\n", (long) retval, op_name[optype])); return (PADOFFSET)retval; } --- 321,327 ---- } SvFLAGS(sv) |= tmptype; curpad = AvARRAY(comppad); ! DEBUG_X(fprintf(Perl_debug_log, "Pad alloc %ld for %s\n", (long) retval, op_name[optype])); return (PADOFFSET)retval; } *************** *** 322,328 **** { if (!po) croak("panic: pad_sv po"); ! DEBUG_X(fprintf(stderr, "Pad sv %d\n", po)); return curpad[po]; /* eventually we'll turn this into a macro */ } --- 335,341 ---- { if (!po) croak("panic: pad_sv po"); ! DEBUG_X(fprintf(Perl_debug_log, "Pad sv %d\n", po)); return curpad[po]; /* eventually we'll turn this into a macro */ } *************** *** 340,346 **** 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) SvPADTMP_off(curpad[po]); if ((I32)po < padix) --- 353,359 ---- croak("panic: pad_free curpad"); if (!po) croak("panic: pad_free po"); ! DEBUG_X(fprintf(Perl_debug_log, "Pad free %d\n", po)); if (curpad[po] && curpad[po] != &sv_undef) SvPADTMP_off(curpad[po]); if ((I32)po < padix) *************** *** 359,365 **** croak("panic: pad_swipe curpad"); if (!po) croak("panic: pad_swipe po"); ! DEBUG_X(fprintf(stderr, "Pad swipe %d\n", po)); SvPADTMP_off(curpad[po]); curpad[po] = NEWSV(1107,0); SvPADTMP_on(curpad[po]); --- 372,378 ---- croak("panic: pad_swipe curpad"); if (!po) croak("panic: pad_swipe po"); ! DEBUG_X(fprintf(Perl_debug_log, "Pad swipe %d\n", po)); SvPADTMP_off(curpad[po]); curpad[po] = NEWSV(1107,0); SvPADTMP_on(curpad[po]); *************** *** 374,380 **** if (AvARRAY(comppad) != curpad) croak("panic: pad_reset curpad"); ! DEBUG_X(fprintf(stderr, "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) --- 387,393 ---- if (AvARRAY(comppad) != curpad) croak("panic: pad_reset curpad"); ! DEBUG_X(fprintf(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) *************** *** 393,399 **** { register OP *kid, *nextkid; ! if (!op) return; if (op->op_flags & OPf_KIDS) { --- 406,412 ---- { register OP *kid, *nextkid; ! if (!op || op->op_seq == (U16)-1) return; if (op->op_flags & OPf_KIDS) { *************** *** 418,423 **** --- 431,437 ---- case OP_DBSTATE: SvREFCNT_dec(cCOP->cop_filegv); break; + /* case OP_ANONCODE: XXX breaks eval of anon subs in closures (cf. Opcode) */ case OP_CONST: SvREFCNT_dec(cSVOP->op_sv); break; *************** *** 1251,1257 **** block_start() { int retval = savestack_ix; ! comppad_name_fill = AvFILL(comppad_name); SAVEINT(min_intro_pending); SAVEINT(max_intro_pending); min_intro_pending = 0; --- 1265,1275 ---- block_start() { int retval = savestack_ix; ! SAVEINT(comppad_name_floor); ! if ((comppad_name_fill = AvFILL(comppad_name)) > 0) ! comppad_name_floor = comppad_name_fill; ! else ! comppad_name_floor = 0; SAVEINT(min_intro_pending); SAVEINT(max_intro_pending); min_intro_pending = 0; *************** *** 1287,1293 **** OP *op; { if (in_eval) { ! eval_root = newUNOP(OP_LEAVEEVAL, 0, op); eval_start = linklist(eval_root); eval_root->op_next = 0; peep(eval_start); --- 1305,1311 ---- OP *op; { if (in_eval) { ! 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); *************** *** 1388,1394 **** } op_free(o); if (type == OP_RV2GV) ! return newGVOP(OP_GV, 0, sv); else { if ((SvFLAGS(sv) & (SVf_IOK|SVf_NOK|SVf_POK)) == SVf_NOK) { IV iv = SvIV(sv); --- 1406,1412 ---- } op_free(o); if (type == OP_RV2GV) ! return newGVOP(OP_GV, 0, (GV*)sv); else { if ((SvFLAGS(sv) & (SVf_IOK|SVf_NOK|SVf_POK)) == SVf_NOK) { IV iv = SvIV(sv); *************** *** 1396,1401 **** --- 1414,1421 ---- SvREFCNT_dec(sv); sv = newSViv(iv); } + else + SvIOK_off(sv); /* undo SvIV() damage */ } return newSVOP(OP_CONST, 0, sv); } *************** *** 1405,1438 **** 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 */ 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)]; --- 1425,1441 ---- return o; if (!(hints & HINT_INTEGER)) { 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)) continue; return o; } if (opargs[curop->op_type] & OA_RETINTEGER) continue; return o; } o->op_ppaddr = ppaddr[++(o->op_type)]; *************** *** 2011,2017 **** char *name; sv = cSVOP->op_sv; name = SvPV(sv, len); ! curstash = gv_stashpv(name,TRUE); sv_setpvn(curstname, name, len); op_free(op); } --- 2014,2020 ---- char *name; sv = cSVOP->op_sv; name = SvPV(sv, len); ! curstash = gv_stashpvn(name,len,TRUE); sv_setpvn(curstname, name, len); op_free(op); } *************** *** 2024,2032 **** } void ! utilize(aver, floor, id, arg) int aver; I32 floor; OP *id; OP *arg; { --- 2027,2036 ---- } void ! utilize(aver, floor, version, id, arg) int aver; I32 floor; + OP *version; OP *id; OP *arg; { *************** *** 2034,2050 **** OP *meth; OP *rqop; OP *imop; if (id->op_type != OP_CONST) croak("Module name must be constant"); /* Fake up an import/unimport */ if (arg && arg->op_type == OP_STUB) imop = arg; /* no import on explicit () */ 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) --- 2038,2084 ---- 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,2070 **** newSVOP(OP_CONST, 0, newSVpv("BEGIN", 5)), Nullop, append_elem(OP_LINESEQ, ! newSTATEOP(0, Nullch, rqop), newSTATEOP(0, Nullch, imop) )); copline = NOLINE; --- 2098,2106 ---- newSVOP(OP_CONST, 0, newSVpv("BEGIN", 5)), Nullop, append_elem(OP_LINESEQ, ! append_elem(OP_LINESEQ, ! newSTATEOP(0, Nullch, rqop), ! newSTATEOP(0, Nullch, veop)), newSTATEOP(0, Nullch, imop) )); copline = NOLINE; *************** *** 2299,2305 **** cop->cop_line = copline; copline = NOLINE; } ! cop->cop_filegv = SvREFCNT_inc(curcop->cop_filegv); cop->cop_stash = curstash; if (perldb && curstash != debstash) { --- 2335,2341 ---- cop->cop_line = copline; copline = NOLINE; } ! cop->cop_filegv = GvREFCNT_inc(curcop->cop_filegv); cop->cop_stash = curstash; if (perldb && curstash != debstash) { *************** *** 2389,2424 **** } OP * ! newCONDOP(flags, first, true, false) I32 flags; OP* first; ! OP* true; ! OP* false; { CONDOP *condop; OP *op; ! if (!false) ! return newLOGOP(OP_AND, 0, first, true); ! if (!true) ! return newLOGOP(OP_OR, 0, first, false); scalarboolean(first); if (first->op_type == OP_CONST) { if (SvTRUE(((SVOP*)first)->op_sv)) { op_free(first); ! op_free(false); ! return true; } else { op_free(first); ! op_free(true); ! return false; } } else if (first->op_type == OP_WANTARRAY) { ! list(true); ! scalar(false); } Newz(1101, condop, 1, CONDOP); --- 2425,2460 ---- } OP * ! newCONDOP(flags, first, trueop, falseop) I32 flags; OP* first; ! OP* trueop; ! OP* falseop; { CONDOP *condop; OP *op; ! 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(falseop); ! return trueop; } else { op_free(first); ! op_free(trueop); ! return falseop; } } else if (first->op_type == OP_WANTARRAY) { ! list(trueop); ! scalar(falseop); } Newz(1101, condop, 1, CONDOP); *************** *** 2426,2445 **** 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_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; op = newUNOP(OP_NULL, 0, (OP*)condop); ! true->op_next = op; ! false->op_next = op; return op; } --- 2462,2481 ---- condop->op_ppaddr = ppaddr[OP_COND_EXPR]; condop->op_first = first; condop->op_flags = flags | OPf_KIDS; ! 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 = trueop; ! trueop->op_sibling = falseop; op = newUNOP(OP_NULL, 0, (OP*)condop); ! trueop->op_next = op; ! falseop->op_next = op; return op; } *************** *** 2723,2729 **** CvCLONED_on(cv); CvFILEGV(cv) = CvFILEGV(proto); ! CvGV(cv) = SvREFCNT_inc(CvGV(proto)); CvSTASH(cv) = CvSTASH(proto); CvROOT(cv) = CvROOT(proto); CvSTART(cv) = CvSTART(proto); --- 2759,2765 ---- CvCLONED_on(cv); CvFILEGV(cv) = CvFILEGV(proto); ! CvGV(cv) = GvREFCNT_inc(CvGV(proto)); CvSTASH(cv) = CvSTASH(proto); CvROOT(cv) = CvROOT(proto); CvSTART(cv) = CvSTART(proto); *************** *** 2796,2802 **** if (GvCVGEN(gv)) cv = 0; /* just a cached method */ else if (CvROOT(cv) || CvXSUB(cv) || GvASSUMECV(gv)) { ! if (dowarn) { /* already defined (or promised)? */ line_t oldline = curcop->cop_line; curcop->cop_line = copline; --- 2832,2838 ---- if (GvCVGEN(gv)) cv = 0; /* just a cached method */ else if (CvROOT(cv) || CvXSUB(cv) || GvASSUMECV(gv)) { ! if (dowarn && strNE(name, "BEGIN")) {/* already defined (or promised)? */ line_t oldline = curcop->cop_line; curcop->cop_line = copline; *************** *** 2823,2829 **** GvCV(gv) = cv; GvCVGEN(gv) = 0; CvFILEGV(cv) = curcop->cop_filegv; ! CvGV(cv) = SvREFCNT_inc(gv); CvSTASH(cv) = curstash; if (proto) { --- 2859,2865 ---- GvCV(gv) = cv; GvCVGEN(gv) = 0; CvFILEGV(cv) = curcop->cop_filegv; ! CvGV(cv) = GvREFCNT_inc(gv); CvSTASH(cv) = curstash; if (proto) { *************** *** 2879,2886 **** 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; --- 2915,2926 ---- av_push(beginav, (SV *)cv); DEBUG_x( dump_sub(gv) ); rs = SvREFCNT_inc(nrs); ! SvREFCNT_inc(cv); calllist(beginav); + if (GvCV(gv) == cv) { /* Detach it. */ + SvREFCNT_dec(cv); + GvCV(gv) = 0; /* Was above calllist, why? IZ */ + } SvREFCNT_dec(rs); rs = oldrs; curcop = &compiling; *************** *** 2966,2972 **** sv_upgrade((SV *)cv, SVt_PVCV); } GvCV(gv) = cv; ! CvGV(cv) = SvREFCNT_inc(gv); GvCVGEN(gv) = 0; CvFILEGV(cv) = gv_fetchfile(filename); CvXSUB(cv) = subaddr; --- 3006,3012 ---- sv_upgrade((SV *)cv, SVt_PVCV); } GvCV(gv) = cv; ! CvGV(cv) = GvREFCNT_inc(gv); GvCVGEN(gv) = 0; CvFILEGV(cv) = gv_fetchfile(filename); CvXSUB(cv) = subaddr; *************** *** 3023,3029 **** } cv = compcv; GvFORM(gv) = cv; ! CvGV(cv) = SvREFCNT_inc(gv); CvFILEGV(cv) = curcop->cop_filegv; for (ix = AvFILL(comppad); ix > 0; ix--) { --- 3063,3069 ---- } cv = compcv; GvFORM(gv) = cv; ! CvGV(cv) = GvREFCNT_inc(gv); CvFILEGV(cv) = curcop->cop_filegv; for (ix = AvFILL(comppad); ix > 0; ix--) { *************** *** 3530,3536 **** ck_glob(op) OP *op; { ! GV *gv = newGVgen("main"); gv_IOadd(gv); append_elem(OP_GLOB, op, newGVOP(OP_GV, 0, gv)); scalarkids(op); --- 3570,3587 ---- ck_glob(op) OP *op; { ! GV *gv = gv_fetchpv("glob", FALSE, SVt_PVCV); ! ! if (gv && GvIMPORTED_CV(gv)) { ! op->op_type = OP_LIST; ! op->op_ppaddr = ppaddr[OP_LIST]; ! op = newUNOP(OP_ENTERSUB, OPf_STACKED, ! append_elem(OP_LIST, op, ! scalar(newUNOP(OP_RV2CV, 0, ! newGVOP(OP_GV, 0, gv))))); ! return ck_subr(op); ! } ! gv = newGVgen("main"); gv_IOadd(gv); append_elem(OP_GLOB, op, newGVOP(OP_GV, 0, gv)); scalarkids(op); *************** *** 3745,3752 **** op_free(op); return newUNOP(type, 0, scalar(newUNOP(OP_RV2AV, 0, ! scalar(newGVOP(OP_GV, 0, ! gv_fetchpv((subline ? "_" : "ARGV"), TRUE, SVt_PVAV) ))))); } return scalar(modkids(ck_fun(op), type)); } --- 3796,3804 ---- op_free(op); return newUNOP(type, 0, scalar(newUNOP(OP_RV2AV, 0, ! scalar(newGVOP(OP_GV, 0, subline ! ? defgv ! : gv_fetchpv("ARGV", TRUE, SVt_PVAV) ))))); } return scalar(modkids(ck_fun(op), type)); } *************** *** 3953,3958 **** --- 4005,4013 ---- default: goto oops; } break; + case ' ': + proto++; + continue; default: oops: croak("Malformed prototype for %s: %s", #~ Overload OPf_SPECIAL with G_KEEPERR status for OP_(ENTER|LEAVE)EVAL diff -Pcr perl5_003/op.h perl5_003_01/op.h *** perl5_003/op.h Sun Jan 28 00:15:28 1996 --- perl5_003_01/op.h Fri Jul 5 13:38:18 1996 *************** *** 63,68 **** --- 63,69 ---- /* 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 $@ */ /* Private for lvalues */ #define OPpLVAL_INTRO 128 /* Lvalue must be localized */ #~ Reflect fix to "truncate" in opcode.pl diff -Pcr perl5_003/opcode.h perl5_003_01/opcode.h *** perl5_003/opcode.h Wed Feb 14 19:00:28 1996 --- perl5_003_01/opcode.h Fri Jul 5 14:59:56 1996 *************** *** 2344,2350 **** 0x00000e14, /* eof */ 0x00000e0c, /* tell */ 0x00011604, /* seek */ ! 0x00001114, /* truncate */ 0x0001160c, /* fcntl */ 0x0001160c, /* ioctl */ 0x0000161c, /* flock */ --- 2344,2350 ---- 0x00000e14, /* eof */ 0x00000e0c, /* tell */ 0x00011604, /* seek */ ! 0x00001614, /* truncate */ 0x0001160c, /* fcntl */ 0x0001160c, /* ioctl */ 0x0000161c, /* flock */ #~ "truncate" should expect file handle as first argument diff -Pcr perl5_003/opcode.pl perl5_003_01/opcode.pl *** perl5_003/opcode.pl Wed Feb 14 19:00:09 1996 --- perl5_003_01/opcode.pl Fri Jul 5 14:58:34 1996 *************** *** 477,483 **** eof eof ck_eof is F? tell tell ck_fun st F? seek seek ck_fun s F S S ! truncate truncate ck_trunc is S S fcntl fcntl ck_fun st F S S ioctl ioctl ck_fun st F S S --- 477,483 ---- eof eof ck_eof is F? tell tell ck_fun st F? seek seek ck_fun s F S S ! truncate truncate ck_trunc is F S fcntl fcntl ck_fun st F S S ioctl ioctl ck_fun st F S S #~ Add a.out support #~ Update library and dynamic loading support diff -Pcr perl5_003/os2/Makefile.SHs perl5_003_01/os2/Makefile.SHs *** perl5_003/os2/Makefile.SHs Mon Mar 25 01:05:00 1996 --- perl5_003_01/os2/Makefile.SHs Tue Jun 18 21:42:20 1996 *************** *** 1,5 **** ! # This file is read by Makefile.SH to produce rules for $(perllib) ! # We insert perl5.def since I do not know how to generate it yet. $spitshell >>Makefile <<'!NO!SUBS!' $(perllib): perl.imp perl.dll perl5.def --- 1,21 ---- ! # This file is read by Makefile.SH to produce rules for $(perllib) (and ! # some additional rules as well). ! ! # Rerun `sh Makefile.SH; make depend' after making any change. ! ! # Additional rules supported: perl_, aout_test, aout_install, use them ! # for a.out style perl (which may fork). ! ! $spitshell >>Makefile <>Makefile <<'!NO!SUBS!' $(perllib): perl.imp perl.dll perl5.def *************** *** 9,15 **** emximp -o perl.imp perl5.def perl.dll: $(obj) perl5.def perl$(OBJ_EXT) ! $(LD) $(LDDLFLAGS) -o $@ perl$(OBJ_EXT) $(obj) -lsocket perl5.def perl5.def: perl.linkexp echo "LIBRARY 'Perl' INITINSTANCE TERMINSTANCE" > $@ --- 25,31 ---- emximp -o perl.imp perl5.def perl.dll: $(obj) perl5.def perl$(OBJ_EXT) ! $(LD) $(LDDLFLAGS) -o $@ perl$(OBJ_EXT) $(obj) $(libs) perl5.def perl5.def: perl.linkexp echo "LIBRARY 'Perl' INITINSTANCE TERMINSTANCE" > $@ *************** *** 19,26 **** --- 35,46 ---- echo DATA LOADONCALL NONSHARED MULTIPLE >>$@ echo EXPORTS >>$@ echo ' "ctermid"' >>$@ + echo ' "get_sysinfo"' >>$@ echo ' "Perl_OS2_init"' >>$@ echo ' "OS2_Perl_data"' >>$@ + echo ' "dlopen"' >>$@ + echo ' "dlsym"' >>$@ + echo ' "dlerror"' >>$@ !NO!SUBS! if [ ! -z "$myttyname" ] ; then *************** *** 49,59 **** cat perl.exports perl.map | sort | uniq -d | sed -e 's/\w\+/ "\0"/' > perl.linkexp perl.map: $(obj) perl$(OBJ_EXT) miniperlmain$(OBJ_EXT) ! $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o dummy.exe miniperlmain$(OBJ_EXT) perl$(OBJ_EXT) $(obj) -lsocket -lm -Zmap -Zlinker /map awk '{if ($$3 == "") print $$2}' perl.map rm dummy.exe dummy.map ! depend: os2ish.h # Stupid make? Needed... os2$(OBJ_EXT) : os2.c --- 69,79 ---- cat perl.exports perl.map | sort | uniq -d | sed -e 's/\w\+/ "\0"/' > perl.linkexp perl.map: $(obj) perl$(OBJ_EXT) miniperlmain$(OBJ_EXT) ! $(CC) $(LARGE) $(CLDFLAGS) $(CCDLFLAGS) -o dummy.exe miniperlmain$(OBJ_EXT) perl$(OBJ_EXT) $(obj) $(libs) -Zmap -Zlinker /map awk '{if ($$3 == "") print $$2}' perl.map rm dummy.exe dummy.map ! depend: os2ish.h dlfcn.h # Stupid make? Needed... os2$(OBJ_EXT) : os2.c *************** *** 61,71 **** --- 81,140 ---- os2.c: os2/os2.c os2ish.h cp $< $@ + dl_os2.c: os2/dl_os2.c os2ish.h + cp $< $@ + os2ish.h: os2/os2ish.h cp $< $@ + dlfcn.h: os2/dlfcn.h + cp $< $@ + + installcmd : perl -e 'die qq{Give the option INSTALLCMDDIR=... to make!} if $$ARGV[0] eq ""' $(INSTALLCMDDIR) perl os2/perl2cmd.pl $(INSTALLCMDDIR) + + # Aout section: + + aout_obj = $(addsuffix $(AOUT_OBJ_EXT),$(basename $(obj))) + AOUT_DYNALOADER = $(addsuffix $(AOUT_LIB_EXT),$(basename $(DYNALOADER))) + aout_static_ext = $(addsuffix $(AOUT_LIB_EXT),$(basename $(dynamic_ext))) + aout_static_lib = $(addsuffix $(LIB_EXT),$(basename $(dynamic_ext))) + + $(aout_perllib) : $(aout_obj) perl$(AOUT_OBJ_EXT) + rm -f $(perllib) + $(AOUT_AR) rcu $(aout_perllib) perl$(AOUT_OBJ_EXT) $(aout_obj) + + .c$(AOUT_OBJ_EXT): + $(AOUT_CCCMD) $(PLDLFLAGS) -c $*.c + + aout_perlmain.c: miniperlmain.c config.sh makefile $(static_ext_autoinit) + sh writemain $(DYNALOADER) $(aout_static_lib) > tmp + sh mv-if-diff tmp aout_perlmain.c + + miniperl_: $& miniperlmain$(AOUT_OBJ_EXT) $(aout_perllib) ext.libs + $(CC) $(LARGE) $(AOUT_CLDFLAGS) $(CCDLFLAGS) -o miniperl_ miniperlmain$(AOUT_OBJ_EXT) $(aout_perllib) `cat ext.libs` $(libs) + + perl_: $& aout_perlmain$(AOUT_OBJ_EXT) $(aout_perllib) $(AOUT_DYNALOADER) $(aout_static_ext) ext.libs + $(CC) $(LARGE) $(AOUT_CLDFLAGS) $(CCDLFLAGS) -o perl_ aout_perlmain$(AOUT_OBJ_EXT) $(AOUT_DYNALOADER) $(aout_static_ext) $(aout_perllib) `cat ext.libs` $(libs) + + aout_clean: + -rm *perl_.* *.o *.a lib/auto/*/*.a ext/*/Makefile.aout + + aout_install: perl_ aout_install.perl + + aout_install.perl: perl_ installperl + ./perl_ installperl + + aout_test: perl_ + - cd t && (rm -f perl_$(EXE_EXT); $(LNS) ../perl_$(EXE_EXT) perl_$(EXE_EXT)) && ./perl_ TEST + + static ULONG retcode; + + void * + dlopen(char *path, int mode) + { + HMODULE handle; + char tmp[260], *beg, *dot; + char fail[300]; + ULONG rc; + + if ((rc = DosLoadModule(fail, sizeof fail, path, &handle)) == 0) + return (void *)handle; + + retcode = rc; + + /* Not found. Check for non-FAT name and try truncated name. */ + /* Don't know if this helps though... */ + for (beg = dot = path + strlen(path); + beg > path && !strchr(":/\\", *(beg-1)); + beg--) + if (*beg == '.') + dot = beg; + if (dot - beg > 8) { + int n = beg+8-path; + memmove(tmp, path, n); + memmove(tmp+n, dot, strlen(dot)+1); + if (DosLoadModule(fail, sizeof fail, tmp, &handle) == 0) + return (void *)handle; + } + + return NULL; + } + + void * + dlsym(void *handle, char *symbol) + { + ULONG rc, type; + PFN addr; + + rc = DosQueryProcAddr((HMODULE)handle, 0, symbol, &addr); + if (rc == 0) { + rc = DosQueryProcType((HMODULE)handle, 0, symbol, &type); + if (rc == 0 && type == PT_32BIT) + return (void *)addr; + rc = ERROR_CALL_NOT_IMPLEMENTED; + } + retcode = rc; + return NULL; + } + + char * + dlerror(void) + { + static char buf[300]; + ULONG len; + + if (retcode == 0) + return NULL; + if (DosGetMessage(NULL, 0, buf, sizeof buf - 1, retcode, "OSO001.MSG", &len)) + sprintf(buf, "OS/2 system error code %d", retcode); + else + buf[len] = '\0'; + retcode = 0; + return buf; + } + #~ Prototypes for OS/2-specific emulation of dlopen routines diff -Pcr perl5_003/os2/dlfcn.h perl5_003_01/os2/dlfcn.h *** perl5_003/os2/dlfcn.h Wed Dec 31 19:00:00 1969 --- perl5_003_01/os2/dlfcn.h Tue Jun 18 20:42:27 1996 *************** *** 0 **** --- 1,6 ---- + void *dlopen(char *path, int mode); + void *dlsym(void *handle, char *symbol); + char *dlerror(void); + void *dlopen(char *path, int mode); + void *dlsym(void *handle, char *symbol); + char *dlerror(void); #~ DB_File OS/2 changes subsumed into new version of DB_File diff -Pcr perl5_003/os2/notes perl5_003_01/os2/notes *** perl5_003/os2/notes Mon Jan 22 20:46:20 1996 --- perl5_003_01/os2/notes Fri Jul 5 18:45:34 1996 *************** *** 25,28 **** diff.c2ph, diff.rest are small and should not break anything. - diff.db_file adds binary mode. --- 25,27 ---- #~ Update process priority functions #~ Use SH_PATH macro to find shell #~ Use local popen only if not using fork() #~ Add OS/2-specific mod2fname for DynaLoader support #~ Add strerror() equivalent for OS/2-specific errors diff -Pcr perl5_003/os2/os2.c perl5_003_01/os2/os2.c *** perl5_003/os2/os2.c Mon Mar 25 01:05:01 1996 --- perl5_003_01/os2/os2.c Tue Jun 18 21:42:24 1996 *************** *** 21,39 **** /*****************************************************************************/ /* priorities */ ! int setpriority(int which, int pid, int val) { ! return DosSetPriority((pid < 0) ? PRTYS_PROCESSTREE : PRTYS_PROCESS, ! val >> 8, val & 0xFF, abs(pid)); } ! int getpriority(int which /* ignored */, int pid) { TIB *tib; PIB *pib; ! DosGetInfoBlocks(&tib, &pib); ! return tib->tib_ptib2->tib2_ulpri; } /*****************************************************************************/ --- 21,131 ---- /*****************************************************************************/ /* priorities */ + static signed char priors[] = {0, 1, 3, 2}; /* Last two interchanged, + self inverse. */ + #define QSS_INI_BUFFER 1024 + + PQTOPLEVEL + get_sysinfo(ULONG pid, ULONG flags) + { + char *pbuffer; + ULONG rc, buf_len = QSS_INI_BUFFER; + + New(1022, pbuffer, buf_len, char); + /* QSS_PROCESS | QSS_MODULE | QSS_SEMAPHORES | QSS_SHARED */ + rc = QuerySysState(flags, pid, pbuffer, buf_len); + while (rc == ERROR_BUFFER_OVERFLOW) { + Renew(pbuffer, buf_len *= 2, char); + rc = QuerySysState(QSS_PROCESS, pid, pbuffer, buf_len); + } + if (rc) { + FillOSError(rc); + Safefree(pbuffer); + return 0; + } + return (PQTOPLEVEL)pbuffer; + } + + #define PRIO_ERR 0x1111 ! static ULONG ! sys_prio(pid) { ! ULONG prio; ! PQTOPLEVEL psi; ! ! psi = get_sysinfo(pid, QSS_PROCESS); ! if (!psi) { ! return PRIO_ERR; ! } ! if (pid != psi->procdata->pid) { ! Safefree(psi); ! croak("panic: wrong pid in sysinfo"); ! } ! prio = psi->procdata->threads->priority; ! Safefree(psi); ! return prio; ! } ! ! int ! setpriority(int which, int pid, int val) ! { ! ULONG rc, prio; ! PQTOPLEVEL psi; ! ! prio = sys_prio(pid); ! ! if (priors[(32 - val) >> 5] + 1 == (prio >> 8)) { ! /* Do not change class. */ ! return CheckOSError(DosSetPriority((pid < 0) ! ? PRTYS_PROCESSTREE : PRTYS_PROCESS, ! 0, ! (32 - val) % 32 - (prio & 0xFF), ! abs(pid))) ! ? -1 : 0; ! } else /* if ((32 - val) % 32 == (prio & 0xFF)) */ { ! /* Documentation claims one can change both class and basevalue, ! * but I find it wrong. */ ! /* Change class, but since delta == 0 denotes absolute 0, correct. */ ! if (CheckOSError(DosSetPriority((pid < 0) ! ? PRTYS_PROCESSTREE : PRTYS_PROCESS, ! priors[(32 - val) >> 5] + 1, ! 0, ! abs(pid)))) ! return -1; ! if ( ((32 - val) % 32) == 0 ) return 0; ! return CheckOSError(DosSetPriority((pid < 0) ! ? PRTYS_PROCESSTREE : PRTYS_PROCESS, ! 0, ! (32 - val) % 32, ! abs(pid))) ! ? -1 : 0; ! } ! /* else return CheckOSError(DosSetPriority((pid < 0) */ ! /* ? PRTYS_PROCESSTREE : PRTYS_PROCESS, */ ! /* priors[(32 - val) >> 5] + 1, */ ! /* (32 - val) % 32 - (prio & 0xFF), */ ! /* abs(pid))) */ ! /* ? -1 : 0; */ } ! int ! getpriority(int which /* ignored */, int pid) { TIB *tib; PIB *pib; ! ULONG rc, ret; ! ! /* DosGetInfoBlocks has old priority! */ ! /* if (CheckOSError(DosGetInfoBlocks(&tib, &pib))) return -1; */ ! /* if (pid != pib->pib_ulpid) { */ ! ret = sys_prio(pid); ! if (ret == PRIO_ERR) { ! return -1; ! } ! /* } else */ ! /* ret = tib->tib_ptib2->tib2_ulpri; */ ! return (1 - priors[((ret >> 8) - 1)])*32 - (ret & 0xFF); } /*****************************************************************************/ *************** *** 135,141 **** have a shell which will not change between computers with the same architecture, to avoid "action on a distance". And to have simple build, this shell should be sh. */ ! shell = "sh.exe"; copt = "-c"; #endif --- 227,233 ---- have a shell which will not change between computers with the same architecture, to avoid "action on a distance". And to have simple build, this shell should be sh. */ ! shell = SH_PATH; copt = "-c"; #endif *************** *** 194,199 **** --- 286,292 ---- return rc; } + #ifndef HAS_FORK FILE * my_popen(cmd,mode) char *cmd; *************** *** 202,212 **** char *shell = getenv("EMXSHELL"); FILE *res; ! my_setenv("EMXSHELL", "sh.exe"); res = popen(cmd, mode); my_setenv("EMXSHELL", shell); return res; } /*****************************************************************************/ --- 295,306 ---- char *shell = getenv("EMXSHELL"); FILE *res; ! my_setenv("EMXSHELL", SH_PATH); res = popen(cmd, mode); my_setenv("EMXSHELL", shell); return res; } + #endif /*****************************************************************************/ *************** *** 357,370 **** flag = (unsigned long)SvIV(ST(2)); } ! errno = DosCopy(src, dst, flag); ! RETVAL = !errno; ST(0) = sv_newmortal(); sv_setiv(ST(0), (IV)RETVAL); } XSRETURN(1); } OS2_Perl_data_t OS2_Perl_data; int --- 451,519 ---- flag = (unsigned long)SvIV(ST(2)); } ! RETVAL = !CheckOSError(DosCopy(src, dst, flag)); ST(0) = sv_newmortal(); sv_setiv(ST(0), (IV)RETVAL); } XSRETURN(1); } + char * + mod2fname(sv) + SV *sv; + { + static char fname[9]; + int pos = 7; + int len; + AV *av; + SV *svp; + char *s; + + if (!SvROK(sv)) croak("Not a reference given to mod2fname"); + sv = SvRV(sv); + if (SvTYPE(sv) != SVt_PVAV) + croak("Not array reference given to mod2fname"); + if (av_len((AV*)sv) < 0) + croak("Empty array reference given to mod2fname"); + s = SvPV(*av_fetch((AV*)sv, av_len((AV*)sv), FALSE), na); + strncpy(fname, s, 8); + if ((len=strlen(s)) < 7) pos = len; + fname[pos] = '_'; + fname[pos + 1] = '\0'; + return (char *)fname; + } + + XS(XS_DynaLoader_mod2fname) + { + dXSARGS; + if (items != 1) + croak("Usage: DynaLoader::mod2fname(sv)"); + { + SV * sv = ST(0); + char * RETVAL; + + RETVAL = mod2fname(sv); + ST(0) = sv_newmortal(); + sv_setpv((SV*)ST(0), RETVAL); + } + XSRETURN(1); + } + + char * + os2error(int rc) + { + static char buf[300]; + ULONG len; + + if (rc == 0) + return NULL; + if (DosGetMessage(NULL, 0, buf, sizeof buf - 1, rc, "OSO001.MSG", &len)) + sprintf(buf, "OS/2 system error code %d=0x%x", rc, rc); + else + buf[len] = '\0'; + return buf; + } + OS2_Perl_data_t OS2_Perl_data; int *************** *** 372,384 **** --- 521,551 ---- { char *file = __FILE__; { + GV *gv; + newXS("File::Copy::syscopy", XS_File__Copy_syscopy, file); + newXS("DynaLoader::mod2fname", XS_DynaLoader_mod2fname, file); + #ifdef PERL_IS_AOUT + gv = gv_fetchpv("OS2::is_aout", TRUE, SVt_PV); + GvMULTI_on(gv); + sv_setiv(GvSV(gv), 1); + #endif } } void Perl_OS2_init() { + char *shell; + settmppath(); OS2_Perl_data.xs_init = &Xs_OS2_init; + if ( (shell = getenv("PERL_SH_DRIVE")) ) { + sh_path[0] = shell[0]; + } } + + char sh_path[33] = BIN_SH; + + extern void dlopen(); + void *fakedl = &dlopen; /* Pull in dynaloading part. */ #~ Add OS-specific setup for cpp macros introduced by Plan9 and VMS #~ Eliminate old PERL_SYS_TERM definition #~ Add a.out support #~ Improved error status/message handling #~ Add data types for process management diff -Pcr perl5_003/os2/os2ish.h perl5_003_01/os2/os2ish.h *** perl5_003/os2/os2ish.h Mon Mar 25 01:05:01 1996 --- perl5_003_01/os2/os2ish.h Thu Jul 25 16:12:38 1996 *************** *** 14,19 **** --- 14,41 ---- #define HAS_KILL #define HAS_WAIT + #define HAS_DLERROR + + /* 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 /**/ #ifndef SIGABRT # define SIGABRT SIGILL *************** *** 34,41 **** --- 56,70 ---- #define PERL_SYS_TERM() + /* #define PERL_SYS_TERM() STMT_START { \ + if (Perl_HAB_set) WinTerminate(Perl_hab); } STMT_END */ + #define dXSUB_SYS int fake = OS2_XS_init() + #ifdef PERL_IS_AOUT + #define NO_SYS_ALLOC + #endif + #define TMPPATH tmppath #define TMPPATH1 "plXXXXXX" extern char *tmppath; *************** *** 96,109 **** unsigned long flags; unsigned long phab; int (*xs_init)(); } OS2_Perl_data_t; extern OS2_Perl_data_t OS2_Perl_data; ! #define hab ((HAB)OS2_Perl_data->phab) ! #define OS2_Perl_flag (OS2_Perl_data->flag) #define Perl_HAB_set_f 1 ! #define Perl_HAB_set (OS2_Perl_flag & Perl_HAB_set_f) ! #define set_Perl_HAB_f (OS2_Perl_flag |= Perl_HAB_set_f) ! #define set_Perl_HAB(h) (set_Perl_HAB_f, hab = h) #define OS2_XS_init() (*OS2_Perl_data.xs_init)() --- 125,337 ---- unsigned long flags; unsigned long phab; int (*xs_init)(); + unsigned long rc; + unsigned long severity; } OS2_Perl_data_t; extern OS2_Perl_data_t OS2_Perl_data; ! #define Perl_hab ((HAB)OS2_Perl_data.phab) ! #define Perl_rc (OS2_Perl_data.rc) ! #define Perl_severity (OS2_Perl_data.severity) ! #define errno_isOS2 12345678 ! #define OS2_Perl_flags (OS2_Perl_data.flags) #define Perl_HAB_set_f 1 ! #define Perl_HAB_set (OS2_Perl_flags & Perl_HAB_set_f) ! #define set_Perl_HAB_f (OS2_Perl_flags |= Perl_HAB_set_f) ! #define set_Perl_HAB(h) (set_Perl_HAB_f, Perl_hab = h) #define OS2_XS_init() (*OS2_Perl_data.xs_init)() + /* The expressions below return true on error. */ + /* INCL_DOSERRORS needed. */ + #define CheckOSError(expr) (!(rc = (expr)) ? 0 : (FillOSError(rc), 1)) + /* INCL_WINERRORS needed. */ + #define SaveWinError(expr) ((expr) ? : (FillWinError, 0)) + #define CheckWinError(expr) ((expr) ? 0: (FillWinError, 1)) + #define FillOSError(rc) (Perl_rc = rc, \ + errno = errno_isOS2, \ + Perl_severity = SEVERITY_ERROR) + #define FillWinError (Perl_rc = WinGetLastError(Perl_hab), \ + errno = errno_isOS2, \ + Perl_severity = ERRORIDSEV(Perl_rc), \ + Perl_rc = ERRORIDERROR(Perl_rc)) + #define Acquire_hab() if (!Perl_HAB_set) { \ + Perl_hab = WinInitialize(0); \ + if (!Perl_hab) die("WinInitialize failed"); \ + set_Perl_HAB_f; \ + } + + extern char sh_path[33]; + #define SH_PATH sh_path + + char *os2error(int rc); + + /* ************************************************************ */ + #define Dos32QuerySysState DosQuerySysState + #define QuerySysState(flags, pid, buf, bufsz) \ + Dos32QuerySysState(flags, 0, pid, 0, buf, bufsz) + + #define QSS_PROCESS 1 + #define QSS_MODULE 2 + #define QSS_SEMAPHORES 4 + #define QSS_FILE 8 /* Buggy until fixpack18 */ + #define QSS_SHARED 16 + + #ifdef _OS2EMX_H + + APIRET APIENTRY Dos32QuerySysState(ULONG func,ULONG arg1,ULONG pid, + ULONG _res_,PVOID buf,ULONG bufsz); + typedef struct { + ULONG threadcnt; + ULONG proccnt; + ULONG modulecnt; + } QGLOBAL, *PQGLOBAL; + + typedef struct { + ULONG rectype; + USHORT threadid; + USHORT slotid; + ULONG sleepid; + ULONG priority; + ULONG systime; + ULONG usertime; + UCHAR state; + UCHAR _reserved1_; /* padding to ULONG */ + USHORT _reserved2_; /* padding to ULONG */ + } QTHREAD, *PQTHREAD; + + typedef struct { + USHORT sfn; + USHORT refcnt; + USHORT flags1; + USHORT flags2; + USHORT accmode1; + USHORT accmode2; + ULONG filesize; + USHORT volhnd; + USHORT attrib; + USHORT _reserved_; + } QFDS, *PQFDS; + + typedef struct qfile { + ULONG rectype; + struct qfile *next; + ULONG opencnt; + PQFDS filedata; + char name[1]; + } QFILE, *PQFILE; + + typedef struct { + ULONG rectype; + PQTHREAD threads; + USHORT pid; + USHORT ppid; + ULONG type; + ULONG state; + ULONG sessid; + USHORT hndmod; + USHORT threadcnt; + ULONG privsem32cnt; + ULONG _reserved2_; + USHORT sem16cnt; + USHORT dllcnt; + USHORT shrmemcnt; + USHORT fdscnt; + PUSHORT sem16s; + PUSHORT dlls; + PUSHORT shrmems; + PUSHORT fds; + } QPROCESS, *PQPROCESS; + + typedef struct sema { + struct sema *next; + USHORT refcnt; + UCHAR sysflags; + UCHAR sysproccnt; + ULONG _reserved1_; + USHORT index; + CHAR name[1]; + } QSEMA, *PQSEMA; + + typedef struct { + ULONG rectype; + ULONG _reserved1_; + USHORT _reserved2_; + USHORT syssemidx; + ULONG index; + QSEMA sema; + } QSEMSTRUC, *PQSEMSTRUC; + + typedef struct { + USHORT pid; + USHORT opencnt; + } QSEMOWNER32, *PQSEMOWNER32; + + typedef struct { + PQSEMOWNER32 own; + PCHAR name; + PVOID semrecs; /* array of associated sema's */ + USHORT flags; + USHORT semreccnt; + USHORT waitcnt; + USHORT _reserved_; /* padding to ULONG */ + } QSEMSMUX32, *PQSEMSMUX32; + + typedef struct { + PQSEMOWNER32 own; + PCHAR name; + PQSEMSMUX32 mux; + USHORT flags; + USHORT postcnt; + } QSEMEV32, *PQSEMEV32; + + typedef struct { + PQSEMOWNER32 own; + PCHAR name; + PQSEMSMUX32 mux; + USHORT flags; + USHORT refcnt; + USHORT thrdnum; + USHORT _reserved_; /* padding to ULONG */ + } QSEMMUX32, *PQSEMMUX32; + + typedef struct semstr32 { + struct semstr *next; + QSEMEV32 evsem; + QSEMMUX32 muxsem; + QSEMSMUX32 smuxsem; + } QSEMSTRUC32, *PQSEMSTRUC32; + + typedef struct shrmem { + struct shrmem *next; + USHORT hndshr; + USHORT selshr; + USHORT refcnt; + CHAR name[1]; + } QSHRMEM, *PQSHRMEM; + + typedef struct module { + struct module *next; + USHORT hndmod; + USHORT type; + ULONG refcnt; + ULONG segcnt; + PVOID _reserved_; + PCHAR name; + USHORT modref[1]; + } QMODULE, *PQMODULE; + + typedef struct { + PQGLOBAL gbldata; + PQPROCESS procdata; + PQSEMSTRUC semadata; + PQSEMSTRUC32 sem32data; + PQSHRMEM shrmemdata; + PQMODULE moddata; + PVOID _reserved2_; + PQFILE filedata; + } QTOPLEVEL, *PQTOPLEVEL; + /* ************************************************************ */ + + PQTOPLEVEL get_sysinfo(ULONG pid, ULONG flags); + + #endif /* _OS2EMX_H */ #~ Update SUBVERSION #~ Hide LOCAL_PATCH_COUNT from metaconfig diff -Pcr perl5_003/patchlevel.h perl5_003_01/patchlevel.h *** perl5_003/patchlevel.h Sun Jun 23 13:57:18 1996 --- perl5_003_01/patchlevel.h Sun Jul 7 20:12:50 1996 *************** *** 1,5 **** #define PATCHLEVEL 3 ! #define SUBVERSION 0 /* local_patches -- list of locally applied less-than-subversion patches. --- 1,5 ---- #define PATCHLEVEL 3 ! #define SUBVERSION 1 /* local_patches -- list of locally applied less-than-subversion patches. *************** *** 41,45 **** ,NULL }; ! #define LOCAL_PATCH_COUNT \ (sizeof(local_patches)/sizeof(local_patches[0])-2) --- 41,46 ---- ,NULL }; ! /* Initial space prevents this variable from being inserted in config.sh */ ! # define LOCAL_PATCH_COUNT \ (sizeof(local_patches)/sizeof(local_patches[0])-2) #~ Clean up interpreter initialization to eliminate leaks when #~ multiple interpreters are started within a single application #~ Add shared hash key support #~ Initialize NeXT dynamic loading #~ Move information from -v to -V to keep the former concise #~ Rename global variables to eliminate collisions with system headers #~ Initialize new UNIVERSAL routines #~ Allow redirection of debug messages #~ Get debugger set up to debug BEGIN blocks #~ Assume G_EVAL in perl_eval_sv(), and propagate G_KEEPERR correctly #~ Remove help info for obsolete OS/2 command line switch #~ Uncouple $/ setup from $\ #~ Update VMS -S handling #~ Recognize perl binaries on #! line when name contains version #~ Insure open script is rewound by suidperl before handing off to normal perl diff -Pcr perl5_003/perl.c perl5_003_01/perl.c *** perl5_003/perl.c Mon Jun 24 17:06:37 1996 --- perl5_003_01/perl.c Thu Jul 11 12:25:43 1996 *************** *** 45,50 **** --- 45,51 ---- static void init_postdump_symbols _((int, char **, char **)); static void init_predump_symbols _((void)); static void init_stacks _((void)); + static void nuke_stacks _((void)); static void open_script _((char *, bool, SV *)); static void usage _((char *)); static void validate_suid _((char *, char*)); *************** *** 77,91 **** linestr = NEWSV(65,80); sv_upgrade(linestr,SVt_PVIV); ! SvREADONLY_on(&sv_undef); ! sv_setpv(&sv_no,No); ! SvNV(&sv_no); ! SvREADONLY_on(&sv_no); ! ! sv_setpv(&sv_yes,Yes); ! SvNV(&sv_yes); ! SvREADONLY_on(&sv_yes); nrs = newSVpv("\n", 1); rs = SvREFCNT_inc(nrs); --- 78,94 ---- linestr = NEWSV(65,80); sv_upgrade(linestr,SVt_PVIV); ! if (!SvREADONLY(&sv_undef)) { ! SvREADONLY_on(&sv_undef); ! sv_setpv(&sv_no,No); ! SvNV(&sv_no); ! SvREADONLY_on(&sv_no); ! ! sv_setpv(&sv_yes,Yes); ! SvNV(&sv_yes); ! SvREADONLY_on(&sv_yes); ! } nrs = newSVpv("\n", 1); rs = SvREFCNT_inc(nrs); *************** *** 126,132 **** #endif #if defined(LOCAL_PATCH_COUNT) ! Ilocalpatches = local_patches; /* For possible -v */ #endif fdpid = newAV(); /* for remembering popen pids by fd */ --- 129,135 ---- #endif #if defined(LOCAL_PATCH_COUNT) ! localpatches = local_patches; /* For possible -v */ #endif fdpid = newAV(); /* for remembering popen pids by fd */ *************** *** 159,171 **** 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; ! } } if (sv_objcount) { /* --- 162,172 ---- LEAVE; FREETMPS; ! /* We must account for everything. First the syntax tree. */ ! if (main_root) { ! curpad = AvARRAY(comppad); ! op_free(main_root); ! main_root = 0; } if (sv_objcount) { /* *************** *** 205,218 **** --- 206,260 ---- /* 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); + sv_free_arenas(); + linestr = NULL; /* No SVs have survived, need to clean out */ + if (origfilename) + Safefree(origfilename); + nuke_stacks(); + hints = 0; /* Reset hints. Should hints be per-interpreter ? */ + DEBUG_P(debprofdump()); } *************** *** 254,259 **** --- 296,306 ---- 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 */ *************** *** 381,387 **** preambleav = newAV(); av_push(preambleav, newSVpv("use Config qw(myconfig config_vars)",0)); if (*++s != ':') { ! Sv = newSVpv("print myconfig(),'@INC: '.\"@INC\\n\"",0); } else { Sv = newSVpv("config_vars(qw(",0); --- 428,476 ---- preambleav = newAV(); av_push(preambleav, newSVpv("use Config qw(myconfig config_vars)",0)); if (*++s != ':') { ! 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(NOEMBED) || defined(MULTIPLICITY) ! strcpy(buf,"\" Compile-time options:"); ! # ifdef DEBUGGING ! strcat(buf," DEBUGGING"); ! # endif ! # ifdef NOEMBED ! strcat(buf," NOEMBED"); ! # endif ! # ifdef MULTIPLICITY ! strcat(buf," MULTIPLICITY"); ! # endif ! strcat(buf,"\\n\","); ! sv_catpv(Sv,buf); ! #endif ! #if defined(LOCAL_PATCH_COUNT) ! if (LOCAL_PATCH_COUNT > 0) ! { int i; ! sv_catpv(Sv,"print \" Locally applied patches:\\n\","); ! for (i = 1; i <= LOCAL_PATCH_COUNT; i++) { ! if (localpatches[i]) { ! sprintf(buf,"\" \\t%s\\n\",",localpatches[i]); ! sv_catpv(Sv,buf); ! } ! } ! } ! #endif ! sprintf(buf,"\" Built under %s\\n\",",OSNAME); ! sv_catpv(Sv,buf); ! #ifdef __DATE__ ! # ifdef __TIME__ ! sprintf(buf,"\" Compiled at %s %s\\n\"",__DATE__,__TIME__); ! # else ! sprintf(buf,"\" Compiled on %s\\n\"",__DATE__); ! # endif ! sv_catpv(Sv,buf); ! #endif ! sv_catpv(Sv,"; $\"=\"\\n \"; print \" \\@INC:\\n @INC\\n\""); } else { Sv = newSVpv("config_vars(qw(",0); *************** *** 437,448 **** compcv = (CV*)NEWSV(1104,0); sv_upgrade((SV *)compcv, SVt_PVCV); ! pad = newAV(); ! comppad = pad; av_push(comppad, Nullsv); curpad = AvARRAY(comppad); ! padname = newAV(); ! comppad_name = padname; comppad_name_fill = 0; min_intro_pending = 0; padix = 0; --- 526,535 ---- compcv = (CV*)NEWSV(1104,0); sv_upgrade((SV *)compcv, SVt_PVCV); ! comppad = newAV(); av_push(comppad, Nullsv); curpad = AvARRAY(comppad); ! comppad_name = newAV(); comppad_name_fill = 0; min_intro_pending = 0; padix = 0; *************** *** 453,458 **** --- 540,546 ---- 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 *************** *** 535,550 **** FREETMPS; return 1; } ! if (stack != mainstack) { dSP; ! SWITCHSTACK(stack, mainstack); } break; } if (!restartop) { DEBUG_x(dump_all()); ! DEBUG(fprintf(stderr,"\nEXECUTING...\n\n")); if (minus_c) { fprintf(stderr,"%s syntax OK\n", origfilename); --- 623,641 ---- FREETMPS; return 1; } ! if (curstack != mainstack) { dSP; ! SWITCHSTACK(curstack, mainstack); } break; } + DEBUG_r(fprintf(stderr, "%s $` $& $' support.\n", + sawampersand ? "Enabling" : "Omitting")); + if (!restartop) { DEBUG_x(dump_all()); ! DEBUG(fprintf(Perl_debug_log,"\nEXECUTING...\n\n")); if (minus_c) { fprintf(stderr,"%s syntax OK\n", origfilename); *************** *** 697,702 **** --- 788,794 ---- I32 retval; Sigjmp_buf oldtop; I32 oldscope; + static CV *DBcv; if (flags & G_DISCARD) { ENTER; *************** *** 717,722 **** --- 809,818 ---- if (flags & G_ARRAY) myop.op_flags |= OPf_LIST; + if (perldb && curstash != debstash + && (DBcv || (DBcv = GvCV(DBsub)))) /* to handle first BEGIN of -d */ + op->op_private |= OPpENTERSUB_DB; + if (flags & G_EVAL) { Copy(top_env, oldtop, 1, Sigjmp_buf); *************** *** 814,820 **** return retval; } ! /* Eval a string. */ I32 perl_eval_sv(sv, flags) --- 910,916 ---- return retval; } ! /* Eval a string. The G_EVAL flag is always assumed. */ I32 perl_eval_sv(sv, flags) *************** *** 843,851 **** 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); --- 939,950 ---- if (!(flags & G_NOARGS)) myop.op_flags = OPf_STACKED; myop.op_next = Nullop; + myop.op_type = OP_ENTEREVAL; myop.op_flags |= OPf_KNOW; + if (flags & G_KEEPERR) + myop.op_flags |= OPf_SPECIAL; if (flags & G_ARRAY) ! myop.op_flags |= OPf_LIST; Copy(top_env, oldtop, 1, Sigjmp_buf); *************** *** 890,896 **** if (op) runops(); retval = stack_sp - (stack_base + oldmark); ! if ((flags & G_EVAL) && !(flags & G_KEEPERR)) sv_setpv(GvSV(errgv),""); cleanup: --- 989,995 ---- if (op) runops(); retval = stack_sp - (stack_base + oldmark); ! if (!(flags & G_KEEPERR)) sv_setpv(GvSV(errgv),""); cleanup: *************** *** 987,995 **** 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"); --- 1086,1091 ---- *************** *** 1106,1116 **** } else { if (RsPARA(nrs)) { ! ors = savepvn("\n\n", 2); orslen = 2; } else ors = SvPV(nrs, orslen); } return s; case 'M': --- 1202,1213 ---- } else { if (RsPARA(nrs)) { ! ors = "\n\n"; orslen = 2; } else ors = SvPV(nrs, orslen); + ors = savepvn(ors, orslen); } return s; case 'M': *************** *** 1180,1225 **** 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); - #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 - #endif - fputs("\n\t+ suidperl security patch", stdout); fputs("\n\nCopyright 1987-1996, Larry Wall\n",stdout); #ifdef MSDOS fputs("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n", stdout); #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); #endif #ifdef atarist fputs("atariST series port, ++jrb bammi@cadence.com\n", stdout); --- 1277,1291 ---- printf("\nThis is perl, version %s",patchlevel); #endif fputs("\n\nCopyright 1987-1996, Larry Wall\n",stdout); + fputs("\n\t+ suidperl security patch", stdout); #ifdef MSDOS fputs("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n", stdout); #endif #ifdef OS2 fputs("OS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n" ! "Version 5 port Copyright (c) 1994-1996, Andreas Kaiser, Ilya Zakharevich\n", stdout); #endif #ifdef atarist fputs("atariST series port, ++jrb bammi@cadence.com\n", stdout); *************** *** 1287,1292 **** --- 1353,1367 ---- 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); *************** *** 1335,1344 **** #endif #ifdef VMS ! if (dosearch && !strpbrk(scriptname,":[ tokenbuf+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++; /* *************** *** 1725,1730 **** --- 1806,1812 ---- /* exec the real perl, substituting fd script for scriptname. */ /* (We pass script name as "subdir" of fd, which perl will grok.) */ rewind(rsfp); + lseek(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"); *************** *** 1759,1765 **** static void find_beginning() { ! register char *s; /* skip forward in input to the real script? */ --- 1841,1847 ---- static void find_beginning() { ! register char *s, *s2; /* skip forward in input to the real script? */ *************** *** 1767,1779 **** 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 */ doextract = FALSE; ! if (s = instr(s,"perl -")) { ! s += 6; ! /*SUPPRESS 530*/ ! while (s = moreswitches(s)) ; } if (cddir && chdir(cddir) < 0) croak("Can't chdir to %s",cddir); --- 1849,1865 ---- while (doextract) { if ((s = sv_gets(linestr, rsfp, 0)) == Nullch) croak("No Perl script found in input\n"); ! if (*s == '#' && s[1] == '!' && (s = instr(s,"perl"))) { ungetc('\n',rsfp); /* to keep line count right */ doextract = FALSE; ! 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); *************** *** 1816,1845 **** 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); ! stack_base = AvARRAY(stack); 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); --- 1902,1948 ---- static void init_stacks() { ! curstack = newAV(); ! mainstack = curstack; /* remember in case we switch stacks */ ! AvREAL_off(curstack); /* not a real array */ ! av_extend(curstack,127); ! stack_base = AvARRAY(curstack); stack_sp = stack_base; stack_max = stack_base + 127; ! /* Shouldn't these stacks be per-interpreter? */ ! 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; ! } cxstack_max = 8192 / sizeof(CONTEXT) - 2; /* Use most of 8K. */ New(50,cxstack,cxstack_max + 1,CONTEXT); *************** *** 1855,1860 **** --- 1958,1970 ---- } ) } + static void + nuke_stacks() + { + Safefree(cxstack); + Safefree(tmps_stack); + } + static FILE *tmpfp; /* moved outside init_lexer() because of UNICOS bug */ static void init_lexer() *************** *** 1898,1904 **** statname = NEWSV(66,0); /* last filename we did stat on */ ! osname = savepv(OSNAME); } static void --- 2008,2015 ---- statname = NEWSV(66,0); /* last filename we did stat on */ ! if (!osname) ! osname = savepv(OSNAME); } static void #~ Update NeXT support #~ Make HIDEMYMALLOC the default #~ Add home-grown calloc() to MYMALLOC #defines #~ Drop long long support under UTS #~ Add new distinct GV type #~ Add Plan9 support #~ Use variable BIN_SH to find shell #~ Allow redirection of output usually sent to stderr, so it can be #~ handled separately from normal output #~ Don't log memory allocations until we've got an interpreter set up #~ Don't doubly define DEBUGGING_MSTATS #~ Add globals and macros for improved signal handling, duplicate "my", #~ strict untie, and debugger updates #~ Rename some globals to avoid collisions with system headers diff -Pcr perl5_003/perl.h perl5_003_01/perl.h *** perl5_003/perl.h Mon Mar 25 01:05:06 1996 --- perl5_003_01/perl.h Sat Jul 27 09:42:41 1996 *************** *** 102,112 **** #endif #include #ifdef USE_NEXT_CTYPE #include ! #else #include ! #endif #ifdef I_LOCALE #include --- 102,119 ---- #endif #include + #ifdef USE_NEXT_CTYPE + + #if NX_CURRENT_COMPILER_RELEASE >= 400 + #include + #else /* NX_CURRENT_COMPILER_RELEASE < 400 */ #include ! #endif /* NX_CURRENT_COMPILER_RELEASE >= 400 */ ! ! #else /* !USE_NEXT_CTYPE */ #include ! #endif /* USE_NEXT_CTYPE */ #ifdef I_LOCALE #include *************** *** 136,149 **** proto.h instead. I guess. The patch had no explanation. */ #ifdef MYMALLOC ! # ifdef HIDEMYMALLOC # define malloc Mymalloc # define realloc Myremalloc # define free Myfree # endif # define safemalloc malloc # define saferealloc realloc # define safefree free #endif #define MEM_SIZE Size_t --- 143,158 ---- proto.h instead. I guess. The patch had no explanation. */ #ifdef MYMALLOC ! # ifndef DONT_HIDEMYMALLOC # define malloc Mymalloc # define realloc Myremalloc # define free Myfree + # define calloc Mycalloc # endif # define safemalloc malloc # define saferealloc realloc # define safefree free + # define safecalloc calloc #endif #define MEM_SIZE Size_t *************** *** 493,499 **** # define SLOPPYDIVIDE #endif ! #if defined(cray) || defined(convex) || defined (uts) || BYTEORDER > 0xffff # define HAS_QUAD #endif --- 502,508 ---- # define SLOPPYDIVIDE #endif ! #if defined(cray) || defined(convex) || BYTEORDER > 0xffff # define HAS_QUAD #endif *************** *** 505,511 **** # ifdef cray # define Quad_t int # else ! # if defined(convex) || defined (uts) # define Quad_t long long # else # define Quad_t long --- 514,520 ---- # ifdef cray # define Quad_t int # else ! # if defined(convex) # define Quad_t long long # else # define Quad_t long *************** *** 542,548 **** typedef struct cv CV; typedef struct regexp REGEXP; typedef struct gp GP; ! typedef struct sv GV; typedef struct io IO; typedef struct context CONTEXT; typedef struct block BLOCK; --- 551,557 ---- typedef struct cv CV; typedef struct regexp REGEXP; typedef struct gp GP; ! typedef struct gv GV; typedef struct io IO; typedef struct context CONTEXT; typedef struct block BLOCK; *************** *** 581,590 **** # if defined(VMS) # include "vmsish.h" # else ! # include "unixish.h" # endif #endif #ifndef HAS_PAUSE #define pause() sleep((32767<<16)+32767) #endif --- 590,607 ---- # if defined(VMS) # include "vmsish.h" # else ! # if defined(PLAN9) ! # include "./plan9/plan9ish.h" ! # else ! # include "unixish.h" ! # endif # endif #endif + #ifndef SH_PATH /* May be a variable. */ + # define SH_PATH BIN_SH + #endif + #ifndef HAS_PAUSE #define pause() sleep((32767<<16)+32767) #endif *************** *** 730,735 **** --- 747,755 ---- #endif #ifdef DEBUGGING + #ifndef Perl_debug_log + #define Perl_debug_log stderr + #endif #define YYDEBUG 1 #define DEB(a) a #define DEBUG(a) if (debug) a *************** *** 740,746 **** #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_f(a) if (debug & 256) a #define DEBUG_r(a) if (debug & 512) a #define DEBUG_x(a) if (debug & 1024) a --- 760,766 ---- #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 (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 *************** *** 854,860 **** # define register # endif # ifdef MYMALLOC ! # define DEBUGGING_MSTATS # endif # define PAD_SV(po) pad_sv(po) #else --- 874,882 ---- # define register # endif # ifdef MYMALLOC ! # ifndef DEBUGGING_MSTATS ! # define DEBUGGING_MSTATS ! # endif # endif # define PAD_SV(po) pad_sv(po) #else *************** *** 867,875 **** /* global state */ EXT PerlInterpreter * curinterp; /* currently running interpreter */ ! #ifndef VMS /* VMS doesn't use environ array */ extern char ** environ; /* environment variables supplied via exec */ ! #endif EXT int uid; /* current real user id */ EXT int euid; /* current effective user id */ EXT int gid; /* current real group id */ --- 889,906 ---- /* global state */ EXT PerlInterpreter * curinterp; /* currently running interpreter */ ! /* VMS doesn't use environ array and NeXT has problems with crt0.o globals */ ! #if !defined(VMS) && !(defined(NeXT) && defined(__DYNAMIC__)) extern char ** environ; /* environment variables supplied via exec */ ! #else ! # if defined(NeXT) && defined(__DYNAMIC__) ! ! # include ! 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 */ *************** *** 989,997 **** --- 1020,1032 ---- #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 #ifdef DOINIT *************** *** 1148,1153 **** --- 1183,1189 ---- 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,1179 **** --- 1210,1216 ---- #define HINT_BLOCK_SCOPE 0x00000100 #define HINT_STRICT_SUBS 0x00000200 #define HINT_STRICT_VARS 0x00000400 + #define HINT_STRICT_UNTIE 0x00000800 /**************************************************************************/ /* This regexp stuff is global since it always happens within 1 expr eval */ *************** *** 1313,1320 **** 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 */ /* memory management */ IEXT SV ** Itmps_stack; --- 1350,1356 ---- IEXT SV * Icurstname; /* name of current package */ IEXT AV * Ibeginav; /* names of BEGIN subroutines */ IEXT AV * Iendav; /* names of END subroutines */ ! IEXT HV * Istrtab; /* shared string table */ /* memory management */ IEXT SV ** Itmps_stack; *************** *** 1360,1365 **** --- 1396,1402 ---- /* 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); *************** *** 1368,1374 **** IEXT I32 Irunlevel; /* stack stuff */ ! IEXT AV * Istack; /* 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 */ --- 1405,1411 ---- IEXT I32 Irunlevel; /* stack stuff */ ! 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 */ *************** *** 1458,1465 **** 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_pack = {0, 0, 0, magic_wipepack, 0}; EXT MGVTBL vtbl_packelem = {magic_getpack, --- 1495,1504 ---- 0, magic_clearenv, 0}; EXT MGVTBL vtbl_sig = {0, 0, 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, #~ Remove old copy before generating new one #~ Add symbol for home-grown calloc diff -Pcr perl5_003/perl_exp.SH perl5_003_01/perl_exp.SH *** perl5_003/perl_exp.SH Mon Mar 25 01:05:08 1996 --- perl5_003_01/perl_exp.SH Thu Jul 11 12:25:53 1996 *************** *** 14,19 **** --- 14,20 ---- echo "Extracting perl.exp" + rm -f perl.exp echo "#!" > perl.exp sed -n '/^[A-Za-z]/ s/^/Perl_/p' global.sym >> perl.exp *************** *** 42,47 **** --- 43,49 ---- perl_call_method perl_call_sv perl_requirepv + safecalloc safemalloc saferealloc safefree #~ Update to reflect changes in perly.y #~ Use safefree instead of Safefree to free memory allocated by safemalloc #~ Allow redirection of debug messages diff -Pcr perl5_003/perly.c perl5_003_01/perly.c *** perl5_003/perly.c Wed Feb 28 17:38:38 1996 --- perl5_003_01/perly.c Sun Jul 7 10:04:15 1996 *************** *** 37,43 **** 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, --- 37,43 ---- 6, 6, 4, 4, 0, 2, 7, 7, 5, 5, 8, 7, 10, 3, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 4, 3, 5, 5, 0, 1, ! 0, 3, 2, 6, 3, 3, 1, 2, 3, 1, 3, 5, 6, 3, 5, 2, 4, 4, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 2, 2, 2, 2, 2, 2, *************** *** 75,89 **** 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, }; short yydgoto[] = { 1, 9, 10, 83, 17, 86, 3, 11, 12, 66, 195, --- 75,89 ---- 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 70, 0, 0, 0, 0, 0, 0, 0, 120, 0, 48, ! 47, 0, 3, 0, 141, 0, 68, 101, 0, 29, 0, 30, 0, 0, 0, 23, 0, 24, 0, 0, 0, 140, 149, 67, 0, 125, 0, 127, 0, 99, 0, 0, 0, 0, 0, 0, 0, 107, 0, 105, ! 0, 116, 0, 121, 54, 65, 0, 0, 0, 0, ! 19, 0, 0, 0, 0, 0, 62, 126, 128, 115, ! 0, 113, 0, 0, 106, 0, 111, 117, 103, 142, ! 27, 28, 21, 0, 22, 0, 32, 0, 114, 112, ! 63, 0, 0, 31, 0, 0, 20, 33, }; short yydgoto[] = { 1, 9, 10, 83, 17, 86, 3, 11, 12, 66, 195, *************** *** 92,1104 **** 2, 14, 15, 16, }; 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, }; short yyrindex[] = { 0, ! 0, 0, 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 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, 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, 0, 0, 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, 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, }; 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, }; ! #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, ! 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, 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, ! 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, 0, 38, 0, ! 39, 40, 41, 0, 0, 0, 0, 42, 43, 44, ! 45, 46, 0, 0, 48, 49, 168, 150, 0, 0, ! 0, 50, 0, 82, 0, 53, 82, 54, 55, 0, ! 0, 24, 25, 26, 27, 28, 0, 29, 30, 31, ! 82, 82, 0, 32, 0, 82, 0, 0, 150, 0, ! 0, 0, 0, 0, 38, 0, 39, 40, 41, 0, ! 0, 0, 0, 42, 43, 44, 45, 46, 0, 0, ! 48, 49, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 146, 0, 146, 0, 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, 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, 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, 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, 0, 0, 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, 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, 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, }; 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, ! 269, -1, -1, 272, 273, 274, 275, -1, -1, -1, ! 123, 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, ! -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, -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, ! -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, 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, ! -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, -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, -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, -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, ! -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, -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, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, 41, -1, -1, 44, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, 93, 58, 59, -1, -1, -1, 63, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! 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, 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, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! 143, -1, -1, -1, -1, -1, -1, -1, 151, 152, ! 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, ! 163, 164, -1, -1, -1, -1, -1, -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, --- 92,1098 ---- 2, 14, 15, 16, }; short yysindex[] = { 0, ! 0, 0, 303, 0, 0, 0, -53, 0, 0, 0, ! 0, 0, 607, 0, 0, 0, -111, -242, -32, 0, ! -216, 0, 0, 0, 149, 149, 0, 8, 0, 2109, ! 0, 0, -15, -8, 4, 6, 32, 2109, 13, 20, ! 57, 149, 994, 2109, 1057, -206, 149, 2109, 938, 1291, ! 2109, 2109, 2109, 2109, 2109, 1347, 0, 2109, 2109, 1403, ! 149, 149, 149, 149, -203, 0, 68, 664, 491, -67, ! -52, 0, 0, -21, 73, 65, 0, 7, 0, -135, ! 0, -126, 0, 0, 0, 0, 0, 2109, 92, 2109, ! 491, 7, -135, 2109, 7, 2109, 7, 2109, 7, 2109, ! 7, 1466, 101, 491, 112, 1700, 938, 0, 102, 0, ! 1228, -22, 1228, 39, -58, 2109, 0, 68, 0, 68, ! -67, 0, 2109, 0, 1228, 472, 472, 472, -88, -88, ! 78, -10, 472, 472, 0, -85, 0, 0, 0, 0, ! 7, 0, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, ! 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, 2109, ! 2109, 2109, 2109, 2109, 0, 0, -29, 2109, 2109, 2109, ! 2109, 2109, 2109, 1756, 0, 0, 0, -46, 2109, 391, ! 0, 2109, -25, 2109, 7, -214, 129, -203, -5, -203, ! 1, -167, 9, -167, 117, 52, 0, 2109, 0, 0, ! 23, 60, 132, 2109, 1812, 1875, 0, 53, 0, 68, ! 2109, 86, 0, 0, 491, -214, -214, -214, -214, -147, ! 0, -54, 382, 1228, 1090, 771, 115, 491, 2942, 1523, ! 314, 1554, 392, 677, 472, 472, 2109, 0, 2109, 0, ! 141, 89, -42, 99, 46, 114, 64, 0, 26, 0, ! 0, 124, 0, 143, 0, 2109, 0, 0, 7, 0, ! 7, 0, 7, 7, 146, 0, 7, 0, 2109, 7, ! 35, 0, 0, 0, 37, 0, 49, 0, 55, 0, ! 130, 2109, 63, 2109, 67, 166, 2109, 0, 66, 0, ! 71, 0, 74, 0, 0, 0, 1170, -203, -203, -167, ! 0, 2109, -167, 131, -203, 7, 0, 0, 0, 0, ! 185, 0, 1119, 76, 0, 161, 0, 0, 0, 0, ! 0, 0, 0, 58, 0, 1466, 0, -203, 0, 0, ! 0, 7, 162, 0, -167, 7, 0, 0, }; short yyrindex[] = { 0, ! 0, 0, 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 2241, 1964, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 2857, 2901, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 107, 0, 360, -1, 62, 3027, ! 3078, 0, 0, 2286, 2020, 0, 0, 0, 0, -12, ! 0, 0, 0, 0, 0, 0, 0, 2415, 0, 0, ! 1251, 0, 82, 173, 0, 0, 0, 0, 0, 0, ! 0, 157, 0, 1661, 0, 0, 178, 0, 2150, 0, ! 3927, 3027, 3958, 0, 0, 2415, 0, 2537, 454, 2581, ! 548, 0, 0, 0, 3989, 3384, 3425, 3461, 3122, 3163, ! 2636, 0, 3497, 3533, 0, 0, 0, 0, 0, 0, ! 0, 0, 2680, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 163, 882, ! 0, 178, 0, 2415, 0, 2, 0, 107, 0, 107, ! 0, 175, 0, 175, 0, 165, 0, 0, 0, 0, ! 0, 180, 0, 0, 0, 0, 0, 0, 0, 2723, ! 0, 2985, 0, 0, 2785, 11, 14, 33, 59, 833, ! 0, 0, -30, 4020, 4036, 3817, 3850, 3275, 0, 1611, ! 4179, 4114, 4098, 3894, 3569, 3646, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 168, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 178, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 107, 107, 175, ! 0, 0, 175, 0, 107, 0, 0, 0, 0, 0, ! 0, 0, 2462, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 190, 0, 107, 0, 0, ! 0, 0, 0, 0, 175, 0, 0, 0, }; short yygindex[] = { 0, ! 0, 0, 0, 148, -13, 106, 0, 0, 0, -91, ! -184, 452, -11, 4373, 886, 0, 0, 0, 0, 0, ! 234, -62, -173, 460, -20, 0, 0, 174, 0, -131, 0, 0, 0, 0, }; ! #define YYTABLESIZE 4657 short yytable[] = { 65, ! 208, 68, 168, 79, 283, 20, 61, 213, 254, 268, ! 80, 23, 250, 80, 80, 255, 289, 206, 256, 95, ! 97, 99, 101, 170, 94, 181, 81, 80, 80, 110, ! 212, 96, 80, 115, 150, 261, 124, 157, 172, 13, ! 82, 263, 38, 98, 132, 100, 49, 90, 136, 267, ! 116, 16, 105, 209, 17, 169, 260, 13, 262, 106, ! 38, 239, 80, 272, 176, 168, 294, 61, 170, 16, ! 171, 102, 17, 14, 141, 306, 23, 307, 184, 148, ! 149, 188, 186, 190, 189, 192, 191, 194, 193, 308, ! 196, 14, 270, 237, 201, 309, 107, 150, 332, 15, ! 169, 173, 60, 273, 291, 60, 25, 23, 264, 265, ! 49, 143, 174, 316, 23, 323, 252, 15, 325, 60, ! 60, 257, 293, 175, 177, 314, 23, 214, 23, 23, ! 179, 182, 216, 217, 218, 219, 220, 221, 222, 25, ! 198, 205, 25, 25, 25, 78, 25, 149, 25, 25, ! 337, 25, 199, 18, 60, 21, 242, 243, 244, 245, ! 246, 247, 249, 207, 251, 25, 321, 322, 211, 259, ! 25, 258, 274, 327, 18, 269, 282, 280, 92, 93, ! 287, 288, 295, 296, 61, 302, 271, 312, 180, 326, ! 317, 290, 275, 277, 279, 318, 334, 25, 319, 281, ! 330, 331, 336, 19, 49, 168, 292, 18, 148, 149, ! 18, 18, 18, 37, 18, 35, 18, 18, 147, 18, ! 148, 145, 310, 13, 167, 285, 37, 286, 238, 25, ! 35, 25, 25, 18, 333, 148, 149, 150, 18, 148, ! 149, 80, 80, 80, 80, 298, 76, 299, 304, 300, ! 301, 148, 149, 303, 0, 151, 305, 186, 315, 152, ! 153, 154, 155, 80, 80, 18, 185, 80, 2, 0, ! 311, 23, 156, 158, 159, 160, 161, 329, 162, 163, ! 0, 0, 164, 148, 149, 165, 166, 167, 148, 149, ! 324, 0, 328, 0, 148, 149, 0, 18, 0, 18, ! 18, 39, 148, 149, 39, 39, 39, 0, 39, 0, ! 39, 39, 0, 39, 68, 0, 148, 149, 335, 148, ! 149, 0, 338, 144, 145, 146, 147, 39, 148, 149, ! 148, 149, 39, 60, 60, 60, 60, 0, 0, 148, ! 149, 0, 148, 149, 0, 148, 149, 0, 148, 149, ! 0, 148, 149, 148, 149, 60, 60, 148, 149, 39, ! 148, 149, 25, 25, 25, 25, 25, 25, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, ! 25, 25, 148, 149, 0, 25, 25, 0, 25, 25, ! 25, 39, 148, 149, 39, 25, 25, 25, 25, 25, ! 57, 154, 25, 25, 168, 84, 0, 148, 149, 25, ! 85, 0, 0, 25, 0, 25, 25, 0, 57, 163, ! 0, 0, 164, 148, 149, 165, 166, 167, 0, 0, ! 18, 18, 18, 18, 18, 18, 150, 18, 18, 18, ! 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, ! 0, 0, 57, 18, 18, 0, 18, 18, 18, 148, ! 149, 0, 0, 18, 18, 18, 18, 18, 0, 0, ! 18, 18, 168, 0, 0, 0, 0, 18, 148, 149, ! 0, 18, 168, 18, 18, 89, 156, 0, 0, 156, ! 156, 156, 0, 156, 143, 156, 156, 143, 156, 118, ! 120, 108, 0, 0, 150, 0, 117, 0, 123, 0, ! 0, 143, 143, 0, 150, 253, 143, 156, 0, 0, ! 137, 138, 139, 140, 39, 39, 39, 39, 39, 39, ! 0, 39, 39, 39, 0, 0, 0, 39, 0, 120, ! 39, 39, 39, 39, 143, 0, 143, 39, 39, 0, ! 39, 39, 39, 157, 0, 0, 0, 39, 39, 39, ! 39, 39, 168, 0, 39, 39, 204, 120, 4, 5, ! 6, 39, 7, 8, 210, 39, 143, 39, 39, 156, ! 157, 168, 0, 157, 157, 157, 0, 157, 102, 157, ! 157, 102, 157, 0, 150, 0, 0, 0, 152, 153, ! 154, 155, 0, 0, 0, 102, 102, 0, 0, 0, ! 102, 157, 0, 150, 160, 161, 0, 162, 163, 0, 0, 164, 0, 0, 165, 166, 167, 0, 0, 0, ! 120, 57, 57, 57, 57, 120, 0, 0, 0, 51, ! 102, 0, 61, 63, 47, 0, 56, 0, 64, 59, ! 0, 58, 0, 57, 57, 0, 4, 5, 6, 0, ! 7, 8, 0, 0, 0, 57, 152, 153, 154, 155, ! 62, 0, 0, 157, 0, 0, 152, 153, 154, 155, ! 158, 159, 160, 161, 0, 162, 163, 0, 0, 164, ! 0, 0, 165, 166, 167, 162, 163, 60, 0, 164, ! 0, 0, 165, 166, 167, 0, 0, 0, 0, 0, ! 156, 156, 156, 156, 156, 0, 156, 156, 156, 0, ! 0, 0, 156, 0, 0, 143, 143, 143, 143, 23, ! 0, 0, 52, 156, 143, 156, 156, 156, 143, 143, ! 143, 143, 156, 156, 156, 156, 156, 143, 143, 156, ! 156, 143, 143, 143, 143, 143, 156, 143, 143, 0, ! 156, 143, 156, 156, 143, 143, 143, 168, 0, 0, ! 0, 151, 0, 0, 0, 152, 153, 154, 155, 164, ! 0, 0, 165, 166, 167, 0, 0, 0, 156, 158, ! 159, 160, 161, 0, 162, 163, 0, 0, 164, 150, ! 0, 165, 166, 167, 157, 157, 157, 157, 157, 0, ! 157, 157, 157, 0, 0, 0, 157, 0, 0, 102, ! 102, 102, 102, 0, 0, 0, 0, 157, 102, 157, ! 157, 157, 102, 102, 102, 102, 157, 157, 157, 157, ! 157, 102, 102, 157, 157, 102, 102, 102, 102, 102, ! 157, 102, 102, 0, 157, 102, 157, 157, 102, 102, ! 102, 168, 22, 24, 25, 26, 27, 28, 0, 29, ! 30, 31, 0, 56, 0, 32, 56, 0, 33, 34, ! 35, 36, 0, 0, 0, 37, 38, 0, 39, 40, ! 41, 56, 0, 150, 0, 42, 43, 44, 45, 46, ! 0, 0, 48, 49, 0, 0, 0, 0, 0, 50, ! 87, 87, 0, 53, 39, 54, 55, 39, 39, 39, ! 0, 39, 103, 39, 39, 56, 39, 87, 112, 0, ! 0, 0, 87, 0, 121, 144, 145, 146, 147, 0, ! 39, 0, 0, 0, 0, 39, 87, 87, 87, 87, ! 0, 0, 0, 0, 0, 0, 0, 148, 149, 0, ! 0, 0, 0, 154, 155, 0, 0, 0, 0, 0, ! 51, 0, 39, 61, 63, 47, 0, 56, 0, 64, ! 59, 163, 58, 0, 164, 0, 0, 165, 166, 167, ! 0, 0, 121, 0, 0, 0, 0, 0, 0, 0, ! 0, 62, 0, 0, 39, 0, 0, 39, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 51, 0, 60, 61, ! 63, 47, 0, 56, 0, 64, 59, 0, 58, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 240, 0, 0, 0, 0, 62, 0, 0, ! 23, 0, 0, 52, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 163, 0, 0, 164, 0, ! 0, 165, 166, 167, 60, 0, 0, 0, 0, 51, ! 0, 0, 61, 63, 47, 0, 56, 0, 64, 59, ! 0, 58, 0, 0, 56, 56, 56, 56, 0, 0, ! 0, 0, 0, 0, 0, 114, 23, 0, 0, 52, ! 62, 0, 0, 0, 0, 0, 56, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 39, 39, 39, ! 39, 39, 39, 0, 39, 39, 39, 60, 0, 0, ! 39, 0, 0, 39, 39, 39, 39, 0, 0, 0, ! 39, 39, 0, 39, 39, 39, 0, 0, 0, 0, ! 39, 39, 39, 39, 39, 0, 0, 39, 39, 0, ! 168, 157, 52, 0, 39, 0, 0, 0, 39, 0, ! 39, 39, 0, 0, 119, 25, 26, 27, 28, 85, ! 29, 30, 31, 0, 0, 0, 32, 0, 0, 168, ! 320, 0, 150, 0, 0, 0, 0, 38, 0, 39, 40, 41, 0, 0, 0, 0, 42, 43, 44, 45, ! 46, 0, 157, 48, 49, 0, 0, 0, 0, 0, ! 50, 150, 0, 0, 53, 0, 54, 55, 0, 0, ! 109, 25, 26, 27, 28, 0, 29, 30, 31, 0, ! 168, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 39, 40, 41, 0, 0, 0, 0, 42, 43, 44, 45, 46, 0, 0, 48, ! 49, 135, 150, 0, 135, 0, 50, 0, 0, 0, ! 53, 0, 54, 55, 0, 0, 0, 0, 135, 135, ! 0, 0, 0, 24, 25, 26, 27, 28, 168, 29, ! 30, 31, 0, 51, 0, 32, 61, 63, 47, 0, ! 56, 0, 64, 59, 0, 58, 38, 0, 39, 40, ! 41, 0, 0, 135, 0, 42, 43, 44, 45, 46, ! 150, 0, 48, 49, 62, 0, 0, 0, 0, 50, ! 0, 0, 0, 53, 0, 54, 55, 0, 0, 0, ! 0, 0, 0, 0, 152, 0, 154, 155, 0, 51, ! 0, 60, 61, 63, 47, 0, 56, 131, 64, 59, ! 0, 58, 0, 162, 163, 0, 0, 164, 0, 151, ! 165, 166, 167, 152, 153, 154, 155, 0, 0, 0, ! 62, 0, 0, 23, 0, 0, 52, 158, 159, 160, ! 161, 0, 162, 163, 0, 0, 164, 0, 0, 165, ! 166, 167, 0, 0, 0, 51, 0, 60, 61, 63, ! 47, 0, 56, 0, 64, 59, 0, 58, 0, 0, ! 151, 0, 0, 0, 152, 153, 154, 155, 0, 0, ! 0, 0, 0, 0, 0, 0, 62, 156, 158, 159, ! 160, 161, 52, 162, 163, 0, 0, 164, 0, 0, ! 165, 166, 167, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 60, 0, 135, 0, 0, 51, 0, ! 0, 61, 63, 47, 0, 56, 0, 64, 59, 0, ! 58, 0, 0, 0, 154, 155, 0, 0, 0, 0, ! 0, 0, 135, 135, 135, 135, 0, 0, 52, 62, ! 0, 162, 163, 0, 0, 164, 0, 0, 165, 166, ! 167, 0, 0, 0, 135, 135, 0, 24, 25, 26, ! 27, 28, 0, 29, 30, 31, 60, 0, 0, 32, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 39, 40, 41, 0, 0, 0, 0, 42, 43, 44, 45, 46, 0, 0, 48, 49, 0, 0, ! 0, 52, 0, 50, 0, 0, 0, 53, 0, 54, 55, 0, 0, 24, 25, 26, 27, 28, 0, 29, ! 30, 31, 0, 168, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 39, 40, 41, 0, 0, 0, 0, 42, 43, 44, 45, 46, ! 0, 0, 48, 49, 168, 150, 0, 0, 0, 50, ! 0, 82, 0, 53, 82, 54, 55, 0, 0, 24, ! 25, 26, 27, 28, 0, 29, 30, 31, 82, 82, ! 0, 32, 0, 82, 0, 0, 150, 0, 0, 0, ! 0, 0, 38, 0, 39, 40, 41, 0, 0, 0, ! 0, 42, 43, 44, 45, 46, 0, 0, 48, 49, ! 0, 130, 0, 82, 130, 50, 0, 0, 0, 53, ! 0, 54, 55, 0, 0, 0, 0, 0, 130, 130, ! 0, 22, 24, 25, 26, 27, 28, 0, 29, 30, ! 31, 0, 51, 0, 32, 61, 63, 47, 0, 56, ! 200, 64, 59, 0, 58, 38, 0, 39, 40, 41, ! 0, 0, 0, 130, 42, 43, 44, 45, 46, 0, ! 0, 48, 49, 62, 0, 0, 0, 0, 50, 0, ! 0, 0, 53, 0, 54, 55, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, ! 60, 61, 63, 47, 0, 56, 248, 64, 59, 0, ! 58, 0, 0, 0, 0, 0, 0, 152, 153, 154, ! 155, 0, 0, 0, 0, 0, 0, 0, 0, 62, ! 0, 0, 159, 160, 161, 52, 162, 163, 0, 0, ! 164, 0, 0, 165, 166, 167, 0, 0, 152, 153, ! 154, 155, 0, 0, 51, 0, 60, 61, 63, 47, ! 0, 56, 276, 64, 59, 161, 58, 162, 163, 0, ! 0, 164, 0, 0, 165, 166, 167, 0, 0, 0, ! 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, ! 0, 52, 82, 82, 82, 82, 0, 0, 0, 0, ! 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 60, 0, 82, 82, 0, 51, 82, 82, ! 61, 63, 47, 0, 56, 278, 64, 59, 0, 58, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 130, 130, 130, 130, 0, 52, 62, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 130, 130, 24, 25, 26, 27, ! 28, 0, 29, 30, 31, 60, 0, 0, 32, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, ! 0, 39, 40, 41, 0, 0, 0, 0, 42, 43, ! 44, 45, 46, 0, 0, 48, 49, 0, 0, 0, ! 52, 0, 50, 0, 136, 0, 53, 136, 54, 55, ! 0, 0, 24, 25, 26, 27, 28, 0, 29, 30, ! 31, 136, 136, 0, 32, 0, 136, 0, 0, 0, ! 0, 0, 0, 0, 0, 38, 0, 39, 40, 41, ! 0, 0, 0, 0, 42, 43, 44, 45, 46, 0, ! 0, 48, 49, 0, 136, 0, 136, 0, 50, 0, ! 119, 0, 53, 119, 54, 55, 0, 0, 24, 25, ! 26, 27, 28, 0, 29, 30, 31, 119, 119, 0, ! 32, 0, 119, 0, 0, 0, 136, 0, 0, 0, ! 0, 38, 0, 39, 40, 41, 0, 0, 0, 0, ! 42, 43, 44, 45, 46, 0, 0, 48, 49, 0, ! 119, 0, 119, 0, 50, 0, 0, 0, 53, 0, ! 54, 55, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 24, 25, 26, 27, 28, 0, 29, 30, 31, ! 0, 51, 119, 32, 61, 63, 47, 0, 56, 0, ! 64, 59, 0, 58, 38, 0, 39, 40, 41, 0, ! 0, 0, 0, 42, 43, 44, 45, 46, 0, 0, ! 48, 49, 62, 0, 0, 0, 0, 50, 0, 0, ! 0, 53, 0, 54, 55, 0, 0, 0, 0, 0, ! 143, 0, 0, 143, 0, 0, 0, 0, 0, 60, ! 0, 0, 0, 0, 0, 0, 0, 143, 143, 0, ! 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 52, 136, 136, 136, 136, 0, ! 143, 0, 143, 0, 136, 0, 0, 0, 136, 136, ! 136, 136, 0, 0, 0, 0, 0, 136, 136, 0, ! 0, 136, 136, 136, 136, 136, 0, 136, 136, 0, ! 0, 136, 143, 0, 136, 136, 136, 0, 0, 0, ! 0, 129, 0, 0, 129, 0, 0, 0, 0, 0, ! 0, 119, 119, 119, 119, 0, 0, 0, 129, 129, ! 119, 0, 0, 129, 119, 119, 119, 119, 0, 0, ! 0, 0, 0, 119, 119, 0, 0, 119, 119, 119, ! 119, 119, 0, 119, 119, 0, 104, 119, 0, 104, ! 119, 119, 119, 129, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 104, 104, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 129, 0, 24, 25, 26, 27, 28, + 0, 29, 30, 31, 0, 0, 104, 32, 104, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, + 39, 40, 41, 0, 0, 0, 0, 42, 43, 44, + 45, 46, 0, 0, 48, 49, 0, 0, 0, 0, + 0, 50, 0, 0, 0, 53, 0, 54, 55, 0, + 0, 143, 143, 143, 143, 0, 0, 0, 0, 0, + 143, 0, 0, 0, 143, 143, 143, 143, 0, 0, + 0, 0, 0, 143, 143, 0, 0, 143, 143, 143, + 143, 143, 0, 143, 143, 145, 0, 143, 145, 0, + 143, 143, 143, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 145, 145, 0, 0, 0, 145, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 83, 0, 0, 83, 0, 145, 0, 0, + 0, 0, 129, 129, 129, 129, 0, 0, 0, 83, + 83, 129, 0, 0, 0, 129, 129, 129, 129, 0, + 0, 0, 0, 0, 129, 129, 0, 145, 129, 129, + 129, 129, 129, 0, 129, 129, 0, 0, 129, 0, + 0, 129, 129, 129, 83, 0, 0, 104, 104, 104, + 104, 0, 0, 0, 0, 0, 104, 0, 0, 0, + 104, 104, 104, 104, 0, 0, 0, 131, 0, 104, + 104, 0, 0, 104, 104, 104, 104, 104, 0, 104, + 104, 0, 0, 104, 131, 131, 104, 104, 104, 131, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 146, 0, 0, 0, 0, 0, 131, 0, 131, + 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, + 0, 0, 0, 146, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 146, 0, 146, 0, 0, 96, 0, 0, 96, 0, 0, 0, 0, 0, 0, 145, 145, 145, 145, ! 0, 0, 0, 96, 96, 145, 0, 0, 96, 145, ! 145, 145, 145, 146, 0, 0, 0, 0, 145, 145, 0, 0, 145, 145, 145, 145, 145, 0, 145, 145, ! 58, 0, 145, 58, 0, 145, 145, 145, 96, 0, ! 0, 0, 0, 83, 83, 83, 83, 58, 58, 0, ! 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 83, 83, 0, 96, 83, ! 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, ! 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, ! 61, 61, 0, 0, 0, 61, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 58, 0, 0, 0, 0, 0, 131, 131, ! 131, 131, 0, 61, 0, 61, 0, 131, 0, 0, ! 0, 131, 131, 131, 131, 59, 0, 0, 59, 0, ! 131, 131, 0, 0, 131, 131, 131, 131, 131, 0, ! 131, 131, 59, 59, 131, 61, 0, 131, 131, 131, ! 0, 0, 146, 146, 146, 146, 0, 0, 0, 0, ! 0, 146, 0, 0, 0, 146, 146, 146, 146, 0, ! 0, 0, 0, 0, 146, 146, 0, 59, 146, 146, ! 146, 146, 146, 0, 146, 146, 0, 0, 146, 0, ! 0, 146, 146, 146, 0, 0, 0, 145, 0, 0, ! 145, 0, 0, 0, 0, 0, 0, 96, 96, 96, ! 96, 0, 0, 0, 145, 145, 96, 0, 0, 145, ! 96, 96, 96, 96, 0, 0, 0, 0, 0, 96, ! 96, 0, 0, 96, 96, 96, 96, 96, 0, 96, ! 96, 132, 0, 96, 132, 0, 96, 96, 96, 145, ! 0, 58, 58, 58, 58, 0, 0, 0, 132, 132, ! 58, 0, 0, 132, 58, 58, 58, 58, 0, 0, ! 0, 0, 0, 58, 58, 0, 0, 58, 58, 58, ! 58, 58, 0, 58, 58, 0, 0, 58, 0, 0, ! 58, 58, 58, 132, 61, 61, 61, 61, 0, 284, ! 0, 0, 0, 61, 157, 0, 0, 61, 61, 61, ! 61, 0, 0, 0, 0, 0, 61, 61, 0, 0, ! 61, 61, 61, 61, 61, 95, 61, 61, 95, 0, ! 61, 0, 168, 61, 61, 61, 0, 0, 0, 0, ! 0, 0, 95, 95, 0, 0, 0, 95, 0, 0, ! 0, 0, 0, 0, 0, 0, 59, 59, 59, 59, ! 0, 0, 0, 0, 150, 0, 0, 102, 0, 0, ! 102, 0, 0, 0, 0, 0, 0, 95, 59, 59, ! 0, 0, 0, 0, 102, 102, 0, 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 109, 102, ! 0, 109, 0, 0, 0, 0, 0, 0, 145, 145, ! 145, 145, 0, 0, 0, 109, 109, 145, 0, 0, ! 109, 145, 145, 145, 145, 0, 0, 0, 0, 0, ! 145, 145, 0, 0, 145, 145, 145, 145, 145, 0, ! 145, 145, 92, 0, 145, 92, 0, 145, 145, 145, ! 109, 0, 132, 132, 132, 132, 0, 0, 0, 92, ! 92, 132, 0, 0, 92, 132, 132, 132, 132, 0, ! 0, 0, 0, 0, 132, 132, 0, 0, 132, 132, ! 132, 132, 132, 93, 132, 132, 93, 0, 132, 0, ! 0, 132, 132, 132, 92, 0, 0, 0, 0, 0, ! 93, 93, 151, 0, 0, 93, 152, 153, 154, 155, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, ! 158, 159, 160, 161, 0, 162, 163, 0, 0, 164, ! 0, 0, 165, 166, 167, 93, 95, 95, 95, 95, ! 0, 0, 0, 0, 0, 95, 0, 0, 0, 95, ! 95, 95, 95, 0, 0, 0, 0, 0, 95, 95, ! 0, 0, 95, 95, 95, 95, 95, 0, 95, 95, ! 0, 0, 95, 0, 0, 95, 95, 95, 102, 102, ! 102, 102, 0, 0, 0, 0, 0, 102, 0, 0, ! 0, 102, 102, 102, 102, 71, 0, 0, 71, 0, ! 102, 102, 0, 0, 102, 102, 102, 102, 102, 0, ! 102, 102, 71, 71, 102, 0, 0, 102, 102, 102, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, ! 109, 109, 109, 0, 0, 0, 0, 0, 109, 0, ! 0, 0, 109, 109, 109, 109, 0, 71, 0, 0, ! 0, 109, 109, 0, 0, 109, 109, 109, 109, 109, ! 0, 109, 109, 0, 0, 109, 0, 0, 109, 109, ! 109, 0, 0, 92, 92, 92, 92, 0, 0, 0, ! 0, 0, 92, 0, 0, 0, 92, 92, 92, 92, ! 0, 0, 0, 0, 0, 92, 92, 0, 0, 92, ! 92, 92, 92, 92, 87, 92, 92, 87, 0, 92, ! 0, 0, 0, 0, 93, 93, 93, 93, 0, 0, ! 0, 87, 87, 93, 0, 0, 87, 93, 93, 93, ! 93, 0, 0, 0, 0, 0, 93, 93, 0, 0, ! 93, 93, 93, 93, 93, 88, 93, 93, 88, 0, ! 93, 0, 0, 0, 0, 0, 87, 0, 0, 0, ! 0, 0, 88, 88, 0, 0, 0, 88, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 89, 0, 0, 89, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 88, 89, 89, ! 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 85, 0, 0, ! 85, 0, 0, 0, 0, 0, 71, 71, 71, 71, ! 0, 0, 0, 89, 85, 85, 0, 0, 0, 85, ! 0, 0, 0, 0, 0, 0, 0, 0, 71, 71, ! 0, 0, 0, 86, 0, 0, 86, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, ! 86, 86, 0, 0, 0, 86, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 86, 84, 84, 0, 0, ! 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 87, 87, 87, 87, 0, + 0, 84, 0, 0, 87, 0, 0, 0, 87, 87, + 87, 87, 0, 0, 0, 0, 0, 87, 87, 0, + 0, 87, 87, 87, 87, 87, 72, 87, 87, 72, + 0, 0, 0, 0, 0, 0, 88, 88, 88, 88, + 0, 0, 0, 72, 72, 88, 0, 0, 72, 88, + 88, 88, 88, 0, 0, 0, 0, 0, 88, 88, + 0, 0, 88, 88, 88, 88, 88, 0, 88, 88, + 0, 0, 89, 89, 89, 89, 0, 0, 72, 0, + 0, 89, 0, 0, 0, 89, 89, 89, 89, 0, + 0, 0, 0, 0, 89, 89, 0, 0, 89, 89, + 89, 89, 89, 0, 89, 89, 0, 0, 85, 85, + 85, 85, 0, 0, 0, 0, 0, 85, 0, 0, 0, 85, 85, 85, 85, 0, 0, 0, 0, 0, ! 85, 85, 0, 0, 85, 85, 85, 85, 85, 0, ! 85, 85, 0, 0, 86, 86, 86, 86, 0, 0, ! 0, 0, 0, 86, 0, 0, 0, 86, 86, 86, ! 86, 0, 0, 0, 0, 0, 86, 86, 0, 0, ! 86, 86, 86, 86, 86, 0, 86, 86, 0, 0, ! 84, 84, 84, 84, 0, 0, 0, 0, 0, 84, ! 0, 0, 0, 84, 84, 84, 84, 73, 0, 0, ! 73, 0, 84, 84, 0, 0, 84, 84, 84, 84, ! 84, 0, 84, 84, 73, 73, 0, 0, 0, 73, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 74, 0, 0, 74, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 74, 74, 73, ! 0, 0, 74, 0, 0, 0, 0, 72, 72, 72, ! 72, 0, 0, 0, 0, 0, 72, 0, 0, 0, ! 72, 72, 72, 72, 75, 0, 0, 75, 0, 72, ! 72, 0, 74, 72, 72, 72, 72, 72, 0, 72, ! 72, 75, 75, 0, 0, 0, 75, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, ! 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 123, 123, 75, 0, 0, 123, ! 0, 0, 0, 0, 0, 0, 0, 0, 94, 0, ! 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 94, 94, 0, 0, 123, ! 94, 0, 0, 0, 0, 0, 0, 0, 0, 134, ! 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 134, 134, 0, 0, ! 94, 134, 0, 0, 0, 0, 0, 0, 0, 0, ! 76, 0, 0, 76, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 77, 76, 76, 77, ! 0, 134, 76, 0, 0, 0, 0, 0, 73, 73, ! 73, 73, 0, 77, 77, 0, 0, 73, 77, 0, ! 0, 73, 73, 73, 73, 0, 0, 0, 0, 0, ! 73, 73, 76, 0, 73, 73, 73, 73, 73, 0, ! 73, 74, 74, 74, 74, 0, 0, 0, 77, 0, ! 74, 0, 0, 0, 74, 74, 0, 74, 78, 0, ! 0, 78, 0, 74, 74, 0, 0, 74, 74, 74, ! 74, 74, 0, 74, 79, 78, 78, 79, 0, 0, ! 78, 0, 0, 0, 0, 75, 75, 75, 75, 0, ! 0, 79, 79, 0, 75, 0, 79, 0, 75, 75, ! 0, 0, 0, 0, 0, 0, 0, 75, 75, 0, ! 78, 75, 75, 75, 75, 75, 0, 75, 123, 123, ! 123, 123, 0, 0, 0, 0, 79, 123, 0, 0, ! 0, 123, 123, 0, 0, 0, 0, 0, 0, 81, ! 123, 123, 81, 0, 123, 123, 123, 123, 123, 94, ! 94, 94, 94, 0, 0, 0, 81, 81, 94, 0, ! 0, 81, 94, 94, 0, 0, 0, 0, 0, 0, ! 0, 94, 94, 0, 0, 94, 94, 94, 94, 94, ! 134, 134, 134, 134, 0, 0, 0, 0, 0, 134, ! 0, 81, 0, 134, 134, 0, 0, 0, 0, 0, ! 0, 0, 134, 134, 0, 0, 134, 134, 134, 134, ! 134, 76, 76, 76, 76, 0, 0, 0, 0, 0, ! 76, 0, 0, 0, 0, 76, 0, 77, 77, 77, ! 77, 0, 0, 76, 76, 0, 77, 76, 76, 76, ! 76, 76, 0, 0, 0, 0, 0, 0, 0, 77, ! 77, 0, 0, 77, 77, 77, 77, 77, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, ! 78, 78, 78, 0, 0, 0, 0, 0, 78, 0, ! 0, 0, 0, 0, 0, 79, 79, 79, 79, 0, ! 0, 78, 78, 0, 79, 78, 78, 78, 78, 78, ! 0, 0, 91, 0, 0, 0, 0, 79, 79, 0, ! 104, 79, 79, 79, 79, 111, 113, 0, 0, 0, ! 0, 0, 125, 126, 127, 128, 129, 130, 0, 0, ! 133, 134, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 81, 81, 81, 81, 0, 0, 0, 0, 0, 81, ! 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 81, 81, 0, 0, 81, 81, 81, 0, ! 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 0, 0, 0, 0, 0, 0, 313, }; short yycheck[] = { 13, ! 59, 13, 91, 17, 59, 59, 36, 93, 182, 194, ! 41, 123, 59, 44, 257, 41, 59, 40, 44, 33, ! 34, 35, 36, 91, 40, 88, 59, 58, 59, 43, ! 41, 40, 63, 45, 123, 41, 50, 63, 91, 41, ! 257, 41, 41, 40, 56, 40, 59, 40, 60, 41, ! 257, 41, 40, 116, 41, 123, 188, 59, 190, 40, ! 59, 91, 93, 41, 78, 91, 41, 36, 91, 59, ! 123, 40, 59, 41, 278, 41, 123, 41, 92, 294, ! 295, 95, 94, 97, 96, 99, 98, 101, 100, 41, ! 102, 59, 41, 123, 106, 41, 40, 123, 41, 41, ! 123, 123, 41, 44, 59, 44, 0, 123, 276, 277, ! 123, 44, 40, 287, 123, 300, 179, 59, 303, 58, ! 59, 184, 59, 59, 260, 59, 123, 141, 123, 123, ! 257, 40, 144, 145, 146, 147, 148, 149, 150, 33, ! 40, 40, 36, 37, 38, 257, 40, 295, 42, 43, ! 335, 45, 41, 6, 93, 8, 168, 169, 170, 171, ! 172, 173, 174, 125, 178, 59, 298, 299, 91, 41, ! 64, 185, 41, 305, 0, 59, 91, 125, 31, 32, ! 40, 93, 59, 41, 36, 40, 198, 125, 83, 59, ! 125, 93, 204, 205, 206, 125, 328, 91, 125, 211, ! 125, 41, 41, 257, 123, 91, 93, 33, 294, 295, ! 36, 37, 38, 41, 40, 59, 42, 43, 41, 45, ! 41, 59, 93, 59, 313, 237, 59, 239, 258, 123, ! 41, 125, 126, 59, 326, 294, 295, 123, 64, 294, ! 295, 272, 273, 274, 275, 259, 13, 261, 269, 263, ! 264, 294, 295, 267, -1, 281, 270, 269, 93, 285, ! 286, 287, 288, 294, 295, 91, 93, 298, 0, -1, ! 282, 123, 298, 299, 300, 301, 302, 93, 304, 305, ! -1, -1, 308, 294, 295, 311, 312, 313, 294, 295, ! 302, -1, 306, -1, 294, 295, -1, 123, -1, 125, ! 126, 33, 294, 295, 36, 37, 38, -1, 40, -1, ! 42, 43, -1, 45, 326, -1, 294, 295, 332, 294, ! 295, -1, 336, 272, 273, 274, 275, 59, 294, 295, ! 294, 295, 64, 272, 273, 274, 275, -1, -1, 294, ! 295, -1, 294, 295, -1, 294, 295, -1, 294, 295, ! -1, 294, 295, 294, 295, 294, 295, 294, 295, 91, ! 294, 295, 256, 257, 258, 259, 260, 261, -1, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, ! 274, 275, 294, 295, -1, 279, 280, -1, 282, 283, ! 284, 123, 294, 295, 126, 289, 290, 291, 292, 293, ! 41, 287, 296, 297, 91, 257, -1, 294, 295, 303, ! 262, -1, -1, 307, -1, 309, 310, -1, 59, 305, ! -1, -1, 308, 294, 295, 311, 312, 313, -1, -1, ! 256, 257, 258, 259, 260, 261, 123, 263, 264, 265, ! 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, ! -1, -1, 93, 279, 280, -1, 282, 283, 284, 294, ! 295, -1, -1, 289, 290, 291, 292, 293, -1, -1, ! 296, 297, 91, -1, -1, -1, -1, 303, 294, 295, ! -1, 307, 91, 309, 310, 26, 33, -1, -1, 36, ! 37, 38, -1, 40, 41, 42, 43, 44, 45, 48, ! 49, 42, -1, -1, 123, -1, 47, -1, 49, -1, ! -1, 58, 59, -1, 123, 125, 63, 64, -1, -1, ! 61, 62, 63, 64, 256, 257, 258, 259, 260, 261, ! -1, 263, 264, 265, -1, -1, -1, 269, -1, 88, ! 272, 273, 274, 275, 91, -1, 93, 279, 280, -1, ! 282, 283, 284, 63, -1, -1, -1, 289, 290, 291, ! 292, 293, 91, -1, 296, 297, 107, 116, 266, 267, ! 268, 303, 270, 271, 123, 307, 123, 309, 310, 126, ! 33, 91, -1, 36, 37, 38, -1, 40, 41, 42, ! 43, 44, 45, -1, 123, -1, -1, -1, 285, 286, ! 287, 288, -1, -1, -1, 58, 59, -1, -1, -1, ! 63, 64, -1, 123, 301, 302, -1, 304, 305, -1, -1, 308, -1, -1, 311, 312, 313, -1, -1, -1, ! 179, 272, 273, 274, 275, 184, -1, -1, -1, 33, ! 93, -1, 36, 37, 38, -1, 40, -1, 42, 43, ! -1, 45, -1, 294, 295, -1, 266, 267, 268, -1, ! 270, 271, -1, -1, -1, 59, 285, 286, 287, 288, ! 64, -1, -1, 126, -1, -1, 285, 286, 287, 288, ! 299, 300, 301, 302, -1, 304, 305, -1, -1, 308, ! -1, -1, 311, 312, 313, 304, 305, 91, -1, 308, ! -1, -1, 311, 312, 313, -1, -1, -1, -1, -1, ! 257, 258, 259, 260, 261, -1, 263, 264, 265, -1, ! -1, -1, 269, -1, -1, 272, 273, 274, 275, 123, ! -1, -1, 126, 280, 281, 282, 283, 284, 285, 286, ! 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, ! 297, 298, 299, 300, 301, 302, 303, 304, 305, -1, ! 307, 308, 309, 310, 311, 312, 313, 91, -1, -1, ! -1, 281, -1, -1, -1, 285, 286, 287, 288, 308, ! -1, -1, 311, 312, 313, -1, -1, -1, 298, 299, ! 300, 301, 302, -1, 304, 305, -1, -1, 308, 123, ! -1, 311, 312, 313, 257, 258, 259, 260, 261, -1, ! 263, 264, 265, -1, -1, -1, 269, -1, -1, 272, ! 273, 274, 275, -1, -1, -1, -1, 280, 281, 282, ! 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, ! 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, ! 303, 304, 305, -1, 307, 308, 309, 310, 311, 312, ! 313, 91, 256, 257, 258, 259, 260, 261, -1, 263, ! 264, 265, -1, 41, -1, 269, 44, -1, 272, 273, ! 274, 275, -1, -1, -1, 279, 280, -1, 282, 283, ! 284, 59, -1, 123, -1, 289, 290, 291, 292, 293, ! -1, -1, 296, 297, -1, -1, -1, -1, -1, 303, ! 25, 26, -1, 307, 33, 309, 310, 36, 37, 38, ! -1, 40, 37, 42, 43, 93, 45, 42, 43, -1, ! -1, -1, 47, -1, 49, 272, 273, 274, 275, -1, ! 59, -1, -1, -1, -1, 64, 61, 62, 63, 64, ! -1, -1, -1, -1, -1, -1, -1, 294, 295, -1, ! -1, -1, -1, 287, 288, -1, -1, -1, -1, -1, ! 33, -1, 91, 36, 37, 38, -1, 40, -1, 42, ! 43, 305, 45, -1, 308, -1, -1, 311, 312, 313, ! -1, -1, 107, -1, -1, -1, -1, -1, -1, -1, ! -1, 64, -1, -1, 123, -1, -1, 126, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, 33, -1, 91, 36, ! 37, 38, -1, 40, -1, 42, 43, -1, 45, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, 167, -1, -1, -1, -1, 64, -1, -1, ! 123, -1, -1, 126, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, 305, -1, -1, 308, -1, ! -1, 311, 312, 313, 91, -1, -1, -1, -1, 33, ! -1, -1, 36, 37, 38, -1, 40, -1, 42, 43, ! -1, 45, -1, -1, 272, 273, 274, 275, -1, -1, ! -1, -1, -1, -1, -1, 59, 123, -1, -1, 126, ! 64, -1, -1, -1, -1, -1, 294, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 256, 257, 258, 259, 260, 261, -1, 263, 264, 265, 91, -1, -1, ! 269, -1, -1, 272, 273, 274, 275, -1, -1, -1, ! 279, 280, -1, 282, 283, 284, -1, -1, -1, -1, 289, 290, 291, 292, 293, -1, -1, 296, 297, -1, ! 91, 63, 126, -1, 303, -1, -1, -1, 307, -1, ! 309, 310, -1, -1, 257, 258, 259, 260, 261, 262, ! 263, 264, 265, -1, -1, -1, 269, -1, -1, 91, ! 41, -1, 123, -1, -1, -1, -1, 280, -1, 282, 283, 284, -1, -1, -1, -1, 289, 290, 291, 292, ! 293, -1, 63, 296, 297, -1, -1, -1, -1, -1, ! 303, 123, -1, -1, 307, -1, 309, 310, -1, -1, ! 257, 258, 259, 260, 261, -1, 263, 264, 265, -1, ! 91, -1, 269, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 280, -1, 282, 283, 284, -1, -1, -1, -1, 289, 290, 291, 292, 293, -1, -1, 296, ! 297, 41, 123, -1, 44, -1, 303, -1, -1, -1, ! 307, -1, 309, 310, -1, -1, -1, -1, 58, 59, ! -1, -1, -1, 257, 258, 259, 260, 261, 91, 263, ! 264, 265, -1, 33, -1, 269, 36, 37, 38, -1, ! 40, -1, 42, 43, -1, 45, 280, -1, 282, 283, ! 284, -1, -1, 93, -1, 289, 290, 291, 292, 293, ! 123, -1, 296, 297, 64, -1, -1, -1, -1, 303, ! -1, -1, -1, 307, -1, 309, 310, -1, -1, -1, ! -1, -1, -1, -1, 285, -1, 287, 288, -1, 33, ! -1, 91, 36, 37, 38, -1, 40, 41, 42, 43, ! -1, 45, -1, 304, 305, -1, -1, 308, -1, 281, ! 311, 312, 313, 285, 286, 287, 288, -1, -1, -1, ! 64, -1, -1, 123, -1, -1, 126, 299, 300, 301, ! 302, -1, 304, 305, -1, -1, 308, -1, -1, 311, ! 312, 313, -1, -1, -1, 33, -1, 91, 36, 37, ! 38, -1, 40, -1, 42, 43, -1, 45, -1, -1, ! 281, -1, -1, -1, 285, 286, 287, 288, -1, -1, ! -1, -1, -1, -1, -1, -1, 64, 298, 299, 300, ! 301, 302, 126, 304, 305, -1, -1, 308, -1, -1, ! 311, 312, 313, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, 91, -1, 93, -1, -1, 33, -1, ! -1, 36, 37, 38, -1, 40, -1, 42, 43, -1, ! 45, -1, -1, -1, 287, 288, -1, -1, -1, -1, ! -1, -1, 272, 273, 274, 275, -1, -1, 126, 64, ! -1, 304, 305, -1, -1, 308, -1, -1, 311, 312, ! 313, -1, -1, -1, 294, 295, -1, 257, 258, 259, ! 260, 261, -1, 263, 264, 265, 91, -1, -1, 269, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 280, -1, 282, 283, 284, -1, -1, -1, -1, 289, 290, 291, 292, 293, -1, -1, 296, 297, -1, -1, ! -1, 126, -1, 303, -1, -1, -1, 307, -1, 309, 310, -1, -1, 257, 258, 259, 260, 261, -1, 263, ! 264, 265, -1, 91, -1, 269, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 280, -1, 282, 283, 284, -1, -1, -1, -1, 289, 290, 291, 292, 293, ! -1, -1, 296, 297, 91, 123, -1, -1, -1, 303, ! -1, 41, -1, 307, 44, 309, 310, -1, -1, 257, ! 258, 259, 260, 261, -1, 263, 264, 265, 58, 59, ! -1, 269, -1, 63, -1, -1, 123, -1, -1, -1, ! -1, -1, 280, -1, 282, 283, 284, -1, -1, -1, ! -1, 289, 290, 291, 292, 293, -1, -1, 296, 297, ! -1, 41, -1, 93, 44, 303, -1, -1, -1, 307, ! -1, 309, 310, -1, -1, -1, -1, -1, 58, 59, ! -1, 256, 257, 258, 259, 260, 261, -1, 263, 264, ! 265, -1, 33, -1, 269, 36, 37, 38, -1, 40, ! 41, 42, 43, -1, 45, 280, -1, 282, 283, 284, ! -1, -1, -1, 93, 289, 290, 291, 292, 293, -1, ! -1, 296, 297, 64, -1, -1, -1, -1, 303, -1, ! -1, -1, 307, -1, 309, 310, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, 33, -1, ! 91, 36, 37, 38, -1, 40, 41, 42, 43, -1, ! 45, -1, -1, -1, -1, -1, -1, 285, 286, 287, ! 288, -1, -1, -1, -1, -1, -1, -1, -1, 64, ! -1, -1, 300, 301, 302, 126, 304, 305, -1, -1, ! 308, -1, -1, 311, 312, 313, -1, -1, 285, 286, ! 287, 288, -1, -1, 33, -1, 91, 36, 37, 38, ! -1, 40, 41, 42, 43, 302, 45, 304, 305, -1, ! -1, 308, -1, -1, 311, 312, 313, -1, -1, -1, ! -1, -1, -1, -1, -1, 64, -1, -1, -1, -1, ! -1, 126, 272, 273, 274, 275, -1, -1, -1, -1, ! -1, 281, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, 91, -1, 294, 295, -1, 33, 298, 299, ! 36, 37, 38, -1, 40, 41, 42, 43, -1, 45, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 272, 273, 274, 275, -1, 126, 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, 294, 295, 257, 258, 259, 260, ! 261, -1, 263, 264, 265, 91, -1, -1, 269, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, 280, ! -1, 282, 283, 284, -1, -1, -1, -1, 289, 290, ! 291, 292, 293, -1, -1, 296, 297, -1, -1, -1, ! 126, -1, 303, -1, 41, -1, 307, 44, 309, 310, ! -1, -1, 257, 258, 259, 260, 261, -1, 263, 264, ! 265, 58, 59, -1, 269, -1, 63, -1, -1, -1, ! -1, -1, -1, -1, -1, 280, -1, 282, 283, 284, ! -1, -1, -1, -1, 289, 290, 291, 292, 293, -1, ! -1, 296, 297, -1, 91, -1, 93, -1, 303, -1, ! 41, -1, 307, 44, 309, 310, -1, -1, 257, 258, ! 259, 260, 261, -1, 263, 264, 265, 58, 59, -1, ! 269, -1, 63, -1, -1, -1, 123, -1, -1, -1, ! -1, 280, -1, 282, 283, 284, -1, -1, -1, -1, ! 289, 290, 291, 292, 293, -1, -1, 296, 297, -1, ! 91, -1, 93, -1, 303, -1, -1, -1, 307, -1, ! 309, 310, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, 257, 258, 259, 260, 261, -1, 263, 264, 265, ! -1, 33, 123, 269, 36, 37, 38, -1, 40, -1, ! 42, 43, -1, 45, 280, -1, 282, 283, 284, -1, ! -1, -1, -1, 289, 290, 291, 292, 293, -1, -1, ! 296, 297, 64, -1, -1, -1, -1, 303, -1, -1, ! -1, 307, -1, 309, 310, -1, -1, -1, -1, -1, ! 41, -1, -1, 44, -1, -1, -1, -1, -1, 91, ! -1, -1, -1, -1, -1, -1, -1, 58, 59, -1, ! -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, 126, 272, 273, 274, 275, -1, ! 91, -1, 93, -1, 281, -1, -1, -1, 285, 286, ! 287, 288, -1, -1, -1, -1, -1, 294, 295, -1, ! -1, 298, 299, 300, 301, 302, -1, 304, 305, -1, ! -1, 308, 123, -1, 311, 312, 313, -1, -1, -1, ! -1, 41, -1, -1, 44, -1, -1, -1, -1, -1, -1, 272, 273, 274, 275, -1, -1, -1, 58, 59, 281, -1, -1, 63, 285, 286, 287, 288, -1, -1, -1, -1, -1, 294, 295, -1, -1, 298, 299, 300, ! 301, 302, -1, 304, 305, -1, 41, 308, -1, 44, ! 311, 312, 313, 93, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, 58, 59, -1, -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, 123, -1, 257, 258, 259, 260, 261, ! -1, 263, 264, 265, -1, -1, 91, 269, 93, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, 280, -1, ! 282, 283, 284, -1, -1, -1, -1, 289, 290, 291, ! 292, 293, -1, -1, 296, 297, -1, -1, -1, -1, ! -1, 303, -1, -1, -1, 307, -1, 309, 310, -1, ! -1, 272, 273, 274, 275, -1, -1, -1, -1, -1, ! 281, -1, -1, -1, 285, 286, 287, 288, -1, -1, ! -1, -1, -1, 294, 295, -1, -1, 298, 299, 300, ! 301, 302, -1, 304, 305, 41, -1, 308, 44, -1, ! 311, 312, 313, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, 58, 59, -1, -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, 41, -1, -1, 44, -1, 93, -1, -1, ! -1, -1, 272, 273, 274, 275, -1, -1, -1, 58, ! 59, 281, -1, -1, -1, 285, 286, 287, 288, -1, ! -1, -1, -1, -1, 294, 295, -1, 123, 298, 299, 300, 301, 302, -1, 304, 305, -1, -1, 308, -1, ! -1, 311, 312, 313, 93, -1, -1, 272, 273, 274, ! 275, -1, -1, -1, -1, -1, 281, -1, -1, -1, ! 285, 286, 287, 288, -1, -1, -1, 41, -1, 294, ! 295, -1, -1, 298, 299, 300, 301, 302, -1, 304, ! 305, -1, -1, 308, 58, 59, 311, 312, 313, 63, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, 41, -1, -1, -1, -1, -1, 91, -1, 93, ! -1, -1, -1, -1, -1, -1, -1, -1, 58, 59, ! -1, -1, -1, 63, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, 123, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, 91, -1, 93, -1, -1, 41, -1, -1, 44, ! -1, -1, -1, -1, -1, -1, 272, 273, 274, 275, -1, -1, -1, 58, 59, 281, -1, -1, 63, 285, ! 286, 287, 288, 123, -1, -1, -1, -1, 294, 295, -1, -1, 298, 299, 300, 301, 302, -1, 304, 305, 41, -1, 308, 44, -1, 311, 312, 313, 93, -1, ! -1, -1, -1, 272, 273, 274, 275, 58, 59, -1, ! -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, 294, 295, -1, 123, 298, ! -1, -1, -1, 41, -1, -1, -1, -1, -1, -1, ! -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, ! 58, 59, -1, -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, 123, -1, -1, -1, -1, -1, 272, 273, ! 274, 275, -1, 91, -1, 93, -1, 281, -1, -1, ! -1, 285, 286, 287, 288, 41, -1, -1, 44, -1, ! 294, 295, -1, -1, 298, 299, 300, 301, 302, -1, ! 304, 305, 58, 59, 308, 123, -1, 311, 312, 313, ! -1, -1, 272, 273, 274, 275, -1, -1, -1, -1, ! -1, 281, -1, -1, -1, 285, 286, 287, 288, -1, ! -1, -1, -1, -1, 294, 295, -1, 93, 298, 299, ! 300, 301, 302, -1, 304, 305, -1, -1, 308, -1, ! -1, 311, 312, 313, -1, -1, -1, 41, -1, -1, ! 44, -1, -1, -1, -1, -1, -1, 272, 273, 274, ! 275, -1, -1, -1, 58, 59, 281, -1, -1, 63, 285, 286, 287, 288, -1, -1, -1, -1, -1, 294, 295, -1, -1, 298, 299, 300, 301, 302, -1, 304, ! 305, 41, -1, 308, 44, -1, 311, 312, 313, 93, -1, 272, 273, 274, 275, -1, -1, -1, 58, 59, 281, -1, -1, 63, 285, 286, 287, 288, -1, -1, -1, -1, -1, 294, 295, -1, -1, 298, 299, 300, ! 301, 302, -1, 304, 305, -1, -1, 308, -1, -1, ! 311, 312, 313, 93, 272, 273, 274, 275, -1, 58, ! -1, -1, -1, 281, 63, -1, -1, 285, 286, 287, ! 288, -1, -1, -1, -1, -1, 294, 295, -1, -1, ! 298, 299, 300, 301, 302, 41, 304, 305, 44, -1, ! 308, -1, 91, 311, 312, 313, -1, -1, -1, -1, ! -1, -1, 58, 59, -1, -1, -1, 63, -1, -1, ! -1, -1, -1, -1, -1, -1, 272, 273, 274, 275, ! -1, -1, -1, -1, 123, -1, -1, 41, -1, -1, ! 44, -1, -1, -1, -1, -1, -1, 93, 294, 295, ! -1, -1, -1, -1, 58, 59, -1, -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, 123, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, 41, 93, ! -1, 44, -1, -1, -1, -1, -1, -1, 272, 273, ! 274, 275, -1, -1, -1, 58, 59, 281, -1, -1, ! 63, 285, 286, 287, 288, -1, -1, -1, -1, -1, ! 294, 295, -1, -1, 298, 299, 300, 301, 302, -1, ! 304, 305, 41, -1, 308, 44, -1, 311, 312, 313, ! 93, -1, 272, 273, 274, 275, -1, -1, -1, 58, ! 59, 281, -1, -1, 63, 285, 286, 287, 288, -1, -1, -1, -1, -1, 294, 295, -1, -1, 298, 299, ! 300, 301, 302, 41, 304, 305, 44, -1, 308, -1, ! -1, 311, 312, 313, 93, -1, -1, -1, -1, -1, ! 58, 59, 281, -1, -1, 63, 285, 286, 287, 288, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, 298, ! 299, 300, 301, 302, -1, 304, 305, -1, -1, 308, ! -1, -1, 311, 312, 313, 93, 272, 273, 274, 275, ! -1, -1, -1, -1, -1, 281, -1, -1, -1, 285, ! 286, 287, 288, -1, -1, -1, -1, -1, 294, 295, ! -1, -1, 298, 299, 300, 301, 302, -1, 304, 305, ! -1, -1, 308, -1, -1, 311, 312, 313, 272, 273, ! 274, 275, -1, -1, -1, -1, -1, 281, -1, -1, ! -1, 285, 286, 287, 288, 41, -1, -1, 44, -1, ! 294, 295, -1, -1, 298, 299, 300, 301, 302, -1, ! 304, 305, 58, 59, 308, -1, -1, 311, 312, 313, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, 272, ! 273, 274, 275, -1, -1, -1, -1, -1, 281, -1, ! -1, -1, 285, 286, 287, 288, -1, 93, -1, -1, ! -1, 294, 295, -1, -1, 298, 299, 300, 301, 302, ! -1, 304, 305, -1, -1, 308, -1, -1, 311, 312, ! 313, -1, -1, 272, 273, 274, 275, -1, -1, -1, ! -1, -1, 281, -1, -1, -1, 285, 286, 287, 288, ! -1, -1, -1, -1, -1, 294, 295, -1, -1, 298, ! 299, 300, 301, 302, 41, 304, 305, 44, -1, 308, ! -1, -1, -1, -1, 272, 273, 274, 275, -1, -1, ! -1, 58, 59, 281, -1, -1, 63, 285, 286, 287, ! 288, -1, -1, -1, -1, -1, 294, 295, -1, -1, ! 298, 299, 300, 301, 302, 41, 304, 305, 44, -1, ! 308, -1, -1, -1, -1, -1, 93, -1, -1, -1, ! -1, -1, 58, 59, -1, -1, -1, 63, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, 41, -1, -1, 44, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, 93, 58, 59, ! -1, -1, -1, 63, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, ! 44, -1, -1, -1, -1, -1, 272, 273, 274, 275, ! -1, -1, -1, 93, 58, 59, -1, -1, -1, 63, ! -1, -1, -1, -1, -1, -1, -1, -1, 294, 295, ! -1, -1, -1, 41, -1, -1, 44, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, 58, 59, -1, -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, 58, 59, -1, -1, -1, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, 272, 273, 274, 275, -1, ! -1, 93, -1, -1, 281, -1, -1, -1, 285, 286, ! 287, 288, -1, -1, -1, -1, -1, 294, 295, -1, ! -1, 298, 299, 300, 301, 302, 41, 304, 305, 44, ! -1, -1, -1, -1, -1, -1, 272, 273, 274, 275, ! -1, -1, -1, 58, 59, 281, -1, -1, 63, 285, ! 286, 287, 288, -1, -1, -1, -1, -1, 294, 295, ! -1, -1, 298, 299, 300, 301, 302, -1, 304, 305, ! -1, -1, 272, 273, 274, 275, -1, -1, 93, -1, ! -1, 281, -1, -1, -1, 285, 286, 287, 288, -1, ! -1, -1, -1, -1, 294, 295, -1, -1, 298, 299, ! 300, 301, 302, -1, 304, 305, -1, -1, 272, 273, ! 274, 275, -1, -1, -1, -1, -1, 281, -1, -1, ! -1, 285, 286, 287, 288, -1, -1, -1, -1, -1, ! 294, 295, -1, -1, 298, 299, 300, 301, 302, -1, ! 304, 305, -1, -1, 272, 273, 274, 275, -1, -1, ! -1, -1, -1, 281, -1, -1, -1, 285, 286, 287, ! 288, -1, -1, -1, -1, -1, 294, 295, -1, -1, ! 298, 299, 300, 301, 302, -1, 304, 305, -1, -1, ! 272, 273, 274, 275, -1, -1, -1, -1, -1, 281, ! -1, -1, -1, 285, 286, 287, 288, 41, -1, -1, ! 44, -1, 294, 295, -1, -1, 298, 299, 300, 301, ! 302, -1, 304, 305, 58, 59, -1, -1, -1, 63, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! 41, -1, -1, 44, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, 58, 59, 93, ! -1, -1, 63, -1, -1, -1, -1, 272, 273, 274, 275, -1, -1, -1, -1, -1, 281, -1, -1, -1, 285, 286, 287, 288, 41, -1, -1, 44, -1, 294, ! 295, -1, 93, 298, 299, 300, 301, 302, -1, 304, 305, 58, 59, -1, -1, -1, 63, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, 41, -1, -1, ! 44, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, 58, 59, 93, -1, -1, 63, ! -1, -1, -1, -1, -1, -1, -1, -1, 41, -1, ! -1, 44, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, 58, 59, -1, -1, 93, ! 63, -1, -1, -1, -1, -1, -1, -1, -1, 41, ! -1, -1, 44, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, 58, 59, -1, -1, ! 93, 63, -1, -1, -1, -1, -1, -1, -1, -1, ! 41, -1, -1, 44, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, 41, 58, 59, 44, ! -1, 93, 63, -1, -1, -1, -1, -1, 272, 273, ! 274, 275, -1, 58, 59, -1, -1, 281, 63, -1, ! -1, 285, 286, 287, 288, -1, -1, -1, -1, -1, ! 294, 295, 93, -1, 298, 299, 300, 301, 302, -1, ! 304, 272, 273, 274, 275, -1, -1, -1, 93, -1, ! 281, -1, -1, -1, 285, 286, -1, 288, 41, -1, ! -1, 44, -1, 294, 295, -1, -1, 298, 299, 300, ! 301, 302, -1, 304, 41, 58, 59, 44, -1, -1, ! 63, -1, -1, -1, -1, 272, 273, 274, 275, -1, ! -1, 58, 59, -1, 281, -1, 63, -1, 285, 286, ! -1, -1, -1, -1, -1, -1, -1, 294, 295, -1, ! 93, 298, 299, 300, 301, 302, -1, 304, 272, 273, ! 274, 275, -1, -1, -1, -1, 93, 281, -1, -1, ! -1, 285, 286, -1, -1, -1, -1, -1, -1, 41, ! 294, 295, 44, -1, 298, 299, 300, 301, 302, 272, ! 273, 274, 275, -1, -1, -1, 58, 59, 281, -1, ! -1, 63, 285, 286, -1, -1, -1, -1, -1, -1, ! -1, 294, 295, -1, -1, 298, 299, 300, 301, 302, ! 272, 273, 274, 275, -1, -1, -1, -1, -1, 281, ! -1, 93, -1, 285, 286, -1, -1, -1, -1, -1, -1, -1, 294, 295, -1, -1, 298, 299, 300, 301, ! 302, 272, 273, 274, 275, -1, -1, -1, -1, -1, ! 281, -1, -1, -1, -1, 286, -1, 272, 273, 274, ! 275, -1, -1, 294, 295, -1, 281, 298, 299, 300, ! 301, 302, -1, -1, -1, -1, -1, -1, -1, 294, ! 295, -1, -1, 298, 299, 300, 301, 302, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, -1, 272, ! 273, 274, 275, -1, -1, -1, -1, -1, 281, -1, -1, -1, -1, -1, -1, 272, 273, 274, 275, -1, ! -1, 294, 295, -1, 281, 298, 299, 300, 301, 302, ! -1, -1, 30, -1, -1, -1, -1, 294, 295, -1, ! 38, 298, 299, 300, 301, 43, 44, -1, -1, -1, ! -1, -1, 50, 51, 52, 53, 54, 55, -1, -1, ! 58, 59, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 272, 273, 274, 275, -1, -1, -1, -1, -1, 281, + -1, -1, 90, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 294, 295, -1, -1, 298, 299, 300, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, 143, -1, -1, -1, -1, ! -1, -1, -1, 151, 152, 153, 154, 155, 156, 157, ! 158, 159, 160, 161, 162, 163, 164, -1, -1, -1, -1, -1, -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,1116 **** -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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, 284, }; #define YYFINAL 1 #ifndef YYDEBUG --- 1101,1110 ---- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, -1, -1, 256, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, ! -1, -1, -1, -1, -1, -1, 284, }; #define YYFINAL 1 #ifndef YYDEBUG *************** *** 1190,1196 **** "startsub :", "package : PACKAGE WORD ';'", "package : PACKAGE ';'", ! "use : USE startsub WORD listexpr ';'", "expr : expr ANDOP expr", "expr : expr OROP expr", "expr : argexpr", --- 1184,1190 ---- "startsub :", "package : PACKAGE WORD ';'", "package : PACKAGE ';'", ! "use : USE startsub WORD WORD listexpr ';'", "expr : expr ANDOP expr", "expr : expr OROP expr", "expr : argexpr", *************** *** 1320,1326 **** YYSTYPE yylval; #line 571 "perly.y" /* PROGRAM */ ! #line 1394 "y.tab.c" #define YYABORT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab --- 1314,1320 ---- YYSTYPE yylval; #line 571 "perly.y" /* PROGRAM */ ! #line 1388 "y.tab.c" #define YYABORT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab *************** *** 1341,1355 **** void* ptr; { struct ysv* ysave = (struct ysv*)ptr; ! if (ysave->yyss) Safefree(ysave->yyss); ! if (ysave->yyvs) Safefree(ysave->yyvs); yydebug = ysave->oldyydebug; yynerrs = ysave->oldyynerrs; yyerrflag = ysave->oldyyerrflag; yychar = ysave->oldyychar; yyval = ysave->oldyyval; yylval = ysave->oldyylval; ! Safefree(ysave); } int --- 1335,1349 ---- void* ptr; { struct ysv* ysave = (struct ysv*)ptr; ! if (ysave->yyss) safefree((char *)ysave->yyss); ! if (ysave->yyvs) safefree((char *)ysave->yyvs); yydebug = ysave->oldyydebug; yynerrs = ysave->oldyynerrs; yyerrflag = ysave->oldyyerrflag; yychar = ysave->oldyychar; yyval = ysave->oldyyval; yylval = ysave->oldyylval; ! safefree((char *)ysave); } int *************** *** 1412,1418 **** yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; ! fprintf(stderr, "yydebug: state %d, reading %d (%s)\n", yystate, yychar, yys); } #endif --- 1406,1412 ---- yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; ! fprintf(Perl_debug_log, "yydebug: state %d, reading %d (%s)\n", yystate, yychar, yys); } #endif *************** *** 1422,1428 **** { #if YYDEBUG if (yydebug) ! fprintf(stderr, "yydebug: state %d, shifting to state %d\n", yystate, yytable[yyn]); #endif if (yyssp >= yyss + yystacksize - 1) --- 1416,1422 ---- { #if YYDEBUG if (yydebug) ! fprintf(Perl_debug_log, "yydebug: state %d, shifting to state %d\n", yystate, yytable[yyn]); #endif if (yyssp >= yyss + yystacksize - 1) *************** *** 1477,1483 **** { #if YYDEBUG if (yydebug) ! fprintf(stderr, "yydebug: state %d, error recovery shifting to state %d\n", *yyssp, yytable[yyn]); #endif --- 1471,1477 ---- { #if YYDEBUG if (yydebug) ! fprintf(Perl_debug_log, "yydebug: state %d, error recovery shifting to state %d\n", *yyssp, yytable[yyn]); #endif *************** *** 1507,1513 **** { #if YYDEBUG if (yydebug) ! fprintf(stderr, "yydebug: error recovery discarding state %d\n", *yyssp); #endif --- 1501,1507 ---- { #if YYDEBUG if (yydebug) ! fprintf(Perl_debug_log, "yydebug: error recovery discarding state %d\n", *yyssp); #endif *************** *** 1526,1532 **** yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; ! fprintf(stderr, "yydebug: state %d, error recovery discards token %d (%s)\n", yystate, yychar, yys); } --- 1520,1526 ---- yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; ! fprintf(Perl_debug_log, "yydebug: state %d, error recovery discards token %d (%s)\n", yystate, yychar, yys); } *************** *** 1537,1543 **** yyreduce: #if YYDEBUG if (yydebug) ! fprintf(stderr, "yydebug: state %d, reducing by rule %d (%s)\n", yystate, yyn, yyrule[yyn]); #endif yym = yylen[yyn]; --- 1531,1537 ---- yyreduce: #if YYDEBUG if (yydebug) ! fprintf(Perl_debug_log, "yydebug: state %d, reducing by rule %d (%s)\n", yystate, yyn, yyrule[yyn]); #endif yym = yylen[yyn]; *************** *** 1785,1791 **** break; case 54: #line 271 "perly.y" ! { utilize(yyvsp[-4].ival, yyvsp[-3].ival, yyvsp[-2].opval, yyvsp[-1].opval); } break; case 55: #line 275 "perly.y" --- 1779,1785 ---- break; case 54: #line 271 "perly.y" ! { utilize(yyvsp[-5].ival, yyvsp[-4].ival, yyvsp[-3].opval, yyvsp[-2].opval, yyvsp[-1].opval); } break; case 55: #line 275 "perly.y" *************** *** 2246,2252 **** #line 568 "perly.y" { yyval.opval = yyvsp[0].opval; } break; ! #line 2236 "y.tab.c" } yyssp -= yym; yystate = *yyssp; --- 2240,2246 ---- #line 568 "perly.y" { yyval.opval = yyvsp[0].opval; } break; ! #line 2230 "y.tab.c" } yyssp -= yym; yystate = *yyssp; *************** *** 2256,2262 **** { #if YYDEBUG if (yydebug) ! fprintf(stderr, "yydebug: after reduction, shifting from state 0 to state %d\n", YYFINAL); #endif --- 2250,2256 ---- { #if YYDEBUG if (yydebug) ! fprintf(Perl_debug_log, "yydebug: after reduction, shifting from state 0 to state %d\n", YYFINAL); #endif *************** *** 2272,2278 **** yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; ! fprintf(stderr, "yydebug: state %d, reading %d (%s)\n", YYFINAL, yychar, yys); } #endif --- 2266,2272 ---- yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; ! fprintf(Perl_debug_log, "yydebug: state %d, reading %d (%s)\n", YYFINAL, yychar, yys); } #endif *************** *** 2287,2293 **** yystate = yydgoto[yym]; #if YYDEBUG if (yydebug) ! fprintf(stderr, "yydebug: after reduction, shifting from state %d to state %d\n", *yyssp, yystate); #endif --- 2281,2287 ---- yystate = yydgoto[yym]; #if YYDEBUG if (yydebug) ! fprintf(Perl_debug_log, "yydebug: after reduction, shifting from state %d to state %d\n", *yyssp, yystate); #endif #~ Update to reflect new perly.c #~ Use safefree instead of Safefree to free memory allocated by safemalloc diff -Pcr perl5_003/perly.c.diff perl5_003_01/perly.c.diff *** perl5_003/perly.c.diff Wed Feb 14 18:48:37 1996 --- perl5_003_01/perly.c.diff Sun Jul 7 19:31:35 1996 *************** *** 1,5 **** ! *** perly.c.orig Wed Feb 14 15:29:04 1996 ! --- perly.c Wed Feb 14 15:29:05 1996 *************** *** 12,82 **** deprecate("\"do\" to call subroutines"); --- 1,5 ---- ! *** perly.c.orig Sun Jul 7 23:27:45 1996 ! --- perly.c Sun Jul 7 23:27:46 1996 *************** *** 12,82 **** deprecate("\"do\" to call subroutines"); *************** *** 75,81 **** 31, 0, 5, 3, 6, 6, 6, 7, 7, 7, --- 12,17 ---- *************** ! *** 1381,1393 **** int yynerrs; int yyerrflag; int yychar; --- 75,81 ---- 31, 0, 5, 3, 6, 6, 6, 7, 7, 7, --- 12,17 ---- *************** ! *** 1375,1387 **** int yynerrs; int yyerrflag; int yychar; *************** *** 88,98 **** - #define yystacksize YYSTACKSIZE #line 571 "perly.y" /* PROGRAM */ ! #line 1394 "y.tab.c" ! --- 1316,1323 ---- *************** ! *** 1394,1407 **** ! --- 1324,1382 ---- #define YYABORT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab --- 88,98 ---- - #define yystacksize YYSTACKSIZE #line 571 "perly.y" /* PROGRAM */ ! #line 1388 "y.tab.c" ! --- 1310,1317 ---- *************** ! *** 1388,1401 **** ! --- 1318,1376 ---- #define YYABORT goto yyabort #define YYACCEPT goto yyaccept #define YYERROR goto yyerrlab *************** *** 113,127 **** + void* ptr; + { + struct ysv* ysave = (struct ysv*)ptr; ! + if (ysave->yyss) Safefree(ysave->yyss); ! + if (ysave->yyvs) Safefree(ysave->yyvs); + yydebug = ysave->oldyydebug; + yynerrs = ysave->oldyynerrs; + yyerrflag = ysave->oldyyerrflag; + yychar = ysave->oldyychar; + yyval = ysave->oldyyval; + yylval = ysave->oldyylval; ! + Safefree(ysave); + } + int --- 113,127 ---- + void* ptr; + { + struct ysv* ysave = (struct ysv*)ptr; ! + if (ysave->yyss) safefree((char *)ysave->yyss); ! + if (ysave->yyvs) safefree((char *)ysave->yyvs); + yydebug = ysave->oldyydebug; + yynerrs = ysave->oldyynerrs; + yyerrflag = ysave->oldyyerrflag; + yychar = ysave->oldyychar; + yyval = ysave->oldyyval; + yylval = ysave->oldyylval; ! + safefree((char *)ysave); + } + int *************** *** 153,160 **** { yyn = *yys; *************** ! *** 1414,1419 **** ! --- 1389,1402 ---- yyerrflag = 0; yychar = (-1); --- 153,160 ---- { yyn = *yys; *************** ! *** 1408,1413 **** ! --- 1383,1396 ---- yyerrflag = 0; yychar = (-1); *************** *** 170,176 **** yyvsp = yyvs; *yyssp = yystate = 0; *************** ! *** 1429,1435 **** yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; --- 170,176 ---- yyvsp = yyvs; *yyssp = yystate = 0; *************** ! *** 1423,1429 **** yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; *************** *** 178,184 **** yychar, yys); } #endif ! --- 1412,1418 ---- yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; --- 178,184 ---- yychar, yys); } #endif ! --- 1406,1412 ---- yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; *************** *** 187,193 **** } #endif *************** ! *** 1439,1450 **** { #if YYDEBUG if (yydebug) --- 187,193 ---- } #endif *************** ! *** 1433,1444 **** { #if YYDEBUG if (yydebug) *************** *** 200,206 **** } *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; ! --- 1422,1447 ---- { #if YYDEBUG if (yydebug) --- 200,206 ---- } *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; ! --- 1416,1441 ---- { #if YYDEBUG if (yydebug) *************** *** 228,234 **** *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; *************** ! *** 1480,1491 **** { #if YYDEBUG if (yydebug) --- 228,234 ---- *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; *************** ! *** 1474,1485 **** { #if YYDEBUG if (yydebug) *************** *** 241,247 **** } *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; ! --- 1477,1503 ---- { #if YYDEBUG if (yydebug) --- 241,247 ---- } *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; ! --- 1471,1497 ---- { #if YYDEBUG if (yydebug) *************** *** 270,276 **** *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; *************** ! *** 1495,1502 **** { #if YYDEBUG if (yydebug) --- 270,276 ---- *++yyssp = yystate = yytable[yyn]; *++yyvsp = yylval; *************** ! *** 1489,1496 **** { #if YYDEBUG if (yydebug) *************** *** 279,285 **** #endif if (yyssp <= yyss) goto yyabort; --yyssp; ! --- 1507,1515 ---- { #if YYDEBUG if (yydebug) --- 279,285 ---- #endif if (yyssp <= yyss) goto yyabort; --yyssp; ! --- 1501,1509 ---- { #if YYDEBUG if (yydebug) *************** *** 290,296 **** if (yyssp <= yyss) goto yyabort; --yyssp; *************** ! *** 1513,1520 **** yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; --- 290,296 ---- if (yyssp <= yyss) goto yyabort; --yyssp; *************** ! *** 1507,1514 **** yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; *************** *** 299,305 **** } #endif yychar = (-1); ! --- 1526,1534 ---- yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; --- 299,305 ---- } #endif yychar = (-1); ! --- 1520,1528 ---- yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; *************** *** 310,316 **** #endif yychar = (-1); *************** ! *** 1523,1529 **** yyreduce: #if YYDEBUG if (yydebug) --- 310,316 ---- #endif yychar = (-1); *************** ! *** 1517,1523 **** yyreduce: #if YYDEBUG if (yydebug) *************** *** 318,324 **** yystate, yyn, yyrule[yyn]); #endif yym = yylen[yyn]; ! --- 1537,1543 ---- yyreduce: #if YYDEBUG if (yydebug) --- 318,324 ---- yystate, yyn, yyrule[yyn]); #endif yym = yylen[yyn]; ! --- 1531,1537 ---- yyreduce: #if YYDEBUG if (yydebug) *************** *** 327,333 **** #endif yym = yylen[yyn]; *************** ! *** 2242,2249 **** { #if YYDEBUG if (yydebug) --- 327,333 ---- #endif yym = yylen[yyn]; *************** ! *** 2236,2243 **** { #if YYDEBUG if (yydebug) *************** *** 336,342 **** #endif yystate = YYFINAL; *++yyssp = YYFINAL; ! --- 2256,2264 ---- { #if YYDEBUG if (yydebug) --- 336,342 ---- #endif yystate = YYFINAL; *++yyssp = YYFINAL; ! --- 2250,2258 ---- { #if YYDEBUG if (yydebug) *************** *** 347,353 **** yystate = YYFINAL; *++yyssp = YYFINAL; *************** ! *** 2257,2263 **** yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; --- 347,353 ---- yystate = YYFINAL; *++yyssp = YYFINAL; *************** ! *** 2251,2257 **** yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; *************** *** 355,361 **** YYFINAL, yychar, yys); } #endif ! --- 2272,2278 ---- yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; --- 355,361 ---- YYFINAL, yychar, yys); } #endif ! --- 2266,2272 ---- yys = 0; if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; if (!yys) yys = "illegal-symbol"; *************** *** 364,370 **** } #endif *************** ! *** 2272,2291 **** yystate = yydgoto[yym]; #if YYDEBUG if (yydebug) --- 364,370 ---- } #endif *************** ! *** 2266,2285 **** yystate = yydgoto[yym]; #if YYDEBUG if (yydebug) *************** *** 385,391 **** yyaccept: ! return (0); } ! --- 2287,2321 ---- yystate = yydgoto[yym]; #if YYDEBUG if (yydebug) --- 385,391 ---- yyaccept: ! return (0); } ! --- 2281,2315 ---- yystate = yydgoto[yym]; #if YYDEBUG if (yydebug) #~ Eliminate duplicate declaration of yylval diff -Pcr perl5_003/perly.h perl5_003_01/perly.h *** perl5_003/perly.h Wed Feb 28 17:38:06 1996 --- perl5_003_01/perly.h Tue Jul 9 11:07:58 1996 *************** *** 62,65 **** GV *gvval; } YYSTYPE; extern YYSTYPE yylval; - extern YYSTYPE yylval; --- 62,64 ---- #~ Add version check option to "use" diff -Pcr perl5_003/perly.y perl5_003_01/perly.y *** perl5_003/perly.y Wed Feb 14 18:48:45 1996 --- perl5_003_01/perly.y Sat Jul 6 09:03:14 1996 *************** *** 267,274 **** { package(Nullop); } ; ! use : USE startsub WORD listexpr ';' ! { utilize($1, $2, $3, $4); } ; expr : expr ANDOP expr --- 267,274 ---- { package(Nullop); } ; ! use : USE startsub WORD WORD listexpr ';' ! { utilize($1, $2, $3, $4, $5); } ; expr : expr ANDOP expr #~ New Plan9 port diff -Pcr perl5_003/plan9/aperl perl5_003_01/plan9/aperl *** perl5_003/plan9/aperl Wed Dec 31 19:00:00 1969 --- perl5_003_01/plan9/aperl Mon Jul 15 16:39:22 1996 *************** *** 0 **** --- 1,7 ---- + #!/bin/rc + + # aperl: + # Executes perl command and alters stderr to produce Acme-friendly error messages + # Created 02-JUL-1996, Luther Huffman, lutherh@stratcom.com + + /bin/perl $* |[2] /bin/perl -pe 's/ line (\d+)/:$1/' >[1=2] #~ New Plan9 port diff -Pcr perl5_003/plan9/arpa/inet.h perl5_003_01/plan9/arpa/inet.h *** perl5_003/plan9/arpa/inet.h Wed Dec 31 19:00:00 1969 --- perl5_003_01/plan9/arpa/inet.h Wed Jul 17 15:21:10 1996 *************** *** 0 **** --- 1,7 ---- + /* Declarations which would have been found in */ + /* On Plan 9, these are found in */ + + /* extern unsigned long inet_addr(const char *); */ + /* extern char *inet_ntoa(struct in_addr); */ + + #include diff -Pcr perl5_003/plan9/buildinfo perl5_003_01/plan9/buildinfo *** perl5_003/plan9/buildinfo Wed Dec 31 19:00:00 1969 --- perl5_003_01/plan9/buildinfo Mon Jul 15 16:39:22 1996 *************** *** 0 **** --- 1 ---- + p9pvers = 5.00301 #~ New Plan9 port diff -Pcr perl5_003/plan9/config.plan9 perl5_003_01/plan9/config.plan9 *** perl5_003/plan9/config.plan9 Wed Dec 31 19:00:00 1969 --- perl5_003_01/plan9/config.plan9 Tue Jul 16 15:26:12 1996 *************** *** 0 **** --- 1,1573 ---- + /* This file (config_H) is a sample config.h file. If you are unable + to successfully run Configure, copy this file to config.h and + edit it to suit your system. + */ + /* + * This file was produced by running the config_h.SH script, which + * gets its values from config.sh, which is generally produced by + * running Configure. + * + * Feel free to modify any of this as the need arises. Note, however, + * 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.U,v 3.0.1.4 1995/09/25 09:10:49 ram Exp $ + */ + + /* Configuration time: Thu Feb 8 17:15:11 EST 1996 + * Configured by: doughera + * Target system: sunos fractal 5.4 generic_101946-29 i86pc i386 + */ + + #ifndef _config_h_ + #define _config_h_ + + /* CAT2: + * This macro catenates 2 tokens together. + */ + + #define CAT2(a,b)a ## b + #define CAT3(a,b,c)a ## b ## c + #define CAT4(a,b,c,d)a ## b ## c ## d + #define CAT5(a,b,c,d,e)a ## b ## c ## d ## e + #define StGiFy(a)# a + #define STRINGIFY(a)StGiFy(a) + #define SCAT2(a,b)StGiFy(a) StGiFy(b) + #define SCAT3(a,b,c)StGiFy(a) StGiFy(b) StGiFy(c) + #define SCAT4(a,b,c,d)StGiFy(a) StGiFy(b) StGiFy(c) StGiFy(d) + #define SCAT5(a,b,c,d,e)StGiFy(a) StGiFy(b) StGiFy(c) StGiFy(d) StGiFy(e) + + /* config-start */ + + /* MEM_ALIGNBYTES: + * This symbol contains the number of bytes required to align a + * double. Usual values are 2, 4 and 8. + */ + #define MEM_ALIGNBYTES 8 /* config-skip */ + + /* 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 "/_P9P_OBJTYPE/bin" /* */ + + /* CPPSTDIN: + * This symbol contains the first part of the string which will invoke + * the C preprocessor on the standard input and produce to standard + * output. Typical value of "cc -E" or "/lib/cpp", but it can also + * call a wrapper. See CPPRUN. + */ + /* CPPMINUS: + * This symbol contains the second part of the string which will invoke + * the C preprocessor on the standard input and produce to standard + * output. This symbol will have the value "-" if CPPSTDIN needs a minus + * to specify standard input, otherwise the value is "". + */ + #define CPPSTDIN "cpp" + #define CPPMINUS "" + + /* HAS_ALARM: + * This symbol, if defined, indicates that the alarm routine is + * available. + */ + #define HAS_ALARM /**/ + + /* HASATTRIBUTE: + * This symbol indicates the C compiler can check for function attributes, + * such as printf formats. This is normally only supported by GNU cc. + */ + #undef HASATTRIBUTE /* config-skip*/ + #ifndef HASATTRIBUTE + #define __attribute__(_arg_) + #endif + + /* HAS_BCMP: + * This symbol is defined if the bcmp() routine is available to + * compare blocks of memory. + */ + #define HAS_BCMP /**/ + + /* HAS_BCOPY: + * This symbol is defined if the bcopy() routine is available to + * copy blocks of memory. + */ + #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 /**/ + + /* CASTI32: + * This symbol is defined if the C compiler can cast negative + * or large floating point numbers to 32-bit ints. + */ + #undef CASTI32 /**/ + + /* CASTNEGFLOAT: + * This symbol is defined if the C compiler can cast negative + * numbers to unsigned longs, ints and shorts. + */ + /* CASTFLAGS: + * This symbol contains flags that say what difficulties the compiler + * has casting odd floating values to unsigned long: + * 0 = ok + * 1 = couldn't cast < 0 + * 2 = couldn't cast >= 0x80000000 + * 4 = couldn't cast in argument expression list + */ + #define CASTNEGFLOAT /**/ + #if _P9P_OBJTYPE == 386 + # define CASTFLAGS 2 /**/ /* config-skip */ + #else + # define CASTFLAGS 0 /**/ /* config-skip */ + #endif + + /* HAS_CHOWN: + * This symbol, if defined, indicates that the chown routine is + * available. + */ + #undef HAS_CHOWN /**/ + + /* HAS_CHROOT: + * This symbol, if defined, indicates that the chroot routine is + * available. + */ + #undef HAS_CHROOT /**/ + + /* HAS_CHSIZE: + * This symbol, if defined, indicates that the chsize routine is available + * to truncate files. You might need a -lx to get this routine. + */ + #undef HAS_CHSIZE /**/ + + /* VOID_CLOSEDIR: + * This symbol, if defined, indicates that the closedir() routine + * does not return a value. + */ + #define VOID_CLOSEDIR /**/ + + /* HASCONST: + * This symbol, if defined, indicates that this C compiler knows about + * the const type. There is no need to actually test for that symbol + * within your programs. The mere use of the "const" keyword will + * trigger the necessary tests. + */ + #define HASCONST /**/ + + /* HAS_CRYPT: + * This symbol, if defined, indicates that the crypt routine is available + * to encrypt passwords and the like. + */ + /* #define HAS_CRYPT /**/ + + /* HAS_CUSERID: + * This symbol, if defined, indicates that the cuserid routine is + * available to get character login names. + */ + #define HAS_CUSERID /**/ + + /* HAS_DBL_DIG: + * This symbol, if defined, indicates that this system's + * or defines the symbol DBL_DIG, which is the number + * of significant digits in a double precision number. If this + * symbol is not defined, a guess of 15 is usually pretty good. + */ + #undef HAS_DBL_DIG /* */ + + /* HAS_DIFFTIME: + * This symbol, if defined, indicates that the difftime routine is + * available. + */ + #define HAS_DIFFTIME /**/ + + /* HAS_DLERROR: + * This symbol, if defined, indicates that the dlerror routine is + * available to return a string describing the last error that + * occurred from a call to dlopen(), dlclose() or dlsym(). + */ + #undef HAS_DLERROR /**/ + + /* HAS_DUP2: + * This symbol, if defined, indicates that the dup2 routine is + * available to duplicate file descriptors. + */ + #define HAS_DUP2 /**/ + + /* HAS_FCHMOD: + * This symbol, if defined, indicates that the fchmod routine is available + * to change mode of opened files. If unavailable, use chmod(). + */ + #undef HAS_FCHMOD /**/ + + /* HAS_FCHOWN: + * This symbol, if defined, indicates that the fchown routine is available + * to change ownership of opened files. If unavailable, use chown(). + */ + #undef HAS_FCHOWN /**/ + + /* HAS_FCNTL: + * This symbol, if defined, indicates to the C program that + * the fcntl() function exists. + */ + #define HAS_FCNTL /**/ + + /* HAS_FGETPOS: + * This symbol, if defined, indicates that the fgetpos routine is + * available to get the file position indicator, similar to ftell(). + */ + #define HAS_FGETPOS /**/ + + /* FLEXFILENAMES: + * This symbol, if defined, indicates that the system supports filenames + * longer than 14 characters. + */ + #define FLEXFILENAMES /**/ + + /* HAS_FLOCK: + * This symbol, if defined, indicates that the flock routine is + * available to do file locking. + */ + #undef HAS_FLOCK /**/ + + /* HAS_FORK: + * This symbol, if defined, indicates that the fork routine is + * available. + */ + #define HAS_FORK /**/ + + /* HAS_FSETPOS: + * This symbol, if defined, indicates that the fsetpos routine is + * available to set the file position indicator, similar to fseek(). + */ + #define HAS_FSETPOS /**/ + + /* 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. + */ + #undef HAS_GETGROUPS /* config-skip */ + + /* HAS_GETHOSTENT: + * This symbol, if defined, indicates that the gethostent routine is + * available to lookup host names in some data base or other. + */ + #undef HAS_GETHOSTENT /* config-skip */ + + /* HAS_UNAME: + * This symbol, if defined, indicates that the C program may use the + * uname() routine to derive the host name. See also HAS_GETHOSTNAME + * and PHOSTNAME. + */ + #undef HAS_UNAME /**/ + + /* HAS_GETLOGIN: + * This symbol, if defined, indicates that the getlogin routine is + * available to get the login name. + */ + #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. + */ + #undef HAS_GETPGRP2 /**/ + + /* HAS_GETPPID: + * This symbol, if defined, indicates that the getppid routine is + * available to get the parent process ID. + */ + #define HAS_GETPPID /**/ + + /* HAS_GETPRIORITY: + * This symbol, if defined, indicates that the getpriority routine is + * available to get a process's priority. + */ + #undef HAS_GETPRIORITY /**/ + + /* HAS_HTONL: + * This symbol, if defined, indicates that the htonl() routine (and + * friends htons() ntohl() ntohs()) are available to do network + * order byte swapping. + */ + /* HAS_HTONS: + * This symbol, if defined, indicates that the htons() routine (and + * friends htonl() ntohl() ntohs()) are available to do network + * order byte swapping. + */ + /* HAS_NTOHL: + * This symbol, if defined, indicates that the ntohl() routine (and + * friends htonl() htons() ntohs()) are available to do network + * order byte swapping. + */ + /* HAS_NTOHS: + * This symbol, if defined, indicates that the ntohs() routine (and + * friends htonl() htons() ntohl()) are available to do network + * order byte swapping. + */ + #define HAS_HTONL /**/ + + #define HAS_HTONS /**/ + + #define HAS_NTOHL /**/ + + #define HAS_NTOHS /**/ + + /* HAS_ISASCII: + * This manifest constant lets the C program know that isascii + * is available. + */ + #undef HAS_ISASCII /**/ + + /* HAS_KILLPG: + * This symbol, if defined, indicates that the killpg routine is available + * to kill process groups. If unavailable, you probably should use kill + * with a negative process number. + */ + #undef HAS_KILLPG /**/ + + /* HAS_LINK: + * This symbol, if defined, indicates that the link routine is + * available to create hard links. + */ + #define HAS_LINK /**/ + + /* HAS_LOCALECONV: + * This symbol, if defined, indicates that the localeconv routine is + * available for numeric and monetary formatting conventions. + */ + #define HAS_LOCALECONV /**/ + + /* HAS_LOCKF: + * This symbol, if defined, indicates that the lockf routine is + * available to do file locking. + */ + #undef HAS_LOCKF /**/ + + /* HAS_LSTAT: + * This symbol, if defined, indicates that the lstat routine is + * available to do file stats on symbolic links. + */ + #define HAS_LSTAT /**/ + + /* HAS_MBLEN: + * This symbol, if defined, indicates that the mblen routine is available + * to find the number of bytes in a multibye character. + */ + #define HAS_MBLEN /**/ + + /* HAS_MBSTOWCS: + * This symbol, if defined, indicates that the mbstowcs routine is + * available to covert a multibyte string into a wide character string. + */ + #define HAS_MBSTOWCS /**/ + + /* HAS_MBTOWC: + * This symbol, if defined, indicates that the mbtowc routine is available + * to covert a multibyte to a wide character. + */ + #define HAS_MBTOWC /**/ + + /* HAS_MEMCMP: + * This symbol, if defined, indicates that the memcmp routine is available + * to compare blocks of memory. + */ + #define HAS_MEMCMP /**/ + + /* HAS_MEMCPY: + * This symbol, if defined, indicates that the memcpy routine is available + * to copy blocks of memory. + */ + #define HAS_MEMCPY /**/ + + /* HAS_MEMMOVE: + * This symbol, if defined, indicates that the memmove routine is available + * to copy potentially overlapping blocks of memory. This should be used + * only when HAS_SAFE_BCOPY is not defined. If neither is there, roll your + * own version. + */ + #define HAS_MEMMOVE /**/ + + /* HAS_MEMSET: + * This symbol, if defined, indicates that the memset routine is available + * to set blocks of memory. + */ + #define HAS_MEMSET /**/ + + /* HAS_MKDIR: + * This symbol, if defined, indicates that the mkdir routine is available + * to create directories. Otherwise you should fork off a new process to + * exec /bin/mkdir. + */ + #define HAS_MKDIR /**/ + + /* HAS_MKFIFO: + * This symbol, if defined, indicates that the mkfifo routine is + * available to create FIFOs. Otherwise, mknod should be able to + * do it for you. However, if mkfifo is there, mknod might require + * super-user privileges which mkfifo will not. + */ + #define HAS_MKFIFO /**/ + + /* HAS_MKTIME: + * This symbol, if defined, indicates that the mktime routine is + * available. + */ + #define HAS_MKTIME /**/ + + /* HAS_MSG: + * This symbol, if defined, indicates that the entire msg*(2) library is + * supported (IPC mechanism based on message queues). + */ + #undef HAS_MSG /**/ + + /* HAS_NICE: + * This symbol, if defined, indicates that the nice routine is + * available. + */ + #undef HAS_NICE /**/ + + /* HAS_OPEN3: + * This manifest constant lets the C program know that the three + * argument form of open(2) is available. + */ + #define HAS_OPEN3 /**/ + + /* HAS_PATHCONF: + * This symbol, if defined, indicates that pathconf() is available + * to determine file-system related limits and options associated + * with a given filename. + */ + /* HAS_FPATHCONF: + * This symbol, if defined, indicates that pathconf() is available + * to determine file-system related limits and options associated + * with a given open file descriptor. + */ + #define HAS_PATHCONF /**/ + #define HAS_FPATHCONF /**/ + + /* HAS_PAUSE: + * This symbol, if defined, indicates that the pause routine is + * available to suspend a process until a signal is received. + */ + #define HAS_PAUSE /**/ + + /* HAS_PIPE: + * This symbol, if defined, indicates that the pipe routine is + * available to create an inter-process channel. + */ + #define HAS_PIPE /**/ + + /* HAS_POLL: + * This symbol, if defined, indicates that the poll routine is + * available to poll active file descriptors. + */ + #undef HAS_POLL /**/ + + /* HAS_READDIR: + * This symbol, if defined, indicates that the readdir routine is + * available to read directory entries. You may have to include + * . See I_DIRENT. + */ + #define HAS_READDIR /**/ + + /* HAS_SEEKDIR: + * This symbol, if defined, indicates that the seekdir routine is + * available. You may have to include . See I_DIRENT. + */ + #undef HAS_SEEKDIR /**/ + + /* HAS_TELLDIR: + * This symbol, if defined, indicates that the telldir routine is + * available. You may have to include . See I_DIRENT. + */ + #undef HAS_TELLDIR /**/ + + /* HAS_REWINDDIR: + * This symbol, if defined, indicates that the rewinddir routine is + * available. You may have to include . See I_DIRENT. + */ + #define HAS_REWINDDIR /**/ + + /* HAS_READLINK: + * This symbol, if defined, indicates that the readlink routine is + * available to read the value of a symbolic link. + */ + #define HAS_READLINK /**/ + + /* HAS_RENAME: + * This symbol, if defined, indicates that the rename routine is available + * to rename files. Otherwise you should do the unlink(), link(), unlink() + * trick. + */ + #define HAS_RENAME /**/ + + /* HAS_RMDIR: + * This symbol, if defined, indicates that the rmdir routine is + * available to remove directories. Otherwise you should fork off a + * new process to exec /bin/rmdir. + */ + #define HAS_RMDIR /**/ + + /* HAS_SAFE_BCOPY: + * This symbol, if defined, indicates that the bcopy routine is available + * to copy potentially overlapping memory blocks. Otherwise you should + * probably use memmove() or memcpy(). If neither is defined, roll your + * own version. + */ + #undef HAS_SAFE_BCOPY /**/ + + /* HAS_SAFE_MEMCPY: + * This symbol, if defined, indicates that the memcpy routine is available + * to copy potentially overlapping memory blocks. Otherwise you should + * probably use memmove() or memcpy(). If neither is defined, roll your + * own version. + */ + #undef HAS_SAFE_MEMCPY /**/ + + /* HAS_SELECT: + * This symbol, if defined, indicates that the select routine is + * available to select active file descriptors. If the timeout field + * is used, may need to be included. + */ + #define HAS_SELECT /* config-skip */ + + /* HAS_SEM: + * This symbol, if defined, indicates that the entire sem*(2) library is + * supported. + */ + #undef HAS_SEM /**/ + + /* HAS_SETEGID: + * This symbol, if defined, indicates that the setegid routine is available + * to change the effective gid of the current program. + */ + #undef HAS_SETEGID /**/ + + /* HAS_SETEUID: + * This symbol, if defined, indicates that the seteuid routine is available + * to change the effective uid of the current program. + */ + #undef HAS_SETEUID /**/ + + /* HAS_SETLINEBUF: + * This symbol, if defined, indicates that the setlinebuf routine is + * available to change stderr or stdout from block-buffered or unbuffered + * to a line-buffered mode. + */ + #undef HAS_SETLINEBUF /**/ + + /* HAS_SETLOCALE: + * This symbol, if defined, indicates that the setlocale routine is + * available to handle locale-specific ctype implementations. + */ + #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(). + */ + #undef HAS_SETPGRP /**/ + #undef 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. + */ + #undef HAS_SETPGRP2 /**/ + + /* HAS_SETPRIORITY: + * This symbol, if defined, indicates that the setpriority routine is + * available to set a process's priority. + */ + #undef HAS_SETPRIORITY /**/ + + /* HAS_SETREGID: + * This symbol, if defined, indicates that the setregid routine is + * available to change the real and effective gid of the current + * process. + */ + /* HAS_SETRESGID: + * This symbol, if defined, indicates that the setresgid routine is + * available to change the real, effective and saved gid of the current + * process. + */ + #undef HAS_SETREGID /**/ + #undef HAS_SETRESGID /**/ + + /* HAS_SETREUID: + * This symbol, if defined, indicates that the setreuid routine is + * available to change the real and effective uid of the current + * process. + */ + /* HAS_SETRESUID: + * This symbol, if defined, indicates that the setresuid routine is + * available to change the real, effective and saved uid of the current + * process. + */ + #undef HAS_SETREUID /**/ + #undef HAS_SETRESUID /**/ + + /* HAS_SETRGID: + * This symbol, if defined, indicates that the setrgid routine is available + * to change the real gid of the current program. + */ + #undef HAS_SETRGID /**/ + + /* HAS_SETRUID: + * This symbol, if defined, indicates that the setruid routine is available + * to change the real uid of the current program. + */ + #undef HAS_SETRUID /**/ + + /* HAS_SETSID: + * This symbol, if defined, indicates that the setsid routine is + * available to set the process group ID. + */ + #define HAS_SETSID /**/ + + /* HAS_SHM: + * This symbol, if defined, indicates that the entire shm*(2) library is + * supported. + */ + #undef HAS_SHM /**/ + + /* Shmat_t: + * This symbol holds the return type of the shmat() system call. + * Usually set to 'void *' or 'char *'. + */ + /* HAS_SHMAT_PROTOTYPE: + * This symbol, if defined, indicates that the sys/shm.h includes + * a prototype for shmat(). Otherwise, it is up to the program to + * guess one. Shmat_t shmat _((int, Shmat_t, int)) is a good guess, + * but not always right so it should be emitted by the program only + * when HAS_SHMAT_PROTOTYPE is not defined to avoid conflicting defs. + */ + #undef Shmat_t /* config-skip */ + #undef HAS_SHMAT_PROTOTYPE /**/ + + /* HAS_SIGACTION: + * This symbol, if defined, indicates that Vr4's sigaction() routine + * is available. + */ + #define HAS_SIGACTION /**/ + + /* HAS_SOCKET: + * This symbol, if defined, indicates that the BSD socket interface is + * supported. + */ + /* HAS_SOCKETPAIR: + * This symbol, if defined, indicates that the BSD socketpair() call is + * supported. + */ + #define HAS_SOCKET /**/ + #define HAS_SOCKETPAIR /**/ + + /* USE_STAT_BLOCKS: + * This symbol is defined if this system has a stat structure declaring + * st_blksize and st_blocks. + */ + #undef USE_STAT_BLOCKS /**/ + + /* USE_STDIO_PTR: + * This symbol is defined if the _ptr and _cnt fields (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_ptr(fp) + * 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. + */ + #undef USE_STDIO_PTR /**/ + #undef 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 + * defined if USE_STDIO_PTR is defined. + */ + /* STDIO_PTR_LVALUE: + * This symbol is defined if the FILE_ptr macro can be used as an + * lvalue. + */ + /* FILE_cnt: + * This macro is used to access the _cnt field (or equivalent) of the + * FILE structure pointed to by its argument. This macro will always be + * defined if USE_STDIO_PTR is defined. + */ + /* STDIO_CNT_LVALUE: + * This symbol is defined if the FILE_cnt macro can be used as an + * lvalue. + */ + #ifdef USE_STDIO_PTR + #define FILE_ptr(fp) ((fp)->_ptr) + #define STDIO_PTR_LVALUE /**/ + #define FILE_cnt(fp) ((fp)->_cnt) + #define STDIO_CNT_LVALUE /**/ + #endif + + /* 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 + * defined if USE_STDIO_BASE is defined. + */ + /* FILE_bufsiz: + * This macro is used to determine the number of bytes in the I/O + * buffer pointed to by _base field (or equivalent) of the FILE + * structure pointed to its argument. This macro will always be defined + * if USE_STDIO_BASE is defined. + */ + #ifdef USE_STDIO_BASE + #define FILE_base(fp) ((fp)->_base) + #define FILE_bufsiz(fp) ((fp)->_cnt + (fp)->_ptr - (fp)->_base) + #endif + + /* HAS_STRCHR: + * This symbol is defined to indicate that the strchr()/strrchr() + * functions are available for string searching. If not, try the + * index()/rindex() pair. + */ + /* HAS_INDEX: + * This symbol is defined to indicate that the index()/rindex() + * functions are available for string searching. + */ + #define HAS_STRCHR /**/ + #undef HAS_INDEX /**/ + + /* HAS_STRCOLL: + * This symbol, if defined, indicates that the strcoll routine is + * available to compare strings using collating information. + */ + #define HAS_STRCOLL /**/ + + /* USE_STRUCT_COPY: + * This symbol, if defined, indicates that this C compiler knows how + * to copy structures. If undefined, you'll need to use a block copy + * routine of some sort instead. + */ + #define USE_STRUCT_COPY /**/ + + /* HAS_STRERROR: + * This symbol, if defined, indicates that the strerror routine is + * available to translate error numbers to strings. See the writeup + * of Strerror() in this file before you try to define your own. + */ + /* HAS_SYS_ERRLIST: + * This symbol, if defined, indicates that the sys_errlist array is + * available to translate error numbers to strings. The extern int + * sys_nerr gives the size of that table. + */ + /* Strerror: + * This preprocessor symbol is defined as a macro if strerror() is + * not available to translate error numbers to strings but sys_errlist[] + * array is there. + */ + #define HAS_STRERROR /**/ + #define HAS_SYS_ERRLIST /**/ + #define Strerror(e) strerror(e) + + /* HAS_STRXFRM: + * This symbol, if defined, indicates that the strxfrm() routine is + * available to transform strings. + */ + #define HAS_STRXFRM /**/ + + /* HAS_SYMLINK: + * This symbol, if defined, indicates that the symlink routine is available + * to create symbolic links. + */ + #define HAS_SYMLINK /**/ + + /* HAS_SYSCALL: + * This symbol, if defined, indicates that the syscall routine is + * available to call arbitrary system calls. If undefined, that's tough. + */ + #undef HAS_SYSCALL /**/ + + /* HAS_SYSCONF: + * This symbol, if defined, indicates that sysconf() is available + * to determine system related limits and options. + */ + #define HAS_SYSCONF /**/ + + /* HAS_SYSTEM: + * This symbol, if defined, indicates that the system routine is + * available to issue a shell command. + */ + #define HAS_SYSTEM /**/ + + /* HAS_TCGETPGRP: + * This symbol, if defined, indicates that the tcgetpgrp routine is + * available to get foreground process group ID. + */ + #define HAS_TCGETPGRP /**/ + + /* HAS_TCSETPGRP: + * This symbol, if defined, indicates that the tcsetpgrp routine is + * available to set foreground process group ID. + */ + #define HAS_TCSETPGRP /**/ + + /* Time_t: + * This symbol holds the type returned by time(). It can be long, + * or time_t on BSD sites (in which case should be + * included). + */ + #define Time_t time_t /* Time type */ + + /* HAS_TIMES: + * This symbol, if defined, indicates that the times() routine exists. + * Note that this became obsolete on some systems (SUNOS), which now + * use getrusage(). It may be necessary to include . + */ + #define HAS_TIMES /**/ + + /* HAS_TRUNCATE: + * This symbol, if defined, indicates that the truncate routine is + * available to truncate files. + */ + #undef HAS_TRUNCATE /**/ + + /* HAS_TZNAME: + * This symbol, if defined, indicates that the tzname[] array is + * available to access timezone names. + */ + #define HAS_TZNAME /**/ + + /* HAS_UMASK: + * This symbol, if defined, indicates that the umask routine is + * available to set and get the value of the file creation mask. + */ + #define HAS_UMASK /**/ + + /* HAS_VFORK: + * This symbol, if defined, indicates that vfork() exists. + */ + #undef HAS_VFORK /**/ + + /* Signal_t: + * This symbol's value is either "void" or "int", corresponding to the + * appropriate return type of a signal handler. Thus, you can declare + * a signal handler using "Signal_t (*handler)()", and define the + * handler using "Signal_t handler(sig)". + */ + #define Signal_t void /* Signal handler's return type */ + + /* HASVOLATILE: + * This symbol, if defined, indicates that this C compiler knows about + * the volatile declaration. + */ + #define HASVOLATILE /**/ + #ifndef HASVOLATILE + #define volatile /* config-skip */ + #endif + + /* HAS_VPRINTF: + * This symbol, if defined, indicates that the vprintf routine is available + * to printf with a pointer to an argument list. If unavailable, you + * may need to write your own, probably in terms of _doprnt(). + */ + /* USE_CHAR_VSPRINTF: + * This symbol is defined if this system has vsprintf() returning type + * (char*). The trend seems to be to declare it as "int vsprintf()". It + * is up to the package author to declare vsprintf correctly based on the + * symbol. + */ + #define HAS_VPRINTF /**/ + #define USE_CHAR_VSPRINTF /**/ + + /* HAS_WAIT4: + * This symbol, if defined, indicates that wait4() exists. + */ + #undef HAS_WAIT4 /**/ + + /* HAS_WAITPID: + * This symbol, if defined, indicates that the waitpid routine is + * available to wait for child process. + */ + #undef HAS_WAITPID /**/ + + /* HAS_WCSTOMBS: + * This symbol, if defined, indicates that the wcstombs routine is + * available to convert wide character strings to multibyte strings. + */ + #define HAS_WCSTOMBS /**/ + + /* HAS_WCTOMB: + * This symbol, if defined, indicates that the wctomb routine is available + * to covert a wide character to a multibyte. + */ + #define HAS_WCTOMB /**/ + + /* Fpos_t: + * This symbol holds the type used to declare file positions in libc. + * It can be fpos_t, long, uint, etc... It may be necessary to include + * to get any typedef'ed information. + */ + #define Fpos_t fpos_t /* File position type */ + + /* Gid_t: + * This symbol holds the return type of getgid() and the type of + * argument to setrgid() and related functions. Typically, + * it is the type of group ids in the kernel. It can be int, ushort, + * uid_t, etc... It may be necessary to include to get + * any typedef'ed information. + */ + #define Gid_t gid_t /* config-skip */ + + /* Groups_t: + * This symbol holds the type used for the second argument to + * getgroups(). 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 to get any + * typedef'ed information. This is only required if you have + * getgroups(). + */ + #ifdef HAS_GETGROUPS + #define Groups_t gid_t /* Type for 2nd arg to getgroups() */ + #endif + + /* DB_Prefix_t: + * This symbol contains the type of the prefix structure element + * in the header file. In older versions of DB, it was + * int, while in newer ones it is u_int32_t. + */ + /* DB_Hash_t: + * This symbol contains the type of the prefix structure element + * in the header file. In older versions of DB, it was + * int, while in newer ones it is size_t. + */ + #define DB_Hash_t int /**/ + #define DB_Prefix_t int /**/ + + /* I_DIRENT: + * This symbol, if defined, indicates to the C program that it should + * include . Using this symbol also triggers the definition + * of the Direntry_t define which ends up being 'struct dirent' or + * 'struct direct' depending on the availability of . + */ + /* DIRNAMLEN: + * This symbol, if defined, indicates to the C program that the length + * of directory entry names is provided by a d_namlen field. Otherwise + * you need to do strlen() on the d_name field. + */ + /* Direntry_t: + * This symbol is set to 'struct direct' or 'struct dirent' depending on + * whether dirent is available or not. You should use this pseudo type to + * portably declare your directory entries. + */ + #define I_DIRENT /**/ + #undef DIRNAMLEN /**/ + #define Direntry_t struct dirent + + /* I_DLFCN: + * This symbol, if defined, indicates that exists and should + * be included. + */ + #undef I_DLFCN /**/ + + /* I_FCNTL: + * This manifest constant tells the C program to include . + */ + #define I_FCNTL /**/ + + /* I_FLOAT: + * This symbol, if defined, indicates to the C program that it should + * include to get definition of symbols like DBL_MAX or + * DBL_MIN, i.e. machine dependent floating point values. + */ + #define I_FLOAT /**/ + + /* I_GRP: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + #define I_GRP /**/ + + /* I_LIMITS: + * This symbol, if defined, indicates to the C program that it should + * include to get definition of symbols like WORD_BIT or + * LONG_MAX, i.e. machine dependant limitations. + */ + #define I_LIMITS /**/ + + /* I_MATH: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + #define I_MATH /**/ + + /* I_MEMORY: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + #undef I_MEMORY /**/ + + /* I_NDBM: + * This symbol, if defined, indicates that exists and should + * be included. + */ + #undef I_NDBM /**/ + + /* I_NET_ERRNO: + * This symbol, if defined, indicates that exists and + * should be included. + */ + #undef I_NET_ERRNO /* config-skip */ + + /* I_NETINET_IN: + * This symbol, if defined, indicates to the C program that it should + * include . Otherwise, you may try . + */ + #define I_NETINET_IN /* config-skip */ + + /* I_PWD: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + /* PWQUOTA: + * This symbol, if defined, indicates to the C program that struct passwd + * contains pw_quota. + */ + /* PWAGE: + * This symbol, if defined, indicates to the C program that struct passwd + * contains pw_age. + */ + /* PWCHANGE: + * This symbol, if defined, indicates to the C program that struct passwd + * contains pw_change. + */ + /* PWCLASS: + * This symbol, if defined, indicates to the C program that struct passwd + * contains pw_class. + */ + /* PWEXPIRE: + * This symbol, if defined, indicates to the C program that struct passwd + * contains pw_expire. + */ + /* PWCOMMENT: + * This symbol, if defined, indicates to the C program that struct passwd + * contains pw_comment. + */ + #define I_PWD /**/ + #undef PWQUOTA /**/ + #undef PWAGE /**/ + #undef PWCHANGE /**/ + #undef PWCLASS /**/ + #undef PWEXPIRE /**/ + #undef PWCOMMENT /**/ + + /* I_STDDEF: + * This symbol, if defined, indicates that exists and should + * be included. + */ + #define I_STDDEF /**/ + + /* I_STDLIB: + * This symbol, if defined, indicates that exists and should + * be included. + */ + #define I_STDLIB /**/ + + /* I_STRING: + * This symbol, if defined, indicates to the C program that it should + * include (USG systems) instead of (BSD systems). + */ + #define I_STRING /**/ + + /* I_SYS_DIR: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + #undef I_SYS_DIR /**/ + + /* I_SYS_FILE: + * This symbol, if defined, indicates to the C program that it should + * include to get definition of R_OK and friends. + */ + #undef I_SYS_FILE /**/ + + /* I_SYS_IOCTL: + * This symbol, if defined, indicates that exists and should + * be included. Otherwise, include or . + */ + #define I_SYS_IOCTL /**/ + + /* I_SYS_NDIR: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + #undef I_SYS_NDIR /**/ + + /* I_SYS_PARAM: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + #define I_SYS_PARAM /**/ + + /* Plan 9: file position in Plan 9 is */ + /* I_SYS_SELECT: + * This symbol, if defined, indicates to the C program that it should + * include in order to get definition of struct timeval. + */ + #undef I_SYS_SELECT /**/ + + /* I_SYS_TIMES: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + #define I_SYS_TIMES /**/ + + /* I_SYS_TYPES: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + #define I_SYS_TYPES /**/ + + /* I_SYS_UN: + * This symbol, if defined, indicates to the C program that it should + * include to get UNIX domain socket definitions. + */ + #define I_SYS_UN /**/ + + /* I_TERMIO: + * This symbol, if defined, indicates that the program should include + * rather than . There are also differences in + * the ioctl() calls that depend on the value of this symbol. + */ + /* I_TERMIOS: + * This symbol, if defined, indicates that the program should include + * the POSIX termios.h rather than sgtty.h or termio.h. + * There are also differences in the ioctl() calls that depend on the + * value of this symbol. + */ + /* I_SGTTY: + * This symbol, if defined, indicates that the program should include + * rather than . There are also differences in + * the ioctl() calls that depend on the value of this symbol. + */ + #undef I_TERMIO /**/ + #define I_TERMIOS /**/ + #undef I_SGTTY /**/ + + /* Plan 9: P9 has both and */ + /* I_TIME: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + /* I_SYS_TIME: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + /* I_SYS_TIME_KERNEL: + * This symbol, if defined, indicates to the C program that it should + * include with KERNEL defined. + */ + #define I_TIME /**/ + #define I_SYS_TIME /**/ + #undef I_SYS_TIME_KERNEL /**/ + + /* I_UNISTD: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + #define I_UNISTD /**/ + + /* I_UTIME: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + #define I_UTIME /**/ + + /* I_VFORK: + * This symbol, if defined, indicates to the C program that it should + * include vfork.h. + */ + #undef I_VFORK /**/ + + /* 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 + * to get any typedef'ed information. + */ + #define Off_t off_t /* type */ + + /* Mode_t: + * This symbol holds the type used to declare file modes + * for systems calls. It is usually mode_t, but may be + * int or unsigned short. It may be necessary to include + * to get any typedef'ed information. + */ + #define Mode_t mode_t /* file mode parameter for system calls */ + + /* CAN_PROTOTYPE: + * If defined, this macro indicates that the C compiler can handle + * function prototypes. + */ + /* _: + * This macro is used to declare function parameters for folks who want + * to make declarations with prototypes using a different style than + * the above macros. Use double parentheses. For example: + * + * int main _((int argc, char *argv[])); + */ + #define CAN_PROTOTYPE /**/ + #ifdef CAN_PROTOTYPE + #define _(args) args /* config-skip */ + #else + #define _(args) () /* config-skip */ + #endif + + /* RANDBITS: + * This symbol contains the number of bits of random number the rand() + * function produces. Usual values are 15, 16, and 31. + */ + #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 "/bin" + + /* 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 + * is defined, and 'int *' otherwise. This is only useful if you + * have select(), of course. + */ + #define Select_fd_set_t fd_set * /**/ + + /* Size_t: + * This symbol holds the type used to declare length parameters + * for string functions. It is usually size_t, but may be + * unsigned long, int, etc. It may be necessary to include + * to get any typedef'ed information. + */ + #define Size_t size_t /* length paramater for string functions */ + + /* SSize_t: + * This symbol holds the type used by functions that return + * a count of bytes or an error condition. It must be a signed type. + * It is usually ssize_t, but may be long or int, etc. + * It may be necessary to include or + * to get any typedef'ed information. + * We will pick a type such that sizeof(SSize_t) == sizeof(Size_t). + */ + #define SSize_t ssize_t /* signed count of bytes */ + + /* STDCHAR: + * This symbol is defined to be the type of char used in stdio.h. + * It has the values "unsigned char" or "char". + */ + #define STDCHAR char /**/ + + /* Uid_t: + * This symbol holds the type used to declare user ids in the kernel. + * It can be int, ushort, uid_t, etc... It may be necessary to include + * to get any typedef'ed information. + */ + #define Uid_t uid_t /* UID type */ + + /* PLAN9: + This symbol, if defined, indicates that the program is running under the + * Plan 9 operating system. + */ + #define PLAN9 /**/ + + #define OSNAME "plan9" + + #define BIN_SH "/bin/rc" + + /* MYMALLOC: + * This symbol, if defined, indicates that we're using our own malloc. + */ + #undef MYMALLOC /**/ + + + #undef VMS + + /* LOC_SED: + * This symbol holds the complete pathname to the sed program. + */ + #define LOC_SED "/bin/sed" /**/ + + /* 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 "/_P9P_OBJTYPE/lib/perl/_P9P_VERSION" + + /* BYTEORDER: + * This symbol hold the hexadecimal constant defined in byteorder, + * i.e. 0x1234 or 0x4321, etc... + */ + #define BYTEORDER 0x1234 /* large digits for MSB */ + + /* CSH: + * This symbol, if defined, indicates that the C-shell exists. + * If defined, contains the full pathname of csh. + */ + #undef CSH /**/ + + /* DLSYM_NEEDS_UNDERSCORE: + * This symbol, if defined, indicates that we need to prepend an + * underscore to the symbol name before calling dlsym(). This only + * makes sense if you *have* dlsym, which we will presume is the + * case if you're using dl_dlopen.xs. + */ + #undef DLSYM_NEEDS_UNDERSCORE /* */ + + /* SETUID_SCRIPTS_ARE_SECURE_NOW: + * This symbol, if defined, indicates that the bug that prevents + * setuid scripts from being secure is not present in this kernel. + */ + /* DOSUID: + * This symbol, if defined, indicates that the C program should + * check the script that it is executing for setuid/setgid bits, and + * attempt to emulate setuid/setgid on systems that have disabled + * setuid #! scripts because the kernel can't do it securely. + * It is up to the package designer to make sure that this emulation + * is done securely. Among other things, it should do an fstat on + * the script it just opened to make sure it really is a setuid/setgid + * script, it should make sure the arguments passed correspond exactly + * to the argument on the #! line, and it should not trust any + * subprocesses to which it must pass the filename rather than the + * file descriptor of the script to be executed. + */ + #define SETUID_SCRIPTS_ARE_SECURE_NOW /**/ + #undef DOSUID /**/ + + /* Gconvert: + * This preprocessor macro is defined to convert a floating point + * number to a string without a trailing decimal point. This + * emulates the behavior of sprintf("%g"), but is sometimes much more + * efficient. If gconvert() is not available, but gcvt() drops the + * trailing decimal point, then gcvt() is used. If all else fails, + * a macro using sprintf("%g") is used. Arguments for the Gconvert + * macro are: value, number of digits, whether trailing zeros should + * be retained, and the output buffer. + * Possible values are: + * d_Gconvert='gconvert((x),(n),(t),(b))' + * d_Gconvert='gcvt((x),(n),(b))' + * d_Gconvert='sprintf((b),"%.*g",(n),(x))' + * The last two assume trailing zeros should not be kept. + */ + #define Gconvert(x,n,t,b) sprintf((b),"%.*g",(n),(x)) + + /* Sigjmp_buf: + * 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. + */ + /* Siglongjmp: + * This macro is used in the same way as siglongjmp(), but will invoke + * traditional longjmp() if siglongjmp isn't available. + */ + #define HAS_SIGSETJMP /**/ /* config-skip */ + #define Sigjmp_buf sigjmp_buf /* config-skip */ + #define Sigsetjmp(buf,save_mask) sigsetjmp(buf,save_mask) /* config-skip */ + #define Siglongjmp(buf,retval) siglongjmp(buf,retval) /* config-skip */ + + /* USE_DYNAMIC_LOADING: + * This symbol, if defined, indicates that dynamic loading of + * some sort is available. + */ + #undef USE_DYNAMIC_LOADING /**/ + + /* I_DBM: + * This symbol, if defined, indicates that exists and should + * be included. + */ + /* I_RPCSVC_DBM: + * This symbol, if defined, indicates that exists and + * should be included. + */ + #undef I_DBM /**/ + #undef I_RPCSVC_DBM /**/ + + /* I_LOCALE: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + #define I_LOCALE /**/ + + /* I_SYS_STAT: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + #define I_SYS_STAT /**/ + + /* I_STDARG: + * This symbol, if defined, indicates that exists and should + * be included. + */ + /* I_VARARGS: + * This symbol, if defined, indicates to the C program that it should + * include . + */ + #define I_STDARG /**/ + #undef 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 /**/ + + /* Free_t: + * This variable contains the return type of free(). It is usually + * void, but occasionally int. + */ + /* Malloc_t: + * This symbol is the type of pointer returned by malloc and realloc. + */ + #define Malloc_t void * /**/ + #define Free_t void /**/ + + /* 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 + + /* 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. + */ + #undef OLDARCHLIB_EXP /**/ + + /* 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 "/sys/lib/perl" /* */ + + /* SIG_NAME: + * This symbol contains a list of signal names in order of + * signal number. This is intended + * to be used as a static array initialization, like this: + * char *sig_name[] = { SIG_NAME }; + * The signals in the list are separated with commas, and each signal + * is surrounded by double quotes. There is no leading SIG in the signal + * name, i.e. SIGQUIT is known as "QUIT". + * Gaps in the signal numbers (up to NSIG) are filled in with NUMnn, + * etc., where nn is the actual signal number (e.g. NUM37). + * The signal number for sig_name[i] is stored in sig_num[i]. + * The last element is 0 to terminate the list with a NULL. This + * corresponds to the 0 at the end of the sig_num list. + */ + /* SIG_NUM: + * This symbol contains a list of signal numbers, in the same order as the + * SIG_NAME list. It is suitable for static array initialization, as in: + * int sig_num[] = { SIG_NUM }; + * The signals in the list are separated with commas, and the indices + * within that list and the SIG_NAME list match, so it's easy to compute + * the signal name from a number or vice versa at the price of a small + * dynamic linear lookup. + * Duplicates are allowed, but are moved to the end of the list. + * The signal number corresponding to sig_name[i] is sig_number[i]. + * if (i < NSIG) then sig_number[i] == i. + * 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","ABRT","FPE","KILL","SEGV","PIPE","ALRM","TERM","USR1","USR2","CHLD","CONT","STOP","TSTP","TTIN","TTOU",0 /* config-skip */ + #define SIG_NUM 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,0 /* config-skip */ + + /* 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 "/sys/lib/perl/site_perl" /* */ + + /* 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 "/_P9P_OBJTYPE/lib/perl/_P9P_VERSION/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 "#!/bin/perl" /**/ + + /* VOIDFLAGS: + * This symbol indicates how much support of the void type is given by this + * compiler. What various bits mean: + * + * 1 = supports declaration of void + * 2 = supports arrays of pointers to functions returning void + * 4 = supports comparisons between pointers to void functions and + * addresses of void functions + * 8 = suports declaration of generic void pointers + * + * The package designer should define VOIDUSED to indicate the requirements + * of the package. This can be done either by #defining VOIDUSED before + * including config.h, or by defining defvoidused in Myinit.U. If the + * latter approach is taken, only those flags will be tested. If the + * level of void support necessary is not present, defines void to int. + */ + #ifndef VOIDUSED + #define VOIDUSED 15 + #endif + #define VOIDFLAGS 15 + #if (VOIDFLAGS & VOIDUSED) != VOIDUSED + #define void int /* is void to be avoided? */ /* config-skip */ + #define M_VOID /* Xenix strikes again */ /* config-skip */ + #endif + + #endif #~ New Plan9 port diff -Pcr perl5_003/plan9/exclude perl5_003_01/plan9/exclude *** perl5_003/plan9/exclude Wed Dec 31 19:00:00 1969 --- perl5_003_01/plan9/exclude Wed Jul 17 20:37:00 1996 *************** *** 0 **** --- 1,29 ---- + comp/cpp.t + comp/script.t + io/argv.t + io/dup.t + io/fs.t + io/inplace.t + io/pipe.t + lib/anydbm.t + lib/dirhand.t + lib/filehand.t + lib/io_dup.t + lib/io_pipe.t + lib/io_sock.t + lib/io_tell.t + lib/io_udp.t + lib/posix.t + lib/safe1.t + lib/safe2.t + lib/socket.t + op/eval.t + op/exec.t + op/goto.t + op/magic.t + op/misc.t + op/oct.t + op/readdir.t + op/split.t + op/stat.t + op/tie.t #~ New Plan9 port diff -Pcr perl5_003/plan9/fndvers perl5_003_01/plan9/fndvers *** perl5_003/plan9/fndvers Wed Dec 31 19:00:00 1969 --- perl5_003_01/plan9/fndvers Tue Jul 16 11:29:13 1996 *************** *** 0 **** --- 1,9 ---- + #!/bin/rc + + . plan9/buildinfo + + ed config.plan9 <) { + push(@ARGV,split(/\|/,$_)); + } + close ARGS; + } + + if (-f "config.h") { $infile = "config.h"; $outdir = "../"; } + elsif (-f "plan9/config.h") { $infile = "plan9/config.h"; $outdir = "./"; } + + if ($infile) { print "Generating config.sh from $infile . . .\n"; } + else { die <${outdir}config.sh") || die "Can't open ${outdir}config.sh: $!\n"; + + $time = localtime; + $cf_by = $ENV{'user'}; + ($vers = $]) =~ tr/./_/; + + # Plan 9 doesn't actually use version numbering. Following the original Unix + # precedent of assigning a Unix edition number based on the edition number + # of the manuals, I am referring to this as Plan 9, 1st edition. + $osvers = '1'; + + print OUT <) { + next unless m%^#(?!if).*\$%; + s/^#//; s!(.*?)\s*/\*.*!$1!; + my(@words) = split; + $words[1] =~ s/\(.*//; # Clip off args from macro + # Did we use a shell variable for the preprocessor directive? + if ($words[0] =~ m!^\$(\w+)!) { $pp_vars{$words[1]} = $1; } + if (@words > 2) { # We may also have a shell var in the value + shift @words; # Discard preprocessor directive + my($token) = shift @words; # and keep constant name + my($word); + foreach $word (@words) { + next unless $word =~ m!\$(\w+)!; + $val_vars{$token} = $1; + last; + } + } + } + close SH; + } + else { warn "Couldn't read ${outfile}config_h.SH: $!\n"; } + $pp_vars{PLAN9} = 'define'; #Plan 9 specific + + # OK, now read the C header file, and retcon statements into config.sh + while () { # roll through the comment header in config.h + last if /config-start/; + } + + while () { + chop; + while (/\\\s*$/) { # pick up contination lines + my $line = $_; + $line =~ s/\\\s*$//; + $_ = ; + s/^\s*//; + $_ = $line . $_; + } + next unless my ($blocked,$un,$token,$val) = + m%^(\/\*)?\s*\#\s*(un)?def\w*\s+([A-Za-z0-9]\w+)\S*\s*(.*)%; + if (/config-skip/) { + delete $pp_vars{$token} if exists $pp_vars{$token}; + delete $val_vars{$token} if exists $val_vars{$token}; + next; + } + $val =~ s!\s*/\*.*!!; # strip off trailing comment + my($had_val); # Maybe a macro with args that we just #undefd or commented + if (!length($val) and $val_vars{$token} and ($un || $blocked)) { + print OUT "$val_vars{$token}=''\n"; + delete $val_vars{$token}; + $had_val = 1; + } + $state = ($blocked || $un) ? 'undef' : 'define'; + if ($pp_vars{$token}) { + print OUT "$pp_vars{$token}='$state'\n"; + delete $pp_vars{$token}; + } + elsif (not length $val and not $had_val) { + # Wups -- should have been shell var for C preprocessor directive + warn "Constant $token not found in config_h.SH\n"; + $token =~ tr/A-Z/a-z/; + $token = "d_$token" unless $token =~ /^i_/; + print OUT "$token='$state'\n"; + } + next unless length $val; + $val =~ s/^"//; $val =~ s/"$//; # remove end quotes + $val =~ s/","/ /g; # make signal list look nice + + if ($val_vars{$token}) { + print OUT "$val_vars{$token}='$val'\n"; + if ($val_vars{$token} =~ s/exp$//) {print OUT "$val_vars{$token}='$val'\n";} + delete $val_vars{$token}; + } + elsif (!$pp_vars{$token}) { # Haven't seen it previously, either + warn "Constant $token not found in config_h.SH (val=|$val|)\n"; + $token =~ tr/A-Z/a-z/; + print OUT "$token='$val'\n"; + if ($token =~ s/exp$//) {print OUT "$token='$val'\n";} + } + } + close IN; + + foreach (sort keys %pp_vars) { + warn "Didn't see $_ in $infile\n"; + } + foreach (sort keys %val_vars) { + warn "Didn't see $_ in $infile(val)\n"; + } + + + # print OUT "libs='",join(' ',@libs),"'\n"; + # print OUT "libc='",join(' ',@crtls),"'\n"; + + if (open(PL,"${outdir}patchlevel.h")) { + while () { + if (/^#define PATCHLEVEL\s+(\S+)/) { print OUT "PATCHLEVEL='$1'\n"; } + elsif (/^#define SUBVERSION\s+(\S+)/) { print OUT "SUBVERSION='$1'\n"; } + } + close PL; + } + else { warn "Can't read ${outdir}patchlevel.h - skipping 'PATCHLEVEL'"; } + + print OUT "pager='/bin/p'\n"; + + close OUT; + + #~ New Plan9 port diff -Pcr perl5_003/plan9/mkfile perl5_003_01/plan9/mkfile *** perl5_003/plan9/mkfile Wed Dec 31 19:00:00 1969 --- perl5_003_01/plan9/mkfile Fri Jul 26 16:53:27 1996 *************** *** 0 **** --- 1,149 ---- + Content-type: text/plain; charset="us-ascii" + Content-disposition: attachment; filename="mkfile" + + APE=/sys/src/ape + < $APE/config + $target + cp ext/IO/*.pm $privlib + if (test !-d $privlib/IO) mkdir $privlib/IO + cp ext/IO/lib/IO/*.pm $privlib/IO + + Socket.$O: config.h Socket.c + $CCCMD -I plan9 Socket.c + + Socket.c: miniperl ext/Socket/Socket.xs + ./miniperl $privlib/ExtUtils/xsubpp -noprototypes -typemap $privlib/ExtUtils/typemap ext/Socket/Socket.xs > $target + cp ext/Socket/Socket.pm $privlib + + Opcode.c: miniperl ext/Opcode/Opcode.xs + ./miniperl $privlib/ExtUtils/xsubpp -noprototypes -typemap $privlib/ExtUtils/typemap ext/Opcode/Opcode.xs > $target + cp ext/Opcode/*.pm $privlib + + Fcntl.c: miniperl ext/Fcntl/Fcntl.xs + ./miniperl $privlib/ExtUtils/xsubpp -noprototypes -typemap $privlib/ExtUtils/typemap ext/Fcntl/Fcntl.xs > $target + cp ext/Fcntl/Fcntl.pm $privlib + + FileHandle.c: miniperl ext/FileHandle/FileHandle.xs + ./miniperl $privlib/ExtUtils/xsubpp -noprototypes -typemap $privlib/ExtUtils/typemap ext/FileHandle/FileHandle.xs > $target + cp ext/FileHandle/FileHandle.pm $privlib + + POSIX.c: miniperl ext/POSIX/POSIX.xs + ./miniperl $privlib/ExtUtils/xsubpp -noprototypes -typemap $privlib/ExtUtils/typemap ext/POSIX/POSIX.xs > $target + cp ext/POSIX/POSIX.pm $privlib + + dl_none.c: miniperl ext/DynaLoader/dl_none.xs + ./miniperl $privlib/ExtUtils/xsubpp -noprototypes -typemap $privlib/ExtUtils/typemap ext/DynaLoader/dl_none.xs > $target + cp ext/DynaLoader/DynaLoader.pm $privlib + + test:V: + bind -b $privlib $sourcedir/lib + bind -b $archlib $sourcedir/lib + cd $sourcedir/t + rm -f perl + cp /$objtype/bin/perl $sourcedir/t + perl TEST `{ ls */*.t | comm -23 - ../plan9/exclude } + + plan9.$O: config.h ./plan9/plan9.c + cp ./plan9/plan9.c ./plan9.c + $CCCMD plan9.c + + %.$O: config.h %.c + $CCCMD $stem.c + + $archlib/Config.pm: miniperl config.sh + ./miniperl configpm $archlib/Config.pm + + config.sh: miniperl config.h + ./miniperl ./plan9/genconfig.pl + + installall:V: + for (objtype in 386 mips 68020 sparc) mk install + + man:V: $perlpods pod/pod2man.PL perl + perl pod/pod2man.PL + for (i in $podnames) pod/pod2man pod/$i.pod > $installman3dir/$i + pod/pod2man plan9/perlplan9.pod > $installman3dir/perlplan9 + + nuke:V: + rm -f *.$O $extensions^.pm config.sh $perllib config.h $perlshr perlmain.c perl miniperl $archlib/Config.pm $ext_c + + clean:V: + rm -f *.$O config.sh miniperl t/perl + + deleteman:V: + rm -f $installman1dir/perl* $installman3dir/perl* #~ New Plan9 port diff -Pcr perl5_003/plan9/myconfig.plan9 perl5_003_01/plan9/myconfig.plan9 *** perl5_003/plan9/myconfig.plan9 Wed Dec 31 19:00:00 1969 --- perl5_003_01/plan9/myconfig.plan9 Mon Jul 15 16:39:22 1996 *************** *** 0 **** --- 1,39 ---- + #!/bin/rc + + # This script is designed to provide a handy summary of the configuration + # information being used to build perl. This is especially useful if you + # are requesting help from comp.lang.perl.misc on usenet or via mail. + + #This script is the "myconfig" script altered to run on Plan 9. + #Last Modified: 28-Jun-96 Luther Huffman lutherh@stratcom.com + + + . config.sh + + # Note that the text lines /^Summary of/ .. /^\s*$/ are copied into Config.pm. + # XXX Add d_sigaction (?) once it's defined. + + $spitshell<. Most perl scripts, however, do have a first line + such as "#!/usr/local/bin/perl". This is known as a shebang + (shell-bang) statement and tells the OS shell where to find + the perl interpreter. In Plan 9 Perl this statement should be + "#!/bin/perl" if you wish to be able to directly invoke the + script by its name. + Alternatively, you may invoke perl with the command "aperl" + instead of "perl". This will produce Acme-friendly error + messages of the form "filename:18". + + Some scripts, usually identified with a *.PL extension, are + self-configuring and are able to correctly create their own + shebang path from config information located in Plan 9 + Perl. These you won't need to be worried about. + + =head2 What's in Plan 9 Perl + + Although Plan 9 Perl currently only provides static + loading, it is built with a number of useful extensions. + These include Safe, FileHandle, Fcntl, and POSIX. Expect + to see others (and DynaLoading!) in the future. + + =head2 What's not in Plan 9 Perl + + As mentioned previously, dynamic loading isn't currently + available nor is MakeMaker. Both are high-priority items. + + =head2 Perl5 Functions not currently supported + + Some, such as C and C aren't provided + because the concept does not exist within Plan 9. Others, + such as some of the socket-related functions, simply + haven't been written yet. Many in the latter category + may be supported in the future. + + The functions not currently implemented include: + + chown, chroot, dbmclose, dbmopen, getsockopt, + setsockopt, recvmsg, sendmsg, getnetbyname, + getnetbyaddr, getnetent, getprotoent, getservent, + sethostent, setnetent, setprotoent, setservent, + endservent, endnetent, endprotoent, umask + + There may be several other functions that have undefined + behavior so this list shouldn't be considered complete. + + =head2 Signals + + For compatibility with perl scripts written for the Unix + environment, Plan 9 Perl uses the POSIX signal emulation + provided in Plan 9's ANSI POSIX Environment (APE). Signal stacking + isn't supported. The signals provided are: + + SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, + SIGFPE, SIGKILL, SIGSEGV, SIGPIPE, SIGPIPE, SIGALRM, + SIGTERM, SIGUSR1, SIGUSR2, SIGCHLD, SIGCONT, + SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU + + =head1 BUGS + + "As many as there are grains of sand on all the beaches of the + world . . ." - Carl Sagan + + =head1 Revision date + + This document was revised 04-July-1996 for Perl 5.003_1. + + =head1 AUTHOR + + Luther Huffman, lutherh@stratcom.com \ No newline at end of file #~ New Plan9 port diff -Pcr perl5_003/plan9/plan9.c perl5_003_01/plan9/plan9.c *** perl5_003/plan9/plan9.c Wed Dec 31 19:00:00 1969 --- perl5_003_01/plan9/plan9.c Wed Jul 17 15:16:52 1996 *************** *** 0 **** --- 1,134 ---- + #include "EXTERN.h" + #include "perl.h" + + /* Functions mentioned in but not implemented */ + + int getsockopt(int a, int b, int c, void *d, int *e) + { + croak("Function \"getsockopt\" not implemented in this version of perl."); + return (int)NULL; + } + + int setsockopt(int a, int b, int c, void *d, int *e) + { + croak("Function \"setsockopt\" not implemented in this version of perl."); + return (int)NULL; + } + + + int recvmsg(int a, struct msghdr *b, int c) + { + croak("Function \"recvmsg\" not implemented in this version of perl."); + return (int)NULL; + } + + int sendmsg(int a, struct msghdr *b, int c) + { + croak("Function \"sendmsg\" not implemented in this version of perl."); + return (int)NULL; + } + + + /* Functions mentioned in but not implemented */ + struct netent *getnetbyname(const char *a) + { + croak("Function \"getnetbyname\" not implemented in this version of perl."); + return (struct netent *)NULL; + } + + struct netent *getnetbyaddr(long a, int b) + { + croak("Function \"getnetbyaddr\" not implemented in this version of perl."); + return (struct netent *)NULL; + } + + struct netent *getnetent() + { + croak("Function \"getnetent\" not implemented in this version of perl."); + return (struct netent *)NULL; + } + + struct protoent *getprotobyname(const char *a) + { + croak("Function \"getprotobyname\" not implemented in this version of perl."); + return (struct protoent *)NULL; + } + + struct protoent *getprotobynumber(int a) + { + croak("Function \"getprotobynumber\" not implemented in this version of perl."); + return (struct protoent *)NULL; + } + + struct protoent *getprotoent() + { + croak("Function \"getprotoent\" not implemented in this version of perl."); + return (struct protoent *)NULL; + } + + struct servent *getservbyport(int a, const char *b) + { + croak("Function \"getservbyport\" not implemented in this version of perl."); + return (struct servent *)NULL; + } + + struct servent *getservent() + { + croak("Function \"getservent\" not implemented in this version of perl."); + return (struct servent *)NULL; + } + + void sethostent(int a) + { + croak("Function \"sethostent\" not implemented in this version of perl."); + } + + void setnetent(int a) + { + croak("Function \"setnetent\" not implemented in this version of perl."); + } + + void setprotoent(int a) + { + croak("Function \"setprotoent\" not implemented in this version of perl."); + } + + void setservent(int a) + { + croak("Function \"setservent\" not implemented in this version of perl."); + } + + void endnetent() + { + croak("Function \"endnetent\" not implemented in this version of perl."); + } + + void endprotoent() + { + croak("Function \"endprotoent\" not implemented in this version of perl."); + } + + void endservent() + { + croak("Function \"endservent\" not implemented in this version of perl."); + } + + int tcdrain(int) + { + croak("Function \"tcdrain\" not implemented in this version of perl."); + } + + int tcflow(int, int) + { + croak("Function \"tcflow\" not implemented in this version of perl."); + } + + int tcflush(int, int) + { + croak("Function \"tcflush\" not implemented in this version of perl."); + } + + int tcsendbreak(int, int) + { + croak("Function \"tcsendbreak\" not implemented in this version of perl."); + } #~ New Plan9 port diff -Pcr perl5_003/plan9/plan9ish.h perl5_003_01/plan9/plan9ish.h *** perl5_003/plan9/plan9ish.h Wed Dec 31 19:00:00 1969 --- perl5_003_01/plan9/plan9ish.h Thu Jul 25 16:13:19 1996 *************** *** 0 **** --- 1,113 ---- + #ifndef __PLAN9ISH_H__ + #define __PLAN9ISH_H__ + + /* + * The following symbols are defined if your operating system supports + * functions by that name. All Unixes I know of support them, thus they + * are not checked by the configuration script, but are directly defined + * here. + */ + + /* HAS_IOCTL: + * This symbol, if defined, indicates that the ioctl() routine is + * available to set I/O characteristics + */ + #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 /**/ + + /* HAS_GROUP + * This symbol, if defined, indicates that the getgrnam(), + * getgrgid(), and getgrent() routines are available to + * get group entries. + */ + /*#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_KILL + #define HAS_WAIT + + /* 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 /**/ + + /* PLAN9: + * This symbol, if defined, indicates that the program is running under + * Plan 9. + */ + #ifndef PLAN9 + #define PLAN9 /**/ + #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 + */ + #undef 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. + */ + #define ACME_MESS /**/ + + #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX) + # include + #endif + + #ifndef SIGABRT + # define SIGABRT SIGILL + #endif + #ifndef SIGILL + # define SIGILL 6 /* blech */ + #endif + #define ABORT() kill(getpid(),SIGABRT); + + #define BIT_BUCKET "/dev/null" + #define PERL_SYS_INIT(c,v) + #define dXSUB_SYS int dummy + #define PERL_SYS_TERM() + + /* + * 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 + * fwrite() itself, which on some systems outputs several distinct records + * if the number_of_items parameter is >1). + */ + #define fwrite1 fwrite + + #define Stat(fname,bufptr) stat((fname),(bufptr)) + #define Fstat(fd,bufptr) fstat((fd),(bufptr)) + #define Fflush(fp) fflush(fp) + + /* getenv related stuff */ + #define my_getenv(var) getenv(var) + /* Plan 9 prefers getenv("home") to getenv("HOME") + #define HOME home + + /* For use by POSIX.xs */ + extern int tcsendbreak(int, int); + + #endif /* __PLAN9ISH_H__ */ #~ New Plan9 port diff -Pcr perl5_003/plan9/setup.rc perl5_003_01/plan9/setup.rc *** perl5_003/plan9/setup.rc Wed Dec 31 19:00:00 1969 --- perl5_003_01/plan9/setup.rc Wed Jul 17 08:26:54 1996 *************** *** 0 **** --- 1,48 ---- + #!/bin/rc + # This is an rc shell script which unpacks the perl distribution, builds + # directories, and puts files where they belong. + # To use, just run it from within the plan9 subdirectory with the appropriate + # permissions. + # Last modified 6/30/96 by: + # Luther Huffman, Strategic Computer Solutions, Inc., lutherh@stratcom.com + + . buildinfo + builddir = `{ cd .. ; pwd } + if(flag a) platforms = (386 mips sparc 68020) + if not platforms = $objtype + sourcedir=/sys/src/cmd/perl/$p9pvers + privlib=/sys/lib/perl + sitelib=$privlib/site_perl + + #Build source directory + if (test ! -d /sys/src/cmd/perl) mkdir /sys/src/cmd/perl + if (test ! -d $sourcedir) mkdir $sourcedir + + #Populate source directory + echo Building source directories ... + {cd $builddir ; tar c .} | { cd $sourcedir ; tar x} + cp $builddir/plan9/config.plan9 $sourcedir/config.plan9 + cp $builddir/plan9/plan9.c $builddir/plan9/plan9ish.h $builddir/plan9/mkfile $sourcedir + cd $sourcedir/lib ; rm -rf * + + #Build library directories + echo Building library directories ... + if (test ! -d $privlib) mkdir $privlib + if (test ! -d $privlib/auto) mkdir $privlib/auto + if (test ! -d $sitelib) mkdir $sitelib + for(i in $platforms){ + archlib=/$i/lib/perl/$p9pvers + sitearch=$archlib/site_perl + corelib=$archlib/CORE + arpalib=$corelib/arpa + if (test ! -d /$i/lib/perl) mkdir /$i/lib/perl + if (test ! -d $archlib) mkdir $archlib + if (test ! -d $sitearch) mkdir $sitearch + if (test ! -d $corelib) mkdir $corelib + if (test ! -d $arpalib) mkdir $arpalib + cp $builddir/*.h $builddir/plan9/*.h $corelib + cp $builddir/plan9/arpa/*.h $arpalib + } + + #Populate library directories + {cd $builddir/lib ; tar c . } | {cd $privlib ; tar x } #~ Replace unclear term "identifier" with "variable name" diff -Pcr perl5_003/pod/perl.pod perl5_003_01/pod/perl.pod *** perl5_003/pod/perl.pod Mon Mar 25 01:05:09 1996 --- perl5_003_01/pod/perl.pod Wed May 1 20:19:18 1996 *************** *** 296,302 **** While none of the built-in data types have any arbitrary size limits (apart from memory size), there are still a few arbitrary limits: a ! given identifier may not be longer than 255 characters, and no component of your PATH may be longer than 255 if you use B<-S>. A regular expression may not compile to more than 32767 bytes internally. --- 296,302 ---- While none of the built-in data types have any arbitrary size limits (apart from memory size), there are still a few arbitrary limits: a ! given variable name may not be longer than 255 characters, and no component of your PATH may be longer than 255 if you use B<-S>. A regular expression may not compile to more than 32767 bytes internally. #~ Quote string argument in example -- necessary if using strict subs diff -Pcr perl5_003/pod/perlbot.pod perl5_003_01/pod/perlbot.pod *** perl5_003/pod/perlbot.pod Mon Feb 12 14:58:13 1996 --- perl5_003_01/pod/perlbot.pod Mon Jul 15 13:36:25 1996 *************** *** 277,287 **** package main; use Fcntl qw( O_RDWR O_CREAT ); ! tie %foo, Mydbm, "Sdbm", O_RDWR|O_CREAT, 0640; $foo{'bar'} = 123; print "foo-bar = $foo{'bar'}\n"; ! tie %bar, Mydbm, "Sdbm2", O_RDWR|O_CREAT, 0640; $bar{'Cathy'} = 456; print "bar-Cathy = $bar{'Cathy'}\n"; --- 277,287 ---- package main; use Fcntl qw( O_RDWR O_CREAT ); ! tie %foo, "Mydbm", "Sdbm", O_RDWR|O_CREAT, 0640; $foo{'bar'} = 123; print "foo-bar = $foo{'bar'}\n"; ! tie %bar, "Mydbm", "Sdbm2", O_RDWR|O_CREAT, 0640; $bar{'Cathy'} = 456; print "bar-Cathy = $bar{'Cathy'}\n"; *************** *** 522,527 **** package main; use Fcntl qw( O_RDWR O_CREAT ); ! tie %foo, Mydbm, "adbm", O_RDWR|O_CREAT, 0640; $foo{'bar'} = 123; print "foo-bar = $foo{'bar'}\n"; --- 522,527 ---- package main; use Fcntl qw( O_RDWR O_CREAT ); ! tie %foo, "Mydbm", "adbm", O_RDWR|O_CREAT, 0640; $foo{'bar'} = 123; print "foo-bar = $foo{'bar'}\n"; #~ More complete discussion of variable names #~ Correction of typos #~ More complete explanation of effect => has on left-hand expression diff -Pcr perl5_003/pod/perldata.pod perl5_003_01/pod/perldata.pod *** perl5_003/pod/perldata.pod Mon Mar 25 01:05:12 1996 --- perl5_003_01/pod/perldata.pod Mon Jun 17 18:30:14 1996 *************** *** 11,16 **** --- 11,38 ---- indexed by number, starting with 0. (Negative subscripts count from the end.) Hash arrays are indexed by string. + Values are usually referred to by name (or through a named reference). + The first character of the name tells you to what sort of data + structure it refers. The rest of the name tells you the particular + value to which it refers. Most often, it consists of a single + I, that is, a string beginning with a letter or underscore, + and containing letters, underscores, and digits. In some cases, it + may be a chain of identifiers, separated by C<::> (or by C<'>, but + that's deprecated); all but the last are interpreted as names of + packages, in order to locate the namespace in which to look + up the final identifier (see L for details). + It's possible to substutite for a simple identifier an expression + which produces a reference to the value at runtime; this is + described in more detail below, and in L. + + There are also special variables whose names don't follow these + rules, so that they don't accidentally collide with one of your + normal variables. Strings which match parenthesized parts of a + regular expression are saved under names containing only digits after + the C<$> (see L and L). In addition, several special + variables which provide windows into the inner working of Perl have names + containing punctuation characters (see L). + Scalar values are always named with '$', even when referring to a scalar that is part of an array. It works like the English word "the". Thus we have: *************** *** 122,128 **** type "filehandle", or anything else. Perl is a contextually polymorphic language whose scalars can be strings, numbers, or references (which includes objects). While strings and numbers are considered pretty ! much same thing for nearly all purposes, references are strongly-typed uncastable pointers with built-in reference-counting and destructor invocation. --- 144,150 ---- type "filehandle", or anything else. Perl is a contextually polymorphic language whose scalars can be strings, numbers, or references (which includes objects). While strings and numbers are considered pretty ! much the same thing for nearly all purposes, references are strongly-typed uncastable pointers with built-in reference-counting and destructor invocation. *************** *** 141,147 **** To find out whether a given string is a valid non-zero number, it's usually enough to test it against both numeric 0 and also lexical "0" (although this will cause B<-w> noises). That's because strings that aren't ! numbers count as 0, just as the do in I: if ($str == 0 && $str ne "0") { warn "That doesn't look like a number"; --- 163,169 ---- To find out whether a given string is a valid non-zero number, it's usually enough to test it against both numeric 0 and also lexical "0" (although this will cause B<-w> noises). That's because strings that aren't ! numbers count as 0, just as they do in I: if ($str == 0 && $str ne "0") { warn "That doesn't look like a number"; *************** *** 166,172 **** length of the array. Shortening an array by this method destroys intervening values. Lengthening an array that was previously shortened I recovers the values that were in those elements. (It used to ! in Perl 4, but we had to break this make to make sure destructors were called when expected.) You can also gain some measure of efficiency by preextending an array that is going to get big. (You can also extend an array by assigning to an element that is off the end of the array.) --- 188,194 ---- length of the array. Shortening an array by this method destroys intervening values. Lengthening an array that was previously shortened I recovers the values that were in those elements. (It used to ! in Perl 4, but we had to break this to make sure destructors were called when expected.) You can also gain some measure of efficiency by preextending an array that is going to get big. (You can also extend an array by assigning to an element that is off the end of the array.) *************** *** 230,243 **** another line containing the quote character, which may be much further on in the script. Variable substitution inside strings is limited to scalar variables, arrays, and array slices. (In other words, ! identifiers beginning with $ or @, followed by an optional bracketed expression as a subscript.) The following code segment prints out "The price is $100." $Price = '$100'; # not interpreted print "The price is $Price.\n"; # interpreted ! As in some shells, you can put curly brackets around the identifier to delimit it from following alphanumerics. In fact, an identifier within such curlies is forced to be a string, as is any single identifier within a hash subscript. Our earlier example, --- 252,265 ---- another line containing the quote character, which may be much further on in the script. Variable substitution inside strings is limited to scalar variables, arrays, and array slices. (In other words, ! names beginning with $ or @, followed by an optional bracketed expression as a subscript.) The following code segment prints out "The price is $100." $Price = '$100'; # not interpreted print "The price is $Price.\n"; # interpreted ! As in some shells, you can put curly brackets around the name to delimit it from following alphanumerics. In fact, an identifier within such curlies is forced to be a string, as is any single identifier within a hash subscript. Our earlier example, *************** *** 254,260 **** Note that a single-quoted string must be separated from a preceding word by a space, since single quote is a valid (though deprecated) character in ! an identifier (see L). Two special literals are __LINE__ and __FILE__, which represent the current line number and filename at that point in your program. They --- 276,282 ---- Note that a single-quoted string must be separated from a preceding word by a space, since single quote is a valid (though deprecated) character in ! a variable name (see L). Two special literals are __LINE__ and __FILE__, which represent the current line number and filename at that point in your program. They *************** *** 457,464 **** It is often more readable to use the C<=E> operator between key/value pairs. The C<=E> operator is mostly just a more visually distinctive ! synonym for a comma, but it also quotes its left-hand operand, which makes ! it nice for initializing hashes: %map = ( red => 0x00f, --- 479,487 ---- It is often more readable to use the C<=E> operator between key/value pairs. The C<=E> operator is mostly just a more visually distinctive ! synonym for a comma, but it also arranges for its left-hand operand to be ! interpreted as a string, if it's a bareword which would be a legal identifier. ! This makes it nice for initializing hashes: %map = ( red => 0x00f, #~ Extensive updates to debugger documentation: commands, output, new features diff -Pcr perl5_003/pod/perldebug.pod perl5_003_01/pod/perldebug.pod *** perl5_003/pod/perldebug.pod Tue Oct 18 12:39:18 1994 --- perl5_003_01/pod/perldebug.pod Mon Jul 15 14:38:30 1996 *************** *** 6,149 **** First of all, have you tried using the B<-w> switch? ! =head2 Debugging ! If you invoke Perl with a B<-d> switch, your script will be run under the ! debugger. However, the Perl debugger is not a separate program as it is ! in a C environment. Instead, the B<-d> flag tells the compiler to insert ! source information into the pseudocode it's about to hand to the ! interpreter. (That means your code must compile correctly for the ! debugger to work on it.) Then when the interpreter starts up, it ! pre-loads a Perl library file containing the debugger itself. The program ! will halt before the first executable statement (but see below) and ask ! you for one of the following commands: =over 12 ! =item h ! Prints out a help message. =item T ! Stack trace. ! If you do bizarre things to your @_ arguments in a subroutine, the stack ! backtrace will not always show the original values. ! =item s Single step. Executes until it reaches the beginning of another ! statement. =item n Next. Executes over subroutine calls, until it reaches the beginning of the next statement. ! =item f ! ! Finish. Executes statements until it has finished the current ! subroutine. ! ! =item c ! Continue. Executes until the next breakpoint is reached. ! =item c line ! Continue to the specified line. Inserts a one-time-only breakpoint at ! the specified line. ! =item ! Repeat last n or s. =item l min+incr ! List incr+1 lines starting at min. If min is omitted, starts where ! last listing left off. If incr is omitted, previous value of incr is ! used. =item l min-max ! List lines in the indicated range. =item l line ! List just the indicated line. ! =item l ! List next window. =item - ! List previous window. ! =item w line ! List window (a few lines worth of code) around line. ! =item l subname ! List subroutine. If it's a long subroutine it just lists the ! beginning. Use "l" to list more. =item /pattern/ ! Regular expression search forward in the source code for pattern; the ! final / is optional. =item ?pattern? ! Regular expression search backward in the source code for pattern; the ! final ? is optional. =item L ! List lines that have breakpoints or actions. ! =item S ! Lists the names of all subroutines. =item t ! Toggle trace mode on or off. ! =item b line [ condition ] Set a breakpoint. If line is omitted, sets a breakpoint on the line ! that is about to be executed. If a condition is specified, it is evaluated each time the statement is reached and a breakpoint is taken only if the condition is true. Breakpoints may only be set on lines ! that begin an executable statement. Conditions don't use C: b 237 $x > 30 b 33 /pattern/i ! =item b subname [ condition ] ! Set breakpoint at first executable line of subroutine. ! =item d line ! Delete breakpoint. If line is omitted, deletes the breakpoint on the ! line that is about to be executed. =item D ! Delete all breakpoints. ! =item a line command ! Set an action for line. A multiline command may be entered by ! backslashing the newlines. This command is Perl code, not another ! debugger command. =item A ! Delete all line actions. =item < command --- 6,342 ---- First of all, have you tried using the B<-w> switch? ! =head1 The Perl Debugger ! If you invoke Perl with the B<-d> switch, your script runs under the ! Perl source debugger. This works like an interactive Perl ! environment, prompting for debugger commands that let you examine ! source code, set breakpoints, get stack backtraces, change the values of ! variables, etc. This is so convenient that you often fire up ! the debugger all by itself just to test out Perl constructs ! interactively to see what they do. For example: ! ! perl -d -e 42 ! ! In Perl, the debugger is not a separate program as it usually is in the ! typical compiled environment. Instead, the B<-d> flag tells the compiler ! to insert source information into the parse trees it's about to hand off ! to the interpreter. That means your code must first compile correctly ! for the debugger to work on it. Then when the interpreter starts up, it ! pre-loads a Perl library file containing the debugger itself. ! ! The program will halt I the first run-time executable ! statement (but see below regarding compile-time statements) and ask you ! to enter a debugger command. Contrary to popular expectations, whenever ! the debugger halts and shows you a line of code, it always displays the ! line it's I to execute, rather than the one it has just executed. ! ! Any command not recognized by the debugger is directly executed ! (C'd) as Perl code in the current package. (The debugger uses the ! DB package for its own state information.) ! ! Leading white space before a command would cause the debugger to think ! it's I a debugger command but for Perl, so be careful not to do ! that. ! ! =head2 Debugger Commands ! ! The debugger understands the following commands: =over 12 ! =item h [command] ! ! Prints out a help message. ! ! If you supply another debugger command as an argument to the C command, ! it prints out the description for just that command. The special ! argument of C produces a more compact help listing, designed to fit ! together on one screen. ! ! If the output the C command (or any command, for that matter) scrolls ! past your screen, either precede the command with a leading pipe symbol so ! it's run through your pager, as in ! ! DB> |h ! ! =item p expr ! ! Same as C in the current package. In particular, ! since this is just Perl's own B function, this means that nested ! data structures and objects are not dumped, unlike with the C command. ! ! =item x expr ! ! Evals its expression in list context and dumps out the result ! in a pretty-printed fashion. Nested data structures are printed out ! recursively, unlike the C function. ! ! =item V [pkg [vars]] ! ! Display all (or some) variables in package (defaulting to the C
! package) using a data pretty-printer (hashes show their keys and values so ! you see what's what, control characters are made printable, etc.). Make ! sure you don't put the type specifier (like C<$>) there, just the symbol ! names, like this: ! V DB filename line ! ! Use C<~pattern> and C for positive and negative regexps. ! ! Nested data structures are printed out in a legible fashion, unlike ! the C function. ! ! =item X [vars] ! ! Same as C. =item T ! Produce a stack backtrace. See below for details on its output. ! =item s [expr] Single step. Executes until it reaches the beginning of another ! statement, descending into subroutine calls. If an expression is ! supplied that includes function calls, it too will be single-stepped. =item n Next. Executes over subroutine calls, until it reaches the beginning of the next statement. ! =item ! Repeat last C or C command. ! =item c [line] ! Continue, optionally inserting a one-time-only breakpoint ! at the specified line. ! =item l ! List next window of lines. =item l min+incr ! List C lines starting at C. =item l min-max ! List lines C through C. =item l line ! List a single line. ! =item l subname ! List first window of lines from subroutine. =item - ! List previous window of lines. ! =item w [line] ! List window (a few lines) around the current line. ! =item . ! Return debugger pointer to the last-executed line and ! print it out. ! ! =item f filename ! ! Switch to viewing a different file. =item /pattern/ ! Search forwards for pattern; final / is optional. =item ?pattern? ! Search backwards for pattern; final ? is optional. =item L ! List all breakpoints and actions for the current file. ! =item S [[!]pattern] ! List subroutine names [not] matching pattern. =item t ! Toggle trace mode. ! ! =item t expr ! ! Trace through execution of expr. For example: ! $ perl -de 42 ! Stack dump during die enabled outside of evals. ! ! Loading DB routines from perl5db.pl patch level 0.94 ! Emacs support available. ! ! Enter h or `h h' for help. ! ! main::(-e:1): 0 ! DB<1> sub foo { 14 } ! ! DB<2> sub bar { 3 } ! ! DB<3> t print foo() * bar() ! main::((eval 172):3): print foo() + bar(); ! main::foo((eval 168):2): ! main::bar((eval 170):2): ! 42 ! DB<4> q ! ! =item b [line] [condition] Set a breakpoint. If line is omitted, sets a breakpoint on the line ! that is about to be executed. If a condition is specified, it's evaluated each time the statement is reached and a breakpoint is taken only if the condition is true. Breakpoints may only be set on lines ! that begin an executable statement. Conditions don't use B: b 237 $x > 30 b 33 /pattern/i ! =item b subname [condition] ! Set a breakpoint at the first line of the named subroutine. ! =item d [line] ! Delete a breakpoint at the specified line. If line is omitted, deletes ! the breakpoint on the line that is about to be executed. =item D ! Delete all installed breakpoints. ! ! =item a [line] command ! ! Set an action to be done before the line is executed. ! The sequence of steps taken by the debugger is ! ! =over 3 ! ! =item 1 ! ! check for a breakpoint at this line ! ! =item 2 ! ! print the line if necessary (tracing) ! ! =item 3 ! ! do any actions associated with that line ! ! =item 4 ! prompt user if at a breakpoint or in single-step ! =item 5 ! ! evaluate line ! ! =back ! ! For example, this will print out C<$foo> every time line ! 53 is passed: ! ! a 53 print "DB FOUND $foo\n" =item A ! Delete all installed actions. ! ! =item O [opt[=val]] [opt"val"] [opt?]... ! ! Set or query values of options. val defaults to 1. opt can ! be abbreviated. Several options can be listed. ! ! =over 12 ! ! =item recallCommand, ShellBang ! ! The characters used to recall command or spawn shell. By ! default, these are both set to C. ! ! =item pager ! ! Program to use for output of pager-piped commands (those ! beginning with a C<|> character.) By default, ! C<$ENV{PAGER}> will be used. ! ! =back ! ! The following options affect what happens with C, C, and C ! commands: ! ! =over 12 ! ! =item arrayDepth, hashDepth ! ! Print only first N elements ('' for all). ! ! =item compactDump, veryCompact ! ! Change style of array and hash dump. ! ! =item globPrint ! ! Whether to print contents of globs. ! ! =item DumpDBFiles ! ! Dump arrays holding debugged files. ! ! =item DumpPackages ! ! Dump symbol tables of packages. ! ! =item quote, HighBit, undefPrint ! ! Change style of string dump. ! ! =item tkRunning ! ! Run Tk while prompting (with ReadLine). ! ! =item signalLevel, warnLevel. dieLevel ! ! Level of verbosity. ! ! =back ! ! The option C affects printing of return value after C ! command, The option C affects printing messages on entry and exit ! from subroutines. If C is 1, messages are printed on entry only; ! if it's set to more than that, they'll will be printed on exit as well, ! which may be useful if interdispersed with other messages. ! ! During startup options are initialized from $ENV{PERLDB_OPTS}. ! You can put additional initialization options C, C, ! C, and C there. Here's an example of using ! the C<$ENV{PERLDB_OPTS}> variable: ! ! $ PERLDB_OPTS="N f=2" perl -d myprogram ! ! will run the script C without human intervention, printing ! out the call tree with entry and exit points. Note that C is ! equivalent to C. Note also that at the moment when ! this documentation was written all the options to the debugger could ! be uniquely abbreviated by the first letter. ! ! See "Debugger Internals" below for more details. =item < command *************** *** 156,183 **** command to return to executing the script. A multiline command may be entered by backslashing the newlines. ! =item V package [symbols] ! ! Display all (or some) variables in package (defaulting to the C
! package) using a data pretty-printer (hashes show their keys and values so ! you see what's what, control characters are made printable, etc.). Make ! sure you don't put the type specifier (like $) there, just the symbol ! names, like this: ! V DB filename line ! =item X [symbols] ! Same as as "V" command, but within the current package. ! =item ! number ! Redo a debugging command. If number is omitted, redoes the previous ! command. ! =item ! -number ! Redo the command that was that many commands ago. =item H -number --- 349,371 ---- command to return to executing the script. A multiline command may be entered by backslashing the newlines. ! =item ! number ! Redo a previous command (default previous command). ! =item ! -number ! Redo number'th-to-last command. ! =item ! pattern ! Redo last command that started with pattern. ! See C, too. ! =item !! cmd ! Run cmd in a subprocess (reads from DB::IN, writes to DB::OUT) ! See C too. =item H -number *************** *** 188,193 **** --- 376,403 ---- Quit. ("quit" doesn't work for this.) + =item R + + Restart the debugger by Bing a new session. It tries to maintain + your history across this, but internal settings and command line options + may be lost. + + =item |dbcmd + + Run debugger command, piping DB::OUT to current pager. + + =item ||dbcmd + + Same as C<|dbcmd> but DB::OUT is temporarily B). If LIST is also omitted, prints $_ to STDOUT. To set the default output channel to something other than STDOUT use the select operation. Note that, because print takes a LIST, anything in the LIST is evaluated in a list context, and any *************** *** 1993,1999 **** put parens around all the arguments. Note that if you're storing FILEHANDLES in an array or other expression, ! you will have to use a block returning its value instead print { $files[$i] } "stuff\n"; print { $OK ? STDOUT : STDERR } "stuff\n"; --- 1996,2002 ---- put parens around all the arguments. Note that if you're storing FILEHANDLES in an array or other expression, ! you will have to use a block returning its value instead: print { $files[$i] } "stuff\n"; print { $OK ? STDOUT : STDERR } "stuff\n"; *************** *** 2005,2010 **** --- 2008,2019 ---- Equivalent to a "print FILEHANDLE sprintf(LIST)". The first argument of the list will be interpreted as the printf format. + =item prototype FUNCTION + + Returns the prototype of a function as a string (or C if the + function has no prototype). FUNCTION is a reference to the the + function whose prototype you want to retrieve. + =item push ARRAY,LIST Treats ARRAY as a stack, and pushes the values of LIST *************** *** 2190,2200 **** otherwise. But it's better just to put the "C<1;>", in case you add more statements. ! If EXPR is a bare word, the require assumes a "F<.pm>" extension for you, to make it easy to load standard modules. This form of loading of modules does not risk altering your namespace. ! For a yet-more-powerful import facility, see the L and L. =item reset EXPR --- 2199,2210 ---- otherwise. But it's better just to put the "C<1;>", in case you add more statements. ! If EXPR is a bare word, the require assumes a "F<.pm>" extension and ! replaces "F<::>" with "F" in the filename for you, to make it easy to load standard modules. This form of loading of modules does not risk altering your namespace. ! For a yet-more-powerful import facility, see L and L. =item reset EXPR *************** *** 2217,2223 **** Resetting "A-Z" is not recommended since you'll wipe out your ARGV and ENV arrays. Only resets package variables--lexical variables are unaffected, but they clean themselves up on scope exit anyway, ! so anymore you probably want to use them instead. See L. =item return LIST --- 2227,2233 ---- Resetting "A-Z" is not recommended since you'll wipe out your ARGV and ENV arrays. Only resets package variables--lexical variables are unaffected, but they clean themselves up on scope exit anyway, ! so you'll probably want to use them instead. See L. =item return LIST *************** *** 2382,2388 **** capable of returning the $timeleft. If not, they always return $timeleft equal to the supplied $timeout. ! You can effect a 250-microsecond sleep this way: select(undef, undef, undef, 0.25); --- 2392,2398 ---- capable of returning the $timeleft. If not, they always return $timeleft equal to the supplied $timeout. ! You can effect a 250-millisecond sleep this way: select(undef, undef, undef, 0.25); *************** *** 2711,2717 **** If the PATTERN contains parentheses, additional array elements are created from each matching substring in the delimiter. ! split(/([,-])/, "1-10,20"); produces the list value --- 2721,2727 ---- If the PATTERN contains parentheses, additional array elements are created from each matching substring in the delimiter. ! split(/([,-])/, "1-10,20", 3); produces the list value *************** *** 2764,2771 **** =item srand EXPR Sets the random number seed for the C operator. If EXPR is omitted, ! does C. Many folks use an explicit C ! instead. Of course, you'd need something much more random than that for cryptographic purposes, since it's easy to guess the current time. Checksumming the compressed output of rapidly changing operating system status programs is the usual method. Examples are posted regularly to --- 2774,2781 ---- =item srand EXPR Sets the random number seed for the C operator. If EXPR is omitted, ! uses a semirandom value based on the current time and process ID, among ! other things. Of course, you'd need something much more random than that for cryptographic purposes, since it's easy to guess the current time. Checksumming the compressed output of rapidly changing operating system status programs is the usual method. Examples are posted regularly to *************** *** 3016,3022 **** # print out history file offsets use NDBM_File; ! tie(%HIST, NDBM_File, '/usr/lib/news/history', 1, 0); while (($key,$val) = each %HIST) { print $key, ' = ', unpack('L',$val), "\n"; } --- 3026,3032 ---- # print out history file offsets use NDBM_File; ! tie(%HIST, 'NDBM_File', '/usr/lib/news/history', 1, 0); while (($key,$val) = each %HIST) { print $key, ' = ', unpack('L',$val), "\n"; } *************** *** 3062,3069 **** =item time ! Returns the number of non-leap seconds since 00:00:00 UTC, January 1, ! 1970. Suitable for feeding to gmtime() and localtime(). =item times --- 3072,3081 ---- =item time ! Returns the number of non-leap seconds since whatever time the system ! considers to be the epoch (that's 00:00:00, January 1, 1904 for MacOS, ! and 00:00:00 UTC, January 1, 1970 for most other systems). ! Suitable for feeding to gmtime() and localtime(). =item times *************** *** 3187,3198 **** --- 3199,3224 ---- =item use Module + =item use Module VERSION LIST + + =item use VERSION + Imports some semantics into the current package from the named module, generally by aliasing certain subroutine or variable names into your package. It is exactly equivalent to BEGIN { require Module; import Module LIST; } + except that Module I be a bare word. + + If the first argument to C is a number, it is treated as a version + number instead of a module name. If the version of the Perl interpreter + is less than VERSION, then an error message is printed and Perl exits + immediately. This is often useful if you need to check the current + Perl version before Cing library modules which have changed in + incompatible ways from older versions of Perl. (We try not to do + this more than we have to.) + The BEGIN forces the require and import to happen at compile time. The require makes sure the module is loaded into memory if it hasn't been yet. The import is not a builtin--it's just an ordinary static method *************** *** 3210,3215 **** --- 3236,3245 ---- BEGIN { require Module; } + If the VERSION argument is present between Module and LIST, then the + C will fail if the C<$VERSION> variable in package Module is + less than VERSION. + Because this is a wide-open interface, pragmas (compiler directives) are also implemented this way. Currently implemented pragmas are: *************** *** 3224,3230 **** effective through the end of the file). There's a corresponding "no" command that unimports meanings imported ! by use. no integer; no strict 'refs'; --- 3254,3260 ---- effective through the end of the file). There's a corresponding "no" command that unimports meanings imported ! by use, i.e. it calls C instead of C. no integer; no strict 'refs'; #~ Use pod formatting instead of ASCII emphasis diff -Pcr perl5_003/pod/perlguts.pod perl5_003_01/pod/perlguts.pod *** perl5_003/pod/perlguts.pod Mon Mar 25 01:05:14 1996 --- perl5_003_01/pod/perlguts.pod Mon Jun 17 19:11:53 1996 *************** *** 39,45 **** SV* newSVpv(char*, int); SV* newSVsv(SV*); ! To change the value of an *already-existing* SV, there are five routines: void sv_setiv(SV*, IV); void sv_setnv(SV*, double); --- 39,45 ---- SV* newSVpv(char*, int); SV* newSVsv(SV*); ! To change the value of an I SV, there are five routines: void sv_setiv(SV*, IV); void sv_setnv(SV*, double); #~ Typos corrected diff -Pcr perl5_003/pod/perlipc.pod perl5_003_01/pod/perlipc.pod *** perl5_003/pod/perlipc.pod Tue Jan 30 13:21:53 1996 --- perl5_003_01/pod/perlipc.pod Mon Jun 17 19:05:09 1996 *************** *** 14,26 **** references of user-installed signal handlers. These handlers will be called with an argument which is the name of the signal that triggered it. A signal may be generated intentionally from a particular keyboard sequence like ! control-C or control-Z, sent to you from an another process, or triggered automatically by the kernel when special events transpire, like a child process exiting, your process running out of stack space, or hitting file size limit. For example, to trap an interrupt signal, set up a handler like this. ! Notice how all we do is set with a global variable and then raise an exception. That's because on most systems libraries are not re-entrant, so calling any print() functions (or even anything that needs to malloc(3) more memory) could in theory trigger a memory fault --- 14,26 ---- references of user-installed signal handlers. These handlers will be called with an argument which is the name of the signal that triggered it. A signal may be generated intentionally from a particular keyboard sequence like ! control-C or control-Z, sent to you from another process, or triggered automatically by the kernel when special events transpire, like a child process exiting, your process running out of stack space, or hitting file size limit. For example, to trap an interrupt signal, set up a handler like this. ! Notice how all we do is set a global variable and then raise an exception. That's because on most systems libraries are not re-entrant, so calling any print() functions (or even anything that needs to malloc(3) more memory) could in theory trigger a memory fault *************** *** 199,205 **** Perl's basic open() statement can also be used for unidirectional interprocess communication by either appending or prepending a pipe symbol to the second ! argument to open(). Here's how to start something up a child process you intend to write to: open(SPOOLER, "| cat -v | lpr -h 2>/dev/null") --- 199,205 ---- Perl's basic open() statement can also be used for unidirectional interprocess communication by either appending or prepending a pipe symbol to the second ! argument to open(). Here's how to start something up in a child process you intend to write to: open(SPOOLER, "| cat -v | lpr -h 2>/dev/null") *************** *** 216,222 **** next if /^(tcp|udp)/; print; } ! close SPOOLER || die "bad netstat: $! $?"; If one can be sure that a particular program is a Perl script that is expecting filenames in @ARGV, the clever programmer can write something --- 216,222 ---- next if /^(tcp|udp)/; print; } ! close STATUS || die "bad netstat: $! $?"; If one can be sure that a particular program is a Perl script that is expecting filenames in @ARGV, the clever programmer can write something *************** *** 296,302 **** Another common use for this construct is when you need to execute something without the shell's interference. With system(), it's ! straigh-forward, but you can't use a pipe open or backticks safely. That's because there's no way to stop the shell from getting its hands on your arguments. Instead, use lower-level control to call exec() directly. --- 296,302 ---- Another common use for this construct is when you need to execute something without the shell's interference. With system(), it's ! straightforward, but you can't use a pipe open or backticks safely. That's because there's no way to stop the shell from getting its hands on your arguments. Instead, use lower-level control to call exec() directly. *************** *** 341,347 **** Note that these operations are full Unix forks, which means they may not be correctly implemented on alien systems. Additionally, these are not true multithreading. If you'd like to learn more about threading, see the ! F file mentioned below in the L section. =head2 Bidirectional Communication --- 341,347 ---- Note that these operations are full Unix forks, which means they may not be correctly implemented on alien systems. Additionally, these are not true multithreading. If you'd like to learn more about threading, see the ! F file mentioned below in the L<"SEE ALSO"> section. =head2 Bidirectional Communication *************** *** 627,633 **** =head2 Unix-Domain TCP Clients and Servers ! That's fine for Internet-domain clients and servers, but what local communications? While you can use the same setup, sometimes you don't want to. Unix-domain sockets are local to the current host, and are often used internally to implement pipes. Unlike Internet domain sockets, UNIX --- 627,633 ---- =head2 Unix-Domain TCP Clients and Servers ! That's fine for Internet-domain clients and servers, but what about local communications? While you can use the same setup, sometimes you don't want to. Unix-domain sockets are local to the current host, and are often used internally to implement pipes. Unlike Internet domain sockets, UNIX *************** *** 808,814 **** die if !defined($key); print "$key\n"; ! Put this code in a separate file to be run in more that one process Call the file F: # create a semaphore --- 808,814 ---- die if !defined($key); print "$key\n"; ! Put this code in a separate file to be run in more than one process. Call the file F: # create a semaphore *************** *** 832,838 **** semop($key,$opstring) || die "$!"; ! Put this code in a separate file to be run in more that one process Call this file F: # 'give' the semaphore --- 832,838 ---- semop($key,$opstring) || die "$!"; ! Put this code in a separate file to be run in more than one process. Call this file F: # 'give' the semaphore *************** *** 870,883 **** If you are running under version 5.000 (dubious) or 5.001, you can still use most of the examples in this document. You may have to remove the C and some of the my() statements for 5.000, and for both ! you'll have to load in version 1.2 of the F module, which ! was/is/shall-be included in I. Most of these routines quietly but politely return C when they fail instead of causing your program to die right then and there due to an uncaught exception. (Actually, some of the new I conversion functions croak() on bad arguments.) It is therefore essential ! that you should check the return values fo these functions. Always begin your socket programs this way for optimal success, and don't forget to add B<-T> taint checking flag to the pound-bang line for servers: --- 870,883 ---- If you are running under version 5.000 (dubious) or 5.001, you can still use most of the examples in this document. You may have to remove the C and some of the my() statements for 5.000, and for both ! you'll have to load in version 1.2 or older of the F module, which ! is included in I. Most of these routines quietly but politely return C when they fail instead of causing your program to die right then and there due to an uncaught exception. (Actually, some of the new I conversion functions croak() on bad arguments.) It is therefore essential ! that you should check the return values of these functions. Always begin your socket programs this way for optimal success, and don't forget to add B<-T> taint checking flag to the pound-bang line for servers: *************** *** 893,899 **** elsewhere, Perl is at the mercy of your C libraries for much of its system behaviour. It's probably safest to assume broken SysV semantics for signals and to stick with simple TCP and UDP socket operations; e.g. don't ! try to pass open filedescriptors over a local UDP datagram socket if you want your code to stand a chance of being portable. Because few vendors provide C libraries that are safely --- 893,899 ---- elsewhere, Perl is at the mercy of your C libraries for much of its system behaviour. It's probably safest to assume broken SysV semantics for signals and to stick with simple TCP and UDP socket operations; e.g. don't ! try to pass open file descriptors over a local UDP datagram socket if you want your code to stand a chance of being portable. Because few vendors provide C libraries that are safely #~ Typos corrected #~ Syntax clarified for optional -> diff -Pcr perl5_003/pod/perllol.pod perl5_003_01/pod/perllol.pod *** perl5_003/pod/perllol.pod Mon Jan 22 20:47:38 1996 --- perl5_003_01/pod/perllol.pod Mon Jun 17 18:52:31 1996 *************** *** 55,61 **** Well, that's because the rule is that on adjacent brackets only (whether square or curly), you are free to omit the pointer dereferencing array. ! But you need not do so for the very first one if it's a scalar containing a reference, which means that $ref_to_LoL always needs it. =head1 Growing Your Own --- 55,61 ---- Well, that's because the rule is that on adjacent brackets only (whether square or curly), you are free to omit the pointer dereferencing array. ! But you cannot do so for the very first one if it's a scalar containing a reference, which means that $ref_to_LoL always needs it. =head1 Growing Your Own *************** *** 128,134 **** $LoL[$i] = [ split ' ', <> ]; } ! You should in general be leary of using potential list functions in a scalar context without explicitly stating such. This would be clearer to the casual reader: --- 128,134 ---- $LoL[$i] = [ split ' ', <> ]; } ! You should in general be leery of using potential list functions in a scalar context without explicitly stating such. This would be clearer to the casual reader: *************** *** 243,249 **** =head1 Slices ! If you want to get at a slide (part of a row) in a multidimensional array, you're going to have to do some fancy subscripting. That's because while we have a nice synonym for single elements via the pointer arrow for dereferencing, no such convenience exists for slices. --- 243,249 ---- =head1 Slices ! If you want to get at a slice (part of a row) in a multidimensional array, you're going to have to do some fancy subscripting. That's because while we have a nice synonym for single elements via the pointer arrow for dereferencing, no such convenience exists for slices. #~ Typos and pod formatting corrected #~ Use "identifier" for both members of an aliased pair of symbols #~ to emphasize their equivalence #~ Add description of "ops" and "vars" pragmatic modules diff -Pcr perl5_003/pod/perlmod.pod perl5_003_01/pod/perlmod.pod *** perl5_003/pod/perlmod.pod Mon Mar 25 01:05:14 1996 --- perl5_003_01/pod/perlmod.pod Thu Jul 11 12:22:54 1996 *************** *** 7,13 **** =head2 Packages Perl provides a mechanism for alternative namespaces to protect packages ! from stomping on each others variables. In fact, apart from certain magical variables, there's really no such thing as a global variable in Perl. The package statement declares the compilation unit as being in the given namespace. The scope of the package declaration is from the --- 7,13 ---- =head2 Packages Perl provides a mechanism for alternative namespaces to protect packages ! from stomping on each other's variables. In fact, apart from certain magical variables, there's really no such thing as a global variable in Perl. The package statement declares the compilation unit as being in the given namespace. The scope of the package declaration is from the *************** *** 22,28 **** refer to variables and filehandles in other packages by prefixing the identifier with the package name and a double colon: C<$Package::Variable>. If the package name is null, the C
package ! as assumed. That is, C<$::sail> is equivalent to C<$main::sail>. (The old package delimiter was a single quote, but double colon is now the preferred delimiter, in part because it's more readable --- 22,28 ---- refer to variables and filehandles in other packages by prefixing the identifier with the package name and a double colon: C<$Package::Variable>. If the package name is null, the C
package ! is assumed. That is, C<$::sail> is equivalent to C<$main::sail>. (The old package delimiter was a single quote, but double colon is now the preferred delimiter, in part because it's more readable *************** *** 69,76 **** The symbol table for a package happens to be stored in the associative array of that name appended with two colons. The main symbol table's ! name is thus C<%main::>, or C<%::> for short. Likewise the nested package ! mentioned earlier is named C<%OUTER::INNER::>. The value in each entry of the associative array is what you are referring to when you use the C<*name> typeglob notation. In fact, the following --- 69,76 ---- The symbol table for a package happens to be stored in the associative array of that name appended with two colons. The main symbol table's ! name is thus C<%main::>, or C<%::> for short. Likewise symbol table for ! the nested package mentioned earlier is named C<%OUTER::INNER::>. The value in each entry of the associative array is what you are referring to when you use the C<*name> typeglob notation. In fact, the following *************** *** 120,126 **** *dick = *richard; causes variables, subroutines and file handles accessible via the ! identifier C to also be accessible via the symbol C. If you only want to alias a particular variable or subroutine, you can assign a reference instead: --- 120,126 ---- *dick = *richard; causes variables, subroutines and file handles accessible via the ! identifier C to also be accessible via the identifier C. If you only want to alias a particular variable or subroutine, you can assign a reference instead: *************** *** 305,311 **** the F<.ph> files made by B will probably end up as extension modules made by B. (Some F<.ph> values may already be available through the POSIX module.) The B file in the distribution may help in your ! conversion, but it's just a mechanical process, so is far from bullet proof. =head2 Pragmatic Modules --- 305,311 ---- the F<.ph> files made by B will probably end up as extension modules made by B. (Some F<.ph> values may already be available through the POSIX module.) The B file in the distribution may help in your ! conversion, but it's just a mechanical process, so is far from bulletproof. =head2 Pragmatic Modules *************** *** 335,340 **** --- 335,344 ---- Pragma to request less of something from the compiler + =item ops + + Pragma to restrict use of unsafe opcodes + =item overload Pragma for overloading operators *************** *** 351,356 **** --- 355,364 ---- Pragma to predeclare sub names + =item vars + + Pragma to predeclare global symbols + =back =head2 Standard Modules *************** *** 602,608 **** =back ! Some of the reguster CPAN sites as of this writing include the following. You should try to choose one close to you: =over --- 610,616 ---- =back ! The registered CPAN sites as of this writing include the following. You should try to choose one close to you: =over *************** *** 676,682 **** =back For an up-to-date listing of CPAN sites, ! see http://www.perl.com/perl/ or ftp://ftp.perl.com/perl/ . =head1 Modules: Creation, Use and Abuse --- 684,690 ---- =back For an up-to-date listing of CPAN sites, ! see F or F. =head1 Modules: Creation, Use and Abuse *************** *** 910,915 **** --- 918,925 ---- split out some of the sections into separate files: INSTALL, Copying, ToDo etc. + =over 4 + =item Adding a Copyright Notice. How you choose to licence your work is a personal decision. *************** *** 991,996 **** --- 1001,1008 ---- =back + =back + =head2 Guidelines for Converting Perl 4 Library Scripts into Modules =over 4 *************** *** 1063,1069 **** perl -e 'use Module::Name; method(@ARGV)' ... or ! perl -mModule::Name ... (in perl5.002?) =back --- 1075,1081 ---- perl -e 'use Module::Name; method(@ARGV)' ... or ! perl -mModule::Name ... (in perl5.002) =back #~ Add documentation for default UNIVERSAL methods diff -Pcr perl5_003/pod/perlobj.pod perl5_003_01/pod/perlobj.pod *** perl5_003/pod/perlobj.pod Mon Mar 25 01:05:15 1996 --- perl5_003_01/pod/perlobj.pod Fri Jul 5 15:55:24 1996 *************** *** 137,143 **** If neither a method nor an AUTOLOAD routine is found in @ISA, then one last try is made for the method (or an AUTOLOAD routine) in a class ! called UNIVERSAL. If that doesn't work, Perl finally gives up and complains. Perl classes only do method inheritance. Data inheritance is left --- 137,145 ---- If neither a method nor an AUTOLOAD routine is found in @ISA, then one last try is made for the method (or an AUTOLOAD routine) in a class ! called UNIVERSAL. (Several commonly used methods are automatically ! supplied in the UNIVERSAL class; see L<"Default UNIVERSAL methods"> for ! more details.) If that doesn't work, Perl finally gives up and complains. Perl classes only do method inheritance. Data inheritance is left *************** *** 267,273 **** $method = $fast ? "findfirst" : "findbest"; $fred->$method(@args); ! =head2 Destructors When the last reference to an object goes away, the object is automatically destroyed. (This may even be after you exit, if you've --- 269,342 ---- $method = $fast ? "findfirst" : "findbest"; $fred->$method(@args); ! =head2 Default UNIVERSAL methods ! ! The C package automatically contains the following methods that ! are inherited by all other classes: ! ! =over 4 ! ! =item isa ( CLASS ) ! ! C returns I if its object is blessed into a sub-class of C ! ! C is also exportable and can be called as a sub with two arguments. This ! allows the ability to check what a reference points to. Example ! ! use UNIVERSAL qw(isa); ! ! if(isa($ref, 'ARRAY')) { ! ... ! } ! ! =item can ( METHOD ) ! ! C checks to see if its object has a method called C, ! if it does then a reference to the sub is returned, if it does not then ! I is returned. ! ! =item require_version ( VERSION ) ! ! C will check that the current version of the package ! is greater than C. This method is normally called as a static method. ! This method is also called when the C form of C is used. ! ! use A 1.2 qw(some imported subs); ! ! A->require_version( 1.2 ); ! ! =item class () ! ! C returns the class name of its object. ! ! =item is_instance () ! ! C returns true if its object is an instance of some ! class, false if its object is the class (package) itself. Example ! ! A->is_instance(); # False ! ! $var = 'A'; ! $var->is_instance(); # False ! ! $ref = bless [], 'A'; ! $ref->is_instance(); # True ! ! =item require_version ( [ VERSION ] ) ! ! C returns the VERSION number of the class (package). If ! an argument is given then it will check that the current version is not ! less that the given argument. ! ! =back ! ! B C directly uses Perl's internal code for method lookup, and ! C uses a very similar method and cache-ing strategy. This may cause ! strange effects if the Perl code dynamically changes @ISA in any package. ! ! You may add other methods to the UNIVERSAL class via Perl or XS code. ! ! =head2 Destructors When the last reference to an object goes away, the object is automatically destroyed. (This may even be after you exit, if you've #~ Correct typos and pod formatting #~ Correct documentation for s///: return value with no substitutions, #~ use of backticks as delimiters diff -Pcr perl5_003/pod/perlop.pod perl5_003_01/pod/perlop.pod *** perl5_003/pod/perlop.pod Mon Mar 25 01:05:15 1996 --- perl5_003_01/pod/perlop.pod Mon Jun 17 19:21:12 1996 *************** *** 749,755 **** Searches a string for a pattern, and if found, replaces that pattern with the replacement text and returns the number of substitutions ! made. Otherwise it returns false (0). If no string is specified via the C<=~> or C operator, the C<$_> variable is searched and modified. (The string specified with C<=~> must --- 749,755 ---- Searches a string for a pattern, and if found, replaces that pattern with the replacement text and returns the number of substitutions ! made. Otherwise it returns false (specifically, the empty string). If no string is specified via the C<=~> or C operator, the C<$_> variable is searched and modified. (The string specified with C<=~> must *************** *** 777,785 **** Any non-alphanumeric, non-whitespace delimiter may replace the slashes. If single quotes are used, no interpretation is done on the ! replacement string (the C modifier overrides this, however). If ! backquotes are used, the replacement string is a command to execute ! whose output will be used as the actual replacement text. If the PATTERN is delimited by bracketing quotes, the REPLACEMENT has its own pair of quotes, which may or may not be bracketing quotes, e.g. C or CfooE/bar/>. A C will cause the --- 777,785 ---- Any non-alphanumeric, non-whitespace delimiter may replace the slashes. If single quotes are used, no interpretation is done on the ! replacement string (the C modifier overrides this, however). Unlike ! Perl 4, Perl 5 treats backticks as normal delimiters; the replacement ! text is not evaluated as a command. If the PATTERN is delimited by bracketing quotes, the REPLACEMENT has its own pair of quotes, which may or may not be bracketing quotes, e.g. C or CfooE/bar/>. A C will cause the *************** *** 1073,1079 **** It you're trying to do variable interpolation, it's definitely better to use the glob() function, because the older notation can cause people ! to become confused with the indirect filehandle notatin. @files = glob("$dir/*.[ch]"); @files = glob($files[$i]); --- 1073,1079 ---- It you're trying to do variable interpolation, it's definitely better to use the glob() function, because the older notation can cause people ! to become confused with the indirect filehandle notation. @files = glob("$dir/*.[ch]"); @files = glob($files[$i]); #~ Correct pod formatting diff -Pcr perl5_003/pod/perlpod.pod perl5_003_01/pod/perlpod.pod *** perl5_003/pod/perlpod.pod Mon Jan 22 20:48:00 1996 --- perl5_003_01/pod/perlpod.pod Wed May 1 17:48:43 1996 *************** *** 104,109 **** --- 104,111 ---- X An index entry Z<> A zero-width character + =back + That's it. The intent is simplicity, not power. I wanted paragraphs to look like paragraphs (block format), so that they stand out visually, and so that I could run them through fmt easily to reformat #~ Correct typo diff -Pcr perl5_003/pod/perlre.pod perl5_003_01/pod/perlre.pod *** perl5_003/pod/perlre.pod Mon Mar 25 01:05:18 1996 --- perl5_003_01/pod/perlre.pod Tue Jun 18 22:01:27 1996 *************** *** 330,336 **** whole string. As C<\d*> can match on an empty string the complete regular expression matched successfully. ! Beginning is , number is <>. Here are some variants, most of which don't work: --- 330,336 ---- whole string. As C<\d*> can match on an empty string the complete regular expression matched successfully. ! Beginning is , number is <>. Here are some variants, most of which don't work: #~ Note potential gc problems with cyclic data structures #~ Distinguish between "identifier" and full variable name diff -Pcr perl5_003/pod/perlref.pod perl5_003_01/pod/perlref.pod *** perl5_003/pod/perlref.pod Mon Mar 25 01:05:18 1996 --- perl5_003_01/pod/perlref.pod Tue Jun 18 19:59:27 1996 *************** *** 15,25 **** Hard references are smart--they keep track of reference counts for you, automatically freeing the thing referred to when its reference count ! goes to zero. If that thing happens to be an object, the object is destructed. See L for more about objects. (In a sense, everything in Perl is an object, but we usually reserve the word for references to objects that have been officially "blessed" into a class package.) A symbolic reference contains the name of a variable, just as a symbolic link in the filesystem merely contains the name of a file. The C<*glob> notation is a kind of symbolic reference. Hard references --- 15,29 ---- Hard references are smart--they keep track of reference counts for you, automatically freeing the thing referred to when its reference count ! goes to zero. (Note: The reference counts for values in self-referential ! or cyclic data structures may not go to zero without a little help; see ! L for a detailed explanation. ! If that thing happens to be an object, the object is destructed. See L for more about objects. (In a sense, everything in Perl is an object, but we usually reserve the word for references to objects that have been officially "blessed" into a class package.) + A symbolic reference contains the name of a variable, just as a symbolic link in the filesystem merely contains the name of a file. The C<*glob> notation is a kind of symbolic reference. Hard references *************** *** 207,215 **** =item 1. ! Anywhere you'd put an identifier as part of a variable or subroutine ! name, you can replace the identifier with a simple scalar variable ! containing a reference of the correct type: $bar = $$scalarref; push(@$arrayref, $filename); --- 211,219 ---- =item 1. ! Anywhere you'd put an identifier (or chain of identifiers) as part ! of a variable or subroutine name, you can replace the identifier with ! a simple scalar variable containing a reference of the correct type: $bar = $$scalarref; push(@$arrayref, $filename); *************** *** 230,239 **** =item 2. ! Anywhere you'd put an identifier as part of a variable or subroutine ! name, you can replace the identifier with a BLOCK returning a reference ! of the correct type. In other words, the previous examples could be ! written like this: $bar = ${$scalarref}; push(@{$arrayref}, $filename); --- 234,243 ---- =item 2. ! Anywhere you'd put an identifier (or chain of identifiers) as part of a ! variable or subroutine name, you can replace the identifier with a ! BLOCK returning a reference of the correct type. In other words, the ! previous examples could be written like this: $bar = ${$scalarref}; push(@{$arrayref}, $filename); #~ Distinguish between "identifier" and full variable name diff -Pcr perl5_003/pod/perlrun.pod perl5_003_01/pod/perlrun.pod *** perl5_003/pod/perlrun.pod Mon Mar 25 01:05:19 1996 --- perl5_003_01/pod/perlrun.pod Wed May 1 20:35:10 1996 *************** *** 415,421 **** =item B<-w> ! prints warnings about identifiers that are mentioned only once, and scalar variables that are used before being set. Also warns about redefined subroutines, and references to undefined filehandles or filehandles opened readonly that you are attempting to write on. Also --- 415,421 ---- =item B<-w> ! prints warnings about variable names that are mentioned only once, and scalar variables that are used before being set. Also warns about redefined subroutines, and references to undefined filehandles or filehandles opened readonly that you are attempting to write on. Also #~ Extensive rewrite diff -Pcr perl5_003/pod/perlsec.pod perl5_003_01/pod/perlsec.pod *** perl5_003/pod/perlsec.pod Mon Jan 22 20:48:20 1996 --- perl5_003_01/pod/perlsec.pod Mon Jul 8 11:56:19 1996 *************** *** 1,147 **** =head1 NAME perlsec - Perl security =head1 DESCRIPTION ! Perl is designed to make it easy to write secure setuid and setgid ! scripts. Unlike shells, which are based on multiple substitution ! passes on each line of the script, Perl uses a more conventional ! evaluation scheme with fewer hidden "gotchas". Additionally, since the ! language has more built-in functionality, it has to rely less upon ! external (and possibly untrustworthy) programs to accomplish its ! purposes. ! ! Beyond the obvious problems that stem from giving special privileges to ! such flexible systems as scripts, on many operating systems, setuid ! scripts are inherently insecure right from the start. This is because ! that between the time that the kernel opens up the file to see what to ! run, and when the now setuid interpreter it ran turns around and reopens ! the file so it can interpret it, things may have changed, especially if ! you have symbolic links on your system. ! ! Fortunately, sometimes this kernel "feature" can be disabled. ! Unfortunately, there are two ways to disable it. The system can simply ! outlaw scripts with the setuid bit set, which doesn't help much. ! Alternately, it can simply ignore the setuid bit on scripts. If the ! latter is true, Perl can emulate the setuid and setgid mechanism when it ! notices the otherwise useless setuid/gid bits on Perl scripts. It does ! this via a special executable called B that is automatically ! invoked for you if it's needed. ! ! If, however, the kernel setuid script feature isn't disabled, Perl will ! complain loudly that your setuid script is insecure. You'll need to ! either disable the kernel setuid script feature, or put a C wrapper around ! the script. See the program B in the F directory of your ! Perl distribution for how to go about doing this. - There are some systems on which setuid scripts are free of this inherent - security bug. For example, recent releases of Solaris are like this. On - such systems, when the kernel passes the name of the setuid script to open - to the interpreter, rather than using a pathname subject to mettling, it - instead passes /dev/fd/3. This is a special file already opened on the - script, so that there can be no race condition for evil scripts to - exploit. On these systems, Perl should be compiled with - C<-DSETUID_SCRIPTS_ARE_SECURE_NOW>. The B program that builds - Perl tries to figure this out for itself. - - When executing a setuid script, or when you have turned on taint checking - explicitly using the B<-T> flag, Perl takes special precautions to - prevent you from falling into any obvious traps. (In some ways, a Perl - script is more secure than the corresponding C program.) Any command line - argument, environment variable, or input is marked as "tainted", and may - not be used, directly or indirectly, in any command that invokes a - subshell, or in any command that modifies files, directories, or - processes. Any variable that is set within an expression that has - previously referenced a tainted value also becomes tainted (even if it is - logically impossible for the tainted value to influence the variable). For example: ! $foo = shift; # $foo is tainted ! $bar = $foo,'bar'; # $bar is also tainted ! $xxx = <>; # Tainted $path = $ENV{'PATH'}; # Tainted, but see below ! $abc = 'abc'; # Not tainted ! system "echo $foo"; # Insecure ! system "/bin/echo", $foo; # Secure (doesn't use sh) ! system "echo $bar"; # Insecure ! system "echo $abc"; # Insecure until PATH set ! $ENV{'PATH'} = '/bin:/usr/bin'; ! $ENV{'IFS'} = '' if $ENV{'IFS'} ne ''; ! $path = $ENV{'PATH'}; # Not tainted ! system "echo $abc"; # Is secure now! ! open(FOO,"$foo"); # OK ! open(FOO,">$foo"); # Not OK ! open(FOO,"echo $foo|"); # Not OK, but... ! open(FOO,"-|") || exec 'echo', $foo; # OK ! $zzz = `echo $foo`; # Insecure, zzz tainted ! unlink $abc,$foo; # Insecure ! umask $foo; # Insecure ! exec "echo $foo"; # Insecure ! exec "echo", $foo; # Secure (doesn't use sh) ! exec "sh", '-c', $foo; # Considered secure, alas ! The taintedness is associated with each scalar value, so some elements ! of an array can be tainted, and others not. If you try to do something insecure, you will get a fatal error saying something like "Insecure dependency" or "Insecure PATH". Note that you ! can still write an insecure system call or exec, but only by explicitly ! doing something like the last example above. You can also bypass the ! tainting mechanism by referencing subpatterns--Perl presumes that if ! you reference a substring using $1, $2, etc, you knew what you were ! doing when you wrote the pattern: ! ! $ARGV[0] =~ /^-P(\w+)$/; ! $printer = $1; # Not tainted ! ! This is fairly secure since C<\w+> doesn't match shell metacharacters. ! Use of C would have been insecure, but Perl doesn't check for that, ! so you must be careful with your patterns. This is the I mechanism ! for untainting user supplied filenames if you want to do file operations ! on them (unless you make C<$E> equal to C<$E> ). ! ! For "Insecure $ENV{PATH}" messages, you need to set C<$ENV{'PATH'}> to a known ! value, and each directory in the path must be non-writable by the world. ! A frequently voiced gripe is that you can get this message even ! if the pathname to an executable is fully qualified. But Perl can't ! know that the executable in question isn't going to execute some other ! program depending on the PATH. It's also possible to get into trouble with other operations that don't care whether they use tainted values. Make judicious use of the file tests in dealing with any user-supplied filenames. When possible, do opens and such after setting C<$E = $E>. (Remember group IDs, ! too!) Perl doesn't prevent you from opening tainted filenames for reading, so be careful what you print out. The tainting mechanism is intended to prevent stupid mistakes, not to remove the need for thought. ! This gives us a reasonably safe way to open a file or pipe: just reset the ! id set to the original IDs. Here's a way to do backticks reasonably ! safely. Notice how the exec() is not called with a string that the shell ! could expand. By the time we get to the exec(), tainting is turned off, ! however, so be careful what you call and what you pass it. die unless defined $pid = open(KID, "-|"); if ($pid) { # parent while () { # do something ! } close KID; } else { ! $> = $<; ! $) = $(; # BUG: initgroups() not called ! exec 'program', 'arg1', 'arg2'; ! die "can't exec program: $!"; } ! For those even more concerned about safety, see the I and I ! modules at a CPAN site near you. See L for a list of CPAN sites. --- 1,268 ---- + =head1 NAME perlsec - Perl security =head1 DESCRIPTION ! Perl is designed to make it easy to program securely even when running ! with extra privileges, like setuid or setgid programs. Unlike most ! command-line shells, which are based on multiple substitution passes on ! each line of the script, Perl uses a more conventional evaluation scheme ! with fewer hidden snags. Additionally, because the language has more ! built-in functionality, it can rely less upon external (and possibly ! untrustworthy) programs to accomplish its purposes. ! ! Perl automatically enables a set of special security checks, called I, when it detects its program running with differing real and effective ! user or group IDs. The setuid bit in Unix permissions is mode 04000, the ! setgid bit mode 02000; either or both may be set. You can also enable taint ! mode explicitly by using the the B<-T> command line flag. This flag is ! I suggested for server programs and any program run on behalf of ! someone else, such as a CGI script. ! ! While in this mode, Perl takes special precautions called I to prevent both obvious and subtle traps. Some of these checks ! are reasonably simple, such as verifying that path directories aren't ! writable by others; careful programmers have always used checks like ! these. Other checks, however, are best supported by the language itself, ! and it is these checks especially that contribute to making a setuid Perl ! program more secure than the corresponding C program. ! ! You may not use data derived from outside your program to affect something ! else outside your program--at least, not by accident. All command-line ! arguments, environment variables, and file input are marked as "tainted". ! Tainted data may not be used directly or indirectly in any command that ! invokes a subshell, nor in any command that modifies files, directories, ! or processes. Any variable set within an expression that has previously ! referenced a tainted value itself becomes tainted, even if it is logically ! impossible for the tainted value to influence the variable. Because ! taintedness is associated with each scalar value, some elements of an ! array can be tainted and others not. For example: ! $arg = shift; # $arg is tainted ! $hid = $arg, 'bar'; # $hid is also tainted ! $line = <>; # Tainted $path = $ENV{'PATH'}; # Tainted, but see below ! $data = 'abc'; # Not tainted ! system "echo $arg"; # Insecure ! system "/bin/echo", $arg; # Secure (doesn't use sh) ! system "echo $hid"; # Insecure ! system "echo $data"; # Insecure until PATH set ! $path = $ENV{'PATH'}; # $path now tainted ! $ENV{'PATH'} = '/bin:/usr/bin'; ! $ENV{'IFS'} = '' if $ENV{'IFS'} ne ''; ! $path = $ENV{'PATH'}; # $path now NOT tainted ! system "echo $data"; # Is secure now! ! open(FOO, "< $arg"); # OK - read-only file ! open(FOO, "> $arg"); # Not OK - trying to write ! open(FOO,"echo $arg|"); # Not OK, but... ! open(FOO,"-|") ! or exec 'echo', $arg; # OK ! $shout = `echo $arg`; # Insecure, $shout now tainted ! unlink $data, $arg; # Insecure ! umask $arg; # Insecure ! exec "echo $arg"; # Insecure ! exec "echo", $arg; # Secure (doesn't use the shell) ! exec "sh", '-c', $arg; # Considered secure, alas! If you try to do something insecure, you will get a fatal error saying something like "Insecure dependency" or "Insecure PATH". Note that you ! can still write an insecure B or B, but only by explicitly ! doing something like the last example above. ! ! =head2 Laundering and Detecting Tainted Data ! ! To test whether a variable contains tainted data, and whose use would thus ! trigger an "Insecure dependency" message, you can use the following ! I function. ! ! sub is_tainted { ! return ! eval { ! join('',@_), kill 0; ! 1; ! }; ! } ! ! This function makes use of the fact that the presence of tainted data ! anywhere within an expression renders the entire expression tainted. It ! would be inefficient for every operator to test every argument for ! taintedness. Instead, the slightly more efficient and conservative ! approach is used that if any tainted value has been accessed within the ! same expression, the whole expression is considered tainted. ! ! But testing for taintedness only gets you so far. Sometimes you just have ! to clear your data's taintedness. The only way to bypass the tainting ! mechanism is by referencing subpatterns from a regular expression match. ! Perl presumes that if you reference a substring using $1, $2, etc., that ! you knew what you were doing when you wrote the pattern. That means using ! a bit of thought--don't just blindly untaint anything, or you defeat the ! entire mechanism. It's better to verify that the variable has only ! good characters (for certain values of "good") rather than checking ! whether it has any bad characters. That's because it's far too easy to ! miss bad characters that you never thought of. ! ! Here's a test to make sure that the data contains nothing but "word" ! characters (alphabetics, numerics, and underscores), a hyphen, an at sign, ! or a dot. ! ! if ($data =~ /^([-\@\w.]+)$/) { ! $data = $1; # $data now untainted ! } else { ! die "Bad data in $data"; # log this somewhere ! } ! ! This is fairly secure since C doesn't normally match shell ! metacharacters, nor are dot, dash, or at going to mean something special ! to the shell. Use of C would have been insecure in theory because ! it lets everything through, but Perl doesn't check for that. The lesson ! is that when untainting, you must be exceedingly careful with your patterns. ! Laundering data using regular expression is the I mechanism for ! untainting dirty data, unless you use the strategy detailed below to fork ! a child of lesser privilege. ! ! =head2 Cleaning Up Your Path ! ! For "Insecure $ENV{PATH}" messages, you need to set C<$ENV{'PATH'}> to a ! known value, and each directory in the path must be non-writable by others ! than its owner and group. You may be surprised to get this message even ! if the pathname to your executable is fully qualified. This is I ! generated because you didn't supply a full path to the program; instead, ! it's generated because you never set your PATH environment variable, or ! you didn't set it to something that was safe. Because Perl can't ! guarantee that the executable in question isn't itself going to turn ! around and execute some other program that is dependent on your PATH, it ! makes sure you set the PATH. It's also possible to get into trouble with other operations that don't care whether they use tainted values. Make judicious use of the file tests in dealing with any user-supplied filenames. When possible, do opens and such after setting C<$E = $E>. (Remember group IDs, ! too!) Perl doesn't prevent you from opening tainted filenames for reading, so be careful what you print out. The tainting mechanism is intended to prevent stupid mistakes, not to remove the need for thought. ! Perl does not call the shell to expand wild cards when you pass B ! and B explicit parameter lists instead of strings with possible shell ! wildcards in them. Unfortunately, the B, B, and ! backtick functions provide no such alternate calling convention, so more ! subterfuge will be required. ! ! Perl provides a reasonably safe way to open a file or pipe from a setuid ! or setgid program: just create a child process with reduced privilege who ! does the dirty work for you. First, fork a child using the special ! B syntax that connects the parent and child by a pipe. Now the ! child resets its ID set and any other per-process attributes, like ! environment variables, umasks, current working directories, back to the ! originals or known safe values. Then the child process, which no longer ! has any special permissions, does the B or other system call. ! Finally, the child passes the data it managed to access back to the ! parent. Since the file or pipe was opened in the child while running ! under less privilege than the parent, it's not apt to be tricked into ! doing something it shouldn't. ! ! Here's a way to do backticks reasonably safely. Notice how the B is ! not called with a string that the shell could expand. This is by far the ! best way to call something that might be subjected to shell escapes: just ! never call the shell at all. By the time we get to the B, tainting ! is turned off, however, so be careful what you call and what you pass it. + use English; die unless defined $pid = open(KID, "-|"); if ($pid) { # parent while () { # do something ! } close KID; } else { ! $EUID = $UID; ! $EGID = $GID; # XXX: initgroups() not called ! $ENV{PATH} = "/bin:/usr/bin"; ! exec 'myprog', 'arg1', 'arg2'; ! die "can't exec myprog: $!"; ! } ! ! A similar strategy would work for wildcard expansion via C. ! ! Taint checking is most useful when although you trust yourself not to have ! written a program to give away the farm, you don't necessarily trust those ! who end up using it not to try to trick it into doing something bad. This ! is the kind of security checking that's useful for setuid programs and ! programs launched on someone else's behalf, like CGI programs. ! ! This is quite different, however, from not even trusting the writer of the ! code not to try to do something evil. That's the kind of trust needed ! when someone hands you a program you've never seen before and says, "Here, ! run this." For that kind of safety, check out the Safe module, ! included standard in the Perl distribution. This module allows the ! programmer to set up special compartments in which all system operations ! are trapped and namespace access is carefully controlled. ! ! =head2 Security Bugs ! ! Beyond the obvious problems that stem from giving special privileges to ! systems as flexible as scripts, on many versions of Unix, setuid scripts ! are inherently insecure right from the start. The problem is a race ! condition in the kernel. Between the time the kernel opens the file to ! see which interpreter to run and when the (now-setuid) interpreter turns ! around and reopens the file to interpret it, the file in question may have ! changed, especially if you have symbolic links on your system. ! ! Fortunately, sometimes this kernel "feature" can be disabled. ! Unfortunately, there are two ways to disable it. The system can simply ! outlaw scripts with the setuid bit set, which doesn't help much. ! Alternately, it can simply ignore the setuid bit on scripts. If the ! latter is true, Perl can emulate the setuid and setgid mechanism when it ! notices the otherwise useless setuid/gid bits on Perl scripts. It does ! this via a special executable called B that is automatically ! invoked for you if it's needed. ! ! However, if the kernel setuid script feature isn't disabled, Perl will ! complain loudly that your setuid script is insecure. You'll need to ! either disable the kernel setuid script feature, or put a C wrapper around ! the script. A C wrapper is just a compiled program that does nothing ! except call your Perl program. Compiled programs are not subject to the ! kernel bug that plagues setuid scripts. Here's a simple wrapper, written ! in C: ! ! #define REAL_PATH "/path/to/script" ! main(ac, av) ! char **av; ! { ! execv(REAL_PATH, av); } ! Compile this wrapper into a binary executable and then make I rather ! than your script setuid or setgid. ! ! See the program B in the F directory of your Perl ! distribution for a convenient way to do this automatically for all your ! setuid Perl programs. It moves setuid scripts into files with the same ! name plus a leading dot, and then compiles a wrapper like the one above ! for each of them. ! ! In recent years, vendors have begun to supply systems free of this ! inherent security bug. On such systems, when the kernel passes the name ! of the setuid script to open to the interpreter, rather than using a ! pathname subject to meddling, it instead passes I. This is a ! special file already opened on the script, so that there can be no race ! condition for evil scripts to exploit. On these systems, Perl should be ! compiled with C<-DSETUID_SCRIPTS_ARE_SECURE_NOW>. The B ! program that builds Perl tries to figure this out for itself, so you ! should never have to specify this yourself. Most modern releases of ! SysVr4 and BSD 4.4 use this approach to avoid the kernel race condition. ! ! Prior to release 5.003 of Perl, a bug in the code of B could ! introduce a security hole in systems compiled with strict POSIX ! compliance. #~ Typos corrected #~ Update reference to AutoLoader/AutoSplit documentation diff -Pcr perl5_003/pod/perlsub.pod perl5_003_01/pod/perlsub.pod *** perl5_003/pod/perlsub.pod Mon Mar 25 01:05:22 1996 --- perl5_003_01/pod/perlsub.pod Fri Jul 5 16:56:18 1996 *************** *** 58,67 **** Perl does not have named formal parameters, but in practice all you do is assign to a my() list of these. Any variables you use in the function that aren't declared private are global variables. For the gory details ! on creating private variables, see the sections below on L<"Private ! Variables via my()"> and L. To create ! protected environments for a set of functions in a separate package (and ! probably a separate file), see L. Example: --- 58,67 ---- Perl does not have named formal parameters, but in practice all you do is assign to a my() list of these. Any variables you use in the function that aren't declared private are global variables. For the gory details ! on creating private variables, see the sections below on ! L<"Private Variables via my()"> and L<"Temporary Values via local()">. ! To create protected environments for a set of functions in a separate ! package (and probably a separate file), see L. Example: *************** *** 286,292 **** You may declare "my" variables at the outer most scope of a file to totally hide any such identifiers from the outside world. This is similar ! to a C's static variables at the file level. To do this with a subroutine requires the use of a closure (anonymous function). If a block (such as an eval(), function, or C) wants to create a private subroutine that cannot be called from outside that block, it can declare a lexical --- 286,292 ---- You may declare "my" variables at the outer most scope of a file to totally hide any such identifiers from the outside world. This is similar ! to C's static variables at the file level. To do this with a subroutine requires the use of a closure (anonymous function). If a block (such as an eval(), function, or C) wants to create a private subroutine that cannot be called from outside that block, it can declare a lexical *************** *** 342,348 **** =head2 Temporary Values via local() B: In general, you should be using "my" instead of "local", because ! it's faster and safer. Execeptions to this include the global punctuation variables, filehandles and formats, and direct manipulation of the Perl symbol table itself. Format variables often use "local" though, as do other variables whose current value must be visible to called --- 342,348 ---- =head2 Temporary Values via local() B: In general, you should be using "my" instead of "local", because ! it's faster and safer. Exceptions to this include the global punctuation variables, filehandles and formats, and direct manipulation of the Perl symbol table itself. Format variables often use "local" though, as do other variables whose current value must be visible to called *************** *** 637,643 **** The interesting thing about & is that you can generate new syntax with it: ! sub try (&$) { my($try,$catch) = @_; eval { &$try }; if ($@) { --- 637,643 ---- The interesting thing about & is that you can generate new syntax with it: ! sub try (&@) { my($try,$catch) = @_; eval { &$try }; if ($@) { *************** *** 764,770 **** system($program, @_); } date(); ! who('am', i'); ls('-l'); In fact, if you preclare the functions you want to call that way, you don't --- 764,770 ---- system($program, @_); } date(); ! who('am', 'i'); ls('-l'); In fact, if you preclare the functions you want to call that way, you don't *************** *** 779,787 **** can treat undefined subroutine calls as calls to Unix programs. Mechanisms are available for modules writers to help split the modules ! up into autoloadable files. See the standard AutoLoader module described ! in L, the standard SelfLoader modules in L, and ! the document on adding C functions to perl code in L. =head1 SEE ALSO --- 779,788 ---- can treat undefined subroutine calls as calls to Unix programs. Mechanisms are available for modules writers to help split the modules ! up into autoloadable files. See the standard AutoLoader module ! described in L and in L, the standard ! SelfLoader modules in L, and the document on adding C ! functions to perl code in L. =head1 SEE ALSO #~ Quote package name in tie -- required when using strict subs #~ Make return value in example meaningful diff -Pcr perl5_003/pod/perltie.pod perl5_003_01/pod/perltie.pod *** perl5_003/pod/perltie.pod Mon Mar 25 01:05:23 1996 --- perl5_003_01/pod/perltie.pod Mon Jul 15 13:36:22 1996 *************** *** 192,198 **** aggregate assignment would be missed.) For example: require Bounded_Array; ! tie @ary, Bounded_Array, 2; $| = 1; for $i (0 .. 10) { print "setting index $i: "; --- 192,198 ---- aggregate assignment would be missed.) For example: require Bounded_Array; ! tie @ary, 'Bounded_Array', 2; $| = 1; for $i (0 .. 10) { print "setting index $i: "; *************** *** 317,323 **** contents. For example: use DotFiles; ! tie %dot, DotFiles; if ( $dot{profile} =~ /MANPATH/ || $dot{login} =~ /MANPATH/ || $dot{cshrc} =~ /MANPATH/ ) --- 317,323 ---- contents. For example: use DotFiles; ! tie %dot, 'DotFiles'; if ( $dot{profile} =~ /MANPATH/ || $dot{login} =~ /MANPATH/ || $dot{cshrc} =~ /MANPATH/ ) *************** *** 327,333 **** Or here's another sample of using our tied class: ! tie %him, DotFiles, 'daemon'; foreach $f ( keys %him ) { printf "daemon dot file %s is size %d\n", $f, length $him{$f}; --- 327,333 ---- Or here's another sample of using our tied class: ! tie %him, 'DotFiles', 'daemon'; foreach $f ( keys %him ) { printf "daemon dot file %s is size %d\n", $f, length $him{$f}; *************** *** 509,517 **** croak "@{[&whowasi]}: won't remove file $file" unless $self->{CLOBBER}; delete $self->{LIST}->{$dot}; ! unlink($file) || carp "@{[&whowasi]}: can't unlink $file: $!"; } =item CLEAR this This method is triggered when the whole hash is to be cleared, usually by --- 509,525 ---- croak "@{[&whowasi]}: won't remove file $file" unless $self->{CLOBBER}; delete $self->{LIST}->{$dot}; ! my $success = unlink($file); ! carp "@{[&whowasi]}: can't unlink $file: $!" unless $success; ! $success; } + The value returned by DELETE becomes the return value of the call + to delete(). If you want to emulate the normal behavior of delete(), + you should return whatever FETCH would have returned for this key. + In this example, we have chosen instead to return a value which tells + the caller whether the file was successfully deleted. + =item CLEAR this This method is triggered when the whole hash is to be cleared, usually by *************** *** 592,598 **** # print out history file offsets use NDBM_File; ! tie(%HIST, NDBM_File, '/usr/lib/news/history', 1, 0); while (($key,$val) = each %HIST) { print $key, ' = ', unpack('L',$val), "\n"; } --- 600,606 ---- # print out history file offsets use NDBM_File; ! tie(%HIST, 'NDBM_File', '/usr/lib/news/history', 1, 0); while (($key,$val) = each %HIST) { print $key, ' = ', unpack('L',$val), "\n"; } #~ Fix pod formatting diff -Pcr perl5_003/pod/perltoc.pod perl5_003_01/pod/perltoc.pod *** perl5_003/pod/perltoc.pod Mon Mar 25 01:05:23 1996 --- perl5_003_01/pod/perltoc.pod Fri Jul 5 17:03:18 1996 *************** *** 323,329 **** =item Alphabetical Listing of Perl Functions ! -X FILEHANDLE, -X EXPR, -X, abs VALUE, accept NEWSOCKET,GENERICSOCKET, alarm SECONDS, atan2 Y,X, bind SOCKET,NAME, binmode FILEHANDLE, bless REF,CLASSNAME, bless REF, caller EXPR, caller, chdir EXPR, chmod LIST, chomp VARIABLE, chomp LIST, chomp, chop VARIABLE, chop LIST, chop, --- 323,329 ---- =item Alphabetical Listing of Perl Functions ! -I FILEHANDLE, -I EXPR, -I, abs VALUE, accept NEWSOCKET,GENERICSOCKET, alarm SECONDS, atan2 Y,X, bind SOCKET,NAME, binmode FILEHANDLE, bless REF,CLASSNAME, bless REF, caller EXPR, caller, chdir EXPR, chmod LIST, chomp VARIABLE, chomp LIST, chomp, chop VARIABLE, chop LIST, chop, *************** *** 1697,1703 **** overload::StrVal(arg), overload::Overloaded(arg), ! overload::Method(obj,op) =item IMPLEMENTATION --- 1697,1703 ---- overload::StrVal(arg), overload::Overloaded(arg), ! C =item IMPLEMENTATION *************** *** 1831,1837 **** =item Standard Exports ! timeit(COUNT, CODE), timethis, timethese, timediff, timestr =item Optional Exports --- 1831,1837 ---- =item Standard Exports ! C, timethis, timethese, timediff, timestr =item Optional Exports #~ Typos and pod formatting corrected #~ Perl4 - Perl5 traps revised extensively diff -Pcr perl5_003/pod/perltrap.pod perl5_003_01/pod/perltrap.pod *** perl5_003/pod/perltrap.pod Tue Jan 30 13:23:50 1996 --- perl5_003_01/pod/perltrap.pod Mon Jul 29 19:27:52 1996 *************** *** 58,64 **** =item * Reading an input line does not split it for you. You get to split it ! yourself to an array. And split() operator has different arguments. =item * --- 58,64 ---- =item * Reading an input line does not split it for you. You get to split it ! yourself to an array. And the split() operator has different arguments. =item * *************** *** 172,178 **** =item * ! printf() does not implement the "*" format for interpolating field widths, but it's trivial to use interpolation of double-quoted strings to achieve the same effect. --- 172,178 ---- =item * ! C does not implement the "*" format for interpolating field widths, but it's trivial to use interpolation of double-quoted strings to achieve the same effect. *************** *** 231,237 **** =item * ! The backtick operator does variable interpretation without regard to the presence of single quotes in the command. =item * --- 231,237 ---- =item * ! The backtick operator does variable interpolation without regard to the presence of single quotes in the command. =item * *************** *** 293,299 **** default to $_, or @ARGV, or whatever, but that others which you might expect to do not. ! =item * The construct is not the name of the filehandle, it is a readline operation on that handle. The data read is only assigned to $_ if the --- 293,299 ---- default to $_, or @ARGV, or whatever, but that others which you might expect to do not. ! =item * The construct is not the name of the filehandle, it is a readline operation on that handle. The data read is only assigned to $_ if the *************** *** 303,309 **** while ($_ = ) { }.. ; # data discarded! ! =item * Remember not to use "C<=>" when you need "C<=~>"; these two constructs are quite different: --- 303,309 ---- while ($_ = ) { }.. ; # data discarded! ! =item * Remember not to use "C<=>" when you need "C<=~>"; these two constructs are quite different: *************** *** 318,326 **** =item * ! Use my() for local variables whenever you can get away with it (but see L for where you can't). ! Using local() actually gives a local value to a global variable, which leaves you open to unforeseen side-effects of dynamic scoping. --- 318,326 ---- =item * ! Use C for local variables whenever you can get away with it (but see L for where you can't). ! Using C actually gives a local value to a global variable, which leaves you open to unforeseen side-effects of dynamic scoping. *************** *** 332,406 **** =back ! =head2 Perl4 Traps ! Penitent Perl 4 Programmers should take note of the following ! incompatible changes that occurred between release 4 and release 5: =over 4 ! =item * ! C<@> now always interpolates an array in double-quotish strings. Some programs ! may now need to use backslash to protect any C<@> that shouldn't interpolate. ! =item * ! Barewords that used to look like strings to Perl will now look like subroutine ! calls if a subroutine by that name is defined before the compiler sees them. ! For example: ! sub SeeYa { die "Hasta la vista, baby!" } ! $SIG{'QUIT'} = SeeYa; ! In Perl 4, that set the signal handler; in Perl 5, it actually calls the ! function! You may use the B<-w> switch to find such places. ! =item * ! Symbols starting with C<_> are no longer forced into package C
, except ! for $_ itself (and @_, etc.). ! =item * ! Double-colon is now a valid package separator in an identifier. Thus these ! behave differently in perl4 vs. perl5: ! print "$a::$b::$c\n"; print "$var::abc::xyz\n"; ! =item * ! C now does no interpolation on either side. It used to ! interpolate C<$lhs> but not C<$rhs>. ! =item * ! The second and third arguments of splice() are now evaluated in scalar ! context (as the book says) rather than list context. ! =item * ! These are now semantic errors because of precedence: ! shift @list + 20; ! $n = keys %map + 20; ! Because if that were to work, then this couldn't: ! sleep $dormancy + 20; ! =item * The precedence of assignment operators is now the same as the precedence of assignment. Perl 4 mistakenly gave them the precedence of the associated operator. So you now must parenthesize them in expressions like /foo/ ? ($a += 2) : ($a -= 2); ! Otherwise ! /foo/ ? $a += 2 : $a -= 2; would be erroneously parsed as --- 332,898 ---- =back ! =head2 Perl4 to Perl5 Traps ! Practicing Perl4 Programmers should take note of the following ! Perl4-to-Perl5 specific traps. ! ! They're crudely ordered according to the following list: =over 4 ! =item Discontinuance, Deprecation, and BugFix traps ! Anything that's been fixed as a perl4 bug, removed as a perl4 feature ! or deprecated as a perl4 feature with the intent to encourage usage of ! some other perl5 feature. ! =item Parsing Traps ! Traps that appear to stem from the new parser. ! =item Numerical Traps ! Traps having to do with numerical or mathematical operators. ! =item General data type traps ! Traps involving perl standard data types. ! =item Context Traps - scalar, list contexts ! ! Traps related to context within lists, scalar statements/declarations. ! ! =item Precedence Traps ! ! Traps related to the precedence of parsing, evaluation, and execution of ! code. ! ! =item General Regular Expression Traps using s///, etc. ! Traps related to the use of pattern matching. ! ! =item Subroutine, Signal, Sorting Traps ! ! Traps related to the use of signals and signal handlers, general subroutines, ! and sorting, along with sorting subroutines. ! ! =item OS Traps ! ! OS-specific traps. ! ! =item DBM Traps ! ! Traps specific to the use of C, and specific dbm implementations. ! ! =item Unclassified Traps ! ! Everything else. ! ! =back ! ! If you find an example of a conversion trap that is not listed here, ! please submit it to Bill Middleton F for inclusion. ! Also note that at least some of these can be caught with C<-w>. ! ! =head2 Discontinuance, Deprecation, and BugFix traps ! ! Anything that has been discontinued, deprecated, or fixed as ! a bug from perl4. ! ! =over 4 ! =item * Discontinuance ! ! Symbols starting with "_" are no longer forced into package main, except ! for C<$_> itself (and C<@_>, etc.). ! ! package test; ! $_legacy = 1; ! ! package main; ! print "\$_legacy is ",$_legacy,"\n"; ! ! # perl4 prints: $_legacy is 1 ! # perl5 prints: $_legacy is ! ! =item * Deprecation ! ! Double-colon is now a valid package separator in a variable name. Thus these ! behave differently in perl4 vs. perl5, since the packages don't exist. ! ! $a=1;$b=2;$c=3;$var=4; ! print "$a::$b::$c "; print "$var::abc::xyz\n"; + + # perl4 prints: 1::2::3 4::abc::xyz + # perl5 prints: 3 + + Given that C<::> is now the preferred package delimiter, it is debatable + whether this should be classed as a bug or not. + (The older package delimiter, ' ,is used here) + + $x = 10 ; + print "x=${'x}\n" ; + + # perl4 prints: x=10 + # perl5 prints: Can't find string terminator "'" anywhere before EOF + + Also see precedence traps, for parsing C<$:>. + + =item * BugFix + + The second and third arguments of C are now evaluated in scalar + context (as the Camel says) rather than list context. + + sub sub1{return(0,2) } # return a 2-elem array + sub sub2{ return(1,2,3)} # return a 3-elem array + @a1 = ("a","b","c","d","e"); + @a2 = splice(@a1,&sub1,&sub2); + print join(' ',@a2),"\n"; + + # perl4 prints: a b + # perl5 prints: c d e ! =item * Discontinuance ! You can't do a C into a block that is optimized away. Darn. ! goto marker1; ! for(1){ ! marker1: ! print "Here I is!\n"; ! } ! ! # perl4 prints: Here I is! ! # perl5 dumps core (SEGV) ! =item * Discontinuance ! It is no longer syntactically legal to use whitespace as the name ! of a variable, or as a delimiter for any kind of quote construct. ! Double darn. ! $a = ("foo bar"); ! $b = q baz ; ! print "a is $a, b is $b\n"; ! ! # perl4 prints: a is foo bar, b is baz ! # perl5 errors: Bare word found where operator expected ! ! =item * Discontinuance ! ! The archaic while/if BLOCK BLOCK syntax is no longer supported. ! ! if { 1 } { ! print "True!"; ! } ! else { ! print "False!"; ! } ! ! # perl4 prints: True! ! # perl5 errors: syntax error at test.pl line 1, near "if {" ! =item * BugFix ! The C<**> operator now binds more tightly than unary minus. ! It was documented to work this way before, but didn't. ! print -4**2,"\n"; ! ! # perl4 prints: 16 ! # perl5 prints: -16 ! ! =item * Discontinuance ! ! The meaning of C has changed slightly when it is iterating over a ! list which is not an array. This used to assign the list to a ! temporary array, but no longer does so (for efficiency). This means ! that you'll now be iterating over the actual values, not over copies of ! the values. Modifications to the loop variable can change the original ! values. ! ! @list = ('ab','abc','bcd','def'); ! foreach $var (grep(/ab/,@list)){ ! $var = 1; ! } ! print (join(':',@list)); ! ! # perl4 prints: ab:abc:bcd:def ! # perl5 prints: 1:1:bcd:def ! ! To retain Perl4 semantics you need to assign your list ! explicitly to a temporary array and then iterate over that. For ! example, you might need to change ! ! foreach $var (grep(/ab/,@list)){ ! ! to ! ! foreach $var (@tmp = grep(/ab/,@list)){ ! ! Otherwise changing $var will clobber the values of @list. (This most often ! happens when you use C<$_> for the loop variable, and call subroutines in ! the loop that don't properly localize C<$_>.) ! ! =item * Deprecation ! ! Some error messages will be different. ! ! =item * Discontinuance ! ! Some bugs may have been inadvertently removed. :-) ! ! =back ! ! =head2 Parsing Traps ! ! Perl4-to-Perl5 traps from having to do with parsing. ! ! =over 4 ! ! =item * Parsing ! ! Note the space between . and = ! ! $string . = "more string"; ! print $string; ! ! # perl4 prints: more string ! # perl5 prints: syntax error at - line 1, near ". =" ! ! =item * Parsing ! ! Better parsing in perl 5 ! ! sub foo {} ! &foo ! print("hello, world\n"); ! ! # perl4 prints: hello, world ! # perl5 prints: syntax error ! ! =item * Parsing ! ! "if it looks like a function, it is a function" rule. ! ! print ! ($foo == 1) ? "is one\n" : "is zero\n"; ! ! # perl4 prints: is zero ! # perl5 warns: "Useless use of a constant in void context" if using -w ! ! =back ! ! =head2 Numerical Traps ! ! Perl4-to-Perl5 traps having to do with numerical operators, ! operands, or output from same. ! ! =over 5 ! ! =item * Numerical ! ! Formatted output and significant digits ! ! print 7.373504 - 0, "\n"; ! printf "%20.18f\n", 7.373504 - 0; ! ! # Perl4 prints: ! 7.375039999999996141 ! 7.37503999999999614 ! ! # Perl5 prints: ! 7.373504 ! 7.37503999999999614 ! ! =item * Numerical ! ! Large integer trap with autoincrement ! ! $a = $b = 2147483647; ! print "$a $b\n"; ! $a += 1; ! $b++; ! print "$a $b\n"; ! ! # perl4 prints: ! 2147483647 2147483647 ! 2147483648 2147483648 ! ! # perl5 prints: ! 2147483647 2147483647 ! 2147483648 -2147483648 ! ! =item * Numerical ! ! Assignment of return values from numeric equality tests ! does not work in perl5 when the test evaluates to false (0). ! Logical tests now return an null, instead of 0 ! ! $p = ($test == 1); ! print $p,"\n"; ! ! # perl4 prints: 0 ! # perl5 prints: ! ! Also see the L tests for another example ! of this new feature... ! ! =back ! ! =head2 General data type traps ! ! Perl4-to-Perl5 traps involving most data-types, and their usage ! within certain expressions and/or context. ! ! =over 5 ! ! =item * (Arrays) ! ! Negative array subscripts now count from the end of the array. ! ! @a = (1, 2, 3, 4, 5); ! print "The third element of the array is $a[3] also expressed as $a[-2] \n"; ! ! # perl4 prints: The third element of the array is 4 also expressed as ! # perl5 prints: The third element of the array is 4 also expressed as 4 ! ! =item * (Arrays) ! ! Setting C<$#array> lower now discards array elements, and makes them ! impossible to recover. ! ! @a = (a,b,c,d,e); ! print "Before: ",join('',@a); ! $#a =1; ! print ", After: ",join('',@a); ! $#a =3; ! print ", Recovered: ",join('',@a),"\n"; ! ! # perl4 prints: Before: abcde, After: ab, Recovered: abcd ! # perl5 prints: Before: abcde, After: ab, Recovered: ab ! ! =item * (Hashes) ! ! Hashes get defined before use ! ! local($s,@a,%h); ! die "scalar \$s defined" if defined($s); ! die "array \@a defined" if defined(@a); ! die "hash \%h defined" if defined(%h); ! ! # perl4 prints: ! # perl5 dies: hash %h defined ! ! =item * (Globs) ! ! glob assignment from variable to variable will fail if the assigned ! variable is localized subsequent to the assignment ! ! @a = ("This is Perl 4"); ! *b = *a; ! local(@a); ! print @b,"\n"; ! ! # perl4 prints: This is Perl 4 ! # perl5 prints: ! ! # Another example ! ! *fred = *barney; # fred is aliased to barney ! @barney = (1, 2, 4); ! # @fred; ! print "@fred"; # should print "1, 2, 4" ! ! # perl4 prints: 1 2 4 ! # perl5 prints: Literal @fred now requires backslash ! ! =item * (Scalar String) ! ! Changes in unary negation (of strings) ! This change effects both the return value and what it ! does to auto(magic)increment. ! ! $x = "aaa"; ! print ++$x," : "; ! print -$x," : "; ! print ++$x,"\n"; ! ! # perl4 prints: aab : -0 : 1 ! # perl5 prints: aab : -aab : aac ! ! =item * (Constants) ! ! perl 4 lets you modify constants: ! ! $foo = "x"; ! &mod($foo); ! for ($x = 0; $x < 3; $x++) { ! &mod("a"); ! } ! sub mod { ! print "before: $_[0]"; ! $_[0] = "m"; ! print " after: $_[0]\n"; ! } ! ! # perl4: ! # before: x after: m ! # before: a after: m ! # before: m after: m ! # before: m after: m ! ! # Perl5: ! # before: x after: m ! # Modification of a read-only value attempted at foo.pl line 12. ! # before: a ! ! =item * (Scalars) ! ! The behavior is slightly different for: ! ! print "$x", defined $x ! ! # perl 4: 1 ! # perl 5: ! ! =item * (Variable Suicide) ! ! Variable suicide behavior is more consistent under Perl 5. ! Perl5 exhibits the same behavior for associative arrays and scalars, ! that perl4 exhibits only for scalars. ! ! $aGlobal{ "aKey" } = "global value"; ! print "MAIN:", $aGlobal{"aKey"}, "\n"; ! $GlobalLevel = 0; ! &test( *aGlobal ); ! ! sub test { ! local( *theArgument ) = @_; ! local( %aNewLocal ); # perl 4 != 5.001l,m ! $aNewLocal{"aKey"} = "this should never appear"; ! print "SUB: ", $theArgument{"aKey"}, "\n"; ! $aNewLocal{"aKey"} = "level $GlobalLevel"; # what should print ! $GlobalLevel++; ! if( $GlobalLevel<4 ) { ! &test( *aNewLocal ); ! } ! } ! ! # Perl4: ! # MAIN:global value ! # SUB: global value ! # SUB: level 0 ! # SUB: level 1 ! # SUB: level 2 ! ! # Perl5: ! # MAIN:global value ! # SUB: global value ! # SUB: this should never appear ! # SUB: this should never appear ! # SUB: this should never appear ! ! =back ! ! =head2 Context Traps - scalar, list contexts ! ! =over 5 ! ! =item * (list context) ! ! The elements of argument lists for formats are now evaluated in list ! context. This means you can interpolate list values now. ! ! @fmt = ("foo","bar","baz"); ! format STDOUT= ! @<<<<< @||||| @>>>>> ! @fmt; ! . ! write; ! ! # perl4 errors: Please use commas to separate fields in file ! # perl5 prints: foo bar baz ! ! =item * (scalar context) ! ! The C function now returns a false value in a scalar context ! if there is no caller. This lets library files determine if they're ! being required. ! ! caller() ? (print "You rang?\n") : (print "Got a 0\n"); ! ! # perl4 errors: There is no caller ! # perl5 prints: Got a 0 ! ! =item * (scalar context) ! ! The comma operator in a scalar context is now guaranteed to give a ! scalar context to its arguments. ! ! @y= ('a','b','c'); ! $x = (1, 2, @y); ! print "x = $x\n"; ! ! # Perl4 prints: x = c # Thinks list context interpolates list ! # Perl5 prints: x = 3 # Knows scalar uses length of list ! ! =item * (list, builtin) ! ! C funkiness (array argument converted to scalar array count) ! This test could be added to t/op/sprintf.t ! ! @z = ('%s%s', 'foo', 'bar'); ! $x = sprintf(@z); ! if ($x eq 'foobar') {print "ok 2\n";} else {print "not ok 2 '$x'\n";} ! ! # perl4 prints: ok 2 ! # perl5 prints: not ok 2 ! ! C works fine, though: ! ! printf STDOUT (@z); ! print "\n"; ! ! # perl4 prints: foobar ! # perl5 prints: foobar ! ! Probably a bug. ! ! =back ! ! =head2 Precedence Traps ! ! Perl4-to-Perl5 traps involving precedence order. ! ! =item * ! ! These are now semantic errors because of precedence: ! ! @list = (1,2,3,4,5); ! %map = ("a",1,"b",2,"c",3,"d",4); ! $n = shift @list + 2; # first item in list plus 2 ! print "n is $n, "; ! $m = keys %map + 2; # number of items in hash plus 2 ! print "m is $m\n"; ! ! # perl4 prints: n is 3, m is 6 ! # perl5 errors and fails to compile ! ! =item * Precedence The precedence of assignment operators is now the same as the precedence of assignment. Perl 4 mistakenly gave them the precedence of the associated operator. So you now must parenthesize them in expressions like /foo/ ? ($a += 2) : ($a -= 2); ! Otherwise ! /foo/ ? $a += 2 : $a -= 2 would be erroneously parsed as *************** *** 408,522 **** On the other hand, ! $a += /foo/ ? 1 : 2; now works as a C programmer would expect. ! =item * ! C is now incorrect. You need parens around the filehandle. ! While temporarily supported, using such a construct will ! generate a non-fatal (but non-suppressible) warning. ! =item * ! The elements of argument lists for formats are now evaluated in list ! context. This means you can interpolate list values now. ! =item * ! You can't do a C into a block that is optimized away. Darn. ! =item * ! It is no longer syntactically legal to use whitespace as the name ! of a variable, or as a delimiter for any kind of quote construct. ! Double darn. ! =item * ! The caller() function now returns a false value in a scalar context if there ! is no caller. This lets library files determine if they're being required. ! =item * C now attaches its state to the searched string rather than the ! regular expression. ! =item * - C is no longer allowed as the name of a sort subroutine. ! =item * ! B is no longer a separate executable. There is now a B<-T> ! switch to turn on tainting when it isn't turned on automatically. ! =item * ! Double-quoted strings may no longer end with an unescaped C<$> or C<@>. ! =item * ! The archaic C BLOCK BLOCK syntax is no longer supported. ! =item * ! Negative array subscripts now count from the end of the array. ! =item * ! The comma operator in a scalar context is now guaranteed to give a ! scalar context to its arguments. ! =item * - The C<**> operator now binds more tightly than unary minus. - It was documented to work this way before, but didn't. - =item * ! Setting C<$#array> lower now discards array elements. ! =item * ! delete() is not guaranteed to return the old value for tie()d arrays, ! since this capability may be onerous for some modules to implement. ! =item * The construct "this is $$x" used to interpolate the pid at that ! point, but now tries to dereference $x. C<$$> by itself still works fine, however. ! =item * ! The meaning of foreach has changed slightly when it is iterating over a ! list which is not an array. This used to assign the list to a ! temporary array, but no longer does so (for efficiency). This means ! that you'll now be iterating over the actual values, not over copies of ! the values. Modifications to the loop variable can change the original ! values. To retain Perl 4 semantics you need to assign your list ! explicitly to a temporary array and then iterate over that. For ! example, you might need to change ! foreach $var (grep /x/, @list) { ... } to ! foreach $var (my @tmp = grep /x/, @list) { ... } ! Otherwise changing C<$var> will clobber the values of @list. (This most often ! happens when you use C<$_> for the loop variable, and call subroutines in ! the loop that don't properly localize C<$_>.) ! =item * ! Some error messages will be different. ! =item * ! Some bugs may have been inadvertently removed. =back --- 900,1354 ---- On the other hand, ! $a += /foo/ ? 1 : 2; now works as a C programmer would expect. ! =item * Precedence ! open FOO || die; ! is now incorrect. You need parens around the filehandle. ! Otherwise, perl5 leaves the statement as it's default precedence: ! open(FOO || die); ! ! # perl4 opens or dies ! # perl5 errors: Precedence problem: open FOO should be open(FOO) ! =item * Precedence ! perl4 gives the special variable, C<$:> precedence, where perl5 ! treats C<$::> as main C ! $a = "x"; print "$::a"; ! ! # perl 4 prints: -:a ! # perl 5 prints: x ! ! =item * Precedence ! concatenation precedence over filetest operator? ! -e $foo .= "q" ! ! # perl4 prints: no output ! # perl5 prints: Can't modify -e in concatenation ! =item * Precedence ! Assignment to value takes precedence over assignment to key in ! perl5 when using the shift operator on both sides. ! ! @arr = ( 'left', 'right' ); ! $a{shift @arr} = shift @arr; ! print join( ' ', keys %a ); ! ! # perl4 prints: left ! # perl5 prints: right ! ! =back ! ! =head2 General Regular Expression Traps using s///, etc. ! ! All types of RE traps. ! ! =over 5 ! ! =item * Regular Expression ! ! C now does no interpolation on either side. It used to ! interpolate C<$lhs> but not C<$rhs>. (And still does not match a literal ! '$' in string) ! ! $a=1;$b=2; ! $string = '1 2 $a $b'; ! $string =~ s'$a'$b'; ! print $string,"\n"; ! ! # perl4 prints: $b 2 $a $b ! # perl5 prints: 1 2 $a $b ! ! =item * Regular Expression C now attaches its state to the searched string rather than the ! regular expression. (Once the scope of a block is left for the sub, the ! state of the searched string is lost) ! $_ = "ababab"; ! while(m/ab/g){ ! &doit("blah"); ! } ! sub doit{local($_) = shift; print "Got $_ "} ! ! # perl4 prints: blah blah blah ! # perl5 prints: infinite loop blah... ! ! =item * Regular Expression ! ! If no parentheses are used in a match, Perl4 sets C<$+> to ! the whole match, just like C<$&>. Perl5 does not. ! ! "abcdef" =~ /b.*e/; ! print "\$+ = $+\n"; ! ! # perl4 prints: bcde ! # perl5 prints: ! ! =item * Regular Expression ! ! substitution now returns the null string if it fails ! ! $string = "test"; ! $value = ($string =~ s/foo//); ! print $value, "\n"; ! ! # perl4 prints: 0 ! # perl5 prints: ! ! Also see L for another example of this new feature. ! ! =item * Regular Expression ! ! C (using backticks) is now a normal substitution, with no ! backtick expansion ! ! $string = ""; ! $string =~ s`^`hostname`; ! print $string, "\n"; ! ! # perl4 prints: ! # perl5 prints: hostname ! ! =item * Regular Expression ! ! Stricter parsing of variables used in regular expressions ! ! s/^([^$grpc]*$grpc[$opt$plus$rep]?)//o; ! ! # perl4: compiles w/o error ! # perl5: with Scalar found where operator expected ..., near "$opt$plus" ! ! an added component of this example, apparently from the same script, is ! the actual value of the s'd string after the substitution. ! C<[$opt]> is a character class in perl4 and an array subscript in perl5 ! ! $grpc = 'a'; ! $opt = 'r'; ! $_ = 'bar'; ! s/^([^$grpc]*$grpc[$opt]?)/foo/; ! print ; ! ! # perl4 prints: foo ! # perl5 prints: foobar ! ! =item * Regular Expression ! ! Under perl5, C matches only once, like C. Under perl4, it matched ! repeatedly, like C or C. ! ! $test = "once"; ! sub match { $test =~ m?once?; } ! &match(); ! if( &match() ) { ! # m?x? matches more then once ! print "perl4\n"; ! } else { ! # m?x? matches only once ! print "perl5\n"; ! } ! ! # perl4 prints: perl4 ! # perl5 prints: perl5 ! =back ! =head2 Subroutine, Signal, Sorting Traps ! The general group of Perl4-to-Perl5 traps having to do with ! Signals, Sorting, and their related subroutines, as well as ! general subroutine traps. Includes some OS-Specific traps. ! =over 5 ! =item * (Signals) ! Barewords that used to look like strings to Perl will now look like subroutine ! calls if a subroutine by that name is defined before the compiler sees them. + sub SeeYa { warn"Hasta la vista, baby!" } + $SIG{'TERM'} = SeeYa; + print "SIGTERM is now $SIG{'TERM'}\n"; + + # perl4 prints: SIGTERM is main'SeeYa + # perl5 prints: SIGTERM is now main::1 + + Use B<-w> to catch this one + + =item * (Sort Subroutine) + + reverse is no longer allowed as the name of a sort subroutine. + + sub reverse{ print "yup "; $a <=> $b } + print sort reverse a,b,c; + + # perl4 prints: yup yup yup yup abc + # perl5 prints: abc ! =back ! =head2 OS Traps ! =over 5 ! =item * (SysV) ! Under HPUX, and some other SysV OS's, one had to reset any signal handler, ! within the signal handler function, each time a signal was handled with ! perl4. With perl5, the reset is now done correctly. Any code relying ! on the handler _not_ being reset will have to be reworked. ! ! 5.002 and beyond uses sigaction() under SysV ! ! sub gotit { ! print "Got @_... "; ! } ! $SIG{'INT'} = 'gotit'; ! ! $| = 1; ! $pid = fork; ! if ($pid) { ! kill('INT', $pid); ! sleep(1); ! kill('INT', $pid); ! } else { ! while (1) {sleep(10);} ! } ! ! # perl4 (HPUX) prints: Got INT... ! # perl5 (HPUX) prints: Got INT... Got INT... ! ! =item * (SysV) ! ! Under SysV OS's, C on a file opened to append CE> now does ! the right thing w.r.t. the fopen() man page. e.g. - When a file is opened ! for append, it is impossible to overwrite information already in ! the file. ! ! open(TEST,">>seek.test"); ! $start = tell TEST ; ! foreach(1 .. 9){ ! print TEST "$_ "; ! } ! $end = tell TEST ; ! seek(TEST,$start,0); ! print TEST "18 characters here"; ! ! # perl4 (solaris) seek.test has: 18 characters here ! # perl5 (solaris) seek.test has: 1 2 3 4 5 6 7 8 9 18 characters here ! =back ! =head2 Interpolation Traps ! =over 5 ! =item * Interpolation ! ! @ now always interpolates an array in double-quotish strings. ! ! print "To: someone@somewhere.com\n"; ! ! # perl4 prints: To:someone@somewhere.com ! # perl5 errors : Literal @somewhere now requires backslash ! ! =item * Interpolation ! ! Perl4-to-Perl5 traps having to do with how things get interpolated ! within certain expressions, statements, contexts, or whatever. ! ! Double-quoted strings may no longer end with an unescaped $ or @. ! ! $foo = "foo$"; ! $bar = "bar@"; ! print "foo is $foo, bar is $bar\n"; ! ! # perl4 prints: foo is foo$, bar is bar@ ! # perl5 errors: Final $ should be \$ or $name ! ! Note: perl5 DOES NOT error on the terminating @ in $bar ! ! =item * Interpolation The construct "this is $$x" used to interpolate the pid at that ! point, but now apparently tries to dereference C<$x>. C<$$> by itself still works fine, however. ! print "this is $$x\n"; ! # perl4 prints: this is XXXx (XXX is the current pid) ! # perl5 prints: this is ! ! =item * Interpolation ! ! Creation of hashes on the fly with C now requires either both ! C<$>'s to be protected in the specification of the hash name, or both curlies ! to be protected. If both curlies are protected, the result will be compatible ! with perl4 and perl5. This is a very common practice, and should be changed ! to use the block form of C if possible. ! $hashname = "foobar"; ! $key = "baz"; ! $value = 1234; ! eval "\$$hashname{'$key'} = q|$value|"; ! (defined($foobar{'baz'})) ? (print "Yup") : (print "Nope"); ! ! # perl4 prints: Yup ! # perl5 prints: Nope ! ! Changing ! ! eval "\$$hashname{'$key'} = q|$value|"; to ! eval "\$\$hashname{'$key'} = q|$value|"; ! causes the following result: ! # perl4 prints: Nope ! # perl5 prints: Yup ! or, changing to ! eval "\$$hashname\{'$key'\} = q|$value|"; ! ! causes the following result: ! ! # perl4 prints: Yup ! # perl5 prints: Yup ! # and is compatible for both versions ! ! ! =item * Interpolation ! ! perl4 programs which unconsciously rely on the bugs in earlier perl versions. ! ! perl -e '$bar=q/not/; print "This is $foo{$bar} perl5"' ! ! # perl4 prints: This is not perl5 ! # perl5 prints: This is perl5 ! ! =item * Interpolation ! ! You also have to be careful about array references. ! ! print "$foo{" ! ! perl 4 prints: { ! perl 5 prints: syntax error ! ! =item * Interpolation ! ! Similarly, watch out for: ! ! $foo = "array"; ! print "\$$foo{bar}\n"; ! ! # perl4 prints: $array{bar} ! # perl5 prints: $ ! ! Perl 5 is looking for C<$array{bar}> which doesn't exist, but perl 4 is ! happy just to expand $foo to "array" by itself. Watch out for this ! especially in C's. ! ! =item * Interpolation ! ! C string passed to C ! ! eval qq( ! foreach \$y (keys %\$x\) { ! \$count++; ! } ! ); ! ! # perl4 runs this ok ! # perl5 prints: Can't find string terminator ")" ! =back ! ! =head2 DBM Traps ! ! General DBM traps. ! ! =over 5 ! ! =item * DBM ! ! Existing dbm databases created under perl4 (or any other dbm/ndbm tool) ! may cause the same script, run under perl5, to fail. The build of perl5 ! must have been linked with the same dbm/ndbm as the default for C ! to function properly without C'ing to an extension dbm implementation. ! ! dbmopen (%dbm, "file", undef); ! print "ok\n"; ! ! # perl4 prints: ok ! # perl5 prints: ok (IFF linked with -ldbm or -lndbm) ! ! ! =item * DBM ! ! Existing dbm databases created under perl4 (or any other dbm/ndbm tool) ! may cause the same script, run under perl5, to fail. The error generated ! when exceeding the limit on the key/value size will cause perl5 to exit ! immediately. ! ! dbmopen(DB, "testdb",0600) || die "couldn't open db! $!"; ! $DB{'trap'} = "x" x 1024; # value too large for most dbm/ndbm ! print "YUP\n"; ! ! # perl4 prints: ! dbm store returned -1, errno 28, key "trap" at - line 3. ! YUP ! ! # perl5 prints: ! dbm store returned -1, errno 28, key "trap" at - line 3. =back + + =head2 Unclassified Traps + + Everything else. + + =item * Unclassified + + C/C trap using returned value + + If the file doit.pl has: + + sub foo { + $rc = do "./do.pl"; + return 8; + } + print &foo, "\n"; + + And the do.pl file has the following single line: + + return 3; + + Running doit.pl gives the following: + + # perl 4 prints: 3 (aborts the subroutine early) + # perl 5 prints: 8 + + Same behavior if you replace C with C. + + =back + + As always, if any of these are ever officially declared as bugs, + they'll be fixed and removed. + #~ Correct pod formatting #~ Expand documentation for $. and $| #~ Correct $# documentation for initial value #~ Add documentation for $^H diff -Pcr perl5_003/pod/perlvar.pod perl5_003_01/pod/perlvar.pod *** perl5_003/pod/perlvar.pod Mon Mar 25 01:05:23 1996 --- perl5_003_01/pod/perlvar.pod Fri Jul 5 17:25:41 1996 *************** *** 102,107 **** --- 102,111 ---- (Mnemonic: underline is understood in certain operations.) + =back + + =over 8 + =item $> Contains the subpattern from the corresponding set of parentheses in *************** *** 176,183 **** =item $. ! The current input line number of the last filehandle that was read. An ! explicit close on the filehandle resets the line number. Since "CE>" never does an explicit close, line numbers increase across ARGV files (but see examples under eof()). Localizing C<$.> has the effect of also localizing Perl's notion of "the last read --- 180,188 ---- =item $. ! The current input line number for the last file handle from ! which you read (or performed a C or on). An ! explicit close on a filehandle resets the line number. Since "CE>" never does an explicit close, line numbers increase across ARGV files (but see examples under eof()). Localizing C<$.> has the effect of also localizing Perl's notion of "the last read *************** *** 214,225 **** =item $| If set to nonzero, forces a flush after every write or print on the ! currently selected output channel. Default is 0. Note that STDOUT ! will typically be line buffered if output is to the terminal and block ! buffered otherwise. Setting this variable is useful primarily when you ! are outputting to a pipe, such as when you are running a Perl script ! under rsh and want to see the output as it's happening. This has no ! effect on input buffering. (Mnemonic: when you want your pipes to be piping hot.) =item output_field_separator HANDLE EXPR --- 219,232 ---- =item $| If set to nonzero, forces a flush after every write or print on the ! currently selected output channel. Default is 0 (regardless of whether ! the channel is actually buffered by the system or not; C<$|> only tells ! you whether you've asked Perl to explicitly flush after each write). ! Note that STDOUT will typically be line buffered if output is to the ! terminal and block buffered otherwise. Setting this variable is useful ! primarily when you are outputting to a pipe, such as when you are running ! a Perl script under rsh and want to see the output as it's happening. This ! has no effect on input buffering. (Mnemonic: when you want your pipes to be piping hot.) =item output_field_separator HANDLE EXPR *************** *** 300,308 **** The output format for printed numbers. This variable is a half-hearted attempt to emulate B's OFMT variable. There are times, however, when B and Perl have differing notions of what is in fact ! numeric. Also, the initial value is %.20g rather than %.6g, so you ! need to set "C<$#>" explicitly to get B's value. (Mnemonic: # is the ! number sign.) Use of "C<$#>" is deprecated in Perl 5. --- 307,316 ---- The output format for printed numbers. This variable is a half-hearted attempt to emulate B's OFMT variable. There are times, however, when B and Perl have differing notions of what is in fact ! numeric. The initial value is %.Ig, where I is the value ! of the macro DBL_DIG from your system's F. This is different from ! B's default OFMT setting of %.6g, so you need to set "C<$#>" ! explicitly to get B's value. (Mnemonic: # is the number sign.) Use of "C<$#>" is deprecated in Perl 5. *************** *** 561,566 **** --- 569,579 ---- status of a file descriptor will be decided according to the value of C<$^F> at the time of the open, not the time of the exec. + =item $^H + + The current set of syntax checks enabled by C. See the + documentation of C for more details. + =item $INPLACE_EDIT =item $^I *************** *** 569,574 **** --- 582,588 ---- inplace editing. (Mnemonic: value of B<-i> switch.) =item $OSNAME + =item $^O The name of the operating system under which this copy of Perl was *************** *** 621,627 **** The array @INC contains the list of places to look for Perl scripts to be evaluated by the C, C, or C constructs. It initially consists of the arguments to any B<-I> command line switches, ! followed by the default Perl library, probably "/usr/local/lib/perl", followed by ".", to represent the current directory. If you need to modify this at runtime, you should use the C pragma in order to also get the machine-dependent library properly loaded: --- 635,641 ---- The array @INC contains the list of places to look for Perl scripts to be evaluated by the C, C, or C constructs. It initially consists of the arguments to any B<-I> command line switches, ! followed by the default Perl library, probably F, followed by ".", to represent the current directory. If you need to modify this at runtime, you should use the C pragma in order to also get the machine-dependent library properly loaded: *************** *** 692,695 **** can die from a __DIE__ handler. Similarly for __WARN__. =back - --- 706,708 ---- #~ Typos and formatting corrected diff -Pcr perl5_003/pod/perlxs.pod perl5_003_01/pod/perlxs.pod *** perl5_003/pod/perlxs.pod Mon Mar 25 01:05:24 1996 --- perl5_003_01/pod/perlxs.pod Mon Jul 8 16:37:00 1996 *************** *** 760,767 **** B case if it is not associated with a conditional. The following example shows CASE switched via C with a function C having an alias C. When the function is called as ! C it's parameters are the usual C<(char *host, time_t *timep)>, ! but when the function is called as C is parameters are reversed, C<(time_t *timep, char *host)>. long --- 760,767 ---- B case if it is not associated with a conditional. The following example shows CASE switched via C with a function C having an alias C. When the function is called as ! C its parameters are the usual C<(char *host, time_t *timep)>, ! but when the function is called as C its parameters are reversed, C<(time_t *timep, char *host)>. long *************** *** 831,843 **** Comments are allowed anywhere after the MODULE keyword. The compiler will pass the preprocessor directives through untouched and will remove the commented lines. Comments can be added to XSUBs by placing a C<#> as the first non-whitespace of a line. Care should be taken to avoid making the comment look like a C preprocessor directive, lest it be interpreted as such. The simplest way to prevent this is to put whitespace in front of the C<#>. - If you use preprocessor directives to choose one of two versions of a function, use --- 831,843 ---- Comments are allowed anywhere after the MODULE keyword. The compiler will pass the preprocessor directives through untouched and will remove the commented lines. + Comments can be added to XSUBs by placing a C<#> as the first non-whitespace of a line. Care should be taken to avoid making the comment look like a C preprocessor directive, lest it be interpreted as such. The simplest way to prevent this is to put whitespace in front of the C<#>. If you use preprocessor directives to choose one of two versions of a function, use *************** *** 1147,1150 **** =head1 AUTHOR Dean Roehrich Froehrich@cray.comE> ! Mar 12, 1996 --- 1147,1150 ---- =head1 AUTHOR Dean Roehrich Froehrich@cray.comE> ! Jul 8, 1996 #~ Typos corrected #~ Reflect change in blib structure at version 5.002 #~ Reflect addition of "use vars" by h2xs #~ Note that h2xs doesn't scan nested includes diff -Pcr perl5_003/pod/perlxstut.pod perl5_003_01/pod/perlxstut.pod *** perl5_003/pod/perlxstut.pod Mon Feb 12 14:59:07 1996 --- perl5_003_01/pod/perlxstut.pod Wed Jul 10 20:36:13 1996 *************** *** 25,30 **** --- 25,38 ---- =item * + In versions of 5.002 prior to the gamma version, the test script in Example + 1 will not function properly. You need to change the "use lib" line to + read: + + use lib './blib'; + + =item * + In versions of 5.002 prior to version beta 3, then the line in the .xs file about "PROTOTYPES: DISABLE" will cause a compiler error. Simply remove that line from the file. *************** *** 150,156 **** printf("Hello, world!\n"); Now we'll run "perl Makefile.PL". This will create a real Makefile, ! which make needs. It's output looks something like: % perl Makefile.PL Checking if your kit is complete... --- 158,164 ---- printf("Hello, world!\n"); Now we'll run "perl Makefile.PL". This will create a real Makefile, ! which make needs. Its output looks something like: % perl Makefile.PL Checking if your kit is complete... *************** *** 178,184 **** #! /opt/perl5/bin/perl ! use lib './blib'; use Mytest; --- 186,192 ---- #! /opt/perl5/bin/perl ! use ExtUtils::testlib; use Mytest; *************** *** 223,233 **** file test.pl. This file is set up to imitate the same kind of testing structure that Perl itself has. Within the test script, you perform a number of tests to confirm the behavior of the extension, printing "ok" ! when the test is correct, "not ok" when it is not. ! ! Remove the line that starts with "use lib", change the print statement in ! the BEGIN block to print "1..4", and add the following code to the end of ! the file: print &Mytest::is_even(0) == 1 ? "ok 2" : "not ok 2", "\n"; print &Mytest::is_even(1) == 0 ? "ok 3" : "not ok 3", "\n"; --- 231,239 ---- file test.pl. This file is set up to imitate the same kind of testing structure that Perl itself has. Within the test script, you perform a number of tests to confirm the behavior of the extension, printing "ok" ! when the test is correct, "not ok" when it is not. Change the print ! statement in the BEGIN block to print "1..4", and add the following code ! to the end of the file: print &Mytest::is_even(0) == 1 ? "ok 2" : "not ok 2", "\n"; print &Mytest::is_even(1) == 0 ? "ok 3" : "not ok 3", "\n"; *************** *** 367,375 **** =head2 WHAT'S NEW HERE? Two things are new here. First, we've made some changes to Makefile.PL. ! In this case, we've specified an extra library to link in, in this case the ! math library, libm. We'll talk later about how to write XSUBs that can call ! every routine in a library. Second, the value of the function is being passed back not as the function's return value, but through the same variable that was passed into the function. --- 373,381 ---- =head2 WHAT'S NEW HERE? Two things are new here. First, we've made some changes to Makefile.PL. ! In this case, we've specified an extra library to link in, the math library ! libm. We'll talk later about how to write XSUBs that can call every routine ! in a library. Second, the value of the function is being passed back not as the function's return value, but through the same variable that was passed into the function. *************** *** 441,447 **** In general, it's not a good idea to write extensions that modify their input parameters, as in Example 3. However, in order to better accomodate calling pre-existing C routines, which often do modify their input parameters, ! this behavior is tolerated. =head2 EXAMPLE 4 --- 447,453 ---- In general, it's not a good idea to write extensions that modify their input parameters, as in Example 3. However, in order to better accomodate calling pre-existing C routines, which often do modify their input parameters, ! this behavior is tolerated. The next example will show how to do this. =head2 EXAMPLE 4 *************** *** 504,510 **** We will now create the main top-level Mytest2 files. Change to the directory above Mytest2 and run the following command: ! % h2xs -O -n Mytest2 < ./Mytest2/mylib/mylib.h This will print out a warning about overwriting Mytest2, but that's okay. Our files are stored in Mytest2/mylib, and will be untouched. --- 510,516 ---- We will now create the main top-level Mytest2 files. Change to the directory above Mytest2 and run the following command: ! % h2xs -O -n Mytest2 ./Mytest2/mylib/mylib.h This will print out a warning about overwriting Mytest2, but that's okay. Our files are stored in Mytest2/mylib, and will be untouched. *************** *** 537,544 **** mylib/mylib.h To keep our namespace nice and unpolluted, edit the .pm file and change ! the line setting @EXPORT to @EXPORT_OK. And finally, in the .xs file, ! edit the #include line to read: #include "mylib/mylib.h" --- 543,551 ---- mylib/mylib.h To keep our namespace nice and unpolluted, edit the .pm file and change ! the lines setting @EXPORT to @EXPORT_OK (there are two: one in the line ! beginning "use vars" and one setting the array itself). Finally, in the ! .xs file, edit the #include line to read: #include "mylib/mylib.h" *************** *** 602,607 **** --- 609,619 ---- mind using the "fully qualified name" of a variable, you could remove most or all of the items in the @EXPORT array. + =item * + + If our include file contained #include directives, these would not be + processed at all by h2xs. There is no good solution to this right now. + =back We've also told Perl about the library that we built in the mylib *************** *** 719,722 **** =head2 Last Changed ! 1996/2/9 --- 731,734 ---- =head2 Last Changed ! 1996/7/10 #~ Correct typo in STDERR #~ Remove .pm as well as .pod suffix from input filename #~ Drop erroneous double quotes around function parameter #~ Convert characters with high bit set to HTML escapes diff -Pcr perl5_003/pod/pod2html.PL perl5_003_01/pod/pod2html.PL *** perl5_003/pod/pod2html.PL Mon Mar 25 01:05:24 1996 --- perl5_003_01/pod/pod2html.PL Mon Jul 8 09:33:52 1996 *************** *** 98,106 **** # loop twice through the pods, first to learn the links, then to produce html for $count (0,1) { ! print STTDER "Scanning pods...\n" unless $count; foreach $podfh ( @Pods ) { ! ($pod = $podfh) =~ s/\.pod$//; Debug("files", "opening 2 $podfh" ); print "Creating $pod.html from $podfh\n" if $count; $RS = "\n="; # grok pods by item (Nonstandard but effecient) --- 98,106 ---- # loop twice through the pods, first to learn the links, then to produce html for $count (0,1) { ! print STDERR "Scanning pods...\n" unless $count; foreach $podfh ( @Pods ) { ! ($pod = $podfh) =~ s/\.(?:pod|pm)$//; Debug("files", "opening 2 $podfh" ); print "Creating $pod.html from $podfh\n" if $count; $RS = "\n="; # grok pods by item (Nonstandard but effecient) *************** *** 151,157 **** if ($count) { # producing html ($depth) or next; # just skip it do_list("back",$all[$i+1],\$in_list,\$depth); ! do_rest("$title.$rest"); } } elsif ($cmd =~ /^cut/) { --- 151,157 ---- if ($count) { # producing html ($depth) or next; # just skip it do_list("back",$all[$i+1],\$in_list,\$depth); ! do_rest($title.$rest); } } elsif ($cmd =~ /^cut/) { *************** *** 161,167 **** if ($count) { # producing html if ($title =~ s/^html//) { $in_html =1; ! do_rest("$title.$rest"); } } } --- 161,167 ---- if ($count) { # producing html if ($title =~ s/^html//) { $in_html =1; ! do_rest($title.$rest); } } } *************** *** 501,506 **** --- 501,507 ---- sub pre_escapes { # twiddle these, and stay up late :-) my($thing) = @_; for ($$thing) { + s/([\200-\377])/noremap("&".ord($1).";")/ge; s/"(.*?)"/``$1''/gs; s/&/noremap("&")/ge; s/<"/ge; } sub clear_noremap { *************** *** 513,523 **** sub expand_HTML_escapes { local($s) = $_[0]; ! $s =~ s { E<([A-Za-z]+)> } { do { ! exists $HTML_Escapes{$1} ! ? do { $HTML_Escapes{$1} } : do { warn "Unknown escape: $& in $_"; "E<$1>"; --- 512,525 ---- sub expand_HTML_escapes { local($s) = $_[0]; ! $s =~ s { E<((\d+)|([A-Za-z]+))> } { do { ! defined($2) ! ? do { chr($2) } ! : ! exists $HTML_Escapes{$3} ! ? do { $HTML_Escapes{$3} } : do { warn "Unknown escape: $& in $_"; "E<$1>"; #~ Handle characters with high bit set #~ Don't try to find local Perl via PATH on Plan9 diff -Pcr perl5_003/pod/pod2man.PL perl5_003_01/pod/pod2man.PL *** perl5_003/pod/pod2man.PL Mon Mar 25 01:05:27 1996 --- perl5_003_01/pod/pod2man.PL Mon Jul 29 19:59:57 1996 *************** *** 225,236 **** (F) The input file wasn't available for the given reason. - =item high bit char in input stream - - (W) You can't use high-bit characters in the input stream, - because the translator uses them for its own nefarious purposes. - Use an HTML entity in angle brackets instead. - =item Improper man page - no dash in NAME header in paragraph %d of %s (W) The NAME header did not have an isolated dash in it. This is --- 225,230 ---- *************** *** 292,299 **** =head1 RESTRICTIONS ! You shouldn't use 8-bit characters in the input stream, as these ! will be used by the translator. =head1 BUGS --- 286,292 ---- =head1 RESTRICTIONS ! None at this time. =head1 BUGS *************** *** 311,317 **** $/ = ""; $cutting = 1; ! ($version,$patch) = `\PATH=.:..:\$PATH; perl -v` =~ /version (\d\.\d{3}(?: +)(?:\S+)?)(?:.*patchlevel (\d\S*))?/s; $DEF_RELEASE = "perl $version"; $DEF_RELEASE .= ", patch $patch" if $patch; --- 304,318 ---- $/ = ""; $cutting = 1; ! # We try first to get the version number from a local binary, in case we're ! # running an installed version of Perl to produce documentation from an ! # uninstalled newer version's pod files. ! if ($^O ne 'plan9') { ! ($version,$patch) = ! `\PATH=.:..:\$PATH; perl -v` =~ /version (\d\.\d{3})(?:_(\d{2}))?/; ! } ! # No luck; we'll just go with the running Perl's version ! ($version,$patch) = $] =~ /^(.{5})(\d{2})?/ unless $version; $DEF_RELEASE = "perl $version"; $DEF_RELEASE .= ", patch $patch" if $patch; *************** *** 952,960 **** } sub init_noremap { ! if ( /[\200-\377]/ ) { ! warn "$0: high bit char in input stream in paragraph $. of $ARGV\n"; ! } } sub clear_noremap { --- 953,960 ---- } sub init_noremap { ! # escape high bit characters in input stream ! s/([\200-\377])/"E<".ord($1).">"/ge; } sub clear_noremap { *************** *** 969,981 **** # otherwise the interative \w<> processing would have # been hosed by the E s { ! E< ! ( [A-Za-z]+ ) > } { ! do { ! exists $HTML_Escapes{$1} ! ? do { $HTML_Escapes{$1} } : do { warn "$0: Unknown escape in paragraph $. of $ARGV: ``$&''\n"; "E<$1>"; --- 969,987 ---- # otherwise the interative \w<> processing would have # been hosed by the E s { ! E< ! ( ! ( \d + ) ! | ( [A-Za-z]+ ) ! ) > } { ! do { ! defined $2 ! ? chr($2) ! : ! exists $HTML_Escapes{$3} ! ? do { $HTML_Escapes{$3} } : do { warn "$0: Unknown escape in paragraph $. of $ARGV: ``$&''\n"; "E<$1>"; #~ Add cast for new GV type #~ Check for magic SV in pp_ref() #~ Use more complex default seed in pp_srand(), but skip bits on Plan9 #~ which give its cc/asm a headache #~ Reflect new HV management #~ Make SV created to hold result of unpack('u',...) a valid string #~ Rename global variable to eliminate collision with system header files diff -Pcr perl5_003/pp.c perl5_003_01/pp.c *** perl5_003/pp.c Fri Feb 23 22:07:37 1996 --- perl5_003_01/pp.c Wed Jul 17 11:48:22 1996 *************** *** 141,147 **** GvREFCNT(sv) = 1; GvSV(sv) = NEWSV(72,0); GvLINE(sv) = curcop->cop_line; ! GvEGV(sv) = sv; } } SETs(sv); --- 141,147 ---- GvREFCNT(sv) = 1; GvSV(sv) = NEWSV(72,0); GvLINE(sv) = curcop->cop_line; ! GvEGV(sv) = (GV*)sv; } } SETs(sv); *************** *** 163,169 **** } } else { ! GV *gv = sv; char *sym; if (SvTYPE(gv) != SVt_PVGV) { --- 163,169 ---- } } else { ! GV *gv = (GV*)sv; char *sym; if (SvTYPE(gv) != SVt_PVGV) { *************** *** 181,187 **** 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); } sv = GvSV(gv); } --- 181,187 ---- sym = SvPV(sv, na); if (op->op_private & HINT_STRICT_REFS) DIE(no_symref, sym, "a SCALAR"); ! gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PV); } sv = GvSV(gv); } *************** *** 331,336 **** --- 331,340 ---- char *pv; sv = POPs; + + if (sv && SvGMAGICAL(sv)) + mg_get(sv); + if (!sv || !SvROK(sv)) RETPUSHNO; *************** *** 1232,1242 **** { dSP; I32 anum; - Time_t when; if (MAXARG < 1) { (void)time(&when); anum = when; } else anum = POPi; --- 1236,1266 ---- { dSP; I32 anum; if (MAXARG < 1) { + #ifdef VMS + # include + unsigned int when[2]; + _ckvmssts(sys$gettim(when)); + anum = when[0] ^ when[1]; + #else + # if defined(I_SYS_TIME) && !defined(PLAN9) + struct timeval when; + gettimeofday(&when,(struct timezone *) 0); + anum = when.tv_sec ^ when.tv_usec; + # else + Time_t when; (void)time(&when); anum = when; + # endif + #endif + #if !defined(PLAN9) /* XXX Plan9 assembler chokes on this; fix coming soon */ + /* 17-Jul-1996 bailey@genetics.upenn.edu */ + /* What is a good hashing algorithm here? */ + anum ^= ( ( 269 * (U32)getpid()) + ^ (26107 * (U32)&when) + ^ (73819 * (U32)stack_sp)); + #endif } else anum = POPi; *************** *** 1789,1796 **** dSP; dTARGET; HV *hash = (HV*)POPs; HE *entry; - I32 i; - char *tmps; PUTBACK; entry = hv_iternext(hash); /* might clobber stack_sp */ --- 1813,1818 ---- *************** *** 1798,1807 **** 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) { PUTBACK; sv_setsv(TARG, hv_iterval(hash, entry)); /* might clobber stack_sp */ --- 1820,1826 ---- EXTEND(SP, 2); if (entry) { ! 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 */ *************** *** 1831,1844 **** SV *sv; 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); ! sv = hv_delete(hv, tmps, len, ! op->op_private & OPpLEAVE_VOID ? G_DISCARD : 0); if (!sv) RETPUSHUNDEF; PUSHs(sv); --- 1850,1861 ---- SV *sv; SV *tmpsv = POPs; HV *hv = (HV*)POPs; STRLEN len; if (SvTYPE(hv) != SVt_PVHV) { DIE("Not a HASH reference"); } ! sv = hv_delete_ent(hv, tmpsv, ! (op->op_private & OPpLEAVE_VOID ? G_DISCARD : 0), 0); if (!sv) RETPUSHUNDEF; PUSHs(sv); *************** *** 1850,1862 **** 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)) RETPUSHYES; RETPUSHNO; } --- 1867,1877 ---- dSP; SV *tmpsv = POPs; HV *hv = (HV*)POPs; STRLEN len; if (SvTYPE(hv) != SVt_PVHV) { DIE("Not a HASH reference"); } ! if (hv_exists_ent(hv, tmpsv, 0)) RETPUSHYES; RETPUSHNO; } *************** *** 1864,1886 **** PP(pp_hslice) { dSP; dMARK; dORIGMARK; ! register SV **svp; 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); ! svp = hv_fetch(hv, key, keylen, lval); if (lval) { ! if (!svp || *svp == &sv_undef) ! DIE(no_helem, key); if (op->op_private & OPpLVAL_INTRO) ! save_svref(svp); } ! *MARK = svp ? *svp : &sv_undef; } } if (GIMME != G_ARRAY) { --- 1879,1900 ---- PP(pp_hslice) { dSP; dMARK; dORIGMARK; ! register HE *he; register HV *hv = (HV*)POPs; register I32 lval = op->op_flags & OPf_MOD; if (SvTYPE(hv) == SVt_PVHV) { while (++MARK <= SP) { ! SV *keysv = *MARK; ! he = hv_fetch_ent(hv, keysv, lval, 0); if (lval) { ! if (!he || HeVAL(he) == &sv_undef) ! DIE(no_helem, SvPV(keysv, na)); if (op->op_private & OPpLVAL_INTRO) ! save_svref(&HeVAL(he)); } ! *MARK = he ? HeVAL(he) : &sv_undef; } } if (GIMME != G_ARRAY) { *************** *** 1981,1994 **** while (MARK < SP) { SV* key = *++MARK; - char *tmps; SV *val = NEWSV(46, 0); if (MARK < SP) sv_setsv(val, *++MARK); else warn("Odd number of elements in hash list"); ! tmps = SvPV(key,len); ! (void)hv_store(hv,tmps,len,val,0); } SP = ORIGMARK; XPUSHs((SV*)hv); --- 1995,2006 ---- while (MARK < SP) { SV* key = *++MARK; SV *val = NEWSV(46, 0); if (MARK < SP) sv_setsv(val, *++MARK); else warn("Odd number of elements in hash list"); ! (void)hv_store_ent(hv,key,val,0); } SP = ORIGMARK; XPUSHs((SV*)hv); *************** *** 2829,2834 **** --- 2841,2848 ---- 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]; *************** *** 3324,3330 **** I32 origlimit = limit; I32 realarray = 0; I32 base; ! AV *oldstack = stack; register REGEXP *rx = pm->op_pmregexp; I32 gimme = GIMME; I32 oldsave = savestack_ix; --- 3338,3344 ---- I32 origlimit = limit; I32 realarray = 0; I32 base; ! AV *oldstack = curstack; register REGEXP *rx = pm->op_pmregexp; I32 gimme = GIMME; I32 oldsave = savestack_ix; *************** *** 3347,3353 **** av_extend(ary,0); av_clear(ary); /* temporarily switch stacks */ ! SWITCHSTACK(stack, ary); } base = SP - stack_base; orig = s; --- 3361,3367 ---- av_extend(ary,0); av_clear(ary); /* temporarily switch stacks */ ! SWITCHSTACK(curstack, ary); } base = SP - stack_base; orig = s; #~ Revise SETsv() and tryAMAGICun() macros #~ Rename global symbol to eliminate collision with system header files diff -Pcr perl5_003/pp.h perl5_003_01/pp.h *** perl5_003/pp.h Mon Mar 25 01:05:28 1996 --- perl5_003_01/pp.h Fri Jul 5 15:31:26 1996 *************** *** 93,102 **** #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 dTOPss SV *sv = TOPs #define dPOPss SV *sv = POPs #define dTOPnv double value = TOPn --- 93,98 ---- *************** *** 127,133 **** stack_base = AvARRAY(t); \ stack_max = stack_base + AvMAX(t); \ sp = stack_sp = stack_base + AvFILL(t); \ ! stack = t; #ifdef OVERLOAD --- 123,129 ---- stack_base = AvARRAY(t); \ stack_max = stack_base + AvMAX(t); \ sp = stack_sp = stack_base + AvFILL(t); \ ! curstack = t; #ifdef OVERLOAD *************** *** 169,178 **** } \ } STMT_END ! #define tryAMAGICun(meth) tryAMAGICunW(meth,SETsv) #define tryAMAGICunSET(meth) tryAMAGICunW(meth,SETs) #define opASSIGN (op->op_flags & OPf_STACKED) /* newSVsv does not behave as advertised, so we copy missing * information by hand */ --- 165,177 ---- } \ } STMT_END ! #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 */ #~ Rename global variable to eliminate collision with system header files #~ Allow redurection of debug messages #~ Make sure the right stack is in use in die() #~ Correct juggling of stack and @_ in pp_goto() #~ Get more information about XSUBs to debugger #~ Preserve SP around eval #~ Propagate G_KEEPERR down into eval #~ Don't worry about %INC if we're not in a "require" diff -Pcr perl5_003/pp_ctl.c perl5_003_01/pp_ctl.c *** perl5_003/pp_ctl.c Mon Mar 25 01:05:31 1996 --- perl5_003_01/pp_ctl.c Mon Jul 15 13:41:09 1996 *************** *** 621,633 **** SAVETMPS; SAVESPTR(op); ! oldstack = stack; if (!sortstack) { sortstack = newAV(); AvREAL_off(sortstack); av_extend(sortstack, 32); } ! SWITCHSTACK(stack, sortstack); if (sortstash != stash) { firstgv = gv_fetchpv("a", TRUE, SVt_PV); secondgv = gv_fetchpv("b", TRUE, SVt_PV); --- 621,633 ---- SAVETMPS; SAVESPTR(op); ! oldstack = curstack; if (!sortstack) { sortstack = newAV(); AvREAL_off(sortstack); av_extend(sortstack, 32); } ! SWITCHSTACK(curstack, sortstack); if (sortstash != stash) { firstgv = gv_fetchpv("a", TRUE, SVt_PV); secondgv = gv_fetchpv("b", TRUE, SVt_PV); *************** *** 881,887 **** 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])); /* Note: we don't need to restore the base context info till the end. */ switch (cx->cx_type) { --- 881,887 ---- while (cxstack_ix > cxix) { cx = &cxstack[cxstack_ix--]; ! DEBUG_l(fprintf(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) { *************** *** 919,924 **** --- 919,931 ---- GV *gv; CV *cv; + /* 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); + } #ifdef I_STDARG va_start(args, pat); #else *************** *** 1308,1315 **** cx->blk_loop.iterix = -1; } else { ! cx->blk_loop.iterary = stack; ! AvFILL(stack) = sp - stack_base; cx->blk_loop.iterix = MARK - stack_base; } --- 1315,1322 ---- cx->blk_loop.iterix = -1; } else { ! cx->blk_loop.iterary = curstack; ! AvFILL(curstack) = sp - stack_base; cx->blk_loop.iterix = MARK - stack_base; } *************** *** 1376,1386 **** PMOP *newpm; I32 optype = 0; ! if (stack == sortstack) { if (cxstack_ix == sortcxix || dopoptosub(cxstack_ix) < sortcxix) { if (cxstack_ix > sortcxix) dounwind(sortcxix); ! AvARRAY(stack)[1] = *SP; stack_sp = stack_base + 1; return 0; } --- 1383,1393 ---- PMOP *newpm; I32 optype = 0; ! if (curstack == sortstack) { if (cxstack_ix == sortcxix || dopoptosub(cxstack_ix) < sortcxix) { if (cxstack_ix > sortcxix) dounwind(sortcxix); ! AvARRAY(curstack)[1] = *SP; stack_sp = stack_base + 1; return 0; } *************** *** 1634,1640 **** AV* av = cx->blk_sub.argarray; items = AvFILL(av) + 1; ! Copy(AvARRAY(av), ++stack_sp, items, SV*); stack_sp += items; GvAV(defgv) = cx->blk_sub.savearray; AvREAL_off(av); --- 1641,1649 ---- AV* av = cx->blk_sub.argarray; items = AvFILL(av) + 1; ! stack_sp++; ! EXTEND(stack_sp, items); /* @_ could have been extended. */ ! Copy(AvARRAY(av), stack_sp, items, SV*); stack_sp += items; GvAV(defgv) = cx->blk_sub.savearray; AvREAL_off(av); *************** *** 1661,1666 **** --- 1670,1676 ---- sp = stack_base + items; } else { + stack_sp--; /* There is no cv arg. */ (void)(*CvXSUB(cv))(cv); } LEAVE; *************** *** 1750,1755 **** --- 1760,1772 ---- mark++; } } + if (perldb && curstash != debstash) { /* &xsub is not copying @_ */ + SV *sv = GvSV(DBsub); + save_item(sv); + gv_efullname(sv, CvGV(cv)); /* We do not care about + * using sv to call CV, + * just for info. */ + } RETURNOP(CvSTART(cv)); } } *************** *** 1843,1849 **** do_undump = FALSE; } ! if (stack == signalstack) { restartop = retop; Siglongjmp(top_env, 3); } --- 1860,1866 ---- do_undump = FALSE; } ! if (curstack == signalstack) { restartop = retop; Siglongjmp(top_env, 3); } *************** *** 1944,1949 **** --- 1961,1968 ---- in_eval = 1; + PUSHMARK(SP); + /* set up a scratch pad */ SAVEINT(padix); *************** *** 1992,1998 **** curcop->cop_arybase = 0; SvREFCNT_dec(rs); rs = newSVpv("\n", 1); ! sv_setpv(GvSV(errgv),""); if (yyparse() || error_count || !eval_root) { SV **newsp; I32 gimme; --- 2011,2020 ---- curcop->cop_arybase = 0; SvREFCNT_dec(rs); rs = newSVpv("\n", 1); ! 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,2009 **** --- 2026,2032 ---- op_free(eval_root); eval_root = Nullop; } + SP = stack_base + POPMARK; /* pop original mark */ POPBLOCK(cx,curpm); POPEVAL(cx); pop_return(); *************** *** 2028,2033 **** --- 2051,2057 ---- /* compiled okay, so do it */ + SP = stack_base + POPMARK; /* pop original mark */ RETURNOP(eval_start); } *************** *** 2201,2206 **** --- 2225,2231 ---- I32 gimme; register CONTEXT *cx; OP *retop; + OP *saveop = op; I32 optype; POPBLOCK(cx,newpm); *************** *** 2233,2253 **** } curpm = newpm; /* Don't pop $1 et al till now */ ! if (optype != OP_ENTEREVAL) { char *name = cx->blk_eval.old_name; ! if (!(gimme == G_SCALAR ? SvTRUE(*sp) : sp > newsp)) { ! /* Unassume the success we assumed earlier. */ ! (void)hv_delete(GvHVn(incgv), name, strlen(name), G_DISCARD); ! ! if (optype == OP_REQUIRE) ! retop = die("%s did not return a true value", name); ! } } lex_end(); LEAVE; ! sv_setpv(GvSV(errgv),""); RETURNOP(retop); } --- 2258,2276 ---- } curpm = newpm; /* Don't pop $1 et al till now */ ! if (optype == OP_REQUIRE && ! !(gimme == G_SCALAR ? SvTRUE(*sp) : sp > newsp)) { char *name = cx->blk_eval.old_name; ! /* Unassume the success we assumed earlier. */ ! (void)hv_delete(GvHVn(incgv), name, strlen(name), G_DISCARD); ! retop = die("%s did not return a true value", name); } lex_end(); LEAVE; ! if (!(saveop->op_flags & OPf_SPECIAL)) ! sv_setpv(GvSV(errgv),""); RETURNOP(retop); } #~ Use new GV type explicitly #~ Update processing of glob expansion under OS/2 #~ Rename global variable to eliminate collision with system headers #~ Give debugger more information about XSUBs #~ Pass @_ through properly to nested XSUB call #~ Improve efficiency of method lookup diff -Pcr perl5_003/pp_hot.c perl5_003_01/pp_hot.c *** perl5_003/pp_hot.c Mon Mar 25 01:05:32 1996 --- perl5_003_01/pp_hot.c Thu Jul 4 14:49:07 1996 *************** *** 414,419 **** --- 414,421 ---- } } else { + GV *gv; + if (SvTYPE(sv) != SVt_PVGV) { char *sym; *************** *** 433,443 **** 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); } ! av = GvAVn(sv); if (op->op_private & OPpLVAL_INTRO) ! av = save_ary(sv); if (op->op_flags & OPf_REF) { PUSHs((SV*)av); RETURN; --- 435,447 ---- sym = SvPV(sv,na); if (op->op_private & HINT_STRICT_REFS) DIE(no_symref, sym, "an ARRAY"); ! gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PVAV); ! } else { ! gv = (GV*)sv; } ! av = GvAVn(gv); if (op->op_private & OPpLVAL_INTRO) ! av = save_ary(gv); if (op->op_flags & OPf_REF) { PUSHs((SV*)av); RETURN; *************** *** 487,492 **** --- 491,498 ---- } } else { + GV *gv; + if (SvTYPE(sv) != SVt_PVGV) { char *sym; *************** *** 508,518 **** 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); } ! hv = GvHVn(sv); if (op->op_private & OPpLVAL_INTRO) ! hv = save_hash(sv); if (op->op_flags & OPf_REF) { SETs((SV*)hv); RETURN; --- 514,526 ---- sym = SvPV(sv,na); if (op->op_private & HINT_STRICT_REFS) DIE(no_symref, sym, "a HASH"); ! gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PVHV); ! } else { ! gv = (GV*)sv; } ! hv = GvHVn(gv); if (op->op_private & OPpLVAL_INTRO) ! hv = save_hash(gv); if (op->op_flags & OPf_REF) { SETs((SV*)hv); RETURN; *************** *** 1045,1055 **** } #else /* !VMS */ #ifdef DOSISH sv_setpv(tmpcmd, "perlglob "); sv_catsv(tmpcmd, tmpglob); sv_catpv(tmpcmd, " |"); ! #else ! #ifdef CSH sv_setpvn(tmpcmd, cshname, cshlen); sv_catpv(tmpcmd, " -cf 'set nonomatch; glob "); sv_catsv(tmpcmd, tmpglob); --- 1053,1069 ---- } #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, " |"); ! #endif /* !OS2 */ ! #else /* !DOSISH */ ! #if defined(CSH) sv_setpvn(tmpcmd, cshname, cshlen); sv_catpv(tmpcmd, " -cf 'set nonomatch; glob "); sv_catsv(tmpcmd, tmpglob); *************** *** 1063,1069 **** sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\n\\n\\n\\n'|"); #endif #endif /* !CSH */ ! #endif /* !MSDOS */ (void)do_open(last_in_gv, SvPVX(tmpcmd), SvCUR(tmpcmd), FALSE, 0, 0, Nullfp); fp = IoIFP(io); --- 1077,1083 ---- sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\n\\n\\n\\n'|"); #endif #endif /* !CSH */ ! #endif /* !DOSISH */ (void)do_open(last_in_gv, SvPVX(tmpcmd), SvCUR(tmpcmd), FALSE, 0, 0, Nullfp); fp = IoIFP(io); *************** *** 1278,1284 **** 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) RETPUSHNO; if (cx->blk_loop.iterix >= AvFILL(av)) --- 1292,1298 ---- if (cx->cx_type != CXt_LOOP) DIE("panic: pp_iter"); av = cx->blk_loop.iterary; ! if (av == curstack && cx->blk_loop.iterix >= cx->blk_oldsp) RETPUSHNO; if (cx->blk_loop.iterix >= AvFILL(av)) *************** *** 1647,1652 **** --- 1661,1667 ---- register CV *cv; register CONTEXT *cx; I32 gimme; + I32 hasargs = (op->op_flags & OPf_STACKED) != 0; if (!sv) DIE("Not a CODE reference"); *************** *** 1717,1734 **** } gimme = GIMME; ! if ((op->op_private & OPpENTERSUB_DB) && !CvXSUB(cv)) { sv = GvSV(DBsub); save_item(sv); ! if (CvFLAGS(cv) & (CVf_ANON | CVf_CLONED)) { /* GV is potentially non-unique */ sv_setsv(sv, newRV((SV*)cv)); } else { - gv = CvGV(cv); gv_efullname(sv,gv); } cv = GvCV(DBsub); if (!cv) DIE("No DBsub routine"); } --- 1732,1751 ---- } gimme = GIMME; ! if ((op->op_private & OPpENTERSUB_DB)) { sv = GvSV(DBsub); save_item(sv); ! gv = CvGV(cv); ! if ( CvFLAGS(cv) & (CVf_ANON | CVf_CLONED) ! || strEQ(GvNAME(gv), "END") ) { /* GV is potentially non-unique */ sv_setsv(sv, newRV((SV*)cv)); } else { gv_efullname(sv,gv); } cv = GvCV(DBsub); + if (CvXSUB(cv)) curcopdb = curcop; if (!cv) DIE("No DBsub routine"); } *************** *** 1738,1743 **** --- 1755,1761 ---- 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,1758 **** --- 1771,1800 ---- 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,1776 **** 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); --- 1812,1817 ---- *************** *** 1922,1930 **** else { GV* iogv; char* packname = 0; if (!SvOK(sv) || ! !(packname = SvPV(sv, na)) || !(iogv = gv_fetchpv(packname, FALSE, SVt_PVIO)) || !(ob=(SV*)GvIO(iogv))) { --- 1963,1972 ---- else { GV* iogv; char* packname = 0; + STRLEN packlen; if (!SvOK(sv) || ! !(packname = SvPV(sv, packlen)) || !(iogv = gv_fetchpv(packname, FALSE, SVt_PVIO)) || !(ob=(SV*)GvIO(iogv))) { *************** *** 1932,1940 **** 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); --- 1974,1982 ---- HV *stash; if (!packname || !isALPHA(*packname)) DIE("Can't call method \"%s\" without a package or object reference", name); ! if (!(stash = gv_stashpvn(packname, packlen, FALSE))) { ! if (gv_stashpvn("UNIVERSAL", 9, FALSE)) ! stash = gv_stashpvn(packname, packlen, TRUE); else DIE("Can't call method \"%s\" in empty package \"%s\"", name, packname); *************** *** 1943,1952 **** if (!gv) DIE("Can't locate object method \"%s\" via package \"%s\"", name, packname); ! SETs(gv); RETURN; } ! *(stack_base + TOPMARK + 1) = sv_2mortal(newRV(iogv)); } if (!ob || !SvOBJECT(ob)) { --- 1985,1994 ---- if (!gv) DIE("Can't locate object method \"%s\" via package \"%s\"", name, packname); ! SETs((SV*)gv); RETURN; } ! *(stack_base + TOPMARK + 1) = sv_2mortal(newRV((SV*)iogv)); } if (!ob || !SvOBJECT(ob)) { *************** *** 1962,1968 **** name, HvNAME(SvSTASH(ob))); } ! SETs(gv); RETURN; } --- 2004,2010 ---- name, HvNAME(SvSTASH(ob))); } ! SETs((SV*)gv); RETURN; } #~ Use home-grown name for chsize() to avoid possible collision with #~ function which exists in system libraries but isn't used #~ Support home-grown analogue to binmode() #~ Give debugger access to function call executing "tie" and "dbmopen" #~ Implement strict untie #~ Add casts to reflect new GV type #~ Allow redirection of debug messages #~ Fix handling of file truncation #~ Handle missing rdev field in struct stat #~ Handle 64-bit time values diff -Pcr perl5_003/pp_sys.c perl5_003_01/pp_sys.c *** perl5_003/pp_sys.c Mon Mar 25 01:05:32 1996 --- perl5_003_01/pp_sys.c Fri Jul 26 09:32:41 1996 *************** *** 89,94 **** --- 89,99 ---- #if !defined(HAS_MKDIR) || !defined(HAS_RMDIR) static int dooneliner _((char *cmd, char *filename)); #endif + + #ifdef HAS_CHSIZE + # define my_chsize chsize + #endif + /* Pushy I/O. */ PP(pp_backtick) *************** *** 376,383 **** --- 381,396 ---- RETPUSHUNDEF; #endif #else + #if defined(USEMYBINMODE) + if (my_binmode(fp,IoTYPE(io)) != NULL) + RETPUSHYES; + else + RETPUSHUNDEF; + #else RETPUSHYES; #endif + #endif + } PP(pp_tie) *************** *** 415,422 **** ENTER; SAVESPTR(op); op = (OP *) &myop; ! XPUSHs(gv); PUTBACK; if (op = pp_entersub()) --- 428,437 ---- ENTER; SAVESPTR(op); op = (OP *) &myop; + if (perldb && curstash != debstash) + op->op_private |= OPpENTERSUB_DB; ! XPUSHs((SV*)gv); PUTBACK; if (op = pp_entersub()) *************** *** 443,452 **** PP(pp_untie) { dSP; ! if (SvTYPE(TOPs) == SVt_PVHV || SvTYPE(TOPs) == SVt_PVAV) ! sv_unmagic(TOPs, 'P'); else ! sv_unmagic(TOPs, 'q'); RETSETYES; } --- 458,485 ---- PP(pp_untie) { dSP; ! SV * sv ; ! ! sv = POPs; ! if (hints & HINT_STRICT_UNTIE) ! { ! 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) ! croak("Can't untie: %d inner references still exist", ! SvREFCNT(SvRV(mg->mg_obj)) - 1 ) ; ! } ! } ! ! if (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV) ! sv_unmagic(sv, 'P'); else ! sv_unmagic(sv, 'q'); RETSETYES; } *************** *** 503,508 **** --- 536,543 ---- ENTER; SAVESPTR(op); op = (OP *) &myop; + if (perldb && curstash != debstash) + op->op_private |= OPpENTERSUB_DB; PUTBACK; pp_pushmark(); *************** *** 514,520 **** else PUSHs(sv_2mortal(newSViv(O_RDWR))); PUSHs(right); ! PUSHs(gv); PUTBACK; if (op = pp_entersub()) --- 549,555 ---- else PUSHs(sv_2mortal(newSViv(O_RDWR))); PUSHs(right); ! PUSHs((SV*)gv); PUTBACK; if (op = pp_entersub()) *************** *** 531,537 **** PUSHs(left); PUSHs(sv_2mortal(newSViv(O_RDONLY))); PUSHs(right); ! PUSHs(gv); PUTBACK; if (op = pp_entersub()) --- 566,572 ---- PUSHs(left); PUSHs(sv_2mortal(newSViv(O_RDONLY))); PUSHs(right); ! PUSHs((SV*)gv); PUTBACK; if (op = pp_entersub()) *************** *** 710,720 **** 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; } --- 745,755 ---- if (! hv) XPUSHs(&sv_undef); else { ! GV **gvp = (GV**)hv_fetch(hv, GvNAME(egv), GvNAMELEN(egv), FALSE); if (gvp && *gvp == egv) gv_efullname(TARG, defoutgv); else ! sv_setsv(TARG, sv_2mortal(newRV((SV*)egv))); XPUSHTARG; } *************** *** 827,833 **** I32 gimme; register CONTEXT *cx; ! DEBUG_f(fprintf(stderr,"left=%ld, todo=%ld\n", (long)IoLINES_LEFT(io), (long)FmLINES(formtarget))); if (IoLINES_LEFT(io) < FmLINES(formtarget) && formtarget != toptarget) --- 862,868 ---- I32 gimme; register CONTEXT *cx; ! DEBUG_f(fprintf(Perl_debug_log,"left=%ld, todo=%ld\n", (long)IoLINES_LEFT(io), (long)FmLINES(formtarget))); if (IoLINES_LEFT(io) < FmLINES(formtarget) && formtarget != toptarget) *************** *** 1211,1244 **** 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); ! if (!GvIO(tmpgv) || !IoIFP(GvIOp(tmpgv)) || ! chsize(fileno(IoIFP(GvIOn(tmpgv))), len) < 0) result = 0; } else { ! int tmpfd; ! ! if ((tmpfd = open(POPp, 0)) < 0) result = 0; ! else { ! if (chsize(tmpfd, len) < 0) ! result = 0; ! close(tmpfd); } - } #endif if (result) RETPUSHYES; --- 1246,1289 ---- SETERRNO(0,0); #if defined(HAS_TRUNCATE) || defined(HAS_CHSIZE) || defined(F_FREESP) if (op->op_flags & OPf_SPECIAL) { tmpgv = gv_fetchpv(POPp,FALSE, SVt_PVIO); + do_ftruncate: if (!GvIO(tmpgv) || !IoIFP(GvIOp(tmpgv)) || + #ifdef HAS_TRUNCATE ftruncate(fileno(IoIFP(GvIOn(tmpgv))), len) < 0) ! #else ! my_chsize(fileno(IoIFP(GvIOn(tmpgv))), len) < 0) ! #endif result = 0; } else { ! SV *sv = POPs; ! 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; ! } ! #ifdef HAS_TRUNCATE ! if (truncate (SvPV (sv, na), len) < 0) result = 0; ! #else ! { ! int tmpfd; ! ! if ((tmpfd = open(SvPV (sv, na), 0)) < 0) ! result = 0; ! else { ! if (my_chsize(tmpfd, len) < 0) ! result = 0; ! close(tmpfd); ! } } #endif + } if (result) RETPUSHYES; *************** *** 1831,1841 **** --- 1876,1896 ---- 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))); *************** *** 2984,2990 **** --- 3039,3049 ---- PP(pp_time) { dSP; dTARGET; + #ifdef BIG_TIME + XPUSHn( time(Null(Time_t*)) ); + #else XPUSHi( time(Null(Time_t*)) ); + #endif RETURN; } *************** *** 3038,3044 **** --- 3097,3107 ---- 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); #~ Reflect name changes to routines and parameters #~ Add new routines for shared has keys, faster symbol lookup, #~ improved %SIG management, default UNIVERSAL methods, #~ verion checking, and safecalloc() #~ Correct count in i18nl10n diff -Pcr perl5_003/proto.h perl5_003_01/proto.h *** perl5_003/proto.h Mon Mar 25 01:05:33 1996 --- perl5_003_01/proto.h Thu Jul 18 11:15:44 1996 *************** *** 30,42 **** 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)); 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)); #endif OP * ck_gvconst _((OP * o)); OP * ck_retarget _((OP *op)); --- 30,43 ---- OP* bind_match _((I32 type, OP* left, OP* pat)); OP* block_end _((int line, int floor, OP* seq)); int block_start _((void)); + void boot_core_UNIVERSAL _((void)); void calllist _((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 my_chsize _((int fd, Off_t length)); #endif OP * ck_gvconst _((OP * o)); OP * ck_retarget _((OP *op)); *************** *** 66,72 **** 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_eof _((GV* gv)); bool do_exec _((char* cmd)); void do_execfree _((void)); --- 67,73 ---- 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 not_implicit)); bool do_eof _((GV* gv)); bool do_exec _((char* cmd)); void do_execfree _((void)); *************** *** 131,151 **** void gv_fullname _((SV* sv, GV* gv)); void gv_init _((GV *gv, HV *stash, char *name, STRLEN len, int multi)); HV* gv_stashpv _((char* name, 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)); SV* hv_delete _((HV* tb, char* key, U32 klen, I32 flags)); bool hv_exists _((HV* tb, char* key, U32 klen)); SV** hv_fetch _((HV* tb, char* key, U32 klen, I32 lval)); I32 hv_iterinit _((HV* tb)); char* hv_iterkey _((HE* entry, I32* retlen)); HE* hv_iternext _((HV* tb)); ! SV * hv_iternextsv _((HV* hv, char** key, I32* retlen)); SV* hv_iterval _((HV* tb, HE* entry)); void hv_magic _((HV* hv, GV* gv, int how)); SV** hv_store _((HV* tb, char* key, U32 klen, SV* val, U32 hash)); void hv_undef _((HV* tb)); I32 ibcmp _((U8* a, U8* b, I32 len)); I32 ingroup _((I32 testgid, I32 effective)); --- 132,158 ---- void gv_fullname _((SV* sv, GV* gv)); 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, I32 shared)); ! void he_free _((HE* hent, I32 shared)); void hoistmust _((PMOP* pm)); void hv_clear _((HV* tb)); 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)); 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_iterval _((HV* tb, HE* entry)); 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 ingroup _((I32 testgid, I32 effective)); *************** *** 164,175 **** --- 171,184 ---- I32 looks_like_number _((SV* sv)); int magic_clearenv _((SV* sv, MAGIC* mg)); int magic_clearpack _((SV* sv, MAGIC* mg)); + int magic_clearsig _((SV* sv, MAGIC* mg)); int magic_existspack _((SV* sv, MAGIC* mg)); int magic_get _((SV* sv, MAGIC* mg)); int magic_getarylen _((SV* sv, MAGIC* mg)); int magic_getpack _((SV* sv, MAGIC* mg)); int magic_getglob _((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)); *************** *** 202,212 **** 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)); int mg_clear _((SV* sv)); ! int mg_copy _((SV *, SV *, char *, STRLEN)); MAGIC* mg_find _((SV* sv, int type)); int mg_free _((SV* sv)); int mg_get _((SV* sv)); --- 211,222 ---- extern Malloc_t malloc _((MEM_SIZE nbytes)); extern Malloc_t realloc _((Malloc_t, MEM_SIZE)); extern Free_t free _((Malloc_t)); + extern Malloc_t calloc _((MEM_SIZE, MEM_SIZE)); #endif void markstack_grow _((void)); char* mess _((char* pat, va_list* args)); int mg_clear _((SV* sv)); ! int mg_copy _((SV *, SV *, char *, I32)); MAGIC* mg_find _((SV* sv, int type)); int mg_free _((SV* sv)); int mg_get _((SV* sv)); *************** *** 313,319 **** 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_i18nl14n _((int printwarn)); 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 --- 323,329 ---- 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_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 *************** *** 347,363 **** --- 357,377 ---- #else char* saferealloc _((char* where, unsigned long size)); #endif + char* safecalloc _((MEM_SIZE cnt, MEM_SIZE size)); #endif #ifdef LEAKTEST void safexfree _((char* where)); char* safexmalloc _((I32 x, MEM_SIZE size)); char* safexrealloc _((char* where, MEM_SIZE size)); + char* safexcalloc _((I32 x, MEM_SIZE size, MEM_SIZE size)); #endif #ifndef HAS_RENAME I32 same_dirent _((char* a, char* b)); #endif char* savepv _((char* sv)); char* savepvn _((char* sv, I32 len)); + char* sharepvn _((char* sv, I32 len, U32 hash)); + void unsharepvn _((char* sv, I32 len, U32 hash)); void savestack_grow _((void)); void save_aptr _((AV** aptr)); AV* save_ary _((GV* gv)); *************** *** 461,467 **** #ifdef UNLINK_ALL_VERSIONS I32 unlnk _((char* f)); #endif ! void utilize _((int aver, I32 floor, OP* id, OP* arg)); I32 wait4pid _((int pid, int* statusp, int flags)); void warn _((char* pat,...)) __attribute__((format(printf,1,2))); void watch _((char **addr)); --- 475,481 ---- #ifdef UNLINK_ALL_VERSIONS I32 unlnk _((char* f)); #endif ! void utilize _((int aver, I32 floor, OP* version, OP* id, OP* arg)); I32 wait4pid _((int pid, int* statusp, int flags)); void warn _((char* pat,...)) __attribute__((format(printf,1,2))); void watch _((char **addr)); #~ Allow redirection of debug messages diff -Pcr perl5_003/regcomp.c perl5_003_01/regcomp.c *** perl5_003/regcomp.c Tue Nov 14 21:42:45 1995 --- perl5_003_01/regcomp.c Tue Jun 18 20:10:12 1996 *************** *** 244,250 **** 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)); /* * If there's something expensive in the r.e., find the --- 244,250 ---- if (sawplus && (!sawopen || !regsawback)) r->reganch |= ROPT_SKIP; /* x+ must match 1st of run */ ! DEBUG_r(fprintf(Perl_debug_log,"first %d next %d offset %d\n", OP(first), OP(NEXTOPER(first)), first - scan)); /* * If there's something expensive in the r.e., find the *************** *** 1432,1438 **** #ifdef DEBUGGING /* ! - regdump - dump a regexp onto stderr in vaguely comprehensible form */ void regdump(r) --- 1432,1438 ---- #ifdef DEBUGGING /* ! - regdump - dump a regexp onto Perl_debug_log in vaguely comprehensible form */ void regdump(r) *************** *** 1450,1462 **** s++; #endif op = OP(s); ! fprintf(stderr,"%2d%s", s-r->program, regprop(s)); /* Where, what. */ next = regnext(s); s += regarglen[(U8)op]; if (next == NULL) /* Next ptr. */ ! fprintf(stderr,"(0)"); else ! fprintf(stderr,"(%d)", (s-r->program)+(next-s)); s += 3; if (op == ANYOF) { s += 32; --- 1450,1462 ---- s++; #endif op = OP(s); ! fprintf(Perl_debug_log,"%2d%s", s-r->program, regprop(s)); /* Where, what. */ next = regnext(s); s += regarglen[(U8)op]; if (next == NULL) /* Next ptr. */ ! fprintf(Perl_debug_log,"(0)"); else ! fprintf(Perl_debug_log,"(%d)", (s-r->program)+(next-s)); s += 3; if (op == ANYOF) { s += 32; *************** *** 1464,1497 **** if (op == EXACTLY) { /* Literal string, where present. */ s++; ! (void)putc(' ', stderr); ! (void)putc('<', stderr); while (*s != '\0') { ! (void)putc(*s, stderr); s++; } ! (void)putc('>', stderr); s++; } ! (void)putc('\n', stderr); } /* 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 "); if (r->reganch & ROPT_SKIP) ! fprintf(stderr,"plus "); if (r->reganch & ROPT_IMPLICIT) ! fprintf(stderr,"implicit "); if (r->regmust != NULL) ! fprintf(stderr,"must have \"%s\" back %ld ", SvPVX(r->regmust), (long) r->regback); ! fprintf(stderr, "minlen %ld ", (long) r->minlen); ! fprintf(stderr,"\n"); } /* --- 1464,1497 ---- if (op == EXACTLY) { /* Literal string, where present. */ s++; ! (void)putc(' ', Perl_debug_log); ! (void)putc('<', Perl_debug_log); while (*s != '\0') { ! (void)putc(*s, Perl_debug_log); s++; } ! (void)putc('>', Perl_debug_log); s++; } ! (void)putc('\n', Perl_debug_log); } /* Header fields of interest. */ if (r->regstart) ! fprintf(Perl_debug_log,"start `%s' ", SvPVX(r->regstart)); if (r->regstclass) ! fprintf(Perl_debug_log,"stclass `%s' ", regprop(r->regstclass)); if (r->reganch & ROPT_ANCH) ! fprintf(Perl_debug_log,"anchored "); if (r->reganch & ROPT_SKIP) ! fprintf(Perl_debug_log,"plus "); if (r->reganch & ROPT_IMPLICIT) ! fprintf(Perl_debug_log,"implicit "); if (r->regmust != NULL) ! fprintf(Perl_debug_log,"must have \"%s\" back %ld ", SvPVX(r->regmust), (long) r->regback); ! fprintf(Perl_debug_log, "minlen %ld ", (long) r->minlen); ! fprintf(Perl_debug_log,"\n"); } /* #~ Allow redirection of debug messages diff -Pcr perl5_003/regexec.c perl5_003_01/regexec.c *** perl5_003/regexec.c Tue Nov 14 21:03:18 1995 --- perl5_003_01/regexec.c Tue Jun 18 20:10:17 1996 *************** *** 590,596 **** #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); } #else --- 590,596 ---- #define sayNO goto no #define saySAME(x) if (x) goto yes; else goto no if (regnarrate) { ! fprintf(Perl_debug_log, "%*s%2d%-8.8s\t<%.10s>\n", regindent*2, "", scan - regprogram, regprop(scan), locinput); } #else *************** *** 806,812 **** #ifdef DEBUGGING if (regnarrate) ! fprintf(stderr, "%*s %d %lx\n", regindent*2, "", n, (long)cc); #endif --- 806,812 ---- #ifdef DEBUGGING if (regnarrate) ! fprintf(Perl_debug_log, "%*s %d %lx\n", regindent*2, "", n, (long)cc); #endif #~ Allow redirection of debug messages diff -Pcr perl5_003/run.c perl5_003_01/run.c *** perl5_003/run.c Mon Mar 25 01:05:34 1996 --- perl5_003_01/run.c Tue Jun 18 20:10:19 1996 *************** *** 47,53 **** do { if (debug) { if (watchaddr != 0 && *watchaddr != watchok) ! fprintf(stderr, "WARNING: %lx changed from %lx to %lx\n", (long)watchaddr, (long)watchok, (long)*watchaddr); DEBUG_s(debstack()); DEBUG_t(debop(op)); --- 47,53 ---- do { if (debug) { if (watchaddr != 0 && *watchaddr != watchok) ! fprintf(Perl_debug_log, "WARNING: %lx changed from %lx to %lx\n", (long)watchaddr, (long)watchok, (long)*watchaddr); DEBUG_s(debstack()); DEBUG_t(debop(op)); *************** *** 65,87 **** deb("%s", op_name[op->op_type]); switch (op->op_type) { case OP_CONST: ! fprintf(stderr, "(%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)); SvREFCNT_dec(sv); } else ! fprintf(stderr, "(NULL)"); break; default: break; } ! fprintf(stderr, "\n"); return 0; } --- 65,87 ---- deb("%s", op_name[op->op_type]); switch (op->op_type) { case OP_CONST: ! fprintf(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(Perl_debug_log, "(%s)", SvPV(sv, na)); SvREFCNT_dec(sv); } else ! fprintf(Perl_debug_log, "(NULL)"); break; default: break; } ! fprintf(Perl_debug_log, "\n"); return 0; } *************** *** 91,97 **** { watchaddr = addr; watchok = *addr; ! fprintf(stderr, "WATCHING, %lx is currently %lx\n", (long)watchaddr, (long)watchok); } --- 91,97 ---- { watchaddr = addr; watchok = *addr; ! fprintf(Perl_debug_log, "WATCHING, %lx is currently %lx\n", (long)watchaddr, (long)watchok); } *************** *** 112,118 **** return; for (i = 0; i < MAXO; i++) { if (profiledata[i]) ! fprintf(stderr, "%d\t%lu\n", i, profiledata[i]); } } --- 112,118 ---- return; for (i = 0; i < MAXO; i++) { if (profiledata[i]) ! fprintf(Perl_debug_log, "%d\t%lu\n", i, profiledata[i]); } } #~ Rename global variable to eliminate collision with system headers #~ Add casts to reflect new GV type #~ Allow redirection of debug messages diff -Pcr perl5_003/scope.c perl5_003_01/scope.c *** perl5_003/scope.c Mon Feb 12 15:00:30 1996 --- perl5_003_01/scope.c Thu Jul 4 14:49:17 1996 *************** *** 22,28 **** int n; { stack_sp = sp; ! av_extend(stack, (p - stack_base) + (n) + 128); return stack_sp; } --- 22,28 ---- int n; { stack_sp = sp; ! av_extend(curstack, (p - stack_base) + (n) + 128); return stack_sp; } *************** *** 518,524 **** break; case SAVEt_NSTAB: gv = (GV*)SSPOPPTR; ! (void)sv_clear(gv); break; case SAVEt_GP: /* scalar reference */ ptr = SSPOPPTR; --- 518,524 ---- break; case SAVEt_NSTAB: gv = (GV*)SSPOPPTR; ! (void)sv_clear((SV*)gv); break; case SAVEt_GP: /* scalar reference */ ptr = SSPOPPTR; *************** *** 608,699 **** } #ifdef DEBUGGING void cx_dump(cx) CONTEXT* cx; { ! fprintf(stderr, "CX %d = %s\n", 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"); } switch (cx->cx_type) { case CXt_NULL: case CXt_BLOCK: break; case CXt_SUB: ! fprintf(stderr, "BLK_SUB.CV = 0x%lx\n", (long)cx->blk_sub.cv); ! fprintf(stderr, "BLK_SUB.GV = 0x%lx\n", (long)cx->blk_sub.gv); ! fprintf(stderr, "BLK_SUB.DFOUTGV = 0x%lx\n", (long)cx->blk_sub.dfoutgv); ! fprintf(stderr, "BLK_SUB.OLDDEPTH = %ld\n", (long)cx->blk_sub.olddepth); ! fprintf(stderr, "BLK_SUB.HASARGS = %d\n", (int)cx->blk_sub.hasargs); break; case CXt_EVAL: ! fprintf(stderr, "BLK_EVAL.OLD_IN_EVAL = %ld\n", (long)cx->blk_eval.old_in_eval); ! fprintf(stderr, "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", cx->blk_eval.old_name); ! fprintf(stderr, "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", cx->blk_loop.label); ! fprintf(stderr, "BLK_LOOP.RESETSP = %ld\n", (long)cx->blk_loop.resetsp); ! fprintf(stderr, "BLK_LOOP.REDO_OP = 0x%lx\n", (long)cx->blk_loop.redo_op); ! fprintf(stderr, "BLK_LOOP.NEXT_OP = 0x%lx\n", (long)cx->blk_loop.next_op); ! fprintf(stderr, "BLK_LOOP.LAST_OP = 0x%lx\n", (long)cx->blk_loop.last_op); ! fprintf(stderr, "BLK_LOOP.ITERIX = %ld\n", (long)cx->blk_loop.iterix); ! fprintf(stderr, "BLK_LOOP.ITERARY = 0x%lx\n", (long)cx->blk_loop.iterary); ! fprintf(stderr, "BLK_LOOP.ITERVAR = 0x%lx\n", (long)cx->blk_loop.itervar); if (cx->blk_loop.itervar) ! fprintf(stderr, "BLK_LOOP.ITERSAVE = 0x%lx\n", (long)cx->blk_loop.itersave); break; case CXt_SUBST: ! fprintf(stderr, "SB_ITERS = %ld\n", (long)cx->sb_iters); ! fprintf(stderr, "SB_MAXITERS = %ld\n", (long)cx->sb_maxiters); ! fprintf(stderr, "SB_SAFEBASE = %ld\n", (long)cx->sb_safebase); ! fprintf(stderr, "SB_ONCE = %ld\n", (long)cx->sb_once); ! fprintf(stderr, "SB_ORIG = %s\n", cx->sb_orig); ! fprintf(stderr, "SB_DSTR = 0x%lx\n", (long)cx->sb_dstr); ! fprintf(stderr, "SB_TARG = 0x%lx\n", (long)cx->sb_targ); ! fprintf(stderr, "SB_S = 0x%lx\n", (long)cx->sb_s); ! fprintf(stderr, "SB_M = 0x%lx\n", (long)cx->sb_m); ! fprintf(stderr, "SB_STREND = 0x%lx\n", (long)cx->sb_strend); ! fprintf(stderr, "SB_SUBBASE = 0x%lx\n", (long)cx->sb_subbase); break; } --- 608,700 ---- } #ifdef DEBUGGING + void cx_dump(cx) CONTEXT* cx; { ! fprintf(Perl_debug_log, "CX %d = %s\n", cx - cxstack, block_type[cx->cx_type]); if (cx->cx_type != CXt_SUBST) { ! fprintf(Perl_debug_log, "BLK_OLDSP = %ld\n", (long)cx->blk_oldsp); ! fprintf(Perl_debug_log, "BLK_OLDCOP = 0x%lx\n", (long)cx->blk_oldcop); ! fprintf(Perl_debug_log, "BLK_OLDMARKSP = %ld\n", (long)cx->blk_oldmarksp); ! fprintf(Perl_debug_log, "BLK_OLDSCOPESP = %ld\n", (long)cx->blk_oldscopesp); ! fprintf(Perl_debug_log, "BLK_OLDRETSP = %ld\n", (long)cx->blk_oldretsp); ! fprintf(Perl_debug_log, "BLK_OLDPM = 0x%lx\n", (long)cx->blk_oldpm); ! fprintf(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(Perl_debug_log, "BLK_SUB.CV = 0x%lx\n", (long)cx->blk_sub.cv); ! fprintf(Perl_debug_log, "BLK_SUB.GV = 0x%lx\n", (long)cx->blk_sub.gv); ! fprintf(Perl_debug_log, "BLK_SUB.DFOUTGV = 0x%lx\n", (long)cx->blk_sub.dfoutgv); ! fprintf(Perl_debug_log, "BLK_SUB.OLDDEPTH = %ld\n", (long)cx->blk_sub.olddepth); ! fprintf(Perl_debug_log, "BLK_SUB.HASARGS = %d\n", (int)cx->blk_sub.hasargs); break; case CXt_EVAL: ! fprintf(Perl_debug_log, "BLK_EVAL.OLD_IN_EVAL = %ld\n", (long)cx->blk_eval.old_in_eval); ! fprintf(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(Perl_debug_log, "BLK_EVAL.OLD_NAME = %s\n", cx->blk_eval.old_name); ! fprintf(Perl_debug_log, "BLK_EVAL.OLD_EVAL_ROOT = 0x%lx\n", (long)cx->blk_eval.old_eval_root); break; case CXt_LOOP: ! fprintf(Perl_debug_log, "BLK_LOOP.LABEL = %s\n", cx->blk_loop.label); ! fprintf(Perl_debug_log, "BLK_LOOP.RESETSP = %ld\n", (long)cx->blk_loop.resetsp); ! fprintf(Perl_debug_log, "BLK_LOOP.REDO_OP = 0x%lx\n", (long)cx->blk_loop.redo_op); ! fprintf(Perl_debug_log, "BLK_LOOP.NEXT_OP = 0x%lx\n", (long)cx->blk_loop.next_op); ! fprintf(Perl_debug_log, "BLK_LOOP.LAST_OP = 0x%lx\n", (long)cx->blk_loop.last_op); ! fprintf(Perl_debug_log, "BLK_LOOP.ITERIX = %ld\n", (long)cx->blk_loop.iterix); ! fprintf(Perl_debug_log, "BLK_LOOP.ITERARY = 0x%lx\n", (long)cx->blk_loop.iterary); ! fprintf(Perl_debug_log, "BLK_LOOP.ITERVAR = 0x%lx\n", (long)cx->blk_loop.itervar); if (cx->blk_loop.itervar) ! fprintf(Perl_debug_log, "BLK_LOOP.ITERSAVE = 0x%lx\n", (long)cx->blk_loop.itersave); break; case CXt_SUBST: ! fprintf(Perl_debug_log, "SB_ITERS = %ld\n", (long)cx->sb_iters); ! fprintf(Perl_debug_log, "SB_MAXITERS = %ld\n", (long)cx->sb_maxiters); ! fprintf(Perl_debug_log, "SB_SAFEBASE = %ld\n", (long)cx->sb_safebase); ! fprintf(Perl_debug_log, "SB_ONCE = %ld\n", (long)cx->sb_once); ! fprintf(Perl_debug_log, "SB_ORIG = %s\n", cx->sb_orig); ! fprintf(Perl_debug_log, "SB_DSTR = 0x%lx\n", (long)cx->sb_dstr); ! fprintf(Perl_debug_log, "SB_TARG = 0x%lx\n", (long)cx->sb_targ); ! fprintf(Perl_debug_log, "SB_S = 0x%lx\n", (long)cx->sb_s); ! fprintf(Perl_debug_log, "SB_M = 0x%lx\n", (long)cx->sb_m); ! fprintf(Perl_debug_log, "SB_STREND = 0x%lx\n", (long)cx->sb_strend); ! fprintf(Perl_debug_log, "SB_SUBBASE = 0x%lx\n", (long)cx->sb_subbase); break; } #~ Correct cast in SAVEDESTRUCTOR macro diff -Pcr perl5_003/scope.h perl5_003_01/scope.h *** perl5_003/scope.h Tue Oct 18 12:23:09 1994 --- perl5_003_01/scope.h Tue Jun 18 15:12:07 1996 *************** *** 54,58 **** #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) --- 54,58 ---- #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((void(*)_((void*)))f,(void*)p) #~ Don't try stdio tricks under QNX #~ Mark deleted SV with "impossible" type #~ Use Safemalloc to allocate memory for SVs, since we'll use Safefree #~ to deallocate it later #~ Use casts to reflect new GV type #~ Allow redirection of debug messages #~ Add shared hash key support #~ Tolerate dangling references in debugger during object destruction #~ Don't warn about unreferenced scalars spotted during sv_clean_all() #~ If we're not trying stdio tricks, at least give system calls some #~ breathing room when we use the same line terminator they do (\n) #~ Add information to sv_dump() output diff -Pcr perl5_003/sv.c perl5_003_01/sv.c *** perl5_003/sv.c Tue Feb 27 20:46:38 1996 --- perl5_003_01/sv.c Thu Jul 25 15:26:20 1996 *************** *** 36,42 **** #endif #endif ! #if defined(USE_STDIO_PTR) && defined(STDIO_PTR_LVALUE) && defined(STDIO_CNT_LVALUE) # define FAST_SV_GETS #endif --- 36,42 ---- #endif #endif ! #if defined(USE_STDIO_PTR) && defined(STDIO_PTR_LVALUE) && defined(STDIO_CNT_LVALUE) && !defined(__QNX__) # define FAST_SV_GETS #endif *************** *** 103,108 **** --- 103,109 ---- del_sv(p); \ else { \ SvANY(p) = (void *)sv_root; \ + SvFLAGS(p) = SVTYPEMASK; \ sv_root = p; \ --sv_count; \ } *************** *** 176,183 **** sv_add_arena(nice_chunk, nice_chunk_size, 0); nice_chunk = Nullch; } ! else ! sv_add_arena(safemalloc(1008), 1008, 0); return new_sv(); } #endif --- 177,187 ---- sv_add_arena(nice_chunk, nice_chunk_size, 0); nice_chunk = Nullch; } ! 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); ! } return new_sv(); } #endif *************** *** 213,221 **** #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))) { --- 217,225 ---- #ifndef DISABLE_DESTRUCTOR_KLUDGE register GV* gv; for (sva = sv_arenaroot; sva; sva = (SV *) SvANY(sva)) { ! gv = (GV*)sva + 1; svend = &sva[SvREFCNT(sva)]; ! while ((SV*)gv < svend) { if (SvTYPE(gv) == SVt_PVGV && (sv = GvSV(gv)) && SvROK(sv) && SvOBJECT(rv = SvRV(sv))) { *************** *** 248,253 **** --- 252,259 ---- } } + static int in_clean_all = 0; + void sv_clean_all() { *************** *** 255,272 **** 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; } } } void --- 261,280 ---- register SV* sv; register SV* svend; + in_clean_all = 1; 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(Perl_debug_log, "Cleaning loops:\n "), sv_dump(sv));) SvFLAGS(sv) |= SVf_BREAK; SvREFCNT_dec(sv); } ++sv; } } + in_clean_all = 0; } void *************** *** 284,290 **** svanext = (SV*) SvANY(svanext); if (!SvFAKE(sva)) ! Safefree(sva); } } --- 292,298 ---- svanext = (SV*) SvANY(svanext); if (!SvFAKE(sva)) ! Safefree((void *)sva); } } *************** *** 1199,1205 **** warn(warn_uninit); return 0; } ! DEBUG_c(fprintf(stderr,"0x%lx 2iv(%ld)\n", (unsigned long)sv,(long)SvIVX(sv))); return SvIVX(sv); } --- 1207,1214 ---- warn(warn_uninit); return 0; } ! (void)SvIOK_on(sv); ! DEBUG_c(fprintf(Perl_debug_log,"0x%lx 2iv(%ld)\n", (unsigned long)sv,(long)SvIVX(sv))); return SvIVX(sv); } *************** *** 1252,1258 **** 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))); } else if (SvTYPE(sv) < SVt_PVNV) sv_upgrade(sv, SVt_PVNV); --- 1261,1267 ---- sv_upgrade(sv, SVt_PVNV); else sv_upgrade(sv, SVt_NV); ! DEBUG_c(fprintf(Perl_debug_log,"0x%lx num(%g)\n",(unsigned long)sv,SvNVX(sv))); } else if (SvTYPE(sv) < SVt_PVNV) sv_upgrade(sv, SVt_PVNV); *************** *** 1272,1278 **** return 0.0; } SvNOK_on(sv); ! DEBUG_c(fprintf(stderr,"0x%lx 2nv(%g)\n",(unsigned long)sv,SvNVX(sv))); return SvNVX(sv); } --- 1281,1287 ---- return 0.0; } SvNOK_on(sv); ! DEBUG_c(fprintf(Perl_debug_log,"0x%lx 2nv(%g)\n",(unsigned long)sv,SvNVX(sv))); return SvNVX(sv); } *************** *** 1407,1413 **** *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))); return SvPVX(sv); tokensave: --- 1416,1422 ---- *lp = s - SvPVX(sv); SvCUR_set(sv, *lp); SvPOK_on(sv); ! DEBUG_c(fprintf(Perl_debug_log,"0x%lx 2pv(%s)\n",(unsigned long)sv,SvPVX(sv))); return SvPVX(sv); tokensave: *************** *** 1600,1606 **** } (void)SvOK_off(dstr); GvINTRO_off(dstr); /* one-shot flag */ ! gp_free(dstr); GvGP(dstr) = gp_ref(GvGP(sstr)); SvTAINT(dstr); if (curcop->cop_stash != GvSTASH(dstr)) --- 1609,1615 ---- } (void)SvOK_off(dstr); GvINTRO_off(dstr); /* one-shot flag */ ! gp_free((GV*)dstr); GvGP(dstr) = gp_ref(GvGP(sstr)); SvTAINT(dstr); if (curcop->cop_stash != GvSTASH(dstr)) *************** *** 1635,1641 **** GvREFCNT(dstr) = 1; GvSV(dstr) = NEWSV(72,0); GvLINE(dstr) = curcop->cop_line; ! GvEGV(dstr) = dstr; } GvMULTI_on(dstr); switch (SvTYPE(sref)) { --- 1644,1650 ---- GvREFCNT(dstr) = 1; GvSV(dstr) = NEWSV(72,0); GvLINE(dstr) = curcop->cop_line; ! GvEGV(dstr) = (GV*)dstr; } GvMULTI_on(dstr); switch (SvTYPE(sref)) { *************** *** 1991,1996 **** --- 2000,2007 ---- 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; *************** *** 2026,2033 **** } mg->mg_type = how; mg->mg_len = namlen; ! if (name && namlen >= 0) ! mg->mg_ptr = savepvn(name, namlen); switch (how) { case 0: mg->mg_virtual = &vtbl_sv; --- 2037,2048 ---- } mg->mg_type = how; mg->mg_len = 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; *************** *** 2134,2140 **** 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_flags & MGf_REFCOUNTED) SvREFCNT_dec(mg->mg_obj); Safefree(mg); --- 2149,2158 ---- if (vtbl && vtbl->svt_free) (*vtbl->svt_free)(sv, mg); if (mg->mg_ptr && mg->mg_type != 'g') ! 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); *************** *** 2261,2266 **** --- 2279,2285 ---- sv_clear(sv); StructCopy(nsv,sv,SV); SvREFCNT(sv) = refcnt; + SvFLAGS(nsv) |= SVTYPEMASK; /* Mark as freed */ del_SV(nsv); } *************** *** 2285,2291 **** Zero(&ref, 1, SV); sv_upgrade(&ref, SVt_RV); - SAVEI32(SvREFCNT(sv)); SvRV(&ref) = SvREFCNT_inc(sv); SvROK_on(&ref); --- 2304,2309 ---- *************** *** 2295,2300 **** --- 2313,2319 ---- PUTBACK; perl_call_sv((SV*)destructor, G_DISCARD|G_EVAL|G_KEEPERR); del_XRV(SvANY(&ref)); + SvREFCNT(sv)--; } LEAVE; } *************** *** 2305,2310 **** --- 2324,2342 ---- if (SvTYPE(sv) != SVt_PVIO) --sv_objcount; /* XXX Might want something more general */ } + if (SvREFCNT(sv)) { + SV *ret; + if ( perldb + && (ret = perl_get_sv("DB::ret", FALSE)) + && SvROK(ret) && SvRV(ret) == sv && SvREFCNT(sv) == 1) { + /* Debugger is prone to dangling references. */ + SvRV(ret) = 0; + SvROK_off(ret); + SvREFCNT(sv) = 0; + } else { + croak("panic: dangling references in DESTROY"); + } + } } if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) mg_free(sv); *************** *** 2328,2334 **** av_undef((AV*)sv); break; case SVt_PVGV: ! gp_free(sv); Safefree(GvNAME(sv)); /* FALL THROUGH */ case SVt_PVLV: --- 2360,2366 ---- av_undef((AV*)sv); break; case SVt_PVGV: ! gp_free((GV*)sv); Safefree(GvNAME(sv)); /* FALL THROUGH */ case SVt_PVLV: *************** *** 2342,2348 **** case SVt_RV: if (SvROK(sv)) SvREFCNT_dec(SvRV(sv)); ! else if (SvPVX(sv)) Safefree(SvPVX(sv)); break; /* --- 2374,2380 ---- case SVt_RV: if (SvROK(sv)) SvREFCNT_dec(SvRV(sv)); ! else if (SvPVX(sv) && SvLEN(sv)) Safefree(SvPVX(sv)); break; /* *************** *** 2428,2433 **** --- 2460,2467 ---- 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; } *************** *** 2680,2694 **** screamer: if (rslen) { ! register STDCHAR *bpe = buf + sizeof(buf); ! bp = buf; ! while ((i = 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; } if (append) --- 2714,2734 ---- screamer: if (rslen) { ! if (rslast == '\n') { ! i = fgets(buf,sizeof buf,fp) == NULL ? EOF : *buf; ! cnt = i == EOF ? 0 : strlen(buf); ! } ! else { ! register STDCHAR *bpe = buf + sizeof(buf); ! bp = buf; ! while ((i = getc(fp)) != EOF && (*bp++ = i) != rslast && bp < bpe) ! ; /* keep reading */ ! cnt = bp - buf; ! } } else { cnt = fread((char*)buf, 1, sizeof(buf), fp); ! i = cnt ? !EOF : EOF; } if (append) *************** *** 3023,3032 **** for (i = 0; i <= (I32) HvMAX(stash); i++) { for (entry = HvARRAY(stash)[i]; entry; ! entry = entry->hent_next) { ! if (!todo[(U8)*entry->hent_key]) continue; ! gv = (GV*)entry->hent_val; sv = GvSV(gv); (void)SvOK_off(sv); if (SvTYPE(sv) >= SVt_PV) { --- 3063,3072 ---- for (i = 0; i <= (I32) HvMAX(stash); i++) { for (entry = HvARRAY(stash)[i]; entry; ! entry = HeNEXT(entry)) { ! if (!todo[(U8)*HeKEY(entry)]) continue; ! gv = (GV*)HeVAL(entry); sv = GvSV(gv); (void)SvOK_off(sv); if (SvTYPE(sv) >= SVt_PV) { *************** *** 3225,3231 **** if (!SvPOK(sv)) { SvPOK_on(sv); /* validate pointer */ SvTAINT(sv); ! DEBUG_c(fprintf(stderr,"0x%lx 2pv(%s)\n", (unsigned long)sv,SvPVX(sv))); } } --- 3265,3271 ---- if (!SvPOK(sv)) { SvPOK_on(sv); /* validate pointer */ SvTAINT(sv); ! DEBUG_c(fprintf(Perl_debug_log,"0x%lx 2pv(%s)\n", (unsigned long)sv,SvPVX(sv))); } } *************** *** 3394,3400 **** assert(SvTYPE(sv) == SVt_PVGV); SvFAKE_off(sv); if (GvGP(sv)) ! gp_free(sv); sv_unmagic(sv, '*'); Safefree(GvNAME(sv)); GvMULTI_off(sv); --- 3434,3440 ---- assert(SvTYPE(sv) == SVt_PVGV); SvFAKE_off(sv); if (GvGP(sv)) ! gp_free((GV*)sv); sv_unmagic(sv, '*'); Safefree(GvNAME(sv)); GvMULTI_off(sv); *************** *** 3427,3433 **** U32 type; if (!sv) { ! fprintf(stderr, "SV = 0\n"); return; } --- 3467,3473 ---- U32 type; if (!sv) { ! fprintf(Perl_debug_log, "SV = 0\n"); return; } *************** *** 3456,3531 **** 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'; ! fprintf(stderr, "SV = "); switch (type) { case SVt_NULL: ! fprintf(stderr,"NULL%s\n", tmpbuf); return; case SVt_IV: ! fprintf(stderr,"IV%s\n", tmpbuf); break; case SVt_NV: ! fprintf(stderr,"NV%s\n", tmpbuf); break; case SVt_RV: ! fprintf(stderr,"RV%s\n", tmpbuf); break; case SVt_PV: ! fprintf(stderr,"PV%s\n", tmpbuf); break; case SVt_PVIV: ! fprintf(stderr,"PVIV%s\n", tmpbuf); break; case SVt_PVNV: ! fprintf(stderr,"PVNV%s\n", tmpbuf); break; case SVt_PVBM: ! fprintf(stderr,"PVBM%s\n", tmpbuf); break; case SVt_PVMG: ! fprintf(stderr,"PVMG%s\n", tmpbuf); break; case SVt_PVLV: ! fprintf(stderr,"PVLV%s\n", tmpbuf); break; case SVt_PVAV: ! fprintf(stderr,"PVAV%s\n", tmpbuf); break; case SVt_PVHV: ! fprintf(stderr,"PVHV%s\n", tmpbuf); break; case SVt_PVCV: ! fprintf(stderr,"PVCV%s\n", tmpbuf); break; case SVt_PVGV: ! fprintf(stderr,"PVGV%s\n", tmpbuf); break; case SVt_PVFM: ! fprintf(stderr,"PVFM%s\n", tmpbuf); break; case SVt_PVIO: ! fprintf(stderr,"PVIO%s\n", tmpbuf); break; default: ! fprintf(stderr,"UNKNOWN%s\n", tmpbuf); 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)); if (SvROK(sv)) { ! fprintf(stderr, " RV = 0x%lx\n", (long)SvRV(sv)); sv_dump(SvRV(sv)); return; } --- 3496,3588 ---- if (flags & SVf_READONLY) strcat(d, "READONLY,"); d += strlen(d); + #ifdef OVERLOAD + if (flags & SVf_AMAGIC) strcat(d, "OVERLOAD,"); + #endif /* OVERLOAD */ 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,"); + + switch (type) { + case SVt_PVCV: + if (CvANON(sv)) strcat(d, "ANON,"); + if (CvCLONE(sv)) strcat(d, "CLONE,"); + if (CvCLONED(sv)) strcat(d, "CLONED,"); + break; + case SVt_PVGV: + if (GvMULTI(sv)) strcat(d, "MULTI,"); + #ifdef OVERLOAD + if (flags & SVpgv_AM) strcat(d, "withOVERLOAD,"); + #endif /* OVERLOAD */ + } + d += strlen(d); if (d[-1] == ',') d--; *d++ = ')'; *d = '\0'; ! fprintf(Perl_debug_log, "SV = "); switch (type) { case SVt_NULL: ! fprintf(Perl_debug_log,"NULL%s\n", tmpbuf); return; case SVt_IV: ! fprintf(Perl_debug_log,"IV%s\n", tmpbuf); break; case SVt_NV: ! fprintf(Perl_debug_log,"NV%s\n", tmpbuf); break; case SVt_RV: ! fprintf(Perl_debug_log,"RV%s\n", tmpbuf); break; case SVt_PV: ! fprintf(Perl_debug_log,"PV%s\n", tmpbuf); break; case SVt_PVIV: ! fprintf(Perl_debug_log,"PVIV%s\n", tmpbuf); break; case SVt_PVNV: ! fprintf(Perl_debug_log,"PVNV%s\n", tmpbuf); break; case SVt_PVBM: ! fprintf(Perl_debug_log,"PVBM%s\n", tmpbuf); break; case SVt_PVMG: ! fprintf(Perl_debug_log,"PVMG%s\n", tmpbuf); break; case SVt_PVLV: ! fprintf(Perl_debug_log,"PVLV%s\n", tmpbuf); break; case SVt_PVAV: ! fprintf(Perl_debug_log,"PVAV%s\n", tmpbuf); break; case SVt_PVHV: ! fprintf(Perl_debug_log,"PVHV%s\n", tmpbuf); break; case SVt_PVCV: ! fprintf(Perl_debug_log,"PVCV%s\n", tmpbuf); break; case SVt_PVGV: ! fprintf(Perl_debug_log,"PVGV%s\n", tmpbuf); break; case SVt_PVFM: ! fprintf(Perl_debug_log,"PVFM%s\n", tmpbuf); break; case SVt_PVIO: ! fprintf(Perl_debug_log,"PVIO%s\n", tmpbuf); break; default: ! fprintf(Perl_debug_log,"UNKNOWN%s\n", tmpbuf); return; } if (type >= SVt_PVIV || type == SVt_IV) ! fprintf(Perl_debug_log, " IV = %ld\n", (long)SvIVX(sv)); if (type >= SVt_PVNV || type == SVt_NV) ! fprintf(Perl_debug_log, " NV = %.*g\n", DBL_DIG, SvNVX(sv)); if (SvROK(sv)) { ! fprintf(Perl_debug_log, " RV = 0x%lx\n", (long)SvRV(sv)); sv_dump(SvRV(sv)); return; } *************** *** 3533,3635 **** return; if (type <= SVt_PVLV) { if (SvPVX(sv)) ! fprintf(stderr, " 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"); } if (type >= SVt_PVMG) { if (SvMAGIC(sv)) { ! fprintf(stderr, " MAGIC = 0x%lx\n", (long)SvMAGIC(sv)); } if (SvSTASH(sv)) ! fprintf(stderr, " 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)); 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)); 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); 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)); if (HvPMROOT(sv)) ! fprintf(stderr, " PMROOT = 0x%lx\n",(long)HvPMROOT(sv)); if (HvNAME(sv)) ! fprintf(stderr, " 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 (type == SVt_PVFM) ! fprintf(stderr, " 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)); 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)); break; } } --- 3590,3701 ---- return; if (type <= SVt_PVLV) { if (SvPVX(sv)) ! fprintf(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(Perl_debug_log, " PV = 0\n"); } if (type >= SVt_PVMG) { if (SvMAGIC(sv)) { ! fprintf(Perl_debug_log, " MAGIC = 0x%lx\n", (long)SvMAGIC(sv)); } if (SvSTASH(sv)) ! fprintf(Perl_debug_log, " STASH = \"%s\"\n", HvNAME(SvSTASH(sv))); } switch (type) { case SVt_PVLV: ! fprintf(Perl_debug_log, " TYPE = %c\n", LvTYPE(sv)); ! fprintf(Perl_debug_log, " TARGOFF = %ld\n", (long)LvTARGOFF(sv)); ! fprintf(Perl_debug_log, " TARGLEN = %ld\n", (long)LvTARGLEN(sv)); ! fprintf(Perl_debug_log, " TARG = 0x%lx\n", (long)LvTARG(sv)); sv_dump(LvTARG(sv)); break; case SVt_PVAV: ! fprintf(Perl_debug_log, " ARRAY = 0x%lx\n", (long)AvARRAY(sv)); ! fprintf(Perl_debug_log, " ALLOC = 0x%lx\n", (long)AvALLOC(sv)); ! fprintf(Perl_debug_log, " FILL = %ld\n", (long)AvFILL(sv)); ! fprintf(Perl_debug_log, " MAX = %ld\n", (long)AvMAX(sv)); ! fprintf(Perl_debug_log, " ARYLEN = 0x%lx\n", (long)AvARYLEN(sv)); flags = AvFLAGS(sv); d = tmpbuf; + *d = '\0'; 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(Perl_debug_log, " FLAGS = (%s)\n", d); break; case SVt_PVHV: ! fprintf(Perl_debug_log, " ARRAY = 0x%lx\n",(long)HvARRAY(sv)); ! fprintf(Perl_debug_log, " KEYS = %ld\n", (long)HvKEYS(sv)); ! fprintf(Perl_debug_log, " FILL = %ld\n", (long)HvFILL(sv)); ! fprintf(Perl_debug_log, " MAX = %ld\n", (long)HvMAX(sv)); ! fprintf(Perl_debug_log, " RITER = %ld\n", (long)HvRITER(sv)); ! fprintf(Perl_debug_log, " EITER = 0x%lx\n",(long) HvEITER(sv)); if (HvPMROOT(sv)) ! fprintf(Perl_debug_log, " PMROOT = 0x%lx\n",(long)HvPMROOT(sv)); if (HvNAME(sv)) ! fprintf(Perl_debug_log, " NAME = \"%s\"\n", HvNAME(sv)); break; case SVt_PVFM: case SVt_PVCV: ! if (SvPOK(sv)) ! fprintf(Perl_debug_log, " PROTOTYPE = \"%s\"\n", SvPV(sv,na)); ! fprintf(Perl_debug_log, " STASH = 0x%lx\n", (long)CvSTASH(sv)); ! fprintf(Perl_debug_log, " START = 0x%lx\n", (long)CvSTART(sv)); ! fprintf(Perl_debug_log, " ROOT = 0x%lx\n", (long)CvROOT(sv)); ! fprintf(Perl_debug_log, " XSUB = 0x%lx\n", (long)CvXSUB(sv)); ! fprintf(Perl_debug_log, " XSUBANY = %ld\n", (long)CvXSUBANY(sv).any_i32); ! fprintf(stderr, " GV = 0x%lx", (long)CvGV(sv)); ! if (CvGV(sv) && GvNAME(CvGV(sv))) { ! fprintf(stderr, " \"%s\"\n", GvNAME(CvGV(sv))); ! } else { ! fprintf(stderr, "\n"); ! } ! fprintf(Perl_debug_log, " FILEGV = 0x%lx\n", (long)CvFILEGV(sv)); ! fprintf(Perl_debug_log, " DEPTH = %ld\n", (long)CvDEPTH(sv)); ! fprintf(Perl_debug_log, " PADLIST = 0x%lx\n", (long)CvPADLIST(sv)); ! fprintf(Perl_debug_log, " OUTSIDE = 0x%lx\n", (long)CvOUTSIDE(sv)); if (type == SVt_PVFM) ! fprintf(Perl_debug_log, " LINES = %ld\n", (long)FmLINES(sv)); break; case SVt_PVGV: ! fprintf(Perl_debug_log, " NAME = \"%s\"\n", GvNAME(sv)); ! fprintf(Perl_debug_log, " NAMELEN = %ld\n", (long)GvNAMELEN(sv)); ! fprintf(Perl_debug_log, " STASH = \"%s\"\n", HvNAME(GvSTASH(sv))); ! fprintf(Perl_debug_log, " GP = 0x%lx\n", (long)GvGP(sv)); ! fprintf(Perl_debug_log, " SV = 0x%lx\n", (long)GvSV(sv)); ! fprintf(Perl_debug_log, " REFCNT = %ld\n", (long)GvREFCNT(sv)); ! fprintf(Perl_debug_log, " IO = 0x%lx\n", (long)GvIOp(sv)); ! fprintf(Perl_debug_log, " FORM = 0x%lx\n", (long)GvFORM(sv)); ! fprintf(Perl_debug_log, " AV = 0x%lx\n", (long)GvAV(sv)); ! fprintf(Perl_debug_log, " HV = 0x%lx\n", (long)GvHV(sv)); ! fprintf(Perl_debug_log, " CV = 0x%lx\n", (long)GvCV(sv)); ! fprintf(Perl_debug_log, " CVGEN = 0x%lx\n", (long)GvCVGEN(sv)); ! fprintf(Perl_debug_log, " LASTEXPR = %ld\n", (long)GvLASTEXPR(sv)); ! fprintf(Perl_debug_log, " LINE = %ld\n", (long)GvLINE(sv)); ! fprintf(Perl_debug_log, " FLAGS = 0x%x\n", (int)GvFLAGS(sv)); ! fprintf(Perl_debug_log, " STASH = \"%s\"\n", HvNAME(GvSTASH(sv))); ! fprintf(Perl_debug_log, " EGV = 0x%lx\n", (long)GvEGV(sv)); break; case SVt_PVIO: ! fprintf(Perl_debug_log, " IFP = 0x%lx\n", (long)IoIFP(sv)); ! fprintf(Perl_debug_log, " OFP = 0x%lx\n", (long)IoOFP(sv)); ! fprintf(Perl_debug_log, " DIRP = 0x%lx\n", (long)IoDIRP(sv)); ! fprintf(Perl_debug_log, " LINES = %ld\n", (long)IoLINES(sv)); ! fprintf(Perl_debug_log, " PAGE = %ld\n", (long)IoPAGE(sv)); ! fprintf(Perl_debug_log, " PAGE_LEN = %ld\n", (long)IoPAGE_LEN(sv)); ! fprintf(Perl_debug_log, " LINES_LEFT = %ld\n", (long)IoLINES_LEFT(sv)); ! fprintf(Perl_debug_log, " TOP_NAME = \"%s\"\n", IoTOP_NAME(sv)); ! fprintf(Perl_debug_log, " TOP_GV = 0x%lx\n", (long)IoTOP_GV(sv)); ! fprintf(Perl_debug_log, " FMT_NAME = \"%s\"\n", IoFMT_NAME(sv)); ! fprintf(Perl_debug_log, " FMT_GV = 0x%lx\n", (long)IoFMT_GV(sv)); ! fprintf(Perl_debug_log, " BOTTOM_NAME = \"%s\"\n", IoBOTTOM_NAME(sv)); ! fprintf(Perl_debug_log, " BOTTOM_GV = 0x%lx\n", (long)IoBOTTOM_GV(sv)); ! fprintf(Perl_debug_log, " SUBPROCESS = %ld\n", (long)IoSUBPROCESS(sv)); ! fprintf(Perl_debug_log, " TYPE = %c\n", IoTYPE(sv)); ! fprintf(Perl_debug_log, " FLAGS = 0x%lx\n", (long)IoFLAGS(sv)); break; } } #~ Add shared hash key support diff -Pcr perl5_003/sv.h perl5_003_01/sv.h *** perl5_003/sv.h Mon Mar 25 01:05:36 1996 --- perl5_003_01/sv.h Tue Jun 18 21:47:09 1996 *************** *** 129,134 **** --- 129,136 ---- #define SVpbm_CASEFOLD 0x40000000 #define SVpbm_TAIL 0x20000000 + #define SVphv_SHAREKEYS 0x20000000 /* keys live on shared string table */ + #ifdef OVERLOAD #define SVpgv_AM 0x40000000 /* #define SVpgv_badAM 0x20000000 */ #~ Mention when tests were skipped instead of passed diff -Pcr perl5_003/t/TEST perl5_003_01/t/TEST *** perl5_003/t/TEST Mon Mar 25 01:05:41 1996 --- perl5_003_01/t/TEST Tue Jul 9 12:11:22 1996 *************** *** 80,87 **** } $next = $next - 1; if ($ok && $next == $max) { ! print "ok\n"; ! $good = $good + 1; } else { $next += 1; print "FAILED on test $next\n"; --- 80,92 ---- } $next = $next - 1; if ($ok && $next == $max) { ! if ($max) { ! print "ok\n"; ! $good = $good + 1; ! } else { ! print "skipping test on this platform\n"; ! $files -= 1; ! } } else { $next += 1; print "FAILED on test $next\n"; #~ Add tests to check treatment of numbers between 0 and -1 diff -Pcr perl5_003/t/cmd/mod.t perl5_003_01/t/cmd/mod.t *** perl5_003/t/cmd/mod.t Mon Mar 25 01:05:37 1996 --- perl5_003_01/t/cmd/mod.t Wed May 1 15:08:47 1996 *************** *** 2,8 **** # $RCSfile: mod.t,v $$Revision: 4.1 $$Date: 92/08/07 18:27:11 $ ! print "1..7\n"; print "ok 1\n" if 1; print "not ok 1\n" unless 1; --- 2,8 ---- # $RCSfile: mod.t,v $$Revision: 4.1 $$Date: 92/08/07 18:27:11 $ ! print "1..11\n"; print "ok 1\n" if 1; print "not ok 1\n" unless 1; *************** *** 31,33 **** --- 31,47 ---- $x = 0; $x++ while ; print $x > 50 && $x < 1000 ? "ok 7\n" : "not ok 7\n"; + + $x = -0.5; + print "not " if scalar($x) < 0 and $x >= 0; + print "ok 8\n"; + + print "not " unless (-(-$x) < 0) == ($x < 0); + print "ok 9\n"; + + print "ok 10\n" if $x < 0; + print "not ok 10\n" unless $x < 0; + + print "ok 11\n" unless $x > 0; + print "not ok 11\n" if $x > 0; + #~ Updated as part of DB_File update diff -Pcr perl5_003/t/lib/db-btree.t perl5_003_01/t/lib/db-btree.t *** perl5_003/t/lib/db-btree.t Sat Jan 20 01:00:26 1996 --- perl5_003_01/t/lib/db-btree.t Fri Jul 5 18:45:38 1996 *************** *** 12,27 **** use DB_File; use Fcntl; ! print "1..76\n"; ! $Dfile = "Op.db-btree"; unlink $Dfile; umask(0); # Check the interface to BTREEINFO ! $dbh = TIEHASH DB_File::BTREEINFO ; print (($dbh->{flags} == undef) ? "ok 1\n" : "not ok 1\n") ; print (($dbh->{cachesize} == undef) ? "ok 2\n" : "not ok 2\n") ; print (($dbh->{psize} == undef) ? "ok 3\n" : "not ok 3\n") ; --- 12,28 ---- use DB_File; use Fcntl; ! print "1..86\n"; ! $Dfile = "dbbtree.tmp"; unlink $Dfile; umask(0); # Check the interface to BTREEINFO ! #$dbh = TIEHASH DB_File::BTREEINFO ; ! $dbh = new DB_File::BTREEINFO ; print (($dbh->{flags} == undef) ? "ok 1\n" : "not ok 1\n") ; print (($dbh->{cachesize} == undef) ? "ok 2\n" : "not ok 2\n") ; print (($dbh->{psize} == undef) ? "ok 3\n" : "not ok 3\n") ; *************** *** 57,65 **** # Check that an invalid entry is caught both for store & fetch eval '$dbh->{fred} = 1234' ; ! print ($@ eq '' ? "ok 17\n" : "not ok 17\n") ; eval '$q = $dbh->{fred}' ; ! print ($@ eq '' ? "ok 18\n" : "not ok 18\n") ; # Now check the interface to BTREE --- 58,66 ---- # Check that an invalid entry is caught both for store & fetch eval '$dbh->{fred} = 1234' ; ! print ($@ =~ /^DB_File::BTREEINFO::STORE - Unknown element 'fred' at/ ? "ok 17\n" : "not ok 17\n") ; eval '$q = $dbh->{fred}' ; ! print ($@ =~ /^DB_File::BTREEINFO::FETCH - Unknown element 'fred' at/ ? "ok 18\n" : "not ok 18\n") ; # Now check the interface to BTREE *************** *** 77,83 **** $h{'goner1'} = 'snork'; $h{'abc'} = 'ABC'; ! print ($h{'abc'} == 'ABC' ? "ok 22\n" : "not ok 22\n") ; print (defined $h{'jimmy'} ? "not ok 23\n" : "ok 23\n"); $h{'def'} = 'DEF'; --- 78,84 ---- $h{'goner1'} = 'snork'; $h{'abc'} = 'ABC'; ! print ($h{'abc'} eq 'ABC' ? "ok 22\n" : "not ok 22\n") ; print (defined $h{'jimmy'} ? "not ok 23\n" : "ok 23\n"); $h{'def'} = 'DEF'; *************** *** 152,158 **** if ($i == 30) {print "ok 26\n";} else {print "not ok 26\n";} ! @keys = ('blurfl', keys(h), 'dyick'); if ($#keys == 31) {print "ok 27\n";} else {print "not ok 27\n";} #Check that the keys can be retrieved in order --- 153,159 ---- if ($i == 30) {print "ok 26\n";} else {print "not ok 26\n";} ! @keys = ('blurfl', keys(%h), 'dyick'); if ($#keys == 31) {print "ok 27\n";} else {print "not ok 27\n";} #Check that the keys can be retrieved in order *************** *** 345,353 **** --- 346,398 ---- $status = $Y->fd ; print ($status == -1 ? "ok 73\n" : "not ok 73\n") ; + undef $Y ; untie %h ; + # Duplicate keys + my $bt = new DB_File::BTREEINFO ; + $bt->{flags} = R_DUP ; + print (($YY = tie(%hh, DB_File, $Dfile, O_RDWR|O_CREAT, 0640, $bt )) ? "ok 74\n" : "not ok 74"); + + $hh{'Wall'} = 'Larry' ; + $hh{'Wall'} = 'Stone' ; # Note the duplicate key + $hh{'Wall'} = 'Brick' ; # Note the duplicate key + $hh{'Smith'} = 'John' ; + $hh{'mouse'} = 'mickey' ; + + # first work in scalar context + print(scalar $YY->get_dup('Unknown') == 0 ? "ok 75\n" : "not ok 75\n") ; + print(scalar $YY->get_dup('Smith') == 1 ? "ok 76\n" : "not ok 76\n") ; + print(scalar $YY->get_dup('Wall') == 3 ? "ok 77\n" : "not ok 77\n") ; + + # now in list context + my @unknown = $YY->get_dup('Unknown') ; + print( "@unknown" eq "" ? "ok 78\n" : "not ok 78\n") ; + + my @smith = $YY->get_dup('Smith') ; + print( "@smith" eq "John" ? "ok 79\n" : "not ok 79\n") ; + + my @wall = $YY->get_dup('Wall') ; + my %wall ; + @wall{@wall} = @wall ; + print( (@wall == 3 && $wall{'Larry'} && $wall{'Stone'} && $wall{'Brick'}) ? "ok 80\n" : "not ok 80\n") ; + + # hash + my %unknown = $YY->get_dup('Unknown', 1) ; + print( keys %unknown == 0 ? "ok 81\n" : "not ok 81\n") ; + + my %smith = $YY->get_dup('Smith', 1) ; + print( (keys %smith == 1 && $smith{'John'}) ? "ok 82\n" : "not ok 82\n") ; + + my %wall = $YY->get_dup('Wall', 1) ; + print( (keys %wall == 3 && $wall{'Larry'} && $wall{'Stone'} && $wall{'Brick'}) ? "ok 83\n" : "not ok 83\n") ; + + undef $YY ; + untie %hh ; + unlink $Dfile; + + # test multiple callbacks $Dfile1 = "btree1" ; $Dfile2 = "btree2" ; *************** *** 392,400 **** 1 ; } ! print ( ArrayCompare (\@srt_1, [keys %h]) ? "ok 74\n" : "not ok 74\n") ; ! print ( ArrayCompare (\@srt_2, [keys %g]) ? "ok 75\n" : "not ok 75\n") ; ! print ( ArrayCompare (\@srt_3, [keys %k]) ? "ok 76\n" : "not ok 76\n") ; untie %h ; untie %g ; --- 437,445 ---- 1 ; } ! print ( ArrayCompare (\@srt_1, [keys %h]) ? "ok 84\n" : "not ok 84\n") ; ! print ( ArrayCompare (\@srt_2, [keys %g]) ? "ok 85\n" : "not ok 85\n") ; ! print ( ArrayCompare (\@srt_3, [keys %k]) ? "ok 86\n" : "not ok 86\n") ; untie %h ; untie %g ; #~ Updated as part of DB_File update diff -Pcr perl5_003/t/lib/db-hash.t perl5_003_01/t/lib/db-hash.t *** perl5_003/t/lib/db-hash.t Tue Oct 18 12:44:07 1994 --- perl5_003_01/t/lib/db-hash.t Fri Jul 5 18:45:41 1996 *************** *** 14,27 **** print "1..43\n"; ! $Dfile = "Op.db-hash"; unlink $Dfile; umask(0); # Check the interface to HASHINFO ! $dbh = TIEHASH DB_File::HASHINFO ; print (($dbh->{bsize} == undef) ? "ok 1\n" : "not ok 1\n") ; print (($dbh->{ffactor} == undef) ? "ok 2\n" : "not ok 2\n") ; print (($dbh->{nelem} == undef) ? "ok 3\n" : "not ok 3\n") ; --- 14,28 ---- print "1..43\n"; ! $Dfile = "dbhash.tmp"; unlink $Dfile; umask(0); # Check the interface to HASHINFO ! #$dbh = TIEHASH DB_File::HASHINFO ; ! $dbh = new DB_File::HASHINFO ; print (($dbh->{bsize} == undef) ? "ok 1\n" : "not ok 1\n") ; print (($dbh->{ffactor} == undef) ? "ok 2\n" : "not ok 2\n") ; print (($dbh->{nelem} == undef) ? "ok 3\n" : "not ok 3\n") ; *************** *** 49,57 **** # Check that an invalid entry is caught both for store & fetch eval '$dbh->{fred} = 1234' ; ! print ($@ eq '' ? "ok 13\n" : "not ok 13\n") ; eval '$q = $dbh->{fred}' ; ! print ($@ eq '' ? "ok 14\n" : "not ok 14\n") ; # Now check the interface to HASH --- 50,58 ---- # Check that an invalid entry is caught both for store & fetch eval '$dbh->{fred} = 1234' ; ! print ($@ =~ /^DB_File::HASHINFO::STORE - Unknown element 'fred' at/ ? "ok 13\n" : "not ok 13\n") ; eval '$q = $dbh->{fred}' ; ! print ($@ =~ /^DB_File::HASHINFO::FETCH - Unknown element 'fred' at/ ? "ok 14\n" : "not ok 14\n") ; # Now check the interface to HASH *************** *** 69,75 **** $h{'goner1'} = 'snork'; $h{'abc'} = 'ABC'; ! print ($h{'abc'} == 'ABC' ? "ok 18\n" : "not ok 18\n") ; print (defined $h{'jimmy'} ? "not ok 19\n" : "ok 19\n"); $h{'def'} = 'DEF'; --- 70,76 ---- $h{'goner1'} = 'snork'; $h{'abc'} = 'ABC'; ! print ($h{'abc'} eq 'ABC' ? "ok 18\n" : "not ok 18\n") ; print (defined $h{'jimmy'} ? "not ok 19\n" : "ok 19\n"); $h{'def'} = 'DEF'; *************** *** 135,141 **** if ($#keys == 29 && $#values == 29) {print "ok 21\n";} else {print "not ok 21\n";} ! while (($key,$value) = each(h)) { if ($key eq $keys[$i] && $value eq $values[$i] && $key gt $value) { $key =~ y/a-z/A-Z/; $i++ if $key eq $value; --- 136,142 ---- if ($#keys == 29 && $#values == 29) {print "ok 21\n";} else {print "not ok 21\n";} ! while (($key,$value) = each(%h)) { if ($key eq $keys[$i] && $value eq $values[$i] && $key gt $value) { $key =~ y/a-z/A-Z/; $i++ if $key eq $value; *************** *** 144,150 **** if ($i == 30) {print "ok 22\n";} else {print "not ok 22\n";} ! @keys = ('blurfl', keys(h), 'dyick'); if ($#keys == 31) {print "ok 23\n";} else {print "not ok 23\n";} $h{'foo'} = ''; --- 145,151 ---- if ($i == 30) {print "ok 22\n";} else {print "not ok 22\n";} ! @keys = ('blurfl', keys(%h), 'dyick'); if ($#keys == 31) {print "ok 23\n";} else {print "not ok 23\n";} $h{'foo'} = ''; #~ Updated as part of DB_File update diff -Pcr perl5_003/t/lib/db-recno.t perl5_003_01/t/lib/db-recno.t *** perl5_003/t/lib/db-recno.t Tue Oct 18 12:44:09 1994 --- perl5_003_01/t/lib/db-recno.t Fri Jul 5 18:45:43 1996 *************** *** 11,34 **** use DB_File; use Fcntl; ! print "1..30\n"; ! $Dfile = "Op.db-recno"; ! unlink $Dfile; umask(0); # Check the interface to RECNOINFO ! $dbh = TIEHASH DB_File::RECNOINFO ; ! print (($dbh->{bval} == undef) ? "ok 1\n" : "not ok 1\n") ; ! print (($dbh->{cachesize} == undef) ? "ok 2\n" : "not ok 2\n") ; ! print (($dbh->{psize} == undef) ? "ok 3\n" : "not ok 3\n") ; ! print (($dbh->{flags} == undef) ? "ok 4\n" : "not ok 4\n") ; ! print (($dbh->{lorder} == undef) ? "ok 5\n" : "not ok 5\n") ; ! print (($dbh->{reclen} == undef) ? "ok 6\n" : "not ok 6\n") ; ! print (($dbh->{bfname} == undef) ? "ok 7\n" : "not ok 7\n") ; $dbh->{bval} = 3000 ; print ($dbh->{bval} == 3000 ? "ok 8\n" : "not ok 8\n") ; --- 11,45 ---- use DB_File; use Fcntl; + use strict ; + use vars qw($dbh $Dfile) ; ! sub ok ! { ! my $no = shift ; ! my $result = shift ; ! ! print "not " unless $result ; ! print "ok $no\n" ; ! } ! print "1..35\n"; ! ! my $Dfile = "recno.tmp"; ! unlink $Dfile ; umask(0); # Check the interface to RECNOINFO ! my $dbh = new DB_File::RECNOINFO ; ! ok(1, $dbh->{bval} == undef ) ; ! ok(2, $dbh->{cachesize} == undef) ; ! ok(3, $dbh->{psize} == undef) ; ! ok(4, $dbh->{flags} == undef) ; ! ok(5, $dbh->{lorder} == undef); ! ok(6, $dbh->{reclen} == undef); ! ok(7, $dbh->{bfname} eq undef); $dbh->{bval} = 3000 ; print ($dbh->{bval} == 3000 ? "ok 8\n" : "not ok 8\n") ; *************** *** 54,80 **** # Check that an invalid entry is caught both for store & fetch eval '$dbh->{fred} = 1234' ; ! print ($@ eq '' ? "ok 15\n" : "not ok 15\n") ; ! eval '$q = $dbh->{fred}' ; ! print ($@ eq '' ? "ok 16\n" : "not ok 16\n") ; # Now check the interface to RECNOINFO ! print (($X = tie(@h, DB_File,$Dfile, O_RDWR|O_CREAT, 0640, $DB_RECNO )) ? "ok 17\n" : "not ok 17"); ! ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime, ! $blksize,$blocks) = stat($Dfile); ! print (($mode & 0777) == 0640 ? "ok 18\n" : "not ok 18\n"); ! #$l = @h ; ! $l = $X->length ; print (!$l ? "ok 19\n" : "not ok 19\n"); ! @data = qw( a b c d ever f g h i j k longername m n o p) ; $h[0] = shift @data ; print ($h[0] eq 'a' ? "ok 20\n" : "not ok 20\n") ; foreach (@data) { $h[++$i] = $_ } --- 65,93 ---- # Check that an invalid entry is caught both for store & fetch eval '$dbh->{fred} = 1234' ; ! print ($@ =~ /^DB_File::RECNOINFO::STORE - Unknown element 'fred' at/ ? "ok 15\n" : "not ok 15\n") ; ! eval 'my $q = $dbh->{fred}' ; ! print ($@ =~ /^DB_File::RECNOINFO::FETCH - Unknown element 'fred' at/ ? "ok 16\n" : "not ok 16\n") ; # Now check the interface to RECNOINFO ! my $X ; ! my @h ; ! ok(17, $X = tie @h, 'DB_File', $Dfile, O_RDWR|O_CREAT, 0640, $DB_RECNO ) ; ! #print (($X = tie(%h, DB_File,$Dfile, O_RDWR|O_CREAT, 0640, $DB_BTREE )) ? "ok 19\n" : "not ok 19"); ! ok(18, ( (stat($Dfile))[2] & 0777) == 0640) ; ! #my $l = @h ; ! my $l = $X->length ; print (!$l ? "ok 19\n" : "not ok 19\n"); ! my @data = qw( a b c d ever f g h i j k longername m n o p) ; $h[0] = shift @data ; print ($h[0] eq 'a' ? "ok 20\n" : "not ok 20\n") ; + my $ i; foreach (@data) { $h[++$i] = $_ } *************** *** 91,97 **** print ($h[3] eq 'replaced' ? "ok 24\n" : "not ok 24\n"); #PUSH ! @push_data = qw(added to the end) ; #push (@h, @push_data) ; $X->push(@push_data) ; push (@data, @push_data) ; --- 104,110 ---- print ($h[3] eq 'replaced' ? "ok 24\n" : "not ok 24\n"); #PUSH ! my @push_data = qw(added to the end) ; #push (@h, @push_data) ; $X->push(@push_data) ; push (@data, @push_data) ; *************** *** 100,106 **** # POP pop (@data) ; #$value = pop(@h) ; ! $value = $X->pop ; print ($value eq 'end' ? "not ok 26\n" : "ok 26\n"); # SHIFT --- 113,119 ---- # POP pop (@data) ; #$value = pop(@h) ; ! my $value = $X->pop ; print ($value eq 'end' ? "not ok 26\n" : "ok 26\n"); # SHIFT *************** *** 114,120 **** $X->unshift ; print ($X->length == @data ? "ok 28\n" : "not ok 28\n") ; ! @new_data = qw(add this to the start of the array) ; #unshift @h, @new_data ; $X->unshift (@new_data) ; unshift (@data, @new_data) ; --- 127,133 ---- $X->unshift ; print ($X->length == @data ? "ok 28\n" : "not ok 28\n") ; ! my @new_data = qw(add this to the start of the array) ; #unshift @h, @new_data ; $X->unshift (@new_data) ; unshift (@data, @new_data) ; *************** *** 124,136 **** # Now both arrays should be identical ! $ok = 1 ; ! $j = 0 ; foreach (@data) { $ok = 0, last if $_ ne $h[$j ++] ; } print ($ok ? "ok 30\n" : "not ok 30\n") ; # IMPORTANT - $X must be undefined before the untie otherwise the # underlying DB close routine will not get called. --- 137,164 ---- # Now both arrays should be identical ! my $ok = 1 ; ! my $j = 0 ; foreach (@data) { $ok = 0, last if $_ ne $h[$j ++] ; } print ($ok ? "ok 30\n" : "not ok 30\n") ; + + # Neagtive subscripts + + # get the last element of the array + print($h[-1] eq $data[-1] ? "ok 31\n" : "not ok 31\n") ; + print($h[-1] eq $h[$X->length -1] ? "ok 32\n" : "not ok 32\n") ; + + # get the first element using a negative subscript + eval '$h[ - ( $X->length)] = "abcd"' ; + print ($@ eq "" ? "ok 33\n" : "not ok 33\n") ; + print ($h[0] eq "abcd" ? "ok 34\n" : "not ok 34\n") ; + + # now try to read before the start of the array + eval '$h[ - (1 + $X->length)] = 1234' ; + print ($@ =~ '^Modification of non-creatable array value attempted' ? "ok 35\n" : "not ok 35\n") ; # IMPORTANT - $X must be undefined before the untie otherwise the # underlying DB close routine will not get called. #~ Check for readdir() directly, rather than more general POSIX test #~ sort results of glob expansion for better alignment with readdir results diff -Pcr perl5_003/t/lib/dirhand.t perl5_003_01/t/lib/dirhand.t *** perl5_003/t/lib/dirhand.t Mon Jan 29 18:30:50 1996 --- perl5_003_01/t/lib/dirhand.t Tue Jul 23 07:11:25 1996 *************** *** 4,10 **** chdir 't' if -d 't'; @INC = '../lib'; require Config; import Config; ! if ($Config{'extensions'} !~ /\bPOSIX\b/) { print "1..0\n"; exit 0; } --- 4,10 ---- chdir 't' if -d 't'; @INC = '../lib'; require Config; import Config; ! if (not $Config{'d_readdir'}) { print "1..0\n"; exit 0; } *************** *** 17,23 **** $dot = new DirHandle "."; print defined($dot) ? "ok" : "not ok", " 1\n"; ! @a = <*>; do { $first = $dot->read } while defined($first) && $first =~ /^\./; print +(grep { $_ eq $first } @a) ? "ok" : "not ok", " 2\n"; --- 17,23 ---- $dot = new DirHandle "."; print defined($dot) ? "ok" : "not ok", " 1\n"; ! @a = sort <*>; do { $first = $dot->read } while defined($first) && $first =~ /^\./; print +(grep { $_ eq $first } @a) ? "ok" : "not ok", " 2\n"; #~ Can't call FileHandle methods on unblessed file handle, since #~ IO::Handle is now the default class diff -Pcr perl5_003/t/lib/filehand.t perl5_003_01/t/lib/filehand.t *** perl5_003/t/lib/filehand.t Mon Mar 25 01:05:37 1996 --- perl5_003_01/t/lib/filehand.t Thu Jul 18 14:17:40 1996 *************** *** 14,20 **** use strict subs; $mystdout = new_from_fd FileHandle 1,"w"; ! autoflush STDOUT; autoflush $mystdout; print "1..4\n"; --- 14,20 ---- use strict subs; $mystdout = new_from_fd FileHandle 1,"w"; ! $| = 1; autoflush $mystdout; print "1..4\n"; *************** *** 24,35 **** $buffer = <$fh>; print $buffer eq "#!./perl\n" ? "ok 3\n" : "not ok 3\n"; ! if ($^O eq 'VMS') { ! ungetc $fh 65; ! CORE::read($fh, $buf,1); ! } ! else { ! ungetc STDIN 65; ! CORE::read(STDIN, $buf,1); ! } print $buf eq 'A' ? "ok 4\n" : "not ok 4\n"; --- 24,29 ---- $buffer = <$fh>; print $buffer eq "#!./perl\n" ? "ok 3\n" : "not ok 3\n"; ! ungetc $fh 65; ! CORE::read($fh, $buf,1); print $buf eq 'A' ? "ok 4\n" : "not ok 4\n"; #~ Add tests for new IO extension diff -Pcr perl5_003/t/lib/io_dup.t perl5_003_01/t/lib/io_dup.t *** perl5_003/t/lib/io_dup.t Wed Dec 31 19:00:00 1969 --- perl5_003_01/t/lib/io_dup.t Wed Jul 10 14:01:25 1996 *************** *** 0 **** --- 1,45 ---- + #!./perl + + BEGIN { + @INC = '../lib'; + require Config; import Config; + if ($Config{'extensions'} !~ /\bIO\b/ && $^O ne 'VMS') { + print "1..0\n"; + exit 0; + } + } + + use IO::Handle; + use IO::File; + + select(STDERR); $| = 1; + select(STDOUT); $| = 1; + + print "1..6\n"; + + print "ok 1\n"; + + $dupout = IO::Handle->new->fdopen( \*STDOUT ,"w"); + $duperr = IO::Handle->new->fdopen( \*STDERR ,"w"); + + $stdout = \*STDOUT; bless $stdout, "IO::File"; # "IO::Handle"; + $stderr = \*STDERR; bless $stderr, "IO::Handle"; + + $stdout->open( "Io.dup","w") || die "Can't open stdout"; + $stderr->fdopen($stdout,"w"); + + print $stdout "ok 2\n"; + print $stderr "ok 3\n"; + system 'echo ok 4'; + system 'echo ok 5 1>&2'; + + $stderr->close; + $stdout->close; + + $stdout->fdopen($dupout,"w"); + $stderr->fdopen($duperr,"w"); + + system 'cat Io.dup'; + unlink 'Io.dup'; + + print STDOUT "ok 6\n"; #~ Add tests for new IO extension diff -Pcr perl5_003/t/lib/io_pipe.t perl5_003_01/t/lib/io_pipe.t *** perl5_003/t/lib/io_pipe.t Wed Dec 31 19:00:00 1969 --- perl5_003_01/t/lib/io_pipe.t Wed Jul 10 14:01:46 1996 *************** *** 0 **** --- 1,82 ---- + #!./perl + + BEGIN { + @INC = '../lib'; + require Config; import Config; + if ($Config{'extensions'} !~ /\bIO\b/ && $^O ne 'VMS') { + print "1..0\n"; + exit 0; + } + } + + use IO::Pipe; + + $| = 1; + print "1..6\n"; + + $pipe = new IO::Pipe; + + $pid = fork(); + + if($pid) + { + $pipe->writer; + print $pipe "Xk 1\n"; + print $pipe "oY 2\n"; + $pipe->close; + wait; + } + elsif(defined $pid) + { + $pipe->reader; + $stdin = bless \*STDIN, "IO::Handle"; + $stdin->fdopen($pipe,"r"); + exec 'tr', 'YX', 'ko'; + } + else + { + die; + } + + $pipe = new IO::Pipe; + $pid = fork(); + + if($pid) + { + $pipe->reader; + while(<$pipe>) { + s/^not //; + print; + } + $pipe->close; + wait; + } + elsif(defined $pid) + { + $pipe->writer; + + $stdout = bless \*STDOUT, "IO::Handle"; + $stdout->fdopen($pipe,"w"); + print STDOUT "not ok 3\n"; + exec 'echo', 'not ok 4'; + } + else + { + die; + } + + $pipe = new IO::Pipe; + $pipe->writer; + + $SIG{'PIPE'} = 'broken_pipe'; + + sub broken_pipe { + print "ok 5\n"; + } + + print $pipe "not ok 5\n"; + $pipe->close; + + + print "ok 6\n"; + #~ Add tests for new IO extension diff -Pcr perl5_003/t/lib/io_sock.t perl5_003_01/t/lib/io_sock.t *** perl5_003/t/lib/io_sock.t Wed Dec 31 19:00:00 1969 --- perl5_003_01/t/lib/io_sock.t Wed Jul 10 14:04:02 1996 *************** *** 0 **** --- 1,75 ---- + #!./perl + + BEGIN { + chdir 't' if -d 't'; + @INC = '../lib' if -d '../lib'; + require Config; import Config; + if ( ($Config{'extensions'} !~ /\bSocket\b/ || + $Config{'extensions'} !~ /\bIO\b/) && + !(($^O eq 'VMS') && $Config{d_socket})) { + print "1..0\n"; + exit 0; + } + } + + $| = 1; + print "1..5\n"; + + use IO::Socket; + + $port = 4002 + int(rand(time) & 0xff); + + $pid = fork(); + + if($pid) { + + $listen = IO::Socket::INET->new(Listen => 2, + Proto => 'tcp', + LocalPort => $port + ) or die "$!"; + + print "ok 1\n"; + + # Wake out child + kill(ALRM => $pid); + + $sock = $listen->accept(); + print "ok 2\n"; + + $sock->autoflush(1); + print $sock->getline(); + + print $sock "ok 4\n"; + + $sock->close; + + waitpid($pid,0); + + print "ok 5\n"; + } elsif(defined $pid) { + + # Wait for a small pause, so that we can ensure the listen socket is setup + # the parent will awake us with a SIGALRM + + $SIG{ALRM} = sub {}; + sleep(10); + + $sock = IO::Socket::INET->new(PeerPort => $port, + Proto => 'tcp', + PeerAddr => 'localhost' + ) or die "$!"; + + $sock->autoflush(1); + print $sock "ok 3\n"; + print $sock->getline(); + $sock->close; + exit; + } else { + die; + } + + + + + + #~ Add tests for new IO extension diff -Pcr perl5_003/t/lib/io_tell.t perl5_003_01/t/lib/io_tell.t *** perl5_003/t/lib/io_tell.t Wed Dec 31 19:00:00 1969 --- perl5_003_01/t/lib/io_tell.t Thu Jul 18 13:35:35 1996 *************** *** 0 **** --- 1,54 ---- + #!./perl + + # $RCSfile: tell.t,v $$Revision: 1.1 $$Date: 1996/05/01 10:52:47 $ + + BEGIN { + chdir 't' if -d 't'; + @INC = '../lib' if -d '../lib'; + require Config; import Config; + if ($Config{'extensions'} !~ /\bIO\b/ && !($^O eq 'VMS')) { + print "1..0\n"; + exit 0; + } + } + + print "1..13\n"; + + use IO::File; + + $tst = IO::File->new("TEST","r") || die("Can't open TEST"); + + if ($tst->eof) { print "not ok 1\n"; } else { print "ok 1\n"; } + + $firstline = <$tst>; + $secondpos = tell; + + $x = 0; + while (<$tst>) { + if (eof) {$x++;} + } + if ($x == 1) { print "ok 2\n"; } else { print "not ok 2\n"; } + + $lastpos = tell; + + unless (eof) { print "not ok 3\n"; } else { print "ok 3\n"; } + + if ($tst->seek(0,0)) { print "ok 4\n"; } else { print "not ok 4\n"; } + + if (eof) { print "not ok 5\n"; } else { print "ok 5\n"; } + + if ($firstline eq <$tst>) { print "ok 6\n"; } else { print "not ok 6\n"; } + + if ($secondpos == tell) { print "ok 7\n"; } else { print "not ok 7\n"; } + + if ($tst->seek(0,1)) { print "ok 8\n"; } else { print "not ok 8\n"; } + + if ($tst->eof) { print "not ok 9\n"; } else { print "ok 9\n"; } + + if ($secondpos == tell) { print "ok 10\n"; } else { print "not ok 10\n"; } + + if ($tst->seek(0,2)) { print "ok 11\n"; } else { print "not ok 11\n"; } + + if ($lastpos == $tst->tell) { print "ok 12\n"; } else { print "not ok 12\n"; } + + unless (eof) { print "not ok 13\n"; } else { print "ok 13\n"; } #~ Add tests for new IO extension diff -Pcr perl5_003/t/lib/io_udp.t perl5_003_01/t/lib/io_udp.t *** perl5_003/t/lib/io_udp.t Wed Dec 31 19:00:00 1969 --- perl5_003_01/t/lib/io_udp.t Tue Jul 23 07:13:12 1996 *************** *** 0 **** --- 1,31 ---- + #!./perl + + BEGIN { + chdir 't' if -d 't'; + @INC = '../lib' if -d '../lib'; + require Config; import Config; + if ( ($Config{'extensions'} !~ /\bSocket\b/ || + $Config{'extensions'} !~ /\bIO\b/) && + !(($^O eq 'VMS') && $Config{d_socket})) { + print "1..0\n"; + exit 0; + } + } + + $| = 1; + print "1..3\n"; + + use Socket; + use IO::Socket qw(AF_INET SOCK_DGRAM INADDR_ANY); + + $udpa = IO::Socket::INET->new(Proto => 'udp', Addr => 'localhost'); + $udpb = IO::Socket::INET->new(Proto => 'udp', Addr => 'localhost'); + + print "ok 1\n"; + + $udpa->send("ok 2\n",0,$udpb->sockname); + $rem = $udpb->recv($buf="",5); + print $buf; + $udpb->send("ok 3\n"); + $udpa->recv($buf="",5); + print $buf; #~ Add tests for new IO extension diff -Pcr perl5_003/t/lib/io_xs.t perl5_003_01/t/lib/io_xs.t *** perl5_003/t/lib/io_xs.t Wed Dec 31 19:00:00 1969 --- perl5_003_01/t/lib/io_xs.t Thu Jul 18 13:35:12 1996 *************** *** 0 **** --- 1,23 ---- + #!./perl + $| = 1; + + BEGIN { + chdir 't' if -d 't'; + @INC = '../lib' if -d '../lib'; + require Config; import Config; + if ($Config{'extensions'} !~ /\bIO\b/ && !($^O eq 'VMS')) { + print "1..0\n"; + exit 0; + } + } + + use IO::File; + use IO::Seekable; + + print "1..2\n"; + use IO::File; + $x = new_tmpfile IO::File or print "not "; + print "ok 1\n"; + print $x "ok 2\n"; + $x->seek(0,SEEK_SET); + print <$x>; #~ Add tests for new Opcode extension diff -Pcr perl5_003/t/lib/opcode.t perl5_003_01/t/lib/opcode.t *** perl5_003/t/lib/opcode.t Wed Dec 31 19:00:00 1969 --- perl5_003_01/t/lib/opcode.t Thu Jul 18 14:24:58 1996 *************** *** 0 **** --- 1,115 ---- + #!./perl -w + + $|=1; + + BEGIN { + chdir 't' if -d 't'; + @INC = '../lib'; + require Config; import Config; + if ($Config{'extensions'} !~ /\bOpcode\b/ && $Config{'osname'} ne 'VMS') { + print "1..0\n"; + exit 0; + } + } + + use Opcode qw( + opcodes opdesc opmask verify_opset + opset opset_to_ops opset_to_hex invert_opset + opmask_add full_opset empty_opset define_optag + ); + + use strict; + + my $t = 1; + my $last_test; # initalised at end + print "1..$last_test\n"; + + my($s1, $s2, $s3); + my(@o1, @o2, @o3); + + # --- opset_to_ops and opset + + my @empty_l = opset_to_ops(empty_opset); + print @empty_l == 0 ? "ok $t\n" : "not ok $t\n"; $t++; + + my @full_l1 = opset_to_ops(full_opset); + print @full_l1 == opcodes() ? "ok $t\n" : "not ok $t\n"; $t++; + my @full_l2 = @full_l1; # = opcodes(); # XXX to be fixed + print "@full_l1" eq "@full_l2" ? "ok $t\n" : "not ok $t\n"; $t++; + + @empty_l = opset_to_ops(opset(':none')); + print @empty_l == 0 ? "ok $t\n" : "not ok $t\n"; $t++; + + my @full_l3 = opset_to_ops(opset(':all')); + print @full_l1 == @full_l3 ? "ok $t\n" : "not ok $t\n"; $t++; + print "@full_l1" eq "@full_l3" ? "ok $t\n" : "not ok $t\n"; $t++; + + die $t unless $t == 7; + $s1 = opset( 'padsv'); + $s2 = opset($s1, 'padav'); + $s3 = opset($s2, '!padav'); + print $s1 eq $s2 ? "not ok $t\n" : "ok $t\n"; ++$t; + print $s1 eq $s3 ? "ok $t\n" : "not ok $t\n"; ++$t; + + # --- define_optag + + print eval { opset(':_tst_') } ? "not ok $t\n" : "ok $t\n"; ++$t; + define_optag(":_tst_", opset(qw(padsv padav padhv))); + print eval { opset(':_tst_') } ? "ok $t\n" : "not ok $t\n"; ++$t; + + # --- opdesc and opcodes + + die $t unless $t == 11; + print opdesc("gv") eq "glob value" ? "ok $t\n" : "not ok $t\n"; $t++; + my @desc = opdesc(':_tst_','stub'); + print "@desc" eq "private variable private array private hash stub" + ? "ok $t\n" : "not ok $t\n#@desc\n"; $t++; + print opcodes() ? "ok $t\n" : "not ok $t\n"; $t++; + print "ok $t\n"; ++$t; + + # --- invert_opset + + $s1 = opset(qw(fileno padsv padav)); + @o2 = opset_to_ops(invert_opset($s1)); + print @o2 == opcodes-3 ? "ok $t\n" : "not ok $t\n"; $t++; + + # --- opmask + + die $t unless $t == 16; + print opmask() eq empty_opset() ? "ok $t\n" : "not ok $t\n"; $t++; # work + print length opmask() == int(opcodes()/8)+1 ? "ok $t\n" : "not ok $t\n"; $t++; + + # --- verify_opset + + print verify_opset($s1) && !verify_opset(42) ? "ok $t\n":"not ok $t\n"; $t++; + + # --- opmask_add + + opmask_add(opset(qw(fileno))); # add to global op_mask + print eval 'fileno STDOUT' ? "not ok $t\n" : "ok $t\n"; $t++; # fail + print $@ =~ /fileno trapped/ ? "ok $t\n" : "not ok $t\n# $@\n"; $t++; + + # --- check use of bit vector ops on opsets + + $s1 = opset('padsv'); + $s2 = opset('padav'); + $s3 = opset('padsv', 'padav', 'padhv'); + + # Non-negated + print (($s1 | $s2) eq opset($s1,$s2) ? "ok $t\n":"not ok $t\n"); $t++; + print (($s2 & $s3) eq opset($s2) ? "ok $t\n":"not ok $t\n"); $t++; + print (($s2 ^ $s3) eq opset('padsv','padhv') ? "ok $t\n":"not ok $t\n"); $t++; + + # Negated, e.g., with possible extra bits in last byte beyond last op bit. + # The extra bits mean we can't just say ~mask eq invert_opset(mask). + + @o1 = opset_to_ops( ~ $s3); + @o2 = opset_to_ops(invert_opset $s3); + print "@o1" eq "@o2" ? "ok $t\n":"not ok $t\n"; $t++; + + # --- finally, check some opname assertions + + foreach(@full_l1) { die "bad opname: $_" if /\W/ or /^\d/ } + + print "ok $last_test\n"; + BEGIN { $last_test = 25 } #~ Add tests for new Opcode extension diff -Pcr perl5_003/t/lib/ops.t perl5_003_01/t/lib/ops.t *** perl5_003/t/lib/ops.t Wed Dec 31 19:00:00 1969 --- perl5_003_01/t/lib/ops.t Thu Jul 18 14:25:12 1996 *************** *** 0 **** --- 1,29 ---- + #!./perl + + BEGIN { + chdir 't' if -d 't'; + @INC = '../lib'; + require Config; import Config; + if ($Config{'extensions'} !~ /\bOpcode\b/ && $Config{'osname'} ne 'VMS') { + print "1..0\n"; + exit 0; + } + } + + print "1..2\n"; + + eval <<'EOP'; + no ops 'fileno'; # equiv to "perl -M-ops=fileno" + $a = fileno STDIN; + EOP + + print $@ =~ /trapped/ ? "ok 1\n" : "not ok 1\n# $@\n"; + + eval <<'EOP'; + use ops ':default'; # equiv to "perl -M(as above) -Mops=:default" + eval 1; + EOP + + print $@ =~ /trapped/ ? "ok 2\n" : "not ok 2\n# $@\n"; + + 1; #~ Add tests for new Opcode extension diff -Pcr perl5_003/t/lib/safe1.t perl5_003_01/t/lib/safe1.t *** perl5_003/t/lib/safe1.t Wed Dec 31 19:00:00 1969 --- perl5_003_01/t/lib/safe1.t Wed Jul 10 14:06:16 1996 *************** *** 0 **** --- 1,68 ---- + #!./perl -w + $|=1; + BEGIN { + chdir 't' if -d 't'; + @INC = '../lib'; + require Config; import Config; + if ($Config{'extensions'} !~ /\bOpcode\b/ && $Config{'osname'} ne 'VMS') { + print "1..0\n"; + exit 0; + } + } + + # Tests Todo: + # 'main' as root + + package test; # test from somewhere other than main + + use vars qw($bar); + + use Opcode 1.00, qw(opdesc opset opset_to_ops opset_to_hex + opmask_add full_opset empty_opset opcodes opmask define_optag); + + use Safe 1.00; + + my $last_test; # initalised at end + print "1..$last_test\n"; + + my $t = 1; + my $cpt; + # create and destroy some automatic Safe compartments first + $cpt = new Safe or die; + $cpt = new Safe or die; + $cpt = new Safe or die; + + $cpt = new Safe "Root" or die; + + foreach(1..3) { + $foo = 42; + + $cpt->share(qw($foo)); + + print ${$cpt->varglob('foo')} == 42 ? "ok $t\n" : "not ok $t\n"; $t++; + + ${$cpt->varglob('foo')} = 9; + + print $foo == 9 ? "ok $t\n" : "not ok $t\n"; $t++; + + print $cpt->reval('$foo') == 9 ? "ok $t\n" : "not ok $t\n"; $t++; + # check 'main' has been changed: + print $cpt->reval('$::foo') == 9 ? "ok $t\n" : "not ok $t\n"; $t++; + print $cpt->reval('$main::foo') == 9 ? "ok $t\n" : "not ok $t\n"; $t++; + # check we can't see our test package: + print $cpt->reval('$test::foo') ? "not ok $t\n" : "ok $t\n"; $t++; + print $cpt->reval('${"test::foo"}') ? "not ok $t\n" : "ok $t\n"; $t++; + + $cpt->erase; # erase the compartment, e.g., delete all variables + + print $cpt->reval('$foo') ? "not ok $t\n" : "ok $t\n"; $t++; + + # Note that we *must* use $cpt->varglob here because if we used + # $Root::foo etc we would still see the original values! + # This seems to be because the compiler has created an extra ref. + + print ${$cpt->varglob('foo')} ? "not ok $t\n" : "ok $t\n"; $t++; + } + + print "ok $last_test\n"; + BEGIN { $last_test = 28 } #~ Add tests for new Opcode extension diff -Pcr perl5_003/t/lib/safe2.t perl5_003_01/t/lib/safe2.t *** perl5_003/t/lib/safe2.t Wed Dec 31 19:00:00 1969 --- perl5_003_01/t/lib/safe2.t Thu Jul 18 14:32:29 1996 *************** *** 0 **** --- 1,140 ---- + #!./perl -w + $|=1; + BEGIN { + chdir 't' if -d 't'; + @INC = '../lib'; + require Config; import Config; + if ($Config{'extensions'} !~ /\bOpcode\b/ && $Config{'osname'} ne 'VMS') { + print "1..0\n"; + exit 0; + } + } + + # Tests Todo: + # 'main' as root + + use vars qw($bar); + + use Opcode 1.00, qw(opdesc opset opset_to_ops opset_to_hex + opmask_add full_opset empty_opset opcodes opmask define_optag); + + use Safe 1.00; + + my $last_test; # initalised at end + print "1..$last_test\n"; + + # Set up a package namespace of things to be visible to the unsafe code + $Root::foo = "visible"; + $bar = "invisible"; + + # Stop perl from moaning about identifies which are apparently only used once + $Root::foo .= ""; + + my $cpt; + # create and destroy a couple of automatic Safe compartments first + $cpt = new Safe or die; + $cpt = new Safe or die; + + $cpt = new Safe "Root"; + + $cpt->reval(q{ system("echo not ok 1"); }); + if ($@ =~ /^system trapped by operation mask/) { + print "ok 1\n"; + } else { + print "#$@" if $@; + print "not ok 1\n"; + } + + $cpt->reval(q{ + print $foo eq 'visible' ? "ok 2\n" : "not ok 2\n"; + print $main::foo eq 'visible' ? "ok 3\n" : "not ok 3\n"; + print defined($bar) ? "not ok 4\n" : "ok 4\n"; + print defined($::bar) ? "not ok 5\n" : "ok 5\n"; + print defined($main::bar) ? "not ok 6\n" : "ok 6\n"; + }); + print $@ ? "not ok 7\n#$@" : "ok 7\n"; + + $foo = "ok 8\n"; + %bar = (key => "ok 9\n"); + @baz = (); push(@baz, "o", "10"); $" = 'k '; + $glob = "ok 11\n"; + @glob = qw(not ok 16); + + sub sayok { print "ok @_\n" } + + $cpt->share(qw($foo %bar @baz *glob sayok $")); + + $cpt->reval(q{ + package other; + sub other_sayok { print "ok @_\n" } + package main; + print $foo ? $foo : "not ok 8\n"; + print $bar{key} ? $bar{key} : "not ok 9\n"; + (@baz) ? print "@baz\n" : print "not ok 10\n"; + print $glob; + other::other_sayok(12); + $foo =~ s/8/14/; + $bar{new} = "ok 15\n"; + @glob = qw(ok 16); + }); + print $@ ? "not ok 13\n#$@" : "ok 13\n"; + $" = ' '; + print $foo, $bar{new}, "@glob\n"; + + $Root::foo = "not ok 17"; + @{$cpt->varglob('bar')} = qw(not ok 18); + ${$cpt->varglob('foo')} = "ok 17"; + @Root::bar = "ok"; + push(@Root::bar, "18"); # Two steps to prevent "Identifier used only once..." + + print "$Root::foo\n"; + print "@{$cpt->varglob('bar')}\n"; + + use strict; + + print 1 ? "ok 19\n" : "not ok 19\n"; + print 1 ? "ok 20\n" : "not ok 20\n"; + + my $m1 = $cpt->mask; + $cpt->trap("negate"); + my $m2 = $cpt->mask; + my @masked = opset_to_ops($m1); + print $m2 eq opset("negate", @masked) ? "ok 21\n" : "not ok 21\n"; + + print eval { $cpt->mask("a bad mask") } ? "not ok 22\n" : "ok 22\n"; + + print $cpt->reval("2 + 2") == 4 ? "ok 23\n" : "not ok 23\n"; + + $cpt->mask(empty_opset); + my $t_scalar = $cpt->reval('print wantarray ? "not ok 24\n" : "ok 24\n"'); + print $cpt->reval('@ary=(6,7,8);@ary') == 3 ? "ok 25\n" : "not ok 25\n"; + my @t_array = $cpt->reval('print wantarray ? "ok 26\n" : "not ok 26\n"; (2,3,4)'); + print $t_array[2] == 4 ? "ok 27\n" : "not ok 27\n"; + + my $t_scalar2 = $cpt->reval('die "foo bar"; 1'); + print defined $t_scalar2 ? "not ok 28\n" : "ok 28\n"; + print $@ =~ /foo bar/ ? "ok 29\n" : "not ok 29\n"; + + # --- rdo + + my $t = 30; + $cpt->rdo('/non/existant/file.name'); + print +(($! =~ /No such file/ || $! =~ /file specification syntax error/) ? + "ok $t\n" : "not ok $t # $!\n"); $t++; + print 1 ? "ok $t\n" : "not ok $t\n#$@/$!\n"; $t++; + + #my $rdo_file = "tmp_rdo.tpl"; + #if (open X,">$rdo_file") { + # print X "999\n"; + # close X; + # $cpt->permit_only('const', 'leaveeval'); + # print $cpt->rdo($rdo_file) == 999 ? "ok $t\n" : "not ok $t\n"; $t++; + # unlink $rdo_file; + #} + #else { + # print "# test $t skipped, can't open file: $!\nok $t\n"; $t++; + #} + + + print "ok $last_test\n"; + BEGIN { $last_test = 32 } #~ Update name of %Config value under VMS diff -Pcr perl5_003/t/lib/socket.t perl5_003_01/t/lib/socket.t *** perl5_003/t/lib/socket.t Mon Mar 25 01:05:40 1996 --- perl5_003_01/t/lib/socket.t Mon Jun 17 19:22:51 1996 *************** *** 5,11 **** @INC = '../lib' if -d '../lib'; require Config; import Config; if ($Config{'extensions'} !~ /\bSocket\b/ && ! !(($^O eq 'VMS') && $Config{d_has_socket})) { print "1..0\n"; exit 0; } --- 5,11 ---- @INC = '../lib' if -d '../lib'; require Config; import Config; if ($Config{'extensions'} !~ /\bSocket\b/ && ! !(($^O eq 'VMS') && $Config{d_socket})) { print "1..0\n"; exit 0; } #~ Added tests for multicharacter record delimiters diff -Pcr perl5_003/t/op/chop.t perl5_003_01/t/op/chop.t *** perl5_003/t/op/chop.t Tue Oct 18 12:44:35 1994 --- perl5_003_01/t/op/chop.t Mon Jun 17 19:37:49 1996 *************** *** 2,8 **** # $RCSfile: chop.t,v $$Revision: 4.1 $$Date: 92/08/07 18:27:40 $ ! print "1..22\n"; # optimized --- 2,8 ---- # $RCSfile: chop.t,v $$Revision: 4.1 $$Date: 92/08/07 18:27:40 $ ! print "1..28\n"; # optimized *************** *** 70,72 **** --- 70,87 ---- $/ = ""; print chomp() == 0 ? "ok 21\n" : "not ok 21\n"; print $_ eq "f" ? "ok 22\n" : "not ok 22\n"; + + $_ = "xx"; + $/ = "xx"; + print chomp() == 2 ? "ok 23\n" : "not ok 23\n"; + print $_ eq "" ? "ok 24\n" : "not ok 24\n"; + + $_ = "axx"; + $/ = "xx"; + print chomp() == 2 ? "ok 25\n" : "not ok 25\n"; + print $_ eq "a" ? "ok 26\n" : "not ok 26\n"; + + $_ = "axx"; + $/ = "yy"; + print chomp() == 0 ? "ok 27\n" : "not ok 27\n"; + print $_ eq "axx" ? "ok 28\n" : "not ok 28\n"; #~ Consider alternate location for system groups command diff -Pcr perl5_003/t/op/groups.t perl5_003_01/t/op/groups.t *** perl5_003/t/op/groups.t Tue Oct 18 12:45:10 1994 --- perl5_003_01/t/op/groups.t Wed May 1 14:55:44 1996 *************** *** 1,6 **** #!./perl ! if (! -x '/usr/ucb/groups') { print "1..0\n"; exit 0; } --- 1,6 ---- #!./perl ! if (! -x ($groups = '/usr/ucb/groups') && ! -x ($groups = '/usr/bin/groups')) { print "1..0\n"; exit 0; } *************** *** 26,32 **** $gr1 = join(' ', sort @gr); ! $gr2 = join(' ', grep(!$basegroup{$_}++, sort split(' ',`/usr/ucb/groups`))); if ($gr1 eq $gr2) { print "ok 1\n"; --- 26,32 ---- $gr1 = join(' ', sort @gr); ! $gr2 = join(' ', grep(!$basegroup{$_}++, sort split(' ',`$groups`))); if ($gr1 eq $gr2) { print "ok 1\n"; #~ Add tests for new strict untie diff -Pcr perl5_003/t/op/tie.t perl5_003_01/t/op/tie.t *** perl5_003/t/op/tie.t Wed Dec 31 19:00:00 1969 --- perl5_003_01/t/op/tie.t Thu Jul 4 09:10:46 1996 *************** *** 0 **** --- 1,144 ---- + #!./perl + + # This test harness will (eventually) test the "tie" functionality + # without the need for a *DBM* implementation. + + # Currently it only tests use strict "untie". + + chdir 't' if -d 't'; + @INC = "../lib"; + $ENV{PERL5LIB} = "../lib"; + + $|=1; + + undef $/; + @prgs = split "\n########\n", ; + print "1..", scalar @prgs, "\n"; + + for (@prgs){ + my($prog,$expected) = split(/\nEXPECT\n/, $_); + eval "$prog" ; + $status = $?; + $results = $@ ; + $results =~ s/\n+$//; + $expected =~ s/\n+$//; + if ( $status or $results !~ /^$expected/){ + print STDERR "STATUS: $status\n"; + print STDERR "PROG: $prog\n"; + print STDERR "EXPECTED:\n$expected\n"; + print STDERR "GOT:\n$results\n"; + print "not "; + } + print "ok ", ++$i, "\n"; + } + + __END__ + + # standard behaviour, without any extra references + use Tie::Hash ; + tie %h, Tie::StdHash; + untie %h; + EXPECT + ######## + + # standard behaviour, with 1 extra reference + use Tie::Hash ; + $a = tie %h, Tie::StdHash; + untie %h; + EXPECT + ######## + + # standard behaviour, with 1 extra reference via tied + use Tie::Hash ; + tie %h, Tie::StdHash; + $a = tied %h; + untie %h; + EXPECT + ######## + + # standard behaviour, with 1 extra reference which is destroyed + use Tie::Hash ; + $a = tie %h, Tie::StdHash; + $a = 0 ; + untie %h; + EXPECT + ######## + + # standard behaviour, with 1 extra reference via tied which is destroyed + use Tie::Hash ; + tie %h, Tie::StdHash; + $a = tied %h; + $a = 0 ; + untie %h; + EXPECT + ######## + + # strict behaviour, without any extra references + use strict 'untie'; + use Tie::Hash ; + tie %h, Tie::StdHash; + untie %h; + EXPECT + ######## + + # strict behaviour, with 1 extra references generating an error + use strict 'untie'; + use Tie::Hash ; + $a = tie %h, Tie::StdHash; + untie %h; + EXPECT + Can't untie: 1 inner references still exist at + ######## + + # strict behaviour, with 1 extra references via tied generating an error + use strict 'untie'; + use Tie::Hash ; + tie %h, Tie::StdHash; + $a = tied %h; + untie %h; + EXPECT + Can't untie: 1 inner references still exist at + ######## + + # strict behaviour, with 1 extra references which are destroyed + use strict 'untie'; + use Tie::Hash ; + $a = tie %h, Tie::StdHash; + $a = 0 ; + untie %h; + EXPECT + ######## + + # strict behaviour, with extra 1 references via tied which are destroyed + use strict 'untie'; + use Tie::Hash ; + tie %h, Tie::StdHash; + $a = tied %h; + $a = 0 ; + untie %h; + EXPECT + ######## + + # strict error behaviour, with 2 extra references + use strict 'untie'; + use Tie::Hash ; + $a = tie %h, Tie::StdHash; + $b = tied %h ; + untie %h; + EXPECT + Can't untie: 2 inner references still exist at + ######## + + # strict behaviour, check scope of strictness. + no strict 'untie'; + use Tie::Hash ; + $A = tie %H, Tie::StdHash; + $C = $B = tied %H ; + { + use strict 'untie'; + use Tie::Hash ; + tie %h, Tie::StdHash; + untie %h; + } + untie %H; + EXPECT #~ Add suport for version check via "use" #~ Add fast symbol lookup support #~ Optimize subs returning constant value to constants #~ Change memory allocation calls to use macros from handy.h #~ Allow \t as well as ' ' between "perl" and switches on #! line #~ Allow leading '_' under strict subs in barewords stringified as hash keys #~ #ifdef out under QNX assertion which gives it trouble diff -Pcr perl5_003/toke.c perl5_003_01/toke.c *** perl5_003/toke.c Mon Mar 25 01:05:42 1996 --- perl5_003_01/toke.c Sun Jul 7 19:02:15 1996 *************** *************** *** 16,21 **** --- 16,22 ---- 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)); *************** *** 45,50 **** --- 46,52 ---- #endif static char * filter_gets _((SV *sv, FILE *fp)); static void restore_rsfp _((void *f)); + static SV * sub_const _((CV *cv)); /* 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). *************** *** 515,520 **** --- 517,550 ---- } } + 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 == '.' && 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; *************** *** 965,971 **** if (indirgv && GvCV(indirgv)) return 0; /* filehandle or package name makes it a method */ ! if (!gv || GvIO(indirgv) || gv_stashpv(tmpbuf, FALSE)) { s = skipspace(s); nextval[nexttoke].opval = (OP*)newSVOP(OP_CONST, 0, --- 995,1001 ---- if (indirgv && GvCV(indirgv)) return 0; /* filehandle or package name makes it a method */ ! if (!gv || GvIO(indirgv) || gv_stashpvn(tmpbuf, len, FALSE)) { s = skipspace(s); nextval[nexttoke].opval = (OP*)newSVOP(OP_CONST, 0, *************** *** 1199,1205 **** return ')'; } if (lex_casemods > 10) { ! char* newlb = (char*)realloc(lex_casestack, lex_casemods + 2); if (newlb != lex_casestack) { SAVEFREEPV(newlb); lex_casestack = newlb; --- 1229,1235 ---- return ')'; } if (lex_casemods > 10) { ! char* newlb = Renew(lex_casestack, lex_casemods + 2, char); if (newlb != lex_casestack) { SAVEFREEPV(newlb); lex_casestack = newlb; *************** *** 1480,1486 **** int oldp = minus_p; while (*d && !isSPACE(*d)) d++; ! while (*d == ' ') d++; if (*d++ == '-') { while (d = moreswitches(d)) ; --- 1510,1516 ---- int oldp = minus_p; while (*d && !isSPACE(*d)) d++; ! while (*d == ' ' || *d == '\t') d++; if (*d++ == '-') { while (d = moreswitches(d)) ; *************** *** 1725,1731 **** leftbracket: s++; if (lex_brackets > 100) { ! char* newlb = (char*)realloc(lex_brackstack, lex_brackets + 1); if (newlb != lex_brackstack) { SAVEFREEPV(newlb); lex_brackstack = newlb; --- 1755,1761 ---- leftbracket: s++; if (lex_brackets > 100) { ! char* newlb = Renew(lex_brackstack, lex_brackets + 1, char); if (newlb != lex_brackstack) { SAVEFREEPV(newlb); lex_brackstack = newlb; *************** *** 1746,1752 **** case XOPERATOR: while (s < bufend && (*s == ' ' || *s == '\t')) s++; ! if (s < bufend && isALPHA(*s)) { d = scan_word(s, tokenbuf, FALSE, &len); while (d < bufend && (*d == ' ' || *d == '\t')) d++; --- 1776,1782 ---- case XOPERATOR: while (s < bufend && (*s == ' ' || *s == '\t')) s++; ! if (s < bufend && (isALPHA(*s) || *s == '_')) { d = scan_word(s, tokenbuf, FALSE, &len); while (d < bufend && (*d == ' ' || *d == '\t')) d++; *************** *** 2445,2450 **** --- 2475,2491 ---- tokenbuf, tokenbuf); last_lop = oldbufptr; last_lop_op = OP_ENTERSUB; + /* Check for a constant sub */ + if (SvPOK(cv) && !SvCUR(cv)) { + SV *sv = sub_const(cv); + if (sv) { + 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)); *************** *** 2944,2949 **** --- 2985,2991 ---- 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); *************** *** 3059,3065 **** *tokenbuf = '\0'; s = force_word(s,WORD,TRUE,TRUE,FALSE); if (isIDFIRST(*tokenbuf)) ! gv_stashpv(tokenbuf, TRUE); else if (*s == '<') yyerror("<> should be quotes"); UNI(OP_REQUIRE); --- 3101,3107 ---- *tokenbuf = '\0'; s = force_word(s,WORD,TRUE,TRUE,FALSE); if (isIDFIRST(*tokenbuf)) ! gv_stashpvn(tokenbuf, strlen(tokenbuf), TRUE); else if (*s == '<') yyerror("<> should be quotes"); UNI(OP_REQUIRE); *************** *** 3383,3389 **** case KEY_use: if (expect != XSTATE) yyerror("\"use\" not allowed in expression"); ! s = force_word(s,WORD,FALSE,TRUE,FALSE); yylval.ival = 1; OPERATOR(USE); --- 3425,3442 ---- case KEY_use: if (expect != XSTATE) yyerror("\"use\" not allowed in expression"); ! 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); *************** *** 4894,4902 **** --- 4947,4957 ---- CV* outsidecv = compcv; AV* comppadlist; + #ifndef __QNX__ if (compcv) { assert(SvTYPE(compcv) == SVt_PVCV); } + #endif save_I32(&subline); save_item(subname); SAVEINT(padix); *************** *** 4930,4935 **** --- 4985,5011 ---- CvOUTSIDE(compcv) = (CV*)SvREFCNT_inc((SV*)outsidecv); return oldsavestack_ix; + } + + SV * + sub_const(cv) + CV *cv; + { + OP *o; + SV *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 (type != OP_CONST || sv) + return Nullsv; + sv = ((SVOP*)o)->op_sv; + } + return sv; } int #~ Add default UNIVERSAL methods to core diff -Pcr perl5_003/universal.c perl5_003_01/universal.c *** perl5_003/universal.c Wed Dec 31 19:00:00 1969 --- perl5_003_01/universal.c Mon Jul 8 09:45:42 1996 *************** *** 0 **** --- 1,232 ---- + #include "EXTERN.h" + #include "perl.h" + #include "XSUB.h" + + /* + * Contributed by Graham Barr + * The main guts of traverse_isa was actually copied from gv_fetchmeth + */ + + static SV * + isa_lookup(stash, name, len, level) + HV *stash; + char *name; + int len; + int level; + { + AV* av; + GV* gv; + GV** gvp; + HV* hv = Nullhv; + + if (!stash) + return &sv_undef; + + if(strEQ(HvNAME(stash), name)) + return &sv_yes; + + if (level > 100) + croak("Recursive inheritance detected"); + + gvp = (GV**)hv_fetch(stash, "::ISA::CACHE::", 14, FALSE); + + if (gvp && (gv = *gvp) != (GV*)&sv_undef && (hv = GvHV(gv))) { + SV* sv; + SV** svp = (SV**)hv_fetch(hv, name, len, FALSE); + if (svp && (sv = *svp) != (SV*)&sv_undef) + return sv; + } + + gvp = (GV**)hv_fetch(stash,"ISA",3,FALSE); + + if (gvp && (gv = *gvp) != (GV*)&sv_undef && (av = GvAV(gv))) { + if(!hv) { + gvp = (GV**)hv_fetch(stash, "::ISA::CACHE::", 14, TRUE); + + gv = *gvp; + + if (SvTYPE(gv) != SVt_PVGV) + gv_init(gv, stash, "::ISA::CACHE::", 14, TRUE); + + hv = GvHVn(gv); + } + if(hv) { + SV** svp = AvARRAY(av); + I32 items = AvFILL(av) + 1; + while (items--) { + SV* sv = *svp++; + HV* basestash = gv_stashsv(sv, FALSE); + if (!basestash) { + if (dowarn) + warn("Can't locate package %s for @%s::ISA", + SvPVX(sv), HvNAME(stash)); + continue; + } + if(&sv_yes == isa_lookup(basestash, name, len, level + 1)) { + (void)hv_store(hv,name,len,&sv_yes,0); + return &sv_yes; + } + } + (void)hv_store(hv,name,len,&sv_no,0); + } + } + + return &sv_no; + } + + static + XS(XS_UNIVERSAL_isa) + { + dXSARGS; + SV *sv, *rv; + char *name; + + if (items != 2) + croak("Usage: UNIVERSAL::isa(reference, kind)"); + + sv = ST(0); + name = (char *)SvPV(ST(1),na); + + if (!SvROK(sv)) { + rv = &sv_no; + } + else if((sv = (SV*)SvRV(sv)) && SvOBJECT(sv) && + &sv_yes == isa_lookup(SvSTASH(sv), name, strlen(name), 0)) { + rv = &sv_yes; + } + else { + char *s; + + switch (SvTYPE(sv)) { + case SVt_NULL: + case SVt_IV: + case SVt_NV: + case SVt_RV: + case SVt_PV: + case SVt_PVIV: + case SVt_PVNV: + case SVt_PVBM: + case SVt_PVMG: s = "SCALAR"; break; + case SVt_PVLV: s = "LVALUE"; break; + case SVt_PVAV: s = "ARRAY"; break; + case SVt_PVHV: s = "HASH"; break; + case SVt_PVCV: s = "CODE"; break; + case SVt_PVGV: s = "GLOB"; break; + case SVt_PVFM: s = "FORMATLINE"; break; + case SVt_PVIO: s = "FILEHANDLE"; break; + default: s = "UNKNOWN"; break; + } + rv = strEQ(s,name) ? &sv_yes : &sv_no; + } + + ST(0) = rv; + XSRETURN(1); + } + + static + XS(XS_UNIVERSAL_can) + { + dXSARGS; + SV *sv; + char *name; + SV *rv; + GV *gv; + CV *cvp; + + if (items != 2) + croak("Usage: UNIVERSAL::can(object-ref, method)"); + + sv = ST(0); + name = (char *)SvPV(ST(1),na); + rv = &sv_undef; + + if(SvROK(sv) && (sv = (SV*)SvRV(sv)) && SvOBJECT(sv)) { + gv = gv_fetchmethod(SvSTASH(sv), name); + + if(gv && GvCV(gv)) { + /* If the sub is only a stub then we may have a gv to AUTOLOAD */ + GV **gvp = (GV**)hv_fetch(GvSTASH(gv), name, strlen(name), TRUE); + if(gvp && (cvp = GvCV(*gvp))) { + rv = sv_newmortal(); + sv_setsv(rv, newRV((SV*)cvp)); + } + } + } + + ST(0) = rv; + XSRETURN(1); + } + + static + XS(XS_UNIVERSAL_is_instance) + { + dXSARGS; + ST(0) = SvROK(ST(0)) ? &sv_yes : &sv_no; + XSRETURN(1); + } + + static + XS(XS_UNIVERSAL_class) + { + dXSARGS; + if(SvROK(ST(0))) { + SV *sv = sv_newmortal(); + sv_setpv(sv, HvNAME(SvSTASH(ST(0)))); + ST(0) = sv; + } + XSRETURN(1); + } + + static + XS(XS_UNIVERSAL_VERSION) + { + dXSARGS; + HV *pkg; + GV **gvp; + GV *gv; + SV *sv; + char *undef; + + if(SvROK(ST(0))) { + sv = (SV*)SvRV(ST(0)); + if(!SvOBJECT(sv)) + croak("Cannot find version of an unblessed reference"); + pkg = SvSTASH(sv); + } + else { + pkg = gv_stashsv(ST(0), FALSE); + } + + gvp = pkg ? (GV**)hv_fetch(pkg,"VERSION",7,FALSE) : Null(GV**); + + if (gvp && (gv = *gvp) != (GV*)&sv_undef && (sv = GvSV(gv))) { + SV *nsv = sv_newmortal(); + sv_setsv(nsv, sv); + sv = nsv; + undef = Nullch; + } + else { + sv = (SV*)&sv_undef; + undef = "(undef)"; + } + + if(items > 1 && (undef || SvNV(ST(1)) > SvNV(sv))) + croak("%s version %s required--this is only version %s", + HvNAME(pkg),SvPV(ST(1),na),undef ? undef : SvPV(sv,na)); + + ST(0) = sv; + + XSRETURN(1); + } + + void + boot_core_UNIVERSAL() + { + char *file = __FILE__; + + newXS("UNIVERSAL::isa", XS_UNIVERSAL_isa, file); + newXS("UNIVERSAL::can", XS_UNIVERSAL_can, file); + newXS("UNIVERSAL::class", XS_UNIVERSAL_class, file); + newXS("UNIVERSAL::is_instance", XS_UNIVERSAL_is_instance, file); + newXS("UNIVERSAL::VERSION", XS_UNIVERSAL_VERSION, file); + } #~ Add OS-specific initialization for macros used in Plan9 and VMS ports diff -Pcr perl5_003/unixish.h perl5_003_01/unixish.h *** perl5_003/unixish.h Mon Mar 25 01:05:42 1996 --- perl5_003_01/unixish.h Thu Jul 25 16:13:39 1996 *************** *** 34,39 **** --- 34,60 ---- #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 #~ Allow redirection of debug messages #~ Add safe calloc() wrappers #~ Correct count in i18nl10n #~ Use Unixish my_p(open|close)() under OS/2 #ifdef HAS_FORK diff -Pcr perl5_003/util.c perl5_003_01/util.c *** perl5_003/util.c Mon Mar 25 01:05:43 1996 --- perl5_003_01/util.c Thu Jul 18 11:15:14 1996 *************** *** 83,91 **** #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)); #else ! DEBUG_m(fprintf(stderr,"0x%lx: (%05d) malloc %ld bytes\n",ptr,an++,(long)size)); #endif if (ptr != Nullch) return ptr; --- 83,91 ---- #endif ptr = malloc(size?size:1); /* malloc(0) is NASTY on our system */ #if !(defined(I286) || defined(atarist)) ! DEBUG_m(fprintf(Perl_debug_log,"0x%x: (%05d) malloc %ld bytes\n",ptr,an++,(long)size)); #else ! DEBUG_m(fprintf(Perl_debug_log,"0x%lx: (%05d) malloc %ld bytes\n",ptr,an++,(long)size)); #endif if (ptr != Nullch) return ptr; *************** *** 130,142 **** #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); } ) #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); } ) #endif --- 130,142 ---- #if !(defined(I286) || defined(atarist)) DEBUG_m( { ! fprintf(Perl_debug_log,"0x%x: (%05d) rfree\n",where,an++); ! fprintf(Perl_debug_log,"0x%x: (%05d) realloc %ld bytes\n",ptr,an++,(long)size); } ) #else DEBUG_m( { ! fprintf(Perl_debug_log,"0x%lx: (%05d) rfree\n",where,an++); ! fprintf(Perl_debug_log,"0x%lx: (%05d) realloc %ld bytes\n",ptr,an++,(long)size); } ) #endif *************** *** 158,166 **** char *where; { #if !(defined(I286) || defined(atarist)) ! DEBUG_m( fprintf(stderr,"0x%x: (%05d) free\n",where,an++)); #else ! DEBUG_m( fprintf(stderr,"0x%lx: (%05d) free\n",where,an++)); #endif if (where) { /*SUPPRESS 701*/ --- 158,166 ---- char *where; { #if !(defined(I286) || defined(atarist)) ! DEBUG_m( fprintf(Perl_debug_log,"0x%x: (%05d) free\n",where,an++)); #else ! DEBUG_m( fprintf(Perl_debug_log,"0x%lx: (%05d) free\n",where,an++)); #endif if (where) { /*SUPPRESS 701*/ *************** *** 168,173 **** --- 168,212 ---- } } + /* safe version of calloc */ + + char * + safecalloc(count, size) + MEM_SIZE count; + MEM_SIZE size; + { + char *ptr; + + #ifdef MSDOS + if (size * count > 0xffff) { + fprintf(stderr, "Allocation too large: %lx\n", size * count) FLUSH; + my_exit(1); + } + #endif /* MSDOS */ + #ifdef DEBUGGING + if ((long)size < 0 || (long)count < 0) + croak("panic: calloc"); + #endif + #if !(defined(I286) || defined(atarist)) + DEBUG_m(fprintf(stderr,"0x%x: (%05d) calloc %ld x %ld bytes\n",ptr,an++,(long)count,(long)size)); + #else + DEBUG_m(fprintf(stderr,"0x%lx: (%05d) calloc %ld x %ld bytes\n",ptr,an++,(long)count,(long)size)); + #endif + size *= count; + ptr = malloc(size?size:1); /* malloc(0) is NASTY on our system */ + if (ptr != Nullch) { + memset((void*)ptr, 0, size); + return ptr; + } + else if (nomemok) + return Nullch; + else { + fputs(no_mem,stderr) FLUSH; + my_exit(1); + } + /*NOTREACHED*/ + } + #endif /* !safemalloc */ #ifdef LEAKTEST *************** *** 211,216 **** --- 250,271 ---- safefree(where); } + char * + safexcalloc(x,count,size) + I32 x; + MEM_SIZE count; + MEM_SIZE size; + { + register char *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() { *************** *** 355,361 **** /* Initialize locale (and the fold[] array).*/ int ! perl_init_i18nl14n(printwarn) int printwarn; { int ok = 1; --- 410,416 ---- /* Initialize locale (and the fold[] array).*/ int ! perl_init_i18nl10n(printwarn) int printwarn; { int ok = 1; *************** *** 463,469 **** } BmRARE(sv) = s[rarest]; BmPREVIOUS(sv) = rarest; ! DEBUG_r(fprintf(stderr,"rarest char %c at %d\n",BmRARE(sv),BmPREVIOUS(sv))); } char * --- 518,524 ---- } BmRARE(sv) = s[rarest]; BmPREVIOUS(sv) = rarest; ! DEBUG_r(fprintf(Perl_debug_log,"rarest char %c at %d\n",BmRARE(sv),BmPREVIOUS(sv))); } char * *************** *** 1364,1370 **** VTOH(vtohl,long) #endif ! #if !defined(DOSISH) && !defined(VMS) /* VMS' my_popen() is in VMS.c, same with OS/2. */ FILE * my_popen(cmd,mode) --- 1419,1425 ---- VTOH(vtohl,long) #endif ! #if (!defined(DOSISH) || defined(HAS_FORK)) && !defined(VMS) /* VMS' my_popen() is in VMS.c, same with OS/2. */ FILE * my_popen(cmd,mode) *************** *** 1499,1505 **** } #endif ! #if !defined(DOSISH) && !defined(VMS) /* VMS' my_popen() is in VMS.c */ I32 my_pclose(ptr) FILE *ptr; --- 1554,1560 ---- } #endif ! #if (!defined(DOSISH) || defined(HAS_FORK)) && !defined(VMS) /* VMS' my_popen() is in VMS.c */ I32 my_pclose(ptr) FILE *ptr; *************** *** 1604,1610 **** return; } ! #if defined(atarist) || defined(OS2) int pclose(); I32 my_pclose(ptr) --- 1659,1665 ---- return; } ! #if defined(atarist) || (defined(OS2) && !defined(HAS_FORK)) int pclose(); I32 my_pclose(ptr) #~ Write output to "install into" directory, not "apparent installed" #~ directory (the two may differ under e.g. AFS) diff -Pcr perl5_003/utils/h2ph.PL perl5_003_01/utils/h2ph.PL *** perl5_003/utils/h2ph.PL Mon Mar 25 01:05:46 1996 --- perl5_003_01/utils/h2ph.PL Fri Jul 5 17:08:07 1996 *************** *** 34,40 **** 'ds 00 \"'; 'ig 00 '; ! \$perlincl = "$Config{archlibexp}"; !GROK!THIS! --- 34,40 ---- 'ds 00 \"'; 'ig 00 '; ! \$perlincl = "$Config{installsitearchlib}"; !GROK!THIS! #~ Add documented -p and -s options, and undocumented -x option #~ Add VMS support diff -Pcr perl5_003/utils/h2xs.PL perl5_003_01/utils/h2xs.PL *** perl5_003/utils/h2xs.PL Mon Mar 25 01:05:46 1996 --- perl5_003_01/utils/h2xs.PL Wed Jul 10 12:10:09 1996 *************** *** 33,46 **** # In the following, perl variables are not expanded during extraction. print OUT <<'!NO!SUBS!'; - =head1 NAME h2xs - convert .h C header files to Perl extensions =head1 SYNOPSIS ! B [B<-AOPXcf>] [B<-v> version] [B<-n> module_name] [headerfile [extra_libraries]] B B<-h> --- 33,45 ---- # In the following, perl variables are not expanded during extraction. print OUT <<'!NO!SUBS!'; =head1 NAME h2xs - convert .h C header files to Perl extensions =head1 SYNOPSIS ! B [B<-AOPXcf>] [B<-v> version] [B<-n> module_name] [B<-p> prefix] [B<-s> sub] [headerfile [extra_libraries]] B B<-h> *************** *** 98,103 **** --- 97,113 ---- Specifies a name to be used for the extension, e.g., S<-n RPC::DCE> + =item B<-p> I + + Specify a prefix which should be removed from the Perl function names, e.g., S<-p sec_rgy_> + This sets up the XS B keyword and removes the prefix from functions that are + autoloaded via the C mechansim. + + =item B<-s> I + + Create a perl subroutine for the specified macros rather than autoload with the constant() subroutine. + These macros are assumed to have a return type of B, e.g., S<-s sec_rgy_wildcard_name,sec_rgy_wildcard_sid>. + =item B<-v> I Specify a version number for this extension. This version number is added *************** *** 138,143 **** --- 148,162 ---- # additional directory /opt/net/lib h2xs rpcsvc/rusers -L/opt/net/lib -lrpc + # Extension is DCE::rgynbase + # prefix "sec_rgy_" is dropped from perl function names + h2xs -n DCE::rgynbase -p sec_rgy_ dce/rgynbase + + # Extension is DCE::rgynbase + # prefix "sec_rgy_" is dropped from perl function names + # subroutines are created for sec_rgy_wildcard_name and sec_rgy_wildcard_sid + h2xs -n DCE::rgynbase -p sec_rgy_ \ + -s sec_rgy_wildcard_name,sec_rgy_wildcard_sid dce/rgynbase =head1 ENVIRONMENT *************** *** 164,174 **** sub usage{ warn "@_\n" if @_; ! die "h2xs [-AOPXcfh] [-v version] [-n module_name] [headerfile [extra_libraries]] version: $H2XS_VERSION -f Force creation of the extension even if the C header does not exist. -n Specify a name to use for the extension (recommended). -c Omit the constant() function and specialised AUTOLOAD from the XS file. -A Omit all autoloading facilities (implies -c). -O Allow overwriting of a pre-existing extension directory. -P Omit the stub POD section. --- 183,195 ---- sub usage{ warn "@_\n" if @_; ! die "h2xs [-AOPXcfh] [-v version] [-n module_name] [-p prefix] [-s subs] [headerfile [extra_libraries]] version: $H2XS_VERSION -f Force creation of the extension even if the C header does not exist. -n Specify a name to use for the extension (recommended). -c Omit the constant() function and specialised AUTOLOAD from the XS file. + -p Specify a prefix which should be removed from the Perl function names. + -s Create subroutines for specified macros. -A Omit all autoloading facilities (implies -c). -O Allow overwriting of a pre-existing extension directory. -P Omit the stub POD section. *************** *** 182,188 **** } ! getopts("AOPXcfhv:n:") || usage; usage if $opt_h; --- 203,209 ---- } ! getopts("AOPXcfhxv:n:p:s:") || usage; usage if $opt_h; *************** *** 190,195 **** --- 211,217 ---- $TEMPLATE_VERSION = $opt_v; } $opt_c = 1 if $opt_A; + %const_xsub = map { $_,1 } split(/,+/, $opt_s) if $opt_s; $path_h = shift; $extralibs = "@ARGV"; *************** *** 204,210 **** warn "Nesting of headerfile ignored with -n\n"; } $path_h .= ".h" unless $path_h =~ /\.h$/; ! $path_h = "/usr/include/$path_h" unless $path_h =~ m#^[./]#; die "Can't find $path_h\n" if ( ! $opt_f && ! -f $path_h ); # Scan the header file (we should deal with nested header files) --- 226,246 ---- warn "Nesting of headerfile ignored with -n\n"; } $path_h .= ".h" unless $path_h =~ /\.h$/; ! if ($^O eq 'VMS') { # Consider overrides of default location ! if ($path_h !~ m![:>\[]!) { ! my($hadsys) = ($path_h =~ s!^sys/!!i); ! if ($ENV{'DECC$System_Include'}) { $path_h = "DECC\$System_Include:$path_h"; } ! elsif ($ENV{'DECC$Library_Include'}) { $path_h = "DECC\$Library_Include:$path_h"; } ! elsif ($ENV{'GNU_CC_Include'}) { $path_h = 'GNU_CC_Include:' . ! ($hadsys ? '[vms]' : '[000000]') . $path_h; } ! elsif ($ENV{'VAXC$Include'}) { $path_h = "VAXC\$_Include:$path_h"; } ! else { $path_h = "Sys\$Library:$path_h"; } ! } ! } ! elsif ($^O eq 'os2') { ! $path_h = "/usr/include/$path_h" unless $path_h =~ m#^([a-z]:)?[./]#i; ! } ! else { $path_h = "/usr/include/$path_h" unless $path_h =~ m#^[./]#; } die "Can't find $path_h\n" if ( ! $opt_f && ! -f $path_h ); # Scan the header file (we should deal with nested header files) *************** *** 212,220 **** # Function prototypes are not (currently) processed. open(CH, "<$path_h") || die "Can't open $path_h: $!\n"; while () { ! if (/^#[ \t]*define\s+(\w+)\b\s*[^("]/) { $_ = $1; next if /^_.*_h_*$/i; # special case, but for what? $const_names{$_}++; } } --- 248,265 ---- # Function prototypes are not (currently) processed. open(CH, "<$path_h") || die "Can't open $path_h: $!\n"; while () { ! if (/^#[ \t]*define\s+([\$\w]+)\b\s*[^("]/) { ! print "Matched $_ ($1)\n"; $_ = $1; next if /^_.*_h_*$/i; # special case, but for what? + if (defined $opt_p) + if (!/^$opt_p(\d)/) { + ++$prefix{$_} if s/^$opt_p//; + } + else { + warn "can't remove $opt_p prefix from '$_'!\n"; + } + } $const_names{$_}++; } } *************** *** 457,462 **** --- 502,508 ---- if( $path_h ){ my($h) = $path_h; $h =~ s#^/usr/include/##; + if ($^O eq 'VMS') { $h =~ s#.*vms\]#sys/# or $h =~ s#.*[:>\]]##; } print XS <<"END"; #include <$h> *************** *** 498,507 **** my($name); while (substr($const_names[0],0,1) eq $letter) { $name = shift(@const_names); print XS <<"END"; if (strEQ(name, "$name")) ! #ifdef $name ! return $name; #else goto not_there; #endif --- 544,555 ---- my($name); while (substr($const_names[0],0,1) eq $letter) { $name = shift(@const_names); + $macro = $prefix{$name} ? "$opt_p$name" : $name; + next if $const_xsub{$macro}; print XS <<"END"; if (strEQ(name, "$name")) ! #ifdef $macro ! return $macro; #else goto not_there; #endif *************** *** 524,536 **** END } # Now switch from C to XS by issuing the first MODULE declaration: print XS <<"END"; ! MODULE = $module PACKAGE = $module END # If a constant() function was written then output a corresponding # XS declaration: print XS <<"END" unless $opt_c; --- 572,603 ---- END } + $prefix = "PREFIX = $opt_p" if defined $opt_p; # Now switch from C to XS by issuing the first MODULE declaration: print XS <<"END"; ! MODULE = $module PACKAGE = $module $prefix END + foreach (sort keys %const_xsub) { + print XS <<"END"; + char * + $_() + + CODE: + #ifdef $_ + RETVAL = $_; + #else + croak("Your vendor has not defined the $module macro $_"); + #endif + + OUTPUT: + RETVAL + + END + } + # If a constant() function was written then output a corresponding # XS declaration: print XS <<"END" unless $opt_c; *************** *** 542,547 **** --- 609,666 ---- END + sub print_decl { + my $fh = shift; + my $decl = shift; + my ($type, $name, $args) = @$decl; + my @argnames = map {$_->[1]} @$args; + my @argtypes = map { normalize_type( $_->[0] ) } @$args; + my $numargs = @$args; + if ($numargs and $argtypes[-1] eq '...') { + $numargs--; + $argnames[-1] = '...'; + } + local $" = ', '; + $type = normalize_type($type); + + print $fh <<"EOP"; + + $type + $name(@argnames) + EOP + + for $arg (0 .. $numargs - 1) { + print $fh <<"EOP"; + $argtypes[$arg] $argnames[$arg] + EOP + } + } + + my $ignore_mods = '(?:\b(?:__const__|static|inline|__inline__)\b\s*)*'; + + sub normalize_type { + my $type = shift; + $type =~ s/$ignore_mods//go; + $type =~ s/\s+/ /g; + $type =~ s/\s+$//; + $type =~ s/^\s+//; + $type =~ s/\b\*/ */g; + $type =~ s/\*\b/* /g; + $type =~ s/\*\s+(?=\*)/*/g; + $type; + } + + if ($opt_x) { + require C::Scan; # Run-time directive + require Config; # Run-time directive + my $c = new C::Scan 'filename' => $path_h; + $c->set('includeDirs' => [$Config::Config{shrpdir}]); + + my $fdec = $c->get('parsed_fdecls'); + + for $decl (@$fdec) { print_decl(\*XS, $decl) } + } + close XS; } # if( ! $opt_X ) #~ More informative prompting #~ Don't edit precomposed file #~ Correct socket %Config variable under VMS #~ Try again if we can't read precomposed file #~ Be more finicky about command to send message diff -Pcr perl5_003/utils/perlbug.PL perl5_003_01/utils/perlbug.PL *** perl5_003/utils/perlbug.PL Mon Mar 25 01:05:47 1996 --- perl5_003_01/utils/perlbug.PL Wed Jul 17 11:25:08 1996 *************** *** 50,56 **** sub paraprint; ! my($Version) = "1.13"; # Changed in 1.06 to skip Mail::Send and Mail::Util if not available. # Changed in 1.07 to see more sendmail execs, and added pipe output. --- 50,56 ---- sub paraprint; ! my($Version) = "1.14"; # Changed in 1.06 to skip Mail::Send and Mail::Util if not available. # Changed in 1.07 to see more sendmail execs, and added pipe output. *************** *** 64,75 **** # clearer and add $ENV{REPLYTO}. # Changed in 1.13 to hopefully make it more difficult to accidentally # send mail # TODO: Allow the user to re-name the file on mail failure, and # make sure failure (transmission-wise) of Mail::Send is # accounted for. ! my( $file, $cc, $address, $perlbug, $testaddress, $filename, $subject, $from, $verbose, $ed, $fh, $me, $Is_VMS, $msg, $body, $andcc ); --- 64,77 ---- # clearer and add $ENV{REPLYTO}. # Changed in 1.13 to hopefully make it more difficult to accidentally # send mail + # Changed in 1.14 to make the prompts a little more clear on providing + # helpful information. Also let file read fail gracefully. # TODO: Allow the user to re-name the file on mail failure, and # make sure failure (transmission-wise) of Mail::Send is # accounted for. ! my( $file, $usefile, $cc, $address, $perlbug, $testaddress, $filename, $subject, $from, $verbose, $ed, $fh, $me, $Is_VMS, $msg, $body, $andcc ); *************** *** 88,94 **** if($::opt_d or !-t STDOUT) { Dump(*STDOUT); exit; } Query(); ! Edit(); NowWhat(); Send(); --- 90,96 ---- if($::opt_d or !-t STDOUT) { Dump(*STDOUT); exit; } Query(); ! Edit() unless $usefile; NowWhat(); Send(); *************** *** 134,139 **** --- 136,144 ---- # Subject of bug-report message $subject = $::opt_s || ""; + # Send a file + $usefile = ($::opt_f || 0); + # File to send as report $file = $::opt_f || ""; *************** *** 141,150 **** $body = $::opt_b || ""; # Editor ! $ed = ($::opt_f ? "file" : ( ! $::opt_e || $ENV{VISUAL} || $ENV{EDITOR} || $ENV{EDIT} || ($Is_VMS ? "edit/tpu" : "vi") ! )); # My username $me = getpwuid($<); --- 146,155 ---- $body = $::opt_b || ""; # Editor ! $ed = ( $::opt_e || $ENV{VISUAL} || $ENV{EDITOR} || $ENV{EDIT} || ($Is_VMS ? "edit/tpu" : "vi") ! ); ! # My username $me = getpwuid($<); *************** *** 157,165 **** # Explain what perlbug is paraprint <); chop $entry; ! ! if($entry ne "") { $ed = $entry; } } --- 321,331 ---- my($entry) =scalar(<>); chop $entry; ! ! $usefile = 0; ! if($entry eq "file") { ! $usefile = 1; ! } elsif($entry ne "") { $ed = $entry; } } *************** *** 328,337 **** # Prompt for file to read report from, if needed ! if( $ed eq "file" and ! $file) { paraprint <); chop($entry); if(!-f $entry or !-r $entry) { ! print "\n\nUnable to read from `$entry'.\nExiting.\n"; ! exit; } $file = $entry; --- 356,379 ---- my($entry) = scalar(<>); chop($entry); + if($entry eq "") { + paraprint <) { print REP $_ } --- 392,399 ---- if($body) { print REP $body; ! } elsif($usefile) { ! open(F,"<$file") or die "Unable to read report file from `$file': $!\n"; while() { print REP $_ } *************** *** 407,415 **** sub Edit { # Edit the report ! tryagain: ! if(!$file and !$body) { my($sts) = system("$ed $filename"); if( $Is_VMS ? !($sts & 1) : $sts ) { #print "\nUnable to run editor!\n"; --- 437,462 ---- sub Edit { # Edit the report + + if($usefile) { + $usefile = 0; + paraprint <); + chop $entry; ! if($entry ne "") { ! $ed = $entry; ! } ! } ! ! tryagain: ! if(!$usefile and !$body) { my($sts) = system("$ed $filename"); if( $Is_VMS ? !($sts & 1) : $sts ) { #print "\nUnable to run editor!\n"; *************** *** 493,498 **** --- 540,554 ---- chop($reply); if( $reply eq "yes" ) { last; + } else { + paraprint <dit, e-edit # edit the message #~ Updates matching vms/descrip.mms diff -Pcr perl5_003/vms/Makefile perl5_003_01/vms/Makefile *** perl5_003/vms/Makefile Sun Jun 23 22:54:44 1996 --- perl5_003_01/vms/Makefile Fri Jul 26 17:49:51 1996 *************** *** 31,41 **** ARCH = VMS_VAX OBJVAL = $@ - .first: - @ $$@[.vms]fndvers.com "" "" "[.vms]Makefile" - # Updated by fndvers.com -- do not edit by hand ! PERL_VERSION = 5_003 # ARCHDIR = [.lib.$(ARCH).$(PERL_VERSION)] --- 31,38 ---- ARCH = VMS_VAX OBJVAL = $@ # Updated by fndvers.com -- do not edit by hand ! PERL_VERSION = 5_00301# ARCHDIR = [.lib.$(ARCH).$(PERL_VERSION)] *************** *** 57,62 **** --- 54,60 ---- # off SYSNAM for the MM[SK] subprocess doesn't hurt anything, so we do it # just in case. .first: + @ $$@[.vms]fndvers.com "" "" "[.vms]Makefile" @ If f$$TrnLnm("Sys").eqs."" .and. f$$TrnLnm("VAXC$Include").eqs."" Then Define/NoLog SYS sys$$Library @ If f$$TrnLnm("Sys").eqs."" .and. f$$TrnLnm("VAXC$Include").nes."" Then Define/NoLog SYS VAXC$Include *************** *** 119,125 **** h4 = regexp.h, scope.h, sv.h, vmsish.h, util.h h = $(h1), $(h2), $(h3), $(h4) $(SOCKHLIS) ! c1 = 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, vms.c $(SOCKCLIS) --- 117,123 ---- h4 = regexp.h, scope.h, sv.h, vmsish.h, util.h h = $(h1), $(h2), $(h3), $(h4) $(SOCKHLIS) ! c1 = av.c, scope.c, op.c, doop.c, doio.c, dump.c, hv.c, mg.c, universal.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, vms.c $(SOCKCLIS) *************** *** 127,133 **** obj1 = perl$(O), gv$(O), toke$(O), perly$(O), op$(O), regcomp$(O), dump$(O), util$(O), mg$(O) obj2 = hv$(O), av$(O), run$(O), pp_hot$(O), sv$(O), pp$(O), scope$(O), pp_ctl$(O), pp_sys$(O) ! obj3 = doop$(O), doio$(O), regexec$(O), taint$(O), deb$(O), globals$(O), vms$(O) $(SOCKOBJ) obj = $(obj1), $(obj2), $(obj3) --- 125,131 ---- obj1 = perl$(O), gv$(O), toke$(O), perly$(O), op$(O), regcomp$(O), dump$(O), util$(O), mg$(O) obj2 = hv$(O), av$(O), run$(O), pp_hot$(O), sv$(O), pp$(O), scope$(O), pp_ctl$(O), pp_sys$(O) ! obj3 = doop$(O), doio$(O), regexec$(O), taint$(O), deb$(O), universal$(O), globals$(O), vms$(O) $(SOCKOBJ) obj = $(obj1), $(obj2), $(obj3) *************** *** 161,171 **** $(CC) $(CFLAGS) $(MMS$SOURCE_NAME).c ! all : base extras archcorefiles preplibrary perlpods @ $(NOOP) base : miniperl perl @ $(NOOP) ! extras : Fcntl FileHandle Safe libmods utils podxform @ $(NOOP) libmods : [.lib]Config.pm $(ARCHDIR)Config.pm [.lib]DynaLoader.pm [.lib.VMS]Filespec.pm @ $(NOOP) --- 159,169 ---- $(CC) $(CFLAGS) $(MMS$SOURCE_NAME).c ! all : base extras libmods utils podxform archcorefiles preplibrary perlpods @ $(NOOP) base : miniperl perl @ $(NOOP) ! extras : Fcntl FileHandle IO Opcode libmods utils podxform @ $(NOOP) libmods : [.lib]Config.pm $(ARCHDIR)Config.pm [.lib]DynaLoader.pm [.lib.VMS]Filespec.pm @ $(NOOP) *************** *** 193,199 **** @ Continue miniperl_objs = miniperlmain$(O), $(obj) $(MINIPERL_EXE) : miniperlmain$(O), $(DBG)libperl$(OLB) $(CRTL) ! Link $(LINKFLAGS)/NoDebug/Exe=$@ miniperlmain$(O), $(DBG)libperl$(OLB)/Library/Include=globals $(CRTLOPTS) $(DBG)miniperl$(E) : $(miniperl_objs), $(DBG)libperl$(OLB) $(CRTL) Link $(LINKFLAGS)/Exe=$@ miniperlmain$(O),$(DBG)libperl$(OLB)/Library/Include=globals $(CRTLOPTS) --- 191,197 ---- @ Continue miniperl_objs = miniperlmain$(O), $(obj) $(MINIPERL_EXE) : miniperlmain$(O), $(DBG)libperl$(OLB) $(CRTL) ! Link $(LINKFLAGS)/NoDebug/NoMap/NoFull/NoCross/Exe=$@ miniperlmain$(O), $(DBG)libperl$(OLB)/Library/Include=globals $(CRTLOPTS) $(DBG)miniperl$(E) : $(miniperl_objs), $(DBG)libperl$(OLB) $(CRTL) Link $(LINKFLAGS)/Exe=$@ miniperlmain$(O),$(DBG)libperl$(OLB)/Library/Include=globals $(CRTLOPTS) *************** *** 253,276 **** @ If f$$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] @ $(MINIPERL) -e "use AutoSplit; autosplit_lib_modules(@ARGV)" [.lib]DynaLoader.pm ! Safe : [.lib]Safe.pm [.lib.auto.Safe]Safe$(E) @ $(NOOP) ! [.lib]Safe.pm : [.ext.Safe]Makefile @ If f$$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] ! @ Set Default [.ext.Safe] $(MMS) @ Set Default [--] ! [.lib.auto.Safe]Safe$(E) : [.ext.Safe]Makefile ! @ Set Default [.ext.Safe] $(MMS) @ Set Default [--] # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C # ${@} necessary to distract different versions of MM[SK]/make ! [.ext.Safe]Makefile : [.ext.Safe]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm perlshr$(E) ! $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Safe]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" FileHandle : [.lib]FileHandle.pm [.lib.auto.FileHandle]FileHandle$(E) @ $(NOOP) --- 251,286 ---- @ If f$$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] @ $(MINIPERL) -e "use AutoSplit; autosplit_lib_modules(@ARGV)" [.lib]DynaLoader.pm ! Opcode : [.lib]Opcode.pm [.lib]ops.pm [.lib]Safe.pm [.lib.auto.Opcode]Opcode$(E) @ $(NOOP) ! [.lib]Opcode.pm : [.ext.Opcode]Makefile ! @ If f$$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] ! @ Set Default [.ext.Opcode] ! $(MMS) ! @ Set Default [--] ! ! [.lib]ops.pm : [.ext.Opcode]Makefile ! @ If f$$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] ! @ Set Default [.ext.Opcode] ! $(MMS) ! @ Set Default [--] ! ! [.lib]Safe.pm : [.ext.Opcode]Makefile @ If f$$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] ! @ Set Default [.ext.Opcode] $(MMS) @ Set Default [--] ! [.lib.auto.Opcode]Opcode$(E) : [.ext.Opcode]Makefile ! @ Set Default [.ext.Opcode] $(MMS) @ Set Default [--] # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C # ${@} necessary to distract different versions of MM[SK]/make ! [.ext.Opcode]Makefile : [.ext.Opcode]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) ! $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Opcode]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" FileHandle : [.lib]FileHandle.pm [.lib.auto.FileHandle]FileHandle$(E) @ $(NOOP) *************** *** 288,294 **** # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C # ${@} necessary to distract different versions of MM[SK]/make ! [.ext.FileHandle]Makefile : [.ext.FileHandle]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.FileHandle]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" Fcntl : [.lib]Fcntl.pm [.lib.auto.Fcntl]Fcntl$(E) --- 298,304 ---- # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C # ${@} necessary to distract different versions of MM[SK]/make ! [.ext.FileHandle]Makefile : [.ext.FileHandle]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.FileHandle]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" Fcntl : [.lib]Fcntl.pm [.lib.auto.Fcntl]Fcntl$(E) *************** *** 307,315 **** # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C # ${@} necessary to distract different versions of MM[SK]/make ! [.ext.Fcntl]Makefile : [.ext.Fcntl]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Fcntl]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" [.lib.VMS]Filespec.pm : [.vms.ext]Filespec.pm @ If f$$Search("[.lib]VMS.Dir").eqs."" Then Create/Directory [.lib.VMS] Copy/Log/NoConfirm [.vms.ext]Filespec.pm $@ --- 317,374 ---- # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C # ${@} necessary to distract different versions of MM[SK]/make ! [.ext.Fcntl]Makefile : [.ext.Fcntl]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Fcntl]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" + IO : [.lib]IO.pm [.lib.IO]File.pm [.lib.IO]Handle.pm [.lib.IO]Pipe.pm [.lib.IO]Seekable.pm [.lib.IO]Socket.pm [.lib.auto.IO]IO$(E) + @ $(NOOP) + + [.lib]IO.pm : [.ext.IO]Makefile + @ If f$$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] + @ Set Default [.ext.IO] + $(MMS) + @ Set Default [--] + + [.lib.IO]File.pm : [.ext.IO]Makefile + @ If f$$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] + @ Set Default [.ext.IO] + $(MMS) + @ Set Default [--] + + [.lib.IO]Handle.pm : [.ext.IO]Makefile + @ If f$$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] + @ Set Default [.ext.IO] + $(MMS) + @ Set Default [--] + + [.lib.IO]Pipe.pm : [.ext.IO]Makefile + @ If f$$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] + @ Set Default [.ext.IO] + $(MMS) + @ Set Default [--] + + [.lib.IO]Seekable.pm : [.ext.IO]Makefile + @ If f$$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] + @ Set Default [.ext.IO] + $(MMS) + @ Set Default [--] + + [.lib.IO]Socket.pm : [.ext.IO]Makefile + @ If f$$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] + @ Set Default [.ext.IO] + $(MMS) + @ Set Default [--] + + [.lib.auto.IO]IO$(E) : [.ext.IO]Makefile + @ Set Default [.ext.IO] + $(MMS) + @ Set Default [--] + + # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C + # ${@} necessary to distract different versions of MM[SK]/make + [.ext.IO]Makefile : [.ext.IO]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) + $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.IO]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" + [.lib.VMS]Filespec.pm : [.vms.ext]Filespec.pm @ If f$$Search("[.lib]VMS.Dir").eqs."" Then Create/Directory [.lib.VMS] Copy/Log/NoConfirm [.vms.ext]Filespec.pm $@ *************** *** 534,540 **** $(CC) $(CFLAGS) perly.c test : all ! - @[.VMS]Test.Com # CORE subset for MakeMaker, so we can build Perl without sources # Should move to VMS installperl when we get one --- 593,599 ---- $(CC) $(CFLAGS) perly.c test : all ! - @[.VMS]Test.Com "$(E)" # CORE subset for MakeMaker, so we can build Perl without sources # Should move to VMS installperl when we get one *************** *** 817,822 **** --- 876,904 ---- mg$(O) : sv.h mg$(O) : vmsish.h mg$(O) : util.h + universal$(O) : EXTERN.h + universal$(O) : av.h + universal$(O) : config.h + universal$(O) : cop.h + universal$(O) : cv.h + universal$(O) : embed.h + universal$(O) : form.h + universal$(O) : gv.h + universal$(O) : handy.h + universal$(O) : hv.h + universal$(O) : mg.h + universal$(O) : op.h + universal$(O) : opcode.h + universal$(O) : perl.h + universal$(O) : perly.h + universal$(O) : pp.h + universal$(O) : proto.h + universal$(O) : regexp.h + universal$(O) : scope.h + universal$(O) : sv.h + universal$(O) : vmsish.h + universal$(O) : util.h + universal$(O) : universal.c perl$(O) : EXTERN.h perl$(O) : av.h perl$(O) : config.h *************** *** 1291,1297 **** - If f$$Search("Perlshr_Gbl*.Mar;-1") .nes."" Then Purge/NoConfirm/Log Perlshr_Gbl*.Mar - If f$$Search("[.Ext.DynaLoader]DL_VMS$(O);-1").nes."" Then Purge/NoConfirm/Log [.Ext.DynaLoader]DL_VMS$(O) - If f$$Search("[.Ext.DynaLoader]DL_VMS.C;-1").nes."" Then Purge/NoConfirm/Log [.Ext.DynaLoader]DL_VMS.C ! - If f$$Search("[.Ext.Safe...];-1").nes."" Then Purge/NoConfirm/Log [.Ext.Safe] - If f$$Search("[.Ext.FileHandle...];-1").nes."" Then Purge/NoConfirm/Log [.Ext.FileHandle] - If f$$Search("[.VMS.Ext...]*.C;-1").nes."" Then Purge/NoConfirm/Log [.VMS.Ext...]*.C - If f$$Search("[.VMS.Ext...]*$(O);-1").nes."" Then Purge/NoConfirm/Log [.VMS.Ext...]*$(O) --- 1373,1379 ---- - If f$$Search("Perlshr_Gbl*.Mar;-1") .nes."" Then Purge/NoConfirm/Log Perlshr_Gbl*.Mar - If f$$Search("[.Ext.DynaLoader]DL_VMS$(O);-1").nes."" Then Purge/NoConfirm/Log [.Ext.DynaLoader]DL_VMS$(O) - If f$$Search("[.Ext.DynaLoader]DL_VMS.C;-1").nes."" Then Purge/NoConfirm/Log [.Ext.DynaLoader]DL_VMS.C ! - If f$$Search("[.Ext.Opcode...];-1").nes."" Then Purge/NoConfirm/Log [.Ext.Opcode] - If f$$Search("[.Ext.FileHandle...];-1").nes."" Then Purge/NoConfirm/Log [.Ext.FileHandle] - If f$$Search("[.VMS.Ext...]*.C;-1").nes."" Then Purge/NoConfirm/Log [.VMS.Ext...]*.C - If f$$Search("[.VMS.Ext...]*$(O);-1").nes."" Then Purge/NoConfirm/Log [.VMS.Ext...]*$(O) *************** *** 1314,1320 **** Set Default [.ext.FileHandle] - $(MMS) clean Set Default [--] ! Set Default [.ext.Safe] - $(MMS) clean Set Default [--] - If f$$Search("*.Opt").nes."" Then Delete/NoConfirm/Log *.Opt;*/Exclude=PerlShr_*.Opt --- 1396,1405 ---- Set Default [.ext.FileHandle] - $(MMS) clean Set Default [--] ! Set Default [.ext.IO] ! - $(MMS) clean ! Set Default [--] ! Set Default [.ext.Opcode] - $(MMS) clean Set Default [--] - If f$$Search("*.Opt").nes."" Then Delete/NoConfirm/Log *.Opt;*/Exclude=PerlShr_*.Opt *************** *** 1344,1356 **** Set Default [.ext.FileHandle] - $(MMS) realclean Set Default [--] ! Set Default [.ext.Safe] - $(MMS) realclean Set Default [--] - If f$$Search("*$(OLB)").nes."" Then Delete/NoConfirm/Log *$(OLB);* - If f$$Search("*.Opt").nes."" Then Delete/NoConfirm/Log *.Opt;* - $(MINIPERL) -e "use File::Path; rmtree(['lib/auto','lib/VMS','lib/$(ARCH)'],1,0);" - If f$$Search("[.Lib]DynaLoader.pm").nes."" Then Delete/NoConfirm/Log [.Lib]DynaLoader.pm;* - If f$$Search("[.Lib]Config.pm").nes."" Then Delete/NoConfirm/Log [.Lib]Config.pm;* - If f$$Search("[.Lib]perlbug.").nes."" Then Delete/NoConfirm/Log [.Lib]perlbug.;* - If f$$Search("$(ARCHDIR)Config.pm").nes."" Then Delete/NoConfirm/Log $(ARCHDIR)Config.pm;* --- 1429,1445 ---- Set Default [.ext.FileHandle] - $(MMS) realclean Set Default [--] ! Set Default [.ext.IO] ! - $(MMS) realclean ! Set Default [--] ! Set Default [.ext.Opcode] - $(MMS) realclean Set Default [--] - If f$$Search("*$(OLB)").nes."" Then Delete/NoConfirm/Log *$(OLB);* - If f$$Search("*.Opt").nes."" Then Delete/NoConfirm/Log *.Opt;* - $(MINIPERL) -e "use File::Path; rmtree(['lib/auto','lib/VMS','lib/$(ARCH)'],1,0);" - If f$$Search("[.Lib]DynaLoader.pm").nes."" Then Delete/NoConfirm/Log [.Lib]DynaLoader.pm;* + - If f$$Search("[.Lib]Socket.pm").nes."" Then Delete/NoConfirm/Log [.Lib]Socket.pm;* - If f$$Search("[.Lib]Config.pm").nes."" Then Delete/NoConfirm/Log [.Lib]Config.pm;* - If f$$Search("[.Lib]perlbug.").nes."" Then Delete/NoConfirm/Log [.Lib]perlbug.;* - If f$$Search("$(ARCHDIR)Config.pm").nes."" Then Delete/NoConfirm/Log $(ARCHDIR)Config.pm;* #~ Incorporate recent changes to config_h.SH: DB_File macros and BIN_SH #~ Update default version number #~ Remove dead code #~ Correct #defines for non-blocking reads until better sorted out #~ Remove duplicate I_SYS_STAT diff -Pcr perl5_003/vms/config.vms perl5_003_01/vms/config.vms *** perl5_003/vms/config.vms Sun Jun 23 22:54:20 1996 --- perl5_003_01/vms/config.vms Thu Jul 18 10:35:43 1996 *************** *** 72,78 **** * when Perl is built. Please do not change it by hand; make * any changes to FndVers.Com instead. */ ! #define ARCHLIB_EXP "/perl_root/lib/VMS_VAX/5_003" /**/ /* CPPSTDIN: * This symbol contains the first part of the string which will invoke --- 72,78 ---- * when Perl is built. Please do not change it by hand; make * any changes to FndVers.Com instead. */ ! #define ARCHLIB_EXP "/perl_root/lib/VMS_VAX/5_00301" /**/ /* CPPSTDIN: * This symbol contains the first part of the string which will invoke *************** *** 134,142 **** * trigger the necessary tests. */ #define HASCONST /**/ - #ifndef HASCONST - #define const - #endif /* HAS_CRYPT: * This symbol, if defined, indicates that the crypt routine is available --- 134,139 ---- *************** *** 566,576 **** */ #define HAS_STRERROR /**/ #undef HAS_SYS_ERRLIST /**/ ! #ifdef HAS_STRERROR ! # define Strerror(e) strerror((e),vaxc$errno) ! #else ! #define Strerror(e) ((e)<0||(e)>=sys_nerr?"unknown":sys_errlist[e]) /**/ /* config-skip */ ! #endif /* HAS_SYMLINK: * This symbol, if defined, indicates that the symlink routine is available --- 563,569 ---- */ #define HAS_STRERROR /**/ #undef HAS_SYS_ERRLIST /**/ ! #define Strerror(e) strerror((e),vaxc$errno) /* HAS_SYMLINK: * This symbol, if defined, indicates that the symlink routine is available *************** *** 1197,1208 **** */ #undef I_LOCALE /**/ - /* I_SYS_STAT: - * This symbol, if defined, indicates to the C program that it should - * include . - */ - #define I_SYS_STAT /**/ - /* INTSIZE: * This symbol contains the size of an int, so that the C preprocessor * can make decisions based on it. --- 1190,1195 ---- *************** *** 1302,1310 **** * 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 ! #define VAL_EAGAIN ! #define RD_NODATA #undef EOF_NONBLOCK /* OLDARCHLIB_EXP: --- 1289,1297 ---- * a non-blocking file descriptor will return 0 on EOF, and not the value * held in RD_NODATA (-1 usually, in that case!). */ ! #undef VAL_O_NONBLOCK ! #undef VAL_EAGAIN ! #undef RD_NODATA #undef EOF_NONBLOCK /* OLDARCHLIB_EXP: *************** *** 1377,1391 **** */ #undef I_SYS_PARAM - /* GNUC_ATTRIBUTE_CHECK: - * This symbol indicates the C compiler can check for function attributes, - * such as printf formats. - */ - /* VMS: true for gcc, undef for VAXC/DECC. This is handled in Descrip.MMS - * C. Bailey 26-Aug-1994 - */ - /*#define GNUC_ATTRIBUTE_CHECK /**/ - /* VOID_CLOSEDIR: * This symbol, if defined, indicates that the closedir() routine * does not return a value. --- 1364,1369 ---- *************** *** 1542,1547 **** --- 1520,1555 ---- */ #define STARTPERL "" /**/ + /* Groups_t: + * This symbol holds the type used for the second argument to + * getgroups(). 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 to get any + * typedef'ed information. This is only required if you have + * getgroups(). + */ + #ifdef HAS_GETGROUPS + #define Groups_t unsigned int /* Type for 2nd arg to getgroups() */ /* config-skip */ + #endif + + /* DB_Prefix_t: + * This symbol contains the type of the prefix structure element + * in the header file. In older versions of DB, it was + * int, while in newer ones it is u_int32_t. + */ + /* DB_Hash_t: + * This symbol contains the type of the prefix structure element + * in the header file. In older versions of DB, it was + * int, while in newer ones it is size_t. + */ + #undef DB_Hash_t /**/ + #undef DB_Prefix_t /**/ + + /* BIN_SH: + * This variable contains the path to the shell. + */ + #define BIN_SH "MCR" /**/ + /* VOIDFLAGS: * This symbol indicates how much support of the void type is given by this * compiler. What various bits mean: *************** *** 1594,1624 **** * include . Otherwise, you may try . */ #undef I_NETINET_IN /**/ /* config-skip */ - - /* Groups_t: - * This symbol holds the type used for the second argument to - * getgroups(). 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 to get any - * typedef'ed information. This is only required if you have - * getgroups(). - */ - #ifdef HAS_GETGROUPS - #define Groups_t unsigned int /* Type for 2nd arg to getgroups() */ /* config-skip */ - #endif - - /* DB_Prefix_t: - * This symbol contains the type of the prefix structure element - * in the header file. In older versions of DB, it was - * int, while in newer ones it is u_int32_t. - */ - /* DB_Hash_t: - * This symbol contains the type of the prefix structure element - * in the header file. In older versions of DB, it was - * int, while in newer ones it is size_t. - */ - #undef DB_Hash_t /**/ - #undef DB_Prefix_t /**/ /* I_NET_ERRNO: * This symbol, if defined, indicates that exists and --- 1602,1607 ---- #~ Use a single .first target -- MMS only processes last one encountered #~ Update default version #~ Add dependencies for new universal.c, Opcode, and IO #~ Remove dependencies for obsolete Safe #~ Turn off all debug options for non-debug link if miniperl #~ Eliminate duplicate library specification to link when using gcc #~ Tell test driver if we're using non-default filetype for executable images diff -Pcr perl5_003/vms/descrip.mms perl5_003_01/vms/descrip.mms *** perl5_003/vms/descrip.mms Sun Jun 23 22:53:30 1996 --- perl5_003_01/vms/descrip.mms Wed Jul 24 09:29:46 1996 *************** *** 64,74 **** OBJVAL = $(MMS$TARGET_NAME)$(O) .endif - .first - @ @[.vms]fndvers.com "" "" "[.vms]descrip.mms" - # Updated by fndvers.com -- do not edit by hand ! PERL_VERSION = 5_003 # ARCHDIR = [.lib.$(ARCH).$(PERL_VERSION)] --- 64,71 ---- OBJVAL = $(MMS$TARGET_NAME)$(O) .endif # Updated by fndvers.com -- do not edit by hand ! PERL_VERSION = 5_00301# ARCHDIR = [.lib.$(ARCH).$(PERL_VERSION)] *************** *** 85,90 **** --- 82,88 ---- #: >>>>>Compiler-specific options <<<<< .ifdef GNUC .first + @ @[.vms]fndvers.com "" "" "[.vms]descrip.mms" @ If F$TrnLnm("Sys").eqs."" Then Define/NoLog SYS GNU_CC_Include:[VMS] CC = gcc # -fno-builtin avoids bug in gcc up to version 2.6.2 which can destroy *************** *** 108,113 **** --- 106,112 ---- # just in case. .first @ Set Process/Privilege=(NoSYSNAM) + @ @[.vms]fndvers.com "" "" "[.vms]descrip.mms" @ If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").nes."" Then Define/NoLog SYS DECC$System_Include .ifdef __AXP__ @ If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").eqs."" Then Define/NoLog SYS Sys$Library *************** *** 120,125 **** --- 119,125 ---- XTRADEF = .else # VAXC .first + @ @[.vms]fndvers.com "" "" "[.vms]descrip.mms" @ If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").eqs."" Then Define/NoLog SYS Sys$Library @ If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").nes."" Then Define/NoLog SYS VAXC$Include *************** *** 214,220 **** h4 = regexp.h, scope.h, sv.h, vmsish.h, util.h h = $(h1), $(h2), $(h3), $(h4) $(SOCKHLIS) ! c1 = 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, vms.c $(SOCKCLIS) --- 214,220 ---- h4 = regexp.h, scope.h, sv.h, vmsish.h, util.h h = $(h1), $(h2), $(h3), $(h4) $(SOCKHLIS) ! c1 = av.c, scope.c, op.c, doop.c, doio.c, dump.c, hv.c, mg.c, universal.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, vms.c $(SOCKCLIS) *************** *** 222,228 **** obj1 = perl$(O), gv$(O), toke$(O), perly$(O), op$(O), regcomp$(O), dump$(O), util$(O), mg$(O) obj2 = hv$(O), av$(O), run$(O), pp_hot$(O), sv$(O), pp$(O), scope$(O), pp_ctl$(O), pp_sys$(O) ! obj3 = doop$(O), doio$(O), regexec$(O), taint$(O), deb$(O), globals$(O), vms$(O) $(SOCKOBJ) obj = $(obj1), $(obj2), $(obj3) --- 222,228 ---- obj1 = perl$(O), gv$(O), toke$(O), perly$(O), op$(O), regcomp$(O), dump$(O), util$(O), mg$(O) obj2 = hv$(O), av$(O), run$(O), pp_hot$(O), sv$(O), pp$(O), scope$(O), pp_ctl$(O), pp_sys$(O) ! obj3 = doop$(O), doio$(O), regexec$(O), taint$(O), deb$(O), universal$(O), globals$(O), vms$(O) $(SOCKOBJ) obj = $(obj1), $(obj2), $(obj3) *************** *** 263,273 **** .endif ! all : base extras archcorefiles preplibrary perlpods @ $(NOOP) base : miniperl perl @ $(NOOP) ! extras : Fcntl FileHandle Safe libmods utils podxform @ $(NOOP) libmods : [.lib]Config.pm $(ARCHDIR)Config.pm [.lib]DynaLoader.pm [.lib.VMS]Filespec.pm @ $(NOOP) --- 263,273 ---- .endif ! all : base extras libmods utils podxform archcorefiles preplibrary perlpods @ $(NOOP) base : miniperl perl @ $(NOOP) ! extras : Fcntl FileHandle IO Opcode libmods utils podxform @ $(NOOP) libmods : [.lib]Config.pm $(ARCHDIR)Config.pm [.lib]DynaLoader.pm [.lib.VMS]Filespec.pm @ $(NOOP) *************** *** 295,301 **** @ Continue miniperl_objs = miniperlmain$(O), $(obj) $(MINIPERL_EXE) : miniperlmain$(O), $(DBG)libperl$(OLB) $(CRTL) ! Link $(LINKFLAGS)/NoDebug/Exe=$(MMS$TARGET) miniperlmain$(O), $(DBG)libperl$(OLB)/Library/Include=globals $(CRTLOPTS) $(DBG)miniperl$(E) : $(miniperl_objs), $(DBG)libperl$(OLB) $(CRTL) Link $(LINKFLAGS)/Exe=$(MMS$TARGET) miniperlmain$(O),$(DBG)libperl$(OLB)/Library/Include=globals $(CRTLOPTS) --- 295,301 ---- @ Continue miniperl_objs = miniperlmain$(O), $(obj) $(MINIPERL_EXE) : miniperlmain$(O), $(DBG)libperl$(OLB) $(CRTL) ! Link $(LINKFLAGS)/NoDebug/NoMap/NoFull/NoCross/Exe=$(MMS$TARGET) miniperlmain$(O), $(DBG)libperl$(OLB)/Library/Include=globals $(CRTLOPTS) $(DBG)miniperl$(E) : $(miniperl_objs), $(DBG)libperl$(OLB) $(CRTL) Link $(LINKFLAGS)/Exe=$(MMS$TARGET) miniperlmain$(O),$(DBG)libperl$(OLB)/Library/Include=globals $(CRTLOPTS) *************** *** 313,321 **** $(DBG)perl$(E) : perlmain$(O), $(DBG)perlshr$(E), $(MINIPERL_EXE) @ @[.vms]genopt "PerlShr.Opt/Write" "|" "''F$Environment("Default")'$(DBG)PerlShr$(E)/Share" .ifdef gnuc ! @ @[.vms]genopt "PerlShr.Opt/Append" "|" "$(LIBS1)|$(LIBS2)" ! .endif Link $(LINKFLAGS)/Exe=$(MMS$TARGET) perlmain$(O), perlshr.opt/Option, perlshr_attr.opt/Option $(DBG)perlshr$(E) : $(DBG)libperl$(OLB) $(extobj) $(DBG)perlshr_xtras.ts Link /NoTrace$(LINKFLAGS)/Share=$(MMS$TARGET) $(extobj) []$(DBG)perlshr_bld.opt/Option, perlshr_attr.opt/Option --- 313,322 ---- $(DBG)perl$(E) : perlmain$(O), $(DBG)perlshr$(E), $(MINIPERL_EXE) @ @[.vms]genopt "PerlShr.Opt/Write" "|" "''F$Environment("Default")'$(DBG)PerlShr$(E)/Share" .ifdef gnuc ! Link $(LINKFLAGS)/Exe=$(MMS$TARGET) perlmain$(O), perlshr.opt/Option, perlshr_attr.opt/Option, crtl.opt/Option ! .else Link $(LINKFLAGS)/Exe=$(MMS$TARGET) perlmain$(O), perlshr.opt/Option, perlshr_attr.opt/Option + .endif $(DBG)perlshr$(E) : $(DBG)libperl$(OLB) $(extobj) $(DBG)perlshr_xtras.ts Link /NoTrace$(LINKFLAGS)/Share=$(MMS$TARGET) $(extobj) []$(DBG)perlshr_bld.opt/Option, perlshr_attr.opt/Option *************** *** 369,392 **** @ If F$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] @ $(MINIPERL) -e "use AutoSplit; autosplit_lib_modules(@ARGV)" [.lib]DynaLoader.pm ! Safe : [.lib]Safe.pm [.lib.auto.Safe]Safe$(E) @ $(NOOP) ! [.lib]Safe.pm : [.ext.Safe]Descrip.MMS @ If F$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] ! @ Set Default [.ext.Safe] $(MMS) @ Set Default [--] ! [.lib.auto.Safe]Safe$(E) : [.ext.Safe]Descrip.MMS ! @ Set Default [.ext.Safe] $(MMS) @ Set Default [--] # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C # ${@} necessary to distract different versions of MM[SK]/make ! [.ext.Safe]Descrip.MMS : [.ext.Safe]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm perlshr$(E) ! $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Safe]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" FileHandle : [.lib]FileHandle.pm [.lib.auto.FileHandle]FileHandle$(E) @ $(NOOP) --- 370,405 ---- @ If F$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] @ $(MINIPERL) -e "use AutoSplit; autosplit_lib_modules(@ARGV)" [.lib]DynaLoader.pm ! Opcode : [.lib]Opcode.pm [.lib]ops.pm [.lib]Safe.pm [.lib.auto.Opcode]Opcode$(E) @ $(NOOP) ! [.lib]Opcode.pm : [.ext.Opcode]Descrip.MMS @ If F$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] ! @ Set Default [.ext.Opcode] $(MMS) @ Set Default [--] ! [.lib]ops.pm : [.ext.Opcode]Descrip.MMS ! @ If F$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] ! @ Set Default [.ext.Opcode] ! $(MMS) ! @ Set Default [--] ! ! [.lib]Safe.pm : [.ext.Opcode]Descrip.MMS ! @ If F$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] ! @ Set Default [.ext.Opcode] ! $(MMS) ! @ Set Default [--] ! ! [.lib.auto.Opcode]Opcode$(E) : [.ext.Opcode]Descrip.MMS ! @ Set Default [.ext.Opcode] $(MMS) @ Set Default [--] # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C # ${@} necessary to distract different versions of MM[SK]/make ! [.ext.Opcode]Descrip.MMS : [.ext.Opcode]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) ! $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Opcode]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" FileHandle : [.lib]FileHandle.pm [.lib.auto.FileHandle]FileHandle$(E) @ $(NOOP) *************** *** 404,410 **** # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C # ${@} necessary to distract different versions of MM[SK]/make ! [.ext.FileHandle]Descrip.MMS : [.ext.FileHandle]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.FileHandle]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" Fcntl : [.lib]Fcntl.pm [.lib.auto.Fcntl]Fcntl$(E) --- 417,423 ---- # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C # ${@} necessary to distract different versions of MM[SK]/make ! [.ext.FileHandle]Descrip.MMS : [.ext.FileHandle]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.FileHandle]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" Fcntl : [.lib]Fcntl.pm [.lib.auto.Fcntl]Fcntl$(E) *************** *** 423,431 **** # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C # ${@} necessary to distract different versions of MM[SK]/make ! [.ext.Fcntl]Descrip.MMS : [.ext.Fcntl]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Fcntl]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" [.lib.VMS]Filespec.pm : [.vms.ext]Filespec.pm @ If F$Search("[.lib]VMS.Dir").eqs."" Then Create/Directory [.lib.VMS] Copy/Log/NoConfirm $(MMS$SOURCE) $(MMS$TARGET) --- 436,493 ---- # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C # ${@} necessary to distract different versions of MM[SK]/make ! [.ext.Fcntl]Descrip.MMS : [.ext.Fcntl]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.Fcntl]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" + IO : [.lib]IO.pm [.lib.IO]File.pm [.lib.IO]Handle.pm [.lib.IO]Pipe.pm [.lib.IO]Seekable.pm [.lib.IO]Socket.pm [.lib.auto.IO]IO$(E) + @ $(NOOP) + + [.lib]IO.pm : [.ext.IO]Descrip.MMS + @ If F$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] + @ Set Default [.ext.IO] + $(MMS) + @ Set Default [--] + + [.lib.IO]File.pm : [.ext.IO]Descrip.MMS + @ If F$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] + @ Set Default [.ext.IO] + $(MMS) + @ Set Default [--] + + [.lib.IO]Handle.pm : [.ext.IO]Descrip.MMS + @ If F$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] + @ Set Default [.ext.IO] + $(MMS) + @ Set Default [--] + + [.lib.IO]Pipe.pm : [.ext.IO]Descrip.MMS + @ If F$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] + @ Set Default [.ext.IO] + $(MMS) + @ Set Default [--] + + [.lib.IO]Seekable.pm : [.ext.IO]Descrip.MMS + @ If F$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] + @ Set Default [.ext.IO] + $(MMS) + @ Set Default [--] + + [.lib.IO]Socket.pm : [.ext.IO]Descrip.MMS + @ If F$Search("[.lib]auto.dir").eqs."" Then Create/Directory [.lib.auto] + @ Set Default [.ext.IO] + $(MMS) + @ Set Default [--] + + [.lib.auto.IO]IO$(E) : [.ext.IO]Descrip.MMS + @ Set Default [.ext.IO] + $(MMS) + @ Set Default [--] + + # Add "-I[--.lib]" t $(MINIPERL) so we use this copy of lib after C + # ${@} necessary to distract different versions of MM[SK]/make + [.ext.IO]Descrip.MMS : [.ext.IO]Makefile.PL $(ARCHDIR)Config.pm [.lib.VMS]Filespec.pm [.lib]DynaLoader.pm $(DBG)perlshr$(E) + $(MINIPERL) "-I[--.lib]" -e "chdir('[.ext.IO]') or die $!; do 'Makefile.PL'; print ${@} if ${@};" "INST_LIB=[--.lib]" "INST_ARCHLIB=[--.lib]" + [.lib.VMS]Filespec.pm : [.vms.ext]Filespec.pm @ If F$Search("[.lib]VMS.Dir").eqs."" Then Create/Directory [.lib.VMS] Copy/Log/NoConfirm $(MMS$SOURCE) $(MMS$TARGET) *************** *** 677,683 **** .endif test : all ! - @[.VMS]Test.Com # CORE subset for MakeMaker, so we can build Perl without sources # Should move to VMS installperl when we get one --- 739,745 ---- .endif test : all ! - @[.VMS]Test.Com "$(E)" # CORE subset for MakeMaker, so we can build Perl without sources # Should move to VMS installperl when we get one *************** *** 967,972 **** --- 1029,1057 ---- mg$(O) : sv.h mg$(O) : vmsish.h mg$(O) : util.h + universal$(O) : EXTERN.h + universal$(O) : av.h + universal$(O) : config.h + universal$(O) : cop.h + universal$(O) : cv.h + universal$(O) : embed.h + universal$(O) : form.h + universal$(O) : gv.h + universal$(O) : handy.h + universal$(O) : hv.h + universal$(O) : mg.h + universal$(O) : op.h + universal$(O) : opcode.h + universal$(O) : perl.h + universal$(O) : perly.h + universal$(O) : pp.h + universal$(O) : proto.h + universal$(O) : regexp.h + universal$(O) : scope.h + universal$(O) : sv.h + universal$(O) : vmsish.h + universal$(O) : util.h + universal$(O) : universal.c perl$(O) : EXTERN.h perl$(O) : av.h perl$(O) : config.h *************** *** 1442,1448 **** - If F$Search("Perlshr_Gbl*.Mar;-1") .nes."" Then Purge/NoConfirm/Log Perlshr_Gbl*.Mar - If F$Search("[.Ext.DynaLoader]DL_VMS$(O);-1").nes."" Then Purge/NoConfirm/Log [.Ext.DynaLoader]DL_VMS$(O) - If F$Search("[.Ext.DynaLoader]DL_VMS.C;-1").nes."" Then Purge/NoConfirm/Log [.Ext.DynaLoader]DL_VMS.C ! - If F$Search("[.Ext.Safe...];-1").nes."" Then Purge/NoConfirm/Log [.Ext.Safe] - If F$Search("[.Ext.FileHandle...];-1").nes."" Then Purge/NoConfirm/Log [.Ext.FileHandle] - If F$Search("[.VMS.Ext...]*.C;-1").nes."" Then Purge/NoConfirm/Log [.VMS.Ext...]*.C - If F$Search("[.VMS.Ext...]*$(O);-1").nes."" Then Purge/NoConfirm/Log [.VMS.Ext...]*$(O) --- 1527,1533 ---- - If F$Search("Perlshr_Gbl*.Mar;-1") .nes."" Then Purge/NoConfirm/Log Perlshr_Gbl*.Mar - If F$Search("[.Ext.DynaLoader]DL_VMS$(O);-1").nes."" Then Purge/NoConfirm/Log [.Ext.DynaLoader]DL_VMS$(O) - If F$Search("[.Ext.DynaLoader]DL_VMS.C;-1").nes."" Then Purge/NoConfirm/Log [.Ext.DynaLoader]DL_VMS.C ! - If F$Search("[.Ext.Opcode...];-1").nes."" Then Purge/NoConfirm/Log [.Ext.Opcode] - If F$Search("[.Ext.FileHandle...];-1").nes."" Then Purge/NoConfirm/Log [.Ext.FileHandle] - If F$Search("[.VMS.Ext...]*.C;-1").nes."" Then Purge/NoConfirm/Log [.VMS.Ext...]*.C - If F$Search("[.VMS.Ext...]*$(O);-1").nes."" Then Purge/NoConfirm/Log [.VMS.Ext...]*$(O) *************** *** 1465,1471 **** Set Default [.ext.FileHandle] - $(MMS) clean Set Default [--] ! Set Default [.ext.Safe] - $(MMS) clean Set Default [--] - If F$Search("*.Opt").nes."" Then Delete/NoConfirm/Log *.Opt;*/Exclude=PerlShr_*.Opt --- 1550,1559 ---- Set Default [.ext.FileHandle] - $(MMS) clean Set Default [--] ! Set Default [.ext.IO] ! - $(MMS) clean ! Set Default [--] ! Set Default [.ext.Opcode] - $(MMS) clean Set Default [--] - If F$Search("*.Opt").nes."" Then Delete/NoConfirm/Log *.Opt;*/Exclude=PerlShr_*.Opt *************** *** 1495,1507 **** Set Default [.ext.FileHandle] - $(MMS) realclean Set Default [--] ! Set Default [.ext.Safe] - $(MMS) realclean Set Default [--] - If F$Search("*$(OLB)").nes."" Then Delete/NoConfirm/Log *$(OLB);* - If F$Search("*.Opt").nes."" Then Delete/NoConfirm/Log *.Opt;* - $(MINIPERL) -e "use File::Path; rmtree(['lib/auto','lib/VMS','lib/$(ARCH)'],1,0);" - If F$Search("[.Lib]DynaLoader.pm").nes."" Then Delete/NoConfirm/Log [.Lib]DynaLoader.pm;* - If F$Search("[.Lib]Config.pm").nes."" Then Delete/NoConfirm/Log [.Lib]Config.pm;* - If F$Search("[.Lib]perlbug.").nes."" Then Delete/NoConfirm/Log [.Lib]perlbug.;* - If F$Search("$(ARCHDIR)Config.pm").nes."" Then Delete/NoConfirm/Log $(ARCHDIR)Config.pm;* --- 1583,1599 ---- Set Default [.ext.FileHandle] - $(MMS) realclean Set Default [--] ! Set Default [.ext.IO] ! - $(MMS) realclean ! Set Default [--] ! Set Default [.ext.Opcode] - $(MMS) realclean Set Default [--] - If F$Search("*$(OLB)").nes."" Then Delete/NoConfirm/Log *$(OLB);* - If F$Search("*.Opt").nes."" Then Delete/NoConfirm/Log *.Opt;* - $(MINIPERL) -e "use File::Path; rmtree(['lib/auto','lib/VMS','lib/$(ARCH)'],1,0);" - If F$Search("[.Lib]DynaLoader.pm").nes."" Then Delete/NoConfirm/Log [.Lib]DynaLoader.pm;* + - If F$Search("[.Lib]Socket.pm").nes."" Then Delete/NoConfirm/Log [.Lib]Socket.pm;* - If F$Search("[.Lib]Config.pm").nes."" Then Delete/NoConfirm/Log [.Lib]Config.pm;* - If F$Search("[.Lib]perlbug.").nes."" Then Delete/NoConfirm/Log [.Lib]perlbug.;* - If F$Search("$(ARCHDIR)Config.pm").nes."" Then Delete/NoConfirm/Log $(ARCHDIR)Config.pm;* #~ Document rmsexpand routine and move it to default export list diff -Pcr perl5_003/vms/ext/Filespec.pm perl5_003_01/vms/ext/Filespec.pm *** perl5_003/vms/ext/Filespec.pm Tue Feb 27 16:32:08 1996 --- perl5_003_01/vms/ext/Filespec.pm Tue Jun 25 09:50:23 1996 *************** *** 12,17 **** --- 12,18 ---- =head1 SYNOPSIS use VMS::Filespec; + $fullspec = rmsexpand('[.VMS]file.specification'); $vmsspec = vmsify('/my/Unix/file/specification'); $unixspec = unixify('my:[VMS]file.specification'); $path = pathify('my:[VMS.or.Unix.directory]specification.dir'); *************** *** 61,66 **** --- 62,75 ---- The routines provided are: + =head2 rmsexpand + + Uses the RMS $PARSE and $SEARCH services to expand the input + specification to its fully qualified form. (If the file does + not exist, the input specification is expanded as much as + possible.) If an error occurs, returns C and sets C<$!> + and C<$^E>. + =head2 vmsify Converts a file specification to VMS syntax. *************** *** 124,133 **** require Exporter; @ISA = qw( Exporter ); ! @EXPORT = qw( &vmsify &unixify &pathify &fileify ! &vmspath &unixpath &candelete); - @EXPORT_OK = qw( &rmsexpand ); 1; --- 133,141 ---- require Exporter; @ISA = qw( Exporter ); ! @EXPORT = qw( &vmsify &unixify &pathify &fileify ! &vmspath &unixpath &candelete &rmsexpand ); 1; *************** *** 142,148 **** # should be adequate for most purposes. # A sort-of sys$parse() replacement ! sub rmsexpand { my($fspec,$defaults) = @_; if (!$fspec) { return undef } my($node,$dev,$dir,$name,$type,$ver,$dnode,$ddev,$ddir,$dname,$dtype,$dver); --- 150,156 ---- # should be adequate for most purposes. # A sort-of sys$parse() replacement ! sub rmsexpand ($;$) { my($fspec,$defaults) = @_; if (!$fspec) { return undef } my($node,$dev,$dir,$name,$type,$ver,$dnode,$ddev,$ddir,$dname,$dtype,$dver); #~ Add tests for VMS-Unix file syntax conversion routines diff -Pcr perl5_003/vms/ext/filespec.t perl5_003_01/vms/ext/filespec.t *** perl5_003/vms/ext/filespec.t Wed Dec 31 19:00:00 1969 --- perl5_003_01/vms/ext/filespec.t Thu Jun 27 15:13:01 1996 *************** *** 0 **** --- 1,88 ---- + #!./perl + + use VMS::Filespec; + + foreach () { + chomp; + s/\s*#.*//; + next if /^\s*$/; + push(@tests,$_); + } + print '1..',scalar(@tests)+1,"\n"; + + foreach $test (@tests) { + ($arg,$func,$expect) = split(/\t+/,$test); + $idx++; + $rslt = eval "$func('$arg')"; + if ($@) { print "not ok $idx : eval error: $@\n"; next; } + else { + if ($rslt ne $expect) { + print "not ok $idx : $func('$arg') expected |$expect|, got |$rslt|\n"; + } + else { print "ok $idx\n"; } + } + } + + print +(rmsexpand('[]') eq "\U$ENV{DEFAULT}" ? 'ok ' : 'not ok '),++$idx,"\n"; + + __DATA__ + + # Basic VMS to Unix filespecs + some:[where.over]the.rainbow unixify /some/where/over/the.rainbow + [.some.where.over]the.rainbow unixify some/where/over/the.rainbow + [-.some.where.over]the.rainbow unixify ../some/where/over/the.rainbow + [.some.--.where.over]the.rainbow unixify some/../../where/over/the.rainbow + [] unixify ./ + [-] unixify ../ + [--] unixify ../../ + + # and back again + /some/where/over/the.rainbow vmsify some:[where.over]the.rainbow + some/where/over/the.rainbow vmsify [.some.where.over]the.rainbow + ../some/where/over/the.rainbow vmsify [-.some.where.over]the.rainbow + some/../../where/over/the.rainbow vmsify [-.where.over]the.rainbow + . vmsify [] + .. vmsify [-] + ../.. vmsify [--] + + # Fileifying directory specs + down:[the.garden.path] fileify down:[the.garden]path.dir;1 + [.down.the.garden.path] fileify [.down.the.garden]path.dir;1 + /down/the/garden/path fileify /down/the/garden/path.dir;1 + /down/the/garden/path/ fileify /down/the/garden/path.dir;1 + down/the/garden/path fileify down/the/garden/path.dir;1 + down:[the.garden]path fileify down:[the.garden]path.dir;1 + down:[the.garden]path. fileify # N.B. trailing . ==> null type + down:[the]garden.path fileify + /down/the/garden/path. fileify # N.B. trailing . ==> null type + /down/the/garden.path fileify + + # and pathifying them + down:[the.garden]path.dir;1 pathify down:[the.garden.path] + [.down.the.garden]path.dir pathify [.down.the.garden.path] + /down/the/garden/path.dir pathify /down/the/garden/path/ + down/the/garden/path.dir pathify down/the/garden/path/ + down:[the.garden]path pathify down:[the.garden.path] + down:[the.garden]path. pathify # N.B. trailing . ==> null type + down:[the]garden.path pathify + /down/the/garden/path. pathify # N.B. trailing . ==> null type + /down/the/garden.path pathify + down:[the.garden]path.dir;2 pathify #N.B. ;2 + path pathify path/ + path.notdir pathify + + # Both VMS/Unix and file/path conversions + down:[the.garden]path.dir;1 unixpath /down/the/garden/path/ + /down/the/garden/path vmspath down:[the.garden.path] + down:[the.garden.path] unixpath /down/the/garden/path/ + /down/the/garden/path.dir vmspath down:[the.garden.path] + [.down.the.garden]path.dir unixpath down/the/garden/path/ + down/the/garden/path vmspath [.down.the.garden.path] + path vmspath [.path] + + # Redundant characters in Unix paths + /some/where//over/./the.rainbow vmsify some:[where.over]the.rainbow + ..//../ vmspath [--] + ./././ vmspath [] + ./../. vmsify [-] + #~ Catch oddball global when using gcc diff -Pcr perl5_003/vms/gen_shrfls.pl perl5_003_01/vms/gen_shrfls.pl *** perl5_003/vms/gen_shrfls.pl Mon Mar 25 01:06:00 1996 --- perl5_003_01/vms/gen_shrfls.pl Thu Jul 18 17:37:13 1996 *************** *** 257,262 **** --- 257,270 ---- print STDERR "Unrecognized enum constant \"$_\" ignored\n"; } } + elsif ($isgcc) { + # gcc creates this as a SHR,WRT psect in globals.c, but we + # don't see it in the perl.h scan, since it's only declared + # if DOINIT is #defined. Bleah. It's cheaper to just add + # it by hand than to add /Define=DOINIT to the preprocessing + # run and wade through all the extra junk. + $vars{'Error'}++; + } # Eventually, we'll check against existing copies here, so we can add new # symbols to an existing options file in an upwardly-compatible manner. #~ Move several values up to initial set of declarations #~ Determine gcc version #~ Add several socket-dependent values #~ Add file-type values #~ Use names of shell vars corresponding to cpp manifests, rather then #~ the names of the manifests themselves #~ Add d_eunice value, since Configure equates it with VMS :-( #~ Eliminiate list of hand-configured values diff -Pcr perl5_003/vms/genconfig.pl perl5_003_01/vms/genconfig.pl *** perl5_003/vms/genconfig.pl Mon Mar 25 01:05:59 1996 --- perl5_003_01/vms/genconfig.pl Thu Jul 18 21:06:32 1996 *************** *** 6,14 **** # that went into your perl binary. In addition, values which change from run # to run may be supplied on the command line as key=val pairs. # ! # Rev. 13-Dec-1995 Charles Bailey bailey@genetics.upenn.edu # unshift(@INC,'lib'); # In case someone didn't define Perl_Root # before the build --- 6,22 ---- # that went into your perl binary. In addition, values which change from run # to run may be supplied on the command line as key=val pairs. # ! # Rev. 23-Apr-1996 Charles Bailey bailey@genetics.upenn.edu # + #==== Locations of installed Perl components + $prefix='perl_root'; + $builddir="$prefix:[000000]"; + $installbin="$prefix:[000000]"; + $installman1dir="$prefix:[man.man1]"; + $installman3dir="$prefix:[man.man3]"; + $installprivlib="$prefix:[lib]"; + unshift(@INC,'lib'); # In case someone didn't define Perl_Root # before the build *************** *** 37,42 **** --- 45,57 ---- open(OUT,">${outdir}Config.sh") || die "Can't open ${outdir}Config.sh: $!\n"; $time = localtime; + $cf_by = (getpwuid($<))[0]; + $archsufx = `Write Sys\$Output F\$GetSyi("HW_MODEL")` > 1024 ? 'AXP' : 'VAX'; + ($vers = $]) =~ tr/./_/; + $installarchlib = VMS::Filespec::vmspath($installprivlib); + $installarchlib =~ s#\]#.VMS_$archsufx.$vers\]#; + ($osvers = `Write Sys\$Output F\$GetSyi("VERSION")`) =~ s/^V?(\S+)\s*\n?$/$1/; + print OUT < 1024) { - print OUT "arch='VMS_AXP'\n"; - print OUT "archname='VMS_AXP'\n"; - $archsufx = "AXP"; - } - else { - print OUT "arch='VMS_VAX'\n"; - print OUT "archname='VMS_VAX'\n"; - $archsufx = 'VAX'; - } - $osvers = `Write Sys\$Output F\$GetSyi("VERSION")`; - $osvers =~ s/^V?(\S+)\s*\n?$/$1/; - print OUT "osvers='$osvers'\n"; foreach (@ARGV) { ($key,$val) = split('=',$_,2); if ($key eq 'cc') { # Figure out which C compiler we're using --- 78,102 ---- alignbytes='8' shrplib='define' usemymalloc='n' + usevfork='true' + useposix='false' spitshell='write sys\$output ' + dlsrc='dl_vms.c' + binexp='$installbin' + man1ext='rno' + man3ext='rno' + arch='VMS_$archsufx' + archname='VMS_$archsufx' + osvers='$osvers' + prefix='$prefix' + builddir='$builddir' + installbin='$installbin' + installman1dir='$installman1dir' + installman3dir='$installman3dir' + installprivlib='$installprivlib' + installarchlib='$installarchlib' EndOfIntro foreach (@ARGV) { ($key,$val) = split('=',$_,2); if ($key eq 'cc') { # Figure out which C compiler we're using *************** *** 95,103 **** $cctype = 'vaxc'; $d_attr = 'undef'; } ! elsif (`$val/NoObject/NoList _nla0:/Version` =~ /GNU/) { $cctype = 'gcc'; $d_attr = 'define'; } elsif ($archsufx eq 'VAX' && `$val/NoObject/NoList /prefix=all _nla0:` =~ /IVQUAL/) { --- 113,122 ---- $cctype = 'vaxc'; $d_attr = 'undef'; } ! elsif (`$val/NoObject/NoList _nla0:/Version` =~ /GNU C version (\S+)/) { $cctype = 'gcc'; $d_attr = 'define'; + print OUT "gccversion='$1'\n"; } elsif ($archsufx eq 'VAX' && `$val/NoObject/NoList /prefix=all _nla0:` =~ /IVQUAL/) { *************** *** 120,128 **** print OUT "ccflags='$ccflags'\n"; $dosock = ($ccflags =~ m!/DEF[^/]+VMS_DO_SOCKETS!i and $ccflags !~ m!/UND[^/]+VMS_DO_SOCKETS!i); next; } ! print OUT "$key=\'$val\'\n"; } # Are there any other logicals which TCP/IP stacks use for the host name? --- 139,160 ---- print OUT "ccflags='$ccflags'\n"; $dosock = ($ccflags =~ m!/DEF[^/]+VMS_DO_SOCKETS!i and $ccflags !~ m!/UND[^/]+VMS_DO_SOCKETS!i); + print OUT "d_vms_do_sockets=",$dosock ? "'define'\n" : "'undef'\n"; + print OUT "d_socket=",$dosock ? "'define'\n" : "'undef'\n"; + print OUT "d_sockpair=",$dosock ? "'define'\n" : "'undef'\n"; + print OUT "d_gethent=",$dosock ? "'define'\n" : "'undef'\n"; + print OUT "d_select=",$dosock ? "'define'\n" : "'undef'\n"; + print OUT "i_niin=",$dosock ? "'define'\n" : "'undef'\n"; + print OUT "i_neterrno=",$dosock ? "'define'\n" : "'undef'\n"; next; } ! elsif ($key eq 'exe_ext') { ! my($nodot) = $val; ! $nodot =~ s!\.!!; ! print OUT "so='$nodot'\ndlext='$nodot'\n"; ! } ! elsif ($key eq 'obj_ext') { print OUT "dlobj='dl_vms$val'\n"; } ! print OUT "$key='$val'\n"; } # Are there any other logicals which TCP/IP stacks use for the host name? *************** *** 152,157 **** --- 184,216 ---- $hwname = $archsufx if $hwname =~ /IVKEYW/; # *really* old VMS version print OUT "myuname='VMS $myname $osvers $hwname'\n"; + # Before we read the C header file, find out what config.sh constants are + # equivalent to the C preprocessor macros + if (open(SH,"${outdir}config_h.SH")) { + while () { + next unless m%^#(?!if).*\$%; + s/^#//; s!(.*?)\s*/\*.*!$1!; + my(@words) = split; + $words[1] =~ s/\(.*//; # Clip off args from macro + # Did we use a shell variable for the preprocessor directive? + if ($words[0] =~ m!^\$(\w+)!) { $pp_vars{$words[1]} = $1; } + if (@words > 2) { # We may also have a shell var in the value + shift @words; # Discard preprocessor directive + my($token) = shift @words; # and keep constant name + my($word); + foreach $word (@words) { + next unless $word =~ m!\$(\w+)!; + $val_vars{$token} = $1; + last; + } + } + } + close SH; + } + else { warn "Couldn't read ${outdir}config_h.SH: $!\n"; } + $pp_vars{UNLINK_ALL_VERSIONS} = 'd_unlink_all_versions'; # VMS_specific + + # OK, now read the C header file, and retcon statements into config.sh while () { # roll through the comment header in Config.VMS last if /config-start/; } *************** *** 165,218 **** s/^\s*//; $_ = $line . $_; } ! next unless my ($blocked,$un,$token,$val) = m%^(\/\*)?\s*\#\s*(un)?def\w*\s*([A-za-z0-9]\w+)\S*\s*(.*)%; ! next if /config-skip/; $state = ($blocked || $un) ? 'undef' : 'define'; ! $token =~ tr/A-Z/a-z/; ! $token =~ s/_exp$/exp/; # Config.pm has 'privlibexp' etc. where config.h ! # has 'privlib_exp' etc. ! # Fixup differences between Configure vars and config.h manifests ! # This isn't comprehensize; we fix 'em as we need 'em. ! $token = 'castneg' if $token eq 'castnegfloat'; ! $token = 'dlsymun' if $token eq 'dlsym_needs_underscore'; ! $token = 'stdstdio' if $token eq 'use_stdio_ptr'; ! $token = 'stdiobase' if $token eq 'use_stdio_base'; ! $val =~ s%/\*.*\*/\s*%%g; $val =~ s/\s*$//; # strip off trailing comment ! $val =~ s/^"//; $val =~ s/"$//; # remove end quotes ! $val =~ s/","/ /g; # make signal list look nice ! if ($val) { print OUT "$token=\'$val\'\n"; } ! else { $token = "d_$token" unless $token =~ /^i_/; print OUT "$token='$state'\n"; } } close IN; ! while () { ! next if /^\s*#/ or /^\s*$/; ! s/#.*$//; s/\s*$//; ! ($key,$val) = split('=',$_,2); ! print OUT "$key='$val'\n"; ! eval "\$$key = '$val'"; } - # Add in some of the architecture-dependent stuff which has to be consistent - print OUT "d_vms_do_sockets=",$dosock ? "'define'\n" : "'undef'\n"; - print OUT "d_has_sockets=",$dosock ? "'define'\n" : "'undef'\n"; - $archlib = &VMS::Filespec::vmspath($privlib); - $installarchlib = &VMS::Filespec::vmspath($installprivlib); - $sitearch = &VMS::Filespec::vmspath($sitelib); - $archlib =~ s#\]#.VMS_$archsufx\]#; - $sitearch =~ s#\]#.VMS_$archsufx\]#; - print OUT "oldarchlib='$archlib'\n"; - print OUT "oldarchlibexp='$archlib'\n"; - ($vers = $]) =~ tr/./_/; - $archlib =~ s#\]#.$vers\]#; - $installarchlib =~ s#\]#.VMS_$archsufx.$vers\]#; - print OUT "archlib='$archlib'\n"; - print OUT "archlibexp='$archlib'\n"; - print OUT "installarchlib='$installarchlib'\n"; - print OUT "sitearch='$sitearch'\n"; - print OUT "sitearchexp='$sitearch'\n"; if (open(OPT,"${outdir}crtl.opt")) { while () { --- 224,284 ---- s/^\s*//; $_ = $line . $_; } ! next unless my ($blocked,$un,$token,$val) = ! m%^(\/\*)?\s*\#\s*(un)?def\w*\s+([A-Za-z0-9]\w+)\S*\s*(.*)%; ! if (/config-skip/) { ! delete $pp_vars{$token} if exists $pp_vars{$token}; ! delete $val_vars{$token} if exists $val_vars{$token}; ! next; ! } ! $val =~ s!\s*/\*.*!!; # strip off trailing comment ! my($had_val); # Maybe a macro with args that we just #undefd or commented ! if (!length($val) and $val_vars{$token} and ($un || $blocked)) { ! print OUT "$val_vars{$token}=''\n"; ! delete $val_vars{$token}; ! $had_val = 1; ! } $state = ($blocked || $un) ? 'undef' : 'define'; ! if ($pp_vars{$token}) { ! print OUT "$pp_vars{$token}='$state'\n"; ! delete $pp_vars{$token}; ! } ! elsif (not length $val and not $had_val) { ! # Wups -- should have been shell var for C preprocessor directive ! warn "Constant $token not found in config_h.SH\n"; ! $token =~ tr/A-Z/a-z/; $token = "d_$token" unless $token =~ /^i_/; print OUT "$token='$state'\n"; } + next unless length $val; + $val =~ s/^"//; $val =~ s/"$//; # remove end quotes + $val =~ s/","/ /g; # make signal list look nice + # Library directory; convert to VMS syntax + $val = VMS::Filespec::vmspath($val) if ($token =~ /EXP$/); + if ($val_vars{$token}) { + print OUT "$val_vars{$token}='$val'\n"; + if ($val_vars{$token} =~ s/exp$//) {print OUT "$val_vars{$token}='$val'\n";} + delete $val_vars{$token}; + } + elsif (!$pp_vars{$token}) { # Haven't seen it previously, either + warn "Constant $token not found in config_h.SH (val=|$val|)\n"; + $token =~ tr/A-Z/a-z/; + print OUT "$token='$val'\n"; + if ($token =~ s/exp$//) {print OUT "$token='$val'\n";} + } } close IN; + # Special case -- preprocessor manifest "VMS" is defined automatically + # on VMS systems, but is also used erroneously by the Perl build process + # as the manifest for the obsolete variable $d_eunice. + print OUT "d_eunice='undef'\n"; delete $pp_vars{VMS}; ! foreach (sort keys %pp_vars) { ! warn "Didn't see $_ in $infile\n"; ! } ! foreach (sort keys %val_vars) { ! warn "Didn't see $_ in $infile(val)\n"; } if (open(OPT,"${outdir}crtl.opt")) { while () { *************** *** 237,243 **** } else { warn "Can't read ${outdir}patchlevel.h - skipping 'PATCHLEVEL'"; } ! # simple pager support for perldoc if (`most` =~ /IVVERB/) { $pager = 'more'; if (`more nl:` =~ /IVVERB/) { $pager = 'type/page'; } --- 303,309 ---- } else { warn "Can't read ${outdir}patchlevel.h - skipping 'PATCHLEVEL'"; } ! # simple pager support for perldoc if (`most` =~ /IVVERB/) { $pager = 'more'; if (`more nl:` =~ /IVVERB/) { $pager = 'type/page'; } *************** *** 246,281 **** print OUT "pager='$pager'\n"; close OUT; - __END__ - - # This list is incomplete in comparison to what ends up in config.sh, but - # should contain the essentials. Some of these definitions reflect - # options chosen when building perl or site-specific data; these should - # be hand-edited appropriately. Someday, perhaps, we'll get this automated. - - # The definitions in this block are constant across most systems, and - # should only rarely need to be changed. - ccdlflags= - cccdlflags= - usedl=true - dlobj=dl_vms.obj - dlsrc=dl_vms.c - so=exe - dlext=exe - libpth=/sys$share /sys$library - usevfork=false - castflags=0 - signal_t=void - timetype=long - builddir=perl_root:[000000] - prefix=perl_root - installprivlib=perl_root:[lib] # The *lib constants should match the - privlib=perl_root:[lib] # equivalent *(?:ARCH)LIB_EXP constants - sitelib=perl_root:[lib.site_perl] # in config.h - installbin=perl_root:[000000] - installman1dir=perl_root:[man.man1] - installman3dir=perl_root:[man.man3] - man1ext=rno - man3ext=rno - binexp=perl_root:[000000] # should be same as installbin - useposix=false --- 312,314 ---- #~ Fix type osver --> osvers diff -Pcr perl5_003/vms/myconfig.com perl5_003_01/vms/myconfig.com *** perl5_003/vms/myconfig.com Mon Mar 25 01:06:03 1996 --- perl5_003_01/vms/myconfig.com Thu Jul 11 10:09:33 1996 *************** *** 299,305 **** $ ECHO " " $ ECHO "Summary of my ''$package' (patchlevel ''$PATCHLEVEL' subversion ''$SUBVERSION') configuration:" $ ECHO " Platform:" ! $ ECHO " osname=''$osname', osver=''$osvers', archname=''$archname'" $ ECHO " uname=''$myuname'" !->d_has_uname? $ ECHO " hint=''$hint' d_sigaction='undef'" !->hintfile? $ ECHO " static exts=''$staticexts'" ! added for VMS --- 299,305 ---- $ ECHO " " $ ECHO "Summary of my ''$package' (patchlevel ''$PATCHLEVEL' subversion ''$SUBVERSION') configuration:" $ ECHO " Platform:" ! $ ECHO " osname=''$osname', osvers=''$osvers', archname=''$archname'" $ ECHO " uname=''$myuname'" !->d_has_uname? $ ECHO " hint=''$hint' d_sigaction='undef'" !->hintfile? $ ECHO " static exts=''$staticexts'" ! added for VMS #~ Mention VMS::Filespec routines in discussion of file syntax #~ Update documentation of binmode() -- now used as a hook for #~ disabling carriage control interpretation on record-structured files #~ Mention that the CORE "time" operator returns a Unix-like time diff -Pcr perl5_003/vms/perlvms.pod perl5_003_01/vms/perlvms.pod *** perl5_003/vms/perlvms.pod Mon Mar 25 01:06:06 1996 --- perl5_003_01/vms/perlvms.pod Thu Jul 25 16:21:20 1996 *************** *** 165,176 **** style file specifications wherever possible. You may use either style, or both, on the command line and in scripts, but you may not combine the two styles within a single fle ! specification. Filenames are, of course, still case- ! insensitive. For consistency, most Perl routines return ! filespecs using lower case letters only, regardless of the ! case used in the arguments passed to them. (This is true ! only when running under VMS; Perl respects the case- ! sensitivity of OSs like Unix.) We've tried to minimize the dependence of Perl library modules on Unix syntax, but you may find that some of these, --- 165,184 ---- style file specifications wherever possible. You may use either style, or both, on the command line and in scripts, but you may not combine the two styles within a single fle ! specification. VMS Perl interprets Unix pathnames in much ! the same way as the CRTL (I the first component of ! an absolute path is read as the device name for the ! VMS file specification). There are a set of functions ! provided in the C package for explicit ! interconversion between VMS and Unix syntax; its ! documentation provides more details. ! ! Filenames are, of course, still case-insensitive. For ! consistency, most Perl routines return filespecs using ! lower case letters only, regardless of the case used in ! the arguments passed to them. (This is true only when ! running under VMS; Perl respects the case-sensitivity ! of OSs like Unix.) We've tried to minimize the dependence of Perl library modules on Unix syntax, but you may find that some of these, *************** *** 351,359 **** =item binmode FILEHANDLE ! The C operator has no effect under VMS. It will ! return TRUE whenever called, but will not affect I/O ! operations on the filehandle given as its argument. =item crypt PLAINTEXT, USER --- 359,377 ---- =item binmode FILEHANDLE ! The C operator will attempt to insure that no translation ! of carriage control occurs on input from or output to this filehandle. ! Since this involves reopening the file and then restoring its ! file position indicator, if this function returns FALSE, the ! underlying filehandle may no longer point to an open file, or may ! point to a different position in the file than before C ! was called. ! ! Note that C is generally not necessary when using normal ! filehandles; it is provided so that you can control I/O to existing ! record-structured files when necessary. You can also use the ! C function in the VMS::Stdio extension to gain finer ! control of I/O to files and devices with different record structures. =item crypt PLAINTEXT, USER *************** *** 502,507 **** --- 520,531 ---- in the same fashion as typiing B at the DCL prompt. Perl waits for the subprocess to complete before continuing execution in the current process. + + =item time + + The value returned by C