diff options
author | ZyX <kp-pav@yandex.ru> | 2015-08-03 23:06:06 +0300 |
---|---|---|
committer | ZyX <kp-pav@yandex.ru> | 2015-10-08 22:00:16 +0300 |
commit | 07d9ab26c6526c0d9af0435f1adeb614a1b88743 (patch) | |
tree | e3023fdfdd1d24ae1cae114d6e936e7b0641babc /src | |
parent | 56174572bc70947ab1e9e6ef48112272682ad6d8 (diff) | |
download | rneovim-07d9ab26c6526c0d9af0435f1adeb614a1b88743.tar.gz rneovim-07d9ab26c6526c0d9af0435f1adeb614a1b88743.tar.bz2 rneovim-07d9ab26c6526c0d9af0435f1adeb614a1b88743.zip |
*: Make ShaDa code use VimL values for additional_\* data
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/buffer.c | 6 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 4 | ||||
-rw-r--r-- | src/nvim/eval.c | 144 | ||||
-rw-r--r-- | src/nvim/eval.h | 4 | ||||
-rw-r--r-- | src/nvim/eval_defs.h | 13 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 7 | ||||
-rw-r--r-- | src/nvim/ex_cmds.h | 4 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 7 | ||||
-rw-r--r-- | src/nvim/ex_getln.h | 3 | ||||
-rw-r--r-- | src/nvim/mark.c | 9 | ||||
-rw-r--r-- | src/nvim/mark_defs.h | 4 | ||||
-rw-r--r-- | src/nvim/ops.c | 10 | ||||
-rw-r--r-- | src/nvim/ops.h | 4 | ||||
-rw-r--r-- | src/nvim/search.c | 6 | ||||
-rw-r--r-- | src/nvim/search.h | 2 | ||||
-rw-r--r-- | src/nvim/shada.c | 530 | ||||
-rw-r--r-- | src/nvim/undo.c | 8 |
17 files changed, 305 insertions, 460 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 53612977ee..a25a51c6ce 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -30,7 +30,6 @@ #include <inttypes.h> #include "nvim/api/private/handle.h" -#include "nvim/api/private/helpers.h" #include "nvim/ascii.h" #include "nvim/vim.h" #include "nvim/buffer.h" @@ -557,10 +556,7 @@ static void free_buffer(buf_T *buf) free_buffer_stuff(buf, TRUE); unref_var_dict(buf->b_vars); aubuflocal_remove(buf); - if (buf->additional_data != NULL) { - api_free_dictionary(*buf->additional_data); - xfree(buf->additional_data); - } + dict_unref(buf->additional_data); free_fmark(buf->b_last_cursor); free_fmark(buf->b_last_insert); free_fmark(buf->b_last_change); diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 2be5386de9..f71575deaf 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -26,7 +26,7 @@ typedef struct file_buffer buf_T; // Forward declaration #include "nvim/eval_defs.h" // for proftime_T #include "nvim/profile.h" -// for String and Dictionary +// for String #include "nvim/api/private/defs.h" #define MODIFIABLE(buf) (!buf->terminal && buf->b_p_ma) @@ -749,7 +749,7 @@ struct file_buffer { Terminal *terminal; // Terminal instance associated with the buffer - Dictionary *additional_data; // Additional data from shada file if any. + dict_T *additional_data; // Additional data from shada file if any. }; /* diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 5a7d4702d2..ad66c4c924 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -108,18 +108,6 @@ function/variable names. */ /* - * In a hashtab item "hi_key" points to "di_key" in a dictitem. - * This avoids adding a pointer to the hashtab item. - * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer. - * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer. - * HI2DI() converts a hashitem pointer to a dictitem pointer. - */ -static dictitem_T dumdi; -#define DI2HIKEY(di) ((di)->di_key) -#define HIKEY2DI(p) ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi))) -#define HI2DI(hi) HIKEY2DI((hi)->hi_key) - -/* * Structure returned by get_lval() and used by set_var_lval(). * For a plain name: * "name" points to the variable name. @@ -5352,7 +5340,7 @@ static int list_concat(list_T *l1, list_T *l2, typval_T *tv) return FAIL; /* make a copy of the first list. */ - l = list_copy(l1, FALSE, 0); + l = list_copy(NULL, l1, FALSE, 0); if (l == NULL) return FAIL; tv->v_type = VAR_LIST; @@ -5363,13 +5351,20 @@ static int list_concat(list_T *l1, list_T *l2, typval_T *tv) return OK; } -/* - * Make a copy of list "orig". Shallow if "deep" is FALSE. - * The refcount of the new list is set to 1. - * See item_copy() for "copyID". - * Returns NULL if orig is NULL or some failure happens. - */ -static list_T *list_copy(list_T *orig, int deep, int copyID) +/// Make a copy of list +/// +/// @param[in] conv If non-NULL, then all internal strings will be converted. +/// @param[in] orig Original list to copy. +/// @param[in] deep If false, then shallow copy will be done. +/// @param[in] copyID See var_item_copy(). +/// +/// @return Copied list. May be NULL in case original list is NULL or some +/// failure happens. The refcount of the new list is set to 1. +static list_T *list_copy(const vimconv_T *const conv, + list_T *const orig, + const bool deep, + const int copyID) + FUNC_ATTR_WARN_UNUSED_RESULT { listitem_T *item; listitem_T *ni; @@ -5388,7 +5383,7 @@ static list_T *list_copy(list_T *orig, int deep, int copyID) item = item->li_next) { ni = listitem_alloc(); if (deep) { - if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) { + if (var_item_copy(conv, &item->li_tv, &ni->li_tv, deep, copyID) == FAIL) { xfree(ni); break; } @@ -5964,13 +5959,20 @@ void dictitem_free(dictitem_T *item) xfree(item); } -/* - * Make a copy of dict "d". Shallow if "deep" is FALSE. - * The refcount of the new dict is set to 1. - * See item_copy() for "copyID". - * Returns NULL if orig is NULL or some other failure. - */ -static dict_T *dict_copy(dict_T *orig, int deep, int copyID) +/// Make a copy of dictionary +/// +/// @param[in] conv If non-NULL, then all internal strings will be converted. +/// @param[in] orig Original dictionary to copy. +/// @param[in] deep If false, then shallow copy will be done. +/// @param[in] copyID See var_item_copy(). +/// +/// @return Copied dictionary. May be NULL in case original dictionary is NULL +/// or some failure happens. The refcount of the new dictionary is set +/// to 1. +static dict_T *dict_copy(const vimconv_T *const conv, + dict_T *const orig, + const bool deep, + const int copyID) { dictitem_T *di; int todo; @@ -5990,10 +5992,21 @@ static dict_T *dict_copy(dict_T *orig, int deep, int copyID) if (!HASHITEM_EMPTY(hi)) { --todo; - di = dictitem_alloc(hi->hi_key); + if (conv == NULL || conv->vc_type == CONV_NONE) { + di = dictitem_alloc(hi->hi_key); + } else { + char *const key = (char *) string_convert((vimconv_T *) conv, + hi->hi_key, NULL); + if (key == NULL) { + di = dictitem_alloc(hi->hi_key); + } else { + di = dictitem_alloc((char_u *) key); + xfree(key); + } + } if (deep) { - if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, - copyID) == FAIL) { + if (var_item_copy(conv, &HI2DI(hi)->di_tv, &di->di_tv, deep, + copyID) == FAIL) { xfree(di); break; } @@ -6305,7 +6318,7 @@ failret: /// the results. /// @param firstargname Name of the first argument. /// @param name Name of the target converter. -#define DEFINE_VIML_CONV_FUNCTIONS(name, firstargtype, firstargname) \ +#define DEFINE_VIML_CONV_FUNCTIONS(scope, name, firstargtype, firstargname) \ static int name##_convert_one_value(firstargtype firstargname, \ MPConvStack *const mpstack, \ typval_T *const tv, \ @@ -6543,7 +6556,7 @@ name##_convert_one_value_regular_dict: \ return OK; \ } \ \ -static int vim_to_##name(firstargtype firstargname, typval_T *const tv) \ +scope int vim_to_##name(firstargtype firstargname, typval_T *const tv) \ FUNC_ATTR_WARN_UNUSED_RESULT \ { \ current_copyID += COPYID_INC; \ @@ -6739,7 +6752,7 @@ vim_to_msgpack_error_ret: \ #define CONV_ALLOW_SPECIAL false -DEFINE_VIML_CONV_FUNCTIONS(string, garray_T *const, gap) +DEFINE_VIML_CONV_FUNCTIONS(static, string, garray_T *const, gap) #undef CONV_RECURSE #define CONV_RECURSE(val, conv_type) \ @@ -6769,7 +6782,7 @@ DEFINE_VIML_CONV_FUNCTIONS(string, garray_T *const, gap) return OK; \ } while (0) -DEFINE_VIML_CONV_FUNCTIONS(echo, garray_T *const, gap) +DEFINE_VIML_CONV_FUNCTIONS(static, echo, garray_T *const, gap) #undef CONV_STRING #undef CONV_STR_STRING @@ -8344,7 +8357,7 @@ static void f_confirm(typval_T *argvars, typval_T *rettv) */ static void f_copy(typval_T *argvars, typval_T *rettv) { - item_copy(&argvars[0], rettv, FALSE, 0); + var_item_copy(NULL, &argvars[0], rettv, false, 0); } /* @@ -8513,7 +8526,9 @@ static void f_deepcopy(typval_T *argvars, typval_T *rettv) EMSG(_(e_invarg)); else { current_copyID += COPYID_INC; - item_copy(&argvars[0], rettv, TRUE, noref == 0 ? current_copyID : 0); + var_item_copy(NULL, &argvars[0], rettv, true, (noref == 0 + ? current_copyID + : 0)); } } @@ -12486,7 +12501,7 @@ static inline bool vim_list_to_buf(const list_T *const list, #define CONV_ALLOW_SPECIAL true -DEFINE_VIML_CONV_FUNCTIONS(msgpack, msgpack_packer *const, packer) +DEFINE_VIML_CONV_FUNCTIONS(, msgpack, msgpack_packer *const, packer) #undef CONV_STRING #undef CONV_STR_STRING @@ -12592,7 +12607,7 @@ static inline ListReaderState init_lrstate(const list_T *const list) } /// Convert msgpack object to a VimL one -static int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv) +int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT { #define INIT_SPECIAL_DICT(tv, type, val) \ @@ -18446,14 +18461,28 @@ void copy_tv(typval_T *from, typval_T *to) } } -/* - * Make a copy of an item. - * Lists and Dictionaries are also copied. A deep copy if "deep" is set. - * For deepcopy() "copyID" is zero for a full copy or the ID for when a - * reference to an already copied list/dict can be used. - * Returns FAIL or OK. - */ -static int item_copy(typval_T *from, typval_T *to, int deep, int copyID) +/// Make a copy of an item +/// +/// Lists and Dictionaries are also copied. +/// +/// @param[in] conv If not NULL, convert all copied strings. +/// @param[in] from Value to copy. +/// @param[out] to Location where to copy to. +/// @param[in] deep If true, use copy the container and all of the contained +/// containers (nested). +/// @param[in] copyID If non-zero then when container is referenced more then +/// once then copy of it that was already done is used. E.g. +/// when copying list `list = [list2, list2]` (`list[0] is +/// list[1]`) var_item_copy with zero copyID will emit +/// a copy with (`copy[0] isnot copy[1]`), with non-zero it +/// will emit a copy with (`copy[0] is copy[1]`) like in the +/// original list. Not use when deep is false. +int var_item_copy(const vimconv_T *const conv, + typval_T *const from, + typval_T *const to, + const bool deep, + const int copyID) + FUNC_ATTR_NONNULL_ARG(2,3) { static int recurse = 0; int ret = OK; @@ -18467,10 +18496,23 @@ static int item_copy(typval_T *from, typval_T *to, int deep, int copyID) switch (from->v_type) { case VAR_NUMBER: case VAR_FLOAT: - case VAR_STRING: case VAR_FUNC: copy_tv(from, to); break; + case VAR_STRING: + if (conv == NULL || conv->vc_type == CONV_NONE) { + copy_tv(from, to); + } else { + to->v_type = VAR_STRING; + to->v_lock = 0; + if ((to->vval.v_string = string_convert((vimconv_T *)conv, + from->vval.v_string, + NULL)) + == NULL) { + to->vval.v_string = (char_u *) xstrdup((char *) from->vval.v_string); + } + } + break; case VAR_LIST: to->v_type = VAR_LIST; to->v_lock = 0; @@ -18481,7 +18523,7 @@ static int item_copy(typval_T *from, typval_T *to, int deep, int copyID) to->vval.v_list = from->vval.v_list->lv_copylist; ++to->vval.v_list->lv_refcount; } else - to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); + to->vval.v_list = list_copy(conv, from->vval.v_list, deep, copyID); if (to->vval.v_list == NULL) ret = FAIL; break; @@ -18495,12 +18537,12 @@ static int item_copy(typval_T *from, typval_T *to, int deep, int copyID) to->vval.v_dict = from->vval.v_dict->dv_copydict; ++to->vval.v_dict->dv_refcount; } else - to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); + to->vval.v_dict = dict_copy(conv, from->vval.v_dict, deep, copyID); if (to->vval.v_dict == NULL) ret = FAIL; break; default: - EMSG2(_(e_intern2), "item_copy()"); + EMSG2(_(e_intern2), "var_item_copy()"); ret = FAIL; } --recurse; diff --git a/src/nvim/eval.h b/src/nvim/eval.h index 8f065eda33..864daed716 100644 --- a/src/nvim/eval.h +++ b/src/nvim/eval.h @@ -1,6 +1,8 @@ #ifndef NVIM_EVAL_H #define NVIM_EVAL_H +#include <msgpack.h> + #include "nvim/profile.h" /* Defines for Vim variables. These must match vimvars[] in eval.c! */ @@ -72,6 +74,8 @@ enum { /// Maximum number of function arguments #define MAX_FUNC_ARGS 20 +int vim_to_msgpack(msgpack_packer *const, typval_T *const); + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "eval.h.generated.h" #endif diff --git a/src/nvim/eval_defs.h b/src/nvim/eval_defs.h index a8a8acd048..373f1e6278 100644 --- a/src/nvim/eval_defs.h +++ b/src/nvim/eval_defs.h @@ -2,6 +2,7 @@ #define NVIM_EVAL_DEFS_H #include <limits.h> +#include <stddef.h> #include "nvim/hashtab.h" @@ -132,4 +133,16 @@ typedef struct list_stack_S { struct list_stack_S *prev; } list_stack_T; +// In a hashtab item "hi_key" points to "di_key" in a dictitem. +// This avoids adding a pointer to the hashtab item. + +/// Convert a dictitem pointer to a hashitem key pointer +#define DI2HIKEY(di) ((di)->di_key) + +/// Convert a hashitem key pointer to a dictitem pointer +#define HIKEY2DI(p) ((dictitem_T *)(p - offsetof(dictitem_T, di_key))) + +/// Convert a hashitem pointer to a dictitem pointer +#define HI2DI(hi) HIKEY2DI((hi)->hi_key) + #endif // NVIM_EVAL_DEFS_H diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 262150a8c0..5db3880026 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -68,8 +68,6 @@ #include "nvim/os/shell.h" #include "nvim/os/input.h" #include "nvim/os/time.h" -#include "nvim/api/private/defs.h" -#include "nvim/api/private/helpers.h" /* * Struct to hold the sign properties. @@ -2846,10 +2844,7 @@ void sub_set_replacement(SubReplacementString sub) { xfree(old_sub.sub); if (sub.additional_elements != old_sub.additional_elements) { - if (old_sub.additional_elements != NULL) { - api_free_array(*old_sub.additional_elements); - xfree(old_sub.additional_elements); - } + list_unref(old_sub.additional_elements); } old_sub = sub; } diff --git a/src/nvim/ex_cmds.h b/src/nvim/ex_cmds.h index 71fc100e41..721145efd8 100644 --- a/src/nvim/ex_cmds.h +++ b/src/nvim/ex_cmds.h @@ -4,7 +4,7 @@ #include <stdbool.h> #include "nvim/os/time.h" -#include "nvim/api/private/defs.h" +#include "nvim/eval_defs.h" /* flags for do_ecmd() */ #define ECMD_HIDE 0x01 /* don't free the current buffer */ @@ -23,7 +23,7 @@ typedef struct { char *sub; ///< Previous replacement string. Timestamp timestamp; ///< Time when it was last set. - Array *additional_elements; ///< Additional data left from ShaDa file. + list_T *additional_elements; ///< Additional data left from ShaDa file. } SubReplacementString; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 38f84f2e7f..7be8d722b8 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -66,8 +66,6 @@ #include "nvim/os/os.h" #include "nvim/event/loop.h" #include "nvim/os/time.h" -#include "nvim/api/private/defs.h" -#include "nvim/api/private/helpers.h" /* * Variables shared between getcmdline(), redrawcmdline() and others. @@ -4252,10 +4250,7 @@ static inline void hist_free_entry(histentry_T *hisptr) FUNC_ATTR_NONNULL_ALL { xfree(hisptr->hisstr); - if (hisptr->additional_elements != NULL) { - api_free_array(*hisptr->additional_elements); - xfree(hisptr->additional_elements); - } + list_unref(hisptr->additional_elements); clear_hist_entry(hisptr); } diff --git a/src/nvim/ex_getln.h b/src/nvim/ex_getln.h index 738e515f21..3bfd6a8aac 100644 --- a/src/nvim/ex_getln.h +++ b/src/nvim/ex_getln.h @@ -1,6 +1,7 @@ #ifndef NVIM_EX_GETLN_H #define NVIM_EX_GETLN_H +#include "nvim/eval_defs.h" #include "nvim/ex_cmds.h" /* Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. */ @@ -40,7 +41,7 @@ typedef struct hist_entry { int hisnum; ///< Entry identifier number. char_u *hisstr; ///< Actual entry, separator char after the NUL. Timestamp timestamp; ///< Time when entry was added. - Array *additional_elements; ///< Additional entries from ShaDa file. + list_T *additional_elements; ///< Additional entries from ShaDa file. } histentry_T; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/mark.c b/src/nvim/mark.c index e88cc11c39..beb8dd6679 100644 --- a/src/nvim/mark.c +++ b/src/nvim/mark.c @@ -41,8 +41,6 @@ #include "nvim/os/os.h" #include "nvim/os/time.h" #include "nvim/os/input.h" -#include "nvim/api/private/defs.h" -#include "nvim/api/private/helpers.h" /* * This file contains routines to maintain and manipulate marks. @@ -74,11 +72,8 @@ int setmark(int c) /// Free fmark_T item void free_fmark(fmark_T fm) { - if (fm.additional_data != NULL) { - api_free_dictionary(*fm.additional_data); - free(fm.additional_data); - fm.additional_data = NULL; - } + dict_unref(fm.additional_data); + fm.additional_data = NULL; } /// Free xfmark_T item diff --git a/src/nvim/mark_defs.h b/src/nvim/mark_defs.h index af4727d634..8f8425f0a6 100644 --- a/src/nvim/mark_defs.h +++ b/src/nvim/mark_defs.h @@ -3,7 +3,7 @@ #include "nvim/pos.h" #include "nvim/os/time.h" -#include "nvim/api/private/defs.h" +#include "nvim/eval_defs.h" /* * marks: positions in a file @@ -36,7 +36,7 @@ typedef struct filemark { pos_T mark; ///< Cursor position. int fnum; ///< File number. Timestamp timestamp; ///< Time when this mark was last set. - Dictionary *additional_data; ///< Additional data from ShaDa file. + dict_T *additional_data; ///< Additional data from ShaDa file. } fmark_T; /// Structure defining extended mark (mark with file name attached) diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 0d7c319fba..9af37df8a0 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -51,8 +51,6 @@ #include "nvim/window.h" #include "nvim/os/input.h" #include "nvim/os/time.h" -#include "nvim/api/private/defs.h" -#include "nvim/api/private/helpers.h" static yankreg_T y_regs[NUM_REGISTERS]; @@ -869,17 +867,13 @@ int do_record(int c) return retval; } -static void set_yreg_additional_data(yankreg_T *reg, - Dictionary *additional_data) +static void set_yreg_additional_data(yankreg_T *reg, dict_T *additional_data) FUNC_ATTR_NONNULL_ARG(1) { if (reg->additional_data == additional_data) { return; } - if (reg->additional_data != NULL) { - api_free_dictionary(*reg->additional_data); - free(reg->additional_data); - } + dict_unref(reg->additional_data); reg->additional_data = additional_data; } diff --git a/src/nvim/ops.h b/src/nvim/ops.h index 5565f1631f..507f933acf 100644 --- a/src/nvim/ops.h +++ b/src/nvim/ops.h @@ -6,7 +6,7 @@ #include "nvim/macros.h" #include "nvim/ascii.h" #include "nvim/types.h" -#include "nvim/api/private/defs.h" +#include "nvim/eval_defs.h" #include "nvim/os/time.h" typedef int (*Indenter)(void); @@ -81,7 +81,7 @@ typedef struct yankreg { char_u y_type; ///< Register type: MLINE, MCHAR or MBLOCK. colnr_T y_width; ///< Register width (only valid for y_type == MBLOCK). Timestamp timestamp; ///< Time when register was last modified. - Dictionary *additional_data; ///< Additional data from ShaDa file. + dict_T *additional_data; ///< Additional data from ShaDa file. } yankreg_T; /// Convert register name into register index diff --git a/src/nvim/search.c b/src/nvim/search.c index f8dd7bd482..285f18e58f 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -51,7 +51,6 @@ #include "nvim/ui.h" #include "nvim/window.h" #include "nvim/os/time.h" -#include "nvim/api/private/helpers.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -292,10 +291,7 @@ void restore_search_patterns(void) static inline void free_spat(struct spat *const spat) { xfree(spat->pat); - if (spat->additional_data != NULL) { - api_free_dictionary(*spat->additional_data); - xfree(spat->additional_data); - } + dict_unref(spat->additional_data); } #if defined(EXITFREE) diff --git a/src/nvim/search.h b/src/nvim/search.h index 691782e41c..1fc2d6710e 100644 --- a/src/nvim/search.h +++ b/src/nvim/search.h @@ -60,7 +60,7 @@ typedef struct spat { bool no_scs; ///< No smartcase for this pattern. Timestamp timestamp; ///< Time of the last change. SearchOffset off; ///< Pattern offset. - Dictionary *additional_data; ///< Additional data from ShaDa file. + dict_T *additional_data; ///< Additional data from ShaDa file. } SearchPattern; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 8830653f48..684a6ea62d 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -287,7 +287,7 @@ typedef struct { char name; pos_T mark; char *fname; - Dictionary *additional_data; + dict_T *additional_data; } filemark; struct search_pattern { bool magic; @@ -299,14 +299,13 @@ typedef struct { bool is_substitute_pattern; bool highlighted; char *pat; - Dictionary *additional_data; + dict_T *additional_data; } search_pattern; struct history_item { uint8_t histtype; char *string; char sep; - bool canfree; - Array *additional_elements; + list_T *additional_elements; } history_item; struct reg { char name; @@ -314,12 +313,12 @@ typedef struct { char **contents; size_t contents_size; size_t width; - Dictionary *additional_data; + dict_T *additional_data; } reg; struct global_var { char *name; - Object value; - Array *additional_elements; + typval_T value; + list_T *additional_elements; } global_var; struct { uint64_t type; @@ -328,14 +327,14 @@ typedef struct { } unknown_item; struct sub_string { char *sub; - Array *additional_elements; + list_T *additional_elements; } sub_string; struct buffer_list { size_t size; struct buffer_list_buffer { pos_T pos; char *fname; - Dictionary *additional_data; + dict_T *additional_data; } *buffers; } buffer_list; } data; @@ -899,7 +898,6 @@ static const void *shada_hist_iter(const void *const iter, ? (char) hist_he.hisstr[STRLEN(hist_he.hisstr) + 1] : 0), .additional_elements = hist_he.additional_elements, - .canfree = zero, } } }; @@ -1254,17 +1252,9 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) break; } case kSDItemVariable: { - typval_T vartv; - Error err; - if (!object_to_vim(cur_entry.data.global_var.value, &vartv, &err)) { - if (err.set) { - emsg3(_(RERR "Error while reading ShaDa file: " - "failed to read value for variable %s: %s"), - cur_entry.data.global_var.name, err.msg); - } - break; - } - var_set_global(cur_entry.data.global_var.name, vartv); + var_set_global(cur_entry.data.global_var.name, + cur_entry.data.global_var.value); + cur_entry.data.global_var.value.v_type = VAR_UNKNOWN; shada_free_shada_entry(&cur_entry); break; } @@ -1367,6 +1357,9 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) cur_entry.data.buffer_list.buffers[i].pos, 0); buflist_setfpos(buf, curwin, buf->b_last_cursor.mark.lnum, buf->b_last_cursor.mark.col, false); + buf->additional_data = + cur_entry.data.buffer_list.buffers[i].additional_data; + cur_entry.data.buffer_list.buffers[i].additional_data = NULL; } } shada_free_shada_entry(&cur_entry); @@ -1567,13 +1560,42 @@ static char *shada_filename(const char *file) /// @param[in] max_kbyte Maximum size of an item in KiB. Zero means no /// restrictions. static bool shada_pack_entry(msgpack_packer *const packer, - const ShadaEntry entry, + ShadaEntry entry, const size_t max_kbyte) FUNC_ATTR_NONNULL_ALL { msgpack_sbuffer sbuf; msgpack_sbuffer_init(&sbuf); msgpack_packer *spacker = msgpack_packer_new(&sbuf, &msgpack_sbuffer_write); +#define DUMP_ADDITIONAL_ELEMENTS(src) \ + do { \ + if ((src) != NULL) { \ + for (listitem_T *li = (src)->lv_first; li != NULL; li = li->li_next) { \ + if (vim_to_msgpack(spacker, &li->li_tv) == FAIL) { \ + return false; \ + } \ + } \ + } \ + } while (0) +#define DUMP_ADDITIONAL_DATA(src) \ + do { \ + dict_T *const d = (src); \ + if (d != NULL) { \ + size_t todo = d->dv_hashtab.ht_used; \ + for (const hashitem_T *hi= d->dv_hashtab.ht_array; todo; hi++) { \ + if (!HASHITEM_EMPTY(hi)) { \ + todo--; \ + dictitem_T *const di = HI2DI(hi); \ + const size_t key_len = strlen((const char *) hi->hi_key); \ + msgpack_pack_str(spacker, key_len); \ + msgpack_pack_str_body(spacker, (const char *) hi->hi_key, key_len); \ + if (vim_to_msgpack(spacker, &di->di_tv) == FAIL) { \ + return false; \ + } \ + } \ + } \ + } \ + } while (0) switch (entry.type) { case kSDItemMissing: { assert(false); @@ -1591,10 +1613,10 @@ static bool shada_pack_entry(msgpack_packer *const packer, case kSDItemHistoryEntry: { const bool is_hist_search = entry.data.history_item.histtype == HIST_SEARCH; - const size_t arr_size = 2 + (size_t) is_hist_search + ( + const size_t arr_size = 2 + (size_t) is_hist_search + (size_t) ( entry.data.history_item.additional_elements == NULL ? 0 - : entry.data.history_item.additional_elements->size); + : entry.data.history_item.additional_elements->lv_len); msgpack_pack_array(spacker, arr_size); msgpack_pack_uint8(spacker, entry.data.history_item.histtype); msgpack_rpc_from_string(cstr_as_string(entry.data.history_item.string), @@ -1602,39 +1624,32 @@ static bool shada_pack_entry(msgpack_packer *const packer, if (is_hist_search) { msgpack_pack_uint8(spacker, (uint8_t) entry.data.history_item.sep); } - for (size_t i = 0; i < arr_size - 2 - (size_t) is_hist_search; i++) { - msgpack_rpc_from_object( - entry.data.history_item.additional_elements->items[i], spacker); - } + DUMP_ADDITIONAL_ELEMENTS(entry.data.history_item.additional_elements); break; } case kSDItemVariable: { - const size_t arr_size = 2 + ( + const size_t arr_size = 2 + (size_t) ( entry.data.global_var.additional_elements == NULL ? 0 - : entry.data.global_var.additional_elements->size); + : entry.data.global_var.additional_elements->lv_len); msgpack_pack_array(spacker, arr_size); msgpack_rpc_from_string(cstr_as_string(entry.data.global_var.name), spacker); - msgpack_rpc_from_object(entry.data.global_var.value, spacker); - for (size_t i = 0; i < arr_size - 2; i++) { - msgpack_rpc_from_object( - entry.data.global_var.additional_elements->items[i], spacker); + if (vim_to_msgpack(spacker, &entry.data.global_var.value) == FAIL) { + return false; } + DUMP_ADDITIONAL_ELEMENTS(entry.data.global_var.additional_elements); break; } case kSDItemSubString: { - const size_t arr_size = 1 + ( + const size_t arr_size = 1 + (size_t) ( entry.data.sub_string.additional_elements == NULL ? 0 - : entry.data.sub_string.additional_elements->size); + : entry.data.sub_string.additional_elements->lv_len); msgpack_pack_array(spacker, arr_size); msgpack_rpc_from_string(cstr_as_string(entry.data.sub_string.sub), spacker); - for (size_t i = 0; i < arr_size - 1; i++) { - msgpack_rpc_from_object( - entry.data.sub_string.additional_elements->items[i], spacker); - } + DUMP_ADDITIONAL_ELEMENTS(entry.data.sub_string.additional_elements); break; } case kSDItemSearchPattern: { @@ -1652,9 +1667,10 @@ static bool shada_pack_entry(msgpack_packer *const packer, // offset defaults to zero: + (size_t) (entry.data.search_pattern.offset != 0) // finally, additional data: - + (size_t) (entry.data.search_pattern.additional_data - ? entry.data.search_pattern.additional_data->size - : 0) + + (size_t) ( + entry.data.search_pattern.additional_data + ? entry.data.search_pattern.additional_data->dv_hashtab.ht_used + : 0) ); msgpack_pack_map(spacker, map_size); PACK_STATIC_STR(SEARCH_KEY_PAT); @@ -1679,16 +1695,7 @@ static bool shada_pack_entry(msgpack_packer *const packer, msgpack_pack_int64(spacker, entry.data.search_pattern.offset); } #undef PACK_BOOL - if (entry.data.search_pattern.additional_data != NULL) { - for (size_t i = 0; i < entry.data.search_pattern.additional_data->size; - i++) { - msgpack_rpc_from_string( - entry.data.search_pattern.additional_data->items[i].key, spacker); - msgpack_rpc_from_object( - entry.data.search_pattern.additional_data->items[i].value, - spacker); - } - } + DUMP_ADDITIONAL_DATA(entry.data.search_pattern.additional_data); break; } case kSDItemChange: @@ -1706,9 +1713,10 @@ static bool shada_pack_entry(msgpack_packer *const packer, && entry.type != kSDItemChange && entry.data.filemark.name != '"') // Additional entries, if any: - + (size_t) (entry.data.filemark.additional_data == NULL - ? 0 - : entry.data.filemark.additional_data->size) + + (size_t) ( + entry.data.filemark.additional_data == NULL + ? 0 + : entry.data.filemark.additional_data->dv_hashtab.ht_used) ); msgpack_pack_map(spacker, map_size); PACK_STATIC_STR(KEY_FILE); @@ -1727,15 +1735,7 @@ static bool shada_pack_entry(msgpack_packer *const packer, PACK_STATIC_STR(KEY_NAME_CHAR); msgpack_pack_uint8(spacker, (uint8_t) entry.data.filemark.name); } - if (entry.data.filemark.additional_data != NULL) { - for (size_t i = 0; i < entry.data.filemark.additional_data->size; - i++) { - msgpack_rpc_from_string( - entry.data.filemark.additional_data->items[i].key, spacker); - msgpack_rpc_from_object( - entry.data.filemark.additional_data->items[i].value, spacker); - } - } + DUMP_ADDITIONAL_DATA(entry.data.filemark.additional_data); break; } case kSDItemRegister: { @@ -1748,7 +1748,7 @@ static bool shada_pack_entry(msgpack_packer *const packer, // Additional entries, if any: + (size_t) (entry.data.reg.additional_data == NULL ? 0 - : entry.data.reg.additional_data->size) + : entry.data.reg.additional_data->dv_hashtab.ht_used) ); msgpack_pack_map(spacker, map_size); PACK_STATIC_STR(REG_KEY_CONTENTS); @@ -1767,15 +1767,7 @@ static bool shada_pack_entry(msgpack_packer *const packer, PACK_STATIC_STR(REG_KEY_WIDTH); msgpack_pack_uint64(spacker, (uint64_t) entry.data.reg.width); } - if (entry.data.reg.additional_data != NULL) { - for (size_t i = 0; i < entry.data.reg.additional_data->size; - i++) { - msgpack_rpc_from_string(entry.data.reg.additional_data->items[i].key, - spacker); - msgpack_rpc_from_object( - entry.data.reg.additional_data->items[i].value, spacker); - } - } + DUMP_ADDITIONAL_DATA(entry.data.reg.additional_data); break; } case kSDItemBufferList: { @@ -1791,7 +1783,8 @@ static bool shada_pack_entry(msgpack_packer *const packer, + (size_t) ( entry.data.buffer_list.buffers[i].additional_data == NULL ? 0 - : entry.data.buffer_list.buffers[i].additional_data->size) + : (entry.data.buffer_list.buffers[i].additional_data + ->dv_hashtab.ht_used)) ); msgpack_pack_map(spacker, map_size); PACK_STATIC_STR(KEY_FILE); @@ -1807,18 +1800,7 @@ static bool shada_pack_entry(msgpack_packer *const packer, msgpack_pack_uint64( spacker, (uint64_t) entry.data.buffer_list.buffers[i].pos.col); } - if (entry.data.buffer_list.buffers[i].additional_data != NULL) { - for (size_t j = 0; - j < entry.data.buffer_list.buffers[i].additional_data->size; - j++) { - msgpack_rpc_from_string( - entry.data.buffer_list.buffers[i].additional_data->items[j].key, - spacker); - msgpack_rpc_from_object( - entry.data.buffer_list.buffers[i].additional_data->items[j].value, - spacker); - } - } + DUMP_ADDITIONAL_DATA(entry.data.buffer_list.buffers[i].additional_data); } break; } @@ -1917,7 +1899,11 @@ static bool shada_pack_encoded_entry(msgpack_packer *const packer, } case kSDItemVariable: { if (sd_conv->vc_type != CONV_NONE) { - convert_object(sd_conv, &entry.data.data.global_var.value); + typval_T tgttv; + var_item_copy(sd_conv, &entry.data.data.global_var.value, &tgttv, + true, 0); + clear_tv(&entry.data.data.global_var.value); + entry.data.data.global_var.value = tgttv; } ret = shada_pack_entry(packer, entry.data, max_kbyte); break; @@ -2135,9 +2121,11 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, if (var_iter == NULL && vartv.v_type == VAR_UNKNOWN) { break; } - Object obj = vim_to_object(&vartv); + typval_T tgttv; if (sd_writer->sd_conv.vc_type != CONV_NONE) { - convert_object(&sd_writer->sd_conv, &obj); + var_item_copy(&sd_writer->sd_conv, &vartv, &tgttv, true, 0); + } else { + copy_tv(&vartv, &tgttv); } if (!shada_pack_entry(packer, (ShadaEntry) { .type = kSDItemVariable, @@ -2145,18 +2133,18 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, .data = { .global_var = { .name = (char *) name, - .value = obj, + .value = tgttv, .additional_elements = NULL, } } }, max_kbyte)) { - api_free_object(obj); clear_tv(&vartv); + clear_tv(&tgttv); ret = kSDWriteFailed; goto shada_write_exit; } - api_free_object(obj); clear_tv(&vartv); + clear_tv(&tgttv); int kh_ret; (void) kh_put(strset, &wms->dumped_variables, name, &kh_ret); } while (var_iter != NULL); @@ -2970,26 +2958,17 @@ static void shada_free_shada_entry(ShadaEntry *const entry) case kSDItemJump: case kSDItemGlobalMark: case kSDItemLocalMark: { - if (entry->data.filemark.additional_data != NULL) { - api_free_dictionary(*entry->data.filemark.additional_data); - xfree(entry->data.filemark.additional_data); - } + dict_unref(entry->data.filemark.additional_data); xfree(entry->data.filemark.fname); break; } case kSDItemSearchPattern: { - if (entry->data.search_pattern.additional_data != NULL) { - api_free_dictionary(*entry->data.search_pattern.additional_data); - xfree(entry->data.search_pattern.additional_data); - } + dict_unref(entry->data.search_pattern.additional_data); xfree(entry->data.search_pattern.pat); break; } case kSDItemRegister: { - if (entry->data.reg.additional_data != NULL) { - api_free_dictionary(*entry->data.reg.additional_data); - xfree(entry->data.reg.additional_data); - } + dict_unref(entry->data.reg.additional_data); for (size_t i = 0; i < entry->data.reg.contents_size; i++) { xfree(entry->data.reg.contents[i]); } @@ -2997,40 +2976,25 @@ static void shada_free_shada_entry(ShadaEntry *const entry) break; } case kSDItemHistoryEntry: { - if (entry->data.history_item.canfree) { - if (entry->data.history_item.additional_elements != NULL) { - api_free_array(*entry->data.history_item.additional_elements); - xfree(entry->data.history_item.additional_elements); - } - xfree(entry->data.history_item.string); - } + list_unref(entry->data.history_item.additional_elements); + xfree(entry->data.history_item.string); break; } case kSDItemVariable: { - if (entry->data.global_var.additional_elements != NULL) { - api_free_array(*entry->data.global_var.additional_elements); - xfree(entry->data.global_var.additional_elements); - } + list_unref(entry->data.global_var.additional_elements); xfree(entry->data.global_var.name); - api_free_object(entry->data.global_var.value); + clear_tv(&entry->data.global_var.value); break; } case kSDItemSubString: { - if (entry->data.sub_string.additional_elements != NULL) { - api_free_array(*entry->data.sub_string.additional_elements); - xfree(entry->data.sub_string.additional_elements); - } + list_unref(entry->data.sub_string.additional_elements); xfree(entry->data.sub_string.sub); break; } case kSDItemBufferList: { for (size_t i = 0; i < entry->data.buffer_list.size; i++) { xfree(entry->data.buffer_list.buffers[i].fname); - if (entry->data.buffer_list.buffers[i].additional_data != NULL) { - api_free_dictionary( - *entry->data.buffer_list.buffers[i].additional_data); - xfree(entry->data.buffer_list.buffers[i].additional_data); - } + dict_unref(entry->data.buffer_list.buffers[i].additional_data); } xfree(entry->data.buffer_list.buffers); break; @@ -3177,77 +3141,6 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, return kSDReadStatusSuccess; } -/// Convert all strings in one Object instance -/// -/// @param[in] sd_conv Conversion definition. -/// @param[in,out] obj Object to convert. -static void convert_object(const vimconv_T *const sd_conv, Object *const obj) - FUNC_ATTR_NONNULL_ALL -{ - kvec_t(Object *) toconv; - kv_init(toconv); - kv_push(Object *, toconv, obj); - while (kv_size(toconv)) { - Object *cur_obj = kv_pop(toconv); -#define CONVERT_STRING(str) \ - do { \ - if (!has_non_ascii((str).data)) { \ - break; \ - } \ - size_t len = (str).size; \ - char *const converted_string = string_convert(sd_conv, (str).data, \ - &len); \ - if (converted_string != NULL) { \ - xfree((str).data); \ - (str).data = converted_string; \ - (str).size = len; \ - } \ - } while (0) - switch (cur_obj->type) { - case kObjectTypeNil: - case kObjectTypeInteger: - case kObjectTypeBoolean: - case kObjectTypeFloat: { - break; - } - case kObjectTypeString: { - CONVERT_STRING(cur_obj->data.string); - break; - } - case kObjectTypeArray: { - for (size_t i = 0; i < cur_obj->data.array.size; i++) { - Object *element = &cur_obj->data.array.items[i]; - if (element->type == kObjectTypeDictionary - || element->type == kObjectTypeArray) { - kv_push(Object *, toconv, element); - } else if (element->type == kObjectTypeString) { - CONVERT_STRING(element->data.string); - } - } - break; - } - case kObjectTypeDictionary: { - for (size_t i = 0; i < cur_obj->data.dictionary.size; i++) { - CONVERT_STRING(cur_obj->data.dictionary.items[i].key); - Object *value = &cur_obj->data.dictionary.items[i].value; - if (value->type == kObjectTypeDictionary - || value->type == kObjectTypeArray) { - kv_push(Object *, toconv, value); - } else if (value->type == kObjectTypeString) { - CONVERT_STRING(value->data.string); - } - } - break; - } - default: { - assert(false); - } - } -#undef CONVERT_STRING - } - kv_destroy(toconv); -} - /// Convert or copy and return a string /// /// @param[in] sd_conv Conversion definition. @@ -3490,6 +3383,58 @@ shada_read_next_item_extra_bytes: ? get_converted_string(&sd_reader->sd_conv, (str), (len)) \ : xmemdupz((str), (len))) #define BIN_CONVERTED(b) CONVERTED(b.ptr, b.size) +#define SET_ADDITIONAL_DATA(tgt, name) \ + do { \ + if (ad_ga.ga_len) { \ + msgpack_object obj = { \ + .type = MSGPACK_OBJECT_MAP, \ + .via = { \ + .map = { \ + .size = (uint32_t) ad_ga.ga_len, \ + .ptr = ad_ga.ga_data, \ + } \ + } \ + }; \ + typval_T adtv; \ + if (msgpack_to_vim(obj, &adtv) == FAIL \ + || adtv.v_type != VAR_DICT) { \ + emsgu(_(RERR "Error while reading ShaDa file: " \ + name " entry at position %" PRIu64 " " \ + "cannot be converted to a VimL dictionary"), \ + (uint64_t) initial_fpos); \ + ga_clear(&ad_ga); \ + clear_tv(&adtv); \ + goto shada_read_next_item_error; \ + } \ + tgt = adtv.vval.v_dict; \ + } \ + ga_clear(&ad_ga); \ + } while (0) +#define SET_ADDITIONAL_ELEMENTS(src, src_maxsize, tgt, name) \ + do { \ + if ((src).size > (size_t) (src_maxsize)) { \ + msgpack_object obj = { \ + .type = MSGPACK_OBJECT_ARRAY, \ + .via = { \ + .array = { \ + .size = ((src).size - (uint32_t) (src_maxsize)), \ + .ptr = (src).ptr + (src_maxsize), \ + } \ + } \ + }; \ + typval_T aetv; \ + if (msgpack_to_vim(obj, &aetv) == FAIL) { \ + emsgu(_(RERR "Error while reading ShaDa file: " \ + name " entry at position %" PRIu64 " " \ + "cannot be converted to a VimL list"), \ + (uint64_t) initial_fpos); \ + clear_tv(&aetv); \ + goto shada_read_next_item_error; \ + } \ + assert(aetv.v_type == VAR_LIST); \ + (tgt) = aetv.vval.v_list; \ + } \ + } while (0) switch ((ShadaEntryType) type_u64) { case kSDItemHeader: { if (!msgpack_rpc_to_dictionary(&(unpacked.data), &(entry->data.header))) { @@ -3552,29 +3497,8 @@ shada_read_next_item_extra_bytes: ga_clear(&ad_ga); goto shada_read_next_item_error; } - if (ad_ga.ga_len) { - msgpack_object obj = { - .type = MSGPACK_OBJECT_MAP, - .via = { - .map = { - .size = (uint32_t) ad_ga.ga_len, - .ptr = ad_ga.ga_data, - } - } - }; - entry->data.search_pattern.additional_data = - xmalloc(sizeof(Dictionary)); - if (!msgpack_rpc_to_dictionary( - &obj, entry->data.search_pattern.additional_data)) { - emsgu(_(RERR "Error while reading ShaDa file: " - "search pattern entry at position %" PRIu64 " " - "cannot be converted to a Dictionary"), - (uint64_t) initial_fpos); - ga_clear(&ad_ga); - goto shada_read_next_item_error; - } - } - ga_clear(&ad_ga); + SET_ADDITIONAL_DATA(entry->data.search_pattern.additional_data, + "search pattern"); break; } case kSDItemChange: @@ -3643,28 +3567,7 @@ shada_read_next_item_extra_bytes: ga_clear(&ad_ga); goto shada_read_next_item_error; } - if (ad_ga.ga_len) { - msgpack_object obj = { - .type = MSGPACK_OBJECT_MAP, - .via = { - .map = { - .size = (uint32_t) ad_ga.ga_len, - .ptr = ad_ga.ga_data, - } - } - }; - entry->data.filemark.additional_data = xmalloc(sizeof(Dictionary)); - if (!msgpack_rpc_to_dictionary( - &obj, entry->data.filemark.additional_data)) { - emsgu(_(RERR "Error while reading ShaDa file: " - "mark entry at position %" PRIu64 " " - "cannot be converted to a Dictionary"), - (uint64_t) initial_fpos); - ga_clear(&ad_ga); - goto shada_read_next_item_error; - } - } - ga_clear(&ad_ga); + SET_ADDITIONAL_DATA(entry->data.filemark.additional_data, "mark"); break; } case kSDItemRegister: { @@ -3738,28 +3641,7 @@ shada_read_next_item_extra_bytes: ga_clear(&ad_ga); goto shada_read_next_item_error; } - if (ad_ga.ga_len) { - msgpack_object obj = { - .type = MSGPACK_OBJECT_MAP, - .via = { - .map = { - .size = (uint32_t) ad_ga.ga_len, - .ptr = ad_ga.ga_data, - } - } - }; - entry->data.reg.additional_data = xmalloc(sizeof(Dictionary)); - if (!msgpack_rpc_to_dictionary( - &obj, entry->data.reg.additional_data)) { - emsgu(_(RERR "Error while reading ShaDa file: " - "register entry at position %" PRIu64 " " - "cannot be converted to a Dictionary"), - (uint64_t) initial_fpos); - ga_clear(&ad_ga); - goto shada_read_next_item_error; - } - } - ga_clear(&ad_ga); + SET_ADDITIONAL_DATA(entry->data.reg.additional_data, "register"); break; } case kSDItemHistoryEntry: { @@ -3859,27 +3741,9 @@ shada_read_next_item_hist_no_conv: entry->data.history_item.string[strsize - 2] = 0; entry->data.history_item.string[strsize - 1] = entry->data.history_item.sep; - if (unpacked.data.via.array.size > (size_t) (2 + is_hist_search)) { - msgpack_object obj = { - .type = MSGPACK_OBJECT_ARRAY, - .via = { - .array = { - .size = (unpacked.data.via.array.size - - (uint32_t) (2 + is_hist_search)), - .ptr = unpacked.data.via.array.ptr + (2 + is_hist_search), - } - } - }; - entry->data.history_item.additional_elements = xmalloc(sizeof(Array)); - if (!msgpack_rpc_to_array( - &obj, entry->data.history_item.additional_elements)) { - emsgu(_(RERR "Error while reading ShaDa file: " - "history entry at position %" PRIu64 " " - "cannot be converted to an Array"), - (uint64_t) initial_fpos); - goto shada_read_next_item_error; - } - } + SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, (2 + is_hist_search), + entry->data.history_item.additional_elements, + "history"); break; } case kSDItemVariable: { @@ -3893,7 +3757,7 @@ shada_read_next_item_hist_no_conv: entry->data.global_var = (struct global_var) { .name = NULL, .value = { - .type = kObjectTypeNil, + .v_type = VAR_UNKNOWN, }, .additional_elements = NULL }; @@ -3922,37 +3786,27 @@ shada_read_next_item_hist_no_conv: entry->data.global_var.name = xmemdupz(unpacked.data.via.array.ptr[0].via.bin.ptr, unpacked.data.via.array.ptr[0].via.bin.size); - if (!msgpack_rpc_to_object(&(unpacked.data.via.array.ptr[1]), - &(entry->data.global_var.value))) { + if (msgpack_to_vim(unpacked.data.via.array.ptr[1], + &(entry->data.global_var.value)) == FAIL) { emsgu(_(RERR "Error while reading ShaDa file: " "variable entry at position %" PRIu64 " " - "has value that cannot be converted to the object"), + "has value that cannot be converted to the VimL value"), (uint64_t) initial_fpos); goto shada_read_next_item_error; } if (sd_reader->sd_conv.vc_type != CONV_NONE) { - convert_object(&sd_reader->sd_conv, &entry->data.global_var.value); - } - if (unpacked.data.via.array.size > 2) { - msgpack_object obj = { - .type = MSGPACK_OBJECT_ARRAY, - .via = { - .array = { - .size = unpacked.data.via.array.size - 2, - .ptr = unpacked.data.via.array.ptr + 2, - } - } - }; - entry->data.global_var.additional_elements = xmalloc(sizeof(Array)); - if (!msgpack_rpc_to_array( - &obj, entry->data.global_var.additional_elements)) { - emsgu(_(RERR "Error while reading ShaDa file: " - "variable entry at position %" PRIu64 " " - "cannot be converted to an Array"), - (uint64_t) initial_fpos); - goto shada_read_next_item_error; - } - } + typval_T tgttv; + var_item_copy(&sd_reader->sd_conv, + &entry->data.global_var.value, + &tgttv, + true, + 0); + clear_tv(&entry->data.global_var.value); + entry->data.global_var.value = tgttv; + } + SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2, + entry->data.global_var.additional_elements, + "variable"); break; } case kSDItemSubString: { @@ -3983,26 +3837,9 @@ shada_read_next_item_hist_no_conv: } entry->data.sub_string.sub = BIN_CONVERTED(unpacked.data.via.array.ptr[0].via.bin); - if (unpacked.data.via.array.size > 1) { - msgpack_object obj = { - .type = MSGPACK_OBJECT_ARRAY, - .via = { - .array = { - .size = unpacked.data.via.array.size - 1, - .ptr = unpacked.data.via.array.ptr + 1, - } - } - }; - entry->data.sub_string.additional_elements = xmalloc(sizeof(Array)); - if (!msgpack_rpc_to_array( - &obj, entry->data.sub_string.additional_elements)) { - emsgu(_(RERR "Error while reading ShaDa file: " - "sub string entry at position %" PRIu64 " " - "cannot be converted to an Array"), - (uint64_t) initial_fpos); - goto shada_read_next_item_error; - } - } + SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 1, + entry->data.sub_string.additional_elements, + "sub string"); break; } case kSDItemBufferList: { @@ -4079,30 +3916,9 @@ shada_read_next_item_hist_no_conv: ga_clear(&ad_ga); goto shada_read_next_item_error; } - if (ad_ga.ga_len) { - msgpack_object obj = { - .type = MSGPACK_OBJECT_MAP, - .via = { - .map = { - .size = (uint32_t) ad_ga.ga_len, - .ptr = ad_ga.ga_data, - } - } - }; - entry->data.buffer_list.buffers[i].additional_data = - xmalloc(sizeof(Dictionary)); - if (!msgpack_rpc_to_dictionary( - &obj, entry->data.buffer_list.buffers[i].additional_data)) { - emsgu(_(RERR "Error while reading ShaDa file: " - "buffer list at position %" PRIu64 " " - "contains entry that cannot be converted " - "to a Dictionary"), - (uint64_t) initial_fpos); - ga_clear(&ad_ga); - goto shada_read_next_item_error; - } - } - ga_clear(&ad_ga); + SET_ADDITIONAL_DATA( + entry->data.buffer_list.buffers[i].additional_data, + "buffer list entry"); } } break; @@ -4132,6 +3948,8 @@ shada_read_next_item_hist_no_conv: #undef LONG_KEY #undef TOU8 #undef TOSIZE +#undef SET_ADDITIONAL_DATA +#undef SET_ADDITIONAL_ELEMENTS shada_read_next_item_error: msgpack_unpacked_destroy(&unpacked); xfree(buf); diff --git a/src/nvim/undo.c b/src/nvim/undo.c index a04e7c2763..b2f71432dc 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -111,7 +111,6 @@ #include "nvim/types.h" #include "nvim/os/os.h" #include "nvim/os/time.h" -#include "nvim/api/private/helpers.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "undo.c.generated.h" @@ -329,11 +328,8 @@ static long get_undolevel(void) static inline void zero_fmark_additional_data(fmark_T *fmarks) { for (size_t i = 0; i < NMARKS; i++) { - if (fmarks[i].additional_data != NULL) { - api_free_dictionary(*fmarks[i].additional_data); - free(fmarks[i].additional_data); - fmarks[i].additional_data = NULL; - } + dict_unref(fmarks[i].additional_data); + fmarks[i].additional_data = NULL; } } |