mescc: Mes C Library: Support GNU Sed: 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:
Jan Nieuwenhuizen 2019-01-05 11:55:00 +01:00
parent 4d6084b20b
commit 013cb1f33d
No known key found for this signature in database
GPG Key ID: F3C1A0D9C1D65273
10 changed files with 74 additions and 74 deletions

View File

@ -23,6 +23,11 @@
#include <libmes-mini.h>
#if POSIX
int mes_open (char const *file_name, int flags, ...);
#define open mes_open
#endif
int __mes_debug ();
double abtod (char const** p, int base);
long abtol (char const** p, int base);

View File

@ -50,6 +50,8 @@ struct rusage
#define RUSAGE_SELF 0
#define RUSAGE_CHILDREN -1
#define RLIMIT_NOFILE 1024
#define OPEN_MAX RLIMIT_NOFILE
int getrusage (int processes, struct rusage *rusage);

View File

@ -96,7 +96,6 @@ int errno;
#include <stdlib/strtoull.c>
#include <string/memmem.c>
#include <string/memmove.c>
#include <string/memset.c>
#include <string/strcat.c>
#include <string/strchr.c>
#include <string/strlwr.c>

View File

@ -74,6 +74,7 @@ __mes_debug ()
#include <string/memchr.c>
#include <string/memcmp.c>
#include <string/memset.c>
#include <string/strcmp.c>
#include <string/strcpy.c>
#include <string/strncmp.c>

View File

@ -42,10 +42,28 @@
#include <mes/fdungetc.c>
#if POSIX
#undef open
#include <fcntl.h>
#include <stdarg.h>
// The Mes C Library defines and initializes these in crt1
int g_stdin = STDIN;
int g_stdout = STDOUT;
int g_stderr = STDERR;
int
mes_open (char const *file_name, int flags, ...)
{
va_list ap;
va_start (ap, flags);
int mask = va_arg (ap, int);
__ungetc_init ();
int r = open (file_name, flags, mask);
if (r > 2)
__ungetc_buf[r] = -1;
va_end (ap);
return r;
}
#include <mes/eputs.c>
#include <mes/oputs.c>
#endif // POSIX

View File

@ -69,14 +69,10 @@ read (int filedes, void *buffer, size_t size)
int
_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);
__ungetc_init ();
if (r > 2)
__ungetc_buf[r] = -1;
return r;
}

View File

@ -23,11 +23,8 @@
int
close (int filedes)
{
if (_ungetc_fd == filedes)
{
_ungetc_pos = -1;
_ungetc_fd = -1;
}
if (filedes > 2)
__ungetc_buf[filedes] = -1;
return _sys_call1 (SYS_close, (int)filedes);
}

View File

@ -19,50 +19,34 @@
*/
#include <libmes.h>
#include <limits.h>
#include <sys/resource.h>
int _ungetc_pos = -1;
int _ungetc_fd = -1;
char _ungetc_buf[10];
int __ungetc_buf[RLIMIT_NOFILE+1] = {0};
void
__ungetc_init ()
{
if (__ungetc_buf[RLIMIT_NOFILE] == 0)
memset (__ungetc_buf, -1, (RLIMIT_NOFILE+1)*sizeof (int));
}
int
fdgetc (int fd)
{
__ungetc_init ();
char c;
int i;
if (_ungetc_pos == -1)
int i = __ungetc_buf[fd];
if (i >= 0)
__ungetc_buf[fd] = -1;
else
{
int r = read (fd, &c, 1);
if (r < 1)
return -1;
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)
i += 256;

View File

@ -23,26 +23,22 @@
int
fdungetc (int c, int fd)
{
__ungetc_init ();
if (c == -1)
return c;
if (_ungetc_pos == -1)
_ungetc_fd = fd;
else if (_ungetc_fd != fd)
else if (__ungetc_buf[fd] != -1)
{
eputs (" ***MES LIB C*** fdungetc ungetc conflict unget-fd=");
eputs (itoa (_ungetc_fd));
eputs (", fdungetc-fd=");
eputs (" ***MES C LIB*** fdungetc ungetc buffer overflow fd=");
eputs (itoa (fd));
eputs ("\n");
exit (1);
}
_ungetc_pos++;
_ungetc_buf[_ungetc_pos] = c;
__ungetc_buf[fd] = c;
return c;
}
int
_fdungetc_p (int fd)
{
return _ungetc_pos > -1;
return __ungetc_buf[fd] >= 0;
}

View File

@ -1,6 +1,6 @@
/* -*-comment-start: "//";comment-end:""-*-
* 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.
*
@ -24,7 +24,8 @@
#include <stdlib.h>
#include <string.h>
struct scm {
struct scm
{
int type;
int car;
int cdr;
@ -56,30 +57,31 @@ main ()
oputs ("\n: ");
oputs ("t: read 0123456789\nt: ");
int c = get ();
while (i < 10) {
*p++ = c;
putchar (c);
c = get ();
i++;
}
while (i < 10)
{
*p++ = c;
putchar (c);
c = get ();
i++;
}
oputs ("\n");
if (strcmp (g_chars, "0123456789")) return 1;
if (strcmp (g_chars, "0123456789"))
return 1;
oputs ("t: ungetc ('A') == getchar ()\n");
ungetc ('A', STDIN);
if (getchar () != 'A') return 1;
ungetc (0, STDIN);
//ungetc ('\1', STDIN);
ungetc (1, STDIN);
oputs ("t: ungetc ();ungetc ();getchar ();getchar ()\n");
if (getchar () != 1) return 1;
//if (getchar () != '\0') return 1;
if (getchar () != 0) return 1;
oputs ("t: fdungetc ('A') == getchar ()\n");
fdungetc ('A', STDIN);
if (getchar () != 'A')
return 2;
oputs ("t: fdungetc (0)\n");
fdungetc (0, STDIN);
if (getchar () != 0)
return 3;
oputs ("t: i == 'm'\n");
char m = 0x1122336d;
i = m;
if (i != 'm') return 1;
if (i != 'm')
return 4;
return 0;
}