shithub: choc

Download patch

ref: 5914e16076339ef487094dba8be67eed21b0a811
parent: 2ab317c4b7c304bc624f803e7b5763ab27f39f7b
author: Simon Howard <fraggle@gmail.com>
date: Sat Oct 18 16:33:30 EDT 2014

dehacked: Allow override of string replacements.

If loading two dehacked patches and both replace the same string,
the second replacement should override the first. Change the API
function DEH_AddStringReplacement so that the from_text and to_text
are implicitly duplicated, and we can free to_text and replace
it later if we subsequently change it to something else.

--- a/src/deh_str.c
+++ b/src/deh_str.c
@@ -52,17 +52,13 @@
     return h;
 }
 
-// Look up a string to see if it has been replaced with something else
-// This will be used throughout the program to substitute text
-
-char *DEH_String(char *s)
+static deh_substitution_t *SubstitutionForString(char *s)
 {
     int entry;
 
     // Fallback if we have not initialized the hash table yet
-
     if (hash_table_length < 0)
-	return s;
+	return NULL;
 
     entry = strhash(s) % hash_table_length;
 
@@ -71,8 +67,7 @@
         if (!strcmp(hash_table[entry]->from_text, s))
         {
             // substitution found!
-
-            return hash_table[entry]->to_text;
+            return hash_table[entry];
         }
 
         entry = (entry + 1) % hash_table_length;
@@ -79,8 +74,26 @@
     }
 
     // no substitution found
+    return NULL;
+}
 
-    return s;
+// Look up a string to see if it has been replaced with something else
+// This will be used throughout the program to substitute text
+
+char *DEH_String(char *s)
+{
+    deh_substitution_t *subst;
+
+    subst = SubstitutionForString(s);
+
+    if (subst != NULL)
+    {
+        return subst->to_text;
+    }
+    else
+    {
+        return s;
+    }
 }
 
 static void InitHashTable(void)
@@ -139,9 +152,8 @@
     {
         IncreaseHashtable();
     }
-    
+
     // find where to insert it
-    
     entry = strhash(sub->from_text) % hash_table_length;
 
     while (hash_table[entry] != NULL)
@@ -156,20 +168,41 @@
 void DEH_AddStringReplacement(char *from_text, char *to_text)
 {
     deh_substitution_t *sub;
+    size_t len;
 
     // Initialize the hash table if this is the first time
-
     if (hash_table_length < 0)
     {
         InitHashTable();
     }
 
-    sub = Z_Malloc(sizeof(*sub), PU_STATIC, 0);
+    // Check to see if there is an existing substitution already in place.
+    sub = SubstitutionForString(from_text);
 
-    sub->from_text = from_text;
-    sub->to_text = to_text;
+    if (sub != NULL)
+    {
+        Z_Free(sub->to_text);
 
-    DEH_AddToHashtable(sub);
+        len = strlen(to_text) + 1;
+        sub->to_text = Z_Malloc(len, PU_STATIC, NULL);
+        memcpy(sub->to_text, to_text, len);
+    }
+    else
+    {
+        // We need to allocate a new substitution.
+        sub = Z_Malloc(sizeof(*sub), PU_STATIC, 0);
+
+        // We need to create our own duplicates of the provided strings.
+        len = strlen(from_text) + 1;
+        sub->from_text = Z_Malloc(len, PU_STATIC, NULL);
+        memcpy(sub->from_text, from_text, len);
+
+        len = strlen(to_text) + 1;
+        sub->to_text = Z_Malloc(len, PU_STATIC, NULL);
+        memcpy(sub->to_text, to_text, len);
+
+        DEH_AddToHashtable(sub);
+    }
 }
 
 typedef enum
--- a/src/deh_text.c
+++ b/src/deh_text.c
@@ -16,6 +16,7 @@
 //
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include "doomtype.h"
@@ -51,7 +52,7 @@
     char *from_text, *to_text;
     int fromlen, tolen;
     int i;
-    
+
     if (sscanf(line, "Text %i %i", &fromlen, &tolen) != 2)
     {
         DEH_Warning(context, "Parse error on section start");
@@ -68,20 +69,15 @@
         return NULL;
     }
 
-    from_text = Z_Malloc(fromlen + 1, PU_STATIC, NULL);
-    to_text = Z_Malloc(tolen + 1, PU_STATIC, NULL);
+    from_text = malloc(fromlen + 1);
+    to_text = malloc(tolen + 1);
 
     // read in the "from" text
 
     for (i=0; i<fromlen; ++i)
     {
-        int c;
-
-        c = DEH_GetChar(context);
-            
-        from_text[i] = c;
+        from_text[i] = DEH_GetChar(context);
     }
-
     from_text[fromlen] = '\0';
 
     // read in the "to" text
@@ -88,16 +84,15 @@
 
     for (i=0; i<tolen; ++i)
     {
-        int c;
-
-        c = DEH_GetChar(context);
-            
-        to_text[i] = c;
+        to_text[i] = DEH_GetChar(context);
     }
     to_text[tolen] = '\0';
 
     DEH_AddStringReplacement(from_text, to_text);
-    
+
+    free(from_text);
+    free(to_text);
+
     return NULL;
 }
 
--- a/src/doom/deh_bexstr.c
+++ b/src/doom/deh_bexstr.c
@@ -360,7 +360,7 @@
     {
 	if (!strcmp(bex_stringtable[i].macro, variable_name))
 	{
-	    DEH_AddStringReplacement(bex_stringtable[i].string, strdup(value));
+	    DEH_AddStringReplacement(bex_stringtable[i].string, value);
 	}
     }
 }
--- a/src/heretic/deh_htext.c
+++ b/src/heretic/deh_htext.c
@@ -16,6 +16,7 @@
 //
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include "doomtype.h"
@@ -776,7 +777,7 @@
         return NULL;
     }
 
-    repl_text = Z_Malloc(repl_len + 1, PU_STATIC, NULL);
+    repl_text = malloc(repl_len + 1);
 
     // read in the "to" text
 
@@ -819,13 +820,10 @@
         // Success.
 
         DEH_AddStringReplacement(orig_text, repl_text);
-
-        return NULL;
     }
 
-    // Failure.
-
-    Z_Free(repl_text);
+    // We must always free the replacement text.
+    free(repl_text);
 
     return NULL;
 }