コード例 #1
0
    def __init__(self, proj_file, devkit_root, workspace_file):
        """ parse an XML file and store the root element, file and dir name """
        if not os.path.isfile(proj_file):
            bdex.raise_bd_err('INVALID_PROJECT_FILE', proj_file)
        if not os.path.isfile(workspace_file):
            bdex.raise_bd_err('INVALID_WORKSPACE_FILE', workspace_file)
        if not os.path.isdir(devkit_root):
            bdex.raise_bd_err('INVALID_DEVKIT_ROOT', devkit_root)

        self.workspace_root = os.path.abspath(workspace_file)
        self.devkit_root = os.path.abspath(devkit_root)
        self.proj_fobj = None
        self.proj_fname = None

        current_wsroot = self._get_wsroot_from_workspace_file(
            workspace_file, devkit_root)
        self.aliases = Aliases(proj_file,
                               sdk=devkit_root,
                               wsroot=current_wsroot)
        try:
            self.proj_fname = proj_file.name
            self.proj_fobj = proj_file
        except AttributeError:
            self.proj_fname = proj_file
            self.proj_fobj = open(proj_file)

        basename = os.path.basename(self.proj_fname)
        self.proj_projname = os.path.splitext(basename)[0]
        self.proj_dirname = os.path.abspath(os.path.dirname(self.proj_fname))
        try:
            tree = ET.ElementTree(file=self.proj_fobj)
        except ET.ParseError as excep:
            line, col = excep.position
            file_name = os.path.abspath(proj_file)
            bdex.raise_bd_err('INVALID_XML', file_name, excep.msg, line, col)

        self.tree_root = tree.getroot()
        self.validate_xml()
コード例 #2
0
class ParseProject(object):
    """ Parse an x2p project
    """
    def __init__(self, project_file, sdk=None, wsroot=None):
        self.xml = parsers.get_xml(project_file)
        self.aliases = Aliases(project_file, sdk=sdk, wsroot=wsroot)
        self.xml_tree = self.xml.parse()
        self.files = self._parse_files()
        self.configurations = self._parse_configurations()

    def _parse_files(self):
        files = []
        for file_element in self.xml_tree.iter(file_xpath):
            file_path = file_element.get(path_attr_str)
            file_path = self.aliases.expand(file_path)
            if not os.path.isabs(file_path):
                file_path = os.path.normpath(
                    os.path.join(self.xml.base_dir, file_path))
            if not os.path.isfile(file_path):
                raise InvalidProjectElement(
                    "File listed in project {} doesn't exist: {}".format(
                        self.xml.filename, file_path))
            files.append(file_path)
        return files

    def _parse_configurations(self):
        configurations_elements = self.xml_tree.findall(configurations_xpath)
        if len(configurations_elements) > 1:
            raise InvalidProjectElement(
                "Multiple <configurations> elements in {}".format(
                    self.xml.filename))
        elif len(configurations_elements) < 1:
            raise InvalidProjectElement(
                "No <configurations> elements found in {}".format(
                    self.xml.filename))

        configurations = {}
        for config in configurations_elements[0].findall(configuration_xpath):
            configuration = Configuration(config)
            configurations[configuration.name] = configuration
        return configurations

    def parse(self):
        return self.files, self.configurations
コード例 #3
0
 def _get_wsroot_from_workspace_file(self, workspace_file, devkit_root):
     aliases = Aliases(workspace_file, devkit_root)
     return aliases["wsroot://"]
コード例 #4
0
class Project(object):
    """ Container for all project file infomation """
    def __init__(self, proj_file, devkit_root, workspace_file):
        """ parse an XML file and store the root element, file and dir name """
        if not os.path.isfile(proj_file):
            bdex.raise_bd_err('INVALID_PROJECT_FILE', proj_file)
        if not os.path.isfile(workspace_file):
            bdex.raise_bd_err('INVALID_WORKSPACE_FILE', workspace_file)
        if not os.path.isdir(devkit_root):
            bdex.raise_bd_err('INVALID_DEVKIT_ROOT', devkit_root)

        self.workspace_root = os.path.abspath(workspace_file)
        self.devkit_root = os.path.abspath(devkit_root)
        self.proj_fobj = None
        self.proj_fname = None

        current_wsroot = self._get_wsroot_from_workspace_file(
            workspace_file, devkit_root)
        self.aliases = Aliases(proj_file,
                               sdk=devkit_root,
                               wsroot=current_wsroot)
        try:
            self.proj_fname = proj_file.name
            self.proj_fobj = proj_file
        except AttributeError:
            self.proj_fname = proj_file
            self.proj_fobj = open(proj_file)

        basename = os.path.basename(self.proj_fname)
        self.proj_projname = os.path.splitext(basename)[0]
        self.proj_dirname = os.path.abspath(os.path.dirname(self.proj_fname))
        try:
            tree = ET.ElementTree(file=self.proj_fobj)
        except ET.ParseError as excep:
            line, col = excep.position
            file_name = os.path.abspath(proj_file)
            bdex.raise_bd_err('INVALID_XML', file_name, excep.msg, line, col)

        self.tree_root = tree.getroot()
        self.validate_xml()

    def validate_xml(self):
        """
         TODO check the XML is compliant with our form e.g. <property name= for
         Heracles files
        """
        pass

    def get_properties(self):
        """ return the properties derived from the project file and folder
        names """
        properties = collections.defaultdict(str)
        properties['OUTDIR'] = self.proj_dirname
        properties['IDE_PROJECT'] = self.proj_projname
        return properties

    def get_configurations(self):
        """
        Return  a list of all the configuration names found under the 'properties'
        tag.
        """
        config_list = []
        for config in self.tree_root.iterfind(
                './configurations/configuration'):
            config_list.append(config.attrib['name'])

        return config_list

    def get_elements_from_tree_path(self, tree_path, elem_name, type=""):
        """
        Return a dict of the elem_name elements of a given tree path.
        """
        def get_text(prop_val, prop):
            """
            Ensure elem_name text is never None
            Replace 'sdk://' to the path to the Devkit root folder
            """
            text = ''
            if prop.text != None:
                text = prop.text

            text = text.replace('sdk://', self.devkit_root + '\\')

            return text

        properties = collections.defaultdict(str)
        xpath_elements = "/*"
        xpath = tree_path + xpath_elements

        #        for prop in self.tree_root.iterfind(xpath):
        #            if prop.tag == elem_name:
        #                # Catenate the text of properties with the 'alias' attribute onto the specified
        #                # alias elem_name. properties is a defaultdict and creates the specified alias key
        #                # if required.
        #                # Do not add a new key to the properties dictionary for the alias itself
        #                if 'alias' in prop.attrib:
        #                    name = prop.attrib['alias']
        #                    properties[name] += ' ' + get_text(properties[name], prop)
        #                else:
        #                    name = prop.attrib['name']
        #                    if name in properties:
        #                        print 'WARNING: Duplicate %s %s' % (elem_name, name)
        #                    properties[name] = ' ' + get_text(properties[name], prop)

        for prop in self.tree_root.iterfind(xpath):
            if prop.tag == elem_name and 'alias' not in prop.attrib:
                name = prop.attrib['name']
                if name in properties:
                    print 'WARNING: Duplicate %s %s' % (elem_name, name)
                properties[name] = get_text(properties[name], prop)
                if type != "":
                    if "type" in prop.attrib:
                        if prop.attrib["type"] != type:
                            properties.pop(name)
                    else:
                        properties.pop(name)

        for prop in self.tree_root.iterfind(xpath):
            if prop.tag == elem_name:
                # Catenate the text of properties with the 'alias' attribute onto the specified
                # alias elem_name. properties is a defaultdict and creates the specified alias key
                # if required.
                # Do not add a new key to the properties dictionary for the alias itself
                if 'alias' in prop.attrib:
                    name = prop.attrib['alias']
                    properties[name] += ' ' + get_text(properties[name], prop)

                properties[name] = properties[name].strip()

        return properties

    def get_attributes_from_config(self, config_name):
        config_list = self.tree_root.iterfind(
            "./configurations/configuration/[@name='%s']" % config_name)
        # config_list for a given config_name should always be 1 element in length
        # config_list is a 'generator', which is iterable but not indexable, so we need to loop once.
        for config in config_list:
            return config.attrib

    def get_properties_from_config(self, config_name):
        return self.get_elements_from_tree_path(
            "./configurations/configuration/[@name='%s']" % config_name,
            "property")

    def get_capabilities_from_config(self, config_name):
        return self.get_elements_from_tree_path(
            "./configurations/configuration/[@name='%s']" % config_name,
            "group", "capability")

    def get_cap_props_from_config(self, config_name, capability):
        return self.get_elements_from_tree_path(
            "./configurations/configuration/[@name='%s']/group/[@name='%s']" %
            (config_name, capability), "property")

    def build_source_path(self, root_el, path):
        """
        Recursively search all 'folder' tags for subordinate 'file' tags and
        retrieve source file paths. xIDE paths are complete, whereas Heracles ones
        use a nested folder structure like a file system and need to be built up into
        a path string.
        All paths have seperators normalised and are prepended with the path parameter .
        """
        file_list = []
        for child in root_el:
            if child.tag == 'file':
                if child.attrib['path'].startswith('root.pri'):
                    sys.exit('ROOT PRI NO SLASHES')
                exp_path = self.aliases.expand(child.attrib['path'])

                file_path = os.path.join(path, exp_path)
                file_path = os.path.normpath(file_path)
                file_list.append(file_path)
            elif child.tag == 'folder':
                child_paths = self.build_source_path(child, path)
                file_list.extend(child_paths)
            elif child.tag == 'sdkfile':
                file_path = os.path.join(self.devkit_root,
                                         child.attrib['path'])
                file_path = os.path.normpath(file_path)
                for f in glob.glob(file_path):
                    file_list.append(f)
            else:
                # Ignore any other kind of tag
                pass

        return file_list

    def get_source_files(self):
        """
        Recursively search all 'folder' tags for subordinate 'file' tags and
        retrieve source file paths. xIDE paths are complete, whereas Heracles ones
        use a nested folder structure like a file system and need to be built up into
        a path string.
        All paths have seperators normalised and are prepended with the path parameter .
        """
        file_list = self.build_source_path(self.tree_root, self.proj_dirname)

        # Check that all the files exist before returning the list
        try:
            for fname in file_list:
                fobj = open(fname)
                fobj.close()
        except IOError as excep:
            print "FAILED SOURCE"
            bdex.raise_bd_err('INVALID_SOURCE_FILE', fname, excep.strerror)

        return file_list

    def get_make_vars(self, config):
        """ merge project properties and config properties and return in a
        single dict """
        proj_props = self.get_properties()
        make_vars = proj_props.copy()

        make_vars['IDE_CONFIG'] = config

        # Configuration properties take priority over project properties
        config_props = self.get_properties_from_config(config)
        make_vars.update(config_props)

        return make_vars

    def get_workspace_path(self):
        """
        Find the workspace element in the file and return the path attribute,
        raising an error if this doesn't point at a real file relative to the
        project file's location.
        """
        workspace_el = self.tree_root.find("workspace")
        if workspace_el is None:
            print "No workspace element in project file"
            return None
        if "path" not in workspace_el.attrib:
            bdex.raise_bd_err("INVALID WORKSPACE ELEMENT")

        ws_path = os.path.normpath(
            os.path.join(self.proj_dirname, workspace_el.attrib["path"]))
        if not os.path.isfile(ws_path):
            bdex.raise_bd_err("INVALID WORKSPACE FILE")

        return ws_path

    def _get_wsroot_from_workspace_file(self, workspace_file, devkit_root):
        aliases = Aliases(workspace_file, devkit_root)
        return aliases["wsroot://"]
コード例 #5
0
 def __init__(self, project_file, sdk=None, wsroot=None):
     self.xml = parsers.get_xml(project_file)
     self.aliases = Aliases(project_file, sdk=sdk, wsroot=wsroot)
     self.xml_tree = self.xml.parse()
     self.files = self._parse_files()
     self.configurations = self._parse_configurations()
コード例 #6
0
ファイル: acat_tab.py プロジェクト: wangyufeng86/qcc3040
def get_audio_elf_path_from_workspace(workspace_file, isSimTarget):
    """
    Given a workspace file (x2w) will return the
    Path to the kymera_audio project contained within
    """
    aliases = Aliases(workspace_file)

    workspace_tree = ElementTree.parse(workspace_file)
    workspace_root = workspace_tree.getroot()
    workspace_path = os.path.dirname(workspace_file)
    project_dict = {}
    workspace_name = os.path.basename(workspace_file)
    workspace_name, dont_care = os.path.splitext(workspace_name)
    main_proj_name = workspace_name + ".x2p"
    kymera_image_path = None
    dkcs_path = None
    bundle_image_list = []
    projects_visited = []

    for project in workspace_root.iter('project'):
        project_path = project.get('path')

        # Skip project items without a path attribute.
        if project_path is None:
            continue

        project_path = aliases.expand(project_path)

        if project_path not in projects_visited:
            projects_visited.append(project_path)
            project_path = os.path.abspath(
                os.path.join(workspace_path, project_path))
            if "kymera_audio.x2p" in project_path:
                is_audio_proj, kymera_image_path = get_output_value_from_audio_proj(
                    project_path, isSimTarget, False)
                if kymera_image_path:
                    kymera_project_path = os.path.dirname(project_path)
                    kymera_image_path = os.path.join(kymera_project_path,
                                                     kymera_image_path)
                    kymera_image_path = os.path.abspath(kymera_image_path)
                    dkcs_path = get_dkcs_path_value_from_audio_proj(
                        project_path)
                    if dkcs_path:
                        dkcs_path = os.path.abspath(
                            os.path.join(kymera_project_path, dkcs_path))
                        if os.path.exists(dkcs_path):
                            for bundle_name in os.listdir(dkcs_path):
                                bundle_name = os.path.join(
                                    os.path.abspath(dkcs_path), bundle_name)
                                if os.path.splitext(bundle_name)[1] == ".elf":
                                    bundle_image_list.append(bundle_name)
            else:
                is_audio_proj, bundle_image_path = get_output_value_from_audio_proj(
                    project_path, isSimTarget, True)
                if is_audio_proj:
                    kymera_project_path = os.path.dirname(project_path)
                    bundle_image_path = os.path.join(kymera_project_path,
                                                     bundle_image_path)
                    bundle_image_path = os.path.abspath(bundle_image_path)
                    bundle_image_list.append(bundle_image_path)
    return kymera_image_path, bundle_image_list
コード例 #7
0
 def __init__(self, workspace_file):
     self.workspace_xml = parsers.get_xml(workspace_file)
     self.aliases = Aliases(workspace_file)
     self.default_project = None
コード例 #8
0
class ParseWorkspace(object):
    """Parse an x2w workspace"""
    def __init__(self, workspace_file):
        self.workspace_xml = parsers.get_xml(workspace_file)
        self.aliases = Aliases(workspace_file)
        self.default_project = None

    def __repr__(self):
        return self.workspace_xml

    def __call__(self):
        return self.workspace_xml

    def _join_workspace_path_with_relative_project_path(
            self, relative_project_path):
        return os.path.abspath(
            os.path.join(self.workspace_xml.base_dir, relative_project_path))

    def _get_absolute_project_path(self, project_xml):
        project_path = self._parse_project_path(project_xml)
        if not os.path.isabs(project_path):
            return self._join_workspace_path_with_relative_project_path(
                project_path)
        return project_path

    def _parse_project_path(self, element):
        if element is not None:
            return self.aliases.expand(element.get(path_attr_str))
        else:
            raise InvalidProjectElement(
                "Project element has no name or path attribute")

    def _parse_project_attributes(self, element):
        if element is not None:
            name = element.get(name_attr_str)
            path = element.get(path_attr_str)
            return name, path
        else:
            raise InvalidProjectElement(
                "Project element has no name or path attribute")

    def _get_project_id_from_path(self, element):
        project_path = self._parse_project_path(element)
        return os.path.splitext(os.path.basename(project_path))[0]

    def _parse_project_name(self, element):
        project_id = element.get(name_attr_str)
        if project_id is None:
            project_id = self._get_project_id_from_path(element)
        return project_id

    def _parse_dependent_projects(self, parsed_project_xpath):
        dependencies = []
        for dependency in parsed_project_xpath.findall(dependencies_xpath):
            dependencies.append(self._parse_project_name(dependency))
        return dependencies

    def _update_project_dependencies(self, parsed_project_xpath, projects):
        for project_xml in parsed_project_xpath:
            project_id = self._parse_project_name(project_xml)
            dependencies = self._parse_dependent_projects(project_xml)
            for dependency in dependencies:
                projects[project_id].dependencies.append(projects[dependency])

    def _parse_project(self, project_name, project_xml):
        project_file = self._get_absolute_project_path(project_xml)
        project = Project(project_name,
                          project_file,
                          sdk=self.aliases.sdk,
                          wsroot=self.aliases.wsroot)
        return project

    @staticmethod
    def _project_is_default(element):
        return element.get(default_attr_str) == "yes"

    def _parse_projects_from_xml_source(self, parsed_project_xpath):
        projects = {}
        for project_xml in parsed_project_xpath:
            project_id = self._parse_project_name(project_xml)
            project = self._parse_project(project_id, project_xml)
            if self._project_is_default(project_xml):
                if self.default_project:
                    raise InvalidProjectElement(
                        ("More than one default project in: {ws}.\n"
                         "Found: {new}\n"
                         "Already had: {old}\n").format(
                             ws=self.workspace_xml.filename,
                             old=self.default_project.name,
                             new=project.name))
                self.default_project = project
            projects[project_id] = project
        if not self.default_project:
            raise ParseError(
                "Default project not found in workspace: {}".format(
                    self.workspace_xml.filename))
        return projects

    def parse(self):
        # This is a 2 stage process: 1. Parse all projects. 2. determine dependent projects

        parsed_project_xpath = self.workspace_xml.parse().findall(
            project_xpath)
        projects = self._parse_projects_from_xml_source(parsed_project_xpath)
        self._update_project_dependencies(parsed_project_xpath, projects)
        return projects