eval: Add msgpackparse and msgpackdump functions

This commit is contained in:
ZyX 2015-07-12 17:31:55 +03:00
parent 4d79edccdc
commit 5a7135fa1c
3 changed files with 628 additions and 0 deletions

View File

@ -1904,6 +1904,8 @@ min( {list}) Number minimum value of items in {list}
mkdir( {name} [, {path} [, {prot}]])
Number create directory {name}
mode( [expr]) String current editing mode
msgpackdump( {list}) List dump a list of objects to msgpack
msgpackparse( {list}) List parse msgpack to a list of objects
nextnonblank( {lnum}) Number line nr of non-blank line >= {lnum}
nr2char( {expr}[, {utf8}]) String single char with ASCII/UTF8 value {expr}
or( {expr}, {expr}) Number bitwise OR
@ -4613,6 +4615,40 @@ mode([expr]) Return a string that indicates the current mode.
"c" or "n".
Also see |visualmode()|.
msgpackdump({list}) *msgpackdump()*
Convert a list of VimL objects to msgpack. Returned value is
|readfile()|-style list. Example: >
call writefile(msgpackdump([{}]), 'fname.mpack', 'b')
< This will write the single 0x80 byte to `fname.mpack` file
(dictionary with zero items is represented by 0x80 byte in
messagepack).
Limitations:
1. |Funcref|s cannot be dumped as funcrefs, they are dumped as
NIL objects instead.
2. NIL and BOOL objects are never dumped, as well as objects
from EXT family.
3. Strings are always dumped as BIN strings.
msgpackparse({list}) *msgpackparse()*
Convert a |readfile()|-style list to a list of VimL objects.
Example: >
let fname = expand('~/.nvim/shada/main.shada')
let mpack = readfile(fname, 'b')
let shada_objects = msgpackparse(mpack)
< This will read |shada-file| to `shada_objects` list.
Limitations:
1. Strings that contain one of EXT format family objects
cannot be parsed by msgpackparse().
2. It may appear that parsed integers do not fit in |Number|
range. Even if your NeoVim installation uses 64-bit
Numbers, it may appear that string contain 64-bit unsigned
number above INT64_MAX.
3. NIL objects are parsed as zeroes. BOOL objects are parsed
as either 1 (true) or 0 (false).
4. BIN and STR strings cannot be distinguished after parsing.
nextnonblank({lnum}) *nextnonblank()*
Return the line number of the first line at or below {lnum}
that is not blank. Example: >

View File

@ -20,6 +20,7 @@
#include <stdbool.h>
#include <math.h>
#include <limits.h>
#include <msgpack.h>
#include "nvim/assert.h"
#include "nvim/vim.h"
@ -90,6 +91,7 @@
#include "nvim/os/time.h"
#include "nvim/msgpack_rpc/channel.h"
#include "nvim/msgpack_rpc/server.h"
#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/api/private/helpers.h"
#include "nvim/api/vim.h"
#include "nvim/os/dl.h"
@ -160,6 +162,13 @@ typedef struct lval_S {
char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */
} lval_T;
/// Structure defining state for read_from_list()
typedef struct {
const listitem_T *li; ///< Item currently read.
size_t offset; ///< Byte offset inside the read item.
size_t li_length; ///< Length of the string inside the read item.
} ListReaderState;
static char *e_letunexp = N_("E18: Unexpected characters in :let");
static char *e_listidx = N_("E684: list index out of range: %" PRId64);
@ -5177,6 +5186,23 @@ void list_append_string(list_T *l, char_u *str, int len)
}
}
/// Append given string to the list
///
/// Unlike list_append_string this function does not copy the string.
///
/// @param[out] l List to append to.
/// @param[in] str String to append.
void list_append_allocated_string(list_T *l, char *const str)
FUNC_ATTR_NONNULL_ARG(1)
{
listitem_T *li = listitem_alloc();
list_append(l, li);
li->li_tv.v_type = VAR_STRING;
li->li_tv.v_lock = 0;
li->li_tv.vval.v_string = (char_u *) str;
}
/*
* Append "n" to list "l".
*/
@ -6583,6 +6609,8 @@ static struct fst {
{"min", 1, 1, f_min},
{"mkdir", 1, 3, f_mkdir},
{"mode", 0, 1, f_mode},
{"msgpackdump", 1, 1, f_msgpackdump},
{"msgpackparse", 1, 1, f_msgpackparse},
{"nextnonblank", 1, 1, f_nextnonblank},
{"nr2char", 1, 2, f_nr2char},
{"or", 2, 2, f_or},
@ -11841,6 +11869,212 @@ static void f_mode(typval_T *argvars, typval_T *rettv)
rettv->v_type = VAR_STRING;
}
/// Msgpack callback for writing to readfile()-style list
static int msgpack_list_write(void *data, const char *buf, size_t len)
{
if (len == 0) {
return 0;
}
list_T *const list = (list_T *) data;
const char *const end = buf + len;
const char *line_end = buf;
if (list->lv_last == NULL) {
list_append_string(list, NULL, 0);
}
listitem_T *li = list->lv_last;
do {
const char *line_start = line_end;
line_end = xmemscan(line_start, NL, end - line_start);
if (line_end == line_start) {
list_append_allocated_string(list, NULL);
} else {
const size_t line_length = line_end - line_start;
char *str;
if (li == NULL) {
str = xmemdupz(line_start, line_length);
} else {
const size_t li_len = (li->li_tv.vval.v_string == NULL
? 0
: STRLEN(li->li_tv.vval.v_string));
li->li_tv.vval.v_string = xrealloc(li->li_tv.vval.v_string,
li_len + line_length + 1);
str = (char *) li->li_tv.vval.v_string + li_len;
memmove(str, line_start, line_length);
str[line_length] = 0;
}
for (size_t i = 0; i < line_length; i++) {
if (str[i] == NUL) {
str[i] = NL;
}
}
if (li == NULL) {
list_append_allocated_string(list, str);
} else {
li = NULL;
}
if (line_end == end - 1) {
list_append_allocated_string(list, NULL);
}
}
line_end++;
} while (line_end < end);
return 0;
}
/// "msgpackdump()" function
static void f_msgpackdump(typval_T *argvars, typval_T *rettv)
FUNC_ATTR_NONNULL_ALL
{
if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listarg), "msgpackdump()");
}
list_T *ret_list = rettv_list_alloc(rettv);
const list_T *list = argvars[0].vval.v_list;
if (list == NULL) {
return;
}
msgpack_packer *lpacker = msgpack_packer_new(ret_list, &msgpack_list_write);
for (const listitem_T *li = list->lv_first; li != NULL; li = li->li_next) {
Object obj = vim_to_object((typval_T *) &li->li_tv);
msgpack_rpc_from_object(obj, lpacker);
api_free_object(obj);
}
msgpack_packer_free(lpacker);
}
/// Read bytes from list
///
/// @param[in,out] state Structure describing position in list from which
/// reading should start. Is updated to reflect position
/// at which reading ended.
/// @param[out] buf Buffer to write to.
/// @param[in] nbuf Buffer length.
/// @param[out] read_bytes Is set to amount of bytes read.
///
/// @return OK when reading was finished, FAIL in case of error (i.e. list item
/// was not a string), NOTDONE if reading was successfull, but there are
/// more bytes to read.
static int read_from_list(ListReaderState *const state, char *const buf,
const size_t nbuf, size_t *const read_bytes)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
char *const buf_end = buf + nbuf;
char *p = buf;
while (p < buf_end) {
for (size_t i = state->offset; i < state->li_length && p < buf_end; i++) {
const char ch = state->li->li_tv.vval.v_string[state->offset++];
*p++ = (ch == NL ? NUL : ch);
}
if (p < buf_end) {
state->li = state->li->li_next;
if (state->li == NULL) {
*read_bytes = (size_t) (p - buf);
return OK;
}
*p++ = NL;
if (state->li->li_tv.v_type != VAR_STRING) {
*read_bytes = (size_t) (p - buf);
return FAIL;
}
state->offset = 0;
state->li_length = (state->li->li_tv.vval.v_string == NULL
? 0
: STRLEN(state->li->li_tv.vval.v_string));
}
}
*read_bytes = nbuf;
return NOTDONE;
}
/// "msgpackparse" function
static void f_msgpackparse(typval_T *argvars, typval_T *rettv)
FUNC_ATTR_NONNULL_ALL
{
if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listarg), "msgpackparse()");
}
list_T *ret_list = rettv_list_alloc(rettv);
const list_T *list = argvars[0].vval.v_list;
if (list == NULL || list->lv_first == NULL) {
return;
}
if (list->lv_first->li_tv.v_type != VAR_STRING) {
EMSG2(_(e_invarg2), "List item is not a string");
return;
}
ListReaderState lrstate = {
.li = list->lv_first,
.offset = 0,
.li_length = (list->lv_first->li_tv.vval.v_string == NULL
? 0
: STRLEN(list->lv_first->li_tv.vval.v_string)),
};
msgpack_unpacker *const unpacker = msgpack_unpacker_new(IOSIZE);
if (unpacker == NULL) {
EMSG(_(e_outofmem));
return;
}
msgpack_unpacked unpacked;
msgpack_unpacked_init(&unpacked);
do {
if (!msgpack_unpacker_reserve_buffer(unpacker, IOSIZE)) {
EMSG(_(e_outofmem));
goto f_msgpackparse_exit;
}
size_t read_bytes;
const int rlret = read_from_list(
&lrstate, msgpack_unpacker_buffer(unpacker), IOSIZE, &read_bytes);
if (rlret == FAIL) {
EMSG2(_(e_invarg2), "List item is not a string");
goto f_msgpackparse_exit;
}
msgpack_unpacker_buffer_consumed(unpacker, read_bytes);
if (read_bytes == 0) {
break;
}
while (unpacker->off < unpacker->used) {
const msgpack_unpack_return result = msgpack_unpacker_next(unpacker,
&unpacked);
if (result == MSGPACK_UNPACK_PARSE_ERROR) {
EMSG2(_(e_invarg2), "Failed to parse msgpack string");
goto f_msgpackparse_exit;
}
if (result == MSGPACK_UNPACK_NOMEM_ERROR) {
EMSG(_(e_outofmem));
goto f_msgpackparse_exit;
}
if (result == MSGPACK_UNPACK_SUCCESS) {
Object obj;
if (!msgpack_rpc_to_object(&unpacked.data, &obj)) {
EMSG2(_(e_invarg2), "Failed to convert parsed string to Object");
goto f_msgpackparse_exit;
}
listitem_T *li = listitem_alloc();
Error err;
if (!object_to_vim(obj, &li->li_tv, &err)) {
EMSG2(_(e_invarg2), err.msg);
goto f_msgpackparse_exit;
}
list_append(ret_list, li);
api_free_object(obj);
}
if (result == MSGPACK_UNPACK_CONTINUE) {
if (rlret == OK) {
EMSG2(_(e_invarg2), "Incomplete msgpack string");
}
break;
}
}
if (rlret == OK) {
break;
}
} while (true);
f_msgpackparse_exit:
msgpack_unpacked_destroy(&unpacked);
msgpack_unpacker_free(unpacker);
return;
}
/*
* "nextnonblank()" function

View File

@ -0,0 +1,358 @@
local helpers = require('test.functional.helpers')
local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute
local eval, eq, neq = helpers.eval, helpers.eq, helpers.neq
local execute, source = helpers.execute, helpers.source
local nvim = helpers.nvim
describe('msgpack*() functions', function()
before_each(function()
clear()
end)
local obj_test = function(msg, obj)
it(msg, function()
nvim('set_var', 'obj', obj)
eq(obj, eval('msgpackparse(msgpackdump(g:obj))'))
end)
end
-- Regression test: msgpack_list_write was failing to write buffer with zero
-- length.
obj_test('are able to dump and restore {"file": ""}', {{file=''}})
-- Regression test: msgpack_list_write was failing to write buffer with NL at
-- the end.
obj_test('are able to dump and restore {0, "echo mpack"}', {{0, 'echo mpack'}})
obj_test('are able to dump and restore "Test\\n"', {'Test\n'})
-- Regression test: msgpack_list_write was failing to write buffer with NL
-- inside.
obj_test('are able to dump and restore "Test\\nTest 2"', {'Test\nTest 2'})
-- Test that big objects (requirement: dump to something that is bigger then
-- IOSIZE) are also fine. This particular object is obtained by concatenating
-- 5 identical shada files.
local big_obj = {
1, 1436711454, 78, {
encoding="utf-8",
max_kbyte=10,
pid=19269,
version="NVIM 0.0.0-alpha+201507121634"
},
8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
8, 1436711391, 8, { file="" },
4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
4, 1436708966, 6, { 0, "cq" },
4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
4, 1436709634, 57, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
},
4, 1436709651, 67, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
},
4, 1436709660, 70, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
},
4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
4, 1436711142, 14, { 0, "echo mpack" },
4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
4, 1436711206, 16, { 0, "echo lengths" },
4, 1436711244, 92, {
0,
("let sum = len(lengths) - 1 | call map(copy(lengths), "
.. "'extend(g:, {\"sum\": sum + v:val})')")
},
4, 1436711245, 12, { 0, "echo sum" },
4, 1436711398, 10, { 0, "echo s" },
4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
4, 1436711415, 22, { 0, "echo shada_objects" },
4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
4, 1436711454, 6, { 0, "qa" },
4, 1436711442, 9, { 1, "test", 47 },
4, 1436711443, 15, { 1, "aontsuesan", 47 },
2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
3, 0, 3, { "" },
10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
1, 1436711454, 78, {
encoding="utf-8",
max_kbyte=10,
pid=19269,
version="NVIM 0.0.0-alpha+201507121634"
},
8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
8, 1436711391, 8, { file="" },
4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
4, 1436708966, 6, { 0, "cq" },
4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
4, 1436709634, 57, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
},
4, 1436709651, 67, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
},
4, 1436709660, 70, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
},
4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
4, 1436711142, 14, { 0, "echo mpack" },
4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
4, 1436711206, 16, { 0, "echo lengths" },
4, 1436711244, 92, {
0,
("let sum = len(lengths) - 1 | call map(copy(lengths), "
.. "'extend(g:, {\"sum\": sum + v:val})')")
},
4, 1436711245, 12, { 0, "echo sum" },
4, 1436711398, 10, { 0, "echo s" },
4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
4, 1436711415, 22, { 0, "echo shada_objects" },
4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
4, 1436711454, 6, { 0, "qa" },
4, 1436711442, 9, { 1, "test", 47 },
4, 1436711443, 15, { 1, "aontsuesan", 47 },
2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
3, 0, 3, { "" },
10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
1, 1436711454, 78, {
encoding="utf-8",
max_kbyte=10,
pid=19269,
version="NVIM 0.0.0-alpha+201507121634"
},
8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
8, 1436711391, 8, { file="" },
4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
4, 1436708966, 6, { 0, "cq" },
4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
4, 1436709634, 57, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
},
4, 1436709651, 67, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
},
4, 1436709660, 70, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
},
4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
4, 1436711142, 14, { 0, "echo mpack" },
4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
4, 1436711206, 16, { 0, "echo lengths" },
4, 1436711244, 92, {
0,
("let sum = len(lengths) - 1 | call map(copy(lengths), "
.. "'extend(g:, {\"sum\": sum + v:val})')")
},
4, 1436711245, 12, { 0, "echo sum" },
4, 1436711398, 10, { 0, "echo s" },
4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
4, 1436711415, 22, { 0, "echo shada_objects" },
4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
4, 1436711454, 6, { 0, "qa" },
4, 1436711442, 9, { 1, "test", 47 },
4, 1436711443, 15, { 1, "aontsuesan", 47 },
2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
3, 0, 3, { "" },
10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
1, 1436711454, 78, {
encoding="utf-8",
max_kbyte=10,
pid=19269,
version="NVIM 0.0.0-alpha+201507121634"
},
8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
8, 1436711391, 8, { file="" },
4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
4, 1436708966, 6, { 0, "cq" },
4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
4, 1436709634, 57, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
},
4, 1436709651, 67, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
},
4, 1436709660, 70, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
},
4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
4, 1436711142, 14, { 0, "echo mpack" },
4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
4, 1436711206, 16, { 0, "echo lengths" },
4, 1436711244, 92, {
0,
("let sum = len(lengths) - 1 | call map(copy(lengths), "
.. "'extend(g:, {\"sum\": sum + v:val})')")
},
4, 1436711245, 12, { 0, "echo sum" },
4, 1436711398, 10, { 0, "echo s" },
4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
4, 1436711415, 22, { 0, "echo shada_objects" },
4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
4, 1436711454, 6, { 0, "qa" },
4, 1436711442, 9, { 1, "test", 47 },
4, 1436711443, 15, { 1, "aontsuesan", 47 },
2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
3, 0, 3, { "" },
10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
1, 1436711454, 78, {
encoding="utf-8",
max_kbyte=10,
pid=19269,
version="NVIM 0.0.0-alpha+201507121634"
},
8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
8, 1436711391, 8, { file="" },
4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
4, 1436708966, 6, { 0, "cq" },
4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
4, 1436709634, 57, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
},
4, 1436709651, 67, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
},
4, 1436709660, 70, {
0,
"echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
},
4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
4, 1436711142, 14, { 0, "echo mpack" },
4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
4, 1436711206, 16, { 0, "echo lengths" },
4, 1436711244, 92, {
0,
("let sum = len(lengths) - 1 | call map(copy(lengths), "
.. "'extend(g:, {\"sum\": sum + v:val})')")
},
4, 1436711245, 12, { 0, "echo sum" },
4, 1436711398, 10, { 0, "echo s" },
4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
4, 1436711415, 22, { 0, "echo shada_objects" },
4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
4, 1436711454, 6, { 0, "qa" },
4, 1436711442, 9, { 1, "test", 47 },
4, 1436711443, 15, { 1, "aontsuesan", 47 },
2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
3, 0, 3, { "" },
10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" }
}
obj_test('are able to dump and restore rather big object', big_obj)
it('dump funcref as nil and restore as zero', function()
execute('let dumped = msgpackdump([function("tr")])')
eq({"\192"}, eval('dumped'))
eq({0}, eval('msgpackparse(dumped)'))
end)
it('restore boolean false as zero', function()
execute('let dumped = ["\\xC2"]')
eq({0}, eval('msgpackparse(dumped)'))
end)
it('restore boolean true as one', function()
execute('let dumped = ["\\xC3"]')
eq({1}, eval('msgpackparse(dumped)'))
end)
it('dump string as BIN 8', function()
nvim('set_var', 'obj', {'Test'})
eq({"\196\004Test"}, eval('msgpackdump(obj)'))
end)
it('restore FIXSTR as string', function()
execute('let dumped = ["\\xa2ab"]')
eq({'ab'}, eval('msgpackparse(dumped)'))
end)
it('restore BIN 8 as string', function()
execute('let dumped = ["\\xC4\\x02ab"]')
eq({'ab'}, eval('msgpackparse(dumped)'))
end)
end)