From 8f67eac83402119dfdd2627da82c65d5a349cb02 Mon Sep 17 00:00:00 2001 From: solar Date: Thu, 17 Jun 2010 05:27:15 +0000 Subject: [PATCH] Reworking internal file handling. --- functions/stdio/fopen.c | 2 +- functions/stdio/freopen.c | 41 +++++++++++++------ functions/stdio/setvbuf.c | 27 +++++------- internals/_PDCLIB_int.h | 2 +- platform/example/functions/_PDCLIB/open.c | 2 +- .../example_cygwin/functions/_PDCLIB/open.c | 2 +- 6 files changed, 42 insertions(+), 34 deletions(-) diff --git a/functions/stdio/fopen.c b/functions/stdio/fopen.c index 1c47c17..93e2719 100644 --- a/functions/stdio/fopen.c +++ b/functions/stdio/fopen.c @@ -64,7 +64,7 @@ struct _PDCLIB_file_t * fopen( const char * _PDCLIB_restrict filename, const cha buffered if and only if it can be determined not to refer to an interactive device." */ - rc->status |= _PDCLIB_LIBBUFFER | _IOLBF; + rc->status |= _IOLBF; /* TODO: Setting mbstate */ /* Adding to list of open files */ rc->next = _PDCLIB_filelist; diff --git a/functions/stdio/freopen.c b/functions/stdio/freopen.c index 906096f..a2c0ada 100644 --- a/functions/stdio/freopen.c +++ b/functions/stdio/freopen.c @@ -17,28 +17,43 @@ identified by the given filename with the given mode (equivalent to fopen()), and associate it with the given stream. If filename is a NULL pointer, attempt to change the mode of the given stream. - This implementation allows the following mode changes: TODO + This implementation allows any mode changes. (Primary use of this function is to redirect stdin, stdout, and stderr.) */ - struct _PDCLIB_file_t * freopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode, struct _PDCLIB_file_t * _PDCLIB_restrict stream ) { - /* FIXME: This is ad-hoc (to make the vprintf() testdriver work), and must be checked. */ - /* FIXME: If filename is NULL, change mode. */ + unsigned int status = stream->status & ( _IONBF | _IOLBF | _IOFBF | _PDCLIB_FREEBUFFER | _PDCLIB_DELONCLOSE ); /* TODO: This function can change wide orientation of a stream */ - if ( filename == NULL ) return NULL; - if ( stream->status & _PDCLIB_FWRITE ) fflush( stream ); - if ( stream->status & _PDCLIB_LIBBUFFER ) free( stream->buffer ); + if ( stream->status & _PDCLIB_FWRITE ) + { + _PDCLIB_flushbuffer( stream ); + } _PDCLIB_close( stream->handle ); clearerr( stream ); - if ( ( mode == NULL ) || ( filename[0] == '\0' ) ) return NULL; - if ( ( stream->status = _PDCLIB_filemode( mode ) ) == 0 ) return NULL; - stream->handle = _PDCLIB_open( filename, stream->status ); - if ( ( stream->buffer = malloc( BUFSIZ ) ) == NULL ) return NULL; - stream->bufsize = BUFSIZ; + /* FIXME: Copy filename into the FILE structure. */ + /* FIXME: filename cannot reside in "big block" memory */ + if ( filename == NULL ) + { + filename = stream->filename; + } + if ( ( mode == NULL ) || ( filename[0] == '\0' ) ) + { + return NULL; + } + if ( ( stream->status = _PDCLIB_filemode( mode ) ) == 0 ) + { + return NULL; + } + /* Re-add the flags we saved above */ + stream->status |= status; stream->bufidx = 0; - stream->status |= _PDCLIB_LIBBUFFER; + stream->bufend = 0; + stream->ungetidx = 0; /* TODO: Setting mbstate */ + if ( ( stream->handle = _PDCLIB_open( filename, stream->status ) ) == _PDCLIB_NOHANDLE ) + { + return NULL; + } return stream; } diff --git a/functions/stdio/setvbuf.c b/functions/stdio/setvbuf.c index 125a73f..b9d97a0 100644 --- a/functions/stdio/setvbuf.c +++ b/functions/stdio/setvbuf.c @@ -21,10 +21,11 @@ int setvbuf( struct _PDCLIB_file_t * _PDCLIB_restrict stream, char * _PDCLIB_res we don't want to e.g. flush the stream for every character of a stream being printed. */ + /* TODO: Check this */ break; case _IOFBF: case _IOLBF: - if ( size > INT_MAX || size == NULL ) + if ( size > INT_MAX || size == 0 ) { /* PDCLib only supports buffers up to INT_MAX in size. A size of zero doesn't make sense. @@ -36,31 +37,23 @@ int setvbuf( struct _PDCLIB_file_t * _PDCLIB_restrict stream, char * _PDCLIB_res /* User requested buffer size, but leaves it to library to allocate the buffer. */ + /* If current buffer is big enough for requested size, but not + over twice as big (and wasting memory space), we use the + current buffer (i.e., do nothing), to save the malloc() / + free() overhead. + */ if ( ( stream->bufsize < size ) || ( stream->bufsize > ( size << 1 ) ) ) { - /* If current buffer is big enough for requested size, but - not over twice as big (and wasting memory space), we use - the current buffer (i.e., do nothing), to save the - malloc() / free() overhead. - */ - /* Free the buffer allocated by fopen(), and allocate a new - one. - */ + /* Buffer too small, or much too large - allocate. */ if ( ( buf = (char *) malloc( size ) ) == NULL ) { /* Out of memory error. */ return -1; } + /* This buffer must be free()d on fclose() */ + stream->status |= _PDCLIB_FREEBUFFER; } } - else - { - /* User provided buffer -> set flag to not free() the buffer - on fclose(). - */ - stream->status &= ~ _PDCLIB_LIBBUFFER; - } - free( stream->buffer ); stream->buffer = buf; stream->bufsize = size; break; diff --git a/internals/_PDCLIB_int.h b/internals/_PDCLIB_int.h index 20a1682..9c67f27 100644 --- a/internals/_PDCLIB_int.h +++ b/internals/_PDCLIB_int.h @@ -258,7 +258,7 @@ typedef unsigned _PDCLIB_intmax _PDCLIB_uintmax_t; #define _PDCLIB_FBIN 128u /* Internal flags, made to fit the same status field as the flags above. */ -#define _PDCLIB_LIBBUFFER 512u +#define _PDCLIB_FREEBUFFER 512u #define _PDCLIB_ERRORFLAG 1024u #define _PDCLIB_EOFFLAG 2048u #define _PDCLIB_WIDESTREAM 4096u diff --git a/platform/example/functions/_PDCLIB/open.c b/platform/example/functions/_PDCLIB/open.c index 7949726..f0379ba 100644 --- a/platform/example/functions/_PDCLIB/open.c +++ b/platform/example/functions/_PDCLIB/open.c @@ -30,7 +30,7 @@ int _PDCLIB_open( char const * const filename, unsigned int mode ) here. */ int osmode; - switch ( mode & ~_PDCLIB_FBIN ) + switch ( mode & ( _PDCLIB_FREAD | _PDCLIB_FWRITE | _PDCLIB_FAPPEND | _PDCLIB_FRW ) ) { case _PDCLIB_FREAD: /* "r" */ osmode = O_RDONLY; diff --git a/platform/example_cygwin/functions/_PDCLIB/open.c b/platform/example_cygwin/functions/_PDCLIB/open.c index 7949726..f0379ba 100644 --- a/platform/example_cygwin/functions/_PDCLIB/open.c +++ b/platform/example_cygwin/functions/_PDCLIB/open.c @@ -30,7 +30,7 @@ int _PDCLIB_open( char const * const filename, unsigned int mode ) here. */ int osmode; - switch ( mode & ~_PDCLIB_FBIN ) + switch ( mode & ( _PDCLIB_FREAD | _PDCLIB_FWRITE | _PDCLIB_FAPPEND | _PDCLIB_FRW ) ) { case _PDCLIB_FREAD: /* "r" */ osmode = O_RDONLY; -- 2.40.0