From 294fda973185ce4b973bba0730850b9fc45d2e97 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Thu, 13 Jan 2022 21:28:19 +0100 Subject: [PATCH] stdio: share the FILE implementation between all versions --- include/fxlibc/printf.h | 2 +- include/stdio.h | 92 ++++++++++++++++- include/target/casiowin-cg/bits/types/FILE.h | 7 -- include/target/casiowin-fx/bits/types/FILE.h | 7 -- include/target/gint/bits/types/FILE.h | 99 ------------------- include/target/vhex-generic/bits/types/FILE.h | 13 --- .../target/vhex-generic/bits/types/__FILE.h | 8 -- .../vhex-generic/bits/types/struct_FILE.h | 26 ----- 8 files changed, 91 insertions(+), 163 deletions(-) delete mode 100644 include/target/casiowin-cg/bits/types/FILE.h delete mode 100644 include/target/casiowin-fx/bits/types/FILE.h delete mode 100644 include/target/gint/bits/types/FILE.h delete mode 100644 include/target/vhex-generic/bits/types/FILE.h delete mode 100644 include/target/vhex-generic/bits/types/__FILE.h delete mode 100644 include/target/vhex-generic/bits/types/struct_FILE.h diff --git a/include/fxlibc/printf.h b/include/fxlibc/printf.h index 4bb80dd..828ebff 100644 --- a/include/fxlibc/printf.h +++ b/include/fxlibc/printf.h @@ -11,7 +11,7 @@ extern "C" { ** parse options, lay out strings, and generate output. */ -#include +#include #include #include #include diff --git a/include/stdio.h b/include/stdio.h index 13b4517..7d56567 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -7,9 +7,97 @@ extern "C" { #include #include +#include +#include -/* Type of FILE handlers. */ -#include +#define __FILE_BUF_READ 0 +#define __FILE_BUF_WRITE 1 + +/* The FILE structure is mostly a buffer around kernel-level I/O. Most of the + work is maintaining that buffer to provide the basic fgetc()/fputc() + functions, then everything else is built on top of the abstracted stream. + + The buffer of a FILE can either be in reading or writing mode. When in + reading mode, the buffer contains pre-fetched data from a previous read that + hasn't yet been requested by the user. When in writing mode, the buffer + contains data written by the user which hasn't yet been sent to the kernel. + + The buffer has the following structure: + + 0 bufpos bufread bufsize + +--------+---------+---------+ + |xxxxxxxx|rrrrrrrrr|uuuuuuuuu| (When reading) + +--------+---------+---------+ + |wwwwwwww|uuuuuuuuuuuuuuuuuuu| (When writing) + +--------+-------------------+ + + x: Data read from file descriptor and returned to user + r: Data read from file descriptor not yet returned to user + w: Data written by user not yet sent to file descriptor + u: Undefined + + In reading mode, the region [0..bufread) contains data obtained from the + file. bufpos marks how much has been read, in the sense that [0..bufpos) has + already been returned to the user while [bufpos..bufread) has not. The offset + on the underlying file descriptor sits at bufread, so the position reported + by ftell() is fdpos - bufread + bufpos. The rest of the buffer is undefined. + + In writing mode, the region [0..bufpos) contains data received through API + but not yet written to the file descriptor. ftell() reports fdpos + bufpos. + The rest of the buffer is undefined. + + The ungetc() function pushes back characters into the buffer; if the FILE is + unbuffered, then it's made buffered temporarily to hold the characters and + cleared at the next fflush() or read. The buffer is put in reading mode. For + this reason, reading functions should test [fp->buf] to check whether there + is a buffer instead of [fp->bufmode != _IONBF]. + + Many fields in the FILE structure are abstracted away by API calls in layers: + + 1. [fd], [fdpos] and [error] are updated by the primitive functions of + fileutil.c which essentially wrap kernel I/O (plus clearerr() obviously). + 2. [buf], [bufsize], [bufmode] and [bufowned] are handled by setbuf(), + setvbuf() and fclose(). + 3. [bufpos], [bufread] and [bufdir] are set by primitive read/write functions + like fgets() or fwrite(), and cleared by fflush(). + 4. [readable], [writable], [append] and [text] are set by fopen() and + freopen(), and used as read-only by the primitive functions of 3. */ +typedef struct { + /* File descriptor */ + int fd; + /* Current position in file, as tracked by the file descriptor (ie. not + accounting for buffer operations) */ + size_t fdpos; + + /* Pointer to buffer (NULL if _IONBF) */ + char *buf; + /* Current position in buffer, water mark of read data in buffer, and + buffer size; see header comment for details */ + size_t bufpos; + size_t bufread; + size_t bufsize; + /* Number of ungetc()'d characters at the start of buffer data */ + int bufungetc; + /* Buffering mode; one of _IOFBF, _IOLBF, or _IONBF */ + uint8_t bufmode :2; + /* We own the buffer and it needs to be freed */ + uint8_t bufowned :1; + /* __FILE_BUF_READ if the buffer is in reading mode + __FILE_BUF_WRITE if it's in writing mode + This mode can only be changed immediately after fflush(). */ + uint8_t bufdir :1; + + /* Opening flags */ + uint8_t readable :1; + uint8_t writable :1; + uint8_t append :1; + /* Non-zero if text mode, zero if binary mode */ + uint8_t text :1; + /* EOF indicator */ + uint8_t eof :1; + /* Error indicator */ + uint8_t error :1; +} FILE; /* Type of positions within files. We don't have wide-oriented streams. */ typedef size_t fpos_t; diff --git a/include/target/casiowin-cg/bits/types/FILE.h b/include/target/casiowin-cg/bits/types/FILE.h deleted file mode 100644 index f65bcb4..0000000 --- a/include/target/casiowin-cg/bits/types/FILE.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __BITS_TYPES_FILE_H__ -# define __BITS_TYPES_FILE_H__ - -typedef struct { -} FILE; - -#endif /*__BITS_TYPES_FILE_H__*/ diff --git a/include/target/casiowin-fx/bits/types/FILE.h b/include/target/casiowin-fx/bits/types/FILE.h deleted file mode 100644 index f65bcb4..0000000 --- a/include/target/casiowin-fx/bits/types/FILE.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __BITS_TYPES_FILE_H__ -# define __BITS_TYPES_FILE_H__ - -typedef struct { -} FILE; - -#endif /*__BITS_TYPES_FILE_H__*/ diff --git a/include/target/gint/bits/types/FILE.h b/include/target/gint/bits/types/FILE.h deleted file mode 100644 index 50be340..0000000 --- a/include/target/gint/bits/types/FILE.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef __BITS_TYPES_FILE_H__ -# define __BITS_TYPES_FILE_H__ - -#include -#include -#include - -#define __FILE_BUF_READ 0 -#define __FILE_BUF_WRITE 1 - -/* The FILE structure is mostly a buffer around kernel-level I/O. Most of the - work is maintaining that buffer to provide the basic fgetc()/fputc() - functions, then everything else is built on top of the abstracted stream. - - The buffer of a FILE can either be in reading or writing mode. When in - reading mode, the buffer contains pre-fetched data from a previous read that - hasn't yet been requested by the user. When in writing mode, the buffer - contains data written by the user which hasn't yet been sent to the kernel. - - The buffer has the following structure: - - 0 bufpos bufread bufsize - +--------+---------+---------+ - |xxxxxxxx|rrrrrrrrr|uuuuuuuuu| (When reading) - +--------+---------+---------+ - |wwwwwwww|uuuuuuuuuuuuuuuuuuu| (When writing) - +--------+-------------------+ - - x: Data read from file descriptor and returned to user - r: Data read from file descriptor not yet returned to user - w: Data written by user not yet sent to file descriptor - u: Undefined - - In reading mode, the region [0..bufread) contains data obtained from the - file. bufpos marks how much has been read, in the sense that [0..bufpos) has - already been returned to the user while [bufpos..bufread) has not. The offset - on the underlying file descriptor sits at bufread, so the position reported - by ftell() is fdpos - bufread + bufpos. The rest of the buffer is undefined. - - In writing mode, the region [0..bufpos) contains data received through API - but not yet written to the file descriptor. ftell() reports fdpos + bufpos. - The rest of the buffer is undefined. - - The ungetc() function pushes back characters into the buffer; if the FILE is - unbuffered, then it's made buffered temporarily to hold the characters and - cleared at the next fflush() or read. The buffer is put in reading mode. For - this reason, reading functions should test [fp->buf] to check whether there - is a buffer instead of [fp->bufmode != _IONBF]. - - Many fields in the FILE structure are abstracted away by API calls in layers: - - 1. [fd], [fdpos] and [error] are updated by the primitive functions of - fileutil.c which essentially wrap kernel I/O (plus clearerr() obviously). - 2. [buf], [bufsize], [bufmode] and [bufowned] are handled by setbuf(), - setvbuf() and fclose(). - 3. [bufpos], [bufread] and [bufdir] are set by primitive read/write functions - like fgets() or fwrite(), and cleared by fflush(). - 4. [readable], [writable], [append] and [text] are set by fopen() and - freopen(), and used as read-only by the primitive functions of 3. - - TODO: EOF indicator */ -typedef struct { - /* File descriptor */ - int fd; - /* Current position in file, as tracked by the file descriptor (ie. not - accounting for buffer operations) */ - size_t fdpos; - - /* Pointer to buffer (NULL if _IONBF) */ - char *buf; - /* Current position in buffer, water mark of read data in buffer, and - buffer size; see header comment for details */ - size_t bufpos; - size_t bufread; - size_t bufsize; - /* Number of ungetc()'d characters at the start of buffer data */ - int bufungetc; - /* Buffering mode; one of _IOFBF, _IOLBF, or _IONBF */ - uint8_t bufmode :2; - /* We own the buffer and it needs to be freed */ - uint8_t bufowned :1; - /* __FILE_BUF_READ if the buffer is in reading mode - __FILE_BUF_WRITE if it's in writing mode - This mode can only be changed immediately after fflush(). */ - uint8_t bufdir :1; - - /* Opening flags */ - uint8_t readable :1; - uint8_t writable :1; - uint8_t append :1; - /* Non-zero if text mode, zero if binary mode */ - uint8_t text :1; - /* EOF indicator */ - uint8_t eof :1; - /* Error indicator */ - uint8_t error :1; -} FILE; - -#endif /*__BITS_TYPES_FILE_H__*/ diff --git a/include/target/vhex-generic/bits/types/FILE.h b/include/target/vhex-generic/bits/types/FILE.h deleted file mode 100644 index ff78882..0000000 --- a/include/target/vhex-generic/bits/types/FILE.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __BITS_TYPES_FILE_H__ -# define __BITS_TYPES_FILE_H__ - -// opaque definition of the _IO_FILE -struct _IO_FILE; - -/* -** The opaque type of streams. -** This is the definition used elsewhere. -*/ -typedef struct _IO_FILE FILE; - -#endif /*__BITS_TYPES_FILE_H__*/ diff --git a/include/target/vhex-generic/bits/types/__FILE.h b/include/target/vhex-generic/bits/types/__FILE.h deleted file mode 100644 index e90bb71..0000000 --- a/include/target/vhex-generic/bits/types/__FILE.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __BITS_TYPES___FILE_H__ -# define ___BITS_TYPES___FILE_H__ - -// define opaque definition of the FILE type -struct _IO_FILE; -typedef struct _IO_FILE __FILE; - -#endif /*__BITS_TYPES___FILE_H__*/ diff --git a/include/target/vhex-generic/bits/types/struct_FILE.h b/include/target/vhex-generic/bits/types/struct_FILE.h deleted file mode 100644 index e35976c..0000000 --- a/include/target/vhex-generic/bits/types/struct_FILE.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __BITS_TYPES_STRUCT_FILE_H__ -# define __BITS_TYPES_STRUCT_FILE_H__ - -#include -#include - -#include - -//--- -// TODO: VFS abstraction ? or ABI-spesific abstraction ? -//--- - - -// Define _IO_FILE -// TODO: add open flags -// TODO: add file descriptor ? -// TODO: update me ! -struct _IO_FILE -{ - off_t cursor; - int permission; - void *file_op; - void *private; -}; - -#endif /*__BITS_TYPES_STRUCT_FILE_H__*/