def parse_line(line, raw_vars, vars, props, seen_props, globals): # Parse a single line from the file, adding its value to the props or vars # dictionary as appropriate. if not line: return raw_vars, vars, props, seen_props key, value, type = split_pc_file_line(line) # Check first if it's one of the known keys. if type == VARIABLE: # Perform substitution using variables found so far and global # variables, then store the result. if key in vars: raise MultiplyDefinedValueError(key) if key in globals: ErrorPrinter().debug_print('Adding %s -> %s to vars from globals', (key, value)) raw_vars[key] = value.strip () vars[key] = substitute (globals[key], vars, globals) else: ErrorPrinter().debug_print('Adding %s -> %s to vars', (key, value)) raw_vars[key] = value.strip () vars[key] = substitute (value.strip(), vars, globals) elif type == PROPERTY: if key in seen_props: raise MultiplyDefinedValueError(key) if key.lower() in empty_raw_props: if value is None: value = empty_raw_props[key.lower()] ErrorPrinter().debug_print('Adding %s -> %s to props', (key, value)) props[key.lower ()] = value seen_props.append(key) else: # As per the original pkg-config, don't raise errors on unknown # keys because they may be from future additions to the file # format. But log an error ErrorPrinter().debug_print('Unknown key/value in %(filename)s:\n%s: %s', (key, value)) else: # Probably a malformed line. Ignore it. pass return raw_vars, vars, props, seen_props
def _process_props(self, global_variables): # Processing of file data props = self.raw_props # May need to reset the prefix variable if sys.platform == 'win32' and \ not Options().get_option('dont_define_prefix'): # Use the location of the .pc file to guess a suitable value for # the prefix variable. Start by checking if the absolute .pc # location ends with '\lib\pkgconfig'. abs_loc = dirname(abspath(self.filename)) if Options().get_option('normalise_paths'): abs_loc = normpath(abs_loc) else: # If not normalising paths, then all paths should be in / # format for consistency abs_loc = abs_loc.replace('\\', '/') if abs_loc.endswith('\\lib\\pkgconfig'): self.variables[Options().get_option('prefix_variable')] = \ abs_loc.rstrip('\\lib\\pkgconfig') ErrorPrinter().debug_print('Replaced {0} with \ {1}'.format(Options().get_option('prefix_variable'), self.variables[Options().get_option('prefix_variable')])) # Perform substitutions for key in props: props[key] = substitute(props[key], self.variables, global_variables) # Parse the data self.properties = deepcopy(empty_processed_props) self.properties['name'] = props['name'] if props['description']: self.properties['description'] = props['description'] if props['version']: try: self.properties['version'] = Version(props['version']) except BadVersionFormatError as e: raise BadVersionFormatError(e.versionstring, props['name']) self.properties['requires'] = \ parse_package_spec_list(props['requires']) self.properties['requires.private'] = \ parse_package_spec_list(props['requires.private']) + \ self.properties['requires'] self.properties['conflicts'] = \ parse_package_spec_list(props['conflicts']) self._parse_cflags(props['cflags'], global_variables) self._parse_libs(props['libs'], global_variables) self._parse_libs(props['libs.private'], global_variables, dest='private.')
def _process_props(self, global_variables): # Processing of file data props = self.raw_props # May need to reset the prefix variable if sys.platform == 'win32' and \ not Options().get_option('dont_define_prefix'): # Use the location of the .pc file to guess a suitable value for # the prefix variable. Start by checking if the absolute .pc # location ends with '\lib\pkgconfig'. abs_loc = dirname(abspath(self.filename)) if Options().get_option('normalise_paths'): abs_loc = normpath(abs_loc) else: # If not normalising paths, then all paths should be in / # format for consistency abs_loc = abs_loc.replace('\\', '/') if abs_loc.endswith('\\lib\\pkgconfig'): self.variables[Options().get_option('prefix_variable')] = \ abs_loc.rstrip('\\lib\\pkgconfig') ErrorPrinter().debug_print('Replaced {0} with \ {1}'.format(Options().get_option('prefix_variable'), self.variables[Options().get_option('prefix_variable')])) # Perform substitutions for key in props: props[key] = substitute(props[key], self.variables, global_variables) # Parse the data self.properties = deepcopy(empty_processed_props) self.properties['name'] = props['name'] if props['description']: self.properties['description'] = props['description'] if props['version']: try: self.properties['version'] = Version(props['version']) except BadVersionFormatError as e: raise BadVersionFormatError(e.versionstring, props['name']) self.properties['requires'] = \ parse_package_spec_list(props['requires']) self.properties['requires.private'] = \ parse_package_spec_list(props['requires.private']) + \ self.properties['requires'] self.properties['conflicts'] = \ parse_package_spec_list(props['conflicts']) self._parse_cflags(props['cflags']) self._parse_libs(props['libs']) self._parse_libs(props['libs.private'], dest='private.')
def test_substitute(self): value = "stuff ${blag2} more stuff ${blag1} ${blag3}" result = "stuff references not recursive variable more stuff not recursive recursive with ${blag3}" self.assertEqual(substitute.substitute(value, self.vars), result)
def test_escaping(self): value = "a $${blag1} that should not be replaced" result = "a $${blag1} that should not be replaced" self.assertEqual(substitute.substitute(value, self.vars), result)
def test_substitute(self): value = 'stuff ${blag2} more stuff ${blag1} ${blag3}' result = 'stuff references not recursive variable more stuff not recursive recursive with ${blag3}' self.assertEqual(substitute.substitute(value, self.vars), result)
def test_escaping(self): value = 'a $${blag1} that should not be replaced' result = 'a ${blag1} that should not be replaced' self.assertEqual(substitute.substitute(value, self.vars), result)