Address GitLab issue #66: Missing couple of ; in saveresume.c
[open-adventure.git] / saveresume.c
index d66854344733de47951fb7a3cd33f9eba356f72c..575b11f2486a319ec2090b284ad8ed2a7d05a7ff 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 #include <time.h>
 #include <inttypes.h>
 
@@ -55,6 +56,25 @@ int savefile(FILE *fp, int32_t version)
 }
 
 /* Suspend and resume */
+
+static char *strip(char *name)
+{
+    // Trim leading whitespace
+    while(isspace((unsigned char)*name))
+       name++; // LCOV_EXCL_LINE
+    if(*name != '\0') {
+       // Trim trailing whitespace;
+       // might be left there by autocomplete
+       char *end = name + strlen(name) - 1;
+       while(end > name && isspace((unsigned char)*end))
+           end--;
+       // Write new null terminator character
+       end[1] = '\0';
+    }
+
+    return name;
+}
+
 int suspend(void)
 {
     /*  Suspend.  Offer to save things in a file, but charging
@@ -63,7 +83,7 @@ int suspend(void)
      *  If ADVENT_NOSAVE is defined, gripe instead. */
 
 #if defined ADVENT_NOSAVE || defined ADVENT_AUTOSAVE
-    rspeak(SAVERESUME_DISABLED)
+    rspeak(SAVERESUME_DISABLED);
     return GO_TOP;
 #endif
     FILE *fp = NULL;
@@ -77,7 +97,10 @@ int suspend(void)
         char* name = myreadline("\nFile name: ");
         if (name == NULL)
             return GO_TOP;
-        fp = fopen(name, WRITE_MODE);
+       name = strip(name);
+       if (strlen(name) == 0)
+            return GO_TOP;     // LCOV_EXCL_LINE
+        fp = fopen(strip(name), WRITE_MODE);
         if (fp == NULL)
             printf("Can't open file %s, try again.\n", name);
         free(name);
@@ -95,7 +118,7 @@ int resume(void)
      *  If ADVENT_NOSAVE is defined, gripe instead. */
 
 #if defined ADVENT_NOSAVE || defined ADVENT_AUTOSAVE
-    rspeak(SAVERESUME_DISABLED)
+    rspeak(SAVERESUME_DISABLED);
     return GO_TOP;
 #endif
     FILE *fp = NULL;
@@ -109,12 +132,12 @@ int resume(void)
 
     while (fp == NULL) {
         char* name = myreadline("\nFile name: ");
-        // Autocomplete can leave the input with an extra trailing space.
-        if (name != NULL && strlen(name) > 0 && name[strlen(name) - 1] == ' ')
-            name[strlen(name) - 1] = '\0';
         if (name == NULL)
             return GO_TOP;
-        fp = fopen(name, READ_MODE);
+       name = strip(name);
+       if (strlen(name) == 0)
+            return GO_TOP;     // LCOV_EXCL_LINE
+       fp = fopen(name, READ_MODE);
         if (fp == NULL)
             printf("Can't open file %s, try again.\n", name);
         free(name);
@@ -137,7 +160,10 @@ int restore(FILE* fp)
     fclose(fp);
     if (save.version != VRSION) {
         rspeak(VERSION_SKEW, save.version / 10, MOD(save.version, 10), VRSION / 10, MOD(VRSION, 10));
-    } else if (is_valid(save.game)) {
+    } else if (!is_valid(save.game)) {
+       rspeak(SAVE_TAMPERING);
+       exit(EXIT_SUCCESS);
+    } else {
         game = save.game;
     }
     return GO_TOP;
@@ -216,7 +242,8 @@ bool is_valid(struct game_t valgame)
 
     /* Check that properties of objects aren't beyond expected */
     for (obj_t obj = 0; obj <= NOBJECTS; obj++) {
-        if (valgame.prop[obj] < STATE_NOTFOUND || valgame.prop[obj] > 1) {
+       /* Magic number -2 allows a STASHED version of state 1 */
+        if (valgame.prop[obj] < -2 || valgame.prop[obj] > 1) {
             switch (obj) {
             case RUG:
             case DRAGON:
@@ -230,7 +257,7 @@ bool is_valid(struct game_t valgame)
             case VASE:
             case CHAIN:
                 if (valgame.prop[obj] == 2) // There are multiple different states, but it's convenient to clump them together
-                    continue;
+                    continue;  // LCOV_EXCL_LINE
             /* FALLTHRU */
             case BEAR:
                 if (valgame.prop[BEAR] == CONTENTED_BEAR || valgame.prop[BEAR] == BEAR_DEAD)