X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FConfig%2FConfig_ModuleReader.cpp;h=2dfd4c135395f8d83c0d82860dae44179e7a9a73;hb=f3f60a3cb69f2534a5837cd249782395e5edb183;hp=83b16f27d5afe166f58d15d66e602cb4a6b8a494;hpb=f4f01be0d0f2642aaca4844b34c98a062e2afbb9;p=modules%2Fshaper.git diff --git a/src/Config/Config_ModuleReader.cpp b/src/Config/Config_ModuleReader.cpp index 83b16f27d..2dfd4c135 100644 --- a/src/Config/Config_ModuleReader.cpp +++ b/src/Config/Config_ModuleReader.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + /* * Config_ModuleReader.cpp * @@ -19,14 +21,17 @@ //Necessary for cerr #include +#include #ifdef WIN32 #include +#pragma warning(disable : 4996) // for getenv #else #include #endif std::map Config_ModuleReader::myPluginTypes; +std::set Config_ModuleReader::myDependencyModules; Config_ModuleReader::Config_ModuleReader(const char* theEventGenerated) : Config_XMLReader(PLUGIN_FILE), @@ -43,7 +48,7 @@ const std::map& Config_ModuleReader::featuresInFiles() return myFeaturesInFiles; } -/* +/*! * Get module name from plugins.xml * (property "module") */ @@ -53,12 +58,11 @@ std::string Config_ModuleReader::getModuleName() return getProperty(aRoot, PLUGINS_MODULE); } -/* - * - */ void Config_ModuleReader::processNode(xmlNodePtr theNode) { if (isNode(theNode, NODE_PLUGIN, NULL)) { + if (!hasRequiredModules(theNode)) + return; std::string aPluginConf = getProperty(theNode, PLUGIN_CONFIG); std::string aPluginLibrary = getProperty(theNode, PLUGIN_LIBRARY); std::string aPluginScript = getProperty(theNode, PLUGIN_SCRIPT); @@ -77,6 +81,18 @@ bool Config_ModuleReader::processChildren(xmlNodePtr theNode) return isNode(theNode, NODE_PLUGINS, NULL); } +bool Config_ModuleReader::hasRequiredModules(xmlNodePtr theNode) const +{ + std::string aRequiredModule = normalize(getProperty(theNode, PLUGIN_DEPENDENCY)); + if(aRequiredModule.empty()) + return true; + std::set::iterator it = myDependencyModules.begin(); + for ( ; it != myDependencyModules.end(); it++ ) { + if (*it == aRequiredModule) return true; + } + return false; +} + std::list Config_ModuleReader::importPlugin(const std::string& thePluginLibrary, const std::string& thePluginXmlConf) { @@ -96,69 +112,106 @@ std::string Config_ModuleReader::addPlugin(const std::string& aPluginLibrary, const std::string& aPluginScript, const std::string& aPluginConf) { - PluginType aType = PluginType::Binary; + PluginType aType = Config_ModuleReader::Binary; std::string aPluginName; if (!aPluginLibrary.empty()) { aPluginName = aPluginLibrary; if (aPluginConf.empty()) { - aType = PluginType::Intrenal; + aType = Config_ModuleReader::Intrenal; } } else if (!aPluginScript.empty()) { aPluginName = aPluginScript; - aType = PluginType::Python; + aType = Config_ModuleReader::Python; } if(!aPluginName.empty()) { myPluginTypes[aPluginName] = aType; - } + addDependencyModule(aPluginName); return aPluginName; } -void Config_ModuleReader::loadPlugin(const std::string thePluginName) +void Config_ModuleReader::loadPlugin(const std::string& thePluginName) { - PluginType aType = PluginType::Binary; + PluginType aType = Config_ModuleReader::Binary; if(myPluginTypes.find(thePluginName) != myPluginTypes.end()) { aType = myPluginTypes.at(thePluginName); } switch (aType) { - case PluginType::Python: + case Config_ModuleReader::Python: loadScript(thePluginName); break; - case PluginType::Binary: - case PluginType::Intrenal: + case Config_ModuleReader::Binary: + case Config_ModuleReader::Intrenal: default: loadLibrary(thePluginName); break; } } -void Config_ModuleReader::loadScript(const std::string theFileName) +void Config_ModuleReader::loadScript(const std::string& theFileName) { - std::string aPythonFile = theFileName + ".py"; /* aquire python thread */ PyGILState_STATE gstate = PyGILState_Ensure(); - PyObject* module = PyImport_ImportModule(aPythonFile.c_str()); + + PyObject* module = PyImport_ImportModule(theFileName.c_str()); + if (!module) { + std::string anErrorMsg = "An error occured while importing " + theFileName; + //Get detailed error message: + if (PyErr_Occurred()) { + PyObject *pstr, *ptype, *pvalue, *ptraceback; + PyErr_Fetch(&ptype, &pvalue, &ptraceback); + PyErr_NormalizeException(&ptype, &pvalue, &ptraceback); + pstr = PyObject_Str(pvalue); + std::string aPyError = std::string(PyString_AsString(pstr)); + if (!aPyError.empty()) { + anErrorMsg += ":\n" + aPyError; + } + Py_XDECREF(pstr); + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + } + Events_Error::send(anErrorMsg); + } + /* release python thread */ PyGILState_Release(gstate); } -void Config_ModuleReader::loadLibrary(const std::string theLibName) +void Config_ModuleReader::loadLibrary(const std::string& theLibName) { std::string aFileName = library(theLibName); if (aFileName.empty()) return; -#ifdef WIN32 + #ifdef WIN32 HINSTANCE aModLib = ::LoadLibrary(aFileName.c_str()); -#else + #else void* aModLib = dlopen( aFileName.c_str(), RTLD_LAZY | RTLD_GLOBAL ); -#endif + #endif if(!aModLib && theLibName != "DFBrowser") { // don't show error for internal debugging tool std::string anErrorMsg = "Failed to load " + aFileName; - #ifndef WIN32 + #ifdef WIN32 + DWORD dwLastError = ::GetLastError(); + LPSTR messageBuffer = NULL; + size_t size = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dwLastError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&messageBuffer, 0, NULL); + anErrorMsg += ": " + std::string(messageBuffer, size); + #else anErrorMsg += ": " + std::string(dlerror()); #endif + std::cerr << anErrorMsg << std::endl; Events_Error::send(anErrorMsg); } } +void Config_ModuleReader::addDependencyModule(const std::string& theModuleName) +{ + myDependencyModules.insert(normalize(theModuleName)); +} +