Salome HOME
Restructuration des fonctions de gestion de l'environnement
[tools/sat.git] / src / fileEnviron.py
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 #  Copyright (C) 2010-2013  CEA/DEN
4 #
5 #  This library is free software; you can redistribute it and/or
6 #  modify it under the terms of the GNU Lesser General Public
7 #  License as published by the Free Software Foundation; either
8 #  version 2.1 of the License.
9 #
10 #  This library is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 #  Lesser General Public License for more details.
14 #
15 #  You should have received a copy of the GNU Lesser General Public
16 #  License along with this library; if not, write to the Free Software
17 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18
19 import os
20 import pprint as PP
21 import src.debug as DBG
22 import src.architecture
23 import src.environment
24
25 def get_file_environ(output, shell, environ=None):
26     """Instantiate correct FileEnvironment sub-class.
27     
28     :param output file: the output file stream.
29     :param shell str: the type of shell syntax to use.
30     :param environ dict: a potential additional environment.
31     """
32     if environ == None:
33         environ=src.environment.Environ({})
34     if shell == "bash":
35         return BashFileEnviron(output, environ)
36     if shell == "bat":
37         return BatFileEnviron(output, environ)
38     if shell == "cfgForPy":
39         return LauncherFileEnviron(output, environ)
40     if shell == "cfg":
41         return ContextFileEnviron(output, environ)
42     raise Exception("FileEnviron: Unknown shell = %s" % shell)
43
44 class FileEnviron(object):
45     """\
46     Base class for shell environment
47     """
48     def __init__(self, output, environ=None):
49         """\
50         Initialization
51         
52         :param output file: the output file stream.
53         :param environ dict: SalomeEnviron.
54         """
55         self._do_init(output, environ)
56
57     def __repr__(self):
58         """\
59         easy non exhaustive quick resume for debug print"""
60         res = {
61           "output" : self.output,
62           "environ" : self.environ,
63         }
64         return "%s(\n%s\n)" % (self.__class__.__name__, PP.pformat(res))
65         
66
67     def _do_init(self, output, environ=None):
68         """\
69         Initialization
70         
71         :param output file: the output file stream.
72         :param environ dict: a potential additional environment.
73         """
74         self.output = output
75         self.init_path=True # by default we initialise all paths, except PATH
76         if environ is not None:
77             self.environ = environ
78         else:
79             self.environ = src.environment.Environ({})
80
81     def add_line(self, number):
82         """\
83         Add some empty lines in the shell file
84         
85         :param number int: the number of lines to add
86         """
87         self.output.write("\n" * number)
88
89     def add_comment(self, comment):
90         """\
91         Add a comment in the shell file
92         
93         :param comment str: the comment to add
94         """
95         self.output.write("# %s\n" % comment)
96
97     def add_echo(self, text):
98         """\
99         Add a "echo" in the shell file
100         
101         :param text str: the text to echo
102         """
103         self.output.write('echo %s"\n' % text)
104
105     def add_warning(self, warning):
106         """\
107         Add a warning "echo" in the shell file
108         
109         :param warning str: the text to echo
110         """
111         self.output.write('echo "WARNING %s"\n' % warning)
112
113     def append_value(self, key, value, sep=os.pathsep):
114         """\
115         append value to key using sep,
116         if value contains ":" or ";" then raise error
117
118         :param key str: the environment variable to append
119         :param value str: the value to append to key
120         :param sep str: the separator string
121         """
122         # check that value so no contain the system separator
123         separator=os.pathsep
124         if separator in value:
125             raise Exception("FileEnviron append key '%s' value '%s' contains forbidden character '%s'" % (key, value, separator))
126         do_append=True
127         if self.environ.is_defined(key):
128             value_list = self.environ.get(key).split(sep)
129             if self.environ._expandvars(value) in value_list:
130                 do_append=False  # value is already in key path : we don't append it again
131                 #print "\nCNC append_value value is already set!! key=%s, val=%s value_list=%s\n" % (key,self.environ._expandvars(value), value_list)
132             
133         if do_append:
134             self.environ.append_value(key, value,sep)
135             self.set(key, self.get(key) + sep + value)
136
137     def append(self, key, value, sep=os.pathsep):
138         """\
139         Same as append_value but the value argument can be a list
140         
141         :param key str: the environment variable to append
142         :param value str or list: the value(s) to append to key
143         :param sep str: the separator string
144         """
145         if isinstance(value, list):
146             for v in value:
147                 self.append_value(key, v, sep)
148         else:
149             self.append_value(key, value, sep)
150
151     def prepend_value(self, key, value, sep=os.pathsep):
152         """\
153         prepend value to key using sep,
154         if value contains ":" or ";" then raise error
155         
156         :param key str: the environment variable to prepend
157         :param value str: the value to prepend to key
158         :param sep str: the separator string
159         """
160         # check that value so no contain the system separator
161         separator=os.pathsep
162         if separator in value:
163             raise Exception("FileEnviron append key '%s' value '%s' contains forbidden character '%s'" % (key, value, separator))
164
165         do_not_prepend=False
166         if self.environ.is_defined(key):
167             value_list = self.environ.get(key).split(sep)
168             exp_val=self.environ._expandvars(value)
169             if exp_val in value_list:
170                 do_not_prepend=True
171                 #print "\nCNC prepend_value value is already set!! key=%s, val=%s value_list=%s\n" % (key,exp_val, value_list)
172         if not do_not_prepend:
173             self.environ.prepend_value(key, value,sep)
174             self.set(key, value + sep + self.get(key))
175
176     def prepend(self, key, value, sep=os.pathsep):
177         """\
178         Same as prepend_value but the value argument can be a list
179         
180         :param key str: the environment variable to prepend
181         :param value str or list: the value(s) to prepend to key
182         :param sep str: the separator string
183         """
184         if isinstance(value, list):
185             for v in reversed(value): # prepend list, first item at last to stay first
186                 self.prepend_value(key, v, sep)
187         else:
188             self.prepend_value(key, value, sep)
189
190     def is_defined(self, key):
191         """\
192         Check if the key exists in the environment
193         
194         :param key str: the environment variable to check
195         """
196         return self.environ.is_defined(key)
197
198     def set(self, key, value):
199         """\
200         Set the environment variable 'key' to value 'value'
201         
202         :param key str: the environment variable to set
203         :param value str: the value
204         """
205         raise NotImplementedError("set is not implement for this shell!")
206
207     def get(self, key):
208         """\
209         Get the value of the environment variable "key"
210         
211         :param key str: the environment variable
212         """
213         return '${%s}' % key
214
215     def get_value(self, key):
216         """Get the real value of the environment variable "key"
217         It can help env scripts
218         :param key str: the environment variable
219         """
220         return self.environ.get_value(key)
221
222     def finish(self):
223         """Add a final instruction in the out file (in case of file generation)
224         
225         :param required bool: Do nothing if required is False
226         """
227         return
228
229     def set_no_init_path(self):
230         """Set the no initialisation mode for all paths.
231            By default only PATH is not reinitialised. All others paths are
232            (LD_LIBRARY_PATH, PYTHONPATH, ...)
233            After the call to these function ALL PATHS ARE NOT REINITIALISED.
234            There initial value is inherited from the environment
235         """
236         self.init_path=False
237
238     def value_filter(self, value):
239         res=value
240         # on windows platform, replace / by \
241         if src.architecture.is_windows():
242             res = value.replace("/","\\")
243         return res
244
245
246 class BashFileEnviron(FileEnviron):
247     """\
248     Class for bash shell.
249     """
250     def __init__(self, output, environ=None):
251         """Initialization
252         
253         :param output file: the output file stream.
254         :param environ dict: a potential additional environment.
255         """
256         self._do_init(output, environ)
257         self.output.write(bash_header)
258
259     def set(self, key, value):
260         """Set the environment variable "key" to value "value"
261         
262         :param key str: the environment variable to set
263         :param value str: the value
264         """
265         self.output.write('export %s="%s"\n' % (key, value))
266         self.environ.set(key, value)
267         
268
269         
270 class BatFileEnviron(FileEnviron):
271     """\
272     for Windows batch shell.
273     """
274     def __init__(self, output, environ=None):
275         """Initialization
276         
277         :param output file: the output file stream.
278         :param environ dict: a potential additional environment.
279         """
280         self._do_init(output, environ)
281         self.output.write(bat_header)
282
283     def add_comment(self, comment):
284         """Add a comment in the shell file
285         
286         :param comment str: the comment to add
287         """
288         self.output.write("rem %s\n" % comment)
289     
290     def get(self, key):
291         """Get the value of the environment variable "key"
292         
293         :param key str: the environment variable
294         """
295         return '%%%s%%' % key
296     
297     def set(self, key, value):
298         """Set the environment variable "key" to value "value"
299         
300         :param key str: the environment variable to set
301         :param value str: the value
302         """
303         self.output.write('set %s=%s\n' % (key, self.value_filter(value)))
304         self.environ.set(key, value)
305
306
307 class ContextFileEnviron(FileEnviron):
308     """Class for a salome context configuration file.
309     """
310     def __init__(self, output, environ=None):
311         """Initialization
312         
313         :param output file: the output file stream.
314         :param environ dict: a potential additional environment.
315         """
316         self._do_init(output, environ)
317         self.output.write(cfg_header)
318
319     def set(self, key, value):
320         """Set the environment variable "key" to value "value"
321         
322         :param key str: the environment variable to set
323         :param value str: the value
324         """
325         self.output.write('%s="%s"\n' % (key, value))
326         self.environ.set(key, value)
327
328     def get(self, key):
329         """Get the value of the environment variable "key"
330         
331         :param key str: the environment variable
332         """
333         return '%({0})s'.format(key)
334
335     def add_echo(self, text):
336         """Add a comment
337         
338         :param text str: the comment to add
339         """
340         self.add_comment(text)
341
342     def add_warning(self, warning):
343         """Add a warning
344         
345         :param text str: the warning to add
346         """
347         self.add_comment("WARNING %s"  % warning)
348
349     def prepend_value(self, key, value, sep=os.pathsep):
350         """prepend value to key using sep
351         
352         :param key str: the environment variable to prepend
353         :param value str: the value to prepend to key
354         :param sep str: the separator string
355         """
356         do_append=True
357         if self.environ.is_defined(key):
358             value_list = self.environ.get(key).split(sep)
359             #value cannot be expanded (unlike bash/bat case) - but it doesn't matter.
360             if value in value_list:
361                 do_append=False  # value is already in key path : we don't append it again
362             
363         if do_append:
364             self.environ.append_value(key, value,sep)
365             self.output.write('ADD_TO_%s: %s\n' % (key, value))
366
367     def append_value(self, key, value, sep=os.pathsep):
368         """append value to key using sep
369         
370         :param key str: the environment variable to append
371         :param value str: the value to append to key
372         :param sep str: the separator string
373         """
374         self.prepend_value(key, value)
375
376
377 class LauncherFileEnviron(FileEnviron):
378     """\
379     Class to generate a launcher file script 
380     (in python syntax) SalomeContext API
381     """
382     def __init__(self, output, environ=None):
383         """Initialization
384         
385         :param output file: the output file stream.
386         :param environ dict: a potential additional environment.
387         """
388         self._do_init(output, environ)
389         self.python_version=self.environ.get("sat_python_version")
390         self.bin_kernel_root_dir=self.environ.get("sat_bin_kernel_install_dir")
391         self.app_root_dir=self.environ.get("sat_app_root_dir")
392
393         # four whitespaces for first indentation in a python script
394         self.indent="    "
395         self.prefix="context."
396         self.setVarEnv="setVariable"
397         self.begin=self.indent+self.prefix
398
399         # write the begining of launcher file.
400         # choose the template version corresponding to python version 
401         # and substitute BIN_KERNEL_INSTALL_DIR (the path to salomeContext.py)
402         if self.python_version == 2:
403             launcher_header=launcher_header2
404         else:
405             launcher_header=launcher_header3
406         self.output.write(launcher_header\
407                           .replace("BIN_KERNEL_INSTALL_DIR", self.bin_kernel_root_dir))
408
409         # for these path, we use specialired functions in salomeContext api
410         self.specialKeys={"PATH": "Path",
411                           "LD_LIBRARY_PATH": "LdLibraryPath",
412                           "PYTHONPATH": "PythonPath"}
413
414         # we do not want to reinitialise PATH.
415         # for that we make sure PATH is in self.environ
416         # and therefore we will not use setVariable for PATH
417         if not self.environ.is_defined("PATH"):
418             self.environ.set("PATH","")
419
420
421     def add_echo(self, text):
422         """Add a comment
423         
424         :param text str: the comment to add
425         """
426         self.output.write('# %s"\n' % text)
427
428     def add_warning(self, warning):
429         """Add a warning
430         
431         :param text str: the warning to add
432         """
433         self.output.write('# "WARNING %s"\n' % warning)
434
435     def append_value(self, key, value, sep=":"):
436         """append value to key using sep,
437         if value contains ":" or ";" then raise error
438         
439         :param key str: the environment variable to append
440         :param value str: the value to append to key
441         :param sep str: the separator string
442         """
443         # append is not defined in context api
444         self.prepend_value(key, value)
445
446     def append(self, key, value, sep=":"):
447         """Same as append_value but the value argument can be a list
448         
449         :param key str: the environment variable to append
450         :param value str or list: the value(s) to append to key
451         :param sep str: the separator string
452         """
453         if isinstance(value, list):
454             for v in value:
455                 self.append_value(key, v, sep)
456         else:
457             self.append_value(key, value, sep)
458
459     def prepend_value(self, key, value, sep=os.pathsep):
460         """prepend value to key using sep,
461         if value contains ":" or ";" then raise error
462         
463         :param key str: the environment variable to prepend
464         :param value str: the value to prepend to key
465         :param sep str: the separator string
466         """
467         # check that value so no contain the system separator
468         separator=os.pathsep
469         msg="LauncherFileEnviron append key '%s' value '%s' contains forbidden character '%s'"
470         if separator in value:
471             raise Exception(msg % (key, value, separator))
472
473         if (self.init_path and (not self.environ.is_defined(key))):
474             # reinitialisation mode set to true (the default)
475             # for the first occurrence of key, we set it.
476             # therefore key will not be inherited from environment
477             self.set(key, value)
478             return
479         # in all other cases we use append (except if value is already the key
480         do_append=True
481         if self.environ.is_defined(key):
482             value_list = self.environ.get(key).split(sep)
483             # rem : value cannot be expanded (unlike bash/bat case) - but it doesn't matter.
484             if value in value_list:
485                 do_append=False  # value is already in key path : we don't append it again
486             
487         if do_append:
488             self.environ.append_value(key, value,sep) # register value in self.environ
489             if key in self.specialKeys.keys():
490                 #for these special keys we use the specific salomeContext function
491                 self.output.write(self.begin+'addTo%s(r"%s")\n' % 
492                                   (self.specialKeys[key], self.value_filter(value)))
493             else:
494                 # else we use the general salomeContext addToVariable function
495                 self.output.write(self.begin+'addToVariable(r"%s", r"%s",separator="%s")\n' 
496                                   % (key, self.value_filter(value), sep))
497             
498
499     def prepend(self, key, value, sep=":"):
500         """Same as prepend_value but the value argument can be a list
501         
502         :param key str: the environment variable to prepend
503         :param value str or list: the value(s) to prepend to key
504         :param sep str: the separator string
505         """
506         if isinstance(value, list):
507             for v in value:
508                 self.prepend_value(key, v, sep)
509         else:
510             self.prepend_value(key, value, sep)
511
512
513     def set(self, key, value):
514         """Set the environment variable "key" to value "value"
515         
516         :param key str: the environment variable to set
517         :param value str: the value
518         """
519         self.output.write(self.begin+self.setVarEnv+
520                           '(r"%s", r"%s", overwrite=True)\n' % 
521                           (key, self.value_filter(value)))
522         self.environ.set(key,value)
523     
524
525     def add_comment(self, comment):
526         # Special comment in case of the distène licence
527         if comment=="DISTENE license":
528             self.output.write(self.indent+
529                               "#"+
530                               self.prefix+
531                               self.setVarEnv+
532                               '(r"%s", r"%s", overwrite=True)\n' % 
533                               ('DISTENE_LICENSE_FILE', 'Use global envvar: DLIM8VAR'))
534             self.output.write(self.indent+
535                               "#"+
536                               self.prefix+
537                               self.setVarEnv+
538                               '(r"%s", r"%s", overwrite=True)\n' % 
539                               ('DLIM8VAR', '<your licence>'))
540             return
541         if "setting environ for" in comment:
542             self.output.write(self.indent+"#[%s]\n" % 
543                               comment.split("setting environ for ")[1])
544             return
545
546         self.output.write(self.indent+"# %s\n" % comment)
547
548     def finish(self):
549         """\
550         Add a final instruction in the out file (in case of file generation)
551         In the particular launcher case, do nothing
552         
553         :param required bool: Do nothing if required is False
554         """
555         if self.python_version == 2:
556             launcher_tail=launcher_tail_py2
557         else:
558             launcher_tail=launcher_tail_py3
559         self.output.write(launcher_tail)
560         return
561
562 class ScreenEnviron(FileEnviron):
563     def __init__(self, output, environ=None):
564         self._do_init(output, environ)
565         self.defined = {}
566
567     def add_line(self, number):
568         pass
569
570     def add_comment(self, comment):
571         pass
572
573     def add_echo(self, text):
574         pass
575
576     def add_warning(self, warning):
577         pass
578
579     def write(self, command, name, value, sign="="):
580         import src
581         self.output.write("  %s%s %s %s %s\n" % \
582             (src.printcolors.printcLabel(command),
583              " " * (12 - len(command)),
584              src.printcolors.printcInfo(name), sign, value))
585
586     def is_defined(self, name):
587         return name in self.defined
588
589     def get(self, name):
590         return "${%s}" % name
591
592     def set(self, name, value):
593         self.write("set", name, value)
594         self.defined[name] = value
595
596     def prepend(self, name, value, sep=":"):
597         if isinstance(value, list):
598             value = sep.join(value)
599         value = value + sep + self.get(name)
600         self.write("prepend", name, value)
601
602     def append(self, name, value, sep=":"):
603         if isinstance(value, list):
604             value = sep.join(value)
605         value = self.get(name) + sep + value
606         self.write("append", name, value)
607
608     def run_env_script(self, module, script):
609         self.write("load", script, "", sign="")
610
611
612 #
613 #  Headers
614 #
615 bat_header="""\
616 @echo off
617
618 rem The following variables are used only in case of a sat package
619 set out_dir_Path=%~dp0
620 """
621
622
623 bash_header="""\
624 #!/bin/bash
625 ##########################################################################
626 #
627 # This line is used only in case of a sat package
628 export out_dir_Path=$(cd $(dirname ${BASH_SOURCE[0]});pwd)
629
630 ###########################################################################
631 """
632
633 cfg_header="""\
634 [SALOME Configuration]
635 """
636
637 launcher_header2="""\
638 #! /usr/bin/env python
639
640 ################################################################
641 # WARNING: this file is automatically generated by SalomeTools #
642 # WARNING: and so could be overwritten at any time.            #
643 ################################################################
644
645 import os
646 import sys
647 import subprocess
648
649
650 # Add the pwdPath to able to run the launcher after unpacking a package
651 # Used only in case of a salomeTools package
652 out_dir_Path=os.path.dirname(os.path.realpath(__file__))
653
654 # Preliminary work to initialize path to SALOME Python modules
655 def __initialize():
656
657   sys.path[:0] = [ 'BIN_KERNEL_INSTALL_DIR' ]  # to get salomeContext
658   
659   # define folder to store omniorb config (initially in virtual application folder)
660   try:
661     from salomeContextUtils import setOmniOrbUserPath
662     setOmniOrbUserPath()
663   except Exception as e:
664     print(e)
665     sys.exit(1)
666 # End of preliminary work
667
668 # salome doc only works for virtual applications. Therefore we overwrite it with this function
669 def _showDoc(modules):
670     for module in modules:
671       modulePath = os.getenv(module+"_ROOT_DIR")
672       if modulePath != None:
673         baseDir = os.path.join(modulePath, "share", "doc", "salome")
674         docfile = os.path.join(baseDir, "gui", module.upper(), "index.html")
675         if not os.path.isfile(docfile):
676           docfile = os.path.join(baseDir, "tui", module.upper(), "index.html")
677         if not os.path.isfile(docfile):
678           docfile = os.path.join(baseDir, "dev", module.upper(), "index.html")
679         if os.path.isfile(docfile):
680           out, err = subprocess.Popen(["xdg-open", docfile]).communicate()
681         else:
682           print "Online documentation is not accessible for module:", module
683       else:
684         print module+"_ROOT_DIR not found!"
685
686 def main(args):
687   # Identify application path then locate configuration files
688   __initialize()
689
690   if args == ['--help']:
691     from salomeContext import usage
692     usage()
693     sys.exit(0)
694
695   #from salomeContextUtils import getConfigFileNames
696   #configFileNames, args, unexisting = getConfigFileNames( args, checkExistence=True )
697   #if len(unexisting) > 0:
698   #  print "ERROR: unexisting configuration file(s): " + ', '.join(unexisting)
699   #  sys.exit(1)
700
701   # Create a SalomeContext which parses configFileNames to initialize environment
702   try:
703     from salomeContext import SalomeContext, SalomeContextException
704     context = SalomeContext(None)
705     
706     # Here set specific variables, if needed
707     # context.addToPath('mypath')
708     # context.addToLdLibraryPath('myldlibrarypath')
709     # context.addToPythonPath('mypythonpath')
710     # context.setVariable('myvarname', 'value')
711
712     # Logger level error
713     context.getLogger().setLevel(40)
714 """
715
716 launcher_header3="""\
717 #! /usr/bin/env python3
718
719 ################################################################
720 # WARNING: this file is automatically generated by SalomeTools #
721 # WARNING: and so could be overwritten at any time.            #
722 ################################################################
723
724 import os
725 import sys
726 import subprocess
727
728
729 # Add the pwdPath to able to run the launcher after unpacking a package
730 # Used only in case of a salomeTools package
731 out_dir_Path=os.path.dirname(os.path.realpath(__file__))
732
733 # Preliminary work to initialize path to SALOME Python modules
734 def __initialize():
735
736   sys.path[:0] = [ 'BIN_KERNEL_INSTALL_DIR' ]
737   
738   # define folder to store omniorb config (initially in virtual application folder)
739   try:
740     from salomeContextUtils import setOmniOrbUserPath
741     setOmniOrbUserPath()
742   except Exception as e:
743     print(e)
744     sys.exit(1)
745 # End of preliminary work
746
747 # salome doc only works for virtual applications. Therefore we overwrite it with this function
748 def _showDoc(modules):
749     for module in modules:
750       modulePath = os.getenv(module+"_ROOT_DIR")
751       if modulePath != None:
752         baseDir = os.path.join(modulePath, "share", "doc", "salome")
753         docfile = os.path.join(baseDir, "gui", module.upper(), "index.html")
754         if not os.path.isfile(docfile):
755           docfile = os.path.join(baseDir, "tui", module.upper(), "index.html")
756         if not os.path.isfile(docfile):
757           docfile = os.path.join(baseDir, "dev", module.upper(), "index.html")
758         if os.path.isfile(docfile):
759           out, err = subprocess.Popen(["xdg-open", docfile]).communicate()
760         else:
761           print("Online documentation is not accessible for module:", module)
762       else:
763         print(module+"_ROOT_DIR not found!")
764
765 def main(args):
766   # Identify application path then locate configuration files
767   __initialize()
768
769   if args == ['--help']:
770     from salomeContext import usage
771     usage()
772     sys.exit(0)
773
774   #from salomeContextUtils import getConfigFileNames
775   #configFileNames, args, unexisting = getConfigFileNames( args, checkExistence=True )
776   #if len(unexisting) > 0:
777   #  print("ERROR: unexisting configuration file(s): " + ', '.join(unexisting))
778   #  sys.exit(1)
779
780   # Create a SalomeContext which parses configFileNames to initialize environment
781   try:
782     from salomeContext import SalomeContext, SalomeContextException
783     context = SalomeContext(None)
784     
785     # Here set specific variables, if needed
786     # context.addToPath('mypath')
787     # context.addToLdLibraryPath('myldlibrarypath')
788     # context.addToPythonPath('mypythonpath')
789     # context.setVariable('myvarname', 'value')
790
791     # Logger level error
792     context.getLogger().setLevel(40)
793 """
794
795 launcher_tail_py2="""\
796     if len(args) >1 and args[0]=='doc':
797         _showDoc(args[1:])
798         return
799
800     # Start SALOME, parsing command line arguments
801     out, err, status = context.runSalome(args)
802     sys.exit(status)
803
804   except SalomeContextException, e:
805     import logging
806     logging.getLogger("salome").error(e)
807     sys.exit(1)
808 #
809
810 if __name__ == "__main__":
811   args = sys.argv[1:]
812   main(args)
813 #
814 """
815
816 launcher_tail_py3="""\
817     if len(args) >1 and args[0]=='doc':
818         _showDoc(args[1:])
819         return
820
821     # Start SALOME, parsing command line arguments
822     out, err, status = context.runSalome(args)
823     sys.exit(status)
824
825   except SalomeContextException as e:
826     import logging
827     logging.getLogger("salome").error(e)
828     sys.exit(1)
829 #
830
831 if __name__ == "__main__":
832   args = sys.argv[1:]
833   main(args)
834 #
835 """
836     
837