Craig A. Berry [mailto:[EMAIL PROTECTED]] writes:
> At 09:56 PM 5/21/2002 +0100, Nick Ing-Simmons wrote:
> 
> >>"The size of the pushback buffer for the DEC C RTL is 1, 
> >>and once it is full additional calls to ungetc() will fail. 
>
> >Ah. But note though that the iperlsys.h stuff does some 
> >other hackery.
> 
> Yes, it's quite possible that's the reason for the hackery in 
> the first place.
> 
> >Break-points in PerlStdio_unread() would be informative - if 
> >we ever get there then VMS is going to exercise paths that
> >other stdio's have not pipe-cleaned.
> 
> Well, I'm in there now.  I've been able to show that we only call 
> PerlSIO_ungetc once during the run of my reduced test program.  The 
> character we are trying to unget is 0xF1 (0d241).  Since I 
> end up in the middle of the C library when I step into
> PerlSIO_ungetc, I think that tells us all the shenanigans the macro
> goes through to avoid calling decc$ungetc are to no avail and it
> does wind up calling it.  I believe the reason is that
> _ptr == _base and it will only do its pointer manipulations
> when _ptr > _base.  I don't know enough about what those things are
> to know what that means, but here's what the _iobuf structure looks
> like:
> 
> **PERLIO\PerlIOStdio_unread\s
>     _cnt:       2789
>     _ptr:       8839168
>     _base:      8839168
>     _flag:      73
>     _padfile:   3
>     _pad1:      4
>     _pad2:      0
>     _file:      3

_cnt is the number of valid bytes remaining in the input buffer.
_ptr is the address of the next valid byte.
_base is the address of the start of the buffer.
_file is the file descriptor of this io attachment.
_flag is where EOF, IOERR, etc. are kept.

See stdio.h for the values of flag (_IOxxxx).

It seems to me that it makes no sense to ungetc() before you have done a
getc().  However, the C standard seems to permit this!

See 7.9.7.11 in the 1990 C standard, and 7.19.7.10 in the 1999 C Standard.
I can type in the paragraph if you don't have access to the standard. The
two standards have almost identical language for ungetc; just some minor
editorial differences.

VOS allows the caller to push back a byte when at the beginning of the
buffer (i.e., a byte that can't possibly have been read from this buffer),
and it looks like we clobber some neighboring storage to make it happen.
Whoops.  But as long as the clobber is not itself a problem, we'd allow
ungetc with the quoted values.

The comment in iperlsys.h that says "Unusual definition of ungetc() here to
accomodate fast_sv_gets()'
belief that it can mix getc/ungetc with reads from stdio buffer" is odd
because I don't see any language in the C standard that would prohibit such
a mixing.

My tentative suggestion is to nix the special definition of ungetc() for VMS
and see what happens if you use the standard logic.

Hope this helps a little.

PG








Reply via email to