mirror of
https://github.com/neovim/neovim.git
synced 2025-09-17 16:58:17 +00:00
shada: When reading marks or registers, free items when set fails
This commit is contained in:
@@ -1343,19 +1343,22 @@ size_t mark_buffer_amount(const buf_T *const buf)
|
|||||||
/// @param[in] fm Mark to be set.
|
/// @param[in] fm Mark to be set.
|
||||||
/// @param[in] update If true then only set global mark if it was created
|
/// @param[in] update If true then only set global mark if it was created
|
||||||
/// later then existing one.
|
/// later then existing one.
|
||||||
void mark_set_global(const char name, const xfmark_T fm, const bool update)
|
///
|
||||||
|
/// @return true on success, false on failure.
|
||||||
|
bool mark_set_global(const char name, const xfmark_T fm, const bool update)
|
||||||
{
|
{
|
||||||
xfmark_T *fm_tgt = &(namedfm[mark_global_index(name)]);
|
xfmark_T *fm_tgt = &(namedfm[mark_global_index(name)]);
|
||||||
if (fm_tgt == &namedfm[0] - 1) {
|
if (fm_tgt == &namedfm[0] - 1) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (update && fm.fmark.timestamp < fm_tgt->fmark.timestamp) {
|
if (update && fm.fmark.timestamp < fm_tgt->fmark.timestamp) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (fm_tgt->fmark.mark.lnum != 0) {
|
if (fm_tgt->fmark.mark.lnum != 0) {
|
||||||
free_xfmark(*fm_tgt);
|
free_xfmark(*fm_tgt);
|
||||||
}
|
}
|
||||||
*fm_tgt = fm;
|
*fm_tgt = fm;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set local mark
|
/// Set local mark
|
||||||
@@ -1365,7 +1368,9 @@ void mark_set_global(const char name, const xfmark_T fm, const bool update)
|
|||||||
/// @param[in] fm Mark to be set.
|
/// @param[in] fm Mark to be set.
|
||||||
/// @param[in] update If true then only set global mark if it was created
|
/// @param[in] update If true then only set global mark if it was created
|
||||||
/// later then existing one.
|
/// later then existing one.
|
||||||
void mark_set_local(const char name, buf_T *const buf,
|
///
|
||||||
|
/// @return true on success, false on failure.
|
||||||
|
bool mark_set_local(const char name, buf_T *const buf,
|
||||||
const fmark_T fm, const bool update)
|
const fmark_T fm, const bool update)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
@@ -1379,15 +1384,16 @@ void mark_set_local(const char name, buf_T *const buf,
|
|||||||
} else if (name == '.') {
|
} else if (name == '.') {
|
||||||
fm_tgt = &(buf->b_last_change);
|
fm_tgt = &(buf->b_last_change);
|
||||||
} else {
|
} else {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (update && fm.timestamp < fm_tgt->timestamp) {
|
if (update && fm.timestamp < fm_tgt->timestamp) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (fm_tgt->mark.lnum != 0) {
|
if (fm_tgt->mark.lnum != 0) {
|
||||||
free_fmark(*fm_tgt);
|
free_fmark(*fm_tgt);
|
||||||
}
|
}
|
||||||
*fm_tgt = fm;
|
*fm_tgt = fm;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -5368,11 +5368,17 @@ size_t op_register_amount(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set register to a given value
|
/// Set register to a given value
|
||||||
void register_set(const char name, const yankreg_T reg)
|
///
|
||||||
|
/// @param[in] name Register name.
|
||||||
|
/// @param[in] reg Register value.
|
||||||
|
///
|
||||||
|
/// @return true on success, false on failure.
|
||||||
|
bool register_set(const char name, const yankreg_T reg)
|
||||||
{
|
{
|
||||||
int i = op_reg_index(name);
|
int i = op_reg_index(name);
|
||||||
if (i == -1) {
|
if (i == -1) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
y_regs[i] = reg;
|
y_regs[i] = reg;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -1240,14 +1240,16 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
|
|||||||
shada_free_shada_entry(&cur_entry);
|
shada_free_shada_entry(&cur_entry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
register_set(cur_entry.data.reg.name, (yankreg_T) {
|
if (!register_set(cur_entry.data.reg.name, (yankreg_T) {
|
||||||
.y_array = (char_u **) cur_entry.data.reg.contents,
|
.y_array = (char_u **) cur_entry.data.reg.contents,
|
||||||
.y_size = (linenr_T) cur_entry.data.reg.contents_size,
|
.y_size = (linenr_T) cur_entry.data.reg.contents_size,
|
||||||
.y_type = cur_entry.data.reg.type,
|
.y_type = cur_entry.data.reg.type,
|
||||||
.y_width = (colnr_T) cur_entry.data.reg.width,
|
.y_width = (colnr_T) cur_entry.data.reg.width,
|
||||||
.timestamp = cur_entry.timestamp,
|
.timestamp = cur_entry.timestamp,
|
||||||
.additional_data = cur_entry.data.reg.additional_data,
|
.additional_data = cur_entry.data.reg.additional_data,
|
||||||
});
|
})) {
|
||||||
|
shada_free_shada_entry(&cur_entry);
|
||||||
|
}
|
||||||
// Do not free shada entry: its allocated memory was saved above.
|
// Do not free shada entry: its allocated memory was saved above.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1277,7 +1279,10 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
if (cur_entry.type == kSDItemGlobalMark) {
|
if (cur_entry.type == kSDItemGlobalMark) {
|
||||||
mark_set_global(cur_entry.data.filemark.name, fm, !force);
|
if (!mark_set_global(cur_entry.data.filemark.name, fm, !force)) {
|
||||||
|
shada_free_shada_entry(&cur_entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (force) {
|
if (force) {
|
||||||
if (curwin->w_jumplistlen == JUMPLISTSIZE) {
|
if (curwin->w_jumplistlen == JUMPLISTSIZE) {
|
||||||
@@ -1400,7 +1405,10 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags)
|
|||||||
.additional_data = cur_entry.data.filemark.additional_data,
|
.additional_data = cur_entry.data.filemark.additional_data,
|
||||||
};
|
};
|
||||||
if (cur_entry.type == kSDItemLocalMark) {
|
if (cur_entry.type == kSDItemLocalMark) {
|
||||||
mark_set_local(cur_entry.data.filemark.name, buf, fm, !force);
|
if (!mark_set_local(cur_entry.data.filemark.name, buf, fm, !force)) {
|
||||||
|
shada_free_shada_entry(&cur_entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int kh_ret;
|
int kh_ret;
|
||||||
(void) kh_put(bufset, cl_bufs, (uintptr_t) buf, &kh_ret);
|
(void) kh_put(bufset, cl_bufs, (uintptr_t) buf, &kh_ret);
|
||||||
|
Reference in New Issue
Block a user