]> pd.if.org Git - pdclib/blob - functions/stdio/fopen.c
Bracing error; fixed.
[pdclib] / functions / stdio / fopen.c
1 /* $Id$ */
2
3 /* fopen( const char *, const char * )
4
5    This file is part of the Public Domain C Library (PDCLib).
6    Permission is granted to use, modify, and / or redistribute at will.
7 */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11
12 #ifndef REGTEST
13 #include <_PDCLIB_glue.h>
14
15 static FILE * _PDCLIB_filelist = NULL;
16
17 /* Helper function that parses the C-style mode string passed to fopen() into
18    the PDCLib flags.FREAD, FWRITE, FAPPEND, FRW (read-write) and FBIN (
19    mode).
20 */
21 static unsigned int filemode( char const * const mode )
22 {
23     int rc = 0;
24     switch ( mode[0] )
25     {
26         case 'r':
27             rc |= _PDCLIB_FREAD;
28             break;
29         case 'w':
30             rc |= _PDCLIB_FWRITE;
31             break;
32         case 'a':
33             rc |= _PDCLIB_FAPPEND;
34             break;
35         default:
36             /* Other than read, write, or append - invalid */
37             return 0;
38     }
39     for ( size_t i = 1; i < 4; ++i )
40     {
41         switch ( mode[1] )
42         {
43             case '+':
44                 if ( rc & _PDCLIB_FRW ) return 0; /* Duplicates are invalid */
45                 rc |= _PDCLIB_FRW;
46                 break;
47             case 'b':
48                 if ( rc & _PDCLIB_FBIN ) return 0; /* Duplicates are invalid */
49                 rc |= _PDCLIB_FBIN;
50                 break;
51             case '\0':
52                 /* End of mode */
53                 return rc;
54             default:
55                 /* Other than read/write or binary - invalid. */
56                 return 0;
57         }
58     }
59     /* Longer than three chars - invalid. */
60     return 0;
61 }
62
63 FILE * fopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode )
64 {
65     FILE * rc;
66     if ( mode == NULL || filename == NULL || filename[0] == '\0' )
67     {
68         /* Mode or filename invalid */
69         return NULL;
70     }
71     if ( ( rc = calloc( 1, sizeof( FILE ) ) ) == NULL )
72     {
73         /* no memory for another FILE */
74         return NULL;
75     }
76     if ( ( rc->status = filemode( mode ) ) == 0 ) goto fail; /* invalid mode */
77     rc->handle = _PDCLIB_open( filename, rc->status );
78     if ( rc->handle == _PDCLIB_NOHANDLE ) goto fail; /* OS open() failed */
79
80     /* Adding to list of open files */
81     rc->next = _PDCLIB_filelist;
82     _PDCLIB_filelist = rc;
83     /* Setting buffer. TODO: Check for unbuffered? */
84     if ( ( rc->buffer = malloc( BUFSIZ ) ) == NULL ) goto fail;
85     /* TODO: Setting mbstate */
86     return rc;
87 fail:
88     free( rc );
89     return NULL;
90 }
91
92 #endif
93
94 #ifdef TEST
95 #include <_PDCLIB_test.h>
96
97 int main( void )
98 {
99     TESTCASE( NO_TESTDRIVER );
100     return TEST_RESULTS;
101 }
102
103 #endif