unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
From: Mark H Weaver <mhw@netris.org>
To: Andy Wingo <wingo@pobox.com>
Cc: dwheeler@dwheeler.com, almkglor <almkglor@gmail.com>,
	12216 <12216@debbugs.gnu.org>
Subject: bug#12216: peek-char incorrectly *CONSUMES* eof
Date: Mon, 01 Apr 2013 17:27:14 -0400	[thread overview]
Message-ID: <87li920wnh.fsf@tines.lan> (raw)
In-Reply-To: <87bo9z3szq.fsf@tines.lan> (Mark H. Weaver's message of "Sun, 31 Mar 2013 22:05:45 -0400")

[-- Attachment #1: Type: text/plain, Size: 159 bytes --]

The prerequisite patches are now in stable-2.0.  Here's an updated patch
that applies against current stable-2.0.  Otherwise it has not changed.

      Mark



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: [PATCH] Peeks do not consume EOFs --]
[-- Type: text/x-diff, Size: 4721 bytes --]

From 7d9ebc691519af7236e1fec8dfefd5fc8784f875 Mon Sep 17 00:00:00 2001
From: Mark H Weaver <mhw@netris.org>
Date: Sun, 31 Mar 2013 19:06:51 -0400
Subject: [PATCH] Peeks do not consume EOFs.

Fixes <http://bugs.gnu.org/12216>.

* libguile/ports-internal.h (struct scm_port_internal): Add
  'pending_eof' flag.

* libguile/inline.h (scm_peek_byte_or_eof): Set 'pending_eof' flag
  before returning EOF.

* libguile/ports.c (scm_i_set_pending_eof): New function.
  (scm_i_clear_pending_eof): New static function.
  (scm_new_port_table_entry): Initialize 'pending_eof'.
  (scm_fill_input): Check for 'pending_eof'.
  (scm_end_input, scm_unget_byte, scm_seek): Clear 'pending_eof'.
  (scm_peek_char): Set 'pending_eof' flag before returning EOF.

* libguile/ports.h (scm_i_set_pending_eof): Add prototype.
---
 libguile/inline.h         |    5 ++++-
 libguile/ports-internal.h |    1 +
 libguile/ports.c          |   32 ++++++++++++++++++++++++++++++--
 libguile/ports.h          |    1 +
 4 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/libguile/inline.h b/libguile/inline.h
index 88ba7f7..fffe101 100644
--- a/libguile/inline.h
+++ b/libguile/inline.h
@@ -134,7 +134,10 @@ scm_peek_byte_or_eof (SCM port)
   if (pt->read_pos >= pt->read_end)
     {
       if (SCM_UNLIKELY (scm_fill_input (port) == EOF))
-	return EOF;
+        {
+          scm_i_set_pending_eof (port);
+          return EOF;
+        }
     }
 
   c = *pt->read_pos;
diff --git a/libguile/ports-internal.h b/libguile/ports-internal.h
index 73a788f..333d4fb 100644
--- a/libguile/ports-internal.h
+++ b/libguile/ports-internal.h
@@ -48,6 +48,7 @@ struct scm_port_internal
 {
   scm_t_port_encoding_mode encoding_mode;
   scm_t_iconv_descriptors *iconv_descriptors;
+  int pending_eof;
   SCM alist;
 };
 
diff --git a/libguile/ports.c b/libguile/ports.c
index becdbed..65e2e6f 100644
--- a/libguile/ports.c
+++ b/libguile/ports.c
@@ -241,6 +241,18 @@ scm_set_port_input_waiting (scm_t_bits tc, int (*input_waiting) (SCM))
   scm_ptobs[SCM_TC2PTOBNUM (tc)].input_waiting = input_waiting;
 }
 
+void
+scm_i_set_pending_eof (SCM port)
+{
+  SCM_PORT_GET_INTERNAL (port)->pending_eof = 1;
+}
+
+static void
+scm_i_clear_pending_eof (SCM port)
+{
+  SCM_PORT_GET_INTERNAL (port)->pending_eof = 0;
+}
+
 SCM
 scm_i_port_alist (SCM port)
 {
@@ -645,6 +657,7 @@ scm_new_port_table_entry (scm_t_bits tag)
   entry->input_cd = pti;   /* XXX pointer to the internal port structure */
   entry->output_cd = NULL; /* XXX unused */
 
+  pti->pending_eof = 0;
   pti->alist = SCM_EOL;
 
   SCM_SET_CELL_TYPE (z, tag);
@@ -1423,9 +1436,16 @@ int
 scm_fill_input (SCM port)
 {
   scm_t_port *pt = SCM_PTAB_ENTRY (port);
+  scm_t_port_internal *pti = SCM_PORT_GET_INTERNAL (port);
 
   assert (pt->read_pos == pt->read_end);
 
+  if (pti->pending_eof)
+    {
+      pti->pending_eof = 0;
+      return EOF;
+    }
+
   if (pt->read_buf == pt->putback_buf)
     {
       /* finished reading put-back chars.  */
@@ -1665,6 +1685,7 @@ scm_end_input (SCM port)
   long offset;
   scm_t_port *pt = SCM_PTAB_ENTRY (port);
 
+  scm_i_clear_pending_eof (port);
   if (pt->read_buf == pt->putback_buf)
     {
       offset = pt->read_end - pt->read_pos;
@@ -1688,6 +1709,7 @@ scm_unget_byte (int c, SCM port)
 {
   scm_t_port *pt = SCM_PTAB_ENTRY (port);
 
+  scm_i_clear_pending_eof (port);
   if (pt->read_buf == pt->putback_buf)
     /* already using the put-back buffer.  */
     {
@@ -1859,7 +1881,10 @@ SCM_DEFINE (scm_peek_char, "peek-char", 0, 1, 0,
       result = SCM_BOOL_F;
     }
   else if (c == EOF)
-    result = SCM_EOF_VAL;
+    {
+      scm_i_set_pending_eof (port);
+      result = SCM_EOF_VAL;
+    }
   else
     result = SCM_MAKE_CHAR (c);
 
@@ -1958,7 +1983,10 @@ SCM_DEFINE (scm_seek, "seek", 3, 0, 0,
 	SCM_MISC_ERROR ("port is not seekable", 
                         scm_cons (fd_port, SCM_EOL));
       else
-	rv = ptob->seek (fd_port, off, how);
+        {
+          scm_i_clear_pending_eof (fd_port);
+          rv = ptob->seek (fd_port, off, how);
+        }
       return scm_from_off_t_or_off64_t (rv);
     }
   else /* file descriptor?.  */
diff --git a/libguile/ports.h b/libguile/ports.h
index 53d5081..5c9334a 100644
--- a/libguile/ports.h
+++ b/libguile/ports.h
@@ -316,6 +316,7 @@ SCM_API SCM scm_port_column (SCM port);
 SCM_API SCM scm_set_port_column_x (SCM port, SCM line);
 SCM_API SCM scm_port_filename (SCM port);
 SCM_API SCM scm_set_port_filename_x (SCM port, SCM filename);
+SCM_INTERNAL void scm_i_set_pending_eof (SCM port);
 SCM_INTERNAL SCM scm_i_port_alist (SCM port);
 SCM_INTERNAL void scm_i_set_port_alist_x (SCM port, SCM alist);
 SCM_INTERNAL const char *scm_i_default_port_encoding (void);
-- 
1.7.10.4


  reply	other threads:[~2013-04-01 21:27 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <E1T29qG-00049i-Rt@fenris.runbox.com>
     [not found] ` <CAF+kUQVT7BmVaZ-XNFDNpaPFXyWUZv9msC_3m9iNa3yQzKw_1w@mail.gmail.com>
2012-08-17  1:53   ` bug#12216: peek-char incorrectly *CONSUMES* eof David A. Wheeler
2013-03-05 16:53     ` Andy Wingo
2013-03-05 19:17       ` David A. Wheeler
2013-03-07 21:32         ` Andy Wingo
2013-03-09  2:25           ` Daniel Hartwig
2013-03-09 17:11             ` David A. Wheeler
2013-03-10  0:23               ` Daniel Hartwig
2013-03-13 11:02               ` Andy Wingo
2013-03-13 13:09                 ` David A. Wheeler
2013-03-13 14:33                   ` Andy Wingo
2013-03-13 18:10                     ` Mark H Weaver
2013-03-13 18:22                       ` Andy Wingo
2013-03-14 17:13                         ` Mark H Weaver
2013-03-14 17:43                           ` David A. Wheeler
2013-03-30 22:37                         ` Mark H Weaver
2013-03-30 23:02                           ` David A. Wheeler
2013-04-01  2:05                           ` Mark H Weaver
2013-04-01 21:27                             ` Mark H Weaver [this message]
2013-04-01 21:33                               ` David A. Wheeler
2013-04-02  7:58                               ` Andy Wingo
2013-04-02 19:41                                 ` Mark H Weaver
2013-04-04 20:00                                   ` Andy Wingo
2013-04-04 21:53                                     ` Mark H Weaver

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87li920wnh.fsf@tines.lan \
    --to=mhw@netris.org \
    --cc=12216@debbugs.gnu.org \
    --cc=almkglor@gmail.com \
    --cc=dwheeler@dwheeler.com \
    --cc=wingo@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).