From: Andy Dougherty Date: Thu, 21 Dec 1995 00:01:16 +0000 (+0000) Subject: This is patch.2b1g to perl5.002beta1. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=cb1a09d0194fed9b905df7b04a4bc031d354609d;p=p5sagit%2Fp5-mst-13.2.git This is patch.2b1g to perl5.002beta1. 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 --- diff --git a/MANIFEST b/MANIFEST index 69370b5..45541d5 100644 --- 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 diff --git a/ext/DB_File/DB_File.pm b/ext/DB_File/DB_File.pm index 55e5e9f..08463df 100644 --- a/ext/DB_File/DB_File.pm +++ b/ext/DB_File/DB_File.pm @@ -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 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 is opening a database file it no longer terminates the process if I returned an error. This allows file protection errors to be caught at run time. Thanks to Judith Grass - for spotting the bug. +Egrass@cybercash.comE 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 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 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 in the -directory C. It is I under the GPL. +Berkeley DB is available at your nearest CPAN archive (see +L for a list) in F, or via the +host F in F. It is I under +the GPL. =head1 SEE ALSO diff --git a/ext/POSIX/POSIX.pm b/ext/POSIX/POSIX.pm index 2c397bb..ee35ea2 100644 --- a/ext/POSIX/POSIX.pm +++ b/ext/POSIX/POSIX.pm @@ -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 { diff --git a/ext/POSIX/POSIX.pod b/ext/POSIX/POSIX.pod index 654028e..2549a61 100644 --- a/ext/POSIX/POSIX.pod +++ b/ext/POSIX/POSIX.pod @@ -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. =item assert +Unimplemented. =item atan @@ -158,6 +163,11 @@ This is identical to the C function C. =item close +Close the file. This uses file descriptors such as those obtained by calling +C. + + $fd = POSIX::open( "foo", &POSIX::O_RDONLY ); + POSIX::close( $fd ); Returns C on failure. @@ -175,10 +185,15 @@ This is identical to the C function C. =item creat +Create a new file. This returns a file descriptor like the ones returned by +C. Use C 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. + +This uses file descriptors such as those obtained by calling +C. Returns C on failure. =item dup2 +This is similar to the C function C. + +This uses file descriptors such as those obtained by calling +C. Returns C on failure. @@ -310,6 +333,14 @@ This is identical to Perl's builtin C 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. + +The following will determine the maximum length of the longest allowable +pathname on the filesystem which holds C. + + $fd = POSIX::open( "/tmp/foo", &POSIX::O_RDONLY ); + $path_max = POSIX::fpathconf( $fd, &POSIX::_PC_PATH_MAX ); Returns C 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 instead. =item fstat +Get file status. This uses file descriptors such as those obtained by +calling C. The data returned is identical to the data from +Perl's builtin C 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 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 function. =item localeconv +Get numeric formatting information. Returns a reference to a hash +containing the current locale formatting values. + +The database for the B (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. + + $fd = POSIX::open( "foo", &POSIX::O_RDONLY ); + $off_t = POSIX::lseek( $fd, 0, &POSIX::SEEK_SET ); Returns C on failure. @@ -527,12 +620,15 @@ malloc() is C-specific. =item mblen +This is identical to the C function C. =item mbstowcs +This is identical to the C function C. =item mbtowc +This is identical to the C function C. =item memchr @@ -560,19 +656,40 @@ This is identical to Perl's builtin C function. =item mkfifo +This is similar to the C function C. Returns C 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), weekday (C), and yearday (C) begin at zero. +I.e. January is 0, not 1; Sunday is 0, not 1; January 1st is 0, not 1. The +year (C) is given in years since 1900. I.e. The year 1995 is 95; the +year 2001 is 101. Consult your system's C 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 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. Returns C 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 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 on failure. =item opendir +Open a directory for reading. + + $dir = POSIX::opendir( "/tmp" ); + @files = POSIX::readdir( $dir ); + POSIX::closedir( $dir ); + +Returns C on failure. =item pathconf @@ -611,6 +753,12 @@ This is identical to the C function C. =item pipe +Create an interprocess channel. This returns file descriptors like those +returned by C. + + ($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. 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 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. Returns C on failure. @@ -714,6 +869,13 @@ Sets the real user id for this process. =item sigaction +Detailed signal management. This uses C objects for the +C and C arguments. Consult your system's C +manpage for details. + +Synopsis: + + sigaction(sig, action, oldaction = 0) Returns C 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 +objects for the C argument. Consult your system's C +manpage for details. + +Synopsis: + + sigpending(sigset) Returns C on failure. =item sigprocmask +Change and/or examine calling process's signal mask. This uses +C objects for the C and C arguments. +Consult your system's C manpage for details. + +Synopsis: + + sigprocmask(how, sigset, oldsigset = 0) Returns C 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 objects for the C argument. Consult your +system's C manpage for details. + +Synopsis: + + sigsuspend(signal_mask) Returns C on failure. @@ -754,6 +937,7 @@ This is identical to Perl's builtin C function. =item sprintf +This is identical to Perl's builtin C 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), weekday (C), and yearday (C) begin at zero. +I.e. January is 0, not 1; Sunday is 0, not 1; January 1st is 0, not 1. The +year (C) is given in years since 1900. I.e. The year 1995 is 95; the +year 2001 is 101. Consult your system's C 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. =item tcdrain +This is similar to the C function C. Returns C on failure. =item tcflow +This is similar to the C function C. Returns C on failure. =item tcflush +This is similar to the C function C. Returns C on failure. @@ -896,11 +1102,13 @@ This is identical to the C function C. =item tcsendbreak +This is similar to the C function C. Returns C on failure. =item tcsetpgrp +This is similar to the C function C. Returns C on failure. @@ -940,9 +1148,14 @@ This is identical to Perl's builtin C function. =item ttyname +This is identical to the C function C. =item tzname +Retrieves the time conversion information from the C variable. + + POSIX::tzset(); + ($std, $dst) = POSIX::tzname(); =item tzset @@ -954,6 +1167,9 @@ This is identical to Perl's builtin C 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 function. =item waitpid +Wait for a child process to change state. This is identical to Perl's +builtin C function. + + $pid = POSIX::waitpid( -1, &POSIX::WNOHANG ); + print "status = ", ($? / 256), "\n"; =item wcstombs +This is identical to the C function C. =item wctomb +This is identical to the C function C. =item write +Write to a file. This uses file descriptors such as those obtained by +calling C. + + $fd = POSIX::open( "foo", &POSIX::O_WRONLY ); + $buf = "hello"; + $bytes = POSIX::write( $b, $buf, 5 ); Returns C on failure. @@ -1006,50 +1236,119 @@ Returns C 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 for append, C for write, and E 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 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 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. + + $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. +The second parameter, the mode, should be C for append, C for write, +and E 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 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 on failure. @@ -1060,6 +1359,9 @@ Returns C on failure. =item tell +Returns the current file position, in bytes. + + $pos = $fh->tell; =item ungetc @@ -1072,8 +1374,17 @@ Returns C 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 object which corresponds to the C +C. 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 +object. The third parameter contains the C. + + $sigset = POSIX::SigSet->new; + $sigaction = POSIX::SigAction->new( 'main::handler', $sigset, &POSIX::SA_NOCLDSTOP ); + +This C object should be used with the C +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 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 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 index 0000000..414df14 --- /dev/null +++ b/ext/Safe/Makefile.PL @@ -0,0 +1,2 @@ +use ExtUtils::MakeMaker; +WriteMakefile(); diff --git a/ext/Safe/Safe.pm b/ext/Safe/Safe.pm new file mode 100644 index 0000000..dc2f9e9 --- /dev/null +++ b/ext/Safe/Safe.pm @@ -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, I, +I, and I but does not mask off operators such as +I, I and IHANDLE>. 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 of the string indicates that operator number +B should be masked (i.e. disallowed). The Safe extension makes +available routines for converting from operator names to operator +numbers (and I) and for converting from a list of operator +names to the corresponding mask (and I). + +=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 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 of a variable without +any leading type marker. For example, + + $cpt = new Safe 'Root'; + $Root::foo = "Hello world"; + # Equivalent version which doesn't need to know $cpt's package name: + ${$cpt->varglob('foo')} = "Hello world"; + + +=item reval (STRING) + +This evaluates STRING as perl code inside the compartment. The code +can only see the compartment's namespace (as returned by the B +method). 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. 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 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 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 index 0000000..4437284 --- /dev/null +++ b/ext/Safe/Safe.xs @@ -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 diff --git a/ext/Socket/Socket.pm b/ext/Socket/Socket.pm index 7f0943b..6462713 100644 --- a/ext/Socket/Socket.pm +++ b/ext/Socket/Socket.pm @@ -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 diff --git a/installman b/installman index bc36ca6..aab0c22 100755 --- a/installman +++ b/installman @@ -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 { diff --git a/lib/AutoSplit.pm b/lib/AutoSplit.pm index 46cf689..fd537bb 100644 --- a/lib/AutoSplit.pm +++ b/lib/AutoSplit.pm @@ -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 diff --git a/lib/Cwd.pm b/lib/Cwd.pm index 2636fd2..a627354 100644 --- a/lib/Cwd.pm +++ b/lib/Cwd.pm @@ -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. diff --git a/lib/Devel/SelfStubber.pm b/lib/Devel/SelfStubber.pm index 1b5e575..0a8caad 100644 --- a/lib/Devel/SelfStubber.pm +++ b/lib/Devel/SelfStubber.pm @@ -60,6 +60,7 @@ sub stub { 1; __END__ + =head1 NAME Devel::SelfStubber - generate stubs for a SelfLoading module diff --git a/lib/Env.pm b/lib/Env.pm index 2187090..0e79075 100644 --- a/lib/Env.pm +++ b/lib/Env.pm @@ -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 diff --git a/lib/Exporter.pm b/lib/Exporter.pm index 8c4368c..382ee85 100644 --- a/lib/Exporter.pm +++ b/lib/Exporter.pm @@ -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 diff --git a/lib/ExtUtils/Liblist.pm b/lib/ExtUtils/Liblist.pm index 53eb032..ebb2536 100644 --- a/lib/ExtUtils/Liblist.pm +++ b/lib/ExtUtils/Liblist.pm @@ -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 diff --git a/lib/ExtUtils/MakeMaker.pm b/lib/ExtUtils/MakeMaker.pm index 5de54c6..6aae816 100644 --- a/lib/ExtUtils/MakeMaker.pm +++ b/lib/ExtUtils/MakeMaker.pm @@ -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 = ) { - 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 = ) { + 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 <{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 diff --git a/lib/ExtUtils/Manifest.pm b/lib/ExtUtils/Manifest.pm index 1c54c77..4d18cbe 100644 --- a/lib/ExtUtils/Manifest.pm +++ b/lib/ExtUtils/Manifest.pm @@ -27,7 +27,8 @@ C =head1 DESCRIPTION Mkmanifest() writes all files in and below the current directory to a -file named C in the current directory. It works similar to +file named in the global variable $ExtUtils::Manifest::MANIFEST (which +defaults to C) 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. Changing it +results in both a different C and a different +C 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. @@ -117,6 +129,10 @@ to MANIFEST. $Verbose is set to 1 by default. =back +=head1 SEE ALSO + +L which has handy targets for most of the functionality. + =head1 AUTHOR Andreas Koenig Fkoenig@franz.ww.TU-Berlin.DEE> @@ -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; diff --git a/lib/ExtUtils/Mkbootstrap.pm b/lib/ExtUtils/Mkbootstrap.pm index a074bb1..5710985 100644 --- a/lib/ExtUtils/Mkbootstrap.pm +++ b/lib/ExtUtils/Mkbootstrap.pm @@ -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 + +=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 Cs, 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 diff --git a/lib/FileHandle.pm b/lib/FileHandle.pm index 9408717..cbc6efb 100644 --- a/lib/FileHandle.pm +++ b/lib/FileHandle.pm @@ -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 for complete descriptions of each of the following supported C 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. + +=item $fh->printf + +See L. + +=item $fh->getline + +This works like <$fh> described in L except that it's more readable +and can be safely called in an array context but still +returns just one line. + +=item $fh->getlines + +This works like <$fh> when called in an array context to +read all the remaining lines in a file, except that it's more readable. +It will also croak() if accidentally called in a scalar context. + +=back + +=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, +L, +L + =head1 BUGS F lies with its C 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, 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 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; diff --git a/lib/IPC/Open2.pm b/lib/IPC/Open2.pm index 71f89f3..1ac963a 100644 --- a/lib/IPC/Open2.pm +++ b/lib/IPC/Open2.pm @@ -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 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; diff --git a/lib/IPC/Open3.pm b/lib/IPC/Open3.pm index db8652e..5bc757c 100644 --- a/lib/IPC/Open3.pm +++ b/lib/IPC/Open3.pm @@ -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 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; diff --git a/lib/SelfLoader.pm b/lib/SelfLoader.pm index 017d204..e3da9eb 100644 --- a/lib/SelfLoader.pm +++ b/lib/SelfLoader.pm @@ -100,6 +100,7 @@ sub _package_defined {} 1; __END__ + =head1 NAME SelfLoader - load functions only on demand diff --git a/lib/Sys/Hostname.pm b/lib/Sys/Hostname.pm index 4dd4fe2..91c62b6 100644 --- a/lib/Sys/Hostname.pm +++ b/lib/Sys/Hostname.pm @@ -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, +C<`hostname`>, C<`uname -n`>, and the file F. +If all that fails it Cs. + +All nulls, returns, and newlines are removed from the result. + +=head1 AUTHOR + +David Sundstrom + +Texas Instruments + +=cut sub hostname { diff --git a/lib/Sys/Syslog.pm b/lib/Sys/Syslog.pm index 671da9f..bd8f07c 100644 --- a/lib/Sys/Syslog.pm +++ b/lib/Sys/Syslog.pm @@ -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; } diff --git a/lib/Term/Cap.pm b/lib/Term/Cap.pm index 061ca70..5e900c3 100644 --- a/lib/Term/Cap.pm +++ b/lib/Term/Cap.pm @@ -1,138 +1,250 @@ -# Term::Cap.pm -- Termcap interface routines package Term::Cap; +use Carp; -# Converted to package on 25 Feb 1994 -# -# 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 function extracts the entry of the specified terminal +type I (defaults to the environment variable I) from the +database. + +It will look in the environment for a I 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, the +I 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 does not begin with a +slash and name is different from I, B searches the +files F<$HOME/.termcap>, F, and F, +in that order, unless the environment variable I exists, +in which case it specifies a list of file pathnames (separated by +spaces or colons) to be searched B. 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 +environment variable string it will continue the search in the +files as above. + +I is the terminal output bit rate (often mistakenly called +the baud rate). I 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 returns a blessed object reference which the user can +then use to send the control strings to the terminal using B +and B. It calls C on failure. + +B decodes a cursor addressing string with the given parameters. + +The output strings for B are cached for counts of 1 for performance. +B and B do not cache. C<$self-E{_xx}> is the raw termcap +data and C<$self-E{xx}> is the cached version. + + print $terminal->Tpad($self->{_xx}, 1); + +B, B, and B 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{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 ($_ = ) { + next if /^\\t/ || /^#/; + if ($_ =~ m/(^|\\|)${termpat}[:|]/o) { + chomp; + s/^[^:]*:// if $first++; + $state = 0; + while ($_ =~ s/\\\\$//) { $_ .= ; chomp; } + last; } + } + $entry .= $_; + }; - open(TERMCAP,"< $TERMCAP\0") || die "Tgetent: $TERMCAP: $!\n"; - # print STDERR "Trying... $TERMCAP\n"; - $loop = " - while () { - next if /^\t/; - next if /^#/; - if (/(^|\\|)${TERM}[:\\|]/) { - chop; - s/^[^:]*:// unless \$first++; - \$state = 0; - while (chop eq '\\\\') { - \$_ .= ; - 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; + diff --git a/lib/Term/Complete.pm b/lib/Term/Complete.pm index 97c71fe..6faef22 100644 --- a/lib/Term/Complete.pm +++ b/lib/Term/Complete.pm @@ -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 and restored using C. + +The following command characters are defined: + +=over 4 + +=item +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 , + +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 cannot be changed. + +=head1 AUTHOR + +Wayne Thompson + +=cut CONFIG: { $complete = "\004"; diff --git a/lib/Test/Harness.pm b/lib/Test/Harness.pm index 635febd..99e06f7 100644 --- a/lib/Test/Harness.pm +++ b/lib/Test/Harness.pm @@ -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 is an increasing sequence of integers. The first line +output by a standard test scxript is C<"1..M"> with C being the +number of tests that should be run within the test +script. Test::Harness::runscripts(@tests) runs all the testscripts +named as arguments and checks standard output for the expected +C<"ok N"> strings. + +After all tests have been performed, runscripts() prints some +performance statistics that are computed by the Benchmark module. + +=head1 EXPORT + +C<&runscripts> is exported by Test::Harness per default. + +=head1 DIAGNOSTICS + +=over 4 + +=item C + +If all tests are successful some statistics about the performance are +printed. + +=item C + +=item C + +If not all tests were successful, the script dies with one of the +above messages. + +=back + +=head1 SEE ALSO + +See L 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 diff --git a/lib/Text/Soundex.pm b/lib/Text/Soundex.pm index 6551523..a334404 100644 --- a/lib/Text/Soundex.pm +++ b/lib/Text/Soundex.pm @@ -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 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, but +many people seem to prefer an I value like C +(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 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 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 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 and C end up with a soundex code +of C. + +=head1 AUTHOR + +This code was implemented by Mike Stok (C) from the +description given by Knuth. Ian Phillips (C) and Rich Pinder +(C) supplied ideas and spotted mistakes. diff --git a/lib/Text/Tabs.pm b/lib/Text/Tabs.pm index 7cfb478..2481d81 100644 --- a/lib/Text/Tabs.pm +++ b/lib/Text/Tabs.pm @@ -10,6 +10,35 @@ # Version: 9/21/95 # +=head1 NAME + +Text::Tabs -- expand and unexpand tabs + +=head1 SYNOPSIS + + use Text::Tabs; + + #$tabstop = 8; # Defaults + print expand("Hello\tworld"); + print unexpand("Hello, world"); + $tabstop = 4; + print join("\n",expand(split(/\n/, + "Hello\tworld,\nit's a nice day.\n" + ))); + +=head1 DESCRIPTION + +This module expands and unexpands tabs into spaces, as per the unix expand +and unexpand programs. Either function should be passed an array of strings +(newlines may I be included, and should be used to split an incoming +string into separate elements.) which will be processed and returned. + +=head1 AUTHOR + +David Muir Sharnoff + +=cut + package Text::Tabs; require Exporter; diff --git a/lib/Text/Wrap.pm b/lib/Text/Wrap.pm index 9b1d054..b665752 100644 --- a/lib/Text/Wrap.pm +++ b/lib/Text/Wrap.pm @@ -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 + +=cut + require Exporter; @ISA = (Exporter); diff --git a/lib/TieHash.pm b/lib/TieHash.pm index 446cbcb..161771a 100644 --- a/lib/TieHash.pm +++ b/lib/TieHash.pm @@ -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 for a list of the functions required in order to tie a hash +to a package. The basic B package provides a C method, as well +as methods C, C and C. The B package +provides most methods required for hashes in L. It inherits from +B, and causes tied hashes to behave exactly like standard hashes, +allowing for selective overloading of methods. The B method is provided +as grandfathering in the case a class forgets to include a B 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. Associates a new +hash instance with the specified class. C would represent additional +arguments (along the lines of L and compatriots) needed to +complete the association. + +=item STORE this, key, value + +Store datum I into I for the tied hash I. + +=item FETCH this, key + +Retrieve the datum in I for the tied hash I. + +=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 exists with the tied hash I. + +=item DELETE this, key + +Delete the key I from the tied hash I. + +=item CLEAR this + +Clear all values from the tied hash I. + +=back + +=head1 CAVEATS + +The L documentation includes a method called C as +a necessary method for tied hashes. Neither B nor B +define a default for this method. + +The C method provided by these two packages is not listed in the +L section. + +=head1 MORE INFORMATION + +The packages relating to various DBM-related implemetations (F, +F, etc.) show examples of general tied hashes, as does the +L module. While these do not utilize B, they serve as +good working examples. + +=cut + use Carp; sub new { diff --git a/lib/Time/Local.pm b/lib/Time/Local.pm index 64e6240..451c7fa 100644 --- a/lib/Time/Local.pm +++ b/lib/Time/Local.pm @@ -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 diff --git a/lib/less.pm b/lib/less.pm index 5e055f3..b3afef0 100644 --- a/lib/less.pm +++ b/lib/less.pm @@ -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 diff --git a/lib/overload.pm b/lib/overload.pm index 3c9562a..54d2cbb 100644 --- a/lib/overload.pm +++ b/lib/overload.pm @@ -62,7 +62,7 @@ __END__ =head1 NAME -C - Package for overloading perl operations +overload - Package for overloading perl operations =head1 SYNOPSIS diff --git a/lib/strict.pm b/lib/strict.pm index d35c6c1..6f6028c 100644 --- a/lib/strict.pm +++ b/lib/strict.pm @@ -53,13 +53,17 @@ name without fully qualifying it. =item C -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 diff --git a/lib/syslog.pl b/lib/syslog.pl index a3b9edf..2034e0a 100644 --- a/lib/syslog.pl +++ b/lib/syslog.pl @@ -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 --- 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", diff --git a/pod/Makefile b/pod/Makefile index 38d5b0f..9cf48eb 100644 --- a/pod/Makefile +++ b/pod/Makefile @@ -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 index 0000000..24248e3 --- /dev/null +++ b/pod/PerlDoc/Functions.pm @@ -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 () { + 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 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 index 0000000..5e2b435 --- /dev/null +++ b/pod/PerlDoc/Functions.pm.POSIX @@ -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 index 0000000..77ddcd0 --- /dev/null +++ b/pod/buildtoc @@ -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; + +($_= < 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 = ) { + 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; + } +} + +($_= <E, 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"; +} diff --git a/pod/perl.pod b/pod/perl.pod index f0504c4..5f3918c 100644 --- a/pod/perl.pod +++ b/pod/perl.pod @@ -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. +See the perl bugs database at F. 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. Perl actually stands for Pathologically Eclectic Rubbish Lister, but don't tell anyone I said that. diff --git a/pod/perlbot.pod b/pod/perlbot.pod index 61a3726..72c1870 100644 --- a/pod/perlbot.pod +++ b/pod/perlbot.pod @@ -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 diff --git a/pod/perldata.pod b/pod/perldata.pod index 648f092..9b3798f 100644 --- a/pod/perldata.pod +++ b/pod/perldata.pod @@ -1,6 +1,6 @@ =head1 NAME -perldata - Perl data structures +perldata - Perl data types =head1 DESCRIPTION @@ -60,8 +60,8 @@ of this, see L. 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: @@ -147,6 +147,18 @@ numbers count as 0, just as the do in I: warn "That doesn't look like a number"; } +That's usually preferable because otherwise you won't treat IEEE notations +like C or C properly. At other times you might prefer to +use a regular expression to check whether data is numeric. See L +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. (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 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 for examples +of how to arrange for an output ordering. + +=head2 Typeglobs and FileHandles + +Perl uses an internal type called a I 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, L, and L for more +discussion on typeglobs. See L for other ways of +generating filehandles. diff --git a/pod/perldiag.pod b/pod/perldiag.pod index ad4a532..83a30c3 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -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 succeeds. +=item %s: Command not found. + +(A) You've accidentally run your script through B 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 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 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 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. =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 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 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 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 diff --git a/pod/perldsc.pod b/pod/perldsc.pod index 1d51af8..258e9ab 100644 --- a/pod/perldsc.pod +++ b/pod/perldsc.pod @@ -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 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, L, L, L =head1 AUTHOR Tom Christiansen EFE Last update: -Sat Oct 7 22:41:09 MDT 1995 +Tue Dec 12 09:20:26 MST 1995 diff --git a/pod/perlembed.pod b/pod/perlembed.pod index 5ac5a9e..2f0e9c3 100644 --- a/pod/perlembed.pod +++ b/pod/perlembed.pod @@ -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 + +Read L and L. + +=item B + +Read about backquotes and L and L. + +=item B + +Read about L and L and L +and L. + +=item B + +Rethink your design. + +=item B + +Read on... + +=back + +=head2 ROADMAP + +L + +There's one example in each of the five sections: + +L + +L + +L + +L + +L + +This documentation is UNIX specific. + +=head2 Compiling your C program + +Every C program that uses Perl must link in the I. + +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 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 directory.) + +Your C program will--usually--allocate, "run", and deallocate a +I 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 and +I, 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, +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, I, et al.) and +library directory (I) 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 or I, 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, +from the source distribution. Here's a bastardized, non-portable version of +I containing the essentials of embedding: + + #include + #include /* from the Perl distribution */ + #include /* 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) 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 just +like perl itself: + + % interp + print "Pretty Good Perl \n"; + print "10890 - 9801 is ", 10890 - 9801; + + 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 before +calling I. + +=head2 Calling a Perl subroutine from your C program + +To call individual Perl subroutines, you'll need to remove the call to +I and replace it with a call to I. + +That's shown below, in a program I'll call I. + + #include + #include + #include + + 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 is a Perl subroutine that takes no arguments (that's the +I) and for which I'll ignore the return value (that's the +I). Those flags, and others, are discussed in L. + +I'll define the I subroutine in a file called I: + + 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 + +=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). +Look for updates to this document soon. + +One way to evaluate a Perl string is to define a function (we'll call +ours I) that wraps around Perl's L. + +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 or L to include external Perl +files. + +Our I lets us evaluate individual Perl strings, and then +extract variables for coercion into C types. The following program, +I, executes three Perl strings, extracting an C from +the first, a C from the second, and a C from the third. + + #include + #include + #include + + 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 in their names help convert Perl scalars to C types. They're described in L. + +If you compile and run I, you'll see the results of using +I to create an C, I to create a C, and +I 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 lets us evaluate strings of Perl code, so we can +define some functions that use it to "specialize" in matches and +substitutions: I, I, and I. + + 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 with the array elements (allocating memory as it does so), +returning the number of matches found. + +Here's a sample program, I, that uses all three: + + #include + #include + #include + + 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. + +Then you'll need to know how to manipulate the Perl stack. That's +described in L. + +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 function). First +I'll create a stub exponentiation function in I: + + sub expo { + my ($a, $b) = @_; + return $a ** $b; + } + +Now I'll create a C program, I, with a function +I that contains all the perlguts necessary to push the +two arguments into I and to pop the return value out. Take a +deep breath... + + #include + #include + #include + + 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 in C, but +you can always I in Perl. Since you can use +each from the other, combine them as you wish. + + +=head1 AUTHOR + +Jon Orwant Forwant@media.mit.eduE>, 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, +Waite Group Press, 1996 (ISBN 1-57169-064-6) and appears +courtesy of Waite Group Press. + diff --git a/pod/perlform.pod b/pod/perlform.pod index c4bb78c..3e5dd78 100644 --- a/pod/perlform.pod +++ b/pod/perlform.pod @@ -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 for other issues. diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod index 2cc480c..6104eb5 100644 --- a/pod/perlfunc.pod +++ b/pod/perlfunc.pod @@ -54,9 +54,9 @@ null list. Remember the following rule: -=over 5 +=over 8 -=item * +=item I @@ -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. =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. 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. +=item continue BLOCK + +Actually a flow control statement rather than a function. If there is a +C BLOCK attached to a BLOCK (typically in a C or +C), it is always executed just before the conditional is about to +be evaluated again, just like the third part of a C loop in C. Thus +it can be used to increment a loop variable, even when the loop has been +continued via the C statement (which is similar to the C C +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 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 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 for many other interesting possibilities. +See also L for a more general description of the pros and +cons of the various dbm apparoches, as well as L 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 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 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 for other flock() examples. =item fork @@ -881,6 +1015,26 @@ fork() returns omitted); } waitpid($pid,0); +See also L 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 for many details and examples. + =item formline PICTURE, LIST @@ -908,14 +1062,13 @@ formline() always returns TRUE. See L 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 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 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 module from your nearest CPAN site; +details on CPAN can be found on L =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 -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 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. 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, '+/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 +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 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 lexical variables created with my(). Typically it +would be the first declaration in a file to be included by the C +or C 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
+package as assumed. That is, C<$::sail> is equivalent to C<$main::sail>. + +See L for more information about packages, modules, +and classes. See L 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. =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. 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 clear the end-of-file condition on the handle, so that the next +CFILE> 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); $_ = ; $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: Do not attempt to mix buffered I/O (like read() or ) +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 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 declare $a +and $b as lexicals. They are package globals. That means +if you're in the C
package, it's + + @articles = sort {$main::b <=> $main::a} @files; + +or just + + @articles = sort {$::b <=> $::a} @files; + +but if you're in the C 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, and L.) =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 or L 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 operator. If EXPR is -omitted, does C. 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 operator. If EXPR is omitted, +does C. Many folks use an explicit C +instead. Of course, you'd need something much more random than that for +cryptographic purposes, since it's easy to guess the current time. +Checksumming the compressed output of rapidly changing operating system +status programs is the usual method. Examples are posted regularly to +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. 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 and +L 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. +256. See also L. This is I what you want to use to capture +the output from a command, for that you should merely use backticks, as +described in L. =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. + +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: diff --git a/pod/perlguts.pod b/pod/perlguts.pod index b836a73..5e8f077 100644 --- a/pod/perlguts.pod +++ b/pod/perlguts.pod @@ -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 or C, or you may allow Perl to -calculate the length by using C or specifying 0 as the second +calculate the length by using C or by specifying 0 as the second argument to C. Be warned, though, that Perl will determine the string's length by using C, 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 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 is true. If you want to append something to the end of string stored in an C, 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's, not C's. +Take note that C and C return C's, not C'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 used only once: possible typo" warning. - 0x04 Issues a "Had to create 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 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 argument can be any of an C, C, or C. 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 argument must be a reference. The C argument specifies +which class the reference will belong to. See the section on L +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) 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 used only once: possible typo" warning. + 0x04 Issues a "Had to create 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 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 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, 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) to the C or C 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. +C. The C flag will create a new package if it is set. The name that C wants is the name of the package whose symbol table you want. The default package is called C
. If you have multiply nested @@ -550,7 +604,8 @@ copy of the name is stored in C field. The sv_magic function uses C to determine which, if any, predefined "Magic Virtual Table" should be assigned to the C field. -See the "Magic Virtual Table" section below. +See the "Magic Virtual Table" section below. The C argument is also +stored in the C field. The C argument is stored in the C field of the C structure. If it is not the same as the C argument, the reference @@ -558,6 +613,19 @@ count of the C object is incremented. If it is the same, or if the C argument is "#", or if it is a null pointer, then C is merely stored, without the reference count being incremented. +There is also a function to add magic to an C: + + void hv_magic(HV *hv, GV *gv, int how); + +This simply calls C and coerces the C argument into an C. + +To remove the magic from an SV, call the function sv_unmagic: + + void sv_unmagic(SV *sv, int type); + +The C argument should be equal to the C value when the C +was initially made magical. + =head2 Magic Virtual Tables The C field in the C structure is a pointer to a @@ -717,6 +785,7 @@ functions: FREETMPS LEAVE XPUSH*() + POP*() For more information, consult L. @@ -766,14 +835,1357 @@ destination starting points. Perl will move, copy, or zero out C instances of the size of the C data structure (using the C function). -=head1 AUTHOR +=head1 API LISTING -Jeff Okamoto +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. + +=item av_clear + +Clears an array, making it empty. + + void av_clear _((AV* ar)); + +=item av_extend + +Pre-extend an array. The C 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 is the +index. If C 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** 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. The +return value will be null if the operation failed, otherwise it can be +dereferenced to get the original C. + + 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 to indicate the class name for a C++ XS +constructor. This is always a C. See C and L. + +=item Copy + +The XSUB-writer's interface to the C C function. The C is the +source, C is the destination, C is the number of items, and C is +the type. + + (void) Copy( s, d, n, t ); + +=item croak + +This is the XSUB-writer's interface to Perl's C function. Use this +function the same way you use the C C function. See C. + +=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. + +=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. +The sub name can be found by + + SvPV( GvSV( DBsub ), na ) + +=item dMARK + +Declare a stack marker for the XSUB. See C and C. + +=item dORIGMARK + +Saves the original stack mark for the XSUB. See C. + +=item dSP + +Declares a stack pointer for the XSUB. See C. + +=item dXSARGS + +Sets up stack and mark pointers for an XSUB, calling dSP and dMARK. This is +usually handled automatically by C. Declares the C variable +to indicate the number of items on the stack. + +=item ENTER + +Opening bracket on a callback. See C and L. + + 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 and +L. + + FREETMPS; + +=item G_ARRAY + +Used to indicate array context. See C and L. + +=item G_DISCARD + +Indicates that arguments returned from a callback should be discarded. See +L. + +=item G_EVAL + +Used to force a Perl C wrapper around a callback. See L. + +=item GIMME + +The XSUB-writer's equivalent to Perl's C. Returns C or +C for scalar or array context. + +=item G_NOARGS + +Indicates that no arguments are being sent to a callback. See L. + +=item G_SCALAR + +Used to indicate scalar context. See C and L. + +=item gv_stashpv + +Returns a pointer to the stash for a specified package. If C is set +then the package will be created if it does not already exist. If C +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. + + 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. + +=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 is the length of the key. The +C 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 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 is the length of the key. If C 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** 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. + + char* hv_iterkey _((HE* entry, I32* retlen)); + +=item hv_iternext + +Returns entries from a hash iterator. See C. + + HE* hv_iternext _((HV* tb)); + +=item hv_iternextsv + +Performs an C, C, and C 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. + + SV* hv_iterval _((HV* tb, HE* entry)); + +=item hv_magic + +Adds magic to a hash. See C. + + void hv_magic _((HV* hv, GV* gv, int how)); + +=item HvNAME + +Returns the package name of a stash. See C, C. + + char *HvNAME (HV* stash) + +=item hv_store + +Stores an SV in a hash. The hash key is specified as C and C is +the length of the key. The C 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** 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 is an ascii alphanumeric +character or digit. + + int isALNUM (char c) + +=item isALPHA + +Returns a boolean indicating whether the C C is an ascii alphanumeric +character. + + int isALPHA (char c) + +=item isDIGIT + +Returns a boolean indicating whether the C C is an ascii digit. + + int isDIGIT (char c) + +=item isLOWER + +Returns a boolean indicating whether the C C is a lowercase character. + + int isLOWER (char c) + +=item isSPACE + +Returns a boolean indicating whether the C C is whitespace. + + int isSPACE (char c) + +=item isUPPER + +Returns a boolean indicating whether the C C is an uppercase character. + + int isUPPER (char c) + +=item items + +Variable which is setup by C to indicate the number of items on the +stack. See L. + +=item LEAVE + +Closing bracket on a callback. See C and L. + + LEAVE; + +=item MARK + +Stack marker for the XSUB. See C. + +=item mg_clear + +Clear something magical that the SV represents. See C. + + int mg_clear _((SV* sv)); + +=item mg_copy + +Copies the magic from one SV to another. See C. + + int mg_copy _((SV *, SV *, char *, STRLEN)); + +=item mg_find + +Finds the magic pointer for type matching the SV. See C. + + MAGIC* mg_find _((SV* sv, int type)); + +=item mg_free + +Free any magic storage used by the SV. See C. + + int mg_free _((SV* sv)); + +=item mg_get + +Do magic after a value is retrieved from the SV. See C. + + int mg_get _((SV* sv)); + +=item mg_len + +Report on the SV's length. See C. + + U32 mg_len _((SV* sv)); + +=item mg_magical + +Turns on the magical status of an SV. See C. + + void mg_magical _((SV* sv)); + +=item mg_set + +Do magic after a value is assigned to the SV. See C. + + int mg_set _((SV* sv)); + +=item Move + +The XSUB-writer's interface to the C C function. The C is the +source, C is the destination, C is the number of items, and C is +the type. + + (void) Move( s, d, n, t ); + +=item na + +A variable which may be used with C to tell Perl to calculate the +string length. + +=item New + +The XSUB-writer's interface to the C C function. + + void * New( x, void *ptr, int size, type ) + +=item Newc + +The XSUB-writer's interface to the C C function, with cast. + + void * Newc( x, void *ptr, int size, type, cast ) + +=item Newz + +The XSUB-writer's interface to the C C function. The allocated +memory is zeroed with C. + + 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 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 is zero then Perl will compute the length. + + SV* newSVpv _((char* s, STRLEN len)); + +=item newSVrv + +Creates a new SV for the RV, C, to point to. If C is not an RV then +it will be upgraded one. If C 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 to hook up XSUBs as Perl subs. + +=item newXSproto + +Used by C 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. + +=item perl_alloc + +Allocates a new Perl interpreter. See L. + +=item perl_call_argv + +Performs a callback to the specified Perl sub. See L. + + 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. + + I32 perl_call_method _((char* methname, I32 flags)); + +=item perl_call_pv + +Performs a callback to the specified Perl sub. See L. + + 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. + + I32 perl_call_sv _((SV* sv, I32 flags)); + +=item perl_construct + +Initializes a new Perl interpreter. See L. + +=item perl_destruct + +Shuts down a Perl interpreter. See L. + +=item perl_eval_sv + +Tells Perl to C the string in the SV. + + I32 perl_eval_sv _((SV* sv, I32 flags)); + +=item perl_free + +Releases a Perl interpreter. See L. + +=item perl_get_av + +Returns the AV of the specified Perl array. If C is set and the +Perl variable does not exist then it will be created. If C 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 is set and the Perl +variable does not exist then it will be created. If C 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 is set and the Perl +variable does not exist then it will be created. If C 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 is set and the +Perl variable does not exist then it will be created. If C 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. + +=item perl_require_pv + +Tells Perl to C a module. + + void perl_require_pv _((char* pv)); + +=item perl_run + +Tells a Perl interpreter to run. See L. + +=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 and L. + + PUSHMARK(p) + +=item PUSHi + +Push an integer onto the stack. The stack must have room for this element. +See C. + + PUSHi(int d) + +=item PUSHn + +Push a double onto the stack. The stack must have room for this element. +See C. + + PUSHn(double d) + +=item PUSHp + +Push a string onto the stack. The stack must have room for this element. +The C indicates the length of the string. See C. + + PUSHp(char *c, int len ) + +=item PUSHs + +Push an SV onto the stack. The stack must have room for this element. See +C. + + PUSHs(sv) + +=item PUTBACK + +Closing bracket for XSUB arguments. This is usually handled by C. +See C and L for other uses. + + PUTBACK; + +=item Renew + +The XSUB-writer's interface to the C C function. + + void * Renew( void *ptr, int size, type ) + +=item Renewc + +The XSUB-writer's interface to the C C function, with cast. + + void * Renewc( void *ptr, int size, type, cast ) + +=item RETVAL + +Variable which is setup by C to hold the return value for an XSUB. +This is always the proper type for the XSUB. See L. + +=item safefree + +The XSUB-writer's interface to the C C function. + +=item safemalloc + +The XSUB-writer's interface to the C C function. + +=item saferealloc + +The XSUB-writer's interface to the C C 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 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 and +L. + + SAVETMPS; + +=item SP + +Stack pointer. This is usually handled by C. See C and +C. + +=item SPAGAIN + +Refetch the stack pointer. Used after a callback. See L. + + 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, is greater than or equal to the +second, C. Returns true or false. + + int strGE( char *s1, char *s2 ) + +=item strGT + +Test two strings to see if the first, C, is greater than the second, +C. Returns true or false. + + int strGT( char *s1, char *s2 ) + +=item strLE + +Test two strings to see if the first, C, is less than or equal to the +second, C. Returns true or false. + + int strLE( char *s1, char *s2 ) + +=item strLT + +Test two strings to see if the first, C, is less than the second, +C. 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 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 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). 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 indicates number of bytes to copy. + + void sv_catpvn _((SV* sv, char* ptr, STRLEN len)); + +=item sv_catsv + +Concatentates the string from SV C onto the end of the string in SV +C. + + void sv_catsv _((SV* dsv, SV* ssv)); + +=item SvCUR + +Returns the length of the string which is in the SV. See C. + + int SvCUR (SV* sv) + +=item SvCUR_set + +Set the length of the string which is in the SV. See C. + + 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. 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 setting. Use C. + + 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. + + 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 SV. See C. 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 setting. Use C. + + 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 setting. Use C. + + 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 setting. Use C. + + 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 is C 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 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 argument indicates the package for the blessing. Set +C to C 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 argument indicates the package for the blessing. Set +C to C 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 argument is NULL then C will be placed into the +SV. The C argument indicates the package for the blessing. Set +C to C 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 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. The SV must be an RV. The C +argument indicates the package for the blessing. Set C to +C 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 copies the pointer while this copies the string. + +=item sv_setsv + +Copies the contents of the source SV C into the destination SV C. + + 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. + +=item SVt_PV + +Pointer type flag for scalars. See C. + +=item SVt_PVAV + +Type flag for arrays. See C. + +=item SVt_PVCV + +Type flag for code refs. See C. + +=item SVt_PVHV + +Type flag for hashes. See C. + +=item SVt_PVMG + +Type flag for blessed scalars. See C. + +=item SVt_NV + +Double type flag for scalars. See C. + +=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 (SV* sv) + +=item svtype + +An enum of flags for Perl types. These are found in the file B in the +C enum. Test these flags with the C macro. + +=item SvUPGRADE + +Used to upgrade an SV to a more complex form. See C. + +=item sv_undef + +This is the C SV. Always refer to this as C<&sv_undef>. + +=item sv_usepvn + +Tells an SV to use C 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, must be supplied. This function will realloc the +memory pointed to by C, 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 SV. See C. Always refer to this as C<&sv_yes>. + +=item THIS + +Variable which is setup by C to designate the object in a C++ XSUB. +This is always the proper type for the C++ object. See C and +L. + +=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 function. Use this +function the same way you use the C C function. See C. + +=item XPUSHi + +Push an integer onto the stack, extending the stack if necessary. See +C. + + XPUSHi(int d) + +=item XPUSHn + +Push a double onto the stack, extending the stack if necessary. See +C. + + XPUSHn(double d) + +=item XPUSHp + +Push a string onto the stack, extending the stack if necessary. The C +indicates the length of the string. See C. + + XPUSHp(char *c, int len) + +=item XPUSHs + +Push an SV onto the stack, extending the stack if necessary. See C. + + XPUSHs(sv) + +=item XSRETURN + +Return from XSUB, indicating number of items on the stack. This is usually +handled by C. + + XSRETURN(x); + +=item XSRETURN_EMPTY + +Return from an XSUB immediately. + + XSRETURN_EMPTY; + +=item XSRETURN_NO + +Return C from an XSUB immediately. + + XSRETURN_NO; + +=item XSRETURN_UNDEF + +Return C from an XSUB immediately. + + XSRETURN_UNDEF; + +=item XSRETURN_YES + +Return C from an XSUB immediately. + + XSRETURN_YES; + +=item Zero + +The XSUB-writer's interface to the C C function. The C is the +destination, C is the number of items, and C is the type. + + (void) Zero( d, n, t ); + +=back + +=head1 AUTHOR + +Jeff Okamoto + +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 . + +=head1 DATE + +Version 20: 1995/12/14 -Version 19: 1995/4/26 diff --git a/pod/perlipc.pod b/pod/perlipc.pod index 3166f1a..1a3bdad 100644 --- a/pod/perlipc.pod +++ b/pod/perlipc.pod @@ -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 diff --git a/pod/perllol.pod b/pod/perllol.pod index 4b58bee..11632e0 100644 --- a/pod/perllol.pod +++ b/pod/perllol.pod @@ -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, 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) diff --git a/pod/perlmod.pod b/pod/perlmod.pod index c5ab08a..3ada156 100644 --- a/pod/perlmod.pod +++ b/pod/perlmod.pod @@ -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
. You can switch namespaces -using the C 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 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 lexical +variables created with my(). Typically it would be the first declaration +in a file to be included by the C or C 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 that C<$INNER::var> refers to C<$OUTER::INNER::var>. It would treat package C 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
. -In addition, the identifiers STDIN, STDOUT, STDERR, ARGV, -ARGVOUT, ENV, INC and SIG are forced to be in package C
, -even when used for other purposes than their built-in one. Note also -that, if you have a package called C, C or C, 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
, +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
, even when used for other purposes than +their built-in one. Note also that, if you have a package called C, +C or C, 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
package to evaluate various expressions in the context of the C
package (or wherever you came from). See L. +See L for other scoping issues related to my() and local(), +or L 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, the name of the subroutine is qualified so that its name is inserted into package C
. -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 assumes this so that you don't have to spell out "F" 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 -instead of C. Therefore, if you're planning on the module altering -your namespace, use C; otherwise, use C. Otherwise you -can get into this problem: +instead of C. 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 is recommended over C. + 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 +=item diagnostics Pragma to produce enhanced diagnostics -=item C +=item integer Pragma to compute arithmetic in integer instead of double -=item C +=item less Pragma to request less of something from the compiler -=item C +=item overload + +Pragma for overloading operators + +=item sigtrap Pragma to enable stack backtrace on unexpected signals -=item C +=item strict Pragma to restrict unsafe constructs -=item C +=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 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('',) || 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 (or C). +Remember that you can add C 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 + diff --git a/pod/perlobj.pod b/pod/perlobj.pod index 6bbaab4..59c6f12 100644 --- a/pod/perlobj.pod +++ b/pod/perlobj.pod @@ -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), 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 Cnew()> 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 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 construct is I 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 built Perl with C, 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 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, 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 for other object tricks, traps, and tips. +You should also check out L for other object tricks, traps, and tips, +as well as L for some style guides on constructing both modules +and classes. diff --git a/pod/perlop.pod b/pod/perlop.pod index 9e1e3f1..13655a7 100644 --- a/pod/perlop.pod +++ b/pod/perlop.pod @@ -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.) +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.) 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 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, 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. +The generalized form of backticks is C. (Because backticks +always undergo shell expansion as well, see L 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, C and C 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 for details on this. If a 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$fooE> diff --git a/pod/perlovl.pod b/pod/perlovl.pod index cdb3ba6..1bad322 100644 --- a/pod/perlovl.pod +++ b/pod/perlovl.pod @@ -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 = ( - '+' => \&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 (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, or $a is -not an object from a package with defined mathemagic addition, but $b is a -reference to a C. It can be called also in other situations, like -C<$a+=7>, or C<$a++>. See L. (Mathemagical -methods refer to methods triggered by an overloaded mathematical -operator.) - -=head2 Calling Conventions for Binary Operations - -The functions in C are called with three (in one -particular case with four, see L) 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 - -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. 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 - - "+", "+=", "-", "-=", "*", "*=", "/", "/=", "%", "%=", - "**", "**=", "<<", "<<=", ">>", ">>=", "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. - -=item * I - - "<", "<=", ">", ">=", "==", "!=", "<=>", - "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 Cing -arrays, C is used to compare values subject to %OVERLOAD. - -=item * I - - "&", "^", "|", "&=", "^=", "|=", "neg", "!", "~", - -"C" stands for unary minus. If the method for C is not -specified, it can be autogenerated using on the method for subtraction. - -=item * I - - "++", "--", - -If undefined, addition and subtraction methods can be -used instead. These operations are called both in prefix and -postfix form. - -=item * I - - "atan2", "cos", "sin", "exp", "abs", "log", "sqrt", - -If C is unavailable, it can be autogenerated using methods -for "<" or "<=>" combined with either unary minus or subtraction. - -=item * I - - "bool", "\"\"", "0+", - -If one or two of these operations are unavailable, the remaining ones can -be used instead. C is used in the flow control operators -(like C) 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 - - "nomethod", "fallback", "=", - -see L. - -=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 - -Perl tries to use a -substituted method (see L). 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 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 scalar. - -=head1 MAGIC AUTOGENERATION - -If a method for an operation is not found, and C<$OVERLOAD{"fallback"}> is -TRUE or undefined, Perl tries to to autogenerate a substitute method for -the missing operation based on defined operations. Autogenerated method -substitutions are possible for the following operations: - -=over 16 - -=item I - -C<$a=+$b> can use the C<$OVERLOAD{"+"}> method if C<$OVERLOAD{"+="}> -is not defined. - -=item I - -String, numeric, and boolean conversion are calculated in terms of one -another if not all of them are defined. - -=item I - -The C<++$a> operation can be expressed in terms of C<$a+=1> or C<$a+1>, -and C<$a--> in terms of C<$a-=1> and C<$a-1>. - -=item C - -can be expressed in terms of C<$aE0> and C<-$a> (or C<0-$a>). - -=item I - -can be expressed in terms of subtraction. - -=item I - -can be expressed in terms of string conversion. - -=item I - -can be expressed in terms of its "spaceship" counterpart: either -C=E> or C: - - <, >, <=, >=, ==, != in terms of <=> - lt, gt, le, ge, eq, ne in terms of cmp - -=item I - -can be expressed in terms of assignment to the dereferenced value, if this -value is scalar but not a reference. - -=back - -=head1 WARNING - -The restriction for the comparison operation is that even if, for example, -`C' should return a reference to a blessed object, the -autogenerated `C' -function will produce only a standard logical value based on the -numerical value of the result of `C'. In particular, a working -numeric conversion is needed in this case (possibly expressed in terms of -other conversions). - -Similarly, C<.=> and C operators lose their mathemagical properties -if the string conversion substitution is applied. - -When you chop() a mathemagical object, it becomes promoted to a string -first, and its mathemagical qualities is lost. The same can happen with other -operations as well. - -=head1 IMPLEMENTATION - -The table of methods for all operations is cached as a magic for the -symbol table hash of the package. It is rechecked for changes of -%OVERLOAD and @ISA only during Cing; so if it is changed -dynamically, you'll need an additional fake Cing to update the -table. - -(Every SVish thing has a magic queue, and a magic is an entry in that queue. -This is how a single variable may participate in multiple forms of magic -simultaneously. For instance, environment variables regularly have two -forms at once: their %ENV magic and their taint magic.) - -If an object belongs to a package with %OVERLOAD, it carries a special -flag. Thus the only speed penalty during arithmetic operations without -overload is the check of this flag. - -In fact, if no %OVERLOAD is ever accessed, there is almost no overhead for -overloadable operations, so most programs should not suffer measurable -performance penalties. Considerable effort was made minimize overhead -when %OVERLOAD is accessed and the current operation is overloadable but -the arguments in question do not belong to packages with %OVERLOAD. When -in doubt, test your speed with %OVERLOAD and without it. So far there -have been no reports of substantial speed degradation if Perl is compiled -with optimization turned on. - -There is no size penalty for data if there is no %OVERLOAD. - -The copying like C<$a=$b> is shallow; however, a one-level-deep -copying is -carried out before any operation that can imply an assignment to the -object $b (or $a) refers to, like C<$b++>. You can override this -behavior by defining your copy constructor (see L<"Copy Constructor">). - -It is expected that arguments to methods that are not explicitly supposed -to be changed are constant (but this is not enforced). - -=head1 AUTHOR - -Ilya Zakharevich >. - -=head1 DIAGNOSTICS - -When Perl is run with the B<-Do> switch or its equivalent, overloading -induces diagnostic messages. - -=head1 BUGS - -Because it's used for overloading, the per-package associative array -%OVERLOAD now has a special meaning in Perl. - -As shipped, %OVERLOAD is not inherited via the @ISA tree. A patch for -this is available from the author. - -This document is confusing. diff --git a/pod/perlpod.pod b/pod/perlpod.pod index b51c9f8..6566ffb 100644 --- a/pod/perlpod.pod +++ b/pod/perlpod.pod @@ -1,6 +1,6 @@ =head1 NAME -pod - plain old documentation +perlpod - plain old documentation =head1 DESCRIPTION @@ -30,6 +30,58 @@ use however it pleases. Currently recognized commands are =over N =back =cut + =pod + +The "=pod" directive does nothing beyond telling the compiler to lay +off of through the next "=cut". It's useful for adding another +paragraph to the doc if you're mixing up code and pod a lot. + +Head1 and head2 produce first and second level headings, with the text on +the same paragraph as "=headn" forming the heading description. + +Item, over, and back require a little more explanation: Over starts a +section specifically for the generation of a list using =item commands. At +the end of your list, use =back to end it. You will probably want to give +"4" as the number to =over, as some formatters will use this for indention. +This should probably be a default. Note also that there are some basic rules +to using =item: don't use them outside of an =over/=back block, use at least +one inside an =over/=back block, you don't _have_ to include the =back if +the list just runs off the document, and perhaps most importantly, keep the +items consistent: either use "=item *" for all of them, to produce bullets, +or use "=item 1.", "=item 2.", etc., to produce numbered lists, or use +"=item foo", "=item bar", etc., i.e., things that looks nothing like bullets +or numbers. If you start with bullets or numbers, stick with them, as many +formatters you the first =item type to decide how to format the list. + +And don't forget, when using any command, that that command lasts up until +the end of the B, not the line. Hence in the examples below, you +can see the blank lines after each command to end it's paragraph. + +Some examples of lists include: + + =over 4 + + =item * + + First item + + =item * + + Second item + + =back + + =over 4 + + =item Foo() + + Description of Foo function + + =item Bar() + + Description of Bar function + + =back =item * @@ -47,7 +99,9 @@ here and in commands: L section in other manpage L<"sec"> section in this manpage (the quotes are optional) + L ditto F Used for filenames + X An index entry Z<> A zero-width character That's it. The intent is simplicity, not power. I wanted paragraphs @@ -74,16 +128,33 @@ the way, but I've gotten along surprisingly well with just these. Note that I'm not at all claiming this to be sufficient for producing a book. I'm just trying to make an idiot-proof common source for nroff, TeX, and other markup languages, as used for online documentation. -Both B and B translators exist. +Translators exist for B (that's for nroff(1) and troff(1)), +B, B, and B. =head1 Embedding Pods in Perl Modules You can embed pod documentation in your Perl scripts. Start your documentation with a =head1 command at the beg, and end it with an =cut command. Perl will ignore the pod text. See any of the -supplied library modules for examples. +supplied library modules for examples. If you're going to put +your pods at the end of the file, and you're using an __END__ +or __DATA__ cut mark, make sure to put a blank line there before +the first pod directive. + + __END__ + + =head1 NAME + + modern - I am a modern module + +If you had not had that blank line there, then the translators wouldn't +have seen it. + +=head1 SEE ALSO + +L and L -=head1 Author +=head1 AUTHOR Larry Wall diff --git a/pod/perlre.pod b/pod/perlre.pod index 7f63501..014ee3c 100644 --- a/pod/perlre.pod +++ b/pod/perlre.pod @@ -4,15 +4,19 @@ perlre - Perl regular expressions =head1 DESCRIPTION -For a description of how to use regular expressions in matching -operations, see C and C in L. The matching operations can +This page describes the syntax of regular expressions in Perl. For a +description of how to actually I regular expressions in matching +operations, plus various examples of the same, see C and C in +L. + +The matching operations can have various modifiers, some of which relate to the interpretation of the regular expression inside. These are: i Do case-insensitive pattern matching. m Treat string as multiple lines. s Treat string as single line. - x Use extended regular expressions. + x Extend your pattern's legibilty with whitespace and comments. These are usually written as "the C modifier", even though the delimiter in question might not actually be a slash. In fact, any of these @@ -102,15 +106,15 @@ also work: \f form feed \v vertical tab, whatever that is \a alarm (bell) - \e escape - \033 octal char - \x1b hex char + \e escape (think troff) + \033 octal char (think of a PDP-11) + \x1B hex char \c[ control char - \l lowercase next char - \u uppercase next char - \L lowercase till \E - \U uppercase till \E - \E end case modification + \l lowercase next char (think vi) + \u uppercase next char (think vi) + \L lowercase till \E (think vi) + \U uppercase till \E (think vi) + \E end case modification (think vi) \Q quote regexp metacharacters till \E In addition, Perl defines the following: @@ -123,9 +127,9 @@ In addition, Perl defines the following: \D Match a non-digit character Note that C<\w> matches a single alphanumeric character, not a whole -word. To match a word you'd need to say C<\w+>. You may use C<\w>, C<\W>, C<\s>, -C<\S>, C<\d> and C<\D> within character classes (though not as either end of a -range). +word. To match a word you'd need to say C<\w+>. You may use C<\w>, +C<\W>, C<\s>, C<\S>, C<\d> and C<\D> within character classes (though not +as either end of a range). Perl defines the following zero-width assertions: @@ -145,16 +149,16 @@ C modifier is used, while "^" and "$" will match at every internal line boundary. When the bracketing construct C<( ... )> is used, \ matches the -digit'th substring. (Outside of the pattern, always use "$" instead of -"\" in front of the digit. The scope of $ (and C<$`>, C<$&>, and C<$')> -extends to the end of the enclosing BLOCK or eval string, or to the -next successful pattern match, whichever comes first. -If you want to -use parentheses to delimit subpattern (e.g. a set of alternatives) without +digit'th substring. Outside of the pattern, always use "$" instead of "\" +in front of the digit. (The \ notation can on rare occasion work +outside the current pattern, this should not be relied upon. See the +WARNING below.) The scope of $ (and C<$`>, C<$&>, and C<$')> +extends to the end of the enclosing BLOCK or eval string, or to the next +successful pattern match, whichever comes first. If you want to use +parentheses to delimit subpattern (e.g. a set of alternatives) without saving it as a subpattern, follow the ( with a ?. -The \ notation -sometimes works outside the current pattern, but should not be relied -upon.) You may have as many parentheses as you wish. If you have more + +You may have as many parentheses as you wish. If you have more than 9 substrings, the variables $10, $11, ... refer to the corresponding substring. Within the pattern, \10, \11, etc. refer back to substrings if there have been at least that many left parens before @@ -202,7 +206,8 @@ extensions are already supported: =item (?#text) -A comment. The text is ignored. +A comment. The text is ignored. If the C switch is used to enable +whitespace formatting, a simple C<#> will suffice. =item (?:regexp) @@ -312,3 +317,28 @@ rules for that subpattern. Therefore, C<(0|0x)\d*\s\1\d*> will match "0x1234 0x4321",but not "0x1234 01234", since subpattern 1 actually matched "0x", even though the rule C<0|0x> could potentially match the leading 0 in the second number. + +=head2 WARNING on \1 vs $1 + +Some people get too used to writing things like + + $pattern =~ s/(\W)/\\\1/g; + +This is grandfathered for the RHS of a substitute to avoid shocking the +B addicts, but it's a dirty habit to get into. That's because in +PerlThink, the right-hand side of a C is a double-quoted string. C<\1> in +the usual double-quoted string means a control-A. The customary Unix +meaning of C<\1> is kludged in for C. However, if you get into the habit +of doing that, you get yourself into trouble if you then add an C +modifier. + + s/(\d+)/ \1 + 1 /eg; + +Or if you try to do + + s/(\d+)/\1000/; + +You can't disambiguate that by saying C<\{1}000>, whereas you can fix it with +C<${1}000>. Basically, the operation of interpolation should not be confused +with the operation of matching a backreference. Certainly they mean two +different things on the I side of the C. diff --git a/pod/perlref.pod b/pod/perlref.pod index 62d99a8..c164e03 100644 --- a/pod/perlref.pod +++ b/pod/perlref.pod @@ -1,20 +1,17 @@ -(Don't -convert references into strings though, or you'll break their referenceness.) - =head1 NAME perlref - Perl references and nested data structures =head1 DESCRIPTION -In Perl 4 it was difficult to represent complex data structures, because -all references had to be symbolic, and even that was difficult to do when -you wanted to refer to a variable rather than a symbol table entry. Perl -5 not only makes it easier to use symbolic references to variables, but -lets you have "hard" references to any piece of data. Any scalar may hold -a hard reference. Since arrays and hashes contain scalars, you can now -easily build arrays of arrays, arrays of hashes, hashes of arrays, arrays -of hashes of functions, and so on. +Before release 5 of Perl it was difficult to represent complex data +structures, because all references had to be symbolic, and even that was +difficult to do when you wanted to refer to a variable rather than a +symbol table entry. Perl 5 not only makes it easier to use symbolic +references to variables, but lets you have "hard" references to any piece +of data. Any scalar may hold a hard reference. Since arrays and hashes +contain scalars, you can now easily build arrays of arrays, arrays of +hashes, hashes of arrays, arrays of hashes of functions, and so on. Hard references are smart--they keep track of reference counts for you, automatically freeing the thing referred to when its reference count @@ -52,6 +49,8 @@ reference that the backslash returned. Here are some examples: $arrayref = \@ARGV; $hashref = \%ENV; $coderef = \&handler; + $globref = \*STDOUT; + =item 2. @@ -66,6 +65,13 @@ elements. (The multidimensional syntax described later can be used to access this. For example, after the above, $arrayref->[2][1] would have the value "b".) +Note that taking a reference to an enumerated list is not the same +as using square brackets--instead it's the same as creating +a list of references! + + @list = (\$a, \$b, \$c); + @list = \($a, $b, $c); # same thing! + =item 3. A reference to an anonymous hash can be constructed using curly @@ -147,7 +153,7 @@ This prints Greetings, earthlings! Note particularly that $x continues to refer to the value passed into -newprint() *despite* the fact that the "my $x" has seemingly gone out of +newprint() I the fact that the "my $x" has seemingly gone out of scope by the time the anonymous subroutine runs. That's what closure is all about. @@ -173,6 +179,24 @@ References of the appropriate type can spring into existence if you dereference them in a context that assumes they exist. Since we haven't talked about dereferencing yet, we can't show you any examples yet. +=item 7. + +References to filehandles can be created by taking a reference to +a typeglob. This is currently the best way to pass filehandles into or +out of subroutines, or to store them in larger data structures. + + splutter(\*STDOUT); + sub splutter { + my $fh = shift; + print $fh "her um well a hmmm\n"; + } + + $rec = get_rec(\*STDIN); + sub get_rec { + my $fh = shift; + return scalar <$fh>; + } + =back That's it for creating references. By now you're probably dying to @@ -192,6 +216,7 @@ containing a reference of the correct type: $$arrayref[0] = "January"; $$hashref{"KEY"} = "VALUE"; &$coderef(1,2,3); + print $globref "output\n"; It's important to understand that we are specifically I dereferencing C<$arrayref[0]> or C<$hashref{"KEY"}> there. The dereference of the @@ -215,6 +240,7 @@ written like this: ${$arrayref}[0] = "January"; ${$hashref}{"KEY"} = "VALUE"; &{$coderef}(1,2,3); + $globref->print("output\n"); # iff you use FileHandle Admittedly, it's a little silly to use the curlies in this case, but the BLOCK can contain any arbitrary expression, in particular, @@ -291,19 +317,22 @@ reference is pointing to. See L. The bless() operator may be used to associate a reference with a package functioning as an object class. See L. -A type glob may be dereferenced the same way a reference can, since +A typeglob may be dereferenced the same way a reference can, since the dereference syntax always indicates the kind of reference desired. So C<${*foo}> and C<${\$foo}> both indicate the same scalar variable. Here's a trick for interpolating a subroutine call into a string: - print "My sub returned ${\mysub(1,2,3)}\n"; + print "My sub returned @{[mysub(1,2,3)]} that time.\n"; + +The way it works is that when the C<@{...}> is seen in the double-quoted +string, it's evaluated as a block. The block creates a reference to an +anonymous array containing the results of the call to C. So +the whole block returns a reference to an array, which is then +dereferenced by C<@{...}> and stuck into the double-quoted string. This +chicanery is also useful for arbitrary expressions: -The way it works is that when the C<${...}> is seen in the double-quoted -string, it's evaluated as a block. The block executes the call to -C, and then takes a reference to that. So the whole block -returns a reference to a scalar, which is then dereferenced by C<${...}> -and stuck into the double-quoted string. + print "That yeilds @{[$n + 5]} widgets\n"; =head2 Symbolic references @@ -407,7 +436,7 @@ The B<-w> switch will warn you if it interprets a reserved word as a string. But it will no longer warn you about using lowercase words, since the string is effectively quoted. -=head2 WARNING +=head1 WARNING You may not (usefully) use a reference as the key to a hash. It will be converted into a string: @@ -415,10 +444,21 @@ converted into a string: $x{ \$a } = $a; If you try to dereference the key, it won't do a hard dereference, and -you won't accomplish what you're attemping. +you won't accomplish what you're attemping. You might want to do something +more like -=head2 Further Reading + $r = \@a; + $x{ $r } = $r; + +And then at least you can use the values(), which will be +real refs, instead of the keys(), which won't. + +=head1 SEE ALSO Besides the obvious documents, source code can be instructive. Some rather pathological examples of the use of references can be found in the F regression test in the Perl source directory. + +See also L and L for how to use references to create +complex data structures, and L for how to use them to create +objects. diff --git a/pod/perlrun.pod b/pod/perlrun.pod index 37be506..12ccaa8 100644 --- a/pod/perlrun.pod +++ b/pod/perlrun.pod @@ -123,8 +123,9 @@ An alternate delimiter may be specified using B<-F>. =item B<-c> causes Perl to check the syntax of the script and then exit without -executing it. Actually, it will execute C and C blocks, -since these are considered part of the compilation. +executing it. Actually, it I execute C, C, and C blocks, +since these are considered as occurring outside the execution of +your program. =item B<-d> @@ -329,8 +330,10 @@ will work under any of csh, sh or Perl, such as the following: =item B<-T> -forces "taint" checks to be turned on. Ordinarily these checks are -done only when running setuid or setgid. See L. +forces "taint" checks to be turned on so you can test them. Ordinarily these checks are +done only when running setuid or setgid. It's a good idea to turn +them on explicitly for programs run on another's behalf, such as CGI +programs. See L. =item B<-u> diff --git a/pod/perlsec.pod b/pod/perlsec.pod index 2bd659e..ccae6e8 100644 --- a/pod/perlsec.pod +++ b/pod/perlsec.pod @@ -45,7 +45,8 @@ exploit. On these systems, Perl should be compiled with C<-DSETUID_SCRIPTS_ARE_SECURE_NOW>. The B program that builds Perl tries to figure this out for itself. -When Perl is executing a setuid script, it takes special precautions to +When executing a setuid script, or when you have turned on taint checking +explicitly using the B<-T> flag, Perl takes special precautions to prevent you from falling into any obvious traps. (In some ways, a Perl script is more secure than the corresponding C program.) Any command line argument, environment variable, or input is marked as "tainted", and may @@ -123,3 +124,24 @@ too!) Perl doesn't prevent you from opening tainted filenames for reading, so be careful what you print out. The tainting mechanism is intended to prevent stupid mistakes, not to remove the need for thought. +This gives us a reasonably safe way to open a file or pipe: just reset the +id set to the original IDs. Here's a way to do backticks reasonably +safely. Notice how the exec() is not called with a string that the shell +could expand. By the time we get to the exec(), tainting is turned off, +however, so be careful what you call and what you pass it. + + die unless defined $pid = open(KID, "-|"); + if ($pid) { # parent + while () { + # do something + } + close KID; + } else { + $> = $<; + $) = $(; # BUG: initgroups() not called + exec 'program', 'arg1', 'arg2'; + die "can't exec program: $!"; + } + +For those even more concerned about safety, see the I and I +modules at a CPAN site near you. See L for a list of CPAN sites. diff --git a/pod/perlstyle.pod b/pod/perlstyle.pod index 43d5355..8bc269d 100644 --- a/pod/perlstyle.pod +++ b/pod/perlstyle.pod @@ -4,12 +4,17 @@ perlstyle - Perl style guide =head1 DESCRIPTION -=head2 Style - Each programmer will, of course, have his or her own preferences in regards to formatting, but there are some general guidelines that will make your programs easier to read, understand, and maintain. +The most important thing is to run your programs under the B<-w> +flag at all times. You may turn it off explicitly for particular +portions of code via the C<$^W> variable if you must. You should +also always run under C or know the reason why not. +The and even pragmas may also prove +useful. + Regarding aesthetics of code lay out, about the only thing Larry cares strongly about is that the closing curly brace of a multi-line BLOCK should line up with the keyword that started the construct. @@ -166,6 +171,35 @@ determined by the B program when Perl was installed. Choose mnemonic identifiers. If you can't remember what mnemonic means, you've got a problem. +=item * + +While short identifiers like $gotit are probably ok, 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 names are sometimes an exception to this rule. Perl informally +reserves lowercase module names for "pragma" modules like C and +C. Other modules should begin with a capital letter and use mixed +case, but probably without underscores due to limitations in primitive +filesystems' representations of module names as files that must fit into a +few sparse bites. + +=item * + +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 * If you have a really hairy regular expression, use the C modifier and @@ -199,6 +233,16 @@ to fit on one line anyway. =item * +Always check the return codes of system calls. Good error messages should +go to STDERR, include which program caused the problem, what the failed +system call and arguments were, and VERY IMPORTANT) should contain the +standard system error message for what went wrong. Here's a simple but +sufficient example: + + opendir(D, $dir) or die "can't opendir $dir: $!"; + +=item * + Line up your translations when it makes sense: tr [abc] @@ -222,4 +266,3 @@ Be consistent. Be nice. =back - diff --git a/pod/perlsub.pod b/pod/perlsub.pod index 1f5201a..a893ff5 100644 --- a/pod/perlsub.pod +++ b/pod/perlsub.pod @@ -6,8 +6,11 @@ perlsub - Perl subroutines To declare subroutines: - sub NAME; # A "forward" declaration. - sub NAME BLOCK # A declaration and a definition. + sub NAME; # A "forward" declaration. + sub NAME(PROTO); # ditto, but with prototypes + + sub NAME BLOCK # A declaration and a definition. + sub NAME(PROTO) BLOCK # ditto, but with prototypes To define an anonymous subroutine at runtime: @@ -19,42 +22,56 @@ To import subroutines: To call subroutines: - &NAME # Passes current @_ to subroutine. - &NAME(LIST); # Parens required with & form. NAME(LIST); # & is optional with parens. NAME LIST; # Parens optional if predeclared/imported. + &NAME; # Passes current @_ to subroutine. =head1 DESCRIPTION -Any arguments passed to the routine come in as array @_, that is -($_[0], $_[1], ...). The array @_ is a local array, but its values are -references to the actual scalar parameters. The return value of the -subroutine is the value of the last expression evaluated, and can be -either an array value or a scalar value. Alternatively, a return -statement may be used to specify the returned value and exit the -subroutine. To create local variables see the local() and my() -operators. - -A subroutine may be called using the "&" prefix. The "&" is optional in Perl -5, and so are the parens if the subroutine has been predeclared. -(Note, however, that the "&" is I optional when you're just naming the -subroutine, such as when it's used as an argument to defined() or -undef(). Nor is it optional when you want to do an indirect subroutine -call with a subroutine name or reference using the C<&$subref()> or -C<&{$subref}()> constructs. See L for more on that.) +Like many languages, Perl provides for user-defined subroutines. These +may be located anywhere in the main program, loaded in from other files +via the C, C, or C keywords, or even generated on the +fly using C or anonymous subroutines (closures). You can even call +a function indirectly using a variable containing its name or a CODE reference. + +The Perl model for function call and return values is simple: all +functions are passed as parameters one single flat list of scalars, and +all functions likewise return to their caller one single flat list of +scalars. Any arrays or hashes in these call and return lists will +collapse, losing their identities--but you may always use +pass-by-reference instead to avoid this. Both call and return lists may +contain as many or as few scalar elements as you'd like. (Often a +function without an explicit return statement is called a subroutine, but +there's really no difference from the language's perspective.) + +Any arguments passed to the routine come in as the array @_. Thus if you +called a function with two arguments, those would be stored in C<$_[0]> +and C<$_[1]>. The array @_ is a local array, but its values are implicit +references (predating L) to the actual scalar parameters. The +return value of the subroutine is the value of the last expression +evaluated. Alternatively, a return statement may be used to specify the +returned value and exit the subroutine. If you return one or more arrays +and/or hashes, these will be flattened together into one large +indistinguishable list. + +Perl does not have named formal parameters, but in practice all you do is +assign to a my() list of these. Any variables you use in the function +that aren't declared private are global variables. For the gory details +on creating private variables, see the sections below on L<"Private +Variables via my()"> and L. To create +protected environments for a set of functions in a separate package (and +probably a separate file), see L. Example: - sub MAX { - my $max = pop(@_); + sub max { + my $max = shift(@_); foreach $foo (@_) { $max = $foo if $max < $foo; } - $max; + return $max; } - - ... - $bestday = &MAX($mon,$tue,$wed,$thu,$fri); + $bestday = max($mon,$tue,$wed,$thu,$fri); Example: @@ -62,7 +79,7 @@ Example: # that start with whitespace sub get_line { - $thisline = $lookahead; + $thisline = $lookahead; # GLOBAL VARIABLES!! LINE: while ($lookahead = ) { if ($lookahead =~ /^[ \t]/) { $thisline .= $lookahead; @@ -83,44 +100,321 @@ Use array assignment to a local list to name your formal arguments: sub maybeset { my($key, $value) = @_; - $foo{$key} = $value unless $foo{$key}; + $Foo{$key} = $value unless $Foo{$key}; } -This also has the effect of turning call-by-reference into -call-by-value, since the assignment copies the values. +This also has the effect of turning call-by-reference into call-by-value, +since the assignment copies the values. Otherwise a function is free to +do in-place modifications of @_ and change its callers values. + + upcase_in($v1, $v2); # this changes $v1 and $v2 + sub upcase_in { + for (@_) { tr/a-z/A-Z/ } + } + +You aren't allowed to modify constants in this way, of course. If an +argument were actually literal and you tried to change it, you'd take a +(presumably fatal) exception. For example, this won't work: + + upcase_in("frederick"); + +It would be much safer if the upcase_in() function +were written to return a copy of its parameters instead +of changing them in place: + + ($v3, $v4) = upcase($v1, $v2); # this doesn't + sub upcase { + my @parms = @_; + for (@parms) { tr/a-z/A-Z/ } + return @parms; + } + +Notice how this (unprototyped) function doesn't care whether it was passed +real scalars or arrays. Perl will see everything as one big long flat @_ +parameter list. This is one of the ways where Perl's simple +argument-passing style shines. The upcase() function would work perfectly +well without changing the upcase() definition even if we fed it things +like this: + + @newlist = upcase(@list1, @list2); + @newlist = upcase( split /:/, $var ); + +Do not, however, be tempted to do this: + + (@a, @b) = upcase(@list1, @list2); + +Because like its flat incoming parameter list, the return list is also +flat. So all you have managed to do here is stored everything in @a and +made @b an empty list. See L for alternatives. + +A subroutine may be called using the "&" prefix. The "&" is optional in +Perl 5, and so are the parens if the subroutine has been predeclared. +(Note, however, that the "&" is I optional when you're just naming +the subroutine, such as when it's used as an argument to defined() or +undef(). Nor is it optional when you want to do an indirect subroutine +call with a subroutine name or reference using the C<&$subref()> or +C<&{$subref}()> constructs. See L for more on that.) Subroutines may be called recursively. If a subroutine is called using -the "&" form, the argument list is optional. If omitted, no @_ array is -set up for the subroutine; the @_ array at the time of the call is -visible to subroutine instead. +the "&" form, the argument list is optional, and if omitted, no @_ array is +set up for the subroutine: the @_ array at the time of the call is +visible to subroutine instead. This is an efficiency mechanism that +new users may wish to avoid. &foo(1,2,3); # pass three arguments foo(1,2,3); # the same foo(); # pass a null list &foo(); # the same - &foo; # pass no arguments--more efficient -If a module wants to create a private subroutine that cannot be called -from outside the module, it can declare a lexical variable containing -an anonymous sub reference: + &foo; # foo() get current args, like foo(@_) !! + foo; # like foo() IFF sub foo pre-declared, else "foo" + +=head2 Private Variables via my() + +Synopsis: + + my $foo; # declare $foo lexically local + my (@wid, %get); # declare list of variables local + my $foo = "flurp"; # declare $foo lexical, and init it + my @oof = @bar; # declare @oof lexical, and init it + +A "my" declares the listed variables to be confined (lexically) to the +enclosing block, subroutine, C, or C'd file. If +more than one value is listed, the list must be placed in parens. All +listed elements must be legal lvalues. Only alphanumeric identifiers may +be lexically scoped--magical builtins like $/ must currently be localized with +"local" instead. + +Unlike dynamic variables created by the "local" statement, lexical +variables declared with "my" are totally hidden from the outside world, +including any called subroutines (even if it's the same subroutine called +from itself or elsewhere--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.) + +The parameter list to my() 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 the undefined value.) Commonly +this is used to name the parameters to a subroutine. Examples: + + $arg = "fred"; # "global" variable + $n = cube_root(27); + print "$arg thinks the root is $n\n"; + fred thinks the root is 3 + + sub cube_root { + my $arg = shift; # name doesn't matter + $arg **= 1/3; + return $arg; + } + +The "my" is simply a modifier on something you might assign to. So when +you do assign to the variables in its argument list, the "my" doesn't +change whether those variables is viewed as a scalar or an array. So + + my ($foo) = ; + my @FOO = ; + +both supply a list context to the righthand side, while + + my $foo = ; + +supplies a scalar context. But the following only declares one variable: - my $subref = sub { ... } - &$subref(1,2,3); + my $foo, $bar = 1; -As long as the reference is never returned by any function within the module, -no outside module can see the subroutine, since its name is not in any -package's symbol table. +That has the same effect as -=head2 Passing Symbol Table Entries + my $foo; + $bar = 1; -[Note: The mechanism described in this section works fine in Perl 5, but -the new reference mechanism is generally easier to work with. See L.] +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'">. + +A my() has both a compile-time and a run-time effect. At compile time, +the compiler takes notice of it; the principle usefulness of this is to +quiet C. The actual initialization doesn't happen +until run time, so gets executed every time through a loop. + +Variables declared with "my" are not part of any package and are therefore +never fully qualified with the package name. In particular, you're not +allowed to try to make a package variable (or other global) lexical: + + my $pack::var; # ERROR! Illegal syntax + my $_; # also illegal (currently) + +In fact, a dynamic variable (also known as package or global variables) +are still accessible using the fully qualified :: notation even while a +lexical of the same name is also visible: + + package main; + local $x = 10; + my $x = 20; + print "$x and $::x\n"; + +That will print out 20 and 10. + +You may declare "my" variables at the outer most scope of a file to +totally hide any such identifiers from the outside world. This is similar +to a C's static variables at the file level. To do this with a subroutine +requires the use of a closure (anonymous function). If a block (such as +an eval(), function, or C) wants to create a private subroutine +that cannot be called from outside that block, it can declare a lexical +variable containing an anonymous sub reference: + + my $secret_version = '1.001-beta'; + my $secret_sub = sub { print $secret_version }; + &$secret_sub(); + +As long as the reference is never returned by any function within the +module, no outside module can see the subroutine, since its name is not in +any package's symbol table. Remember that it's not I called +$some_pack::secret_version or anything; it's just $secret_version, +unqualified and unqualifiable. + +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 lexical variable is lexically (also called statically) +scoped doesn't mean that within a function it works like a C static. It +normally works more like a C auto. But here's a mechanism for giving a +function private variables with both lexical scoping and a static +lifetime. If you do want to create something like C's static variables, +just enclose the whole function in an extra block, and put the +static variable outside the function but in the block. + + { + my $secret_val = 0; + sub gimme_another { + return ++$secret_val; + } + } + # $secret_val now becomes unreachable by the outside + # world, but retains its value between calls to gimme_another + +If this function is being sourced in from a separate file +via C or C, then this is probably just fine. If it's +all in the main program, you'll need to arrange for the my() +to be executed early, either by putting the whole block above +your pain program, or more likely, merely placing a BEGIN +sub around it to make sure it gets executed before your program +starts to run: + + sub BEGIN { + my $secret_val = 0; + sub gimme_another { + return ++$secret_val; + } + } + +See L about the BEGIN function. + +=head2 Temporary Values via local() + +B: In general, you should be using "my" instead of "local", because +it's faster and safer. Execeptions to this include the global punctuation +variables, filehandles and formats, and direct manipulation of the Perl +symbol table itself. Format variables often use "local" though, as do +other variables whose current value must be visible to called +subroutines. + +Synopsis: + + local $foo; # declare $foo dynamically local + local (@wid, %get); # declare list of variables local + local $foo = "flurp"; # declare $foo dynamic, and init it + local @oof = @bar; # declare @oof dynamic, and init it + + local *FH; # localize $FH, @FH, %FH, &FH ... + local *merlyn = *randal; # now $merlyn is really $randal, plus + # @merlyn is really @randal, etc + local *merlyn = 'randal'; # SAME THING: promote 'randal' to *randal + local *merlyn = \$randal; # just alias $merlyn, not @merlyn etc + +A local() modifies its listed variables to be local to the enclosing +block, (or subroutine, C or C) and I. A local() just gives temporary values to global +(meaning package) variables. This is known as dynamic scoping. Lexical +scoping is done with "my", which works more like C's auto declarations. + +If more than one variable is given to local(), they must be placed in +parens. All listed elements must be legal lvalues. This operator works +by saving the current values of those variables in its argument 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 argument 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: + + for $i ( 0 .. 9 ) { + $digits{$i} = $i; + } + # assume this function uses global %digits hash + parse_num(); + + # now temporarily add to %digits hash + if ($base12) { + # (NOTE: not claiming this is efficient!) + local %digits = (%digits, 't' => 10, 'e' => 11); + parse_num(); # parse_num gets this new %digits! + } + # old %digits restored here + +Because local() is a run-time command, and so gets executed every time +through a loop. In releases of Perl previous to 5.0, this used more stack +storage each time until the loop was exited. Perl now 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 variable, the local doesn't change whether its list is viewed +as a scalar or an array. So + + local($foo) = ; + local @FOO = ; + +both supply a list context to the righthand side, while + + local $foo = ; + +supplies a scalar context. + +=head2 Passing Symbol Table Entries (typeglobs) + +[Note: The mechanism described in this section was originally the only +way to simulate pass-by-reference in older versions of Perl. While it +still works fine in modern versions, the new reference mechanism is +generally easier to work with. See below.] Sometimes you don't want to pass the value of an array to a subroutine but rather the name of it, so that the subroutine can modify the global copy of it rather than working with a local copy. In perl you can -refer to all the objects of a particular name by prefixing the name +refer to all objects of a particular name by prefixing the name with a star: C<*foo>. This is often known as a "type glob", since the star on the front can be thought of as a wildcard match for all the funny prefix characters on variables and subroutines and such. @@ -149,9 +443,242 @@ an array. It will certainly be faster to pass the typeglob (or reference). Even if you don't want to modify an array, this mechanism is useful for passing multiple arrays in a single LIST, since normally the LIST mechanism will merge all the array values so that you can't extract out -the individual arrays. +the individual arrays. For more on typeglobs, see L. + +=head2 Pass by Reference + +If you want to pass more than one array or hash into a function--or +return them from it--and have them maintain their integrity, +then you're going to have to use an explicit pass-by-reference. +Before you do that, you need to understand references; see L. + +Here are a few simple examples. First, let's pass in several +arrays to a function and have it pop all of then, return a new +list of all their former last elements: + + @tailings = popmany ( \@a, \@b, \@c, \@d ); + + sub popmany { + my $aref; + my @retlist = (); + foreach $aref ( @_ ) { + push @retlist, pop @$aref; + } + return @retlist; + } + +Here's how you might write a function that returns a +list of keys occurring in all the hashes passed to it: + + @common = inter( \%foo, \%bar, \%joe ); + sub inter { + my ($k, $href, %seen); # locals + foreach $href (@_) { + while ( $k = each %$href ) { + $seen{$k}++; + } + } + return grep { $seen{$_} == @_ } keys %seen; + } + +So far, we're just using the normal list return mechanism. +What happens if you want to pass or return a hash? Well, +if you're only using one of them, or you don't mind them +concatenating, then the normal calling convention is ok, although +a little expensive. + +Where people get into trouble is here: + + (@a, @b) = func(@c, @d); +or + (%a, %b) = func(%c, %d); + +That syntax simply won't work. It just sets @a or %a and clears the @b or +%b. Plus the function didn't get passed into two separate arrays or +hashes: it got one long list in @_, as always. + +If you can arrange for everyone to deal with this through references, it's +cleaner code, although not so nice to look at. Here's a function that +takes two array references as arguments, returning the two array elements +in order of how many elements they have in them: + + ($aref, $bref) = func(\@c, \@d); + print "@$aref has more than @$bref\n"; + sub func { + my ($cref, $dref) = @_; + if (@$cref > @$dref) { + return ($cref, $dref); + } else { + return ($cref, $cref); + } + } + +It turns out that you can actually do this also: + + (*a, *b) = func(\@c, \@d); + print "@a has more than @b\n"; + sub func { + local (*c, *d) = @_; + if (@c > @d) { + return (\@c, \@d); + } else { + return (\@d, \@c); + } + } + +Here we're using the typeglobs to do symbol table aliasing. It's +a tad subtle, though, and also won't work if you're using my() +variables, since only globals (well, and local()s) are in the symbol table. + +If you're passing around filehandles, you could usually just use the bare +typeglob, like *STDOUT, but typeglobs references would be better because +they'll still work properly under C. For example: + + splutter(\*STDOUT); + sub splutter { + my $fh = shift; + print $fh "her um well a hmmm\n"; + } + + $rec = get_rec(\*STDIN); + sub get_rec { + my $fh = shift; + return scalar <$fh>; + } + +If you're planning on generating new filehandles, you could do this: + + sub openit { + my $name = shift; + local *FH; + return open (FH, $path) ? \*FH : undef; + } + +Although that will actually produce a small memory leak. See the bottom +of L for a somewhat cleaner way using the FileHandle +functions supplied with the POSIX package. + +=head2 Prototypes + +As of the 5.002 release of perl, if you declare + + sub mypush (\@@) + +then mypush() takes arguments exactly like push() does. (This only works +for function calls that are visible at compile time, not indirect function +calls through a C<&$func> reference nor for method calls as described in +L.) + +Here are the prototypes for some other functions that parse almost exactly +like the corresponding builtins. + + Declared as Called as + + sub mylink ($$) mylink $old, $new + sub myvec ($$$) myvec $var, $offset, 1 + sub myindex ($$;$) myindex &getstring, "substr" + sub mysyswrite ($$$;$) mysyswrite $buf, 0, length($buf) - $off, $off + sub myreverse (@) myreverse $a,$b,$c + sub myjoin ($@) myjoin ":",$a,$b,$c + sub mypop (\@) mypop @array + sub mysplice (\@$$@) mysplice @array,@array,0,@pushme + sub mykeys (\%) mykeys %{$hashref} + sub myopen (*;$) myopen HANDLE, $name + sub mypipe (**) mypipe READHANDLE, WRITEHANDLE + sub mygrep (&@) mygrep { /foo/ } $a,$b,$c + sub myrand ($) myrand 42 + sub mytime () mytime + +Any backslashed prototype character must be passed something starting +with that character. Any unbackslashed @ or % eats all the rest of the +arguments, and forces list context. An argument represented by $ +forces scalar context. An & requires an anonymous subroutine, and * +does whatever it has to do to turn the argument into a reference to a +symbol table entry. A semicolon separates mandatory arguments from +optional arguments. + +Note that the last three are syntactically distinguished by the lexer. +mygrep() is parsed as a true list operator, myrand() is parsed as a +true unary operator with unary precedence the same as rand(), and +mytime() is truly argumentless, just like time(). That is, if you +say + + mytime +2; + +you'll get mytime() + 2, not mytime(2), which is how it would be parsed +without the prototype. + +The interesting thing about & is that you can generate new syntax with it: + + sub try (&$) { + my($try,$catch) = @_; + eval { &$try }; + if ($@) { + local $_ = $@; + &$catch; + } + } + sub catch (&) { @_ } + + try { + die "phooey"; + } catch { + /phooey/ and print "unphooey\n"; + }; + +That prints "unphooey". (Yes, there are still unresolved +issues having to do with the visibility of @_. I'm ignoring that +question for the moment. (But note that if we make @_ lexically +scoped, those anonymous subroutines can act like closures... (Gee, +is this sounding a little Lispish? (Nevermind.)))) + +And here's a reimplementation of grep: + + sub mygrep (&@) { + my $code = shift; + my @result; + foreach $_ (@_) { + push(@result, $_) if &$ref; + } + @result; + } -=head2 Overriding builtin functions +Some folks would prefer full alphanumeric prototypes. Alphanumerics have +been intentionally left out of prototypes for the express purpose of +someday in the future adding named, formal parameters. The current +mechanism's main goal is to let module writers provide better diagnostics +for module users. Larry feels the notation quite understandable to Perl +programmers, and that it will not intrude greatly upon the meat of the +module, nor make it harder to read. The line noise is visually +encapsulated into a small pill that's easy to swallow. + +It's probably best to prototype new functions, not retrofit prototyping +into older ones. That's because you must be especially careful about +silent impositions of differing list versus scalar contexts. For example, +if you decide that a function should take just one parameter, like this: + + sub func ($) { + my $n = shift; + print "you gave me $n\n"; + } + +and someone has been calling it with an array or expression +returning a list: + + func(@foo); + func( split /:/ ); + +Then you've just supplied an automatic scalar() in front of their +argument, which can be more than a bit surprising. The old @foo +which used to hold one thing doesn't get passed in. Instead, +the func() now gets passed in 1, that is, the number of elments +in @foo. And the split() gets called in a scalar context and +starts scribbling on your @_ parameter list. + +This is all very powerful, of course, and should only be used in moderation +to make the world a better place. + +=head2 Overriding Builtin Functions Many builtin functions may be overridden, though this should only be tried occasionally and for good reason. Typically this might be @@ -201,10 +728,37 @@ question using eval, and then execute that subroutine using a special form of "goto" that erases the stack frame of the C routine without a trace. (See the standard C module, for example.) But an C routine can also just emulate the routine and never -define it. A good example of this is the standard Shell module, which +define it. For example, let's pretend that a function that wasn't defined +should just call system() with those arguments. All you'd do is this: + + sub AUTOLOAD { + my $program = $AUTOLOAD; + $program =~ s/.*:://; + system($program, @_); + } + date(); + who('am', i'); + ls('-l'); + +In fact, if you preclare the functions you want to call that way, you don't +even need the parentheses: + + use subs qw(date who ls); + date; + who "am", "i"; + ls -l; + +A more complete example of this is the standard Shell module, which can treat undefined subroutine calls as calls to Unix programs. -There are mechanisms available for modules to help them split themselves -up into autoloadable files to be used with the standard AutoLoader module. -See the document on extensions. +Mechanisms are available for modules writers to help split the modules +up into autoloadable files. See the standard AutoLoader module described +in L, the standard SelfLoader modules in L, and +the document on adding C functions to perl code in L. + +=head1 SEE ALSO +See L for more on references. See L if you'd +like to learn about calling C subroutines from perl. See +L to learn about bundling up your functions in +separate files. diff --git a/pod/perlsyn.pod b/pod/perlsyn.pod index 4b1d607..e41caee 100644 --- a/pod/perlsyn.pod +++ b/pod/perlsyn.pod @@ -226,15 +226,16 @@ statement in that block is true. While this "feature" continues to work in version 5, it has been deprecated, so please change any occurrences of "if BLOCK" to "if (do BLOCK)". -=head2 For and Foreach +=head2 For Loops -Perl's C-style C loop works exactly like the corresponding C loop: +Perl's C-style C loop works exactly like the corresponding C loop; +that means that this: for ($i = 1; $i < 10; $i++) { ... } -is the same as +is the same as this: $i = 1; while ($i < 10) { @@ -243,6 +244,20 @@ is the same as $i++; } +Besides the normal array index looping, C can lend itself +to many other interesting applications. Here's one that avoids the +problem you get into if you explicitly test for end-of-file on +an interactive file descriptor causing your program to appear to +hang. + + $on_a_tty = -t STDIN && -t STDOUT; + sub prompt { print "yes? " if $on_a_tty } + for ( prompt(); ; prompt() ) { + # do something + } + +=head2 Foreach Loops + The C loop iterates over a normal list value and sets the variable VAR to be each element of the list in turn. The variable is implicitly local to the loop and regains its former value upon exiting the @@ -286,26 +301,26 @@ Here's how a C programmer might code up a particular algorithm in Perl: } $ary1[$i] += $ary2[$j]; } + # this is where that last takes me } Whereas here's how a Perl programmer more confortable with the idiom might -do it this way: +do it: - OUTER: foreach $i (@ary1) { - INNER: foreach $j (@ary2) { - next OUTER if $i > $j; - $i += $j; + OUTER: foreach $wid (@ary1) { + INNER: foreach $jet (@ary2) { + next OUTER if $wid > $jet; + $wid += $jet; } } -See how much easier this is? It's cleaner, safer, and faster. -It's cleaner because it's less noisy. -It's safer because if code gets added +See how much easier this is? It's cleaner, safer, and faster. It's +cleaner because it's less noisy. It's safer because if code gets added between the inner and outer loops later, you won't accidentally excecute it because you've explicitly asked to iterate the other loop rather than -merely terminating the inner one. -And it's faster because Perl exececute C statement more -rapidly than it would the equivalent C loop. +merely terminating the inner one. And it's faster because Perl executes a +C statement more rapidly than it would the equivalent C +loop. =head2 Basic BLOCKs and Switch Statements @@ -335,7 +350,7 @@ above, you could write $nothing = 1; } -(That's actually not as strange as it looks one you realize that you can +(That's actually not as strange as it looks once you realize that you can use loop control "operators" within an expression, That's just the normal C comma operator.) @@ -399,6 +414,18 @@ a temporary assignment to $_ for convenient matching: die "unknown value for form variable where: `$where'"; } +Another interesting approach to a switch statement is arrange +for a C block to return the proper value: + + $amode = do { + if ($flag & O_RDONLY) { "r" } + elsif ($flag & O_WRONLY) { ($flag & O_APPEND) ? "w" : "a" } + elsif ($flag & O_RDWR) { + if ($flag & O_CREAT) { "w+" } + else { ($flag & O_APPEND) ? "r+" : "a+" } + } + }; + =head2 Goto Although not for the faint of heart, Perl does support a C statement. @@ -433,3 +460,47 @@ In almost cases like this, it's usually a far, far better idea to use the structured control flow mechanisms of C, C, or C insetad resorting to a C. For certain applications, the catch and throw pair of C and die() for exception processing can also be a prudent approach. + +=head2 PODs: Embedded Documentation + +Perl has a mechanism for intermixing documentation with source code. +If while expecting the beginning of a new statement, the compiler +encounters a line that begins with an equal sign and a word, like this + + =head1 Here There Be Pods! + +Then that text and all remaining text up through and including a line +beginning with C<=cut> will be ignored. The format of the intervening +text is described in L. + +This allows you to intermix your source code +and your documentation text freely, as in + + =item snazzle($) + + The snazzle() function will behave in the most spectacular + form that you can possibly imagine, not even excepting + cybernetic pyrotechnics. + + =cut back to the compiler, nuff of this pod stuff! + + sub snazzle($) { + my $thingie = shift; + ......... + } + +Note that pod translators should only look at paragraphs beginning +with a pod diretive (it makes parsing easier), whereas the compiler +actually knows to look for pod escapes even in the middle of a +paragraph. This means that the following secret stuff will be +ignored by both the compiler and the translators. + + $a=3; + =secret stuff + warn "Neither POD nor CODE!?" + =cut back + print "got $a\n"; + +You probably shouldn't rely upon the warn() being podded out forever. +Not all pod translators are well-behaved in this regard, and perhaps +the compiler will become pickier. diff --git a/pod/perltie.pod b/pod/perltie.pod new file mode 100644 index 0000000..7898700 --- /dev/null +++ b/pod/perltie.pod @@ -0,0 +1,609 @@ +=head1 NAME + +perltie - how to hide an object class in a simple variable + +=head1 SYNOPSIS + + tie VARIABLE, CLASSNAME, LIST + + untie VARIABLE + +=head1 DESCRIPTION + +Prior to release 5.0 of Perl, a programmer could use dbmopen() +to magically connect an on-disk database in the standard Unix dbm(3x) +format to a %HASH in their program. However, their Perl was either +built with one particular dbm library or another, but not both, and +you couldn't extend this mechanism to other packages or types of variables. + +Now you can. + +The tie() function binds a variable to a class (package) that will provide +the implementation for access methods for that variable. Once this magic +has been performed, accessing a tied variable automatically triggers +method calls in the proper class. All of the complexity of the class is +hidden behind magic methods calls. The method names are in ALL CAPS, +which is a convention that Perl uses to indicate that they're called +implicitly rather than explicitly--just like the BEGIN() and END() +functions. + +In the tie() call, C is the name of the variable to be +enchanted. C is the name of a class implementing objects of +the correct type. Any additional arguments in the C are passed to +the appropriate constructor method for that class--meaning TIESCALAR(), +TIEARRAY(), or TIEHASH(). (Typically these are arguments such as might be +passed to the dbminit() function of C.) The object returned by the "new" +method is also returned by the tie() function, which would be useful if +you wanted to access other methods in C. (You don't actually +have to return a reference to a right "type" (e.g. HASH or C) +so long as it's a properly blessed object.) + + +Unlike dbmopen(), the tie() function will not C or C a module +for you--you need to do that explicitly yourself. + +=head2 Tying Scalars + +A class implementing a tied scalar should define the following methods: +TIESCALAR, FETCH, STORE, and possibly DESTROY. + +Let's look at each in turn, using as an example a tie class for +scalars that allows the user to do something like: + + tie $his_speed, 'Nice', getppid(); + tie $my_speed, 'Nice', $$; + +And now whenever either of those variables is accessed, its current +system priority is retrieved and returned. If those variables are set, +then the process's priority is changed! + +We'll use Jarkko Hietaniemi FJarkko.Hietaniemi@hut.fiE>'s +BSD::Resource class (not included) to access the PRIO_PROCESS, PRIO_MIN, +and PRIO_MAX constants from your system, as well as the getpriority() and +setpriority() system calls. Here's the preamble of the class. + + package Nice; + use Carp; + use BSD::Resource; + use strict; + $Nice::DEBUG = 0 unless defined $Nice::DEBUG; + +=over + +=item TIESCALAR classname, LIST + +This is the constructor for the class. That means it is +expected to return a blessed reference to a new scalar +(probably anonymous) that it's creating. For example: + + sub TIESCALAR { + my $class = shift; + my $pid = shift || $$; # 0 means me + + if ($pid !~ /^\d+$/) { + carp "Nice::TieScalar got non-numeric pid $pid" if $^W; + return undef; + } + + unless (kill 0, $pid) { # EPERM or ERSCH, no doubt + carp "Nice::TieScalar got bad pid $pid: $!" if $^W; + return undef; + } + + return bless \$pid, $class; + } + +This tie class has chosen to return an error rather than raising an +exception if its constructor should fail. While this is how dbmopen() works, +other classes may well not wish to be so forgiving. It checks the global +variable C<$^W> to see whether to emit a bit of noise anyway. + +=item FETCH this + +This method will be triggered every time the tied variable is accessed +(read). It takes no arguments beyond its self reference, which is the +object representing the scalar we're dealing with. Since in this case +we're just using a SCALAR ref for the tied scalar object, a simple $$self +allows the method to get at the real value stored there. In our example +below, that real value is the process ID to which we've tied our variable. + + sub FETCH { + my $self = shift; + confess "wrong type" unless ref $self; + croak "usage error" if @_; + my $nicety; + local($!) = 0; + $nicety = getpriority(PRIO_PROCESS, $$self); + if ($!) { croak "getpriority failed: $!" } + return $nicety; + } + +This time we've decided to blow up (raise an exception) if the renice +fails--there's no place for us to return an error otherwise, and it's +probably the right thing to do. + +=item STORE this, value + +This method will be triggered every time the tied variable is set +(assigned). Beyond its self reference, it also expects one (and only one) +argument--the new value the user is trying to assign. + + sub STORE { + my $self = shift; + confess "wrong type" unless ref $self; + my $new_nicety = shift; + croak "usage error" if @_; + + if ($new_nicety < PRIO_MIN) { + carp sprintf + "WARNING: priority %d less than minimum system priority %d", + $new_nicety, PRIO_MIN if $^W; + $new_nicety = PRIO_MIN; + } + + if ($new_nicety > PRIO_MAX) { + carp sprintf + "WARNING: priority %d greater than maximum system priority %d", + $new_nicety, PRIO_MAX if $^W; + $new_nicety = PRIO_MAX; + } + + unless (defined setpriority(PRIO_PROCESS, $$self, $new_nicety)) { + confess "setpriority failed: $!"; + } + return $new_nicety; + } + +=item DESTROY this + +This method will be triggered when the tied variable needs to be destructed. +As with other object classes, such a method is seldom ncessary, since Perl +deallocates its moribund object's memory for you automatically--this isn't +C++, you know. We'll use a DESTROY method here for debugging purposes only. + + sub DESTROY { + my $self = shift; + confess "wrong type" unless ref $self; + carp "[ Nice::DESTROY pid $$self ]" if $Nice::DEBUG; + } + +=back + +That's about all there is to it. Actually, it's more than all there +is to it, since we've done a few nice things here for the sake +of completeness, robustness, and general aesthetics. Simpler +TIESCALAR classes are certainly possible. + +=head2 Tying Arrays + +A class implementing a tied ordinary array should define the following +methods: TIEARRAY, FETCH, STORE, and perhaps DESTROY. + +B: Tied arrays are I. They are also distinctly lacking +something for the C<$#ARRAY> access (which is hard, as it's an lvalue), as +well as the other obvious array functions, like push(), pop(), shift(), +unshift(), and splice(). + +For this discussion, we'll implement an array whose indices are fixed at +its creation. If you try to access anything beyond those bounds, you'll +take an exception. (Well, if you access an individual element; an +aggregate assignment would be missed.) For example: + + require Bounded_Array; + tie @ary, Bounded_Array, 2; + $| = 1; + for $i (0 .. 10) { + print "setting index $i: "; + $ary[$i] = 10 * $i; + $ary[$i] = 10 * $i; + print "value of elt $i now $ary[$i]\n"; + } + +The preamble code for the class is as follows: + + package Bounded_Array; + use Carp; + use strict; + +=over + +=item TIEARRAY classname, LIST + +This is the constructor for the class. That means it is expected to +return a blessed reference through which the new array (probably an +anonymous ARRAY ref) will be accessed. + +In our example, just to show you that you don't I have to return an +ARRAY reference, we'll choose a HASH reference to represent our object. +A HASH works out well as a generic record type: the C<{BOUND}> field will +store the maximum bound allowed, and the C<{ARRAY} field will hold the +true ARRAY ref. If someone outside the class tries to dereference the +object returned (doubtless thinking it an ARRAY ref), they'll blow up. +This just goes to show you that you should respect an object's privacy. + + sub TIEARRAY { + my $class = shift; + my $bound = shift; + confess "usage: tie(\@ary, 'Bounded_Array', max_subscript)" + if @_ || $bound =~ /\D/; + return bless { + BOUND => $bound, + ARRAY => [], + }, $class; + } + +=item FETCH this, index + +This method will be triggered every time an individual element the tied array +is accessed (read). It takes one argument beyond its self reference: the +index whose value we're trying to fetch. + + sub FETCH { + my($self,$idx) = @_; + if ($idx > $self->{BOUND}) { + confess "Array OOB: $idx > $self->{BOUND}"; + } + return $self->{ARRAY}[$idx]; + } + +As you may have noticed, the name of the FETCH method (et al.) is the same +for all accesses, even though the constructors differ in names (TIESCALAR +vs TIEARRAY). While in theory you could have the same class servicing +several tied types, in practice this becomes cumbersome, and it's easiest +to simply keep them at one tie type per class. + +=item STORE this, index, value + +This method will be triggered every time an element in the tied array is set +(written). It takes two arguments beyond its self reference: the index at +which we're trying to store something and the value we're trying to put +there. For example: + + sub STORE { + my($self, $idx, $value) = @_; + print "[STORE $value at $idx]\n" if _debug; + if ($idx > $self->{BOUND} ) { + confess "Array OOB: $idx > $self->{BOUND}"; + } + return $self->{ARRAY}[$idx] = $value; + } + +=item DESTROY this + +This method will be triggered when the tied variable needs to be destructed. +As with the sclar tie class, this is almost never needed in a +language that does its own garbage collection, so this time we'll +just leave it out. + +=back + +The code we presented at the top of the tied array class accesses many +elements of the array, far more than we've set the bounds to. Therefore, +it will blow up once they try to access beyond the 2nd element of @ary, as +the following output demonstrates: + + setting index 0: value of elt 0 now 0 + setting index 1: value of elt 1 now 10 + setting index 2: value of elt 2 now 20 + setting index 3: Array OOB: 3 > 2 at Bounded_Array.pm line 39 + Bounded_Array::FETCH called at testba line 12 + +=head2 Tying Hashes + +As the first Perl data type to be tied (see dbmopen()), associative arrays +have the most complete and useful tie() implementation. A class +implementing a tied associative array should define the following +methods: TIEHASH is the constructor. FETCH and STORE access the key and +value pairs. EXISTS reports whether a key is present in the hash, and +DELETE deletes one. CLEAR empties the hash by deleting all the key and +value pairs. FIRSTKEY and NEXTKEY implement the keys() and each() +functions to iterate over all the keys. And DESTROY is called when the +tied variable is garbage collected. + +If this seems like a lot, then feel free to merely inherit +from the standard TieHash module for most of your methods, redefining only +the interesting ones. See L for details. + +Remember that Perl distinguishes between a key not existing in the hash, +and the key existing in the hash but having a corresponding value of +C. The two possibilities can be tested with the C and +C functions. + +Here's an example of a somewhat interesting tied hash class: it gives you +a hash representing a particular user's dotfiles. You index into the hash +with the name of the file (minus the dot) and you get back that dotfile's +contents. For example: + + use DotFiles; + tie %dot, DotFiles; + if ( $dot{profile} =~ /MANPATH/ || + $dot{login} =~ /MANPATH/ || + $dot{cshrc} =~ /MANPATH/ ) + { + print "you seem to set your manpath\n"; + } + +Or here's another sample of using our tied class: + + tie %him, DotFiles, 'daemon'; + foreach $f ( keys %him ) { + printf "daemon dot file %s is size %d\n", + $f, length $him{$f}; + } + +In our tied hash DotFiles example, we use a regular +hash for the object containing several important +fields, of which only the C<{LIST}> field will be what the +user thinks of as the real hash. + +=over 5 + +=item USER + +whose dot files this object represents + +=item HOME + +where those dotfiles live + +=item CLOBBER + +whether we should try to change or remove those dot files + +=item LIST + +the hash of dotfile names and content mappings + +=back + +Here's the start of F: + + package DotFiles; + use Carp; + sub whowasi { (caller(1))[3] . '()' } + my $DEBUG = 0; + sub debug { $DEBUG = @_ ? shift : 1 } + +For our example, we want to able to emit debugging info to help in tracing +during development. We keep also one convenience function around +internally to help print out warnings; whowasi() returns the function name +that calls it. + +Here are the methods for the DotFiles tied hash. + +=over + +=item TIEHASH classname, LIST + +This is the constructor for the class. That means it is expected to +return a blessed reference through which the new object (probably but not +necessarily an anonymous hash) will be accessed. + +Here's the constructor: + + sub TIEHASH { + my $self = shift; + my $user = shift || $>; + my $dotdir = shift || ''; + croak "usage: @{[&whowasi]} [USER [DOTDIR]]" if @_; + $user = getpwuid($user) if $user =~ /^\d+$/; + my $dir = (getpwnam($user))[7] + || croak "@{[&whowasi]}: no user $user"; + $dir .= "/$dotdir" if $dotdir; + + my $node = { + USER => $user, + HOME => $dir, + LIST => {}, + CLOBBER => 0, + }; + + opendir(DIR, $dir) + || croak "@{[&whowasi]}: can't opendir $dir: $!"; + foreach $dot ( grep /^\./ && -f "$dir/$_", readdir(DIR)) { + $dot =~ s/^\.//; + $node->{LIST}{$dot} = undef; + } + closedir DIR; + return bless $node, $self; + } + +It's probably worth mentioning that if you're going 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. + +=item FETCH this, key + +This method will be triggered every time an element in the tied hash is +accessed (read). It takes one argument beyond its self reference: the key +whose value we're trying to fetch. + +Here's the fetch for our DotFiles example. + + sub FETCH { + carp &whowasi if $DEBUG; + my $self = shift; + my $dot = shift; + my $dir = $self->{HOME}; + my $file = "$dir/.$dot"; + + unless (exists $self->{LIST}->{$dot} || -f $file) { + carp "@{[&whowasi]}: no $dot file" if $DEBUG; + return undef; + } + + if (defined $self->{LIST}->{$dot}) { + return $self->{LIST}->{$dot}; + } else { + return $self->{LIST}->{$dot} = `cat $dir/.$dot`; + } + } + +It was easy to write by having it call the Unix cat(1) command, but it +would probably be more portable to open the file manually (and somewhat +more efficient). Of course, since dot files are a Unixy concept, we're +not that concerned. + +=item STORE this, key, value + +This method will be triggered every time an element in the tied hash is set +(written). It takes two arguments beyond its self reference: the index at +which we're trying to store something, and the value we're trying to put +there. + +Here in our DotFiles example, we'll be careful not to let +them try to overwrite the file unless they've called the clobber() +method on the original object reference returned by tie(). + + sub STORE { + carp &whowasi if $DEBUG; + my $self = shift; + my $dot = shift; + my $value = shift; + my $file = $self->{HOME} . "/.$dot"; + my $user = $self->{USER}; + + croak "@{[&whowasi]}: $file not clobberable" + unless $self->{CLOBBER}; + + open(F, "> $file") || croak "can't open $file: $!"; + print F $value; + close(F); + } + +If they wanted to clobber something, they might say: + + $ob = tie %daemon_dots, 'daemon'; + $ob->clobber(1); + $daemon_dots{signature} = "A true daemon\n"; + +Where the clobber method is simply: + + sub clobber { + my $self = shift; + $self->{CLOBBER} = @_ ? shift : 1; + } + +=item DELETE this, key + +This method is triggered when we remove an element from the hash, +typically by using the delete() function. Again, we'll +be careful to check whether they really want to clobber files. + + sub DELETE { + carp &whowasi if $DEBUG; + + my $self = shift; + my $dot = shift; + my $file = $self->{HOME} . "/.$dot"; + croak "@{[&whowasi]}: won't remove file $file" + unless $self->{CLOBBER}; + delete $self->{LIST}->{$dot}; + unlink($file) || carp "@{[&whowasi]}: can't unlink $file: $!"; + } + +=item CLEAR this + +This method is triggered when the whole hash is to be cleared, usually by +assigning the empty list to it. + +In our example, that would remove all the user's dotfiles! It's such a +dangerous thing that they'll have to set CLOBBER to something higher than +1 to make it happen. + + sub CLEAR { + carp &whowasi if $DEBUG; + my $self = shift; + croak "@{[&whowasi]}: won't remove all dotfiles for $self->{USER}" + unless $self->{CLOBBER} > 1; + my $dot; + foreach $dot ( keys %{$self->{LIST}}) { + $self->DELETE($dot); + } + } + +=item EXISTS this, key + +This method is triggered when the user uses the exists() function +on a particular hash. In our example, we'll look at the C<{LIST}> +hash element for this: + + sub EXISTS { + carp &whowasi if $DEBUG; + my $self = shift; + my $dot = shift; + return exists $self->{LIST}->{$dot}; + } + +=item FIRSTKEY this + +This method will be triggered when the user is going +to iterate through the hash, such as via a keys() or each() +call. + + sub FIRSTKEY { + carp &whowasi if $DEBUG; + my $self = shift; + my $a = keys %{$self->{LIST}}; + each %{$self->{LIST}} + } + +=item NEXTKEY this, lastkey + +This method gets triggered during a keys() or each() iteration. It has a +second argument which is the last key that had been accessed. This is +useful if you're carrying about ordering or calling the iterator from more +than one sequence, or not really storing things in a hash anywhere. + +For our example, we our using a real hash so we'll just do the simple +thing, but we'll have to indirect through the LIST field. + + sub NEXTKEY { + carp &whowasi if $DEBUG; + my $self = shift; + return each %{ $self->{LIST} } + } + +=item DESTROY this + +This method is triggered when a tied hash is about to go out of +scope. You don't really need it unless you're trying to add debugging +or have auxiliary state to clean up. Here's a very simple function: + + sub DESTROY { + carp &whowasi if $DEBUG; + } + +=back + +Note that functions such as keys() and values() may return huge array +values when used on large objects, like DBM files. You may prefer to +use the each() function to iterate over such. Example: + + # print out history file offsets + use NDBM_File; + tie(%HIST, NDBM_File, '/usr/lib/news/history', 1, 0); + while (($key,$val) = each %HIST) { + print $key, ' = ', unpack('L',$val), "\n"; + } + untie(%HIST); + +=head2 Tying FileHandles + +This isn't implemented yet. Sorry; maybe someday. + +=head1 SEE ALSO + +See L or L for some interesting tie() implementations. + +=head1 BUGS + +Tied arrays are I. They are also distinctly lacking something +for the C<$#ARRAY> access (which is hard, as it's an lvalue), as well as +the other obvious array functions, like push(), pop(), shift(), unshift(), +and splice(). + +=head1 AUTHOR + +Tom Christiansen diff --git a/pod/perltoc.pod b/pod/perltoc.pod new file mode 100644 index 0000000..4de2350 --- /dev/null +++ b/pod/perltoc.pod @@ -0,0 +1,2783 @@ + +=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. + +=head1 BASIC DOCUMENTATION + + + + +=head2 perl - Practical Extraction and Report Language + +=item SYNOPSIS + + +=item DESCRIPTION + + +Many usability enhancements, Simplified grammar, Lexical scoping, +Arbitrarily nested data structures, Modularity and reusability, +Object-oriented programming, Embeddible and Extensible, POSIX +compliant, Package constructors and destructors, Multiple simultaneous +DBM implementations, Subroutine definitions may now be autoloaded, +Regular expression enhancements + +=item ENVIRONMENT + + +HOME, LOGDIR, PATH, PERL5LIB, PERL5DB, PERLLIB + +=item AUTHOR + + +=item FILES + + +=item SEE ALSO + + +=item DIAGNOSTICS + + +=item BUGS + + +=item NOTES + + + + + +=head2 perldata - Perl data types + +=item DESCRIPTION + + +=over + +=item Variable names + + +=item Context + + +=item Scalar values + + +=item Scalar value constructors + + +=item List value constructors + + +=item Typeglobs and FileHandles + + + + +=back + + + + +=head2 perlsyn - Perl syntax + +=item DESCRIPTION + + +=over + +=item Declarations + + +=item Simple statements + + +=item Compound statements + + +=item Loop Control + + +=item For Loops + + +=item Foreach Loops + + +=item Basic BLOCKs and Switch Statements + + +=item Goto + + +=item PODs: Embedded Documentation + + + + +=back + + + + +=head2 perlop - Perl operators and precedence + +=item SYNOPSIS + + +=item DESCRIPTION + + +=over + +=item Terms and List Operators (Leftward) + + +=item The Arrow Operator + + +=item Autoincrement and Autodecrement + + +=item Exponentiation + + +=item Symbolic Unary Operators + + +=item Binding Operators + + +=item Multiplicative Operators + + +=item Additive Operators + + +=item Shift Operators + + +=item Named Unary Operators + + +=item Relational Operators + + +=item Equality Operators + + +=item Bitwise And + + +=item Bitwise Or and Exclusive Or + + +=item C-style Logical And + + +=item C-style Logical Or + + +=item Range Operator + + +=item Conditional Operator + + +=item Assignment Operators + + +=item Comma Operator + + +=item List Operators (Rightward) + + +=item Logical Not + + +=item Logical And + + +=item Logical or and Exclusive Or + + +=item C Operators Missing From Perl + + +unary &, unary *, (TYPE) + +=item Quote and Quotelike Operators + + +=item Regexp Quotelike Operators + + +?PATTERN?, m/PATTERN/gimosx, /PATTERN/gimosx, q/STRING/, C<'STRING'>, +qq/STRING/, "STRING", qx/STRING/, `STRING`, qw/STRING/, +s/PATTERN/REPLACEMENT/egimosx, tr/SEARCHLIST/REPLACEMENTLIST/cds, +y/SEARCHLIST/REPLACEMENTLIST/cds + +=item I/O Operators + + +=item Constant Folding + + +=item Integer arithmetic + + + + +=back + + + + +=head2 perlre - Perl regular expressions + +=item DESCRIPTION + + +=over + +=item Regular Expressions + + +(?#text), (?:regexp), (?=regexp), (?!regexp), (?imsx) + +=item Version 8 Regular Expressions + + +=item WARNING on \1 vs $1 + + + + +=back + + + + +=head2 perlrun - how to execute the Perl interpreter + +=item SYNOPSIS + + +=item DESCRIPTION + + +=over + +=item Switches + + +B<-0>I, B<-a>, B<-c>, B<-d>, B<-D>I, B<-D>I, +B<-e> I, B<-F>I, B<-i>I, +B<-I>I, B<-l>I, B<-n>, B<-p>, B<-P>, B<-s>, B<-S>, +B<-T>, B<-u>, B<-U>, B<-v>, B<-w>, B<-x> I + + + +=back + + + + +=head2 perlfunc - Perl builtin functions + +=item DESCRIPTION + + + + +=over + +=item Perl Functions by Category + + +Functions for SCALARs or strings, Regular expressions and pattern +matching, Numeric functions, Functions for real @ARRAYs, Functions for +list data, Functions for real %HASHes, Input and output functions, +Functions for fixed length data or records, Functions for filehandles, +files, or directories, Keywords related to the control flow of your +perl program, Keywords related to scoping, Miscellaneous functions, +Functions for processes and process groups, Keywords related to perl +modules, Keywords related to classes and object-orientedness, Low-level +socket functions, System V interprocess communication functions, +Fetching user and group info, Fetching network info, Time-related +functions + +=item Alphabetical Listing of Perl Functions + + +-X FILEHANDLE, -X EXPR, -X, abs VALUE, accept NEWSOCKET,GENERICSOCKET, +alarm SECONDS, atan2 Y,X, bind SOCKET,NAME, binmode FILEHANDLE, bless +REF,CLASSNAME, bless REF, caller EXPR, caller, chdir EXPR, chmod LIST, +chomp VARIABLE, chomp LIST, chomp, chop VARIABLE, chop LIST, chop, +chown LIST, chr NUMBER, chroot FILENAME, close FILEHANDLE, closedir +DIRHANDLE, connect SOCKET,NAME, continue BLOCK, cos EXPR, crypt +PLAINTEXT,SALT, dbmclose ASSOC_ARRAY, dbmopen ASSOC,DBNAME,MODE, +defined EXPR, delete EXPR, die LIST, do BLOCK, do SUBROUTINE(LIST), do +EXPR, dump LABEL, each ASSOC_ARRAY, eof FILEHANDLE, eof (), eof, eval +EXPR, eval BLOCK, exec LIST, exists EXPR, exit EXPR, exp EXPR, fcntl +FILEHANDLE,FUNCTION,SCALAR, fileno FILEHANDLE, flock +FILEHANDLE,OPERATION, fork, format, formline PICTURE, LIST, getc +FILEHANDLE, getc, getlogin, getpeername SOCKET, getpgrp PID, getppid, +getpriority WHICH,WHO, getpwnam NAME, getgrnam NAME, gethostbyname +NAME, getnetbyname NAME, getprotobyname NAME, getpwuid UID, getgrgid +GID, getservb + + + +=back + + + + +=head2 perlvar - Perl predefined variables + +=item DESCRIPTION + + +=over + +=item Predefined Names + + +$ARG, $_, $>, $MATCH, $&, $PREMATCH, $`, $POSTMATCH, $', +$LAST_PAREN_MATCH, $+, $MULTILINE_MATCHING, $*, input_line_number +HANDLE EXPR, $INPUT_LINE_NUMBER, $NR, $, input_record_separator HANDLE +EXPR, $INPUT_RECORD_SEPARATOR, $RS, $/, autoflush HANDLE EXPR, +$OUTPUT_AUTOFLUSH, $|, output_field_separator HANDLE EXPR, +$OUTPUT_FIELD_SEPARATOR, $OFS, $,, output_record_separator HANDLE EXPR, +$OUTPUT_RECORD_SEPARATOR, $ORS, $\, $LIST_SEPARATOR, $", +$SUBSCRIPT_SEPARATOR, $SUBSEP, $;, $OFMT, $#, format_page_number HANDLE +EXPR, $FORMAT_PAGE_NUMBER, $%, format_lines_per_page HANDLE EXPR, +$FORMAT_LINES_PER_PAGE, $=, format_lines_left HANDLE EXPR, +$FORMAT_LINES_LEFT, $-, format_name HANDLE EXPR, $FORMAT_NAME, $~, +format_top_name HANDLE EXPR, $FORMAT_TOP_NAME, $^, +format_line_break_characters HANDLE EXPR, +$FORMAT_LINE_BREAK_CHARACTERS, $:, format_formfeed HANDLE EXPR, +$FORMAT_FORMFEED, $^L, $ACCUMULATOR, $^A, $CHILD_ERROR, $?, $OS_ERROR, +$ERRNO, $!, $EVAL_ERROR, $@, $PROCESS_ID, $PID, $$, $REAL_USER_ID, +$UID, $<, + + + +=back + + + + +=head2 perlsub - Perl subroutines + +=item SYNOPSIS + + +=item DESCRIPTION + + +=over + +=item Private Variables via my() + + +=item Temporary Values via local() + + +=item Passing Symbol Table Entries (typeglobs) + + +=item Pass by Reference + + +=item Prototypes + + +=item Overriding Builtin Functions + + +=item Autoloading + + + + +=back + +=item SEE ALSO + + + + + +=head2 perlmod - Perl modules (packages) + +=item DESCRIPTION + + +=over + +=item Packages + + +=item Symbol Tables + + +=item Package Constructors and Destructors + + +=item Perl Classes + + +=item Perl Modules + + + + +=back + +=item NOTE + + +=item THE PERL MODULE LIBRARY + + +=over + +=item Pragmatic Modules + + +diagnostics, integer, less, overload, sigtrap, strict, subs + +=item Standard Modules + + +AnyDBM_File, AutoLoader, AutoSplit, Benchmark, Carp, Config, Cwd, +DB_File, Devel::SelfStubber, DynaLoader, English, Env, Exporter, +ExtUtils::Liblist, ExtUtils::MakeMaker, ExtUtils::Manifest, +ExtUtils::Mkbootstrap, ExtUtils::Miniperl, Fcntl, File::Basename, +File::CheckTree, File::Find, FileHandle, File::Path, Getopt::Long, +Getopt::Std, I18N::Collate, IPC::Open2, IPC::Open3, Net::Ping, POSIX, +SelfLoader, Socket, Test::Harness, Text::Abbrev + +=item Extension Modules + + + + +=back + +=item CPAN + + +Language Extensions and Documentation Tools, Development Support, +Operating System Interfaces, Networking, Device Control (modems) and +InterProcess Communication, Data Types and Data Type Utilities, +Database Interfaces, User Interfaces, Interfaces to / Emulations of +Other Programming Languages, File Names, File Systems and File Locking +(see also File Handles), String Processing, Language Text Processing, +Parsing and Searching, Option, Argument, Parameter and Configuration +File Processing, Internationalization and Locale, Authentication, +Security and Encryption, World Wide Web, HTML, HTTP, CGI, MIME, Server +and Daemon Utilities, Archiving and Compression, Images, Pixmap and +Bitmap Manipulation, Drawing and Graphing, Mail and Usenet News, +Control Flow Utilities (callbacks and exceptions etc), File Handle and +Input/Output Stream Utilities, Miscellaneous Modules + +=item Modules: Creation, Use and Abuse + + +=over + +=item Guidelines for Module Creation + + +Do similar modules already exist in some form?, Try to design the new +module to be easy to extend and reuse, Some simple style guidelines, +Select what to export, Select a name for the module, Have you got it +right?, README and other Additional Files, A description of the +module/package/extension etc, A copyright notice - see below, +Prerequisites - what else you may need to have, How to build it - +possible changes to Makefile.PL etc, How to install it, Recent changes +in this release, especially incompatibilities, Changes / enhancements +you plan to make in the future, Adding a Copyright Notice, Give the +module a version/issue/release number, How to release and distribute a +module, Take care when changing a released module + +=item Guidelines for Converting Perl 4 Library Scripts into Modules + + +There is no requirement to convert anything, Consider the implications, +Make the most of the opportunity, The pl2pm utility will get you +started, Adds the standard Module prologue lines, Converts package +specifiers from ' to ::, Converts die(...) to croak(...), Several other +minor changes + +=item Guidelines for Reusing Application Code + + +Complete applications rarely belong in the Perl Module Library, Many +applications contain some perl code which could be reused, Break-out +the reusable code into one or more separate module files, Take the +opportunity to reconsider and redesign the interfaces, In some cases +the 'application' can then be reduced to a small + + + +=back + + + + +=head2 perlref - Perl references and nested data structures + +=item DESCRIPTION + + +=over + +=item Symbolic references + + +=item Not-so-symbolic references + + + + +=back + +=item WARNING + + +=item SEE ALSO + + + + + +=head2 perldsc - Perl Data Structures Cookbook + +=item DESCRIPTION + + +arrays of arrays, hashes of arrays, arrays of hashes, hashes of hashes, +more elaborate constructs, recursive and self-referential data +structures, objects + +=item REFERENCES + + +=item COMMON MISTAKES + + +=item CAVEAT ON PRECEDENCE + + +=item WHY YOU SHOULD ALWAYS C + + +=item DEBUGGING + + +=item CODE EXAMPLES + + +=item LISTS OF LISTS + + +=over + +=item Declaration of a LIST OF LISTS + + +=item Generation of a LIST OF LISTS + + +=item Access and Printing of a LIST OF LISTS + + + + +=back + +=item HASHES OF LISTS + + +=over + +=item Declaration of a HASH OF LISTS + + +=item Generation of a HASH OF LISTS + + +=item Access and Printing of a HASH OF LISTS + + + + +=back + +=item LISTS OF HASHES + + +=over + +=item Declaration of a LIST OF HASHES + + +=item Generation of a LIST OF HASHES + + +=item Access and Printing of a LIST OF HASHES + + + + +=back + +=item HASHES OF HASHES + + +=over + +=item Declaration of a HASH OF HASHES + + +=item Generation of a HASH OF HASHES + + +=item Access and Printing of a HASH OF HASHES + + + + +=back + +=item MORE ELABORATE RECORDS + + +=over + +=item Declaration of MORE ELABORATE RECORDS + + +=item Declaration of a HASH OF COMPLEX RECORDS + + +=item Generation of a HASH OF COMPLEX RECORDS + + + + +=back + +=item SEE ALSO + + +=item AUTHOR + + + + + +=head2 perllol, perlLoL - Manipulating Lists of Lists in Perl + +=item DESCRIPTION + + +=item Declaration and Access of Lists of Lists + + +=item Growing Your Own + + +=item Access and Printing + + +=item Slices + + +=item SEE ALSO + + +=item AUTHOR + + + + + +=head2 perlobj - Perl objects + +=item DESCRIPTION + + +=over + +=item An Object is Simply a Reference + + +=item A Class is Simply a Package + + +=item A Method is Simply a Subroutine + + +=item Method Invocation + + +=item Destructors + + +=item WARNING + + +=item Summary + + +=item Two-Phased Garbage Collection + + + + +=back + +=item SEE ALSO + + + + + +=head2 perltie - how to hide an object class in a simple variable + +=item SYNOPSIS + + +=item DESCRIPTION + + +=over + +=item Tying Scalars + + +TIESCALAR classname, LIST, FETCH this, STORE this, value, DESTROY this + +=item Tying Arrays + + +TIEARRAY classname, LIST, FETCH this, index, STORE this, index, value, +DESTROY this + +=item Tying Hashes + + +USER, HOME, CLOBBER, LIST, TIEHASH classname, LIST, FETCH this, key, +STORE this, key, value, DELETE this, key, CLEAR this, EXISTS this, key, +FIRSTKEY this, NEXTKEY this, lastkey, DESTROY this + +=item Tying FileHandles + + + + +=back + +=item SEE ALSO + + +=item BUGS + + +=item AUTHOR + + + + + +=head2 perlbot - Bag'o Object Tricks (the BOT) + +=item DESCRIPTION + + +=item OO SCALING TIPS + + +=item INSTANCE VARIABLES + + +=item SCALAR INSTANCE VARIABLES + + +=item INSTANCE VARIABLE INHERITANCE + + +=item OBJECT RELATIONSHIPS + + +=item OVERRIDING SUPERCLASS METHODS + + +=item USING RELATIONSHIP WITH SDBM + + +=item THINKING OF CODE REUSE + + +=item CLASS CONTEXT AND THE OBJECT + + +=item INHERITING A CONSTRUCTOR + + +=item DELEGATION + + + + + +=head2 perldebug - Perl debugging + +=item DESCRIPTION + + +=over + +=item Debugging + + +h, T, s, n, f, c, c line, , l min+incr, l min-max, l line, l, -, w +line, l subname, /pattern/, ?pattern?, L, S, t, b line [ condition ], b +subname [ condition ], d line, D, a line command, A, < command, > +command, V package [symbols], X [symbols], ! number, ! -number, H +-number, q or ^D, command, p expr + +=item Customization + + +=item Other resources + + + + +=back + +=item BUGS + + + + + +=head2 perldiag - various Perl diagnostics + +=item DESCRIPTION + + + + + +=head2 perlform - Perl formats + +=item DESCRIPTION + + +=over + +=item Format Variables + + + + +=back + +=item NOTES + + +=over + +=item Footers + + +=item Accessing Formatting Internals + + + + +=back + +=item WARNING + + + + + +=head2 perlipc - Perl interprocess communication (signals, fifos, +pipes, safe subprocceses, sockets, and semaphores) + +=item DESCRIPTION + + +=item Signals + + +=item Named Pipes + + +=item Using open() for IPC + + +=over + +=item Safe Pipe Opens + + +=item Bidirectional Communication + + + + +=back + +=item Sockets: Client/Server Communication + + +=over + +=item Internet TCP Clients and Servers + + +=item Unix-Domain TCP Clients and Servers + + +=item UDP: Message Passing + + + + +=back + +=item SysV IPC + + +=item WARNING + + +=item NOTES + + +=item BUGS + + +=item AUTHOR + + +=item SEE ALSO + + + + + +=head2 perlsec - Perl security + +=item DESCRIPTION + + + + + +=head2 perltrap - Perl traps for the unwary + +=item DESCRIPTION + + +=over + +=item Awk Traps + + +=item C Traps + + +=item Sed Traps + + +=item Shell Traps + + +=item Perl Traps + + +=item Perl4 Traps + + + + +=back + + + + +=head2 perlstyle - Perl style guide + +=item DESCRIPTION + + + + + +=head2 perlxs - XS language reference manual + +=item DESCRIPTION + + +=over + +=item Introduction + + +=item On The Road + + +=item The Anatomy of an XSUB + + +=item The Argument Stack + + +=item The RETVAL Variable + + +=item The MODULE Keyword + + +=item The PACKAGE Keyword + + +=item The PREFIX Keyword + + +=item The OUTPUT: Keyword + + +=item The CODE: Keyword + + +=item The NO_INIT Keyword + + +=item Initializing Function Parameters + + +=item Default Parameter Values + + +=item Variable-length Parameter Lists + + +=item The PPCODE: Keyword + + +=item Returning Undef And Empty Lists + + +=item The REQUIRE: Keyword + + +=item The CLEANUP: Keyword + + +=item The BOOT: Keyword + + +=item Inserting Comments and C Preprocessor Directives + + +=item Using XS With C++ + + +=item Interface Strategy + + +=item Perl Objects And C Structures + + +=item The Typemap + + + + +=back + +=item EXAMPLES + + +=item AUTHOR + + + + + +=head2 perlxstut, perlXStut - Tutorial for XSUB's + +=item DESCRIPTION + + +=item EXAMPLE 1 + + +=item EXAMPLE 2 + + +=item WHAT HAS GONE ON? + + +=item EXAMPLE 3 + + +=item WHAT'S NEW HERE? + + +=item INPUT AND OUTPUT PARAMETERS + + +=item THE XSUBPP COMPILER + + +=item THE TYPEMAP FILE + + +=item WARNING + + +=item EXAMPLE 4 + + +=item Author + + +=item Last Changed + + + + + +=head2 perlguts - Perl's Internal Functions + +=item DESCRIPTION + + +=item Datatypes + + +=over + +=item What is an "IV"? + + +=item Working with SV's + + +=item What's Really Stored in an SV? + + +=item Working with AV's + + +=item Working with HV's + + +=item References + + +=item Blessed References and Class Objects + + + + +=back + +=item Creating New Variables + + +=item XSUB's and the Argument Stack + + +=item Mortality + + +=item Stashes + + +=item Magic + + +=over + +=item Assigning Magic + + +=item Magic Virtual Tables + + +=item Finding Magic + + + + +=back + +=item Double-Typed SV's + + +=item Calling Perl Routines from within C Programs + + +=item Memory Allocation + + +=item API LISTING + + +AvFILL, av_clear, av_extend, av_fetch, av_len, av_make, av_pop, +av_push, av_shift, av_store, av_undef, av_unshift, CLASS, Copy, croak, +CvSTASH, DBsingle, DBsub, dMARK, dORIGMARK, dSP, dXSARGS, ENTER, +EXTEND, FREETMPS, G_ARRAY, G_DISCARD, G_EVAL, GIMME, G_NOARGS, +G_SCALAR, gv_stashpv, gv_stashsv, GvSV, he_free, hv_clear, hv_delete, +hv_exists, hv_fetch, hv_iterinit, hv_iterkey, hv_iternext, +hv_iternextsv, hv_iterval, hv_magic, HvNAME, hv_store, hv_undef, +isALNUM, isALPHA, isDIGIT, isLOWER, isSPACE, isUPPER, items, LEAVE, +MARK, mg_clear, mg_copy, mg_find, mg_free, mg_get, mg_len, mg_magical, +mg_set, Move, na, New, Newc, Newz, newAV, newHV, newRV, newSV, newSViv, +newSVnv, newSVpv, newSVrv, newSVsv, newXS, newXSproto, Nullav, Nullch, +Nullcv, Nullhv, Nullsv, ORIGMARK, perl_alloc, perl_call_argv, +perl_call_method, perl_call_pv, perl_call_sv, perl_construct, +perl_destruct, perl_eval_sv, perl_free, perl_get_av, perl_get_cv, +perl_get_hv, perl_get_sv, perl_parse, perl_require_pv, perl_run, POPi, +POPl, POPp, POPn, POPs, + +=item AUTHOR + + +=item DATE + + + + + +=head2 perlcall - Perl calling conventions from C + +=item DESCRIPTION + + +An Error Handler, An Event Driven Program + +=item THE PERL_CALL FUNCTIONS + + +B, B, B, +B + +=item FLAG VALUES + + +=over + +=item G_SCALAR + + +=item G_ARRAY + + +=item G_DISCARD + + +=item G_NOARGS + + +=item G_EVAL + + +=item Determining the Context + + + + +=back + +=item KNOWN PROBLEMS + + +=item EXAMPLES + + +=over + +=item No Parameters, Nothing returned + + +=item Passing Parameters + + +=item Returning a Scalar + + +=item Returning a list of values + + +=item Returning a list in a scalar context + + +=item Returning Data from Perl via the parameter list + + +=item Using G_EVAL + + +=item Using perl_call_sv + + +=item Using perl_call_argv + + +=item Using perl_call_method + + +=item Using GIMME + + +=item Using Perl to dispose of temporaries + + +=item Strategies for storing Callback Context Information + + +1. Ignore the problem - Allow only 1 callback, 2. Create a sequence of +callbacks - hard wired limit, 3. Use a parameter to map to the Perl +callback + +=item Alternate Stack Manipulation + + + + +=back + +=item SEE ALSO + + +=item AUTHOR + + +=item DATE + + + + + +=head2 perlembed - how to embed perl in your C program + +=item DESCRIPTION + + +=over + +=item PREAMBLE + + +B, B, B, B, B + +=item ROADMAP + + +=item Compiling your C program + + +=item Adding a Perl interpreter to your C program + + +=item Calling a Perl subroutine from your C program + + +=item Evaluating a Perl statement from your C program + + +=item Performing Perl pattern matches and substitutions from your C +program + + + + +=back + +=item MORAL + + +=item AUTHOR + + + + + +=head2 perlpod - plain old documentation + +=item DESCRIPTION + + +=item Embedding Pods in Perl Modules + + +=item SEE ALSO + + +=item AUTHOR + + + + + +=head2 perlbook - Perl book information + +=item DESCRIPTION + + + + + +=head1 PRAGMA DOCUMENTATION + + + + +=head2 diagnostics - Perl compiler pragma to force verbose warning +diagnostics + +=item SYNOPSIS + + +=item DESCRIPTION + + +=over + +=item The C Pragma + + +=item The I Program + + + + +=back + +=item EXAMPLES + + +=item INTERNALS + + +=item BUGS + + +=item AUTHOR + + + + + +=head2 integer - Perl pragma to compute arithmetic in integer instead +of double + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 less - perl pragma to request less of something from the +compiler + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 lib - manipulate @INC at compile time + +=item SYNOPSIS + + +=item DESCRIPTION + + +=over + +=item ADDING DIRECTORIES TO @INC + + +=item DELETING DIRECTORIES FROM @INC + + +=item RESTORING ORIGINAL @INC + + + + +=back + +=item SEE ALSO + + +=item AUTHOR + + + + + +=head2 overload - Package for overloading perl operations + +=item SYNOPSIS + + +=item CAVEAT SCRIPTOR + + +=item DESCRIPTION + + +=over + +=item Declaration of overloaded functions + + +=item Calling Conventions for Binary Operations + + +FALSE, TRUE, C + +=item Calling Conventions for Unary Operations + + +=item Overloadable Operations + + +I, I, I, +I, I, I, I + + + +=back + +=item SPECIAL SYMBOLS FOR C + + +=over + +=item Last Resort + + +=item Fallback + + +C, TRUE, defined, but FALSE + +=item Copy Constructor + + +B + + + +=back + +=item MAGIC AUTOGENERATION + + +I, I, +I, C, I, +I, I, I + +=item WARNING + + +=item Run-time Overloading + + +=item Public functions + + +overload::StrVal(arg), overload::Overloaded(arg), +overload::Method(obj,op) + +=item IMPLEMENTATION + + +=item AUTHOR + + +=item DIAGNOSTICS + + +=item BUGS + + + + + +=head2 sigtrap - Perl pragma to enable stack backtrace on unexpected +signals + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 strict - Perl pragma to restrict unsafe constructs + +=item SYNOPSIS + + +=item DESCRIPTION + + +C, C, C + + + + +=head2 subs - Perl pragma to predeclare sub names + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head1 MODULE DOCUMENTATION + + + + +=head2 AnyDBM_File - provide framework for multiple DBMs + +=item SYNOPSIS + + +=item DESCRIPTION + + +=over + +=item DBM Comparisons + + +[0], [1], [2], [3] + + + +=back + +=item SEE ALSO + + + + + +=head2 AutoLoader - load functions only on demand + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 AutoSplit - split a package for autoloading + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 Benchmark - benchmark running times of code + +=item SYNOPSIS + + +=item DESCRIPTION + + +=over + +=item Methods + + +new, debug + +=item Standard Exports + + +timeit(COUNT, CODE), timethis, timethese, timediff, timestr + +=item Optional Exports + + + + +=back + +=item NOTES + + +=item INHERITANCE + + +=item CAVEATS + + +=item AUTHORS + + +=item MODIFICATION HISTORY + + + + + +=head2 Carp, carp - warn of errors (from perspective of caller) + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 Config - access Perl configuration option + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item EXAMPLE + + +=item NOTE + + + + + +=head2 Cwd, getcwd - get pathname of current working directory + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 DB_File - Perl5 access to Berkeley DB + +=item SYNOPSIS + + +=item DESCRIPTION + + +DB_HASH, DB_BTREE, DB_RECNO + +=over + +=item How does DB_File interface to Berkeley DB? + + +=item Differences with Berkeley DB + + +=item RECNO + + +=item In Memory Databases + + +=item Using the Berkeley DB Interface Directly + + +get, put, del, fd, seq, sync + + + +=back + +=item EXAMPLES + + +=over + +=item Using HASH + + +=item Using BTREE + + +=item Using RECNO + + +=item Locking Databases + + + + +=back + +=item HISTORY + + +=item WARNINGS + + +=item BUGS + + +=item AVAILABILITY + + +=item SEE ALSO + + +=item AUTHOR + + + + + +=head2 Devel::SelfStubber - generate stubs for a SelfLoading module + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 DynaLoader - Dynamically load C libraries into Perl code + +=item SYNOPSIS + + +=item DESCRIPTION + + +@dl_library_path, @dl_resolve_using, @dl_require_symbols, dl_error(), +$dl_debug, dl_findfile(), dl_expandspec(), dl_load_file(), +dl_find_symbol(), dl_undef_symbols(), dl_install_xsub(), boostrap() + +=item AUTHOR + + + + + +=head2 English - use nice English (or awk) names for ugly punctuation +variables + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 Env - perl module that imports environment variables + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item AUTHOR + + + + + +=head2 Exporter - provide inport/export controls for Perl modules + +=item SYNOPSIS + + +=item DESCRIPTION + + +=over + +=item Module Version Checking + + + + +=back + + + + +=head2 ExtUtils::Liblist - determine libraries to use and how to use +them + +=item SYNOPSIS + + +=item DESCRIPTION + + +For static extensions, For dynamic extensions, For dynamic extensions + +=over + +=item EXTRALIBS + + +=item LDLOADLIBS and LD_RUN_PATH + + +=item BSLOADLIBS + + + + +=back + +=item PORTABILITY + + +=item SEE ALSO + + + + + +=head2 ExtUtils::MakeMaker - create an extension Makefile + +=item SYNOPSIS + + +=item DESCRIPTION + + +=over + +=item Hintsfile support + + +=item What's new in version 5 of MakeMaker + + +=item Incompatibilities between MakeMaker 5.00 and 4.23 + + +=item Default Makefile Behaviour + + +=item Special case make install + + +=item PREFIX attribute + + +=item AFS users + + +=item Static Linking of a new Perl Binary + + +=item Determination of Perl Library and Installation Locations + + +=item Useful Default Makefile Macros + + +=item Using Attributes (and Parameters) + + +C, CONFIG, CONFIGURE, DEFINE, DIR, DISTNAME, DL_FUNCS, DL_VARS, +EXE_FILES, FIRST_MAKEFILE, FULLPERL, H, INC, INSTALLARCHLIB, +INSTALLBIN, INSTALLMAN1DIR, INSTALLMAN3DIR, INSTALLPRIVLIB, +INST_ARCHLIB, INST_EXE, INST_LIB, INST_MAN1DIR, INST_MAN3DIR, LDFROM, +LIBPERL_A, LIBS, LINKTYPE, MAKEAPERL, MAKEFILE, MAN1PODS, MAN3PODS, +MAP_TARGET, MYEXTLIB, NAME, NEEDS_LINKING, NORECURS, OBJECT, PERL, +PERLMAINCC, PERL_ARCHLIB, PERL_LIB, PERL_SRC, PL_FILES, PM, PMLIBDIRS, +PREFIX, PREREQ, SKIP, TYPEMAPS, VERSION, XS, XSOPT, XSPROTOARG + +=item Additional lowercase attributes + + +clean, dist, dynamic_lib, installpm, linkext, macro, realclean, +tool_autosplit + +=item Overriding MakeMaker Methods + + +=item Distribution Support + + + make distcheck, make skipcheck, make distclean, make + manifest, make distdir, make tardist, make dist, make + uutardist, make shdist, make ci + + + +=back + +=item AUTHORS + + +=item MODIFICATION HISTORY + + +=item TODO + + + + + +=head2 ExtUtils::Manifest - utilities to write and check a MANIFEST +file + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item MANIFEST.SKIP + + +=item EXPORT_OK + + +=item GLOBAL VARIABLES + + +=item DIAGNOSTICS + + +C I, C I, C +I<$!>, C I + +=item SEE ALSO + + +=item AUTHOR + + + + + +=head2 ExtUtils::Miniperl, writemain - write the C code for perlmain.c + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item SEE ALSO + + + + + +=head2 ExtUtils::Mkbootstrap, Mkbootstrap - make a bootstrap file for +use by DynaLoader + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 Fcntl - load the C Fcntl.h defines + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item NOTE + + + + + +=head2 File::Basename, Basename - parse file specifications + +=item SYNOPSIS + + +=item DESCRIPTION + + +fileparse_set_fstype, fileparse + +=item EXAMPLES + + +C, C + + + + +=head2 File::CheckTree, validate - run many filetest checks on a tree + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 File::Find, find - traverse a file tree + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 File::Path - create or remove a series of directories + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item AUTHORS + + +=item REVISION + + + + + +=head2 FileHandle - supply object methods for filehandles + +=item SYNOPSIS + + +=item DESCRIPTION + + +$fh->print, $fh->printf, $fh->getline, $fh->getlines + +=over + +=item The cacheout() Library + + + + +=back + +=item SEE ALSO + + +=item BUGS + + + + + +=head2 Getopt::Long, GetOptions - extended getopt processing + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item EXAMPLES + + +$autoabbrev, $getopt_compat, $option_start, $order, $ignorecase, $debug + +=item NOTE + + + + + +=head2 Getopt::Std, getopt - Process single-character switches with +switch clustering + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 I18N::Collate, Collate - compare 8-bit scalar data according to +the current locale + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 IPC::Open2, open2 - open a process for both reading and writing + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item WARNING + + +=item SEE ALSO + + + + + +=head2 IPC::Open3, open3 - open a process for reading, writing, and +error handling + +=item SYNOPSIS + + +=item DESCRIPTION + + + + + +=head2 Net::Ping, pingecho - check a host for upness + +=item SYNOPSIS + + +=item DESCRIPTION + + +=over + +=item Parameters + + +hostname, timeout + + + +=back + +=item WARNING + + + + + +=head2 POSIX - Perl interface to IEEE Std 1003.1 + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item NOTE + + +=item CAVEATS + + +=item FUNCTIONS + + +_exit, abort, abs, access, acos, alarm, asctime, asin, assert, atan, +atan2, atexit, atof, atoi, atol, bsearch, calloc, ceil, chdir, chmod, +chown, clearerr, clock, close, closedir, cos, cosh, creat, ctermid, +ctime, cuserid, difftime, div, dup, dup2, errno, execl, execle, execlp, +execv, execve, execvp, exit, exp, fabs, fclose, fcntl, fdopen, feof, +ferror, fflush, fgetc, fgetpos, fgets, fileno, floor, fmod, fopen, +fork, fpathconf, fprintf, fputc, fputs, fread, free, freopen, frexp, +fscanf, fseek, fsetpos, fstat, ftell, fwrite, getc, getchar, getcwd, +getegid, getenv, geteuid, getgid, getgrgid, getgrnam, getgroups, +getlogin, getpgrp, getpid, getppid, getpwnam, getpwuid, gets, getuid, +gmtime, isalnum, isalpha, isatty, iscntrl, isdigit, isgraph, islower, +isprint, ispunct, isspace, isupper, isxdigit, kill, labs, ldexp, ldiv, +link, localeconv, localtime, log, log10, longjmp, lseek, malloc, mblen, +mbstowcs, mbtowc, memchr, memcmp, memcpy, memmove, memset, mkdir, +mkfifo, mktime, modf, nice, offsetof, open, opendir, pat + +=item CLASSES + + +=over + +=item FileHandle + + +new, clearerr, close, eof, error, fileno, flush, getc, getpos, gets, +new_from_fd, new_tmpfile, seek, setbuf, setpos, setvbuf, tell, ungetc + +=item POSIX::SigAction + + +new + +=item POSIX::SigSet + + +new, addset, delset, emptyset, fillset, ismember + +=item POSIX::Termios + + +new, getattr, getcc, getcflag, getiflag, getispeed, getlflag, getoflag, +getospeed, setattr, setcc, setcflag, setiflag, setispeed, setlflag, +setoflag, setospeed, Baud rate values, Terminal interface values, c_cc +field values, c_cflag field values, c_iflag field values, c_lflag field +values, c_oflag field values + + + +=back + +=item PATHNAME CONSTANTS + + +Constants + +=item POSIX CONSTANTS + + +Constants + +=item SYSTEM CONFIGURATION + + +Constants + +=item ERRNO + + +Constants + +=item FCNTL + + +Constants + +=item FLOAT + + +Constants + +=item LIMITS + + +Constants + +=item LOCALE + + +Constants + +=item MATH + + +Constants + +=item SIGNAL + + +Constants + +=item STAT + + +Constants, Macros + +=item STDLIB + + +Constants + +=item STDIO + + +Constants + +=item TIME + + +Constants + +=item UNISTD + + +Constants + +=item WAIT + + +Constants, Macros + +=item CREATION + + + + + +=head2 Safe - Safe extension module for Perl + +=item DESCRIPTION + + +a new namespace, an operator mask + +=over + +=item Operator masks + + +=item Methods in class Safe + + +NAMESPACE, MASK, root (NAMESPACE), mask (MASK), trap (OP, ...), untrap +(OP, ...), share (VARNAME, ...), varglob (VARNAME), reval (STRING), rdo +(FILENAME) + +=item Subroutines in package Safe + + +ops_to_mask (OP, ...), mask_to_ops (MASK), opcode (OP, ...), opname +(OP, ...), fullmask, emptymask, MAXO, op_mask + +=item AUTHOR + + + + +=back + + + + +=head2 SelfLoader - load functions only on demand + +=item SYNOPSIS + + +=item DESCRIPTION + + +=over + +=item The __DATA__ token + + +=item SelfLoader autoloading + + +=item Autoloading and package lexicals + + +=item SelfLoader and AutoLoader + + +=item __DATA__, __END__, and the FOOBAR::DATA filehandle. + + +=item Classes and inherited methods. + + + + +=back + +=item Multiple packages and fully qualified subroutine names + + + + + +=head2 Socket, sockaddr_in, sockaddr_un, inet_aton, inet_ntoa - load +the C + socket.h defines and structure manipulators + +=item SYNOPSIS + + +=item DESCRIPTION + + +inet_aton HOSTNAME, inet_ntoa IP_ADDRESS, INADDR_ANY, INADDR_LOOPBACK, +INADDR_NONE, sockaddr_in PORT, ADDRESS, sockaddr_in SOCKADDR_IN, +pack_sockaddr_in PORT, IP_ADDRESS, unpack_sockaddr_in SOCKADDR_IN, +sockaddr_un PATHNAME, sockaddr_un SOCKADDR_UN, pack_sockaddr_un PATH, +unpack_sockaddr_un SOCKADDR_UN + + + + +=head2 Sys::Hostname - Try every conceivable way to get hostname + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item AUTHOR + + + + + +=head2 Term::Cap - Perl termcap interface + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item EXAMPLES + + + + + +=head2 Term::Complete - Perl word completion module + +=item SYNOPSIS + + +=item DESCRIPTION + + +Attempts word completion. Cannot be changed, ^D, ^U, , + +=item DIAGNOSTICS + + +=item BUGS + + +=item AUTHOR + + + + + +=head2 Test::Harness - run perl standard test scripts with statistics + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item EXPORT + + +=item DIAGNOSTICS + + +C, C, C + +=item SEE ALSO + + +=item BUGS + + + + + +=head2 Text::Abbrev, abbrev - create an abbreviation table from a list + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item EXAMPLE + + + + + +=head2 Text::Soundex - Implementation of the Soundex Algorithm as +Described by Knuth + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item EXAMPLES + + +=item LIMITATIONS + + +=item AUTHOR + + + + + +=head2 Text::Tabs -- expand and unexpand tabs + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item AUTHOR + + + + + +=head2 Text::Wrap -- wrap text into a paragraph + +=item SYNOPSIS + + +=item DESCRIPTION + + +=item AUTHOR + + + + + +=head2 TieHash, TieHash::Std - base class definitions for tied hashes + +=item SYNOPSIS + + +=item DESCRIPTION + + +TIEHASH classname, LIST, STORE this, key, value, FETCH this, key, +FIRSTKEY this, NEXTKEY this, lastkey, EXISTS this, key, DELETE this, +key, CLEAR this + +=item CAVEATS + + +=item MORE INFORMATION + + + + + +=head2 Time::Local - efficiently compute tome from local and GMT time + +=item SYNOPSIS + + +=item DESCRIPTION + + + + +=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 EE, with the help of oodles of +other folks. + + diff --git a/pod/perltrap.pod b/pod/perltrap.pod index cfe9642..79e3ae5 100644 --- a/pod/perltrap.pod +++ b/pod/perltrap.pod @@ -4,13 +4,9 @@ perltrap - Perl traps for the unwary =head1 DESCRIPTION -The biggest trap of all is forgetting to use the B<-w> switch; -see L. Making your entire program runnable under - - use strict; - -can help make your program more bullet-proof, but sometimes -it's too annoying for quick throw-away programs. +The biggest trap of all is forgetting to use the B<-w> switch; see +L. The second biggest trap is not making your entire program +runnable under C. =head2 Awk Traps @@ -361,6 +357,14 @@ for $_ itself (and @_, etc.). =item * +Double-colon is now a valid package separator in an identifier. Thus these +behave differently in perl4 vs. perl5: + + print "$a::$b::$c\n"; + print "$var::abc::xyz\n"; + +=item * + C now does no interpolation on either side. It used to interpolate C<$lhs> but not C<$rhs>. diff --git a/pod/perlvar.pod b/pod/perlvar.pod index e5d0091..c36355a 100644 --- a/pod/perlvar.pod +++ b/pod/perlvar.pod @@ -63,6 +63,43 @@ equivalent: chop chop($_) +Here are the places where Perl will assume $_ even if you +don't use it: + +=over 3 + +=item * + +Various unary functions, including functions like ord() and int(), as well +as the all file tests (C<-f>, C<-d>) except for C<-t>, which defaults to +STDIN. + +=item * + +Various list functions like print() and unlink(). + +=item * + +The pattern matching operations C, C, and C when used +without an C<=~> operator. + +=item * + +The default iterator variable in a C loop if no other +variable is supplied. + +=item * + +The implicit iterator variable in the grep() and map() functions. + +=item * + +The default place to put an input record when a CFHE> +operation's result is tested by itself as the sole criterion of a C +test. Note that outside of a C test, this will not happen. + +=back + (Mnemonic: underline is understood in certain operations.) =item $> @@ -181,8 +218,9 @@ currently selected output channel. Default is 0. Note that STDOUT will typically be line buffered if output is to the terminal and block buffered otherwise. Setting this variable is useful primarily when you are outputting to a pipe, such as when you are running a Perl script -under rsh and want to see the output as it's happening. (Mnemonic: -when you want your pipes to be piping hot.) +under rsh and want to see the output as it's happening. This has no +effect on input buffering. +(Mnemonic: when you want your pipes to be piping hot.) =item output_field_separator HANDLE EXPR @@ -444,7 +482,8 @@ you, if you're running setgid.) Note: "C<$E>", "C<$E>", "C<$(>" and "C<$)>" can only be set on machines that support the corresponding I routine. "C<$(>" and "C<$)>" -can only be swapped on machines supporting setregid(). +can only be swapped on machines supporting setregid(). Because Perl doesn't +currently use initgroups(), you can't set your group vector to multiple groups. =item $PROGRAM_NAME @@ -472,7 +511,9 @@ discouraged. =item $] -The string printed out when you say C. It can be used to +The string printed out when you say C. +(This is currently I). +It can be used to determine at the beginning of a script whether the perl interpreter executing the script is in the right range of versions. If used in a numeric context, returns the version + patchlevel / 1000. Example: @@ -562,8 +603,13 @@ The array @INC contains the list of places to look for Perl scripts to be evaluated by the C, C, or C constructs. It initially consists of the arguments to any B<-I> command line switches, followed by the default Perl library, probably "/usr/local/lib/perl", -followed by ".", to represent the current directory. +followed by ".", to represent the current directory. If you need to +modify this at runtime, you should use the C pragma in order +to also get the machine-dependent library properly loaded: + use lib '/mypath/libdir/'; + use SomeMod; + =item %INC The hash %INC contains entries for each filename that has @@ -622,7 +668,9 @@ The routine indicated by $SIG{__DIE__} is called when a fatal exception is about to be thrown. The error message is passed as the first argument. When a __DIE__ hook routine returns, the exception processing continues as it would have in the absence of the hook, -unless the hook routine itself exits via a goto, a loop exit, or a die. +unless the hook routine itself exits via a C, a loop exit, or a die(). +The __DIE__ handler is explicitly disabled during the call, so that you +can die from a __DIE__ handler. Similarly for __WARN__. =back diff --git a/pod/perlxs.pod b/pod/perlxs.pod index df2aefa..b663dcf 100644 --- a/pod/perlxs.pod +++ b/pod/perlxs.pod @@ -23,38 +23,7 @@ many common C types. A supplement typemap must be created to handle special structures and types for the library being linked. -=head2 Getting Started - -A new extension should begin with the B tool. This will generate -templates for the new Perl module (PM), the XS source file (XS), the MANIFEST -file, and the Makefile.PL (PL) files. The Makefile.PL file is a Perl script -which will generate a Makefile. This makefile knows how to find and run -xsubpp for your extension. When you type "make" your XS file will be run -through xsubpp and a C file will be produced. Then the C file will be -compiled. A simple example looks like this for an example module named -B: - - $ h2xs -Afn Foo - $ cd ext/Foo - $ ls - Foo.pm Foo.xs MANIFEST Makefile.PL - $ perl5 Makefile.PL - $ ls - Foo.pm Foo.xs MANIFEST Makefile.PL Makefile - $ - $ make - for a tutorial on the whole extension creation process. =head2 On The Road @@ -451,8 +420,8 @@ Perl as a single list. bool_t status; status = rpcb_gettime( host, &timep ); EXTEND(sp, 2); - PUSHs(sv_2mortal(newSVnv(status))); - PUSHs(sv_2mortal(newSVnv(timep))); + PUSHs(sv_2mortal(newSViv(status))); + PUSHs(sv_2mortal(newSViv(timep))); } Notice that the programmer must supply the C code necessary @@ -535,7 +504,7 @@ then not push return values on the stack. { time_t timep; if( rpcb_gettime( host, &timep ) ) - PUSHs(sv_2mortal(newSVnv(timep))); + PUSHs(sv_2mortal(newSViv(timep))); else{ /* Nothing pushed on stack, so an empty */ /* list is implicitly returned. */ @@ -592,92 +561,89 @@ If a function is defined as a C++ method then it will assume its first argument is an object pointer. The object pointer will be stored in a variable called THIS. The object should have been created by C++ with the new() function and should -be blessed by Perl with the sv_setptrobj() macro. The -blessing of the object by Perl can be handled by the -T_PTROBJ typemap. +be blessed by Perl with the sv_setref_pv() macro. The +blessing of the object by Perl can be handled by a typemap. An example +typemap is shown at the end of this section. If the method is defined as static it will call the C++ function using the class::method() syntax. If the method is not static the function will be called using the THIS->method() syntax. -=head2 Perl Variables +The next examples will use the following C++ class. -The following demonstrates how the Perl variable $host can -be accessed from an XSUB. The function B is -used to obtain a pointer to the variable, known as an B -(Scalar Variable) internally. The package name C will be -added to the name of the variable so perl_get_sv() will know -in which package $host can be found. If the package name is -not supplied then perl_get_sv() will search package C
for -the variable. The macro B is then used to dereference -the SV to obtain a C pointer to its contents. + class colors { + public: + colors(); + ~colors(); + int blue(); + void set_blue( int ); + + private: + int c_blue; + }; + +The XSUBs for the blue() and set_blue() methods are defined with the class +name but the parameter for the object (THIS, or "self") is implicit and is +not listed. + + int + color::blue() void - rpcb_gettime() - PPCODE: - { - char *host; - SV *hostsv; - time_t timep; - - hostsv = perl_get_sv( "RPC::host", FALSE ); - if( hostsv != NULL ){ - host = SvPVX( hostsv ); - if( rpcb_gettime( host, &timep ) ) - PUSHs(sv_2mortal(newSVnv(timep))); - } - } + color::set_blue( val ) + int val -This Perl code can be used to call that XSUB. +Both functions will expect an object as the first parameter. The xsubpp +compiler will call that object C and will use it to call the specified +method. So in the C++ code the blue() and set_blue() methods will be called +in the following manner. - $RPC::host = "localhost"; - $timep = rpcb_gettime(); + RETVAL = THIS->blue(); -In the above example the SV contained a C C but a Perl -scalar variable may also contain numbers and references. If -the SV is expected to have a C C then the macro B -should be used to dereference the SV. When the SV contains -a C double then B should be used. + THIS->set_blue( val ); -The macro B can be used to dereference an SV when it is a Perl -reference. The result will be another SV which points to the actual Perl -variable. This can then be dereferenced with SvPVX(), SvNVX(), or -SvIVX(). The following XSUB will use SvRV(). +If the function's name is B then the C++ C function will be +called and C will be given as its parameter. void - rpcb_gettime() - PPCODE: - { - char *host; - SV *rv; - SV *hostsv; - time_t timep; - - rv = perl_get_sv( "RPC::host", FALSE ); - if( rv != NULL ){ - hostsv = SvRV( rv ); - host = SvPVX( hostsv ); - if( rpcb_gettime( host, &timep ) ) - PUSHs(sv_2mortal(newSVnv(timep))); - } - } + color::DESTROY() + +The C++ code will call C. + + delete THIS; -This Perl code will create a variable $RPC::host which is a -reference to $MY::host. The variable $MY::host contains the -hostname which will be used. +If the function's name is B then the C++ C function will be called +to create a dynamic C++ object. The XSUB will expect the class name, which +will be kept in a variable called C, to be given as the first +argument. - $MY::host = "localhost"; - $RPC::host = \$MY::host; - $timep = rpcb_gettime(); + color * + color::new() -The second argument to perl_get_sv() will normally be B -as shown in the above examples. An argument of B will -cause variables to be created if they do not already exist. -One should not use TRUE unless steps are taken to deal with -a possibly empty SV. +The C++ code will call C. -XSUBs may use B, B, and B to -access Perl arrays, hashes, and code values. + RETVAL = new color(); + +The following is an example of a typemap that could be used for this C++ +example. + + TYPEMAP + color * O_OBJECT + + OUTPUT + # The Perl object is blessed into 'CLASS', which should be a + # char* having the name of the package for the blessing. + O_OBJECT + sv_setref_pv( $arg, CLASS, (void*)$var ); + + INPUT + O_OBJECT + if( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) ) + $var = ($type)SvIV((SV*)SvRV( $arg )); + else{ + warn( \"${Package}::$func_name() -- $var is not a blessed SV reference\" ); + XSRETURN_UNDEF; + } =head2 Interface Strategy @@ -707,41 +673,6 @@ cases it may be helpful to use the T_PTROBJ typemap for these structures so they can be manipulated by Perl as blessed objects. -=head2 The Perl Module - -The Perl module is the link between the extension library, -which was generated from XS code, and the Perl interpreter. -The module is used to tell Perl what the extension library -contains. The name and package of the module should match -the name of the library. - -The following is a Perl module for an extension containing -some ONC+ RPC bind library functions. - - package RPC; - - require Exporter; - require DynaLoader; - @ISA = qw(Exporter DynaLoader); - @EXPORT = qw( rpcb_gettime rpcb_getmaps rpcb_getaddr - rpcb_rmtcall rpcb_set rpcb_unset ); - - bootstrap RPC; - 1; - -The RPC extension contains the functions found in the -@EXPORT list. By using the C module the RPC module -can make these function names visible to the rest of the -Perl program. The C module will allow the RPC -module to bootstrap the extension library. To load this -extension and make the functions available, the following -Perl statement should be used. - - use RPC; - -For more information about the DynaLoader consult its documentation in the -ext/DynaLoader directory in the Perl source. - =head2 Perl Objects And C Structures When dealing with C structures one should select either @@ -808,76 +739,6 @@ does not care, that this object is a C struct and not a Perl object. In this sense, there is no difference between the object created by the getnetconfigent() XSUB and an object created by a normal Perl subroutine. -=head2 C Headers and Perl - -The B compiler is designed to convert C header files in -/usr/include into Perl extensions. This compiler will -create a directory under the C directory of the Perl -source and will populate it with a Makefile, a Perl Module, -an XS source file, and a MANIFEST file. - -The following command will create an extension called C -from the header. - - h2xs rpcsvc/rusers - -When the Rusers extension has been compiled and installed -Perl can use it to retrieve any C<#define> statements which -were in the C header. - - use Rusers; - print "RPC program number for rusers service: "; - print &RUSERSPROG, "\n"; - -=head2 Creating A New Extension - -The B compiler can generate template source files and -Makefiles. These templates offer a suitable starting point -for most extensions. The following example demonstrates how -one might use B to create an extension containing the RPC -functions in this document. - -The extension will not use autoloaded functions and will not define -constants, so the B<-A> option will be given to B. When run from the -Perl source directory, the B compiler will create the directory -ext/RPC and will populate it with files called RPC.xs, RPC.pm, Makefile.PL, -and MANIFEST. The XS code for the RPC functions should be added to the -RPC.xs file. The @EXPORT list in RPC.pm should be updated to include the -functions from RPC.xs. - - h2xs -An RPC - -To compile the extension for dynamic loading the following -command should be executed from the ext/RPC directory. - - make dynamic - -If the extension will be statically linked into the Perl -binary then the makefile (use C, not C) in the -Perl source directory should be edited to add C -to the C variable. Before making this change Perl -should have already been built. After the makefile has been -updated the following command should be executed from the -Perl source directory. - - make - -Perl's B script can also be used to add extensions. The extension -should be placed in the C directory under the Perl source before Perl -has been built and prior to running Configure. When Configure is run it -will find the extension along with the other extensions in the C -directory and will add it to the list of extensions to be built. When make -is run the extension will be built along with the other extensions. - -Configure recognizes extensions if they have an XS source -file which matches the name of the extension directory. If -the extension directory includes a MANIFEST file Configure -will search that file for any B<.SH> files and extract them -after it extracts all the other .SH files listed in the main -MANIFEST. The main Perl Makefile will then run B in the -extension's directory if it finds an XS file matching the -name of the extension's directory. - =head2 The Typemap The typemap is a collection of code fragments which are used by the B @@ -982,4 +843,4 @@ File C: Perl test program for the RPC extension. =head1 AUTHOR Dean Roehrich Froehrich@cray.comE> -Oct 12, 1995 +Dec 10, 1995 diff --git a/pod/perlxstut.pod b/pod/perlxstut.pod index 484f49d..082e2cd 100644 --- a/pod/perlxstut.pod +++ b/pod/perlxstut.pod @@ -22,7 +22,7 @@ are welcome. Our first extension will be very simple. When we call the routine in the extension, it will print out a well-known message and terminate. -Run "h2xs -A -n Test1". This creates a directory named Test1, possibly under +Run C. This creates a directory named Test1, possibly under ext/ if it exists in the current working directory. Four files will be created in the Test1 dir: MANIFEST, Makefile.PL, Test1.pm, Test1.xs. @@ -80,7 +80,7 @@ Let's edit the .xs file by adding this to the end of the file: CODE: printf("Hello, world!\n"); -Now we'll run "perl Makefile.PL". This will create a real Makefile, +Now we'll run C. This will create a real Makefile, which make needs. It's output looks something like: % perl Makefile.PL @@ -128,7 +128,7 @@ Now we run the script and we should see the following output: Now let's create a simple extension that will take a single argument and return 0 if the argument is even, 1 if the argument is odd. -Run "h2xs -A -n Test2". This will create a Test2 directory with a file +Run C. This will create a Test2 directory with a file Test2.xs underneath it. Add the following to the end of the XS file: int @@ -236,7 +236,7 @@ from other extensions or from the calling program itself. Our third extension will take one argument as its input, round off that value, and set the argument to the rounded value. -Run "h2xs -A -n Test3". This will create a Test3 directory with a file +Run C. This will create a Test3 directory with a file Test3.xs underneath it. Add the following to the end of the XS file: void @@ -438,9 +438,9 @@ Now let's move the libtest4.h and libtest.a files into a sub-directory under Okay, now that we have a header file and a library, let's begin actually writing the extension. -Run "h2xs -n Test4 /tmp/test4/include/libtest4.h" (notice we are no longer -specifying -A as an argument). This will create a Test4 directory with a file -Test4.xs underneath it. If we look at it now, we'll see some interesting +Run C (notice we are no longer +specifying B<-A> as an argument). This will create a Test4 directory with a file +F underneath it. If we look at it now, we'll see some interesting things have been added to the various files. =over 2 diff --git a/pod/pod2man.PL b/pod/pod2man.PL index 3a8c5db..3b6c1f8 100644 --- a/pod/pod2man.PL +++ b/pod/pod2man.PL @@ -27,42 +27,395 @@ print "Extracting $file (with variable substitutions)\n"; print OUT <<"!GROK!THIS!"; $Config{'startperl'} - eval 'exec perl -S \$0 "\$@"' - if 0; !GROK!THIS! # In the following, perl variables are not expanded during extraction. print OUT <<'!NO!SUBS!'; +eval 'exec perl -S $0 "$@"' + if 0; + +=head1 NAME + +pod2man - translate embedded Perl pod directives into man pages + +=head1 SYNOPSIS + +B +[ B<--section=>I ] +[ B<--release=>I ] +[ B<--center=>I ] +[ B<--date=>I ] +[ B<--fixed=>I ] +[ B<--official> ] +I + +=head1 DESCRIPTION + +B converts its input file containing embedded pod directives (see +L) into nroff source suitable for viewing with nroff(1) or +troff(1) using the man(7) macro set. + +Besides the obvious pod conversions, B also takes care of +func(), func(n), and simple variable references like $foo or @bar so +you don't have to use code escapes for them; complex expressions like +C<$fred{'stuff'}> will still need to be escaped, though. Other nagging +little roffish things that it catches include translating the minus in +something like foo-bar, making a long dash--like this--into a real em +dash, fixing up "paired quotes", putting a little space after the +parens in something like func(), making C++ and PI look right, making +double underbars have a little tiny space between them, making ALLCAPS +a teeny bit smaller in troff(1), and escaping backslashes so you don't +have to. + +=head1 OPTIONS + +=over 8 + +=item center + +Set the centered header to a specific string. The default is +"User Contributed Perl Documentation", unless the C<--official> flag is +given, in which case the default is "Perl Programmers Reference Guide". + +=item date + +Set the left-hand footer string to this value. By default, +the modification date of the input file will be used. + +=item fixed + +The fixed font to use for code refs. Defaults to CW. + +=item official + +Set the default header to indicate that this page is of +the standard release in case C<--center> is not given. + +=item release + +Set the centered footer. By default, this is the current +perl release. + +=item section + +Set the section for the C<.TH> macro. The standard conventions on +sections are to use 1 for user commands, 2 for system calls, 3 for +functions, 4 for devices, 5 for file formats, 6 for games, 7 for +miscellaneous information, and 8 for administrator commands. This works +best if you put your Perl man pages in a separate tree, like +F. By default, section 1 will be used +unless the file ends in F<.pm> in which case section 3 will be selected. + +=back + +=head1 Anatomy of a Proper Man Page + +For those not sure of the proper layout of a man page, here's +an example of the skeleton of a proper man page. Head of the +major headers should be setout as a C<=head1> directive, and +are historically written in the rather startling ALL UPPER CASE +format, although this is not mandatory. +Minor headers may be included using C<=head2>, and are +typically in mixed case. + +=over 10 + +=item NAME + +Mandatory section; should be a comma-separated list of programs or +functions documented by this podpage, such as: + + foo, bar - programs to do something + +=item SYNOPSIS + +A short usage summary for programs and functions, which +may someday be deemed mandatory. + +=item DESCRIPTION + +Long drawn out discussion of the program. It's a good idea to break this +up into subsections using the C<=head2> directives, like + + =head2 A Sample Subection + + =head2 Yet Another Sample Subection + +=item OPTIONS + +Some people make this separate from the description. + +=item RETURN VALUE + +What the program or function returns if successful. + +=item ERRORS + +Exceptions, return codes, exit stati, and errno settings. + +=item EXAMPLES + +Give some example uses of the program. + +=item ENVIRONMENT + +Envariables this program might care about. + +=item FILES + +All files used by the program. You should probably use the FEE +for these. + +=item SEE ALSO + +Other man pages to check out, like man(1), man(7), makewhatis(8), or catman(8). + +=item NOTES + +Miscellaneous commentary. + +=item CAVEATS + +Things to take special care with; sometimes called WARNINGS. + +=item DIAGNOSTICS + +All possible messages the program can print out--and +what they mean. + +=item BUGS + +Things that are broken or just don't work quite right. + +=item RESTRICTIONS + +Bugs you don't plan to fix :-) + +=item AUTHOR + +Who wrote it (or AUTHORS if multiple). + +=item HISTORY + +Programs derived from other sources sometimes have this, or +you might keep a modification long here. + +=back + +=head1 EXAMPLES + + pod2man program > program.1 + pod2man some_module.pm > /usr/perl/man/man3/some_module.3 + pod2man --section=7 note.pod > note.7 + +=head1 DIAGNOSTICS + +The following diagnostics are generated by B. Items +marked "(W)" are non-fatal, whereas the "(F)" errors will cause +B to immediately exit with a non-zero status. + +=over 4 + +=item bad option in paragraph %d of %s: ``%s'' should be [%s]<%s> + +(W) If you start include an option, you should set it off +as bold, italic, or code. + +=item can't open %s: %s + +(F) The input file wasn't available for the given reason. + +=item high bit char in input stream + +(W) You can't use high-bit characters in the input stream, +because the translator uses them for its own nefarious purposes. +Use an HTML entity in angle brackets instead. + +=item Improper man page - no dash in NAME header in paragraph %d of %s + +(W) The NAME header did not have an isolated dash in it. This is +considered important. + +=item Invalid man page - no NAME line in %s + +(F) You did not include a NAME header, which is essential. + +=item roff font should be 1 or 2 chars, not `%s' (F) + +(F) The font specified with the C<--fixed> option was not +a one- or two-digit roff font. + +=item %s is missing required section: %s + +(W) Required sections include NAME, DESCRIPTION, and if you're +using a section starting with a 3, also a SYNOPSIS. Actually, +not having a NAME is a fatal. + +=item Unknown escape: %s in %s + +(W) An unknown HTML entity (probably for an 8-bit character) was given via +a CE> directive. Besides amp, lt, gt, and quot, recognized +entities are Aacute, aacute, Acirc, acirc, AElig, aelig, Agrave, agrave, +Aring, aring, Atilde, atilde, Auml, auml, Ccedil, ccedil, Eacute, eacute, +Ecirc, ecirc, Egrave, egrave, ETH, eth, Euml, euml, Iacute, iacute, Icirc, +icirc, Igrave, igrave, Iuml, iuml, Ntilde, ntilde, Oacute, oacute, Ocirc, +ocirc, Ograve, ograve, Oslash, oslash, Otilde, otilde, Ouml, ouml, szlig, +THORN, thorn, Uacute, uacute, Ucirc, ucirc, Ugrave, ugrave, Uuml, uuml, +Yacute, yacute, and yuml. + +=item Unmatched =back + +(W) You have a C<=back> without a corresponding C<=over>. + +=item Unrecognized pod directive: %s + +(W) You specified a pod directive that isn't in the known list of +C<=head1>, C<=head2>, C<=item>, C<=over>, C<=back>, or C<=cut>. + + +=back + +=head1 NOTES + +If you would like to print out a lot of man page continuously, you +probably want to set the C and D registers to set contiguous page +numbering and even/odd paging, at least one some versions of man(7). +Settting the F register will get you some additional experimental +indexing: + + troff -man -rC1 -rD1 -rF1 perl.1 perldata.1 perlsyn.1 ... + +The indexing merely outputs messages via C<.tm> for each +major page, section, subsection, item, and any CE> +directives. + + +=head1 RESTRICTIONS + +You shouldn't use 8-bit characters in the input stream, as these +will be used by the translator. + +=head1 BUGS + +The =over and =back directives don't really work right. They +take absolute positions instead of offsets, don't nest well, and +making people count is suboptimal in any event. + +=head1 AUTHORS + +Original prototype by Larry Wall, but so massively hacked over by +Tom Christiansen such that Larry probably doesn't recognize it anymore. + +=cut $/ = ""; $cutting = 1; -$CFont = 'CW'; -if ($ARGV[0] =~ s/-fc(.*)//) { - shift; - $CFont = $1 || shift; +($version,$patch) = `\PATH=.:..:\$PATH; perl -v` =~ /version (\d\.\d{3}(?: +)(?:\S+)?)(?:.*patchlevel (\d\S*))?/s; +$DEF_RELEASE = "perl $version"; +$DEF_RELEASE .= ", patch $patch" if $patch; + + +sub makedate { + my $secs = shift; + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($secs); + my $mname = (qw{Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec})[$mon]; + return "$mday/$mname/$year"; } +use Getopt::Long; + +$DEF_SECTION = 1; +$DEF_CENTER = "User Contributed Perl Documentation"; +$STD_CENTER = "Perl Programmers Reference Guide"; +$DEF_FIXED = 'CW'; + +sub usage { + warn "$0: @_\n" if @_; + die <"; +$Filename = $name; +$name = uc($name) if $section =~ /^1/; $name =~ s/\..*//; +if ($name ne 'something') { + FCHECK: { + open(F, "< $ARGV[0]") || die "can't open $ARGV[0]: $!"; + while () { + if (/^=head1\s+NAME\s*$/) { # an /m would forgive mistakes + $_ = ; + unless (/\s*-+\s+/) { + $oops++; + warn "$0: Improper man page - no dash in NAME header in paragraph $. of $ARGV[0]:\n" + } + %namedesc = split /\s+-\s+/; + last FCHECK; + } + } + die "$0: Invalid man page - no NAME line in $ARGV[0]\n"; + } + close F; +} + print <<"END"; .rn '' }` ''' \$RCSfile\$\$Revision\$\$Date\$ -''' +''' ''' \$Log\$ -''' +''' .de Sh .br .if t .Sp @@ -100,6 +453,7 @@ print <<"END"; .tr \\(*W-|\\(bv\\*(Tr .ie n \\{\\ .ds -- \\(*W- +.ds PI pi .if (\\n(.H=4u)&(1m=24u) .ds -- \\(*W\\h'-12u'\\(*W\\h'-12u'-\\" diablo 10 pitch .if (\\n(.H=4u)&(1m=20u) .ds -- \\(*W\\h'-12u'\\(*W\\h'-8u'-\\" diablo 12 pitch .ds L" "" @@ -114,15 +468,42 @@ print <<"END"; .ds R" '' .ds L' ` .ds R' ' -.if t .ds PI \\(*p -.if n .ds PI PI +.ds PI \\(*p 'br\\} -.TH \U$name\E 1 "\\*(RP" +END + +print <<'END'; +.\" If the F register is turned on, we'll generate +.\" index entries out stderr for the following things: +.\" TH Title +.\" SH Header +.\" Sh Subsection +.\" Ip Item +.\" X<> Xref (embedded +.\" Of course, you have to process the output yourself +.\" in some meaninful fashion. +.if \nF \{ +.de IX +.tm Index:\\$1\t\\n%\t"\\$2" +.. +.nr % 0 +.rr F +.\} +END + +print <<"END"; +.TH $name $section "$RP" "$date" "$center" +.IX Title "$name $section" .UC END +while (($name, $desc) = each %namedesc) { + for ($name, $desc) { s/^\s+//; s/\s+$//; } + print qq(.IX Name "$name - $desc"\n); +} + print <<'END'; -.if n .hy 0 +.if n .hy 0 .if n .na .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .de CQ \" put $1 in typewriter font @@ -163,8 +544,8 @@ print <<'END'; . ds ~ ~ . ds ? ? . ds ! ! -. ds / -. ds q +. ds / +. ds q .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" @@ -257,7 +638,7 @@ while (<>) { # trofficate backslashes; must do it before what happens below s/\\/noremap('\\e')/ge; - # first hide the escapes in case we need to + # first hide the escapes in case we need to # intuit something and get it wrong due to fmting s/([A-Z]<[^<>]*>)/noremap($1)/ge; @@ -291,14 +672,16 @@ while (<>) { [^\051]*? \) ) - }x && $` !~ /([LCI]<[^<>]*|-)$/ && !/^=\w/) + }x && $` !~ /([LCI]<[^<>]*|-)$/ && !/^=\w/) { - warn "``$1'' should be a [LCI]<$1> ref"; - } + warn "$0: bad option in paragraph $. of $ARGV: ``$1'' should be [LCI]<$1>\n"; + $oops++; + } while (/(-[a-zA-Z])\b/g && $` !~ /[\w\-]$/) { - warn "``$1'' should be [CB]<$1> ref"; - } + warn "$0: bad option in paragraph $. of $ARGV: ``$1'' should be [CB]<$1>\n"; + $oops++; + } # put it back so we get the <> processed again; clear_noremap(0); # 0 means leave the E's @@ -307,7 +690,7 @@ while (<>) { # trofficate backslashes s/\\/noremap('\\e')/ge; - } + } # need to hide E<> first; they're processed in clear_noremap s/(E<[^<>]+>)/noremap($1)/ge; @@ -325,7 +708,7 @@ while (<>) { # no break -- usually we want C<> for this s/S<([^<>]*)>/nobreak($1)/eg; - # LREF: a manpage(3f) + # LREF: a manpage(3f) s:L<([a-zA-Z][^\s\/]+)(\([^\)]+\))?>:the I<$1>$2 manpage:g; # LREF: an =item on another manpage @@ -359,7 +742,7 @@ while (<>) { s{ L< (?: - ([a-zA-Z]\S+?) / + ([a-zA-Z]\S+?) / )? "?(.*?)"? > @@ -368,7 +751,7 @@ while (<>) { $1 # if no $1, assume it means on this page. ? "the section on I<$2> in the I<$1> manpage" : "the section on I<$2>" - } + } }gex; s/Z<>/\\&/g; @@ -395,14 +778,18 @@ while (<>) { $cutting = 1; } elsif ($Cmd eq 'head1') { - print qq{.SH "$_"\n} + s/\s+$//; + delete $wanna_see{$_} if exists $wanna_see{$_}; + print qq{.SH "$_"\n}; + print qq{.IX Header "$_"\n}; } elsif ($Cmd eq 'head2') { - print qq{.Sh "$_"\n} + print qq{.Sh "$_"\n}; + print qq{.IX Subsection "$_"\n}; } elsif ($Cmd eq 'over') { push(@indent,$indent); - $indent = $_ + 0; + $indent += ($_ + 0) || 5; } elsif ($Cmd eq 'back') { $indent = pop(@indent); @@ -412,9 +799,13 @@ while (<>) { elsif ($Cmd eq 'item') { s/^\*( |$)/\\(bu$1/g; print STDOUT qq{.Ip "$_" $indent\n}; + print qq{.IX Item "$_"\n}; } + elsif ($Cmd eq 'pod') { + # this is just a comment + } else { - warn "Unrecognized directive: $Cmd\n"; + warn "Unrecognized pod directive: $Cmd\n"; } } else { @@ -433,6 +824,17 @@ print <<"END"; .rn }` '' END +if (%wanna_see) { + @missing = keys %wanna_see; + warn "$0: $Filename is missing required section" + . (@missing > 1 && "s") + . ": @missing\n"; + $oops++; +} + +exit; +#exit ($oops != 0); + ######################################################################### sub nobreak { @@ -443,6 +845,8 @@ sub nobreak { sub escapes { + s/X<(.*?)>/mkindex($1)/ge; + # translate the minus in foo-bar into foo\-bar for roff s/([^0-9a-z-])-([^-])/$1\\-$2/g; @@ -459,7 +863,7 @@ sub escapes { #s/(?!")(?:.)--(?!")(?:.)/\\*(--/g; #s/(?:(?!")(?:.)--(?:"))|(?:(?:")--(?!")(?:.))/\\*(--/g; - + # make sure that func() keeps a bit a space tween the parens ### s/\b\(\)/\\|()/g; @@ -471,7 +875,7 @@ sub escapes { # make double underbars have a little tiny space between them s/__/_\\|_/g; - # PI goes to \*(-- (defined above) + # PI goes to \*(PI (defined above) s/\bPI\b/noremap('\\*(PI')/ge; # make all caps a teeny bit smaller, but don't muck with embedded code literals @@ -494,7 +898,7 @@ sub escapes { ( \b[A-Z]{2,}[\/A-Z+:\-\d_\$]*\b ) - } { + } { $1 . noremap( '\\s-1' . $2 . '\\s0' ) }egmox; @@ -510,9 +914,9 @@ sub ccvt { # what about $" ? } else { noremap(qq{${CFont_embed}$_\\fR}); - } + } noremap(qq{.CQ "$_" \n\\&}); -} +} sub makespace { if ($indent) { @@ -523,22 +927,33 @@ sub makespace { } } +sub mkindex { + my ($entry) = @_; + my @entries = split m:\s*/\s*:, $entry; + print ".IX Xref "; + for $entry (@entries) { + print qq("$entry" ); + } + print "\n"; + return ''; +} + sub font { local($font) = shift; return '\\f' . noremap($font); -} +} sub noremap { local($thing_to_hide) = shift; $thing_to_hide =~ tr/\000-\177/\200-\377/; return $thing_to_hide; -} +} sub init_noremap { if ( /[\200-\377]/ ) { - warn "hit bit char in input stream"; - } -} + warn "high bit char in input stream"; + } +} sub clear_noremap { my $ready_to_print = $_[0]; @@ -555,17 +970,17 @@ sub clear_noremap { E< ( [A-Za-z]+ ) > - } { + } { do { exists $HTML_Escapes{$1} ? do { $HTML_Escapes{$1} } : do { warn "Unknown escape: $& in $_"; "E<$1>"; - } - } + } + } }egx if $ready_to_print; -} +} sub internal_lrefs { local($_) = shift; @@ -578,14 +993,14 @@ sub internal_lrefs { $retstr .= "C<$items[$i]>"; $retstr .= ", " if @items > 2 && $i != $#items; $retstr .= " and " if $i+2 == @items; - } + } $retstr .= " entr" . ( @items > 1 ? "ies" : "y" ) . " elsewhere in this document"; return $retstr; -} +} BEGIN { %HTML_Escapes = ( @@ -658,6 +1073,7 @@ BEGIN { "yuml" => "y\\*:", # small y, dieresis or umlaut mark ); } + !NO!SUBS! close OUT or die "Can't close $file: $!"; diff --git a/pod/pod2text b/pod/pod2text new file mode 100644 index 0000000..caa6ec4 --- /dev/null +++ b/pod/pod2text @@ -0,0 +1,359 @@ +#!/usr/local/bin/perl + +$SCREEN = ($ARGV[0] =~ /^-(\d+)/ && (shift, $1)) + || ($ENV{TERMCAP} =~ /co#(\d+)/)[0] + || $ENV{COLUMNS} + || (`stty -a 2>/dev/null` =~ /(\d+) columns/)[0] + || 72; + +$/ = ""; + +$FANCY = 0; + +$cutting = 1; +$DEF_INDENT = 4; +$indent = $DEF_INDENT; +$needspace = 0; + +POD_DIRECTIVE: while (<>) { + if ($cutting) { + next unless /^=/; + $cutting = 0; + } + 1 while s{^(.*?)(\t+)(.*)$}{ + $1 + . (' ' x (length($2) * 8 - length($1) % 8)) + . $3 + }me; + # Translate verbatim paragraph + if (/^\s/) { + $needspace = 1; + output($_); + next; + } + +sub prepare_for_output { + + s/\s*$/\n/; + &init_noremap; + + # need to hide E<> first; they're processed in clear_noremap + s/(E<[^<>]+>)/noremap($1)/ge; + $maxnest = 10; + while ($maxnest-- && /[A-Z]/`$1'/g; + } else { + s/C<(.*?)>/noremap("E${1}E")/ge; + } + # s/[IF]<(.*?)>/italic($1)/ge; + s/I<(.*?)>/*$1*/g; + # s/[CB]<(.*?)>/bold($1)/ge; + s/X<.*?>//g; + # LREF: a manpage(3f) + s:L<([a-zA-Z][^\s\/]+)(\([^\)]+\))?>:the $1$2 manpage:g; + # LREF: an =item on another manpage + s{ + L< + ([^/]+) + / + ( + [:\w]+ + (\(\))? + ) + > + } {the "$2" entry in the $1 manpage}gx; + + # LREF: an =item on this manpage + s{ + ((?: + L< + / + ( + [:\w]+ + (\(\))? + ) + > + (,?\s+(and\s+)?)? + )+) + } { internal_lrefs($1) }gex; + + # LREF: a =head2 (head1?), maybe on a manpage, maybe right here + # the "func" can disambiguate + s{ + L< + (?: + ([a-zA-Z]\S+?) / + )? + "?(.*?)"? + > + }{ + do { + $1 # if no $1, assume it means on this page. + ? "the section on \"$2\" in the $1 manpage" + : "the section on \"$2\"" + } + }gex; + + s/[A-Z]<(.*?)>/$1/g; + } + clear_noremap(1); +} + + &prepare_for_output; + + if (s/^=//) { + # $needspace = 0; # Assume this. + # s/\n/ /g; + ($Cmd, $_) = split(' ', $_, 2); + # clear_noremap(1); + if ($Cmd eq 'cut') { + $cutting = 1; + } + elsif ($Cmd eq 'head1') { + makespace(); + print; + #print uc($_); + } + elsif ($Cmd eq 'head2') { + makespace(); + # s/(\w+)/\u\L$1/g; + #print ' ' x $DEF_INDENT, $_; + # print "\xA7"; + s/(\w)/\xA7 $1/ if $FANCY; + print ' ' x ($DEF_INDENT/2), $_, "\n"; + } + elsif ($Cmd eq 'over') { + push(@indent,$indent); + $indent += ($_ + 0) || $DEF_INDENT; + } + elsif ($Cmd eq 'back') { + $indent = pop(@indent); + warn "Unmatched =back\n" unless defined $indent; + $needspace = 1; + } + elsif ($Cmd eq 'item') { + makespace(); + # s/\A(\s*)\*/$1\xb7/ if $FANCY; + # s/^(\s*\*\s+)/$1 /; + { + if (length() + 3 < $indent) { + my $paratag = $_; + $_ = <>; + if (/^=/) { # tricked! + local($indent) = $indent[$#index - 1] || $DEF_INDENT; + output($paratag); + redo POD_DIRECTIVE; + } + &prepare_for_output; + IP_output($paratag, $_); + } else { + local($indent) = $indent[$#index - 1] || $DEF_INDENT; + output($_); + } + } + } + else { + warn "Unrecognized directive: $Cmd\n"; + } + } + else { + # clear_noremap(1); + makespace(); + output($_, 1); + } +} + +######################################################################### + +sub makespace { + if ($needspace) { + print "\n"; + $needspace = 0; + } +} + +sub bold { + my $line = shift; + $line =~ s/(.)/$1\b$1/g; + return $line; +} + +sub italic { + my $line = shift; + $line =~ s/(.)/_\b$1/g; + return $line; +} + +sub IP_output { + local($tag, $_) = @_; + local($tag_indent) = $indent[$#index - 1] || $DEF_INDENT; + $tag_cols = $SCREEN - $tag_indent; + $cols = $SCREEN - $indent; + $tag =~ s/\s*$//; + s/\s+/ /g; + s/^ //; + $str = "format STDOUT = \n" + . (" " x ($tag_indent)) + . '@' . ('<' x ($indent - $tag_indent - 1)) + . "^" . ("<" x ($cols - 1)) . "\n" + . '$tag, $_' + . "\n~~" + . (" " x ($indent-2)) + . "^" . ("<" x ($cols - 5)) . "\n" + . '$_' . "\n\n.\n1"; + #warn $str; warn "tag is $tag, _ is $_"; + eval $str || die; + write; +} + +sub output { + local($_, $reformat) = @_; + if ($reformat) { + $cols = $SCREEN - $indent; + s/\s+/ /g; + s/^ //; + $str = "format STDOUT = \n~~" + . (" " x ($indent-2)) + . "^" . ("<" x ($cols - 5)) . "\n" + . '$_' . "\n\n.\n1"; + eval $str || die; + write; + } else { + s/^/' ' x $indent/gem; + s/^\s+\n$/\n/gm; + print; + } +} + +sub noremap { + local($thing_to_hide) = shift; + $thing_to_hide =~ tr/\000-\177/\200-\377/; + return $thing_to_hide; +} + +sub init_noremap { + die "unmatched init" if $mapready++; + if ( /[\200-\377]/ ) { + warn "hit bit char in input stream"; + } +} + +sub clear_noremap { + my $ready_to_print = $_[0]; + die "unmatched clear" unless $mapready--; + tr/\200-\377/\000-\177/; + # now for the E<>s, which have been hidden until now + # otherwise the interative \w<> processing would have + # been hosed by the E + s { + E< + ( [A-Za-z]+ ) + > + } { + do { + defined $HTML_Escapes{$1} + ? do { $HTML_Escapes{$1} } + : do { + warn "Unknown escape: $& in $_"; + "E<$1>"; + } + } + }egx if $ready_to_print; +} + +sub internal_lrefs { + local($_) = shift; + s{L]+)>}{$1}g; + my(@items) = split( /(?:,?\s+(?:and\s+)?)/ ); + my $retstr = "the "; + my $i; + for ($i = 0; $i <= $#items; $i++) { + $retstr .= "C<$items[$i]>"; + $retstr .= ", " if @items > 2 && $i != $#items; + $retstr .= " and " if $i+2 == @items; + } + + $retstr .= " entr" . ( @items > 1 ? "ies" : "y" ) + . " elsewhere in this document "; + + return $retstr; + +} + +BEGIN { + +%HTML_Escapes = ( + 'amp' => '&', # ampersand + 'lt' => '<', # left chevron, less-than + 'gt' => '>', # right chevron, greater-than + 'quot' => '"', # double quote + + "Aacute" => "\xC1", # capital A, acute accent + "aacute" => "\xE1", # small a, acute accent + "Acirc" => "\xC2", # capital A, circumflex accent + "acirc" => "\xE2", # small a, circumflex accent + "AElig" => "\xC6", # capital AE diphthong (ligature) + "aelig" => "\xE6", # small ae diphthong (ligature) + "Agrave" => "\xC0", # capital A, grave accent + "agrave" => "\xE0", # small a, grave accent + "Aring" => "\xC5", # capital A, ring + "aring" => "\xE5", # small a, ring + "Atilde" => "\xC3", # capital A, tilde + "atilde" => "\xE3", # small a, tilde + "Auml" => "\xC4", # capital A, dieresis or umlaut mark + "auml" => "\xE4", # small a, dieresis or umlaut mark + "Ccedil" => "\xC7", # capital C, cedilla + "ccedil" => "\xE7", # small c, cedilla + "Eacute" => "\xC9", # capital E, acute accent + "eacute" => "\xE9", # small e, acute accent + "Ecirc" => "\xCA", # capital E, circumflex accent + "ecirc" => "\xEA", # small e, circumflex accent + "Egrave" => "\xC8", # capital E, grave accent + "egrave" => "\xE8", # small e, grave accent + "ETH" => "\xD0", # capital Eth, Icelandic + "eth" => "\xF0", # small eth, Icelandic + "Euml" => "\xCB", # capital E, dieresis or umlaut mark + "euml" => "\xEB", # small e, dieresis or umlaut mark + "Iacute" => "\xCD", # capital I, acute accent + "iacute" => "\xED", # small i, acute accent + "Icirc" => "\xCE", # capital I, circumflex accent + "icirc" => "\xEE", # small i, circumflex accent + "Igrave" => "\xCD", # capital I, grave accent + "igrave" => "\xED", # small i, grave accent + "Iuml" => "\xCF", # capital I, dieresis or umlaut mark + "iuml" => "\xEF", # small i, dieresis or umlaut mark + "Ntilde" => "\xD1", # capital N, tilde + "ntilde" => "\xF1", # small n, tilde + "Oacute" => "\xD3", # capital O, acute accent + "oacute" => "\xF3", # small o, acute accent + "Ocirc" => "\xD4", # capital O, circumflex accent + "ocirc" => "\xF4", # small o, circumflex accent + "Ograve" => "\xD2", # capital O, grave accent + "ograve" => "\xF2", # small o, grave accent + "Oslash" => "\xD8", # capital O, slash + "oslash" => "\xF8", # small o, slash + "Otilde" => "\xD5", # capital O, tilde + "otilde" => "\xF5", # small o, tilde + "Ouml" => "\xD6", # capital O, dieresis or umlaut mark + "ouml" => "\xF6", # small o, dieresis or umlaut mark + "szlig" => "\xDF", # small sharp s, German (sz ligature) + "THORN" => "\xDE", # capital THORN, Icelandic + "thorn" => "\xFE", # small thorn, Icelandic + "Uacute" => "\xDA", # capital U, acute accent + "uacute" => "\xFA", # small u, acute accent + "Ucirc" => "\xDB", # capital U, circumflex accent + "ucirc" => "\xFB", # small u, circumflex accent + "Ugrave" => "\xD9", # capital U, grave accent + "ugrave" => "\xF9", # small u, grave accent + "Uuml" => "\xDC", # capital U, dieresis or umlaut mark + "uuml" => "\xFC", # small u, dieresis or umlaut mark + "Yacute" => "\xDD", # capital Y, acute accent + "yacute" => "\xFD", # small y, acute accent + "yuml" => "\xFF", # small y, dieresis or umlaut mark + + "lchevron" => "\xAB", # left chevron (double less than) + "rchevron" => "\xBB", # right chevron (double greater than) +); +} + diff --git a/pod/roffitall b/pod/roffitall new file mode 100644 index 0000000..024279a --- /dev/null +++ b/pod/roffitall @@ -0,0 +1,84 @@ +#!/bin/sh +#psroff -t -man -rC1 -rD1 -rF1 > /tmp/PerlDoc.ps 2>/tmp/PerlTOC.raw \ +nroff -man -rC1 -rD1 -rF1 > /tmp/PerlDoc.txt 2>/tmp/PerlTOC.nr.raw \ + /usr/local/man/man1/perl.1 \ + /usr/local/man/man1/perldata.1 \ + /usr/local/man/man1/perlsyn.1 \ + /usr/local/man/man1/perlop.1 \ + /usr/local/man/man1/perlre.1 \ + /usr/local/man/man1/perlrun.1 \ + /usr/local/man/man1/perlfunc.1 \ + /usr/local/man/man1/perlvar.1 \ + /usr/local/man/man1/perlsub.1 \ + /usr/local/man/man1/perlmod.1 \ + /usr/local/man/man1/perlref.1 \ + /usr/local/man/man1/perldsc.1 \ + /usr/local/man/man1/perllol.1 \ + /usr/local/man/man1/perlobj.1 \ + /usr/local/man/man1/perltie.1 \ + /usr/local/man/man1/perlbot.1 \ + /usr/local/man/man1/perldebug.1 \ + /usr/local/man/man1/perldiag.1 \ + /usr/local/man/man1/perlform.1 \ + /usr/local/man/man1/perlipc.1 \ + /usr/local/man/man1/perlsec.1 \ + /usr/local/man/man1/perltrap.1 \ + /usr/local/man/man1/perlstyle.1 \ + /usr/local/man/man1/perlxs.1 \ + /usr/local/man/man1/perlxstut.1 \ + /usr/local/man/man1/perlguts.1 \ + /usr/local/man/man1/perlcall.1 \ + /usr/local/man/man1/perlembed.1 \ + /usr/local/man/man1/perlpod.1 \ + /usr/local/man/man1/perlbook.1 \ + \ + /usr/local/man/man3/diagnostics.3 \ + /usr/local/man/man3/integer.3 \ + /usr/local/man/man3/less.3 \ + /usr/local/man/man3/lib.3 \ + /usr/local/man/man3/overload.3 \ + /usr/local/man/man3/sigtrap.3 \ + /usr/local/man/man3/strict.3 \ + /usr/local/man/man3/subs.3 \ + \ + /usr/local/man/man3/AnyDBM_File.3 \ + /usr/local/man/man3/AutoLoader.3 \ + /usr/local/man/man3/AutoSplit.3 \ + /usr/local/man/man3/Benchmark.3 \ + /usr/local/man/man3/Carp.3 \ + /usr/local/man/man3/Config.3 \ + /usr/local/man/man3/Cwd.3 \ + /usr/local/man/man3/DB_File.3 \ + /usr/local/man/man3/Devel::SelfStubber.3 \ + /usr/local/man/man3/DynaLoader.3 \ + /usr/local/man/man3/English.3 \ + /usr/local/man/man3/Env.3 \ + /usr/local/man/man3/Exporter.3 \ + /usr/local/man/man3/ExtUtils::Liblist.3 \ + /usr/local/man/man3/ExtUtils::MakeMaker.3 \ + /usr/local/man/man3/ExtUtils::Manifest.3 \ + /usr/local/man/man3/ExtUtils::Mkbootstrap.3 \ + /usr/local/man/man3/Fcntl.3 \ + /usr/local/man/man3/File::Basename.3 \ + /usr/local/man/man3/File::CheckTree.3 \ + /usr/local/man/man3/File::Find.3 \ + /usr/local/man/man3/FileHandle.3 \ + /usr/local/man/man3/File::Path.3 \ + /usr/local/man/man3/Getopt::Long.3 \ + /usr/local/man/man3/Getopt::Std.3 \ + /usr/local/man/man3/I18N::Collate.3 \ + /usr/local/man/man3/IPC::Open2.3 \ + /usr/local/man/man3/IPC::Open3.3 \ + /usr/local/man/man3/Net::Ping.3 \ + /usr/local/man/man3/POSIX.3 \ + /usr/local/man/man3/Safe.3 \ + /usr/local/man/man3/SelfLoader.3 \ + /usr/local/man/man3/Socket.3 \ + /usr/local/man/man3/Sys::Hostname.3 \ + /usr/local/man/man3/Term::Cap.3 \ + /usr/local/man/man3/Term::Complete.3 \ + /usr/local/man/man3/Test::Harness.3 \ + /usr/local/man/man3/Text::Abbrev.3 \ + /usr/local/man/man3/Text::Soundex.3 \ + /usr/local/man/man3/TieHash.3 \ + /usr/local/man/man3/Time::Local.3 diff --git a/pod/splitpod b/pod/splitpod new file mode 100644 index 0000000..fd327d8 --- /dev/null +++ b/pod/splitpod @@ -0,0 +1,47 @@ +#!/usr/bin/perl + +use PerlDoc::Functions; + +local $/ = ''; + +$cur = ''; +while (<>) { + + next unless /^=(?!cut)/ .. /^=cut/; + + if (s/=item (\S+)/$1/) { + #$cur = "POSIX::" . $1; + $cur = $1; + $syn{$cur} .= $_; + next; + } else { + #s,L $name.pod") || die "can't open $name.pod: $!"; + print POD <