void PluginManager::RegisterPlugin(const wxString& name, CreatePluginProc createProc, FreePluginProc freeProc, PluginSDKVersionProc versionProc) { // sanity checks if (name.IsEmpty() || !createProc || !freeProc || !versionProc) return; // first check to see it's not already loaded if (FindPluginByName(name)) return; // yes, already loaded // read manifest file for plugin PluginInfo info; if (!ReadManifestFile(m_CurrentlyLoadingFilename, name, &info) || info.name.IsEmpty()) { Manager::Get()->GetLogManager()->LogError(_T("Invalid manifest file for: ") + name); return; } // now get the SDK version number (extra check) int major; int minor; int release; versionProc(&major, &minor, &release); if (major != PLUGIN_SDK_VERSION_MAJOR || minor != PLUGIN_SDK_VERSION_MINOR || release != PLUGIN_SDK_VERSION_RELEASE) { // wrong version: in this case, inform the user... wxString fmt; fmt.Printf(_("SDK version mismatch for %s (%d.%d.%d). Expecting %d.%d.%d"), name.c_str(), major, minor, release, PLUGIN_SDK_VERSION_MAJOR, PLUGIN_SDK_VERSION_MINOR, PLUGIN_SDK_VERSION_RELEASE); Manager::Get()->GetLogManager()->LogError(fmt); return; } // all done // add this plugin in the temporary registration vector to be loaded // by LoadPlugin() (which triggered the call to this function). PluginRegistration pr; pr.name = name; pr.createProc = createProc; pr.freeProc = freeProc; pr.versionProc = versionProc; pr.info = info; m_RegisteredPlugins.push_back(pr); }
int PluginManager::ScanForPlugins(const wxString& path) { static const wxString PluginsMask = platform::windows ? _T("*.dll") : (platform::darwin || platform::macosx) ? _T("*.dylib") : _T("*.so"); int count = 0; if (!wxDirExists(path)) return count; wxDir dir(path); if (!dir.IsOpened()) return count; bool batch = Manager::IsBatchBuild(); wxArrayString bbplugins; if (batch) { ConfigManager *bbcfg = Manager::Get()->GetConfigManager(_T("plugins")); bbplugins = bbcfg->ReadArrayString(_T("/batch_build_plugins")); if (!bbplugins.GetCount()) { // defaults if (platform::windows) bbplugins.Add(_T("compiler.dll")); else if (platform::darwin || platform::macosx) bbplugins.Add(_T("libcompiler.dylib")); else bbplugins.Add(_T("libcompiler.so")); } } wxString filename; wxString failed; bool ok = dir.GetFirst(&filename, PluginsMask, wxDIR_FILES); while (ok) { if (batch) { // for batch builds, we will load only those plugins that the // user has set (default only compiler.dll) bool matched = false; for (size_t i = 0; i < bbplugins.GetCount(); ++i) { if (bbplugins[i] == filename) { matched = true; break; } } if (!matched) { ok = dir.GetNext(&filename); continue; } } // load manifest m_pCurrentlyLoadingManifestDoc = nullptr; if (ReadManifestFile(filename)) { if (LoadPlugin(path + wxFILE_SEP_PATH + filename)) ++count; else failed << _T('\n') << filename; } if (m_pCurrentlyLoadingManifestDoc) { delete m_pCurrentlyLoadingManifestDoc; m_pCurrentlyLoadingManifestDoc = nullptr; } ok = dir.GetNext(&filename); } Manager::Get()->GetLogManager()->Log(F(_("Loaded %d plugins"), count)); if (!failed.IsEmpty()) { InfoWindow::Display(_("Warning"), _("One or more plugins were not loaded.\n" "This usually happens when a plugin is built for\n" "a different version of the Code::Blocks SDK.\n" "Check the application log for more info.\n\n" "List of failed plugins:\n") + failed, 15000, 3000); } return count; }
bool RheiaPluginManager::RegisterPlugin(const wxString& name, CreatePluginProcess createProc, FreePluginProcess freeProc ) { // sanity checks if ( name.IsEmpty() || !createProc || !freeProc ) { RheiaLoggerManager::sdLog( wxT("RheiaPluginManager::RegisterPlugin wrong plugin : ") + name + wxT(" ...") , RheiaLogging::error ); return false; } // first check to see it's not already loaded if (FindElement(name)) { RheiaLoggerManager::sdLog( wxT("RheiaPluginManager::RegisterPlugin plugin exists : ") + name + wxT(" ...") , RheiaLogging::error ); return false; } // read manifest file for plugin wxString resName = name; if ( !FileExt::DYNAMIC_LIBRARY_PREFIX.IsEmpty() && !platform::windows && resName.StartsWith(FileExt::DYNAMIC_LIBRARY_PREFIX) ) resName = resName.Remove(0,FileExt::DYNAMIC_LIBRARY_PREFIX.Length()); wxString libName = name; if ( !FileExt::DYNAMIC_LIBRARY_PREFIX.IsEmpty() && !platform::windows && !libName.StartsWith(FileExt::DYNAMIC_LIBRARY_PREFIX) ) libName = FileExt::DYNAMIC_LIBRARY_PREFIX + libName + FileExt::PLUGIN_EXT; RheiaPluginManifest* manifest = ReadManifestFile( resName + wxT("_res") ); if ( manifest == NULL ) { wxMessageBox(wxT("Error reading manifest for ") + name,_("Error")); return false; } // now perform the SDK version number (extra check) RheiaPackageVersion* sdkversion = manifest->GetSDKVersion(); long major = sdkversion->GetMajor(); long minor = sdkversion->GetMinor(); //long build = sdkversion->GetBuild(); long dmajor = AutoVersion::MAJOR; long dminor = AutoVersion::MINOR; if( CompareVersions( dmajor , dminor , major , minor ) < 0 ) //package is made for a newer version than the current one { RheiaLoggerManager::sdLog( wxT("RheiaPluginManager::RegisterPlugin version problem : ") + name + wxT(" ...") , RheiaLogging::error ); delete manifest; return false; } // all done // register this plugin in the map so that the plugin can be attached later RheiaPluginRegistration registration; registration.name = name; registration.createProcess = createProc; registration.freeProcess = freeProc; registration.info = manifest; RegisteredPlugins.push_back(registration); return true; }