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
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
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
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
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)
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)