Merge #8218 'Fix errors reported by PVS'

closes #4983
This commit is contained in:
Justin M. Keyes 2018-04-27 09:25:02 +02:00 committed by GitHub
commit 53f11dcfc7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 1045 additions and 1016 deletions

View File

@ -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 = "";

View File

@ -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

View File

@ -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;
}

View File

@ -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"),

View File

@ -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" */
// 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);
#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;
#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
*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);
} else {
STRLCPY(buf + off, "...", SPACE_FOR_ARGNR - off + 1);
// Avoid "c:/name" to be reduced to "c".
if (isalpha((uint8_t)buf_p) && *(buf_p + 1) == ':') {
buf_p += 2;
}
STRCAT(buf, ")");
#endif
// 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 ((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 {
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);
}
*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) {

View File

@ -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.
///
/// @return translated string
char_u *transstr(char_u *s) FUNC_ATTR_NONNULL_RET
/// @param[in] s String to check.
///
/// @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];
const char *p = s;
size_t len = 0;
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(pcc[0])) {
len += l;
} else {
for (size_t i = 0; i < ARRAY_SIZE(pcc); i++) {
char hexbuf[11];
len += transchar_hex(hexbuf, pcc[i]);
}
}
p += l;
} else {
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);
}
}
return len;
}
/// 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(pcc[0])) {
memmove(buf_p, p, l);
buf_p += l;
} else {
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 {
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);
}
/// 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.
size_t len = 0;
p = s;
while (*p != NUL) {
if ((l = (size_t)(*mb_ptr2len)(p)) > 1) {
c = (*mb_ptr2char)(p);
p += l;
if (vim_isprintc(c)) {
len += l;
} else {
transchar_hex(hexbuf, c);
len += STRLEN(hexbuf);
}
} else {
l = (size_t)byte2cells(*p++);
if (l > 0) {
len += l;
} else {
// illegal byte sequence
len += 4;
}
}
}
res = xmallocz(len);
*res = NUL;
p = s;
while (*p != NUL) {
if ((l = (size_t)(*mb_ptr2len)(p)) > 1) {
c = (*mb_ptr2char)(p);
if (vim_isprintc(c)) {
// append printable multi-byte char
STRNCAT(res, p, l);
} else {
transchar_hex(res + STRLEN(res), c);
}
p += l;
} else {
STRCAT(res, transchar_byte(*p++));
}
}
return res;
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);
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_u)(nr2hex((unsigned)c >> 4));
buf[++i] = (char_u)(nr2hex((unsigned)c));
buf[++i] = '>';
buf[++i] = NUL;
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;
}

View File

@ -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);

View File

@ -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

View File

@ -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) {

View File

@ -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,

View File

@ -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: {

View File

@ -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

View File

@ -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, {

View File

@ -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 { \

View File

@ -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.

View File

@ -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;
}
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++];
}
/* 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)
#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;
}
}

View File

@ -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;
}

View File

@ -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 = '.';
}
}
}
}

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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>

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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);
}

View File

@ -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

View File

@ -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 */

View File

@ -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
{

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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 (--dstlen > 0) {
*dst_p++ = '~';
}
/*
* If it's just the home directory, add "/".
*/
if (!vim_ispathsep(src[0]) && --dstlen > 0)
*dst++ = '/';
// 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.

View File

@ -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) {

View File

@ -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))) {

View File

@ -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) {

View File

@ -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

View File

@ -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 =

View File

@ -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;

View File

@ -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));
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]));
}
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));
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]));
}
/*

View File

@ -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();

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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++) { \

View File

@ -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.

View File

@ -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));
}
}

View File

@ -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);

View File

@ -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) {

View File

@ -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)

View File

@ -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)