This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
This is patch.2b1g to perl5.002beta1.
authorAndy Dougherty <doughera.lafayette.edu>
Thu, 21 Dec 1995 00:01:16 +0000 (00:01 +0000)
committerAndy Dougherty <doughera.lafayette.edu>
Thu, 21 Dec 1995 00:01:16 +0000 (00:01 +0000)
cd to your perl source directory, and type
patch -p1 -N < patch.2b1g

This patch is just my packaging of Tom's documentation patches
he released as patch.2b1g.

Patch and enjoy,

    Andy Dougherty doughera@lafcol.lafayette.edu
    Dept. of Physics
    Lafayette College, Easton PA 18042

74 files changed:
MANIFEST
ext/DB_File/DB_File.pm
ext/POSIX/POSIX.pm
ext/POSIX/POSIX.pod
ext/Safe/Makefile.PL [new file with mode: 0644]
ext/Safe/Safe.pm [new file with mode: 0644]
ext/Safe/Safe.xs [new file with mode: 0644]
ext/Socket/Socket.pm
installman
lib/AutoSplit.pm
lib/Cwd.pm
lib/Devel/SelfStubber.pm
lib/Env.pm
lib/Exporter.pm
lib/ExtUtils/Liblist.pm
lib/ExtUtils/MakeMaker.pm
lib/ExtUtils/Manifest.pm
lib/ExtUtils/Mkbootstrap.pm
lib/FileHandle.pm
lib/IPC/Open2.pm
lib/IPC/Open3.pm
lib/SelfLoader.pm
lib/Sys/Hostname.pm
lib/Sys/Syslog.pm
lib/Term/Cap.pm
lib/Term/Complete.pm
lib/Test/Harness.pm
lib/Text/Soundex.pm
lib/Text/Tabs.pm
lib/Text/Wrap.pm
lib/TieHash.pm
lib/Time/Local.pm
lib/less.pm
lib/overload.pm
lib/strict.pm
lib/syslog.pl
perl.c
pod/Makefile
pod/PerlDoc/Functions.pm [new file with mode: 0644]
pod/PerlDoc/Functions.pm.POSIX [new file with mode: 0644]
pod/buildtoc [new file with mode: 0644]
pod/perl.pod
pod/perlbot.pod
pod/perldata.pod
pod/perldiag.pod
pod/perldsc.pod
pod/perlembed.pod
pod/perlform.pod
pod/perlfunc.pod
pod/perlguts.pod
pod/perlipc.pod
pod/perllol.pod
pod/perlmod.pod
pod/perlobj.pod
pod/perlop.pod
pod/perlovl.pod
pod/perlpod.pod
pod/perlre.pod
pod/perlref.pod
pod/perlrun.pod
pod/perlsec.pod
pod/perlstyle.pod
pod/perlsub.pod
pod/perlsyn.pod
pod/perltie.pod [new file with mode: 0644]
pod/perltoc.pod [new file with mode: 0644]
pod/perltrap.pod
pod/perlvar.pod
pod/perlxs.pod
pod/perlxstut.pod
pod/pod2man.PL
pod/pod2text [new file with mode: 0644]
pod/roffitall [new file with mode: 0644]
pod/splitpod [new file with mode: 0644]

index 69370b5..45541d5 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -365,6 +365,8 @@ perly.h                     The header file for perly.c
 perly.y                        Yacc grammar for perl
 pl2pm                  A pl to pm translator
 pod/Makefile           Make pods into something else
+pod/PerlDoc/Functions.pm       used by splitpod
+pod/buildtoc           generate perltoc.pod
 pod/perl.pod           Top level perl man page
 pod/perlbook.pod       Book info
 pod/perlbot.pod                Object-oriented Bag o' Tricks
@@ -391,6 +393,7 @@ pod/perlsec.pod             Security info
 pod/perlstyle.pod      Style info
 pod/perlsub.pod                Subroutine info
 pod/perlsyn.pod                Syntax info
+pod/perltoc.pod                TOC info
 pod/perltrap.pod       Trap info
 pod/perlvar.pod                Variable info
 pod/perlxs.pod         XS api info
@@ -398,7 +401,10 @@ pod/perlxstut.pod  XS tutorial
 pod/pod2html.PL                Precursor for translator to turn pod into HTML
 pod/pod2latex.PL       Precursor for translator to turn pod into LaTeX
 pod/pod2man.PL         Precursor for translator to turn pod into manpage
+pod/pod2text           Precursor for translator to turn pod into text
+pod/roffitall          troff the whole man page set
 pod/splitman           Splits perlfunc into multiple man pages
+pod/splitpod           Splits perlfunc into multiple pod pages
 pp.c                   Push/Pop code
 pp.h                   Push/Pop code defs
 pp_ctl.c               Push/Pop code for control flow
index 55e5e9f..08463df 100644 (file)
@@ -528,25 +528,84 @@ Here is the output from the code above.
        untie @h ;
 
 
+=head2 Locking Databases
 
-=head1 CHANGES
+Concurrent access of a read-write database by several parties requires
+them all to use some kind of locking.  Here's an example of Tom's that
+uses the I<fd> method to get the file descriptor, and then a careful
+open() to give something Perl will flock() for you.  Run this repeatedly
+in the background to watch the locks granted in proper order.
 
-=head2 0.1
+    use Fcntl;
+    use DB_File;
+
+    use strict;
+
+    sub LOCK_SH { 1 }
+    sub LOCK_EX { 2 }
+    sub LOCK_NB { 4 }
+    sub LOCK_UN { 8 }
+
+    my($oldval, $fd, $db, %db, $value, $key);
+
+    $key = shift || 'default';
+    $value = shift || 'magic';
+
+    $value .= " $$";
+
+    $db = tie(%db, 'DB_File', '/tmp/foo.db', O_CREAT|O_RDWR, 0644) 
+           || die "dbcreat /tmp/foo.db $!";
+    $fd = $db->fd;
+    print "$$: db fd is $fd\n";
+    open(DB_FH, "+<&=$fd") || die "dup $!";
+
+
+    unless (flock (DB_FH, LOCK_SH | LOCK_NB)) {
+       print "$$: CONTENTION; can't read during write update!
+                   Waiting for read lock ($!) ....";
+       unless (flock (DB_FH, LOCK_SH)) { die "flock: $!" }
+    } 
+    print "$$: Read lock granted\n";
+
+    $oldval = $db{$key};
+    print "$$: Old value was $oldval\n";
+    flock(DB_FH, LOCK_UN);
+
+    unless (flock (DB_FH, LOCK_EX | LOCK_NB)) {
+       print "$$: CONTENTION; must have exclusive lock!
+                   Waiting for write lock ($!) ....";
+       unless (flock (DB_FH, LOCK_EX)) { die "flock: $!" }
+    } 
+
+    print "$$: Write lock granted\n";
+    $db{$key} = $value;
+    sleep 10;
+
+    flock(DB_FH, LOCK_UN);
+    untie %db;
+    close(DB_FH);
+    print "$$: Updated db to $key=$value\n";
+
+=head1 HISTORY
+
+=over
+
+=item 0.1
 
 First Release.
 
-=head2 0.2
+=item 0.2
 
 When B<DB_File> is opening a database file it no longer terminates the
 process if I<dbopen> returned an error. This allows file protection
 errors to be caught at run time. Thanks to Judith Grass
-<grass@cybercash.com> for spotting the bug.
+E<lt>grass@cybercash.comE<gt> for spotting the bug.
 
-=head2 0.3
+=item 0.3
 
 Added prototype support for multiple btree compare callbacks.
 
-=head2 1.0
+=item 1.0
 
 B<DB_File> has been in use for over a year. To reflect that, the
 version number has been incremented to 1.0.
@@ -556,7 +615,7 @@ Added complete support for multiple concurrent callbacks.
 Using the I<push> method on an empty list didn't work properly. This
 has been fixed.
 
-=head2 1.01
+=item 1.01
 
 Fixed a core dump problem with SunOS.
 
@@ -583,8 +642,10 @@ suggest any enhancements, I would welcome your comments.
 
 =head1 AVAILABILITY
 
-Berkeley DB is available via the hold C<ftp.cs.berkeley.edu> in the
-directory C</ucb/4bsd/db.tar.gz>.  It is I<not> under the GPL.
+Berkeley DB is available at your nearest CPAN archive (see
+L<perlmod/"CPAN"> for a list) in F<src/misc/db.1.85.tar.gz>, or via the
+host F<ftp.cs.berkeley.edu> in F</ucb/4bsd/db.tar.gz>.  It is I<not> under
+the GPL.
 
 =head1 SEE ALSO
 
index 2c397bb..ee35ea2 100644 (file)
@@ -830,17 +830,13 @@ sub umask {
 }
 
 sub wait {
-    usage "wait(statusvariable)" if @_ != 1;
-    local $result = wait();
-    $_[0] = $?;
-    $result;
+    usage "wait()" if @_ != 0;
+    wait();
 }
 
 sub waitpid {
-    usage "waitpid(pid, statusvariable, options)" if @_ != 3;
-    local $result = waitpid($_[0], $_[2]);
-    $_[1] = $?;
-    $result;
+    usage "waitpid(pid, options)" if @_ != 2;
+    waitpid($_[0], $_[1]);
 }
 
 sub gmtime {
index 654028e..2549a61 100644 (file)
@@ -2,6 +2,19 @@
 
 POSIX - Perl interface to IEEE Std 1003.1
 
+=head1 SYNOPSIS
+
+    use POSIX;
+    use POSIX qw(setsid);
+    use POSIX qw(:errno_h :fcntl_h);
+
+    printf "EINTR is %d\n", EINTR;
+
+    $sess_id = POSIX::setsid();
+
+    $fd = POSIX::open($path, O_CREAT|O_EXCL|O_WRONLY, 0644);
+       # note: that's a filedescriptor, *NOT* a filehandle
+
 =head1 DESCRIPTION
 
 The POSIX module permits you to access all (or nearly all) the standard
@@ -22,15 +35,6 @@ and other miscellaneous objects.  The remaining sections list various
 constants and macros in an organization which roughly follows IEEE Std
 1003.1b-1993.
 
-=head1 EXAMPLES
-
-    printf "EINTR is %d\n", EINTR;
-
-    $sess_id = POSIX::setsid();
-
-    $fd = POSIX::open($path, O_CREAT|O_EXCL|O_WRONLY, 0644);
-       # note: that's a filedescriptor, *NOT* a filehandle
-
 =head1 NOTE
 
 The POSIX module is probably the most complex Perl module supplied with
@@ -99,6 +103,7 @@ This is identical to the C function C<asin()>.
 
 =item assert
 
+Unimplemented.
 
 =item atan
 
@@ -158,6 +163,11 @@ This is identical to the C function C<clock()>.
 
 =item close
 
+Close the file.  This uses file descriptors such as those obtained by calling
+C<POSIX::open>.
+
+       $fd = POSIX::open( "foo", &POSIX::O_RDONLY );
+       POSIX::close( $fd );
 
 Returns C<undef> on failure.
 
@@ -175,10 +185,15 @@ This is identical to the C function C<cosh()>.
 
 =item creat
 
+Create a new file.  This returns a file descriptor like the ones returned by
+C<POSIX::open>.  Use C<POSIX::close> to close the file.
+
+       $fd = POSIX::creat( "foo", 0611 );
+       POSIX::close( $fd );
 
 =item ctermid
 
-Generates the path name for controlling terminal.
+Generates the path name for the controlling terminal.
 
        $path = POSIX::ctermid();
 
@@ -202,11 +217,19 @@ div() is C-specific.
 
 =item dup
 
+This is similar to the C function C<dup()>.
+
+This uses file descriptors such as those obtained by calling
+C<POSIX::open>.
 
 Returns C<undef> on failure.
 
 =item dup2
 
+This is similar to the C function C<dup2()>.
+
+This uses file descriptors such as those obtained by calling
+C<POSIX::open>.
 
 Returns C<undef> on failure.
 
@@ -310,6 +333,14 @@ This is identical to Perl's builtin C<fork()> function.
 
 =item fpathconf
 
+Retrieves the value of a configurable limit on a file or directory.  This
+uses file descriptors such as those obtained by calling C<POSIX::open>.
+
+The following will determine the maximum length of the longest allowable
+pathname on the filesystem which holds C</tmp/foo>.
+
+       $fd = POSIX::open( "/tmp/foo", &POSIX::O_RDONLY );
+       $path_max = POSIX::fpathconf( $fd, &POSIX::_PC_PATH_MAX );
 
 Returns C<undef> on failure.
 
@@ -339,6 +370,9 @@ freopen() is C-specific--use open instead.
 
 =item frexp
 
+Return the mantissa and exponent of a floating-point number.
+
+       ($mantissa, $exponent) = POSIX::frexp( 3.14 );
 
 =item fscanf
 
@@ -354,6 +388,12 @@ Use method C<FileHandle::setpos()> instead.
 
 =item fstat
 
+Get file status.  This uses file descriptors such as those obtained by
+calling C<POSIX::open>.  The data returned is identical to the data from
+Perl's builtin C<stat> function.
+
+       $fd = POSIX::open( "foo", &POSIX::O_RDONLY );
+       @stats = POSIX::fstat( $fd );
 
 =item ftell
 
@@ -441,9 +481,13 @@ This is identical to Perl's builtin C<gmtime()> function.
 
 =item isalnum
 
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
 
 =item isalpha
 
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
 
 =item isatty
 
@@ -452,30 +496,48 @@ to a tty.
 
 =item iscntrl
 
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
 
 =item isdigit
 
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
 
 =item isgraph
 
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
 
 =item islower
 
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
 
 =item isprint
 
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
 
 =item ispunct
 
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
 
 =item isspace
 
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
 
 =item isupper
 
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
 
 =item isxdigit
 
+This is identical to the C function, except that it can apply to a single
+character or to a whole string.
 
 =item kill
 
@@ -499,6 +561,32 @@ This is identical to Perl's builtin C<link()> function.
 
 =item localeconv
 
+Get numeric formatting information.  Returns a reference to a hash
+containing the current locale formatting values.
+
+The database for the B<de> (Deutsch or German) locale.
+
+       $loc = POSIX::setlocale( &POSIX::LC_ALL, "de" );
+       print "Locale = $loc\n";
+       $lconv = POSIX::localeconv();
+       print "decimal_point    = ", $lconv->{decimal_point},   "\n";
+       print "thousands_sep    = ", $lconv->{thousands_sep},   "\n";
+       print "grouping = ", $lconv->{grouping},        "\n";
+       print "int_curr_symbol  = ", $lconv->{int_curr_symbol}, "\n";
+       print "currency_symbol  = ", $lconv->{currency_symbol}, "\n";
+       print "mon_decimal_point = ", $lconv->{mon_decimal_point}, "\n";
+       print "mon_thousands_sep = ", $lconv->{mon_thousands_sep}, "\n";
+       print "mon_grouping     = ", $lconv->{mon_grouping},    "\n";
+       print "positive_sign    = ", $lconv->{positive_sign},   "\n";
+       print "negative_sign    = ", $lconv->{negative_sign},   "\n";
+       print "int_frac_digits  = ", $lconv->{int_frac_digits}, "\n";
+       print "frac_digits      = ", $lconv->{frac_digits},     "\n";
+       print "p_cs_precedes    = ", $lconv->{p_cs_precedes},   "\n";
+       print "p_sep_by_space   = ", $lconv->{p_sep_by_space},  "\n";
+       print "n_cs_precedes    = ", $lconv->{n_cs_precedes},   "\n";
+       print "n_sep_by_space   = ", $lconv->{n_sep_by_space},  "\n";
+       print "p_sign_posn      = ", $lconv->{p_sign_posn},     "\n";
+       print "n_sign_posn      = ", $lconv->{n_sign_posn},     "\n";
 
 =item localtime
 
@@ -518,6 +606,11 @@ longjmp() is C-specific: use die instead.
 
 =item lseek
 
+Move the read/write file pointer.  This uses file descriptors such as
+those obtained by calling C<POSIX::open>.
+
+       $fd = POSIX::open( "foo", &POSIX::O_RDONLY );
+       $off_t = POSIX::lseek( $fd, 0, &POSIX::SEEK_SET );
 
 Returns C<undef> on failure.
 
@@ -527,12 +620,15 @@ malloc() is C-specific.
 
 =item mblen
 
+This is identical to the C function C<mblen()>.
 
 =item mbstowcs
 
+This is identical to the C function C<mbstowcs()>.
 
 =item mbtowc
 
+This is identical to the C function C<mbtowc()>.
 
 =item memchr
 
@@ -560,19 +656,40 @@ This is identical to Perl's builtin C<mkdir()> function.
 
 =item mkfifo
 
+This is similar to the C function C<mkfifo()>.
 
 Returns C<undef> on failure.
 
 =item mktime
 
+Convert date/time info to a calendar time.
+
+Synopsis:
+
+       mktime(sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
+
+The month (C<mon>), weekday (C<wday>), and yearday (C<yday>) begin at zero.
+I.e. January is 0, not 1; Sunday is 0, not 1; January 1st is 0, not 1.  The
+year (C<year>) is given in years since 1900.  I.e. The year 1995 is 95; the
+year 2001 is 101.  Consult your system's C<mktime()> manpage for details
+about these and the other arguments.
+
+Calendar time for December 12, 1995, at 10:30 am.
+
+       $time_t = POSIX::mktime( 0, 30, 10, 12, 11, 95 );
+       print "Date = ", POSIX::ctime($time_t);
 
 Returns C<undef> on failure.
 
 =item modf
 
+Return the integral and fractional parts of a floating-point number.
+
+       ($fractional, $integral) = POSIX::modf( 3.14 );
 
 =item nice
 
+This is similar to the C function C<nice()>.
 
 Returns C<undef> on failure.
 
@@ -582,11 +699,36 @@ offsetof() is C-specific.
 
 =item open
 
+Open a file for reading for writing.  This returns file descriptors, not
+Perl filehandles.  Use C<POSIX::close> to close the file.
+
+Open a file read-only with mode 0666.
+
+       $fd = POSIX::open( "foo" );
+
+Open a file for read and write.
+
+       $fd = POSIX::open( "foo", &POSIX::O_RDWR );
+
+Open a file for write, with truncation.
+
+       $fd = POSIX::open( "foo", &POSIX::O_WRONLY | &POSIX::O_TRUNC );
+
+Create a new file with mode 0640.  Set up the file for writing.
+
+       $fd = POSIX::open( "foo", &POSIX::O_CREAT | &POSIX::O_WRONLY, 0640 );
 
 Returns C<undef> on failure.
 
 =item opendir
 
+Open a directory for reading.
+
+       $dir = POSIX::opendir( "/tmp" );
+       @files = POSIX::readdir( $dir );
+       POSIX::closedir( $dir );
+
+Returns C<undef> on failure.
 
 =item pathconf
 
@@ -611,6 +753,12 @@ This is identical to the C function C<perror()>.
 
 =item pipe
 
+Create an interprocess channel.  This returns file descriptors like those
+returned by C<POSIX::open>.
+
+       ($fd0, $fd1) = POSIX::pipe();
+       POSIX::write( $fd0, "hello", 5 );
+       POSIX::read( $fd1, $buf, 5 );
 
 =item pow
 
@@ -648,6 +796,12 @@ rand() is non-portable, use Perl's rand instead.
 
 =item read
 
+Read from a file.  This uses file descriptors such as those obtained by
+calling C<POSIX::open>.  If the buffer C<$buf> is not large enough for the
+read then Perl will extend it to make room for the request.
+
+       $fd = POSIX::open( "foo", &POSIX::O_RDONLY );
+       $bytes = POSIX::read( $fd, $buf, 3 );
 
 Returns C<undef> on failure.
 
@@ -701,6 +855,7 @@ The following will set the traditional UNIX system locale behavior.
 
 =item setpgid
 
+This is similar to the C function C<setpgid()>.
 
 Returns C<undef> on failure.
 
@@ -714,6 +869,13 @@ Sets the real user id for this process.
 
 =item sigaction
 
+Detailed signal management.  This uses C<POSIX::SigAction> objects for the
+C<action> and C<oldaction> arguments.  Consult your system's C<sigaction>
+manpage for details.
+
+Synopsis:
+
+       sigaction(sig, action, oldaction = 0)
 
 Returns C<undef> on failure.
 
@@ -723,11 +885,25 @@ siglongjmp() is C-specific: use die instead.
 
 =item sigpending
 
+Examine signals that are blocked and pending.  This uses C<POSIX::SigSet>
+objects for the C<sigset> argument.  Consult your system's C<sigpending>
+manpage for details.
+
+Synopsis:
+
+       sigpending(sigset)
 
 Returns C<undef> on failure.
 
 =item sigprocmask
 
+Change and/or examine calling process's signal mask.  This uses
+C<POSIX::SigSet> objects for the C<sigset> and C<oldsigset> arguments.
+Consult your system's C<sigprocmask> manpage for details.
+
+Synopsis:
+
+       sigprocmask(how, sigset, oldsigset = 0)
 
 Returns C<undef> on failure.
 
@@ -737,6 +913,13 @@ sigsetjmp() is C-specific: use eval {} instead.
 
 =item sigsuspend
 
+Install a signal mask and suspend process until signal arrives.  This uses
+C<POSIX::SigSet> objects for the C<signal_mask> argument.  Consult your
+system's C<sigsuspend> manpage for details.
+
+Synopsis:
+
+       sigsuspend(signal_mask)
 
 Returns C<undef> on failure.
 
@@ -754,6 +937,7 @@ This is identical to Perl's builtin C<sleep()> function.
 
 =item sprintf
 
+This is identical to Perl's builtin C<sprintf()> function.
 
 =item sqrt
 
@@ -801,6 +985,22 @@ Returns the error string for the specified errno.
 
 =item strftime
 
+Convert date and time information to string.  Returns the string.
+
+Synopsis:
+
+       strftime(fmt, sec, min, hour, mday, mon, year, wday = 0, yday = 0, isdst = 0)
+
+The month (C<mon>), weekday (C<wday>), and yearday (C<yday>) begin at zero.
+I.e. January is 0, not 1; Sunday is 0, not 1; January 1st is 0, not 1.  The
+year (C<year>) is given in years since 1900.  I.e. The year 1995 is 95; the
+year 2001 is 101.  Consult your system's C<strftime()> manpage for details
+about these and the other arguments.
+
+The string for Tuesday, December 12, 1995.
+
+       $str = POSIX::strftime( "%A, %B %d, %Y", 0, 0, 0, 12, 11, 95, 2 );
+       print "$str\n";
 
 =item strlen
 
@@ -852,6 +1052,9 @@ strtol() is C-specific.
 
 =item strxfrm
 
+String transformation.  Returns the transformed string.
+
+       $dst = POSIX::strxfrm( $src );
 
 =item sysconf
 
@@ -877,16 +1080,19 @@ This is identical to the C function C<tanh()>.
 
 =item tcdrain
 
+This is similar to the C function C<tcdrain()>.
 
 Returns C<undef> on failure.
 
 =item tcflow
 
+This is similar to the C function C<tcflow()>.
 
 Returns C<undef> on failure.
 
 =item tcflush
 
+This is similar to the C function C<tcflush()>.
 
 Returns C<undef> on failure.
 
@@ -896,11 +1102,13 @@ This is identical to the C function C<tcgetpgrp()>.
 
 =item tcsendbreak
 
+This is similar to the C function C<tcsendbreak()>.
 
 Returns C<undef> on failure.
 
 =item tcsetpgrp
 
+This is similar to the C function C<tcsetpgrp()>.
 
 Returns C<undef> on failure.
 
@@ -940,9 +1148,14 @@ This is identical to Perl's builtin C<uc()> function.
 
 =item ttyname
 
+This is identical to the C function C<ttyname()>.
 
 =item tzname
 
+Retrieves the time conversion information from the C<tzname> variable.
+
+       POSIX::tzset();
+       ($std, $dst) = POSIX::tzname();
 
 =item tzset
 
@@ -954,6 +1167,9 @@ This is identical to Perl's builtin C<umask()> function.
 
 =item uname
 
+Get name of current operating system.
+
+       ($sysname, $nodename, $release, $version, $machine ) = POSIX::uname();
 
 =item ungetc
 
@@ -981,18 +1197,32 @@ vsprintf() is C-specific.
 
 =item wait
 
+This is identical to Perl's builtin C<wait()> function.
 
 =item waitpid
 
+Wait for a child process to change state.  This is identical to Perl's
+builtin C<waitpid()> function.
+
+       $pid = POSIX::waitpid( -1, &POSIX::WNOHANG );
+       print "status = ", ($? / 256), "\n";
 
 =item wcstombs
 
+This is identical to the C function C<wcstombs()>.
 
 =item wctomb
 
+This is identical to the C function C<wctomb()>.
 
 =item write
 
+Write to a file.  This uses file descriptors such as those obtained by
+calling C<POSIX::open>.
+
+       $fd = POSIX::open( "foo", &POSIX::O_WRONLY );
+       $buf = "hello";
+       $bytes = POSIX::write( $b, $buf, 5 );
 
 Returns C<undef> on failure.
 
@@ -1006,50 +1236,119 @@ Returns C<undef> on failure.
 
 =item new
 
+Open a file and return a Perl filehandle.  The first parameter is the
+filename and the second parameter is the mode.  The mode should be specified
+as C<a> for append, C<w> for write, and E<lt> or C<""> for read.
+
+Open a file for reading.
+
+       $fh = FileHandle->new( "foo", "" );
+       die "Unable to open foo for reading" unless $fh;
+
+Open a file for writing.
+
+       $fh = FileHandle->new( "foo", "w" );
+       die "Unable to open foo for writing" unless $fh;
+
+Use C<FileHandle::close()> to close the file or let the FileHandle object's
+destructor perform the close.
 
 =item clearerr
 
+Resets the error indicator and EOF indicator to zero.
+
+       $fh->clearerr;
 
 =item close
 
+Close the file.
+
+       $fh->close;
 
 =item eof
 
+Tests for end of file.
+
+       if( $fh->eof ){
+               print "end of file\n";
+       }
 
 =item error
 
+Returns non-zero if there has been an error while reading or writing a file.
+
+       if( $fh->error ){
+               print "error\n";
+       }
 
 =item fileno
 
+Returns the integer file descriptor associated with the file.
+
+       $fileno = $fh->fileno;
 
 =item flush
 
+Flush the stream.
+
+       $fh->flush;
 
 Returns C<undef> on failure.
 
 =item getc
 
+Get a character from the stream.
+
+       $ch = $fh->getc;
 
 =item getpos
 
+Retrieve the file pointer position.  The returned value can be used as an
+argument to C<setpos()>.
+
+       $pos = $fh->getpos;
 
 =item gets
 
+Retrieve a line from the open file.
+
+       $line = $fh->gets;
 
 =item new_from_fd
 
+Open a file using a file descriptor.  Return a Perl filehandle.  The first
+parameter should be a file descriptor, which can come from C<POSIX::open()>.
+The second parameter, the mode, should be C<a> for append, C<w> for write,
+and E<lt> or C<""> for read.  The mode should match the mode which was used
+when the file descriptor was created.
+
+       $fd = POSIX::open( "typemap" );
+       $fh = FileHandle->new_from_fd( $fd, "<" );
+       die "FileHandle failed" unless $fh;
 
 =item new_tmpfile
 
+Creates a temporary file, opens it for writing, and returns a Perl
+filehandle.  Consult your system's C<tmpfile()> manpage for details.
+
+       $fh = FileHandle->new_tmpfile;
+       die "FileHandle failed" unless $fh;
 
 =item seek
 
+Reposition file pointer.
+
+       $fh->seek( 2, &POSIX::SEEK_SET );
 
 =item setbuf
 
 
 =item setpos
 
+Set the file pointer position.
+
+       $pos = $fh->getpos;
+       $fh->setpos( $pos );
 
 Returns C<undef> on failure.
 
@@ -1060,6 +1359,9 @@ Returns C<undef> on failure.
 
 =item tell
 
+Returns the current file position, in bytes.
+
+       $pos = $fh->tell;
 
 =item ungetc
 
@@ -1072,8 +1374,17 @@ Returns C<undef> on failure.
 
 =item new
 
-Creates a new SigAction object.  This object will be destroyed automatically
-when it is no longer needed.
+Creates a new C<POSIX::SigAction> object which corresponds to the C
+C<struct sigaction>.  This object will be destroyed automatically when it is
+no longer needed.  The first parameter is the fully-qualified name of a sub
+which is a signal-handler.  The second parameter is a C<POSIX::SigSet>
+object.  The third parameter contains the C<sa_flags>.
+
+       $sigset = POSIX::SigSet->new;
+       $sigaction = POSIX::SigAction->new( 'main::handler', $sigset, &POSIX::SA_NOCLDSTOP );
+
+This C<POSIX::SigAction> object should be used with the C<POSIX::sigaction()>
+function.
 
 =back
 
@@ -1150,6 +1461,15 @@ when it is no longer needed.
 
 =item getattr
 
+Get terminal control attributes.
+
+Obtain the attributes for stdin.
+
+       $termios->getattr()
+
+Obtain the attributes for stdout.
+
+       $termios->getattr( 1 )
 
 Returns C<undef> on failure.
 
@@ -1198,6 +1518,11 @@ Retrieve the output baud rate.
 
 =item setattr
 
+Set terminal control attributes.
+
+Set attributes immediately for stdout.
+
+       $termios->setattr( 1, &POSIX::TCSANOW );
 
 Returns C<undef> on failure.
 
@@ -1448,5 +1773,5 @@ WIFEXITED WEXITSTATUS WIFSIGNALED WTERMSIG WIFSTOPPED WSTOPSIG
 
 =head1 CREATION
 
-This document generated by mkposixman.PL version 951129.
+This document generated by ./mkposixman.PL version 19951212.
 
diff --git a/ext/Safe/Makefile.PL b/ext/Safe/Makefile.PL
new file mode 100644 (file)
index 0000000..414df14
--- /dev/null
@@ -0,0 +1,2 @@
+use ExtUtils::MakeMaker;
+WriteMakefile();
diff --git a/ext/Safe/Safe.pm b/ext/Safe/Safe.pm
new file mode 100644 (file)
index 0000000..dc2f9e9
--- /dev/null
@@ -0,0 +1,387 @@
+package Safe;
+require Exporter;
+require DynaLoader;
+use Carp;
+@ISA = qw(Exporter DynaLoader);
+@EXPORT_OK = qw(op_mask ops_to_mask mask_to_ops opcode opname
+               MAXO emptymask fullmask);
+
+=head1 NAME
+
+Safe - Safe extension module for Perl
+
+=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 share
+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 much 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.
+
+By default, the operator mask for a newly created compartment masks
+out all operations which give "access to the system" in some sense.
+This includes masking off operators such as I<system>, I<open>,
+I<chown>, and I<shmget> but does not mask off operators such as
+I<print>, I<sysread> and I<E<lt>HANDLE<gt>>. Those file operators
+are allowed since for the code in the compartment to have access
+to a filehandle, the code outside the compartment must have explicitly
+placed the filehandle variable inside the compartment.
+
+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
+
+=head2 Operator masks
+
+An operator mask exists at user-level as a string of bytes of length
+MAXO, each of which is either 0x00 or 0x01. Here, MAXO is the number
+of operators in the current version of perl. The subroutine MAXO()
+(available for export by package Safe) returns the number of operators
+in the current version of perl. Note that, unlike the beta versions of
+the Safe extension, this is a reliable count of the number of
+operators in the currently running perl executable. The presence of a
+0x01 byte at offset B<n> of the string indicates that operator number
+B<n> should be masked (i.e. disallowed).  The Safe extension makes
+available routines for converting from operator names to operator
+numbers (and I<vice versa>) and for converting from a list of operator
+names to the corresponding mask (and I<vice versa>).
+
+=head2 Methods in class Safe
+
+To create a new compartment, use
+
+    $cpt = new Safe;
+
+Optional arguments are (NAMESPACE, MASK), where
+
+=over 8
+
+=item NAMESPACE
+
+is the root namespace to use for the compartment (defaults to
+"Safe::Root000000000", auto-incremented for each new compartment); and
+
+=item MASK
+
+is the operator mask to use (defaults to a fairly restrictive set).
+
+=back
+
+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 root (NAMESPACE)
+
+This is a get-or-set method for the compartment's namespace. With the
+NAMESPACE argument present, it sets the root namespace for the
+compartment. With no NAMESPACE argument present, it returns the
+current root namespace of the compartment.
+
+=item mask (MASK)
+
+This is a get-or-set method for the compartment's operator mask.
+With the MASK argument present, it sets the operator mask for the
+compartment. With no MASK argument present, it returns the
+current operator mask of the compartment.
+
+=item trap (OP, ...)
+
+This sets bits in the compartment's operator mask corresponding
+to each operator named in the list of arguments. Each OP can be
+either the name of an operation or its number. See opcode.h or
+opcode.pl in the main perl distribution for a canonical list of
+operator names.
+
+=item untrap (OP, ...)
+
+This resets bits in the compartment's operator mask corresponding
+to each operator named in the list of arguments. Each OP can be
+either the name of an operation or its number. See opcode.h or
+opcode.pl in the main perl distribution for a canonical list of
+operator names.
+
+=item share (VARNAME, ...)
+
+This shares the variable(s) in the argument list with the compartment.
+Each VARNAME must be the B<name> of a variable with a leading type
+identifier included. Examples of legal variable names are '$foo' for
+a scalar, '@foo' for an array, '%foo' for a hash, '&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).
+
+=item varglob (VARNAME)
+
+This returns a glob for the symbol table entry of VARNAME in the package
+of the compartment. VARNAME must be the B<name> 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<root>
+method). Any attempt by code in STRING to use an operator which is
+in the compartment's mask 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<eval()>. Note that 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.
+
+=item rdo (FILENAME)
+
+This evaluates the contents of file FILENAME inside the compartment.
+See above documentation on the B<reval> method for further details.
+
+=back
+
+=head2 Subroutines in package Safe
+
+The Safe package contains subroutines for manipulating operator
+names and operator masks. All are available for export by the package.
+The canonical list of operator names is the contents of the array
+op_name defined and initialised in file F<opcode.h> of the Perl
+source distribution.
+
+=over 8
+
+=item ops_to_mask (OP, ...)
+
+This takes a list of operator names and returns an operator mask
+with precisely those operators masked.
+
+=item mask_to_ops (MASK)
+
+This takes an operator mask and returns a list of operator names
+corresponding to those operators which are masked in MASK.
+
+=item opcode (OP, ...)
+
+This takes a list of operator names and returns the corresponding
+list of opcodes (which can then be used as byte offsets into a mask).
+
+=item opname (OP, ...)
+
+This takes a list of opcodes and returns the corresponding list of
+operator names.
+
+=item fullmask
+
+This just returns a mask which has all operators masked.
+It returns the string "\1" x MAXO().
+
+=item emptymask
+
+This just returns a mask which has all operators unmasked.
+It returns the string "\0" x MAXO(). This is useful if you
+want a compartment to make use of the namespace protection
+features but do not want the default restrictive mask.
+
+=item MAXO
+
+This returns the number of operators (and hence the length of an
+operator mask). Note that, unlike the beta distributions of the
+Safe extension, this is derived from a genuine integer variable
+in the perl executable and not from a preprocessor constant.
+This means that the Safe extension is more robust in the presence
+of mismatched versions of the perl executable and the Safe extension.
+
+=item op_mask
+
+This returns the operator mask which is actually in effect at the
+time the invocation to the subroutine is compiled. In general,
+this is probably not terribly useful.
+
+=back
+
+=head2 AUTHOR
+
+Malcolm Beattie, mbeattie@sable.ox.ac.uk.
+
+=cut
+
+my $safes = "1111111111111111111111101111111111111111111111111111111111111111"
+         . "1111111111111111111111111111111111111111111111111111111111111111"
+         . "1111110011111111111011111111111111111111111111111111111101001010"
+         . "0110111111111111111111110011111111100001000000000000000000000100"
+         . "0000000000000111110000001111111110100000000000001111111111111111"
+         . "11111111111111111110";
+
+my $default_root = 'Safe::Root000000000';
+
+sub new {
+    my($class, $root, $mask) = @_;
+    my $obj = {};
+    bless $obj, $class;
+    $obj->root(defined($root) ? $root : $default_root++);
+    $obj->mask(defined($mask) ? $mask : $default_mask);
+    # 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->root . "::_"} = *_;
+    return $obj;
+}
+
+sub root {
+    my $obj = shift;
+    if (@_) {
+       $obj->{Root} = $_[0];
+    } else {
+       return $obj->{Root};
+    }
+}
+
+sub mask {
+    my $obj = shift;
+    if (@_) {
+       $obj->{Mask} = verify_mask($_[0]);
+    } else {
+       return $obj->{Mask};
+    }
+}
+
+sub verify_mask {
+    my($mask) = @_;
+    if (length($mask) != MAXO() || $mask !~ /^[\0\1]+$/) {
+       croak("argument is not a mask");
+    }
+    return $mask;
+}
+
+sub trap {
+    my $obj = shift;
+    $obj->setmaskel("\1", @_);
+}
+
+sub untrap {
+    my $obj = shift;
+    $obj->setmaskel("\0", @_);
+}
+
+sub emptymask { "\0" x MAXO() }
+sub fullmask { "\1" x MAXO() }
+
+sub setmaskel {
+    my $obj = shift;
+    my $val = shift;
+    croak("bad value for mask element") unless $val eq "\0" || $val eq "\1";
+    my $maskref = \$obj->{Mask};
+    my ($op, $opcode);
+    foreach $op (@_) {
+       $opcode = ($op =~ /^\d/) ? $op : opcode($op);
+       substr($$maskref, $opcode, 1) = $val;
+    }
+}
+
+sub share {
+    my $obj = shift;
+    my $root = $obj->root();
+    my ($arg);
+    foreach $arg (@_) {
+       my $var;
+       ($var = $arg) =~ s/^(.)//;
+       my $caller = caller;
+       *{$root."::$var"} = ($1 eq '$') ? \${$caller."::$var"}
+                         : ($1 eq '@') ? \@{$caller."::$var"}
+                         : ($1 eq '%') ? \%{$caller."::$var"}
+                         : ($1 eq '*') ? *{$caller."::$var"}
+                         : ($1 eq '&') ? \&{$caller."::$var"}
+                         : croak(qq(No such variable type for "$1$var"));
+    }
+}
+
+sub varglob {
+    my ($obj, $var) = @_;
+    return *{$obj->root()."::$var"};
+}
+
+sub reval {
+    my ($obj, $expr) = @_;
+    my $root = $obj->{Root};
+    my $mask = $obj->{Mask};
+    verify_mask($mask);
+
+    my $evalsub = eval sprintf(<<'EOT', $root);
+       package %s;
+       sub {
+           eval $expr;
+       }
+EOT
+    return safe_call_sv($root, $mask, $evalsub);
+}
+
+sub rdo {
+    my ($obj, $file) = @_;
+    my $root = $obj->{Root};
+    my $mask = $obj->{Mask};
+    verify_mask($mask);
+
+    $file =~ s/"/\\"/g; # just in case the filename contains any double quotes
+    my $evalsub = eval sprintf(<<'EOT', $root, $file);
+       package %s;
+       sub {
+           do "%s";
+       }
+EOT
+    return safe_call_sv($root, $mask, $evalsub);
+}
+
+bootstrap Safe;
+
+$safes .= "0" x (MAXO() - length($safes));
+($default_mask = $safes) =~ tr/01/\1\0/;       # invert for mask
+
+1;
diff --git a/ext/Safe/Safe.xs b/ext/Safe/Safe.xs
new file mode 100644 (file)
index 0000000..4437284
--- /dev/null
@@ -0,0 +1,113 @@
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+MODULE = Safe  PACKAGE = Safe
+
+void
+safe_call_sv(package, mask, codesv)
+       char *  package
+       SV *    mask
+       SV *    codesv
+    CODE:
+       int i;
+       char *str;
+       STRLEN len;
+
+       ENTER;
+       SAVETMPS;
+       save_hptr(&defstash);
+       save_aptr(&endav);
+       SAVEPPTR(op_mask);
+       Newz(666, op_mask, maxo, char);
+       SAVEFREEPV(op_mask);
+       str = SvPV(mask, len);
+       if (maxo != len)
+           croak("Bad mask length");
+       for (i = 0; i < maxo; i++)
+           op_mask[i] = str[i];
+       defstash = gv_stashpv(package, TRUE);
+       endav = (AV*)sv_2mortal((SV*)newAV()); /* Ignore END blocks for now */
+       GvHV(gv_fetchpv("main::", TRUE, SVt_PVHV)) = defstash;
+       PUSHMARK(sp);
+       i = perl_call_sv(codesv, G_SCALAR|G_EVAL|G_KEEPERR);
+       SPAGAIN;
+       ST(0) = i ? newSVsv(POPs) : &sv_undef;
+       PUTBACK;
+       FREETMPS;
+       LEAVE;
+       sv_2mortal(ST(0));
+
+void
+op_mask()
+    CODE:
+       ST(0) = sv_newmortal();
+       if (op_mask)
+           sv_setpvn(ST(0), op_mask, maxo);
+
+void
+mask_to_ops(mask)
+       SV *    mask
+    PPCODE:
+       STRLEN len;
+       char *maskstr = SvPV(mask, len);
+       int i;
+       if (maxo != len)
+           croak("Bad mask length");
+       for (i = 0; i < maxo; i++)
+           if (maskstr[i])
+               XPUSHs(sv_2mortal(newSVpv(op_name[i], 0)));
+
+void
+ops_to_mask(...)
+    CODE:
+       int i, j;
+       char *mask, *op;
+       Newz(666, mask, maxo, char);
+       for (i = 0; i < items; i++)
+       {
+           op = SvPV(ST(i), na);
+           for (j = 0; j < maxo && strNE(op, op_name[j]); j++) /* nothing */ ;
+           if (j < maxo)
+               mask[j] = 1;
+           else
+           {
+               Safefree(mask);
+               croak("bad op name \"%s\" in mask", op);
+           }
+       }
+       ST(0) = sv_newmortal();
+       sv_usepvn(ST(0), mask, maxo);
+
+void
+opname(...)
+    PPCODE:
+       int i, opcode;
+       for (i = 0; i < items; i++)
+       {
+           opcode = SvIV(ST(i));
+           if (opcode < 0 || opcode >= maxo)
+               croak("opcode out of range");
+           XPUSHs(sv_2mortal(newSVpv(op_name[opcode], 0)));
+       }
+
+void
+opcode(...)
+    PPCODE:
+       int i, j;
+       char *op;
+       for (i = 0; i < items; i++)
+       {
+           op = SvPV(ST(i), na);
+           for (j = 0; j < maxo && strNE(op, op_name[j]); j++) /* nothing */ ;
+           if (j == maxo)
+               croak("bad op name \"%s\"", op);
+           XPUSHs(sv_2mortal(newSViv(j)));
+       }
+
+int
+MAXO()
+    CODE:
+       RETVAL = maxo;
+    OUTPUT:
+       RETVAL
index 7f0943b..6462713 100644 (file)
@@ -3,8 +3,7 @@ $VERSION = 1.5;
 
 =head1 NAME
 
-Socket, sockaddr_in, sockaddr_un, inet_aton, inet_ntoa - load the C
-    socket.h defines and structure manipulators 
+Socket, sockaddr_in, sockaddr_un, inet_aton, inet_ntoa - load the C socket.h defines and structure manipulators 
 
 =head1 SYNOPSIS
 
index bc36ca6..aab0c22 100755 (executable)
@@ -74,7 +74,7 @@ sub runpod2man {
     # yet. (The user may have set the $install* Configure variables 
     # to point to some temporary home, from which the executable gets
     # installed by occult means.)
-    $pod2man = "../perl -I ../lib ../pod/pod2man";
+    $pod2man = "../perl -I ../lib ../pod/pod2man --section=$manext --official";
 
     &makedir($mandir);
     # Make a list of all the .pm and .pod files in the directory.  We will
@@ -89,8 +89,13 @@ sub runpod2man {
        $manpage =~ s#\.p(m|od)$##;
        $manpage =~ s#/#::#g;
        $manpage = "${mandir}/${manpage}.${manext}";
-       # Print $release $patchlevel stuff?  or should pod2man do that?
        &cmd("$pod2man $mod > $manpage");
+       if (-z $manpage) {
+           print STDERR "unlink $manpage\n";
+           unless ($notify) {
+               unlink($manpage) || warn "cannot unlink $manpage: $!";
+           } 
+       } 
     }
     chdir "$builddir" || die "Unable to cd back to $builddir directory!\n$!\n";
 }
@@ -116,9 +121,10 @@ sub cmd {
     local($cmd) = @_;
     print STDERR "  $cmd\n";
     unless ($notify) {
-       system $cmd;
-       warn "Command failed!!!\n" if $?;
+       fork ? wait : exec $cmd;
+       warn "Command failed!!\n" if $?;
     }
+    return $? != 0;
 }
 
 sub link {
index 46cf689..fd537bb 100644 (file)
@@ -14,6 +14,10 @@ use Carp;
 
 AutoSplit - split a package for autoloading
 
+=head1 SYNOPSIS
+
+ perl -e 'use AutoSplit; autosplit_modules(@ARGV)'  ...
+
 =head1 DESCRIPTION
 
 This function will split up your program into files that the AutoLoader
index 2636fd2..a627354 100644 (file)
@@ -31,7 +31,7 @@ getcwd - get pathname of current working directory
 The getcwd() function re-implements the getcwd(3) (or getwd(3)) functions
 in Perl.
 
-The fastgetcwd() function looks the same as getcwd(), but runs faster.
+The fastcwd() function looks the same as getcwd(), but runs faster.
 It's also more dangerous because you might conceivably chdir() out of a
 directory that you can't chdir() back into.
 
index 1b5e575..0a8caad 100644 (file)
@@ -60,6 +60,7 @@ sub stub {
 
 1;
 __END__
+
 =head1 NAME
 
 Devel::SelfStubber - generate stubs for a SelfLoading module
index 2187090..0e79075 100644 (file)
@@ -2,7 +2,12 @@ package Env;
 
 =head1 NAME
 
-Env - Perl module that imports environment variables
+Env - perl module that imports environment variables
+
+=head1 SYNOPSIS
+
+    use Env;
+    use Env qw(PATH HOME TERM);
 
 =head1 DESCRIPTION
 
index 8c4368c..382ee85 100644 (file)
@@ -1,6 +1,15 @@
 package Exporter;
 
-=head1 Comments
+=head1 NAME
+
+Exporter - provide inport/export controls for Perl modules
+
+=head1 SYNOPSIS
+
+use Module;
+use Module qw(name1 name2 :tag /pattern/ !name);
+
+=head1 DESCRIPTION
 
 If the first entry in an import list begins with !, : or / then the
 list is treated as a series of specifications which either add to or
index 53eb032..ebb2536 100644 (file)
@@ -171,6 +171,7 @@ sub lsdir { #yes, duplicate code seems less hassle than having an
 
 1;
 __END__
+
 =head1 NAME
 
 ExtUtils::Liblist - determine libraries to use and how to use them
index 5de54c6..6aae816 100644 (file)
@@ -56,10 +56,10 @@ sub warndirectuse {
 
 package ExtUtils::MakeMaker;
 
-# Last edited $Date: 1995/12/05 18:20:28 $ by Andreas Koenig
-# $Id: MakeMaker.pm,v 1.115 1995/12/05 18:20:28 k Exp $
+# Last edited $Date: 1995/12/10 23:38:09 $ by Andreas Koenig
+# $Id: MakeMaker.pm,v 1.116 1995/12/10 23:38:09 k Exp $
 
-$Version = $VERSION = "5.11";
+$Version = $VERSION = "5.12";
 
 $ExtUtils::MakeMaker::Version_OK = 4.13;       # Makefiles older than $Version_OK will die
                        # (Will be checked from MakeMaker version 4.13 onwards)
@@ -993,7 +993,7 @@ EOM
     # version compatibility between the *.pm file and the
     # corresponding *.xs file. The bottomline was, that we need an
     # XS_VERSION macro that defaults to VERSION:
-    $self->{XS_VERSION} ||= $self->{VERSION};
+    $self->{XS_VERSION} ||= $self->{VERSION};
 
     # --- Initialize Perl Binary Locations
 
@@ -1132,25 +1132,27 @@ sub init_dirscan {      # --- File and Directory Lists (.xs .pm .pod etc)
        $self->{MAN1PODS} = {};
     } else {
        my %manifypods = ();
-       foreach $name (@{$self->{EXE_FILES}}) {
-           local(*TESTPOD);
-           my($ispod)=0;
-           if (open(TESTPOD,"<$name")) {
-               my $testpodline;
-               while ($testpodline = <TESTPOD>) {
-                   if($testpodline =~ /^=head/) {
-                       $ispod=1;
-                       last;
+       if( exists $self->{EXE_FILES} ){
+               foreach $name (@{$self->{EXE_FILES}}) {
+                   local(*TESTPOD);
+                   my($ispod)=0;
+                   if (open(TESTPOD,"<$name")) {
+                       my $testpodline;
+                       while ($testpodline = <TESTPOD>) {
+                           if($testpodline =~ /^=head/) {
+                               $ispod=1;
+                               last;
+                           }
+                       }
+                       close(TESTPOD);
+                   } else {
+                       # If it doesn't exist yet, we assume, it has pods in it
+                       $ispod = 1;
+                   }
+                   if( $ispod ) {
+                       $manifypods{$name} = $self->catdir('$(INST_MAN1DIR)',basename($name).'.$(MAN1EXT)');
                    }
                }
-               close(TESTPOD);
-           } else {
-               # If it doesn't exist yet, we assume, it has pods in it
-               $ispod = 1;
-           }
-           if( $ispod ) {
-               $manifypods{$name} = $self->catdir('$(INST_MAN1DIR)',basename($name).'.$(MAN1EXT)');
-           }
        }
 
        $self->{MAN1PODS} = \%manifypods;
@@ -1241,7 +1243,10 @@ sub init_others {        # --- Initialize Other Attributes
     # Compute EXTRALIBS, BSLOADLIBS and LDLOADLIBS from $self->{LIBS}
     # Lets look at $self->{LIBS} carefully: It may be an anon array, a string or
     # undefined. In any case we turn it into an anon array:
-    $self->{LIBS}=[] unless $self->{LIBS};
+
+    # May check $Config{libs} too, thus not empty.
+    $self->{LIBS}=[''] unless $self->{LIBS}; 
+
     $self->{LIBS}=[$self->{LIBS}] if ref \$self->{LIBS} eq SCALAR;
     $self->{LD_RUN_PATH} = "";
     my($libs);
@@ -1288,7 +1293,7 @@ sub init_others { # --- Initialize Other Attributes
     $self->{UMASK_NULL} = "umask 0";
 }
 
-sub find_perl{
+sub find_perl {
     my($self, $ver, $names, $dirs, $trace) = @_;
     unless (ref $self){
        ExtUtils::MakeMaker::TieAtt::warndirectuse((caller(0))[3]);
@@ -1306,10 +1311,10 @@ in these dirs:
        next unless defined $dir; # $self->{PERL_SRC} may be undefined
        foreach $name (@$names){
            my $abs;
-           if ($name =~ m|^/|) {
+           if ($self->file_name_is_absolute($name)) {
                $abs = $name;
-           } elsif ($name =~ m|/|) {
-               $abs = $self->catfile(".", $name); # not absolute
+           } elsif ($name =~ m|/|) { # file_name_contains_path
+               $abs = $self->catfile(".", $name);
            } else {
                $abs = $self->catfile($dir, $name);
            }
@@ -1366,6 +1371,12 @@ sub maybe_command {
     return;
 }
 
+sub perl_script {
+    my($self,$file) = @_;
+    return 1 if -r $file && ! -d $file;
+    return;
+}
+
 # Ilya's suggestion, not yet used
 sub file_name_is_absolute {
     my($self,$file) = @_;
@@ -1421,9 +1432,9 @@ VERSION = $self->{VERSION}
 VERSION_SYM = $self->{VERSION_SYM}
 VERSION_MACRO = VERSION
 DEFINE_VERSION = -D\$(VERSION_MACRO)=\\\"\$(VERSION)\\\"
-XS_VERSION = $self->{XS_VERSION}
-XS_VERSION_MACRO = XS_VERSION
-XS_DEFINE_VERSION = -D\$(XS_VERSION_MACRO)=\\\"\$(XS_VERSION)\\\"
+XS_VERSION = $self->{XS_VERSION}
+XS_VERSION_MACRO = XS_VERSION
+XS_DEFINE_VERSION = -D\$(XS_VERSION_MACRO)=\\\"\$(XS_VERSION)\\\"
 
 # In which directory should we put this extension during 'make'?
 # This is typically ./blib.
@@ -2286,7 +2297,7 @@ sub manifypods {
     } else {
        $pod2man_exe = "$Config{bin}/pod2man";
     }
-    unless ($self->maybe_command($pod2man_exe)) {
+    unless ($self->perl_script($pod2man_exe)) {
        # No pod2man but some MAN3PODS to be installed
        print <<END;
 
@@ -2338,6 +2349,7 @@ $self->{PL_FILES}->{$plfile} :: $plfile
 sub installbin {
     my($self) = shift;
     return "" unless $self->{EXE_FILES} && ref $self->{EXE_FILES} eq "ARRAY";
+    return "" unless @{$self->{EXE_FILES}};
     my(@m, $from, $to, %fromto, @to);
     push @m, $self->dir_target(qw[$(INST_EXE)]);
     for $from (@{$self->{EXE_FILES}}) {
@@ -2615,7 +2627,7 @@ doc_install ::
        @ echo Appending installation info to $(INSTALLARCHLIB)/perllocal.pod
        @ $(PERL) -I$(INST_ARCHLIB) -I$(INST_LIB) -I$(PERL_ARCHLIB) -I$(PERL_LIB)  \\
                -e "use ExtUtils::MakeMaker; MY->new({})->writedoc('Module', '$(NAME)', \\
-               'LINKTYPE=$(LINKTYPE)', 'VERSION=$(VERSION)', 'XS_VERSION=$(XS_VERSION)', \\
+               'LINKTYPE=$(LINKTYPE)', 'VERSION=$(VERSION)', \\
                'EXE_FILES=$(EXE_FILES)')" >> $(INSTALLARCHLIB)/perllocal.pod
 };
 
@@ -3921,11 +3933,6 @@ May be set to an empty string, which is identical to C<-prototypes>, or
 C<-noprototypes>. See the xsubpp documentation for details. MakeMaker
 defaults to the empty string.
 
-=item XS_VERSION
-
-Your version number for the XS part of your extension.  This defaults
-to S(VERSION).
-
 =back
 
 =head2 Additional lowercase attributes
index 1c54c77..4d18cbe 100644 (file)
@@ -27,7 +27,8 @@ C<ExtUtils::Manifest::manicopy($read,$target,$how);>
 =head1 DESCRIPTION
 
 Mkmanifest() writes all files in and below the current directory to a
-file named C<MANIFEST> in the current directory. It works similar to
+file named in the global variable $ExtUtils::Manifest::MANIFEST (which
+defaults to C<MANIFEST>) in the current directory. It works similar to
 
     find . -print
 
@@ -89,6 +90,17 @@ expressions should appear one on each line. A typical example:
 C<&mkmanifest>, C<&manicheck>, C<&filecheck>, C<&fullcheck>,
 C<&maniread>, and C<&manicopy> are exportable.
 
+=head1 GLOBAL VARIABLES
+
+C<$ExtUtils::Manifest::MANIFEST> defaults to C<MANIFEST>. Changing it
+results in both a different C<MANIFEST> and a different
+C<MANIFEST.SKIP> file. This is useful if you want to maintain
+different distributions for different audiences (say a user version
+and a developer version including RCS).
+
+<$ExtUtils::Manifest::Quiet> defaults to 0. If set to a true value,
+all functions act silently.
+
 =head1 DIAGNOSTICS
 
 All diagnostic output is sent to C<STDERR>.
@@ -117,6 +129,10 @@ to MANIFEST. $Verbose is set to 1 by default.
 
 =back
 
+=head1 SEE ALSO
+
+L<ExtUtils::MakeMaker> which has handy targets for most of the functionality.
+
 =head1 AUTHOR
 
 Andreas Koenig F<E<lt>koenig@franz.ww.TU-Berlin.DEE<gt>>
@@ -136,10 +152,12 @@ $Debug = 0;
 $Verbose = 1;
 $Is_VMS = $Config{'osname'} eq 'VMS';
 
-$VERSION = $VERSION = substr(q$Revision: 1.17 $,10,4);
+$VERSION = $VERSION = substr(q$Revision: 1.18 $,10,4);
 
 $Quiet = 0;
 
+$MANIFEST = 'MANIFEST';
+
 # Really cool fix from Ilya :)
 unless (defined $Config{d_link}) {
     *ln = \&cp;
@@ -150,8 +168,8 @@ sub mkmanifest {
     my $read = maniread() or $manimiss++;
     $read = {} if $manimiss;
     local *M;
-    rename "MANIFEST", "MANIFEST.bak" unless $manimiss;
-    open M, ">MANIFEST" or die "Could not open MANIFEST: $!";
+    rename $MANIFEST, "$MANIFEST.bak" unless $manimiss;
+    open M, ">$MANIFEST" or die "Could not open $MANIFEST: $!";
     my $matches = _maniskip();
     my $found = manifind();
     my($key,$val,$file,%all);
@@ -159,7 +177,7 @@ sub mkmanifest {
     foreach $file (sort keys %all) {
        next if &$matches($file);
        if ($Verbose){
-           warn "Added to MANIFEST: $file\n" unless exists $read->{$file};
+           warn "Added to $MANIFEST: $file\n" unless exists $read->{$file};
        }
        my $text = $all{$file};
        ($file,$text) = split(/\s+/,$text,2) if $Is_VMS;
@@ -205,7 +223,7 @@ sub _manicheck {
     if ($arg & 1){
        my $found = manifind();
        foreach $file (sort keys %$read){
-           warn "Debug: manicheck checking from MANIFEST $file\n" if $Debug;
+           warn "Debug: manicheck checking from $MANIFEST $file\n" if $Debug;
            unless ( exists $found->{$file} ) {
                warn "No such file: $file\n" unless $Quiet;
                push @missfile, $file;
@@ -224,7 +242,7 @@ sub _manicheck {
            }
            warn "Debug: manicheck checking from disk $file\n" if $Debug;
            unless ( exists $read->{$file} ) {
-               warn "Not in MANIFEST: $file\n" unless $Quiet;
+               warn "Not in $MANIFEST: $file\n" unless $Quiet;
                push @missentry, $file;
            }
        }
@@ -234,7 +252,7 @@ sub _manicheck {
 
 sub maniread {
     my ($mfile) = @_;
-    $mfile = "MANIFEST" unless defined $mfile;
+    $mfile = $MANIFEST unless defined $mfile;
     my $read = {};
     local *M;
     unless (open M, $mfile){
@@ -255,7 +273,7 @@ sub _maniskip {
     my ($mfile) = @_;
     my $matches = sub {0};
     my @skip ;
-    my $mfile = "MANIFEST.SKIP" unless defined $mfile;
+    my $mfile = "$MANIFEST.SKIP" unless defined $mfile;
     local *M;
     return $matches unless -f $mfile;
     open M, $mfile or return $matches;
index a074bb1..5710985 100644 (file)
@@ -7,12 +7,17 @@ $Version=2.0; # just to start somewhere
 
 sub Mkbootstrap {
 
-=head1 USEFUL SUBROUTINES
+=head1 NAME
 
-=head2 Mkbootstrap()
+Mkbootstrap - make a bootstrap file for use by DynaLoader
 
-Make a bootstrap file for use by this system's DynaLoader.  It
-typically gets called from an extension Makefile.
+=head1 SYNOPSIS
+
+C<mkbootstrap>
+
+=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
@@ -20,15 +25,14 @@ 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 Andy's
-extliblist script. If this array still is empty, we do nothing, else
-we write a .bs file with an C<@DynaLoader::dl_resolve_using> array, but
-without any C<if>s, because there is no longer a need to deal with
-special cases.
-
-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.
+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
index 9408717..cbc6efb 100644 (file)
@@ -2,7 +2,7 @@ package FileHandle;
 
 # Note that some additional FileHandle methods are defined in POSIX.pm.
 
-=head1 NAME 
+=head1 NAME
 
 FileHandle - supply object methods for filehandles
 
@@ -21,7 +21,6 @@ cacheout - keep more files open than the system permits
 See L<perlvar> for complete descriptions of each of the following supported C<FileHandle> 
 methods:
 
-    print
     autoflush
     output_field_separator
     output_record_separator
@@ -35,15 +34,55 @@ methods:
     format_line_break_characters
     format_formfeed
 
+Furthermore, for doing normal I/O you might need these:
+
+=over 
+
+=item $fh->print
+
+See L<perlfunc/print>.
+
+=item $fh->printf
+
+See L<perlfunc/printf>.
+
+=item $fh->getline
+
+This works like <$fh> described in L<perlop/"I/O Operators"> 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
+
+=head2 The cacheout() Library
+
 The cacheout() function will make sure that there's a filehandle
 open for writing available as the pathname you give it.  It automatically
 closes and re-opens files if you exceed your system file descriptor maximum.
 
+=head1 SEE ALSO
+
+L<perlfunc>, 
+L<perlop/"I/O Operators">,
+L<POSIX/"FileHandle">
+
 =head1 BUGS
 
 F<sys/param.h> lies with its C<NOFILE> define on some systems,
 so you may have to set $cacheout::maxopen yourself.
 
+Some of the methods that set variables (like format_name()) don't
+seem to work.
+
+The POSIX functions that create FileHandle methods should be
+in this module instead.
+
 Due to backwards compatibility, all filehandles resemble objects
 of class C<FileHandle>, or actually classes derived from that class.
 They actually aren't.  Which means you can't derive your own 
@@ -53,11 +92,11 @@ class from C<FileHandle> and inherit those methods.
 
 require 5.000;
 use English;
+use Carp;
 use Exporter;
 
 @ISA = qw(Exporter);
 @EXPORT = qw(
-    print
     autoflush
     output_field_separator
     output_record_separator
@@ -70,6 +109,12 @@ use Exporter;
     format_top_name
     format_line_break_characters
     format_formfeed
+
+    print
+    printf
+    getline
+    getlines
+
     cacheout
 );
 
@@ -78,6 +123,24 @@ sub print {
     print $this @_;
 }
 
+sub printf {
+    local($this) = shift;
+    printf $this @_;
+}
+
+sub getline {
+    local($this) = shift;
+    croak "usage: FileHandle::getline()" if @_;
+    return scalar <$this>;
+} 
+
+sub getlines {
+    local($this) = shift;
+    croak "usage: FileHandle::getline()" if @_;
+    croak "can't call FileHandle::getlines in a scalar context" if wantarray;
+    return <$this>;
+} 
+
 sub autoflush {
     local($old) = select($_[0]);
     local($prev) = $OUTPUT_AUTOFLUSH;
index 71f89f3..1ac963a 100644 (file)
@@ -10,9 +10,9 @@ IPC::Open2, open2 - open a process for both reading and writing
 =head1 SYNOPSIS
 
     use IPC::Open2;
-    $pid = open2('rdr', 'wtr', 'some cmd and args');
+    $pid = open2(\*RDR, \*WTR, 'some cmd and args');
       # or
-    $pid = open2('rdr', 'wtr', 'some', 'cmd', 'and', 'args');
+    $pid = open2(\*RDR, \*WTR, 'some', 'cmd', 'and', 'args');
 
 =head1 DESCRIPTION
 
@@ -39,7 +39,7 @@ however, are quite apt to cause deadlock.
 
 The big problem with this approach is that if you don't have control 
 over source code being run in the the child process, you can't control what it does 
-with pipe buffering.  Thus you can't just open a pipe to "cat -v" and continually
+with pipe buffering.  Thus you can't just open a pipe to C<cat -v> and continually
 read and write a line from it.
 
 =head1 SEE ALSO
@@ -80,8 +80,8 @@ sub open2 {
 
     # force unqualified filehandles into callers' package
     local($package) = caller;
-    $dad_rdr =~ s/^[^']+$/$package'$&/;
-    $dad_wtr =~ s/^[^']+$/$package'$&/;
+    $dad_rdr =~ s/^[^']+$/$package'$&/ unless ref $dad_rdr;
+    $dad_wtr =~ s/^[^']+$/$package'$&/ unless ref $dad_wtr;
 
     local($kid_rdr) = ++$fh;
     local($kid_wtr) = ++$fh;
index db8652e..5bc757c 100644 (file)
@@ -9,7 +9,7 @@ IPC::Open3, open3 - open a process for reading, writing, and error handling
 
 =head1 SYNOPSIS
 
-    $pid = open3('WTRFH', 'RDRFH', 'ERRFH' 
+    $pid = open3(\*WTRFH, \*RDRFH, \*ERRFH 
                    'some cmd and args', 'optarg', ...);
 
 =head1 DESCRIPTION
@@ -24,6 +24,11 @@ the child will read from it directly.  If RDRFH or ERRFH begins with
 ">&", then the child will send output directly to that file handle.  In both
 cases, there will be a dup(2) instead of a pipe(2) made.
 
+If you try to read from the child's stdout writer and their stderr
+writer, you'll have problems with blocking, which means you'll
+want to use select(), which means you'll have to use sysread() instead
+of normal stuff.
+
 All caveats from open2() continue to apply.  See L<open2> for details.
 
 =cut
@@ -78,9 +83,9 @@ sub open3 {
 
     # force unqualified filehandles into callers' package
     my($package) = caller;
-    $dad_wtr =~ s/^[^:]+$/$package\:\:$&/;
-    $dad_rdr =~ s/^[^:]+$/$package\:\:$&/;
-    $dad_err =~ s/^[^:]+$/$package\:\:$&/;
+    $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;
index 017d204..e3da9eb 100644 (file)
@@ -100,6 +100,7 @@ sub _package_defined {}
 
 1;
 __END__
+
 =head1 NAME
 
 SelfLoader - load functions only on demand
index 4dd4fe2..91c62b6 100644 (file)
@@ -1,6 +1,3 @@
-# by David Sundstrom   sunds@asictest.sc.ti.com
-#    Texas Instruments
-
 package Sys::Hostname;
 
 use Carp;
@@ -8,9 +5,31 @@ require Exporter;
 @ISA = qw(Exporter);
 @EXPORT = qw(hostname);
 
-#
-# Try every conceivable way to get hostname.
-# 
+=head1 NAME
+
+Sys::Hostname - Try every conceivable way to get hostname
+
+=head1 SYNOPSIS
+
+    use Sys::Hostname;
+    $host = hostname;
+
+=head1 DESCRIPTION
+
+Attempts several methods of getting the system hostname and
+then caches the result.  It tries C<syscall(SYS_gethostname)>,
+C<`hostname`>, C<`uname -n`>, and the file F</com/host>.
+If all that fails it C<croak>s.
+
+All nulls, returns, and newlines are removed from the result.
+
+=head1 AUTHOR
+
+David Sundstrom <sunds@asictest.sc.ti.com>
+
+Texas Instruments
+
+=cut
 
 sub hostname {
 
index 671da9f..bd8f07c 100644 (file)
@@ -125,7 +125,7 @@ sub syslog {
        if ($lo_cons) {
            if ($pid = fork) {
                unless ($lo_nowait) {
-                   do {$died = wait;} until $died == $pid || $died < 0;
+                   $died = waitpid($pid, 0);
                }
            }
            else {
@@ -147,44 +147,12 @@ sub xlate {
 }
 
 sub connect {
-    $pat = 'S n C4 x8';
-
-    $af_unix = AF_UNIX();
-    $af_inet = AF_INET();
-
-    $stream = SOCK_STREAM();
-    $datagram = SOCK_DGRAM();
-
-    ($name,$aliases,$proto) = getprotobyname('udp');
-    $udp = $proto;
-
-    ($name,$aliase,$port,$proto) = getservbyname('syslog','udp');
-    $syslog = $port;
-
-    if ($myname = hostname()) {
-       ($name,$aliases,$addrtype,$length,@addrs) = gethostbyname($myname);
-       croak "Can't lookup $myname" unless $name;
-       @bytes = unpack("C4",$addrs[0]);
-    }
-    else {
-       @bytes = (0,0,0,0);
-    }
-    $this = pack($pat, $af_inet, 0, @bytes);
-
-    if ($host =~ /^\d+\./) {
-       @bytes = split(/\./,$host);
-    }
-    else {
-       ($name,$aliases,$addrtype,$length,@addrs) = gethostbyname($host);
-       croak "Can't lookup $host" unless $name;
-       @bytes = unpack("C4",$addrs[0]);
-    }
-    $that = pack($pat,$af_inet,$syslog,@bytes);
-
-    socket(SYSLOG,$af_inet,$datagram,$udp) || croak "socket: $!";
-    bind(SYSLOG,$this) || croak "bind: $!";
-    connect(SYSLOG,$that) || croak "connect: $!";
-
+    my $udp = getprotobyname('udp');
+    my $syslog = getservbyname('syslog','udp');
+    my $this = sockaddr_in($syslog, INADDR_ANY);
+    my $that = sockaddr_in($syslog, inet_aton($host) || croak "Can't lookup $host");
+    socket(SYSLOG,AF_INET,SOCK_DGRAM,$udp)          || croak "socket: $!";
+    connect(SYSLOG,$that)                           || croak "connect: $!";
     local($old) = select(SYSLOG); $| = 1; select($old);
     $connected = 1;
 }
index 061ca70..5e900c3 100644 (file)
-# Term::Cap.pm -- Termcap interface routines
 package Term::Cap;
+use Carp;
 
-# Converted to package on 25 Feb 1994 <sanders@bsdi.com>
-#
-# Usage:
-#      require 'ioctl.pl';
-#      ioctl(TTY,$TIOCGETP,$sgtty);
-#      ($ispeed,$ospeed) = unpack('cc',$sgtty);
-#
-#      require Term::Cap;
-#
-#      $term = Tgetent Term::Cap { TERM => undef, OSPEED => $ospeed };
-#              sets $term->{'_cm'}, etc.
-#      $this->Trequire(qw/ce ku kd/);
-#              die unless entries are defined for the terminal
-#      $term->Tgoto('cm', $col, $row, $FH);
-#      $term->Tputs('dl', $cnt = 1, $FH);
-#      $this->Tpad($string, $cnt = 1, $FH);
-#              processes a termcap string and adds padding if needed
-#              if $FH is undefined these just return the string
-#
-# CHANGES:
-#      Converted to package
-#      Allows :tc=...: in $ENV{'TERMCAP'} (flows to default termcap file)
-#      Now die's properly if it can't open $TERMCAP or if the eval $loop fails
-#      Tputs() results are cached (use Tgoto or Tpad to avoid)
-#      Tgoto() will do output if $FH is passed (like Tputs without caching)
-#      Supports POSIX termios speeds and old style speeds
-#      Searches termcaps properly (TERMPATH, etc)
-#      The output routines are optimized for cached Tputs().
-#      $this->{_xx} is the raw termcap data and $this->{xx} is a
-#          cached and padded string for count == 1.
-#
+# Last updated: Thu Dec 14 20:02:42 CST 1995 by sanders@bsdi.com
 
-# internal routines
-sub getenv { defined $ENV{$_[0]} ? $ENV{$_[0]} : ''; }
-sub termcap_path {
-    local @termcap_path = ('/etc/termcap', '/usr/share/misc/termcap');
-    local $v;
-    if ($v = getenv(TERMPATH)) {
-       # user specified path
-       @termcap_path = split(':', $v);
-    } else {
-       # default path
-       @termcap_path = ('/etc/termcap', '/usr/share/misc/termcap');
-       $v = getenv(HOME);
-       unshift(@termcap_path, $v . '/.termcap') if $v;
+# TODO:
+# support Berkeley DB termcaps
+# should probably be a .xs module
+# force $FH into callers package?
+# keep $FH in object at Tgetent time?
+
+=head1 NAME
+
+Term::Cap - Perl termcap interface
+
+=head1 SYNOPSIS
+
+    require Term::Cap;
+    $terminal = Tgetent Term::Cap { TERM => undef, OSPEED => $ospeed };
+    $terminal->Trequire(qw/ce ku kd/);
+    $terminal->Tgoto('cm', $col, $row, $FH);
+    $terminal->Tputs('dl', $count, $FH);
+    $terminal->Tpad($string, $count, $FH);
+
+=head1 DESCRIPTION
+
+These are low-level functions to extract and use capabilities from
+a terminal capability (termcap) database.
+
+The B<Tgetent> function extracts the entry of the specified terminal
+type I<TERM> (defaults to the environment variable I<TERM>) from the
+database.
+
+It will look in the environment for a I<TERMCAP> variable.  If
+found, and the value does not begin with a slash, and the terminal
+type name is the same as the environment string I<TERM>, the
+I<TERMCAP> string is used instead of reading a termcap file.  If
+it does begin with a slash, the string is used as a path name of
+the termcap file to search.  If I<TERMCAP> does not begin with a
+slash and name is different from I<TERM>, B<Tgetent> searches the
+files F<$HOME/.termcap>, F</etc/termcap>, and F</usr/share/misc/termcap>,
+in that order, unless the environment variable I<TERMPATH> exists,
+in which case it specifies a list of file pathnames (separated by
+spaces or colons) to be searched B<instead>.  Whenever multiple
+files are searched and a tc field occurs in the requested entry,
+the entry it names must be found in the same file or one of the
+succeeding files.  If there is a C<:tc=...:> in the I<TERMCAP>
+environment variable string it will continue the search in the
+files as above.
+
+I<OSPEED> is the terminal output bit rate (often mistakenly called
+the baud rate).  I<OSPEED> can be specified as either a POSIX
+termios/SYSV termio speeds (where 9600 equals 9600) or an old
+BSD-style speeds (where 13 equals 9600).
+
+B<Tgetent> returns a blessed object reference which the user can
+then use to send the control strings to the terminal using B<Tputs>
+and B<Tgoto>.  It calls C<croak> on failure.
+
+B<Tgoto> decodes a cursor addressing string with the given parameters.
+
+The output strings for B<Tputs> are cached for counts of 1 for performance.
+B<Tgoto> and B<Tpad> do not cache.  C<$self-E<gt>{_xx}> is the raw termcap
+data and C<$self-E<gt>{xx}> is the cached version.
+
+    print $terminal->Tpad($self->{_xx}, 1);
+
+B<Tgoto>, B<Tputs>, and B<Tpad> return the string and will also
+output the string to $FH if specified.
+
+The extracted termcap entry is available in the object
+as C<$self-E<gt>{TERMCAP}>.
+
+=head1 EXAMPLES
+
+    # Get terminal output speed
+    require POSIX;
+    my $termios = new POSIX::Termios;
+    $termios->getattr;
+    my $ospeed = $termios->getospeed;
+
+    # Old-style ioctl code to get ospeed:
+    #     require 'ioctl.pl';
+    #     ioctl(TTY,$TIOCGETP,$sgtty);
+    #     ($ispeed,$ospeed) = unpack('cc',$sgtty);
+
+    # allocate and initialize a terminal structure
+    $terminal = Tgetent Term::Cap { TERM => undef, OSPEED => $ospeed };
+
+    # require certain capabilities to be available
+    $terminal->Trequire(qw/ce ku kd/);
+
+    # Output Routines, if $FH is undefined these just return the string
+
+    # Tgoto does the % expansion stuff with the given args
+    $terminal->Tgoto('cm', $col, $row, $FH);
+
+    # Tputs doesn't do any % expansion.
+    $terminal->Tputs('dl', $count = 1, $FH);
+
+=cut
+
+# Returns a list of termcap files to check.
+sub termcap_path { ## private
+    my @termcap_path;
+    # $TERMCAP, if it's a filespec
+    push(@termcap_path, $ENV{TERMCAP}) if $ENV{TERMCAP} =~ /^\//;
+    if ($ENV{TERMPATH}) {
+       # Add the users $TERMPATH
+       push(@termcap_path, split(/(:|\s+)/, $ENV{TERMPATH}))
+    }
+    else {
+       # Defaults
+       push(@termcap_path,
+           $ENV{'HOME'} . '/.termcap',
+           '/etc/termcap',
+           '/usr/share/misc/termcap',
+       );
     }
-    # we always search TERMCAP first
-    $v = getenv(TERMCAP);
-    unshift(@termcap_path, $v) if $v =~ /^\//;
+    # return the list of those termcaps that exist
     grep(-f, @termcap_path);
 }
 
-sub Tgetent {
-    local($type) = shift;
-    local($this) = @_;
-    local($TERM,$TERMCAP,$term,$entry,$cap,$loop,$field,$entry,$_);
-
-    warn "Tgetent: no ospeed set\n" unless $this->{OSPEED} > 0;
-    $this->{DECR} = 10000 / $this->{OSPEED} if $this->{OSPEED} > 50;
-    $term = $TERM = $this->{TERM} =
-       $this->{TERM} || getenv(TERM) || die "Tgetent: TERM not set\n";
-
-    $TERMCAP = getenv(TERMCAP);
-    $TERMCAP = '' if $TERMCAP =~ m:^/: || $TERMCAP !~ /(^|\|)$TERM[:\|]/;
-    local @termcap_path = &termcap_path;
-    die "Tgetent: Can't find a valid termcap file\n"
-       unless @termcap_path || $TERMCAP;
-
-    # handle environment TERMCAP, setup for continuation if needed
-    $entry = $TERMCAP;
-    $entry =~ s/:tc=([^:]+):/:/ && ($TERM = $1);
-    if ($TERMCAP eq '' || $1) {                                # the search goes on
-       local $first = $TERMCAP eq '' ? 1 : 0;          # make it pretty
-       local $max = 32;                                # max :tc=...:'s
-       local $state = 1;                               # 0 == finished
-                                                       # 1 == next file
-                                                       # 2 == search again
-       do {
-           if ($state == 1) {
-               $TERMCAP = shift @termcap_path
-                   || die "Tgetent: failed lookup on $TERM\n";
-           } else {
-               $max-- || die "Tgetent: termcap loop at $TERM\n";
-               $state = 1;                             # back to default state
+sub Tgetent { ## public -- static method
+    my $class = shift;
+    my $self = bless shift, $class;
+    my($term,$cap,$search,$field,$max,$tmp_term,$TERMCAP);
+    local($termpat,$state,$first,$entry);      # used inside eval
+    local $_;
+
+    # Compute PADDING factor from OSPEED (to be used by Tpad)
+    if (! $self->{OSPEED}) {
+       carp "OSPEED was not set, defaulting to 9600";
+       $self->{OSPEED} = 9600;
+    }
+    if ($self->{OSPEED} < 16) {
+       # delays for old style speeds
+       my @pad = (0,200,133.3,90.9,74.3,66.7,50,33.3,16.7,8.3,5.5,4.1,2,1,.5,.2);
+       $self->{PADDING} = $pad[$self->{OSPEED}];
+    }
+    else {
+       $self->{PADDING} = 10000 / $self->{OSPEED};
+    }
+
+    $self->{TERM} = ($self->{TERM} || $ENV{TERM} || croak "TERM not set");
+    $term = $self->{TERM};     # $term is the term type we are looking for
+
+    # $tmp_term is always the next term (possibly :tc=...:) we are looking for
+    $tmp_term = $self->{TERM};
+    # protect any pattern metacharacters in $tmp_term 
+    $termpat = $tmp_term; $termpat =~ s/(\W)/\\$1/g;
+
+    my $foo = $ENV{TERMCAP};
+
+    # $entry is the extracted termcap entry
+    if (($foo !~ m:^/:) && ($foo =~ m/(^|\|)${termpat}[:|]/)) {
+       $entry = $foo;
+    }
+
+    my @termcap_path = termcap_path;
+    croak "Can't find a valid termcap file" unless @termcap_path || $entry;
+
+    $state = 1;                                        # 0 == finished
+                                               # 1 == next file
+                                               # 2 == search again
+
+    $first = 0;                                        # first entry (keeps term name)
+
+    $max = 32;                                 # max :tc=...:'s
+
+    if ($entry) {
+       # ok, we're starting with $TERMCAP
+       $first++;                               # we're the first entry
+       # do we need to continue?
+       if ($entry =~ s/:tc=([^:]+):/:/) {
+           $tmp_term = $1;
+           # protect any pattern metacharacters in $tmp_term 
+           $termpat = $tmp_term; $termpat =~ s/(\W)/\\$1/g;
+       }
+       else {
+           $state = 0;                         # we're already finished
+       }
+    }
+
+    # This is eval'ed inside the while loop for each file
+    $search = q{
+       while ($_ = <TERMCAP>) {
+           next if /^\\t/ || /^#/;
+           if ($_ =~ m/(^|\\|)${termpat}[:|]/o) {
+               chomp;
+               s/^[^:]*:// if $first++;
+               $state = 0;
+               while ($_ =~ s/\\\\$//) { $_ .= <TERMCAP>; chomp; }
+               last;
            }
+       }
+       $entry .= $_;
+    };
 
-           open(TERMCAP,"< $TERMCAP\0") || die "Tgetent: $TERMCAP: $!\n";
-           # print STDERR "Trying... $TERMCAP\n";
-           $loop = "
-               while (<TERMCAP>) {
-                   next if /^\t/;
-                   next if /^#/;
-                   if (/(^|\\|)${TERM}[:\\|]/) {
-                       chop;
-                       s/^[^:]*:// unless \$first++;
-                       \$state = 0;
-                       while (chop eq '\\\\') {
-                           \$_ .= <TERMCAP>;
-                           chop;
-                       }
-                       \$_ .= ':';
-                       last;
-                   }
-               }
-               \$entry .= \$_;
-           ";
-           eval $loop;
-           die $@ if $@;
-           #print STDERR "$TERM: $_\n--------\n";      # DEBUG
-           close TERMCAP;
-           # If :tc=...: found then search this file again
-           $entry =~ s/:tc=([^:]+):/:/ && ($TERM = $1, $state = 2);
-       } while $state != 0;
+    while ($state != 0) {
+       if ($state == 1) {
+           # get the next TERMCAP
+           $TERMCAP = shift @termcap_path
+               || croak "failed termcap lookup on $tmp_term";
+       }
+       else {
+           # do the same file again
+           # prevent endless recursion
+           $max-- || croak "failed termcap loop at $tmp_term";
+           $state = 1;         # ok, maybe do a new file next time
+       }
+
+       open(TERMCAP,"< $TERMCAP\0") || croak "open $TERMCAP: $!";
+       eval $search;
+       die $@ if $@;
+       close TERMCAP;
+
+       # If :tc=...: found then search this file again
+       $entry =~ s/:tc=([^:]+):/:/ && ($tmp_term = $1, $state = 2);
+       # protect any pattern metacharacters in $tmp_term 
+       $termpat = $tmp_term; $termpat =~ s/(\W)/\\$1/g;
     }
-    die "Tgetent: Can't find $term\n" unless $entry ne '';
-    $entry =~ s/:\s+:/:/g;
-    $this->{TERMCAP} = $entry;
-    #print STDERR $entry, "\n";                                # DEBUG
+
+    croak "Can't find $term" if $entry eq '';
+    $entry =~ s/:+\s*:+/:/g;                           # cleanup $entry
+    $entry =~ s/:+/:/g;                                        # cleanup $entry
+    $self->{TERMCAP} = $entry;                         # save it
+    # print STDERR "DEBUG: $entry = ", $entry, "\n";
 
     # Precompile $entry into the object
+    $entry =~ s/^[^:]*://;
     foreach $field (split(/:[\s:\\]*/,$entry)) {
-       if ($field =~ /^\w\w$/) {
-           $this->{'_' . $field} = 1 unless defined $this->{'_' . $1};
+       if ($field =~ /^(\w\w)$/) {
+           $self->{'_' . $field} = 1 unless defined $self->{'_' . $1};
+           # print STDERR "DEBUG: flag $1\n";
        }
        elsif ($field =~ /^(\w\w)\@/) {
-           $this->{'_' . $1} = "";
+           $self->{'_' . $1} = "";
+           # print STDERR "DEBUG: unset $1\n";
        }
        elsif ($field =~ /^(\w\w)#(.*)/) {
-           $this->{'_' . $1} = $2 unless defined $this->{'_' . $1};
+           $self->{'_' . $1} = $2 unless defined $self->{'_' . $1};
+           # print STDERR "DEBUG: numeric $1 = $2\n";
        }
        elsif ($field =~ /^(\w\w)=(.*)/) {
-           next if defined $this->{'_' . ($cap = $1)};
+           # print STDERR "DEBUG: string $1 = $2\n";
+           next if defined $self->{'_' . ($cap = $1)};
            $_ = $2;
            s/\\E/\033/g;
            s/\\(\d\d\d)/pack('c',oct($1) & 0177)/eg;
@@ -146,47 +258,47 @@ sub Tgetent {
            s/\^(.)/pack('c',ord($1) & 31)/eg;
            s/\\(.)/$1/g;
            s/\377/^/g;
-           $this->{'_' . $cap} = $_;
+           $self->{'_' . $cap} = $_;
        }
-       # else { warn "Tgetent: junk in $term: $field\n"; }
+       # else { carp "junk in $term ignored: $field"; }
     }
-    $this->{'_pc'} = "\0" unless defined $this->{'_pc'};
-    $this->{'_bc'} = "\b" unless defined $this->{'_bc'};
-    $this;
+    $self->{'_pc'} = "\0" unless defined $self->{'_pc'};
+    $self->{'_bc'} = "\b" unless defined $self->{'_bc'};
+    $self;
 }
 
-# delays for old style speeds
-@Tpad = (0,200,133.3,90.9,74.3,66.7,50,33.3,16.7,8.3,5.5,4.1,2,1,.5,.2);
-
-# $term->Tpad($string, $cnt, $FH);
-sub Tpad {
-    local($this, $string, $cnt, $FH) = @_;
-    local($decr, $ms);
+# $terminal->Tpad($string, $cnt, $FH);
+sub Tpad { ## public
+    my $self = shift;
+    my($string, $cnt, $FH) = @_;
+    my($decr, $ms);
 
     if ($string =~ /(^[\d.]+)(\*?)(.*)$/) {
        $ms = $1;
        $ms *= $cnt if $2;
        $string = $3;
-       $decr = $this->{OSPEED} < 50 ? $Tpad[$this->{OSPEED}] : $this->{DECR};
+       $decr = $self->{PADDING};
        if ($decr > .1) {
            $ms += $decr / 2;
-           $string .= $this->{'_pc'} x ($ms / $decr);
+           $string .= $self->{'_pc'} x ($ms / $decr);
        }
     }
     print $FH $string if $FH;
     $string;
 }
 
-# $term->Tputs($cap, $cnt, $FH);
-sub Tputs {
-    local($this, $cap, $cnt, $FH) = @_;
-    local $string;
+# $terminal->Tputs($cap, $cnt, $FH);
+sub Tputs { ## public
+    my $self = shift;
+    my($cap, $cnt, $FH) = @_;
+    my $string;
 
     if ($cnt > 1) {
-       $string = Tpad($this, $this->{'_' . $cap}, $cnt);
+       $string = Tpad($self, $self->{'_' . $cap}, $cnt);
     } else {
-       $string = defined $this->{$cap} ? $this->{$cap} :
-           ($this->{$cap} = Tpad($this, $this->{'_' . $cap}, 1));
+       # cache result because Tpad can be slow
+       $string = defined $self->{$cap} ? $self->{$cap} :
+           ($self->{$cap} = Tpad($self, $self->{'_' . $cap}, 1));
     }
     print $FH $string if $FH;
     $string;
@@ -207,15 +319,16 @@ sub Tputs {
 # %n   exclusive-or all parameters with 0140 (Datamedia 2500)
 # %D   Reverse coding (value - 2*(value%16)), no output (Delta Data)
 #
-# $term->Tgoto($cap, $col, $row, $FH);
-sub Tgoto {
-    local($this, $cap, $code, $tmp, $FH) = @_;
-    local $string = $this->{'_' . $cap};
-    local $result = '';
-    local $after = '';
-    local $online = 0;
-    local @tmp = ($tmp,$code);
-    local $cnt = $code;
+# $terminal->Tgoto($cap, $col, $row, $FH);
+sub Tgoto { ## public
+    my $self = shift;
+    my($cap, $code, $tmp, $FH) = @_;
+    my $string = $self->{'_' . $cap};
+    my $result = '';
+    my $after = '';
+    my $online = 0;
+    my @tmp = ($tmp,$code);
+    my $cnt = $code;
 
     while ($string =~ /^([^%]*)%(.)(.*)/) {
        $result .= $1;
@@ -228,10 +341,10 @@ sub Tgoto {
            $tmp = shift(@tmp);
            if ($tmp == 0 || $tmp == 4 || $tmp == 10) {
                if ($online) {
-                   ++$tmp, $after .= $this->{'_up'} if $this->{'_up'};
+                   ++$tmp, $after .= $self->{'_up'} if $self->{'_up'};
                }
                else {
-                   ++$tmp, $after .= $this->{'_bc'};
+                   ++$tmp, $after .= $self->{'_bc'};
                }
            }
            $result .= sprintf("%c",$tmp);
@@ -269,19 +382,21 @@ sub Tgoto {
            return "OOPS";
        }
     }
-    $string = Tpad($this, $result . $string . $after, $cnt);
+    $string = Tpad($self, $result . $string . $after, $cnt);
     print $FH $string if $FH;
     $string;
 }
 
-# $this->Trequire($cap1, $cap2, ...);
-sub Trequire {
-    local $this = shift;
-    local $_;
-    foreach (@_) {
-       die "Trequire: Terminal does not support: $_\n"
-           unless defined $this->{'_' . $_} && $this->{'_' . $_};
+# $terminal->Trequire(qw/ce ku kd/);
+sub Trequire { ## public
+    my $self = shift;
+    my($cap,@undefined);
+    foreach $cap (@_) {
+       push(@undefined, $cap)
+           unless defined $self->{'_' . $cap} && $self->{'_' . $cap};
     }
+    croak "Terminal does not support: (@undefined)" if @undefined;
 }
 
 1;
+
index 97c71fe..6faef22 100644 (file)
@@ -5,30 +5,63 @@ require Exporter;
 @ISA = qw(Exporter);
 @EXPORT = qw(Complete);
 
-#
 #      @(#)complete.pl,v1.1            (me@anywhere.EBay.Sun.COM) 09/23/91
-#
-# Author: Wayne Thompson
-#
-# Description:
-#     This routine provides word completion.
-#     (TAB) attempts word completion.
-#     (^D)  prints completion list.
-#      (These may be changed by setting $Complete::complete, etc.)
-#
-# Diagnostics:
-#     Bell when word completion fails.
-#
-# Dependencies:
-#     The tty driver is put into raw mode.
-#
-# Bugs:
-#
-# Usage:
-#     $input = complete('prompt_string', \@completion_list);
-#         or
-#     $input = complete('prompt_string', @completion_list);
-#
+
+=head1 NAME
+
+Term::Complete - Perl word completion module
+
+=head1 SYNOPSIS
+
+    $input = complete('prompt_string', \@completion_list);
+    $input = complete('prompt_string', @completion_list);
+
+=head1 DESCRIPTION
+
+This routine provides word completion on the list of words in
+the array (or array ref).
+
+The tty driver is put into raw mode using the system command
+C<stty raw -echo> and restored using C<stty -raw echo>.
+
+The following command characters are defined:
+
+=over 4
+
+=item <tab>
+Attempts word completion.
+Cannot be changed.
+
+=item ^D
+
+Prints completion list.
+Defined by I<$Term::Complete::complete>.
+
+=item ^U
+
+Erases the current input.
+Defined by I<$Term::Complete::kill>.
+
+=item <del>, <bs>
+
+Erases one character.
+Defined by I<$Term::Complete::erase1> and I<$Term::Complete::erase2>.
+
+=back
+
+=head1 DIAGNOSTICS
+
+Bell sounds when word completion fails.
+
+=head1 BUGS
+
+The completion charater <tab> cannot be changed.
+
+=head1 AUTHOR
+
+Wayne Thompson
+
+=cut
 
 CONFIG: {
     $complete = "\004";
index 635febd..99e06f7 100644 (file)
@@ -10,7 +10,7 @@ $ENV{EMXSHELL} = 'sh' if $Is_OS2; # to run commands
 $path_s = $Is_OS2 ? ';' : ':' ;
 
 @ISA=(Exporter);
-@EXPORT= qw(&runtests &test_lib);
+@EXPORT= qw(&runtests);
 @EXPORT_OK= qw($verbose $switches);
 
 $verbose = 0;
@@ -85,3 +85,63 @@ sub runtests {
 }
 
 1;
+__END__
+
+=head1 NAME
+
+Test::Harness - run perl standard test scripts with statistics
+
+=head1 SYNOPSIS
+
+use Test::Harness;
+
+runtests(@tests);
+
+=head1 DESCRIPTION
+
+Perl test scripts print to standard output C<"ok N"> for each single
+test, where C<N> is an increasing sequence of integers. The first line
+output by a standard test scxript is C<"1..M"> with C<M> 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.
+
+=head1 EXPORT
+
+C<&runscripts> is exported by Test::Harness per default.
+
+=head1 DIAGNOSTICS
+
+=over 4
+
+=item C<All tests successful.\nFiles=%d,  Tests=%d, %s>
+
+If all tests are successful some statistics about the performance are
+printed.
+
+=item C<Failed 1 test, $pct% okay.>
+
+=item C<Failed %d/%d tests, %.2f%% okay.>
+
+If not all tests were successful, the script dies with one of the
+above messages.
+
+=back
+
+=head1 SEE ALSO
+
+See L<Benchmerk> for the underlying timing routines.
+
+=head1 BUGS
+
+Test::Harness uses $^X to determine the perl binary to run the tests
+with. Test scripts running via the shebang (C<#!>) line may not be portable
+because $^X is not consistent for shebang scripts across
+platforms. This is no problem when Test::Harness is run with an
+absolute path to the perl binary.
+
+=cut
index 6551523..a334404 100644 (file)
@@ -40,19 +40,12 @@ require Exporter;
 
 $soundex_nocode = undef;
 
-# soundex
-#
-# usage:
-#
-# @codes = &soundex (@wordList);
-# $code = &soundex ($word);
-#
-# This strenuously avoids 0
-
 sub soundex
 {
   local (@s, $f, $fc, $_) = @_;
 
+  push @s, '' unless @s;       # handle no args as a single empty string
+
   foreach (@s)
   {
     tr/a-z/A-Z/;
@@ -80,3 +73,76 @@ sub soundex
 
 1;
 
+__END__
+
+=head1 NAME
+
+Text::Soundex - Implementation of the Soundex Algorithm as Described by Knuth
+
+=head1 SYNOPSIS
+
+  use Text::Soundex;
+
+  $code = soundex $string;            # get soundex code for a string
+  @codes = soundex @list;             # get list of codes for list of strings
+
+  # set value to be returned for strings without soundex code
+
+  $soundex_nocode = 'Z000';
+
+=head1 DESCRIPTION
+
+This module implements the soundex algorithm as described by Donald Knuth
+in Volume 3 of B<The Art of Computer Programming>.  The algorithm is
+intended to hash words (in particular surnames) into a small space using a
+simple model which approximates the sound of the word when spoken by an English
+speaker.  Each word is reduced to a four character string, the first
+character being an upper case letter and the remaining three being digits.
+
+If there is no soundex code representation for a string then the value of
+C<$soundex_nocode> is returned.  This is initially set to C<undef>, but
+many people seem to prefer an I<unlikely> value like C<Z000>
+(how unlikely this is depends on the data set being dealt with.)  Any value
+can be assigned to C<$soundex_nocode>.
+
+In scalar context C<soundex> returns the soundex code of its first
+argument, and in array context a list is returned in which each element is the 
+soundex code for the corresponding argument passed to C<soundex> e.g.
+
+  @codes = soundex qw(Mike Stok);
+
+leaves C<@codes> containing C<('M200', 'S320')>.
+
+=head1 EXAMPLES
+
+Knuth's examples of various names and the soundex codes they map to
+are listed below:
+
+  Euler, Ellery -> E460
+  Gauss, Ghosh -> G200
+  Hilbert, Heilbronn -> H416
+  Knuth, Kant -> K530
+  Lloyd, Ladd -> L300
+  Lukasiewicz, Lissajous -> L222
+
+so:
+
+  $code = soundex 'Knuth';              # $code contains 'K530'
+  @list = soundex qw(Lloyd Gauss);     # @list contains 'L300', 'G200'
+
+=head1 LIMITATIONS
+
+As the soundex algorithm was originally used a B<long> time ago in the US
+it considers only the English alphabet and pronunciation.
+
+As it is mapping a large space (arbitrary length strings) onto a small
+space (single letter plus 3 digits) no inference can be made about the
+similarity of two strings which end up with the same soundex code.  For 
+example, both C<Hilbert> and C<Heilbronn> end up with a soundex code
+of C<H416>.
+
+=head1 AUTHOR
+
+This code was implemented by Mike Stok (C<stok@cybercom.net>) from the 
+description given by Knuth.  Ian Phillips (C<ian@pipex.net>) and Rich Pinder 
+(C<rpinder@hsc.usc.edu>) supplied ideas and spotted mistakes.
index 7cfb478..2481d81 100644 (file)
 # 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<not> 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 <muir@idiom.com>
+
+=cut
+
 package Text::Tabs;
 
 require Exporter;
index 9b1d054..b665752 100644 (file)
@@ -30,6 +30,31 @@ package Text::Wrap;
 # 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 <muir@idiom.com>
+
+=cut
+
 require Exporter;
 
 @ISA = (Exporter);
index 446cbcb..161771a 100644 (file)
@@ -1,4 +1,103 @@
 package TieHash;
+
+=head1 NAME
+
+TieHash, TieHash::Std - base class definitions for tied hashes
+
+=head1 SYNOPSIS
+
+    package NewHash;
+    require TieHash;
+    
+    @ISA = (TieHash);
+    
+    sub DELETE { ... }         # Provides needed method
+    sub CLEAR { ... }          # Overrides inherited method
+    
+    
+    package NewStdHash;
+    require TieHash;
+    
+    @ISA = (TieHash::Std);
+    
+    # All methods provided by default, define only those needing overrides
+    sub DELETE { ... }
+    
+    
+    package main;
+    
+    tie %new_hash, NewHash;
+    tie %new_std_hash, NewStdHash;
+
+=head1 DESCRIPTION
+
+This module provides some skeletal methods for hash-tying classes. See
+L<perlfunc/tie> for a list of the functions required in order to tie a hash
+to a package. The basic B<TieHash> package provides a C<new> method, as well
+as methods C<TIEHASH>, C<EXISTS> and C<CLEAR>. The B<TieHash::Std> package
+provides most methods required for hashes in L<perlfunc/tie>. It inherits from
+B<TieHash>, and causes tied hashes to behave exactly like standard hashes,
+allowing for selective overloading of methods. The B<new> method is provided
+as grandfathering in the case a class forgets to include a B<TIEHASH> method.
+
+For developers wishing to write their own tied hashes, the required methods
+are:
+
+=item TIEHASH classname, LIST
+
+The method invoked by the command C<tie %hash, class>. Associates a new
+hash instance with the specified class. C<LIST> would represent additional
+arguments (along the lines of L<AnyDBM_File> and compatriots) needed to
+complete the association.
+
+=item STORE this, key, value
+
+Store datum I<value> into I<key> for the tied hash I<this>.
+
+=item FETCH this, key
+
+Retrieve the datum in I<key> for the tied hash I<this>.
+
+=item FIRSTKEY this
+
+Return the (key, value) pair for the first key in the hash.
+
+=item NEXTKEY this, lastkey
+
+Return the next (key, value) pair for the hash.
+
+=item EXISTS this, key
+
+Verify that I<key> exists with the tied hash I<this>.
+
+=item DELETE this, key
+
+Delete the key I<key> from the tied hash I<this>.
+
+=item CLEAR this
+
+Clear all values from the tied hash I<this>.
+
+=back
+
+=head1 CAVEATS
+
+The L<perlfunc/tie> documentation includes a method called C<DESTROY> as
+a necessary method for tied hashes. Neither B<TieHash> nor B<TieHash::Std>
+define a default for this method.
+
+The C<CLEAR> method provided by these two packages is not listed in the
+L<perlfunc/tie> section.
+
+=head1 MORE INFORMATION
+
+The packages relating to various DBM-related implemetations (F<DB_File>,
+F<NDBM_File>, etc.) show examples of general tied hashes, as does the
+L<Config> module. While these do not utilize B<TieHash>, they serve as
+good working examples.
+
+=cut
+    
 use Carp;
 
 sub new {
index 64e6240..451c7fa 100644 (file)
@@ -6,31 +6,38 @@ use Carp;
 @ISA = qw(Exporter);
 @EXPORT = qw(timegm timelocal);
 
-# timelocal.pl
-#
-# Usage:
-#      $time = timelocal($sec,$min,$hours,$mday,$mon,$year);
-#      $time = timegm($sec,$min,$hours,$mday,$mon,$year);
-
-# These routines are quite efficient and yet are always guaranteed to agree
-# with localtime() and gmtime().  We manage this by caching the start times
-# of any months we've seen before.  If we know the start time of the month,
-# we can always calculate any time within the month.  The start times
-# themselves are guessed by successive approximation starting at the
-# current time, since most dates seen in practice are close to the
-# current date.  Unlike algorithms that do a binary search (calling gmtime
-# once for each bit of the time value, resulting in 32 calls), this algorithm
-# calls it at most 6 times, and usually only once or twice.  If you hit
-# the month cache, of course, it doesn't call it at all.
-
-# timelocal is implemented using the same cache.  We just assume that we're
-# translating a GMT time, and then fudge it when we're done for the timezone
-# and daylight savings arguments.  The timezone is determined by examining
-# the result of localtime(0) when the package is initialized.  The daylight
-# savings offset is currently assumed to be one hour.
-
-# Both routines return -1 if the integer limit is hit. I.e. for dates
-# after the 1st of January, 2038 on most machines.
+=head1 NAME
+
+Time::Local - efficiently compute tome from local and GMT time
+
+=head1 SYNOPSIS
+
+    $time = timelocal($sec,$min,$hours,$mday,$mon,$year);
+    $time = timegm($sec,$min,$hours,$mday,$mon,$year);
+
+=head1 DESCRIPTION
+
+These routines are quite efficient and yet are always guaranteed to agree
+with localtime() and gmtime().  We manage this by caching the start times
+of any months we've seen before.  If we know the start time of the month,
+we can always calculate any time within the month.  The start times
+themselves are guessed by successive approximation starting at the
+current time, since most dates seen in practice are close to the
+current date.  Unlike algorithms that do a binary search (calling gmtime
+once for each bit of the time value, resulting in 32 calls), this algorithm
+calls it at most 6 times, and usually only once or twice.  If you hit
+the month cache, of course, it doesn't call it at all.
+
+timelocal is implemented using the same cache.  We just assume that we're
+translating a GMT time, and then fudge it when we're done for the timezone
+and daylight savings arguments.  The timezone is determined by examining
+the result of localtime(0) when the package is initialized.  The daylight
+savings offset is currently assumed to be one hour.
+
+Both routines return -1 if the integer limit is hit. I.e. for dates
+after the 1st of January, 2038 on most machines.
+
+=cut
 
 @epoch = localtime(0);
 $tzmin = $epoch[2] * 60 + $epoch[1];   # minutes east of GMT
index 5e055f3..b3afef0 100644 (file)
@@ -2,7 +2,11 @@ package less;
 
 =head1 NAME
 
-less - Perl pragma to request less of something from the compiler
+less - perl pragma to request less of something from the compiler
+
+=head1 SYNOPSIS
+
+    use less;  # unimplemented
 
 =head1 DESCRIPTION
 
index 3c9562a..54d2cbb 100644 (file)
@@ -62,7 +62,7 @@ __END__
 
 =head1 NAME 
 
-C<overload.pm> - Package for overloading perl operations
+overload - Package for overloading perl operations
 
 =head1 SYNOPSIS
 
index d35c6c1..6f6028c 100644 (file)
@@ -53,13 +53,17 @@ name without fully qualifying it.
 
 =item C<strict subs>
 
-This disables the poetry optimization,
-generating a compile-time error if you 
-try to use a bareword identifier that's not a subroutine.
+This disables the poetry optimization, generating a compile-time error if
+you try to use a bareword identifier that's not a subroutine, unless it
+appears in curly braces or on the left hand side of the "=>" symbol.
+
 
     use strict 'subs';
     $SIG{PIPE} = Plumber;      # blows up
-    $SIG{"PIPE"} = "Plumber";  # just fine
+    $SIG{PIPE} = "Plumber";    # just fine: bareword in curlies always ok
+    $SIG{PIPE} = \&Plumber;    # preferred form
+
+
 
 =back
 
index a3b9edf..2034e0a 100644 (file)
@@ -31,8 +31,16 @@ package syslog;
 
 $host = 'localhost' unless $host;      # set $syslog'host to change
 
+if ($] >= 5) {
+    warn "You should 'use Sys::Socket' instead; continuing" # if $^W
+} 
+
 require 'syslog.ph';
 
+ eval 'require Socket'                 || 
+eval { require "socket.ph" }   || 
+       require "sys/socket.ph";
+
 $maskpri = &LOG_UPTO(&LOG_DEBUG);
 
 sub main'openlog {
@@ -141,16 +149,16 @@ sub xlate {
 sub connect {
     $pat = 'S n C4 x8';
 
-    $af_unix = 1;
-    $af_inet = 2;
+    $af_unix = &AF_UNIX;
+    $af_inet = &AF_INET;
 
-    $stream = 1;
-    $datagram = 2;
+    $stream = &SOCK_STREAM;
+    $datagram = &SOCK_DGRAM;
 
     ($name,$aliases,$proto) = getprotobyname('udp');
     $udp = $proto;
 
-    ($name,$aliase,$port,$proto) = getservbyname('syslog','udp');
+    ($name,$aliases,$port,$proto) = getservbyname('syslog','udp');
     $syslog = $port;
 
     if (chop($myname = `hostname`)) {
diff --git a/perl.c b/perl.c
index 39e8449..bc1353e 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -1093,7 +1093,7 @@ char *s;
        s++;
        return s;
     case 'v':
-       printf("\nThis is perl, version %s beta\n\n",patchlevel);
+       printf("\nThis is perl, version %s beta1g\n\n",patchlevel);
        fputs("\nCopyright 1987-1995, Larry Wall\n",stdout);
 #ifdef MSDOS
        fputs("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n",
index 38d5b0f..9cf48eb 100644 (file)
@@ -2,7 +2,7 @@ CONVERTERS = pod2html pod2latex pod2man
 
 all: $(CONVERTERS) man
 
-PERL = ../miniperl
+#PERL = ../miniperl
 
 POD = \
        perl.pod        \
@@ -21,8 +21,8 @@ POD = \
        perllol.pod     \
        perlmod.pod     \
        perlobj.pod     \
+       perltie.pod     \
        perlop.pod      \
-       perlovl.pod     \
        perlpod.pod     \
        perlre.pod      \
        perlref.pod     \
@@ -31,10 +31,11 @@ POD = \
        perlstyle.pod   \
        perlsub.pod     \
        perlsyn.pod     \
+       perltoc.pod     \
        perltrap.pod    \
        perlvar.pod     \
        perlxs.pod      \
-       perlxstut.pod
+       perlxstut.pod 
 
 MAN = \
        perl.man        \
@@ -53,8 +54,8 @@ MAN = \
        perllol.man     \
        perlmod.man     \
        perlobj.man     \
+       perltie.man     \
        perlop.man      \
-       perlovl.man     \
        perlpod.man     \
        perlre.man      \
        perlref.man     \
@@ -63,10 +64,11 @@ MAN = \
        perlstyle.man   \
        perlsub.man     \
        perlsyn.man     \
+       perltoc.man     \
        perltrap.man    \
        perlvar.man     \
        perlxs.man      \
-       perlxstut.man
+       perlxstut.man 
 
 HTML = \
        perl.html       \
@@ -85,8 +87,8 @@ HTML = \
        perllol.html    \
        perlmod.html    \
        perlobj.html    \
+       perltie.html    \
        perlop.html     \
-       perlovl.html    \
        perlpod.html    \
        perlre.html     \
        perlref.html    \
@@ -95,10 +97,11 @@ HTML = \
        perlstyle.html  \
        perlsub.html    \
        perlsyn.html    \
+       perltoc.html    \
        perltrap.html   \
        perlvar.html    \
        perlxs.html     \
-       perlxstut.html
+       perlxstut.html 
 
 TEX = \
        perl.tex        \
@@ -117,8 +120,8 @@ TEX = \
        perllol.tex     \
        perlmod.tex     \
        perlobj.tex     \
+       perltie.tex     \
        perlop.tex      \
-       perlovl.tex     \
        perlpod.tex     \
        perlre.tex      \
        perlref.tex     \
@@ -127,6 +130,7 @@ TEX = \
        perlstyle.tex   \
        perlsub.tex     \
        perlsyn.tex     \
+       perltoc.tex     \
        perltrap.tex    \
        perlvar.tex     \
        perlxs.tex      \
@@ -136,26 +140,35 @@ man:  pod2man $(MAN)
 
 # pod2html normally runs on all the pods at once in order to build up
 # cross-references.
-html: pod2html
-       $(PERL) pod2html *.pod
+html: pod2html 
+       $(PERL) pod2html $(POD)
 
 tex:   pod2latex $(TEX)
 
-.SUFFIXES: .pod .man
+.SUFFIXES: .pm .pod .man 
+
+.pm.man:     pod2man
+       $(PERL) pod2man $*.pm >$*.man
 
 .pod.man:     pod2man
        $(PERL) pod2man $*.pod >$*.man
 
-.SUFFIXES: .pod .html
+.SUFFIXES: .mp .pod .html
+
+.pm.html:    pod2html
+       $(PERL) pod2html $*.pod
 
 .pod.html:    pod2html
        $(PERL) pod2html $*.pod
 
-.SUFFIXES: .pod .tex
+.SUFFIXES: .pm .pod .tex
 
 .pod.tex: pod2latex
        $(PERL) pod2latex $*.pod
 
+.pm.tex: pod2latex
+       $(PERL) pod2latex $*.pod
+
 clean:
        rm -f $(MAN) $(HTML) $(TEX)
 
diff --git a/pod/PerlDoc/Functions.pm b/pod/PerlDoc/Functions.pm
new file mode 100644 (file)
index 0000000..24248e3
--- /dev/null
@@ -0,0 +1,295 @@
+package PerlDoc::Functions;
+
+#:vi:set ts=20
+
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT = qw(%Kinds %Type %Flavor %Type_Descriptions @Type_Order);
+
+%Type_Description = (
+    'ARRAY'    => 'Functions for real @ARRAYs',
+    'Binary'   => 'Functions for fixed length data or records',
+    'File'     => 'Functions for filehandles, files, or directories',
+    'Flow'     => 'Keywords related to control flow of your perl program',
+    'HASH'     => 'Functions for real %HASHes',
+    'I/O'      => 'Input and output functions',
+    'LIST'     => 'Functions for list data',
+    'Math'     => 'Numeric functions',
+    'Misc'     => 'Miscellaneous functions',
+    'Modules'  => 'Keywords related to perl modules',
+    'Network'  => 'Fetching network info',
+    'Objects'  => 'Keywords related to classes and object-orientedness',
+    'Process'  => 'Functions for processes and process groups',
+    'Regexp'   => 'Regular expressions and pattern matching',
+    'Socket'   => 'Low-level socket functions',
+    'String'   => 'Functions for SCALARs or strings',
+    'SysV'     => 'System V interprocess communication functions',
+    'Time'     => 'Time-related functions',
+    'User'     => 'Fetching user and group info',
+    'Namespace'        => 'Keywords altering or affecting scoping of identifiers',
+);
+
+@Type_Order = qw{
+    String
+    Regexp
+    Math
+    ARRAY
+    LIST
+    HASH
+    I/O
+    Binary
+    File
+    Flow
+    Namespace
+    Misc
+    Process
+    Modules
+    Objects
+    Socket
+    SysV
+    User
+    Network
+    Time
+};
+
+while (<DATA>) {
+    chomp;
+    s/#.*//;
+    next unless $_;
+    ($name, $type, $text) = split " ", $_, 3;
+    $Type{$name} = $type;
+    $Flavor{$name} = $text;
+    for $type ( split /[,\s]+/, $type ) {
+       push @{$Kinds{$type}}, $name;
+    }
+} 
+
+unless (caller) { 
+    foreach $type ( @Type_Order ) {
+       $list = join(", ", sort @{$Kinds{$type}});
+       $typedesc = $Type_Description{$type} . ":";
+       write;
+    } 
+}
+
+format = 
+
+^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+    $typedesc 
+~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+    $typedesc 
+ ~~  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+       $list
+.
+
+1
+
+__DATA__
+-X     File    a file test (-r, -x, etc)
+abs    Math    absolute value function
+accept Socket  accept an incoming socket connect
+alarm  Process schedule a SIGALRM 
+atan2  Math    arctangent of Y/X 
+bind   Socket  binds an address to a socket
+binmode        I/O     prepare binary files on old systems
+bless  Objects create an object 
+caller Flow,Namespace  get context of the current subroutine call
+chdir  File    change your current working directory
+chmod  File    changes the permissions on a list of files
+chomp  String  remove a trailing record separator from a string
+chop   String  remove the last character from a string
+chown  File    change the owership on a list of files
+chr    String  get character this number represents
+chroot File    make directory new root for path lookups
+close  I/O     close file (or pipe or socket) handle
+closedir       I/O     close directory handle
+connect        Socket  connect to a remove socket
+continue       Flow    optional trailing block in a while or foreach 
+cos    Math    cosine function
+crypt  String  one-way passwd-style encryption
+dbmclose       Objects,I/O     breaks binding on a tied dbm file
+dbmopen        Objects,I/O     create binding on a tied dbm file
+defined        Misc    test whether a value, variable, or function is defined
+delete HASH    deletes a value from a hash
+die    I/O,Flow        raise an exception or bail out
+do     Flow,Modules    turn a BLOCK into a TERM
+dump   Misc,Flow       create an immediate core dump
+each   HASH    retrieve the next key/value pair from a hash
+endgrent       User    be done using group file
+endhostent     User    be done using hosts file
+endnetent      User    be done using networks file
+endprotoent    Network be done using protocols file
+endpwent       User    be done using passwd file
+endservent     Network be done using services file
+eof    I/O     test a filehandle for its end
+eval   Flow,Misc       catch exceptions or compile code
+exec   Process abandon this program to run another
+exists HASH    test whether a hash key is present
+exit   Flow    terminate this program
+exp    Math    raise I<e> to a power
+fcntl  File    file control system all
+fileno I/O     return file descriptor from filehandle
+flock  I/O     lock an entire file with an advisory lock
+fork   Process create a new process just like this one
+format I/O     declare a picture format with use by the write() function
+formline       Misc    internal function used for formats
+getc   I/O     get     the next character from the filehandle
+getgrent       User    get next group record 
+getgrgid       User    get group record given group user ID
+getgrnam       User    get group record given group name
+gethostbyaddr  Network get host record given its address
+gethostbyname  Network get host record given name
+gethostent     Network get next hosts record 
+getlogin       User    return who logged in at this tty
+getnetbyaddr   Network get network record given its address
+getnetbyname   Network get networks record given name
+getnetent      Network get next networks record 
+getpeername    Socket  find the other hend of a socket connection
+getpgrp        Process get process group
+getppid        Process get parent process ID
+getpriority    Process get current nice value
+getprotobyname Network get protocol record given name
+getprotobynumber       Network get protocol record numeric protocol
+getprotoent    Network get next protocols record
+getpwent       User    get next passwd record
+getpwnam       User    get passwd record given user login name
+getpwuid       User    get passwd record given user ID
+getservbyname  Network get services record given its name
+getservbyport  Network get services record given numeric port
+getservent     Network get next services record 
+getsockname    Socket  retrieve the sockaddr for a given socket
+getsockopt     Socket  get socket options on a given socket
+glob   File            expand filenames using wildcards
+gmtime Time    convert UNIX time into record or string using Greenwich time
+goto   Flow    create spaghetti code
+grep   LIST    locate elements in a list test true against a given criterion
+hex    Math,String     convert a string to a hexadecimal number
+import Modules,Namespace       patch a module's namespace into your own
+index  String  find a substring within a string
+int    Math    get the integer portion of a number
+ioctl  File    system-dependent device control system call
+join   LIST    join a list into a string using a separator
+keys   HASH    retrieve list of indices from a hash
+kill   Process send a signal to a process or process group
+last   Flow    exit a block prematurely
+lc     String  return lower-case version of a string
+lcfirst        String  return a string with just the next letter in lower case
+length String  return the number of bytes in a string
+link   File    create a hard link in the filesytem
+listen Socket  register your socket as a server 
+local  Misc,Namespace  create a temporary value for a global variable (dynamic scoping)
+localtime      Time    convert UNIX time into record or string using local time
+log    Math    retrieve the natural logarithm for a number
+lstat  File    stat a symbolic link
+m//    Regexp  match a string with a regular expression pattern
+map    LIST    apply a change to a list to get back a new list with the changes
+mkdir  File    create a directory
+msgctl SysV    SysV IPC message control operations
+msgget SysV    get SysV IPC message queue
+msgrcv SysV    receive a SysV IPC message from a message queue
+msgsnd SysV    send a SysV IPC message to a message queue
+my     Misc,Namespace  declare and assign a local variable (lexical scoping)
+next   Flow    iterate a block prematurely
+no     Modules unimport some module symbols or semantics at compile time
+package        Modules,Objects,Namespace       declare a separate global namespace
+oct    String,Math     convert a string to an octal number
+open   File    open a file, pipe, or descriptor
+opendir        File    open a directory
+ord    String  find a character's numeric representation
+pack   Binary,String   convert a list into a binary representation
+pipe   Process open a pair of connected filehandles
+pop    ARRAY   remove the last element from an array and return it
+pos    Regexp  find or set the offset for the last/next m//g search
+print  I/O     output a list to a filehandle
+printf I/O     output a formatted list to a filehandle
+push   ARRAY   append one or more elements to an array
+q/STRING/      String  singly quote a string
+qq/STRING/     String  doubly quote a string
+quotemeta      Regexp  quote regular expression magic characters
+qw/STRING/     LIST    quote a list of words
+qx/STRING/     Process backquote quote a string
+rand   Math    retrieve the next pseudorandom number 
+read   I/O,Binary      fixed-length buffered input from a filehandle
+readdir        I/O     get a directory from a directory handle
+readlink       File    determine where a symbolic link is pointing
+recv   Socket  receive a message over a Socket
+redo   Flow    start this loop iteration over again
+ref    Objects find out the type of thing being referenced
+rename File    change a filename
+require        Modules load in external functions from a library at runtime
+reset  Misc    clear all variables of a given name
+return Flow    get out of a function early
+reverse        String,LIST     flip a string or a list
+rewinddir      I/O     reset directory handle
+rindex String  right-to-left substring search
+rmdir  File    remove a directory
+s///   Regexp  replace a pattern with a string
+scalar Misc    force a scalar context
+seek   I/O     reposition file pointer for random-access I/O
+seekdir        I/O     reposition directory pointer 
+select I/O     reset default output or do I/O multiplexing
+semctl SysV    SysV semaphore control operations
+semget SysV    get set of SysV semaphores
+semop  SysV    SysV semaphore operations
+send   Socket  send a message over a socket
+setgrent       User    prepare group file for use
+sethostent     Network prepare hosts file for use
+setnetent      Network prepare networks file for use
+setpgrp        Process set the process group of a process
+setpriority    Process set a process's nice value
+setprotoent    Network prepare protocols file for use
+setpwent       User    prepare passwd file for use
+setservent     Network prepare services file for use
+setsockopt     Socket  set some socket options
+shift  ARRAY   remove the first element of an array, and return it
+shmctl SysV    SysV shared memory operations
+shmget SysV    get SysV shared memory segment identifier
+shmread        SysV    read SysV shared memory 
+shmwrite       SysV    write SysV shared memory 
+shutdown       Socket  close down just half of a socket connection
+sin    Math    return the sin of a number
+sleep  Process block for some number of seconds
+socket Socket  create a socket
+socketpair     Socket  create a pair of sockets
+sort   LIST    sort a list of values 
+splice ARRAY   add or remove elements anywhere in an array
+split  Regexp  split up a string using a regexp delimiter
+sprintf        String  formatted print into a string   
+sqrt   Math    square root function
+srand  Math    seed the random number generator
+stat   File    get a file's status information
+study  Regexp  optimize input data for repeated searches
+sub    Flow    declare a subroutine, possibly anonymously
+substr String  get or alter a portion of a stirng
+symlink        File    create a symbolic link to a file
+syscall        I/O,Binary      execute an arbitrary system call
+sysread        I/O,Binary      fixed-length unbuffered input from a filehandle
+system Process run a separate program 
+syswrite       I/O,Binary      fixed-length unbuffered output to a filehandle
+tell   I/O     get current seekpointer on a filehandle
+telldir        I/O     get current seekpointer on a directory handle
+tie    Objects bind a variable to an object class 
+time   Time    return number of seconds since 1970
+times  Process,Time    return elapsed time for self and child processes
+tr///  String  transliterate a string
+truncate       I/O     shorten a file
+uc     String  return upper-case version of a string
+ucfirst        String  return a string with just the next letter in upper case
+umask  File    set file creation mode mask
+undef  Misc    remove a variable or function definition
+unlink File    remove one link to a file
+unpack Binary,LIST     convert binary structure into normal perl variables
+unshift        ARRAY   prepend more elements to the beginning of a list
+untie  Objects break a tie binding to a variable
+use    Modules,Namespace       load a module and import its namespace
+use    Objects load in a module at compile time
+utime  File    set a file's last access and modify times
+values HASH    return a list of the values in a hash
+vec    Binary  test or set particular bits in a string
+wait   Process wait for any child process to die
+waitpid        Process wait for  a particular child process to die
+wantarray      Misc,Flow       get list vs array context of current subroutine call
+warn   I/O     print debugging info
+write  I/O     print a picture record
+y///   String  transliterate a string
diff --git a/pod/PerlDoc/Functions.pm.POSIX b/pod/PerlDoc/Functions.pm.POSIX
new file mode 100644 (file)
index 0000000..5e2b435
--- /dev/null
@@ -0,0 +1,215 @@
+POSIX::_exit   POSIX   terminate a process
+POSIX::abort   POSIX   generate a fault
+POSIX::abs     POSIX   integer absolute value
+POSIX::access  POSIX   determine accessibility of file
+POSIX::acos    POSIX   trigonometric functions
+POSIX::alarm   POSIX   schedule signal after specified time
+POSIX::asctime POSIX   convert date and time
+POSIX::asin    POSIX   trigonometric functions
+POSIX::assert  POSIX   program verification
+POSIX::atan2   POSIX   trigonometric functions
+POSIX::atan    POSIX   trigonometric functions
+POSIX::atof    POSIX   convert string to double-precision number
+POSIX::atoi    POSIX   convert string to integer
+POSIX::atol    POSIX   convert string to integer
+POSIX::bsearch POSIX   binary search a sorted table
+POSIX::calloc  POSIX   memory allocator
+POSIX::ceil    POSIX   round to integral value in floating-point or integer format
+POSIX::chdir   POSIX   change current working directory
+POSIX::chmod   POSIX   change mode of file
+POSIX::chown   POSIX   change owner and group of a file
+POSIX::clearerr        POSIX   stream status inquiries
+POSIX::clock   POSIX   report CPU time used
+POSIX::close   POSIX   delete a descriptor
+POSIX::closedir        POSIX   directory operations
+POSIX::cos     POSIX   trigonometric functions
+POSIX::cosh    POSIX   hyperbolic functions
+POSIX::creat   POSIX   create a new file
+POSIX::ctermid POSIX   generate filename for terminal
+POSIX::ctime   POSIX   convert date and time
+POSIX::cuserid POSIX   get character login name of the user
+POSIX::dup2    POSIX   duplicate a descriptor
+POSIX::dup     POSIX   duplicate a descriptor
+POSIX::errno   POSIX   system error messages
+POSIX::execl   POSIX   execute a file
+POSIX::execle  POSIX   execute a file
+POSIX::execlp  POSIX   execute a file
+POSIX::execv   POSIX   execute a file
+POSIX::execve  POSIX   execute a file
+POSIX::execvp  POSIX   execute a file
+POSIX::exit    POSIX   terminate a process after performing cleanup
+POSIX::exp     POSIX   exponential, logarithm, power
+POSIX::fabs    POSIX   appendix and related miscellaneous functions for IEEE arithmetic
+POSIX::fclose  POSIX   close or flush a stream
+POSIX::fcntl   POSIX   file control
+POSIX::fdopen  POSIX   open a stream
+POSIX::feof    POSIX   stream status inquiries
+POSIX::ferror  POSIX   stream status inquiries
+POSIX::fflush  POSIX   close or flush a stream
+POSIX::fgetc   POSIX   get character or integer from stream
+POSIX::fgets   POSIX   get a string from a stream
+POSIX::fileno  POSIX   stream status inquiries
+POSIX::floor   POSIX   round to integral value in floating-point or integer format
+POSIX::fmod    POSIX   appendix and related miscellaneous functions for IEEE arithmetic
+POSIX::fopen   POSIX   open a stream
+POSIX::fork    POSIX   create a new process
+POSIX::fpathconf       POSIX   query file system related limits and options
+POSIX::fprintf POSIX   formatted output conversion
+POSIX::fputc   POSIX   put character or word on a stream
+POSIX::fputs   POSIX   put a string on a stream
+POSIX::fread   POSIX   buffered binary input/output
+POSIX::free    POSIX   memory allocator
+POSIX::freopen POSIX   open a stream
+POSIX::frexp   POSIX   traditional UNIX functions
+POSIX::fscanf  POSIX   formatted input conversion
+POSIX::fseek   POSIX   reposition a stream
+POSIX::fstat   POSIX   get file status
+POSIX::ftell   POSIX   reposition a stream
+POSIX::fwrite  POSIX   buffered binary input/output
+POSIX::getc    POSIX   get character or integer from stream
+POSIX::getchar POSIX   get character or integer from stream
+POSIX::getcwd  POSIX   get pathname of current working directory
+POSIX::getegid POSIX   get group identity
+POSIX::getenv  POSIX   return value for environment name
+POSIX::geteuid POSIX   get user identity
+POSIX::getgid  POSIX   get group identity
+POSIX::getgrgid        POSIX   get group file entry
+POSIX::getgrnam        POSIX   get group file entry
+POSIX::getgroups       POSIX   get or set supplementary group IDs
+POSIX::getlogin        POSIX   get login name
+POSIX::getpgrp POSIX   return or set the process group of a process
+POSIX::getpid  POSIX   get process identification
+POSIX::getppid POSIX   get process identification
+POSIX::getpwnam        POSIX   get password file entry
+POSIX::getpwuid        POSIX   get password file entry
+POSIX::gets    POSIX   get a string from a stream
+POSIX::getuid  POSIX   get user identity
+POSIX::gmtime  POSIX   convert date and time
+POSIX::isalnum POSIX   character classification and conversion macros and functions
+POSIX::isalpha POSIX   character classification and conversion macros and functions
+POSIX::isatty  POSIX   find name of a terminal
+POSIX::iscntrl POSIX   character classification and conversion macros and functions
+POSIX::isdigit POSIX   character classification and conversion macros and functions
+POSIX::isgraph POSIX   character classification and conversion macros and functions
+POSIX::islower POSIX   character classification and conversion macros and functions
+POSIX::isprint POSIX   character classification and conversion macros and functions
+POSIX::ispunct POSIX   character classification and conversion macros and functions
+POSIX::isspace POSIX   character classification and conversion macros and functions
+POSIX::isupper POSIX   character classification and conversion macros and functions
+POSIX::isxdigit        POSIX   character classification and conversion macros and functions
+POSIX::kill    POSIX   send a signal to a process or a group of processes
+POSIX::ldexp   POSIX   traditional UNIX functions
+POSIX::link    POSIX   make a hard link to a file
+POSIX::localeconv      POSIX   get numeric and monetary formatting conventions
+POSIX::localtime       POSIX   convert date and time
+POSIX::log10   POSIX   exponential, logarithm, power
+POSIX::log     POSIX   exponential, logarithm, power
+POSIX::longjmp POSIX   non-local goto
+POSIX::lseek   POSIX   move read/write pointer
+POSIX::malloc  POSIX   memory allocator
+POSIX::mblen   POSIX   multibyte character handling
+POSIX::mbstowcs        POSIX   multibyte character handling
+POSIX::mbtowc  POSIX   multibyte character handling
+POSIX::memchr  POSIX   memory operations
+POSIX::memcmp  POSIX   memory operations
+POSIX::memcpy  POSIX   memory operations
+POSIX::memset  POSIX   memory operations
+POSIX::mkdir   POSIX   make a directory file
+POSIX::mkfifo  POSIX   make a special file
+POSIX::modf    POSIX   traditional UNIX functions
+POSIX::nice    POSIX   change nice value of a process
+POSIX::open    POSIX   open or create a file for reading or writing
+POSIX::opendir POSIX   directory operations
+POSIX::pathconf        POSIX   query file system related limits and options
+POSIX::pause   POSIX   stop until signal
+POSIX::perror  POSIX   system error messages
+POSIX::pipe    POSIX   create an interprocess communication channel
+POSIX::pow     POSIX   exponential, logarithm, power
+POSIX::pow     POSIX   multiple precision integer arithmetic
+POSIX::printf  POSIX   formatted output conversion
+POSIX::putc    POSIX   put character or word on a stream
+POSIX::putchar POSIX   put character or word on a stream
+POSIX::puts    POSIX   put a string on a stream
+POSIX::qsort   POSIX   quicker sort
+POSIX::rand    POSIX   simple random number generator
+POSIX::read    POSIX   read input
+POSIX::readdir POSIX   directory operations
+POSIX::realloc POSIX   memory allocator
+POSIX::rename  POSIX   change the name of a file
+POSIX::rewind  POSIX   reposition a stream
+POSIX::rewinddir       POSIX   directory operations
+POSIX::rmdir   POSIX   remove a directory file
+POSIX::scanf   POSIX   formatted input conversion
+POSIX::setbuf  POSIX   assign buffering to a stream
+POSIX::setgid  POSIX   set user and group ID
+POSIX::setjmp  POSIX   non-local goto
+POSIX::setlocale       POSIX   set international environment
+POSIX::setpgid POSIX   set process group ID for job control
+POSIX::setsid  POSIX   create session and set process group ID
+POSIX::setuid  POSIX   set user and group ID
+POSIX::setvbuf POSIX   assign buffering to a stream
+POSIX::sigaction       POSIX   examine and change signal action 
+POSIX::siglongjmp      POSIX   non-local goto
+POSIX::sigpending      POSIX   examine pending signals
+POSIX::sigprocmask     POSIX   examine and change blocked signals
+POSIX::sigsetjmp       POSIX   non-local goto
+POSIX::sigsuspend      POSIX   automatically release blocked signals and wait for interrupt
+POSIX::sin     POSIX   trigonometric functions
+POSIX::sinh    POSIX   hyperbolic functions
+POSIX::sleep   POSIX   suspend execution for interval
+POSIX::sprintf POSIX   formatted output conversion
+POSIX::sqrt    POSIX   cube root, square root
+POSIX::srand   POSIX   simple random number generator
+POSIX::sscanf  POSIX   formatted input conversion
+POSIX::stat    POSIX   get file status
+POSIX::strcat  POSIX   string operations
+POSIX::strchr  POSIX   string operations
+POSIX::strcmp  POSIX   string operations
+POSIX::strcoll POSIX   compare or transform strings using collating information
+POSIX::strcpy  POSIX   string operations
+POSIX::strcspn POSIX   string operations
+POSIX::strftime        POSIX   convert date and time
+POSIX::strlen  POSIX   string operations
+POSIX::strncat POSIX   string operations
+POSIX::strncmp POSIX   string operations
+POSIX::strncpy POSIX   string operations
+POSIX::strpbrk POSIX   string operations
+POSIX::strrchr POSIX   string operations
+POSIX::strspn  POSIX   string operations
+POSIX::strstr  POSIX   string operations
+POSIX::strtod  POSIX   convert string to double-precision number
+POSIX::strtok  POSIX   string operations
+POSIX::strtol  POSIX   convert string to integer
+POSIX::strxfrm POSIX   compare or transform strings using collating information
+POSIX::sysconf POSIX   query system related limits, values, options
+POSIX::system  POSIX   issue a shell command
+POSIX::tan     POSIX   trigonometric functions
+POSIX::tanh    POSIX   hyperbolic functions
+POSIX::tcdrain POSIX   get and set terminal attributes, line control, get and set baud rate, get and set terminal foreground process group ID
+POSIX::tcflow  POSIX   get and set terminal attributes, line control, get and set baud rate, get and set terminal foreground process group ID
+POSIX::tcflush POSIX   get and set terminal attributes, line control, get and set baud rate, get and set terminal foreground process group ID
+POSIX::tcgetpgrp       POSIX   get, set foreground process group ID
+POSIX::tcsendbreak     POSIX   get and set terminal attributes, line control, get and set baud rate, get and set terminal foreground process group ID
+POSIX::tcsetpgrp       POSIX   get, set foreground process group ID
+POSIX::tell    POSIX   move read/write pointer
+POSIX::time    POSIX   get date and time
+POSIX::times   POSIX   get process times
+POSIX::tmpfile POSIX   create a temporary file
+POSIX::tmpnam  POSIX   create a name for a temporary file
+POSIX::tolower POSIX   character classification and conversion macros and functions
+POSIX::toupper POSIX   character classification and conversion macros and functions
+POSIX::ttyname POSIX   find name of a terminal
+POSIX::tzset   POSIX   convert date and time
+POSIX::umask   POSIX   set file creation mode mask
+POSIX::uname   POSIX   get information about current system
+POSIX::ungetc  POSIX   push character back into input stream
+POSIX::unlink  POSIX   remove directory entry
+POSIX::utime   POSIX   set file times
+POSIX::vfprintf        POSIX   print formatted output of a varargs argument list
+POSIX::vprintf POSIX   print formatted output of a varargs argument list
+POSIX::vsprintf        POSIX   print formatted output of a varargs argument list
+POSIX::wait    POSIX   wait for process to terminate or stop, examine returned status
+POSIX::waitpid POSIX   wait for process to terminate or stop, examine returned status
+POSIX::wcstombs        POSIX   multibyte character handling
+POSIX::wctomb  POSIX   multibyte character handling
+POSIX::write   POSIX   write output
diff --git a/pod/buildtoc b/pod/buildtoc
new file mode 100644 (file)
index 0000000..77ddcd0
--- /dev/null
@@ -0,0 +1,202 @@
+use File::Find;
+use Cwd;
+
+@pods = qw{
+           perl perldata perlsyn perlop perlre perlrun perlfunc perlvar
+           perlsub perlmod perlref perldsc perllol perlobj perltie
+           perlbot perldebug perldiag perlform perlipc perlsec perltrap
+           perlstyle perlxs perlxstut perlguts perlcall perlembed perlpod
+           perlbook 
+       };
+for (@pods) { s/$/.pod/ } 
+
+$/ = '';
+@ARGV = @pods;
+
+($_= <<EOPOD2B) =~ s/^\t//gm && print;
+
+       =head1 NAME
+
+       perltoc - perl documentation table of contents
+
+       =head1 DESCRIPTION
+
+       This page provides a brief table of contents for the rest of the Perl 
+       documentation set.  It is meant to be be quickly scanned or grepped 
+       through to locate the proper section you're looking for.
+
+       =head1 BASIC DOCUMENTATION
+
+EOPOD2B
+
+podset(@pods);
+
+find \&getpods => qw(../lib ../ext);
+sub getpods {
+    if (/\.p(od|m)$/) { 
+       my $file = $File::Find::name;
+       die "tut $name" if $file =~ /TUT/;
+       unless (open (F, "< $_\0")) {
+           warn "bogus <$file>: $!";
+           system "ls", "-l", $file;
+       }  else { 
+           my $line;
+           while ($line = <F>) {
+               if ($line =~ /^=head1\s+NAME\b/) {
+                   push @modpods, $file;
+                   #warn "GOOD $file\n";
+                   return;
+               } 
+           } 
+           warn "EVIL $file\n";
+       }
+    }
+}
+
+die "no pods" unless @modpods;
+
+for (@modpods) {
+    #($name) = /(\w+)\.p(m|od)$/;
+    $name = path2modname($_);
+    if ($name =~ /^[a-z]/) {
+       push @pragmata, $_;
+    } else {
+       if ($done{$name}++) {
+           # warn "already did $_\n";
+           next;
+       } 
+       push @modules, $_;
+       push @modname, $name;
+    } 
+} 
+
+($_= <<EOPOD2B) =~ s/^\t//gm && print;
+
+
+       =head1 PRAGMA DOCUMENTATION
+
+EOPOD2B
+
+podset(sort @pragmata);
+
+($_= <<EOPOD2B) =~ s/^\t//gm && print;
+
+
+       =head1 MODULE DOCUMENTATION
+
+EOPOD2B
+
+podset( @modules[ sort { $modname[$a] cmp $modname[$b] } 0 .. $#modules ] );
+
+($_= <<EOPOD2B) =~ s/^\t//gm;
+
+       =head1 AUXILIARY DOCUMENTATION
+
+       Here should be listed all the extra program's docs, but they
+       don't all have man pages yet:
+
+       =item a2p
+
+       =item s2p
+
+       =item find2perl
+       
+       =item h2ph
+       
+       =item c2ph
+
+       =item h2xs
+
+       =item xsubpp
+
+       =item pod2man 
+
+       =item wrapsuid
+
+
+       =head1 AUTHOR
+
+       Larry Wall E<lt><F<lwall\@netlabs.com>E<gt>, with the help of oodles 
+       of other folks.
+
+
+EOPOD2B
+print;
+
+exit;
+
+sub podset {
+    local @ARGV = @_;
+
+    while(<>) {
+       if (s/^=head1 (NAME)\s*/=head2 /) {
+           $pod = path2modname($ARGV);
+           sub path2modname {
+               local $_ = shift;
+               s/\.p(m|od)$//;
+               s-.*?/(lib|ext)/--;
+               s-/-::-g;
+               s/(\w+)::\1/$1/;
+               return $_;
+           }
+           unitem(); unhead2();
+           print "\n \n\n=head2 ";
+           $_ = <>;
+           if ( /^\s*$pod\b/ ) {
+               print;
+           } else {
+               s/^/$pod, /;
+               print;
+           } 
+           next;
+       }
+       if (s/^=head1 (.*)/=item $1/) {
+           unitem(); unhead2();
+           print; nl(); next;
+       } 
+       if (s/^=head2 (.*)/=item $1/) {
+           unitem();
+           print "=over\n\n" unless $inhead2;
+           $inhead2 = 1;
+           print; nl(); next;
+
+       } 
+       if (s/^=item (.*)\n/$1/) {
+           next if $pod eq 'perldiag';
+           s/^\s*\*\s*$// && next;
+           s/^\s*\*\s*//;
+           s/\s+$//;
+           next if /^[\d.]+$/;
+           next if $pod eq 'perlmod' && /^ftp:/;
+           ##print "=over\n\n" unless $initem;
+           print ", " if $initem;
+           $initem = 1;
+           s/\.$//;
+           print; next;
+       } 
+    } 
+
+} 
+
+sub unhead2 {
+    if ($inhead2) {
+       print "\n\n=back\n\n";
+    } 
+    $inhead2 = 0; 
+    $initem = 0;
+} 
+
+sub unitem {
+    if ($initem) {
+       print "\n\n";
+       ##print "\n\n=back\n\n";
+    } 
+    $initem = 0;
+} 
+
+sub nl {
+    print "\n";
+} 
index f0504c4..5f3918c 100644 (file)
@@ -8,6 +8,7 @@ For ease of access, the Perl manual has been split up into a number
 of sections:
 
     perl       Perl overview (this section)
+    perltoc    Perl documentation table of contents
     perldata   Perl data structures
     perlsyn    Perl syntax
     perlop     Perl operators and precedence
@@ -21,6 +22,7 @@ of sections:
     perldsc    Perl data structures intro
     perllol    Perl data structures: lists of lists
     perlobj    Perl objects
+    perltie    Perl objects hidden behind simple variables
     perlbot    Perl OO tricks and examples
     perldebug  Perl debugging
     perldiag   Perl diagnostic messages
@@ -33,7 +35,6 @@ of sections:
     perlxstut  Perl XS tutorial
     perlguts   Perl internal functions for those doing extensions 
     perlcall   Perl calling conventions from C
-    perlovl    Perl overloading semantics
     perlembed  Perl how to embed perl in your C or C++ app
     perlpod    Perl plain old documentation
     perlbook   Perl book information
@@ -286,7 +287,10 @@ 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.
 
-See the perl bugs database at L<http://perl.com/perl/bugs/>.
+See the perl bugs database at F<http://perl.com/perl/bugs/>.  You may
+mail your bug reports (be sure to include full configuration information
+as output by the myconfig program in the perl source tree) to
+F<perlbug@perl.com>.
 
 Perl actually stands for Pathologically Eclectic Rubbish Lister, but
 don't tell anyone I said that.
index 61a3726..72c1870 100644 (file)
@@ -2,7 +2,7 @@
 
 perlbot - Bag'o Object Tricks (the BOT)
 
-=head1 INTRODUCTION
+=head1 DESCRIPTION
 
 The following collection of tricks and hints is intended to whet curious
 appetites about such things as the use of instance variables and the
index 648f092..9b3798f 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-perldata - Perl data structures
+perldata - Perl data types
 
 =head1 DESCRIPTION
 
@@ -60,8 +60,8 @@ of this, see L<perlref>.
 
 Names that start with a digit may only contain more digits.  Names
 which do not start with a letter, underscore,  or digit are limited to
-one character, e.g.  "$%" or "$$".  (Most of these one character names
-have a predefined significance to Perl.  For instance, $$ is the
+one character, e.g.  C<$%> or C<$$>.  (Most of these one character names
+have a predefined significance to Perl.  For instance, C<$$> is the
 current process id.)
 
 =head2 Context
@@ -138,7 +138,7 @@ array.  An undefined null scalar may become defined the first time you
 use it as if it were defined, but prior to that you can use the
 defined() operator to determine whether the value is defined or not.
 
-To find out whether a given string is a valid non-zero number, it's usally
+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<awk>:
@@ -147,6 +147,18 @@ numbers count as 0, just as the do in I<awk>:
        warn "That doesn't look like a number";
     } 
 
+That's usually preferable because otherwise you won't treat IEEE notations
+like C<NaN> or C<Infinity> properly.  At other times you might prefer to
+use a regular expression to check whether data is numeric.  See L<perlre>
+for details on regular expressions.
+
+    warn "has nondigits"       if     /\D/;
+    warn "not a whole number"   unless /^\d+$/;
+    warn "not an integer"       unless /^[+-]?\d+$/     
+    warn "not a decimal number" unless /^[+-]?\d+\.?\d*$/ 
+    warn "not a C float" 
+       unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
+
 The length of an array is a scalar value.  You may find the length of
 array @days by evaluating C<$#days>, as in B<csh>.  (Actually, it's not
 the length of the array, it's the subscript of the last element, since
@@ -252,7 +264,8 @@ logical end of the script before the actual end of file.  Any following
 text is ignored, but may be read via the DATA filehandle.  (The DATA
 filehandle may read data only from the main script, but not from any
 required file or evaluated string.)  The two control characters ^D and
-^Z are synonyms for __END__ (or __DATA__ in a module).
+^Z are synonyms for __END__ (or __DATA__ in a module; see L<SelfLoader> for 
+details on __DATA__).
 
 A word that has no other interpretation in the grammar will
 be treated as if it were a quoted string.  These are known as
@@ -471,3 +484,39 @@ or for using call-by-named-parameter to complicated functions:
                linebreak => 'true',
                labels    => \%labels
    );
+
+Note that just because a hash is initialized in that order doesn't
+mean that it comes out in that order.  See L<perlfunc/sort> for examples
+of how to arrange for an output ordering.
+
+=head2 Typeglobs and FileHandles
+
+Perl uses an internal type called a I<typeglob> to hold an entire
+symbol table entry.  The type prefix of a typeglob is a C<*>, because
+it represents all types.  This used to be the preferred way to 
+pass arrays and hashes by reference into a function, but now that
+we have real references, this is seldom needed.
+
+One place where you still use typeglobs (or references thereto)
+is for passing or storing filehandles.  If you want to save away
+a filehandle, do it this way:
+
+    $fh = *STDOUT;
+
+or perhaps as a real reference, like this:
+
+    $fh = \*STDOUT;
+
+This is also the way to create a local filehandle.  For example:
+
+    sub newopen {
+       my $path = shift;
+       local *FH;  # not my!
+       open (FH, $path) || return undef;
+       return \*FH;
+    }
+    $fh = newopen('/etc/passwd');
+
+See L<perlref>, L<perlsub>, and L<perlmod/"Symbols Tables"> for more
+discussion on typeglobs.  See L<perlfunc/open> for other ways of
+generating filehandles.
index ad4a532..83a30c3 100644 (file)
@@ -13,6 +13,7 @@ desperation):
     (F) A fatal error (trappable).
     (P) An internal error you should never see (trappable).
     (X) A very fatal error (non-trappable).
+    (A) An alien error message (not generated by Perl).
 
 Optional warnings are enabled by using the B<-w> switch.  Warnings may
 be captured by setting C<$^Q> to a reference to a routine that will be
@@ -98,6 +99,30 @@ before it could possibly have been used.
 
 (F) The final summary message when a C<perl -c> succeeds.
 
+=item %s: Command not found.
+
+(A) You've accidentally run your script through B<csh> instead
+of Perl.  Check the <#!> line, or manually feed your script
+into Perl yourself.
+
+=item %s: Expression syntax.
+
+(A) You've accidentally run your script through B<csh> instead
+of Perl.  Check the <#!> line, or manually feed your script
+into Perl yourself.
+
+=item %s: Undefined variable.
+
+(A) You've accidentally run your script through B<csh> instead
+of Perl.  Check the <#!> line, or manually feed your script
+into Perl yourself.
+
+=item %s: not found
+
+(A) You've accidentally run your script through the Bourne shell 
+instead of Perl.  Check the <#!> line, or manually feed your script
+into Perl yourself.
+
 =item B<-P> not allowed for setuid/setgid script
 
 (F) The script would have to be opened by the C preprocessor by name,
@@ -245,6 +270,12 @@ wasn't a symbol table entry.
 (P) An internal request asked to add a hash entry to something that
 wasn't a symbol table entry.
 
+=item Badly places ()'s
+
+(A) You've accidentally run your script through B<csh> instead
+of Perl.  Check the <#!> line, or manually feed your script
+into Perl yourself.
+
 =item BEGIN failed--compilation aborted
 
 (F) An untrapped exception was raised while executing a BEGIN subroutine.
@@ -1556,7 +1587,7 @@ Perl assumes that memory is now corrupted.  See L<perlfunc/ioctl>.
 =item Precedence problem: open %s should be open(%s)
 
 (S) The old irregular construct
-    
+
     open FOO || die;
 
 is now misinterpreted as
@@ -1847,6 +1878,12 @@ the only way to figure out what's triggering the error is to call
 C<perl -c> repeatedly, chopping away half the program each time to see
 if the error went away.  Sort of the cybernetic version of S<20 questions>.
 
+=item syntax error at line %d: `%s' unexpected
+
+(A) You've accidentally run your script through the Bourne shell 
+instead of Perl.  Check the <#!> line, or manually feed your script
+into Perl yourself.
+
 =item System V IPC is not implemented on this machine
 
 (F) You tried to do something with a function beginning with "sem", "shm"
@@ -1911,6 +1948,14 @@ you're not running on Unix.
 (F) There has to be at least one argument to syscall() to specify the
 system call to call, silly dilly.
 
+=item Too many ('s
+
+=item Too many )'s
+
+(A) You've accidentally run your script through B<csh> instead
+of Perl.  Check the <#!> line, or manually feed your script
+into Perl yourself.
+
 =item Too many args to syscall
 
 (F) Perl only supports a maximum of 14 args to syscall().
@@ -2161,6 +2206,12 @@ something else of the same name (usually a subroutine) is exported
 by that module.  It usually means you put the wrong funny character
 on the front of your variable.
 
+=item Variable syntax.
+
+(A) You've accidentally run your script through B<csh> instead
+of Perl.  Check the <#!> line, or manually feed your script
+into Perl yourself.
+
 =item Warning: unable to close filehandle %s properly.
 
 (S) The implicit close() done by an open() got an error indication on the 
index 1d51af8..258e9ab 100644 (file)
@@ -1,8 +1,8 @@
-=head1 TITLE
+=head1 NAME
 
-perldsc - Manipulating Complex Data Structures in Perl
+perldsc - Perl Data Structures Cookbook
 
-=head1 INTRODUCTION
+=head1 DESCRIPTION
 
 The single feature most sorely lacking in the Perl programming language
 prior to its 5.0 release was complex data structures.  Even without direct
@@ -335,14 +335,493 @@ given the assignment to $LoL above, here's the debugger output:
 
 There's also a lower-case B<x> command which is nearly the same.
 
+=head1 CODE EXAMPLES
+
+Presented with little comment (these will get their own man pages someday)
+here are short code examples illustrating access of various 
+types of data structures.
+
+=head1 LISTS OF LISTS
+
+=head2 Declaration of a LIST OF LISTS
+
+ @LoL = (
+        [ "fred", "barney" ],
+        [ "george", "jane", "elroy" ],
+        [ "homer", "marge", "bart" ],
+      );
+
+=head2 Generation of a LIST OF LISTS
+
+ # reading from file
+ while ( <> ) {
+     push @LoL, [ split ];
+
+
+ # calling a function
+ for $i ( 1 .. 10 ) {
+     $LoL[$i] = [ somefunc($i) ];
+
+
+ # using temp vars
+ for $i ( 1 .. 10 ) {
+     @tmp = somefunc($i);
+     $LoL[$i] = [ @tmp ];
+
+
+ # add to an existing row
+ push @{ $LoL[0] }, "wilma", "betty";
+
+=head2 Access and Printing of a LIST OF LISTS
+
+ # one element
+ $LoL[0][0] = "Fred";
+
+ # another element
+ $LoL[1][1] =~ s/(\w)/\u$1/;
+
+ # print the whole thing with refs
+ for $aref ( @LoL ) {
+     print "\t [ @$aref ],\n";
+
+
+ # print the whole thing with indices
+ for $i ( 0 .. $#LoL ) {
+     print "\t [ @{$LoL[$i]} ],\n";
+
+
+ # print the whole thing one at a time
+ for $i ( 0 .. $#LoL ) {
+     for $j ( 0 .. $#{$LoL[$i]} ) {
+         print "elt $i $j is $LoL[$i][$j]\n";
+     }
+
+
+=head1 HASHES OF LISTS
+
+=head2 Declaration of a HASH OF LISTS
+
+ %HoL = (
+        "flintstones"        => [ "fred", "barney" ],
+        "jetsons"            => [ "george", "jane", "elroy" ],
+        "simpsons"           => [ "homer", "marge", "bart" ],
+      );
+
+=head2 Generation of a HASH OF LISTS
+
+ # reading from file
+ # flintstones: fred barney wilma dino
+ while ( <> ) {
+     next unless s/^(.*?):\s*//;
+     $HoL{$1} = [ split ];
+
+
+ # reading from file; more temps
+ # flintstones: fred barney wilma dino
+ while ( $line = <> ) {
+     ($who, $rest) = split /:\s*/, $line, 2;
+     @fields = split ' ', $rest;
+     $HoL{$who} = [ @fields ];
+
+
+ # calling a function that returns a list
+ for $group ( "simpsons", "jetsons", "flintstones" ) {
+     $HoL{$group} = [ get_family($group) ];
+
+
+ # likewise, but using temps
+ for $group ( "simpsons", "jetsons", "flintstones" ) {
+     @members = get_family($group);
+     $HoL{$group} = [ @members ];
+
+
+ # append new members to an existing family
+ push @{ $HoL{"flintstones"} }, "wilma", "betty";
+
+=head2 Access and Printing of a HASH OF LISTS
+
+ # one element
+ $HoL{flintstones}[0] = "Fred";
+
+ # another element
+ $HoL{simpsons}[1] =~ s/(\w)/\u$1/;
+
+ # print the whole thing
+ foreach $family ( keys %HoL ) {
+     print "$family: @{ $HoL{$family} }\n"
+
+
+ # print the whole thing with indices
+ foreach $family ( keys %HoL ) {
+     print "family: ";
+     foreach $i ( 0 .. $#{ $HoL{$family} ) {
+         print " $i = $HoL{$family}[$i]";
+     }
+     print "\n";
+
+
+ # print the whole thing sorted by number of members
+ foreach $family ( sort { @{$HoL{$b}} <=> @{$HoL{$b}} } keys %HoL ) {
+     print "$family: @{ $HoL{$family} }\n"
+
+ # print the whole thing sorted by number of members and name
+ foreach $family ( sort { @{$HoL{$b}} <=> @{$HoL{$a}} } keys %HoL ) {
+     print "$family: ", join(", ", sort @{ $HoL{$family}), "\n";
+
+=head1 LISTS OF HASHES
+
+=head2 Declaration of a LIST OF HASHES
+
+ @LoH = (
+        {
+           Lead      => "fred",
+           Friend    => "barney",
+        },
+        {
+            Lead     => "george",
+            Wife     => "jane",
+            Son      => "elroy",
+        },
+        {
+            Lead     => "homer",
+            Wife     => "marge",
+            Son      => "bart",
+        }
+  );
+
+=head2 Generation of a LIST OF HASHES
+
+ # reading from file
+ # format: LEAD=fred FRIEND=barney
+ while ( <> ) {
+     $rec = {};
+     for $field ( split ) {
+         ($key, $value) = split /=/, $field;
+         $rec->{$key} = $value;
+     }
+     push @LoH, $rec;
+
+
+ # reading from file
+ # format: LEAD=fred FRIEND=barney
+ # no temp
+ while ( <> ) {
+     push @LoH, { split /[\s+=]/ };
+
+
+ # calling a function  that returns a key,value list, like
+ # "lead","fred","daughter","pebbles"
+ while ( %fields = getnextpairset() )
+     push @LoH, { %fields };
+
+
+ # likewise, but using no temp vars
+ while (<>) {
+     push @LoH, { parsepairs($_) };
+
+
+ # add key/value to an element
+ $LoH[0]{"pet"} = "dino";
+ $LoH[2]{"pet"} = "santa's little helper";
+
+=head2 Access and Printing of a LIST OF HASHES
+
+ # one element
+ $LoH[0]{"lead"} = "fred";
+
+ # another element
+ $LoH[1]{"lead"} =~ s/(\w)/\u$1/;
+
+ # print the whole thing with refs
+ for $href ( @LoH ) {
+     print "{ ";
+     for $role ( keys %$href ) {
+         print "$role=$href->{$role} ";
+     }
+     print "}\n";
+
+
+ # print the whole thing with indices
+ for $i ( 0 .. $#LoH ) {
+     print "$i is { ";
+     for $role ( keys %{ $LoH[$i] } ) {
+         print "$role=$LoH[$i]{$role} ";
+     }
+     print "}\n";
+
+
+ # print the whole thing one at a time
+ for $i ( 0 .. $#LoH ) {
+     for $role ( keys %{ $LoH[$i] } ) {
+         print "elt $i $role is $LoH[$i]{$role}\n";
+     }
+
+=head1 HASHES OF HASHES
+
+=head2 Declaration of a HASH OF HASHES
+
+ %HoH = (
+        "flintstones" => {
+            "lead"    => "fred",
+            "pal"     => "barney",
+        },
+        "jetsons"     => {
+             "lead"   => "george",
+             "wife"   => "jane",
+             "his boy"=> "elroy",
+         }
+        "simpsons"    => {
+             "lead"   => "homer",
+             "wife"   => "marge",
+             "kid"    => "bart",
+      );
+
+=head2 Generation of a HASH OF HASHES
+
+ # reading from file
+ # flintstones: lead=fred pal=barney wife=wilma pet=dino
+ while ( <> ) {
+     next unless s/^(.*?):\s*//;
+     $who = $1;
+     for $field ( split ) {
+         ($key, $value) = split /=/, $field;
+         $HoH{$who}{$key} = $value;
+     }
+
+
+ # reading from file; more temps
+ while ( <> ) {
+     next unless s/^(.*?):\s*//;
+     $who = $1;
+     $rec = {};
+     $HoH{$who} = $rec;
+     for $field ( split ) {
+         ($key, $value) = split /=/, $field;
+         $rec->{$key} = $value;
+     }
+
+
+ # calling a function  that returns a key,value list, like
+ # "lead","fred","daughter","pebbles"
+ while ( %fields = getnextpairset() )
+     push @a, { %fields };
+
+
+ # calling a function  that returns a key,value hash
+ for $group ( "simpsons", "jetsons", "flintstones" ) {
+     $HoH{$group} = { get_family($group) };
+
+
+ # likewise, but using temps
+ for $group ( "simpsons", "jetsons", "flintstones" ) {
+     %members = get_family($group);
+     $HoH{$group} = { %members };
+
+
+ # append new members to an existing family
+ %new_folks = (
+     "wife" => "wilma",
+     "pet"  => "dino";
+ );
+ for $what (keys %new_folks) {
+     $HoH{flintstones}{$what} = $new_folks{$what};
+
+
+=head2 Access and Printing of a HASH OF HASHES
+
+ # one element
+ $HoH{"flintstones"}{"wife"} = "wilma";
+
+ # another element
+ $HoH{simpsons}{lead} =~ s/(\w)/\u$1/;
+
+ # print the whole thing
+ foreach $family ( keys %HoH ) {
+     print "$family: ";
+     for $role ( keys %{ $HoH{$family} } {
+         print "$role=$HoH{$family}{$role} ";
+     }
+     print "}\n";
+
+
+ # print the whole thing  somewhat sorted
+ foreach $family ( sort keys %HoH ) {
+     print "$family: ";
+     for $role ( sort keys %{ $HoH{$family} } {
+         print "$role=$HoH{$family}{$role} ";
+     }
+     print "}\n";
+
+
+ # print the whole thing sorted by number of members
+ foreach $family ( sort { keys %{$HoH{$b}} <=> keys %{$HoH{$b}} } keys %HoH ) {
+     print "$family: ";
+     for $role ( sort keys %{ $HoH{$family} } {
+         print "$role=$HoH{$family}{$role} ";
+     }
+     print "}\n";
+
+
+ # establish a sort order (rank) for each role
+ $i = 0;
+ for ( qw(lead wife son daughter pal pet) ) { $rank{$_} = ++$i }
+
+ # now print the whole thing sorted by number of members
+ foreach $family ( sort { keys %{$HoH{$b}} <=> keys %{$HoH{$b}} } keys %HoH ) {
+     print "$family: ";
+     # and print these according to rank order
+     for $role ( sort { $rank{$a} <=> $rank{$b} keys %{ $HoH{$family} } {
+         print "$role=$HoH{$family}{$role} ";
+     }
+     print "}\n";
+
+
+=head1 MORE ELABORATE RECORDS
+
+=head2 Declaration of MORE ELABORATE RECORDS
+
+Here's a sample showing how to create and use a record whose fields are of
+many different sorts:
+
+     $rec = {
+         STRING  => $string,
+         LIST    => [ @old_values ],
+         LOOKUP  => { %some_table },
+         FUNC    => \&some_function,
+         FANON   => sub { $_[0] ** $_[1] },
+         FH      => \*STDOUT,
+     };
+
+     print $rec->{STRING};
+
+     print $rec->{LIST}[0];
+     $last = pop @ { $rec->{LIST} };
+
+     print $rec->{LOOKUP}{"key"};
+     ($first_k, $first_v) = each %{ $rec->{LOOKUP} };
+
+     $answer = &{ $rec->{FUNC} }($arg);
+     $answer = &{ $rec->{FANON} }($arg1, $arg2);
+
+     # careful of extra block braces on fh ref
+     print { $rec->{FH} } "a string\n";
+
+     use FileHandle;
+     $rec->{FH}->autoflush(1);
+     $rec->{FH}->print(" a string\n");
+
+=head2 Declaration of a HASH OF COMPLEX RECORDS
+
+     %TV = (
+        "flintstones" => {
+            series   => "flintstones",
+            nights   => [ qw(monday thursday friday) ];
+            members  => [
+                { name => "fred",    role => "lead", age  => 36, },
+                { name => "wilma",   role => "wife", age  => 31, },
+                { name => "pebbles", role => "kid", age  =>  4, },
+            ],
+        },
+
+        "jetsons"     => {
+            series   => "jetsons",
+            nights   => [ qw(wednesday saturday) ];
+            members  => [
+                { name => "george",  role => "lead", age  => 41, },
+                { name => "jane",    role => "wife", age  => 39, },
+                { name => "elroy",   role => "kid",  age  =>  9, },
+            ],
+         },
+
+        "simpsons"    => {
+            series   => "simpsons",
+            nights   => [ qw(monday) ];
+            members  => [
+                { name => "homer", role => "lead", age  => 34, },
+                { name => "marge", role => "wife", age => 37, },
+                { name => "bart",  role => "kid",  age  =>  11, },
+            ],
+         },
+      );
+
+=head2 Generation of a HASH OF COMPLEX RECORDS
+
+     # reading from file
+     # this is most easily done by having the file itself be
+     # in the raw data format as shown above.  perl is happy
+     # to parse complex datastructures if declared as data, so
+     # sometimes it's easiest to do that
+
+     # here's a piece by piece build up
+     $rec = {};
+     $rec->{series} = "flintstones";
+     $rec->{nights} = [ find_days() ];
+
+     @members = ();
+     # assume this file in field=value syntax
+     while () {
+         %fields = split /[\s=]+/;
+         push @members, { %fields };
+     }
+     $rec->{members} = [ @members ];
+
+     # now remember the whole thing
+     $TV{ $rec->{series} } = $rec;
+
+     ###########################################################
+     # now, you might want to make interesting extra fields that
+     # include pointers back into the same data structure so if
+     # change one piece, it changes everywhere, like for examples
+     # if you wanted a {kids} field that was an array reference
+     # to a list of the kids' records without having duplicate
+     # records and thus update problems.
+     ###########################################################
+     foreach $family (keys %TV) {
+         $rec = $TV{$family}; # temp pointer
+         @kids = ();
+         for $person ( @{$rec->{members}} ) {
+             if ($person->{role} =~ /kid|son|daughter/) {
+                 push @kids, $person;
+             }
+         }
+         # REMEMBER: $rec and $TV{$family} point to same data!!
+         $rec->{kids} = [ @kids ];
+     }
+
+     # you copied the list, but the list itself contains pointers
+     # to uncopied objects. this means that if you make bart get
+     # older via
+
+     $TV{simpsons}{kids}[0]{age}++;
+
+     # then this would also change in
+     print $TV{simpsons}{members}[2]{age};
+
+     # because $TV{simpsons}{kids}[0] and $TV{simpsons}{members}[2]
+     # both point to the same underlying anonymous hash table
+
+     # print the whole thing
+     foreach $family ( keys %TV ) {
+         print "the $family";
+         print " is on during @{ $TV{$family}{nights} }\n";
+         print "its members are:\n";
+         for $who ( @{ $TV{$family}{members} } ) {
+             print " $who->{name} ($who->{role}), age $who->{age}\n";
+         }
+         print "it turns out that $TV{$family}{'lead'} has ";
+         print scalar ( @{ $TV{$family}{kids} } ), " kids named ";
+         print join (", ", map { $_->{name} } @{ $TV{$family}{kids} } );
+         print "\n";
+     }
+
 =head1 SEE ALSO
 
-perlref(1), perldata(1)
+L<perlref>, L<perllol>, L<perldata>, L<perlobj>
 
 =head1 AUTHOR
 
 Tom Christiansen E<lt>F<tchrist@perl.com>E<gt>
 
 Last update: 
-Sat Oct  7 22:41:09 MDT 1995
+Tue Dec 12 09:20:26 MST 1995
 
index 5ac5a9e..2f0e9c3 100644 (file)
@@ -1,7 +1,565 @@
 =head1 NAME
 
-perlembed - how to embed perl in your C or C++ app
+perlembed - how to embed perl in your C program
 
 =head1 DESCRIPTION
 
-Look at perlmain.c, and do something like that.
+=head2 PREAMBLE
+
+Do you want to:
+
+=over 5
+
+=item B<Use C from Perl?>  
+
+Read L<perlcall> and L<perlxs>.
+
+=item B<Use a UNIX program from Perl?>  
+
+Read about backquotes and L<perlfunc/system> and L<perlfunc/exec>.
+
+=item B<Use Perl from Perl?>  
+
+Read about L<perlfunc/do> and L<perlfunc/eval> and L<perlmod/use> 
+and L<perlmod/require>.
+
+=item B<Use C from C?>  
+
+Rethink your design.
+
+=item B<Use Perl from C?>  
+
+Read on...
+
+=back
+
+=head2 ROADMAP
+
+L<Compiling your C program>
+
+There's one example in each of the five sections:
+
+L<Adding a Perl interpreter to your C program>
+
+L<Calling a Perl subroutine from your C program>
+
+L<Evaluating a Perl statement from your C program>
+
+L<Performing Perl pattern matches and substitutions from your C program>
+
+L<Fiddling with the Perl stack from your C program>
+
+This documentation is UNIX specific.
+
+=head2 Compiling your C program
+
+Every C program that uses Perl must link in the I<perl library>.  
+
+What's that, you ask?  Perl is itself written in C; the perl library
+is the collection of compiled C programs that were used to create your
+perl executable (I</usr/bin/perl> or equivalent).  (Corollary: you
+can't use Perl from your C program unless Perl has been compiled on
+your machine, or installed properly--that's why you shouldn't blithely
+copy Perl executables from machine to machine without also copying the
+I<lib> directory.)
+
+Your C program will--usually--allocate, "run", and deallocate a
+I<PerlInterpreter> object, which is defined in the perl library.  
+
+If your copy of Perl is recent enough to contain this documentation
+(5.002 or later), then the perl library (and I<EXTERN.h> and
+I<perl.h>, which you'll also need) will
+reside in a directory resembling this:
+
+    /usr/local/lib/perl5/your_architecture_here/CORE
+
+or perhaps just
+
+    /usr/local/lib/perl5/CORE
+
+or maybe something like
+
+    /usr/opt/perl5/CORE
+
+Execute this statement for a hint about where to find CORE:
+
+    perl -e 'use Config; print $Config{archlib}'
+
+Here's how you might compile the example in the next section,
+L<Adding a Perl interpreter to your C program>,
+on a DEC Alpha running the OSF operating system:
+
+    % cc -o interp interp.c -L/usr/local/lib/perl5/alpha-dec_osf/CORE 
+    -I/usr/local/lib/perl5/alpha-dec_osf/CORE -lperl -lm
+
+You'll have to choose the appropriate compiler (I<cc>, I<gcc>, et al.)  and
+library directory (I</usr/local/lib/...>)  for your machine.  If your
+compiler complains that certain functions are undefined, or that it
+can't locate I<-lperl>, then you need to change the path following the
+-L.  If it complains that it can't find I<EXTERN.h> or I<perl.h>, you need
+to change the path following the -I.  
+
+You may have to add extra libraries as well.  Which ones?
+Perhaps those printed by 
+
+   perl -e 'use Config; print $Config{libs}'
+
+=head2 Adding a Perl interpreter to your C program
+
+In a sense, perl (the C program) is a good example of embedding Perl
+(the language), so I'll demonstrate embedding with I<miniperlmain.c>,
+from the source distribution.  Here's a bastardized, non-portable version of
+I<miniperlmain.c> containing the essentials of embedding:
+
+    #include <stdio.h>
+    #include <EXTERN.h>               /* from the Perl distribution     */
+    #include <perl.h>                 /* from the Perl distribution     */
+    
+    static PerlInterpreter *my_perl;  /***    The Perl interpreter    ***/
+   
+    int main(int argc, char **argv, char **env)
+    {
+        my_perl = perl_alloc();
+        perl_construct(my_perl);
+        perl_parse(my_perl, NULL, argc, argv, env);
+        perl_run(my_perl);
+        perl_destruct(my_perl);
+        perl_free(my_perl);
+    }
+
+Now compile this program (I'll call it I<interp.c>) into an executable:
+
+    % cc -o interp interp.c -L/usr/local/lib/perl5/alpha-dec_osf/CORE 
+    -I/usr/local/lib/perl5/alpha-dec_osf/CORE -lperl -lm
+
+After a successful compilation, you'll be able to use I<interp> just
+like perl itself:
+
+    % interp
+    print "Pretty Good Perl \n";
+    print "10890 - 9801 is ", 10890 - 9801;
+    <CTRL-D>
+    Pretty Good Perl
+    10890 - 9801 is 1089
+
+or
+
+    % interp -e 'printf("%x", 3735928559)'
+    deadbeef
+
+You can also read and execute Perl statements from a file while in the
+midst of your C program, by placing the filename in I<argv[1]> before
+calling I<perl_run()>.  
+
+=head2 Calling a Perl subroutine from your C program
+
+To call individual Perl subroutines, you'll need to remove the call to
+I<perl_run()> and replace it with a call to I<perl_call_argv()>.
+
+That's shown below, in a program I'll call I<showtime.c>.
+
+    #include <stdio.h>
+    #include <EXTERN.h>
+    #include <perl.h>                 
+    
+    static PerlInterpreter *my_perl;  
+    
+    int main(int argc, char **argv, char **env)
+    {
+        my_perl = perl_alloc();
+        perl_construct(my_perl);
+    
+        perl_parse(my_perl, NULL, argc, argv, env);
+    
+                                     /*** This replaces perl_run() ***/
+        perl_call_argv("showtime", G_DISCARD | G_NOARGS, argv);
+        perl_destruct(my_perl);
+        perl_free(my_perl);
+    }
+
+where I<showtime> is a Perl subroutine that takes no arguments (that's the
+I<G_NOARGS>) and for which I'll ignore the return value (that's the 
+I<G_DISCARD>).  Those flags, and others, are discussed in L<perlcall>.
+
+I'll define the I<showtime> subroutine in a file called I<showtime.pl>:
+
+    print "I shan't be printed.";
+    
+    sub showtime {
+        print time;
+    }
+
+Simple enough.  Now compile and run:
+
+    % cc -o showtime showtime.c -L/usr/local/lib/perl5/alpha-dec_osf/CORE 
+    -I/usr/local/lib/perl5/alpha-dec_osf/CORE -lperl -lm
+    
+    % showtime showtime.pl
+    818284590
+
+yielding the number of seconds that elapsed between January 1, 1970
+(the beginning of the UNIX epoch), and the moment I began writing this
+sentence.
+
+If you want to pass some arguments to the Perl subroutine, or
+you want to access the return value, you'll need to manipulate the
+Perl stack, demonstrated in the last section of this document: 
+L<Fiddling with the Perl stack from your C program>
+
+=head2 Evaluating a Perl statement from your C program
+
+NOTE: This section, and the next, employ some very brittle techniques
+for evaluting strings of Perl code.  Perl 5.002 contains some nifty
+features that enable A Better Way (such as with L<perlguts/perl_eval_sv>).
+Look for updates to this document soon.
+
+One way to evaluate a Perl string is to define a function (we'll call 
+ours I<perl_eval()>) that wraps around Perl's L<perlfunc/eval>.
+
+Arguably, this is the only routine you'll ever need to execute
+snippets of Perl code from within your C program.  Your string can be
+as long as you wish; it can contain multiple statements; it can
+use L<perlmod/require> or L<perlfunc/do> to include external Perl
+files.  
+
+Our I<perl_eval()> lets us evaluate individual Perl strings, and then 
+extract variables for coercion into C types.  The following program, 
+I<string.c>, executes three Perl strings, extracting an C<int> from
+the first, a C<float> from the second, and a C<char *> from the third.
+
+   #include <stdio.h>
+   #include <EXTERN.h>
+   #include <perl.h>
+   
+   static PerlInterpreter *my_perl;
+   
+   int perl_eval(char *string)
+   {
+     char *argv[2];
+     argv[0] = string;
+     argv[1] = NULL;
+     perl_call_argv("_eval_", 0, argv);
+   }
+   
+   main (int argc, char **argv, char **env)
+   {
+     char *embedding[] = { "", "-e", "sub _eval_ { eval $_[0] }" };
+     STRLEN length;
+   
+     my_perl = perl_alloc();
+     perl_construct( my_perl );
+   
+     perl_parse(my_perl, NULL, 3, embedding, env);
+   
+                                       /** Treat $a as an integer **/
+     perl_eval("$a = 3; $a **= 2");
+     printf("a = %d\n", SvIV(perl_get_sv("a", FALSE)));
+   
+                                       /** Treat $a as a float **/
+     perl_eval("$a = 3.14; $a **= 2");
+     printf("a = %f\n", SvNV(perl_get_sv("a", FALSE)));
+   
+                                       /** Treat $a as a string **/
+     perl_eval("$a = 'rekcaH lreP rehtonA tsuJ'; $a = reverse($a); ");
+     printf("a = %s\n", SvPV(perl_get_sv("a", FALSE), length));
+   
+     perl_destruct(my_perl);
+     perl_free(my_perl);
+   }
+
+All of those strange functions with I<sv> in their names help convert Perl scalars to C types.  They're described in L<perlguts>.
+
+If you compile and run I<string.c>, you'll see the results of using
+I<SvIV()> to create an C<int>, I<SvNV()> to create a C<float>, and
+I<SvPV()> to create a string:
+
+   a = 9
+   a = 9.859600
+   a = Just Another Perl Hacker
+
+
+=head2 Performing Perl pattern matches and substitutions from your C program
+
+Our I<perl_eval()> lets us evaluate strings of Perl code, so we can
+define some functions that use it to "specialize" in matches and
+substitutions: I<match()>, I<substitute()>, and I<matches()>.
+
+   char match(char *string, char *pattern); 
+
+Given a string and a pattern (e.g. "m/clasp/" or "/\b\w*\b/", which in
+your program might be represented as C<"/\\b\\w*\\b/">),
+returns 1 if the string matches the pattern and 0 otherwise.
+
+
+   int substitute(char *string[], char *pattern);
+
+Given a pointer to a string and an "=~" operation (e.g. "s/bob/robert/g" or 
+"tr[A-Z][a-z]"), modifies the string according to the operation,
+returning the number of substitutions made.
+
+   int matches(char *string, char *pattern, char **matches[]);
+
+Given a string, a pattern, and a pointer to an empty array of strings,
+evaluates C<$string =~ $pattern> in an array context, and fills in
+I<matches> with the array elements (allocating memory as it does so), 
+returning the number of matches found.
+
+Here's a sample program, I<match.c>, that uses all three:
+
+   #include <stdio.h>
+   #include <EXTERN.h>
+   #include <perl.h>
+   
+   static PerlInterpreter *my_perl;
+   
+   int eval(char *string)
+   {
+     char *argv[2];
+     argv[0] = string;
+     argv[1] = NULL;
+     perl_call_argv("_eval_", 0, argv);
+   }
+   
+   /** match(string, pattern)
+    ** 
+    ** Used for matches in a scalar context.
+    **
+    ** Returns 1 if the match was successful; 0 otherwise. 
+    **/
+   char match(char *string, char *pattern) 
+   {
+     char *command;
+     command = malloc(sizeof(char) * strlen(string) + strlen(pattern) + 37);
+     sprintf(command, "$string = '%s'; $return = $string =~ %s", 
+       string, pattern); 
+     perl_eval(command);
+     free(command);
+     return SvIV(perl_get_sv("return", FALSE));
+   }
+   
+   /** substitute(string, pattern)
+    **
+    ** Used for =~ operations that modify their left-hand side (s/// and tr///)
+    **
+    ** Returns the number of successful matches, and
+    ** modifies the input string if there were any.
+    **/
+   int substitute(char *string[], char *pattern) 
+   {
+     char *command;
+     STRLEN length;
+     command = malloc(sizeof(char) * strlen(*string) + strlen(pattern) + 35);
+     sprintf(command, "$string = '%s'; $ret = ($string =~ %s)", 
+       *string, pattern); 
+     perl_eval(command);
+     free(command);
+     *string = SvPV(perl_get_sv("string", FALSE), length);
+     return SvIV(perl_get_sv("ret", FALSE));
+   }
+   
+   /** matches(string, pattern, matches)
+    ** 
+    ** Used for matches in an array context.
+    **
+    ** Returns the number of matches, 
+    ** and fills in **matches with the matching substrings (allocates memory!)
+    **/
+   int matches(char *string, char *pattern, char **matches[]) 
+   {
+     char *command;
+     SV *current_match;
+     AV *array;
+     I32 num_matches;
+     STRLEN length;
+     int i;
+   
+     command = malloc(sizeof(char) * strlen(string) + strlen(pattern) + 38);
+     sprintf(command, "$string = '%s'; @array = ($string =~ %s)", 
+       string, pattern); 
+     perl_eval(command);
+     free(command);
+     array = perl_get_av("array", FALSE);
+     num_matches = av_len(array) + 1; /** assume $[ is 0 **/
+     *matches = (char **) malloc(sizeof(char *) * num_matches);
+     for (i = 0; i <= num_matches; i++) {  
+       current_match = av_shift(array);
+       (*matches)[i] = SvPV(current_match, length);
+     }
+     return num_matches;
+   }
+   
+   main (int argc, char **argv, char **env)
+   {
+     char *embedding[] = { "", "-e", "sub _eval_ { eval $_[0] }" };
+     char *text, **matches;
+     int num_matches, i;
+     int j;
+   
+     my_perl = perl_alloc();
+     perl_construct( my_perl );
+   
+     perl_parse(my_perl, NULL, 3, embedding, env);
+   
+     text = (char *) malloc(sizeof(char) * 486); /** A long string follows! **/
+     sprintf(text, "%s", "When he is at a convenience store and the bill comes to some amount like 76 cents, Maynard is aware that there is something he *should* do, something that will enable him to get back a quarter, but he has no idea *what*.  He fumbles through his red squeezey changepurse and gives the boy three extra pennies with his dollar, hoping that he might luck into the correct amount.  The boy gives him back two of his own pennies and then the big shiny quarter that is his prize. -RICHH");  
+   
+     if (perl_match(text, "m/quarter/")) /** Does text contain 'quarter'? **/
+       printf("perl_match: Text contains the word 'quarter'.\n\n");
+     else 
+       printf("perl_match: Text doesn't contain the word 'quarter'.\n\n");
+   
+     if (perl_match(text, "m/eighth/")) /** Does text contain 'eighth'? **/
+       printf("perl_match: Text contains the word 'eighth'.\n\n");
+     else 
+       printf("perl_match: Text doesn't contain the word 'eighth'.\n\n");
+   
+                                      /** Match all occurrences of /wi../ **/
+     num_matches = perl_matches(text, "m/(wi..)/g", &matches);
+     
+     printf("perl_matches: m/(wi..)/g found %d matches...\n", num_matches);
+     for (i = 0; i < num_matches; i++) 
+       printf("match: %s\n", matches[i]);
+     printf("\n");
+     for (i = 0; i < num_matches; i++) {
+       free(matches[i]);
+     }
+     free(matches);
+   
+                                       /** Remove all vowels from text **/
+     num_matches = perl_substitute(&text, "s/[aeiou]//gi");
+     if (num_matches) {
+       printf("perl_substitute: s/[aeiou]//gi...%d substitutions made.\n", 
+       num_matches);
+       printf("Now text is: %s\n\n", text);
+     }
+   
+                                       /** Attempt a substitution
+     if (!perl_substitute(&text, "s/Perl/C/")) {
+       printf("perl_substitute: s/Perl/C...No substitution made.\n\n");
+     }
+   
+     free(text);
+   
+     perl_destruct(my_perl);
+     perl_free(my_perl);
+   }
+
+which produces the output
+
+   perl_match: Text contains the word 'quarter'.
+   
+   perl_match: Text doesn't contain the word 'eighth'.
+   
+   perl_matches: m/(wi..)/g found 2 matches...
+   match: will
+   match: with
+   
+   perl_substitute: s/[aeiou]//gi...139 substitutions made.
+   Now text is: Whn h s t  cnvnnc str nd th bll cms t sm mnt lk 76 cnts, Mynrd s wr tht thr s smthng h *shld* d, smthng tht wll nbl hm t gt bck  qrtr, bt h hs n d *wht*.  H fmbls thrgh hs rd sqzy chngprs nd gvs th by thr xtr pnns wth hs dllr, hpng tht h mght lck nt th crrct mnt.  Th by gvs hm bck tw f hs wn pnns nd thn th bg shny qrtr tht s hs prz. -RCHH
+   
+   perl_substitute: s/Perl/C...No substitution made.
+      
+=head2 Fiddling with the Perl stack from your C program
+
+When trying to explain stacks, most computer science textbooks mumble
+something about spring-loaded columns of cafeteria plates: the last
+thing you pushed on the stack is the first thing you pop off.  That'll
+do for our purposes: your C program will push some arguments onto "the Perl
+stack", shut its eyes while some magic happens, and then pop the
+results--the return value of your Perl subroutine--off the stack.
+   
+First you'll need to know how to convert between C types and Perl
+types, with newSViv() and sv_setnv() and newAV() and all their
+friends.  They're described in L<perlguts>.
+
+Then you'll need to know how to manipulate the Perl stack.  That's
+described in L<perlcall>.
+
+Once you've understood those, embedding Perl in C is easy.  
+
+Since C has no built-in function for integer exponentiation, let's
+make Perl's ** operator available to it (this is less useful than it
+sounds, since Perl implements ** with C's I<pow()> function).  First
+I'll create a stub exponentiation function in I<power.pl>:
+
+    sub expo {
+        my ($a, $b) = @_;
+        return $a ** $b;
+    }
+
+Now I'll create a C program, I<power.c>, with a function
+I<PerlPower()> that contains all the perlguts necessary to push the
+two arguments into I<expo()> and to pop the return value out.  Take a
+deep breath...
+
+    #include <stdio.h>
+    #include <EXTERN.h>
+    #include <perl.h>
+    
+    static PerlInterpreter *my_perl;
+    
+    static void
+    PerlPower(int a, int b)
+    {
+      dSP;                            /* initialize stack pointer      */
+      ENTER;                          /* everything created after here */
+      SAVETMPS;                       /* ...is a temporary variable.   */
+      PUSHMARK(sp);                   /* remember the stack pointer    */
+      XPUSHs(sv_2mortal(newSViv(a))); /* push the base onto the stack  */
+      XPUSHs(sv_2mortal(newSViv(b))); /* push the exponent onto stack  */
+      PUTBACK;                      /* make local stack pointer global */
+      perl_call_pv("expo", G_SCALAR); /* call the function             */
+      SPAGAIN;                        /* refresh stack pointer         */
+                                    /* pop the return value from stack */
+      printf ("%d to the %dth power is %d.\n", a, b, POPi);
+      PUTBACK;                               
+      FREETMPS;                       /* free that return value        */
+      LEAVE;                       /* ...and the XPUSHed "mortal" args.*/
+    }
+    
+    int main (int argc, char **argv, char **env) 
+    {
+      char *my_argv[2];
+    
+      my_perl = perl_alloc();
+      perl_construct( my_perl );
+    
+      my_argv[1] = (char *) malloc(10);
+      sprintf(my_argv[1], "power.pl");
+    
+      perl_parse(my_perl, NULL, argc, my_argv, env);
+      
+      PerlPower(3, 4);                      /*** Compute 3 ** 4 ***/
+    
+      perl_destruct(my_perl);
+      perl_free(my_perl);
+    }
+    
+
+
+Compile and run:
+
+    % cc -o power power.c -L/usr/local/lib/perl5/alpha-dec_osf/CORE 
+    -I/usr/local/lib/perl5/alpha-dec_osf/CORE -lperl -lm
+    
+    % power 
+    3 to the 4th power is 81.
+
+=head1 MORAL
+
+You can sometimes I<write faster code> in C, but
+you can always I<write code faster> in Perl.  Since you can use
+each from the other, combine them as you wish.
+
+
+=head1 AUTHOR
+
+Jon Orwant F<E<lt>orwant@media.mit.eduE<gt>>, with contributions from
+Tim Bunce, Tom Christiansen, Dov Grobgeld, and Ilya Zakharevich.
+
+December 18, 1995
+
+Some of this material is excerpted from my book: I<Perl 5 Interactive>, 
+Waite Group Press, 1996 (ISBN 1-57169-064-6) and appears
+courtesy of Waite Group Press.
+
index c4bb78c..3e5dd78 100644 (file)
@@ -310,5 +310,6 @@ is to printf(), do this:
 
 Lexical variables (declared with "my") are not visible within a
 format unless the format is declared within the scope of the lexical
-variable.  (They weren't visible at all before version 5.001.)  See
+variable.  (They weren't visible at all before version 5.001.)  Furthermore,
+lexical aliases will not be compiled correctly: see
 L<perlfunc/my> for other issues.
index 2cc480c..6104eb5 100644 (file)
@@ -54,9 +54,9 @@ null list.
 
 Remember the following rule:
 
-=over 5
+=over 8
 
-=item *
+=item  
 
 I<THERE IS NO GENERAL RULE FOR CONVERTING A LIST INTO A SCALAR!>
 
@@ -70,6 +70,121 @@ last value in the list.  Some operators return a count of successful
 operations.  In general, they do what you want, unless you want
 consistency.
 
+=head2 Perl Functions by Category
+
+Here are Perl's functions (including things that look like
+functions, like some of the keywords and named operators)
+arranged by category.  Some functions appear in more
+than one place.
+
+=over
+
+=item Functions for SCALARs or strings
+
+chomp, chop, chr, crypt, hex, index, lc, lcfirst, length,
+oct, ord, pack, q/STRING/, qq/STRING/, reverse, rindex,
+sprintf, substr, tr///, uc, ucfirst, y///
+
+=item Regular expressions and pattern matching
+
+m//, pos, quotemeta, s///, split, study
+
+=item Numeric functions
+
+abs, atan2, cos, exp, hex, int, log, oct, rand, sin, sqrt,
+srand
+
+=item Functions for real @ARRAYs
+
+pop, push, shift, splice, unshift
+
+=item Functions for list data
+
+grep, join, map, qw/STRING/, reverse, sort, unpack
+
+=item Functions for real %HASHes
+
+delete, each, exists, keys, values
+
+=item Input and output functions
+
+binmode, close, closedir, dbmclose, dbmopen, die, eof,
+fileno, flock, format, getc, print, printf, read, readdir,
+rewinddir, seek, seekdir, select, syscall, sysread,
+syswrite, tell, telldir, truncate, warn, write
+
+=item Functions for fixed length data or records
+
+pack, read, syscall, sysread, syswrite, unpack, vec
+
+=item Functions for filehandles, files, or directories
+
+-X, chdir, chmod, chown, chroot, fcntl, glob, ioctl, link,
+lstat, mkdir, open, opendir, readlink, rename, rmdir,
+stat, symlink, umask, unlink, utime
+
+=item Keywords related to the control flow of your perl program
+
+caller, continue, die, do, dump, eval, exit, goto, last,
+next, redo, return, sub, wantarray
+
+=item Keywords related to scoping 
+
+caller, import, local, my, package, use
+
+=item Miscellaneous functions
+
+defined, dump, eval, formline, local, my, reset, scalar,
+undef, wantarray
+
+=item Functions for processes and process groups
+
+alarm, exec, fork, getpgrp, getppid, getpriority, kill,
+pipe, qx/STRING/, setpgrp, setpriority, sleep, system,
+times, wait, waitpid
+
+=item Keywords related to perl modules
+
+do, import, no, package, require, use
+
+=item Keywords related to classes and object-orientedness
+
+bless, dbmclose, dbmopen, package, ref, tie, untie, use
+
+=item Low-level socket functions
+
+accept, bind, connect, getpeername, getsockname,
+getsockopt, listen, recv, send, setsockopt, shutdown,
+socket, socketpair
+
+=item System V interprocess communication functions
+
+msgctl, msgget, msgrcv, msgsnd, semctl, semget, semop,
+shmctl, shmget, shmread, shmwrite
+
+=item Fetching user and group info
+
+endgrent, endhostent, endnetent, endpwent, getgrent,
+getgrgid, getgrnam, getlogin, getpwent, getpwnam,
+getpwuid, setgrent, setpwent
+
+=item Fetching network info
+
+endprotoent, endservent, gethostbyaddr, gethostbyname,
+gethostent, getnetbyaddr, getnetbyname, getnetent,
+getprotobyname, getprotobynumber, getprotoent,
+getservbyname, getservbyport, getservent, sethostent,
+setnetent, setprotoent, setservent
+
+=item Time-related functions
+
+gmtime, localtime, time, times
+
+=back
+
+=head2 Alphabetical Listing of Perl Functions
+
+
 =over 8
 
 =item -X FILEHANDLE
@@ -212,13 +327,17 @@ L<perlipc/"Sockets: Client/Server Communication">.
 
 =item binmode FILEHANDLE
 
-Arranges for the file to be read or written in "binary" mode in
-operating systems that distinguish between binary and text files.
-Files that are not in binary mode have CR LF sequences translated to LF
-on input and LF translated to CR LF on output.  Binmode has no effect
-under Unix; in DOS, it may be imperative--otherwise your DOS C library
-may mangle your file.  If FILEHANDLE is an expression,
-the value is taken as the name of the filehandle.
+Arranges for the file to be read or written in "binary" mode in operating
+systems that distinguish between binary and text files.  Files that are
+not in binary mode have CR LF sequences translated to LF on input and LF
+translated to CR LF on output.  Binmode has no effect under Unix; in DOS
+and similarly archaic systems, it may be imperative--otherwise your
+DOS-damaged C library may mangle your file.  The key distinction between
+systems that need binmode and those that don't is their text file
+formats.  Systems like Unix and Plan9 that delimit lines with a single
+character, and that encode that character in C as '\n', do not need
+C<binmode>.  The rest need it.  If FILEHANDLE is an expression, the value
+is taken as the name of the filehandle.
 
 =item bless REF,CLASSNAME
 
@@ -398,6 +517,16 @@ does.  Returns TRUE if it succeeded, FALSE otherwise.  NAME should be a
 packed address of the appropriate type for the socket.  See the examples in
 L<perlipc/"Sockets: Client/Server Communication">.
 
+=item continue BLOCK
+
+Actually a flow control statement rather than a function.  If there is a
+C<continue> BLOCK attached to a BLOCK (typically in a C<while> or
+C<foreach>), it is always executed just before the conditional is about to
+be evaluated again, just like the third part of a C<for> loop in C.  Thus
+it can be used to increment a loop variable, even when the loop has been
+continued via the C<next> statement (which is similar to the C C<continue>
+statement).
+
 =item cos EXPR
 
 Returns the cosine of EXPR (expressed in radians).  If EXPR is omitted
@@ -442,16 +571,16 @@ Breaks the binding between a DBM file and an associative array.
 
 [This function has been superseded by the tie() function.]
 
-This binds a dbm(3), ndbm(3), sdbm(3), gdbm(), or Berkeley DB file to an associative array.  ASSOC is the
-name of the associative array.  (Unlike normal open, the first argument
-is I<NOT> a filehandle, even though it looks like one).  DBNAME is the
-name of the database (without the F<.dir> or F<.pag> extension if any).  If the
-database does not exist, it is created with protection specified by
-MODE (as modified by the umask()).  If your system only supports the
-older DBM functions, you may perform only one dbmopen() in your program.
-In order versions of Perl,
-if your system had neither DBM nor ndbm, calling dbmopen() produced a
-fatal error; it now falls back to sdbm(3).  
+This binds a dbm(3), ndbm(3), sdbm(3), gdbm(), or Berkeley DB file to an
+associative array.  ASSOC is the name of the associative array.  (Unlike
+normal open, the first argument is I<NOT> a filehandle, even though it
+looks like one).  DBNAME is the name of the database (without the F<.dir>
+or F<.pag> extension if any).  If the database does not exist, it is
+created with protection specified by MODE (as modified by the umask()).
+If your system only supports the older DBM functions, you may perform only
+one dbmopen() in your program.  In older versions of Perl, if your system
+had neither DBM nor ndbm, calling dbmopen() produced a fatal error; it now
+falls back to sdbm(3).
 
 If you don't have write access to the DBM file, you can only read
 associative array variables, not set them.  If you want to test whether
@@ -469,11 +598,13 @@ function to iterate over large DBM files.  Example:
     }
     dbmclose(%HIST);
 
-See also L<DB_File> for many other interesting possibilities.
+See also L<AnyDBM_File> for a more general description of the pros and
+cons of the various dbm apparoches, as well as L<DB_File> for a particularly
+rich implementation.
 
 =item defined EXPR
 
-Returns a boolean value saying whether the lvalue EXPR has a real value
+Returns a boolean value saying whether EXPR has a real value
 or not.  Many operations return the undefined value under exceptional
 conditions, such as end of file, uninitialized variable, system error
 and such.  This function allows you to distinguish between an undefined
@@ -730,7 +861,7 @@ reader wonder what else might be happening (nothing is).) Cases 3 and 4
 likewise behave in the same way: they run the code <$x>, which does
 nothing at all.  (Case 4 is preferred for purely visual reasons.) Case 5
 is a place where normally you I<WOULD> like to use double quotes, except
-in that particular situation, you can just use symbolic references
+that in that particular situation, you can just use symbolic references
 instead, as in case 6.
 
 =item exec LIST
@@ -823,7 +954,11 @@ value is taken as the name of the filehandle.
 Calls flock(2) on FILEHANDLE.  See L<flock(2)> for definition of
 OPERATION.  Returns TRUE for success, FALSE on failure.  Will produce a
 fatal error if used on a machine that doesn't implement either flock(2) or
-fcntl(2). (fcntl(2) will be automatically used if flock(2) is missing.)
+fcntl(2). The fcntl(2) system call will be automatically used if flock(2)
+is missing from your system.  This makes flock() the portable file locking
+strategy, although it will only lock entire files, not records.  Note also
+that some versions of flock() cannot lock things over the network; you
+would need to use the more system-specific fcntl() for that.
 
 Here's a mailbox appender for BSD systems.
 
@@ -850,8 +985,7 @@ Here's a mailbox appender for BSD systems.
     print MBOX $msg,"\n\n";
     unlock();
 
-Note that many versions of flock() cannot lock things over the network.  
-You need to do locking with fcntl() for that.
+See also L<DB_File> for other flock() examples.
 
 =item fork
 
@@ -881,6 +1015,26 @@ fork() returns omitted);
     }
     waitpid($pid,0);
 
+See also L<perlipc> for more examples of forking and reaping
+moribund children.
+
+=item format
+
+Declare a picture format with use by the write() function.  For
+example:
+
+    format Something = 
+       Test: @<<<<<<<< @||||| @>>>>>
+             $str,     $%,    '$' . int($num)
+    .
+
+    $str = "widget";
+    $num = $cost/$quantiy;
+    $~ = 'Something';
+    write;
+
+See L<perlform> for many details and examples.
+
 
 =item formline PICTURE, LIST
 
@@ -908,14 +1062,13 @@ formline() always returns TRUE.  See L<perlform> for other examples.
 Returns the next character from the input file attached to FILEHANDLE,
 or a null string at end of file.  If FILEHANDLE is omitted, reads from STDIN.
 This is not particularly efficient.  It cannot be used to get unbuffered
-single-character 
+single-characters, however.  For that, try something more like:
 
     if ($BSD_STYLE) {
        system "stty cbreak </dev/tty >/dev/tty 2>&1";
     }
     else {
-       system "stty", '-icanon',
-       system "stty", 'eol', "\001"; 
+       system "stty", '-icanon', 'eol', "\001"; 
     }
 
     $key = getc(STDIN);
@@ -924,13 +1077,15 @@ single-character
        system "stty -cbreak </dev/tty >/dev/tty 2>&1";
     }
     else {
-       system "stty", 'icanon';
-       system "stty", 'eol', '^@'; # ascii null
+       system "stty", 'icanon', 'eol', '^@'; # ascii null
     }
     print "\n";
 
 Determination of whether to whether $BSD_STYLE should be set 
-is left as an exercise to the reader.
+is left as an exercise to the reader.  
+
+See also the C<Term::ReadKey> module from your nearest CPAN site;
+details on CPAN can be found on L<perlmod/CPAN> 
 
 =item getlogin
 
@@ -1252,7 +1407,7 @@ or how about sorted by key:
     }
 
 To sort an array by value, you'll need to use a C<sort{}>
-function.  Here's a descending numeric sort by value:
+function.  Here's a descending numeric sort of a hash by its values:
 
     foreach $key (sort { $hash{$b} <=> $hash{$a} } keys %hash)) {
        printf "%4d %s\n", $hash{$key}, $key;
@@ -1316,73 +1471,14 @@ it succeeded, FALSE otherwise.  See example in L<perlipc/"Sockets: Client/Server
 
 =item local EXPR
 
-In general, you should be using "my" instead of "local", because it's
-faster and safer.  Format variables often use "local" though, as
-do other variables whose current value must be visible to called
-subroutines.  This is known as dynamic scoping.  Lexical scoping is
-done with "my", which works more like C's auto declarations.
-
 A local modifies the listed variables to be local to the enclosing block,
-subroutine, eval or "do".  If more than one value is listed, the list
-must be placed in parens.  All the listed elements must be legal
-lvalues.  This operator works by saving the current values of those
-variables in LIST on a hidden stack and restoring them upon exiting the
-block, subroutine or eval.  This means that called subroutines can also
-reference the local variable, but not the global one.  The LIST may be
-assigned to if desired, which allows you to initialize your local
-variables.  (If no initializer is given for a particular variable, it
-is created with an undefined value.)  Commonly this is used to name the
-parameters to a subroutine.  Examples:
-
-    sub RANGEVAL {
-       local($min, $max, $thunk) = @_;
-       local $result = '';
-       local $i;
-
-       # Presumably $thunk makes reference to $i
-
-       for ($i = $min; $i < $max; $i++) {
-           $result .= eval $thunk;
-       }
-
-       $result;
-    }
-
-
-    if ($sw eq '-v') {
-       # init local array with global array
-       local @ARGV = @ARGV;
-       unshift(@ARGV,'echo');
-       system @ARGV;
-    }
-    # @ARGV restored
+subroutine, C<eval{}> or C<do>.  If more than one value is listed, the
+list must be placed in parens.  See L<perlsub/"Temporary Values via
+local()"> for details.
 
-
-    # temporarily add to digits associative array
-    if ($base12) {
-       # (NOTE: not claiming this is efficient!)
-       local(%digits) = (%digits,'t',10,'e',11);
-       parse_num();
-    }
-
-Note that local() is a run-time command, and so gets executed every
-time through a loop.  In Perl 4 it used more stack storage each
-time until the loop was exited.  Perl 5 reclaims the space each time
-through, but it's still more efficient to declare your variables
-outside the loop.
-
-A local is simply a modifier on an lvalue expression.
-When you assign to a localized EXPR, the local doesn't change whether
-EXPR is viewed as a scalar or an array.  So
-
-    local($foo) = <STDIN>;
-    local @FOO = <STDIN>;
-
-both supply a list context to the righthand side, while
-
-    local $foo = <STDIN>;
-
-supplies a scalar context.
+But you really probably want to be using my() instead, because local() isn't
+what most people think of as "local").  See L<perlsub/"Private Variables
+via my()"> for details.
 
 =item localtime EXPR
 
@@ -1480,129 +1576,9 @@ an error.
 =item my EXPR
 
 A "my" declares the listed variables to be local (lexically) to the
-enclosing block, subroutine, C<eval>, or C<do/require/use>'d file.  If more than one value is
-listed, the list must be placed in parens.  All the listed elements
-must be legal lvalues.  Only alphanumeric identifiers may be lexically
-scoped--magical builtins like $/ must be localized with "local"
-instead.  You also cannot use my() on a package variable.
-In particular, you're not allowed to say
-
-    my $_;             # Illegal!
-    my $pack::$var;    # Illegal!
-
-Unlike the "local" declaration, variables declared with "my"
-are totally hidden from the outside world, including any called
-subroutines (even if it's the same subroutine--every call gets its own
-copy). 
-
-(An eval(), however, can see the lexical variables of the scope it is
-being evaluated in so long as the names aren't hidden by declarations within
-the eval() itself.  See L<perlref>.)
-
-The EXPR may be assigned to if desired, which allows you to initialize
-your variables.  (If no initializer is given for a particular
-variable, it is created with an undefined value.)  Commonly this is
-used to name the parameters to a subroutine.  Examples:
-
-    sub RANGEVAL {
-       my($min, $max, $thunk) = @_;
-       my $result = '';
-       my $i;
-
-       # Presumably $thunk makes reference to $i
-
-       for ($i = $min; $i < $max; $i++) {
-           $result .= eval $thunk;
-       }
-
-       $result;
-    }
-
-
-    if ($sw eq '-v') {
-       # init my array with global array
-       my @ARGV = @ARGV;
-       unshift(@ARGV,'echo');
-       system @ARGV;
-    }
-    # Outer @ARGV again visible
-
-The "my" is simply a modifier on something you might assign to.
-So when you do assign to the EXPR, the "my" doesn't change whether
-EXPR is viewed as a scalar or an array.  So
-
-    my ($foo) = <STDIN>;
-    my @FOO = <STDIN>;
-
-both supply a list context to the righthand side, while
-
-    my $foo = <STDIN>;
-
-supplies a scalar context.  But the following only declares one variable:
-
-    my $foo, $bar = 1;
-
-That has the same effect as
-
-    my $foo;
-    $bar = 1;
-
-The declared variable is not introduced (is not visible) until after
-the current statement.  Thus,
-
-    my $x = $x;
-
-can be used to initialize the new $x with the value of the old $x, and 
-the expression
-
-    my $x = 123 and $x == 123
-
-is false unless the old $x happened to have the value 123.
-
-Some users may wish to encourage the use of lexically scoped variables.
-As an aid to catching implicit references to package variables,
-if you say
-
-    use strict 'vars';
-
-then any variable reference from there to the end of the enclosing
-block must either refer to a lexical variable, or must be fully
-qualified with the package name.  A compilation error results
-otherwise.  An inner block may countermand this with S<"no strict 'vars'">.
-
-Variables declared with "my" are not part of any package and
-are therefore never fully qualified with the package name.
-However, you may declare a "my" variable 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): 
-
-    my $secret_version = '1.001-beta';
-    my $secret_sub = { print $secret_version };
-    &$secret_sub();
-
-This does not work with object methods, however; 
-all object methods have to be in the symbol table of some
-package to be found.
-
-Just because the "my" variable is lexically scoped doesn't mean that
-within a function it works like a C static.  Here's a mechanism for giving
-a function private variables with both lexical scoping and a static
-lifetime.
-
-    #!/usr/bin/perl -l
-    $var = "global";
-    {   my $count = 0;
-        my $var = "static";
-        sub foo {
-           $count++;
-            print "$var (call # $count)";
-        }
-    }
-    print $var; foo();
-    print $var; foo();
-    print $var; foo();
+enclosing block, subroutine, C<eval>, or C<do/require/use>'d file.  If
+more than one value is listed, the list must be placed in parens.  See
+L<perlsub/"Private Variables via my()"> for details.
 
 =item next LABEL
 
@@ -1645,18 +1621,34 @@ of the real filehandle wanted.  If EXPR is omitted, the scalar variable of
 the same name as the FILEHANDLE contains the filename.  If the filename
 begins with "<" or nothing, the file is opened for input.  If the filename
 begins with ">", the file is opened for output.  If the filename begins
-with ">>", the file is opened for appending.  (You can put a '+' in front
+with ">>", the file is opened for appending.  You can put a '+' in front
 of the '>' or '<' to indicate that you want both read and write access to
-the file.)  If the filename begins with "|", the filename is interpreted
+the file; thus '+<' is usually preferred for read/write updates--the '+>'
+mode would clobber the file first.  These correspond to the fopen(3) modes
+of 'r', 'r+', 'w', 'w+', 'a', and 'a+'.
+
+If the filename begins with "|", the filename is interpreted
 as a command to which output is to be piped, and if the filename ends with
 a "|", the filename is interpreted See L<perlipc/"Using open() for IPC">
 for more examples of this.  as command which pipes input to us.  (You may
-not have a command that pipes both in and out, but see See L<open2>,
+not have a raw open() to a command that pipes both in I<and> out, but see See L<open2>,
 L<open3>, and L<perlipc/"Bidirectional Communication"> for alternatives.)
+
 Opening '-' opens STDIN and opening '>-' opens STDOUT.  Open returns
 non-zero upon success, the undefined value otherwise.  If the open
 involved a pipe, the return value happens to be the pid of the
-subprocess.  Examples:
+subprocess.  
+
+If you're unfortunate enough to be running Perl on a system that
+distinguishes between text files and binary files (modern operating
+systems don't care), then you should check out L</binmode> for tips for
+dealing with this.  The key distinction between systems that need binmode
+and those that don't is their text file formats.  Systems like Unix and
+Plan9 that delimit lines with a single character, and that encode that
+character in C as '\n', do not need C<binmode>.  The rest need it.
+
+
+Examples:
 
     $ARTICLE = 100;
     open ARTICLE or die "Can't find article $ARTICLE: $!\n";
@@ -1664,6 +1656,8 @@ subprocess.  Examples:
 
     open(LOG, '>>/usr/spool/news/twitlog'); # (log is reserved)
 
+    open(DBASE, '+<dbase.mine');           # open for update
+
     open(ARTICLE, "caesar <$article |");    # decrypt article
 
     open(EXTRACT, "|sort >/tmp/Tmp$$");     # $$ is our process id
@@ -1696,6 +1690,8 @@ with ">&", in which case the rest of the string is interpreted as the
 name of a filehandle (or file descriptor, if numeric) which is to be
 duped and opened.  You may use & after >, >>, <, +>, +>> and +<.  The
 mode you specify should match the mode of the original filehandle.
+(Duping a filehandle does not take into acount any existing contents of
+stdio buffers.)
 Here is a script that saves, redirects, and restores STDOUT and
 STDERR:
 
@@ -1760,8 +1756,24 @@ whitespace deleted.  In order to open a file with arbitrary weird
 characters in it, it's necessary to protect any leading and trailing
 whitespace thusly:
 
-        $file =~ s#^(\s)#./$1#;
-        open(FOO, "< $file\0");
+    $file =~ s#^(\s)#./$1#;
+    open(FOO, "< $file\0");
+
+If you want a "real" C open() (see L<open(2)) on your system, then
+you should probably use the POSIX::open() function as found in the L<POSIX> 
+documents.  For example:
+
+    use FileHandle;
+    use POSIX qw(:fcntl_h);
+    $fd = POSIX::open($path, O_RDWR|O_CREAT|O_EXCL, 0700);
+    die "POSIX::open $path: $!" unless defined $fd;
+    $fh = FileHandle->new_from_fd($fd, $amode) || die "fdopen: $!";
+    $fh->autoflush(1);
+    $fh->print("stuff $$\n");
+    seek($fh, 0, SEEK_SET);
+    print "File contains: ", <$fh>;
+
+See L</seek()> for some details about mixing reading and writing.
 
 =item opendir DIRHANDLE,EXPR
 
@@ -1866,6 +1878,25 @@ Examples:
 
 The same template may generally also be used in the unpack function.
 
+=item package NAMESPACE
+
+Declares the compilation unit as being in the given namespace.  The scope
+of the package declaration is from the declaration itself through the end of
+the enclosing block (the same scope as the local() operator).  All further
+unqualified dynamic identifiers will be in this namespace.  A package
+statement only affects dynamic variables--including those you've used
+local() on--but I<not> lexical variables created with my().  Typically it
+would be the first declaration in a file to be included by the C<require>
+or C<use> operator.  You can switch into a package in more than one place;
+it merely influences which symbol table is used by the compiler for the
+rest of that block.  You can 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<main>
+package as assumed.  That is, C<$::sail> is equivalent to C<$main::sail>.
+
+See L<perlmod/"Packages"> for more information about packages, modules,
+and classes.  See L<perlsub> for other scoping issues.
+
 =item pipe READHANDLE,WRITEHANDLE
 
 Opens a pair of connected pipes like the corresponding system call.
@@ -1885,6 +1916,9 @@ Pops and returns the last value of the array, shortening the array by
     $tmp = $ARRAY[$#ARRAY--];
 
 If there are no elements in the array, returns the undefined value.
+If ARRAY is omitted, pops the
+@ARGV array in the main program, and the @_ array in subroutines, just
+like shift().
 
 =item pos SCALAR
 
@@ -1897,9 +1931,9 @@ in question.  May be modified to change that offset.
 
 =item print
 
-Prints a string or a comma-separated list of strings.  Returns non-zero
+Prints a string or a comma-separated list of strings.  Returns TRUE
 if successful.  FILEHANDLE may be a scalar variable name, in which case
-the variable contains the name of the filehandle, thus introducing one
+the variable contains the name of or a reference to the filehandle, thus introducing one
 level of indirection.  (NOTE: If FILEHANDLE is a variable and the next
 token is a term, it may be misinterpreted as an operator unless you
 interpose a + or put parens around the arguments.)  If FILEHANDLE is
@@ -1990,6 +2024,14 @@ If used in a list context, returns all the rest of the entries in the
 directory.  If there are no more entries, returns an undefined value in
 a scalar context or a null list in a list context.
 
+If you're planning to filetest the return values out of a readdir(), you'd
+better prepend the directory in question.  Otherwise, since we didn't
+chdir() there, it would have been testing the wrong file.
+
+    opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!";
+    @dots = grep { /^\./ && -f "$some_dir/$_" } readdir(DIR);
+    closedir DIR;
+
 =item readlink EXPR
 
 Returns the value of a symbolic link, if symbolic links are
@@ -2177,7 +2219,15 @@ The substitution operator.  See L<perlop>.
 =item scalar EXPR
 
 Forces EXPR to be interpreted in a scalar context and returns the value
-of EXPR.
+of EXPR.  
+
+    @counts = ( scalar @a, scalar @b, scalar @c );
+
+There is no equivalent operator to force an expression to 
+be interpolated in a list context because it's in practice never
+needed.  If you really wanted to do so, however, you could use
+the construction C<@{[ (some expression) ]}>, but usually a simple
+C<(some expression)> suffices.
 
 =item seek FILEHANDLE,POSITION,WHENCE
 
@@ -2188,6 +2238,31 @@ POSITION, 1 to set the it to current plus POSITION, and 2 to set it to EOF
 plus offset.  You may use the values SEEK_SET, SEEK_CUR, and SEEK_END for
 this from POSIX module.  Returns 1 upon success, 0 otherwise.
 
+On some systems you have to do a seek whenever you switch between reading
+and writing.  Amongst other things, this may have the effect of calling
+stdio's clearerr(3).  A "whence" of 1 (SEEK_CUR) is useful for not moving
+the file pointer:
+
+    seek(TEST,0,1);
+
+This is also useful for applications emulating C<tail -f>.  Once you hit
+EOF on your read, and then sleep for a while, you might have to stick in a
+seek() to reset things.  First the simple trick listed above to clear the
+filepointer.  The seek() doesn't change the current position, but it
+I<does> clear the end-of-file condition on the handle, so that the next
+C<E<lt>FILE<E<gt>> makes Perl try again to read something.  Hopefully.
+
+If that doesn't work (some stdios are particularly cantankerous), then
+you may need something more like this:
+
+    for (;;) {
+       for ($curpos = tell(FILE); $_ = <FILE>; $curpos = tell(FILE)) {
+           # search for some stuff and put it into files
+       }
+       sleep($for_a_while);
+       seek(FILE, $curpos, 0);
+    }
+
 =item seekdir DIRHANDLE,POS
 
 Sets the current position for the readdir() routine on DIRHANDLE.  POS
@@ -2264,6 +2339,8 @@ You can effect a 250-microsecond sleep this way:
 
     select(undef, undef, undef, 0.25);
 
+B<WARNING>: Do not attempt to mix buffered I/O (like read() or <FH>)
+with select().  You have to use sysread() instead.
 
 =item semctl ID,SEMNUM,CMD,ARG
 
@@ -2380,6 +2457,10 @@ On some older systems, it may sleep up to a full second less than what
 you requested, depending on how it counts seconds.  Most modern systems
 always sleep the full amount.
 
+For delays of finer granularity than one second, you may use Perl's
+syscall() interface to access setitimer(2) if your system supports it, 
+or else see L</select()> below.  
+
 =item socket SOCKET,DOMAIN,TYPE,PROTOCOL
 
 Opens a socket of the specified kind and attaches it to filehandle
@@ -2411,11 +2492,12 @@ value provides the name of the subroutine to use.  In place of a
 SUBNAME, you can provide a BLOCK as an anonymous, in-line sort
 subroutine.
 
-In the interests of efficiency the normal calling code for subroutines
-is bypassed, with the following effects: the subroutine may not be a
-recursive subroutine, and the two elements to be compared are passed
-into the subroutine not via @_ but as $a and $b (see example below).
-They are passed by reference, so don't modify $a and $b.
+In the interests of efficiency the normal calling code for subroutines is
+bypassed, with the following effects: the subroutine may not be a
+recursive subroutine, and the two elements to be compared are passed into
+the subroutine not via @_ but as the package global variables $a and
+$b (see example below).  They are passed by reference, so don't
+modify $a and $b.  And don't try to declare them as lexicals either.
 
 Examples:
 
@@ -2425,6 +2507,9 @@ Examples:
     # same thing, but with explicit sort routine
     @articles = sort {$a cmp $b} @files;
 
+    # now case-insensitively
+    @articles = sort { uc($a) cmp uc($b)} @files;
+
     # same thing in reversed order
     @articles = sort {$b cmp $a} @files;
 
@@ -2450,6 +2535,53 @@ Examples:
     print sort @george, 'to', @harry;
            # prints AbelAxedCainPunishedcatchaseddoggonetoxyz
 
+    # inefficiently sort by descending numeric compare using 
+    # the first integer after the first = sign, or the 
+    # whole record case-insensitively otherwise
+
+    @new = sort {
+       ($b =~ /=(\d+)/)[0] <=> ($a =~ /=(\d+)/)[0]
+                           ||
+                   uc($a)  cmp  uc($b)
+    } @old;
+
+    # same thing, but much more efficiently;
+    # we'll build auxiliary indices instead
+    # for speed
+    @nums = @caps = ();
+    for (@old) { 
+       push @nums, /=(\d+)/;
+       push @caps, uc($_);
+    } 
+
+    @new = @old[ sort {
+                       $nums[$b] <=> $nums[$a]
+                                ||
+                       $caps[$a] cmp $caps[$b]
+                      } 0..$#old
+              ];
+
+    # same thing using a Schwartzian Transform (no temps)
+    @new = map { $_->[0] }
+        sort { $b->[1] <=> $a->[1]
+                        ||
+               $a->[2] cmp $b->[2]
+        } map { [$_, /=(\d+)/, uc($_)] } @old;
+
+If you're and using strict, you I<MUST NOT> declare $a
+and $b as lexicals.  They are package globals.  That means
+if you're in the C<main> package, it's
+
+    @articles = sort {$main::b <=> $main::a} @files;
+
+or just
+
+    @articles = sort {$::b <=> $::a} @files;
+
+but if you're in the C<FooPack> package, it's
+
+    @articles = sort {$FooPack::b <=> $FooPack::a} @files;
+
 =item splice ARRAY,OFFSET,LENGTH,LIST
 
 =item splice ARRAY,OFFSET,LENGTH
@@ -2567,10 +2699,11 @@ L</chomp>, and L</join>.)
 =item sprintf FORMAT,LIST
 
 Returns a string formatted by the usual printf conventions of the C
-language.  (The * character for an indirectly specified length is not
+language.  See L<sprintf(3)> or L<printf(3)> on your system for details.
+(The * character for an indirectly specified length is not
 supported, but you can get the same effect by interpolating a variable
-into the pattern.)  Some C libraries' implementations of sprintf() can dump core
-when fed ludiocrous arguments.
+into the pattern.)  Some C libraries' implementations of sprintf() can
+dump core when fed ludicrous arguments.
 
 =item sqrt EXPR
 
@@ -2579,12 +2712,13 @@ root of $_.
 
 =item srand EXPR
 
-Sets the random number seed for the C<rand> operator.  If EXPR is
-omitted, does C<srand(time)>.  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 comp.security.unix.
+Sets the random number seed for the C<rand> operator.  If EXPR is omitted,
+does C<srand(time)>.  Many folks use an explicit C<srand(time ^ $$)>
+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
+the comp.security.unix newsgroup.
 
 =item stat FILEHANDLE
 
@@ -2667,6 +2801,18 @@ out the names of those files that contain a match:
        print $file, "\n";
     }
 
+=item sub BLOCK
+
+=item sub NAME
+
+=item sub NAME BLOCK
+
+This is subroutine definition, not a real function I<per se>.  With just a
+NAME (and possibly prototypes), it's just a forward declaration.  Without
+a NAME, it's an anonymous function declaration, and does actually return a
+value: the CODE ref of the closure you just created. See L<perlsub> and
+L<perlref> for details.
+
 =item substr EXPR,OFFSET,LEN
 
 =item substr EXPR,OFFSET
@@ -2731,7 +2877,9 @@ first, and the parent process waits for the child process to complete.
 Note that argument processing varies depending on the number of
 arguments.  The return value is the exit status of the program as
 returned by the wait() call.  To get the actual exit value divide by
-256.  See also L</exec>.
+256.  See also L</exec>.  This is I<NOT> what you want to use to capture 
+the output from a command, for that you should merely use backticks, as
+described in L<perlop/"`STRING`">.
 
 =item syswrite FILEHANDLE,SCALAR,LENGTH,OFFSET
 
@@ -2767,8 +2915,8 @@ to be enchanted.  CLASSNAME is the name of a class implementing objects
 of correct type.  Any additional arguments are passed to the "new"
 method of the class (meaning TIESCALAR, TIEARRAY, or TIEHASH).
 Typically these are arguments such as might be passed to the dbm_open()
-function of C.  The object returned by the "new" method +is also
-returned by the tie() function, which would be useful if you +want to
+function of C.  The object returned by the "new" method is also
+returned by the tie() function, which would be useful if you want to
 access other methods in CLASSNAME.
 
 Note that functions such as keys() and values() may return huge array
@@ -2947,8 +3095,6 @@ package.  It is exactly equivalent to
 
     BEGIN { require Module; import Module LIST; }
 
-If you don't want your namespace altered, use require instead.
-
 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
@@ -2956,7 +3102,15 @@ call into the "Module" package to tell the module to import the list of
 features back into the current package.  The module can implement its
 import method any way it likes, though most modules just choose to
 derive their import method via inheritance from the Exporter class that
-is defined in the Exporter module.
+is defined in the Exporter module. See L<Exporter>.
+
+If you don't want your namespace altered, explicitly supply an empty list:
+
+    use Module ();
+
+That is exactly equivalent to
+
+    BEGIN { require Module; }
 
 Because this is a wide-open interface, pragmas (compiler directives)
 are also implemented this way.  Currently implemented pragmas are:
index b836a73..5e8f077 100644 (file)
@@ -39,7 +39,7 @@ The four routines are:
     SV*  newSVpv(char*, int);
     SV*  newSVsv(SV*);
 
-To change the value of an *already-existing* scalar, there are five routines:
+To change the value of an *already-existing* SV, there are five routines:
 
     void  sv_setiv(SV*, IV);
     void  sv_setnv(SV*, double);
@@ -49,7 +49,7 @@ To change the value of an *already-existing* scalar, there are five routines:
 
 Notice that you can choose to specify the length of the string to be
 assigned by using C<sv_setpvn> or C<newSVpv>, or you may allow Perl to
-calculate the length by using C<sv_setpv> or specifying 0 as the second
+calculate the length by using C<sv_setpv> or by specifying 0 as the second
 argument to C<newSVpv>.  Be warned, though, that Perl will determine the
 string's length by using C<strlen>, which depends on the string terminating
 with a NUL character.
@@ -95,7 +95,12 @@ the following macros:
     SvCUR(SV*)
     SvCUR_set(SV*, I32 val)
 
-But note that these are valid only if C<SvPOK()> is true.
+You can also get a pointer to the end of the string stored in the SV
+with the macro:
+
+    SvEND(SV*)
+
+But note that these last three macros are valid only if C<SvPOK()> is true.
 
 If you want to append something to the end of string stored in an C<SV*>,
 you can use the following functions:
@@ -203,12 +208,14 @@ Here are some other functions:
     SV**  av_store(AV*, I32 key, SV* val);
             /* Stores val at offset key */
 
-Take note that these two functions return C<SV**>'s, not C<SV*>'s.
+Take note that C<av_fetch> and C<av_store> return C<SV**>'s, not C<SV*>'s.
 
     void  av_clear(AV*);
             /* Clear out all elements, but leave the array */
     void  av_undef(AV*);
             /* Undefines the array, removing all elements */
+    void  av_extend(AV*, I32 key);
+            /* Extend the array to a total of key elements */
 
 If you know the name of an array variable, you can get a pointer to its AV
 by using the following:
@@ -265,10 +272,10 @@ specified below.
     char*  hv_iterkey(HE* entry, I32* retlen);
             /* Get the key from an HE structure and also return
                the length of the key string */
-    SV*     hv_iterval(HV*, HE* entry);
+    SV*    hv_iterval(HV*, HE* entry);
             /* Return a SV pointer to the value of the HE
                structure */
-    SV*     hv_iternextsv(HV*, char** key, I32* retlen);
+    SV*    hv_iternextsv(HV*, char** key, I32* retlen);
             /* This convenience routine combines hv_iternext,
               hv_iterkey, and hv_iterval.  The key and retlen
               arguments are return values for the key and its
@@ -289,31 +296,6 @@ The hash algorithm, for those who are interested, is:
     while (i--)
        hash = hash * 33 + *s++;
 
-=head1 Creating New Variables
-
-To create a new Perl variable, which can be accessed from your Perl script,
-use the following routines, depending on the variable type.
-
-    SV*  perl_get_sv("varname", TRUE);
-    AV*  perl_get_av("varname", TRUE);
-    HV*  perl_get_hv("varname", TRUE);
-
-Notice the use of TRUE as the second parameter.  The new variable can now
-be set, using the routines appropriate to the data type.
-
-There are additional bits that may be OR'ed with the TRUE argument to enable
-certain extra features.  Those bits are:
-
-    0x02  Marks the variable as multiply defined, thus preventing the
-         "Indentifier <varname> used only once: possible typo" warning.
-    0x04  Issues a "Had to create <varname> unexpectedly" warning if
-         the variable didn't actually exist.  This is useful if
-         you expected the variable to already exist and want to propagate
-         this warning back to the user.
-       
-If the C<varname> argument does not contain a package specifier, it is
-created in the current package.
-
 =head2 References
 
 References are a special type of scalar that point to other data types
@@ -321,7 +303,7 @@ References are a special type of scalar that point to other data types
 
 To create a reference, use the following command:
 
-    SV*  newRV((SV*) thing);
+    SV* newRV((SV*) thing);
 
 The C<thing> argument can be any of an C<SV*>, C<AV*>, or C<HV*>.  Once
 you have a reference, you can use the following macro to dereference the
@@ -351,6 +333,75 @@ The most useful types that will be returned are:
     SVt_PVCV  Code
     SVt_PVMG  Blessed Scalar
 
+=head2 Blessed References and Class Objects
+
+References are also used to support object-oriented programming.  In the
+OO lexicon, an object is simply a reference that has been blessed into a
+package (or class).  Once blessed, the programmer may now use the reference
+to access the various methods in the class.
+
+A reference can be blessed into a package with the following function:
+
+    SV* sv_bless(SV* sv, HV* stash);
+
+The C<sv> argument must be a reference.  The C<stash> argument specifies
+which class the reference will belong to.  See the section on L<Stashes>
+for information on converting class names into stashes.
+
+/* Still under construction */
+
+Upgrades rv to reference if not already one.  Creates new SV for rv to
+point to.
+If classname is non-null, the SV is blessed into the specified class.
+SV is returned.
+
+       SV* newSVrv(SV* rv, char* classname);
+
+Copies integer or double into an SV whose reference is rv.  SV is blessed
+if classname is non-null.
+
+       SV* sv_setref_iv(SV* rv, char* classname, IV iv);
+       SV* sv_setref_nv(SV* rv, char* classname, NV iv);
+
+Copies pointer (I<not a string!>) into an SV whose reference is rv.
+SV is blessed if classname is non-null.
+
+       SV* sv_setref_pv(SV* rv, char* classname, PV iv);
+
+Copies string into an SV whose reference is rv.
+Set length to 0 to let Perl calculate the string length.
+SV is blessed if classname is non-null.
+
+       SV* sv_setref_pvn(SV* rv, char* classname, PV iv, int length);
+
+       int sv_isa(SV* sv, char* name);
+       int sv_isobject(SV* sv);
+
+=head1 Creating New Variables
+
+To create a new Perl variable, which can be accessed from your Perl script,
+use the following routines, depending on the variable type.
+
+    SV*  perl_get_sv("varname", TRUE);
+    AV*  perl_get_av("varname", TRUE);
+    HV*  perl_get_hv("varname", TRUE);
+
+Notice the use of TRUE as the second parameter.  The new variable can now
+be set, using the routines appropriate to the data type.
+
+There are additional bits that may be OR'ed with the TRUE argument to enable
+certain extra features.  Those bits are:
+
+    0x02  Marks the variable as multiply defined, thus preventing the
+         "Indentifier <varname> used only once: possible typo" warning.
+    0x04  Issues a "Had to create <varname> unexpectedly" warning if
+         the variable didn't actually exist.  This is useful if
+         you expected the variable to already exist and want to propagate
+         this warning back to the user.
+
+If the C<varname> argument does not contain a package specifier, it is
+created in the current package.
+
 =head1 XSUB's and the Argument Stack
 
 The XSUB mechanism is a simple way for Perl programs to access C subroutines.
@@ -408,6 +459,9 @@ explicitly done so (via the Perl C<undef> call or other routines in Perl
 itself).
 
 Add cruft about reference counts.
+       int SvREFCNT(SV* sv);
+       void SvREFCNT_inc(SV* sv);
+       void SvREFCNT_dec(SV* sv);
 
 In the above example with C<tzname>, we needed to create two new SV's to push
 onto the argument stack, that being the two strings.  However, we don't want
@@ -433,7 +487,7 @@ The mortal routines are not just for SV's -- AV's and HV's can be made mortal
 by passing their address (and casting them to C<SV*>) to the C<sv_2mortal> or
 C<sv_mortalcopy> routines.
 
-From Ilya:
+>From Ilya:
 Beware that the sv_2mortal() call is eventually equivalent to
 svREFCNT_dec(). A value can happily be mortal in two different contexts,
 and it will be svREFCNT_dec()ed twice, once on exit from these
@@ -446,7 +500,7 @@ You should be careful about creating mortal variables.  It is possible for
 strange things to happen should you make the same value mortal within
 multiple contexts.
 
-=head1 Stashes and Objects
+=head1 Stashes
 
 A stash is a hash table (associative array) that contains all of the
 different objects that are contained within a package.  Each key of the
@@ -454,7 +508,7 @@ stash is a symbol name (shared by all the different types of objects
 that have the same name), and each value in the hash table is called a
 GV (for Glob Value).  This GV in turn contains references to the various
 objects of that name, including (but not limited to) the following:
-    
+
     Scalar Value
     Array Value
     Hash Value
@@ -476,7 +530,7 @@ To get the stash pointer for a particular package, use the function:
 
 The first function takes a literal string, the second uses the string stored
 in the SV.  Remember that a stash is just a hash table, so you get back an
-C<HV*>.
+C<HV*>.  The C<create> flag will create a new package if it is set.
 
 The name that C<gv_stash*v> wants is the name of the package whose symbol table
 you want.  The default package is called C<main>.  If you have multiply nested
@@ -550,7 +604,8 @@ copy of the name is stored in C<mg_ptr> field.
 
 The sv_magic function uses C<how> to determine which, if any, predefined
 "Magic Virtual Table" should be assigned to the C<mg_virtual> field.
-See the "Magic Virtual Table" section below.
+See the "Magic Virtual Table" section below.  The C<how> argument is also
+stored in the C<mg_type> field.
 
 The C<obj> argument is stored in the C<mg_obj> field of the C<MAGIC>
 structure.  If it is not the same as the C<sv> argument, the reference
@@ -558,6 +613,19 @@ count of the C<obj> object is incremented.  If it is the same, or if
 the C<how> argument is "#", or if it is a null pointer, then C<obj> is
 merely stored, without the reference count being incremented.
 
+There is also a function to add magic to an C<HV>:
+
+    void hv_magic(HV *hv, GV *gv, int how);
+
+This simply calls C<sv_magic> and coerces the C<gv> argument into an C<SV>.
+
+To remove the magic from an SV, call the function sv_unmagic:
+
+    void sv_unmagic(SV *sv, int type);
+
+The C<type> argument should be equal to the C<how> value when the C<SV>
+was initially made magical.
+
 =head2 Magic Virtual Tables
 
 The C<mg_virtual> field in the C<MAGIC> structure is a pointer to a
@@ -717,6 +785,7 @@ functions:
     FREETMPS
     LEAVE
     XPUSH*()
+    POP*()
 
 For more information, consult L<perlcall>.
 
@@ -766,14 +835,1357 @@ destination starting points.  Perl will move, copy, or zero out C<number>
 instances of the size of the C<type> data structure (using the C<sizeof>
 function).
 
-=head1 AUTHOR
+=head1 API LISTING
 
-Jeff Okamoto <okamoto@corp.hp.com>
+This is a listing of functions, macros, flags, and variables that may be
+useful to extension writers or that may be found while reading other
+extensions.
 
-With lots of help and suggestions from Dean Roehrich, Malcolm Beattie,
-Andreas Koenig, Paul Hudson, Ilya Zakharevich, Paul Marquess, Neil
-Bowers, Matthew Green, Tim Bunce, and Spider Boardman.
+=over 8
 
-=head1 DATE
+=item AvFILL
+
+See C<av_len>.
+
+=item av_clear
+
+Clears an array, making it empty.
+
+       void    av_clear _((AV* ar));
+
+=item av_extend
+
+Pre-extend an array.  The C<key> is the index to which the array should be
+extended.
+
+       void    av_extend _((AV* ar, I32 key));
+
+=item av_fetch
+
+Returns the SV at the specified index in the array.  The C<key> is the
+index.  If C<lval> is set then the fetch will be part of a store.  Check
+that the return value is non-null before dereferencing it to a C<SV*>.
+
+       SV**    av_fetch _((AV* ar, I32 key, I32 lval));
+
+=item av_len
+
+Returns the highest index in the array.  Returns -1 if the array is empty.
+
+       I32     av_len _((AV* ar));
+
+=item av_make
+
+Creats a new AV and populates it with a list of SVs.  The SVs are copied
+into the array, so they may be freed after the call to av_make.
+
+       AV*     av_make _((I32 size, SV** svp));
+
+=item av_pop
+
+Pops an SV off the end of the array.  Returns C<&sv_undef> if the array is
+empty.
+
+       SV*     av_pop _((AV* ar));
+
+=item av_push
+
+Pushes an SV onto the end of the array.
+
+       void    av_push _((AV* ar, SV* val));
+
+=item av_shift
+
+Shifts an SV off the beginning of the array.
+
+       SV*     av_shift _((AV* ar));
+
+=item av_store
+
+Stores an SV in an array.  The array index is specified as C<key>.  The
+return value will be null if the operation failed, otherwise it can be
+dereferenced to get the original C<SV*>.
+
+       SV**    av_store _((AV* ar, I32 key, SV* val));
+
+=item av_undef
+
+Undefines the array.
+
+       void    av_undef _((AV* ar));
+
+=item av_unshift
+
+Unshift an SV onto the beginning of the array.
+
+       void    av_unshift _((AV* ar, I32 num));
+
+=item CLASS
+
+Variable which is setup by C<xsubpp> to indicate the class name for a C++ XS
+constructor.  This is always a C<char*>.  See C<THIS> and L<perlxs>.
+
+=item Copy
+
+The XSUB-writer's interface to the C C<memcpy> function.  The C<s> is the
+source, C<d> is the destination, C<n> is the number of items, and C<t> is
+the type.
+
+       (void) Copy( s, d, n, t );
+
+=item croak
+
+This is the XSUB-writer's interface to Perl's C<die> function.  Use this
+function the same way you use the C C<printf> function.  See C<warn>.
+
+=item CvSTASH
+
+Returns the stash of the CV.
+
+       HV * CvSTASH( SV* sv )
+
+=item DBsingle
+
+When Perl is run in debugging mode, with the B<-d> switch, this SV is a
+boolean which indicates whether subs are being single-stepped.
+Single-stepping is automatically turned on after every step.  See C<DBsub>.
+
+=item DBsub
+
+When Perl is run in debugging mode, with the B<-d> switch, this GV contains
+the SV which holds the name of the sub being debugged.  See C<DBsingle>.
+The sub name can be found by
+
+       SvPV( GvSV( DBsub ), na )
+
+=item dMARK
+
+Declare a stack marker for the XSUB.  See C<MARK> and C<dORIGMARK>.
+
+=item dORIGMARK
+
+Saves the original stack mark for the XSUB.  See C<ORIGMARK>.
+
+=item dSP
+
+Declares a stack pointer for the XSUB.  See C<SP>.
+
+=item dXSARGS
+
+Sets up stack and mark pointers for an XSUB, calling dSP and dMARK.  This is
+usually handled automatically by C<xsubpp>.  Declares the C<items> variable
+to indicate the number of items on the stack.
+
+=item ENTER
+
+Opening bracket on a callback.  See C<LEAVE> and L<perlcall>.
+
+       ENTER;
+
+=item EXTEND
+
+Used to extend the argument stack for an XSUB's return values.
+
+       EXTEND( sp, int x );
+
+=item FREETMPS
+
+Closing bracket for temporaries on a callback.  See C<SAVETMPS> and
+L<perlcall>.
+
+       FREETMPS;
+
+=item G_ARRAY
+
+Used to indicate array context.  See C<GIMME> and L<perlcall>.
+
+=item G_DISCARD
+
+Indicates that arguments returned from a callback should be discarded.  See
+L<perlcall>.
+
+=item G_EVAL
+
+Used to force a Perl C<eval> wrapper around a callback.  See L<perlcall>.
+
+=item GIMME
+
+The XSUB-writer's equivalent to Perl's C<wantarray>.  Returns C<G_SCALAR> or
+C<G_ARRAY> for scalar or array context.
+
+=item G_NOARGS
+
+Indicates that no arguments are being sent to a callback.  See L<perlcall>.
+
+=item G_SCALAR
+
+Used to indicate scalar context.  See C<GIMME> and L<perlcall>.
+
+=item gv_stashpv
+
+Returns a pointer to the stash for a specified package.  If C<create> is set
+then the package will be created if it does not already exist.  If C<create>
+is not set and the package does not exist then NULL is returned.
+
+       HV*     gv_stashpv _((char* name, I32 create));
+
+=item gv_stashsv
+
+Returns a pointer to the stash for a specified package.  See C<gv_stashpv>.
+
+       HV*     gv_stashsv _((SV* sv, I32 create));
+
+=item GvSV
+
+Return the SV from the GV.
+
+=item he_free
+
+Releases a hash entry from an iterator.  See C<hv_iternext>.
+
+=item hv_clear
+
+Clears a hash, making it empty.
+
+       void    hv_clear _((HV* tb));
+
+=item hv_delete
+
+Deletes a key/value pair in the hash.  The value SV is removed from the hash
+and returned to the caller.  The C<lken> is the length of the key.  The
+C<flags> value will normally be zero; if set to G_DISCARD then null will be
+returned.
+
+       SV*     hv_delete _((HV* tb, char* key, U32 klen, I32 flags));
+
+=item hv_exists
+
+Returns a boolean indicating whether the specified hash key exists.  The
+C<lken> is the length of the key.
+
+       bool    hv_exists _((HV* tb, char* key, U32 klen));
+
+=item hv_fetch
+
+Returns the SV which corresponds to the specified key in the hash.  The
+C<lken> is the length of the key.  If C<lval> is set then the fetch will be
+part of a store.  Check that the return value is non-null before
+dereferencing it to a C<SV*>.
+
+       SV**    hv_fetch _((HV* tb, char* key, U32 klen, I32 lval));
+
+=item hv_iterinit
+
+Prepares a starting point to traverse a hash table.
+
+       I32     hv_iterinit _((HV* tb));
+
+=item hv_iterkey
+
+Returns the key from the current position of the hash iterator.  See
+C<hv_iterinit>.
+
+       char*   hv_iterkey _((HE* entry, I32* retlen));
+
+=item hv_iternext
+
+Returns entries from a hash iterator.  See C<hv_iterinit>.
+
+       HE*     hv_iternext _((HV* tb));
+
+=item hv_iternextsv
+
+Performs an C<hv_iternext>, C<hv_iterkey>, and C<hv_iterval> in one
+operation.
+
+       SV *    hv_iternextsv _((HV* hv, char** key, I32* retlen));
+
+=item hv_iterval
+
+Returns the value from the current position of the hash iterator.  See
+C<hv_iterkey>.
+
+       SV*     hv_iterval _((HV* tb, HE* entry));
+
+=item hv_magic
+
+Adds magic to a hash.  See C<sv_magic>.
+
+       void    hv_magic _((HV* hv, GV* gv, int how));
+
+=item HvNAME
+
+Returns the package name of a stash.  See C<SvSTASH>, C<CvSTASH>.
+
+       char *HvNAME (HV* stash)
+
+=item hv_store
+
+Stores an SV in a hash.  The hash key is specified as C<key> and C<klen> is
+the length of the key.  The C<hash> parameter is the pre-computed hash
+value; if it is zero then Perl will compute it.  The return value will be
+null if the operation failed, otherwise it can be dereferenced to get the
+original C<SV*>.
+
+       SV**    hv_store _((HV* tb, char* key, U32 klen, SV* val, U32 hash));
+
+=item hv_undef
+
+Undefines the hash.
+
+       void    hv_undef _((HV* tb));
+
+=item isALNUM
+
+Returns a boolean indicating whether the C C<char> is an ascii alphanumeric
+character or digit.
+
+       int isALNUM (char c)
+
+=item isALPHA
+
+Returns a boolean indicating whether the C C<char> is an ascii alphanumeric
+character.
+
+       int isALPHA (char c)
+
+=item isDIGIT
+
+Returns a boolean indicating whether the C C<char> is an ascii digit.
+
+       int isDIGIT (char c)
+
+=item isLOWER
+
+Returns a boolean indicating whether the C C<char> is a lowercase character.
+
+       int isLOWER (char c)
+
+=item isSPACE
+
+Returns a boolean indicating whether the C C<char> is whitespace.
+
+       int isSPACE (char c)
+
+=item isUPPER
+
+Returns a boolean indicating whether the C C<char> is an uppercase character.
+
+       int isUPPER (char c)
+
+=item items
+
+Variable which is setup by C<xsubpp> to indicate the number of items on the
+stack.  See L<perlxs>.
+
+=item LEAVE
+
+Closing bracket on a callback.  See C<ENTER> and L<perlcall>.
+
+       LEAVE;
+
+=item MARK
+
+Stack marker for the XSUB.  See C<dMARK>.
+
+=item mg_clear
+
+Clear something magical that the SV represents.  See C<sv_magic>.
+
+       int     mg_clear _((SV* sv));
+
+=item mg_copy
+
+Copies the magic from one SV to another.  See C<sv_magic>.
+
+       int     mg_copy _((SV *, SV *, char *, STRLEN));
+
+=item mg_find
+
+Finds the magic pointer for type matching the SV.  See C<sv_magic>.
+
+       MAGIC*  mg_find _((SV* sv, int type));
+
+=item mg_free
+
+Free any magic storage used by the SV.  See C<sv_magic>.
+
+       int     mg_free _((SV* sv));
+
+=item mg_get
+
+Do magic after a value is retrieved from the SV.  See C<sv_magic>.
+
+       int     mg_get _((SV* sv));
+
+=item mg_len
+
+Report on the SV's length.  See C<sv_magic>.
+
+       U32     mg_len _((SV* sv));
+
+=item mg_magical
+
+Turns on the magical status of an SV.  See C<sv_magic>.
+
+       void    mg_magical _((SV* sv));
+
+=item mg_set
+
+Do magic after a value is assigned to the SV.  See C<sv_magic>.
+
+       int     mg_set _((SV* sv));
+
+=item Move
+
+The XSUB-writer's interface to the C C<memmove> function.  The C<s> is the
+source, C<d> is the destination, C<n> is the number of items, and C<t> is
+the type.
+
+       (void) Move( s, d, n, t );
+
+=item na
+
+A variable which may be used with C<SvPV> to tell Perl to calculate the
+string length.
+
+=item New
+
+The XSUB-writer's interface to the C C<malloc> function.
+
+       void * New( x, void *ptr, int size, type )
+
+=item Newc
+
+The XSUB-writer's interface to the C C<malloc> function, with cast.
+
+       void * Newc( x, void *ptr, int size, type, cast )
+
+=item Newz
+
+The XSUB-writer's interface to the C C<malloc> function.  The allocated
+memory is zeroed with C<memzero>.
+
+       void * Newz( x, void *ptr, int size, type )
+
+=item newAV
+
+Creates a new AV.  The refcount is set to 1.
+
+       AV*     newAV _((void));
+
+=item newHV
+
+Creates a new HV.  The refcount is set to 1.
+
+       HV*     newHV _((void));
+
+=item newRV
+
+Creates an RV wrapper for an SV.  The refcount for the original SV is
+incremented.
+
+       SV*     newRV _((SV* ref));
+
+=item newSV
+
+Creates a new SV.  The C<len> parameter indicates the number of bytes of
+pre-allocated string space the SV should have.  The refcount for the new SV
+is set to 1.
+
+       SV*     newSV _((STRLEN len));
+
+=item newSViv
+
+Creates a new SV and copies an integer into it.  The refcount for the SV is
+set to 1.
+
+       SV*     newSViv _((IV i));
+
+=item newSVnv
+
+Creates a new SV and copies a double into it.  The refcount for the SV is
+set to 1.
+
+       SV*     newSVnv _((NV i));
+
+=item newSVpv
+
+Creates a new SV and copies a string into it.  The refcount for the SV is
+set to 1.  If C<len> is zero then Perl will compute the length.
+
+       SV*     newSVpv _((char* s, STRLEN len));
+
+=item newSVrv
+
+Creates a new SV for the RV, C<rv>, to point to.  If C<rv> is not an RV then
+it will be upgraded one.  If C<classname> is non-null then the new SV will
+be blessed in the specified package.  The new SV is returned and its
+refcount is 1.
+
+       SV*     newSVrv _((SV* rv, char* classname));
+
+=item newSVsv
+
+Creates a new SV which is an exact duplicate of the orignal SV.
+
+       SV*     newSVsv _((SV* old));
+
+=item newXS
+
+Used by C<xsubpp> to hook up XSUBs as Perl subs.
+
+=item newXSproto
+
+Used by C<xsubpp> to hook up XSUBs as Perl subs.  Adds Perl prototypes to
+the subs.
+
+=item Nullav
+
+Null AV pointer.
+
+=item Nullch
+
+Null character pointer.
+
+=item Nullcv
+
+Null CV pointer.
+
+=item Nullhv
+
+Null HV pointer.
+
+=item Nullsv
+
+Null SV pointer.
+
+=item ORIGMARK
+
+The original stack mark for the XSUB.  See C<dORIGMARK>.
+
+=item perl_alloc
+
+Allocates a new Perl interpreter.  See L<perlembed>.
+
+=item perl_call_argv
+
+Performs a callback to the specified Perl sub.  See L<perlcall>.
+
+       I32     perl_call_argv _((char* subname, I32 flags, char** argv));
+
+=item perl_call_method
+
+Performs a callback to the specified Perl method.  The blessed object must
+be on the stack.  See L<perlcall>.
+
+       I32     perl_call_method _((char* methname, I32 flags));
+
+=item perl_call_pv
+
+Performs a callback to the specified Perl sub.  See L<perlcall>.
+
+       I32     perl_call_pv _((char* subname, I32 flags));
+
+=item perl_call_sv
+
+Performs a callback to the Perl sub whose name is in the SV.  See
+L<perlcall>.
+
+       I32     perl_call_sv _((SV* sv, I32 flags));
+
+=item perl_construct
+
+Initializes a new Perl interpreter.  See L<perlembed>.
+
+=item perl_destruct
+
+Shuts down a Perl interpreter.  See L<perlembed>.
+
+=item perl_eval_sv
+
+Tells Perl to C<eval> the string in the SV.
+
+       I32     perl_eval_sv _((SV* sv, I32 flags));
+
+=item perl_free
+
+Releases a Perl interpreter.  See L<perlembed>.
+
+=item perl_get_av
+
+Returns the AV of the specified Perl array.  If C<create> is set and the
+Perl variable does not exist then it will be created.  If C<create> is not
+set and the variable does not exist then null is returned.
+
+       AV*     perl_get_av _((char* name, I32 create));
+
+=item perl_get_cv
+
+Returns the CV of the specified Perl sub.  If C<create> is set and the Perl
+variable does not exist then it will be created.  If C<create> is not
+set and the variable does not exist then null is returned.
+
+       CV*     perl_get_cv _((char* name, I32 create));
+
+=item perl_get_hv
+
+Returns the HV of the specified Perl hash.  If C<create> is set and the Perl
+variable does not exist then it will be created.  If C<create> is not
+set and the variable does not exist then null is returned.
+
+       HV*     perl_get_hv _((char* name, I32 create));
+
+=item perl_get_sv
+
+Returns the SV of the specified Perl scalar.  If C<create> is set and the
+Perl variable does not exist then it will be created.  If C<create> is not
+set and the variable does not exist then null is returned.
+
+       SV*     perl_get_sv _((char* name, I32 create));
+
+=item perl_parse
+
+Tells a Perl interpreter to parse a Perl script.  See L<perlembed>.
+
+=item perl_require_pv
+
+Tells Perl to C<require> a module.
+
+       void    perl_require_pv _((char* pv));
+
+=item perl_run
+
+Tells a Perl interpreter to run.  See L<perlembed>.
+
+=item POPi
+
+Pops an integer off the stack.
+
+       int POPi();
+
+=item POPl
+
+Pops a long off the stack.
+
+       long POPl();
+
+=item POPp
+
+Pops a string off the stack.
+
+       char * POPp();
+
+=item POPn
+
+Pops a double off the stack.
+
+       double POPn();
+
+=item POPs
+
+Pops an SV off the stack.
+
+       SV* POPs();
+
+=item PUSHMARK
+
+Opening bracket for arguments on a callback.  See C<PUTBACK> and L<perlcall>.
+
+       PUSHMARK(p)
+
+=item PUSHi
+
+Push an integer onto the stack.  The stack must have room for this element.
+See C<XPUSHi>.
+
+       PUSHi(int d)
+
+=item PUSHn
+
+Push a double onto the stack.  The stack must have room for this element.
+See C<XPUSHn>.
+
+       PUSHn(double d)
+
+=item PUSHp
+
+Push a string onto the stack.  The stack must have room for this element.
+The C<len> indicates the length of the string.  See C<XPUSHp>.
+
+       PUSHp(char *c, int len )
+
+=item PUSHs
+
+Push an SV onto the stack.  The stack must have room for this element.  See
+C<XPUSHs>.
+
+       PUSHs(sv)
+
+=item PUTBACK
+
+Closing bracket for XSUB arguments.  This is usually handled by C<xsubpp>.
+See C<PUSHMARK> and L<perlcall> for other uses.
+
+       PUTBACK;
+
+=item Renew
+
+The XSUB-writer's interface to the C C<realloc> function.
+
+       void * Renew( void *ptr, int size, type )
+
+=item Renewc
+
+The XSUB-writer's interface to the C C<realloc> function, with cast.
+
+       void * Renewc( void *ptr, int size, type, cast )
+
+=item RETVAL
+
+Variable which is setup by C<xsubpp> to hold the return value for an XSUB.
+This is always the proper type for the XSUB.  See L<perlxs>.
+
+=item safefree
+
+The XSUB-writer's interface to the C C<free> function.
+
+=item safemalloc
+
+The XSUB-writer's interface to the C C<malloc> function.
+
+=item saferealloc
+
+The XSUB-writer's interface to the C C<realloc> function.
+
+=item savepv
+
+Copy a string to a safe spot.  This does not use an SV.
+
+       char*   savepv _((char* sv));
+
+=item savepvn
+
+Copy a string to a safe spot.  The C<len> indicates number of bytes to
+copy.  This does not use an SV.
+
+       char*   savepvn _((char* sv, I32 len));
+
+=item SAVETMPS
+
+Opening bracket for temporaries on a callback.  See C<FREETMPS> and
+L<perlcall>.
+
+       SAVETMPS;
+
+=item SP
+
+Stack pointer.  This is usually handled by C<xsubpp>.  See C<dSP> and
+C<SPAGAIN>.
+
+=item SPAGAIN
+
+Refetch the stack pointer.  Used after a callback.  See L<perlcall>.
+
+       SPAGAIN;
+
+=item ST
+
+Used to access elements on the XSUB's stack.
+
+       SV* ST(int x)
+
+=item strEQ
+
+Test two strings to see if they are equal.  Returns true or false.
+
+       int strEQ( char *s1, char *s2 )
+
+=item strGE
+
+Test two strings to see if the first, C<s1>, is greater than or equal to the
+second, C<s2>.  Returns true or false.
+
+       int strGE( char *s1, char *s2 )
+
+=item strGT
+
+Test two strings to see if the first, C<s1>, is greater than the second,
+C<s2>.  Returns true or false.
+
+       int strGT( char *s1, char *s2 )
+
+=item strLE
+
+Test two strings to see if the first, C<s1>, is less than or equal to the
+second, C<s2>.  Returns true or false.
+
+       int strLE( char *s1, char *s2 )
+
+=item strLT
+
+Test two strings to see if the first, C<s1>, is less than the second,
+C<s2>.  Returns true or false.
+
+       int strLT( char *s1, char *s2 )
+
+=item strNE
+
+Test two strings to see if they are different.  Returns true or false.
+
+       int strNE( char *s1, char *s2 )
+
+=item strnEQ
+
+Test two strings to see if they are equal.  The C<len> parameter indicates
+the number of bytes to compare.  Returns true or false.
+
+       int strnEQ( char *s1, char *s2 )
+
+=item strnNE
+
+Test two strings to see if they are different.  The C<len> parameter
+indicates the number of bytes to compare.  Returns true or false.
+
+       int strnNE( char *s1, char *s2, int len )
+
+=item sv_2mortal
+
+Marks an SV as mortal.  The SV will be destroyed when the current context
+ends.
+
+       SV*     sv_2mortal _((SV* sv));
+
+=item sv_bless
+
+Blesses an SV into a specified package.  The SV must be an RV.  The package
+must be designated by its stash (see C<gv_stashpv()>).  The refcount of the
+SV is unaffected.
+
+       SV*     sv_bless _((SV* sv, HV* stash));
+
+=item sv_catpv
+
+Concatenates the string onto the end of the string which is in the SV.
+
+       void    sv_catpv _((SV* sv, char* ptr));
+
+=item sv_catpvn
+
+Concatenates the string onto the end of the string which is in the SV.  The
+C<len> indicates number of bytes to copy.
+
+       void    sv_catpvn _((SV* sv, char* ptr, STRLEN len));
+
+=item sv_catsv
+
+Concatentates the string from SV C<ssv> onto the end of the string in SV
+C<dsv>.
+
+       void    sv_catsv _((SV* dsv, SV* ssv));
+
+=item SvCUR
+
+Returns the length of the string which is in the SV.  See C<SvLEN>.
+
+       int SvCUR (SV* sv)
+
+=item SvCUR_set
+
+Set the length of the string which is in the SV.  See C<SvCUR>.
+
+       SvCUR_set (SV* sv, int val )
+
+=item SvEND
+
+Returns a pointer to the last character in the string which is in the SV.
+See C<SvCUR>.  Access the character as
+
+       *SvEND(sv)
+
+=item SvGROW
+
+Expands the character buffer in the SV.
+
+       char * SvGROW( SV* sv, int len )
+
+=item SvIOK
+
+Returns a boolean indicating whether the SV contains an integer.
+
+       int SvIOK (SV* SV)
+
+=item SvIOK_off
+
+Unsets the IV status of an SV.
+
+       SvIOK_off (SV* sv)
+
+=item SvIOK_on
+
+Tells an SV that it is an integer.
+
+       SvIOK_on (SV* sv)
+
+=item SvIOKp
+
+Returns a boolean indicating whether the SV contains an integer.  Checks the
+B<private> setting.  Use C<SvIOK>.
+
+       int SvIOKp (SV* SV)
+
+=item sv_isa
+
+Returns a boolean indicating whether the SV is blessed into the specified
+class.  This does not know how to check for subtype, so it doesn't work in
+an inheritance relationship.
+
+       int     sv_isa _((SV* sv, char* name));
+
+=item SvIV
+
+Returns the integer which is in the SV.
+
+       int SvIV (SV* sv)
+
+=item sv_isobject
+
+Returns a boolean indicating whether the SV is an RV pointing to a blessed
+object.  If the SV is not an RV, or if the object is not blessed, then this
+will return false.
+
+       int     sv_isobject _((SV* sv));
+
+=item SvIVX
+
+Returns the integer which is stored in the SV.
+
+       int  SvIVX (SV* sv);
+
+=item SvLEN
+
+Returns the size of the string buffer in the SV.  See C<SvCUR>.
+
+       int SvLEN (SV* sv)
+
+=item sv_magic
+
+Adds magic to an SV.
+
+       void    sv_magic _((SV* sv, SV* obj, int how, char* name, I32 namlen));
+
+=item sv_mortalcopy
+
+Creates a new SV which is a copy of the original SV.  The new SV is marked
+as mortal.
+
+       SV*     sv_mortalcopy _((SV* oldsv));
+
+=item SvOK
+
+Returns a boolean indicating whether the value is an SV.
+
+       int SvOK (SV* sv)
+
+=item sv_newmortal
+
+Creates a new SV which is mortal.  The refcount of the SV is set to 1.
+
+       SV*     sv_newmortal _((void));
+
+=item sv_no
+
+This is the C<false> SV.  See C<sv_yes>.  Always refer to this as C<&sv_no>.
+
+=item SvNIOK
+
+Returns a boolean indicating whether the SV contains a number, integer or
+double.
+
+       int SvNIOK (SV* SV)
+
+=item SvNIOK_off
+
+Unsets the NV/IV status of an SV.
+
+       SvNIOK_off (SV* sv)
+
+=item SvNIOKp
+
+Returns a boolean indicating whether the SV contains a number, integer or
+double.  Checks the B<private> setting.  Use C<SvNIOK>.
+
+       int SvNIOKp (SV* SV)
+
+=item SvNOK
+
+Returns a boolean indicating whether the SV contains a double.
+
+       int SvNOK (SV* SV)
+
+=item SvNOK_off
+
+Unsets the NV status of an SV.
+
+       SvNOK_off (SV* sv)
+
+=item SvNOK_on
+
+Tells an SV that it is a double.
+
+       SvNOK_on (SV* sv)
+
+=item SvNOKp
+
+Returns a boolean indicating whether the SV contains a double.  Checks the
+B<private> setting.  Use C<SvNOK>.
+
+       int SvNOKp (SV* SV)
+
+=item SvNV
+
+Returns the double which is stored in the SV.
+
+       double SvNV (SV* sv);
+
+=item SvNVX
+
+Returns the double which is stored in the SV.
+
+       double SvNVX (SV* sv);
+
+=item SvPOK
+
+Returns a boolean indicating whether the SV contains a character string.
+
+       int SvPOK (SV* SV)
+
+=item SvPOK_off
+
+Unsets the PV status of an SV.
+
+       SvPOK_off (SV* sv)
+
+=item SvPOK_on
+
+Tells an SV that it is a string.
+
+       SvPOK_on (SV* sv)
+
+=item SvPOKp
+
+Returns a boolean indicating whether the SV contains a character string.
+Checks the B<private> setting.  Use C<SvPOK>.
+
+       int SvPOKp (SV* SV)
+
+=item SvPV
+
+Returns a pointer to the string in the SV, or a stringified form of the SV
+if the SV does not contain a string.  If C<len> is C<na> then Perl will
+handle the length on its own.
+
+       char * SvPV (SV* sv, int len )
+
+=item SvPVX
+
+Returns a pointer to the string in the SV.  The SV must contain a string.
+
+       char * SvPVX (SV* sv)
+
+=item SvREFCNT
+
+Returns the value of the object's refcount.
+
+       int SvREFCNT (SV* sv);
+
+=item SvREFCNT_dec
+
+Decrements the refcount of the given SV.
+
+       void SvREFCNT_dec (SV* sv)
+
+=item SvREFCNT_inc
+
+Increments the refcount of the given SV.
+
+       void SvREFCNT_inc (SV* sv)
+
+=item SvROK
+
+Tests if the SV is an RV.
+
+       int SvROK (SV* sv)
+
+=item SvROK_off
+
+Unsets the RV status of an SV.
+
+       SvROK_off (SV* sv)
+
+=item SvROK_on
+
+Tells an SV that it is an RV.
+
+       SvROK_on (SV* sv)
+
+=item SvRV
+
+Dereferences an RV to return the SV.
+
+       SV*     SvRV (SV* sv);
+
+=item sv_setiv
+
+Copies an integer into the given SV.
+
+       void    sv_setiv _((SV* sv, IV num));
+
+=item sv_setnv
+
+Copies a double into the given SV.
+
+       void    sv_setnv _((SV* sv, double num));
+
+=item sv_setpv
+
+Copies a string into an SV.  The string must be null-terminated.
+
+       void    sv_setpv _((SV* sv, char* ptr));
+
+=item sv_setpvn
+
+Copies a string into an SV.  The C<len> parameter indicates the number of
+bytes to be copied.
+
+       void    sv_setpvn _((SV* sv, char* ptr, STRLEN len));
+
+=item sv_setref_iv
+
+Copies an integer into an SV, optionally blessing the SV.  The SV must be an
+RV.  The C<classname> argument indicates the package for the blessing.  Set
+C<classname> to C<Nullch> to avoid the blessing.  The new SV will be
+returned and will have a refcount of 1.
+
+       SV*     sv_setref_iv _((SV *rv, char *classname, IV iv));
+
+=item sv_setref_nv
+
+Copies a double into an SV, optionally blessing the SV.  The SV must be an
+RV.  The C<classname> argument indicates the package for the blessing.  Set
+C<classname> to C<Nullch> to avoid the blessing.  The new SV will be
+returned and will have a refcount of 1.
+
+       SV*     sv_setref_nv _((SV *rv, char *classname, double nv));
+
+=item sv_setref_pv
+
+Copies a pointer into an SV, optionally blessing the SV.  The SV must be an
+RV.  If the C<pv> argument is NULL then C<sv_undef> will be placed into the
+SV.  The C<classname> argument indicates the package for the blessing.  Set
+C<classname> to C<Nullch> to avoid the blessing.  The new SV will be
+returned and will have a refcount of 1.
+
+       SV*     sv_setref_pv _((SV *rv, char *classname, void* pv));
+
+Do not use with integral Perl types such as HV, AV, SV, CV, because those
+objects will become corrupted by the pointer copy process.
+
+Note that C<sv_setref_pvn> copies the string while this copies the pointer.
+
+=item sv_setref_pvn
+
+Copies a string into an SV, optionally blessing the SV.  The lenth of the
+string must be specified with C<n>.  The SV must be an RV.  The C<classname>
+argument indicates the package for the blessing.  Set C<classname> to
+C<Nullch> to avoid the blessing.  The new SV will be returned and will have
+a refcount of 1.
+
+       SV*     sv_setref_pvn _((SV *rv, char *classname, char* pv, I32 n));
+
+Note that C<sv_setref_pv> copies the pointer while this copies the string.
+
+=item sv_setsv
+
+Copies the contents of the source SV C<ssv> into the destination SV C<dsv>.
+
+       void    sv_setsv _((SV* dsv, SV* ssv));
+
+=item SvSTASH
+
+Returns the stash of the SV.
+
+       HV * SvSTASH (SV* sv)
+
+=item SVt_IV
+
+Integer type flag for scalars.  See C<svtype>.
+
+=item SVt_PV
+
+Pointer type flag for scalars.  See C<svtype>.
+
+=item SVt_PVAV
+
+Type flag for arrays.  See C<svtype>.
+
+=item SVt_PVCV
+
+Type flag for code refs.  See C<svtype>.
+
+=item SVt_PVHV
+
+Type flag for hashes.  See C<svtype>.
+
+=item SVt_PVMG
+
+Type flag for blessed scalars.  See C<svtype>.
+
+=item SVt_NV
+
+Double type flag for scalars.  See C<svtype>.
+
+=item SvTRUE
+
+Returns a boolean indicating whether Perl would evaluate the SV as true or
+false, defined or undefined.
+
+       int SvTRUE (SV* sv)
+
+=item SvTYPE
+
+Returns the type of the SV.  See C<svtype>.
+
+       svtype  SvTYPE (SV* sv)
+
+=item svtype
+
+An enum of flags for Perl types.  These are found in the file B<sv.h> in the
+C<svtype> enum.  Test these flags with the C<SvTYPE> macro.
+
+=item SvUPGRADE
+
+Used to upgrade an SV to a more complex form.  See C<svtype>.
+
+=item sv_undef
+
+This is the C<undef> SV.  Always refer to this as C<&sv_undef>.
+
+=item sv_usepvn
+
+Tells an SV to use C<ptr> to find its string value.  Normally the string is
+stored inside the SV; this allows the SV to use an outside string.  The
+string length, C<len>, must be supplied.  This function will realloc the
+memory pointed to by C<ptr>, so that pointer should not be freed or used by
+the programmer after giving it to sv_usepvn.
+
+       void    sv_usepvn _((SV* sv, char* ptr, STRLEN len));
+
+=item sv_yes
+
+This is the C<true> SV.  See C<sv_no>.  Always refer to this as C<&sv_yes>.
+
+=item THIS
+
+Variable which is setup by C<xsubpp> to designate the object in a C++ XSUB.
+This is always the proper type for the C++ object.  See C<CLASS> and
+L<perlxs>.
+
+=item toLOWER
+
+Converts the specified character to lowercase.
+
+       int toLOWER (char c)
+
+=item toUPPER
+
+Converts the specified character to uppercase.
+
+       int toUPPER (char c)
+
+=item warn
+
+This is the XSUB-writer's interface to Perl's C<warn> function.  Use this
+function the same way you use the C C<printf> function.  See C<croak()>.
+
+=item XPUSHi
+
+Push an integer onto the stack, extending the stack if necessary.  See
+C<PUSHi>.
+
+       XPUSHi(int d)
+
+=item XPUSHn
+
+Push a double onto the stack, extending the stack if necessary.  See
+C<PUSHn>.
+
+       XPUSHn(double d)
+
+=item XPUSHp
+
+Push a string onto the stack, extending the stack if necessary.  The C<len>
+indicates the length of the string.  See C<PUSHp>.
+
+       XPUSHp(char *c, int len)
+
+=item XPUSHs
+
+Push an SV onto the stack, extending the stack if necessary.  See C<PUSHs>.
+
+       XPUSHs(sv)
+
+=item XSRETURN
+
+Return from XSUB, indicating number of items on the stack.  This is usually
+handled by C<xsubpp>.
+
+       XSRETURN(x);
+
+=item XSRETURN_EMPTY
+
+Return from an XSUB immediately.
+
+       XSRETURN_EMPTY;
+
+=item XSRETURN_NO
+
+Return C<false> from an XSUB immediately.
+
+       XSRETURN_NO;
+
+=item XSRETURN_UNDEF
+
+Return C<undef> from an XSUB immediately.
+
+       XSRETURN_UNDEF;
+
+=item XSRETURN_YES
+
+Return C<true> from an XSUB immediately.
+
+       XSRETURN_YES;
+
+=item Zero
+
+The XSUB-writer's interface to the C C<memzero> function.  The C<d> is the
+destination, C<n> is the number of items, and C<t> is the type.
+
+       (void) Zero( d, n, t );
+
+=back
+
+=head1 AUTHOR
+
+Jeff Okamoto <okamoto@corp.hp.com>
+
+With lots of help and suggestions from Dean Roehrich, Malcolm Beattie,
+Andreas Koenig, Paul Hudson, Ilya Zakharevich, Paul Marquess, Neil
+Bowers, Matthew Green, Tim Bunce, and Spider Boardman.
+
+API Listing by Dean Roehrich <roehrich@cray.com>.
+
+=head1 DATE
+
+Version 20: 1995/12/14
 
-Version 19: 1995/4/26
index 3166f1a..1a3bdad 100644 (file)
@@ -1,7 +1,6 @@
 =head1 NAME
 
-perlipc - Perl interprocess communication (signals, fifos, pipes, safe
-subprocceses, sockets, and semaphores)
+perlipc - Perl interprocess communication (signals, fifos, pipes, safe subprocceses, sockets, and semaphores)
 
 =head1 DESCRIPTION
 
index 4b58bee..11632e0 100644 (file)
@@ -1,8 +1,10 @@
-=head1 TITLE
+=head1 NAME
 
 perlLoL - Manipulating Lists of Lists in Perl
 
-=head1 Declaration and Access
+=head1 DESCRIPTION
+
+=head1 Declaration and Access of Lists of Lists
 
 The simplest thing to build is a list of lists (sometimes called an array
 of arrays).  It's reasonably easy to understand, and almost everything
@@ -300,48 +302,6 @@ If I were you, I'd put that in a function:
     } 
 
 
-=head1 Passing Arguments
-
-One place where a list of lists crops up is when you pass
-in several list references to a function.  Consider:
-
-    @tailings = popmany ( \@a, \@b, \@c, \@d );
-
-    sub popmany {
-       my $aref;
-       my @retlist = ();
-       foreach $aref ( @_ ) {
-           push @retlist, pop @$aref;
-       } 
-       return @retlist;
-    } 
-
-This function was designed to pop off the last element from each of
-its arguments and return those in a list.  In this function, 
-you can think of @_ as a list of lists.
-
-Just as a side note, what happens if the function is called with the
-"wrong" types of arguments?  Normally nothing, but in the case of
-references, we can be a bit pickier.  This isn't detectable at
-compile-time (yet--Larry does have a prototype prototype in the works for
-5.002), but you could check it at run time using the ref() function.
-
-    use Carp;
-    for $i ( 0 .. $#_) {
-       if (ref($_[$i]) ne 'ARRAY') {
-           confess "popmany: arg $i not an array reference\n";
-       }
-    } 
-
-However, that's not usually necessary unless you want to trap it.  It's
-also dubious in that it would fail on a real array references blessed into
-its own class (an object).  But since you're all going to be using
-C<strict refs>, it would raise an exception anyway even without the die.
-
-This will matter more to you later on when you start building up 
-more complex data structures that all aren't woven of the same 
-cloth, so to speak.
-
 =head1 SEE ALSO
 
 perldata(1), perlref(1), perldsc(1)
index c5ab08a..3ada156 100644 (file)
@@ -7,14 +7,16 @@ perlmod - Perl modules (packages)
 =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.
-By default, a Perl script starts
-compiling into the package known as C<main>.  You can switch namespaces
-using the C<package> declaration.  The scope of the package declaration is
-from the declaration itself to the end of the enclosing block (the same
-scope as the local() operator).  Typically it would be the first
-declaration in a file to be included by the C<require> operator.  You can
+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
+declaration itself through the end of the enclosing block (the same scope
+as the local() operator).  All further unqualified dynamic identifiers
+will be in this namespace.  A package statement only affects dynamic
+variables--including those you've used local() on--but I<not> lexical
+variables created with my().  Typically it would be the first declaration
+in a file to be included by the C<require> or C<use> operator.  You can
 switch into a package in more than one place; it merely influences which
 symbol table is used by the compiler for the rest of that block.  You can
 refer to variables and filehandles in other packages by prefixing the
@@ -35,17 +37,19 @@ within package C<OUTER> that C<$INNER::var> refers to C<$OUTER::INNER::var>.
 It would treat package C<INNER> as a totally separate global package.
 
 Only identifiers starting with letters (or underscore) are stored in a
-package's symbol table.  All other symbols are kept in package C<main>.
-In addition, the identifiers STDIN, STDOUT, STDERR, ARGV,
-ARGVOUT, ENV, INC and SIG are forced to be in package C<main>,
-even when used for other purposes than their built-in one.  Note also
-that, if you have a package called C<m>, C<s> or C<y>, then you can't use
-the qualified form of an identifier because it will be interpreted instead
-as a pattern match, a substitution, or a translation.
+package's symbol table.  All other symbols are kept in package C<main>,
+including all of the punctuation variables like $_.  In addition, the
+identifiers STDIN, STDOUT, STDERR, ARGV, ARGVOUT, ENV, INC and SIG are
+forced to be in package C<main>, even when used for other purposes than
+their built-in one.  Note also that, if you have a package called C<m>,
+C<s> or C<y>, then you can't use the qualified form of an identifier
+because it will be interpreted instead as a pattern match, a substitution,
+or a translation.
 
 (Variables beginning with underscore used to be forced into package
 main, but we decided it was more useful for package writers to be able
-to use leading underscore to indicate private variables and method names.)
+to use leading underscore to indicate private variables and method names.
+$_ is still global though.)
 
 Eval()ed strings are compiled in the package in which the eval() was
 compiled.  (Assignments to C<$SIG{}>, however, assume the signal
@@ -58,6 +62,9 @@ temporarily switches back to the C<main> package to evaluate various
 expressions in the context of the C<main> package (or wherever you came
 from).  See L<perldebug>.
 
+See L<perlsub> for other scoping issues related to my() and local(), 
+or L<perlref> regarding closures.
+
 =head2 Symbol Tables
 
 The symbol table for a package happens to be stored in the associative
@@ -65,10 +72,10 @@ 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
-have the same effect, though the first is more efficient because it
-does the symbol table lookups at compile time:
+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
+have the same effect, though the first is more efficient because it does
+the symbol table lookups at compile time:
 
     local(*main::foo) = *main::bar; local($main::{'foo'}) =
     $main::{'bar'};
@@ -108,8 +115,7 @@ Note that even though the subroutine is compiled in package C<dumpvar>,
 the name of the subroutine is qualified so that its name is inserted
 into package C<main>.
 
-Assignment to a typeglob performs an aliasing operation,
-i.e.,
+Assignment to a typeglob performs an aliasing operation, i.e.,
 
     *dick = *richard;
 
@@ -123,6 +129,32 @@ assign a reference instead:
 makes $richard and $dick the same variable, but leaves
 @richard and @dick as separate arrays.  Tricky, eh?
 
+This mechanism may be used to pass and return cheap references
+into or from subroutines if you won't want to copy the whole
+thing.
+
+    %some_hash = ();
+    *some_hash = fn( \%another_hash );
+    sub fn {
+       local *hashsym = shift;
+       # now use %hashsym normally, and you
+       # will affect the caller's %another_hash
+       my %nhash = (); # do what you want
+       return \%nhash; 
+    }
+
+On return, the reference wil overwrite the hash slot in the
+symbol table specified by the *some_hash typeglob.  This
+is a somewhat tricky way of passing around refernces cheaply
+when you won't want to have to remember to dereference variables
+explicitly.
+
+Another use of symbol tables is for making "constant"  scalars.
+
+    *PI = \3.14159265358979;
+
+Now you cannot alter $PI, which is probably a good thing all in all.
+
 =head2 Package Constructors and Destructors
 
 There are two special subroutine definitions that function as package
@@ -196,6 +228,14 @@ or
 
     BEGIN { require "Module.pm"; import Module LIST; }
 
+As a special case
+
+    use Module ();
+
+is exactly equivalent to
+
+    BEGIN { require "Module.pm"; }
+
 All Perl module files have the extension F<.pm>.  C<use> assumes this so
 that you don't have to spell out "F<Module.pm>" in quotes.  This also
 helps to differentiate new modules from old F<.pl> and F<.ph> files.
@@ -209,9 +249,7 @@ before the rest of the file is compiled.  This is how it is able
 to function as a pragma mechanism, and also how modules are able to
 declare subroutines that are then visible as list operators for
 the rest of the current file.  This will not work if you use C<require>
-instead of C<use>.  Therefore, if you're planning on the module altering
-your namespace, use C<use>; otherwise, use C<require>.  Otherwise you 
-can get into this problem:
+instead of C<use>.  With require you can get into this problem:
 
     require Cwd;               # make Cwd:: accessible
     $here = Cwd::getcwd();     
@@ -222,6 +260,8 @@ can get into this problem:
     require Cwd;               # make Cwd:: accessible
     $here = getcwd();          # oops! no main::getcwd()
 
+In general C<use Module ();> is recommended over C<require Module;>.
+
 Perl packages may be nested inside other package names, so we can have
 package names containing C<::>.  But if we used that package name
 directly as a filename it would makes for unwieldy or impossible
@@ -283,27 +323,31 @@ The following programs are defined (and have their own documentation).
 
 =over 12
 
-=item C<diagnostics>
+=item diagnostics
 
 Pragma to produce enhanced diagnostics
 
-=item C<integer>
+=item integer
 
 Pragma to compute arithmetic in integer instead of double
 
-=item C<less>
+=item less
 
 Pragma to request less of something from the compiler
 
-=item C<sigtrap>
+=item overload
+
+Pragma for overloading operators 
+
+=item sigtrap
 
 Pragma to enable stack backtrace on unexpected signals
 
-=item C<strict>
+=item strict
 
 Pragma to restrict unsafe constructs
 
-=item C<subs>
+=item subs
 
 Pragma to predeclare sub names
 
@@ -315,7 +359,152 @@ Standard, bundled modules are all expected to behave in a well-defined
 manner with respect to namespace pollution because they use the
 Exporter module.  See their own documentation for details.
 
-To find out all the modules installed on your system, do this:
+=over 12
+
+=item AnyDBM_File
+
+provide framework for multiple DBMs
+
+=item AutoLoader
+
+load functions only on demand
+
+=item AutoSplit
+
+split a package for autoloading
+
+=item Benchmark
+
+benchmark running times of code
+
+=item Carp
+
+warn of errors (from perspective of caller)
+
+=item Config
+
+access Perl configuration option
+
+=item Cwd
+
+get pathname of current working directory
+
+=item DB_File
+
+Perl access to Berkeley DB
+
+=item Devel::SelfStubber
+
+generate stubs for a SelfLoading module
+
+=item DynaLoader
+
+Dynamically load C libraries into Perl code
+
+=item English
+
+use nice English (or awk) names for ugly punctuation variables
+
+=item Env
+
+perl module that imports environment variables
+
+=item Exporter
+
+provide inport/export controls for Perl modules
+
+=item ExtUtils::Liblist
+
+determine libraries to use and how to use them
+
+=item ExtUtils::MakeMaker
+
+create an extension Makefile
+
+=item ExtUtils::Manifest
+
+utilities to write and check a MANIFEST file
+
+=item ExtUtils::Mkbootstrap
+
+make a bootstrap file for use by DynaLoader
+
+=item ExtUtils::Miniperl
+
+!!!GOOD QUESTION!!!
+
+=item Fcntl
+
+load the C Fcntl.h defines
+
+=item File::Basename
+
+parse file specifications
+
+=item File::CheckTree
+
+run many filetest checks on a tree
+
+=item File::Find
+
+traverse a file tree
+
+=item FileHandle
+
+supply object methods for filehandles
+
+=item File::Path
+
+create or remove a series of directories
+
+=item Getopt::Long
+
+extended getopt processing
+
+=item Getopt::Std
+
+Process single-character switches with switch clustering
+
+=item I18N::Collate
+
+compare 8-bit scalar data according to the current locale
+
+=item IPC::Open2
+
+a process for both reading and writing
+
+=item IPC::Open3
+
+open a process for reading, writing, and error handling
+
+=item Net::Ping
+
+check a host for upness
+
+=item POSIX
+
+Perl interface to IEEE Std 1003.1
+
+=item SelfLoader
+
+load functions only on demand
+
+=item Socket
+
+load the C socket.h defines and structure manipulators
+
+=item Test::Harness
+
+run perl standard test scripts with statistics
+
+=item Text::Abbrev
+
+rceate an abbreviation table from a list
+
+=back
+
+To find out I<all> the modules installed on your system, including
+those without documentation or outside the standard release, do this:
 
     find `perl -e 'print "@INC"'` -name '*.pm' -print
 
@@ -328,15 +517,15 @@ Extension modules are written in C (or a mix of Perl and C) and get
 dynamically loaded into Perl if and when you need them.  Supported
 extension modules include the Socket, Fcntl, and POSIX modules.
 
-Many popular C extension modules
-do not come bundled (at least, not completely)
-due to their size, volatility, or simply lack of time for adequate testing
-and configuration across the multitude of platforms on which Perl was
-beta-tested.  You are encouraged to look for them in archie(1L), the Perl
-FAQ or Meta-FAQ, the WWW page, and even with their authors before randomly
-posting asking for their present condition and disposition.  
+Many popular C extension modules do not come bundled (at least, not
+completely) due to their size, volatility, or simply lack of time for
+adequate testing and configuration across the multitude of platforms on
+which Perl was beta-tested.  You are encouraged to look for them in
+archie(1L), the Perl FAQ or Meta-FAQ, the WWW page, and even with their
+authors before randomly posting asking for their present condition and
+disposition.
 
-=head2 CPAN
+=head1 CPAN
 
 CPAN stands for the Comprehensive Perl Archive Network.  This is a globally
 replicated collection of all known Perl materials, including hundreds 
@@ -483,4 +672,394 @@ ftp://ftp.is.co.za/programming/perl/CPAN/
 =back
 
 For an up-to-date listing of CPAN sites, 
-see http://www.perl.com/perl/ or ftp://ftp.perl.com/perl/.
+see http://www.perl.com/perl/ or ftp://ftp.perl.com/perl/ .
+
+=head1 Modules: Creation, Use and Abuse
+
+(The following section is borrowed directly from Tim Bunce's modules
+file, available at your nearest CPAN site.)
+
+Perl 5 implements a class using a package, but the presence of a
+package doesn't imply the presence of a class.  A package is just a
+namespace.  A class is a package that provides subroutines that can be
+used as methods.  A method is just a subroutine that expects, as its
+first argument, either the name of a package (for "static" methods),
+or a reference to something (for "virtual" methods).
+
+A module is a file that (by convention) provides a class of the same
+name (sans the .pm), plus an import method in that class that can be
+called to fetch exported symbols.  This module may implement some of
+its methods by loading dynamic C or C++ objects, but that should be
+totally transparent to the user of the module.  Likewise, the module
+might set up an AUTOLOAD function to slurp in subroutine definitions on
+demand, but this is also transparent.  Only the .pm file is required to
+exist.
+
+=head2 Guidelines for Module Creation
+
+=over 4
+
+=item Do similar modules already exist in some form?
+
+If so, please try to reuse the existing modules either in whole or
+by inheriting useful features into a new class.  If this is not
+practical try to get together with the module authors to work on
+extending or enhancing the functionality of the existing modules.
+A perfect example is the plethora of packages in perl4 for dealing
+with command line options.
+
+If you are writing a module to expand an already existing set of
+modules, please coordinate with the author of the package.  It
+helps if you follow the same naming scheme and module interaction
+scheme as the original author.
+
+=item Try to design the new module to be easy to extend and reuse.
+
+Use blessed references.  Use the two argument form of bless to bless
+into the class name given as the first parameter of the constructor,
+e.g.:
+
+ sub new { 
+       my $class = shift;
+       return bless {}, $class;
+ }
+
+or even this if you'd like it to be used as either a static
+or a virtual method.
+
+ sub new { 
+       my $self  = shift;
+       my $class = ref($self) || $self;
+       return bless {}, $class;
+ }
+
+Pass arrays as references so more parameters can be added later
+(it's also faster).  Convert functions into methods where
+appropriate.  Split large methods into smaller more flexible ones.
+Inherit methods from other modules if appropriate.
+
+Avoid class name tests like: die "Invalid" unless ref $ref eq 'FOO'.
+Generally you can delete the "eq 'FOO'" part with no harm at all.
+Let the objects look after themselves! Generally, avoid hardwired
+class names as far as possible.
+
+Avoid $r->Class::func() where using @ISA=qw(... Class ...) and
+$r->func() would work (see perlbot man page for more details).
+
+Use autosplit so little used or newly added functions won't be a
+burden to programs which don't use them. Add test functions to
+the module after __END__ either using AutoSplit or by saying:
+
+ eval join('',<main::DATA>) || die $@ unless caller();
+
+Does your module pass the 'empty sub-class' test? If you say
+"@SUBCLASS::ISA = qw(YOURCLASS);" your applications should be able
+to use SUBCLASS in exactly the same way as YOURCLASS.  For example,
+does your application still work if you change:  $obj = new YOURCLASS;
+into: $obj = new SUBCLASS; ?
+
+Avoid keeping any state information in your packages. It makes it
+difficult for multiple other packages to use yours. Keep state
+information in objects.
+
+Always use C<-w>. Try to C<use strict;> (or C<use strict qw(...);>).
+Remember that you can add C<no strict qw(...);> to individual blocks
+of code which need less strictness. Always use C<-w>. Always use C<-w>!
+Follow the guidelines in the perlstyle(1) manual.
+
+=item Some simple style guidelines
+
+The perlstyle manual supplied with perl has many helpful points.
+
+Coding style is a matter of personal taste. Many people evolve their
+style over several years as they learn what helps them write and
+maintain good code.  Here's one set of assorted suggestions that
+seem to be widely used by experienced developers:
+
+Use underscores to separate words.  It is generally easier to read
+$var_names_like_this than $VarNamesLikeThis, especially for
+non-native speakers of English. It's also a simple rule that works
+consistently with VAR_NAMES_LIKE_THIS.
+
+Package/Module names are an exception to this rule. Perl informally
+reserves lowercase module names for 'pragma' modules like integer
+and strict. Other modules normally begin with a capital letter and
+use mixed case with no underscores (need to be short and portable).
+
+You may find it helpful to use letter case to indicate the scope
+or nature of a variable. For example:
+
+ $ALL_CAPS_HERE   constants only (beware clashes with perl vars)
+ $Some_Caps_Here  package-wide global/static
+ $no_caps_here    function scope my() or local() variables
+
+Function and method names seem to work best as all lowercase.
+E.g., $obj->as_string().
+
+You can use a leading underscore to indicate that a variable or
+function should not be used outside the package that defined it.
+
+=item Select what to export.
+
+Do NOT export method names!
+
+Do NOT export anything else by default without a good reason!
+
+Exports pollute the namespace of the module user.  If you must
+export try to use @EXPORT_OK in preference to @EXPORT and avoid
+short or common names to reduce the risk of name clashes.
+
+Generally anything not exported is still accessible from outside the
+module using the ModuleName::item_name (or $blessed_ref->method)
+syntax.  By convention you can use a leading underscore on names to
+informally indicate that they are 'internal' and not for public use.
+
+(It is actually possible to get private functions by saying:
+my $subref = sub { ... };  &$subref; But there's no way to call that
+directly as a method, since a method must have a name in the symbol
+table.)
+
+As a general rule, if the module is trying to be object oriented
+then export nothing. If it's just a collection of functions then
+@EXPORT_OK anything but use @EXPORT with caution.
+
+=item Select a name for the module.
+
+This name should be as descriptive, accurate and complete as
+possible.  Avoid any risk of ambiguity. Always try to use two or
+more whole words.  Generally the name should reflect what is special
+about what the module does rather than how it does it.  Please use
+nested module names to informally group or categorise a module.
+A module should have a very good reason not to have a nested name.
+Module names should begin with a capital letter.
+
+Having 57 modules all called Sort will not make life easy for anyone
+(though having 23 called Sort::Quick is only marginally better :-).
+Imagine someone trying to install your module alongside many others.
+If in any doubt ask for suggestions in comp.lang.perl.misc.
+
+If you are developing a suite of related modules/classes it's good
+practice to use nested classes with a common prefix as this will
+avoid namespace clashes. For example:  Xyz::Control, Xyz::View,
+Xyz::Model etc. Use the modules in this list as a naming guide.
+
+If adding a new module to a set, follow the original author's
+standards for naming modules and the interface to methods in
+those modules.
+
+To be portable each component of a module name should be limited to
+11 characters. If it might be used on DOS then try to ensure each is
+unique in the first 8 characters. Nested modules make this easier.
+
+=item Have you got it right?
+
+How do you know that you've made the right decisions? Have you
+picked an interface design that will cause problems later? Have
+you picked the most appropriate name? Do you have any questions?
+
+The best way to know for sure, and pick up many helpful suggestions,
+is to ask someone who knows. Comp.lang.perl.misc is read by just about
+all the people who develop modules and it's the best place to ask.
+
+All you need to do is post a short summary of the module, its
+purpose and interfaces. A few lines on each of the main methods is
+probably enough. (If you post the whole module it might be ignored
+by busy people - generally the very people you want to read it!)
+
+Don't worry about posting if you can't say when the module will be
+ready - just say so in the message. It might be worth inviting
+others to help you, they may be able to complete it for you!
+
+=item README and other Additional Files.
+
+It's well known that software developers usually fully document the
+software they write. If, however, the world is in urgent need of
+your software and there is not enough time to write the full
+documentation please at least provide a README file containing:
+
+=over 10
+
+=item *
+A description of the module/package/extension etc.
+
+=item *
+A copyright notice - see below.
+
+=item *
+Prerequisites - what else you may need to have.
+
+=item *
+How to build it - possible changes to Makefile.PL etc.
+
+=item *
+How to install it.
+
+=item *
+Recent changes in this release, especially incompatibilities
+
+=item *
+Changes / enhancements you plan to make in the future.
+
+=back
+
+If the README file seems to be getting too large you may wish to
+split out some of the sections into separate files: INSTALL,
+Copying, ToDo etc.
+
+=item Adding a Copyright Notice.
+
+How you choose to licence your work is a personal decision.
+The general mechanism is to assert your Copyright and then make
+a declaration of how others may copy/use/modify your work.
+
+Perl, for example, is supplied with two types of licence: The GNU
+GPL and The Artistic License (see the files README, Copying and
+Artistic).  Larry has good reasons for NOT just using the GNU GPL.
+
+My personal recommendation, out of respect for Larry, Perl and the
+perl community at large is to simply state something like:
+
+ Copyright (c) 1995 Your Name. All rights reserved.
+ This program is free software; you can redistribute it and/or
+ modify it under the same terms as Perl itself.
+
+This statement should at least appear in the README file. You may
+also wish to include it in a Copying file and your source files.
+Remember to include the other words in addition to the Copyright.
+
+=item Give the module a version/issue/release number.
+
+To be fully compatible with the Exporter and MakeMaker modules you
+should store your module's version number in a non-my package
+variable called $VERSION.  This should be a valid floating point 
+number with at least two digits after the decimal (ie hundredths,
+e.g, $VERSION = "0.01").  Don't use a "1.3.2" style version.
+See Exporter.pm in Perl5.001m or later for details.
+
+It may be handy to add a function or method to retrieve the number.
+Use the number in announcements and archive file names when
+releasing the module (ModuleName-1.02.tar.Z).
+See perldoc ExtUtils::MakeMaker.pm for details.
+
+=item How to release and distribute a module.
+
+It's good idea to post an announcement of the availability of your
+module (or the module itself if small) to the comp.lang.perl.announce
+Usenet newsgroup.  This will at least ensure very wide once-off
+distribution.
+
+If possible you should place the module into a major ftp archive and
+include details of it's location in your announcement.
+
+Some notes about ftp archives: Please use a long descriptive file
+name which includes the version number. Most incoming directories
+will not be readable/listable, i.e., you won't be able to see your
+file after uploading it. Remember to send your email notification
+message as soon as possible after uploading else your file may get
+deleted automatically. Allow time for the file to be processed
+and/or check the file has been processed before announcing its
+location.
+
+FTP Archives for Perl Modules:
+
+Follow the instructions and links on
+
+   http://franz.ww.tu-berlin.de/modulelist
+
+or upload to one of these sites: 
+
+   ftp://franz.ww.tu-berlin.de/incoming
+   ftp://ftp.cis.ufl.edu/incoming  
+
+and notify upload@franz.ww.tu-berlin.de.
+
+By using the WWW interface you can ask the Upload Server to mirror
+your modules from your ftp or WWW site into your own directory on
+CPAN!
+
+Please remember to send me an updated entry for the Module list!
+
+=item Take care when changing a released module.
+
+Always strive to remain compatible with previous released versions
+(see 2.2 above) Otherwise try to add a mechanism to revert to the
+old behaviour if people rely on it. Document incompatible changes.
+
+=back
+
+=head2 Guidelines for Converting Perl 4 Library Scripts into Modules
+
+=over 4
+
+=item There is no requirement to convert anything.
+
+If it ain't broke, don't fix it! Perl 4 library scripts should
+continue to work with no problems. You may need to make some minor
+changes (like escaping non-array @'s in double quoted strings) but
+there is no need to convert a .pl file into a Module for just that.
+
+=item Consider the implications.
+
+All the perl applications which make use of the script will need to
+be changed (slightly) if the script is converted into a module.  Is
+it worth it unless you plan to make other changes at the same time?
+
+=item Make the most of the opportunity.
+
+If you are going to convert the script to a module you can use the
+opportunity to redesign the interface. The 'Guidelines for Module
+Creation' above include many of the issues you should consider.
+
+=item The pl2pm utility will get you started.
+
+This utility will read *.pl files (given as parameters) and write
+corresponding *.pm files. The pl2pm utilities does the following:
+
+=over 10
+
+=item *
+Adds the standard Module prologue lines
+
+=item *
+Converts package specifiers from ' to ::
+
+=item *
+Converts die(...) to croak(...)
+
+=item *
+Several other minor changes
+
+=back
+
+Being a mechanical process pl2pm is not bullet proof. The converted
+code will need careful checking, especially any package statements.
+Don't delete the original .pl file till the new .pm one works!
+
+=back
+
+=head2 Guidelines for Reusing Application Code
+
+=over 4
+
+=item Complete applications rarely belong in the Perl Module Library.
+
+=item Many applications contain some perl code which could be reused.
+
+Help save the world! Share your code in a form that makes it easy
+to reuse.
+
+=item Break-out the reusable code into one or more separate module files.
+
+=item Take the opportunity to reconsider and redesign the interfaces.
+
+=item In some cases the 'application' can then be reduced to a small
+
+fragment of code built on top of the reusable modules. In these cases
+the application could invoked as:
+
+     perl -e 'use Module::Name; method(@ARGV)' ...
+or   
+     perl -mModule::Name ...    (in perl5.002?)
+
+=back
+
index 6bbaab4..59c6f12 100644 (file)
@@ -34,7 +34,7 @@ We'll cover these points now in more depth.
 
 Unlike say C++, Perl doesn't provide any special syntax for
 constructors.  A constructor is merely a subroutine that returns a
-reference that has been "blessed" into a class, generally the
+reference to something "blessed" into a class, generally the
 class that the subroutine is defined in.  Here is a typical
 constructor:
 
@@ -61,7 +61,33 @@ that wish to call methods in the class as part of the construction:
        my $self = {}
        bless $self;
        $self->initialize();
-       $self;
+       return $self;
+    }
+
+If you care about inheritance (and you should; see L<perlmod/"Modules:
+Creation, Use and Abuse">), then you want to use the two-arg form of bless
+so that your constructors may be inherited:
+
+    sub new {
+       my $class = shift;
+       my $self = {};
+       bless $self, $class
+       $self->initialize();
+       return $self;
+    }
+
+Or if you expect people to call not just C<CLASS->new()> but also
+C<$obj->new()>, then use something like this.  The initialize()
+method used will be of whatever $class we blessed the 
+object into:
+
+    sub new {
+       my $this = shift;
+       my $class = ref($this) || $this;
+       my $self = {};
+       bless $self, $class
+       $self->initialize();
+       return $self;
     }
 
 Within the class package, the methods will typically deal with the
@@ -100,7 +126,7 @@ package.  This is how Perl implements inheritance.  Each element of the
 @ISA array is just the name of another package that happens to be a
 class package.  The classes are searched (depth first) for missing
 methods in the order that they occur in @ISA.  The classes accessible
-through @ISA are known as base classes of the current class.
+through @ISA are known as base classes of the current class. 
 
 If a missing method is found in one of the base classes, it is cached
 in the current class for efficiency.  Changing @ISA or defining new
@@ -224,6 +250,16 @@ name with the package like this:
     $fred = Critter->MyCritter::find("Fred");
     $fred->MyCritter::display('Height', 'Weight');
 
+If you're trying to control where the method search begins I<and> you're
+executing in the class itself, then you may use the SUPER pseudoclass,
+which says to start looking in your base class's @ISA list without having
+to explicitly name it:
+
+    $self->SUPER::display('Height', 'Weight');
+
+Please note that the C<SUPER::> construct is I<only> meaningful within the
+class.
+
 Sometimes you want to call a method when you don't know the method name
 ahead of time.  You can use the arrow form, replacing the method name
 with a simple scalar variable containing the method name:
@@ -268,6 +304,107 @@ That's about all there is to it.  Now you just need to go off and buy a
 book about object-oriented design methodology, and bang your forehead
 with it for the next six months or so.
 
+=head2 Two-Phased Garbage Collection
+
+For most purposes, Perl uses a fast and simple reference-based
+garbage collection system.  For this reason, there's an extra
+dereference going on at some level, so if you haven't built
+your Perl executable using your C compiler's C<-O> flag, performance
+will suffer.  If you I<have> built Perl with C<cc -O>, then this
+probably won't matter.
+
+A more serious concern is that unreachable memory with a non-zero
+reference count will not normally get freed.  Therefore, this is a bad
+idea:  
+
+    {
+       my $a;
+       $a = \$a;
+    } 
+
+Even thought $a I<should> go away, it can't.  When building recursive data
+structures, you'll have to break the self-reference yourself explicitly
+if you don't care to leak.  For example, here's a self-referential
+node such as one might use in a sophisticated tree structure:
+
+    sub new_node {
+       my $self = shift;
+       my $class = ref($self) || $self;
+       my $node = {};
+       $node->{LEFT} = $node->{RIGHT} = $node;
+       $node->{DATA} = [ @_ ];
+       return bless $node => $class;
+    } 
+
+If you create nodes like that, they (currently) won't go away unless you
+break their self reference yourself.  (In other words, this is not to be
+construed as a feature, and you shouldn't depend on it.)
+
+Almost.
+
+When an interpreter thread finally shuts down (usually when your program
+exits), then a rather costly but complete mark-and-sweep style of garbage
+collection is performed, and everything allocated by that thread gets
+destroyed.  This is essential to support Perl as an embedded or a
+multithreadable language.  For example, this program demonstrates Perl's
+two-phased garbage collection:
+
+    #!/usr/bin/perl 
+    package Subtle;
+
+    sub new {
+       my $test;
+       $test = \$test;
+       warn "CREATING " . \$test;
+       return bless \$test;
+    } 
+
+    sub DESTROY {
+       my $self = shift;
+       warn "DESTROYING $self";
+    } 
+
+    package main;
+
+    warn "starting program";
+    {
+       my $a = Subtle->new;
+       my $b = Subtle->new;
+       $$a = 0;  # break selfref
+       warn "leaving block";
+    } 
+
+    warn "just exited block";
+    warn "time to die...";
+    exit;
+
+When run as F</tmp/test>, the following output is produced:
+
+    starting program at /tmp/test line 18.
+    CREATING SCALAR(0x8e5b8) at /tmp/test line 7.
+    CREATING SCALAR(0x8e57c) at /tmp/test line 7.
+    leaving block at /tmp/test line 23.
+    DESTROYING Subtle=SCALAR(0x8e5b8) at /tmp/test line 13.
+    just exited block at /tmp/test line 26.
+    time to die... at /tmp/test line 27.
+    DESTROYING Subtle=SCALAR(0x8e57c) during global destruction.
+
+Notice that "global destruction" bit there?  That's the thread
+garbage collector reaching the unreachable.  
+
+Objects are always destructed, even when regular refs aren't and in fact
+are destructed in a separate pass before ordinary refs just to try to
+prevent object destructors from using refs that have been themselves
+destructed.  Plain refs are only garbage collected if the destruct level
+is greater than 0.  You can test the higher levels of global destruction
+by setting the PERL_DESTRUCT_LEVEL environment variable, presuming
+C<-DDEBUGGING> was enabled during perl build time.
+
+A more complete garbage collection strategy will be implemented
+at a future date.
+
 =head1 SEE ALSO
 
-You should also check out L<perlbot> for other object tricks, traps, and tips.
+You should also check out L<perlbot> for other object tricks, traps, and tips, 
+as well as L<perlmod> for some style guides on constructing both modules
+and classes.
index 9e1e3f1..13655a7 100644 (file)
@@ -37,7 +37,7 @@ Perl easier for C folks.)
 
 In the following sections, these operators are covered in precedence order.
 
-=head1 DESCRIPTIONS
+=head1 DESCRIPTION
 
 =head2 Terms and List Operators (Leftward)
 
@@ -127,7 +127,9 @@ The autodecrement operator is not magical.
 =head2 Exponentiation
 
 Binary "**" is the exponentiation operator.  Note that it binds even more
-tightly than unary minus, so -2**4 is -(2**4), not (-2)**4.
+tightly than unary minus, so -2**4 is -(2**4), not (-2)**4. (This is
+implemented using C's pow(3) function, which actually works on doubles
+internally.)
 
 =head2 Symbolic Unary Operators
 
@@ -155,17 +157,17 @@ thing from interpretation.
 
 =head2 Binding Operators
 
-Binary "=~" binds an expression to a pattern match.
-Certain operations search or modify the string $_ by default.  This
-operator makes that kind of operation work on some other string.  The
-right argument is a search pattern, substitution, or translation.  The
-left argument is what is supposed to be searched, substituted, or
-translated instead of the default $_.  The return value indicates the
-success of the operation.  (If the right argument is an expression
-rather than a search pattern, substitution, or translation, it is
-interpreted as a search pattern at run time.  This is less efficient
-than an explicit search, since the pattern must be compiled every time
-the expression is evaluated--unless you've used C</o>.)
+Binary "=~" binds an expression to a pattern match.  Certain operations
+search or modify the string $_ by default.  This operator makes that kind
+of operation work on some other string.  The right argument is a search
+pattern, substitution, or translation.  The left argument is what is
+supposed to be searched, substituted, or translated instead of the default
+$_.  The return value indicates the success of the operation.  (If the
+right argument is an expression rather than a search pattern,
+substitution, or translation, it is interpreted as a search pattern at run
+time.  This is less efficient than an explicit search, since the pattern
+must be compiled every time the expression is evaluated--unless you've
+used C</o>.)
 
 Binary "!~" is just like "=~" except the return value is negated in
 the logical sense.
@@ -404,15 +406,24 @@ specified.
 Ternary "?:" is the conditional operator, just as in C.  It works much
 like an if-then-else.  If the argument before the ? is true, the
 argument before the : is returned, otherwise the argument after the :
-is returned.  Scalar or list context propagates downward into the 2nd
-or 3rd argument, whichever is selected.  The operator may be assigned
-to if both the 2nd and 3rd arguments are legal lvalues (meaning that you
-can assign to them):
+is returned.  For example:
+
+    printf "I have %d dog%s.\n", $n, 
+           ($n == 1) ? '' : "s";
+
+Scalar or list context propagates downward into the 2nd
+or 3rd argument, whichever is selected.  
+
+    $a = $ok ? $b : $c;  # get a scalar
+    @a = $ok ? @b : @c;  # get an array
+    $a = $ok ? @b : @c;  # oops, that's just a count!
+
+The operator may be assigned to if both the 2nd and 3rd arguments are
+legal lvalues (meaning that you can assign to them):
 
     ($a_or_b ? $a : $b) = $c;
 
-Note that this is not guaranteed to contribute to the readability of
-your program.
+This is not necessarily guaranteed to contribute to the readability of your program.
 
 =head2 Assignment Operators
 
@@ -464,7 +475,7 @@ In a list context, it's just the list argument separator, and inserts
 both its arguments into the list.
 
 The => digraph is mostly just a synonym for the comma operator.  It's useful for
-documenting arguments that come in pairs.  As of 5.001, it also forces
+documenting arguments that come in pairs.  As of release 5.001, it also forces
 any word to the left of it to be interpreted as a string.
 
 =head2 List Operators (Rightward)
@@ -543,7 +554,7 @@ the same character fore and aft, but the 4 sorts of brackets
                 s{}{}   Substitution      yes
                tr{}{}   Translation       no
 
-For constructs that do interpolation, variables beginning with "C<$> or "C<@>"
+For constructs that do interpolation, variables beginning with "C<$>" or "C<@>"
 are interpolated, as are the following sequences:
 
     \t         tab
@@ -575,6 +586,11 @@ particular, contrary to the expectations of shell programmers, backquotes
 do I<NOT> interpolate within double quotes, nor do single quotes impede
 evaluation of variables when used within double quotes.
 
+=head2 Regexp Quotelike Operators
+
+Here are the quotelike operators that apply to pattern
+matching and related activities.
+
 =over 8
 
 =item ?PATTERN?
@@ -912,7 +928,9 @@ of C<$?>).  Unlike in B<csh>, no translation is done on the return
 data--newlines remain newlines.  Unlike in any of the shells, single
 quotes do not hide variable names in the command from interpretation.
 To pass a $ through to the shell you need to hide it with a backslash.
-The generalized form of backticks is C<qx//>.
+The generalized form of backticks is C<qx//>.  (Because backticks
+always undergo shell expansion as well, see L<perlsec> for 
+security concerns.)
 
 Evaluating a filehandle in angle brackets yields the next line from
 that file (newline included, so it's never false until end of file, at
@@ -935,7 +953,7 @@ The filehandles STDIN, STDOUT and STDERR are predefined.  (The
 filehandles C<stdin>, C<stdout> and C<stderr> will also work except in
 packages, where they would be interpreted as local identifiers rather
 than global.)  Additional filehandles may be created with the open()
-function.
+function.  See L<perlfunc/open()> for details on this.
 
 If a <FILEHANDLE> is used in a context that is looking for a list, a
 list consisting of all the input lines is returned, one line per list
@@ -996,9 +1014,13 @@ haven't set @ARGV, will input from STDIN.
 
 If the string inside the angle brackets is a reference to a scalar
 variable (e.g. <$foo>), then that variable contains the name of the
-filehandle to input from.
+filehandle to input from, or a reference to the same.  For example:
+
+    $fh = \*STDIN;
+    $line = <$fh>;
 
-If the string inside angle brackets is not a filehandle, it is interpreted
+If the string inside angle brackets is not a filehandle or a scalar
+variable containing a filehandle name or reference, then it is interpreted
 as a filename pattern to be globbed, and either a list of filenames or the
 next filename in the list is returned, depending on context.  One level of
 $ interpretation is done first, but you can't say C<E<lt>$fooE<gt>>
index cdb3ba6..1bad322 100644 (file)
@@ -1,355 +1,8 @@
-=head1 NAME 
+=head1 NAME
 
-perlovl - perl overloading semantics
+perlovl - overload perl mathematical functions [superseded]
 
-=head1 SYNOPSIS
+=head1
 
-    package SomeThing;
+This man page has been superseded by L<overload>.
 
-    %OVERLOAD = (
-       '+' => \&myadd,
-       '-' => \&mysub,
-       # etc
-    );
-    ...
-
-    package main;
-    $a = new SomeThing 57;
-    $b=5+$a;
-
-=head1 CAVEAT SCRIPTOR
-
-Overloading of operators is a subject not to be taken lightly.
-Neither its precise implementation, syntax, nor semantics are
-100% endorsed by Larry Wall.  So any of these may be changed 
-at some point in the future.
-
-=head1 DESCRIPTION
-
-=head2 Declaration of overloaded functions
-
-    package Number;
-    %OVERLOAD = ( 
-       "+" => \&add, 
-       "*=" => "muas"
-    );
-
-declares function Number::add() for addition, and method muas() in
-the "class" C<Number> (or one of its base classes)
-for the assignment form C<*=> of multiplication.  Legal values of this
-hash array are values legal inside C<&{ ... }> call, so the name of a
-subroutine, a reference to a subroutine, or an anonymous subroutine 
-will all work.
-
-The subroutine C<$OVERLOAD{"+"}> will be called to execute C<$a+$b> if $a
-is a reference to an object blessed into the package C<Number>, or $a is
-not an object from a package with defined mathemagic addition, but $b is a
-reference to a C<Number>.  It can be called also in other situations, like
-C<$a+=7>, or C<$a++>.  See L<MAGIC AUTOGENERATION>.  (Mathemagical
-methods refer to methods triggered by an overloaded mathematical
-operator.)
-
-=head2 Calling Conventions for Binary Operations
-
-The functions in C<values %OVERLOAD> are called with three (in one
-particular case with four, see L<Last Resort>) arguments.  If the
-corresponding operation is binary, then the first two arguments are the
-two arguments of the operation.  However, due to general object calling
-conventions, the first argument should be always an object in the package,
-so in the situation of C<7+$a>, the order of arguments is interchanged.
-Most probably it does not matter for implementation of the addition
-method, but whether the arguments are reversed is vital for the
-subtraction method.  The subroutine can query this information by
-examining the third argument, which can take three different values:
-
-=over 7
-
-=item FALSE
-
-the order of arguments is as in the current operation.
-
-=item TRUE
-
-the arguments are reversed.
-
-=item C<undef>
-
-the current operation is an assignment variant (as in
-C<$a+=7>), but the usual function is called instead.  This additional
-information can be used to generate some optimizations.
-
-=back
-
-=head2 Calling Conventions for Unary Operations
-
-Unary operation are considered binary operations with the second
-argument being C<undef>.  Thus C<$OVERLOAD{"++"}> is called with
-arguments C<($a,undef,'')> when $a++ is executed.
-
-=head2 Overloadable Operations
-
-The following keys of %OVERLOAD are recognized:
-
-=over 5
-
-=item * I<Arithmetic operations>
-
-    "+", "+=", "-", "-=", "*", "*=", "/", "/=", "%", "%=",
-    "**", "**=", "<<", "<<=", ">>", ">>=", "x", "x=", ".", ".=",
-
-For these operations a substituted non-assignment variant can be called if
-the assignment variant is not available.  Methods for operations "C<+>",
-"C<->", "C<+=>", and "C<-=>" can be called to automatically generate
-increment and decrement methods.  The operations "C<->" can be used to
-autogenerate missing methods for unary minus or C<abs>.
-
-=item * I<Comparison operations>
-
-    "<",  "<=", ">",  ">=", "==", "!=", "<=>",
-    "lt", "le", "gt", "ge", "eq", "ne", "cmp",
-
-If the corresponding "spaceship" variant is available, it can be
-used to substitute for the missing operation.  During C<sort>ing
-arrays, C<cmp> is used to compare values subject to %OVERLOAD.
-
-=item * I<Bit operations>
-
-    "&", "^", "|", "&=", "^=", "|=", "neg", "!", "~",
-
-"C<neg>" stands for unary minus.  If the method for C<neg> is not
-specified, it can be autogenerated using on the method for subtraction.
-
-=item * I<Increment and decrement>
-
-    "++", "--",
-
-If undefined, addition and subtraction methods can be
-used instead.  These operations are called both in prefix and
-postfix form.
-
-=item * I<Transcendental functions>
-
-    "atan2", "cos", "sin", "exp", "abs", "log", "sqrt",
-
-If C<abs> is unavailable, it can be autogenerated using methods
-for "<" or "<=>" combined with either unary minus or subtraction.
-
-=item * I<Boolean, string and numeric conversion>
-
-    "bool", "\"\"", "0+",
-
-If one or two of these operations are unavailable, the remaining ones can
-be used instead.  C<bool> is used in the flow control operators
-(like C<while>) and for the ternary "C<?:>" operation.  These functions can
-return any arbitrary Perl value.  If the corresponding operation for this value
-is overloaded too, that operation will be called again with this value.
-
-=item * I<Special>
-
-    "nomethod", "fallback", "=",
-
-see L<SPECIAL KEYS OF %OVERLOAD>.
-
-=back
-
-See L<"Fallback"> for an explanation of when a missing method can be autogenerated.
-
-=head1 SPECIAL KEYS OF %OVERLOAD
-
-Three keys are recognized by Perl that are not covered by the above
-description.
-
-=head2  Last Resort
-
-C<$OVERLOAD{"nomethod"}> is a reference to a function of four parameters.
-If defined, it is called when the overloading mechanism cannot find a
-method for some operation.  The first three arguments of this function
-coincide with arguments for the corresponding method if it were found, the
-fourth argument is the key of %OVERLOAD corresponding to the missing
-method.  If several methods are tried, the last one is used.  Say, C<1-$a>
-can be equivalent to
-
-       &{ $Pack::OVERLOAD{"nomethod"} }($a,1,1,"-").
-
-If some operation cannot be resolved, and there is no
-C<$OVERLOAD{"nomethod"}>, then an exception will be raised 
-via die() -- unless C<$OVERLOAD{"fallback"}> is true. 
-
-=head2 Fallback 
-
-C<$OVERLOAD{"fallback"}> governs what to do if a method for a particular
-operation is not found.  Three different cases are possible depending on
-value of C<$OVERLOAD{"fallback"}>:
-
-=over 16
-
-=item * C<undef>
-
-Perl tries to use a
-substituted method (see L<MAGIC AUTOGENERATION>).  If this fails, it
-then tries to calls C<$OVERLOAD{"nomethod"}>; if missing, an exception
-will be raised.
-
-=item * TRUE
-
-The same as for the C<undef> value, but no exception is raised.  Instead,
-it silently reverts to what it would have done were there no %OVERLOAD is
-present.
-
-=item * defined, but FALSE
-
-No autogeneration is tried.  Perl tries to call
-C<$OVERLOAD{"nomethod"}>, and if this is missing, raises an exception. 
-
-=back
-
-=head2 Copy Constructor
-
-C<$OVERLOAD{"="}> is a reference to a function with three arguments,
-i.e., it looks like a usual value of %OVERLOAD.  This operation
-is called in the situations when a mutator is applied to a reference
-that shares its object with some other reference, such as
-
-       $a=$b; 
-       $a++;
-
-To make this change to $a and not to change $b, a freshly made copy of
-C<$$a> is made, and $a is assigned a reference to this object.  This
-operation is executed during C<$a++>, (so before this C<$$a> coincides
-with C<$$b>), and only if C<++> is expressed via  C<$OPERATOR{'++'}> or
-C<$OPERATOR{'+='}>.  Note that if this operation is expressed via 'C<+>',
-i.e., as
-
-       $a=$b; 
-       $a=$a+1;
-
-then C<$$a> and C<$$b> do not appear as lvalues.
-
-If the copy constructor is required during execution of some mutator, but
-C<$OPERATOR{'='}> is missing, it can be autogenerated as a string
-copy if an object of
-the package is a plain scal