diff --git a/CMakeLists.txt b/CMakeLists.txt index c8d5b33..6679ff6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,14 +119,21 @@ set(SOURCES src/libc/signal/raise.c # stdio src/libc/stdio/asprintf.c + src/libc/stdio/clearerr.c src/libc/stdio/dprintf.c src/libc/stdio/fclose.c src/libc/stdio/fdopen.c + src/libc/stdio/ferror.c + src/libc/stdio/feof.c src/libc/stdio/fflush.c + src/libc/stdio/fgetpos.c src/libc/stdio/fileutil.c src/libc/stdio/fopen.c src/libc/stdio/fprintf.c src/libc/stdio/freopen.c + src/libc/stdio/fseek.c + src/libc/stdio/fsetpos.c + src/libc/stdio/ftell.c src/libc/stdio/printf.c src/libc/stdio/printf/format_fixed.c src/libc/stdio/printf/format_fp.c @@ -136,6 +143,7 @@ set(SOURCES src/libc/stdio/putc.c src/libc/stdio/puts.c src/libc/stdio/remove.c + src/libc/stdio/rewind.c src/libc/stdio/setbuf.c src/libc/stdio/setvbuf.c src/libc/stdio/snprintf.c diff --git a/STATUS b/STATUS index 919b6dc..d51da92 100644 --- a/STATUS +++ b/STATUS @@ -95,7 +95,7 @@ TEST: Function/symbol/macro needs to be tested 7.19.5.2 fflush TEST 7.19.5.3 fopen TEST (EXT) fdopen TEST - 7.19.5.4 freopen TODO + 7.19.5.4 freopen TEST 7.19.5.5 setbuf TEST 7.19.5.6 setvbuf TEST @@ -133,15 +133,15 @@ TEST: Function/symbol/macro needs to be tested 7.19.8.1 fread TODO 7.19.8.2 fwrite TODO - 7.19.9.1 fgetpos TODO - 7.19.9.2 fseek TODO - 7.19.9.3 fsetpos TODO - 7.19.9.4 ftell TODO - 7.19.9.5 rewind TODO + 7.19.9.1 fgetpos TEST + 7.19.9.2 fseek TEST + 7.19.9.3 fsetpos TEST + 7.19.9.4 ftell TEST + 7.19.9.5 rewind TEST - 7.19.10.1 clearerr TODO - 7.19.10.2 feof TODO - 7.19.10.3 ferror TODO + 7.19.10.1 clearerr - + 7.19.10.2 feof - + 7.19.10.3 ferror - 7.19.10.4 perror TODO 7.20 diff --git a/include/stdio.h b/include/stdio.h index 0630100..8ec7286 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -11,7 +11,7 @@ extern "C" { /* Type of FILE handlers. */ #include -/* Type of positions within files. */ +/* Type of positions within files. We don't have wide-oriented streams. */ typedef size_t fpos_t; /* Buffering modes. */ @@ -174,6 +174,38 @@ extern int asprintf(char ** __restrict__ __str, extern int vasprintf(char ** __restrict__ __str, char const * __restrict__ __format, va_list __args); +/* +** File positioning functions; +*/ + +/* Get current position (same as ftell() unless wide-oriented). */ +extern int fgetpos(FILE * __restrict__ __fp, fpos_t * __restrict__ __pos); + +/* Set the current position. */ +extern int fseek(FILE *__fp, long __offset, int __whence); + +/* Restore the position to a value returned by fgetpos(). */ +extern int fsetpos(FILE *__fp, fpos_t const *__pos); + +/* Get the current position. */ +extern long ftell(FILE *__fp); + +/* Sets the file position to the start of the stream. */ +extern void rewind(FILE *__fp); + +/* +** Error-handling functions. +*/ + +/* Clear EOF and error flags in the stream. */ +extern void clearerr(FILE *__fp); + +/* Test the EOF flag. */ +extern int feof(FILE *__fp); + +/* Test the error flag. */ +extern int ferror(FILE *__fp); + #ifdef __cplusplus } #endif diff --git a/include/target/gint/bits/types/FILE.h b/include/target/gint/bits/types/FILE.h index 8d047e3..af868ce 100644 --- a/include/target/gint/bits/types/FILE.h +++ b/include/target/gint/bits/types/FILE.h @@ -73,7 +73,7 @@ typedef struct { 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 when bufpos=0, ie. just after fflush(). */ + This mode can only be changed immediately after fflush(). */ uint8_t bufdir :1; /* Opening flags */ diff --git a/src/libc/stdio/clearerr.c b/src/libc/stdio/clearerr.c new file mode 100644 index 0000000..01b479b --- /dev/null +++ b/src/libc/stdio/clearerr.c @@ -0,0 +1,7 @@ +#include + +void clearerr(FILE *fp) +{ + fp->error = 0; + fp->eof = 0; +} diff --git a/src/libc/stdio/feof.c b/src/libc/stdio/feof.c new file mode 100644 index 0000000..f5a9722 --- /dev/null +++ b/src/libc/stdio/feof.c @@ -0,0 +1,6 @@ +#include + +int feof(FILE *fp) +{ + return fp->eof; +} diff --git a/src/libc/stdio/ferror.c b/src/libc/stdio/ferror.c new file mode 100644 index 0000000..bc8261b --- /dev/null +++ b/src/libc/stdio/ferror.c @@ -0,0 +1,6 @@ +#include + +int ferror(FILE *fp) +{ + return fp->error; +} diff --git a/src/libc/stdio/fgetpos.c b/src/libc/stdio/fgetpos.c new file mode 100644 index 0000000..bdb3b54 --- /dev/null +++ b/src/libc/stdio/fgetpos.c @@ -0,0 +1,16 @@ +#include + +int fgetpos(FILE *fp, fpos_t *pos) +{ + if(fp->buf && fp->bufdir == __FILE_BUF_WRITE) { + *pos = fp->fdpos + fp->bufpos; + } + else if(fp->buf && fp->bufdir == __FILE_BUF_READ) { + *pos = fp->fdpos - fp->bufread + fp->bufpos; + } + else { + *pos = fp->fdpos; + } + + return 0; +} diff --git a/src/libc/stdio/fseek.c b/src/libc/stdio/fseek.c new file mode 100644 index 0000000..4ea1d38 --- /dev/null +++ b/src/libc/stdio/fseek.c @@ -0,0 +1,16 @@ +#include +#include + +int fseek(FILE *fp, long offset, int whence) +{ + if(fflush(fp) == EOF) + return -1; + + off_t rc = lseek(fp->fd, offset, whence); + if(rc < 0) + return -1; + + fp->fdpos = rc; + fp->eof = 0; + return 0; +} diff --git a/src/libc/stdio/fsetpos.c b/src/libc/stdio/fsetpos.c new file mode 100644 index 0000000..ffaa4e0 --- /dev/null +++ b/src/libc/stdio/fsetpos.c @@ -0,0 +1,13 @@ +#include +#include + +int fsetpos(FILE *fp, fpos_t const *pos) +{ + if(fflush(fp) == EOF) + return -1; + + lseek(fp->fd, *pos, SEEK_SET); + fp->fdpos = *pos; + fp->eof = 0; + return 0; +} diff --git a/src/libc/stdio/ftell.c b/src/libc/stdio/ftell.c new file mode 100644 index 0000000..f5deecd --- /dev/null +++ b/src/libc/stdio/ftell.c @@ -0,0 +1,10 @@ +#include + +long ftell(FILE *fp) +{ + fpos_t pos; + if(fgetpos(fp, &pos)) + return -1; + + return (long)pos; +} diff --git a/src/libc/stdio/rewind.c b/src/libc/stdio/rewind.c new file mode 100644 index 0000000..6876a68 --- /dev/null +++ b/src/libc/stdio/rewind.c @@ -0,0 +1,6 @@ +#include + +void rewind(FILE *fp) +{ + fseek(fp, 0, SEEK_SET); +}