/* Soot - a J*va Optimization Framework * Copyright (C) 2005 Jennifer Lhotak * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package ca.mcgill.sable.soot.cfg; import soot.util.dot.*; import ca.mcgill.sable.soot.cfg.model.*; import java.util.*; public class AnnotatedCFGSaver { private CFGGraph graph; private String fileNameBase; private String title; public AnnotatedCFGSaver(CFGGraph graph, String fileNameBase, String title) { this.graph = graph; this.fileNameBase = fileNameBase; this.title = title; } public void saveGraph(){ DotGraph canvas = initGraph(); HashMap nodes = makeNodes(canvas); makeEdges(canvas, nodes); formatNames(canvas, nodes); String fileName = formFileName(); System.out.println("cfg fileName: "+fileName); canvas.plot(fileName); } private DotGraph initGraph(){ DotGraph canvas = new DotGraph(title); canvas.setGraphLabel(title); canvas.setGraphSize(8.0, 10.0); canvas.setOrientation(DotGraphConstants.GRAPH_ORIENT_PORTRAIT); canvas.setNodeShape(DotGraphConstants.NODE_SHAPE_PLAINTEXT); return canvas; } private HashMap makeNodes(DotGraph canvas){ HashMap nodeMap = new HashMap(); Iterator it = graph.getChildren().iterator(); int count = 0; while (it.hasNext()){ CFGNode next = (CFGNode)it.next(); String nodeName = "n"+count; nodeMap.put(next, nodeName); canvas.drawNode(nodeName); count++; } return nodeMap; } private void makeEdges(DotGraph canvas, HashMap nodeMap){ Iterator it = nodeMap.keySet().iterator(); while (it.hasNext()){ CFGNode node = (CFGNode)it.next(); String nodeName = (String)nodeMap.get(node); Iterator inputs = node.getInputs().iterator(); while (inputs.hasNext()){ CFGEdge edge = (CFGEdge)inputs.next(); CFGNode src = edge.getFrom(); String srcName = (String)nodeMap.get(src); canvas.drawEdge(srcName, nodeName); } } } private void formatNames(DotGraph canvas, HashMap nodeMap){ Iterator it = nodeMap.keySet().iterator(); while (it.hasNext()){ CFGNode node = (CFGNode)it.next(); String nodeName = (String)nodeMap.get(node); DotGraphNode dgNode = canvas.getNode(nodeName); dgNode.setHTMLLabel(getNodeLabel(node)); } } private String getNodeLabel(CFGNode node){ StringBuffer sb = new StringBuffer(); sb.append("<<TABLE BORDER=\"0\">"); sb.append("<TR><TD>"); if (node.getBefore() != null) { Iterator before = node.getBefore().getChildren().iterator(); while (before.hasNext()){ Iterator pFlowData = ((CFGPartialFlowData)before.next()).getChildren().iterator(); while (pFlowData.hasNext()){ CFGFlowInfo info = (CFGFlowInfo)pFlowData.next(); String temp = info.getText(); temp = soot.util.StringTools.replaceAll(temp, "<", "<"); temp = soot.util.StringTools.replaceAll(temp, ">", ">"); sb.append(temp); } } } sb.append("</TD></TR>"); sb.append("<TR><TD>"); sb.append("<TABLE>"); sb.append("<TR><TD>"); Iterator data = node.getData().getText().iterator(); while (data.hasNext()){ String temp = data.next().toString(); temp = soot.util.StringTools.replaceAll(temp, "<", "<"); temp = soot.util.StringTools.replaceAll(temp, ">", ">"); sb.append(temp); } sb.append("</TD></TR>"); sb.append("</TABLE>"); sb.append("</TD></TR>"); sb.append("<TR><TD>"); if (node.getAfter() != null){ Iterator after = node.getAfter().getChildren().iterator(); while (after.hasNext()){ Iterator pFlowData = ((CFGPartialFlowData)after.next()).getChildren().iterator(); while (pFlowData.hasNext()){ CFGFlowInfo info = (CFGFlowInfo)pFlowData.next(); String temp = info.getText(); temp = soot.util.StringTools.replaceAll(temp, "<", "<"); temp = soot.util.StringTools.replaceAll(temp, ">", ">"); sb.append(temp); } } } sb.append("</TD></TR>"); sb.append("</TABLE>>"); System.out.println("node data string: "+sb.toString()); return sb.toString(); } private String formFileName(){ StringBuffer sb = new StringBuffer(); sb.append(fileNameBase); String sep = System.getProperty("file.separator"); sb.append(sep); sb.append(title); sb.append(".cfg"); return sb.toString(); } }