commit
53f11dcfc7
|
@ -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 = "";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, {
|
||||
|
|
|
@ -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 { \
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 = '.';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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, ®type, 1);
|
||||
tv_list_append_string(args, ®type, 1); // -V614
|
||||
tv_list_append_string(args, ((char[]) { (char)name }), 1);
|
||||
|
||||
(void)eval_call_provider("clipboard", "set", args);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(®match, name, 0))
|
||||
|| ((flags & EW_NOTWILD)
|
||||
&& fnamencmp(path + (s - buf), name, e - s) == 0))) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(®match, 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 =
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -451,9 +451,10 @@ void syntax_start(win_T *wp, linenr_T lnum)
|
|||
if (INVALID_STATE(¤t_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(®match, 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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++) { \
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
Loading…
Reference in New Issue