mirror of
https://github.com/neovim/neovim.git
synced 2025-10-01 15:38:33 +00:00
Improve map module: Refactor vim_to_object_rec
Now the map.c module is used to implement the 'lookup set' for that function
This commit is contained in:
@@ -9,27 +9,18 @@
|
|||||||
#include "nvim/window.h"
|
#include "nvim/window.h"
|
||||||
#include "nvim/memory.h"
|
#include "nvim/memory.h"
|
||||||
#include "nvim/eval.h"
|
#include "nvim/eval.h"
|
||||||
|
#include "nvim/map_defs.h"
|
||||||
|
#include "nvim/map.h"
|
||||||
#include "nvim/option.h"
|
#include "nvim/option.h"
|
||||||
#include "nvim/option_defs.h"
|
#include "nvim/option_defs.h"
|
||||||
|
|
||||||
#include "nvim/lib/khash.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(ARCH_64)
|
|
||||||
#define ptr_hash_func(key) kh_int64_hash_func(key)
|
|
||||||
#elif defined(ARCH_32)
|
|
||||||
#define ptr_hash_func(key) kh_int_hash_func(key)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
KHASH_INIT(Lookup, uintptr_t, char, 0, ptr_hash_func, kh_int_hash_equal)
|
|
||||||
|
|
||||||
/// Recursion helper for the `vim_to_object`. This uses a pointer table
|
/// Recursion helper for the `vim_to_object`. This uses a pointer table
|
||||||
/// to avoid infinite recursion due to cyclic references
|
/// to avoid infinite recursion due to cyclic references
|
||||||
///
|
///
|
||||||
/// @param obj The source object
|
/// @param obj The source object
|
||||||
/// @param lookup Lookup table containing pointers to all processed objects
|
/// @param lookup Lookup table containing pointers to all processed objects
|
||||||
/// @return The converted value
|
/// @return The converted value
|
||||||
static Object vim_to_object_rec(typval_T *obj, khash_t(Lookup) *lookup);
|
static Object vim_to_object_rec(typval_T *obj, Map(ptr_t) *lookup);
|
||||||
|
|
||||||
static bool object_to_vim(Object obj, typval_T *tv, Error *err);
|
static bool object_to_vim(Object obj, typval_T *tv, Error *err);
|
||||||
|
|
||||||
@@ -285,10 +276,10 @@ Object vim_to_object(typval_T *obj)
|
|||||||
{
|
{
|
||||||
Object rv;
|
Object rv;
|
||||||
// We use a lookup table to break out of cyclic references
|
// We use a lookup table to break out of cyclic references
|
||||||
khash_t(Lookup) *lookup = kh_init(Lookup);
|
Map(ptr_t) *lookup = map_new(ptr_t)();
|
||||||
rv = vim_to_object_rec(obj, lookup);
|
rv = vim_to_object_rec(obj, lookup);
|
||||||
// Free the table
|
// Free the table
|
||||||
kh_destroy(Lookup, lookup);
|
map_free(ptr_t)(lookup);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,19 +434,18 @@ static bool object_to_vim(Object obj, typval_T *tv, Error *err)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object vim_to_object_rec(typval_T *obj, khash_t(Lookup) *lookup)
|
static Object vim_to_object_rec(typval_T *obj, Map(ptr_t) *lookup)
|
||||||
{
|
{
|
||||||
Object rv = {.type = kObjectTypeNil};
|
Object rv = {.type = kObjectTypeNil};
|
||||||
|
|
||||||
if (obj->v_type == VAR_LIST || obj->v_type == VAR_DICT) {
|
if (obj->v_type == VAR_LIST || obj->v_type == VAR_DICT) {
|
||||||
int ret;
|
|
||||||
// Container object, add it to the lookup table
|
// Container object, add it to the lookup table
|
||||||
kh_put(Lookup, lookup, (uintptr_t)obj, &ret);
|
if (map_has(ptr_t)(lookup, obj)) {
|
||||||
if (!ret) {
|
|
||||||
// It's already present, meaning we alredy processed it so just return
|
// It's already present, meaning we alredy processed it so just return
|
||||||
// nil instead.
|
// nil instead.
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
map_put(ptr_t)(lookup, obj, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (obj->v_type) {
|
switch (obj->v_type) {
|
||||||
|
@@ -15,6 +15,15 @@
|
|||||||
#define uint32_t_hash kh_int_hash_func
|
#define uint32_t_hash kh_int_hash_func
|
||||||
#define uint32_t_eq kh_int_hash_equal
|
#define uint32_t_eq kh_int_hash_equal
|
||||||
|
|
||||||
|
#if defined(ARCH_64)
|
||||||
|
#define ptr_t_hash(key) uint64_t_hash((uint64_t)key)
|
||||||
|
#define ptr_t_eq(a, b) uint64_t_eq((uint64_t)a, (uint64_t)b)
|
||||||
|
#elif defined(ARCH_32)
|
||||||
|
#define ptr_t_hash(key) uint32_t_hash((uint32_t)key)
|
||||||
|
#define ptr_t_eq(a, b) uint32_t_eq((uint32_t)a, (uint32_t)b)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define MAP_IMPL(T) \
|
#define MAP_IMPL(T) \
|
||||||
__KHASH_IMPL(T##_map,, T, void *, 1, T##_hash, T##_eq) \
|
__KHASH_IMPL(T##_map,, T, void *, 1, T##_hash, T##_eq) \
|
||||||
\
|
\
|
||||||
@@ -27,7 +36,6 @@
|
|||||||
\
|
\
|
||||||
void map_##T##_free(Map(T) *map) \
|
void map_##T##_free(Map(T) *map) \
|
||||||
{ \
|
{ \
|
||||||
kh_clear(T##_map, map->table); \
|
|
||||||
kh_destroy(T##_map, map->table); \
|
kh_destroy(T##_map, map->table); \
|
||||||
free(map); \
|
free(map); \
|
||||||
} \
|
} \
|
||||||
@@ -56,11 +64,9 @@
|
|||||||
\
|
\
|
||||||
if (!ret) { \
|
if (!ret) { \
|
||||||
rv = kh_val(map->table, k); \
|
rv = kh_val(map->table, k); \
|
||||||
kh_del(T##_map, map->table, k); \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
kh_val(map->table, k) = value; \
|
kh_val(map->table, k) = value; \
|
||||||
\
|
|
||||||
return rv; \
|
return rv; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@@ -78,3 +84,4 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
MAP_IMPL(cstr_t)
|
MAP_IMPL(cstr_t)
|
||||||
|
MAP_IMPL(ptr_t)
|
||||||
|
@@ -16,10 +16,11 @@
|
|||||||
void map_##T##_free(Map(T) *map); \
|
void map_##T##_free(Map(T) *map); \
|
||||||
void *map_##T##_get(Map(T) *map, T key); \
|
void *map_##T##_get(Map(T) *map, T key); \
|
||||||
bool map_##T##_has(Map(T) *map, T key); \
|
bool map_##T##_has(Map(T) *map, T key); \
|
||||||
void *map_##T##_put(Map(T) *map, T key, void *value); \
|
void* map_##T##_put(Map(T) *map, T key, void *value); \
|
||||||
void *map_##T##_del(Map(T) *map, T key);
|
void* map_##T##_del(Map(T) *map, T key);
|
||||||
|
|
||||||
MAP_DECLS(cstr_t)
|
MAP_DECLS(cstr_t)
|
||||||
|
MAP_DECLS(ptr_t)
|
||||||
|
|
||||||
#define map_new(T) map_##T##_new
|
#define map_new(T) map_##T##_new
|
||||||
#define map_free(T) map_##T##_free
|
#define map_free(T) map_##T##_free
|
||||||
|
@@ -5,6 +5,7 @@
|
|||||||
#include "nvim/lib/khash.h"
|
#include "nvim/lib/khash.h"
|
||||||
|
|
||||||
typedef const char * cstr_t;
|
typedef const char * cstr_t;
|
||||||
|
typedef void * ptr_t;
|
||||||
|
|
||||||
#define Map(T) Map_##T
|
#define Map(T) Map_##T
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user