guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PR guile/21104] Fix GDB build failure with Guile 2.2


From: Doug Evans
Subject: [RFC PR guile/21104] Fix GDB build failure with Guile 2.2
Date: Mon, 22 Jan 2018 07:10:09 +0000

Hi.

This patch gets gdb building again with guile 2.2.
Regression tested with guile 2.0.{13,14} and 2.2.3 on amd64-linux.
[might also test with 2.2.{0,1,2}]

I still need to at least add a NEWS item and update the docs as these
Scheme functions are no longer present:
        memory-port-read-buffer-size, set-memory-port-read-buffer-size!
        memory-port-write-buffer-size, set-memory-port-write-buffer-size!
For guile >= 2.2 we just use existing buffering. Ergo RFC.

In time I think we could delete Guile 2.0 support and that would
simplify the code, but no rush.
[And if someone wants to redo the 2.0 support to further reduced diffs
that may be a possibility.]

2018-01-21  Doug Evans  <address@hidden>

        PR guile/21104
        * configure.ac: Add guile-2.2 back.
        * configure: Regenerate.
        * guile/scm-ports.c (PORTS_V22): New macro.
        (ioscm_memory_port) [!PORTS_V22]: Make read_buf_size,write_buf_size
        !PORTS_V22 only.
        (port_type_t): New type.
        (stdio_port_type): Renamed from stdio_port_desc.
        (stdio_port_type_name): Renamed from stdio_port_desc_name.
        (memory_port_type): Renamed from memory_port_desc.
        (memmory_port_type_name): Renamed from memory_port_desc_name.
        (natural_buf_size) [PORTS_V22]: New variable.
        (ioscm_open_port): New argument stream. All callers updated.
        (ioscm_read, ioscm_write) [PORTS_V22]: New functions.
        (ioscm_init_gdb_stdio_port) [PORTS_V22]: Adapt for use in Guile >= 2.2.
        (gdbscm_is_stdio_port): New function.
        (gdbscm_stdio_port_p): Call it.
        (gdbscm_get_natural_buffer_sizes, gdbscm_memory_port_seek)
        (gdbscm_memory_port_read, gdbscm_memory_port_write) [PORTS_V22]: New
        functions.
        (gdbscm_memory_port_print): Adapt for use in Guile >= 2.2.
        (ioscm_init_memory_port_type): Ditto.
        (ioscm_init_memory_stream): Replaces ioscm_init_memory_port.
        (ioscm_init_memory_port_buffers): New function.
        (gdbscm_open_memory): Update.
        (gdbscm_is_memory_port): Adapt for use in Guile >= 2.2.
        (port_functions) [!PORTS_V22]: Only define Guile functions
        memory-port-read-buffer-size, set-memory-port-read-buffer-size!,
        memory-port-write-buffer-size, set-memory-port-write-buffer-size!
        for Guile < 2.2.
        (gdbscm_initialize_ports): Only initialize out_of_range_buf_size if
        !PORTS_V22.

diff --git a/gdb/configure.ac b/gdb/configure.ac
index d4133ea71e..50ca76b3ca 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -1149,7 +1149,7 @@ AC_MSG_RESULT([$with_guile])
 dnl We check guile with pkg-config.
 AC_PATH_PROG(pkg_config_prog_path, pkg-config, missing)
 
-try_guile_versions="guile-2.0"
+try_guile_versions="guile-2.0 guile-2.2"
 have_libguile=no
 case "${with_guile}" in
 no)
diff --git a/gdb/guile/scm-ports.c b/gdb/guile/scm-ports.c
index 26361e4a0c..01fe617641 100644
--- a/gdb/guile/scm-ports.c
+++ b/gdb/guile/scm-ports.c
@@ -36,6 +36,13 @@
 #endif
 #endif
 
+/* Guile ports radically changed in Guile 2.2.
+   Note: We don't support Guile < 2.0.
+   TODO(dje): Suggest deprecating and then removing Guile 2.0 support
+   at some point in the future.  */
+#define PORTS_V22 (SCM_MAJOR_VERSION > 2 \
+                  || SCM_MAJOR_VERSION == 2 && SCM_MINOR_VERSION >= 2)
+
 /* A ui-file for sending output to Guile.  */
 
 class ioscm_file_port : public ui_file
@@ -66,12 +73,14 @@ typedef struct
      This value is always in the range [0, size].  */
   ULONGEST current;
 
+#if !PORTS_V22
   /* The size of the internal r/w buffers.
      Scheme ports aren't a straightforward mapping to memory r/w.
      Generally the user specifies how much to r/w and all access is
      unbuffered.  We don't try to provide equivalent access, but we allow
      the user to specify these values to help get something similar.  */
   unsigned read_buf_size, write_buf_size;
+#endif
 } ioscm_memory_port;
 
 /* Copies of the original system input/output/error ports.
@@ -80,11 +89,17 @@ static SCM orig_input_port_scm;
 static SCM orig_output_port_scm;
 static SCM orig_error_port_scm;
 
-/* This is the stdio port descriptor, scm_ptob_descriptor.  */
-static scm_t_bits stdio_port_desc;
+#if PORTS_V22
+typedef scm_t_port_type *port_type_t;
+#else
+typedef scm_t_bits port_type_t;
+#endif
+
+/* This is the stdio port type.  */
+static port_type_t stdio_port_type;
 
 /* Note: scm_make_port_type takes a char * instead of a const char *.  */
-static /*const*/ char stdio_port_desc_name[] = "gdb:stdio-port";
+static /*const*/ char stdio_port_type_name[] = "gdb:stdio-port";
 
 /* Names of each gdb port.  */
 static const char input_port_name[] = "gdb:stdin";
@@ -101,11 +116,18 @@ static SCM error_port_scm;
 /* Internal enum for specifying output port.  */
 enum oport { GDB_STDOUT, GDB_STDERR };
 
-/* This is the memory port descriptor, scm_ptob_descriptor.  */
-static scm_t_bits memory_port_desc;
+/* This is the memory port type.  */
+static port_type_t memory_port_type;
 
 /* Note: scm_make_port_type takes a char * instead of a const char *.  */
-static /*const*/ char memory_port_desc_name[] = "gdb:memory-port";
+static /*const*/ char memory_port_type_name[] = "gdb:memory-port";
+
+#if PORTS_V22
+
+/* The maximum values to use for get_natural_buffer_sizes.  */
+static const unsigned natural_buf_size = 16;
+
+#else
 
 /* The default amount of memory to fetch for each read/write request.
    Scheme ports don't provide a way to specify the size of a read,
@@ -120,6 +142,8 @@ static const unsigned default_write_buf_size = 16;
 static const unsigned min_memory_port_buf_size = 1;
 static const unsigned max_memory_port_buf_size = 4096;
 
+#endif
+
 /* "out of range" error message for buf sizes.  */
 static char *out_of_range_buf_size;
 
@@ -132,7 +156,7 @@ static SCM size_keyword;
    Newer versions of Guile (2.1.x) have scm_c_make_port.  */
 
 static SCM
-ioscm_open_port (scm_t_bits port_type, long mode_bits)
+ioscm_open_port (port_type_t port_type, long mode_bits, scm_t_bits stream)
 {
   SCM port;
 
@@ -140,9 +164,13 @@ ioscm_open_port (scm_t_bits port_type, long mode_bits)
   scm_i_scm_pthread_mutex_lock (&scm_i_port_table_mutex);
 #endif
 
+#if PORTS_V22
+  port = scm_c_make_port (port_type, mode_bits, stream);
+#else
   port = scm_new_port_table_entry (port_type);
-
   SCM_SET_CELL_TYPE (port, port_type | mode_bits);
+  SCM_SETSTREAM(port, stream);
+#endif
 
 #if 0 /* TODO: Guile doesn't export this.  What to do?  */
   scm_i_pthread_mutex_unlock (&scm_i_port_table_mutex);
@@ -150,6 +178,23 @@ ioscm_open_port (scm_t_bits port_type, long mode_bits)
 
   return port;
 }
+
+/* Like fputstrn_filtered, but don't escape characters, except nul.
+   Also like fputs_filtered, but a length is specified.  */
+
+static void
+fputsn_filtered (const char *s, size_t size, struct ui_file *stream)
+{
+  size_t i;
+
+  for (i = 0; i < size; ++i)
+    {
+      if (s[i] == '\0')
+       fputs_filtered ("\\000", stream);
+      else
+       fputc_filtered (s[i], stream);
+    }
+}
 
 /* Support for connecting Guile's stdio ports to GDB's stdio ports.  */
 
@@ -184,11 +229,10 @@ ioscm_input_waiting (SCM port)
 
     if (use_poll)
       {
-       /* Guile doesn't export SIGINT hooks like Python does.
-          For now pass EINTR to scm_syserror, that's what fports.c does.  */
        if (poll (&pollfd, 1, 0) < 0)
-         scm_syserror (FUNC_NAME);
-
+         {
+           scm_syserror (FUNC_NAME);
+         }
        return pollfd.revents & POLLIN ? 1 : 0;
       }
   }
@@ -210,14 +254,79 @@ ioscm_input_waiting (SCM port)
                                      &timeout);
     if (num_found < 0)
       {
-       /* Guile doesn't export SIGINT hooks like Python does.
-          For now pass EINTR to scm_syserror, that's what fports.c does.  */
         scm_syserror (FUNC_NAME);
       }
     return num_found > 0 && FD_ISSET (fdes, &input_fds);
   }
 }
 
+#if PORTS_V22
+
+static size_t
+ioscm_read (SCM port, SCM dst, size_t start, size_t count)
+{
+  /* Borrowed from libguile/fports.c.  */
+  auto ptr = reinterpret_cast<char*>(SCM_BYTEVECTOR_CONTENTS (dst) + start);
+  ssize_t ret;
+
+  /* If we're called on stdout,stderr, punt.  */
+  if (! scm_is_eq (port, input_port_scm))
+    return 0; /* EOF */
+
+  gdb_flush (gdb_stdout);
+  gdb_flush (gdb_stderr);
+
+ retry:
+  ret = ui_file_read (gdb_stdin, ptr, count);
+  if (ret < 0)
+    {
+      if (errno == EINTR)
+        {
+          scm_async_tick ();
+          goto retry;
+        }
+      if (errno == EWOULDBLOCK || errno == EAGAIN)
+       {
+         /* See the discussion of non-blocking I/O in the Guile manual.  */
+         return -1;
+       }
+      scm_syserror ("ioscm_read");
+    }
+  return ret;
+}
+
+static size_t
+ioscm_write (SCM port, SCM src, size_t start, size_t count)
+{
+  /* Borrowed from libguile/fports.c.  */
+  auto ptr = reinterpret_cast<char*>(SCM_BYTEVECTOR_CONTENTS (src) + start);
+  ssize_t ret;
+
+  /* If we're called on stdin, punt.  */
+  if (scm_is_eq (port, input_port_scm))
+    {
+      errno = EIO;
+      scm_syserror("ioscm_write");
+    }
+
+  TRY
+    {
+      if (scm_is_eq (port, error_port_scm))
+       fputsn_filtered (ptr, count, gdb_stderr);
+      else
+       fputsn_filtered (ptr, count, gdb_stdout);
+    }
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDBSCM_HANDLE_GDB_EXCEPTION (except);
+    }
+  END_CATCH
+
+  return count;
+}
+
+#else /* !PORTS_V22 */
+
 /* The scm_t_ptob_descriptor.fill_input "method".  */
 
 static int
@@ -245,29 +354,11 @@ ioscm_fill_input (SCM port)
   return *pt->read_buf;
 }
 
-/* Like fputstrn_filtered, but don't escape characters, except nul.
-   Also like fputs_filtered, but a length is specified.  */
-
-static void
-fputsn_filtered (const char *s, size_t size, struct ui_file *stream)
-{
-  size_t i;
-
-  for (i = 0; i < size; ++i)
-    {
-      if (s[i] == '\0')
-       fputs_filtered ("\\000", stream);
-      else
-       fputc_filtered (s[i], stream);
-    }
-}
-
 /* Write to gdb's stdout or stderr.  */
 
 static void
 ioscm_write (SCM port, const void *data, size_t size)
 {
-
   /* If we're called on stdin, punt.  */
   if (scm_is_eq (port, input_port_scm))
     return;
@@ -301,6 +392,8 @@ ioscm_flush (SCM port)
     gdb_flush (gdb_stdout);
 }
 
+#endif
+
 /* Initialize the gdb stdio port type.
 
    N.B. isatty? will fail on these ports, it is only supported for file
@@ -309,13 +402,23 @@ ioscm_flush (SCM port)
 static void
 ioscm_init_gdb_stdio_port (void)
 {
-  stdio_port_desc = scm_make_port_type (stdio_port_desc_name,
-                                       ioscm_fill_input, ioscm_write);
+  stdio_port_type = scm_make_port_type (stdio_port_type_name,
+#if PORTS_V22
+                                       ioscm_read,
+#else
+                                       ioscm_fill_input,
+#endif
+                                       ioscm_write);
+
+  scm_set_port_input_waiting (stdio_port_type, ioscm_input_waiting);
 
-  scm_set_port_input_waiting (stdio_port_desc, ioscm_input_waiting);
-  scm_set_port_flush (stdio_port_desc, ioscm_flush);
+#if !PORTS_V22
+  scm_set_port_flush (stdio_port_type, ioscm_flush);
+#endif
 }
 
+#if !PORTS_V22
+
 /* Subroutine of ioscm_make_gdb_stdio_port to simplify it.
    Set up the buffers of port PORT.
    MODE_BITS are the mode bits of PORT.  */
@@ -358,6 +461,8 @@ ioscm_init_stdio_buffers (SCM port, long mode_bits)
   pt->write_end = pt->write_buf + pt->write_buf_size;
 }
 
+#endif
+
 /* Create a gdb stdio port.  */
 
 static SCM
@@ -388,23 +493,36 @@ ioscm_make_gdb_stdio_port (int fd)
     }
 
   mode_bits = scm_mode_bits ((char *) mode_str);
-  port = ioscm_open_port (stdio_port_desc, mode_bits);
+  port = ioscm_open_port (stdio_port_type, mode_bits, 0);
 
   scm_set_port_filename_x (port, gdbscm_scm_from_c_string (name));
 
+#if !PORTS_V22
   ioscm_init_stdio_buffers (port, mode_bits);
+#endif
 
   return port;
 }
 
+/* Return non-zero if OBJ is a stdio port.  */
+
+static int
+gdbscm_is_stdio_port (SCM obj)
+{
+  /* This is copied from SCM_FPORTP.  */
+#if PORTS_V22
+  return SCM_PORTP (obj) && SCM_PORT_TYPE (obj) == stdio_port_type;
+#else
+  return !SCM_IMP (obj) && SCM_TYP16 (obj) == stdio_port_type;
+#endif
+}
+
 /* (stdio-port? object) -> boolean */
 
 static SCM
-gdbscm_stdio_port_p (SCM scm)
+gdbscm_stdio_port_p (SCM obj)
 {
-  /* This is copied from SCM_FPORTP.  */
-  return scm_from_bool (!SCM_IMP (scm)
-                       && (SCM_TYP16 (scm) == stdio_port_desc));
+  return scm_from_bool (gdbscm_is_stdio_port (obj));
 }
 
 /* GDB's ports are accessed via functions to keep them read-only.  */
@@ -567,6 +685,94 @@ ioscm_lseek_address (ioscm_memory_port *iomem, LONGEST 
offset, int whence)
   return 1;
 }
 
+#if PORTS_V22
+
+/* The semantics get weird if the buffer size is larger than the port range,
+   so provide a better default buffer size.  */
+
+static void
+gdbscm_get_natural_buffer_sizes (SCM port, size_t *read_size,
+                                size_t *write_size)
+{
+  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
+
+  size_t size = natural_buf_size;
+  if (iomem->size < size)
+    size = iomem->size;
+  *read_size = *write_size = size;
+}
+
+static scm_t_off
+gdbscm_memory_port_seek (SCM port, scm_t_off offset, int whence)
+{
+  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
+  scm_t_off result;
+  int rc;
+
+  if (ioscm_lseek_address (iomem, offset, whence) == 0)
+    {
+      gdbscm_out_of_range_error (FUNC_NAME, 0,
+                                gdbscm_scm_from_longest (offset),
+                                _("bad seek"));
+    }
+
+  return iomem->current;
+}
+
+static size_t
+gdbscm_memory_port_read (SCM port, SCM dst, size_t start, size_t count)
+{
+  /* Borrowed from libguile/fports.c.  */
+  auto ptr = reinterpret_cast<gdb_byte*>(SCM_BYTEVECTOR_CONTENTS (dst) + 
start);
+  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
+  size_t to_read;
+
+  /* "current" is the offset of the first byte we want to read.  */
+  gdb_assert (iomem->current <= iomem->size);
+  if (iomem->current == iomem->size)
+    return 0; /* EOF */
+
+  /* Don't read outside the allowed memory range.  */
+  to_read = count;
+  if (to_read > iomem->size - iomem->current)
+    to_read = iomem->size - iomem->current;
+
+  if (target_read_memory (iomem->start + iomem->current, ptr, to_read) != 0)
+    gdbscm_memory_error (FUNC_NAME, _("error reading memory"), SCM_EOL);
+
+  iomem->current += to_read;
+  return to_read;
+}
+
+static size_t
+gdbscm_memory_port_write (SCM port, SCM src, size_t start, size_t count)
+{
+  /* Borrowed from libguile/fports.c.  */
+  auto ptr = reinterpret_cast<const gdb_byte*>(SCM_BYTEVECTOR_CONTENTS (src) +
+                                              start);
+  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
+  ssize_t ret;
+
+  /* "current" is the offset of the first byte we want to read.  */
+  gdb_assert (iomem->current <= iomem->size);
+
+  /* There's no way to indicate a short write, so if the request goes past
+     the end of the port's memory range, flag an error.  */
+  if (count > iomem->size - iomem->current)
+    {
+      gdbscm_out_of_range_error (FUNC_NAME, 0, gdbscm_scm_from_ulongest 
(count),
+                                _("writing beyond end of memory range"));
+    }
+
+  if (target_write_memory (iomem->start + iomem->current, ptr, count) != 0)
+    gdbscm_memory_error (FUNC_NAME, _("error writing memory"), SCM_EOL);
+  iomem->current += count;
+
+  return count;
+}
+
+#else /* !PORTS_V22 */
+
 /* "fill_input" method for memory ports.  */
 
 static int
@@ -850,18 +1056,19 @@ gdbscm_memory_port_free (SCM port)
   return 0;
 }
 
+#endif
+
 /* "print" method for memory ports.  */
 
 static int
 gdbscm_memory_port_print (SCM exp, SCM port, scm_print_state *pstate)
 {
   ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (exp);
-  char *type = SCM_PTOBNAME (SCM_PTOBNUM (exp));
 
   scm_puts ("#<", port);
   scm_print_port_mode (exp, port);
   /* scm_print_port_mode includes a trailing space.  */
-  gdbscm_printf (port, "%s %s-%s", type,
+  gdbscm_printf (port, "%s %s-%s", memory_port_type_name,
                 hex_string (iomem->start), hex_string (iomem->end));
   scm_putc ('>', port);
   return 1;
@@ -872,16 +1079,25 @@ gdbscm_memory_port_print (SCM exp, SCM port, 
scm_print_state *pstate)
 static void
 ioscm_init_memory_port_type (void)
 {
-  memory_port_desc = scm_make_port_type (memory_port_desc_name,
+  memory_port_type = scm_make_port_type (memory_port_type_name,
+#if PORTS_V22
+                                        gdbscm_memory_port_read,
+#else
                                         gdbscm_memory_port_fill_input,
+#endif
                                         gdbscm_memory_port_write);
 
-  scm_set_port_end_input (memory_port_desc, gdbscm_memory_port_end_input);
-  scm_set_port_flush (memory_port_desc, gdbscm_memory_port_flush);
-  scm_set_port_seek (memory_port_desc, gdbscm_memory_port_seek);
-  scm_set_port_close (memory_port_desc, gdbscm_memory_port_close);
-  scm_set_port_free (memory_port_desc, gdbscm_memory_port_free);
-  scm_set_port_print (memory_port_desc, gdbscm_memory_port_print);
+#if PORTS_V22
+  scm_set_port_get_natural_buffer_sizes (memory_port_type,
+                                        gdbscm_get_natural_buffer_sizes);
+#else
+  scm_set_port_end_input (memory_port_type, gdbscm_memory_port_end_input);
+  scm_set_port_flush (memory_port_type, gdbscm_memory_port_flush);
+  scm_set_port_free (memory_port_type, gdbscm_memory_port_free);
+  scm_set_port_close (memory_port_type, gdbscm_memory_port_close);
+#endif
+  scm_set_port_seek (memory_port_type, gdbscm_memory_port_seek);
+  scm_set_port_print (memory_port_type, gdbscm_memory_port_print);
 }
 
 /* Helper for gdbscm_open_memory to parse the mode bits.
@@ -921,27 +1137,20 @@ ioscm_parse_mode_bits (const char *func_name, const char 
*mode)
   return mode_bits;
 }
 
-/* Helper for gdbscm_open_memory to finish initializing the port.
-   The port has address range [start,end).
-   This means that address of 0xff..ff is not accessible.
-   I can live with that.  */
-
-static void
-ioscm_init_memory_port (SCM port, CORE_ADDR start, CORE_ADDR end)
+static scm_t_bits
+ioscm_init_memory_stream (bool buffered, CORE_ADDR start, CORE_ADDR end)
 {
-  scm_t_port *pt;
-  ioscm_memory_port *iomem;
-  int buffered = (SCM_CELL_WORD_0 (port) & SCM_BUF0) == 0;
+  auto iomem = reinterpret_cast<ioscm_memory_port *>(
+    scm_gc_malloc_pointerless (sizeof (ioscm_memory_port), "memory port"));
 
   gdb_assert (start <= end);
 
-  iomem = (ioscm_memory_port *) scm_gc_malloc_pointerless (sizeof (*iomem),
-                                                          "memory port");
-
   iomem->start = start;
   iomem->end = end;
   iomem->size = end - start;
   iomem->current = 0;
+
+#if !PORTS_V22
   if (buffered)
     {
       iomem->read_buf_size = default_read_buf_size;
@@ -952,6 +1161,24 @@ ioscm_init_memory_port (SCM port, CORE_ADDR start, 
CORE_ADDR end)
       iomem->read_buf_size = 1;
       iomem->write_buf_size = 1;
     }
+#endif
+
+  return reinterpret_cast<scm_t_bits>(iomem);
+}
+
+#if !PORTS_V22
+
+/* Helper for gdbscm_open_memory to finish initializing the port.
+   The port has address range [start,end).
+   This means that address of 0xff..ff is not accessible.
+   I can live with that.  */
+
+static void
+ioscm_init_memory_port_buffers (SCM port)
+{
+  scm_t_port *pt;
+  auto iomem = reinterpret_cast<const ioscm_memory_port *>(SCM_STREAM (port));
+  bool buffered = (SCM_CELL_WORD_0 (port) & SCM_BUF0) == 0;
 
   pt = SCM_PTAB_ENTRY (port);
   /* Match the expectation of `binary-port?'.  */
@@ -972,8 +1199,6 @@ ioscm_init_memory_port (SCM port, CORE_ADDR start, 
CORE_ADDR end)
   pt->read_pos = pt->read_end = pt->read_buf;
   pt->write_pos = pt->write_buf;
   pt->write_end = pt->write_buf + pt->write_buf_size;
-
-  SCM_SETSTREAM (port, iomem);
 }
 
 /* Re-initialize a memory port, updating its read/write buffer sizes.
@@ -1041,6 +1266,8 @@ ioscm_reinit_memory_port (SCM port, size_t read_buf_size,
     }
 }
 
+#endif /* !PORTS_V22 */
+
 /* (open-memory [#:mode string] [#:start address] [#:size integer]) -> port
    Return a port that can be used for reading and writing memory.
    MODE is a string, and must be one of "r", "w", or "r+".
@@ -1107,10 +1334,19 @@ gdbscm_open_memory (SCM rest)
     end = ~(CORE_ADDR) 0;
 
   mode_bits = ioscm_parse_mode_bits (FUNC_NAME, mode);
-
-  port = ioscm_open_port (memory_port_desc, mode_bits);
-
-  ioscm_init_memory_port (port, start, end);
+  /* Edge case: empty range -> unbuffered.
+     There's no need to disallow empty ranges, but we need an unbuffered port
+     to get the semantics right.  */
+  if (size == 0)
+    mode_bits |= SCM_BUF0;
+
+  bool buffered = (mode_bits & SCM_BUF0) == 0;
+  auto stream = ioscm_init_memory_stream(buffered, start, end);
+  port = ioscm_open_port (memory_port_type, mode_bits, stream);
+
+#if !PORTS_V22
+  ioscm_init_memory_port_buffers (port);
+#endif
 
   scm_dynwind_end ();
 
@@ -1123,7 +1359,12 @@ gdbscm_open_memory (SCM rest)
 static int
 gdbscm_is_memory_port (SCM obj)
 {
-  return !SCM_IMP (obj) && (SCM_TYP16 (obj) == memory_port_desc);
+  /* This is copied from SCM_FPORTP.  */
+#if PORTS_V22
+  return SCM_PORTP (obj) && SCM_PORT_TYPE (obj) == memory_port_type;
+#else
+  return !SCM_IMP (obj) && SCM_TYP16 (obj) == memory_port_type;
+#endif
 }
 
 /* (memory-port? obj) -> boolean */
@@ -1142,13 +1383,15 @@ gdbscm_memory_port_range (SCM port)
   ioscm_memory_port *iomem;
 
   SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
-                  memory_port_desc_name);
+                  memory_port_type_name);
 
   iomem = (ioscm_memory_port *) SCM_STREAM (port);
   return scm_list_2 (gdbscm_scm_from_ulongest (iomem->start),
                     gdbscm_scm_from_ulongest (iomem->end));
 }
 
+#if !PORTS_V22
+
 /* (memory-port-read-buffer-size port) -> integer */
 
 static SCM
@@ -1157,7 +1400,7 @@ gdbscm_memory_port_read_buffer_size (SCM port)
   ioscm_memory_port *iomem;
 
   SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
-                  memory_port_desc_name);
+                  memory_port_type_name);
 
   iomem = (ioscm_memory_port *) SCM_STREAM (port);
   return scm_from_uint (iomem->read_buf_size);
@@ -1173,7 +1416,7 @@ gdbscm_set_memory_port_read_buffer_size_x (SCM port, SCM 
size)
   ioscm_memory_port *iomem;
 
   SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
-                  memory_port_desc_name);
+                  memory_port_type_name);
   SCM_ASSERT_TYPE (scm_is_integer (size), size, SCM_ARG2, FUNC_NAME,
                   _("integer"));
 
@@ -1199,7 +1442,7 @@ gdbscm_memory_port_write_buffer_size (SCM port)
   ioscm_memory_port *iomem;
 
   SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
-                  memory_port_desc_name);
+                  memory_port_type_name);
 
   iomem = (ioscm_memory_port *) SCM_STREAM (port);
   return scm_from_uint (iomem->write_buf_size);
@@ -1215,7 +1458,7 @@ gdbscm_set_memory_port_write_buffer_size_x (SCM port, SCM 
size)
   ioscm_memory_port *iomem;
 
   SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
-                  memory_port_desc_name);
+                  memory_port_type_name);
   SCM_ASSERT_TYPE (scm_is_integer (size), size, SCM_ARG2, FUNC_NAME,
                   _("integer"));
 
@@ -1232,6 +1475,8 @@ gdbscm_set_memory_port_write_buffer_size_x (SCM port, SCM 
size)
 
   return SCM_UNSPECIFIED;
 }
+
+#endif /* !PORTS_V22 */
 
 /* Initialize gdb ports.  */
 
@@ -1268,6 +1513,7 @@ Return #t if the object is a memory port." },
     "\
 Return the memory range of the port as (start end)." },
 
+#if !PORTS_V22
   { "memory-port-read-buffer-size", 1, 0, 0,
     as_a_scm_t_subr (gdbscm_memory_port_read_buffer_size),
     "\
@@ -1293,6 +1539,7 @@ Set the size of the write buffer for the memory port.\n\
 \n\
   Arguments: port integer\n\
   Returns: unspecified." },
+#endif
 
   END_FUNCTIONS
 };
@@ -1365,9 +1612,11 @@ gdbscm_initialize_ports (void)
   start_keyword = scm_from_latin1_keyword ("start");
   size_keyword = scm_from_latin1_keyword ("size");
 
+#if !PORTS_V22
   /* Error message text for "out of range" memory port buffer sizes.  */
 
   out_of_range_buf_size = xstrprintf ("size not between %u - %u",
                                      min_memory_port_buf_size,
                                      max_memory_port_buf_size);
+#endif
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]