6 FILE *read_open( char *file )
8 /* Martin A. Hansen, November 2005 */
12 /* Given a file name, read-opens the file, */
13 /* and returns a file pointer. */
17 if ( ( fp = fopen( file, "r" ) ) == NULL )
19 fprintf( stderr, "ERROR: Could not read-open file '%s': %s\n", file, strerror( errno ) );
27 FILE *write_open( char *file )
29 /* Martin A. Hansen, November 2005 */
33 /* Given a file name, write-opens the file, */
34 /* and returns a file pointer. */
38 if ( ( fp = fopen( file, "w" ) ) == NULL )
40 fprintf( stderr, "ERROR: Could not write-open file '%s': %s\n", file, strerror( errno ) );
48 FILE *append_open( char *file )
50 /* Martin A. Hansen, November 2005 */
54 /* Given a file name, append-opens the file, */
55 /* and returns a file pointer. */
59 if ( ( fp = fopen( file, "a" ) ) == NULL )
61 fprintf( stderr, "ERROR: Could not append-open file '%s': %s\n", file, strerror( errno ) );
69 void close_stream( FILE *fp )
71 /* Martin A. Hansen, May 2008 */
75 /* Closes a stream or file associated with a given file pointer. */
77 if ( ( fclose( fp ) ) != 0 )
79 fprintf( stderr, "ERROR: Could not close stream: %s\n", strerror( errno ) );
85 char *file_read( FILE *fp, size_t len )
87 /* Martin A. Hansen, June 2008 */
89 /* Read in len number of bytes from the current position of a */
90 /* file pointer into a string that is allocated and null terminated. */
96 string = mem_get( len + 1 );
98 fread( string, len, 1, fp );
100 if ( ferror( fp ) != 0 )
102 fprintf( stderr, "ERROR: file_read failed\n" );
105 else if ( feof( fp ) )
107 fprintf( stderr, "ERROR: file_read failed - end-of-file reached\n" );
112 string[ len ] = '\0';
118 void file_unlink( char *file )
120 /* Martin A. Hansen, June 2008 */
122 /* Unit test done. */
126 if ( unlink( file ) == -1 )
128 fprintf( stderr, "ERROR: Could not unlink file '%s': %s\n", file, strerror( errno ) );
134 void file_rename( char *old_name, char *new_name )
136 /* Martin A. Hansen, June 2008 */
138 /* Unit test done. */
142 if ( rename( old_name, new_name ) != 0 )
144 fprintf( stderr, "ERROR: Could not rename file '%s' -> '%s': %s\n", old_name, new_name, strerror( errno ) );
151 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FILE BUFFER <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
154 struct file_buffer *read_open_buffer( char *file )
156 /* Martin A. Hansen, June 2008 */
158 /* Opens a file for reading and loads a new buffer.*/
160 struct file_buffer *buffer;
167 fp = read_open( file );
169 str = file_read( fp, FILE_BUFFER_SIZE );
171 feof( fp ) ? ( eof = TRUE ) : ( eof = FALSE );
177 buffer->end = strlen( str );
178 buffer->size = FILE_BUFFER_SIZE;
185 char buffer_getc( struct file_buffer *buffer )
187 /* Martin A. Hansen, June 2008 */
189 /* Get the next char from a file buffer, which is resized if necessary, until EOF.*/
193 if ( buffer->use == buffer->end )
201 buffer->pos = buffer->use;
202 buffer_new_size( buffer, buffer->use );
203 buffer_resize( buffer );
207 return buffer->str[ buffer->use++ ];
212 char *buffer_gets( struct file_buffer *buffer )
214 /* Martin A. Hansen, June 2008 */
216 /* Get the next line that is terminated by \n or EOF from a file buffer. */
224 if ( ( pt = memchr( &buffer->str[ buffer->use ], '\n', buffer->end - buffer->use ) ) != NULL )
226 line_size = pt - &buffer->str[ buffer->use ] + 1;
228 line = mem_get( line_size );
230 memcpy( line, &buffer->str[ buffer->use ], line_size );
232 line[ line_size ] = '\0';
234 buffer->use += line_size;
236 buffer_new_size( buffer, line_size );
245 buffer_resize( buffer );
252 void buffer_new_size( struct file_buffer *buffer, int len )
254 /* Martin A. Hansen, June 2008 */
256 /* Increases buffer size until it is larger than len. */
258 while ( buffer->size < len )
262 if ( buffer->size <= 0 ) {
263 die( "buffer_new_size failed." );
269 void buffer_resize( struct file_buffer *buffer )
271 /* Martin A. Hansen, June 2008 */
273 /* Resize file buffer. */
279 str = file_read( buffer->fp, buffer->size );
281 str_len = strlen( str );
283 feof( buffer->fp ) ? ( buffer->eof = TRUE ) : ( buffer->eof = FALSE );
285 if ( buffer->pos != 0 )
287 memmove( buffer->str, &buffer->str[ buffer->pos ], buffer->use - buffer->pos );
289 buffer->end -= buffer->pos;
294 new_end = buffer->end + str_len;
296 buffer->str = mem_resize( buffer->str, new_end + 1 );
298 memcpy( &buffer->str[ buffer->end ], str, str_len );
300 buffer->str[ new_end + 1 ] = '\0';
302 buffer->end = new_end;
308 void buffer_destroy( struct file_buffer *buffer )
310 /* Martin A. Hansen, June 2008 */
312 /* Deallocates memory and close stream used by file buffer. */
314 close_stream( buffer->fp );
316 mem_free( buffer->str );
321 void buffer_print( struct file_buffer *buffer )
323 /* Martin A. Hansen, June 2008 */
325 /* Debug function that prints the content of a file_buffer. */
327 printf( "buffer: {\n" );
328 printf( " pos : %lu\n", buffer->pos );
329 printf( " use : %lu\n", buffer->use );
330 printf( " end : %lu\n", buffer->end );
331 printf( " eof : %d\n", buffer->eof );
332 printf( " str : ->%s<-\n", buffer->str );
333 printf( " str_len: %lu\n", strlen( buffer->str ) );
338 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/