]> Creatis software - cpPlugins.git/blobdiff - lib/cpPlugins/Interface.cxx
Windows compilation is broken.
[cpPlugins.git] / lib / cpPlugins / Interface.cxx
index 58e468d29e114cc2b802a22fab6cb1b8f90d07f2..8b5e106e5791c29d697ab123f414c56359248818 100644 (file)
@@ -6,11 +6,13 @@
 #  include <dlfcn.h>
 #endif // cpPlugins_SYS_WINDOWS
 #include <cpPlugins_dirent.h>
+#include <algorithm>
 
 // -------------------------------------------------------------------------
 cpPlugins::Interface::
 Interface( )
 {
+  this->UpdatePaths( );
 }
 
 // -------------------------------------------------------------------------
@@ -29,64 +31,102 @@ GetFilters( )
 }
 
 // -------------------------------------------------------------------------
-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 \"" ) +
@@ -94,6 +134,13 @@ LoadPluginFile( const std::string& filename )
       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 );
 
@@ -122,7 +169,7 @@ LoadPluginFile( const std::string& filename )
         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;
 
@@ -136,42 +183,11 @@ LoadPluginFile( const std::string& filename )
 
   // 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( )
@@ -181,7 +197,7 @@ 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( );
@@ -206,6 +222,48 @@ Create( const std::string& category, const std::string& name )
   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 )
@@ -220,6 +278,29 @@ _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::
@@ -237,7 +318,7 @@ _DLGetFilters( void* hnd )
   {
     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