drawschema.cpp File Reference

Implement block-diagram schema generation in svg or postscript format. More...

#include <stdio.h>
#include <ctype.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <ostream>
#include <sstream>
#include <set>
#include <utility>
#include <map>
#include <stack>
#include <string>
#include "boxes.hh"
#include "ppbox.hh"
#include "prim2.hh"
#include <vector>
#include "devLib.h"
#include "xtended.hh"
#include "occurrences.hh"
#include "boxcomplexity.h"
#include "schema.h"
#include "drawschema.hh"
#include "compatibility.hh"
#include "names.hh"
Include dependency graph for drawschema.cpp:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define linkcolor   "#003366"
#define normalcolor   "#4B71A1"
#define uicolor   "#477881"
#define slotcolor   "#47945E"
#define numcolor   "#f44800"

Functions

static void writeSchemaFile (Tree bd)
 Write a top level diagram.
static schemagenerateDiagramSchema (Tree t)
 Generate an appropriate schema according to the type of block diagram.
static schemagenerateInsideSchema (Tree t)
 Generate the inside schema of a block diagram according to its type.
static void scheduleDrawing (Tree t)
 Schedule a makeBlockSchema diagram to be drawn.
static bool pendingDrawing (Tree &t)
 Retrieve next block diagram that must be drawn.
static schemagenerateAbstractionSchema (schema *x, Tree t)
 Generate an abstraction schema by placing in sequence the input slots and the body.
static schemagenerateOutputSlotSchema (Tree a)
 Generate a 0->1 block schema for an output slot.
static schemagenerateInputSlotSchema (Tree a)
 Generate a 1->0 block schema for an input slot.
static schemagenerateBargraphSchema (Tree t)
 Generate a 1->1 block schema for a user interface bargraph.
static schemagenerateUserInterfaceSchema (Tree t)
 Generate a 0->1 block schema for a user interface element.
static char * legalFileName (Tree t, int n, char *dst)
 Transform the definition name property of tree <t> into a legal file name.
static int cholddir ()
 Switch back to the previously stored current directory.
static int mkchdir (const char *dirname)
 Create a new directory in the current one to store the diagrams.
void drawSchema (Tree bd, const char *projname, const char *dev)
 The entry point to generate from a block diagram as a set of svg files stored in the directory "<projname>-svg/" or "<projname>-ps/" depending of <dev>.

Variables

int gFoldThreshold
static OccurrencesgOccurrences
static bool sFoldingFlag
static stack< TreegPendingExp
static set< TreegDrawnExp
static const char * gDevSuffix
static char gCurrentDir [512]
static string gSchemaFileName
static map< Tree, string > gBackLink

Detailed Description

Implement block-diagram schema generation in svg or postscript format.

The result is a folder containing one or more schema files in svg or ps format. Complex block-diagrams are automatically splitted.

Definition in file drawschema.cpp.


Define Documentation

#define linkcolor   "#003366"

Definition at line 112 of file drawschema.cpp.

Referenced by generateDiagramSchema().

#define normalcolor   "#4B71A1"

Definition at line 113 of file drawschema.cpp.

Referenced by generateInsideSchema().

#define numcolor   "#f44800"

Definition at line 116 of file drawschema.cpp.

Referenced by generateInsideSchema().

#define slotcolor   "#47945E"

Definition at line 115 of file drawschema.cpp.

Referenced by generateInputSlotSchema(), and generateOutputSlotSchema().

#define uicolor   "#477881"

Definition at line 114 of file drawschema.cpp.

Referenced by generateBargraphSchema(), and generateUserInterfaceSchema().


Function Documentation

static int cholddir (  )  [static]

Switch back to the previously stored current directory.

Definition at line 273 of file drawschema.cpp.

References gCurrentDir.

Referenced by drawSchema().

00274 {
00275     if (chdir(gCurrentDir) == 0) {
00276         return 0;
00277     } else {
00278         perror("cholddir");
00279         exit(errno);
00280     }
00281 }

Here is the caller graph for this function:

void drawSchema ( Tree  bd,
const char *  projname,
const char *  dev 
)

The entry point to generate from a block diagram as a set of svg files stored in the directory "<projname>-svg/" or "<projname>-ps/" depending of <dev>.

Definition at line 158 of file drawschema.cpp.

References boxComplexity(), cholddir(), gDevSuffix, gFoldThreshold, mkchdir(), pendingDrawing(), scheduleDrawing(), sFoldingFlag, and writeSchemaFile().

Referenced by main(), and printDocDgm().

00159 {
00160     gDevSuffix      = dev;
00161     sFoldingFlag    = boxComplexity(bd) > gFoldThreshold;
00162 
00163     mkchdir(projname);          // create a directory to store files
00164 
00165     scheduleDrawing(bd);        // schedule the initial drawing
00166 
00167     Tree t; while (pendingDrawing(t)) {
00168         writeSchemaFile(t);     // generate all the pending drawing
00169     }
00170 
00171     cholddir();                 // return to current directory
00172 }

Here is the call graph for this function:

Here is the caller graph for this function:

static schema * generateAbstractionSchema ( schema x,
Tree  t 
) [static]

Generate an abstraction schema by placing in sequence the input slots and the body.

Definition at line 491 of file drawschema.cpp.

References generateDiagramSchema(), generateInputSlotSchema(), isBoxSymbolic(), makeParSchema(), and makeSeqSchema().

Referenced by generateInsideSchema().

00492 {
00493     Tree    a,b;
00494 
00495     while (isBoxSymbolic(t,a,b)) {
00496         x = makeParSchema(x, generateInputSlotSchema(a));
00497         t = b;
00498     }
00499     return makeSeqSchema(x, generateDiagramSchema(t));
00500 }

Here is the call graph for this function:

Here is the caller graph for this function:

static schema * generateBargraphSchema ( Tree  t  )  [static]

Generate a 1->1 block schema for a user interface bargraph.

Definition at line 453 of file drawschema.cpp.

References makeBlockSchema(), and uicolor.

Referenced by generateInsideSchema().

00454 {
00455     stringstream    s;
00456     s << boxpp(t);
00457 
00458     return makeBlockSchema(1, 1, s.str(), uicolor, "");
00459 }

Here is the call graph for this function:

Here is the caller graph for this function:

static schema * generateDiagramSchema ( Tree  t  )  [static]

Generate an appropriate schema according to the type of block diagram.

When folding is requiered, instead of going down block-diagrams with a name, schedule them for an individual file.

Definition at line 318 of file drawschema.cpp.

References boxComplexity(), gDevSuffix, generateInsideSchema(), getBoxType(), getDefNameProperty(), isBoxSlot(), legalFileName(), linkcolor, makeBlockSchema(), makeDecorateSchema(), scheduleDrawing(), sFoldingFlag, and tree2str().

Referenced by generateAbstractionSchema(), and generateInsideSchema().

00319 {
00320     Tree    id;
00321     int     ins, outs;
00322 
00323     //cerr << t << " generateDiagramSchema " << boxpp(t)<< endl;
00324 
00325     if (getDefNameProperty(t, id)) {
00326         stringstream    s; s << tree2str(id);
00327         //cerr << t << "\tNAMED : " << s.str() << endl;
00328     }
00329 
00330     if ( sFoldingFlag && /*(gOccurrences->getCount(t) > 0) &&*/
00331             (boxComplexity(t) > 2) && getDefNameProperty(t, id)) {
00332         char    temp[1024];
00333         getBoxType(t, &ins, &outs);
00334         stringstream s, l;
00335         s << tree2str(id);
00336         l << legalFileName(t,1024,temp) << "." << gDevSuffix;
00337         scheduleDrawing(t);
00338         return makeBlockSchema(ins, outs, s.str(), linkcolor, l.str());
00339 
00340     } else  if (getDefNameProperty(t, id) && ! isBoxSlot(t)) {
00341         // named case : not a slot, with a name
00342         // draw a line around the object with its name
00343         stringstream    s; s << tree2str(id);
00344         return makeDecorateSchema(generateInsideSchema(t), 10, s.str());
00345 
00346     } else {
00347         // normal case
00348         return generateInsideSchema(t);
00349     }
00350 }

Here is the call graph for this function:

Here is the caller graph for this function:

static schema * generateInputSlotSchema ( Tree  a  )  [static]

Generate a 1->0 block schema for an input slot.

Definition at line 466 of file drawschema.cpp.

References getDefNameProperty(), makeBlockSchema(), slotcolor, and tree2str().

Referenced by generateAbstractionSchema(), and generateInsideSchema().

00467 {
00468     Tree id; assert(getDefNameProperty(a, id));
00469     stringstream s; s << tree2str(id);
00470     return makeBlockSchema(1, 0, s.str(), slotcolor, "");
00471 }

Here is the call graph for this function:

Here is the caller graph for this function:

static schema * generateInsideSchema ( Tree  t  )  [static]

Generate the inside schema of a block diagram according to its type.

Definition at line 358 of file drawschema.cpp.

References xtended::arity(), ffarity(), ffname(), generateAbstractionSchema(), generateBargraphSchema(), generateDiagramSchema(), generateInputSlotSchema(), generateOutputSlotSchema(), generateUserInterfaceSchema(), getDefNameProperty(), getUserData(), isBoxButton(), isBoxCheckbox(), isBoxCut(), isBoxFConst(), isBoxFFun(), isBoxFVar(), isBoxHBargraph(), isBoxHGroup(), isBoxHSlider(), isBoxInt(), isBoxMerge(), isBoxNumEntry(), isBoxPar(), isBoxPrim0(), isBoxPrim1(), isBoxPrim2(), isBoxPrim3(), isBoxPrim4(), isBoxPrim5(), isBoxReal(), isBoxRec(), isBoxSeq(), isBoxSlot(), isBoxSplit(), isBoxSymbolic(), isBoxTGroup(), isBoxVBargraph(), isBoxVGroup(), isBoxVSlider(), isBoxWire(), makeBlockSchema(), makeCableSchema(), makeCutSchema(), makeDecorateSchema(), makeMergeSchema(), makeParSchema(), makeRecSchema(), makeSeqSchema(), makeSplitSchema(), xtended::name(), name(), normalcolor, numcolor, prim0name(), prim1name(), prim2name(), prim3name(), prim4name(), prim5name(), print(), and tree2str().

Referenced by generateDiagramSchema(), and writeSchemaFile().

00359 {
00360     Tree a, b, ff, l, type,name,file;
00361     int     i;
00362     double  r;
00363     prim0   p0;
00364     prim1   p1;
00365     prim2   p2;
00366     prim3   p3;
00367     prim4   p4;
00368     prim5   p5;
00369 
00370 
00371     xtended* xt = (xtended*)getUserData(t);
00372 
00373     if (xt)                         { return makeBlockSchema(xt->arity(), 1, xt->name(), normalcolor, ""); }
00374 
00375     else if (isBoxInt(t, &i))       { stringstream  s; s << i; return makeBlockSchema(0, 1, s.str(), numcolor, "" ); }
00376     else if (isBoxReal(t, &r))      { stringstream  s; s << r; return makeBlockSchema(0, 1, s.str(), numcolor, "" ); }
00377     else if (isBoxWire(t))          { return makeCableSchema(); }
00378     else if (isBoxCut(t))           { return makeCutSchema();  }
00379 
00380     else if (isBoxPrim0(t, &p0))    { return makeBlockSchema(0, 1, prim0name(p0), normalcolor, ""); }
00381     else if (isBoxPrim1(t, &p1))    { return makeBlockSchema(1, 1, prim1name(p1), normalcolor, ""); }
00382     else if (isBoxPrim2(t, &p2))    { return makeBlockSchema(2, 1, prim2name(p2), normalcolor, ""); }
00383     else if (isBoxPrim3(t, &p3))    { return makeBlockSchema(3, 1, prim3name(p3), normalcolor, ""); }
00384     else if (isBoxPrim4(t, &p4))    { return makeBlockSchema(4, 1, prim4name(p4), normalcolor, ""); }
00385     else if (isBoxPrim5(t, &p5))    { return makeBlockSchema(5, 1, prim5name(p5), normalcolor, ""); }
00386 
00387     else if (isBoxFFun(t, ff))                  { return makeBlockSchema(ffarity(ff), 1, ffname(ff), normalcolor, ""); }
00388     else if (isBoxFConst(t, type,name,file))    { return makeBlockSchema(0, 1, tree2str(name), normalcolor, ""); }
00389     else if (isBoxFVar (t, type, name,file))    { return makeBlockSchema(0, 1, tree2str(name), normalcolor, ""); }
00390 
00391     else if (isBoxButton(t))        { return generateUserInterfaceSchema(t); }
00392     else if (isBoxCheckbox(t))      { return generateUserInterfaceSchema(t); }
00393     else if (isBoxVSlider(t))       { return generateUserInterfaceSchema(t); }
00394     else if (isBoxHSlider(t))       { return generateUserInterfaceSchema(t); }
00395     else if (isBoxNumEntry(t))      { return generateUserInterfaceSchema(t); }
00396     else if (isBoxVBargraph(t))     { return generateBargraphSchema(t); }
00397     else if (isBoxHBargraph(t))     { return generateBargraphSchema(t); }
00398 
00399     // don't draw group rectangle when labels are empty (ie "")
00400     else if (isBoxVGroup(t,l,a))    {   stringstream s; s << "vgroup(" << tree2str(l) << ")";
00401                                         schema* r = generateDiagramSchema(a);
00402                                         return makeDecorateSchema(r, 10, s.str()); }
00403     else if (isBoxHGroup(t,l,a))    {   stringstream s; s << "hgroup(" << tree2str(l) << ")";
00404                                         schema* r = generateDiagramSchema(a);
00405                                         return makeDecorateSchema(r, 10, s.str()); }
00406     else if (isBoxTGroup(t,l,a))    {   stringstream s; s << "tgroup(" << tree2str(l) << ")";
00407                                         schema* r = generateDiagramSchema(a);
00408                                         return makeDecorateSchema(r, 10, s.str()); }
00409 
00410     else if (isBoxSeq(t, a, b))     { return makeSeqSchema(generateDiagramSchema(a), generateDiagramSchema(b)); }
00411     else if (isBoxPar(t, a, b))     { return makeParSchema(generateDiagramSchema(a), generateDiagramSchema(b)); }
00412     else if (isBoxSplit(t, a, b))   { return makeSplitSchema(generateDiagramSchema(a), generateDiagramSchema(b)); }
00413     else if (isBoxMerge(t, a, b))   { return makeMergeSchema(generateDiagramSchema(a), generateDiagramSchema(b)); }
00414     else if (isBoxRec(t, a, b))     { return makeRecSchema(generateDiagramSchema(a), generateDiagramSchema(b)); }
00415 
00416     else if (isBoxSlot(t, &i))      { return generateOutputSlotSchema(t); }
00417     else if (isBoxSymbolic(t,a,b))  {
00418         Tree    id;
00419         if (getDefNameProperty(t, id)) {
00420             return generateAbstractionSchema(generateInputSlotSchema(a), b);
00421         } else {
00422             return makeDecorateSchema(generateAbstractionSchema(generateInputSlotSchema(a), b), 10, "Abstraction");
00423         }
00424     }
00425 
00426     else {
00427 
00428         fprintf(stderr, "Internal Error, box expression not recognized : "); print(t, stderr); fprintf(stderr, "\n");
00429         exit(1);
00430 
00431     }
00432 }

Here is the caller graph for this function:

static schema * generateOutputSlotSchema ( Tree  a  )  [static]

Generate a 0->1 block schema for an output slot.

Definition at line 478 of file drawschema.cpp.

References getDefNameProperty(), makeBlockSchema(), slotcolor, and tree2str().

Referenced by generateInsideSchema().

00479 {
00480     Tree id; assert(getDefNameProperty(a, id));
00481     stringstream s; s << tree2str(id);
00482     return makeBlockSchema(0, 1, s.str(), slotcolor, "");
00483 }

Here is the call graph for this function:

Here is the caller graph for this function:

static schema * generateUserInterfaceSchema ( Tree  t  )  [static]

Generate a 0->1 block schema for a user interface element.

Definition at line 440 of file drawschema.cpp.

References makeBlockSchema(), and uicolor.

Referenced by generateInsideSchema().

00441 {
00442     stringstream    s;
00443     s << boxpp(t);
00444 
00445     return makeBlockSchema(0, 1, s.str(), uicolor, "");
00446 }

Here is the call graph for this function:

Here is the caller graph for this function:

static char * legalFileName ( Tree  t,
int  n,
char *  dst 
) [static]

Transform the definition name property of tree <t> into a legal file name.

The resulting file name is stored in <dst> a table of at least <n> chars. Returns the <dst> pointer for convenience.

Definition at line 290 of file drawschema.cpp.

References getDefNameProperty(), and tree2str().

Referenced by generateDiagramSchema(), and writeSchemaFile().

00291 {
00292     Tree    id;
00293     int     i=0;
00294     if (getDefNameProperty(t, id)) {
00295         const char*     src = tree2str(id);
00296         for (i=0; isalnum(src[i]) && i<16; i++) {
00297             dst[i] = src[i];
00298         }
00299     }
00300     dst[i] = 0;
00301     if (strcmp(dst, "process") != 0) { 
00302         // if it is not process add the hex address to make the name unique
00303         snprintf(&dst[i], n-i, "-%p", t);
00304     }
00305     return dst;
00306 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int mkchdir ( const char *  dirname  )  [static]

Create a new directory in the current one to store the diagrams.

The current directory is saved to be later restaured.

Definition at line 253 of file drawschema.cpp.

References gCurrentDir.

Referenced by drawSchema().

00254 {
00255     //cerr << "mkchdir of " << dirname << endl;
00256     if (getcwd(gCurrentDir, 512) != 0) {
00257         int status = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
00258         if (status == 0 || errno == EEXIST) {
00259             if (chdir(dirname) == 0) {
00260                 return 0;
00261             }
00262         }
00263     }
00264     perror("mkchdir");
00265     exit(errno);
00266     //return errno;
00267 }

Here is the caller graph for this function:

static bool pendingDrawing ( Tree t  )  [static]

Retrieve next block diagram that must be drawn.

Definition at line 199 of file drawschema.cpp.

References gPendingExp.

Referenced by drawSchema().

00200 {
00201     if (gPendingExp.empty()) return false;
00202     t = gPendingExp.top();
00203     gPendingExp.pop();
00204     return true;
00205 }

Here is the caller graph for this function:

static void scheduleDrawing ( Tree  t  )  [static]

Schedule a makeBlockSchema diagram to be drawn.

Definition at line 187 of file drawschema.cpp.

References gBackLink, gDrawnExp, gPendingExp, and gSchemaFileName.

Referenced by drawSchema(), and generateDiagramSchema().

00188 {
00189     if (gDrawnExp.find(t) == gDrawnExp.end()) {
00190         gDrawnExp.insert(t);
00191         gBackLink.insert(make_pair(t,gSchemaFileName)); // remember the enclosing filename
00192         gPendingExp.push(t);
00193     }
00194 }

Here is the caller graph for this function:

static void writeSchemaFile ( Tree  bd  )  [static]

Write a top level diagram.

A top level diagram is decorated with its definition name property and is drawn in an individual file

Definition at line 216 of file drawschema.cpp.

References schema::draw(), gBackLink, gDevSuffix, generateInsideSchema(), getDefNameProperty(), gSchemaFileName, schema::height(), kLeftRight, legalFileName(), makeTopSchema(), schema::place(), tree2str(), and schema::width().

Referenced by drawSchema().

00217 {
00218     Tree            id;
00219     schema*         ts;
00220 
00221     char            temp[1024];
00222 
00223     gOccurrences = new Occurrences(bd);
00224 
00225     bool hasname = getDefNameProperty(bd, id); assert(hasname);
00226 
00227     // generate legal file name for the schema
00228     stringstream s1; s1 << legalFileName(bd, 1024, temp) << "." << gDevSuffix;
00229     gSchemaFileName = s1.str();
00230 
00231     // generate the label of the schema
00232     stringstream s2; s2 << tree2str(id);
00233     string link = gBackLink[bd];
00234     ts = makeTopSchema(generateInsideSchema(bd), 20, s2.str(), link);
00235     // draw to the device defined by gDevSuffix
00236     if (strcmp(gDevSuffix, "svg") == 0) {
00237         SVGDev dev(s1.str().c_str(), ts->width(), ts->height());
00238         ts->place(0,0, kLeftRight);
00239         ts->draw(dev);
00240     } else {
00241         PSDev dev(s1.str().c_str(), ts->width(), ts->height());
00242         ts->place(0,0, kLeftRight);
00243         ts->draw(dev);
00244     }
00245 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

map<Tree,string> gBackLink [static]

Definition at line 133 of file drawschema.cpp.

Referenced by scheduleDrawing(), and writeSchemaFile().

char gCurrentDir[512] [static]

Definition at line 131 of file drawschema.cpp.

Referenced by cholddir(), and mkchdir().

const char* gDevSuffix [static]

Definition at line 130 of file drawschema.cpp.

Referenced by drawSchema(), generateDiagramSchema(), and writeSchemaFile().

set<Tree> gDrawnExp [static]

Definition at line 129 of file drawschema.cpp.

Referenced by scheduleDrawing().

Definition at line 119 of file main.cpp.

Referenced by drawSchema(), and process_cmdline().

Definition at line 126 of file drawschema.cpp.

stack<Tree> gPendingExp [static]

Definition at line 128 of file drawschema.cpp.

Referenced by pendingDrawing(), and scheduleDrawing().

string gSchemaFileName [static]

Definition at line 132 of file drawschema.cpp.

Referenced by scheduleDrawing(), and writeSchemaFile().

bool sFoldingFlag [static]

Definition at line 127 of file drawschema.cpp.

Referenced by drawSchema(), and generateDiagramSchema().

Generated on Wed Apr 28 23:45:48 2010 for FAUST compiler by  doxygen 1.6.3