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 size_t file_read( FILE *fp, char **string_ppt, 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. */
91 /* The number of read chars is returned. */
93 char *string = *string_ppt;
98 string = mem_get( len + 1 );
100 num = fread( string, 1, len, fp );
102 if ( ferror( fp ) != 0 )
104 fprintf( stderr, "ERROR: file_read failed\n" );
108 string[ num ] = '\0';
110 *string_ppt = string;
116 void file_unlink( char *file )
118 /* Martin A. Hansen, June 2008 */
120 /* Unit test done. */
124 if ( unlink( file ) == -1 )
126 fprintf( stderr, "ERROR: Could not unlink file '%s': %s\n", file, strerror( errno ) );
132 void file_rename( char *old_name, char *new_name )
134 /* Martin A. Hansen, June 2008 */
136 /* Unit test done. */
140 if ( rename( old_name, new_name ) != 0 )
142 fprintf( stderr, "ERROR: Could not rename file '%s' -> '%s': %s\n", old_name, new_name, strerror( errno ) );
149 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> FILE BUFFER <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
152 size_t buffer_new( char *file, file_buffer **buffer_ppt, size_t size )
154 /* Martin A. Hansen, June 2008 */
156 /* Opens a file for reading and loads a new buffer.*/
157 /* The number of read chars is returned. */
159 file_buffer *buffer = *buffer_ppt;
163 buffer = mem_get( sizeof( file_buffer ) );
165 fp = read_open( file );
169 buffer->token_pos = 0;
170 buffer->token_len = 0;
171 buffer->buffer_pos = 0;
172 buffer->buffer_end = 0;
173 buffer->buffer_size = size;
176 num = buffer_read( &buffer );
178 *buffer_ppt = buffer;
184 size_t buffer_read( file_buffer **buffer_ppt )
186 /* Martin A. Hansen, June 2008 */
188 /* Read in buffer->buffer_size bytes from file and appends to buffer string. */
190 file_buffer *buffer = *buffer_ppt;
196 num = file_read( buffer->fp, &str, buffer->buffer_size );
201 new_end = buffer->buffer_end + str_len;
203 buffer->str = mem_resize( buffer->str, new_end );
205 memcpy( &buffer->str[ buffer->buffer_end ], str, str_len );
207 buffer->str[ new_end ] = '\0';
208 buffer->buffer_end = new_end;
213 buffer->eof = feof( buffer->fp ) ? TRUE : FALSE;
215 *buffer_ppt = buffer;
221 char buffer_getc( file_buffer *buffer )
223 /* Martin A. Hansen, June 2008 */
225 /* Get the next char from a file buffer, which is resized if necessary, until EOF.*/
229 if ( buffer->buffer_pos == buffer->buffer_end )
237 buffer->token_pos = buffer->buffer_pos;
238 buffer_new_size( buffer, buffer->buffer_pos ); // MOVE THIS TO buffer_resize !!!!! ??????
240 if ( ( buffer_resize( buffer ) == FALSE ) ) {
246 return buffer->str[ buffer->buffer_pos++ ];
251 void buffer_ungetc( file_buffer *buffer )
253 /* Martin A. Hansen, August 2008. */
255 /* Rewinds the file buffer one char, */
256 /* i.e. put one char back on the buffer. */
258 assert( buffer->buffer_pos > 0 );
260 buffer->buffer_pos--;
264 char *buffer_gets( file_buffer *buffer )
266 /* Martin A. Hansen, June 2008 */
268 /* Get the next line that is terminated by \n or EOF from a file buffer. */
272 size_t line_size = 0;
276 if ( ( pt = memchr( &buffer->str[ buffer->buffer_pos ], '\n', buffer->buffer_end + 1 - buffer->buffer_pos ) ) != NULL )
278 line_size = pt - &buffer->str[ buffer->buffer_pos ] + 1;
280 line = mem_get( line_size + 1 );
282 memcpy( line, &buffer->str[ buffer->buffer_pos ], line_size );
284 line[ line_size ] = '\0';
286 buffer->token_len = line_size;
287 buffer->buffer_pos += line_size;
289 buffer_new_size( buffer, line_size );
297 if ( buffer->buffer_pos < buffer->buffer_end )
299 line_size = buffer->buffer_end - buffer->buffer_pos + 1;
301 line = mem_get( line_size + 1 );
303 memcpy( line, &buffer->str[ buffer->buffer_pos ], line_size );
305 line[ line_size ] = '\0';
307 buffer->token_len = line_size;
308 buffer->buffer_pos += line_size;
319 buffer_resize( buffer );
326 void buffer_ungets( file_buffer *buffer )
328 /* Martin A. Hansen, August 2008 */
330 /* Rewind the file buffer one line, */
331 /* i.e. put one line back on the buffer. */
333 assert( buffer->buffer_pos >= buffer->token_len );
335 buffer->buffer_pos -= buffer->token_len;
339 void buffer_new_size( file_buffer *buffer, long len )
341 /* Martin A. Hansen, June 2008 */
343 /* Doubles buffer size until it is larger than len. */
345 while ( buffer->buffer_size <= len )
347 buffer->buffer_size <<= 1;
349 if ( buffer->buffer_size <= 0 )
351 fprintf( stderr, "ERROR: buffer_new_size failed.\n" );
358 bool buffer_resize( file_buffer *buffer )
360 /* Martin A. Hansen, June 2008 */
362 /* Resize file buffer. */
366 if ( buffer->token_pos != 0 ) {
367 buffer_move( buffer, buffer->buffer_pos, buffer->token_pos );
370 num = buffer_read( &buffer );
380 size_t buffer_move( file_buffer *buffer, size_t size, size_t num )
382 /* Martin A. Hansen, August 2008 */
384 /* Moves file buffer of a given size num positions to the left. */
385 /* The size of the resulting string is returned. */
391 assert( num <= size );
393 memmove( buffer->str, &buffer->str[ num ], size );
397 buffer->buffer_end = len;
398 buffer->buffer_pos = 0;
399 buffer->token_pos = 0;
405 void buffer_destroy( file_buffer **buffer_ppt )
407 /* Martin A. Hansen, June 2008 */
409 /* Deallocates memory and close stream used by file buffer. */
411 file_buffer *buffer = *buffer_ppt;
413 assert( buffer != NULL );
415 close_stream( buffer->fp );
417 mem_free( &buffer->str );
424 void buffer_print( file_buffer *buffer )
426 /* Martin A. Hansen, June 2008 */
428 /* Debug function that prints the content of a file_buffer. */
430 printf( "\nbuffer: {\n" );
431 printf( " token_pos : %zu\n", buffer->token_pos );
432 printf( " token_len : %zu\n", buffer->token_len );
433 printf( " buffer_pos : %zu\n", buffer->buffer_pos );
434 printf( " buffer_end : %zu\n", buffer->buffer_end );
435 printf( " buffer_size : %ld\n", buffer->buffer_size );
436 printf( " str : ->%s<-\n", buffer->str );
437 printf( " eof : %d\n", buffer->eof );
439 if ( buffer->str != NULL ) {
440 printf( " _str_len_ : %zu\n", strlen( buffer->str ) );
447 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/