]> SALOME platform Git repositories - modules/yacs.git/commitdiff
Salome HOME
Merge remote branch 'origin/V7_4_BR'
authorvsr <vsr@opencascade.com>
Thu, 28 Aug 2014 09:05:41 +0000 (13:05 +0400)
committervsr <vsr@opencascade.com>
Thu, 28 Aug 2014 09:05:41 +0000 (13:05 +0400)
29 files changed:
bin/appliskel/tests/concurrentSession/TestConcurrentSession.py
bin/appliskel/tests/launcher/TestLauncherSessionArgs.py
bin/appliskel/tests/launcher/getLogger.py
bin/launchConfigureParser.py
bin/parseConfigFile.py
bin/runConsole.py
bin/runSession.py
bin/salomeContext.py
bin/salomeContextUtils.py.in
bin/salome_session.py
doc/salome/salome_command.dox
idl/SALOME_Component.idl
idl/SALOME_PyNode.idl
salome_adm/cmake_files/FindCAS.cmake
src/Container/Container_i.cxx
src/Container/Container_init_python.cxx
src/Container/SALOME_ComponentPy.py
src/Container/SALOME_Container_i.hxx
src/Container/SALOME_PyNode.py
src/KERNEL_PY/kernel/deprecation.py
src/KERNEL_PY/kernel/diclookup.py
src/KERNEL_PY/kernel/parametric/study_exchange_vars.py
src/KERNEL_PY/kernel/studyedit.py
src/KERNEL_PY/kernel/syshelper.py
src/KERNEL_PY/salome_ComponentGUI.py
src/LifeCycleCORBA_SWIG/LifeCycleCORBA.py
src/ParallelContainer/SALOME_ParallelContainer_i.cxx
src/ParallelContainer/SALOME_ParallelContainer_i.hxx
src/SALOMEDSImpl/SALOMEDSImpl_Study.cxx

index aab1777af46e7363f2ad8b167508f7f047904848..1bc310ccc3983411eff9dc9fc62eec89415a417b 100644 (file)
@@ -42,7 +42,9 @@ class TestConcurrentLaunch(unittest.TestCase):
   def tearDown(self):
     pass
   #
-  def appli(self, args=[]):
+  def appli(self, args=None):
+    if args is None:
+      args = []
     try:
       self.SALOME.main(self.SALOME_appli_args + args)
     except SystemExit, e:
@@ -50,7 +52,9 @@ class TestConcurrentLaunch(unittest.TestCase):
         logging.error(e)
       pass
   #
-  def session(self, args=[]):
+  def session(self, args=None):
+    if args is None:
+      args = []
     try:
       self.SALOME.main(self.SALOME_shell_args + args)
     except SystemExit, e:
index 20445e9df9a9e2b74cede9ed59863e6946e5485b..f3987f18b4ef8b28ef90c2658b6a9991e1801e4f 100644 (file)
@@ -67,7 +67,9 @@ class TestSessionArgs(unittest.TestCase):
   def tearDown(self):
     self.removeLogFile()
   #
-  def session(self, args=[]):
+  def session(self, args=None):
+    if args is None:
+      args = []
     try:
       self.SALOME.main(self.SALOME_args + args)
     except SystemExit, e:
index 8e952ebf52b42b1829ea24730fb9e6cff34467da..4d45dc3f13b01b97ca90b5a151a1759e81d6539b 100644 (file)
@@ -21,7 +21,9 @@ import os
 import sys
 import logging
 
-def getLogger(args=[]):
+def getLogger(args=None):
+  if args is None:
+    args = []
   outfileOptionPrefix = "outfile="
   outfileArgs = [ str(x) for x in args if str(x).startswith(outfileOptionPrefix) ]
   allFiles = [ x.replace(outfileOptionPrefix, '') for x in outfileArgs ]
index cfb247f619dcbfef936d53549b6061ca2a5d0519..77df1a60d64b7f23e1ca8b8c807676a90db49e6d 100755 (executable)
@@ -483,7 +483,9 @@ def store_boolean (option, opt, value, parser, *args):
         for attribute in args:
             setattr(parser.values, attribute, value)
 
-def CreateOptionParser (theAdditionalOptions=[]):
+def CreateOptionParser (theAdditionalOptions=None):
+    if theAdditionalOptions is None:
+        theAdditionalOptions = []
     # GUI/Terminal. Default: GUI
     help_str = "Launch without GUI (in the terminal mode)."
     o_t = optparse.Option("-t",
@@ -871,7 +873,7 @@ Python file arguments, if any, must be comma-separated (without blank characters
 args = {}
 #def get_env():
 #args = []
-def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgname):
+def get_env(theAdditionalOptions=None, appname=salomeappname, cfgname=salomecfgname):
     ###
     # Collect launch configuration files:
     # - The environment variable "<appname>Config" (SalomeAppConfig) which can
@@ -894,6 +896,9 @@ def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgnam
     #   specified in configuration file(s)
     ###
 
+    if theAdditionalOptions is None:
+        theAdditionalOptions = []
+
     global args
     config_var = appname+'Config'
 
@@ -902,15 +907,13 @@ def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgnam
         separator = ";"
 
     # check KERNEL_ROOT_DIR
-    try:
-        kernel_root_dir=os.environ["KERNEL_ROOT_DIR"]
-    except:
+    kernel_root_dir = os.environ.get("KERNEL_ROOT_DIR", None)
+    if kernel_root_dir is None:
         print """
         For each SALOME module, the environment variable <moduleN>_ROOT_DIR must be set.
         KERNEL_ROOT_DIR is mandatory.
         """
         sys.exit(1)
-        pass
 
     ############################
     # parse command line options
@@ -1000,15 +1003,15 @@ def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgnam
     # set default values for options which are NOT set in config files
     for aKey in listKeys:
         if not args.has_key( aKey ):
-            args[aKey]=[]
+            args[aKey] = []
 
     for aKey in boolKeys:
         if not args.has_key( aKey ):
-            args[aKey]=0
+            args[aKey] = 0
 
     if args[file_nam]:
         afile=args[file_nam]
-        args[file_nam]=[afile]
+        args[file_nam] = [afile]
 
     args[appname_nam] = appname
 
index 3054ed1f341eeb2154d3280befda32627afe1970..2f2bbb2ead9cf4998129338d3600b2bcb9c2d6f1 100644 (file)
@@ -163,7 +163,9 @@ class MultiOptSafeConfigParser(ConfigParser.SafeConfigParser):
 # Input: filename, and a list of reserved keywords (environment variables)
 # Output: a list of pairs (variable, value), and a dictionary associating a list of user-defined values to each reserved keywords
 # Note: Does not support duplicate keys in a same section
-def parseConfigFile(filename, reserved = []):
+def parseConfigFile(filename, reserved = None):
+  if reserved is None:
+    reserved = []
   config = MultiOptSafeConfigParser()
   config.optionxform = str # case sensitive
 
@@ -183,10 +185,12 @@ def parseConfigFile(filename, reserved = []):
     raise SalomeContextException(msg)
 #
 
-def __processConfigFile(config, reserved = [], filename="UNKNOWN FILENAME"):
+def __processConfigFile(config, reserved = None, filename="UNKNOWN FILENAME"):
   # :TODO: may detect duplicated variables in the same section (raise a warning)
   #        or even duplicate sections
 
+  if reserved is None:
+    reserved = []
   unsetVariables = []
   outputVariables = []
   # Get raw items for each section, and make some processing for environment variables management
@@ -245,12 +249,14 @@ def _trimColons(var):
 #    - virtually add a section to configuration file
 #    - process shell keywords (if, then...)
 class EnvFileConverter(object):
-  def __init__(self, fp, section_name, reserved = [], outputFile=None):
+  def __init__(self, fp, section_name, reserved = None, outputFile=None):
+    if reserved is None:
+      reserved = []
     self.fp = fp
     self.sechead = '[' + section_name + ']\n'
     self.reserved = reserved
     self.outputFile = outputFile
-    self.allParsedVariableNames=[]
+    self.allParsedVariableNames = []
     # exclude line that begin with:
     self.exclude = [ 'if', 'then', 'else', 'fi', '#', 'echo', 'exit' ]
     self.exclude.append('$gconfTool') # QUICK FIX :TODO: provide method to extend this variable
@@ -371,7 +377,9 @@ class EnvFileConverter(object):
   #
 
 # Convert .sh environment file to configuration file format
-def convertEnvFileToConfigFile(envFilename, configFilename, reserved=[]):
+def convertEnvFileToConfigFile(envFilename, configFilename, reserved=None):
+  if reserved is None:
+    reserved = []
   logConfigParser.debug('convert env file %s to %s'%(envFilename, configFilename))
   fileContents = open(envFilename, 'r').read()
 
index fdaba6ce5abbf6e4d96288d9f9d2471708004f11..57c54d0ed367c8a1c59b7c56ed04e793427fb613 100644 (file)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-def __prompt(environment = None, commands=[], message = "Connecting to SALOME"):
+def __prompt(environment = None, commands=None, message = "Connecting to SALOME"):
   if environment is None:
     environment = globals().copy()
     environment.update(locals())
+  if commands is None:
+    commands = []
 
   import code
   import rlcompleter
@@ -38,7 +40,9 @@ def __prompt(environment = None, commands=[], message = "Connecting to SALOME"):
   return shell.interact
 #
 
-def connect(args=[]):
+def connect(args=None):
+  if args is None:
+    args = []
   p = __prompt(commands=["import salomeConsole"])
   p()
 #
index 92c6b4705936450753b0c0c2375419ef5687f477..f698e323d252914a436b0cbc298a2c3cbb9d49b8 100644 (file)
@@ -34,7 +34,9 @@ class MyParser(OptionParser):
         return self.epilog
 #
 
-def configureSession(args=[]):
+def configureSession(args=None):
+  if args is None:
+    args = []
   usage = "Usage: %prog [options] [command]"
   epilog  = """\n
 If the command is not given a shell is opened; else execute the given command.
index f4eb21508eb2fbfed0d8be11c1ff1644b98b796b..00de96345629011071517ea9ef43a30ef26091ad 100644 (file)
@@ -69,11 +69,11 @@ class SalomeContext:
   the SalomeContext class will try to automatically convert them
   to .cfg format before setting the environment.
   """
-  def __init__(self, configFileNames=[]):
+  def __init__(self, configFileNames=0):
     #it could be None explicitely (if user use multiples setVariable...for standalone)
-    if configFileNames==None:
+    if configFileNames is None:
        return
-
+    configFileNames = configFileNames or []
     if len(configFileNames) == 0:
       raise SalomeContextException("No configuration files given")
 
@@ -231,7 +231,9 @@ class SalomeContext:
       sys.exit(1)
   #
 
-  def __setEnvironmentFromConfigFile(self, filename, reserved=[]):
+  def __setEnvironmentFromConfigFile(self, filename, reserved=None):
+    if reserved is None:
+      reserved = []
     try:
       unsetVars, configVars, reservedDict = parseConfigFile(filename, reserved)
     except SalomeContextException, e:
@@ -277,7 +279,9 @@ class SalomeContext:
     sys.path[:0] = os.getenv('PYTHONPATH','').split(':')
   #
 
-  def _runAppli(self, args=[]):
+  def _runAppli(self, args=None):
+    if args is None:
+      args = []
     # Initialize SALOME environment
     sys.argv = ['runSalome'] + args
     import setenv
@@ -287,7 +291,9 @@ class SalomeContext:
     runSalome.runSalome()
   #
 
-  def _runSession(self, args=[]):
+  def _runSession(self, args=None):
+    if args is None:
+      args = []
     sys.argv = ['runSession'] + args
     import runSession
     runSession.configureSession(args)
@@ -300,7 +306,9 @@ class SalomeContext:
     return runSession.runSession(command)
   #
 
-  def _runConsole(self, args=[]):
+  def _runConsole(self, args=None):
+    if args is None:
+      args = []
     # Initialize SALOME environment
     sys.argv = ['runConsole'] + args
     import setenv
@@ -311,7 +319,9 @@ class SalomeContext:
     return proc.communicate()
   #
 
-  def _killAll(self, args=[]):
+  def _killAll(self, args=None):
+    if args is None:
+      args = []
     try:
       import PortManager # mandatory
       from multiprocessing import Process
@@ -332,16 +342,16 @@ class SalomeContext:
 
   #
 
-  def _showInfo(self, args=[]):
+  def _showInfo(self, args=None):
     print "Running with python", platform.python_version()
     self._runAppli(["--version"])
   #
 
-  def _usage(self, unused=[]):
+  def _usage(self, unused=None):
     usage()
   #
 
-  def _makeCoffee(self, args=[]):
+  def _makeCoffee(self, args=None):
     print "                        ("
     print "                          )     ("
     print "                   ___...(-------)-....___"
@@ -388,7 +398,6 @@ class SalomeContext:
     return self._logger
   #
 
-import pickle
 if __name__ == "__main__":
   if len(sys.argv) == 3:
     context = pickle.loads(sys.argv[1])
index 3f517dcf73b3c154d03c8d0dc99170cce3e16ac0..6e6a8fe0ae3af54fbab910b535a156c137ce4933 100644 (file)
@@ -102,7 +102,9 @@ def __getScriptPath(scriptName, searchPathList):
 #
 
 # Return an array of dictionaries {script_name: [list_of_its_args]}
-def getScriptsAndArgs(args=[], searchPathList=None):
+def getScriptsAndArgs(args=None, searchPathList=None):
+  if args is None:
+    args = []
   if searchPathList is None:
     searchPathList = sys.path
 
@@ -175,7 +177,9 @@ def getScriptsAndArgs(args=[], searchPathList=None):
 
 # Formatting scripts and args as a Bash-like command-line:
 # script1.py [args] ; script2.py [args] ; ...
-def formatScriptsAndArgs(scriptArgs=[]):
+def formatScriptsAndArgs(scriptArgs=None):
+    if scriptArgs is None:
+      scriptArgs = []
     commands = []
     for sc_dict in scriptArgs:
       for script, sc_args in sc_dict.items(): # single entry
index d7d79639c2aa57d924113cff0a12812a9e24c4c1..e9f3b088b26bc37a57d05e5a215949a54ce9557f 100644 (file)
@@ -33,7 +33,9 @@ import socket
 
 _session = None
 
-def startSession(modules=[]):
+def startSession(modules=None):
+    if modules is None:
+        modules = []
     global _session
     if _session: return
     from searchFreePort import searchFreePort
index e4c924d540b6eec0e527cbca33f4171a784833ec..dd52d38fd2b5a015985d03e0bfcdd8c66d850a2a 100644 (file)
@@ -118,7 +118,7 @@ except SystemExit, e:
 \section salome_api The API
 An API named \c SalomeContext, written in Python, allows for the construction of SALOME execution context and for application start. Each launcher creates a \c SalomeContext object, and optionally gives it a list of configuration files to describe the context:
 \code
-SalomeContext.__init__(configFileNames=[])
+SalomeContext.__init__(configFileNames=None)
 \endcode
 
 A launcher can also directly call the API functions to define, suppress or extend (add information) an environment variable:
index f399b33086ed94bae5b7fe87bd0866e2a4721516..f645e2219911e93fadbd17dc31e370a5255242fb 100644 (file)
@@ -222,12 +222,18 @@ module Engines
      */
     PyNode createPyNode(in string nodeName, in string code)  raises(SALOME::SALOME_Exception);
 
+    //! Retrieves the last created PyNode instance with createPyNode.
+    PyNode getDefaultPyNode();
+
     //! Create a PyScriptNode in the container
     /*!
       \param nodeName the name of the PyScriptNode
       \param code python code as text to load in the node
      */
     PyScriptNode createPyScriptNode(in string nodeName, in string code)  raises(SALOME::SALOME_Exception);
+
+    //! Retrieves the last created PyScriptNode instance with createPyScriptNode.
+    PyScriptNode getDefaultPyScriptNode();
   };
 
   /*! \brief Interface to pass data files from the client side to the SALOME Container.
index 97c419d3cfdadbaec74d83b347c78a46cc70ca06..ba3bfaadb665a60a2b15c2d328c6eaa9da97f6e6 100644 (file)
@@ -38,22 +38,29 @@ module Engines
   typedef sequence<octet> pickledArgs;
   typedef sequence<string> listofstring;
 
-  interface PyNode : SALOME::GenericObj
+  interface PyNodeBase : SALOME::GenericObj
   {
+    /*!
+    This methode executes the python code in \a codeStr and can append/remove symboles in context to make them available or not for future call of execute on this.
+    \param [in] codeStr - the python code (without statement) to be executed, that can modify the context initialized at initialization.
+     */
+    void executeAnotherPieceOfCode(in string codeStr) raises (SALOME::SALOME_Exception);
+  };
 
+  interface PyNode : PyNodeBase
+  {
     /*! \brief execute a python function defined in the node
 
       \param functionName the python function defined in the node to execute
       \param inargs input argument values (tuple,dict) provided as a python pickle
       \return output argument values (tuple) as a python pickle
     */
-    pickledArgs execute(in string functionName,in pickledArgs inargs) raises (SALOME::SALOME_Exception);
+    pickledArgs execute(in string functionName, in pickledArgs inargs) raises (SALOME::SALOME_Exception);
 
   } ;
 
-  interface PyScriptNode : SALOME::GenericObj
+  interface PyScriptNode : PyNodeBase
   {
-
     /*! \brief execute a python script defined in the node
 
       \param outargsname output argument names 
index 9ffea50c4e0acc5cf99ffccbfa78d9b2669cbee4..46bad445a7a7f7a117515b9f4f8e5f7fd2f5c503 100644 (file)
@@ -84,7 +84,9 @@ FIND_LIBRARY(CAS_FWOSPlugin FWOSPlugin )
 FIND_LIBRARY(CAS_PTKernel PTKernel )
 #FIND_LIBRARY(CAS_StdLPlugin StdLPlugin )
 #FIND_LIBRARY(CAS_StdPlugin StdPlugin )
+IF(CAS_VERSION_STR VERSION_LESS "6.7.2")
 FIND_LIBRARY(CAS_TKAdvTools TKAdvTools )
+ENDIF()
 FIND_LIBRARY(CAS_TKBin TKBin )
 FIND_LIBRARY(CAS_TKBinL TKBinL )
 FIND_LIBRARY(CAS_TKBinTObj TKBinTObj )
@@ -167,67 +169,71 @@ SET(CAS_TKSTEP ${CAS_TKSTEP_EA})
 SET(CAS_TKSTL ${CAS_TKSTL_EA})
 SET(CAS_TKCAF ${CAS_TKCAF_EA})
 
-INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(CAS 
-      REQUIRED_VARS CAS_INCLUDE_DIRS  
-        CAS_FWOSPlugin
-        CAS_PTKernel
-        CAS_TKAdvTools
-        CAS_TKBin
-        CAS_TKBinL
-        CAS_TKBinTObj
-        CAS_TKBinXCAF
-        CAS_TKBO
-        CAS_TKBool
-        CAS_TKBRep
-        CAS_TKCAF
-        CAS_TKCDF
-        CAS_TKernel
-        CAS_TKFeat
-        CAS_TKFillet
-        CAS_TKG2d
-        CAS_TKG3d
-        CAS_TKGeomAlgo
-        CAS_TKGeomBase
-        CAS_TKHLR
-        CAS_TKIGES
-        CAS_TKLCAF
-        CAS_TKMath
-        CAS_TKMesh
-        CAS_TKMeshVS
-        CAS_TKNIS
-        CAS_TKOffset
-        CAS_TKOpenGl
-        CAS_TKPCAF
-        CAS_TKPLCAF
-        CAS_TKPrim
-        CAS_TKPShape
-        CAS_TKService
-        CAS_TKShapeSchema
-        CAS_TKShHealing
-        CAS_TKStdLSchema
-        CAS_TKStdSchema
-        CAS_TKSTEP
-        CAS_TKSTEP209
-        CAS_TKSTEPAttr
-        CAS_TKSTEPBase
-        CAS_TKSTL
-        CAS_TKTObj
-        CAS_TKTopAlgo
-        CAS_TKV3d
-        CAS_TKVRML
-        CAS_TKXCAF
-        CAS_TKXCAFSchema
-        CAS_TKXDEIGES
-        CAS_TKXDESTEP
-        CAS_TKXMesh
-        CAS_TKXml
-        CAS_TKXmlL
-        CAS_TKXmlTObj
-        CAS_TKXmlXCAF
-        CAS_TKXSBase
+SET(_libs
+  CAS_FWOSPlugin
+  CAS_PTKernel
+  CAS_TKBin
+  CAS_TKBinL
+  CAS_TKBinTObj
+  CAS_TKBinXCAF
+  CAS_TKBO
+  CAS_TKBool
+  CAS_TKBRep
+  CAS_TKCAF
+  CAS_TKCDF
+  CAS_TKernel
+  CAS_TKFeat
+  CAS_TKFillet
+  CAS_TKG2d
+  CAS_TKG3d
+  CAS_TKGeomAlgo
+  CAS_TKGeomBase
+  CAS_TKHLR
+  CAS_TKIGES
+  CAS_TKLCAF
+  CAS_TKMath
+  CAS_TKMesh
+  CAS_TKMeshVS
+  CAS_TKNIS
+  CAS_TKOffset
+  CAS_TKOpenGl
+  CAS_TKPCAF
+  CAS_TKPLCAF
+  CAS_TKPrim
+  CAS_TKPShape
+  CAS_TKService
+  CAS_TKShapeSchema
+  CAS_TKShHealing
+  CAS_TKStdLSchema
+  CAS_TKStdSchema
+  CAS_TKSTEP
+  CAS_TKSTEP209
+  CAS_TKSTEPAttr
+  CAS_TKSTEPBase
+  CAS_TKSTL
+  CAS_TKTObj
+  CAS_TKTopAlgo
+  CAS_TKV3d
+  CAS_TKVRML
+  CAS_TKXCAF
+  CAS_TKXCAFSchema
+  CAS_TKXDEIGES
+  CAS_TKXDESTEP
+  CAS_TKXMesh
+  CAS_TKXml
+  CAS_TKXmlL
+  CAS_TKXmlTObj
+  CAS_TKXmlXCAF
+  CAS_TKXSBase
 )
 
+IF(CAS_VERSION_STR VERSION_LESS "6.7.2")
+  LIST(APPEND _libs CAS_TKAdvTools)
+ENDIF()
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(CAS REQUIRED_VARS CAS_INCLUDE_DIRS ${_libs})
+
 IF(CAS_FOUND AND NOT CAS_FIND_QUIETLY)
   IF(CAS_VERSION_DEVELOPMENT)
     MESSAGE(STATUS "Found OpenCascade version: ${CAS_VERSION_STR} (development)")
index 390b4740eb4a308fbf85bdef856b93bb32058686..9cea0e4407c0b7d81c2e041239330eb4a8f03cd5 100644 (file)
@@ -201,15 +201,20 @@ Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb,
     myCommand += "')\n";
     SCRUTE(myCommand);
 
-    // [ABN]: using the PyGILState* API here is unstable. omniORB logic is invoked
-    // by the Python code executed below, and in some (random) cases, the Python code
-    // execution ends with a PyThreadState which was not the one we have here.
-    // (TODO: understand why ...)
-    // To be on the safe side we get and load the thread state ourselves:
-    //PyGILState_STATE gstate = PyGILState_Ensure();
-    PyEval_AcquireLock();  // get GIL
-    PyThreadState * mainThreadState = PyThreadState_Get();
-    PyThreadState_Swap(mainThreadState);
+    //[RNV]: Comment the PyEval_AcquireLock() and PyEval_ReleaseLock() because this 
+    //approach leads to the deadlock of the main thread of the application on Windows platform
+    //in case if cppContainer runs in the standalone mode. The problem with the PyThreadState 
+    //described by ABN seems not reproduced, to be checked carefully later...
+    PyGILState_STATE gstate = PyGILState_Ensure();
+    
+    //// [ABN]: using the PyGILState* API here is unstable. omniORB logic is invoked
+    //// by the Python code executed below, and in some (random) cases, the Python code
+    //// execution ends with a PyThreadState which was not the one we have here.
+    //// (TODO: understand why ...)
+    //// To be on the safe side we get and load the thread state ourselves:    
+    //PyEval_AcquireLock();  // get GIL
+    //PyThreadState * mainThreadState = PyThreadState_Get();
+    //PyThreadState_Swap(mainThreadState);
 
 #ifdef WIN32
     // mpv: this is temporary solution: there is a unregular crash if not
@@ -225,9 +230,9 @@ Engines_Container_i::Engines_Container_i (CORBA::ORB_ptr orb,
     PyObject *globals = PyModule_GetDict(mainmod);
     _pyCont = PyDict_GetItemString(globals, "pyCont");
 
-    PyThreadState_Swap(NULL);
-    PyEval_ReleaseLock();
-    //PyGILState_Release(gstate);
+    //PyThreadState_Swap(NULL);
+    //PyEval_ReleaseLock();
+    PyGILState_Release(gstate);
 
     fileTransfer_i* aFileTransfer = new fileTransfer_i();
     CORBA::Object_var obref=aFileTransfer->_this();
@@ -249,6 +254,10 @@ Engines_Container_i::~Engines_Container_i()
     delete _id;
   if(_NS)
     delete _NS;
+  if(!CORBA::is_nil(_dftPyNode))
+    _dftPyNode->UnRegister();
+  if(!CORBA::is_nil(_dftPyScriptNode))
+    _dftPyScriptNode->UnRegister();
 }
 
 //=============================================================================
@@ -1641,6 +1650,11 @@ Engines::PyNode_ptr Engines_Container_i::createPyNode(const char* nodeName, cons
       {
         CORBA::Object_var obj = _orb->string_to_object(astr.c_str());
         node = Engines::PyNode::_narrow(obj);
+        if(!CORBA::is_nil(_dftPyNode))
+          _dftPyNode->UnRegister();
+        _dftPyNode = node;
+        if(!CORBA::is_nil(_dftPyNode))
+          _dftPyNode->Register();
         return node._retn();
       }
     else
@@ -1653,6 +1667,19 @@ Engines::PyNode_ptr Engines_Container_i::createPyNode(const char* nodeName, cons
 
 }
 
+//=============================================================================
+/*! \brief Retrieves the last created PyNode instance with createPyNode.
+ *
+ */
+//=============================================================================
+Engines::PyNode_ptr  Engines_Container_i::getDefaultPyNode()
+{
+  if(!CORBA::is_nil(_dftPyNode))
+    return Engines::PyNode::_duplicate(_dftPyNode);
+  else
+    return Engines::PyNode::_nil();
+}
+
 //=============================================================================
 /*! \brief create a PyScriptNode object to execute remote python code
  * \param nodeName the name of the node
@@ -1690,6 +1717,11 @@ Engines::PyScriptNode_ptr Engines_Container_i::createPyScriptNode(const char* no
       {
         CORBA::Object_var obj = _orb->string_to_object(astr.c_str());
         node = Engines::PyScriptNode::_narrow(obj);
+        if(!CORBA::is_nil(_dftPyScriptNode))
+          _dftPyScriptNode->UnRegister();
+        _dftPyScriptNode = node;
+        if(!CORBA::is_nil(_dftPyScriptNode))
+          _dftPyScriptNode->Register();
         return node._retn();
       }
     else
@@ -1701,6 +1733,19 @@ Engines::PyScriptNode_ptr Engines_Container_i::createPyScriptNode(const char* no
       }
 }
 
+//=============================================================================
+/*! \brief Retrieves the last created PyScriptNode instance with createPyScriptNode.
+ *
+ */
+//=============================================================================
+Engines::PyScriptNode_ptr Engines_Container_i::getDefaultPyScriptNode()
+{
+  if(!CORBA::is_nil(_dftPyScriptNode))
+    return Engines::PyScriptNode::_duplicate(_dftPyScriptNode);
+  else
+    return Engines::PyScriptNode::_nil();
+}
+
 //=============================================================================
 /* int checkifexecutable(const char *filename)
 *
index 2034b6d0bc81a59725d2e9054c42cdc464a65441..7a9427c4af2027439ce7b13262009ba83d150342 100644 (file)
@@ -54,6 +54,7 @@ void KERNEL_PYTHON::init_python(int argc, char **argv)
   PySys_SetArgv(argc, argv);
   PyRun_SimpleString("import threading\n");
   PyEval_InitThreads(); // Create (and acquire) the interpreter lock
-  PyEval_ReleaseLock();  // Py_InitThreads acquires the GIL
+  PyThreadState *pts = PyGILState_GetThisThreadState(); 
+  PyEval_ReleaseThread(pts);  
 }
 
index 3a801a75329ab19136b48e242c3cc1c3e8d19d11..e581178d2b15e846c68960a78b2d1690e7461db3 100755 (executable)
@@ -322,11 +322,11 @@ class SALOME_ComponentPy_i (Engines__POA.EngineComponent):
     #-------------------------------------------------------------------------    
 
     def importData(self, studyId, dataContainer, options):
-       return [] # no implmenetation by default
+       return [] # no implementation by default
 
     #-------------------------------------------------------------------------    
 
     def getModifiedData(self, studyId):
-       return [] # no implmenetation by default
+       return [] # no implementation by default
 
     pass # end of SALOME_ComponentPy_i
index 5a48dc9c037b3880f6696746747cbbaf9fe52c54..c9857f71136fd5b1b98c2371996279d947d9d1f0 100644 (file)
@@ -106,7 +106,9 @@ public:
   virtual Engines::Salome_file_ptr createSalome_file(const char* origFileName);
   void copyFile(Engines::Container_ptr container, const char* remoteFile, const char* localFile);
   Engines::PyNode_ptr createPyNode(const char* nodeName, const char* code);
+  Engines::PyNode_ptr getDefaultPyNode();
   Engines::PyScriptNode_ptr createPyScriptNode(const char* nodeName, const char* code);
+  Engines::PyScriptNode_ptr getDefaultPyScriptNode();
   // --- local C++ methods
 
   Engines::EngineComponent_ptr
@@ -154,6 +156,8 @@ protected:
   std::map<std::string,Engines::EngineComponent_var> _listInstances_map;
   std::map<std::string,Engines::fileRef_var> _fileRef_map;
   std::map<std::string,Engines::Salome_file_var> _Salome_file_map;
+  Engines::PyScriptNode_var _dftPyScriptNode;
+  Engines::PyNode_var _dftPyNode;
   std::list<std::string> _tmp_files;
   Engines::fileTransfer_var _fileTransfer;
 
index 04ce26b7ab26ce79d5f76325730808610df146ba..9cbc8a615f1f17f8ddceacc0786c790d1a341cd5 100644 (file)
@@ -64,6 +64,14 @@ class PyNode_i (Engines__POA.PyNode,Generic):
     self.context["my_container"] = self.my_container
     exec ccode in self.context
 
+  def executeAnotherPieceOfCode(self,code):
+    """Called for initialization of container lodging self."""
+    try:
+      ccode=compile(code,self.nodeName,'exec')
+      exec ccode in self.context
+    except:
+      raise SALOME.SALOME_Exception(SALOME.ExceptionStruct(SALOME.BAD_PARAM,"","PyScriptNode (%s) : code to be executed \"%s\"" %(self.nodeName,code),0))
+
   def execute(self,funcName,argsin):
     """Execute the function funcName found in local context with pickled args (argsin)"""
     try:
@@ -90,6 +98,14 @@ class PyScriptNode_i (Engines__POA.PyScriptNode,Generic):
     self.context={}
     self.context["my_container"] = self.my_container
 
+  def executeAnotherPieceOfCode(self,code):
+    """Called for initialization of container lodging self."""
+    try:
+      ccode=compile(code,self.nodeName,'exec')
+      exec ccode in self.context
+    except:
+      raise SALOME.SALOME_Exception(SALOME.ExceptionStruct(SALOME.BAD_PARAM,"","PyScriptNode (%s) : code to be executed \"%s\"" %(self.nodeName,code),0))
+
   def execute(self,outargsname,argsin):
     """Execute the script stored in attribute ccode with pickled args (argsin)"""
     try:
index 588b4162566975eba2fa75123a91ddf0b39d2787..ebd1b30021691ae346d97bb2b9753e0b7399c435 100644 (file)
@@ -149,7 +149,9 @@ def is_called_by_sphinx():
 
 
 def __show_colored_warning(message, category, filename,
-                           lineno, file = sys.stderr, line = None):
+                           lineno, file = None, line = None):
+    if file is None:
+        file = sys.stderr
     str = warnings.formatwarning(message, category, filename, lineno, line)
     if category == DeprecationWarning and termcolor.canDisplayColor(file):
         file.write(termcolor.makeColoredMessage(str, termcolor.BLUE))
index 140d13ad86e10b63d7148a6cb759ce63748b992f..7c7095a04dfe511124a1273522506e79bf69145e 100644 (file)
@@ -53,8 +53,10 @@ class Lookup(dict):
     a dictionary which can lookup value by key, or keys by value
     """
     ## items can be a list of pair_lists or a dictionary
-    def __init__(self, items=[]):
+    def __init__(self, items=None):
         """items can be a list of pair_lists or a dictionary"""
+       if items is None:
+           items = []
         dict.__init__(self, items)
 
     ## find the key(s) as a list given a value
index e30a33949d811b35fd308a1018fb2be7d30f060d..ccc1cb53be228f0f075e5341d8cca957f49d8fe6 100644 (file)
@@ -50,8 +50,10 @@ class Variable:
     its name. Other attributes are reserved for future use.
     """
     
-    def __init__(self, name, dimension = [], minValue = None, maxValue = None,
+    def __init__(self, name, dimension = None, minValue = None, maxValue = None,
                  initialValue = None):
+        if dimension is None:
+         dimension = []
         self.name = name
         
         # Reserved for future use
@@ -100,8 +102,12 @@ class ExchangeVariables:
 
     """
     
-    def __init__(self, inputVarList = [], outputVarList = [],
+    def __init__(self, inputVarList = None, outputVarList = None,
                  refEntry = None):
+        if inputVarList is None:
+         inputVarList = []
+       if outputVarList is None:
+         outputVarList = []
         self.inputVarList = inputVarList
         self.outputVarList = outputVarList
         self.refEntry = refEntry
index c11a8b33b5e596b705ef275867c41aee0f20da4a..6ea5a386dabc1ffbaf4005fade3ee61de278d630 100644 (file)
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-#
 # Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 # This library is free software; you can redistribute it and/or
@@ -41,6 +39,9 @@ logger = Logger("salome.kernel.studyedit", color = termcolor.PURPLE)
 _editors = {}
 _DEFAULT_CONTAINER = "FactoryServer"
 
+# The codec to use for strings that are displayed in Salome study tree is UTF-8
+ENCODING_FOR_SALOME_STUDY = "utf-8"
+
 ## Return the ID of the active study. In GUI mode, this function is equivalent
 #  to salome.sg.getActiveStudyId(). Outside GUI, it returns <b> salome.myStudyId </b>
 #  variable.
@@ -314,12 +315,12 @@ class StudyEditor:
         while childIterator.More() and foundItem is None:
             childItem = childIterator.Value()
             if childItem and \
-               (name is None or childItem.GetName() == name) and \
+               (name is None or self.getName(childItem) == name) and \
                (fileType is None or \
                 self.getFileType(childItem) == fileType) and \
                (fileName is None or \
                 self.getFileName(childItem) == fileName) and \
-               (comment is None or childItem.GetComment() == comment) and \
+               (comment is None or self.getComment(childItem) == comment) and \
                (icon is None or \
                 self.getIcon(childItem) == icon) and \
                (IOR is None or childItem.GetIOR() == IOR) and \
@@ -396,16 +397,16 @@ class StudyEditor:
     #
     #  \param item (SObject) item to modify.
     #
-    #  \param name (string) item name (attribute \b AttributeName).
+    #  \param name (string or unicode) item name (attribute \b AttributeName).
     #
-    #  \param fileType (string) item file type (attribute \b AttributeFileType).
+    #  \param fileType (string or unicode) item file type (attribute \b AttributeFileType).
     #
-    #  \param fileName (string) item file name (attribute \b AttributeExternalFileDef).
+    #  \param fileName (string or unicode) item file name (attribute \b AttributeExternalFileDef).
     #
-    #  \param comment (string) item comment (attribute \b AttributeComment). Note that
+    #  \param comment (string or unicode) item comment (attribute \b AttributeComment). Note that
     #  this attribute will appear in the \b Value column in the object browser.
     #
-    #  \param icon (string) item icon name (attribute \b AttributePixMap).
+    #  \param icon (string or unicode) item icon name (attribute \b AttributePixMap).
     #
     #  \param IOR (string) IOR of a CORBA object associated with the item
     #  (attribute \b AttributeIOR).
@@ -420,22 +421,22 @@ class StudyEditor:
         :type  item: SObject
         :param item: item to modify.
 
-        :type  name: string
+        :type  name: string or unicode
         :param name: item name (attribute 'AttributeName').
 
-        :type  fileType: string
+        :type  fileType: string or unicode
         :param fileType: item file type (attribute 'AttributeFileType').
 
-        :type  fileName: string
+        :type  fileName: string or unicode
         :param fileName: item file name (attribute
                          'AttributeExternalFileDef').
 
-        :type  comment: string
+        :type  comment: string or unicode
         :param comment: item comment (attribute 'AttributeComment'). Note that
                         this attribute will appear in the 'Value' column in
                         the object browser.
 
-        :type  icon: string
+        :type  icon: string or unicode
         :param icon: item icon name (attribute 'AttributePixMap').
 
         :type  IOR: string
@@ -449,19 +450,18 @@ class StudyEditor:
                      "comment=%s, icon=%s, IOR=%s" %
                      (item.GetID(), name, fileType, fileName, comment,
                       icon, IOR))
-        # Explicit cast is necessary for unicode to string conversion
         if name is not None:
-            self.builder.SetName(item, str(name))
+            self.setName(item, name)
         if fileType is not None:
             self.setFileType(item, fileType)
         if fileName is not None:
             self.setFileName(item, fileName)
         if comment is not None:
-            self.builder.SetComment(item, str(comment))
+            self.setComment(item, comment)
         if icon is not None:
             self.setIcon(item, icon)
         if IOR is not None:
-            self.builder.SetIOR(item, str(IOR))
+            self.builder.SetIOR(item, IOR)
         if typeId is not None:
             self.setTypeId(item, typeId)
 
@@ -538,6 +538,24 @@ class StudyEditor:
                      IOR, typeId)
         return sObj
 
+    ## Return the name of the object sObject
+    def getName(self, sObject):
+        val = sObject.GetName()
+        return unicode(val, ENCODING_FOR_SALOME_STUDY)
+
+    ## Set the name of the object sObject
+    def setName(self, sObject, name):
+        self.builder.SetName(sObject, name.encode(ENCODING_FOR_SALOME_STUDY))
+
+    ## Return the comment of the object sObject
+    def getComment(self, sObject):
+        val = sObject.GetComment()
+        return unicode(val, ENCODING_FOR_SALOME_STUDY)
+
+    ## Set the comment of the object sObject
+    def setComment(self, sObject, comment):
+        self.builder.SetComment(sObject, comment.encode(ENCODING_FOR_SALOME_STUDY))
+
     ## Return the value of the attribute named \b attributeName on the object
     #  sObject, or \b default if the attribute doesn't exist.
     def getAttributeValue(self, sObject, attributeName, default = None):
@@ -586,7 +604,8 @@ class StudyEditor:
         Return the value of the attribute "AttributeFileType" of the object
         `sObject`, or an empty string if it is not set.
         """
-        return self.getAttributeValue(sObject, "AttributeFileType", "")
+        val = self.getAttributeValue(sObject, "AttributeFileType", "")
+        return unicode(val, ENCODING_FOR_SALOME_STUDY)
 
     ## Set the attribute "AttributeFileType" of the object sObject to the
     #  value value.
@@ -595,8 +614,8 @@ class StudyEditor:
         Set the attribute "AttributeFileType" of the object `sObject` to the
         value `value`.
         """
-        # Explicit cast is necessary for unicode to string conversion
-        self.setAttributeValue(sObject, "AttributeFileType", str(value))
+        self.setAttributeValue(sObject, "AttributeFileType",
+                               value.encode(ENCODING_FOR_SALOME_STUDY))
 
     ## Return the value of the attribute "AttributeExternalFileDef" of the
     #  object sObject, or an empty string if it is not set.
@@ -605,7 +624,8 @@ class StudyEditor:
         Return the value of the attribute "AttributeExternalFileDef" of the
         object `sObject`, or an empty string if it is not set.
         """
-        return self.getAttributeValue(sObject, "AttributeExternalFileDef", "")
+        val = self.getAttributeValue(sObject, "AttributeExternalFileDef", "")
+        return unicode(val, ENCODING_FOR_SALOME_STUDY)
 
     ## Set the attribute "AttributeExternalFileDef" of the object sObject
     #  to the value value.
@@ -614,9 +634,8 @@ class StudyEditor:
         Set the attribute "AttributeExternalFileDef" of the object `sObject`
         to the value `value`.
         """
-        # Explicit cast is necessary for unicode to string conversion
         self.setAttributeValue(sObject, "AttributeExternalFileDef",
-                               str(value))
+                               value.encode(ENCODING_FOR_SALOME_STUDY))
 
     ## Return the value of the attribute "AttributePixMap" of the object
     #  sObject, or an empty string if it is not set.
@@ -629,7 +648,7 @@ class StudyEditor:
         found, attr = self.builder.FindAttribute(sObject, "AttributePixMap")
         if found and attr.HasPixMap():
             value = attr.GetPixMap()
-        return value
+        return unicode(value, ENCODING_FOR_SALOME_STUDY)
 
     ## Set the attribute "AttributePixMap" of the object sObject to the
     #  value value.
@@ -639,5 +658,4 @@ class StudyEditor:
         value `value`.
         """
         attr = self.builder.FindOrCreateAttribute(sObject, "AttributePixMap")
-        # Explicit cast is necessary for unicode to string conversion
-        attr.SetPixMap(str(value))
+        attr.SetPixMap(value.encode(ENCODING_FOR_SALOME_STUDY))
index eb83e7966b546e81f7f8951fdb41422c2e07abde..e76502b646711fa80679ef09115ca1e54881404f 100644 (file)
@@ -25,7 +25,7 @@ __author__="gboulant"
 __date__ ="$21 mai 2010 18:00:23$"
 
 
-def findFiles(rootpath, excludes=[]):
+def findFiles(rootpath, excludes=None):
     """
     This looks after files recursively from the specified rootpath,
     but without visiting directories whose basename is in the list
@@ -34,6 +34,8 @@ def findFiles(rootpath, excludes=[]):
     if not os.path.exists(rootpath):
         raise RuntimeError("the path %s does not exists"%rootpath)
 
+    if excludes is None:
+        excludes = []
     exclude_options=""
     for excludepath in excludes:
         exclude_options+="-e %s "%excludepath
index 902e5d33fc072b005edba752bec57ed548d023a6..9c6ef033f7cc3a6cb50bad8fd9f86446cac83b13 100644 (file)
@@ -69,6 +69,11 @@ def setVectorsMode(objId, mode):
 
     #--------------------------------------------------------------------------
 
+def setVerticesMode(objId, mode):
+    return
+
+    #--------------------------------------------------------------------------
+
 # --- From SMESHGUI_SWIG
 
     #--------------------------------------------------------------------------
index 9a4995c0dd16a0ac64a2f9125a7c08a9f09b5916..fd1fa6508ab5b4efee4a85222a322e4d3565ac1e 100644 (file)
@@ -46,28 +46,40 @@ class ContainerParameters (Engines.ContainerParameters):
     Engines.ContainerParameters.__init__(self,container_name, mode, workingdir, nb_proc, isMPI, parallelLib,resource_params)
 
 class ResourceParameters (Engines.ResourceParameters):
-  def __init__(self, name="", hostname="", OS="", componentList=[],
+  def __init__(self, name="", hostname="", OS="", componentList=None,
                      nb_proc=0, mem_mb=0, cpu_clock=0, nb_node=0, nb_proc_per_node=0,
-                     policy="", resList=[], can_launch_batch_jobs = False, can_run_containers = False):
+                     policy="", resList=None, can_launch_batch_jobs = False, can_run_containers = False):
+    if componentList is None:
+      componentList = []
+    if resList is None:
+      resList = []
     Engines.ResourceParameters.__init__(self, name, hostname, can_launch_batch_jobs, can_run_containers,
                                         OS, componentList, nb_proc, mem_mb, cpu_clock, nb_node,
                                         nb_proc_per_node, policy, resList)
 
 class JobParameters (Engines.JobParameters):
-  def __init__(self, job_name="", job_type="", job_file="", env_file="", in_files=[], out_files=[],
+  def __init__(self, job_name="", job_type="", job_file="", env_file="", in_files=None, out_files=None,
                      work_directory="", local_directory="", result_directory="", maximum_duration="",
                      resource_required=None, queue="", exclusive = False, mem_per_cpu = 0,
-                     specific_parameters=[], launcher_file = "", launcher_args = ""):
+                     specific_parameters=None, launcher_file = "", launcher_args = ""):
+    if in_files is None:
+      in_files = []
+    if out_files is None:
+      out_files = []
+    if specific_parameters is None:
+      specific_parameters = []
     Engines.JobParameters.__init__(self, job_name, job_type, job_file, env_file, in_files, out_files,
                                          work_directory, local_directory, result_directory, maximum_duration,
                                          resource_required, queue, exclusive, mem_per_cpu,
                                          specific_parameters, launcher_file, launcher_args)
 
 class ResourceDefinition(Engines.ResourceDefinition):
-  def __init__(self, name="", hostname="", protocol="rsh", username="", applipath="", componentList=[],
+  def __init__(self, name="", hostname="", protocol="rsh", username="", applipath="", componentList=None,
                mode="interactive", OS="", mem_mb=1, cpu_clock=1, nb_node=1, nb_proc_per_node=1,
                batch="", mpiImpl="", iprotocol="rsh", type = "single_machine",
                can_launch_batch_jobs = False, can_run_containers = False, working_directory = ""):
+    if componentList is None:
+      componentList = []
     Engines.ResourceDefinition.__init__(self, name, hostname, type, protocol, username, applipath,
                                         componentList, OS, mem_mb, cpu_clock, nb_node, nb_proc_per_node,
                                         batch, mpiImpl, iprotocol, can_launch_batch_jobs,
index 1beef16323b716e224ea3a9f9af7dbdcae7b9f94..e90641db1adc290587818ad94b3757dc4a64ff8b 100644 (file)
@@ -1127,6 +1127,12 @@ Engines_Parallel_Container_i::createPyNode(const char* nodeName, const char* cod
   return node._retn();
 }
 
+Engines::PyNode_ptr Engines_Parallel_Container_i::getDefaultPyNode()
+{
+  INFOS("Python component not yet implemented");
+  return Engines::PyNode::_nil();
+}
+
 Engines::PyScriptNode_ptr 
 Engines_Parallel_Container_i::createPyScriptNode(const char* nodeName, const char* cod)
 {
@@ -1135,6 +1141,12 @@ Engines_Parallel_Container_i::createPyScriptNode(const char* nodeName, const cha
   return node._retn();
 }
 
+Engines::PyScriptNode_ptr Engines_Parallel_Container_i::getDefaultPyScriptNode()
+{
+  INFOS("Python script node not yet implemented");
+  return Engines::PyScriptNode::_nil();
+}
+
 //=============================================================================
 /*! 
  *  
index bc64e8dc658919ec10a053ed106eb59588b099bc..6576ba613842252e57e1ee475a9cb6a2c359b62a 100644 (file)
@@ -138,8 +138,9 @@ public:
   virtual Engines::Salome_file_ptr createSalome_file(const char* origFileName);
   void copyFile(Engines::Container_ptr container, const char* remoteFile, const char* localFile);
   Engines::PyNode_ptr createPyNode(const char* nodeName, const char* code);
+  Engines::PyNode_ptr getDefaultPyNode();
   Engines::PyScriptNode_ptr createPyScriptNode(const char* nodeName, const char* code);
-
+  Engines::PyScriptNode_ptr getDefaultPyScriptNode();
 protected:
 
   SALOME_NamingService *_NS;
index 9eea0a2d39a9b430c559ba67a7dc6d5a8a0abcec..3918ade66ebb3a65b6140183bf1740a574559cd0 100644 (file)
@@ -1418,7 +1418,7 @@ bool SALOMEDSImpl_Study::DumpStudy(const std::string& thePath,
 std::string SALOMEDSImpl_Study::GetDumpStudyComment(const char* theComponentName)
 {
   std::stringstream txt;
-  txt << "# -*- coding: iso-8859-1 -*-" << std::endl << std::endl;
+  txt << "# -*- coding: utf-8 -*-" << std::endl << std::endl;
   txt << "###" << std::endl;
   txt << "### This file is generated automatically by SALOME v"
       << KERNEL_VERSION_STR