#include #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 300) #error You need at least flext version 0.3.0 #endif #include #include #include class expand: public flext_base { FLEXT_HEADER(expand,flext_base) public: expand( int argc, t_atom *argv ); ~expand(); protected: void m_transform( const t_symbol *s, int argc, t_atom *argv ); void m_set( const t_symbol *s, int argc, t_atom *argv ); string subst( const char *p ); private: FLEXT_CALLBACK_A( m_transform ); FLEXT_CALLBACK_A( m_set ); string *a_value; unsigned int a_count; }; FLEXT_NEW_V("expand",expand) expand::expand( int argc, t_atom *argv ): a_value( NULL ), a_count( 0 ) { AddInAnything(); // messages to be transformed AddInAnything(); // substring defaults AddOutAnything(); // transformed message SetupInOut(); FLEXT_ADDMETHOD(0,m_transform); FLEXT_ADDMETHOD(1,m_set); m_set( NULL, argc, argv ); }; expand::~expand() { if ( a_value ) delete[] a_value; }; void expand::m_transform( const t_symbol *s, int argc, t_atom *argv ) { AtomList result( argc ); unsigned int k; string out; const char *p; for ( k = 0; k < argc; ++k ) { switch ( argv[k].a_type ) { case A_SYMBOL: case A_DOLLSYM: p = GetString( argv[k] ); out = subst( p ); SetString( result[k], out.c_str() ); break; default: // post( "unknown Type: %d", argv[k].a_type ); CopyAtom( &(result[k]), &(argv[k]) ); }; }; t_atom t; p = GetString( s ); out = subst( p ); SetString( t, out.c_str() ); ToOutAnything( 0, GetSymbol( t ), argc, result.Atoms() ); }; string expand::subst( const char *p ) { string out; unsigned int i; // post( "\"%s\"", p ); while ( *p != 0 ) { switch( *p ) { case '&': ++p; if ( !isdigit( *p ) ) { out += '&'; break; }; i = atoi( p ); while ( isdigit( *p ) ) ++p; if ( i < a_count ) out+= a_value[i]; break; default: out += *p; ++p; break; }; }; return out; }; void expand::m_set( const t_symbol *s, int argc, t_atom *argv ) { int i, i0; if ( a_value ) delete[] a_value; a_count = s ? argc+1 : argc; if ( !a_count ) return; a_value = new string[ a_count ]; if ( s ) { a_value[0] = GetString( s ); i0 = 1; } else i0 = 0; for ( i = i0; i < a_count; ++i ) { ostrstream ost; switch( argv[i-i0].a_type ) { case A_SYMBOL: a_value[i] = GetString( argv[i-i0] ); break; case A_FLOAT: ost << GetFloat( argv[i-i0] ) << ends; a_value[i] = ost.str(); break; default: a_value[i] = ""; post( "expand: unknown value type" ); break; }; }; }; // eof