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?

>and (b) we never fill the buffer unless we are reading a
>byte out of it too. So we NEVER have a case where the ungetc function can be
>called with the ptr on the first byte of the buffer.


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]

Reply via email to