X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=bin%2FlaunchConfigureParser.py;h=54959618f4e122123ca919329907fe56b36591eb;hb=ee84dc2b25345766bbab2505870804e781fce00a;hp=47f120d8e01cad8d8dd62fa89789774e3d7cd9e9;hpb=e0c86149d9bc71a5e7e3f7c688263d358d249a75;p=modules%2Fkernel.git diff --git a/bin/launchConfigureParser.py b/bin/launchConfigureParser.py index 47f120d8e..54959618f 100755 --- a/bin/launchConfigureParser.py +++ b/bin/launchConfigureParser.py @@ -1,79 +1,300 @@ -import os, glob, string, sys +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +import os, glob, string, sys, re import xml.sax +import optparse +import types + +from salome_utils import verbose, setVerbose, getPortNumber + +# names of tags in XML configuration file +doc_tag = "document" +sec_tag = "section" +par_tag = "parameter" +import_tag = "import" + +# names of attributes in XML configuration file +nam_att = "name" +val_att = "value" + +# certain values in XML configuration file ("launch" section) +lanch_nam = "launch" +help_nam = "help" +gui_nam = "gui" +splash_nam = "splash" +logger_nam = "logger" +xterm_nam = "xterm" +file_nam = "file" +portkill_nam = "portkill" +killall_nam = "killall" +modules_nam = "modules" +embedded_nam = "embedded" +standalone_nam = "standalone" +key_nam = "key" +terminal_nam = "terminal" +interp_nam = "interp" +except_nam = "noexcepthandler" +terminal_nam = "terminal" +pinter_nam = "pinter" +batch_nam = "batch" +test_nam = "test" +play_nam = "play" +gdb_session_nam = "gdb_session" +ddd_session_nam = "ddd_session" +valgrind_session_nam = "valgrind_session" +shutdown_servers_nam = "shutdown_servers" +foreground_nam = "foreground" +wake_up_session_nam = "wake_up_session" + +# values in XML configuration file giving specific module parameters ( section) +# which are stored in opts with key _ (eg SMESH_plugins) +plugins_nam = "plugins" + +# values passed as arguments, NOT read from XML config file, but set from within this script +appname_nam = "appname" +port_nam = "port" +salomeappname = "SalomeApp" +script_nam = "pyscript" + +# possible choices for the "embedded" and "standalone" parameters +embedded_choices = [ "registry", "study", "moduleCatalog", "cppContainer", "SalomeAppEngine" ] +standalone_choices = [ "registry", "study", "moduleCatalog", "cppContainer", "pyContainer"] + +# values of boolean type (must be '0' or '1'). +# xml_parser.boolValue() is used for correct setting +boolKeys = ( gui_nam, splash_nam, logger_nam, file_nam, xterm_nam, portkill_nam, killall_nam, except_nam, pinter_nam, shutdown_servers_nam ) +intKeys = ( interp_nam, ) + +# values of list type +listKeys = ( embedded_nam, key_nam, modules_nam, standalone_nam, plugins_nam ) + +### +# Get the application version +# Uses GUI_ROOT_DIR (or KERNEL_ROOT_DIR in batch mode) +/bin/salome/VERSION file +### +def version(): + try: + filename = None + root_dir = os.environ.get( 'KERNEL_ROOT_DIR', '' ) # KERNEL_ROOT_DIR or "" if not found + if root_dir and os.path.exists( root_dir + "/bin/salome/VERSION" ): + filename = root_dir + "/bin/salome/VERSION" + root_dir = os.environ.get( 'GUI_ROOT_DIR', '' ) # GUI_ROOT_DIR "" if not found + if root_dir and os.path.exists( root_dir + "/bin/salome/VERSION" ): + filename = root_dir + "/bin/salome/VERSION" + if filename: + str = open( filename, "r" ).readline() # str = "THIS IS SALOME - SALOMEGUI VERSION: 3.0.0" + match = re.search( r':\s+([a-zA-Z0-9.]+)\s*$', str ) + if match : + return match.group( 1 ) + except: + pass + return '' + +### +# Calculate and return configuration file unique ID +# For example: for SALOME version 3.1.0a1 the id is 300999701 +### +def version_id( fname ): + vers = fname.split(".") + major = int(vers[0]) + minor = int(vers[1]) + mr = re.search(r'^([0-9]+)([A-Za-z]?)([0-9]*)',vers[2]) + release = dev = 0 + if mr: + release = int(mr.group(1)) + dev1 = dev2 = 0 + if len(mr.group(2)): dev1 = ord(mr.group(2)) + if len(mr.group(3)): dev2 = int(mr.group(3)) + dev = dev1 * 100 + dev2 + else: + return None + ver = major + ver = ver * 100 + minor + ver = ver * 100 + release + ver = ver * 10000 + if dev > 0: ver = ver - 10000 + dev + return ver + +### +# Get user configuration file name +### +def userFile(appname): + v = version() + if not v: + return "" # not unknown version + if sys.platform == "win32": + filename = "%s\%s.xml.%s" % (os.environ['HOME'], appname, v) + else: + filename = "%s/.%src.%s" % (os.environ['HOME'], appname, v) + if os.path.exists(filename): + return filename # user preferences file for the current version exists + # initial id + id0 = version_id( v ) + # get all existing user preferences files + if sys.platform == "win32": + files = glob.glob( os.environ['HOME'] + "\." + appname + ".xml.*" ) + else: + files = glob.glob( os.environ['HOME'] + "/." + appname + "rc.*" ) + f2v = {} + for file in files: + match = re.search( r'\.%src\.([a-zA-Z0-9.]+)$'%appname, file ) + if match: f2v[file] = match.group(1) + last_file = "" + last_version = 0 + for file in f2v: + ver = version_id( f2v[file] ) + if ver and abs(last_version-id0) > abs(ver-id0): + last_version = ver + last_file = file + return last_file + +# -- + +def process_containers_params( standalone, embedded ): + # 1. filter inappropriate containers names + if standalone is not None: + standalone = filter( lambda x: x in standalone_choices, standalone ) + if embedded is not None: + embedded = filter( lambda x: x in embedded_choices, embedded ) + + # 2. remove containers appearing in 'standalone' parameter from the 'embedded' + # parameter --> i.e. 'standalone' parameter has higher priority + if standalone is not None and embedded is not None: + embedded = filter( lambda x: x not in standalone, embedded ) + + # 3. return corrected parameters values + return standalone, embedded # ----------------------------------------------------------------------------- -### xml reader for launch configuration file usage +### +# XML reader for launch configuration file usage +### + +section_to_skip = "" class xml_parser: - def __init__(self, fileName): + def __init__(self, fileName, _opts, _importHistory=[] ): + if verbose(): print "Configure parser: processing %s ..." % fileName + self.fileName = os.path.abspath(fileName) + self.importHistory = _importHistory + self.importHistory.append(self.fileName) self.space = [] - self.opts = {} + self.opts = _opts + self.section = section_to_skip parser = xml.sax.make_parser() parser.setContentHandler(self) parser.parse(fileName) + standalone, embedded = process_containers_params( self.opts.get( standalone_nam ), + self.opts.get( embedded_nam ) ) + if standalone is not None: + self.opts[ standalone_nam ] = standalone + if embedded is not None: + self.opts[ embedded_nam ] = embedded pass - def CorrectBoolean(self, str): - if str in ("yes", "y", "1"): - return 1 - elif str in ("no", "n", "0"): - return 0 - else: - return str + def boolValue( self, str ): + strloc = str + if isinstance(strloc, types.UnicodeType): + strloc = strloc.encode().strip() + if isinstance(strloc, types.StringType): + strlow = strloc.lower() + if strlow in ("1", "yes", "y", "on", "true", "ok"): + return True + elif strlow in ("0", "no", "n", "off", "false", "cancel"): + return False + return strloc + pass + + def intValue( self, str ): + strloc = str + if isinstance(strloc, types.UnicodeType): + strloc = strloc.encode().strip() + if isinstance(strloc, types.StringType): + strlow = strloc.lower() + if strlow in ("1", "yes", "y", "on", "true", "ok"): + return 1 + elif strlow in ("0", "no", "n", "off", "false", "cancel"): + return 0 + else: + return string.atoi(strloc) + return strloc pass def startElement(self, name, attrs): - #print "startElement name=",name - #print "startElement attrs=",attrs.getNames() self.space.append(name) self.current = None - - if self.space[:2] == ["Configuration-list","launchoptions"] and len(self.space) == 3: - self.current = name - elif self.space == ["Configuration-list","modules-list"]: - self.opts["modules"] = [] - elif self.space == ["Configuration-list","modules-list","module"] and "name" in attrs.getNames(): - for field in attrs.getNames(): - if field == "name": - self.currentModuleName = str(attrs.getValue("name")) - self.opts["modules"].append(self.currentModuleName) - else: - self.opts[str(attrs.getValue("name"))+"_"+str(field)] = self.CorrectBoolean(attrs.getValue(field)) - pass - pass - elif self.space == ["Configuration-list","modules-list","module","plugin"] and "name" in attrs.getNames(): - key = str(self.currentModuleName)+"_plugins" - if not self.opts.has_key("key"): - self.opts[key]=[] - pass - self.opts[key].append(attrs.getValue("name")) - elif self.space == ["Configuration-list","embedded-list"]: - self.opts["embedded"] = [] - pass - elif self.space == ["Configuration-list","standalone-list"]: - self.opts["standalone"] = [] + + # if we are importing file + if self.space == [doc_tag, import_tag] and nam_att in attrs.getNames(): + self.importFile( attrs.getValue(nam_att) ) + + # if we are analyzing "section" element and its "name" attribute is + # either "launch" or module name -- set section_name + if self.space == [doc_tag, sec_tag] and nam_att in attrs.getNames(): + section_name = attrs.getValue( nam_att ) + if section_name == lanch_nam: + self.section = section_name # launch section + elif self.opts.has_key( modules_nam ) and \ + section_name in self.opts[ modules_nam ]: + self.section = section_name # section + else: + self.section = section_to_skip # any other section pass - elif self.space == ["Configuration-list","containers-list"]: - self.opts["containers"] = [] + + # if we are analyzing "parameter" elements - children of either + # "section launch" or "section """ element, then store them + # in self.opts assiciative array (key = [_ + ] value of "name" attribute) + elif self.section != section_to_skip and \ + self.space == [doc_tag, sec_tag, par_tag] and \ + nam_att in attrs.getNames() and \ + val_att in attrs.getNames(): + nam = attrs.getValue( nam_att ) + val = attrs.getValue( val_att ) + if self.section == lanch_nam: # key for launch section + key = nam + else: # key for section + key = self.section + "_" + nam + if nam in boolKeys: + self.opts[key] = self.boolValue( val ) # assign boolean value: 0 or 1 + elif nam in intKeys: + self.opts[key] = self.intValue( val ) # assign integer value + elif nam in listKeys: + self.opts[key] = filter( lambda a: a.strip(), re.split( "[:;,]", val ) ) # assign list value: [] + else: + self.opts[key] = val pass pass def endElement(self, name): p = self.space.pop() self.current = None + if self.section != section_to_skip and name == sec_tag: + self.section = section_to_skip pass def characters(self, content): - #print "Characters content:",content - if self.current: - self.opts[self.current] = self.CorrectBoolean(content) - elif self.space == ["Configuration-list","embedded-list", "embeddedserver"]: - self.opts["embedded"].append(content) - elif self.space == ["Configuration-list","standalone-list", "standaloneserver"]: - self.opts["standalone"].append(content) - elif self.space == ["Configuration-list","containers-list", "containertype"]: - self.opts["containers"].append(content) pass def processingInstruction(self, target, data): @@ -89,216 +310,779 @@ class xml_parser: def endDocument(self): self.read = None pass + + def importFile(self, fname): + # get absolute name + if os.path.isabs (fname) : + absfname = fname + else: + absfname = os.path.join(os.path.dirname(self.fileName), fname) + + # check existing and registry file + for ext in ["", ".xml", ".XML"] : + if os.path.exists(absfname + ext) : + absfname += ext + if absfname in self.importHistory : + if verbose(): print "Configure parser: file %s is already imported" % absfname + return # already imported + break + pass + else: + if verbose(): print "Configure parser: Error : file %s does NOT exists" % absfname + return + + # importing file + try: + # copy current options + import copy + opts = copy.deepcopy(self.opts) + # import file + imp = xml_parser(absfname, opts, self.importHistory) + # merge results + for key in imp.opts.keys(): + if not self.opts.has_key(key): + self.opts[key] = imp.opts[key] + pass + pass + pass + except: + if verbose(): print "Configure parser: Error : can not read configuration file %s" % absfname + pass + # ----------------------------------------------------------------------------- -### searching for launch configuration file : $HOME/.$(application_name)/$(application_name).launch +booleans = { '1': True , 'yes': True , 'y': True , 'on' : True , 'true' : True , 'ok' : True, + '0': False, 'no' : False, 'n': False, 'off': False, 'false': False, 'cancel' : False } -appname = None -dirname = None -filename = None -for bindir in glob.glob(os.environ["KERNEL_ROOT_DIR"]+"/bin/*"): - appname = string.split(bindir, "/").pop() - print 'Application name: "'+appname+'"' - # find version number - versnb = "" - try: - file = open(os.environ["KERNEL_ROOT_DIR"]+"/bin/"+appname+"/VERSION", "r") - s = file.read() - l = string.split(s, ":") - vl = string.split(l[1], " ") - i = 0 - while len(versnb) == 0: - versnb = vl[i] - i += 1 - pass - versnb = string.split(versnb, "\n")[0] - print "Version ",versnb - except: - pass - # end find version number - dirname = os.environ["HOME"]+"/."+appname+"_"+versnb - filename = dirname+"/"+appname+".launch" - if not os.path.exists(filename) and \ - not os.path.exists(os.environ["KERNEL_ROOT_DIR"]+"/bin/"+appname+"/"+appname+".launch"): - filename = None +boolean_choices = booleans.keys() + +def check_embedded(option, opt, value, parser): + from optparse import OptionValueError + assert value is not None + if parser.values.embedded: + embedded = filter( lambda a: a.strip(), re.split( "[:;,]", parser.values.embedded ) ) else: - break + embedded = [] + if parser.values.standalone: + standalone = filter( lambda a: a.strip(), re.split( "[:;,]", parser.values.standalone ) ) + else: + standalone = [] + vals = filter( lambda a: a.strip(), re.split( "[:;,]", value ) ) + for v in vals: + if v not in embedded_choices: + raise OptionValueError( "option %s: invalid choice: %r (choose from %s)" % ( opt, v, ", ".join( map( repr, embedded_choices ) ) ) ) + if v not in embedded: + embedded.append( v ) + if v in standalone: + del standalone[ standalone.index( v ) ] + pass + parser.values.embedded = ",".join( embedded ) + parser.values.standalone = ",".join( standalone ) pass -if not appname: - print "Can not find application name" - if not os.have_key("KERNEL_ROOT_DIR"): - print "KERNEL_ROOT_DIR environment variable must be set" - pass - sys.exit(1); -elif not filename or not os.path.exists(filename): - filename = dirname+"/"+appname+".launch" - #filename = os.environ["HOME"]+"/."+appname+"/"+appname+".launch" - print "Launch configuration file does not exist. Create default:",filename - os.system("mkdir -p "+dirname) - #os.system("mkdir -p "+os.environ["HOME"]+"/."+appname) - os.system("cp -f "+os.environ["KERNEL_ROOT_DIR"]+"/bin/"+appname+"/"+appname+".launch "+filename) + +def check_standalone(option, opt, value, parser): + from optparse import OptionValueError + assert value is not None + if parser.values.embedded: + embedded = filter( lambda a: a.strip(), re.split( "[:;,]", parser.values.embedded ) ) + else: + embedded = [] + if parser.values.standalone: + standalone = filter( lambda a: a.strip(), re.split( "[:;,]", parser.values.standalone ) ) + else: + standalone = [] + vals = filter( lambda a: a.strip(), re.split( "[:;,]", value ) ) + for v in vals: + if v not in standalone_choices: + raise OptionValueError( "option %s: invalid choice: %r (choose from %s)" % ( opt, v, ", ".join( map( repr, standalone_choices ) ) ) ) + if v not in standalone: + standalone.append( v ) + if v in embedded: + del embedded[ embedded.index( v ) ] + pass + parser.values.embedded = ",".join( embedded ) + parser.values.standalone = ",".join( standalone ) pass -### get options from launch configuration file +def store_boolean (option, opt, value, parser, *args): + if isinstance(value, types.StringType): + try: + value_conv = booleans[value.strip().lower()] + for attribute in args: + setattr(parser.values, attribute, value_conv) + except KeyError: + raise optparse.OptionValueError( + "option %s: invalid boolean value: %s (choose from %s)" + % (opt, value, boolean_choices)) + else: + for attribute in args: + setattr(parser.values, attribute, value) -try: - p = xml_parser(filename) -except: - print 'Can not read launch configuration file ', filename - filename = None - pass +def CreateOptionParser (theAdditionalOptions=[]): + # GUI/Terminal. Default: GUI + help_str = "Launch without GUI (in the terminal mode)." + o_t = optparse.Option("-t", + "--terminal", + action="store_false", + dest="gui", + help=help_str) -if filename: - args = p.opts -else: - args = {} - pass + help_str = "Launch in Batch Mode. (Without GUI on batch machine)" + o_b = optparse.Option("-b", + "--batch", + action="store_true", + dest="batch", + help=help_str) -# --- args completion -for aKey in ("containers","embedded","key","modules","standalone"): - if not args.has_key(aKey): - args[aKey]=[] -for aKey in ("gui","logger","xterm","portkill","killall"): - if not args.has_key(aKey): - args[aKey]=0 -args["appname"] = appname - -### searching for my port - -my_port = 2809 -try: - file = open(os.environ["OMNIORB_CONFIG"], "r") - s = file.read() - while len(s): - l = string.split(s, ":") - if string.split(l[0], " ")[0] == "ORBInitRef": - my_port = int(l[len(l)-1]) - pass - s = file.read() - pass -except: - pass + help_str = "Launch in GUI mode [default]." + o_g = optparse.Option("-g", + "--gui", + action="store_true", + dest="gui", + help=help_str) + + # Show Desktop (inly in GUI mode). Default: True + help_str = "1 to activate GUI desktop [default], " + help_str += "0 to not activate GUI desktop (Session_Server starts, but GUI is not shown). " + help_str += "Ignored in the terminal mode." + o_d = optparse.Option("-d", + "--show-desktop", + metavar="<1/0>", + #type="choice", choices=boolean_choices, + type="string", + action="callback", callback=store_boolean, callback_args=('desktop',), + dest="desktop", + help=help_str) + help_str = "Do not activate GUI desktop (Session_Server starts, but GUI is not shown). " + help_str += "The same as --show-desktop=0." + o_o = optparse.Option("-o", + "--hide-desktop", + action="store_false", + dest="desktop", + help=help_str) + + # Use logger or log-file. Default: nothing. + help_str = "Redirect messages to the CORBA collector." + #o4 = optparse.Option("-l", "--logger", action="store_true", dest="logger", help=help_str) + o_l = optparse.Option("-l", + "--logger", + action="store_const", const="CORBA", + dest="log_file", + help=help_str) + help_str = "Redirect messages to the " + o_f = optparse.Option("-f", + "--log-file", + metavar="", + type="string", + action="store", + dest="log_file", + help=help_str) + + # Execute python scripts. Default: None. + help_str = "Python script(s) to be imported. Python scripts are imported " + help_str += "in the order of their appearance. In GUI mode python scripts " + help_str += "are imported in the embedded python interpreter of current study, " + help_str += "otherwise in an external python interpreter. " + help_str += "Note: this option is obsolete. Instead you can pass Python script(s) " + help_str += "directly as positional parameter." + o_u = optparse.Option("-u", + "--execute", + metavar="", + type="string", + action="append", + dest="py_scripts", + help=help_str) + + # Configuration XML file. Default: $(HOME)/.SalomeApprc.$(version). + help_str = "Parse application settings from the " + help_str += "instead of default $(HOME)/.SalomeApprc.$(version)" + o_r = optparse.Option("-r", + "--resources", + metavar="", + type="string", + action="store", + dest="resources", + help=help_str) + + # Use own xterm for each server. Default: False. + help_str = "Launch each SALOME server in own xterm console" + o_x = optparse.Option("-x", + "--xterm", + action="store_true", + dest="xterm", + help=help_str) + + # Modules. Default: Like in configuration files. + help_str = "SALOME modules list (where , are the names " + help_str += "of SALOME modules which should be available in the SALOME session)" + o_m = optparse.Option("-m", + "--modules", + metavar="", + type="string", + action="append", + dest="modules", + help=help_str) + + # Embedded servers. Default: Like in configuration files. + help_str = "CORBA servers to be launched in the Session embedded mode. " + help_str += "Valid values for : %s " % ", ".join( embedded_choices ) + help_str += "[by default the value from the configuration files is used]" + o_e = optparse.Option("-e", + "--embedded", + metavar="", + type="string", + action="callback", + dest="embedded", + callback=check_embedded, + help=help_str) + + # Standalone servers. Default: Like in configuration files. + help_str = "CORBA servers to be launched in the standalone mode (as separate processes). " + help_str += "Valid values for : %s " % ", ".join( standalone_choices ) + help_str += "[by default the value from the configuration files is used]" + o_s = optparse.Option("-s", + "--standalone", + metavar="", + type="string", + action="callback", + dest="standalone", + callback=check_standalone, + help=help_str) + + # Kill with port. Default: False. + help_str = "Kill SALOME with the current port" + o_p = optparse.Option("-p", + "--portkill", + action="store_true", + dest="portkill", + help=help_str) + + # Kill all. Default: False. + help_str = "Kill all running SALOME sessions" + o_k = optparse.Option("-k", + "--killall", + action="store_true", + dest="killall", + help=help_str) + + # Additional python interpreters. Default: 0. + help_str = "The number of additional external python interpreters to run. " + help_str += "Each additional python interpreter is run in separate " + help_str += "xterm session with properly set SALOME environment" + o_i = optparse.Option("-i", + "--interp", + metavar="", + type="int", + action="store", + dest="interp", + help=help_str) + + # Splash. Default: True. + help_str = "1 to display splash screen [default], " + help_str += "0 to disable splash screen. " + help_str += "This option is ignored in the terminal mode. " + help_str += "It is also ignored if --show-desktop=0 option is used." + o_z = optparse.Option("-z", + "--splash", + metavar="<1/0>", + #type="choice", choices=boolean_choices, + type="string", + action="callback", callback=store_boolean, callback_args=('splash',), + dest="splash", + help=help_str) + + # Catch exceptions. Default: True. + help_str = "1 (yes,true,on,ok) to enable centralized exception handling [default], " + help_str += "0 (no,false,off,cancel) to disable centralized exception handling." + o_c = optparse.Option("-c", + "--catch-exceptions", + metavar="<1/0>", + #type="choice", choices=boolean_choices, + type="string", + action="callback", callback=store_boolean, callback_args=('catch_exceptions',), + dest="catch_exceptions", + help=help_str) + + # Print free port and exit + help_str = "Print free port and exit" + o_a = optparse.Option("--print-port", + action="store_true", + dest="print_port", default=False, + help=help_str) + + # Do not relink ${HOME}/.omniORB_last.cfg + help_str = "Do not save current configuration ${HOME}/.omniORB_last.cfg" + o_n = optparse.Option("--nosave-config", + action="store_false", + dest="save_config", default=True, + help=help_str) + + # Launch with interactive python console. Default: False. + help_str = "Launch with interactive python console." + o_pi = optparse.Option("--pinter", + action="store_true", + dest="pinter", + help=help_str) + + # Print Naming service port into a user file. Default: False. + help_str = "Print Naming Service Port into a user file." + o_nspl = optparse.Option("--ns-port-log", + metavar="", + type="string", + action="store", + dest="ns_port_log_file", + help=help_str) + + # Write/read test script file with help of TestRecorder. Default: False. + help_str = "Write/read test script file with help of TestRecorder." + o_test = optparse.Option("--test", + metavar="", + type="string", + action="store", + dest="test_script_file", + help=help_str) + + # Reproducing test script with help of TestRecorder. Default: False. + help_str = "Reproducing test script with help of TestRecorder." + o_play = optparse.Option("--play", + metavar="", + type="string", + action="store", + dest="play_script_file", + help=help_str) + + # gdb session + help_str = "Launch session with gdb" + o_gdb = optparse.Option("--gdb-session", + action="store_true", + dest="gdb_session", default=False, + help=help_str) + + # ddd session + help_str = "Launch session with ddd" + o_ddd = optparse.Option("--ddd-session", + action="store_true", + dest="ddd_session", default=False, + help=help_str) + + + # valgrind session + help_str = "Launch session with valgrind $VALGRIND_OPTIONS" + o_valgrind = optparse.Option("--valgrind-session", + action="store_true", + dest="valgrind_session", default=False, + help=help_str) + + # shutdown-servers. Default: False. + help_str = "1 to shutdown standalone servers when leaving python interpreter, " + help_str += "0 to keep the standalone servers as daemon [default]. " + help_str += "This option is only useful in batchmode " + help_str += "(terminal mode or without showing desktop)." + o_shutdown = optparse.Option("--shutdown-servers", + metavar="<1/0>", + #type="choice", choices=boolean_choices, + type="string", + action="callback", callback=store_boolean, callback_args=('shutdown_servers',), + dest="shutdown_servers", + help=help_str) -args["port"] = my_port + # foreground. Default: True. + help_str = "0 and runSalome exits after have launched the gui, " + help_str += "1 to launch runSalome in foreground mode [default]." + o_foreground = optparse.Option("--foreground", + metavar="<1/0>", + #type="choice", choices=boolean_choices, + type="string", + action="callback", callback=store_boolean, callback_args=('foreground',), + dest="foreground", + help=help_str) + + # wake up session + help_str = "Wake up a previously closed session. " + help_str += "The session object is found in the naming service pointed by the variable OMNIORB_CONFIG. " + help_str += "If this variable is not setted, the last configuration is taken. " + o_wake_up = optparse.Option("--wake-up-session", + action="store_true", + dest="wake_up_session", default=False, + help=help_str) + + # All options + opt_list = [o_t,o_g, # GUI/Terminal + o_d,o_o, # Desktop + o_b, # Batch + o_l,o_f, # Use logger or log-file + o_u, # Execute python scripts + o_r, # Configuration XML file + o_x, # xterm + o_m, # Modules + o_e, # Embedded servers + o_s, # Standalone servers + o_p, # Kill with port + o_k, # Kill all + o_i, # Additional python interpreters + o_z, # Splash + o_c, # Catch exceptions + o_a, # Print free port and exit + o_n, # --nosave-config + o_pi, # Interactive python console + o_nspl, + o_test, # Write/read test script file with help of TestRecorder + o_play, # Reproducing test script with help of TestRecorder + o_gdb, + o_ddd, + o_valgrind, + o_shutdown, + o_foreground, + o_wake_up, + ] + + #std_options = ["gui", "desktop", "log_file", "py_scripts", "resources", + # "xterm", "modules", "embedded", "standalone", + # "portkill", "killall", "interp", "splash", + # "catch_exceptions", "print_port", "save_config", "ns_port_log_file"] + + opt_list += theAdditionalOptions + + a_usage = "%prog [options] [STUDY_FILE] [PYTHON_FILE [PYTHON_FILE ...]]" + version_str = "Salome %s" % version() + pars = optparse.OptionParser(usage=a_usage, version=version_str, option_list=opt_list) + + return pars # ----------------------------------------------------------------------------- -### command line options reader - -def options_parser(line): - source = line - list = [] - for delimiter in [" ", ",", "="]: - for o in source: - list += string.split(o, delimiter) - pass - source = list - list = [] - pass +### +# Get the environment +### + +# this attribute is obsolete +args = {} +#def get_env(): +#args = [] +def get_env(theAdditionalOptions=[], appname="SalomeApp"): + ### + # Collect launch configuration files: + # - The environment variable "Config" (SalomeAppConfig) which can + # define a list of directories (separated by ':' or ';' symbol) is checked + # - If the environment variable "Config" is not set, only + # ${GUI_ROOT_DIR}/share/salome/resources/gui is inspected + # - ${GUI_ROOT_DIR}/share/salome/resources/gui directory is always inspected + # so it is not necessary to put it in the "Config" variable + # - The directories which are inspected are checked for files ".xml" + # (SalomeApp.xml) which define SALOME configuration + # - These directories are analyzed beginning from the last one in the list, + # so the first directory listed in "Config" environment variable + # has higher priority: it means that if some configuration options + # is found in the next analyzed cofiguration file - it will be replaced + # - The last configuration file which is parsed is user configuration file + # situated in the home directory: "~/.rc[.]" (~/SalomeApprc.3.2.0) + # (if it exists) + # - Command line options have the highest priority and replace options + # specified in configuration file(s) + ### + + global args + config_var = appname+'Config' - print "source=",source - - result = {} - i = 0 - while i < len(source): - if source[i][0] != '-': - key = None - elif source[i][1] == '-': - key = source[i][2] + separator = ":" + if os.sys.platform == 'win32': + separator = ";" + + # check KERNEL_ROOT_DIR + try: + kernel_root_dir=os.environ["KERNEL_ROOT_DIR"] + except: + print """ + For each SALOME module, the environment variable _ROOT_DIR must be set. + KERNEL_ROOT_DIR is mandatory. + """ + sys.exit(1) + pass + + ############################ + # parse command line options + pars = CreateOptionParser(theAdditionalOptions) + (cmd_opts, cmd_args) = pars.parse_args(sys.argv[1:]) + ############################ + + # Process --print-port option + if cmd_opts.print_port: + from runSalome import searchFreePort + searchFreePort({}) + print "port:%s"%(os.environ['NSPORT']) + sys.exit(0) + pass + + # set resources variable SalomeAppConfig if it is not set yet + dirs = [] + if os.getenv(config_var): + if sys.platform == 'win32': + dirs += re.split(';', os.getenv(config_var)) + else: + dirs += re.split('[;|:]', os.getenv(config_var)) + + gui_available = True + if os.getenv("GUI_ROOT_DIR") and os.path.isdir( os.getenv("GUI_ROOT_DIR") + "/share/salome/resources/gui" ): + dirs += [os.getenv("GUI_ROOT_DIR") + "/share/salome/resources/gui"] + pass else: - key = source[i][1] - pass - - result[key] = [] - if key: - i += 1 - pass - while i < len(source) and source[i][0] != '-': - result[key].append(source[i]) - i += 1 - pass - pass - return result + gui_available = False + if os.getenv("KERNEL_ROOT_DIR") and os.path.isdir( os.getenv("KERNEL_ROOT_DIR") + "/bin/salome/appliskel" ): + dirs += [os.getenv("KERNEL_ROOT_DIR") + "/bin/salome/appliskel"] + pass + os.environ[config_var] = separator.join(dirs) -# ----------------------------------------------------------------------------- + dirs.reverse() # reverse order, like in "path" variable - FILO-style processing -### read command-line options : each arg given in command line supersedes arg from xml config file + try: + dirs.remove('') # to remove empty dirs if the variable terminate by ":" or if there are "::" inside + except: + pass -try: - opts = options_parser(sys.argv[1:]) - print "opts=",opts - kernel_root_dir=os.environ["KERNEL_ROOT_DIR"] -except: - opts["h"] = 1 - pass + _opts = {} # associative array of options to be filled -### check all options are right - -opterror=0 -for opt in opts: - if not opt in ("h","g","l","x","m","e","s","c","p","k","t"): - print "command line error: -", opt - opterror=1 - -if opterror == 1: - opts["h"] = 1 - -if opts.has_key("h"): - print """USAGE: runSalome.py [options] - [command line options] : - --help or -h : print this help - --gui or -g : lancement du GUI - --terminal -t : launching without gui (to deny --gui) - --logger or -l : redirection des messages dans un fichier - --xterm or -x : les serveurs ouvrent une fenêtre xterm et les messages sont affichés dans cette fenêtre - --modules=module1,module2,... : où modulen est le nom d'un module Salome à charger dans le catalogue - or -m=module1,module2,... - --embedded=registry,study,moduleCatalog,cppContainer - or -e=registry,study,moduleCatalog,cppContainer - : serveurs CORBA embarqués (par defaut: registry,study,moduleCatalog,cppContainer) - : (logger,pyContainer,supervContainer ne peuvent pas être embarqués - --standalone=registry,study,moduleCatalog,cppContainer,pyContainer,supervContainer - or -s=registry,study,moduleCatalog,cppContainer,pyContainer,supervContainer - : executables serveurs CORBA indépendants (par défaut: pyContainer,supervContainer) - --containers=cpp,python,superv: (obsolete) lancement des containers cpp, python et de supervision - or -c=cpp,python,superv : = on prend les defauts de -e et -s - --portkill or -p : kill the salome with current port - --killall or -k : kill salome - - La variable d'environnement _ROOT_DIR doit etre préalablement - positionnée (modulen doit etre en majuscule). - KERNEL_ROOT_DIR est obligatoire. - """ - sys.exit(1) - pass + # parse SalomeApp.xml files in directories specified by SalomeAppConfig env variable + for dir in dirs: + #filename = dir+'/'+appname+'.xml' + filename = dir+'/'+salomeappname+'.xml' + if not os.path.exists(filename): + print "Configure parser: Warning : could not find configuration file %s" % filename + else: + try: + p = xml_parser(filename, _opts) + _opts = p.opts + except: + print "Configure parser: Error : can not read configuration file %s" % filename + pass + + # parse user configuration file + # It can be set via --resources= command line option + # or is given by default from ${HOME}/.rc. + # If user file for the current version is not found the nearest to it is used + user_config = cmd_opts.resources + if not user_config: + user_config = userFile(appname) + if not user_config or not os.path.exists(user_config): + print "Configure parser: Warning : could not find user configuration file" + else: + try: + p = xml_parser(user_config, _opts) + _opts = p.opts + except: + print 'Configure parser: Error : can not read user configuration file' + user_config = "" + + args = _opts + + args['user_config'] = user_config + #print "User Configuration file: ", args['user_config'] + + # set default values for options which are NOT set in config files + for aKey in listKeys: + if not args.has_key( aKey ): + args[aKey]=[] + + for aKey in boolKeys: + if not args.has_key( aKey ): + args[aKey]=0 + + if args[file_nam]: + afile=args[file_nam] + args[file_nam]=[afile] + + args[appname_nam] = appname + + # get the port number + my_port = getPortNumber() -### apply command-line options to the arguments -for opt in opts: - if opt == 'g': - args['gui'] = 1 - elif opt == 'l': - args['logger'] = 1 - elif opt == 'x': - args['xterm'] = 1 - elif opt == 'm': - args['modules'] = opts['m'] - elif opt == 'e': - args['embedded'] = opts['e'] - elif opt == 's': - args['standalone'] = opts['s'] - elif opt == 'c': - args['containers'] = opts['c'] - elif opt == 'p': - args['portkill'] = 1 - elif opt == 'k': - args['killall'] = 1 + args[port_nam] = my_port + + #################################################### + # apply command-line options to the arguments + # each option given in command line overrides the option from xml config file + # + # Options: gui, desktop, log_file, py_scripts, resources, + # xterm, modules, embedded, standalone, + # portkill, killall, interp, splash, + # catch_exceptions, pinter + + # GUI/Terminal, Desktop, Splash, STUDY_HDF + args["session_gui"] = False + args[batch_nam] = False + args["study_hdf"] = None + if cmd_opts.gui is not None: + args[gui_nam] = cmd_opts.gui + if cmd_opts.batch is not None: + args[batch_nam] = True + + if not gui_available: + args[gui_nam] = False + + if args[gui_nam]: + args["session_gui"] = True + if cmd_opts.desktop is not None: + args["session_gui"] = cmd_opts.desktop + args[splash_nam] = cmd_opts.desktop + if args["session_gui"]: + if cmd_opts.splash is not None: + args[splash_nam] = cmd_opts.splash + else: + args["session_gui"] = False + args[splash_nam] = False + + # Logger/Log file + if cmd_opts.log_file is not None: + if cmd_opts.log_file == 'CORBA': + args[logger_nam] = True + else: + args[file_nam] = [cmd_opts.log_file] + + # Naming Service port log file + if cmd_opts.ns_port_log_file is not None: + args["ns_port_log_file"] = cmd_opts.ns_port_log_file + + # Python scripts + args[script_nam] = [] + if cmd_opts.py_scripts is not None: + listlist = cmd_opts.py_scripts + for listi in listlist: + if os.sys.platform == 'win32': + args[script_nam] += re.split( "[;,]", listi) + else: + args[script_nam] += re.split( "[:;,]", listi) + for arg in cmd_args: + if arg[-3:] == ".py": + args[script_nam].append(arg) + elif not args["study_hdf"]: + args["study_hdf"] = arg + pass pass - pass -# 'terminal' must be processed in the end: to deny any 'gui' options -if 't' in opts: - args['gui'] = 0 - pass + # xterm + if cmd_opts.xterm is not None: args[xterm_nam] = cmd_opts.xterm + + # Modules + if cmd_opts.modules is not None: + args[modules_nam] = [] + listlist = cmd_opts.modules + for listi in listlist: + args[modules_nam] += re.split( "[:;,]", listi) + else: + # if --modules (-m) command line option is not given + # try SALOME_MODULES environment variable + if os.getenv( "SALOME_MODULES" ): + args[modules_nam] = re.split( "[:;,]", os.getenv( "SALOME_MODULES" ) ) + pass + + # Embedded + if cmd_opts.embedded is not None: + args[embedded_nam] = filter( lambda a: a.strip(), re.split( "[:;,]", cmd_opts.embedded ) ) + + # Standalone + if cmd_opts.standalone is not None: + args[standalone_nam] = filter( lambda a: a.strip(), re.split( "[:;,]", cmd_opts.standalone ) ) + + # Normalize the '--standalone' and '--embedded' parameters + standalone, embedded = process_containers_params( args.get( standalone_nam ), + args.get( embedded_nam ) ) + if standalone is not None: + args[ standalone_nam ] = standalone + if embedded is not None: + args[ embedded_nam ] = embedded + + # Kill + if cmd_opts.portkill is not None: args[portkill_nam] = cmd_opts.portkill + if cmd_opts.killall is not None: args[killall_nam] = cmd_opts.killall + + # Interpreter + if cmd_opts.interp is not None: + args[interp_nam] = cmd_opts.interp + + # Exceptions + if cmd_opts.catch_exceptions is not None: + args[except_nam] = not cmd_opts.catch_exceptions + + # Relink config file + if cmd_opts.save_config is not None: + args['save_config'] = cmd_opts.save_config + + # Interactive python console + if cmd_opts.pinter is not None: + args[pinter_nam] = cmd_opts.pinter + + # Gdb session in xterm + if cmd_opts.gdb_session is not None: + args[gdb_session_nam] = cmd_opts.gdb_session + + # Ddd session in xterm + if cmd_opts.ddd_session is not None: + args[ddd_session_nam] = cmd_opts.ddd_session + + # valgrind session + if cmd_opts.valgrind_session is not None: + args[valgrind_session_nam] = cmd_opts.valgrind_session + + # Shutdown servers + if cmd_opts.shutdown_servers is None: + args[shutdown_servers_nam] = 0 + else: + args[shutdown_servers_nam] = cmd_opts.shutdown_servers + pass + + # Foreground + if cmd_opts.foreground is None: + args[foreground_nam] = 1 + else: + args[foreground_nam] = cmd_opts.foreground + pass + + # wake up session + if cmd_opts.wake_up_session is not None: + args[wake_up_session_nam] = cmd_opts.wake_up_session + + #################################################### + # Add values to args + for add_opt in theAdditionalOptions: + cmd = "args[\"%s\"] = cmd_opts.%s"%(add_opt.dest,add_opt.dest) + exec(cmd) + #################################################### + + # disable signals handling + if args[except_nam] == 1: + os.environ["NOT_INTERCEPT_SIGNALS"] = "1" + pass + + # now modify SalomeAppConfig environment variable + # to take into account the SALOME modules + if os.sys.platform == 'win32': + dirs = re.split('[;]', os.environ[config_var] ) + else: + dirs = re.split('[;|:]', os.environ[config_var] ) + for m in args[modules_nam]: + if m not in ["KERNEL", "GUI", ""] and os.getenv("%s_ROOT_DIR"%m): + d1 = os.getenv("%s_ROOT_DIR"%m) + "/share/salome/resources/" + m.lower() + d2 = os.getenv("%s_ROOT_DIR"%m) + "/share/salome/resources" + #if os.path.exists( "%s/%s.xml"%(d1, appname) ): + if os.path.exists( "%s/%s.xml"%(d1, salomeappname) ): + dirs.append( d1 ) + #elif os.path.exists( "%s/%s.xml"%(d2, appname) ): + elif os.path.exists( "%s/%s.xml"%(d2, salomeappname) ): + dirs.append( d2 ) + + # Test + if cmd_opts.test_script_file is not None: + args[test_nam] = [] + filename = cmd_opts.test_script_file + args[test_nam] += re.split( "[:;,]", filename ) + + # Play + if cmd_opts.play_script_file is not None: + args[play_nam] = [] + filename = cmd_opts.play_script_file + args[play_nam] += re.split( "[:;,]", filename ) -print "args=",args + # return arguments + os.environ[config_var] = separator.join(dirs) + #print "Args: ", args + return args