diff --git a/include/hashmap.h b/include/hashmap.h index fddb0eae..f81664f0 100644 --- a/include/hashmap.h +++ b/include/hashmap.h @@ -33,6 +33,16 @@ typedef struct HashMapEntry *HashMap[HASHMAP_NB_BUCKETS]; */ 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 diff --git a/src/asm/charmap.c b/src/asm/charmap.c index c8cfca72..eaddc3e0 100644 --- a/src/asm/charmap.c +++ b/src/asm/charmap.c @@ -173,6 +173,7 @@ void charmap_Add(char *mapping, uint8_t value) 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 */ diff --git a/src/hashmap.c b/src/hashmap.c index 76299396..a45cd449 100644 --- a/src/hashmap.c +++ b/src/hashmap.c @@ -64,6 +64,22 @@ bool hash_AddElement(HashMap map, char const *key, void *element) 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); diff --git a/test/asm/charmap-inheritance.asm b/test/asm/charmap-inheritance.asm new file mode 100644 index 00000000..eab9c12f --- /dev/null +++ b/test/asm/charmap-inheritance.asm @@ -0,0 +1,23 @@ +SECTION "test", ROM0 + + newcharmap foo + + charmap "", $00 + charmap "", $01 + charmap "", $02 + charmap "", $03 + charmap "", $04 + charmap "", $05 + charmap "", $06 + charmap "", $07 + charmap "", $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 diff --git a/test/asm/charmap-inheritance.err b/test/asm/charmap-inheritance.err new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/charmap-inheritance.out b/test/asm/charmap-inheritance.out new file mode 100644 index 00000000..e69de29b