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;
}