From 10252013988cd7f344c11c8ccb97916b0881da37 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Mon, 5 May 2008 13:35:04 -0500 Subject: [PATCH] Escape/unescape newlines in string parameters of journal messages. --- Timeline/Loggable.C | 92 +++++++++++++++++++++++++++++++++++++++++++++ Timeline/Loggable.H | 5 ++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/Timeline/Loggable.C b/Timeline/Loggable.C index e6a64d8..f847445 100644 --- a/Timeline/Loggable.C +++ b/Timeline/Loggable.C @@ -96,6 +96,96 @@ Loggable::close ( void ) return true; } +/* /\** return a new copy of string /s/ with all newlines escaped *\/ */ +/* static char * */ +/* escape ( const char *s ) */ +/* { */ +/* size_t l = strlen( s ) + 20; */ + +/* char *result = (char*)malloc( l ); */ + +/* char *r = result; */ + +/* int ri = 0; */ + +/* int i = strlen( s ); */ + +/* again: */ + +/* for ( ; i-- && ri < l; ++s, ri++ ) */ +/* { */ +/* if ( '\n' == *s ) */ +/* { */ +/* r[ ri++ ] = '\\'; */ +/* r[ ri ] = 'n'; */ +/* } */ +/* else */ +/* r[ ri ] = *s; */ +/* } */ + +/* if ( ri == l ) */ +/* { */ +/* result = (char*) realloc( result, l += 20 ); */ +/* goto again; */ +/* } */ + +/* return result; */ +/* } */ + + +/** return a pointer to a static copy of /s/ with all special characters escaped */ +const char * +Loggable::escape ( const char *s ) +{ + static char r[512]; + + for ( int i = 0; i < sizeof( r ); ++i, ++s ) + { + if ( '\n' == *s ) + { + r[ i++ ] = '\\'; + r[ i ] = 'n'; + } + else if ( '"' == *s ) + { + r[ i++ ] = '\\'; + r[ i ] = '"'; + } + else + r[ i ] = *s; + } + + return r; +} + +/** remove escapes from string /s/ in-place */ +static void +unescape ( char *s ) +{ + char *r = s; + for ( ; *s; s++, r++ ) + { + if ( '\\' == *s ) + { + switch ( *(++s) ) + { + case 'n': + *r = '\n'; + break; + case '"': + *r = '"'; + break; + default: + break; + } + } + else + *r = *s; + } + + *r = '\0'; +} + /** sigh. parse a string of ":name value :name value" pairs into an * array of strings, one per pair */ // FIXME: doesn't handle the case of :name ":foo bar", nested quotes @@ -146,6 +236,8 @@ parse_alist( const char *s ) /* remove quotes */ char *v = pair + strlen( pair ) + 1; + unescape( v ); + if ( *v == '"' ) { // v++; diff --git a/Timeline/Loggable.H b/Timeline/Loggable.H index 0a5cc19..a82de5c 100644 --- a/Timeline/Loggable.H +++ b/Timeline/Loggable.H @@ -103,6 +103,7 @@ private: int _nest; + void log_print( char **o, char **n ) const; static void log ( const char *fmt, ... ); @@ -120,6 +121,8 @@ private: public: + static const char *escape ( const char *s ); + int id ( void ) const { return _id; } static bool open ( const char *filename ); @@ -369,7 +372,7 @@ public: ADD( int, "%d", v ); ADD( nframes_t, "%lu", (unsigned long)v ); ADD( unsigned long, "%lu", v ); - ADD( const char *, "\"%s\"", v ? v : "" ); + ADD( const char *, "\"%s\"", v ? Loggable::escape( v ) : "" ); ADD( Loggable * , "0x%X", v ? v->id() : 0 ); ADD( float, "%f", v ); ADD( double, "%f", v );