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

form-dev / form / 15701338753

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

Pull #662

github

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

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

2 existing lines in 1 file now uncovered.

41784 of 82935 relevant lines covered (50.38%)

2640008.85 hits per line

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

2.73
/sources/checkpoint.c
1
/*
2
          #[ Explanations :
3
*/
4
/** @file checkpoint.c
5
 * 
6
 *  Contains all functions that deal with the recovery mechanism controlled and
7
 *  activated by the On Checkpoint switch.
8
 *
9
 *  The main function are DoCheckpoint, DoRecovery, and DoSnapshot. If the
10
 *  checkpoints are activated DoCheckpoint is called every time a module is
11
 *  finished executing. If the conditions for the creation of a recovery
12
 *  snapshot are met DoCheckpoint calls DoSnapshot. DoRecovery is called once
13
 *  when FORM starts up with the command line argument -R. Most of the other
14
 *  code contains debugging facilities that are only compiled if the macro
15
 *  PRINTDEBUG is defined.
16
 *
17
 *  The recovery mechanism is atomic, i.e. only if everything went well, the
18
 *  final recovery file is created (and the older one overwritten) in a single
19
 *  step (copying). If some errors occur, a warning is issued and the program
20
 *  continues without having created a new recovery file. The only situation in
21
 *  which the creation of the recovery data leads to a termination of the
22
 *  running program is if not enough disk or memory space is left.
23
 *
24
 *  For ParFORM each slave creates its own recovery file, sends it to the 
25
 *  master and then it deletes the recovery file. The master stores all the 
26
 *  recovery files and on recovery it feeds these files to the slaves. It is
27
 *  nearly impossible to recover after some MPI fault so ParFORM terminates 
28
 *  on any recovery failure.
29
 *
30
 *  DoRecovery and DoSnapshot do the loading and saving of the recovery data,
31
 *  respectively. Every change in one functions needs to be accompanied by the
32
 *  appropriate change in the other function. The structure of both functions is
33
 *  quite similar. They handle the relevant global structs one after the other
34
 *  and then care about the copying of the hide and scratch files.
35
 *
36
 *  The names of the recovery, scratch and hide files are hard-coded in the
37
 *  variables in fold "filenames and system commands".
38
 *
39
 *  If the global structs AM,AP,AC,AR are changed, DoRecovery and DoSnapshot
40
 *  usually also have to be changed. Some structs are read/written as a whole
41
 *  (AP,AC), some are read/written only partly as a selection of their
42
 *  individual elements (AM,AR). If AM or AR have been changed by adding or
43
 *  removing an element that is important for the runtime status, then the
44
 *  reading/writing statements have to be added to or removed from DoRecovery
45
 *  and DoSnapshot. If AP or AC are changed, then for non-pointer variables (in
46
 *  the case of a struct it also means that none of its elements is a pointer)
47
 *  nothing has to be changed in the functions here. If pointers are involved,
48
 *  extra code has to be added (or removed). See the comments of DoRecovery and
49
 *  DoSnapshot.
50
 *
51
 */
52
/*
53
          #] Explanations : 
54
          #[ License :
55
 *
56
 *   Copyright (C) 1984-2023 J.A.M. Vermaseren
57
 *   When using this file you are requested to refer to the publication
58
 *   J.A.M.Vermaseren "New features of FORM" math-ph/0010025
59
 *   This is considered a matter of courtesy as the development was paid
60
 *   for by FOM the Dutch physics granting agency and we would like to
61
 *   be able to track its scientific use to convince FOM of its value
62
 *   for the community.
63
 *
64
 *   This file is part of FORM.
65
 *
66
 *   FORM is free software: you can redistribute it and/or modify it under the
67
 *   terms of the GNU General Public License as published by the Free Software
68
 *   Foundation, either version 3 of the License, or (at your option) any later
69
 *   version.
70
 *
71
 *   FORM is distributed in the hope that it will be useful, but WITHOUT ANY
72
 *   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
73
 *   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
74
 *   details.
75
 *
76
 *   You should have received a copy of the GNU General Public License along
77
 *   with FORM.  If not, see <http://www.gnu.org/licenses/>.
78
 */
79
/*
80
          #] License : 
81
          #[ Includes :
82
*/
83

84
#include "form3.h"
85

86
#include <errno.h>
87

88
/*
89
#define PRINTDEBUG
90
*/
91

92
/*
93
#define PRINTTIMEMARKS
94
*/
95

96
/*
97
          #] Includes : 
98
          #[ filenames and system commands :
99
*/
100

101
/**
102
 *  BaseName of recovery files
103
 */
104
#ifdef WITHMPI
105
#define BASENAME_FMT "%c%04dFORMrecv"
106
/**
107
 * The basenames for ParFORM will be created from BASENAME_FMT by means of 
108
 * sprintf(BaseName,BASENAME_FMT,(PF.me == MASTER)?'m':'s',PF.me);
109
 * in InitRecovery(). Here just reserve the space:
110
 */
111
static char BaseName[] = BASENAME_FMT;
112
#else
113
static char *BaseName = "FORMrecv";
114
#endif
115
/**
116
 *  filename for the recovery file
117
 */
118
static char *recoveryfile = 0;
119
/**
120
 *  filename for the intermediate recovery file. only if the write is
121
 *  completely successful, this file will be moved/renamed to the one
122
 *  named by recoveryfile. this offers atomicity for the snapshot generation.
123
 */
124
static char *intermedfile = 0;
125
/**
126
 *  filename of sort file copy
127
 */
128
static char *sortfile = 0;
129
/**
130
 *  filename of hide file copy
131
 */
132
static char *hidefile = 0;
133
/**
134
 *  filename of store file copy
135
 */
136
static char *storefile = 0;
137

138
/**
139
 *  >0 if at least once the respective file has been created.
140
 *  Checked by DeleteRecoveryFile().
141
 */
142
static int done_snapshot = 0;
143

144
#ifdef WITHMPI
145
/**
146
 *  The position at which BASENAME_FMT should be applied.
147
 *  Initialized in InitRecovery().
148
 */
149
static int PF_fmt_pos;
150

151
/**
152
 *  Returns the contents of recoveryfile or intermedfile but with the renaming
153
 *  specified by the arguments.
154
 */
155
static const char *PF_recoveryfile(char prefix, int id, int intermed)
156
{
157
        /*
158
         * Assume that InitRecovery() has been already called, namely
159
         * recoveryfile, intermedfile and PF_fmt_pos are already initialized.
160
         */
161
        static char *tmp_recovery = NULL;
162
        static char *tmp_intermed  = NULL;
163
        char *tmp, c;
164
        if ( tmp_recovery == NULL ) {
165
                if ( PF.numtasks > 9999 ) {  /* see BASENAME_FMT */
166
                        MesPrint("Checkpoint: too many number of processors.");
167
                        Terminate(-1);
168
                }
169
                tmp_recovery = (char *)Malloc1(strlen(recoveryfile) + strlen(intermedfile) + 2, "PF_recoveryfile");
170
                tmp_intermed = tmp_recovery + strlen(recoveryfile) + 1;
171
                strcpy(tmp_recovery, recoveryfile);
172
                strcpy(tmp_intermed, intermedfile);
173
        }
174
        tmp = intermed ? tmp_intermed : tmp_recovery;
175
        c = tmp[PF_fmt_pos + 13];  /* The magic number 13 comes from BASENAME_FMT. */
176
        sprintf(tmp + PF_fmt_pos, BASENAME_FMT, prefix, id);
177
        tmp[PF_fmt_pos + 13] = c;
178
        return tmp;
179
}
180
#endif
181

182
/*
183
          #] filenames and system commands : 
184
          #[ CheckRecoveryFile :
185
*/
186

187
/**
188
 *  Checks whether a snapshot/recovery file exists.
189
 *  Returns 1 if it exists, 0 otherwise.
190
 */
191
#ifdef WITHMPI
192

193
/**
194
 * The master has all the recovery files. It checks whether these files
195
 * exist and sends proper files to slaves. On any error PF_CheckRecoveryFile()
196
 * returns -1 which leads to the program termination.
197
 */
198
static int PF_CheckRecoveryFile()
199
{
200
        int i,ret=0;
201
        FILE *fd;
202
        /* Check if the recovery file for the master exists. */
203
        if ( PF.me == MASTER ) {
204
                if ( (fd = fopen(recoveryfile, "r")) ) {
205
                        fclose(fd);
206
                        PF_BroadcastNumber(1);
207
                }
208
                else {
209
                        PF_BroadcastNumber(0);
210
                        return 0;
211
                }
212
        }
213
        else {
214
                if ( !PF_BroadcastNumber(0) )
215
                        return 0;
216
        }
217
        /* Now the main part. */
218
        if (PF.me == MASTER){
219
                /*We have to have recovery files for the master and all the slaves:*/
220
                for(i=1; i<PF.numtasks;i++){
221
                        const char *tmpnam = PF_recoveryfile('m', i, 0);
222
                        if ( (fd = fopen(tmpnam, "r")) )
223
                                fclose(fd);
224
                        else
225
                                break;
226
                }/*for(i=0; i<PF.numtasks;i++)*/
227
                if(i!=PF.numtasks){/*some files are absent*/
228
                        int j;
229
                        /*Send all slaves failure*/
230
                        for(j=1; j<PF.numtasks;j++){
231
                                ret=PF_SendFile(j, NULL);
232
                                if(ret<0)
233
                                        return(-1);
234
                        }
235
                        if(i==0)
236
                                return(0);/*Ok, no recovery files at all.*/
237
                        /*The master recovery file exists but some slave files are absent*/
238
                        MesPrint("The file %s exists but some of the slave recovery files are absent.",
239
                                                        RecoveryFilename());
240
                        return(-1);
241
                }/*if(i!=PF.numtasks)*/
242
                /*All the files are here.*/
243
                /*Send all slaves success and files:*/
244
                for(i=1; i<PF.numtasks;i++){
245
                        const char *tmpnam = PF_recoveryfile('m', i, 0);
246
                        fd = fopen(tmpnam, "r");
247
                        ret=PF_SendFile(i, fd);/*if fd==NULL, PF_SendFile seds to a slave the failure tag*/
248
                        if(fd == NULL)
249
                                return(-1);
250
                        else
251
                                fclose(fd);
252
                        if(ret<0)
253
                                return(-1);
254
                }/*for(i=0; i<PF.numtasks;i++)*/
255
                return(1);                
256
        }/*if (PF.me == MASTER)*/
257
        /*Slave:*/
258
        /*Get the answer from the master:*/
259
        fd=fopen(recoveryfile,"w");
260
        if(fd == NULL) {
261
                MesPrint("Failed to open %s in write mode in process %w", recoveryfile);
262
                return(-1);
263
        }
264
        ret=PF_RecvFile(MASTER,fd);
265
        if(ret<0)
266
                return(-1);
267
        fclose(fd);
268
        if(ret==0){
269
                /*Nothing is found by the master*/
270
                remove(recoveryfile);
271
                return(0);
272
        }
273
        /*Recovery file is successfully transferred*/
274
        return(1);
275
}
276
#endif
277

278
int CheckRecoveryFile(void)
1,952✔
279
{
280
        int ret = 0;
1,952✔
281
#ifdef WITHMPI
282
        ret = PF_CheckRecoveryFile();
283
#else
284
        FILE *fd;
1,952✔
285
        if ( (fd = fopen(recoveryfile, "r")) ) {
1,952✔
286
                fclose(fd);
×
287
                ret = 1;
×
288
        }
289
#endif
290
        if ( ret < 0 ){/*In ParFORM CheckRecoveryFile() may return a fatal error.*/
×
291
                MesPrint("Fail checking recovery file");
292
                Terminate(-1);
293
        }
294
        else if  ( ret > 0 ) {
1,952✔
295
                if ( AC.CheckpointFlag != -1 ) {
×
296
                        /* recovery file exists but recovery option is not given */
297
#ifdef WITHMPI
298
                        if ( PF.me == MASTER ) {
299
#endif
300
                        MesPrint("The recovery file %s exists, but the recovery option -R has not been given!", RecoveryFilename());
×
301
                        MesPrint("FORM will be terminated to avoid unintentional loss of data.");
×
302
                        MesPrint("Delete the recovery file manually, if you want to start FORM without recovery.");
×
303
#ifdef WITHMPI
304
                        }
305
                        if(PF.me != MASTER)
306
                                remove(RecoveryFilename());
307
#endif
308
                        Terminate(-1);
×
309
                }
310
        }
311
        else {
312
                if ( AC.CheckpointFlag == -1 ) {
1,952✔
313
                        /* recovery option given but recovery file does not exist */
314
#ifdef WITHMPI
315
                        if ( PF.me == MASTER )
316
#endif
317
                        MesPrint("Option -R for recovery has been given, but the recovery file %s does not exist!", RecoveryFilename());
×
318
                        Terminate(-1);
×
319
                }
320
        }
321
        return(ret);
1,952✔
322
}
323

324
/*
325
          #] CheckRecoveryFile : 
326
          #[ DeleteRecoveryFile :
327
*/
328

329
/**
330
 *  Deletes the recovery files. It is called by CleanUp() in the case of a
331
 *  successful completion.
332
 */
333
void DeleteRecoveryFile(void)
1,748✔
334
{
335
        if ( done_snapshot ) {
1,748✔
336
                remove(recoveryfile);
×
337
#ifdef WITHMPI
338
                if( PF.me == MASTER){
339
                        int i;
340
                        for(i=1; i<PF.numtasks;i++){
341
                                const char *tmpnam = PF_recoveryfile('m', i, 0);
342
                                remove(tmpnam);
343
                        }/*for(i=1; i<PF.numtasks;i++)*/
344
                        remove(storefile);
345
                        remove(sortfile);
346
                        remove(hidefile);
347
                }/*if( PF.me == MASTER)*/
348
#else
349
                remove(storefile);
×
350
                remove(sortfile);
×
351
                remove(hidefile);
×
352
#endif
353
        }
354
}
1,748✔
355

356
/*
357
          #] DeleteRecoveryFile : 
358
          #[ RecoveryFilename :
359
*/
360

361
/**
362
 *  Returns pointer to recovery filename. 
363
 */
NEW
364
char *RecoveryFilename(void)
×
365
{
366
        return(recoveryfile);
×
367
}
368

369
/*
370
          #] RecoveryFilename : 
371
          #[ InitRecovery :
372
*/
373

374
/**
375
 *  Utility function for InitRecovery().
376
 */
377
static char *InitName(char *str, char *ext)
9,760✔
378
{
379
        char *s, *d = str;
9,760✔
380
        if ( AM.TempDir ) {
9,760✔
381
                s = (char*)AM.TempDir;
382
                while ( *s ) { *d++ = *s++; }
×
383
                *d++ = SEPARATOR;
×
384
        }
385
        s = BaseName;
9,760✔
386
        while ( *s ) { *d++ = *s++; }
87,840✔
387
        *d++ = '.';
9,760✔
388
        s = ext;
9,760✔
389
        while ( *s ) { *d++ = *s++; }
39,040✔
390
        *d++ = 0;
9,760✔
391
        return d;
9,760✔
392
}
393

394
/**
395
 *  Sets up the strings for the filenames of the recovery files.
396
 *  This functions should only be called once to avoid memory leaks and after
397
 *  AM.TempDir has been initialized.
398
 */
399
void InitRecovery(void)
1,952✔
400
{
401
        int lenpath = AM.TempDir ? strlen((char*)AM.TempDir)+1 : 0;
1,952✔
402
#ifdef WITHMPI
403
        sprintf(BaseName,BASENAME_FMT,(PF.me == MASTER)?'m':'s',PF.me);
404
        /*Now BaseName has a form ?XXXXFORMrecv where ? == 'm' for master and 's' for slave,
405
                XXXX is a zero - padded PF.me*/
406
        PF_fmt_pos = lenpath;
407
#endif        
408
        recoveryfile = (char*)Malloc1(5*(lenpath+strlen(BaseName)+4+1),"InitRecovery");
1,952✔
409
        intermedfile = InitName(recoveryfile, "tmp");
1,952✔
410
        sortfile     = InitName(intermedfile, "XXX");
1,952✔
411
        hidefile     = InitName(sortfile, "out");
1,952✔
412
        storefile    = InitName(hidefile, "hid");
1,952✔
413
                       InitName(storefile, "str");
1,952✔
414
}
1,952✔
415

416
/*
417
          #] InitRecovery : 
418
          #[ Debugging :
419
*/
420

421
#ifdef PRINTDEBUG
422

423
void print_BYTE(void *p)
424
{
425
        UBYTE h = (UBYTE)(*((UBYTE*)p) >> 4);
426
        UBYTE l = (UBYTE)(*((UBYTE*)p) & 0x0F);
427
        if ( h > 9 ) h += 55; else h += 48;
428
        if ( l > 9 ) l += 55; else l += 48;
429
        printf("%c%c ", h, l);
430
}
431

432
static void print_STR(UBYTE *p)
433
{
434
        if ( p ) {
435
                MesPrint("%s", (char*)p);
436
        }
437
        else {
438
                MesPrint("NULL");
439
        }
440
}
441

442
static void print_WORDB(WORD *buf, WORD *top)
443
{
444
        LONG size = top-buf;
445
        int i;
446
        while ( size > 0 ) {
447
                if ( size > MAXPOSITIVE ) i = MAXPOSITIVE;
448
                else i = size;
449
                size -= i;
450
                MesPrint("%a",i,buf);
451
                buf += i;
452
        }
453
}
454

455
static void print_VOIDP(void *p, size_t size)
456
{
457
        int i;
458
        if ( p ) {
459
                while ( size > 0 ) {
460
                        if ( size > MAXPOSITIVE ) i = MAXPOSITIVE;
461
                        else i = size;
462
                        size -= i;
463
                        MesPrint("%b",i,(UBYTE *)p);
464
                        p = ((UBYTE *)p)+i;
465
                }
466
        }
467
        else {
468
                MesPrint("NULL");
469
        }
470
}
471

472
static void print_CHARS(UBYTE *p, size_t size)
473
{
474
        int i;
475
        while ( size > 0 ) {
476
                if ( size > MAXPOSITIVE ) i = MAXPOSITIVE;
477
                else i = size;
478
                size -= i;
479
                MesPrint("%C",i,(char *)p);
480
                p += i;
481
        }
482
}
483

484
static void print_WORDV(WORD *p, size_t size)
485
{
486
        int i;
487
        if ( p ) {
488
                while ( size > 0 ) {
489
                        if ( size > MAXPOSITIVE ) i = MAXPOSITIVE;
490
                        else i = size;
491
                        size -= i;
492
                        MesPrint("%a",i,p);
493
                        p += i;
494
                }
495
        }
496
        else {
497
                MesPrint("NULL");
498
        }
499
}
500

501
static void print_INTV(int *p, size_t size)
502
{
503
        int iarray[8];
504
        WORD i = 0;
505
        if ( p ) {
506
                while ( size > 0 ) {
507
                        if ( i >= 8 ) {
508
                                MesPrint("%I",i,iarray);
509
                                i = 0;
510
                        }
511
                        iarray[i++] = *p++;
512
                        size--;
513
                }
514
                if ( i > 0 ) MesPrint("%I",i,iarray);
515
        }
516
        else {
517
                MesPrint("NULL");
518
        }
519
}
520

521
static void print_LONGV(LONG *p, size_t size)
522
{
523
        LONG larray[8];
524
        WORD i = 0;
525
        if ( p ) {
526
                while ( size > 0 ) {
527
                        if ( i >= 8 ) {
528
                                MesPrint("%I",i,larray);
529
                                i = 0;
530
                        }
531
                        larray[i++] = *p++;
532
                        size--;
533
                }
534
                if ( i > 0 ) MesPrint("%I",i,larray);
535
        }
536
        else {
537
                MesPrint("NULL");
538
        }
539
}
540

541
static void print_PRELOAD(PRELOAD *l)
542
{
543
        if ( l->size ) {
544
                print_CHARS(l->buffer, l->size);
545
        }
546
        MesPrint("%ld", l->size);
547
}
548

549
static void print_PREVAR(PREVAR *l)
550
{
551
        MesPrint("%s", l->name);
552
        print_STR(l->value);
553
        if ( l->nargs ) print_STR(l->argnames);
554
        MesPrint("%d", l->nargs);
555
        MesPrint("%d", l->wildarg);
556
}
557

558
static void print_DOLLARS(DOLLARS l)
559
{
560
        print_VOIDP(l->where, l->size);
561
        MesPrint("%ld", l->size);
562
        MesPrint("%ld", l->name);
563
        MesPrint("%s", AC.dollarnames->namebuffer+l->name);
564
        MesPrint("%d", l->type);
565
        MesPrint("%d", l->node);
566
        MesPrint("%d", l->index);
567
        MesPrint("%d", l->zero);
568
        MesPrint("%d", l->numdummies);
569
        MesPrint("%d", l->nfactors);
570
}
571

572
static void print_LIST(LIST *l)
573
{
574
        print_VOIDP(l->lijst, l->size);
575
        MesPrint("%s", l->message);
576
        MesPrint("%d", l->num);
577
        MesPrint("%d", l->maxnum);
578
        MesPrint("%d", l->size);
579
        MesPrint("%d", l->numglobal);
580
        MesPrint("%d", l->numtemp);
581
        MesPrint("%d", l->numclear);
582
}
583

584
static void print_DOLOOP(DOLOOP *l)
585
{
586
        print_PRELOAD(&(l->p));
587
        print_STR(l->name);
588
        if ( l->type != NUMERICALLOOP ) {
589
                print_STR(l->vars);
590
        }
591
        print_STR(l->contents);
592
        if ( l->type != LISTEDLOOP && l->type != NUMERICALLOOP ) {
593
                print_STR(l->dollarname);
594
        }
595
        MesPrint("%l", l->startlinenumber);
596
        MesPrint("%l", l->firstnum);
597
        MesPrint("%l", l->lastnum);
598
        MesPrint("%l", l->incnum);
599
        MesPrint("%d", l->type);
600
        MesPrint("%d", l->NoShowInput);
601
        MesPrint("%d", l->errorsinloop);
602
        MesPrint("%d", l->firstloopcall);
603
}
604

605
static void print_PROCEDURE(PROCEDURE *l)
606
{
607
        if ( l->loadmode != 1 ) {
608
                print_PRELOAD(&(l->p));
609
        }
610
        print_STR(l->name);
611
        MesPrint("%d", l->loadmode);
612
}
613

614
static void print_NAMETREE(NAMETREE *t)
615
{
616
        int i;
617
        for ( i=0; i<t->nodefill; ++i ) {
618
                MesPrint("%l %d %d %d %d %d %d\n", t->namenode[i].name,
619
                         t->namenode[i].parent, t->namenode[i].left, t->namenode[i].right,
620
                         t->namenode[i].balance, t->namenode[i].type, t->namenode[i].number );
621
        }
622
        print_CHARS(t->namebuffer, t->namefill);
623
        MesPrint("%l", t->namesize);
624
        MesPrint("%l", t->namefill);
625
        MesPrint("%l", t->nodesize);
626
        MesPrint("%l", t->nodefill);
627
        MesPrint("%l", t->oldnamefill);
628
        MesPrint("%l", t->oldnodefill);
629
        MesPrint("%l", t->globalnamefill);
630
        MesPrint("%l", t->globalnodefill);
631
        MesPrint("%l", t->clearnamefill);
632
        MesPrint("%l", t->clearnodefill);
633
        MesPrint("%d", t->headnode);
634
}
635

636
void print_CBUF(CBUF *c)
637
{
638
        int i;
639
        print_WORDV(c->Buffer, c->BufferSize);
640
        /*
641
        MesPrint("%x", c->Buffer);
642
        MesPrint("%x", c->lhs);
643
        MesPrint("%x", c->rhs);
644
        */
645
        for ( i=0; i<c->numlhs; ++i ) {
646
                if ( c->lhs[i]) MesPrint("%d", *(c->lhs[i]));
647
        }
648
        for ( i=0; i<c->numrhs; ++i ) {
649
                if ( c->rhs[i]) MesPrint("%d", *(c->rhs[i]));
650
        }
651
        MesPrint("%l", *c->CanCommu);
652
        MesPrint("%l", *c->NumTerms);
653
        MesPrint("%d", *c->numdum);
654
        for ( i=0; i<c->MaxTreeSize; ++i ) {
655
                MesPrint("%d %d %d %d %d", c->boomlijst[i].parent, c->boomlijst[i].left, c->boomlijst[i].right,
656
                                c->boomlijst[i].value, c->boomlijst[i].blnce);
657
        }
658
}
659

660
static void print_STREAM(STREAM *t)
661
{
662
        print_CHARS(t->buffer, t->inbuffer);
663
        MesPrint("%l", (LONG)(t->pointer-t->buffer));
664
        print_STR(t->FoldName);
665
        print_STR(t->name);
666
        if ( t->type == PREVARSTREAM || t->type == DOLLARSTREAM ) {
667
                print_STR(t->pname);
668
        }
669
        MesPrint("%l", (LONG)t->fileposition);
670
        MesPrint("%l", (LONG)t->linenumber);
671
        MesPrint("%l", (LONG)t->prevline);
672
        MesPrint("%l", t->buffersize);
673
        MesPrint("%l", t->bufferposition);
674
        MesPrint("%l", t->inbuffer);
675
        MesPrint("%d", t->previous);
676
        MesPrint("%d", t->handle);
677
        switch ( t->type ) {
678
                case FILESTREAM: MesPrint("%d == FILESTREAM", t->type); break;
679
                case PREVARSTREAM: MesPrint("%d == PREVARSTREAM", t->type); break;
680
                case PREREADSTREAM: MesPrint("%d == PREREADSTREAM", t->type); break;
681
                case PIPESTREAM: MesPrint("%d == PIPESTREAM", t->type); break;
682
                case PRECALCSTREAM: MesPrint("%d == PRECALCSTREAM", t->type); break;
683
                case DOLLARSTREAM: MesPrint("%d == DOLLARSTREAM", t->type); break;
684
                case PREREADSTREAM2: MesPrint("%d == PREREADSTREAM2", t->type); break;
685
                case EXTERNALCHANNELSTREAM: MesPrint("%d == EXTERNALCHANNELSTREAM", t->type); break;
686
                case PREREADSTREAM3: MesPrint("%d == PREREADSTREAM3", t->type); break;
687
                default: MesPrint("%d == UNKNOWN", t->type);
688
        }
689
}
690

691
static void print_M()
692
{
693
        MesPrint("%%%% M_const");
694
        MesPrint("%d", *AM.gcmod);
695
        MesPrint("%d", *AM.gpowmod);
696
        print_STR(AM.TempDir);
697
        print_STR(AM.TempSortDir);
698
        print_STR(AM.IncDir);
699
        print_STR(AM.InputFileName);
700
        print_STR(AM.LogFileName);
701
        print_STR(AM.OutBuffer);
702
        print_STR(AM.Path);
703
        print_STR(AM.SetupDir);
704
        print_STR(AM.SetupFile);
705
        MesPrint("--MARK  1");
706
        MesPrint("%l", (LONG)BASEPOSITION(AM.zeropos));
707
#ifdef WITHPTHREADS
708
        MesPrint("%l", AM.ThreadScratSize);
709
        MesPrint("%l", AM.ThreadScratOutSize);
710
#endif
711
        MesPrint("%l", AM.MaxTer);
712
        MesPrint("%l", AM.CompressSize);
713
        MesPrint("%l", AM.ScratSize);
714
        MesPrint("%l", AM.SizeStoreCache);
715
        MesPrint("%l", AM.MaxStreamSize);
716
        MesPrint("%l", AM.SIOsize);
717
        MesPrint("%l", AM.SLargeSize);
718
        MesPrint("%l", AM.SSmallEsize);
719
        MesPrint("%l", AM.SSmallSize);
720
        MesPrint("--MARK  2");
721
        MesPrint("%l", AM.STermsInSmall);
722
        MesPrint("%l", AM.MaxBracketBufferSize);
723
        MesPrint("%l", AM.hProcessBucketSize);
724
        MesPrint("%l", AM.gProcessBucketSize);
725
        MesPrint("%l", AM.shmWinSize);
726
        MesPrint("%l", AM.OldChildTime);
727
        MesPrint("%l", AM.OldSecTime);
728
        MesPrint("%l", AM.OldMilliTime);
729
        MesPrint("%l", AM.WorkSize);
730
        MesPrint("%l", AM.gThreadBucketSize);
731
        MesPrint("--MARK  3");
732
        MesPrint("%l", AM.ggThreadBucketSize);
733
        MesPrint("%d", AM.FileOnlyFlag);
734
        MesPrint("%d", AM.Interact);
735
        MesPrint("%d", AM.MaxParLevel);
736
        MesPrint("%d", AM.OutBufSize);
737
        MesPrint("%d", AM.SMaxFpatches);
738
        MesPrint("%d", AM.SMaxPatches);
739
        MesPrint("%d", AM.StdOut);
740
        MesPrint("%d", AM.ginsidefirst);
741
        MesPrint("%d", AM.gDefDim);
742
        MesPrint("%d", AM.gDefDim4);
743
        MesPrint("--MARK  4");
744
        MesPrint("%d", AM.NumFixedSets);
745
        MesPrint("%d", AM.NumFixedFunctions);
746
        MesPrint("%d", AM.rbufnum);
747
        MesPrint("%d", AM.dbufnum);
748
        MesPrint("%d", AM.SkipClears);
749
        MesPrint("%d", AM.gfunpowers);
750
        MesPrint("%d", AM.gStatsFlag);
751
        MesPrint("%d", AM.gNamesFlag);
752
        MesPrint("%d", AM.gCodesFlag);
753
        MesPrint("%d", AM.gTokensWriteFlag);
754
        MesPrint("%d", AM.gSortType);
755
        MesPrint("%d", AM.gproperorderflag);
756
        MesPrint("--MARK  5");
757
        MesPrint("%d", AM.hparallelflag);
758
        MesPrint("%d", AM.gparallelflag);
759
        MesPrint("%d", AM.totalnumberofthreads);
760
        MesPrint("%d", AM.gSizeCommuteInSet);
761
        MesPrint("%d", AM.gThreadStats);
762
        MesPrint("%d", AM.ggThreadStats);
763
        MesPrint("%d", AM.gFinalStats);
764
        MesPrint("%d", AM.ggFinalStats);
765
        MesPrint("%d", AM.gThreadsFlag);
766
        MesPrint("%d", AM.ggThreadsFlag);
767
        MesPrint("%d", AM.gThreadBalancing);
768
        MesPrint("%d", AM.ggThreadBalancing);
769
        MesPrint("%d", AM.gThreadSortFileSynch);
770
        MesPrint("%d", AM.ggThreadSortFileSynch);
771
        MesPrint("%d", AM.gProcessStats);
772
        MesPrint("%d", AM.ggProcessStats);
773
        MesPrint("%d", AM.gOldParallelStats);
774
        MesPrint("%d", AM.ggOldParallelStats);
775
        MesPrint("%d", AM.gWTimeStatsFlag);
776
        MesPrint("%d", AM.ggWTimeStatsFlag);
777
        MesPrint("%d", AM.maxFlevels);
778
        MesPrint("--MARK  6");
779
        MesPrint("%d", AM.resetTimeOnClear);
780
        MesPrint("%d", AM.gcNumDollars);
781
        MesPrint("%d", AM.MultiRun);
782
        MesPrint("%d", AM.gNoSpacesInNumbers);
783
        MesPrint("%d", AM.ggNoSpacesInNumbers);
784
        MesPrint("%d", AM.MaxTal);
785
        MesPrint("%d", AM.IndDum);
786
        MesPrint("%d", AM.DumInd);
787
        MesPrint("%d", AM.WilInd);
788
        MesPrint("%d", AM.gncmod);
789
        MesPrint("%d", AM.gnpowmod);
790
        MesPrint("%d", AM.gmodmode);
791
        MesPrint("--MARK  7");
792
        MesPrint("%d", AM.gUnitTrace);
793
        MesPrint("%d", AM.gOutputMode);
794
        MesPrint("%d", AM.gCnumpows);
795
        MesPrint("%d", AM.gOutputSpaces);
796
        MesPrint("%d", AM.gOutNumberType);
797
        MesPrint("%d %d %d %d", AM.gUniTrace[0], AM.gUniTrace[1], AM.gUniTrace[2], AM.gUniTrace[3]);
798
        MesPrint("%d", AM.MaxWildcards);
799
        MesPrint("%d", AM.mTraceDum);
800
        MesPrint("%d", AM.OffsetIndex);
801
        MesPrint("%d", AM.OffsetVector);
802
        MesPrint("%d", AM.RepMax);
803
        MesPrint("%d", AM.LogType);
804
        MesPrint("%d", AM.ggStatsFlag);
805
        MesPrint("%d", AM.gLineLength);
806
        MesPrint("%d", AM.qError);
807
        MesPrint("--MARK  8");
808
        MesPrint("%d", AM.FortranCont);
809
        MesPrint("%d", AM.HoldFlag);
810
        MesPrint("%d %d %d %d %d", AM.Ordering[0], AM.Ordering[1], AM.Ordering[2], AM.Ordering[3], AM.Ordering[4]);
811
        MesPrint("%d %d %d %d %d", AM.Ordering[5], AM.Ordering[6], AM.Ordering[7], AM.Ordering[8], AM.Ordering[9]);
812
        MesPrint("%d %d %d %d %d", AM.Ordering[10], AM.Ordering[11], AM.Ordering[12], AM.Ordering[13], AM.Ordering[14]);
813
        MesPrint("%d", AM.silent);
814
        MesPrint("%d", AM.tracebackflag);
815
        MesPrint("%d", AM.expnum);
816
        MesPrint("%d", AM.denomnum);
817
        MesPrint("%d", AM.facnum);
818
        MesPrint("%d", AM.invfacnum);
819
        MesPrint("%d", AM.sumnum);
820
        MesPrint("%d", AM.sumpnum);
821
        MesPrint("--MARK  9");
822
        MesPrint("%d", AM.OldOrderFlag);
823
        MesPrint("%d", AM.termfunnum);
824
        MesPrint("%d", AM.matchfunnum);
825
        MesPrint("%d", AM.countfunnum);
826
        MesPrint("%d", AM.gPolyFun);
827
        MesPrint("%d", AM.gPolyFunInv);
828
        MesPrint("%d", AM.gPolyFunType);
829
        MesPrint("%d", AM.gPolyFunExp);
830
        MesPrint("%d", AM.gPolyFunVar);
831
        MesPrint("%d", AM.gPolyFunPow);
832
        MesPrint("--MARK 10");
833
        MesPrint("%d", AM.dollarzero);
834
        MesPrint("%d", AM.atstartup);
835
        MesPrint("%d", AM.exitflag);
836
        MesPrint("%d", AM.NumStoreCaches);
837
        MesPrint("%d", AM.gIndentSpace);
838
        MesPrint("%d", AM.ggIndentSpace);
839
        MesPrint("%d", AM.gShortStatsMax);
840
        MesPrint("%d", AM.ggShortStatsMax);
841
        MesPrint("--MARK 11");
842
        MesPrint("%d", AM.FromStdin);
843
        MesPrint("%d", AM.IgnoreDeprecation);
844
        MesPrint("%%%% END M_const");
845
/*        fflush(0); */
846
}
847

848
static void print_P()
849
{
850
        int i;
851
        MesPrint("%%%% P_const");
852
        print_LIST(&AP.DollarList);
853
        for ( i=0; i<AP.DollarList.num; ++i ) {
854
                print_DOLLARS(&(Dollars[i]));
855
        }
856
        MesPrint("--MARK  1");
857
        print_LIST(&AP.PreVarList);
858
        for ( i=0; i<AP.PreVarList.num; ++i ) {
859
                print_PREVAR(&(PreVar[i]));
860
        }
861
        MesPrint("--MARK  2");
862
        print_LIST(&AP.LoopList);
863
        for ( i=0; i<AP.LoopList.num; ++i ) {
864
                print_DOLOOP(&(DoLoops[i]));
865
        }
866
        MesPrint("--MARK  3");
867
        print_LIST(&AP.ProcList);
868
        for ( i=0; i<AP.ProcList.num; ++i ) {
869
                print_PROCEDURE(&(Procedures[i]));
870
        }
871
        MesPrint("--MARK  4");
872
        for ( i=0; i<=AP.PreSwitchLevel; ++i ) {
873
                print_STR(AP.PreSwitchStrings[i]);
874
        }
875
        MesPrint("%l", AP.preStop-AP.preStart);
876
        if ( AP.preFill ) MesPrint("%l", AP.preFill-AP.preStart);
877
        print_CHARS(AP.preStart, AP.pSize);
878
        MesPrint("%s", AP.procedureExtension);
879
        MesPrint("%s", AP.cprocedureExtension);
880
        print_INTV(AP.PreIfStack, AP.MaxPreIfLevel);
881
        print_INTV(AP.PreSwitchModes, AP.NumPreSwitchStrings+1);
882
        print_INTV(AP.PreTypes, AP.NumPreTypes+1);
883
        MesPrint("%d", AP.PreAssignFlag);
884
        MesPrint("--MARK  5");
885
        MesPrint("%d", AP.PreContinuation);
886
        MesPrint("%l", AP.InOutBuf);
887
        MesPrint("%l", AP.pSize);
888
        MesPrint("%d", AP.PreproFlag);
889
        MesPrint("%d", AP.iBufError);
890
        MesPrint("%d", AP.PreOut);
891
        MesPrint("%d", AP.PreSwitchLevel);
892
        MesPrint("%d", AP.NumPreSwitchStrings);
893
        MesPrint("%d", AP.MaxPreTypes);
894
        MesPrint("--MARK  6");
895
        MesPrint("%d", AP.NumPreTypes);
896
        MesPrint("%d", AP.DelayPrevar);
897
        MesPrint("%d", AP.AllowDelay);
898
        MesPrint("%d", AP.lhdollarerror);
899
        MesPrint("%d", AP.eat);
900
        MesPrint("%d", AP.gNumPre);
901
        MesPrint("%d", AP.PreDebug);
902
        MesPrint("--MARK  7");
903
        MesPrint("%d", AP.DebugFlag);
904
        MesPrint("%d", AP.preError);
905
        MesPrint("%C", 1, &(AP.ComChar));
906
        MesPrint("%C", 1, &(AP.cComChar));
907
        MesPrint("%%%% END P_const");
908
/*        fflush(0); */
909
}
910

911
static void print_C()
912
{
913
        int i;
914
        UBYTE buf[40], *t;
915
        MesPrint("%%%% C_const");
916
        for ( i=0; i<32; ++i ) {
917
                t = buf;
918
                t = NumCopy((WORD)(AC.separators[i].bit_7),t);
919
                t = NumCopy((WORD)(AC.separators[i].bit_6),t);
920
                t = NumCopy((WORD)(AC.separators[i].bit_5),t);
921
                t = NumCopy((WORD)(AC.separators[i].bit_4),t);
922
                t = NumCopy((WORD)(AC.separators[i].bit_3),t);
923
                t = NumCopy((WORD)(AC.separators[i].bit_2),t);
924
                t = NumCopy((WORD)(AC.separators[i].bit_1),t);
925
                t = NumCopy((WORD)(AC.separators[i].bit_0),t);
926
                MesPrint("%s ",buf);
927
        }
928
        print_NAMETREE(AC.dollarnames);
929
        print_NAMETREE(AC.exprnames);
930
        print_NAMETREE(AC.varnames);
931
        MesPrint("--MARK  1");
932
        print_LIST(&AC.ChannelList);
933
        for ( i=0; i<AC.ChannelList.num; ++i ) {
934
                MesPrint("%s %d", channels[i].name, channels[i].handle);
935
        }
936
        MesPrint("--MARK  2");
937
        print_LIST(&AC.DubiousList);
938
        MesPrint("--MARK  3");
939
        print_LIST(&AC.FunctionList);
940
        for ( i=0; i<AC.FunctionList.num; ++i ) {
941
                if ( functions[i].tabl ) {
942

943
                }
944
                MesPrint("%l", functions[i].symminfo);
945
                MesPrint("%l", functions[i].name);
946
                MesPrint("%d", functions[i].namesize);
947
        }
948
        MesPrint("--MARK  4");
949
        print_LIST(&AC.ExpressionList);
950
        print_LIST(&AC.IndexList);
951
        print_LIST(&AC.SetElementList);
952
        print_LIST(&AC.SetList);
953
        MesPrint("--MARK  5");
954
        print_LIST(&AC.SymbolList);
955
        print_LIST(&AC.VectorList);
956
        print_LIST(&AC.PotModDolList);
957
        print_LIST(&AC.ModOptDolList);
958
        print_LIST(&AC.TableBaseList);
959

960
/*
961
        print_LIST(&AC.cbufList);
962
        for ( i=0; i<AC.cbufList.num; ++i ) {
963
                MesPrint("cbufList.num == %d", i);
964
                print_CBUF(cbuf+i);
965
        }
966
        MesPrint("%d", AC.cbufnum);
967
*/
968
        MesPrint("--MARK  6");
969

970
        print_LIST(&AC.AutoSymbolList);
971
        print_LIST(&AC.AutoIndexList);
972
        print_LIST(&AC.AutoVectorList);
973
        print_LIST(&AC.AutoFunctionList);
974

975
        print_NAMETREE(AC.autonames);
976
        MesPrint("--MARK  7");
977

978
        print_LIST(AC.Symbols);
979
        print_LIST(AC.Indices);
980
        print_LIST(AC.Vectors);
981
        print_LIST(AC.Functions);
982
        MesPrint("--MARK  8");
983

984
        print_NAMETREE(*AC.activenames);
985
        
986
        MesPrint("--MARK  9");
987

988
        MesPrint("%d", AC.AutoDeclareFlag);
989

990
        for ( i=0; i<AC.NumStreams; ++i ) {
991
                MesPrint("Stream %d\n", i);
992
                print_STREAM(AC.Streams+i);
993
        }
994
        print_STREAM(AC.CurrentStream);
995
        MesPrint("--MARK 10");
996

997
        print_LONGV(AC.termstack, AC.maxtermlevel);
998
        print_LONGV(AC.termsortstack, AC.maxtermlevel);
999
        print_VOIDP(AC.cmod, AM.MaxTal*4*sizeof(UWORD));
1000
        print_WORDV((WORD *)(AC.cmod), 1);
1001
        print_WORDV((WORD *)(AC.powmod), 1);
1002
        print_WORDV((WORD*)AC.modpowers, 1);
1003
        print_WORDV((WORD*)AC.halfmod, 1);
1004
        MesPrint("--MARK 10-2");
1005
        /*
1006
        print_WORDV(AC.ProtoType, AC.ProtoType[1]);
1007
        print_WORDV(AC.WildC, 1);
1008
        */
1009

1010
        MesPrint("--MARK 11");
1011
        /* IfHeap ... Labels */
1012

1013
        print_CHARS((UBYTE*)AC.tokens, AC.toptokens-AC.tokens);
1014
        MesPrint("%l", AC.endoftokens-AC.tokens);
1015
        print_WORDV(AC.tokenarglevel, AM.MaxParLevel);
1016
        print_WORDV((WORD*)AC.modinverses, ABS(AC.ncmod));
1017
#ifdef WITHPTHREADS
1018
        print_LONGV(AC.inputnumbers, AC.sizepfirstnum+AC.sizepfirstnum*sizeof(WORD)/sizeof(LONG));
1019
        print_WORDV(AC.pfirstnum, 1);
1020
#endif
1021
        MesPrint("--MARK 12");
1022
    print_LONGV(AC.argstack, MAXNEST);
1023
    print_LONGV(AC.insidestack, MAXNEST);
1024
    print_LONGV(AC.inexprstack, MAXNEST);
1025
        MesPrint("%l", AC.iBufferSize);
1026
        MesPrint("%l", AC.TransEname);
1027
        MesPrint("%l", AC.ProcessBucketSize);
1028
        MesPrint("%l", AC.mProcessBucketSize);
1029
        MesPrint("%l", AC.CModule);
1030
        MesPrint("%l", AC.ThreadBucketSize);
1031
        MesPrint("%d", AC.NoShowInput);
1032
        MesPrint("%d", AC.ShortStats);
1033
        MesPrint("%d", AC.compiletype);
1034
        MesPrint("%d", AC.firstconstindex);
1035
        MesPrint("%d", AC.insidefirst);
1036
        MesPrint("%d", AC.minsidefirst);
1037
        MesPrint("%d", AC.wildflag);
1038
        MesPrint("%d", AC.NumLabels);
1039
        MesPrint("%d", AC.MaxLabels);
1040
        MesPrint("--MARK 13");
1041
        MesPrint("%d", AC.lDefDim);
1042
        MesPrint("%d", AC.lDefDim4);
1043
        MesPrint("%d", AC.NumWildcardNames);
1044
        MesPrint("%d", AC.WildcardBufferSize);
1045
        MesPrint("%d", AC.MaxIf);
1046
        MesPrint("%d", AC.NumStreams);
1047
        MesPrint("%d", AC.MaxNumStreams);
1048
        MesPrint("%d", AC.firstctypemessage);
1049
        MesPrint("%d", AC.tablecheck);
1050
        MesPrint("%d", AC.idoption);
1051
        MesPrint("%d", AC.BottomLevel);
1052
        MesPrint("%d", AC.CompileLevel);
1053
        MesPrint("%d", AC.TokensWriteFlag);
1054
        MesPrint("%d", AC.UnsureDollarMode);
1055
        MesPrint("%d", AC.outsidefun);
1056
        MesPrint("%d", AC.funpowers);
1057
        MesPrint("--MARK 14");
1058
        MesPrint("%d", AC.WarnFlag);
1059
        MesPrint("%d", AC.StatsFlag);
1060
        MesPrint("%d", AC.NamesFlag);
1061
        MesPrint("%d", AC.CodesFlag);
1062
        MesPrint("%d", AC.TokensWriteFlag);
1063
        MesPrint("%d", AC.SetupFlag);
1064
        MesPrint("%d", AC.SortType);
1065
        MesPrint("%d", AC.lSortType);
1066
        MesPrint("%d", AC.ThreadStats);
1067
        MesPrint("%d", AC.FinalStats);
1068
        MesPrint("%d", AC.ThreadsFlag);
1069
        MesPrint("%d", AC.ThreadBalancing);
1070
        MesPrint("%d", AC.ThreadSortFileSynch);
1071
        MesPrint("%d", AC.ProcessStats);
1072
        MesPrint("%d", AC.OldParallelStats);
1073
        MesPrint("%d", AC.WTimeStatsFlag);
1074
        MesPrint("%d", AC.BracketNormalize);
1075
        MesPrint("%d", AC.maxtermlevel);
1076
        MesPrint("%d", AC.dumnumflag);
1077
        MesPrint("--MARK 15");
1078
        MesPrint("%d", AC.bracketindexflag);
1079
        MesPrint("%d", AC.parallelflag);
1080
        MesPrint("%d", AC.mparallelflag);
1081
        MesPrint("%d", AC.properorderflag);
1082
        MesPrint("%d", AC.vetofilling);
1083
        MesPrint("%d", AC.tablefilling);
1084
        MesPrint("%d", AC.vetotablebasefill);
1085
        MesPrint("%d", AC.exprfillwarning);
1086
        MesPrint("%d", AC.lhdollarflag);
1087
        MesPrint("%d", AC.NoCompress);
1088
#ifdef WITHPTHREADS
1089
        MesPrint("%d", AC.numpfirstnum);
1090
        MesPrint("%d", AC.sizepfirstnum);
1091
#endif
1092
        MesPrint("%d", AC.RepLevel);
1093
        MesPrint("%d", AC.arglevel);
1094
        MesPrint("%d", AC.insidelevel);
1095
        MesPrint("%d", AC.inexprlevel);
1096
        MesPrint("%d", AC.termlevel);
1097
        MesPrint("--MARK 16");
1098
        print_WORDV(AC.argsumcheck, MAXNEST);
1099
        print_WORDV(AC.insidesumcheck, MAXNEST);
1100
        print_WORDV(AC.inexprsumcheck, MAXNEST);
1101
        MesPrint("%d", AC.MustTestTable);
1102
        MesPrint("%d", AC.DumNum);
1103
        MesPrint("%d", AC.ncmod);
1104
        MesPrint("%d", AC.npowmod);
1105
        MesPrint("%d", AC.modmode);
1106
        MesPrint("%d", AC.nhalfmod);
1107
        MesPrint("%d", AC.DirtPow);
1108
        MesPrint("%d", AC.lUnitTrace);
1109
        MesPrint("%d", AC.NwildC);
1110
        MesPrint("%d", AC.ComDefer);
1111
        MesPrint("%d", AC.CollectFun);
1112
        MesPrint("%d", AC.AltCollectFun);
1113
        MesPrint("--MARK 17");
1114
        MesPrint("%d", AC.OutputMode);
1115
        MesPrint("%d", AC.Cnumpows);
1116
        MesPrint("%d", AC.OutputSpaces);
1117
        MesPrint("%d", AC.OutNumberType);
1118
        print_WORDV(AC.lUniTrace, 4);
1119
        print_WORDV(AC.RepSumCheck, MAXREPEAT);
1120
        MesPrint("%d", AC.DidClean);
1121
        MesPrint("%d", AC.IfLevel);
1122
        MesPrint("%d", AC.WhileLevel);
1123
        print_WORDV(AC.IfSumCheck, (AC.MaxIf+1));
1124
        MesPrint("%d", AC.LogHandle);
1125
        MesPrint("%d", AC.LineLength);
1126
        MesPrint("%d", AC.StoreHandle);
1127
        MesPrint("%d", AC.HideLevel);
1128
        MesPrint("%d", AC.lPolyFun);
1129
        MesPrint("%d", AC.lPolyFunInv);
1130
        MesPrint("%d", AC.lPolyFunType);
1131
        MesPrint("%d", AC.lPolyFunExp);
1132
        MesPrint("%d", AC.lPolyFunVar);
1133
        MesPrint("%d", AC.lPolyFunPow);
1134
        MesPrint("%d", AC.SymChangeFlag);
1135
        MesPrint("%d", AC.CollectPercentage);
1136
        MesPrint("%d", AC.ShortStatsMax);
1137
        MesPrint("--MARK 18");
1138

1139
        print_CHARS(AC.Commercial, COMMERCIALSIZE+2);
1140

1141
        MesPrint("%", AC.CheckpointFlag);
1142
        MesPrint("%l", AC.CheckpointStamp);
1143
        print_STR((unsigned char*)AC.CheckpointRunAfter);
1144
        print_STR((unsigned char*)AC.CheckpointRunBefore);
1145
        MesPrint("%l", AC.CheckpointInterval);
1146

1147
        MesPrint("%%%% END C_const");
1148
/*        fflush(0); */
1149
}
1150

1151
static void print_R()
1152
{
1153
        GETIDENTITY
1154
        int i;
1155
        MesPrint("%%%% R_const");
1156
        MesPrint("%l", (LONG)(AR.infile-AR.Fscr));
1157
        MesPrint("%s", AR.infile->name);
1158
        MesPrint("%l", (LONG)(AR.outfile-AR.Fscr));
1159
        MesPrint("%s", AR.outfile->name);
1160
        MesPrint("%l", AR.hidefile-AR.Fscr);
1161
        MesPrint("%s", AR.hidefile->name);
1162
        for ( i=0; i<3; ++i ) {
1163
                MesPrint("FSCR %d", i);
1164
                print_WORDB(AR.Fscr[i].PObuffer, AR.Fscr[i].POfull);
1165
        }
1166
        /* ... */
1167
        MesPrint("%l", AR.OldTime);
1168
        MesPrint("%l", AR.InInBuf);
1169
        MesPrint("%l", AR.InHiBuf);
1170
        MesPrint("%l", AR.pWorkSize);
1171
        MesPrint("%l", AR.lWorkSize);
1172
        MesPrint("%l", AR.posWorkSize);
1173
        MesPrint("%d", AR.NoCompress);
1174
        MesPrint("%d", AR.gzipCompress);
1175
        MesPrint("%d", AR.Cnumlhs);
1176
#ifdef WITHPTHREADS
1177
        MesPrint("%d", AR.exprtodo);
1178
#endif
1179
        MesPrint("%d", AR.GetFile);
1180
        MesPrint("%d", AR.KeptInHold);
1181
        MesPrint("%d", AR.BracketOn);
1182
        MesPrint("%d", AR.MaxBracket);
1183
        MesPrint("%d", AR.CurDum);
1184
        MesPrint("%d", AR.DeferFlag);
1185
        MesPrint("%d", AR.TePos);
1186
        MesPrint("%d", AR.sLevel);
1187
        MesPrint("%d", AR.Stage4Name);
1188
        MesPrint("%d", AR.GetOneFile);
1189
        MesPrint("%d", AR.PolyFun);
1190
        MesPrint("%d", AR.PolyFunInv);
1191
        MesPrint("%d", AR.PolyFunType);
1192
        MesPrint("%d", AR.PolyFunExp);
1193
        MesPrint("%d", AR.PolyFunVar);
1194
        MesPrint("%d", AR.PolyFunPow);
1195
        MesPrint("%d", AR.Eside);
1196
        MesPrint("%d", AR.MaxDum);
1197
        MesPrint("%d", AR.level);
1198
        MesPrint("%d", AR.expchanged);
1199
        MesPrint("%d", AR.expflags);
1200
        MesPrint("%d", AR.CurExpr);
1201
        MesPrint("%d", AR.SortType);
1202
        MesPrint("%d", AR.ShortSortCount);
1203
        MesPrint("%%%% END R_const");
1204
/*        fflush(0); */
1205
}
1206

1207
#endif /* ifdef PRINTDEBUG */
1208

1209
/*
1210
          #] Debugging : 
1211
          #[ Cached file operation functions :
1212
*/
1213

1214
#define CACHED_SNAPSHOT
1215

1216
#define CACHE_SIZE 4096
1217

1218
#ifdef CACHED_SNAPSHOT
1219
unsigned char cache_buffer[CACHE_SIZE];
1220
size_t cache_fill = 0;
1221

1222
size_t fwrite_cached(const void *ptr, size_t size, size_t nmemb, FILE *fd)
×
1223
{
1224
        size_t fullsize = size*nmemb;
×
1225
        if ( fullsize+cache_fill >= CACHE_SIZE ) {
×
1226
                size_t overlap = CACHE_SIZE-cache_fill;
×
1227
                memcpy(cache_buffer+cache_fill, (unsigned char*)ptr, overlap);
×
1228
                if ( fwrite(cache_buffer, 1, CACHE_SIZE, fd) != CACHE_SIZE ) return 0;
×
1229
                fullsize -= overlap;
×
1230
                if ( fullsize >= CACHE_SIZE ) {
×
1231
                        cache_fill = fullsize % CACHE_SIZE;
×
1232
                        if ( cache_fill ) memcpy(cache_buffer, (unsigned char*)ptr+overlap+fullsize-cache_fill, cache_fill);
×
1233
                        if ( fwrite((unsigned char*)ptr+overlap, 1, fullsize-cache_fill, fd) != fullsize-cache_fill ) return 0;
×
1234
                }
1235
                else {
1236
                        memcpy(cache_buffer, (unsigned char*)ptr+overlap, fullsize);
×
1237
                        cache_fill = fullsize;
×
1238
                }
1239
        }
1240
        else {
1241
                memcpy(cache_buffer+cache_fill, (unsigned char*)ptr, fullsize);
×
1242
                cache_fill += fullsize;
×
1243
        }
1244
        return nmemb;
1245
}
1246

1247
size_t flush_cache(FILE *fd)
×
1248
{
1249
        if ( cache_fill ) {
×
1250
                size_t retval = fwrite(cache_buffer, 1, cache_fill, fd);
×
1251
                if ( retval != cache_fill ) {
×
1252
                         cache_fill = 0;
×
1253
                        return 0;
×
1254
                }
1255
                 cache_fill = 0;
×
1256
        }
1257
        return 1;
1258
}
1259
#else
1260
size_t fwrite_cached(const void *ptr, size_t size, size_t nmemb, FILE *fd)
1261
{
1262
        return fwrite(ptr, size, nmemb, fd);
1263
}
1264

1265
size_t flush_cache(FILE *fd)
1266
{
1267
        DUMMYUSE(fd)
1268
        return 1;
1269
}
1270
#endif
1271

1272
/*
1273
          #] Cached file operation functions : 
1274
          #[ Helper Macros :
1275
*/
1276

1277
/* some helper macros to streamline the code in DoSnapshot() and DoRecovery() */
1278

1279
/* freeing memory */
1280

1281
#define R_FREE(ARG) \
1282
        if ( ARG ) M_free(ARG, #ARG);
1283

1284
#define R_FREE_NAMETREE(ARG) \
1285
        R_FREE(ARG->namenode); \
1286
        R_FREE(ARG->namebuffer); \
1287
        R_FREE(ARG);
1288

1289
#define R_FREE_STREAM(ARG) \
1290
        R_FREE(ARG.buffer); \
1291
        R_FREE(ARG.FoldName); \
1292
        R_FREE(ARG.name);
1293

1294
/* reading a single variable */
1295

1296
#define R_SET(VAR,TYPE) \
1297
        VAR = *((TYPE*)p); p = (unsigned char*)p + sizeof(TYPE);
1298

1299
/* general buffer */
1300

1301
#define R_COPY_B(VAR,SIZE,CAST) \
1302
        VAR = (CAST)Malloc1(SIZE,#VAR); \
1303
        memcpy(VAR, p, SIZE); p = (unsigned char*)p + SIZE;
1304

1305
#define S_WRITE_B(BUF,LEN) \
1306
        if ( fwrite_cached(BUF, 1, LEN, fd) != (size_t)(LEN) ) return(__LINE__);
1307

1308
#define S_FLUSH_B \
1309
        if ( flush_cache(fd) != 1 ) return(__LINE__);
1310

1311
/* character strings */
1312

1313
#define R_COPY_S(VAR,CAST) \
1314
        if ( VAR ) { \
1315
                VAR = (CAST)Malloc1(strlen(p)+1,"R_COPY_S"); \
1316
                strcpy((char*)VAR, p); p = (unsigned char*)p + strlen(p) + 1; \
1317
        }
1318

1319
#define S_WRITE_S(STR) \
1320
        if ( STR ) { \
1321
                l = strlen((char*)STR) + 1; \
1322
                if ( fwrite_cached(STR, 1, l, fd) != (size_t)l ) return(__LINE__); \
1323
        }
1324

1325
/* LIST */
1326

1327
#define R_COPY_LIST(ARG) \
1328
        if ( ARG.maxnum ) { \
1329
                R_COPY_B(ARG.lijst, ARG.size*ARG.maxnum, void*) \
1330
        }
1331

1332
#define S_WRITE_LIST(LST) \
1333
        if ( LST.maxnum ) { \
1334
                S_WRITE_B((char*)LST.lijst, LST.maxnum*LST.size) \
1335
        }
1336

1337
/* NAMETREE */
1338

1339
#define R_COPY_NAMETREE(ARG) \
1340
        R_COPY_B(ARG, sizeof(NAMETREE), NAMETREE*); \
1341
        if ( ARG->namenode ) { \
1342
                R_COPY_B(ARG->namenode, ARG->nodesize*sizeof(NAMENODE), NAMENODE*); \
1343
        } \
1344
        if ( ARG->namebuffer ) { \
1345
                R_COPY_B(ARG->namebuffer, ARG->namesize, UBYTE*); \
1346
        }
1347

1348
#define S_WRITE_NAMETREE(ARG) \
1349
        S_WRITE_B(ARG, sizeof(NAMETREE)); \
1350
        if ( ARG->namenode ) { \
1351
                S_WRITE_B(ARG->namenode, ARG->nodesize*sizeof(struct NaMeNode)); \
1352
        } \
1353
        if ( ARG->namebuffer ) { \
1354
                S_WRITE_B(ARG->namebuffer, ARG->namesize); \
1355
        }
1356

1357
/* DOLLAR */
1358

1359
#define S_WRITE_DOLLAR(ARG) \
1360
        if ( ARG.size && ARG.where && ARG.where != &(AM.dollarzero) ) { \
1361
                S_WRITE_B(ARG.where, ARG.size*sizeof(WORD)) \
1362
        }
1363

1364
/* Printing time marks with ANNOUNCE macro */
1365

1366
#ifdef PRINTTIMEMARKS
1367
time_t announce_time;
1368
#define ANNOUNCE(str) time(&announce_time); MesPrint("TIMEMARK %s  %s", ctime(&announce_time), #str);
1369
#else
1370
#define ANNOUNCE(str)
1371
#endif
1372

1373
/*
1374
          #] Helper Macros : 
1375
          #[ DoRecovery :
1376
*/
1377

1378
/**
1379
 *  Reads from the recovery file and restores all necessary variables and
1380
 *  states in FORM, so that the execution can recommence in preprocessor() as
1381
 *  if no restart of FORM had occurred.
1382
 *
1383
 *  The recovery file is read into memory as a whole. The pointer p then points
1384
 *  into this memory at the next non-processed data. The macros by which
1385
 *  variables are restored, like R_SET, automatically increase p appropriately.
1386
 *
1387
 *  If something goes wrong, the function returns with a non-zero value.
1388
 *
1389
 *  Allocated memory that would be lost when overwriting the global structs with
1390
 *  data from the file is freed first. A major part of the code deals with the
1391
 *  restoration of pointers. The idiom we use is to memorize the original
1392
 *  pointer value (org), allocate new memory and copy the data from the file
1393
 *  into this memory, calculate the offset between the old pointer value
1394
 *  and the new allocated memory position (ofs), and then correct all affected
1395
 *  pointers (+=ofs).
1396
 *
1397
 *  We rely on the fact that several variables (especially in AM) are already
1398
 *  assigned the correct values by the startup functions. That means, in
1399
 *  principle, that a change in the setup files between snapshot creation and
1400
 *  recovery will be noticed.
1401
 */
1402
int DoRecovery(int *moduletype)
×
1403
{
1404
        GETIDENTITY
1405
        FILE *fd;
×
1406
        POSITION pos;
×
1407
        void *buf, *p;
×
1408
        LONG size, l;
×
1409
        int i, j;
×
1410
        UBYTE *org;
×
1411
        char *namebufout, *namebufhide;
×
1412
        LONG ofs;
×
1413
        void *oldAMdollarzero;
×
1414
        LIST PotModDolListBackup;
×
1415
        LIST ModOptDolListBackup;
×
1416
        WORD oldLogHandle;
×
1417

1418
        MesPrint("Recovering ... %"); fflush(0);
×
1419

1420
        if ( !(fd = fopen(recoveryfile, "r")) ) return(__LINE__);
×
1421

1422
        /* load the complete recovery file into a buffer */
1423
        if ( fread(&pos, sizeof(POSITION), 1, fd) != 1 ) return(__LINE__);
×
1424
        size = BASEPOSITION(pos) - sizeof(POSITION);
×
1425
        buf = Malloc1(size, "recovery buffer");
×
1426
        if ( fread(buf, size, 1, fd) != 1 ) return(__LINE__);
×
1427

1428
        /* pointer p will go through the buffer in the following */
1429
        p = buf;
×
1430

1431
        /* read moduletype */
1432
        R_SET(*moduletype, int);
×
1433

1434
        /*#[ AM : */
1435

1436
        /* only certain elements will be restored. the rest of AM should have gotten
1437
         * the correct values at startup. */
1438

1439
        R_SET(AM.hparallelflag, int);
×
1440
        R_SET(AM.gparallelflag, int);
×
1441
        R_SET(AM.gCodesFlag, int);
×
1442
        R_SET(AM.gNamesFlag, int);
×
1443
        R_SET(AM.gStatsFlag, int);
×
1444
        R_SET(AM.gTokensWriteFlag, int);
×
1445
        R_SET(AM.gNoSpacesInNumbers, int);
×
1446
        R_SET(AM.gIndentSpace, WORD);
×
1447
        R_SET(AM.gUnitTrace, WORD);
×
1448
        R_SET(AM.gDefDim, int);
×
1449
        R_SET(AM.gDefDim4, int);
×
1450
        R_SET(AM.gncmod, WORD);
×
1451
        R_SET(AM.gnpowmod, WORD);
×
1452
        R_SET(AM.gmodmode, WORD);
×
1453
        R_SET(AM.gOutputMode, WORD);
×
1454
        R_SET(AM.gCnumpows, WORD);
×
1455
        R_SET(AM.gOutputSpaces, WORD);
×
1456
        R_SET(AM.gOutNumberType, WORD);
×
1457
        R_SET(AM.gfunpowers, int);
×
1458
        R_SET(AM.gPolyFun, WORD);
×
1459
        R_SET(AM.gPolyFunInv, WORD);
×
1460
        R_SET(AM.gPolyFunType, WORD);
×
1461
        R_SET(AM.gPolyFunExp, WORD);
×
1462
        R_SET(AM.gPolyFunVar, WORD);
×
1463
        R_SET(AM.gPolyFunPow, WORD);
×
1464
        R_SET(AM.gProcessBucketSize, LONG);
×
1465
        R_SET(AM.OldChildTime, LONG);
×
1466
        R_SET(AM.OldSecTime, LONG);
×
1467
        R_SET(AM.OldMilliTime, LONG);
×
1468
        R_SET(AM.gproperorderflag, int);
×
1469
        R_SET(AM.gThreadBucketSize, LONG);
×
1470
        R_SET(AM.gSizeCommuteInSet, int);
×
1471
        R_SET(AM.gThreadStats, int);
×
1472
        R_SET(AM.gFinalStats, int);
×
1473
        R_SET(AM.gThreadsFlag, int);
×
1474
        R_SET(AM.gThreadBalancing, int);
×
1475
        R_SET(AM.gThreadSortFileSynch, int);
×
1476
        R_SET(AM.gProcessStats, int);
×
1477
        R_SET(AM.gOldParallelStats, int);
×
1478
        R_SET(AM.gSortType, int);
×
1479
        R_SET(AM.gShortStatsMax, WORD);
×
1480
        R_SET(AM.gIsFortran90, int);
×
1481
        R_SET(oldAMdollarzero, void*);
×
1482
        R_FREE(AM.gFortran90Kind);
×
1483
        R_SET(AM.gFortran90Kind,UBYTE *);
×
1484
        R_COPY_S(AM.gFortran90Kind,UBYTE *);
×
1485

1486
        R_COPY_S(AM.gextrasym,UBYTE *);
×
1487
        R_COPY_S(AM.ggextrasym,UBYTE *);
×
1488

1489
        R_SET(AM.PrintTotalSize,int);
×
1490
        R_SET(AM.fbuffersize,int);
×
1491
        R_SET(AM.gOldFactArgFlag,int);
×
1492
        R_SET(AM.ggOldFactArgFlag,int);
×
1493

1494
    R_SET(AM.gnumextrasym,int);
×
1495
    R_SET(AM.ggnumextrasym,int);
×
1496
        R_SET(AM.NumSpectatorFiles,int);
×
1497
        R_SET(AM.SizeForSpectatorFiles,int);
×
1498
    R_SET(AM.gOldGCDflag,int);
×
1499
    R_SET(AM.ggOldGCDflag,int);
×
1500
        R_SET(AM.gWTimeStatsFlag, int);
×
1501

1502
        R_FREE(AM.Path);
×
1503
        R_SET(AM.Path,UBYTE *);
×
1504
        R_COPY_S(AM.Path,UBYTE *);
×
1505

1506
        R_SET(AM.FromStdin, BOOL);
×
1507
        R_SET(AM.IgnoreDeprecation, BOOL);
×
1508

1509
#ifdef PRINTDEBUG
1510
        print_M();
1511
#endif
1512

1513
        /*#] AM : */ 
1514
        /*#[ AC : */
1515

1516
        /* #[ AC free pointers */
1517

1518
        /* AC will be overwritten by data from the recovery file, therefore
1519
         * dynamically allocated memory must be freed first. */
1520

1521
        R_FREE_NAMETREE(AC.dollarnames);
×
1522
        R_FREE_NAMETREE(AC.exprnames);
×
1523
        R_FREE_NAMETREE(AC.varnames);
×
1524
        for ( i=0; i<AC.ChannelList.num; ++i ) {
×
1525
                R_FREE(channels[i].name);
×
1526
        }
1527
        R_FREE(AC.ChannelList.lijst);
×
1528
        R_FREE(AC.DubiousList.lijst);
×
1529
        for ( i=0; i<AC.FunctionList.num; ++i ) {
×
1530
                TABLES T = functions[i].tabl;
×
1531
                if ( T ) {
×
1532
                        R_FREE(T->buffers);
×
1533
                        R_FREE(T->mm);
×
1534
                        R_FREE(T->flags);
×
1535
                        R_FREE(T->prototype);
×
1536
                        R_FREE(T->tablepointers);
×
1537
                        if ( T->sparse ) {
×
1538
                                R_FREE(T->boomlijst);
×
1539
                                R_FREE(T->argtail);
×
1540
                        }
1541
                        if ( T->spare ) {
×
1542
                                R_FREE(T->spare->buffers);
×
1543
                                R_FREE(T->spare->mm);
×
1544
                                R_FREE(T->spare->flags);
×
1545
                                R_FREE(T->spare->tablepointers);
×
1546
                                if ( T->spare->sparse ) {
×
1547
                                        R_FREE(T->spare->boomlijst);
×
1548
                                }
1549
                                R_FREE(T->spare);
×
1550
                        }
1551
                        R_FREE(T);
×
1552
                }
1553
        }
1554
        R_FREE(AC.FunctionList.lijst);
×
1555
        for ( i=0; i<AC.ExpressionList.num; ++i ) {
×
1556
                if ( Expressions[i].renum ) {
×
1557
                        R_FREE(Expressions[i].renum->symb.lo);
×
1558
                        R_FREE(Expressions[i].renum);
×
1559
                }
1560
                if ( Expressions[i].bracketinfo ) {
×
1561
                        R_FREE(Expressions[i].bracketinfo->indexbuffer);
×
1562
                        R_FREE(Expressions[i].bracketinfo->bracketbuffer);
×
1563
                        R_FREE(Expressions[i].bracketinfo);
×
1564
                }
1565
                if ( Expressions[i].newbracketinfo ) {
×
1566
                        R_FREE(Expressions[i].newbracketinfo->indexbuffer);
×
1567
                        R_FREE(Expressions[i].newbracketinfo->bracketbuffer);
×
1568
                        R_FREE(Expressions[i].newbracketinfo);
×
1569
                }
1570
                if ( Expressions[i].renumlists != AN.dummyrenumlist ) { 
×
1571
                        R_FREE(Expressions[i].renumlists);
×
1572
                }
1573
                R_FREE(Expressions[i].inmem);
×
1574
        }
1575
        R_FREE(AC.ExpressionList.lijst);
×
1576
        R_FREE(AC.IndexList.lijst);
×
1577
        R_FREE(AC.SetElementList.lijst);
×
1578
        R_FREE(AC.SetList.lijst);
×
1579
        R_FREE(AC.SymbolList.lijst);
×
1580
        R_FREE(AC.VectorList.lijst);
×
1581
        for ( i=0; i<AC.TableBaseList.num; ++i ) {
×
1582
                R_FREE(tablebases[i].iblocks);
×
1583
                R_FREE(tablebases[i].nblocks);
×
1584
                R_FREE(tablebases[i].name);
×
1585
                R_FREE(tablebases[i].fullname);
×
1586
                R_FREE(tablebases[i].tablenames);
×
1587
        }
1588
        R_FREE(AC.TableBaseList.lijst);
×
1589
        for ( i=0; i<AC.cbufList.num; ++i ) {
×
1590
                R_FREE(cbuf[i].Buffer);
×
1591
                R_FREE(cbuf[i].lhs);
×
1592
                R_FREE(cbuf[i].rhs);
×
1593
                R_FREE(cbuf[i].boomlijst);
×
1594
        }
1595
        R_FREE(AC.cbufList.lijst);
×
1596
        R_FREE(AC.AutoSymbolList.lijst);
×
1597
        R_FREE(AC.AutoIndexList.lijst);
×
1598
        R_FREE(AC.AutoVectorList.lijst);
×
1599
        /* Tables cannot be auto-declared, therefore no extra code here */
1600
        R_FREE(AC.AutoFunctionList.lijst);
×
1601
        R_FREE_NAMETREE(AC.autonames);
×
1602
        for ( i=0; i<AC.NumStreams; ++i ) {
×
1603
                R_FREE_STREAM(AC.Streams[i]);
×
1604
        }
1605
        R_FREE(AC.Streams);
×
1606
        R_FREE(AC.termstack);
×
1607
        R_FREE(AC.termsortstack);
×
1608
        R_FREE(AC.cmod);
×
1609
        R_FREE(AC.modpowers);
×
1610
        R_FREE(AC.halfmod);
×
1611
        R_FREE(AC.IfHeap);
×
1612
        R_FREE(AC.IfCount);
×
1613
        R_FREE(AC.iBuffer);
×
1614
        for ( i=0; i<AC.NumLabels; ++i ) {
×
1615
                R_FREE(AC.LabelNames[i]);
×
1616
        }
1617
        R_FREE(AC.LabelNames);
×
1618
        R_FREE(AC.FixIndices);
×
1619
        R_FREE(AC.termsumcheck);
×
1620
        R_FREE(AC.WildcardNames);
×
1621
        R_FREE(AC.tokens);
×
1622
        R_FREE(AC.tokenarglevel);
×
1623
        R_FREE(AC.modinverses);
×
1624
        R_FREE(AC.Fortran90Kind);
×
1625
#ifdef WITHPTHREADS
1626
        R_FREE(AC.inputnumbers);
1627
#endif
1628
        R_FREE(AC.IfSumCheck);
×
1629
        R_FREE(AC.CommuteInSet);
×
1630
        R_FREE(AC.CheckpointRunAfter);
×
1631
        R_FREE(AC.CheckpointRunBefore);
×
1632

1633
        /* #] AC free pointers */
1634

1635
        /* backup some lists in order to restore it to the initial setup */
1636
        PotModDolListBackup = AC.PotModDolList;
×
1637
        ModOptDolListBackup = AC.ModOptDolList;
×
1638
        oldLogHandle = AC.LogHandle;
×
1639

1640
        /* first we copy AC as a whole and then restore the pointer structures step
1641
           by step. */
1642

1643
        AC = *((struct C_const*)p); p = (unsigned char*)p + sizeof(struct C_const);
×
1644
        
1645
        R_COPY_NAMETREE(AC.dollarnames);
×
1646
        R_COPY_NAMETREE(AC.exprnames);
×
1647
        R_COPY_NAMETREE(AC.varnames);
×
1648

1649
        R_COPY_LIST(AC.ChannelList);
×
1650
        for ( i=0; i<AC.ChannelList.num; ++i ) {
×
1651
                R_COPY_S(channels[i].name,char*);
×
1652
                channels[i].handle = ReOpenFile(channels[i].name);
×
1653
        }
1654
        AC.ChannelList.message = "channel buffer";
×
1655

1656
        AC.DubiousList.lijst = 0;
×
1657
        AC.DubiousList.message = "ambiguous variable";
×
1658
        AC.DubiousList.num =
×
1659
        AC.DubiousList.maxnum =
×
1660
        AC.DubiousList.numglobal =
×
1661
        AC.DubiousList.numtemp =
×
1662
        AC.DubiousList.numclear = 0;
×
1663

1664
        R_COPY_LIST(AC.FunctionList);
×
1665
        for ( i=0; i<AC.FunctionList.num; ++i ) {
×
1666
                if ( functions[i].tabl ) {
×
1667
                        TABLES tabl;
×
1668
                        R_COPY_B(tabl, sizeof(struct TaBlEs), TABLES);
×
1669
                        functions[i].tabl = tabl;
×
1670
                        if ( tabl->tablepointers ) {
×
1671
                                if ( tabl->sparse ) {
×
1672
                                        R_COPY_B(tabl->tablepointers,
×
1673
                                                tabl->reserved*sizeof(WORD)*(tabl->numind+TABLEEXTENSION),
1674
                                                WORD*);
×
1675
                                }
1676
                                else {
1677
                                        R_COPY_B(tabl->tablepointers, 
×
1678
                                                TABLEEXTENSION*sizeof(WORD)*(tabl->totind), WORD*);
×
1679
                                }
1680
                        }
1681
                        org = (UBYTE*)tabl->prototype;
×
1682
#ifdef WITHPTHREADS
1683
                        R_COPY_B(tabl->prototype, tabl->prototypeSize, WORD**);
1684
                        ofs = (UBYTE*)tabl->prototype - org;
1685
                        for ( j=0; j<AM.totalnumberofthreads; ++j ) {
1686
                                if ( tabl->prototype[j] ) {
1687
                                        tabl->prototype[j] = (WORD*)((UBYTE*)tabl->prototype[j] + ofs);
1688
                                }
1689
                        }
1690
                        if ( tabl->pattern ) {
1691
                                tabl->pattern = (WORD**)((UBYTE*)tabl->pattern + ofs);
1692
                                for ( j=0; j<AM.totalnumberofthreads; ++j ) {
1693
                                        if ( tabl->pattern[j] ) {
1694
                                                tabl->pattern[j] = (WORD*)((UBYTE*)tabl->pattern[j] + ofs);
1695
                                        }
1696
                                }
1697
                        }
1698
#else
1699
                        ofs = tabl->pattern - tabl->prototype;
1700
                        R_COPY_B(tabl->prototype, tabl->prototypeSize, WORD*);
1701
                        if ( tabl->pattern ) {
1702
                                tabl->pattern = tabl->prototype + ofs;
1703
                        }
1704
#endif
1705
                        R_COPY_B(tabl->mm, tabl->numind*(LONG)sizeof(MINMAX), MINMAX*);
×
1706
                        R_COPY_B(tabl->flags, tabl->numind*(LONG)sizeof(WORD), WORD*);
×
1707
                        if ( tabl->sparse ) {
×
1708
                                R_COPY_B(tabl->boomlijst, tabl->MaxTreeSize*(LONG)sizeof(COMPTREE), COMPTREE*);
×
1709
                                R_COPY_S(tabl->argtail,UBYTE*);
×
1710
                        }
1711
                        R_COPY_B(tabl->buffers, tabl->bufferssize*(LONG)sizeof(WORD), WORD*);
×
1712
                        if ( tabl->spare ) {
×
1713
                                TABLES spare;
×
1714
                                R_COPY_B(spare, sizeof(struct TaBlEs), TABLES);
×
1715
                                tabl->spare = spare;
×
1716
                                if ( spare->tablepointers ) {
×
1717
                                        if ( spare->sparse ) {
×
1718
                                                R_COPY_B(spare->tablepointers,
×
1719
                                                        spare->reserved*sizeof(WORD)*(spare->numind+TABLEEXTENSION),
1720
                                                        WORD*);
×
1721
                                        }
1722
                                        else {
1723
                                                R_COPY_B(spare->tablepointers,
×
1724
                                                        TABLEEXTENSION*sizeof(WORD)*(spare->totind), WORD*);
×
1725
                                        }
1726
                                }
1727
                                spare->prototype = tabl->prototype;
×
1728
                                spare->pattern = tabl->pattern;
×
1729
                                R_COPY_B(spare->mm, spare->numind*(LONG)sizeof(MINMAX), MINMAX*);
×
1730
                                R_COPY_B(spare->flags, spare->numind*(LONG)sizeof(WORD), WORD*);
×
1731
                                if ( tabl->sparse ) {
×
1732
                                        R_COPY_B(spare->boomlijst, spare->MaxTreeSize*(LONG)sizeof(COMPTREE), COMPTREE*);
×
1733
                                        spare->argtail = tabl->argtail;
×
1734
                                }
1735
                                spare->spare = tabl;
×
1736
                                R_COPY_B(spare->buffers, spare->bufferssize*(LONG)sizeof(WORD), WORD*);
×
1737
                        }
1738
                }
1739
        }
1740
        AC.FunctionList.message = "function";
×
1741

1742
        R_COPY_LIST(AC.ExpressionList);
×
1743
        for ( i=0; i<AC.ExpressionList.num; ++i ) {
×
1744
                EXPRESSIONS ex = Expressions + i;
×
1745
                if ( ex->renum ) {
×
1746
                        R_COPY_B(ex->renum, sizeof(struct ReNuMbEr), RENUMBER);
×
1747
                        org = (UBYTE*)ex->renum->symb.lo;
×
1748
                        R_SET(size, size_t);
×
1749
                        R_COPY_B(ex->renum->symb.lo, size, WORD*);
×
1750
                        ofs = (UBYTE*)ex->renum->symb.lo - org;
×
1751
                        ex->renum->symb.start = (WORD*)((UBYTE*)ex->renum->symb.start + ofs);
×
1752
                        ex->renum->symb.hi = (WORD*)((UBYTE*)ex->renum->symb.hi + ofs);
×
1753
                        ex->renum->indi.lo = (WORD*)((UBYTE*)ex->renum->indi.lo + ofs);
×
1754
                        ex->renum->indi.start = (WORD*)((UBYTE*)ex->renum->indi.start + ofs);
×
1755
                        ex->renum->indi.hi = (WORD*)((UBYTE*)ex->renum->indi.hi + ofs);
×
1756
                        ex->renum->vect.lo = (WORD*)((UBYTE*)ex->renum->vect.lo + ofs);
×
1757
                        ex->renum->vect.start = (WORD*)((UBYTE*)ex->renum->vect.start + ofs);
×
1758
                        ex->renum->vect.hi = (WORD*)((UBYTE*)ex->renum->vect.hi + ofs);
×
1759
                        ex->renum->func.lo = (WORD*)((UBYTE*)ex->renum->func.lo + ofs);
×
1760
                        ex->renum->func.start = (WORD*)((UBYTE*)ex->renum->func.start + ofs);
×
1761
                        ex->renum->func.hi = (WORD*)((UBYTE*)ex->renum->func.hi + ofs);
×
1762
                        ex->renum->symnum = (WORD*)((UBYTE*)ex->renum->symnum + ofs);
×
1763
                        ex->renum->indnum = (WORD*)((UBYTE*)ex->renum->indnum + ofs);
×
1764
                        ex->renum->vecnum = (WORD*)((UBYTE*)ex->renum->vecnum + ofs);
×
1765
                        ex->renum->funnum = (WORD*)((UBYTE*)ex->renum->funnum + ofs);
×
1766
                }
1767
                if ( ex->bracketinfo ) {
×
1768
                        R_COPY_B(ex->bracketinfo, sizeof(BRACKETINFO), BRACKETINFO*);
×
1769
                        R_COPY_B(ex->bracketinfo->indexbuffer, ex->bracketinfo->indexbuffersize*sizeof(BRACKETINDEX), BRACKETINDEX*);
×
1770
                        R_COPY_B(ex->bracketinfo->bracketbuffer, ex->bracketinfo->bracketbuffersize*sizeof(WORD), WORD*);
×
1771
                }
1772
                if ( ex->newbracketinfo ) {
×
1773
                        R_COPY_B(ex->newbracketinfo, sizeof(BRACKETINFO), BRACKETINFO*);
×
1774
                        R_COPY_B(ex->newbracketinfo->indexbuffer, ex->newbracketinfo->indexbuffersize*sizeof(BRACKETINDEX), BRACKETINDEX*);
×
1775
                        R_COPY_B(ex->newbracketinfo->bracketbuffer, ex->newbracketinfo->bracketbuffersize*sizeof(WORD), WORD*);
×
1776
                }
1777
#ifdef WITHPTHREADS
1778
                ex->renumlists = 0;
1779
#else
1780
                ex->renumlists = AN.dummyrenumlist;
1781
#endif
1782
                if ( ex->inmem ) {
×
1783
                        R_SET(size, size_t);
×
1784
                        R_COPY_B(ex->inmem, size, WORD*);
×
1785
                }
1786
        }
1787
        AC.ExpressionList.message = "expression";
×
1788

1789
        R_COPY_LIST(AC.IndexList);
×
1790
        AC.IndexList.message = "index";
×
1791
        R_COPY_LIST(AC.SetElementList);
×
1792
        AC.SetElementList.message = "set element";
×
1793
        R_COPY_LIST(AC.SetList);
×
1794
        AC.SetList.message = "set";
×
1795
        R_COPY_LIST(AC.SymbolList);
×
1796
        AC.SymbolList.message = "symbol";
×
1797
        R_COPY_LIST(AC.VectorList);
×
1798
        AC.VectorList.message = "vector";
×
1799

1800
        AC.PotModDolList = PotModDolListBackup;
×
1801
        AC.ModOptDolList = ModOptDolListBackup;
×
1802

1803
        R_COPY_LIST(AC.TableBaseList);
×
1804
        for ( i=0; i<AC.TableBaseList.num; ++i ) {
×
1805
                if ( tablebases[i].iblocks ) {
×
1806
                        R_COPY_B(tablebases[i].iblocks, tablebases[i].info.numberofindexblocks*sizeof(INDEXBLOCK*),INDEXBLOCK**);
×
1807
                        for ( j=0; j<tablebases[i].info.numberofindexblocks; ++j ) {
×
1808
                                if ( tablebases[i].iblocks[j] ) {
×
1809
                                        R_COPY_B(tablebases[i].iblocks[j], sizeof(INDEXBLOCK), INDEXBLOCK*);
×
1810
                                }
1811
                        }
1812
                }
1813
                if ( tablebases[i].nblocks ) {
×
1814
                        R_COPY_B(tablebases[i].nblocks, tablebases[i].info.numberofnamesblocks*sizeof(NAMESBLOCK*),NAMESBLOCK**);
×
1815
                        for ( j=0; j<tablebases[i].info.numberofindexblocks; ++j ) {
×
1816
                                if ( tablebases[i].nblocks[j] ) {
×
1817
                                        R_COPY_B(tablebases[i].nblocks[j], sizeof(NAMESBLOCK), NAMESBLOCK*);
×
1818
                                }
1819
                        }
1820
                }
1821
                /* reopen file */
1822
                if ( ( tablebases[i].handle = fopen(tablebases[i].fullname, "r+b") ) == NULL ) {
×
1823
                        MesPrint("ERROR: Could not reopen tablebase %s!",tablebases[i].name);
×
1824
                        Terminate(-1);
×
1825
                }
1826
                R_COPY_S(tablebases[i].name,char*);
×
1827
                R_COPY_S(tablebases[i].fullname,char*);
×
1828
                R_COPY_S(tablebases[i].tablenames,char*);
×
1829
        }
1830
        AC.TableBaseList.message = "list of tablebases";
×
1831

1832
        R_COPY_LIST(AC.cbufList);
×
1833
        for ( i=0; i<AC.cbufList.num; ++i ) {
×
1834
                org = (UBYTE*)cbuf[i].Buffer;
×
1835
                R_COPY_B(cbuf[i].Buffer, cbuf[i].BufferSize*sizeof(WORD), WORD*);
×
1836
                ofs = (UBYTE*)cbuf[i].Buffer - org;
×
1837
                cbuf[i].Top = (WORD*)((UBYTE*)cbuf[i].Top + ofs);
×
1838
                cbuf[i].Pointer = (WORD*)((UBYTE*)cbuf[i].Pointer + ofs);
×
1839
                R_COPY_B(cbuf[i].lhs, cbuf[i].maxlhs*(LONG)sizeof(WORD*), WORD**);
×
1840
                for ( j=1; j<=cbuf[i].numlhs; ++j ) {
×
1841
                        if ( cbuf[i].lhs[j] ) cbuf[i].lhs[j] = (WORD*)((UBYTE*)cbuf[i].lhs[j] + ofs);
×
1842
                }
1843
                org = (UBYTE*)cbuf[i].rhs;
×
1844
                R_COPY_B(cbuf[i].rhs, cbuf[i].maxrhs*(LONG)(sizeof(WORD*)+2*sizeof(LONG)+2*sizeof(WORD)), WORD**);
×
1845
                for ( j=1; j<=cbuf[i].numrhs; ++j ) {
×
1846
                        if ( cbuf[i].rhs[j] ) cbuf[i].rhs[j] = (WORD*)((UBYTE*)cbuf[i].rhs[j] + ofs);
×
1847
                }
1848
                ofs = (UBYTE*)cbuf[i].rhs - org;
×
1849
                cbuf[i].CanCommu = (LONG*)((UBYTE*)cbuf[i].CanCommu + ofs);
×
1850
                cbuf[i].NumTerms = (LONG*)((UBYTE*)cbuf[i].NumTerms + ofs);
×
1851
                cbuf[i].numdum = (WORD*)((UBYTE*)cbuf[i].numdum + ofs);
×
1852
                cbuf[i].dimension = (WORD*)((UBYTE*)cbuf[i].dimension + ofs);
×
1853
                if ( cbuf[i].boomlijst ) {
×
1854
                        R_COPY_B(cbuf[i].boomlijst, cbuf[i].MaxTreeSize*sizeof(COMPTREE), COMPTREE*);
×
1855
                }
1856
        }
1857
        AC.cbufList.message = "compiler buffer";
×
1858

1859
        R_COPY_LIST(AC.AutoSymbolList);
×
1860
        AC.AutoSymbolList.message = "autosymbol";
×
1861
        R_COPY_LIST(AC.AutoIndexList);
×
1862
        AC.AutoIndexList.message = "autoindex";
×
1863
        R_COPY_LIST(AC.AutoVectorList);
×
1864
        AC.AutoVectorList.message = "autovector";
×
1865
        R_COPY_LIST(AC.AutoFunctionList);
×
1866
        AC.AutoFunctionList.message = "autofunction";
×
1867

1868
        R_COPY_NAMETREE(AC.autonames);
×
1869

1870
        AC.Symbols = &(AC.SymbolList);
×
1871
        AC.Indices = &(AC.IndexList);
×
1872
        AC.Vectors = &(AC.VectorList);
×
1873
        AC.Functions = &(AC.FunctionList);
×
1874
        AC.activenames = &(AC.varnames);
×
1875

1876
        org = (UBYTE*)AC.Streams;
×
1877
        R_COPY_B(AC.Streams, AC.MaxNumStreams*(LONG)sizeof(STREAM), STREAM*);
×
1878
        for ( i=0; i<AC.NumStreams; ++i ) {
×
1879
                if ( AC.Streams[i].type != FILESTREAM ) {
×
1880
                        UBYTE *org2;
×
1881
                        org2 = AC.Streams[i].buffer;
×
1882
                        if ( AC.Streams[i].inbuffer ) {
×
1883
                                R_COPY_B(AC.Streams[i].buffer, AC.Streams[i].inbuffer, UBYTE*);
×
1884
                        }
1885
                        ofs = AC.Streams[i].buffer - org2;
×
1886
                        AC.Streams[i].pointer += ofs;
×
1887
                        AC.Streams[i].top += ofs;
×
1888
                }
1889
                else {
1890
                        p = (unsigned char*)p + AC.Streams[i].inbuffer;
×
1891
                }
1892
                AC.Streams[i].buffersize = AC.Streams[i].inbuffer;
×
1893
                R_COPY_S(AC.Streams[i].FoldName,UBYTE*);
×
1894
                R_COPY_S(AC.Streams[i].name,UBYTE*);
×
1895
                if ( AC.Streams[i].type == PREVARSTREAM || AC.Streams[i].type == DOLLARSTREAM ) {
×
1896
                        AC.Streams[i].pname = AC.Streams[i].name;
×
1897
                }
1898
                else if ( AC.Streams[i].type == FILESTREAM ) {
×
1899
                        UBYTE *org2;
×
1900
                        org2 = AC.Streams[i].buffer;
×
1901
                        AC.Streams[i].buffer = (UBYTE*)Malloc1(AC.Streams[i].buffersize, "buffer");
×
1902
                        ofs = AC.Streams[i].buffer - org2;
×
1903
                        AC.Streams[i].pointer += ofs;
×
1904
                        AC.Streams[i].top += ofs;
×
1905

1906
                        /* open file except for already opened main input file */
1907
                        if ( i ) {
×
1908
                                AC.Streams[i].handle = OpenFile((char *)(AC.Streams[i].name));
×
1909
                                if ( AC.Streams[i].handle == -1 ) {
×
1910
                                        MesPrint("ERROR: Could not reopen stream %s!",AC.Streams[i].name);
×
1911
                                        Terminate(-1);
×
1912
                                }
1913
                        }
1914
                        
1915
                        PUTZERO(pos);
×
1916
                        ADDPOS(pos, AC.Streams[i].bufferposition);
×
1917
                        SeekFile(AC.Streams[i].handle, &pos, SEEK_SET);
×
1918

1919
                        AC.Streams[i].inbuffer = ReadFile(AC.Streams[i].handle, AC.Streams[i].buffer, AC.Streams[i].inbuffer);
×
1920

1921
                        SETBASEPOSITION(pos, AC.Streams[i].fileposition);
×
1922
                        SeekFile(AC.Streams[i].handle, &pos, SEEK_SET);
×
1923
                }
1924
                /* 
1925
                 * Ideally, we should check if we have a type PREREADSTREAM, PREREADSTREAM2, and
1926
                 * PRECALCSTREAM here. If so, we should free element name and point it
1927
                 * to the name element of the embracing stream's struct. In practice,
1928
                 * this is undoable without adding new data to STREAM. Since we create
1929
                 * only a small memory leak here (some few byte for each existing
1930
                 * stream of these types) and only once when we do a recovery, we
1931
                 * tolerate this leak and keep it STREAM as it is.
1932
                 */
1933
        }
1934
        ofs = (UBYTE*)AC.Streams - org;
×
1935
        AC.CurrentStream = (STREAM*)((UBYTE*)AC.CurrentStream + ofs);
×
1936

1937
        if ( AC.termstack ) {
×
1938
                R_COPY_B(AC.termstack, AC.maxtermlevel*(LONG)sizeof(LONG), LONG*);
×
1939
        }
1940

1941
        if ( AC.termsortstack ) {
×
1942
                R_COPY_B(AC.termsortstack, AC.maxtermlevel*(LONG)sizeof(LONG), LONG*);
×
1943
        }
1944

1945
        /* exception: here we also change values from struct AM */
1946
        R_COPY_B(AC.cmod, AM.MaxTal*4*(LONG)sizeof(UWORD), UWORD*);
×
1947
        AM.gcmod = AC.cmod + AM.MaxTal;
×
1948
        AC.powmod = AM.gcmod + AM.MaxTal;
×
1949
        AM.gpowmod = AC.powmod + AM.MaxTal;
×
1950

1951
        AC.modpowers = 0;
×
1952
        AC.halfmod = 0;
×
1953

1954
        /* we don't care about AC.ProtoType/WildC */
1955

1956
        if ( AC.IfHeap ) {
×
1957
                ofs = AC.IfStack - AC.IfHeap;
×
1958
                R_COPY_B(AC.IfHeap, (LONG)sizeof(LONG)*(AC.MaxIf+1), LONG*);
×
1959
                AC.IfStack = AC.IfHeap + ofs;
×
1960
                R_COPY_B(AC.IfCount, (LONG)sizeof(LONG)*(AC.MaxIf+1), LONG*);
×
1961
        }
1962

1963
        org = AC.iBuffer;
×
1964
        size = AC.iStop - AC.iBuffer + 2;
×
1965
        R_COPY_B(AC.iBuffer, size, UBYTE*);
×
1966
        ofs = AC.iBuffer - org;
×
1967
        AC.iPointer += ofs;
×
1968
        AC.iStop += ofs;
×
1969

1970
        if ( AC.LabelNames ) {
×
1971
                org = (UBYTE*)AC.LabelNames;
×
1972
                R_COPY_B(AC.LabelNames, AC.MaxLabels*(LONG)(sizeof(UBYTE*)+sizeof(WORD)), UBYTE**);
×
1973
                for ( i=0; i<AC.NumLabels; ++i ) {
×
1974
                        R_COPY_S(AC.LabelNames[i],UBYTE*);
×
1975
                }
1976
                ofs = (UBYTE*)AC.LabelNames - org;
×
1977
                AC.Labels = (int*)((UBYTE*)AC.Labels + ofs);
×
1978
        }
1979
        
1980
        R_COPY_B(AC.FixIndices, AM.OffsetIndex*(LONG)sizeof(WORD), WORD*);
×
1981

1982
        if ( AC.termsumcheck ) {
×
1983
                R_COPY_B(AC.termsumcheck, AC.maxtermlevel*(LONG)sizeof(WORD), WORD*);
×
1984
        }
1985

1986
        R_COPY_B(AC.WildcardNames, AC.WildcardBufferSize, UBYTE*);
×
1987

1988
        if ( AC.tokens ) {
×
1989
                size = AC.toptokens - AC.tokens;
×
1990
                if ( size ) {
×
1991
                        org = (UBYTE*)AC.tokens;
×
1992
                        R_COPY_B(AC.tokens, size, SBYTE*);
×
1993
                        ofs = (UBYTE*)AC.tokens - org;
×
1994
                        AC.endoftokens += ofs;
×
1995
                        AC.toptokens += ofs;
×
1996
                }
1997
                else {
1998
                        AC.tokens = 0;
×
1999
                        AC.endoftokens = AC.tokens;
×
2000
                        AC.toptokens = AC.tokens;
×
2001
                }
2002
        }
2003

2004
        R_COPY_B(AC.tokenarglevel, AM.MaxParLevel*(LONG)sizeof(WORD), WORD*);
×
2005

2006
        AC.modinverses = 0;
×
2007

2008
        R_COPY_S(AC.Fortran90Kind,UBYTE *);
×
2009

2010
#ifdef WITHPTHREADS
2011
        if ( AC.inputnumbers ) {
2012
                org = (UBYTE*)AC.inputnumbers;
2013
                R_COPY_B(AC.inputnumbers, AC.sizepfirstnum*(LONG)(sizeof(WORD)+sizeof(LONG)), LONG*);
2014
                ofs = (UBYTE*)AC.inputnumbers - org;
2015
                AC.pfirstnum = (WORD*)((UBYTE*)AC.pfirstnum + ofs);
2016
        }
2017
        AC.halfmodlock = dummylock;
2018
#endif /* ifdef WITHPTHREADS */
2019

2020
        if ( AC.IfSumCheck ) {
×
2021
                R_COPY_B(AC.IfSumCheck, (LONG)sizeof(WORD)*(AC.MaxIf+1), WORD*);
×
2022
        }
2023
        if ( AC.CommuteInSet ) {
×
2024
                R_COPY_B(AC.CommuteInSet, (LONG)sizeof(WORD)*(AC.SizeCommuteInSet+1), WORD*);
×
2025
        }
2026

2027
        AC.LogHandle = oldLogHandle;
×
2028

2029
        R_COPY_S(AC.CheckpointRunAfter,char*);
×
2030
        R_COPY_S(AC.CheckpointRunBefore,char*);
×
2031

2032
        R_COPY_S(AC.extrasym,UBYTE *);
×
2033

2034
#ifdef PRINTDEBUG
2035
        print_C();
2036
#endif
2037

2038
        /*#] AC : */ 
2039
        /*#[ AP : */
2040

2041
        /* #[ AP free pointers */
2042

2043
        /* AP will be overwritten by data from the recovery file, therefore
2044
         * dynamically allocated memory must be freed first. */
2045

2046
        for ( i=0; i<AP.DollarList.num; ++i ) {
×
2047
                if ( Dollars[i].size ) {
×
2048
                        R_FREE(Dollars[i].where);
×
2049
                }
2050
                CleanDollarFactors(Dollars+i);
×
2051
        }
2052
        R_FREE(AP.DollarList.lijst);
×
2053

2054
        for ( i=0; i<AP.PreVarList.num; ++i ) {
×
2055
                R_FREE(PreVar[i].name);
×
2056
        }
2057
        R_FREE(AP.PreVarList.lijst);
×
2058

2059
        for ( i=0; i<AP.LoopList.num; ++i ) {
×
2060
                R_FREE(DoLoops[i].p.buffer);
×
2061
                if ( DoLoops[i].dollarname ) {
×
2062
                        R_FREE(DoLoops[i].dollarname);
×
2063
                }
2064
        }
2065
        R_FREE(AP.LoopList.lijst);
×
2066
        
2067
        for ( i=0; i<AP.ProcList.num; ++i ) {
×
2068
                R_FREE(Procedures[i].p.buffer);
×
2069
                R_FREE(Procedures[i].name);
×
2070
        }
2071
        R_FREE(AP.ProcList.lijst);
×
2072

2073
        for ( i=1; i<=AP.PreSwitchLevel; ++i ) {
×
2074
                R_FREE(AP.PreSwitchStrings[i]);
×
2075
        }
2076
        R_FREE(AP.PreSwitchStrings);
×
2077
        R_FREE(AP.preStart);
×
2078
        R_FREE(AP.procedureExtension);
×
2079
        R_FREE(AP.cprocedureExtension);
×
2080
        R_FREE(AP.PreIfStack);
×
2081
        R_FREE(AP.PreSwitchModes);
×
2082
        R_FREE(AP.PreTypes);
×
2083

2084
        /* #] AP free pointers */
2085
        
2086
        /* first we copy AP as a whole and then restore the pointer structures step
2087
           by step. */
2088

2089
        AP = *((struct P_const*)p); p = (unsigned char*)p + sizeof(struct P_const);
×
2090
#ifdef WITHPTHREADS
2091
        AP.PreVarLock = dummylock;
2092
#endif
2093

2094
        R_COPY_LIST(AP.DollarList);
×
2095
        for ( i=0; i<AP.DollarList.num; ++i ) {
×
2096
                DOLLARS d = Dollars + i;
×
2097
                size = d->size * sizeof(WORD);
×
2098
                if ( size && d->where && d->where != oldAMdollarzero ) {
×
2099
                        R_COPY_B(d->where, size, void*);
×
2100
                }
2101
#ifdef WITHPTHREADS
2102
                d->pthreadslockread = dummylock;
2103
                d->pthreadslockwrite = dummylock;
2104
#endif
2105
                if ( d->nfactors > 1 ) {
×
2106
                        R_COPY_B(d->factors,sizeof(FACDOLLAR)*d->nfactors,FACDOLLAR*);
×
2107
                        for ( j = 0; j < d->nfactors; j++ ) {
×
2108
                                if ( d->factors[j].size > 0 ) {
×
2109
                                        R_COPY_B(d->factors[i].where,sizeof(WORD)*(d->factors[j].size+1),WORD*);
×
2110
                                }
2111
                        }
2112
                }
2113
        }
2114
        AP.DollarList.message = "$-variable";
×
2115

2116
        R_COPY_LIST(AP.PreVarList);
×
2117
        for ( i=0; i<AP.PreVarList.num; ++i ) {
×
2118
                R_SET(size, size_t);
×
2119
                org = PreVar[i].name;
×
2120
                R_COPY_B(PreVar[i].name, size, UBYTE*);
×
2121
                ofs = PreVar[i].name - org;
×
2122
                if ( PreVar[i].value ) PreVar[i].value += ofs;
×
2123
                if ( PreVar[i].argnames ) PreVar[i].argnames += ofs;
×
2124
        }
2125
        AP.PreVarList.message = "PreVariable";
×
2126

2127
        R_COPY_LIST(AP.LoopList);
×
2128
        for ( i=0; i<AP.LoopList.num; ++i ) {
×
2129
                org = DoLoops[i].p.buffer;
×
2130
                R_COPY_B(DoLoops[i].p.buffer, DoLoops[i].p.size, UBYTE*);
×
2131
                ofs = DoLoops[i].p.buffer - org;
×
2132
                if ( DoLoops[i].name ) DoLoops[i].name += ofs;
×
2133
                if ( DoLoops[i].vars ) DoLoops[i].vars += ofs;
×
2134
                if ( DoLoops[i].contents ) DoLoops[i].contents += ofs;
×
2135
                if ( DoLoops[i].type == ONEEXPRESSION ) {
×
2136
                        R_COPY_S(DoLoops[i].dollarname,UBYTE*);
×
2137
                }
2138
        }
2139
        AP.LoopList.message = "doloop";
×
2140

2141
        R_COPY_LIST(AP.ProcList);
×
2142
        for ( i=0; i<AP.ProcList.num; ++i ) {
×
2143
                if ( Procedures[i].p.size ) {
×
2144
                        if ( Procedures[i].loadmode != 1 ) {
×
2145
                                R_COPY_B(Procedures[i].p.buffer, Procedures[i].p.size, UBYTE*);
×
2146
                        }
2147
                        else {
2148
                                R_SET(j, int);
×
2149
                                Procedures[i].p.buffer = Procedures[j].p.buffer;
×
2150
                        }
2151
                }
2152
                R_COPY_S(Procedures[i].name,UBYTE*);
×
2153
        }
2154
        AP.ProcList.message = "procedure";
×
2155

2156
        size = (AP.NumPreSwitchStrings+1)*(LONG)sizeof(UBYTE*);
×
2157
        R_COPY_B(AP.PreSwitchStrings, size, UBYTE**);
×
2158
        for ( i=1; i<=AP.PreSwitchLevel; ++i ) {
×
2159
                R_COPY_S(AP.PreSwitchStrings[i],UBYTE*);
×
2160
        }
2161

2162
        org = AP.preStart;
×
2163
        R_COPY_B(AP.preStart, AP.pSize, UBYTE*);
×
2164
        ofs = AP.preStart - org;
×
2165
        if ( AP.preFill ) AP.preFill += ofs;
×
2166
        if ( AP.preStop ) AP.preStop += ofs;
×
2167

2168
        R_COPY_S(AP.procedureExtension,UBYTE*);
×
2169
        R_COPY_S(AP.cprocedureExtension,UBYTE*);
×
2170

2171
        R_COPY_B(AP.PreAssignStack,AP.MaxPreAssignLevel*(LONG)sizeof(LONG),LONG*);
×
2172
        R_COPY_B(AP.PreIfStack, AP.MaxPreIfLevel*(LONG)sizeof(int), int*);
×
2173
        R_COPY_B(AP.PreSwitchModes, (AP.NumPreSwitchStrings+1)*(LONG)sizeof(int), int*);
×
2174
        R_COPY_B(AP.PreTypes, (AP.MaxPreTypes+1)*(LONG)sizeof(int), int*);
×
2175

2176
#ifdef PRINTDEBUG
2177
        print_P();
2178
#endif
2179

2180
        /*#] AP : */ 
2181
        /*#[ AR : */
2182

2183
        R_SET(ofs,LONG);
×
2184
        if ( ofs ) {
×
2185
                AR.infile = AR.Fscr+1;
×
2186
                AR.outfile = AR.Fscr;
×
2187
                AR.hidefile = AR.Fscr+2;
×
2188
        }
2189
        else {
2190
                AR.infile = AR.Fscr;
×
2191
                AR.outfile = AR.Fscr+1;
×
2192
                AR.hidefile = AR.Fscr+2;
×
2193
        }
2194

2195
        /* #[ AR free pointers */
2196

2197
        /* Parts of AR will be overwritten by data from the recovery file, therefore
2198
         * dynamically allocated memory must be freed first. */
2199

2200
        namebufout = AR.outfile->name;
×
2201
        namebufhide = AR.hidefile->name;
×
2202
        R_FREE(AR.outfile->PObuffer);
×
2203
#ifdef WITHZLIB
2204
        R_FREE(AR.outfile->zsp);
×
2205
        R_FREE(AR.outfile->ziobuffer);
×
2206
#endif
2207
        namebufhide = AR.hidefile->name;
×
2208
        R_FREE(AR.hidefile->PObuffer);
×
2209
#ifdef WITHZLIB
2210
        R_FREE(AR.hidefile->zsp);
×
2211
        R_FREE(AR.hidefile->ziobuffer);
×
2212
#endif
2213
        /* no files should be opened -> nothing to do with handle */
2214

2215
        /* #] AR free pointers */
2216
        
2217
        /* outfile */
2218
        R_SET(*AR.outfile, FILEHANDLE);
×
2219
        org = (UBYTE*)AR.outfile->PObuffer;
×
2220
        size = AR.outfile->POfull - AR.outfile->PObuffer;
×
2221
        AR.outfile->PObuffer = (WORD*)Malloc1(AR.outfile->POsize, "PObuffer");
×
2222
        if ( size ) {
×
2223
                memcpy(AR.outfile->PObuffer, p, size*sizeof(WORD));
×
2224
                p = (unsigned char*)p + size*sizeof(WORD);
×
2225
        }
2226
        ofs = (UBYTE*)AR.outfile->PObuffer - org;
×
2227
        AR.outfile->POstop = (WORD*)((UBYTE*)AR.outfile->POstop + ofs);
×
2228
        AR.outfile->POfill = (WORD*)((UBYTE*)AR.outfile->POfill + ofs);
×
2229
        AR.outfile->POfull = (WORD*)((UBYTE*)AR.outfile->POfull + ofs);
×
2230
        AR.outfile->name = namebufout;
×
2231
#ifdef WITHPTHREADS
2232
        AR.outfile->wPObuffer = AR.outfile->PObuffer;
2233
        AR.outfile->wPOstop = AR.outfile->POstop;
2234
        AR.outfile->wPOfill = AR.outfile->POfill;
2235
        AR.outfile->wPOfull = AR.outfile->POfull;
2236
#endif
2237
#ifdef WITHZLIB
2238
        /* zsp and ziobuffer will be allocated when used */
2239
        AR.outfile->zsp = 0;
×
2240
        AR.outfile->ziobuffer = 0;
×
2241
#endif
2242
        /* reopen old outfile */
2243
#ifdef WITHMPI
2244
        if(PF.me==MASTER)
2245
#endif
2246
        if ( AR.outfile->handle >= 0 ) {
×
2247
                if ( CopyFile(sortfile, AR.outfile->name) ) {
×
2248
                        MesPrint("ERROR: Could not copy old output sort file %s!",sortfile);
×
2249
                        Terminate(-1);
×
2250
                }
2251
                AR.outfile->handle = ReOpenFile(AR.outfile->name);
×
2252
                if ( AR.outfile->handle == -1 ) {
×
2253
                        MesPrint("ERROR: Could not reopen output sort file %s!",AR.outfile->name);
×
2254
                        Terminate(-1);
×
2255
                }
2256
                SeekFile(AR.outfile->handle, &AR.outfile->POposition, SEEK_SET);
×
2257
        }
2258

2259
        /* hidefile */
2260
        R_SET(*AR.hidefile, FILEHANDLE);
×
2261
        AR.hidefile->name = namebufhide;
×
2262
        if ( AR.hidefile->PObuffer ) {
×
2263
                org = (UBYTE*)AR.hidefile->PObuffer;
×
2264
                size = AR.hidefile->POfull - AR.hidefile->PObuffer;
×
2265
                AR.hidefile->PObuffer = (WORD*)Malloc1(AR.hidefile->POsize, "PObuffer");
×
2266
                if ( size ) {
×
2267
                        memcpy(AR.hidefile->PObuffer, p, size*sizeof(WORD));
×
2268
                        p = (unsigned char*)p + size*sizeof(WORD);
×
2269
                }
2270
                ofs = (UBYTE*)AR.hidefile->PObuffer - org;
×
2271
                AR.hidefile->POstop = (WORD*)((UBYTE*)AR.hidefile->POstop + ofs);
×
2272
                AR.hidefile->POfill = (WORD*)((UBYTE*)AR.hidefile->POfill + ofs);
×
2273
                AR.hidefile->POfull = (WORD*)((UBYTE*)AR.hidefile->POfull + ofs);
×
2274
#ifdef WITHPTHREADS
2275
                AR.hidefile->wPObuffer = AR.hidefile->PObuffer;
2276
                AR.hidefile->wPOstop = AR.hidefile->POstop;
2277
                AR.hidefile->wPOfill = AR.hidefile->POfill;
2278
                AR.hidefile->wPOfull = AR.hidefile->POfull;
2279
#endif
2280
        }
2281
#ifdef WITHZLIB
2282
                /* zsp and ziobuffer will be allocated when used */
2283
                AR.hidefile->zsp = 0;
×
2284
                AR.hidefile->ziobuffer = 0;
×
2285
#endif
2286
        /* reopen old hidefile */
2287
        if ( AR.hidefile->handle >= 0 ) {
×
2288
                if ( CopyFile(hidefile, AR.hidefile->name) ) {
×
2289
                        MesPrint("ERROR: Could not copy old hide file %s!",hidefile);
×
2290
                        Terminate(-1);
×
2291
                }
2292
                AR.hidefile->handle = ReOpenFile(AR.hidefile->name);
×
2293
                if ( AR.hidefile->handle == -1 ) {
×
2294
                        MesPrint("ERROR: Could not reopen hide file %s!",AR.hidefile->name);
×
2295
                        Terminate(-1);
×
2296
                }
2297
                SeekFile(AR.hidefile->handle, &AR.hidefile->POposition, SEEK_SET);
×
2298
        }
2299

2300
        /* store file */
2301
        R_SET(pos, POSITION);
×
2302
        if ( ISNOTZEROPOS(pos) ) {
×
2303
                CloseFile(AR.StoreData.Handle);
×
2304
                R_SET(AR.StoreData, FILEDATA);
×
2305
                if ( CopyFile(storefile, FG.fname) ) {
×
2306
                        MesPrint("ERROR: Could not copy old store file %s!",storefile);
×
2307
                        Terminate(-1);
×
2308
                }
2309
                AR.StoreData.Handle = (WORD)ReOpenFile(FG.fname);
×
2310
                SeekFile(AR.StoreData.Handle, &AR.StoreData.Position, SEEK_SET);
×
2311
        }
2312

2313
        R_SET(AR.DefPosition, POSITION);
×
2314
        R_SET(AR.OldTime, LONG);
×
2315
        R_SET(AR.InInBuf, LONG);
×
2316
        R_SET(AR.InHiBuf, LONG);
×
2317

2318
        R_SET(AR.NoCompress, int);
×
2319
        R_SET(AR.gzipCompress, int);
×
2320

2321
        R_SET(AR.outtohide, int);
×
2322

2323
        R_SET(AR.GetFile, WORD);
×
2324
        R_SET(AR.KeptInHold, WORD);
×
2325
        R_SET(AR.BracketOn, WORD);
×
2326
        R_SET(AR.MaxBracket, WORD);
×
2327
        R_SET(AR.CurDum, WORD);
×
2328
        R_SET(AR.DeferFlag, WORD);
×
2329
        R_SET(AR.TePos, WORD);
×
2330
        R_SET(AR.sLevel, WORD);
×
2331
        R_SET(AR.Stage4Name, WORD);
×
2332
        R_SET(AR.GetOneFile, WORD);
×
2333
        R_SET(AR.PolyFun, WORD);
×
2334
        R_SET(AR.PolyFunInv, WORD);
×
2335
        R_SET(AR.PolyFunType, WORD);
×
2336
        R_SET(AR.PolyFunExp, WORD);
×
2337
        R_SET(AR.PolyFunVar, WORD);
×
2338
        R_SET(AR.PolyFunPow, WORD);
×
2339
        R_SET(AR.Eside, WORD);
×
2340
        R_SET(AR.MaxDum, WORD);
×
2341
        R_SET(AR.level, WORD);
×
2342
        R_SET(AR.expchanged, WORD);
×
2343
        R_SET(AR.expflags, WORD);
×
2344
        R_SET(AR.CurExpr, WORD);
×
2345
        R_SET(AR.SortType, WORD);
×
2346
        R_SET(AR.ShortSortCount, WORD);
×
2347

2348
        /* this is usually done in Process(), but sometimes FORM does not
2349
           end up executing Process() before it uses the AR.CompressPointer,
2350
           so we need to explicitly set it here. */
2351
        AR.CompressPointer = AR.CompressBuffer;
×
2352

2353
#ifdef WITHPTHREADS
2354
        for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
2355
                R_SET(AB[j]->R.wranfnpair1, int);
2356
                R_SET(AB[j]->R.wranfnpair2, int);
2357
                R_SET(AB[j]->R.wranfcall, int);
2358
                R_SET(AB[j]->R.wranfseed, ULONG);
2359
                R_SET(AB[j]->R.wranfia,ULONG*);
2360
                if ( AB[j]->R.wranfia ) {
2361
                        R_COPY_B(AB[j]->R.wranfia, sizeof(ULONG)*AB[j]->R.wranfnpair2, ULONG*);
2362
                }
2363
        }
2364
#else
2365
        R_SET(AR.wranfnpair1, int);
2366
        R_SET(AR.wranfnpair2, int);
2367
        R_SET(AR.wranfcall, int);
2368
        R_SET(AR.wranfseed, ULONG);
2369
        R_SET(AR.wranfia,ULONG*);
2370
        if ( AR.wranfia ) {
2371
                R_COPY_B(AR.wranfia, sizeof(ULONG)*AR.wranfnpair2, ULONG*);
2372
        }
2373
#endif
2374

2375
#ifdef PRINTDEBUG
2376
        print_R();
2377
#endif
2378

2379
        /*#] AR : */ 
2380
        /*#[ AO :*/
2381
/*
2382
        We copy all non-pointer variables.
2383
*/
2384
        l = sizeof(A.O) - ((UBYTE *)(&(A.O.NumInBrack))-(UBYTE *)(&A.O));
×
2385
        memcpy(&(A.O.NumInBrack), p, l); p = (unsigned char*)p + l;
×
2386
/*
2387
        Now the variables in OptimizeResult
2388
*/
2389
        memcpy(&(A.O.OptimizeResult),p,sizeof(OPTIMIZERESULT));
×
2390
                p = (unsigned char*)p + sizeof(OPTIMIZERESULT);
×
2391

2392
        if ( A.O.OptimizeResult.codesize > 0 ) {
×
2393
                R_COPY_B(A.O.OptimizeResult.code,A.O.OptimizeResult.codesize*sizeof(WORD),WORD *);
×
2394
        }
2395
        R_COPY_S(A.O.OptimizeResult.nameofexpr,UBYTE *);
×
2396
/*
2397
        And now the dictionaries. We know how many there are. We also know
2398
        how many elements the array AO.Dictionaries should have.
2399
*/
2400
        if ( AO.SizeDictionaries > 0 ) {
×
2401
                AO.Dictionaries = (DICTIONARY **)Malloc1(AO.SizeDictionaries*sizeof(DICTIONARY *),
×
2402
                                        "Dictionaries");
2403
                for ( i = 0; i < AO.NumDictionaries; i++ ) {
×
2404
                        R_SET(l,LONG)
×
2405
                        AO.Dictionaries[i] = DictFromBytes(p);
×
2406
                        p = (char *)p + l;
×
2407
                }
2408
        }
2409
        /*#] AO :*/ 
2410
#ifdef WITHMPI
2411
        /*#[ PF : */
2412
        {/*Block*/
2413
                int numtasks;
2414
                R_SET(numtasks, int);
2415
                if(numtasks!=PF.numtasks){
2416
                        MesPrint("%d number of tasks expected instead of %d; use mpirun -np %d",
2417
                                                        numtasks,PF.numtasks,numtasks);
2418
                        if(PF.me!=MASTER)
2419
                                remove(RecoveryFilename());
2420
                        Terminate(-1);
2421
                }
2422
        }/*Block*/
2423
        R_SET(PF.rhsInParallel, int);
2424
        R_SET(PF.exprbufsize, int);
2425
        R_SET(PF.log, int);
2426
        /*#] PF : */ 
2427
#endif
2428

2429
#ifdef WITHPTHREADS
2430
        /* read timing information of individual threads */
2431
        R_SET(i, int);
2432
        for ( j=1; j<AM.totalnumberofthreads; ++j ) {
2433
                /* ... and correcting OldTime */
2434
                AB[j]->R.OldTime = -(*((LONG*)p+j));
2435
        }
2436
        WriteTimerInfo((LONG*)p,(LONG *)((unsigned char*)p + i*(LONG)sizeof(LONG)));
2437
        p = (unsigned char*)p + 2*i*(LONG)sizeof(LONG);
2438
#endif /* ifdef WITHPTHREADS */
2439

2440
        if ( fclose(fd) ) return(__LINE__);
×
2441

2442
        M_free(buf,"recovery buffer");
×
2443

2444
        /* cares about data in S_const */
2445
        UpdatePositions();
×
2446
        AT.SS = AT.S0;
×
2447
/*
2448
        Set the checkpoint parameter right for the next checkpoint.
2449
*/
2450
        AC.CheckpointStamp = TimeWallClock(1);
×
2451
        
2452
        done_snapshot = 1;
×
2453
        MesPrint("done."); fflush(0);
×
2454

2455
        return(0);
×
2456
}
2457

2458
/*
2459
          #] DoRecovery : 
2460
          #[ DoSnapshot :
2461
*/
2462

2463
/**
2464
 *  Writes all relevant information for a recovery to the recovery file. It
2465
 *  writes first to an intermediate file and then only if everything went well
2466
 *  it renames this intermediate file to the final recovery file. Then it copies
2467
 *  the sort and store files if necessary.
2468
 *
2469
 *  The data is directly written to file from the structs or struct element.
2470
 *
2471
 *  No data is changed in the global structs and this function should never crash.
2472
 *  Honorably exception might be: not enough memory for the allocation of the
2473
 *  command strings (usually less than 100 bytes), or not enough disk space for
2474
 *  the recovery file and the copies of the hide/scratch/store files.
2475
 *
2476
 *  If something goes wrong, the function returns with a non-zero value.
2477
 */
2478
static int DoSnapshot(int moduletype)
×
2479
{
2480
        GETIDENTITY
2481
        FILE *fd;
×
2482
        POSITION pos;
×
2483
        int i, j;
×
2484
        LONG l;
×
2485
        WORD *w;
×
2486
        void *adr;
×
2487
#ifdef WITHPTHREADS
2488
        LONG *longp,*longpp;
2489
#endif /* ifdef WITHPTHREADS */
2490

2491
        MesPrint("Saving recovery point ... %"); fflush(0);
×
2492
#ifdef PRINTTIMEMARKS
2493
        MesPrint("\n");
2494
#endif
2495

2496
        if ( !(fd = fopen(intermedfile, "wb")) ) return(__LINE__);
×
2497

2498
        /* reserve space in the file for a length field */
2499
        if ( fwrite(&pos, 1, sizeof(POSITION), fd) != sizeof(POSITION) ) return(__LINE__);
×
2500

2501
        /* write moduletype */
2502
        if ( fwrite(&moduletype, 1, sizeof(int), fd) != sizeof(int) ) return(__LINE__);
×
2503

2504
        /*#[ AM :*/
2505

2506
        /* since most values don't change during execution, AM doesn't need to be
2507
         * written as a whole. all values will be correctly set when starting up
2508
         * anyway. only the exceptions need to be taken care of. see MakeGlobal()
2509
         * and PopVariables() in execute.c. */
2510

2511
        ANNOUNCE(AM)
2512
        S_WRITE_B(&AM.hparallelflag, sizeof(int));
×
2513
        S_WRITE_B(&AM.gparallelflag, sizeof(int));
×
2514
        S_WRITE_B(&AM.gCodesFlag, sizeof(int));
×
2515
        S_WRITE_B(&AM.gNamesFlag, sizeof(int));
×
2516
        S_WRITE_B(&AM.gStatsFlag, sizeof(int));
×
2517
        S_WRITE_B(&AM.gTokensWriteFlag, sizeof(int));
×
2518
        S_WRITE_B(&AM.gNoSpacesInNumbers, sizeof(int));
×
2519
        S_WRITE_B(&AM.gIndentSpace, sizeof(WORD));
×
2520
        S_WRITE_B(&AM.gUnitTrace, sizeof(WORD));
×
2521
        S_WRITE_B(&AM.gDefDim, sizeof(int));
×
2522
        S_WRITE_B(&AM.gDefDim4, sizeof(int));
×
2523
        S_WRITE_B(&AM.gncmod, sizeof(WORD));
×
2524
        S_WRITE_B(&AM.gnpowmod, sizeof(WORD));
×
2525
        S_WRITE_B(&AM.gmodmode, sizeof(WORD));
×
2526
        S_WRITE_B(&AM.gOutputMode, sizeof(WORD));
×
2527
        S_WRITE_B(&AM.gCnumpows, sizeof(WORD));
×
2528
        S_WRITE_B(&AM.gOutputSpaces, sizeof(WORD));
×
2529
        S_WRITE_B(&AM.gOutNumberType, sizeof(WORD));
×
2530
        S_WRITE_B(&AM.gfunpowers, sizeof(int));
×
2531
        S_WRITE_B(&AM.gPolyFun, sizeof(WORD));
×
2532
        S_WRITE_B(&AM.gPolyFunInv, sizeof(WORD));
×
2533
        S_WRITE_B(&AM.gPolyFunType, sizeof(WORD));
×
2534
        S_WRITE_B(&AM.gPolyFunExp, sizeof(WORD));
×
2535
        S_WRITE_B(&AM.gPolyFunVar, sizeof(WORD));
×
2536
        S_WRITE_B(&AM.gPolyFunPow, sizeof(WORD));
×
2537
        S_WRITE_B(&AM.gProcessBucketSize, sizeof(LONG));
×
2538
        S_WRITE_B(&AM.OldChildTime, sizeof(LONG));
×
2539
        S_WRITE_B(&AM.OldSecTime, sizeof(LONG));
×
2540
        S_WRITE_B(&AM.OldMilliTime, sizeof(LONG));
×
2541
        S_WRITE_B(&AM.gproperorderflag, sizeof(int));
×
2542
        S_WRITE_B(&AM.gThreadBucketSize, sizeof(LONG));
×
2543
        S_WRITE_B(&AM.gSizeCommuteInSet, sizeof(int));
×
2544
        S_WRITE_B(&AM.gThreadStats, sizeof(int));
×
2545
        S_WRITE_B(&AM.gFinalStats, sizeof(int));
×
2546
        S_WRITE_B(&AM.gThreadsFlag, sizeof(int));
×
2547
        S_WRITE_B(&AM.gThreadBalancing, sizeof(int));
×
2548
        S_WRITE_B(&AM.gThreadSortFileSynch, sizeof(int));
×
2549
        S_WRITE_B(&AM.gProcessStats, sizeof(int));
×
2550
        S_WRITE_B(&AM.gOldParallelStats, sizeof(int));
×
2551
        S_WRITE_B(&AM.gSortType, sizeof(int));
×
2552
        S_WRITE_B(&AM.gShortStatsMax, sizeof(WORD));
×
2553
        S_WRITE_B(&AM.gIsFortran90, sizeof(int));
×
2554
        adr = &AM.dollarzero;
×
2555
        S_WRITE_B(&adr, sizeof(void*));
×
2556
        S_WRITE_B(&AM.gFortran90Kind,sizeof(UBYTE *));
×
2557
        S_WRITE_S(AM.gFortran90Kind);
×
2558

2559
        S_WRITE_S(AM.gextrasym);
×
2560
        S_WRITE_S(AM.ggextrasym);
×
2561

2562
        S_WRITE_B(&AM.PrintTotalSize,sizeof(int));
×
2563
        S_WRITE_B(&AM.fbuffersize,sizeof(int));
×
2564
        S_WRITE_B(&AM.gOldFactArgFlag,sizeof(int));
×
2565
        S_WRITE_B(&AM.ggOldFactArgFlag,sizeof(int));
×
2566

2567
    S_WRITE_B(&AM.gnumextrasym,sizeof(int));
×
2568
    S_WRITE_B(&AM.ggnumextrasym,sizeof(int));
×
2569
        S_WRITE_B(&AM.NumSpectatorFiles,sizeof(int));
×
2570
        S_WRITE_B(&AM.SizeForSpectatorFiles,sizeof(int));
×
2571
    S_WRITE_B(&AM.gOldGCDflag,sizeof(int));
×
2572
    S_WRITE_B(&AM.ggOldGCDflag,sizeof(int));
×
2573
        S_WRITE_B(&AM.gWTimeStatsFlag, sizeof(int));
×
2574

2575
        S_WRITE_B(&AM.Path,sizeof(UBYTE *));
×
2576
        S_WRITE_S(AM.Path);
×
2577

2578
        S_WRITE_B(&AM.FromStdin,sizeof(BOOL));
×
2579
        S_WRITE_B(&AM.IgnoreDeprecation,sizeof(BOOL));
×
2580

2581
        /*#] AM :*/ 
2582
        /*#[ AC :*/
2583

2584
        /* we write AC as a whole and then write all additional data step by step.
2585
         * AC.DubiousList doesn't need to be treated, because it should be empty. */
2586

2587
        ANNOUNCE(AC)
2588
        S_WRITE_B(&AC, sizeof(struct C_const));
×
2589

2590
        S_WRITE_NAMETREE(AC.dollarnames);
×
2591
        S_WRITE_NAMETREE(AC.exprnames);
×
2592
        S_WRITE_NAMETREE(AC.varnames);
×
2593
        
2594
        S_WRITE_LIST(AC.ChannelList);
×
2595
        for ( i=0; i<AC.ChannelList.num; ++i ) {
×
2596
                S_WRITE_S(channels[i].name);
×
2597
        }
2598

2599
        ANNOUNCE(AC.FunctionList)
2600
        S_WRITE_LIST(AC.FunctionList);
×
2601
        for ( i=0; i<AC.FunctionList.num; ++i ) {
×
2602
                /* if the function is a table */
2603
                if ( functions[i].tabl ) {
×
2604
                        TABLES tabl = functions[i].tabl;
×
2605
                        S_WRITE_B(tabl, sizeof(struct TaBlEs));
×
2606
                        if ( tabl->tablepointers ) {
×
2607
                                if ( tabl->sparse ) {
×
2608
                                        /* sparse tables. reserved holds number of allocated
2609
                                         * elements. the size of an element is numind plus
2610
                                         * TABLEEXTENSION times the size of WORD. */
2611
                                        S_WRITE_B(tabl->tablepointers,
×
2612
                                                tabl->reserved*sizeof(WORD)*(tabl->numind+TABLEEXTENSION));
2613
                                }
2614
                                else {
2615
                                        /* matrix like tables. */
2616
                                        S_WRITE_B(tabl->tablepointers,
×
2617
                                                TABLEEXTENSION*sizeof(WORD)*(tabl->totind));
×
2618
                                }
2619
                        }
2620
                        S_WRITE_B(tabl->prototype, tabl->prototypeSize);
×
2621
                        S_WRITE_B(tabl->mm, tabl->numind*(LONG)sizeof(MINMAX));
×
2622
                        S_WRITE_B(tabl->flags, tabl->numind*(LONG)sizeof(WORD));
×
2623
                        if ( tabl->sparse ) {
×
2624
                                S_WRITE_B(tabl->boomlijst, tabl->MaxTreeSize*(LONG)sizeof(COMPTREE));
×
2625
                                S_WRITE_S(tabl->argtail);
×
2626
                        }
2627
                        S_WRITE_B(tabl->buffers, tabl->bufferssize*(LONG)sizeof(WORD));
×
2628
                        if ( tabl->spare ) {
×
2629
                                TABLES spare = tabl->spare;
×
2630
                                S_WRITE_B(spare, sizeof(struct TaBlEs));
×
2631
                                if ( spare->tablepointers ) {
×
2632
                                        if ( spare->sparse ) {
×
2633
                                                /* sparse tables */
2634
                                                S_WRITE_B(spare->tablepointers,
×
2635
                                                        spare->reserved*sizeof(WORD)*(spare->numind+TABLEEXTENSION));
2636
                                        }
2637
                                        else {
2638
                                                /* matrix like tables */
2639
                                                S_WRITE_B(spare->tablepointers,
×
2640
                                                        TABLEEXTENSION*sizeof(WORD)*(spare->totind));
×
2641
                                        }
2642
                                }
2643
                                S_WRITE_B(spare->mm, spare->numind*(LONG)sizeof(MINMAX));
×
2644
                                S_WRITE_B(spare->flags, spare->numind*(LONG)sizeof(WORD));
×
2645
                                if ( spare->sparse ) {
×
2646
                                        S_WRITE_B(spare->boomlijst, spare->MaxTreeSize*(LONG)sizeof(COMPTREE));
×
2647
                                }
2648
                                S_WRITE_B(spare->buffers, spare->bufferssize*(LONG)sizeof(WORD));
×
2649
                        }
2650
                }
2651
        }
2652

2653
        ANNOUNCE(AC.ExpressionList)
2654
        S_WRITE_LIST(AC.ExpressionList);
×
2655
        for ( i=0; i<AC.ExpressionList.num; ++i ) {
×
2656
                EXPRESSIONS ex = Expressions + i;
×
2657
                if ( ex->renum ) {
×
2658
                        S_WRITE_B(ex->renum, sizeof(struct ReNuMbEr));
×
2659
                        /* there is one dynamically allocated buffer for struct ReNuMbEr and
2660
                         * symb.lo points to its beginning. the size of the buffer is not
2661
                         * stored anywhere but we know it is 2*sizeof(WORD)*N, where N is
2662
                         * the number of all vectors, indices, functions and symbols. since
2663
                         * funum points into the buffer at a distance 2N-[Number of
2664
                         * functions] from symb.lo (see GetTable() in store.c), we can
2665
                         * calculate the buffer size by some pointer arithmetic. the size is
2666
                         * then written to the file. */
2667
                        l = ex->renum->funnum - ex->renum->symb.lo;
×
2668
                        l += ex->renum->funnum - ex->renum->func.lo;
×
2669
                        S_WRITE_B(&l, sizeof(size_t));
×
2670
                        S_WRITE_B(ex->renum->symb.lo, l);
×
2671
                }
2672
                if ( ex->bracketinfo ) {
×
2673
                        S_WRITE_B(ex->bracketinfo, sizeof(BRACKETINFO));
×
2674
                        S_WRITE_B(ex->bracketinfo->indexbuffer, ex->bracketinfo->indexbuffersize*sizeof(BRACKETINDEX));
×
2675
                        S_WRITE_B(ex->bracketinfo->bracketbuffer, ex->bracketinfo->bracketbuffersize*sizeof(WORD));
×
2676
                }
2677
                if ( ex->newbracketinfo ) {
×
2678
                        S_WRITE_B(ex->newbracketinfo, sizeof(BRACKETINFO));
×
2679
                        S_WRITE_B(ex->newbracketinfo->indexbuffer, ex->newbracketinfo->indexbuffersize*sizeof(BRACKETINDEX));
×
2680
                        S_WRITE_B(ex->newbracketinfo->bracketbuffer, ex->newbracketinfo->bracketbuffersize*sizeof(WORD));
×
2681
                }
2682
                /* don't need to write ex->renumlists */
2683
                if ( ex->inmem ) {
×
2684
                        /* size of the inmem buffer has to be determined. we use the fact
2685
                         * that the end of an expression is marked by a zero. */
2686
                        w = ex->inmem;
2687
                        while ( *w++ ) ;
×
2688
                        l = w - ex->inmem;
×
2689
                        S_WRITE_B(&l, sizeof(size_t));
×
2690
                        S_WRITE_B(ex->inmem, l);
×
2691
                }
2692
        }
2693
        
2694
        ANNOUNCE(AC.IndexList)
2695
        S_WRITE_LIST(AC.IndexList);
×
2696
        S_WRITE_LIST(AC.SetElementList);
×
2697
        S_WRITE_LIST(AC.SetList);
×
2698
        S_WRITE_LIST(AC.SymbolList);
×
2699
        S_WRITE_LIST(AC.VectorList);
×
2700

2701
        ANNOUNCE(AC.TableBaseList)
2702
        S_WRITE_LIST(AC.TableBaseList);
×
2703
        for ( i=0; i<AC.TableBaseList.num; ++i ) {
×
2704
                /* see struct dbase in minos.h */
2705
                if ( tablebases[i].iblocks ) {
×
2706
                        S_WRITE_B(tablebases[i].iblocks, tablebases[i].info.numberofindexblocks * sizeof(INDEXBLOCK*));
×
2707
                        for ( j=0; j<tablebases[i].info.numberofindexblocks; ++j ) {
×
2708
                                if ( tablebases[i].iblocks[j] ) {
×
2709
                                        S_WRITE_B(tablebases[i].iblocks[j], sizeof(INDEXBLOCK));
×
2710
                                }
2711
                        }
2712
                }
2713
                if ( tablebases[i].nblocks ) {
×
2714
                        S_WRITE_B(tablebases[i].nblocks, tablebases[i].info.numberofnamesblocks * sizeof(NAMESBLOCK*));
×
2715
                        for ( j=0; j<tablebases[i].info.numberofnamesblocks; ++j ) {
×
2716
                                if ( tablebases[i].nblocks[j] ) {
×
2717
                                        S_WRITE_B(tablebases[i].nblocks[j], sizeof(NAMESBLOCK));
×
2718
                                }
2719
                        }
2720
                }
2721
                S_WRITE_S(tablebases[i].name);
×
2722
                S_WRITE_S(tablebases[i].fullname);
×
2723
                S_WRITE_S(tablebases[i].tablenames);
×
2724
        }
2725

2726
        ANNOUNCE(AC.cbufList)
2727
        S_WRITE_LIST(AC.cbufList);
×
2728
        for ( i=0; i<AC.cbufList.num; ++i ) {
×
2729
                S_WRITE_B(cbuf[i].Buffer, cbuf[i].BufferSize*sizeof(WORD));
×
2730
                /* see inicbufs in comtool.c */
2731
                S_WRITE_B(cbuf[i].lhs, cbuf[i].maxlhs*(LONG)sizeof(WORD*));
×
2732
                S_WRITE_B(cbuf[i].rhs, cbuf[i].maxrhs*(LONG)(sizeof(WORD*)+2*sizeof(LONG)+2*sizeof(WORD)));
×
2733
                if ( cbuf[i].boomlijst ) {
×
2734
                        S_WRITE_B(cbuf[i].boomlijst, cbuf[i].MaxTreeSize*(LONG)sizeof(COMPTREE));
×
2735
                }
2736
        }
2737

2738
        S_WRITE_LIST(AC.AutoSymbolList);
×
2739
        S_WRITE_LIST(AC.AutoIndexList);
×
2740
        S_WRITE_LIST(AC.AutoVectorList);
×
2741
        S_WRITE_LIST(AC.AutoFunctionList);
×
2742

2743
        S_WRITE_NAMETREE(AC.autonames);
×
2744

2745
        ANNOUNCE(AC.Streams)
2746
        S_WRITE_B(AC.Streams, AC.MaxNumStreams*(LONG)sizeof(STREAM));
×
2747
        for ( i=0; i<AC.NumStreams; ++i ) {
×
2748
                if ( AC.Streams[i].inbuffer ) {
×
2749
                        S_WRITE_B(AC.Streams[i].buffer, AC.Streams[i].inbuffer);
×
2750
                }
2751
                S_WRITE_S(AC.Streams[i].FoldName);
×
2752
                S_WRITE_S(AC.Streams[i].name);
×
2753
        }
2754

2755
        if ( AC.termstack ) {
×
2756
                S_WRITE_B(AC.termstack, AC.maxtermlevel*(LONG)sizeof(LONG));
×
2757
        }
2758

2759
        if ( AC.termsortstack ) {
×
2760
                S_WRITE_B(AC.termsortstack, AC.maxtermlevel*(LONG)sizeof(LONG));
×
2761
        }
2762

2763
        S_WRITE_B(AC.cmod, AM.MaxTal*4*(LONG)sizeof(UWORD));
×
2764

2765
        if ( AC.IfHeap ) {
×
2766
                S_WRITE_B(AC.IfHeap, (LONG)sizeof(LONG)*(AC.MaxIf+1));
×
2767
                S_WRITE_B(AC.IfCount, (LONG)sizeof(LONG)*(AC.MaxIf+1));
×
2768
        }
2769

2770
        l = AC.iStop - AC.iBuffer + 2;
×
2771
        S_WRITE_B(AC.iBuffer, l);
×
2772

2773
        if ( AC.LabelNames ) {
×
2774
                S_WRITE_B(AC.LabelNames, AC.MaxLabels*(LONG)(sizeof(UBYTE*)+sizeof(WORD)));
×
2775
                for ( i=0; i<AC.NumLabels; ++i ) {
×
2776
                        S_WRITE_S(AC.LabelNames[i]);
×
2777
                }
2778
        }
2779

2780
        S_WRITE_B(AC.FixIndices, AM.OffsetIndex*(LONG)sizeof(WORD));
×
2781

2782
        if ( AC.termsumcheck ) {
×
2783
                S_WRITE_B(AC.termsumcheck, AC.maxtermlevel*(LONG)sizeof(WORD));
×
2784
        }
2785

2786
        S_WRITE_B(AC.WildcardNames, AC.WildcardBufferSize);
×
2787

2788
        if ( AC.tokens ) {
×
2789
                l = AC.toptokens - AC.tokens;
×
2790
                if ( l ) {
×
2791
                        S_WRITE_B(AC.tokens, l);
×
2792
                }
2793
        }
2794

2795
        S_WRITE_B(AC.tokenarglevel, AM.MaxParLevel*(LONG)sizeof(WORD));
×
2796

2797
        S_WRITE_S(AC.Fortran90Kind);
×
2798
        
2799
#ifdef WITHPTHREADS
2800
        if ( AC.inputnumbers ) {
2801
                S_WRITE_B(AC.inputnumbers, AC.sizepfirstnum*(LONG)(sizeof(WORD)+sizeof(LONG)));
2802
        }
2803
#endif /* ifdef WITHPTHREADS */
2804

2805
        if ( AC.IfSumCheck ) {
×
2806
                S_WRITE_B(AC.IfSumCheck, (LONG)sizeof(WORD)*(AC.MaxIf+1));
×
2807
        }
2808
        if ( AC.CommuteInSet ) {
×
2809
                S_WRITE_B(AC.CommuteInSet, (LONG)sizeof(WORD)*(AC.SizeCommuteInSet+1));
×
2810
        }
2811

2812
        S_WRITE_S(AC.CheckpointRunAfter);
×
2813
        S_WRITE_S(AC.CheckpointRunBefore);
×
2814

2815
        S_WRITE_S(AC.extrasym);
×
2816

2817
        /*#] AC :*/ 
2818
        /*#[ AP :*/
2819

2820
        /* we write AP as a whole and then write all additional data step by step. */
2821

2822
        ANNOUNCE(AP)
2823
        S_WRITE_B(&AP, sizeof(struct P_const));
×
2824

2825
        S_WRITE_LIST(AP.DollarList);
×
2826
        for ( i=0; i<AP.DollarList.num; ++i ) {
×
2827
                DOLLARS d = Dollars + i;
×
2828
                S_WRITE_DOLLAR(Dollars[i]);
×
2829
                if ( d->nfactors > 1 ) {
×
2830
                        S_WRITE_B(&(d->factors),sizeof(FACDOLLAR)*d->nfactors);
×
2831
                        for ( j = 0; j < d->nfactors; j++ ) {
×
2832
                                if ( d->factors[j].size > 0 ) {
×
2833
                                        S_WRITE_B(&(d->factors[i].where),sizeof(WORD)*(d->factors[j].size+1));
×
2834
                                }
2835
                        }
2836
                }
2837
        }
2838

2839
        S_WRITE_LIST(AP.PreVarList);
×
2840
        for ( i=0; i<AP.PreVarList.num; ++i ) {
×
2841
                /* there is one dynamically allocated buffer in struct pReVaR holding
2842
                 * the strings name, value and several argnames. the size of the buffer
2843
                 * can be calculated by adding up their string lengths. */
2844
                l = strlen((char*)PreVar[i].name) + 1;
×
2845
                if ( PreVar[i].value ) {
×
2846
                        l += strlen((char*)(PreVar[i].name+l)) + 1;
×
2847
                }
2848
                for ( j=0; j<PreVar[i].nargs; ++j ) {
×
2849
                        l += strlen((char*)(PreVar[i].name+l)) + 1;
×
2850
                }
2851
                S_WRITE_B(&l, sizeof(size_t));
×
2852
                S_WRITE_B(PreVar[i].name, l);
×
2853
        }
2854

2855
        ANNOUNCE(AP.LoopList)
2856
        S_WRITE_LIST(AP.LoopList);
×
2857
        for ( i=0; i<AP.LoopList.num; ++i ) {
×
2858
                S_WRITE_B(DoLoops[i].p.buffer, DoLoops[i].p.size);
×
2859
                if ( DoLoops[i].type == ONEEXPRESSION ) {
×
2860
                        /* do loops with an expression keep this expression in a dynamically
2861
                         * allocated buffer in dollarname */
2862
                        S_WRITE_S(DoLoops[i].dollarname);
×
2863
                }
2864
        }
2865

2866
        S_WRITE_LIST(AP.ProcList);
×
2867
        for ( i=0; i<AP.ProcList.num; ++i ) {
×
2868
                if ( Procedures[i].p.size ) {
×
2869
                        if ( Procedures[i].loadmode != 1 ) {
×
2870
                                S_WRITE_B(Procedures[i].p.buffer, Procedures[i].p.size);
×
2871
                        }
2872
                        else {
2873
                                for ( j=0; j<AP.ProcList.num; ++j ) {
×
2874
                                        if ( Procedures[i].p.buffer == Procedures[j].p.buffer ) {
×
2875
                                                break;
2876
                                        }
2877
                                }
2878
                                if ( j == AP.ProcList.num ) {
×
2879
                                        MesPrint("Error writing procedures to recovery file!");
×
2880
                                }
2881
                                S_WRITE_B(&j, sizeof(int));
×
2882
                        }
2883
                }
2884
                S_WRITE_S(Procedures[i].name);
×
2885
        }
2886

2887
        S_WRITE_B(AP.PreSwitchStrings, (AP.NumPreSwitchStrings+1)*(LONG)sizeof(UBYTE*));
×
2888
        for ( i=1; i<=AP.PreSwitchLevel; ++i ) {
×
2889
                S_WRITE_S(AP.PreSwitchStrings[i]);
×
2890
        }
2891

2892
        S_WRITE_B(AP.preStart, AP.pSize);
×
2893
        
2894
        S_WRITE_S(AP.procedureExtension);
×
2895
        S_WRITE_S(AP.cprocedureExtension);
×
2896

2897
        S_WRITE_B(AP.PreAssignStack, AP.MaxPreAssignLevel*(LONG)sizeof(LONG));
×
2898
        S_WRITE_B(AP.PreIfStack, AP.MaxPreIfLevel*(LONG)sizeof(int));
×
2899
        S_WRITE_B(AP.PreSwitchModes, (AP.NumPreSwitchStrings+1)*(LONG)sizeof(int));
×
2900
        S_WRITE_B(AP.PreTypes, (AP.MaxPreTypes+1)*(LONG)sizeof(int));
×
2901

2902
        /*#] AP :*/ 
2903
        /*#[ AR :*/
2904

2905
        ANNOUNCE(AR)
2906
        /* to remember which entry in AR.Fscr corresponds to the infile */
2907
        l = AR.infile - AR.Fscr;
×
2908
        S_WRITE_B(&l, sizeof(LONG));
×
2909
        
2910
        /* write the FILEHANDLEs */
2911
        S_WRITE_B(AR.outfile, sizeof(FILEHANDLE));
×
2912
        l = AR.outfile->POfull - AR.outfile->PObuffer;
×
2913
        if ( l ) {
×
2914
                S_WRITE_B(AR.outfile->PObuffer, l*sizeof(WORD));
×
2915
        }
2916
        S_WRITE_B(AR.hidefile, sizeof(FILEHANDLE));
×
2917
        l = AR.hidefile->POfull - AR.hidefile->PObuffer;
×
2918
        if ( l ) {
×
2919
                S_WRITE_B(AR.hidefile->PObuffer, l*sizeof(WORD));
×
2920
        }
2921

2922
        S_WRITE_B(&AR.StoreData.Fill, sizeof(POSITION));
×
2923
        if ( ISNOTZEROPOS(AR.StoreData.Fill) ) {
×
2924
                S_WRITE_B(&AR.StoreData, sizeof(FILEDATA));
×
2925
        }
2926

2927
        S_WRITE_B(&AR.DefPosition, sizeof(POSITION));
×
2928

2929
        l = TimeCPU(1); l = -l;
×
2930
        S_WRITE_B(&l, sizeof(LONG));
×
2931

2932
        ANNOUNCE(AR.InInBuf)
2933
        S_WRITE_B(&AR.InInBuf, sizeof(LONG));
×
2934
        S_WRITE_B(&AR.InHiBuf, sizeof(LONG));
×
2935
        
2936
        S_WRITE_B(&AR.NoCompress, sizeof(int));
×
2937
        S_WRITE_B(&AR.gzipCompress, sizeof(int));
×
2938
        
2939
        S_WRITE_B(&AR.outtohide, sizeof(int));
×
2940

2941
        S_WRITE_B(&AR.GetFile, sizeof(WORD));
×
2942
        S_WRITE_B(&AR.KeptInHold, sizeof(WORD));
×
2943
        S_WRITE_B(&AR.BracketOn, sizeof(WORD));
×
2944
        S_WRITE_B(&AR.MaxBracket, sizeof(WORD));
×
2945
        S_WRITE_B(&AR.CurDum, sizeof(WORD));
×
2946
        S_WRITE_B(&AR.DeferFlag, sizeof(WORD));
×
2947
        S_WRITE_B(&AR.TePos, sizeof(WORD));
×
2948
        S_WRITE_B(&AR.sLevel, sizeof(WORD));
×
2949
        S_WRITE_B(&AR.Stage4Name, sizeof(WORD));
×
2950
        S_WRITE_B(&AR.GetOneFile, sizeof(WORD));
×
2951
        S_WRITE_B(&AR.PolyFun, sizeof(WORD));
×
2952
        S_WRITE_B(&AR.PolyFunInv, sizeof(WORD));
×
2953
        S_WRITE_B(&AR.PolyFunType, sizeof(WORD));
×
2954
        S_WRITE_B(&AR.PolyFunExp, sizeof(WORD));
×
2955
        S_WRITE_B(&AR.PolyFunVar, sizeof(WORD));
×
2956
        S_WRITE_B(&AR.PolyFunPow, sizeof(WORD));
×
2957
        S_WRITE_B(&AR.Eside, sizeof(WORD));
×
2958
        S_WRITE_B(&AR.MaxDum, sizeof(WORD));
×
2959
        S_WRITE_B(&AR.level, sizeof(WORD));
×
2960
        S_WRITE_B(&AR.expchanged, sizeof(WORD));
×
2961
        S_WRITE_B(&AR.expflags, sizeof(WORD));
×
2962
        S_WRITE_B(&AR.CurExpr, sizeof(WORD));
×
2963
        S_WRITE_B(&AR.SortType, sizeof(WORD));
×
2964
        S_WRITE_B(&AR.ShortSortCount, sizeof(WORD));
×
2965

2966
#ifdef WITHPTHREADS
2967
        for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
2968
                S_WRITE_B(&(AB[j]->R.wranfnpair1), sizeof(int));
2969
                S_WRITE_B(&(AB[j]->R.wranfnpair2), sizeof(int));
2970
                S_WRITE_B(&(AB[j]->R.wranfcall), sizeof(int));
2971
                S_WRITE_B(&(AB[j]->R.wranfseed), sizeof(ULONG));
2972
                S_WRITE_B(&(AB[j]->R.wranfia),sizeof(ULONG *));
2973
                if ( AB[j]->R.wranfia ) {
2974
                        S_WRITE_B(AB[j]->R.wranfia, sizeof(ULONG)*AB[j]->R.wranfnpair2);
2975
                }
2976
        }
2977
#else
2978
        S_WRITE_B(&(AR.wranfnpair1), sizeof(int));
2979
        S_WRITE_B(&(AR.wranfnpair2), sizeof(int));
2980
        S_WRITE_B(&(AR.wranfcall), sizeof(int));
2981
        S_WRITE_B(&(AR.wranfseed), sizeof(ULONG));
2982
        S_WRITE_B(&(AR.wranfia),sizeof(ULONG *));
2983
        if ( AR.wranfia ) {
2984
                S_WRITE_B(AR.wranfia, sizeof(ULONG)*AR.wranfnpair2);
2985
        }
2986
#endif
2987

2988
        /*#] AR :*/ 
2989
        /*#[ AO :*/
2990
/*
2991
        We copy all non-pointer variables.
2992
*/
2993
        ANNOUNCE(AO)
2994
        l = sizeof(A.O) - ((UBYTE *)(&(A.O.NumInBrack))-(UBYTE *)(&A.O));
×
2995
        S_WRITE_B(&(A.O.NumInBrack),l);
×
2996
/*
2997
        Now the variables in OptimizeResult
2998
*/
2999
        S_WRITE_B(&(A.O.OptimizeResult),sizeof(OPTIMIZERESULT));
×
3000
        if ( A.O.OptimizeResult.codesize > 0 ) {
×
3001
                S_WRITE_B(A.O.OptimizeResult.code,A.O.OptimizeResult.codesize*sizeof(WORD));
×
3002
        }
3003
        S_WRITE_S(A.O.OptimizeResult.nameofexpr);
×
3004
/*
3005
        And now the dictionaries.
3006
        We write each dictionary to a buffer and get the size of that buffer.
3007
        Then we write the size and the buffer.
3008
*/
3009
        for ( i = 0; i < AO.NumDictionaries; i++ ) {
×
3010
                l = DictToBytes(AO.Dictionaries[i],(UBYTE *)(AT.WorkPointer));
×
3011
                S_WRITE_B(&l,sizeof(LONG));
×
3012
                S_WRITE_B(AT.WorkPointer,l);
×
3013
        }
3014

3015
        /*#] AO :*/ 
3016
        /*#[ PF :*/
3017
#ifdef WITHMPI
3018
        S_WRITE_B(&PF.numtasks, sizeof(int));
3019
        S_WRITE_B(&PF.rhsInParallel, sizeof(int));
3020
        S_WRITE_B(&PF.exprbufsize, sizeof(int));
3021
        S_WRITE_B(&PF.log, sizeof(int));
3022
#endif
3023
        /*#] PF :*/ 
3024

3025
#ifdef WITHPTHREADS
3026

3027
        ANNOUNCE(GetTimerInfo)
3028
/*
3029
        write timing information of individual threads
3030
*/
3031
        i = GetTimerInfo(&longp,&longpp);
3032
        S_WRITE_B(&i, sizeof(int));
3033
        S_WRITE_B(longp, i*(LONG)sizeof(LONG));
3034
        S_WRITE_B(&i, sizeof(int));
3035
        S_WRITE_B(longpp, i*(LONG)sizeof(LONG));
3036

3037
#endif
3038

3039
        S_FLUSH_B /* because we will call fwrite() directly in the following code */
×
3040

3041
        /* save length of data at the beginning of the file */
3042
        ANNOUNCE(file length)
3043
        SETBASEPOSITION(pos, (ftell(fd)));
×
3044
        fseek(fd, 0, SEEK_SET);
×
3045
        if ( fwrite(&pos, 1, sizeof(POSITION), fd) != sizeof(POSITION) ) return(__LINE__);
×
3046
        fseek(fd, BASEPOSITION(pos), SEEK_SET);
×
3047

3048
        ANNOUNCE(file close)
3049
        if ( fclose(fd) ) return(__LINE__);
×
3050
#ifdef WITHMPI
3051
        if ( PF.me == MASTER ) {
3052
#endif
3053
/*
3054
                copy store file if necessary
3055
*/
3056
                ANNOUNCE(copy store file)
3057
                if ( ISNOTZEROPOS(AR.StoreData.Fill) ) {
×
3058
                        if ( CopyFile(FG.fname, storefile) ) return(__LINE__);
×
3059
                }
3060
/*
3061
                copy sort file if necessary
3062
*/
3063
                ANNOUNCE(copy sort file)
3064
                if ( AR.outfile->handle >= 0 ) {
×
3065
                        if ( CopyFile(AR.outfile->name, sortfile) ) return(__LINE__);
×
3066
                }
3067
/*
3068
                copy hide file if necessary
3069
*/
3070
                ANNOUNCE(copy hide file)
3071
                if ( AR.hidefile->handle >= 0 ) {
×
3072
                        if ( CopyFile(AR.hidefile->name, hidefile) ) return(__LINE__);
×
3073
                }
3074
#ifdef WITHMPI
3075
        }
3076
        /*
3077
         * For ParFORM, the renaming will be performed after the master got
3078
         * all recovery files from the slaves.
3079
         */
3080
#else
3081
/*
3082
        make the intermediate file the recovery file
3083
*/
3084
        ANNOUNCE(rename intermediate file)
3085
        if ( rename(intermedfile, recoveryfile) ) return(__LINE__);
×
3086

3087
        done_snapshot = 1;
×
3088

3089
        MesPrint("done."); fflush(0);
×
3090
#endif
3091

3092
#ifdef PRINTDEBUG
3093
        print_M();
3094
        print_C();
3095
        print_P();
3096
        print_R();
3097
#endif
3098

3099
        return(0);
×
3100
}
3101

3102
/*
3103
          #] DoSnapshot : 
3104
          #[ DoCheckpoint :
3105
*/
3106

3107
/**
3108
 *  Checks whether a snapshot should be done. Calls DoSnapshot() to create the
3109
 *  snapshot.
3110
 */
3111
void DoCheckpoint(int moduletype)
×
3112
{
3113
        int error;
×
3114
        LONG timestamp = TimeWallClock(1);
×
3115
#ifdef WITHMPI
3116
        if(PF.me == MASTER){
3117
#endif
3118
        if ( timestamp - AC.CheckpointStamp >= AC.CheckpointInterval ) {
×
3119
                char argbuf[20];
×
3120
                int retvalue = 0;
×
3121
                if ( AC.CheckpointRunBefore ) {
×
3122
                        size_t l, l2;
×
3123
                        char *str;
×
3124
                        l = strlen(AC.CheckpointRunBefore);
×
3125
                        NumToStr((UBYTE*)argbuf, AC.CModule);
×
3126
                        l2 = strlen(argbuf);
×
3127
                        str = (char*)Malloc1(l+l2+2, "callbefore");
×
3128
                        strcpy(str, AC.CheckpointRunBefore);
×
3129
                        *(str+l) = ' ';
×
3130
                        strcpy(str+l+1, argbuf);
×
3131
                        retvalue = system(str);
×
3132
                        M_free(str, "callbefore");
×
3133
                        if ( retvalue ) {
×
3134
                                MesPrint("Script returned error -> no recovery file will be created.");
×
3135
                        }
3136
                }
3137
#ifdef WITHMPI
3138
                /* Confirm slaves to make snapshots. */
3139
                PF_BroadcastNumber(retvalue == 0);
3140
#endif
3141
                if ( retvalue == 0 ) {
×
3142
                        if ( (error = DoSnapshot(moduletype)) ) {
×
3143
                                MesPrint("Error creating recovery files: %d", error);
×
3144
                        }
3145
#ifdef WITHMPI
3146
                        {
3147
                        int i;
3148
                        /*get recovery files from slaves:*/
3149
                        for(i=1; i<PF.numtasks;i++){
3150
                                FILE *fd;
3151
                                const char *tmpnam = PF_recoveryfile('m', i, 1);
3152
                                fd = fopen(tmpnam, "w");
3153
                                if(fd == NULL){
3154
                                        MesPrint("Error opening recovery file for slave %d",i);
3155
                                        Terminate(-1);
3156
                                }/*if(fd == NULL)*/
3157
                                retvalue=PF_RecvFile(i,fd);
3158
                                if(retvalue<=0){
3159
                                        MesPrint("Error receiving recovery file from slave %d",i);
3160
                                        Terminate(-1);
3161
                                }/*if(retvalue<=0)*/
3162
                                fclose(fd);
3163
                        }/*for(i=0; i<PF.numtasks;i++)*/
3164
                        /*
3165
                         * Make the intermediate files the recovery files.
3166
                         */
3167
                        ANNOUNCE(rename intermediate file)
3168
                        for ( i = 0; i < PF.numtasks; i++ ) {
3169
                                const char *src = PF_recoveryfile('m', i, 1);
3170
                                const char *dst = PF_recoveryfile('m', i, 0);
3171
                                if ( rename(src, dst) ) {
3172
                                        MesPrint("Error renaming recovery file %s -> %s", src, dst);
3173
                                }
3174
                        }
3175
                        done_snapshot = 1;
3176
                        MesPrint("done."); fflush(0);
3177
                        }
3178
#endif
3179
                }
3180
                if ( AC.CheckpointRunAfter ) {
×
3181
                        size_t l, l2;
×
3182
                        char *str;
×
3183
                        l = strlen(AC.CheckpointRunAfter);
×
3184
                        NumToStr((UBYTE*)argbuf, AC.CModule);
×
3185
                        l2 = strlen(argbuf);
×
3186
                        str = (char*)Malloc1(l+l2+2, "callafter");
×
3187
                        strcpy(str, AC.CheckpointRunAfter);
×
3188
                        *(str+l) = ' ';
×
3189
                        strcpy(str+l+1, argbuf);
×
3190
                        retvalue = system(str);
×
3191
                        M_free(str, "callafter");
×
3192
                        if ( retvalue ) {
×
3193
                                MesPrint("Error calling script after recovery.");
×
3194
                        }
3195
                }
3196
                AC.CheckpointStamp = TimeWallClock(1);
×
3197
        }
3198
#ifdef WITHMPI
3199
        else{/* timestamp - AC.CheckpointStamp < AC.CheckpointInterval*/
3200
                /* The slaves don't need to make snapshots. */
3201
                PF_BroadcastNumber(0);
3202
        }
3203
        }/*if(PF.me == MASTER)*/
3204
        else{/*Slave*/
3205
                int i;
3206
                /* Check if the slave needs to make a snapshot. */
3207
                if ( PF_BroadcastNumber(0) ) {
3208
                        error = DoSnapshot(moduletype);
3209
                        if(error == 0){
3210
                                FILE *fd;
3211
                                /*
3212
                                 * Send the recovery file to the master. Note that no renaming
3213
                                 * has been performed and what we have to send is actually sitting
3214
                                 * in the intermediate file.
3215
                                 */
3216
                                fd = fopen(intermedfile, "r");
3217
                                i=PF_SendFile(MASTER, fd);/*if fd==NULL, PF_SendFile seds to a slave the failure tag*/
3218
                                if(fd == NULL)
3219
                                        Terminate(-1);
3220
                                fclose(fd);
3221
                                if(i<=0)
3222
                                        Terminate(-1);
3223
                                /*Now the slave need not the recovery file so remove it:*/
3224
                                remove(intermedfile);
3225
                        }
3226
                        else{
3227
                                /*send the error tag to the master:*/
3228
                                PF_SendFile(MASTER,NULL);/*if fd==NULL, PF_SendFile seds to a slave the failure tag*/
3229
                                Terminate(-1);
3230
                        }
3231
                        done_snapshot = 1;
3232
                }/*if(tag=PF_DATA_MSGTAG)*/
3233
        }/*if(PF.me != MASTER)*/
3234
#endif
3235
}
×
3236

3237
/*
3238
          #] DoCheckpoint : 
3239
*/
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