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

form-dev / form / 15701338753

17 Jun 2025 07:49AM UTC coverage: 50.382% (-0.004%) from 50.386%
15701338753

Pull #662

github

web-flow
Merge f1f68c050 into 207386593
Pull Request #662: Cleanup: change VOID into void

178 of 245 new or added lines in 34 files covered. (72.65%)

2 existing lines in 1 file now uncovered.

41784 of 82935 relevant lines covered (50.38%)

2640008.85 hits per line

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

40.94
/sources/execute.c
1
/** @file execute.c
2
 * 
3
 *        The routines that start the execution phase of a module.
4
 *        It also contains the routines for placing the bracket subterm.
5
 */
6
/* #[ License : */
7
/*
8
 *   Copyright (C) 1984-2023 J.A.M. Vermaseren
9
 *   When using this file you are requested to refer to the publication
10
 *   J.A.M.Vermaseren "New features of FORM" math-ph/0010025
11
 *   This is considered a matter of courtesy as the development was paid
12
 *   for by FOM the Dutch physics granting agency and we would like to
13
 *   be able to track its scientific use to convince FOM of its value
14
 *   for the community.
15
 *
16
 *   This file is part of FORM.
17
 *
18
 *   FORM is free software: you can redistribute it and/or modify it under the
19
 *   terms of the GNU General Public License as published by the Free Software
20
 *   Foundation, either version 3 of the License, or (at your option) any later
21
 *   version.
22
 *
23
 *   FORM is distributed in the hope that it will be useful, but WITHOUT ANY
24
 *   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
25
 *   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
26
 *   details.
27
 *
28
 *   You should have received a copy of the GNU General Public License along
29
 *   with FORM.  If not, see <http://www.gnu.org/licenses/>.
30
 */
31
/* #] License : */ 
32
/*
33
          #[ Includes : execute.c
34
*/
35

36
#include "form3.h"
37

38
/*
39
          #] Includes : 
40
        #[ DoExecute :
41
                 #[ CleanExpr :
42

43
                par == 1 after .store or .clear
44
                par == 0 after .sort
45
*/
46

47
WORD CleanExpr(WORD par)
3,710✔
48
{
49
        GETIDENTITY
2,468✔
50
        WORD j, n, i;
3,710✔
51
        POSITION length;
3,710✔
52
        EXPRESSIONS e_in, e_out, e;
3,710✔
53
        int numhid = 0;
3,710✔
54
        NAMENODE *node;
3,710✔
55
        n = NumExpressions;
3,710✔
56
        j = 0;
3,710✔
57
        e_in = e_out = Expressions;
3,710✔
58
        if ( n > 0 ) { do {
3,710✔
59
                e_in->vflags &= ~( TOBEFACTORED | TOBEUNFACTORED );
1,405,088✔
60
                if ( par ) {
1,405,088✔
61
                        if ( e_in->renumlists ) {
54✔
62
                                if ( e_in->renumlists != AN.dummyrenumlist )
×
63
                                                M_free(e_in->renumlists,"Renumber-lists");
×
64
                                e_in->renumlists = 0;
×
65
                        }
66
                        if ( e_in->renum ) {
54✔
67
                                M_free(e_in->renum,"Renumber"); e_in->renum = 0;
×
68
                        }
69
                }
70
                if ( e_in->status == HIDDENLEXPRESSION
1,405,088✔
71
                || e_in->status == HIDDENGEXPRESSION ) numhid++;
1,405,088✔
72
                switch ( e_in->status ) {
1,405,088✔
73
                        case SPECTATOREXPRESSION:
932,624✔
74
                        case LOCALEXPRESSION:
75
                        case HIDDENLEXPRESSION:
76
                                if ( par ) {
932,624✔
77
                                        AC.exprnames->namenode[e_in->node].type = CDELETE;
×
78
                                        AC.DidClean = 1;
×
79
                                        if ( e_in->status != HIDDENLEXPRESSION )
×
80
                                                ClearBracketIndex(e_in-Expressions);
×
81
                                        break;
82
                                }
83
                                /* fall through */
84
                        case GLOBALEXPRESSION:
85
                        case HIDDENGEXPRESSION:
86
                                if ( par ) {
54✔
87
#ifdef WITHMPI
88
                                        /*
89
                                         * Broadcast the global expression from the master to the all workers.
90
                                         */
91
                                        if ( PF_BroadcastExpr(e_in, e_in->status == HIDDENGEXPRESSION ? AR.hidefile : AR.outfile) ) return -1;
92
                                        if ( PF.me == MASTER ) {
93
#endif
94
                                        e = e_in;
54✔
95
                                        i = n-1;
54✔
96
                                        while ( --i >= 0 ) {
54✔
97
                                                e++;
24✔
98
                                                if ( e_in->status == HIDDENGEXPRESSION ) {
24✔
99
                                                        if ( e->status == HIDDENGEXPRESSION
×
100
                                                        || e->status == HIDDENLEXPRESSION ) break;
×
101
                                                }
102
                                                else {
103
                                                        if ( e->status == GLOBALEXPRESSION
24✔
104
                                                        || e->status == LOCALEXPRESSION ) break;
24✔
105
                                                }
106
                                        }
107
#ifdef WITHMPI
108
                                        }
109
                                        else {
110
                                                /*
111
                                                 * On the slaves, the broadcast expression is sitting at the end of the file.
112
                                                 */
113
                                                e = e_in;
114
                                                i = -1;
115
                                        }
116
#endif
117
                                        if ( i >= 0 ) {
54✔
118
                                                DIFPOS(length,e->onfile,e_in->onfile);
24✔
119
                                        }
120
                                        else {
121
                                                FILEHANDLE *f = e_in->status == HIDDENGEXPRESSION ? AR.hidefile : AR.outfile;
30✔
122
                                                if ( f->handle < 0 ) {
30✔
123
                                                        SETBASELENGTH(length,TOLONG(f->POfull)
30✔
124
                                                         - TOLONG(f->PObuffer)
125
                                                         - BASEPOSITION(e_in->onfile));
126
                                                }
127
                                                else {
128
                                                        SeekFile(f->handle,&(f->filesize),SEEK_SET);
×
129
                                                        DIFPOS(length,f->filesize,e_in->onfile);
×
130
                                                }
131
                                        }
132
                                        if ( ToStorage(e_in,&length) ) {
54✔
133
                                                return(MesCall("CleanExpr"));
×
134
                                        }
135
                                        e_in->status = STOREDEXPRESSION;
54✔
136
                                        if ( e_in->status != HIDDENGEXPRESSION )
54✔
137
                                                ClearBracketIndex(e_in-Expressions);
54✔
138
                                }
139
                                /* fall through */
140
                        case SKIPLEXPRESSION:
141
                        case DROPLEXPRESSION:
142
                        case DROPHLEXPRESSION:
143
                        case DROPGEXPRESSION:
144
                        case DROPHGEXPRESSION:
145
                        case STOREDEXPRESSION:
146
                        case DROPSPECTATOREXPRESSION:
147
                                if ( e_out != e_in ) {
932,726✔
148
                                        node = AC.exprnames->namenode + e_in->node;
618✔
149
                                        node->number = e_out - Expressions;
618✔
150

151
                                        e_out->onfile = e_in->onfile;
618✔
152
                                        e_out->size = e_in->size;
618✔
153
                                        e_out->printflag = 0;
618✔
154
                                        if ( par ) e_out->status = STOREDEXPRESSION;
618✔
155
                                        else e_out->status = e_in->status;
618✔
156
                                        e_out->name = e_in->name;
618✔
157
                                        e_out->node = e_in->node;
618✔
158
                                        e_out->renum = e_in->renum;
618✔
159
                                        e_out->renumlists = e_in->renumlists;
618✔
160
                                        e_out->counter = e_in->counter;
618✔
161
                                        e_out->hidelevel = e_in->hidelevel;
618✔
162
                                        e_out->inmem = e_in->inmem;
618✔
163
                                        e_out->bracketinfo = e_in->bracketinfo;
618✔
164
                                        e_out->newbracketinfo = e_in->newbracketinfo;
618✔
165
                                        e_out->numdummies = e_in->numdummies;
618✔
166
                                        e_out->numfactors = e_in->numfactors;
618✔
167
                                        e_out->vflags = e_in->vflags;
618✔
168
                                        e_out->uflags = e_in->uflags;
618✔
169
                                        e_out->sizeprototype = e_in->sizeprototype;
618✔
170
                                }
171
#ifdef PARALLELCODE
172
                                e_out->partodo = 0;
621,804✔
173
#endif
174
                                e_out++;
932,726✔
175
                                j++;
932,726✔
176
                                break;
932,726✔
177
                        case DROPPEDEXPRESSION:
178
                                break;
179
                        default:
×
180
                                AC.exprnames->namenode[e_in->node].type = CDELETE;
×
181
                                AC.DidClean = 1;
×
182
                                break;
×
183
                }
184
                e_in++;
1,405,088✔
185
        } while ( --n > 0 ); }
1,405,088✔
186
        UpdateMaxSize();
3,710✔
187
        NumExpressions = j;
3,710✔
188
        if ( numhid == 0 && AR.hidefile->PObuffer ) {
3,710✔
189
                if ( AR.hidefile->handle >= 0 ) {
2,308✔
190
                        CloseFile(AR.hidefile->handle);
×
191
                        remove(AR.hidefile->name);
×
192
                        AR.hidefile->handle = -1;
×
193
                }
194
                AR.hidefile->POfull =
2,308✔
195
                AR.hidefile->POfill = AR.hidefile->PObuffer;
2,308✔
196
                PUTZERO(AR.hidefile->POposition);
2,308✔
197
        }
198
        FlushSpectators();
3,710✔
199
        return(0);
3,710✔
200
}
201

202
/*
203
                 #] CleanExpr : 
204
                 #[ PopVariables :
205

206
        Pops the local variables from the tables.
207
        The Expressions are reprocessed and their tables are compactified.
208

209
*/
210

211
WORD PopVariables(void)
30✔
212
{
213
        GETIDENTITY
20✔
214
        WORD i, j, retval;
30✔
215
        UBYTE *s;
30✔
216

217
        retval = CleanExpr(1);
30✔
218
        ResetVariables(1);
30✔
219

220
        if ( AC.DidClean ) CompactifyTree(AC.exprnames,EXPRNAMES);
30✔
221

222
        AC.CodesFlag = AM.gCodesFlag;
30✔
223
        AC.NamesFlag = AM.gNamesFlag;
30✔
224
        AC.StatsFlag = AM.gStatsFlag;
30✔
225
#ifdef WITHFLOAT
226
        AC.MaxWeight = AM.gMaxWeight;
30✔
227
        AC.DefaultPrecision = AM.gDefaultPrecision;
30✔
228
#endif
229
        AC.OldFactArgFlag = AM.gOldFactArgFlag;
30✔
230
        AC.TokensWriteFlag = AM.gTokensWriteFlag;
30✔
231
        AC.extrasymbols = AM.gextrasymbols;
30✔
232
        if ( AC.extrasym ) { M_free(AC.extrasym,"extrasym"); AC.extrasym = 0; }
30✔
233
        i = 1; s = AM.gextrasym; while ( *s ) { s++; i++; }
60✔
234
        AC.extrasym = (UBYTE *)Malloc1(i*sizeof(UBYTE),"extrasym");
30✔
235
        for ( j = 0; j < i; j++ ) AC.extrasym[j] = AM.gextrasym[j];
90✔
236
        AO.NoSpacesInNumbers = AM.gNoSpacesInNumbers;
30✔
237
        AO.IndentSpace = AM.gIndentSpace;
30✔
238
        AC.lUnitTrace = AM.gUnitTrace;
30✔
239
        AC.lDefDim = AM.gDefDim;
30✔
240
        AC.lDefDim4 = AM.gDefDim4;
30✔
241
        if ( AC.halfmod ) {
30✔
242
                if ( AC.ncmod == AM.gncmod && AC.modmode == AM.gmodmode ) {
×
243
                        j = ABS(AC.ncmod);
×
244
                        while ( --j >= 0 ) {
×
245
                                if ( AC.cmod[j] != AM.gcmod[j] ) break;
×
246
                        }
247
                        if ( j >= 0 ) {
×
248
                                M_free(AC.halfmod,"halfmod");
×
249
                                AC.halfmod = 0; AC.nhalfmod = 0;
×
250
                        }
251
                }
252
                else {
253
                        M_free(AC.halfmod,"halfmod");
×
254
                        AC.halfmod = 0; AC.nhalfmod = 0;
×
255
                }
256
        }
257
        if ( AC.modinverses ) {
30✔
258
                if ( AC.ncmod == AM.gncmod && AC.modmode == AM.gmodmode ) {
×
259
                        j = ABS(AC.ncmod);
×
260
                        while ( --j >= 0 ) {
×
261
                                if ( AC.cmod[j] != AM.gcmod[j] ) break;
×
262
                        }
263
                        if ( j >= 0 ) {
×
264
                                M_free(AC.modinverses,"modinverses");
×
265
                                AC.modinverses = 0;
×
266
                        }
267
                }
268
                else {
269
                        M_free(AC.modinverses,"modinverses");
×
270
                        AC.modinverses = 0;
×
271
                }
272
        }
273
        AN.ncmod = AC.ncmod = AM.gncmod;
30✔
274
        AC.npowmod = AM.gnpowmod;
30✔
275
        AC.modmode = AM.gmodmode;
30✔
276
        if ( ( ( AC.modmode & INVERSETABLE ) != 0 ) && ( AC.modinverses == 0 ) )
30✔
277
                        MakeInverses();
×
278
        AC.funpowers = AM.gfunpowers;
30✔
279
        AC.lPolyFun = AM.gPolyFun;
30✔
280
        AC.lPolyFunInv = AM.gPolyFunInv;
30✔
281
        AC.lPolyFunType = AM.gPolyFunType;
30✔
282
        AC.lPolyFunExp = AM.gPolyFunExp;
30✔
283
        AR.PolyFunVar = AC.lPolyFunVar = AM.gPolyFunVar;
30✔
284
        AC.lPolyFunPow = AM.gPolyFunPow;
30✔
285
        AC.parallelflag = AM.gparallelflag;
30✔
286
        AC.ProcessBucketSize = AC.mProcessBucketSize = AM.gProcessBucketSize;
30✔
287
        AC.properorderflag = AM.gproperorderflag;
30✔
288
    AC.ThreadBucketSize = AM.gThreadBucketSize;
30✔
289
        AC.ThreadStats = AM.gThreadStats;
30✔
290
        AC.FinalStats = AM.gFinalStats;
30✔
291
        AC.OldGCDflag = AM.gOldGCDflag;
30✔
292
        AC.WTimeStatsFlag = AM.gWTimeStatsFlag;
30✔
293
        AC.ThreadsFlag = AM.gThreadsFlag;
30✔
294
        AC.ThreadBalancing = AM.gThreadBalancing;
30✔
295
        AC.ThreadSortFileSynch = AM.gThreadSortFileSynch;
30✔
296
        AC.ProcessStats = AM.gProcessStats;
30✔
297
        AC.OldParallelStats = AM.gOldParallelStats;
30✔
298
        AC.IsFortran90 = AM.gIsFortran90;
30✔
299
        AC.SizeCommuteInSet = AM.gSizeCommuteInSet;
30✔
300
        PruneExtraSymbols(AM.gnumextrasym);
30✔
301

302
        if ( AC.Fortran90Kind ) {
30✔
303
                M_free(AC.Fortran90Kind,"Fortran90 Kind");
×
304
                AC.Fortran90Kind = 0;
×
305
        }
306
        if ( AM.gFortran90Kind ) {
30✔
307
                AC.Fortran90Kind = strDup1(AM.gFortran90Kind,"Fortran90 Kind");
×
308
        }
309
        if ( AC.ThreadsFlag && AM.totalnumberofthreads > 1 ) AS.MultiThreaded = 1;
30✔
310
        {
311
                UWORD *p, *m;
30✔
312
                p = AM.gcmod;
30✔
313
                m = AC.cmod;
30✔
314
                j = ABS(AC.ncmod);
30✔
315
                NCOPY(m,p,j);
30✔
316
                p = AM.gpowmod;
30✔
317
                m = AC.powmod;
30✔
318
                j = AC.npowmod;
30✔
319
                NCOPY(m,p,j);
30✔
320
                if ( AC.DirtPow ) {
30✔
321
                        if ( MakeModTable() ) {
×
322
                                MesPrint("===No printing in powers of generator");
×
323
                        }
324
                        AC.DirtPow = 0;
×
325
                }
326
        }
327
        {
328
                WORD *p, *m;
329
                p = AM.gUniTrace;
330
                m = AC.lUniTrace;
331
                j = 4;
332
                NCOPY(m,p,j);
150✔
333
        }
334
        AC.Cnumpows = AM.gCnumpows;
30✔
335
        AC.OutputMode = AM.gOutputMode;
30✔
336
        AC.OutputSpaces = AM.gOutputSpaces;
30✔
337
        AC.OutNumberType = AM.gOutNumberType;
30✔
338
        AR.SortType = AC.SortType = AM.gSortType;
30✔
339
        AC.ShortStatsMax = AM.gShortStatsMax;
30✔
340
/*
341
        Now we have to clean up the commutation properties
342
*/
343
        for ( i = 0; i < NumFunctions; i++ ) functions[i].flags &= ~COULDCOMMUTE;
3,930✔
344
        if ( AC.CommuteInSet ) {
30✔
345
                WORD *g, *gg;
346
                g = AC.CommuteInSet;
347
                while ( *g ) {
×
348
                        gg = g+1; g += *g;
×
349
                        while ( gg < g ) {
×
350
                                if ( *gg <= GAMMASEVEN && *gg >= GAMMA ) {
×
351
                                        functions[GAMMA-FUNCTION].flags |= COULDCOMMUTE;
×
352
                                        functions[GAMMAI-FUNCTION].flags |= COULDCOMMUTE;
×
353
                                        functions[GAMMAFIVE-FUNCTION].flags |= COULDCOMMUTE;
×
354
                                        functions[GAMMASIX-FUNCTION].flags |= COULDCOMMUTE;
×
355
                                        functions[GAMMASEVEN-FUNCTION].flags |= COULDCOMMUTE;
×
356
                                }
357
                                else {
358
                                        functions[*gg-FUNCTION].flags |= COULDCOMMUTE;
×
359
                                }
360
                        }
361
                }
362
        }
363
/*
364
        Clean up the dictionaries.
365
*/
366
        for ( i = AO.NumDictionaries-1; i >= AO.gNumDictionaries; i-- ) {
30✔
367
                RemoveDictionary(AO.Dictionaries[i]);
×
368
                M_free(AO.Dictionaries[i],"Dictionary");
×
369
        }
370
        for( ; i >= 0; i-- ) {
30✔
371
                ShrinkDictionary(AO.Dictionaries[i]);
×
372
        }
373
        AO.NumDictionaries = AO.gNumDictionaries;
30✔
374
        return(retval);
30✔
375
}
376

377
/*
378
                 #] PopVariables : 
379
                 #[ MakeGlobal :
380
*/
381

NEW
382
void MakeGlobal(void)
×
383
{
384
        WORD i, j, *pp, *mm;
×
385
        UWORD *p, *m;
×
386
        UBYTE *s;
×
387
        Globalize(0);
×
388

389
        AM.gCodesFlag = AC.CodesFlag;
×
390
        AM.gNamesFlag = AC.NamesFlag;
×
391
        AM.gStatsFlag = AC.StatsFlag;
×
392
#ifdef WITHFLOAT
393
        AM.gMaxWeight = AC.MaxWeight;
×
394
        AM.gDefaultPrecision = AC.DefaultPrecision;
×
395
#endif
396
    AM.gOldFactArgFlag = AC.OldFactArgFlag;
×
397
        AM.gextrasymbols = AC.extrasymbols;
×
398
        if ( AM.gextrasym ) { M_free(AM.gextrasym,"extrasym"); AM.gextrasym = 0; }
×
399
        i = 1; s = AC.extrasym; while ( *s ) { s++; i++; }
×
400
        AM.gextrasym = (UBYTE *)Malloc1(i*sizeof(UBYTE),"extrasym");
×
401
        for ( j = 0; j < i; j++ ) AM.gextrasym[j] = AC.extrasym[j];
×
402
        AM.gTokensWriteFlag= AC.TokensWriteFlag;
×
403
        AM.gNoSpacesInNumbers = AO.NoSpacesInNumbers;
×
404
        AM.gIndentSpace = AO.IndentSpace;
×
405
        AM.gUnitTrace = AC.lUnitTrace;
×
406
        AM.gDefDim = AC.lDefDim;
×
407
        AM.gDefDim4 = AC.lDefDim4;
×
408
        AM.gncmod = AC.ncmod;
×
409
        AM.gnpowmod = AC.npowmod;
×
410
        AM.gmodmode = AC.modmode;
×
411
        AM.gCnumpows = AC.Cnumpows;
×
412
        AM.gOutputMode = AC.OutputMode;
×
413
        AM.gOutputSpaces = AC.OutputSpaces;
×
414
        AM.gOutNumberType = AC.OutNumberType;
×
415
        AM.gfunpowers = AC.funpowers;
×
416
        AM.gPolyFun = AC.lPolyFun;
×
417
        AM.gPolyFunInv = AC.lPolyFunInv;
×
418
        AM.gPolyFunType = AC.lPolyFunType;
×
419
        AM.gPolyFunExp = AC.lPolyFunExp;
×
420
        AM.gPolyFunVar = AC.lPolyFunVar;
×
421
        AM.gPolyFunPow = AC.lPolyFunPow;
×
422
        AM.gparallelflag = AC.parallelflag;
×
423
        AM.gProcessBucketSize = AC.ProcessBucketSize;
×
424
        AM.gproperorderflag = AC.properorderflag;
×
425
    AM.gThreadBucketSize = AC.ThreadBucketSize;
×
426
        AM.gThreadStats = AC.ThreadStats;
×
427
        AM.gFinalStats = AC.FinalStats;
×
428
        AM.gOldGCDflag = AC.OldGCDflag;
×
429
        AM.gWTimeStatsFlag = AC.WTimeStatsFlag;
×
430
        AM.gThreadsFlag = AC.ThreadsFlag;
×
431
        AM.gThreadBalancing = AC.ThreadBalancing;
×
432
        AM.gThreadSortFileSynch = AC.ThreadSortFileSynch;
×
433
        AM.gProcessStats = AC.ProcessStats;
×
434
        AM.gOldParallelStats = AC.OldParallelStats;
×
435
        AM.gIsFortran90 = AC.IsFortran90;
×
436
        AM.gSizeCommuteInSet = AC.SizeCommuteInSet;
×
437
        AM.gnumextrasym = (cbuf+AM.sbufnum)->numrhs;
×
438
        if ( AM.gFortran90Kind ) {
×
439
                M_free(AM.gFortran90Kind,"Fortran 90 Kind");
×
440
                AM.gFortran90Kind = 0;
×
441
        }
442
        if ( AC.Fortran90Kind ) {
×
443
                AM.gFortran90Kind = strDup1(AC.Fortran90Kind,"Fortran 90 Kind");
×
444
        }
445
        p = AM.gcmod;
×
446
        m = AC.cmod;
×
447
        i = ABS(AC.ncmod);
×
448
        NCOPY(p,m,i);
×
449
        p = AM.gpowmod;
×
450
        m = AC.powmod;
×
451
        i = AC.npowmod;
×
452
        NCOPY(p,m,i);
×
453
        pp = AM.gUniTrace;
454
        mm = AC.lUniTrace;
455
        i = 4;
456
        NCOPY(pp,mm,i);
×
457
        AM.gSortType = AC.SortType;
×
458
        AM.gShortStatsMax = AC.ShortStatsMax;
×
459

460
        if ( AO.CurrentDictionary > 0 || AP.OpenDictionary > 0 ) {
×
461
                Warning("You cannot have an open or selected dictionary at a .global. Dictionary closed.");
×
462
                AP.OpenDictionary = 0;
×
463
                AO.CurrentDictionary = 0;
×
464
        }
465

466
        AO.gNumDictionaries = AO.NumDictionaries;
×
467
        for ( i = 0; i < AO.NumDictionaries; i++ ) {
×
468
                AO.Dictionaries[i]->gnumelements = AO.Dictionaries[i]->numelements;
×
469
        }
470
        if ( AM.NumSpectatorFiles > 0 ) {
×
471
                for ( i = 0; i < AM.SizeForSpectatorFiles; i++ ) {
×
472
                        if ( AM.SpectatorFiles[i].name != 0 )
×
473
                                        AM.SpectatorFiles[i].flags |= GLOBALSPECTATORFLAG;
×
474
                }
475
        }
476
}
×
477

478
/*
479
                 #] MakeGlobal : 
480
                 #[ TestDrop :
481
*/
482

483
void TestDrop(void)
3,710✔
484
{
485
        EXPRESSIONS e;
3,710✔
486
        WORD j;
3,710✔
487
        for ( j = 0, e = Expressions; j < NumExpressions; j++, e++ ) {
1,408,798✔
488
                switch ( e->status ) {
1,405,088✔
489
                        case SKIPLEXPRESSION:
×
490
                                e->status = LOCALEXPRESSION;
×
491
                                break;
×
492
                        case UNHIDELEXPRESSION:
6✔
493
                                e->status = LOCALEXPRESSION;
6✔
494
                                ClearBracketIndex(j);
6✔
495
                                e->bracketinfo = e->newbracketinfo; e->newbracketinfo = 0;
6✔
496
                                break;
6✔
497
                        case HIDELEXPRESSION:
×
498
                                e->status = HIDDENLEXPRESSION;
×
499
                                break;
×
500
                        case SKIPGEXPRESSION:
×
501
                                e->status = GLOBALEXPRESSION;
×
502
                                break;
×
503
                        case UNHIDEGEXPRESSION:
×
504
                                e->status = GLOBALEXPRESSION;
×
505
                                ClearBracketIndex(j);
×
506
                                e->bracketinfo = e->newbracketinfo; e->newbracketinfo = 0;
×
507
                                break;
×
508
                        case HIDEGEXPRESSION:
×
509
                                e->status = HIDDENGEXPRESSION;
×
510
                                break;
×
511
                        case DROPLEXPRESSION:
472,362✔
512
                        case DROPGEXPRESSION:
513
                        case DROPHLEXPRESSION:
514
                        case DROPHGEXPRESSION:
515
                        case DROPSPECTATOREXPRESSION:
516
                                e->status = DROPPEDEXPRESSION;
472,362✔
517
                                ClearBracketIndex(j);
472,362✔
518
                                e->bracketinfo = e->newbracketinfo; e->newbracketinfo = 0;
472,362✔
519
                                if ( e->replace >= 0 ) {
472,362✔
520
                                        Expressions[e->replace].replace = REGULAREXPRESSION;
138✔
521
                                        AC.exprnames->namenode[e->node].number = e->replace;
138✔
522
                                        e->replace = REGULAREXPRESSION;
138✔
523
                                }
524
                                else {
525
                                        AC.exprnames->namenode[e->node].type = CDELETE;
472,224✔
526
                                        AC.DidClean = 1;
472,224✔
527
                                }
528
                                break;
529
                        case LOCALEXPRESSION:
477,506✔
530
                        case GLOBALEXPRESSION:
531
                                ClearBracketIndex(j);
477,506✔
532
                                e->bracketinfo = e->newbracketinfo; e->newbracketinfo = 0;
477,506✔
533
                                break;
477,506✔
534
                        case HIDDENLEXPRESSION:
535
                        case HIDDENGEXPRESSION:
536
                                break;
537
                        case INTOHIDELEXPRESSION:
6✔
538
                                ClearBracketIndex(j);
6✔
539
                                e->bracketinfo = e->newbracketinfo; e->newbracketinfo = 0;
6✔
540
                                e->status = HIDDENLEXPRESSION;
6✔
541
                                break;
6✔
542
                        case INTOHIDEGEXPRESSION:
×
543
                                ClearBracketIndex(j);
×
544
                                e->bracketinfo = e->newbracketinfo; e->newbracketinfo = 0;
×
545
                                e->status = HIDDENGEXPRESSION;
×
546
                                break;
×
547
                        default:
204✔
548
                                ClearBracketIndex(j);
204✔
549
                                e->bracketinfo = 0;
204✔
550
                                break;
204✔
551
                }
552
                if ( e->replace == NEWLYDEFINEDEXPRESSION ) e->replace = REGULAREXPRESSION;
1,405,088✔
553
        }
554
}
3,710✔
555

556
/*
557
                 #] TestDrop : 
558
                 #[ PutInVflags :
559
*/
560

561
void PutInVflags(WORD nexpr)
476,276✔
562
{
563
        EXPRESSIONS e = Expressions + nexpr;
476,276✔
564
        POSITION *old;
476,276✔
565
        WORD *oldw;
476,276✔
566
        int i;
476,276✔
567
restart:;
476,276✔
568
        if ( AS.OldOnFile == 0 ) {
476,276✔
569
                AS.NumOldOnFile = 20;
1,802✔
570
                AS.OldOnFile = (POSITION *)Malloc1(AS.NumOldOnFile*sizeof(POSITION),"file pointers");
1,802✔
571
        }
572
        else if ( nexpr >= AS.NumOldOnFile ) {
474,474✔
573
                old = AS.OldOnFile;
912✔
574
                AS.OldOnFile = (POSITION *)Malloc1(2*AS.NumOldOnFile*sizeof(POSITION),"file pointers");
912✔
575
                for ( i = 0; i < AS.NumOldOnFile; i++ ) AS.OldOnFile[i] = old[i];
614,112✔
576
                AS.NumOldOnFile = 2*AS.NumOldOnFile;
912✔
577
                M_free(old,"process file pointers");
912✔
578
        }
579
        if ( AS.OldNumFactors == 0 ) {
476,276✔
580
                AS.NumOldNumFactors = 20;
1,802✔
581
                AS.OldNumFactors = (WORD *)Malloc1(AS.NumOldNumFactors*sizeof(WORD),"numfactors pointers");
1,802✔
582
                AS.Oldvflags = (WORD *)Malloc1(AS.NumOldNumFactors*sizeof(WORD),"vflags pointers");
1,802✔
583
                AS.Olduflags = (WORD *)Malloc1(AS.NumOldNumFactors*sizeof(WORD),"uflags pointers");
1,802✔
584
        }
585
        else if ( nexpr >= AS.NumOldNumFactors ) {
474,474✔
586
                oldw = AS.OldNumFactors;
912✔
587
                AS.OldNumFactors = (WORD *)Malloc1(2*AS.NumOldNumFactors*sizeof(WORD),"numfactors pointers");
912✔
588
                for ( i = 0; i < AS.NumOldNumFactors; i++ ) AS.OldNumFactors[i] = oldw[i];
614,112✔
589
                M_free(oldw,"numfactors pointers");
912✔
590
                oldw = AS.Oldvflags;
912✔
591
                AS.Oldvflags = (WORD *)Malloc1(2*AS.NumOldNumFactors*sizeof(WORD),"vflags pointers");
912✔
592
                for ( i = 0; i < AS.NumOldNumFactors; i++ ) AS.Oldvflags[i] = oldw[i];
614,112✔
593
                M_free(oldw,"vflags pointers");
912✔
594
                oldw = AS.Olduflags;
912✔
595
                AS.Olduflags = (WORD *)Malloc1(2*AS.NumOldNumFactors*sizeof(WORD),"uflags pointers");
912✔
596
                for ( i = 0; i < AS.NumOldNumFactors; i++ ) AS.Olduflags[i] = oldw[i];
614,112✔
597
                M_free(oldw,"uflags pointers");
912✔
598
                AS.NumOldNumFactors = 2*AS.NumOldNumFactors;
912✔
599
        }
600
/*
601
        The next is needed when we Load a .sav file with lots of expressions.
602
*/
603
        if ( nexpr >= AS.NumOldOnFile || nexpr >= AS.NumOldNumFactors ) goto restart;
476,276✔
604
        AS.OldOnFile[nexpr] = e->onfile;
476,276✔
605
        AS.OldNumFactors[nexpr] = e->numfactors;
476,276✔
606
        AS.Oldvflags[nexpr] = e->vflags;
476,276✔
607
        AS.Olduflags[nexpr] = e->uflags;
476,276✔
608
}
476,276✔
609

610
/*
611
                 #] PutInVflags : 
612
                 #[ DoExecute :
613
*/
614

615
WORD DoExecute(WORD par, WORD skip)
3,826✔
616
{
617
        GETIDENTITY
2,548✔
618
        WORD RetCode = 0;
3,826✔
619
        int i, oldmultithreaded = AS.MultiThreaded;
3,826✔
620
#ifdef PARALLELCODE
621
        int j;
2,548✔
622
#endif
623

624
        SpecialCleanup(BHEAD0);
3,826✔
625
        if ( skip ) goto skipexec;
3,826✔
626
        if ( AC.IfLevel > 0 ) {
3,826✔
627
                MesPrint(" %d endif statement(s) missing",AC.IfLevel);
×
628
                RetCode = 1;
×
629
        }
630
        if ( AC.WhileLevel > 0 ) {
3,826✔
631
                MesPrint(" %d endwhile statement(s) missing",AC.WhileLevel);
×
632
                RetCode = 1;
×
633
        }
634
        if ( AC.arglevel > 0 ) {
3,826✔
635
                MesPrint(" %d endargument statement(s) missing",AC.arglevel);
×
636
                RetCode = 1;
×
637
        }
638
        if ( AC.termlevel > 0 ) {
3,826✔
639
                MesPrint(" %d endterm statement(s) missing",AC.termlevel);
×
640
                RetCode = 1;
×
641
        }
642
        if ( AC.insidelevel > 0 ) {
3,826✔
643
                MesPrint(" %d endinside statement(s) missing",AC.insidelevel);
×
644
                RetCode = 1;
×
645
        }
646
        if ( AC.inexprlevel > 0 ) {
3,826✔
647
                MesPrint(" %d endinexpression statement(s) missing",AC.inexprlevel);
×
648
                RetCode = 1;
×
649
        }
650
        if ( AC.NumLabels > 0 ) {
3,826✔
651
                for ( i = 0; i < AC.NumLabels; i++ ) {
222✔
652
                        if ( AC.Labels[i] < 0 ) {
192✔
653
                                MesPrint(" -->Label %s missing",AC.LabelNames[i]);
×
654
                                RetCode = 1;
×
655
                        }
656
                }
657
        }
658
        if ( AC.SwitchLevel > 0 ) {
3,826✔
659
                MesPrint(" %d endswitch statement(s) missing",AC.SwitchLevel);
×
660
                RetCode = 1;
×
661
        }
662
        if ( AC.dolooplevel > 0 ) {
3,826✔
663
                MesPrint(" %d enddo statement(s) missing",AC.dolooplevel);
×
664
                RetCode = 1;
×
665
        }
666
        if ( AP.OpenDictionary > 0 ) {
3,826✔
667
                MesPrint(" Dictionary %s has not been closed.",
×
668
                        AO.Dictionaries[AP.OpenDictionary-1]->name);
×
669
                AP.OpenDictionary = 0;
×
670
                RetCode = 1;
×
671
        }
672
        if ( RetCode ) return(RetCode);
3,826✔
673
        AR.Cnumlhs = cbuf[AM.rbufnum].numlhs;
3,826✔
674

675
        if ( ( AS.ExecMode = par ) == GLOBALMODULE ) AS.ExecMode = 0;
3,826✔
676
#ifdef PARALLELCODE
677
/*
678
                Now check whether we have either the regular parallel flag or the
679
                mparallel flag set.
680
                Next check whether any of the expressions has partodo set.
681
                If any of the above we need to check what the dollar status is.
682
*/
683
        AC.partodoflag = -1;
2,548✔
684
        if ( NumPotModdollars >= 0 ) {
2,548✔
685
                for ( i = 0; i < NumExpressions; i++ ) {
624,880✔
686
                        if ( Expressions[i].partodo ) { AC.partodoflag = 1; break; }
622,564✔
687
                }
688
        }
689
#ifdef WITHMPI
690
        if ( AC.partodoflag > 0 && PF.numtasks < 3 ) {
691
                AC.partodoflag = 0;
692
        }
693
#endif
694
        if ( AC.partodoflag > 0 || ( NumPotModdollars > 0 && AC.mparallelflag == PARALLELFLAG ) ) {
2,548✔
695
          if ( NumPotModdollars > NumModOptdollars ) {
296✔
696
                AC.mparallelflag |= NOPARALLEL_DOLLAR;
44✔
697
#ifdef WITHPTHREADS
698
                AS.MultiThreaded = 0;
44✔
699
#endif
700
                AC.partodoflag = 0;
44✔
701
          }
702
          else {
703
                for ( i = 0; i < NumPotModdollars; i++ ) {
284✔
704
                  for ( j = 0; j < NumModOptdollars; j++ ) 
48✔
705
                        if ( PotModdollars[i] == ModOptdollars[j].number ) break;
48✔
706
                  if ( j >= NumModOptdollars ) {
32✔
707
                        AC.mparallelflag |= NOPARALLEL_DOLLAR;
708
#ifdef WITHPTHREADS
709
                        AS.MultiThreaded = 0;
710
#endif
711
                        AC.partodoflag = 0;
712
                        break;
713
                  }
714
                  switch ( ModOptdollars[j].type ) {
32✔
715
                        case MODSUM:
716
                        case MODMAX:
717
                        case MODMIN:
718
                        case MODLOCAL:
719
                                break;
720
                        default:
721
                                AC.mparallelflag |= NOPARALLEL_DOLLAR;
722
                                AS.MultiThreaded = 0;
723
                                AC.partodoflag = 0;
724
                                break;
725
                  }
726
                }
727
          }
728
        }
729
        else if ( ( AC.mparallelflag & NOPARALLEL_USER ) != 0 ) {
2,252✔
730
#ifdef WITHPTHREADS
731
                AS.MultiThreaded = 0;
4✔
732
#endif
733
                AC.partodoflag = 0;
4✔
734
        }
735
        if ( AC.partodoflag == 0 ) {
2,548✔
736
                for ( i = 0; i < NumExpressions; i++ ) {
116✔
737
                        Expressions[i].partodo = 0;
68✔
738
                }
739
        }
740
        else if ( AC.partodoflag == -1 ) {
2,500✔
741
                AC.partodoflag = 0;
2,268✔
742
        }
743
#endif
744
#ifdef WITHMPI
745
        /*
746
         * Check RHS expressions.
747
         */
748
        if ( AC.RhsExprInModuleFlag && (AC.mparallelflag == PARALLELFLAG || AC.partodoflag) ) {
749
                if (PF.rhsInParallel) {
750
                        PF.mkSlaveInfile=1;
751
                        if(PF.me != MASTER){
752
                                PF.slavebuf.PObuffer=(WORD *)Malloc1(AM.ScratSize*sizeof(WORD),"PF inbuf");
753
                                PF.slavebuf.POsize=AM.ScratSize*sizeof(WORD);
754
                                PF.slavebuf.POfull = PF.slavebuf.POfill = PF.slavebuf.PObuffer;
755
                                PF.slavebuf.POstop= PF.slavebuf.PObuffer+AM.ScratSize;
756
                                PUTZERO(PF.slavebuf.POposition);
757
                        }/*if(PF.me != MASTER)*/
758
                } 
759
                else {
760
                        AC.mparallelflag |= NOPARALLEL_RHS;
761
                        AC.partodoflag = 0;
762
                        for ( i = 0; i < NumExpressions; i++ ) {
763
                                Expressions[i].partodo = 0;
764
                        }
765
                }
766
        }
767
        /*
768
         * Set $-variables with MODSUM to zero on the slaves.
769
         */
770
        if ( (AC.mparallelflag == PARALLELFLAG || AC.partodoflag) && PF.me != MASTER ) {
771
                for ( i = 0; i < NumModOptdollars; i++ ) {
772
                        if ( ModOptdollars[i].type == MODSUM ) {
773
                                DOLLARS d = Dollars + ModOptdollars[i].number;
774
                                d->type = DOLZERO;
775
                                if ( d->where && d->where != &AM.dollarzero ) M_free(d->where, "old content of dollar");
776
                                d->where = &AM.dollarzero;
777
                                d->size = 0;
778
                                CleanDollarFactors(d);
779
                        }
780
                }
781
        }
782
#endif
783
        AR.SortType = AC.SortType;
3,826✔
784
#ifdef WITHMPI
785
        if ( PF.me == MASTER )
786
#endif
787
        {
788
                if ( AC.SetupFlag ) WriteSetup();
3,826✔
789
                if ( AC.NamesFlag || AC.CodesFlag ) WriteLists();
3,826✔
790
        }
791
        if ( par == GLOBALMODULE ) MakeGlobal();
3,826✔
792
        if ( RevertScratch() ) return(-1);
3,826✔
793
        if ( AC.ncmod ) SetMods();
3,826✔
794
/*
795
        Warn if the module has to run in sequential mode due to some problems.
796
*/
797
#ifdef WITHMPI
798
        if ( PF.me == MASTER )
799
#endif
800
        {
801
                if ( !AC.ThreadsFlag || AC.mparallelflag & NOPARALLEL_USER ) {
3,826✔
802
                        /* The user switched off the parallel execution explicitly. */
803
                }
804
                else if ( AC.mparallelflag & NOPARALLEL_DOLLAR ) {
3,820✔
805
                        if ( AC.WarnFlag >= 2 ) {  /* HighWarning */
44✔
806
                                int i, j, k, n;
×
807
                                UBYTE *s, *s1;
×
808
                                s = strDup1((UBYTE *)"","NOPARALLEL_DOLLAR s");
×
809
                                n = 0;
×
810
                                j = NumPotModdollars;
×
811
                                for ( i = 0; i < j; i++ ) {
×
812
                                        for ( k = 0; k < NumModOptdollars; k++ )
×
813
                                                if ( ModOptdollars[k].number == PotModdollars[i] ) break;
×
814
                                        if ( k >= NumModOptdollars ) {
×
815
                                                /* global $-variable */
816
                                                if ( n > 0 )
×
817
                                                        s = AddToString(s,(UBYTE *)", ",0);
×
818
                                                s = AddToString(s,(UBYTE *)"$",0);
×
819
                                                s = AddToString(s,DOLLARNAME(Dollars,PotModdollars[i]),0);
×
820
                                                n++;
×
821
                                        }
822
                                }
823
                                s1 = strDup1((UBYTE *)"This module is forced to run in sequential mode due to $-variable","NOPARALLEL_DOLLAR s1");
×
824
                                if ( n != 1 )
×
825
                                        s1 = AddToString(s1,(UBYTE *)"s",0);
×
826
                                s1 = AddToString(s1,(UBYTE *)": ",0);
×
827
                                s1 = AddToString(s1,s,0);
×
828
                                HighWarning((char *)s1);
×
829
                                M_free(s,"NOPARALLEL_DOLLAR s");
×
830
                                M_free(s1,"NOPARALLEL_DOLLAR s1");
×
831
                        }
832
                }
833
                else if ( AC.mparallelflag & NOPARALLEL_RHS ) {
3,776✔
834
                        HighWarning("This module is forced to run in sequential mode due to RHS expression names");
×
835
                }
836
                else if ( AC.mparallelflag & NOPARALLEL_CONVPOLY ) {
3,776✔
837
                        HighWarning("This module is forced to run in sequential mode due to conversion to extra symbols");
×
838
                }
839
                else if ( AC.mparallelflag & NOPARALLEL_SPECTATOR ) {
3,776✔
840
                        HighWarning("This module is forced to run in sequential mode due to tospectator/copyspectator");
×
841
                }
842
                else if ( AC.mparallelflag & NOPARALLEL_TBLDOLLAR ) {
3,776✔
843
                        HighWarning("This module is forced to run in sequential mode due to $-variable assignments in tables");
×
844
                }
845
                else if ( AC.mparallelflag & NOPARALLEL_NPROC ) {
3,776✔
846
                        HighWarning("This module is forced to run in sequential mode because there is only one processor");
×
847
                }
848
        }
849
/*
850
        Now the actual execution
851
*/
852
#ifdef WITHMPI
853
        /*
854
         * Turn on AS.printflag to print runtime errors occurring on slaves.
855
         */
856
        AS.printflag = 1;
857
#endif
858
        if ( AP.preError == 0 && ( Processor() || WriteAll() ) ) RetCode = -1;
3,826✔
859
#ifdef WITHMPI
860
        AS.printflag = 0;
861
#endif
862
/*
863
        That was it. Next is cleanup.
864
*/
865
        if ( AC.ncmod ) UnSetMods();
3,710✔
866
        AS.MultiThreaded = oldmultithreaded;
3,710✔
867
        TableReset();
3,710✔
868

869
/*[28sep2005 mt]:*/
870
#ifdef WITHMPI
871
        /* Combine and then broadcast modified dollar variables. */
872
        if ( NumPotModdollars > 0 ) {
873
                RetCode = PF_CollectModifiedDollars();
874
                if ( RetCode ) return RetCode;
875
                RetCode = PF_BroadcastModifiedDollars();
876
                if ( RetCode ) return RetCode;
877
        }
878
        /* Broadcast the list of objects converted to symbols in AM.sbufnum. */
879
        if ( AC.topolynomialflag & TOPOLYNOMIALFLAG ) {
880
                RetCode = PF_BroadcastCBuf(AM.sbufnum);
881
                if ( RetCode ) return RetCode;
882
        }
883
        /*
884
         * Broadcast AR.expflags, which may be used on the slaves in the next module
885
         * via ZERO_ or UNCHANGED_. It also broadcasts several flags of each expression.
886
         */
887
        RetCode = PF_BroadcastExpFlags();
888
        if ( RetCode ) return RetCode;
889
        /*
890
         * Clean the hide file on the slaves, which was used for RHS expressions
891
         * broadcast from the master at the beginning of the module.
892
         */
893
        if ( PF.me != MASTER && AR.hidefile->PObuffer ) {
894
                if ( AR.hidefile->handle >= 0 ) {
895
                        CloseFile(AR.hidefile->handle);
896
                        AR.hidefile->handle = -1;
897
                        remove(AR.hidefile->name);
898
                }
899
                AR.hidefile->POfull = AR.hidefile->POfill = AR.hidefile->PObuffer;
900
                PUTZERO(AR.hidefile->POposition);
901
        }
902
#endif
903
#ifdef WITHPTHREADS
904
        for ( j = 0; j < NumModOptdollars; j++ ) {
4,972✔
905
                if ( ModOptdollars[j].dstruct ) {
36✔
906
/*
907
                        First clean up dollar values.
908
*/
909
                        for ( i = 0; i < AM.totalnumberofthreads; i++ ) {
120✔
910
                                if ( ModOptdollars[j].dstruct[i].size > 0 ) {
96✔
911
                                        CleanDollarFactors(&(ModOptdollars[j].dstruct[i]));
59✔
912
                                        M_free(ModOptdollars[j].dstruct[i].where,"Local dollar value");
59✔
913
                                }
914
                        }
915
/*
916
                        Now clean up the whole array.
917
*/
918
                        M_free(ModOptdollars[j].dstruct,"Local DOLLARS");
24✔
919
                        ModOptdollars[j].dstruct = 0;
24✔
920
                }
921
        }
922
#endif
923
/*:[28sep2005 mt]*/
924

925
/*
926
        @@@@@@@@@@@@@@@
927
        Now follows the code to invalidate caches for all objects in the
928
        PotModdollars. There are NumPotModdollars of them and PotModdollars
929
        is an array of WORD.
930
*/
931
/*
932
        Cleanup:
933
*/
934
#ifdef JV_IS_WRONG
935
/*
936
        Giving back this memory gives way too much activity with Malloc1
937
        Better to keep it and just put the number of used objects to zero (JV)
938
        If you put the lijst equal to NULL, please also make maxnum = 0
939
*/
940
        if ( ModOptdollars ) M_free(ModOptdollars, "ModOptdollars pointer");
941
        if ( PotModdollars ) M_free(PotModdollars, "PotModdollars pointer");
942
        
943
        /* ModOptdollars changed to AC.ModOptDolList.lijst because AIX C compiler complained. MF 30/07/2003. */
944
        AC.ModOptDolList.lijst = NULL;
945
        /* PotModdollars changed to AC.PotModDolList.lijst because AIX C compiler complained. MF 30/07/2003. */
946
        AC.PotModDolList.lijst = NULL;
947
#endif
948
        NumPotModdollars = 0;
3,710✔
949
        NumModOptdollars = 0;
3,710✔
950

951
skipexec:
3,710✔
952
/*
953
        Clean up the switch information.
954
        We keep the switch array and heap.
955
*/
956
if ( AC.SwitchInArray > 0 ) {
3,710✔
957
        for ( i = 0; i < AC.SwitchInArray; i++ ) {
×
958
                SWITCH *sw = AC.SwitchArray + i;
×
959
                if ( sw->table ) M_free(sw->table,"Switch table");
×
960
                sw->table = 0;
×
961
                sw->defaultcase.ncase = 0;
×
962
                sw->defaultcase.value = 0;
×
963
                sw->defaultcase.compbuffer = 0;
×
964
                sw->endswitch.ncase = 0;
×
965
                sw->endswitch.value = 0;
×
966
                sw->endswitch.compbuffer = 0;
×
967
                sw->typetable = 0;
×
968
                sw->maxcase = 0;
×
969
                sw->mincase = 0;
×
970
                sw->numcases = 0;
×
971
                sw->tablesize = 0;
×
972
                sw->caseoffset = 0;
×
973
                sw->iflevel = 0;
×
974
                sw->whilelevel = 0;
×
975
                sw->nestingsum = 0;
×
976
        }
977
        AC.SwitchInArray = 0;
×
978
        AC.SwitchLevel = 0;
×
979
}
980
#ifdef PARALLELCODE
981
        AC.numpfirstnum = 0;
2,468✔
982
#endif
983
        AC.DidClean = 0;
3,710✔
984
        AC.PolyRatFunChanged = 0;
3,710✔
985
        TestDrop();
3,710✔
986
        if ( par == STOREMODULE || par == CLEARMODULE ) {
3,710✔
987
                ClearOptimize();
30✔
988
                if ( par == STOREMODULE && PopVariables() ) RetCode = -1;
30✔
989
                if ( AR.infile->handle >= 0 ) {
30✔
990
                        CloseFile(AR.infile->handle);
×
991
                        remove(AR.infile->name);
×
992
                        AR.infile->handle = -1;
×
993
                }
994
                AR.infile->POfill = AR.infile->PObuffer;
30✔
995
                PUTZERO(AR.infile->POposition);
30✔
996
                AR.infile->POfull = AR.infile->PObuffer;
30✔
997
                if ( AR.outfile->handle >= 0 ) {
30✔
998
                        CloseFile(AR.outfile->handle);
×
999
                        remove(AR.outfile->name);
×
1000
                        AR.outfile->handle = -1;
×
1001
                }
1002
                AR.outfile->POfull =
30✔
1003
                AR.outfile->POfill = AR.outfile->PObuffer;
30✔
1004
                PUTZERO(AR.outfile->POposition);
30✔
1005
                if ( AR.hidefile->handle >= 0 ) {
30✔
1006
                        CloseFile(AR.hidefile->handle);
×
1007
                        remove(AR.hidefile->name);
×
1008
                        AR.hidefile->handle = -1;
×
1009
                }
1010
                AR.hidefile->POfull =
30✔
1011
                AR.hidefile->POfill = AR.hidefile->PObuffer;
30✔
1012
                PUTZERO(AR.hidefile->POposition);
30✔
1013
                AC.HideLevel = 0;
30✔
1014
                if ( par == CLEARMODULE ) {
30✔
1015
                        if ( DeleteStore(0) < 0 ) {
×
1016
                                MesPrint("Cannot restart the storage file");
×
1017
                                RetCode = -1;
×
1018
                        }
1019
                        else RetCode = 0;
1020
                        CleanUp(1);
×
1021
                        ResetVariables(2);
×
1022
                        AM.gProcessBucketSize = AM.hProcessBucketSize;
×
1023
                        AM.gparallelflag = PARALLELFLAG;
×
1024
                        AM.gnumextrasym = AM.ggnumextrasym;
×
1025
                        PruneExtraSymbols(AM.ggnumextrasym);
×
1026
                        IniVars();
×
1027
                }
1028
                ClearSpectators(par);
30✔
1029
        }
1030
        else {
1031
                if ( CleanExpr(0) ) RetCode = -1;
3,680✔
1032
                if ( AC.DidClean ) CompactifyTree(AC.exprnames,EXPRNAMES);
3,680✔
1033
                ResetVariables(0);
3,680✔
1034
                CleanUpSort(-1);
3,680✔
1035
        }
1036
        clearcbuf(AC.cbufnum);
3,710✔
1037
        if ( AC.MultiBracketBuf != 0 ) {
3,710✔
1038
          for ( i = 0; i < MAXMULTIBRACKETLEVELS; i++ ) {
×
1039
                if ( AC.MultiBracketBuf[i] ) {
×
1040
                        M_free(AC.MultiBracketBuf[i],"bracket buffer i");
×
1041
                        AC.MultiBracketBuf[i] = 0;
×
1042
                }
1043
          }
1044
          AC.MultiBracketLevels = 0;
×
1045
          M_free(AC.MultiBracketBuf,"multi bracket buffer");
×
1046
          AC.MultiBracketBuf = 0;
×
1047
        }
1048

1049
        if ( AC.SortReallocateFlag ) {
3,710✔
1050
                /* Reallocate the sort buffers to reduce resident set usage */
1051
                /* AT.SS is the same as AT.S0 here */
1052
                SORTING* S = AT.S0;
24✔
1053
                M_free(S->lBuffer, "SortReallocate lBuffer+sBuffer");
24✔
1054
                S->lBuffer = Malloc1(sizeof(*(S->lBuffer))*(S->LargeSize+S->SmallEsize), "SortReallocate lBuffer+sBuffer");
24✔
1055
                S->lTop = S->lBuffer+S->LargeSize;
24✔
1056
                S->sBuffer = S->lTop;
24✔
1057
                if ( S->LargeSize == 0 ) { S->lBuffer = 0; S->lTop = 0; }
24✔
1058
                S->sTop = S->sBuffer + S->SmallSize;
24✔
1059
                S->sTop2 = S->sBuffer + S->SmallEsize;
24✔
1060
                S->sHalf = S->sBuffer + (LONG)((S->SmallSize+S->SmallEsize)>>1);
24✔
1061

1062
#ifdef WITHPTHREADS
1063
                /* We have to re-set the pointers into master lBuffer in the SortBlocks */
1064
                UpdateSortBlocks(AM.totalnumberofthreads-1);
16✔
1065

1066
                /* The SortBots do not have a real sort buffer to reallocate. */
1067
                /* AB[0] has been reallocated above already. */
1068
                for ( i = 1; i < AM.totalnumberofthreads; i++ ) {
80✔
1069
                        SORTING* S = AB[i]->T.S0;
48✔
1070
                        M_free(S->lBuffer, "SortReallocate lBuffer+sBuffer");
48✔
1071
                        S->lBuffer = Malloc1(sizeof(*(S->lBuffer))*(S->LargeSize+S->SmallEsize), "SortReallocate lBuffer+sBuffer");
48✔
1072
                        S->lTop = S->lBuffer+S->LargeSize;
48✔
1073
                        S->sBuffer = S->lTop;
48✔
1074
                        if ( S->LargeSize == 0 ) { S->lBuffer = 0; S->lTop = 0; }
48✔
1075
                        S->sTop = S->sBuffer + S->SmallSize;
48✔
1076
                        S->sTop2 = S->sBuffer + S->SmallEsize;
48✔
1077
                        S->sHalf = S->sBuffer + (LONG)((S->SmallSize+S->SmallEsize)>>1);
48✔
1078
                }
1079
#endif
1080
        }
1081
        if ( AC.SortReallocateFlag == 2 ) {
3,710✔
1082
                /* The Flag was set for a single module by the preprocessor #sortreallocate,
1083
                   so turn it off again. */
1084
                AC.SortReallocateFlag = 0;
6✔
1085
        }
1086

1087
        return(RetCode);
1088
}
1089

1090
/*
1091
                 #] DoExecute : 
1092
                 #[ PutBracket :
1093

1094
        Routine uses the bracket info to split a term into two pieces:
1095
        1: the part outside the bracket, and
1096
        2: the part inside the bracket.
1097
        These parts are separated by a subterm of type HAAKJE.
1098
        This subterm looks like: HAAKJE,3,level
1099
        The level is used for nestings of brackets. The print routines
1100
        cannot handle this yet (31-Mar-1988).
1101

1102
        The Bracket selector is in AT.BrackBuf in the form of a regular term,
1103
        but without coefficient.
1104
        When AR.BracketOn < 0 we have a socalled antibracket. The main effect
1105
        is an exchange of the inner and outer part and where the coefficient goes.
1106

1107
        Routine recoded to facilitate b p1,p2; etc for dotproducts and tensors
1108
        15-oct-1991
1109
*/
1110

1111
WORD PutBracket(PHEAD WORD *termin)
82,404✔
1112
{
1113
        GETBIDENTITY
1114
        WORD *t, *t1, *b, i, j, *lastfun;
82,404✔
1115
        WORD *t2, *s1, *s2;
82,404✔
1116
        WORD *bStop, *bb, *bf, *tStop;
82,404✔
1117
        WORD *term1,*term2, *m1, *m2, *tStopa;
82,404✔
1118
        WORD *bbb = 0, *bind, *binst = 0, bwild = 0, *bss = 0, *bns = 0, bset = 0;
82,404✔
1119
        term1 = AT.WorkPointer+1;
82,404✔
1120
        term2 = (WORD *)(((UBYTE *)(term1)) + AM.MaxTer);
82,404✔
1121
        if ( ( (WORD *)(((UBYTE *)(term2)) + AM.MaxTer) ) > AT.WorkTop ) return(MesWork());
82,404✔
1122
        if ( AR.BracketOn < 0 ) {
82,404✔
1123
                t2 = term1; t1 = term2;                /* AntiBracket */
1124
        }
1125
        else {
1126
                t1 = term1; t2 = term2;                /* Regular bracket */
82,356✔
1127
        }
1128
        b = AT.BrackBuf; bStop = b+*b; b++;
82,404✔
1129
        while ( b < bStop ) {
169,824✔
1130
                if ( *b == INDEX ) { bwild = 1; bbb = b+2; binst = b + b[1]; }
87,420✔
1131
                if ( *b == SETSET ) { bset = 1; bss = b+2; bns = b + b[1]; }
87,420✔
1132
                b += b[1];
87,420✔
1133
        }
1134

1135
        t = termin; tStopa = t + *t; i = *(t + *t -1); i = ABS(i);
82,404✔
1136
        if ( AR.PolyFun && AT.PolyAct ) tStop = termin + AT.PolyAct;
82,404✔
1137
#ifdef WITHFLOAT
1138
        else if ( AT.FloatPos ) tStop = termin + AT.FloatPos;
82,404✔
1139
#endif
1140
        else tStop = tStopa - i;
82,404✔
1141
        t++;
82,404✔
1142
        if ( AR.BracketOn < 0 ) {
82,404✔
1143
                lastfun = 0;
48✔
1144
                while ( t < tStop && *t >= FUNCTION
30✔
1145
                        && functions[*t-FUNCTION].commute ) {
54✔
1146
                        b = AT.BrackBuf+1;
1147
                        while ( b < bStop ) {
×
1148
                                if ( *b == *t ) {
×
1149
                                        lastfun = t;
×
1150
                                        while ( t < tStop && *t >= FUNCTION
×
1151
                                                && functions[*t-FUNCTION].commute ) t += t[1];
×
1152
                                        goto NextNcom1;
×
1153
                                }
1154
                                b += b[1];
×
1155
                        }
1156
                        if ( bset ) {
×
1157
                                b = bss;
1158
                                while ( b < bns ) {
×
1159
                                        if ( b[1] == CFUNCTION ) { /* Set of functions */
×
1160
                                                SETS set = Sets+b[0]; WORD i;
×
1161
                                                for ( i = set->first; i < set->last; i++ ) {
×
1162
                                                        if ( SetElements[i] == *t ) {
×
1163
                                                                lastfun = t;
×
1164
                                                                while ( t < tStop && *t >= FUNCTION
×
1165
                                                                        && functions[*t-FUNCTION].commute ) t += t[1];
×
1166
                                                                goto NextNcom1;
×
1167
                                                        }
1168
                                                }
1169
                                        }
1170
                                        b += 2;
×
1171
                                }
1172
                        }
1173
                        if ( bwild && *t >= FUNCTION && functions[*t-FUNCTION].spec ) {
×
1174
                                s1 = t + t[1];
×
1175
                                s2 = t + FUNHEAD;
×
1176
                                while ( s2 < s1 ) {
×
1177
                                        bind = bbb;
1178
                                        while ( bind < binst ) {
×
1179
                                                if ( *bind == *s2 ) {
×
1180
                                                        lastfun = t;
×
1181
                                                        while ( t < tStop && *t >= FUNCTION
×
1182
                                                                && functions[*t-FUNCTION].commute ) t += t[1];
×
1183
                                                        goto NextNcom1;
×
1184
                                                }
1185
                                                bind++;
×
1186
                                        }
1187
                                        s2++;
×
1188
                                }
1189
                        }
1190
                        t += t[1];
×
1191
                }
1192
NextNcom1:
48✔
1193
                s1 = termin + 1;
48✔
1194
                if ( lastfun ) {
48✔
1195
                        while ( s1 < lastfun ) *t2++ = *s1++;
×
1196
                        while ( s1 < t ) *t1++ = *s1++;
×
1197
                }
1198
                else {
1199
                        while ( s1 < t ) *t2++ = *s1++;
48✔
1200
                }
1201

1202
        }
1203
        else {
1204
                lastfun = t;
1205
                while ( t < tStop && *t >= FUNCTION
82,326✔
1206
                        && functions[*t-FUNCTION].commute ) {
162,054✔
1207
                        b = AT.BrackBuf+1;
1208
                        while ( b < bStop ) {
30✔
1209
                                if ( *b == *t ) { lastfun = t + t[1]; goto NextNcom; }
18✔
1210
                                b += b[1];
12✔
1211
                        }
1212
                        if ( bset ) {
12✔
1213
                                b = bss;
1214
                                while ( b < bns ) {
×
1215
                                        if ( b[1] == CFUNCTION ) { /* Set of functions */
×
1216
                                                SETS set = Sets+b[0]; WORD i;
×
1217
                                                for ( i = set->first; i < set->last; i++ ) {
×
1218
                                                        if ( SetElements[i] == *t ) {
×
1219
                                                                lastfun = t + t[1];
×
1220
                                                                goto NextNcom;
×
1221
                                                        }
1222
                                                }
1223
                                        }
1224
                                        b += 2;
×
1225
                                }
1226
                        }
1227
                        if ( bwild && *t >= FUNCTION && functions[*t-FUNCTION].spec ) {
12✔
1228
                                s1 = t + t[1];
×
1229
                                s2 = t + FUNHEAD;
×
1230
                                while ( s2 < s1 ) {
×
1231
                                        bind = bbb;
1232
                                        while ( bind < binst ) {
×
1233
                                                if ( *bind == *s2 ) { lastfun = t + t[1]; goto NextNcom; }
×
1234
                                                bind++;
×
1235
                                        }
1236
                                        s2++;
×
1237
                                }
1238
                        }
1239
NextNcom:
12✔
1240
                        t += t[1];
18✔
1241
                }
1242
                s1 = termin + 1;
1243
                while ( s1 < lastfun ) *t1++ = *s1++;
82,476✔
1244
                while ( s1 < t ) *t2++ = *s1++;
82,422✔
1245
        }
1246
/*
1247
        Now we have only commuting functions left. Move the b pointer to them.
1248
*/
1249
        b = AT.BrackBuf + 1;
82,404✔
1250
        while ( b < bStop && *b >= FUNCTION
164,808✔
1251
                && ( *b < FUNCTION || functions[*b-FUNCTION].commute ) ) {
155,694✔
1252
                b += b[1];
6✔
1253
        }
1254
        bf = b;
1255

1256
        while ( t < tStop && ( bf < bStop || bwild || bset ) ) {
165,390✔
1257
                b = bf;
1258
                while ( b < bStop && *b != *t ) { b += b[1]; }
252,222✔
1259
                i = t[1];
165,390✔
1260
                if ( *t >= FUNCTION ) { /* We are in function territory */
165,390✔
1261
                        if ( b < bStop && *b == *t ) goto FunBrac;
146,508✔
1262
                        if ( bset ) {
73,158✔
1263
                                b = bss;
1264
                                while ( b < bns ) {
×
1265
                                        if ( b[1] == CFUNCTION ) { /* Set of functions */
×
1266
                                                SETS set = Sets+b[0]; WORD i;
×
1267
                                                for ( i = set->first; i < set->last; i++ ) {
×
1268
                                                        if ( SetElements[i] == *t ) goto FunBrac;
×
1269
                                                }
1270
                                        }
1271
                                        b += 2;
×
1272
                                }
1273
                        }
1274
                        if ( bwild && *t >= FUNCTION && functions[*t-FUNCTION].spec ) {
73,158✔
1275
                                s1 = t + t[1];
×
1276
                                s2 = t + FUNHEAD;
×
1277
                                while ( s2 < s1 ) {
×
1278
                                        bind = bbb;
1279
                                        while ( bind < binst ) {
×
1280
                                                if ( *bind == *s2 ) goto FunBrac;
×
1281
                                                bind++;
×
1282
                                        }
1283
                                        s2++;
×
1284
                                }
1285
                        }
1286
                        NCOPY(t2,t,i);
702,396✔
1287
                        continue;
73,158✔
1288
FunBrac:        NCOPY(t1,t,i);
641,124✔
1289
                        continue;
73,350✔
1290
                }
1291
/*
1292
        We have left: DELTA, INDEX, VECTOR, DOTPRODUCT, SYMBOL
1293
*/
1294
                if ( *t == DELTA ) {
18,882✔
1295
                        if ( b < bStop && *b == DELTA ) {
×
1296
                                b += b[1];
×
1297
                                NCOPY(t1,t,i);
×
1298
                        }
1299
                        else { NCOPY(t2,t,i); }
×
1300
                }
1301
                else if ( *t == INDEX ) {
1302
                        if ( bwild ) {
12✔
1303
                                m1 = t1; m2 = t2;
×
1304
                                *t1++ = *t; t1++; *t2++ = *t; t2++;
×
1305
                                bind = bbb;
×
1306
                                j = t[1] -2;
×
1307
                                t += 2;
×
1308
                                while ( --j >= 0 ) {
×
1309
                                        while ( *bind < *t && bind < binst ) bind++;
×
1310
                                        if ( *bind == *t && bind < binst ) {
×
1311
                                                *t1++ = *t++;
×
1312
                                        }
1313
                                        else if ( bset ) {
×
1314
                                                WORD *b3 = bss;
1315
                                                while ( b3 < bns ) {
×
1316
                                                        if ( b3[1] == CVECTOR ) {
×
1317
                                                                SETS set = Sets+b3[0]; WORD i;
×
1318
                                                                for ( i = set->first; i < set->last; i++ ) {
×
1319
                                                                        if ( SetElements[i] == *t ) {
×
1320
                                                                                *t1++ = *t++;
×
1321
                                                                                goto nextind;
×
1322
                                                                        }
1323
                                                                }
1324
                                                        }
1325
                                                        b3 += 2;
×
1326
                                                }
1327
                                                *t2++ = *t++;
×
1328
                                        }
1329
                                        else *t2++ = *t++;
×
1330
nextind:;
×
1331
                                }
1332
                                m1[1] = WORDDIF(t1,m1);
×
1333
                                if ( m1[1] == 2 ) t1 = m1;
×
1334
                                m2[1] = WORDDIF(t2,m2);
×
1335
                                if ( m2[1] == 2 ) t2 = m2;
×
1336
                        }
1337
                        else if ( bset ) {
12✔
1338
                                m1 = t1; m2 = t2;
×
1339
                                *t1++ = *t; t1++; *t2++ = *t; t2++;
×
1340
                                j = t[1] -2;
×
1341
                                t += 2;
×
1342
                                while ( --j >= 0 ) {
×
1343
                                        WORD *b3 = bss;
1344
                                        while ( b3 < bns ) {
×
1345
                                                if ( b3[1] == CVECTOR ) {
×
1346
                                                        SETS set = Sets+b3[0]; WORD i;
×
1347
                                                        for ( i = set->first; i < set->last; i++ ) {
×
1348
                                                                if ( SetElements[i] == *t ) {
×
1349
                                                                        *t1++ = *t++;
×
1350
                                                                        goto nextind2;
×
1351
                                                                }
1352
                                                        }
1353
                                                }
1354
                                                b3 += 2;
×
1355
                                        }
1356
                                        *t2++ = *t++;
×
1357
nextind2:;
×
1358
                                }
1359
                                m1[1] = WORDDIF(t1,m1);
×
1360
                                if ( m1[1] == 2 ) t1 = m1;
×
1361
                                m2[1] = WORDDIF(t2,m2);
×
1362
                                if ( m2[1] == 2 ) t2 = m2;
×
1363
                        }
1364
                        else {
1365
                                NCOPY(t2,t,i);
48✔
1366
                        }
1367
                }
1368
                else if ( *t == VECTOR ) {
1369
                        if ( ( b < bStop && *b == VECTOR ) || bwild ) {
18✔
1370
                                if ( b < bStop && *b == VECTOR ) {
×
1371
                                        bb = b + b[1]; b += 2;
×
1372
                                }
1373
                                else bb = b;
1374
                                j = t[1] - 2;
×
1375
                                m1 = t1; m2 = t2; *t1++ = *t; *t2++ = *t; t1++; t2++; t += 2;
×
1376
                                while ( j > 0 ) {
×
1377
                                        j -= 2;
×
1378
                                        while ( b < bb && ( *b < *t ||
×
1379
                                        ( *b == *t && b[1] < t[1] ) ) ) b += 2;
×
1380
                                        if ( b < bb && ( *t == *b && t[1] == b[1] ) ) {
×
1381
                                                *t1++ = *t++; *t1++ = *t++; goto nextvec;
×
1382
                                        }
1383
                                        else if ( bwild ) {
×
1384
                                                bind = bbb;
1385
                                                while ( bind < binst ) {
×
1386
                                                        if ( *t == *bind || t[1] == *bind ) {
×
1387
                                                                *t1++ = *t++; *t1++ = *t++;
×
1388
                                                                goto nextvec;
×
1389
                                                        }
1390
                                                        bind++;
×
1391
                                                }
1392
                                        }
1393
                                        if ( bset ) {
×
1394
                                                WORD *b3 = bss;
1395
                                                while ( b3 < bns ) {
×
1396
                                                        if ( b3[1] == CVECTOR ) {
×
1397
                                                                SETS set = Sets+b3[0]; WORD i;
×
1398
                                                                for ( i = set->first; i < set->last; i++ ) {
×
1399
                                                                        if ( SetElements[i] == *t ) {
×
1400
                                                                                *t1++ = *t++; *t1++ = *t++;
×
1401
                                                                                goto nextvec;
×
1402
                                                                        }
1403
                                                                }
1404
                                                        }
1405
                                                        b3 += 2;
×
1406
                                                }
1407
                                        }
1408
                                        *t2++ = *t++; *t2++ = *t++;
×
1409
nextvec:;
×
1410
                                }
1411
                                m1[1] = WORDDIF(t1,m1);
×
1412
                                if ( m1[1] == 2 ) t1 = m1;
×
1413
                                m2[1] = WORDDIF(t2,m2);
×
1414
                                if ( m2[1] == 2 ) t2 = m2;
×
1415
                        }
1416
                        else if ( bset ) {
18✔
1417
                                m1 = t1; *t1++ = *t; t1++;
×
1418
                                m2 = t2; *t2++ = *t; t2++;
×
1419
                                s2 = t + i; t += 2;
×
1420
                                while ( t < s2 ) {
×
1421
                                        WORD *b3 = bss;
1422
                                        while ( b3 < bns ) {
×
1423
                                                if ( b3[1] == CVECTOR ) {
×
1424
                                                        SETS set = Sets+b3[0]; WORD i;
×
1425
                                                        for ( i = set->first; i < set->last; i++ ) {
×
1426
                                                                if ( SetElements[i] == *t ) {
×
1427
                                                                        *t1++ = *t++; *t1++ = *t++;
×
1428
                                                                        goto nextvec2;
×
1429
                                                                }
1430
                                                        }
1431
                                                }
1432
                                                b3 += 2;
×
1433
                                        }
1434
                                        *t2++ = *t++; *t2++ = *t++;
×
1435
nextvec2:;
×
1436
                                }
1437
                                m1[1] = WORDDIF(t1,m1);
×
1438
                                if ( m1[1] == 2 ) t1 = m1;
×
1439
                                m2[1] = WORDDIF(t2,m2);
×
1440
                                if ( m2[1] == 2 ) t2 = m2;
×
1441
                        }
1442
                        else {
1443
                                NCOPY(t2,t,i);
90✔
1444
                        }
1445
                }
1446
                else if ( *t == DOTPRODUCT ) {
1447
                        if ( ( b < bStop && *b == *t ) || bwild ) {
12✔
1448
                                m1 = t1; *t1++ = *t; t1++;
×
1449
                                m2 = t2; *t2++ = *t; t2++;
×
1450
                                if ( b >= bStop || *b != *t ) { bb = b; s1 = b; }
×
1451
                                else {
1452
                                        s1 = b + b[1]; bb = b + 2;
×
1453
                                }
1454
                                s2 = t + i; t += 2;
×
1455
                                while ( t < s2 && ( bb < s1 || bwild || bset ) ) {
×
1456
                                        while ( bb < s1 && ( *bb < *t ||
×
1457
                                        ( *bb == *t && bb[1] < t[1] ) ) ) bb += 3;
×
1458
                                        if ( bb < s1 && *bb == *t && bb[1] == t[1] ) {
×
1459
                                                *t1++ = *t++; *t1++ = *t++; *t1++ = *t++; bb += 3;
×
1460
                                                goto nextdot;
×
1461
                                        }
1462
                                        else if ( bwild ) {
×
1463
                                                bind = bbb;
1464
                                                while ( bind < binst ) {
×
1465
                                                        if ( *bind == *t || *bind == t[1] ) {
×
1466
                                                                *t1++ = *t++; *t1++ = *t++; *t1++ = *t++;
×
1467
                                                                goto nextdot;
×
1468
                                                        }
1469
                                                        bind++;
×
1470
                                                }
1471
                                        }
1472
                                        if ( bset ) {
×
1473
                                                WORD *b3 = bss;
1474
                                                while ( b3 < bns ) {
×
1475
                                                        if ( b3[1] == CVECTOR ) {
×
1476
                                                                SETS set = Sets+b3[0]; WORD i;
×
1477
                                                                for ( i = set->first; i < set->last; i++ ) {
×
1478
                                                                        if ( SetElements[i] == *t || SetElements[i] == t[1] ) {
×
1479
                                                                                *t1++ = *t++; *t1++ = *t++; *t1++ = *t++;
×
1480
                                                                                goto nextdot;
×
1481
                                                                        }
1482
                                                                }
1483
                                                        }
1484
                                                        b3 += 2;
×
1485
                                                }
1486
                                        }
1487
                                        *t2++ = *t++; *t2++ = *t++; *t2++ = *t++;
×
1488
nextdot:;
×
1489
                                }
1490
                                while ( t < s2 ) *t2++ = *t++;
×
1491
                                m1[1] = WORDDIF(t1,m1);
×
1492
                                if ( m1[1] == 2 ) t1 = m1;
×
1493
                                m2[1] = WORDDIF(t2,m2);
×
1494
                                if ( m2[1] == 2 ) t2 = m2;
×
1495
                        }
1496
                        else if ( bset ) {
12✔
1497
                                m1 = t1; *t1++ = *t; t1++;
×
1498
                                m2 = t2; *t2++ = *t; t2++;
×
1499
                                s2 = t + i; t += 2;
×
1500
                                while ( t < s2 ) {
×
1501
                                        WORD *b3 = bss;
1502
                                        while ( b3 < bns ) {
×
1503
                                                if ( b3[1] == CVECTOR ) {
×
1504
                                                        SETS set = Sets+b3[0]; WORD i;
×
1505
                                                        for ( i = set->first; i < set->last; i++ ) {
×
1506
                                                                if ( SetElements[i] == *t || SetElements[i] == t[1] ) {
×
1507
                                                                        *t1++ = *t++; *t1++ = *t++; *t1++ = *t++;
×
1508
                                                                        goto nextdot2;
×
1509
                                                                }
1510
                                                        }
1511
                                                }
1512
                                                b3 += 2;
×
1513
                                        }
1514
                                        *t2++ = *t++; *t2++ = *t++; *t2++ = *t++;
×
1515
nextdot2:;
×
1516
                                }
1517
                                m1[1] = WORDDIF(t1,m1);
×
1518
                                if ( m1[1] == 2 ) t1 = m1;
×
1519
                                m2[1] = WORDDIF(t2,m2);
×
1520
                                if ( m2[1] == 2 ) t2 = m2;
×
1521
                        }
1522
                        else { NCOPY(t2,t,i); }
72✔
1523
                }
1524
                else if ( *t == SYMBOL ) {
1525
                        if ( b < bStop && *b == *t ) {
18,840✔
1526
                                m1 = t1; *t1++ = *t; t1++;
5,832✔
1527
                                m2 = t2; *t2++ = *t; t2++;
5,832✔
1528
                                s1 = b + b[1]; bb = b+2;
5,832✔
1529
                                s2 = t + i; t += 2;
5,832✔
1530
                                while ( bb < s1 && t < s2 ) {
5,832✔
1531
                                        while ( bb < s1 && *bb < *t ) bb += 2;
9,228✔
1532
                                        if ( bb >= s1 ) {
7,518✔
1533
                                                if ( bset ) goto TrySymbolSet;
1,710✔
1534
                                                break;
1535
                                        }
1536
                                        if ( *bb == *t ) { *t1++ = *t++; *t1++ = *t++; }
5,808✔
1537
                                        else if ( bset ) {
24✔
1538
                                                WORD *bbb;
1539
TrySymbolSet:
×
1540
                                                bbb = bss;
1541
                                                while ( bbb < bns ) {
×
1542
                                                        if ( bbb[1] == CSYMBOL ) { /* Set of symbols */
×
1543
                                                                SETS set = Sets+bbb[0]; WORD i;
×
1544
                                                                for ( i = set->first; i < set->last; i++ ) {
×
1545
                                                                        if ( SetElements[i] == *t ) {
×
1546
                                                                                *t1++ = *t++; *t1++ = *t++;
×
1547
                                                                                goto NextSymbol;
×
1548
                                                                        }
1549
                                                                }
1550
                                                        }
1551
                                                        bbb += 2;
×
1552
                                                }
1553
                                                *t2++ = *t++; *t2++ = *t++;
×
1554
                                        }
1555
                                        else { *t2++ = *t++; *t2++ = *t++; } 
24✔
1556
NextSymbol:;
11,640✔
1557
                                }
1558
                                while ( t < s2 ) *t2++ = *t++;
9,660✔
1559
                                m1[1] = WORDDIF(t1,m1);
5,832✔
1560
                                if ( m1[1] == 2 ) t1 = m1;
5,832✔
1561
                                m2[1] = WORDDIF(t2,m2);
5,832✔
1562
                                if ( m2[1] == 2 ) t2 = m2;
5,832✔
1563
                        }
1564
                        else if ( bset ) {
13,008✔
1565
                                WORD *bbb;
24✔
1566
                                m1 = t1; *t1++ = *t; t1++;
24✔
1567
                                m2 = t2; *t2++ = *t; t2++;
24✔
1568
                                s2 = t + i; t += 2;
24✔
1569
                                while ( t < s2 ) {
24✔
1570
                                        bbb = bss;
1571
                                        while ( bbb < bns ) {
72✔
1572
                                                if ( bbb[1] == CSYMBOL ) { /* Set of symbols */
48✔
1573
                                                        SETS set = Sets+bbb[0]; WORD i;
48✔
1574
                                                        for ( i = set->first; i < set->last; i++ ) {
108✔
1575
                                                                if ( SetElements[i] == *t ) {
84✔
1576
                                                                        *t1++ = *t++; *t1++ = *t++;
24✔
1577
                                                                        goto NextSymbol2;
24✔
1578
                                                                }
1579
                                                        }
1580
                                                }
1581
                                                bbb += 2;
24✔
1582
                                        }
1583
                                        *t2++ = *t++; *t2++ = *t++;
24✔
1584
NextSymbol2:;
72✔
1585
                                }
1586
                                m1[1] = WORDDIF(t1,m1);
24✔
1587
                                if ( m1[1] == 2 ) t1 = m1;
24✔
1588
                                m2[1] = WORDDIF(t2,m2);
24✔
1589
                                if ( m2[1] == 2 ) t2 = m2;
24✔
1590
                        }
1591
                        else { NCOPY(t2,t,i); }
88,056✔
1592
                }
1593
                else {
1594
                        NCOPY(t2,t,i);
247,794✔
1595
                }
1596
        }
1597
        if ( ( i = WORDDIF(tStop,t) ) > 0 ) NCOPY(t2,t,i);
82,404✔
1598
        if ( AR.BracketOn < 0 ) {
82,404✔
1599
                s1 = t1; t1 = t2; t2 = s1;
48✔
1600
        }
1601
        do { *t2++ = *t++; } while ( t < (WORD *)tStopa );
247,224✔
1602
        t = AT.WorkPointer;
82,404✔
1603
        i = WORDDIF(t1,term1);
82,404✔
1604
        *t++ = 4 + i + WORDDIF(t2,term2);
82,404✔
1605
        t += i;
82,404✔
1606
        *t++ = HAAKJE;
82,404✔
1607
        *t++ = 3;
82,404✔
1608
        *t++ = 0;                        /* This feature won't be used for a while */
82,404✔
1609
        i = WORDDIF(t2,term2);
82,404✔
1610
        t1 = term2;
82,404✔
1611
        if ( i > 0 ) NCOPY(t,t1,i);
1,041,690✔
1612

1613
        AT.WorkPointer = t;
82,404✔
1614

1615
        return(0);
82,404✔
1616
}
1617

1618
/*
1619
                 #] PutBracket : 
1620
                 #[ SpecialCleanup :
1621
*/
1622

1623
void SpecialCleanup(PHEAD0)
3,826✔
1624
{
1625
        GETBIDENTITY
1626
        if ( AT.previousEfactor ) M_free(AT.previousEfactor,"Efactor cache");
3,826✔
1627
        AT.previousEfactor = 0;
3,826✔
1628
}
3,826✔
1629

1630
/*
1631
                 #] SpecialCleanup : 
1632
                 #[ SetMods :
1633
*/
1634

1635
#ifndef WITHPTHREADS
1636

1637
void SetMods(void)
2✔
1638
{
1639
        int i, n;
2✔
1640
        if ( AN.cmod != 0 ) M_free(AN.cmod,"AN.cmod");
2✔
1641
        n = ABS(AN.ncmod);
2✔
1642
        AN.cmod = (UWORD *)Malloc1(sizeof(WORD)*n,"AN.cmod");
2✔
1643
        for ( i = 0; i < n; i++ ) AN.cmod[i] = AC.cmod[i];
4✔
1644
}
2✔
1645

1646
#endif
1647

1648
/*
1649
                 #] SetMods : 
1650
                 #[ UnSetMods :
1651
*/
1652

1653
#ifndef WITHPTHREADS
1654

1655
void UnSetMods(void)
2✔
1656
{
1657
        if ( AN.cmod != 0 ) M_free(AN.cmod,"AN.cmod");
2✔
1658
        AN.cmod = 0;
2✔
1659
}
2✔
1660

1661
#endif
1662

1663
/*
1664
                 #] UnSetMods : 
1665
        #] DoExecute :
1666
        #[ Expressions :
1667
                 #[ ExchangeExpressions :
1668
*/
1669

1670
void ExchangeExpressions(int num1, int num2)
×
1671
{
1672
        GETIDENTITY
1673
        WORD node1, node2, namesize, TMproto[SUBEXPSIZE];
×
1674
        INDEXENTRY *ind;
×
1675
        EXPRESSIONS e1, e2;
×
1676
        LONG a;
×
1677
        SBYTE *s1, *s2;
×
1678
        int i;
×
1679
        e1 = Expressions + num1;
×
1680
        e2 = Expressions + num2;
×
1681
        node1 = e1->node;
×
1682
        node2 = e2->node;
×
1683
        AC.exprnames->namenode[node1].number = num2;
×
1684
        AC.exprnames->namenode[node2].number = num1;
×
1685
        a = e1->name; e1->name = e2->name; e2->name = a;
×
1686
        namesize = e1->namesize; e1->namesize = e2->namesize; e2->namesize = namesize;
×
1687
        e1->node = node2;
×
1688
        e2->node = node1;
×
1689
        if ( e1->status == STOREDEXPRESSION ) {
×
1690
/*
1691
                Find the name in the index and replace by the new name
1692
*/
1693
                TMproto[0] = EXPRESSION;
×
1694
                TMproto[1] = SUBEXPSIZE;
×
1695
                TMproto[2] = num1;
×
1696
                TMproto[3] = 1;
×
1697
                { int ie; for ( ie = 4; ie < SUBEXPSIZE; ie++ ) TMproto[ie] = 0; }
×
1698
                AT.TMaddr = TMproto;
×
1699
                ind = FindInIndex(num1,&AR.StoreData,0,0);
×
1700
                s1 = (SBYTE *)(AC.exprnames->namebuffer+e1->name);
×
1701
                i = e1->namesize;
×
1702
                s2 = ind->name;
×
1703
                NCOPY(s2,s1,i);
×
1704
                *s2 = 0;
×
1705
                SeekFile(AR.StoreData.Handle,&(e1->onfile),SEEK_SET);
×
1706
                if ( WriteFile(AR.StoreData.Handle,(UBYTE *)ind,
×
1707
                (LONG)(sizeof(INDEXENTRY))) != sizeof(INDEXENTRY) ) {
1708
                        MesPrint("File error while exchanging expressions");
×
1709
                        Terminate(-1);
×
1710
                }
1711
                FlushFile(AR.StoreData.Handle);
×
1712
        }
1713
        if ( e2->status == STOREDEXPRESSION ) {
×
1714
/*
1715
                Find the name in the index and replace by the new name
1716
*/
1717
                TMproto[0] = EXPRESSION;
×
1718
                TMproto[1] = SUBEXPSIZE;
×
1719
                TMproto[2] = num2;
×
1720
                TMproto[3] = 1;
×
1721
                { int ie; for ( ie = 4; ie < SUBEXPSIZE; ie++ ) TMproto[ie] = 0; }
×
1722
                AT.TMaddr = TMproto;
×
1723
                ind = FindInIndex(num1,&AR.StoreData,0,0);
×
1724
                s1 = (SBYTE *)(AC.exprnames->namebuffer+e2->name);
×
1725
                i = e2->namesize;
×
1726
                s2 = ind->name;
×
1727
                NCOPY(s2,s1,i);
×
1728
                *s2 = 0;
×
1729
                SeekFile(AR.StoreData.Handle,&(e2->onfile),SEEK_SET);
×
1730
                if ( WriteFile(AR.StoreData.Handle,(UBYTE *)ind,
×
1731
                (LONG)(sizeof(INDEXENTRY))) != sizeof(INDEXENTRY) ) {
1732
                        MesPrint("File error while exchanging expressions");
×
1733
                        Terminate(-1);
×
1734
                }
1735
                FlushFile(AR.StoreData.Handle);
×
1736
        }
1737
}
×
1738

1739
/*
1740
                 #] ExchangeExpressions : 
1741
                 #[ GetFirstBracket :
1742
*/
1743

1744
int GetFirstBracket(WORD *term, int num)
6✔
1745
{
1746
/*
1747
                Gets the first bracket of the expression 'num'
1748
                Puts it in term. If no brackets the answer is one.
1749
                Routine should be thread-safe
1750
*/
1751
        GETIDENTITY
4✔
1752
        POSITION position, oldposition;
6✔
1753
        RENUMBER renumber;
6✔
1754
        FILEHANDLE *fi;
6✔
1755
        WORD type, *oldcomppointer, oldonefile, numword;
6✔
1756
        WORD *t, *tstop;
6✔
1757

1758
        oldcomppointer = AR.CompressPointer;
6✔
1759
        type = Expressions[num].status;
6✔
1760
        if ( type == STOREDEXPRESSION ) {
6✔
1761
                WORD TMproto[SUBEXPSIZE];
×
1762
                TMproto[0] = EXPRESSION;
×
1763
                TMproto[1] = SUBEXPSIZE;
×
1764
                TMproto[2] = num;
×
1765
                TMproto[3] = 1;
×
1766
                { int ie; for ( ie = 4; ie < SUBEXPSIZE; ie++ ) TMproto[ie] = 0; }
×
1767
                AT.TMaddr = TMproto;
×
1768
                PUTZERO(position);
×
1769
                if ( ( renumber = GetTable(num,&position,0) ) == 0 ) {
×
1770
                        MesCall("GetFirstBracket");
×
1771
                        SETERROR(-1)
×
1772
                }
1773
                if ( GetFromStore(term,&position,renumber,&numword,num) < 0 ) {
×
1774
                        MesCall("GetFirstBracket");
×
1775
                        SETERROR(-1)
×
1776
                }
1777
/*
1778
#ifdef WITHPTHREADS
1779
*/
1780
                if ( renumber->symb.lo != AN.dummyrenumlist )
×
1781
                        M_free(renumber->symb.lo,"VarSpace");
×
1782
                M_free(renumber,"Renumber");
×
1783
/*
1784
#endif
1785
*/
1786
        }
1787
        else {                        /* Active expression */
1788
                oldonefile = AR.GetOneFile;
6✔
1789
                if ( type == HIDDENLEXPRESSION || type == HIDDENGEXPRESSION ) {
6✔
1790
                        AR.GetOneFile = 2; fi = AR.hidefile;
×
1791
                }
1792
                else {
1793
                        AR.GetOneFile = 0; fi = AR.infile;
6✔
1794
                }
1795
                if ( fi->handle >= 0 ) {
6✔
1796
                        PUTZERO(oldposition);
×
1797
/*
1798
                        SeekFile(fi->handle,&oldposition,SEEK_CUR);
1799
*/
1800
                        }
1801
                else {
1802
                        SETBASEPOSITION(oldposition,fi->POfill-fi->PObuffer);
6✔
1803
                }
1804
                position = AS.OldOnFile[num];
6✔
1805
                if ( GetOneTerm(BHEAD term,fi,&position,1) < 0
6✔
1806
                || ( GetOneTerm(BHEAD term,fi,&position,1) < 0 ) ) {
6✔
1807
                        MLOCK(ErrorMessageLock);
×
1808
                        MesCall("GetFirstBracket");
×
1809
                        MUNLOCK(ErrorMessageLock);
×
1810
                        SETERROR(-1)
×
1811
                }
1812
                if ( fi->handle >= 0 ) {
6✔
1813
/*
1814
                        SeekFile(fi->handle,&oldposition,SEEK_SET);
1815
                        if ( ISNEGPOS(oldposition) ) {
1816
                                MLOCK(ErrorMessageLock);
1817
                                MesPrint("File error");
1818
                                MUNLOCK(ErrorMessageLock);
1819
                                SETERROR(-1)
1820
                        }
1821
*/
1822
                }
1823
                else {
1824
                        fi->POfill = fi->PObuffer+BASEPOSITION(oldposition);
6✔
1825
                }
1826
                AR.GetOneFile = oldonefile;
6✔
1827
        }
1828
        AR.CompressPointer = oldcomppointer;
6✔
1829
        if ( *term ) {
6✔
1830
                tstop = term + *term; tstop -= ABS(tstop[-1]);
6✔
1831
                t = term + 1;
6✔
1832
                while ( t < tstop ) {
12✔
1833
                        if ( *t == HAAKJE ) break;
12✔
1834
                        t += t[1];
6✔
1835
                }
1836
                if ( t >= tstop ) {
6✔
1837
                        term[0] = 4; term[1] = 1; term[2] = 1; term[3] = 3;
×
1838
                }
1839
                else {
1840
                        *t++ = 1; *t++ = 1; *t++ = 3; *term = t - term;
6✔
1841
                } 
1842
        }
1843
        else {
1844
                term[0] = 4; term[1] = 1; term[2] = 1; term[3] = 3;
×
1845
        }
1846
        return(*term);
6✔
1847
}
1848

1849
/*
1850
                 #] GetFirstBracket : 
1851
                 #[ GetFirstTerm :
1852
*/
1853

1854
/**
1855
 * Gets the first term of an expression. Routine should be thread safe.
1856
 *
1857
 * @param[out] term Pointer to the buffer where the term should be written.
1858
 * @param[in] num   The expression number from which to get the term.
1859
 * @param[in] pre   Denotes a pre-processor call (1) or not (0). Used to
1860
 *                  determine the correct source file for the expression.
1861
 * @return          First WORD of term, a negative value denotes an error.
1862
 */
1863
int GetFirstTerm(WORD *term, int num, int pre)
60✔
1864
{
1865
        GETIDENTITY
40✔
1866
        POSITION position, oldposition;
60✔
1867
        RENUMBER renumber;
60✔
1868
        FILEHANDLE *fi;
60✔
1869
        WORD type, *oldcomppointer, oldonefile, numword;
60✔
1870

1871
        oldcomppointer = AR.CompressPointer;
60✔
1872
        type = Expressions[num].status;
60✔
1873
        if ( type == STOREDEXPRESSION ) {
60✔
1874
                WORD TMproto[SUBEXPSIZE];
×
1875
                TMproto[0] = EXPRESSION;
×
1876
                TMproto[1] = SUBEXPSIZE;
×
1877
                TMproto[2] = num;
×
1878
                TMproto[3] = 1;
×
1879
                { int ie; for ( ie = 4; ie < SUBEXPSIZE; ie++ ) TMproto[ie] = 0; }
×
1880
                AT.TMaddr = TMproto;
×
1881
                PUTZERO(position);
×
1882
                if ( ( renumber = GetTable(num,&position,0) ) == 0 ) {
×
1883
                        MesCall("GetFirstTerm");
×
1884
                        SETERROR(-1)
×
1885
                }
1886
                if ( GetFromStore(term,&position,renumber,&numword,num) < 0 ) {
×
1887
                        MesCall("GetFirstTerm");
×
1888
                        SETERROR(-1)
×
1889
                }
1890
/*
1891
#ifdef WITHPTHREADS
1892
*/
1893
                if ( renumber->symb.lo != AN.dummyrenumlist )
×
1894
                        M_free(renumber->symb.lo,"VarSpace");
×
1895
                M_free(renumber,"Renumber");
×
1896
/*
1897
#endif
1898
*/
1899
        }
1900
        else {                        /* Active expression */
1901
                oldonefile = AR.GetOneFile;
60✔
1902
                if ( type == HIDDENLEXPRESSION || type == HIDDENGEXPRESSION ) {
60✔
1903
                        AR.GetOneFile = 2; fi = AR.hidefile;
18✔
1904
                }
1905
                else {
1906
                        AR.GetOneFile = 0;
42✔
1907
                        if ( Expressions[num].replace == NEWLYDEFINEDEXPRESSION ) {
42✔
1908
                                /* During execution, if the expression has already been processed it
1909
                                   will be in the outfile. If it has not, the usage is illegal according
1910
                                   to the manual, though no error is given. */
1911
                                if ( pre == 0 ) { fi = AR.outfile; }
12✔
1912
                                /* During preprocessing, the expression certainly has not been processed
1913
                                   yet. Print an error and terminate. */
1914
                                else {
1915
                                        MesPrint("&isnumerical: expression is not yet defined!");
6✔
1916
                                        SETERROR(-1);
12✔
1917
                                }
1918
                        }
1919
                        else {
1920
                                /* During execution, we should use the definition as stored at the end
1921
                                   of the previous module. This is in the infile. */
1922
                                if ( pre == 0 ) { fi = AR.infile; }
30✔
1923
                                /* During preprocessing, this function is called before the RevertScratch
1924
                                   at the beginning of this module's execution. Thus the expressions are
1925
                                   in the outfile of the previous module. */
1926
                                else { fi = AR.outfile; }
18✔
1927
                        }
1928
                }
1929
                if ( fi->handle >= 0 ) {
54✔
1930
                        PUTZERO(oldposition);
×
1931
/*
1932
                        SeekFile(fi->handle,&oldposition,SEEK_CUR);
1933
*/
1934
                        }
1935
                else {
1936
                        SETBASEPOSITION(oldposition,fi->POfill-fi->PObuffer);
54✔
1937
                }
1938
                position = AS.OldOnFile[num];
54✔
1939
                if ( GetOneTerm(BHEAD term,fi,&position,1) < 0
54✔
1940
                || ( GetOneTerm(BHEAD term,fi,&position,1) < 0 ) ) {
54✔
1941
                        MLOCK(ErrorMessageLock);
×
1942
                        MesCall("GetFirstTerm");
×
1943
                        MUNLOCK(ErrorMessageLock);
×
1944
                        SETERROR(-1)
×
1945
                }
1946
                if ( fi->handle >= 0 ) {
54✔
1947
/*
1948
                        SeekFile(fi->handle,&oldposition,SEEK_SET);
1949
                        if ( ISNEGPOS(oldposition) ) {
1950
                                MLOCK(ErrorMessageLock);
1951
                                MesPrint("File error");
1952
                                MUNLOCK(ErrorMessageLock);
1953
                                SETERROR(-1)
1954
                        }
1955
*/
1956
                }
1957
                else {
1958
                        fi->POfill = fi->PObuffer+BASEPOSITION(oldposition);
54✔
1959
                }
1960
                AR.GetOneFile = oldonefile;
54✔
1961
        }
1962
        AR.CompressPointer = oldcomppointer;
54✔
1963
        return(*term);
54✔
1964
}
1965

1966
/*
1967
                 #] GetFirstTerm : 
1968
                 #[ GetContent :
1969
*/
1970

1971
int GetContent(WORD *content, int num)
×
1972
{
1973
/*
1974
                Gets the content of the expression 'num'
1975
                Puts it in content.
1976
                Routine should be thread-safe
1977
                The content is defined as the term that will make the expression 'num'
1978
                with integer coefficients, no GCD and all common factors taken out,
1979
                all negative powers removed when we divide the expression by this
1980
                content.
1981
*/
1982
        GETIDENTITY
1983
        POSITION position, oldposition;
×
1984
        RENUMBER renumber;
×
1985
        FILEHANDLE *fi;
×
1986
        WORD type, *oldcomppointer, oldonefile, numword, *term, i;
×
1987
        WORD *cbuffer = TermMalloc("GetContent");
×
1988
        WORD *oldworkpointer = AT.WorkPointer;
×
1989

1990
        oldcomppointer = AR.CompressPointer;
×
1991
        type = Expressions[num].status;
×
1992
        if ( type == STOREDEXPRESSION ) {
×
1993
                WORD TMproto[SUBEXPSIZE];
×
1994
                TMproto[0] = EXPRESSION;
×
1995
                TMproto[1] = SUBEXPSIZE;
×
1996
                TMproto[2] = num;
×
1997
                TMproto[3] = 1;
×
1998
                { int ie; for ( ie = 4; ie < SUBEXPSIZE; ie++ ) TMproto[ie] = 0; }
×
1999
                AT.TMaddr = TMproto;
×
2000
                PUTZERO(position);
×
2001
                if ( ( renumber = GetTable(num,&position,0) ) == 0 ) goto CalledFrom;
×
2002
                if ( GetFromStore(cbuffer,&position,renumber,&numword,num) < 0 ) goto CalledFrom;
×
2003
                for(;;) {
×
2004
                        term = oldworkpointer;
×
2005
                        AR.CompressPointer = oldcomppointer;
×
2006
                        if ( GetFromStore(term,&position,renumber,&numword,num) < 0 ) goto CalledFrom;
×
2007
                        if ( *term == 0 ) break;
×
2008
/*
2009
                        'merge' the two terms
2010
*/
2011
                        if ( ContentMerge(BHEAD cbuffer,term) < 0 ) goto CalledFrom;
×
2012
                }
2013
/*
2014
#ifdef WITHPTHREADS
2015
*/
2016
                if ( renumber->symb.lo != AN.dummyrenumlist )
×
2017
                        M_free(renumber->symb.lo,"VarSpace");
×
2018
                M_free(renumber,"Renumber");
×
2019
/*
2020
#endif
2021
*/
2022
        }
2023
        else {                        /* Active expression */
2024
                oldonefile = AR.GetOneFile;
×
2025
                if ( type == HIDDENLEXPRESSION || type == HIDDENGEXPRESSION ) {
×
2026
                        AR.GetOneFile = 2; fi = AR.hidefile;
×
2027
                }
2028
                else {
2029
                        AR.GetOneFile = 0;
×
2030
                        if ( Expressions[num].replace == NEWLYDEFINEDEXPRESSION )
×
2031
                             fi = AR.outfile;
×
2032
                        else fi = AR.infile;
×
2033
                }
2034
                if ( fi->handle >= 0 ) {
×
2035
                        PUTZERO(oldposition);
×
2036
/*
2037
                        SeekFile(fi->handle,&oldposition,SEEK_CUR);
2038
*/
2039
                        }
2040
                else {
2041
                        SETBASEPOSITION(oldposition,fi->POfill-fi->PObuffer);
×
2042
                }
2043
                position = AS.OldOnFile[num];
×
2044
                if ( GetOneTerm(BHEAD cbuffer,fi,&position,1) < 0 ) goto CalledFrom;
×
2045
                AR.CompressPointer = oldcomppointer;
×
2046
                if ( GetOneTerm(BHEAD cbuffer,fi,&position,1) < 0 ) goto CalledFrom;
×
2047
/*
2048
                Now go through the terms. For each term we have to test whether
2049
                what is in cbuffer is also in that term. If not, we have to remove
2050
                it from cbuffer. Additionally we have to accumulate the GCD of the
2051
                numerators and the LCM of the denominators. This is all done in the
2052
                routine ContentMerge.
2053
*/
2054
                for(;;) {
×
2055
                        term = oldworkpointer;
×
2056
                        AR.CompressPointer = oldcomppointer;
×
2057
                        if ( GetOneTerm(BHEAD term,fi,&position,1) < 0 ) goto CalledFrom;
×
2058
                        if ( *term == 0 ) break;
×
2059
/*
2060
                        'merge' the two terms
2061
*/
2062
                        if ( ContentMerge(BHEAD cbuffer,term) < 0 ) goto CalledFrom;
×
2063
                }
2064
                if ( fi->handle < 0 ) {
×
2065
                        fi->POfill = fi->PObuffer+BASEPOSITION(oldposition);
×
2066
                }
2067
                AR.GetOneFile = oldonefile;
×
2068
        }
2069
        AR.CompressPointer = oldcomppointer;
×
2070
        for ( i = 0; i < *cbuffer; i++ ) content[i] = cbuffer[i];
×
2071
        TermFree(cbuffer,"GetContent");
×
2072
        AT.WorkPointer = oldworkpointer;
×
2073
        return(*content);
×
2074
CalledFrom:
×
2075
        MLOCK(ErrorMessageLock);
×
2076
        MesCall("GetContent");
×
2077
        MUNLOCK(ErrorMessageLock);
×
2078
        SETERROR(-1)
×
2079
}
2080

2081
/*
2082
                 #] GetContent : 
2083
                 #[ CleanupTerm :
2084

2085
                Removes noncommuting objects from the term
2086
*/
2087

2088
int CleanupTerm(WORD *term)
×
2089
{
2090
        WORD *tstop, *t, *tfill, *tt;
×
2091
        GETSTOP(term,tstop);
×
2092
        t = term+1;
×
2093
        while ( t < tstop ) {
×
2094
                if ( *t >= FUNCTION && ( functions[*t-FUNCTION].commute || *t == DENOMINATOR ) ) {
×
2095
                        tfill = t; tt = t + t[1]; tstop = term + *term;
×
2096
                        while ( tt < tstop ) *tfill++ = *tt++;
×
2097
                        *term = tfill - term;
×
2098
                        tstop -= ABS(tfill[-1]);
×
2099
                }
2100
                else {
2101
                        t += t[1];
×
2102
                }
2103
        }
2104
        return(0);
×
2105
}
2106

2107
/*
2108
                 #] CleanupTerm : 
2109
                 #[ ContentMerge :
2110
*/
2111

2112
WORD ContentMerge(PHEAD WORD *content, WORD *term)
24✔
2113
{
2114
        GETBIDENTITY
2115
        WORD *cstop, csize, crsize, sign = 1, numsize, densize, i, tnsize, tdsize;
24✔
2116
        UWORD *num, *den, *tnum, *tden;
24✔
2117
        WORD *outfill, *outb = TermMalloc("ContentMerge"), *ct;
24✔
2118
        WORD *t, *tstop, tsize, trsize, *told;
24✔
2119
        WORD *t1, *t2, *c1, *c2, i1, i2, *out1;
24✔
2120
        WORD didsymbol = 0, diddotp = 0, tfirst;
24✔
2121
        cstop = content + *content;
24✔
2122
        csize = cstop[-1];
24✔
2123
        if ( csize < 0 ) { sign = -sign; csize = -csize; }
24✔
2124
        cstop -= csize;
24✔
2125
        numsize = densize = crsize = (csize-1)/2;
24✔
2126
        num = NumberMalloc("ContentMerge");
24✔
2127
        den = NumberMalloc("ContentMerge");
24✔
2128
        for ( i = 0; i < numsize; i++ ) num[i] = (UWORD)(cstop[i]);
48✔
2129
        for ( i = 0; i < densize; i++ ) den[i] = (UWORD)(cstop[i+crsize]);
48✔
2130
        while ( num[numsize-1] == 0 ) numsize--;                
24✔
2131
        while ( den[densize-1] == 0 ) densize--;                
24✔
2132
/*
2133
        First we do the coefficient
2134
*/
2135
        tstop = term + *term;
24✔
2136
        tsize = tstop[-1];
24✔
2137
        if ( tsize < 0 ) tsize = -tsize;
24✔
2138
/*        else { sign = 1; } */
2139
        tstop = tstop - tsize;
24✔
2140
        tnsize = tdsize = trsize = (tsize-1)/2;
24✔
2141
        tnum = (UWORD *)tstop; tden = (UWORD *)(tstop + trsize);
24✔
2142
        while ( tnum[tnsize-1] == 0 ) tnsize--;
24✔
2143
        while ( tden[tdsize-1] == 0 ) tdsize--;
24✔
2144
        GcdLong(BHEAD num, numsize, tnum, tnsize, num, &numsize);
24✔
2145
        if ( LcmLong(BHEAD den, densize, tden, tdsize, den, &densize) ) goto CalledFrom;
24✔
2146
        outfill = outb + 1;
24✔
2147
        ct = content + 1;
24✔
2148
        t = term + 1;
24✔
2149
        while ( ct < cstop ) {
42✔
2150
                switch ( *ct ) {
18✔
2151
                        case SYMBOL:
2152
                                didsymbol = 1;
18✔
2153
                                t = term+1;
2154
                                while ( t < tstop && *t != *ct ) t += t[1];
18✔
2155
                                if ( t >= tstop ) break;
18✔
2156
                                t1 = t+2; t2 = t+t[1];
18✔
2157
                                c1 = ct+2; c2 = ct+ct[1];
18✔
2158
                                out1 = outfill; *outfill++ = *ct; outfill++;
18✔
2159
                                while ( c1 < c2 && t1 < t2 ) {
48✔
2160
                                        if ( *c1 == *t1 ) {
30✔
2161
                                                if ( t1[1] <= c1[1] ) {
12✔
2162
                                                        *outfill++ = *t1++; *outfill++ = *t1++;
6✔
2163
                                                        c1 += 2;
6✔
2164
                                                }
2165
                                                else {
2166
                                                        *outfill++ = *c1++; *outfill++ = *c1++;
6✔
2167
                                                        t1 += 2;
6✔
2168
                                                }
2169
                                        }
2170
                                        else if ( *c1 < *t1 ) {
18✔
2171
                                                if ( c1[1] < 0 ) {
6✔
2172
                                                        *outfill++ = *c1++; *outfill++ = *c1++;
6✔
2173
                                                }
2174
                                                else { c1 += 2; }
×
2175
                                        }
2176
                                        else {
2177
                                                if ( t1[1] < 0 ) {
12✔
2178
                                                        *outfill++ = *t1++; *outfill++ = *t1++;
×
2179
                                                }
2180
                                                else t1 += 2;
12✔
2181
                                        }
2182
                                }
2183
                                while ( c1 < c2 ) {
24✔
2184
                                        if ( c1[1] < 0 ) { *outfill++ = c1[0]; *outfill++ = c1[1]; }
6✔
2185
                                        c1 += 2;
6✔
2186
                                }
2187
                                while ( t1 < t2 ) {
18✔
2188
                                        if ( t1[1] < 0 ) { *outfill++ = t1[0]; *outfill++ = t1[1]; }
×
2189
                                        t1 += 2;
×
2190
                                }
2191
                                out1[1] = outfill - out1;
18✔
2192
                                if ( out1[1] == 2 ) outfill = out1;
18✔
2193
                                break;
2194
                        case DOTPRODUCT:
2195
                                diddotp = 1;
×
2196
                                t = term+1;
2197
                                while ( t < tstop && *t != *ct ) t += t[1];
×
2198
                                if ( t >= tstop ) break;
×
2199
                                t1 = t+2; t2 = t+t[1];
×
2200
                                c1 = ct+2; c2 = ct+ct[1];
×
2201
                                out1 = outfill; *outfill++ = *ct; outfill++;
×
2202
                                while ( c1 < c2 && t1 < t2 ) {
×
2203
                                        if ( *c1 == *t1 && c1[1] == t1[1] ) {
×
2204
                                                if ( t1[2] <= c1[2] ) {
×
2205
                                                        *outfill++ = *t1++; *outfill++ = *t1++; *outfill++ = *t1++;
×
2206
                                                        c1 += 3;
×
2207
                                                }
2208
                                                else {
2209
                                                        *outfill++ = *c1++; *outfill++ = *c1++; *outfill++ = *c1++;
×
2210
                                                        t1 += 3;
×
2211
                                                }
2212
                                        }
2213
                                        else if ( *c1 < *t1 || ( *c1 == *t1 && c1[1] < t1[1] ) ) {
×
2214
                                                if ( c1[2] < 0 ) {
×
2215
                                                        *outfill++ = *c1++; *outfill++ = *c1++; *outfill++ = *c1++;
×
2216
                                                }
2217
                                                else { c1 += 3; }
×
2218
                                        }
2219
                                        else {
2220
                                                if ( t1[2] < 0 ) {
×
2221
                                                        *outfill++ = *t1++; *outfill++ = *t1++; *outfill++ = *t1++;
×
2222
                                                }
2223
                                                else t1 += 3;
×
2224
                                        }
2225
                                }
2226
                                while ( c1 < c2 ) {
×
2227
                                        if ( c1[2] < 0 ) { *outfill++ = c1[0]; *outfill++ = c1[1]; *outfill++ = c1[1]; }
×
2228
                                        c1 += 3;
×
2229
                                }
2230
                                while ( t1 < t2 ) {
×
2231
                                        if ( t1[2] < 0 ) { *outfill++ = t1[0]; *outfill++ = t1[1]; *outfill++ = t1[1]; }
×
2232
                                        t1 += 3;
×
2233
                                }
2234
                                out1[1] = outfill - out1;
×
2235
                                if ( out1[1] == 2 ) outfill = out1;
×
2236
                                break;
2237
                        case INDEX:
2238
                                t = term+1;
2239
                                while ( t < tstop && *t != *ct ) t += t[1];
×
2240
                                if ( t >= tstop ) break;
×
2241
                                t1 = t+2; t2 = t+t[1];
×
2242
                                c1 = ct+2; c2 = ct+ct[1];
×
2243
                                out1 = outfill; *outfill++ = *ct; outfill++;
×
2244
                                while ( c1 < c2 && t1 < t2 ) {
×
2245
                                        if ( *c1 == *t1 ) {
×
2246
                                                *outfill++ = *c1++;
×
2247
                                                t1 += 1;
×
2248
                                        }
2249
                                        else if ( *c1 < *t1 ) { c1 += 1; }
×
2250
                                        else { t1 += 1; }
×
2251
                                }
2252
                                out1[1] = outfill - out1;
×
2253
                                if ( out1[1] == 2 ) outfill = out1;
×
2254
                                break;
2255
                        case VECTOR:
2256
                        case DELTA:
2257
                                t = term+1;
2258
                                while ( t < tstop && *t != *ct ) t += t[1];
×
2259
                                if ( t >= tstop ) break;
×
2260
                                t1 = t+2; t2 = t+t[1];
×
2261
                                c1 = ct+2; c2 = ct+ct[1];
×
2262
                                out1 = outfill; *outfill++ = *ct; outfill++;
×
2263
                                while ( c1 < c2 && t1 < t2 ) {
×
2264
                                        if ( *c1 == *t1 && c1[1] && t1[1] ) {
×
2265
                                                *outfill++ = *c1++; *outfill++ = *c1++;
×
2266
                                                t1 += 2;
×
2267
                                        }
2268
                                        else if ( *c1 < *t1 || ( *c1 == *t1 && c1[1] < t1[1] ) ) {
×
2269
                                                c1 += 2;
×
2270
                                        }
2271
                                        else {
2272
                                                t1 += 2;
×
2273
                                        }
2274
                                }
2275
                                out1[1] = outfill - out1;
×
2276
                                if ( out1[1] == 2 ) outfill = out1;
×
2277
                                break;
2278
                        case GAMMA:
2279
                        default:                        /* Functions */
2280
                                told = t;
2281
                                t = term+1;
2282
                                while ( t < tstop ) {
×
2283
                                        if ( *t != *ct ) { t += t[1]; continue; }
×
2284
                                        if ( ct[1] != t[1] ) { t += t[1]; continue; }
×
2285
                                        if ( ct[2] != t[2] ) { t += t[1]; continue; }
×
2286
                                        t1 = t; t2 = ct; i1 = t1[1]; i2 = t2[1];
2287
                                        while ( i1 > 0 ) {
×
2288
                                                if ( *t1 != *t2 ) break;
×
2289
                                                t1++; t2++; i1--;
×
2290
                                        }
2291
                                        if ( i1 != 0 ) { t += t[1]; continue; }
×
2292
                                        t1 = t;
×
2293
                                        for ( i = 0; i < i2; i++ ) { *outfill++ = *t++; }
×
2294
/*
2295
                                        Mark as 'used'. The flags must be different!
2296
*/
2297
                                        t1[2] |= SUBTERMUSED1;
×
2298
                                        ct[2] |= SUBTERMUSED2;
×
2299
                                        t = told;
×
2300
                                        break;
×
2301
                                }
2302
                                break;
2303
                }
2304
                ct += ct[1];
18✔
2305
        }
2306
        if ( diddotp == 0 ) {
24✔
2307
                t = term+1; while ( t < tstop && *t != DOTPRODUCT ) t += t[1];
48✔
2308
                if ( t < tstop ) { /* now we need the negative powers */
24✔
2309
                        tfirst = 1; told = outfill;
2310
                        for ( i = 2; i < t[1]; i += 3 ) {
×
2311
                                if ( t[i+2] < 0 ) {
×
2312
                                        if ( tfirst ) { *outfill++ = DOTPRODUCT; *outfill++ = 0; tfirst = 0; }
×
2313
                                        *outfill++ = t[i]; *outfill++ = t[i+1]; *outfill++ = t[i+2];
×
2314
                                }
2315
                        }
2316
                        if ( outfill > told ) told[1] = outfill-told;
×
2317
                }
2318
        }
2319
        if ( didsymbol == 0 ) {
24✔
2320
                t = term+1; while ( t < tstop && *t != SYMBOL ) t += t[1];
6✔
2321
                if ( t < tstop ) { /* now we need the negative powers */
6✔
2322
                        tfirst = 1; told = outfill;
2323
                        for ( i = 2; i < t[1]; i += 2 ) {
12✔
2324
                                if ( t[i+1] < 0 ) {
6✔
2325
                                        if ( tfirst ) { *outfill++ = SYMBOL; *outfill++ = 0; tfirst = 0; }
6✔
2326
                                        *outfill++ = t[i]; *outfill++ = t[i+1];
6✔
2327
                                }
2328
                        }
2329
                        if ( outfill > told ) told[1] = outfill-told;
6✔
2330
                }
2331
        }
2332
/*
2333
        Now put the coefficient back.
2334
*/
2335
        if ( numsize < densize ) {
24✔
2336
                for ( i = numsize; i < densize; i++ ) num[i] = 0;
×
2337
                numsize = densize;
×
2338
        }
2339
        else if ( densize < numsize ) {
24✔
2340
                for ( i = densize; i < numsize; i++ ) den[i] = 0;
×
2341
                densize = numsize;
×
2342
        }
2343
        for ( i = 0; i < numsize; i++ ) *outfill++ = num[i];
48✔
2344
        for ( i = 0; i < densize; i++ ) *outfill++ = den[i];
48✔
2345
        csize = numsize+densize+1;
24✔
2346
        if ( sign < 0 ) csize = -csize;
24✔
2347
        *outfill++ = csize;
24✔
2348
        *outb = outfill-outb;
24✔
2349
        NumberFree(den,"ContentMerge");
24✔
2350
        NumberFree(num,"ContentMerge");
24✔
2351
        for ( i = 0; i < *outb; i++ ) content[i] = outb[i];
228✔
2352
        TermFree(outb,"ContentMerge");
24✔
2353
/*
2354
        Now we have to 'restore' the term to its original.
2355
        We do not restore the content, because if anything was used the
2356
        new content overwrites the old. 6-mar-2018 JV
2357
*/
2358
        t = term + 1;
24✔
2359
        while ( t < tstop ) {
48✔
2360
                if ( *t >= FUNCTION ) t[2] &= ~SUBTERMUSED1;
24✔
2361
                t += t[1];
24✔
2362
        }
2363
        return(*content);
24✔
2364
CalledFrom:
×
2365
        MLOCK(ErrorMessageLock);
×
2366
        MesCall("GetContent");
×
2367
        MUNLOCK(ErrorMessageLock);
×
2368
        SETERROR(-1)
×
2369
}
2370

2371
/*
2372
                 #] ContentMerge : 
2373
                 #[ TermsInExpression :
2374
*/
2375

2376
LONG TermsInExpression(WORD num)
48✔
2377
{
2378
        LONG x = Expressions[num].counter;
48✔
2379
        if ( x >= 0 ) return(x);
48✔
2380
        return(-1);
2381
}
2382

2383
/*
2384
                 #] TermsInExpression : 
2385
                 #[ SizeOfExpression :
2386
*/
2387

2388
LONG SizeOfExpression(WORD num)
×
2389
{
2390
        LONG x = (LONG)(DIVPOS(Expressions[num].size,sizeof(WORD)));
×
2391
        if ( x >= 0 ) return(x);
×
2392
        return(-1);
2393
}
2394

2395
/*
2396
                 #] SizeOfExpression : 
2397
                 #[ UpdatePositions :
2398
*/
2399

2400
void UpdatePositions(void)
7,224✔
2401
{
2402
        EXPRESSIONS e = Expressions;
7,224✔
2403
        POSITION *old;
7,224✔
2404
        WORD *oldw;
7,224✔
2405
        int i;
7,224✔
2406
        if ( NumExpressions > 0 &&
7,224✔
2407
                 ( AS.OldOnFile == 0 || AS.NumOldOnFile < NumExpressions ) ) {
6,762✔
2408
                if ( AS.OldOnFile ) {
×
2409
                        old = AS.OldOnFile;
×
2410
                        AS.OldOnFile = (POSITION *)Malloc1(NumExpressions*sizeof(POSITION),"file pointers");
×
2411
                        for ( i = 0; i < AS.NumOldOnFile; i++ ) AS.OldOnFile[i] = old[i];
×
2412
                        AS.NumOldOnFile = NumExpressions;
×
2413
                        M_free(old,"process file pointers");
×
2414
                }
2415
                else {
2416
                        AS.OldOnFile = (POSITION *)Malloc1(NumExpressions*sizeof(POSITION),"file pointers");
×
2417
                        AS.NumOldOnFile = NumExpressions;
×
2418
                }
2419
        }
2420
        if ( NumExpressions > 0 &&
7,224✔
2421
                 ( AS.OldNumFactors == 0 || AS.NumOldNumFactors < NumExpressions ) ) {
6,762✔
2422
                if ( AS.OldNumFactors ) {
×
2423
                        oldw = AS.OldNumFactors;
×
2424
                        AS.OldNumFactors = (WORD *)Malloc1(NumExpressions*sizeof(WORD),"numfactors pointers");
×
2425
                        for ( i = 0; i < AS.NumOldNumFactors; i++ ) AS.OldNumFactors[i] = oldw[i];
×
2426
                        M_free(oldw,"numfactors pointers");
×
2427
                        oldw = AS.Oldvflags;
×
2428
                        AS.Oldvflags = (WORD *)Malloc1(NumExpressions*sizeof(WORD),"vflags pointers");
×
2429
                        for ( i = 0; i < AS.NumOldNumFactors; i++ ) AS.Oldvflags[i] = oldw[i];
×
2430
                        AS.NumOldNumFactors = NumExpressions;
×
2431
                        M_free(oldw,"vflags pointers");
×
2432
                        oldw = AS.Olduflags;
×
2433
                        AS.Olduflags = (WORD *)Malloc1(NumExpressions*sizeof(WORD),"uflags pointers");
×
2434
                        for ( i = 0; i < AS.NumOldNumFactors; i++ ) AS.Olduflags[i] = oldw[i];
×
2435
                        AS.NumOldNumFactors = NumExpressions;
×
2436
                        M_free(oldw,"uflags pointers");
×
2437
                }
2438
                else {
2439
                        AS.OldNumFactors = (WORD *)Malloc1(NumExpressions*sizeof(WORD),"numfactors pointers");
×
2440
                        AS.Oldvflags = (WORD *)Malloc1(NumExpressions*sizeof(WORD),"vflags pointers");
×
2441
                        AS.Olduflags = (WORD *)Malloc1(NumExpressions*sizeof(WORD),"uflags pointers");
×
2442
                        AS.NumOldNumFactors = NumExpressions;
×
2443
                }
2444
        }
2445
        for ( i = 0; i < NumExpressions; i++ ) {
2,345,184✔
2446
                AS.OldOnFile[i] = e[i].onfile;
2,337,960✔
2447
                AS.OldNumFactors[i] = e[i].numfactors;
2,337,960✔
2448
                AS.Oldvflags[i] = e[i].vflags;
2,337,960✔
2449
                AS.Olduflags[i] = e[i].uflags;
2,337,960✔
2450
        }
2451
}
7,224✔
2452

2453
/*
2454
                 #] UpdatePositions : 
2455
                 #[ CountTerms1 :                LONG CountTerms1()
2456

2457
                Counts the terms in the current deferred bracket
2458
                Is mainly an adaptation of the routine Deferred in proces.c
2459
*/
2460

2461
LONG CountTerms1(PHEAD0)
×
2462
{
2463
        GETBIDENTITY
2464
        POSITION oldposition, startposition;
×
2465
        WORD *t, *m, *mstop, decr, i, *oldwork, retval;
×
2466
        WORD *oldipointer = AR.CompressPointer;
×
2467
        WORD oldGetOneFile = AR.GetOneFile, olddeferflag = AR.DeferFlag;
×
2468
        LONG numterms = 0;
×
2469
        AR.GetOneFile = 1;
×
2470
        oldwork = AT.WorkPointer;
×
2471
    AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
×
2472
        AR.DeferFlag = 0;
×
2473
        startposition = AR.DefPosition;
×
2474
/*
2475
                Store old position
2476
*/
2477
        if ( AR.infile->handle >= 0 ) {
×
2478
                PUTZERO(oldposition);
×
2479
/*
2480
                SeekFile(AR.infile->handle,&oldposition,SEEK_CUR);
2481
*/
2482
        }
2483
        else {
2484
                SETBASEPOSITION(oldposition,AR.infile->POfill-AR.infile->PObuffer);
×
2485
                AR.infile->POfill = (WORD *)((UBYTE *)(AR.infile->PObuffer)
×
2486
                                        +BASEPOSITION(startposition));
×
2487
        }
2488
/*
2489
                Look in the CompressBuffer where the bracket contents start
2490
*/
2491
        t = m = AR.CompressBuffer;
×
2492
        t += *t;
×
2493
        mstop = t - ABS(t[-1]);
×
2494
        m++;
×
2495
        while ( *m != HAAKJE && m < mstop ) m += m[1];
×
2496
        if ( m >= mstop ) {        /* No deferred action! */
×
2497
                numterms = 1;
×
2498
                AR.DeferFlag = olddeferflag;
×
2499
                AT.WorkPointer = oldwork;
×
2500
                AR.GetOneFile = oldGetOneFile;
×
2501
                return(numterms);
×
2502
        }
2503
        mstop = m + m[1];
×
2504
        decr = WORDDIF(mstop,AR.CompressBuffer)-1;
×
2505

2506
        m = AR.CompressBuffer;
×
2507
        t = AR.CompressPointer;
×
2508
        i = *m;
×
2509
        NCOPY(t,m,i);
×
2510
        AR.TePos = 0;
×
2511
        AN.TeSuOut = 0;
×
2512
/*
2513
                Status:
2514
                First bracket content starts at mstop.
2515
                Next term starts at startposition.
2516
                Decompression information is in AR.CompressPointer.
2517
                The outside of the bracket runs from AR.CompressBuffer+1 to mstop.
2518
*/
2519
        AR.CompressPointer = oldipointer;
×
2520
        for(;;) {
×
2521
                numterms++;
×
2522
                retval = GetOneTerm(BHEAD AT.WorkPointer,AR.infile,&startposition,0);
×
2523
                if ( retval >= 0 ) AR.CompressPointer = oldipointer;
×
2524
                if ( retval <= 0 ) break;
×
2525
                t = AR.CompressPointer;
×
2526
                if ( *t < (1 + decr + ABS(*(t+*t-1))) ) break;
×
2527
                t++;
×
2528
                m = AR.CompressBuffer+1;
×
2529
                while ( m < mstop ) {
×
2530
                        if ( *m != *t ) goto Thatsit;
×
2531
                        m++; t++;
×
2532
                }
2533
        }
2534
Thatsit:;
×
2535
/*
2536
                Finished. Reposition the file, restore information and return.
2537
*/
2538
        AT.WorkPointer = oldwork;
×
2539
        if ( AR.infile->handle >= 0 ) {
×
2540
/*
2541
                SeekFile(AR.infile->handle,&oldposition,SEEK_SET);
2542
*/
2543
        }
2544
        else {
2545
                AR.infile->POfill = AR.infile->PObuffer + BASEPOSITION(oldposition);
×
2546
        }
2547
        AR.DeferFlag = olddeferflag;
×
2548
        AR.GetOneFile = oldGetOneFile;
×
2549
        return(numterms);
×
2550
}
2551

2552
/*
2553
                 #] CountTerms1 : 
2554
                 #[ TermsInBracket :                LONG TermsInBracket(term,level)
2555

2556
        The function TermsInBracket_()
2557
        Syntax:
2558
                TermsInBracket_() : The current bracket in a Keep Brackets
2559
                TermsInBracket_(bracket) : This bracket in the current expression
2560
                TermsInBracket_(expression,bracket) : This bracket in the given expression
2561
        All other specifications don't have any effect.
2562
*/
2563

2564
#define CURRENTBRACKET 1
2565
#define BRACKETCURRENTEXPR 2
2566
#define BRACKETOTHEREXPR 3
2567
#define NOBRACKETACTIVE 4
2568

2569
LONG TermsInBracket(PHEAD WORD *term, WORD level)
×
2570
{
2571
        WORD *t, *tstop, *b, *tt, *n1, *n2;
×
2572
        int type = 0, i, num;
×
2573
        LONG numterms = 0;
×
2574
        WORD *bracketbuffer = AT.WorkPointer;
×
2575
        t = term; GETSTOP(t,tstop);
×
2576
        t++; b = bracketbuffer;
×
2577
        while ( t < tstop ) {
×
2578
                if ( *t != TERMSINBRACKET ) { t += t[1]; continue; }
×
2579
                if ( t[1] == FUNHEAD || (
×
2580
                         t[1] == FUNHEAD+2
2581
                        && t[FUNHEAD] == -SNUMBER
×
2582
                        && t[FUNHEAD+1] == 0
×
2583
                 ) ) {
2584
                        if ( AC.ComDefer == 0 ) {
×
2585
                                type = NOBRACKETACTIVE;
2586
                        }
2587
                        else {
2588
                                type = CURRENTBRACKET;
×
2589
                        }
2590
                        *b = 0;
×
2591
                        break;
×
2592
                }
2593
                if ( t[FUNHEAD] == -EXPRESSION ) {
×
2594
                        if ( t[FUNHEAD+2] < 0 ) {
×
2595
                                if ( ( t[FUNHEAD+2] <= -FUNCTION ) && ( t[1] == FUNHEAD+3 ) ) {
×
2596
                                        type = BRACKETOTHEREXPR;
×
2597
                                        *b++ = FUNHEAD+4; *b++ = -t[FUNHEAD+2]; *b++ = FUNHEAD;
×
2598
                                        for ( i = 2; i < FUNHEAD; i++ ) *b++ = 0;
×
2599
                                        *b++ = 1; *b++ = 1; *b++ = 3;
×
2600
                                        break;
×
2601
                                }
2602
                                else if ( ( t[FUNHEAD+2] > -FUNCTION ) && ( t[1] == FUNHEAD+4 ) ) {
×
2603
                                        type = BRACKETOTHEREXPR;
×
2604
                                        tt = t + FUNHEAD+2;
×
2605
                                        switch ( *tt ) {
×
2606
                                                case -SYMBOL:
×
2607
                                                        *b++ = 8; *b++ = SYMBOL; *b++ = 4; *b++ = tt[1];
×
2608
                                                        *b++ = 1; *b++ = 1; *b++ = 1; *b++ = 3;
×
2609
                                                        break;
×
2610
                                                case -SNUMBER:
×
2611
                                                        if ( tt[1] == 1 ) {
×
2612
                                                                *b++ = 4; *b++ = 1; *b++ = 1; *b++ = 3;
×
2613
                                                        }
2614
                                                        else goto IllBraReq;
×
2615
                                                        break;
×
2616
                                                default:
×
2617
                                                        goto IllBraReq;
×
2618
                                        }
2619
                                        break;
2620
                                }
2621
                        }
2622
                        else if ( ( t[FUNHEAD+2] == (t[1]-FUNHEAD-2) ) &&
×
2623
                                          ( t[FUNHEAD+2+ARGHEAD] == (t[FUNHEAD+2]-ARGHEAD) ) ) {
×
2624
                                type = BRACKETOTHEREXPR;
×
2625
                                tt = t + FUNHEAD + ARGHEAD; num = *tt;
×
2626
                                for ( i = 0; i < num; i++ ) *b++ = *tt++;
×
2627
                                break;
2628
                        }
2629
                }
2630
                else {
2631
                        if ( t[FUNHEAD] < 0 ) {
×
2632
                                if ( ( t[FUNHEAD] <= -FUNCTION ) && ( t[1] == FUNHEAD+1 ) ) {
×
2633
                                        type = BRACKETCURRENTEXPR;
×
2634
                                        *b++ = FUNHEAD+4; *b++ = -t[FUNHEAD+2]; *b++ = FUNHEAD;
×
2635
                                        for ( i = 2; i < FUNHEAD; i++ ) *b++ = 0;
×
2636
                                        *b++ = 1; *b++ = 1; *b++ = 3; *b = 0;
×
2637
                                        break;
×
2638
                                }
2639
                                else if ( ( t[FUNHEAD] > -FUNCTION ) && ( t[1] == FUNHEAD+2 ) ) {
×
2640
                                        type = BRACKETCURRENTEXPR;
×
2641
                                        tt = t + FUNHEAD+2;
×
2642
                                        switch ( *tt ) {
×
2643
                                                case -SYMBOL:
×
2644
                                                        *b++ = 8; *b++ = SYMBOL; *b++ = 4; *b++ = tt[1];
×
2645
                                                        *b++ = 1; *b++ = 1; *b++ = 1; *b++ = 3;
×
2646
                                                        break;
×
2647
                                                case -SNUMBER:
×
2648
                                                        if ( tt[1] == 1 ) {
×
2649
                                                                *b++ = 4; *b++ = 1; *b++ = 1; *b++ = 3;
×
2650
                                                        }
2651
                                                        else goto IllBraReq;
×
2652
                                                        break;
×
2653
                                                default:
×
2654
                                                        goto IllBraReq;
×
2655
                                        }
2656
                                        break;
2657
                                }
2658
                        }
2659
                        else if ( ( t[FUNHEAD] == (t[1]-FUNHEAD) ) &&
×
2660
                                          ( t[FUNHEAD+ARGHEAD] == (t[FUNHEAD]-ARGHEAD) ) ) {
×
2661
                                type = BRACKETCURRENTEXPR;
×
2662
                                tt = t + FUNHEAD + ARGHEAD; num = *tt;
×
2663
                                for ( i = 0; i < num; i++ ) *b++ = *tt++;
×
2664
                                break;
2665
                        }
2666
                        else {
2667
IllBraReq:;
×
2668
                                MLOCK(ErrorMessageLock);
×
2669
                                MesPrint("Illegal bracket request in termsinbracket_ function.");
×
2670
                                MUNLOCK(ErrorMessageLock);
×
2671
                                Terminate(-1);
×
2672
                        }
2673
                }
2674
                t += t[1];
×
2675
        }
2676
        AT.WorkPointer = b;
×
2677
        if ( AT.WorkPointer + *term +4 > AT.WorkTop ) {
×
2678
                MLOCK(ErrorMessageLock);
×
2679
                MesWork();
×
2680
                MesPrint("Called from termsinbracket_ function.");
×
2681
                MUNLOCK(ErrorMessageLock);
×
2682
                return(-1);
×
2683
        }
2684
/*
2685
        We are now in the position to look for the bracket
2686
*/
2687
        switch ( type ) {
×
2688
                case CURRENTBRACKET:
×
2689
/*
2690
                        The code here should be rather similar to when we pick up
2691
                        the contents of the bracket. In our case we only count the
2692
                        terms though.
2693
*/
2694
                        numterms = CountTerms1(BHEAD0);
×
2695
                        break;
×
2696
                case BRACKETCURRENTEXPR:
×
2697
/*
2698
                        Not implemented yet.
2699
*/
2700
                        MLOCK(ErrorMessageLock);
×
2701
                        MesPrint("termsinbracket_ function currently only handles Keep Brackets.");
×
2702
                        MUNLOCK(ErrorMessageLock);
×
2703
                        return(-1);
×
2704
                case BRACKETOTHEREXPR:
×
2705
                        MLOCK(ErrorMessageLock);
×
2706
                        MesPrint("termsinbracket_ function currently only handles Keep Brackets.");
×
2707
                        MUNLOCK(ErrorMessageLock);
×
2708
                        return(-1);
×
2709
                case NOBRACKETACTIVE:
×
2710
                        numterms = 1;
×
2711
                        break;
×
2712
        }
2713
/*
2714
        Now we have the number in numterms. We replace the function by it.
2715
*/
2716
        n1 = term; n2 = AT.WorkPointer; tstop = n1 + *n1;
×
2717
        while ( n1 < t ) *n2++ = *n1++;
×
2718
        i = numterms >> BITSINWORD;
×
2719
        if ( i == 0 ) {
×
2720
                *n2++ = LNUMBER; *n2++ = 4; *n2++ = 1; *n2++ = (WORD)(numterms & WORDMASK);
×
2721
        }
2722
        else {
2723
                *n2++ = LNUMBER; *n2++ = 5; *n2++ = 2;
×
2724
                *n2++ = (WORD)(numterms & WORDMASK); *n2++ = i;
×
2725
        }
2726
        n1 += n1[1];
×
2727
        while ( n1 < tstop ) *n2++ = *n1++;
×
2728
        AT.WorkPointer[0] = n2 - AT.WorkPointer;
×
2729
        AT.WorkPointer = n2;
×
2730
        if ( Generator(BHEAD n1,level) < 0 ) {
×
2731
                AT.WorkPointer = bracketbuffer;
×
2732
                MLOCK(ErrorMessageLock);
×
2733
                MesPrint("Called from termsinbracket_ function.");
×
2734
                MUNLOCK(ErrorMessageLock);
×
2735
                return(-1);
×
2736
        }
2737
/*
2738
        Finished. Reset things and return.
2739
*/
2740
        AT.WorkPointer = bracketbuffer;
×
2741
        return(numterms);
×
2742
}
2743
/*
2744
                 #] TermsInBracket :                LONG TermsInBracket(term,level) 
2745
        #] Expressions :
2746
*/
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