Input source is parametrized all the way down.
authorEric S. Raymond <esr@thyrsus.com>
Tue, 23 May 2017 19:57:38 +0000 (15:57 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Thu, 23 Mar 2023 15:28:53 +0000 (11:28 -0400)
This means that, potentially, do_command() could be called on any text file
pointer and the right thing would happen.

actions1.c
actions2.c
funcs.h
main.c
misc.c
misc.h

index 1b0086bfdfe5bd415dfbed7d099468108e3aad10..66bad5e89017bb127e544326673eac0a61f04bb6 100644 (file)
@@ -14,7 +14,7 @@
 /*  Analyse a verb.  Remember what it was, go back for object if second word
  *  unless verb is "say", which snarfs arbitrary second word. */
 
-int action(long STARTAT) {
+int action(FILE *input, long STARTAT) {
        switch(STARTAT) {
           case 4000: goto L4000;
           case 4090: goto L4090;
@@ -269,7 +269,7 @@ L9094:      DROP(JADE,LOC);
 
 /*  Attack also moved into separate module. */
 
-L9120: return(attack());
+L9120: return(attack(input));
 
 /*  Pour.  If no object, or object is bottle, assume contents of bottle.
  *  special tests for pouring water or oil on plant or rusty door. */
@@ -349,11 +349,11 @@ L9160:    if(OBJ != LAMP)SPK=76;
 
 /*  Throw moved into separate module. */
 
-L9170: return(throw());
+L9170: return(throw(input));
 
 /*  Quit.  Intransitive only.  Verify intent and exit if that's what he wants. */
 
-L8180: if(YES(22,54,54)) score(1);
+L8180: if(YES(input,22,54,54)) score(1);
         return(2012);
 
 /*  Find.  Might be carrying it, or it might be here.  Else give caveat. */
@@ -446,7 +446,7 @@ L9270:      if(DARK(0)) goto L5190;
        PSPEAK(OBJ,OBJTXT[OBJ]+PROP[OBJ]);
         return(2012);
 
-L9275: CLSHNT=YES(192,193,54);
+L9275: CLSHNT=YES(input,192,193,54);
         return(2012);
 
 /*  Break.  Only works for mirror in repository and, of course, the vase. */
@@ -475,7 +475,7 @@ L9290:      if(OBJ != DWARF || !CLOSED) return(2011);
 
 L8300: SPK=201;
        RSPEAK(260);
-       if(!YES(200,54,54)) return(2012);
+       if(!YES(input,200,54,54)) return(2012);
        SAVED=SAVED+5;
        KK= -1;
 
@@ -525,7 +525,7 @@ L8305:      DATIME(I,K);
 L8310: KK=1;
        if(LOC == 1 && ABB[1] == 1) goto L8305;
        RSPEAK(268);
-       if(!YES(200,54,54)) return(2012);
+       if(!YES(input,200,54,54)) return(2012);
         goto L8305;
 
 L8312: SETPRM(1,K/10,MOD(K,10));
index 4385ad94fa4570e13e0cbd3995233fb41f0e605e..dcc649da04b43856bcace8eab25df80c5168c3f0 100644 (file)
@@ -131,7 +131,7 @@ L9028:      PROP[VASE]=2;
  *  objects fall into two categories: enemies (snake, dwarf, etc.)  and others
  *  (bird, clam, machine).  Ambiguous if 2 enemies, or no enemies but 2 others. */
 
-int attack() {
+int attack(FILE *input) {
        I=ATDWRF(LOC);
        if(OBJ != 0) goto L9124;
        if(I > 0)OBJ=DWARF;
@@ -176,7 +176,7 @@ L9126:      if(OBJ == 0)SPK=44;
        RSPEAK(49);
        VERB=0;
        OBJ=0;
-       GETIN(WD1,WD1X,WD2,WD2X);
+       GETIN(input,WD1,WD1X,WD2,WD2X);
        if(WD1 != MAKEWD(25) && WD1 != MAKEWD(250519)) return(2607);
        PSPEAK(DRAGON,3);
        PROP[DRAGON]=1;
@@ -214,7 +214,7 @@ L9129:      /*etc*/ ;
  *  and if dwarf is present then one might be killed.  (Only way to do so!)
  *  Axe also special for dragon, bear, and troll.  Treasures special for troll. */
 
-int throw() {
+int throw(FILE *cmdin) {
        if(TOTING(ROD2) && OBJ == ROD && !TOTING(ROD))OBJ=ROD2;
        if(!TOTING(OBJ)) return(2011);
        if(OBJ >= 50 && OBJ <= MAXTRS && AT(TROLL)) goto L9178;
@@ -230,7 +230,7 @@ int throw() {
        if(AT(OGRE)) goto L9175;
        if(HERE(BEAR) && PROP[BEAR] == 0) goto L9176;
        OBJ=0;
-       return(attack());
+       return(attack(cmdin));
 
 L9172: SPK=48;
        if(RAN(7) < DFLAG) goto L9175;
diff --git a/funcs.h b/funcs.h
index e86fb2cdf4bf90869c4d3bd411ea0f036bda47b4..455de2d6b78360ae63c24aaf9528feb70b969410 100644 (file)
--- a/funcs.h
+++ b/funcs.h
@@ -37,7 +37,7 @@
 #define OUTSID(LOC)    ((LOC) <= 8 || FOREST(LOC) || (LOC) == PLAC[SAPPH] || (LOC) == 180 || (LOC) == 182)
 #define INDEEP(LOC)    ((LOC) >= 15 && !OUTSID(LOC) && (LOC) != 179)
 
-extern int carry(void), discard(bool), attack(void), throw(void), feed(void), fill(void);
+extern int carry(void), discard(bool), attack(FILE *), throw(FILE *), feed(void), fill(void);
 void score(long);
 
 
diff --git a/main.c b/main.c
index 60e3dd07cc26d4f7597b842a374614dbe96e680d..de25b32a388cf642e4c34af86cc5886df7dfecd3 100644 (file)
--- a/main.c
+++ b/main.c
@@ -45,13 +45,13 @@ bool oldstyle = false;
 
 extern void initialise();
 extern void score(long);
-extern int action(long);
+extern int action(FILE *, long);
 
 /*
  * MAIN PROGRAM
  */
 
-static void do_command(void);
+static void do_command(FILE *);
 
 int main(int argc, char *argv[]) {
        int ch;
@@ -118,18 +118,18 @@ int main(int argc, char *argv[]) {
 L1:    SETUP= -1;
        I=RAN(-1);
        ZZWORD=RNDVOC(3,0)+MESH*2;
-       NOVICE=YES(65,1,0);
+       NOVICE=YES(stdin, 65,1,0);
        NEWLOC=1;
        LOC=1;
        LIMIT=330;
        if(NOVICE)LIMIT=1000;
 
        for (;;) {
-           do_command();
+           do_command(stdin);
        }
 }
 
-static void do_command(void) {
+static void do_command(FILE *cmdin) {
 
 /*  Can't leave cave once it's closing (except by main office). */
 
@@ -381,7 +381,7 @@ L2603:      if(!CLOSED) goto L2605;
 L2605: WZDARK=DARK(0);
        if(KNFLOC > 0 && KNFLOC != LOC)KNFLOC=0;
        I=RAN(1);
-       GETIN(WD1,WD1X,WD2,WD2X);
+       GETIN(cmdin, WD1,WD1X,WD2,WD2X);
 
 /*  Every input, check "FOOBAR" flag.  If zero, nothing's going on.  If pos,
  *  make neg.  If neg, he skipped a word, so make it zero. */
@@ -449,7 +449,7 @@ L4000:      I=4000; goto Laction;
 L4090: I=4090; goto Laction;
 L5000: I=5000;
 Laction:
-       switch (action(I)) {
+        switch (action(cmdin, I)) {
           case 2: return;
           case 8: goto L8;
           case 2000: goto L2000;
@@ -670,7 +670,7 @@ L90:        RSPEAK(23);
 
 L99:   if(CLOSNG) goto L95;
        NUMDIE=NUMDIE+1;
-       if(!YES(79+NUMDIE*2,80+NUMDIE*2,54)) score(0);
+       if(!YES(cmdin,79+NUMDIE*2,80+NUMDIE*2,54)) score(0);
        if(NUMDIE == MAXDIE) score(0);
        PLACE[WATER]=0;
        PLACE[OIL]=0;
@@ -713,10 +713,10 @@ L40000:    switch (HINT-1) { case 0: goto L40100; case 1: goto L40200; case 2: g
        BUG(27);
 
 L40010: HINTLC[HINT]=0;
-       if(!YES(HINTS[HINT][3],0,54)) goto L2602;
+       if(!YES(cmdin,HINTS[HINT][3],0,54)) goto L2602;
        SETPRM(1,HINTS[HINT][2],HINTS[HINT][2]);
        RSPEAK(261);
-       HINTED[HINT]=YES(175,HINTS[HINT][4],54);
+       HINTED[HINT]=YES(cmdin,175,HINTS[HINT][4],54);
        if(HINTED[HINT] && LIMIT > 30)LIMIT=LIMIT+30*HINTS[HINT][2];
 L40020: HINTLC[HINT]=0;
 L40030:  goto L2602;
diff --git a/misc.c b/misc.c
index b1f3f8367ad66f427dc1884bdcbb531a89f9b0b7..63052ced47351603e80fccdd31da28c47ca90cca 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -172,7 +172,7 @@ void fSETPRM(long FIRST, long P1, long P2) {
 #define WORD1X (*wORD1X)
 #define WORD2 (*wORD2)
 #define WORD2X (*wORD2X)
-void fGETIN(long *wORD1, long *wORD1X, long *wORD2, long *wORD2X) {
+void fGETIN(FILE *input, long *wORD1, long *wORD1X, long *wORD2, long *wORD2X) {
 long JUNK;
 
 /*  Get a command from the adventurer.  Snarf out the first word, pad it with
@@ -183,8 +183,8 @@ long JUNK;
 
 
 L10:   if(BLKLIN)TYPE0();
-       MAPLIN(stdin);
-       if(feof(stdin)) score(1);
+       MAPLIN(input);
+       if(input == stdin && feof(stdin)) score(1);
        WORD1=GETTXT(true,true,true,0);
        if(BLKLIN && WORD1 < 0) goto L10;
        WORD1X=GETTXT(false,true,true,0);
@@ -205,9 +205,9 @@ L22:        JUNK=GETTXT(false,true,true,0);
 #undef WORD1X
 #undef WORD2
 #undef WORD2X
-#define GETIN(WORD1,WORD1X,WORD2,WORD2X) fGETIN(&WORD1,&WORD1X,&WORD2,&WORD2X)
+#define GETIN(SRC,WORD1,WORD1X,WORD2,WORD2X) fGETIN(SRC,&WORD1,&WORD1X,&WORD2,&WORD2X)
 #undef YES
-long fYES(long X, long Y, long Z) {
+long fYES(FILE *input, long X, long Y, long Z) {
 
 long YES, REPLY, JUNK1, JUNK2, JUNK3;
 
@@ -215,7 +215,7 @@ long YES, REPLY, JUNK1, JUNK2, JUNK3;
  *  if no, print Z and return false. */
 
 L1:    RSPEAK(X);
-       GETIN(REPLY,JUNK1,JUNK2,JUNK3);
+       GETIN(input, REPLY,JUNK1,JUNK2,JUNK3);
        if(REPLY == MAKEWD(250519) || REPLY == MAKEWD(25)) goto L10;
        if(REPLY == MAKEWD(1415) || REPLY == MAKEWD(14)) goto L20;
        RSPEAK(185);
diff --git a/misc.h b/misc.h
index 19612b0c6af0e0dc8e6afe2c78f31a8cb779f8be..561ac52fe82e62f61e656d016544d8cc5c1df8f4 100644 (file)
--- a/misc.h
+++ b/misc.h
@@ -13,10 +13,10 @@ extern void fRSPEAK(long);
 #define RSPEAK(I) fRSPEAK(I)
 extern void fSETPRM(long,long,long);
 #define SETPRM(FIRST,P1,P2) fSETPRM(FIRST,P1,P2)
-extern void fGETIN(long*,long*,long*,long*);
-#define GETIN(WORD1,WORD1X,WORD2,WORD2X) fGETIN(&WORD1,&WORD1X,&WORD2,&WORD2X)
-extern long fYES(long,long,long);
-#define YES(X,Y,Z) fYES(X,Y,Z)
+extern void fGETIN(FILE *,long*,long*,long*,long*);
+#define GETIN(input,WORD1,WORD1X,WORD2,WORD2X) fGETIN(input,&WORD1,&WORD1X,&WORD2,&WORD2X)
+extern long fYES(FILE *,long,long,long);
+#define YES(input,X,Y,Z) fYES(input,X,Y,Z)
 extern long fGETNUM(FILE *);
 #define GETNUM(K) fGETNUM(K)
 extern long fGETTXT(long,long,long,long);