X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=bin%2FparseConfigFile.py;h=69c3e2acd741bb362f820e32da0306f02c62931d;hb=a896fba3e95e73b50c720e51723f2990074018c6;hp=3054ed1f341eeb2154d3280befda32627afe1970;hpb=641929d327319a80b4fc6f6157605a21f46413c4;p=modules%2Fkernel.git diff --git a/bin/parseConfigFile.py b/bin/parseConfigFile.py old mode 100755 new mode 100644 index 3054ed1f3..69c3e2acd --- a/bin/parseConfigFile.py +++ b/bin/parseConfigFile.py @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2014 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2013-2020 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -17,13 +17,13 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -import ConfigParser +import configparser import os import logging import re from io import StringIO import subprocess -from salomeContextUtils import SalomeContextException +from salomeContextUtils import SalomeContextException #@UnresolvedImport logging.basicConfig() logConfigParser = logging.getLogger(__name__) @@ -44,9 +44,9 @@ def _expandSystemVariables(key, val): # # :TRICKY: So ugly solution... -class MultiOptSafeConfigParser(ConfigParser.SafeConfigParser): +class MultiOptSafeConfigParser(configparser.SafeConfigParser): def __init__(self): - ConfigParser.SafeConfigParser.__init__(self) + configparser.SafeConfigParser.__init__(self) # copied from python 2.6.8 Lib.ConfigParser.py # modified (see code comments) to handle duplicate keys @@ -88,7 +88,7 @@ class MultiOptSafeConfigParser(ConfigParser.SafeConfigParser): sectname = mo.group('header') if sectname in self._sections: cursect = self._sections[sectname] - elif sectname == ConfigParser.DEFAULTSECT: + elif sectname == configparser.DEFAULTSECT: cursect = self._defaults else: cursect = self._dict() @@ -98,7 +98,7 @@ class MultiOptSafeConfigParser(ConfigParser.SafeConfigParser): optname = None # no section header in the file? elif cursect is None: - raise ConfigParser.MissingSectionHeaderError(fpname, lineno, line) + raise configparser.MissingSectionHeaderError(fpname, lineno, line) # an option line? else: mo = self.OPTCRE.match(line) @@ -133,7 +133,7 @@ class MultiOptSafeConfigParser(ConfigParser.SafeConfigParser): cursect[optname][0] += ','+optval else: cursect[optname] = [optval] - # END OF SUBSITUTION + # END OF SUBSTITUTION else: # valueless option handling cursect[optname] = optval @@ -143,7 +143,7 @@ class MultiOptSafeConfigParser(ConfigParser.SafeConfigParser): # raised at the end of the file and will contain a # list of all bogus lines if not e: - e = ConfigParser.ParsingError(fpname) + e = configparser.ParsingError(fpname) e.append(lineno, repr(line)) # if any parsing errors occurred, raise an exception if e: @@ -151,9 +151,9 @@ class MultiOptSafeConfigParser(ConfigParser.SafeConfigParser): # join the multi-line values collected while reading all_sections = [self._defaults] - all_sections.extend(self._sections.values()) + all_sections.extend(list(self._sections.values())) for options in all_sections: - for name, val in options.items(): + for name, val in list(options.items()): if isinstance(val, list): options[name] = '\n'.join(val) # @@ -163,7 +163,9 @@ class MultiOptSafeConfigParser(ConfigParser.SafeConfigParser): # Input: filename, and a list of reserved keywords (environment variables) # Output: a list of pairs (variable, value), and a dictionary associating a list of user-defined values to each reserved keywords # Note: Does not support duplicate keys in a same section -def parseConfigFile(filename, reserved = []): +def parseConfigFile(filename, reserved = None): + if reserved is None: + reserved = [] config = MultiOptSafeConfigParser() config.optionxform = str # case sensitive @@ -172,21 +174,23 @@ def parseConfigFile(filename, reserved = []): # Read config file try: config.read(filename) - except ConfigParser.MissingSectionHeaderError: + except configparser.MissingSectionHeaderError: logConfigParser.error("No section found in file: %s"%(filename)) return [] try: return __processConfigFile(config, reserved, filename) - except ConfigParser.InterpolationMissingOptionError, e: + except configparser.InterpolationMissingOptionError as e: msg = "A variable may be undefined in SALOME context file: %s\nParser error is: %s\n"%(filename, e) raise SalomeContextException(msg) # -def __processConfigFile(config, reserved = [], filename="UNKNOWN FILENAME"): +def __processConfigFile(config, reserved = None, filename="UNKNOWN FILENAME"): # :TODO: may detect duplicated variables in the same section (raise a warning) # or even duplicate sections + if reserved is None: + reserved = [] unsetVariables = [] outputVariables = [] # Get raw items for each section, and make some processing for environment variables management @@ -239,153 +243,3 @@ def _trimColons(var): 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 = [], outputFile=None): - 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=[]): - 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) -#