diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index 235db83006..97c34f55ff 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -49,15 +49,6 @@ struct config_include_list struct config_include_list *next; }; -static uint32_t config_file_hash_string(const char *str) -{ - unsigned char c; - uint32_t hash = (uint32_t)0x811c9dc5; - while ((c = (unsigned char)*(str++)) != '\0') - hash = ((hash * (uint32_t)0x01000193) ^ (uint32_t)c); - return (hash ? hash : 1); -} - /* Forward declaration */ static bool config_file_parse_line(config_file_t *conf, struct config_entry_list *list, char *line, config_file_cb_t *cb); @@ -336,15 +327,16 @@ static void config_file_add_child_list(config_file_t *parent, config_file_t *chi * to the parent hash map */ for (i = 0, cap = RHMAP_CAP(child->entries_map); i != cap; i++) { - uint32_t child_hash = RHMAP_KEY(child->entries_map, i); + uint32_t child_hash = RHMAP_KEY(child->entries_map, i); + const char *child_key = RHMAP_KEY_STR(child->entries_map, i); - if (!RHMAP_HAS(parent->entries_map, child_hash)) + if (!RHMAP_HAS_FULL(parent->entries_map, child_hash, child_key)) { struct config_entry_list *entry = - RHMAP_GET(child->entries_map, child_hash); + RHMAP_GET_FULL(child->entries_map, child_hash, child_key); if (entry) - RHMAP_SET(parent->entries_map, child_hash, entry); + RHMAP_SET_FULL(parent->entries_map, child_hash, child_key, entry); } } @@ -481,11 +473,11 @@ static int config_file_load_internal( /* Only add entry to the map if an entry * with the specified value does not * already exist */ - uint32_t hash = config_file_hash_string(list->key); + uint32_t hash = rhmap_hash_string(list->key); - if (!RHMAP_HAS(conf->entries_map, hash)) + if (!RHMAP_HAS_FULL(conf->entries_map, hash, list->key)) { - RHMAP_SET(conf->entries_map, hash, list); + RHMAP_SET_FULL(conf->entries_map, hash, list->key, list); if (cb && list->value) cb->config_file_new_entry_cb(list->key, list->value); @@ -697,9 +689,9 @@ static int config_file_from_string_internal( /* Only add entry to the map if an entry * with the specified value does not * already exist */ - uint32_t hash = config_file_hash_string(list->key); - if (!RHMAP_HAS(conf->entries_map, hash)) - RHMAP_SET(conf->entries_map, hash, list); + uint32_t hash = rhmap_hash_string(list->key); + if (!RHMAP_HAS_FULL(conf->entries_map, hash, list->key)) + RHMAP_SET_FULL(conf->entries_map, hash, list->key, list); } } @@ -804,10 +796,11 @@ bool config_append_file(config_file_t *conf, const char *path) for (i = 0, cap = RHMAP_CAP(new_conf->entries_map); i != cap; i++) { uint32_t new_hash = RHMAP_KEY(new_conf->entries_map, i); - struct config_entry_list *entry = RHMAP_GET(new_conf->entries_map, new_hash); + const char *new_key = RHMAP_KEY_STR(new_conf->entries_map, i); + struct config_entry_list *entry = RHMAP_GET_FULL(new_conf->entries_map, new_hash, new_key); if (entry) - RHMAP_SET(conf->entries_map, new_hash, entry); + RHMAP_SET_FULL(conf->entries_map, new_hash, new_key, entry); } if (new_conf->tail) @@ -934,7 +927,7 @@ static struct config_entry_list *config_get_entry_internal( struct config_entry_list *entry = NULL; struct config_entry_list *previous = prev ? *prev : NULL; - entry = RHMAP_GET(conf->entries_map, config_file_hash_string(key)); + entry = RHMAP_GET_STR(conf->entries_map, key); if (entry) return entry; @@ -953,7 +946,7 @@ static struct config_entry_list *config_get_entry_internal( struct config_entry_list *config_get_entry( const config_file_t *conf, const char *key) { - return RHMAP_GET(conf->entries_map, config_file_hash_string(key)); + return RHMAP_GET_STR(conf->entries_map, key); } bool config_get_double(config_file_t *conf, const char *key, double *in) @@ -1227,7 +1220,7 @@ void config_set_string(config_file_t *conf, const char *key, const char *val) conf->last = entry; - RHMAP_SET(conf->entries_map, config_file_hash_string(entry->key), entry); + RHMAP_SET_STR(conf->entries_map, entry->key, entry); } void config_unset(config_file_t *conf, const char *key) @@ -1244,7 +1237,7 @@ void config_unset(config_file_t *conf, const char *key) if (!entry) return; - (void)RHMAP_DEL(conf->entries_map, config_file_hash_string(entry->key)); + (void)RHMAP_DEL_STR(conf->entries_map, entry->key); if (entry->key) free(entry->key); @@ -1465,7 +1458,7 @@ void config_file_dump(config_file_t *conf, FILE *file, bool sort) bool config_entry_exists(config_file_t *conf, const char *entry) { - return (bool)RHMAP_HAS(conf->entries_map, config_file_hash_string(entry)); + return (bool)RHMAP_HAS_STR(conf->entries_map, entry); } bool config_get_entry_list_head(config_file_t *conf, diff --git a/libretro-common/include/array/rhmap.h b/libretro-common/include/array/rhmap.h index 84cd37794f..20558f784f 100644 --- a/libretro-common/include/array/rhmap.h +++ b/libretro-common/include/array/rhmap.h @@ -116,12 +116,12 @@ #define RHMAP_FIT(b, n) ((!(n) || ((b) && (size_t)(n) * 2 <= RHMAP_MAX(b))) ? 0 : RHMAP__GROW(b, n)) #define RHMAP_TRYFIT(b, n) (RHMAP_FIT((b), (n)), (!(n) || ((b) && (size_t)(n) * 2 <= RHMAP_MAX(b)))) -#define RHMAP_SET(b, key, val) RHMAP__SET_FULL(b, key, NULL, val) -#define RHMAP_GET(b, key) RHMAP__GET_FULL(b, key, NULL) -#define RHMAP_HAS(b, key) RHMAP__HAS_FULL(b, key, NULL) -#define RHMAP_DEL(b, key) RHMAP__DEL_FULL(b, key, NULL) -#define RHMAP_PTR(b, key) RHMAP__PTR_FULL(b, key, NULL) -#define RHMAP_IDX(b, key) RHMAP__IDX_FULL(b, key, NULL) +#define RHMAP_SET(b, key, val) RHMAP_SET_FULL(b, key, NULL, val) +#define RHMAP_GET(b, key) RHMAP_GET_FULL(b, key, NULL) +#define RHMAP_HAS(b, key) RHMAP_HAS_FULL(b, key, NULL) +#define RHMAP_DEL(b, key) RHMAP_DEL_FULL(b, key, NULL) +#define RHMAP_PTR(b, key) RHMAP_PTR_FULL(b, key, NULL) +#define RHMAP_IDX(b, key) RHMAP_IDX_FULL(b, key, NULL) #ifdef __GNUC__ #define RHMAP__UNUSED __attribute__((__unused__)) @@ -134,14 +134,21 @@ #pragma warning(disable:4505) //unreferenced local function has been removed #endif -#define RHMAP_SET_STR(b, string_key, val) RHMAP__SET_FULL(b, hash_string(string_key), string_key, val) -#define RHMAP_GET_STR(b, string_key) RHMAP__GET_FULL(b, hash_string(string_key), string_key) -#define RHMAP_HAS_STR(b, string_key) RHMAP__HAS_FULL(b, hash_string(string_key), string_key) -#define RHMAP_DEL_STR(b, string_key) RHMAP__DEL_FULL(b, hash_string(string_key), string_key) -#define RHMAP_PTR_STR(b, string_key) RHMAP__PTR_FULL(b, hash_string(string_key), string_key) -#define RHMAP_IDX_STR(b, string_key) RHMAP__IDX_FULL(b, hash_string(string_key), string_key) +#define RHMAP_SET_FULL(b, key, str, val) (RHMAP__FIT1(b), b[rhmap__idx(RHMAP__HDR(b), (key), (str), 1, 0)] = (val)) +#define RHMAP_GET_FULL(b, key, str) (RHMAP__FIT1(b), b[rhmap__idx(RHMAP__HDR(b), (key), (str), 0, 0)]) +#define RHMAP_HAS_FULL(b, key, str) ((b) ? rhmap__idx(RHMAP__HDR(b), (key), (str), 0, 0) != -1 : 0) +#define RHMAP_DEL_FULL(b, key, str) ((b) ? rhmap__idx(RHMAP__HDR(b), (key), (str), 0, sizeof(*(b))) != -1 : 0) +#define RHMAP_PTR_FULL(b, key, str) (RHMAP__FIT1(b), &b[rhmap__idx(RHMAP__HDR(b), (key), (str), 1, 0)]) +#define RHMAP_IDX_FULL(b, key, str) ((b) ? rhmap__idx(RHMAP__HDR(b), (key), (str), 0, 0) : -1) -RHMAP__UNUSED static uint32_t hash_string(const char* str) +#define RHMAP_SET_STR(b, string_key, val) RHMAP_SET_FULL(b, rhmap_hash_string(string_key), string_key, val) +#define RHMAP_GET_STR(b, string_key) RHMAP_GET_FULL(b, rhmap_hash_string(string_key), string_key) +#define RHMAP_HAS_STR(b, string_key) RHMAP_HAS_FULL(b, rhmap_hash_string(string_key), string_key) +#define RHMAP_DEL_STR(b, string_key) RHMAP_DEL_FULL(b, rhmap_hash_string(string_key), string_key) +#define RHMAP_PTR_STR(b, string_key) RHMAP_PTR_FULL(b, rhmap_hash_string(string_key), string_key) +#define RHMAP_IDX_STR(b, string_key) RHMAP_IDX_FULL(b, rhmap_hash_string(string_key), string_key) + +RHMAP__UNUSED static uint32_t rhmap_hash_string(const char* str) { unsigned char c; uint32_t hash = (uint32_t)0x811c9dc5; @@ -155,13 +162,6 @@ struct rhmap__hdr { size_t len, maxlen; uint32_t *keys; char** key_strs; }; #define RHMAP__GROW(b, n) (*(void**)(&(b)) = rhmap__grow(RHMAP__HDR(b), (void*)(b), sizeof(*(b)), (size_t)(n))) #define RHMAP__FIT1(b) ((b) && RHMAP_LEN(b) * 2 <= RHMAP_MAX(b) ? 0 : RHMAP__GROW(b, 0)) -#define RHMAP__SET_FULL(b, key, str, val) (RHMAP__FIT1(b), b[rhmap__idx(RHMAP__HDR(b), (key), (str), 1, 0)] = (val)) -#define RHMAP__GET_FULL(b, key, str) (RHMAP__FIT1(b), b[rhmap__idx(RHMAP__HDR(b), (key), (str), 0, 0)]) -#define RHMAP__HAS_FULL(b, key, str) ((b) ? rhmap__idx(RHMAP__HDR(b), (key), (str), 0, 0) != -1 : 0) -#define RHMAP__DEL_FULL(b, key, str) ((b) ? rhmap__idx(RHMAP__HDR(b), (key), (str), 0, sizeof(*(b))) != -1 : 0) -#define RHMAP__PTR_FULL(b, key, str) (RHMAP__FIT1(b), &b[rhmap__idx(RHMAP__HDR(b), (key), (str), 1, 0)]) -#define RHMAP__IDX_FULL(b, key, str) ((b) ? rhmap__idx(RHMAP__HDR(b), (key), (str), 0, 0) : -1) - RHMAP__UNUSED static void* rhmap__grow(struct rhmap__hdr *old_hdr, void* old_ptr, size_t elem_size, size_t reserve) { struct rhmap__hdr *new_hdr; @@ -236,7 +236,7 @@ RHMAP__UNUSED static ptrdiff_t rhmap__idx(struct rhmap__hdr* hdr, uint32_t key, for (i = key;; i++) { - if (hdr->keys[i &= hdr->maxlen] == key && (!hdr->key_strs[i] || !strcmp(hdr->key_strs[i], str))) + if (hdr->keys[i &= hdr->maxlen] == key && (!hdr->key_strs[i] || !str || !strcmp(hdr->key_strs[i], str))) { if (del) {