]> pd.if.org Git - pdclib/blob - functions/stdio/freopen.c
Comment cleanups.
[pdclib] / functions / stdio / freopen.c
1 /* freopen( const char *, const char *, FILE * )
2
3    This file is part of the Public Domain C Library (PDCLib).
4    Permission is granted to use, modify, and / or redistribute at will.
5 */
6
7 #include <stdio.h>
8
9 #ifndef REGTEST
10
11 #include <_PDCLIB_glue.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 struct _PDCLIB_file_t * freopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode, struct _PDCLIB_file_t * _PDCLIB_restrict stream )
16 {
17     unsigned int status = stream->status & ( _IONBF | _IOLBF | _IOFBF | _PDCLIB_FREEBUFFER | _PDCLIB_DELONCLOSE );
18     /* TODO: This function can change wide orientation of a stream */
19     if ( stream->status & _PDCLIB_FWRITE )
20     {
21         _PDCLIB_flushbuffer( stream );
22     }
23     if ( ( filename == NULL ) && ( stream->filename == NULL ) )
24     {
25         /* TODO: Special handling for mode changes on std-streams */
26         return NULL;
27     }
28     _PDCLIB_close( stream->handle );
29     /* TODO: It is not nice to do this on a stream we just closed.
30        It does not matter with the current implementation of clearerr(),
31        but it might start to matter if someone replaced that implementation.
32     */
33     clearerr( stream );
34     /* The new filename might not fit the old buffer */
35     if ( filename == NULL )
36     {
37         /* Use previous filename */
38         filename = stream->filename;
39     }
40     else if ( ( stream->filename != NULL ) && ( strlen( stream->filename ) >= strlen( filename ) ) )
41     {
42         /* Copy new filename into existing buffer */
43         strcpy( stream->filename, filename );
44     }
45     else
46     {
47         /* Allocate new buffer */
48         if ( ( stream->filename = (char *)malloc( strlen( filename ) ) ) == NULL )
49         {
50             return NULL;
51         }
52         strcpy( stream->filename, filename );
53     }
54     if ( ( mode == NULL ) || ( filename[0] == '\0' ) )
55     {
56         return NULL;
57     }
58     if ( ( stream->status = _PDCLIB_filemode( mode ) ) == 0 )
59     {
60         return NULL;
61     }
62     /* Re-add the flags we saved above */
63     stream->status |= status;
64     stream->bufidx = 0;
65     stream->bufend = 0;
66     stream->ungetidx = 0;
67     /* TODO: Setting mbstate */
68     if ( ( stream->handle = _PDCLIB_open( filename, stream->status ) ) == _PDCLIB_NOHANDLE )
69     {
70         return NULL;
71     }
72     return stream;
73 }
74
75 #endif
76
77 #ifdef TEST
78 #include <_PDCLIB_test.h>
79
80 int main( void )
81 {
82     FILE * fin;
83     FILE * fout;
84     TESTCASE( ( fin = fopen( testfile1, "wb+" ) ) != NULL );
85     TESTCASE( fputc( 'x', fin ) == 'x' );
86     TESTCASE( fclose( fin ) == 0 );
87     TESTCASE( ( fin = freopen( testfile1, "rb", stdin ) ) != NULL );
88     TESTCASE( getchar() == 'x' );
89
90     TESTCASE( ( fout = freopen( testfile2, "wb+", stdout ) ) != NULL );
91     TESTCASE( putchar( 'x' ) == 'x' );
92     rewind( fout );
93     TESTCASE( fgetc( fout ) == 'x' );
94
95     TESTCASE( fclose( fin ) == 0 );
96     TESTCASE( fclose( fout ) == 0 );
97     TESTCASE( remove( testfile1 ) == 0 );
98     TESTCASE( remove( testfile2 ) == 0 );
99
100     return TEST_RESULTS;
101 }
102
103 #endif