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

tueda / form / 8437027567

26 Mar 2024 01:43PM UTC coverage: 51.572% (+3.1%) from 48.497%
8437027567

push

github

tueda
fix: typos in comments

9 of 10 new or added lines in 5 files covered. (90.0%)

11805 existing lines in 27 files now uncovered.

38361 of 74383 relevant lines covered (51.57%)

564198.37 hits per line

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

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

38
#include "form3.h"
39

40
/*
41
          #] Includes : 
42
         #[ Utilities :
43
                 #[ MakeDirty :
44

45
                Routine finds the function with the address x in it
46
                and mark all arguments that contain x as dirty.
47
                if par == 0 term is a full term, else term is the start of a 
48
                function
49
*/
50

51
WORD MakeDirty(WORD *term, WORD *x, WORD par)
×
52
{
53
        WORD *next, *n;
×
54
        if ( !par ) {
×
55
                next = term; next += *term;
×
56
                next -= ABS(next[-1]);
×
57
                term++;
×
58
                if ( x < term ) return(0);
×
59
                if ( x >= next ) return(0);
×
60
                while ( term < next ) {
×
61
                        n = term + term[1];
×
62
                        if ( x < n ) break;
×
63
                        term = n;
64
                }
65
/*                next = n; */
66
        }
67
        else {
68
                next = term + term[1];
×
69
                if ( x < term || x >= next ) return(0);
×
70
        }
71
        if ( *term < FUNCTION ) return(0);
×
72
        if ( functions[*term-FUNCTION].spec >= TENSORFUNCTION ) return(0);
×
73
        term += FUNHEAD;
×
74
        if ( x < term ) return(0);
×
75
        next = term; NEXTARG(next)
×
76
        while ( x >= next ) { term = next; NEXTARG(next) }
×
77
        if ( *term < 0 ) return(0);
×
78
        term[1] = 1;
×
79
        term += ARGHEAD;
×
80
        if ( x < term ) return(1);
×
81
        next = term + *term;
×
82
        while ( x >= next ) { term = next; next += *next; }
×
83
        MakeDirty(term,x,0);
×
84
        return(1);
×
85
}
86

87
/*
88
                 #] MakeDirty : 
89
                 #[ MarkDirty :
90

91
                Routine marks all functions dirty with the given flags.
92
                Is to be used when there is a possibility that symmetrization
93
                properties of functions may have changed. In that case we play
94
                it safe.
95
*/
96

97
void MarkDirty(WORD *term, WORD flags)
73✔
98
{
99
        WORD *t, *r, *m, *tstop;
73✔
100
        GETSTOP(term,tstop);
73✔
101
        t = term+1;
73✔
102
        while ( t < tstop ) {
148✔
103
                if ( *t < FUNCTION ) { t += t[1]; continue; }
75✔
104
                t[2] |= flags;
6✔
105
                if ( *t < FUNCTION+WILDOFFSET && functions[*t-FUNCTION].spec > 0 ) {
6✔
106
                        t += t[1]; continue;
×
107
                }
108
                if ( *t >= FUNCTION+WILDOFFSET && functions[*t-FUNCTION-WILDOFFSET].spec > 0 ) {
6✔
109
                        t += t[1]; continue;
×
110
                }
111
                r = t + FUNHEAD;
6✔
112
                t += t[1];
6✔
113
                while ( r < t ) {
66✔
114
                        if ( *r <= 0 ) {
60✔
115
                                if ( *r <= -FUNCTION ) r++;
60✔
116
                                else r += 2;
60✔
117
                                continue;
60✔
118
                        }
119
                        r[1] |= DIRTYFLAG;
×
120
                        m = r + ARGHEAD;
×
121
                        r += *r;
×
122
                        while ( m < r ) {
×
123
                                MarkDirty(m,flags);
×
124
                                m += *m;
×
125
                        }
126
                }
127
        }
128
}
73✔
129

130
/*
131
                 #] MarkDirty : 
132
                 #[ PolyFunDirty :
133

134
                Routine marks the PolyFun or the PolyRatFun dirty.
135
                This is used when there is modular calculus and the modulus
136
                has changed for the current module.
137
*/
138

139
void PolyFunDirty(PHEAD WORD *term)
1,790✔
140
{
141
        GETBIDENTITY
142
        WORD *t, *tstop, *endarg;
1,790✔
143
        tstop = term + *term;
1,790✔
144
        tstop -= ABS(tstop[-1]);
1,790✔
145
        t = term+1;
1,790✔
146
        while ( t < tstop ) {
5,278✔
147
                if ( *t == AR.PolyFun ) {
3,488✔
148
                        if ( AR.PolyFunType == 2 ) t[2] |= MUSTCLEANPRF;
873✔
149
                        endarg = t + t[1];
873✔
150
                        t[2] |= DIRTYFLAG;
873✔
151
                        t += FUNHEAD;
873✔
152
                        while ( t < endarg ) {
873✔
153
                                if ( *t > 0 ) {
1,746✔
154
                                        t[1] |= DIRTYFLAG;
1,617✔
155
                                }
156
                                NEXTARG(t);
4,365✔
157
                        }
158
                }
159
                else {
160
                        t += t[1];
2,615✔
161
                }
162
        }
163
}
1,790✔
164

165
/*
166
                 #] PolyFunDirty : 
167
                 #[ PolyFunClean :
168

169
                Routine marks the PolyFun or the PolyRatFun clean.
170
                This is used when there is modular calculus and the modulus
171
                has changed for the current module.
172
*/
173

174
void PolyFunClean(PHEAD WORD *term)
1,725✔
175
{
176
        GETBIDENTITY
177
        WORD *t, *tstop;
1,725✔
178
        tstop = term + *term;
1,725✔
179
        tstop -= ABS(tstop[-1]);
1,725✔
180
        t = term+1;
1,725✔
181
        while ( t < tstop ) {
5,955✔
182
                if ( *t == AR.PolyFun ) {
4,230✔
183
                        t[2] &= ~MUSTCLEANPRF;
1,692✔
184
                }
185
                t += t[1];
4,230✔
186
        }
187
}
1,725✔
188

189
/*
190
                 #] PolyFunClean : 
191
                 #[ Symmetrize :
192

193
                (Anti)Symmetrizes the arguments of a function. 
194
                Nlist tells of how many arguments are involved.
195
                Nlist == 0                All arguments must be sorted.
196
                Nlist > 0                Arguments mentioned are to be sorted, rest skipped.
197
                type = SYMMETRIC       Full symmetrization
198
                type = ANTISYMMETRIC:  Full symmetrization
199
                type = CYCLESYMMETRIC: Cyclic
200
                type = RCYCLESYMMETRIC:Cyclic or reverse
201
                Return value: OR of:
202
                        0 even, 1 odd
203
                        2 equal groups
204
                        4 there was a permutation.
205

206
                The information in Lijst tells what grouping is to be applied.
207
                The information is:
208
                ngroups number of groups
209
                gsize size of groups
210
                Lijst[0]....  The groups.
211
*/
212

213
WORD Symmetrize(PHEAD WORD *func, WORD *Lijst, WORD ngroups, WORD gsize,
1,178✔
214
                WORD type)
215
{
216
        GETBIDENTITY
217
        WORD **args,**arg,nargs;
1,178✔
218
        WORD *to, *r, *fstop;
1,178✔
219
        WORD i, j, k, ff, exch, nexch, neq;
1,178✔
220
        WORD *a1, *a2, *a3;
1,178✔
221
        WORD reverseorder;
1,178✔
222
        if ( ( type & REVERSEORDER ) != 0 ) reverseorder = -1;
1,178✔
223
        else                                reverseorder = 1;
1,178✔
224
        type &= ~REVERSEORDER;
1,178✔
225

226
        ff = ( *func > FUNCTION ) ? functions[*func-FUNCTION].spec: 0;
1,178✔
227

228
        if ( 2*func[1] > AN.arglistsize ) {
1,178✔
229
                if ( AN.arglist ) M_free(AN.arglist,"Symmetrize");
55✔
230
                AN.arglistsize = 2*func[1] + 8;
55✔
231
                AN.arglist = (WORD **)Malloc1(AN.arglistsize*sizeof(WORD *),"Symmetrize");
55✔
232
        }
233
        arg = args = AN.arglist;
1,178✔
234
        to = AT.WorkPointer;
1,178✔
235
        r = func;
1,178✔
236
        fstop = r + r[1];
1,178✔
237
        r += FUNHEAD;
1,178✔
238
        nargs = 0;
1,178✔
239
        while ( r < fstop ) {        /* Make list of arguments */
1,178✔
240
                *arg++ = r;
2,564✔
241
                nargs++;
2,564✔
242
                if ( ff ) {
2,564✔
243
                        if ( *r == FUNNYWILD ) r++;
×
244
                        r++;
×
245
                }
246
                else { NEXTARG(r); }
6,306✔
247
        }
248
        exch = 0;
1,178✔
249
        nexch = 0;
1,178✔
250
        neq = 0;
1,178✔
251
        a1 = Lijst;
1,178✔
252
        if ( type == SYMMETRIC || type == ANTISYMMETRIC ) {
1,178✔
253
        for ( i = 1; i < ngroups; i++ ) {
2,549✔
254
                a3 = a2 = a1 + gsize;
1,377✔
255
                k = reverseorder*CompGroup(BHEAD ff,args,a1,a2,gsize);
1,377✔
256
                if ( k < 0 ) {
1,377✔
257
                        j = i-1;
382✔
258
                        for(;;) {
1,092✔
259
                                for ( k = 0; k < gsize; k++ ) {
1,474✔
260
                                        r = args[a1[k]]; args[a1[k]] = args[a2[k]]; args[a2[k]] = r;
737✔
261
                                }
262
                                exch ^= 1;
737✔
263
                                nexch = 4;
737✔
264
                                if ( j <= 0 ) break;
737✔
265
                                a1 -= gsize;
484✔
266
                                a2 -= gsize;
484✔
267
                                k = reverseorder*CompGroup(BHEAD ff,args,a1,a2,gsize);
484✔
268
                                if ( k == 0 ) neq = 2;
484✔
269
                                if ( k >= 0 ) break;
484✔
270
                                j--;
355✔
271
                        }
272
                }
273
                else if ( k == 0 ) neq = 2;
995✔
274
                a1 = a3;
1,377✔
275
        }
276
        }
277
        else if ( type == CYCLESYMMETRIC || type == RCYCLESYMMETRIC ) {
6✔
278
                WORD rev = 0, jmin = 0, ii, iimin;
279
recycle:
6✔
280
                for ( j = 1; j < ngroups; j++ ) {
15✔
281
                        for ( i = 0; i < ngroups; i++ ) {
9✔
282
                                iimin = jmin + i;
9✔
283
                                if ( iimin >= ngroups ) iimin -= ngroups;
9✔
284
                                ii = j + i;
9✔
285
                                if ( ii >= ngroups ) ii -= ngroups;
9✔
286
                                k = reverseorder*CompGroup(BHEAD ff,args,Lijst+gsize*iimin,Lijst+gsize*ii,gsize);
9✔
287
                                if ( k > 0 ) break;
9✔
288
                                if ( k < 0 ) { jmin = j; nexch = 4; break; }
×
289
                        }
290
                }
291
                if ( type == RCYCLESYMMETRIC && rev == 0 && ngroups > 1 ) {
6✔
292
                        for ( j = 0; j < ngroups; j++ ) {
×
293
                                for ( i = 0; i < ngroups; i++ ) {
×
294
                                        iimin = jmin + i;
×
295
                                        if ( iimin >= ngroups ) iimin -= ngroups;
×
296
                                        ii = j - i;
×
297
                                        if ( ii < 0 ) ii += ngroups;
×
298
                                        k = reverseorder*CompGroup(BHEAD ff,args,Lijst+gsize*iimin,Lijst+gsize*ii,gsize);
×
299
                                        if ( k > 0 ) break;
×
300
                                        if ( k < 0 ) {
×
301
                                                nexch = 4;
×
302
                                                jmin = 0;
×
303
                                                a1 = Lijst;
×
304
                                                a2 = Lijst + gsize * (ngroups-1);
×
305
                                                while ( a2 > a1 ) {
×
306
                                                        for ( k = 0; k < gsize; k++ ) {
×
307
                                                                r = args[a1[k]];
×
308
                                                                args[a1[k]] = args[a2[k]];
×
309
                                                                args[a2[k]] = r;
×
310
                                                        }
311
                                                        a1 += gsize; a2 -= gsize;
×
312
                                                }
313
                                                rev = 1;
×
314
                                                goto recycle;
×
315
                                        }
316
                                }
317
                        }
318
                }
319
                if ( jmin != 0 ) {
6✔
320
                        arg = AN.arglist + func[1];
×
321
                        a1 = Lijst + gsize * jmin;
×
322
                        k = gsize * ngroups;
×
323
                        a2 = Lijst + k;
×
324
                        for ( i = 0; i < k; i++ ) {
×
325
                                if ( a1 >= a2 ) a1 = Lijst;
×
326
                                *arg++ = args[*a1++];
×
327
                        }
328
                        arg = AN.arglist + func[1];
×
329
                        a1 = Lijst;
×
330
                        for ( i = 0; i < k; i++ ) args[*a1++] = *arg++;
×
331
                }
332
        }
333
        r = func;
1,178✔
334
        i = FUNHEAD;
1,178✔
335
        NCOPY(to,r,i);
4,712✔
336
        for ( i = 0; i < nargs; i++ ) {
3,742✔
337
                if ( ff ) {
2,564✔
338
                        if ( *(args[i]) == FUNNYWILD ) {
×
339
                                *to++ = *(args[i]);
×
340
                                *to++ = args[i][1];
×
341
                        }
342
                        else *to++ = *(args[i]);
×
343
                }
344
                else if ( ( j = *args[i] ) < 0 ) {
2,564✔
345
                        *to++ = j;
2,521✔
346
                        if ( j > -FUNCTION ) *to++ = args[i][1];
2,521✔
347
                }
348
                else {
349
                        r = args[i];
350
                        NCOPY(to,r,j);
4,204✔
351
                }
352
        }
353
        i = func[1];
1,178✔
354
        to = func;
1,178✔
355
        r = AT.WorkPointer;
1,178✔
356
        NCOPY(to,r,i);
11,394✔
357
        return ( exch | nexch | neq );
1,178✔
358
}
359

360
/*
361
                 #] Symmetrize : 
362
                 #[ CompGroup :
363

364
                        Routine compares two groups of arguments
365
                        The arguments are in args[a1[i]] and args[a2[i]]
366
                        for i = 0 to num
367
                        type indicates the type of function.
368
                        return value: -1 if there should be an exchange
369
                        0 if they are equal
370
                        1 if they are OK.
371
*/
372

373
WORD CompGroup(PHEAD WORD type, WORD **args, WORD *a1, WORD *a2, WORD num)
1,870✔
374
{
375
        GETBIDENTITY
376
        WORD *t1, *t2, i1, i2, n, k;
1,870✔
377

378
        for ( n = 0; n < num; n++ ) {
2,423✔
379
                t1 = args[a1[n]]; t2 = args[a2[n]];
1,870✔
380
                if ( type >= TENSORFUNCTION ) {
1,870✔
381
                        if ( AR.Eside == LHSIDE || AR.Eside == LHSIDEX ) {
×
382
                                if ( *t1 == FUNNYWILD ) {
×
383
                                        if ( *t2 == FUNNYWILD ) {
×
384
                                                if ( t1[1] < t2[1] ) return(1);
×
385
                                                if ( t1[1] > t2[1] ) return(-1);
×
386
                                        }
387
                                        return(-1);
388
                                }
389
                                else if ( *t2 == FUNNYWILD ) {
×
390
                                        return(1);
391
                                }
392
                                else {
393
                                        if ( *t1 < *t2 ) return(1);
×
394
                                        if ( *t1 > *t2 ) return(-1);
×
395
                                }
396
                        }
397
                        else {
398
                                if ( *t1 < *t2 ) return(1);
×
399
                                if ( *t1 > *t2 ) return(-1);
×
400
                        }
401
                }
402
                else if ( type == 0 ) {
1,870✔
403
                        if ( AC.properorderflag ) {
1,870✔
404
                                k = CompArg(t1,t2);
×
405
                                if ( k < 0 ) return(1);
×
406
                                if ( k > 0 ) return(-1);
×
407
                                NEXTARG(t1)
×
408
                                NEXTARG(t2)
553✔
409
                        }
410
                        else {
411
                                if ( *t1 > 0 ) {
1,870✔
412
                                        i1 = *t1 - ARGHEAD - 1;
501✔
413
                                        t1 += ARGHEAD + 1;
501✔
414
                                        if ( *t2 > 0 ) {
501✔
415
                                                i2 = *t2 - ARGHEAD - 1;
47✔
416
                                                t2 += ARGHEAD + 1;
47✔
417
                                                while ( i1 > 0 && i2 > 0 ) {
257✔
418
                                                        if ( *t1 > *t2 ) return(-1);
255✔
419
                                                        else if ( *t1 < *t2 ) return(1);
230✔
420
                                                        i1--; i2--; t1++; t2++;
210✔
421
                                                }
422
                                                if ( i1 > 0 ) return(-1);
2✔
423
                                                else if ( i2 > 0 ) return(1);
2✔
424
                                        }
425
/*
426
                                        This seems to be a bug. Reported by Aneesh Monahar, 28-sep-2005
427
                                        else return(1);
428
*/
429
                                        else return(-1);
430
                                }
431
                                else if ( *t2 > 0 ) return(1);
1,369✔
432
                                else {
433
                                        if ( *t1 != *t2 ) {
1,364✔
434
                                                if ( *t1 <= -FUNCTION && *t2 <= -FUNCTION ) {
147✔
435
                                                        if ( *t1 < *t2 ) return(-1);
×
436
                                                        return(1);
×
437
                                                }
438
                                                else {
439
                                                        if ( *t1 < *t2 ) return(1);
147✔
440
                                                        return(-1);
12✔
441
                                                }
442
                                        }
443
                                        if ( *t1 > -FUNCTION ) {
1,217✔
444
                                                if ( t1[1] != t2[1] ) {
1,217✔
445
                                                        if ( t1[1] < t2[1] ) return(1);
666✔
446
                                                        return(-1);
246✔
447
                                                }
448
                                        }
449
                                }
450
                        }
451
                }
452
        }
453
        return(0);
454
}
455

456
/*
457
                 #] CompGroup : 
458
                 #[ FullSymmetrize :
459

460
                Relay function for Normalize to execute a full symmetrization
461
                of a function fun. It hooks into Symmetrize according to the
462
                calling conventions for it.
463
                type = 0: Symmetrize
464
                type = 1: AntiSymmetrize
465
                type = 2: CycleSymmetrize
466
                type = 3: RCycleSymmetrize
467
                Return values:
468
                bit 0: odd permutation
469
                bit 1: identical arguments
470
                bit 2: there was a permutation.
471
*/
472

473
int FullSymmetrize(PHEAD WORD *fun, int type)
2,853✔
474
{
475
        GETBIDENTITY
476
        WORD *Lijst, count = 0;
2,853✔
477
        WORD *t, *funstop, i;
2,853✔
478
        int retval;
2,853✔
479

480
        if ( functions[*fun-FUNCTION].spec > 0 ) {
2,853✔
481
                count = fun[1] - FUNHEAD;
×
482
                for ( i = fun[1]-1; i >= FUNHEAD; i-- ) {
×
483
                        if ( fun[i] == FUNNYWILD ) count--;
×
484
                }
485
        }
486
        else {
487
                funstop = fun + fun[1];
2,853✔
488
                t = fun + FUNHEAD;
2,853✔
489
                while ( t < funstop ) { count++; NEXTARG(t) }
6,939✔
490
        }
491
        if ( count < 2 ) {
2,853✔
492
                fun[2] &= ~DIRTYSYMFLAG;
1,698✔
493
                return(0);
1,698✔
494
        }
495
        Lijst = AT.WorkPointer;
1,155✔
496
        for ( i = 0; i < count; i++ ) Lijst[i] = i;
3,543✔
497
        AT.WorkPointer += count;
1,155✔
498
        retval = Symmetrize(BHEAD fun,Lijst,count,1,type);
1,155✔
499
        fun[2] &= ~DIRTYSYMFLAG;
1,155✔
500
        AT.WorkPointer = Lijst;
1,155✔
501
        return(retval);
1,155✔
502
}
503

504
/*
505
                 #] FullSymmetrize : 
506
                 #[ SymGen :
507

508
                Routine does the outer work in the symmetrization.
509
                It locates the function(s) and loads up the parameters.
510
                It also studies the result.
511

512
                if params[4] = -1 and no extra -> all
513
                                      extra -> strip groups with elements too large
514
                               0  -> if group with element too large: nofun
515
                                           >0 -> must have right number of arguments
516
*/
517

518
WORD SymGen(PHEAD WORD *term, WORD *params, WORD num, WORD level)
12✔
519
{
520
        GETBIDENTITY
521
        WORD *t, *r, *m;
12✔
522
        WORD i, j, k, c1, c2, ngroup;
12✔
523
        WORD *rstop, Nlist, *inLijst, *Lijst, sign = 1, sumch = 0, count;
12✔
524
        DUMMYUSE(num);
12✔
525
        c1 = params[3];                /* function number */
12✔
526
        c2 = FUNCTION + WILDOFFSET;
12✔
527
        Nlist = params[4];
12✔
528
        if ( Nlist < 0 ) Nlist = 0;
12✔
529
        else Nlist = params[0] - 7;
12✔
530
        t = term;
12✔
531
        m = t + *t;
12✔
532
        m -= ABS(m[-1]);
12✔
533
        t++;
12✔
534
        while ( t < m ) {
24✔
535
                if ( *t == c1 || c1 > c2 ) {        /* Candidate function */
12✔
536
                        if ( *t >= FUNCTION && functions[*t-FUNCTION].spec
12✔
537
                        >= TENSORFUNCTION ) {
538
                                count = t[1] - FUNHEAD;
×
539
                        }
540
                        else {
541
                                count = 0;
12✔
542
                                r = t;
12✔
543
                                rstop = t + t[1];
12✔
544
                                r += FUNHEAD;
12✔
545
                                while ( r < rstop ) { count++; NEXTARG(r) }
36✔
546
                        }
547
                        if ( ( j = params[4] ) > 0 && j != count ) goto NextFun;
12✔
548
                        if ( j == 0 ) {
12✔
549
                                inLijst = params+7;
12✔
550
                                for ( i = 0; i < Nlist; i++ )
12✔
551
                                        if ( inLijst[i] > count-1 ) goto NextFun;
×
552
                        }
553

554
                        if ( Nlist > (params[0] - 7) ) Nlist = params[0] - 7;
12✔
555
                        Lijst = AT.WorkPointer;
12✔
556
                        inLijst = params + 7;
12✔
557
                        ngroup = params[5];
12✔
558
                        if ( Nlist > 0 && j < 0 ) {
12✔
559
                                k = 0;
560
                                for ( i = 0; i < ngroup; i++ ) {
×
561
                                        for ( j = 0; j < params[6]; j++ ) {
×
562
                                                if ( inLijst[j] > count+1 ) {
×
563
                                                        inLijst += params[6];
×
564
                                                        goto NextGroup;
×
565
                                                }
566
                                        }
567
                                        j = params[6];
568
                                        NCOPY(Lijst,inLijst,j);
×
569
                                        k++;
×
570
NextGroup:;
×
571
                                }
572
                                if ( k <= 1 ) goto NextFun;
×
573
                                ngroup = k;
×
574
                                inLijst = AT.WorkPointer;
×
575
                                AT.WorkPointer = Lijst;
×
576
                                Lijst = inLijst;
×
577
                        }
578
                        else if ( Nlist == 0 ) {
12✔
579
                                for ( i = 0; i < count; i++ ) Lijst[i] = i;
36✔
580
                                AT.WorkPointer += count;
12✔
581
                                ngroup = count;
12✔
582
                        }
583
                        else {
584
                                for ( i = 0; i < Nlist; i++ ) Lijst[i] = inLijst[i];
×
585
                                AT.WorkPointer += Nlist;
×
586
                        }
587
                        j = Symmetrize(BHEAD t,Lijst,ngroup,params[6],params[2]);
12✔
588
                        AT.WorkPointer = Lijst;
12✔
589
                        if ( params[2] == 4 ) { /* antisymmetric */
12✔
590
                                if ( ( j & 1 ) != 0 ) sign = -sign;
×
591
                                if ( ( j & 2 ) != 0 ) return(0); /* equal arguments */
×
592
                        }
593
                        if ( ( j & 4 ) != 0 ) sumch++;
12✔
594
                        t[2] &= ~DIRTYSYMFLAG;
12✔
595
                }
596
NextFun:
×
597
                t += t[1];
12✔
598
        }
599
        if ( sign < 0 ) {
12✔
600
                t = term;
×
601
                t += *t - 1;
×
602
                *t = -*t;
×
603
        }
604
        if ( sumch ) {
12✔
605
                if ( Normalize(BHEAD term) ) {
6✔
606
                        MLOCK(ErrorMessageLock);
×
607
                        MesCall("SymGen");
×
608
                        MUNLOCK(ErrorMessageLock);
×
609
                        return(-1);
×
610
                }
611
                if ( !*term ) return(0);
6✔
612
                *AN.RepPoint = 1;
6✔
613
                AR.expchanged = 1;
6✔
614
                if ( AR.CurDum > AM.IndDum && AR.sLevel <= 0 ) ReNumber(BHEAD term);
6✔
615
        }
616
        return(Generator(BHEAD term,level));
12✔
617
}
618

619
/*
620
                 #] SymGen : 
621
                 #[ SymFind :
622

623
                There is a certain amount of double work here, as this routine
624
                finds the function to be treated, while the SymGen routine has
625
                to find it again. Note however that this way things remain
626
                uniform and simple. Moreover this avoids problems with actions
627
                on more than one function simultaneously.
628
                Output in AT.TMout:
629
                Number,sym/anti,fun,lenpar,ngroups,gsize,fields
630

631
*/
632

633
WORD SymFind(PHEAD WORD *term, WORD *params)
12✔
634
{
635
        GETBIDENTITY
636
        WORD *t, *r, *m;
12✔
637
        WORD j, c1, c2, count;
12✔
638
        WORD *rstop;
12✔
639
        c1 = params[4];                /* function number */
12✔
640
        c2 = FUNCTION + WILDOFFSET;
12✔
641
        t = term;
12✔
642
        m = t + *t;
12✔
643
        m -= ABS(m[-1]);
12✔
644
        t++;
12✔
645
        while ( t < m ) {
12✔
646
                if ( *t == c1 || c1 > c2 ) {        /* Candidate function */
12✔
647
                        if ( *t >= FUNCTION && functions[*t-FUNCTION].spec
12✔
648
                                >= TENSORFUNCTION ) { count = t[1] - FUNHEAD; }
×
649
                        else {
650
                                count = 0;
12✔
651
                                r = t;
12✔
652
                                rstop = t + t[1];
12✔
653
                                r += FUNHEAD;
12✔
654
                                while ( r < rstop ) { count++; NEXTARG(r) }
36✔
655
                        }
656
                        if ( ( j = params[5] ) > 0 && j != count ) goto NextFun;
12✔
657
                        if ( j == 0 ) {
12✔
658
                                r = params + 8;
12✔
659
                                rstop = params + params[1];
12✔
660
                                while ( r < rstop ) {
12✔
661
                                        if ( *r > count + 1 ) goto NextFun;
×
662
                                        r++;
×
663
                                }
664
                        }
665
                        
666
                        t = AT.TMout;
12✔
667
                        r = params;
12✔
668
                        j = r[1] - 1;
12✔
669
                        *t++ = j;
12✔
670
                        *t++ = SYMMETRIZE;
12✔
671
                        r += 3;
12✔
672
                        j--;
12✔
673
                        NCOPY(t,r,j);
84✔
674
                        return(1);
675
                }
676
NextFun:
×
677
                t += t[1];
×
678
        }
679
        return(0);
680
}
681

682
/*
683
                 #] SymFind : 
684
                 #[ ChainIn :
685

686
                Equivalent to repeat id f(?a)*f(?b) = f(?a,?b);
687

688
                This one always takes less space.
689
*/
690

691
int ChainIn(PHEAD WORD *term, WORD funnum)
120✔
692
{
693
        GETBIDENTITY
694
        WORD *t, *tend, *m, *tt, *ts;
120✔
695
        int action;
120✔
696
        if ( funnum < 0 ) {        /* Dollar to be expanded */
120✔
697
                funnum = DolToFunction(BHEAD -funnum);
×
698
                if ( AN.ErrorInDollar || funnum <= 0 ) {
×
699
                        MLOCK(ErrorMessageLock);
×
700
                        MesPrint("Dollar variable does not evaluate to function in ChainIn statement");
×
701
                        MUNLOCK(ErrorMessageLock);
×
702
                        return(-1);
×
703
                }
704
        }
705
        do {
204✔
706
                action = 0;
204✔
707
                tend = term+*term;
204✔
708
                tend -= ABS(tend[-1]);
204✔
709
                t = term+1;
204✔
710
                while ( t < tend ) {
444✔
711
                        if ( *t != funnum ) { t += t[1]; continue; }
324✔
712
                        m = t;
201✔
713
                        t += t[1];
201✔
714
                        tt = t;
201✔
715
                        if ( t >= tend || *t != funnum ) continue;
201✔
716
                        action = 1;
186✔
717
                        while ( t < tend && *t == funnum ) {
186✔
718
                                ts = t + t[1];
102✔
719
                                t += FUNHEAD;
102✔
720
                                while ( t < ts ) *tt++ = *t++;
306✔
721
                        }
722
                        m[1] = tt - m;
84✔
723
                        ts = term + *term;
84✔
724
                        while ( t < ts ) *tt++ = *t++;
1,326✔
725
                        *term = tt - term;
84✔
726
                        break;
84✔
727
                }
728
        } while ( action );
84✔
729
        return(0);
730
}
731

732
/*
733
                 #] ChainIn : 
734
                 #[ ChainOut :
735

736
                Equivalent to repeat id f(x1?,x2?,?a) = f(x1)*f(x2,?a);
737
*/
738

739
int ChainOut(PHEAD WORD *term, WORD funnum)
515✔
740
{
741
        GETBIDENTITY
742
        WORD *t, *tend, *tt, *ts, *w, *ws;
515✔
743
        int flag = 0, i;
515✔
744
        if ( funnum < 0 ) {        /* Dollar to be expanded */
515✔
745
                funnum = DolToFunction(BHEAD -funnum);
×
746
                if ( AN.ErrorInDollar || funnum <= 0 ) {
×
747
                        MLOCK(ErrorMessageLock);
×
748
                        MesPrint("Dollar variable does not evaluate to function in ChainOut statement");
×
749
                        MUNLOCK(ErrorMessageLock);
×
750
                        return(-1);
×
751
                }
752
        }
753
        tend = term+*term;
515✔
754
        if ( AT.WorkPointer < tend ) AT.WorkPointer = tend;
515✔
755
        tend -= ABS(tend[-1]);
515✔
756
        t = term+1; tt = term; w = AT.WorkPointer;
515✔
757
        while ( t < tend ) {
1,030✔
758
                if ( *t != funnum || t[1] == FUNHEAD ) { t += t[1]; continue; }
515✔
759
                flag = 1;
10✔
760
                while ( tt < t ) *w++ = *tt++;
10✔
761
                ts = t + t[1];
5✔
762
                t += FUNHEAD;
5✔
763
                while ( t < ts ) {
133✔
764
                        ws = w;
512✔
765
                        for ( i = 0; i < FUNHEAD; i++ ) *w++ = tt[i];
512✔
766
                        if ( functions[*tt-FUNCTION].spec >= TENSORFUNCTION ) {
128✔
767
                                *w++ = *t++;
×
768
                        }
769
                        else if ( *t < 0 ) {
128✔
770
                                if ( *t <= -FUNCTION ) *w++ = *t++;
109✔
771
                                else { *w++ = *t++; *w++ = *t++; }
109✔
772
                        }
773
                        else {
774
                                i = *t; NCOPY(w,t,i);
1,269✔
775
                        }
776
                        ws[1] = w - ws;
128✔
777
                }
778
                tt = t;
779
        }
780
        if ( flag == 1 ) {
515✔
781
                ts = term + *term;
5✔
782
                while ( tt < ts ) *w++ = *tt++;
20✔
783
                *AT.WorkPointer = w - AT.WorkPointer;
5✔
784
                t = term; w = AT.WorkPointer; i = *w;
5✔
785
                NCOPY(t,w,i)
1,877✔
786
                AT.WorkPointer = term + *term;
5✔
787
                Normalize(BHEAD term);
5✔
788
        }
789
        return(0);
790
}
791

792
/*
793
                 #] ChainOut : 
794
          #] Utilities : 
795
        #[ Patterns :
796
                 #[ MatchFunction :                        WORD MatchFunction(pattern,interm,wilds)
797

798
                The routine assumes that the function numbers are the same.
799
                The contents are compared and a possible wildcard assignment
800
                is made. Note that it may be necessary to use a wildcard
801
                assignment stack to do things right.
802
                The routine can become arbitrarily complicated as there is
803
                no end to the possible wildcarding.
804
                Examples:
805
                -        a:        No wildcarding -> straight match
806
                -        b:        Individual arguments (object -> object)
807
                -        c:        whole arguments (object to subexpression)
808
                -        d:        any argumentlist
809
                        e:        part of an argument (object inside subexpression)
810

811
                The ones with a minus sign in front have been implemented.
812

813
                Note: the argument wilds allows backtracking when multiple
814
                ?a,?b give a match that later turns out to be useless.
815
*/
816

817
WORD MatchFunction(PHEAD WORD *pattern, WORD *interm, WORD *wilds)
158,487✔
818
{
819
        GETBIDENTITY
820
        WORD *m, *t, *r, i;
158,487✔
821
        WORD *mstop = 0, *tstop = 0;
158,487✔
822
        WORD *argmstop, *argtstop;
158,487✔
823
        WORD *mtrmstop, *ttrmstop;
158,487✔
824
        WORD *msubstop, *mnextsub;
158,487✔
825
        WORD msizcoef, mcount, tcount, newvalue, j;
158,487✔
826
        WORD *oldm, *oldt;
158,487✔
827
        WORD *OldWork, numofwildarg;
158,487✔
828
        WORD nwstore, tobeeaten, reservevalue = 0, resernum = 0, withwild;
158,487✔
829
        WORD *wildargtaken;
158,487✔
830
        CBUF *C = cbuf+AT.ebufnum;
158,487✔
831
        int ntwa = AN.NumTotWildArgs;
158,487✔
832
        LONG oldcpointer = C->Pointer - C->Buffer;
158,487✔
833
/*
834
        Test first for a straight match
835
*/
836
        AN.RepFunList[AN.RepFunNum+1] = 0;
158,487✔
837
        if ( *wilds == 0 ) {
158,487✔
838
                m = pattern; t = interm;
158,481✔
839

840
                if ( *m != *t ) {
158,481✔
841
                        if ( *m < (FUNCTION + WILDOFFSET) ) return(0);
999✔
842
                        if ( *t < FUNCTION ) return(0);
999✔
843
                        if ( functions[*t-FUNCTION].spec !=
999✔
844
                        functions[*m-FUNCTION-WILDOFFSET].spec ) return(0);
999✔
845
                }
846
                i = m[1];
158,481✔
847
                if ( *m >= (FUNCTION + WILDOFFSET) ) { i--; m++; t++; }
158,481✔
848
                do { if ( *m++ != *t++ ) break; } while ( --i > 0 );
605,519✔
849
                if ( i <= 0 ) {                        /* Arguments match */
158,481✔
850
                        if ( AN.SignCheck && AN.ExpectedSign ) return(0);
36✔
851
                        i = *pattern - WILDOFFSET;
36✔
852
                        if ( i >= FUNCTION ) {
36✔
853
                                if ( *interm != GAMMA
×
UNCOV
854
                                && !CheckWild(BHEAD i,FUNTOFUN,*interm,&newvalue) ) {
×
855
                                        AddWild(BHEAD i,FUNTOFUN,newvalue);
×
UNCOV
856
                                        return(1);
×
857
                                }
858
                                return(0);
×
859
                        }
860
                        else return(1);
861
                }
862
        }
863
/*
864
        Store the current Wildcard assignments
865
*/
866
        t = wildargtaken = OldWork = AT.WorkPointer;
158,451✔
867
        t += ntwa;
158,451✔
868
        m = AN.WildValue;
158,451✔
869
        nwstore = i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
158,451✔
870
        if ( i > 0 ) {
158,451✔
871
                r = AT.WildMask;
158,267✔
872
                do {
175,652✔
873
                        *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
175,652✔
874
                } while ( --i > 0 );
175,652✔
875
                *t++ = C->numrhs;
158,267✔
876
        }
877
        if ( t >= AT.WorkTop ) {
158,451✔
UNCOV
878
                MLOCK(ErrorMessageLock);
×
UNCOV
879
                MesWork();
×
UNCOV
880
                MUNLOCK(ErrorMessageLock);
×
UNCOV
881
                Terminate(-1);
×
882
        }
883
        AT.WorkPointer = t;
158,451✔
884

885
        if ( *wilds ) {
158,451✔
886
                if ( *wilds == 1 ) goto endoloop;
6✔
UNCOV
887
                else               goto enloop;                        /* tensors = 2 */
×
888
        }
889
        m = pattern; t = interm;
158,445✔
890
/*
891
        Single out the specials
892
*/
893
        if ( *t == GAMMA ) {
158,445✔
894
/*
895
                 #[ GAMMA :
896

897
                For the gamma's we need to do two things:
898
                a:        Find that there is a match
899
                b:        Find where the match occurs in the string
900
                This last thing cannot be stored in the current conventions,
901
                but once the wildcard assignments have been made it is much
902
                easier to find it back.
903
                Alternative: replace the function number in the term temporarily
904
                by the offset inside the string. This makes things maybe easier.
905
*/
UNCOV
906
                if ( *m != GAMMA ) goto NoCaseB;
×
UNCOV
907
                i = t[1] - m[1];
×
UNCOV
908
                if ( m[1] == FUNHEAD+1 ) {
×
UNCOV
909
                        if ( i ) goto NoCaseB;
×
910
                        if ( m[FUNHEAD] < (AM.OffsetIndex+WILDOFFSET) ||
×
911
                        t[FUNHEAD] >= (AM.OffsetIndex+WILDOFFSET) ) goto NoCaseB;
×
912

913
                        if ( CheckWild(BHEAD m[FUNHEAD]-WILDOFFSET,INDTOIND,t[FUNHEAD],&newvalue) ) goto NoCaseB;
×
914
                        AddWild(BHEAD m[FUNHEAD]-WILDOFFSET,INDTOIND,newvalue);
×
915
                        
UNCOV
916
                        AT.WorkPointer = OldWork;
×
917
                        if ( AN.SignCheck && AN.ExpectedSign ) return(0);
×
918
                        return(1);                /* m was eaten. we have a match! */
×
919
                }
920
                if ( i < 0 ) goto NoCaseB;        /* Pattern longer than target */
×
921
                mstop = m + m[1];
×
922
                tstop = t + t[1];
×
UNCOV
923
                m += FUNHEAD; t += FUNHEAD;
×
924
                if ( *m >= (AM.OffsetIndex+WILDOFFSET) && *t < (AM.OffsetIndex+WILDOFFSET) ) {
×
925
                        if ( CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*t,&newvalue) ) goto NoCaseB;
×
926
                        reservevalue = newvalue;
×
927
                        withwild = 1;
×
928
                        resernum = *m-WILDOFFSET;
×
929
                        AddWild(BHEAD *m-WILDOFFSET,INDTOIND,newvalue);
×
930
                }
931
                else if ( *m != *t ) goto NoCaseB;
×
932
                else withwild = 0;
933
                m++; t++;
×
UNCOV
934
                oldm = m; argtstop = oldt = t;
×
935
                j = 0;                                        /* No wildcard assignments yet */
×
UNCOV
936
                while ( i >= 0 ) {
×
937
                        if ( *m == *t ) {
×
938
WithGamma:                m++; t++;
×
939
                                if ( m >= mstop ) {
×
940
                                        if ( t < tstop && mstop < AN.patstop ) {
×
941
                                                WORD k;
×
942
                                                mnextsub = pattern + pattern[1];
×
943
                                                k = *mnextsub;
×
944
                                                while ( k == GAMMA && mnextsub[FUNHEAD]
×
945
                                                != pattern[FUNHEAD] ) {
×
946
                                                        mnextsub += mnextsub[1];
×
947
                                                        if ( mnextsub >= AN.patstop ) goto FullOK;
×
948
                                                        k = *mnextsub;
×
949
                                                }
950
                                                if ( k >= FUNCTION ) {
×
951
                                                        if ( k > (FUNCTION + WILDOFFSET) ) k -= WILDOFFSET;
×
952
                                                        if ( functions[k-FUNCTION].commute ) goto NoGamma;
×
953
                                                }
954
                                        }
955
FullOK:                                if ( AN.SignCheck && AN.ExpectedSign ) goto NoGamma;
×
956
                                        AN.RepFunList[AN.RepFunNum+1] = WORDDIF(oldt,argtstop);
×
UNCOV
957
                                        return(1);
×
958
                                }
959
                                if ( t >= tstop ) goto NoCaseB;
×
960
                        }
961
                        else if ( *m >= (AM.OffsetIndex+WILDOFFSET)
×
UNCOV
962
                        && *m < (AM.OffsetIndex + (WILDOFFSET<<1)) && ( *t >= 0 ||
×
963
                        *t < MINSPEC ) ) {                        /* Wildcard index */
UNCOV
964
                                if ( !CheckWild(BHEAD *m-WILDOFFSET,INDTOIND,*t,&newvalue) ) {
×
965
                                        AddWild(BHEAD *m-WILDOFFSET,INDTOIND,newvalue);
×
966
                                        j = 1;
×
UNCOV
967
                                        goto WithGamma;
×
968
                                }
969
                                else goto NoGamma;
×
970
                        }
971
                        else if ( *m < MINSPEC && *m >= (AM.OffsetVector+WILDOFFSET)
×
NEW
972
                        && *t < MINSPEC ) {                        /* Wildcard vector */
×
973
                                if ( !CheckWild(BHEAD *m-WILDOFFSET,VECTOVEC,*t,&newvalue) ) {
×
UNCOV
974
                                        AddWild(BHEAD *m-WILDOFFSET,VECTOVEC,newvalue);
×
975
                                        j = 1;
×
976
                                        goto WithGamma;
×
977
                                }
978
                                else goto NoGamma;
×
979
                        }
980
                        else {
UNCOV
981
NoGamma:
×
982
                                if ( j ) {                /* Undo wildcards */
×
UNCOV
983
                                        m = AN.WildValue;
×
UNCOV
984
                                        t = OldWork + AN.NumTotWildArgs; r = AT.WildMask; j = nwstore;
×
985
                                        if ( j > 0 ) {
×
986
                                                do {
×
987
                                                        *m++ = *t++; *m++ = *t++;
×
988
                                                        *m++ = *t++; *m++ = *t++; *r++ = *t++;
×
989
                                                } while ( --j > 0 );
×
990
                                                C->numrhs = *t++;
×
991
                                                C->Pointer = C->Buffer + oldcpointer;
×
992
                                        }
993
                                        j = 0;
994
                                }
995
                                m = oldm; t = ++oldt; i--;
×
UNCOV
996
                                if ( withwild ) {
×
UNCOV
997
                                        AddWild(BHEAD resernum,INDTOIND,reservevalue);
×
998
                                }
999
                        }
1000
                }
1001
                goto NoCaseB;
×
1002
/*
1003
                 #] GAMMA : 
1004
                 #[ Tensors :
1005
*/
1006
        }
1007
        else if ( *t >= FUNCTION && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) {
158,445✔
UNCOV
1008
                mstop = m + m[1];
×
UNCOV
1009
                tstop = t + t[1];
×
UNCOV
1010
                mcount = 0;
×
UNCOV
1011
                m += FUNHEAD;
×
1012
                t += FUNHEAD;
×
1013
                AN.WildArgs = 0;
×
1014
                tcount = WORDDIF(tstop,t);
×
1015
                while ( m < mstop ) {
×
1016
                        if ( *m == FUNNYWILD ) { m++; AN.WildArgs++; }
×
1017
                        m++; mcount++;
×
1018
                }
1019
                tobeeaten = tcount - mcount + AN.WildArgs;
×
1020
                if ( tobeeaten ) {
×
1021
                        if ( tobeeaten < 0 || AN.WildArgs == 0 ) {
×
UNCOV
1022
                                AT.WorkPointer = OldWork;
×
1023
                                return(0);        /* Cannot match */
×
1024
                        }
1025
                }
1026
                AT.WildArgTaken[0] = AN.WildEat = tobeeaten;
×
1027
                for ( i = 1; i < AN.WildArgs; i++ ) AT.WildArgTaken[i] = 0;
×
UNCOV
1028
toploop:
×
UNCOV
1029
                numofwildarg = 0;
×
1030

1031
                m = pattern; t = interm;
×
1032
                mstop = m + m[1];
×
1033
                if ( *m != *t ) {
×
UNCOV
1034
                        i = *m - WILDOFFSET;
×
1035
                        if ( CheckWild(BHEAD i,FUNTOFUN,*t,&newvalue) ) goto NoCaseB;
×
1036
                        AddWild(BHEAD i,FUNTOFUN,newvalue);
×
1037
                }
1038
                m += FUNHEAD;
×
1039
                t += FUNHEAD;
×
1040
                while ( m < mstop ) {
×
1041
/*
1042
                        First test for an exact match
1043
*/
1044
                        if ( *m == *t ) { m++; t++; continue; }
×
1045
/*
1046
                        No exact match. Try ARGWILD
1047
*/
1048
                        AN.argaddress = t;
×
UNCOV
1049
                        if ( *m == FUNNYWILD ) {
×
UNCOV
1050
                                tobeeaten = AT.WildArgTaken[numofwildarg++];
×
UNCOV
1051
                                if ( CheckWild(BHEAD m[1],ARGTOARG|EATTENSOR,tobeeaten,t) ) goto endloop;
×
1052
                                AddWild(BHEAD m[1],ARGTOARG,i);
×
1053
                                m += 2;
×
1054
                                t += tobeeaten;
×
1055
                                continue;
×
1056
                        }
1057
/*
1058
                        Now the various cases:
1059
*/
UNCOV
1060
                        i = *m;
×
UNCOV
1061
                        if ( i < MINSPEC ) {
×
UNCOV
1062
                                if ( *t != i ) {
×
UNCOV
1063
                                        if ( *t >= MINSPEC ) goto endloop;
×
1064
                                        i -= WILDOFFSET;
×
1065
                                        if ( i < AM.OffsetVector ) goto endloop;
×
1066
                                        if ( CheckWild(BHEAD i,VECTOVEC,*t,&newvalue) )
×
1067
                                                goto endloop;
×
1068
                                        AddWild(BHEAD i,VECTOVEC,newvalue);
×
1069
                                }
1070
                        }
1071
                        else if ( i >= AM.OffsetIndex ) {                        /* Index */
×
1072
                                if ( i < ( AM.OffsetIndex + WILDOFFSET ) ) goto endloop;
×
UNCOV
1073
                                if ( i >= ( AM.OffsetIndex + (WILDOFFSET<<1) ) ) {
×
1074
                                                                                                /* Summed over index */
1075
                                        goto endloop;                                /* For the moment */
×
1076
                                }
1077
                                i -= WILDOFFSET;
×
UNCOV
1078
                                if ( CheckWild(BHEAD i,INDTOIND,*t,&newvalue) )
×
1079
                                        goto endloop;                /* Assignment not allowed */
×
UNCOV
1080
                                AddWild(BHEAD i,INDTOIND,newvalue);
×
1081
                        }
1082
                        else goto endloop;
×
1083
                        m++; t++;
×
1084
                }
UNCOV
1085
                if ( AN.SignCheck && AN.ExpectedSign ) goto endloop;
×
1086
                AT.WorkPointer = OldWork;
×
1087
                if ( AN.WildArgs > 1 ) *wilds = 2;
×
UNCOV
1088
                return(1);                /* m was eaten. we have a match! */
×
1089

1090
endloop:;
×
1091
/*
1092
        restore the current Wildcard assignments
1093
*/
1094
                i = nwstore;
×
UNCOV
1095
                if ( i > 0 ) {
×
UNCOV
1096
                        m = AN.WildValue;
×
UNCOV
1097
                        t = OldWork + ntwa; r = AT.WildMask;
×
1098
                        do {
×
1099
                                *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
×
1100
                        } while ( --i > 0 );
×
1101
                        C->numrhs = *t++;
×
1102
                        C->Pointer = C->Buffer + oldcpointer;
×
1103
                }
1104
enloop:;
×
1105
                i = AN.WildArgs - 1;
×
1106
                if ( i <= 0 ) {
×
UNCOV
1107
                        AT.WorkPointer = OldWork;
×
1108
                        return(0);
×
1109
                }
1110
                while ( --i >= 0 ) {
×
1111
                        if ( AT.WildArgTaken[i] == 0 ) {
×
1112
                                if ( i == 0 ) {
×
UNCOV
1113
                                        AT.WorkPointer = OldWork;
×
1114
                                        *wilds = 0;
×
1115
                                        return(0);
×
1116
                                }
1117
                        }
1118
                        else {
1119
                                (AT.WildArgTaken[i])--;
×
UNCOV
1120
                                numofwildarg = 0;
×
UNCOV
1121
                                for ( j = 0; j <= i; j++ ) {
×
UNCOV
1122
                                        numofwildarg += AT.WildArgTaken[j];
×
1123
                                }
1124
                                AT.WildArgTaken[j] = AN.WildEat-numofwildarg;
×
1125
                                for ( j++; j < AN.WildArgs; j++ ) AT.WildArgTaken[j] = 0;
×
1126
                                break;
1127
                        }
1128
                }
1129
                goto toploop;
×
1130
/*
1131
                 #] Tensors : 
1132
*/
1133
        }
1134
/*
1135
        Count the number of arguments. Either equal or an argument wildcard.
1136
*/
1137
        mstop = m + m[1];
158,445✔
1138
        tstop = t + t[1];
158,445✔
1139
        mcount = 0; tcount = 0;
158,445✔
1140
        m += FUNHEAD; t += FUNHEAD;
158,445✔
1141
        while ( t < tstop ) { tcount++; NEXTARG(t) }
666,201✔
1142
        AN.WildArgs = 0;
158,445✔
1143
        while ( m < mstop ) {
330,129✔
1144
                mcount++;
171,684✔
1145
                if ( *m == -ARGWILD ) AN.WildArgs++;
171,684✔
1146
                NEXTARG(m)
171,684✔
1147
        }
1148
        tobeeaten = tcount - mcount + AN.WildArgs;
158,445✔
1149
        if ( tobeeaten ) {
158,445✔
1150
                if ( tobeeaten < 0 || AN.WildArgs == 0 ) {
8,853✔
1151
                        AT.WorkPointer = OldWork;
36✔
1152
                        return(0);        /* Cannot match */
36✔
1153
                }
1154
        }
1155
/*
1156
        Set up the array AT.WildArgTaken for the number of arguments that each
1157
        wildarg eats.
1158
*/
1159
        AT.WildArgTaken[0] = AN.WildEat = tobeeaten;
158,409✔
1160
        for ( i = 1; i < AN.WildArgs; i++ ) AT.WildArgTaken[i] = 0;
164,607✔
1161
topofloop:
158,409✔
1162
        numofwildarg = 0;
2,987,706✔
1163
/*
1164
        Test for single wildcard object/argument
1165
*/
1166
        m = pattern; t = interm;
2,987,706✔
1167
        if ( *m != *t ) {
2,987,706✔
1168
                i = *m - WILDOFFSET;
999✔
1169
                if ( CheckWild(BHEAD i,FUNTOFUN,*t,&newvalue) ) goto NoCaseB;
999✔
1170
                AddWild(BHEAD i,FUNTOFUN,newvalue);
999✔
1171
        }
1172
        mstop = m + m[1];
2,987,706✔
1173
/*        tstop = t + t[1];  */
1174
        m += FUNHEAD;
2,987,706✔
1175
        t += FUNHEAD;
2,987,706✔
1176
        while ( m < mstop ) {
11,646,640✔
1177
                argmstop = oldm = m;
11,488,460✔
1178
                argtstop = oldt = t;
11,488,460✔
1179
                NEXTARG(argmstop)
11,488,460✔
1180
                NEXTARG(argtstop)
11,488,460✔
1181
                if ( t == tstop ) { /* This concerns a very rare bug */
11,488,460✔
1182
                        if ( *m == -ARGWILD ) goto ArgAll;
274✔
UNCOV
1183
                        goto endofloop;
×
1184
                }
1185
                if ( *m < 0 && *t < 0 ) {
11,488,190✔
1186
                        if ( *t <= -FUNCTION ) {
11,481,310✔
1187
                                if ( *t == *m ) {}
6✔
1188
                                else if ( *m <= -FUNCTION-WILDOFFSET
6✔
UNCOV
1189
                                && functions[-*t-FUNCTION].spec
×
UNCOV
1190
                                == functions[-*m-FUNCTION-WILDOFFSET].spec ) {
×
UNCOV
1191
                                        i = -*m - WILDOFFSET;
×
UNCOV
1192
                                        if ( CheckWild(BHEAD i,FUNTOFUN,-*t,&newvalue) ) goto endofloop;
×
1193
                                        AddWild(BHEAD i,FUNTOFUN,newvalue);
×
1194
                                }
1195
                                else if ( *m == -SYMBOL && m[1] >= 2*MAXPOWER ) {
6✔
1196
                                        i = m[1] - 2*MAXPOWER;
×
1197
                                        AN.argaddress = AT.FunArg;
×
UNCOV
1198
                                        AT.FunArg[ARGHEAD+1] = -*t;
×
UNCOV
1199
                                        if ( CheckWild(BHEAD i,SYMTOSUB,1,AN.argaddress) ) goto endofloop;
×
1200
                                        AddWild(BHEAD i,SYMTOSUB,0);
×
1201
                                }
1202
                                else if ( *m == -ARGWILD ) {
6✔
1203
ArgAll:                                i = AT.WildArgTaken[numofwildarg++];
6✔
1204
                                        AN.argaddress = t;
5,673,480✔
1205
                                        if ( CheckWild(BHEAD m[1],ARGTOARG,i,t) ) goto endofloop;
5,673,480✔
1206
                                        AddWild(BHEAD m[1],ARGTOARG,i);
5,673,480✔
1207
/*                                        m += 2; */
1208
                                        while ( --i >= 0 ) { NEXTARG(t) }
157,580,000✔
1209
                                        argtstop = t;
1210
                                }
UNCOV
1211
                                else goto endofloop;
×
1212
                        }
1213
                        else if ( *t == *m ) {
11,481,300✔
1214
                                if ( t[1] == m[1] ) {}
5,664,810✔
1215
                                else if ( *t == -SYMBOL ) {
5,664,660✔
1216
                                        j = SYMTOSYM;
1217
SymAll:
144,191✔
1218
                                        if ( ( i = m[1] - 2*MAXPOWER ) < 0 ) goto endofloop;
144,191✔
1219
                                        if ( CheckWild(BHEAD i,j,t[1],&newvalue) ) goto endofloop;
144,191✔
1220
                                        AddWild(BHEAD i,j,newvalue);
144,080✔
1221
                                }
1222
                                else if ( *t == -INDEX ) {
5,664,510✔
1223
IndAll:                                i = m[1] - WILDOFFSET;
18✔
1224
                                        if ( i < AM.OffsetIndex || i >= WILDOFFSET+AM.OffsetIndex )
834✔
UNCOV
1225
                                                                                                                        goto endofloop;
×
1226
                                                                /* We kill the summed over indices here */
1227
                                        if ( CheckWild(BHEAD i,INDTOIND,t[1],&newvalue) ) goto endofloop;
834✔
1228
                                        AddWild(BHEAD i,INDTOIND,newvalue);
810✔
1229
                                }
1230
                                else if ( *t == -VECTOR || *t == -MINVECTOR ) {
5,664,480✔
1231
                                        i = m[1] - WILDOFFSET;
5,664,450✔
1232
                                        if ( i < AM.OffsetVector ) goto endofloop;
5,664,450✔
1233
                                        if ( CheckWild(BHEAD i,VECTOVEC,t[1],&newvalue) ) goto endofloop;
5,664,450✔
1234
                                        AddWild(BHEAD i,VECTOVEC,newvalue);
2,835,234✔
1235
                                }
1236
                                else goto endofloop;
24✔
1237
                        }
1238
                        else if ( *m == -ARGWILD ) goto ArgAll;
5,816,500✔
1239
                        else if ( *m == -INDEX && m[1] >= AM.OffsetIndex+WILDOFFSET
144,953✔
1240
                        && m[1] < AM.OffsetIndex+(WILDOFFSET<<1) ) {
897✔
1241
                                if ( *t == -VECTOR ) goto IndAll;
897✔
1242
                                if ( *t == -SNUMBER && t[1] >= 0 && t[1] < AM.OffsetIndex ) goto IndAll;
891✔
1243
                                if ( *t == -MINVECTOR ) {
81✔
UNCOV
1244
                                        i = m[1] - WILDOFFSET;
×
UNCOV
1245
                                        AN.argaddress = AT.MinVecArg;
×
UNCOV
1246
                                        AT.MinVecArg[ARGHEAD+3] = t[1];
×
UNCOV
1247
                                        if ( CheckWild(BHEAD i,INDTOSUB,1,AN.argaddress) ) goto endofloop;
×
1248
                                        AddWild(BHEAD i,INDTOSUB,(WORD)0);
×
1249
                                }
1250
                                else goto endofloop;
81✔
1251
                        }
1252
                        else if ( *m == -SYMBOL && m[1] >= 2*MAXPOWER && *t == -SNUMBER ) {
144,056✔
1253
                                j = SYMTONUM;
144,029✔
1254
                                goto SymAll;
144,029✔
1255
                        }
1256
                        else if ( *m == -VECTOR && *t == -MINVECTOR &&
27✔
1257
                        ( i = m[1] - WILDOFFSET ) >= AM.OffsetVector ) {
15✔
1258
/*
1259
================================
1260
                                AN.argaddress = AT.MinVecArg;
1261
                                AT.MinVecArg[ARGHEAD+3] = t[1];
1262
                                if ( CheckWild(BHEAD i,VECTOSUB,1,AN.argaddress) ) goto endofloop;
1263
                                AddWild(BHEAD i,VECTOSUB,(WORD)0);
1264
================================
1265
*/
1266
                                if ( CheckWild(BHEAD i,VECTOMIN,t[1],&newvalue) ) goto endofloop;
15✔
1267
                                AddWild(BHEAD i,VECTOMIN,newvalue);
9✔
1268

1269
                        }
1270
                        else if ( *m == -MINVECTOR && *t == -VECTOR &&
12✔
1271
                        ( i = m[1] - WILDOFFSET ) >= AM.OffsetVector ) {
6✔
1272
/*
1273
================================
1274
                                AN.argaddress = AT.MinVecArg;
1275
                                AT.MinVecArg[ARGHEAD+3] = t[1];
1276
                                if ( CheckWild(BHEAD i,VECTOSUB,1,AN.argaddress) ) goto endofloop;
1277
                                AddWild(BHEAD i,VECTOSUB,(WORD)0);
1278
================================
1279
*/
1280
                                if ( CheckWild(BHEAD i,VECTOMIN,t[1],&newvalue) ) goto endofloop;
6✔
UNCOV
1281
                                AddWild(BHEAD i,VECTOMIN,newvalue);
×
1282
                        }
1283
                        else goto endofloop;
6✔
1284
                }
1285
                else if ( *t <= -FUNCTION && *m > 0 ) {
6,879✔
1286
                        if ( ( m[ARGHEAD]+ARGHEAD == *m ) && m[*m-1] == 3
18✔
1287
                        && m[*m-2] == 1 && m[*m-3] == 1 && m[ARGHEAD+1] >= FUNCTION
18✔
1288
                        && m[ARGHEAD+2] == *m-ARGHEAD-4 ) { /* Check for f(?a) etc */
18✔
1289
                                WORD *mmmst, *mmm;
18✔
1290
                                if ( m[ARGHEAD+1] >= FUNCTION+WILDOFFSET ) {
18✔
1291
/*                                        i = *m - WILDOFFSET; */
1292
                                        i = m[ARGHEAD+1] - WILDOFFSET;
18✔
1293
                                        if ( CheckWild(BHEAD i,FUNTOFUN,-*t,&newvalue) ) goto endofloop;
18✔
1294
                                        AddWild(BHEAD i,FUNTOFUN,newvalue);
18✔
1295
                                }
UNCOV
1296
                                else if ( m[ARGHEAD+1] != -*t ) goto endofloop;
×
1297
/*
1298
                                        Only arguments allowed are ?a etc.
1299
*/
1300
                                mmmst = m+*m-3;
18✔
1301
                                mmm = m + ARGHEAD + FUNHEAD + 1;
18✔
1302
                                while ( mmm < mmmst ) {
36✔
1303
                                        if ( *mmm != -ARGWILD ) goto endofloop;
18✔
1304
                                        i = 0;
18✔
1305
                                        AN.argaddress = t;
18✔
1306
                                        if ( CheckWild(BHEAD mmm[1],ARGTOARG,i,t) ) goto endofloop;
18✔
1307
                                        AddWild(BHEAD mmm[1],ARGTOARG,i);
18✔
1308
                                        mmm += 2;
18✔
1309
                                }
1310
                        }
UNCOV
1311
                        else goto endofloop;
×
1312
                }
1313
                else if ( *m < 0 && *t > 0 ) {
6,861✔
1314
                        if ( *m == -SYMBOL ) {                        /* SYMTOSUB */
6,294✔
1315
                                if ( m[1] < 2*MAXPOWER ) goto endofloop;
4,620✔
1316
                                i = m[1] - 2*MAXPOWER;
4,611✔
1317
                                AN.argaddress = t;
4,611✔
1318
                                if ( CheckWild(BHEAD i,SYMTOSUB,1,AN.argaddress) ) goto endofloop;
4,611✔
1319
                                AddWild(BHEAD i,SYMTOSUB,0);
4,602✔
1320
                        }
1321
                        else if ( *m == -VECTOR ) {
1,674✔
UNCOV
1322
                                if ( ( i = m[1] - WILDOFFSET ) < AM.OffsetVector )
×
UNCOV
1323
                                                                                                                        goto endofloop;
×
UNCOV
1324
                                AN.argaddress = t;
×
UNCOV
1325
                                if ( CheckWild(BHEAD i,VECTOSUB,1,t) ) goto endofloop;
×
1326
                                AddWild(BHEAD i,VECTOSUB,(WORD)0);
×
1327
                        }
1328
                        else if ( *m == -INDEX ) {
1,674✔
1329
                                if ( ( i = m[1] - WILDOFFSET ) < AM.OffsetIndex ) goto endofloop;
×
1330
                                if ( i >= AM.OffsetIndex + WILDOFFSET ) goto endofloop;
×
UNCOV
1331
                                AN.argaddress = t;
×
UNCOV
1332
                                if ( CheckWild(BHEAD i,INDTOSUB,1,AN.argaddress) ) goto endofloop;
×
1333
                                AddWild(BHEAD i,INDTOSUB,(WORD)0);
×
1334
                        }
1335
                        else if ( *m == -ARGWILD ) goto ArgAll;
1,674✔
1336
                        else goto endofloop;
18✔
1337
                }
1338
                else if ( *m > 0 && *t > 0 ) {
567✔
1339
                        WORD ii = *t-*m;
873✔
1340
                        i = *m;
873✔
1341
                        do { if ( *m++ != *t++ ) break; } while ( --i > 0 );
873✔
1342
                        if ( i == 1 && ii == 0 ) {        /* sign difference */
567✔
1343
                                goto endofloop;
3✔
1344
                        }
1345
                        else if ( i > 0 ) {
564✔
1346
                                WORD *cto, *cfrom, *csav, ci;
564✔
1347
                                WORD oRepFunNum;
564✔
1348
                                WORD *oRepFunList;
564✔
1349
                                WORD *oterstart,*oterstop,*opatstop;
564✔
1350
                                WORD oExpectedSign;
564✔
1351
                                WORD wildargs, wildeat;
564✔
1352
/*
1353
                                Not an exact match here.
1354
                                We have to hope that the pattern contains a composite wildcard.
1355
*/
1356
                                m = oldm; t = oldt;
564✔
1357
                                m += ARGHEAD; t += ARGHEAD;                        /* Point at (first?) term */
564✔
1358
                                mtrmstop = m + *m;
564✔
1359
                                ttrmstop = t + *t;
564✔
1360
                                if ( mtrmstop < argmstop ) goto endofloop;/* More than one term */
564✔
1361
                                msizcoef = mtrmstop[-1];
564✔
1362
                                if ( msizcoef < 0 ) msizcoef = -msizcoef;
564✔
1363
                                msubstop = mtrmstop - msizcoef;
564✔
1364
                                m++;
564✔
1365
                                if ( m >= msubstop ) goto endofloop;        /* Only coefficient */
564✔
1366
/*
1367
                                Here we have a composite term. It can match provided it
1368
                                matches the entire argument. This argument must be a
1369
                                single term also and the coefficients should match
1370
                                (more or less).
1371
                                The matching takes:
1372
                                1:        Match the functions etc. Nothing can be left.
1373
                                2:        Match dotproducts and symbols. ONLY must match
1374
                                        and nothing may be left.
1375
                                For safety it is best to take the term out and put it
1376
                                in workspace.
1377
*/
1378

1379
                                if ( argtstop > ttrmstop ) goto endofloop;
564✔
1380
                                m--;
564✔
1381
                                oterstart = AN.terstart;
564✔
1382
                                oterstop = AN.terstop;
564✔
1383
                                opatstop = AN.patstop;
564✔
1384
                                oRepFunList = AN.RepFunList;
564✔
1385
                                oRepFunNum = AN.RepFunNum;
564✔
1386
                                AN.RepFunNum = 0;
564✔
1387
                                AN.RepFunList = AT.WorkPointer;
564✔
1388
                        AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
564✔
1389
                                if ( AT.WorkPointer+*t+5 > AT.WorkTop ) {
564✔
UNCOV
1390
                                        MLOCK(ErrorMessageLock);
×
UNCOV
1391
                                        MesWork();
×
UNCOV
1392
                                        MUNLOCK(ErrorMessageLock);
×
UNCOV
1393
                                        return(-1);
×
1394
                                }
1395
                                csav = cto = AT.WorkPointer;
12,288✔
1396
                                cfrom = t;
1397
                                ci = *t;
1398
                                while ( --ci >= 0 ) *cto++ = *cfrom++;
12,288✔
1399
                                AT.WorkPointer = cto;
564✔
1400
                                ci = msizcoef;
564✔
1401
                                cfrom = mtrmstop;
564✔
1402
                                --ci;
564✔
1403
                                if ( abs(*--cfrom) != abs(*--cto) ) {
564✔
UNCOV
1404
                                        AT.WorkPointer = csav;
×
UNCOV
1405
                                        AN.RepFunList = oRepFunList;
×
UNCOV
1406
                                        AN.RepFunNum = oRepFunNum;
×
UNCOV
1407
                                        AN.terstart = oterstart;
×
1408
                                        AN.terstop = oterstop;
×
1409
                                        AN.patstop = opatstop;
×
1410
                                        goto endofloop;
×
1411
                                }
1412
                                i = (*cfrom != *cto) ? 1 : 0; /* buffer AN.ExpectedSign until we are beyond the goto */
564✔
1413
                                while ( --ci >= 0 ) {
1,692✔
1414
                                        if ( *--cfrom != *--cto ) {
1,128✔
UNCOV
1415
                                                AT.WorkPointer = csav;
×
UNCOV
1416
                                                AN.RepFunList = oRepFunList;
×
UNCOV
1417
                                                AN.RepFunNum = oRepFunNum;
×
UNCOV
1418
                                                AN.terstart = oterstart;
×
1419
                                                AN.terstop = oterstop;
×
1420
                                                AN.patstop = opatstop;
×
1421
                                                goto endofloop;
×
1422
                                        }
1423
                                }
1424
                                oExpectedSign =  AN.ExpectedSign; /* buffer AN.ExpectedSign until we are beyond FindRest/FindOnly */
564✔
1425
                                AN.ExpectedSign = i;
564✔
1426
                                *m -= msizcoef;
564✔
1427
                                wildargs = AN.WildArgs;
564✔
1428
                                wildeat = AN.WildEat;
564✔
1429
                                for ( i = 0; i < wildargs; i++ ) wildargtaken[i] = AT.WildArgTaken[i];
564✔
1430
                                AN.ForFindOnly = 0; AN.UseFindOnly = 1;
564✔
1431
                                AN.nogroundlevel++;
564✔
1432
                                if ( FindRest(BHEAD csav,m) && ( AN.UsedOtherFind || FindOnly(BHEAD csav,m) ) ) {}
564✔
1433
                                else {
1434
nomatch:
6✔
1435
                                        *m += msizcoef;
6✔
1436
                                        AT.WorkPointer = csav;
6✔
1437
                                        AN.RepFunList = oRepFunList;
6✔
1438
                                        AN.RepFunNum = oRepFunNum;
6✔
1439
                                        AN.terstart = oterstart;
6✔
1440
                                        AN.terstop = oterstop;
6✔
1441
                                        AN.patstop = opatstop;
6✔
1442
                                        AN.WildArgs = wildargs;
6✔
1443
                                        AN.WildEat = wildeat;
6✔
1444
                                        AN.ExpectedSign = oExpectedSign;
6✔
1445
                                        AN.nogroundlevel--;
6✔
1446
                                        for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
6✔
1447
                                        goto endofloop;
6✔
1448
                                }
1449
/*                                if ( *m == 1 || m[1] < FUNCTION || functions[m[1]-FUNCTION].spec >= TENSORFUNCTION ) { */
1450
                                if ( *m == 1 || m[1] < FUNCTION ) {
558✔
UNCOV
1451
                                        if ( AN.ExpectedSign ) goto nomatch;
×
1452
                                }
1453
                                else {
1454
                                        if ( m[1] > FUNCTION + WILDOFFSET ) {
558✔
1455
                                                if ( functions[m[1]-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION ) {
552✔
UNCOV
1456
                                                        if ( AN.ExpectedSign != AN.RepFunList[AN.RepFunNum-1] ) goto nomatch;
×
1457
                                                }
1458
                                        }
1459
                             else {
1460
                                                if ( AN.ExpectedSign != AN.RepFunList[AN.RepFunNum-1] ) goto nomatch;
6✔
1461
/*
1462
                                                if ( functions[m[1]-FUNCTION].spec >= TENSORFUNCTION ) {
1463
                                                        if ( AN.ExpectedSign != AN.RepFunList[AN.RepFunNum-1] ) goto nomatch;
1464
                                                }
1465
*/
1466
                                        }
1467
                                }
1468
                                AN.nogroundlevel--;
558✔
1469
                                AN.ExpectedSign = oExpectedSign;
558✔
1470
                                AN.WildArgs = wildargs;
558✔
1471
                                AN.WildEat = wildeat;
558✔
1472
                                for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
558✔
1473
                                Substitute(BHEAD csav,m,1);
558✔
1474
                                cto = csav;
558✔
1475
                                cfrom = cto + *cto - msizcoef;
558✔
1476
                                cto++;
558✔
1477
                                *m += msizcoef;
558✔
1478
                                AT.WorkPointer = csav;
558✔
1479
                                AN.RepFunList = oRepFunList;
558✔
1480
                                AN.RepFunNum = oRepFunNum;
558✔
1481
                                AN.terstart = oterstart;
558✔
1482
                                AN.terstop = oterstop;
558✔
1483
                                AN.patstop = opatstop;
558✔
1484
                                if ( *cto != SUBEXPRESSION ) goto endofloop;
558✔
1485
                                cto += cto[1];
558✔
1486
                                if ( cto < cfrom ) goto endofloop;
558✔
1487
                        }
1488
                }
UNCOV
1489
                else goto endofloop;
×
1490

1491
                t = argtstop;                                                /* Next argument */
1492
                m = argmstop;
1493
        }
1494
        if ( AN.SignCheck && AN.ExpectedSign ) goto endofloop;
158,169✔
1495
        AT.WorkPointer = OldWork;
158,169✔
1496
        if ( AN.WildArgs > 1 ) *wilds = 1;
158,169✔
1497
        if ( AN.SignCheck && AN.ExpectedSign ) return(0);
158,169✔
1498
        return(1);                /* m was eaten. we have a match! */
1499

1500
endofloop:;
2,829,531✔
1501
/*
1502
        restore the current Wildcard assignments
1503
*/
1504
        i = nwstore;
2,829,531✔
1505
        if ( i > 0 ) {
2,829,531✔
1506
                m = AN.WildValue;
2,829,477✔
1507
                t = OldWork + ntwa; r = AT.WildMask;
2,829,477✔
1508
                do {
11,317,680✔
1509
                        *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
11,317,680✔
1510
                } while ( --i > 0 );
11,317,680✔
1511
                C->numrhs = *t++;
2,829,477✔
1512
                C->Pointer = C->Buffer + oldcpointer;
2,829,477✔
1513
        }
1514

1515
endoloop:;
54✔
1516
        i = AN.WildArgs-1;
2,829,537✔
1517
        if ( i <= 0 ) {
2,829,537✔
1518
                AT.WorkPointer = OldWork;
177✔
1519
                return(0);
177✔
1520
        }
1521
        while ( --i >= 0 ) {
2,954,742✔
1522
                if ( AT.WildArgTaken[i] == 0 ) {
2,954,742✔
1523
                        if ( i == 0 ) {
125,451✔
1524
                                AT.WorkPointer = OldWork;
69✔
1525
                                return(0);
69✔
1526
                        }
1527
                }
1528
                else {
1529
                        (AT.WildArgTaken[i])--;
2,829,291✔
1530
                        numofwildarg = 0;
2,829,291✔
1531
                        for ( j = 0; j <= i; j++ ) {
8,362,420✔
1532
                                numofwildarg += AT.WildArgTaken[j];
5,533,140✔
1533
                        }
1534
                        AT.WildArgTaken[j] = AN.WildEat-numofwildarg;
2,829,291✔
1535
/* ----> bug to be replaced in other source code */
1536
                        for ( j++; j < AN.WildArgs; j++ ) AT.WildArgTaken[j] = 0;
2,954,613✔
1537
                        break;
1538
                }
1539
        }
1540
        goto topofloop;
2,829,291✔
UNCOV
1541
NoCaseB:
×
1542
/*
1543
        Restore the old Wildcard assignments
1544
*/
1545
        i = nwstore;
×
UNCOV
1546
        if ( i > 0 ) {
×
UNCOV
1547
                m = AN.WildValue;
×
UNCOV
1548
                t = OldWork + ntwa; r = AT.WildMask;
×
1549
                do {
×
1550
                        *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
×
1551
                } while ( --i > 0 );
×
1552
                C->numrhs = *t++;
×
1553
                C->Pointer = C->Buffer + oldcpointer;
×
1554
        }
1555
        AT.WorkPointer = OldWork;
×
1556
        return(0);                /* no match */
×
1557
}
1558

1559
/*
1560
                 #] MatchFunction : 
1561
                 #[ ScanFunctions :                        WORD ScanFunctions(inpat,inter,par)
1562

1563
                Finds in which functions to look for a match.
1564
                inpat is the start of the pattern still to be matched.
1565
                inter is the start of the term still to be matched.
1566
                par gives information about commutativity.
1567
                        par = 0: nothing special
1568
                        par = 1: regular noncommuting function
1569
                        par = 2: GAMMA function
1570

1571
                AN.patstop: end of the functions field in the search pattern
1572
                AN.terstop: end of the functions field in the target pattern
1573
                AN.terstart: address of entire term;
1574

1575
                The actual matching of the functions and their arguments is done
1576
                in a number of different routines. Mainly MatchFunction when there
1577
                are no symmetry properties.
1578
                Also: MatchE
1579
                      MatchCy
1580
                      FunMatchSy
1581
                      FunMatchCy
1582

1583
                The main problem here is backtracking, ie continuing with wildcard
1584
                possibilities when a first assignment doesn't work.
1585
                Important note: this was completely forgotten in the symmetric
1586
                functions till 6-jan-2009. As of the moment this still has to
1587
                be fixed.
1588

1589
                Functions inside functions can cause problems when antisymmetric
1590
                functions are involved. The sign of the term may be at stake.
1591
                At the lowest level this is no problem but in f(-fas(n2,n1)) this
1592
                plays a role. Next is when we have a product of functions inside
1593
                an argument. The strategy must be that we test the sign only at the
1594
                last function. Hence, when inpat+inpat[1] >= AN.patstop.
1595
                We might relax that to the last antisymmetric function at a later stage.
1596

1597
        New scheme to be implemented for non-commuting objects:
1598
        When we are matching a second (or higher) function, any match can only
1599
        be directly after the last matched non-commuting function or a commuting
1600
        function. This will take care of whatever happens in MatchE etc.
1601
*/
1602

1603
WORD ScanFunctions(PHEAD WORD *inpat, WORD *inter, WORD par)
209,234✔
1604
{
1605
        GETBIDENTITY
1606
        WORD i, *m, *t, *r, sym, psym;
209,234✔
1607
        WORD *newpat, *newter, *instart, *oinpat = 0, *ointer = 0;
209,234✔
1608
        WORD nwstore, offset, *OldWork, SetStop = 0, oRepFunNum = AN.RepFunNum;
209,234✔
1609
        WORD wilds, wildargs = 0, wildeat = 0, *wildargtaken;
209,234✔
1610
        WORD *Oterfirstcomm = AN.terfirstcomm;
209,234✔
1611
        CBUF *C = cbuf+AT.ebufnum;
209,234✔
1612
        int ntwa = AN.NumTotWildArgs;
209,234✔
1613
        LONG oldcpointer = C->Pointer - C->Buffer;
209,234✔
1614
        WORD oldSignCheck = AN.SignCheck;
209,234✔
1615
        instart = inter;
209,234✔
1616
/*
1617
        Only active for the last function in the pattern.
1618
        The actual test on the sign is in MatchFunction or the symmetric functions
1619
*/
1620
        if ( AN.nogroundlevel ) {
209,234✔
1621
                AN.SignCheck = ( inpat + inpat[1] >= AN.patstop ) ? 1 : 0;
558✔
1622
        }
1623
        else {
1624
                AN.SignCheck = 0;
208,676✔
1625
        }
1626
/*
1627
                        Store the current Wildcard assignments
1628
*/
1629
        t = wildargtaken = OldWork = AT.WorkPointer;
209,234✔
1630
        t += ntwa;
209,234✔
1631
        m = AN.WildValue;
209,234✔
1632
        nwstore = i = (m[-SUBEXPSIZE+1]-SUBEXPSIZE)/4;
209,234✔
1633
        if ( i > 0 ) {
209,234✔
1634
                r = AT.WildMask;
209,051✔
1635
                do {
235,952✔
1636
                        *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *m++; *t++ = *r++;
235,952✔
1637
                } while ( --i > 0 );
235,952✔
1638
                *t++ = C->numrhs;
209,051✔
1639
        }
1640
        if ( t >= AT.WorkTop ) {
209,234✔
UNCOV
1641
                MLOCK(ErrorMessageLock);
×
UNCOV
1642
                MesWork();
×
UNCOV
1643
                MUNLOCK(ErrorMessageLock);
×
UNCOV
1644
                Terminate(-1);
×
1645
        }
1646
        AT.WorkPointer = t;
209,234✔
1647
        do {
259,125✔
1648
#ifndef NEWCOMMUTE
1649
/*
1650
                Find an eligible unsubstituted function
1651
*/
1652
                if ( AN.RepFunNum > 0 ) {
259,125✔
1653
/*
1654
                        First try a non-commuting function, just after the last
1655
                        substituted non-commuting function.
1656
*/
1657
                        if ( *inter >= FUNCTION && functions[*inter-FUNCTION].commute ) {
2,139✔
1658
                                do {
3✔
1659
                                        offset = WORDDIF(inter,AN.terstart);
3✔
1660
                                        for ( i = 0; i < AN.RepFunNum; i += 2 ) {
6✔
1661
                                                if ( AN.RepFunList[i] >= offset ) break;
3✔
1662
                                        }
1663
                                        if ( i >= AN.RepFunNum ) break;
3✔
UNCOV
1664
                                        inter += inter[1];
×
UNCOV
1665
                                } while ( inter < AN.terfirstcomm );
×
1666
                                if ( inter < AN.terfirstcomm ) { /* Check that it is directly after */
3✔
1667
                                        for ( i = 0; i < AN.RepFunNum; i += 2 ) {
3✔
1668
                                                if ( functions[AN.terstart[AN.RepFunList[i]]-FUNCTION].commute
3✔
1669
                                                && AN.RepFunList[i]+AN.terstart[AN.RepFunList[i]+1] == offset ) break;
3✔
1670
                                        }
1671
                                        if ( i < AN.RepFunNum ) goto trythis;
3✔
1672
                                }
1673
                                inter = AN.terfirstcomm;
1674
                        }
1675
/*
1676
                        Now try one of the commuting functions
1677
*/
1678
                        while ( inter < AN.terstop ) {
4,275✔
1679
                                offset = WORDDIF(inter,AN.terstart);
4,269✔
1680
                                for ( i = 0; i < AN.RepFunNum; i += 2 ) {
6,597✔
1681
                                        if ( AN.RepFunList[i] == offset ) break;
4,467✔
1682
                                }
1683
                                if ( i >= AN.RepFunNum ) break;
4,269✔
1684
                                inter += inter[1];
2,139✔
1685
                        }
1686
                        if ( inter >= AN.terstop ) goto Failure;
2,136✔
1687
trythis:;
2,130✔
1688
                }
1689
                else {
1690
/*
1691
                        The first function can be anywhere. We have no problems.
1692
*/
1693
                        offset = WORDDIF(inter,AN.terstart);
256,986✔
1694
                }
1695
#else
1696
                /* first find an unsubstituted function */
1697
                do {
1698
                        offset = WORDDIF(inter,AN.terstart);
1699
                        for ( i = 0; i < AN.RepFunNum; i += 2 ) {
1700
                                if ( AN.RepFunList[i] == offset ) break;
1701
                        }
1702
                        if ( i >= AN.RepFunNum ) break;
1703
                        inter += inter[1];
1704
                } while ( inter < AN.terstop );
1705
                if ( inter >= AN.terstop ) goto Failure;
1706
#endif
1707
                wilds = 0;
259,119✔
1708
                /* We found one */
1709
                if ( *inter >= FUNCTION && *inpat >= FUNCTION ) {
259,119✔
1710
                        if ( *inpat == *inter || *inpat >= FUNCTION + WILDOFFSET ) {
235,135✔
1711
/*
1712
                                if ( inter[1] == FUNHEAD ) goto rewild;
1713
*/
1714
                                if ( functions[*inter-FUNCTION].spec >= TENSORFUNCTION
159,554✔
UNCOV
1715
                                && ( *inter == *inpat ||
×
UNCOV
1716
                                functions[*inpat-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION ) ) {
×
UNCOV
1717
                                        sym = functions[*inter-FUNCTION].symmetric & ~REVERSEORDER;
×
UNCOV
1718
                                        if ( *inpat == *inter ) psym = sym;
×
1719
                                        else psym = functions[*inpat-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER;
×
1720
                                        if ( sym == ANTISYMMETRIC || sym == SYMMETRIC
×
1721
                                        || psym == SYMMETRIC || psym == ANTISYMMETRIC ) {
×
1722
                                                if ( sym == ANTISYMMETRIC && psym == SYMMETRIC ) goto rewild;
×
1723
                                                if ( sym == SYMMETRIC && psym == ANTISYMMETRIC ) goto rewild;
×
1724
/*
1725
                                                Special function call for (anti)symmetric tensors
1726
*/
1727
                                                if ( MatchE(BHEAD inpat,inter,instart,par) ) goto OnSuccess;
×
1728
                                        }
UNCOV
1729
                                        else if ( sym == CYCLESYMMETRIC || sym == RCYCLESYMMETRIC
×
UNCOV
1730
                                        || psym == CYCLESYMMETRIC || psym == RCYCLESYMMETRIC ) {
×
1731
/*
1732
                                                Special function call for (r)cyclic tensors
1733
*/
1734
                                                if ( MatchCy(BHEAD inpat,inter,instart,par) ) goto OnSuccess;
×
1735
                                        }
UNCOV
1736
                                        else goto rewild;
×
1737
                                }
1738
                                else if ( functions[*inter-FUNCTION].spec == 0
159,554✔
1739
                                && ( *inter == *inpat ||
159,554✔
1740
                                functions[*inpat-FUNCTION-WILDOFFSET].spec == 0 ) ) {
2,322✔
1741
                                        sym = functions[*inter-FUNCTION].symmetric & ~REVERSEORDER;
159,554✔
1742
                                        if ( *inpat == *inter ) psym = sym;
159,554✔
1743
                                        else psym = functions[*inpat-FUNCTION-WILDOFFSET].symmetric & ~REVERSEORDER;
2,322✔
1744
                                        if ( psym == SYMMETRIC || sym == SYMMETRIC
159,554✔
1745
/*
1746
                                        The next statement was commented out. Why????
1747
                                        Werkt nog niet. Teken wordt nog niet bijgehouden.
1748
                                        5-nov-2001
1749
*/
1750
                                        || psym == ANTISYMMETRIC || sym == ANTISYMMETRIC
157,487✔
1751
                                        ) {
1752
                                                if ( sym == ANTISYMMETRIC && psym == SYMMETRIC ) goto rewild;
2,073✔
1753
                                                if ( sym == SYMMETRIC && psym == ANTISYMMETRIC ) goto rewild;
1,632✔
1754
                                                if ( FunMatchSy(BHEAD inpat,inter,instart,par) ) goto OnSuccess;
1,632✔
1755
                                        }
1756
                                        else
1757
                                                if ( sym == CYCLESYMMETRIC || sym == RCYCLESYMMETRIC
157,481✔
1758
                                        || psym == CYCLESYMMETRIC || psym == RCYCLESYMMETRIC ) {
157,481✔
UNCOV
1759
                                                if ( FunMatchCy(BHEAD inpat,inter,instart,par) ) goto OnSuccess;
×
1760
                                        }
1761
                                        else goto rewild;
157,481✔
1762
                                }
1763
                                else goto rewild;
×
1764
                                AN.terfirstcomm = Oterfirstcomm;
375✔
1765
                        }
1766
                        else if ( par > 0 ) { SetStop = 1; goto maybenext; }
75,581✔
1767
                }
1768
                else {
1769
rewild:
23,984✔
1770
                AN.terfirstcomm = Oterfirstcomm;
181,912✔
1771
                if ( *inter != SUBEXPRESSION && MatchFunction(BHEAD inpat,inter,&wilds) ) {
181,912✔
1772
                        AN.terfirstcomm = Oterfirstcomm;
157,646✔
1773
                        if ( wilds ) {
157,646✔
1774
/*
1775
                                Store wildcards to continue in MatchFunction if the current
1776
                                wildcards do not work out.
1777
*/
1778
                                wildargs = AN.WildArgs;
3,075✔
1779
                                wildeat = AN.WildEat;
3,075✔
1780
                                for ( i = 0; i < wildargs; i++ ) wildargtaken[i] = AT.WildArgTaken[i];
12,225✔
1781
                                oinpat = inpat; ointer = inter;
1782
                        }
1783
                        if ( par && *inter == GAMMA && AN.RepFunList[AN.RepFunNum+1] ) {
157,646✔
UNCOV
1784
                                SetStop = 1; goto NoMat;
×
1785
                        }
1786
                        if ( par == 2 ) {
157,646✔
UNCOV
1787
                                if ( *inter < FUNCTION || functions[*inter-FUNCTION].commute ) {
×
1788
                                        goto NoMat;
×
1789
                                }
1790
                                par = 1;
1791
                        }
1792
                        AN.RepFunList[AN.RepFunNum] = offset;
157,646✔
1793
                        AN.RepFunNum += 2;
157,646✔
1794
                        newpat = inpat + inpat[1];
157,646✔
1795
                        if ( newpat >= AN.patstop ) {
157,646✔
1796
                                if ( AN.UseFindOnly == 0 ) {
155,633✔
1797
                                        if ( FindOnce(BHEAD AN.findTerm,AN.findPattern) ) {
18✔
1798
                                                AN.UsedOtherFind = 1;
18✔
1799
                                                goto OnSuccess;
18✔
1800
                                        }
UNCOV
1801
                                        AN.RepFunNum -= 2;
×
UNCOV
1802
                                        goto NoMat;
×
1803
                                }
1804
                                goto OnSuccess;
155,615✔
1805
                        }
1806
                        if ( *inter < FUNCTION || functions[*inter-FUNCTION].commute ) {
2,013✔
1807
                                newter = inter + inter[1];
6✔
1808
                                if ( newter >= AN.terstop ) goto Failure;
6✔
1809
                                if ( *inter == GAMMA && inpat[1] <
6✔
UNCOV
1810
                                inter[1] - AN.RepFunList[AN.RepFunNum-1] ) {
×
UNCOV
1811
                                        if ( ScanFunctions(BHEAD newpat,newter,2) ) goto OnSuccess;
×
UNCOV
1812
                                        AN.terfirstcomm = Oterfirstcomm;
×
1813
                                }
1814
                                else if ( *newter ==  SUBEXPRESSION ) {}
6✔
1815
                                else if ( functions[*inter-FUNCTION].commute ) {
6✔
1816
                                        if ( ScanFunctions(BHEAD newpat,newter,1) ) goto OnSuccess;
6✔
UNCOV
1817
                                        AN.terfirstcomm = Oterfirstcomm;
×
UNCOV
1818
                                        if ( ( *newpat < (FUNCTION+WILDOFFSET)
×
UNCOV
1819
                                                && ( functions[*newpat-FUNCTION].commute == 0 ) ) ||
×
1820
                                                ( *newpat >= (FUNCTION+WILDOFFSET)
1821
                                                && ( functions[*newpat-FUNCTION-WILDOFFSET].commute == 0 ) ) ) {
×
1822
                                                newter = AN.terfirstcomm;
×
1823
                                                if ( newter < AN.terstop && ScanFunctions(BHEAD newpat,newter,1) ) goto OnSuccess;
×
1824
                                        }
1825
                                }
1826
                                else {
1827
                                        if ( ScanFunctions(BHEAD newpat,instart,1) ) goto OnSuccess;
×
UNCOV
1828
                                        AN.terfirstcomm = Oterfirstcomm;
×
1829
                                }
1830
                                SetStop = par;
1831
                        }
1832
                        else {
1833
/*
1834
                                Shouldn't this be newpat instead of inpat?????
1835
*/
1836
                                if ( par && inter > instart && ( ( *newpat < (FUNCTION+WILDOFFSET)
2,007✔
UNCOV
1837
                                && functions[*newpat-FUNCTION].commute ) ||
×
1838
                                ( *newpat >= (FUNCTION+WILDOFFSET)
UNCOV
1839
                                && functions[*newpat-FUNCTION-WILDOFFSET].commute ) ) ) {
×
1840
                                        SetStop = 1;
1841
                                }
1842
                                else {
1843
                                        newter = instart;
2,007✔
1844
                                        if ( ScanFunctions(BHEAD newpat,newter,par) ) goto OnSuccess;
2,007✔
1845
                                        AN.terfirstcomm = Oterfirstcomm;
18✔
1846
                                }
1847
                        }
1848
/*
1849
                        Restore the old Wildcard assignments
1850
*/
1851
NoMat:
36✔
1852
                        i = nwstore;
36✔
1853
                        if ( i > 0 ) {
36✔
1854
                                m = AN.WildValue;
36✔
1855
                                t = OldWork + ntwa; r = AT.WildMask;
36✔
1856
                                do {
174✔
1857
                                        *m++ = *t++; *m++ = *t++; *m++ = *t++; *m++ = *t++; *r++ = *t++;
174✔
1858
                                } while ( --i > 0 );
174✔
1859
                                C->numrhs = *t++;
36✔
1860
                                C->Pointer = C->Buffer + oldcpointer;
36✔
1861
                        }
1862
/*                        AN.RepFunNum -= 2; */
1863
                        AN.RepFunNum = oRepFunNum;
36✔
1864
                        if ( wilds ) {
36✔
1865
                                inter = ointer; inpat = oinpat;
6✔
1866
                                AN.WildArgs = wildargs;
6✔
1867
                                AN.WildEat = wildeat;
6✔
1868
                                for ( i = 0; i < wildargs; i++ ) AT.WildArgTaken[i] = wildargtaken[i];
18✔
1869
                                goto rewild;
6✔
1870
                        }
1871
                        if ( SetStop ) break;
30✔
1872
                }
1873
                else if ( par ) {
24,266✔
UNCOV
1874
maybenext:
×
UNCOV
1875
                        if ( *inpat < (FUNCTION+WILDOFFSET) ) {
×
UNCOV
1876
                                if ( *inpat < FUNCTION ||
×
UNCOV
1877
                                functions[*inpat-FUNCTION].commute ) break;
×
1878
                        }
1879
                        else {
1880
                                if ( functions[*inpat-FUNCTION-WILDOFFSET].commute ) break;
×
1881
                        }
1882
                }}
1883
                inter += inter[1];
100,252✔
1884
        } while ( inter < AN.terstop );
100,252✔
1885
Failure:
50,361✔
1886
    AN.SignCheck = oldSignCheck;
50,367✔
1887
        AT.WorkPointer = OldWork;
50,367✔
1888
        return(0);
50,367✔
1889
OnSuccess:
158,885✔
1890
        if ( AT.idallflag && AN.nogroundlevel <= 0 ) {
158,885✔
1891
                if ( AT.idallmaxnum > 0 && AT.idallnum >= AT.idallmaxnum ) {
18✔
UNCOV
1892
                        AN.terfirstcomm = Oterfirstcomm;
×
UNCOV
1893
                    AN.SignCheck = oldSignCheck;
×
UNCOV
1894
                        AT.WorkPointer = OldWork;
×
UNCOV
1895
                        return(0);
×
1896
                }
1897
                SubsInAll(BHEAD0);
18✔
1898
                AT.idallnum++;
18✔
1899
                if ( AT.idallmaxnum == 0 || AT.idallnum < AT.idallmaxnum ) goto NoMat;
18✔
1900
        }
1901
        AN.terfirstcomm = Oterfirstcomm;
158,867✔
1902
    AN.SignCheck = oldSignCheck;
158,867✔
1903
/*
1904
        Now the disorder test
1905
*/
1906
        if ( AN.DisOrderFlag && AN.RepFunNum >= 4 ) {
158,867✔
1907
                WORD k, kk;
UNCOV
1908
                for ( i = 2; i < AN.RepFunNum; i += 2 ) {
×
1909
/*
1910
------------> We still have to copy the code from Normalize wrt properorderflag
1911
*/
1912
                        m = AN.terstart + AN.RepFunList[i-2];
×
UNCOV
1913
                        t = AN.terstart + AN.RepFunList[i];
×
UNCOV
1914
                        if ( *m != *t ) {
×
UNCOV
1915
                                if ( *m > *t ) continue;
×
1916
                                goto doesmatch;
×
1917
                        }
1918
                        if ( *m >= FUNCTION && functions[*m-FUNCTION].spec >=
×
1919
                                TENSORFUNCTION ) {
1920
                                k = m[1] - FUNHEAD;
×
UNCOV
1921
                                kk = t[1] - FUNHEAD;
×
1922
                                m += FUNHEAD;
×
UNCOV
1923
                                t += FUNHEAD;
×
1924
                        }
1925
                        else {
1926
                                k = m[1] - FUNHEAD;
×
1927
                                kk = t[1] - FUNHEAD;
×
UNCOV
1928
                                m += FUNHEAD;
×
UNCOV
1929
                                t += FUNHEAD;
×
1930
                        }
1931
                        while ( k > 0 && kk > 0 ) {
×
1932
                                if ( *m < *t ) goto NextFor;
×
1933
                                else if ( *m++ > *t++ ) goto doesmatch;
×
UNCOV
1934
                                k--; kk--;
×
1935
                        }
1936
                        if ( k > 0 ) goto doesmatch;
×
1937
NextFor:;
×
1938
                }
UNCOV
1939
                SetStop = 1;
×
1940
                goto NoMat;
×
1941
        }
1942
doesmatch:
158,867✔
1943
        AT.WorkPointer = OldWork;
158,867✔
1944
        return(1);
158,867✔
1945
}
1946

1947
/*
1948
                 #] ScanFunctions : 
1949
        #] Patterns :
1950
*/
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