aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThiago de Arruda <tpadilha84@gmail.com>2014-05-19 11:01:55 -0300
committerThiago de Arruda <tpadilha84@gmail.com>2014-05-19 11:01:55 -0300
commit080f5dbd95942dcef47c61349ce69fb42cbafc2a (patch)
treecb702efff9dc967bb4d946fbe8e0b46d16d524ad /src
parent93f9023b46c1c33c59e978acd305dfd015bc0df3 (diff)
parent25595d97d5c1038dd3789e85194a81ee7e4fdbd2 (diff)
downloadrneovim-080f5dbd95942dcef47c61349ce69fb42cbafc2a.tar.gz
rneovim-080f5dbd95942dcef47c61349ce69fb42cbafc2a.tar.bz2
rneovim-080f5dbd95942dcef47c61349ce69fb42cbafc2a.zip
Merge pull request #732 from tarruda/map-improvements
Diffstat (limited to 'src')
-rw-r--r--src/nvim/CMakeLists.txt1
-rw-r--r--src/nvim/api/helpers.c26
-rw-r--r--src/nvim/map.c154
-rw-r--r--src/nvim/map.h80
-rw-r--r--src/nvim/map_defs.h16
-rw-r--r--src/nvim/os/server.c34
6 files changed, 138 insertions, 173 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 221019ebe4..d9ec65af86 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -48,6 +48,7 @@ set(CONV_SRCS
arabic.c
garray.c
memory.c
+ map.c
os/env.c
os/event.c
os/job.c
diff --git a/src/nvim/api/helpers.c b/src/nvim/api/helpers.c
index 3256abeeee..a193c8721e 100644
--- a/src/nvim/api/helpers.c
+++ b/src/nvim/api/helpers.c
@@ -9,27 +9,18 @@
#include "nvim/window.h"
#include "nvim/memory.h"
#include "nvim/eval.h"
+#include "nvim/map_defs.h"
+#include "nvim/map.h"
#include "nvim/option.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
/// to avoid infinite recursion due to cyclic references
///
/// @param obj The source object
/// @param lookup Lookup table containing pointers to all processed objects
/// @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);
@@ -285,10 +276,10 @@ Object vim_to_object(typval_T *obj)
{
Object rv;
// 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);
// Free the table
- kh_destroy(Lookup, lookup);
+ map_free(ptr_t)(lookup);
return rv;
}
@@ -443,19 +434,18 @@ static bool object_to_vim(Object obj, typval_T *tv, Error *err)
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};
if (obj->v_type == VAR_LIST || obj->v_type == VAR_DICT) {
- int ret;
// Container object, add it to the lookup table
- kh_put(Lookup, lookup, (uintptr_t)obj, &ret);
- if (!ret) {
+ if (map_has(ptr_t)(lookup, obj)) {
// It's already present, meaning we alredy processed it so just return
// nil instead.
return rv;
}
+ map_put(ptr_t)(lookup, obj, NULL);
}
switch (obj->v_type) {
diff --git a/src/nvim/map.c b/src/nvim/map.c
index 40868e5b92..28fd0af61c 100644
--- a/src/nvim/map.c
+++ b/src/nvim/map.c
@@ -8,84 +8,80 @@
#include "nvim/lib/khash.h"
-typedef struct {
- void *ptr;
-} Value;
-
-KHASH_MAP_INIT_STR(Map, Value)
-
-struct map {
- khash_t(Map) *table;
-};
-
-Map *map_new()
-{
- Map *rv = xmalloc(sizeof(Map));
- rv->table = kh_init(Map);
- return rv;
-}
-
-void map_free(Map *map)
-{
- kh_clear(Map, map->table);
- kh_destroy(Map, map->table);
- free(map);
-}
-
-void *map_get(Map *map, const char *key)
-{
- khiter_t k;
-
- if ((k = kh_get(Map, map->table, key)) == kh_end(map->table)) {
- return NULL;
+#define cstr_t_hash kh_str_hash_func
+#define cstr_t_eq kh_str_hash_equal
+#define uint64_t_hash kh_int64_hash_func
+#define uint64_t_eq kh_int64_hash_equal
+#define uint32_t_hash kh_int_hash_func
+#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) \
+ __KHASH_IMPL(T##_map,, T, void *, 1, T##_hash, T##_eq) \
+ \
+ Map(T) *map_##T##_new() \
+ { \
+ Map(T) *rv = xmalloc(sizeof(Map(T))); \
+ rv->table = kh_init(T##_map); \
+ return rv; \
+ } \
+ \
+ void map_##T##_free(Map(T) *map) \
+ { \
+ kh_destroy(T##_map, map->table); \
+ free(map); \
+ } \
+ \
+ void *map_##T##_get(Map(T) *map, T key) \
+ { \
+ khiter_t k; \
+ \
+ if ((k = kh_get(T##_map, map->table, key)) == kh_end(map->table)) { \
+ return NULL; \
+ } \
+ \
+ return kh_val(map->table, k); \
+ } \
+ \
+ bool map_##T##_has(Map(T) *map, T key) \
+ { \
+ return kh_get(T##_map, map->table, key) != kh_end(map->table); \
+ } \
+ \
+ void *map_##T##_put(Map(T) *map, T key, void *value) \
+ { \
+ int ret; \
+ void *rv = NULL; \
+ khiter_t k = kh_put(T##_map, map->table, key, &ret); \
+ \
+ if (!ret) { \
+ rv = kh_val(map->table, k); \
+ } \
+ \
+ kh_val(map->table, k) = value; \
+ return rv; \
+ } \
+ \
+ void *map_##T##_del(Map(T) *map, T key) \
+ { \
+ void *rv = NULL; \
+ khiter_t k; \
+ \
+ if ((k = kh_get(T##_map, map->table, key)) != kh_end(map->table)) { \
+ rv = kh_val(map->table, k); \
+ kh_del(T##_map, map->table, k); \
+ } \
+ \
+ return rv; \
}
- return kh_val(map->table, k).ptr;
-}
-
-bool map_has(Map *map, const char *key)
-{
- return map_get(map, key) != NULL;
-}
-
-void *map_put(Map *map, const char *key, void *value)
-{
- int ret;
- void *rv = NULL;
- khiter_t k = kh_put(Map, map->table, key, &ret);
- Value val = {.ptr = value};
-
- if (!ret) {
- // key present, return the current value
- rv = kh_val(map->table, k).ptr;
- kh_del(Map, map->table, k);
- }
-
- kh_val(map->table, k) = val;
-
- return rv;
-}
-
-void *map_del(Map *map, const char *key)
-{
- void *rv = NULL;
- khiter_t k;
-
- if ((k = kh_get(Map, map->table, key)) != kh_end(map->table)) {
- rv = kh_val(map->table, k).ptr;
- kh_del(Map, map->table, k);
- }
-
- return rv;
-}
-
-void map_foreach(Map *map, key_value_cb cb)
-{
- const char *key;
- Value value;
-
- kh_foreach(map->table, key, value, {
- cb(map, (const char *)key, value.ptr);
- });
-}
-
+MAP_IMPL(cstr_t)
+MAP_IMPL(ptr_t)
diff --git a/src/nvim/map.h b/src/nvim/map.h
index 7b4c03ffa0..ae47561deb 100644
--- a/src/nvim/map.h
+++ b/src/nvim/map.h
@@ -1,4 +1,3 @@
-// General-purpose string->pointer associative array with a simple API
#ifndef NVIM_MAP_H
#define NVIM_MAP_H
@@ -6,52 +5,35 @@
#include "nvim/map_defs.h"
-/// Creates a new `Map` instance
-///
-/// @return a pointer to the new instance
-Map *map_new(void);
-
-/// Frees memory for a `Map` instance
-///
-/// @param map The `Map` instance
-void map_free(Map *map);
-
-/// Gets the value corresponding to a key in a `Map` instance
-///
-/// @param map The `Map` instance
-/// @param key A key string
-/// @return The value if the key exists in the map, or NULL if it doesn't
-void *map_get(Map *map, const char *key);
-
-/// Checks if a key exists in the map
-///
-/// @param map The `Map` instance
-/// @param key A key string
-/// @return true if the key exists, false otherwise
-bool map_has(Map *map, const char *key);
-
-/// Set the value corresponding to a key in a `Map` instance and returns
-/// the old value.
-///
-/// @param map The `Map` instance
-/// @param key A key string
-/// @param value A value
-/// @return The current value if exists or NULL otherwise
-void *map_put(Map *map, const char *key, void *value);
-
-/// Deletes the value corresponding to a key in a `Map` instance and returns
-/// the old value.
-///
-/// @param map The `Map` instance
-/// @param key A key string
-/// @return The current value if exists or NULL otherwise
-void *map_del(Map *map, const char *key);
-
-/// Iterates through each key/value pair in the map
-///
-/// @param map The `Map` instance
-/// @param cb A function that will be called for each key/value
-void map_foreach(Map *map, key_value_cb cb);
-
-#endif /* NVIM_MAP_H */
+#define MAP_DECLS(T) \
+ KHASH_DECLARE(T##_map, T, void *) \
+ \
+ typedef struct { \
+ khash_t(T##_map) *table; \
+ } Map(T); \
+ \
+ Map(T) *map_##T##_new(void); \
+ void map_##T##_free(Map(T) *map); \
+ void *map_##T##_get(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##_del(Map(T) *map, T key);
+
+MAP_DECLS(cstr_t)
+MAP_DECLS(ptr_t)
+
+#define map_new(T) map_##T##_new
+#define map_free(T) map_##T##_free
+#define map_get(T) map_##T##_get
+#define map_has(T) map_##T##_has
+#define map_put(T) map_##T##_put
+#define map_del(T) map_##T##_del
+
+#define map_foreach(map, key, value, block) \
+ kh_foreach(map->table, key, value, block)
+
+#define map_foreach_value(map, value, block) \
+ kh_foreach_value(map->table, value, block)
+
+#endif // NVIM_MAP_H
diff --git a/src/nvim/map_defs.h b/src/nvim/map_defs.h
index e56a1461d4..d9f35dfc67 100644
--- a/src/nvim/map_defs.h
+++ b/src/nvim/map_defs.h
@@ -1,14 +1,14 @@
#ifndef NVIM_MAP_DEFS_H
#define NVIM_MAP_DEFS_H
-typedef struct map Map;
-/// Callback for iterating through each key/value pair in a map
-///
-/// @param map The `Map` instance
-/// @param key A key string
-/// @param value A value
-typedef void (*key_value_cb)(Map *map, const char *key, void *value);
+#include "nvim/lib/khash.h"
-#endif /* NVIM_MAP_DEFS_H */
+typedef const char * cstr_t;
+typedef void * ptr_t;
+
+#define Map(T) Map_##T
+
+
+#endif // NVIM_MAP_DEFS_H
diff --git a/src/nvim/os/server.c b/src/nvim/os/server.c
index e9a11809ae..9b5410c323 100644
--- a/src/nvim/os/server.c
+++ b/src/nvim/os/server.c
@@ -43,16 +43,15 @@ typedef struct {
} socket;
} Server;
-static Map *servers = NULL;
+static Map(cstr_t) *servers = NULL;
-static void close_server(Map *map, const char *endpoint, void *server);
static void connection_cb(uv_stream_t *server, int status);
static void free_client(uv_handle_t *handle);
static void free_server(uv_handle_t *handle);
void server_init()
{
- servers = map_new();
+ servers = map_new(cstr_t)();
if (!os_getenv("NEOVIM_LISTEN_ADDRESS")) {
char *listen_address = (char *)vim_tempname('s');
@@ -70,7 +69,15 @@ void server_teardown()
return;
}
- map_foreach(servers, close_server);
+ Server *server;
+
+ map_foreach_value(servers, server, {
+ if (server->type == kServerTypeTcp) {
+ uv_close((uv_handle_t *)&server->socket.tcp.handle, free_server);
+ } else {
+ uv_close((uv_handle_t *)&server->socket.pipe.handle, free_server);
+ }
+ });
}
void server_start(char *endpoint, ChannelProtocol prot)
@@ -81,7 +88,7 @@ void server_start(char *endpoint, ChannelProtocol prot)
strncpy(addr, endpoint, sizeof(addr));
// Check if the server already exists
- if (map_has(servers, addr)) {
+ if (map_has(cstr_t)(servers, addr)) {
EMSG2("Already listening on %s", addr);
return;
}
@@ -167,7 +174,7 @@ void server_start(char *endpoint, ChannelProtocol prot)
server->type = server_type;
// Add the server to the hash table
- map_put(servers, addr, server);
+ map_put(cstr_t)(servers, addr, server);
}
void server_stop(char *endpoint)
@@ -178,7 +185,7 @@ void server_stop(char *endpoint)
// Trim to `ADDRESS_MAX_SIZE`
strncpy(addr, endpoint, sizeof(addr));
- if ((server = map_get(servers, addr)) == NULL) {
+ if ((server = map_get(cstr_t)(servers, addr)) == NULL) {
EMSG2("Not listening on %s", addr);
return;
}
@@ -189,7 +196,7 @@ void server_stop(char *endpoint)
uv_close((uv_handle_t *)&server->socket.pipe.handle, free_server);
}
- map_del(servers, addr);
+ map_del(cstr_t)(servers, addr);
}
static void connection_cb(uv_stream_t *server, int status)
@@ -221,17 +228,6 @@ static void connection_cb(uv_stream_t *server, int status)
channel_from_stream(client, srv->protocol);
}
-static void close_server(Map *map, const char *endpoint, void *srv)
-{
- Server *server = srv;
-
- if (server->type == kServerTypeTcp) {
- uv_close((uv_handle_t *)&server->socket.tcp.handle, free_server);
- } else {
- uv_close((uv_handle_t *)&server->socket.pipe.handle, free_server);
- }
-}
-
static void free_client(uv_handle_t *handle)
{
free(handle);