mescc: Mes C Library: Fix ungetc.
* include/sys/resource.h (OPEN_MAX, RLIMIT_NOFILE): New macro. * lib/libc.c: Add memset.c include. * lib/libc+tcc.c: Remove memset.c include. * lib/linux/tcc.c (close): * lib/mes/fdgetc.c (__ungetc_buf): New global. (_ungetc_pos, _ungetc_fd, _ungetc_buf): Remove. Update users. * scaffold/tests/65-read.c: Update.
This commit is contained in:
parent
48a0bf181d
commit
ff32cd03cc
|
@ -50,6 +50,8 @@ struct rusage
|
||||||
|
|
||||||
#define RUSAGE_SELF 0
|
#define RUSAGE_SELF 0
|
||||||
#define RUSAGE_CHILDREN -1
|
#define RUSAGE_CHILDREN -1
|
||||||
|
#define RLIMIT_NOFILE 1024
|
||||||
|
#define OPEN_MAX RLIMIT_NOFILE
|
||||||
|
|
||||||
int getrusage (int processes, struct rusage *rusage);
|
int getrusage (int processes, struct rusage *rusage);
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,6 @@ int errno;
|
||||||
#include <stdlib/strtoull.c>
|
#include <stdlib/strtoull.c>
|
||||||
#include <string/memmem.c>
|
#include <string/memmem.c>
|
||||||
#include <string/memmove.c>
|
#include <string/memmove.c>
|
||||||
#include <string/memset.c>
|
|
||||||
#include <string/strcat.c>
|
#include <string/strcat.c>
|
||||||
#include <string/strchr.c>
|
#include <string/strchr.c>
|
||||||
#include <string/strlwr.c>
|
#include <string/strlwr.c>
|
||||||
|
|
|
@ -74,6 +74,7 @@ __mes_debug ()
|
||||||
|
|
||||||
#include <string/memchr.c>
|
#include <string/memchr.c>
|
||||||
#include <string/memcmp.c>
|
#include <string/memcmp.c>
|
||||||
|
#include <string/memset.c>
|
||||||
#include <string/strcmp.c>
|
#include <string/strcmp.c>
|
||||||
#include <string/strcpy.c>
|
#include <string/strcpy.c>
|
||||||
#include <string/strncmp.c>
|
#include <string/strncmp.c>
|
||||||
|
|
|
@ -69,14 +69,10 @@ read (int filedes, void *buffer, size_t size)
|
||||||
int
|
int
|
||||||
_open3 (char const *file_name, int flags, int mask)
|
_open3 (char const *file_name, int flags, int mask)
|
||||||
{
|
{
|
||||||
#if !MES_BOOTSTRAP
|
|
||||||
if (!flags)
|
|
||||||
{
|
|
||||||
_ungetc_pos = -1;
|
|
||||||
_ungetc_fd = -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
int r = _sys_call3 (SYS_open, (long)file_name, (int)flags, (int)mask);
|
int r = _sys_call3 (SYS_open, (long)file_name, (int)flags, (int)mask);
|
||||||
|
__ungetc_init ();
|
||||||
|
if (r > 2)
|
||||||
|
__ungetc_buf[r] = -1;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,8 @@
|
||||||
int
|
int
|
||||||
close (int filedes)
|
close (int filedes)
|
||||||
{
|
{
|
||||||
if (_ungetc_fd == filedes)
|
if (filedes > 2)
|
||||||
{
|
__ungetc_buf[filedes] = -1;
|
||||||
_ungetc_pos = -1;
|
|
||||||
_ungetc_fd = -1;
|
|
||||||
}
|
|
||||||
return _sys_call1 (SYS_close, (int)filedes);
|
return _sys_call1 (SYS_close, (int)filedes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,50 +19,34 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libmes.h>
|
#include <libmes.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
|
||||||
int _ungetc_pos = -1;
|
int __ungetc_buf[RLIMIT_NOFILE+1] = {0};
|
||||||
int _ungetc_fd = -1;
|
|
||||||
char _ungetc_buf[10];
|
void
|
||||||
|
__ungetc_init ()
|
||||||
|
{
|
||||||
|
if (__ungetc_buf[RLIMIT_NOFILE] == 0)
|
||||||
|
memset (__ungetc_buf, -1, (RLIMIT_NOFILE+1)*sizeof (int));
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fdgetc (int fd)
|
fdgetc (int fd)
|
||||||
{
|
{
|
||||||
|
__ungetc_init ();
|
||||||
|
|
||||||
char c;
|
char c;
|
||||||
int i;
|
int i = __ungetc_buf[fd];
|
||||||
if (_ungetc_pos == -1)
|
if (i >= 0)
|
||||||
|
__ungetc_buf[fd] = -1;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
int r = read (fd, &c, 1);
|
int r = read (fd, &c, 1);
|
||||||
if (r < 1)
|
if (r < 1)
|
||||||
return -1;
|
return -1;
|
||||||
i = c;
|
i = c;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
i = _ungetc_buf[_ungetc_pos];
|
|
||||||
if (_ungetc_fd != fd && i == 10)
|
|
||||||
{
|
|
||||||
// FIXME: Nyacc's ungetc exposes harmless libmec.c bug
|
|
||||||
// we need one unget position per FD
|
|
||||||
_ungetc_pos = -1;
|
|
||||||
_ungetc_fd = -1;
|
|
||||||
return fdgetc (fd);
|
|
||||||
}
|
|
||||||
else if (_ungetc_fd != fd)
|
|
||||||
{
|
|
||||||
eputs (" ***MES C LIB*** fdgetc ungetc conflict unget-fd=");
|
|
||||||
eputs (itoa (_ungetc_fd));
|
|
||||||
eputs (", fdgetc-fd=");
|
|
||||||
eputs (itoa (fd));
|
|
||||||
eputs (", c=");
|
|
||||||
eputs (itoa ( _ungetc_buf[_ungetc_pos]));
|
|
||||||
eputs ("\n");
|
|
||||||
exit (1);
|
|
||||||
}
|
|
||||||
i = _ungetc_buf[_ungetc_pos];
|
|
||||||
_ungetc_pos -= 1;
|
|
||||||
if (_ungetc_pos == -1)
|
|
||||||
_ungetc_fd = -1;
|
|
||||||
}
|
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
i += 256;
|
i += 256;
|
||||||
|
|
||||||
|
|
|
@ -23,26 +23,22 @@
|
||||||
int
|
int
|
||||||
fdungetc (int c, int fd)
|
fdungetc (int c, int fd)
|
||||||
{
|
{
|
||||||
|
__ungetc_init ();
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
return c;
|
return c;
|
||||||
if (_ungetc_pos == -1)
|
else if (__ungetc_buf[fd] != -1)
|
||||||
_ungetc_fd = fd;
|
|
||||||
else if (_ungetc_fd != fd)
|
|
||||||
{
|
{
|
||||||
eputs (" ***MES LIB C*** fdungetc ungetc conflict unget-fd=");
|
eputs (" ***MES C LIB*** fdungetc ungetc buffer overflow fd=");
|
||||||
eputs (itoa (_ungetc_fd));
|
|
||||||
eputs (", fdungetc-fd=");
|
|
||||||
eputs (itoa (fd));
|
eputs (itoa (fd));
|
||||||
eputs ("\n");
|
eputs ("\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
_ungetc_pos++;
|
__ungetc_buf[fd] = c;
|
||||||
_ungetc_buf[_ungetc_pos] = c;
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_fdungetc_p (int fd)
|
_fdungetc_p (int fd)
|
||||||
{
|
{
|
||||||
return _ungetc_pos > -1;
|
return __ungetc_buf[fd] >= 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* -*-comment-start: "//";comment-end:""-*-
|
/* -*-comment-start: "//";comment-end:""-*-
|
||||||
* GNU Mes --- Maxwell Equations of Software
|
* GNU Mes --- Maxwell Equations of Software
|
||||||
* Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
* Copyright © 2017,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
||||||
*
|
*
|
||||||
* This file is part of GNU Mes.
|
* This file is part of GNU Mes.
|
||||||
*
|
*
|
||||||
|
@ -24,7 +24,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct scm {
|
struct scm
|
||||||
|
{
|
||||||
int type;
|
int type;
|
||||||
int car;
|
int car;
|
||||||
int cdr;
|
int cdr;
|
||||||
|
@ -56,30 +57,31 @@ main ()
|
||||||
oputs ("\n: ");
|
oputs ("\n: ");
|
||||||
oputs ("t: read 0123456789\nt: ");
|
oputs ("t: read 0123456789\nt: ");
|
||||||
int c = get ();
|
int c = get ();
|
||||||
while (i < 10) {
|
while (i < 10)
|
||||||
*p++ = c;
|
{
|
||||||
putchar (c);
|
*p++ = c;
|
||||||
c = get ();
|
putchar (c);
|
||||||
i++;
|
c = get ();
|
||||||
}
|
i++;
|
||||||
|
}
|
||||||
oputs ("\n");
|
oputs ("\n");
|
||||||
if (strcmp (g_chars, "0123456789")) return 1;
|
if (strcmp (g_chars, "0123456789"))
|
||||||
|
return 1;
|
||||||
|
|
||||||
oputs ("t: ungetc ('A') == getchar ()\n");
|
oputs ("t: fdungetc ('A') == getchar ()\n");
|
||||||
ungetc ('A', STDIN);
|
fdungetc ('A', STDIN);
|
||||||
if (getchar () != 'A') return 1;
|
if (getchar () != 'A')
|
||||||
ungetc (0, STDIN);
|
return 2;
|
||||||
//ungetc ('\1', STDIN);
|
oputs ("t: fdungetc (0)\n");
|
||||||
ungetc (1, STDIN);
|
fdungetc (0, STDIN);
|
||||||
oputs ("t: ungetc ();ungetc ();getchar ();getchar ()\n");
|
if (getchar () != 0)
|
||||||
if (getchar () != 1) return 1;
|
return 3;
|
||||||
//if (getchar () != '\0') return 1;
|
|
||||||
if (getchar () != 0) return 1;
|
|
||||||
|
|
||||||
oputs ("t: i == 'm'\n");
|
oputs ("t: i == 'm'\n");
|
||||||
char m = 0x1122336d;
|
char m = 0x1122336d;
|
||||||
i = m;
|
i = m;
|
||||||
if (i != 'm') return 1;
|
if (i != 'm')
|
||||||
|
return 4;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue