# include <dlfcn.h>
#endif // cpPlugins_SYS_WINDOWS
#include <cpPlugins_dirent.h>
+#include <algorithm>
// -------------------------------------------------------------------------
cpPlugins::Interface::
Interface( )
{
+ this->UpdatePaths( );
}
// -------------------------------------------------------------------------
}
// -------------------------------------------------------------------------
-bool cpPlugins::Interface::
-LoadConfiguration( const std::string& filename )
+void cpPlugins::Interface::
+UpdatePaths( )
{
- std::ifstream in( filename.c_str( ) );
- if( !in )
- return( false );
+ // Load environment configuration
+ 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( "." );
+}
- this->UnloadAll( );
- std::string line;
- while( std::getline( in, line ) )
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::
+GuessAccesiblePlugins( )
+{
+ for( auto i = this->m_Paths.begin( ); i != this->m_Paths.end( ); ++i )
+ try { this->LoadPluginDir( *i ); } catch( ... ) { }
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::
+LoadPlugin( const std::string& name )
+{
+ 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( line );
+ this->LoadPluginFile( filename );
+ found = true;
}
catch( ... )
{
- // Do nothing
-
} // yrt
- } // elihw
- 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::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( ent->d_name );
- count++;
- }
- catch( ... )
- {
- // Ignore errors
- } // yrt
- } // 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::string cpPlugins::Interface::
+GetPluginName( const ProcessObject* obj ) const
+{
+ if( obj != NULL )
+ return(
+ this->GetPluginName(
+ obj->GetClassCategory( ),
+ obj->GetClassName( )
+ )
+ );
+ else
+ return( "" );
+}
+
+// -------------------------------------------------------------------------
+std::set< std::string > cpPlugins::Interface::
+GetPlugins( ) const
+{
+ std::set< std::string > res;
+ auto i = this->m_DynLibraries.begin( );
+ for( ; i != this->m_DynLibraries.end( ); ++i )
+ res.insert( 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