scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 567ff7edd184b1e0d3d3988f73860068a194ae91
parent ce905e8370025cc5fd2f22a518d58df17c0dda5b
Author: Michael Forney <mforney@mforney.org>
Date:   Mon,  4 Oct 2021 00:24:29 -0700

libc: Add implementation of ungetc

Co-authored-by: Roberto E. Vargas Caballero <k0ga@shike2.com>

Diffstat:
Msrc/libc/objs/common-objs.mk | 1+
Msrc/libc/stdio/Makefile | 1+
Asrc/libc/stdio/ungetc.c | 35+++++++++++++++++++++++++++++++++++
3 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/src/libc/objs/common-objs.mk b/src/libc/objs/common-objs.mk @@ -57,6 +57,7 @@ COMMON_OBJS =\ stdio/snprintf.$O\ stdio/sprintf.$O\ stdio/tmpnam.$O\ + stdio/ungetc.$O\ stdio/vfprintf.$O\ stdio/vprintf.$O\ stdio/vsnprintf.$O\ diff --git a/src/libc/stdio/Makefile b/src/libc/stdio/Makefile @@ -40,6 +40,7 @@ OBJS =\ sprintf.$O\ __iob.$O\ tmpnam.$O\ + ungetc.$O\ vfprintf.$O\ vsnprintf.$O\ vsprintf.$O\ diff --git a/src/libc/stdio/ungetc.c b/src/libc/stdio/ungetc.c @@ -0,0 +1,35 @@ +#include <stdio.h> + +/** + * ungetc() - push back one character to a input stream + * + * Context: A stream just opened has rp, wp, lp and buf pointing to NULL, + * in the same way that a closed stream. In both cases we have to + * return EOF, so the check fp->rp == fp->buf detects both cases. + * An input stream can be either a read only input or a read and + * write input in read state, and we can detect the write state + * when wp does not point to the beginning of buf. _IOSTRG is used + * in sprintf/sscanf functions, where it is possible rp points to + * a constant string, so we cannot write back c, but it is safe + * because in those functions we are going to push back always + * the same character that the one contained in the string. + */ +int +ungetc(int c, FILE *fp) +{ + if (c == EOF) + return EOF; + + if ((fp->flags & _IOWRITE) != 0) + return EOF; + + if (fp->rp == fp->buf || fp->wp != fp->buf) + return EOF; + + --fp->rp; + if ((fp->flags & _IOSTRG) == 0) + *fp->rp = c; + fp->flags &= ~_IOEOF; + + return c; +}