aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2023-05-14 18:45:56 +0200
committerbfredl <bjorn.linse@gmail.com>2023-05-17 12:26:21 +0200
commite2fdd53d8c015913e8be4ff708fc3488558c8906 (patch)
tree2858a7eb734b605225296c0019aa8048e24e425d
parent33687f5e87a0f048f7bc02d4658e58ef8cc0fd49 (diff)
downloadrneovim-e2fdd53d8c015913e8be4ff708fc3488558c8906.tar.gz
rneovim-e2fdd53d8c015913e8be4ff708fc3488558c8906.tar.bz2
rneovim-e2fdd53d8c015913e8be4ff708fc3488558c8906.zip
refactor(map): avoid duplicated khash_t types for values
This reduces the total number of khash_t instantiations from 22 to 8. Make the khash internal functions take the size of values as a runtime parameter. This is abstracted with typesafe Map containers which are still specialized for both key, value type. Introduce `Set(key)` type for when there is no value. Refactor shada.c to use Map/Set instead of khash directly. This requires `map_ref` operation to be more flexible. Return pointers to both key and value, plus an indicator for new_item. As a bonus, `map_key` is now redundant. Instead of Map(cstr_t, FileMarks), use a pointer map as the FileMarks struct is humongous. Make `event_strings` actually work like an intern pool instead of wtf it was doing before.
-rw-r--r--cmake.config/iwyu/mapping.imp1
-rwxr-xr-xsrc/clint.py1
-rw-r--r--src/klib/khash.h135
-rw-r--r--src/nvim/api/extmark.c10
-rw-r--r--src/nvim/api/extmark.h1
-rw-r--r--src/nvim/api/private/helpers.h12
-rw-r--r--src/nvim/api/ui.c2
-rw-r--r--src/nvim/autocmd.c24
-rw-r--r--src/nvim/buffer.c4
-rw-r--r--src/nvim/channel.c8
-rw-r--r--src/nvim/channel.h1
-rw-r--r--src/nvim/eval.c10
-rw-r--r--src/nvim/extmark.c22
-rw-r--r--src/nvim/highlight.c30
-rw-r--r--src/nvim/highlight_group.c2
-rw-r--r--src/nvim/lua/executor.c6
-rw-r--r--src/nvim/lua/executor.h2
-rw-r--r--src/nvim/lua/treesitter.c6
-rw-r--r--src/nvim/map.c109
-rw-r--r--src/nvim/map.h104
-rw-r--r--src/nvim/map_defs.h12
-rw-r--r--src/nvim/marktree.c6
-rw-r--r--src/nvim/marktree.h1
-rw-r--r--src/nvim/memory.c2
-rw-r--r--src/nvim/msgpack_rpc/channel.c49
-rw-r--r--src/nvim/msgpack_rpc/channel_defs.h2
-rw-r--r--src/nvim/runtime.c29
-rw-r--r--src/nvim/shada.c208
-rw-r--r--src/nvim/terminal.c20
-rw-r--r--src/nvim/tui/input.c17
-rw-r--r--src/nvim/ui.c16
-rw-r--r--src/nvim/window.c8
32 files changed, 403 insertions, 457 deletions
diff --git a/cmake.config/iwyu/mapping.imp b/cmake.config/iwyu/mapping.imp
index 22710d8571..7cdd63a723 100644
--- a/cmake.config/iwyu/mapping.imp
+++ b/cmake.config/iwyu/mapping.imp
@@ -194,7 +194,6 @@
{ include: [ '"nvim/extmark_defs.h"', public, '"nvim/extmark.h"', public ] },
{ include: [ '"nvim/grid_defs.h"', public, '"nvim/grid.h"', public ] },
{ include: [ '"nvim/highlight_defs.h"', public, '"nvim/highlight.h"', public ] },
- { include: [ '"nvim/map_defs.h"', public, '"nvim/map.h"', public ] },
{ include: [ '"nvim/mark_defs.h"', public, '"nvim/mark.h"', public ] },
{ include: [ '"nvim/mbyte_defs.h"', public, '"nvim/mbyte.h"', public ] },
{ include: [ '"nvim/memfile_defs.h"', public, '"nvim/memfile.h"', public ] },
diff --git a/src/clint.py b/src/clint.py
index a6649763c2..ee2d0ecc3c 100755
--- a/src/clint.py
+++ b/src/clint.py
@@ -2244,6 +2244,7 @@ def CheckSpacing(filename, clean_lines, linenum, error):
r'(?<!\bkbtree_t)'
r'(?<!\bkbitr_t)'
r'(?<!\bPMap)'
+ r'(?<!\bSet)'
r'(?<!\bArrayOf)'
r'(?<!\bDictionaryOf)'
r'(?<!\bDict)'
diff --git a/src/klib/khash.h b/src/klib/khash.h
index 57a41f9c13..eb1714c471 100644
--- a/src/klib/khash.h
+++ b/src/klib/khash.h
@@ -185,41 +185,46 @@ typedef khint_t khiter_t;
#define __ac_HASH_UPPER 0.77
-#define __KHASH_TYPE(name, khkey_t, khval_t) \
+// This is only used for stack temporaries. Heap allocation is done with precise sizes.
+#define KHASH_MAX_VAL_SIZE 32
+
+#define __KHASH_TYPE(name, khkey_t) \
typedef struct { \
khint_t n_buckets, size, n_occupied, upper_bound; \
khint32_t *flags; \
khkey_t *keys; \
- khval_t *vals; \
+ char *vals_buf; \
} kh_##name##_t;
-#define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \
+#define __KHASH_PROTOTYPES(name, khkey_t) \
extern kh_##name##_t *kh_init_##name(void); \
extern void kh_dealloc_##name(kh_##name##_t *h); \
extern void kh_destroy_##name(kh_##name##_t *h); \
extern void kh_clear_##name(kh_##name##_t *h); \
extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \
- extern void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \
- extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \
+ extern void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets, size_t val_size); \
+ extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret, size_t val_size); \
extern void kh_del_##name(kh_##name##_t *h, khint_t x);
-#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, \
- __hash_equal) \
+#define kh_bval(h, x) (&(h)->vals_buf[val_size*(x)])
+#define kh_copyval(to, from) memcpy(to, from, val_size)
+
+#define __KHASH_IMPL(name, SCOPE, khkey_t, __hash_func, __hash_equal) \
SCOPE kh_##name##_t *kh_init_##name(void) \
- REAL_FATTR_UNUSED; \
+ REAL_FATTR_UNUSED; \
SCOPE kh_##name##_t *kh_init_##name(void) { \
return (kh_##name##_t *)kcalloc(1, sizeof(kh_##name##_t)); \
} \
SCOPE void kh_dealloc_##name(kh_##name##_t *h) \
- REAL_FATTR_UNUSED; \
+ REAL_FATTR_UNUSED; \
SCOPE void kh_dealloc_##name(kh_##name##_t *h) \
{ \
kfree(h->keys); \
kfree(h->flags); \
- kfree(h->vals); \
+ kfree(h->vals_buf); \
} \
SCOPE void kh_destroy_##name(kh_##name##_t *h) \
- REAL_FATTR_UNUSED; \
+ REAL_FATTR_UNUSED; \
SCOPE void kh_destroy_##name(kh_##name##_t *h) \
{ \
if (h) { \
@@ -228,7 +233,7 @@ typedef khint_t khiter_t;
} \
} \
SCOPE void kh_clear_##name(kh_##name##_t *h) \
- REAL_FATTR_UNUSED; \
+ REAL_FATTR_UNUSED; \
SCOPE void kh_clear_##name(kh_##name##_t *h) \
{ \
if (h && h->flags) { \
@@ -237,7 +242,7 @@ typedef khint_t khiter_t;
} \
} \
SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \
- REAL_FATTR_UNUSED; \
+ REAL_FATTR_UNUSED; \
SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \
{ \
if (h->n_buckets) { \
@@ -257,9 +262,9 @@ typedef khint_t khiter_t;
return 0; \
} \
} \
- SCOPE void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
- REAL_FATTR_UNUSED; \
- SCOPE void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
+ SCOPE void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets, size_t val_size) \
+ REAL_FATTR_UNUSED; \
+ SCOPE void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets, size_t val_size) \
{ /* This function uses 0.25*n_buckets bytes of working space instead of */ \
/* [sizeof(key_t+val_t)+.25]*n_buckets. */ \
khint32_t *new_flags = 0; \
@@ -280,23 +285,23 @@ typedef khint_t khiter_t;
if (h->n_buckets < new_n_buckets) { /* expand */ \
khkey_t *new_keys = (khkey_t *)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
h->keys = new_keys; \
- if (kh_is_map) { \
- khval_t *new_vals = \
- (khval_t *)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \
- h->vals = new_vals; \
+ if (val_size) { \
+ char *new_vals = krealloc( h->vals_buf, new_n_buckets * val_size); \
+ h->vals_buf = new_vals; \
} \
} /* otherwise shrink */ \
} \
} \
+ char cval[KHASH_MAX_VAL_SIZE]; \
+ char ctmp[KHASH_MAX_VAL_SIZE]; \
if (j) { /* rehashing is needed */ \
for (j = 0; j != h->n_buckets; ++j) { \
if (__ac_iseither(h->flags, j) == 0) { \
khkey_t key = h->keys[j]; \
- khval_t val; \
khint_t new_mask; \
new_mask = new_n_buckets - 1; \
- if (kh_is_map) { \
- val = h->vals[j]; \
+ if (val_size) { \
+ kh_copyval(cval, kh_bval(h, j)); \
} \
__ac_set_isdel_true(h->flags, j); \
/* kick-out process; sort of like in Cuckoo hashing */ \
@@ -315,17 +320,17 @@ typedef khint_t khiter_t;
h->keys[i] = key; \
key = tmp; \
} \
- if (kh_is_map) { \
- khval_t tmp = h->vals[i]; \
- h->vals[i] = val; \
- val = tmp; \
+ if (val_size) { \
+ kh_copyval(ctmp, kh_bval(h, i)); \
+ kh_copyval(kh_bval(h, i), cval); \
+ kh_copyval(cval, ctmp); \
} \
/* mark it as deleted in the old hash table */ \
__ac_set_isdel_true(h->flags, i); \
} else { /* write the element and jump out of the loop */ \
h->keys[i] = key; \
- if (kh_is_map) { \
- h->vals[i] = val; \
+ if (val_size) { \
+ kh_copyval(kh_bval(h, i), cval); \
} \
break; \
} \
@@ -335,9 +340,8 @@ typedef khint_t khiter_t;
if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \
h->keys = (khkey_t *)krealloc((void *)h->keys, \
new_n_buckets * sizeof(khkey_t)); \
- if (kh_is_map) { \
- h->vals = (khval_t *)krealloc((void *)h->vals, \
- new_n_buckets * sizeof(khval_t)); \
+ if (val_size) { \
+ h->vals_buf = krealloc((void *)h->vals_buf, new_n_buckets * val_size); \
} \
} \
kfree(h->flags); /* free the working space */ \
@@ -347,16 +351,16 @@ typedef khint_t khiter_t;
h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \
} \
} \
- SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \
- REAL_FATTR_UNUSED; \
- SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \
+ SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret, size_t val_size) \
+ REAL_FATTR_UNUSED; \
+ SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret, size_t val_size) \
{ \
khint_t x; \
if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \
if (h->n_buckets > (h->size << 1)) { \
- kh_resize_##name(h, h->n_buckets - 1); /* clear "deleted" elements */ \
+ kh_resize_##name(h, h->n_buckets - 1, val_size); /* clear "deleted" elements */ \
} else { \
- kh_resize_##name(h, h->n_buckets + 1); /* expand the hash table */ \
+ kh_resize_##name(h, h->n_buckets + 1, val_size); /* expand the hash table */ \
} \
} /* TODO: implement automatically shrinking; */ \
/* resize() already support shrinking */ \
@@ -407,7 +411,7 @@ typedef khint_t khiter_t;
return x; \
} \
SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \
- REAL_FATTR_UNUSED; \
+ REAL_FATTR_UNUSED; \
SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \
{ \
if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \
@@ -416,16 +420,16 @@ typedef khint_t khiter_t;
} \
}
-#define KHASH_DECLARE(name, khkey_t, khval_t) \
- __KHASH_TYPE(name, khkey_t, khval_t) \
- __KHASH_PROTOTYPES(name, khkey_t, khval_t)
+#define KHASH_DECLARE(khkey_t) \
+ __KHASH_TYPE(khkey_t, khkey_t) \
+ __KHASH_PROTOTYPES(khkey_t, khkey_t)
-#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
+#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, __hash_func, __hash_equal) \
__KHASH_TYPE(name, khkey_t, khval_t) \
- __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
+ __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, __hash_func, __hash_equal)
-#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
- KHASH_INIT2(name, static kh_inline, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
+#define KHASH_INIT(name, khkey_t, khval_t, __hash_func, __hash_equal) \
+ KHASH_INIT2(name, static kh_inline, khkey_t, khval_t, __hash_func, __hash_equal)
// --- BEGIN OF HASH FUNCTIONS ---
@@ -542,7 +546,7 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key)
the bucket has been deleted [int*]
@return Iterator to the inserted element [khint_t]
*/
-#define kh_put(name, h, k, r) kh_put_##name(h, k, r)
+#define kh_put(name, h, k, r, vs) kh_put_##name(h, k, r, vs)
/*! @function
@abstract Retrieve a key from the hash table.
@@ -584,12 +588,7 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key)
@return Value [type of values]
@discussion For hash sets, calling this results in segfault.
*/
-#define kh_val(h, x) ((h)->vals[x])
-
-/*! @function
- @abstract Alias of kh_val()
- */
-#define kh_value(h, x) ((h)->vals[x])
+#define kh_val(type, h, x) (*(type *)(&(h)->vals_buf[(x)*(sizeof (type))]))
/*! @function
@abstract Get the start iterator
@@ -626,13 +625,15 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key)
@param vvar Variable to which value will be assigned
@param code Block of code to execute
*/
-#define kh_foreach(h, kvar, vvar, code) { khint_t __i; \
- for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
- if (!kh_exist(h, __i)) continue; \
- (kvar) = kh_key(h, __i); \
- (vvar) = kh_val(h, __i); \
- code; \
- } }
+#define kh_foreach(type, h, kvar, vvar, code) { \
+ khint_t __i; \
+ for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
+ if (!kh_exist(h,__i)) continue; \
+ (kvar) = kh_key(h,__i); \
+ (vvar) = kh_val(type, h,__i); \
+ code; \
+ } \
+}
/*! @function
@abstract Iterate over the values in the hash table
@@ -640,12 +641,14 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key)
@param vvar Variable to which value will be assigned
@param code Block of code to execute
*/
-#define kh_foreach_value(h, vvar, code) { khint_t __i; \
- for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
- if (!kh_exist(h, __i)) continue; \
- (vvar) = kh_val(h, __i); \
- code; \
- } }
+#define kh_foreach_value(type, h, vvar, code) { \
+ khint_t __i; \
+ for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
+ if (!kh_exist(h,__i)) continue; \
+ (vvar) = kh_val(type, h,__i); \
+ code; \
+ } \
+}
/*! @function
@abstract Iterate over the keys in the hash table
@@ -725,6 +728,6 @@ typedef const char *kh_cstr_t;
.upper_bound = 0, \
.flags = NULL, \
.keys = NULL, \
- .vals = NULL, \
+ .vals_buf = NULL, \
})
#endif // NVIM_LIB_KHASH_H
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index 87232a8a93..d6f0288f94 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -33,12 +33,10 @@
void api_extmark_free_all_mem(void)
{
String name;
- handle_T id;
- map_foreach(&namespace_ids, name, id, {
- (void)id;
+ map_foreach_key(&namespace_ids, name, {
xfree(name.data);
})
- map_destroy(String, handle_T)(&namespace_ids);
+ map_destroy(String, &namespace_ids);
}
/// Creates a new namespace or gets an existing one. \*namespace\*
@@ -77,7 +75,7 @@ Dictionary nvim_get_namespaces(void)
String name;
handle_T id;
- map_foreach(&namespace_ids, name, id, {
+ map_foreach(handle_T, &namespace_ids, name, id, {
PUT(retval, name.data, INTEGER_OBJ(id));
})
@@ -88,7 +86,7 @@ const char *describe_ns(NS ns_id)
{
String name;
handle_T id;
- map_foreach(&namespace_ids, name, id, {
+ map_foreach(handle_T, &namespace_ids, name, id, {
if ((NS)id == ns_id && name.size) {
return name.data;
}
diff --git a/src/nvim/api/extmark.h b/src/nvim/api/extmark.h
index a6586e3031..3c979fa4f6 100644
--- a/src/nvim/api/extmark.h
+++ b/src/nvim/api/extmark.h
@@ -6,7 +6,6 @@
#include "nvim/decoration.h"
#include "nvim/macros.h"
#include "nvim/map.h"
-#include "nvim/map_defs.h"
#include "nvim/types.h"
EXTERN Map(String, handle_T) namespace_ids INIT(= MAP_INIT);
diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h
index 2623c97c9d..bac501ed62 100644
--- a/src/nvim/api/private/helpers.h
+++ b/src/nvim/api/private/helpers.h
@@ -122,13 +122,13 @@
#define api_free_window(value)
#define api_free_tabpage(value)
-EXTERN PMap(handle_T) buffer_handles INIT(= MAP_INIT);
-EXTERN PMap(handle_T) window_handles INIT(= MAP_INIT);
-EXTERN PMap(handle_T) tabpage_handles INIT(= MAP_INIT);
+EXTERN PMap(int) buffer_handles INIT(= MAP_INIT);
+EXTERN PMap(int) window_handles INIT(= MAP_INIT);
+EXTERN PMap(int) tabpage_handles INIT(= MAP_INIT);
-#define handle_get_buffer(h) pmap_get(handle_T)(&buffer_handles, (h))
-#define handle_get_window(h) pmap_get(handle_T)(&window_handles, (h))
-#define handle_get_tabpage(h) pmap_get(handle_T)(&tabpage_handles, (h))
+#define handle_get_buffer(h) pmap_get(int)(&buffer_handles, (h))
+#define handle_get_window(h) pmap_get(int)(&window_handles, (h))
+#define handle_get_tabpage(h) pmap_get(int)(&tabpage_handles, (h))
/// Structure used for saving state for :try
///
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index bd3482c85f..532c3054ab 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -111,7 +111,7 @@ void remote_ui_disconnect(uint64_t channel_id)
}
UIData *data = ui->data;
kv_destroy(data->call_buf);
- pmap_del(uint64_t)(&connected_uis, channel_id);
+ pmap_del(uint64_t)(&connected_uis, channel_id, NULL);
ui_detach_impl(ui, channel_id);
// Destroy `ui`.
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index 2d5d8e262b..17a3fd33f1 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -108,14 +108,13 @@ static Map(int, String) map_augroup_id_to_name = MAP_INIT;
static void augroup_map_del(int id, const char *name)
{
if (name != NULL) {
- String key = map_key(String, int)(&map_augroup_name_to_id, cstr_as_string((char *)name));
- map_del(String, int)(&map_augroup_name_to_id, key);
+ String key;
+ map_del(String, int)(&map_augroup_name_to_id, cstr_as_string((char *)name), &key);
api_free_string(key);
}
if (id > 0) {
- String mapped = map_get(int, String)(&map_augroup_id_to_name, id);
+ String mapped = map_del(int, String)(&map_augroup_id_to_name, id, NULL);
api_free_string(mapped);
- map_del(int, String)(&map_augroup_id_to_name, id);
}
}
@@ -543,7 +542,7 @@ void do_augroup(char *arg, int del_group)
String name;
int value;
- map_foreach(&map_augroup_name_to_id, name, value, {
+ map_foreach(int, &map_augroup_name_to_id, name, value, {
if (value > 0) {
msg_puts(name.data);
} else {
@@ -572,18 +571,15 @@ void free_all_autocmds(void)
// Delete the augroup_map, including free the data
String name;
- int id;
- map_foreach(&map_augroup_name_to_id, name, id, {
- (void)id;
+ map_foreach_key(&map_augroup_name_to_id, name, {
api_free_string(name);
})
- map_destroy(String, int)(&map_augroup_name_to_id);
+ map_destroy(String, &map_augroup_name_to_id);
- map_foreach(&map_augroup_id_to_name, id, name, {
- (void)id;
+ map_foreach_value(String, &map_augroup_id_to_name, name, {
api_free_string(name);
})
- map_destroy(int, String)(&map_augroup_id_to_name);
+ map_destroy(int, &map_augroup_id_to_name);
// aucmd_win[] is freed in win_free_all()
}
@@ -1311,7 +1307,7 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
block_autocmds(); // We don't want BufEnter/WinEnter autocommands.
if (need_append) {
win_append(lastwin, auc_win);
- pmap_put(handle_T)(&window_handles, auc_win->handle, auc_win);
+ pmap_put(int)(&window_handles, auc_win->handle, auc_win);
win_config_float(auc_win, auc_win->w_float_config);
}
// Prevent chdir() call in win_enter_ext(), through do_autochdir()
@@ -1367,7 +1363,7 @@ win_found:
}
// Remove the window.
win_remove(curwin, NULL);
- pmap_del(handle_T)(&window_handles, curwin->handle);
+ pmap_del(int)(&window_handles, curwin->handle, NULL);
if (curwin->w_grid_alloc.chars != NULL) {
ui_comp_remove_grid(&curwin->w_grid_alloc);
ui_call_win_hide(curwin->w_grid_alloc.handle);
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index b2edbf4053..e734a340d9 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -833,7 +833,7 @@ void buf_freeall(buf_T *buf, int flags)
/// itself (not the file, that must have been done already).
static void free_buffer(buf_T *buf)
{
- pmap_del(handle_T)(&buffer_handles, buf->b_fnum);
+ pmap_del(int)(&buffer_handles, buf->b_fnum, NULL);
buf_free_count++;
// b:changedtick uses an item in buf_T.
free_buffer_stuff(buf, kBffClearWinInfo);
@@ -1865,7 +1865,7 @@ buf_T *buflist_new(char *ffname_arg, char *sfname_arg, linenr_T lnum, int flags)
lastbuf = buf;
buf->b_fnum = top_file_num++;
- pmap_put(handle_T)(&buffer_handles, buf->b_fnum, buf);
+ pmap_put(int)(&buffer_handles, buf->b_fnum, buf);
if (top_file_num < 0) { // wrap around (may cause duplicates)
emsg(_("W14: Warning: List of file names overflow"));
if (emsg_silent == 0 && !in_assert_fails) {
diff --git a/src/nvim/channel.c b/src/nvim/channel.c
index 820ce534e1..154b8206b8 100644
--- a/src/nvim/channel.c
+++ b/src/nvim/channel.c
@@ -57,7 +57,7 @@ void channel_teardown(void)
{
Channel *channel;
- map_foreach_value(&channels, channel, {
+ pmap_foreach_value(&channels, channel, {
channel_close(channel->id, kChannelPartAll, NULL);
});
}
@@ -279,7 +279,7 @@ static void free_channel_event(void **argv)
callback_reader_free(&chan->on_stderr);
callback_free(&chan->on_exit);
- pmap_del(uint64_t)(&channels, chan->id);
+ pmap_del(uint64_t)(&channels, chan->id, NULL);
multiqueue_free(chan->events);
xfree(chan);
}
@@ -289,7 +289,7 @@ static void channel_destroy_early(Channel *chan)
if ((chan->id != --next_chan_id)) {
abort();
}
- pmap_del(uint64_t)(&channels, chan->id);
+ pmap_del(uint64_t)(&channels, chan->id, NULL);
chan->id = 0;
if ((--chan->refcount != 0)) {
@@ -938,7 +938,7 @@ Array channel_all_info(void)
{
Channel *channel;
Array ret = ARRAY_DICT_INIT;
- map_foreach_value(&channels, channel, {
+ pmap_foreach_value(&channels, channel, {
ADD(ret, DICTIONARY_OBJ(channel_info(channel->id)));
});
return ret;
diff --git a/src/nvim/channel.h b/src/nvim/channel.h
index 7400465af0..deb693373c 100644
--- a/src/nvim/channel.h
+++ b/src/nvim/channel.h
@@ -15,7 +15,6 @@
#include "nvim/macros.h"
#include "nvim/main.h"
#include "nvim/map.h"
-#include "nvim/map_defs.h"
#include "nvim/msgpack_rpc/channel_defs.h"
#include "nvim/os/pty_process.h"
#include "nvim/terminal.h"
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 5c05b8faf7..1b21f107a8 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -4520,7 +4520,7 @@ bool garbage_collect(bool testing)
// Channels
{
Channel *data;
- map_foreach_value(&channels, data, {
+ pmap_foreach_value(&channels, data, {
set_ref_in_callback_reader(&data->on_data, copyID, NULL, NULL);
set_ref_in_callback_reader(&data->on_stderr, copyID, NULL, NULL);
set_ref_in_callback(&data->on_exit, copyID, NULL, NULL);
@@ -4530,7 +4530,7 @@ bool garbage_collect(bool testing)
// Timers
{
timer_T *timer;
- map_foreach_value(&timers, timer, {
+ pmap_foreach_value(&timers, timer, {
set_ref_in_callback(&timer->callback, copyID, NULL, NULL);
})
}
@@ -5986,7 +5986,7 @@ void add_timer_info_all(typval_T *rettv)
{
tv_list_alloc_ret(rettv, map_size(&timers));
timer_T *timer;
- map_foreach_value(&timers, timer, {
+ pmap_foreach_value(&timers, timer, {
if (!timer->stopped || timer->refcount > 1) {
add_timer_info(rettv, timer);
}
@@ -6084,7 +6084,7 @@ static void timer_close_cb(TimeWatcher *tw, void *data)
timer_T *timer = (timer_T *)data;
multiqueue_free(timer->tw.events);
callback_free(&timer->callback);
- pmap_del(uint64_t)(&timers, (uint64_t)timer->timer_id);
+ pmap_del(uint64_t)(&timers, (uint64_t)timer->timer_id, NULL);
timer_decref(timer);
}
@@ -6098,7 +6098,7 @@ static void timer_decref(timer_T *timer)
void timer_stop_all(void)
{
timer_T *timer;
- map_foreach_value(&timers, timer, {
+ pmap_foreach_value(&timers, timer, {
timer_stop(timer);
})
}
diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c
index 727be1562c..acdc36f9c7 100644
--- a/src/nvim/extmark.c
+++ b/src/nvim/extmark.c
@@ -50,11 +50,6 @@
# include "extmark.c.generated.h"
#endif
-static uint32_t *buf_ns_ref(buf_T *buf, uint32_t ns_id, bool put)
-{
- return map_ref(uint32_t, uint32_t)(buf->b_extmark_ns, ns_id, put);
-}
-
/// Create or update an extmark
///
/// must not be used during iteration!
@@ -62,7 +57,7 @@ void extmark_set(buf_T *buf, uint32_t ns_id, uint32_t *idp, int row, colnr_T col
colnr_T end_col, Decoration *decor, bool right_gravity, bool end_right_gravity,
ExtmarkOp op, Error *err)
{
- uint32_t *ns = buf_ns_ref(buf, ns_id, true);
+ uint32_t *ns = map_put_ref(uint32_t, uint32_t)(buf->b_extmark_ns, ns_id, NULL, NULL);
uint32_t id = idp ? *idp : 0;
bool decor_full = false;
@@ -237,7 +232,7 @@ bool extmark_clear(buf_T *buf, uint32_t ns_id, int l_row, colnr_T l_col, int u_r
bool all_ns = (ns_id == 0);
uint32_t *ns = NULL;
if (!all_ns) {
- ns = buf_ns_ref(buf, ns_id, false);
+ ns = map_ref(uint32_t, uint32_t)(buf->b_extmark_ns, ns_id, NULL);
if (!ns) {
// nothing to do
return false;
@@ -258,15 +253,14 @@ bool extmark_clear(buf_T *buf, uint32_t ns_id, int l_row, colnr_T l_col, int u_r
|| (mark.pos.row == u_row && mark.pos.col > u_col)) {
break;
}
- ssize_t *del_status = map_ref(uint64_t, ssize_t)(&delete_set, mt_lookup_key(mark),
- false);
+ ssize_t *del_status = map_ref(uint64_t, ssize_t)(&delete_set, mt_lookup_key(mark), NULL);
if (del_status) {
marktree_del_itr(buf->b_marktree, itr, false);
if (*del_status >= 0) { // we had a decor_id
DecorItem it = kv_A(decors, *del_status);
decor_remove(buf, it.row1, mark.pos.row, mark.decor_full);
}
- map_del(uint64_t, ssize_t)(&delete_set, mt_lookup_key(mark));
+ map_del(uint64_t, ssize_t)(&delete_set, mt_lookup_key(mark), NULL);
continue;
}
@@ -294,7 +288,7 @@ bool extmark_clear(buf_T *buf, uint32_t ns_id, int l_row, colnr_T l_col, int u_r
}
uint64_t id;
ssize_t decor_id;
- map_foreach(&delete_set, id, decor_id, {
+ map_foreach(ssize_t, &delete_set, id, decor_id, {
mtkey_t mark = marktree_lookup(buf->b_marktree, id, itr);
assert(marktree_itr_valid(itr));
marktree_del_itr(buf->b_marktree, itr, false);
@@ -303,7 +297,7 @@ bool extmark_clear(buf_T *buf, uint32_t ns_id, int l_row, colnr_T l_col, int u_r
decor_remove(buf, it.row1, mark.pos.row, mark.decor_full);
}
});
- map_clear(uint64_t, ssize_t)(&delete_set);
+ map_clear(uint64_t, &delete_set);
kv_size(decors) = 0;
return marks_cleared;
}
@@ -424,8 +418,8 @@ void extmark_free_all(buf_T *buf)
marktree_clear(buf->b_marktree);
- map_destroy(uint32_t, uint32_t)(buf->b_extmark_ns);
- map_init(uint32_t, uint32_t, buf->b_extmark_ns);
+ map_destroy(uint32_t, buf->b_extmark_ns);
+ *buf->b_extmark_ns = (Map(uint32_t, uint32_t)) MAP_INIT;
}
/// Save info for undo/redo of set marks
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index cc332c530d..a53da95fba 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -50,7 +50,7 @@ static Map(int, int) blendthrough_attr_entries = MAP_INIT;
/// highlight entries private to a namespace
static Map(ColorKey, ColorItem) ns_hls;
typedef int NSHlAttr[HLF_COUNT + 1];
-static PMap(handle_T) ns_hl_attr;
+static PMap(int) ns_hl_attr;
void highlight_init(void)
{
@@ -277,7 +277,7 @@ bool hl_check_ns(void)
hl_attr_active = highlight_attr;
if (ns > 0) {
update_ns_hl(ns);
- NSHlAttr *hl_def = (NSHlAttr *)pmap_get(handle_T)(&ns_hl_attr, ns);
+ NSHlAttr *hl_def = (NSHlAttr *)pmap_get(int)(&ns_hl_attr, ns);
if (hl_def) {
hl_attr_active = *hl_def;
}
@@ -335,7 +335,7 @@ void update_window_hl(win_T *wp, bool invalid)
if (ns_id != wp->w_ns_hl_active || wp->w_ns_hl_attr == NULL) {
wp->w_ns_hl_active = ns_id;
- wp->w_ns_hl_attr = *(NSHlAttr *)pmap_get(handle_T)(&ns_hl_attr, ns_id);
+ wp->w_ns_hl_attr = *(NSHlAttr *)pmap_get(int)(&ns_hl_attr, ns_id);
if (!wp->w_ns_hl_attr) {
// No specific highlights, use the defaults.
wp->w_ns_hl_attr = highlight_attr;
@@ -419,7 +419,7 @@ void update_ns_hl(int ns_id)
return;
}
- NSHlAttr **alloc = (NSHlAttr **)pmap_ref(handle_T)(&ns_hl_attr, ns_id, true);
+ NSHlAttr **alloc = (NSHlAttr **)pmap_put_ref(int)(&ns_hl_attr, ns_id, NULL, NULL);
if (*alloc == NULL) {
*alloc = xmalloc(sizeof(**alloc));
}
@@ -491,28 +491,28 @@ void clear_hl_tables(bool reinit)
{
if (reinit) {
kv_size(attr_entries) = 1;
- map_clear(HlEntry, int)(&attr_entry_ids);
- map_clear(int, int)(&combine_attr_entries);
- map_clear(int, int)(&blend_attr_entries);
- map_clear(int, int)(&blendthrough_attr_entries);
+ map_clear(HlEntry, &attr_entry_ids);
+ map_clear(int, &combine_attr_entries);
+ map_clear(int, &blend_attr_entries);
+ map_clear(int, &blendthrough_attr_entries);
memset(highlight_attr_last, -1, sizeof(highlight_attr_last));
highlight_attr_set_all();
highlight_changed();
screen_invalidate_highlights();
} else {
kv_destroy(attr_entries);
- map_destroy(HlEntry, int)(&attr_entry_ids);
- map_destroy(int, int)(&combine_attr_entries);
- map_destroy(int, int)(&blend_attr_entries);
- map_destroy(int, int)(&blendthrough_attr_entries);
- map_destroy(ColorKey, ColorItem)(&ns_hls);
+ map_destroy(HlEntry, &attr_entry_ids);
+ map_destroy(int, &combine_attr_entries);
+ map_destroy(int, &blend_attr_entries);
+ map_destroy(int, &blendthrough_attr_entries);
+ map_destroy(ColorKey, &ns_hls);
}
}
void hl_invalidate_blends(void)
{
- map_clear(int, int)(&blend_attr_entries);
- map_clear(int, int)(&blendthrough_attr_entries);
+ map_clear(int, &blend_attr_entries);
+ map_clear(int, &blendthrough_attr_entries);
highlight_changed();
update_window_hl(curwin, true);
}
diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c
index a0f0a947b8..41e7bdb7ac 100644
--- a/src/nvim/highlight_group.c
+++ b/src/nvim/highlight_group.c
@@ -1420,7 +1420,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
void free_highlight(void)
{
ga_clear(&highlight_ga);
- map_destroy(cstr_t, int)(&highlight_unames);
+ map_destroy(cstr_t, &highlight_unames);
arena_mem_free(arena_finish(&highlight_arena));
}
diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c
index 9586b56f3c..1d11379956 100644
--- a/src/nvim/lua/executor.c
+++ b/src/nvim/lua/executor.c
@@ -910,7 +910,7 @@ static void nlua_common_free_all_mem(lua_State *lstate)
if (nlua_track_refs) {
// in case there are leaked luarefs, leak the associated memory
// to get LeakSanitizer stacktraces on exit
- pmap_destroy(handle_T)(&ref_state->ref_markers);
+ map_destroy(int, &ref_state->ref_markers);
}
#endif
@@ -1285,7 +1285,7 @@ LuaRef nlua_ref(lua_State *lstate, nlua_ref_state_t *ref_state, int index)
#ifdef NLUA_TRACK_REFS
if (nlua_track_refs) {
// dummy allocation to make LeakSanitizer track our luarefs
- pmap_put(handle_T)(&ref_state->ref_markers, ref, xmalloc(3));
+ pmap_put(int)(&ref_state->ref_markers, ref, xmalloc(3));
}
#endif
}
@@ -1305,7 +1305,7 @@ void nlua_unref(lua_State *lstate, nlua_ref_state_t *ref_state, LuaRef ref)
#ifdef NLUA_TRACK_REFS
// NB: don't remove entry from map to track double-unref
if (nlua_track_refs) {
- xfree(pmap_get(handle_T)(&ref_state->ref_markers, ref));
+ xfree(pmap_get(int)(&ref_state->ref_markers, ref));
}
#endif
luaL_unref(lstate, LUA_REGISTRYINDEX, ref);
diff --git a/src/nvim/lua/executor.h b/src/nvim/lua/executor.h
index 7e16c0f45c..f340d9d0d8 100644
--- a/src/nvim/lua/executor.h
+++ b/src/nvim/lua/executor.h
@@ -24,7 +24,7 @@ typedef struct {
LuaRef empty_dict_ref;
int ref_count;
#if __has_feature(address_sanitizer)
- PMap(handle_T) ref_markers;
+ PMap(int) ref_markers;
#endif
} nlua_ref_state_t;
diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c
index 0c16d09b63..dae1365272 100644
--- a/src/nvim/lua/treesitter.c
+++ b/src/nvim/lua/treesitter.c
@@ -231,9 +231,9 @@ int tslua_remove_lang(lua_State *L)
const char *lang_name = luaL_checkstring(L, 1);
bool present = pmap_has(cstr_t)(&langs, lang_name);
if (present) {
- char *key = (char *)pmap_key(cstr_t)(&langs, lang_name);
- pmap_del(cstr_t)(&langs, lang_name);
- xfree(key);
+ cstr_t key;
+ pmap_del(cstr_t)(&langs, lang_name, &key);
+ xfree((void *)key);
}
lua_pushboolean(L, present);
return 1;
diff --git a/src/nvim/map.c b/src/nvim/map.c
index 191a459863..4c8506f468 100644
--- a/src/nvim/map.c
+++ b/src/nvim/map.c
@@ -16,7 +16,6 @@
#include "klib/khash.h"
#include "nvim/gettext.h"
#include "nvim/map.h"
-#include "nvim/map_defs.h"
#include "nvim/memory.h"
#define cstr_t_hash kh_str_hash_func
@@ -29,8 +28,6 @@
#define int_eq kh_int_hash_equal
#define handle_T_hash kh_int_hash_func
#define handle_T_eq kh_int_hash_equal
-#define KittyKey_hash kh_int_hash_func
-#define KittyKey_eq kh_int_hash_equal
#if defined(ARCH_64)
# define ptr_t_hash(key) uint64_t_hash((uint64_t)(key))
@@ -45,74 +42,69 @@
#define DEFAULT_INITIALIZER { 0 }
#define SSIZE_INITIALIZER { -1 }
+#define KEY_IMPL(T) \
+ __KHASH_IMPL(T, , T, T##_hash, T##_eq) \
+
#define MAP_IMPL(T, U, ...) \
INITIALIZER_DECLARE(T, U, __VA_ARGS__); \
- __KHASH_IMPL(T##_##U##_map, , T, U, 1, T##_hash, T##_eq) \
- void map_##T##_##U##_destroy(Map(T, U) *map) \
- { \
- kh_dealloc(T##_##U##_map, &map->table); \
- } \
U map_##T##_##U##_get(Map(T, U) *map, T key) \
{ \
khiter_t k; \
- if ((k = kh_get(T##_##U##_map, &map->table, key)) == kh_end(&map->table)) { \
+ if ((k = kh_get(T, &map->table, key)) == kh_end(&map->table)) { \
return INITIALIZER(T, U); \
} \
- return kh_val(&map->table, k); \
- } \
- bool map_##T##_##U##_has(Map(T, U) *map, T key) \
- { \
- return kh_get(T##_##U##_map, &map->table, key) != kh_end(&map->table); \
- } \
- T map_##T##_##U##_key(Map(T, U) *map, T key) \
- { \
- khiter_t k; \
- if ((k = kh_get(T##_##U##_map, &map->table, key)) == kh_end(&map->table)) { \
- abort(); /* Caller must check map_has(). */ \
- } \
- return kh_key(&map->table, k); \
+ return kh_val(U, &map->table, k); \
} \
U map_##T##_##U##_put(Map(T, U) *map, T key, U value) \
{ \
+ STATIC_ASSERT(sizeof(U) <= KHASH_MAX_VAL_SIZE, "increase KHASH_MAX_VAL_SIZE"); \
int ret; \
U rv = INITIALIZER(T, U); \
- khiter_t k = kh_put(T##_##U##_map, &map->table, key, &ret); \
+ khiter_t k = kh_put(T, &map->table, key, &ret, sizeof(U)); \
if (!ret) { \
- rv = kh_val(&map->table, k); \
+ rv = kh_val(U, &map->table, k); \
} \
- kh_val(&map->table, k) = value; \
+ kh_val(U, &map->table, k) = value; \
return rv; \
} \
- U *map_##T##_##U##_ref(Map(T, U) *map, T key, bool put) \
+ U *map_##T##_##U##_ref(Map(T, U) *map, T key, T **key_alloc) \
+ { \
+ khiter_t k = kh_get(T, &map->table, key); \
+ if (k == kh_end(&map->table)) { \
+ return NULL; \
+ } \
+ if (key_alloc) { \
+ *key_alloc = &kh_key(&map->table, k); \
+ } \
+ return &kh_val(U, &map->table, k); \
+ } \
+ U *map_##T##_##U##_put_ref(Map(T, U) *map, T key, T **key_alloc, bool *new_item) \
{ \
int ret; \
- khiter_t k; \
- if (put) { \
- k = kh_put(T##_##U##_map, &map->table, key, &ret); \
- if (ret) { \
- kh_val(&map->table, k) = INITIALIZER(T, U); \
- } \
- } else { \
- k = kh_get(T##_##U##_map, &map->table, key); \
- if (k == kh_end(&map->table)) { \
- return NULL; \
- } \
+ khiter_t k = kh_put(T, &map->table, key, &ret, sizeof(U)); \
+ if (ret) { \
+ kh_val(U, &map->table, k) = INITIALIZER(T, U); \
} \
- return &kh_val(&map->table, k); \
+ if (new_item) { \
+ *new_item = (bool)ret; \
+ } \
+ if (key_alloc) { \
+ *key_alloc = &kh_key(&map->table, k); \
+ } \
+ return &kh_val(U, &map->table, k); \
} \
- U map_##T##_##U##_del(Map(T, U) *map, T key) \
+ U map_##T##_##U##_del(Map(T, U) *map, T key, T *key_alloc) \
{ \
U rv = INITIALIZER(T, U); \
khiter_t k; \
- if ((k = kh_get(T##_##U##_map, &map->table, key)) != kh_end(&map->table)) { \
- rv = kh_val(&map->table, k); \
- kh_del(T##_##U##_map, &map->table, k); \
+ if ((k = kh_get(T, &map->table, key)) != kh_end(&map->table)) { \
+ rv = kh_val(U, &map->table, k); \
+ if (key_alloc) { \
+ *key_alloc = kh_key(&map->table, k); \
+ } \
+ kh_del(T, &map->table, k); \
} \
return rv; \
- } \
- void map_##T##_##U##_clear(Map(T, U) *map) \
- { \
- kh_clear(T##_##U##_map, &map->table); \
}
static inline khint_t String_hash(String s)
@@ -162,7 +154,17 @@ static inline bool ColorKey_eq(ColorKey ae1, ColorKey ae2)
return memcmp(&ae1, &ae2, sizeof(ae1)) == 0;
}
+KEY_IMPL(int)
+KEY_IMPL(cstr_t)
+KEY_IMPL(ptr_t)
+KEY_IMPL(uint64_t)
+KEY_IMPL(uint32_t)
+KEY_IMPL(String)
+KEY_IMPL(HlEntry)
+KEY_IMPL(ColorKey)
+
MAP_IMPL(int, int, DEFAULT_INITIALIZER)
+MAP_IMPL(int, ptr_t, DEFAULT_INITIALIZER)
MAP_IMPL(int, cstr_t, DEFAULT_INITIALIZER)
MAP_IMPL(cstr_t, ptr_t, DEFAULT_INITIALIZER)
MAP_IMPL(cstr_t, int, DEFAULT_INITIALIZER)
@@ -172,26 +174,19 @@ MAP_IMPL(uint64_t, ptr_t, DEFAULT_INITIALIZER)
MAP_IMPL(uint64_t, ssize_t, SSIZE_INITIALIZER)
MAP_IMPL(uint64_t, uint64_t, DEFAULT_INITIALIZER)
MAP_IMPL(uint32_t, uint32_t, DEFAULT_INITIALIZER)
-MAP_IMPL(handle_T, ptr_t, DEFAULT_INITIALIZER)
MAP_IMPL(HlEntry, int, DEFAULT_INITIALIZER)
MAP_IMPL(String, handle_T, 0)
MAP_IMPL(String, int, DEFAULT_INITIALIZER)
MAP_IMPL(int, String, DEFAULT_INITIALIZER)
-
MAP_IMPL(ColorKey, ColorItem, COLOR_ITEM_INITIALIZER)
-MAP_IMPL(KittyKey, cstr_t, DEFAULT_INITIALIZER)
-
/// Deletes a key:value pair from a string:pointer map, and frees the
/// storage of both key and value.
///
void pmap_del2(PMap(cstr_t) *map, const char *key)
{
- if (pmap_has(cstr_t)(map, key)) {
- void *k = (void *)pmap_key(cstr_t)(map, key);
- void *v = pmap_get(cstr_t)(map, key);
- pmap_del(cstr_t)(map, key);
- xfree(k);
- xfree(v);
- }
+ cstr_t key_alloc = NULL;
+ ptr_t val = pmap_del(cstr_t)(map, key, &key_alloc);
+ xfree((void *)key_alloc);
+ xfree(val);
}
diff --git a/src/nvim/map.h b/src/nvim/map.h
index 92f0b32255..cc32a20740 100644
--- a/src/nvim/map.h
+++ b/src/nvim/map.h
@@ -7,39 +7,71 @@
#include "klib/khash.h"
#include "nvim/api/private/defs.h"
-#include "nvim/extmark_defs.h"
-#include "nvim/gettext.h"
+#include "nvim/assert.h"
#include "nvim/highlight_defs.h"
-#include "nvim/map_defs.h"
-#include "nvim/tui/input_defs.h"
#include "nvim/types.h"
-#include "nvim/ui_client.h"
#if defined(__NetBSD__)
# undef uint64_t
# define uint64_t uint64_t
#endif
+typedef const char *cstr_t;
+typedef void *ptr_t;
+
+#define Map(T, U) Map_##T##_##U
+#define PMap(T) Map(T, ptr_t)
+
+#define KEY_DECLS(T) \
+ KHASH_DECLARE(T) \
+ static inline bool set_put_##T(Set(T) *set, T key, T **key_alloc) { \
+ int kh_ret; \
+ khiter_t k = kh_put(T, set, key, &kh_ret, 0); \
+ if (key_alloc) { \
+ *key_alloc = &kh_key(set, k); \
+ } \
+ return kh_ret; \
+ } \
+ static inline void set_del_##T(Set(T) *set, T key) \
+ { \
+ khiter_t k; \
+ if ((k = kh_get(T, set, key)) != kh_end(set)) { \
+ kh_del(T, set, k); \
+ } \
+ } \
+ static inline bool set_has_##T(Set(T) *set, T key) { \
+ return (kh_get(T, set, key) != kh_end(set)); \
+ } \
+
#define MAP_DECLS(T, U) \
- KHASH_DECLARE(T##_##U##_map, T, U) \
typedef struct { \
- khash_t(T##_##U##_map) table; \
+ khash_t(T) table; \
} Map(T, U); \
- Map(T, U) *map_##T##_##U##_new(void); \
- void map_##T##_##U##_free(Map(T, U) *map); \
- void map_##T##_##U##_destroy(Map(T, U) *map); \
U map_##T##_##U##_get(Map(T, U) *map, T key); \
- bool map_##T##_##U##_has(Map(T, U) *map, T key); \
- T map_##T##_##U##_key(Map(T, U) *map, T key); \
+ static inline bool map_##T##_##U##_has(Map(T, U) *map, T key) \
+ { \
+ return kh_get(T, &map->table, key) != kh_end(&map->table); \
+ } \
U map_##T##_##U##_put(Map(T, U) *map, T key, U value); \
- U *map_##T##_##U##_ref(Map(T, U) *map, T key, bool put); \
- U map_##T##_##U##_del(Map(T, U) *map, T key); \
- void map_##T##_##U##_clear(Map(T, U) *map);
+ U *map_##T##_##U##_ref(Map(T, U) *map, T key, T **key_alloc); \
+ U *map_##T##_##U##_put_ref(Map(T, U) *map, T key, T **key_alloc, bool *new_item); \
+ U map_##T##_##U##_del(Map(T, U) *map, T key, T *key_alloc); \
-//
// NOTE: Keys AND values must be allocated! khash.h does not make a copy.
-//
+
+#define Set(type) khash_t(type)
+
+KEY_DECLS(int)
+KEY_DECLS(cstr_t)
+KEY_DECLS(ptr_t)
+KEY_DECLS(uint64_t)
+KEY_DECLS(uint32_t)
+KEY_DECLS(String)
+KEY_DECLS(HlEntry)
+KEY_DECLS(ColorKey)
+
MAP_DECLS(int, int)
+MAP_DECLS(int, ptr_t)
MAP_DECLS(int, cstr_t)
MAP_DECLS(cstr_t, ptr_t)
MAP_DECLS(cstr_t, int)
@@ -49,48 +81,50 @@ MAP_DECLS(uint64_t, ptr_t)
MAP_DECLS(uint64_t, ssize_t)
MAP_DECLS(uint64_t, uint64_t)
MAP_DECLS(uint32_t, uint32_t)
-
-MAP_DECLS(handle_T, ptr_t)
MAP_DECLS(HlEntry, int)
MAP_DECLS(String, handle_T)
MAP_DECLS(String, int)
MAP_DECLS(int, String)
-
MAP_DECLS(ColorKey, ColorItem)
-MAP_DECLS(KittyKey, cstr_t)
-
-#define MAP_INIT { { 0, 0, 0, 0, NULL, NULL, NULL } }
-#define map_init(k, v, map) do { *(map) = (Map(k, v)) MAP_INIT; } while (false)
+#define SET_INIT { 0, 0, 0, 0, NULL, NULL, NULL }
+#define MAP_INIT { SET_INIT }
-#define map_destroy(T, U) map_##T##_##U##_destroy
#define map_get(T, U) map_##T##_##U##_get
#define map_has(T, U) map_##T##_##U##_has
-#define map_key(T, U) map_##T##_##U##_key
#define map_put(T, U) map_##T##_##U##_put
#define map_ref(T, U) map_##T##_##U##_ref
+#define map_put_ref(T, U) map_##T##_##U##_put_ref
#define map_del(T, U) map_##T##_##U##_del
-#define map_clear(T, U) map_##T##_##U##_clear
+#define map_destroy(T, map) kh_dealloc(T, &(map)->table)
+#define map_clear(T, map) kh_clear(T, &(map)->table)
#define map_size(map) ((map)->table.size)
-#define pmap_destroy(T) map_destroy(T, ptr_t)
#define pmap_get(T) map_get(T, ptr_t)
#define pmap_has(T) map_has(T, ptr_t)
-#define pmap_key(T) map_key(T, ptr_t)
#define pmap_put(T) map_put(T, ptr_t)
#define pmap_ref(T) map_ref(T, ptr_t)
+#define pmap_put_ref(T) map_put_ref(T, ptr_t)
/// @see pmap_del2
#define pmap_del(T) map_del(T, ptr_t)
-#define pmap_clear(T) map_clear(T, ptr_t)
-#define pmap_init(k, map) map_init(k, ptr_t, map)
-#define map_foreach(map, key, value, block) \
- kh_foreach(&(map)->table, key, value, block)
+#define map_foreach(U, map, key, value, block) kh_foreach(U, &(map)->table, key, value, block)
-#define map_foreach_value(map, value, block) \
- kh_foreach_value(&(map)->table, value, block)
+#define map_foreach_value(U, map, value, block) kh_foreach_value(U, &(map)->table, value, block)
+#define map_foreach_key(map, key, block) kh_foreach_key(&(map)->table, key, block)
+#define set_foreach(set, key, block) kh_foreach_key(set, key, block)
+
+#define pmap_foreach_value(map, value, block) map_foreach_value(ptr_t, map, value, block)
+#define pmap_foreach(map, key, value, block) map_foreach(ptr_t, map, key, value, block)
void pmap_del2(PMap(cstr_t) *map, const char *key);
+#define set_has(T, set, key) set_has_##T(set, key)
+#define set_put(T, set, key) set_put_##T(set, key, NULL)
+#define set_put_ref(T, set, key, key_alloc) set_put_##T(set, key, key_alloc)
+#define set_del(T, set, key) set_del_##T(set, key)
+#define set_destroy(T, set) kh_dealloc(T, set)
+#define set_clear(T, set) kh_clear(T, set)
+
#endif // NVIM_MAP_H
diff --git a/src/nvim/map_defs.h b/src/nvim/map_defs.h
deleted file mode 100644
index 61afedbe50..0000000000
--- a/src/nvim/map_defs.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef NVIM_MAP_DEFS_H
-#define NVIM_MAP_DEFS_H
-
-#include "klib/khash.h"
-
-typedef const char *cstr_t;
-typedef void *ptr_t;
-
-#define Map(T, U) Map_##T##_##U
-#define PMap(T) Map(T, ptr_t)
-
-#endif // NVIM_MAP_DEFS_H
diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c
index 757906d42f..840b6b646e 100644
--- a/src/nvim/marktree.c
+++ b/src/nvim/marktree.c
@@ -359,7 +359,7 @@ uint64_t marktree_del_itr(MarkTree *b, MarkTreeIter *itr, bool rev)
}
b->n_keys--;
- pmap_del(uint64_t)(b->id2node, id);
+ pmap_del(uint64_t)(b->id2node, id, NULL);
// 5.
bool itr_dirty = false;
@@ -549,8 +549,8 @@ void marktree_clear(MarkTree *b)
b->root = NULL;
}
if (b->id2node->table.keys) {
- pmap_destroy(uint64_t)(b->id2node);
- pmap_init(uint64_t, b->id2node);
+ map_destroy(uint64_t, b->id2node);
+ *b->id2node = (PMap(uint64_t)) MAP_INIT;
}
b->n_keys = 0;
b->n_nodes = 0;
diff --git a/src/nvim/marktree.h b/src/nvim/marktree.h
index 29d2abcd46..cd56115b58 100644
--- a/src/nvim/marktree.h
+++ b/src/nvim/marktree.h
@@ -9,7 +9,6 @@
#include "nvim/assert.h"
#include "nvim/garray.h"
#include "nvim/map.h"
-#include "nvim/map_defs.h"
#include "nvim/pos.h"
#include "nvim/types.h"
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index b9a26e1ac6..1f550ffb01 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -664,6 +664,7 @@ char *arena_memdupz(Arena *arena, const char *buf, size_t size)
# include "nvim/getchar.h"
# include "nvim/grid.h"
# include "nvim/mark.h"
+# include "nvim/msgpack_rpc/channel.h"
# include "nvim/ops.h"
# include "nvim/option.h"
# include "nvim/os/os.h"
@@ -823,6 +824,7 @@ void free_all_mem(void)
ui_free_all_mem();
nlua_free_all_mem();
+ rpc_free_all_mem();
// should be last, in case earlier free functions deallocates arenas
arena_free_reuse_blks();
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index 96b4bf5c3a..cd5daee915 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -110,7 +110,7 @@ static void log_client_msg(uint64_t channel_id, bool is_request, const char *nam
# define log_server_msg(...)
#endif
-static PMap(cstr_t) event_strings = MAP_INIT;
+static Set(cstr_t) event_strings = SET_INIT;
static msgpack_sbuffer out_buffer;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -254,14 +254,12 @@ void rpc_subscribe(uint64_t id, char *event)
abort();
}
- char *event_string = pmap_get(cstr_t)(&event_strings, event);
-
- if (!event_string) {
- event_string = xstrdup(event);
- pmap_put(cstr_t)(&event_strings, event_string, event_string);
+ const char **key_alloc = NULL;
+ if (set_put_ref(cstr_t, &event_strings, event, &key_alloc)) {
+ *key_alloc = xstrdup(event);
}
- pmap_put(cstr_t)(channel->rpc.subscribed_events, event_string, event_string);
+ set_put(cstr_t, channel->rpc.subscribed_events, *key_alloc);
}
/// Unsubscribes to event broadcasts
@@ -553,9 +551,9 @@ static void broadcast_event(const char *name, Array args)
kvec_t(Channel *) subscribed = KV_INITIAL_VALUE;
Channel *channel;
- map_foreach_value(&channels, channel, {
+ pmap_foreach_value(&channels, channel, {
if (channel->is_rpc
- && pmap_has(cstr_t)(channel->rpc.subscribed_events, name)) {
+ && set_has(cstr_t, channel->rpc.subscribed_events, name)) {
kv_push(subscribed, channel);
}
});
@@ -583,24 +581,12 @@ end:
static void unsubscribe(Channel *channel, char *event)
{
- char *event_string = pmap_get(cstr_t)(&event_strings, event);
- if (!event_string) {
+ if (!set_has(cstr_t, &event_strings, event)) {
WLOG("RPC: ch %" PRIu64 ": tried to unsubscribe unknown event '%s'",
channel->id, event);
return;
}
- pmap_del(cstr_t)(channel->rpc.subscribed_events, event_string);
-
- map_foreach_value(&channels, channel, {
- if (channel->is_rpc
- && pmap_has(cstr_t)(channel->rpc.subscribed_events, event_string)) {
- return;
- }
- });
-
- // Since the string is no longer used by other channels, release it's memory
- pmap_del(cstr_t)(&event_strings, event_string);
- xfree(event_string);
+ set_del(cstr_t, channel->rpc.subscribed_events, event);
}
/// Mark rpc state as closed, and release its reference to the channel.
@@ -630,13 +616,7 @@ void rpc_free(Channel *channel)
unpacker_teardown(channel->rpc.unpacker);
xfree(channel->rpc.unpacker);
- // Unsubscribe from all events
- char *event_string;
- map_foreach_value(channel->rpc.subscribed_events, event_string, {
- unsubscribe(channel, event_string);
- });
-
- pmap_destroy(cstr_t)(channel->rpc.subscribed_events);
+ set_destroy(cstr_t, channel->rpc.subscribed_events);
kv_destroy(channel->rpc.call_stack);
api_free_dictionary(channel->rpc.info);
}
@@ -734,3 +714,12 @@ const char *rpc_client_name(Channel *chan)
return NULL;
}
+
+void rpc_free_all_mem(void)
+{
+ cstr_t key;
+ set_foreach(&event_strings, key, {
+ xfree((void *)key);
+ });
+ set_destroy(cstr_t, &event_strings);
+}
diff --git a/src/nvim/msgpack_rpc/channel_defs.h b/src/nvim/msgpack_rpc/channel_defs.h
index 404e68329a..1b5f0bb298 100644
--- a/src/nvim/msgpack_rpc/channel_defs.h
+++ b/src/nvim/msgpack_rpc/channel_defs.h
@@ -31,7 +31,7 @@ typedef struct {
} RequestEvent;
typedef struct {
- PMap(cstr_t) subscribed_events[1];
+ Set(cstr_t) subscribed_events[1];
bool closed;
Unpacker *unpacker;
uint32_t next_request_id;
diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c
index 34e94d6021..f7b7723553 100644
--- a/src/nvim/runtime.c
+++ b/src/nvim/runtime.c
@@ -646,21 +646,20 @@ int do_in_path_and_pp(char *path, char *name, int flags, DoInRuntimepathCB callb
return done;
}
-static void push_path(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used, char *entry,
+static void push_path(RuntimeSearchPath *search_path, Set(String) *rtp_used, char *entry,
bool after)
{
- handle_T h = map_get(String, handle_T)(rtp_used, cstr_as_string(entry));
- if (h == 0) {
- char *allocated = xstrdup(entry);
- map_put(String, handle_T)(rtp_used, cstr_as_string(allocated), 1);
- kv_push(*search_path, ((SearchPathItem){ allocated, after, kNone }));
+ String *key_alloc;
+ if (set_put_ref(String, rtp_used, cstr_as_string(entry), &key_alloc)) {
+ *key_alloc = cstr_to_string(entry);
+ kv_push(*search_path, ((SearchPathItem){ key_alloc->data, after, kNone }));
}
}
-static void expand_rtp_entry(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used,
- char *entry, bool after)
+static void expand_rtp_entry(RuntimeSearchPath *search_path, Set(String) *rtp_used, char *entry,
+ bool after)
{
- if (map_get(String, handle_T)(rtp_used, cstr_as_string(entry))) {
+ if (set_has(String, rtp_used, cstr_as_string(entry))) {
return;
}
@@ -679,7 +678,7 @@ static void expand_rtp_entry(RuntimeSearchPath *search_path, Map(String, handle_
}
}
-static void expand_pack_entry(RuntimeSearchPath *search_path, Map(String, handle_T) *rtp_used,
+static void expand_pack_entry(RuntimeSearchPath *search_path, Set(String) *rtp_used,
CharVec *after_path, char *pack_entry, size_t pack_entry_len)
{
static char buf[MAXPATHL];
@@ -712,10 +711,8 @@ static bool path_is_after(char *buf, size_t buflen)
RuntimeSearchPath runtime_search_path_build(void)
{
kvec_t(String) pack_entries = KV_INITIAL_VALUE;
- // TODO(bfredl): these should just be sets, when Set(String) is do merge to
- // master.
Map(String, handle_T) pack_used = MAP_INIT;
- Map(String, handle_T) rtp_used = MAP_INIT;
+ Set(String) rtp_used = SET_INIT;
RuntimeSearchPath search_path = KV_INITIAL_VALUE;
CharVec after_path = KV_INITIAL_VALUE;
@@ -744,7 +741,7 @@ RuntimeSearchPath runtime_search_path_build(void)
// fact: &rtp entries can contain wild chars
expand_rtp_entry(&search_path, &rtp_used, buf, false);
- handle_T *h = map_ref(String, handle_T)(&pack_used, cstr_as_string(buf), false);
+ handle_T *h = map_ref(String, handle_T)(&pack_used, cstr_as_string(buf), NULL);
if (h) {
(*h)++;
expand_pack_entry(&search_path, &rtp_used, &after_path, buf, buflen);
@@ -774,8 +771,8 @@ RuntimeSearchPath runtime_search_path_build(void)
// strings are not owned
kv_destroy(pack_entries);
kv_destroy(after_path);
- map_destroy(String, handle_T)(&pack_used);
- map_destroy(String, handle_T)(&rtp_used);
+ map_destroy(String, &pack_used);
+ set_destroy(String, &rtp_used);
return search_path;
}
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index c405b8ca5f..d3a0b12e5e 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -16,7 +16,6 @@
#include <uv.h>
#include "auto/config.h"
-#include "klib/khash.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
@@ -35,6 +34,7 @@
#include "nvim/globals.h"
#include "nvim/hashtab.h"
#include "nvim/macros.h"
+#include "nvim/map.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memory.h"
@@ -62,19 +62,6 @@
# include ENDIAN_INCLUDE_FILE
#endif
-// Note: when using bufset hash pointers are intentionally casted to uintptr_t
-// and not to khint32_t or khint64_t: this way compiler must give a warning
-// (-Wconversion) when types change.
-#ifdef ARCH_32
-KHASH_SET_INIT_INT(bufset)
-#elif defined(ARCH_64)
-KHASH_SET_INIT_INT64(bufset)
-#else
-# error Not a 64- or 32-bit architecture
-#endif
-KHASH_MAP_INIT_STR(fnamebufs, buf_T *)
-KHASH_SET_INIT_STR(strset)
-
#define SEARCH_KEY_MAGIC "sm"
#define SEARCH_KEY_SMARTCASE "sc"
#define SEARCH_KEY_HAS_LINE_OFFSET "sl"
@@ -305,8 +292,6 @@ typedef struct hm_llist_entry {
struct hm_llist_entry *prev; ///< Pointer to previous entry or NULL.
} HMLListEntry;
-KHASH_MAP_INIT_STR(hmll_entries, HMLListEntry *)
-
/// Sized linked list structure for history merger
typedef struct {
HMLListEntry *entries; ///< Pointer to the start of the allocated array of
@@ -318,9 +303,8 @@ typedef struct {
HMLListEntry *last_free_entry; ///< Last unused element in entries array.
size_t size; ///< Number of allocated entries.
size_t num_entries; ///< Number of entries already used.
- khash_t(hmll_entries) contained_entries; ///< Hash mapping all history entry
- ///< strings to corresponding entry
- ///< pointers.
+ PMap(cstr_t) contained_entries; ///< Map all history entry strings to
+ ///< corresponding entry pointers.
} HMLList;
typedef struct {
@@ -348,8 +332,6 @@ typedef struct {
Timestamp greatest_timestamp; ///< Greatest timestamp among marks.
} FileMarks;
-KHASH_MAP_INIT_STR(file_marks, FileMarks)
-
/// State structure used by shada_write
///
/// Before actually writing most of the data is read to this structure.
@@ -363,8 +345,8 @@ typedef struct {
PossiblyFreedShadaEntry search_pattern; ///< Last search pattern.
PossiblyFreedShadaEntry sub_search_pattern; ///< Last s/ search pattern.
PossiblyFreedShadaEntry replacement; ///< Last s// replacement string.
- khash_t(strset) dumped_variables; ///< Names of already dumped variables.
- khash_t(file_marks) file_marks; ///< All file marks.
+ Set(cstr_t) dumped_variables; ///< Names of already dumped variables.
+ PMap(cstr_t) file_marks; ///< All file marks.
} WriteMergerState;
struct sd_read_def;
@@ -504,7 +486,7 @@ static inline void hmll_init(HMLList *const hmll, const size_t size)
.free_entry = NULL,
.size = size,
.num_entries = 0,
- .contained_entries = KHASH_EMPTY_TABLE(hmll_entries),
+ .contained_entries = MAP_INIT,
};
hmll->last_free_entry = hmll->entries;
}
@@ -535,10 +517,10 @@ static inline void hmll_remove(HMLList *const hmll, HMLListEntry *const hmll_ent
assert(hmll->free_entry == NULL);
hmll->free_entry = hmll_entry;
}
- const khiter_t k = kh_get(hmll_entries, &hmll->contained_entries,
- hmll_entry->data.data.history_item.string);
- assert(k != kh_end(&hmll->contained_entries));
- kh_del(hmll_entries, &hmll->contained_entries, k);
+ ptr_t val = pmap_del(cstr_t)(&hmll->contained_entries,
+ hmll_entry->data.data.history_item.string, NULL);
+ assert(val);
+ (void)val;
if (hmll_entry->next == NULL) {
hmll->last = hmll_entry->prev;
} else {
@@ -586,11 +568,11 @@ static inline void hmll_insert(HMLList *const hmll, HMLListEntry *hmll_entry, co
}
target_entry->data = data;
target_entry->can_free_entry = can_free_entry;
- int kh_ret;
- const khiter_t k = kh_put(hmll_entries, &hmll->contained_entries,
- data.data.history_item.string, &kh_ret);
- if (kh_ret > 0) {
- kh_val(&hmll->contained_entries, k) = target_entry;
+ bool new_item = false;
+ ptr_t *val = pmap_put_ref(cstr_t)(&hmll->contained_entries, data.data.history_item.string,
+ NULL, &new_item);
+ if (new_item) {
+ *val = target_entry;
}
hmll->num_entries++;
target_entry->prev = hmll_entry;
@@ -614,7 +596,7 @@ static inline void hmll_insert(HMLList *const hmll, HMLListEntry *hmll_entry, co
static inline void hmll_dealloc(HMLList *const hmll)
FUNC_ATTR_NONNULL_ALL
{
- kh_dealloc(hmll_entries, &hmll->contained_entries);
+ map_destroy(cstr_t, &hmll->contained_entries);
xfree(hmll->entries);
}
@@ -771,30 +753,6 @@ static void close_file(void *cookie)
}
}
-/// Check whether buffer is in the given set
-///
-/// @param[in] set Set to check within.
-/// @param[in] buf Buffer to find.
-///
-/// @return true or false.
-static inline bool in_bufset(const khash_t(bufset) *const set, const buf_T *buf)
- FUNC_ATTR_PURE
-{
- return kh_get(bufset, set, (uintptr_t)buf) != kh_end(set);
-}
-
-/// Check whether string is in the given set
-///
-/// @param[in] set Set to check within.
-/// @param[in] buf Buffer to find.
-///
-/// @return true or false.
-static inline bool in_strset(const khash_t(strset) *const set, char *str)
- FUNC_ATTR_PURE
-{
- return kh_get(strset, set, str) != kh_end(set);
-}
-
/// Msgpack callback for writing to ShaDaWriteDef*
static int msgpack_sd_writer_write(void *data, const char *buf, size_t len)
{
@@ -930,10 +888,11 @@ static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry,
}
}
HMLList *const hmll = &hms_p->hmll;
- const khiter_t k = kh_get(hmll_entries, &hms_p->hmll.contained_entries,
- entry.data.history_item.string);
- if (k != kh_end(&hmll->contained_entries)) {
- HMLListEntry *const existing_entry = kh_val(&hmll->contained_entries, k);
+ cstr_t *key_alloc = NULL;
+ ptr_t *val = pmap_ref(cstr_t)(&hms_p->hmll.contained_entries, entry.data.history_item.string,
+ &key_alloc);
+ if (val) {
+ HMLListEntry *const existing_entry = *val;
if (entry.timestamp > existing_entry->data.timestamp) {
hmll_remove(hmll, existing_entry);
} else if (!do_iter && entry.timestamp == existing_entry->data.timestamp) {
@@ -944,7 +903,7 @@ static void hms_insert(HistoryMergerState *const hms_p, const ShadaEntry entry,
existing_entry->data = entry;
existing_entry->can_free_entry = can_free_entry;
// Previous key was freed above, as part of freeing the ShaDa entry.
- kh_key(&hmll->contained_entries, k) = entry.data.history_item.string;
+ *key_alloc = entry.data.history_item.string;
return;
} else {
return;
@@ -1046,24 +1005,27 @@ static inline void hms_dealloc(HistoryMergerState *const hms_p)
/// @param[in] fname File name to find.
///
/// @return Pointer to the buffer or NULL.
-static buf_T *find_buffer(khash_t(fnamebufs) *const fname_bufs, const char *const fname)
+static buf_T *find_buffer(PMap(cstr_t) *const fname_bufs, const char *const fname)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- int kh_ret;
- khint_t k = kh_put(fnamebufs, fname_bufs, fname, &kh_ret);
- if (!kh_ret) {
- return kh_val(fname_bufs, k);
+ cstr_t *key_alloc = NULL;
+ bool new_item = false;
+ buf_T **ref = (buf_T **)pmap_put_ref(cstr_t)(fname_bufs, fname, &key_alloc, &new_item);
+ if (new_item) {
+ *key_alloc = xstrdup(fname);
+ } else {
+ return *ref; // item already existed (can be a NULL value)
}
- kh_key(fname_bufs, k) = xstrdup(fname);
+
FOR_ALL_BUFFERS(buf) {
if (buf->b_ffname != NULL) {
if (path_fnamecmp(fname, buf->b_ffname) == 0) {
- kh_val(fname_bufs, k) = buf;
+ *ref = buf;
return buf;
}
}
}
- kh_val(fname_bufs, k) = NULL;
+ *ref = NULL;
return NULL;
}
@@ -1163,9 +1125,9 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
}
}
ShadaEntry cur_entry;
- khash_t(bufset) cl_bufs = KHASH_EMPTY_TABLE(bufset);
- khash_t(fnamebufs) fname_bufs = KHASH_EMPTY_TABLE(fnamebufs);
- khash_t(strset) oldfiles_set = KHASH_EMPTY_TABLE(strset);
+ Set(ptr_t) cl_bufs = SET_INIT;
+ PMap(cstr_t) fname_bufs = MAP_INIT;
+ Set(cstr_t) oldfiles_set = SET_INIT;
if (get_old_files && (oldfiles_list == NULL || force)) {
oldfiles_list = tv_list_alloc(kListLenUnknown);
set_vim_var_list(VV_OLDFILES, oldfiles_list);
@@ -1359,8 +1321,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
break;
case kSDItemChange:
case kSDItemLocalMark: {
- if (get_old_files && !in_strset(&oldfiles_set,
- cur_entry.data.filemark.fname)) {
+ if (get_old_files && !set_has(cstr_t, &oldfiles_set, cur_entry.data.filemark.fname)) {
char *fname = cur_entry.data.filemark.fname;
if (want_marks) {
// Do not bother with allocating memory for the string if already
@@ -1368,8 +1329,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
// want_marks is set because this way it may be used for a mark.
fname = xstrdup(fname);
}
- int kh_ret;
- (void)kh_put(strset, &oldfiles_set, fname, &kh_ret);
+ set_put(cstr_t, &oldfiles_set, fname);
tv_list_append_allocated_string(oldfiles_list, fname);
if (!want_marks) {
// Avoid free because this string was already used.
@@ -1398,8 +1358,7 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
break;
}
} else {
- int kh_ret;
- (void)kh_put(bufset, &cl_bufs, (uintptr_t)buf, &kh_ret);
+ set_put(ptr_t, &cl_bufs, buf);
#define SDE_TO_FMARK(entry) fm
#define AFTERFREE(entry) (entry).data.filemark.fname = NULL
#define DUMMY_IDX_ADJ(i)
@@ -1440,18 +1399,18 @@ shada_read_main_cycle_end:
if (cl_bufs.n_occupied) {
FOR_ALL_TAB_WINDOWS(tp, wp) {
(void)tp;
- if (in_bufset(&cl_bufs, wp->w_buffer)) {
+ if (set_has(ptr_t, &cl_bufs, wp->w_buffer)) {
wp->w_changelistidx = wp->w_buffer->b_changelistlen;
}
}
}
- kh_dealloc(bufset, &cl_bufs);
+ set_destroy(ptr_t, &cl_bufs);
const char *key;
- kh_foreach_key(&fname_bufs, key, {
- xfree((void *)key);
+ map_foreach_key(&fname_bufs, key, {
+ xfree((char *)key);
})
- kh_dealloc(fnamebufs, &fname_bufs);
- kh_dealloc(strset, &oldfiles_set);
+ map_destroy(cstr_t, &fname_bufs);
+ set_destroy(cstr_t, &oldfiles_set);
}
/// Default shada file location: cached path
@@ -2154,7 +2113,7 @@ static inline ShaDaWriteResult shada_read_when_writing(ShaDaReadDef *const sd_re
break;
}
case kSDItemVariable:
- if (!in_strset(&wms->dumped_variables, entry.data.global_var.name)) {
+ if (!set_has(cstr_t, &wms->dumped_variables, entry.data.global_var.name)) {
ret = shada_pack_entry(packer, entry, 0);
}
shada_free_shada_entry(&entry);
@@ -2211,13 +2170,12 @@ static inline ShaDaWriteResult shada_read_when_writing(ShaDaReadDef *const sd_re
break;
}
const char *const fname = entry.data.filemark.fname;
- khiter_t k;
- int kh_ret;
- k = kh_put(file_marks, &wms->file_marks, fname, &kh_ret);
- FileMarks *const filemarks = &kh_val(&wms->file_marks, k);
- if (kh_ret > 0) {
- CLEAR_POINTER(filemarks);
+ cstr_t *key = NULL;
+ ptr_t *val = pmap_put_ref(cstr_t)(&wms->file_marks, fname, &key, NULL);
+ if (*val == NULL) {
+ *val = xcalloc(1, sizeof(FileMarks));
}
+ FileMarks *const filemarks = *val;
if (entry.timestamp > filemarks->greatest_timestamp) {
filemarks->greatest_timestamp = entry.timestamp;
}
@@ -2237,9 +2195,8 @@ static inline ShaDaWriteResult shada_read_when_writing(ShaDaReadDef *const sd_re
break;
}
if (wms_entry->can_free_entry) {
- if (kh_key(&wms->file_marks, k)
- == wms_entry->data.data.filemark.fname) {
- kh_key(&wms->file_marks, k) = entry.data.filemark.fname;
+ if (*key == wms_entry->data.data.filemark.fname) {
+ *key = entry.data.filemark.fname;
}
shada_free_shada_entry(&wms_entry->data);
}
@@ -2281,11 +2238,11 @@ static inline ShaDaWriteResult shada_read_when_writing(ShaDaReadDef *const sd_re
/// @param[in] removable_bufs Cache of buffers ignored due to their location.
///
/// @return true or false.
-static inline bool ignore_buf(const buf_T *const buf, khash_t(bufset) *const removable_bufs)
+static inline bool ignore_buf(const buf_T *const buf, Set(ptr_t) *const removable_bufs)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
{
return (buf->b_ffname == NULL || !buf->b_p_bl || bt_quickfix(buf) \
- || bt_terminal(buf) || in_bufset(removable_bufs, buf));
+ || bt_terminal(buf) || set_has(ptr_t, removable_bufs, (ptr_t)buf));
}
/// Get list of buffers to write to the shada file
@@ -2293,7 +2250,7 @@ static inline bool ignore_buf(const buf_T *const buf, khash_t(bufset) *const rem
/// @param[in] removable_bufs Buffers which are ignored
///
/// @return ShadaEntry List of buffers to save, kSDItemBufferList entry.
-static inline ShadaEntry shada_get_buflist(khash_t(bufset) *const removable_bufs)
+static inline ShadaEntry shada_get_buflist(Set(ptr_t) *const removable_bufs)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALWAYS_INLINE
{
int max_bufs = get_shada_parameter('%');
@@ -2461,12 +2418,11 @@ static inline void replace_numbered_mark(WriteMergerState *const wms, const size
/// Find buffers ignored due to their location.
///
/// @param[out] removable_bufs Cache of buffers ignored due to their location.
-static inline void find_removable_bufs(khash_t(bufset) *removable_bufs)
+static inline void find_removable_bufs(Set(ptr_t) *removable_bufs)
{
FOR_ALL_BUFFERS(buf) {
if (buf->b_ffname != NULL && shada_removable(buf->b_ffname)) {
- int kh_ret;
- (void)kh_put(bufset, removable_bufs, (uintptr_t)buf, &kh_ret);
+ set_put(ptr_t, removable_bufs, (ptr_t)buf);
}
}
}
@@ -2518,7 +2474,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef
max_reg_lines = get_shada_parameter('"');
}
const bool dump_registers = (max_reg_lines != 0);
- khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset);
+ Set(ptr_t) removable_bufs = SET_INIT;
const size_t max_kbyte = (size_t)max_kbyte_i;
const size_t num_marked_files = (size_t)get_shada_parameter('\'');
const bool dump_global_marks = get_shada_parameter('f') != 0;
@@ -2662,8 +2618,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef
tv_clear(&vartv);
tv_clear(&tgttv);
if (spe_ret == kSDWriteSuccessful) {
- int kh_ret;
- (void)kh_put(strset, &wms->dumped_variables, name, &kh_ret);
+ set_put(cstr_t, &wms->dumped_variables, name);
}
} while (var_iter != NULL);
}
@@ -2723,7 +2678,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef
} else {
const buf_T *const buf = buflist_findnr(fm.fmark.fnum);
if (buf == NULL || buf->b_ffname == NULL
- || in_bufset(&removable_bufs, buf)) {
+ || set_has(ptr_t, &removable_bufs, (ptr_t)buf)) {
continue;
}
fname = buf->b_ffname;
@@ -2759,18 +2714,16 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef
// Initialize buffers
if (num_marked_files > 0) {
FOR_ALL_BUFFERS(buf) {
- if (buf->b_ffname == NULL || in_bufset(&removable_bufs, buf)) {
+ if (buf->b_ffname == NULL || set_has(ptr_t, &removable_bufs, buf)) {
continue;
}
const void *local_marks_iter = NULL;
const char *const fname = buf->b_ffname;
- khiter_t k;
- int kh_ret;
- k = kh_put(file_marks, &wms->file_marks, fname, &kh_ret);
- FileMarks *const filemarks = &kh_val(&wms->file_marks, k);
- if (kh_ret > 0) {
- CLEAR_POINTER(filemarks);
+ ptr_t *val = pmap_put_ref(cstr_t)(&wms->file_marks, fname, NULL, NULL);
+ if (*val == NULL) {
+ *val = xcalloc(1, sizeof(FileMarks));
}
+ FileMarks *const filemarks = *val;
do {
fmark_T fm;
char name = NUL;
@@ -2887,16 +2840,14 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, ShaDaReadDef
PACK_WMS_ENTRY(wms->replacement);
#undef PACK_WMS_ENTRY
- const size_t file_markss_size = kh_size(&wms->file_marks);
+ const size_t file_markss_size = map_size(&wms->file_marks);
FileMarks **const all_file_markss =
xmalloc(file_markss_size * sizeof(*all_file_markss));
FileMarks **cur_file_marks = all_file_markss;
- for (khint_t i = kh_begin(&wms->file_marks); i != kh_end(&wms->file_marks);
- i++) {
- if (kh_exist(&wms->file_marks, i)) {
- *cur_file_marks++ = &kh_val(&wms->file_marks, i);
- }
- }
+ ptr_t val;
+ map_foreach_value(ptr_t, &wms->file_marks, val, {
+ *cur_file_marks++ = val;
+ })
qsort((void *)all_file_markss, file_markss_size, sizeof(*all_file_markss),
&compare_file_marks);
const size_t file_markss_to_dump = MIN(num_marked_files, file_markss_size);
@@ -2949,10 +2900,13 @@ shada_write_exit:
hms_dealloc(&wms->hms[i]);
}
}
- kh_dealloc(file_marks, &wms->file_marks);
- kh_dealloc(bufset, &removable_bufs);
+ map_foreach_value(ptr_t, &wms->file_marks, val, {
+ xfree(val);
+ })
+ map_destroy(cstr_t, &wms->file_marks);
+ set_destroy(ptr_t, &removable_bufs);
msgpack_packer_free(packer);
- kh_dealloc(strset, &wms->dumped_variables);
+ set_destroy(cstr_t, &wms->dumped_variables);
xfree(wms);
return ret;
}
@@ -4035,7 +3989,7 @@ static bool shada_removable(const char *name)
///
/// @return number of jumplist entries
static inline size_t shada_init_jumps(PossiblyFreedShadaEntry *jumps,
- khash_t(bufset) *const removable_bufs)
+ Set(ptr_t) *const removable_bufs)
{
// Initialize jump list
size_t jumps_size = 0;
@@ -4056,7 +4010,7 @@ static inline size_t shada_init_jumps(PossiblyFreedShadaEntry *jumps,
? NULL
: buflist_findnr(fm.fmark.fnum));
if (buf != NULL
- ? in_bufset(removable_bufs, buf)
+ ? set_has(ptr_t, removable_bufs, (ptr_t)buf)
: fm.fmark.fnum != 0) {
continue;
}
@@ -4111,7 +4065,7 @@ void shada_encode_regs(msgpack_sbuffer *const sbuf)
void shada_encode_jumps(msgpack_sbuffer *const sbuf)
FUNC_ATTR_NONNULL_ALL
{
- khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset);
+ Set(ptr_t) removable_bufs = SET_INIT;
find_removable_bufs(&removable_bufs);
PossiblyFreedShadaEntry jumps[JUMPLISTSIZE];
size_t jumps_size = shada_init_jumps(jumps, &removable_bufs);
@@ -4130,7 +4084,7 @@ void shada_encode_jumps(msgpack_sbuffer *const sbuf)
void shada_encode_buflist(msgpack_sbuffer *const sbuf)
FUNC_ATTR_NONNULL_ALL
{
- khash_t(bufset) removable_bufs = KHASH_EMPTY_TABLE(bufset);
+ Set(ptr_t) removable_bufs = SET_INIT;
find_removable_bufs(&removable_bufs);
ShadaEntry buflist_entry = shada_get_buflist(&removable_bufs);
msgpack_packer packer;
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 0b0e321d8c..62a2d1b6e6 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -169,7 +169,7 @@ static VTermScreenCallbacks vterm_screen_callbacks = {
.sb_popline = term_sb_pop,
};
-static PMap(ptr_t) invalidated_terminals = MAP_INIT;
+static Set(ptr_t) invalidated_terminals = SET_INIT;
void terminal_init(void)
{
@@ -183,10 +183,10 @@ void terminal_teardown(void)
time_watcher_stop(&refresh_timer);
multiqueue_free(refresh_timer.events);
time_watcher_close(&refresh_timer, NULL);
- pmap_destroy(ptr_t)(&invalidated_terminals);
+ set_destroy(ptr_t, &invalidated_terminals);
// terminal_destroy might be called after terminal_teardown is invoked
// make sure it is in an empty, valid state
- pmap_init(ptr_t, &invalidated_terminals);
+ invalidated_terminals = (Set(ptr_t)) SET_INIT;
}
static void term_output_callback(const char *s, size_t len, void *user_data)
@@ -652,12 +652,12 @@ void terminal_destroy(Terminal **termpp)
}
if (!term->refcount) {
- if (pmap_has(ptr_t)(&invalidated_terminals, term)) {
+ if (set_has(ptr_t, &invalidated_terminals, term)) {
// flush any pending changes to the buffer
block_autocmds();
refresh_terminal(term);
unblock_autocmds();
- pmap_del(ptr_t)(&invalidated_terminals, term);
+ set_del(ptr_t, &invalidated_terminals, term);
}
for (size_t i = 0; i < term->sb_current; i++) {
xfree(term->sb_buffer[i]);
@@ -1027,7 +1027,7 @@ static int term_sb_push(int cols, const VTermScreenCell *cells, void *data)
}
memcpy(sbrow->cells, cells, sizeof(cells[0]) * c);
- pmap_put(ptr_t)(&invalidated_terminals, term, NULL);
+ set_put(ptr_t, &invalidated_terminals, term);
return 1;
}
@@ -1068,7 +1068,7 @@ static int term_sb_pop(int cols, VTermScreenCell *cells, void *data)
}
xfree(sbrow);
- pmap_put(ptr_t)(&invalidated_terminals, term, NULL);
+ set_put(ptr_t, &invalidated_terminals, term);
return 1;
}
@@ -1524,7 +1524,7 @@ static void invalidate_terminal(Terminal *term, int start_row, int end_row)
term->invalid_end = MAX(term->invalid_end, end_row);
}
- pmap_put(ptr_t)(&invalidated_terminals, term, NULL);
+ set_put(ptr_t, &invalidated_terminals, term);
if (!refresh_pending) {
time_watcher_start(&refresh_timer, refresh_timer_cb, REFRESH_DELAY, 0);
refresh_pending = true;
@@ -1567,10 +1567,10 @@ static void refresh_timer_cb(TimeWatcher *watcher, void *data)
void *stub; (void)(stub);
// don't process autocommands while updating terminal buffers
block_autocmds();
- map_foreach(&invalidated_terminals, term, stub, {
+ set_foreach(&invalidated_terminals, term, {
refresh_terminal(term);
});
- pmap_clear(ptr_t)(&invalidated_terminals);
+ set_clear(ptr_t, &invalidated_terminals);
unblock_autocmds();
}
diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c
index 73ed7b6096..81a68d5b07 100644
--- a/src/nvim/tui/input.c
+++ b/src/nvim/tui/input.c
@@ -33,7 +33,7 @@
#define KEY_BUFFER_SIZE 0xfff
static const struct kitty_key_map_entry {
- KittyKey key;
+ int key;
const char *name;
} kitty_key_map_entry[] = {
{ KITTY_KEY_ESCAPE, "Esc" },
@@ -115,7 +115,7 @@ static const struct kitty_key_map_entry {
{ KITTY_KEY_KP_BEGIN, "kOrigin" },
};
-static Map(KittyKey, cstr_t) kitty_key_map = MAP_INIT;
+static Map(int, cstr_t) kitty_key_map = MAP_INIT;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "tui/input.c.generated.h"
@@ -135,8 +135,8 @@ void tinput_init(TermInput *input, Loop *loop)
input->key_buffer = rbuffer_new(KEY_BUFFER_SIZE);
for (size_t i = 0; i < ARRAY_SIZE(kitty_key_map_entry); i++) {
- map_put(KittyKey, cstr_t)(&kitty_key_map, kitty_key_map_entry[i].key,
- kitty_key_map_entry[i].name);
+ map_put(int, cstr_t)(&kitty_key_map, kitty_key_map_entry[i].key,
+ kitty_key_map_entry[i].name);
}
input->in_fd = STDIN_FILENO;
@@ -162,7 +162,7 @@ void tinput_init(TermInput *input, Loop *loop)
void tinput_destroy(TermInput *input)
{
- map_destroy(KittyKey, cstr_t)(&kitty_key_map);
+ map_destroy(int, &kitty_key_map);
rbuffer_free(input->key_buffer);
time_watcher_close(&input->timer_handle, NULL);
stream_close(&input->read_stream, NULL, NULL);
@@ -231,7 +231,7 @@ static void tinput_enqueue(TermInput *input, char *buf, size_t size)
static void handle_kitty_key_protocol(TermInput *input, TermKeyKey *key)
{
- const char *name = map_get(KittyKey, cstr_t)(&kitty_key_map, (KittyKey)key->code.codepoint);
+ const char *name = map_get(int, cstr_t)(&kitty_key_map, (int)key->code.codepoint);
if (name) {
char buf[64];
size_t len = 0;
@@ -257,7 +257,7 @@ static void forward_simple_utf8(TermInput *input, TermKeyKey *key)
char *ptr = key->utf8;
if (key->code.codepoint >= 0xE000 && key->code.codepoint <= 0xF8FF
- && map_has(KittyKey, cstr_t)(&kitty_key_map, (KittyKey)key->code.codepoint)) {
+ && map_has(int, cstr_t)(&kitty_key_map, (int)key->code.codepoint)) {
handle_kitty_key_protocol(input, key);
return;
}
@@ -286,8 +286,7 @@ static void forward_modified_utf8(TermInput *input, TermKeyKey *key)
} else {
assert(key->modifiers);
if (key->code.codepoint >= 0xE000 && key->code.codepoint <= 0xF8FF
- && map_has(KittyKey, cstr_t)(&kitty_key_map,
- (KittyKey)key->code.codepoint)) {
+ && map_has(int, cstr_t)(&kitty_key_map, (int)key->code.codepoint)) {
handle_kitty_key_protocol(input, key);
return;
}
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 6d09b9f3a3..24f20af2f3 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -127,10 +127,10 @@ void ui_free_all_mem(void)
kv_destroy(call_buf);
UIEventCallback *event_cb;
- map_foreach_value(&ui_event_cbs, event_cb, {
+ pmap_foreach_value(&ui_event_cbs, event_cb, {
free_ui_event_callback(event_cb);
})
- pmap_destroy(uint32_t)(&ui_event_cbs);
+ map_destroy(uint32_t, &ui_event_cbs);
}
#endif
@@ -660,7 +660,7 @@ void ui_call_event(char *name, Array args)
{
UIEventCallback *event_cb;
bool handled = false;
- map_foreach_value(&ui_event_cbs, event_cb, {
+ pmap_foreach_value(&ui_event_cbs, event_cb, {
Error err = ERROR_INIT;
Object res = nlua_call_ref(event_cb->cb, name, args, false, &err);
if (res.type == kObjectTypeBoolean && res.data.boolean == true) {
@@ -686,7 +686,7 @@ void ui_cb_update_ext(void)
for (size_t i = 0; i < kUIGlobalCount; i++) {
UIEventCallback *event_cb;
- map_foreach_value(&ui_event_cbs, event_cb, {
+ pmap_foreach_value(&ui_event_cbs, event_cb, {
if (event_cb->ext_widgets[i]) {
ui_cb_ext[i] = true;
break;
@@ -710,9 +710,9 @@ void ui_add_cb(uint32_t ns_id, LuaRef cb, bool *ext_widgets)
event_cb->ext_widgets[kUICmdline] = true;
}
- UIEventCallback **item = (UIEventCallback **)pmap_ref(uint32_t)(&ui_event_cbs, ns_id, true);
+ ptr_t *item = pmap_put_ref(uint32_t)(&ui_event_cbs, ns_id, NULL, NULL);
if (*item) {
- free_ui_event_callback(*item);
+ free_ui_event_callback((UIEventCallback *)(*item));
}
*item = event_cb;
@@ -723,8 +723,8 @@ void ui_add_cb(uint32_t ns_id, LuaRef cb, bool *ext_widgets)
void ui_remove_cb(uint32_t ns_id)
{
if (pmap_has(uint32_t)(&ui_event_cbs, ns_id)) {
- free_ui_event_callback(pmap_get(uint32_t)(&ui_event_cbs, ns_id));
- pmap_del(uint32_t)(&ui_event_cbs, ns_id);
+ UIEventCallback *item = pmap_del(uint32_t)(&ui_event_cbs, ns_id, NULL);
+ free_ui_event_callback(item);
}
ui_cb_update_ext();
ui_refresh();
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 4f6b5f81a4..90c8ba92f9 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -4077,7 +4077,7 @@ static tabpage_T *alloc_tabpage(void)
static int last_tp_handle = 0;
tabpage_T *tp = xcalloc(1, sizeof(tabpage_T));
tp->handle = ++last_tp_handle;
- pmap_put(handle_T)(&tabpage_handles, tp->handle, tp);
+ pmap_put(int)(&tabpage_handles, tp->handle, tp);
// Init t: variables.
tp->tp_vars = tv_dict_alloc();
@@ -4090,7 +4090,7 @@ static tabpage_T *alloc_tabpage(void)
void free_tabpage(tabpage_T *tp)
{
- pmap_del(handle_T)(&tabpage_handles, tp->handle);
+ pmap_del(int)(&tabpage_handles, tp->handle, NULL);
diff_clear(tp);
for (int idx = 0; idx < SNAP_COUNT; idx++) {
clear_snapshot(tp, idx);
@@ -5062,7 +5062,7 @@ static win_T *win_alloc(win_T *after, bool hidden)
win_T *new_wp = xcalloc(1, sizeof(win_T));
new_wp->handle = ++last_win_id;
- pmap_put(handle_T)(&window_handles, new_wp->handle, new_wp);
+ pmap_put(int)(&window_handles, new_wp->handle, new_wp);
grid_assign_handle(&new_wp->w_grid_alloc);
@@ -5124,7 +5124,7 @@ void free_wininfo(wininfo_T *wip, buf_T *bp)
/// @param tp tab page "win" is in, NULL for current
static void win_free(win_T *wp, tabpage_T *tp)
{
- pmap_del(handle_T)(&window_handles, wp->handle);
+ pmap_del(int)(&window_handles, wp->handle, NULL);
clearFolding(wp);
// reduce the reference count to the argument list.