diff --git a/Loggable.C b/Loggable.C index d8483fd..6f3b44a 100644 --- a/Loggable.C +++ b/Loggable.C @@ -24,6 +24,7 @@ #include #include #include +#include FILE *Loggable::_fp; int Loggable::_log_id = 0; @@ -198,15 +199,21 @@ Loggable::undo ( void ) if ( *(s + 1) == '\t' ) continue; + if ( *(s + 1) == '}' ) + { + *(s + 1) = NULL; + continue; + } + break; } } s++; - strtok( s, "\n" ); buf[ len ] = NULL; + // fsync( fileno( _fp ) ); /* pop the entry off the end */ @@ -219,22 +226,48 @@ Loggable::undo ( void ) return; } - printf( "undoing \"%s\"\n", s ); - - int id; - sscanf( s, "%*s %X ", &id ); - Loggable *l = find( id ); -// assert( l ); + char *b = s; - char classname[40]; - char command[40]; - char *arguments; + s += strlen( s ) - 1; - sscanf( s, "%s %*X %s %*[^\n<] << %a[^\n]", classname, command, &arguments ); + if ( strtok( b, "\n" ) == NULL ) + { + printf( "error, empty undo transaction!\n" ); + abort(); + } + int n = 1; + while ( strtok( NULL, "\n" ) ) + ++n; int ui = _undo_index; + while ( n-- ) + { + while ( s >= b && *(--s) ); + + s++; + + if ( ( ! strcmp( s, "{" ) ) + || ( ! strcmp( s, "}" ) ) ) + continue; + + if ( *s == '\t' ) + s++; + + printf( "undoing \"%s\"\n", s ); + + int id; + sscanf( s, "%*s %X ", &id ); + Loggable *l = find( id ); +// assert( l ); + + char classname[40]; + char command[40]; + char *arguments; + + sscanf( s, "%s %*X %s %*[^\n<] << %a[^\n]", classname, command, &arguments ); + /* if ( ! l ) */ /* { */ @@ -242,49 +275,50 @@ Loggable::undo ( void ) /* abort(); */ /* } */ - - - if ( ! strcmp( command, "destroy" ) ) - { - char **sa = parse_alist( arguments ); - - if ( ! _class_map[ string( classname ) ] ) - printf( "error class %s is unregistered!\n", classname ); - else + if ( ! strcmp( command, "destroy" ) ) { - /* create */ - Loggable *l = _class_map[ string( classname ) ]( sa ); - l->update_id( id ); - l->log_create(); + char **sa = parse_alist( arguments ); + + if ( ! _class_map[ string( classname ) ] ) + printf( "error class %s is unregistered!\n", classname ); + else + { + /* create */ + Loggable *l = _class_map[ string( classname ) ]( sa ); + l->update_id( id ); + l->log_create(); + } } - } - else - if ( ! strcmp( command, "set" ) ) - { + else + if ( ! strcmp( command, "set" ) ) + { - printf( "got set command.\n" ); + printf( "got set command.\n" ); - char **sa = parse_alist( arguments ); + char **sa = parse_alist( arguments ); - l->log_start(); - l->set( sa ); - l->log_end(); + l->log_start(); + l->set( sa ); + l->log_end(); - } - else - if ( ! strcmp( command, "create" ) ) - { - int id = l->id(); - delete l; - _loggables[ id ] = NULL; } - + else + if ( ! strcmp( command, "create" ) ) + { + int id = l->id(); + delete l; + _loggables[ id ] = NULL; + } + + s -= 2; + } // FIXME: bogus... needs to account for multiple events. _undo_index = ui + 1; ++_undo_index; + delete buf; }