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