• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vermaseren / form / 9364948935

04 Jun 2024 09:49AM UTC coverage: 49.979% (-0.02%) from 49.999%
9364948935

Pull #526

github

web-flow
Merge 7062bd769 into 83e3d4185
Pull Request #526: RFC: better debugging

52 of 415 new or added lines in 46 files covered. (12.53%)

32 existing lines in 2 files now uncovered.

41391 of 82816 relevant lines covered (49.98%)

878690.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

48.96
/sources/index.c
1
/** @file index.c
2
 * 
3
 *  The routines that deal with bracket indexing
4
 *        It creates the bracket index and it can find the brackets using
5
 *        the index.
6
 */
7

8
/* #[ License : */
9
/*
10
 *   Copyright (C) 1984-2023 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

65
POSITION *FindBracket(WORD nexp, WORD *bracket)
30,109✔
66
{
67
        GETIDENTITY
20,060✔
68
        BRACKETINDEX *bi;
30,109✔
69
        BRACKETINFO *bracketinfo;
30,109✔
70
        EXPRESSIONS e = &(Expressions[nexp]);
30,109✔
71
        LONG hi, low, med;
30,109✔
72
        int i;
30,109✔
73
        WORD oldsorttype = AR.SortType, *t1, *t2, j, bsize, *term, *p, *pstop, *pp;
30,109✔
74
        WORD *tstop, *cp, a[4], *bracketh;
30,109✔
75
        FILEHANDLE *fi;
30,109✔
76
        POSITION auxpos, toppos;
30,109✔
77
        switch ( e->status ) {
30,109✔
78
                case UNHIDELEXPRESSION:
40✔
79
                case UNHIDEGEXPRESSION:
80
                case DROPHLEXPRESSION:
81
                case DROPHGEXPRESSION:
82
                case HIDDENLEXPRESSION:
83
                case HIDDENGEXPRESSION:
84
                        fi = AR.hidefile;
40✔
85
                        break;
40✔
86
                default:
30,069✔
87
                        fi = AR.infile;
30,069✔
88
                        break;
30,069✔
89
        }
90
        if ( AT.bracketinfo ) bracketinfo = AT.bracketinfo;
30,109✔
91
        else                  bracketinfo = e->bracketinfo;
30,073✔
92
        hi = bracketinfo->indexfill; low = 0;
30,109✔
93
        if ( hi <= 0 ) return(0);
30,109✔
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");
30,109✔
101
        i = *bracket; p = bracket; pp = bracketh; NCOPY(pp,p,i)
301,061✔
102
        pp -= 3; *pp++ = HAAKJE; *pp++ = 3; *pp++ = 0; *pp++ = 1; *pp++ = 1; *pp++ = 3;
30,109✔
103
        *bracketh += 3;
30,109✔
104

105
        AT.fromindex = 1;
30,109✔
106
        AR.SortType = bracketinfo->SortType;
30,109✔
107
        bi = bracketinfo->indexbuffer + hi - 1;
30,109✔
108
        if ( *bracketh == 7 ) {
30,109✔
109
                if ( bracketinfo->bracketbuffer[bi->bracket] == 7 ) i = 0;
4✔
110
                else i = -1;
111
        }
112
        else if ( bracketinfo->bracketbuffer[bi->bracket] == 7 ) i = 1;
30,105✔
113
        else i = CompareTerms(BHEAD bracketh,bracketinfo->bracketbuffer+bi->bracket,0);
30,069✔
114
        if ( i < 0 ) {
30,069✔
115
                AR.SortType = oldsorttype;
×
116
                AT.fromindex = 0;
×
117
                TermFree(bracketh,"FindBracket");
×
118
                return(0);
×
119
        }
120
        else if ( i == 0 ) med = hi-1;
30,109✔
121
        else {
122
                for (;;) {
172,054✔
123
                med = (hi+low)/2;
172,054✔
124
                bi = bracketinfo->indexbuffer + med;
172,054✔
125
                if ( *bracketh == 7 ) {
172,054✔
126
                        if ( bracketinfo->bracketbuffer[bi->bracket] == 7 ) i = 0;
×
127
                        else i = -1;
128
                }
129
                else if ( bracketinfo->bracketbuffer[bi->bracket] == 7 ) i = 1;
172,054✔
130
                else i = CompareTerms(BHEAD bracketh,bracketinfo->bracketbuffer+bi->bracket,0);
172,054✔
131
                if ( i == 0 ) { break; }
172,054✔
132
                if ( i > 0 ) {
142,284✔
133
                        if ( low == med ) { /* no occurrence */
66,956✔
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 ) {
75,328✔
142
                        if ( low == med ) break;
75,328✔
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];
30,109✔
151
        ADD2POS(AN.theposition,bi->start);
30,109✔
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;
30,109✔
163
        t1 = bracketinfo->bracketbuffer+bi->bracket;
30,109✔
164
        j = *t1;
30,109✔
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;
30,109✔
175
        t2 = AR.CompressPointer;
30,109✔
176
        NCOPY(t2,t1,j)
391,388✔
177
        if ( i == 0 ) {        /* We found the proper bracket already */
30,109✔
178
                AR.SortType = oldsorttype;
30,109✔
179
                AT.fromindex = 0;
30,109✔
180
                TermFree(bracketh,"FindBracket");
30,109✔
181
                return(&AN.theposition);
30,109✔
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
        }
311
found:
×
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

331
VOID PutBracketInIndex(PHEAD WORD *term, POSITION *newpos)
31,684✔
332
{
333
        GETBIDENTITY
334
        BRACKETINDEX *bi, *b1, *b2, *b3;
31,684✔
335
        BRACKETINFO *b;
31,684✔
336
        POSITION thepos;
31,684✔
337
        EXPRESSIONS e = Expressions + AR.CurExpr;
31,684✔
338
        LONG hi, i, average;
31,684✔
339
        WORD *t, *tstop, *t1, *t2, *oldt, oldsize, a[4];
31,684✔
340
        if ( ( b = e->newbracketinfo ) == 0 ) return;
31,684✔
341
        DIFPOS(thepos,*newpos,e->onfile);
31,684✔
342
        tstop = term + *term;
31,684✔
343
        tstop -= ABS(tstop[-1]);
31,684✔
344
        t = term+1;
31,684✔
345
        while ( *t != HAAKJE && t < tstop ) t += t[1];
63,380✔
346
        if ( t >= tstop ) return; /* no ticket, no laundry */
31,684✔
347
        t += t[1];  /* include HAAKJE for the sorting */
31,684✔
348
        a[0] = t[0]; a[1] = t[1]; a[2] = t[2];
31,684✔
349
        oldt = t; oldsize = *term; *t++ = 1; *t++ = 1; *t++ = 3;
31,684✔
350
        *term = t - term;
31,684✔
351
        AT.fromindex = 1;
31,684✔
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;
31,684✔
357
        if ( hi > 0 ) {
31,684✔
358
                bi = b->indexbuffer + hi - 1;
31,545✔
359
                bi->next = thepos;
31,545✔
360
                if ( *term == 7 ) {
31,545✔
361
                        if ( b->bracketbuffer[bi->bracket] == 7 ) i = 0;
52✔
362
                        else i = -1;
363
                }
364
                else if ( b->bracketbuffer[bi->bracket] == 7 ) i = 1;
31,493✔
365
                else i = CompareTerms(BHEAD term,b->bracketbuffer+bi->bracket,0);
31,493✔
366
                if ( i == 0 ) {        /* still the same bracket */
31,493✔
367
                        bi->termsinbracket++;
30,696✔
368
                        goto bracketdone;
30,696✔
369
                }
370
                if ( i > 0 ) { /* We have a problem */
849✔
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
/*
386
problems:;
387
*/
388
                                *term = oldsize; oldt[0] = a[0]; oldt[1] = a[1]; oldt[2] = a[2];
×
389
                                MLOCK(ErrorMessageLock);
×
390
                                MesPrint("Error!!!! Illegal bracket sequence detected in PutBracketInIndex");
×
391
#ifdef WITHPTHREADS
392
                                MesPrint("Worker = %w");
393
#endif
394
                                PrintTerm(term,"term into index");
×
395
                                PrintTerm(b->bracketbuffer+bi->bracket,"Last in index");
×
396
                                MUNLOCK(ErrorMessageLock);
×
397
                                AT.fromindex = 0;
×
NEW
398
                                TERMINATE(-1);
×
399
                        }
400
                        i = -1;
988✔
401
                }
402
        }
403
/*
404
        If there is room for more brackets, we add this one.
405
*/
406
        if ( b->bracketfill+*term >= b->bracketbuffersize
988✔
407
        && ( b->bracketbuffersize < AM.MaxBracketBufferSize
×
408
        || ( e->vflags & ISFACTORIZED ) != 0 ) ) {
×
409
/*
410
                Enlarge bracket buffer
411
*/
412
                WORD *oldbracketbuffer = b->bracketbuffer;
×
413
                i = MaX(b->bracketbuffersize * 2, b->bracketfill+*term+1);
×
414
                if ( i > AM.MaxBracketBufferSize && ( e->vflags & ISFACTORIZED ) == 0 )
×
415
                                i = AM.MaxBracketBufferSize;
×
416
                if ( i > b->bracketfill+*term ) {
×
417
                        b->bracketbuffersize = i;
×
418
                        b->bracketbuffer = (WORD *)Malloc1(b->bracketbuffersize*sizeof(WORD),
×
419
                                                                "new bracket buffer");
420
                        t1 = b->bracketbuffer; t2 = oldbracketbuffer;
×
421
                        i = b->bracketfill;
×
422
                        NCOPY(t1,t2,i)
×
423
                        if ( oldbracketbuffer ) M_free(oldbracketbuffer,"old bracket buffer");
×
424
                }
425
        }
426
        if ( b->bracketfill+*term < b->bracketbuffersize ) {
988✔
427
                if ( b->indexfill >= b->indexbuffersize ) {
988✔
428
/*
429
                        Enlarge index
430
*/
431
                        BRACKETINDEX *oldindexbuffer = b->indexbuffer;
3✔
432
                        b->indexbuffersize *= 2;
3✔
433
                        b->indexbuffer = (BRACKETINDEX *)
6✔
434
                                Malloc1(b->indexbuffersize*sizeof(BRACKETINDEX),"new bracket index");
3✔
435
                        b1 = b->indexbuffer; b2 = oldindexbuffer;
3✔
436
                        i = b->indexfill;
3✔
437
                        NCOPY(b1,b2,i)
153✔
438
                        if ( oldindexbuffer ) M_free(oldindexbuffer,"old bracket index");
3✔
439
                }
440
        }
441
        else {
442
/*
443
                We have too many brackets in the buffer. Try to improve.
444
                This is the interesting algorithm. We try to eliminate about 1/4 to
445
                1/2 of the brackets from the index. This should be done by size of
446
                the bracket contents to make the searching as fast as possible.
447
                But! Do not touch the last bracket.
448
                Note that we are always filling from the back.
449
                Algorithm: Throw away every second bracket, unless b1+b2 is much longer
450
            than average. How much is something we can tune.
451
*/
452
                average = DIVPOS(thepos,b->indexfill+1);
×
453
                if ( average <= 0 ) {
×
454
                        MLOCK(ErrorMessageLock);
×
455
                        MesPrint("Problems with bracket buffer. Increase MaxBracketBufferSize in form.set");
×
456
                        MesPrint("Current size is %l",AM.MaxBracketBufferSize*sizeof(WORD));
×
457
                        MUNLOCK(ErrorMessageLock);
×
NEW
458
                        TERMINATE(-1);
×
459
                }
460
                average *= 4;  /* 2*2: one 2 for much longer, one 2 because we have pairs */
×
461
                t2 = b->bracketbuffer;
×
462
                b3 = b1 = b->indexbuffer;
×
463
                bi = b->indexbuffer + b->indexfill;
×
464
                b2 = b1+1;
×
465
                while ( b2+2 < bi ) {
×
466
                        if ( DIFBASE(b2->next,b1->start) > average ) {
×
467
                                t1 = b->bracketbuffer + b1->bracket;
×
468
                                b1->bracket = t2 - b->bracketbuffer;
×
469
                                i = *t1; NCOPY(t2,t1,i)
×
470
                                *b3++ = *b1;
×
471
                                t1 = b->bracketbuffer + b2->bracket;
×
472
                                b2->bracket = t2 - b->bracketbuffer;
×
473
                                i = *t1; NCOPY(t2,t1,i)
×
474
                                *b3++ = *b2;
×
475
                                if ( b3 <= b1 ) {
×
476
                                        PUTZERO(b1->start);
×
477
                                        PUTZERO(b1->next);
×
478
                                        b1->bracket = 0;
×
479
                                        b1->termsinbracket = 0;
×
480
                                }
481
                                if ( b3 <= b2 ) {
×
482
                                        PUTZERO(b2->start);
×
483
                                        PUTZERO(b2->next);
×
484
                                        b2->bracket = 0;
×
485
                                        b2->termsinbracket = 0;
×
486
                                }
487
                        }
488
                        else {
489
                                t1 = b->bracketbuffer + b1->bracket;
×
490
                                b1->bracket = t2 - b->bracketbuffer;
×
491
                                i = *t1; NCOPY(t2,t1,i)
×
492
                                b1->next = b2->next;
×
493
                                b1->termsinbracket += b2->termsinbracket;
×
494
                                *b3++ = *b1;
×
495
                                if ( b3 <= b1 ) {
×
496
                                        PUTZERO(b1->start);
×
497
                                        PUTZERO(b1->next);
×
498
                                        b1->bracket = 0;
×
499
                                        b1->termsinbracket = 0;
×
500
                                }
501
                                PUTZERO(b2->start);
×
502
                                PUTZERO(b2->next);
×
503
                                b2->bracket = 0;
×
504
                                b2->termsinbracket = 0;
×
505
                        }
506
                        b1 += 2; b2 += 2;
×
507
                }
508
                while ( b1 < bi ) {
×
509
                        t1 = b->bracketbuffer + b1->bracket;
×
510
                        b1->bracket = t2 - b->bracketbuffer;
×
511
                        i = *t1; NCOPY(t2,t1,i)
×
512
                        *b3++ = *b1;
×
513
                        if ( b3 <= b1 ) {
×
514
                                PUTZERO(b1->start);
×
515
                                PUTZERO(b1->next);
×
516
                                b1->bracket = 0;
×
517
                                b1->termsinbracket = 0;
×
518
                        }
519
                        b1++;
×
520
                }
521
                b->indexfill = b3 - b->indexbuffer;
×
522
                b->bracketfill = t2 - b->bracketbuffer;
×
523
        }
524
        bi = b->indexbuffer + b->indexfill;
988✔
525
        b->indexfill++;
988✔
526
        bi->bracket = b->bracketfill;
988✔
527
        bi->start = thepos;
988✔
528
        bi->next = thepos;
988✔
529
        bi->termsinbracket = 1;
988✔
530
/*
531
        Copy the bracket into the buffer
532
*/
533
        t1 = term; t2 = b->bracketbuffer + bi->bracket; i = *t1;
988✔
534
        b->bracketfill += i;
988✔
535
        NCOPY(t2,t1,i)
12,204✔
536
bracketdone:
988✔
537
        *term = oldsize; oldt[0] = a[0]; oldt[1] = a[1]; oldt[2] = a[2];
31,684✔
538
        AT.fromindex = 0;
31,684✔
539
}
540

541
/*
542
          #] PutBracketInIndex : 
543
          #[ ClearBracketIndex :
544
*/
545

546
void ClearBracketIndex(WORD numexp)
17,869✔
547
{
548
        BRACKETINFO *b;
17,869✔
549
        if ( numexp >= 0 ) {
17,869✔
550
                b = Expressions[numexp].bracketinfo;
17,825✔
551
                Expressions[numexp].bracketinfo = 0;
17,825✔
552
        }
553
        else if ( numexp == -1 ) {
44✔
554
                GETIDENTITY
4✔
555
                b = AT.bracketinfo;
8✔
556
                AT.bracketinfo = 0;
8✔
557
        }
558
        else {
559
                numexp = -numexp-2;
36✔
560
                b = Expressions[numexp].newbracketinfo;
36✔
561
                Expressions[numexp].newbracketinfo = 0;
36✔
562
        }
563
        if ( b == 0 ) return;
17,869✔
564
        b->indexfill = b->indexbuffersize = 0;
63✔
565
        b->bracketfill = b->bracketbuffersize = 0;
63✔
566
        M_free(b->bracketbuffer,"ClearBracketBuffer");
63✔
567
        M_free(b->indexbuffer,"ClearIndexBuffer");
63✔
568
        M_free(b,"BracketInfo");
63✔
569
}
570

571
/*
572
          #] ClearBracketIndex : 
573
          #[ OpenBracketIndex :
574

575
        Note: This routine is thread-safe
576
*/
577

578
VOID OpenBracketIndex(WORD nexpr)
147✔
579
{
580
        EXPRESSIONS e = Expressions + nexpr;
147✔
581
        BRACKETINFO *bi;
147✔
582
        LONG i;
147✔
583
        bi = (BRACKETINFO *)Malloc1(sizeof(BRACKETINFO),"BracketInfo");
147✔
584
        e->newbracketinfo = bi;
147✔
585
/*
586
        i = 20*AM.MaxTer/sizeof(WORD);
587
        if ( i < 1000 ) i = 1000;
588
*/
589
        i = 2000;
147✔
590
        bi->bracketbuffer = (WORD *)Malloc1(i*sizeof(WORD),"Bracket Buffer");
147✔
591
        bi->bracketbuffersize = i;
147✔
592
        bi->bracketfill = 0;
147✔
593
        i = 50;
147✔
594
        bi->indexbuffer = (BRACKETINDEX *)Malloc1(i*sizeof(BRACKETINDEX),"Bracket Index");
147✔
595
        bi->indexbuffersize = i;
147✔
596
        bi->indexfill = 0;
147✔
597
        bi->SortType = AC.SortType;
147✔
598
}
147✔
599

600
/*
601
          #] OpenBracketIndex : 
602
          #[ PutInside :
603

604
        Puts a term, or a bracket determined part of a term inside a function.
605

606
        AT.WorkPointer points at term+*term
607
*/
608

609
int PutInside(PHEAD WORD *term, WORD *code)
212✔
610
{
611
        WORD *from, *to, *oldbuf, *tStop, *t, *tt, oldon, oldact, inc, argsize, *termout;
212✔
612
        int i, ii, error;
212✔
613
        
614
        if ( code[1] == 4 && ( code[2] == 0 || code[2] == 1 ) ) {
212✔
615
/*
616
                Put all inside. Move the term by 1+FUNHEAD+ARGHEAD
617
*/
618
                from = term+*term; to = from+1+ARGHEAD+FUNHEAD; i = ii = *term;
×
619
                to[0] = 1; to[1] = 1; to[2] = 3;
×
620
                while ( --i >= 0 ) *--to = *--from;
×
621
                to = term;
×
622
                *to++ = term[0]+4+ARGHEAD+FUNHEAD;
×
623
                *to++ = code[3];
×
624
                *to++ = ii+FUNHEAD+ARGHEAD;
×
625
                *to++ = 1;        /* set dirty flags, because there could be a fast notation */
×
626
                FILLFUN3(to)
627
                *to++ = ii+ARGHEAD;
×
628
                *to++ = 1;
×
629
                FILLARG(to)
630
                return(0);
×
631
        }
632
/*
633
        First we save the old bracket variables. Then we set variables to
634
        influence the PutBracket routine and call it.
635
        After that we set the values back and sort out the results by placing the
636
        inside of the bracket inside the function.
637
*/
638
        termout = AT.WorkPointer;
212✔
639
        oldbuf = AT.BrackBuf;
212✔
640
        oldon  = AR.BracketOn;
212✔
641
        oldact = AT.PolyAct;
212✔
642
        AR.BracketOn = -code[2];
212✔
643
        AT.BrackBuf  = code+4;
212✔
644
        AT.PolyAct = 0;
212✔
645
        error = PutBracket(BHEAD term);
212✔
646
        AT.PolyAct = oldact;
212✔
647
        AT.BrackBuf = oldbuf;
212✔
648
        AR.BracketOn = oldon;
212✔
649
        if ( error ) return(error);
212✔
650
        i = *termout; from = termout; to = term;
212✔
651
        NCOPY(to,from,i);
4,460✔
652
        tStop = term +*term; tStop -= tStop[-1];
212✔
653
        t = term+1;
212✔
654
        while ( t < tStop && *t != HAAKJE ) t += t[1];
388✔
655
    from = term + *term;
212✔
656
        inc = FUNHEAD+ARGHEAD-t[1]+1;
212✔
657
        tt = t + t[1];
212✔
658
        argsize = from-tt+1;
212✔
659
        to = from + inc;
212✔
660
        to[0] = 1;
212✔
661
        to[1] = 1;
212✔
662
        to[2] = 3;
212✔
663
        while ( from > tt ) *--to = *--from;
2,484✔
664
        *--to = argsize;
212✔
665
        *t++ = code[3];
212✔
666
        *t++ = argsize+FUNHEAD+ARGHEAD;
212✔
667
        *t++ = 1;
212✔
668
        FILLFUN3(t);
212✔
669
        *t++ = argsize+ARGHEAD;
212✔
670
        *t++ = 1;
212✔
671
        FILLARG(t);
212✔
672
        *term += inc+3;
212✔
673
        AT.WorkPointer = term+*term;
212✔
674
        if ( Normalize(BHEAD term) ) error = 1;
212✔
675
        return(error);
676
}
677

678
/*
679
          #] PutInside : 
680
*/
681

682
/*
683
        The next routines are for indexing the local output files in a parallel
684
        sort. This indexing is needed to get a fast determination of the 
685
        splitting terms needed to divide the terms evenly over the processors.
686
        Actually this method works well for ParFORM, but may not work well
687
        for TFORM.
688

689
          #[ PutTermInIndex :
690

691
        Puts a term in the term index.
692
        Action:
693
                if the index hasn't reached its full size
694
                        if there is room, put the term
695
                        if there is no room: extend the buffer, put the term
696
                else
697
                        check if the last term has a number of the type skip*m+1
698
                                if no, overwrite the last term
699
                                if yes, check whether there is room for one more term
700
                                        yes: add the term
701
                                        no: drop all even terms, compress the list,
702
                                                multiply skip by 2, and add this term.
703

704
int PutTermInIndex(WORD *term,POSITION *position)
705
{
706
        return(0);
707
}
708

709
          #] PutTermInIndex : 
710
*/
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc