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 279 of file drawschema.cpp.

References gCurrentDir.

Referenced by drawSchema().

00280 {
00281     if (chdir(gCurrentDir) == 0) {
00282         return 0;
00283     } else {
00284         perror("cholddir");
00285         exit(errno);
00286     }
00287 }

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 497 of file drawschema.cpp.

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

Referenced by generateInsideSchema().

00498 {
00499     Tree    a,b;
00500 
00501     while (isBoxSymbolic(t,a,b)) {
00502         x = makeParSchema(x, generateInputSlotSchema(a));
00503         t = b;
00504     }
00505     return makeSeqSchema(x, generateDiagramSchema(t));
00506 }

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 459 of file drawschema.cpp.

References makeBlockSchema(), and uicolor.

Referenced by generateInsideSchema().

00460 {
00461     stringstream    s;
00462     s << boxpp(t);
00463 
00464     return makeBlockSchema(1, 1, s.str(), uicolor, "");
00465 }

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 324 of file drawschema.cpp.

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

Referenced by generateAbstractionSchema(), and generateInsideSchema().

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

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 472 of file drawschema.cpp.

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

Referenced by generateAbstractionSchema(), and generateInsideSchema().

00473 {
00474     Tree id; assert(getDefNameProperty(a, id));
00475     stringstream s; s << tree2str(id);
00476     return makeBlockSchema(1, 0, s.str(), slotcolor, "");
00477 }

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 364 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().

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

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 484 of file drawschema.cpp.

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

Referenced by generateInsideSchema().

00485 {
00486     Tree id; assert(getDefNameProperty(a, id));
00487     stringstream s; s << tree2str(id);
00488     return makeBlockSchema(0, 1, s.str(), slotcolor, "");
00489 }

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 446 of file drawschema.cpp.

References makeBlockSchema(), and uicolor.

Referenced by generateInsideSchema().

00447 {
00448     stringstream    s;
00449     s << boxpp(t);
00450 
00451     return makeBlockSchema(0, 1, s.str(), uicolor, "");
00452 }

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 296 of file drawschema.cpp.

References getDefNameProperty(), and tree2str().

Referenced by generateDiagramSchema(), and writeSchemaFile().

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

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 259 of file drawschema.cpp.

References gCurrentDir.

Referenced by drawSchema().

00260 {
00261     //cerr << "mkchdir of " << dirname << endl;
00262     if (getcwd(gCurrentDir, 512) != 0) {
00263         int status = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
00264         if (status == 0 || errno == EEXIST) {
00265             if (chdir(dirname) == 0) {
00266                 return 0;
00267             }
00268         }
00269     }
00270     perror("mkchdir");
00271     exit(errno);
00272     //return errno;
00273 }

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(), tree(), tree2str(), unique(), 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); 
00226 
00227     //assert(hasname);
00228     if (!hasname) {
00229         // create an arbitrary name 
00230         id = tree(Node(unique("diagram_")));
00231     }
00232 
00233     // generate legal file name for the schema
00234     stringstream s1; s1 << legalFileName(bd, 1024, temp) << "." << gDevSuffix;
00235     gSchemaFileName = s1.str();
00236 
00237     // generate the label of the schema
00238     stringstream s2; s2 << tree2str(id);
00239     string link = gBackLink[bd];
00240     ts = makeTopSchema(generateInsideSchema(bd), 20, s2.str(), link);
00241     // draw to the device defined by gDevSuffix
00242     if (strcmp(gDevSuffix, "svg") == 0) {
00243         SVGDev dev(s1.str().c_str(), ts->width(), ts->height());
00244         ts->place(0,0, kLeftRight);
00245         ts->draw(dev);
00246     } else {
00247         PSDev dev(s1.str().c_str(), ts->width(), ts->height());
00248         ts->place(0,0, kLeftRight);
00249         ts->draw(dev);
00250     }
00251 }

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 124 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 Thu Jul 15 15:47:00 2010 for FAUST compiler by  doxygen 1.6.3