diff --git a/nonlib/Loggable.C b/nonlib/Loggable.C index e7d7413..bf50335 100644 --- a/nonlib/Loggable.C +++ b/nonlib/Loggable.C @@ -177,10 +177,13 @@ Loggable::load_unjournaled_state ( void ) } unsigned int id; - char buf[BUFSIZ]; + char *buf; - while ( fscanf( fp, "%X set %[^\n]\n", &id, buf ) == 2 ) + while ( fscanf( fp, "%X set %a[^\n]\n", &id, &buf ) == 2 ) + { _loggables[ id ].unjournaled_state = new Log_Entry( buf ); + free(buf); + } fclose( fp ); @@ -210,8 +213,7 @@ Loggable::replay ( const char *file ) bool Loggable::replay ( FILE *fp ) { - /* FIXME: bogus */ - char buf[BUFSIZ]; + char *buf = NULL; struct stat st; fstat( fileno( fp ), &st ); @@ -222,7 +224,7 @@ Loggable::replay ( FILE *fp ) if ( _progress_callback ) _progress_callback( 0, _progress_callback_arg ); - while ( fscanf( fp, "%[^\n]\n", buf ) == 1 ) + while ( fscanf( fp, "%a[^\n]\n", &buf ) == 1 ) { if ( ! ( ! strcmp( buf, "{" ) || ! strcmp( buf, "}" ) ) ) { @@ -232,6 +234,8 @@ Loggable::replay ( FILE *fp ) do_this( buf, false ); } + free(buf); + current = ftell( fp ); if ( _progress_callback ) @@ -480,8 +484,7 @@ Loggable::do_this ( const char *s, bool reverse ) void Loggable::undo ( void ) { - const int bufsiz = 1024; - char buf[bufsiz]; + char *buf; block_start(); @@ -489,34 +492,49 @@ Loggable::undo ( void ) fseek( _fp, _undo_offset, SEEK_SET ); - backwards_fgets( buf, bufsiz, _fp ); - - if ( ! strcmp( buf, "}\n" ) ) + if ( ( buf = backwards_afgets( _fp ) ) ) { - DMESSAGE( "undoing block" ); - for ( ;; ) + if ( ! strcmp( buf, "}\n" ) ) { - backwards_fgets( buf, bufsiz, _fp ); + free( buf ); + + DMESSAGE( "undoing block" ); + for ( ;; ) + { + if ( ( buf = backwards_afgets( _fp ) ) ) + { + char *s = buf; + if ( *s != '\t' ) + { + DMESSAGE( "done with block", s ); - char *s = buf; - if ( *s != '\t' ) - break; - else - ++s; + break; + } + else + ++s; + + do_this( s, true ); - do_this( s, true ); + free( buf ); + } + } + } + else + { + do_this( buf, true ); + + free( buf ); } } - else - do_this( buf, true ); off_t uo = ftell( _fp ); ASSERT( _undo_offset <= here, "WTF?" ); - + block_end(); _undo_offset = uo; + } /** write a snapshot of the current state of all loggable objects to diff --git a/nonlib/file.C b/nonlib/file.C index f861727..f52a481 100644 --- a/nonlib/file.C +++ b/nonlib/file.C @@ -107,25 +107,46 @@ backwards_fgetc ( FILE *fp ) } char * -backwards_fgets ( char *s, int size, FILE *fp ) +backwards_afgets ( FILE *fp ) { - if ( fseek( fp, -1, SEEK_CUR ) != 0 ) - return NULL; + size_t size = 0; + char *s = NULL; + size_t i = 0; int c; while ( ( c = backwards_fgetc( fp ) ) >= 0 ) - if ( '\n' == c ) + { + if ( i > 0 && '\n' == c ) break; - long here = ftell( fp ); + if ( i >= size ) + { + size += 256; + s = (char*)realloc( s, size ); + } + + s[i++] = c; + + } + + if ( s ) + { + s[i] = 0; + + int len = strlen(s) ; + int c, i, j; + + for (i = 0, j = len - 1; i < j; i++, j--) + { + c = s[i]; + s[i] = s[j]; + s[j] = c; + } + } fseek( fp, 1, SEEK_CUR ); - char *r = fgets( s, size, fp ); - - fseek( fp, here, SEEK_SET ); - - return r; + return s; } diff --git a/nonlib/file.h b/nonlib/file.h index 63aa4dd..a5de6e2 100644 --- a/nonlib/file.h +++ b/nonlib/file.h @@ -27,7 +27,7 @@ int exists ( const char *name ); bool acquire_lock ( int *lockfd, const char *filename ); void release_lock ( int *lockfd, const char *filename ); int backwards_fgetc ( FILE *fp ); -char * backwards_fgets ( char *s, int size, FILE *fp ); +char * backwards_afgets ( FILE *fp ); void touch ( int fd ); void write_line ( const char *dir, const char *name, const char *value ); char * read_line ( const char *dir, const char *name );