scc

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

commit 4dd5500352c42601000a36152c10b044f96cb352
parent 437e32bac531455249a2ad20e2756da782fc2167
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed,  6 Dec 2017 15:17:32 +0000

[lib/c] Add putc() and getc()

Diffstat:
Mlib/c/include/errno.h | 3++-
Mlib/c/src/Makefile | 1+
Alib/c/src/__getc.c | 36++++++++++++++++++++++++++++++++++++
Alib/c/src/__putc.c | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alib/c/src/getc.c | 9+++++++++
Alib/c/src/putc.c | 9+++++++++
6 files changed, 145 insertions(+), 1 deletion(-)

diff --git a/lib/c/include/errno.h b/lib/c/include/errno.h @@ -4,7 +4,8 @@ #define EDOM 1 #define EILSEQ 2 #define ERANGE 3 -#define ENOMEN 4 +#define ENOMEM 4 +#define EBADF 5 extern int errno; diff --git a/lib/c/src/Makefile b/lib/c/src/Makefile @@ -7,6 +7,7 @@ OBJ = bsearch.o \ printf.o fprintf.o vfprintf.o \ fgets.o gets.of fgetc.o fputc.o getchar.o putchar.o \ fputs.o puts.o fread.o fwrite.o \ + getc.o putc.o __putc.o __getc.o \ realloc.o calloc.o malloc.o \ assert.o strcpy.o strcmp.o strlen.o strchr.o \ strrchr.o strcat.o strncmp.o strncpy.o strncat.o strcoll.o \ diff --git a/lib/c/src/__getc.c b/lib/c/src/__getc.c @@ -0,0 +1,36 @@ + +#include <errno.h> +#include <stdio.h> +#include "syscall.h" +#undef getc + +int +__getc(FILE *fp) +{ + int cnt; + + if (fp->flags & (_IOEOF | _IOERR)) + return EOF; + + if ((fp->flags & (_IOREAD | _IORW)) == 0) { + fp->flags |= _IOERR; + errno = EBADF; + return EOF; + } + + if (fp->flags & _IOSTRG) { + fp->flags |= _IOEOF; + return EOF; + } + + if ((cnt = _read(fp->fd, fp->buf, fp->len)) <= 0) { + fp->flags |= (cnt == 0) ? _IOEOF : _IOERR; + return EOF; + } + + fp->flags |= _IOREAD; + fp->rp = fp->buf; + fp->wp = fp->buf + cnt; + + return *fp->rp++; +} diff --git a/lib/c/src/__putc.c b/lib/c/src/__putc.c @@ -0,0 +1,88 @@ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include "syscall.h" + +int +_fflush(FILE *fp) +{ + int lnbuf = fp->flags & _IOLBF; + size_t cnt; + + cnt = ((lnbuf) ? fp->lp : fp->wp) - fp->buf; + + if (_write(fp->fd, fp->buf, cnt) != cnt) { + fp->flags |= _IOERR; + return EOF; + } + fp->rp = fp->wp = fp->buf; + + return 0; +} + +int +fflush(FILE *fp) +{ + int err = 0; + + if (fp) + return _flsbuf(fp); + + for (fp = __iob; fp < &__iob[FOPEN_MAX]; ++fp) { + if ((fp->flags & _IOWRITE) == 0 && _flush(fp)) + err = EOF; + } + return err; +} + +static void +cleanup(void) +{ + fflush(NULL); +} + +int +__putc(int ch, FILE *fp) +{ + static int first = 1; + + if (fp->flags & _IOERR) + return EOF; + + if (fp->flags & _IOREAD) { + fp->flags |= _IOERR; + errno = EBADF; + return EOF; + } + + if (fp->flags & _IOSTRG) { + fp->flags |= _IOERR; + return EOF; + } + + if (first) { + if (atexit(cleanup)) { + fp->flags |= _IOERR; + errno = ENOMEM; + return EOF; + } + first = 0; + } + + if (fp->flags & _IOLBF) { + if (fp->lp == fp->rp && _flush(fp)) + return EOF; + *fp->lp++ = ch; + if (ch == '\n' && flsbuf(fp)) + return EOF; + } else { + if (fp->wp == fp->rp && _flsbuf(fp)) + return EOF; + *fp->wp++ = ch; + } + +done: + fp->flags |= _IOWRITE; + return ch & 0xFF; +} diff --git a/lib/c/src/getc.c b/lib/c/src/getc.c @@ -0,0 +1,9 @@ + +#include <stdio.h> +#undef getc + +int +getc(FILE *fp) +{ + return (fp->rp >= fp->wp) ? __getc(fp) : *fp->rp++; +} diff --git a/lib/c/src/putc.c b/lib/c/src/putc.c @@ -0,0 +1,9 @@ + +#include <stdio.h> +#undef putc + +int +putc(int ch, FILE *fp) +{ + return (fp->wp >= fp->rp) ? __putc(c,fp) : *fp->wp++ = c; +}