| @@ -24,6 +24,7 @@ | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <stdarg.h> | |||
| #include <string.h> | |||
| 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; | |||
| } | |||