69#define BANNER (4*sizeof(LONG))
70void *malloclist[60000];
71LONG mallocsizes[60000];
72char *mallocstrings[60000];
77extern "C" getdtablesize();
90#error "MALLOCPROTECT": undefine "TRAPSIGNALS" in unix.h first!
92#include "mallocprotect.h"
98#define M_alloc mprotectMalloc
102#ifdef TERMMALLOCDEBUG
103WORD **DebugHeap1, **DebugHeap2;
112UBYTE *LoadInputFile(UBYTE *filename,
int type)
116 UBYTE *buffer, *name = filename;
118 handle = LocateFile(&name,type);
119 if ( handle < 0 )
return(0);
121 SeekFile(handle,&scrpos,SEEK_END);
122 TELLFILE(handle,&scrpos);
123 filesize = BASEPOSITION(scrpos);
125 SeekFile(handle,&scrpos,SEEK_SET);
126 buffer = (UBYTE *)Malloc1(filesize+2,
"LoadInputFile");
127 if ( ReadFile(handle,buffer,filesize) != filesize ) {
128 Error1(
"Read error for file ",name);
129 M_free(buffer,
"LoadInputFile");
130 if ( name != filename ) M_free(name,
"FromLoadInputFile");
135 if ( type == PROCEDUREFILE || type == SETUPFILE ) {
136 buffer[filesize] =
'\n';
137 buffer[filesize+1] = 0;
140 buffer[filesize] = 0;
142 if ( name != filename ) M_free(name,
"FromLoadInputFile");
151UBYTE ReadFromStream(
STREAM *stream)
156 if ( stream->type == PIPESTREAM ) {
160 RWLOCKR(AM.handlelock);
161 f = (FILE *)(filelist[stream->handle]);
162 UNRWLOCK(AM.handlelock);
164 if ( cc == EOF )
return(ENDOFSTREAM);
170 if ( PF.me == MASTER ) {
173 RWLOCKR(AM.handlelock);
174 f = (FILE *)filelist[stream->handle];
175 UNRWLOCK(AM.handlelock);
177 end = stream->
buffer + stream->buffersize;
195 stream->inbuffer = len;
196 stream->
top = stream->
buffer + stream->inbuffer;
197 if ( stream->
pointer == stream->
top )
return ENDOFSTREAM;
201 if ( stream->eqnum == 1 ) { stream->eqnum = 0; stream->linenumber++; }
202 if ( c == LINEFEED ) stream->eqnum = 1;
207#ifdef WITHEXTERNALCHANNEL
208 if ( stream->type == EXTERNALCHANNELSTREAM ) {
210 cc = getcFromExtChannel();
217 Error0(
"No current external channel");
223 if ( stream->eqnum == 1 ) { stream->eqnum = 0; stream->linenumber++; }
224 if ( c == LINEFEED ) stream->eqnum = 1;
229 if ( stream->type == INPUTSTREAM ) {
234 if ( ReadFile(stream->handle,&c,1) != 1 ) {
237 if ( stream->fileposition == 0 ) {
239 stream->buffersize = 32;
240 stream->
buffer = (UBYTE *)Malloc1(stream->buffersize,
"input stream buffer");
244 if ( stream->
top - stream->
buffer >= stream->buffersize ) {
245 LONG oldsize = stream->buffersize;
246 DoubleBuffer((
void**)&stream->
buffer,(
void**)&stream->
top,
sizeof(UBYTE),
"double input stream buffer");
247 stream->buffersize = stream->
top - stream->
buffer;
256 if ( stream->eqnum == 1 ) { stream->eqnum = 0; stream->linenumber++; }
257 if ( c == LINEFEED ) stream->eqnum = 1;
261 if ( stream->type != FILESTREAM )
return(ENDOFSTREAM);
262 if ( stream->fileposition != stream->bufferposition+stream->inbuffer ) {
263 stream->fileposition = stream->bufferposition+stream->inbuffer;
264 SETBASEPOSITION(scrpos,stream->fileposition);
265 SeekFile(stream->handle,&scrpos,SEEK_SET);
267 stream->bufferposition = stream->fileposition;
268 stream->inbuffer = ReadFile(stream->handle,
269 stream->
buffer,stream->buffersize);
270 if ( stream->inbuffer <= 0 )
return(ENDOFSTREAM);
271 stream->
top = stream->
buffer + stream->inbuffer;
273 stream->fileposition = stream->bufferposition + stream->inbuffer;
275 if ( stream->eqnum == 1 ) { stream->eqnum = 0; stream->linenumber++; }
277 if ( c == LINEFEED ) stream->eqnum = 1;
286UBYTE GetFromStream(
STREAM *stream)
289 if ( stream->isnextchar > 0 ) {
290 return(stream->nextchar[--stream->isnextchar]);
292 c1 = ReadFromStream(stream);
293 if ( c1 == LINEFEED || c1 == CARRIAGERETURN ) {
294 c2 = ReadFromStream(stream);
295 if ( c2 == c1 || ( c2 != LINEFEED && c2 != CARRIAGERETURN ) ) {
296 stream->isnextchar = 1;
297 stream->nextchar[0] = c2;
309UBYTE LookInStream(
STREAM *stream)
311 UBYTE c = GetFromStream(stream);
312 UngetFromStream(stream,c);
321STREAM *OpenStream(UBYTE *name,
int type,
int prevarmode,
int raiselow)
324 UBYTE *rhsofvariable, *s, *newname, c;
329 case REVERSEFILESTREAM:
337 handle = LocateFile(&newname,-1);
338 if ( handle < 0 )
return(0);
340 SeekFile(handle,&scrpos,SEEK_END);
341 TELLFILE(handle,&scrpos);
342 filesize = BASEPOSITION(scrpos);
344 SeekFile(handle,&scrpos,SEEK_SET);
345 if ( filesize > AM.MaxStreamSize && type == FILESTREAM )
346 filesize = AM.MaxStreamSize;
347 stream = CreateStream((UBYTE *)
"filestream");
351 stream->
buffer = (UBYTE *)Malloc1(filesize+1,
"name of input stream");
352 stream->inbuffer = ReadFile(handle,stream->
buffer,filesize);
353 if ( type == REVERSEFILESTREAM ) {
354 if ( ReverseStatements(stream) ) {
355 M_free(stream->
buffer,
"name of input stream");
359 stream->
top = stream->
buffer + stream->inbuffer;
361 stream->handle = handle;
362 stream->buffersize = filesize;
363 stream->fileposition = stream->inbuffer;
364 if ( newname != name ) stream->
name = newname;
365 else if ( name ) stream->
name = strDup1(name,
"name of input stream");
368 stream->prevline = stream->linenumber = 1;
372 if ( ( rhsofvariable = GetPreVar(name,WITHERROR) ) == 0 )
return(0);
373 stream = CreateStream((UBYTE *)
"var-stream");
377 stream->inbuffer = s - stream->
buffer;
378 stream->
name = AC.CurrentStream->name;
379 stream->linenumber = AC.CurrentStream->linenumber;
380 stream->prevline = AC.CurrentStream->prevline;
381 stream->eqnum = AC.CurrentStream->eqnum;
382 stream->
pname = strDup1(name,
"stream->pname");
383 stream->olddelay = AP.AllowDelay;
384 s = stream->
pname;
while ( *s ) s++;
385 while ( s[-1] ==
'+' || s[-1] ==
'-' ) s--;
390 if ( ( num = GetDollar(name) ) < 0 ) {
396 s = name;
while ( *s && *s !=
'[' ) s++;
397 if ( *s == 0 )
return(0);
399 if ( ( num = GetDollar(name) ) < 0 )
return(0);
402 if ( *s == 0 || FG.cTable[*s] != 1 || *s ==
']' ) {
403 MesPrint(
"@Illegal factor number for dollar variable");
406 while ( *s && FG.cTable[*s] == 1 ) {
407 numfac = 10*numfac+*s++-
'0';
409 if ( *s !=
']' || s[1] != 0 ) {
410 MesPrint(
"@Illegal factor number for $ variable");
413 stream = CreateStream((UBYTE *)
"dollar-stream");
414 stream->
buffer = stream->
pointer = s = WriteDollarFactorToBuffer(num,numfac,1);
417 stream = CreateStream((UBYTE *)
"dollar-stream");
418 stream->
buffer = stream->
pointer = s = WriteDollarToBuffer(num,1);
422 stream->inbuffer = s - stream->
buffer;
423 stream->
name = AC.CurrentStream->name;
424 stream->linenumber = AC.CurrentStream->linenumber;
425 stream->prevline= AC.CurrentStream->prevline;
426 stream->eqnum = AC.CurrentStream->eqnum;
427 stream->
pname = strDup1(name,
"stream->pname");
428 s = stream->
pname;
while ( *s ) s++;
429 while ( s[-1] ==
'+' || s[-1] ==
'-' ) s--;
432 AO.DollarOutSizeBuffer = 0;
433 AO.DollarOutBuffer = 0;
434 AO.DollarInOutBuffer = 0;
440 stream = CreateStream((UBYTE *)
"calculator");
444 stream->inbuffer = s - stream->
buffer;
445 stream->
name = AC.CurrentStream->name;
446 stream->linenumber = AC.CurrentStream->linenumber;
447 stream->prevline = AC.CurrentStream->prevline;
452 stream = CreateStream((UBYTE *)
"pipe");
456 if ( ( f = popen((
char *)name,
"r") ) == 0 ) {
457 Error0(
"@Cannot create pipe");
459 stream->handle = CreateHandle();
460 RWLOCKW(AM.handlelock);
461 filelist[stream->handle] = (FILES *)f;
462 UNRWLOCK(AM.handlelock);
465 stream->inbuffer = 0;
470 if ( PF.me == MASTER ) {
471 f = popen((
char *)name,
"r");
473 if ( f == 0 ) Error0(
"@Cannot create pipe");
479 stream->handle = CreateHandle();
480 RWLOCKW(AM.handlelock);
481 filelist[stream->handle] = (FILES *)f;
482 UNRWLOCK(AM.handlelock);
485 stream->buffersize = AM.MaxStreamSize;
486 stream->
buffer = (UBYTE *)Malloc1(stream->buffersize,
"pipe buffer");
487 stream->inbuffer = 0;
491 stream->
name = strDup1((UBYTE *)
"pipe",
"pipe");
492 stream->prevline = stream->linenumber = 1;
497#ifdef WITHEXTERNALCHANNEL
498 case EXTERNALCHANNELSTREAM:
501 if( (n=getCurrentExternalChannel()) == 0 )
502 Error0(
"@No current external channel");
503 stream = CreateStream((UBYTE *)
"externalchannel");
504 stream->handle = CreateHandle();
505 tmpn = (
int *)Malloc1(
sizeof(
int),
"external channel handle");
507 RWLOCKW(AM.handlelock);
508 filelist[stream->handle] = (FILES *)tmpn;
509 UNRWLOCK(AM.handlelock);
512 stream->inbuffer = 0;
513 stream->
name = strDup1((UBYTE *)
"externalchannel",
"externalchannel");
514 stream->prevline = stream->linenumber = 1;
525 stream = CreateStream((UBYTE *)
"input stream");
526 stream->handle = CreateHandle();
528 FILES *f = (FILES *)Malloc1(
sizeof(
int),
"input stream handle");
531 f->descriptor = (int)(ssize_t)name;
533 f = name ? (FILES *)name : stdin;
535 RWLOCKW(AM.handlelock);
536 filelist[stream->handle] = f;
537 UNRWLOCK(AM.handlelock);
540 stream->inbuffer = 0;
541 stream->
name = strDup1((UBYTE *)(name ?
"INPUT" :
"STDIN"),
"input stream name");
542 stream->prevline = stream->linenumber = 1;
549 stream->fileposition = -1;
554 stream->bufferposition = 0;
555 stream->isnextchar = 0;
557 stream->previousNoShowInput = AC.NoShowInput;
558 stream->afterwards = raiselow;
559 if ( AC.CurrentStream ) stream->previous = AC.CurrentStream - AC.Streams;
560 else stream->previous = -1;
562 if ( prevarmode == 0 ) stream->prevars = -1;
563 else if ( prevarmode > 0 ) stream->prevars = NumPre;
564 else if ( prevarmode < 0 ) stream->prevars = -prevarmode-1;
565 AC.CurrentStream = stream;
566 if ( type == PREREADSTREAM || type == PREREADSTREAM3 || type == PRECALCSTREAM
567 || type == DOLLARSTREAM ) AC.NoShowInput = 1;
576int LocateFile(UBYTE **name,
int type)
578 int handle, namesize, i;
579 UBYTE *s, *to, *u1, *u2, *newname, *indir;
580 handle = OpenFile((
char *)(*name));
581 if ( handle >= 0 )
return(handle);
582 if ( type == SETUPFILE && AM.SetupFile ) {
583 handle = OpenFile((
char *)(AM.SetupFile));
584 if ( handle >= 0 )
return(handle);
585 MesPrint(
"Could not open setup file %s",(
char *)(AM.SetupFile));
587 namesize = 4; s = *name;
588 while ( *s ) { s++; namesize++; }
589 if ( type == SETUPFILE ) indir = AM.SetupDir;
590 else indir = AM.IncDir;
594 while ( *s ) { s++; i++; }
595 newname = (UBYTE *)Malloc1(namesize+i,
"LocateFile");
596 s = indir; to = newname;
597 while ( *s ) *to++ = *s++;
598 if ( to > newname && to[-1] != SEPARATOR ) *to++ = SEPARATOR;
600 while ( *s ) *to++ = *s++;
602 handle = OpenFile((
char *)newname);
607 M_free(newname,
"LocateFile, incdir/file");
609 if ( type == SETUPFILE ) {
610 handle = OpenFile(setupfilename);
611 if ( handle >= 0 )
return(handle);
612 s = (UBYTE *)getenv(
"FORMSETUP");
614 handle = OpenFile((
char *)s);
615 if ( handle >= 0 )
return(handle);
616 MesPrint(
"Could not open setup file %s",s);
619 if ( type != SETUPFILE && AM.Path ) {
624 while ( *u1 && *u1 !=
';' ) {
628 while ( *u1 && *u1 !=
':' ) {
629 if ( *u1 ==
'\\' ) u1++;
633 newname = (UBYTE *)Malloc1(namesize+i,
"LocateFile");
634 s = u2; to = newname;
637 if ( *s ==
'\\' ) s++;
641 if ( to > newname && to[-1] != SEPARATOR ) *to++ = SEPARATOR;
643 while ( *s ) *to++ = *s++;
645 handle = OpenFile((
char *)newname);
650 M_free(newname,
"LocateFile Path/file");
654 if ( type != SETUPFILE && type >= -1 ) Error1(
"LocateFile: Cannot find file",*name);
665 int newstr = stream->previous, sgn;
666 UBYTE *t, numbuf[24];
669 M_free(stream->
FoldName,
"stream->FoldName");
672 if ( stream->type == FILESTREAM || stream->type == REVERSEFILESTREAM ) {
673 CloseFile(stream->handle);
674 if ( stream->
buffer != 0 ) M_free(stream->
buffer,
"name of input stream");
678 else if ( stream->type == PIPESTREAM ) {
679 RWLOCKW(AM.handlelock);
681 if ( PF.me == MASTER )
683 pclose((FILE *)(filelist[stream->handle]));
684 filelist[stream->handle] = 0;
686 UNRWLOCK(AM.handlelock);
688 if ( stream->
buffer != 0 ) {
689 M_free(stream->
buffer,
"pipe buffer");
696#ifdef WITHEXTERNALCHANNEL
697 else if ( stream->type == EXTERNALCHANNELSTREAM ) {
699 RWLOCKW(AM.handlelock);
700 tmpn = (
int *)(filelist[stream->handle]);
701 filelist[stream->handle] = 0;
703 UNRWLOCK(AM.handlelock);
704 M_free(tmpn,
"external channel handle");
708 else if ( stream->type == INPUTSTREAM ) {
710 RWLOCKW(AM.handlelock);
711 f = filelist[stream->handle];
712 filelist[stream->handle] = 0;
714 UNRWLOCK(AM.handlelock);
715 M_free(f,
"input stream handle");
717 else if ( stream->type == PREVARSTREAM && (
718 stream->afterwards == PRERAISEAFTER || stream->afterwards == PRELOWERAFTER ) ) {
719 t = stream->
buffer; x = 0; sgn = 1;
720 while ( *t ==
'-' || *t ==
'+' ) {
721 if ( *t ==
'-' ) sgn = -sgn;
724 if ( FG.cTable[*t] == 1 ) {
725 while ( *t && FG.cTable[*t] == 1 ) x = 10*x + *t++ -
'0';
727 if ( stream->afterwards == PRERAISEAFTER ) x = sgn*x + 1;
734 else if ( stream->type == DOLLARSTREAM && (
735 stream->afterwards == PRERAISEAFTER || stream->afterwards == PRELOWERAFTER ) ) {
736 if ( stream->afterwards == PRERAISEAFTER ) x = 1;
738 DollarRaiseLow(stream->
pname,x);
739 if ( stream->
buffer ) M_free(stream->
buffer,
"stream->buffer");
742 else if ( stream->type == PRECALCSTREAM || stream->type == DOLLARSTREAM ) {
743 if ( stream->
buffer ) M_free(stream->
buffer,
"stream->buffer");
746 if ( stream->
name && stream->type != PREVARSTREAM
747 && stream->type != PREREADSTREAM && stream->type != PREREADSTREAM2 && stream->type != PREREADSTREAM3
748 && stream->type != PRECALCSTREAM && stream->type != DOLLARSTREAM ) {
749 M_free(stream->
name,
"stream->name");
753 AC.NoShowInput = stream->previousNoShowInput;
759 if ( stream->prevars >= 0 ) {
760 while ( NumPre > stream->prevars ) {
762 M_free(PreVar[NumPre].name,
"PreVar[NumPre].name");
763 PreVar[NumPre].name = PreVar[NumPre].value = 0;
766 if ( stream->type == PREVARSTREAM ) {
767 AP.AllowDelay = stream->olddelay;
768 ClearMacro(stream->
pname);
769 M_free(stream->
pname,
"stream->pname");
771 else if ( stream->type == DOLLARSTREAM ) {
772 M_free(stream->
pname,
"stream->pname");
775 if ( newstr >= 0 )
return(AC.Streams + newstr);
784STREAM *CreateStream(UBYTE *where)
789 if ( AC.NumStreams >= AC.MaxNumStreams ) {
790 if ( AC.MaxNumStreams == 0 ) numnewstreams = 10;
791 else numnewstreams = 2*AC.MaxNumStreams;
792 newstreams = (
STREAM *)Malloc1(
sizeof(
STREAM)*(numnewstreams+1),
"CreateStream");
793 if ( AC.MaxNumStreams > 0 ) {
794 offset = AC.CurrentStream - AC.Streams;
795 for ( i = 0; i < AC.MaxNumStreams; i++ ) {
796 newstreams[i] = AC.Streams[i];
798 AC.CurrentStream = newstreams + offset;
800 else newstreams[0].previous = -1;
801 AC.MaxNumStreams = numnewstreams;
802 if ( AC.Streams ) M_free(AC.Streams,(
char *)where);
803 AC.Streams = newstreams;
805 newstreams = AC.Streams+AC.NumStreams++;
806 newstreams->
name = 0;
815LONG GetStreamPosition(
STREAM *stream)
817 return(stream->bufferposition + ((LONG)stream->
pointer-(LONG)stream->
buffer));
825void PositionStream(
STREAM *stream, LONG position)
828 if ( position >= stream->bufferposition
829 && position < stream->bufferposition + stream->inbuffer ) {
830 stream->
pointer = stream->
buffer + (position-stream->bufferposition);
832 else if ( stream->type == FILESTREAM ) {
833 SETBASEPOSITION(scrpos,position);
834 SeekFile(stream->handle,&scrpos,SEEK_SET);
835 stream->inbuffer = ReadFile(stream->handle,stream->
buffer,stream->buffersize);
837 stream->
top = stream->
buffer + stream->inbuffer;
838 stream->bufferposition = position;
839 stream->fileposition = position + stream->inbuffer;
840 stream->isnextchar = 0;
843 Error0(
"Illegal position for stream");
857int ReverseStatements(
STREAM *stream)
859 UBYTE *spare = (UBYTE *)Malloc1((stream->inbuffer+1)*
sizeof(UBYTE),
"Reverse copy");
860 UBYTE *top = stream->
buffer + stream->inbuffer, *in, *s, *ss, *out;
861 out = spare+stream->inbuffer+1;
865 if ( *s == AP.ComChar ) {
868 if ( s == top ) { *--out =
'\n';
break; }
872irrend: MesPrint(
"@Irregular end of reverse include file.");
876 else if ( *s ==
'\n' ) {
878 while ( ss > in ) *--out = *--ss;
880 if ( out[0] == AP.ComChar && ss+6 < s && out[3] ==
'#' ) {
884 if ( out[4] ==
'[' ) out[4] =
']';
885 else if ( out[4] ==
']' ) out[4] =
'[';
893 while ( s < top && ( *s ==
' ' || *s ==
'\t' ) ) s++;
911 while ( s < top && ( *s ==
' ' || *s ==
'\t' ) ) s++;
912 while ( s < top && *s ==
'\n' ) s++;
913 if ( s >= top && s[-1] !=
'\n' ) *s++ =
'\n';
915 while ( ss > in ) *--out = *--ss;
919 else if ( *s ==
'"' ) {
922 if ( *s ==
'"' )
break;
923 if ( *s ==
'\\' ) { s++; }
926 if ( s >= top )
goto irrend;
928 else if ( *s ==
'\\' ) {
930 if ( s >= top )
goto irrend;
935 if ( s >= top && s[-1] !=
'\n' ) *s++ =
'\n';
937 while ( ss > in ) *--out = *--ss;
941 if ( out == spare ) stream->inbuffer++;
942 if ( out > spare+1 ) {
943 MesPrint(
"@Internal error in #reverseinclude instruction.");
946 memcpy((
void *)(stream->
buffer),(
void *)out,(
size_t)(stream->inbuffer*
sizeof(UBYTE)));
947 M_free(spare,
"Reverse copy");
960 int i = CreateHandle();
961 filelist[i] = Ustdout;
966 AR.Fscr[0].handle = -1;
967 AR.Fscr[1].handle = -1;
968 AR.Fscr[2].handle = -1;
969 AR.FoStage4[0].handle = -1;
970 AR.FoStage4[1].handle = -1;
971 AR.infile = &(AR.Fscr[0]);
972 AR.outfile = &(AR.Fscr[1]);
973 AR.hidefile = &(AR.Fscr[2]);
974 AR.StoreData.Handle = -1;
977 AC.MaxNumStreams = 0;
985int OpenFile(
char *name)
990 if ( ( f = Uopen(name,
"rb") ) == 0 )
return(-1);
993 RWLOCKW(AM.handlelock);
995 UNRWLOCK(AM.handlelock);
1004int OpenAddFile(
char *name)
1009 if ( ( f = Uopen(name,
"a+b") ) == 0 )
return(-1);
1012 RWLOCKW(AM.handlelock);
1014 UNRWLOCK(AM.handlelock);
1015 TELLFILE(i,&scrpos);
1016 SeekFile(i,&scrpos,SEEK_SET);
1025int ReOpenFile(
char *name)
1030 if ( ( f = Uopen(name,
"r+b") ) == 0 )
return(-1);
1032 RWLOCKW(AM.handlelock);
1034 UNRWLOCK(AM.handlelock);
1035 TELLFILE(i,&scrpos);
1036 SeekFile(i,&scrpos,SEEK_SET);
1045int CreateFile(
char *name)
1049 if ( ( f = Uopen(name,
"w+b") ) == 0 )
return(-1);
1051 RWLOCKW(AM.handlelock);
1053 UNRWLOCK(AM.handlelock);
1062int CreateLogFile(
char *name)
1066 if ( ( f = Uopen(name,
"w+b") ) == 0 )
return(-1);
1069 RWLOCKW(AM.handlelock);
1071 UNRWLOCK(AM.handlelock);
1080void CloseFile(
int handle)
1082 if ( handle >= 0 ) {
1084 RWLOCKW(AM.handlelock);
1085 f = filelist[handle];
1086 filelist[handle] = 0;
1088 UNRWLOCK(AM.handlelock);
1106 #define COPYFILEBUFSIZE 40960L
1108 size_t countin, countout, sumcount;
1109 char *buffer = NULL;
1111 sumcount = (AM.S0->LargeSize+AM.S0->SmallEsize)*
sizeof(WORD);
1112 if ( sumcount <= COPYFILEBUFSIZE ) {
1113 sumcount = COPYFILEBUFSIZE;
1114 buffer = (
char*)Malloc1(sumcount,
"file copy buffer");
1117 buffer = (
char *)(AM.S0->lBuffer);
1120 in = fopen(source,
"rb");
1122 perror(
"CopyFile: ");
1125 out = fopen(dest,
"wb");
1126 if ( out == NULL ) {
1128 perror(
"CopyFile: ");
1132 while ( !feof(in) ) {
1133 countin = fread(buffer, 1, sumcount, in);
1134 if ( countin != sumcount ) {
1136 perror(
"CopyFile: ");
1140 countout = fwrite(buffer, 1, countin, out);
1141 if ( countin != countout ) {
1142 perror(
"CopyFile: ");
1149 if ( sumcount <= COPYFILEBUFSIZE ) {
1150 M_free(buffer,
"file copy buffer");
1166int CreateHandle(
void)
1170 RWLOCKW(AM.handlelock);
1172 if ( filelistsize == 0 ) {
1174 filelist = (FILES **)Malloc1(
sizeof(FILES *)*filelistsize,
"file handle");
1175 for ( j = 0; j < filelistsize; j++ ) filelist[j] = 0;
1179 else if ( numinfilelist >= filelistsize ) {
1180 void **fl = (
void **)filelist;
1182 if ( DoubleList((
void ***)(&fl),&filelistsize,(
int)
sizeof(FILES *),
1183 "list of open files") != 0 ) Terminate(-1);
1184 filelist = (FILES **)fl;
1185 for ( j = i; j < filelistsize; j++ ) filelist[j] = 0;
1186 numinfilelist = i + 1;
1190 for ( j = 0; j < filelistsize; j++ ) {
1191 if ( filelist[j] == 0 ) { i = j;
break; }
1195 filelist[i] = (FILES *)(filelist);
1201 if ( numinfilelist > MAX_OPEN_FILES ) {
1203 UNRWLOCK(AM.handlelock);
1205 MesPrint(
"More than %d open files",MAX_OPEN_FILES);
1206 Error0(
"System limit. This limit is not due to FORM!");
1210 UNRWLOCK(AM.handlelock);
1221LONG ReadFile(
int handle, UBYTE *buffer, LONG size)
1228 RWLOCKR(AM.handlelock);
1229 f = filelist[handle];
1230 UNRWLOCK(AM.handlelock);
1234 r = Uread(b,1,size,f);
1235 if ( r < 0 )
return(r);
1236 if ( r == 0 )
return(inbuf);
1238 if ( r == size )
return(inbuf);
1239 if ( r > size )
return(-1);
1275 WORD *b = (WORD *)buffer, *t;
1277 if ( fi->handle < 0 ) {
1278 fi->POfill = (WORD *)((UBYTE *)(fi->PObuffer) + BASEPOSITION(*pos));
1280 while ( size > 0 && fi->POfill < fi->POfull ) { *b++ = *t++; size--; }
1283 if ( ISLESSPOS(*pos,fi->POposition) || ISGEPOSINC(*pos,fi->POposition,
1284 ((UBYTE *)(fi->POfull)-(UBYTE *)(fi->PObuffer))) ) {
1289 fi->POposition = *pos;
1290 LOCK(AS.inputslock);
1291 SeekFile(fi->handle,pos,SEEK_SET);
1292 retval = ReadFile(fi->handle,(UBYTE *)(fi->PObuffer),fi->POsize);
1293 UNLOCK(AS.inputslock);
1294 fi->POfull = fi->PObuffer+retval/
sizeof(WORD);
1295 fi->POfill = fi->PObuffer;
1296 if ( fi != AR.hidefile ) AR.InInBuf = retval/
sizeof(WORD);
1297 else AR.InHiBuf = retval/
sizeof(WORD);
1300 fi->POfill = (WORD *)((UBYTE *)(fi->PObuffer) + DIFBASE(*pos,fi->POposition));
1302 if ( fi->POfill + size <= fi->POfull ) {
1304 while ( size > 0 ) { *b++ = *t++; size--; }
1308 i = fi->POfull - fi->POfill; t = fi->POfill;
1309 if ( i > size ) i = size;
1311 while ( --i >= 0 ) *b++ = *t++;
1312 if ( size == 0 )
break;
1313 ADDPOS(fi->POposition,(UBYTE *)(fi->POfull)-(UBYTE *)(fi->PObuffer));
1314 LOCK(AS.inputslock);
1315 SeekFile(fi->handle,&(fi->POposition),SEEK_SET);
1316 retval = ReadFile(fi->handle,(UBYTE *)(fi->PObuffer),fi->POsize);
1317 UNLOCK(AS.inputslock);
1318 fi->POfull = fi->PObuffer+retval/
sizeof(WORD);
1319 fi->POfill = fi->PObuffer;
1320 if ( fi != AR.hidefile ) AR.InInBuf = retval/
sizeof(WORD);
1321 else AR.InHiBuf = retval/
sizeof(WORD);
1322 if ( retval == 0 ) { t = fi->POfill;
break; }
1326 retval = (UBYTE *)b - buffer;
1328 ADDPOS(*pos,retval);
1337LONG WriteFileToFile(
int handle, UBYTE *buffer, LONG size)
1340 LONG retval, totalwritten = 0, stilltowrite;
1341 RWLOCKR(AM.handlelock);
1342 f = filelist[handle];
1343 UNRWLOCK(AM.handlelock);
1344 while ( totalwritten < size ) {
1345 stilltowrite = size - totalwritten;
1349 retval = Uwrite((
char *)buffer+totalwritten,1,stilltowrite,f);
1350 if ( retval < 0 )
return(retval);
1351 if ( retval == 0 )
return(totalwritten);
1352 totalwritten += retval;
1357 return(totalwritten);
1361WRITEFILE WriteFile = &WriteFileToFile;
1375void SeekFile(
int handle,
POSITION *offset,
int origin)
1378 RWLOCKR(AM.handlelock);
1379 f = filelist[handle];
1380 UNRWLOCK(AM.handlelock);
1384 if ( origin == SEEK_SET ) {
1385 Useek(f,BASEPOSITION(*offset),origin);
1386 SETBASEPOSITION(*offset,(Utell(f)));
1389 else if ( origin == SEEK_END ) {
1392 SETBASEPOSITION(*offset,(Utell(f)));
1400LONG TellFile(
int handle)
1403 TELLFILE(handle,&pos);
1407 return(BASEPOSITION(pos));
1410void TELLFILE(
int handle,
POSITION *position)
1413 RWLOCKR(AM.handlelock);
1414 f = filelist[handle];
1415 UNRWLOCK(AM.handlelock);
1416 SETBASEPOSITION(*position,(Utell(f)));
1424void FlushFile(
int handle)
1427 RWLOCKR(AM.handlelock);
1428 f = filelist[handle];
1429 UNRWLOCK(AM.handlelock);
1438int GetPosFile(
int handle, fpos_t *pospointer)
1441 RWLOCKR(AM.handlelock);
1442 f = filelist[handle];
1443 UNRWLOCK(AM.handlelock);
1444 return(Ugetpos(f,pospointer));
1452int SetPosFile(
int handle, fpos_t *pospointer)
1455 RWLOCKR(AM.handlelock);
1456 f = filelist[handle];
1457 UNRWLOCK(AM.handlelock);
1458 return(Usetpos(f,(fpos_t *)pospointer));
1472void SynchFile(
int handle)
1475 if ( handle >= 0 ) {
1476 RWLOCKR(AM.handlelock);
1477 f = filelist[handle];
1478 UNRWLOCK(AM.handlelock);
1494void TruncateFile(
int handle)
1497 if ( handle >= 0 ) {
1498 RWLOCKR(AM.handlelock);
1499 f = filelist[handle];
1500 UNRWLOCK(AM.handlelock);
1514int GetChannel(
char *name,
int mode)
1519 for ( i = 0; i < NumOutputChannels; i++ ) {
1520 if ( channels[i].name == 0 )
continue;
1521 if ( StrCmp((UBYTE *)name,(UBYTE *)(channels[i].name)) == 0 )
return(channels[i].handle);
1524 MesPrint(
"&File %s in print statement is not open",name);
1525 MesPrint(
" You should open it first with a #write or #append instruction");
1528 for ( i = 0; i < NumOutputChannels; i++ ) {
1529 if ( channels[i].name == 0 )
break;
1531 if ( i < NumOutputChannels ) { ch = &(channels[i]); }
1532 else { ch = (
CHANNEL *)FromList(&AC.ChannelList); }
1533 ch->
name = (
char *)strDup1((UBYTE *)name,
"name of channel");
1534 ch->
handle = CreateFile(name);
1535 RWLOCKR(AM.handlelock);
1536 f = filelist[ch->
handle];
1537 UNRWLOCK(AM.handlelock);
1550int GetAppendChannel(
char *name)
1555 for ( i = 0; i < NumOutputChannels; i++ ) {
1556 if ( channels[i].name == 0 )
continue;
1557 if ( StrCmp((UBYTE *)name,(UBYTE *)(channels[i].name)) == 0 )
return(channels[i].handle);
1559 for ( i = 0; i < NumOutputChannels; i++ ) {
1560 if ( channels[i].name == 0 )
break;
1562 if ( i < NumOutputChannels ) { ch = &(channels[i]); }
1563 else { ch = (
CHANNEL *)FromList(&AC.ChannelList); }
1564 ch->
name = (
char *)strDup1((UBYTE *)name,
"name of channel");
1565 ch->
handle = OpenAddFile(name);
1566 RWLOCKR(AM.handlelock);
1567 f = filelist[ch->
handle];
1568 UNRWLOCK(AM.handlelock);
1580int CloseChannel(
char *name)
1583 for ( i = 0; i < NumOutputChannels; i++ ) {
1584 if ( channels[i].name == 0 )
continue;
1585 if ( channels[i].name[0] == 0 )
continue;
1586 if ( StrCmp((UBYTE *)name,(UBYTE *)(channels[i].name)) == 0 ) {
1587 CloseFile(channels[i].handle);
1588 M_free(channels[i].name,
"CloseChannel");
1589 channels[i].name = 0;
1614void UpdateMaxSize(
void)
1622 if ( PF.me != MASTER )
return;
1625 if ( AM.PrintTotalSize ) {
1630 scr = AB[0]->R.Fscr;
1634 for ( i = 0; i <=2; i++ ) {
1635 if ( scr[i].handle < 0 ) {
1636 SETBASEPOSITION(position,(scr[i].POfull-scr[i].PObuffer)*
sizeof(WORD));
1639 position = scr[i].filesize;
1641 ADD2POS(sumsize,position);
1650 for ( j = 0; j < AM.totalnumberofthreads; j++ ) {
1652 if ( AT.SS && AT.SS->file.handle >= 0 ) {
1653 position = AT.SS->file.filesize;
1659 ADD2POS(sumsize,position);
1661 if ( AR.FoStage4[0].handle >= 0 ) {
1662 position = AR.FoStage4[0].filesize;
1663 ADD2POS(sumsize,position);
1668 if ( AT.SS && AT.SS->file.handle >= 0 ) {
1669 position = AT.SS->file.filesize;
1670 ADD2POS(sumsize,position);
1672 if ( AR.FoStage4[0].handle >= 0 ) {
1673 position = AR.FoStage4[0].filesize;
1674 ADD2POS(sumsize,position);
1680 ADD2POS(sumsize,AC.StoreFileSize);
1684 if ( ISLESSPOS(AS.MaxExprSize,sumsize) ) {
1686 LOCK(AS.MaxExprSizeLock);
1687 if ( ISLESSPOS(AS.MaxExprSize,sumsize) ) AS.MaxExprSize = sumsize;
1688 UNLOCK(AS.MaxExprSizeLock);
1690 AS.MaxExprSize = sumsize;
1704int StrCmp(UBYTE *s1, UBYTE *s2)
1706 while ( *s1 && *s1 == *s2 ) { s1++; s2++; }
1707 return((
int)*s1-(
int)*s2);
1715int StrICmp(UBYTE *s1, UBYTE *s2)
1717 while ( *s1 && tolower(*s1) == tolower(*s2) ) { s1++; s2++; }
1718 return((
int)tolower(*s1)-(
int)tolower(*s2));
1726int StrHICmp(UBYTE *s1, UBYTE *s2)
1728 while ( *s1 && tolower(*s1) == *s2 ) { s1++; s2++; }
1729 return((
int)tolower(*s1)-(
int)(*s2));
1737int StrICont(UBYTE *s1, UBYTE *s2)
1739 while ( *s1 && tolower(*s1) == tolower(*s2) ) { s1++; s2++; }
1740 if ( *s1 == 0 )
return(0);
1741 return((
int)tolower(*s1)-(
int)tolower(*s2));
1749int CmpArray(WORD *t1, WORD *t2, WORD n)
1752 for ( i = 0; i < n; i++ ) {
1753 if ( ( x = (
int)(t1[i]-t2[i]) ) != 0 )
return(x);
1763int ConWord(UBYTE *s1, UBYTE *s2)
1765 while ( *s1 && ( tolower(*s1) == tolower(*s2) ) ) { s1++; s2++; }
1766 if ( *s1 == 0 )
return(1);
1778 while ( *s ) { s++; i++; }
1787void NumToStr(UBYTE *s, LONG x)
1792 if ( x < 0 ) { *s++ =
'-'; xx = -x; }
1795 *t++ = xx % 10 +
'0';
1798 while ( t > str ) *s++ = *--t;
1811void WriteString(
int type, UBYTE *str,
int num)
1815 if ( num > 0 && str[num-1] == 0 ) { num--; }
1816 else if ( num <= 0 || str[num-1] != LINEFEED ) {
1817 AddLineFeed(str,num);
1820 if(type == EXTERNALCHANNELOUT){
1821 if(WriteFile(0,str,num) != num) error = 1;
1824 if ( AM.silent == 0 || type == ERROROUT ) {
1825 if ( type == INPUTOUT ) {
1826 if ( !AM.FileOnlyFlag && WriteFile(AM.StdOut,(UBYTE *)
" ",4) != 4 ) error = 1;
1827 if ( AC.LogHandle >= 0 && WriteFile(AC.LogHandle,(UBYTE *)
" ",4) != 4 ) error = 1;
1829 if ( !AM.FileOnlyFlag && WriteFile(AM.StdOut,str,num) != num ) error = 1;
1830 if ( AC.LogHandle >= 0 && WriteFile(AC.LogHandle,str,num) != num ) error = 1;
1832 if ( error ) Terminate(-1);
1845void WriteUnfinString(
int type, UBYTE *str,
int num)
1850 if(type == EXTERNALCHANNELOUT){
1851 if(WriteFile(0,str,num) != num) error = 1;
1854 if ( AM.silent == 0 || type == ERROROUT ) {
1855 if ( type == INPUTOUT ) {
1856 if ( !AM.FileOnlyFlag && WriteFile(AM.StdOut,(UBYTE *)
" ",4) != 4 ) error = 1;
1857 if ( AC.LogHandle >= 0 && WriteFile(AC.LogHandle,(UBYTE *)
" ",4) != 4 ) error = 1;
1859 if ( !AM.FileOnlyFlag && WriteFile(AM.StdOut,str,num) != num ) error = 1;
1860 if ( AC.LogHandle >= 0 && WriteFile(AC.LogHandle,str,num) != num ) error = 1;
1862 if ( error ) Terminate(-1);
1870UBYTE *AddToString(UBYTE *outstring, UBYTE *extrastring,
int par)
1872 UBYTE *s = extrastring, *t, *newstring;
1874 while ( *s ) { s++; }
1876 if ( outstring == 0 ) {
1878 t = outstring = (UBYTE *)Malloc1(n+1,
"AddToString");
1887 t = newstring = (UBYTE *)Malloc1(n+nn+2,
"AddToString");
1890 if ( par == 1 ) *t++ =
',';
1894 M_free(outstring,
"AddToString");
1908UBYTE *strDup1(UBYTE *instring,
char *ifwrong)
1910 UBYTE *s = instring, *to;
1912 to = s = (UBYTE *)Malloc1((s-instring)+1,ifwrong);
1913 while ( *instring ) *to++ = *instring++;
1937 while ( ( c = (UBYTE)(FG.cTable[*s]) ) == 0 || c == 1 ) s++;
1960 while ( *s && ( c = (UBYTE)(FG.cTable[*s]) ) != 0 && c != 1 ) s++;
1981 if ( *s ==
',' && level == 0 )
return(s);
1982 if ( *s ==
'(' ) level++;
1983 else if ( *s ==
')' ) { level--;
if ( level < 0 ) level = 0; }
1984 else if ( *s ==
'[' ) {
1987 else if ( *s ==
'{' ) {
2005WORD ReadSnum(UBYTE **p)
2010 if ( FG.cTable[*s] == 1 ) {
2012 x = ( x << 3 ) + ( x << 1 ) + ( *s++ -
'0' );
2013 if ( x > MAXPOSITIVE )
return(-1);
2014 }
while ( FG.cTable[*s] == 1 );
2029UBYTE *NumCopy(WORD y, UBYTE *to)
2039 do { *s++ = (UBYTE)((x % 10)+
'0'); i++; }
while ( ( x /= 10 ) != 0 );
2043 i = to[j]; to[j] = s[-j]; s[-j] = (UBYTE)i; j--;
2056char *LongCopy(LONG y,
char *to)
2066 do { *s++ = (x % 10)+
'0'; i++; }
while ( ( x /= 10 ) != 0 );
2070 i = to[j]; to[j] = s[-j]; s[-j] = (char)i; j--;
2083char *LongLongCopy(off_t *y,
char *to)
2096 if ( x < 0 ) { x = -x; *to++ =
'-'; }
2098 do { *s++ = (x % 10)+
'0'; i++; }
while ( ( x /= 10 ) != 0 );
2102 i = to[j]; to[j] = s[-j]; s[-j] = (char)i; j--;
2114#if defined(ANSI) || defined(mBSD)
2116static char notime[] =
"";
2119UBYTE *MakeDate(
void)
2121#if defined(ANSI) || defined(mBSD)
2124 return((UBYTE *)ctime(&tp));
2126 return((UBYTE *)notime);
2139 case 0:
return(set->bit_0);
2140 case 1:
return(set->bit_1);
2141 case 2:
return(set->bit_2);
2142 case 3:
return(set->bit_3);
2143 case 4:
return(set->bit_4);
2144 case 5:
return(set->bit_5);
2145 case 6:
return(set->bit_6);
2146 case 7:
return(set->bit_7);
2160 case 0: set->bit_0=1;
break;
2161 case 1: set->bit_1=1;
break;
2162 case 2: set->bit_2=1;
break;
2163 case 3: set->bit_3=1;
break;
2164 case 4: set->bit_4=1;
break;
2165 case 5: set->bit_5=1;
break;
2166 case 6: set->bit_6=1;
break;
2167 case 7: set->bit_7=1;
break;
2181 case 0: set->bit_0=0;
break;
2182 case 1: set->bit_1=0;
break;
2183 case 2: set->bit_2=0;
break;
2184 case 3: set->bit_3=0;
break;
2185 case 4: set->bit_4=0;
break;
2186 case 5: set->bit_5=0;
break;
2187 case 6: set->bit_6=0;
break;
2188 case 7: set->bit_7=0;
break;
2205 case 0: set->bit_0=(set1->bit_0&&(!set2->bit_0));
break;
2206 case 1: set->bit_1=(set1->bit_1&&(!set2->bit_1));
break;
2207 case 2: set->bit_2=(set1->bit_2&&(!set2->bit_2));
break;
2208 case 3: set->bit_3=(set1->bit_3&&(!set2->bit_3));
break;
2209 case 4: set->bit_4=(set1->bit_4&&(!set2->bit_4));
break;
2210 case 5: set->bit_5=(set1->bit_5&&(!set2->bit_5));
break;
2211 case 6: set->bit_6=(set1->bit_6&&(!set2->bit_6));
break;
2212 case 7: set->bit_7=(set1->bit_7&&(!set2->bit_7));
break;
2213 case 8: set++;set1++;set2++;
2227 if ( mprotectInit() ) exit(0);
2245void *Malloc1(LONG size,
const char *messageifwrong)
2254 MesPrint(
"!>%wAsking for 0 bytes in Malloc1");
2261 if ( ( size & 7 ) != 0 ) { size = size - ( size&7 ) + 8; }
2265 mem = (
void *)M_alloc(size);
2268 MLOCK(ErrorMessageLock);
2270 MesPrint(
"Attempted to allocate %l bytes.", size);
2271 MesPrint(
"@No memory while allocating %s", (UBYTE *)messageifwrong);
2273 MUNLOCK(ErrorMessageLock);
2280 mallocsizes[nummalloclist] = size;
2281 mallocstrings[nummalloclist] = (
char *)messageifwrong;
2282 malloclist[nummalloclist++] = mem;
2283 if ( AC.MemDebugFlag && filelist ) MesPrint(
"%wMem1 at 0x%x: %l bytes. %s",mem,size,messageifwrong);
2285 int i = nummalloclist-1;
2286 while ( --i >= 0 ) {
2287 if ( (
char *)mem < (((
char *)malloclist[i]) + mallocsizes[i])
2288 && (
char *)(malloclist[i]) < ((
char *)mem + size) ) {
2289 if ( filelist ) MesPrint(
"This memory overlaps with the block at 0x%x"
2295#ifdef MALLOCDEBUGOUTPUT
2296 printf (
"Malloc1: %s, allocated %li bytes at %.8lx\n",messageifwrong,size,(
unsigned long)mem);
2302 for ( i = 0; i < (int)BANNER; i++ ) { *t++ = FILLVALUE; *--u = FILLVALUE; }
2323void M_free(
void *x,
const char *where)
2326 char *t = (
char *)x;
2329 x = (
void *)(((
char *)x)-BANNER);
2331 if ( AC.MemDebugFlag ) MesPrint(
"%wFreeing 0x%x: %s",x,where);
2333 for ( i = nummalloclist-1; i >= 0; i-- ) {
2334 if ( x == malloclist[i] ) {
2335 size = mallocsizes[i];
2336 for ( j = i+1; j < nummalloclist; j++ ) {
2337 malloclist[j-1] = malloclist[j];
2338 mallocsizes[j-1] = mallocsizes[j];
2339 mallocstrings[j-1] = mallocstrings[j];
2346 unsigned int xx = ((ULONG)x);
2347 printf(
"Error returning non-allocated address: 0x%x from %s\n"
2354 for ( k = 0, j = 0; k < (int)BANNER; k++ ) {
2355 if ( *--t != FILLVALUE ) j++;
2358 LONG *tt = (LONG *)x;
2359 MesPrint(
"%w!!!!! Banner has been written in !!!!!: %x %x %x %x",
2360 tt[0],tt[1],tt[2],tt[3]);
2363 for ( k = 0, j = 0; k < (int)BANNER; k++ ) {
2364 if ( *--t != FILLVALUE ) j++;
2367 LONG *tt = (LONG *)x;
2368 MesPrint(
"%w!!!!! Tail has been written in !!!!!: %x %x %x %x",
2369 tt[0],tt[1],tt[2],tt[3]);
2382#ifdef MALLOCDEBUGOUTPUT
2383 printf (
"M_free: %s, memory freed at %.8lx\n",where,(
unsigned long)x);
2388 mprotectFree((
void *)x);
2402void M_check1() { MesPrint(
"Checking Malloc"); M_check(); }
2406 int i,j,k,error = 0;
2409 for ( i = 0; i < nummalloclist; i++ ) {
2410 t = (
char *)(malloclist[i]);
2411 for ( k = 0, j = 0; k < (int)BANNER; k++ ) {
2412 if ( *t++ != FILLVALUE ) j++;
2415 tt = (LONG *)(malloclist[i]);
2416 MesPrint(
"%w!!!!! Banner %d (%s) has been written in !!!!!: %x %x %x %x",
2417 i,mallocstrings[i],tt[0],tt[1],tt[2],tt[3]);
2418 tt[0] = tt[1] = tt[2] = tt[3] = 0;
2421 t = (
char *)(malloclist[i]) + mallocsizes[i];
2422 for ( k = 0, j = 0; k < (int)BANNER; k++ ) {
2423 if ( *--t != FILLVALUE ) j++;
2427 MesPrint(
"%w!!!!! Tail %d (%s) has been written in !!!!!: %x %x %x %x",
2428 i,mallocstrings[i],tt[0],tt[1],tt[2],tt[3]);
2429 tt[0] = tt[1] = tt[2] = tt[3] = 0;
2432 if ( ( mallocstrings[i][0] ==
' ' ) || ( mallocstrings[i][0] ==
'#' ) ) {
2433 MesPrint(
"%w!!!!! Funny mallocstring");
2448 MesPrint(
"We have the following memory allocations left:");
2449 for ( i = 0; i < nummalloclist; i++ ) {
2450 MesPrint(
"0x%x: %l bytes. number %d: '%s'",malloclist[i],mallocsizes[i],i,mallocstrings[i]);
2456void M_check1(
void) {}
2457void M_print(
void) {}
2487#define TERMMEMSTARTNUM 16
2488#define TERMEXTRAWORDS 10
2490void TermMallocAddMemory(PHEAD0)
2495 else extra = AT.TermMemMax;
2496 if ( AT.TermMemHeap ) M_free(AT.TermMemHeap,
"TermMalloc");
2497 newbufs = (WORD *)Malloc1(extra*(AM.MaxTer+TERMEXTRAWORDS*
sizeof(WORD)),
"TermMalloc");
2498 AT.TermMemHeap = (WORD **)Malloc1((extra+AT.TermMemMax)*
sizeof(WORD *),
"TermMalloc");
2499 for ( i = 0; i < extra; i++ ) {
2500 AT.TermMemHeap[i] = newbufs + i*(AM.MaxTer/
sizeof(WORD)+TERMEXTRAWORDS);
2502#ifdef TERMMALLOCDEBUG
2503 DebugHeap2 = (WORD **)Malloc1((extra+AT.TermMemMax)*
sizeof(WORD *),
"TermMalloc");
2504 for ( i = 0; i < AT.TermMemMax; i++ ) { DebugHeap2[i] = DebugHeap1[i]; }
2505 for ( i = 0; i < extra; i++ ) {
2506 DebugHeap2[i+AT.TermMemMax] = newbufs + i*(AM.MaxTer/
sizeof(WORD)+TERMEXTRAWORDS);
2508 if ( DebugHeap1 ) M_free(DebugHeap1,
"TermMalloc");
2509 DebugHeap1 = DebugHeap2;
2511 AT.TermMemTop = extra;
2512 AT.TermMemMax += extra;
2513#ifdef TERMMALLOCDEBUG
2514 MesPrint(
"AT.TermMemMax is now %l",AT.TermMemMax);
2520WORD *TermMalloc2(PHEAD
char *text)
2522 if ( AT.TermMemTop <= 0 ) TermMallocAddMemory(BHEAD0);
2524#ifdef TERMMALLOCDEBUG
2525 MesPrint(
"TermMalloc: %s, %d",text,(AT.TermMemMax-AT.TermMemTop));
2528#ifdef MALLOCDEBUGOUTPUT
2529 MesPrint(
"TermMalloc: %s, %l/%l (%x)",text,AT.TermMemTop,AT.TermMemMax,AT.TermMemHeap[AT.TermMemTop-1]);
2533 return(AT.TermMemHeap[--AT.TermMemTop]);
2536void TermFree2(PHEAD WORD *TermMem,
char *text)
2538#ifdef TERMMALLOCDEBUG
2542 for ( i = 0; i < AT.TermMemMax; i++ ) {
2543 if ( TermMem == DebugHeap1[i] )
break;
2545 if ( i >= AT.TermMemMax ) {
2546 MesPrint(
" ERROR: TermFree called with an address not given by TermMalloc.");
2551 AT.TermMemHeap[AT.TermMemTop++] = TermMem;
2553#ifdef TERMMALLOCDEBUG
2554 MesPrint(
"TermFree: %s, %d",text,(AT.TermMemMax-AT.TermMemTop));
2556#ifdef MALLOCDEBUGOUTPUT
2557 MesPrint(
"TermFree: %s, %l/%l (%x)",text,AT.TermMemTop,AT.TermMemMax,TermMem);
2587#define NUMBERMEMSTARTNUM 16
2588#define NUMBEREXTRAWORDS 10L
2590#ifdef TERMMALLOCDEBUG
2591UWORD **DebugHeap3, **DebugHeap4;
2594void NumberMallocAddMemory(PHEAD0)
2600 else extra = AT.NumberMemMax;
2601 if ( AT.NumberMemHeap ) M_free(AT.NumberMemHeap,
"NumberMalloc");
2602 newbufs = (UWORD *)Malloc1(extra*(AM.MaxTal+NUMBEREXTRAWORDS)*
sizeof(UWORD),
"NumberMalloc");
2603 AT.NumberMemHeap = (UWORD **)Malloc1((extra+AT.NumberMemMax)*
sizeof(UWORD *),
"NumberMalloc");
2604 for ( i = 0; i < extra; i++ ) {
2605 AT.NumberMemHeap[i] = newbufs + i*(LONG)(AM.MaxTal+NUMBEREXTRAWORDS);
2607#ifdef TERMMALLOCDEBUG
2608 DebugHeap4 = (UWORD **)Malloc1((extra+AT.NumberMemMax)*
sizeof(WORD *),
"NumberMalloc");
2609 for ( i = 0; i < AT.NumberMemMax; i++ ) { DebugHeap4[i] = DebugHeap3[i]; }
2610 for ( i = 0; i < extra; i++ ) {
2611 DebugHeap4[i+AT.NumberMemMax] = newbufs + i*(LONG)(AM.MaxTal+NUMBEREXTRAWORDS);
2613 if ( DebugHeap3 ) M_free(DebugHeap3,
"NumberMalloc");
2614 DebugHeap3 = DebugHeap4;
2616 AT.NumberMemTop = extra;
2617 AT.NumberMemMax += extra;
2625UWORD *NumberMalloc2(PHEAD
char *text)
2627 if ( AT.NumberMemTop <= 0 ) NumberMallocAddMemory(BHEAD text);
2629#ifdef MALLOCDEBUGOUTPUT
2630 if ( (AT.NumberMemMax-AT.NumberMemTop) > 10 )
2631 MesPrint(
"NumberMalloc: %s, %l/%l (%x)",text,AT.NumberMemTop,AT.NumberMemMax,AT.NumberMemHeap[AT.NumberMemTop-1]);
2635 return(AT.NumberMemHeap[--AT.NumberMemTop]);
2638void NumberFree2(PHEAD UWORD *NumberMem,
char *text)
2640#ifdef TERMMALLOCDEBUG
2642 for ( i = 0; i < AT.NumberMemMax; i++ ) {
2643 if ( NumberMem == DebugHeap3[i] )
break;
2645 if ( i >= AT.NumberMemMax ) {
2646 MesPrint(
" ERROR: NumberFree called with an address not given by NumberMalloc.");
2651 AT.NumberMemHeap[AT.NumberMemTop++] = NumberMem;
2653#ifdef MALLOCDEBUGOUTPUT
2654 if ( (AT.NumberMemMax-AT.NumberMemTop) > 10 )
2655 MesPrint(
"NumberFree: %s, %l/%l (%x)",text,AT.NumberMemTop,AT.NumberMemMax,NumberMem);
2668void CacheNumberMallocAddMemory(PHEAD0)
2674 else extra = AT.CacheNumberMemMax;
2675 if ( AT.CacheNumberMemHeap ) M_free(AT.CacheNumberMemHeap,
"NumberMalloc");
2676 newbufs = (UWORD *)Malloc1(extra*(AM.MaxTal+NUMBEREXTRAWORDS)*
sizeof(UWORD),
"CacheNumberMalloc");
2677 AT.CacheNumberMemHeap = (UWORD **)Malloc1((extra+AT.NumberMemMax)*
sizeof(UWORD *),
"CacheNumberMalloc");
2678 for ( i = 0; i < extra; i++ ) {
2679 AT.CacheNumberMemHeap[i] = newbufs + i*(LONG)(AM.MaxTal+NUMBEREXTRAWORDS);
2681 AT.CacheNumberMemTop = extra;
2682 AT.CacheNumberMemMax += extra;
2687UWORD *CacheNumberMalloc2(PHEAD
char *text)
2689 if ( AT.CacheNumberMemTop <= 0 ) CacheNumberMallocAddMemory(BHEAD0);
2691#ifdef MALLOCDEBUGOUTPUT
2692 MesPrint(
"NumberMalloc: %s, %l/%l (%x)",text,AT.NumberMemTop,AT.NumberMemMax,AT.NumberMemHeap[AT.NumberMemTop-1]);
2696 return(AT.CacheNumberMemHeap[--AT.CacheNumberMemTop]);
2699void CacheNumberFree2(PHEAD UWORD *NumberMem,
char *text)
2702 AT.CacheNumberMemHeap[AT.CacheNumberMemTop++] = NumberMem;
2704#ifdef MALLOCDEBUGOUTPUT
2705 MesPrint(
"NumberFree: %s, %l/%l (%x)",text,AT.NumberMemTop,AT.NumberMemMax,NumberMem);
2720void *FromList(
LIST *L)
2729 i = ( L->
num * L->
size ) /
sizeof(
int);
2730 old = (
int *)L->
lijst; newL = (
int *)newlist;
2731 while ( --i >= 0 ) *newL++ = *old++;
2732 if ( L->
lijst ) M_free(L->
lijst,
"L->lijst FromList");
2746void *From0List(
LIST *L)
2754 i = ( L->
num * L->
size ) /
sizeof(
int);
2755 old = (
int *)(L->
lijst); newL = (
int *)newlist;
2756 while ( --i >= 0 ) *newL++ = *old++;
2757 i = ( L->
maxnum - L->
num ) /
sizeof(
int);
2758 while ( --i >= 0 ) *newL++ = 0;
2759 if ( L->
lijst ) M_free(L->
lijst,
"L->lijst From0List");
2775void *FromVarList(
LIST *L)
2781 else if ( L->
lijst ) {
2783 if ( L == &(AP.DollarList) ) {
2784 if ( L->
maxnum > MAXDOLLARVARIABLES ) L->
maxnum = MAXDOLLARVARIABLES;
2785 if ( L->
num >= MAXDOLLARVARIABLES ) {
2787 MesPrint(
"!>More than %l objects in list of $-variables",
2788 MAXDOLLARVARIABLES);
2794 if ( L->
maxnum > MAXVARIABLES ) L->
maxnum = MAXVARIABLES;
2795 if ( L->
num >= MAXVARIABLES ) {
2797 MesPrint(
"!>More than %l objects in list of variables",
2806 i = ( L->
num * L->
size ) /
sizeof(
int);
2807 old = (
int *)(L->
lijst); newL = (
int *)newlist;
2808 while ( --i >= 0 ) *newL++ = *old++;
2809 if ( L->
lijst ) M_free(L->
lijst,
"L->lijst from VarList");
2813 return( ((
char *)(L->
lijst)) + L->
size * ((L->
num)++) );
2821int DoubleList(
void ***lijst,
int *oldsize,
int objectsize,
char *nameoftype)
2824 LONG i, newsize, fullsize;
2826 static LONG maxlistsize = (LONG)(MAXPOSITIVE);
2827 if ( *lijst == 0 ) {
2828 if ( *oldsize > 0 ) newsize = *oldsize;
2831 else newsize = *oldsize * 2;
2832 if ( newsize > maxlistsize ) {
2833 if ( *oldsize == maxlistsize ) {
2834 MesPrint(
"No memory for extra space in %s",nameoftype);
2837 newsize = maxlistsize;
2839 fullsize = ( newsize * objectsize +
sizeof(
void *)-1 ) & (-
sizeof(
void *));
2840 newlist = (
void **)Malloc1(fullsize,nameoftype);
2842 to = newlist; from = *lijst; i = (*oldsize * objectsize)/
sizeof(
void *);
2849 while ( --i >= 0 ) *to++ = *from++;
2851 if ( *lijst ) M_free(*lijst,
"DoubleLList");
2873int DoubleLList(
void ***lijst, LONG *oldsize,
int objectsize,
char *nameoftype)
2876 LONG i, newsize, fullsize;
2878 static LONG maxlistsize = (LONG)(MAXLONG);
2879 if ( *lijst == 0 ) {
2880 if ( *oldsize > 0 ) newsize = *oldsize;
2883 else newsize = *oldsize * 2;
2884 if ( newsize > maxlistsize ) {
2885 if ( *oldsize == maxlistsize ) {
2886 MesPrint(
"No memory for extra space in %s",nameoftype);
2889 newsize = maxlistsize;
2891 fullsize = ( newsize * objectsize +
sizeof(
void *)-1 ) & (-
sizeof(
void *));
2892 newlist = (
void **)Malloc1(fullsize,nameoftype);
2894 to = newlist; from = *lijst; i = (*oldsize * objectsize)/
sizeof(
void *);
2901 while ( --i >= 0 ) *to++ = *from++;
2903 if ( *lijst ) M_free(*lijst,
"DoubleLList");
2914#define DODOUBLE(x) { x *s, *t, *u; if ( *start ) { \
2915 oldsize = *(x **)stop - *(x **)start; newsize = 2*oldsize; \
2916 t = u = (x *)Malloc1(newsize*sizeof(x),text); s = *(x **)start; \
2917 for ( i = 0; i < oldsize; i++ ) {*t++ = *s++;} M_free(*start,"double"); } \
2918 else { newsize = 100; u = (x *)Malloc1(newsize*sizeof(x),text); } \
2919 *start = (void *)u; *stop = (void *)(u+newsize); }
2921void DoubleBuffer(
void **start,
void **stop,
int size,
char *text)
2923 LONG oldsize, newsize, i;
2924 if ( size ==
sizeof(
char) ) DODOUBLE(
char)
2925 else if ( size ==
sizeof(
short) ) DODOUBLE(
short)
2926 else if ( size ==
sizeof(
int) ) DODOUBLE(
int)
2927 else if ( size ==
sizeof(LONG) ) DODOUBLE(LONG)
2928 else if ( size %
sizeof(
int) == 0 ) DODOUBLE(
int)
2930 MesPrint(
"---Cannot handle doubling buffers of size %d",size);
2940#define DOEXPAND(x) { x *newbuffer, *t, *m; \
2941 t = newbuffer = (x *)Malloc1((newsize+2)*type,"ExpandBuffer"); \
2942 if ( *buffer ) { m = (x *)*buffer; i = *oldsize; \
2943 while ( --i >= 0 ) {*t++ = *m++;} M_free(*buffer,"ExpandBuffer"); \
2944 } *buffer = newbuffer; *oldsize = newsize; }
2946void ExpandBuffer(
void **buffer, LONG *oldsize,
int type)
2949 if ( *oldsize <= 0 ) { newsize = 100; }
2950 else newsize = 2*(*oldsize);
2951 if ( type ==
sizeof(
char) ) DOEXPAND(
char)
2952 else if ( type ==
sizeof(
short) ) DOEXPAND(
short)
2953 else if ( type ==
sizeof(
int) ) DOEXPAND(
int)
2954 else if ( type ==
sizeof(LONG) ) DOEXPAND(LONG)
2957 MesPrint(
"---Cannot handle expanding buffers with objects of size %d",type);
2970LONG iexp(LONG x,
int p)
2975 if ( x == 0 )
return(0);
2976 if ( p == 0 )
return(1);
2977 sign = x < 0 ? -1 : 1;
2978 if ( sign < 0 && ( p & 1 ) == 0 ) sign = 1;
2980 if ( ux == 1 )
return(sign);
2981 if ( p < 0 )
return(0);
2984 if ( ( p & 1 ) != 0 ) y *= ux;
2988 if ( sign < 0 ) y = -y;
2989 return ULongToLong(y);
3001void ToGeneral(WORD *r, WORD *m, WORD par)
3005 else { m[1] = 0; m += ARGHEAD + 1; }
3009 if ( j >= FUNCTION ) { *m++ = j; *m++ = FUNHEAD; FILLFUN(m) }
3012 case SYMBOL: *m++ = j; *m++ = 4; *m++ = *r++; *m++ = 1;
break;
3014 if ( *r > 0 ) { *m++ = *r; *m++ = 1; *m++ = 3; }
3015 else if ( *r == 0 ) { m--; }
3016 else { *m++ = -*r; *m++ = 1; *m++ = -3; }
3023 *m++ = INDEX; *m++ = 3; *m++ = *r++;
3027 *m++ = 1; *m++ = 1; *m++ = k;
3030 if ( !par ) mm[ARGHEAD] = *mm-ARGHEAD;
3045int ToFast(WORD *r, WORD *m)
3048 if ( *r == ARGHEAD ) { *m++ = -SNUMBER; *m++ = 0;
return(1); }
3049 if ( *r != r[ARGHEAD]+ARGHEAD )
return(0);
3052 if ( r[2] != 1 || r[1] <= 0 )
return(0);
3053 *m++ = -SNUMBER; *m = ( r[3] < 0 ) ? -r[1] : r[1];
return(1);
3056 if ( r[i-1] != 1 || r[i-2] != 1 )
return(0);
3058 if ( r[i] == -3 && r[2] == *r-4 && r[2] == 3 && r[1] == INDEX
3059 && r[3] < MINSPEC ) {}
3062 else if ( r[2] != *r - 4 )
return(0);
3064 if ( *r >= FUNCTION ) {
3065 if ( r[1] <= FUNHEAD ) { *m++ = -*r;
return(1); }
3067 else if ( *r == SYMBOL ) {
3068 if ( r[1] == 4 && r[3] == 1 )
3069 { *m++ = -SYMBOL; *m++ = r[2];
return(1); }
3071 else if ( *r == INDEX ) {
3073 if ( r[2] >= MINSPEC ) {
3074 if ( r[2] >= 0 && r[2] < AM.OffsetIndex ) *m++ = -SNUMBER;
3078 if ( r[5] == -3 ) *m++ = -MINVECTOR;
3079 else *m++ = -VECTOR;
3098WORD ToPolyFunGeneral(PHEAD WORD *term)
3100 WORD *t = term+1, *tt, *to, *to1, *termout, *tstop, *tnext;
3101 WORD numarg, i, change = 0;
3102 tstop = term + *term; tstop -= ABS(tstop[-1]);
3103 termout = to = AT.WorkPointer;
3105 while ( t < tstop ) {
3106 if ( *t == AR.PolyFun ) {
3107 tt = t+FUNHEAD; tnext = t + t[1];
3109 while ( tt < tnext ) { numarg++; NEXTARG(tt); }
3110 if ( numarg == 2 ) {
3113 i = FUNHEAD; NCOPY(to,t,i);
3114 while ( tt < tnext ) {
3116 i = *tt; NCOPY(to,tt,i);
3118 else if ( *tt == -SYMBOL ) {
3119 to1[1] += 6+ARGHEAD; to1[2] |= MUSTCLEANPRF; change++;
3120 *to++ = 8+ARGHEAD; *to++ = 0; FILLARG(to);
3121 *to++ = 8; *to++ = SYMBOL; *to++ = 4; *to++ = tt[1];
3122 *to++ = 1; *to++ = 1; *to++ = 1; *to++ = 3;
3125 else if ( *tt == -SNUMBER ) {
3127 to1[1] += 2+ARGHEAD; to1[2] |= MUSTCLEANPRF; change++;
3128 *to++ = 4+ARGHEAD; *to++ = 0; FILLARG(to);
3129 *to++ = 4; *to++ = tt[1]; *to++ = 1; *to++ = 3;
3132 else if ( tt[1] < 0 ) {
3133 to1[1] += 2+ARGHEAD; to1[2] |= MUSTCLEANPRF; change++;
3134 *to++ = 4+ARGHEAD; *to++ = 0; FILLARG(to);
3135 *to++ = 4; *to++ = -tt[1]; *to++ = 1; *to++ = -3;
3140 MLOCK(ErrorMessageLock);
3141 MesPrint(
"!>Internal error: Zero in PolyRatFun");
3142 MUNLOCK(ErrorMessageLock);
3152 i = t[1]; NCOPY(to,t,i)
3156 while ( t < tt ) *to++ = *t++;
3157 *termout = to - termout;
3158 t = term; i = *termout; tt = termout;
3160 AT.WorkPointer = term + *term;
3175int IsLikeVector(WORD *arg)
3177 WORD *sstop, *t, *tstop;
3179 if ( *arg == -VECTOR || *arg == -INDEX )
return(1);
3180 if ( *arg == -SNUMBER && arg[1] >= 0 && arg[1] < AM.OffsetIndex )
3184 sstop = arg + *arg; arg += ARGHEAD;
3185 while ( arg < sstop ) {
3187 tstop = t - ABS(t[-1]);
3189 while ( arg < tstop ) {
3190 if ( *arg == INDEX )
return(1);
3203int AreArgsEqual(WORD *arg1, WORD *arg2)
3206 if ( *arg2 != *arg1 )
return(0);
3209 while ( --i > 0 ) {
if ( arg1[i] != arg2[i] )
return(0); }
3212 else if ( *arg1 <= -FUNCTION )
return(1);
3213 else if ( arg1[1] == arg2[1] )
return(1);
3222int CompareArgs(WORD *arg1, WORD *arg2)
3226 if ( *arg2 < 0 )
return(-1);
3227 i1 = *arg1-ARGHEAD; arg1 += ARGHEAD;
3228 i2 = *arg2-ARGHEAD; arg2 += ARGHEAD;
3229 while ( i1 > 0 && i2 > 0 ) {
3230 if ( *arg1 != *arg2 )
return((
int)(*arg1)-(
int)(*arg2));
3231 i1--; i2--; arg1++; arg2++;
3235 else if ( *arg2 > 0 )
return(1);
3237 if ( *arg1 != *arg2 ) {
3238 if ( *arg1 < *arg2 )
return(-1);
3241 if ( *arg1 <= -FUNCTION )
return(0);
3242 return((
int)(arg1[1])-(
int)(arg2[1]));
3253int CompArg(WORD *s1, WORD *s2)
3256 WORD *st1, *st2, x[7];
3260 if ( *s1 <= -FUNCTION && *s2 <= -FUNCTION ) {
3261 if ( *s1 > *s2 )
return(-1);
3262 if ( *s1 < *s2 )
return(1);
3265 if ( *s1 > *s2 )
return(1);
3266 if ( *s1 < *s2 )
return(-1);
3267 if ( *s1 <= -FUNCTION )
return(0);
3269 if ( *s1 > *s2 )
return(1);
3270 if ( *s1 < *s2 )
return(-1);
3273 x[1] = AT.comsym[3];
3274 x[2] = AT.comnum[1];
3275 x[3] = AT.comnum[3];
3276 x[4] = AT.comind[3];
3277 x[5] = AT.comind[6];
3278 x[6] = AT.comfun[1];
3279 if ( *s1 == -SYMBOL ) {
3280 AT.comsym[3] = s1[1];
3281 st1 = AT.comsym+8; s1 = AT.comsym;
3283 else if ( *s1 == -SNUMBER ) {
3285 AT.comnum[1] = -s1[1]; AT.comnum[3] = -3;
3288 AT.comnum[1] = s1[1]; AT.comnum[3] = 3;
3293 else if ( *s1 == -INDEX || *s1 == -VECTOR ) {
3294 AT.comind[3] = s1[1]; AT.comind[6] = 3;
3295 st1 = AT.comind+7; s1 = AT.comind;
3297 else if ( *s1 == -MINVECTOR ) {
3298 AT.comind[3] = s1[1]; AT.comind[6] = -3;
3299 st1 = AT.comind+7; s1 = AT.comind;
3301 else if ( *s1 <= -FUNCTION ) {
3302 AT.comfun[1] = -*s1;
3303 st1 = AT.comfun+FUNHEAD+4; s1 = AT.comfun;
3309 else if ( *s1 == -ARGWILD ) {
3312 else {
goto argerror; }
3313 st2 = s2 + *s2; s2 += ARGHEAD;
3316 else if ( *s2 < 0 ) {
3317 x[1] = AT.comsym[3];
3318 x[2] = AT.comnum[1];
3319 x[3] = AT.comnum[3];
3320 x[4] = AT.comind[3];
3321 x[5] = AT.comind[6];
3322 x[6] = AT.comfun[1];
3323 if ( *s2 == -SYMBOL ) {
3324 AT.comsym[3] = s2[1];
3325 st2 = AT.comsym+8; s2 = AT.comsym;
3327 else if ( *s2 == -SNUMBER ) {
3329 AT.comnum[1] = -s2[1]; AT.comnum[3] = -3;
3332 else if ( s2[1] == 0 ) {
3333 st2 = AT.comnum+4; s2 = st2;
3336 AT.comnum[1] = s2[1]; AT.comnum[3] = 3;
3341 else if ( *s2 == -INDEX || *s2 == -VECTOR ) {
3342 AT.comind[3] = s2[1]; AT.comind[6] = 3;
3343 st2 = AT.comind+7; s2 = AT.comind;
3345 else if ( *s2 == -MINVECTOR ) {
3346 AT.comind[3] = s2[1]; AT.comind[6] = -3;
3347 st2 = AT.comind+7; s2 = AT.comind;
3349 else if ( *s2 <= -FUNCTION ) {
3350 AT.comfun[1] = -*s2;
3351 st2 = AT.comfun+FUNHEAD+4; s2 = AT.comfun;
3357 else if ( *s2 == -ARGWILD ) {
3360 else {
goto argerror; }
3361 st1 = s1 + *s1; s1 += ARGHEAD;
3365 x[1] = AT.comsym[3];
3366 x[2] = AT.comnum[1];
3367 x[3] = AT.comnum[3];
3368 x[4] = AT.comind[3];
3369 x[5] = AT.comind[6];
3370 x[6] = AT.comfun[1];
3371 st1 = s1 + *s1; st2 = s2 + *s2;
3372 s1 += ARGHEAD; s2 += ARGHEAD;
3374 while ( s1 < st1 && s2 < st2 ) {
3375 if ( ( k = CompareTerms(BHEAD s1,s2,(WORD)2) ) != 0 ) {
3376 AT.comsym[3] = x[1];
3377 AT.comnum[1] = x[2];
3378 AT.comnum[3] = x[3];
3379 AT.comind[3] = x[4];
3380 AT.comind[6] = x[5];
3381 AT.comfun[1] = x[6];
3384 s1 += *s1; s2 += *s2;
3386 AT.comsym[3] = x[1];
3387 AT.comnum[1] = x[2];
3388 AT.comnum[3] = x[3];
3389 AT.comind[3] = x[4];
3390 AT.comind[6] = x[5];
3391 AT.comfun[1] = x[6];
3392 if ( s1 < st1 )
return(1);
3393 if ( s2 < st2 )
return(-1);
3399 MesPrint(
"!>Illegal type of short function argument in Normalize");
3400 Terminate(-1);
return(0);
3409#ifdef HAVE_CLOCK_GETTIME
3412#ifdef HAVE_GETTIMEOFDAY
3413#include <sys/time.h>
3415#include <sys/timeb.h>
3431#ifdef HAVE_CLOCK_GETTIME
3433 clock_gettime(CLOCK_MONOTONIC, &ts);
3436 return(((LONG)(ts.tv_sec)-AM.OldSecTime)*100 +
3437 ((LONG)(ts.tv_nsec / 1000000)-AM.OldMilliTime)/10);
3440 AM.OldSecTime = (LONG)(ts.tv_sec);
3441 AM.OldMilliTime = (LONG)(ts.tv_nsec / 1000000);
3445#ifdef HAVE_GETTIMEOFDAY
3448 gettimeofday(&t, NULL);
3449 sec = (LONG)t.tv_sec;
3450 msec = (LONG)(t.tv_usec/1000);
3452 return (sec-AM.OldSecTime)*100 + (msec-AM.OldMilliTime)/10;
3455 AM.OldSecTime = sec;
3456 AM.OldMilliTime = msec;
3464 return(((LONG)(tp.time)-AM.OldSecTime)*100 +
3465 ((LONG)(tp.millitm)-AM.OldMilliTime)/10);
3468 AM.OldSecTime = (LONG)(tp.time);
3469 AM.OldMilliTime = (LONG)(tp.millitm);
3481LONG TimeChildren(WORD par)
3483 if ( par )
return(Timer(1)-AM.OldChildTime);
3484 AM.OldChildTime = Timer(1);
3502 if ( par )
return(Timer(0)-AR.OldTime);
3503 AR.OldTime = Timer(0);
3516 static int initialized = 0;
3517 static HANDLE hProcess;
3518 FILETIME ftCreate, ftExit, ftKernel, ftUser;
3521 if ( !initialized ) {
3522 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
3524 if ( GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser) ) {
3525 PFILETIME pftKernel = &ftKernel;
3526 PFILETIME pftUser = &ftUser;
3527 __int64 t = *(__int64 *)pftKernel + *(__int64 *)pftUser;
3528 return (LONG)(t / 10000);
3534 FILETIME ftCreate, ftExit, ftKernel, ftUser;
3537 hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, GetCurrentThreadId());
3539 if ( GetThreadTimes(hThread, &ftCreate, &ftExit, &ftKernel, &ftUser) ) {
3540 PFILETIME pftKernel = &ftKernel;
3541 PFILETIME pftUser = &ftUser;
3542 __int64 t = *(__int64 *)pftKernel + *(__int64 *)pftUser;
3543 lResult = (LONG)(t / 10000);
3545 CloseHandle(hThread);
3552#include <sys/time.h>
3553#include <sys/resource.h>
3554#ifdef WITHPOSIXCLOCK
3563#ifdef WITHPOSIXCLOCK
3582 if ( clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t) ) {
3584 MesPrint(
"!>Error in getting timing information");
3587 return (LONG)t.tv_sec * 1000 + (LONG)t.tv_nsec / 1000000;
3591 struct rusage rusage;
3593 getrusage(RUSAGE_CHILDREN,&rusage);
3594 return(((LONG)(rusage.ru_utime.tv_sec)+(LONG)(rusage.ru_stime.tv_sec))*1000
3595 +(rusage.ru_utime.tv_usec/1000+rusage.ru_stime.tv_usec/1000));
3598 getrusage(RUSAGE_SELF,&rusage);
3599 return(((LONG)(rusage.ru_utime.tv_sec)+(LONG)(rusage.ru_stime.tv_sec))*1000
3600 +(rusage.ru_utime.tv_usec/1000+rusage.ru_stime.tv_usec/1000));
3607#include <sys/time.h>
3608#include <sys/resource.h>
3612 struct rusage rusage;
3614 getrusage(RUSAGE_CHILDREN,&rusage);
3615 return(((LONG)(rusage.ru_utime.tv_sec)+(LONG)(rusage.ru_stime.tv_sec))*1000
3616 +(rusage.ru_utime.tv_usec/1000+rusage.ru_stime.tv_usec/1000));
3619 getrusage(RUSAGE_SELF,&rusage);
3620 return(((LONG)(rusage.ru_utime.tv_sec)+(LONG)(rusage.ru_stime.tv_sec))*1000
3621 +(rusage.ru_utime.tv_usec/1000+rusage.ru_stime.tv_usec/1000));
3626#include <sys/time.h>
3627#include <sys/resource.h>
3631 struct rusage rusage;
3633 getrusage(RUSAGE_CHILDREN,&rusage);
3634 return(((LONG)(rusage.ru_utime.tv_sec)+(LONG)(rusage.ru_stime.tv_sec))*1000
3635 +(rusage.ru_utime.tv_usec/1000+rusage.ru_stime.tv_usec/1000));
3638 getrusage(RUSAGE_SELF,&rusage);
3639 return(((LONG)(rusage.ru_utime.tv_sec)+(LONG)(rusage.ru_stime.tv_sec))*1000
3640 +(rusage.ru_utime.tv_usec/1000+rusage.ru_stime.tv_usec/1000));
3656#include <sys/time.h>
3657#include <sys/resource.h>
3658 struct rusage rusage;
3660 getrusage(RUSAGE_CHILDREN,&rusage);
3661 return(((LONG)(rusage.ru_utime.tv_sec)+(LONG)(rusage.ru_stime.tv_sec))*1000
3662 +(rusage.ru_utime.tv_usec/1000+rusage.ru_stime.tv_usec/1000));
3665 getrusage(RUSAGE_SELF,&rusage);
3666 return(((LONG)(rusage.ru_utime.tv_sec)+(LONG)(rusage.ru_stime.tv_sec))*1000
3667 +(rusage.ru_utime.tv_usec/1000+rusage.ru_stime.tv_usec/1000));
3671 clock_t tikken = clock();
3672 return((LONG)tikken/1000);
3674 clock_t t, tikken = clock();
3675 t = tikken % CLK_TCK;
3678 tikken += (t*1000)/CLK_TCK;
3686void times(tbuffer_t *buffer);
3692 if ( par == 1 ) {
return(0); }
3695 return(buffer.proc_user_time * 10);
3708#include <sys/types.h>
3709#include <sys/times.h>
3714#include <sys/time.h>
3715#include <sys/resource.h>
3723 if ( par == 1 ) {
return(0); }
3725 if ( ( AO.wrapnum & 1 ) != 0 ) t ^= 0x80000000;
3731 return(AO.wrap+(t/1000));
3736 ULONG a1, a2, a3, a4;
3737 if ( par == 1 ) {
return(0); }
3739 a1 = (ULONG)buffer.tms_utime;
3743 a2 = 1000*a2 + (a3 >> 16);
3748 ret = (LONG)((a4 << 16) + a3 / CLK_TCK);
3754 struct timezone tzp;
3755 if ( par == 1 ) {
return(0); }
3756 gettimeofday(&tp,&tzp); */
3757 return(tp.tv_sec*1000+tp.tv_usec/1000);
3759 struct rusage rusage;
3761 getrusage(RUSAGE_CHILDREN,&rusage);
3762 return((rusage.ru_utime.tv_sec+rusage.ru_stime.tv_sec)*1000
3763 +(rusage.ru_utime.tv_usec/1000+rusage.ru_stime.tv_usec/1000));
3766 getrusage(RUSAGE_SELF,&rusage);
3767 return((rusage.ru_utime.tv_sec+rusage.ru_stime.tv_sec)*1000
3768 +(rusage.ru_utime.tv_usec/1000+rusage.ru_stime.tv_usec/1000));
3814 int errorcode = 0, coeffsize;
3815 WORD *t, *tt, *tstop, *endterm, *targ, *targstop, *funstop, *argterm;
3816 endterm = term + *term;
3817 coeffsize = ABS(endterm[-1]);
3818 if ( coeffsize >= *term ) {
3820 MLOCK(ErrorMessageLock);
3821 MesPrint(
"!>TestTerm: Internal inconsistency in term. Coefficient too big.");
3822 MUNLOCK(ErrorMessageLock);
3827 if ( ( coeffsize < 3 ) || ( ( coeffsize & 1 ) != 1 ) ) {
3829 MLOCK(ErrorMessageLock);
3830 MesPrint(
"!>TestTerm: Internal inconsistency in term. Wrong size coefficient.");
3831 MUNLOCK(ErrorMessageLock);
3837 tstop = endterm - coeffsize;
3838 while ( t < tstop ) {
3850 MLOCK(ErrorMessageLock);
3851 MesPrint(
"!>TestTerm: Internal inconsistency in term. L or S number");
3852 MUNLOCK(ErrorMessageLock);
3859 case DOLLAREXPRESSION:
3873 MLOCK(ErrorMessageLock);
3874 MesPrint(
"!>TestTerm: Internal inconsistency in term. Illegal subterm.");
3875 MUNLOCK(ErrorMessageLock);
3885 MLOCK(ErrorMessageLock);
3886 MesPrint(
"!>TestTerm: Internal inconsistency in term. Illegal subterm number.");
3887 MUNLOCK(ErrorMessageLock);
3895 if ( *t-FUNCTION >= NumFunctions ) {
3897 MLOCK(ErrorMessageLock);
3898 MesPrint(
"!>TestTerm: Internal inconsistency in term. Illegal function number");
3899 MUNLOCK(ErrorMessageLock);
3905 if ( funstop > tstop )
goto subtermsize;
3908 MLOCK(ErrorMessageLock);
3909 MesPrint(
"!>TestTerm: Internal inconsistency in term. Dirty flag nonzero.");
3910 MUNLOCK(ErrorMessageLock);
3916 if ( targ > funstop ) {
3918 MLOCK(ErrorMessageLock);
3919 MesPrint(
"!>TestTerm: Internal inconsistency in term. Illegal function size.");
3920 MUNLOCK(ErrorMessageLock);
3925 if ( functions[*t-FUNCTION].spec >= TENSORFUNCTION ) {
3928 while ( targ < funstop ) {
3930 if ( *targ <= -(FUNCTION+NumFunctions) ) {
3932 MLOCK(ErrorMessageLock);
3933 MesPrint(
"!>TestTerm: Internal inconsistency in term. Illegal function number in argument.");
3934 MUNLOCK(ErrorMessageLock);
3939 if ( *targ <= -FUNCTION ) { targ++; }
3941 if ( ( *targ != -SYMBOL ) && ( *targ != -VECTOR )
3942 && ( *targ != -MINVECTOR )
3943 && ( *targ != -SNUMBER )
3944 && ( *targ != -ARGWILD )
3945 && ( *targ != -INDEX ) ) {
3947 MLOCK(ErrorMessageLock);
3948 MesPrint(
"!>TestTerm: Internal inconsistency in term. Illegal object in argument.");
3949 MUNLOCK(ErrorMessageLock);
3957 else if ( ( *targ < ARGHEAD ) || ( targ+*targ > funstop ) ) {
3959 MLOCK(ErrorMessageLock);
3960 MesPrint(
"!>TestTerm: Internal inconsistency in term. Illegal size of argument.");
3961 MUNLOCK(ErrorMessageLock);
3966 else if ( targ[1] != 0 ) {
3968 MLOCK(ErrorMessageLock);
3969 MesPrint(
"!>TestTerm: Internal inconsistency in term. Dirty flag in argument.");
3970 MUNLOCK(ErrorMessageLock);
3976 targstop = targ + *targ;
3977 argterm = targ + ARGHEAD;
3978 while ( argterm < targstop ) {
3979 if ( ( *argterm < 4 ) || ( argterm + *argterm > targstop ) ) {
3981 MLOCK(ErrorMessageLock);
3982 MesPrint(
"!>TestTerm: Internal inconsistency in term. Illegal termsize in argument.");
3983 MUNLOCK(ErrorMessageLock);
3990 MLOCK(ErrorMessageLock);
3991 MesPrint(
"!>TestTerm: Internal inconsistency in term. Called from TestTerm.");
3992 MUNLOCK(ErrorMessageLock);
3997 argterm += *argterm;
4009 MLOCK(ErrorMessageLock);
4010 MesPrint(
"!>TestTerm: Internal inconsistency in term. Illegal subterm size.");
4011 MUNLOCK(ErrorMessageLock);
4028int DistrN(
int n,
int *cpl,
int ncpl,
int *scratch)
4039 if ( scratch[0] == -2 ) { scratch[0] = 0;
return(1); }
4042 if ( scratch[0] == ncpl-1 ) {
4045 else if ( scratch[0] == -2 ) {
4046 for ( i = 0; i < n; i++ ) scratch[i] = 0;
4052 if ( scratch[j] < ncpl )
break;
4056 while ( j < n ) { scratch[j] = scratch[j-1]; j++; }
4058 for ( i = 0; i < ncpl; i++ ) cpl[i] = 0;
4059 for ( i = 0; i < n; i++ ) { cpl[scratch[i]]++; }
int PutPreVar(UBYTE *, UBYTE *, UBYTE *, int)
int PF_Bcast(void *buffer, int count)
LONG PF_WriteFileToFile(int handle, UBYTE *buffer, LONG size)
LONG PF_BroadcastNumber(LONG x)
struct bit_field * one_byte
struct bit_field set_of_char[32]