diff options
author | Thiago de Arruda <tpadilha84@gmail.com> | 2014-05-08 18:25:59 -0300 |
---|---|---|
committer | Thiago de Arruda <tpadilha84@gmail.com> | 2014-05-13 09:33:41 -0300 |
commit | 5f5e39323ee799def35adde7cfee06698c2dfcc8 (patch) | |
tree | 75233a7524cf18b32ce74881b8e7acef9d356103 | |
parent | 57df213b86f08124010990665dd2f8f8b655810c (diff) | |
download | rneovim-5f5e39323ee799def35adde7cfee06698c2dfcc8.tar.gz rneovim-5f5e39323ee799def35adde7cfee06698c2dfcc8.tar.bz2 rneovim-5f5e39323ee799def35adde7cfee06698c2dfcc8.zip |
API: Move vim_to_object to helpers.c
-rw-r--r-- | src/api/helpers.c | 128 | ||||
-rw-r--r-- | src/api/helpers.h | 8 | ||||
-rw-r--r-- | src/api/vim.c | 136 |
3 files changed, 137 insertions, 135 deletions
diff --git a/src/api/helpers.c b/src/api/helpers.c index 9f41e55d39..2e189861a5 100644 --- a/src/api/helpers.c +++ b/src/api/helpers.c @@ -5,6 +5,20 @@ #include "api/helpers.h" #include "api/defs.h" #include "../vim.h" +#include "memory.h" +#include "eval.h" + +#include "lib/khash.h" + +KHASH_SET_INIT_INT64(Lookup) + +/// 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); void try_start() { @@ -48,3 +62,117 @@ bool try_end(Error *err) return err->set; } +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); + rv = vim_to_object_rec(obj, lookup); + // Free the table + kh_destroy(Lookup, lookup); + return rv; +} + +static Object vim_to_object_rec(typval_T *obj, khash_t(Lookup) *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, (uint64_t)obj, &ret); + if (!ret) { + // It's already present, meaning we alredy processed it so just return + // nil instead. + return rv; + } + } + + switch (obj->v_type) { + case VAR_STRING: + if (obj->vval.v_string != NULL) { + rv.type = kObjectTypeString; + rv.data.string.data = xstrdup((char *)obj->vval.v_string); + rv.data.string.size = strlen(rv.data.string.data); + } + break; + + case VAR_NUMBER: + rv.type = kObjectTypeInt; + rv.data.integer = obj->vval.v_number; + break; + + case VAR_FLOAT: + rv.type = kObjectTypeFloat; + rv.data.floating_point = obj->vval.v_float; + break; + + case VAR_LIST: + { + list_T *list = obj->vval.v_list; + listitem_T *item; + + if (list != NULL) { + rv.type = kObjectTypeArray; + rv.data.array.size = list->lv_len; + rv.data.array.items = xmalloc(list->lv_len * sizeof(Object)); + + uint32_t i = 0; + for (item = list->lv_first; item != NULL; item = item->li_next) { + rv.data.array.items[i] = vim_to_object_rec(&item->li_tv, lookup); + i++; + } + } + } + break; + + case VAR_DICT: + { + dict_T *dict = obj->vval.v_dict; + hashtab_T *ht; + uint64_t todo; + hashitem_T *hi; + dictitem_T *di; + + if (dict != NULL) { + ht = &obj->vval.v_dict->dv_hashtab; + todo = ht->ht_used; + rv.type = kObjectTypeDictionary; + + // Count items + rv.data.dictionary.size = 0; + for (hi = ht->ht_array; todo > 0; ++hi) { + if (!HASHITEM_EMPTY(hi)) { + todo--; + rv.data.dictionary.size++; + } + } + + rv.data.dictionary.items = + xmalloc(rv.data.dictionary.size * sizeof(KeyValuePair)); + todo = ht->ht_used; + uint32_t i = 0; + + // Convert all + for (hi = ht->ht_array; todo > 0; ++hi) { + if (!HASHITEM_EMPTY(hi)) { + di = dict_lookup(hi); + // Convert key + rv.data.dictionary.items[i].key.data = + xstrdup((char *)hi->hi_key); + rv.data.dictionary.items[i].key.size = + strlen((char *)hi->hi_key); + // Convert value + rv.data.dictionary.items[i].value = + vim_to_object_rec(&di->di_tv, lookup); + todo--; + i++; + } + } + } + } + break; + } + + return rv; +} diff --git a/src/api/helpers.h b/src/api/helpers.h index b1faf4edee..ddb46eaad4 100644 --- a/src/api/helpers.h +++ b/src/api/helpers.h @@ -4,6 +4,7 @@ #include <stdbool.h> #include "api/defs.h" +#include "../vim.h" #define set_api_error(message, err) \ do { \ @@ -21,5 +22,12 @@ void try_start(void); /// @return true if an error occurred bool try_end(Error *err); +/// Convert a vim object to an `Object` instance, recursively expanding +/// Arrays/Dictionaries. +/// +/// @param obj The source object +/// @return The converted value +Object vim_to_object(typval_T *obj); + #endif /* NEOVIM_API_HELPERS_H */ diff --git a/src/api/vim.c b/src/api/vim.c index 3d449678f4..efe37d9e9a 100644 --- a/src/api/vim.c +++ b/src/api/vim.c @@ -12,28 +12,9 @@ #include "ascii.h" #include "ex_docmd.h" #include "screen.h" +#include "memory.h" #include "eval.h" #include "misc2.h" -#include "memory.h" - -#include "lib/khash.h" - -KHASH_SET_INIT_INT64(Lookup) - -/// Convert a vim object to an `Object` instance, recursively expanding -/// Arrays/Dictionaries. -/// -/// @param obj The source object -/// @return The converted value -static Object vim_to_object(typval_T *vim_obj); - -/// 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); void vim_push_keys(String str) { @@ -240,118 +221,3 @@ void vim_set_current_tabpage(Tabpage tabpage) { abort(); } - -static 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); - rv = vim_to_object_rec(obj, lookup); - // Free the table - kh_destroy(Lookup, lookup); - return rv; -} - -static Object vim_to_object_rec(typval_T *obj, khash_t(Lookup) *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, (uint64_t)obj, &ret); - if (!ret) { - // It's already present, meaning we alredy processed it so just return - // nil instead. - return rv; - } - } - - switch (obj->v_type) { - case VAR_STRING: - if (obj->vval.v_string != NULL) { - rv.type = kObjectTypeString; - rv.data.string.data = xstrdup((char *)obj->vval.v_string); - rv.data.string.size = strlen(rv.data.string.data); - } - break; - - case VAR_NUMBER: - rv.type = kObjectTypeInt; - rv.data.integer = obj->vval.v_number; - break; - - case VAR_FLOAT: - rv.type = kObjectTypeFloat; - rv.data.floating_point = obj->vval.v_float; - break; - - case VAR_LIST: - { - list_T *list = obj->vval.v_list; - listitem_T *item; - - if (list != NULL) { - rv.type = kObjectTypeArray; - rv.data.array.size = list->lv_len; - rv.data.array.items = xmalloc(list->lv_len * sizeof(Object)); - - uint32_t i = 0; - for (item = list->lv_first; item != NULL; item = item->li_next) { - rv.data.array.items[i] = vim_to_object_rec(&item->li_tv, lookup); - i++; - } - } - } - break; - - case VAR_DICT: - { - dict_T *dict = obj->vval.v_dict; - hashtab_T *ht; - uint64_t todo; - hashitem_T *hi; - dictitem_T *di; - - if (dict != NULL) { - ht = &obj->vval.v_dict->dv_hashtab; - todo = ht->ht_used; - rv.type = kObjectTypeDictionary; - - // Count items - rv.data.dictionary.size = 0; - for (hi = ht->ht_array; todo > 0; ++hi) { - if (!HASHITEM_EMPTY(hi)) { - todo--; - rv.data.dictionary.size++; - } - } - - rv.data.dictionary.items = - xmalloc(rv.data.dictionary.size * sizeof(KeyValuePair)); - todo = ht->ht_used; - uint32_t i = 0; - - // Convert all - for (hi = ht->ht_array; todo > 0; ++hi) { - if (!HASHITEM_EMPTY(hi)) { - di = dict_lookup(hi); - // Convert key - rv.data.dictionary.items[i].key.data = - xstrdup((char *)hi->hi_key); - rv.data.dictionary.items[i].key.size = - strlen((char *)hi->hi_key); - // Convert value - rv.data.dictionary.items[i].value = - vim_to_object_rec(&di->di_tv, lookup); - todo--; - i++; - } - } - } - } - break; - } - - return rv; -} |