DOT.C

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030  
00031 #include "Graph.h"
00032 #include "Node.h"
00033 #include "Edge.h"
00034 #include <string>
00035 #include <stdio.h>
00036  
00037 using namespace Dyninst;
00038 using namespace std;
00039  
00040 bool Graph::printDOT(const std::string& fileName) {
00041     FILE *file = fopen(fileName.c_str(), "w");
00042     if (file == NULL) {
00043         return false;
00044     }
00045 
00046     fprintf(file, "digraph G {\n");
00047 
00048     NodeSet visited;
00049     std::queue<Node::Ptr> worklist;
00050 
00051     NodeIterator entryBegin, entryEnd;
00052     entryNodes(entryBegin, entryEnd);
00053 
00054      // Initialize visitor worklist
00055     for (NodeIterator iter = entryBegin; iter != entryEnd; ++iter) {
00056         worklist.push(*iter);
00057     }
00058 
00059     // Put the entry nodes on their own (minimum) rank
00060     fprintf(file, "  { rank = min;");
00061     for (NodeIterator iter = entryBegin; iter != entryEnd; ++iter) {
00062       fprintf(file, "\"%p\"; ", (*iter).get());
00063     }
00064     fprintf(file, "}\n");
00065 
00066     NodeIterator exitBegin, exitEnd;
00067     exitNodes(exitBegin, exitEnd);
00068 
00069     // Put the entry nodes on their own (minimum) rank
00070     fprintf(file, "  { rank = max;");
00071     for (NodeIterator iter = exitBegin; iter != exitEnd; ++iter) {
00072       fprintf(file, "\"%p\"; ", (*iter).get());
00073     }
00074     fprintf(file, "}\n");
00075     
00076 
00077     while (!worklist.empty()) {
00078         Node::Ptr source = worklist.front();
00079 
00080         worklist.pop();
00081 
00082          //fprintf(stderr, "Considering node %s\n", source->format().c_str());
00083 
00084          // We may have already treated this node...
00085         if (visited.find(source) != visited.end()) {
00086              //fprintf(stderr, "\t skipping previously visited node\n");
00087             continue;
00088         }
00089          //fprintf(stderr, "\t inserting %s into visited set, %d elements pre-insert\n", source->format().c_str(), visited.size());
00090         visited.insert(source);
00091 
00092         fprintf(file, "\t%s\n", source->DOTshape().c_str());
00093         fprintf(file, "\t%s\n", source->DOTrank().c_str());
00094     fprintf(file, "\t\"%p\" [label=\"%s\"];\n", 
00095         source.get(), source->DOTname().c_str());
00096 
00097         NodeIterator outBegin, outEnd;
00098         source->outs(outBegin, outEnd);
00099 
00100         for (; outBegin != outEnd; ++outBegin) {
00101             Node::Ptr target = *outBegin;
00102             if (!target->DOTinclude()) continue;
00103             //fprintf(file, "\t %s -> %s;\n", source->DOTname().c_str(), target->DOTname().c_str());
00104         fprintf(file, "\t \"%p\" -> \"%p\";\n", source.get(), target.get());
00105             if (visited.find(target) == visited.end()) {
00106                  //fprintf(stderr, "\t\t adding child %s\n", target->format().c_str());
00107                 worklist.push(target);
00108             }
00109             else {
00110                  //fprintf(stderr, "\t\t skipping previously visited child %s\n", 
00111                  //target->format().c_str());
00112             }
00113         }
00114     }
00115     fprintf(file, "}\n\n\n");
00116     fclose(file);
00117 
00118     return true;
00119 }
00120 
00121 std::string Node::DOTname() const {
00122     return format();
00123 }
00124 
00125 std::string Node::DOTshape() const {
00126     // Use defaults...
00127     return std::string("// ") + format() + std::string(" [shape=ellipse];");
00128 }
00129 
00130 std::string Node::DOTrank() const {
00131     // Use defaults...
00132     return std::string("// ") + format();
00133 };
00134 
00135 std::string VirtualNode::DOTshape() const {
00136     return format() + std::string(" [shape=box];"); 
00137 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1