00001
00002
00003
00004
00005
00006
00007
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
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
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
00063 if (fileCheck(home1)) {
00064 readConfig(home1);
00065 }
00066 delete [] home1;
00067
00068
00069 if (fileCheck(home2)) {
00070 readConfig(home2);
00071 }
00072 delete [] home2;
00073 }
00074
00075
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
00121
00122 void printNetwork(ostream& o, int level, NetworkBase* p, bool ismain)
00123 {
00124 if (level > 0)
00125 {
00126
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
00138
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
00162 for (nrip = 0; nrip < p->nrInPorts(); ++nrip) {
00163 printInPort(o, level, p->getInPort(nrip));
00164 }
00165
00166
00167
00168 for (nrop = 0; nrop < p->nrOutPorts(); ++nrop) {
00169 printOutPort(o, level, p->getOutPort(nrop));
00170 }
00171
00172
00173
00174 for (unsigned int nrpr = 0; nrpr < p->nrProcesses(); ++nrpr) {
00175 printProcess(o, p->getProcess(nrpr));
00176 }
00177
00178
00179
00180 for (unsigned int nrnw = 0; nrnw < p->nrNetworks(); ++nrnw) {
00181 printNetwork(o, level-1, p->getNetwork(nrnw));
00182 }
00183
00184
00185
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
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
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
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) {
00250 otherName = myDestination->parent()->fullName();
00251 }
00252 else if (level == 1) {
00253 otherName = myDestination->parent()->fullName();
00254 }
00255 else {
00256 otherName = myDestination->fullName();
00257 }
00258
00259 o << "\"" << thisName << "\""
00260 << " -> "
00261 << "\"" << otherName << "\""
00262 << ";\n";
00263 }
00264 }
00265 }
00266
00267
00268
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) {
00287 otherName = mySource->parent()->fullName();
00288 }
00289 else if (level == 1) {
00290 otherName = mySource->parent()->fullName();
00291 }
00292 else {
00293 otherName = mySource->fullName();
00294 }
00295
00296 o << "\"" << otherName << "\""
00297 << " -> "
00298 << "\"" << thisName << "\""
00299 << ";\n";
00300 }
00301 }
00302
00303
00304
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) {
00316 sourceName = mySource->parent()->fullName();
00317 }
00318 else if (level == 1) {
00319 sourceName = mySource->parent()->fullName();
00320 }
00321 else {
00322 sourceName = mySource->fullName();
00323 }
00324
00325 if (myDestination->nrDst() == 0) {
00326 destName = myDestination->parent()->fullName();
00327 }
00328 else if (level == 1) {
00329 destName = myDestination->parent()->fullName();
00330 }
00331 else {
00332 destName = myDestination->fullName();
00333 }
00334
00335 if (DotDefs::nodeFifo == "true") {
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 {
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
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 }