mescc: Support binutils 2.15a: fread: read ungetc'd chars too.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sat, 16 Jun 2018 18:51:16 +0000 (20:51 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sat, 16 Jun 2018 18:51:16 +0000 (20:51 +0200)
* lib/libmes.c (_ungetc_fd): New variable.
  (fdgetc): Use it.
  (_fdungetc_p): New function.
* lib/libc+tcc.c (_fungetc_p): New function.
* lib/libc+tcc.c (fread): Use it to read ungetc'd chars too.

lib/libc+tcc.c
lib/libmes.c
lib/linux+tcc.c
lib/linux.c

index e2a5a1a41365fb1caf62594bb4ff74b9e304482a..b3e2bb3a4d43869a70b88bc15e0aee59a2d43365 100644 (file)
@@ -155,12 +155,46 @@ fprintf (FILE *stream, char const *format, ...)
   return r;
 }
 
+int
+_fungetc_p (FILE *stream)
+{
+  return _fdungetc_p ((int)stream);
+}
+
 size_t
 fread (void *data, size_t size, size_t count, FILE *stream)
 {
   if (! size || !count)
     return 0;
-  int bytes = read ((int)stream, data, size * count);
+
+  size_t todo = size * count;
+  char *buf = (char*)data;
+
+  int bytes = 0;
+  while (_fungetc_p (stream) && todo-- && ++bytes)
+    *buf++ = fgetc (stream);
+  if (todo)
+    {
+      int r = read ((int)stream, buf, todo);
+      if (r < 0 && !bytes)
+        bytes = r;
+      else
+        bytes += r;
+    }
+
+  if (__mes_debug ())
+    {
+      eputs ("fread fd="); eputs (itoa ((int)stream));
+      eputs (" bytes="); eputs (itoa (bytes)); eputs ("\n");
+      static char buf[4096];
+      if (bytes > 0 && bytes < sizeof (buf))
+        {
+          strncpy (buf, data, bytes);
+          buf[bytes] = 0;
+          eputs ("fread buf="); eputs (buf); eputs ("\n");
+        }
+    }
+
   if (bytes > 0)
     return bytes/size;
 
index f6a04d7868dae67669e035fb86388bab15a211bb..0c45310b8445cabd4c306317e7400b030c16465b 100644 (file)
@@ -130,6 +130,7 @@ utoa (unsigned x)
 }
 
 int _ungetc_pos = -1;
+int _ungetc_fd = -1;
 char _ungetc_buf[10];
 
 int
@@ -146,8 +147,19 @@ fdgetc (int fd)
    }
   else
     {
+      if (_ungetc_fd != fd)
+        {
+          eputs (" ***MES LIB C*** fdgetc ungetc conflict unget-fd=");
+          eputs (itoa (_ungetc_fd));
+          eputs (", fdgetc-fd=");
+          eputs (itoa (fd));
+          eputs ("\n");
+          exit (1);
+        }
       i = _ungetc_buf[_ungetc_pos];
       _ungetc_pos -= 1;
+      if (_ungetc_pos == -1)
+        _ungetc_fd = -1;
      }
   if (i < 0)
     i += 256;
@@ -173,11 +185,28 @@ fdputs (char const* s, int fd)
 int
 fdungetc (int c, int fd)
 {
+  if (_ungetc_pos == -1)
+    _ungetc_fd = fd;
+  else if (_ungetc_fd != fd)
+    {
+      eputs (" ***MES LIB C*** fdungetc ungetc conflict unget-fd=");
+      eputs (itoa (_ungetc_fd));
+      eputs (", fdungetc-fd=");
+      eputs (itoa (fd));
+      eputs ("\n");
+      exit (1);
+    }
   _ungetc_pos++;
   _ungetc_buf[_ungetc_pos] = c;
   return c;
 }
 
+int
+_fdungetc_p (int fd)
+{
+  return _ungetc_pos > -1;
+}
+
 #if POSIX || __x86_64__
 #define STDERR 2
 int
index cf69a264aa6e26ff62d3fc2da9e68c491d509128..092d65dd1ff22d82d5e9d27690ff14d3d4e6c41e 100644 (file)
 int
 close (int filedes)
 {
+  if (_ungetc_fd == filedes)
+    {
+      _ungetc_pos = -1;
+      _ungetc_fd = -1;
+    }
   return _sys_call1 (SYS_close, (int)filedes);
 }
 
index f9dbcd9e5f2aa162bafbe00a91528afb15d65f2b..454aa7b2df183fb65e45f9366db81b0aa04209ef 100644 (file)
@@ -18,6 +18,7 @@
  * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <fcntl.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <libmes.h>
@@ -55,6 +56,13 @@ open (char const *file_name, int flags, ...)
   va_list ap;
   va_start (ap, flags);
   int mask = va_arg (ap, int);
+#if !MES_BOOTSTRAP
+  if (!flags)
+    {
+      _ungetc_pos = -1;
+      _ungetc_fd = -1;
+    }
+#endif
   int r = _sys_call3 (SYS_open, (int)file_name, (int)flags, (int)mask);
   va_end (ap);
   return r;