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);
366 MLOCK(ErrorMessageLock);
367 MesPrint(
"Cannot create spectator file %s",fi->name);
368 MUNLOCK(ErrorMessageLock);
369 UNLOCK(fi->pthreadslock);
373 SeekFile(fi->
handle,&(sp->position),SEEK_SET);
374 if ( ( RetCode = WriteFile(fi->
handle,(UBYTE *)(fi->PObuffer),fi->POsize) ) != fi->POsize ) {
375 MLOCK(ErrorMessageLock);
376 MesPrint(
"Error during spectator write. Disk full?");
377 MesPrint(
"Attempt to write %l bytes on file %d at position %15p",
378 fi->POsize,fi->
handle,&(fi->POposition));
379 MesPrint(
"RetCode = %l, Buffer address = %l",RetCode,(LONG)(fi->PObuffer));
380 MUNLOCK(ErrorMessageLock);
381 UNLOCK(fi->pthreadslock);
384 ADDPOS(fi->filesize,fi->POsize);
386 ADDPOS(sp->position,fi->POsize);
387 fi->POposition = sp->position;
391 fi->POfull = fi->POfill = p;
392 Expressions[AM.SpectatorFiles[specnum].exprnumber].counter++;
393 UNLOCK(fi->pthreadslock);
402void FlushSpectators(
void)
409 if ( AM.NumSpectatorFiles <= 0 )
return;
410 for ( i = 0; i < AM.SizeForSpectatorFiles; i++, sp++ ) {
411 if ( sp->name == 0 )
continue;
413 if ( ( sp->flags & READSPECTATORFLAG ) != 0 ) {
414 sp->flags &= ~READSPECTATORFLAG;
415 fh->POfill = fh->PObuffer;
417 SeekFile(fh->
handle,&(sp->position),SEEK_SET);
418 fh->POposition = sp->position;
422 if ( fh->POfill <= fh->PObuffer )
continue;
424 if ( ( RetCode = CreateFile(fh->name) ) >= 0 ) {
425 PUTZERO(fh->filesize);
426 PUTZERO(fh->POposition);
427 fh->
handle = (WORD)RetCode;
430 MLOCK(ErrorMessageLock);
431 MesPrint(
"Cannot create spectator file %s",fh->name);
432 MUNLOCK(ErrorMessageLock);
435 PUTZERO(sp->position);
437 SeekFile(fh->
handle,&(sp->position),SEEK_SET);
438 size = (fh->POfill - fh->PObuffer)*
sizeof(WORD);
439 if ( ( RetCode = WriteFile(fh->
handle,(UBYTE *)(fh->PObuffer),size) ) != size ) {
440 MLOCK(ErrorMessageLock);
441 MesPrint(
"Write error synching spectator file. Disk full?");
442 MesPrint(
"Attempt to write %l bytes on file %s at position %15p",
443 size,fh->name,&(sp->position));
444 MUNLOCK(ErrorMessageLock);
447 fh->POfill = fh->PObuffer;
448 SeekFile(fh->
handle,&(sp->position),SEEK_END);
449 fh->POposition = sp->position;
459int CoCopySpectator(UBYTE *inp)
462 UBYTE *q, c, *exprname, *p;
463 WORD c1, c2, numexpr;
464 int specnum, error = 0;
466 while ( *inp ==
',' ) inp++;
467 if ( ( q =
SkipAName(inp) ) == 0 || q[-1] ==
'_' ) {
468 MesPrint(
"&Illegal name for expression");
471 if ( *q == 0 )
goto Syntax;
473 if ( GetVar(inp,&c1,&c2,ALLVARIABLES,NOAUTO) != NAMENOTFOUND ) {
474 MesPrint(
"&%s is the name of an existing variable.",inp);
477 numexpr = EntVar(CEXPRESSION,inp,LOCALEXPRESSION,0,0,0);
481 while ( *q ==
' ' || *q ==
',' || *q ==
'\t' ) q++;
482 if ( *q !=
'=' )
goto Syntax;
484 while ( *q ==
' ' || *q ==
',' || *q ==
'\t' ) q++;
486 if ( ( q =
SkipAName(inp) ) == 0 || q[-1] ==
'_' ) {
487 MesPrint(
"&Illegal name for spectator expression");
490 if ( *q != 0 )
goto Syntax;
491 if ( AM.NumSpectatorFiles <= 0 ) {
492 MesPrint(
"&CopySpectator: There are no spectator expressions!");
495 sp = AM.SpectatorFiles;
496 for ( specnum = 0; specnum < AM.SizeForSpectatorFiles; specnum++, sp++ ) {
497 if ( sp->name != 0 ) {
498 if ( StrCmp((UBYTE *)(sp->name),(UBYTE *)(inp)) == 0 )
break;
501 if ( specnum >= AM.SizeForSpectatorFiles ) {
502 MesPrint(
"&Spectator %s not found.",inp);
505 sp->flags |= READSPECTATORFLAG;
506 PUTZERO(sp->fh->POposition);
507 PUTZERO(sp->readpos);
508 sp->fh->POfill = sp->fh->PObuffer;
509 if ( sp->fh->
handle >= 0 ) {
510 SeekFile(sp->fh->
handle,&(sp->fh->POposition),SEEK_SET);
524 OldWork = w = AT.WorkPointer;
525 *w++ = TYPEEXPRESSION;
529 AR.CurExpr = numexpr;
530 *w++ = SUBEXPRESSION;
540 SeekScratch(AR.outfile,&pos);
541 Expressions[numexpr].counter = 1;
542 Expressions[numexpr].onfile = pos;
543 Expressions[numexpr].whichbuffer = 0;
545 Expressions[numexpr].partodo = AC.inparallelflag;
547 OldWork[2] = w - OldWork - 3;
550 if (
PutOut(BHEAD OldWork+2,&pos,AR.outfile,0) < 0 ) {
552 MesPrint(
"&Cannot create expression %s",exprname);
557 OldWork[2] = 4+SUBEXPSIZE;
558 OldWork[4] = SUBEXPSIZE;
559 OldWork[5] = numexpr;
560 OldWork[SUBEXPSIZE+3] = 1;
561 OldWork[SUBEXPSIZE+4] = 1;
562 OldWork[SUBEXPSIZE+5] = 3;
563 OldWork[SUBEXPSIZE+6] = 0;
564 if (
PutOut(BHEAD OldWork+2,&pos,AR.outfile,0) < 0
567 MesPrint(
"&Cannot create expression %s",exprname);
571 AR.outfile->POfull = AR.outfile->POfill;
573 OldWork[2] = numexpr;
579 AT.WorkPointer = OldWork;
580 if ( AC.dumnumflag ) Add2Com(TYPEDETCURDUM)
586 AC.mparallelflag |= NOPARALLEL_SPECTATOR;
590 MesPrint(
"&Proper syntax is: CopySpectator,exprname=spectatorname;");
601WORD GetFromSpectator(WORD *term,WORD specnum)
603 SPECTATOR *sp = &(AM.SpectatorFiles[specnum]);
605 WORD i, size, *t = term;
607 if ( fh-> handle < 0 ) {
617 if ( ISZEROPOS(sp->readpos) ) {
619 SeekFile(fh->
handle,&(sp->readpos),SEEK_SET);
620 InIn = ReadFile(fh->
handle,(UBYTE *)(fh->PObuffer),fh->POsize);
621 if ( InIn < 0 || ( InIn & 1 ) ) {
622 MLOCK(ErrorMessageLock);
623 MesPrint(
"Error reading information for %s spectator",sp->name);
624 MUNLOCK(ErrorMessageLock);
627 InIn /=
sizeof(WORD);
628 if ( InIn == 0 ) { *term = 0;
return(0); }
629 SeekFile(fh->
handle,&(sp->readpos),SEEK_CUR);
630 fh->POposition = sp->readpos;
631 fh->POfull = fh->PObuffer+InIn;
632 fh->POfill = fh->PObuffer;
634 if ( fh->POfill == fh->POfull ) {
635 if ( ISLESSPOS(sp->readpos,sp->position) )
goto FillBuffer;
639 size = *fh->POfill++; *t++ = size;
640 for ( i = 1; i < size; i++ ) {
641 if ( fh->POfill >= fh->POfull ) {
642 SeekFile(fh->
handle,&(sp->readpos),SEEK_SET);
643 InIn = ReadFile(fh->
handle,(UBYTE *)(fh->PObuffer),fh->POsize);
644 if ( InIn < 0 || ( InIn & 1 ) ) {
645 MLOCK(ErrorMessageLock);
646 MesPrint(
"Error reading information for %s spectator",sp->name);
647 MUNLOCK(ErrorMessageLock);
650 InIn /=
sizeof(WORD);
652 MLOCK(ErrorMessageLock);
653 MesPrint(
"Reading incomplete information for %s spectator",sp->name);
654 MUNLOCK(ErrorMessageLock);
657 SeekFile(fh->
handle,&(sp->readpos),SEEK_CUR);
658 fh->POposition = sp->readpos;
659 fh->POfull = fh->PObuffer+InIn;
660 fh->POfill = fh->PObuffer;
662 *t++ = *fh->POfill++;
675void ClearSpectators(WORD par)
680 if ( AM.NumSpectatorFiles > 0 ) {
681 for ( i = 0; i < AM.SizeForSpectatorFiles; i++, sp++ ) {
682 if ( sp->name == 0 )
continue;
683 if ( ( sp->flags & GLOBALSPECTATORFLAG ) == 1 && par == STOREMODULE )
continue;
685 if ( GetVar((UBYTE *)(sp->name),&c1,&numexpr,ALLVARIABLES,NOAUTO) == NAMENOTFOUND ||
686 c1 != CEXPRESSION ) {
687 MesPrint(
"&%s is not a valid expression.",sp->name);
690 Expressions[numexpr].status = DROPPEDEXPRESSION;
691 if ( sp->fh->
handle != -1 ) {
692 CloseFile(sp->fh->
handle);
694 remove(sp->fh->name);
696 M_free(sp->fh,
"Temporary FileHandle");
697 M_free(sp->name,
"Spectator expression name");
698 PUTZERO(sp->position);
703 AM.NumSpectatorFiles--;
UBYTE * SkipAName(UBYTE *s)
WORD PutOut(PHEAD WORD *, POSITION *, FILEHANDLE *, WORD)
int FlushOut(POSITION *, FILEHANDLE *, int)