#else // cpPlugins_SYS_WINDOWS
# include <dlfcn.h>
#endif // cpPlugins_SYS_WINDOWS
+#include <cpPlugins_dirent.h>
+#include <algorithm>
// -------------------------------------------------------------------------
cpPlugins::Interface::
return( this->m_Filters );
}
+// -------------------------------------------------------------------------
+void cpPlugins::Interface::
+GuessAccesiblePlugins( )
+{
+ // 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
+
+ // Load local path
+ auto lpath = cpPlugins::CanonicalPath( "." );
+ try { this->LoadPluginDir( lpath ); } catch( ... ) { }
+}
+
// -------------------------------------------------------------------------
bool cpPlugins::Interface::
LoadConfiguration( const std::string& filename )
this->UnloadAll( );
std::string line;
while( std::getline( in, line ) )
- {
- try
- {
- this->LoadPluginFile( line );
- }
- catch( ... )
- {
- // Do nothing
-
- } // yrt
-
- } // elihw
+ try { this->LoadPluginFile( line ); } catch( ... ) { }
return( true );
}
for( ; dIt != this->m_DynLibraries.end( ); ++dIt )
out << dIt->first << std::endl;
out.close( );
+ return( true );
}
// -------------------------------------------------------------------------
{
// Open library with its canonical path name
auto canonical_fn = cpPlugins::PathHelper::CanonicalPath( filename );
+ if( canonical_fn == "" )
+ 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 );
if( hnd == NULL )
throw std::runtime_error(
std::string( "cpPlugins::Interface: Could not load library \"" ) +
- canonical_fn +
+ filename +
std::string( "\"" )
);
if( new_filter )
{
// Update filters container
- TCreator creator = Self::_DLGetCreator( hnd, catIt->first, *clsIt );
+ auto creator = Self::_DLGetCreator( hnd, catIt->first, *clsIt );
if( creator != NULL )
{
this->m_DynFilters[ catIt->first][ *clsIt ] =
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( )
cpPlugins::ProcessObject::Pointer cpPlugins::Interface::
Create( const std::string& category, const std::string& name )
{
- cpPlugins::ProcessObject::Pointer filter = NULL;
+ typedef cpPlugins::ProcessObject::Pointer _TPointer;
+ _TPointer filter = NULL;
auto catIt = this->m_DynFilters.find( category );
if( catIt != this->m_DynFilters.end( ) )
{
auto clsIt = catIt->second.find( name );
if( clsIt != catIt->second.end( ) )
- filter = clsIt->second.second( );
+ filter =
+ ( reinterpret_cast< _TPointer* >( clsIt->second.second( ) ) )->
+ GetPointer( );
} // fi
return( filter );
TFilters cpPlugins::Interface::
_DLGetFilters( void* hnd )
{
- typedef const TFilters ( *f_t )( );
-
- TFilters filters;
+ // Get descriptors
+ typedef const char* ( *f_t )( );
+ f_t f = NULL;
#ifdef cpPlugins_SYS_WINDOWS
- auto f = ( f_t )(
- ::GetProcAddress( ( HMODULE )hnd, "cpPlugins_LoadedFilters" )
- );
- std::cout << f << std::endl;
+ f = ( f_t )( ::GetProcAddress( ( HMODULE )hnd, "cpPlugins_LoadedFilters" ) );
#else // cpPlugins_SYS_WINDOWS
- auto f = ( f_t ) dlsym( hnd, "cpPlugins_LoadedFilters" );
- const char* err = dlerror( );
- if( err != NULL )
+ f = ( f_t )( dlsym( hnd, "cpPlugins_LoadedFilters" ) );
+#endif // cpPlugins_SYS_WINDOWS
+ if( f == NULL )
{
- dlclose( hnd );
+ Self::_DLClose( hnd );
throw std::runtime_error(
- std::string(
- "cpPlugins::Interface: Library not recognized as a cpPlugins library: "
- ) + std::string( err )
+ "cpPlugins::Interface: Library not recognized as a cpPlugins library: "
);
} // fi
-#endif // cpPlugins_SYS_WINDOWS
- filters = f( );
+ std::string descriptors = f( );
+
+ // Demangle descriptors
+ TFilters filters;
+ std::replace( descriptors.begin( ), descriptors.end( ), ';', ' ' );
+ std::istringstream str( descriptors );
+ while( str )
+ {
+ std::string value, category, name;
+ str >> value;
+ if( value == "" )
+ continue;
+ std::replace( value.begin( ), value.end( ), ':', ' ' );
+ std::istringstream value_str( value );
+ value_str >> category >> name;
+ filters[ category ].insert( name );
+
+ } // elihw
return( filters );
}
TCreator c = NULL;
std::string func_name = category + "_" + name;
#ifdef cpPlugins_SYS_WINDOWS
- // TODO:
+ c = ( TCreator )( ::GetProcAddress( ( HMODULE )hnd, func_name.c_str( ) ) );
#else // cpPlugins_SYS_WINDOWS
- c = ( TCreator )dlsym( hnd, func_name.c_str( ) );
+ c = ( TCreator )( dlsym( hnd, func_name.c_str( ) ) );
+#endif // cpPlugins_SYS_WINDOWS
if( c == NULL )
throw std::runtime_error(
std::string( "cpPlugins::Interface: Class \"" ) +
category + std::string( ":" ) + name +
std::string( "\" does not have a valid creator function." )
);
-#endif // cpPlugins_SYS_WINDOWS
return( c );
}