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

vermaseren / form / 9364948935

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

Pull #526

github

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

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

32 existing lines in 2 files now uncovered.

41391 of 82816 relevant lines covered (49.98%)

878690.77 hits per line

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

79.59
/sources/startup.c
1
/** @file startup.c
2
 * 
3
 *  This file contains the main program.
4
 *  It also deals with the very early stages of the startup of FORM
5
 *        and the final stages when the program attempts some cleanup.
6
 *        Here is the routine that analyses the command tail.
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 :
36
*/
37

38
#include "form3.h"
39
#include "inivar.h"
40

41
#ifdef TRAPSIGNALS
42
#include "portsignals.h"
43
#else
44
#include <signal.h>
45
#endif
46
#include <execinfo.h>
47

48
/*
49
 * A macro for translating the contents of `x' into a string after expanding.
50
 */
51
#define STRINGIFY(x)  STRINGIFY__(x)
52
#define STRINGIFY__(x) #x
53

54
/*
55
 * FORMNAME = "FORM" or "TFORM" or "ParFORM".
56
 */
57
#if defined(WITHPTHREADS)
58
        #define FORMNAME "TFORM"
59
#elif defined(WITHMPI)
60
        #define FORMNAME "ParFORM"
61
#else
62
        #define FORMNAME "FORM"
63
#endif
64

65
/*
66
 * VERSIONSTR is the version information printed in the header line.
67
 */
68
#ifdef HAVE_CONFIG_H
69
        /* We have also version.h. */
70
        #include "version.h"
71
        #ifndef REPO_VERSION
72
                #define REPO_VERSION STRINGIFY(REPO_MAJOR_VERSION) "." STRINGIFY(REPO_MINOR_VERSION)
73
        #endif
74
        #ifndef REPO_DATE
75
                /* The build date, instead of the repo date. */
76
                #define REPO_DATE __DATE__
77
        #endif
78
        #ifdef REPO_REVISION
79
                #define VERSIONSTR FORMNAME " " REPO_VERSION " (" REPO_DATE ", " REPO_REVISION ")"
80
        #else
81
                #define VERSIONSTR FORMNAME " " REPO_VERSION " (" REPO_DATE ")"
82
        #endif
83
        #define MAJORVERSION REPO_MAJOR_VERSION
84
        #define MINORVERSION REPO_MINOR_VERSION
85
#else
86
        /*
87
         * Otherwise, form3.h defines MAJORVERSION, MINORVERSION and PRODUCTIONDATE,
88
         * possibly BETAVERSION.
89
         */
90
        #ifdef BETAVERSION
91
                #define VERSIONSTR__ STRINGIFY(MAJORVERSION) "." STRINGIFY(MINORVERSION) "Beta"
92
        #else
93
                #define VERSIONSTR__ STRINGIFY(MAJORVERSION) "." STRINGIFY(MINORVERSION)
94
        #endif
95
        #define VERSIONSTR FORMNAME " " VERSIONSTR__ " (" PRODUCTIONDATE ")"
96
#endif
97

98
/*
99
                 #] includes : 
100
                 #[ PrintHeader :
101
*/
102

103
/**
104
 * Prints the header line of the output.
105
 *
106
 * @param  with_full_info  True for printing also runtime information.
107
 */
108
static void PrintHeader(int with_full_info)
1,776✔
109
{
110
#ifdef WITHMPI
111
        if ( PF.me == MASTER && !AM.silent ) {
989✔
112
#else
113
        if ( !AM.silent ) {
787✔
114
#endif
115
                char buffer1[250], buffer2[80], *s = buffer1, *t = buffer2;
259,785✔
116
                WORD length, n;
117
                for ( n = 0; n < 250; n++ ) buffer1[n] = ' ';
259,785✔
118
                /*
119
                 * NOTE: we expect that the compiler optimizes strlen("string literal")
120
                 * to just a number.
121
                 */
122
                if ( strlen(VERSIONSTR) <= 100 ) {
1,035✔
123
                        strcpy(s,VERSIONSTR);
1,035✔
124
                        s += strlen(VERSIONSTR);
1,035✔
125
                        *s = 0;
1,035✔
126
                }
127
                else {
128
                        /*
129
                         * Truncate when it is too long.
130
                         */
131
                        strncpy(s,VERSIONSTR,97);
132
                        s[97] = '.';
133
                        s[98] = '.';
134
                        s[99] = ')';
135
                        s[100] = '\0';
136
                        s += 100;
137
                }
138
/*
139
                By now we omit the message about 32/64 bits. It should all be 64.
140

141
                s += snprintf(s,250-(s-buffer1)," %d-bits",(WORD)(sizeof(WORD)*16));
142
                *s = 0;
143
*/
144
                if ( with_full_info ) {
1,035✔
145
#if defined(WITHPTHREADS) || defined(WITHMPI)
146
#if defined(WITHPTHREADS)
147
                        int nworkers = AM.totalnumberofthreads-1;
524✔
148
#elif defined(WITHMPI)
149
                        int nworkers = PF.numtasks-1;
248✔
150
#endif
151
                        s += snprintf(s,250-(s-buffer1)," %d worker",nworkers);
772✔
152
                        *s = 0;
772✔
153
/*                        while ( *s ) s++; */
154
                        if ( nworkers != 1 ) {
772✔
155
                                *s++ = 's';
772✔
156
                                *s = '\0';
772✔
157
                        }
158
#endif
159

160
                        snprintf(t,80-(t-buffer2),"Run: %s",MakeDate());
1,035✔
161
                        while ( *t ) t++;
32,085✔
162

163
                        /*
164
                         * Align the date to the right, if it fits in a line.
165
                         */
166
                        length = (s-buffer1) + (t-buffer2);
1,035✔
167
                        if ( length+2 <= AC.LineLength ) {
1,035✔
168
                                for ( n = AC.LineLength-length; n > 0; n-- ) *s++ = ' ';
×
169
                                *s = 0;
×
170
                                strcat(s,buffer2);
×
171
                                while ( *s ) s++;
×
172
                        }
173
                        else {
174
                                *s = 0;
1,035✔
175
                                strcat(s,"  ");
1,035✔
176
                                while ( *s ) s++;
3,105✔
177
                                *s = 0;
1,035✔
178
                                strcat(s,buffer2);
1,035✔
179
                                while ( *s ) s++;
32,085✔
180
                        }
181
                }
182

183
                /*
184
                 * If the header information doesn't fit in a line, we need to extend
185
                 * the line length temporarily.
186
                 */
187
                length = s-buffer1;
1,035✔
188
                if ( length <= AC.LineLength ) {
1,035✔
189
                        MesPrint("%s",buffer1);
×
190
                }
191
                else {
192
                        WORD oldLineLength = AC.LineLength;
1,035✔
193
                        AC.LineLength = length;
1,035✔
194
                        MesPrint("%s",buffer1);
1,035✔
195
                        AC.LineLength = oldLineLength;
1,035✔
196
                }
197
        }
198
}
1,776✔
199

200
/*
201
                 #] PrintHeader : 
202
                 #[ DoTail :
203

204
                Routine reads the command tail and handles the commandline options.
205
                It sets the flags for later actions and stored pathnames for
206
                the setup file, include/prc/sub directories etc.
207
                Finally the name of the program is passed on.
208
                Note that we do not support interactive use yet. This will come
209
                to pass in the distant future when we can couple STedi to FORM.
210
                Routine made 23-feb-1993 by J.Vermaseren
211
*/
212

213
#ifdef WITHINTERACTION
214
static UBYTE deflogname[] = "formsession.log";
215
#endif
216

217
#define TAKEPATH(x) if(s[1]== '=' ){x=s+2;} else{x=*argv++;argc--;}
218

219
int DoTail(int argc, UBYTE **argv)
1,776✔
220
{
221
        int errorflag = 0, onlyversion = 1;
1,776✔
222
        UBYTE *s, *t, *copy;
1,776✔
223
        int threadnum = 0;
1,776✔
224
        argc--; argv++;
1,776✔
225
        AM.ClearStore = 0;
1,776✔
226
        AM.TimeLimit = 0;
1,776✔
227
        AM.LogType = -1;
1,776✔
228
        AM.HoldFlag = AM.qError = AM.Interact = AM.FileOnlyFlag = 0;
1,776✔
229
        AM.InputFileName = AM.LogFileName = AM.IncDir = AM.TempDir = AM.TempSortDir =
1,776✔
230
        AM.SetupDir = AM.SetupFile = AM.Path = 0;
1,776✔
231
        AM.FromStdin = 0;
1,776✔
232
        if ( argc < 1 ) {
1,776✔
233
                onlyversion = 0;
×
234
                goto printversion;
×
235
        }
236
        while ( argc >= 1 ) {
4,074✔
237
                s = *argv++; argc--;
2,298✔
238
                if ( *s == '-' || ( *s == '/' && ( argc > 0 || AM.Interact ) ) ) {
2,298✔
239
                        s++;
522✔
240
                        switch (*s) {
522✔
241
                                case 'c': /* Error checking only */
×
242
                                                        AM.qError = 1;   break;
×
243
                                case 'C': /* Next arg is filename of log file */
×
244
                                                        TAKEPATH(AM.LogFileName)  break;
×
245
                                case 'D':
×
246
                                case 'd': /* Next arg is define preprocessor var. */
247
                                                        t = copy = strDup1(*argv,"Dotail");
×
248
                                                        while ( *t && *t != '=' ) t++;
×
249
                                                        if ( *t == 0 ) {
×
250
                                                                if ( PutPreVar(copy,(UBYTE *)"1",0,0) < 0 ) return(-1);
×
251
                                                        }
252
                                                        else {
253
                                                                *t++ = 0;
×
254
                                                                if ( PutPreVar(copy,t,0,0) < 0 ) return(-1);
×
255
                                                                t[-1] = '=';
×
256
                                                        }
257
                                                        M_free(copy,"-d prevar");
×
258
                                                        argv++; argc--; break;
×
259
                                case 'f': /* Output only to regular log file */
×
260
                                                        AM.FileOnlyFlag = 1; AM.LogType = 0; break;
×
261
                                case 'F': /* Output only to log file. Further like L. */
×
262
                                                        AM.FileOnlyFlag = 1; AM.LogType = 1; break;
×
263
                                case 'h': /* For old systems: wait for key before exit */
×
264
                                                        AM.HoldFlag = 1; break;
×
265
#ifdef WITHINTERACTION
266
                                case 'i': /* Interactive session (not used yet) */
267
                                                        AM.Interact = 1; break;
268
#endif
269
                                case 'I': /* Next arg is dir for inc/prc/sub files */
×
270
                                                        TAKEPATH(AM.IncDir)  break;
×
271
                                case 'l': /* Make regular log file */
×
272
                                                        if ( s[1] == 'l' ) AM.LogType = 1; /*compatibility! */
×
273
                                                        else               AM.LogType = 0;
×
274
                                                        break;
275
                                case 'L': /* Make log file with only final statistics */
×
276
                                                        AM.LogType = 1;  break;
×
277
                                case 'M': /* Multirun. Name of tempfiles will contain PID */
×
278
                                                        AM.MultiRun = 1;
×
279
                                                        break;
×
280
                                case 'm': /* Read number of threads */
522✔
281
                                case 'w': /* Read number of workers */
282
                                                        t = s++;
522✔
283
                                                        threadnum = 0;
522✔
284
                                                        while ( *s >= '0' && *s <= '9' )
1,044✔
285
                                                                threadnum = 10*threadnum + *s++ - '0';
522✔
286
                                                        if ( *s ) {
522✔
287
#ifdef WITHMPI
288
                                                                if ( PF.me == MASTER )
289
#endif
290
                                                                printf("Illegal value for option m or w: %s\n",t);
×
291
                                                                errorflag++;
×
292
                                                        }
293
/*                                                        if ( threadnum == 1 ) threadnum = 0; */
294
                                                        threadnum++;
522✔
295
                                                        break;
522✔
296
                                case 'W': /* Print the wall-clock time on the master. */
×
297
                                                        AM.ggWTimeStatsFlag = 1;
×
298
                                                        break;
×
299
/*
300
                                case 'n':
301
                                                        Reserved for number of slaves without MPI
302
*/
303
                                case 'p':
×
304
#ifdef WITHEXTERNALCHANNEL
305
                                        /*There are two possibilities: -p|-pipe*/                
306
                                        if(s[1]=='i'){
×
307
                                                if( (s[2]=='p')&&(s[3]=='e')&&(s[4]=='\0') ){
×
308
                                                        argc--;
×
309
                                                        /*Initialize pre-set external channels, see 
310
                                                                the file extcmd.c:*/
311
                                                        if(initPresetExternalChannels(*argv++,AX.timeout)<1){
×
312
#ifdef WITHMPI
313
                                                                if ( PF.me == MASTER )
314
#endif
315
                                                                printf("Error initializing preset external channels\n");
×
316
                                                                errorflag++;
×
317
                                                        }
318
                                                        AX.timeout=-1;/*This indicates that preset channels 
×
319
                                                                                                        are initialized from cmdline*/
320
                                                }else{
321
#ifdef WITHMPI
322
                                                        if ( PF.me == MASTER )
323
#endif
324
                                                        printf("Illegal option in call of FORM: %s\n",s);
×
325
                                                        errorflag++;
×
326
                                                }
327
                                        }else
328
#else
329
                                        if ( s[1] ) {
330
                                                if ( ( s[1]=='i' ) && ( s[2] == 'p' ) && (s[3] == 'e' )
331
                                                && ( s[4] == '\0' ) ){
332
#ifdef WITHMPI
333
                                                        if ( PF.me == MASTER )
334
#endif
335
                                                        printf("Illegal option: Pipes not supported on this system.\n");
336
                                                }
337
                                                else {
338
#ifdef WITHMPI
339
                                                        if ( PF.me == MASTER )
340
#endif
341
                                                        printf("Illegal option: %s\n",s);
342
                                                }
343
                                                errorflag++;
344
                                        }
345
                                        else
346
#endif
347
                                        {
348
                                                         /* Next arg is a path variable like in environment */
349
                                                TAKEPATH(AM.Path)
×
350
                                        }
351
                                        break;
352
                                case 'q': /* Quiet option. Only output. Same as -si */
×
353
                                                        AM.silent = 1; break;
×
354
                                case 'R': /* recover from saved snapshot */
×
355
                                                        AC.CheckpointFlag = -1;
×
356
                                                        break;
×
357
                                case 's': /* Next arg is dir with form.set to be used */
×
358
                                                        if ( ( s[1] == 'o' ) && ( s[2] == 'r' ) && ( s[3] == 't' ) ) {
×
359
                                                                if(s[4]== '=' ) {
×
360
                                                                        AM.TempSortDir = s+5;
×
361
                                                                }
362
                                                                else {
363
                                                                        AM.TempSortDir = *argv++;
×
364
                                                                        argc--;
×
365
                                                                }
366
                                                        }
367
                                                        else if ( s[1] == 'i' ) { /* compatibility: silent/quiet */
×
368
                                                                AM.silent = 1;
×
369
                                                        }
370
                                                        else {
371
                                                                TAKEPATH(AM.SetupDir)
×
372
                                                        }
373
                                                        break;
374
                                case 'S': /* Next arg is setup file */
×
375
                                                        TAKEPATH(AM.SetupFile) break;
×
376
                                case 't': /* Next arg is directory for temp files */
×
377
                                                        if ( s[1] == 's' ) {
×
378
                                                                s++;
×
379
                                                                AM.havesortdir = 1;
×
380
                                                                TAKEPATH(AM.TempSortDir)
×
381
                                                        }
382
                                                        else {
383
                                                                TAKEPATH(AM.TempDir)
×
384
                                                        }
385
                                                        break;
386
                                case 'T': /* Print the total size used at end of job */
×
387
                                                        AM.PrintTotalSize = 1; break;
×
388
                                case 'v':
389
printversion:;
×
390
#ifdef WITHMPI
391
                                                        if ( PF.me == MASTER )
392
#endif
393
                                                                PrintHeader(0);
×
394
                                                        if ( onlyversion ) return(1);
×
395
                                                        goto NoFile;
×
396
                                case 'y': /* Preprocessor dumps output. No compilation. */
×
397
                                                        AP.PreDebug = PREPROONLY;   break;
×
398
                                case 'z': /* The number following is a time limit in sec. */
×
399
                                                        t = s++;
×
400
                                                        AM.TimeLimit = 0;
×
401
                                                        while ( *s >= '0' && *s <= '9' )
×
402
                                                                AM.TimeLimit = 10*AM.TimeLimit + *s++ - '0';
×
403
                                                        break;
404
                                case 'Z': /* Removes the .str file on crash, no matter its contents */
×
405
                                                        AM.ClearStore = 1;   break;
×
406
                                case '\0': /* "-" to use STDIN for the input. */
×
407
#ifdef WITHMPI
408
                                                        /* At the moment, ParFORM doesn't implement STDIN broadcasts. */
409
                                                        if ( PF.me == MASTER )
410
                                                                printf("Sorry, reading STDIN as input is currently not supported by ParFORM\n");
411
                                                        errorflag++;
412
#endif
413
                                                        AM.FromStdin = 1;
×
414
                                                        AC.NoShowInput = 1; // disable input echoing by default
×
415
                                                        break;
×
416
                                default:
×
417
                                                if ( FG.cTable[*s] == 1 ) {
×
418
                                                        AM.SkipClears = 0; t = s;
×
419
                                                        while ( FG.cTable[*t] == 1 )
×
420
                                                                AM.SkipClears = 10*AM.SkipClears + *t++ - '0';
×
421
                                                        if ( *t != 0 ) {
×
422
#ifdef WITHMPI
423
                                                                if ( PF.me == MASTER )
424
#endif
425
                                                                printf("Illegal numerical option in call of FORM: %s\n",s);
×
426
                                                                errorflag++;
×
427
                                                        }
428
                                                }
429
                                                else {
430
#ifdef WITHMPI
431
                                                        if ( PF.me == MASTER )
432
#endif
433
                                                        printf("Illegal option in call of FORM: %s\n",s);
×
434
                                                        errorflag++;
×
435
                                                }
436
                                                break;
437
                        }
438
                }
439
                else if ( argc == 0 && !AM.Interact ) AM.InputFileName = argv[-1];
1,776✔
440
                else {
441
#ifdef WITHMPI
442
                        if ( PF.me == MASTER )
443
#endif
444
                        printf("Illegal option in call of FORM: %s\n",s);
×
445
                        errorflag++;
×
446
                }
447
        }
448
        AM.totalnumberofthreads = threadnum;
1,776✔
449
        if ( AM.InputFileName ) {
1,776✔
450
                if ( AM.FromStdin ) {
1,776✔
451
                        printf("STDIN and the input filename cannot be specified simultaneously\n");
×
452
                        errorflag++;
×
453
                }
454
                s = AM.InputFileName;
1,776✔
455
                while ( *s ) s++;
11,360✔
456
                if ( s < AM.InputFileName+4 ||
1,776✔
457
                s[-4] != '.' || s[-3] != 'f' || s[-2] != 'r' || s[-1] != 'm' ) {
1,776✔
458
                        t = (UBYTE *)Malloc1((s-AM.InputFileName)+5,"adding .frm");
×
459
                        s = AM.InputFileName;
×
460
                        AM.InputFileName = t;
×
461
                        while ( *s ) *t++ = *s++;
×
462
                        *t++ = '.'; *t++ = 'f'; *t++ = 'r'; *t++ = 'm'; *t = 0;
×
463
                }
464
                if ( AM.LogType >= 0 && AM.LogFileName == 0 ) {
1,776✔
465
                        AM.LogFileName = strDup1(AM.InputFileName,"name of logfile");
×
466
                        s = AM.LogFileName;
×
467
                        while ( *s ) s++;
×
468
                        s[-3] = 'l'; s[-2] = 'o'; s[-1] = 'g';
×
469
                }
470
        }
471
#ifdef WITHINTERACTION
472
        else if ( AM.Interact ) {
473
                if ( AM.LogType >= 0 ) {
474
/*
475
                        We may have to do better than just taking a name.
476
                        It is not unique! This will be left for later.
477
*/
478
                        AM.LogFileName = deflogname;
479
                }
480
        }
481
#endif
482
        else if ( AM.FromStdin ) {
×
483
                /* Do nothing. */
484
        }
485
        else {
486
NoFile:
×
487
#ifdef WITHMPI
488
                if ( PF.me == MASTER )
489
#endif
490
                printf("No filename specified in call of FORM\n");
×
491
                errorflag++;
×
492
        }
493
        if ( AM.Path == 0 ) AM.Path = (UBYTE *)getenv("FORMPATH");
1,776✔
494
        if ( AM.Path ) {
1,776✔
495
                /*
496
                 * AM.Path is taken from argv or getenv. Reallocate it to avoid invalid
497
                 * frees when AM.Path has to be changed.
498
                 */
499
                AM.Path = strDup1(AM.Path,"DoTail Path");
1,776✔
500
        }
501
        return(errorflag);
502
}
503

504
/*
505
                 #] DoTail : 
506
                 #[ OpenInput :
507

508
                Major task here after opening is to skip the proper number of
509
                .clear instructions if so desired without using interpretation
510
*/
511

512
int OpenInput(VOID)
1,776✔
513
{
514
        int oldNoShowInput = AC.NoShowInput;
1,776✔
515
        UBYTE c;
1,776✔
516
        if ( !AM.Interact ) {
1,776✔
517
                if ( AM.FromStdin ) {
1,776✔
518
                        if ( OpenStream(0,INPUTSTREAM,0,PRENOACTION) == 0 ) {
×
519
                                Error0("Cannot open STDIN");
×
520
                                return(-1);
×
521
                        }
522
                }
523
                else {
524
                if ( OpenStream(AM.InputFileName,FILESTREAM,0,PRENOACTION) == 0 ) {
1,776✔
525
                        Error1("Cannot open file",AM.InputFileName);
×
526
                        return(-1);
×
527
                }
528
                if ( AC.CurrentStream->inbuffer <= 0 ) {
1,776✔
529
                        Error1("No input in file",AM.InputFileName);
×
530
                        return(-1);
×
531
                }
532
                }
533
                AC.NoShowInput = 1;
1,776✔
534
                while ( AM.SkipClears > 0 ) {
1,776✔
535
                        c = GetInput();
×
536
                        if ( c == ENDOFINPUT ) {
×
537
                                Error0("Not enough .clear instructions in input file");
×
538
                        }
539
                        if ( c == '\\' ) {
×
540
                                c = GetInput();
×
541
                                if ( c == ENDOFINPUT )
×
542
                                        Error0("Not enough .clear instructions in input file");
×
543
                                continue;
×
544
                        }
545
                        if ( c == ' ' || c == '\t' ) continue;
×
546
                        if ( c == '.' ) {
×
547
                                c = GetInput();
×
548
                                if ( tolower(c) == 'c' ) {
×
549
                                        c = GetInput();
×
550
                                        if ( tolower(c) == 'l' ) {
×
551
                                                c = GetInput();
×
552
                                                if ( tolower(c) == 'e' ) {
×
553
                                                        c = GetInput();
×
554
                                                        if ( tolower(c) == 'a' ) {
×
555
                                                                c = GetInput();
×
556
                                                                if ( tolower(c) == 'r' ) {
×
557
                                                                        c = GetInput();
×
558
                                                                        if ( FG.cTable[c] > 2 ) {
×
559
                                                                                AM.SkipClears--;
×
560
                                                                        }
561
                                                                }
562
                                                        }
563
                                                }
564
                                        }
565
                                }
566
                                while ( c != '\n' && c != '\r' && c != ENDOFINPUT ) {
×
567
                                        c = GetInput();
×
568
                                        if ( c == '\\' ) c = GetInput();
×
569
                                }
570
                        }
571
                        else if ( c == '\n' || c == '\r' ) continue;
×
572
                        else {
573
                                while ( ( c = GetInput() ) != '\n' && c != '\r' ) {
×
574
                                        if ( c == ENDOFINPUT ) {
×
575
                                                Error0("Not enough .clear instructions in input file");
×
576
                                        }
577
                                }
578
                        }
579
                }
580
                AC.NoShowInput = oldNoShowInput;
1,776✔
581
        }
582
        if ( AM.LogFileName ) {
1,776✔
583
#ifdef WITHMPI
584
                if ( PF.me != MASTER ) {
585
                        /*
586
                         * Only the master writes to the log file. On slaves, we need
587
                         * a dummy handle, without opening the file.
588
                         */
589
                        extern FILES **filelist;  /* in tools.c */
590
                        int i = CreateHandle();
591
                        RWLOCKW(AM.handlelock);
592
                        filelist[i] = (FILES *)123;  /* Must be nonzero to prevent a reuse in CreateHandle. */
593
                        UNRWLOCK(AM.handlelock);
594
                        AC.LogHandle = i;
595
                }
596
                else
597
#endif
598
                if ( AC.CheckpointFlag != -1 ) {
×
599
                        if ( ( AC.LogHandle = CreateLogFile((char *)(AM.LogFileName)) ) < 0 ) {
×
600
                                Error1("Cannot create logfile",AM.LogFileName);
×
601
                                return(-1);
×
602
                        }
603
                }
604
                else {
605
                        if ( ( AC.LogHandle = OpenAddFile((char *)(AM.LogFileName)) ) < 0 ) {
×
606
                                Error1("Cannot re-open logfile",AM.LogFileName);
×
607
                                return(-1);
×
608
                        }
609
                }
610
        }
611
        return(0);
612
}
613

614
/*
615
                 #] OpenInput : 
616
                 #[ ReserveTempFiles :
617

618
                Order of preference:
619
                a: if there is a path in the commandtail, take that.
620
                b: if none, try in the form.set file.
621
                c: if still none, try in the environment for the variable FORMTMP
622
                d: if still none, try the current directory.
623

624
                The parameter indicates action in the case of multithreaded running.
625
                par = 0 : We just run on a single processor. Keep everything normal.
626
                par = 1 : Multithreaded running startup phase 1.
627
                par = 2 : Multithreaded running startup phase 2.
628
*/
629

630
UBYTE *emptystring = (UBYTE *)".";
631
UBYTE *defaulttempfilename = (UBYTE *)"xformxxx.str";
632

633
VOID ReserveTempFiles(int par)
3,866✔
634
{
635
        GETIDENTITY
2,614✔
636
        SETUPPARAMETERS *sp;
3,866✔
637
        UBYTE *s, *t, *tenddir, *tenddir2, c;        
3,866✔
638
        int i = 0;
3,866✔
639
        WORD j;
3,866✔
640
        if ( par == 0 || par == 1 ) {
3,866✔
641
        if ( AM.TempDir == 0 ) {
1,776✔
642
                sp = GetSetupPar((UBYTE *)"tempdir");
1,776✔
643
                if ( ( sp->flags & USEDFLAG ) != USEDFLAG ) {
1,776✔
644
                        AM.TempDir = (UBYTE *)getenv("FORMTMP");
1,776✔
645
                        if ( AM.TempDir == 0 ) AM.TempDir = emptystring;
1,776✔
646
                }
647
                else AM.TempDir = (UBYTE *)(sp->value);
×
648
        }
649
        if ( AM.TempSortDir == 0 ) {
1,776✔
650
                if ( AM.havesortdir ) {
1,776✔
651
                        sp = GetSetupPar((UBYTE *)"tempsortdir");
×
652
                        AM.TempSortDir = (UBYTE *)(sp->value);
×
653
                }
654
                else {
655
                        AM.TempSortDir = (UBYTE *)getenv("FORMTMPSORT");
1,776✔
656
                        if ( AM.TempSortDir == 0 ) AM.TempSortDir = AM.TempDir;
1,776✔
657
                }
658
        }
659
/*
660
        We have now in principle a path but we will use its first element only.
661
        Later that should become more complicated. Then we will use a path and
662
        when one device is full we can continue on the next one.
663
*/
664
        s = AM.TempDir; i = 200;   /* Some extra for VMS */
1,776✔
665
        while ( *s && *s != ':' ) { if ( *s == '\\' ) s++; s++; i++; }
3,552✔
666
        FG.fnamesize = sizeof(UBYTE)*(i+14);
1,776✔
667
        FG.fname = (char *)Malloc1(FG.fnamesize,"name for temporary files");
1,776✔
668
        s = AM.TempDir; t = (UBYTE *)FG.fname;
1,776✔
669
        while ( *s && *s != ':' ) { if ( *s == '\\' ) s++; *t++ = *s++; }
3,552✔
670
        if ( (char *)t > FG.fname && t[-1] != SEPARATOR && t[-1] != ALTSEPARATOR )
1,776✔
671
                *t++ = SEPARATOR;
1,776✔
672
        *t = 0;
1,776✔
673
        tenddir = t;
1,776✔
674
        FG.fnamebase = t-(UBYTE *)(FG.fname);
1,776✔
675

676
        s = AM.TempSortDir; i = 200;   /* Some extra for VMS */
1,776✔
677
        while ( *s && *s != ':' ) { if ( *s == '\\' ) s++; s++; i++; }
3,552✔
678

679
        FG.fname2size = sizeof(UBYTE)*(i+14);
1,776✔
680
        FG.fname2 = (char *)Malloc1(FG.fname2size,"name for sort files");
1,776✔
681
        s = AM.TempSortDir; t = (UBYTE *)FG.fname2;
1,776✔
682
        while ( *s && *s != ':' ) { if ( *s == '\\' ) s++; *t++ = *s++; }
3,552✔
683
        if ( (char *)t > FG.fname2 && t[-1] != SEPARATOR && t[-1] != ALTSEPARATOR )
1,776✔
684
                *t++ = SEPARATOR;
1,776✔
685
        *t = 0;
1,776✔
686
        tenddir2 = t;
1,776✔
687
        FG.fname2base = t-(UBYTE *)(FG.fname2);
1,776✔
688

689
        t = tenddir;
1,776✔
690
        s = defaulttempfilename;
1,776✔
691
#ifdef WITHMPI
692
        { 
693
          int iii;
989✔
694
#ifdef SMP
695
          /* Very dirty quick-hack for the qcm smp machine at TTP */
696
          M_free(FG.fname,"name for temporary files");
697
          if(PF.me == 0){
698
      /*[04nov2003 mt] To avoid segfault with -fast optimization option*/
699
                /*[04nov2003 mt]:*/ /*NOTE, this is only a temporary stub!*/
700
                /*FG.fname = "/formswap/xxxxxxxxxxxxxxxxxxxxx";*/
701
                FG.fname = calloc(128,1);
702
                strcpy(FG.fname,"/formswap/xxxxxxxxxxxxxxxxxxxxx");
703
                /*:[04nov2003 mt]*/
704
                t = (UBYTE *)FG.fname + 10;
705
                FG.fnamebase = t-FG.fname;
706
          }
707
          else{
708
                /*[04nov2003 mt]:*/
709
                /*FG.fname = "/formswapx/xxxxxxxxxxxxxxxxxxxxx";*/
710
                FG.fname = calloc(128,1);
711
                strcpy(FG.fname,"/formswapx/xxxxxxxxxxxxxxxxxxxxx");
712
                /*:[04nov2003 mt]*/
713
                FG.fname[9] = '0' + PF.me;
714
                t = (UBYTE *)FG.fname + 11;
715
                FG.fnamebase = t-FG.fname;
716
          }
717
#else
718
          iii = snprintf((char*)t,FG.fnamesize-((char*)t-FG.fname),"%d",PF.me);
989✔
719
          t+= iii;
989✔
720
          s+= iii; /* in case defaulttmpfilename is too short */
989✔
721
#endif
722
        }
723
#endif
724
        while ( *s ) *t++ = *s++;
22,099✔
725
        *t = 0;
1,776✔
726
/*
727
                There are problems when running many FORM jobs at the same time
728
                from make or minos. If they start up simultaneously, occasionally
729
                they can make the same .str file. We prevent this with first trying
730
                a file that contains the digits of the pid. If this file
731
                has already been taken we fall back on the old scheme.
732
                The whole is controlled with the -M (MultiRun) parameter in the
733
                command tail.
734
*/
735
        if ( AM.MultiRun ) {
1,776✔
736
                int num = ((int)GetPID())%100000;
×
737
                t += 2;
×
738
                *t = 0;
×
739
                t[-1] = 'r';
×
740
                t[-2] = 't';
×
741
                t[-3] = 's';
×
742
                t[-4] = '.';
×
743
                t[-5] = (UBYTE)('0' + num%10);
×
744
                t[-6] = (UBYTE)('0' + (num/10)%10);
×
745
                t[-7] = (UBYTE)('0' + (num/100)%10);
×
746
                t[-8] = (UBYTE)('0' + (num/1000)%10);
×
747
                t[-9] = (UBYTE)('0' + num/10000);
×
748
                if ( ( AC.StoreHandle = CreateFile((char *)FG.fname) ) < 0 ) {
×
749
                        t[-5] = 'x'; t[-6] = 'x'; t[-7] = 'x'; t[-8] = 'x'; t[-9] = 'x';
×
750
                        goto classic;
×
751
                }
752
        }
753
        else
754
        {
755
classic:;
1,776✔
756
          for(;;) {
1,776✔
757
                if ( ( AC.StoreHandle = OpenFile((char *)FG.fname) ) < 0 ) {
1,776✔
758
                        if ( ( AC.StoreHandle = CreateFile((char *)FG.fname) ) >= 0 ) break;
1,776✔
759
                }
760
                else CloseFile(AC.StoreHandle);
×
761
                c = t[-5];
×
762
                if ( c == 'x' ) t[-5] = '0';
×
763
                else if ( c == '9' ) {
×
764
                        t[-5] = '0';
×
765
                        c = t[-6];
×
766
                        if ( c == 'x' ) t[-6] = '0';
×
767
                        else if ( c == '9' ) {
×
768
                                t[-6] = '0';
×
769
                                c = t[-7];
×
770
                                if ( c == 'x' ) t[-7] = '0';
×
771
                                else if ( c == '9' ) {
×
772
/*
773
                                        Note that we tried 1111 names!
774
*/
775
                                        MesPrint("Name space for temp files exhausted");
×
776
                                        t[-7] = 0;
×
777
                                        MesPrint("Please remove files of the type %s or try a different directory"
×
778
                                                ,FG.fname);
NEW
779
                                        TERMINATE(-1);
×
780
                                }
781
                                else t[-7] = (UBYTE)(c+1);
×
782
                        }
783
                        else t[-6] = (UBYTE)(c+1);
×
784
                }
785
                else t[-5] = (UBYTE)(c+1);
×
786
          }
787
        }
788
/*
789
        Now we should make sure that the tempsortdir cq tempsortfilename makes it
790
        into a similar construction.
791
*/
792
        s = tenddir; t = tenddir2; while ( *s ) *t++ = *s++;
23,088✔
793
        *t = 0;
1,776✔
794

795
/*
796
        Now we should assign a name to the main sort file and the two stage 4 files.
797
*/
798
        AM.S0->file.name = (char *)Malloc1(sizeof(char)*(i+14),"name for temporary files");
1,776✔
799
        s = (UBYTE *)AM.S0->file.name;
1,776✔
800
        t = (UBYTE *)FG.fname2;
1,776✔
801
        i = 1;
1,776✔
802
        while ( *t ) { *s++ = *t++; i++; }
26,640✔
803
        s[-2] = 'o'; *s = 0;
1,776✔
804
        }
805
/*
806
        With the stage4 and scratch file names we have to be a bit more careful.
807
        They are to be allocated after the threads are initialized when there
808
        are threads of course.
809
*/
810
        if ( par == 0 ) {
3,866✔
811
                s = (UBYTE *)((void *)(FG.fname2)); i = 0;
1,252✔
812
                while ( *s ) { s++; i++; }
18,780✔
813
                s = (UBYTE *)Malloc1(sizeof(char)*(i+1),"name for stage4 file a");
1,252✔
814
                AR.FoStage4[1].name = (char *)s;
1,252✔
815
                t = (UBYTE *)FG.fname2;
1,252✔
816
                while ( *t ) *s++ = *t++;
18,780✔
817
                s[-2] = '4'; s[-1] = 'a'; *s = 0;
1,252✔
818
                s = (UBYTE *)((void *)(FG.fname)); i = 0;
1,252✔
819
                while ( *s ) { s++; i++; }
18,780✔
820
                s = (UBYTE *)Malloc1(sizeof(char)*(i+1),"name for stage4 file b");
1,252✔
821
                AR.FoStage4[0].name = (char *)s;
1,252✔
822
                t = (UBYTE *)FG.fname;
1,252✔
823
                while ( *t ) *s++ = *t++;
18,780✔
824
                s[-2] = '4'; s[-1] = 'b'; *s = 0;
1,252✔
825
                for ( j = 0; j < 3; j++ ) {
5,008✔
826
                        s = (UBYTE *)Malloc1(sizeof(char)*(i+1),"name for scratch file");
3,756✔
827
                        AR.Fscr[j].name = (char *)s;
3,756✔
828
                        t = (UBYTE *)FG.fname;
3,756✔
829
                        while ( *t ) *s++ = *t++;
56,340✔
830
                        s[-2] = 'c'; s[-1] = (UBYTE)('0'+j); *s = 0;
3,756✔
831
                }
832
        }
833
#ifdef WITHPTHREADS
834
        else if ( par == 2 ) {
2,614✔
835
                size_t tname;
2,090✔
836
                s = (UBYTE *)((void *)(FG.fname2)); i = 0;
2,090✔
837
                while ( *s ) { s++; i++; }
31,350✔
838
                tname = sizeof(char)*(i+12);
2,090✔
839
                s = (UBYTE *)Malloc1(tname,"name for stage4 file a");
2,090✔
840
                snprintf((char *)s,tname,"%s.%d",FG.fname2,AT.identity);
2,090✔
841
                s[i-2] = '4'; s[i-1] = 'a';
2,090✔
842
                AR.FoStage4[1].name = (char *)s;
2,090✔
843
                s = (UBYTE *)((void *)(FG.fname)); i = 0;
2,090✔
844
                while ( *s ) { s++; i++; }
31,350✔
845
                tname = sizeof(char)*(i+12);
2,090✔
846
                s = (UBYTE *)Malloc1(tname,"name for stage4 file b");
2,090✔
847
                snprintf((char *)s,tname,"%s.%d",FG.fname,AT.identity);
2,090✔
848
                s[i-2] = '4'; s[i-1] = 'b';
2,090✔
849
                AR.FoStage4[0].name = (char *)s;
2,090✔
850
                if ( AT.identity == 0 ) {
2,090✔
851
                        for ( j = 0; j < 3; j++ ) {
2,096✔
852
                                s = (UBYTE *)Malloc1(sizeof(char)*(i+1),"name for scratch file");
1,572✔
853
                                AR.Fscr[j].name = (char *)s;
1,572✔
854
                                t = (UBYTE *)FG.fname;
1,572✔
855
                                while ( *t ) *s++ = *t++;
23,580✔
856
                                s[-2] = 'c'; s[-1] = (UBYTE)('0'+j); *s = 0;
1,572✔
857
                        }
858
                }
859
        }
860
#endif
861
}
3,866✔
862

863
/*
864
                 #] ReserveTempFiles : 
865
                 #[ StartVariables :
866
*/
867

868
#ifdef WITHPTHREADS
869
ALLPRIVATES *DummyPointer = 0;
870
#endif
871

872
VOID StartVariables(VOID)
1,776✔
873
{
874
        int i, ii;
1,776✔
875
        PUTZERO(AM.zeropos);
1,776✔
876
        StartPrepro();
1,776✔
877
/*
878
        The module counter:
879
*/
880
        AC.CModule=0;
1,776✔
881
#ifdef WITHPTHREADS
882
/*
883
        We need a value in AB because in the startup some routines may call AB[0].
884
*/
885
        AB = (ALLPRIVATES **)&DummyPointer;
524✔
886
#endif
887
/*
888
        separators used to delimit arguments in #call and #do, by default ',' and '|':
889
        Be sure, it is en empty set:
890
*/
891
        set_sub(AC.separators,AC.separators,AC.separators);
1,776✔
892
        set_set(',',AC.separators);
1,776✔
893
        set_set('|',AC.separators);
1,776✔
894

895
        AM.BracketFactors[0] = 8;
1,776✔
896
        AM.BracketFactors[1] = SYMBOL;
1,776✔
897
        AM.BracketFactors[2] = 4;
1,776✔
898
        AM.BracketFactors[3] = FACTORSYMBOL;
1,776✔
899
        AM.BracketFactors[4] = 1;
1,776✔
900
        AM.BracketFactors[5] = 1;
1,776✔
901
        AM.BracketFactors[6] = 1;
1,776✔
902
        AM.BracketFactors[7] = 3;
1,776✔
903

904
        AM.SkipClears = 0;
1,776✔
905
        AC.Cnumpows = 0;
1,776✔
906
        AC.OutputMode = 72;
1,776✔
907
        AC.OutputSpaces = NORMALFORMAT;
1,776✔
908
        AC.LineLength = 79;
1,776✔
909
        AM.gIsFortran90 = AC.IsFortran90 = ISNOTFORTRAN90;
1,776✔
910
        AM.gFortran90Kind = AC.Fortran90Kind = 0;
1,776✔
911
        AM.gCnumpows = 0;
1,776✔
912
        AC.exprfillwarning = 0;
1,776✔
913
        AM.gLineLength = 79;
1,776✔
914
        AM.OutBufSize = 80;
1,776✔
915
        AM.MaxStreamSize = MAXFILESTREAMSIZE;
1,776✔
916
        AP.MaxPreAssignLevel = 4;
1,776✔
917
        AC.iBufferSize = 512;
1,776✔
918
        AP.pSize = 128;
1,776✔
919
        AP.MaxPreIfLevel = 10;
1,776✔
920
        AP.cComChar = AP.ComChar = '*';
1,776✔
921
        AP.firstnamespace = 0;
1,776✔
922
        AP.lastnamespace = 0;
1,776✔
923
        AP.fullnamesize = 127;
1,776✔
924
        AP.fullname = (UBYTE *)Malloc1((AP.fullnamesize+1)*sizeof(UBYTE),"AP.fullname");
1,776✔
925
        AM.OffsetVector = -2*WILDOFFSET+MINSPEC;
1,776✔
926
        AC.cbufList.num = 0;
1,776✔
927
        AM.hparallelflag = AM.gparallelflag =
1,776✔
928
        AC.parallelflag = AC.mparallelflag = PARALLELFLAG;
1,776✔
929
#ifdef WITHMPI
930
        if ( PF.numtasks < 2 ) AM.hparallelflag |= NOPARALLEL_NPROC;
989✔
931
#endif
932
        AC.tablefilling = 0;
1,776✔
933
        AC.models = 0;
1,776✔
934
        AC.nummodels = 0;
1,776✔
935
        AC.ModelLevel = 0;
1,776✔
936
        AC.modelspace = 0;
1,776✔
937
        AM.resetTimeOnClear = 1;
1,776✔
938
        AM.gnumextrasym = AM.ggnumextrasym = 0;
1,776✔
939
        AM.havesortdir = 0;
1,776✔
940
        AM.SpectatorFiles = 0;
1,776✔
941
        AM.NumSpectatorFiles = 0;
1,776✔
942
        AM.SizeForSpectatorFiles = 0;
1,776✔
943
/*
944
        Information for the lists of variables. Part of error message and size:
945
*/
946
        AP.ProcList.message = "procedure";
1,776✔
947
        AP.ProcList.size = sizeof(PROCEDURE);
1,776✔
948
        AP.LoopList.message = "doloop";
1,776✔
949
        AP.LoopList.size = sizeof(DOLOOP);
1,776✔
950
        AP.PreVarList.message = "PreVariable";
1,776✔
951
        AP.PreVarList.size = sizeof(PREVAR);
1,776✔
952
        AC.SymbolList.message = "symbol";
1,776✔
953
        AC.SymbolList.size = sizeof(struct SyMbOl);
1,776✔
954
        AC.IndexList.message = "index";
1,776✔
955
        AC.IndexList.size = sizeof(struct InDeX);
1,776✔
956
        AC.VectorList.message = "vector";
1,776✔
957
        AC.VectorList.size = sizeof(struct VeCtOr);
1,776✔
958
        AC.FunctionList.message = "function";
1,776✔
959
        AC.FunctionList.size = sizeof(struct FuNcTiOn);
1,776✔
960
        AC.SetList.message = "set";
1,776✔
961
        AC.SetList.size = sizeof(struct SeTs);
1,776✔
962
        AC.SetElementList.message = "set element";
1,776✔
963
        AC.SetElementList.size = sizeof(WORD);
1,776✔
964
        AC.ExpressionList.message = "expression";
1,776✔
965
        AC.ExpressionList.size = sizeof(struct ExPrEsSiOn);
1,776✔
966
        AC.cbufList.message = "compiler buffer";
1,776✔
967
        AC.cbufList.size = sizeof(CBUF);
1,776✔
968
        AC.ChannelList.message = "channel buffer";
1,776✔
969
        AC.ChannelList.size = sizeof(CHANNEL);
1,776✔
970
        AP.DollarList.message = "$-variable";
1,776✔
971
        AP.DollarList.size = sizeof(struct DoLlArS);
1,776✔
972
        AC.DubiousList.message = "ambiguous variable";
1,776✔
973
        AC.DubiousList.size = sizeof(struct DuBiOuS);
1,776✔
974
        AC.TableBaseList.message = "list of tablebases";
1,776✔
975
        AC.TableBaseList.size = sizeof(DBASE);
1,776✔
976
        AC.TestValue = 0;
1,776✔
977
        AC.InnerTest = 0;
1,776✔
978

979
        AC.AutoSymbolList.message = "autosymbol";
1,776✔
980
        AC.AutoSymbolList.size = sizeof(struct SyMbOl);
1,776✔
981
        AC.AutoIndexList.message = "autoindex";
1,776✔
982
        AC.AutoIndexList.size = sizeof(struct InDeX);
1,776✔
983
        AC.AutoVectorList.message = "autovector";
1,776✔
984
        AC.AutoVectorList.size = sizeof(struct VeCtOr);
1,776✔
985
        AC.AutoFunctionList.message = "autofunction";
1,776✔
986
        AC.AutoFunctionList.size = sizeof(struct FuNcTiOn);
1,776✔
987
        AC.PotModDolList.message = "potentially modified dollar";
1,776✔
988
        AC.PotModDolList.size = sizeof(WORD);
1,776✔
989
        AC.ModOptDolList.message = "moduleoptiondollar";
1,776✔
990
        AC.ModOptDolList.size = sizeof(MODOPTDOLLAR);
1,776✔
991

992
        AO.FortDotChar = '_';
1,776✔
993
        AO.ErrorBlock = 0;
1,776✔
994
        AC.firstconstindex = 1;
1,776✔
995
        AO.Optimize.mctsconstant.fval = 1.0;
1,776✔
996
        AO.Optimize.horner = O_MCTS;
1,776✔
997
        AO.Optimize.hornerdirection = O_FORWARDORBACKWARD;
1,776✔
998
        AO.Optimize.method = O_GREEDY;
1,776✔
999
        AO.Optimize.mctstimelimit = 0;
1,776✔
1000
        AO.Optimize.mctsnumexpand = 1000;
1,776✔
1001
        AO.Optimize.mctsnumkeep = 10;
1,776✔
1002
        AO.Optimize.mctsnumrepeat = 1;
1,776✔
1003
        AO.Optimize.greedytimelimit = 0;
1,776✔
1004
        AO.Optimize.greedyminnum = 10;
1,776✔
1005
        AO.Optimize.greedymaxperc = 5;
1,776✔
1006
        AO.Optimize.printstats = 0;
1,776✔
1007
        AO.Optimize.debugflags = 0;
1,776✔
1008
        AO.OptimizeResult.code = NULL;
1,776✔
1009
        AO.inscheme = 0;
1,776✔
1010
        AO.schemenum = 0;
1,776✔
1011
        AO.wpos = 0;
1,776✔
1012
        AO.wpoin = 0;
1,776✔
1013
        AO.wlen = 0;
1,776✔
1014
        AM.dollarzero = 0;
1,776✔
1015
         AC.doloopstack = 0;
1,776✔
1016
         AC.doloopstacksize = 0;
1,776✔
1017
         AC.dolooplevel = 0;
1,776✔
1018
/*
1019
        Set up the main name trees:
1020
*/
1021
        AC.varnames  = MakeNameTree();
1,776✔
1022
        AC.exprnames = MakeNameTree();
1,776✔
1023
        AC.dollarnames = MakeNameTree();
1,776✔
1024
        AC.autonames = MakeNameTree();
1,776✔
1025
        AC.activenames = &(AC.varnames);
1,776✔
1026
        AP.preError = 0;
1,776✔
1027
/*
1028
        Initialize the compiler:
1029
*/
1030
        inictable();
1,776✔
1031
        AM.rbufnum = inicbufs();                /* Regular compiler buffer */
1,776✔
1032
#ifndef WITHPTHREADS
1033
        AT.ebufnum = inicbufs();                /* Buffer for extras during execution */
1,252✔
1034
        AT.fbufnum = inicbufs();                /* Buffer for caching in factorization */
1,252✔
1035
        AT.allbufnum = inicbufs();                /* Buffer for id,all */
1,252✔
1036
        AT.aebufnum = inicbufs();                /* Buffer for id,all */
1,252✔
1037
        AN.tryterm = 0;
1,252✔
1038
#else
1039
        AS.MasterSort = 0;
524✔
1040
#endif
1041
        AM.dbufnum = inicbufs();                /* Buffer for dollar variables */
1,776✔
1042
        AM.sbufnum = inicbufs();                /* Subterm buffer for polynomials and optimization */
1,776✔
1043
        AC.ffbufnum = inicbufs();                /* Buffer number for user defined factorizations */
1,776✔
1044
        AM.zbufnum = inicbufs();                /* For very special values */
1,776✔
1045
        {
1046
                CBUF *C = cbuf+AM.zbufnum;
1,776✔
1047
                WORD one[5] = {4,1,1,3,0};
1,776✔
1048
                WORD zero = 0;
1,776✔
1049
                AddRHS(AM.zbufnum,1);
1,776✔
1050
                AM.zerorhs = C->numrhs;
1,776✔
1051
                AddNtoC(AM.zbufnum,1,&zero,17);
1,776✔
1052
                AddRHS(AM.zbufnum,1);
1,776✔
1053
                AM.onerhs = C->numrhs;
1,776✔
1054
                AddNtoC(AM.zbufnum,5,one,17);
1,776✔
1055
        }
1056
        AP.inside.inscbuf = inicbufs();        /* For the #inside instruction */
1,776✔
1057
/*
1058
        Enter the built in objects
1059
*/
1060
        AC.Symbols = &(AC.SymbolList);
1,776✔
1061
        AC.Indices = &(AC.IndexList);
1,776✔
1062
        AC.Vectors = &(AC.VectorList);
1,776✔
1063
        AC.Functions = &(AC.FunctionList);
1,776✔
1064
        AC.vetofilling = 0;
1,776✔
1065

1066
        AddDollar((UBYTE *)"$",DOLUNDEFINED,0,0);
1,776✔
1067

1068
        cbuf[AM.dbufnum].mnumlhs = cbuf[AM.dbufnum].numlhs;
1,776✔
1069
        cbuf[AM.dbufnum].mnumrhs = cbuf[AM.dbufnum].numrhs;
1,776✔
1070

1071
        AddSymbol((UBYTE *)"i_",-MAXPOWER,MAXPOWER,VARTYPEIMAGINARY,0);
1,776✔
1072
        AM.numpi = AddSymbol((UBYTE *)"pi_",-MAXPOWER,MAXPOWER,VARTYPENONE,0);
1,776✔
1073
/*
1074
        coeff_ should have the number COEFFSYMBOL and den_ the number DENOMINATOR
1075
    and the three should be in this order!
1076
*/
1077
        AddSymbol((UBYTE *)"coeff_",-MAXPOWER,MAXPOWER,VARTYPENONE,0);
1,776✔
1078
        AddSymbol((UBYTE *)"num_",-MAXPOWER,MAXPOWER,VARTYPENONE,0);
1,776✔
1079
        AddSymbol((UBYTE *)"den_",-MAXPOWER,MAXPOWER,VARTYPENONE,0);
1,776✔
1080
        AddSymbol((UBYTE *)"xarg_",-MAXPOWER,MAXPOWER,VARTYPENONE,0);
1,776✔
1081
        AddSymbol((UBYTE *)"dimension_",-MAXPOWER,MAXPOWER,VARTYPENONE,0);
1,776✔
1082
        AddSymbol((UBYTE *)"factor_",-MAXPOWER,MAXPOWER,VARTYPENONE,0);
1,776✔
1083
        AddSymbol((UBYTE *)"sep_",-MAXPOWER,MAXPOWER,VARTYPENONE,0);
1,776✔
1084
        i = BUILTINSYMBOLS;  /* update this in ftypes.h when we add new symbols */
1,776✔
1085
/*
1086
        Next we add a number of dummy symbols for ensuring that the user defined
1087
        symbols start at a fixed given number FIRSTUSERSYMBOL
1088
        We do want to give them unique names though that the user cannot access.
1089
*/
1090
        {
1091
                char dumstr[20];
1,776✔
1092
                for ( ; i < FIRSTUSERSYMBOL; i++ ) {
23,088✔
1093
                        snprintf(dumstr,20,":%d:",i);
19,536✔
1094
                        AddSymbol((UBYTE *)dumstr,-MAXPOWER,MAXPOWER,VARTYPENONE,0);
19,536✔
1095
                }
1096
        }
1097

1098
        AddIndex((UBYTE *)"iarg_",4,0);
1,776✔
1099
        AddVector((UBYTE *)"parg_",VARTYPENONE,0);
1,776✔
1100

1101
        AM.NumFixedFunctions = sizeof(fixedfunctions)/sizeof(struct fixedfun);
1,776✔
1102
        for ( i = 0; i < AM.NumFixedFunctions; i++ ) {
186,480✔
1103
                ii = AddFunction((UBYTE *)fixedfunctions[i].name
184,704✔
1104
                                         ,fixedfunctions[i].commu
1105
                                         ,fixedfunctions[i].tensor
1106
                                         ,fixedfunctions[i].complx
1107
                                         ,fixedfunctions[i].symmetric
1108
                                         ,0,-1,-1);
1109
                if ( fixedfunctions[i].tensor == GAMMAFUNCTION )
184,704✔
1110
                                                        functions[ii].flags |= COULDCOMMUTE;
8,880✔
1111
        }
1112
/*
1113
        Next we add a number of dummy functions for ensuring that the user defined
1114
        functions start at a fixed given number FIRSTUSERFUNCTION.
1115
        We do want to give them unique names though that the user cannot access.
1116
*/
1117
        {
1118
                char dumstr[20];
1119
                for ( ; i < FIRSTUSERFUNCTION-FUNCTION; i++ ) {
47,952✔
1120
                        snprintf(dumstr,20,"::%d::",i);
46,176✔
1121
                        AddFunction((UBYTE *)dumstr,0,0,0,0,0,-1,-1);
46,176✔
1122
                }
1123
        }
1124
        AM.NumFixedSets = sizeof(fixedsets)/sizeof(struct fixedset);
1,776✔
1125
        for ( i = 0; i < AM.NumFixedSets; i++ ) {
24,864✔
1126
                ii = AddSet((UBYTE *)fixedsets[i].name,fixedsets[i].dimension);
23,088✔
1127
                Sets[ii].type = fixedsets[i].type;
23,088✔
1128
        }
1129
        AM.RepMax = MAXREPEAT;
1,776✔
1130
#ifndef WITHPTHREADS
1131
        AT.RepCount = (int *)Malloc1((LONG)((AM.RepMax+3)*sizeof(int)),"repeat buffers");
1,252✔
1132
        AN.RepPoint = AT.RepCount;
1,252✔
1133
        AT.RepTop = AT.RepCount + AM.RepMax;
1,252✔
1134
        AN.polysortflag = 0;
1,252✔
1135
        AN.subsubveto = 0;
1,252✔
1136
#endif
1137
        AC.NumWildcardNames = 0;
1,776✔
1138
        AC.WildcardBufferSize = 50;
1,776✔
1139
        AC.WildcardNames = (UBYTE *)Malloc1((LONG)AC.WildcardBufferSize,"argument list names");
1,776✔
1140
#ifndef WITHPTHREADS
1141
        AT.WildArgTaken = (WORD *)Malloc1((LONG)AC.WildcardBufferSize*sizeof(WORD)/2
1,252✔
1142
                                ,"argument list names");
1143
        AT.WildcardBufferSize = AC.WildcardBufferSize;
1,252✔
1144
        AR.CompareRoutine = (COMPAREDUMMY)(&Compare1);
1,252✔
1145
        AT.nfac = AT.nBer = 0;
1,252✔
1146
        AT.factorials = 0;
1,252✔
1147
        AT.bernoullis = 0;
1,252✔
1148
        AR.wranfia = 0;
1,252✔
1149
        AR.wranfcall = 0;
1,252✔
1150
        AR.wranfnpair1 = NPAIR1;
1,252✔
1151
        AR.wranfnpair2 = NPAIR2;
1,252✔
1152
        AR.wranfseed = 0;
1,252✔
1153
#endif
1154
        AM.atstartup = 1;
1,776✔
1155
        AM.oldnumextrasymbols = strDup1((UBYTE *)"OLDNUMEXTRASYMBOLS_","oldnumextrasymbols");
1,776✔
1156
        PutPreVar((UBYTE *)"VERSION_",(UBYTE *)STRINGIFY(MAJORVERSION),0,0);
1,776✔
1157
        PutPreVar((UBYTE *)"SUBVERSION_",(UBYTE *)STRINGIFY(MINORVERSION),0,0);
1,776✔
1158
        PutPreVar((UBYTE *)"DATE_",(UBYTE *)MakeDate(),0,0);
1,776✔
1159
        PutPreVar((UBYTE *)"random_",(UBYTE *)"________",(UBYTE *)"?a",0);
1,776✔
1160
        PutPreVar((UBYTE *)"optimminvar_",(UBYTE *)("0"),0,0);
1,776✔
1161
        PutPreVar((UBYTE *)"optimmaxvar_",(UBYTE *)("0"),0,0);
1,776✔
1162
        PutPreVar(AM.oldnumextrasymbols,(UBYTE *)("0"),0,0);
1,776✔
1163
        PutPreVar((UBYTE *)"optimvalue_",(UBYTE *)("0"),0,0);
1,776✔
1164
        PutPreVar((UBYTE *)"optimscheme_",(UBYTE *)("0"),0,0);
1,776✔
1165
        PutPreVar((UBYTE *)"tolower_",(UBYTE *)("0"),(UBYTE *)("?a"),0);
1,776✔
1166
        PutPreVar((UBYTE *)"toupper_",(UBYTE *)("0"),(UBYTE *)("?a"),0);
1,776✔
1167
        PutPreVar((UBYTE *)"takeleft_",(UBYTE *)("0"),(UBYTE *)("?a"),0);
1,776✔
1168
        PutPreVar((UBYTE *)"takeright_",(UBYTE *)("0"),(UBYTE *)("?a"),0);
1,776✔
1169
        PutPreVar((UBYTE *)"keepleft_",(UBYTE *)("0"),(UBYTE *)("?a"),0);
1,776✔
1170
        PutPreVar((UBYTE *)"keepright_",(UBYTE *)("0"),(UBYTE *)("?a"),0);
1,776✔
1171
        PutPreVar((UBYTE *)"SYSTEMERROR_",(UBYTE *)("0"),0,0);
1,776✔
1172
/*
1173
        Next are a few 'constants' for diagram generation
1174
*/
1175
        PutPreVar((UBYTE *)"ONEPI_",(UBYTE *)("1"),0,0);
1,776✔
1176
        PutPreVar((UBYTE *)"WITHOUTINSERTIONS_",(UBYTE *)("2"),0,0);
1,776✔
1177
        PutPreVar((UBYTE *)"NOTADPOLES_",(UBYTE *)("4"),0,0);
1,776✔
1178
        PutPreVar((UBYTE *)"SYMMETRIZE_",(UBYTE *)("8"),0,0);
1,776✔
1179
        PutPreVar((UBYTE *)"TOPOLOGIESONLY_",(UBYTE *)("16"),0,0);
1,776✔
1180
        PutPreVar((UBYTE *)"NONODES_",(UBYTE *)("32"),0,0);
1,776✔
1181
        PutPreVar((UBYTE *)"WITHEDGES_",(UBYTE *)("64"),0,0);
1,776✔
1182
/*                Note that CHECKEXTERN is 128 */
1183
        PutPreVar((UBYTE *)"WITHBLOCKS_",(UBYTE *)("256"),0,0);
1,776✔
1184
                PutPreVar((UBYTE *)"WITHONEPISETS_",(UBYTE *)("512"),0,0);
1,776✔
1185
        PutPreVar((UBYTE *)"NOSNAILS_",(UBYTE *)("1024"),0,0);
1,776✔
1186
        PutPreVar((UBYTE *)"NOEXTSELF_",(UBYTE *)("2048"),0,0);
1,776✔
1187

1188
        {
1189
                char buf[41];  /* up to 128-bit */
1,776✔
1190
                LONG pid;
1,776✔
1191
#ifndef WITHMPI
1192
                pid = GetPID();
787✔
1193
#else
1194
                pid = ( PF.me == MASTER ) ? GetPID() : (LONG)0;
989✔
1195
                pid = PF_BroadcastNumber(pid);
989✔
1196
#endif
1197
                LongCopy(pid,buf);
1,776✔
1198
                PutPreVar((UBYTE *)"PID_",(UBYTE *)buf,0,0);
1,776✔
1199
        }
1200
        AM.atstartup = 0;
1,776✔
1201
        AP.MaxPreTypes = 10;
1,776✔
1202
        AP.NumPreTypes = 0;
1,776✔
1203
        AP.PreTypes = (int *)Malloc1(sizeof(int)*(AP.MaxPreTypes+1),"preprocessor types");
1,776✔
1204
        AP.inside.buffer = 0;
1,776✔
1205
        AP.inside.size = 0;
1,776✔
1206

1207
        AC.SortType = AC.lSortType = AM.gSortType = SORTLOWFIRST;
1,776✔
1208
#ifdef WITHPTHREADS
1209
#else
1210
        AR.SortType = AC.SortType;
1,252✔
1211
#endif
1212
        AC.LogHandle = -1;
1,776✔
1213
        AC.SetList.numtemp        = AC.SetList.num;
1,776✔
1214
        AC.SetElementList.numtemp = AC.SetElementList.num;
1,776✔
1215

1216
        GetName(AC.varnames,(UBYTE *)"exp_",&AM.expnum,NOAUTO);
1,776✔
1217
        GetName(AC.varnames,(UBYTE *)"denom_",&AM.denomnum,NOAUTO);
1,776✔
1218
        GetName(AC.varnames,(UBYTE *)"fac_",&AM.facnum,NOAUTO);
1,776✔
1219
        GetName(AC.varnames,(UBYTE *)"invfac_",&AM.invfacnum,NOAUTO);
1,776✔
1220
        GetName(AC.varnames,(UBYTE *)"sum_",&AM.sumnum,NOAUTO);
1,776✔
1221
        GetName(AC.varnames,(UBYTE *)"sump_",&AM.sumpnum,NOAUTO);
1,776✔
1222
        GetName(AC.varnames,(UBYTE *)"term_",&AM.termfunnum,NOAUTO);
1,776✔
1223
        GetName(AC.varnames,(UBYTE *)"match_",&AM.matchfunnum,NOAUTO);
1,776✔
1224
        GetName(AC.varnames,(UBYTE *)"count_",&AM.countfunnum,NOAUTO);
1,776✔
1225
        AM.termfunnum += FUNCTION;
1,776✔
1226
        AM.matchfunnum += FUNCTION;
1,776✔
1227
        AM.countfunnum += FUNCTION;
1,776✔
1228

1229
        AC.ThreadStats = AM.gThreadStats = AM.ggThreadStats = 1;
1,776✔
1230
        AC.FinalStats = AM.gFinalStats = AM.ggFinalStats = 1;
1,776✔
1231
        AC.StatsFlag = AM.gStatsFlag = AM.ggStatsFlag = 1;
1,776✔
1232
        AC.ThreadsFlag = AM.gThreadsFlag = AM.ggThreadsFlag = 1;
1,776✔
1233
        AC.ThreadBalancing = AM.gThreadBalancing = AM.ggThreadBalancing = 1;
1,776✔
1234
        AC.ThreadSortFileSynch = AM.gThreadSortFileSynch = AM.ggThreadSortFileSynch = 0;
1,776✔
1235
        AC.ProcessStats = AM.gProcessStats = AM.ggProcessStats = 1;
1,776✔
1236
        AC.OldParallelStats = AM.gOldParallelStats = AM.ggOldParallelStats = 0;
1,776✔
1237
        AC.OldFactArgFlag = AM.gOldFactArgFlag = AM.ggOldFactArgFlag = NEWFACTARG;
1,776✔
1238
        AC.OldGCDflag = AM.gOldGCDflag = AM.ggOldGCDflag = 1;
1,776✔
1239
        AC.WTimeStatsFlag = AM.gWTimeStatsFlag = AM.ggWTimeStatsFlag = 0;
1,776✔
1240
        AM.gcNumDollars = AP.DollarList.num;
1,776✔
1241
        AC.SizeCommuteInSet = AM.gSizeCommuteInSet = 0;
1,776✔
1242
#ifdef WITHFLOAT
1243
        AC.MaxWeight = AM.gMaxWeight = AM.ggMaxWeight = MAXWEIGHT;
1,776✔
1244
        AC.DefaultPrecision = AM.gDefaultPrecision = AM.ggDefaultPrecision = DEFAULTPRECISION;
1,776✔
1245
#endif
1246
        AC.CommuteInSet = 0;
1,776✔
1247

1248
        AM.PrintTotalSize = 0;
1,776✔
1249

1250
        AO.NoSpacesInNumbers = AM.gNoSpacesInNumbers = AM.ggNoSpacesInNumbers = 0;
1,776✔
1251
        AO.IndentSpace = AM.gIndentSpace = AM.ggIndentSpace = INDENTSPACE;
1,776✔
1252
        AO.BlockSpaces = 0;
1,776✔
1253
        AO.OptimizationLevel = 0;
1,776✔
1254
        PUTZERO(AS.MaxExprSize);
1,776✔
1255
        PUTZERO(AC.StoreFileSize);
1,776✔
1256

1257
#ifdef WITHPTHREADS
1258
        AC.inputnumbers = 0;
524✔
1259
        AC.pfirstnum = 0;
524✔
1260
        AC.numpfirstnum = AC.sizepfirstnum = 0;
524✔
1261
#endif
1262
        AC.MemDebugFlag = 1;
1,776✔
1263

1264
#ifdef WITHEXTERNALCHANNEL
1265
        AX.currentExternalChannel=0;
1,776✔
1266
        AX.killSignal=SIGKILL;
1,776✔
1267
        AX.killWholeGroup=1;
1,776✔
1268
        AX.daemonize=1;
1,776✔
1269
        AX.currentPrompt=0;
1,776✔
1270
        AX.timeout=1000;/*One second to initialize preset channels*/
1,776✔
1271
        AX.shellname=strDup1((UBYTE *)"/bin/sh -c","external channel shellname");
1,776✔
1272
        AX.stderrname=strDup1((UBYTE *)"/dev/null","external channel stderrname");
1,776✔
1273
#endif
1274
}
1,776✔
1275

1276
/*
1277
                 #] StartVariables : 
1278
                 #[ StartMore :
1279
*/
1280

1281
VOID StartMore(VOID)
1,776✔
1282
{
1283
#ifdef WITHEXTERNALCHANNEL
1284
        /*If env.variable "FORM_PIPES" is defined, we have to initialize 
1285
                corresponding pre-set external channels, see file extcmd.c.*/
1286
        /*This line must be after all setup settings: in future, timeout
1287
                could be changed at setup.*/
1288
        if(AX.timeout>=0)/*if AX.timeout<0, this was done by cmdline option -pipe*/
1,776✔
1289
                initPresetExternalChannels((UBYTE*)getenv("FORM_PIPES"),AX.timeout);
1,776✔
1290
#endif
1291

1292
#ifdef WITHMPI
1293
/*
1294
        Define preprocessor variable PARALLELTASK_ as a process number, 0 is the master
1295
        Define preprocessor variable NPARALLELTASKS_ as a total number of processes
1296
*/
1297
        {
1298
                UBYTE buf[32];
989✔
1299
                snprintf((char*)buf,32,"%d",PF.me);
989✔
1300
                PutPreVar((UBYTE *)"PARALLELTASK_",buf,0,0);
989✔
1301
                snprintf((char*)buf,32,"%d",PF.numtasks);
989✔
1302
                PutPreVar((UBYTE *)"NPARALLELTASKS_",buf,0,0);
989✔
1303
        }
1304
#else
1305
        PutPreVar((UBYTE *)"PARALLELTASK_",(UBYTE *)"0",0,0);
787✔
1306
        PutPreVar((UBYTE *)"NPARALLELTASKS_",(UBYTE *)"1",0,0);
787✔
1307
#endif
1308

1309
        PutPreVar((UBYTE *)"NAME_",AM.InputFileName ? AM.InputFileName : (UBYTE *)"STDIN",0,0);
3,552✔
1310
}
1,776✔
1311

1312
/*
1313
                 #] StartMore : 
1314
                 #[ IniVars :
1315

1316
                This routine initializes the parameters that may change during the run.
1317
*/
1318

1319
WORD IniVars(VOID)
1,776✔
1320
{
1321
#ifdef WITHPTHREADS
1322
        GETIDENTITY
524✔
1323
#else
1324
        WORD *t;
1,252✔
1325
#endif
1326
        WORD *fi, i, one = 1;
1,776✔
1327
        CBUF *C = cbuf+AC.cbufnum;
1,776✔
1328

1329
#ifdef WITHPTHREADS
1330
        UBYTE buf[32];
524✔
1331
        snprintf((char*)buf,32,"%d",AM.totalnumberofthreads);
524✔
1332
        PutPreVar((UBYTE *)"NTHREADS_",buf,0,1);
524✔
1333
#else
1334
        PutPreVar((UBYTE *)"NTHREADS_",(UBYTE *)"1",0,1);
1,252✔
1335
#endif
1336

1337
        AC.ShortStats = 0;
1,776✔
1338
        AC.WarnFlag = 1;
1,776✔
1339
        AR.SortType = AC.SortType = AC.lSortType = AM.gSortType;
1,776✔
1340
        AC.OutputMode = 72;
1,776✔
1341
        AC.OutputSpaces = NORMALFORMAT;
1,776✔
1342
        AR.Eside = 0;
1,776✔
1343
        AC.DumNum = 0;
1,776✔
1344
        AC.ncmod = AM.gncmod = 0;
1,776✔
1345
        AC.modmode = AM.gmodmode = 0;
1,776✔
1346
        AC.npowmod = AM.gnpowmod = 0;
1,776✔
1347
        AC.halfmod = 0; AC.nhalfmod = 0;
1,776✔
1348
        AC.modinverses = 0;
1,776✔
1349
        AC.lPolyFun = AM.gPolyFun = 0;
1,776✔
1350
        AC.lPolyFunInv = AM.gPolyFunInv = 0;
1,776✔
1351
        AC.lPolyFunType = AM.gPolyFunType = 0;
1,776✔
1352
        AC.lPolyFunExp = AM.gPolyFunExp = 0;
1,776✔
1353
        AC.lPolyFunVar = AM.gPolyFunVar = 0;
1,776✔
1354
        AC.lPolyFunPow = AM.gPolyFunPow = 0;
1,776✔
1355
        AC.DirtPow = 0;
1,776✔
1356
        AC.lDefDim = AM.gDefDim = 4;
1,776✔
1357
        AC.lDefDim4 = AM.gDefDim4 = 0;
1,776✔
1358
        AC.lUnitTrace = AM.gUnitTrace = 4;
1,776✔
1359
        AC.NamesFlag = AM.gNamesFlag = 0;
1,776✔
1360
        AC.CodesFlag = AM.gCodesFlag = 0;
1,776✔
1361
        AC.extrasymbols = AM.gextrasymbols = AM.ggextrasymbols = 0;
1,776✔
1362
        AC.extrasym = (UBYTE *)Malloc1(2*sizeof(UBYTE),"extrasym");
1,776✔
1363
        AM.gextrasym = (UBYTE *)Malloc1(2*sizeof(UBYTE),"extrasym");
1,776✔
1364
        AM.ggextrasym = (UBYTE *)Malloc1(2*sizeof(UBYTE),"extrasym");
1,776✔
1365
        AC.extrasym[0] = AM.gextrasym[0] = AM.ggextrasym[0] = 'Z';
1,776✔
1366
        AC.extrasym[1] = AM.gextrasym[1] = AM.ggextrasym[1] = 0;
1,776✔
1367
        AC.TokensWriteFlag = AM.gTokensWriteFlag = 0;
1,776✔
1368
        AC.SetupFlag = 0;
1,776✔
1369
        AC.LineLength = AM.gLineLength = 79;
1,776✔
1370
        AC.NwildC = 0;
1,776✔
1371
        AC.OutputMode = 0;
1,776✔
1372
        AM.gOutputMode = 0;
1,776✔
1373
        AC.OutputSpaces = NORMALFORMAT;
1,776✔
1374
        AM.gOutputSpaces = NORMALFORMAT;
1,776✔
1375
        AC.OutNumberType = RATIONALMODE;
1,776✔
1376
        AM.gOutNumberType = RATIONALMODE;
1,776✔
1377
#ifdef WITHZLIB
1378
        AR.gzipCompress = GZIPDEFAULT;
1,776✔
1379
        AR.FoStage4[0].ziobuffer = 0;
1,776✔
1380
        AR.FoStage4[1].ziobuffer = 0;
1,776✔
1381
#endif
1382
        AR.BracketOn = 0;
1,776✔
1383
        AC.bracketindexflag = 0;
1,776✔
1384
        AT.bracketindexflag = 0;
1,776✔
1385
        AT.bracketinfo = 0;
1,776✔
1386
        AO.IsBracket = 0;
1,776✔
1387
        AM.gfunpowers = AC.funpowers = COMFUNPOWERS;
1,776✔
1388
        AC.parallelflag = AM.gparallelflag;
1,776✔
1389
        AC.properorderflag = AM.gproperorderflag = PROPERORDERFLAG;
1,776✔
1390
        AC.ProcessBucketSize = AC.mProcessBucketSize = AM.gProcessBucketSize;
1,776✔
1391
    AC.ThreadBucketSize = AM.gThreadBucketSize;
1,776✔
1392
        AC.ShortStatsMax = 0;
1,776✔
1393
        AM.gShortStatsMax = 0;
1,776✔
1394
        AM.ggShortStatsMax = 0;
1,776✔
1395

1396
        GlobalSymbols     = NumSymbols;
1,776✔
1397
        GlobalIndices     = NumIndices;
1,776✔
1398
        GlobalVectors     = NumVectors;
1,776✔
1399
        GlobalFunctions   = NumFunctions;
1,776✔
1400
        GlobalSets        = NumSets;
1,776✔
1401
        GlobalSetElements = NumSetElements;
1,776✔
1402
        AC.modpowers = (UWORD *)0;
1,776✔
1403

1404
        i = AM.OffsetIndex;
1,776✔
1405
        fi = AC.FixIndices;
1,776✔
1406
        if ( i > 0 ) do { *fi++ = one; } while ( --i >= 0 );
232,656✔
1407
        AR.sLevel = -1;
1,776✔
1408
        AM.Ordering[0] = 5;
1,776✔
1409
        AM.Ordering[1] = 6;
1,776✔
1410
        AM.Ordering[2] = 7;
1,776✔
1411
        AM.Ordering[3] = 0;
1,776✔
1412
        AM.Ordering[4] = 1;
1,776✔
1413
        AM.Ordering[5] = 2;
1,776✔
1414
        AM.Ordering[6] = 3;
1,776✔
1415
        AM.Ordering[7] = 4;
1,776✔
1416
        for ( i = 8; i < 15; i++ ) AM.Ordering[i] = i;
14,208✔
1417
        AM.gUniTrace[0] = 
1,776✔
1418
        AC.lUniTrace[0] = SNUMBER;
1,776✔
1419
        AM.gUniTrace[1] = 
1,776✔
1420
        AC.lUniTrace[1] = 
1,776✔
1421
        AM.gUniTrace[2] = 
1,776✔
1422
        AC.lUniTrace[2] = 4;
1,776✔
1423
        AM.gUniTrace[3] = 
1,776✔
1424
        AC.lUniTrace[3] = 1;
1,776✔
1425
#ifdef WITHPTHREADS
1426
        AS.Balancing = 0;
524✔
1427
#else
1428
        AT.MinVecArg[0] = 7+ARGHEAD;
1,252✔
1429
        AT.MinVecArg[ARGHEAD] = 7;
1,252✔
1430
        AT.MinVecArg[1+ARGHEAD] = INDEX;
1,252✔
1431
        AT.MinVecArg[2+ARGHEAD] = 3;
1,252✔
1432
        AT.MinVecArg[3+ARGHEAD] = 0;
1,252✔
1433
        AT.MinVecArg[4+ARGHEAD] = 1;
1,252✔
1434
        AT.MinVecArg[5+ARGHEAD] = 1;
1,252✔
1435
        AT.MinVecArg[6+ARGHEAD] = -3;
1,252✔
1436
        t = AT.FunArg;
1,252✔
1437
        *t++ = 4+ARGHEAD+FUNHEAD;
1,252✔
1438
        for ( i = 1; i < ARGHEAD; i++ ) *t++ = 0;
2,504✔
1439
        *t++ = 4+FUNHEAD;
1,252✔
1440
        *t++ = 0;
1,252✔
1441
        *t++ = FUNHEAD;
1,252✔
1442
        for ( i = 2; i < FUNHEAD; i++ ) *t++ = 0;
2,504✔
1443
        *t++ = 1; *t++ = 1; *t++ = 3;
1,252✔
1444

1445
#ifdef WITHMPI
1446
        AS.printflag = 0;
989✔
1447
#endif
1448

1449
        AT.comsym[0] = 8;
1,252✔
1450
        AT.comsym[1] = SYMBOL;
1,252✔
1451
        AT.comsym[2] = 4;
1,252✔
1452
        AT.comsym[3] = 0;
1,252✔
1453
        AT.comsym[4] = 1;
1,252✔
1454
        AT.comsym[5] = 1;
1,252✔
1455
        AT.comsym[6] = 1;
1,252✔
1456
        AT.comsym[7] = 3;
1,252✔
1457
        AT.comnum[0] = 4;
1,252✔
1458
        AT.comnum[1] = 1;
1,252✔
1459
        AT.comnum[2] = 1;
1,252✔
1460
        AT.comnum[3] = 3;
1,252✔
1461
        AT.comfun[0] = FUNHEAD+4;
1,252✔
1462
        AT.comfun[1] = FUNCTION;
1,252✔
1463
        AT.comfun[2] = FUNHEAD;
1,252✔
1464
        AT.comfun[3] = 0;
1,252✔
1465
#if FUNHEAD == 4
1466
        AT.comfun[4] = 0;
1467
#endif
1468
        AT.comfun[FUNHEAD+1] = 1;
1,252✔
1469
        AT.comfun[FUNHEAD+2] = 1;
1,252✔
1470
        AT.comfun[FUNHEAD+3] = 3;
1,252✔
1471
        AT.comind[0] = 7;
1,252✔
1472
        AT.comind[1] = INDEX;
1,252✔
1473
        AT.comind[2] = 3;
1,252✔
1474
        AT.comind[3] = 0;
1,252✔
1475
        AT.comind[4] = 1;
1,252✔
1476
        AT.comind[5] = 1;
1,252✔
1477
        AT.comind[6] = 3;
1,252✔
1478
        AT.locwildvalue[0] = SUBEXPRESSION;
1,252✔
1479
        AT.locwildvalue[1] = SUBEXPSIZE;
1,252✔
1480
        for ( i = 2; i < SUBEXPSIZE; i++ ) AT.locwildvalue[i] = 0;
5,008✔
1481
        AT.mulpat[0] = TYPEMULT;
1,252✔
1482
        AT.mulpat[1] = SUBEXPSIZE+3;
1,252✔
1483
        AT.mulpat[2] = 0;
1,252✔
1484
        AT.mulpat[3] = SUBEXPRESSION;
1,252✔
1485
        AT.mulpat[4] = SUBEXPSIZE;
1,252✔
1486
        AT.mulpat[5] = 0;
1,252✔
1487
        AT.mulpat[6] = 1;
1,252✔
1488
        for ( i = 7; i < SUBEXPSIZE+5; i++ ) AT.mulpat[i] = 0;
5,008✔
1489
        AT.proexp[0] = SUBEXPSIZE+4;
1,252✔
1490
        AT.proexp[1] = EXPRESSION;
1,252✔
1491
        AT.proexp[2] = SUBEXPSIZE;
1,252✔
1492
        AT.proexp[3] = -1;
1,252✔
1493
        AT.proexp[4] = 1;
1,252✔
1494
        for ( i = 5; i < SUBEXPSIZE+1; i++ ) AT.proexp[i] = 0;
2,504✔
1495
        AT.proexp[SUBEXPSIZE+1] = 1;
1,252✔
1496
        AT.proexp[SUBEXPSIZE+2] = 1;
1,252✔
1497
        AT.proexp[SUBEXPSIZE+3] = 3;
1,252✔
1498
        AT.proexp[SUBEXPSIZE+4] = 0;
1,252✔
1499
        AT.dummysubexp[0] = SUBEXPRESSION;
1,252✔
1500
        AT.dummysubexp[1] = SUBEXPSIZE+4;
1,252✔
1501
        for ( i = 2; i < SUBEXPSIZE; i++ ) AT.dummysubexp[i] = 0;
5,008✔
1502
        AT.dummysubexp[SUBEXPSIZE] = WILDDUMMY;
1,252✔
1503
        AT.dummysubexp[SUBEXPSIZE+1] = 4;
1,252✔
1504
        AT.dummysubexp[SUBEXPSIZE+2] = 0;
1,252✔
1505
        AT.dummysubexp[SUBEXPSIZE+3] = 0;
1,252✔
1506

1507
        AT.inprimelist = -1;
1,252✔
1508
        AT.sizeprimelist = 0;
1,252✔
1509
        AT.primelist = 0;
1,252✔
1510
        AT.LeaveNegative = 0;
1,252✔
1511
        AT.TrimPower = 0;
1,252✔
1512
        AN.SplitScratch = 0;
1,252✔
1513
        AN.SplitScratchSize = AN.InScratch = 0;
1,252✔
1514
        AN.SplitScratch1 = 0;
1,252✔
1515
        AN.SplitScratchSize1 = AN.InScratch1 = 0;
1,252✔
1516
        AN.idfunctionflag = 0;
1,252✔
1517
#endif
1518
        AO.OutputLine = AO.OutFill = BufferForOutput;
1,776✔
1519
        AO.FactorMode = 0;
1,776✔
1520
        C->Pointer = C->Buffer;
1,776✔
1521

1522
        AP.PreOut = 0;
1,776✔
1523
        AP.ComChar = AP.cComChar;
1,776✔
1524
        AC.cbufnum = AM.rbufnum;                /* Select the default compiler buffer */
1,776✔
1525
        AC.HideLevel = 0;
1,776✔
1526
        AP.PreAssignFlag = 0;
1,776✔
1527
        return(0);
1,776✔
1528
}
1529

1530
/*
1531
                 #] IniVars : 
1532
                 #[ Signal handlers :
1533
*/
1534
/*[28apr2004 mt]:*/
1535
#ifdef TRAPSIGNALS
1536

1537
static int exitInProgress = 0;
1538
static int trappedTerminate = 0;
1539

1540
/*INTSIGHANDLER : some systems require a signal handler to return an integer,
1541
  so define the macro INTSIGHANDLER if compiler fails:*/
1542
#ifdef INTSIGHANDLER
1543
static int onErrSig(int i)
1544
#else
1545
static VOID onErrSig(int i)
99✔
1546
#endif
1547
{
1548
        if (exitInProgress){
99✔
1549
                signal(i,SIG_DFL);/* Use default behaviour*/
×
1550
                raise (i);/*reproduce trapped signal*/
×
1551
#ifdef INTSIGHANDLER
1552
                return(i);
1553
#else
1554
                return;
×
1555
#endif
1556
        }
1557
        trappedTerminate = 1;
99✔
1558
        /*[13jul2005 mt]*//*Terminate(-1) on signal is here:*/
NEW
1559
        TERMINATE(-1);
×
1560
}
1561

1562
#ifdef INTSIGHANDLER
1563
static VOID setNewSig(int i, int (*handler)(int))
1564
#else
1565
static VOID setNewSig(int i, void (*handler)(int))
26,640✔
1566
#endif
1567
{
1568
        if(! (i<NSIG) )/* Invalid signal -- see comments in the file */
26,640✔
1569
                return;
1570
        if ( signal(i,SIG_IGN) !=SIG_IGN)
23,088✔
1571
        /* if compiler fails here, try to define INTSIGHANDLER):*/
1572
                signal(i,handler);
23,088✔
1573
}
1574

1575
VOID setSignalHandlers(VOID)
1,776✔
1576
{
1577
        /* Reset various unrecoverable error signals:*/
1578
        setNewSig(SIGSEGV,onErrSig);
1,776✔
1579
        setNewSig(SIGFPE,onErrSig);
1,776✔
1580
        setNewSig(SIGILL,onErrSig);
1,776✔
1581
        setNewSig(SIGEMT,onErrSig);
1,776✔
1582
        setNewSig(SIGSYS,onErrSig);
1,776✔
1583
        setNewSig(SIGPIPE,onErrSig);
1,776✔
1584
        setNewSig(SIGLOST,onErrSig);
1,776✔
1585
        setNewSig(SIGXCPU,onErrSig);
1,776✔
1586
        setNewSig(SIGXFSZ,onErrSig);
1,776✔
1587

1588
        /* Reset interrupt signals:*/
1589
        setNewSig(SIGTERM,onErrSig);
1,776✔
1590
        setNewSig(SIGINT,onErrSig);
1,776✔
1591
        setNewSig(SIGQUIT,onErrSig);
1,776✔
1592
        setNewSig(SIGHUP,onErrSig);
1,776✔
1593
        setNewSig(SIGALRM,onErrSig);
1,776✔
1594
        setNewSig(SIGVTALRM,onErrSig);
1,776✔
1595
/*        setNewSig(SIGPROF,onErrSig); */  /* Why did Tentukov forbid profilers?? */
1596
}
1,776✔
1597

1598
#endif
1599
/*:[28apr2004 mt]*/
1600
/*
1601
                 #] Signal handlers : 
1602
                 #[ main :
1603
*/
1604

1605
#ifdef WITHPTHREADS
1606
ALLPRIVATES *ABdummy[10];
1607
#endif
1608

1609
int main(int argc, char **argv)
1,776✔
1610
{
1611
        int retval;
1,776✔
1612
        bzero((VOID *)(&A),sizeof(A)); /* make sure A is initialized at zero */
1,776✔
1613
        iniTools();
1,776✔
1614
#ifdef TRAPSIGNALS
1615
        setSignalHandlers();
1,776✔
1616
#endif
1617

1618
#ifdef WITHPTHREADS
1619
        AB = ABdummy;
524✔
1620
        StartHandleLock();
524✔
1621
        BeginIdentities();
524✔
1622
#else
1623
        AM.SumTime = TimeCPU(0);
1,252✔
1624
        TimeWallClock(0);
1,252✔
1625
#endif
1626

1627
#ifdef WITHMPI
1628
        if ( PF_Init(&argc,&argv) ) exit(-1);
989✔
1629
#endif
1630

1631
        StartFiles();
1,776✔
1632
        StartVariables();
1,776✔
1633
#ifdef WITHMPI
1634
        /*
1635
         * Here MesPrint() is ready. We turn on AS.printflag to print possible
1636
         * errors occurring on slaves in the initialization. With AS.printflag = -1
1637
         * MesPrint() does not use the synchronized output. This may lead broken
1638
         * texts in the output somewhat, but it is safer to implement in this way
1639
         * for the situation in which some of MesPrint() calls use MLOCK()-MUNLOCK()
1640
         * and some do not. In future if we set AS.printflag = 1 and modify the
1641
         * source code such that all MesPrint() calls are sandwiched by MLOCK()-
1642
         * MUNLOCK(), we need also to modify the code for the master to catch
1643
         * messages corresponding to MUNLOCK() calls at some point.
1644
         *
1645
         * AS.printflag will be set to 0 in IniVars() to prevent slaves from
1646
         * printing redundant errors in the preprocessor and compiler (e.g., syntax
1647
         * errors).
1648
         */
1649
        AS.printflag = -1;
989✔
1650
#endif
1651

1652
        if ( ( retval = DoTail(argc,(UBYTE **)argv) ) != 0 ) {
1,776✔
NEW
1653
                if ( retval > 0 ) TERMINATE(0);
×
NEW
1654
                else              TERMINATE(-1);
×
1655
        }
1656
        if ( DoSetups() ) TERMINATE(-2);
1,776✔
1657
#ifdef WITHMPI
1658
        /* It is messy if all errors in OpenInput() on slaves are printed. */
1659
        AS.printflag = 0;
989✔
1660
#endif
1661
        if ( OpenInput() ) TERMINATE(-3);
1,776✔
1662
#ifdef WITHMPI
1663
        AS.printflag = -1;
989✔
1664
#endif
1665
        if ( TryEnvironment() ) TERMINATE(-2);
1,776✔
1666
        if ( TryFileSetups() ) TERMINATE(-2);
1,776✔
1667
        if ( MakeSetupAllocs() ) TERMINATE(-2);
1,776✔
1668
        StartMore();
1,776✔
1669
        InitRecovery();
1,776✔
1670
        CheckRecoveryFile();
1,776✔
1671
        if ( AM.totalnumberofthreads == 0 ) AM.totalnumberofthreads = 1;
1,776✔
1672
        AS.MultiThreaded = 0;
1,776✔
1673
#ifdef WITHPTHREADS
1674
        if ( AM.totalnumberofthreads > 1 ) AS.MultiThreaded = 1;
524✔
1675
        ReserveTempFiles(1);
524✔
1676
        StartAllThreads(AM.totalnumberofthreads);
524✔
1677
        IniFbufs();
524✔
1678
#else
1679
        ReserveTempFiles(0);
1,252✔
1680
        IniFbuffer(AT.fbufnum);
1,252✔
1681
#endif
1682
        if ( !AM.FromStdin ) PrintHeader(1);
1,776✔
1683
        IniVars();
1,776✔
1684
        Globalize(1);
1,776✔
1685
#ifdef WITH_ALARM
1686
        if ( AM.TimeLimit > 0 ) alarm(AM.TimeLimit);
1,776✔
1687
#endif
1688
        TimeCPU(0);
1,776✔
1689
        TimeChildren(0);
1,776✔
1690
        TimeWallClock(0);
1,776✔
1691
        PreProcessor();
1,776✔
NEW
1692
        TERMINATE(0);
×
1693
        return(0);
1694
}
1695
/*
1696
                 #] main : 
1697
                 #[ CleanUp :
1698

1699
                if par < 0 we have to keep the storage file.
1700
                when par > 0 we ran into a .clear statement.
1701
                In that case we keep the zero level input and the log file.
1702

1703
*/
1704

1705
VOID CleanUp(WORD par)
1,776✔
1706
{
1707
        GETIDENTITY
524✔
1708
        int i;
1,776✔
1709

1710
        if ( FG.fname ) {
1,776✔
1711
        CleanUpSort(0);
1,776✔
1712
        for ( i = 0; i < 3; i++ ) {
8,880✔
1713
                if ( AR.Fscr[i].handle >= 0 ) {
5,328✔
1714
                        if ( AR.Fscr[i].name ) {
×
1715
/*
1716
                                If there are more threads referring to the same file
1717
                                only the one with the name is the owner of the file.
1718
*/
1719
                                CloseFile(AR.Fscr[i].handle);
×
1720
                                remove(AR.Fscr[i].name);
×
1721
                        }
1722
                        AR.Fscr[i].handle = - 1;
×
1723
                        AR.Fscr[i].POfill = 0;
×
1724
                }
1725
        }
1726
        if ( par > 0 ) {
1,776✔
1727
/*
1728
        Close all input levels above the lowest?
1729
*/
1730
        }
1,776✔
1731
        if ( AC.StoreHandle >= 0 && par <= 0 ) {
1,776✔
1732
#ifdef TRAPSIGNALS
1733
                if ( trappedTerminate ) { /* We don't throw .str if it has contents */
1,776✔
1734
                        POSITION pos;
96✔
1735
                        PUTZERO(pos);
96✔
1736
                        SeekFile(AC.StoreHandle,&pos,SEEK_END);
96✔
1737
                        if ( ISNOTZEROPOS(pos) ) {
96✔
1738
                                CloseFile(AC.StoreHandle);
7✔
1739
                                goto dontremove;
7✔
1740
                        }
1741
                }
1742
                CloseFile(AC.StoreHandle);
1,769✔
1743
                if ( par >= 0 || AR.StoreData.Handle < 0 || AM.ClearStore ) {
1,769✔
1744
                        remove(FG.fname);
1,769✔
1745
                }
1746
dontremove:;
×
1747
#else
1748
                CloseFile(AC.StoreHandle);
1749
                if ( par >= 0 || AR.StoreData.Handle < 0 || AM.ClearStore > 0 ) {
1750
                        remove(FG.fname);
1751
                }
1752
#endif
1753
        }
1754
        }
1755
        ClearSpectators(CLEARMODULE);
1,776✔
1756
/*
1757
        Remove recovery file on exit if everything went well
1758
*/
1759
        if ( par == 0 ) {
1,776✔
1760
                DeleteRecoveryFile();
1,680✔
1761
        }
1762
/*
1763
        Now the final message concerning the total time
1764
*/
1765
        if ( AC.LogHandle >= 0 && par <= 0 ) {
1,776✔
1766
                WORD lh = AC.LogHandle;
×
1767
                AC.LogHandle = -1;
×
1768
#ifdef WITHMPI
1769
                if ( PF.me == MASTER )  /* Only the master opened the real file. */
1770
#endif
1771
                CloseFile(lh);
×
1772
        }
1773
}
1,776✔
1774

1775
/*
1776
                 #] CleanUp : 
1777
                 #[ Terminate :
1778
*/
1779

1780
static int firstterminate = 1;
1781

1782
VOID Terminate(int errorcode, const char* file, int line, const char* function)
1,872✔
1783
{
1784
        if ( errorcode && firstterminate ) {
1,872✔
1785
                firstterminate = 0;
96✔
1786
#ifdef WITHPTHREADS
1787
                MesPrint("Program terminating in thread %w at &");
40✔
1788
#elif defined(WITHMPI)
1789
                MesPrint("Program terminating in process %w at &");
36✔
1790
#else
1791
                MesPrint("Program terminating at &");
20✔
1792
#endif
1793
        MesPrint("Terminate called from %s:%d (%s). Backtrace:", file, line, function);
96✔
1794

1795
        void *stack[64];
96✔
1796
        int stacksize;
96✔
1797
        stacksize = backtrace(stack, 64);
96✔
1798

1799
        for (int i = 0; i < stacksize; ++i) {
692✔
1800
                FILE *fp;
596✔
1801
                char cmd[512];
596✔
1802
                snprintf(cmd, 512, "eu-addr2line -s --pretty-print -f -i '%p' --pid=%d\n", stack[i], getpid());
596✔
1803
                fp = popen(cmd, "r");
596✔
1804
                while ( fgets(cmd, sizeof(cmd), fp) != NULL ) {
596✔
NEW
1805
                        MesPrint("%#%d: %s", i, cmd);
×
1806
                }
1807
                pclose(fp);
596✔
1808
        }
1809

1810
                Crash();
96✔
1811
        }
1812
#ifdef TRAPSIGNALS
1813
        exitInProgress=1;
1,776✔
1814
#endif
1815
#ifdef WITHEXTERNALCHANNEL
1816
/*
1817
        This function can be called from the error handler, so it is better to
1818
        clean up all started processes before any activity:
1819
*/
1820
        closeAllExternalChannels();
1,776✔
1821
        AX.currentExternalChannel=0;
1,776✔
1822
        /*[08may2006 mt]:*/
1823
        AX.killSignal=SIGKILL;
1,776✔
1824
        AX.killWholeGroup=1;
1,776✔
1825
        AX.daemonize=1;
1,776✔
1826
        /*:[08may2006 mt]*/
1827
        if(AX.currentPrompt){
1,776✔
1828
                M_free(AX.currentPrompt,"external channel prompt");
7✔
1829
                AX.currentPrompt=0;
7✔
1830
        }
1831
        /*[08may2006 mt]:*/
1832
        if(AX.shellname){
1,776✔
1833
                M_free(AX.shellname,"external channel shellname");
1,776✔
1834
                AX.shellname=0;
1,776✔
1835
        }
1836
        if(AX.stderrname){
1,776✔
1837
                M_free(AX.stderrname,"external channel stderrname");
1,776✔
1838
                AX.stderrname=0;
1,776✔
1839
        }
1840
        /*:[08may2006 mt]*/
1841
#endif
1842
#ifdef WITHPTHREADS
1843
        if ( !WhoAmI() && !errorcode ) {
524✔
1844
                TerminateAllThreads();
484✔
1845
        }
1846
#endif
1847
        if ( AC.FinalStats ) {
1,776✔
1848
                if ( AM.PrintTotalSize ) {
1,765✔
1849
                        MesPrint("Max. space for expressions: %19p bytes",&(AS.MaxExprSize));
×
1850
                }
1851
                PrintRunningTime();
1,765✔
1852
        }
1853
#ifdef WITHMPI
1854
        if ( AM.HoldFlag && PF.me == MASTER ) {
989✔
1855
                WriteFile(AM.StdOut,(UBYTE *)("Hit any key "),12);
1856
                PF_FlushStdOutBuffer();
1857
                getchar();
1858
        }
1859
#else
1860
        if ( AM.HoldFlag ) {
787✔
1861
                WriteFile(AM.StdOut,(UBYTE *)("Hit any key "),12);
1862
                getchar();
1863
        }
1864
#endif
1865
#ifdef WITHMPI
1866
        PF_Terminate(errorcode);
989✔
1867
#endif
1868
        CleanUp(errorcode);
1,776✔
1869
        M_print();
1,776✔
1870
#ifdef VMS
1871
        P_term(errorcode? 0: 1);
1872
#else
1873
        P_term(errorcode);
1,776✔
1874
#endif
1875
}
1876

1877
/*
1878
                 #] Terminate : 
1879
                 #[ PrintRunningTime :
1880
*/
1881

1882
VOID PrintRunningTime(VOID)
1,821✔
1883
{
1884
#if (defined(WITHPTHREADS) && (defined(WITHPOSIXCLOCK) || defined(WINDOWS))) || defined(WITHMPI)
1885
        LONG mastertime;
1,552✔
1886
        LONG workertime;
1,552✔
1887
        LONG wallclocktime;
1,552✔
1888
        LONG totaltime;
1,552✔
1889
#if defined(WITHPTHREADS)
1890
        if ( AB[0] != 0 ) {
536✔
1891
                workertime = GetWorkerTimes();
536✔
1892
#else
1893
        workertime = PF_GetSlaveTimes();  /* must be called on all processors */
1,016✔
1894
        if ( PF.me == MASTER ) {
1,016✔
1895
#endif
1896
                mastertime = AM.SumTime + TimeCPU(1);
790✔
1897
                wallclocktime = TimeWallClock(1);
790✔
1898
                totaltime = mastertime+workertime;
790✔
1899
                if ( !AM.silent ) {
790✔
1900
                MesPrint("  %l.%2i sec + %l.%2i sec: %l.%2i sec out of %l.%2i sec",
790✔
1901
                        mastertime/1000,(WORD)((mastertime%1000)/10),
790✔
1902
                        workertime/1000,(WORD)((workertime%1000)/10),
790✔
1903
                        totaltime/1000,(WORD)((totaltime%1000)/10),
790✔
1904
                        wallclocktime/100,(WORD)(wallclocktime%100));
790✔
1905
                }
1906
        }
1907
#else
1908
        LONG mastertime = AM.SumTime + TimeCPU(1);
269✔
1909
        LONG wallclocktime = TimeWallClock(1);
269✔
1910
        if ( !AM.silent ) {
269✔
1911
        MesPrint("  %l.%2i sec out of %l.%2i sec",
269✔
1912
                mastertime/1000,(WORD)((mastertime%1000)/10),
269✔
1913
                wallclocktime/100,(WORD)(wallclocktime%100));
269✔
1914
        }
1915
#endif
1916
}
1,821✔
1917

1918
/*
1919
                 #] PrintRunningTime : 
1920
                 #[ GetRunningTime :
1921
*/
1922

1923
LONG GetRunningTime(VOID)
1,776✔
1924
{
1925
#if defined(WITHPTHREADS) && (defined(WITHPOSIXCLOCK) || defined(WINDOWS))
1926
        LONG mastertime;
524✔
1927
        if ( AB[0] != 0 ) {
524✔
1928
/* 
1929
#if ( defined(APPLE64) || defined(APPLE32) )
1930
                mastertime = AM.SumTime + TimeCPU(1);
1931
                return(mastertime);
1932
#else
1933
*/
1934
                LONG workertime = GetWorkerTimes();
524✔
1935
                mastertime = AM.SumTime + TimeCPU(1);
524✔
1936
                return(mastertime+workertime);
524✔
1937
/*
1938
#endif
1939
*/
1940
        }
1941
        else {
1942
                return(AM.SumTime + TimeCPU(1));
1943
        }
1944
#elif defined(WITHMPI)
1945
        LONG mastertime, t = 0;
989✔
1946
        LONG workertime = PF_GetSlaveTimes();  /* must be called on all processors */
989✔
1947
        if ( PF.me == MASTER ) {
989✔
1948
                mastertime = AM.SumTime + TimeCPU(1);
248✔
1949
                t = mastertime + workertime;
248✔
1950
        }
1951
        return PF_BroadcastNumber(t);  /* must be called on all processors */
989✔
1952
#else
1953
        return(AM.SumTime + TimeCPU(1));
263✔
1954
#endif
1955
}
1956

1957
/*
1958
                 #] GetRunningTime : 
1959
*/
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