// "cfa -E fstream.c > fstream_out.c" // "cfa -c -o fstream.o fstream.c" #include "fstream.h" extern "C" { #include #include } struct ofstream { FILE *file; int fail; }; ofstream * write( ofstream *os, const char *data, streamsize_type size ) { if( !os->fail ) { fwrite( data, size, 1, os->file ); os->fail = ferror( os->file ); } return os; } int fail( ofstream *os ) { return os->fail; } static ofstream * make_ofstream() { ofstream *new_stream = malloc( sizeof( ofstream ) ); new_stream->fail = 0; return new_stream; } ofstream * ofstream_stdout() { ofstream *stdout_stream = make_ofstream(); stdout_stream->file = stdout; return stdout_stream; } ofstream * ofstream_stderr() { ofstream *stderr_stream = make_ofstream(); stderr_stream->file = stderr; return stderr_stream; } ofstream * ofstream_fromfile( const char *name ) { ofstream *file_stream = make_ofstream(); file_stream->file = fopen( name, "w" ); file_stream->fail = file_stream->file == 0; return file_stream; } void ofstream_close( ofstream *os ) { if( os->file != stdout && os->file != stderr ) { os->fail = fclose( os->file ); } free( os ); } struct ifstream { FILE *file; int fail; int eof; }; ifstream * read( ifstream *is, char *data, streamsize_type size ) { if( !is->fail && !is->eof ) { fread( data, size, 1, is->file ); is->fail = ferror( is->file ); is->eof = feof( is->file ); } return is; } ifstream *unread( ifstream *is, char c ) { if( !is->fail ) { if( EOF == ungetc( c, is->file ) ) { is->fail = 1; } } return is; } int fail( ifstream *is ) { return is->fail; } int eof( ifstream *is ) { return is->eof; } static ifstream * make_ifstream() { ifstream *new_stream = malloc( sizeof( ifstream ) ); new_stream->fail = 0; new_stream->eof = 0; return new_stream; } ifstream * ifstream_stdin() { ifstream *stdin_stream = make_ifstream(); stdin_stream->file = stdin; return stdin_stream; } ifstream * ifstream_fromfile( const char *name ) { ifstream *file_stream = make_ifstream(); file_stream->file = fopen( name, "r" ); file_stream->fail = file_stream->file == 0; return file_stream; }