shithub: rgbds

Download patch

ref: 91889fc14abbf705271bb484e89e349e08f76477
parent: f9daf27511bfa49a100fa45648c5098098d696b5
parent: 7c8ec5a5edbdae184ce5c0f6bbcde6037340f209
author: Eldred Habert <eldredhabert0@gmail.com>
date: Fri Oct 9 22:15:04 EDT 2020

Merge pull request #593 from Rangi42/issue586

Fix #586: Update the `charmaps` hashmap when an existing charmap is resized

--- a/include/hashmap.h
+++ b/include/hashmap.h
@@ -34,6 +34,16 @@
 bool hash_AddElement(HashMap map, char const *key, void *element);
 
 /**
+ * Replaces an element with an already-present key in a hashmap.
+ * @warning Inserting a NULL will make `hash_GetElement`'s return ambiguous!
+ * @param map The HashMap to replace the element in
+ * @param key The key with which the element will be stored and retrieved
+ * @param element The element to replace
+ * @return True if the element was found and replaced
+ */
+bool hash_ReplaceElement(HashMap const map, char const *key, void *element);
+
+/**
  * Removes an element from a hashmap.
  * @param map The HashMap to remove the element from
  * @param key The key to search the element with
--- a/src/asm/charmap.c
+++ b/src/asm/charmap.c
@@ -173,6 +173,7 @@
 			if (currentCharmap->usedNodes == currentCharmap->capacity) {
 				currentCharmap->capacity *= 2;
 				currentCharmap = resizeCharmap(currentCharmap, currentCharmap->capacity);
+				hash_ReplaceElement(charmaps, currentCharmap->name, currentCharmap);
 			}
 
 			/* Switch to and init new node */
--- a/src/hashmap.c
+++ b/src/hashmap.c
@@ -64,6 +64,22 @@
 	return newEntry->next != NULL;
 }
 
+bool hash_ReplaceElement(HashMap const map, char const *key, void *element)
+{
+	HashType hashedKey = hash(key);
+	struct HashMapEntry *ptr = map[(HalfHashType)hashedKey];
+
+	while (ptr) {
+		if (hashedKey >> HALF_HASH_NB_BITS == ptr->hash
+		 && !strcmp(ptr->key, key)) {
+			ptr->content = element;
+			return true;
+		}
+		ptr = ptr->next;
+	}
+	return false;
+}
+
 bool hash_RemoveElement(HashMap map, char const *key)
 {
 	HashType hashedKey = hash(key);
--- /dev/null
+++ b/test/asm/charmap-inheritance.asm
@@ -1,0 +1,23 @@
+SECTION "test", ROM0
+
+	newcharmap foo
+
+	charmap "<START>",  $00
+	charmap "<RAM>",    $01
+	charmap "<WAIT>",   $02
+	charmap "<ASM>",    $03
+	charmap "<NUM>",    $04
+	charmap "<EXIT>",   $05
+	charmap "<SOUND>",  $06
+	charmap "<DAY>",    $07
+	charmap "<FAR>",    $08
+
+	; At this point, enough nodes were allocated for 'foo' to be reallocated.
+	; Its value in the charmaps' hashmap should have been updated too,
+	; so that usages of 'foo' will not segfault.
+
+	; This uses 'foo; by switching to it.
+	setcharmap foo
+
+	; This uses 'foo' by deriving another charmap from it.
+	newcharmap bar, foo