From 359c2bd72f2b701048d418d2fc85eb32d12b97c1 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Sun, 24 Feb 2008 22:14:19 -0600 Subject: [PATCH] Actually get (single) undo working. --- Loggable.C | 145 ++++++++++++++++++++++++++++++++++++++++++++--------- Loggable.H | 14 ++++-- Region.H | 4 +- main.C | 9 +++- 4 files changed, 142 insertions(+), 30 deletions(-) diff --git a/Loggable.C b/Loggable.C index 59ead6c..87d7af8 100644 --- a/Loggable.C +++ b/Loggable.C @@ -21,6 +21,7 @@ #include "Loggable.H" #undef _LOGABLE_C +#include #include #include @@ -43,22 +44,121 @@ Loggable::open ( const char *filename ) return true; } -/* void */ -/* Loggable::log ( const char *module, const char *action, const char *fmt, ... ) */ -/* { */ -/* va_list args; */ +/** sigh. parse a string of ":name value :name value" pairs into an array of strings, one per pair */ +static +char ** +parse_alist( const char *s ) +{ -/* fprintf( _fp, "%-15s %-8s %p ", module, action, _id ); */ +// FIXME: bogus over allocation... -/* if ( fmt ) */ -/* { */ -/* va_start( args, fmt ); */ -/* vfprintf( _fp, fmt, args ); */ -/* va_end( args ); */ -/* } */ + int tl = strlen( s ); + char **r = (char**)malloc( sizeof( char* ) * tl ); + + const char *e = s + tl; + + const char *c = NULL; + int i = 0; + for ( ; ; s++ ) + { + +/* if ( *s == '\n' ) */ +/* break; */ + +// if ( *s == ':' || s == e ) + if ( *s == ':' || *s == '\0' ) + { + if ( c ) + { + int l = s - c; + + char *pair = (char*)malloc( l + 1 ); + + strncpy( pair, c, l ); + + pair[ l ] = '\0'; + + r[ i++ ] = pair; + } + + c = s; + + if ( *s == '\0' ) + break; + } + } + + r[ i ] = NULL; + + return r; +} + + +void +Loggable::undo ( void ) +{ + char *buf = new char[ BUFSIZ ]; + +// fflush( _fp ); + + fseek( _fp, 0 - BUFSIZ, SEEK_END ); + +// fseek( _fp, 0, SEEK_SET ); -/* fprintf( _fp, "\n" ); */ -/* } */ + size_t len = fread( buf, 1, BUFSIZ, _fp ); + + char *s = buf + len - 1; + +// FIXME: handle blocks + for ( --s; *s && s > buf; --s ) + if ( *s == '\n' ) + { + s++; + break; + } + + buf[ len ] = NULL; + + printf( "undoing \"%s\"\n", s ); + + int id; + sscanf( s, "%*s %X ", &id ); + Loggable *l = find( id ); + assert( l ); + + char command[40]; + char *arguments; + + sscanf( s, "%*s %*X %s %*[^\n<] << %a[^\n]", command, &arguments ); + + if ( ! strcmp( command, "set" ) ) + { + + printf( "got set command.\n" ); + + char **sa = parse_alist( arguments ); + + l->set( sa ); + + } + + delete buf; + +} + + +void +Loggable::log ( const char *fmt, ... ) +{ + va_list args; + + if ( fmt ) + { + va_start( args, fmt ); + vfprintf( _fp, fmt, args ); + va_end( args ); + } +} static @@ -72,22 +172,21 @@ void free_sa ( char **sa ) } -static void -log_print( char **o, char **n ) +Loggable::log_print( char **o, char **n ) { if ( n ) for ( ; *n; n++ ) - printf( "%s%s", *n, *(n + 1) ? " " : "" ); + log( "%s%s", *n, *(n + 1) ? " " : "" ); if ( o && *o ) { - if ( n ) printf( " << " ); + if ( n ) log( " << " ); for ( ; *o; o++ ) - printf( "%s%s", *o, *(o + 1) ? " " : "" ); + log( "%s%s", *o, *(o + 1) ? " " : "" ); } - printf( "\n" ); + log( "\n" ); } /** compare elements of dumps s1 and s2, removing those elements @@ -152,7 +251,7 @@ Loggable::log_end ( void ) if ( log_diff( _old_state, _new_state ) ) { indent(); - printf( "%s 0x%X set ", class_name(), _id ); + log( "%s 0x%X set ", class_name(), _id ); log_print( _old_state, _new_state ); } @@ -178,7 +277,7 @@ void Loggable::log_create ( void ) { indent(); - printf( "%s 0x%X new ", class_name(), _id ); + log( "%s 0x%X new ", class_name(), _id ); char **sa = log_dump(); @@ -188,14 +287,14 @@ Loggable::log_create ( void ) free_sa( sa ); } else - printf( "\n" ); + log( "\n" ); } void Loggable::log_destroy ( void ) { indent(); - printf( "%s 0x%X destroy ", class_name(), _id ); + log( "%s 0x%X destroy ", class_name(), _id ); char **sa = log_dump(); diff --git a/Loggable.H b/Loggable.H index 68d302e..aea251d 100644 --- a/Loggable.H +++ b/Loggable.H @@ -47,25 +47,30 @@ private: int _nest; + void log_print( char **o, char **n ); + static void log ( const char *fmt, ... ); + static void indent ( void ) { int n = Loggable::_level; while ( n-- ) - printf( "\t" ); + log( "\t" ); } + public: static bool open ( const char *filename ); + static void undo ( void ); static void block_start ( void ) { indent(); - printf( "{\n" ); + log( "{\n" ); ++Loggable::_level; } static @@ -74,7 +79,7 @@ public: { assert( --Loggable::_level >= 0 ); indent(); - printf( "}\n" ); + log( "}\n" ); } static @@ -84,7 +89,7 @@ public: if ( id > _log_id ) return NULL; - return _loggables[ id ]; + return _loggables[ id - 1 ]; } Loggable ( ) @@ -108,7 +113,6 @@ public: protected: -// void log ( const char *module, const char *action, const char *fmt, ... ); void log_start ( void ); void log_end ( void ); void log_create ( void ); diff --git a/Region.H b/Region.H index 21a12cd..25686c4 100644 --- a/Region.H +++ b/Region.H @@ -88,7 +88,7 @@ protected: strtok( s, " " ); - char *v = s + strlen( s ); + char *v = s + strlen( s ) + 1; if ( ! strcmp( s, ":x" ) ) _offset = atol( v ); @@ -122,6 +122,8 @@ protected: } free( sa ); + + _track->redraw(); } public: diff --git a/main.C b/main.C index 1fb3a14..717475d 100644 --- a/main.C +++ b/main.C @@ -26,7 +26,7 @@ #include #include #include - +#include #include "Scalebar.H" @@ -104,6 +104,10 @@ cb_scroll ( Fl_Widget *w, void *v ) } +void cb_undo ( Fl_Widget *w, void *v ) +{ + Loggable::undo(); +} int main ( int argc, char **argv ) @@ -129,6 +133,9 @@ main ( int argc, char **argv ) timeline->scrollbar->type( 1 ); timeline->scrollbar->callback( cb_scroll, 0 ); + Fl_Button *o = new Fl_Button( 0, 0, 50, 50, "undo" ); + o->callback( cb_undo, 0 ); + main_window->end(); main_window->show();