Craig A. Berry [mailto:[EMAIL PROTECTED]] asks: > At 01:18 PM 5/22/2002 -0400, Green, Paul wrote: > >Nicholas Clark [mailto:[EMAIL PROTECTED]] asks: > >> Note that sv.c has this in sv__gets: > >> > >> #if defined(VMS) && defined(PERLIO_IS_STDIO) > >> /* An ungetc()d char is handled separately from the regular > >> * buffer, so we getc() it back out and stuff it in the buffer. > >> */ > >> i = PerlIO_getc(fp); > >> if (i == EOF) return 0; > >> *(--((*fp)->_ptr)) = (unsigned char) i; > >> (*fp)->_cnt++; > >> #endif > >> > >> How that code can know whether there is space at the start of > >> the buffer to do the stuffing, I don't know. > > Good question. It does not compare _ptr with _base as the > macro in iperlsys.h does. > > >I wondered this too. I could only check our own > >implementation. We use the same trick of putting the > >ungetc's character right back into the input > >buffer. The reason it works is that (a) we only permit you > >to ungetc a single character, > > How do you guarantee you'll never hit the code in > PerlIOStdio_unread that does ungetc inside a loop?
We will hit it. But it will fail after the first ungetc. We have hidden variables in the stream data structure that tell us whether an ungetc is permitted. The ungetc function sets and checks these hidden variables such that any attempt to do two ungetc's in a row will cause subsequent ungetc's to return an error. > I'm going to give the following a try and see what happens: > > --- sv.c;-0 Sat May 18 18:59:19 2002 > +++ sv.c Wed May 22 12:40:17 2002 > @@ -5732,12 +5732,12 @@ > > #if defined(VMS) && defined(PERLIO_IS_STDIO) > /* An ungetc()d char is handled separately from the regular > - * buffer, so we getc() it back out and stuff it in the buffer. > + * buffer, so we seek to our current position, which is a > + * noop except for synching up ungetc()'s special 1-byte > + * pushback buffer with the main stdio buffer. > */ > - i = PerlIO_getc(fp); > + i = PerlSIO_fseek(fp, (Off_t) 0, SEEK_CUR); > if (i == EOF) return 0; > - *(--((*fp)->_ptr)) = (unsigned char) i; > - (*fp)->_cnt++; > #endif > > /* Here is some breathtakingly efficient cheating */ > [end of not yet a patch] My copy of the C Standard says that doing a fseek, fsetpos or rewind discards any pushed-back characters. Is that what you want to happen? PG
