mescc: Support binutils 2.15a: fread: read ungetc'd chars too.

* 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.
This commit is contained in:
Jan Nieuwenhuizen 2018-06-16 20:51:16 +02:00
parent 7a42e5e6b0
commit a9215931e8
No known key found for this signature in database
GPG key ID: F3C1A0D9C1D65273
4 changed files with 77 additions and 1 deletions

View 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;

View 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

View file

@ -28,6 +28,11 @@
int
close (int filedes)
{
if (_ungetc_fd == filedes)
{
_ungetc_pos = -1;
_ungetc_fd = -1;
}
return _sys_call1 (SYS_close, (int)filedes);
}

View 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;