summaryrefslogtreecommitdiff
path: root/assoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'assoc.c')
-rw-r--r--assoc.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/assoc.c b/assoc.c
index bbc7b177..5d3cd11b 100644
--- a/assoc.c
+++ b/assoc.c
@@ -7,7 +7,7 @@
* chet@ins.cwru.edu
*/
-/* Copyright (C) 2008,2009 Free Software Foundation, Inc.
+/* Copyright (C) 2008,2009,2011 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -65,7 +65,7 @@ assoc_flush (hash)
{
hash_flush (hash, 0);
}
-
+
int
assoc_insert (hash, key, value)
HASH_TABLE *hash;
@@ -77,11 +77,39 @@ assoc_insert (hash, key, value)
b = hash_search (key, hash, HASH_CREATE);
if (b == 0)
return -1;
+ /* If we are overwriting an existing element's value, we're not going to
+ use the key. Nothing in the array assignment code path frees the key
+ string, so we can free it here to avoid a memory leak. */
+ if (b->key != key)
+ free (key);
FREE (b->data);
b->data = value ? savestring (value) : (char *)0;
return (0);
}
+/* Like assoc_insert, but returns b->data instead of freeing it */
+PTR_T
+assoc_replace (hash, key, value)
+ HASH_TABLE *hash;
+ char *key;
+ char *value;
+{
+ BUCKET_CONTENTS *b;
+ PTR_T t;
+
+ b = hash_search (key, hash, HASH_CREATE);
+ if (b == 0)
+ return (PTR_T)0;
+ /* If we are overwriting an existing element's value, we're not going to
+ use the key. Nothing in the array assignment code path frees the key
+ string, so we can free it here to avoid a memory leak. */
+ if (b->key != key)
+ free (key);
+ t = b->data;
+ b->data = value ? savestring (value) : (char *)0;
+ return t;
+}
+
void
assoc_remove (hash, string)
HASH_TABLE *hash;