def _add_library( child, root, project_object, synthesise, ): """Process the given library node and add it to the project_dictionary. Any files containedwithin the library will be added to the project_dictionary under that library""" attribs = ProjectAttributes.process_attributes( child.attributes, root, defaults=ProjectAttributes.LIBRARY_NODE_DEFAULTS ) if attribs[ProjectAttributes.ATTRIBUTE_NAME] is None: log.warning('Ignoring library with no name specified') return library_name = attribs[ProjectAttributes.ATTRIBUTE_NAME] if synthesise is None: synthesise = attribs[ProjectAttributes.ATTRIBUTE_SYNTHESIS] # Add all files in this library node to the project for file_node in filter( lambda x: x.nodeName == ProjectAttributes.XML_NODE_FILE, child.childNodes ): XmlProjectParser._add_file( file_node, library_name, root, project_object, synthesise, )
def add_config(self, name, value, force=False): """ Add a configuration key, value mapping for the project. """ value = ProjectAttributes.get_processed_attribute( value, self.root, name ) if self.config.get(name, None) is not None and not force: log.warning( 'Ignoring duplicate configuration attribute ' + 'found in project file, ' + str(name) + ' set to ' + str(value) + ' ' + 'but already defined as ' + str(self.config[name]) ) else: log.debug( 'Set project configuration \'' + str(name) + '\' to \'' + str(value) + '\'' ) self.config[name] = value
def _add_file( file_node, library_name, root, project_object, synthesise ): """Add the given file to the given library and ensure that any relative file paths are correctly converted into absolute paths using the project_root as a reference""" attribs = ProjectAttributes.process_attributes( file_node.attributes, root, defaults=ProjectAttributes.FILE_NODE_DEFAULTS ) if attribs[ProjectAttributes.ATTRIBUTE_PATH] is not None: # Override the file synthesis flag if the library is marked for # exclusion from synthesis if synthesise is not None: attribs[ProjectAttributes.ATTRIBUTE_SYNTHESIS] = synthesise # Path is passed directly, so remove it from kwargs path = attribs[ProjectAttributes.ATTRIBUTE_PATH] del attribs[ProjectAttributes.ATTRIBUTE_PATH] project_object.add_file( path=path, library=library_name, **attribs ) else: log.warning('Ignoring file with no path.')
def _add_library( child, root, project_object, synthesise, ): """Process the given library node and add it to the project_dictionary. Any files containedwithin the library will be added to the project_dictionary under that library""" attribs = ProjectAttributes.process_attributes( child.attributes, root, defaults=ProjectAttributes.LIBRARY_NODE_DEFAULTS) if attribs[ProjectAttributes.ATTRIBUTE_NAME] is None: log.warning('Ignoring library with no name specified') return library_name = attribs[ProjectAttributes.ATTRIBUTE_NAME] if synthesise is None: synthesise = attribs[ProjectAttributes.ATTRIBUTE_SYNTHESIS] # Add all files in this library node to the project for file_node in filter( lambda x: x.nodeName == ProjectAttributes.XML_NODE_FILE, child.childNodes): XmlProjectParser._add_file( file_node, library_name, root, project_object, synthesise, )
def _add_unittest(child, root, project_object): attribs = ProjectAttributes.process_attributes( child.attributes, root, defaults=ProjectAttributes.UNITTEST_NODE_DEFAULTS) path = attribs[ProjectAttributes.ATTRIBUTE_PATH] # Path is passed separately, so delete it from the kwargs dict. del attribs[ProjectAttributes.ATTRIBUTE_PATH] project_object.add_unittest(path, **attribs)
def _add_constraints(child, root, project_object): attribs = ProjectAttributes.process_attributes( child.attributes, root, defaults=ProjectAttributes.CONSTRAINTS_NODE_DEFAULTS) path = attribs[ProjectAttributes.ATTRIBUTE_PATH] # Path is passed separately, so delete it from the kwargs dict. del attribs[ProjectAttributes.ATTRIBUTE_PATH] project_object.add_constraints(path, **attribs)
def _add_constraints(child, root, project_object): attribs = ProjectAttributes.process_attributes( child.attributes, root, defaults=ProjectAttributes.CONSTRAINTS_NODE_DEFAULTS ) path = attribs[ProjectAttributes.ATTRIBUTE_PATH] # Path is passed separately, so delete it from the kwargs dict. del attribs[ProjectAttributes.ATTRIBUTE_PATH] project_object.add_constraints( path, **attribs )
def _add_unittest(child, root, project_object): attribs = ProjectAttributes.process_attributes( child.attributes, root, defaults=ProjectAttributes.UNITTEST_NODE_DEFAULTS ) path = attribs[ProjectAttributes.ATTRIBUTE_PATH] # Path is passed separately, so delete it from the kwargs dict. del attribs[ProjectAttributes.ATTRIBUTE_PATH] project_object.add_unittest( path, **attribs )
def add_file(self, path, library="work", **attribs): """Add the given file to the project.""" attribs[ProjectAttributes.ATTRIBUTE_PATH] = path attribs[ProjectAttributes.ATTRIBUTE_LIBRARY] = library # Process the attributes to ensure they conform to our expectations attribs = ProjectAttributes.process_attributes(attribs, self.root) # Default synthesis to true file_object = File(**attribs) if library not in self.project_data: self.project_data[library] = [] if file_object not in self.project_data[library]: # Both a dictionary and list of files are maintained so that # compilation order can be preserved self.project_data[library].append(file_object) self.file_list.append(file_object)
def add_file(self, path, library='work', **attribs): """Add the given file to the project.""" attribs[ProjectAttributes.ATTRIBUTE_PATH] = path attribs[ProjectAttributes.ATTRIBUTE_LIBRARY] = library # Process the attributes to ensure they conform to our expectations attribs = ProjectAttributes.process_attributes(attribs, self.root) # Default synthesis to true file_object = File(**attribs) if library not in self.project_data: self.project_data[library] = [] if file_object not in self.project_data[library]: # Both a dictionary and list of files are maintained so that # compilation order can be preserved self.project_data[library].append(file_object) self.file_list.append(file_object)
def add_unittest(self, path, **attribs): """Add the given TestSuite file to the project.""" attribs[ProjectAttributes.ATTRIBUTE_PATH] = path # Process the attributes to ensure they conform to our expectations attribs = ProjectAttributes.process_attributes(attribs, self.root) unit = UnitTestFile(**attribs) # Perform TestSuite loading on the supplied path if os.path.exists(attribs[ProjectAttributes.ATTRIBUTE_PATH]): # Convert the testsuite path into an unpacked testsuite # for each file object that has a link to a test suite. unpacked_testsuite = load_tests(attribs[ProjectAttributes.ATTRIBUTE_PATH], self.get_simulation_directory()) # Modify the file object, replacing the testsuite path # string with the testsuite object that we just # unpacked. unit.testsuite = unpacked_testsuite self.tests.append(unit)
def add_config(self, name, value, force=False): """ Add a configuration key, value mapping for the project. """ value = ProjectAttributes.get_processed_attribute(value, self.root, name) if self.config.get(name, None) is not None and not force: log.warning( "Ignoring duplicate configuration attribute " + "found in project file, " + str(name) + " set to " + str(value) + " " + "but already defined as " + str(self.config[name]) ) else: log.debug("Set project configuration '" + str(name) + "' to '" + str(value) + "'") self.config[name] = value
def add_unittest(self, path, **attribs): """Add the given TestSuite file to the project.""" attribs[ProjectAttributes.ATTRIBUTE_PATH] = path # Process the attributes to ensure they conform to our expectations attribs = ProjectAttributes.process_attributes(attribs, self.root) unit = UnitTestFile(**attribs) # Perform TestSuite loading on the supplied path if os.path.exists(attribs[ProjectAttributes.ATTRIBUTE_PATH]): # Convert the testsuite path into an unpacked testsuite # for each file object that has a link to a test suite. unpacked_testsuite = load_tests( attribs[ProjectAttributes.ATTRIBUTE_PATH], self.get_simulation_directory(), ) # Modify the file object, replacing the testsuite path # string with the testsuite object that we just # unpacked. unit.testsuite = unpacked_testsuite self.tests.append(unit)
def _add_file(file_node, library_name, root, project_object, synthesise): """Add the given file to the given library and ensure that any relative file paths are correctly converted into absolute paths using the project_root as a reference""" attribs = ProjectAttributes.process_attributes( file_node.attributes, root, defaults=ProjectAttributes.FILE_NODE_DEFAULTS) if attribs[ProjectAttributes.ATTRIBUTE_PATH] is not None: # Override the file synthesis flag if the library is marked for # exclusion from synthesis if synthesise is not None: attribs[ProjectAttributes.ATTRIBUTE_SYNTHESIS] = synthesise # Path is passed directly, so remove it from kwargs path = attribs[ProjectAttributes.ATTRIBUTE_PATH] del attribs[ProjectAttributes.ATTRIBUTE_PATH] project_object.add_file(path=path, library=library_name, **attribs) else: log.warning('Ignoring file with no path.')
def parse_project(filepath, project_object, synthesise=None): """Parse the XML project and update the project_dictionary or return a new dictionary if one is not supplied. """ log.info('Parsing: ' + str(filepath) + ' synthesis=' + str(synthesise)) start_time = time.time() project_root = os.path.dirname(os.path.realpath(filepath)) try: xml_obj = minidom.parse(filepath) for project_node in xml_obj.getElementsByTagName( ProjectAttributes.XML_NODE_PROJECT): # Project attributes (if any) # If this whole node should not be synthesised, ignore any # child flags otherwise get the child synthesis flag and use # that. if synthesise is None: project_attribs = ProjectAttributes.process_attributes( project_node.attributes, project_root) synthesis_enabled = project_attribs.get( ProjectAttributes.ATTRIBUTE_SYNTHESIS, None) else: synthesis_enabled = synthesise for child in project_node.childNodes: if child.nodeName == ProjectAttributes.XML_NODE_PROJECT: attribs = ProjectAttributes.process_attributes( child.attributes, project_root, defaults=ProjectAttributes.PROJECT_NODE_DEFAULTS) # If this whole node should not be synthesised, ignore # any child flags otherwise get the child synthesis # flag and use that. if synthesis_enabled is None: synthesise = attribs.get( ProjectAttributes.ATTRIBUTE_SYNTHESIS, None) else: synthesise = synthesis_enabled if ProjectAttributes.ATTRIBUTE_PATH in attribs: log.debug( 'Found sub-project: ' + str(attribs[ProjectAttributes.ATTRIBUTE_PATH])) # Recursively call this parser with the new project # path XmlProjectParser.parse_project( str(attribs[ProjectAttributes.ATTRIBUTE_PATH]), project_object, synthesise) elif child.nodeName == ProjectAttributes.XML_NODE_CONFIG: XmlProjectParser._add_config(child, project_root, project_object) elif child.nodeName == ProjectAttributes.XML_NODE_LIBRARY: XmlProjectParser._add_library(child, project_root, project_object, synthesis_enabled) elif child.nodeName == ( ProjectAttributes.XML_NODE_CONSTRAINTS): XmlProjectParser._add_constraints( child, project_root, project_object, ) elif child.nodeName == ( ProjectAttributes.XML_NODE_UNITTEST): XmlProjectParser._add_unittest( child, project_root, project_object, ) elif child.nodeName == ProjectAttributes.XML_NODE_GENERIC: # Build a dictionary of generics using the attribute # name and value attribs = child.attributes if attribs is None: continue attribs = dict(attribs.items()) for attrName, attrVal in attribs.items(): project_object.add_generic(attrName, attrVal) elif child.nodeName == ProjectAttributes.XML_NODE_FILE: # Files should not be left unassociated with a library # unless you wish to add all files to the work library. # The default behavior will be to add parentless files # to the work library, but a configuration option could # make this post an error instead. log.warning('Found file with no parent library, ' + 'defaulting to work library') # If this whole node should not be synthesised, ignore # any child flags otherwise get the child synthesis # flag and use that. if synthesis_enabled is None: synthesise = ( ProjectAttributes.get_processed_attribute( child.attributes.get( ProjectAttributes.ATTRIBUTE_SYNTHESIS, None), project_root, ProjectAttributes.ATTRIBUTE_SYNTHESIS)) else: synthesise = synthesis_enabled XmlProjectParser._add_file(child, 'work', project_root, project_object, synthesise=synthesise) elif child.nodeName == ProjectAttributes.XML_NODE_TEXT: pass elif child.nodeName == ProjectAttributes.XML_NODE_COMMENT: pass except xml.parsers.expat.ExpatError: log.error( 'Error found in XML file, check the formatting. ' + 'Refer to the traceback below for the line number and file.') log.error(traceback.format_exc()) project_object.initialise() return log.debug(filepath + ' parsed in ' + utils.time_delta_string(start_time, time.time()))
def add_constraints(self, path, **attribs): """Add the given constraints file to the project.""" attribs[ProjectAttributes.ATTRIBUTE_PATH] = path # Process the attributes to ensure they conform to our expectations attribs = ProjectAttributes.process_attributes(attribs, self.root) self.constraints.append(Constraints(**attribs))
def parse_project( filepath, project_object, synthesise=None ): """Parse the XML project and update the project_dictionary or return a new dictionary if one is not supplied. """ log.info('Parsing: ' + str(filepath) + ' synthesis=' + str(synthesise)) start_time = time.time() project_root = os.path.dirname(os.path.realpath(filepath)) try: xml_obj = minidom.parse(filepath) for project_node in xml_obj.getElementsByTagName( ProjectAttributes.XML_NODE_PROJECT ): # Project attributes (if any) # If this whole node should not be synthesised, ignore any # child flags otherwise get the child synthesis flag and use # that. if synthesise is None: project_attribs = ProjectAttributes.process_attributes( project_node.attributes, project_root ) synthesis_enabled = project_attribs.get( ProjectAttributes.ATTRIBUTE_SYNTHESIS, None ) else: synthesis_enabled = synthesise for child in project_node.childNodes: if child.nodeName == ProjectAttributes.XML_NODE_PROJECT: attribs = ProjectAttributes.process_attributes( child.attributes, project_root, defaults=ProjectAttributes.PROJECT_NODE_DEFAULTS ) # If this whole node should not be synthesised, ignore # any child flags otherwise get the child synthesis # flag and use that. if synthesis_enabled is None: synthesise = attribs.get( ProjectAttributes.ATTRIBUTE_SYNTHESIS, None ) else: synthesise = synthesis_enabled if ProjectAttributes.ATTRIBUTE_PATH in attribs: log.debug( 'Found sub-project: ' + str( attribs[ ProjectAttributes.ATTRIBUTE_PATH ] ) ) # Recursively call this parser with the new project # path XmlProjectParser.parse_project( str( attribs[ ProjectAttributes.ATTRIBUTE_PATH ] ), project_object, synthesise ) elif child.nodeName == ProjectAttributes.XML_NODE_CONFIG: XmlProjectParser._add_config( child, project_root, project_object ) elif child.nodeName == ProjectAttributes.XML_NODE_LIBRARY: XmlProjectParser._add_library( child, project_root, project_object, synthesis_enabled ) elif child.nodeName == ( ProjectAttributes.XML_NODE_CONSTRAINTS ): XmlProjectParser._add_constraints( child, project_root, project_object, ) elif child.nodeName == ( ProjectAttributes.XML_NODE_UNITTEST ): XmlProjectParser._add_unittest( child, project_root, project_object, ) elif child.nodeName == ProjectAttributes.XML_NODE_GENERIC: # Build a dictionary of generics using the attribute # name and value attribs = child.attributes if attribs is None: continue attribs = dict(attribs.items()) for attrName, attrVal in attribs.items(): project_object.add_generic( attrName, attrVal ) elif child.nodeName == ProjectAttributes.XML_NODE_FILE: # Files should not be left unassociated with a library # unless you wish to add all files to the work library. # The default behavior will be to add parentless files # to the work library, but a configuration option could # make this post an error instead. log.warning( 'Found file with no parent library, ' + 'defaulting to work library' ) # If this whole node should not be synthesised, ignore # any child flags otherwise get the child synthesis # flag and use that. if synthesis_enabled is None: synthesise = ( ProjectAttributes.get_processed_attribute( child.attributes.get( ProjectAttributes.ATTRIBUTE_SYNTHESIS, None ), project_root, ProjectAttributes.ATTRIBUTE_SYNTHESIS ) ) else: synthesise = synthesis_enabled XmlProjectParser._add_file( child, 'work', project_root, project_object, synthesise=synthesise ) elif child.nodeName == ProjectAttributes.XML_NODE_TEXT: pass elif child.nodeName == ProjectAttributes.XML_NODE_COMMENT: pass except xml.parsers.expat.ExpatError: log.error( 'Error found in XML file, check the formatting. ' + 'Refer to the traceback below for the line number and file.' ) log.error(traceback.format_exc()) project_object.initialise() return log.debug(filepath + ' parsed in ' + utils.time_delta_string( start_time, time.time()) )