(coded-charset-entity-reference-alist): Add setting for
[chise/xemacs-chise.git.1] / src / lstream.c
index d7c4f70..8151bc7 100644 (file)
@@ -26,7 +26,6 @@ Boston, MA 02111-1307, USA.  */
 
 #include <config.h>
 #include "lisp.h"
 
 #include <config.h>
 #include "lisp.h"
-#include <limits.h>
 
 #include "buffer.h"
 #include "insdel.h"
 
 #include "buffer.h"
 #include "insdel.h"
@@ -52,7 +51,7 @@ Boston, MA 02111-1307, USA.  */
 
 /* Functions are as follows:
 
 
 /* Functions are as follows:
 
-Lstream *Lstream_new (Lstream_implementation *imp, CONST char *mode)
+Lstream *Lstream_new (Lstream_implementation *imp, const char *mode)
        Allocate and return a new Lstream.  This function is not
        really meant to be called directly; rather, each stream type
        should provide its own stream creation function, which
        Allocate and return a new Lstream.  This function is not
        really meant to be called directly; rather, each stream type
        should provide its own stream creation function, which
@@ -75,37 +74,40 @@ int Lstream_putc (Lstream *stream, int c)
        0 on success, -1 on error.
 
 int Lstream_getc (Lstream *stream)
        0 on success, -1 on error.
 
 int Lstream_getc (Lstream *stream)
-       Read one byte from the stream.  This is a macro and so it
-       is very efficient.  The STREAM argument is evaluated more
-       than once.  Return value is -1 for EOF or error.
+       Read one byte from the stream and returns it as an unsigned
+       char cast to an int, or EOF on end of file or error.
+       This is a macro and so it is very efficient.  The STREAM
+       argument is evaluated more than once.
 
 void Lstream_ungetc (Lstream *stream, int c)
 
 void Lstream_ungetc (Lstream *stream, int c)
-       Push one byte back onto the input queue.  This will be the
-       next byte read from the stream.  Any number of bytes can be
-       pushed back and will be read in the reverse order they were
-       pushed back -- most recent first. (This is necessary for
-       consistency -- if there are a number of bytes that have been
-       unread and I read and unread a byte, it needs to be the first
-       to be read again.) This is a macro and so it is very
-       efficient.  The C argument is only evaluated once but the
-       STREAM argument is evaluated more than once.
+       Push one byte back onto the input queue, cast to unsigned char.
+       This will be the next byte read from the stream.  Any number
+       of bytes can be pushed back and will be read in the reverse
+       order they were pushed back -- most recent first. (This is
+       necessary for consistency -- if there are a number of bytes
+       that have been unread and I read and unread a byte, it needs
+       to be the first to be read again.) This is a macro and so it
+       is very efficient.  The C argument is only evaluated once but
+       the STREAM argument is evaluated more than once.
 
 int Lstream_fputc (Lstream *stream, int c)
 int Lstream_fgetc (Lstream *stream)
 void Lstream_fungetc (Lstream *stream, int c)
        Function equivalents of the above macros.
 
 
 int Lstream_fputc (Lstream *stream, int c)
 int Lstream_fgetc (Lstream *stream)
 void Lstream_fungetc (Lstream *stream, int c)
        Function equivalents of the above macros.
 
-int Lstream_read (Lstream *stream, void *data, size_t size)
+Lstream_data_count Lstream_read (Lstream *stream, void *data,
+                                 Lstream_data_count size)
        Read SIZE bytes of DATA from the stream.  Return the number of
        bytes read.  0 means EOF. -1 means an error occurred and no
        bytes were read.
 
        Read SIZE bytes of DATA from the stream.  Return the number of
        bytes read.  0 means EOF. -1 means an error occurred and no
        bytes were read.
 
-int Lstream_write (Lstream *stream, void *data, size_t size)
+Lstream_data_count Lstream_write (Lstream *stream, void *data,
+                                  Lstream_data_count size)
        Write SIZE bytes of DATA to the stream.  Return the number of
        bytes written.  -1 means an error occurred and no bytes were
        written.
 
        Write SIZE bytes of DATA to the stream.  Return the number of
        bytes written.  -1 means an error occurred and no bytes were
        written.
 
-void Lstream_unread (Lstream *stream, void *data, size_t size)
+void Lstream_unread (Lstream *stream, void *data, Lstream_data_count size)
        Push back SIZE bytes of DATA onto the input queue.  The
        next call to Lstream_read() with the same size will read the
        same bytes back.  Note that this will be the case even if
        Push back SIZE bytes of DATA onto the input queue.  The
        next call to Lstream_read() with the same size will read the
        same bytes back.  Note that this will be the case even if
@@ -179,11 +181,17 @@ finalize_lstream (void *header, int for_disksave)
     }
 }
 
     }
 }
 
+inline static size_t
+aligned_sizeof_lstream (size_t lstream_type_specific_size)
+{
+  return ALIGN_SIZE (offsetof (Lstream, data) + lstream_type_specific_size,
+                    ALIGNOF (max_align_t));
+}
+
 static size_t
 static size_t
-sizeof_lstream (CONST void *header)
+sizeof_lstream (const void *header)
 {
 {
-  CONST Lstream *lstr = (CONST Lstream *) header;
-  return sizeof (*lstr) + lstr->imp->size - 1;
+  return aligned_sizeof_lstream (((const Lstream *) header)->imp->size);
 }
 
 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream,
 }
 
 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream,
@@ -210,12 +218,12 @@ Lstream_set_buffering (Lstream *lstr, Lstream_buffering buffering,
     }
 }
 
     }
 }
 
-static CONST Lstream_implementation *lstream_types[32];
+static const Lstream_implementation *lstream_types[32];
 static Lisp_Object Vlstream_free_list[32];
 static int lstream_type_count;
 
 Lstream *
 static Lisp_Object Vlstream_free_list[32];
 static int lstream_type_count;
 
 Lstream *
-Lstream_new (CONST Lstream_implementation *imp, CONST char *mode)
+Lstream_new (const Lstream_implementation *imp, const char *mode)
 {
   Lstream *p;
   int i;
 {
   Lstream *p;
   int i;
@@ -231,15 +239,15 @@ Lstream_new (CONST Lstream_implementation *imp, CONST char *mode)
       assert (lstream_type_count < countof (lstream_types));
       lstream_types[lstream_type_count] = imp;
       Vlstream_free_list[lstream_type_count] =
       assert (lstream_type_count < countof (lstream_types));
       lstream_types[lstream_type_count] = imp;
       Vlstream_free_list[lstream_type_count] =
-       make_lcrecord_list (sizeof (*p) + imp->size - 1,
+       make_lcrecord_list (aligned_sizeof_lstream (imp->size),
                            &lrecord_lstream);
       lstream_type_count++;
     }
 
   p = XLSTREAM (allocate_managed_lcrecord (Vlstream_free_list[i]));
   /* Zero it out, except the header. */
                            &lrecord_lstream);
       lstream_type_count++;
     }
 
   p = XLSTREAM (allocate_managed_lcrecord (Vlstream_free_list[i]));
   /* Zero it out, except the header. */
-  memset ((char *) p + sizeof (p->header), 0,
-         sizeof (*p) - sizeof (p->header) + imp->size - 1);
+  memset ((char *) p + sizeof (p->header), '\0',
+         aligned_sizeof_lstream (imp->size) - sizeof (p->header));
   p->imp = imp;
   Lstream_set_buffering (p, LSTREAM_BLOCK_BUFFERED, 0);
   p->flags = LSTREAM_FL_IS_OPEN;
   p->imp = imp;
   Lstream_set_buffering (p, LSTREAM_BLOCK_BUFFERED, 0);
   p->flags = LSTREAM_FL_IS_OPEN;
@@ -276,13 +284,13 @@ Lstream_delete (Lstream *lstr)
        }
     }
 
        }
     }
 
-  abort ();
+  ABORT ();
 }
 
 #define Lstream_internal_error(reason, lstr) \
   Lstream_signal_simple_error ("Internal error: " reason, lstr)
 
 }
 
 #define Lstream_internal_error(reason, lstr) \
   Lstream_signal_simple_error ("Internal error: " reason, lstr)
 
-static void Lstream_signal_simple_error (CONST char *reason, Lstream *lstr)
+static void Lstream_signal_simple_error (const char *reason, Lstream *lstr)
 {
   Lisp_Object obj;
   XSETLSTREAM (obj, lstr);
 {
   Lisp_Object obj;
   XSETLSTREAM (obj, lstr);
@@ -302,11 +310,11 @@ Lstream_reopen (Lstream *lstr)
 int
 Lstream_flush_out (Lstream *lstr)
 {
 int
 Lstream_flush_out (Lstream *lstr)
 {
-  int num_written;
+  Lstream_data_count num_written;
 
   while (lstr->out_buffer_ind > 0)
     {
 
   while (lstr->out_buffer_ind > 0)
     {
-      int size = lstr->out_buffer_ind;
+      Lstream_data_count size = lstr->out_buffer_ind;
       if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
        Lstream_internal_error ("lstream not open", lstr);
       if (! (lstr->flags & LSTREAM_FL_WRITE))
       if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
        Lstream_internal_error ("lstream not open", lstr);
       if (! (lstr->flags & LSTREAM_FL_WRITE))
@@ -319,8 +327,8 @@ Lstream_flush_out (Lstream *lstr)
           character at the end.  We need to spit back that
           incomplete character. */
        {
           character at the end.  We need to spit back that
           incomplete character. */
        {
-         CONST unsigned char *data = lstr->out_buffer;
-         CONST unsigned char *dataend = data + size - 1;
+         const unsigned char *data = lstr->out_buffer;
+         const unsigned char *dataend = data + size - 1;
          assert (size > 0); /* safety check ... */
          /* Optimize the most common case. */
          if (!BYTE_ASCII_P (*dataend))
          assert (size > 0); /* safety check ... */
          /* Optimize the most common case. */
          if (!BYTE_ASCII_P (*dataend))
@@ -347,7 +355,7 @@ Lstream_flush_out (Lstream *lstr)
           the attempt to write the data might have resulted in an
           EWOULDBLOCK error. */
        return 0;
           the attempt to write the data might have resulted in an
           EWOULDBLOCK error. */
        return 0;
-      else if (num_written >= (int) lstr->out_buffer_ind)
+      else if (num_written >= lstr->out_buffer_ind)
        lstr->out_buffer_ind = 0;
       else if (num_written > 0)
        {
        lstr->out_buffer_ind = 0;
       else if (num_written > 0)
        {
@@ -389,31 +397,36 @@ Lstream_flush (Lstream *lstr)
    if it's getting EWOULDBLOCK errors.   We have to keep stocking them
    up until they can be written, so as to avoid losing data. */
 
    if it's getting EWOULDBLOCK errors.   We have to keep stocking them
    up until they can be written, so as to avoid losing data. */
 
-static int
-Lstream_adding (Lstream *lstr, size_t num, int force)
+static Lstream_data_count
+Lstream_adding (Lstream *lstr, Lstream_data_count num, int force)
 {
 {
-  /* Compute the size that the outbuffer needs to be after the
-     chars are added. */
-  size_t size_needed = max (lstr->out_buffer_size,
-                           num + lstr->out_buffer_ind);
+  Lstream_data_count size = num + lstr->out_buffer_ind;
+
+  if (size <= lstr->out_buffer_size)
+    return num;
+
   /* Maybe chop it down so that we don't buffer more characters
      than our advertised buffering size. */
   /* Maybe chop it down so that we don't buffer more characters
      than our advertised buffering size. */
-  if (!force)
-    size_needed = min (lstr->buffering_size, size_needed);
-  DO_REALLOC (lstr->out_buffer, lstr->out_buffer_size,
-             size_needed, unsigned char);
-  /* There might be more data buffered than the buffering size,
-     so make sure we don't return a negative number here. */
-  return max (0, min (num, size_needed - lstr->out_buffer_ind));
+  if ((size > lstr->buffering_size) && !force)
+    {
+      size = lstr->buffering_size;
+      /* There might be more data buffered than the buffering size. */
+      if (size <= lstr->out_buffer_ind)
+       return 0;
+    }
+
+  DO_REALLOC (lstr->out_buffer, lstr->out_buffer_size, size, unsigned char);
+
+  return size - lstr->out_buffer_ind;
 }
 
 /* Like Lstream_write(), but does not handle line-buffering correctly. */
 
 }
 
 /* Like Lstream_write(), but does not handle line-buffering correctly. */
 
-static int
-Lstream_write_1 (Lstream *lstr, CONST void *data, size_t size)
+static Lstream_data_count
+Lstream_write_1 (Lstream *lstr, const void *data, Lstream_data_count size)
 {
 {
-  CONST unsigned char *p = (CONST unsigned char *) data;
-  int off = 0;
+  const unsigned char *p = (const unsigned char *) data;
+  Lstream_data_count off = 0;
   if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
     Lstream_internal_error ("lstream not open", lstr);
   if (! (lstr->flags & LSTREAM_FL_WRITE))
   if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
     Lstream_internal_error ("lstream not open", lstr);
   if (! (lstr->flags & LSTREAM_FL_WRITE))
@@ -424,7 +437,7 @@ Lstream_write_1 (Lstream *lstr, CONST void *data, size_t size)
     while (1)
       {
        /* Figure out how much we can add to the buffer */
     while (1)
       {
        /* Figure out how much we can add to the buffer */
-       int chunk = Lstream_adding (lstr, size, 0);
+       Lstream_data_count chunk = Lstream_adding (lstr, size, 0);
        if (chunk == 0)
          {
            if (couldnt_write_last_time)
        if (chunk == 0)
          {
            if (couldnt_write_last_time)
@@ -467,37 +480,35 @@ Lstream_write_1 (Lstream *lstr, CONST void *data, size_t size)
 /* If the stream is not line-buffered, then we can just call
    Lstream_write_1(), which writes in chunks.  Otherwise, we
    repeatedly call Lstream_putc(), which knows how to handle
 /* If the stream is not line-buffered, then we can just call
    Lstream_write_1(), which writes in chunks.  Otherwise, we
    repeatedly call Lstream_putc(), which knows how to handle
-   line buffering. */
+   line buffering.  Returns number of bytes written. */
 
 
-int
-Lstream_write (Lstream *lstr, CONST void *data, size_t size)
+Lstream_data_count
+Lstream_write (Lstream *lstr, const void *data, Lstream_data_count size)
 {
 {
-  int i;
-  CONST unsigned char *p = (CONST unsigned char *) data;
+  Lstream_data_count i;
+  const unsigned char *p = (const unsigned char *) data;
 
   if (size == 0)
     return size;
   if (lstr->buffering != LSTREAM_LINE_BUFFERED)
     return Lstream_write_1 (lstr, data, size);
 
   if (size == 0)
     return size;
   if (lstr->buffering != LSTREAM_LINE_BUFFERED)
     return Lstream_write_1 (lstr, data, size);
-  for (i = 0; i < (int) size; i++)
+  for (i = 0; i < size; i++)
     {
       if (Lstream_putc (lstr, p[i]) < 0)
        break;
     }
     {
       if (Lstream_putc (lstr, p[i]) < 0)
        break;
     }
-  return i == 0 ? -1 : 0;
+  return i == 0 ? -1 : i;
 }
 
 int
 Lstream_was_blocked_p (Lstream *lstr)
 {
 }
 
 int
 Lstream_was_blocked_p (Lstream *lstr)
 {
-  if (lstr->imp->was_blocked_p)
-    return (lstr->imp->was_blocked_p) (lstr);
-  else
-    return 0;
+  return lstr->imp->was_blocked_p ? lstr->imp->was_blocked_p (lstr) : 0;
 }
 
 }
 
-static int
-Lstream_raw_read (Lstream *lstr, unsigned char *buffer, size_t size)
+static Lstream_data_count
+Lstream_raw_read (Lstream *lstr, unsigned char *buffer,
+                 Lstream_data_count size)
 {
   if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
     Lstream_internal_error ("lstream not open", lstr);
 {
   if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
     Lstream_internal_error ("lstream not open", lstr);
@@ -511,16 +522,18 @@ Lstream_raw_read (Lstream *lstr, unsigned char *buffer, size_t size)
 
 /* Assuming the buffer is empty, fill it up again. */
 
 
 /* Assuming the buffer is empty, fill it up again. */
 
-static int
+static Lstream_data_count
 Lstream_read_more (Lstream *lstr)
 {
 #if 0
 Lstream_read_more (Lstream *lstr)
 {
 #if 0
-  int size_needed = max (1, min (MAX_READ_SIZE, lstr->buffering_size));
+  Lstream_data_count size_needed 
+    = max (1, min (MAX_READ_SIZE, lstr->buffering_size));
 #else
   /* If someone requested a larger buffer size, so be it! */
 #else
   /* If someone requested a larger buffer size, so be it! */
-  int size_needed = max (1, lstr->buffering_size);
+  Lstream_data_count size_needed =
+    max (1, lstr->buffering_size);
 #endif
 #endif
-  int size_gotten;
+  Lstream_data_count size_gotten;
 
   DO_REALLOC (lstr->in_buffer, lstr->in_buffer_size,
              size_needed, unsigned char);
 
   DO_REALLOC (lstr->in_buffer, lstr->in_buffer_size,
              size_needed, unsigned char);
@@ -530,12 +543,12 @@ Lstream_read_more (Lstream *lstr)
   return size_gotten < 0 ? -1 : size_gotten;
 }
 
   return size_gotten < 0 ? -1 : size_gotten;
 }
 
-int
-Lstream_read (Lstream *lstr, void *data, size_t size)
+Lstream_data_count
+Lstream_read (Lstream *lstr, void *data, Lstream_data_count size)
 {
   unsigned char *p = (unsigned char *) data;
 {
   unsigned char *p = (unsigned char *) data;
-  int off = 0;
-  size_t chunk;
+  Lstream_data_count off = 0;
+  Lstream_data_count chunk;
   int error_occurred = 0;
 
   if (size == 0)
   int error_occurred = 0;
 
   if (size == 0)
@@ -546,7 +559,7 @@ Lstream_read (Lstream *lstr, void *data, size_t size)
   if (chunk > 0)
     {
       /* The bytes come back in reverse order. */
   if (chunk > 0)
     {
       /* The bytes come back in reverse order. */
-      for (; off < (int) chunk; off++)
+      for (; off < chunk; off++)
        p[off] = lstr->unget_buffer[--lstr->unget_buffer_ind];
       lstr->byte_count += chunk;
       size -= chunk;
        p[off] = lstr->unget_buffer[--lstr->unget_buffer_ind];
       lstr->byte_count += chunk;
       size -= chunk;
@@ -568,7 +581,7 @@ Lstream_read (Lstream *lstr, void *data, size_t size)
       /* If we need some more, try to get some more from the stream's end */
       if (size > 0)
        {
       /* If we need some more, try to get some more from the stream's end */
       if (size > 0)
        {
-         int retval = Lstream_read_more (lstr);
+         Lstream_data_count retval = Lstream_read_more (lstr);
          if (retval < 0)
            error_occurred = 1;
          if (retval <= 0)
          if (retval < 0)
            error_occurred = 1;
          if (retval <= 0)
@@ -582,7 +595,7 @@ Lstream_read (Lstream *lstr, void *data, size_t size)
       /* It's quite possible for us to get passed an incomplete
         character at the end.  We need to spit back that
         incomplete character. */
       /* It's quite possible for us to get passed an incomplete
         character at the end.  We need to spit back that
         incomplete character. */
-      CONST unsigned char *dataend = p + off - 1;
+      const unsigned char *dataend = p + off - 1;
       /* Optimize the most common case. */
       if (!BYTE_ASCII_P (*dataend))
        {
       /* Optimize the most common case. */
       if (!BYTE_ASCII_P (*dataend))
        {
@@ -592,7 +605,7 @@ Lstream_read (Lstream *lstr, void *data, size_t size)
          VALIDATE_CHARPTR_BACKWARD (dataend);
          if (dataend + REP_BYTES_BY_FIRST_BYTE (*dataend) != p + off)
            {
          VALIDATE_CHARPTR_BACKWARD (dataend);
          if (dataend + REP_BYTES_BY_FIRST_BYTE (*dataend) != p + off)
            {
-             int newoff = dataend - p;
+             Lstream_data_count newoff = dataend - p;
              /* If not, chop the size down to ignore the last char
                 and stash it away for next time. */
              Lstream_unread (lstr, dataend, off - newoff);
              /* If not, chop the size down to ignore the last char
                 and stash it away for next time. */
              Lstream_unread (lstr, dataend, off - newoff);
@@ -601,25 +614,24 @@ Lstream_read (Lstream *lstr, void *data, size_t size)
        }
     }
 
        }
     }
 
-  return ((off == 0 && error_occurred) ? -1 : off);
+  return off == 0 && error_occurred ? -1 : off;
 }
 
 void
 }
 
 void
-Lstream_unread (Lstream *lstr, CONST void *data, size_t size)
+Lstream_unread (Lstream *lstr, const void *data, Lstream_data_count size)
 {
 {
-  int i;
-  unsigned char *p = (unsigned char *) data;
+  const unsigned char *p = (const unsigned char *) data;
 
   /* Make sure buffer is big enough */
 
   /* Make sure buffer is big enough */
-
   DO_REALLOC (lstr->unget_buffer, lstr->unget_buffer_size,
              lstr->unget_buffer_ind + size, unsigned char);
 
   DO_REALLOC (lstr->unget_buffer, lstr->unget_buffer_size,
              lstr->unget_buffer_ind + size, unsigned char);
 
+  lstr->byte_count -= size;
+
   /* Bytes have to go on in reverse order -- they are reversed
      again when read back. */
   /* Bytes have to go on in reverse order -- they are reversed
      again when read back. */
-  for (i = size - 1; i >= 0; i--)
-    lstr->unget_buffer[lstr->unget_buffer_ind++] = p[i];
-  lstr->byte_count -= size;
+  while (size--)
+    lstr->unget_buffer[lstr->unget_buffer_ind++] = p[size];
 }
 
 int
 }
 
 int
@@ -646,15 +658,11 @@ Lstream_seekable_p (Lstream *lstr)
 static int
 Lstream_pseudo_close (Lstream *lstr)
 {
 static int
 Lstream_pseudo_close (Lstream *lstr)
 {
-  int rc;
-
-  if (!lstr->flags & LSTREAM_FL_IS_OPEN)
+  if (! (lstr->flags & LSTREAM_FL_IS_OPEN))
     Lstream_internal_error ("lstream is not open", lstr);
 
   /* don't check errors here -- best not to risk file descriptor loss */
     Lstream_internal_error ("lstream is not open", lstr);
 
   /* don't check errors here -- best not to risk file descriptor loss */
-  rc = Lstream_flush (lstr);
-
-  return rc;
+  return Lstream_flush (lstr);
 }
 
 int
 }
 
 int
@@ -729,7 +737,7 @@ int
 Lstream_fputc (Lstream *lstr, int c)
 {
   unsigned char ch = (unsigned char) c;
 Lstream_fputc (Lstream *lstr, int c)
 {
   unsigned char ch = (unsigned char) c;
-  int retval = Lstream_write_1 (lstr, &ch, 1);
+  Lstream_data_count retval = Lstream_write_1 (lstr, &ch, 1);
   if (retval >= 0 && lstr->buffering == LSTREAM_LINE_BUFFERED && ch == '\n')
     return Lstream_flush_out (lstr);
   return retval < 0 ? -1 : 0;
   if (retval >= 0 && lstr->buffering == LSTREAM_LINE_BUFFERED && ch == '\n')
     return Lstream_flush_out (lstr);
   return retval < 0 ? -1 : 0;
@@ -768,7 +776,7 @@ DEFINE_LSTREAM_IMPLEMENTATION ("stdio", lstream_stdio,
                               sizeof (struct stdio_stream));
 
 static Lisp_Object
                               sizeof (struct stdio_stream));
 
 static Lisp_Object
-make_stdio_stream_1 (FILE *stream, int flags, CONST char *mode)
+make_stdio_stream_1 (FILE *stream, int flags, const char *mode)
 {
   Lisp_Object obj;
   Lstream *lstr = Lstream_new (lstream_stdio, mode);
 {
   Lisp_Object obj;
   Lstream *lstr = Lstream_new (lstream_stdio, mode);
@@ -792,24 +800,43 @@ make_stdio_output_stream (FILE *stream, int flags)
   return make_stdio_stream_1 (stream, flags, "w");
 }
 
   return make_stdio_stream_1 (stream, flags, "w");
 }
 
-static int
-stdio_reader (Lstream *stream, unsigned char *data, size_t size)
+/* #### From reading the Unix 98 specification, it appears that if we
+   want stdio_reader() to be completely correct, we should check for
+   0 < val < size and if so, check to see if an error has occurred.
+   If an error has occurred, but val is non-zero, we should go ahead
+   and act as if the read was successful, but remember in some fashion
+   or other, that an error has occurred, and report that on the next
+   call to stdio_reader instead of calling fread() again.
+
+   Currently, in such a case, we end up calling fread() twice and we
+   assume that
+
+   1) this is not harmful, and
+   2) the error will still be reported on the second read.
+
+   This is probably reasonable, so I don't think we should change this
+   code (it could even be argued that the error might have fixed
+   itself, so we should do the fread() again.  */
+
+static Lstream_data_count
+stdio_reader (Lstream *stream, unsigned char *data, Lstream_data_count size)
 {
   struct stdio_stream *str = STDIO_STREAM_DATA (stream);
 {
   struct stdio_stream *str = STDIO_STREAM_DATA (stream);
-  size_t val = fread (data, 1, (size_t) size, str->file);
+  Lstream_data_count val = fread (data, 1, size, str->file);
   if (!val && ferror (str->file))
     return -1;
   if (!val && ferror (str->file))
     return -1;
-  return (int) val;
+  return val;
 }
 
 }
 
-static int
-stdio_writer (Lstream *stream, CONST unsigned char *data, size_t size)
+static Lstream_data_count
+stdio_writer (Lstream *stream, const unsigned char *data,
+             Lstream_data_count size)
 {
   struct stdio_stream *str = STDIO_STREAM_DATA (stream);
 {
   struct stdio_stream *str = STDIO_STREAM_DATA (stream);
-  size_t val = fwrite (data, 1, size, str->file);
+  Lstream_data_count val = fwrite (data, 1, size, str->file);
   if (!val && ferror (str->file))
     return -1;
   if (!val && ferror (str->file))
     return -1;
-  return (int) val;
+  return val;
 }
 
 static int
 }
 
 static int
@@ -837,9 +864,6 @@ stdio_flusher (Lstream *stream)
   if (stream->flags & LSTREAM_FL_WRITE)
     return fflush (str->file);
   else
   if (stream->flags & LSTREAM_FL_WRITE)
     return fflush (str->file);
   else
-    /* call fpurge?  Only exists on some systems.  #### Why not add a
-       configure check for HAVE_FPURGE and utilize it on systems that
-       support it?  --hniksic */
     return 0;
 }
 
     return 0;
 }
 
@@ -853,7 +877,6 @@ stdio_closer (Lstream *stream)
   if (stream->flags & LSTREAM_FL_WRITE)
     return fflush (str->file);
   else
   if (stream->flags & LSTREAM_FL_WRITE)
     return fflush (str->file);
   else
-    /* call fpurge?  Only exists on some systems. */
     return 0;
 }
 
     return 0;
 }
 
@@ -886,7 +909,7 @@ DEFINE_LSTREAM_IMPLEMENTATION ("filedesc", lstream_filedesc,
    ignored when writing); -1 for unlimited. */
 static Lisp_Object
 make_filedesc_stream_1 (int filedesc, int offset, int count, int flags,
    ignored when writing); -1 for unlimited. */
 static Lisp_Object
 make_filedesc_stream_1 (int filedesc, int offset, int count, int flags,
-                       CONST char *mode)
+                       const char *mode)
 {
   Lisp_Object obj;
   Lstream *lstr = Lstream_new (lstream_filedesc, mode);
 {
   Lisp_Object obj;
   Lstream *lstr = Lstream_new (lstream_filedesc, mode);
@@ -921,14 +944,16 @@ make_filedesc_output_stream (int filedesc, int offset, int count, int flags)
   return make_filedesc_stream_1 (filedesc, offset, count, flags, "w");
 }
 
   return make_filedesc_stream_1 (filedesc, offset, count, flags, "w");
 }
 
-static int
-filedesc_reader (Lstream *stream, unsigned char *data, size_t size)
+static Lstream_data_count
+filedesc_reader (Lstream *stream, unsigned char *data, Lstream_data_count size)
 {
 {
-  int nread;
+  Lstream_data_count nread;
   struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
   if (str->end_pos >= 0)
   struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
   if (str->end_pos >= 0)
-    size = min (size, (size_t) (str->end_pos - str->current_pos));
-  nread = (str->allow_quit ? read_allowing_quit : read) (str->fd, data, size);
+    size = min (size, (Lstream_data_count) (str->end_pos - str->current_pos));
+  nread = str->allow_quit ?
+    read_allowing_quit (str->fd, data, size) :
+    read (str->fd, data, size);
   if (nread > 0)
     str->current_pos += nread;
   return nread;
   if (nread > 0)
     str->current_pos += nread;
   return nread;
@@ -948,11 +973,12 @@ errno_would_block_p (int val)
   return 0;
 }
 
   return 0;
 }
 
-static int
-filedesc_writer (Lstream *stream, CONST unsigned char *data, size_t size)
+static Lstream_data_count
+filedesc_writer (Lstream *stream, const unsigned char *data,
+                Lstream_data_count size)
 {
   struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
 {
   struct filedesc_stream *str = FILEDESC_STREAM_DATA (stream);
-  int retval;
+  Lstream_data_count retval;
   int need_newline = 0;
 
   /* This function would be simple if it were not for the blasted
   int need_newline = 0;
 
   /* This function would be simple if it were not for the blasted
@@ -964,9 +990,9 @@ filedesc_writer (Lstream *stream, CONST unsigned char *data, size_t size)
   if (str->pty_flushing)
     {
       /* To make life easy, only send out one line at the most. */
   if (str->pty_flushing)
     {
       /* To make life easy, only send out one line at the most. */
-      CONST unsigned char *ptr;
+      const unsigned char *ptr;
 
 
-      ptr = (CONST unsigned char *) memchr (data, '\n', size);
+      ptr = (const unsigned char *) memchr (data, '\n', size);
       if (ptr)
        need_newline = 1;
       else
       if (ptr)
        need_newline = 1;
       else
@@ -981,8 +1007,9 @@ filedesc_writer (Lstream *stream, CONST unsigned char *data, size_t size)
 
   /**** start of non-PTY-crap ****/
   if (size > 0)
 
   /**** start of non-PTY-crap ****/
   if (size > 0)
-    retval = ((str->allow_quit ? write_allowing_quit : write)
-             (str->fd, data, size));
+    retval = str->allow_quit ?
+      write_allowing_quit (str->fd, data, size) :
+      write (str->fd, data, size);
   else
     retval = 0;
   if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok)
   else
     retval = 0;
   if (retval < 0 && errno_would_block_p (errno) && str->blocked_ok)
@@ -1005,8 +1032,10 @@ filedesc_writer (Lstream *stream, CONST unsigned char *data, size_t size)
         out for EWOULDBLOCK. */
       if (str->chars_sans_newline >= str->pty_max_bytes)
        {
         out for EWOULDBLOCK. */
       if (str->chars_sans_newline >= str->pty_max_bytes)
        {
-         int retval2 = ((str->allow_quit ? write_allowing_quit : write)
-                        (str->fd, &str->eof_char, 1));
+         Lstream_data_count retval2 = str->allow_quit ?
+           write_allowing_quit (str->fd, &str->eof_char, 1) :
+           write (str->fd, &str->eof_char, 1);
+
          if (retval2 > 0)
            str->chars_sans_newline = 0;
          else if (retval2 < 0)
          if (retval2 > 0)
            str->chars_sans_newline = 0;
          else if (retval2 < 0)
@@ -1036,8 +1065,10 @@ filedesc_writer (Lstream *stream, CONST unsigned char *data, size_t size)
   if (need_newline)
     {
       Bufbyte nl = '\n';
   if (need_newline)
     {
       Bufbyte nl = '\n';
-      int retval2 = ((str->allow_quit ? write_allowing_quit : write)
-                    (str->fd, &nl, 1));
+      Lstream_data_count retval2 = str->allow_quit ?
+       write_allowing_quit (str->fd, &nl, 1) :
+       write (str->fd, &nl, 1);
+
       if (retval2 > 0)
         {
           str->chars_sans_newline = 0;
       if (retval2 > 0)
         {
           str->chars_sans_newline = 0;
@@ -1170,8 +1201,9 @@ make_lisp_string_input_stream (Lisp_Object string, Bytecount offset,
   return obj;
 }
 
   return obj;
 }
 
-static int
-lisp_string_reader (Lstream *stream, unsigned char *data, size_t size)
+static Lstream_data_count
+lisp_string_reader (Lstream *stream, unsigned char *data,
+                   Lstream_data_count size)
 {
   struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
   /* Don't lose if the string shrank past us ... */
 {
   struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (stream);
   /* Don't lose if the string shrank past us ... */
@@ -1186,7 +1218,7 @@ lisp_string_reader (Lstream *stream, unsigned char *data, size_t size)
   if (stream->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
     VALIDATE_CHARPTR_BACKWARD (start);
   offset = start - strstart;
   if (stream->flags & LSTREAM_FL_NO_PARTIAL_CHARS)
     VALIDATE_CHARPTR_BACKWARD (start);
   offset = start - strstart;
-  size = min (size, (size_t) (str->end - offset));
+  size = min (size, (Lstream_data_count) (str->end - offset));
   memcpy (data, start, size);
   str->offset = offset + size;
   return size;
   memcpy (data, start, size);
   str->offset = offset + size;
   return size;
@@ -1227,41 +1259,42 @@ lisp_string_marker (Lisp_Object stream)
 
 struct fixed_buffer_stream
 {
 
 struct fixed_buffer_stream
 {
-  CONST unsigned char *inbuf;
+  const unsigned char *inbuf;
   unsigned char *outbuf;
   unsigned char *outbuf;
-  size_t size;
-  size_t offset;
+  Lstream_data_count size;
+  Lstream_data_count offset;
 };
 
 DEFINE_LSTREAM_IMPLEMENTATION ("fixed-buffer", lstream_fixed_buffer,
                               sizeof (struct fixed_buffer_stream));
 
 Lisp_Object
 };
 
 DEFINE_LSTREAM_IMPLEMENTATION ("fixed-buffer", lstream_fixed_buffer,
                               sizeof (struct fixed_buffer_stream));
 
 Lisp_Object
-make_fixed_buffer_input_stream (CONST unsigned char *buf, size_t size)
+make_fixed_buffer_input_stream (const void *buf, Lstream_data_count size)
 {
   Lisp_Object obj;
   Lstream *lstr = Lstream_new (lstream_fixed_buffer, "r");
   struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
 {
   Lisp_Object obj;
   Lstream *lstr = Lstream_new (lstream_fixed_buffer, "r");
   struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
-  str->inbuf = buf;
+  str->inbuf = (const unsigned char *) buf;
   str->size = size;
   XSETLSTREAM (obj, lstr);
   return obj;
 }
 
 Lisp_Object
   str->size = size;
   XSETLSTREAM (obj, lstr);
   return obj;
 }
 
 Lisp_Object
-make_fixed_buffer_output_stream (unsigned char *buf, size_t size)
+make_fixed_buffer_output_stream (void *buf, Lstream_data_count size)
 {
   Lisp_Object obj;
   Lstream *lstr = Lstream_new (lstream_fixed_buffer, "w");
   struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
 {
   Lisp_Object obj;
   Lstream *lstr = Lstream_new (lstream_fixed_buffer, "w");
   struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (lstr);
-  str->outbuf = buf;
+  str->outbuf = (unsigned char *) buf;
   str->size = size;
   XSETLSTREAM (obj, lstr);
   return obj;
 }
 
   str->size = size;
   XSETLSTREAM (obj, lstr);
   return obj;
 }
 
-static int
-fixed_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
+static Lstream_data_count
+fixed_buffer_reader (Lstream *stream, unsigned char *data,
+                    Lstream_data_count size)
 {
   struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
   size = min (size, str->size - str->offset);
 {
   struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
   size = min (size, str->size - str->offset);
@@ -1270,8 +1303,9 @@ fixed_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
   return size;
 }
 
   return size;
 }
 
-static int
-fixed_buffer_writer (Lstream *stream, CONST unsigned char *data, size_t size)
+static Lstream_data_count
+fixed_buffer_writer (Lstream *stream, const unsigned char *data,
+                    Lstream_data_count size)
 {
   struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
   if (str->offset == str->size)
 {
   struct fixed_buffer_stream *str = FIXED_BUFFER_STREAM_DATA (stream);
   if (str->offset == str->size)
@@ -1294,7 +1328,7 @@ fixed_buffer_rewinder (Lstream *stream)
   return 0;
 }
 
   return 0;
 }
 
-CONST unsigned char *
+const unsigned char *
 fixed_buffer_input_stream_ptr (Lstream *stream)
 {
   assert (stream->imp == lstream_fixed_buffer);
 fixed_buffer_input_stream_ptr (Lstream *stream)
 {
   assert (stream->imp == lstream_fixed_buffer);
@@ -1316,7 +1350,7 @@ fixed_buffer_output_stream_ptr (Lstream *stream)
 struct resizing_buffer_stream
 {
   unsigned char *buf;
 struct resizing_buffer_stream
 {
   unsigned char *buf;
-  size_t allocked;
+  Lstream_data_count allocked;
   int max_stored;
   int stored;
 };
   int max_stored;
   int stored;
 };
@@ -1332,8 +1366,9 @@ make_resizing_buffer_output_stream (void)
   return obj;
 }
 
   return obj;
 }
 
-static int
-resizing_buffer_writer (Lstream *stream, CONST unsigned char *data, size_t size)
+static Lstream_data_count
+resizing_buffer_writer (Lstream *stream, const unsigned char *data,
+                       Lstream_data_count size)
 {
   struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
   DO_REALLOC (str->buf, str->allocked, str->stored + size, unsigned char);
 {
   struct resizing_buffer_stream *str = RESIZING_BUFFER_STREAM_DATA (stream);
   DO_REALLOC (str->buf, str->allocked, str->stored + size, unsigned char);
@@ -1394,8 +1429,9 @@ make_dynarr_output_stream (unsigned_char_dynarr *dyn)
   return obj;
 }
 
   return obj;
 }
 
-static int
-dynarr_writer (Lstream *stream, CONST unsigned char *data, size_t size)
+static Lstream_data_count
+dynarr_writer (Lstream *stream, const unsigned char *data,
+              Lstream_data_count size)
 {
   struct dynarr_stream *str = DYNARR_STREAM_DATA (stream);
   Dynarr_add_many (str->dyn, data, size);
 {
   struct dynarr_stream *str = DYNARR_STREAM_DATA (stream);
   Dynarr_add_many (str->dyn, data, size);
@@ -1438,7 +1474,7 @@ DEFINE_LSTREAM_IMPLEMENTATION ("lisp-buffer", lstream_lisp_buffer,
 
 static Lisp_Object
 make_lisp_buffer_stream_1 (struct buffer *buf, Bufpos start, Bufpos end,
 
 static Lisp_Object
 make_lisp_buffer_stream_1 (struct buffer *buf, Bufpos start, Bufpos end,
-                          int flags, CONST char *mode)
+                          int flags, const char *mode)
 {
   Lisp_Object obj;
   Lstream *lstr;
 {
   Lisp_Object obj;
   Lstream *lstr;
@@ -1448,7 +1484,7 @@ make_lisp_buffer_stream_1 (struct buffer *buf, Bufpos start, Bufpos end,
 
   /* Make sure the luser didn't pass "w" in. */
   if (!strcmp (mode, "w"))
 
   /* Make sure the luser didn't pass "w" in. */
   if (!strcmp (mode, "w"))
-    abort ();
+    ABORT ();
 
   if (flags & LSTR_IGNORE_ACCESSIBLE)
     {
 
   if (flags & LSTR_IGNORE_ACCESSIBLE)
     {
@@ -1518,8 +1554,9 @@ make_lisp_buffer_output_stream (struct buffer *buf, Bufpos pos, int flags)
   return lstr;
 }
 
   return lstr;
 }
 
-static int
-lisp_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
+static Lstream_data_count
+lisp_buffer_reader (Lstream *stream, unsigned char *data,
+                   Lstream_data_count size)
 {
   struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
   unsigned char *orig_data = data;
 {
   struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
   unsigned char *orig_data = data;
@@ -1543,7 +1580,7 @@ lisp_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
                                   BI_BUF_ZV (buf));
     }
 
                                   BI_BUF_ZV (buf));
     }
 
-  size = min (size, (size_t) (end - start));
+  size = min (size, (Lstream_data_count) (end - start));
   end = start + size;
   /* We cannot return a partial character. */
   VALIDATE_BYTIND_BACKWARD (buf, end);
   end = start + size;
   /* We cannot return a partial character. */
   VALIDATE_BYTIND_BACKWARD (buf, end);
@@ -1576,8 +1613,9 @@ lisp_buffer_reader (Lstream *stream, unsigned char *data, size_t size)
   return data - orig_data;
 }
 
   return data - orig_data;
 }
 
-static int
-lisp_buffer_writer (Lstream *stream, CONST unsigned char *data, size_t size)
+static Lstream_data_count
+lisp_buffer_writer (Lstream *stream, const unsigned char *data,
+                   Lstream_data_count size)
 {
   struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
   Bufpos pos;
 {
   struct lisp_buffer_stream *str = LISP_BUFFER_STREAM_DATA (stream);
   Bufpos pos;
@@ -1687,5 +1725,7 @@ reinit_vars_of_lstream (void)
 void
 vars_of_lstream (void)
 {
 void
 vars_of_lstream (void)
 {
+  INIT_LRECORD_IMPLEMENTATION (lstream);
+
   reinit_vars_of_lstream ();
 }
   reinit_vars_of_lstream ();
 }