89int CoCreateSpectator(UBYTE *inp)
91 UBYTE *p, *q, *filename, c, cc;
92 WORD c1, c2, numexpr = 0, specnum, HadOne = 0;
94 while ( *inp ==
',' ) inp++;
95 if ( ( q =
SkipAName(inp) ) == 0 || q[-1] ==
'_' ) {
96 MesPrint(
"&Illegal name for expression");
100 if ( GetVar(inp,&c1,&c2,ALLVARIABLES,NOAUTO) != NAMENOTFOUND ) {
101 if ( c2 == CEXPRESSION &&
102 Expressions[c1].status == DROPSPECTATOREXPRESSION ) {
104 Expressions[numexpr].status = SPECTATOREXPRESSION;
108 MesPrint(
"&The name %s has been used already.",inp);
114 while ( *p ==
',' ) p++;
115 if ( *p !=
'"' )
goto Syntax;
117 while ( *p && *p !=
'"' ) {
118 if ( *p ==
'\\' ) p++;
121 if ( *p !=
'"' )
goto Syntax;
123 while ( *q && ( *q ==
',' || *q ==
' ' || *q ==
'\t' ) ) q++;
124 if ( *q )
goto Syntax;
130 numexpr = EntVar(CEXPRESSION,inp,SPECTATOREXPRESSION,0,0,0);
131 fh = AllocFileHandle(1,(
char *)filename);
135 if ( AM.NumSpectatorFiles >= AM.SizeForSpectatorFiles || AM.SpectatorFiles == 0 ) {
138 if ( AM.SizeForSpectatorFiles == 0 ) {
140 AM.NumSpectatorFiles = AM.SizeForSpectatorFiles = 0;
142 else newsize = AM.SizeForSpectatorFiles*2;
144 for ( i = 0; i < AM.NumSpectatorFiles; i++ )
145 newspectators[i] = AM.SpectatorFiles[i];
146 for ( ; i < newsize; i++ ) {
147 newspectators[i].fh = 0;
148 newspectators[i].name = 0;
149 newspectators[i].exprnumber = -1;
150 newspectators[i].flags = 0;
151 PUTZERO(newspectators[i].position);
152 PUTZERO(newspectators[i].readpos);
154 AM.SizeForSpectatorFiles = newsize;
155 if ( AM.SpectatorFiles != 0 ) M_free(AM.SpectatorFiles,
"Spectators");
156 AM.SpectatorFiles = newspectators;
157 specnum = AM.NumSpectatorFiles++;
160 for ( specnum = 0; specnum < AM.SizeForSpectatorFiles; specnum++ ) {
161 if ( AM.SpectatorFiles[specnum].name == 0 )
break;
163 AM.NumSpectatorFiles++;
165 PUTZERO(AM.SpectatorFiles[specnum].position);
166 AM.SpectatorFiles[specnum].name = (
char *)(strDup1(inp,
"Spectator expression name"));
167 AM.SpectatorFiles[specnum].fh = fh;
168 AM.SpectatorFiles[specnum].exprnumber = numexpr;
172 MesPrint(
"&Proper syntax is: CreateSpectator,exprname,\"filename\";");
181int CoToSpectator(UBYTE *inp)
186 while ( *inp ==
',' ) inp++;
187 if ( ( q =
SkipAName(inp) ) == 0 || q[-1] ==
'_' ) {
188 MesPrint(
"&Illegal name for expression");
191 if ( *q != 0 )
goto Syntax;
192 if ( GetVar(inp,&c1,&numexpr,ALLVARIABLES,NOAUTO) == NAMENOTFOUND ||
193 c1 != CEXPRESSION ) {
194 MesPrint(
"&%s is not a valid expression.",inp);
197 if ( Expressions[numexpr].status != SPECTATOREXPRESSION ) {
198 MesPrint(
"&%s is not an active spectator.",inp);
201 for ( i = 0; i < AM.SizeForSpectatorFiles; i++ ) {
202 if ( AM.SpectatorFiles[i].name != 0 ) {
203 if ( StrCmp((UBYTE *)(AM.SpectatorFiles[i].name),(UBYTE *)(inp)) == 0 )
break;
206 if ( i >= AM.SizeForSpectatorFiles ) {
207 MesPrint(
"&Spectator %s not found.",inp);
210 if ( ( AM.SpectatorFiles[i].flags & READSPECTATORFLAG ) != 0 ) {
211 MesPrint(
"&Spectator %s: It is not permitted to read from and write to the same spectator in one module.",inp);
214 AM.SpectatorFiles[i].exprnumber = numexpr;
215 Add3Com(TYPETOSPECTATOR,i);
220 AC.mparallelflag |= NOPARALLEL_SPECTATOR;
224 MesPrint(
"&Proper syntax is: ToSpectator,exprname;");
233int CoRemoveSpectator(UBYTE *inp)
239 while ( *inp ==
',' ) inp++;
240 if ( ( q =
SkipAName(inp) ) == 0 || q[-1] ==
'_' ) {
241 MesPrint(
"&Illegal name for expression");
244 if ( *q != 0 )
goto Syntax;
245 if ( GetVar(inp,&c1,&numexpr,ALLVARIABLES,NOAUTO) == NAMENOTFOUND ||
246 c1 != CEXPRESSION ) {
247 MesPrint(
"&%s is not a valid expression.",inp);
250 if ( Expressions[numexpr].status != SPECTATOREXPRESSION ) {
251 MesPrint(
"&%s is not a spectator.",inp);
254 for ( i = 0; i < AM.SizeForSpectatorFiles; i++ ) {
255 if ( AM.SpectatorFiles[i].name != 0 ) {
256 if ( StrCmp((UBYTE *)(AM.SpectatorFiles[i].name),(UBYTE *)(inp)) == 0 ) {
261 if ( i >= AM.SizeForSpectatorFiles ) {
262 MesPrint(
"&Spectator %s not found.",inp);
265 sp = AM.SpectatorFiles+i;
266 Expressions[numexpr].status = DROPSPECTATOREXPRESSION;
267 if ( sp->fh->
handle != -1 ) {
268 CloseFile(sp->fh->
handle);
270 remove(sp->fh->name);
272 M_free(sp->fh,
"Temporary FileHandle");
273 M_free(sp->name,
"Spectator expression name");
275 PUTZERO(sp->position);
276 PUTZERO(sp->readpos);
281 AM.NumSpectatorFiles--;
284 MesPrint(
"&Proper syntax is: RemoveSpectator,exprname;");
293int CoEmptySpectator(UBYTE *inp)
299 while ( *inp ==
',' ) inp++;
300 if ( ( q =
SkipAName(inp) ) == 0 || q[-1] ==
'_' ) {
301 MesPrint(
"&Illegal name for expression");
304 if ( *q != 0 )
goto Syntax;
305 if ( GetVar(inp,&c1,&numexpr,ALLVARIABLES,NOAUTO) == NAMENOTFOUND ||
306 c1 != CEXPRESSION ) {
307 MesPrint(
"&%s is not a valid expression.",inp);
310 if ( Expressions[numexpr].status != SPECTATOREXPRESSION ) {
311 MesPrint(
"&%s is not a spectator.",inp);
314 for ( i = 0; i < AM.SizeForSpectatorFiles; i++ ) {
315 if ( StrCmp((UBYTE *)(AM.SpectatorFiles[i].name),(UBYTE *)(inp)) == 0 )
break;
317 if ( i >= AM.SizeForSpectatorFiles ) {
318 MesPrint(
"&Spectator %s not found.",inp);
321 sp = AM.SpectatorFiles+i;
322 if ( sp->fh->
handle != -1 ) {
323 CloseFile(sp->fh->
handle);
325 remove(sp->fh->name);
327 sp->fh->POfill = sp->fh->POfull = sp->fh->PObuffer;
328 PUTZERO(sp->position);
329 PUTZERO(sp->readpos);
332 MesPrint(
"&Proper syntax is: EmptySpectator,exprname;");
345int PutInSpectator(WORD *term,WORD specnum)
350 SPECTATOR *sp = &(AM.SpectatorFiles[specnum]);
353 if ( ( i = *term ) <= 0 )
return(0);
354 LOCK(fi->pthreadslock);
358 if ( p >= fi->POstop ) {
360 if ( ( RetCode = CreateFile(fi->name) ) >= 0 ) {
361 fi->
handle = (WORD)RetCode;
362 PUTZERO(fi->filesize);
363 PUTZERO(fi->POposition);
367 MLOCK(ErrorMessageLock);
368 MesPrint(
"!>Cannot create spectator file %s",fi->name);
369 MUNLOCK(ErrorMessageLock);
370 UNLOCK(fi->pthreadslock);
375 SeekFile(fi->
handle,&(sp->position),SEEK_SET);
376 if ( ( RetCode = WriteFile(fi->
handle,(UBYTE *)(fi->PObuffer),fi->POsize) ) != fi->POsize ) {
377 MLOCK(ErrorMessageLock);
378 MesPrint(
"Error during spectator write. Disk full?");
379 MesPrint(
"Attempt to write %l bytes on file %d at position %15p",
380 fi->POsize,fi->
handle,&(fi->POposition));
381 MesPrint(
"RetCode = %l, Buffer address = %l",RetCode,(LONG)(fi->PObuffer));
382 MUNLOCK(ErrorMessageLock);
383 UNLOCK(fi->pthreadslock);
386 ADDPOS(fi->filesize,fi->POsize);
388 ADDPOS(sp->position,fi->POsize);
389 fi->POposition = sp->position;
393 fi->POfull = fi->POfill = p;
394 Expressions[AM.SpectatorFiles[specnum].exprnumber].counter++;
395 UNLOCK(fi->pthreadslock);
404void FlushSpectators(
void)
411 if ( AM.NumSpectatorFiles <= 0 )
return;
412 for ( i = 0; i < AM.SizeForSpectatorFiles; i++, sp++ ) {
413 if ( sp->name == 0 )
continue;
415 if ( ( sp->flags & READSPECTATORFLAG ) != 0 ) {
416 sp->flags &= ~READSPECTATORFLAG;
417 fh->POfill = fh->PObuffer;
419 SeekFile(fh->
handle,&(sp->position),SEEK_SET);
420 fh->POposition = sp->position;
424 if ( fh->POfill <= fh->PObuffer )
continue;
426 if ( ( RetCode = CreateFile(fh->name) ) >= 0 ) {
427 PUTZERO(fh->filesize);
428 PUTZERO(fh->POposition);
429 fh->
handle = (WORD)RetCode;
433 MLOCK(ErrorMessageLock);
434 MesPrint(
"!>Cannot create spectator file %s",fh->name);
435 MUNLOCK(ErrorMessageLock);
439 PUTZERO(sp->position);
441 SeekFile(fh->
handle,&(sp->position),SEEK_SET);
442 size = (fh->POfill - fh->PObuffer)*
sizeof(WORD);
443 if ( ( RetCode = WriteFile(fh->
handle,(UBYTE *)(fh->PObuffer),size) ) != size ) {
444 MLOCK(ErrorMessageLock);
445 MesPrint(
"Write error synching spectator file. Disk full?");
446 MesPrint(
"Attempt to write %l bytes on file %s at position %15p",
447 size,fh->name,&(sp->position));
448 MUNLOCK(ErrorMessageLock);
451 fh->POfill = fh->PObuffer;
452 SeekFile(fh->
handle,&(sp->position),SEEK_END);
453 fh->POposition = sp->position;
463int CoCopySpectator(UBYTE *inp)
466 UBYTE *q, c, *exprname, *p;
467 WORD c1, c2, numexpr;
468 int specnum, error = 0;
470 while ( *inp ==
',' ) inp++;
471 if ( ( q =
SkipAName(inp) ) == 0 || q[-1] ==
'_' ) {
472 MesPrint(
"&Illegal name for expression");
475 if ( *q == 0 )
goto Syntax;
477 if ( GetVar(inp,&c1,&c2,ALLVARIABLES,NOAUTO) != NAMENOTFOUND ) {
478 MesPrint(
"&%s is the name of an existing variable.",inp);
481 numexpr = EntVar(CEXPRESSION,inp,LOCALEXPRESSION,0,0,0);
485 while ( *q ==
' ' || *q ==
',' || *q ==
'\t' ) q++;
486 if ( *q !=
'=' )
goto Syntax;
488 while ( *q ==
' ' || *q ==
',' || *q ==
'\t' ) q++;
490 if ( ( q =
SkipAName(inp) ) == 0 || q[-1] ==
'_' ) {
491 MesPrint(
"&Illegal name for spectator expression");
494 if ( *q != 0 )
goto Syntax;
495 if ( AM.NumSpectatorFiles <= 0 ) {
496 MesPrint(
"&CopySpectator: There are no spectator expressions!");
499 sp = AM.SpectatorFiles;
500 for ( specnum = 0; specnum < AM.SizeForSpectatorFiles; specnum++, sp++ ) {
501 if ( sp->name != 0 ) {
502 if ( StrCmp((UBYTE *)(sp->name),(UBYTE *)(inp)) == 0 )
break;
505 if ( specnum >= AM.SizeForSpectatorFiles ) {
506 MesPrint(
"&Spectator %s not found.",inp);
509 sp->flags |= READSPECTATORFLAG;
510 PUTZERO(sp->fh->POposition);
511 PUTZERO(sp->readpos);
512 sp->fh->POfill = sp->fh->PObuffer;
513 if ( sp->fh->
handle >= 0 ) {
514 SeekFile(sp->fh->
handle,&(sp->fh->POposition),SEEK_SET);
528 OldWork = w = AT.WorkPointer;
529 *w++ = TYPEEXPRESSION;
533 AR.CurExpr = numexpr;
534 *w++ = SUBEXPRESSION;
544 SeekScratch(AR.outfile,&pos);
545 Expressions[numexpr].counter = 1;
546 Expressions[numexpr].onfile = pos;
547 Expressions[numexpr].whichbuffer = 0;
549 Expressions[numexpr].partodo = AC.inparallelflag;
551 OldWork[2] = w - OldWork - 3;
554 if (
PutOut(BHEAD OldWork+2,&pos,AR.outfile,0) < 0 ) {
556 MesPrint(
"&Cannot create expression %s",exprname);
561 OldWork[2] = 4+SUBEXPSIZE;
562 OldWork[4] = SUBEXPSIZE;
563 OldWork[5] = numexpr;
564 OldWork[SUBEXPSIZE+3] = 1;
565 OldWork[SUBEXPSIZE+4] = 1;
566 OldWork[SUBEXPSIZE+5] = 3;
567 OldWork[SUBEXPSIZE+6] = 0;
568 if (
PutOut(BHEAD OldWork+2,&pos,AR.outfile,0) < 0
571 MesPrint(
"&Cannot create expression %s",exprname);
575 AR.outfile->POfull = AR.outfile->POfill;
577 OldWork[2] = numexpr;
583 AT.WorkPointer = OldWork;
584 if ( AC.dumnumflag ) Add2Com(TYPEDETCURDUM)
590 AC.mparallelflag |= NOPARALLEL_SPECTATOR;
594 MesPrint(
"&Proper syntax is: CopySpectator,exprname=spectatorname;");
605WORD GetFromSpectator(WORD *term,WORD specnum)
607 SPECTATOR *sp = &(AM.SpectatorFiles[specnum]);
609 WORD i, size, *t = term;
611 if ( fh-> handle < 0 ) {
621 if ( ISZEROPOS(sp->readpos) ) {
623 SeekFile(fh->
handle,&(sp->readpos),SEEK_SET);
624 InIn = ReadFile(fh->
handle,(UBYTE *)(fh->PObuffer),fh->POsize);
625 if ( InIn < 0 || ( InIn & 1 ) ) {
627 MLOCK(ErrorMessageLock);
628 MesPrint(
"!>Error reading information for %s spectator",sp->name);
629 MUNLOCK(ErrorMessageLock);
633 InIn /=
sizeof(WORD);
634 if ( InIn == 0 ) { *term = 0;
return(0); }
635 SeekFile(fh->
handle,&(sp->readpos),SEEK_CUR);
636 fh->POposition = sp->readpos;
637 fh->POfull = fh->PObuffer+InIn;
638 fh->POfill = fh->PObuffer;
640 if ( fh->POfill == fh->POfull ) {
641 if ( ISLESSPOS(sp->readpos,sp->position) )
goto FillBuffer;
645 size = *fh->POfill++; *t++ = size;
646 for ( i = 1; i < size; i++ ) {
647 if ( fh->POfill >= fh->POfull ) {
648 SeekFile(fh->
handle,&(sp->readpos),SEEK_SET);
649 InIn = ReadFile(fh->
handle,(UBYTE *)(fh->PObuffer),fh->POsize);
650 if ( InIn < 0 || ( InIn & 1 ) ) {
652 MLOCK(ErrorMessageLock);
653 MesPrint(
"!>Error reading information for %s spectator",sp->name);
654 MUNLOCK(ErrorMessageLock);
658 InIn /=
sizeof(WORD);
661 MLOCK(ErrorMessageLock);
662 MesPrint(
"!>Reading incomplete information for %s spectator",sp->name);
663 MUNLOCK(ErrorMessageLock);
667 SeekFile(fh->
handle,&(sp->readpos),SEEK_CUR);
668 fh->POposition = sp->readpos;
669 fh->POfull = fh->PObuffer+InIn;
670 fh->POfill = fh->PObuffer;
672 *t++ = *fh->POfill++;
685void ClearSpectators(WORD par)
690 if ( AM.NumSpectatorFiles > 0 ) {
691 for ( i = 0; i < AM.SizeForSpectatorFiles; i++, sp++ ) {
692 if ( sp->name == 0 )
continue;
693 if ( ( sp->flags & GLOBALSPECTATORFLAG ) == 1 && par == STOREMODULE )
continue;
695 if ( GetVar((UBYTE *)(sp->name),&c1,&numexpr,ALLVARIABLES,NOAUTO) == NAMENOTFOUND ||
696 c1 != CEXPRESSION ) {
697 MesPrint(
"&%s is not a valid expression.",sp->name);
700 Expressions[numexpr].status = DROPPEDEXPRESSION;
701 if ( sp->fh->
handle != -1 ) {
702 CloseFile(sp->fh->
handle);
704 remove(sp->fh->name);
706 M_free(sp->fh,
"Temporary FileHandle");
707 M_free(sp->name,
"Spectator expression name");
708 PUTZERO(sp->position);
713 AM.NumSpectatorFiles--;
UBYTE * SkipAName(UBYTE *s)
WORD PutOut(PHEAD WORD *, POSITION *, FILEHANDLE *, WORD)
int FlushOut(POSITION *, FILEHANDLE *, int)