aboutsummaryrefslogtreecommitdiff
path: root/src/nvim
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim')
-rw-r--r--src/nvim/CMakeLists.txt1
-rw-r--r--src/nvim/README.md3
-rw-r--r--src/nvim/buffer.c6
-rw-r--r--src/nvim/bufwrite.c16
-rw-r--r--src/nvim/cmdhist.c7
-rw-r--r--src/nvim/eval/userfunc.c6
-rw-r--r--src/nvim/ex_docmd.c8
-rw-r--r--src/nvim/fileio.c27
-rw-r--r--src/nvim/lua/treesitter.c89
-rw-r--r--src/nvim/main.c14
-rw-r--r--src/nvim/move.c4
-rw-r--r--src/nvim/option.c2
-rw-r--r--src/nvim/os/stdpaths.c2
-rw-r--r--src/nvim/runtime.c2
-rw-r--r--src/nvim/tag.c2
-rw-r--r--src/nvim/testing.c4
-rw-r--r--src/nvim/textobject.c3
-rw-r--r--src/nvim/undo.c2
18 files changed, 152 insertions, 46 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 325b376b30..070cea3b59 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -836,6 +836,7 @@ if(ENABLE_ASAN_UBSAN)
-fsanitize=address
-fsanitize=undefined)
target_link_libraries(nvim PRIVATE -fsanitize=address -fsanitize=undefined)
+ target_compile_definitions(nvim PRIVATE ENABLE_ASAN_UBSAN)
elseif(ENABLE_MSAN)
message(STATUS "Enabling memory sanitizer for nvim.")
target_compile_options(nvim PRIVATE
diff --git a/src/nvim/README.md b/src/nvim/README.md
index cbd5daba4e..75155fb9c6 100644
--- a/src/nvim/README.md
+++ b/src/nvim/README.md
@@ -71,9 +71,8 @@ Create a directory to store logs:
Configure the sanitizer(s) via these environment variables:
# Change to detect_leaks=1 to detect memory leaks (slower, noisier).
- export ASAN_OPTIONS="detect_leaks=0:log_path=$HOME/logs/asan,handle_abort=1,handle_sigill=1"
+ export ASAN_OPTIONS="detect_leaks=0:log_path=$HOME/logs/asan"
# Show backtraces in the logs.
- export UBSAN_OPTIONS=print_stacktrace=1
export MSAN_OPTIONS="log_path=${HOME}/logs/msan"
export TSAN_OPTIONS="log_path=${HOME}/logs/tsan"
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index e734a340d9..49fd09ebd0 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -1084,11 +1084,11 @@ char *do_bufdel(int command, char *arg, int addr_count, int start_bnr, int end_b
if (deleted == 0) {
if (command == DOBUF_UNLOAD) {
- STRCPY(IObuff, _("E515: No buffers were unloaded"));
+ xstrlcpy(IObuff, _("E515: No buffers were unloaded"), IOSIZE);
} else if (command == DOBUF_DEL) {
- STRCPY(IObuff, _("E516: No buffers were deleted"));
+ xstrlcpy(IObuff, _("E516: No buffers were deleted"), IOSIZE);
} else {
- STRCPY(IObuff, _("E517: No buffers were wiped out"));
+ xstrlcpy(IObuff, _("E517: No buffers were wiped out"), IOSIZE);
}
errormsg = IObuff;
} else if (deleted >= p_report) {
diff --git a/src/nvim/bufwrite.c b/src/nvim/bufwrite.c
index 84c1276b8b..cfa3ea5bf3 100644
--- a/src/nvim/bufwrite.c
+++ b/src/nvim/bufwrite.c
@@ -745,7 +745,7 @@ static int buf_write_make_backup(char *fname, bool append, FileInfo *file_info_o
// the ones from the original file.
// First find a file name that doesn't exist yet (use some
// arbitrary numbers).
- STRCPY(IObuff, fname);
+ xstrlcpy(IObuff, fname, IOSIZE);
for (int i = 4913;; i += 123) {
char *tail = path_tail(IObuff);
size_t size = (size_t)(tail - IObuff);
@@ -1749,24 +1749,24 @@ restore_backup:
add_quoted_fname(IObuff, IOSIZE, buf, fname);
bool insert_space = false;
if (write_info.bw_conv_error) {
- STRCAT(IObuff, _(" CONVERSION ERROR"));
+ xstrlcat(IObuff, _(" CONVERSION ERROR"), IOSIZE);
insert_space = true;
if (write_info.bw_conv_error_lnum != 0) {
vim_snprintf_add(IObuff, IOSIZE, _(" in line %" PRId64 ";"),
(int64_t)write_info.bw_conv_error_lnum);
}
} else if (notconverted) {
- STRCAT(IObuff, _("[NOT converted]"));
+ xstrlcat(IObuff, _("[NOT converted]"), IOSIZE);
insert_space = true;
} else if (converted) {
- STRCAT(IObuff, _("[converted]"));
+ xstrlcat(IObuff, _("[converted]"), IOSIZE);
insert_space = true;
}
if (device) {
- STRCAT(IObuff, _("[Device]"));
+ xstrlcat(IObuff, _("[Device]"), IOSIZE);
insert_space = true;
} else if (newfile) {
- STRCAT(IObuff, new_file_message());
+ xstrlcat(IObuff, new_file_message(), IOSIZE);
insert_space = true;
}
if (no_eol) {
@@ -1780,9 +1780,9 @@ restore_backup:
msg_add_lines(insert_space, (long)lnum, nchars); // add line/char count
if (!shortmess(SHM_WRITE)) {
if (append) {
- STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [a]") : _(" appended"));
+ xstrlcat(IObuff, shortmess(SHM_WRI) ? _(" [a]") : _(" appended"), IOSIZE);
} else {
- STRCAT(IObuff, shortmess(SHM_WRI) ? _(" [w]") : _(" written"));
+ xstrlcat(IObuff, shortmess(SHM_WRI) ? _(" [w]") : _(" written"), IOSIZE);
}
}
diff --git a/src/nvim/cmdhist.c b/src/nvim/cmdhist.c
index 81b93e5304..fc84cecc1a 100644
--- a/src/nvim/cmdhist.c
+++ b/src/nvim/cmdhist.c
@@ -641,9 +641,10 @@ void ex_history(exarg_T *eap)
}
for (; !got_int && histype1 <= histype2; histype1++) {
- STRCPY(IObuff, "\n # ");
+ xstrlcpy(IObuff, "\n # ", IOSIZE);
assert(history_names[histype1] != NULL);
- STRCAT(STRCAT(IObuff, history_names[histype1]), " history");
+ xstrlcat(IObuff, history_names[histype1], IOSIZE);
+ xstrlcat(IObuff, " history", IOSIZE);
msg_puts_title(IObuff);
int idx = hisidx[histype1];
histentry_T *hist = history[histype1];
@@ -669,7 +670,7 @@ void ex_history(exarg_T *eap)
trunc_string(hist[i].hisstr, IObuff + strlen(IObuff),
Columns - 10, IOSIZE - (int)strlen(IObuff));
} else {
- STRCAT(IObuff, hist[i].hisstr);
+ xstrlcat(IObuff, hist[i].hisstr, IOSIZE);
}
msg_outtrans(IObuff);
}
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 7e20a298dd..a52b8d3f18 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -2892,9 +2892,9 @@ char *get_user_func_name(expand_T *xp, int idx)
cat_func_name(IObuff, IOSIZE, fp);
if (xp->xp_context != EXPAND_USER_FUNC) {
- STRCAT(IObuff, "(");
+ xstrlcat(IObuff, "(", IOSIZE);
if (!fp->uf_varargs && GA_EMPTY(&fp->uf_args)) {
- STRCAT(IObuff, ")");
+ xstrlcat(IObuff, ")", IOSIZE);
}
}
return IObuff;
@@ -3505,7 +3505,7 @@ char *get_return_cmd(void *rettv)
s = "";
}
- STRCPY(IObuff, ":return ");
+ xstrlcpy(IObuff, ":return ", IOSIZE);
xstrlcpy(IObuff + 8, s, IOSIZE - 8);
if (strlen(s) + 8 >= IOSIZE) {
STRCPY(IObuff + IOSIZE - 4, "...");
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 83232d5f17..9666d80de2 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -1454,7 +1454,7 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er
}
// Fail if command is invalid
if (eap->cmdidx == CMD_SIZE) {
- STRCPY(IObuff, _(e_not_an_editor_command));
+ xstrlcpy(IObuff, _(e_not_an_editor_command), IOSIZE);
// If the modifier was parsed OK the error must be in the following command
char *cmdname = after_modifier ? after_modifier : cmdline;
append_command(cmdname);
@@ -2044,7 +2044,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter
// Check for wrong commands.
if (ea.cmdidx == CMD_SIZE) {
if (!ea.skip) {
- STRCPY(IObuff, _(e_not_an_editor_command));
+ xstrlcpy(IObuff, _(e_not_an_editor_command), IOSIZE);
// If the modifier was parsed OK the error must be in the following
// command
char *cmdname = after_modifier ? after_modifier : *cmdlinep;
@@ -2321,7 +2321,7 @@ doend:
if (errormsg != NULL && *errormsg != NUL && !did_emsg) {
if (flags & DOCMD_VERBOSE) {
if (errormsg != IObuff) {
- STRCPY(IObuff, errormsg);
+ xstrlcpy(IObuff, errormsg, IOSIZE);
errormsg = IObuff;
}
append_command(*ea.cmdlinep);
@@ -2888,7 +2888,7 @@ static void append_command(char *cmd)
d -= utf_head_off(IObuff, d);
STRCPY(d, "...");
}
- STRCAT(IObuff, ": ");
+ xstrlcat(IObuff, ": ", IOSIZE);
d = IObuff + strlen(IObuff);
while (*s != NUL && d - IObuff + 5 < IOSIZE) {
if ((uint8_t)s[0] == 0xc2 && (uint8_t)s[1] == 0xa0) {
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index d659987686..57aa063504 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -1693,22 +1693,22 @@ failed:
#ifdef UNIX
if (S_ISFIFO(perm)) { // fifo
- STRCAT(IObuff, _("[fifo]"));
+ xstrlcat(IObuff, _("[fifo]"), IOSIZE);
c = true;
}
if (S_ISSOCK(perm)) { // or socket
- STRCAT(IObuff, _("[socket]"));
+ xstrlcat(IObuff, _("[socket]"), IOSIZE);
c = true;
}
# ifdef OPEN_CHR_FILES
if (S_ISCHR(perm)) { // or character special
- STRCAT(IObuff, _("[character special]"));
+ xstrlcat(IObuff, _("[character special]"), IOSIZE);
c = true;
}
# endif
#endif
if (curbuf->b_p_ro) {
- STRCAT(IObuff, shortmess(SHM_RO) ? _("[RO]") : _("[readonly]"));
+ xstrlcat(IObuff, shortmess(SHM_RO) ? _("[RO]") : _("[readonly]"), IOSIZE);
c = true;
}
if (read_no_eol_lnum) {
@@ -1716,18 +1716,18 @@ failed:
c = true;
}
if (ff_error == EOL_DOS) {
- STRCAT(IObuff, _("[CR missing]"));
+ xstrlcat(IObuff, _("[CR missing]"), IOSIZE);
c = true;
}
if (split) {
- STRCAT(IObuff, _("[long lines split]"));
+ xstrlcat(IObuff, _("[long lines split]"), IOSIZE);
c = true;
}
if (notconverted) {
- STRCAT(IObuff, _("[NOT converted]"));
+ xstrlcat(IObuff, _("[NOT converted]"), IOSIZE);
c = true;
} else if (converted) {
- STRCAT(IObuff, _("[converted]"));
+ xstrlcat(IObuff, _("[converted]"), IOSIZE);
c = true;
}
if (conv_error != 0) {
@@ -1739,7 +1739,7 @@ failed:
_("[ILLEGAL BYTE in line %" PRId64 "]"), (int64_t)illegal_byte);
c = true;
} else if (error) {
- STRCAT(IObuff, _("[READ ERRORS]"));
+ xstrlcat(IObuff, _("[READ ERRORS]"), IOSIZE);
c = true;
}
if (msg_add_fileformat(fileformat)) {
@@ -2128,17 +2128,17 @@ bool msg_add_fileformat(int eol_type)
{
#ifndef USE_CRNL
if (eol_type == EOL_DOS) {
- STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[dos]") : _("[dos format]"));
+ xstrlcat(IObuff, shortmess(SHM_TEXT) ? _("[dos]") : _("[dos format]"), IOSIZE);
return true;
}
#endif
if (eol_type == EOL_MAC) {
- STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[mac]") : _("[mac format]"));
+ xstrlcat(IObuff, shortmess(SHM_TEXT) ? _("[mac]") : _("[mac format]"), IOSIZE);
return true;
}
#ifdef USE_CRNL
if (eol_type == EOL_UNIX) {
- STRCAT(IObuff, shortmess(SHM_TEXT) ? _("[unix]") : _("[unix format]"));
+ xstrlcat(IObuff, shortmess(SHM_TEXT) ? _("[unix]") : _("[unix format]"), IOSIZE);
return true;
}
#endif
@@ -2170,8 +2170,7 @@ void msg_add_lines(int insert_space, long lnum, off_T nchars)
/// Append message for missing line separator to IObuff.
void msg_add_eol(void)
{
- STRCAT(IObuff,
- shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]"));
+ xstrlcat(IObuff, shortmess(SHM_LAST) ? _("[noeol]") : _("[Incomplete last line]"), IOSIZE);
}
bool time_differs(const FileInfo *file_info, long mtime, long mtime_ns) FUNC_ATTR_CONST
diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c
index dae1365272..a9e7838980 100644
--- a/src/nvim/lua/treesitter.c
+++ b/src/nvim/lua/treesitter.c
@@ -20,6 +20,7 @@
#include "nvim/api/private/helpers.h"
#include "nvim/buffer_defs.h"
#include "nvim/globals.h"
+#include "nvim/lua/executor.h"
#include "nvim/lua/treesitter.h"
#include "nvim/macros.h"
#include "nvim/map.h"
@@ -43,6 +44,13 @@ typedef struct {
int max_match_id;
} TSLua_cursor;
+typedef struct {
+ LuaRef cb;
+ lua_State *lstate;
+ bool lex;
+ bool parse;
+} TSLuaLoggerOpts;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "lua/treesitter.c.generated.h"
#endif
@@ -56,6 +64,8 @@ static struct luaL_Reg parser_meta[] = {
{ "included_ranges", parser_get_ranges },
{ "set_timeout", parser_set_timeout },
{ "timeout", parser_get_timeout },
+ { "_set_logger", parser_set_logger },
+ { "_logger", parser_get_logger },
{ NULL, NULL }
};
@@ -322,6 +332,12 @@ static int parser_gc(lua_State *L)
return 0;
}
+ TSLogger logger = ts_parser_logger(*p);
+ if (logger.log) {
+ TSLuaLoggerOpts *opts = (TSLuaLoggerOpts *)logger.payload;
+ xfree(opts);
+ }
+
ts_parser_delete(*p);
return 0;
}
@@ -669,9 +685,82 @@ static int parser_get_timeout(lua_State *L)
}
lua_pushinteger(L, (long)ts_parser_timeout_micros(*p));
+ return 1;
+}
+
+static void logger_cb(void *payload, TSLogType logtype, const char *s)
+{
+ TSLuaLoggerOpts *opts = (TSLuaLoggerOpts *)payload;
+ if ((!opts->lex && logtype == TSLogTypeLex)
+ || (!opts->parse && logtype == TSLogTypeParse)) {
+ return;
+ }
+
+ lua_State *lstate = opts->lstate;
+
+ nlua_pushref(lstate, opts->cb);
+ lua_pushstring(lstate, logtype == TSLogTypeParse ? "parse" : "lex");
+ lua_pushstring(lstate, s);
+ if (lua_pcall(lstate, 2, 0, 0)) {
+ luaL_error(lstate, "Error executing treesitter logger callback");
+ }
+}
+
+static int parser_set_logger(lua_State *L)
+{
+ TSParser **p = parser_check(L, 1);
+ if (!p) {
+ return 0;
+ }
+
+ if (!lua_isboolean(L, 2)) {
+ return luaL_argerror(L, 2, "boolean expected");
+ }
+
+ if (!lua_isboolean(L, 3)) {
+ return luaL_argerror(L, 3, "boolean expected");
+ }
+
+ if (!lua_isfunction(L, 4)) {
+ return luaL_argerror(L, 4, "function expected");
+ }
+
+ TSLuaLoggerOpts *opts = xmalloc(sizeof(TSLuaLoggerOpts));
+
+ *opts = (TSLuaLoggerOpts){
+ .lex = lua_toboolean(L, 2),
+ .parse = lua_toboolean(L, 3),
+ .cb = nlua_ref_global(L, 4),
+ .lstate = L
+ };
+
+ TSLogger logger = {
+ .payload = (void *)opts,
+ .log = logger_cb
+ };
+
+ ts_parser_set_logger(*p, logger);
return 0;
}
+static int parser_get_logger(lua_State *L)
+{
+ TSParser **p = parser_check(L, 1);
+ if (!p) {
+ return 0;
+ }
+
+ TSLogger logger = ts_parser_logger(*p);
+ if (logger.log) {
+ TSLuaLoggerOpts *opts = (TSLuaLoggerOpts *)logger.payload;
+ nlua_pushref(L, opts->cb);
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
// Tree methods
/// push tree interface on lua stack.
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 659eccc6f0..4999d9dd2a 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -2222,3 +2222,17 @@ static void check_swap_exists_action(void)
}
handle_swap_exists(NULL);
}
+
+#ifdef ENABLE_ASAN_UBSAN
+const char *__ubsan_default_options(void);
+const char *__ubsan_default_options(void)
+{
+ return "print_stacktrace=1";
+}
+
+const char *__asan_default_options(void);
+const char *__asan_default_options(void)
+{
+ return "handle_abort=1,handle_sigill=1";
+}
+#endif
diff --git a/src/nvim/move.c b/src/nvim/move.c
index 6a6f8149dd..ead2b3b0d3 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -1502,11 +1502,11 @@ void adjust_skipcol(void)
} else {
curwin->w_skipcol -= width1;
}
- redraw_later(curwin, UPD_NOT_VALID);
scrolled = true;
- validate_virtcol();
}
if (scrolled) {
+ validate_virtcol();
+ redraw_later(curwin, UPD_NOT_VALID);
return; // don't scroll in the other direction now
}
long col = curwin->w_virtcol - curwin->w_skipcol + scrolloff_cols;
diff --git a/src/nvim/option.c b/src/nvim/option.c
index fc1fc87b62..327c5fc089 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -1626,7 +1626,7 @@ int do_set(char *arg, int opt_flags)
int i = (int)strlen(IObuff) + 2;
if (i + (arg - startarg) < IOSIZE) {
// append the argument with the error
- STRCAT(IObuff, ": ");
+ xstrlcat(IObuff, ": ", IOSIZE);
assert(arg >= startarg);
memmove(IObuff + i, startarg, (size_t)(arg - startarg));
IObuff[i + (arg - startarg)] = NUL;
diff --git a/src/nvim/os/stdpaths.c b/src/nvim/os/stdpaths.c
index 5235828f7a..8b62b9e895 100644
--- a/src/nvim/os/stdpaths.c
+++ b/src/nvim/os/stdpaths.c
@@ -130,7 +130,7 @@ char *get_xdg_home(const XDGVarType idx)
xstrlcpy(IObuff, appname, appname_len + 1);
#if defined(MSWIN)
if (idx == kXDGDataHome || idx == kXDGStateHome) {
- STRCAT(IObuff, "-data");
+ xstrlcat(IObuff, "-data", IOSIZE);
}
#endif
dir = concat_fnames_realloc(dir, IObuff, true);
diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c
index f7b7723553..a9068fabc8 100644
--- a/src/nvim/runtime.c
+++ b/src/nvim/runtime.c
@@ -1544,7 +1544,7 @@ static inline char *add_dir(char *dest, const char *const dir, const size_t dir_
xstrlcpy(IObuff, appname, appname_len + 1);
#if defined(MSWIN)
if (type == kXDGDataHome || type == kXDGStateHome) {
- STRCAT(IObuff, "-data");
+ xstrlcat(IObuff, "-data", IOSIZE);
appname_len += 5;
}
#endif
diff --git a/src/nvim/tag.c b/src/nvim/tag.c
index 81bca67cf7..18331cc95d 100644
--- a/src/nvim/tag.c
+++ b/src/nvim/tag.c
@@ -732,7 +732,7 @@ void do_tag(char *tag, int type, int count, int forceit, int verbose)
num_matches,
max_num_matches != MAXCOL ? _(" or more") : "");
if (ic) {
- STRCAT(IObuff, _(" Using tag with different case!"));
+ xstrlcat(IObuff, _(" Using tag with different case!"), IOSIZE);
}
if ((num_matches > prev_num_matches || new_tag)
&& num_matches > 1) {
diff --git a/src/nvim/testing.c b/src/nvim/testing.c
index 5483a58525..25ec8e898a 100644
--- a/src/nvim/testing.c
+++ b/src/nvim/testing.c
@@ -418,11 +418,11 @@ static int assert_equalfile(typval_T *argvars)
const int c2 = fgetc(fd2);
if (c1 == EOF) {
if (c2 != EOF) {
- STRCPY(IObuff, "first file is shorter");
+ xstrlcpy(IObuff, "first file is shorter", IOSIZE);
}
break;
} else if (c2 == EOF) {
- STRCPY(IObuff, "second file is shorter");
+ xstrlcpy(IObuff, "second file is shorter", IOSIZE);
break;
} else {
line1[lineidx] = (char)c1;
diff --git a/src/nvim/textobject.c b/src/nvim/textobject.c
index 428b14a68d..5036c10827 100644
--- a/src/nvim/textobject.c
+++ b/src/nvim/textobject.c
@@ -22,6 +22,7 @@
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
+#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option_defs.h"
#include "nvim/pos.h"
@@ -414,6 +415,7 @@ int bck_word(long count, bool bigword, bool stop)
finished:
stop = false;
}
+ adjust_skipcol();
return OK;
}
@@ -518,6 +520,7 @@ int bckend_word(long count, bool bigword, bool eol)
}
}
}
+ adjust_skipcol();
return OK;
}
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 35f46e512d..00a3922a5b 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -2667,7 +2667,7 @@ void ex_undolist(exarg_T *eap)
undo_fmt_time(IObuff + strlen(IObuff), IOSIZE - strlen(IObuff), uhp->uh_time);
if (uhp->uh_save_nr > 0) {
while (strlen(IObuff) < 33) {
- STRCAT(IObuff, " ");
+ xstrlcat(IObuff, " ", IOSIZE);
}
vim_snprintf_add(IObuff, IOSIZE, " %3ld", uhp->uh_save_nr);
}