diff options
author | Steve Bennett <steveb@workware.net.au> | 2014-01-11 16:19:17 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2014-01-15 11:23:06 +1000 |
commit | 46c54f834c37df0324aea37ba099f01b043668a8 (patch) | |
tree | e8c8eb90e548bd942fe886e14e4e7858729a3c41 /jim.c | |
parent | fd5d1d16f156d270989f7a79593bab18b19a995a (diff) | |
download | jimtcl-46c54f834c37df0324aea37ba099f01b043668a8.zip jimtcl-46c54f834c37df0324aea37ba099f01b043668a8.tar.gz jimtcl-46c54f834c37df0324aea37ba099f01b043668a8.tar.bz2 |
jim.c: Fix Jim_ReplaceHashEntry() for ref counted objects
If both a val dup and a val destructor exist, need to
dup before destroying.
Signed-off-by: Steve Bennett <steveb@workware.net.au>
Diffstat (limited to 'jim.c')
-rw-r--r-- | jim.c | 18 |
1 files changed, 15 insertions, 3 deletions
@@ -820,16 +820,28 @@ int Jim_ReplaceHashEntry(Jim_HashTable *ht, const void *key, void *val) * the element already exists. */ entry = JimInsertHashEntry(ht, key, 1); if (entry->key) { - /* It already exists, so replace the value */ - Jim_FreeEntryVal(ht, entry); + /* It already exists, so only replace the value. + * Note if both a destructor and a duplicate function exist, + * need to dup before destroy. perhaps they are the same + * reference counted object + */ + if (ht->type->valDestructor && ht->type->valDup) { + void *newval = ht->type->valDup(ht->privdata, val); + ht->type->valDestructor(ht->privdata, entry->u.val); + entry->u.val = newval; + } + else { + Jim_FreeEntryVal(ht, entry); + Jim_SetHashVal(ht, entry, val); + } existed = 1; } else { /* Doesn't exist, so set the key */ Jim_SetHashKey(ht, entry, key); + Jim_SetHashVal(ht, entry, val); existed = 0; } - Jim_SetHashVal(ht, entry, val); return existed; } |