From d60ad184f15fca30a70a82db68636dc2c30305e1 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 22 Jul 2023 10:58:34 +0200 Subject: [PATCH] libc: A bit of nice refactoring --- libc/include/stdio.h | 23 +++++++------ libc/src/stdio.cpp | 81 +++++++++++++++++++++++--------------------- 2 files changed, 56 insertions(+), 48 deletions(-) diff --git a/libc/include/stdio.h b/libc/include/stdio.h index 0e706f52..f8f6961d 100644 --- a/libc/include/stdio.h +++ b/libc/include/stdio.h @@ -14,16 +14,19 @@ typedef struct { - int _fd; - int _err; - int _eof; - size_t _bufcap; - size_t _bufsize; - size_t _bufindex; - char* _buffer; - int _flags; - int _pending; - int _mode; + int _fd; // The underlying file descriptor. + int _err; // The error status flag. + int _eof; // The end-of-file status flag. + struct + { + size_t capacity; // The buffer's total capacity. + size_t size; // The buffer's used size. + size_t index; // The read index into the buffer. + char* buffer; // The memory used for the buffer. + int status; // The buffer status flags. + int mode; // The buffering mode. + } _buf; + int _flags; // The file access mode with which the file was opened. } FILE; #define EOF -1 diff --git a/libc/src/stdio.cpp b/libc/src/stdio.cpp index 3a01c05b..de32c539 100644 --- a/libc/src/stdio.cpp +++ b/libc/src/stdio.cpp @@ -13,7 +13,12 @@ FILE* stdout = nullptr; FILE* s_open_files[FOPEN_MAX]; -#define FFLAG_FREE_AFTER_BUFFER_USE (1 << 0) +enum FileStatusFlags +{ + BufferIsMalloced = (1 << 0), + LastRead = (1 << 1), + LastWrite = (1 << 2), +}; static const char* read_tmpdir() { @@ -57,12 +62,12 @@ static int fdopen_check_compatible_mode(int fd, int new_flags) static int flush_write_buffer(FILE* stream) { - if (stream->_mode == _IONBF) return 0; + if (stream->_buf.mode == _IONBF) return 0; - ssize_t result = write(stream->_fd, stream->_buffer, stream->_bufsize); + ssize_t result = write(stream->_fd, stream->_buf.buffer, stream->_buf.size); - stream->_bufindex = 0; - stream->_bufsize = 0; + stream->_buf.index = 0; + stream->_buf.size = 0; return result < 0 ? EOF : 0; } @@ -74,20 +79,20 @@ static ssize_t write_into_buffer(FILE* stream, const u8* data, ssize_t size) while (size > 0) { ssize_t nwritten; - if (stream->_mode != _IONBF) + if (stream->_buf.mode != _IONBF) { - if ((stream->_bufsize + size) > stream->_bufcap) + if ((stream->_buf.size + size) > stream->_buf.capacity) { if (flush_write_buffer(stream) < 0) return -1; } - ssize_t size_remaining = stream->_bufcap - stream->_bufsize; + ssize_t size_remaining = stream->_buf.capacity - stream->_buf.size; nwritten = size > size_remaining ? size_remaining : size; - memcpy(stream->_buffer + stream->_bufsize, data, nwritten); + memcpy(stream->_buf.buffer + stream->_buf.size, data, nwritten); - stream->_bufsize += nwritten; + stream->_buf.size += nwritten; - if (stream->_mode == _IOLBF && memchr(data, '\n', nwritten)) + if (stream->_buf.mode == _IOLBF && memchr(data, '\n', nwritten)) { if (flush_write_buffer(stream) < 0) return -1; } @@ -112,7 +117,7 @@ extern "C" int fflush(FILE* stream) { - if (stream && stream->_mode != _IONBF) flush_write_buffer(stream); + if (stream && stream->_buf.mode != _IONBF) flush_write_buffer(stream); else if (!stream) { for (int i = 0; i < FOPEN_MAX; i++) @@ -142,12 +147,12 @@ extern "C" f->_fd = fd; clearerr(f); - f->_pending = 0; f->_flags = flags; - f->_mode = isatty(fd) ? _IOLBF : _IOFBF; - f->_bufsize = f->_bufindex = 0; - f->_buffer = nullptr; - setvbuf(f, NULL, f->_mode, 0); + f->_buf.status = 0; + f->_buf.mode = isatty(fd) ? _IOLBF : _IOFBF; + f->_buf.size = f->_buf.index = 0; + f->_buf.buffer = nullptr; + setvbuf(f, NULL, f->_buf.mode, 0); s_open_files[fd] = f; @@ -168,12 +173,12 @@ extern "C" f->_fd = fd; clearerr(f); - f->_pending = 0; f->_flags = flags; - f->_mode = buffering_mode < 0 ? (isatty(fd) ? _IOLBF : _IOFBF) : buffering_mode; - f->_bufsize = f->_bufindex = 0; - f->_buffer = nullptr; - setvbuf(f, NULL, f->_mode, 0); + f->_buf.status = 0; + f->_buf.mode = buffering_mode < 0 ? (isatty(fd) ? _IOLBF : _IOFBF) : buffering_mode; + f->_buf.size = f->_buf.index = 0; + f->_buf.buffer = nullptr; + setvbuf(f, NULL, f->_buf.mode, 0); s_open_files[fd] = f; @@ -195,7 +200,7 @@ extern "C" s_open_files[stream->_fd] = nullptr; - if (stream->_buffer && (stream->_pending & FFLAG_FREE_AFTER_BUFFER_USE)) free(stream->_buffer); + if (stream->_buf.buffer && (stream->_buf.status & FileStatusFlags::BufferIsMalloced)) free(stream->_buf.buffer); if (!path) { fail("FIXME: freopen() called with path=nullptr"); } @@ -205,12 +210,12 @@ extern "C" stream->_fd = fd; clearerr(stream); - stream->_pending = 0; stream->_flags = flags; - stream->_mode = isatty(fd) ? _IOLBF : _IOFBF; - stream->_bufsize = stream->_bufindex = 0; - stream->_buffer = nullptr; - setvbuf(stream, NULL, stream->_mode, 0); + stream->_buf.status = 0; + stream->_buf.mode = isatty(fd) ? _IOLBF : _IOFBF; + stream->_buf.size = stream->_buf.index = 0; + stream->_buf.buffer = nullptr; + setvbuf(stream, NULL, stream->_buf.mode, 0); s_open_files[fd] = stream; @@ -223,7 +228,7 @@ extern "C" if (close(stream->_fd) < 0) return EOF; - if (stream->_buffer && (stream->_pending & FFLAG_FREE_AFTER_BUFFER_USE)) free(stream->_buffer); + if (stream->_buf.buffer && (stream->_buf.status & FileStatusFlags::BufferIsMalloced)) free(stream->_buf.buffer); s_open_files[stream->_fd] = nullptr; @@ -610,28 +615,28 @@ extern "C" int setvbuf(FILE* stream, char* buf, int mode, size_t size) { - int pending = 0; + int status = 0; if (mode < 0 || mode > _IOFBF) return errno = EINVAL, -1; - if (stream->_bufsize != 0 || stream->_bufindex != 0) return -1; // Buffer is already in use. + if (stream->_buf.size != 0 || stream->_buf.index != 0) return -1; // Buffer is already in use. if (mode != _IONBF && buf == NULL) { size = BUFSIZ; buf = (char*)calloc(size, 1); if (!buf) return -1; - pending = FFLAG_FREE_AFTER_BUFFER_USE; + status = FileStatusFlags::BufferIsMalloced; } - else + else if (mode == _IONBF) { buf = NULL; size = 0; } - if (stream->_buffer && (stream->_pending & FFLAG_FREE_AFTER_BUFFER_USE)) free(stream->_buffer); + if (stream->_buf.buffer && (stream->_buf.status & FileStatusFlags::BufferIsMalloced)) free(stream->_buf.buffer); - stream->_buffer = buf; - stream->_bufcap = size; - stream->_mode = mode; - stream->_pending = pending; + stream->_buf.buffer = buf; + stream->_buf.capacity = size; + stream->_buf.mode = mode; + stream->_buf.status = status; return 0; }