#include <stdio.h> #include <string.h> #include <stdlib.h> #include "struct.h" /* * Executive.c: Version 1.10 * Author: Alan Cox * Last Changed: 14/12/90 * * Purpose: * Provides a re-entrant executive for interpreting the system * tables, and executing actions. Provides error reporting for the * failure situations also. * * Bugs & Limits * * Functions Provided: * ReportError,GoSplat,ExecTable,ExecLine,NextLineMove,GetCLine, * SetCLine,Arg,TQuery,TQuery2,NQuery,NQuery2,DoConsult. * * Functions Used: * panic,DoRedraw,Exec_Cmd. * */ static LINE *nln; extern TABLE *Table; extern char **Messages; tag SysFlags[256]; int CurTable= -1; int CurLine= -1; int CurStat= -1; void ReportError(file,line,m) char *file; int line; int m; { log_error("Error: File %s Line %d, Invalid item reference of %d.\n",file,line,m); log_error("Table %d Line %d (MAXITEM=%d).\n",CurTable,CurLine,NObs()); panic(); } void ReportLines() { fprintf(stderr,"Table %d Line %d Stat %d (MAXITEM=%d).\n",CurTable,CurLine,CurStat,NObs()); fflush(stderr); } void MsgError(file,line,m) char *file; int line; char *m; { log_error("Error: File %s Line %d, %s.\n",file,line,m); log_error("Table %d Line %d (MAXITEM=%d).\n",CurTable,CurLine,NObs()); panic(); } void GoSplat() { FILE *f=fopen("fail_report","a"); fprintf(f,"Caught signal: Table %d Line %d Stat %d.\n",CurTable,CurLine,CurStat); fprintf(f,"Abandoning all hope!\n"); fclose(f); panic(); } /* * Run a table - REENTRANT */ struct StackFrame *StackContext() { struct StackFrame *Frame=(struct StackFrame *)malloc( sizeof(struct StackFrame)); if(Frame==NULL) { log_error("Out of memory.\n"); panic(); } bzero((char *)Frame,sizeof(*Frame)); Frame->Previous=SysStack; SysStack=Frame; return(Frame); } void RestoreContext() { struct StackFrame *t=SysStack; SysStack=t->Previous; free((char *)t); } void ExecTable(n) int n; { DoExecTable(Table[n],n); } int DoExecTable(n,nm) TABLE n; int nm; { static int Recurse=0; LINE *ol=nln; int ot=CurTable; int pl=CurLine; int os=CurStat; if(Booted==0) return(0); /* Dont run tables till boot complete */ /* ie - tables from queries! */ if(n==NULL) return(0); /* Nothing to run */ CurStat=0; if(Recurse>MAXRECURSE) { log_error("[EXECUTIVE]: Recursive Trap\n"); return(-1); } StackContext(); SeekFor=0; /* printf("EXECT-OK\n");*/ Recurse++; CurLine=0; CurTable=nm; nln=n; while(1)/*nln[0][0]!=-1)*/ { if(ExecLine(*nln)==5) /* DONE */ break; nln++; CurLine++; } nln=ol; CurTable=ot; CurLine=pl; CurStat=os; if(CurTable==-1) DoRedraw(); /* Redraw of screen status */ Recurse--; RestoreContext(); return(0); } static LINE tl; /* * Run a line REENTRANT */ ExecLine(n) LINE n; { extern int SeekFor; LINE otl=tl; tl=n; /* printf("[%d,%d,%d]\n",tl[0],tl[1],tl[2]);*/ if(tl[0]!=-1&&tl[0]!=NUM(SysFlags[3])) /* Verb ? */ { tl=otl; return(1); } if(tl[1]!=-1&&tl[1]!=NUM(SysFlags[1])) /* Noun1 */ { tl=otl; return(1); } if(tl[2]!=-1&&tl[2]!=NUM(SysFlags[2])) /* Noun2 */ { tl=otl; return(1); } /* printf(".(%d,%d,%d)\n",NUM(SysFlags[3]),NUM(SysFlags[1]),NUM(SysFlags[2]));*/ CurStat=0; tl+=3; /* Point at data */ while(*tl!=-1) { int nf,v; nf=0; /* printf("{%d}",*tl);*/ if(*tl==255) /* NOT /'-' marker*/ { nf=1; tl++; /* printf("{%d}",*tl); */ } if(*tl==0&&SeekFor==0) /* DONE */ { tl=otl; return(5); } v=ExecCmd(*tl); /* Do function */ CurStat++; if((v&&nf)||((!v)&&(!nf))) { tl=otl; return(0); /* Condition failed */ } tl++; } tl=otl; return(0); } void NextLineMove(v) /* Shift line */ int v; { nln+=v; CurLine+=v; } GetCLine() { return(CurLine); } void SetCLine(v) int v; { NextLineMove(v-GetCLine()-1); } /* * Obtain an argument */ tag Arg() { tag v; v= *++tl; if(IFOBJ(v)&&VAL(v)>30999) /* ?x */ { return(LOC(ISOBJ(VAL(v)-31000))); } if(IFNUM(v)&&VAL(v)>29999) /* !x */ { return(SysFlags[VAL(v)-30000]); } return(v); } char *TQuery(i,def,c) tag i; char *def; int c; { tag sa_flags[19]; if(OBJECT(i)->ob_Table==NULL) return(def); memcpy((char *)sa_flags,(char *)SysFlags,19*sizeof(tag)); /* OBJ(i); /* check is an object */ SysFlags[8]=SysFlags[0]; SysFlags[0]=i; SysFlags[1]= ISNUM(-1); SysFlags[2]= ISNUM(-1); SysFlags[3]= ISNUM(c); SysFlags[17]= ISNUM(-1); if(DoExecTable(OBJECT(i)->ob_Table,-i)==-1) { log_error("Reference was: %s [query code %d] default=%s\n", OBJECT(i)->ob_Name,c,def); } c=SysFlags[17]; memcpy((char *)SysFlags,(char *)sa_flags,19*sizeof(tag)); if(VAL(c)==-1) return(def); else return(Messages[MSG(c)]); } char *TQuery2(i,def,c,d) tag i; char *def; int c,d; { tag sa_flags[19]; if(OBJECT(i)->ob_Table==NULL) return(def); memcpy((char *)sa_flags,(char *)SysFlags,19*sizeof(tag)); /*OBJ(i);*/ SysFlags[8]=SysFlags[0]; SysFlags[0]=i; SysFlags[1]= ISNUM(-1); SysFlags[2]= ISNUM(-1); SysFlags[3]= ISNUM(c); SysFlags[17]= ISNUM(-1); SysFlags[18]= ISNUM(d); if(DoExecTable(OBJECT(i)->ob_Table,-i)==-1) { log_error("Reference was: %s [query code %d] default=%s\n", OBJECT(i)->ob_Name,c,def); } c=SysFlags[17]; memcpy((char *)SysFlags,(char *)sa_flags,19*sizeof(tag)); if(VAL(c)==-1) return(def); else return(Messages[MSG(c)]); } tag NQuery(i,def,c) tag i; int def; int c; { tag rv=def; tag sa_flags[19]; if(OBJECT(i)->ob_Table==NULL) return(def); memcpy((char *)sa_flags,(char *)SysFlags,19*sizeof(tag)); /*OBJ(i);*/ SysFlags[8]=SysFlags[0]; SysFlags[0]=i; SysFlags[1]= ISNUM(-1); SysFlags[2]= ISNUM(-1); SysFlags[3]= ISNUM(c); SysFlags[17]= ISNUM(def); SysFlags[18]= ISNUM(-1); if(DoExecTable(OBJECT(i)->ob_Table,-i)==-1) { log_error("Reference was: %s [query code %d] default=%s\n", OBJECT(i)->ob_Name,c,def); } if(VAL(SysFlags[18])!= -1) rv=VAL(SysFlags[18]); memcpy((char *)SysFlags,(char *)sa_flags,19*sizeof(tag)); /*NUM(rv);*/ return(rv); } tag NQuery2(i,def,c,d) tag i; int def; int c,d; { tag rv; tag sa_flags[19]; if(OBJECT(i)->ob_Table==NULL) return(def); memcpy((char *)sa_flags,(char *)SysFlags,19*sizeof(tag)); SysFlags[8]=SysFlags[0]; SysFlags[0]=i; SysFlags[1]=ISNUM(-1); SysFlags[2]=ISNUM(-1); SysFlags[3]= ISNUM(c); SysFlags[17]= ISNUM(def); SysFlags[18]=ISNUM(d); if(DoExecTable(OBJECT(i)->ob_Table,-i)==-1) { log_error("Reference was: %s [query code %d] default=%s\n", OBJECT(i)->ob_Name,c,def); } rv=SysFlags[17]; if(VAL(SysFlags[18])==-1) rv=def; memcpy((char *)SysFlags,(char *)sa_flags,19*sizeof(tag)); return(rv); } void DoConsult(i,v,n,n2) tag i; int v,n,n2; { tag sa_flags[19]; if(OBJECT(i)->ob_Table==NULL) return; memcpy((char *)sa_flags,(char *)SysFlags,19*sizeof(tag)); SysFlags[8]=SysFlags[0]; SysFlags[0]=i; SysFlags[1]=ISNUM(n); SysFlags[2]=ISNUM(n2); SysFlags[3]=ISNUM(v); if(DoExecTable(OBJECT(i)->ob_Table,-i)==-1) { log_error("Reference was: %s [consult code %d]\n", OBJECT(i)->ob_Name,v); } memcpy((char *)SysFlags,(char *)sa_flags,19*sizeof(tag)); return; }