summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Howard2014-10-18 20:33:30 -0400
committerSimon Howard2014-10-18 20:33:30 -0400
commit5914e16076339ef487094dba8be67eed21b0a811 (patch)
tree36c72e60e176f495bd391dfc6da09cbbb60e4acc
parent2ab317c4b7c304bc624f803e7b5763ab27f39f7b (diff)
downloadchocolate-doom-5914e16076339ef487094dba8be67eed21b0a811.tar.gz
chocolate-doom-5914e16076339ef487094dba8be67eed21b0a811.tar.bz2
chocolate-doom-5914e16076339ef487094dba8be67eed21b0a811.zip
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.
-rw-r--r--src/deh_str.c65
-rw-r--r--src/deh_text.c25
-rw-r--r--src/doom/deh_bexstr.c2
-rw-r--r--src/heretic/deh_htext.c10
4 files changed, 64 insertions, 38 deletions
diff --git a/src/deh_str.c b/src/deh_str.c
index ecd00a6b..1422b759 100644
--- a/src/deh_str.c
+++ b/src/deh_str.c
@@ -52,17 +52,13 @@ static unsigned int strhash(char *s)
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,16 +67,33 @@ char *DEH_String(char *s)
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;
}
// 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 @@ static void DEH_AddToHashtable(deh_substitution_t *sub)
{
IncreaseHashtable();
}
-
+
// find where to insert it
-
entry = strhash(sub->from_text) % hash_table_length;
while (hash_table[entry] != NULL)
@@ -156,20 +168,41 @@ static void DEH_AddToHashtable(deh_substitution_t *sub)
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);
+
+ 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);
- DEH_AddToHashtable(sub);
+ // 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
diff --git a/src/deh_text.c b/src/deh_text.c
index 1fc91185..9e621b43 100644
--- 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 @@ static void *DEH_TextStart(deh_context_t *context, char *line)
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,36 +69,30 @@ static void *DEH_TextStart(deh_context_t *context, char *line)
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
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;
}
diff --git a/src/doom/deh_bexstr.c b/src/doom/deh_bexstr.c
index e29b71dc..ac3ab651 100644
--- a/src/doom/deh_bexstr.c
+++ b/src/doom/deh_bexstr.c
@@ -360,7 +360,7 @@ static void DEH_BEXStrParseLine(deh_context_t *context, char *line, void *tag)
{
if (!strcmp(bex_stringtable[i].macro, variable_name))
{
- DEH_AddStringReplacement(bex_stringtable[i].string, strdup(value));
+ DEH_AddStringReplacement(bex_stringtable[i].string, value);
}
}
}
diff --git a/src/heretic/deh_htext.c b/src/heretic/deh_htext.c
index 55f32872..fe0dc663 100644
--- 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 @@ static void *DEH_TextStart(deh_context_t *context, char *line)
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 @@ static void *DEH_TextStart(deh_context_t *context, char *line)
// 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;
}