cpPlugins::Interface::
Interface( )
{
+ this->UpdatePaths( );
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
void cpPlugins::Interface::
-GuessAccesiblePlugins( )
+UpdatePaths( )
{
// Load environment configuration
- char* path = std::getenv( "cpPlugins_PATHS" );
- if( path != NULL )
- {
- std::vector< std::string > tokens;
- cpPlugins::TokenizeString( tokens, path, "#" );
- for( auto tIt = tokens.begin( ); tIt != tokens.end( ); ++tIt )
- try { this->LoadPluginDir( *tIt ); } catch( ... ) { }
-
- } // fi
+ this->m_Paths.clear( );
+ char* p = std::getenv( "cpPlugins_PATHS" );
+ if( p != NULL )
+ cpPlugins::TokenizeString( this->m_Paths, p, cpPlugins_SEPARATOR );
+ this->m_Paths.push_back( "." );
+}
- // Load local path
- auto lpath = cpPlugins::CanonicalPath( "." );
- try { this->LoadPluginDir( lpath ); } catch( ... ) { }
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::
+GuessAccesiblePlugins( )
+{
+ for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i )
+ try { this->LoadPluginDir( *i ); } catch( ... ) { }
}
// -------------------------------------------------------------------------
-bool cpPlugins::Interface::
-LoadConfiguration( const std::string& filename )
+void cpPlugins::Interface::
+LoadPlugin( const std::string& name )
{
- std::ifstream in( filename.c_str( ) );
- if( !in )
- return( false );
+ std::stringstream str;
+ str << cpPlugins_LIB_PREFIX << name << "." << cpPlugins_LIB_EXT;
+ std::string base_name = str.str( );
+ bool found = false;
+ for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i )
+ {
+ std::string filename = *i;
+ if( i->back( ) != '/' )
+ filename += std::string( "/" );
+ filename += base_name;
+ try
+ {
+ this->LoadPluginFile( filename );
+ found = true;
+ }
+ catch( ... )
+ {
+ } // yrt
- this->UnloadAll( );
- std::string line;
- while( std::getline( in, line ) )
- try { this->LoadPluginFile( line ); } catch( ... ) { }
- return( true );
+ } // rof
+ if( !found )
+ throw std::runtime_error(
+ std::string( "cpPlugins::Interface: Plugins library \"" ) +
+ name +
+ std::string( "\" not found." )
+ );
}
// -------------------------------------------------------------------------
-bool cpPlugins::Interface::
-SaveConfiguration( const std::string& filename ) const
+void cpPlugins::Interface::
+LoadPluginDir( const std::string& dirname )
{
- std::ofstream out( filename.c_str( ) );
- if( !out )
- return( false );
- auto dIt = this->m_DynLibraries.begin( );
- for( ; dIt != this->m_DynLibraries.end( ); ++dIt )
- out << dIt->first << std::endl;
- out.close( );
- return( true );
+ DIR* dir;
+ struct dirent* ent;
+ if( ( dir = opendir( dirname.c_str( ) ) ) != NULL )
+ {
+ while( ( ent = readdir( dir ) ) != NULL )
+ {
+ try
+ {
+ this->LoadPluginFile(
+ dirname +
+ std::string( "/" ) +
+ ent->d_name
+ );
+ }
+ catch( ... ) { }
+
+ } // elihw
+ closedir( dir );
+ }
+ else
+ throw std::runtime_error(
+ std::string( "cpPlugins::Interface: Could not load directory " ) +
+ std::string( "\"" ) + dirname + std::string( "\"" )
+ );
}
// -------------------------------------------------------------------------
void cpPlugins::Interface::
LoadPluginFile( const std::string& filename )
{
- // Open library with its canonical path name
- auto canonical_fn = cpPlugins::PathHelper::CanonicalPath( filename );
- if( canonical_fn == "" )
+ // Canonical filename
+ auto canonical = cpPlugins::PathHelper::CanonicalPath( filename );
+ if( canonical == "" )
throw std::runtime_error(
std::string( "cpPlugins::Interface: Library \"" ) +
filename +
std::string( "\" does not exist." )
);
- // Check if it was already loaded
- if(
- this->m_DynLibraries.find( canonical_fn ) != this->m_DynLibraries.end( )
- )
- return;
-
- // Ok, try to load the library
- void* hnd = Self::_DLOpen( canonical_fn );
+ // Try to load the library
+ void* hnd = Self::_DLOpen( canonical );
if( hnd == NULL )
throw std::runtime_error(
std::string( "cpPlugins::Interface: Could not load library \"" ) +
std::string( "\"" )
);
+ // Get plugin name
+ std::string pl_name = Self::_DLGetName( hnd );
+
+ // Check if it was already loaded
+ if( this->m_DynLibraries.find( pl_name ) != this->m_DynLibraries.end( ) )
+ return;
+
// Load filters
TFilters filters = Self::_DLGetFilters( hnd );
if( creator != NULL )
{
this->m_DynFilters[ catIt->first][ *clsIt ] =
- TDynFunc( canonical_fn, creator );
+ TDynFunc( pl_name, creator );
this->m_Filters[ catIt->first ].insert( *clsIt );
save_handler = true;
// Keep dynlib handler, if needed
if( save_handler )
- this->m_DynLibraries[ canonical_fn ] = hnd;
+ this->m_DynLibraries[ pl_name ] = TDynFileInfo( canonical, hnd );
else
Self::_DLClose( hnd );
}
-// -------------------------------------------------------------------------
-unsigned int cpPlugins::Interface::
-LoadPluginDir( const std::string& dirname )
-{
- DIR* dir;
- struct dirent* ent;
- unsigned int count = 0;
- if( ( dir = opendir( dirname.c_str( ) ) ) != NULL )
- {
- while( ( ent = readdir( dir ) ) != NULL )
- {
- try
- {
- this->LoadPluginFile(
- dirname +
- std::string( "/" ) +
- ent->d_name
- );
- count++;
- }
- catch( ... ) { }
-
- } // elihw
- closedir( dir );
- }
- else
- throw std::runtime_error(
- std::string( "cpPlugins::Interface: Could not load directory " ) +
- std::string( "\"" ) + dirname + std::string( "\"" )
- );
- return( count );
-}
-
// -------------------------------------------------------------------------
void cpPlugins::Interface::
UnloadAll( )
d != this->m_DynLibraries.end( );
++d
)
- Self::_DLClose( d->second );
+ Self::_DLClose( d->second.second );
this->m_DynLibraries.clear( );
this->m_DynFilters.clear( );
this->m_Filters.clear( );
return( filter );
}
+// -------------------------------------------------------------------------
+std::string cpPlugins::Interface::
+GetPluginName( const std::string& category, const std::string& name ) const
+{
+ std::string plugin = "";
+ auto catIt = this->m_DynFilters.find( category );
+ if( catIt != this->m_DynFilters.end( ) )
+ {
+ auto clsIt = catIt->second.find( name );
+ if( clsIt != catIt->second.end( ) )
+ plugin = clsIt->second.first;
+
+ } // fi
+ return( plugin );
+}
+
+// -------------------------------------------------------------------------
+std::vector< std::string > cpPlugins::Interface::
+GetPlugins( ) const
+{
+ std::vector< std::string > res;
+ auto i = this->m_DynLibraries.begin( );
+ for( ; i != this->m_DynLibraries.end( ); ++i )
+ res.push_back( i->first );
+ return( res );
+}
+
// -------------------------------------------------------------------------
void* cpPlugins::Interface::
_DLOpen( const std::string& fname )
return( hnd );
}
+// -------------------------------------------------------------------------
+const char* cpPlugins::Interface::
+_DLGetName( void* hnd )
+{
+ // Get descriptors
+ typedef const char* ( *f_t )( );
+ f_t f = NULL;
+#ifdef cpPlugins_SYS_WINDOWS
+ f = ( f_t )( ::GetProcAddress( ( HMODULE )hnd, "cpPlugins_Name" ) );
+#else // cpPlugins_SYS_WINDOWS
+ f = ( f_t )( dlsym( hnd, "cpPlugins_Name" ) );
+#endif // cpPlugins_SYS_WINDOWS
+ if( f == NULL )
+ {
+ Self::_DLClose( hnd );
+ throw std::runtime_error(
+ "cpPlugins::Interface: Library not recognized as a cpPlugins library."
+ );
+
+ } // fi
+ return( f( ) );
+}
+
// -------------------------------------------------------------------------
cpPlugins::Interface::
TFilters cpPlugins::Interface::
{
Self::_DLClose( hnd );
throw std::runtime_error(
- "cpPlugins::Interface: Library not recognized as a cpPlugins library: "
+ "cpPlugins::Interface: Library not recognized as a cpPlugins library."
);
} // fi
typedef std::pair< std::string, TCreator > TDynFunc;
typedef std::map< std::string, TDynFunc > TDynFilter;
typedef std::map< std::string, TDynFilter > TDynFilters;
- typedef std::map< std::string, void* > TDynLibraries;
typedef std::map< std::string, std::set< std::string > > TFilters;
+ typedef std::pair< std::string, void* > TDynFileInfo;
+ typedef std::map< std::string, TDynFileInfo > TDynLibraries;
public:
Interface( );
const TFilters& GetFilters( );
+ void UpdatePaths( );
void GuessAccesiblePlugins( );
-
- bool LoadConfiguration( const std::string& filename );
- bool SaveConfiguration( const std::string& filename ) const;
+ void LoadPlugin( const std::string& name );
+ void LoadPluginDir( const std::string& dirname );
void LoadPluginFile( const std::string& filename );
- unsigned int LoadPluginDir( const std::string& dirname );
void UnloadAll( );
cpPlugins::ProcessObject::Pointer Create(
const std::string& category, const std::string& name
);
+ std::string GetPluginName(
+ const std::string& category, const std::string& name
+ ) const;
+ std::vector< std::string > GetPlugins( ) const;
protected:
static void* _DLOpen( const std::string& fname );
+ static const char* _DLGetName( void* hnd );
static TFilters _DLGetFilters( void* hnd );
static TCreator _DLGetCreator(
void* hnd, const std::string& category, const std::string& name
static void _DLClose( void* hnd );
protected:
+ std::vector< std::string > m_Paths;
TDynLibraries m_DynLibraries;
TDynFilters m_DynFilters;
TFilters m_Filters;