aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2018-04-27 09:25:02 +0200
committerGitHub <noreply@github.com>2018-04-27 09:25:02 +0200
commit53f11dcfc7139fe6c8a6b114db4bfec5d91005a9 (patch)
treee9bfbaf10fc6681bbbcba0a0eabdce8a6f6840b5
parent009ccfe170ada2c78ca7feabda567a7e901fb30b (diff)
parent4ce8521ee4a72e050bd187c2986708c5f98c7442 (diff)
downloadrneovim-53f11dcfc7139fe6c8a6b114db4bfec5d91005a9.tar.gz
rneovim-53f11dcfc7139fe6c8a6b114db4bfec5d91005a9.tar.bz2
rneovim-53f11dcfc7139fe6c8a6b114db4bfec5d91005a9.zip
Merge #8218 'Fix errors reported by PVS'
closes #4983
-rw-r--r--config/pathdef.c.in2
-rwxr-xr-xscripts/pvscheck.sh42
-rw-r--r--src/nvim/api/buffer.c8
-rw-r--r--src/nvim/api/vim.c2
-rw-r--r--src/nvim/buffer.c150
-rw-r--r--src/nvim/charset.c261
-rw-r--r--src/nvim/diff.c20
-rw-r--r--src/nvim/edit.c2
-rw-r--r--src/nvim/eval.c88
-rw-r--r--src/nvim/eval/decode.c2
-rw-r--r--src/nvim/eval/typval.c2
-rw-r--r--src/nvim/eval/typval.h14
-rw-r--r--src/nvim/eval/typval_encode.c.h8
-rw-r--r--src/nvim/event/loop.h2
-rw-r--r--src/nvim/event/process.c2
-rw-r--r--src/nvim/ex_cmds.c142
-rw-r--r--src/nvim/ex_docmd.c30
-rw-r--r--src/nvim/ex_getln.c73
-rw-r--r--src/nvim/file_search.c30
-rw-r--r--src/nvim/fileio.c17
-rw-r--r--src/nvim/fold.c2
-rw-r--r--src/nvim/generators/gen_api_dispatch.lua2
-rw-r--r--src/nvim/globals.h8
-rw-r--r--src/nvim/if_cscope.c4
-rw-r--r--src/nvim/lib/kvec.h2
-rw-r--r--src/nvim/mbyte.c64
-rw-r--r--src/nvim/mbyte.h7
-rw-r--r--src/nvim/memline.c19
-rw-r--r--src/nvim/memory.c22
-rw-r--r--src/nvim/message.c5
-rw-r--r--src/nvim/ops.c49
-rw-r--r--src/nvim/option.c72
-rw-r--r--src/nvim/os/env.c160
-rw-r--r--src/nvim/os/fs.c2
-rw-r--r--src/nvim/path.c5
-rw-r--r--src/nvim/popupmnu.c2
-rw-r--r--src/nvim/pos.h6
-rw-r--r--src/nvim/quickfix.c35
-rw-r--r--src/nvim/regexp_nfa.c18
-rw-r--r--src/nvim/screen.c291
-rw-r--r--src/nvim/search.c69
-rw-r--r--src/nvim/spell.c22
-rw-r--r--src/nvim/spellfile.c80
-rw-r--r--src/nvim/strings.c18
-rw-r--r--src/nvim/strings.h18
-rw-r--r--src/nvim/syntax.c81
-rw-r--r--src/nvim/tui/tui.c6
-rw-r--r--src/nvim/ugrid.h2
-rw-r--r--src/nvim/ui_bridge.c2
-rw-r--r--src/nvim/undo.c4
-rw-r--r--src/nvim/viml/parser/expressions.c10
-rw-r--r--src/nvim/window.c5
-rw-r--r--test/functional/eval/sort_spec.lua15
-rw-r--r--test/functional/eval/uniq_spec.lua31
54 files changed, 1032 insertions, 1003 deletions
diff --git a/config/pathdef.c.in b/config/pathdef.c.in
index 4579fbe455..41950f5ac5 100644
--- a/config/pathdef.c.in
+++ b/config/pathdef.c.in
@@ -1,3 +1,5 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include "${PROJECT_SOURCE_DIR}/src/nvim/vim.h"
char *default_vim_dir = "${CMAKE_INSTALL_FULL_DATAROOTDIR}/nvim";
char *default_vimruntime_dir = "";
diff --git a/scripts/pvscheck.sh b/scripts/pvscheck.sh
index 314966f6aa..11b672c515 100755
--- a/scripts/pvscheck.sh
+++ b/scripts/pvscheck.sh
@@ -21,13 +21,14 @@ help() {
echo 'Usage:'
echo ' pvscheck.sh [--pvs URL] [--deps] [--environment-cc]'
echo ' [target-directory [branch]]'
- echo ' pvscheck.sh [--pvs URL] [--recheck] [--environment-cc]'
+ echo ' pvscheck.sh [--pvs URL] [--recheck] [--environment-cc] [--update]'
echo ' [target-directory]'
echo ' pvscheck.sh [--pvs URL] --only-analyse [target-directory]'
echo ' pvscheck.sh [--pvs URL] --pvs-install {target-directory}'
echo ' pvscheck.sh --patch [--only-build]'
echo
echo ' --pvs: Fetch pvs-studio from URL.'
+ echo
echo ' --pvs detect: Auto-detect latest version (by scraping viva64.com).'
echo
echo ' --deps: (for regular run) Use top-level Makefile and build deps.'
@@ -47,6 +48,8 @@ help() {
echo
echo ' --recheck: run analysis on a prepared target directory.'
echo
+ echo ' --update: when rechecking first do a pull.'
+ echo
echo ' --only-analyse: run analysis on a prepared target directory '
echo ' without building Neovim.'
echo
@@ -302,8 +305,16 @@ create_compile_commands() {(
# realpath is not available in Ubuntu trusty yet.
realdir() {(
local dir="$1"
- cd "$dir"
- printf '%s\n' "$PWD"
+ local add=""
+ while ! cd "$dir" 2>/dev/null ; do
+ add="${dir##*/}/$add"
+ local new_dir="${dir%/*}"
+ if test "$new_dir" = "$dir" ; then
+ return 1
+ fi
+ dir="$new_dir"
+ done
+ printf '%s\n' "$PWD/$add"
)}
patch_sources() {(
@@ -353,9 +364,12 @@ run_analysis() {(
--file build/compile_commands.json \
--sourcetree-root . || true
- plog-converter -t xml -o PVS-studio.xml PVS-studio.log
- plog-converter -t errorfile -o PVS-studio.err PVS-studio.log
- plog-converter -t tasklist -o PVS-studio.tsk PVS-studio.log
+ rm -rf PVS-studio.{xml,err,tsk,html.d}
+ local plog_args="PVS-studio.log --srcRoot . --excludedCodes V011"
+ plog-converter $plog_args --renderTypes xml --output PVS-studio.xml
+ plog-converter $plog_args --renderTypes errorfile --output PVS-studio.err
+ plog-converter $plog_args --renderTypes tasklist --output PVS-studio.tsk
+ plog-converter $plog_args --renderTypes fullhtml --output PVS-studio.html.d
)}
detect_url() {
@@ -389,13 +403,24 @@ do_check() {
install_pvs "$tgt" "$pvs_url"
- do_recheck "$tgt" "$deps" "$environment_cc"
+ do_recheck "$tgt" "$deps" "$environment_cc" ""
}
do_recheck() {
local tgt="$1" ; shift
local deps="$1" ; shift
local environment_cc="$1" ; shift
+ local update="$1" ; shift
+
+ if test -n "$update" ; then
+ (
+ cd "$tgt"
+ local branch="$(git rev-parse --abbrev-ref HEAD)"
+ git checkout --detach
+ git fetch -f origin "${branch}:${branch}"
+ git checkout -f "$branch"
+ )
+ fi
create_compile_commands "$tgt" "$deps" "$environment_cc"
@@ -427,6 +452,7 @@ main() {
pvs-install store_const \
deps store_const \
environment-cc store_const \
+ update store_const \
-- \
'modify realdir tgt "$PWD/../neovim-pvs"' \
'store branch master' \
@@ -445,7 +471,7 @@ main() {
elif test -n "$pvs_install" ; then
install_pvs "$tgt" "$pvs_url"
elif test -n "$recheck" ; then
- do_recheck "$tgt" "$deps" "$environment_cc"
+ do_recheck "$tgt" "$deps" "$environment_cc" "$update"
elif test -n "$only_analyse" ; then
do_analysis "$tgt"
else
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index af723639c5..6be981a18e 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -186,12 +186,12 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id,
for (size_t i = 0; i < rv.size; i++) {
int64_t lnum = start + (int64_t)i;
- if (lnum > LONG_MAX) {
+ if (lnum >= MAXLNUM) {
api_set_error(err, kErrorTypeValidation, "Line index is too high");
goto end;
}
- const char *bufstr = (char *) ml_get_buf(buf, (linenr_T) lnum, false);
+ const char *bufstr = (char *)ml_get_buf(buf, (linenr_T)lnum, false);
Object str = STRING_OBJ(cstr_to_string(bufstr));
// Vim represents NULs as NLs, but this may confuse clients.
@@ -360,7 +360,7 @@ void nvim_buf_set_lines(uint64_t channel_id,
for (size_t i = 0; i < to_replace; i++) {
int64_t lnum = start + (int64_t)i;
- if (lnum > LONG_MAX) {
+ if (lnum >= MAXLNUM) {
api_set_error(err, kErrorTypeValidation, "Index value is too high");
goto end;
}
@@ -378,7 +378,7 @@ void nvim_buf_set_lines(uint64_t channel_id,
for (size_t i = to_replace; i < new_len; i++) {
int64_t lnum = start + (int64_t)i - 1;
- if (lnum > LONG_MAX) {
+ if (lnum >= MAXLNUM) {
api_set_error(err, kErrorTypeValidation, "Index value is too high");
goto end;
}
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 64fe1359c6..af3d379870 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -1200,7 +1200,7 @@ Dictionary nvim_parse_expression(String expr, String flags, Boolean highlight,
.node_p = &node->next,
.ret_node_p = cur_item.ret_node_p + 1,
}));
- } else if (node != NULL) {
+ } else {
kv_drop(ast_conv_stack, 1);
ret_node->items[ret_node->size++] = (KeyValuePair) {
.key = STATIC_CSTR_TO_STRING("type"),
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 0cd6f628b5..ba63822837 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -22,6 +22,7 @@
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
+#include <assert.h>
#include "nvim/api/private/handle.h"
#include "nvim/api/private/helpers.h"
@@ -2885,15 +2886,13 @@ static char_u *lasticon = NULL;
void maketitle(void)
{
- char_u *p;
char_u *t_str = NULL;
char_u *i_name;
char_u *i_str = NULL;
int maxlen = 0;
int len;
int mustset;
- char_u buf[IOSIZE];
- int off;
+ char buf[IOSIZE];
if (!redrawing()) {
/* Postpone updating the title when 'lazyredraw' is set. */
@@ -2913,97 +2912,117 @@ void maketitle(void)
}
}
- t_str = buf;
if (*p_titlestring != NUL) {
if (stl_syntax & STL_IN_TITLE) {
int use_sandbox = FALSE;
int save_called_emsg = called_emsg;
use_sandbox = was_set_insecurely((char_u *)"titlestring", 0);
- called_emsg = FALSE;
- build_stl_str_hl(curwin, t_str, sizeof(buf),
- p_titlestring, use_sandbox,
- 0, maxlen, NULL, NULL);
- if (called_emsg)
- set_string_option_direct((char_u *)"titlestring", -1,
- (char_u *)"", OPT_FREE, SID_ERROR);
+ called_emsg = false;
+ build_stl_str_hl(curwin, (char_u *)buf, sizeof(buf),
+ p_titlestring, use_sandbox,
+ 0, maxlen, NULL, NULL);
+ t_str = (char_u *)buf;
+ if (called_emsg) {
+ set_string_option_direct((char_u *)"titlestring", -1, (char_u *)"",
+ OPT_FREE, SID_ERROR);
+ }
called_emsg |= save_called_emsg;
- } else
+ } else {
t_str = p_titlestring;
+ }
} else {
- /* format: "fname + (path) (1 of 2) - VIM" */
-
-#define SPACE_FOR_FNAME (IOSIZE - 100)
-#define SPACE_FOR_DIR (IOSIZE - 20)
-#define SPACE_FOR_ARGNR (IOSIZE - 10) /* at least room for " - VIM" */
- if (curbuf->b_fname == NULL)
- STRLCPY(buf, _("[No Name]"), SPACE_FOR_FNAME + 1);
- else {
- p = transstr(path_tail(curbuf->b_fname));
- STRLCPY(buf, p, SPACE_FOR_FNAME + 1);
- xfree(p);
+ // Format: "fname + (path) (1 of 2) - VIM".
+
+#define SPACE_FOR_FNAME (sizeof(buf) - 100)
+#define SPACE_FOR_DIR (sizeof(buf) - 20)
+#define SPACE_FOR_ARGNR (sizeof(buf) - 10) // At least room for " - NVIM".
+ char *buf_p = buf;
+ if (curbuf->b_fname == NULL) {
+ const size_t size = xstrlcpy(buf_p, _("[No Name]"),
+ SPACE_FOR_FNAME + 1);
+ buf_p += MIN(size, SPACE_FOR_FNAME);
+ } else {
+ buf_p += transstr_buf((const char *)path_tail(curbuf->b_fname),
+ buf_p, SPACE_FOR_FNAME + 1);
}
switch (bufIsChanged(curbuf)
- + (curbuf->b_p_ro * 2)
- + (!MODIFIABLE(curbuf) * 4)) {
- case 1: STRCAT(buf, " +"); break;
- case 2: STRCAT(buf, " ="); break;
- case 3: STRCAT(buf, " =+"); break;
- case 4:
- case 6: STRCAT(buf, " -"); break;
- case 5:
- case 7: STRCAT(buf, " -+"); break;
+ | (curbuf->b_p_ro << 1)
+ | (!MODIFIABLE(curbuf) << 2)) {
+ case 0: break;
+ case 1: buf_p = strappend(buf_p, " +"); break;
+ case 2: buf_p = strappend(buf_p, " ="); break;
+ case 3: buf_p = strappend(buf_p, " =+"); break;
+ case 4:
+ case 6: buf_p = strappend(buf_p, " -"); break;
+ case 5:
+ case 7: buf_p = strappend(buf_p, " -+"); break;
+ default: assert(false);
}
if (curbuf->b_fname != NULL) {
- /* Get path of file, replace home dir with ~ */
- off = (int)STRLEN(buf);
- buf[off++] = ' ';
- buf[off++] = '(';
- home_replace(curbuf, curbuf->b_ffname,
- buf + off, (size_t)(SPACE_FOR_DIR - off), true);
+ // Get path of file, replace home dir with ~.
+ *buf_p++ = ' ';
+ *buf_p++ = '(';
+ home_replace(curbuf, curbuf->b_ffname, (char_u *)buf_p,
+ (SPACE_FOR_DIR - (size_t)(buf_p - buf)), true);
#ifdef BACKSLASH_IN_FILENAME
- /* avoid "c:/name" to be reduced to "c" */
- if (isalpha(buf[off]) && buf[off + 1] == ':')
- off += 2;
+ // Avoid "c:/name" to be reduced to "c".
+ if (isalpha((uint8_t)buf_p) && *(buf_p + 1) == ':') {
+ buf_p += 2;
+ }
#endif
- /* remove the file name */
- p = path_tail_with_sep(buf + off);
- if (p == buf + off)
- /* must be a help buffer */
- STRLCPY(buf + off, _("help"), SPACE_FOR_DIR - off);
- else
+ // Remove the file name.
+ char *p = (char *)path_tail_with_sep((char_u *)buf_p);
+ if (p == buf_p) {
+ // Must be a help buffer.
+ xstrlcpy(buf_p, _("help"), SPACE_FOR_DIR - (size_t)(buf_p - buf));
+ } else {
*p = NUL;
+ }
- /* Translate unprintable chars and concatenate. Keep some
- * room for the server name. When there is no room (very long
- * file name) use (...). */
- if (off < SPACE_FOR_DIR) {
- p = transstr(buf + off);
- STRLCPY(buf + off, p, SPACE_FOR_DIR - off + 1);
- xfree(p);
+ // Translate unprintable chars and concatenate. Keep some
+ // room for the server name. When there is no room (very long
+ // file name) use (...).
+ if ((size_t)(buf_p - buf) < SPACE_FOR_DIR) {
+ char *const tbuf = transstr(buf_p);
+ const size_t free_space = SPACE_FOR_DIR - (size_t)(buf_p - buf) + 1;
+ const size_t dir_len = xstrlcpy(buf_p, tbuf, free_space);
+ buf_p += MIN(dir_len, free_space - 1);
+ xfree(tbuf);
} else {
- STRLCPY(buf + off, "...", SPACE_FOR_ARGNR - off + 1);
+ const size_t free_space = SPACE_FOR_ARGNR - (size_t)(buf_p - buf) + 1;
+ const size_t dots_len = xstrlcpy(buf_p, "...", free_space);
+ buf_p += MIN(dots_len, free_space - 1);
}
- STRCAT(buf, ")");
+ *buf_p++ = ')';
+ *buf_p = NUL;
+ } else {
+ *buf_p = NUL;
}
- append_arg_number(curwin, buf, SPACE_FOR_ARGNR, FALSE);
+ append_arg_number(curwin, (char_u *)buf_p,
+ (int)(SPACE_FOR_ARGNR - (size_t)(buf_p - buf)), false);
- STRCAT(buf, " - NVIM");
+ xstrlcat(buf_p, " - NVIM", (sizeof(buf) - (size_t)(buf_p - buf)));
if (maxlen > 0) {
- /* make it shorter by removing a bit in the middle */
- if (vim_strsize(buf) > maxlen)
- trunc_string(buf, buf, maxlen, IOSIZE);
+ // Make it shorter by removing a bit in the middle.
+ if (vim_strsize((char_u *)buf) > maxlen) {
+ trunc_string((char_u *)buf, (char_u *)buf, maxlen, sizeof(buf));
+ }
}
+ t_str = (char_u *)buf;
+#undef SPACE_FOR_FNAME
+#undef SPACE_FOR_DIR
+#undef SPACE_FOR_ARGNR
}
}
mustset = ti_change(t_str, &lasttitle);
if (p_icon) {
- i_str = buf;
+ i_str = (char_u *)buf;
if (*p_iconstring != NUL) {
if (stl_syntax & STL_IN_ICON) {
int use_sandbox = FALSE;
@@ -3091,7 +3110,6 @@ void free_titles(void)
/// be used when printing numbers in the status line.
typedef enum {
kNumBaseDecimal = 10,
- kNumBaseOctal = 8,
kNumBaseHexadecimal = 16
} NumberBase;
@@ -3889,9 +3907,7 @@ int build_stl_str_hl(
// Note: The `*` means we take the width as one of the arguments
*t++ = '*';
- *t++ = (char_u) (base == kNumBaseHexadecimal ? 'X'
- : (base == kNumBaseOctal ? 'o'
- : 'd'));
+ *t++ = (char_u)(base == kNumBaseHexadecimal ? 'X' : 'd');
*t = 0;
// }
@@ -5346,7 +5362,7 @@ void bufhl_clear_line_range(buf_T *buf,
if (line > line_end) {
break;
}
- if (line_start <= line && line <= line_end) {
+ if (line_start <= line) {
BufhlLineStatus status = bufhl_clear_line(l, src_id, line);
if (status != kBLSUnchanged) {
if (line > last_changed) {
diff --git a/src/nvim/charset.c b/src/nvim/charset.c
index 980b4ed426..7d5f80c531 100644
--- a/src/nvim/charset.c
+++ b/src/nvim/charset.c
@@ -313,69 +313,112 @@ void trans_characters(char_u *buf, int bufsize)
}
}
-/// Translate a string into allocated memory, replacing special chars with
-/// printable chars.
+/// Find length of a string capable of holding s with all specials replaced
///
-/// @param s
+/// Assumes replacing special characters with printable ones just like
+/// strtrans() does.
+///
+/// @param[in] s String to check.
///
-/// @return translated string
-char_u *transstr(char_u *s) FUNC_ATTR_NONNULL_RET
+/// @return number of bytes needed to hold a translation of `s`, NUL byte not
+/// included.
+size_t transstr_len(const char *const s)
+ FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
{
- char_u *res;
- char_u *p;
- int c;
- size_t l;
- char_u hexbuf[11];
-
- // Compute the length of the result, taking account of unprintable
- // multi-byte characters.
+ const char *p = s;
size_t len = 0;
- p = s;
- while (*p != NUL) {
- if ((l = (size_t)(*mb_ptr2len)(p)) > 1) {
- c = (*mb_ptr2char)(p);
- p += l;
+ while (*p) {
+ const size_t l = (size_t)utfc_ptr2len((const char_u *)p);
+ if (l > 1) {
+ int pcc[MAX_MCO + 2];
+ pcc[0] = utfc_ptr2char((const char_u *)p, &pcc[1]);
- if (vim_isprintc(c)) {
+ if (vim_isprintc(pcc[0])) {
len += l;
} else {
- transchar_hex(hexbuf, c);
- len += STRLEN(hexbuf);
+ for (size_t i = 0; i < ARRAY_SIZE(pcc); i++) {
+ char hexbuf[11];
+ len += transchar_hex(hexbuf, pcc[i]);
+ }
}
+ p += l;
} else {
- l = (size_t)byte2cells(*p++);
-
- if (l > 0) {
- len += l;
- } else {
- // illegal byte sequence
- len += 4;
- }
+ const int b2c_l = byte2cells((uint8_t)(*p++));
+ // Illegal byte sequence may occupy up to 4 characters.
+ len += (size_t)(b2c_l > 0 ? b2c_l : 4);
}
}
- res = xmallocz(len);
-
- *res = NUL;
- p = s;
+ return len;
+}
- while (*p != NUL) {
- if ((l = (size_t)(*mb_ptr2len)(p)) > 1) {
- c = (*mb_ptr2char)(p);
+/// Replace special characters with printable ones
+///
+/// @param[in] s String to replace characters from.
+/// @param[out] buf Buffer to which result should be saved.
+/// @param[in] len Buffer length. Resulting string may not occupy more then
+/// len - 1 bytes (one for trailing NUL byte).
+///
+/// @return length of the resulting string, without the NUL byte.
+size_t transstr_buf(const char *const s, char *const buf, const size_t len)
+ FUNC_ATTR_NONNULL_ALL
+{
+ const char *p = s;
+ char *buf_p = buf;
+ char *const buf_e = buf_p + len - 1;
+
+ while (*p != NUL && buf_p < buf_e) {
+ const size_t l = (size_t)utfc_ptr2len((const char_u *)p);
+ if (l > 1) {
+ if (buf_p + l >= buf_e) {
+ break;
+ }
+ int pcc[MAX_MCO + 2];
+ pcc[0] = utfc_ptr2char((const char_u *)p, &pcc[1]);
- if (vim_isprintc(c)) {
- // append printable multi-byte char
- STRNCAT(res, p, l);
+ if (vim_isprintc(pcc[0])) {
+ memmove(buf_p, p, l);
+ buf_p += l;
} else {
- transchar_hex(res + STRLEN(res), c);
+ for (size_t i = 0; i < ARRAY_SIZE(pcc); i++) {
+ char hexbuf[11];
+ const size_t hexlen = transchar_hex(hexbuf, pcc[i]);
+ if (buf_p + hexlen >= buf_e) {
+ break;
+ }
+ memmove(buf_p, hexbuf, hexlen);
+ buf_p += hexlen;
+ }
}
p += l;
} else {
- STRCAT(res, transchar_byte(*p++));
+ const char *const tb = (const char *)transchar_byte((uint8_t)(*p++));
+ const size_t tb_len = strlen(tb);
+ memmove(buf_p, tb, tb_len);
+ buf_p += tb_len;
}
}
+ *buf_p = NUL;
+ assert(buf_p <= buf_e);
+ return (size_t)(buf_p - buf);
+}
- return res;
+/// Copy string and replace special characters with printable characters
+///
+/// Works like `strtrans()` does, used for that and in some other places.
+///
+/// @param[in] s String to replace characters from.
+///
+/// @return [allocated] translated string
+char *transstr(const char *const s)
+ FUNC_ATTR_NONNULL_RET
+{
+ // Compute the length of the result, taking account of unprintable
+ // multi-byte characters.
+ const size_t len = transstr_len((const char *)s) + 1;
+ char *const buf = xmalloc(len);
+ transstr_buf(s, buf, len);
+ return buf;
}
/// Convert the string "str[orglen]" to do ignore-case comparing.
@@ -474,14 +517,16 @@ char_u* str_foldcase(char_u *str, int orglen, char_u *buf, int buflen)
// Does NOT work for multi-byte characters, c must be <= 255.
// Also doesn't work for the first byte of a multi-byte, "c" must be a
// character!
-static char_u transchar_buf[7];
+static char_u transchar_buf[11];
-/// Translates a character
+/// Translate a character into a printable one, leaving printable ASCII intact
///
-/// @param c
+/// All unicode characters are considered non-printable in this function.
///
-/// @return translated character.
-char_u* transchar(int c)
+/// @param[in] c Character to translate.
+///
+/// @return translated character into a static buffer.
+char_u *transchar(int c)
{
int i = 0;
if (IS_SPECIAL(c)) {
@@ -494,23 +539,27 @@ char_u* transchar(int c)
if ((!chartab_initialized && (((c >= ' ') && (c <= '~'))
|| (p_altkeymap && F_ischar(c))))
- || ((c < 256) && vim_isprintc_strict(c))) {
+ || ((c <= 0xFF) && vim_isprintc_strict(c))) {
// printable character
transchar_buf[i] = (char_u)c;
transchar_buf[i + 1] = NUL;
- } else {
+ } else if (c <= 0xFF) {
transchar_nonprint(transchar_buf + i, c);
+ } else {
+ transchar_hex((char *)transchar_buf + i, c);
}
return transchar_buf;
}
-/// Like transchar(), but called with a byte instead of a character. Checks
-/// for an illegal UTF-8 byte.
+/// Like transchar(), but called with a byte instead of a character
///
-/// @param c
+/// Checks for an illegal UTF-8 byte.
+///
+/// @param[in] c Byte to translate.
///
/// @return pointer to translated character in transchar_buf.
-char_u* transchar_byte(int c)
+char_u *transchar_byte(const int c)
+ FUNC_ATTR_WARN_UNUSED_RESULT
{
if (c >= 0x80) {
transchar_nonprint(transchar_buf, c);
@@ -519,12 +568,14 @@ char_u* transchar_byte(int c)
return transchar(c);
}
-/// Convert non-printable character to two or more printable characters in
-/// "buf[]". "buf" needs to be able to hold five bytes.
-/// Does NOT work for multi-byte characters, c must be <= 255.
+/// Convert non-printable characters to 2..4 printable ones
///
-/// @param buf
-/// @param c
+/// @warning Does not work for multi-byte characters, c must be <= 255.
+///
+/// @param[out] buf Buffer to store result in, must be able to hold at least
+/// 5 bytes (conversion result + NUL).
+/// @param[in] c Character to convert. NUL is assumed to be NL according to
+/// `:h NL-used-for-NUL`.
void transchar_nonprint(char_u *buf, int c)
{
if (c == NL) {
@@ -534,54 +585,63 @@ void transchar_nonprint(char_u *buf, int c)
// we use CR in place of NL in this case
c = NL;
}
+ assert(c <= 0xff);
- if (dy_flags & DY_UHEX) {
+ if (dy_flags & DY_UHEX || c > 0x7f) {
// 'display' has "uhex"
- transchar_hex(buf, c);
- } else if (c <= 0x7f) {
+ transchar_hex((char *)buf, c);
+ } else {
// 0x00 - 0x1f and 0x7f
buf[0] = '^';
// DEL displayed as ^?
buf[1] = (char_u)(c ^ 0x40);
buf[2] = NUL;
- } else {
- transchar_hex(buf, c);
}
}
-/// Convert a non-printable character to hex.
+/// Convert a non-printable character to hex C string like "<FFFF>"
///
-/// @param buf
-/// @param c
-void transchar_hex(char_u *buf, int c)
+/// @param[out] buf Buffer to store result in.
+/// @param[in] c Character to convert.
+///
+/// @return Number of bytes stored in buffer, excluding trailing NUL byte.
+size_t transchar_hex(char *const buf, const int c)
+ FUNC_ATTR_NONNULL_ALL
{
- int i = 0;
+ size_t i = 0;
- buf[0] = '<';
+ buf[i++] = '<';
if (c > 255) {
- buf[++i] = (char_u)nr2hex((unsigned)c >> 12);
- buf[++i] = (char_u)nr2hex((unsigned)c >> 8);
- }
- buf[++i] = (char_u)(nr2hex((unsigned)c >> 4));
- buf[++i] = (char_u)(nr2hex((unsigned)c));
- buf[++i] = '>';
- buf[++i] = NUL;
+ if (c > 255 * 256) {
+ buf[i++] = (char)nr2hex((unsigned)c >> 20);
+ buf[i++] = (char)nr2hex((unsigned)c >> 16);
+ }
+ buf[i++] = (char)nr2hex((unsigned)c >> 12);
+ buf[i++] = (char)nr2hex((unsigned)c >> 8);
+ }
+ buf[i++] = (char)(nr2hex((unsigned)c >> 4));
+ buf[i++] = (char)(nr2hex((unsigned)c));
+ buf[i++] = '>';
+ buf[i] = NUL;
+ return i;
}
-/// Convert the lower 4 bits of byte "c" to its hex character.
+/// Convert the lower 4 bits of byte "c" to its hex character
+///
/// Lower case letters are used to avoid the confusion of <F1> being 0xf1 or
/// function key 1.
///
-/// @param c
+/// @param[in] n Number to convert.
///
/// @return the hex character.
-static unsigned nr2hex(unsigned c)
+static inline unsigned nr2hex(unsigned n)
+ FUNC_ATTR_CONST FUNC_ATTR_WARN_UNUSED_RESULT
{
- if ((c & 0xf) <= 9) {
- return (c & 0xf) + '0';
+ if ((n & 0xf) <= 9) {
+ return (n & 0xf) + '0';
}
- return (c & 0xf) - 10 + 'a';
+ return (n & 0xf) - 10 + 'a';
}
/// Return number of display cells occupied by byte "b".
@@ -863,7 +923,7 @@ bool vim_isprintc(int c)
if (c >= 0x100) {
return utf_printable(c);
}
- return c >= 0x100 || (c > 0 && (g_chartab[c] & CT_PRINT_CHAR));
+ return c > 0 && (g_chartab[c] & CT_PRINT_CHAR);
}
/// Strict version of vim_isprintc(c), don't return true if "c" is the head
@@ -1671,7 +1731,7 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
&& !STRING_ENDED(ptr + 1)
&& ptr[0] == '0' && ptr[1] != '8' && ptr[1] != '9') {
pre = ptr[1];
- // Detect hexadecimal: 0x or 0X follwed by hex digit
+ // Detect hexadecimal: 0x or 0X followed by hex digit.
if ((what & STR2NR_HEX)
&& !STRING_ENDED(ptr + 2)
&& (pre == 'X' || pre == 'x')
@@ -1679,7 +1739,7 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
ptr += 2;
goto vim_str2nr_hex;
}
- // Detect binary: 0b or 0B follwed by 0 or 1
+ // Detect binary: 0b or 0B followed by 0 or 1.
if ((what & STR2NR_BIN)
&& !STRING_ENDED(ptr + 2)
&& (pre == 'B' || pre == 'b')
@@ -1687,7 +1747,7 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
ptr += 2;
goto vim_str2nr_bin;
}
- // Detect octal number: zero followed by octal digits without '8' or '9'
+ // Detect octal number: zero followed by octal digits without '8' or '9'.
pre = 0;
if (!(what & STR2NR_OCT)
|| !('0' <= ptr[1] && ptr[1] <= '7')) {
@@ -1718,32 +1778,21 @@ void vim_str2nr(const char_u *const start, int *const prep, int *const len,
ptr++; \
} \
} while (0)
- switch (pre) {
- case 'b':
- case 'B': {
vim_str2nr_bin:
- PARSE_NUMBER(2, (*ptr == '0' || *ptr == '1'), (*ptr - '0'));
- break;
- }
- case '0': {
+ PARSE_NUMBER(2, (*ptr == '0' || *ptr == '1'), (*ptr - '0'));
+ goto vim_str2nr_proceed;
vim_str2nr_oct:
- PARSE_NUMBER(8, ('0' <= *ptr && *ptr <= '7'), (*ptr - '0'));
- break;
- }
- case 0: {
+ PARSE_NUMBER(8, ('0' <= *ptr && *ptr <= '7'), (*ptr - '0'));
+ goto vim_str2nr_proceed;
vim_str2nr_dec:
- PARSE_NUMBER(10, (ascii_isdigit(*ptr)), (*ptr - '0'));
- break;
- }
- case 'x':
- case 'X': {
+ PARSE_NUMBER(10, (ascii_isdigit(*ptr)), (*ptr - '0'));
+ goto vim_str2nr_proceed;
vim_str2nr_hex:
- PARSE_NUMBER(16, (ascii_isxdigit(*ptr)), (hex2nr(*ptr)));
- break;
- }
- }
+ PARSE_NUMBER(16, (ascii_isxdigit(*ptr)), (hex2nr(*ptr)));
+ goto vim_str2nr_proceed;
#undef PARSE_NUMBER
+vim_str2nr_proceed:
if (prep != NULL) {
*prep = pre;
}
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index 0ee1c3815d..f9e40ed06f 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -859,9 +859,9 @@ void ex_diffpatch(exarg_T *eap)
char_u *esc_name = NULL;
#ifdef UNIX
- char_u dirbuf[MAXPATHL];
- char_u *fullname = NULL;
+ char *fullname = NULL;
#endif
+
// We need two temp file names.
// Name of original temp file.
char_u *tmp_orig = vim_tempname();
@@ -881,21 +881,17 @@ void ex_diffpatch(exarg_T *eap)
#ifdef UNIX
// Get the absolute path of the patchfile, changing directory below.
- fullname = (char_u *)FullName_save((char *)eap->arg, false);
-#endif
-
+ fullname = FullName_save((char *)eap->arg, false);
esc_name = vim_strsave_shellescape(
-#ifdef UNIX
- fullname != NULL ? fullname :
+ (fullname != NULL ? (char_u *)fullname : eap->arg), true, true);
+#else
+ esc_name = vim_strsave_shellescape(eap->arg, true, true);
#endif
- eap->arg, true, true);
- if (esc_name == NULL) {
- goto theend;
- }
size_t buflen = STRLEN(tmp_orig) + STRLEN(esc_name) + STRLEN(tmp_new) + 16;
buf = xmalloc(buflen);
#ifdef UNIX
+ char_u dirbuf[MAXPATHL];
// Temporarily chdir to /tmp, to avoid patching files in the current
// directory when the patch file contains more than one patch. When we
// have our own temp dir use that instead, it will be cleaned up when we
@@ -918,7 +914,7 @@ void ex_diffpatch(exarg_T *eap)
// Use 'patchexpr' to generate the new file.
#ifdef UNIX
eval_patch((char *)tmp_orig,
- (char *)(fullname != NULL ? fullname : eap->arg),
+ (fullname != NULL ? fullname : (char *)eap->arg),
(char *)tmp_new);
#else
eval_patch((char *)tmp_orig, (char *)eap->arg, (char *)tmp_new);
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index a0f6ce152b..a1987cf2d5 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -5265,7 +5265,7 @@ insertchar (
// - need to check for abbreviation: A non-word char after a word-char
while ((c = vpeekc()) != NUL
&& !ISSPECIAL(c)
- && (!has_mbyte || MB_BYTE2LEN_CHECK(c) == 1)
+ && MB_BYTE2LEN(c) == 1
&& i < INPUT_BUFLEN
&& !(p_fkmap && KeyTyped) // Farsi mode mapping moves cursor
&& (textwidth == 0
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 713eb816f8..cc29496968 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -2682,19 +2682,21 @@ void ex_call(exarg_T *eap)
return;
}
- tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi, &partial);
+ tofree = trans_function_name(&arg, false, TFN_INT, &fudi, &partial);
if (fudi.fd_newkey != NULL) {
- /* Still need to give an error message for missing key. */
+ // Still need to give an error message for missing key.
EMSG2(_(e_dictkey), fudi.fd_newkey);
xfree(fudi.fd_newkey);
}
- if (tofree == NULL)
+ if (tofree == NULL) {
return;
+ }
- /* Increase refcount on dictionary, it could get deleted when evaluating
- * the arguments. */
- if (fudi.fd_dict != NULL)
- ++fudi.fd_dict->dv_refcount;
+ // Increase refcount on dictionary, it could get deleted when evaluating
+ // the arguments.
+ if (fudi.fd_dict != NULL) {
+ fudi.fd_dict->dv_refcount++;
+ }
// If it is the name of a variable of type VAR_FUNC or VAR_PARTIAL use its
// contents. For VAR_PARTIAL get its partial, unless we already have one
@@ -2703,8 +2705,8 @@ void ex_call(exarg_T *eap)
name = deref_func_name((const char *)tofree, &len,
partial != NULL ? NULL : &partial, false);
- /* Skip white space to allow ":call func ()". Not good, but required for
- * backward compatibility. */
+ // Skip white space to allow ":call func ()". Not good, but required for
+ // backward compatibility.
startarg = skipwhite(arg);
rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this.
@@ -2713,20 +2715,9 @@ void ex_call(exarg_T *eap)
goto end;
}
- /*
- * When skipping, evaluate the function once, to find the end of the
- * arguments.
- * When the function takes a range, this is discovered after the first
- * call, and the loop is broken.
- */
- if (eap->skip) {
- emsg_skip++;
- lnum = eap->line2; // Do it once, also with an invalid range.
- } else {
- lnum = eap->line1;
- }
+ lnum = eap->line1;
for (; lnum <= eap->line2; lnum++) {
- if (!eap->skip && eap->addr_count > 0) { // -V560
+ if (eap->addr_count > 0) { // -V560
curwin->w_cursor.lnum = lnum;
curwin->w_cursor.col = 0;
curwin->w_cursor.coladd = 0;
@@ -2734,40 +2725,40 @@ void ex_call(exarg_T *eap)
arg = startarg;
if (get_func_tv(name, (int)STRLEN(name), &rettv, &arg,
eap->line1, eap->line2, &doesrange,
- !eap->skip, partial, fudi.fd_dict) == FAIL) {
+ true, partial, fudi.fd_dict) == FAIL) {
failed = true;
break;
}
// Handle a function returning a Funcref, Dictionary or List.
- if (handle_subscript((const char **)&arg, &rettv, !eap->skip, true)
+ if (handle_subscript((const char **)&arg, &rettv, true, true)
== FAIL) {
failed = true;
break;
}
tv_clear(&rettv);
- if (doesrange || eap->skip) { // -V560
+ if (doesrange) {
break;
}
- /* Stop when immediately aborting on error, or when an interrupt
- * occurred or an exception was thrown but not caught.
- * get_func_tv() returned OK, so that the check for trailing
- * characters below is executed. */
- if (aborting())
+ // Stop when immediately aborting on error, or when an interrupt
+ // occurred or an exception was thrown but not caught.
+ // get_func_tv() returned OK, so that the check for trailing
+ // characters below is executed.
+ if (aborting()) {
break;
+ }
}
- if (eap->skip)
- --emsg_skip;
if (!failed) {
- /* Check for trailing illegal characters and a following command. */
+ // Check for trailing illegal characters and a following command.
if (!ends_excmd(*arg)) {
emsg_severe = TRUE;
EMSG(_(e_trailing));
- } else
+ } else {
eap->nextcmd = check_nextcmd(arg);
+ }
}
end:
@@ -5807,8 +5798,8 @@ static int get_lambda_tv(char_u **arg, typval_T *rettv, bool evaluate)
lambda_no++;
snprintf((char *)name, sizeof(name), "<lambda>%d", lambda_no);
- fp = (ufunc_T *)xcalloc(1, sizeof(ufunc_T) + STRLEN(name));
- pt = (partial_T *)xcalloc(1, sizeof(partial_T));
+ fp = xcalloc(1, offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
+ pt = xcalloc(1, sizeof(partial_T));
ga_init(&newlines, (int)sizeof(char_u *), 1);
ga_grow(&newlines, 1);
@@ -15456,7 +15447,7 @@ static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
; li != NULL;) {
listitem_T *const prev_li = TV_LIST_ITEM_PREV(l, li);
if (item_compare_func_ptr(&prev_li, &li) == 0) {
- if (info.item_compare_func_err) {
+ if (info.item_compare_func_err) { // -V547
EMSG(_("E882: Uniq compare function failed"));
break;
}
@@ -15630,7 +15621,6 @@ f_spellsuggest_return:
static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
- regmatch_T regmatch;
char_u *save_cpo;
int match;
colnr_T col = 0;
@@ -15663,9 +15653,13 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
return;
}
- regmatch.regprog = vim_regcomp((char_u *)pat, RE_MAGIC + RE_STRING);
+ regmatch_T regmatch = {
+ .regprog = vim_regcomp((char_u *)pat, RE_MAGIC + RE_STRING),
+ .startp = { NULL },
+ .endp = { NULL },
+ .rm_ic = false,
+ };
if (regmatch.regprog != NULL) {
- regmatch.rm_ic = FALSE;
while (*str != NUL || keepempty) {
if (*str == NUL) {
match = false; // Empty item at the end.
@@ -15684,8 +15678,9 @@ static void f_split(typval_T *argvars, typval_T *rettv, FunPtr fptr)
&& end < (const char *)regmatch.endp[0])) {
tv_list_append_string(rettv->vval.v_list, str, end - str);
}
- if (!match)
+ if (!match) {
break;
+ }
// Advance to just after the match.
if (regmatch.endp[0] > (char_u *)str) {
col = 0;
@@ -16143,7 +16138,7 @@ static void f_strridx(typval_T *argvars, typval_T *rettv, FunPtr fptr)
static void f_strtrans(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = transstr((char_u *)tv_get_string(&argvars[0]));
+ rettv->vval.v_string = (char_u *)transstr(tv_get_string(&argvars[0]));
}
/*
@@ -18781,7 +18776,7 @@ static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len,
if (name_len == 0) {
return NULL;
}
- if (name_len == 1 || (name_len >= 2 && name[1] != ':')) {
+ if (name_len == 1 || name[1] != ':') {
// name has implicit scope
if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) {
// The name must not start with a colon or #.
@@ -20112,7 +20107,7 @@ void ex_function(exarg_T *eap)
}
}
- fp = xcalloc(1, sizeof(ufunc_T) + STRLEN(name));
+ fp = xcalloc(1, offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
if (fudi.fd_dict != NULL) {
if (fudi.fd_di == NULL) {
@@ -20867,8 +20862,9 @@ char_u *get_user_func_name(expand_T *xp, int idx)
return (char_u *)""; // don't show dict and lambda functions
}
- if (STRLEN(fp->uf_name) + 4 >= IOSIZE)
- return fp->uf_name; /* prevents overflow */
+ if (STRLEN(fp->uf_name) + 4 >= IOSIZE) {
+ return fp->uf_name; // Prevent overflow.
+ }
cat_func_name(IObuff, fp);
if (xp->xp_context != EXPAND_USER_FUNC) {
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c
index 17799b500c..4d75c7bda1 100644
--- a/src/nvim/eval/decode.c
+++ b/src/nvim/eval/decode.c
@@ -985,7 +985,7 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
break;
}
case MSGPACK_OBJECT_NEGATIVE_INTEGER: {
- if (mobj.via.i64 >= VARNUMBER_MIN) {
+ if (mobj.via.i64 >= VARNUMBER_MIN) { // -V547
*rettv = (typval_T) {
.v_type = VAR_NUMBER,
.v_lock = VAR_UNLOCKED,
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index c8b550f902..7930653be0 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -2825,7 +2825,7 @@ const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf)
{
switch (tv->v_type) {
case VAR_NUMBER: {
- snprintf(buf, NUMBUFLEN, "%" PRIdVARNUMBER, tv->vval.v_number);
+ snprintf(buf, NUMBUFLEN, "%" PRIdVARNUMBER, tv->vval.v_number); // -V576
return buf;
}
case VAR_STRING: {
diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h
index 2272a580d6..33e2aa6b61 100644
--- a/src/nvim/eval/typval.h
+++ b/src/nvim/eval/typval.h
@@ -197,15 +197,6 @@ typedef struct {
}, \
}
-// Structure to hold an item of a Dictionary.
-// Also used for a variable.
-// The key is copied into "di_key" to avoid an extra alloc/free for it.
-struct dictitem_S {
- typval_T di_tv; ///< type and value of the variable
- char_u di_flags; ///< flags (only used for variable)
- char_u di_key[1]; ///< key (actually longer!)
-};
-
#define TV_DICTITEM_STRUCT(...) \
struct { \
typval_T di_tv; /* Structure that holds scope dictionary itself. */ \
@@ -286,9 +277,8 @@ struct ufunc {
///< used for s: variables
int uf_refcount; ///< reference count, see func_name_refcount()
funccall_T *uf_scoped; ///< l: local variables for closure
- char_u uf_name[1]; ///< name of function (actually longer); can
- ///< start with <SNR>123_ (<SNR> is K_SPECIAL
- ///< KS_EXTRA KE_SNR)
+ char_u uf_name[]; ///< Name of function; can start with <SNR>123_
+ ///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR)
};
/// Maximum number of function arguments
diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h
index f2d0d7265f..4556ce8193 100644
--- a/src/nvim/eval/typval_encode.c.h
+++ b/src/nvim/eval/typval_encode.c.h
@@ -340,8 +340,9 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
case VAR_PARTIAL: {
partial_T *const pt = tv->vval.v_partial;
(void)pt;
- TYPVAL_ENCODE_CONV_FUNC_START(tv, (pt == NULL ? NULL : partial_name(pt)));
- _mp_push(*mpstack, ((MPConvStackVal) {
+ TYPVAL_ENCODE_CONV_FUNC_START( // -V547
+ tv, (pt == NULL ? NULL : partial_name(pt)));
+ _mp_push(*mpstack, ((MPConvStackVal) { // -V779
.type = kMPConvPartial,
.tv = tv,
.saved_copyID = copyID - 1,
@@ -541,7 +542,8 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
}
list_T *const val_list = val_di->di_tv.vval.v_list;
if (val_list == NULL || tv_list_len(val_list) == 0) {
- TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, TYPVAL_ENCODE_NODICT_VAR);
+ TYPVAL_ENCODE_CONV_EMPTY_DICT( // -V501
+ tv, TYPVAL_ENCODE_NODICT_VAR);
break;
}
TV_LIST_ITER_CONST(val_list, li, {
diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h
index c0e2f49e4f..f5dd23ac8b 100644
--- a/src/nvim/event/loop.h
+++ b/src/nvim/event/loop.h
@@ -52,6 +52,8 @@ typedef struct loop {
} \
} while (0)
+// -V:LOOP_PROCESS_EVENTS_UNTIL:547
+
// Poll for events until a condition or timeout
#define LOOP_PROCESS_EVENTS_UNTIL(loop, multiqueue, timeout, condition) \
do { \
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
index f82614e7a1..7a8a39dbcf 100644
--- a/src/nvim/event/process.c
+++ b/src/nvim/event/process.c
@@ -356,7 +356,7 @@ static void flush_stream(Process *proc, Stream *stream)
}
// Stream can be closed if it is empty.
- if (num_bytes == stream->num_bytes) {
+ if (num_bytes == stream->num_bytes) { // -V547
if (stream->read_cb && !stream->did_eof) {
// Stream callback could miss EOF handling if a child keeps the stream
// open. But only send EOF if we haven't already.
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index c396b5891a..f575d58f05 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -109,82 +109,86 @@ typedef struct {
# include "ex_cmds.c.generated.h"
#endif
-/*
- * ":ascii" and "ga".
- */
-void do_ascii(exarg_T *eap)
+/// ":ascii" and "ga" implementation
+void do_ascii(const exarg_T *const eap)
{
- int c;
- int cval;
- char buf1[20];
- char buf2[20];
- char_u buf3[7];
int cc[MAX_MCO];
- int ci = 0;
- int len;
- const bool l_enc_utf8 = enc_utf8;
-
- if (l_enc_utf8)
- c = utfc_ptr2char(get_cursor_pos_ptr(), cc);
- else
- c = gchar_cursor();
+ int c = utfc_ptr2char(get_cursor_pos_ptr(), cc);
if (c == NUL) {
MSG("NUL");
return;
}
- IObuff[0] = NUL;
- if (!has_mbyte || (enc_dbcs != 0 && c < 0x100) || c < 0x80) {
- if (c == NL) /* NUL is stored as NL */
+ size_t iobuff_len = 0;
+
+ int ci = 0;
+ if (c < 0x80) {
+ if (c == NL) { // NUL is stored as NL.
c = NUL;
- if (c == CAR && get_fileformat(curbuf) == EOL_MAC)
- cval = NL; /* NL is stored as CR */
- else
- cval = c;
- if (vim_isprintc_strict(c) && (c < ' '
- || c > '~'
- )) {
+ }
+ const int cval = (c == CAR && get_fileformat(curbuf) == EOL_MAC
+ ? NL // NL is stored as CR.
+ : c);
+ char buf1[20];
+ if (vim_isprintc_strict(c) && (c < ' ' || c > '~')) {
+ char_u buf3[7];
transchar_nonprint(buf3, c);
vim_snprintf(buf1, sizeof(buf1), " <%s>", (char *)buf3);
- } else
+ } else {
buf1[0] = NUL;
- if (c >= 0x80)
- vim_snprintf(buf2, sizeof(buf2), " <M-%s>",
- (char *)transchar(c & 0x7f));
- else
- buf2[0] = NUL;
- vim_snprintf((char *)IObuff, IOSIZE,
- _("<%s>%s%s %d, Hex %02x, Octal %03o"),
- transchar(c), buf1, buf2, cval, cval, cval);
- if (l_enc_utf8)
- c = cc[ci++];
- else
- c = 0;
- }
-
- /* Repeat for combining characters. */
- while (has_mbyte && (c >= 0x100 || (l_enc_utf8 && c >= 0x80))) {
- len = (int)STRLEN(IObuff);
- /* This assumes every multi-byte char is printable... */
- if (len > 0)
- IObuff[len++] = ' ';
- IObuff[len++] = '<';
- if (l_enc_utf8 && utf_iscomposing(c)
-# ifdef USE_GUI
- && !gui.in_use
-# endif
- )
- IObuff[len++] = ' '; /* draw composing char on top of a space */
- len += (*mb_char2bytes)(c, IObuff + len);
- vim_snprintf((char *)IObuff + len, IOSIZE - len,
- c < 0x10000 ? _("> %d, Hex %04x, Octal %o")
- : _("> %d, Hex %08x, Octal %o"), c, c, c);
- if (ci == MAX_MCO)
+ }
+ char buf2[20];
+ buf2[0] = NUL;
+ iobuff_len += (
+ vim_snprintf((char *)IObuff + iobuff_len, sizeof(IObuff) - iobuff_len,
+ _("<%s>%s%s %d, Hex %02x, Octal %03o"),
+ transchar(c), buf1, buf2, cval, cval, cval));
+ c = cc[ci++];
+ }
+
+#define SPACE_FOR_DESC (1 + 1 + 1 + MB_MAXBYTES + 16 + 4 + 3 + 3 + 1)
+ // Space for description:
+ // - 1 byte for separator (starting from second entry)
+ // - 1 byte for "<"
+ // - 1 byte for space to draw composing character on (optional, but really
+ // mostly required)
+ // - up to MB_MAXBYTES bytes for character itself
+ // - 16 bytes for raw text ("> , Hex , Octal ").
+ // - at least 4 bytes for hexadecimal representation
+ // - at least 3 bytes for decimal representation
+ // - at least 3 bytes for octal representation
+ // - 1 byte for NUL
+ //
+ // Taking into account MAX_MCO and characters which need 8 bytes for
+ // hexadecimal representation, but not taking translation into account:
+ // resulting string will occupy less then 400 bytes (conservative estimate).
+ //
+ // Less then 1000 bytes if translation multiplies number of bytes needed for
+ // raw text by 6, so it should always fit into 1025 bytes reserved for IObuff.
+
+ // Repeat for combining characters, also handle multiby here.
+ while (c >= 0x80 && iobuff_len < sizeof(IObuff) - SPACE_FOR_DESC) {
+ // This assumes every multi-byte char is printable...
+ if (iobuff_len > 0) {
+ IObuff[iobuff_len++] = ' ';
+ }
+ IObuff[iobuff_len++] = '<';
+ if (utf_iscomposing(c)) {
+ IObuff[iobuff_len++] = ' '; // Draw composing char on top of a space.
+ }
+ iobuff_len += utf_char2bytes(c, IObuff + iobuff_len);
+ iobuff_len += (
+ vim_snprintf((char *)IObuff + iobuff_len, sizeof(IObuff) - iobuff_len,
+ (c < 0x10000
+ ? _("> %d, Hex %04x, Octal %o")
+ : _("> %d, Hex %08x, Octal %o")), c, c, c));
+ if (ci == MAX_MCO) {
break;
- if (l_enc_utf8)
- c = cc[ci++];
- else
- c = 0;
+ }
+ c = cc[ci++];
+ }
+ if (ci != MAX_MCO && c != 0) {
+ xstrlcpy((char *)IObuff + iobuff_len, " ...", sizeof(IObuff) - iobuff_len);
}
msg(IObuff);
@@ -2018,13 +2022,13 @@ int getfile(int fnum, char_u *ffname, char_u *sfname, int setpm, linenr_T lnum,
}
if (other && !forceit && curbuf->b_nwindows == 1 && !buf_hide(curbuf)
&& curbufIsChanged() && autowrite(curbuf, forceit) == FAIL) {
- if (p_confirm && p_write)
- dialog_changed(curbuf, FALSE);
+ if (p_confirm && p_write) {
+ dialog_changed(curbuf, false);
+ }
if (curbufIsChanged()) {
- if (other)
- --no_wait_return;
+ no_wait_return--;
EMSG(_(e_nowrtmsg));
- retval = 2; /* file has been changed */
+ retval = 2; // File has been changed.
goto theend;
}
}
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 8aa670fc74..3dbeccaaa5 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -5186,11 +5186,13 @@ static void ex_command(exarg_T *eap)
p = skipwhite(end);
}
- /* Get the name (if any) and skip to the following argument */
+ // Get the name (if any) and skip to the following argument.
name = p;
- if (ASCII_ISALPHA(*p))
- while (ASCII_ISALNUM(*p))
- ++p;
+ if (ASCII_ISALPHA(*p)) {
+ while (ASCII_ISALNUM(*p)) {
+ p++;
+ }
+ }
if (!ends_excmd(*p) && !ascii_iswhite(*p)) {
EMSG(_("E182: Invalid command name"));
return;
@@ -5208,8 +5210,7 @@ static void ex_command(exarg_T *eap)
EMSG(_("E183: User defined commands must start with an uppercase letter"));
return;
} else if ((name_len == 1 && *name == 'X')
- || (name_len <= 4
- && STRNCMP(name, "Next", name_len > 4 ? 4 : name_len) == 0)) {
+ || (name_len <= 4 && STRNCMP(name, "Next", name_len) == 0)) {
EMSG(_("E841: Reserved name, cannot be used for user defined command"));
return;
} else
@@ -5673,22 +5674,21 @@ static void do_ucmd(exarg_T *eap)
if (start != NULL)
end = vim_strchr(start + 1, '>');
if (buf != NULL) {
- for (ksp = p; *ksp != NUL && *ksp != K_SPECIAL; ++ksp)
- ;
+ for (ksp = p; *ksp != NUL && *ksp != K_SPECIAL; ksp++) {
+ }
if (*ksp == K_SPECIAL
&& (start == NULL || ksp < start || end == NULL)
- && ((ksp[1] == KS_SPECIAL && ksp[2] == KE_FILLER)
- )) {
- /* K_SPECIAL has been put in the buffer as K_SPECIAL
- * KS_SPECIAL KE_FILLER, like for mappings, but
- * do_cmdline() doesn't handle that, so convert it back.
- * Also change K_SPECIAL KS_EXTRA KE_CSI into CSI. */
+ && (ksp[1] == KS_SPECIAL && ksp[2] == KE_FILLER)) {
+ // K_SPECIAL has been put in the buffer as K_SPECIAL
+ // KS_SPECIAL KE_FILLER, like for mappings, but
+ // do_cmdline() doesn't handle that, so convert it back.
+ // Also change K_SPECIAL KS_EXTRA KE_CSI into CSI.
len = ksp - p;
if (len > 0) {
memmove(q, p, len);
q += len;
}
- *q++ = ksp[1] == KS_SPECIAL ? K_SPECIAL : CSI;
+ *q++ = K_SPECIAL;
p = ksp + 3;
continue;
}
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 698419405a..e1198d6f1c 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -3590,40 +3590,33 @@ nextwild (
xp->xp_pattern_len = ccline.cmdpos - i;
if (type == WILD_NEXT || type == WILD_PREV) {
- /*
- * Get next/previous match for a previous expanded pattern.
- */
+ // Get next/previous match for a previous expanded pattern.
p2 = ExpandOne(xp, NULL, NULL, 0, type);
} else {
- /*
- * Translate string into pattern and expand it.
- */
- if ((p1 = addstar(xp->xp_pattern, xp->xp_pattern_len,
- xp->xp_context)) == NULL)
- p2 = NULL;
- else {
- int use_options = options |
- WILD_HOME_REPLACE|WILD_ADD_SLASH|WILD_SILENT;
- if (escape)
- use_options |= WILD_ESCAPE;
-
- if (p_wic)
- use_options += WILD_ICASE;
- p2 = ExpandOne(xp, p1,
- vim_strnsave(&ccline.cmdbuff[i], xp->xp_pattern_len),
- use_options, type);
- xfree(p1);
- /* longest match: make sure it is not shorter, happens with :help */
- if (p2 != NULL && type == WILD_LONGEST) {
- for (j = 0; j < xp->xp_pattern_len; ++j)
- if (ccline.cmdbuff[i + j] == '*'
- || ccline.cmdbuff[i + j] == '?')
- break;
- if ((int)STRLEN(p2) < j) {
- xfree(p2);
- p2 = NULL;
+ // Translate string into pattern and expand it.
+ p1 = addstar(xp->xp_pattern, xp->xp_pattern_len, xp->xp_context);
+ const int use_options = (
+ options
+ | WILD_HOME_REPLACE
+ | WILD_ADD_SLASH
+ | WILD_SILENT
+ | (escape ? WILD_ESCAPE : 0)
+ | (p_wic ? WILD_ICASE : 0));
+ p2 = ExpandOne(xp, p1, vim_strnsave(&ccline.cmdbuff[i], xp->xp_pattern_len),
+ use_options, type);
+ xfree(p1);
+ // Longest match: make sure it is not shorter, happens with :help.
+ if (p2 != NULL && type == WILD_LONGEST) {
+ for (j = 0; j < xp->xp_pattern_len; j++) {
+ if (ccline.cmdbuff[i + j] == '*'
+ || ccline.cmdbuff[i + j] == '?') {
+ break;
}
}
+ if ((int)STRLEN(p2) < j) {
+ xfree(p2);
+ p2 = NULL;
+ }
}
}
@@ -4856,23 +4849,27 @@ void ExpandGeneric(
// copy the matching names into allocated memory
count = 0;
- for (i = 0;; ++i) {
+ for (i = 0;; i++) {
str = (*func)(xp, i);
- if (str == NULL) // end of list
+ if (str == NULL) { // End of list.
break;
- if (*str == NUL) // skip empty strings
+ }
+ if (*str == NUL) { // Skip empty strings.
continue;
+ }
if (vim_regexec(regmatch, str, (colnr_T)0)) {
- if (escaped)
+ if (escaped) {
str = vim_strsave_escaped(str, (char_u *)" \t\\.");
- else
+ } else {
str = vim_strsave(str);
+ }
(*file)[count++] = str;
- if (func == get_menu_names && str != NULL) {
- /* test for separator added by get_menu_names() */
+ if (func == get_menu_names) {
+ // Test for separator added by get_menu_names().
str += STRLEN(str) - 1;
- if (*str == '\001')
+ if (*str == '\001') {
*str = '.';
+ }
}
}
}
diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c
index 3272ce81bc..5b17b58781 100644
--- a/src/nvim/file_search.c
+++ b/src/nvim/file_search.c
@@ -1541,21 +1541,25 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope)
char buf[8];
switch (scope) {
- case kCdScopeGlobal:
- snprintf(buf, sizeof(buf), "global");
- break;
- case kCdScopeTab:
- snprintf(buf, sizeof(buf), "tab");
- break;
- case kCdScopeWindow:
- snprintf(buf, sizeof(buf), "window");
- break;
- case kCdScopeInvalid:
- // Should never happen.
- assert(false);
+ case kCdScopeGlobal: {
+ snprintf(buf, sizeof(buf), "global");
+ break;
+ }
+ case kCdScopeTab: {
+ snprintf(buf, sizeof(buf), "tab");
+ break;
+ }
+ case kCdScopeWindow: {
+ snprintf(buf, sizeof(buf), "window");
+ break;
+ }
+ case kCdScopeInvalid: {
+ // Should never happen.
+ assert(false);
+ }
}
- tv_dict_add_str(dict, S_LEN("scope"), buf);
+ tv_dict_add_str(dict, S_LEN("scope"), buf); // -V614
tv_dict_add_str(dict, S_LEN("cwd"), new_dir);
tv_dict_set_keys_readonly(dict);
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index d96f5412ec..efeee1ba2b 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -298,8 +298,7 @@ readfile (
off_T filesize = 0;
int skip_read = false;
context_sha256_T sha_ctx;
- int read_undo_file = FALSE;
- int split = 0; /* number of split lines */
+ int read_undo_file = false;
linenr_T linecnt;
int error = FALSE; /* errors encountered */
int ff_error = EOL_UNKNOWN; /* file format with errors */
@@ -1029,8 +1028,8 @@ retry:
size = size / ICONV_MULT; /* worst case */
if (conv_restlen > 0) {
- /* Insert unconverted bytes from previous line. */
- memmove(ptr, conv_rest, conv_restlen);
+ // Insert unconverted bytes from previous line.
+ memmove(ptr, conv_rest, conv_restlen); // -V614
ptr += conv_restlen;
size -= conv_restlen;
}
@@ -1842,10 +1841,6 @@ failed:
STRCAT(IObuff, _("[CR missing]"));
c = TRUE;
}
- if (split) {
- STRCAT(IObuff, _("[long lines split]"));
- c = TRUE;
- }
if (notconverted) {
STRCAT(IObuff, _("[NOT converted]"));
c = TRUE;
@@ -3352,9 +3347,9 @@ restore_backup:
*s++ = NL;
}
}
- if (++len == bufsize && end) {
+ if (++len == bufsize) {
if (buf_write_bytes(&write_info) == FAIL) {
- end = 0; /* write error: break loop */
+ end = 0; // Write error: break loop.
break;
}
nchars += bufsize;
@@ -3363,7 +3358,7 @@ restore_backup:
os_breakcheck();
if (got_int) {
- end = 0; /* Interrupted, break loop */
+ end = 0; // Interrupted, break loop.
break;
}
}
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index db88791967..ad9cd4d562 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -1775,7 +1775,7 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume,
break;
}
if (*p != NUL) {
- p = transstr(text);
+ p = (char_u *)transstr((const char *)text);
xfree(text);
text = p;
}
diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua
index b01321e713..2ee1e5d4c5 100644
--- a/src/nvim/generators/gen_api_dispatch.lua
+++ b/src/nvim/generators/gen_api_dispatch.lua
@@ -324,6 +324,8 @@ end
output = io.open(lua_c_bindings_outputf, 'wb')
output:write([[
+// This is an open source non-commercial project. Dear PVS-Studio, please check
+// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 403a5928c9..e02100e933 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -16,8 +16,6 @@
#define IOSIZE (1024+1) // file I/O and sprintf buffer size
-#define MAX_MCO 6 // maximum value for 'maxcombine'
-
# define MSG_BUF_LEN 480 // length of buffer for small messages
# define MSG_BUF_CLEN (MSG_BUF_LEN / 6) // cell length (worst case: utf-8
// takes 6 bytes for one cell)
@@ -165,10 +163,6 @@ EXTERN u8char_T *ScreenLinesC[MAX_MCO]; /* composing characters */
EXTERN int Screen_mco INIT(= 0); /* value of p_mco used when
allocating ScreenLinesC[] */
-/* Only used for euc-jp: Second byte of a character that starts with 0x8e.
- * These are single-width. */
-EXTERN schar_T *ScreenLines2 INIT(= NULL);
-
EXTERN int screen_Rows INIT(= 0); /* actual size of ScreenLines[] */
EXTERN int screen_Columns INIT(= 0); /* actual size of ScreenLines[] */
@@ -721,7 +715,7 @@ EXTERN int vr_lines_changed INIT(= 0); /* #Lines changed by "gR" so far */
// mbyte flags that used to depend on 'encoding'. These are now deprecated, as
// 'encoding' is always "utf-8". Code that use them can be refactored to
// remove dead code.
-#define enc_dbcs false
+#define enc_dbcs 0
#define enc_utf8 true
#define has_mbyte true
diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c
index b78b56562c..5d7bd26a2b 100644
--- a/src/nvim/if_cscope.c
+++ b/src/nvim/if_cscope.c
@@ -1001,8 +1001,8 @@ static int cs_find_common(char *opt, char *pat, int forceit, int verbose,
return FALSE;
}
- if (qfpos != NULL && *qfpos != '0' && totmatches > 0) {
- /* fill error list */
+ if (qfpos != NULL && *qfpos != '0') {
+ // Fill error list.
FILE *f;
char_u *tmp = vim_tempname();
qf_info_T *qi = NULL;
diff --git a/src/nvim/lib/kvec.h b/src/nvim/lib/kvec.h
index ad56c9237b..6d54c7f78d 100644
--- a/src/nvim/lib/kvec.h
+++ b/src/nvim/lib/kvec.h
@@ -142,6 +142,8 @@ static inline void *_memcpy_free(void *const restrict dest,
return dest;
}
+// -V:kvi_push:512
+
/// Resize vector with preallocated array
///
/// @note May not resize to an array smaller then init_array: if requested,
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 008bce6df6..a52ab9f5d3 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -704,12 +704,14 @@ bool utf_composinglike(const char_u *p1, const char_u *p2)
return arabic_combine(utf_ptr2char(p1), c2);
}
-/*
- * Convert a UTF-8 byte string to a wide character. Also get up to MAX_MCO
- * composing characters.
- *
- * @param [out] pcc: composing chars, last one is 0
- */
+/// Convert a UTF-8 string to a wide character
+///
+/// Also gets up to #MAX_MCO composing characters.
+///
+/// @param[out] pcc Location where to store composing characters. Must have
+/// space at least for #MAX_MCO + 1 elements.
+///
+/// @return leading character.
int utfc_ptr2char(const char_u *p, int *pcc)
{
int len;
@@ -1977,37 +1979,39 @@ char_u * enc_locale(void)
return NULL;
}
- /* The most generic locale format is:
- * language[_territory][.codeset][@modifier][+special][,[sponsor][_revision]]
- * If there is a '.' remove the part before it.
- * if there is something after the codeset, remove it.
- * Make the name lowercase and replace '_' with '-'.
- * Exception: "ja_JP.EUC" == "euc-jp", "zh_CN.EUC" = "euc-cn",
- * "ko_KR.EUC" == "euc-kr"
- */
+ // The most generic locale format is:
+ // language[_territory][.codeset][@modifier][+special][,[sponsor][_revision]]
+ // If there is a '.' remove the part before it.
+ // if there is something after the codeset, remove it.
+ // Make the name lowercase and replace '_' with '-'.
+ // Exception: "ja_JP.EUC" == "euc-jp", "zh_CN.EUC" = "euc-cn",
+ // "ko_KR.EUC" == "euc-kr"
const char *p = (char *)vim_strchr((char_u *)s, '.');
if (p != NULL) {
if (p > s + 2 && !STRNICMP(p + 1, "EUC", 3)
&& !isalnum((int)p[4]) && p[4] != '-' && p[-3] == '_') {
- /* copy "XY.EUC" to "euc-XY" to buf[10] */
- strcpy(buf + 10, "euc-");
- buf[14] = p[-2];
- buf[15] = p[-1];
- buf[16] = 0;
- s = buf + 10;
- } else
- s = p + 1;
- }
- for (i = 0; i < (int)sizeof(buf) - 1 && s[i] != NUL; i++) {
- if (s[i] == '_' || s[i] == '-') {
- buf[i] = '-';
- } else if (isalnum((int)s[i])) {
- buf[i] = TOLOWER_ASC(s[i]);
+ // Copy "XY.EUC" to "euc-XY" to buf[10].
+ memmove(buf, "euc-", 4);
+ buf[4] = (ASCII_ISALNUM(p[-2]) ? TOLOWER_ASC(p[-2]) : 0);
+ buf[5] = (ASCII_ISALNUM(p[-1]) ? TOLOWER_ASC(p[-1]) : 0);
+ buf[6] = NUL;
} else {
- break;
+ s = p + 1;
+ goto enc_locale_copy_enc;
+ }
+ } else {
+enc_locale_copy_enc:
+ for (i = 0; i < (int)sizeof(buf) - 1 && s[i] != NUL; i++) {
+ if (s[i] == '_' || s[i] == '-') {
+ buf[i] = '-';
+ } else if (ASCII_ISALNUM((uint8_t)s[i])) {
+ buf[i] = TOLOWER_ASC(s[i]);
+ } else {
+ break;
+ }
}
+ buf[i] = NUL;
}
- buf[i] = NUL;
return enc_canonize((char_u *)buf);
}
diff --git a/src/nvim/mbyte.h b/src/nvim/mbyte.h
index a5ce1b0a15..dd8e44b3f9 100644
--- a/src/nvim/mbyte.h
+++ b/src/nvim/mbyte.h
@@ -19,6 +19,13 @@
#define MB_BYTE2LEN(b) utf8len_tab[b]
#define MB_BYTE2LEN_CHECK(b) (((b) < 0 || (b) > 255) ? 1 : utf8len_tab[b])
+/// Maximum value for 'maxcombine'
+///
+/// At most that number of composing characters may be attached to the leading
+/// character by various `utfc_*` functions. Note that some functions do not
+/// have this limit.
+enum { MAX_MCO = 6 };
+
// max length of an unicode char
#define MB_MAXCHAR 6
diff --git a/src/nvim/memline.c b/src/nvim/memline.c
index 1e26a728a3..1f388dd34c 100644
--- a/src/nvim/memline.c
+++ b/src/nvim/memline.c
@@ -843,8 +843,7 @@ void ml_recover(void)
mfp = mf_open(fname_used, O_RDONLY);
fname_used = p;
if (mfp == NULL || mfp->mf_fd < 0) {
- if (fname_used != NULL)
- EMSG2(_("E306: Cannot open %s"), fname_used);
+ EMSG2(_("E306: Cannot open %s"), fname_used);
goto theend;
}
buf->b_ml.ml_mfp = mfp;
@@ -1297,18 +1296,14 @@ recover_names (
msg_putchar('\n');
}
- /*
- * Do the loop for every directory in 'directory'.
- * First allocate some memory to put the directory name in.
- */
+ // Do the loop for every directory in 'directory'.
+ // First allocate some memory to put the directory name in.
dir_name = xmalloc(STRLEN(p_dir) + 1);
dirp = p_dir;
- while (dir_name != NULL && *dirp) {
- /*
- * Isolate a directory name from *dirp and put it in dir_name (we know
- * it is large enough, so use 31000 for length).
- * Advance dirp to next directory name.
- */
+ while (*dirp) {
+ // Isolate a directory name from *dirp and put it in dir_name (we know
+ // it is large enough, so use 31000 for length).
+ // Advance dirp to next directory name.
(void)copy_option_part(&dirp, dir_name, 31000, ",");
if (dir_name[0] == '.' && dir_name[1] == NUL) { /* check current dir */
diff --git a/src/nvim/memory.c b/src/nvim/memory.c
index a66ab6a3cc..bfc2f208dd 100644
--- a/src/nvim/memory.c
+++ b/src/nvim/memory.c
@@ -369,10 +369,12 @@ char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen)
/// string that fits in the buffer (unless, of course, the buffer size is
/// zero). It does not pad out the result like strncpy() does.
///
-/// @param dst Buffer to store the result
-/// @param src String to be copied
-/// @param dsize Size of `dst`
-/// @return strlen(src). If retval >= dstsize, truncation occurs.
+/// @param[out] dst Buffer to store the result.
+/// @param[in] src String to be copied.
+/// @param[in] dsize Size of `dst`.
+///
+/// @return Length of `src`. May be greater than `dsize - 1`, which would mean
+/// that string was truncated.
size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t dsize)
FUNC_ATTR_NONNULL_ALL
{
@@ -394,11 +396,13 @@ size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t dsize)
/// @see vim_strcat from Vim.
/// @see strlcat from OpenBSD.
///
-/// @param dst Buffer to be appended-to. Must have a NUL byte.
-/// @param src String to put at the end of `dst`
-/// @param dsize Size of `dst` including NUL byte. Must be greater than 0.
-/// @return strlen(src) + strlen(initial dst)
-/// If retval >= dsize, truncation occurs.
+/// @param[in,out] dst Buffer to be appended-to. Must have a NUL byte.
+/// @param[in] src String to put at the end of `dst`.
+/// @param[in] dsize Size of `dst` including NUL byte. Must be greater than 0.
+///
+/// @return Length of the resulting string as if destination size was #SIZE_MAX.
+/// May be greater than `dsize - 1`, which would mean that string was
+/// truncated.
size_t xstrlcat(char *const dst, const char *const src, const size_t dsize)
FUNC_ATTR_NONNULL_ALL
{
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 3a3c9cb167..7ca82c2878 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -1382,9 +1382,6 @@ const char *str2special(const char **const sp, const bool replace_spaces,
if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) {
c = TO_SPECIAL((uint8_t)str[1], (uint8_t)str[2]);
str += 2;
- if (c == KS_ZERO) { // display <Nul> as ^@ or <Nul>
- c = NUL;
- }
}
if (IS_SPECIAL(c) || modifiers) { // Special key.
special = true;
@@ -1415,7 +1412,7 @@ const char *str2special(const char **const sp, const bool replace_spaces,
|| (replace_lt && c == '<')) {
return (const char *)get_special_key_name(c, modifiers);
}
- buf[0] = c;
+ buf[0] = (char)c;
buf[1] = NUL;
return buf;
}
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index b421d81b7e..b39b139f9b 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -3568,7 +3568,7 @@ int do_join(size_t count,
int *comments = NULL;
int remove_comments = (use_formatoptions == TRUE)
&& has_format_option(FO_REMOVE_COMS);
- bool prev_was_comment;
+ bool prev_was_comment = false;
if (save_undo && u_save(curwin->w_cursor.lnum - 1,
curwin->w_cursor.lnum + (linenr_T)count) == FAIL) {
@@ -3592,17 +3592,16 @@ int do_join(size_t count,
curwin->w_buffer->b_op_start.col = (colnr_T)STRLEN(curr);
}
if (remove_comments) {
- /* We don't want to remove the comment leader if the
- * previous line is not a comment. */
+ // We don't want to remove the comment leader if the
+ // previous line is not a comment.
if (t > 0 && prev_was_comment) {
-
- char_u *new_curr = skip_comment(curr, TRUE, insert_space,
- &prev_was_comment);
+ char_u *new_curr = skip_comment(curr, true, insert_space,
+ &prev_was_comment);
comments[t] = (int)(new_curr - curr);
curr = new_curr;
- } else
- curr = skip_comment(curr, FALSE, insert_space,
- &prev_was_comment);
+ } else {
+ curr = skip_comment(curr, false, insert_space, &prev_was_comment);
+ }
}
if (insert_space && t > 0) {
@@ -3891,9 +3890,6 @@ fex_format (
// Make a copy, the option could be changed while calling it.
fex = vim_strsave(curbuf->b_p_fex);
- if (fex == NULL) {
- return 0;
- }
// Evaluate the function.
if (use_sandbox) {
sandbox++;
@@ -4610,9 +4606,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
}
}
curwin->w_cursor.col = col;
- if (!did_change) {
- startpos = curwin->w_cursor;
- }
+ startpos = curwin->w_cursor;
did_change = true;
(void)del_char(false);
ins_char(firstdigit);
@@ -4687,9 +4681,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
// Delete the old number.
curwin->w_cursor.col = col;
- if (!did_change) {
- startpos = curwin->w_cursor;
- }
+ startpos = curwin->w_cursor;
did_change = true;
todel = length;
c = gchar_cursor();
@@ -4716,9 +4708,6 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
// When there are many leading zeros it could be very long.
// Allocate a bit too much.
buf1 = xmalloc((size_t)length + NUMBUFLEN);
- if (buf1 == NULL) {
- goto theend;
- }
ptr = buf1;
if (negative && (!visual || was_positive)) {
*ptr++ = '-';
@@ -4754,7 +4743,7 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIu64, (uint64_t)n);
} else if (pre == '0') {
vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIo64, (uint64_t)n);
- } else if (pre && hexupper) {
+ } else if (hexupper) {
vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIX64, (uint64_t)n);
} else {
vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIx64, (uint64_t)n);
@@ -4775,18 +4764,16 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
ins_str(buf1); // insert the new number
xfree(buf1);
endpos = curwin->w_cursor;
- if (did_change && curwin->w_cursor.col) {
+ if (curwin->w_cursor.col) {
curwin->w_cursor.col--;
}
}
- if (did_change) {
- // set the '[ and '] marks
- curbuf->b_op_start = startpos;
- curbuf->b_op_end = endpos;
- if (curbuf->b_op_end.col > 0) {
- curbuf->b_op_end.col--;
- }
+ // set the '[ and '] marks
+ curbuf->b_op_start = startpos;
+ curbuf->b_op_end = endpos;
+ if (curbuf->b_op_end.col > 0) {
+ curbuf->b_op_end.col--;
}
theend:
@@ -5764,7 +5751,7 @@ static void set_clipboard(int name, yankreg_T *reg)
list_T *args = tv_list_alloc(3);
tv_list_append_list(args, lines);
- tv_list_append_string(args, &regtype, 1);
+ tv_list_append_string(args, &regtype, 1); // -V614
tv_list_append_string(args, ((char[]) { (char)name }), 1);
(void)eval_call_provider("clipboard", "set", args);
diff --git a/src/nvim/option.c b/src/nvim/option.c
index c43ba2fc4f..48fd797ee9 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -625,12 +625,12 @@ void set_init_1(void)
opt_idx = findoption("maxmemtot");
if (opt_idx >= 0) {
{
- /* Use half of amount of memory available to Vim. */
- /* If too much to fit in uintptr_t, get uintptr_t max */
+ // Use half of amount of memory available to Vim.
+ // If too much to fit in uintptr_t, get uintptr_t max.
uint64_t available_kib = os_get_total_mem_kib();
- uintptr_t n = available_kib / 2 > UINTPTR_MAX
- ? UINTPTR_MAX
- : (uintptr_t)(available_kib /2);
+ uintptr_t n = (available_kib / 2 > UINTPTR_MAX // -V547
+ ? UINTPTR_MAX
+ : (uintptr_t)(available_kib /2));
options[opt_idx].def_val[VI_DEFAULT] = (char_u *)n;
opt_idx = findoption("maxmem");
if (opt_idx >= 0) {
@@ -4160,10 +4160,6 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
if (value < 0) {
errmsg = e_positive;
}
- } else if (pp == &p_titlelen) {
- if (value < 0) {
- errmsg = e_positive;
- }
} else if (pp == &p_so) {
if (value < 0 && full_screen) {
errmsg = e_scroll;
@@ -4184,27 +4180,23 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
if (value < 0) {
errmsg = e_positive;
}
- } else if (pp == &curwin->w_p_fdl
- || pp == (long *)GLOBAL_WO(&curwin->w_p_fdl)) {
+ } else if (pp == &curwin->w_p_fdl || pp == &curwin->w_allbuf_opt.wo_fdl) {
if (value < 0) {
errmsg = e_positive;
}
- } else if (pp == &curwin->w_p_fdc
- || pp == (long *)GLOBAL_WO(&curwin->w_p_fdc)) {
+ } else if (pp == &curwin->w_p_fdc || pp == &curwin->w_allbuf_opt.wo_fdc) {
if (value < 0) {
errmsg = e_positive;
} else if (value > 12) {
errmsg = e_invarg;
}
- } else if (pp == &curwin->w_p_cole
- || pp == (long *)GLOBAL_WO(&curwin->w_p_cole)) {
+ } else if (pp == &curwin->w_p_cole || pp == &curwin->w_allbuf_opt.wo_cole) {
if (value < 0) {
errmsg = e_positive;
} else if (value > 3) {
errmsg = e_invarg;
}
- } else if (pp == &curwin->w_p_nuw
- || pp == (long *)GLOBAL_WO(&curwin->w_p_nuw)) {
+ } else if (pp == &curwin->w_p_nuw || pp == &curwin->w_allbuf_opt.wo_nuw) {
if (value < 1) {
errmsg = e_positive;
} else if (value > 10) {
@@ -5801,25 +5793,28 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_ro = FALSE; /* don't copy readonly */
buf->b_p_fenc = vim_strsave(p_fenc);
switch (*p_ffs) {
- case 'm':
- buf->b_p_ff = vim_strsave((char_u *)FF_MAC);
- break;
- case 'd':
- buf->b_p_ff = vim_strsave((char_u *)FF_DOS);
- break;
- case 'u':
- buf->b_p_ff = vim_strsave((char_u *)FF_UNIX);
- break;
- default:
- buf->b_p_ff = vim_strsave(p_ff);
- }
- if (buf->b_p_ff != NULL) {
- buf->b_start_ffc = *buf->b_p_ff;
+ case 'm': {
+ buf->b_p_ff = vim_strsave((char_u *)FF_MAC);
+ break;
+ }
+ case 'd': {
+ buf->b_p_ff = vim_strsave((char_u *)FF_DOS);
+ break;
+ }
+ case 'u': {
+ buf->b_p_ff = vim_strsave((char_u *)FF_UNIX);
+ break;
+ }
+ default: {
+ buf->b_p_ff = vim_strsave(p_ff);
+ break;
+ }
}
buf->b_p_bh = empty_option;
buf->b_p_bt = empty_option;
- } else
- free_buf_options(buf, FALSE);
+ } else {
+ free_buf_options(buf, false);
+ }
buf->b_p_ai = p_ai;
buf->b_p_ai_nopaste = p_ai_nopaste;
@@ -6080,7 +6075,7 @@ set_context_in_set_cmd (
xp->xp_context = EXPAND_UNSUCCESSFUL;
return;
}
- if (xp->xp_context != EXPAND_BOOL_SETTINGS && p[1] == NUL) {
+ if (p[1] == NUL) {
xp->xp_context = EXPAND_OLD_SETTING;
if (is_term_option)
expand_option_idx = -1;
@@ -6224,14 +6219,15 @@ void ExpandOldSetting(int *num_file, char_u ***file)
}
if (expand_option_idx >= 0) {
- /* put string of option value in NameBuff */
+ // Put string of option value in NameBuff.
option_value2string(&options[expand_option_idx], expand_option_flags);
var = NameBuff;
- } else if (var == NULL)
+ } else {
var = (char_u *)"";
+ }
- /* A backslash is required before some characters. This is the reverse of
- * what happens in do_set(). */
+ // A backslash is required before some characters. This is the reverse of
+ // what happens in do_set().
char_u *buf = vim_strsave_escaped(var, escape_chars);
#ifdef BACKSLASH_IN_FILENAME
diff --git a/src/nvim/os/env.c b/src/nvim/os/env.c
index 3fcb9415c7..7fb4a93b54 100644
--- a/src/nvim/os/env.c
+++ b/src/nvim/os/env.c
@@ -14,6 +14,7 @@
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/path.h"
+#include "nvim/macros.h"
#include "nvim/strings.h"
#include "nvim/eval.h"
#include "nvim/ex_getln.h"
@@ -176,7 +177,7 @@ void os_get_hostname(char *hostname, size_t size)
/// - do os_dirname() to get the real name of that directory.
/// This also works with mounts and links.
/// Don't do this for Windows, it will change the "current dir" for a drive.
-static char_u *homedir = NULL;
+static char *homedir = NULL;
void init_homedir(void)
{
@@ -220,7 +221,7 @@ void init_homedir(void)
}
}
#endif
- homedir = vim_strsave((char_u *)var);
+ homedir = xstrdup(var);
}
}
@@ -357,7 +358,7 @@ void expand_env_esc(char_u *restrict srcp,
} else if (src[1] == NUL // home directory
|| vim_ispathsep(src[1])
|| vim_strchr((char_u *)" ,\t\n", src[1]) != NULL) {
- var = homedir;
+ var = (char_u *)homedir;
tail = src + 1;
} else { // user directory
#if defined(UNIX)
@@ -719,108 +720,123 @@ char *vim_getenv(const char *name)
/// Replace home directory by "~" in each space or comma separated file name in
/// 'src'.
+///
+/// Replace home directory with tilde in each file name
+///
/// If anything fails (except when out of space) dst equals src.
-/// @param buf When not NULL, check for help files
-/// @param src Input file name
-/// @param dst Where to put the result
-/// @param dstlen Maximum length of the result
-/// @param one If true, only replace one file name, including spaces and commas
-/// in the file name
-void home_replace(const buf_T *const buf, const char_u *src,
- char_u *dst, size_t dstlen, bool one)
+///
+/// @param[in] buf When not NULL, uses this buffer to check whether it is
+/// a help file. If it is then path to file is removed
+/// completely, `one` is ignored and assumed to be true.
+/// @param[in] src Input file names. Assumed to be a space/comma separated
+/// list unless `one` is true.
+/// @param[out] dst Where to put the result.
+/// @param[in] dstlen Destination length.
+/// @param[in] one If true, assumes source is a single file name and not
+/// a list of them.
+///
+/// @return length of the string put into dst, does not include NUL byte.
+size_t home_replace(const buf_T *const buf, const char_u *src,
+ char_u *const dst, size_t dstlen, const bool one)
+ FUNC_ATTR_NONNULL_ARG(3)
{
- size_t dirlen = 0, envlen = 0;
- size_t len;
+ size_t dirlen = 0;
+ size_t envlen = 0;
if (src == NULL) {
*dst = NUL;
- return;
+ return 0;
}
- /*
- * If the file is a help file, remove the path completely.
- */
if (buf != NULL && buf->b_help) {
- xstrlcpy((char *)dst, (char *)path_tail(src), dstlen);
- return;
+ const size_t dlen = xstrlcpy((char *)dst, (char *)path_tail(src), dstlen);
+ return MIN(dlen, dstlen - 1);
}
- /*
- * We check both the value of the $HOME environment variable and the
- * "real" home directory.
- */
- if (homedir != NULL)
- dirlen = STRLEN(homedir);
+ // We check both the value of the $HOME environment variable and the
+ // "real" home directory.
+ if (homedir != NULL) {
+ dirlen = strlen(homedir);
+ }
- char_u *homedir_env = (char_u *)os_getenv("HOME");
+ const char *const homedir_env = os_getenv("HOME");
+ char *homedir_env_mod = (char *)homedir_env;
bool must_free = false;
- if (homedir_env != NULL && vim_strchr(homedir_env, '~') != NULL) {
+ if (homedir_env_mod != NULL && strchr(homedir_env_mod, '~') != NULL) {
must_free = true;
size_t usedlen = 0;
- size_t flen = STRLEN(homedir_env);
+ size_t flen = strlen(homedir_env_mod);
char_u *fbuf = NULL;
- (void)modify_fname((char_u *)":p", &usedlen, &homedir_env, &fbuf, &flen);
- flen = STRLEN(homedir_env);
- if (flen > 0 && vim_ispathsep(homedir_env[flen - 1]))
- /* Remove the trailing / that is added to a directory. */
- homedir_env[flen - 1] = NUL;
+ (void)modify_fname((char_u *)":p", &usedlen, (char_u **)&homedir_env_mod,
+ &fbuf, &flen);
+ flen = strlen(homedir_env_mod);
+ assert(homedir_env_mod != homedir_env);
+ if (vim_ispathsep(homedir_env_mod[flen - 1])) {
+ // Remove the trailing / that is added to a directory.
+ homedir_env_mod[flen - 1] = NUL;
+ }
}
- if (homedir_env != NULL)
- envlen = STRLEN(homedir_env);
+ if (homedir_env_mod != NULL) {
+ envlen = strlen(homedir_env_mod);
+ }
- if (!one)
+ if (!one) {
src = skipwhite(src);
+ }
+ char *dst_p = (char *)dst;
while (*src && dstlen > 0) {
- /*
- * Here we are at the beginning of a file name.
- * First, check to see if the beginning of the file name matches
- * $HOME or the "real" home directory. Check that there is a '/'
- * after the match (so that if e.g. the file is "/home/pieter/bla",
- * and the home directory is "/home/piet", the file does not end up
- * as "~er/bla" (which would seem to indicate the file "bla" in user
- * er's home directory)).
- */
- char_u *p = homedir;
- len = dirlen;
- for (;; ) {
- if ( len
- && fnamencmp(src, p, len) == 0
- && (vim_ispathsep(src[len])
- || (!one && (src[len] == ',' || src[len] == ' '))
- || src[len] == NUL)) {
+ // Here we are at the beginning of a file name.
+ // First, check to see if the beginning of the file name matches
+ // $HOME or the "real" home directory. Check that there is a '/'
+ // after the match (so that if e.g. the file is "/home/pieter/bla",
+ // and the home directory is "/home/piet", the file does not end up
+ // as "~er/bla" (which would seem to indicate the file "bla" in user
+ // er's home directory)).
+ char *p = homedir;
+ size_t len = dirlen;
+ for (;;) {
+ if (len
+ && fnamencmp(src, (char_u *)p, len) == 0
+ && (vim_ispathsep(src[len])
+ || (!one && (src[len] == ',' || src[len] == ' '))
+ || src[len] == NUL)) {
src += len;
- if (--dstlen > 0)
- *dst++ = '~';
-
- /*
- * If it's just the home directory, add "/".
- */
- if (!vim_ispathsep(src[0]) && --dstlen > 0)
- *dst++ = '/';
+ if (--dstlen > 0) {
+ *dst_p++ = '~';
+ }
+
+ // If it's just the home directory, add "/".
+ if (!vim_ispathsep(src[0]) && --dstlen > 0) {
+ *dst_p++ = '/';
+ }
break;
}
- if (p == homedir_env)
+ if (p == homedir_env_mod) {
break;
- p = homedir_env;
+ }
+ p = homedir_env_mod;
len = envlen;
}
- /* if (!one) skip to separator: space or comma */
- while (*src && (one || (*src != ',' && *src != ' ')) && --dstlen > 0)
- *dst++ = *src++;
- /* skip separator */
- while ((*src == ' ' || *src == ',') && --dstlen > 0)
- *dst++ = *src++;
+ // if (!one) skip to separator: space or comma.
+ while (*src && (one || (*src != ',' && *src != ' ')) && --dstlen > 0) {
+ *dst_p++ = (char)(*src++);
+ }
+ // Skip separator.
+ while ((*src == ' ' || *src == ',') && --dstlen > 0) {
+ *dst_p++ = (char)(*src++);
+ }
}
- /* if (dstlen == 0) out of space, what to do??? */
+ // If (dstlen == 0) out of space, what to do???
- *dst = NUL;
+ *dst_p = NUL;
if (must_free) {
- xfree(homedir_env);
+ xfree(homedir_env_mod);
}
+ return (size_t)(dst_p - (char *)dst);
}
/// Like home_replace, store the replaced string in allocated memory.
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index 3e1af7f1c2..5412c5daae 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -542,7 +542,7 @@ ptrdiff_t os_readv(const int fd, bool *const ret_eof, struct iovec *iov,
}
while (read_bytes < toread && iov_size && !*ret_eof) {
ptrdiff_t cur_read_bytes = readv(fd, iov, (int)iov_size);
- if (toread && cur_read_bytes == 0) {
+ if (cur_read_bytes == 0) {
*ret_eof = true;
}
if (cur_read_bytes > 0) {
diff --git a/src/nvim/path.c b/src/nvim/path.c
index 168d835a66..4f3f7c0661 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -673,11 +673,12 @@ static size_t do_path_expand(garray_T *gap, const char_u *path,
// Find all matching entries.
char_u *name;
scandir_next_with_dots(NULL); // initialize
- while ((name = (char_u *) scandir_next_with_dots(&dir)) && name != NULL) {
+ while ((name = (char_u *)scandir_next_with_dots(&dir)) != NULL) {
if ((name[0] != '.'
|| starts_with_dot
|| ((flags & EW_DODOT)
- && name[1] != NUL && (name[1] != '.' || name[2] != NUL)))
+ && name[1] != NUL
+ && (name[1] != '.' || name[2] != NUL))) // -V557
&& ((regmatch.regprog != NULL && vim_regexec(&regmatch, name, 0))
|| ((flags & EW_NOTWILD)
&& fnamencmp(path + (s - buf), name, e - s) == 0))) {
diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c
index 348daf028a..4c2fc6d906 100644
--- a/src/nvim/popupmnu.c
+++ b/src/nvim/popupmnu.c
@@ -387,7 +387,7 @@ void pum_redraw(void)
char_u saved = *p;
*p = NUL;
- st = transstr(s);
+ st = (char_u *)transstr((const char *)s);
*p = saved;
if (curwin->w_p_rl) {
diff --git a/src/nvim/pos.h b/src/nvim/pos.h
index 966255e6a4..0a2afd5847 100644
--- a/src/nvim/pos.h
+++ b/src/nvim/pos.h
@@ -10,8 +10,10 @@ typedef int colnr_T;
/// Format used to print values which have colnr_T type
#define PRIdCOLNR "d"
-#define MAXLNUM 0x7fffffff // maximum (invalid) line number
-#define MAXCOL 0x7fffffff // maximum column number, 31 bits
+/// Maximal (invalid) line number
+enum { MAXLNUM = 0x7fffffff };
+/// Maximal column number, 31 bits
+enum { MAXCOL = 0x7fffffff };
/*
* position in file or buffer
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 46124e0672..1c3cb5d6b2 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -924,7 +924,7 @@ restofline:
if (qfprev == NULL) {
return QF_FAIL;
}
- if (*fields->errmsg && !qi->qf_multiignore) {
+ if (*fields->errmsg) {
size_t len = STRLEN(qfprev->qf_text);
qfprev->qf_text = xrealloc(qfprev->qf_text,
len + STRLEN(fields->errmsg) + 2);
@@ -2062,7 +2062,7 @@ win_found:
EMSG(_("E924: Current window was closed"));
is_abort = true;
opened_window = false;
- } else if (old_qf_curlist != qi->qf_curlist
+ } else if (old_qf_curlist != qi->qf_curlist // -V560
|| !is_qf_entry_present(qi, qf_ptr)) {
if (qi == &ql_info) {
EMSG(_("E925: Current quickfix was changed"));
@@ -3626,7 +3626,7 @@ void ex_vimgrep(exarg_T *eap)
&& eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd)
|| qi->qf_curlist == qi->qf_listcount) {
// make place for a new list
- qf_new_list(qi, title != NULL ? title : *eap->cmdlinep);
+ qf_new_list(qi, title);
}
/* parse the list of arguments */
@@ -4205,11 +4205,9 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
if ((status == OK) && (flags & QF_GETLIST_CONTEXT)) {
if (qi->qf_lists[qf_idx].qf_ctx != NULL) {
di = tv_dict_item_alloc_len(S_LEN("context"));
- if (di != NULL) {
- tv_copy(qi->qf_lists[qf_idx].qf_ctx, &di->di_tv);
- if (tv_dict_add(retdict, di) == FAIL) {
- tv_dict_item_free(di);
- }
+ tv_copy(qi->qf_lists[qf_idx].qf_ctx, &di->di_tv);
+ if (tv_dict_add(retdict, di) == FAIL) {
+ tv_dict_item_free(di);
}
} else {
status = tv_dict_add_str(retdict, S_LEN("context"), "");
@@ -4740,15 +4738,7 @@ void ex_helpgrep(exarg_T *eap)
regmatch.regprog = vim_regcomp(eap->arg, RE_MAGIC + RE_STRING);
regmatch.rm_ic = FALSE;
if (regmatch.regprog != NULL) {
- vimconv_T vc;
-
- /* Help files are in utf-8 or latin1, convert lines when 'encoding'
- * differs. */
- vc.vc_type = CONV_NONE;
- if (!enc_utf8)
- convert_setup(&vc, (char_u *)"utf-8", p_enc);
-
- /* create a new quickfix list */
+ // Create a new quickfix list.
qf_new_list(qi, *eap->cmdlinep);
/* Go through all directories in 'runtimepath' */
@@ -4780,15 +4770,6 @@ void ex_helpgrep(exarg_T *eap)
lnum = 1;
while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) {
char_u *line = IObuff;
- /* Convert a line if 'encoding' is not utf-8 and
- * the line contains a non-ASCII character. */
- if (vc.vc_type != CONV_NONE
- && has_non_ascii(IObuff)) {
- line = string_convert(&vc, IObuff, NULL);
- if (line == NULL)
- line = IObuff;
- }
-
if (vim_regexec(&regmatch, line, (colnr_T)0)) {
int l = (int)STRLEN(line);
@@ -4831,8 +4812,6 @@ void ex_helpgrep(exarg_T *eap)
}
vim_regfree(regmatch.regprog);
- if (vc.vc_type != CONV_NONE)
- convert_setup(&vc, NULL, NULL);
qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE;
qi->qf_lists[qi->qf_curlist].qf_ptr =
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index c520ef5fb9..98fae858f6 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -4117,7 +4117,7 @@ skip_add:
if (state->c == NFA_ZSTART) {
subidx = 0;
sub = &subs->norm;
- } else if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9) {
+ } else if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9) { // -V560
subidx = state->c - NFA_ZOPEN;
sub = &subs->synt;
} else {
@@ -4169,11 +4169,12 @@ skip_add:
}
subs = addstate(l, state->out, subs, pim, off_arg);
- /* "subs" may have changed, need to set "sub" again */
- if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9)
+ // "subs" may have changed, need to set "sub" again.
+ if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9) { // -V560
sub = &subs->synt;
- else
+ } else {
sub = &subs->norm;
+ }
if (save_in_use == -1) {
if (REG_MULTI) {
@@ -4217,7 +4218,7 @@ skip_add:
if (state->c == NFA_ZEND) {
subidx = 0;
sub = &subs->norm;
- } else if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) {
+ } else if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) { // -V560
subidx = state->c - NFA_ZCLOSE;
sub = &subs->synt;
} else {
@@ -4250,11 +4251,12 @@ skip_add:
}
subs = addstate(l, state->out, subs, pim, off_arg);
- /* "subs" may have changed, need to set "sub" again */
- if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9)
+ // "subs" may have changed, need to set "sub" again.
+ if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) { // -V560
sub = &subs->synt;
- else
+ } else {
sub = &subs->norm;
+ }
if (REG_MULTI) {
sub->list.multi[subidx] = save_multipos;
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 731bb2658a..2e64eb864f 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -24,8 +24,6 @@
* cells the next byte in ScreenLines[] is 0.
* ScreenLinesC[][] contain up to 'maxcombine' composing characters
* (drawn on top of the first character). There is 0 after the last one used.
- * ScreenLines2[] is only used for euc-jp to store the second byte if the
- * first byte is 0x8e (single-width character).
*
* The screen_*() functions write to the screen and handle updating
* ScreenLines[].
@@ -1918,12 +1916,10 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T
}
if (cells > 1)
ScreenLines[idx + 1] = 0;
- } else if (enc_dbcs == DBCS_JPNU && *p == 0x8e)
- /* double-byte single width character */
- ScreenLines2[idx] = p[1];
- else if (cells > 1)
- /* double-width character */
+ } else if (cells > 1) {
+ // Double-width character.
ScreenLines[idx + 1] = p[1];
+ }
col += cells;
idx += cells;
p += c_len;
@@ -2144,7 +2140,6 @@ win_line (
bool nochange /* not updating for changed text */
)
{
- int col = 0; // visual column on screen
unsigned off; // offset in ScreenLines/ScreenAttrs
int c = 0; // init for GCC
long vcol = 0; // virtual column (for tabs)
@@ -2553,7 +2548,7 @@ win_line (
ptr = prev_ptr;
// If the character fits on the screen, don't need to skip it.
// Except for a TAB.
- if (((*mb_ptr2cells)(ptr) >= c || *ptr == TAB) && col == 0) {
+ if (utf_ptr2cells(ptr) >= c || *ptr == TAB) {
n_skip = v - vcol;
}
}
@@ -2702,11 +2697,11 @@ win_line (
}
off = (unsigned)(current_ScreenLine - ScreenLines);
- col = 0;
+ int col = 0; // Visual column on screen.
if (wp->w_p_rl) {
- /* Rightleft window: process the text in the normal direction, but put
- * it in current_ScreenLine[] from right to left. Start at the
- * rightmost column of the window. */
+ // Rightleft window: process the text in the normal direction, but put
+ // it in current_ScreenLine[] from right to left. Start at the
+ // rightmost column of the window.
col = wp->w_width - 1;
off += col;
}
@@ -2761,7 +2756,6 @@ win_line (
// Draw cells with the sign value or blank.
c_extra = ' ';
char_attr = win_hl_attr(wp, HLF_SC);
- n_extra = 2;
n_extra = win_signcol_width(wp);
if (row == startrow + filler_lines && filler_todo <= 0) {
@@ -3210,9 +3204,9 @@ win_line (
|| (mb_l > 1 && (!vim_isprintc(mb_c)))) {
// Illegal UTF-8 byte: display as <xx>.
// Non-BMP character : display as ? or fullwidth ?.
- transchar_hex(extra, mb_c);
- if (wp->w_p_rl) { // reverse
- rl_mirror(extra);
+ transchar_hex((char *)extra, mb_c);
+ if (wp->w_p_rl) { // reverse
+ rl_mirror(extra);
}
p_extra = extra;
@@ -3543,8 +3537,7 @@ win_line (
tab_len += vcol_off;
}
// boguscols before FIX_FOR_BOGUSCOLS macro from above.
- if (wp->w_p_list && lcs_tab1 && old_boguscols > 0
- && n_extra > tab_len) {
+ if (lcs_tab1 && old_boguscols > 0 && n_extra > tab_len) {
tab_len += n_extra - tab_len;
}
@@ -4090,24 +4083,19 @@ win_line (
--col;
}
ScreenLines[off] = c;
- if (enc_dbcs == DBCS_JPNU) {
- if ((mb_c & 0xff00) == 0x8e00)
- ScreenLines[off] = 0x8e;
- ScreenLines2[off] = mb_c & 0xff;
- } else if (enc_utf8) {
- if (mb_utf8) {
- int i;
-
- ScreenLinesUC[off] = mb_c;
- if ((c & 0xff) == 0)
- ScreenLines[off] = 0x80; /* avoid storing zero */
- for (i = 0; i < Screen_mco; ++i) {
- ScreenLinesC[i][off] = u8cc[i];
- if (u8cc[i] == 0)
- break;
+ if (mb_utf8) {
+ ScreenLinesUC[off] = mb_c;
+ if ((c & 0xff) == 0) {
+ ScreenLines[off] = 0x80; // Avoid storing zero.
+ }
+ for (int i = 0; i < Screen_mco; i++) {
+ ScreenLinesC[i][off] = u8cc[i];
+ if (u8cc[i] == 0) {
+ break;
}
- } else
- ScreenLinesUC[off] = 0;
+ }
+ } else {
+ ScreenLinesUC[off] = 0;
}
if (multi_attr) {
ScreenAttrs[off] = multi_attr;
@@ -4379,23 +4367,14 @@ static int comp_char_differs(int off_from, int off_to)
static int char_needs_redraw(int off_from, int off_to, int cols)
{
return (cols > 0
- && ((ScreenLines[off_from] != ScreenLines[off_to]
- || ScreenAttrs[off_from] != ScreenAttrs[off_to])
-
- || (enc_dbcs != 0
- && MB_BYTE2LEN(ScreenLines[off_from]) > 1
- && (enc_dbcs == DBCS_JPNU && ScreenLines[off_from] == 0x8e
- ? ScreenLines2[off_from] != ScreenLines2[off_to]
- : (cols > 1 && ScreenLines[off_from + 1]
- != ScreenLines[off_to + 1])))
- || (enc_utf8
- && (ScreenLinesUC[off_from] != ScreenLinesUC[off_to]
- || (ScreenLinesUC[off_from] != 0
- && comp_char_differs(off_from, off_to))
- || ((*mb_off2cells)(off_from, off_from + cols) > 1
- && ScreenLines[off_from + 1]
- != ScreenLines[off_to + 1])))
- || p_wd < 0));
+ && (ScreenLines[off_from] != ScreenLines[off_to]
+ || ScreenAttrs[off_from] != ScreenAttrs[off_to]
+ || ScreenLinesUC[off_from] != ScreenLinesUC[off_to]
+ || (ScreenLinesUC[off_from] != 0
+ && comp_char_differs(off_from, off_to))
+ || (utf_off2cells(off_from, off_from + cols) > 1
+ && ScreenLines[off_from + 1] != ScreenLines[off_to + 1])
+ || p_wd < 0));
}
/*
@@ -4503,9 +4482,6 @@ static void screen_line(int row, int coloff, int endcol,
ScreenLines[off_to + 2] = 0;
redraw_next = TRUE;
}
-
- if (enc_dbcs == DBCS_JPNU)
- ScreenLines2[off_to] = ScreenLines2[off_from];
}
/* When writing a single-width character over a double-width
* character and at the end of the redrawn text, need to clear out
@@ -5238,8 +5214,8 @@ win_redr_custom (
xfree(stl);
ewp->w_p_crb = p_crb_save;
- /* Make all characters printable. */
- p = transstr(buf);
+ // Make all characters printable.
+ p = (char_u *)transstr((const char *)buf);
len = STRLCPY(buf, p, sizeof(buf));
len = (size_t)len < sizeof(buf) ? len : (int)sizeof(buf) - 1;
xfree(p);
@@ -5331,16 +5307,7 @@ void screen_getbytes(int row, int col, char_u *bytes, int *attrp)
bytes[0] = ScreenLines[off];
bytes[1] = NUL;
- if (enc_utf8 && ScreenLinesUC[off] != 0)
- bytes[utfc_char2bytes(off, bytes)] = NUL;
- else if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e) {
- bytes[0] = ScreenLines[off];
- bytes[1] = ScreenLines2[off];
- bytes[2] = NUL;
- } else if (enc_dbcs && MB_BYTE2LEN(bytes[0]) > 1) {
- bytes[1] = ScreenLines[off + 1];
- bytes[2] = NUL;
- }
+ bytes[utfc_char2bytes(off, bytes)] = NUL;
}
}
@@ -5530,11 +5497,9 @@ void screen_puts_len(char_u *text, int textlen, int row, int col, int attr)
ScreenLines[off + 1] = ptr[1];
ScreenAttrs[off + 1] = attr;
screen_char_2(off, row, col);
- } else if (l_enc_dbcs == DBCS_JPNU && c == 0x8e) {
- ScreenLines2[off] = ptr[1];
- screen_char(off, row, col);
- } else
+ } else {
screen_char(off, row, col);
+ }
}
if (l_has_mbyte) {
off += mbyte_cells;
@@ -5907,7 +5872,7 @@ static void screen_char(unsigned off, int row, int col)
ui_cursor_goto(row, col);
ui_set_highlight(ScreenAttrs[off]);
- if (enc_utf8 && ScreenLinesUC[off] != 0) {
+ if (ScreenLinesUC[off] != 0) {
char_u buf[MB_MAXBYTES + 1];
// Convert UTF-8 character to bytes and write it.
@@ -5915,10 +5880,6 @@ static void screen_char(unsigned off, int row, int col)
ui_puts(buf);
} else {
ui_putc(ScreenLines[off]);
- // double-byte character in single-width cell
- if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e) {
- ui_putc(ScreenLines2[off]);
- }
}
}
@@ -6110,40 +6071,25 @@ int screen_valid(int doclear)
void screenalloc(bool doclear)
{
int new_row, old_row;
- int outofmem = FALSE;
int len;
- schar_T *new_ScreenLines;
- u8char_T *new_ScreenLinesUC = NULL;
- u8char_T *new_ScreenLinesC[MAX_MCO];
- schar_T *new_ScreenLines2 = NULL;
- int i;
- sattr_T *new_ScreenAttrs;
- unsigned *new_LineOffset;
- char_u *new_LineWraps;
- StlClickDefinition *new_tab_page_click_defs;
static bool entered = false; // avoid recursiveness
static bool done_outofmem_msg = false;
int retry_count = 0;
- const bool l_enc_utf8 = enc_utf8;
- const int l_enc_dbcs = enc_dbcs;
retry:
- /*
- * Allocation of the screen buffers is done only when the size changes and
- * when Rows and Columns have been set and we have started doing full
- * screen stuff.
- */
+ // Allocation of the screen buffers is done only when the size changes and
+ // when Rows and Columns have been set and we have started doing full
+ // screen stuff.
if ((ScreenLines != NULL
&& Rows == screen_Rows
&& Columns == screen_Columns
- && l_enc_utf8 == (ScreenLinesUC != NULL)
- && (l_enc_dbcs == DBCS_JPNU) == (ScreenLines2 != NULL)
- && p_mco == Screen_mco
- )
+ && ScreenLinesUC != NULL
+ && p_mco == Screen_mco)
|| Rows == 0
|| Columns == 0
- || (!full_screen && ScreenLines == NULL))
+ || (!full_screen && ScreenLines == NULL)) {
return;
+ }
/*
* It's possible that we produce an out-of-memory message below, which
@@ -6181,22 +6127,22 @@ retry:
if (aucmd_win != NULL)
win_free_lsize(aucmd_win);
- new_ScreenLines = xmalloc((size_t)((Rows + 1) * Columns * sizeof(schar_T)));
- memset(new_ScreenLinesC, 0, sizeof(u8char_T *) * MAX_MCO);
- if (l_enc_utf8) {
- new_ScreenLinesUC = xmalloc(
- (size_t)((Rows + 1) * Columns * sizeof(u8char_T)));
- for (i = 0; i < p_mco; ++i)
- new_ScreenLinesC[i] = xcalloc((Rows + 1) * Columns, sizeof(u8char_T));
- }
- if (l_enc_dbcs == DBCS_JPNU)
- new_ScreenLines2 = xmalloc(
- (size_t)((Rows + 1) * Columns * sizeof(schar_T)));
- new_ScreenAttrs = xmalloc((size_t)((Rows + 1) * Columns * sizeof(sattr_T)));
- new_LineOffset = xmalloc((size_t)(Rows * sizeof(unsigned)));
- new_LineWraps = xmalloc((size_t)(Rows * sizeof(char_u)));
- new_tab_page_click_defs = xcalloc(
- (size_t) Columns, sizeof(*new_tab_page_click_defs));
+ schar_T *new_ScreenLines = xmalloc(
+ (size_t)((Rows + 1) * Columns * sizeof(*new_ScreenLines)));
+ u8char_T *new_ScreenLinesC[MAX_MCO];
+ memset(new_ScreenLinesC, 0, sizeof(new_ScreenLinesC));
+ u8char_T *new_ScreenLinesUC = xmalloc(
+ (size_t)((Rows + 1) * Columns * sizeof(*new_ScreenLinesUC)));
+ for (int i = 0; i < p_mco; i++) {
+ new_ScreenLinesC[i] = xcalloc(
+ (size_t)((Rows + 1) * Columns), sizeof(new_ScreenLinesC[0][0]));
+ }
+ sattr_T *new_ScreenAttrs = xmalloc(
+ (size_t)((Rows + 1) * Columns * sizeof(*new_ScreenAttrs)));
+ unsigned *new_LineOffset = xmalloc((size_t)(Rows * sizeof(*new_LineOffset)));
+ char_u *new_LineWraps = xmalloc((size_t)(Rows * sizeof(*new_LineWraps)));
+ StlClickDefinition *new_tab_page_click_defs = xcalloc(
+ (size_t)Columns, sizeof(*new_tab_page_click_defs));
FOR_ALL_TAB_WINDOWS(tp, wp) {
win_alloc_lines(wp);
@@ -6205,23 +6151,20 @@ retry:
win_alloc_lines(aucmd_win);
}
- for (i = 0; i < p_mco; ++i)
- if (new_ScreenLinesC[i] == NULL)
+ int i;
+ for (i = 0; i < p_mco; i++) {
+ if (new_ScreenLinesC[i] == NULL) {
break;
- if (new_ScreenLines == NULL
- || (new_ScreenLinesUC == NULL || i != p_mco)
- || new_ScreenAttrs == NULL
- || new_LineOffset == NULL
- || new_LineWraps == NULL
- || new_tab_page_click_defs == NULL
- || outofmem) {
+ }
+ }
+ if (i != p_mco) {
if (ScreenLines != NULL || !done_outofmem_msg) {
- /* guess the size */
+ // Guess the size.
do_outofmem_msg((Rows + 1) * Columns);
- /* Remember we did this to avoid getting outofmem messages over
- * and over again. */
- done_outofmem_msg = TRUE;
+ // Remember we did this to avoid getting outofmem messages over
+ // and over again.
+ done_outofmem_msg = true;
}
xfree(new_ScreenLines);
new_ScreenLines = NULL;
@@ -6231,8 +6174,6 @@ retry:
xfree(new_ScreenLinesC[i]);
new_ScreenLinesC[i] = NULL;
}
- xfree(new_ScreenLines2);
- new_ScreenLines2 = NULL;
xfree(new_ScreenAttrs);
new_ScreenAttrs = NULL;
xfree(new_LineOffset);
@@ -6255,53 +6196,42 @@ retry:
* executing an external command, for the GUI).
*/
if (!doclear) {
- (void)memset(new_ScreenLines + new_row * Columns,
- ' ', (size_t)Columns * sizeof(schar_T));
- if (l_enc_utf8) {
- (void)memset(new_ScreenLinesUC + new_row * Columns,
- 0, (size_t)Columns * sizeof(u8char_T));
- for (i = 0; i < p_mco; ++i)
- (void)memset(new_ScreenLinesC[i]
- + new_row * Columns,
- 0, (size_t)Columns * sizeof(u8char_T));
+ memset(new_ScreenLines + new_row * Columns,
+ ' ', (size_t)Columns * sizeof(new_ScreenLines[0]));
+ memset(new_ScreenLinesUC + new_row * Columns,
+ 0, (size_t)Columns * sizeof(new_ScreenLinesUC[0]));
+ for (i = 0; i < p_mco; i++) {
+ memset(new_ScreenLinesC[i] + new_row * Columns,
+ 0, (size_t)Columns * sizeof(new_ScreenLinesC[0][0]));
}
- if (l_enc_dbcs == DBCS_JPNU)
- (void)memset(new_ScreenLines2 + new_row * Columns,
- 0, (size_t)Columns * sizeof(schar_T));
- (void)memset(new_ScreenAttrs + new_row * Columns,
- 0, (size_t)Columns * sizeof(sattr_T));
+ memset(new_ScreenAttrs + new_row * Columns,
+ 0, (size_t)Columns * sizeof(new_ScreenAttrs[0]));
old_row = new_row + (screen_Rows - Rows);
if (old_row >= 0 && ScreenLines != NULL) {
if (screen_Columns < Columns)
len = screen_Columns;
else
len = Columns;
- /* When switching to utf-8 don't copy characters, they
- * may be invalid now. Also when p_mco changes. */
- if (!(l_enc_utf8 && ScreenLinesUC == NULL)
- && p_mco == Screen_mco)
+ // When switching to utf-8 don't copy characters, they
+ // may be invalid now. Also when p_mco changes.
+ if (ScreenLinesUC != NULL && p_mco == Screen_mco) {
memmove(new_ScreenLines + new_LineOffset[new_row],
- ScreenLines + LineOffset[old_row],
- (size_t)len * sizeof(schar_T));
- if (l_enc_utf8 && ScreenLinesUC != NULL
- && p_mco == Screen_mco) {
- memmove(new_ScreenLinesUC + new_LineOffset[new_row],
- ScreenLinesUC + LineOffset[old_row],
- (size_t)len * sizeof(u8char_T));
- for (i = 0; i < p_mco; ++i)
- memmove(new_ScreenLinesC[i]
- + new_LineOffset[new_row],
- ScreenLinesC[i] + LineOffset[old_row],
- (size_t)len * sizeof(u8char_T));
+ ScreenLines + LineOffset[old_row],
+ (size_t)len * sizeof(new_ScreenLines[0]));
}
- if (ScreenLines2 != NULL) {
- memmove(new_ScreenLines2 + new_LineOffset[new_row],
- ScreenLines2 + LineOffset[old_row],
- (size_t)len * sizeof(schar_T));
+ if (ScreenLinesUC != NULL && p_mco == Screen_mco) {
+ memmove(new_ScreenLinesUC + new_LineOffset[new_row],
+ ScreenLinesUC + LineOffset[old_row],
+ (size_t)len * sizeof(new_ScreenLinesUC[0]));
+ for (i = 0; i < p_mco; i++) {
+ memmove(new_ScreenLinesC[i] + new_LineOffset[new_row],
+ ScreenLinesC[i] + LineOffset[old_row],
+ (size_t)len * sizeof(new_ScreenLinesC[0][0]));
+ }
}
memmove(new_ScreenAttrs + new_LineOffset[new_row],
ScreenAttrs + LineOffset[old_row],
- (size_t)len * sizeof(sattr_T));
+ (size_t)len * sizeof(new_ScreenAttrs[0]));
}
}
}
@@ -6316,7 +6246,6 @@ retry:
for (i = 0; i < p_mco; ++i)
ScreenLinesC[i] = new_ScreenLinesC[i];
Screen_mco = p_mco;
- ScreenLines2 = new_ScreenLines2;
ScreenAttrs = new_ScreenAttrs;
LineOffset = new_LineOffset;
LineWraps = new_LineWraps;
@@ -6350,12 +6279,10 @@ retry:
void free_screenlines(void)
{
- int i;
-
xfree(ScreenLinesUC);
- for (i = 0; i < Screen_mco; ++i)
+ for (int i = 0; i < Screen_mco; i++) {
xfree(ScreenLinesC[i]);
- xfree(ScreenLines2);
+ }
xfree(ScreenLines);
xfree(ScreenAttrs);
xfree(LineOffset);
@@ -6439,25 +6366,21 @@ static void lineclear(unsigned off, int width)
*/
static void linecopy(int to, int from, win_T *wp)
{
- unsigned off_to = LineOffset[to] + wp->w_wincol;
- unsigned off_from = LineOffset[from] + wp->w_wincol;
+ const unsigned off_to = LineOffset[to] + wp->w_wincol;
+ const unsigned off_from = LineOffset[from] + wp->w_wincol;
memmove(ScreenLines + off_to, ScreenLines + off_from,
- wp->w_width * sizeof(schar_T));
- if (enc_utf8) {
- int i;
+ wp->w_width * sizeof(ScreenLines[0]));
- memmove(ScreenLinesUC + off_to, ScreenLinesUC + off_from,
- wp->w_width * sizeof(u8char_T));
- for (i = 0; i < p_mco; ++i)
- memmove(ScreenLinesC[i] + off_to, ScreenLinesC[i] + off_from,
- wp->w_width * sizeof(u8char_T));
+ memmove(ScreenLinesUC + off_to, ScreenLinesUC + off_from,
+ wp->w_width * sizeof(ScreenLinesUC[0]));
+ for (int i = 0; i < p_mco; i++) {
+ memmove(ScreenLinesC[i] + off_to, ScreenLinesC[i] + off_from,
+ wp->w_width * sizeof(ScreenLinesC[0]));
}
- if (enc_dbcs == DBCS_JPNU)
- memmove(ScreenLines2 + off_to, ScreenLines2 + off_from,
- wp->w_width * sizeof(schar_T));
+
memmove(ScreenAttrs + off_to, ScreenAttrs + off_from,
- wp->w_width * sizeof(sattr_T));
+ wp->w_width * sizeof(ScreenAttrs[0]));
}
/*
diff --git a/src/nvim/search.c b/src/nvim/search.c
index 1943e2ca43..84782497a0 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -1493,38 +1493,34 @@ static int check_prevcol(char_u *linep, int col, int ch, int *prevcol)
* Raw string start is found at linep[startpos.col - 1].
* Return true if the matching end can be found between startpos and endpos.
*/
-static int find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos)
+static bool find_rawstring_end(char_u *linep, pos_T *startpos, pos_T *endpos)
{
char_u *p;
char_u *delim_copy;
size_t delim_len;
linenr_T lnum;
- int found = false;
- for (p = linep + startpos->col + 1; *p && *p != '('; ++p) {}
+ for (p = linep + startpos->col + 1; *p && *p != '('; p++) {}
delim_len = (p - linep) - startpos->col - 1;
delim_copy = vim_strnsave(linep + startpos->col + 1, delim_len);
- if (delim_copy == NULL)
- return false;
- for (lnum = startpos->lnum; lnum <= endpos->lnum; ++lnum)
- {
+ bool found = false;
+ for (lnum = startpos->lnum; lnum <= endpos->lnum; lnum++) {
char_u *line = ml_get(lnum);
- for (p = line + (lnum == startpos->lnum
- ? startpos->col + 1 : 0); *p; ++p)
- {
- if (lnum == endpos->lnum && (colnr_T)(p - line) >= endpos->col)
+ for (p = line + (lnum == startpos->lnum ? startpos->col + 1 : 0); *p; p++) {
+ if (lnum == endpos->lnum && (colnr_T)(p - line) >= endpos->col) {
break;
+ }
if (*p == ')' && p[delim_len + 1] == '"'
- && STRNCMP(delim_copy, p + 1, delim_len) == 0)
- {
+ && STRNCMP(delim_copy, p + 1, delim_len) == 0) {
found = true;
break;
}
}
- if (found)
+ if (found) {
break;
+ }
}
xfree(delim_copy);
return found;
@@ -3396,11 +3392,13 @@ again:
goto again;
}
- if (do_include || r < 1) {
- /* Include up to the '>'. */
- while (*get_cursor_pos_ptr() != '>')
- if (inc_cursor() < 0)
+ if (do_include) {
+ // Include up to the '>'.
+ while (*get_cursor_pos_ptr() != '>') {
+ if (inc_cursor() < 0) {
break;
+ }
+ }
} else {
char_u *c = get_cursor_pos_ptr();
// Exclude the '<' of the end tag.
@@ -3944,15 +3942,15 @@ current_search (
if (VIsual_active) {
orig_pos = pos = curwin->w_cursor;
- /* make sure, searching further will extend the match */
- if (VIsual_active) {
- if (forward)
- incl(&pos);
- else
- decl(&pos);
+ // Searching further will extend the match.
+ if (forward) {
+ incl(&pos);
+ } else {
+ decl(&pos);
}
- } else
+ } else {
orig_pos = pos = curwin->w_cursor;
+ }
/* Is the pattern is zero-width? */
int one_char = is_one_char(spats[last_idx].pat, true);
@@ -4017,23 +4015,22 @@ current_search (
VIsual = start_pos;
curwin->w_cursor = pos;
- VIsual_active = TRUE;
+ VIsual_active = true;
VIsual_mode = 'v';
- if (VIsual_active) {
- redraw_curbuf_later(INVERTED); /* update the inversion */
- if (*p_sel == 'e') {
- /* Correction for exclusive selection depends on the direction. */
- if (forward && ltoreq(VIsual, curwin->w_cursor))
- inc_cursor();
- else if (!forward && ltoreq(curwin->w_cursor, VIsual))
- inc(&VIsual);
+ redraw_curbuf_later(INVERTED); // Update the inversion.
+ if (*p_sel == 'e') {
+ // Correction for exclusive selection depends on the direction.
+ if (forward && ltoreq(VIsual, curwin->w_cursor)) {
+ inc_cursor();
+ } else if (!forward && ltoreq(curwin->w_cursor, VIsual)) {
+ inc(&VIsual);
}
-
}
- if (fdo_flags & FDO_SEARCH && KeyTyped)
+ if (fdo_flags & FDO_SEARCH && KeyTyped) {
foldOpenCursor();
+ }
may_start_select('c');
setmouse();
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 34eb2fdf1b..84aeeda2bf 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -7368,16 +7368,24 @@ static void dump_word(slang_T *slang, char_u *word, char_u *pat, int *dir, int d
if ((flags & (WF_BANNED | WF_RARE | WF_REGION)) || keepcap) {
STRCPY(badword, p);
STRCAT(badword, "/");
- if (keepcap)
+ if (keepcap) {
STRCAT(badword, "=");
- if (flags & WF_BANNED)
+ }
+ if (flags & WF_BANNED) {
STRCAT(badword, "!");
- else if (flags & WF_RARE)
+ } else if (flags & WF_RARE) {
STRCAT(badword, "?");
- if (flags & WF_REGION)
- for (i = 0; i < 7; ++i)
- if (flags & (0x10000 << i))
- sprintf((char *)badword + STRLEN(badword), "%d", i + 1);
+ }
+ if (flags & WF_REGION) {
+ for (i = 0; i < 7; i++) {
+ if (flags & (0x10000 << i)) {
+ const size_t badword_len = STRLEN(badword);
+ snprintf((char *)badword + badword_len,
+ sizeof(badword) - badword_len,
+ "%d", i + 1);
+ }
+ }
+ }
p = badword;
}
diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c
index f5d5d408a1..dab9a2aacd 100644
--- a/src/nvim/spellfile.c
+++ b/src/nvim/spellfile.c
@@ -1644,7 +1644,7 @@ spell_read_tree (
if (len < 0) {
return SP_TRUNCERROR;
}
- if ((size_t)len >= SIZE_MAX / sizeof(int)) {
+ if ((size_t)len >= SIZE_MAX / sizeof(int)) { // -V547
// Invalid length, multiply with sizeof(int) would overflow.
return SP_FORMERROR;
}
@@ -1949,7 +1949,6 @@ static void spell_print_tree(wordnode_T *root)
static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
{
FILE *fd;
- afffile_T *aff;
char_u rline[MAXLINELEN];
char_u *line;
char_u *pc = NULL;
@@ -2006,11 +2005,7 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
do_mapline = GA_EMPTY(&spin->si_map);
// Allocate and init the afffile_T structure.
- aff = (afffile_T *)getroom(spin, sizeof(afffile_T), true);
- if (aff == NULL) {
- fclose(fd);
- return NULL;
- }
+ afffile_T *aff = getroom(spin, sizeof(*aff), true);
hash_init(&aff->af_pref);
hash_init(&aff->af_suff);
hash_init(&aff->af_comp);
@@ -2098,20 +2093,18 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
smsg(_("FLAG after using flags in %s line %d: %s"),
fname, lnum, items[1]);
} else if (spell_info_item(items[0]) && itemcnt > 1) {
- p = (char_u *)getroom(spin,
- (spin->si_info == NULL ? 0 : STRLEN(spin->si_info))
- + STRLEN(items[0])
- + STRLEN(items[1]) + 3, false);
- if (p != NULL) {
- if (spin->si_info != NULL) {
- STRCPY(p, spin->si_info);
- STRCAT(p, "\n");
- }
- STRCAT(p, items[0]);
- STRCAT(p, " ");
- STRCAT(p, items[1]);
- spin->si_info = p;
+ p = getroom(spin,
+ (spin->si_info == NULL ? 0 : STRLEN(spin->si_info))
+ + STRLEN(items[0])
+ + STRLEN(items[1]) + 3, false);
+ if (spin->si_info != NULL) {
+ STRCPY(p, spin->si_info);
+ STRCAT(p, "\n");
}
+ STRCAT(p, items[0]);
+ STRCAT(p, " ");
+ STRCAT(p, items[1]);
+ spin->si_info = p;
} else if (is_aff_rule(items, itemcnt, "MIDWORD", 2)
&& midword == NULL) {
midword = getroom_save(spin, items[1]);
@@ -2291,14 +2284,12 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
fname, lnum, items[1]);
} else {
// New affix letter.
- cur_aff = (affheader_T *)getroom(spin,
- sizeof(affheader_T), true);
- if (cur_aff == NULL)
- break;
+ cur_aff = getroom(spin, sizeof(*cur_aff), true);
cur_aff->ah_flag = affitem2flag(aff->af_flagtype, items[1],
- fname, lnum);
- if (cur_aff->ah_flag == 0 || STRLEN(items[1]) >= AH_KEY_LEN)
+ fname, lnum);
+ if (cur_aff->ah_flag == 0 || STRLEN(items[1]) >= AH_KEY_LEN) {
break;
+ }
if (cur_aff->ah_flag == aff->af_bad
|| cur_aff->ah_flag == aff->af_rare
|| cur_aff->ah_flag == aff->af_keepcase
@@ -2306,11 +2297,12 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
|| cur_aff->ah_flag == aff->af_circumfix
|| cur_aff->ah_flag == aff->af_nosuggest
|| cur_aff->ah_flag == aff->af_needcomp
- || cur_aff->ah_flag == aff->af_comproot)
+ || cur_aff->ah_flag == aff->af_comproot) {
smsg(_("Affix also used for "
"BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST"
"in %s line %d: %s"),
- fname, lnum, items[1]);
+ fname, lnum, items[1]);
+ }
STRCPY(cur_aff->ah_key, items[1]);
hash_add(tp, cur_aff->ah_key);
@@ -2372,11 +2364,8 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
smsg(_(e_afftrailing), fname, lnum, items[lasti]);
// New item for an affix letter.
- --aff_todo;
- aff_entry = (affentry_T *)getroom(spin,
- sizeof(affentry_T), true);
- if (aff_entry == NULL)
- break;
+ aff_todo--;
+ aff_entry = getroom(spin, sizeof(*aff_entry), true);
if (STRCMP(items[2], "0") != 0)
aff_entry->ae_chop = getroom_save(spin, items[2]);
@@ -2848,12 +2837,10 @@ static void process_compflags(spellinfo_T *spin, afffile_T *aff, char_u *compfla
// the existing ID. Otherwise add a new entry.
STRLCPY(key, prevp, p - prevp + 1);
hi = hash_find(&aff->af_comp, key);
- if (!HASHITEM_EMPTY(hi))
+ if (!HASHITEM_EMPTY(hi)) {
id = HI2CI(hi)->ci_newID;
- else {
- ci = (compitem_T *)getroom(spin, sizeof(compitem_T), true);
- if (ci == NULL)
- break;
+ } else {
+ ci = getroom(spin, sizeof(compitem_T), true);
STRCPY(ci->ci_key, key);
ci->ci_flag = flag;
// Avoid using a flag ID that has a special meaning in a
@@ -3737,12 +3724,8 @@ static void *getroom(spellinfo_T *spin, size_t len, bool align)
// Returns NULL when out of memory.
static char_u *getroom_save(spellinfo_T *spin, char_u *s)
{
- char_u *sc;
-
- sc = (char_u *)getroom(spin, STRLEN(s) + 1, false);
- if (sc != NULL)
- STRCPY(sc, s);
- return sc;
+ const size_t s_size = STRLEN(s) + 1;
+ return memcpy(getroom(spin, s_size, false), s, s_size);
}
@@ -3761,6 +3744,7 @@ static void free_blocks(sblock_T *bl)
// Allocate the root of a word tree.
// Returns NULL when out of memory.
static wordnode_T *wordtree_alloc(spellinfo_T *spin)
+ FUNC_ATTR_NONNULL_RET
{
return (wordnode_T *)getroom(spin, sizeof(wordnode_T), true);
}
@@ -4794,8 +4778,6 @@ static int sug_filltree(spellinfo_T *spin, slang_T *slang)
// We use si_foldroot for the soundfolded trie.
spin->si_foldroot = wordtree_alloc(spin);
- if (spin->si_foldroot == NULL)
- return FAIL;
// Let tree_add_word() know we're adding to the soundfolded tree
spin->si_sugtree = true;
@@ -5183,12 +5165,6 @@ mkspell (
spin.si_foldroot = wordtree_alloc(&spin);
spin.si_keeproot = wordtree_alloc(&spin);
spin.si_prefroot = wordtree_alloc(&spin);
- if (spin.si_foldroot == NULL
- || spin.si_keeproot == NULL
- || spin.si_prefroot == NULL) {
- free_blocks(spin.si_blocks);
- goto theend;
- }
// When not producing a .add.spl file clear the character table when
// we encounter one in the .aff file. This means we dump the current
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index e3f6a8cbf6..b3a0e4816b 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -1145,8 +1145,8 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap,
f, uarg);
break;
}
- assert(str_arg_l < sizeof(tmp));
}
+ assert(str_arg_l < sizeof(tmp));
// include the optional minus sign and possible "0x" in the region
// before the zero padding insertion point
@@ -1376,16 +1376,14 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap,
}
// insert zero padding as requested by precision or min field width
- if (number_of_zeros_to_pad > 0) {
- size_t zn = number_of_zeros_to_pad;
- if (str_avail) {
- size_t avail = str_m - str_l;
- memset(str + str_l, '0', MIN(zn, avail));
- str_avail = zn < avail;
- }
- assert(zn <= SIZE_MAX - str_l);
- str_l += zn;
+ size_t zn = number_of_zeros_to_pad;
+ if (str_avail) {
+ size_t avail = str_m - str_l;
+ memset(str + str_l, '0', MIN(zn, avail));
+ str_avail = zn < avail;
}
+ assert(zn <= SIZE_MAX - str_l);
+ str_l += zn;
}
// insert formatted string
diff --git a/src/nvim/strings.h b/src/nvim/strings.h
index 59b8701a3f..f2876c6307 100644
--- a/src/nvim/strings.h
+++ b/src/nvim/strings.h
@@ -3,10 +3,28 @@
#include <stdbool.h>
#include <stdarg.h>
+#include <string.h>
#include "nvim/types.h"
#include "nvim/eval/typval.h"
+/// Append string to string and return pointer to the next byte
+///
+/// Unlike strcat, this one does *not* add NUL byte and returns pointer to the
+/// past of the added string.
+///
+/// @param[out] dst String to append to.
+/// @param[in] src String to append.
+///
+/// @return pointer to the byte just past the appended byte.
+static inline char *strappend(char *const dst, const char *const src)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_NONNULL_RET
+{
+ const size_t src_len = strlen(src);
+ return (char *)memmove(dst, src, src_len) + src_len;
+}
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "strings.h.generated.h"
#endif
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index 2613c09c19..26de519f3c 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -451,9 +451,10 @@ void syntax_start(win_T *wp, linenr_T lnum)
if (INVALID_STATE(&current_state) && syn_block->b_sst_array != NULL) {
/* Find last valid saved state before start_lnum. */
for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next) {
- if (p->sst_lnum > lnum)
+ if (p->sst_lnum > lnum) {
break;
- if (p->sst_lnum <= lnum && p->sst_change_lnum == 0) {
+ }
+ if (p->sst_change_lnum == 0) {
last_valid = p;
if (p->sst_lnum >= lnum - syn_block->b_syn_sync_minlines)
last_min_valid = p;
@@ -2825,9 +2826,10 @@ syn_add_end_off (
if (off > 0) {
while (off-- > 0 && *p != NUL)
mb_ptr_adv(p);
- } else if (off < 0) {
- while (off++ < 0 && base < p)
+ } else {
+ while (off++ < 0 && base < p) {
mb_ptr_back(base, p);
+ }
}
col = (int)(p - base);
}
@@ -2870,11 +2872,13 @@ syn_add_start_off (
base = ml_get_buf(syn_buf, result->lnum, FALSE);
p = base + col;
if (off > 0) {
- while (off-- && *p != NUL)
+ while (off-- && *p != NUL) {
mb_ptr_adv(p);
- } else if (off < 0) {
- while (off++ && base < p)
+ }
+ } else {
+ while (off++ && base < p) {
mb_ptr_back(base, p);
+ }
}
col = (int)(p - base);
}
@@ -4549,20 +4553,21 @@ syn_cmd_region (
++key_end;
xfree(key);
key = vim_strnsave_up(rest, (int)(key_end - rest));
- if (STRCMP(key, "MATCHGROUP") == 0)
+ if (STRCMP(key, "MATCHGROUP") == 0) {
item = ITEM_MATCHGROUP;
- else if (STRCMP(key, "START") == 0)
+ } else if (STRCMP(key, "START") == 0) {
item = ITEM_START;
- else if (STRCMP(key, "END") == 0)
+ } else if (STRCMP(key, "END") == 0) {
item = ITEM_END;
- else if (STRCMP(key, "SKIP") == 0) {
- if (pat_ptrs[ITEM_SKIP] != NULL) { /* one skip pattern allowed */
- illegal = TRUE;
+ } else if (STRCMP(key, "SKIP") == 0) {
+ if (pat_ptrs[ITEM_SKIP] != NULL) { // One skip pattern allowed.
+ illegal = true;
break;
}
item = ITEM_SKIP;
- } else
+ } else {
break;
+ }
rest = skipwhite(key_end);
if (*rest != '=') {
rest = NULL;
@@ -4598,21 +4603,23 @@ syn_cmd_region (
pat_ptrs[item] = ppp;
ppp->pp_synp = xcalloc(1, sizeof(synpat_T));
- /*
- * Get the syntax pattern and the following offset(s).
- */
- /* Enable the appropriate \z specials. */
- if (item == ITEM_START)
+ // Get the syntax pattern and the following offset(s).
+
+ // Enable the appropriate \z specials.
+ if (item == ITEM_START) {
reg_do_extmatch = REX_SET;
- else if (item == ITEM_SKIP || item == ITEM_END)
+ } else {
+ assert(item == ITEM_SKIP || item == ITEM_END);
reg_do_extmatch = REX_USE;
+ }
rest = get_syn_pattern(rest, ppp->pp_synp);
reg_do_extmatch = 0;
if (item == ITEM_END && vim_regcomp_had_eol()
- && !(syn_opt_arg.flags & HL_EXCLUDENL))
+ && !(syn_opt_arg.flags & HL_EXCLUDENL)) {
ppp->pp_synp->sp_flags |= HL_HAS_EOL;
+ }
ppp->pp_matchgroup_id = matchgroup_id;
- ++pat_count;
+ pat_count++;
}
}
xfree(key);
@@ -5321,18 +5328,19 @@ get_id_list (
for (int i = highlight_ga.ga_len; --i >= 0; ) {
if (vim_regexec(&regmatch, HL_TABLE()[i].sg_name, (colnr_T)0)) {
if (round == 2) {
- /* Got more items than expected; can happen
- * when adding items that match:
- * "contains=a.*b,axb".
- * Go back to first round */
+ // Got more items than expected; can happen
+ // when adding items that match:
+ // "contains=a.*b,axb".
+ // Go back to first round.
if (count >= total_count) {
xfree(retval);
round = 1;
- } else
- retval[count] = i + 1;
+ } else {
+ retval[count] = i + 1; // -V522
+ }
}
- ++count;
- id = -1; /* remember that we found one */
+ count++;
+ id = -1; // Remember that we found one.
}
}
vim_regfree(regmatch.regprog);
@@ -5346,12 +5354,13 @@ get_id_list (
}
if (id > 0) {
if (round == 2) {
- /* Got more items than expected, go back to first round */
+ // Got more items than expected, go back to first round.
if (count >= total_count) {
xfree(retval);
round = 1;
- } else
+ } else {
retval[count] = id;
+ }
}
++count;
}
@@ -5721,13 +5730,9 @@ int syn_get_id(
{
// When the position is not after the current position and in the same
// line of the same buffer, need to restart parsing.
- if (wp->w_buffer != syn_buf
- || lnum != current_lnum
- || col < current_col) {
+ if (wp->w_buffer != syn_buf || lnum != current_lnum || col < current_col) {
syntax_start(wp, lnum);
- } else if (wp->w_buffer == syn_buf
- && lnum == current_lnum
- && col > current_col) {
+ } else if (col > current_col) {
// next_match may not be correct when moving around, e.g. with the
// "skip" expression in searchpair()
next_match_idx = -1;
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 72a25b0b59..65957626cb 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -605,8 +605,7 @@ static void cursor_goto(UI *ui, int row, int col)
int n = col - grid->col;
if (n <= (row == grid->row ? 4 : 2)
&& cheap_to_print(ui, grid->row, grid->col, n)) {
- UGRID_FOREACH_CELL(grid, grid->row, grid->row,
- grid->col, col - 1, {
+ UGRID_FOREACH_CELL(grid, grid->row, grid->row, grid->col, col - 1, {
print_cell(ui, cell);
});
}
@@ -1771,7 +1770,8 @@ static void flush_buf(UI *ui)
bufp++;
}
- if (!data->busy && data->is_invisible) {
+ if (!data->busy) {
+ assert(data->is_invisible);
// not busy and the cursor is invisible. Write a "cursor normal" command
// after writing the buffer.
bufp->base = data->norm;
diff --git a/src/nvim/ugrid.h b/src/nvim/ugrid.h
index 60c9068eb1..035074846e 100644
--- a/src/nvim/ugrid.h
+++ b/src/nvim/ugrid.h
@@ -23,6 +23,8 @@ struct ugrid {
UCell **cells;
};
+// -V:UGRID_FOREACH_CELL:625
+
#define UGRID_FOREACH_CELL(grid, top, bot, left, right, code) \
do { \
for (int row = top; row <= bot; row++) { \
diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c
index 56e0c0c454..a8bbeea035 100644
--- a/src/nvim/ui_bridge.c
+++ b/src/nvim/ui_bridge.c
@@ -116,7 +116,7 @@ static void ui_bridge_stop(UI *b)
uv_mutex_lock(&bridge->mutex);
stopped = bridge->stopped;
uv_mutex_unlock(&bridge->mutex);
- if (stopped) {
+ if (stopped) { // -V547
break;
}
loop_poll_events(&main_loop, 10); // Process one event.
diff --git a/src/nvim/undo.c b/src/nvim/undo.c
index 35857510fc..e1ae4b4cc0 100644
--- a/src/nvim/undo.c
+++ b/src/nvim/undo.c
@@ -972,7 +972,7 @@ static u_entry_T *unserialize_uep(bufinfo_T * bi, bool *error,
char_u **array = NULL;
if (uep->ue_size > 0) {
- if ((size_t)uep->ue_size < SIZE_MAX / sizeof(char_u *)) {
+ if ((size_t)uep->ue_size < SIZE_MAX / sizeof(char_u *)) { // -V547
array = xmalloc(sizeof(char_u *) * (size_t)uep->ue_size);
memset(array, 0, sizeof(char_u *) * (size_t)uep->ue_size);
}
@@ -1404,7 +1404,7 @@ void u_read_undo(char *name, char_u *hash, char_u *orig_name)
// sequence numbers of the headers.
// When there are no headers uhp_table is NULL.
if (num_head > 0) {
- if ((size_t)num_head < SIZE_MAX / sizeof(*uhp_table)) {
+ if ((size_t)num_head < SIZE_MAX / sizeof(*uhp_table)) { // -V547
uhp_table = xmalloc((size_t)num_head * sizeof(*uhp_table));
}
}
diff --git a/src/nvim/viml/parser/expressions.c b/src/nvim/viml/parser/expressions.c
index ee59dc8c96..1a7e55c11e 100644
--- a/src/nvim/viml/parser/expressions.c
+++ b/src/nvim/viml/parser/expressions.c
@@ -2416,11 +2416,6 @@ viml_pexpr_parse_valid_colon:
cur_token,
_("E15: Expected value, got closing bracket: %.*s"));
}
- } else {
- if (!kv_size(ast_stack)) {
- new_top_node_p = top_node_p;
- goto viml_pexpr_parse_bracket_closing_error;
- }
}
do {
new_top_node_p = kv_pop(ast_stack);
@@ -2535,11 +2530,6 @@ viml_pexpr_parse_bracket_closing_error:
cur_token,
_("E15: Expected value, got closing figure brace: %.*s"));
}
- } else {
- if (!kv_size(ast_stack)) {
- new_top_node_p = top_node_p;
- goto viml_pexpr_parse_figure_brace_closing_error;
- }
}
do {
new_top_node_p = kv_pop(ast_stack);
diff --git a/src/nvim/window.c b/src/nvim/window.c
index b4ef901d94..82fffe305c 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -4466,8 +4466,7 @@ static void frame_setwidth(frame_T *curfrp, int width)
if (width <= room)
break;
if (run == 2 || curfrp->fr_height >= ROWS_AVAIL) {
- if (width > room)
- width = room;
+ width = room;
break;
}
frame_setwidth(curfrp->fr_parent, width
@@ -4807,7 +4806,7 @@ void win_new_height(win_T *wp, int height)
// call win_new_height() recursively.
validate_cursor();
}
- if (wp->w_height != prev_height) {
+ if (wp->w_height != prev_height) { // -V547
return; // Recursive call already changed the size, bail out.
}
if (wp->w_wrow != wp->w_prev_fraction_row) {
diff --git a/test/functional/eval/sort_spec.lua b/test/functional/eval/sort_spec.lua
index 4e5a0afba4..82557575ce 100644
--- a/test/functional/eval/sort_spec.lua
+++ b/test/functional/eval/sort_spec.lua
@@ -8,6 +8,7 @@ local meths = helpers.meths
local funcs = helpers.funcs
local command = helpers.command
local exc_exec = helpers.exc_exec
+local redir_exec = helpers.redir_exec
before_each(clear)
@@ -38,4 +39,18 @@ describe('sort()', function()
eq('[-1.0e-4, function(\'tr\'), v:true, v:false, v:null, [], {\'a\': 42}, \'check\', 1.0e-4]',
eval('string(g:list)'))
end)
+
+ it('can yield E702 and stop sorting after that', function()
+ command([[
+ function Cmp(a, b)
+ if type(a:a) == type([]) || type(a:b) == type([])
+ return []
+ endif
+ return (a:a > a:b) - (a:a < a:b)
+ endfunction
+ ]])
+ eq('\nE745: Using a List as a Number\nE702: Sort compare function failed',
+ redir_exec('let sl = sort([1, 0, [], 3, 2], "Cmp")'))
+ eq({1, 0, {}, 3, 2}, meths.get_var('sl'))
+ end)
end)
diff --git a/test/functional/eval/uniq_spec.lua b/test/functional/eval/uniq_spec.lua
new file mode 100644
index 0000000000..0e7a013e32
--- /dev/null
+++ b/test/functional/eval/uniq_spec.lua
@@ -0,0 +1,31 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local eq = helpers.eq
+local clear = helpers.clear
+local meths = helpers.meths
+local command = helpers.command
+local exc_exec = helpers.exc_exec
+local redir_exec = helpers.redir_exec
+
+before_each(clear)
+
+describe('uniq()', function()
+ it('errors out when processing special values', function()
+ eq('Vim(call):E907: Using a special value as a Float',
+ exc_exec('call uniq([v:true, v:false], "f")'))
+ end)
+
+ it('can yield E882 and stop filtering after that', function()
+ command([[
+ function Cmp(a, b)
+ if type(a:a) == type([]) || type(a:b) == type([])
+ return []
+ endif
+ return (a:a > a:b) - (a:a < a:b)
+ endfunction
+ ]])
+ eq('\nE745: Using a List as a Number\nE882: Uniq compare function failed',
+ redir_exec('let fl = uniq([0, 0, [], 1, 1], "Cmp")'))
+ eq({0, {}, 1, 1}, meths.get_var('fl'))
+ end)
+end)