diff options
Diffstat (limited to 'src/nvim/shada.c')
-rw-r--r-- | src/nvim/shada.c | 301 |
1 files changed, 159 insertions, 142 deletions
diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 340c14066a..51c8597d53 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -1,8 +1,3 @@ -#ifdef HAVE_BE64TOH -# define _BSD_SOURCE 1 -# define _DEFAULT_SOURCE 1 -# include <endian.h> -#endif #include <stdlib.h> #include <stddef.h> #include <stdbool.h> @@ -10,9 +5,7 @@ #include <stdint.h> #include <inttypes.h> #include <errno.h> -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif +#include <fcntl.h> #include <assert.h> #include <msgpack.h> @@ -38,7 +31,6 @@ #include "nvim/misc2.h" #include "nvim/ex_getln.h" #include "nvim/search.h" -#include "nvim/eval.h" #include "nvim/regexp.h" #include "nvim/eval_defs.h" #include "nvim/version.h" @@ -46,9 +38,17 @@ #include "nvim/fileio.h" #include "nvim/strings.h" #include "nvim/quickfix.h" +#include "nvim/eval/encode.h" +#include "nvim/eval/decode.h" #include "nvim/lib/khash.h" #include "nvim/lib/kvec.h" +#ifdef HAVE_BE64TOH +# define _BSD_SOURCE 1 +# define _DEFAULT_SOURCE 1 +# include ENDIAN_INCLUDE_FILE +#endif + // Note: when using bufset hash pointers are intentionally casted to uintptr_t // and not to khint32_t or khint64_t: this way compiler must give a warning // (-Wconversion) when types change. @@ -66,9 +66,6 @@ KHASH_SET_INIT_STR(strset) ((char *) copy_option_part((char_u **) src, (char_u *) dest, __VA_ARGS__)) #define find_shada_parameter(...) \ ((const char *) find_shada_parameter(__VA_ARGS__)) -#define emsg2(a, b) emsg2((char_u *) a, (char_u *) b) -#define emsg3(a, b, c) emsg3((char_u *) a, (char_u *) b, (char_u *) c) -#define emsgu(a, ...) emsgu((char_u *) a, __VA_ARGS__) #define home_replace_save(a, b) \ ((char *)home_replace_save(a, (char_u *)b)) #define home_replace(a, b, c, d, e) \ @@ -122,7 +119,7 @@ KHASH_SET_INIT_STR(strset) // E576: Missing '>' // E577: Illegal register name // E886: Can't rename viminfo file to %s! -// Now only five of them are used: +// Now only six of them are used: // E137: ShaDa file is not writeable (for pre-open checks) // E138: All %s.tmp.X files exist, cannot write ShaDa file! // RCERR (E576) for critical read errors. @@ -130,6 +127,7 @@ KHASH_SET_INIT_STR(strset) // RERR (E575) for various errors inside read ShaDa file. // SERR (E886) for various “system” errors (always contains output of // strerror) +// WERR (E574) for various ignorable write errors /// Common prefix for all errors inside ShaDa file /// @@ -148,6 +146,9 @@ KHASH_SET_INIT_STR(strset) /// Common prefix for all “rename” errors #define RNERR "E136: " +/// Common prefix for all ignorable “write” errors +#define WERR "E574: " + /// Flags for shada_read_file and children typedef enum { kShaDaWantInfo = 1, ///< Load non-mark information @@ -198,6 +199,9 @@ typedef enum { ///< a ShaDa file. kSDWriteFailed, ///< Writing was not successfull (e.g. because there ///< was no space left on device). + kSDWriteIgnError, ///< Writing resulted in a error which can be ignored + ///< (e.g. when trying to dump a function reference or + ///< self-referencing container in a variable). } ShaDaWriteResult; /// Flags for shada_read_next_item @@ -279,7 +283,7 @@ typedef struct { } history_item; struct reg { char name; - uint8_t type; + MotionType type; char **contents; size_t contents_size; size_t width; @@ -471,7 +475,7 @@ static const ShadaEntry sd_default_values[] = { .additional_elements = NULL), DEF_SDE(Register, reg, .name = NUL, - .type = MCHAR, + .type = kMTCharWise, .contents = NULL, .contents_size = 0, .width = 0, @@ -754,9 +758,9 @@ static void close_sd_writer(ShaDaWriteDef *const sd_writer) FUNC_ATTR_NONNULL_ALL { const int fd = (int)(intptr_t) sd_writer->cookie; - if (fsync(fd) < 0) { - emsg2(_(SERR "System error while synchronizing ShaDa file: %s"), - strerror(errno)); + if (os_fsync(fd) < 0) { + emsgf(_(SERR "System error while synchronizing ShaDa file: %s"), + os_strerror(errno)); errno = 0; } close_file(fd); @@ -805,11 +809,11 @@ static ShaDaReadResult sd_reader_skip(ShaDaReadDef *const sd_reader, { if (sd_reader->skip(sd_reader, offset) != OK) { if (sd_reader->error != NULL) { - emsg2(_(SERR "System error while skipping in ShaDa file: %s"), + emsgf(_(SERR "System error while skipping in ShaDa file: %s"), sd_reader->error); return kSDReadStatusReadError; } else if (sd_reader->eof) { - emsgu(_(RCERR "Error while reading ShaDa file: " + emsgf(_(RCERR "Error while reading ShaDa file: " "last entry specified that it occupies %" PRIu64 " bytes, " "but file ended earlier"), (uint64_t) offset); @@ -843,7 +847,7 @@ open_file_start: goto open_file_start; } if (fd != UV_EEXIST) { - emsg3(_(SERR "System error while opening ShaDa file %s: %s"), + emsgf(_(SERR "System error while opening ShaDa file %s: %s"), fname, os_strerror(fd)); } return fd; @@ -891,7 +895,7 @@ close_file_start: errno = 0; goto close_file_start; } else { - emsg2(_(SERR "System error while closing ShaDa file: %s"), + emsgf(_(SERR "System error while closing ShaDa file: %s"), strerror(errno)); errno = 0; } @@ -928,7 +932,7 @@ static int msgpack_sd_writer_write(void *data, const char *buf, size_t len) ShaDaWriteDef *const sd_writer = (ShaDaWriteDef *) data; ptrdiff_t written_bytes = sd_writer->write(sd_writer, buf, len); if (written_bytes == -1) { - emsg2(_(SERR "System error while writing ShaDa file: %s"), + emsgf(_(SERR "System error while writing ShaDa file: %s"), sd_writer->error); return -1; } @@ -975,7 +979,7 @@ static int shada_read_file(const char *const file, const int flags) if (of_ret != 0) { if (of_ret == UV_ENOENT && (flags & kShaDaMissingError)) { - emsg3(_(SERR "System error while opening ShaDa file %s for reading: %s"), + emsgf(_(SERR "System error while opening ShaDa file %s for reading: %s"), fname, os_strerror(of_ret)); } xfree(fname); @@ -1403,9 +1407,9 @@ static void shada_read(ShaDaReadDef *const sd_reader, const int flags) break; } case kSDItemRegister: { - if (cur_entry.data.reg.type != MCHAR - && cur_entry.data.reg.type != MLINE - && cur_entry.data.reg.type != MBLOCK) { + if (cur_entry.data.reg.type != kMTCharWise + && cur_entry.data.reg.type != kMTLineWise + && cur_entry.data.reg.type != kMTBlockWise) { shada_free_shada_entry(&cur_entry); break; } @@ -1666,25 +1670,30 @@ static char *shada_filename(const char *file) /// @param[in] entry Entry written. /// @param[in] max_kbyte Maximum size of an item in KiB. Zero means no /// restrictions. -static bool shada_pack_entry(msgpack_packer *const packer, - ShadaEntry entry, - const size_t max_kbyte) +/// +/// @return kSDWriteSuccessfull, kSDWriteFailed or kSDWriteIgnError. +static ShaDaWriteResult shada_pack_entry(msgpack_packer *const packer, + ShadaEntry entry, + const size_t max_kbyte) FUNC_ATTR_NONNULL_ALL { + ShaDaWriteResult ret = kSDWriteFailed; msgpack_sbuffer sbuf; msgpack_sbuffer_init(&sbuf); msgpack_packer *spacker = msgpack_packer_new(&sbuf, &msgpack_sbuffer_write); -#define DUMP_ADDITIONAL_ELEMENTS(src) \ +#define DUMP_ADDITIONAL_ELEMENTS(src, what) \ 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) { \ + if (encode_vim_to_msgpack(spacker, &li->li_tv, \ + _("additional elements of ShaDa " what)) \ + == FAIL) { \ goto shada_pack_entry_error; \ } \ } \ } \ } while (0) -#define DUMP_ADDITIONAL_DATA(src) \ +#define DUMP_ADDITIONAL_DATA(src, what) \ do { \ dict_T *const d = (src); \ if (d != NULL) { \ @@ -1696,7 +1705,9 @@ static bool shada_pack_entry(msgpack_packer *const packer, 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) { \ + if (encode_vim_to_msgpack(spacker, &di->di_tv, \ + _("additional data of ShaDa " what)) \ + == FAIL) { \ goto shada_pack_entry_error; \ } \ } \ @@ -1731,7 +1742,8 @@ static bool shada_pack_entry(msgpack_packer *const packer, if (is_hist_search) { msgpack_pack_uint8(spacker, (uint8_t) entry.data.history_item.sep); } - DUMP_ADDITIONAL_ELEMENTS(entry.data.history_item.additional_elements); + DUMP_ADDITIONAL_ELEMENTS(entry.data.history_item.additional_elements, + "history entry item"); break; } case kSDItemVariable: { @@ -1740,11 +1752,20 @@ static bool shada_pack_entry(msgpack_packer *const packer, ? 0 : entry.data.global_var.additional_elements->lv_len); msgpack_pack_array(spacker, arr_size); - PACK_BIN(cstr_as_string(entry.data.global_var.name)); - if (vim_to_msgpack(spacker, &entry.data.global_var.value) == FAIL) { + const String varname = cstr_as_string(entry.data.global_var.name); + PACK_BIN(varname); + char vardesc[256] = "variable g:"; + memcpy(&vardesc[sizeof("variable g:") - 1], varname.data, + varname.size + 1); + if (encode_vim_to_msgpack(spacker, &entry.data.global_var.value, vardesc) + == FAIL) { + ret = kSDWriteIgnError; + EMSG2(_(WERR "Failed to write variable %s"), + entry.data.global_var.name); goto shada_pack_entry_error; } - DUMP_ADDITIONAL_ELEMENTS(entry.data.global_var.additional_elements); + DUMP_ADDITIONAL_ELEMENTS(entry.data.global_var.additional_elements, + "variable item"); break; } case kSDItemSubString: { @@ -1754,7 +1775,8 @@ static bool shada_pack_entry(msgpack_packer *const packer, : entry.data.sub_string.additional_elements->lv_len); msgpack_pack_array(spacker, arr_size); PACK_BIN(cstr_as_string(entry.data.sub_string.sub)); - DUMP_ADDITIONAL_ELEMENTS(entry.data.sub_string.additional_elements); + DUMP_ADDITIONAL_ELEMENTS(entry.data.sub_string.additional_elements, + "sub string item"); break; } case kSDItemSearchPattern: { @@ -1801,7 +1823,8 @@ static bool shada_pack_entry(msgpack_packer *const packer, msgpack_pack_int64(spacker, entry.data.search_pattern.offset); } #undef PACK_BOOL - DUMP_ADDITIONAL_DATA(entry.data.search_pattern.additional_data); + DUMP_ADDITIONAL_DATA(entry.data.search_pattern.additional_data, + "search pattern item"); break; } case kSDItemChange: @@ -1836,7 +1859,8 @@ 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); } - DUMP_ADDITIONAL_DATA(entry.data.filemark.additional_data); + DUMP_ADDITIONAL_DATA(entry.data.filemark.additional_data, + "mark (change, jump, global or local) item"); break; } case kSDItemRegister: { @@ -1858,13 +1882,13 @@ static bool shada_pack_entry(msgpack_packer *const packer, msgpack_pack_char(spacker, entry.data.reg.name); if (!CHECK_DEFAULT(entry, reg.type)) { PACK_STATIC_STR(REG_KEY_TYPE); - msgpack_pack_uint8(spacker, entry.data.reg.type); + msgpack_pack_uint8(spacker, (uint8_t)entry.data.reg.type); } if (!CHECK_DEFAULT(entry, reg.width)) { PACK_STATIC_STR(REG_KEY_WIDTH); msgpack_pack_uint64(spacker, (uint64_t) entry.data.reg.width); } - DUMP_ADDITIONAL_DATA(entry.data.reg.additional_data); + DUMP_ADDITIONAL_DATA(entry.data.reg.additional_data, "register item"); break; } case kSDItemBufferList: { @@ -1895,7 +1919,8 @@ static bool shada_pack_entry(msgpack_packer *const packer, msgpack_pack_uint64( spacker, (uint64_t) entry.data.buffer_list.buffers[i].pos.col); } - DUMP_ADDITIONAL_DATA(entry.data.buffer_list.buffers[i].additional_data); + DUMP_ADDITIONAL_DATA(entry.data.buffer_list.buffers[i].additional_data, + "buffer list subitem"); } break; } @@ -1946,11 +1971,11 @@ static bool shada_pack_entry(msgpack_packer *const packer, } msgpack_packer_free(spacker); msgpack_sbuffer_destroy(&sbuf); - return true; + return kSDWriteSuccessfull; shada_pack_entry_error: msgpack_packer_free(spacker); msgpack_sbuffer_destroy(&sbuf); - return false; + return ret; } #undef PACK_STRING @@ -1965,13 +1990,13 @@ shada_pack_entry_error: /// is assumed that entry was already converted. /// @param[in] max_kbyte Maximum size of an item in KiB. Zero means no /// restrictions. -static bool shada_pack_encoded_entry(msgpack_packer *const packer, - const vimconv_T *const sd_conv, - PossiblyFreedShadaEntry entry, - const size_t max_kbyte) +static ShaDaWriteResult shada_pack_encoded_entry(msgpack_packer *const packer, + const vimconv_T *const sd_conv, + PossiblyFreedShadaEntry entry, + const size_t max_kbyte) FUNC_ATTR_NONNULL_ALL { - bool ret = true; + ShaDaWriteResult ret = kSDWriteSuccessfull; if (entry.can_free_entry) { ret = shada_pack_entry(packer, entry.data, max_kbyte); shada_free_shada_entry(&entry.data); @@ -2134,7 +2159,7 @@ shada_parse_msgpack_read_next: {} break; } case MSGPACK_UNPACK_PARSE_ERROR: { - emsgu(_(RCERR "Failed to parse ShaDa file due to a msgpack parser error " + emsgf(_(RCERR "Failed to parse ShaDa file due to a msgpack parser error " "at position %" PRIu64), (uint64_t) initial_fpos); ret = kSDReadStatusNotShaDa; @@ -2151,7 +2176,7 @@ shada_parse_msgpack_read_next: {} break; } case MSGPACK_UNPACK_CONTINUE: { - emsgu(_(RCERR "Failed to parse ShaDa file: incomplete msgpack string " + emsgf(_(RCERR "Failed to parse ShaDa file: incomplete msgpack string " "at position %" PRIu64), (uint64_t) initial_fpos); ret = kSDReadStatusNotShaDa; @@ -2159,7 +2184,7 @@ shada_parse_msgpack_read_next: {} } case MSGPACK_UNPACK_EXTRA_BYTES: { shada_parse_msgpack_extra_bytes: - emsgu(_(RCERR "Failed to parse ShaDa file: extra bytes in msgpack string " + emsgf(_(RCERR "Failed to parse ShaDa file: extra bytes in msgpack string " "at position %" PRIu64), (uint64_t) initial_fpos); ret = kSDReadStatusNotShaDa; @@ -2244,9 +2269,7 @@ static inline ShaDaWriteResult shada_read_when_writing( assert(false); } case kSDItemUnknown: { - if (!shada_pack_entry(packer, entry, 0)) { - ret = kSDWriteFailed; - } + ret = shada_pack_entry(packer, entry, 0); shada_free_shada_entry(&entry); break; } @@ -2262,9 +2285,7 @@ static inline ShaDaWriteResult shada_read_when_writing( } case kSDItemHistoryEntry: { if (entry.data.history_item.histtype >= HIST_COUNT) { - if (!shada_pack_entry(packer, entry, 0)) { - ret = kSDWriteFailed; - } + ret = shada_pack_entry(packer, entry, 0); shada_free_shada_entry(&entry); break; } @@ -2275,9 +2296,7 @@ static inline ShaDaWriteResult shada_read_when_writing( case kSDItemRegister: { const int idx = op_reg_index(entry.data.reg.name); if (idx < 0) { - if (!shada_pack_entry(packer, entry, 0)) { - ret = kSDWriteFailed; - } + ret = shada_pack_entry(packer, entry, 0); shada_free_shada_entry(&entry); break; } @@ -2286,9 +2305,7 @@ static inline ShaDaWriteResult shada_read_when_writing( } case kSDItemVariable: { if (!in_strset(&wms->dumped_variables, entry.data.global_var.name)) { - if (!shada_pack_entry(packer, entry, 0)) { - ret = kSDWriteFailed; - } + ret = shada_pack_entry(packer, entry, 0); } shada_free_shada_entry(&entry); break; @@ -2296,9 +2313,7 @@ static inline ShaDaWriteResult shada_read_when_writing( case kSDItemGlobalMark: { const int idx = mark_global_index(entry.data.filemark.name); if (idx < 0) { - if (!shada_pack_entry(packer, entry, 0)) { - ret = kSDWriteFailed; - } + ret = shada_pack_entry(packer, entry, 0); shada_free_shada_entry(&entry); break; } @@ -2465,7 +2480,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, } // Write header - if (!shada_pack_entry(packer, (ShadaEntry) { + if (shada_pack_entry(packer, (ShadaEntry) { .type = kSDItemHeader, .timestamp = os_time(), .data = { @@ -2486,7 +2501,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, }), } } - }, 0)) { + }, 0) == kSDWriteFailed) { ret = kSDWriteFailed; goto shada_write_exit; } @@ -2526,7 +2541,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, }; i++; } - if (!shada_pack_entry(packer, buflist_entry, 0)) { + if (shada_pack_entry(packer, buflist_entry, 0) == kSDWriteFailed) { xfree(buflist_entry.data.buffer_list.buffers); ret = kSDWriteFailed; goto shada_write_exit; @@ -2552,7 +2567,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, } else { copy_tv(&vartv, &tgttv); } - if (!shada_pack_entry(packer, (ShadaEntry) { + ShaDaWriteResult spe_ret; + if ((spe_ret = shada_pack_entry(packer, (ShadaEntry) { .type = kSDItemVariable, .timestamp = cur_timestamp, .data = { @@ -2562,7 +2578,7 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, .additional_elements = NULL, } } - }, max_kbyte)) { + }, max_kbyte)) == kSDWriteFailed) { clear_tv(&vartv); clear_tv(&tgttv); ret = kSDWriteFailed; @@ -2570,8 +2586,10 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, } clear_tv(&vartv); clear_tv(&tgttv); - int kh_ret; - (void) kh_put(strset, &wms->dumped_variables, name, &kh_ret); + if (spe_ret == kSDWriteSuccessfull) { + int kh_ret; + (void) kh_put(strset, &wms->dumped_variables, name, &kh_ret); + } } while (var_iter != NULL); } @@ -2739,8 +2757,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, .reg = { .contents = (char **) reg.y_array, .contents_size = (size_t) reg.y_size, - .type = (uint8_t) reg.y_type, - .width = (size_t) (reg.y_type == MBLOCK ? reg.y_width : 0), + .type = reg.y_type, + .width = (size_t) (reg.y_type == kMTBlockWise ? reg.y_width : 0), .additional_data = reg.additional_data, .name = name, } @@ -2828,9 +2846,9 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, do { \ for (size_t i_ = 0; i_ < ARRAY_SIZE(wms_array); i_++) { \ if (wms_array[i_].data.type != kSDItemMissing) { \ - if (!shada_pack_encoded_entry(packer, &sd_writer->sd_conv, \ - wms_array[i_], \ - max_kbyte)) { \ + if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, \ + wms_array[i_], \ + max_kbyte) == kSDWriteFailed) { \ ret = kSDWriteFailed; \ goto shada_write_exit; \ } \ @@ -2840,8 +2858,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, PACK_WMS_ARRAY(wms->global_marks); PACK_WMS_ARRAY(wms->registers); for (size_t i = 0; i < wms->jumps_size; i++) { - if (!shada_pack_encoded_entry(packer, &sd_writer->sd_conv, wms->jumps[i], - max_kbyte)) { + if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, wms->jumps[i], + max_kbyte) == kSDWriteFailed) { ret = kSDWriteFailed; goto shada_write_exit; } @@ -2849,8 +2867,8 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, #define PACK_WMS_ENTRY(wms_entry) \ do { \ if (wms_entry.data.type != kSDItemMissing) { \ - if (!shada_pack_encoded_entry(packer, &sd_writer->sd_conv, wms_entry, \ - max_kbyte)) { \ + if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, wms_entry, \ + max_kbyte) == kSDWriteFailed) { \ ret = kSDWriteFailed; \ goto shada_write_exit; \ } \ @@ -2877,16 +2895,16 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, for (size_t i = 0; i < file_markss_to_dump; i++) { PACK_WMS_ARRAY(all_file_markss[i]->marks); for (size_t j = 0; j < all_file_markss[i]->changes_size; j++) { - if (!shada_pack_encoded_entry(packer, &sd_writer->sd_conv, - all_file_markss[i]->changes[j], - max_kbyte)) { + if (shada_pack_encoded_entry(packer, &sd_writer->sd_conv, + all_file_markss[i]->changes[j], + max_kbyte) == kSDWriteFailed) { ret = kSDWriteFailed; goto shada_write_exit; } } for (size_t j = 0; j < all_file_markss[i]->additional_marks_size; j++) { - if (!shada_pack_entry(packer, all_file_markss[i]->additional_marks[j], - 0)) { + if (shada_pack_entry(packer, all_file_markss[i]->additional_marks[j], + 0) == kSDWriteFailed) { shada_free_shada_entry(&all_file_markss[i]->additional_marks[j]); ret = kSDWriteFailed; goto shada_write_exit; @@ -2903,16 +2921,15 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, if (dump_one_history[i]) { hms_insert_whole_neovim_history(&wms->hms[i]); HMS_ITER(&wms->hms[i], cur_entry, { - if (!shada_pack_encoded_entry( + if (shada_pack_encoded_entry( packer, &sd_writer->sd_conv, (PossiblyFreedShadaEntry) { .data = cur_entry->data, .can_free_entry = cur_entry->can_free_entry, - }, max_kbyte)) { + }, max_kbyte) == kSDWriteFailed) { ret = kSDWriteFailed; break; } }) - hms_dealloc(&wms->hms[i]); if (ret == kSDWriteFailed) { goto shada_write_exit; } @@ -2921,6 +2938,11 @@ static ShaDaWriteResult shada_write(ShaDaWriteDef *const sd_writer, } shada_write_exit: + for (size_t i = 0; i < HIST_COUNT; i++) { + if (dump_one_history[i]) { + hms_dealloc(&wms->hms[i]); + } + } kh_dealloc(file_marks, &wms->file_marks); kh_dealloc(bufset, &removable_bufs); msgpack_packer_free(packer); @@ -3043,6 +3065,7 @@ shada_write_file_nomerge: {} const ShaDaWriteResult sw_ret = shada_write(&sd_writer, (nomerge ? NULL : &sd_reader)); + assert(sw_ret != kSDWriteIgnError); #ifndef UNIX sd_writer.close(&sd_writer); #endif @@ -3242,11 +3265,11 @@ static ShaDaReadResult fread_len(ShaDaReadDef *const sd_reader, (void) read_bytes; if (sd_reader->error != NULL) { - emsg2(_(SERR "System error while reading ShaDa file: %s"), + emsgf(_(SERR "System error while reading ShaDa file: %s"), sd_reader->error); return kSDReadStatusReadError; } else if (sd_reader->eof) { - emsgu(_(RCERR "Error while reading ShaDa file: " + emsgf(_(RCERR "Error while reading ShaDa file: " "last entry specified that it occupies %" PRIu64 " bytes, " "but file ended earlier"), (uint64_t) length); @@ -3281,11 +3304,11 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, if (first_char == EOF) { if (sd_reader->error) { - emsg2(_(SERR "System error while reading integer from ShaDa file: %s"), + emsgf(_(SERR "System error while reading integer from ShaDa file: %s"), sd_reader->error); return kSDReadStatusReadError; } else if (sd_reader->eof) { - emsgu(_(RCERR "Error while reading ShaDa file: " + emsgf(_(RCERR "Error while reading ShaDa file: " "expected positive integer at position %" PRIu64 ", but got nothing"), (uint64_t) fpos); @@ -3316,7 +3339,7 @@ static ShaDaReadResult msgpack_read_uint64(ShaDaReadDef *const sd_reader, break; } default: { - emsgu(_(RCERR "Error while reading ShaDa file: " + emsgf(_(RCERR "Error while reading ShaDa file: " "expected positive integer at position %" PRIu64), (uint64_t) fpos); return kSDReadStatusNotShaDa; @@ -3380,18 +3403,18 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv, proc) \ do { \ if (!(condition)) { \ - emsgu(_(READERR(entry_name, error_desc)), initial_fpos); \ + emsgf(_(READERR(entry_name, error_desc)), initial_fpos); \ CLEAR_GA_AND_ERROR_OUT(ad_ga); \ } \ tgt = proc(obj.via.attr); \ } while (0) #define CHECK_KEY_IS_STR(entry_name) \ if (unpacked.data.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR) { \ - emsgu(_(READERR(entry_name, "has key which is not a string")), \ + emsgf(_(READERR(entry_name, "has key which is not a string")), \ initial_fpos); \ CLEAR_GA_AND_ERROR_OUT(ad_ga); \ } else if (unpacked.data.via.map.ptr[i].key.via.str.size == 0) { \ - emsgu(_(READERR(entry_name, "has empty key")), initial_fpos); \ + emsgf(_(READERR(entry_name, "has empty key")), initial_fpos); \ CLEAR_GA_AND_ERROR_OUT(ad_ga); \ } #define CHECKED_KEY(entry_name, name, error_desc, tgt, condition, attr, proc) \ @@ -3454,7 +3477,7 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv, typval_T adtv; \ if (msgpack_to_vim(obj, &adtv) == FAIL \ || adtv.v_type != VAR_DICT) { \ - emsgu(_(READERR(name, \ + emsgf(_(READERR(name, \ "cannot be converted to a VimL dictionary")), \ initial_fpos); \ ga_clear(&ad_ga); \ @@ -3479,7 +3502,7 @@ static inline char *get_converted_string(const vimconv_T *const sd_conv, }; \ typval_T aetv; \ if (msgpack_to_vim(obj, &aetv) == FAIL) { \ - emsgu(_(READERR(name, "cannot be converted to a VimL list")), \ + emsgf(_(READERR(name, "cannot be converted to a VimL list")), \ initial_fpos); \ clear_tv(&aetv); \ goto shada_read_next_item_error; \ @@ -3547,7 +3570,7 @@ shada_read_next_item_start: // kSDItemUnknown cannot possibly pass that far because it is -1 and that // will fail in msgpack_read_uint64. But kSDItemMissing may and it will // otherwise be skipped because (1 << 0) will never appear in flags. - emsgu(_(RCERR "Error while reading ShaDa file: " + emsgf(_(RCERR "Error while reading ShaDa file: " "there is an item at position %" PRIu64 " " "that must not be there: Missing items are " "for internal uses only"), @@ -3617,14 +3640,14 @@ shada_read_next_item_start: switch ((ShadaEntryType) type_u64) { case kSDItemHeader: { if (!msgpack_rpc_to_dictionary(&(unpacked.data), &(entry->data.header))) { - emsgu(_(READERR("header", "is not a dictionary")), initial_fpos); + emsgf(_(READERR("header", "is not a dictionary")), initial_fpos); goto shada_read_next_item_error; } break; } case kSDItemSearchPattern: { if (unpacked.data.type != MSGPACK_OBJECT_MAP) { - emsgu(_(READERR("search pattern", "is not a dictionary")), + emsgf(_(READERR("search pattern", "is not a dictionary")), initial_fpos); goto shada_read_next_item_error; } @@ -3655,7 +3678,7 @@ shada_read_next_item_start: ADDITIONAL_KEY } if (entry->data.search_pattern.pat == NULL) { - emsgu(_(READERR("search pattern", "has no pattern")), initial_fpos); + emsgf(_(READERR("search pattern", "has no pattern")), initial_fpos); CLEAR_GA_AND_ERROR_OUT(ad_ga); } SET_ADDITIONAL_DATA(entry->data.search_pattern.additional_data, @@ -3667,7 +3690,7 @@ shada_read_next_item_start: case kSDItemGlobalMark: case kSDItemLocalMark: { if (unpacked.data.type != MSGPACK_OBJECT_MAP) { - emsgu(_(READERR("mark", "is not a dictionary")), initial_fpos); + emsgf(_(READERR("mark", "is not a dictionary")), initial_fpos); goto shada_read_next_item_error; } garray_T ad_ga; @@ -3676,7 +3699,7 @@ shada_read_next_item_start: CHECK_KEY_IS_STR("mark") if (CHECK_KEY(unpacked.data.via.map.ptr[i].key, KEY_NAME_CHAR)) { if (type_u64 == kSDItemJump || type_u64 == kSDItemChange) { - emsgu(_(READERR("mark", "has n key which is only valid for " + emsgf(_(READERR("mark", "has n key which is only valid for " "local and global mark entries")), initial_fpos); CLEAR_GA_AND_ERROR_OUT(ad_ga); } @@ -3693,15 +3716,15 @@ shada_read_next_item_start: ADDITIONAL_KEY } if (entry->data.filemark.fname == NULL) { - emsgu(_(READERR("mark", "is missing file name")), initial_fpos); + emsgf(_(READERR("mark", "is missing file name")), initial_fpos); CLEAR_GA_AND_ERROR_OUT(ad_ga); } if (entry->data.filemark.mark.lnum <= 0) { - emsgu(_(READERR("mark", "has invalid line number")), initial_fpos); + emsgf(_(READERR("mark", "has invalid line number")), initial_fpos); CLEAR_GA_AND_ERROR_OUT(ad_ga); } if (entry->data.filemark.mark.col < 0) { - emsgu(_(READERR("mark", "has invalid column number")), initial_fpos); + emsgf(_(READERR("mark", "has invalid column number")), initial_fpos); CLEAR_GA_AND_ERROR_OUT(ad_ga); } SET_ADDITIONAL_DATA(entry->data.filemark.additional_data, "mark"); @@ -3709,7 +3732,7 @@ shada_read_next_item_start: } case kSDItemRegister: { if (unpacked.data.type != MSGPACK_OBJECT_MAP) { - emsgu(_(READERR("register", "is not a dictionary")), initial_fpos); + emsgf(_(READERR("register", "is not a dictionary")), initial_fpos); goto shada_read_next_item_error; } garray_T ad_ga; @@ -3719,14 +3742,14 @@ shada_read_next_item_start: if (CHECK_KEY(unpacked.data.via.map.ptr[i].key, REG_KEY_CONTENTS)) { if (unpacked.data.via.map.ptr[i].val.type != MSGPACK_OBJECT_ARRAY) { - emsgu(_(READERR("register", + emsgf(_(READERR("register", "has " REG_KEY_CONTENTS " key with non-array value")), initial_fpos); CLEAR_GA_AND_ERROR_OUT(ad_ga); } if (unpacked.data.via.map.ptr[i].val.via.array.size == 0) { - emsgu(_(READERR("register", + emsgf(_(READERR("register", "has " REG_KEY_CONTENTS " key with empty array")), initial_fpos); CLEAR_GA_AND_ERROR_OUT(ad_ga); @@ -3735,7 +3758,7 @@ shada_read_next_item_start: unpacked.data.via.map.ptr[i].val.via.array; for (size_t i = 0; i < arr.size; i++) { if (arr.ptr[i].type != MSGPACK_OBJECT_BIN) { - emsgu(_(READERR("register", "has " REG_KEY_CONTENTS " array " + emsgf(_(READERR("register", "has " REG_KEY_CONTENTS " array " "with non-binary value")), initial_fpos); CLEAR_GA_AND_ERROR_OUT(ad_ga); } @@ -3755,7 +3778,7 @@ shada_read_next_item_start: ADDITIONAL_KEY } if (entry->data.reg.contents == NULL) { - emsgu(_(READERR("register", "has missing " REG_KEY_CONTENTS " array")), + emsgf(_(READERR("register", "has missing " REG_KEY_CONTENTS " array")), initial_fpos); CLEAR_GA_AND_ERROR_OUT(ad_ga); } @@ -3764,29 +3787,29 @@ shada_read_next_item_start: } case kSDItemHistoryEntry: { if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) { - emsgu(_(READERR("history", "is not an array")), initial_fpos); + emsgf(_(READERR("history", "is not an array")), initial_fpos); goto shada_read_next_item_error; } if (unpacked.data.via.array.size < 2) { - emsgu(_(READERR("history", "does not have enough elements")), + emsgf(_(READERR("history", "does not have enough elements")), initial_fpos); goto shada_read_next_item_error; } if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { - emsgu(_(READERR("history", "has wrong history type type")), + emsgf(_(READERR("history", "has wrong history type type")), initial_fpos); goto shada_read_next_item_error; } if (unpacked.data.via.array.ptr[1].type != MSGPACK_OBJECT_BIN) { - emsgu(_(READERR("history", "has wrong history string type")), + emsgf(_(READERR("history", "has wrong history string type")), initial_fpos); goto shada_read_next_item_error; } if (memchr(unpacked.data.via.array.ptr[1].via.bin.ptr, 0, unpacked.data.via.array.ptr[1].via.bin.size) != NULL) { - emsgu(_(READERR("history", "contains string with zero byte inside")), + emsgf(_(READERR("history", "contains string with zero byte inside")), initial_fpos); goto shada_read_next_item_error; } @@ -3796,13 +3819,13 @@ shada_read_next_item_start: entry->data.history_item.histtype == HIST_SEARCH; if (is_hist_search) { if (unpacked.data.via.array.size < 3) { - emsgu(_(READERR("search history", + emsgf(_(READERR("search history", "does not have separator character")), initial_fpos); goto shada_read_next_item_error; } if (unpacked.data.via.array.ptr[2].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { - emsgu(_(READERR("search history", + emsgf(_(READERR("search history", "has wrong history separator type")), initial_fpos); goto shada_read_next_item_error; } @@ -3844,22 +3867,16 @@ shada_read_next_item_hist_no_conv: } case kSDItemVariable: { if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) { - emsgu(_(READERR("variable", "is not an array")), initial_fpos); + emsgf(_(READERR("variable", "is not an array")), initial_fpos); goto shada_read_next_item_error; } if (unpacked.data.via.array.size < 2) { - emsgu(_(READERR("variable", "does not have enough elements")), + emsgf(_(READERR("variable", "does not have enough elements")), initial_fpos); goto shada_read_next_item_error; } if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_BIN) { - emsgu(_(READERR("variable", "has wrong variable name type")), - initial_fpos); - goto shada_read_next_item_error; - } - if (unpacked.data.via.array.ptr[1].type == MSGPACK_OBJECT_NIL - || unpacked.data.via.array.ptr[1].type == MSGPACK_OBJECT_EXT) { - emsgu(_(READERR("variable", "has wrong variable value type")), + emsgf(_(READERR("variable", "has wrong variable name type")), initial_fpos); goto shada_read_next_item_error; } @@ -3868,7 +3885,7 @@ shada_read_next_item_hist_no_conv: unpacked.data.via.array.ptr[0].via.bin.size); if (msgpack_to_vim(unpacked.data.via.array.ptr[1], &(entry->data.global_var.value)) == FAIL) { - emsgu(_(READERR("variable", "has value that cannot " + emsgf(_(READERR("variable", "has value that cannot " "be converted to the VimL value")), initial_fpos); goto shada_read_next_item_error; } @@ -3889,16 +3906,16 @@ shada_read_next_item_hist_no_conv: } case kSDItemSubString: { if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) { - emsgu(_(READERR("sub string", "is not an array")), initial_fpos); + emsgf(_(READERR("sub string", "is not an array")), initial_fpos); goto shada_read_next_item_error; } if (unpacked.data.via.array.size < 1) { - emsgu(_(READERR("sub string", "does not have enough elements")), + emsgf(_(READERR("sub string", "does not have enough elements")), initial_fpos); goto shada_read_next_item_error; } if (unpacked.data.via.array.ptr[0].type != MSGPACK_OBJECT_BIN) { - emsgu(_(READERR("sub string", "has wrong sub string type")), + emsgf(_(READERR("sub string", "has wrong sub string type")), initial_fpos); goto shada_read_next_item_error; } @@ -3911,7 +3928,7 @@ shada_read_next_item_hist_no_conv: } case kSDItemBufferList: { if (unpacked.data.type != MSGPACK_OBJECT_ARRAY) { - emsgu(_(READERR("buffer list", "is not an array")), initial_fpos); + emsgf(_(READERR("buffer list", "is not an array")), initial_fpos); goto shada_read_next_item_error; } if (unpacked.data.via.array.size == 0) { @@ -3928,7 +3945,7 @@ shada_read_next_item_hist_no_conv: { msgpack_unpacked unpacked = unpacked_2; if (unpacked.data.type != MSGPACK_OBJECT_MAP) { - emsgu(_(RERR "Error while reading ShaDa file: " + emsgf(_(RERR "Error while reading ShaDa file: " "buffer list at position %" PRIu64 " " "contains entry that is not a dictionary"), initial_fpos); @@ -3953,21 +3970,21 @@ shada_read_next_item_hist_no_conv: } } if (entry->data.buffer_list.buffers[i].pos.lnum <= 0) { - emsgu(_(RERR "Error while reading ShaDa file: " + emsgf(_(RERR "Error while reading ShaDa file: " "buffer list at position %" PRIu64 " " "contains entry with invalid line number"), initial_fpos); CLEAR_GA_AND_ERROR_OUT(ad_ga); } if (entry->data.buffer_list.buffers[i].pos.col < 0) { - emsgu(_(RERR "Error while reading ShaDa file: " + emsgf(_(RERR "Error while reading ShaDa file: " "buffer list at position %" PRIu64 " " "contains entry with invalid column number"), initial_fpos); CLEAR_GA_AND_ERROR_OUT(ad_ga); } if (entry->data.buffer_list.buffers[i].fname == NULL) { - emsgu(_(RERR "Error while reading ShaDa file: " + emsgf(_(RERR "Error while reading ShaDa file: " "buffer list at position %" PRIu64 " " "contains entry that does not have a file name"), initial_fpos); |