Skip to content

Commit 32e6532

Browse files
Chip Salzenbergsmpeters
Chip Salzenberg
authored andcommitted
[perl #60978] [PATCH] Tied filehandles can't distinguish eof forms
Message-ID: <[email protected]> p4raw-id: //depot/perl@35074
1 parent 94ccb80 commit 32e6532

File tree

3 files changed

+93
-41
lines changed

3 files changed

+93
-41
lines changed

pod/perltie.pod

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,19 @@ This method will be called when the C<getc> function is called.
952952

953953
sub GETC { print "Don't GETC, Get Perl"; return "a"; }
954954

955+
=item EOF this
956+
X<EOF>
957+
958+
This method will be called when the C<eof> function is called.
959+
960+
Starting with Perl 5.12, an additional integer parameter will be passed. It
961+
will be zero if C<eof> is called without parameter; C<1> if C<eof> is given
962+
a filehandle as a parameter, e.g. C<eof(FH)>; and C<2> in the very special
963+
case that the tied filehandle is C<ARGV> and C<eof> is called with an empty
964+
parameter list, e.g. C<eof()>.
965+
966+
sub EOF { not length $stringbuf }
967+
955968
=item CLOSE this
956969
X<CLOSE>
957970

pp_sys.c

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2025,51 +2025,60 @@ PP(pp_eof)
20252025
{
20262026
dVAR; dSP;
20272027
GV *gv;
2028+
IO *io;
2029+
MAGIC *mg;
20282030

2029-
if (MAXARG == 0) {
2030-
if (PL_op->op_flags & OPf_SPECIAL) { /* eof() */
2031-
IO *io;
2032-
gv = PL_last_in_gv = GvEGV(PL_argvgv);
2033-
io = GvIO(gv);
2034-
if (io && !IoIFP(io)) {
2035-
if ((IoFLAGS(io) & IOf_START) && av_len(GvAVn(gv)) < 0) {
2036-
IoLINES(io) = 0;
2037-
IoFLAGS(io) &= ~IOf_START;
2038-
do_open(gv, "-", 1, FALSE, O_RDONLY, 0, NULL);
2039-
if ( GvSV(gv) ) {
2040-
sv_setpvs(GvSV(gv), "-");
2041-
}
2042-
else {
2043-
GvSV(gv) = newSVpvs("-");
2044-
}
2045-
SvSETMAGIC(GvSV(gv));
2046-
}
2047-
else if (!nextargv(gv))
2048-
RETPUSHYES;
2049-
}
2050-
}
2031+
if (MAXARG)
2032+
gv = PL_last_in_gv = MUTABLE_GV(POPs); /* eof(FH) */
2033+
else if (PL_op->op_flags & OPf_SPECIAL)
2034+
gv = PL_last_in_gv = GvEGV(PL_argvgv); /* eof() - ARGV magic */
2035+
else
2036+
gv = PL_last_in_gv; /* eof */
2037+
2038+
if (!gv)
2039+
RETPUSHNO;
2040+
2041+
if ((io = GvIO(gv)) && (mg = SvTIED_mg((const SV *)io, PERL_MAGIC_tiedscalar))) {
2042+
PUSHMARK(SP);
2043+
XPUSHs(SvTIED_obj(MUTABLE_SV(io), mg));
2044+
/*
2045+
* in Perl 5.12 and later, the additional paramter is a bitmask:
2046+
* 0 = eof
2047+
* 1 = eof(FH)
2048+
* 2 = eof() <- ARGV magic
2049+
*/
2050+
if (MAXARG)
2051+
mPUSHi(1); /* 1 = eof(FH) - simple, explicit FH */
2052+
else if (PL_op->op_flags & OPf_SPECIAL)
2053+
mPUSHi(2); /* 2 = eof() - ARGV magic */
20512054
else
2052-
gv = PL_last_in_gv; /* eof */
2055+
mPUSHi(0); /* 0 = eof - simple, implicit FH */
2056+
PUTBACK;
2057+
ENTER;
2058+
call_method("EOF", G_SCALAR);
2059+
LEAVE;
2060+
SPAGAIN;
2061+
RETURN;
20532062
}
2054-
else
2055-
gv = PL_last_in_gv = MUTABLE_GV(POPs); /* eof(FH) */
20562063

2057-
if (gv) {
2058-
IO * const io = GvIO(gv);
2059-
MAGIC * mg;
2060-
if (io && (mg = SvTIED_mg((const SV *)io, PERL_MAGIC_tiedscalar))) {
2061-
PUSHMARK(SP);
2062-
XPUSHs(SvTIED_obj(MUTABLE_SV(io), mg));
2063-
PUTBACK;
2064-
ENTER;
2065-
call_method("EOF", G_SCALAR);
2066-
LEAVE;
2067-
SPAGAIN;
2068-
RETURN;
2064+
if (!MAXARG && (PL_op->op_flags & OPf_SPECIAL)) { /* eof() */
2065+
if (io && !IoIFP(io)) {
2066+
if ((IoFLAGS(io) & IOf_START) && av_len(GvAVn(gv)) < 0) {
2067+
IoLINES(io) = 0;
2068+
IoFLAGS(io) &= ~IOf_START;
2069+
do_open(gv, "-", 1, FALSE, O_RDONLY, 0, NULL);
2070+
if (GvSV(gv))
2071+
sv_setpvs(GvSV(gv), "-");
2072+
else
2073+
GvSV(gv) = newSVpvs("-");
2074+
SvSETMAGIC(GvSV(gv));
2075+
}
2076+
else if (!nextargv(gv))
2077+
RETPUSHYES;
20692078
}
20702079
}
20712080

2072-
PUSHs(boolSV(!gv || do_eof(gv)));
2081+
PUSHs(boolSV(do_eof(gv)));
20732082
RETURN;
20742083
}
20752084

t/op/tiehandle.t

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ my $data = "";
1010
my @data = ();
1111

1212
require './test.pl';
13-
plan(tests => 50);
13+
plan(tests => 63);
1414

1515
sub compare {
1616
local $Level = $Level + 1;
@@ -61,6 +61,11 @@ sub READ {
6161
3;
6262
}
6363

64+
sub EOF {
65+
::compare(EOF => @_);
66+
@data ? '' : 1;
67+
}
68+
6469
sub WRITE {
6570
::compare(WRITE => @_);
6671
$data = substr($_[1],$_[3] || 0, $_[2]);
@@ -69,7 +74,6 @@ sub WRITE {
6974

7075
sub CLOSE {
7176
::compare(CLOSE => @_);
72-
7377
5;
7478
}
7579

@@ -92,11 +96,18 @@ is($r, 1);
9296
$r = printf $fh @expect[2,3];
9397
is($r, 2);
9498

95-
$text = (@data = ("the line\n"))[0];
99+
@data = ("the line\n");
100+
@expect = (EOF => $ob, 1);
101+
is(eof($fh), '');
102+
103+
$text = $data[0];
96104
@expect = (READLINE => $ob);
97105
$ln = <$fh>;
98106
is($ln, $text);
99107

108+
@expect = (EOF => $ob, 0);
109+
is(eof, 1);
110+
100111
@expect = ();
101112
@in = @data = qw(a line at a time);
102113
@line = <$fh>;
@@ -273,3 +284,22 @@ is($r, 1);
273284
sub READLINE { "foobar\n" }
274285
}
275286

287+
{
288+
# make sure the new eof() features work with @ARGV magic
289+
local *ARGV;
290+
@ARGV = ('haha');
291+
292+
@expect = (TIEHANDLE => 'Implement');
293+
$ob = tie *ARGV, 'Implement';
294+
is(ref($ob), 'Implement');
295+
is(tied(*ARGV), $ob);
296+
297+
@data = ("stuff\n");
298+
@expect = (EOF => $ob, 1);
299+
is(eof(ARGV), '');
300+
@expect = (EOF => $ob, 2);
301+
is(eof(), '');
302+
shift @data;
303+
@expect = (EOF => $ob, 0);
304+
is(eof, 1);
305+
}

0 commit comments

Comments
 (0)