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 #include <memory.h>
00092 #include "udanax.h"
00093
00094 #ifdef DISTRIBUTION
00095 char granf2err[] = "g2error\n";
00096 #endif
00097
00098 static void findisatoinsertmolecule(typecuc * fullcrumptr, typehint * hintptr, IStreamAddr * isaptr);
00099 static void klugefindisatoinsertnonmolecule(typecuc * fullcrumptr, typehint * hintptr, IStreamAddr * isaptr);
00100 static void findisatoinsertnonmolecule(typecuc * fullcrumptr, typehint * hintptr, IStreamAddr * isaptr);
00101
00109 typeorgl
00110 fetchorglgr(
00111 Session *sess,
00112 typegranf fullcrumptr,
00113 IStreamAddr *address)
00114 {
00115 CrumContext *context;
00116 typecuc *ret = NULL;
00117
00118 #ifndef DISTRIBUTION
00119 if (debug) {
00120 L("fetchorglgr ");
00121 dumptumbler(address);
00122 L("\n");
00123 }
00124 #endif
00125
00126 if (tumblercmp(&((typecuc *) fullcrumptr)->cwid.dsas[WIDTH], address) == LESS)
00127 return NULL;
00128
00129 if ((context = retrievecrums((typecuc *) fullcrumptr, address, WIDTH)) == NULL)
00130 return NULL;
00131
00132 if (!tumblereq((Tumbler *) & context->totaloffset, address)) {
00133 crumcontextfree(context);
00134 return NULL;
00135 }
00136
00137 if (!context->corecrum->cinfo.granstuff.orglstuff.orglptr && context->corecrum->cinfo.granstuff.orglstuff.diskorglptr.diskblocknumber == DISKPTRNULL) {
00138 assert(0);
00139 }
00140
00141 assert(context->corecrum->cinfo.infotype == GRANORGL);
00142
00143 if (!context->corecrum->cinfo.granstuff.orglstuff.orglincore) {
00144 if (context->corecrum->cinfo.granstuff.orglstuff.diskorglptr.diskblocknumber == DISKPTRNULL)
00145 assert(0);
00146 inorgl(context->corecrum);
00147 }
00148
00149 ret = context->corecrum->cinfo.granstuff.orglstuff.orglptr;
00150 if (!ret)
00151 assert(0);
00152
00153 crumcontextfree(context);
00154 rejuvinate((typecorecrum *) ret);
00155 return (typeorgl) ret;
00156 }
00157
00165 static bool
00166 isaexistsgr(
00167 typecuc *crumptr,
00168 IStreamAddr *isaptr)
00169 {
00170 Context *context = retrieve(crumptr, isaptr, WIDTH);
00171 bool ret = tumblereq((Tumbler *) &context->totaloffset, isaptr);
00172
00173 contextfree(context);
00174 return ret;
00175 }
00176
00184 static bool
00185 findisatoinsertgr(
00186 typecuc *fullcrumptr,
00187 typehint *hintptr,
00188 IStreamAddr *isaptr)
00189 {
00190
00191 if (!isaexistsgr(fullcrumptr, &hintptr->hintisa)) {
00192 if (hintptr->subtype != ATOM) {
00193
00194 klugefindisatoinsertnonmolecule(fullcrumptr, hintptr, isaptr);
00195 tumblerjustify(isaptr);
00196 return true;
00197 }
00198 #ifndef DISTRIBUTION
00199 L("nothing at hintisa\n");
00200 #endif
00201 return false;
00202 }
00203
00204 if (hintptr->subtype == ATOM)
00205 findisatoinsertmolecule(fullcrumptr, hintptr, isaptr);
00206 else
00207 findisatoinsertnonmolecule(fullcrumptr, hintptr, isaptr);
00208
00209 tumblerjustify(isaptr);
00210 return true;
00211 }
00212
00220 bool
00221 inserttextgr(
00222 Session *sess,
00223 typegranf fullcrumptr,
00224 typehint *hintptr,
00225 typetextset textset,
00226 typeispanset *ispansetptr)
00227 {
00228 typegranbottomcruminfo locinfo;
00229 typeispan *ispanptr;
00230
00231 IStreamAddr lsa;
00232 if (!findisatoinsertgr((typecuc *) fullcrumptr, hintptr, &lsa))
00233 return false;
00234
00235 Tumbler spanorigin;
00236 movetumbler(&lsa, &spanorigin);
00237
00238 for (; textset; textset = textset->next) {
00239 locinfo.infotype = GRANTEXT;
00240 locinfo.granstuff.textstuff.textlength = textset->length;
00241 movmem(textset->string, locinfo.granstuff.textstuff.textstring, locinfo.granstuff.textstuff.textlength);
00242 insertseq((typecuc *) fullcrumptr, &lsa, &locinfo);
00243 tumblerincrement(&lsa, 0, textset->length, &lsa);
00244 }
00245
00246 ispanptr = new(sess) typeispan;
00247
00248 ispanptr->itemid = ISPANID;
00249 ispanptr->next = NULL;
00250
00251 movetumbler(&spanorigin, &ispanptr->stream);
00252 tumblersub(&lsa, &spanorigin, &ispanptr->width);
00253 *ispansetptr = ispanptr;
00254
00255 return true;
00256 }
00257
00265 bool
00266 createorglgr(
00267 Session *sess,
00268 typegranf fullcrumptr,
00269 typehint *hintptr,
00270 IStreamAddr *isaptr)
00271 {
00272 typegranbottomcruminfo locinfo;
00273
00274 if (!findisatoinsertgr((typecuc *) fullcrumptr, hintptr, isaptr))
00275 return false;
00276
00277 locinfo.infotype = GRANORGL;
00278 locinfo.granstuff.orglstuff.orglptr = createenf(POOM);
00279 reserve((typecorecrum *) locinfo.granstuff.orglstuff.orglptr);
00280
00281 locinfo.granstuff.orglstuff.orglincore = true;
00282 locinfo.granstuff.orglstuff.diskorglptr.diskblocknumber = DISKPTRNULL;
00283 locinfo.granstuff.orglstuff.diskorglptr.insidediskblocknumber = 0;
00284
00285 insertseq((typecuc *) fullcrumptr, isaptr, &locinfo);
00286 rejuvinate((typecorecrum *) locinfo.granstuff.orglstuff.orglptr);
00287
00288 return true;
00289 }
00290
00298 static void
00299 findlastisaincbcgr(
00300 typecbc *ptr,
00301 IStreamAddr *offset)
00302
00303 {
00304 if (ptr->cinfo.infotype == GRANTEXT)
00305 tumblerincrement(offset, 0, (int) ptr->cinfo.granstuff.textstuff.textlength - 1, offset);
00306 }
00307
00315 static void
00316 findpreviousisagr(
00317 typecorecrum *crumptr,
00318 IStreamAddr *upperbound,
00319 IStreamAddr *offset)
00320 {
00321 RECURSIVE
00322 int tmp;
00323
00324
00325 if (crumptr->height == 0) {
00326 findlastisaincbcgr((typecbc *) crumptr, offset);
00327 return;
00328 }
00329
00330 typecorecrum *ptr;
00331 for (ptr = findleftson((typecuc *) crumptr); ptr; ptr = findrightbro(ptr)) {
00332 if ((tmp = whereoncrum(ptr, (typewid *) offset, upperbound, WIDTH)) == THRUME
00333 || tmp == ONMYRIGHTBORDER || !ptr->rightbro) {
00334 findpreviousisagr(ptr, upperbound, offset);
00335 return;
00336 } else {
00337 tumbleradd(offset, &ptr->cwid.dsas[WIDTH], offset);
00338 }
00339 }
00340 }
00341
00349 static void
00350 findisatoinsertmolecule(
00351 typecuc *fullcrumptr,
00352 typehint *hintptr,
00353 IStreamAddr *isaptr)
00354 {
00355 IStreamAddr upperbound, lowerbound;
00356
00357 tumblerincrement(&hintptr->hintisa, 2, hintptr->atomtype + 1, &upperbound);
00358 clear(&lowerbound, sizeof(lowerbound));
00359
00360 findpreviousisagr((typecorecrum *) fullcrumptr, &upperbound, &lowerbound);
00361 if (tumblerlength(&hintptr->hintisa) == tumblerlength(&lowerbound)) {
00362 tumblerincrement(&lowerbound, 2, hintptr->atomtype, isaptr);
00363 tumblerincrement(isaptr, 1, 1, isaptr);
00364 } else if (hintptr->atomtype == TEXTATOM) {
00365 tumblerincrement(&lowerbound, 0, 1, isaptr);
00366 } else if (hintptr->atomtype == LINKATOM) {
00367 tumblerincrement(&hintptr->hintisa, 2, 2, isaptr);
00368 if (tumblercmp(&lowerbound, isaptr) == LESS)
00369 tumblerincrement(isaptr, 1, 1, isaptr);
00370 else
00371 tumblerincrement(&lowerbound, 0, 1, isaptr);
00372 } else
00373 assert(0);
00374 }
00375
00383 static void
00384 klugefindisatoinsertnonmolecule(
00385 typecuc *fullcrumptr,
00386 typehint *hintptr,
00387 IStreamAddr *isaptr)
00388 {
00389
00390
00391
00392
00393
00394 #ifdef UnDeFIned
00395
00396 tumblercopy( hintptr , isaptr);
00397 #endif
00398 tumblercopy(&hintptr->hintisa, isaptr);
00399
00400 }
00401
00409 static void
00410 findisatoinsertnonmolecule(
00411 typecuc *fullcrumptr,
00412 typehint *hintptr,
00413 IStreamAddr *isaptr)
00414 {
00415 int depth = (hintptr->supertype == hintptr->subtype) ? 1 : 2;
00416 int hintlength = tumblerlength(&hintptr->hintisa);
00417
00418 IStreamAddr upperbound;
00419 tumblerincrement(&hintptr->hintisa, depth - 1, 1, &upperbound);
00420
00421 IStreamAddr lowerbound;
00422 clear(&lowerbound, sizeof(lowerbound));
00423
00424 findpreviousisagr((typecorecrum *) fullcrumptr, &upperbound, &lowerbound);
00425
00426 tumblertruncate(&lowerbound, hintlength + depth, isaptr);
00427 tumblerincrement(isaptr, (tumblerlength(isaptr) == hintlength) ? depth : 0, 1, isaptr);
00428 }
00429
00437 typevstuffset *
00438 ispan2vstuffset(
00439 Session *sess,
00440 typegranf fullcrumptr,
00441 typeispan *ispanptr,
00442 typevstuffset *vstuffsetptr)
00443 {
00444 typevstuffset vstuffset;
00445 Context *temp;
00446
00447 *vstuffsetptr = NULL;
00448
00449 IStreamAddr lowerbound;
00450 movetumbler(&ispanptr->stream, &lowerbound);
00451
00452 IStreamAddr upperbound;
00453 tumbleradd(&lowerbound, &ispanptr->width, &upperbound);
00454
00455 Context *context = retrieveinspan((typecuc *) fullcrumptr, &lowerbound, &upperbound, WIDTH);
00456
00457 #ifndef DISTRIBUTION
00458 foocontextlist("retrieveinspan returning\n", context);
00459 #endif
00460
00461 for (temp = context; temp; temp = (Context *) temp->nextcontext) {
00462 #ifndef DISTRIBUTION
00463 foocontext("passing context temp =", temp);
00464 #endif
00465 if (context2vstuff(sess, temp, ispanptr, &vstuffset)) {
00466 #ifndef DISTRIBUTION
00467 foohex("vstuffsetptr = ", (int) vstuffsetptr);
00468 foohex("vstuffset = ", (int) vstuffset);
00469 foohex("&vstuffset->next = ", (int) &((typeitemheader *) vstuffset)->next);
00470 #endif
00471 *vstuffsetptr = vstuffset;
00472 vstuffsetptr = (typevstuffset *) & ((typeitemheader *) vstuffset)->next;
00473 }
00474 }
00475
00476 contextfree(context);
00477 return vstuffsetptr;
00478 }