00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00030 #include <stdio.h>
00031 #include <ctype.h>
00032 #include <sys/stat.h>
00033 #include <sys/types.h>
00034 #include <errno.h>
00035 #include <string.h>
00036
00037 #include <ostream>
00038 #include <sstream>
00039 #include <set>
00040 #include <utility>
00041 #include <map>
00042 #include <stack>
00043 #include <string>
00044
00045 #include "boxes.hh"
00046 #include "ppbox.hh"
00047 #include "prim2.hh"
00048
00049 #include <vector>
00050 #include "devLib.h"
00051 #include "ppbox.hh"
00052 #include "xtended.hh"
00053 #include "eval.hh"
00054 #include "occurrences.hh"
00055 #include "boxcomplexity.h"
00056
00057 #include "schema.h"
00058 #include "drawschema.hh"
00059 #include "compatibility.hh"
00060
00061 #if 0
00062 #define linkcolor "#b3d1dc"
00063 #define normalcolor "#ffeaa2"
00064 #define uicolor "#F1CFA1"
00065 #define slotcolor "#ffffd7"
00066 #define numcolor "#ffffff"
00067 #endif
00068
00069 #if 0
00070 #define linkcolor "#F57900"
00071 #define normalcolor "#4B71A1"
00072 #define uicolor "#47945E"
00073 #define slotcolor "#EDD400"
00074 #define numcolor "#4B71A1"
00075 #endif
00076
00077 #if 0
00078 #define linkcolor "#47945E"
00079 #define normalcolor "#4B71A1"
00080 #define uicolor "#f44800"
00081 #define slotcolor "#EDD400"
00082 #define numcolor "#f44800"
00083 #endif
00084
00085 #if 0
00086 #define linkcolor "#47945E"
00087 #define normalcolor "#4B71A1"
00088 #define uicolor "#816647"
00089 #define slotcolor "#EDD400"
00090 #define numcolor "#f44800"
00091 #endif
00092
00093 #if 0
00094 #define linkcolor "#003366"
00095 #define normalcolor "#4B71A1"
00096 #define uicolor "#816647"
00097 #define slotcolor "#EDD400"
00098 #define numcolor "#f44800"
00099 #endif
00100
00101 #if 0
00102 #define linkcolor "#003366"
00103 #define normalcolor "#4B71A1"
00104 #define uicolor "#477881"
00105 #define slotcolor "#816647"
00106 #define numcolor "#f44800"
00107 #endif
00108
00109
00110 #if 1
00111 #define linkcolor "#003366"
00112 #define normalcolor "#4B71A1"
00113 #define uicolor "#477881"
00114 #define slotcolor "#47945E"
00115 #define numcolor "#f44800"
00116 #endif
00117
00118 using namespace std;
00119
00120
00121 extern int gFoldThreshold;
00122
00123
00124
00125 static Occurrences* gOccurrences;
00126 static bool sFoldingFlag;
00127 static stack<Tree> gPendingExp;
00128 static set<Tree> gDrawnExp;
00129 static const char* gDevSuffix;
00130 static char gCurrentDir[512];
00131 static string gSchemaFileName;
00132 static map<Tree,string> gBackLink;
00133
00134
00135 static void writeSchemaFile(Tree bd);
00136 static schema* generateDiagramSchema (Tree bd);
00137 static schema* generateInsideSchema(Tree t);
00138 static void scheduleDrawing(Tree t);
00139 static bool pendingDrawing(Tree& t);
00140 static schema* generateAbstractionSchema(schema* x, Tree t);
00141 static schema* generateOutputSlotSchema(Tree a);
00142 static schema* generateInputSlotSchema(Tree a);
00143 static schema* generateBargraphSchema(Tree t);
00144 static schema* generateUserInterfaceSchema(Tree t);
00145 static char* legalFileName(Tree t, int n, char* dst);
00146 static int cholddir ();
00147 static int mkchdir(const char* dirname);
00148
00149
00150
00151
00157 void drawSchema(Tree bd, const char* projname, const char* dev)
00158 {
00159 gDevSuffix = dev;
00160 sFoldingFlag = boxComplexity(bd) > gFoldThreshold;
00161
00162 mkchdir(projname);
00163
00164 scheduleDrawing(bd);
00165
00166 Tree t; while (pendingDrawing(t)) {
00167 writeSchemaFile(t);
00168 }
00169
00170 cholddir();
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00186 static void scheduleDrawing(Tree t)
00187 {
00188 if (gDrawnExp.find(t) == gDrawnExp.end()) {
00189 gDrawnExp.insert(t);
00190 gBackLink.insert(make_pair(t,gSchemaFileName));
00191 gPendingExp.push(t);
00192 }
00193 }
00194
00198 static bool pendingDrawing(Tree& t)
00199 {
00200 if (gPendingExp.empty()) return false;
00201 t = gPendingExp.top();
00202 gPendingExp.pop();
00203 return true;
00204 }
00205
00206
00207
00208
00209
00215 static void writeSchemaFile(Tree bd)
00216 {
00217 Tree id;
00218 schema* ts;
00219
00220 char temp[1024];
00221
00222 gOccurrences = new Occurrences(bd);
00223
00224 bool hasname = getDefNameProperty(bd, id); assert(hasname);
00225
00226
00227 stringstream s1; s1 << legalFileName(bd, 1024, temp) << "." << gDevSuffix;
00228 gSchemaFileName = s1.str();
00229
00230
00231 stringstream s2; s2 << tree2str(id);
00232 string link = gBackLink[bd];
00233 ts = makeTopSchema(generateInsideSchema(bd), 20, s2.str(), link);
00234
00235 if (strcmp(gDevSuffix, "svg") == 0) {
00236 SVGDev dev(s1.str().c_str(), ts->width(), ts->height());
00237 ts->place(0,0, kLeftRight);
00238 ts->draw(dev);
00239 } else {
00240 PSDev dev(s1.str().c_str(), ts->width(), ts->height());
00241 ts->place(0,0, kLeftRight);
00242 ts->draw(dev);
00243 }
00244 }
00245
00246
00247
00252 static int mkchdir(const char* dirname)
00253 {
00254
00255 if (getcwd(gCurrentDir, 512) != 0) {
00256 int status = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
00257 if (status == 0 || errno == EEXIST) {
00258 if (chdir(dirname) == 0) {
00259 return 0;
00260 }
00261 }
00262 }
00263 perror("mkchdir");
00264 exit(errno);
00265
00266 }
00267
00268
00272 static int cholddir ()
00273 {
00274 if (chdir(gCurrentDir) == 0) {
00275 return 0;
00276 } else {
00277 perror("cholddir");
00278 exit(errno);
00279 }
00280 }
00281
00282
00289 static char* legalFileName(Tree t, int n, char* dst)
00290 {
00291 Tree id;
00292 int i=0;
00293 if (getDefNameProperty(t, id)) {
00294 const char* src = tree2str(id);
00295 for (i=0; isalnum(src[i]) && i<16; i++) {
00296 dst[i] = src[i];
00297 }
00298 }
00299 dst[i] = 0;
00300 if (strcmp(dst, "process") != 0) {
00301
00302 snprintf(&dst[i], n-i, "-%p", t);
00303 }
00304 return dst;
00305 }
00306
00307
00308
00309
00310
00317 static schema* generateDiagramSchema(Tree t)
00318 {
00319 Tree id;
00320 int ins, outs;
00321
00322
00323
00324 if (getDefNameProperty(t, id)) {
00325 stringstream s; s << tree2str(id);
00326
00327 }
00328
00329 if ( sFoldingFlag &&
00330 (boxComplexity(t) > 2) && getDefNameProperty(t, id)) {
00331 char temp[1024];
00332 getBoxType(t, &ins, &outs);
00333 stringstream s, l;
00334 s << tree2str(id);
00335 l << legalFileName(t,1024,temp) << "." << gDevSuffix;
00336 scheduleDrawing(t);
00337 return makeBlockSchema(ins, outs, s.str(), linkcolor, l.str());
00338
00339 } else if (getDefNameProperty(t, id) && ! isBoxSlot(t)) {
00340
00341
00342 stringstream s; s << tree2str(id);
00343 return makeDecorateSchema(generateInsideSchema(t), 10, s.str());
00344
00345 } else {
00346
00347 return generateInsideSchema(t);
00348 }
00349 }
00350
00351
00352
00357 static schema* generateInsideSchema(Tree t)
00358 {
00359 Tree a, b, ff, l, type,name,file;
00360 int i;
00361 float r;
00362 prim0 p0;
00363 prim1 p1;
00364 prim2 p2;
00365 prim3 p3;
00366 prim4 p4;
00367 prim5 p5;
00368
00369
00370 xtended* xt = (xtended*)getUserData(t);
00371
00372 if (xt) { return makeBlockSchema(xt->arity(), 1, xt->name(), normalcolor, ""); }
00373
00374 else if (isBoxInt(t, &i)) { stringstream s; s << i; return makeBlockSchema(0, 1, s.str(), numcolor, "" ); }
00375 else if (isBoxReal(t, &r)) { stringstream s; s << r; return makeBlockSchema(0, 1, s.str(), numcolor, "" ); }
00376 else if (isBoxWire(t)) { return makeCableSchema(); }
00377 else if (isBoxCut(t)) { return makeCutSchema(); }
00378
00379 else if (isBoxPrim0(t, &p0)) { return makeBlockSchema(0, 1, prim0name(p0), normalcolor, ""); }
00380 else if (isBoxPrim1(t, &p1)) { return makeBlockSchema(1, 1, prim1name(p1), normalcolor, ""); }
00381 else if (isBoxPrim2(t, &p2)) { return makeBlockSchema(2, 1, prim2name(p2), normalcolor, ""); }
00382 else if (isBoxPrim3(t, &p3)) { return makeBlockSchema(3, 1, prim3name(p3), normalcolor, ""); }
00383 else if (isBoxPrim4(t, &p4)) { return makeBlockSchema(4, 1, prim4name(p4), normalcolor, ""); }
00384 else if (isBoxPrim5(t, &p5)) { return makeBlockSchema(5, 1, prim5name(p5), normalcolor, ""); }
00385
00386 else if (isBoxFFun(t, ff)) { return makeBlockSchema(ffarity(ff), 1, ffname(ff), normalcolor, ""); }
00387 else if (isBoxFConst(t, type,name,file)) { return makeBlockSchema(0, 1, tree2str(name), normalcolor, ""); }
00388 else if (isBoxFVar (t, type, name,file)) { return makeBlockSchema(0, 1, tree2str(name), normalcolor, ""); }
00389
00390 else if (isBoxButton(t)) { return generateUserInterfaceSchema(t); }
00391 else if (isBoxCheckbox(t)) { return generateUserInterfaceSchema(t); }
00392 else if (isBoxVSlider(t)) { return generateUserInterfaceSchema(t); }
00393 else if (isBoxHSlider(t)) { return generateUserInterfaceSchema(t); }
00394 else if (isBoxNumEntry(t)) { return generateUserInterfaceSchema(t); }
00395 else if (isBoxVBargraph(t)) { return generateBargraphSchema(t); }
00396 else if (isBoxHBargraph(t)) { return generateBargraphSchema(t); }
00397
00398
00399 else if (isBoxVGroup(t,l,a)) { stringstream s; s << "vgroup(" << tree2str(l) << ")";
00400 schema* r = generateDiagramSchema(a);
00401 return makeDecorateSchema(r, 10, s.str()); }
00402 else if (isBoxHGroup(t,l,a)) { stringstream s; s << "hgroup(" << tree2str(l) << ")";
00403 schema* r = generateDiagramSchema(a);
00404 return makeDecorateSchema(r, 10, s.str()); }
00405 else if (isBoxTGroup(t,l,a)) { stringstream s; s << "tgroup(" << tree2str(l) << ")";
00406 schema* r = generateDiagramSchema(a);
00407 return makeDecorateSchema(r, 10, s.str()); }
00408
00409 else if (isBoxSeq(t, a, b)) { return makeSeqSchema(generateDiagramSchema(a), generateDiagramSchema(b)); }
00410 else if (isBoxPar(t, a, b)) { return makeParSchema(generateDiagramSchema(a), generateDiagramSchema(b)); }
00411 else if (isBoxSplit(t, a, b)) { return makeSplitSchema(generateDiagramSchema(a), generateDiagramSchema(b)); }
00412 else if (isBoxMerge(t, a, b)) { return makeMergeSchema(generateDiagramSchema(a), generateDiagramSchema(b)); }
00413 else if (isBoxRec(t, a, b)) { return makeRecSchema(generateDiagramSchema(a), generateDiagramSchema(b)); }
00414
00415 else if (isBoxSlot(t, &i)) { return generateOutputSlotSchema(t); }
00416 else if (isBoxSymbolic(t,a,b)) {
00417 Tree id;
00418 if (getDefNameProperty(t, id)) {
00419 return generateAbstractionSchema(generateInputSlotSchema(a), b);
00420 } else {
00421 return makeDecorateSchema(generateAbstractionSchema(generateInputSlotSchema(a), b), 10, "Abstraction");
00422 }
00423 }
00424
00425 else {
00426
00427 fprintf(stderr, "Internal Error, box expression not recognized : "); print(t, stderr); fprintf(stderr, "\n");
00428 exit(1);
00429
00430 }
00431 }
00432
00433
00434
00435
00439 static schema* generateUserInterfaceSchema(Tree t)
00440 {
00441 stringstream s;
00442 s << boxpp(t);
00443
00444 return makeBlockSchema(0, 1, s.str(), uicolor, "");
00445 }
00446
00447
00448
00452 static schema* generateBargraphSchema(Tree t)
00453 {
00454 stringstream s;
00455 s << boxpp(t);
00456
00457 return makeBlockSchema(1, 1, s.str(), uicolor, "");
00458 }
00459
00460
00461
00465 static schema* generateInputSlotSchema(Tree a)
00466 {
00467 Tree id; assert(getDefNameProperty(a, id));
00468 stringstream s; s << tree2str(id);
00469 return makeBlockSchema(1, 0, s.str(), slotcolor, "");
00470 }
00471
00472
00473
00477 static schema* generateOutputSlotSchema(Tree a)
00478 {
00479 Tree id; assert(getDefNameProperty(a, id));
00480 stringstream s; s << tree2str(id);
00481 return makeBlockSchema(0, 1, s.str(), slotcolor, "");
00482 }
00483
00484
00485
00490 static schema* generateAbstractionSchema(schema* x, Tree t)
00491 {
00492 Tree a,b;
00493
00494 while (isBoxSymbolic(t,a,b)) {
00495 x = makeParSchema(x, generateInputSlotSchema(a));
00496 t = b;
00497 }
00498 return makeSeqSchema(x, generateDiagramSchema(t));
00499 }
00500