1 /* Martin Asser Hansen (mail@maasha.dk) Copyright (C) 2008 - All right reserved */
8 FILE *read_open( char *file )
10 /* Martin A. Hansen, November 2005 */
14 /* Given a file name, read-opens the file, */
15 /* and returns a file pointer. */
19 if ( ( fp = fopen( file, "r" ) ) == NULL )
21 fprintf( stderr, "ERROR: Could not read-open file '%s': %s\n", file, strerror( errno ) );
29 FILE *write_open( char *file )
31 /* Martin A. Hansen, November 2005 */
35 /* Given a file name, write-opens the file, */
36 /* and returns a file pointer. */
40 if ( ( fp = fopen( file, "w" ) ) == NULL )
42 fprintf( stderr, "ERROR: Could not write-open file '%s': %s\n", file, strerror( errno ) );
50 FILE *append_open( char *file )
52 /* Martin A. Hansen, November 2005 */
56 /* Given a file name, append-opens the file, */
57 /* and returns a file pointer. */
61 if ( ( fp = fopen( file, "a" ) ) == NULL )
63 fprintf( stderr, "ERROR: Could not append-open file '%s': %s\n", file, strerror( errno ) );
71 void close_stream( FILE *fp )
73 /* Martin A. Hansen, May 2008 */
77 /* Closes a stream or file associated with a given file pointer. */
79 if ( ( fclose( fp ) ) != 0 )
81 fprintf( stderr, "ERROR: Could not close stream: %s\n", strerror( errno ) );
87 size_t file_read( FILE *fp, char **string_ppt, size_t len )
89 /* Martin A. Hansen, June 2008 */
91 /* Read in len number of bytes from the current position of a */
92 /* file pointer into a string that is allocated and null terminated. */
93 /* The number of read chars is returned. */
95 char *string = *string_ppt;
100 string = mem_get( len + 1 );
102 num = fread( string, 1, len, fp );
104 if ( ferror( fp ) != 0 )
106 fprintf( stderr, "ERROR: file_read failed\n" );
110 string[ num ] = '\0';
112 *string_ppt = string;
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 size_t buffer_new( char *file, file_buffer **buffer_ppt, size_t size )
156 /* Martin A. Hansen, June 2008 */
158 /* Opens a file for reading and loads a new buffer.*/
159 /* The number of read chars is returned. */
161 file_buffer *buffer = *buffer_ppt;
165 buffer = mem_get( sizeof( file_buffer ) );
167 fp = read_open( file );
171 buffer->token_pos = 0;
172 buffer->token_len = 0;
173 buffer->buffer_pos = 0;
174 buffer->buffer_end = 0;
175 buffer->buffer_size = size;
178 num = buffer_read( &buffer );
180 *buffer_ppt = buffer;
186 size_t buffer_read( file_buffer **buffer_ppt )
188 /* Martin A. Hansen, June 2008 */
190 /* Read in buffer->buffer_size bytes from file and appends to buffer string. */
192 file_buffer *buffer = *buffer_ppt;
198 num = file_read( buffer->fp, &str, buffer->buffer_size );
203 new_end = buffer->buffer_end + str_len;
205 buffer->str = mem_resize( buffer->str, new_end );
207 memcpy( &buffer->str[ buffer->buffer_end ], str, str_len );
209 buffer->str[ new_end ] = '\0';
210 buffer->buffer_end = new_end;
215 buffer->eof = feof( buffer->fp ) ? TRUE : FALSE;
217 *buffer_ppt = buffer;
223 char buffer_getc( file_buffer *buffer )
225 /* Martin A. Hansen, June 2008 */
227 /* Get the next char from a file buffer, which is resized if necessary, until EOF.*/
231 if ( buffer->buffer_pos == buffer->buffer_end )
239 buffer->token_pos = buffer->buffer_pos;
240 buffer_new_size( buffer, buffer->buffer_pos ); // MOVE THIS TO buffer_resize !!!!! ??????
242 if ( ( buffer_resize( buffer ) == FALSE ) ) {
248 return buffer->str[ buffer->buffer_pos++ ];
253 void buffer_ungetc( file_buffer *buffer )
255 /* Martin A. Hansen, August 2008. */
257 /* Rewinds the file buffer one char, */
258 /* i.e. put one char back on the buffer. */
260 assert( buffer->buffer_pos > 0 );
262 buffer->buffer_pos--;
266 char *buffer_gets( file_buffer *buffer )
268 /* Martin A. Hansen, June 2008 */
270 /* Get the next line that is terminated by \n or EOF from a file buffer. */
274 size_t line_size = 0;
278 if ( ( pt = memchr( &buffer->str[ buffer->buffer_pos ], '\n', buffer->buffer_end + 1 - buffer->buffer_pos ) ) != NULL )
280 line_size = pt - &buffer->str[ buffer->buffer_pos ] + 1;
282 line = mem_get( line_size + 1 );
284 memcpy( line, &buffer->str[ buffer->buffer_pos ], line_size );
286 line[ line_size ] = '\0';
288 buffer->token_len = line_size;
289 buffer->buffer_pos += line_size;
291 buffer_new_size( buffer, line_size );
299 if ( buffer->buffer_pos < buffer->buffer_end )
301 line_size = buffer->buffer_end - buffer->buffer_pos + 1;
303 line = mem_get( line_size + 1 );
305 memcpy( line, &buffer->str[ buffer->buffer_pos ], line_size );
307 line[ line_size ] = '\0';
309 buffer->token_len = line_size;
310 buffer->buffer_pos += line_size;
321 buffer_resize( buffer );
328 void buffer_ungets( file_buffer *buffer )
330 /* Martin A. Hansen, August 2008 */
332 /* Rewind the file buffer one line, */
333 /* i.e. put one line back on the buffer. */
335 assert( buffer->buffer_pos >= buffer->token_len );
337 buffer->buffer_pos -= buffer->token_len;
341 void buffer_new_size( file_buffer *buffer, long len )
343 /* Martin A. Hansen, June 2008 */
345 /* Doubles buffer size until it is larger than len. */
347 while ( buffer->buffer_size <= len )
349 buffer->buffer_size <<= 1;
351 if ( buffer->buffer_size <= 0 )
353 fprintf( stderr, "ERROR: buffer_new_size failed.\n" );
360 bool buffer_resize( file_buffer *buffer )
362 /* Martin A. Hansen, June 2008 */
364 /* Resize file buffer. */
368 if ( buffer->token_pos != 0 ) {
369 buffer_move( buffer, buffer->buffer_pos, buffer->token_pos );
372 num = buffer_read( &buffer );
382 size_t buffer_move( file_buffer *buffer, size_t size, size_t num )
384 /* Martin A. Hansen, August 2008 */
386 /* Moves file buffer of a given size num positions to the left. */
387 /* The size of the resulting string is returned. */
393 assert( num <= size );
395 memmove( buffer->str, &buffer->str[ num ], size );
399 buffer->buffer_end = len;
400 buffer->buffer_pos = 0;
401 buffer->token_pos = 0;
407 void buffer_destroy( file_buffer **buffer_ppt )
409 /* Martin A. Hansen, June 2008 */
411 /* Deallocates memory and close stream used by file buffer. */
413 file_buffer *buffer = *buffer_ppt;
415 assert( buffer != NULL );
417 close_stream( buffer->fp );
419 mem_free( &buffer->str );
426 void buffer_print( file_buffer *buffer )
428 /* Martin A. Hansen, June 2008 */
430 /* Debug function that prints the content of a file_buffer. */
432 printf( "\nbuffer: {\n" );
433 printf( " token_pos : %zu\n", buffer->token_pos );
434 printf( " token_len : %zu\n", buffer->token_len );
435 printf( " buffer_pos : %zu\n", buffer->buffer_pos );
436 printf( " buffer_end : %zu\n", buffer->buffer_end );
437 printf( " buffer_size : %ld\n", buffer->buffer_size );
438 printf( " str : ->%s<-\n", buffer->str );
439 printf( " eof : %d\n", buffer->eof );
441 if ( buffer->str != NULL ) {
442 printf( " _str_len_ : %zu\n", strlen( buffer->str ) );
449 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/