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
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 #include <memory.h>
00096 #include "udanax.h"
00097
00098 static int contextnum = 0;
00099 static int c2dontextnum = 0;
00100 static int crumcontextnum = 0;
00101
00109 static Context *
00110 createcontext(
00111 unsigned char type)
00112 {
00113 Context *ret;
00114
00115 if (type == GRAN) {
00116 ret = (Context *) eallocwithtag(sizeof(Context), CONTEXTTAG);
00117 clear(ret, sizeof(Context));
00118 ++contextnum;
00119 } else {
00120 ret = (Context *) eallocwithtag(sizeof(type2dcontext), CONTEXT2DTAG);
00121 clear(ret, sizeof(type2dcontext));
00122 ++c2dontextnum;
00123 }
00124 ret->contexttype = type;
00125 return (ret);
00126 }
00127
00135 void
00136 contextfree(
00137 Context *context)
00138 {
00139 Context *c;
00140
00141 for (; (c = context) != 0;) {
00142 if (c->contexttype == GRAN) {
00143 --contextnum;
00144 } else {
00145 --c2dontextnum;
00146 }
00147
00148 context = (Context *) context->nextcontext;;
00149 efree((char *)c);
00150 }
00151 }
00152
00160 CrumContext *
00161 createcrumcontext(
00162 typecorecrum *crumptr,
00163 typedsp *offsetptr)
00164 {
00165 reserve(crumptr);
00166 CrumContext *ret = (CrumContext *) eallocwithtag(sizeof(CrumContext), CRUMCONTEXTTAG);
00167 ret->nextcrumcontext = NULL;
00168 ret->corecrum = (typecbc *) crumptr;
00169 movewisp(offsetptr, &ret->totaloffset);
00170 ++crumcontextnum;
00171 return ret;
00172 }
00173
00181 void
00182 crumcontextfree(
00183 CrumContext *context)
00184 {
00185 CrumContext *c;
00186
00187 for (; (c = context) != 0; context = context->nextcrumcontext, efree((char *)c)) {
00188 rejuvinate((typecorecrum *) c->corecrum);
00189 --crumcontextnum;
00190 }
00191 }
00192
00200 static int
00201 whereoncontext(
00202 Context *ptr,
00203 Tumbler *address,
00204 int index )
00205 {
00206 Tumbler left, right;
00207
00208 switch (ptr->contexttype) {
00209 case GRAN:
00210 movetumbler(&ptr->totaloffset.dsas[WIDTH], &left);
00211 tumbleradd(&left, &ptr->contextwid.dsas[WIDTH], &right);
00212 break;
00213 case SPAN:
00214
00215
00216
00217
00218
00219 case POOM:
00220 movetumbler(&ptr->totaloffset.dsas[index], &left);
00221 tumbleradd(&left, &ptr->contextwid.dsas[index], &right);
00222 break;
00223 default:
00224 assert(0);
00225 }
00226
00227 return intervalcmp(&left, &right, address);
00228 }
00229
00237
00238
00239 static void
00240 prologuecontextnd(
00241 Context *ptr,
00242 typedsp *grasp,
00243 typedsp *reach)
00244 {
00245 movewisp(&ptr->totaloffset, grasp);
00246 if (reach)
00247 dspadd(grasp, &ptr->contextwid, reach, ptr->contexttype);
00248 }
00249
00257
00258 void
00259 incontextlistnd(
00260 Context **clistptr,
00261 Context *c,
00262 int index)
00263 {
00264 Context *clist, *nextc;
00265 typedsp grasp;
00266
00267 prologuecontextnd(c, &grasp, (typedsp *) NULL);
00268 c->nextcontext = NULL;
00269 clist = *clistptr;
00270
00271 if (!clist) {
00272
00273 *clistptr = c;
00274 return;
00275 }
00276
00277 if (whereoncontext(clist, &grasp.dsas[index], index) < THRUME) {
00278
00279 c->nextcontext = clist;
00280 *clistptr = c;
00281 return;
00282 } else {
00283 for (; (nextc = (Context *) clist->nextcontext) != 0; clist = nextc) {
00284
00285 if ((whereoncontext(clist, &grasp.dsas[index], index) > ONMYLEFTBORDER)
00286 && (whereoncontext(nextc, &grasp.dsas[index], index) < ONMYLEFTBORDER)) {
00287
00288 c->nextcontext = nextc;
00289 clist->nextcontext = c;
00290 return;
00291 }
00292 }
00293 }
00294
00295
00296 c->nextcontext = NULL;
00297 clist->nextcontext = c;
00298 }
00299
00307 void
00308 oncontextlistseq(
00309 Context **clistptr,
00310 Context *c)
00311 {
00312 c->nextcontext = NULL;
00313 if (!*clistptr) {
00314 *clistptr = c;
00315 c->lastcontext = c;
00316 } else {
00317 (*clistptr)->lastcontext->nextcontext = c;
00318 (*clistptr)->lastcontext = c;
00319 }
00320 }
00321
00329 Context *
00330 makecontextfromcbc(
00331 typecbc *crumptr,
00332 typewid *offsetptr)
00333 {
00334 Context *context;
00335
00336 #ifndef DISTRIBUTION
00337 if (debug) {
00338 foo("make contextfromcbc crum is ");
00339 dump((typecorecrum *) crumptr);
00340 }
00341 #endif
00342 reserve((typecorecrum *) crumptr);
00343 context = createcontext(crumptr->cenftype);
00344 movewisp(offsetptr, &context->totaloffset);
00345 movewisp(&crumptr->cwid, &context->contextwid);
00346
00347 if (is2dcrum((typecorecrum *) crumptr))
00348 move2dinfo(&((type2dcbc *) crumptr)->c2dinfo, &((type2dcontext *) context)->context2dinfo);
00349 else
00350 moveinfo((typebottomcruminfo *) &crumptr->cinfo, &context->contextinfo);
00351
00352 if (crumptr->cenftype != GRAN)
00353 dspadd(&context->totaloffset, &crumptr->cdsp, &context->totaloffset, (int) crumptr->cenftype);
00354 context->nextcontext = NULL;
00355 rejuvinate((typecorecrum *) crumptr);
00356 #ifndef DISTRIBUTION
00357 if (debug) {
00358 dumpcontext(context);
00359 }
00360 #endif
00361 return context;
00362 }
00363
00371 static typeitemid
00372 index2itemid(
00373 int index,
00374 Context *context)
00375 {
00376 switch (context->contexttype) {
00377 case POOM: return (index == I) ? ISPANID : VSPANID;
00378 case SPAN: return ISPANID;
00379 default:
00380 assert(0);
00381 return UNKNOWNID;
00382 }
00383 }
00384
00392 void
00393 context2span(
00394 Context *context,
00395 typespan *restrictionspanptr,
00396 int idx1,
00397 typespan *foundspanptr,
00398 int idx2)
00399 {
00400 Tumbler upperbound, lowerbound;
00401 typedsp grasp, reach;
00402
00403
00404
00405
00406
00407
00408
00409 movetumbler(&restrictionspanptr->stream, &lowerbound);
00410 tumbleradd(&lowerbound, &restrictionspanptr->width, &upperbound);
00411 prologuecontextnd(context, &grasp, &reach);
00412
00413
00414 if (tumblercmp(&grasp.dsas[idx1], &lowerbound) == LESS) {
00415
00416
00417 tumblerincrement(&grasp.dsas[idx2], 0, (int) tumblerintdiff(&lowerbound, &grasp.dsas[idx1]), &grasp.dsas[idx2]);
00418
00419 }
00420 if (tumblercmp(&reach.dsas[idx1], &upperbound) == GREATER) {
00421
00422
00423 tumblerincrement(&reach.dsas[idx2], 0,
00424 -tumblerintdiff(&reach.dsas[idx1], &upperbound), &reach.dsas[idx2]);
00425
00426
00427 }
00428
00429
00430 movetumbler(&grasp.dsas[idx2], &foundspanptr->stream);
00431 tumblersub(&reach.dsas[idx2], &grasp.dsas[idx2], &foundspanptr->width);
00432
00433 foundspanptr->itemid = index2itemid(idx2, context);
00434 foundspanptr->next = NULL;
00435
00436 }
00437
00445 static void
00446 context2vtext(
00447 Context *context,
00448 typeispan *ispanptr,
00449 typevstuffset vstuffset)
00450 {
00451 IStreamAddr crumistart, crumiend, ispanstart, ispanend;
00452 int i, vtlength;
00453
00454 movetumbler(&context->totaloffset.dsas[WIDTH], &crumistart);
00455 #ifndef DISTRIBUTION
00456 footumbler("crumistart = ", &crumistart);
00457 #endif
00458 tumblerincrement(&crumistart, 0, (int) context->contextinfo.granbottomcruminfo.granstuff.textstuff.textlength,
00459 &crumiend);
00460 #ifndef DISTRIBUTION
00461 footumbler("crumiend = ", &crumiend);
00462 #endif
00463 movetumbler(&ispanptr->stream, &ispanstart);
00464 tumbleradd(&ispanstart, &ispanptr->width, &ispanend);
00465 i = 0;
00466 vtlength = context->contextinfo.granbottomcruminfo.granstuff.textstuff.textlength;
00467 if (tumblercmp(&crumistart, &ispanstart) == LESS) {
00468 #ifndef DISTRIBUTION
00469 foo("first if\n\ti = tumblerintdiff (&ispanstart, &crumistart)\n");
00470 #endif
00471 i = tumblerintdiff(&ispanstart, &crumistart);
00472 vtlength -= i;
00473 }
00474 if (tumblercmp(&crumiend, &ispanend) == GREATER) {
00475 #ifndef DISTRIBUTION
00476 foo("second if\n\tvtlength -= tumblerintdiff (&crumiend, &ispanend)\n");
00477 #endif
00478 vtlength -= tumblerintdiff(&crumiend, &ispanend);
00479 }
00480 ((typetext *) vstuffset)->length = vtlength > 0 ? vtlength : -vtlength;
00481 movmem(&context->contextinfo.granbottomcruminfo.granstuff.textstuff.textstring[i], ((typetext *) vstuffset)->string,
00482 ((typetext *) vstuffset)->length);
00483 }
00484
00492 bool
00493 context2vstuff(
00494 Session *sess,
00495 Context *context,
00496 typeispan *ispanptr,
00497 typevstuffset *vstuffsetptr)
00498 {
00499 typevstuffset vstuffset = NULL;
00500
00501 #ifndef DISTRIBUTION
00502 foo("context2stuff\n");
00503 #endif
00504
00505 int contextinfotype = context->contextinfo.granbottomcruminfo.infotype;
00506
00507 if (contextinfotype != GRANTEXT && contextinfotype != GRANORGL)
00508 return false;
00509
00510 switch (contextinfotype) {
00511 case GRANTEXT:
00512 vstuffset = (typevstuffset) new(sess) typetext;
00513
00514
00515 ((typeitemheader *) vstuffset)->next = NULL;
00516 #ifndef DISTRIBUTION
00517 foocontext("context after item= ", context);
00518 #endif
00519 ((typeitemheader *) vstuffset)->itemid = TEXTID;
00520 context2vtext(context, ispanptr, vstuffset);
00521 if (((typetext *) vstuffset)->length == 0)
00522 return false;
00523 break;
00524
00525 case GRANORGL:
00526 vstuffset = (typevstuffset) new(sess) typeaddress;
00527
00528
00529 ((typeitemheader *) vstuffset)->next = NULL;
00530 #ifndef DISTRIBUTION
00531 foocontext("context after item= ", context);
00532 #endif
00533 ((typeitemheader *) vstuffset)->itemid = ADDRESSID;
00534 movetumbler(&context->totaloffset.dsas[WIDTH], &((typelink *) vstuffset)->address);
00535 }
00536
00537 *vstuffsetptr = vstuffset;
00538 return true;
00539 }