diff --git a/client/tarantool/CMakeLists.txt b/client/tarantool/CMakeLists.txt
index c8f1a369ac60e870e3beb312771fadf09b82c69c..d03e72375cf7c3bd7f1b30a3afabb4646499cf6b 100644
--- a/client/tarantool/CMakeLists.txt
+++ b/client/tarantool/CMakeLists.txt
@@ -8,7 +8,8 @@ if (NOT READLINE_FOUND)
 endif()
 
 set (cli "tarantool")
-set (cli_sources tc.c tc_opt.c tc_admin.c tc_query.c tc_print.c tc_cli.c tc_store.c)
+set (cli_sources tc.c tc_opt.c tc_admin.c tc_query.c tc_print.c tc_buf.c
+		tc_cli.c tc_store.c tc_print_xlog.c tc_print_snap.c)
 set (cli_libs tntrpl tntnet tntsql tnt gopt ${READLINE_LIBRARIES})
 
 include_directories(${READLINE_INCLUDE_DIR})
diff --git a/client/tarantool/tc.c b/client/tarantool/tc.c
index ffb96d5c3c7a94e15f3c12dee1c4cc78cf950226..2b190f07b291361f9812fc28099222e376a68173 100644
--- a/client/tarantool/tc.c
+++ b/client/tarantool/tc.c
@@ -45,6 +45,8 @@
 #include "client/tarantool/tc.h"
 #include "client/tarantool/tc_cli.h"
 #include "client/tarantool/tc_print.h"
+#include "client/tarantool/tc_print_snap.h"
+#include "client/tarantool/tc_print_xlog.h"
 #include "client/tarantool/tc_store.h"
 
 struct tc tc;
@@ -103,10 +105,15 @@ static void tc_connect_admin(void)
 
 static void tc_validate(void)
 {
-	tc.opt.printer = tc_print_getcb(tc.opt.format);
-	if (tc.opt.printer == NULL)
-		return tc_error("unsupported output format '%s'",
+	tc.opt.xlog_printer = tc_print_getxlogcb(tc.opt.format);
+	tc.opt.snap_printer = tc_print_getsnapcb(tc.opt.format);
+	if (tc.opt.xlog_printer == NULL)
+		return tc_error("unsupported output xlog format '%s'",
 				tc.opt.format);
+	if (tc.opt.snap_printer == NULL)
+		return tc_error("unsupported output snap format '%s'",
+				tc.opt.format);
+	
 	if (tc.opt.format && strcmp(tc.opt.format, "raw") == 0)
 		tc.opt.raw = 1;
 }
diff --git a/client/tarantool/tc_admin.c b/client/tarantool/tc_admin.c
index bdd4a806837c5dd05fbe2f6e2d92e738ac1084a9..7c941ee49c8083d19cce300cecae2d3740b0e031 100644
--- a/client/tarantool/tc_admin.c
+++ b/client/tarantool/tc_admin.c
@@ -115,9 +115,11 @@ int tc_admin_reply(struct tc_admin *a, char **r, size_t *size)
 		ssize_t rxi = recv(a->fd, rx, sizeof(rx), 0);
 		if (rxi <= 0)
 			break;
-		char *bufn = realloc(buf, off + rxi + 1);
-		if (bufn == NULL)
+		char *bufn = (char *)realloc(buf, off + rxi + 1);
+		if (bufn == NULL) {
+			free(buf);
 			break;
+		}
 		buf = bufn;
 		memcpy(buf + off, rx, rxi);
 		off += rxi;
diff --git a/client/tarantool/tc_buf.c b/client/tarantool/tc_buf.c
new file mode 100644
index 0000000000000000000000000000000000000000..b4556bb796078d1b86f5b54a84b2146268e22c87
--- /dev/null
+++ b/client/tarantool/tc_buf.c
@@ -0,0 +1,126 @@
+/*
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+#include <ctype.h>
+
+#include "client/tarantool/tc_buf.h"
+
+/* Strip trailing ws from (char*) */
+size_t strip_end_ws(char *str) {
+	size_t last = 0;
+	for (size_t i = 0; str[i] != 0; ++i)
+		if (!isspace(str[i]))
+			last = i + 1;
+	str[last] = '\0';
+	return last;
+}
+
+/* Init membuf */
+int tc_buf(struct tc_buf *buf) {
+	buf->size = TC_BUF_INIT_SIZE;
+	buf->used = 0;
+	buf->data = (char *)malloc(buf->size);
+	if (buf->data == NULL)
+		return -1;
+	return 0;
+}
+
+/* Append len bytes of memory from str pointed memory */
+int tc_buf_append(struct tc_buf *buf, void *str, size_t len) {
+	if (buf->size - buf->used < len) {
+		if (buf->size < len)
+			buf->size = len;
+		buf->size *= TC_BUF_MULTIPLIER;
+		char *nd = (char *)realloc(buf->data, buf->size);
+		if (nd == NULL)
+			return -1;
+		buf->data = nd;
+	}
+	memcpy(buf->data + buf->used, str, len);
+	buf->used += len;
+	return 0;
+}
+
+/* Remove last "num" symbols */
+size_t tc_buf_delete(struct tc_buf *buf, size_t num) {
+	if (buf->used > num) {
+		buf->used -= num;
+	} else {
+		num = buf->used;
+		buf->used = 0;
+	}
+	return num;
+}
+
+inline int tc_buf_isempty(struct tc_buf *buf) {
+	return (buf->used == 0);
+}
+
+inline void tc_buf_clear(struct tc_buf *buf) {
+	buf->used = 0;
+}
+
+/* Free membuffer */
+void tc_buf_free(struct tc_buf *buf) {
+	if (buf->data)
+		free(buf->data);
+}
+
+/* Init buffer as STR */
+int tc_buf_str(struct tc_buf *buf) {
+	if (tc_buf(buf))
+		return -1;
+	return tc_buf_append(buf, (void *)"\0", 1);
+}
+
+/* Append str to STR */
+int tc_buf_str_append(struct tc_buf *buf, char *str, size_t len) {
+	tc_buf_delete(buf, 1);
+	if (tc_buf_append(buf, (void *)str, len))
+		return -1;
+	if (tc_buf_append(buf, (void *)"\0", 1))
+		return -1;
+	return 0;
+}
+
+/* Remove trailing ws from STR */
+int tc_buf_str_stripws(struct tc_buf *buf) {
+	if (buf->data) {
+		buf->used = 1 + strip_end_ws(buf->data);
+		return 0;
+	}
+	return -1;
+}
+
+inline int tc_buf_str_isempty(struct tc_buf *buf) {
+	return (buf->used == 1 ? 1 : 0) || (tc_buf_isempty(buf));
+}
diff --git a/client/tarantool/tc_buf.h b/client/tarantool/tc_buf.h
new file mode 100644
index 0000000000000000000000000000000000000000..52383666e7a7adf1cd869c1e96ff3a4e197d781d
--- /dev/null
+++ b/client/tarantool/tc_buf.h
@@ -0,0 +1,51 @@
+/*
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#define TC_BUF_INIT_SIZE 4096
+#define TC_BUF_MULTIPLIER 2
+
+size_t strip_end_ws(char *str);
+
+struct tc_buf {
+	size_t size;
+	size_t used;
+	char *data;
+};
+
+int tc_buf(struct tc_buf *buf);
+void *tc_buf_realloc(void *data, size_t size);
+int tc_buf_append(struct tc_buf *buf, void *str, size_t len);
+size_t tc_buf_delete(struct tc_buf *buf, size_t len);
+int tc_buf_isempty(struct tc_buf *buf);
+void tc_buf_clear(struct tc_buf *buf);
+void tc_buf_free(struct tc_buf *buf);
+
+int tc_buf_str(struct tc_buf *buf);
+int tc_buf_str_append(struct tc_buf *buf, char *str, size_t len);
+int tc_buf_str_stripws(struct tc_buf *buf);
+int tc_buf_str_isempty(struct tc_buf *buf);
diff --git a/client/tarantool/tc_cli.c b/client/tarantool/tc_cli.c
index efe47330fb0f64b764fd38665ddb6edd2cf9d8dc..b7255ef4c6c195c69f8f8cbb917da4ab96a1ebff 100644
--- a/client/tarantool/tc_cli.c
+++ b/client/tarantool/tc_cli.c
@@ -32,6 +32,7 @@
 #include <stdarg.h>
 #include <string.h>
 #include <stdint.h>
+#include <ctype.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -39,6 +40,7 @@
 #include <fcntl.h>
 #include <signal.h>
 #include <errno.h>
+#include <wchar.h>
 
 #include <readline/readline.h>
 #include <readline/history.h>
@@ -58,9 +60,13 @@
 #include "client/tarantool/tc_query.h"
 #include "client/tarantool/tc_cli.h"
 #include "client/tarantool/tc_print.h"
+#include "client/tarantool/tc_buf.h"
 
 #define TC_DEFAULT_HISTORY_FILE ".tarantool_history"
 
+#define TC_ALLOCATION_ERROR "error: memory allocation failed for %zu bytes\n"
+#define TC_REALLOCATION_ERROR "error: memory reallocation failed for %zu bytes\n"
+
 extern struct tc tc;
 
 static inline int tc_cli_error(char *e) {
@@ -89,7 +95,9 @@ enum tc_keywords {
 	TC_TEE,
 	TC_NOTEE,
 	TC_LOADFILE,
-	TC_HELP
+	TC_HELP,
+	TC_SETOPT,
+	TC_SETOPT_DELIM
 };
 
 static struct tnt_lex_keyword tc_lex_keywords[] =
@@ -106,6 +114,10 @@ static struct tnt_lex_keyword tc_lex_keywords[] =
 	{ "tee", 3, TC_TEE },
 	{ "notee", 5, TC_NOTEE },
 	{ "loadfile", 8, TC_LOADFILE },
+	{ "s", 1, TC_SETOPT},
+	{ "setopt", 6, TC_SETOPT},
+	{ "delim", 5, TC_SETOPT_DELIM},
+	{ "delimiter", 9, TC_SETOPT_DELIM},
 	{ NULL, 0, TNT_TK_NONE }
 };
 
@@ -125,6 +137,8 @@ tc_cmd_usage(void)
 		" - tee 'path'\n"
 		" - notee\n"
 		" - loadfile 'path'\n"
+		" - setopt key=val\n"
+		" - (possible pairs: delim=\'str\')\n"
 		"...\n";
 	tc_printf("%s", usage);
 }
@@ -194,9 +208,9 @@ tc_cmd_loadfile(char *path, int *reconnect)
 	int fd = open(path, O_RDONLY);
 	if (fd == -1)
 		return -1;
-	char *buf = malloc(st.st_size);
+	char *buf = (char *)malloc(st.st_size);
 	if (buf == NULL) {
-		tc_printf("error: memory allocation failed for %zu bytes\n",
+		tc_printf(TC_ALLOCATION_ERROR,
 			  st.st_size);
 		return -1;
 	}
@@ -252,6 +266,37 @@ tc_cmd_try(char *cmd, size_t size, int *reconnect)
 		if (tc_cmd_loadfile((char*)TNT_TK_S(tk)->data, reconnect) == -1)
 			rc = TC_CLI_ERROR;
 		goto done;
+	case TC_SETOPT:
+		switch (tnt_lex(&lex, &tk)) {
+		case TC_SETOPT_DELIM:
+			if (tnt_lex(&lex, &tk) == '=' &&
+			    tnt_lex(&lex, &tk) == TNT_TK_STRING) {
+				if (!TNT_TK_S(tk)->size) {
+					tc.opt.delim = "";
+					tc.opt.delim_len = 0;
+					goto done;
+				}
+				char * temp = (char *)malloc(TNT_TK_S(tk)->size);
+				if (temp == NULL)
+					tc_error(TC_ALLOCATION_ERROR,
+						 TNT_TK_S(tk)->size);
+				strncpy(temp,
+					(const char *)TNT_TK_S(tk)->data,
+					TNT_TK_S(tk)->size + 1);
+				tc.opt.delim = temp;
+				tc.opt.delim_len = strlen(tc.opt.delim);
+			} else {
+				tc_printf("---\n");
+				tc_printf(" - Expected delim='string'\n");
+				tc_printf("---\n");
+			}
+			break;
+		default:
+			tc_printf("---\n");
+			tc_printf(" - Unknown option to set\n");
+			tc_printf("---\n");
+		}
+		goto done;
 	}
 	*reconnect = tc_cli_admin(cmd, rc == TC_CLI_EXIT);
 	if (*reconnect)
@@ -321,6 +366,56 @@ static void tc_cli_init(void) {
 		tc_error("signal initialization failed\n");
 }
 
+static char* tc_cli_readline_pipe() {
+	int size = 8192, pos = 0;
+	const size_t wcsize = sizeof(wchar_t);
+	char *str = (char *)malloc(size);
+	if (str == NULL)
+		tc_error(TC_ALLOCATION_ERROR, size);
+	wchar_t c;
+	while ((c = getwchar())) {
+		if (size < (pos + wcsize)) {
+			size *= 2;
+			char *nd = (char *)realloc(str, size);
+			if (nd == NULL)
+				tc_error(TC_REALLOCATION_ERROR, size);
+			str = nd;
+		}
+		if (c == '\r' || c == '\n' || c == WEOF) {
+			char c_t = (c != WEOF ? getchar() : '\n');
+			if (c_t != '\r' && c_t != '\n')
+				ungetc(c_t, stdin);
+			wctomb(str + pos++, 0);
+			break;
+		}
+		else
+			pos += wctomb(str + pos, c);
+	}
+	if (pos == 1 && c == WEOF) {
+		free(str);
+		return NULL;
+	}
+	return str;
+}
+
+
+
+static int check_delim(char* str, size_t len, size_t sep_len) {
+	const char *sep = tc.opt.delim;
+	len = strip_end_ws(str);
+	if (sep_len == 0)
+		return 1;
+	if (len < sep_len)
+		return 0;
+	size_t i;
+	for (i = len; sep_len > 0; --sep_len, --i)
+		if (str[i - 1] != sep[sep_len - 1])
+			return 0;
+	str[i] = '\0';
+	len = strip_end_ws(str);
+	return 1;
+}
+
 int tc_cli(void)
 {
 	/* initializing cli */
@@ -335,25 +430,62 @@ int tc_cli(void)
 
 	/* setting prompt */
 	char prompt[128];
-	snprintf(prompt, sizeof(prompt), "%s> ", tc.opt.host);
-
+	int prompt_len = snprintf(prompt, sizeof(prompt), "%s> ", tc.opt.host) - 2;
+	char prompt_delim[128];
 	/* interactive mode */
-	char *cmd;
-	while ((cmd = readline(prompt))) {
-		if (!cmd[0])
-			goto next;
-		int cmd_len = strlen(cmd);
-		tc_print_cmd2tee(prompt, cmd, cmd_len);
-		enum tc_cli_cmd_ret ret = tc_cli_cmd(cmd, cmd_len);
-		if (ret == TC_CLI_EXIT)
+	char *part_cmd;
+	struct tc_buf cmd;
+	if (tc_buf_str(&cmd))
+		tc_error(TC_REALLOCATION_ERROR,
+			 cmd.size);
+	while (1) {
+		if (isatty(STDIN_FILENO)) {
+			snprintf(prompt_delim, sizeof(prompt_delim),
+				 "%*s> ", prompt_len, "-");
+			part_cmd = readline(!tc_buf_str_isempty(&cmd) ? prompt_delim
+							   : prompt);
+		} else {
+			clearerr(stdin);
+			part_cmd = tc_cli_readline_pipe();
+		}
+		if (!part_cmd)
 			break;
-		add_history(cmd);
+		size_t part_cmd_len = strlen(part_cmd);
+		int delim_exists = check_delim(part_cmd,
+					       part_cmd_len,
+					       tc.opt.delim_len);
+		if (tc_buf_str_append(&cmd, part_cmd, strlen(part_cmd)))
+			tc_error(TC_REALLOCATION_ERROR,
+				 cmd.size);
+		free(part_cmd);
+		if (!delim_exists && !feof(stdin)) {
+			if (tc_buf_str_append(&cmd, " ", 1))
+				tc_error(TC_REALLOCATION_ERROR,
+					 cmd.size);
+			continue;
+		}
+		tc_buf_str_stripws(&cmd);
+		if (delim_exists && tc_buf_str_isempty(&cmd))
+			goto next;
+		tc_print_cmd2tee(cmd.used != 1 ? prompt_delim : prompt,
+				 cmd.data, cmd.used - 1);
+		enum tc_cli_cmd_ret ret = tc_cli_cmd(cmd.data,
+						     cmd.used - 1);
+		if (isatty(STDIN_FILENO))
+			add_history(cmd.data);
 next:
-		free(cmd);
-	}
+		tc_buf_clear(&cmd);
+		if (ret == TC_CLI_EXIT || feof(stdin)) {
+			tc_buf_free(&cmd);
+			break;
+		}
+}
 
 	/* updating history file */
 	write_history(history);
 	clear_history();
 	return 0;
 }
+
+#undef TC_ALLOCATION_ERROR
+#undef TC_REALLOCATION_ERROR
diff --git a/client/tarantool/tc_opt.c b/client/tarantool/tc_opt.c
index c666b292110c7216f1539657afc8e71f9d8d10d0..331ad3e59a836853b98be0064a95b3f2ab7a94bf 100644
--- a/client/tarantool/tc_opt.c
+++ b/client/tarantool/tc_opt.c
@@ -35,6 +35,7 @@
 
 #include "client/tarantool/tc_opt.h"
 
+
 #define TC_DEFAULT_HOST "localhost"
 #define TC_DEFAULT_PORT 33013
 #define TC_DEFAULT_PORT_ADMIN 33015
@@ -63,6 +64,14 @@ static const void *tc_options_def = gopt_start(
 		    gopt_longs("header"), NULL, "add file headers for the raw output"),
 	gopt_option('R', GOPT_ARG, gopt_shorts('R'),
 		    gopt_longs("rpl"), " <lsn>", "act as replica for the specified server"),
+	gopt_option('B', 0, gopt_shorts('B'),
+		    gopt_longs("bin"), NULL, "print STR in lua printer instead"
+		    " of NUM32 and NUM64, except arithmetic update arguments"),
+	gopt_option('D', GOPT_ARG, gopt_shorts('D'),
+		    gopt_longs("delim"), " <delim>",
+		    "if you use --cat, then it will add delim to an end of every line of your"
+		    "lua file, when used at CLI start of client, then it's replacement of "
+		    "setopt delim='<delim>' command"),
 	gopt_option('?', 0, gopt_shorts(0), gopt_longs("help"),
 		    NULL, "display this help and exit"),
 	gopt_option('v', 0, gopt_shorts('v'), gopt_longs("version"),
@@ -148,6 +157,17 @@ enum tc_opt_mode tc_opt_init(struct tc_opt *opt, int argc, char **argv)
 	if (gopt(tc_options, 'H'))
 		opt->raw_with_headers = 1;
 
+	/* string instead of num and num64 */
+	opt->str_instead_int = 0;
+	if (gopt(tc_options, 'B'))
+		opt->str_instead_int = 1;
+
+	/* set delimiter on start */
+	opt->delim = "";
+	opt->delim_len = 0;
+	if (gopt_arg(tc_options, 'D', &opt->delim))
+		opt->delim_len = strlen(opt->delim);
+
 	/* replica mode */
 	if (gopt_arg(tc_options, 'R', &arg)) {
 		opt->mode = TC_OPT_RPL;
diff --git a/client/tarantool/tc_opt.h b/client/tarantool/tc_opt.h
index 931e95150fcca5db80b95f7be830216aa784a41c..cef473890b3b1009f4ae54e671bd917537448699 100644
--- a/client/tarantool/tc_opt.h
+++ b/client/tarantool/tc_opt.h
@@ -57,10 +57,14 @@ struct tc_opt {
 	const char *format;
 	int raw;
 	int raw_with_headers;
-	void *printer;
+	int str_instead_int;
+	void *xlog_printer;
+	void *snap_printer;
 	const char *file;
 	char **cmdv;
 	int cmdc;
+	const char *delim;
+	size_t delim_len;
 };
 
 void tc_opt_usage(void);
diff --git a/client/tarantool/tc_print.c b/client/tarantool/tc_print.c
index 78f64dce43d529773c431ff0c9dbfcffc6546a95..bacdef37eb3d390221cb1e31668df138447d8b0d 100644
--- a/client/tarantool/tc_print.c
+++ b/client/tarantool/tc_print.c
@@ -37,6 +37,7 @@
 #include <unistd.h>
 #include <errno.h>
 
+
 #include <connector/c/include/tarantool/tnt.h>
 #include <connector/c/include/tarantool/tnt_xlog.h>
 #include <connector/c/include/tarantool/tnt_rpl.h>
@@ -49,6 +50,8 @@
 
 extern struct tc tc;
 
+/*##################### Base printing functions #####################*/
+
 void tc_print_tee(char *buf, size_t size) {
 	if (tc.tee_fd == -1)
 		return;
@@ -95,6 +98,8 @@ void tc_printf(char *fmt, ...) {
 	}
 }
 
+/*##################### string functions #####################*/
+
 static int tc_str_valid(char *data, uint32_t size) {
 	int length;
 	wchar_t dest;
@@ -111,19 +116,34 @@ static int tc_str_valid(char *data, uint32_t size) {
 	return 1;
 }
 
-static void tc_print_str(char *data, uint32_t size) {
+void tc_print_string(char *data, uint32_t size, char lua)
+{
 	if (tc_str_valid(data, size)) {
 		wchar_t dest;
 		int length;
 		mbtowc (NULL, NULL, 0);
 		while ((length = mbtowc(&dest, data, size)) > -1 && size > 0) {
 			if (dest >= 0x20) {
-				tc_printf ("%lc", dest);
+				if (lua)
+					switch (dest) {
+					case '\'':
+						tc_printf("\\\'");
+						break;
+					case '\\':
+						tc_printf("\\\\");
+						break;
+					default:
+						tc_printf ("%lc", dest);
+					}
+				else
+					tc_printf ("%lc", dest);
 			}
 			else {
 				switch (dest) {
 				case 0x00:
 					tc_printf("\\0");
+					length++;
+					/* Cause of mbtowc returns 0 when \0 */
 					break;
 				case 0x07:
 					tc_printf("\\a");
@@ -147,12 +167,10 @@ static void tc_print_str(char *data, uint32_t size) {
 					tc_printf("\\r");
 					break;
 				default:
-					tc_printf("\\x%02lX", 
+					tc_printf("\\x%02lX",
 						(unsigned long int)dest);
 					break;
 				}
-				if (length == 0) 
-					++length;
 			}
 			size -= length;
 			data += length;
@@ -166,7 +184,11 @@ static void tc_print_str(char *data, uint32_t size) {
 	}
 }
 
-static void tc_print_fields(struct tnt_tuple *tu) {
+/*##################### Tuple and Fields #####################*/
+/* tarantool */
+
+void tc_print_fields(struct tnt_tuple *tu)
+{
 	struct tnt_iter ifl;
 	tnt_iter(&ifl, tu);
 	while (tnt_next(&ifl)) {
@@ -183,7 +205,7 @@ static void tc_print_fields(struct tnt_tuple *tu) {
 			tc_printf("%"PRIu64, *((uint64_t*)data));
 			break;
 		default:
-			tc_print_str(data, size);
+			tc_print_string(data, size, 0);
 		}
 		tc_printf("'");
 	}
@@ -210,46 +232,46 @@ void tc_print_list(struct tnt_list *l)
 	tnt_iter_free(&it);
 }
 
-static void
-tc_printer_tarantool(struct tnt_log_header_v11 *hdr,
-		     struct tnt_request *r)
+/* lua */
+
+void tc_print_lua_field(char *data, uint32_t size, char string)
 {
-	tc_printf("%s lsn: %"PRIu64", time: %f, len: %"PRIu32"\n",
-		  tc_query_type(r->h.type),
-		  hdr->lsn,
-		  hdr->tm,
-		  hdr->len);
-	switch (r->h.type) {
-	case TNT_OP_INSERT:
-		tc_print_tuple(&r->r.insert.t);
+	if (string)
+		goto _string;
+	switch (size){
+	case 4:
+		tc_printf("%"PRIu32, *((uint32_t*)data));
 		break;
-	case TNT_OP_DELETE:
-		tc_print_tuple(&r->r.del.t);
-		break;
-	case TNT_OP_UPDATE:
-		tc_print_tuple(&r->r.update.t);
+	case 8:
+		tc_printf("%"PRIu64, *((uint64_t*)data));
 		break;
+	default:
+_string:
+		tc_printf("\'");
+		tc_print_string(data, size, 1);
+		tc_printf("\'");
 	}
 }
 
-static void
-tc_printer_raw(struct tnt_log_header_v11 *hdr, struct tnt_request *r)
+void tc_print_lua_fields(struct tnt_tuple *tu)
 {
-	if (tc.opt.raw_with_headers) {
-		fwrite(&tnt_log_marker_v11,
-		       sizeof(tnt_log_marker_v11), 1, stdout);
+	struct tnt_iter ifl;
+	tnt_iter(&ifl, tu);
+	while (tnt_next(&ifl)) {
+		if ((TNT_IFIELD_IDX(&ifl)) != 0)
+			tc_printf(", ");
+		char *data = TNT_IFIELD_DATA(&ifl);
+		uint32_t size = TNT_IFIELD_SIZE(&ifl);
+		tc_print_lua_field(data, size, tc.opt.str_instead_int);
 	}
-	fwrite(hdr, sizeof(*hdr), 1, stdout);
-	fwrite(r->origin, r->origin_size, 1, stdout);
+	if (ifl.status == TNT_ITER_FAIL)
+		tc_printf("<parsing error>");
+	tnt_iter_free(&ifl);
 }
 
-tc_printerf_t tc_print_getcb(const char *name)
+void tc_print_lua_tuple(struct tnt_tuple *tu)
 {
-	if (name == NULL)
-		return tc_printer_tarantool;
-	if (!strcasecmp(name, "tarantool"))
-		return tc_printer_tarantool;
-	if (!strcasecmp(name, "raw"))
-		return tc_printer_raw;
-	return NULL;
+	tc_printf("{");
+	tc_print_lua_fields(tu);
+	tc_printf("}");
 }
diff --git a/client/tarantool/tc_print.h b/client/tarantool/tc_print.h
index 4af4b1b87d3104fc0d56cce61f48bde9c269096a..fe2612e74b113fdae5b1ccdceb2fca883c91d63f 100644
--- a/client/tarantool/tc_print.h
+++ b/client/tarantool/tc_print.h
@@ -29,17 +29,19 @@
  * SUCH DAMAGE.
  */
 
-typedef void (*tc_printerf_t)(struct tnt_log_header_v11 *hdr,
-		              struct tnt_request *r);
-
 void tc_print_tee(char *buf, size_t size);
 void tc_print_cmd2tee(char *prompt, char *cmd, int size);
 void tc_printf(char *fmt, ...);
 void tc_print_buf(char *buf, size_t size);
 
+void tc_print_string(char *data, uint32_t size, char lua);
+
+void tc_print_fields(struct tnt_tuple *tu);
 void tc_print_tuple(struct tnt_tuple *tu);
 void tc_print_list(struct tnt_list *l);
 
-tc_printerf_t tc_print_getcb(const char *name);
+void tc_print_lua_field(char *data, uint32_t size, char string);
+void tc_print_lua_fields(struct tnt_tuple *tu);
+void tc_print_lua_tuple(struct tnt_tuple *tu);
 
 #endif /* TC_PRINT_H_INCLUDED */
diff --git a/client/tarantool/tc_print_snap.c b/client/tarantool/tc_print_snap.c
new file mode 100644
index 0000000000000000000000000000000000000000..e08d183994722288657c9d7687efafa98f7cbadb
--- /dev/null
+++ b/client/tarantool/tc_print_snap.c
@@ -0,0 +1,68 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdint.h>
+
+#include <connector/c/include/tarantool/tnt.h>
+#include <connector/c/include/tarantool/tnt_xlog.h>
+#include <connector/c/include/tarantool/tnt_snapshot.h>
+
+#include "client/tarantool/tc_opt.h"
+#include "client/tarantool/tc_admin.h"
+#include "client/tarantool/tc.h"
+#include "client/tarantool/tc_print.h"
+#include "client/tarantool/tc_print_snap.h"
+#include "client/tarantool/tc_query.h"
+#include "client/tarantool/tc_store.h"
+
+extern struct tc tc;
+
+static void
+tc_printer_snap_raw( struct tnt_log_row_snap_v11 *row,
+		     struct tnt_tuple *tu)
+{
+	if (tc.opt.raw_with_headers) {
+		fwrite(&tnt_log_marker_v11,
+			sizeof(tnt_log_marker_v11), 1, stdout);
+	}
+	fwrite(row, sizeof(row), 1, stdout);
+	fwrite(tu->data, tu->size, 1, stdout);
+}
+static void
+tc_printer_snap_tarantool( struct tnt_log_row_snap_v11 *row,
+			   struct tnt_tuple *tu)
+{
+	tc_printf("tag: %"PRIu16", cookie: %"PRIu64", space: %"PRIu32"\n",
+		row->tag,
+		row->cookie,
+		row->space);
+	tc_print_tuple(tu);
+
+}
+static void
+tc_printer_snap_lua( struct tnt_log_row_snap_v11 *row,
+		     struct tnt_tuple *tu)
+{
+	tc_printf("lua box.insert(%"PRIu32", ", row->space);
+	tc_print_lua_fields(tu);
+	tc_printf(")");
+	if (tc.opt.delim_len > 0)
+		tc_printf("%s\n", tc.opt.delim);
+	else
+		tc_printf("\n");
+}
+
+tc_printerf_snap_t tc_print_getsnapcb(const char *name)
+{
+	if (name == NULL)
+		return tc_printer_snap_tarantool;
+	if (!strcasecmp(name, "tarantool"))
+		return tc_printer_snap_tarantool;
+	if (!strcasecmp(name, "raw"))
+		return tc_printer_snap_raw;
+	if (!strcasecmp(name, "lua"))
+		return tc_printer_snap_lua;
+	return NULL;
+}
diff --git a/client/tarantool/tc_print_snap.h b/client/tarantool/tc_print_snap.h
new file mode 100644
index 0000000000000000000000000000000000000000..9bf467a2bc062be0b8e9c8cfe55dec5bc5d99250
--- /dev/null
+++ b/client/tarantool/tc_print_snap.h
@@ -0,0 +1,37 @@
+#ifndef TC_PRINT_SNAP_H_INCLUDED
+#define TC_PRINT_SNAP_H_INCLUDED
+/*
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+typedef void (*tc_printerf_snap_t)(struct tnt_log_row_snap_v11 *row,
+				   struct tnt_tuple *tu);
+
+tc_printerf_snap_t tc_print_getsnapcb(const char *name);
+
+#endif /* TC_PRINT_SNAP_H_INCLUDED */
diff --git a/client/tarantool/tc_print_xlog.c b/client/tarantool/tc_print_xlog.c
new file mode 100644
index 0000000000000000000000000000000000000000..57f48513cd957f02eea149a2e3b01d3865c573b3
--- /dev/null
+++ b/client/tarantool/tc_print_xlog.c
@@ -0,0 +1,197 @@
+/*
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <strings.h>
+
+#include <connector/c/include/tarantool/tnt.h>
+#include <connector/c/include/tarantool/tnt_xlog.h>
+#include <connector/c/include/tarantool/tnt_rpl.h>
+
+#include "client/tarantool/tc_opt.h"
+#include "client/tarantool/tc_admin.h"
+#include "client/tarantool/tc_print.h"
+#include "client/tarantool/tc_print_xlog.h"
+#include "client/tarantool/tc_query.h"
+#include "client/tarantool/tc_print.h"
+#include "client/tarantool/tc.h"
+
+extern struct tc tc;
+
+static void
+tc_printer_xlog_raw(struct tnt_log_header_v11 *hdr,
+		    struct tnt_request *r)
+{
+	if (tc.opt.raw_with_headers) {
+		fwrite(&tnt_log_marker_v11,
+			sizeof(tnt_log_marker_v11), 1, stdout);
+	}
+	fwrite(hdr, sizeof(*hdr), 1, stdout);
+	fwrite(r->origin, r->origin_size, 1, stdout);
+}
+
+static void
+tc_printer_xlog_tarantool(struct tnt_log_header_v11 *hdr,
+			  struct tnt_request *r)
+{
+	tc_printf("%s lsn: %"PRIu64", time: %f, len: %"PRIu32"\n",
+		tc_query_type(r->h.type),
+		hdr->lsn,
+		hdr->tm,
+		hdr->len);
+	switch (r->h.type) {
+	case TNT_OP_INSERT:
+		tc_print_tuple(&r->r.insert.t);
+		break;
+	case TNT_OP_DELETE:
+		tc_print_tuple(&r->r.del.t);
+		break;
+	case TNT_OP_UPDATE:
+		tc_print_tuple(&r->r.update.t);
+		break;
+	}
+}
+
+static void
+tc_printer_xlog_lua(struct tnt_log_header_v11 *hdr,
+		    struct tnt_request *r)
+{
+	tc_printf("lua box.");
+	switch (r->h.type) {
+	case TNT_OP_INSERT:
+		if (r->r.insert.h.flags && TNT_FLAG_REPLACE == TNT_FLAG_REPLACE)
+			tc_printf("replace(");
+		else
+			tc_printf("insert(");
+		tc_printf("%"PRIu32", ", r->r.insert.h.ns);
+		tc_print_lua_fields(&r->r.insert.t);
+		break;
+	case TNT_OP_DELETE:
+		tc_printf("delete(");
+		tc_printf("%"PRIu32", ", r->r.del.h.ns);
+		tc_print_lua_tuple(&r->r.del.t);
+		break;
+	case TNT_OP_UPDATE:
+		tc_printf("update(");
+		tc_printf("%"PRIu32", ", r->r.update.h.ns);
+		tc_print_lua_tuple(&r->r.update.t);
+		tc_printf(", '");
+		for (uint32_t i = 0; i < r->r.update.opc; i++) {
+			switch (r->r.update.opv[i].op) {
+			case TNT_UPDATE_ASSIGN:
+				tc_printf("=p");
+				break;
+			case TNT_UPDATE_ADD:
+				tc_printf("+p");
+				break;
+			case TNT_UPDATE_AND:
+				tc_printf("&p");
+				break;
+			case TNT_UPDATE_XOR:
+				tc_printf("^p");
+				break;
+			case TNT_UPDATE_OR:
+				tc_printf("|p");
+				break;
+			case TNT_UPDATE_SPLICE:
+				tc_printf(":p");
+				break;
+			case TNT_UPDATE_DELETE:
+				tc_printf("#p");
+				break;
+			case TNT_UPDATE_INSERT:
+				tc_printf("!p");
+				break;
+			}
+		}
+		tc_printf("'");
+		for (uint32_t i = 0; i < r->r.update.opc; i++) {
+			tc_printf(", %"PRIu32,
+				r->r.update.opv[i].field);
+			switch (r->r.update.opv[i].op){
+			case TNT_UPDATE_ADD:
+			case TNT_UPDATE_AND:
+			case TNT_UPDATE_XOR:
+			case TNT_UPDATE_OR:
+				tc_printf(", ");
+				tc_print_lua_field(r->r.update.opv[i].data,
+						r->r.update.opv[i].size, 0);
+				break;
+			case TNT_UPDATE_SPLICE:
+				tc_printf(", box.pack('ppp'");
+				char *data = r->r.update.opv[i].data;
+				size_t pos = 1;
+				tc_printf(", %"PRId32,
+					*(int32_t *)(data + pos));
+				pos += 5;
+				tc_printf(", %"PRId32", ",
+					*(int32_t *)(data + pos));
+				pos += 4 + r->r.update.opv[i].size_enc_len;
+				tc_printf("\'");
+				tc_print_string(data,
+					r->r.update.opv[i].size - pos, 1);
+				tc_printf("\'");
+				tc_printf(")");
+				break;
+			case TNT_UPDATE_DELETE:
+				tc_printf(", \'\'");
+				break;
+			case TNT_UPDATE_INSERT:
+			case TNT_UPDATE_ASSIGN:
+				tc_printf(", ");
+				tc_print_lua_field(r->r.update.opv[i].data,
+						r->r.update.opv[i].size,
+						tc.opt.str_instead_int);
+				break;
+			}
+		}
+		break;
+	}
+	tc_printf(") -- %"PRIu64, hdr->lsn);
+	if (tc.opt.delim_len > 0)
+		tc_printf("%s\n", tc.opt.delim);
+	else
+		tc_printf("\n");
+}
+
+tc_printerf_xlog_t tc_print_getxlogcb(const char *name)
+{
+	if (name == NULL)
+		return tc_printer_xlog_tarantool;
+	if (!strcasecmp(name, "tarantool"))
+		return tc_printer_xlog_tarantool;
+	if (!strcasecmp(name, "raw"))
+		return tc_printer_xlog_raw;
+	if (!strcasecmp(name, "lua"))
+		return tc_printer_xlog_lua;
+	return NULL;
+}
diff --git a/client/tarantool/tc_print_xlog.h b/client/tarantool/tc_print_xlog.h
new file mode 100644
index 0000000000000000000000000000000000000000..e9918606ee7d3278b3d3206f0aa23b404410c7d2
--- /dev/null
+++ b/client/tarantool/tc_print_xlog.h
@@ -0,0 +1,37 @@
+#ifndef TC_PRINT_XLOG_H_INCLUDED
+#define TC_PRINT_XLOG_H_INCLUDED
+/*
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the
+ *    following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+typedef void (*tc_printerf_xlog_t)(struct tnt_log_header_v11 *hdr,
+				   struct tnt_request *r);
+
+tc_printerf_xlog_t tc_print_getxlogcb(const char *name);
+
+#endif /* TC_PRINT_XLOG_H_INCLUDED */
diff --git a/client/tarantool/tc_store.c b/client/tarantool/tc_store.c
index c04d8c481b2fdd4c1149d51e65e486d3597bc8b4..ec2bc020e7b259ceebf9f49e53f5ab7b53b65f0f 100644
--- a/client/tarantool/tc_store.c
+++ b/client/tarantool/tc_store.c
@@ -44,6 +44,8 @@
 #include "client/tarantool/tc_admin.h"
 #include "client/tarantool/tc.h"
 #include "client/tarantool/tc_print.h"
+#include "client/tarantool/tc_print_xlog.h"
+#include "client/tarantool/tc_print_snap.h"
 #include "client/tarantool/tc_query.h"
 #include "client/tarantool/tc_store.h"
 
@@ -125,7 +127,7 @@ static int tc_store_printer(struct tnt_iter *i) {
 		return 0;
 	struct tnt_stream_xlog *s =
 		TNT_SXLOG_CAST(TNT_IREQUEST_STREAM(i));
-	((tc_printerf_t)tc.opt.printer)(&s->log.current.hdr, r);
+	((tc_printerf_xlog_t)tc.opt.xlog_printer)(&s->log.current.hdr, r);
 	return 0;
 }
 
@@ -133,21 +135,7 @@ static int tc_snapshot_printer(struct tnt_iter *i) {
 	struct tnt_tuple *tu = TNT_ISTORAGE_TUPLE(i);
 	struct tnt_stream_snapshot *ss =
 		TNT_SSNAPSHOT_CAST(TNT_ISTORAGE_STREAM(i));
-	if (tc.opt.raw) {
-		if (tc.opt.raw_with_headers) {
-			fwrite(&tnt_log_marker_v11,
-			       sizeof(tnt_log_marker_v11), 1, stdout);
-		}
-		fwrite(&ss->log.current.row_snap,
-		       sizeof(ss->log.current.row_snap), 1, stdout);
-		fwrite(tu->data, tu->size, 1, stdout);
-	} else {
-		tc_printf("tag: %"PRIu16", cookie: %"PRIu64", space: %"PRIu32"\n",
-			  ss->log.current.row_snap.tag,
-			  ss->log.current.row_snap.cookie,
-			  ss->log.current.row_snap.space);
-		tc_print_tuple(tu);
-	}
+	((tc_printerf_snap_t)tc.opt.snap_printer)(&ss->log.current.row_snap, tu);
 	return 0;
 }
 
@@ -200,6 +188,7 @@ int tc_store_cat(void)
 		fputs("\n", stdout);
 	}
 	int rc;
+
 	switch (type) {
 	case TNT_LOG_SNAPSHOT:
 		rc = tc_store_foreach_snapshot(tc_snapshot_printer);
diff --git a/connector/c/include/tp.h b/connector/c/include/tp.h
index 4d886719bb2fe7515e8528bf57daefc05ff0e770..d76e827be6d569bcb59fca7b3abe92a5f0d5e670 100644
--- a/connector/c/include/tp.h
+++ b/connector/c/include/tp.h
@@ -329,6 +329,12 @@ tp_unused(struct tp *p) {
  * data must be manually freed when the buffer is no longer
  * needed.
  * (eg. free(p->s));
+ * if realloc will return NULL, then you must destroy previous memory.
+ * (eg.
+ * if (tp_realloc(p, ..) == NULL) {
+ * 	free(p->s)
+ * 	return NULL;
+ * }
 */
 tp_function_unused static char*
 tp_realloc(struct tp *p, size_t required, size_t *size) {
diff --git a/connector/c/tnt/tnt_buf.c b/connector/c/tnt/tnt_buf.c
index c5209dd1b2effcaf52220e88dc7828d7cf831941..a67016197d2de33feb4637f56886f0bfa8f98b25 100644
--- a/connector/c/tnt/tnt_buf.c
+++ b/connector/c/tnt/tnt_buf.c
@@ -68,8 +68,10 @@ static char* tnt_buf_resize(struct tnt_stream *s, size_t size) {
 	size_t off = sb->size;
 	size_t nsize = off + size;
 	char *nd = realloc(sb->data, nsize);
-	if (nd == NULL)
+	if (nd == NULL) {
+		free(sb->data);
 		return NULL;
+	}
 	sb->data = nd;
 	sb->size = nsize;
 	return sb->data + off;
diff --git a/connector/c/tnt/tnt_tuple.c b/connector/c/tnt/tnt_tuple.c
index 0a9c36baf7451ed8da96ff71d2708e8d44e7e950..9b8cec4a6ae2aeaee781fcef811e80193b55551f 100644
--- a/connector/c/tnt/tnt_tuple.c
+++ b/connector/c/tnt/tnt_tuple.c
@@ -394,6 +394,7 @@ struct tnt_tuple *tnt_list_at(struct tnt_list *l, struct tnt_tuple *t) {
 	/* reallocating tuple data */
 	char *ndata = realloc(l->list, sizeof(struct tnt_list_ptr) * (l->count + 1));
 	if (ndata == NULL) {
+		free(l->list);
 		if (allocated)
 			tnt_tuple_free(t);
 		return NULL;