FORM v5.0.1-33-gdf7fc94
index.c
Go to the documentation of this file.
1
8/* #[ License : */
9/*
10 * Copyright (C) 1984-2026 J.A.M. Vermaseren
11 * When using this file you are requested to refer to the publication
12 * J.A.M.Vermaseren "New features of FORM" math-ph/0010025
13 * This is considered a matter of courtesy as the development was paid
14 * for by FOM the Dutch physics granting agency and we would like to
15 * be able to track its scientific use to convince FOM of its value
16 * for the community.
17 *
18 * This file is part of FORM.
19 *
20 * FORM is free software: you can redistribute it and/or modify it under the
21 * terms of the GNU General Public License as published by the Free Software
22 * Foundation, either version 3 of the License, or (at your option) any later
23 * version.
24 *
25 * FORM is distributed in the hope that it will be useful, but WITHOUT ANY
26 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
27 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
28 * details.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with FORM. If not, see <http://www.gnu.org/licenses/>.
32 */
33/* #] License : */
34
35/*
36 #[ Includes : index.c
37*/
38
39#include "form3.h"
40
41/*
42 #] Includes :
43 #[ syntax and use :
44
45 The indexing of brackets is not automatic! It should only be used
46 when one intends to use the contents of individual brackets.
47 This is done with the addition of a + sign to the bracket statement:
48 B+ a,b,c; or AB+ a,b,c;
49 It does require resources! The index is kept in memory and is removed
50 once the expression is treated and passed on to the output with different
51 or no brackets.
52 The index is limited to a given amount of space. Hence if there are too
53 many brackets we will skip some in the index. Skipping goes by space
54 occupied by the contents. We take the two adjacent bracket(s) with the
55 least space together and represent them by the first one only. This gives
56 a new spot.
57 The expression struct has two pointers:
58 bracketinfo for using.
59 newbracketinfo for making new index.
60
61 #] syntax and use :
62 #[ FindBracket :
63*/
64
65POSITION *FindBracket(WORD nexp, WORD *bracket)
66{
67 GETIDENTITY
68 BRACKETINDEX *bi;
69 BRACKETINFO *bracketinfo;
70 EXPRESSIONS e = &(Expressions[nexp]);
71 LONG hi, low, med;
72 int i;
73 WORD oldsorttype = AR.SortType, *t1, *t2, j, bsize, *term, *p, *pstop, *pp;
74 WORD *tstop, *cp, a[4], *bracketh;
75 FILEHANDLE *fi;
76 POSITION auxpos, toppos;
77 switch ( e->status ) {
78 case UNHIDELEXPRESSION:
79 case UNHIDEGEXPRESSION:
80 case DROPHLEXPRESSION:
81 case DROPHGEXPRESSION:
82 case HIDDENLEXPRESSION:
83 case HIDDENGEXPRESSION:
84 fi = AR.hidefile;
85 break;
86 default:
87 fi = AR.infile;
88 break;
89 }
90 if ( AT.bracketinfo ) bracketinfo = AT.bracketinfo;
91 else bracketinfo = e->bracketinfo;
92 hi = bracketinfo->indexfill; low = 0;
93 if ( hi <= 0 ) return(0);
94/*
95 The next code is needed for a problem with sorting when there are
96 only functions outside the bracket. This gives ordinarily the wrong
97 sorting. We solve that by taking HAAKJE along with the outside while
98 running the Compare. But this means that we need to copy bracket.
99*/
100 bracketh = TermMalloc("FindBracket");
101 i = *bracket; p = bracket; pp = bracketh; NCOPY(pp,p,i)
102 pp -= 3; *pp++ = HAAKJE; *pp++ = 3; *pp++ = 0; *pp++ = 1; *pp++ = 1; *pp++ = 3;
103 *bracketh += 3;
104
105 AT.fromindex = 1;
106 AR.SortType = bracketinfo->SortType;
107 bi = bracketinfo->indexbuffer + hi - 1;
108 if ( *bracketh == 7 ) {
109 if ( bracketinfo->bracketbuffer[bi->bracket] == 7 ) i = 0;
110 else i = -1;
111 }
112 else if ( bracketinfo->bracketbuffer[bi->bracket] == 7 ) i = 1;
113 else i = CompareTerms(BHEAD bracketh,bracketinfo->bracketbuffer+bi->bracket,0);
114 if ( i < 0 ) {
115 AR.SortType = oldsorttype;
116 AT.fromindex = 0;
117 TermFree(bracketh,"FindBracket");
118 return(0);
119 }
120 else if ( i == 0 ) med = hi-1;
121 else {
122 for (;;) {
123 med = (hi+low)/2;
124 bi = bracketinfo->indexbuffer + med;
125 if ( *bracketh == 7 ) {
126 if ( bracketinfo->bracketbuffer[bi->bracket] == 7 ) i = 0;
127 else i = -1;
128 }
129 else if ( bracketinfo->bracketbuffer[bi->bracket] == 7 ) i = 1;
130 else i = CompareTerms(BHEAD bracketh,bracketinfo->bracketbuffer+bi->bracket,0);
131 if ( i == 0 ) { break; }
132 if ( i > 0 ) {
133 if ( low == med ) { /* no occurrence */
134 AR.SortType = oldsorttype;
135 AT.fromindex = 0;
136 TermFree(bracketh,"FindBracket");
137 return(0);
138 }
139 hi = med;
140 }
141 else if ( i < 0 ) {
142 if ( low == med ) break;
143 low = med;
144 }
145 }}
146/*
147 The bracket is now either bi itself or between bi and the next one
148 or it is not present at all.
149*/
150 AN.theposition = AS.OldOnFile[nexp];
151 ADD2POS(AN.theposition,bi->start);
152/*
153 The seek will have to move closer to the actual read so that we
154 can place a lock around the two.
155 if ( fi->handle >= 0 ) SeekFile(fi->handle,&AN.theposition,SEEK_SET);
156 else SetScratch(fi,&AN.theposition);
157*/
158/*
159 Put the bracket in the compress buffer as if it were the last term read.
160 Have a look at AR.CompressPointer. (set it right)
161*/
162 term = AT.WorkPointer;
163 t1 = bracketinfo->bracketbuffer+bi->bracket;
164 j = *t1;
165/*
166 Note that in the bracketbuffer, the bracket sits with HAAKJE.
167
168 The next is (hopefully) a bug fix. Originally the code read bsize = j
169 but that overcounts one. We have the part outside the bracket and the
170 coefficient which is 1,1,3. But we also have the length indicator.
171 Where we use the variable bsize we do not include the length indicator,
172 and we have the part outside plus 7,3,0 which is also three words.
173*/
174 bsize = j-1;
175 t2 = AR.CompressPointer;
176 NCOPY(t2,t1,j)
177 if ( i == 0 ) { /* We found the proper bracket already */
178 AR.SortType = oldsorttype;
179 AT.fromindex = 0;
180 TermFree(bracketh,"FindBracket");
181 return(&AN.theposition);
182 }
183/*
184 Here we have to skip to the bracket if it exists (!)
185 Let us first look whether the expression is in memory.
186 If not we have to make a buffer to increase speed..
187*/
188 if ( fi->handle < 0 ) {
189 p = (WORD *)((UBYTE *)(fi->PObuffer)
190 + BASEPOSITION(AS.OldOnFile[nexp])
191 + BASEPOSITION(bi->start));
192 pstop = (WORD *)((UBYTE *)(fi->PObuffer)
193 + BASEPOSITION(AS.OldOnFile[nexp])
194 + BASEPOSITION(bi->next));
195 while ( p < pstop ) {
196/*
197 Check now: if size or part from previous term < size of bracket
198 we have to setup the bracket again and test.
199 Otherwise, skip immediately to the next term.
200*/
201 if ( *p <= -bsize ) { /* no change of bracket */
202 p++; p += *p + 1;
203 }
204 else if ( *p < 0 ) { /* changes bracket */
205 pp = p;
206 t2 = AR.CompressPointer;
207 t1 = t2 - *p++ + 1;
208 j = *p++;
209 NCOPY(t1,p,j)
210 t2++; while ( *t2 != HAAKJE ) t2 += t2[1];
211 t2 += t2[1];
212 a[1] = t2[0]; a[2] = t2[1]; a[3] = t2[2];
213 *t2++ = 1; *t2++ = 1; *t2++ = 3;
214 *AR.CompressPointer = t2 - AR.CompressPointer;
215 bsize = *AR.CompressPointer - 1;
216 if ( *bracketh == 7 ) {
217 if ( AR.CompressPointer[0] == 7 ) i = 0;
218 else i = -1;
219 }
220 else if ( AR.CompressPointer[0] == 7 ) i = 1;
221 else i = CompareTerms(BHEAD bracketh,AR.CompressPointer,0);
222 t2[-3] = a[1]; t2[-2] = a[2]; t2[-1] = a[3];
223 if ( i == 0 ) {
224 SETBASEPOSITION(AN.theposition,(pp-fi->PObuffer)*sizeof(WORD));
225 fi->POfill = pp;
226 goto found;
227 }
228 if ( i > 0 ) break; /* passed what was possible */
229 }
230 else { /* no compression. We have to check! */
231 WORD *oldworkpointer = AT.WorkPointer, *t3, *t4;
232 t2 = p + 1; while ( *t2 != HAAKJE ) t2 += t2[1];
233 t2 += t2[1];
234/*
235 Here we need to copy the term. Modifying has proven to
236 be NOT threadsafe.
237*/
238 t3 = oldworkpointer; t4 = p;
239 while ( t4 < t2 ) *t3++ = *t4++;
240 *t3++ = 1; *t3++ = 1; *t3++ = 3;
241 *oldworkpointer = t3 - oldworkpointer;
242 bsize = *oldworkpointer - 1;
243 AT.WorkPointer = t3;
244 t3 = oldworkpointer;
245 if ( *bracketh == 7 ) {
246 if ( t3[0] == 7 ) i = 0;
247 else i = -1;
248 }
249 else if ( t3[0] == 7 ) i = 1;
250 else {
251 i = CompareTerms(BHEAD bracketh,t3,0);
252 }
253 AT.WorkPointer = oldworkpointer;
254 if ( i == 0 ) {
255 SETBASEPOSITION(AN.theposition,(p-fi->PObuffer)*sizeof(WORD));
256 fi->POfill = p;
257 goto found;
258 }
259 if ( i > 0 ) break; /* passed what was possible */
260 p += *p;
261 }
262 }
263 AR.SortType = oldsorttype;
264 AT.fromindex = 0;
265 TermFree(bracketh,"FindBracket");
266 return(0); /* Bracket does not exist */
267 }
268 else {
269/*
270 In this case we can work with the old representation without HAAKJE.
271 We stop searching when we reach toppos and we do not call Compare.
272*/
273 toppos = AS.OldOnFile[nexp];
274 ADD2POS(toppos,bi->next);
275 cp = AR.CompressPointer;
276 for(;;) {
277 auxpos = AN.theposition;
278 GetOneTerm(BHEAD term,fi,&auxpos,0);
279 if ( *term == 0 ) {
280 AR.SortType = oldsorttype;
281 AT.fromindex = 0;
282 return(0); /* Bracket does not exist */
283 }
284 tstop = term + *term;
285 tstop -= ABS(tstop[-1]);
286 t1 = term + 1;
287 while ( *t1 != HAAKJE && t1 < tstop ) t1 += t1[1];
288 i = *bracket-4;
289 if ( t1-term == *bracket-3 ) {
290 t1 = term + 1; t2 = bracket+1;
291 while ( i > 0 && *t1 == *t2 ) { t1++; t2++; i--; }
292 if ( i <= 0 ) {
293 AR.CompressPointer = cp;
294 goto found;
295 }
296 }
297 AR.CompressPointer = cp;
298 AN.theposition = auxpos;
299/*
300 Now check whether we passed the 'point'
301*/
302 if ( ISGEPOS(AN.theposition,toppos) ) {
303 AR.SortType = oldsorttype;
304 AR.CompressPointer = cp;
305 AT.fromindex = 0;
306 TermFree(bracketh,"FindBracket");
307 return(0); /* Bracket does not exist */
308 }
309 }
310 }
311found:
312 AR.SortType = oldsorttype;
313 AT.fromindex = 0;
314 TermFree(bracketh,"FindBracket");
315 return(&AN.theposition);
316}
317
318/*
319 #] FindBracket :
320 #[ PutBracketInIndex :
321
322 Call via
323 if ( AR.BracketOn ) PutBracketInIndex(BHEAD term);
324
325 This means that there should be a bracket somewhere
326 Note that the brackets come in in proper order.
327
328 DON'T forget AR.SortType to be put into e->bracketinfo->SortType
329*/
330
331void PutBracketInIndex(PHEAD WORD *term, POSITION *newpos)
332{
333 GETBIDENTITY
334 BRACKETINDEX *bi, *b1, *b2, *b3;
335 BRACKETINFO *b;
336 POSITION thepos;
337 EXPRESSIONS e = Expressions + AR.CurExpr;
338 LONG hi, i, average;
339 WORD *t, *tstop, *t1, *t2, *oldt, oldsize, a[4];
340 if ( ( b = e->newbracketinfo ) == 0 ) return;
341 DIFPOS(thepos,*newpos,e->onfile);
342 tstop = term + *term;
343 tstop -= ABS(tstop[-1]);
344 t = term+1;
345 while ( *t != HAAKJE && t < tstop ) t += t[1];
346 if ( t >= tstop ) return; /* no ticket, no laundry */
347 t += t[1]; /* include HAAKJE for the sorting */
348 a[0] = t[0]; a[1] = t[1]; a[2] = t[2];
349 oldt = t; oldsize = *term; *t++ = 1; *t++ = 1; *t++ = 3;
350 *term = t - term;
351 AT.fromindex = 1;
352/*
353 Check now with the last bracket in the buffer.
354 If it is the same we can abort.
355*/
356 hi = b->indexfill;
357 if ( hi > 0 ) {
358 bi = b->indexbuffer + hi - 1;
359 bi->next = thepos;
360 if ( *term == 7 ) {
361 if ( b->bracketbuffer[bi->bracket] == 7 ) i = 0;
362 else i = -1;
363 }
364 else if ( b->bracketbuffer[bi->bracket] == 7 ) i = 1;
365 else i = CompareTerms(BHEAD term,b->bracketbuffer+bi->bracket,0);
366 if ( i == 0 ) { /* still the same bracket */
367 bi->termsinbracket++;
368 goto bracketdone;
369 }
370 if ( i > 0 ) { /* We have a problem */
371/*
372 There is a special case in which we have only functions and
373 term is contained completely in the bracket
374*/
375/*
376 t = term + 1;
377 tstop = term + *term - 3;
378 while ( t < tstop && *t > HAAKJE ) t += t[1];
379 if ( t < tstop ) goto problems;
380*/
381 for ( i = 1; i < *term - 3; i++ ) {
382 if ( term[i] != b->bracketbuffer[bi->bracket+i] ) break;
383 }
384 if ( i < *term - 3 ) {
385/*
386problems:;
387*/
388/* INTERNAL_ERROR_EXCL_START */
389 *term = oldsize; oldt[0] = a[0]; oldt[1] = a[1]; oldt[2] = a[2];
390 MLOCK(ErrorMessageLock);
391 MesPrint("!>Error! Illegal bracket sequence detected in PutBracketInIndex");
392#ifdef WITHPTHREADS
393 MesPrint("Worker = %w");
394#endif
395 PrintTerm(term,"term into index");
396 PrintTerm(b->bracketbuffer+bi->bracket,"Last in index");
397 MUNLOCK(ErrorMessageLock);
398 AT.fromindex = 0;
399 Terminate(-1);
400/* INTERNAL_ERROR_EXCL_STOP */
401 }
402 i = -1;
403 }
404 }
405/*
406 If there is room for more brackets, we add this one.
407*/
408 if ( b->bracketfill+*term >= b->bracketbuffersize
409 && ( b->bracketbuffersize < AM.MaxBracketBufferSize
410 || ( e->vflags & ISFACTORIZED ) != 0 ) ) {
411/*
412 Enlarge bracket buffer
413*/
414 WORD *oldbracketbuffer = b->bracketbuffer;
415 i = MaX(b->bracketbuffersize * 2, b->bracketfill+*term+1);
416 if ( i > AM.MaxBracketBufferSize && ( e->vflags & ISFACTORIZED ) == 0 )
417 i = AM.MaxBracketBufferSize;
418 if ( i > b->bracketfill+*term ) {
419 b->bracketbuffersize = i;
420 b->bracketbuffer = (WORD *)Malloc1(b->bracketbuffersize*sizeof(WORD),
421 "new bracket buffer");
422 t1 = b->bracketbuffer; t2 = oldbracketbuffer;
423 i = b->bracketfill;
424 NCOPY(t1,t2,i)
425 if ( oldbracketbuffer ) M_free(oldbracketbuffer,"old bracket buffer");
426 }
427 }
428 if ( b->bracketfill+*term < b->bracketbuffersize ) {
429 if ( b->indexfill >= b->indexbuffersize ) {
430/*
431 Enlarge index
432*/
433 BRACKETINDEX *oldindexbuffer = b->indexbuffer;
434 b->indexbuffersize *= 2;
436 Malloc1(b->indexbuffersize*sizeof(BRACKETINDEX),"new bracket index");
437 b1 = b->indexbuffer; b2 = oldindexbuffer;
438 i = b->indexfill;
439 NCOPY(b1,b2,i)
440 if ( oldindexbuffer ) M_free(oldindexbuffer,"old bracket index");
441 }
442 }
443 else {
444/*
445 We have too many brackets in the buffer. Try to improve.
446 This is the interesting algorithm. We try to eliminate about 1/4 to
447 1/2 of the brackets from the index. This should be done by size of
448 the bracket contents to make the searching as fast as possible.
449 But! Do not touch the last bracket.
450 Note that we are always filling from the back.
451 Algorithm: Throw away every second bracket, unless b1+b2 is much longer
452 than average. How much is something we can tune.
453*/
454 average = DIVPOS(thepos,b->indexfill+1);
455 if ( average <= 0 ) {
456 MLOCK(ErrorMessageLock);
457 MesPrint("Problems with bracket buffer. Increase MaxBracketBufferSize in form.set");
458 MesPrint("Current size is %l",AM.MaxBracketBufferSize*sizeof(WORD));
459 MUNLOCK(ErrorMessageLock);
460 Terminate(-1);
461 }
462 average *= 4; /* 2*2: one 2 for much longer, one 2 because we have pairs */
463 t2 = b->bracketbuffer;
464 b3 = b1 = b->indexbuffer;
465 bi = b->indexbuffer + b->indexfill;
466 b2 = b1+1;
467 while ( b2+2 < bi ) {
468 if ( DIFBASE(b2->next,b1->start) > average ) {
469 t1 = b->bracketbuffer + b1->bracket;
470 b1->bracket = t2 - b->bracketbuffer;
471 i = *t1; NCOPY(t2,t1,i)
472 *b3++ = *b1;
473 t1 = b->bracketbuffer + b2->bracket;
474 b2->bracket = t2 - b->bracketbuffer;
475 i = *t1; NCOPY(t2,t1,i)
476 *b3++ = *b2;
477 if ( b3 <= b1 ) {
478 PUTZERO(b1->start);
479 PUTZERO(b1->next);
480 b1->bracket = 0;
481 b1->termsinbracket = 0;
482 }
483 if ( b3 <= b2 ) {
484 PUTZERO(b2->start);
485 PUTZERO(b2->next);
486 b2->bracket = 0;
487 b2->termsinbracket = 0;
488 }
489 }
490 else {
491 t1 = b->bracketbuffer + b1->bracket;
492 b1->bracket = t2 - b->bracketbuffer;
493 i = *t1; NCOPY(t2,t1,i)
494 b1->next = b2->next;
495 b1->termsinbracket += b2->termsinbracket;
496 *b3++ = *b1;
497 if ( b3 <= b1 ) {
498 PUTZERO(b1->start);
499 PUTZERO(b1->next);
500 b1->bracket = 0;
501 b1->termsinbracket = 0;
502 }
503 PUTZERO(b2->start);
504 PUTZERO(b2->next);
505 b2->bracket = 0;
506 b2->termsinbracket = 0;
507 }
508 b1 += 2; b2 += 2;
509 }
510 while ( b1 < bi ) {
511 t1 = b->bracketbuffer + b1->bracket;
512 b1->bracket = t2 - b->bracketbuffer;
513 i = *t1; NCOPY(t2,t1,i)
514 *b3++ = *b1;
515 if ( b3 <= b1 ) {
516 PUTZERO(b1->start);
517 PUTZERO(b1->next);
518 b1->bracket = 0;
519 b1->termsinbracket = 0;
520 }
521 b1++;
522 }
523 b->indexfill = b3 - b->indexbuffer;
524 b->bracketfill = t2 - b->bracketbuffer;
525 }
526 bi = b->indexbuffer + b->indexfill;
527 b->indexfill++;
528 bi->bracket = b->bracketfill;
529 bi->start = thepos;
530 bi->next = thepos;
531 bi->termsinbracket = 1;
532/*
533 Copy the bracket into the buffer
534*/
535 t1 = term; t2 = b->bracketbuffer + bi->bracket; i = *t1;
536 b->bracketfill += i;
537 NCOPY(t2,t1,i)
538bracketdone:
539 *term = oldsize; oldt[0] = a[0]; oldt[1] = a[1]; oldt[2] = a[2];
540 AT.fromindex = 0;
541}
542
543/*
544 #] PutBracketInIndex :
545 #[ ClearBracketIndex :
546*/
547
548void ClearBracketIndex(WORD numexp)
549{
550 BRACKETINFO *b;
551 if ( numexp >= 0 ) {
552 b = Expressions[numexp].bracketinfo;
553 Expressions[numexp].bracketinfo = 0;
554 }
555 else if ( numexp == -1 ) {
556 GETIDENTITY
557 b = AT.bracketinfo;
558 AT.bracketinfo = 0;
559 }
560 else {
561 numexp = -numexp-2;
562 b = Expressions[numexp].newbracketinfo;
563 Expressions[numexp].newbracketinfo = 0;
564 }
565 if ( b == 0 ) return;
566 b->indexfill = b->indexbuffersize = 0;
567 b->bracketfill = b->bracketbuffersize = 0;
568 M_free(b->bracketbuffer,"ClearBracketBuffer");
569 M_free(b->indexbuffer,"ClearIndexBuffer");
570 M_free(b,"BracketInfo");
571}
572
573/*
574 #] ClearBracketIndex :
575 #[ OpenBracketIndex :
576
577 Note: This routine is thread-safe
578*/
579
580void OpenBracketIndex(WORD nexpr)
581{
582 EXPRESSIONS e = Expressions + nexpr;
583 BRACKETINFO *bi;
584 LONG i;
585 bi = (BRACKETINFO *)Malloc1(sizeof(BRACKETINFO),"BracketInfo");
586 e->newbracketinfo = bi;
587/*
588 i = 20*AM.MaxTer/sizeof(WORD);
589 if ( i < 1000 ) i = 1000;
590*/
591 i = 2000;
592 bi->bracketbuffer = (WORD *)Malloc1(i*sizeof(WORD),"Bracket Buffer");
593 bi->bracketbuffersize = i;
594 bi->bracketfill = 0;
595 i = 50;
596 bi->indexbuffer = (BRACKETINDEX *)Malloc1(i*sizeof(BRACKETINDEX),"Bracket Index");
597 bi->indexbuffersize = i;
598 bi->indexfill = 0;
599 bi->SortType = AC.SortType;
600}
601
602/*
603 #] OpenBracketIndex :
604 #[ PutInside :
605
606 Puts a term, or a bracket determined part of a term inside a function.
607
608 AT.WorkPointer points at term+*term
609*/
610
611int PutInside(PHEAD WORD *term, WORD *code)
612{
613 WORD *from, *to, *oldbuf, *tStop, *t, *tt, oldon, oldact, inc, argsize, *termout;
614 int i, ii, error;
615
616 if ( code[1] == 4 && ( code[2] == 0 || code[2] == 1 ) ) {
617/*
618 Put all inside. Move the term by 1+FUNHEAD+ARGHEAD
619*/
620 from = term+*term; to = from+1+ARGHEAD+FUNHEAD; i = ii = *term;
621 to[0] = 1; to[1] = 1; to[2] = 3;
622 while ( --i >= 0 ) *--to = *--from;
623 to = term;
624 *to++ = term[0]+4+ARGHEAD+FUNHEAD;
625 *to++ = code[3];
626 *to++ = ii+FUNHEAD+ARGHEAD;
627 *to++ = 1; /* set dirty flags, because there could be a fast notation */
628 FILLFUN3(to)
629 *to++ = ii+ARGHEAD;
630 *to++ = 1;
631 FILLARG(to)
632 return(0);
633 }
634/*
635 First we save the old bracket variables. Then we set variables to
636 influence the PutBracket routine and call it.
637 After that we set the values back and sort out the results by placing the
638 inside of the bracket inside the function.
639*/
640 termout = AT.WorkPointer;
641 oldbuf = AT.BrackBuf;
642 oldon = AR.BracketOn;
643 oldact = AT.PolyAct;
644 AR.BracketOn = -code[2];
645 AT.BrackBuf = code+4;
646 AT.PolyAct = 0;
647 error = PutBracket(BHEAD term);
648 AT.PolyAct = oldact;
649 AT.BrackBuf = oldbuf;
650 AR.BracketOn = oldon;
651 if ( error ) return(error);
652 i = *termout; from = termout; to = term;
653 NCOPY(to,from,i);
654 tStop = term +*term; tStop -= tStop[-1];
655 t = term+1;
656 while ( t < tStop && *t != HAAKJE ) t += t[1];
657 from = term + *term;
658 inc = FUNHEAD+ARGHEAD-t[1]+1;
659 tt = t + t[1];
660 argsize = from-tt+1;
661 to = from + inc;
662 to[0] = 1;
663 to[1] = 1;
664 to[2] = 3;
665 while ( from > tt ) *--to = *--from;
666 *--to = argsize;
667 *t++ = code[3];
668 *t++ = argsize+FUNHEAD+ARGHEAD;
669 *t++ = 1;
670 FILLFUN3(t);
671 *t++ = argsize+ARGHEAD;
672 *t++ = 1;
673 FILLARG(t);
674 *term += inc+3;
675 AT.WorkPointer = term+*term;
676 if ( Normalize(BHEAD term) ) error = 1;
677 return(error);
678}
679
680/*
681 #] PutInside :
682*/
683
684/*
685 The next routines are for indexing the local output files in a parallel
686 sort. This indexing is needed to get a fast determination of the
687 splitting terms needed to divide the terms evenly over the processors.
688 Actually this method works well for ParFORM, but may not work well
689 for TFORM.
690
691 #[ PutTermInIndex :
692
693 Puts a term in the term index.
694 Action:
695 if the index hasn't reached its full size
696 if there is room, put the term
697 if there is no room: extend the buffer, put the term
698 else
699 check if the last term has a number of the type skip*m+1
700 if no, overwrite the last term
701 if yes, check whether there is room for one more term
702 yes: add the term
703 no: drop all even terms, compress the list,
704 multiply skip by 2, and add this term.
705
706int PutTermInIndex(WORD *term,POSITION *position)
707{
708 return(0);
709}
710
711 #] PutTermInIndex :
712*/
BRACKETINDEX * indexbuffer
Definition structs.h:323
WORD * bracketbuffer
Definition structs.h:324
WORD SortType
Definition structs.h:329
int handle
Definition structs.h:709