Gut and rebuild YES() with cleaner approach that doesn't rely on packing. 101/head
authorJason S. Ninneman <jsn@mbar.us>
Sun, 18 Jun 2017 20:37:51 +0000 (13:37 -0700)
committerJason S. Ninneman <jsn@mbar.us>
Sun, 18 Jun 2017 20:39:59 +0000 (13:39 -0700)
The new support functions get_input() and echo_input() (and others not made yet) will eventually replace GETIN() and MAPLIN().

actions.c
advent.h
main.c
misc.c
saveresume.c
tests/logopt.chk

index 1938d24be054ce6c904e8d0d7247013f23e39c70..5348d3d80033b1494e701806f6de8c02a6dceef2 100644 (file)
--- a/actions.c
+++ b/actions.c
@@ -792,7 +792,7 @@ static int pour(token_t verb, token_t obj)
 static int quit(FILE *input)
 /*  Quit.  Intransitive only.  Verify intent and exit if that's what he wants. */
 {
-    if (YES(input, REALLY_QUIT, OK_MAN, OK_MAN))
+    if (YES(REALLY_QUIT, OK_MAN, OK_MAN))
         terminate(quitgame);
     return GO_CLEAROBJ;
 }
@@ -820,7 +820,7 @@ static int read(FILE *input, token_t verb, token_t obj)
         return GO_CLEAROBJ;
     }
     if (obj == OYSTER && !game.clshnt) {
-        game.clshnt = YES(input, CLUE_QUERY, WAYOUT_CLUE, OK_MAN);
+        game.clshnt = YES(CLUE_QUERY, WAYOUT_CLUE, OK_MAN);
         return GO_CLEAROBJ;
     }
     PSPEAK(obj, OBJTXT[obj] + game.prop[obj]);
index 77c8079e6160ead8a349ae39d268f8ba9e975fe4..d23d8fd0a54948d71b83e073f9b5925b150c6980 100644 (file)
--- a/advent.h
+++ b/advent.h
@@ -83,6 +83,7 @@ extern bool oldstyle, editline, prompt;
 /* b is not needed for POSIX but harmless */
 #define READ_MODE "rb"
 #define WRITE_MODE "wb"
+extern void* xmalloc(size_t size);
 extern char* xstrdup(const char*);
 extern void packed_to_token(long, char token[]);
 extern void speak(const char*);
@@ -90,7 +91,9 @@ extern void PSPEAK(vocab_t,int);
 extern void RSPEAK(vocab_t);
 extern void SETPRM(long,long,long);
 extern bool GETIN(FILE *,token_t*,token_t*,token_t*,token_t*);
-extern long YES(FILE *,vocab_t,vocab_t,vocab_t);
+extern void echo_input(FILE*, char*, char*);
+extern char* get_input(void);
+extern bool YES(vocab_t, vocab_t, vocab_t);
 extern long GETTXT(bool,bool,bool);
 extern token_t MAKEWD(long);
 extern long VOCAB(long,long);
diff --git a/main.c b/main.c
index e5859b613622cd108ebda83fbb0033b5e74cbac8..b97e44c24872de5d95d1d6a3db6ee437b748301b 100644 (file)
--- a/main.c
+++ b/main.c
@@ -135,7 +135,7 @@ int main(int argc, char *argv[])
     game.loc = LOC_START;
     game.limit = 330;
     if (!rfp) {
-        game.novice = YES(stdin, WELCOME_YOU, CAVE_NEARBY, NO_MESSAGE);
+        game.novice = YES(WELCOME_YOU, CAVE_NEARBY, NO_MESSAGE);
         if (game.novice)game.limit = 1000;
     } else {
         restore(rfp);
@@ -251,11 +251,11 @@ static void checkhints(FILE *cmdin)
 
                 /* Fall through to hint display */
                 game.hintlc[hint] = 0;
-                if (!YES(cmdin, HINTS[hint][3], NO_MESSAGE, OK_MAN))
+                if (!YES(HINTS[hint][3], NO_MESSAGE, OK_MAN))
                     return;
                 SETPRM(1, HINTS[hint][2], HINTS[hint][2]);
                 RSPEAK(HINT_COST);
-                game.hinted[hint] = YES(cmdin, WANT_HINT, HINTS[hint][4], OK_MAN);
+                game.hinted[hint] = YES(WANT_HINT, HINTS[hint][4], OK_MAN);
                 if (game.hinted[hint] && game.limit > WARNTIME)
                     game.limit += WARNTIME * HINTS[hint][2];
             }
@@ -485,7 +485,7 @@ static void croak(FILE *cmdin)
         terminate(endgame);
     }
     /* FIXME: Arithmetic on message numbers */
-    else if (game.numdie == MAXDIE || !YES(cmdin, WATCH_IT + game.numdie * 2, WHICH_WAY + game.numdie * 2, OK_MAN))
+    else if (game.numdie == MAXDIE || !YES(WATCH_IT + game.numdie * 2, WHICH_WAY + game.numdie * 2, OK_MAN))
         terminate(endgame);
     else {
         game.place[WATER] = game.place[OIL] = NOWHERE;
diff --git a/misc.c b/misc.c
index 410dfd88542fbf700894d866ae520c0740b60ab2..aa4286bc570f6e29e40c06cb7fa620e9ee265674 100644 (file)
--- a/misc.c
+++ b/misc.c
 #include "linenoise/linenoise.h"
 #include "newdb.h"
 
+void* xmalloc(size_t size)
+{
+  void* ptr = malloc(size);
+  if (ptr == NULL)
+    {
+      fprintf(stderr, "Out of memory!\n");
+      exit(EXIT_FAILURE);
+    }
+  return(ptr);
+}
+
 char* xstrdup(const char* s)
 {
     char* ptr = strdup(s);
@@ -185,25 +196,101 @@ bool GETIN(FILE *input,
     }
 }
 
-long YES(FILE *input, vocab_t x, vocab_t y, vocab_t z)
+void echo_input(FILE* destination, char* input_prompt, char* input)
+{
+  size_t len = strlen(input_prompt) + strlen(input) + 1;
+  char* prompt_and_input = (char*) xmalloc(len);
+  strcpy(prompt_and_input, input_prompt);
+  strcat(prompt_and_input, input);
+  fprintf(destination, "%s\n", prompt_and_input);
+  free(prompt_and_input);
+}
+
+char* get_input()
+{ 
+  // Set up the prompt
+  char input_prompt[] = "> ";
+  if (!prompt)
+    input_prompt[0] = '\0';
+  
+  // Print a blank line if game.blklin tells us to.
+  if (game.blklin == true)
+    printf("\n");
+
+  char* input;
+  while (true)
+    {
+      if (editline)
+       input = linenoise(input_prompt);
+      else
+       {
+         input = NULL;
+         size_t n = 0;
+         if (isatty(0))
+           printf("%s", input_prompt);
+         getline(&input, &n, stdin);
+       }
+      
+      if (input == NULL) // Got EOF; quit.
+       exit(EXIT_SUCCESS);
+      else if (input[0] == '#') // Ignore comments.
+       continue;
+      else // We have a 'normal' line; leave the loop.
+       break;
+    }
+
+  // Strip trailing newlines from the input
+  input[strcspn(input, "\n")] = 0;
+
+  linenoiseHistoryAdd(input);
+
+  if (!isatty(0))
+    echo_input(stdout, input_prompt, input);
+
+  if (logfp)
+    echo_input(logfp, input_prompt, input);
+    
+  return(input);
+}
+
+bool YES(vocab_t question, vocab_t yes_response, vocab_t no_response)
 /*  Print message X, wait for yes/no answer.  If yes, print Y and return true;
  *  if no, print Z and return false. */
 {
-    token_t reply, junk1, junk2, junk3;
-
+    char* reply;
+    bool outcome;
+   
     for (;;) {
-        RSPEAK(x);
-        GETIN(input, &reply, &junk1, &junk2, &junk3);
-        if (reply == MAKEWD(250519) || reply == MAKEWD(25)) {
-            RSPEAK(y);
-            return true;
-        }
-        if (reply == MAKEWD(1415) || reply == MAKEWD(14)) {
-            RSPEAK(z);
-            return false;
-        }
-        RSPEAK(PLEASE_ANSWER);
+       RSPEAK(question);
+
+       reply = get_input();
+
+       char* firstword = (char*) xmalloc(strlen(reply));
+       sscanf(reply, "%s", firstword);
+
+       for (int i = 0; i < strlen(firstword); ++i)
+           firstword[i] = tolower(firstword[i]);
+       
+       int yes = strncmp("yes", reply, sizeof("yes") - 1);
+       int y = strncmp("y", reply, sizeof("y") - 1);
+       int no = strncmp("no", reply, sizeof("no") - 1);
+       int n = strncmp("n", reply, sizeof("n") - 1);
+       
+       if (yes == 0 || y == 0) {
+           RSPEAK(yes_response);
+           outcome = true;
+           break;
+       }
+       else if (no == 0 || n == 0) {
+           RSPEAK(no_response);
+           outcome = false;
+           break;
+       }
+       else
+           RSPEAK(PLEASE_ANSWER);
     }
+    linenoiseFree(reply);
+    return(outcome);
 }
 
 /*  Line-parsing routines (GETTXT, MAKEWD, PUTTXT, SHFTXT) */
index 6f570b9aab8a874fe4f0a3aad4b20468ef8ff4da..50091718bc25f125c57d76f3cef3fca06a76e191 100644 (file)
@@ -44,7 +44,7 @@ int suspend(FILE *input)
     FILE *fp = NULL;
 
     RSPEAK(SUSPEND_WARNING);
-    if (!YES(input, THIS_ACCEPTABLE, OK_MAN, OK_MAN)) return GO_CLEAROBJ;
+    if (!YES(THIS_ACCEPTABLE, OK_MAN, OK_MAN)) return GO_CLEAROBJ;
     game.saved = game.saved + 5;
 
     while (fp == NULL) {
@@ -83,7 +83,7 @@ int resume(FILE *input)
 
     if (game.loc != 1 || game.abbrev[1] != 1) {
         RSPEAK(RESUME_ABANDON);
-        if (!YES(input, THIS_ACCEPTABLE, OK_MAN, OK_MAN)) return GO_CLEAROBJ;
+        if (!YES(THIS_ACCEPTABLE, OK_MAN, OK_MAN)) return GO_CLEAROBJ;
     }
 
     while (fp == NULL) {
@@ -123,4 +123,4 @@ int restore(FILE* fp)
     return GO_TOP;
 }
 
-/* end */
\ No newline at end of file
+/* end */
index 1ed3c78d15741d06b0644a568a6ed23e2d74635c..06c8fba21e68448897469d9964190c8c6b81214f 100644 (file)
@@ -1,7 +1,8 @@
 
 Welcome to Adventure!!  Would you like instructions?
 
-> > > 
+> n
+
 You are standing at the end of a road before a small brick building.
 Around you is a forest.  A small stream flows out of the building and
 down a gully.