shithub: scc

Download patch

ref: 5a13b1a8c6e3232be716f6cfeb7dec710f947f14
parent: 258c23680f121b4681340e155a75e072531cc104
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat Dec 9 15:17:40 EST 2017

[lib/c] Add setbuf(), setbuffer(), setlinebuf() and setvbuf()

Again, it is only a work in progress.

--- a/lib/c/include/stdio.h
+++ b/lib/c/include/stdio.h
@@ -116,11 +116,12 @@
 #define putc(c, fp)  ((fp)->wp >= (fp)->rp ? __putc(c,fp) : (*(fp)->wp++ = c))
 #endif
 
-#define ferror(fp)   ((fp)->flags & _IOERR)
-#define feof(fp)     ((fp)->flags & _IOEOF)
-#define clearerr(fp) (void) ((fp)->flags &= ~(_IOERR|_IOEOF))
-#define getchar()    getc(stdin)
-#define putchar(c)   putc((c), stdout)
+#define ferror(fp)          ((fp)->flags & _IOERR)
+#define feof(fp)            ((fp)->flags & _IOEOF)
+#define clearerr(fp)        (void) ((fp)->flags &= ~(_IOERR|_IOEOF))
+#define getchar()           getc(stdin)
+#define putchar(c)          putc((c), stdout)
+#define setbuf(fp, b)       (void) setvbuf(fp, b, b ? _IOFBF:_IONBF, BUFSIZ)
 #endif
 
 #endif
--- a/lib/c/src/Makefile
+++ b/lib/c/src/Makefile
@@ -10,6 +10,7 @@
       fputs.o puts.o fread.o fwrite.o \
       getc.o putc.o __putc.o __getc.o \
       rewind.o fseek.o ferror.o feof.o clearerr.o \
+      setbuf.o setvbuf.o \
       fclose.o fopen.c freopen.c _fpopen.o stdio.o \
       realloc.o calloc.o malloc.o \
       assert.o strcpy.o strcmp.o strlen.o strchr.o \
--- /dev/null
+++ b/lib/c/src/setbuf.c
@@ -1,0 +1,9 @@
+
+#include <stdio.h>
+#undef setbuf
+
+void
+setbuf(FILE * restrict fp, char * restrict buf)
+{
+	setvbuf(fp, buf, (buf) ? _IOFBF : _IONBF, BUFSIZ);
+}
--- /dev/null
+++ b/lib/c/src/setvbuf.c
@@ -1,0 +1,44 @@
+
+#include <errno.h>
+#include <stdio.h>
+#undef setvbuf
+
+int
+setvbuf(FILE * restrict fp, char * restrict buf, int mode, size_t size)
+{
+	int flags, r;
+
+	if (fflush(fp) == EOF)
+		return EOF;
+
+	switch (mode) {
+	case _IONBF:
+		size = sizeof(fp->unbuf);
+		buf = fp->unbuf;
+		break;
+	case _IOLBF:
+	case _IOFBF:
+		if (size == 0) {
+			if ((buf = malloc(BUFSIZ)) == NULL) {
+				errno = ENOMEM;
+				return EOF;
+			}
+			size = BUFSIZ;
+		}
+		break;
+	default:
+		errno = EIVAL;
+		return EOF;
+	}
+
+	flags = fp->flags;
+	if (flags & _IOALLOC)
+		free(fp->buf);
+	flag &= ~(_IONBF | _IOLBF | _IOFBF | _IOALLOC | _IOALLOC);
+	flags |= mode;
+	fp->flags = flags;
+	fp->buf = buf;
+	fp->size = size;
+
+	return 0;
+}