mirror of
https://github.com/neovim/neovim.git
synced 2025-09-25 04:28:33 +00:00
*: Make ShaDa code use VimL values for additional_\* data
This commit is contained in:
@@ -30,7 +30,6 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
#include "nvim/api/private/handle.h"
|
#include "nvim/api/private/handle.h"
|
||||||
#include "nvim/api/private/helpers.h"
|
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
#include "nvim/vim.h"
|
#include "nvim/vim.h"
|
||||||
#include "nvim/buffer.h"
|
#include "nvim/buffer.h"
|
||||||
@@ -557,10 +556,7 @@ static void free_buffer(buf_T *buf)
|
|||||||
free_buffer_stuff(buf, TRUE);
|
free_buffer_stuff(buf, TRUE);
|
||||||
unref_var_dict(buf->b_vars);
|
unref_var_dict(buf->b_vars);
|
||||||
aubuflocal_remove(buf);
|
aubuflocal_remove(buf);
|
||||||
if (buf->additional_data != NULL) {
|
dict_unref(buf->additional_data);
|
||||||
api_free_dictionary(*buf->additional_data);
|
|
||||||
xfree(buf->additional_data);
|
|
||||||
}
|
|
||||||
free_fmark(buf->b_last_cursor);
|
free_fmark(buf->b_last_cursor);
|
||||||
free_fmark(buf->b_last_insert);
|
free_fmark(buf->b_last_insert);
|
||||||
free_fmark(buf->b_last_change);
|
free_fmark(buf->b_last_change);
|
||||||
|
@@ -26,7 +26,7 @@ typedef struct file_buffer buf_T; // Forward declaration
|
|||||||
#include "nvim/eval_defs.h"
|
#include "nvim/eval_defs.h"
|
||||||
// for proftime_T
|
// for proftime_T
|
||||||
#include "nvim/profile.h"
|
#include "nvim/profile.h"
|
||||||
// for String and Dictionary
|
// for String
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/api/private/defs.h"
|
||||||
|
|
||||||
#define MODIFIABLE(buf) (!buf->terminal && buf->b_p_ma)
|
#define MODIFIABLE(buf) (!buf->terminal && buf->b_p_ma)
|
||||||
@@ -749,7 +749,7 @@ struct file_buffer {
|
|||||||
|
|
||||||
Terminal *terminal; // Terminal instance associated with the 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.
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
140
src/nvim/eval.c
140
src/nvim/eval.c
@@ -107,18 +107,6 @@
|
|||||||
#define AUTOLOAD_CHAR '#' /* Character used as separator in autoload
|
#define AUTOLOAD_CHAR '#' /* Character used as separator in autoload
|
||||||
function/variable names. */
|
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().
|
* Structure returned by get_lval() and used by set_var_lval().
|
||||||
* For a plain name:
|
* For a plain name:
|
||||||
@@ -5352,7 +5340,7 @@ static int list_concat(list_T *l1, list_T *l2, typval_T *tv)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
/* make a copy of the first list. */
|
/* make a copy of the first list. */
|
||||||
l = list_copy(l1, FALSE, 0);
|
l = list_copy(NULL, l1, FALSE, 0);
|
||||||
if (l == NULL)
|
if (l == NULL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
tv->v_type = VAR_LIST;
|
tv->v_type = VAR_LIST;
|
||||||
@@ -5363,13 +5351,20 @@ static int list_concat(list_T *l1, list_T *l2, typval_T *tv)
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Make a copy of list
|
||||||
* Make a copy of list "orig". Shallow if "deep" is FALSE.
|
///
|
||||||
* The refcount of the new list is set to 1.
|
/// @param[in] conv If non-NULL, then all internal strings will be converted.
|
||||||
* See item_copy() for "copyID".
|
/// @param[in] orig Original list to copy.
|
||||||
* Returns NULL if orig is NULL or some failure happens.
|
/// @param[in] deep If false, then shallow copy will be done.
|
||||||
*/
|
/// @param[in] copyID See var_item_copy().
|
||||||
static list_T *list_copy(list_T *orig, int deep, int copyID)
|
///
|
||||||
|
/// @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 *item;
|
||||||
listitem_T *ni;
|
listitem_T *ni;
|
||||||
@@ -5388,7 +5383,7 @@ static list_T *list_copy(list_T *orig, int deep, int copyID)
|
|||||||
item = item->li_next) {
|
item = item->li_next) {
|
||||||
ni = listitem_alloc();
|
ni = listitem_alloc();
|
||||||
if (deep) {
|
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);
|
xfree(ni);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5964,13 +5959,20 @@ void dictitem_free(dictitem_T *item)
|
|||||||
xfree(item);
|
xfree(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Make a copy of dictionary
|
||||||
* Make a copy of dict "d". Shallow if "deep" is FALSE.
|
///
|
||||||
* The refcount of the new dict is set to 1.
|
/// @param[in] conv If non-NULL, then all internal strings will be converted.
|
||||||
* See item_copy() for "copyID".
|
/// @param[in] orig Original dictionary to copy.
|
||||||
* Returns NULL if orig is NULL or some other failure.
|
/// @param[in] deep If false, then shallow copy will be done.
|
||||||
*/
|
/// @param[in] copyID See var_item_copy().
|
||||||
static dict_T *dict_copy(dict_T *orig, int deep, int copyID)
|
///
|
||||||
|
/// @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;
|
dictitem_T *di;
|
||||||
int todo;
|
int todo;
|
||||||
@@ -5990,9 +5992,20 @@ static dict_T *dict_copy(dict_T *orig, int deep, int copyID)
|
|||||||
if (!HASHITEM_EMPTY(hi)) {
|
if (!HASHITEM_EMPTY(hi)) {
|
||||||
--todo;
|
--todo;
|
||||||
|
|
||||||
|
if (conv == NULL || conv->vc_type == CONV_NONE) {
|
||||||
di = dictitem_alloc(hi->hi_key);
|
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 (deep) {
|
||||||
if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep,
|
if (var_item_copy(conv, &HI2DI(hi)->di_tv, &di->di_tv, deep,
|
||||||
copyID) == FAIL) {
|
copyID) == FAIL) {
|
||||||
xfree(di);
|
xfree(di);
|
||||||
break;
|
break;
|
||||||
@@ -6305,7 +6318,7 @@ failret:
|
|||||||
/// the results.
|
/// the results.
|
||||||
/// @param firstargname Name of the first argument.
|
/// @param firstargname Name of the first argument.
|
||||||
/// @param name Name of the target converter.
|
/// @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, \
|
static int name##_convert_one_value(firstargtype firstargname, \
|
||||||
MPConvStack *const mpstack, \
|
MPConvStack *const mpstack, \
|
||||||
typval_T *const tv, \
|
typval_T *const tv, \
|
||||||
@@ -6543,7 +6556,7 @@ name##_convert_one_value_regular_dict: \
|
|||||||
return OK; \
|
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 \
|
FUNC_ATTR_WARN_UNUSED_RESULT \
|
||||||
{ \
|
{ \
|
||||||
current_copyID += COPYID_INC; \
|
current_copyID += COPYID_INC; \
|
||||||
@@ -6739,7 +6752,7 @@ vim_to_msgpack_error_ret: \
|
|||||||
|
|
||||||
#define CONV_ALLOW_SPECIAL false
|
#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
|
#undef CONV_RECURSE
|
||||||
#define CONV_RECURSE(val, conv_type) \
|
#define CONV_RECURSE(val, conv_type) \
|
||||||
@@ -6769,7 +6782,7 @@ DEFINE_VIML_CONV_FUNCTIONS(string, garray_T *const, gap)
|
|||||||
return OK; \
|
return OK; \
|
||||||
} while (0)
|
} 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_STRING
|
||||||
#undef CONV_STR_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)
|
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));
|
EMSG(_(e_invarg));
|
||||||
else {
|
else {
|
||||||
current_copyID += COPYID_INC;
|
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 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_STRING
|
||||||
#undef CONV_STR_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
|
/// 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
|
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
|
||||||
{
|
{
|
||||||
#define INIT_SPECIAL_DICT(tv, type, val) \
|
#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
|
||||||
* Make a copy of an item.
|
///
|
||||||
* Lists and Dictionaries are also copied. A deep copy if "deep" is set.
|
/// Lists and Dictionaries are also copied.
|
||||||
* 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.
|
/// @param[in] conv If not NULL, convert all copied strings.
|
||||||
* Returns FAIL or OK.
|
/// @param[in] from Value to copy.
|
||||||
*/
|
/// @param[out] to Location where to copy to.
|
||||||
static int item_copy(typval_T *from, typval_T *to, int deep, int copyID)
|
/// @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;
|
static int recurse = 0;
|
||||||
int ret = OK;
|
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) {
|
switch (from->v_type) {
|
||||||
case VAR_NUMBER:
|
case VAR_NUMBER:
|
||||||
case VAR_FLOAT:
|
case VAR_FLOAT:
|
||||||
case VAR_STRING:
|
|
||||||
case VAR_FUNC:
|
case VAR_FUNC:
|
||||||
copy_tv(from, to);
|
copy_tv(from, to);
|
||||||
break;
|
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:
|
case VAR_LIST:
|
||||||
to->v_type = VAR_LIST;
|
to->v_type = VAR_LIST;
|
||||||
to->v_lock = 0;
|
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 = from->vval.v_list->lv_copylist;
|
||||||
++to->vval.v_list->lv_refcount;
|
++to->vval.v_list->lv_refcount;
|
||||||
} else
|
} 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)
|
if (to->vval.v_list == NULL)
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
break;
|
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 = from->vval.v_dict->dv_copydict;
|
||||||
++to->vval.v_dict->dv_refcount;
|
++to->vval.v_dict->dv_refcount;
|
||||||
} else
|
} 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)
|
if (to->vval.v_dict == NULL)
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
EMSG2(_(e_intern2), "item_copy()");
|
EMSG2(_(e_intern2), "var_item_copy()");
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
}
|
}
|
||||||
--recurse;
|
--recurse;
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
#ifndef NVIM_EVAL_H
|
#ifndef NVIM_EVAL_H
|
||||||
#define NVIM_EVAL_H
|
#define NVIM_EVAL_H
|
||||||
|
|
||||||
|
#include <msgpack.h>
|
||||||
|
|
||||||
#include "nvim/profile.h"
|
#include "nvim/profile.h"
|
||||||
|
|
||||||
/* Defines for Vim variables. These must match vimvars[] in eval.c! */
|
/* Defines for Vim variables. These must match vimvars[] in eval.c! */
|
||||||
@@ -72,6 +74,8 @@ enum {
|
|||||||
/// Maximum number of function arguments
|
/// Maximum number of function arguments
|
||||||
#define MAX_FUNC_ARGS 20
|
#define MAX_FUNC_ARGS 20
|
||||||
|
|
||||||
|
int vim_to_msgpack(msgpack_packer *const, typval_T *const);
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "eval.h.generated.h"
|
# include "eval.h.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
#define NVIM_EVAL_DEFS_H
|
#define NVIM_EVAL_DEFS_H
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "nvim/hashtab.h"
|
#include "nvim/hashtab.h"
|
||||||
|
|
||||||
@@ -132,4 +133,16 @@ typedef struct list_stack_S {
|
|||||||
struct list_stack_S *prev;
|
struct list_stack_S *prev;
|
||||||
} list_stack_T;
|
} 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
|
#endif // NVIM_EVAL_DEFS_H
|
||||||
|
@@ -68,8 +68,6 @@
|
|||||||
#include "nvim/os/shell.h"
|
#include "nvim/os/shell.h"
|
||||||
#include "nvim/os/input.h"
|
#include "nvim/os/input.h"
|
||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
#include "nvim/api/private/defs.h"
|
|
||||||
#include "nvim/api/private/helpers.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Struct to hold the sign properties.
|
* Struct to hold the sign properties.
|
||||||
@@ -2846,10 +2844,7 @@ void sub_set_replacement(SubReplacementString sub)
|
|||||||
{
|
{
|
||||||
xfree(old_sub.sub);
|
xfree(old_sub.sub);
|
||||||
if (sub.additional_elements != old_sub.additional_elements) {
|
if (sub.additional_elements != old_sub.additional_elements) {
|
||||||
if (old_sub.additional_elements != NULL) {
|
list_unref(old_sub.additional_elements);
|
||||||
api_free_array(*old_sub.additional_elements);
|
|
||||||
xfree(old_sub.additional_elements);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
old_sub = sub;
|
old_sub = sub;
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/eval_defs.h"
|
||||||
|
|
||||||
/* flags for do_ecmd() */
|
/* flags for do_ecmd() */
|
||||||
#define ECMD_HIDE 0x01 /* don't free the current buffer */
|
#define ECMD_HIDE 0x01 /* don't free the current buffer */
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
char *sub; ///< Previous replacement string.
|
char *sub; ///< Previous replacement string.
|
||||||
Timestamp timestamp; ///< Time when it was last set.
|
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;
|
} SubReplacementString;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
|
@@ -66,8 +66,6 @@
|
|||||||
#include "nvim/os/os.h"
|
#include "nvim/os/os.h"
|
||||||
#include "nvim/event/loop.h"
|
#include "nvim/event/loop.h"
|
||||||
#include "nvim/os/time.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.
|
* Variables shared between getcmdline(), redrawcmdline() and others.
|
||||||
@@ -4252,10 +4250,7 @@ static inline void hist_free_entry(histentry_T *hisptr)
|
|||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
xfree(hisptr->hisstr);
|
xfree(hisptr->hisstr);
|
||||||
if (hisptr->additional_elements != NULL) {
|
list_unref(hisptr->additional_elements);
|
||||||
api_free_array(*hisptr->additional_elements);
|
|
||||||
xfree(hisptr->additional_elements);
|
|
||||||
}
|
|
||||||
clear_hist_entry(hisptr);
|
clear_hist_entry(hisptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#ifndef NVIM_EX_GETLN_H
|
#ifndef NVIM_EX_GETLN_H
|
||||||
#define NVIM_EX_GETLN_H
|
#define NVIM_EX_GETLN_H
|
||||||
|
|
||||||
|
#include "nvim/eval_defs.h"
|
||||||
#include "nvim/ex_cmds.h"
|
#include "nvim/ex_cmds.h"
|
||||||
|
|
||||||
/* Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. */
|
/* Values for nextwild() and ExpandOne(). See ExpandOne() for meaning. */
|
||||||
@@ -40,7 +41,7 @@ typedef struct hist_entry {
|
|||||||
int hisnum; ///< Entry identifier number.
|
int hisnum; ///< Entry identifier number.
|
||||||
char_u *hisstr; ///< Actual entry, separator char after the NUL.
|
char_u *hisstr; ///< Actual entry, separator char after the NUL.
|
||||||
Timestamp timestamp; ///< Time when entry was added.
|
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;
|
} histentry_T;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
|
@@ -41,8 +41,6 @@
|
|||||||
#include "nvim/os/os.h"
|
#include "nvim/os/os.h"
|
||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
#include "nvim/os/input.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.
|
* This file contains routines to maintain and manipulate marks.
|
||||||
@@ -74,11 +72,8 @@ int setmark(int c)
|
|||||||
/// Free fmark_T item
|
/// Free fmark_T item
|
||||||
void free_fmark(fmark_T fm)
|
void free_fmark(fmark_T fm)
|
||||||
{
|
{
|
||||||
if (fm.additional_data != NULL) {
|
dict_unref(fm.additional_data);
|
||||||
api_free_dictionary(*fm.additional_data);
|
|
||||||
free(fm.additional_data);
|
|
||||||
fm.additional_data = NULL;
|
fm.additional_data = NULL;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Free xfmark_T item
|
/// Free xfmark_T item
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "nvim/pos.h"
|
#include "nvim/pos.h"
|
||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/eval_defs.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* marks: positions in a file
|
* marks: positions in a file
|
||||||
@@ -36,7 +36,7 @@ typedef struct filemark {
|
|||||||
pos_T mark; ///< Cursor position.
|
pos_T mark; ///< Cursor position.
|
||||||
int fnum; ///< File number.
|
int fnum; ///< File number.
|
||||||
Timestamp timestamp; ///< Time when this mark was last set.
|
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;
|
} fmark_T;
|
||||||
|
|
||||||
/// Structure defining extended mark (mark with file name attached)
|
/// Structure defining extended mark (mark with file name attached)
|
||||||
|
@@ -51,8 +51,6 @@
|
|||||||
#include "nvim/window.h"
|
#include "nvim/window.h"
|
||||||
#include "nvim/os/input.h"
|
#include "nvim/os/input.h"
|
||||||
#include "nvim/os/time.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];
|
static yankreg_T y_regs[NUM_REGISTERS];
|
||||||
|
|
||||||
@@ -869,17 +867,13 @@ int do_record(int c)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_yreg_additional_data(yankreg_T *reg,
|
static void set_yreg_additional_data(yankreg_T *reg, dict_T *additional_data)
|
||||||
Dictionary *additional_data)
|
|
||||||
FUNC_ATTR_NONNULL_ARG(1)
|
FUNC_ATTR_NONNULL_ARG(1)
|
||||||
{
|
{
|
||||||
if (reg->additional_data == additional_data) {
|
if (reg->additional_data == additional_data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (reg->additional_data != NULL) {
|
dict_unref(reg->additional_data);
|
||||||
api_free_dictionary(*reg->additional_data);
|
|
||||||
free(reg->additional_data);
|
|
||||||
}
|
|
||||||
reg->additional_data = additional_data;
|
reg->additional_data = additional_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
#include "nvim/macros.h"
|
#include "nvim/macros.h"
|
||||||
#include "nvim/ascii.h"
|
#include "nvim/ascii.h"
|
||||||
#include "nvim/types.h"
|
#include "nvim/types.h"
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/eval_defs.h"
|
||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
|
|
||||||
typedef int (*Indenter)(void);
|
typedef int (*Indenter)(void);
|
||||||
@@ -81,7 +81,7 @@ typedef struct yankreg {
|
|||||||
char_u y_type; ///< Register type: MLINE, MCHAR or MBLOCK.
|
char_u y_type; ///< Register type: MLINE, MCHAR or MBLOCK.
|
||||||
colnr_T y_width; ///< Register width (only valid for y_type == MBLOCK).
|
colnr_T y_width; ///< Register width (only valid for y_type == MBLOCK).
|
||||||
Timestamp timestamp; ///< Time when register was last modified.
|
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;
|
} yankreg_T;
|
||||||
|
|
||||||
/// Convert register name into register index
|
/// Convert register name into register index
|
||||||
|
@@ -51,7 +51,6 @@
|
|||||||
#include "nvim/ui.h"
|
#include "nvim/ui.h"
|
||||||
#include "nvim/window.h"
|
#include "nvim/window.h"
|
||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
#include "nvim/api/private/helpers.h"
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
@@ -292,10 +291,7 @@ void restore_search_patterns(void)
|
|||||||
static inline void free_spat(struct spat *const spat)
|
static inline void free_spat(struct spat *const spat)
|
||||||
{
|
{
|
||||||
xfree(spat->pat);
|
xfree(spat->pat);
|
||||||
if (spat->additional_data != NULL) {
|
dict_unref(spat->additional_data);
|
||||||
api_free_dictionary(*spat->additional_data);
|
|
||||||
xfree(spat->additional_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(EXITFREE)
|
#if defined(EXITFREE)
|
||||||
|
@@ -60,7 +60,7 @@ typedef struct spat {
|
|||||||
bool no_scs; ///< No smartcase for this pattern.
|
bool no_scs; ///< No smartcase for this pattern.
|
||||||
Timestamp timestamp; ///< Time of the last change.
|
Timestamp timestamp; ///< Time of the last change.
|
||||||
SearchOffset off; ///< Pattern offset.
|
SearchOffset off; ///< Pattern offset.
|
||||||
Dictionary *additional_data; ///< Additional data from ShaDa file.
|
dict_T *additional_data; ///< Additional data from ShaDa file.
|
||||||
} SearchPattern;
|
} SearchPattern;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
|
522
src/nvim/shada.c
522
src/nvim/shada.c
@@ -287,7 +287,7 @@ typedef struct {
|
|||||||
char name;
|
char name;
|
||||||
pos_T mark;
|
pos_T mark;
|
||||||
char *fname;
|
char *fname;
|
||||||
Dictionary *additional_data;
|
dict_T *additional_data;
|
||||||
} filemark;
|
} filemark;
|
||||||
struct search_pattern {
|
struct search_pattern {
|
||||||
bool magic;
|
bool magic;
|
||||||
@@ -299,14 +299,13 @@ typedef struct {
|
|||||||
bool is_substitute_pattern;
|
bool is_substitute_pattern;
|
||||||
bool highlighted;
|
bool highlighted;
|
||||||
char *pat;
|
char *pat;
|
||||||
Dictionary *additional_data;
|
dict_T *additional_data;
|
||||||
} search_pattern;
|
} search_pattern;
|
||||||
struct history_item {
|
struct history_item {
|
||||||
uint8_t histtype;
|
uint8_t histtype;
|
||||||
char *string;
|
char *string;
|
||||||
char sep;
|
char sep;
|
||||||
bool canfree;
|
list_T *additional_elements;
|
||||||
Array *additional_elements;
|
|
||||||
} history_item;
|
} history_item;
|
||||||
struct reg {
|
struct reg {
|
||||||
char name;
|
char name;
|
||||||
@@ -314,12 +313,12 @@ typedef struct {
|
|||||||
char **contents;
|
char **contents;
|
||||||
size_t contents_size;
|
size_t contents_size;
|
||||||
size_t width;
|
size_t width;
|
||||||
Dictionary *additional_data;
|
dict_T *additional_data;
|
||||||
} reg;
|
} reg;
|
||||||
struct global_var {
|
struct global_var {
|
||||||
char *name;
|
char *name;
|
||||||
Object value;
|
typval_T value;
|
||||||
Array *additional_elements;
|
list_T *additional_elements;
|
||||||
} global_var;
|
} global_var;
|
||||||
struct {
|
struct {
|
||||||
uint64_t type;
|
uint64_t type;
|
||||||
@@ -328,14 +327,14 @@ typedef struct {
|
|||||||
} unknown_item;
|
} unknown_item;
|
||||||
struct sub_string {
|
struct sub_string {
|
||||||
char *sub;
|
char *sub;
|
||||||
Array *additional_elements;
|
list_T *additional_elements;
|
||||||
} sub_string;
|
} sub_string;
|
||||||
struct buffer_list {
|
struct buffer_list {
|
||||||
size_t size;
|
size_t size;
|
||||||
struct buffer_list_buffer {
|
struct buffer_list_buffer {
|
||||||
pos_T pos;
|
pos_T pos;
|
||||||
char *fname;
|
char *fname;
|
||||||
Dictionary *additional_data;
|
dict_T *additional_data;
|
||||||
} *buffers;
|
} *buffers;
|
||||||
} buffer_list;
|
} buffer_list;
|
||||||
} data;
|
} data;
|
||||||
@@ -899,7 +898,6 @@ static const void *shada_hist_iter(const void *const iter,
|
|||||||
? (char) hist_he.hisstr[STRLEN(hist_he.hisstr) + 1]
|
? (char) hist_he.hisstr[STRLEN(hist_he.hisstr) + 1]
|
||||||
: 0),
|
: 0),
|
||||||
.additional_elements = hist_he.additional_elements,
|
.additional_elements = hist_he.additional_elements,
|
||||||
.canfree = zero,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1254,17 +1252,9 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemVariable: {
|
case kSDItemVariable: {
|
||||||
typval_T vartv;
|
var_set_global(cur_entry.data.global_var.name,
|
||||||
Error err;
|
cur_entry.data.global_var.value);
|
||||||
if (!object_to_vim(cur_entry.data.global_var.value, &vartv, &err)) {
|
cur_entry.data.global_var.value.v_type = VAR_UNKNOWN;
|
||||||
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);
|
|
||||||
shada_free_shada_entry(&cur_entry);
|
shada_free_shada_entry(&cur_entry);
|
||||||
break;
|
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);
|
cur_entry.data.buffer_list.buffers[i].pos, 0);
|
||||||
buflist_setfpos(buf, curwin, buf->b_last_cursor.mark.lnum,
|
buflist_setfpos(buf, curwin, buf->b_last_cursor.mark.lnum,
|
||||||
buf->b_last_cursor.mark.col, false);
|
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);
|
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
|
/// @param[in] max_kbyte Maximum size of an item in KiB. Zero means no
|
||||||
/// restrictions.
|
/// restrictions.
|
||||||
static bool shada_pack_entry(msgpack_packer *const packer,
|
static bool shada_pack_entry(msgpack_packer *const packer,
|
||||||
const ShadaEntry entry,
|
ShadaEntry entry,
|
||||||
const size_t max_kbyte)
|
const size_t max_kbyte)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
msgpack_sbuffer sbuf;
|
msgpack_sbuffer sbuf;
|
||||||
msgpack_sbuffer_init(&sbuf);
|
msgpack_sbuffer_init(&sbuf);
|
||||||
msgpack_packer *spacker = msgpack_packer_new(&sbuf, &msgpack_sbuffer_write);
|
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) {
|
switch (entry.type) {
|
||||||
case kSDItemMissing: {
|
case kSDItemMissing: {
|
||||||
assert(false);
|
assert(false);
|
||||||
@@ -1591,10 +1613,10 @@ static bool shada_pack_entry(msgpack_packer *const packer,
|
|||||||
case kSDItemHistoryEntry: {
|
case kSDItemHistoryEntry: {
|
||||||
const bool is_hist_search =
|
const bool is_hist_search =
|
||||||
entry.data.history_item.histtype == 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
|
entry.data.history_item.additional_elements == NULL
|
||||||
? 0
|
? 0
|
||||||
: entry.data.history_item.additional_elements->size);
|
: entry.data.history_item.additional_elements->lv_len);
|
||||||
msgpack_pack_array(spacker, arr_size);
|
msgpack_pack_array(spacker, arr_size);
|
||||||
msgpack_pack_uint8(spacker, entry.data.history_item.histtype);
|
msgpack_pack_uint8(spacker, entry.data.history_item.histtype);
|
||||||
msgpack_rpc_from_string(cstr_as_string(entry.data.history_item.string),
|
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) {
|
if (is_hist_search) {
|
||||||
msgpack_pack_uint8(spacker, (uint8_t) entry.data.history_item.sep);
|
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++) {
|
DUMP_ADDITIONAL_ELEMENTS(entry.data.history_item.additional_elements);
|
||||||
msgpack_rpc_from_object(
|
|
||||||
entry.data.history_item.additional_elements->items[i], spacker);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemVariable: {
|
case kSDItemVariable: {
|
||||||
const size_t arr_size = 2 + (
|
const size_t arr_size = 2 + (size_t) (
|
||||||
entry.data.global_var.additional_elements == NULL
|
entry.data.global_var.additional_elements == NULL
|
||||||
? 0
|
? 0
|
||||||
: entry.data.global_var.additional_elements->size);
|
: entry.data.global_var.additional_elements->lv_len);
|
||||||
msgpack_pack_array(spacker, arr_size);
|
msgpack_pack_array(spacker, arr_size);
|
||||||
msgpack_rpc_from_string(cstr_as_string(entry.data.global_var.name),
|
msgpack_rpc_from_string(cstr_as_string(entry.data.global_var.name),
|
||||||
spacker);
|
spacker);
|
||||||
msgpack_rpc_from_object(entry.data.global_var.value, spacker);
|
if (vim_to_msgpack(spacker, &entry.data.global_var.value) == FAIL) {
|
||||||
for (size_t i = 0; i < arr_size - 2; i++) {
|
return false;
|
||||||
msgpack_rpc_from_object(
|
|
||||||
entry.data.global_var.additional_elements->items[i], spacker);
|
|
||||||
}
|
}
|
||||||
|
DUMP_ADDITIONAL_ELEMENTS(entry.data.global_var.additional_elements);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemSubString: {
|
case kSDItemSubString: {
|
||||||
const size_t arr_size = 1 + (
|
const size_t arr_size = 1 + (size_t) (
|
||||||
entry.data.sub_string.additional_elements == NULL
|
entry.data.sub_string.additional_elements == NULL
|
||||||
? 0
|
? 0
|
||||||
: entry.data.sub_string.additional_elements->size);
|
: entry.data.sub_string.additional_elements->lv_len);
|
||||||
msgpack_pack_array(spacker, arr_size);
|
msgpack_pack_array(spacker, arr_size);
|
||||||
msgpack_rpc_from_string(cstr_as_string(entry.data.sub_string.sub),
|
msgpack_rpc_from_string(cstr_as_string(entry.data.sub_string.sub),
|
||||||
spacker);
|
spacker);
|
||||||
for (size_t i = 0; i < arr_size - 1; i++) {
|
DUMP_ADDITIONAL_ELEMENTS(entry.data.sub_string.additional_elements);
|
||||||
msgpack_rpc_from_object(
|
|
||||||
entry.data.sub_string.additional_elements->items[i], spacker);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemSearchPattern: {
|
case kSDItemSearchPattern: {
|
||||||
@@ -1652,8 +1667,9 @@ static bool shada_pack_entry(msgpack_packer *const packer,
|
|||||||
// offset defaults to zero:
|
// offset defaults to zero:
|
||||||
+ (size_t) (entry.data.search_pattern.offset != 0)
|
+ (size_t) (entry.data.search_pattern.offset != 0)
|
||||||
// finally, additional data:
|
// finally, additional data:
|
||||||
+ (size_t) (entry.data.search_pattern.additional_data
|
+ (size_t) (
|
||||||
? entry.data.search_pattern.additional_data->size
|
entry.data.search_pattern.additional_data
|
||||||
|
? entry.data.search_pattern.additional_data->dv_hashtab.ht_used
|
||||||
: 0)
|
: 0)
|
||||||
);
|
);
|
||||||
msgpack_pack_map(spacker, map_size);
|
msgpack_pack_map(spacker, map_size);
|
||||||
@@ -1679,16 +1695,7 @@ static bool shada_pack_entry(msgpack_packer *const packer,
|
|||||||
msgpack_pack_int64(spacker, entry.data.search_pattern.offset);
|
msgpack_pack_int64(spacker, entry.data.search_pattern.offset);
|
||||||
}
|
}
|
||||||
#undef PACK_BOOL
|
#undef PACK_BOOL
|
||||||
if (entry.data.search_pattern.additional_data != NULL) {
|
DUMP_ADDITIONAL_DATA(entry.data.search_pattern.additional_data);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemChange:
|
case kSDItemChange:
|
||||||
@@ -1706,9 +1713,10 @@ static bool shada_pack_entry(msgpack_packer *const packer,
|
|||||||
&& entry.type != kSDItemChange
|
&& entry.type != kSDItemChange
|
||||||
&& entry.data.filemark.name != '"')
|
&& entry.data.filemark.name != '"')
|
||||||
// Additional entries, if any:
|
// Additional entries, if any:
|
||||||
+ (size_t) (entry.data.filemark.additional_data == NULL
|
+ (size_t) (
|
||||||
|
entry.data.filemark.additional_data == NULL
|
||||||
? 0
|
? 0
|
||||||
: entry.data.filemark.additional_data->size)
|
: entry.data.filemark.additional_data->dv_hashtab.ht_used)
|
||||||
);
|
);
|
||||||
msgpack_pack_map(spacker, map_size);
|
msgpack_pack_map(spacker, map_size);
|
||||||
PACK_STATIC_STR(KEY_FILE);
|
PACK_STATIC_STR(KEY_FILE);
|
||||||
@@ -1727,15 +1735,7 @@ static bool shada_pack_entry(msgpack_packer *const packer,
|
|||||||
PACK_STATIC_STR(KEY_NAME_CHAR);
|
PACK_STATIC_STR(KEY_NAME_CHAR);
|
||||||
msgpack_pack_uint8(spacker, (uint8_t) entry.data.filemark.name);
|
msgpack_pack_uint8(spacker, (uint8_t) entry.data.filemark.name);
|
||||||
}
|
}
|
||||||
if (entry.data.filemark.additional_data != NULL) {
|
DUMP_ADDITIONAL_DATA(entry.data.filemark.additional_data);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemRegister: {
|
case kSDItemRegister: {
|
||||||
@@ -1748,7 +1748,7 @@ static bool shada_pack_entry(msgpack_packer *const packer,
|
|||||||
// Additional entries, if any:
|
// Additional entries, if any:
|
||||||
+ (size_t) (entry.data.reg.additional_data == NULL
|
+ (size_t) (entry.data.reg.additional_data == NULL
|
||||||
? 0
|
? 0
|
||||||
: entry.data.reg.additional_data->size)
|
: entry.data.reg.additional_data->dv_hashtab.ht_used)
|
||||||
);
|
);
|
||||||
msgpack_pack_map(spacker, map_size);
|
msgpack_pack_map(spacker, map_size);
|
||||||
PACK_STATIC_STR(REG_KEY_CONTENTS);
|
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);
|
PACK_STATIC_STR(REG_KEY_WIDTH);
|
||||||
msgpack_pack_uint64(spacker, (uint64_t) entry.data.reg.width);
|
msgpack_pack_uint64(spacker, (uint64_t) entry.data.reg.width);
|
||||||
}
|
}
|
||||||
if (entry.data.reg.additional_data != NULL) {
|
DUMP_ADDITIONAL_DATA(entry.data.reg.additional_data);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemBufferList: {
|
case kSDItemBufferList: {
|
||||||
@@ -1791,7 +1783,8 @@ static bool shada_pack_entry(msgpack_packer *const packer,
|
|||||||
+ (size_t) (
|
+ (size_t) (
|
||||||
entry.data.buffer_list.buffers[i].additional_data == NULL
|
entry.data.buffer_list.buffers[i].additional_data == NULL
|
||||||
? 0
|
? 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);
|
msgpack_pack_map(spacker, map_size);
|
||||||
PACK_STATIC_STR(KEY_FILE);
|
PACK_STATIC_STR(KEY_FILE);
|
||||||
@@ -1807,18 +1800,7 @@ static bool shada_pack_entry(msgpack_packer *const packer,
|
|||||||
msgpack_pack_uint64(
|
msgpack_pack_uint64(
|
||||||
spacker, (uint64_t) entry.data.buffer_list.buffers[i].pos.col);
|
spacker, (uint64_t) entry.data.buffer_list.buffers[i].pos.col);
|
||||||
}
|
}
|
||||||
if (entry.data.buffer_list.buffers[i].additional_data != NULL) {
|
DUMP_ADDITIONAL_DATA(entry.data.buffer_list.buffers[i].additional_data);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1917,7 +1899,11 @@ static bool shada_pack_encoded_entry(msgpack_packer *const packer,
|
|||||||
}
|
}
|
||||||
case kSDItemVariable: {
|
case kSDItemVariable: {
|
||||||
if (sd_conv->vc_type != CONV_NONE) {
|
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);
|
ret = shada_pack_entry(packer, entry.data, max_kbyte);
|
||||||
break;
|
break;
|
||||||
@@ -2135,9 +2121,11 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
|
|||||||
if (var_iter == NULL && vartv.v_type == VAR_UNKNOWN) {
|
if (var_iter == NULL && vartv.v_type == VAR_UNKNOWN) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Object obj = vim_to_object(&vartv);
|
typval_T tgttv;
|
||||||
if (sd_writer->sd_conv.vc_type != CONV_NONE) {
|
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) {
|
if (!shada_pack_entry(packer, (ShadaEntry) {
|
||||||
.type = kSDItemVariable,
|
.type = kSDItemVariable,
|
||||||
@@ -2145,18 +2133,18 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer,
|
|||||||
.data = {
|
.data = {
|
||||||
.global_var = {
|
.global_var = {
|
||||||
.name = (char *) name,
|
.name = (char *) name,
|
||||||
.value = obj,
|
.value = tgttv,
|
||||||
.additional_elements = NULL,
|
.additional_elements = NULL,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, max_kbyte)) {
|
}, max_kbyte)) {
|
||||||
api_free_object(obj);
|
|
||||||
clear_tv(&vartv);
|
clear_tv(&vartv);
|
||||||
|
clear_tv(&tgttv);
|
||||||
ret = kSDWriteFailed;
|
ret = kSDWriteFailed;
|
||||||
goto shada_write_exit;
|
goto shada_write_exit;
|
||||||
}
|
}
|
||||||
api_free_object(obj);
|
|
||||||
clear_tv(&vartv);
|
clear_tv(&vartv);
|
||||||
|
clear_tv(&tgttv);
|
||||||
int kh_ret;
|
int kh_ret;
|
||||||
(void) kh_put(strset, &wms->dumped_variables, name, &kh_ret);
|
(void) kh_put(strset, &wms->dumped_variables, name, &kh_ret);
|
||||||
} while (var_iter != NULL);
|
} while (var_iter != NULL);
|
||||||
@@ -2970,26 +2958,17 @@ static void shada_free_shada_entry(ShadaEntry *const entry)
|
|||||||
case kSDItemJump:
|
case kSDItemJump:
|
||||||
case kSDItemGlobalMark:
|
case kSDItemGlobalMark:
|
||||||
case kSDItemLocalMark: {
|
case kSDItemLocalMark: {
|
||||||
if (entry->data.filemark.additional_data != NULL) {
|
dict_unref(entry->data.filemark.additional_data);
|
||||||
api_free_dictionary(*entry->data.filemark.additional_data);
|
|
||||||
xfree(entry->data.filemark.additional_data);
|
|
||||||
}
|
|
||||||
xfree(entry->data.filemark.fname);
|
xfree(entry->data.filemark.fname);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemSearchPattern: {
|
case kSDItemSearchPattern: {
|
||||||
if (entry->data.search_pattern.additional_data != NULL) {
|
dict_unref(entry->data.search_pattern.additional_data);
|
||||||
api_free_dictionary(*entry->data.search_pattern.additional_data);
|
|
||||||
xfree(entry->data.search_pattern.additional_data);
|
|
||||||
}
|
|
||||||
xfree(entry->data.search_pattern.pat);
|
xfree(entry->data.search_pattern.pat);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemRegister: {
|
case kSDItemRegister: {
|
||||||
if (entry->data.reg.additional_data != NULL) {
|
dict_unref(entry->data.reg.additional_data);
|
||||||
api_free_dictionary(*entry->data.reg.additional_data);
|
|
||||||
xfree(entry->data.reg.additional_data);
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < entry->data.reg.contents_size; i++) {
|
for (size_t i = 0; i < entry->data.reg.contents_size; i++) {
|
||||||
xfree(entry->data.reg.contents[i]);
|
xfree(entry->data.reg.contents[i]);
|
||||||
}
|
}
|
||||||
@@ -2997,40 +2976,25 @@ static void shada_free_shada_entry(ShadaEntry *const entry)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemHistoryEntry: {
|
case kSDItemHistoryEntry: {
|
||||||
if (entry->data.history_item.canfree) {
|
list_unref(entry->data.history_item.additional_elements);
|
||||||
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);
|
xfree(entry->data.history_item.string);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemVariable: {
|
case kSDItemVariable: {
|
||||||
if (entry->data.global_var.additional_elements != NULL) {
|
list_unref(entry->data.global_var.additional_elements);
|
||||||
api_free_array(*entry->data.global_var.additional_elements);
|
|
||||||
xfree(entry->data.global_var.additional_elements);
|
|
||||||
}
|
|
||||||
xfree(entry->data.global_var.name);
|
xfree(entry->data.global_var.name);
|
||||||
api_free_object(entry->data.global_var.value);
|
clear_tv(&entry->data.global_var.value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemSubString: {
|
case kSDItemSubString: {
|
||||||
if (entry->data.sub_string.additional_elements != NULL) {
|
list_unref(entry->data.sub_string.additional_elements);
|
||||||
api_free_array(*entry->data.sub_string.additional_elements);
|
|
||||||
xfree(entry->data.sub_string.additional_elements);
|
|
||||||
}
|
|
||||||
xfree(entry->data.sub_string.sub);
|
xfree(entry->data.sub_string.sub);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemBufferList: {
|
case kSDItemBufferList: {
|
||||||
for (size_t i = 0; i < entry->data.buffer_list.size; i++) {
|
for (size_t i = 0; i < entry->data.buffer_list.size; i++) {
|
||||||
xfree(entry->data.buffer_list.buffers[i].fname);
|
xfree(entry->data.buffer_list.buffers[i].fname);
|
||||||
if (entry->data.buffer_list.buffers[i].additional_data != NULL) {
|
dict_unref(entry->data.buffer_list.buffers[i].additional_data);
|
||||||
api_free_dictionary(
|
|
||||||
*entry->data.buffer_list.buffers[i].additional_data);
|
|
||||||
xfree(entry->data.buffer_list.buffers[i].additional_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
xfree(entry->data.buffer_list.buffers);
|
xfree(entry->data.buffer_list.buffers);
|
||||||
break;
|
break;
|
||||||
@@ -3177,77 +3141,6 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader,
|
|||||||
return kSDReadStatusSuccess;
|
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
|
/// Convert or copy and return a string
|
||||||
///
|
///
|
||||||
/// @param[in] sd_conv Conversion definition.
|
/// @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)) \
|
? get_converted_string(&sd_reader->sd_conv, (str), (len)) \
|
||||||
: xmemdupz((str), (len)))
|
: xmemdupz((str), (len)))
|
||||||
#define BIN_CONVERTED(b) CONVERTED(b.ptr, b.size)
|
#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) {
|
switch ((ShadaEntryType) type_u64) {
|
||||||
case kSDItemHeader: {
|
case kSDItemHeader: {
|
||||||
if (!msgpack_rpc_to_dictionary(&(unpacked.data), &(entry->data.header))) {
|
if (!msgpack_rpc_to_dictionary(&(unpacked.data), &(entry->data.header))) {
|
||||||
@@ -3552,29 +3497,8 @@ shada_read_next_item_extra_bytes:
|
|||||||
ga_clear(&ad_ga);
|
ga_clear(&ad_ga);
|
||||||
goto shada_read_next_item_error;
|
goto shada_read_next_item_error;
|
||||||
}
|
}
|
||||||
if (ad_ga.ga_len) {
|
SET_ADDITIONAL_DATA(entry->data.search_pattern.additional_data,
|
||||||
msgpack_object obj = {
|
"search pattern");
|
||||||
.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);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemChange:
|
case kSDItemChange:
|
||||||
@@ -3643,28 +3567,7 @@ shada_read_next_item_extra_bytes:
|
|||||||
ga_clear(&ad_ga);
|
ga_clear(&ad_ga);
|
||||||
goto shada_read_next_item_error;
|
goto shada_read_next_item_error;
|
||||||
}
|
}
|
||||||
if (ad_ga.ga_len) {
|
SET_ADDITIONAL_DATA(entry->data.filemark.additional_data, "mark");
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemRegister: {
|
case kSDItemRegister: {
|
||||||
@@ -3738,28 +3641,7 @@ shada_read_next_item_extra_bytes:
|
|||||||
ga_clear(&ad_ga);
|
ga_clear(&ad_ga);
|
||||||
goto shada_read_next_item_error;
|
goto shada_read_next_item_error;
|
||||||
}
|
}
|
||||||
if (ad_ga.ga_len) {
|
SET_ADDITIONAL_DATA(entry->data.reg.additional_data, "register");
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemHistoryEntry: {
|
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 - 2] = 0;
|
||||||
entry->data.history_item.string[strsize - 1] =
|
entry->data.history_item.string[strsize - 1] =
|
||||||
entry->data.history_item.sep;
|
entry->data.history_item.sep;
|
||||||
if (unpacked.data.via.array.size > (size_t) (2 + is_hist_search)) {
|
SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, (2 + is_hist_search),
|
||||||
msgpack_object obj = {
|
entry->data.history_item.additional_elements,
|
||||||
.type = MSGPACK_OBJECT_ARRAY,
|
"history");
|
||||||
.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemVariable: {
|
case kSDItemVariable: {
|
||||||
@@ -3893,7 +3757,7 @@ shada_read_next_item_hist_no_conv:
|
|||||||
entry->data.global_var = (struct global_var) {
|
entry->data.global_var = (struct global_var) {
|
||||||
.name = NULL,
|
.name = NULL,
|
||||||
.value = {
|
.value = {
|
||||||
.type = kObjectTypeNil,
|
.v_type = VAR_UNKNOWN,
|
||||||
},
|
},
|
||||||
.additional_elements = NULL
|
.additional_elements = NULL
|
||||||
};
|
};
|
||||||
@@ -3922,37 +3786,27 @@ shada_read_next_item_hist_no_conv:
|
|||||||
entry->data.global_var.name =
|
entry->data.global_var.name =
|
||||||
xmemdupz(unpacked.data.via.array.ptr[0].via.bin.ptr,
|
xmemdupz(unpacked.data.via.array.ptr[0].via.bin.ptr,
|
||||||
unpacked.data.via.array.ptr[0].via.bin.size);
|
unpacked.data.via.array.ptr[0].via.bin.size);
|
||||||
if (!msgpack_rpc_to_object(&(unpacked.data.via.array.ptr[1]),
|
if (msgpack_to_vim(unpacked.data.via.array.ptr[1],
|
||||||
&(entry->data.global_var.value))) {
|
&(entry->data.global_var.value)) == FAIL) {
|
||||||
emsgu(_(RERR "Error while reading ShaDa file: "
|
emsgu(_(RERR "Error while reading ShaDa file: "
|
||||||
"variable entry at position %" PRIu64 " "
|
"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);
|
(uint64_t) initial_fpos);
|
||||||
goto shada_read_next_item_error;
|
goto shada_read_next_item_error;
|
||||||
}
|
}
|
||||||
if (sd_reader->sd_conv.vc_type != CONV_NONE) {
|
if (sd_reader->sd_conv.vc_type != CONV_NONE) {
|
||||||
convert_object(&sd_reader->sd_conv, &entry->data.global_var.value);
|
typval_T tgttv;
|
||||||
}
|
var_item_copy(&sd_reader->sd_conv,
|
||||||
if (unpacked.data.via.array.size > 2) {
|
&entry->data.global_var.value,
|
||||||
msgpack_object obj = {
|
&tgttv,
|
||||||
.type = MSGPACK_OBJECT_ARRAY,
|
true,
|
||||||
.via = {
|
0);
|
||||||
.array = {
|
clear_tv(&entry->data.global_var.value);
|
||||||
.size = unpacked.data.via.array.size - 2,
|
entry->data.global_var.value = tgttv;
|
||||||
.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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 2,
|
||||||
|
entry->data.global_var.additional_elements,
|
||||||
|
"variable");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemSubString: {
|
case kSDItemSubString: {
|
||||||
@@ -3983,26 +3837,9 @@ shada_read_next_item_hist_no_conv:
|
|||||||
}
|
}
|
||||||
entry->data.sub_string.sub =
|
entry->data.sub_string.sub =
|
||||||
BIN_CONVERTED(unpacked.data.via.array.ptr[0].via.bin);
|
BIN_CONVERTED(unpacked.data.via.array.ptr[0].via.bin);
|
||||||
if (unpacked.data.via.array.size > 1) {
|
SET_ADDITIONAL_ELEMENTS(unpacked.data.via.array, 1,
|
||||||
msgpack_object obj = {
|
entry->data.sub_string.additional_elements,
|
||||||
.type = MSGPACK_OBJECT_ARRAY,
|
"sub string");
|
||||||
.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kSDItemBufferList: {
|
case kSDItemBufferList: {
|
||||||
@@ -4079,30 +3916,9 @@ shada_read_next_item_hist_no_conv:
|
|||||||
ga_clear(&ad_ga);
|
ga_clear(&ad_ga);
|
||||||
goto shada_read_next_item_error;
|
goto shada_read_next_item_error;
|
||||||
}
|
}
|
||||||
if (ad_ga.ga_len) {
|
SET_ADDITIONAL_DATA(
|
||||||
msgpack_object obj = {
|
entry->data.buffer_list.buffers[i].additional_data,
|
||||||
.type = MSGPACK_OBJECT_MAP,
|
"buffer list entry");
|
||||||
.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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -4132,6 +3948,8 @@ shada_read_next_item_hist_no_conv:
|
|||||||
#undef LONG_KEY
|
#undef LONG_KEY
|
||||||
#undef TOU8
|
#undef TOU8
|
||||||
#undef TOSIZE
|
#undef TOSIZE
|
||||||
|
#undef SET_ADDITIONAL_DATA
|
||||||
|
#undef SET_ADDITIONAL_ELEMENTS
|
||||||
shada_read_next_item_error:
|
shada_read_next_item_error:
|
||||||
msgpack_unpacked_destroy(&unpacked);
|
msgpack_unpacked_destroy(&unpacked);
|
||||||
xfree(buf);
|
xfree(buf);
|
||||||
|
@@ -111,7 +111,6 @@
|
|||||||
#include "nvim/types.h"
|
#include "nvim/types.h"
|
||||||
#include "nvim/os/os.h"
|
#include "nvim/os/os.h"
|
||||||
#include "nvim/os/time.h"
|
#include "nvim/os/time.h"
|
||||||
#include "nvim/api/private/helpers.h"
|
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "undo.c.generated.h"
|
# include "undo.c.generated.h"
|
||||||
@@ -329,12 +328,9 @@ static long get_undolevel(void)
|
|||||||
static inline void zero_fmark_additional_data(fmark_T *fmarks)
|
static inline void zero_fmark_additional_data(fmark_T *fmarks)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < NMARKS; i++) {
|
for (size_t i = 0; i < NMARKS; i++) {
|
||||||
if (fmarks[i].additional_data != NULL) {
|
dict_unref(fmarks[i].additional_data);
|
||||||
api_free_dictionary(*fmarks[i].additional_data);
|
|
||||||
free(fmarks[i].additional_data);
|
|
||||||
fmarks[i].additional_data = NULL;
|
fmarks[i].additional_data = NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user