00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 #include <memory.h>
00085 #include "udanax.h"
00086
00087
00088
00089
00097 static CrumContext *
00098 findcbcseqcrum(
00099 typecorecrum *ptr,
00100 typedsp *offsetptr,
00101 Tumbler *address)
00102 {
00103 if (!ptr)
00104 assert(0);
00105
00106 for (; getrightbro(ptr); ptr = ptr->rightbro) {
00107 if (whereoncrum(ptr, offsetptr, address, WIDTH) <= THRUME)
00108 break;
00109
00110 dspadd(offsetptr, &ptr->cwid, offsetptr, (int) ptr->cenftype);
00111 }
00112
00113 if (ptr->height != 0) {
00114 ptr = findleftson((typecuc *) ptr);
00115 return findcbcseqcrum(ptr, offsetptr, address);
00116 } else
00117 return createcrumcontext(ptr, offsetptr);
00118 }
00119
00127 static Context *
00128 findcbcseq(
00129 typecorecrum *ptr,
00130 typedsp *offsetptr,
00131 Tumbler *address)
00132 {
00133 for (; getrightbro(ptr); ptr = ptr->rightbro) {
00134 if (whereoncrum(ptr, offsetptr, address, WIDTH) <= THRUME)
00135 break;
00136
00137 dspadd(offsetptr, &ptr->cwid, offsetptr, (int) ptr->cenftype);
00138 }
00139
00140 if (ptr->height != 0) {
00141 ptr = findleftson((typecuc *) ptr);
00142 return findcbcseq(ptr, offsetptr, address);
00143 } else
00144 return makecontextfromcbc((typecbc *) ptr, (typewid *) offsetptr);
00145 }
00146
00154 static Context *
00155 findcbcnd(
00156 typecorecrum *father,
00157 typewid *offsetptr,
00158 Tumbler *address,
00159 int index)
00160 {
00161 typecorecrum *ptr;
00162 typewid grasp;
00163 Context *retr = NULL;
00164 int cmp;
00165
00166 if ((cmp = whereoncrum(father, offsetptr, address, index)) < ONMYLEFTBORDER || cmp > THRUME)
00167 return NULL;
00168
00169 if (father->height != 0) {
00170 prologuend(father, offsetptr, &grasp, (typedsp *) NULL);
00171 for (ptr = findleftson((typecuc *) father); ptr; ptr = getrightbro(ptr))
00172 if ((retr = findcbcnd(ptr, &grasp, address, index)) != 0)
00173 break;
00174
00175 } else
00176 retr = makecontextfromcbc((typecbc *) father, offsetptr);
00177
00178 return retr;
00179 }
00180
00188 static bool
00189 crumqualifies2d(
00190 typecorecrum *crumptr,
00191 typedsp *offset,
00192 Tumbler *span1start,
00193 Tumbler *span1end,
00194 int index1,
00195 Tumbler *span2start,
00196 Tumbler *span2end,
00197 int index2,
00198 type2dbottomcruminfo *infoptr)
00199
00200 {
00201 int startcmp, endcmp;
00202
00203
00204 if ((crumptr->height == 0) && infoptr && !tumblereq(&infoptr->homedoc, &(((type2dcbc *) crumptr)->c2dinfo.homedoc))) {
00205 #ifndef DISTRIBUTION
00206 L("mumble homedoc");
00207 #endif
00208
00209 return false;
00210 }
00211
00212 endcmp = iszerotumbler(span1end) ? TOMYRIGHT : whereoncrum(crumptr, offset, span1end, index1);
00213 if (endcmp <= ONMYLEFTBORDER)
00214 return false;
00215
00216 startcmp = whereoncrum(crumptr, offset, span1start, index1);
00217 if ((startcmp > THRUME ))
00218 return false;
00219
00220 endcmp = iszerotumbler(span2end) ? TOMYRIGHT : whereoncrum(crumptr, offset, span2end, index2);
00221 if (endcmp < ONMYLEFTBORDER)
00222 return false;
00223
00224 startcmp = whereoncrum(crumptr, offset, span2start, index2);
00225 if ((startcmp > THRUME ))
00226 return false;
00227
00228 return true;
00229 }
00230
00238 static void
00239 findcbcinarea2d(
00240 typecorecrum *crumptr,
00241 typedsp *offsetptr,
00242 Tumbler *span1start,
00243 Tumbler *span1end,
00244 int index1,
00245 Tumbler *span2start,
00246 Tumbler *span2end,
00247 int index2,
00248 Context **headptr,
00249 typebottomcruminfo *infoptr)
00250 {
00251 typedsp localoffset;
00252 Context *context;
00253
00254 #ifndef DISTRIBUTION
00255
00256
00257
00258
00259
00260
00261 if (infoptr) {
00262 L("not NULL infoptr versions mumble specialcase 11/27/84 shouldent happen till we try something fancier\n");
00263 assert(0);
00264 }
00265 #else
00266 if (infoptr)
00267 assert(0);
00268 #endif
00269
00270 for (; crumptr; crumptr = getrightbro(crumptr)) {
00271 if (!crumqualifies2d(crumptr, offsetptr, span1start, span1end, index1, span2start, span2end, index2, (type2dbottomcruminfo *) infoptr))
00272 continue;
00273
00274
00275 if (crumptr->height != 0) {
00276 dspadd(offsetptr, &crumptr->cdsp, &localoffset, (int) crumptr->cenftype);
00277 findcbcinarea2d(findleftson((typecuc *) crumptr), &localoffset, span1start, span1end, index1, span2start, span2end, index2, headptr, infoptr);
00278 } else {
00279
00280 context = makecontextfromcbc((typecbc *) crumptr, (typewid *) offsetptr);
00281 incontextlistnd(headptr, context, index1);
00282 }
00283 }
00284
00285
00286
00287 }
00288
00296 CrumContext *
00297 retrievecrums(
00298 typecuc *fullcrumptr,
00299 Tumbler *address,
00300 int index)
00301 {
00302 typedsp offset;
00303 clear(&offset, sizeof(typedsp));
00304
00305 if (fullcrumptr->cenftype == GRAN)
00306 return findcbcseqcrum((typecorecrum *) fullcrumptr, &offset, address);
00307 else {
00308 assert(0);
00309 return NULL;
00310 }
00311 }
00312
00320 Context *
00321 retrieve(
00322 typecuc *fullcrumptr,
00323 Tumbler *address,
00324 int index)
00325
00326 {
00327 typedsp offset;
00328
00329 clear(&offset, sizeof(typedsp));
00330 switch (fullcrumptr->cenftype) {
00331 case GRAN:
00332 return findcbcseq((typecorecrum *) fullcrumptr, &offset, address);
00333 case SPAN:
00334 case POOM:
00335 return findcbcnd((typecorecrum *) fullcrumptr, &offset, address, index);
00336 default:
00337 assert(0);
00338 return NULL;
00339 }
00340 }
00341
00349 static Context *
00350 retrieveinarea(
00351 typecuc *fullcrumptr,
00352 Tumbler *span1start,
00353 Tumbler *span1end,
00354 int index1,
00355 Tumbler *span2start,
00356 Tumbler *span2end,
00357 int index2,
00358 typebottomcruminfo *infoptr)
00359 {
00360
00361 typedsp offset;
00362 clear(&offset, sizeof(offset));
00363
00364 Context *context = NULL;
00365
00366 switch (fullcrumptr->cenftype) {
00367 case SPAN:
00368 case POOM:
00369 findcbcinarea2d((typecorecrum *) fullcrumptr, &offset, span1start, span1end, index1, span2start, span2end,
00370 index2, &context, infoptr);
00371 break;
00372 default:
00373
00374 assert(0);
00375 }
00376
00377
00378 return context;
00379 }
00380
00388 Context *
00389 retrieverestricted(
00390 typecuc *fullcrumptr,
00391 typespan *span1ptr,
00392 int index1,
00393 typespan *span2ptr,
00394 int index2,
00395 IStreamAddr *docisaptr)
00396 {
00397 Tumbler span1start, span1end, span2start, span2end;
00398 type2dbottomcruminfo info, *infoptr;
00399
00400 if (span1ptr) {
00401 movetumbler(&span1ptr->stream, &span1start);
00402 tumbleradd(&span1start, &span1ptr->width, &span1end);
00403 } else {
00404 tumblerclear(&span1start);
00405 tumblerclear(&span1end);
00406 }
00407
00408 if (span2ptr) {
00409 movetumbler(&span2ptr->stream, &span2start);
00410 tumbleradd(&span2start, &span2ptr->width, &span2end);
00411 } else {
00412 tumblerclear(&span2start);
00413 tumblerclear(&span2end);
00414 }
00415
00416 if (docisaptr) {
00417 movetumbler(docisaptr, &info.homedoc );
00418 infoptr = &info;
00419 } else {
00420 infoptr = NULL;
00421 }
00422
00423 return retrieveinarea(fullcrumptr, &span1start, &span1end, index1, &span2start, &span2end, index2,
00424 (typebottomcruminfo *) infoptr);
00425 }
00426
00434 static Context *
00435 findlastcbcseq(
00436 typecorecrum *fullcrumptr)
00437 {
00438 Tumbler offset;
00439 tumblerclear(&offset);
00440
00441 typecorecrum *ptr;
00442 for (ptr = fullcrumptr; ptr; ptr = findleftson((typecuc *) ptr)) {
00443 for (; getrightbro(ptr); ptr = ptr->rightbro)
00444 tumbleradd(&offset, &ptr->cwid.dsas[WIDTH], &offset);
00445
00446 if (ptr->height == 0)
00447 return makecontextfromcbc((typecbc *) ptr, (typewid *) &offset);
00448 }
00449
00450 assert(0);
00451 return NULL;
00452 }
00453
00461 static bool
00462 crumintersectsspanseq(
00463 typecorecrum *crumptr,
00464 Tumbler *offsetptr,
00465 Tumbler *spanstart,
00466 Tumbler *spanend)
00467 {
00468 if (iszerotumbler(&crumptr->cwid.dsas[WIDTH]))
00469 return false;
00470
00471 return (whereoncrum(crumptr, (typewid *) offsetptr, spanstart, WIDTH) < ONMYRIGHTBORDER)
00472 && (whereoncrum(crumptr, (typewid *) offsetptr, spanend, WIDTH) >
00473 ONMYLEFTBORDER);
00474 }
00475
00483 static void
00484 findcbcinspanseq(
00485 typecorecrum *crumptr,
00486 typewid *offsetptr,
00487 Tumbler *spanstart,
00488 Tumbler *spanend,
00489 Context **headptr)
00490 {
00491 typewid localoffset;
00492 Context *context;
00493
00494 movewisp(offsetptr, &localoffset);
00495 for (; crumptr; crumptr = getrightbro(crumptr)) {
00496 if (!crumintersectsspanseq(crumptr, (Tumbler *) & localoffset, spanstart, spanend)) {
00497 dspadd(&localoffset, &crumptr->cwid, &localoffset, (int) crumptr->cenftype);
00498 continue;
00499 }
00500
00501 if (crumptr->height == 0) {
00502 context = makecontextfromcbc((typecbc *) crumptr, offsetptr);
00503 oncontextlistseq(headptr, context);
00504 } else {
00505 findcbcinspanseq(findleftson((typecuc *) crumptr), &localoffset, spanstart, spanend, headptr);
00506 }
00507
00508 dspadd(&localoffset, &crumptr->cwid, &localoffset, (int) crumptr->cenftype);
00509 }
00510 }
00511
00519 Context *
00520 retrieveinspan(
00521 typecuc *fullcrumptr,
00522 Tumbler *spanstart,
00523 Tumbler *spanend,
00524 int index)
00525 {
00526 typedsp offset;
00527 clear(&offset, sizeof(offset));
00528
00529 Context *context = NULL;
00530
00531 switch (fullcrumptr->cenftype) {
00532 case GRAN:
00533 findcbcinspanseq((typecorecrum *) fullcrumptr, &offset, spanstart, spanend, &context);
00534 if (tumblercmp(spanend, &fullcrumptr->cwid.dsas[WIDTH]) == GREATER) {
00535 Context *c = findlastcbcseq((typecorecrum *) fullcrumptr);
00536 oncontextlistseq(&context, c);
00537 }
00538 return context;
00539 default:
00540 assert(0);
00541 return NULL;
00542 }
00543 }
00544
00552
00553
00554 void
00555 prologuend(
00556 typecorecrum *ptr,
00557 typedsp *offset,
00558 typedsp *grasp,
00559 typedsp *reach)
00560 {
00561 dspadd(offset, &ptr->cdsp, grasp, (int) ptr->cenftype);
00562 if (reach)
00563 dspadd(grasp, &ptr->cwid, reach, (int) ptr->cenftype);
00564 }
00565
00566 #define intervalcmppart1(left,address) cmp = tumblercmp ((address), (left)); if (cmp == LESS) return (TOMYLEFT); else if (cmp == EQUAL) return (ONMYLEFTBORDER);
00567
00568 #define intervalcmppart2(right,address) cmp = tumblercmp ((address), (right)); if (cmp == LESS) return (THRUME); else if (cmp == EQUAL) return (ONMYRIGHTBORDER); else return (TOMYRIGHT);
00569
00577 int
00578 whereoncrum(
00579 typecorecrum *ptr,
00580 typewid *offset,
00581 Tumbler *address,
00582 int index)
00583
00584
00585 {
00586 Tumbler left, right;
00587 int cmp;
00588
00589 switch (ptr->cenftype) {
00590 case GRAN:
00591 tumbleradd(&offset->dsas[WIDTH], &ptr->cwid.dsas[WIDTH], &right);
00592 return intervalcmp(&offset->dsas[WIDTH], &right, address);
00593
00594 case SPAN:
00595 case POOM:
00596 tumbleradd(&offset->dsas[index], &ptr->cdsp.dsas[index], &left);
00597 cmp = tumblercmp(address, &left);
00598 if (cmp == LESS) {
00599 return TOMYLEFT;
00600 } else if (cmp == EQUAL) {
00601 return ONMYLEFTBORDER;
00602 }
00603
00604
00605 tumbleradd(&left, &ptr->cwid.dsas[index], &right);
00606 cmp = tumblercmp(address, &right);
00607 if (cmp == LESS) {
00608 return THRUME;
00609 } else if (cmp == EQUAL) {
00610 return ONMYRIGHTBORDER;
00611 } else {
00612 return TOMYRIGHT;
00613 }
00614
00615
00616
00617
00618
00619
00620
00621 default:
00622 assert(0);
00623 }
00624
00625 assert(0);
00626 return 0;
00627 }