diff options
author | Gurusamy Sarathy <gsar@cpan.org> | 1999-02-14 05:51:56 +0000 |
---|---|---|
committer | Gurusamy Sarathy <gsar@cpan.org> | 1999-02-14 05:51:56 +0000 |
commit | fbad3eb55c1f8c84d1dfd0e484ecddeffc891e79 (patch) | |
tree | f3886be033e03113de9177f18cdf413345741e1c | |
parent | 428f79ef10ad4e14667125f22397bceac3e2c65e (diff) | |
download | perl-fbad3eb55c1f8c84d1dfd0e484ecddeffc891e79.tar.gz |
slurping an empty file should return '' rather than undef, with
commensurate effects on ARGV processing
p4raw-id: //depot/perl@2910
-rw-r--r-- | pod/perldelta.pod | 36 | ||||
-rw-r--r-- | pod/perlfunc.pod | 15 | ||||
-rw-r--r-- | pod/perlop.pod | 15 | ||||
-rw-r--r-- | pod/perlvar.pod | 4 | ||||
-rw-r--r-- | pp_hot.c | 12 | ||||
-rw-r--r-- | sv.h | 1 | ||||
-rwxr-xr-x | t/io/argv.t | 21 |
7 files changed, 88 insertions, 16 deletions
diff --git a/pod/perldelta.pod b/pod/perldelta.pod index efa52de096..d858508fa1 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -125,6 +125,25 @@ now correctly prints "3|a", instead of "2|a". The new format type 'Z' is useful for packing and unpacking null-terminated strings. See L<perlfunc/"pack">. +=head1 Significant bug fixes + +=head2 E<lt>HANDLEE<gt> on empty files + +With C<$/> set to C<undef>, slurping an empty file returns a string of +zero length (instead of C<undef>, as it used to) for the first time the +HANDLE is read. Subsequent reads yield C<undef>. + +This means that the following will append "foo" to an empty file (it used +to not do anything before): + + perl -0777 -pi -e 's/^/foo/' empty_file + +Note that the behavior of: + + perl -pi -e 's/^/foo/' empty_file + +is unchanged (it continues to leave the file empty). + =head1 Supported Platforms =over 4 @@ -225,8 +244,25 @@ stat(2) might lie, while access(2) knows better. =head1 Utility Changes +=head2 New Modules + +=over + Todo. +=back + +=head2 Changes in existing modules + +=over + +=item Exporter + +Exporter::expand() takes an import list and returns the expanded +list of names. + +=back + =head1 Documentation Changes =over 4 diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod index 1495514bac..0d09e855e8 100644 --- a/pod/perlfunc.pod +++ b/pod/perlfunc.pod @@ -2841,10 +2841,17 @@ C<chdir()> there, it would have been testing the wrong file. =item readline EXPR -Reads from the filehandle whose typeglob is contained in EXPR. In scalar context, a single line -is read and returned. In list context, reads until end-of-file is -reached and returns a list of lines (however you've defined lines -with C<$/> or C<$INPUT_RECORD_SEPARATOR>). +Reads from the filehandle whose typeglob is contained in EXPR. In scalar +context, each call reads and returns the next line, until end-of-file is +reached, whereupon the subsequent call returns undef. In list context, +reads until end-of-file is reached and returns a list of lines. Note that +the notion of "line" used here is however you may have defined it +with C<$/> or C<$INPUT_RECORD_SEPARATOR>). See L<perlvar/"$/">. + +When C<$/> is set to C<undef> and when readline() is in a scalar +context (i.e. file slurp mode), it returns C<''> the first time, +followed by C<undef> subsequently. + This is the internal function implementing the C<E<lt>EXPRE<gt>> operator, but you can use it directly. The C<E<lt>EXPRE<gt>> operator is discussed in more detail in L<perlop/"I/O Operators">. diff --git a/pod/perlop.pod b/pod/perlop.pod index b386651eee..73066c1119 100644 --- a/pod/perlop.pod +++ b/pod/perlop.pod @@ -1445,6 +1445,7 @@ to change. =head2 I/O Operators There are several I/O operators you should know about. + A string enclosed by backticks (grave accents) first undergoes variable substitution just like a double quoted string. It is then interpreted as a command, and the output of that command is the value @@ -1462,9 +1463,12 @@ The generalized form of backticks is C<qx//>. (Because backticks always undergo shell expansion as well, see L<perlsec> for security concerns.) -Evaluating a filehandle in angle brackets yields the next line from -that file (newline, if any, included), or C<undef> at end of file. -Ordinarily you must assign that value to a variable, but there is one +In a scalar context, evaluating a filehandle in angle brackets yields the +next line from that file (newline, if any, included), or C<undef> at +end-of-file. When C<$/> is set to C<undef> (i.e. file slurp mode), +it returns C<''> the first time, followed by C<undef> subsequently. + +Ordinarily you must assign the returned value to a variable, but there is one situation where an automatic assignment happens. I<If and ONLY if> the input symbol is the only thing inside the conditional of a C<while> or C<for(;;)> loop, the value is automatically assigned to the variable @@ -1501,13 +1505,16 @@ The filehandles STDIN, STDOUT, and STDERR are predefined. (The filehandles C<stdin>, C<stdout>, and C<stderr> will also work except in packages, where they would be interpreted as local identifiers rather than global.) Additional filehandles may be created with the open() -function. See L<perlfunc/open()> for details on this. +function. See L<perlfunc/open> for details on this. If a E<lt>FILEHANDLEE<gt> 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 element. It's easy to make a I<LARGE> data space this way, so use with care. +E<lt>FILEHANDLEE<gt> may also be spelt readline(FILEHANDLE). See +L<perlfunc/readline>. + The null filehandle E<lt>E<gt> is special and can be used to emulate the behavior of B<sed> and B<awk>. Input from E<lt>E<gt> comes either from standard input, or from each file listed on the command line. Here's diff --git a/pod/perlvar.pod b/pod/perlvar.pod index b9b0ce6c0a..44124d6bb0 100644 --- a/pod/perlvar.pod +++ b/pod/perlvar.pod @@ -250,8 +250,8 @@ line. Setting it to C<"\n\n"> will blindly assume that the next input character belongs to the next paragraph, even if it's a newline. (Mnemonic: / is used to delimit line boundaries when quoting poetry.) - undef $/; - $_ = <FH>; # whole file now here + undef $/; # enable "slurp" mode + $_ = <FH>; # whole file now here s/\n[ \t]+/ /g; Remember: the value of $/ is a string, not a regexp. AWK has to be @@ -1297,8 +1297,18 @@ do_readline(void) sv = sv_2mortal(NEWSV(57, 80)); offset = 0; } + +/* flip-flop EOF state for a snarfed empty file */ +#define SNARF_EOF(gimme,rs,io,sv) \ + ((gimme != G_SCALAR || SvCUR(sv) \ + || (IoFLAGS(io) & IOf_NOLINE) || IoLINES(io) || !RsSNARF(rs)) \ + ? ((IoFLAGS(io) &= ~IOf_NOLINE), TRUE) \ + : ((IoFLAGS(io) |= IOf_NOLINE), FALSE)) + for (;;) { - if (!sv_gets(sv, fp, offset)) { + if (!sv_gets(sv, fp, offset) + && (type == OP_GLOB || SNARF_EOF(gimme, PL_rs, io, sv))) + { PerlIO_clearerr(fp); if (IoFLAGS(io) & IOf_ARGV) { fp = nextargv(PL_last_in_gv); @@ -313,6 +313,7 @@ struct xpvio { #define IOf_FLUSH 4 /* this fp wants a flush after write op */ #define IOf_DIDTOP 8 /* just did top of form */ #define IOf_UNTAINT 16 /* consider this fp (and its data) "safe" */ +#define IOf_NOLINE 32 /* slurped a pseudo-line from empty file */ /* The following macros define implementation-independent predicates on SVs. */ diff --git a/t/io/argv.t b/t/io/argv.t index d99865e142..cb2ffb346e 100755 --- a/t/io/argv.t +++ b/t/io/argv.t @@ -1,10 +1,8 @@ #!./perl -# $RCSfile: argv.t,v $$Revision: 4.1 $$Date: 92/08/07 18:27:25 $ +print "1..6\n"; -print "1..5\n"; - -open(try, '>Io.argv.tmp') || (die "Can't open temp file."); +open(try, '>Io.argv.tmp') || (die "Can't open temp file: $!"); print try "a line\n"; close try; @@ -45,4 +43,17 @@ if ($y eq "1a line\n2a line\n3a line\n") else {print "not ok 5\n";} -unlink 'Io.argv.tmp'; +open(try, '>Io.argv.tmp') or die "Can't open temp file: $!"; +close try; +@ARGV = 'Io.argv.tmp'; +$^I = ''; +$/ = undef; +while (<>) { + s/^/ok 6\n/; + print; +} +open(try, '<Io.argv.tmp') or die "Can't open temp file: $!"; +print while <try>; +close try; + +END { unlink 'Io.argv.tmp' } |