00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "Debug.H"
00022 #include "Expr.H"
00023
00024 #include <ThreadIO.H>
00025
00026 using std::ostream;
00027 using std::cout;
00028 using std::endl;
00029 using std::flush;
00030 using OS::cio;
00031
00032 bool CacheIt(Val v) {
00033 if (!v->cacheit) {
00034 cio().start_err() << "Cannot be cached." << endl;
00035 cio().end_err();
00036 return false;
00037 }
00038 switch (v->vKind) {
00039 case BindingVK:
00040 {
00041 Binding b = (BindingVC*)v;
00042 Context elems = b->elems;
00043 while (!elems.Null()) {
00044 if (!CacheIt(elems.Pop()->val))
00045 return false;
00046 }
00047 break;
00048 }
00049 case ListVK:
00050 {
00051 Vals elems = ((ListVC*)v)->elems;
00052 while (!elems.Null()) {
00053 if (!CacheIt(elems.Pop()))
00054 return false;
00055 }
00056 break;
00057 }
00058 default:
00059 break;
00060 }
00061 return true;
00062 }
00063
00064 void PrintVars(ostream& os, const Vars& fv)
00065 {
00066 Vars vars = fv;
00067 os << "< ";
00068 if (!vars.Null())
00069 os << vars.Pop();
00070 while (!vars.Null())
00071 os << ", " << vars.Pop();
00072 os << " >";
00073 os.flush();
00074 }
00075
00076 void PrintTags(ostream& os, const FP::List& tags)
00077 {
00078 os << "{" << endl;
00079 for (int i = 0; i < tags.len; i++) {
00080 os << " " << i << ". " << tags.fp[i] << endl;
00081 }
00082 os << "}" << endl;
00083 return;
00084 }
00085
00086 void PrintNames(ostream& os, const FV2::List& names)
00087 {
00088 os << "{" << endl;
00089 for (int i = 0; i < names.len; i++) {
00090 os << " " << i << ". " << *names.name[i] << endl;
00091 }
00092 os << "}" << endl;
00093 return;
00094 }
00095
00096 Val ContextNames(const Context& c) {
00097 Context work = c;
00098
00099 Vals names;
00100 while (!work.Null()) {
00101 names.Append1D(NEW_CONSTR(TextVC, (work.Pop()->name)));
00102 }
00103 return NEW_CONSTR(ListVC, (names));
00104 }
00105
00106 void PrintDpnd(ostream& os, Val v)
00107 {
00108 int index = 0;
00109 os << "{ ";
00110 if (v->path) {
00111 os << index++ << ". <";
00112 v->path->Print(os);
00113 os << " : ";
00114 v->PrintD(os);
00115 os << ">";
00116 os << ";";
00117 }
00118 if (v->SizeOfDPS() != 0) {
00119 DepPathTbl::TIter iter(v->dps);
00120 DepPathTbl::KVPairPtr ptr;
00121 if (iter.Next(ptr)) {
00122 os << endl << " " << index++ << ". <";
00123 ptr->key.Print(os);
00124 os << " : ";
00125 ptr->val->PrintD(os);
00126 os << ">";
00127 while (iter.Next(ptr)) {
00128 os << "," << endl << " " << index++ << ". <";
00129 ptr->key.Print(os);
00130 os << " : ";
00131 ptr->val->PrintD(os);
00132 os << ">";
00133 }
00134 }
00135 }
00136 os << " }" << endl;
00137 }
00138
00139 void CollectAllDpnd(Val v, bool isModel, DPaths& ps) {
00140
00141
00142
00143 if (v->SizeOfDPS() == 0)
00144 v->dps = NULL;
00145 else {
00146 DepPathTbl::TIter iter(v->dps);
00147 DepPathTbl::KVPairPtr ptr;
00148 if (isModel) {
00149 while (iter.Next(ptr)) {
00150 if (ptr->key.content->path->getlo() == nameDot)
00151 (void)ps.Put(ptr);
00152 }
00153 }
00154 else {
00155 while (iter.Next(ptr))
00156 (void)ps.Put(ptr);
00157 }
00158 }
00159 DepPath *dp = v->path;
00160 if (dp != NULL) {
00161
00162 if (!isModel || (dp->content->path->getlo() == nameDot)) {
00163 DepPathTbl::KVPairPtr pr;
00164 (void)ps.Put(*dp, v, pr);
00165
00166 }
00167 else
00168 v->path = NULL;
00169 }
00170 else {
00171
00172 switch (v->vKind) {
00173 case BindingVK:
00174 {
00175 BindingVC *bv = (BindingVC*)v;
00176 if (bv->lenDps != NULL && bv->lenDps->Size() != 0) {
00177 DepPathTbl::TIter iter(bv->lenDps);
00178 DepPathTbl::KVPairPtr ptr;
00179 if (isModel) {
00180 while (iter.Next(ptr)) {
00181 if (ptr->key.content->path->getlo() == nameDot) {
00182 DepPath lenPath(ptr->key.content->path, BLenPK, ptr->key.content->pathFP);
00183 Val vNames = ((BindingVC*)ptr->val)->Names();
00184 (void)ps.Put(lenPath, vNames, ptr);
00185
00186 }
00187 }
00188 }
00189 else {
00190 while (iter.Next(ptr)) {
00191 DepPath lenPath(ptr->key.content->path, BLenPK, ptr->key.content->pathFP);
00192 Val vNames = ((BindingVC*)ptr->val)->Names();
00193 (void)ps.Put(lenPath, vNames, ptr);
00194
00195 }
00196 }
00197 }
00198 Context work = bv->elems;
00199 while (!work.Null())
00200 CollectAllDpnd(work.Pop()->val, isModel, ps);
00201 break;
00202 }
00203 case ListVK:
00204 {
00205 ListVC *lstv = (ListVC*)v;
00206 if (lstv->lenDps != NULL && lstv->lenDps->Size() != 0) {
00207 DepPathTbl::TIter iter(lstv->lenDps);
00208 DepPathTbl::KVPairPtr ptr;
00209 if (isModel) {
00210 while (iter.Next(ptr)) {
00211 if (ptr->key.content->path->getlo() == nameDot) {
00212 DepPath lenPath(ptr->key.content->path, LLenPK,
00213 ptr->key.content->pathFP);
00214 Val vLen = NEW_CONSTR(IntegerVC,
00215 (((ListVC*)ptr->val)->elems.Length()));
00216 (void)ps.Put(lenPath, vLen, ptr);
00217
00218 }
00219 }
00220 }
00221 else {
00222 while (iter.Next(ptr)) {
00223 DepPath lenPath(ptr->key.content->path, LLenPK,
00224 ptr->key.content->pathFP);
00225 Val vLen = NEW_CONSTR(IntegerVC,
00226 (((ListVC*)ptr->val)->elems.Length()));
00227 (void)ps.Put(lenPath, vLen, ptr);
00228
00229 }
00230 }
00231 }
00232 Vals vv = lstv->elems;
00233 while (!vv.Null())
00234 CollectAllDpnd(vv.Pop(), isModel, ps);
00235 break;
00236 }
00237 case ClosureVK:
00238 {
00239 ClosureVC *cl = (ClosureVC*)v;
00240 Context work = cl->con;
00241 while (!work.Null()) {
00242 Assoc a = work.Pop();
00243 if (cl->func->name != a->name)
00244 CollectAllDpnd(a->val, isModel, ps);
00245 }
00246 break;
00247 }
00248 default:
00249 break;
00250 }
00251 }
00252 return;
00253 }
00254
00255 void PrintAllDpnd(ostream& os, Val v)
00256 {
00257
00258 DPaths *ps = NEW_CONSTR(DPaths, (v->SizeOfDPS()));
00259 CollectAllDpnd(v, false, *ps);
00260 ps->Print(os);
00261 }
00262
00263 void PrintDpndSize(ostream& os, Val v)
00264 {
00265 switch (v->vKind) {
00266 case BindingVK:
00267 {
00268 Binding b = (BindingVC*)v;
00269 Context elems = b->elems;
00270 os << "[";
00271 os << v->SizeOfDPS();
00272 os << ", ";
00273 if (v->path != NULL) os << "*";
00274 os << "[";
00275 if (!elems.Null())
00276 PrintDpndSize(os, elems.Pop()->val);
00277 while (!elems.Null()) {
00278 os << ", ";
00279 PrintDpndSize(os, elems.Pop()->val);
00280 }
00281 os << "]]";
00282 break;
00283 }
00284 case ListVK:
00285 {
00286 Vals elems = ((ListVC*)v)->elems;
00287 os << "[";
00288 os << v->SizeOfDPS();
00289 os << ", ";
00290 if (v->path != NULL) os << "*";
00291 os << "[";
00292 if (!elems.Null())
00293 PrintDpndSize(os, elems.Pop());
00294 while (!elems.Null()) {
00295 os << ", ";
00296 PrintDpndSize(os, elems.Pop());
00297 }
00298 os << "]]";
00299 break;
00300 }
00301 default:
00302 os << v->SizeOfDPS();
00303 break;
00304 }
00305 return;
00306 }
00307
00308 #ifndef NO_DUMP_VAL
00309
00310
00311
00312 void DumpVal(Val v);
00313
00314
00315
00316
00317
00318
00319
00320
00321 static Text DumpValIndent(unsigned int nesting)
00322 {
00323 Text result = "";
00324 for(unsigned int i = 0; i < nesting; i++)
00325 result += " ";
00326 return result;
00327 }
00328
00329 static const char *DumpValKind(ValueKind k)
00330 {
00331 switch(k)
00332 {
00333 case BooleanVK:
00334 return "bool";
00335 case IntegerVK:
00336 return "int";
00337 case ListVK:
00338 return "list";
00339 case BindingVK:
00340 return "binding";
00341 case PrimitiveVK:
00342 return "prim";
00343 case TextVK:
00344 return "text";
00345 case ClosureVK:
00346 return "closure";
00347 case ModelVK:
00348 return "model";
00349 case ErrorVK:
00350 return "error";
00351 case FpVK:
00352 return "fp";
00353 case UnbndVK:
00354 return "unbound";
00355 }
00356 }
00357
00358 static void DumpValInner(Val v, unsigned int nesting = 0)
00359 {
00360 Text indent = DumpValIndent(nesting);
00361 cout << indent << "Val @ " << ((void *) v) << endl
00362 << indent << " type : " << DumpValKind(v->vKind) << endl;
00363 if(v->path)
00364 {
00365 cout << indent << " path @ " << ((void *) v->path) << " : ";
00366 v->path->Print(cout);
00367 cout << endl;
00368 }
00369
00370 if (v->SizeOfDPS() != 0)
00371 {
00372 cout << indent << " dps @ " << ((void *) v->dps) << " :" << endl;
00373 DepPathTbl::TIter iter(v->dps);
00374 DepPathTbl::KVPairPtr ptr;
00375 while(iter.Next(ptr))
00376 {
00377 int index = 0;
00378 cout << indent << " " << index++ << ". <" << flush;
00379 ptr->key.Print(cout);
00380 cout << flush;
00381 cout << " : " << flush;
00382 ptr->val->PrintD(cout, false, (nesting*4)+3);
00383 cout << flush;
00384 cout << ">" << endl;
00385 }
00386 }
00387
00388 switch (v->vKind)
00389 {
00390 case BindingVK:
00391 {
00392 BindingVC *bv = (BindingVC*)v;
00393 if(bv->lenDps && bv->lenDps->Size())
00394 {
00395 cout << indent << " lenDps @ " << ((void *) bv->lenDps) << " :"
00396 << endl;
00397 DepPathTbl::TIter iter(bv->lenDps);
00398 DepPathTbl::KVPairPtr ptr;
00399 while(iter.Next(ptr))
00400 {
00401 int index = 0;
00402 cout << indent << " " << index++ << ". <";
00403 ptr->key.Print(cout);
00404 cout << " : ";
00405 ptr->val->PrintD(cout, false, (nesting*4)+3);
00406 cout << ">";
00407 }
00408 }
00409
00410 Context work = bv->elems;
00411 cout << indent << " value : " << endl
00412 << indent << " [" << endl;
00413 while (!work.Null())
00414 {
00415 Assoc a = work.Pop();
00416 cout << indent << " " << a->name << " = " << endl;
00417 DumpValInner(a->val, nesting + 1);
00418 }
00419 cout << indent << " ]" << endl;
00420 }
00421 break;
00422 case ListVK:
00423 {
00424 ListVC *lv = (ListVC*)v;
00425
00426 if(lv->lenDps && lv->lenDps->Size())
00427 {
00428 cout << indent << " lenDps @ " << ((void *) lv->lenDps) << " :"
00429 << endl;
00430 DepPathTbl::TIter iter(lv->lenDps);
00431 DepPathTbl::KVPairPtr ptr;
00432 while(iter.Next(ptr))
00433 {
00434 int index = 0;
00435 cout << indent << " " << index++ << ". <";
00436 ptr->key.Print(cout);
00437 cout << " : ";
00438 ptr->val->PrintD(cout, false, (nesting*4)+3);
00439 cout << ">";
00440 }
00441 }
00442
00443 Vals elems = lv->elems;
00444 cout << indent << " value : " << endl
00445 << indent << " <" << endl;
00446 while (!elems.Null())
00447 {
00448 DumpValInner(elems.Pop(), nesting + 1);
00449 }
00450 }
00451 break;
00452 case ClosureVK:
00453 {
00454 ClosureVC *cl = (ClosureVC*)v;
00455
00456 cout << indent << " definition : "
00457 << cl->func->loc->file
00458 << ", line " << cl->func->loc->line
00459 << ", char " << cl->func->loc->character << endl;
00460
00461 Context work = cl->con;
00462 cout << indent << " context : " << endl
00463 << indent << " [" << endl;
00464 while (!work.Null())
00465 {
00466 Assoc a = work.Pop();
00467 if (a->name != cl->func->name)
00468 {
00469 cout << indent << " " << a->name << " = " << endl;
00470 DumpValInner(a->val, nesting + 1);
00471 }
00472 }
00473 cout << indent << " ]" << endl;
00474 }
00475 break;
00476 default:
00477 {
00478 cout << indent << " value : " << endl
00479 << indent << " ";
00480 v->PrintD(cout, false, (nesting*4)+2);
00481 cout << endl;
00482 }
00483 break;
00484 }
00485 }
00486
00487 void DumpVal(Val v)
00488 {
00489 DumpValInner(v);
00490 cout << endl;
00491 }
00492 #endif
00493
00494 class DepCompareInfo
00495 {
00496 private:
00497 ostream &out;
00498 const Text &source;
00499 const FP::Tag &pk;
00500 CacheEntry::Index cIndex;
00501 bool printed;
00502 public:
00503 DepCompareInfo(ostream &o, const Text &s,
00504 const FP::Tag &pk, CacheEntry::Index ci)
00505 : out(o), source(s), pk(pk), cIndex(ci), printed(false)
00506 {
00507 }
00508
00509 void print()
00510 {
00511 if(!printed)
00512 {
00513 out << endl << "----- Dependency Differences In -----: " << endl
00514 << source << endl
00515 << "Cache Hit PK: " << pk << endl
00516 << "Cache Index: " << cIndex << endl << endl;
00517 printed = true;
00518 }
00519 }
00520 };
00521
00522 static void printDPSDiffInner(ostream &out,
00523 DepCompareInfo &where, Text subpath,
00524 DPaths* old_dps, DPaths* new_dps)
00525 {
00526 DPaths* deleted = 0;
00527 if(!new_dps)
00528 deleted = old_dps;
00529 else if(old_dps)
00530 deleted = old_dps->Difference(new_dps);
00531 if(deleted && deleted->Empty())
00532 deleted = 0;
00533
00534 DPaths* added = 0;
00535 if(!old_dps)
00536 added = new_dps;
00537 else if(new_dps)
00538 added = new_dps->Difference(old_dps);
00539 if(added && added->Empty())
00540 added = 0;
00541
00542 if(deleted || added) {
00543 where.print();
00544 out << subpath << " :" << endl;
00545 if(deleted)
00546 deleted->Print(out, "-");
00547 if(added)
00548 added->Print(out, "+");
00549 out << endl;
00550 }
00551 }
00552
00553 static void printDepsDiffInner(ostream &out,
00554 DepCompareInfo &where, Text subpath,
00555 Val old_v, Val new_v)
00556 {
00557
00558 if(old_v->path || new_v->path)
00559 {
00560
00561 if(!old_v->path)
00562 {
00563 where.print();
00564 out << subpath << "->path :" << endl
00565 << " ! No old path" << endl
00566 << " + ";
00567 new_v->path->Print(out);
00568 out << endl << endl;
00569 }
00570
00571 else if(!new_v->path)
00572 {
00573 where.print();
00574 out << subpath << "->path :" << endl
00575 << " - ";
00576 old_v->path->Print(out);
00577 out << endl
00578 << " ! No new path" << endl << endl;
00579 }
00580
00581 else if(!(*(old_v->path) == *(new_v->path)))
00582 {
00583 where.print();
00584 out << subpath << "->path :" << endl
00585 << " - ";
00586 old_v->path->Print(out);
00587 out << endl
00588 << " + ";
00589 new_v->path->Print(out);
00590 out << endl << endl;
00591 }
00592 }
00593
00594
00595 printDPSDiffInner(out, where, subpath+"->dps",
00596 old_v->dps, new_v->dps);
00597
00598
00599 if(old_v->vKind != new_v->vKind)
00600 {
00601 where.print();
00602 out << subpath << "->vKind :" << endl
00603 << " - " << DumpValKind(old_v->vKind) << endl
00604 << " + " << DumpValKind(new_v->vKind) << endl << endl;
00605
00606
00607 return;
00608 }
00609
00610
00611 switch (old_v->vKind)
00612 {
00613 case BindingVK:
00614 {
00615 BindingVC *old_bv = (BindingVC*)old_v;
00616 BindingVC *new_bv = (BindingVC*)new_v;
00617
00618
00619 printDPSDiffInner(out, where, subpath+"->lenDps",
00620 old_bv->lenDps, new_bv->lenDps);
00621
00622
00623
00624 TextSeq name_del, name_add;
00625
00626
00627 Context work = old_bv->elems;
00628 while (!work.Null())
00629 {
00630 Assoc a = work.Pop();
00631 Val new_sv = new_bv->LookupNoDpnd(a->name);
00632 if(new_sv != valUnbnd)
00633 {
00634 printDepsDiffInner(out, where, subpath+"/"+a->name,
00635 a->val, new_sv);
00636 }
00637 else
00638 {
00639
00640 name_del.addhi(a->name);
00641 }
00642 }
00643
00644 work = new_bv->elems;
00645 while(!work.Null())
00646 {
00647 Assoc a = work.Pop();
00648 if(old_bv->LookupNoDpnd(a->name) == valUnbnd)
00649 {
00650
00651 name_add.addhi(a->name);
00652 }
00653 }
00654
00655
00656 if((name_add.size() > 0) || (name_del.size() > 0))
00657 {
00658 where.print();
00659 out << subpath << "->{binding names} :" << endl;
00660 while(name_del.size() > 0)
00661 out << " - " << name_del.remlo() << endl;
00662 while(name_add.size() > 0)
00663 out << " + " << name_add.remlo() << endl;
00664 }
00665 }
00666 break;
00667 case ListVK:
00668 {
00669 ListVC *old_lv = (ListVC*)old_v;
00670 ListVC *new_lv = (ListVC*)new_v;
00671
00672
00673 printDPSDiffInner(out, where, subpath+"->lenDps",
00674 old_lv->lenDps, new_lv->lenDps);
00675
00676
00677 Vals old_elems = old_lv->elems;
00678 Vals new_elems = new_lv->elems;
00679 unsigned int i = 0;
00680 while(!old_elems.Null() && !new_elems.Null())
00681 {
00682 Val old_sv = old_elems.Pop();
00683 Val new_sv = new_elems.Pop();
00684 char i_str[11];
00685 sprintf(i_str, "%u", i);
00686 printDepsDiffInner(out, where, subpath+"["+Text(i_str)+"]",
00687 old_sv, new_sv);
00688 i++;
00689 }
00690
00691 if(!old_elems.Null() || !new_elems.Null())
00692 {
00693 where.print();
00694 out << subpath << "->{list length} :" << endl
00695 << " - " << old_lv->elems.Length() << endl
00696 << " + " << new_lv->elems.Length() << endl;
00697 }
00698 }
00699 break;
00700 case ClosureVK:
00701 {
00702 ClosureVC *old_cl = (ClosureVC*)old_v;
00703 ClosureVC *new_cl = (ClosureVC*)new_v;
00704
00705
00706
00707 TextSeq name_del, name_add;
00708
00709
00710 Context work = old_cl->con;
00711 while(!work.Null())
00712 {
00713 Assoc a = work.Pop();
00714 if(a->name == old_cl->func->name)
00715
00716
00717 continue;
00718
00719 Val new_sv = LookupInContext(a->name, new_cl->con);
00720 if(new_sv != valUnbnd)
00721 {
00722 printDepsDiffInner(out, where, subpath+"/"+a->name,
00723 a->val, new_sv);
00724 }
00725 else
00726 {
00727
00728 name_del.addhi(a->name);
00729 }
00730 }
00731
00732 work = new_cl->con;
00733 while(!work.Null())
00734 {
00735 Assoc a = work.Pop();
00736 if(LookupInContext(a->name, old_cl->con) == valUnbnd)
00737 {
00738
00739 name_add.addhi(a->name);
00740 }
00741 }
00742
00743
00744 if((name_add.size() > 0) || (name_del.size() > 0))
00745 {
00746 where.print();
00747 out << subpath << "->{context names} :" << endl;
00748 while(name_del.size() > 0)
00749 out << " - " << name_del.remlo() << endl;
00750 while(name_add.size() > 0)
00751 out << " + " << name_add.remlo() << endl;
00752 }
00753 }
00754 break;
00755 }
00756 }
00757
00758 void PrintDepsDiffs(const Text &source, const FP::Tag &pk, CacheEntry::Index cIndex,
00759 Val old_v, Val new_v, const Text &name)
00760 {
00761 ostream &out = cio().start_out();
00762
00763 DepCompareInfo where(out, source, pk, cIndex);
00764 printDepsDiffInner(out, where, name, old_v, new_v);
00765
00766 cio().end_out();
00767 }