package jqian.sootex.util.graph; import java.util.*; import jqian.util.graph.Graph; import jqian.util.graph.GraphEdge; import jqian.util.graph.GraphNode; import soot.toolkits.graph.*; /** * @author bruteforce * */ public class GraphHelper { public static Set<?> getReachables(DirectedGraph<Object> graph,Object start){ return getReachables(graph, start,null); } public static Set<?> getReachables(DirectedGraph<Object> graph,Object start,Object block){ Collection<Object> starts = new ArrayList<Object>(1); starts.add(start); return getReachables(graph, starts,block); } public static Set<?> getReachables(DirectedGraph<Object> graph, Collection<?> starts, Object block) { Set<Object> results = new HashSet<Object>(); Stack<Object> stack = new Stack<Object>(); Set<Object> inStack = new HashSet<Object>(); stack.addAll(starts); inStack.addAll(starts); while (!stack.isEmpty()) { Object top = stack.pop(); inStack.remove(top); //if meet a block node, can not pass it if(block!=null && top==block){ continue; } if (!results.add(top)) { continue; } List<Object> nexts = graph.getSuccsOf(top); if (nexts == null) continue; for (Iterator<Object> it = nexts.iterator(); it.hasNext();) { Object succ = it.next(); if (!results.contains(succ) && !inStack.contains(succ)) { stack.add(succ); inStack.add(succ); } } } return results; } public static class LabelProvider{ public String getLabel(Object o){ return o.toString(); } } @SuppressWarnings("rawtypes") public static Graph toDisplayGraph(DirectedGraph graph, String graphName){ return toDisplayGraph(graph, graphName, new LabelProvider()); } @SuppressWarnings({ "rawtypes", "unchecked" }) public static Graph toDisplayGraph(DirectedGraph graph, String graphName, LabelProvider labelProvider){ Graph cfg = new Graph(graphName); Map<Object,GraphNode> object2Node=new HashMap<Object,GraphNode>(graph.size()*2+1,0.7f); for (Iterator<Object> it = graph.iterator(); it.hasNext();) { Object o = it.next(); String label = labelProvider.getLabel(o); GraphNode node = new GraphNode(label); cfg.addNode(node); object2Node.put(o, node); } for(Iterator<Object> it = graph.iterator();it.hasNext();){ Object from = it.next(); List lst = graph.getSuccsOf(from); Iterator sit = lst.listIterator(); while (sit.hasNext()) { Object to = sit.next(); GraphNode fromNode = object2Node.get(from); GraphNode toNode = object2Node.get(to); cfg.addEdge(new GraphEdge(fromNode,toNode)); } } return cfg; } }