@@ -96,6 +96,96 @@ Loggable::close ( void ) | |||||
return true; | 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 | /** sigh. parse a string of ":name value :name value" pairs into an | ||||
* array of strings, one per pair */ | * array of strings, one per pair */ | ||||
// FIXME: doesn't handle the case of :name ":foo bar", nested quotes | // FIXME: doesn't handle the case of :name ":foo bar", nested quotes | ||||
@@ -146,6 +236,8 @@ parse_alist( const char *s ) | |||||
/* remove quotes */ | /* remove quotes */ | ||||
char *v = pair + strlen( pair ) + 1; | char *v = pair + strlen( pair ) + 1; | ||||
unescape( v ); | |||||
if ( *v == '"' ) | if ( *v == '"' ) | ||||
{ | { | ||||
// v++; | // v++; | ||||
@@ -103,6 +103,7 @@ private: | |||||
int _nest; | int _nest; | ||||
void log_print( char **o, char **n ) const; | void log_print( char **o, char **n ) const; | ||||
static void log ( const char *fmt, ... ); | static void log ( const char *fmt, ... ); | ||||
@@ -120,6 +121,8 @@ private: | |||||
public: | public: | ||||
static const char *escape ( const char *s ); | |||||
int id ( void ) const { return _id; } | int id ( void ) const { return _id; } | ||||
static bool open ( const char *filename ); | static bool open ( const char *filename ); | ||||
@@ -369,7 +372,7 @@ public: | |||||
ADD( int, "%d", v ); | ADD( int, "%d", v ); | ||||
ADD( nframes_t, "%lu", (unsigned long)v ); | ADD( nframes_t, "%lu", (unsigned long)v ); | ||||
ADD( unsigned long, "%lu", 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( Loggable * , "0x%X", v ? v->id() : 0 ); | ||||
ADD( float, "%f", v ); | ADD( float, "%f", v ); | ||||
ADD( double, "%f", v ); | ADD( double, "%f", v ); | ||||