v = pattern.sub(r':', v) # remove matching patterns
return v
#
-
-# This class is used to parse .sh environment file
-# It deals with specific treatments:
-# - virtually add a section to configuration file
-# - process shell keywords (if, then...)
-class EnvFileConverter(object):
- def __init__(self, fp, section_name, reserved = None, outputFile=None):
- if reserved is None:
- reserved = []
- self.fp = fp
- self.sechead = '[' + section_name + ']\n'
- self.reserved = reserved
- self.outputFile = outputFile
- self.allParsedVariableNames = []
- # exclude line that begin with:
- self.exclude = [ 'if', 'then', 'else', 'fi', '#', 'echo', 'exit' ]
- self.exclude.append('$gconfTool') # QUICK FIX :TODO: provide method to extend this variable
- # discard the following keywords if at the beginning of line:
- self.discard = [ 'export' ]
- # the following keywords imply a special processing if at the beginning of line:
- self.special = [ 'unset' ]
-
- def readline(self):
- if self.sechead:
- try:
- if self.outputFile is not None:
- self.outputFile.write(self.sechead)
- return self.sechead
- finally:
- self.sechead = None
- else:
- line = self.fp.readline()
- # trim whitespaces
- line = line.strip(' \t\n\r')
- # line of interest? (not beginning by a keyword of self.exclude)
- for k in self.exclude:
- if line.startswith(k):
- return '\n'
- # look for substrinsg beginning with sharp charcter ('#')
- line = re.sub(r'#.*$', r'', line)
- # line to be pre-processed? (beginning by a keyword of self.special)
- for k in self.special:
- if k == "unset" and line.startswith(k):
- line = line[len(k):]
- line = line.strip(' \t\n\r')
- line = UNSET_KEYWORD + ": " + line
- # line to be pre-processed? (beginning by a keyword of self.discard)
- for k in self.discard:
- if line.startswith(k):
- line = line[len(k):]
- line = line.strip(' \t\n\r')
- # process reserved keywords
- for k in self.reserved:
- if line.startswith(k) and "=" in line:
- variable, value = line.split('=')
- value = self._purgeValue(value, k)
- line = ADD_TO_PREFIX + k + ": " + value
- # Update list of variable names
- # :TODO: define excludeBlock variable (similar to exclude) and provide method to extend it
- if "cleandup()" in line:
- print "WARNING: parseConfigFile.py: skip cleandup and look for '# PRODUCT environment'"
- while True:
- line = self.fp.readline()
- if "# PRODUCT environment" in line:
- print "WARNING: parseConfigFile.py: '# PRODUCT environment' found"
- break
- while "clean " in line[0:6]: #skip clean calls with ending ";" crash
- line = self.fp.readline()
- # Extract variable=value
- if "=" in line:
- try:
- variable, value = line.split('=')
- except: #avoid error for complicated sh line xx=`...=...`, but warning
- print "WARNING: parseConfigFile.py: line with multiples '=' character are hazardous: '"+line+"'"
- variable, value = line.split('=',1)
- pass
-
- # Self-extending variables that are not in reserved keywords
- # Example: FOO=something:${FOO}
- # In this case, remove the ${FOO} in value
- if variable in value:
- value = self._purgeValue(value, variable)
- line = "%s=%s"%(variable,value)
-
- self.allParsedVariableNames.append(variable)
- # End of extraction
-
- if not line:
- return line
-
- #
- # replace "${FOO}" and "$FOO" and ${FOO} and $FOO by %(FOO)s if FOO is
- # defined in current file (i.e. it is not an external environment variable)
- for k in self.allParsedVariableNames:
- key = r'\$\{?'+k+'\}?'
- pattern = re.compile(key, re.VERBOSE)
- line = pattern.sub(r'%('+k+')s', line)
- # Remove quotes (if line does not contain whitespaces)
- try:
- variable, value = line.split('=', 1)
- except ValueError:
- variable, value = line.split(':', 1)
- if not ' ' in value.strip():
- pattern = re.compile(r'\"', re.VERBOSE)
- line = pattern.sub(r'', line)
- #
-
- # Replace `shell_command` by its result
- def myrep(obj):
- obj = re.sub('`', r'', obj.group(0)) # remove quotes
- obj = obj.split()
- res = subprocess.Popen(obj, stdout=subprocess.PIPE).communicate()[0]
- res = res.strip(' \t\n\r') # trim whitespaces
- return res
- #
- line = re.sub('`[^`]+`', myrep, line)
- #
- if self.outputFile is not None:
- self.outputFile.write(line+'\n')
- return line
-
- def _purgeValue(self, value, name):
- # Replace foo:${PATTERN}:bar or foo:$PATTERN:bar by foo:bar
- key = r'\$\{?'+name+'\}?'
- pattern = re.compile(key, re.VERBOSE)
- value = pattern.sub(r'', value)
-
- # trim colons
- value = _trimColons(value)
-
- return value
- #
-
-# Convert .sh environment file to configuration file format
-def convertEnvFileToConfigFile(envFilename, configFilename, reserved=None):
- if reserved is None:
- reserved = []
- logConfigParser.debug('convert env file %s to %s'%(envFilename, configFilename))
- fileContents = open(envFilename, 'r').read()
-
- pattern = re.compile('\n[\n]+', re.VERBOSE) # multiple '\n'
- fileContents = pattern.sub(r'\n', fileContents) # replace by a single '\n'
-
- finput = StringIO(unicode(fileContents))
- foutput = open(configFilename, 'w')
-
- config = MultiOptSafeConfigParser()
- config.optionxform = str # case sensitive
- config.readfp(EnvFileConverter(finput, 'SALOME Configuration', reserved, outputFile=foutput))
-
- foutput.close()
-
- logConfigParser.info('Configuration file generated: %s'%configFilename)
-#
import ConfigParser
from parseConfigFile import parseConfigFile
-from parseConfigFile import convertEnvFileToConfigFile
import tempfile
import pickle
"""
Initialize context from a list of configuration files
identified by their names.
- These files should be in appropriate (new .cfg) format.
- However you can give old .sh environment files; in this case,
- the SalomeContext class will try to automatically convert them
- to .cfg format before setting the context.
+ These files should be in appropriate .cfg format.
"""
def __init__(self, configFileNames=0):
self.getLogger().setLevel(logging.INFO)
basename, extension = os.path.splitext(filename)
if extension == ".cfg":
self.__setContextFromConfigFile(filename, reserved)
- elif extension == ".sh":
- #new convert procedures, temporary could be use not to be automatically deleted
- #temp = tempfile.NamedTemporaryFile(suffix='.cfg', delete=False)
- temp = tempfile.NamedTemporaryFile(suffix='.cfg')
- try:
- convertEnvFileToConfigFile(filename, temp.name, reserved)
- self.__setContextFromConfigFile(temp.name, reserved)
- temp.close()
- except (ConfigParser.ParsingError, ValueError) as e:
- self.getLogger().error("Invalid token found when parsing file: %s\n"%(filename))
- temp.close()
- sys.exit(1)
else:
self.getLogger().warning("Unrecognized extension for configuration file: %s", filename)
#
unsetVars, configVars, reservedDict = parseConfigFile(filename, reserved)
except SalomeContextException, e:
msg = "%s"%e
- file_dir = os.path.dirname(filename)
- file_base = os.path.basename(filename)
- base_no_ext, ext = os.path.splitext(file_base)
- sh_file = os.path.join(file_dir, base_no_ext+'.sh')
- #if ext == ".cfg" and os.path.isfile(sh_file):
- if False:
- msg += "Found similar %s file; trying to parse this one instead..."%(base_no_ext+'.sh')
- temp = tempfile.NamedTemporaryFile(suffix='.cfg')
- try:
- convertEnvFileToConfigFile(sh_file, temp.name, reserved)
- self.__setContextFromConfigFile(temp.name, reserved)
- msg += "OK\n"
- self.getLogger().warning(msg)
- temp.close()
- return
- except (ConfigParser.ParsingError, ValueError) as e:
- msg += "Invalid token found when parsing file: %s\n"%(sh_file)
- self.getLogger().error(msg)
- temp.close()
- sys.exit(1)
- else:
- self.getLogger().error(msg)
- sys.exit(1)
+ self.getLogger().error(msg)
+ sys.exit(1)
# unset variables
for var in unsetVars: