shada: When reading marks or registers, free items when set fails

This commit is contained in:
ZyX
2015-08-04 08:14:08 +03:00
parent 07d9ab26c6
commit 5b3e668f3e
3 changed files with 32 additions and 12 deletions

View File

@@ -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;
} }
/* /*

View File

@@ -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;
} }

View File

@@ -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);