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
00095 static int
00096 widdiffs(typecuc *crumptr)
00097 {
00098 if (crumptr->cenftype != POOM)
00099 return 0;
00100
00101 int i = lastdigitintumbler(&crumptr->cwid.dsas[I]);
00102 int v = lastdigitintumbler(&crumptr->cwid.dsas[V]);
00103 return i - v;
00104 }
00105
00112 static void
00113 findaddressofsecondcutforinsert(
00114 Tumbler *position,
00115 Tumbler *secondcut)
00116 {
00117 Tumbler zero, intpart;
00118
00119 tumblerclear(&zero);
00120 tumblerincrement(position, -1, 1, secondcut);
00121 beheadtumbler(position, &intpart);
00122 tumblerincrement(secondcut, 0, -tumblerintdiff(&intpart, &zero), secondcut);
00123 tumblerincrement(secondcut, 1, 1, secondcut);
00124 }
00125
00132 static void
00133 makegappm(
00134 Session *sess,
00135 typecuc *fullcrumptr,
00136 typewid *origin,
00137 typewid *width)
00138 {
00139 typeknives knives;
00140 typewid offset, grasp, reach;
00141 typecuc *father;
00142 typecorecrum *ptr;
00143 typewid foffset, fgrasp;
00144 int i ;
00145
00146 #ifndef DISTRIBUTION
00147 foo("makegappm\n");
00148 checkwholesubtree(fullcrumptr);
00149 #endif
00150
00151
00152 clear(&offset, sizeof(offset));
00153 prologuend((typecorecrum *) fullcrumptr, &offset, &grasp, &reach);
00154 if (iszerotumbler(&fullcrumptr->cwid.dsas[V])
00155 || tumblercmp(&origin->dsas[V], &grasp.dsas[V]) == LESS || tumblercmp(&origin->dsas[V], &reach.dsas[V]) != LESS)
00156 return;
00157
00158 movetumbler(&origin->dsas[V], &knives.blades[0]);
00159 findaddressofsecondcutforinsert(&origin->dsas[V], &knives.blades[1]);
00160 knives.nblades = 2;
00161 knives.dimension = V;
00162
00163 makecutsnd(fullcrumptr, &knives);
00164 newfindintersectionnd(fullcrumptr, &knives, &father, &foffset);
00165 prologuend((typecorecrum *) father, &foffset, &fgrasp, (typedsp *) NULL);
00166
00167 for (ptr = findleftson(father); ptr; ptr = findrightbro(ptr)) {
00168 i = insertcutsectionnd(ptr, &fgrasp, &knives);
00169 switch (i) {
00170 case 0:
00171 case 2:
00172 break;
00173 case -1:
00174 dump(ptr);
00175 assert(0);
00176 break;
00177 case 1:
00178 tumbleradd(&ptr->cdsp.dsas[V], &width->dsas[V], &ptr->cdsp.dsas[V]);
00179
00180 ivemodified(ptr);
00181 break;
00182 default:
00183 assert(0);
00184 }
00185 }
00186 setwidnd(father);
00187 setwispupwards(findfather((typecorecrum *) father), 1);
00188 }
00189
00196 static void
00197 firstinsertionnd(
00198 typecuc *father,
00199 typewid *origin,
00200 typewid *width,
00201 type2dbottomcruminfo *infoptr)
00202 {
00203 typecorecrum *ptr = findleftson(father);
00204 movewisp(origin, &ptr->cdsp);
00205 movewisp(width, &ptr->cwid);
00206 move2dinfo(infoptr, &((type2dcbc *) ptr)->c2dinfo);
00207 ivemodified(ptr);
00208 setwisp((typecorecrum *) father);
00209 }
00210
00217 static bool
00218 isanextensionnd(
00219 typecbc *ptr,
00220 typedsp *offsetptr,
00221 typedsp *originptr,
00222 type2dbottomcruminfo *infoptr)
00223 {
00224 if (!tumblereq(&infoptr->homedoc, &((type2dcbc *) ptr)->c2dinfo.homedoc))
00225 return false;
00226
00227 typedsp grasp, reach;
00228 prologuend((typecorecrum *) ptr, offsetptr, &grasp, &reach);
00229 return lockeq(reach.dsas, originptr->dsas, (unsigned) dspsize(ptr->cenftype));
00230 }
00231
00238 static int
00239 insertcbcnd(
00240 typecuc *father,
00241 typedsp *grasp,
00242 typewid *origin,
00243 typewid *width,
00244 type2dbottomcruminfo *infoptr)
00245 {
00246 typecorecrum *ptr, *newcc;
00247 bool splitsomething;
00248
00249 for (ptr = findleftson(father); ptr; ptr = findrightbro(ptr)) {
00250 if (isanextensionnd((typecbc *) ptr, grasp, origin, infoptr)) {
00251 dspadd(&ptr->cwid, width, &ptr->cwid, (int) father->cenftype);
00252 ivemodified(ptr);
00253 setwispupwards(father, 1);
00254
00255 if (!isfullcrum((typecorecrum *) father))
00256 return setwispupwards(findfather((typecorecrum *) father), 1);
00257
00258 return false;
00259 }
00260 }
00261
00262 newcc = createcrum(0, (int) father->cenftype);
00263 reserve(newcc);
00264 adopt(newcc, SON, (typecorecrum *) father);
00265 dspsub(origin, grasp, &newcc->cdsp, (int) father->cenftype);
00266
00267 if (iszerolock((Tumbler *) width, 2))
00268 assert(0);
00269
00270 movewisp(width, &newcc->cwid);
00271 move2dinfo(infoptr, &((type2dcbc *) newcc)->c2dinfo);
00272 ivemodified(newcc);
00273
00274 setwispupwards((typecuc *) newcc , 0);
00275 setwispupwards(father, 1);
00276 splitsomething = splitcrumupwards(father);
00277 rejuvinate(newcc);
00278
00279 return splitsomething;
00280 }
00281
00288 static typecorecrum *
00289 findsontoinsertundernd(
00290 typecuc *father,
00291 typedsp *grasp,
00292 typewid *origin,
00293 typewid *width,
00294 int index)
00295 {
00296 typecorecrum *ptr, *nearestonleft;
00297 Tumbler spanend, sonstart;
00298
00299 if (iszerotumbler(&width->dsas[index]))
00300 assert(0);
00301
00302 tumbleradd(&origin->dsas[index], &width->dsas[index], &spanend);
00303
00304 ptr = nearestonleft = findleftson(father);
00305
00306 for (; ptr; ptr = findrightbro(ptr)) {
00307 tumbleradd(&grasp->dsas[index], &ptr->cdsp.dsas[index], &sonstart);
00308 if (tumblercmp(&sonstart, &origin->dsas[index]) != GREATER
00309 && tumblercmp(&ptr->cdsp.dsas[index], &nearestonleft->cdsp.dsas[index]) != LESS) {
00310 nearestonleft = ptr;
00311 }
00312
00313 if (whereoncrum(ptr, grasp, &origin->dsas[index], index) >= ONMYLEFTBORDER
00314 && whereoncrum(ptr, grasp, &spanend, index) <= ONMYRIGHTBORDER)
00315 return ptr;
00316 }
00317 return nearestonleft;
00318 }
00319
00326 static int
00327 insertmorend(
00328 typecuc *father,
00329 typedsp *offset,
00330 typewid *origin,
00331 typewid *width,
00332 type2dbottomcruminfo *infoptr,
00333 int index)
00334 {
00335 typedsp grasp;
00336
00337 if (iszerotumbler(&width->dsas[index]))
00338 assert(0);
00339
00340 makeroomonleftnd(father, offset, origin, &grasp);
00341 if (father->height == 1)
00342 return insertcbcnd(father, &grasp, origin, width, infoptr);
00343
00344 typecorecrum *ptr = findsontoinsertundernd(father, &grasp, origin, width, index);
00345 int temp = insertmorend((typecuc *) ptr, &grasp, origin, width, infoptr, index);
00346
00347
00348 setwispupwards(father, 1);
00349
00350 ivemodified(ptr);
00351 return temp;
00352 }
00353
00360 static int
00361 doinsertnd(
00362 typecuc *father,
00363 typewid *origin,
00364 typewid *width,
00365 type2dbottomcruminfo *infoptr,
00366 int index)
00367 {
00368 typedsp offset;
00369
00370 if (iszerotumbler(&width->dsas[index]))
00371 assert(0);
00372
00373 if (isemptyenfilade(father)) {
00374 firstinsertionnd(father, origin, width, infoptr);
00375 return false;
00376 }
00377 clear(&offset, sizeof(typedsp));
00378 return insertmorend(father, &offset, origin, width, infoptr, index);
00379 }
00380
00387 void
00388 insertnd(
00389 Session *sess,
00390 typecuc *fullcrumptr,
00391 typewid *origin,
00392 typewid *width,
00393 type2dbottomcruminfo *infoptr,
00394 int index)
00395
00396
00397 {
00398 int bothertorecombine = 0;
00399 int newdiff;
00400
00401 int olddiff = widdiffs(fullcrumptr);
00402 int oldheight = fullcrumptr->height;
00403
00404 if (iszerotumbler(&width->dsas[index]))
00405 assert(0);
00406
00407 Tumbler oldwid;
00408 tumblercopy(&fullcrumptr->cwid.dsas[V], &oldwid);
00409
00410 switch (fullcrumptr->cenftype) {
00411 case POOM:
00412 makegappm(sess, fullcrumptr, origin, width);
00413 checkspecandstringbefore();
00414 setwispupwards(fullcrumptr, 0);
00415
00416 bothertorecombine = doinsertnd(fullcrumptr, origin, width, infoptr, index);
00417 setwispupwards(fullcrumptr, 1);
00418 break;
00419
00420 case SPAN:
00421 bothertorecombine = doinsertnd(fullcrumptr, origin, width, infoptr, index);
00422 setwispupwards(fullcrumptr, 1);
00423 break;
00424
00425 default:
00426 assert(0);
00427 }
00428
00429 if (bothertorecombine || (fullcrumptr->height != oldheight))
00430 recombine(fullcrumptr);
00431
00432 newdiff = widdiffs(fullcrumptr);
00433 }