aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2015-07-26 20:46:40 +0300
committerZyX <kp-pav@yandex.ru>2015-10-08 22:00:25 +0300
commit12a31c70c1beb3d106c4450bbd2ab33a1f8c2316 (patch)
tree888af6f3129e2c010dd11e5f69cca5f41691d998 /src
parent82934e8797651b934569ba77bd9fd6d8f75e87e6 (diff)
downloadrneovim-12a31c70c1beb3d106c4450bbd2ab33a1f8c2316.tar.gz
rneovim-12a31c70c1beb3d106c4450bbd2ab33a1f8c2316.tar.bz2
rneovim-12a31c70c1beb3d106c4450bbd2ab33a1f8c2316.zip
shada,functests: Test compatibility support
For compatibility the following things are done: 1. Items with type greater then greatest type are ignored when reading and copied when writing. 2. Registers with unknown name are ignored when reading and blindly copied when writing. 3. Registers with unknown type are ignored when reading and merged as usual when writing. 4. Local and global marks with unknown names are ignored when reading. When writing global marks are blindly copied and local marks are also blindly copied, but only if file they are attached to fits in the `'N` limit defined in &shada. Unknown local mark’s timestamp is also taken into account when calculating which files exactly should fit into this limit. 5. History items with unknown type are ignored when reading and blindly copied when writing. 6. Unknown keys found in register, local marks, global marks, changes, jumps and search pattern entries are read to additional_data Dictionary and dumped (of course, unless any of these elements were not overwritten later). It obviously works only for values conversible to Object type. 7. Additional elements found in replacement string and history entries are read to additional_elements Array and dumped (same: only if they were not overwritten later). Again this works only for elements conversible to Object type. 8. Additional elements found in variable entries are simply ignored when reading. When writing *new* variables they will be preserved during merging, but that’s all. Variable values dumped from current NeoVim session never have additional elements.
Diffstat (limited to 'src')
-rw-r--r--src/nvim/mark.c4
-rw-r--r--src/nvim/shada.c45
2 files changed, 31 insertions, 18 deletions
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 5afa24e621..7e1ae42c47 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -1351,7 +1351,7 @@ bool mark_set_global(const char name, const xfmark_T fm, const bool update)
if (fm_tgt == &namedfm[0] - 1) {
return false;
}
- if (update && fm.fmark.timestamp < fm_tgt->fmark.timestamp) {
+ if (update && fm.fmark.timestamp <= fm_tgt->fmark.timestamp) {
return false;
}
if (fm_tgt->fmark.mark.lnum != 0) {
@@ -1386,7 +1386,7 @@ bool mark_set_local(const char name, buf_T *const buf,
} else {
return false;
}
- if (update && fm.timestamp < fm_tgt->timestamp) {
+ if (update && fm.timestamp <= fm_tgt->timestamp) {
return false;
}
if (fm_tgt->mark.lnum != 0) {
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index be049fbb20..770a5a89f4 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -1567,6 +1567,11 @@ static char *shada_filename(const char *file)
msgpack_pack_str(spacker, sizeof(s) - 1); \
msgpack_pack_str_body(spacker, s, sizeof(s) - 1); \
} while (0)
+#define PACK_STRING(s) \
+ do { \
+ msgpack_pack_str(spacker, s.size); \
+ msgpack_pack_str_body(spacker, s.data, s.size); \
+ } while (0)
/// Write single ShaDa entry
///
@@ -1587,7 +1592,7 @@ static bool shada_pack_entry(msgpack_packer *const packer,
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; \
+ goto shada_pack_entry_error; \
} \
} \
} \
@@ -1605,7 +1610,7 @@ static bool shada_pack_entry(msgpack_packer *const packer,
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; \
+ goto shada_pack_entry_error; \
} \
} \
} \
@@ -1616,12 +1621,9 @@ static bool shada_pack_entry(msgpack_packer *const packer,
assert(false);
}
case kSDItemUnknown: {
- if ((msgpack_pack_uint64(packer, (uint64_t) entry.data.unknown_item.size)
- == -1)
- || (packer->callback(packer->data, entry.data.unknown_item.contents,
- (unsigned) entry.data.unknown_item.size)
- == -1)) {
- return false;
+ if (spacker->callback(spacker->data, entry.data.unknown_item.contents,
+ (unsigned) entry.data.unknown_item.size) == -1) {
+ goto shada_pack_entry_error;
}
break;
}
@@ -1651,7 +1653,7 @@ static bool shada_pack_entry(msgpack_packer *const packer,
msgpack_rpc_from_string(cstr_as_string(entry.data.global_var.name),
spacker);
if (vim_to_msgpack(spacker, &entry.data.global_var.value) == FAIL) {
- return false;
+ goto shada_pack_entry_error;
}
DUMP_ADDITIONAL_ELEMENTS(entry.data.global_var.additional_elements);
break;
@@ -1826,30 +1828,34 @@ static bool shada_pack_entry(msgpack_packer *const packer,
}
if (!max_kbyte || sbuf.size <= max_kbyte * 1024) {
if (entry.type == kSDItemUnknown) {
- if (msgpack_pack_uint64(packer, (uint64_t) entry.data.unknown_item.type)
- == -1) {
- return false;
+ if (msgpack_pack_uint64(packer, entry.data.unknown_item.type) == -1) {
+ goto shada_pack_entry_error;
}
} else {
if (msgpack_pack_uint64(packer, (uint64_t) entry.type) == -1) {
- return false;
+ goto shada_pack_entry_error;
}
}
if (msgpack_pack_uint64(packer, (uint64_t) entry.timestamp) == -1) {
- return false;
+ goto shada_pack_entry_error;
}
if (sbuf.size > 0) {
if ((msgpack_pack_uint64(packer, (uint64_t) sbuf.size) == -1)
|| (packer->callback(packer->data, sbuf.data,
(unsigned) sbuf.size) == -1)) {
- return false;
+ goto shada_pack_entry_error;
}
}
}
msgpack_packer_free(spacker);
msgpack_sbuffer_destroy(&sbuf);
return true;
+shada_pack_entry_error:
+ msgpack_packer_free(spacker);
+ msgpack_sbuffer_destroy(&sbuf);
+ return false;
}
+#undef PACK_STRING
/// Write single ShaDa entry, converting it if needed
///
@@ -3260,7 +3266,14 @@ shada_read_next_item_start:
entry->data.unknown_item.size = length;
entry->data.unknown_item.type = type_u64;
entry->data.unknown_item.contents = xmalloc(length);
- return fread_len(sd_reader, entry->data.unknown_item.contents, length);
+ const ShaDaReadResult fl_ret = fread_len(sd_reader,
+ entry->data.unknown_item.contents,
+ length);
+ if (fl_ret != kSDReadStatusSuccess) {
+ shada_free_shada_entry(entry);
+ entry->type = kSDItemMissing;
+ }
+ return fl_ret;
}
char *const buf = xmalloc(length);