Test Coverage -- lots of new pieces of actions.c
[open-adventure.git] / misc.c
diff --git a/misc.c b/misc.c
index fc7ac5f9a8af44059eefb5e73b803d7973c37c0d..09244625cfe0c536bb866fcf17eccf21356d5e48 100644 (file)
--- a/misc.c
+++ b/misc.c
 
 void* xmalloc(size_t size)
 {
-  void* ptr = malloc(size);
-  if (ptr == NULL)
-    {
-      fprintf(stderr, "Out of memory!\n");
-      exit(EXIT_FAILURE);
+    void* ptr = malloc(size);
+    if (ptr == NULL) {
+        fprintf(stderr, "Out of memory!\n");
+        exit(EXIT_FAILURE);
     }
-  return(ptr);
+    return (ptr);
 }
 
 char* xstrdup(const char* s)
@@ -51,6 +50,35 @@ void packed_to_token(long packed, char token[6])
     }
 }
 
+void token_to_packed(char token[6], long* packed)
+{
+  *packed = 0;
+  for (size_t i = 0; i < 5; ++i)
+    {
+      if (token[4 - i] == '\0')
+       continue;       
+      char mapped = ascii_to_advent[(int) token[4 - i]];
+      *packed |= (mapped << (6 * i));
+    }
+}
+
+/* Hide the fact that wods are corrently packed longs */
+
+bool wordeq(token_t a, token_t b)
+{
+    return a == b;
+}
+
+bool wordempty(token_t a)
+{
+    return a == 0;
+}
+
+void wordclear(token_t *v)
+{
+    *v = 0;
+}
+
 /*  I/O routines (SPEAK, PSPEAK, RSPEAK, SETPRM, GETIN, YES) */
 
 void speak(const char* msg)
@@ -153,7 +181,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;
@@ -198,101 +226,101 @@ bool GETIN(FILE *input,
 
 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);
+    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;
+{
+    // 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; return with it.
+           return(input);
+        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;
+    // Strip trailing newlines from the input
+    input[strcspn(input, "\n")] = 0;
+
+    linenoiseHistoryAdd(input);
 
-  linenoiseHistoryAdd(input);
+    if (!isatty(0))
+        echo_input(stdout, input_prompt, input);
 
-  if (!isatty(0))
-    echo_input(stdout, input_prompt, input);
+    if (logfp)
+        echo_input(logfp, input_prompt, input);
 
-  if (logfp)
-    echo_input(logfp, input_prompt, input);
-    
-  return(input);
+    return (input);
 }
 
-bool YES(vocab_t question, vocab_t yes_response, vocab_t no_response)
+bool YES(const char* question, const char* yes_response, const char* no_response)
 /*  Print message X, wait for yes/no answer.  If yes, print Y and return true;
  *  if no, print Z and return false. */
 {
     char* reply;
     bool outcome;
-   
+
     for (;;) {
-       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", 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;
+        speak(question);
+
+        reply = get_input();
+       if (reply == NULL) {
+         linenoiseFree(reply);
+         exit(EXIT_SUCCESS);
        }
-       else
-           RSPEAK(PLEASE_ANSWER);
+
+        char* firstword = (char*) xmalloc(strlen(reply)+1);
+        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) {
+            speak(yes_response);
+            outcome = true;
+            break;
+        } else if (no == 0 || n == 0) {
+            speak(no_response);
+            outcome = false;
+            break;
+        } else
+            RSPEAK(PLEASE_ANSWER);
     }
     linenoiseFree(reply);
-    return(outcome);
+    return (outcome);
 }
 
 /*  Line-parsing routines (GETTXT, MAKEWD, PUTTXT, SHFTXT) */
@@ -384,7 +412,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;
@@ -395,7 +423,7 @@ long VOCAB(long id, long init)
             return (lexeme);
         }
     }
-    BUG(21);
+    BUG(RAN_OFF_END_OF_VOCABULARY_TABLE);
 }
 
 void JUGGLE(long object)
@@ -422,7 +450,7 @@ void MOVE(long object, long where)
         from = game.fixed[object - NOBJECTS];
     else
         from = game.place[object];
-    if (from != NOWHERE && from != CARRIED && !SPECIAL(from))
+    if (from != LOC_NOWHERE && from != CARRIED && !SPECIAL(from))
         CARRY(object, from);
     DROP(object, where);
 }
@@ -497,7 +525,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. */
@@ -559,36 +587,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) */
 
@@ -669,10 +667,10 @@ bool MAPLIN(FILE *fp)
          *  If the data file uses a character other than space (e.g., tab) to
          *  separate numbers, that character should also translate to 0.
          *
-         *  This procedure may use the map1,map2 arrays to maintain static data for
-         *  the mapping.  MAP2(1) is set to 0 when the program starts
-         *  and is not changed thereafter unless the routines on this page choose
-         *  to do so. */
+         *  This procedure may use the map1,map2 arrays to maintain
+         *  static data for he mapping.  MAP2(1) is set to 0 when the
+         *  program starts and is not changed thereafter unless the
+         *  routines in this module choose to do so. */
         LNLENG = 0;
         for (long i = 1; i <= (long)sizeof(INLINE) && INLINE[i] != 0; i++) {
             long val = INLINE[i];
@@ -693,4 +691,10 @@ void DATIME(long* d, long* t)
     *t = (long) tv.tv_usec;
 }
 
+void bug(enum bugtype num, const char *error_string)
+{
+    fprintf(stderr, "Fatal error %d, %s.\n", num, error_string);
+    exit(EXIT_FAILURE);
+}
+
 /* end */