magic numbers, show usage, fixed linty warnings
[open-adventure.git] / misc.c
diff --git a/misc.c b/misc.c
index 410dfd88542fbf700894d866ae520c0740b60ab2..d097bad0a0b4e82c26c41ce1171e99541eb6b15a 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);
@@ -142,7 +153,7 @@ void SETPRM(long first, long p1, long p2)
  *  are stored into PARMS(first) and PARMS(first+1). */
 {
     if (first >= MAXPARMS)
-        BUG(29);
+        BUG(TOO_MANY_PARAMETERS_GIVEN_TO_SETPRM);
     else {
         PARMS[first] = p1;
         PARMS[first + 1] = p2;
@@ -185,25 +196,103 @@ 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);
+         IGNORE(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 < (int)strlen(firstword); ++i)
+           firstword[i] = tolower(firstword[i]);
+       
+       int yes = strncmp("yes", firstword, sizeof("yes") - 1);
+       int y = strncmp("y", firstword, sizeof("y") - 1);
+       int no = strncmp("no", firstword, sizeof("no") - 1);
+       int n = strncmp("n", firstword, sizeof("n") - 1);
+
+       free(firstword);
+       
+       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) */
@@ -295,7 +384,7 @@ long VOCAB(long id, long init)
             lexeme = -1;
             if (init < 0)
                 return (lexeme);
-            BUG(5);
+            BUG(REQUIRED_VOCABULARY_WORD_NOT_FOUND);
         }
         if (init >= 0 && KTAB[i] / 1000 != init)
             continue;
@@ -306,7 +395,7 @@ long VOCAB(long id, long init)
             return (lexeme);
         }
     }
-    BUG(21);
+    BUG(RAN_OFF_END_OF_VOCABULARY_TABLE);
 }
 
 void JUGGLE(long object)
@@ -408,7 +497,7 @@ long ATDWRF(long where)
 }
 
 /*  Utility routines (SETBIT, TSTBIT, set_seed, get_next_lcg_value,
- *  randrange, RNDVOC, BUG) */
+ *  randrange, RNDVOC) */
 
 long SETBIT(long bit)
 /*  Returns 2**bit for use in constructing bit-masks. */
@@ -470,36 +559,6 @@ long RNDVOC(long second, long force)
     return rnd;
 }
 
-void BUG(long num)
-/*  The following conditions are currently considered fatal bugs.  Numbers < 20
- *  are detected while reading the database; the others occur at "run time".
- *     0       Message line > 70 characters
- *     1       Null line in message
- *     2       Too many words of messages
- *     3       Too many travel options
- *     4       Too many vocabulary words
- *     5       Required vocabulary word not found
- *     6       Too many RTEXT messages
- *     7       Too many hints
- *     8       Location has cond bit being set twice
- *     9       Invalid section number in database
- *     10      Too many locations
- *     11      Too many class or turn messages
- *     20      Special travel (500>L>300) exceeds goto list
- *     21      Ran off end of vocabulary table
- *     22      Vocabulary type (N/1000) not between 0 and 3
- *     23      Intransitive action verb exceeds goto list
- *     24      Transitive action verb exceeds goto list
- *     25      Conditional travel entry with no alternative
- *     26      Location has no travel entries
- *     27      Hint number exceeds goto list
- *     28      Invalid month returned by date function
- *     29      Too many parameters given to SETPRM */
-{
-
-    printf("Fatal error %ld.  See source code for interpretation.\n", num);
-    exit(0);
-}
 
 /*  Machine dependent routines (MAPLIN, SAVEIO) */