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 "occurrences.hh"
00054 #include "boxcomplexity.h"
00055
00056 #include "schema.h"
00057 #include "drawschema.hh"
00058 #include "compatibility.hh"
00059 #include "names.hh"
00060
00061
00062 #if 0
00063 #define linkcolor "#b3d1dc"
00064 #define normalcolor "#ffeaa2"
00065 #define uicolor "#F1CFA1"
00066 #define slotcolor "#ffffd7"
00067 #define numcolor "#ffffff"
00068 #endif
00069
00070 #if 0
00071 #define linkcolor "#F57900"
00072 #define normalcolor "#4B71A1"
00073 #define uicolor "#47945E"
00074 #define slotcolor "#EDD400"
00075 #define numcolor "#4B71A1"
00076 #endif
00077
00078 #if 0
00079 #define linkcolor "#47945E"
00080 #define normalcolor "#4B71A1"
00081 #define uicolor "#f44800"
00082 #define slotcolor "#EDD400"
00083 #define numcolor "#f44800"
00084 #endif
00085
00086 #if 0
00087 #define linkcolor "#47945E"
00088 #define normalcolor "#4B71A1"
00089 #define uicolor "#816647"
00090 #define slotcolor "#EDD400"
00091 #define numcolor "#f44800"
00092 #endif
00093
00094 #if 0
00095 #define linkcolor "#003366"
00096 #define normalcolor "#4B71A1"
00097 #define uicolor "#816647"
00098 #define slotcolor "#EDD400"
00099 #define numcolor "#f44800"
00100 #endif
00101
00102 #if 0
00103 #define linkcolor "#003366"
00104 #define normalcolor "#4B71A1"
00105 #define uicolor "#477881"
00106 #define slotcolor "#816647"
00107 #define numcolor "#f44800"
00108 #endif
00109
00110
00111 #if 1
00112 #define linkcolor "#003366"
00113 #define normalcolor "#4B71A1"
00114 #define uicolor "#477881"
00115 #define slotcolor "#47945E"
00116 #define numcolor "#f44800"
00117 #endif
00118
00119 using namespace std;
00120
00121
00122 extern int gFoldThreshold;
00123
00124
00125
00126 static Occurrences* gOccurrences;
00127 static bool sFoldingFlag;
00128 static stack<Tree> gPendingExp;
00129 static set<Tree> gDrawnExp;
00130 static const char* gDevSuffix;
00131 static char gCurrentDir[512];
00132 static string gSchemaFileName;
00133 static map<Tree,string> gBackLink;
00134
00135
00136 static void writeSchemaFile(Tree bd);
00137 static schema* generateDiagramSchema (Tree bd);
00138 static schema* generateInsideSchema(Tree t);
00139 static void scheduleDrawing(Tree t);
00140 static bool pendingDrawing(Tree& t);
00141 static schema* generateAbstractionSchema(schema* x, Tree t);
00142 static schema* generateOutputSlotSchema(Tree a);
00143 static schema* generateInputSlotSchema(Tree a);
00144 static schema* generateBargraphSchema(Tree t);
00145 static schema* generateUserInterfaceSchema(Tree t);
00146 static char* legalFileName(Tree t, int n, char* dst);
00147 static int cholddir ();
00148 static int mkchdir(const char* dirname);
00149
00150
00151
00152
00158 void drawSchema(Tree bd, const char* projname, const char* dev)
00159 {
00160 gDevSuffix = dev;
00161 sFoldingFlag = boxComplexity(bd) > gFoldThreshold;
00162
00163 mkchdir(projname);
00164
00165 scheduleDrawing(bd);
00166
00167 Tree t; while (pendingDrawing(t)) {
00168 writeSchemaFile(t);
00169 }
00170
00171 cholddir();
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00187 static void scheduleDrawing(Tree t)
00188 {
00189 if (gDrawnExp.find(t) == gDrawnExp.end()) {
00190 gDrawnExp.insert(t);
00191 gBackLink.insert(make_pair(t,gSchemaFileName));
00192 gPendingExp.push(t);
00193 }
00194 }
00195
00199 static bool pendingDrawing(Tree& t)
00200 {
00201 if (gPendingExp.empty()) return false;
00202 t = gPendingExp.top();
00203 gPendingExp.pop();
00204 return true;
00205 }
00206
00207
00208
00209
00210
00216 static void writeSchemaFile(Tree bd)
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
00228 stringstream s1; s1 << legalFileName(bd, 1024, temp) << "." << gDevSuffix;
00229 gSchemaFileName = s1.str();
00230
00231
00232 stringstream s2; s2 << tree2str(id);
00233 string link = gBackLink[bd];
00234 ts = makeTopSchema(generateInsideSchema(bd), 20, s2.str(), link);
00235
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 }
00246
00247
00248
00253 static int mkchdir(const char* dirname)
00254 {
00255
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
00267 }
00268
00269
00273 static int cholddir ()
00274 {
00275 if (chdir(gCurrentDir) == 0) {
00276 return 0;
00277 } else {
00278 perror("cholddir");
00279 exit(errno);
00280 }
00281 }
00282
00283
00290 static char* legalFileName(Tree t, int n, char* dst)
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
00303 snprintf(&dst[i], n-i, "-%p", t);
00304 }
00305 return dst;
00306 }
00307
00308
00309
00310
00311
00318 static schema* generateDiagramSchema(Tree t)
00319 {
00320 Tree id;
00321 int ins, outs;
00322
00323
00324
00325 if (getDefNameProperty(t, id)) {
00326 stringstream s; s << tree2str(id);
00327
00328 }
00329
00330 if ( sFoldingFlag &&
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
00342
00343 stringstream s; s << tree2str(id);
00344 return makeDecorateSchema(generateInsideSchema(t), 10, s.str());
00345
00346 } else {
00347
00348 return generateInsideSchema(t);
00349 }
00350 }
00351
00352
00353
00358 static schema* generateInsideSchema(Tree t)
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
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 }
00433
00434
00435
00436
00440 static schema* generateUserInterfaceSchema(Tree t)
00441 {
00442 stringstream s;
00443 s << boxpp(t);
00444
00445 return makeBlockSchema(0, 1, s.str(), uicolor, "");
00446 }
00447
00448
00449
00453 static schema* generateBargraphSchema(Tree t)
00454 {
00455 stringstream s;
00456 s << boxpp(t);
00457
00458 return makeBlockSchema(1, 1, s.str(), uicolor, "");
00459 }
00460
00461
00462
00466 static schema* generateInputSlotSchema(Tree a)
00467 {
00468 Tree id; assert(getDefNameProperty(a, id));
00469 stringstream s; s << tree2str(id);
00470 return makeBlockSchema(1, 0, s.str(), slotcolor, "");
00471 }
00472
00473
00474
00478 static schema* generateOutputSlotSchema(Tree a)
00479 {
00480 Tree id; assert(getDefNameProperty(a, id));
00481 stringstream s; s << tree2str(id);
00482 return makeBlockSchema(0, 1, s.str(), slotcolor, "");
00483 }
00484
00485
00486
00491 static schema* generateAbstractionSchema(schema* x, Tree t)
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 }
00501