]> pd.if.org Git - pdclib/blob - functions/stdio/_PDCLIB_filemode.c
PDCLib includes with quotes, not <>.
[pdclib] / functions / stdio / _PDCLIB_filemode.c
1 /* _PDCLIB_filemode( const char * )
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 <stddef.h>
8
9 #ifndef REGTEST
10 #include "_PDCLIB_io.h"
11 /* Helper function that parses the C-style mode string passed to fopen() into
12    the PDCLib flags FREAD, FWRITE, FAPPEND, FRW (read-write) and FBIN (binary
13    mode).
14 */
15 unsigned int _PDCLIB_filemode( char const * const mode )
16 {
17     if(!mode) return 0;
18
19     unsigned rc = 0;
20     switch ( mode[0] )
21     {
22         case 'r':
23             rc |= _PDCLIB_FREAD;
24             break;
25         case 'w':
26             rc |= _PDCLIB_FWRITE;
27             break;
28         case 'a':
29             rc |= _PDCLIB_FAPPEND | _PDCLIB_FWRITE;
30             break;
31         default:
32             /* Other than read, write, or append - invalid */
33             return 0;
34     }
35     for ( size_t i = 1; i < 4; ++i )
36     {
37         switch ( mode[i] )
38         {
39             case '+':
40                 if ( rc & _PDCLIB_FRW ) return 0; /* Duplicates are invalid */
41                 rc |= _PDCLIB_FRW;
42                 break;
43             case 'b':
44                 if ( rc & _PDCLIB_FBIN ) return 0; /* Duplicates are invalid */
45                 rc |= _PDCLIB_FBIN;
46                 break;
47             case '\0':
48                 /* End of mode */
49                 return rc;
50             default:
51                 /* Other than read/write or binary - invalid. */
52                 return 0;
53         }
54     }
55     /* Longer than three chars - invalid. */
56     return 0;
57 }
58 #endif
59
60 #ifdef TEST
61 #include "_PDCLIB_test.h"
62
63 int main( void )
64 {
65 #ifndef REGTEST
66     TESTCASE( _PDCLIB_filemode( "r" ) == _PDCLIB_FREAD );
67     TESTCASE( _PDCLIB_filemode( "w" ) == _PDCLIB_FWRITE );
68     TESTCASE( _PDCLIB_filemode( "a" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE ) );
69     TESTCASE( _PDCLIB_filemode( "r+" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW ) );
70     TESTCASE( _PDCLIB_filemode( "w+" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW ) );
71     TESTCASE( _PDCLIB_filemode( "a+" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FRW ) );
72     TESTCASE( _PDCLIB_filemode( "rb" ) == ( _PDCLIB_FREAD | _PDCLIB_FBIN ) );
73     TESTCASE( _PDCLIB_filemode( "wb" ) == ( _PDCLIB_FWRITE | _PDCLIB_FBIN ) );
74     TESTCASE( _PDCLIB_filemode( "ab" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FBIN ) );
75     TESTCASE( _PDCLIB_filemode( "r+b" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW | _PDCLIB_FBIN ) );
76     TESTCASE( _PDCLIB_filemode( "w+b" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) );
77     TESTCASE( _PDCLIB_filemode( "a+b" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) );
78     TESTCASE( _PDCLIB_filemode( "rb+" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW | _PDCLIB_FBIN ) );
79     TESTCASE( _PDCLIB_filemode( "wb+" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) );
80     TESTCASE( _PDCLIB_filemode( "ab+" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) );
81     TESTCASE( _PDCLIB_filemode( "x" ) == 0 );
82     TESTCASE( _PDCLIB_filemode( "r++" ) == 0 );
83     TESTCASE( _PDCLIB_filemode( "wbb" ) == 0 );
84     TESTCASE( _PDCLIB_filemode( "a+bx" ) == 0 );
85 #endif
86     return TEST_RESULTS;
87 }
88
89 #endif
90