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:
parent
7a42e5e6b0
commit
a9215931e8
|
@ -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;
|
||||
|
||||
|
|
29
lib/libmes.c
29
lib/libmes.c
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue