X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=bin%2FlaunchConfigureParser.py;h=57c492797c978a1bb50f293b790b5fdb32688f70;hb=e72332cd1cce863d7efbdecfb2055b8d9ee0630f;hp=92b5e9aea20eb2a489e9a2341c2dc8018098f060;hpb=e5867636265822b5e70ca0406c9321ccff264bb0;p=modules%2Fkernel.git diff --git a/bin/launchConfigureParser.py b/bin/launchConfigureParser.py index 92b5e9aea..57c492797 100755 --- a/bin/launchConfigureParser.py +++ b/bin/launchConfigureParser.py @@ -1,5 +1,5 @@ # -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2016 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 @@ -7,7 +7,7 @@ # 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. +# version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -26,7 +26,7 @@ import xml.sax import optparse import types -from salome_utils import verbose, setVerbose, getPortNumber, getHomeDir +from salome_utils import verbose, getPortNumber, getHomeDir # names of tags in XML configuration file doc_tag = "document" @@ -60,6 +60,7 @@ pinter_nam = "pinter" batch_nam = "batch" test_nam = "test" play_nam = "play" +lang_nam = "language" gdb_session_nam = "gdb_session" ddd_session_nam = "ddd_session" valgrind_session_nam = "valgrind_session" @@ -74,13 +75,14 @@ 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" +useport_nam = "useport" salomecfgname = "salome" 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"] +standalone_choices = [ "registry", "study", "moduleCatalog", "cppContainer"] # values of boolean type (must be '0' or '1'). # xml_parser.boolValue() is used for correct setting @@ -98,11 +100,13 @@ 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" + version_file = os.path.join(root_dir, 'bin', 'salome', 'VERSION') + if root_dir and os.path.exists( version_file ): + filename = version_file 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" + version_file = os.path.join(root_dir, 'bin', 'salome', 'VERSION') + if root_dir and os.path.exists( version_file ): + filename = version_file 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 ) @@ -119,8 +123,19 @@ def version(): def version_id(fname): major = minor = release = dev1 = dev2 = 0 vers = fname.split(".") - if len(vers) > 0: major = int(vers[0]) - if len(vers) > 1: minor = int(vers[1]) + if len(vers) > 0: + try: + major = int(vers[0]) + except ValueError: + # If salome version given is DEV, the call to int('DEV') will fail with + # a ValueError exception + pass + try: + if len(vers) > 1: minor = int(vers[1]) + except ValueError: + # If salome version given is 7.DEV, the call to int('DEV') will fail with + # a ValueError exception + pass if len(vers) > 2: mr = re.search(r'^([0-9]+)([A-Z]|RC)?([0-9]*)',vers[2], re.I) if mr: @@ -153,18 +168,13 @@ def version_id(fname): ### def defaultUserFile(appname=salomeappname, cfgname=salomecfgname): v = version() - if v: v = ".%s" % v - if sys.platform == "win32": - filename = os.path.join(getHomeDir(), "%s.xml%s" % (appname, v)) - else: - if cfgname: - filename = os.path.join(getHomeDir(), ".config", cfgname, "%src%s" % (appname, v)) - pass - else: - filename = os.path.join(getHomeDir(), ".%src%s" % (appname, v)) - pass - pass - return filename + filetmpl = sys.platform == "win32" and "{0}.xml.{1}" or "{0}rc.{1}" + paths = [] + paths.append(getHomeDir()) + paths.append(".config") + if cfgname: paths.append(cfgname) + paths.append(filetmpl.format(appname, v)) + return os.path.join(*paths) ### # Get user configuration file name @@ -188,19 +198,20 @@ def userFile(appname, cfgname): if not id0: return None # bad version id -> can't detect appropriate file # ... get all existing user preferences files - if sys.platform == "win32": - files = glob.glob(os.path.join(getHomeDir(), "%s.xml.*" % appname)) - else: - files = [] - if cfgname: - # Since v6.6.0 - in ~/.config/salome directory, without dot prefix - files += glob.glob(os.path.join(getHomeDir(), ".config", cfgname, "%src.*" % appname)) - # Since v6.5.0 - in ~/.config/salome directory, dot-prefixed (backward compatibility) - files += glob.glob(os.path.join(getHomeDir(), ".config", cfgname, ".%src.*" % appname)) - pass - # old style (before v6.5.0) - in ~ directory, dot-prefixed - files += glob.glob(os.path.join(getHomeDir(), ".%src.*" % appname)) + filetmpl1 = sys.platform == "win32" and "{0}.xml.*" or "{0}rc.*" + filetmpl2 = sys.platform == "win32" and filetmpl1 or "." + filetmpl1 + files = [] + if cfgname: + # Since v6.6.0 - in ~/.config/salome directory, without dot prefix + files += glob.glob(os.path.join(getHomeDir(), ".config", cfgname, filetmpl1.format(appname))) + # Since v6.5.0 - in ~/.config/salome directory, dot-prefixed (backward compatibility) + if filetmpl2 and filetmpl2 != filetmpl1: + files += glob.glob(os.path.join(getHomeDir(), ".config", cfgname, filetmpl2.format(appname))) pass + # old style (before v6.5.0) - in ~ directory, dot-prefixed + if filetmpl2 and filetmpl2 != filetmpl1: + files += glob.glob(os.path.join(getHomeDir(), filetmpl2.format(appname))) + pass # ... loop through all files and find most appopriate file (with closest id) appr_id = -1 @@ -208,9 +219,9 @@ def userFile(appname, cfgname): for f in files: ff = os.path.basename( f ) if sys.platform == "win32": - match = re.search( r'^%s\.xml\.([a-zA-Z0-9.]+)$'%appname, ff ) + match = re.search( r'^{0}\.xml\.([a-zA-Z0-9.]+)$'.format(appname), ff ) else: - match = re.search( r'^\.?%src\.([a-zA-Z0-9.]+)$'%appname, ff ) + match = re.search( r'^\.?{0}rc\.([a-zA-Z0-9.]+)$'.format(appname), ff ) if match: ver = version_id(match.group(1)) if not ver: continue # bad version id -> skip file @@ -251,7 +262,8 @@ def process_containers_params( standalone, embedded ): section_to_skip = "" class xml_parser: - def __init__(self, fileName, _opts, _importHistory=[] ): + def __init__(self, fileName, _opts, _importHistory): + #warning _importHistory=[] is NOT good: is NOT empty,reinitialized after first call if verbose(): print "Configure parser: processing %s ..." % fileName self.fileName = os.path.abspath(fileName) self.importHistory = _importHistory @@ -298,6 +310,15 @@ class xml_parser: return strloc pass + def strValue( self, str ): + strloc = str + try: + if isinstance(strloc, types.UnicodeType): strloc = strloc.encode().strip() + else: strloc = strloc.strip() + except: + pass + return strloc + def startElement(self, name, attrs): self.space.append(name) self.current = None @@ -310,7 +331,7 @@ class xml_parser: # 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: + if section_name in [lanch_nam, lang_nam]: self.section = section_name # launch section elif self.opts.has_key( modules_nam ) and \ section_name in self.opts[ modules_nam ]: @@ -332,19 +353,20 @@ class xml_parser: key = nam else: # key for section key = self.section + "_" + nam + key = self.strValue( key ) 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: [] + self.opts[key] = [ self.strValue( a ) for a in re.split( "[:;,]", val ) ] # assign list value: [] else: - self.opts[key] = val + self.opts[key] = self.strValue( val ) # string value pass pass def endElement(self, name): - p = self.space.pop() + self.space.pop() self.current = None if self.section != section_to_skip and name == sec_tag: self.section = section_to_skip @@ -475,7 +497,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, exeName=None): + if theAdditionalOptions is None: + theAdditionalOptions = [] # GUI/Terminal. Default: GUI help_str = "Launch without GUI (in the terminal mode)." o_t = optparse.Option("-t", @@ -535,21 +559,6 @@ def CreateOptionParser (theAdditionalOptions=[]): 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: see defaultUserFile() function help_str = "Parse application settings from the " help_str += "instead of default %s" % defaultUserFile() @@ -735,7 +744,8 @@ def CreateOptionParser (theAdditionalOptions=[]): 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", + o_shutdown = optparse.Option("-w", + "--shutdown-servers", metavar="<1/0>", #type="choice", choices=boolean_choices, type="string", @@ -773,12 +783,30 @@ def CreateOptionParser (theAdditionalOptions=[]): dest="server_launch_mode", help=help_str) + # use port + help_str = "Preferable port SALOME to be started on. " + help_str += "If specified port is not busy, SALOME session will start on it; " + help_str += "otherwise, any available port will be searched and used." + o_port = optparse.Option("--port", + metavar="", + type="int", + action="store", + dest="use_port", + help=help_str) + + help_str = "Force application language. By default, a language specified in " + help_str += "the user's preferences is used." + o_lang = optparse.Option("-a", + "--language", + action="store", + dest="language", + 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 @@ -802,16 +830,23 @@ def CreateOptionParser (theAdditionalOptions=[]): o_foreground, o_wake_up, o_slm, # Server launch mode + o_port, # Use port + o_lang, # Language ] - #std_options = ["gui", "desktop", "log_file", "py_scripts", "resources", + #std_options = ["gui", "desktop", "log_file", "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 ...]]" + if not exeName: + exeName = "%prog" + + a_usage = """%s [options] [STUDY_FILE] [PYTHON_FILE [args] [PYTHON_FILE [args]...]] +Python file arguments, if any, must be comma-separated (without blank characters) and prefixed by "args:" (without quotes), e.g. myscript.py args:arg1,arg2=val,... +"""%exeName version_str = "Salome %s" % version() pars = optparse.OptionParser(usage=a_usage, version=version_str, option_list=opt_list) @@ -827,7 +862,7 @@ def CreateOptionParser (theAdditionalOptions=[]): args = {} #def get_env(): #args = [] -def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgname): +def get_env(theAdditionalOptions=None, appname=salomeappname, cfgname=salomecfgname, exeName=None): ### # Collect launch configuration files: # - The environment variable "Config" (SalomeAppConfig) which can @@ -850,27 +885,24 @@ def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgnam # specified in configuration file(s) ### + if theAdditionalOptions is None: + theAdditionalOptions = [] + global args config_var = appname+'Config' - separator = ":" - if os.sys.platform == 'win32': - 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 _ROOT_DIR must be set. KERNEL_ROOT_DIR is mandatory. """ sys.exit(1) - pass ############################ # parse command line options - pars = CreateOptionParser(theAdditionalOptions) + pars = CreateOptionParser(theAdditionalOptions, exeName=exeName) (cmd_opts, cmd_args) = pars.parse_args(sys.argv[1:]) ############################ @@ -879,6 +911,13 @@ def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgnam from searchFreePort import searchFreePort searchFreePort({}) print "port:%s"%(os.environ['NSPORT']) + + try: + import PortManager + PortManager.releasePort(os.environ['NSPORT']) + except ImportError: + pass + sys.exit(0) pass @@ -886,20 +925,23 @@ def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgnam dirs = [] if os.getenv(config_var): if sys.platform == 'win32': - dirs += re.split(';', os.getenv(config_var)) + dirs += re.split(os.pathsep, 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"] + gui_available = False + if os.getenv("GUI_ROOT_DIR"): + gui_resources_dir = os.path.join(os.getenv("GUI_ROOT_DIR"),'share','salome','resources','gui') + if os.path.isdir( gui_resources_dir ): + gui_available = True + dirs.append(gui_resources_dir) pass - else: - 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"] + if not gui_available: + kernel_resources_dir = os.path.join(os.getenv("KERNEL_ROOT_DIR"),'bin','salome','appliskel') + if os.getenv("KERNEL_ROOT_DIR") and os.path.isdir( kernel_resources_dir ): + dirs.append(kernel_resources_dir) pass - os.environ[config_var] = separator.join(dirs) + os.environ[config_var] = os.pathsep.join(dirs) dirs.reverse() # reverse order, like in "path" variable - FILO-style processing @@ -917,7 +959,7 @@ def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgnam if verbose(): print "Configure parser: Warning : can not find configuration file %s" % filename else: try: - p = xml_parser(filename, _opts) + p = xml_parser(filename, _opts, []) _opts = p.opts except: if verbose(): print "Configure parser: Error : can not read configuration file %s" % filename @@ -935,7 +977,7 @@ def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgnam if verbose(): print "Configure parser: Warning : can not find user configuration file" else: try: - p = xml_parser(user_config, _opts) + p = xml_parser(user_config, _opts, []) _opts = p.opts except: if verbose(): print 'Configure parser: Error : can not read user configuration file' @@ -949,15 +991,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 @@ -970,7 +1012,7 @@ def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgnam # 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, + # Options: gui, desktop, log_file, resources, # xterm, modules, embedded, standalone, # portkill, killall, interp, splash, # catch_exceptions, pinter @@ -1010,22 +1052,21 @@ def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgnam 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) + # Study files for arg in cmd_args: - if arg[-3:] == ".py": - args[script_nam].append(arg) - elif not args["study_hdf"]: + if arg[-4:] == ".hdf" and not args["study_hdf"]: args["study_hdf"] = arg - pass - pass + + # Python scripts + from salomeContextUtils import getScriptsAndArgs, ScriptAndArgs + args[script_nam] = getScriptsAndArgs(cmd_args) + if args[gui_nam] and args["session_gui"]: + new_args = [] + for sa_obj in args[script_nam]: # args[script_nam] is a list of ScriptAndArgs objects + script = re.sub(r'^python.*\s+', r'', sa_obj.script) + new_args.append(ScriptAndArgs(script=script, args=sa_obj.args, out=sa_obj.out)) + # + args[script_nam] = new_args # xterm if cmd_opts.xterm is not None: args[xterm_nam] = cmd_opts.xterm @@ -1112,7 +1153,7 @@ def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgnam #################################################### # Add values to args for add_opt in theAdditionalOptions: - cmd = "args[\"%s\"] = cmd_opts.%s"%(add_opt.dest,add_opt.dest) + cmd = "args[\"{0}\"] = cmd_opts.{0}".format(add_opt.dest) exec(cmd) #################################################### @@ -1127,16 +1168,19 @@ def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgnam 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" + for module in args[modules_nam]: + if module not in ["KERNEL", "GUI", ""] and os.getenv("{0}_ROOT_DIR".format(module)): + d1 = os.path.join(os.getenv("{0}_ROOT_DIR".format(module)),"share","salome","resources",module.lower()) + d2 = os.path.join(os.getenv("{0}_ROOT_DIR".format(module)),"share","salome","resources") #if os.path.exists( "%s/%s.xml"%(d1, appname) ): - if os.path.exists( "%s/%s.xml"%(d1, salomeappname) ): + if os.path.exists( os.path.join(d1,"{0}.xml".format(salomeappname)) ): dirs.append( d1 ) #elif os.path.exists( "%s/%s.xml"%(d2, appname) ): - elif os.path.exists( "%s/%s.xml"%(d2, salomeappname) ): + elif os.path.exists( os.path.join(d2,"{0}.xml".format(salomeappname)) ): dirs.append( d2 ) + else: + #print "* '"+m+"' should be deleted from ",args[modules_nam] + pass # Test if cmd_opts.test_script_file is not None: @@ -1152,9 +1196,25 @@ def get_env(theAdditionalOptions=[], appname=salomeappname, cfgname=salomecfgnam # Server launch command if cmd_opts.server_launch_mode is not None: - args["server_launch_mode"] = cmd_opts.server_launch_mode + args["server_launch_mode"] = cmd_opts.server_launch_mode + + # Server launch command + if cmd_opts.use_port is not None: + min_port = 2810 + max_port = min_port + 100 + if cmd_opts.use_port not in xrange(min_port, max_port+1): + print "Error: port number should be in range [%d, %d])" % (min_port, max_port) + sys.exit(1) + args[useport_nam] = cmd_opts.use_port + + if cmd_opts.language is not None: + langs = args["language_languages"] if "language_languages" in args else [] + if cmd_opts.language not in langs: + print "Error: unsupported language: %s" % cmd_opts.language + sys.exit(1) + args[lang_nam] = cmd_opts.language # return arguments - os.environ[config_var] = separator.join(dirs) + os.environ[config_var] = os.pathsep.join(dirs) #print "Args: ", args return args