FORM v5.0.1-23-g7a8f756
checkpoint.c
Go to the documentation of this file.
1/*
2 #[ Explanations :
3*/
52/*
53 #] Explanations :
54 #[ License :
55 *
56 * Copyright (C) 1984-2026 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/* UNFINISHED_FEATURE_EXCL_START */
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
104#ifdef WITHMPI
105#define BASENAME_FMT "%c%04dFORMrecv"
111static char BaseName[] = BASENAME_FMT;
112#else
113static char *BaseName = "FORMrecv";
114#endif
118static char *recoveryfile = 0;
124static char *intermedfile = 0;
128static char *sortfile = 0;
132static char *hidefile = 0;
136static char *storefile = 0;
137
142static int done_snapshot = 0;
143
144#ifdef WITHMPI
149static int PF_fmt_pos;
150
155static 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
191#ifdef WITHMPI
192
198static 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);
207 }
208 else {
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.",
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
279{
280 int ret = 0;
281#ifdef WITHMPI
282 ret = PF_CheckRecoveryFile();
283#else
284 FILE *fd;
285 if ( (fd = fopen(recoveryfile, "r")) ) {
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 ) {
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 ) {
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);
322}
323
324/*
325 #] CheckRecoveryFile :
326 #[ DeleteRecoveryFile :
327*/
328
334{
335 if ( done_snapshot ) {
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}
355
356/*
357 #] DeleteRecoveryFile :
358 #[ RecoveryFilename :
359*/
360
365{
366 return(recoveryfile);
367}
368
369/*
370 #] RecoveryFilename :
371 #[ InitRecovery :
372*/
373
377static char *InitName(char *str, char *ext)
378{
379 char *s, *d = str;
380 if ( AM.TempDir ) {
381 s = (char*)AM.TempDir;
382 while ( *s ) { *d++ = *s++; }
383 *d++ = SEPARATOR;
384 }
385 s = BaseName;
386 while ( *s ) { *d++ = *s++; }
387 *d++ = '.';
388 s = ext;
389 while ( *s ) { *d++ = *s++; }
390 *d++ = 0;
391 return d;
392}
393
399void InitRecovery(void)
400{
401 int lenpath = AM.TempDir ? strlen((char*)AM.TempDir)+1 : 0;
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");
409 intermedfile = InitName(recoveryfile, "tmp");
410 sortfile = InitName(intermedfile, "XXX");
411 hidefile = InitName(sortfile, "out");
412 storefile = InitName(hidefile, "hid");
413 InitName(storefile, "str");
414}
415
416/*
417 #] InitRecovery :
418 #[ Debugging :
419*/
420
421#ifdef PRINTDEBUG
422
423void 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
432static void print_STR(UBYTE *p)
433{
434 if ( p ) {
435 MesPrint("%s", (char*)p);
436 }
437 else {
438 MesPrint("NULL");
439 }
440}
441
442static 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
455static 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
472static 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
484static 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
501static 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
521static 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
541static 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
549static 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
558static 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
572static 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
584static 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
605static 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
614static 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
636void 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
660static 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
691static 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
848static 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
911static 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
1151static 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
1219unsigned char cache_buffer[CACHE_SIZE];
1220size_t cache_fill = 0;
1221
1222size_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
1247size_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
1260size_t fwrite_cached(const void *ptr, size_t size, size_t nmemb, FILE *fd)
1261{
1262 return fwrite(ptr, size, nmemb, fd);
1263}
1264
1265size_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
1367time_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
1402int 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 ) {
1424 fclose(fd);
1425 return(__LINE__);
1426 }
1427 size = BASEPOSITION(pos) - sizeof(POSITION);
1428 buf = Malloc1(size, "recovery buffer");
1429 if ( fread(buf, size, 1, fd) != 1 ) {
1430 fclose(fd);
1431 return(__LINE__);
1432 }
1433
1434 /* pointer p will go through the buffer in the following */
1435 p = buf;
1436
1437 /* read moduletype */
1438 R_SET(*moduletype, int);
1439
1440 /*#[ AM : */
1441
1442 /* only certain elements will be restored. the rest of AM should have gotten
1443 * the correct values at startup. */
1444
1445 R_SET(AM.hparallelflag, int);
1446 R_SET(AM.gparallelflag, int);
1447 R_SET(AM.gCodesFlag, int);
1448 R_SET(AM.gNamesFlag, int);
1449 R_SET(AM.gStatsFlag, int);
1450 R_SET(AM.gTokensWriteFlag, int);
1451 R_SET(AM.gNoSpacesInNumbers, int);
1452 R_SET(AM.gIndentSpace, WORD);
1453 R_SET(AM.gUnitTrace, WORD);
1454 R_SET(AM.gDefDim, int);
1455 R_SET(AM.gDefDim4, int);
1456 R_SET(AM.gncmod, WORD);
1457 R_SET(AM.gnpowmod, WORD);
1458 R_SET(AM.gmodmode, WORD);
1459 R_SET(AM.gOutputMode, WORD);
1460 R_SET(AM.gCnumpows, WORD);
1461 R_SET(AM.gOutputSpaces, WORD);
1462 R_SET(AM.gOutNumberType, WORD);
1463 R_SET(AM.gfunpowers, int);
1464 R_SET(AM.gPolyFun, WORD);
1465 R_SET(AM.gPolyFunInv, WORD);
1466 R_SET(AM.gPolyFunType, WORD);
1467 R_SET(AM.gPolyFunExp, WORD);
1468 R_SET(AM.gPolyFunVar, WORD);
1469 R_SET(AM.gPolyFunPow, WORD);
1470 R_SET(AM.gProcessBucketSize, LONG);
1471 R_SET(AM.OldChildTime, LONG);
1472 R_SET(AM.OldSecTime, LONG);
1473 R_SET(AM.OldMilliTime, LONG);
1474 R_SET(AM.gproperorderflag, int);
1475 R_SET(AM.gThreadBucketSize, LONG);
1476 R_SET(AM.gSizeCommuteInSet, int);
1477 R_SET(AM.gThreadStats, int);
1478 R_SET(AM.gFinalStats, int);
1479 R_SET(AM.gThreadsFlag, int);
1480 R_SET(AM.gThreadBalancing, int);
1481 R_SET(AM.gThreadSortFileSynch, int);
1482 R_SET(AM.gProcessStats, int);
1483 R_SET(AM.gOldParallelStats, int);
1484 R_SET(AM.gSortType, int);
1485 R_SET(AM.gShortStatsMax, WORD);
1486 R_SET(AM.gIsFortran90, int);
1487 R_SET(oldAMdollarzero, void*);
1488 R_FREE(AM.gFortran90Kind);
1489 R_SET(AM.gFortran90Kind,UBYTE *);
1490 R_COPY_S(AM.gFortran90Kind,UBYTE *);
1491
1492 R_COPY_S(AM.gextrasym,UBYTE *);
1493 R_COPY_S(AM.ggextrasym,UBYTE *);
1494
1495 R_SET(AM.PrintTotalSize,int);
1496 R_SET(AM.fbuffersize,int);
1497 R_SET(AM.gOldFactArgFlag,int);
1498 R_SET(AM.ggOldFactArgFlag,int);
1499
1500 R_SET(AM.gnumextrasym,int);
1501 R_SET(AM.ggnumextrasym,int);
1502 R_SET(AM.NumSpectatorFiles,int);
1503 R_SET(AM.SizeForSpectatorFiles,int);
1504 R_SET(AM.gOldGCDflag,int);
1505 R_SET(AM.ggOldGCDflag,int);
1506 R_SET(AM.gWTimeStatsFlag, int);
1507
1508 R_FREE(AM.Path);
1509 R_SET(AM.Path,UBYTE *);
1510 R_COPY_S(AM.Path,UBYTE *);
1511
1512 R_SET(AM.FromStdin, BOOL);
1513 R_SET(AM.IgnoreDeprecation, BOOL);
1514
1515#ifdef PRINTDEBUG
1516 print_M();
1517#endif
1518
1519 /*#] AM : */
1520 /*#[ AC : */
1521
1522 /* #[ AC free pointers */
1523
1524 /* AC will be overwritten by data from the recovery file, therefore
1525 * dynamically allocated memory must be freed first. */
1526
1527 R_FREE_NAMETREE(AC.dollarnames);
1528 R_FREE_NAMETREE(AC.exprnames);
1529 R_FREE_NAMETREE(AC.varnames);
1530 for ( i=0; i<AC.ChannelList.num; ++i ) {
1531 R_FREE(channels[i].name);
1532 }
1533 R_FREE(AC.ChannelList.lijst);
1534 R_FREE(AC.DubiousList.lijst);
1535 for ( i=0; i<AC.FunctionList.num; ++i ) {
1536 TABLES T = functions[i].tabl;
1537 if ( T ) {
1538 R_FREE(T->buffers);
1539 R_FREE(T->mm);
1540 R_FREE(T->flags);
1541 R_FREE(T->prototype);
1542 R_FREE(T->tablepointers);
1543 if ( T->sparse ) {
1544 R_FREE(T->boomlijst);
1545 R_FREE(T->argtail);
1546 }
1547 if ( T->spare ) {
1548 R_FREE(T->spare->buffers);
1549 R_FREE(T->spare->mm);
1550 R_FREE(T->spare->flags);
1551 R_FREE(T->spare->tablepointers);
1552 if ( T->spare->sparse ) {
1553 R_FREE(T->spare->boomlijst);
1554 }
1555 R_FREE(T->spare);
1556 }
1557 R_FREE(T);
1558 }
1559 }
1560 R_FREE(AC.FunctionList.lijst);
1561 for ( i=0; i<AC.ExpressionList.num; ++i ) {
1562 if ( Expressions[i].renum ) {
1563 R_FREE(Expressions[i].renum->symb.lo);
1564 R_FREE(Expressions[i].renum);
1565 }
1566 if ( Expressions[i].bracketinfo ) {
1567 R_FREE(Expressions[i].bracketinfo->indexbuffer);
1568 R_FREE(Expressions[i].bracketinfo->bracketbuffer);
1569 R_FREE(Expressions[i].bracketinfo);
1570 }
1571 if ( Expressions[i].newbracketinfo ) {
1572 R_FREE(Expressions[i].newbracketinfo->indexbuffer);
1573 R_FREE(Expressions[i].newbracketinfo->bracketbuffer);
1574 R_FREE(Expressions[i].newbracketinfo);
1575 }
1576 if ( Expressions[i].renumlists != AN.dummyrenumlist ) {
1577 R_FREE(Expressions[i].renumlists);
1578 }
1579 R_FREE(Expressions[i].inmem);
1580 }
1581 R_FREE(AC.ExpressionList.lijst);
1582 R_FREE(AC.IndexList.lijst);
1583 R_FREE(AC.SetElementList.lijst);
1584 R_FREE(AC.SetList.lijst);
1585 R_FREE(AC.SymbolList.lijst);
1586 R_FREE(AC.VectorList.lijst);
1587 for ( i=0; i<AC.TableBaseList.num; ++i ) {
1588 R_FREE(tablebases[i].iblocks);
1589 R_FREE(tablebases[i].nblocks);
1590 R_FREE(tablebases[i].name);
1591 R_FREE(tablebases[i].fullname);
1592 R_FREE(tablebases[i].tablenames);
1593 }
1594 R_FREE(AC.TableBaseList.lijst);
1595 for ( i=0; i<AC.cbufList.num; ++i ) {
1596 R_FREE(cbuf[i].Buffer);
1597 R_FREE(cbuf[i].lhs);
1598 R_FREE(cbuf[i].rhs);
1599 R_FREE(cbuf[i].boomlijst);
1600 }
1601 R_FREE(AC.cbufList.lijst);
1602 R_FREE(AC.AutoSymbolList.lijst);
1603 R_FREE(AC.AutoIndexList.lijst);
1604 R_FREE(AC.AutoVectorList.lijst);
1605 /* Tables cannot be auto-declared, therefore no extra code here */
1606 R_FREE(AC.AutoFunctionList.lijst);
1607 R_FREE_NAMETREE(AC.autonames);
1608 for ( i=0; i<AC.NumStreams; ++i ) {
1609 R_FREE_STREAM(AC.Streams[i]);
1610 }
1611 R_FREE(AC.Streams);
1612 R_FREE(AC.termstack);
1613 R_FREE(AC.termsortstack);
1614 R_FREE(AC.cmod);
1615 R_FREE(AC.modpowers);
1616 R_FREE(AC.halfmod);
1617 R_FREE(AC.IfHeap);
1618 R_FREE(AC.IfCount);
1619 R_FREE(AC.iBuffer);
1620 for ( i=0; i<AC.NumLabels; ++i ) {
1621 R_FREE(AC.LabelNames[i]);
1622 }
1623 R_FREE(AC.LabelNames);
1624 R_FREE(AC.FixIndices);
1625 R_FREE(AC.termsumcheck);
1626 R_FREE(AC.WildcardNames);
1627 R_FREE(AC.tokens);
1628 R_FREE(AC.tokenarglevel);
1629 R_FREE(AC.modinverses);
1630 R_FREE(AC.Fortran90Kind);
1631#ifdef WITHPTHREADS
1632 R_FREE(AC.inputnumbers);
1633#endif
1634 R_FREE(AC.IfSumCheck);
1635 R_FREE(AC.CommuteInSet);
1636 R_FREE(AC.CheckpointRunAfter);
1637 R_FREE(AC.CheckpointRunBefore);
1638
1639 /* #] AC free pointers */
1640
1641 /* backup some lists in order to restore it to the initial setup */
1642 PotModDolListBackup = AC.PotModDolList;
1643 ModOptDolListBackup = AC.ModOptDolList;
1644 oldLogHandle = AC.LogHandle;
1645
1646 /* first we copy AC as a whole and then restore the pointer structures step
1647 by step. */
1648
1649 AC = *((struct C_const*)p); p = (unsigned char*)p + sizeof(struct C_const);
1650
1651 R_COPY_NAMETREE(AC.dollarnames);
1652 R_COPY_NAMETREE(AC.exprnames);
1653 R_COPY_NAMETREE(AC.varnames);
1654
1655 R_COPY_LIST(AC.ChannelList);
1656 for ( i=0; i<AC.ChannelList.num; ++i ) {
1657 R_COPY_S(channels[i].name,char*);
1658 channels[i].handle = ReOpenFile(channels[i].name);
1659 }
1660 AC.ChannelList.message = "channel buffer";
1661
1662 AC.DubiousList.lijst = 0;
1663 AC.DubiousList.message = "ambiguous variable";
1664 AC.DubiousList.num =
1665 AC.DubiousList.maxnum =
1666 AC.DubiousList.numglobal =
1667 AC.DubiousList.numtemp =
1668 AC.DubiousList.numclear = 0;
1669
1670 R_COPY_LIST(AC.FunctionList);
1671 for ( i=0; i<AC.FunctionList.num; ++i ) {
1672 if ( functions[i].tabl ) {
1673 TABLES tabl;
1674 R_COPY_B(tabl, sizeof(struct TaBlEs), TABLES);
1675 functions[i].tabl = tabl;
1676 if ( tabl->tablepointers ) {
1677 if ( tabl->sparse ) {
1678 R_COPY_B(tabl->tablepointers,
1679 tabl->reserved*sizeof(WORD)*(tabl->numind+TABLEEXTENSION),
1680 WORD*);
1681 }
1682 else {
1683 R_COPY_B(tabl->tablepointers,
1684 TABLEEXTENSION*sizeof(WORD)*(tabl->totind), WORD*);
1685 }
1686 }
1687 org = (UBYTE*)tabl->prototype;
1688#ifdef WITHPTHREADS
1689 R_COPY_B(tabl->prototype, tabl->prototypeSize, WORD**);
1690 ofs = (UBYTE*)tabl->prototype - org;
1691 for ( j=0; j<AM.totalnumberofthreads; ++j ) {
1692 if ( tabl->prototype[j] ) {
1693 tabl->prototype[j] = (WORD*)((UBYTE*)tabl->prototype[j] + ofs);
1694 }
1695 }
1696 if ( tabl->pattern ) {
1697 tabl->pattern = (WORD**)((UBYTE*)tabl->pattern + ofs);
1698 for ( j=0; j<AM.totalnumberofthreads; ++j ) {
1699 if ( tabl->pattern[j] ) {
1700 tabl->pattern[j] = (WORD*)((UBYTE*)tabl->pattern[j] + ofs);
1701 }
1702 }
1703 }
1704#else
1705 ofs = tabl->pattern - tabl->prototype;
1706 R_COPY_B(tabl->prototype, tabl->prototypeSize, WORD*);
1707 if ( tabl->pattern ) {
1708 tabl->pattern = tabl->prototype + ofs;
1709 }
1710#endif
1711 R_COPY_B(tabl->mm, tabl->numind*(LONG)sizeof(MINMAX), MINMAX*);
1712 R_COPY_B(tabl->flags, tabl->numind*(LONG)sizeof(WORD), WORD*);
1713 if ( tabl->sparse ) {
1714 R_COPY_B(tabl->boomlijst, tabl->MaxTreeSize*(LONG)sizeof(COMPTREE), COMPTREE*);
1715 R_COPY_S(tabl->argtail,UBYTE*);
1716 }
1717 R_COPY_B(tabl->buffers, tabl->bufferssize*(LONG)sizeof(WORD), WORD*);
1718 if ( tabl->spare ) {
1719 TABLES spare;
1720 R_COPY_B(spare, sizeof(struct TaBlEs), TABLES);
1721 tabl->spare = spare;
1722 if ( spare->tablepointers ) {
1723 if ( spare->sparse ) {
1724 R_COPY_B(spare->tablepointers,
1725 spare->reserved*sizeof(WORD)*(spare->numind+TABLEEXTENSION),
1726 WORD*);
1727 }
1728 else {
1729 R_COPY_B(spare->tablepointers,
1730 TABLEEXTENSION*sizeof(WORD)*(spare->totind), WORD*);
1731 }
1732 }
1733 spare->prototype = tabl->prototype;
1734 spare->pattern = tabl->pattern;
1735 R_COPY_B(spare->mm, spare->numind*(LONG)sizeof(MINMAX), MINMAX*);
1736 R_COPY_B(spare->flags, spare->numind*(LONG)sizeof(WORD), WORD*);
1737 if ( tabl->sparse ) {
1738 R_COPY_B(spare->boomlijst, spare->MaxTreeSize*(LONG)sizeof(COMPTREE), COMPTREE*);
1739 spare->argtail = tabl->argtail;
1740 }
1741 spare->spare = tabl;
1742 R_COPY_B(spare->buffers, spare->bufferssize*(LONG)sizeof(WORD), WORD*);
1743 }
1744 }
1745 }
1746 AC.FunctionList.message = "function";
1747
1748 R_COPY_LIST(AC.ExpressionList);
1749 for ( i=0; i<AC.ExpressionList.num; ++i ) {
1750 EXPRESSIONS ex = Expressions + i;
1751 if ( ex->renum ) {
1752 R_COPY_B(ex->renum, sizeof(struct ReNuMbEr), RENUMBER);
1753 org = (UBYTE*)ex->renum->symb.lo;
1754 R_SET(size, size_t);
1755 R_COPY_B(ex->renum->symb.lo, size, WORD*);
1756 ofs = (UBYTE*)ex->renum->symb.lo - org;
1757 ex->renum->symb.start = (WORD*)((UBYTE*)ex->renum->symb.start + ofs);
1758 ex->renum->symb.hi = (WORD*)((UBYTE*)ex->renum->symb.hi + ofs);
1759 ex->renum->indi.lo = (WORD*)((UBYTE*)ex->renum->indi.lo + ofs);
1760 ex->renum->indi.start = (WORD*)((UBYTE*)ex->renum->indi.start + ofs);
1761 ex->renum->indi.hi = (WORD*)((UBYTE*)ex->renum->indi.hi + ofs);
1762 ex->renum->vect.lo = (WORD*)((UBYTE*)ex->renum->vect.lo + ofs);
1763 ex->renum->vect.start = (WORD*)((UBYTE*)ex->renum->vect.start + ofs);
1764 ex->renum->vect.hi = (WORD*)((UBYTE*)ex->renum->vect.hi + ofs);
1765 ex->renum->func.lo = (WORD*)((UBYTE*)ex->renum->func.lo + ofs);
1766 ex->renum->func.start = (WORD*)((UBYTE*)ex->renum->func.start + ofs);
1767 ex->renum->func.hi = (WORD*)((UBYTE*)ex->renum->func.hi + ofs);
1768 ex->renum->symnum = (WORD*)((UBYTE*)ex->renum->symnum + ofs);
1769 ex->renum->indnum = (WORD*)((UBYTE*)ex->renum->indnum + ofs);
1770 ex->renum->vecnum = (WORD*)((UBYTE*)ex->renum->vecnum + ofs);
1771 ex->renum->funnum = (WORD*)((UBYTE*)ex->renum->funnum + ofs);
1772 }
1773 if ( ex->bracketinfo ) {
1774 R_COPY_B(ex->bracketinfo, sizeof(BRACKETINFO), BRACKETINFO*);
1775 R_COPY_B(ex->bracketinfo->indexbuffer, ex->bracketinfo->indexbuffersize*sizeof(BRACKETINDEX), BRACKETINDEX*);
1776 R_COPY_B(ex->bracketinfo->bracketbuffer, ex->bracketinfo->bracketbuffersize*sizeof(WORD), WORD*);
1777 }
1778 if ( ex->newbracketinfo ) {
1779 R_COPY_B(ex->newbracketinfo, sizeof(BRACKETINFO), BRACKETINFO*);
1780 R_COPY_B(ex->newbracketinfo->indexbuffer, ex->newbracketinfo->indexbuffersize*sizeof(BRACKETINDEX), BRACKETINDEX*);
1781 R_COPY_B(ex->newbracketinfo->bracketbuffer, ex->newbracketinfo->bracketbuffersize*sizeof(WORD), WORD*);
1782 }
1783#ifdef WITHPTHREADS
1784 ex->renumlists = 0;
1785#else
1786 ex->renumlists = AN.dummyrenumlist;
1787#endif
1788 if ( ex->inmem ) {
1789 R_SET(size, size_t);
1790 R_COPY_B(ex->inmem, size, WORD*);
1791 }
1792 }
1793 AC.ExpressionList.message = "expression";
1794
1795 R_COPY_LIST(AC.IndexList);
1796 AC.IndexList.message = "index";
1797 R_COPY_LIST(AC.SetElementList);
1798 AC.SetElementList.message = "set element";
1799 R_COPY_LIST(AC.SetList);
1800 AC.SetList.message = "set";
1801 R_COPY_LIST(AC.SymbolList);
1802 AC.SymbolList.message = "symbol";
1803 R_COPY_LIST(AC.VectorList);
1804 AC.VectorList.message = "vector";
1805
1806 AC.PotModDolList = PotModDolListBackup;
1807 AC.ModOptDolList = ModOptDolListBackup;
1808
1809 R_COPY_LIST(AC.TableBaseList);
1810 for ( i=0; i<AC.TableBaseList.num; ++i ) {
1811 if ( tablebases[i].iblocks ) {
1812 R_COPY_B(tablebases[i].iblocks, tablebases[i].info.numberofindexblocks*sizeof(INDEXBLOCK*),INDEXBLOCK**);
1813 for ( j=0; j<tablebases[i].info.numberofindexblocks; ++j ) {
1814 if ( tablebases[i].iblocks[j] ) {
1815 R_COPY_B(tablebases[i].iblocks[j], sizeof(INDEXBLOCK), INDEXBLOCK*);
1816 }
1817 }
1818 }
1819 if ( tablebases[i].nblocks ) {
1820 R_COPY_B(tablebases[i].nblocks, tablebases[i].info.numberofnamesblocks*sizeof(NAMESBLOCK*),NAMESBLOCK**);
1821 for ( j=0; j<tablebases[i].info.numberofindexblocks; ++j ) {
1822 if ( tablebases[i].nblocks[j] ) {
1823 R_COPY_B(tablebases[i].nblocks[j], sizeof(NAMESBLOCK), NAMESBLOCK*);
1824 }
1825 }
1826 }
1827 /* reopen file */
1828 if ( ( tablebases[i].handle = fopen(tablebases[i].fullname, "r+b") ) == NULL ) {
1829 MesPrint("ERROR: Could not reopen tablebase %s!",tablebases[i].name);
1830 Terminate(-1);
1831 }
1832 R_COPY_S(tablebases[i].name,char*);
1833 R_COPY_S(tablebases[i].fullname,char*);
1834 R_COPY_S(tablebases[i].tablenames,char*);
1835 }
1836 AC.TableBaseList.message = "list of tablebases";
1837
1838 R_COPY_LIST(AC.cbufList);
1839 for ( i=0; i<AC.cbufList.num; ++i ) {
1840 org = (UBYTE*)cbuf[i].Buffer;
1841 R_COPY_B(cbuf[i].Buffer, cbuf[i].BufferSize*sizeof(WORD), WORD*);
1842 ofs = (UBYTE*)cbuf[i].Buffer - org;
1843 cbuf[i].Top = (WORD*)((UBYTE*)cbuf[i].Top + ofs);
1844 cbuf[i].Pointer = (WORD*)((UBYTE*)cbuf[i].Pointer + ofs);
1845 R_COPY_B(cbuf[i].lhs, cbuf[i].maxlhs*(LONG)sizeof(WORD*), WORD**);
1846 for ( j=1; j<=cbuf[i].numlhs; ++j ) {
1847 if ( cbuf[i].lhs[j] ) cbuf[i].lhs[j] = (WORD*)((UBYTE*)cbuf[i].lhs[j] + ofs);
1848 }
1849 org = (UBYTE*)cbuf[i].rhs;
1850 R_COPY_B(cbuf[i].rhs, cbuf[i].maxrhs*(LONG)(sizeof(WORD*)+2*sizeof(LONG)+2*sizeof(WORD)), WORD**);
1851 for ( j=1; j<=cbuf[i].numrhs; ++j ) {
1852 if ( cbuf[i].rhs[j] ) cbuf[i].rhs[j] = (WORD*)((UBYTE*)cbuf[i].rhs[j] + ofs);
1853 }
1854 ofs = (UBYTE*)cbuf[i].rhs - org;
1855 cbuf[i].CanCommu = (LONG*)((UBYTE*)cbuf[i].CanCommu + ofs);
1856 cbuf[i].NumTerms = (LONG*)((UBYTE*)cbuf[i].NumTerms + ofs);
1857 cbuf[i].numdum = (WORD*)((UBYTE*)cbuf[i].numdum + ofs);
1858 cbuf[i].dimension = (WORD*)((UBYTE*)cbuf[i].dimension + ofs);
1859 if ( cbuf[i].boomlijst ) {
1860 R_COPY_B(cbuf[i].boomlijst, cbuf[i].MaxTreeSize*sizeof(COMPTREE), COMPTREE*);
1861 }
1862 }
1863 AC.cbufList.message = "compiler buffer";
1864
1865 R_COPY_LIST(AC.AutoSymbolList);
1866 AC.AutoSymbolList.message = "autosymbol";
1867 R_COPY_LIST(AC.AutoIndexList);
1868 AC.AutoIndexList.message = "autoindex";
1869 R_COPY_LIST(AC.AutoVectorList);
1870 AC.AutoVectorList.message = "autovector";
1871 R_COPY_LIST(AC.AutoFunctionList);
1872 AC.AutoFunctionList.message = "autofunction";
1873
1874 R_COPY_NAMETREE(AC.autonames);
1875
1876 AC.Symbols = &(AC.SymbolList);
1877 AC.Indices = &(AC.IndexList);
1878 AC.Vectors = &(AC.VectorList);
1879 AC.Functions = &(AC.FunctionList);
1880 AC.activenames = &(AC.varnames);
1881
1882 org = (UBYTE*)AC.Streams;
1883 R_COPY_B(AC.Streams, AC.MaxNumStreams*(LONG)sizeof(STREAM), STREAM*);
1884 for ( i=0; i<AC.NumStreams; ++i ) {
1885 if ( AC.Streams[i].type != FILESTREAM ) {
1886 UBYTE *org2;
1887 org2 = AC.Streams[i].buffer;
1888 if ( AC.Streams[i].inbuffer ) {
1889 R_COPY_B(AC.Streams[i].buffer, AC.Streams[i].inbuffer, UBYTE*);
1890 }
1891 ofs = AC.Streams[i].buffer - org2;
1892 AC.Streams[i].pointer += ofs;
1893 AC.Streams[i].top += ofs;
1894 }
1895 else {
1896 p = (unsigned char*)p + AC.Streams[i].inbuffer;
1897 }
1898 AC.Streams[i].buffersize = AC.Streams[i].inbuffer;
1899 R_COPY_S(AC.Streams[i].FoldName,UBYTE*);
1900 R_COPY_S(AC.Streams[i].name,UBYTE*);
1901 if ( AC.Streams[i].type == PREVARSTREAM || AC.Streams[i].type == DOLLARSTREAM ) {
1902 AC.Streams[i].pname = AC.Streams[i].name;
1903 }
1904 else if ( AC.Streams[i].type == FILESTREAM ) {
1905 UBYTE *org2;
1906 org2 = AC.Streams[i].buffer;
1907 AC.Streams[i].buffer = (UBYTE*)Malloc1(AC.Streams[i].buffersize, "buffer");
1908 ofs = AC.Streams[i].buffer - org2;
1909 AC.Streams[i].pointer += ofs;
1910 AC.Streams[i].top += ofs;
1911
1912 /* open file except for already opened main input file */
1913 if ( i ) {
1914 AC.Streams[i].handle = OpenFile((char *)(AC.Streams[i].name));
1915 if ( AC.Streams[i].handle == -1 ) {
1916 MesPrint("ERROR: Could not reopen stream %s!",AC.Streams[i].name);
1917 Terminate(-1);
1918 }
1919 }
1920
1921 PUTZERO(pos);
1922 ADDPOS(pos, AC.Streams[i].bufferposition);
1923 SeekFile(AC.Streams[i].handle, &pos, SEEK_SET);
1924
1925 AC.Streams[i].inbuffer = ReadFile(AC.Streams[i].handle, AC.Streams[i].buffer, AC.Streams[i].inbuffer);
1926
1927 SETBASEPOSITION(pos, AC.Streams[i].fileposition);
1928 SeekFile(AC.Streams[i].handle, &pos, SEEK_SET);
1929 }
1930 /*
1931 * Ideally, we should check if we have a type PREREADSTREAM, PREREADSTREAM2, and
1932 * PRECALCSTREAM here. If so, we should free element name and point it
1933 * to the name element of the embracing stream's struct. In practice,
1934 * this is undoable without adding new data to STREAM. Since we create
1935 * only a small memory leak here (some few byte for each existing
1936 * stream of these types) and only once when we do a recovery, we
1937 * tolerate this leak and keep it STREAM as it is.
1938 */
1939 }
1940 ofs = (UBYTE*)AC.Streams - org;
1941 AC.CurrentStream = (STREAM*)((UBYTE*)AC.CurrentStream + ofs);
1942
1943 if ( AC.termstack ) {
1944 R_COPY_B(AC.termstack, AC.maxtermlevel*(LONG)sizeof(LONG), LONG*);
1945 }
1946
1947 if ( AC.termsortstack ) {
1948 R_COPY_B(AC.termsortstack, AC.maxtermlevel*(LONG)sizeof(LONG), LONG*);
1949 }
1950
1951 /* exception: here we also change values from struct AM */
1952 R_COPY_B(AC.cmod, AM.MaxTal*4*(LONG)sizeof(UWORD), UWORD*);
1953 AM.gcmod = AC.cmod + AM.MaxTal;
1954 AC.powmod = AM.gcmod + AM.MaxTal;
1955 AM.gpowmod = AC.powmod + AM.MaxTal;
1956
1957 AC.modpowers = 0;
1958 AC.halfmod = 0;
1959
1960 /* we don't care about AC.ProtoType/WildC */
1961
1962 if ( AC.IfHeap ) {
1963 ofs = AC.IfStack - AC.IfHeap;
1964 R_COPY_B(AC.IfHeap, (LONG)sizeof(LONG)*(AC.MaxIf+1), LONG*);
1965 AC.IfStack = AC.IfHeap + ofs;
1966 R_COPY_B(AC.IfCount, (LONG)sizeof(LONG)*(AC.MaxIf+1), LONG*);
1967 }
1968
1969 org = AC.iBuffer;
1970 size = AC.iStop - AC.iBuffer + 2;
1971 R_COPY_B(AC.iBuffer, size, UBYTE*);
1972 ofs = AC.iBuffer - org;
1973 AC.iPointer += ofs;
1974 AC.iStop += ofs;
1975
1976 if ( AC.LabelNames ) {
1977 org = (UBYTE*)AC.LabelNames;
1978 R_COPY_B(AC.LabelNames, AC.MaxLabels*(LONG)(sizeof(UBYTE*)+sizeof(WORD)), UBYTE**);
1979 for ( i=0; i<AC.NumLabels; ++i ) {
1980 R_COPY_S(AC.LabelNames[i],UBYTE*);
1981 }
1982 ofs = (UBYTE*)AC.LabelNames - org;
1983 AC.Labels = (int*)((UBYTE*)AC.Labels + ofs);
1984 }
1985
1986 R_COPY_B(AC.FixIndices, AM.OffsetIndex*(LONG)sizeof(WORD), WORD*);
1987
1988 if ( AC.termsumcheck ) {
1989 R_COPY_B(AC.termsumcheck, AC.maxtermlevel*(LONG)sizeof(WORD), WORD*);
1990 }
1991
1992 R_COPY_B(AC.WildcardNames, AC.WildcardBufferSize, UBYTE*);
1993
1994 if ( AC.tokens ) {
1995 size = AC.toptokens - AC.tokens;
1996 if ( size ) {
1997 org = (UBYTE*)AC.tokens;
1998 R_COPY_B(AC.tokens, size, SBYTE*);
1999 ofs = (UBYTE*)AC.tokens - org;
2000 AC.endoftokens += ofs;
2001 AC.toptokens += ofs;
2002 }
2003 else {
2004 AC.tokens = 0;
2005 AC.endoftokens = AC.tokens;
2006 AC.toptokens = AC.tokens;
2007 }
2008 }
2009
2010 R_COPY_B(AC.tokenarglevel, AM.MaxParLevel*(LONG)sizeof(WORD), WORD*);
2011
2012 AC.modinverses = 0;
2013
2014 R_COPY_S(AC.Fortran90Kind,UBYTE *);
2015
2016#ifdef WITHPTHREADS
2017 if ( AC.inputnumbers ) {
2018 org = (UBYTE*)AC.inputnumbers;
2019 R_COPY_B(AC.inputnumbers, AC.sizepfirstnum*(LONG)(sizeof(WORD)+sizeof(LONG)), LONG*);
2020 ofs = (UBYTE*)AC.inputnumbers - org;
2021 AC.pfirstnum = (WORD*)((UBYTE*)AC.pfirstnum + ofs);
2022 }
2023 AC.halfmodlock = dummylock;
2024#endif /* ifdef WITHPTHREADS */
2025
2026 if ( AC.IfSumCheck ) {
2027 R_COPY_B(AC.IfSumCheck, (LONG)sizeof(WORD)*(AC.MaxIf+1), WORD*);
2028 }
2029 if ( AC.CommuteInSet ) {
2030 R_COPY_B(AC.CommuteInSet, (LONG)sizeof(WORD)*(AC.SizeCommuteInSet+1), WORD*);
2031 }
2032
2033 AC.LogHandle = oldLogHandle;
2034
2035 R_COPY_S(AC.CheckpointRunAfter,char*);
2036 R_COPY_S(AC.CheckpointRunBefore,char*);
2037
2038 R_COPY_S(AC.extrasym,UBYTE *);
2039
2040#ifdef PRINTDEBUG
2041 print_C();
2042#endif
2043
2044 /*#] AC : */
2045 /*#[ AP : */
2046
2047 /* #[ AP free pointers */
2048
2049 /* AP will be overwritten by data from the recovery file, therefore
2050 * dynamically allocated memory must be freed first. */
2051
2052 for ( i=0; i<AP.DollarList.num; ++i ) {
2053 if ( Dollars[i].size ) {
2054 R_FREE(Dollars[i].where);
2055 }
2056 CleanDollarFactors(Dollars+i);
2057 }
2058 R_FREE(AP.DollarList.lijst);
2059
2060 for ( i=0; i<AP.PreVarList.num; ++i ) {
2061 R_FREE(PreVar[i].name);
2062 }
2063 R_FREE(AP.PreVarList.lijst);
2064
2065 for ( i=0; i<AP.LoopList.num; ++i ) {
2066 R_FREE(DoLoops[i].p.buffer);
2067 if ( DoLoops[i].dollarname ) {
2068 R_FREE(DoLoops[i].dollarname);
2069 }
2070 }
2071 R_FREE(AP.LoopList.lijst);
2072
2073 for ( i=0; i<AP.ProcList.num; ++i ) {
2074 R_FREE(Procedures[i].p.buffer);
2075 R_FREE(Procedures[i].name);
2076 }
2077 R_FREE(AP.ProcList.lijst);
2078
2079 for ( i=1; i<=AP.PreSwitchLevel; ++i ) {
2080 R_FREE(AP.PreSwitchStrings[i]);
2081 }
2082 R_FREE(AP.PreSwitchStrings);
2083 R_FREE(AP.preStart);
2084 R_FREE(AP.procedureExtension);
2085 R_FREE(AP.cprocedureExtension);
2086 R_FREE(AP.PreIfStack);
2087 R_FREE(AP.PreSwitchModes);
2088 R_FREE(AP.PreTypes);
2089
2090 /* #] AP free pointers */
2091
2092 /* first we copy AP as a whole and then restore the pointer structures step
2093 by step. */
2094
2095 AP = *((struct P_const*)p); p = (unsigned char*)p + sizeof(struct P_const);
2096#ifdef WITHPTHREADS
2097 AP.PreVarLock = dummylock;
2098#endif
2099
2100 R_COPY_LIST(AP.DollarList);
2101 for ( i=0; i<AP.DollarList.num; ++i ) {
2102 DOLLARS d = Dollars + i;
2103 size = d->size * sizeof(WORD);
2104 if ( size && d->where && d->where != oldAMdollarzero ) {
2105 R_COPY_B(d->where, size, void*);
2106 }
2107#ifdef WITHPTHREADS
2108 INIRECLOCK(d->pthreadslock);
2109#endif
2110 if ( d->nfactors > 1 ) {
2111 R_COPY_B(d->factors,sizeof(FACDOLLAR)*d->nfactors,FACDOLLAR*);
2112 for ( j = 0; j < d->nfactors; j++ ) {
2113 if ( d->factors[j].size > 0 ) {
2114 R_COPY_B(d->factors[i].where,sizeof(WORD)*(d->factors[j].size+1),WORD*);
2115 }
2116 }
2117 }
2118 }
2119 AP.DollarList.message = "$-variable";
2120
2121 R_COPY_LIST(AP.PreVarList);
2122 for ( i=0; i<AP.PreVarList.num; ++i ) {
2123 R_SET(size, size_t);
2124 org = PreVar[i].name;
2125 R_COPY_B(PreVar[i].name, size, UBYTE*);
2126 ofs = PreVar[i].name - org;
2127 if ( PreVar[i].value ) PreVar[i].value += ofs;
2128 if ( PreVar[i].argnames ) PreVar[i].argnames += ofs;
2129 }
2130 AP.PreVarList.message = "PreVariable";
2131
2132 R_COPY_LIST(AP.LoopList);
2133 for ( i=0; i<AP.LoopList.num; ++i ) {
2134 org = DoLoops[i].p.buffer;
2135 R_COPY_B(DoLoops[i].p.buffer, DoLoops[i].p.size, UBYTE*);
2136 ofs = DoLoops[i].p.buffer - org;
2137 if ( DoLoops[i].name ) DoLoops[i].name += ofs;
2138 if ( DoLoops[i].vars ) DoLoops[i].vars += ofs;
2139 if ( DoLoops[i].contents ) DoLoops[i].contents += ofs;
2140 if ( DoLoops[i].type == ONEEXPRESSION ) {
2141 R_COPY_S(DoLoops[i].dollarname,UBYTE*);
2142 }
2143 }
2144 AP.LoopList.message = "doloop";
2145
2146 R_COPY_LIST(AP.ProcList);
2147 for ( i=0; i<AP.ProcList.num; ++i ) {
2148 if ( Procedures[i].p.size ) {
2149 if ( Procedures[i].loadmode != 1 ) {
2150 R_COPY_B(Procedures[i].p.buffer, Procedures[i].p.size, UBYTE*);
2151 }
2152 else {
2153 R_SET(j, int);
2154 Procedures[i].p.buffer = Procedures[j].p.buffer;
2155 }
2156 }
2157 R_COPY_S(Procedures[i].name,UBYTE*);
2158 }
2159 AP.ProcList.message = "procedure";
2160
2161 size = (AP.NumPreSwitchStrings+1)*(LONG)sizeof(UBYTE*);
2162 R_COPY_B(AP.PreSwitchStrings, size, UBYTE**);
2163 for ( i=1; i<=AP.PreSwitchLevel; ++i ) {
2164 R_COPY_S(AP.PreSwitchStrings[i],UBYTE*);
2165 }
2166
2167 org = AP.preStart;
2168 R_COPY_B(AP.preStart, AP.pSize, UBYTE*);
2169 ofs = AP.preStart - org;
2170 if ( AP.preFill ) AP.preFill += ofs;
2171 if ( AP.preStop ) AP.preStop += ofs;
2172
2173 R_COPY_S(AP.procedureExtension,UBYTE*);
2174 R_COPY_S(AP.cprocedureExtension,UBYTE*);
2175
2176 R_COPY_B(AP.PreAssignStack,AP.MaxPreAssignLevel*(LONG)sizeof(LONG),LONG*);
2177 R_COPY_B(AP.PreIfStack, AP.MaxPreIfLevel*(LONG)sizeof(int), int*);
2178 R_COPY_B(AP.PreSwitchModes, (AP.NumPreSwitchStrings+1)*(LONG)sizeof(int), int*);
2179 R_COPY_B(AP.PreTypes, (AP.MaxPreTypes+1)*(LONG)sizeof(int), int*);
2180
2181#ifdef PRINTDEBUG
2182 print_P();
2183#endif
2184
2185 /*#] AP : */
2186 /*#[ AR : */
2187
2188 R_SET(ofs,LONG);
2189 if ( ofs ) {
2190 AR.infile = AR.Fscr+1;
2191 AR.outfile = AR.Fscr;
2192 AR.hidefile = AR.Fscr+2;
2193 }
2194 else {
2195 AR.infile = AR.Fscr;
2196 AR.outfile = AR.Fscr+1;
2197 AR.hidefile = AR.Fscr+2;
2198 }
2199
2200 /* #[ AR free pointers */
2201
2202 /* Parts of AR will be overwritten by data from the recovery file, therefore
2203 * dynamically allocated memory must be freed first. */
2204
2205 namebufout = AR.outfile->name;
2206 namebufhide = AR.hidefile->name;
2207 R_FREE(AR.outfile->PObuffer);
2208#ifdef WITHZLIB
2209 R_FREE(AR.outfile->zsp);
2210 R_FREE(AR.outfile->ziobuffer);
2211#endif
2212 namebufhide = AR.hidefile->name;
2213 R_FREE(AR.hidefile->PObuffer);
2214#ifdef WITHZLIB
2215 R_FREE(AR.hidefile->zsp);
2216 R_FREE(AR.hidefile->ziobuffer);
2217#endif
2218 /* no files should be opened -> nothing to do with handle */
2219
2220 /* #] AR free pointers */
2221
2222 /* outfile */
2223 R_SET(*AR.outfile, FILEHANDLE);
2224 org = (UBYTE*)AR.outfile->PObuffer;
2225 size = AR.outfile->POfull - AR.outfile->PObuffer;
2226 AR.outfile->PObuffer = (WORD*)Malloc1(AR.outfile->POsize, "PObuffer");
2227 if ( size ) {
2228 memcpy(AR.outfile->PObuffer, p, size*sizeof(WORD));
2229 p = (unsigned char*)p + size*sizeof(WORD);
2230 }
2231 ofs = (UBYTE*)AR.outfile->PObuffer - org;
2232 AR.outfile->POstop = (WORD*)((UBYTE*)AR.outfile->POstop + ofs);
2233 AR.outfile->POfill = (WORD*)((UBYTE*)AR.outfile->POfill + ofs);
2234 AR.outfile->POfull = (WORD*)((UBYTE*)AR.outfile->POfull + ofs);
2235 AR.outfile->name = namebufout;
2236#ifdef WITHPTHREADS
2237 AR.outfile->wPObuffer = AR.outfile->PObuffer;
2238 AR.outfile->wPOstop = AR.outfile->POstop;
2239 AR.outfile->wPOfill = AR.outfile->POfill;
2240 AR.outfile->wPOfull = AR.outfile->POfull;
2241#endif
2242#ifdef WITHZLIB
2243 /* zsp and ziobuffer will be allocated when used */
2244 AR.outfile->zsp = 0;
2245 AR.outfile->ziobuffer = 0;
2246#endif
2247 /* reopen old outfile */
2248#ifdef WITHMPI
2249 if(PF.me==MASTER)
2250#endif
2251 if ( AR.outfile->handle >= 0 ) {
2252 if ( CopyFile(sortfile, AR.outfile->name) ) {
2253 MesPrint("ERROR: Could not copy old output sort file %s!",sortfile);
2254 Terminate(-1);
2255 }
2256 AR.outfile->handle = ReOpenFile(AR.outfile->name);
2257 if ( AR.outfile->handle == -1 ) {
2258 MesPrint("ERROR: Could not reopen output sort file %s!",AR.outfile->name);
2259 Terminate(-1);
2260 }
2261 SeekFile(AR.outfile->handle, &AR.outfile->POposition, SEEK_SET);
2262 }
2263
2264 /* hidefile */
2265 R_SET(*AR.hidefile, FILEHANDLE);
2266 AR.hidefile->name = namebufhide;
2267 if ( AR.hidefile->PObuffer ) {
2268 org = (UBYTE*)AR.hidefile->PObuffer;
2269 size = AR.hidefile->POfull - AR.hidefile->PObuffer;
2270 AR.hidefile->PObuffer = (WORD*)Malloc1(AR.hidefile->POsize, "PObuffer");
2271 if ( size ) {
2272 memcpy(AR.hidefile->PObuffer, p, size*sizeof(WORD));
2273 p = (unsigned char*)p + size*sizeof(WORD);
2274 }
2275 ofs = (UBYTE*)AR.hidefile->PObuffer - org;
2276 AR.hidefile->POstop = (WORD*)((UBYTE*)AR.hidefile->POstop + ofs);
2277 AR.hidefile->POfill = (WORD*)((UBYTE*)AR.hidefile->POfill + ofs);
2278 AR.hidefile->POfull = (WORD*)((UBYTE*)AR.hidefile->POfull + ofs);
2279#ifdef WITHPTHREADS
2280 AR.hidefile->wPObuffer = AR.hidefile->PObuffer;
2281 AR.hidefile->wPOstop = AR.hidefile->POstop;
2282 AR.hidefile->wPOfill = AR.hidefile->POfill;
2283 AR.hidefile->wPOfull = AR.hidefile->POfull;
2284#endif
2285 }
2286#ifdef WITHZLIB
2287 /* zsp and ziobuffer will be allocated when used */
2288 AR.hidefile->zsp = 0;
2289 AR.hidefile->ziobuffer = 0;
2290#endif
2291 /* reopen old hidefile */
2292 if ( AR.hidefile->handle >= 0 ) {
2293 if ( CopyFile(hidefile, AR.hidefile->name) ) {
2294 MesPrint("ERROR: Could not copy old hide file %s!",hidefile);
2295 Terminate(-1);
2296 }
2297 AR.hidefile->handle = ReOpenFile(AR.hidefile->name);
2298 if ( AR.hidefile->handle == -1 ) {
2299 MesPrint("ERROR: Could not reopen hide file %s!",AR.hidefile->name);
2300 Terminate(-1);
2301 }
2302 SeekFile(AR.hidefile->handle, &AR.hidefile->POposition, SEEK_SET);
2303 }
2304
2305 /* store file */
2306 R_SET(pos, POSITION);
2307 if ( ISNOTZEROPOS(pos) ) {
2308 CloseFile(AR.StoreData.Handle);
2309 R_SET(AR.StoreData, FILEDATA);
2310 if ( CopyFile(storefile, FG.fname) ) {
2311 MesPrint("ERROR: Could not copy old store file %s!",storefile);
2312 Terminate(-1);
2313 }
2314 AR.StoreData.Handle = (WORD)ReOpenFile(FG.fname);
2315 SeekFile(AR.StoreData.Handle, &AR.StoreData.Position, SEEK_SET);
2316 }
2317
2318 R_SET(AR.DefPosition, POSITION);
2319 R_SET(AR.OldTime, LONG);
2320 R_SET(AR.InInBuf, LONG);
2321 R_SET(AR.InHiBuf, LONG);
2322
2323 R_SET(AR.NoCompress, int);
2324 R_SET(AR.gzipCompress, int);
2325
2326 R_SET(AR.outtohide, int);
2327
2328 R_SET(AR.GetFile, WORD);
2329 R_SET(AR.KeptInHold, WORD);
2330 R_SET(AR.BracketOn, WORD);
2331 R_SET(AR.MaxBracket, WORD);
2332 R_SET(AR.CurDum, WORD);
2333 R_SET(AR.DeferFlag, WORD);
2334 R_SET(AR.TePos, WORD);
2335 R_SET(AR.sLevel, WORD);
2336 R_SET(AR.Stage4Name, WORD);
2337 R_SET(AR.GetOneFile, WORD);
2338 R_SET(AR.PolyFun, WORD);
2339 R_SET(AR.PolyFunInv, WORD);
2340 R_SET(AR.PolyFunType, WORD);
2341 R_SET(AR.PolyFunExp, WORD);
2342 R_SET(AR.PolyFunVar, WORD);
2343 R_SET(AR.PolyFunPow, WORD);
2344 R_SET(AR.Eside, WORD);
2345 R_SET(AR.MaxDum, WORD);
2346 R_SET(AR.level, WORD);
2347 R_SET(AR.expchanged, WORD);
2348 R_SET(AR.expflags, WORD);
2349 R_SET(AR.CurExpr, WORD);
2350 R_SET(AR.SortType, WORD);
2351 R_SET(AR.ShortSortCount, WORD);
2352
2353 /* this is usually done in Process(), but sometimes FORM does not
2354 end up executing Process() before it uses the AR.CompressPointer,
2355 so we need to explicitly set it here. */
2356 AR.CompressPointer = AR.CompressBuffer;
2357
2358#ifdef WITHPTHREADS
2359 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
2360 R_SET(AB[j]->R.wranfnpair1, int);
2361 R_SET(AB[j]->R.wranfnpair2, int);
2362 R_SET(AB[j]->R.wranfcall, int);
2363 R_SET(AB[j]->R.wranfseed, ULONG);
2364 R_SET(AB[j]->R.wranfia,ULONG*);
2365 if ( AB[j]->R.wranfia ) {
2366 R_COPY_B(AB[j]->R.wranfia, sizeof(ULONG)*AB[j]->R.wranfnpair2, ULONG*);
2367 }
2368 }
2369#else
2370 R_SET(AR.wranfnpair1, int);
2371 R_SET(AR.wranfnpair2, int);
2372 R_SET(AR.wranfcall, int);
2373 R_SET(AR.wranfseed, ULONG);
2374 R_SET(AR.wranfia,ULONG*);
2375 if ( AR.wranfia ) {
2376 R_COPY_B(AR.wranfia, sizeof(ULONG)*AR.wranfnpair2, ULONG*);
2377 }
2378#endif
2379
2380#ifdef PRINTDEBUG
2381 print_R();
2382#endif
2383
2384 /*#] AR : */
2385 /*#[ AO :*/
2386/*
2387 We copy all non-pointer variables.
2388*/
2389 l = sizeof(A.O) - ((UBYTE *)(&(A.O.NumInBrack))-(UBYTE *)(&A.O));
2390 memcpy(&(A.O.NumInBrack), p, l); p = (unsigned char*)p + l;
2391/*
2392 Now the variables in OptimizeResult
2393*/
2394 memcpy(&(A.O.OptimizeResult),p,sizeof(OPTIMIZERESULT));
2395 p = (unsigned char*)p + sizeof(OPTIMIZERESULT);
2396
2397 if ( A.O.OptimizeResult.codesize > 0 ) {
2398 R_COPY_B(A.O.OptimizeResult.code,A.O.OptimizeResult.codesize*sizeof(WORD),WORD *);
2399 }
2400 R_COPY_S(A.O.OptimizeResult.nameofexpr,UBYTE *);
2401/*
2402 And now the dictionaries. We know how many there are. We also know
2403 how many elements the array AO.Dictionaries should have.
2404*/
2405 if ( AO.SizeDictionaries > 0 ) {
2406 AO.Dictionaries = (DICTIONARY **)Malloc1(AO.SizeDictionaries*sizeof(DICTIONARY *),
2407 "Dictionaries");
2408 for ( i = 0; i < AO.NumDictionaries; i++ ) {
2409 R_SET(l,LONG)
2410 AO.Dictionaries[i] = DictFromBytes(p);
2411 p = (char *)p + l;
2412 }
2413 }
2414 /*#] AO :*/
2415#ifdef WITHMPI
2416 /*#[ PF : */
2417 {/*Block*/
2418 int numtasks;
2419 R_SET(numtasks, int);
2420 if(numtasks!=PF.numtasks){
2421 MesPrint("%d number of tasks expected instead of %d; use mpirun -np %d",
2422 numtasks,PF.numtasks,numtasks);
2423 if(PF.me!=MASTER)
2424 remove(RecoveryFilename());
2425 Terminate(-1);
2426 }
2427 }/*Block*/
2428 R_SET(PF.rhsInParallel, int);
2429 R_SET(PF.exprbufsize, int);
2430 R_SET(PF.log, int);
2431 /*#] PF : */
2432#endif
2433
2434#ifdef WITHPTHREADS
2435 /* read timing information of individual threads */
2436 R_SET(i, int);
2437 for ( j=1; j<AM.totalnumberofthreads; ++j ) {
2438 /* ... and correcting OldTime */
2439 AB[j]->R.OldTime = -(*((LONG*)p+j));
2440 }
2441 WriteTimerInfo((LONG*)p,(LONG *)((unsigned char*)p + i*(LONG)sizeof(LONG)));
2442 p = (unsigned char*)p + 2*i*(LONG)sizeof(LONG);
2443#endif /* ifdef WITHPTHREADS */
2444
2445 if ( fclose(fd) ) return(__LINE__);
2446
2447 M_free(buf,"recovery buffer");
2448
2449 /* cares about data in S_const */
2450 UpdatePositions();
2451 AT.SS = AT.S0;
2452/*
2453 Set the checkpoint parameter right for the next checkpoint.
2454*/
2455 AC.CheckpointStamp = TimeWallClock(1);
2456
2457 done_snapshot = 1;
2458 MesPrint("done."); fflush(0);
2459
2460 return(0);
2461}
2462
2463/*
2464 #] DoRecovery :
2465 #[ DoSnapshot :
2466*/
2467
2483static int DoSnapshot(int moduletype)
2484{
2485 GETIDENTITY
2486 FILE *fd;
2487 POSITION pos = {0};
2488 int i, j;
2489 LONG l;
2490 WORD *w;
2491 void *adr;
2492#ifdef WITHPTHREADS
2493 LONG *longp,*longpp;
2494#endif /* ifdef WITHPTHREADS */
2495
2496 MesPrint("Saving recovery point ... %"); fflush(0);
2497#ifdef PRINTTIMEMARKS
2498 MesPrint("\n");
2499#endif
2500
2501 if ( !(fd = fopen(intermedfile, "wb")) ) return(__LINE__);
2502
2503 /* reserve space in the file for a length field */
2504 if ( fwrite(&pos, 1, sizeof(POSITION), fd) != sizeof(POSITION) ) {
2505 fclose(fd);
2506 return(__LINE__);
2507 }
2508
2509 /* write moduletype */
2510 if ( fwrite(&moduletype, 1, sizeof(int), fd) != sizeof(int) ) {
2511 fclose(fd);
2512 return(__LINE__);
2513 }
2514
2515 /*#[ AM :*/
2516
2517 /* since most values don't change during execution, AM doesn't need to be
2518 * written as a whole. all values will be correctly set when starting up
2519 * anyway. only the exceptions need to be taken care of. see MakeGlobal()
2520 * and PopVariables() in execute.c. */
2521
2522 ANNOUNCE(AM)
2523 S_WRITE_B(&AM.hparallelflag, sizeof(int));
2524 S_WRITE_B(&AM.gparallelflag, sizeof(int));
2525 S_WRITE_B(&AM.gCodesFlag, sizeof(int));
2526 S_WRITE_B(&AM.gNamesFlag, sizeof(int));
2527 S_WRITE_B(&AM.gStatsFlag, sizeof(int));
2528 S_WRITE_B(&AM.gTokensWriteFlag, sizeof(int));
2529 S_WRITE_B(&AM.gNoSpacesInNumbers, sizeof(int));
2530 S_WRITE_B(&AM.gIndentSpace, sizeof(WORD));
2531 S_WRITE_B(&AM.gUnitTrace, sizeof(WORD));
2532 S_WRITE_B(&AM.gDefDim, sizeof(int));
2533 S_WRITE_B(&AM.gDefDim4, sizeof(int));
2534 S_WRITE_B(&AM.gncmod, sizeof(WORD));
2535 S_WRITE_B(&AM.gnpowmod, sizeof(WORD));
2536 S_WRITE_B(&AM.gmodmode, sizeof(WORD));
2537 S_WRITE_B(&AM.gOutputMode, sizeof(WORD));
2538 S_WRITE_B(&AM.gCnumpows, sizeof(WORD));
2539 S_WRITE_B(&AM.gOutputSpaces, sizeof(WORD));
2540 S_WRITE_B(&AM.gOutNumberType, sizeof(WORD));
2541 S_WRITE_B(&AM.gfunpowers, sizeof(int));
2542 S_WRITE_B(&AM.gPolyFun, sizeof(WORD));
2543 S_WRITE_B(&AM.gPolyFunInv, sizeof(WORD));
2544 S_WRITE_B(&AM.gPolyFunType, sizeof(WORD));
2545 S_WRITE_B(&AM.gPolyFunExp, sizeof(WORD));
2546 S_WRITE_B(&AM.gPolyFunVar, sizeof(WORD));
2547 S_WRITE_B(&AM.gPolyFunPow, sizeof(WORD));
2548 S_WRITE_B(&AM.gProcessBucketSize, sizeof(LONG));
2549 S_WRITE_B(&AM.OldChildTime, sizeof(LONG));
2550 S_WRITE_B(&AM.OldSecTime, sizeof(LONG));
2551 S_WRITE_B(&AM.OldMilliTime, sizeof(LONG));
2552 S_WRITE_B(&AM.gproperorderflag, sizeof(int));
2553 S_WRITE_B(&AM.gThreadBucketSize, sizeof(LONG));
2554 S_WRITE_B(&AM.gSizeCommuteInSet, sizeof(int));
2555 S_WRITE_B(&AM.gThreadStats, sizeof(int));
2556 S_WRITE_B(&AM.gFinalStats, sizeof(int));
2557 S_WRITE_B(&AM.gThreadsFlag, sizeof(int));
2558 S_WRITE_B(&AM.gThreadBalancing, sizeof(int));
2559 S_WRITE_B(&AM.gThreadSortFileSynch, sizeof(int));
2560 S_WRITE_B(&AM.gProcessStats, sizeof(int));
2561 S_WRITE_B(&AM.gOldParallelStats, sizeof(int));
2562 S_WRITE_B(&AM.gSortType, sizeof(int));
2563 S_WRITE_B(&AM.gShortStatsMax, sizeof(WORD));
2564 S_WRITE_B(&AM.gIsFortran90, sizeof(int));
2565 adr = &AM.dollarzero;
2566 S_WRITE_B(&adr, sizeof(void*));
2567 S_WRITE_B(&AM.gFortran90Kind,sizeof(UBYTE *));
2568 S_WRITE_S(AM.gFortran90Kind);
2569
2570 S_WRITE_S(AM.gextrasym);
2571 S_WRITE_S(AM.ggextrasym);
2572
2573 S_WRITE_B(&AM.PrintTotalSize,sizeof(int));
2574 S_WRITE_B(&AM.fbuffersize,sizeof(int));
2575 S_WRITE_B(&AM.gOldFactArgFlag,sizeof(int));
2576 S_WRITE_B(&AM.ggOldFactArgFlag,sizeof(int));
2577
2578 S_WRITE_B(&AM.gnumextrasym,sizeof(int));
2579 S_WRITE_B(&AM.ggnumextrasym,sizeof(int));
2580 S_WRITE_B(&AM.NumSpectatorFiles,sizeof(int));
2581 S_WRITE_B(&AM.SizeForSpectatorFiles,sizeof(int));
2582 S_WRITE_B(&AM.gOldGCDflag,sizeof(int));
2583 S_WRITE_B(&AM.ggOldGCDflag,sizeof(int));
2584 S_WRITE_B(&AM.gWTimeStatsFlag, sizeof(int));
2585
2586 S_WRITE_B(&AM.Path,sizeof(UBYTE *));
2587 S_WRITE_S(AM.Path);
2588
2589 S_WRITE_B(&AM.FromStdin,sizeof(BOOL));
2590 S_WRITE_B(&AM.IgnoreDeprecation,sizeof(BOOL));
2591
2592 /*#] AM :*/
2593 /*#[ AC :*/
2594
2595 /* we write AC as a whole and then write all additional data step by step.
2596 * AC.DubiousList doesn't need to be treated, because it should be empty. */
2597
2598 ANNOUNCE(AC)
2599 S_WRITE_B(&AC, sizeof(struct C_const));
2600
2601 S_WRITE_NAMETREE(AC.dollarnames);
2602 S_WRITE_NAMETREE(AC.exprnames);
2603 S_WRITE_NAMETREE(AC.varnames);
2604
2605 S_WRITE_LIST(AC.ChannelList);
2606 for ( i=0; i<AC.ChannelList.num; ++i ) {
2607 S_WRITE_S(channels[i].name);
2608 }
2609
2610 ANNOUNCE(AC.FunctionList)
2611 S_WRITE_LIST(AC.FunctionList);
2612 for ( i=0; i<AC.FunctionList.num; ++i ) {
2613 /* if the function is a table */
2614 if ( functions[i].tabl ) {
2615 TABLES tabl = functions[i].tabl;
2616 S_WRITE_B(tabl, sizeof(struct TaBlEs));
2617 if ( tabl->tablepointers ) {
2618 if ( tabl->sparse ) {
2619 /* sparse tables. reserved holds number of allocated
2620 * elements. the size of an element is numind plus
2621 * TABLEEXTENSION times the size of WORD. */
2622 S_WRITE_B(tabl->tablepointers,
2623 tabl->reserved*sizeof(WORD)*(tabl->numind+TABLEEXTENSION));
2624 }
2625 else {
2626 /* matrix like tables. */
2627 S_WRITE_B(tabl->tablepointers,
2628 TABLEEXTENSION*sizeof(WORD)*(tabl->totind));
2629 }
2630 }
2631 S_WRITE_B(tabl->prototype, tabl->prototypeSize);
2632 S_WRITE_B(tabl->mm, tabl->numind*(LONG)sizeof(MINMAX));
2633 S_WRITE_B(tabl->flags, tabl->numind*(LONG)sizeof(WORD));
2634 if ( tabl->sparse ) {
2635 S_WRITE_B(tabl->boomlijst, tabl->MaxTreeSize*(LONG)sizeof(COMPTREE));
2636 S_WRITE_S(tabl->argtail);
2637 }
2638 S_WRITE_B(tabl->buffers, tabl->bufferssize*(LONG)sizeof(WORD));
2639 if ( tabl->spare ) {
2640 TABLES spare = tabl->spare;
2641 S_WRITE_B(spare, sizeof(struct TaBlEs));
2642 if ( spare->tablepointers ) {
2643 if ( spare->sparse ) {
2644 /* sparse tables */
2645 S_WRITE_B(spare->tablepointers,
2646 spare->reserved*sizeof(WORD)*(spare->numind+TABLEEXTENSION));
2647 }
2648 else {
2649 /* matrix like tables */
2650 S_WRITE_B(spare->tablepointers,
2651 TABLEEXTENSION*sizeof(WORD)*(spare->totind));
2652 }
2653 }
2654 S_WRITE_B(spare->mm, spare->numind*(LONG)sizeof(MINMAX));
2655 S_WRITE_B(spare->flags, spare->numind*(LONG)sizeof(WORD));
2656 if ( spare->sparse ) {
2657 S_WRITE_B(spare->boomlijst, spare->MaxTreeSize*(LONG)sizeof(COMPTREE));
2658 }
2659 S_WRITE_B(spare->buffers, spare->bufferssize*(LONG)sizeof(WORD));
2660 }
2661 }
2662 }
2663
2664 ANNOUNCE(AC.ExpressionList)
2665 S_WRITE_LIST(AC.ExpressionList);
2666 for ( i=0; i<AC.ExpressionList.num; ++i ) {
2667 EXPRESSIONS ex = Expressions + i;
2668 if ( ex->renum ) {
2669 S_WRITE_B(ex->renum, sizeof(struct ReNuMbEr));
2670 /* there is one dynamically allocated buffer for struct ReNuMbEr and
2671 * symb.lo points to its beginning. the size of the buffer is not
2672 * stored anywhere but we know it is 2*sizeof(WORD)*N, where N is
2673 * the number of all vectors, indices, functions and symbols. since
2674 * funum points into the buffer at a distance 2N-[Number of
2675 * functions] from symb.lo (see GetTable() in store.c), we can
2676 * calculate the buffer size by some pointer arithmetic. the size is
2677 * then written to the file. */
2678 l = ex->renum->funnum - ex->renum->symb.lo;
2679 l += ex->renum->funnum - ex->renum->func.lo;
2680 S_WRITE_B(&l, sizeof(size_t));
2681 S_WRITE_B(ex->renum->symb.lo, l);
2682 }
2683 if ( ex->bracketinfo ) {
2684 S_WRITE_B(ex->bracketinfo, sizeof(BRACKETINFO));
2685 S_WRITE_B(ex->bracketinfo->indexbuffer, ex->bracketinfo->indexbuffersize*sizeof(BRACKETINDEX));
2686 S_WRITE_B(ex->bracketinfo->bracketbuffer, ex->bracketinfo->bracketbuffersize*sizeof(WORD));
2687 }
2688 if ( ex->newbracketinfo ) {
2689 S_WRITE_B(ex->newbracketinfo, sizeof(BRACKETINFO));
2690 S_WRITE_B(ex->newbracketinfo->indexbuffer, ex->newbracketinfo->indexbuffersize*sizeof(BRACKETINDEX));
2691 S_WRITE_B(ex->newbracketinfo->bracketbuffer, ex->newbracketinfo->bracketbuffersize*sizeof(WORD));
2692 }
2693 /* don't need to write ex->renumlists */
2694 if ( ex->inmem ) {
2695 /* size of the inmem buffer has to be determined. we use the fact
2696 * that the end of an expression is marked by a zero. */
2697 w = ex->inmem;
2698 while ( *w++ ) ;
2699 l = w - ex->inmem;
2700 S_WRITE_B(&l, sizeof(size_t));
2701 S_WRITE_B(ex->inmem, l);
2702 }
2703 }
2704
2705 ANNOUNCE(AC.IndexList)
2706 S_WRITE_LIST(AC.IndexList);
2707 S_WRITE_LIST(AC.SetElementList);
2708 S_WRITE_LIST(AC.SetList);
2709 S_WRITE_LIST(AC.SymbolList);
2710 S_WRITE_LIST(AC.VectorList);
2711
2712 ANNOUNCE(AC.TableBaseList)
2713 S_WRITE_LIST(AC.TableBaseList);
2714 for ( i=0; i<AC.TableBaseList.num; ++i ) {
2715 /* see struct dbase in minos.h */
2716 if ( tablebases[i].iblocks ) {
2717 S_WRITE_B(tablebases[i].iblocks, tablebases[i].info.numberofindexblocks * sizeof(INDEXBLOCK*));
2718 for ( j=0; j<tablebases[i].info.numberofindexblocks; ++j ) {
2719 if ( tablebases[i].iblocks[j] ) {
2720 S_WRITE_B(tablebases[i].iblocks[j], sizeof(INDEXBLOCK));
2721 }
2722 }
2723 }
2724 if ( tablebases[i].nblocks ) {
2725 S_WRITE_B(tablebases[i].nblocks, tablebases[i].info.numberofnamesblocks * sizeof(NAMESBLOCK*));
2726 for ( j=0; j<tablebases[i].info.numberofnamesblocks; ++j ) {
2727 if ( tablebases[i].nblocks[j] ) {
2728 S_WRITE_B(tablebases[i].nblocks[j], sizeof(NAMESBLOCK));
2729 }
2730 }
2731 }
2732 S_WRITE_S(tablebases[i].name);
2733 S_WRITE_S(tablebases[i].fullname);
2734 S_WRITE_S(tablebases[i].tablenames);
2735 }
2736
2737 ANNOUNCE(AC.cbufList)
2738 S_WRITE_LIST(AC.cbufList);
2739 for ( i=0; i<AC.cbufList.num; ++i ) {
2740 S_WRITE_B(cbuf[i].Buffer, cbuf[i].BufferSize*sizeof(WORD));
2741 /* see inicbufs in comtool.c */
2742 S_WRITE_B(cbuf[i].lhs, cbuf[i].maxlhs*(LONG)sizeof(WORD*));
2743 S_WRITE_B(cbuf[i].rhs, cbuf[i].maxrhs*(LONG)(sizeof(WORD*)+2*sizeof(LONG)+2*sizeof(WORD)));
2744 if ( cbuf[i].boomlijst ) {
2745 S_WRITE_B(cbuf[i].boomlijst, cbuf[i].MaxTreeSize*(LONG)sizeof(COMPTREE));
2746 }
2747 }
2748
2749 S_WRITE_LIST(AC.AutoSymbolList);
2750 S_WRITE_LIST(AC.AutoIndexList);
2751 S_WRITE_LIST(AC.AutoVectorList);
2752 S_WRITE_LIST(AC.AutoFunctionList);
2753
2754 S_WRITE_NAMETREE(AC.autonames);
2755
2756 ANNOUNCE(AC.Streams)
2757 S_WRITE_B(AC.Streams, AC.MaxNumStreams*(LONG)sizeof(STREAM));
2758 for ( i=0; i<AC.NumStreams; ++i ) {
2759 if ( AC.Streams[i].inbuffer ) {
2760 S_WRITE_B(AC.Streams[i].buffer, AC.Streams[i].inbuffer);
2761 }
2762 S_WRITE_S(AC.Streams[i].FoldName);
2763 S_WRITE_S(AC.Streams[i].name);
2764 }
2765
2766 if ( AC.termstack ) {
2767 S_WRITE_B(AC.termstack, AC.maxtermlevel*(LONG)sizeof(LONG));
2768 }
2769
2770 if ( AC.termsortstack ) {
2771 S_WRITE_B(AC.termsortstack, AC.maxtermlevel*(LONG)sizeof(LONG));
2772 }
2773
2774 S_WRITE_B(AC.cmod, AM.MaxTal*4*(LONG)sizeof(UWORD));
2775
2776 if ( AC.IfHeap ) {
2777 S_WRITE_B(AC.IfHeap, (LONG)sizeof(LONG)*(AC.MaxIf+1));
2778 S_WRITE_B(AC.IfCount, (LONG)sizeof(LONG)*(AC.MaxIf+1));
2779 }
2780
2781 l = AC.iStop - AC.iBuffer + 2;
2782 S_WRITE_B(AC.iBuffer, l);
2783
2784 if ( AC.LabelNames ) {
2785 S_WRITE_B(AC.LabelNames, AC.MaxLabels*(LONG)(sizeof(UBYTE*)+sizeof(WORD)));
2786 for ( i=0; i<AC.NumLabels; ++i ) {
2787 S_WRITE_S(AC.LabelNames[i]);
2788 }
2789 }
2790
2791 S_WRITE_B(AC.FixIndices, AM.OffsetIndex*(LONG)sizeof(WORD));
2792
2793 if ( AC.termsumcheck ) {
2794 S_WRITE_B(AC.termsumcheck, AC.maxtermlevel*(LONG)sizeof(WORD));
2795 }
2796
2797 S_WRITE_B(AC.WildcardNames, AC.WildcardBufferSize);
2798
2799 if ( AC.tokens ) {
2800 l = AC.toptokens - AC.tokens;
2801 if ( l ) {
2802 S_WRITE_B(AC.tokens, l);
2803 }
2804 }
2805
2806 S_WRITE_B(AC.tokenarglevel, AM.MaxParLevel*(LONG)sizeof(WORD));
2807
2808 S_WRITE_S(AC.Fortran90Kind);
2809
2810#ifdef WITHPTHREADS
2811 if ( AC.inputnumbers ) {
2812 S_WRITE_B(AC.inputnumbers, AC.sizepfirstnum*(LONG)(sizeof(WORD)+sizeof(LONG)));
2813 }
2814#endif /* ifdef WITHPTHREADS */
2815
2816 if ( AC.IfSumCheck ) {
2817 S_WRITE_B(AC.IfSumCheck, (LONG)sizeof(WORD)*(AC.MaxIf+1));
2818 }
2819 if ( AC.CommuteInSet ) {
2820 S_WRITE_B(AC.CommuteInSet, (LONG)sizeof(WORD)*(AC.SizeCommuteInSet+1));
2821 }
2822
2823 S_WRITE_S(AC.CheckpointRunAfter);
2824 S_WRITE_S(AC.CheckpointRunBefore);
2825
2826 S_WRITE_S(AC.extrasym);
2827
2828 /*#] AC :*/
2829 /*#[ AP :*/
2830
2831 /* we write AP as a whole and then write all additional data step by step. */
2832
2833 ANNOUNCE(AP)
2834 S_WRITE_B(&AP, sizeof(struct P_const));
2835
2836 S_WRITE_LIST(AP.DollarList);
2837 for ( i=0; i<AP.DollarList.num; ++i ) {
2838 DOLLARS d = Dollars + i;
2839 S_WRITE_DOLLAR(Dollars[i]);
2840 if ( d->nfactors > 1 ) {
2841 S_WRITE_B(&(d->factors),sizeof(FACDOLLAR)*d->nfactors);
2842 for ( j = 0; j < d->nfactors; j++ ) {
2843 if ( d->factors[j].size > 0 ) {
2844 S_WRITE_B(&(d->factors[i].where),sizeof(WORD)*(d->factors[j].size+1));
2845 }
2846 }
2847 }
2848 }
2849
2850 S_WRITE_LIST(AP.PreVarList);
2851 for ( i=0; i<AP.PreVarList.num; ++i ) {
2852 /* there is one dynamically allocated buffer in struct pReVaR holding
2853 * the strings name, value and several argnames. the size of the buffer
2854 * can be calculated by adding up their string lengths. */
2855 l = strlen((char*)PreVar[i].name) + 1;
2856 if ( PreVar[i].value ) {
2857 l += strlen((char*)(PreVar[i].name+l)) + 1;
2858 }
2859 for ( j=0; j<PreVar[i].nargs; ++j ) {
2860 l += strlen((char*)(PreVar[i].name+l)) + 1;
2861 }
2862 S_WRITE_B(&l, sizeof(size_t));
2863 S_WRITE_B(PreVar[i].name, l);
2864 }
2865
2866 ANNOUNCE(AP.LoopList)
2867 S_WRITE_LIST(AP.LoopList);
2868 for ( i=0; i<AP.LoopList.num; ++i ) {
2869 S_WRITE_B(DoLoops[i].p.buffer, DoLoops[i].p.size);
2870 if ( DoLoops[i].type == ONEEXPRESSION ) {
2871 /* do loops with an expression keep this expression in a dynamically
2872 * allocated buffer in dollarname */
2873 S_WRITE_S(DoLoops[i].dollarname);
2874 }
2875 }
2876
2877 S_WRITE_LIST(AP.ProcList);
2878 for ( i=0; i<AP.ProcList.num; ++i ) {
2879 if ( Procedures[i].p.size ) {
2880 if ( Procedures[i].loadmode != 1 ) {
2881 S_WRITE_B(Procedures[i].p.buffer, Procedures[i].p.size);
2882 }
2883 else {
2884 for ( j=0; j<AP.ProcList.num; ++j ) {
2885 if ( Procedures[i].p.buffer == Procedures[j].p.buffer ) {
2886 break;
2887 }
2888 }
2889 if ( j == AP.ProcList.num ) {
2890 MesPrint("Error writing procedures to recovery file!");
2891 }
2892 S_WRITE_B(&j, sizeof(int));
2893 }
2894 }
2895 S_WRITE_S(Procedures[i].name);
2896 }
2897
2898 S_WRITE_B(AP.PreSwitchStrings, (AP.NumPreSwitchStrings+1)*(LONG)sizeof(UBYTE*));
2899 for ( i=1; i<=AP.PreSwitchLevel; ++i ) {
2900 S_WRITE_S(AP.PreSwitchStrings[i]);
2901 }
2902
2903 S_WRITE_B(AP.preStart, AP.pSize);
2904
2905 S_WRITE_S(AP.procedureExtension);
2906 S_WRITE_S(AP.cprocedureExtension);
2907
2908 S_WRITE_B(AP.PreAssignStack, AP.MaxPreAssignLevel*(LONG)sizeof(LONG));
2909 S_WRITE_B(AP.PreIfStack, AP.MaxPreIfLevel*(LONG)sizeof(int));
2910 S_WRITE_B(AP.PreSwitchModes, (AP.NumPreSwitchStrings+1)*(LONG)sizeof(int));
2911 S_WRITE_B(AP.PreTypes, (AP.MaxPreTypes+1)*(LONG)sizeof(int));
2912
2913 /*#] AP :*/
2914 /*#[ AR :*/
2915
2916 ANNOUNCE(AR)
2917 /* to remember which entry in AR.Fscr corresponds to the infile */
2918 l = AR.infile - AR.Fscr;
2919 S_WRITE_B(&l, sizeof(LONG));
2920
2921 /* write the FILEHANDLEs */
2922 S_WRITE_B(AR.outfile, sizeof(FILEHANDLE));
2923 l = AR.outfile->POfull - AR.outfile->PObuffer;
2924 if ( l ) {
2925 S_WRITE_B(AR.outfile->PObuffer, l*sizeof(WORD));
2926 }
2927 S_WRITE_B(AR.hidefile, sizeof(FILEHANDLE));
2928 l = AR.hidefile->POfull - AR.hidefile->PObuffer;
2929 if ( l ) {
2930 S_WRITE_B(AR.hidefile->PObuffer, l*sizeof(WORD));
2931 }
2932
2933 S_WRITE_B(&AR.StoreData.Fill, sizeof(POSITION));
2934 if ( ISNOTZEROPOS(AR.StoreData.Fill) ) {
2935 S_WRITE_B(&AR.StoreData, sizeof(FILEDATA));
2936 }
2937
2938 S_WRITE_B(&AR.DefPosition, sizeof(POSITION));
2939
2940 l = TimeCPU(1); l = -l;
2941 S_WRITE_B(&l, sizeof(LONG));
2942
2943 ANNOUNCE(AR.InInBuf)
2944 S_WRITE_B(&AR.InInBuf, sizeof(LONG));
2945 S_WRITE_B(&AR.InHiBuf, sizeof(LONG));
2946
2947 S_WRITE_B(&AR.NoCompress, sizeof(int));
2948 S_WRITE_B(&AR.gzipCompress, sizeof(int));
2949
2950 S_WRITE_B(&AR.outtohide, sizeof(int));
2951
2952 S_WRITE_B(&AR.GetFile, sizeof(WORD));
2953 S_WRITE_B(&AR.KeptInHold, sizeof(WORD));
2954 S_WRITE_B(&AR.BracketOn, sizeof(WORD));
2955 S_WRITE_B(&AR.MaxBracket, sizeof(WORD));
2956 S_WRITE_B(&AR.CurDum, sizeof(WORD));
2957 S_WRITE_B(&AR.DeferFlag, sizeof(WORD));
2958 S_WRITE_B(&AR.TePos, sizeof(WORD));
2959 S_WRITE_B(&AR.sLevel, sizeof(WORD));
2960 S_WRITE_B(&AR.Stage4Name, sizeof(WORD));
2961 S_WRITE_B(&AR.GetOneFile, sizeof(WORD));
2962 S_WRITE_B(&AR.PolyFun, sizeof(WORD));
2963 S_WRITE_B(&AR.PolyFunInv, sizeof(WORD));
2964 S_WRITE_B(&AR.PolyFunType, sizeof(WORD));
2965 S_WRITE_B(&AR.PolyFunExp, sizeof(WORD));
2966 S_WRITE_B(&AR.PolyFunVar, sizeof(WORD));
2967 S_WRITE_B(&AR.PolyFunPow, sizeof(WORD));
2968 S_WRITE_B(&AR.Eside, sizeof(WORD));
2969 S_WRITE_B(&AR.MaxDum, sizeof(WORD));
2970 S_WRITE_B(&AR.level, sizeof(WORD));
2971 S_WRITE_B(&AR.expchanged, sizeof(WORD));
2972 S_WRITE_B(&AR.expflags, sizeof(WORD));
2973 S_WRITE_B(&AR.CurExpr, sizeof(WORD));
2974 S_WRITE_B(&AR.SortType, sizeof(WORD));
2975 S_WRITE_B(&AR.ShortSortCount, sizeof(WORD));
2976
2977#ifdef WITHPTHREADS
2978 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
2979 S_WRITE_B(&(AB[j]->R.wranfnpair1), sizeof(int));
2980 S_WRITE_B(&(AB[j]->R.wranfnpair2), sizeof(int));
2981 S_WRITE_B(&(AB[j]->R.wranfcall), sizeof(int));
2982 S_WRITE_B(&(AB[j]->R.wranfseed), sizeof(ULONG));
2983 S_WRITE_B(&(AB[j]->R.wranfia),sizeof(ULONG *));
2984 if ( AB[j]->R.wranfia ) {
2985 S_WRITE_B(AB[j]->R.wranfia, sizeof(ULONG)*AB[j]->R.wranfnpair2);
2986 }
2987 }
2988#else
2989 S_WRITE_B(&(AR.wranfnpair1), sizeof(int));
2990 S_WRITE_B(&(AR.wranfnpair2), sizeof(int));
2991 S_WRITE_B(&(AR.wranfcall), sizeof(int));
2992 S_WRITE_B(&(AR.wranfseed), sizeof(ULONG));
2993 S_WRITE_B(&(AR.wranfia),sizeof(ULONG *));
2994 if ( AR.wranfia ) {
2995 S_WRITE_B(AR.wranfia, sizeof(ULONG)*AR.wranfnpair2);
2996 }
2997#endif
2998
2999 /*#] AR :*/
3000 /*#[ AO :*/
3001/*
3002 We copy all non-pointer variables.
3003*/
3004 ANNOUNCE(AO)
3005 l = sizeof(A.O) - ((UBYTE *)(&(A.O.NumInBrack))-(UBYTE *)(&A.O));
3006 S_WRITE_B(&(A.O.NumInBrack),l);
3007/*
3008 Now the variables in OptimizeResult
3009*/
3010 S_WRITE_B(&(A.O.OptimizeResult),sizeof(OPTIMIZERESULT));
3011 if ( A.O.OptimizeResult.codesize > 0 ) {
3012 S_WRITE_B(A.O.OptimizeResult.code,A.O.OptimizeResult.codesize*sizeof(WORD));
3013 }
3014 S_WRITE_S(A.O.OptimizeResult.nameofexpr);
3015/*
3016 And now the dictionaries.
3017 We write each dictionary to a buffer and get the size of that buffer.
3018 Then we write the size and the buffer.
3019*/
3020 for ( i = 0; i < AO.NumDictionaries; i++ ) {
3021 l = DictToBytes(AO.Dictionaries[i],(UBYTE *)(AT.WorkPointer));
3022 S_WRITE_B(&l,sizeof(LONG));
3023 S_WRITE_B(AT.WorkPointer,l);
3024 }
3025
3026 /*#] AO :*/
3027 /*#[ PF :*/
3028#ifdef WITHMPI
3029 S_WRITE_B(&PF.numtasks, sizeof(int));
3030 S_WRITE_B(&PF.rhsInParallel, sizeof(int));
3031 S_WRITE_B(&PF.exprbufsize, sizeof(int));
3032 S_WRITE_B(&PF.log, sizeof(int));
3033#endif
3034 /*#] PF :*/
3035
3036#ifdef WITHPTHREADS
3037
3038 ANNOUNCE(GetTimerInfo)
3039/*
3040 write timing information of individual threads
3041*/
3042 i = GetTimerInfo(&longp,&longpp);
3043 S_WRITE_B(&i, sizeof(int));
3044 S_WRITE_B(longp, i*(LONG)sizeof(LONG));
3045 S_WRITE_B(&i, sizeof(int));
3046 S_WRITE_B(longpp, i*(LONG)sizeof(LONG));
3047
3048#endif
3049
3050 S_FLUSH_B /* because we will call fwrite() directly in the following code */
3051
3052 /* save length of data at the beginning of the file */
3053 ANNOUNCE(file length)
3054 SETBASEPOSITION(pos, (ftell(fd)));
3055 fseek(fd, 0, SEEK_SET);
3056 if ( fwrite(&pos, 1, sizeof(POSITION), fd) != sizeof(POSITION) ) return(__LINE__);
3057 fseek(fd, BASEPOSITION(pos), SEEK_SET);
3058
3059 ANNOUNCE(file close)
3060 if ( fclose(fd) ) return(__LINE__);
3061#ifdef WITHMPI
3062 if ( PF.me == MASTER ) {
3063#endif
3064/*
3065 copy store file if necessary
3066*/
3067 ANNOUNCE(copy store file)
3068 if ( ISNOTZEROPOS(AR.StoreData.Fill) ) {
3069 if ( CopyFile(FG.fname, storefile) ) return(__LINE__);
3070 }
3071/*
3072 copy sort file if necessary
3073*/
3074 ANNOUNCE(copy sort file)
3075 if ( AR.outfile->handle >= 0 ) {
3076 if ( CopyFile(AR.outfile->name, sortfile) ) return(__LINE__);
3077 }
3078/*
3079 copy hide file if necessary
3080*/
3081 ANNOUNCE(copy hide file)
3082 if ( AR.hidefile->handle >= 0 ) {
3083 if ( CopyFile(AR.hidefile->name, hidefile) ) return(__LINE__);
3084 }
3085#ifdef WITHMPI
3086 }
3087 /*
3088 * For ParFORM, the renaming will be performed after the master got
3089 * all recovery files from the slaves.
3090 */
3091#else
3092/*
3093 make the intermediate file the recovery file
3094*/
3095 ANNOUNCE(rename intermediate file)
3096 if ( rename(intermedfile, recoveryfile) ) return(__LINE__);
3097
3098 done_snapshot = 1;
3099
3100 MesPrint("done."); fflush(0);
3101#endif
3102
3103#ifdef PRINTDEBUG
3104 print_M();
3105 print_C();
3106 print_P();
3107 print_R();
3108#endif
3109
3110 return(0);
3111}
3112
3113/*
3114 #] DoSnapshot :
3115 #[ DoCheckpoint :
3116*/
3117
3122void DoCheckpoint(int moduletype)
3123{
3124 int error;
3125 LONG timestamp = TimeWallClock(1);
3126#ifdef WITHMPI
3127 if(PF.me == MASTER){
3128#endif
3129 if ( timestamp - AC.CheckpointStamp >= AC.CheckpointInterval ) {
3130 char argbuf[20];
3131 int retvalue = 0;
3132 if ( AC.CheckpointRunBefore ) {
3133 size_t l, l2;
3134 char *str;
3135 l = strlen(AC.CheckpointRunBefore);
3136 NumToStr((UBYTE*)argbuf, AC.CModule);
3137 l2 = strlen(argbuf);
3138 str = (char*)Malloc1(l+l2+2, "callbefore");
3139 strcpy(str, AC.CheckpointRunBefore);
3140 *(str+l) = ' ';
3141 strcpy(str+l+1, argbuf);
3142 retvalue = system(str);
3143 M_free(str, "callbefore");
3144 if ( retvalue ) {
3145 MesPrint("Script returned error -> no recovery file will be created.");
3146 }
3147 }
3148#ifdef WITHMPI
3149 /* Confirm slaves to make snapshots. */
3150 PF_BroadcastNumber(retvalue == 0);
3151#endif
3152 if ( retvalue == 0 ) {
3153 if ( (error = DoSnapshot(moduletype)) ) {
3154 MesPrint("Error creating recovery files: %d", error);
3155 }
3156#ifdef WITHMPI
3157 {
3158 int i;
3159 /*get recovery files from slaves:*/
3160 for(i=1; i<PF.numtasks;i++){
3161 FILE *fd;
3162 const char *tmpnam = PF_recoveryfile('m', i, 1);
3163 fd = fopen(tmpnam, "w");
3164 if(fd == NULL){
3165 MesPrint("Error opening recovery file for slave %d",i);
3166 Terminate(-1);
3167 }/*if(fd == NULL)*/
3168 retvalue=PF_RecvFile(i,fd);
3169 if(retvalue<=0){
3170 MesPrint("Error receiving recovery file from slave %d",i);
3171 Terminate(-1);
3172 }/*if(retvalue<=0)*/
3173 fclose(fd);
3174 }/*for(i=0; i<PF.numtasks;i++)*/
3175 /*
3176 * Make the intermediate files the recovery files.
3177 */
3178 ANNOUNCE(rename intermediate file)
3179 for ( i = 0; i < PF.numtasks; i++ ) {
3180 const char *src = PF_recoveryfile('m', i, 1);
3181 const char *dst = PF_recoveryfile('m', i, 0);
3182 if ( rename(src, dst) ) {
3183 MesPrint("Error renaming recovery file %s -> %s", src, dst);
3184 }
3185 }
3186 done_snapshot = 1;
3187 MesPrint("done."); fflush(0);
3188 }
3189#endif
3190 }
3191 if ( AC.CheckpointRunAfter ) {
3192 size_t l, l2;
3193 char *str;
3194 l = strlen(AC.CheckpointRunAfter);
3195 NumToStr((UBYTE*)argbuf, AC.CModule);
3196 l2 = strlen(argbuf);
3197 str = (char*)Malloc1(l+l2+2, "callafter");
3198 strcpy(str, AC.CheckpointRunAfter);
3199 *(str+l) = ' ';
3200 strcpy(str+l+1, argbuf);
3201 retvalue = system(str);
3202 M_free(str, "callafter");
3203 if ( retvalue ) {
3204 MesPrint("Error calling script after recovery.");
3205 }
3206 }
3207 AC.CheckpointStamp = TimeWallClock(1);
3208 }
3209#ifdef WITHMPI
3210 else{/* timestamp - AC.CheckpointStamp < AC.CheckpointInterval*/
3211 /* The slaves don't need to make snapshots. */
3213 }
3214 }/*if(PF.me == MASTER)*/
3215 else{/*Slave*/
3216 int i;
3217 /* Check if the slave needs to make a snapshot. */
3218 if ( PF_BroadcastNumber(0) ) {
3219 error = DoSnapshot(moduletype);
3220 if(error == 0){
3221 FILE *fd;
3222 /*
3223 * Send the recovery file to the master. Note that no renaming
3224 * has been performed and what we have to send is actually sitting
3225 * in the intermediate file.
3226 */
3227 fd = fopen(intermedfile, "r");
3228 i=PF_SendFile(MASTER, fd);/*if fd==NULL, PF_SendFile seds to a slave the failure tag*/
3229 if(fd == NULL)
3230 Terminate(-1);
3231 fclose(fd);
3232 if(i<=0)
3233 Terminate(-1);
3234 /*Now the slave need not the recovery file so remove it:*/
3235 remove(intermedfile);
3236 }
3237 else{
3238 /*send the error tag to the master:*/
3239 PF_SendFile(MASTER,NULL);/*if fd==NULL, PF_SendFile seds to a slave the failure tag*/
3240 Terminate(-1);
3241 }
3242 done_snapshot = 1;
3243 }/*if(tag=PF_DATA_MSGTAG)*/
3244 }/*if(PF.me != MASTER)*/
3245#endif
3246}
3247/* UNFINISHED_FEATURE_EXCL_STOP */
3248/*
3249 #] DoCheckpoint :
3250*/
void InitRecovery(void)
Definition checkpoint.c:399
void DeleteRecoveryFile(void)
Definition checkpoint.c:333
void DoCheckpoint(int moduletype)
int DoRecovery(int *moduletype)
int CheckRecoveryFile(void)
Definition checkpoint.c:278
char * RecoveryFilename(void)
Definition checkpoint.c:364
LONG TimeWallClock(WORD)
Definition tools.c:3415
int CopyFile(char *, char *)
Definition tools.c:1104
LONG TimeCPU(WORD)
Definition tools.c:3489
int PF_RecvFile(int from, FILE *fd)
Definition parallel.c:4272
LONG PF_BroadcastNumber(LONG x)
Definition parallel.c:2098
int PF_SendFile(int to, FILE *fd)
Definition parallel.c:4234
BRACKETINDEX * indexbuffer
Definition structs.h:323
WORD * bracketbuffer
Definition structs.h:324
LONG BufferSize
Definition structs.h:981
WORD * numdum
Definition structs.h:978
LONG * NumTerms
Definition structs.h:977
COMPTREE * boomlijst
Definition structs.h:980
WORD ** rhs
Definition structs.h:975
WORD ** lhs
Definition structs.h:974
WORD * Buffer
Definition structs.h:971
LONG * CanCommu
Definition structs.h:976
UBYTE * dollarname
Definition structs.h:881
PRELOAD p
Definition structs.h:877
UBYTE * name
Definition structs.h:878
WORD * renumlists
Definition structs.h:389
char * message
Definition structs.h:204
int numclear
Definition structs.h:210
int size
Definition structs.h:207
int numglobal
Definition structs.h:208
int maxnum
Definition structs.h:206
int num
Definition structs.h:205
void * lijst
Definition structs.h:203
int numtemp
Definition structs.h:209
WORD type
Definition structs.h:249
WORD balance
Definition structs.h:248
WORD left
Definition structs.h:246
WORD number
Definition structs.h:250
LONG name
Definition structs.h:244
WORD parent
Definition structs.h:245
WORD right
Definition structs.h:247
LONG clearnodefill
Definition structs.h:276
LONG namefill
Definition structs.h:269
LONG nodesize
Definition structs.h:266
LONG oldnamefill
Definition structs.h:270
LONG namesize
Definition structs.h:268
WORD headnode
Definition structs.h:277
LONG nodefill
Definition structs.h:267
UBYTE * namebuffer
Definition structs.h:263
NAMENODE * namenode
Definition structs.h:261
LONG clearnamefill
Definition structs.h:275
LONG globalnamefill
Definition structs.h:272
LONG oldnodefill
Definition structs.h:271
LONG globalnodefill
Definition structs.h:274
VARRENUM indi
Definition structs.h:180
WORD * symnum
Definition structs.h:184
WORD * funnum
Definition structs.h:187
WORD * vecnum
Definition structs.h:186
VARRENUM func
Definition structs.h:182
WORD * indnum
Definition structs.h:185
VARRENUM symb
Definition structs.h:179
VARRENUM vect
Definition structs.h:181
UBYTE * pointer
Definition structs.h:727
UBYTE * pname
Definition structs.h:731
UBYTE * FoldName
Definition structs.h:729
UBYTE * buffer
Definition structs.h:726
UBYTE * name
Definition structs.h:730
WORD * pattern
Definition structs.h:349
WORD * buffers
Definition structs.h:357
struct TaBlEs * spare
Definition structs.h:356
WORD * tablepointers
Definition structs.h:343
int prototypeSize
Definition structs.h:362
UBYTE * argtail
Definition structs.h:354
COMPTREE * boomlijst
Definition structs.h:353
LONG reserved
Definition structs.h:359
int MaxTreeSize
Definition structs.h:369
WORD bufferssize
Definition structs.h:371
WORD * flags
Definition structs.h:352
WORD * prototype
Definition structs.h:348
MINMAX * mm
Definition structs.h:351
int numind
Definition structs.h:363
LONG totind
Definition structs.h:358
int sparse
Definition structs.h:366
WORD * hi
Definition structs.h:167
WORD * lo
Definition structs.h:166
WORD * start
Definition structs.h:165
int nargs
Definition structs.h:827
int wildarg
Definition structs.h:828
UBYTE * argnames
Definition structs.h:826
UBYTE * value
Definition structs.h:825
UBYTE * name
Definition structs.h:824
int blnce
Definition structs.h:293
int right
Definition structs.h:291
int parent
Definition structs.h:289
int value
Definition structs.h:292
int left
Definition structs.h:290