Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members

dotty.cc

Go to the documentation of this file.
00001 /*--------------------------------------------------------------------
00002  *
00003  * (C) Copyright Koninklijke Philips Electronics NV 2006. 
00004  * All rights reserved. This software is licensed under the terms of
00005  * version 2.1 of the GNU Lesser General Public License as published 
00006  * by the Free Software Foundation. For licensing and warranty
00007  * information, see the file COPYING in the main directory.
00008  *
00009  *------------------------------------------------------------------*/
00010 
00011 #include <sys/types.h>
00012 #include "dotty.h"
00013 #include "id.h"
00014 #include "component.h"
00015 #include "connector.h"
00016 #include "networkbase.h"
00017 #include "processbase.h"
00018 #include "portbase.h"
00019 #include "fifobase.h"
00020 #include "dotdefs.h"
00021 #include "check.h"
00022 #include <stdio.h>
00023 
00024 using std::ostream;
00025 using std::string;
00026 
00027 // Print Functions
00028 void printDotty(ostream& o, NetworkBase* p);
00029 void printNetwork(ostream& o, int level, NetworkBase* p, bool ismain = false);
00030 void printProcess(ostream& o, ProcessBase* p);
00031 void printInPort(ostream& o, int level, InPortBase* p);
00032 void printOutPort(ostream& o, int level, OutPortBase* p);
00033 void printFifo(ostream& o, int level, FifoBase* p);
00034 
00035 // File Functions
00036 bool fileCheck(const char* fileName);
00037 void readConfig(const char* filePlace);
00038 
00039 static ostream* g_errorStream = &std::cerr;
00040 
00041 void printDotty(const ProcessNetwork& p, ostream& o, ostream& e)
00042 {
00043   g_errorStream = &e;
00044   printDotty(o, (NetworkBase*)&p);
00045 }
00046 
00047 void printDotty(ostream& o, NetworkBase* p)
00048 {
00049   const char* current = "dotty.cfg";
00050   char* home = getenv("HOME");
00051 
00052   if (home) {
00053     const char* cfgVisible = "/dotty.cfg";
00054     const char* cfgHidden = "/.dotty.cfg";
00055     char* home1 = new char[strlen(home) + strlen(cfgHidden) + 1];
00056     char* home2 = new char[strlen(home) + strlen(cfgVisible) + 1];
00057     strcpy(home1, home);
00058     strcpy(home2, home);
00059     strcat(home1, cfgHidden);
00060     strcat(home2, cfgVisible);
00061 
00062     // check for .dotty.cfg in the home directory
00063     if (fileCheck(home1)) {
00064       readConfig(home1);
00065     } 
00066     delete [] home1;
00067     
00068     // check for dotty.cfg in the home directory
00069     if (fileCheck(home2)) {
00070       readConfig(home2);
00071     }
00072     delete [] home2;
00073   } 
00074 
00075   // check for dotty.cfg in the current directory
00076   if (fileCheck(current)) {
00077     readConfig(current);
00078   }
00079 
00080   if (check(p, *g_errorStream) > 0)
00081   {
00082     *g_errorStream << "Errors in process network, cannot print dotty" << std::endl;
00083     return;
00084   }
00085 
00086   if (uniqueId(p, *g_errorStream) > 0)
00087   {
00088     *g_errorStream << "IDs in process network are not unique, cannot print dotty" << std::endl;
00089     return;
00090   }
00091 
00092         
00093   o << "digraph \"" << p->fullName() << "\" {\n"
00094   << " label=\"" << p->name()
00095   << " (" << p->type() << ")\";\n"
00096   << " fontname="   << DotDefs::fontNameClusterTitle << ";\n"
00097   << " fontsize="   << DotDefs::fontSizeClusterTitle << ";\n"
00098   << " fontcolor="  << DotDefs::fontColorClusterTitle << ";\n"
00099   << " rankdir="    << DotDefs::rankDir << ";\n"
00100   << " size="   << DotDefs::size << ";\n"
00101   << " ratio="    << DotDefs::ratio << ";\n"
00102   << " nodesep="    << DotDefs::nodeSep << ";\n"
00103   << " orientation="  << DotDefs::orientation << ";\n"
00104   << " center="   << DotDefs::center << ";\n"
00105   << " margin="   << DotDefs::margin << ";\n"
00106   << " node [shape="  << DotDefs::nodeShapeProcess << ",\n"
00107   << "       width="  << DotDefs::nodeWidthProcess << ",\n"
00108   << "       height=" << DotDefs::nodeHeightProcess << ",\n"
00109   << "       style="  << DotDefs::nodeStyle << "];\n"
00110   << " edge [decorate=" << DotDefs::edgeDecorate << ",\n"
00111   << "       weight=" << DotDefs::edgeWeight << ",\n"
00112   << "       minlen=" << DotDefs::edgeMinLen << "];\n\n";
00113 
00114   printNetwork(o, DotDefs::levelInit, p, true);
00115 
00116   o << "}\n\n";  
00117 }
00118 
00119 
00120 // Network
00121 
00122 void printNetwork(ostream& o, int level, NetworkBase* p, bool ismain)
00123 {
00124   if (level > 0)
00125   {
00126     // print Level as a Cluster
00127     if (!ismain)
00128     {
00129       o << "\n\nsubgraph \"cluster_" << p->fullName() << "\"{\n"
00130       << " label=\"" << p->name()
00131       << " (" << p->type() << ")\";\n"
00132       << " fontname=" << DotDefs::fontNameClusterTitle << ";\n"
00133       << " fontcolor=" << DotDefs::fontColorClusterTitle << ";\n"
00134       << " fontsize=" << DotDefs::fontSizeClusterTitle << ";\n";
00135           } 
00136 
00137     // Make sure InPorts are at beginning and OutPorts are at end
00138     // to improve the networkport layout
00139 
00140     unsigned int nrip = 0;
00141     if (nrip < p->nrInPorts()) 
00142     {
00143       o << "{rank = min";
00144       for (nrip = 0; nrip < p->nrInPorts(); ++nrip) 
00145       {
00146         o << ";\n\"" << p->getInPort(nrip)->fullName() << "\"";
00147           }
00148       o << "};\n\n";
00149     }    
00150 
00151           unsigned int nrop = 0;
00152     if (nrop < p->nrOutPorts()) {
00153       o << "{rank = max";
00154       for (nrop = 0; nrop < p->nrOutPorts(); ++nrop)
00155       {
00156         o << ";\n\"" << p->getOutPort(nrop)->fullName() << "\"";
00157       }
00158       o << "};\n\n";
00159     }    
00160   
00161     // InPorts
00162     for (nrip = 0; nrip < p->nrInPorts(); ++nrip) {
00163       printInPort(o, level, p->getInPort(nrip));
00164     }
00165   
00166    
00167     // OutPorts
00168     for (nrop = 0; nrop < p->nrOutPorts(); ++nrop) {
00169       printOutPort(o, level, p->getOutPort(nrop));
00170     }
00171      
00172      
00173     // Processes
00174     for (unsigned int nrpr = 0; nrpr < p->nrProcesses(); ++nrpr) {
00175       printProcess(o, p->getProcess(nrpr));
00176     }    
00177   
00178 
00179     // Networks
00180     for (unsigned int nrnw = 0; nrnw < p->nrNetworks(); ++nrnw) {
00181       printNetwork(o, level-1, p->getNetwork(nrnw));
00182     }    
00183 
00184 
00185     // Fifos
00186     for (unsigned int nrfi = 0; nrfi < p->nrFifos(); ++nrfi) {
00187       printFifo(o, level, p->getFifo(nrfi));
00188     }    
00189      
00190     if (!ismain) {
00191       o << "}\n\n";
00192     }
00193 
00194   } else {
00195     // print Level as a Node                         
00196     
00197     int li = DotDefs::levelInit + 1;
00198   
00199     o << "\"" << p->fullName() << "\""
00200     << " [label=\"" << p->name() << "\\n(" << p->type() << ")"
00201     << "|" << li << "\""
00202     << ", shape=" << DotDefs::nodeShapeProcessNetwork
00203     << ", width=" << DotDefs::nodeWidthProcessNetwork
00204     << ", height=" << DotDefs::nodeHeightProcessNetwork
00205     << ", style=" << DotDefs::nodeStyle
00206     << ", fontname=" << DotDefs::fontNameProcessNetwork
00207     << ", fontcolor=" << DotDefs::fontColorProcessNetwork
00208     << ", fontsize=" << DotDefs::fontSizeProcessNetwork
00209     << ", color=" << DotDefs::nodeColorProcessNetwork << "];\n";
00210   }
00211 }
00212 
00213 
00214 // Process
00215 
00216 void printProcess(ostream& o, ProcessBase* p)
00217 {
00218   o << "\"" << p->fullName() << "\""
00219   << " [label=\"" << p->name() 
00220   << "\\n(" << p->type() << ")\""
00221   << ", fontname=" << DotDefs::fontNameProcess
00222   << ", fontsize=" << DotDefs::fontSizeProcess
00223   << ", fontcolor=" << DotDefs::fontColorProcess
00224   << ", color=" << DotDefs::nodeColorProcess << "];\n";
00225 }
00226 
00227 
00228 // InPort
00229 
00230 void printInPort(ostream& o, int level, InPortBase* p)
00231 {
00232   o << "\"" << p->fullName() << "\""
00233     << " [label=\"" << p->name() << "\""
00234     << ", shape=" << DotDefs::nodeShapePort 
00235     << ", color=" << DotDefs::nodeColorPort
00236     << ", width=" << DotDefs::nodeWidthPort
00237     << ", height="  << DotDefs::nodeHeightPort
00238     << ", fontname="  << DotDefs::fontNamePort
00239     << ", fontcolor=" << DotDefs::fontColorPort
00240     << ", fontsize="  << DotDefs::fontSizePort << "];\n";
00241       
00242   if (level > 0) {
00243     string otherName, thisName = p->fullName();
00244     
00245     for(unsigned int i=0; i<p->nrDst(); i++)
00246     {
00247       InPortBase* myDestination = p->getDstPort(i);
00248         
00249       if (myDestination->nrDst() == 0) {  // processInPort
00250         otherName = myDestination->parent()->fullName();
00251       }
00252       else if (level == 1) {  // networkLevel
00253         otherName = myDestination->parent()->fullName(); 
00254       }
00255       else {  // networkInPort  
00256         otherName = myDestination->fullName();
00257       }  
00258 
00259       o << "\"" << thisName << "\""
00260         << " -> "
00261         << "\"" << otherName << "\""
00262         << ";\n";
00263     }
00264   }
00265 }       
00266 
00267 
00268 // OutPort
00269 
00270 void printOutPort(ostream& o, int level, OutPortBase* p)
00271 {
00272     o << "\"" << p->fullName() << "\""
00273       << " [label=\"" << p->name() << "\""
00274       << ", shape=" << DotDefs::nodeShapePort 
00275       << ", color=" << DotDefs::nodeColorPort
00276       << ", width=" << DotDefs::nodeWidthPort
00277       << ", height="  << DotDefs::nodeHeightPort
00278       << ", fontname="  << DotDefs::fontNamePort
00279       << ", fontcolor=" << DotDefs::fontColorPort
00280       << ", fontsize="  << DotDefs::fontSizePort << "];\n";
00281       
00282   if (level > 0) {
00283     string otherName, thisName = p->fullName();
00284     OutPortBase* mySource = p->getSrcPort();
00285         
00286     if (mySource->nrSrc() == 0) {                      // processOutPort  
00287       otherName = mySource->parent()->fullName();
00288     }
00289     else if (level == 1) {                             // networkLevel
00290       otherName = mySource->parent()->fullName();  
00291     }
00292     else {                                        // networkOutPort
00293       otherName = mySource->fullName();
00294     }
00295 
00296     o << "\"" << otherName << "\""
00297       << " -> "
00298       << "\"" << thisName << "\""
00299       << ";\n";
00300   }
00301 }       
00302 
00303 
00304 // Fifo
00305 
00306 void printFifo(ostream& o, int level, FifoBase* p)
00307 {   
00308   for(unsigned int i=0; i<p->nrDst(); i++)
00309   {
00310     OutPortBase* mySource = p->srcPort();
00311     InPortBase* myDestination = p->dstPort(i);
00312 
00313     string sourceName, destName, fifoName = p->fullName();
00314   
00315     if (mySource->nrSrc() == 0) {                        // processOutPort
00316       sourceName = mySource->parent()->fullName();
00317     }
00318     else if (level == 1) {                               // networkLevel
00319       sourceName = mySource->parent()->fullName();
00320     }
00321     else {                                          // networkOutPort
00322       sourceName = mySource->fullName();    
00323     }
00324     
00325     if (myDestination->nrDst() == 0) {                   // processInPort
00326       destName = myDestination->parent()->fullName();
00327     }
00328     else if (level == 1) {                               // networkLevel
00329       destName = myDestination->parent()->fullName();
00330     }  
00331     else {                                          // networkInPort
00332       destName = myDestination->fullName();
00333     }
00334    
00335     if (DotDefs::nodeFifo == "true") {        // print Fifo as a Node
00336 
00337         o << "\"" << p->fullName() << "\""
00338           << " [label=\"" << p->name() << "\""
00339           << ", shape="   << DotDefs::nodeShapeFifo 
00340           << ", color="   << DotDefs::nodeColorFifo
00341           << ", width="   << DotDefs::nodeWidthFifo
00342           << ", height="  << DotDefs::nodeHeightFifo
00343           << ", fontname="  << DotDefs::fontNameFifo
00344           << ", fontcolor=" << DotDefs::fontColorFifo
00345           << ", fontsize="  << DotDefs::fontSizeFifo << "];\n";
00346 
00347         o << "\"" << sourceName << "\""
00348           << " -> "
00349           << "\"" << fifoName << "\""
00350           << ";\n";
00351   
00352         o << "\"" << fifoName << "\""
00353           << " -> "
00354           << "\"" << destName << "\""
00355           << ";\n";
00356     }
00357     else {                                    // print Fifo as an Edge
00358 
00359          o << "\"" << sourceName << "\" -> \"" << destName << "\""
00360            << " [ label = \"" << p->name() << "\""
00361            << ",  fontname="  << DotDefs::fontNameFifo
00362            << ",  fontcolor=" << DotDefs::fontColorFifo
00363            << ",  fontsize="  << DotDefs::fontSizeFifo << "];\n";
00364     }
00365   }
00366 }
00367 
00368 
00369 // File Functions
00370 
00371 bool fileCheck(const char* fileName)
00372 {
00373     FILE* fp = fopen(fileName, "r");
00374     if (fp) {
00375         fclose(fp);
00376   return true;
00377     }
00378     else return false;
00379 }
00380 
00381 void readConfig(const char* filePlace)
00382 {
00383     extern bool readDottyConfiguration(const char* f, ostream&);
00384     readDottyConfiguration(filePlace, *g_errorStream);
00385 }  

Generated on Wed Feb 15 14:52:38 2006 for yapi by doxygen 1.3.2