]> pd.if.org Git - pdclib/commitdiff
Reworking internal file handling.
authorsolar <unknown>
Thu, 17 Jun 2010 05:27:15 +0000 (05:27 +0000)
committersolar <unknown>
Thu, 17 Jun 2010 05:27:15 +0000 (05:27 +0000)
functions/stdio/fopen.c
functions/stdio/freopen.c
functions/stdio/setvbuf.c
internals/_PDCLIB_int.h
platform/example/functions/_PDCLIB/open.c
platform/example_cygwin/functions/_PDCLIB/open.c

index 1c47c17a974636e3acdb3af3fbe8ec28ac17cdfb..93e27191aaf9a06d78d9253e3db96406d9080e51 100644 (file)
@@ -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."
     */
        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;
     /* TODO: Setting mbstate */
     /* Adding to list of open files */
     rc->next = _PDCLIB_filelist;
index 906096f4a5cfbc57e6ab28770b9e2bc7dfd67f3c..a2c0adade6b91908d5644c7b3dbb1e7ad66fd6b7 100644 (file)
    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.
    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.)
 */
    (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 )
 {
 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 */
     /* 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 );
     _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->bufidx = 0;
-    stream->status |= _PDCLIB_LIBBUFFER;
+    stream->bufend = 0;
+    stream->ungetidx = 0;
     /* TODO: Setting mbstate */
     /* TODO: Setting mbstate */
+    if ( ( stream->handle = _PDCLIB_open( filename, stream->status ) ) == _PDCLIB_NOHANDLE )
+    {
+        return NULL;
+    }
     return stream;
 }
 
     return stream;
 }
 
index 125a73f8808a32d341cd67710c1f0c0d7b9694e2..b9d97a01d0cead30eb2abbc4e0f4a90b3f4af1a6 100644 (file)
@@ -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.
             */
                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:
             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.
             {
                 /* 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.
                 */
                 /* 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 ( ( 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;
                     }
                     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;
             stream->buffer = buf;
             stream->bufsize = size;
             break;
index 20a1682303f0b8424be974f41a532af31743ddd7..9c67f277ee4fec47ba1abc2e46e4329fd55f4a8c 100644 (file)
@@ -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_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
 #define _PDCLIB_ERRORFLAG   1024u
 #define _PDCLIB_EOFFLAG     2048u
 #define _PDCLIB_WIDESTREAM  4096u
index 79497266350fb49992c533adb00bd546fe2b8e5e..f0379ba64d986823fa6dc6acf37ccd3daf67570a 100644 (file)
@@ -30,7 +30,7 @@ int _PDCLIB_open( char const * const filename, unsigned int mode )
        here.
     */
     int osmode;
        here.
     */
     int osmode;
-    switch ( mode & ~_PDCLIB_FBIN )
+    switch ( mode & ( _PDCLIB_FREAD | _PDCLIB_FWRITE | _PDCLIB_FAPPEND | _PDCLIB_FRW ) )
     {
         case _PDCLIB_FREAD: /* "r" */
             osmode = O_RDONLY;
     {
         case _PDCLIB_FREAD: /* "r" */
             osmode = O_RDONLY;
index 79497266350fb49992c533adb00bd546fe2b8e5e..f0379ba64d986823fa6dc6acf37ccd3daf67570a 100644 (file)
@@ -30,7 +30,7 @@ int _PDCLIB_open( char const * const filename, unsigned int mode )
        here.
     */
     int osmode;
        here.
     */
     int osmode;
-    switch ( mode & ~_PDCLIB_FBIN )
+    switch ( mode & ( _PDCLIB_FREAD | _PDCLIB_FWRITE | _PDCLIB_FAPPEND | _PDCLIB_FRW ) )
     {
         case _PDCLIB_FREAD: /* "r" */
             osmode = O_RDONLY;
     {
         case _PDCLIB_FREAD: /* "r" */
             osmode = O_RDONLY;