shithub: scc

Download patch

ref: 2d455f13954cd94ae98ed346bb7da23d579ad6d7
parent: 22f5e45998b00a0e48eb69282ab2c9a247defd13
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Dec 6 10:17:32 EST 2017

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

--- 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;
 
--- a/lib/c/src/Makefile
+++ b/lib/c/src/Makefile
@@ -7,6 +7,7 @@
       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 \
--- /dev/null
+++ b/lib/c/src/__getc.c
@@ -1,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++;
+}
--- /dev/null
+++ b/lib/c/src/__putc.c
@@ -1,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;
+}
--- /dev/null
+++ b/lib/c/src/getc.c
@@ -1,0 +1,9 @@
+
+#include <stdio.h>
+#undef getc
+
+int
+getc(FILE *fp)
+{
+	return (fp->rp >= fp->wp) ?  __getc(fp) : *fp->rp++;
+}
--- /dev/null
+++ b/lib/c/src/putc.c
@@ -1,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;
+}