Exemplo n.º 1
0
def digraph_to_dot(name, digraph, extract_nodes=[], trans_reduce=False):
    """Generate dot source for for a directed graph.

    Args:
         name (str): Name of the graph.
         digraph (dict): The graph to draw.
         extract_nodes (list, optional): The nodes to remove from the graph.
         trans_reduce: Whether to transitively reduce the graph.

    Returns:
         A string containing the dot source.
    """
    digraph, etps = _extract_nodes(digraph, extract_nodes)
    levels = graphutil.levelize(digraph)

    if trans_reduce:
        digraph = graphutil.transitive_reduce(digraph)

    desc = 'digraph %s {\n' % name
    desc += 'ranksep=0.6; size = "75,75";\n'
    desc += 'bgcolor=grey70;'
    desc += 'style=filled;\n'
    desc += 'color=lightgrey;\n'
    desc += 'subgraph {\n'
    desc += '\tnode [shape=circle, style=filled, fontsize=11];\n'
    desc += '\t' + ' -> '.join(
        reversed([str(l) for l in range(len(levels) + 1)][1:])) + ';\n'
    desc += '}\n'

    desc += 'node [shape=box,style=filled,color=goldenrod3];\n'
    index = 0
    while index < len(levels):
        node_list = ['"' + node + '";' for node in levels[index]]
        desc += '{ rank = same; %d; %s }\n' % (index + 1, ' '.join(node_list))
        index += 1

    for node in digraph:
        children = digraph[node]
        for c in children:
            desc += '\t"%s" -> "%s";\n' % (node, c)

    for etp in etps:
        if etp.parents:
            parent_str = '"_' + ','.join(etp.parents) + '_" ->'
        else:
            parent_str = ''
        if etp.children:
            child_str = '-> "_' + ','.join(etp.children) + '_"'
        else:
            child_str = ''
        desc += 'subgraph cluster {\n'
        desc += ' %s "%s" %s;' % (
            parent_str,  etp.name, child_str)
        desc += '}\n'

    desc += '}\n'

    return desc
Exemplo n.º 2
0
def digraph_to_dot(name, digraph, extract_nodes=[], trans_reduce=False):
    """Generate dot source for for a directed graph.

    Args:
         name (str): Name of the graph.
         digraph (dict): The graph to draw.
         extract_nodes (list, optional): The nodes to remove from the graph.
         trans_reduce: Whether to transitively reduce the graph.

    Returns:
         A string containing the dot source.
    """
    digraph, etps = _extract_nodes(digraph, extract_nodes)
    levels = graphutil.levelize(digraph)

    if trans_reduce:
        digraph = graphutil.transitive_reduce(digraph)

    desc = 'digraph %s {\n' % name
    desc += 'ranksep=0.6; size = "75,75";\n'
    desc += 'bgcolor=grey70;'
    desc += 'style=filled;\n'
    desc += 'color=lightgrey;\n'
    desc += 'subgraph {\n'
    desc += '\tnode [shape=circle, style=filled, fontsize=11];\n'
    desc += '\t' + ' -> '.join(
        reversed([str(l) for l in range(len(levels) + 1)][1:])) + ';\n'
    desc += '}\n'

    desc += 'node [shape=box,style=filled,color=goldenrod3];\n'
    index = 0
    while index < len(levels):
        node_list = ['"' + node + '";' for node in levels[index]]
        desc += '{ rank = same; %d; %s }\n' % (index + 1, ' '.join(node_list))
        index += 1

    for node in digraph:
        children = digraph[node]
        for c in children:
            desc += '\t"%s" -> "%s";\n' % (node, c)

    for etp in etps:
        if etp.parents:
            parent_str = '"_' + ','.join(etp.parents) + '_" ->'
        else:
            parent_str = ''
        if etp.children:
            child_str = '-> "_' + ','.join(etp.children) + '_"'
        else:
            child_str = ''
        desc += 'subgraph cluster {\n'
        desc += ' %s "%s" %s;' % (
            parent_str,  etp.name, child_str)
        desc += '}\n'

    desc += '}\n'

    return desc
Exemplo n.º 3
0
    def test_levelize(self):
        levels = graphutil.levelize(self.group_dep)
        exp_levels = [
            set(['bsl']),
            set(['bde', 'bst']),
            set(['bce', 'bbe']),
            set(['bte', 'bae'])
        ]

        self.assertEqual(levels, exp_levels)

        graph1 = {'a': ['b'], 'b': ['c'], 'c': ['b']}
        try:
            levels = graphutil.levelize(graph1)
            self.AssertFalse(True)
        except blderror.CycleError:
            # print(e.message)
            pass
Exemplo n.º 4
0
    def test_levelize(self):
        levels = graphutil.levelize(self.group_dep)
        exp_levels = [
            set(['bsl']),
            set(['bde', 'bst']),
            set(['bce', 'bbe']),
            set(['bte', 'bae'])
        ]

        self.assertEqual(levels, exp_levels)

        graph1 = {
            'a': ['b'],
            'b': ['c'],
            'c': ['b']
        }
        try:
            levels = graphutil.levelize(graph1)
            self.AssertFalse(True)
        except blderror.CycleError:
            # print(e.message)
            pass
Exemplo n.º 5
0
    def load_uor(uor):
        # Preserve the existing behavior of loading defs, opts and cap files as
        # bde_build:
        #
        # - Exported options of an UOR: read the defs files of its dependencies
        #   follow by itself. The files of the dependencies should be read in
        #   topological order, if the order of certain dependencies are
        #   ambiguous, order them first by dependency levels, and then by their
        #   name.
        #
        # - Internal options of an UOR: read the defs files in the same way,
        #   followed by its own opts file.

        dep_levels = graphutil.levelize(uor_dep_graph,
                                        uor_dep_graph[uor.name])

        oe = copy.deepcopy(def_oe)
        # We load options in levelized order instead of any topological order
        # to preserve the behavior with bde_build (older version of the build
        # tool).  Note that we cannot cache intermediate results because later
        # option rules may change the results from the preivous rule.
        for level in dep_levels:
            for dep_name in sorted(level):
                if dep_name not in build_config.external_dep and \
                   dep_name not in build_config.third_party_dirs:
                    dep_uor = uor_map[dep_name]
                    oe.store_option_rules(dep_uor.cap)
                    oe.store_option_rules(dep_uor.defs)

        if (build_config.uplid.os_type == 'windows' and
                build_config.uplid.comp_type == 'cl'):
            # By default, Visual Studio uses a single pdb file for all object
            # files compiled from a particular directory named
            # vc<vs_version>.pdb.  We want to use a separate pdb file for each
            # package group and standard alone package.
            #
            # BDE_CXXFLAGS and BDE_CFLAGS are defined by default.opts, so the
            # code below is a bit hackish.
            pdb_option = ' /Fd%s\\%s.pdb' % (
                os.path.relpath(uor.path, build_config.root_path), uor.name)
            oe.results['BDE_CXXFLAGS'] += pdb_option
            oe.results['BDE_CFLAGS'] += pdb_option

        if uor.type_ == repounits.UnitType.GROUP:
            uor_bc = buildconfig.PackageGroupBuildConfig()
        elif uor.type_ in repounits.UnitTypeCategory.PACKAGE_STAND_ALONE_CAT:
            uor_bc = buildconfig.StdalonePackageBuildConfig()
        else:
            assert(False)

        uor_bc.name = uor.name
        uor_bc.path = uor.path
        uor_bc.doc = uor.doc
        uor_bc.version = uor.version
        uor_bc.dep = uor.dep - build_config.external_dep
        uor_bc.external_dep = uor.dep & build_config.external_dep

        # Store options from dependencies, options for exports, and internal
        # options separately

        dep_oe = copy.deepcopy(oe)
        dep_oe.evaluate()
        oe.store_option_rules(uor.cap)
        oe.store_option_rules(uor.defs)
        set_unit_loc(oe, uor)
        export_oe = copy.deepcopy(oe)
        int_oe = copy.deepcopy(oe)
        export_oe.evaluate()
        if export_oe.results.get('CAPABILITY') == 'NEVER':
            logutil.warn('Skipped non-supported UOR %s' % uor.name)
            return

        int_oe.store_option_rules(uor.opts)

        # Copy unevaluted internal options to be used by packages within
        # package groups.
        int_oe_copy = copy.deepcopy(int_oe)
        if debug_keys:
            logutil.info('--Evaluating %s' % uor.name)
        int_oe.evaluate(debug_keys)

        # Remove export flags of an uor's dependencies from its own export
        # flags.  This implementation is not very optimal, but it's gets the
        # job done.
        dep_flags = get_build_flags_from_opts(build_flags_parser,
                                              dep_oe.results, dep_oe.results)

        uor_bc.flags = get_build_flags_from_opts(
            build_flags_parser, int_oe.results, export_oe.results,
            dep_flags.export_flags, dep_flags.export_libs)

        if uor.type_ == repounits.UnitType.GROUP:
            load_package_group(uor, uor_bc, int_oe_copy)
        elif uor.type_ in repounits.UnitTypeCategory.PACKAGE_STAND_ALONE_CAT:
            load_sa_package(uor, uor_bc)
        else:
            assert(False)
Exemplo n.º 6
0
    def load_uor(uor):
        # Preserve the existing behavior of loading defs, opts and cap files as
        # bde_build:
        #
        # - Exported options of an UOR: read the defs files of its dependencies
        #   follow by itself. The files of the dependencies should be read in
        #   topological order, if the order of certain dependencies are
        #   ambiguous, order them first by dependency levels, and then by their
        #   name.
        #
        # - Internal options of an UOR: read the defs files in the same way,
        #   followed by its own opts file.

        dep_levels = graphutil.levelize(uor_dep_graph, uor_dep_graph[uor.name])

        oe = copy.deepcopy(def_oe)
        # We load options in levelized order instead of any topological order
        # to preserve the behavior with bde_build (older version of the build
        # tool).  Note that we cannot cache intermediate results because later
        # option rules may change the results from the preivous rule.
        for level in dep_levels:
            for dep_name in sorted(level):
                if dep_name not in build_config.external_dep and \
                   dep_name not in build_config.third_party_dirs:
                    dep_uor = uor_map[dep_name]
                    oe.store_option_rules(dep_uor.cap)
                    oe.store_option_rules(dep_uor.defs)

        if (build_config.uplid.os_type == 'windows'
                and build_config.uplid.comp_type == 'cl'):
            # By default, Visual Studio uses a single pdb file for all object
            # files compiled from a particular directory named
            # vc<vs_version>.pdb.  We want to use a separate pdb file for each
            # package group and standard alone package.
            #
            # BDE_CXXFLAGS and BDE_CFLAGS are defined by default.opts, so the
            # code below is a bit hackish.
            pdb_option = ' /Fd%s\\%s.pdb' % (os.path.relpath(
                uor.path, build_config.root_path), uor.name)
            oe.results['BDE_CXXFLAGS'] += pdb_option
            oe.results['BDE_CFLAGS'] += pdb_option

        if uor.type_ == repounits.UnitType.GROUP:
            uor_bc = buildconfig.PackageGroupBuildConfig()
        elif uor.type_ in repounits.UnitTypeCategory.PACKAGE_STAND_ALONE_CAT:
            uor_bc = buildconfig.StdalonePackageBuildConfig()
        else:
            assert (False)

        uor_bc.name = uor.name
        uor_bc.path = uor.path
        uor_bc.doc = uor.doc
        uor_bc.version = uor.version
        uor_bc.dep = uor.dep - build_config.external_dep
        uor_bc.external_dep = uor.dep & build_config.external_dep

        # Store options from dependencies, options for exports, and internal
        # options separately

        dep_oe = copy.deepcopy(oe)
        dep_oe.evaluate()
        oe.store_option_rules(uor.cap)
        oe.store_option_rules(uor.defs)
        set_unit_loc(oe, uor)
        export_oe = copy.deepcopy(oe)
        int_oe = copy.deepcopy(oe)
        export_oe.evaluate()
        if export_oe.results.get('CAPABILITY') == 'NEVER':
            logutil.warn('Skipped non-supported UOR %s' % uor.name)
            return

        int_oe.store_option_rules(uor.opts)

        # Copy unevaluted internal options to be used by packages within
        # package groups.
        int_oe_copy = copy.deepcopy(int_oe)
        if debug_keys:
            logutil.info('--Evaluating %s' % uor.name)
        int_oe.evaluate(debug_keys)

        # Remove export flags of an uor's dependencies from its own export
        # flags.  This implementation is not very optimal, but it's gets the
        # job done.
        dep_flags = get_build_flags_from_opts(build_flags_parser,
                                              dep_oe.results, dep_oe.results)

        uor_bc.flags = get_build_flags_from_opts(build_flags_parser,
                                                 int_oe.results,
                                                 export_oe.results,
                                                 dep_flags.export_flags,
                                                 dep_flags.export_libs)

        if uor.type_ == repounits.UnitType.GROUP:
            load_package_group(uor, uor_bc, int_oe_copy)
        elif uor.type_ in repounits.UnitTypeCategory.PACKAGE_STAND_ALONE_CAT:
            load_sa_package(uor, uor_bc)
        else:
            assert (False)