diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | config/CMakeLists.txt | 1 | ||||
-rw-r--r-- | config/config.h.in | 1 | ||||
-rw-r--r-- | runtime/doc/windows.txt | 59 | ||||
-rwxr-xr-x | scripts/vim-patch.sh | 123 | ||||
-rw-r--r-- | src/nvim/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/nvim/ex_cmds.lua | 34 | ||||
-rw-r--r-- | src/nvim/ex_cmds_defs.h | 2 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 66 | ||||
-rw-r--r-- | src/nvim/getchar.c | 22 | ||||
-rw-r--r-- | src/nvim/globals.h | 3 | ||||
-rw-r--r-- | src/nvim/misc1.c | 15 | ||||
-rw-r--r-- | src/nvim/misc2.c | 47 | ||||
-rw-r--r-- | src/nvim/ops.c | 8 | ||||
-rw-r--r-- | src/nvim/option.c | 1 | ||||
-rw-r--r-- | src/nvim/os/shell.c | 1 | ||||
-rw-r--r-- | src/nvim/screen.c | 7 | ||||
-rw-r--r-- | src/nvim/search.c | 7 | ||||
-rw-r--r-- | src/nvim/spell.c | 264 | ||||
-rw-r--r-- | src/nvim/testdir/test63.in | 6 | ||||
-rw-r--r-- | src/nvim/undo.c | 109 | ||||
-rw-r--r-- | src/nvim/version.c | 20 | ||||
-rw-r--r-- | test/functional/legacy/mapping_spec.lua | 26 |
23 files changed, 446 insertions, 380 deletions
diff --git a/.gitignore b/.gitignore index 5332ef5c76..3ad1a352eb 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,9 @@ /src/nvim/po/vim.pot /src/nvim/po/*.ck +# Files generated by scripts/vim-patch.sh +/.vim-src/ + # Files generated by the tests /src/nvim/testdir/mbyte.vim /src/nvim/testdir/mzscheme.vim diff --git a/config/CMakeLists.txt b/config/CMakeLists.txt index 0f5dd7d984..aab4b5c23d 100644 --- a/config/CMakeLists.txt +++ b/config/CMakeLists.txt @@ -5,7 +5,6 @@ include(CheckIncludeFiles) check_type_size("int" SIZEOF_INT) check_type_size("long" SIZEOF_LONG) -check_type_size("time_t" SIZEOF_TIME_T) check_type_size("off_t" SIZEOF_OFF_T) check_type_size("void *" SIZEOF_VOID_PTR) diff --git a/config/config.h.in b/config/config.h.in index 79dabc61e4..005eb1ccb0 100644 --- a/config/config.h.in +++ b/config/config.h.in @@ -11,7 +11,6 @@ #define SIZEOF_INT @SIZEOF_INT@ #define SIZEOF_LONG @SIZEOF_LONG@ -#define SIZEOF_TIME_T @SIZEOF_TIME_T@ #define SIZEOF_OFF_T @SIZEOF_OFF_T@ #if @SIZEOF_VOID_PTR@ == 8 diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt index 4ba28a3c08..00fe956dd4 100644 --- a/runtime/doc/windows.txt +++ b/runtime/doc/windows.txt @@ -1042,36 +1042,41 @@ list of buffers. |unlisted-buffer| a number). Insert a backslash before a space in a buffer name. -:[N]b[uffer][!] [N] *:b* *:bu* *:buf* *:buffer* *E86* +:[N]b[uffer][!] [+cmd] [N] *:b* *:bu* *:buf* *:buffer* *E86* Edit buffer [N] from the buffer list. If [N] is not given, the current buffer remains being edited. See |:buffer-!| for [!]. This will also edit a buffer that is not in the buffer list, without setting the 'buflisted' flag. + Also see ||+cmd|. -:[N]b[uffer][!] {bufname} +:[N]b[uffer][!] [+cmd] {bufname} Edit buffer for {bufname} from the buffer list. See |:buffer-!| for [!]. This will also edit a buffer that is not in the buffer list, without setting the 'buflisted' flag. + Also see ||+cmd|. -:[N]sb[uffer] [N] *:sb* *:sbuffer* +:[N]sb[uffer] [+cmd] [N] *:sb* *:sbuffer* Split window and edit buffer [N] from the buffer list. If [N] is not given, the current buffer is edited. Respects the "useopen" setting of 'switchbuf' when splitting. This will also edit a buffer that is not in the buffer list, without setting the 'buflisted' flag. + Also see ||+cmd|. -:[N]sb[uffer] {bufname} +:[N]sb[uffer] [+cmd] {bufname} Split window and edit buffer for {bufname} from the buffer list. This will also edit a buffer that is not in the buffer list, without setting the 'buflisted' flag. Note: If what you want to do is split the buffer, make a copy under another name, you can do it this way: > :w foobar | sp # +< Also see ||+cmd|. -:[N]bn[ext][!] [N] *:bn* *:bnext* *E87* +:[N]bn[ext][!] [+cmd] [N] *:bn* *:bnext* *E87* Go to [N]th next buffer in buffer list. [N] defaults to one. Wraps around the end of the buffer list. See |:buffer-!| for [!]. + Also see ||+cmd|. If you are in a help buffer, this takes you to the next help buffer (if there is one). Similarly, if you are in a normal (non-help) buffer, this takes you to the next normal buffer. @@ -1079,55 +1084,61 @@ list of buffers. |unlisted-buffer| the way when you're browsing code/text buffers. The next three commands also work like this. + *:sbn* *:sbnext* -:[N]sbn[ext] [N] +:[N]sbn[ext] [+cmd] [N] Split window and go to [N]th next buffer in buffer list. Wraps around the end of the buffer list. Uses 'switchbuf' + Also see ||+cmd|. -:[N]bN[ext][!] [N] *:bN* *:bNext* *:bp* *:bprevious* *E88* -:[N]bp[revious][!] [N] +:[N]bN[ext][!] [+cmd] [N] *:bN* *:bNext* *:bp* *:bprevious* *E88* +:[N]bp[revious][!] [+cmd] [N] Go to [N]th previous buffer in buffer list. [N] defaults to one. Wraps around the start of the buffer list. See |:buffer-!| for [!] and 'switchbuf'. + Also see ||+cmd|. -:[N]sbN[ext] [N] *:sbN* *:sbNext* *:sbp* *:sbprevious* -:[N]sbp[revious] [N] +:[N]sbN[ext] [+cmd] [N] *:sbN* *:sbNext* *:sbp* *:sbprevious* +:[N]sbp[revious] [+cmd] [N] Split window and go to [N]th previous buffer in buffer list. Wraps around the start of the buffer list. Uses 'switchbuf'. + Also see ||+cmd|. - *:br* *:brewind* -:br[ewind][!] Go to first buffer in buffer list. If the buffer list is +:br[ewind][!] [+cmd] *:br* *:brewind* + Go to first buffer in buffer list. If the buffer list is empty, go to the first unlisted buffer. See |:buffer-!| for [!]. - *:bf* *:bfirst* -:bf[irst] Same as ":brewind". +:bf[irst] [+cmd] *:bf* *:bfirst* + Same as |:brewind|. + Also see |+cmd|. - *:sbr* *:sbrewind* -:sbr[ewind] Split window and go to first buffer in buffer list. If the +:sbr[ewind] [+cmd] *:sbr* *:sbrewind* + Split window and go to first buffer in buffer list. If the buffer list is empty, go to the first unlisted buffer. Respects the 'switchbuf' option. + Also see |+cmd|. - *:sbf* *:sbfirst* -:sbf[irst] Same as ":sbrewind". +:sbf[irst] [+cmd] *:sbf* *:sbfirst* + Same as ":sbrewind". - *:bl* *:blast* -:bl[ast][!] Go to last buffer in buffer list. If the buffer list is +:bl[ast][!] [+cmd] *:bl* *:blast* + Go to last buffer in buffer list. If the buffer list is empty, go to the last unlisted buffer. See |:buffer-!| for [!]. - *:sbl* *:sblast* -:sbl[ast] Split window and go to last buffer in buffer list. If the +:sbl[ast] [+cmd] *:sbl* *:sblast* + Split window and go to last buffer in buffer list. If the buffer list is empty, go to the last unlisted buffer. Respects 'switchbuf' option. -:[N]bm[odified][!] [N] *:bm* *:bmodified* *E84* +:[N]bm[odified][!] [+cmd] [N] *:bm* *:bmodified* *E84* Go to [N]th next modified buffer. Note: this command also finds unlisted buffers. If there is no modified buffer the command fails. -:[N]sbm[odified] [N] *:sbm* *:sbmodified* +:[N]sbm[odified] [+cmd] [N] *:sbm* *:sbmodified* Split window and go to [N]th next modified buffer. Respects 'switchbuf' option. Note: this command also finds buffers not in the buffer list. diff --git a/scripts/vim-patch.sh b/scripts/vim-patch.sh index 6e098dd5eb..f6b4793184 100755 --- a/scripts/vim-patch.sh +++ b/scripts/vim-patch.sh @@ -1,27 +1,26 @@ -#!/bin/bash -e +#!/usr/bin/env bash + +set -e +set -o pipefail NEOVIM_SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -VIM_SOURCE_DIR_DEFAULT=${NEOVIM_SOURCE_DIR}/build/vim +VIM_SOURCE_DIR_DEFAULT=${NEOVIM_SOURCE_DIR}/.vim-src VIM_SOURCE_DIR="${VIM_SOURCE_DIR:-${VIM_SOURCE_DIR_DEFAULT}}" if [[ ${#} != 1 ]]; then >&2 echo "Helper script for porting Vim patches. For more information," >&2 echo "see https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-vim." >&2 echo - >&2 echo "Usage: ${0} vim-version" - >&2 echo "vim-version must be in format '7.4.xxx'." + >&2 echo "Usage: ${0} vim-revision" + >&2 echo "vim-revision can be a version number in format '7.4.xxx'" + >&2 echo "or a Mercurial commit hash." >&2 echo >&2 echo "Set VIM_SOURCE_DIR to change where Vim's sources are stored." >&2 echo "The default is '${VIM_SOURCE_DIR_DEFAULT}'." exit 1 fi -vim_version="${1}" -if [[ ! ${vim_version} =~ [0-9]\.[0-9]\.[0-9][0-9][0-9] ]]; then - >&2 echo "vim-version must be in format '7.4.xxx'." - exit 2 -fi - +echo "Retrieving Vim sources." if [[ ! -d ${VIM_SOURCE_DIR} ]]; then echo "Cloning Vim sources into '${VIM_SOURCE_DIR}'." hg clone https://code.google.com/p/vim ${VIM_SOURCE_DIR} @@ -29,53 +28,93 @@ if [[ ! -d ${VIM_SOURCE_DIR} ]]; then else echo "Updating Vim sources in '${VIM_SOURCE_DIR}'." cd ${VIM_SOURCE_DIR} - hg pull --update || echo 'Could not update Vim sources.' + hg pull --update || echo "✘ Could not update Vim sources." fi -vim_tag="v${vim_version//./-}" -echo "Using Vim tag '${vim_tag}'." +if [[ "${1}" =~ [0-9]\.[0-9]\.[0-9]{3,4} ]]; then + # Interpret parameter as version number. + vim_version="${1}" + vim_commit="v${1//./-}" + strip_commit_line=true +else + # Interpret parameter as commit hash. + vim_version="${1:0:7}" + vim_commit="${1}" + strip_commit_line=false +fi -hg log --rev ${vim_tag} >/dev/null 2>&1 || { - >&2 echo "Couldn't find Vim tag '${vim_tag}'." +hg log --rev ${vim_commit} >/dev/null 2>&1 || { + >&2 echo "✘ Couldn't find Vim revision '${vim_commit}'." exit 3 } - -vim_full="$(hg log --patch --git --verbose --rev ${vim_tag})" -vim_message="$(hg log --template "{desc}" --rev ${vim_tag} \ - | sed -e '1d')" # Remove first line of commit message. -vim_diff="$(hg diff --show-function --git --change ${vim_tag} \ +echo "✔ Found Vim revision '${vim_commit}'." + +# Collect patch details and store into variables. +vim_full="$(hg log --patch --git --verbose --rev ${vim_commit})" +vim_message="$(hg log --template "{desc}" --rev ${vim_commit})" +if [[ "${strip_commit_line}" == "true" ]]; then + # Remove first line of commit message. + vim_message="$(echo "${vim_message}" | sed -e '1d')" +fi +vim_diff="$(hg diff --show-function --git --change ${vim_commit} \ | sed -e 's/\( [ab]\/src\)/\1\/nvim/g')" # Change directory to src/nvim. +neovim_message=" +vim-patch:${vim_version} + +${vim_message} + +https://code.google.com/p/vim/source/detail?r=${vim_commit}" +neovim_pr=" +\`\`\` +${vim_message} +\`\`\` +https://code.google.com/p/vim/source/detail?r=${vim_commit} +Original patch: + +\`\`\`diff +${vim_diff} +\`\`\`" neovim_branch="vim-${vim_version}" + echo -echo "Creating Neovim branch '${neovim_branch}'." +echo "Creating Git branch." cd ${NEOVIM_SOURCE_DIR} -git checkout -b "${neovim_branch}" +echo -n "✘ " +# 'git checkout -b' writes to stderr in case of success :-( +# Re-add newline (stripped by echo -n) in error case. +git checkout -b "${neovim_branch}" 2>&1 | xargs echo -n || (echo; false) +echo -n "." # Add trailing dot. +echo -e "\r✔ " # Replace ✘ with ✔ echo -echo "Saving patch to '${NEOVIM_SOURCE_DIR}/${neovim_branch}.patch'." -echo "${vim_diff}" > ${NEOVIM_SOURCE_DIR}/${neovim_branch}.patch - -echo "Saving full commit details to '${NEOVIM_SOURCE_DIR}/${neovim_branch}.commit'." -echo "${vim_full}" > ${NEOVIM_SOURCE_DIR}/${neovim_branch}.commit +echo "Creating empty commit with correct commit message." +echo -n "✘ " +git commit --allow-empty --file - <<< "${neovim_message}" | xargs echo -n +echo -e "\r✔ " # Replace ✘ with ✔ echo -echo "Creating empty Neovim commit with correct commit message." -neovim_message=" -vim-patch:${vim_version} - -${vim_message} - -https://code.google.com/p/vim/source/detail?r=${vim_tag}" - -git commit --allow-empty --file - <<< "${neovim_message}" +echo "Creating files." +echo "${vim_diff}" > ${NEOVIM_SOURCE_DIR}/${neovim_branch}.diff +echo "✔ Saved patch to '${NEOVIM_SOURCE_DIR}/${neovim_branch}.diff'." +echo "${vim_full}" > ${NEOVIM_SOURCE_DIR}/${neovim_branch}.patch +echo "✔ Saved full commit details to '${NEOVIM_SOURCE_DIR}/${neovim_branch}.patch'." +echo "${neovim_pr}" > ${NEOVIM_SOURCE_DIR}/${neovim_branch}.pr +echo "✔ Saved suggested PR description to '${NEOVIM_SOURCE_DIR}/${neovim_branch}.pr'." +echo "You can use 'git clean' to remove these files when you're done." echo -echo "Proceed to port the patch and stage your changes ('git add ...')." -echo "Then use 'git commit --amend' to commit." -echo "Push your changes with 'git push origin ${neovim_branch}' and create a" -echo "pull request called '[RFC] vim-patch:${vim_version}'." +echo "Instructions:" +echo +echo " Proceed to port the patch." +echo " You might want to try 'patch -p1 < ${neovim_branch}.diff' first." +echo +echo " Stage your changes ('git add ...') and use 'git commit --amend' to commit." +echo +echo " Push your changes with 'git push origin ${neovim_branch}' and create a" +echo " pull request called '[RFC] vim-patch:${vim_version}'. You might want " +echo " to use the text in '${neovim_branch}.pr' as the description of this pull request." echo -echo "See https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-vim" -echo "for more information." +echo " See https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-vim" +echo " for more information." diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 8c0979026a..c688c3d330 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -87,7 +87,6 @@ set(CONV_SOURCES tag.c term.c ui.c - undo.c version.c window.c) diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index d5d6d39616..c9dd974d11 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -127,12 +127,12 @@ return { }, { command='buffer', - flags=bit.bor(BANG, RANGE, NOTADR, BUFNAME, BUFUNL, COUNT, EXTRA, TRLBAR), + flags=bit.bor(BANG, RANGE, NOTADR, BUFNAME, BUFUNL, COUNT, EXTRA, EDITCMD, TRLBAR), func='ex_buffer', }, { command='bNext', - flags=bit.bor(BANG, RANGE, NOTADR, COUNT, TRLBAR), + flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), func='ex_bprevious', }, { @@ -162,22 +162,22 @@ return { }, { command='bfirst', - flags=bit.bor(BANG, RANGE, NOTADR, TRLBAR), + flags=bit.bor(BANG, RANGE, NOTADR, EDITCMD, TRLBAR), func='ex_brewind', }, { command='blast', - flags=bit.bor(BANG, RANGE, NOTADR, TRLBAR), + flags=bit.bor(BANG, RANGE, NOTADR, EDITCMD, TRLBAR), func='ex_blast', }, { command='bmodified', - flags=bit.bor(BANG, RANGE, NOTADR, COUNT, TRLBAR), + flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), func='ex_bmodified', }, { command='bnext', - flags=bit.bor(BANG, RANGE, NOTADR, COUNT, TRLBAR), + flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), func='ex_bnext', }, { @@ -187,12 +187,12 @@ return { }, { command='bprevious', - flags=bit.bor(BANG, RANGE, NOTADR, COUNT, TRLBAR), + flags=bit.bor(BANG, RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), func='ex_bprevious', }, { command='brewind', - flags=bit.bor(BANG, RANGE, NOTADR, TRLBAR), + flags=bit.bor(BANG, RANGE, NOTADR, EDITCMD, TRLBAR), func='ex_brewind', }, { @@ -1762,47 +1762,47 @@ return { }, { command='sbuffer', - flags=bit.bor(BANG, RANGE, NOTADR, BUFNAME, BUFUNL, COUNT, EXTRA, TRLBAR), + flags=bit.bor(BANG, RANGE, NOTADR, BUFNAME, BUFUNL, COUNT, EXTRA, EDITCMD, TRLBAR), func='ex_buffer', }, { command='sbNext', - flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), + flags=bit.bor(RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), func='ex_bprevious', }, { command='sball', - flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), + flags=bit.bor(RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), func='ex_buffer_all', }, { command='sbfirst', - flags=bit.bor(TRLBAR), + flags=bit.bor(EDITCMD, TRLBAR), func='ex_brewind', }, { command='sblast', - flags=bit.bor(TRLBAR), + flags=bit.bor(EDITCMD, TRLBAR), func='ex_blast', }, { command='sbmodified', - flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), + flags=bit.bor(RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), func='ex_bmodified', }, { command='sbnext', - flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), + flags=bit.bor(RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), func='ex_bnext', }, { command='sbprevious', - flags=bit.bor(RANGE, NOTADR, COUNT, TRLBAR), + flags=bit.bor(RANGE, NOTADR, COUNT, EDITCMD, TRLBAR), func='ex_bprevious', }, { command='sbrewind', - flags=bit.bor(TRLBAR), + flags=bit.bor(EDITCMD, TRLBAR), func='ex_brewind', }, { diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h index abf7cc4587..0e13574321 100644 --- a/src/nvim/ex_cmds_defs.h +++ b/src/nvim/ex_cmds_defs.h @@ -88,8 +88,6 @@ typedef struct cmdname { long_u cmd_argt; ///< Relevant flags from the declared above. } CommandDefinition; -#define USER_CMDIDX(idx) ((int)(idx) < 0) - /// Arguments used for Ex commands. struct exarg { char_u *arg; ///< argument of the command diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index e4a8c2735b..359c4b31d1 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -92,6 +92,9 @@ static garray_T ucmds = {0, 0, sizeof(ucmd_T), 4, NULL}; #define USER_CMD(i) (&((ucmd_T *)(ucmds.ga_data))[i]) #define USER_CMD_GA(gap, i) (&((ucmd_T *)((gap)->ga_data))[i]) +/* Wether a command index indicates a user command. */ +# define IS_USER_CMDIDX(idx) ((int)(idx) < 0) + /* Struct for storing a line inside a while/for loop */ typedef struct { char_u *line; /* command line */ @@ -1489,11 +1492,10 @@ static char_u * do_one_cmd(char_u **cmdlinep, goto doend; } - ni = ( - !USER_CMDIDX(ea.cmdidx) && - (cmdnames[ea.cmdidx].cmd_func == ex_ni + ni = (!IS_USER_CMDIDX(ea.cmdidx) + && (cmdnames[ea.cmdidx].cmd_func == ex_ni #ifdef HAVE_EX_SCRIPT_NI - || cmdnames[ea.cmdidx].cmd_func == ex_script_ni + || cmdnames[ea.cmdidx].cmd_func == ex_script_ni #endif )); @@ -1509,8 +1511,9 @@ static char_u * do_one_cmd(char_u **cmdlinep, /* * 5. parse arguments */ - if (!USER_CMDIDX(ea.cmdidx)) + if (!IS_USER_CMDIDX(ea.cmdidx)) { ea.argt = (long)cmdnames[(int)ea.cmdidx].cmd_argt; + } if (!ea.skip) { #ifdef HAVE_SANDBOX @@ -1527,8 +1530,7 @@ static char_u * do_one_cmd(char_u **cmdlinep, } if (text_locked() && !(ea.argt & CMDWIN) - && !USER_CMDIDX(ea.cmdidx) - ) { + && !IS_USER_CMDIDX(ea.cmdidx)) { /* Command not allowed when editing the command line. */ if (cmdwin_type != 0) errormsg = (char_u *)_(e_cmdwin); @@ -1542,7 +1544,7 @@ static char_u * do_one_cmd(char_u **cmdlinep, if (!(ea.argt & CMDWIN) && ea.cmdidx != CMD_edit && ea.cmdidx != CMD_checktime - && !USER_CMDIDX(ea.cmdidx) + && !IS_USER_CMDIDX(ea.cmdidx) && curbuf_locked()) goto doend; @@ -1708,17 +1710,15 @@ static char_u * do_one_cmd(char_u **cmdlinep, if ( (ea.argt & REGSTR) && *ea.arg != NUL /* Do not allow register = for user commands */ - && (!USER_CMDIDX(ea.cmdidx) || *ea.arg != '=') + && (!IS_USER_CMDIDX(ea.cmdidx) || *ea.arg != '=') && !((ea.argt & COUNT) && VIM_ISDIGIT(*ea.arg))) { /* check these explicitly for a more specific error message */ if (*ea.arg == '*' || *ea.arg == '+') { errormsg = (char_u *)_(e_invalidreg); goto doend; } - if ( - valid_yank_reg(*ea.arg, (ea.cmdidx != CMD_put - && USER_CMDIDX(ea.cmdidx))) - ) { + if (valid_yank_reg(*ea.arg, (ea.cmdidx != CMD_put + && !IS_USER_CMDIDX(ea.cmdidx)))) { ea.regname = *ea.arg++; /* for '=' register: accept the rest of the line as an expression */ if (ea.arg[-1] == '=' && ea.arg[0] != NUL) { @@ -1868,7 +1868,7 @@ static char_u * do_one_cmd(char_u **cmdlinep, * number. Don't do this for a user command. */ if ((ea.argt & BUFNAME) && *ea.arg != NUL && ea.addr_count == 0 - && !USER_CMDIDX(ea.cmdidx) + && !IS_USER_CMDIDX(ea.cmdidx) ) { /* * :bdelete, :bwipeout and :bunload take several arguments, separated @@ -1901,7 +1901,7 @@ static char_u * do_one_cmd(char_u **cmdlinep, ea.cookie = cookie; ea.cstack = cstack; - if (USER_CMDIDX(ea.cmdidx)) { + if (IS_USER_CMDIDX(ea.cmdidx)) { /* * Execute a user-defined command. */ @@ -1949,9 +1949,9 @@ doend: emsg(errormsg); } do_errthrow(cstack, - (ea.cmdidx != CMD_SIZE - && !USER_CMDIDX(ea.cmdidx) - ) ? cmdnames[(int)ea.cmdidx].cmd_name : (char_u *)NULL); + (ea.cmdidx != CMD_SIZE && !IS_USER_CMDIDX(ea.cmdidx)) + ? cmdnames[(int)ea.cmdidx].cmd_name + : (char_u *)NULL); if (verbose_save >= 0) p_verbose = verbose_save; @@ -2464,8 +2464,9 @@ set_one_cmd_context ( /* * 5. parse arguments */ - if (!USER_CMDIDX(ea.cmdidx)) + if (!IS_USER_CMDIDX(ea.cmdidx)) { ea.argt = (long)cmdnames[(int)ea.cmdidx].cmd_argt; + } arg = skipwhite(p); @@ -3958,13 +3959,17 @@ static void ex_bunload(exarg_T *eap) */ static void ex_buffer(exarg_T *eap) { - if (*eap->arg) + if (*eap->arg) { eap->errmsg = e_trailing; - else { - if (eap->addr_count == 0) /* default is current buffer */ + } else { + if (eap->addr_count == 0) { // default is current buffer goto_buffer(eap, DOBUF_CURRENT, FORWARD, 0); - else + } else { goto_buffer(eap, DOBUF_FIRST, FORWARD, (int)eap->line2); + } + if (eap->do_ecmd_cmd != NULL) { + do_cmdline_cmd(eap->do_ecmd_cmd); + } } } @@ -3975,6 +3980,9 @@ static void ex_buffer(exarg_T *eap) static void ex_bmodified(exarg_T *eap) { goto_buffer(eap, DOBUF_MOD, FORWARD, (int)eap->line2); + if (eap->do_ecmd_cmd != NULL) { + do_cmdline_cmd(eap->do_ecmd_cmd); + } } /* @@ -3984,6 +3992,9 @@ static void ex_bmodified(exarg_T *eap) static void ex_bnext(exarg_T *eap) { goto_buffer(eap, DOBUF_CURRENT, FORWARD, (int)eap->line2); + if (eap->do_ecmd_cmd != NULL) { + do_cmdline_cmd(eap->do_ecmd_cmd); + } } /* @@ -3995,6 +4006,9 @@ static void ex_bnext(exarg_T *eap) static void ex_bprevious(exarg_T *eap) { goto_buffer(eap, DOBUF_CURRENT, BACKWARD, (int)eap->line2); + if (eap->do_ecmd_cmd != NULL) { + do_cmdline_cmd(eap->do_ecmd_cmd); + } } /* @@ -4006,6 +4020,9 @@ static void ex_bprevious(exarg_T *eap) static void ex_brewind(exarg_T *eap) { goto_buffer(eap, DOBUF_FIRST, FORWARD, 0); + if (eap->do_ecmd_cmd != NULL) { + do_cmdline_cmd(eap->do_ecmd_cmd); + } } /* @@ -4015,6 +4032,9 @@ static void ex_brewind(exarg_T *eap) static void ex_blast(exarg_T *eap) { goto_buffer(eap, DOBUF_LAST, BACKWARD, 0); + if (eap->do_ecmd_cmd != NULL) { + do_cmdline_cmd(eap->do_ecmd_cmd); + } } int ends_excmd(int c) FUNC_ATTR_CONST diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 882d30388c..d0eebf8fea 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -15,6 +15,7 @@ * mappings and abbreviations */ +#include <assert.h> #include <stdbool.h> #include <string.h> #include <inttypes.h> @@ -3637,11 +3638,26 @@ int check_abbr(int c, char_u *ptr, int col, int mincol) for (; mp; mp->m_next == NULL ? (mp = mp2, mp2 = NULL) : (mp = mp->m_next)) { + int qlen = mp->m_keylen; + char_u *q = mp->m_keys; + int match; + + if (vim_strbyte(mp->m_keys, K_SPECIAL) != NULL) { + /* might have CSI escaped mp->m_keys */ + q = vim_strsave(mp->m_keys); + vim_unescape_csi(q); + qlen = (int)STRLEN(q); + } /* find entries with right mode and keys */ - if ( (mp->m_mode & State) - && mp->m_keylen == len - && !STRNCMP(mp->m_keys, ptr, (size_t)len)) + match = (mp->m_mode & State) + && qlen == len + && !STRNCMP(q, ptr, (size_t)len); + if (q != mp->m_keys) { + free(q); + } + if (match) { break; + } } if (mp != NULL) { /* diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 5f542eec0c..f53a780efe 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -606,9 +606,6 @@ EXTERN int exiting INIT(= FALSE); /* TRUE when planning to exit Vim. Might * still keep on running if there is a changed * buffer. */ -EXTERN int really_exiting INIT(= FALSE); -/* TRUE when we are sure to exit, e.g., after - * a deadly signal */ /* volatile because it is used in signal handler deathtrap(). */ EXTERN volatile int full_screen INIT(= FALSE); /* TRUE when doing full-screen output diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index fc848466c6..4f17f84e11 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -3329,32 +3329,35 @@ void prepare_to_exit(void) */ void preserve_exit(void) { + // 'true' when we are sure to exit, e.g., after a deadly signal + static bool really_exiting = false; + // Prevent repeated calls into this method. if (really_exiting) { exit(2); } - really_exiting = TRUE; + really_exiting = true; prepare_to_exit(); out_str(IObuff); - screen_start(); /* don't know where cursor is now */ + screen_start(); // don't know where cursor is now out_flush(); - ml_close_notmod(); /* close all not-modified buffers */ + ml_close_notmod(); // close all not-modified buffers FOR_ALL_BUFFERS(buf) { if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL) { OUT_STR("Vim: preserving files...\n"); - screen_start(); /* don't know where cursor is now */ + screen_start(); // don't know where cursor is now out_flush(); - ml_sync_all(FALSE, FALSE); /* preserve all swap files */ + ml_sync_all(false, false); // preserve all swap files break; } } - ml_close_all(FALSE); /* close all memfiles, without deleting */ + ml_close_all(false); // close all memfiles, without deleting OUT_STR("Vim: Finished.\n"); diff --git a/src/nvim/misc2.c b/src/nvim/misc2.c index e6531ee1b2..1407dcf04b 100644 --- a/src/nvim/misc2.c +++ b/src/nvim/misc2.c @@ -501,47 +501,22 @@ char *read_string(FILE *fd, size_t cnt) return (char *)str; } -/* - * Write a number to file "fd", MSB first, in "len" bytes. - */ -int put_bytes(FILE *fd, long_u nr, int len) +/// Write a number to file "fd", MSB first, in "len" bytes. +/// @return OK/FAIL. +int put_bytes(FILE *fd, uintmax_t number, unsigned int len) { - int i; - - for (i = len - 1; i >= 0; --i) - if (putc((int)(nr >> (i * 8)), fd) == EOF) + for (unsigned int i = len - 1; i < len; --i) + if (putc((int)(number >> (i * 8)), fd) == EOF) return FAIL; return OK; } - -/* - * Write time_t to file "fd" in 8 bytes. - */ -void put_time(FILE *fd, time_t the_time) +/// Write time_t to file "fd" in 8 bytes. +void put_time(FILE *fd, time_t time_) { - int c; - int i; - time_t wtime = the_time; - - /* time_t can be up to 8 bytes in size, more than long_u, thus we - * can't use put_bytes() here. - * Another problem is that ">>" may do an arithmetic shift that keeps the - * sign. This happens for large values of wtime. A cast to long_u may - * truncate if time_t is 8 bytes. So only use a cast when it is 4 bytes, - * it's safe to assume that long_u is 4 bytes or more and when using 8 - * bytes the top bit won't be set. */ - for (i = 7; i >= 0; --i) { - if (i + 1 > (int)sizeof(time_t)) - /* ">>" doesn't work well when shifting more bits than avail */ - putc(0, fd); - else { -#if defined(SIZEOF_TIME_T) && SIZEOF_TIME_T > 4 - c = (int)(wtime >> (i * 8)); -#else - c = (int)((long_u)wtime >> (i * 8)); -#endif - putc(c, fd); - } + // time_t can be up to 8 bytes in size, more than uintmax_t in 32 bits + // systems, thus we can't use put_bytes() here. + for (unsigned int i = 7; i < 8; --i) { + putc((int)((uint64_t)time_ >> (i * 8)), fd); } } diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 931b877a95..9b33b6732c 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2979,9 +2979,11 @@ do_put ( } if (VIsual_active) lnum++; - } while ( - VIsual_active && lnum <= curbuf->b_visual.vi_end.lnum - ); + } while (VIsual_active && lnum <= curbuf->b_visual.vi_end.lnum); + + if (VIsual_active) { /* reset lnum to the last visual line */ + lnum--; + } curbuf->b_op_end = curwin->w_cursor; /* For "CTRL-O p" in Insert mode, put cursor after last char */ diff --git a/src/nvim/option.c b/src/nvim/option.c index 1bab0da79a..1c07bef3e3 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -3645,6 +3645,7 @@ set_string_option_direct ( idx = findoption(name); if (idx < 0) { /* not found (should not happen) */ EMSG2(_(e_intern2), "set_string_option_direct()"); + EMSG2(_("For option %s"), name); return; } } diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index c450e24284..d0f8442768 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -268,6 +268,7 @@ static int shell(const char *cmd, static void dynamic_buffer_ensure(DynamicBuffer *buf, size_t desired) { if (buf->cap >= desired) { + assert(buf->data); return; } diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 0148979335..324171aca2 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2962,8 +2962,13 @@ win_line ( if (shl->startcol != MAXCOL && v >= (long)shl->startcol && v < (long)shl->endcol) { + int tmp_col = v + MB_PTR2LEN(ptr); + + if (shl->endcol < tmp_col) { + shl->endcol = tmp_col; + } shl->attr_cur = shl->attr; - } else if (v >= (long)shl->endcol && shl->lnum == lnum) { + } else if (v == (long)shl->endcol) { shl->attr_cur = 0; next_search_hl(wp, shl, lnum, (colnr_T)v, cur); diff --git a/src/nvim/search.c b/src/nvim/search.c index ef98944a06..5158e6cd86 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -3294,10 +3294,11 @@ again: if (VIsual_active) { /* If the end is before the start there is no text between tags, select * the char under the cursor. */ - if (lt(end_pos, start_pos)) + if (lt(end_pos, start_pos)) { curwin->w_cursor = start_pos; - else if (*p_sel == 'e') - ++curwin->w_cursor.col; + } else if (*p_sel == 'e') { + inc_cursor(); + } VIsual = start_pos; VIsual_mode = 'v'; redraw_curbuf_later(INVERTED); /* update the inversion */ diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 4759b4efa6..b8713909b8 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -287,6 +287,7 @@ #include <assert.h> #include <errno.h> #include <inttypes.h> +#include <limits.h> #include <stdbool.h> #include <string.h> #include <stdlib.h> @@ -6594,25 +6595,13 @@ static int rep_compare(const void *s1, const void *s2) } // Write the Vim .spl file "fname". -// Return FAIL or OK; +// Return OK/FAIL. static int write_vim_spell(spellinfo_T *spin, char_u *fname) { - FILE *fd; - int regionmask; - int round; - wordnode_T *tree; - int nodecount; - int i; - int l; - garray_T *gap; - fromto_T *ftp; - char_u *p; - int rr; int retval = OK; - size_t fwv = 1; // collect return value of fwrite() to avoid - // warnings from picky compiler + int regionmask; - fd = mch_fopen((char *)fname, "w"); + FILE *fd = mch_fopen((char *)fname, "w"); if (fd == NULL) { EMSG2(_(e_notopen), fname); return FAIL; @@ -6620,7 +6609,7 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) // <HEADER>: <fileID> <versionnr> // <fileID> - fwv &= fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, fd); + size_t fwv = fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, 1, fd); if (fwv != (size_t)1) // Catch first write error, don't try writing more. goto theend; @@ -6633,10 +6622,9 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) if (spin->si_info != NULL) { putc(SN_INFO, fd); // <sectionID> putc(0, fd); // <sectionflags> - - i = (int)STRLEN(spin->si_info); - put_bytes(fd, (long_u)i, 4); // <sectionlen> - fwv &= fwrite(spin->si_info, (size_t)i, (size_t)1, fd); // <infotext> + size_t i = STRLEN(spin->si_info); + put_bytes(fd, i, 4); // <sectionlen> + fwv &= fwrite(spin->si_info, i, 1, fd); // <infotext> } // SN_REGION: <regionname> ... @@ -6644,9 +6632,9 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) if (spin->si_region_count > 1) { putc(SN_REGION, fd); // <sectionID> putc(SNF_REQUIRED, fd); // <sectionflags> - l = spin->si_region_count * 2; - put_bytes(fd, (long_u)l, 4); // <sectionlen> - fwv &= fwrite(spin->si_region_name, (size_t)l, (size_t)1, fd); + size_t l = (size_t)spin->si_region_count * 2; + put_bytes(fd, l, 4); // <sectionlen> + fwv &= fwrite(spin->si_region_name, l, 1, fd); // <regionname> ... regionmask = (1 << spin->si_region_count) - 1; } else @@ -6669,17 +6657,17 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) putc(SNF_REQUIRED, fd); // <sectionflags> // Form the <folchars> string first, we need to know its length. - l = 0; - for (i = 128; i < 256; ++i) { + size_t l = 0; + for (size_t i = 128; i < 256; ++i) { if (has_mbyte) - l += mb_char2bytes(spelltab.st_fold[i], folchars + l); + l += (size_t)mb_char2bytes(spelltab.st_fold[i], folchars + l); else folchars[l++] = spelltab.st_fold[i]; } - put_bytes(fd, (long_u)(1 + 128 + 2 + l), 4); // <sectionlen> + put_bytes(fd, 1 + 128 + 2 + l, 4); // <sectionlen> fputc(128, fd); // <charflagslen> - for (i = 128; i < 256; ++i) { + for (size_t i = 128; i < 256; ++i) { flags = 0; if (spelltab.st_isw[i]) flags |= CF_WORD; @@ -6688,8 +6676,8 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) fputc(flags, fd); // <charflags> } - put_bytes(fd, (long_u)l, 2); // <folcharslen> - fwv &= fwrite(folchars, (size_t)l, (size_t)1, fd); // <folchars> + put_bytes(fd, l, 2); // <folcharslen> + fwv &= fwrite(folchars, l, 1, fd); // <folchars> } // SN_MIDWORD: <midword> @@ -6697,9 +6685,9 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) putc(SN_MIDWORD, fd); // <sectionID> putc(SNF_REQUIRED, fd); // <sectionflags> - i = (int)STRLEN(spin->si_midword); - put_bytes(fd, (long_u)i, 4); // <sectionlen> - fwv &= fwrite(spin->si_midword, (size_t)i, (size_t)1, fd); + size_t i = STRLEN(spin->si_midword); + put_bytes(fd, i, 4); // <sectionlen> + fwv &= fwrite(spin->si_midword, i, 1, fd); // <midword> } @@ -6708,8 +6696,8 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) putc(SN_PREFCOND, fd); // <sectionID> putc(SNF_REQUIRED, fd); // <sectionflags> - l = write_spell_prefcond(NULL, &spin->si_prefcond); - put_bytes(fd, (long_u)l, 4); // <sectionlen> + size_t l = (size_t)write_spell_prefcond(NULL, &spin->si_prefcond); + put_bytes(fd, l, 4); // <sectionlen> write_spell_prefcond(fd, &spin->si_prefcond); } @@ -6721,7 +6709,8 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) // round 1: SN_REP section // round 2: SN_SAL section (unless SN_SOFO is used) // round 3: SN_REPSAL section - for (round = 1; round <= 3; ++round) { + for (unsigned int round = 1; round <= 3; ++round) { + garray_T *gap; if (round == 1) gap = &spin->si_rep; else if (round == 2) { @@ -6741,45 +6730,47 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) qsort(gap->ga_data, (size_t)gap->ga_len, sizeof(fromto_T), rep_compare); - i = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL); + int i = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL); putc(i, fd); // <sectionID> // This is for making suggestions, section is not required. putc(0, fd); // <sectionflags> // Compute the length of what follows. - l = 2; // count <repcount> or <salcount> - for (int i = 0; i < gap->ga_len; ++i) { - ftp = &((fromto_T *)gap->ga_data)[i]; - l += 1 + (int)STRLEN(ftp->ft_from); // count <*fromlen> and <*from> - l += 1 + (int)STRLEN(ftp->ft_to); // count <*tolen> and <*to> + size_t l = 2; // count <repcount> or <salcount> + assert(gap->ga_len >= 0); + for (size_t i = 0; i < (size_t)gap->ga_len; ++i) { + fromto_T *ftp = &((fromto_T *)gap->ga_data)[i]; + l += 1 + STRLEN(ftp->ft_from); // count <*fromlen> and <*from> + l += 1 + STRLEN(ftp->ft_to); // count <*tolen> and <*to> } if (round == 2) - ++l; // count <salflags> - put_bytes(fd, (long_u)l, 4); // <sectionlen> + ++l; // count <salflags> + put_bytes(fd, l, 4); // <sectionlen> if (round == 2) { - i = 0; + int i = 0; if (spin->si_followup) i |= SAL_F0LLOWUP; if (spin->si_collapse) i |= SAL_COLLAPSE; if (spin->si_rem_accents) i |= SAL_REM_ACCENTS; - putc(i, fd); // <salflags> + putc(i, fd); // <salflags> } - put_bytes(fd, (long_u)gap->ga_len, 2); // <repcount> or <salcount> - for (int i = 0; i < gap->ga_len; ++i) { + put_bytes(fd, (uintmax_t)gap->ga_len, 2); // <repcount> or <salcount> + for (size_t i = 0; i < (size_t)gap->ga_len; ++i) { // <rep> : <repfromlen> <repfrom> <reptolen> <repto> // <sal> : <salfromlen> <salfrom> <saltolen> <salto> - ftp = &((fromto_T *)gap->ga_data)[i]; - for (rr = 1; rr <= 2; ++rr) { - p = rr == 1 ? ftp->ft_from : ftp->ft_to; - l = (int)STRLEN(p); - putc(l, fd); + fromto_T *ftp = &((fromto_T *)gap->ga_data)[i]; + for (unsigned int rr = 1; rr <= 2; ++rr) { + char_u *p = rr == 1 ? ftp->ft_from : ftp->ft_to; + l = STRLEN(p); + assert(l < INT_MAX); + putc((int)l, fd); if (l > 0) - fwv &= fwrite(p, l, (size_t)1, fd); + fwv &= fwrite(p, l, 1, fd); } } @@ -6791,16 +6782,15 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) putc(SN_SOFO, fd); // <sectionID> putc(0, fd); // <sectionflags> - l = (int)STRLEN(spin->si_sofofr); - put_bytes(fd, (long_u)(l + STRLEN(spin->si_sofoto) + 4), 4); - // <sectionlen> + size_t l = STRLEN(spin->si_sofofr); + put_bytes(fd, l + STRLEN(spin->si_sofoto) + 4, 4); // <sectionlen> - put_bytes(fd, (long_u)l, 2); // <sofofromlen> - fwv &= fwrite(spin->si_sofofr, l, (size_t)1, fd); // <sofofrom> + put_bytes(fd, l, 2); // <sofofromlen> + fwv &= fwrite(spin->si_sofofr, l, 1, fd); // <sofofrom> - l = (int)STRLEN(spin->si_sofoto); - put_bytes(fd, (long_u)l, 2); // <sofotolen> - fwv &= fwrite(spin->si_sofoto, l, (size_t)1, fd); // <sofoto> + l = STRLEN(spin->si_sofoto); + put_bytes(fd, l, 2); // <sofotolen> + fwv &= fwrite(spin->si_sofoto, l, 1, fd); // <sofoto> } // SN_WORDS: <word> ... @@ -6811,22 +6801,22 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) // round 1: count the bytes // round 2: write the bytes - for (round = 1; round <= 2; ++round) { - int todo; - int len = 0; + for (unsigned int round = 1; round <= 2; ++round) { + size_t todo; + size_t len = 0; hashitem_T *hi; - todo = (int)spin->si_commonwords.ht_used; + todo = spin->si_commonwords.ht_used; for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi) if (!HASHITEM_EMPTY(hi)) { - l = (int)STRLEN(hi->hi_key) + 1; + size_t l = STRLEN(hi->hi_key) + 1; len += l; if (round == 2) // <word> - fwv &= fwrite(hi->hi_key, (size_t)l, (size_t)1, fd); + fwv &= fwrite(hi->hi_key, l, 1, fd); --todo; } if (round == 1) - put_bytes(fd, (long_u)len, 4); // <sectionlen> + put_bytes(fd, len, 4); // <sectionlen> } } @@ -6835,10 +6825,9 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) if (!GA_EMPTY(&spin->si_map)) { putc(SN_MAP, fd); // <sectionID> putc(0, fd); // <sectionflags> - l = spin->si_map.ga_len; - put_bytes(fd, (long_u)l, 4); // <sectionlen> - fwv &= fwrite(spin->si_map.ga_data, (size_t)l, (size_t)1, fd); - // <mapstr> + size_t l = (size_t)spin->si_map.ga_len; + put_bytes(fd, l, 4); // <sectionlen> + fwv &= fwrite(spin->si_map.ga_data, l, 1, fd); // <mapstr> } // SN_SUGFILE: <timestamp> @@ -6851,7 +6840,7 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) || (spin->si_sofofr != NULL && spin->si_sofoto != NULL))) { putc(SN_SUGFILE, fd); // <sectionID> putc(0, fd); // <sectionflags> - put_bytes(fd, (long_u)8, 4); // <sectionlen> + put_bytes(fd, 8, 4); // <sectionlen> // Set si_sugtime and write it to the file. spin->si_sugtime = time(NULL); @@ -6864,7 +6853,7 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) if (spin->si_nosplitsugs) { putc(SN_NOSPLITSUGS, fd); // <sectionID> putc(0, fd); // <sectionflags> - put_bytes(fd, (long_u)0, 4); // <sectionlen> + put_bytes(fd, 0, 4); // <sectionlen> } // SN_COMPOUND: compound info. @@ -6874,28 +6863,27 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) putc(SN_COMPOUND, fd); // <sectionID> putc(0, fd); // <sectionflags> - l = (int)STRLEN(spin->si_compflags); - for (int i = 0; i < spin->si_comppat.ga_len; ++i) { - l += (int)STRLEN(((char_u **)(spin->si_comppat.ga_data))[i]) + 1; + size_t l = STRLEN(spin->si_compflags); + assert(spin->si_comppat.ga_len >= 0); + for (size_t i = 0; i < (size_t)spin->si_comppat.ga_len; ++i) { + l += STRLEN(((char_u **)(spin->si_comppat.ga_data))[i]) + 1; } - put_bytes(fd, (long_u)(l + 7), 4); // <sectionlen> + put_bytes(fd, l + 7, 4); // <sectionlen> putc(spin->si_compmax, fd); // <compmax> putc(spin->si_compminlen, fd); // <compminlen> putc(spin->si_compsylmax, fd); // <compsylmax> putc(0, fd); // for Vim 7.0b compatibility putc(spin->si_compoptions, fd); // <compoptions> - put_bytes(fd, (long_u)spin->si_comppat.ga_len, 2); - // <comppatcount> - for (int i = 0; i < spin->si_comppat.ga_len; ++i) { - p = ((char_u **)(spin->si_comppat.ga_data))[i]; + put_bytes(fd, (uintmax_t)spin->si_comppat.ga_len, 2); // <comppatcount> + for (size_t i = 0; i < (size_t)spin->si_comppat.ga_len; ++i) { + char_u *p = ((char_u **)(spin->si_comppat.ga_data))[i]; + assert(STRLEN(p) < INT_MAX); putc((int)STRLEN(p), fd); // <comppatlen> - fwv &= fwrite(p, (size_t)STRLEN(p), (size_t)1, fd); - // <comppattext> + fwv &= fwrite(p, STRLEN(p), 1, fd); // <comppattext> } // <compflags> - fwv &= fwrite(spin->si_compflags, (size_t)STRLEN(spin->si_compflags), - (size_t)1, fd); + fwv &= fwrite(spin->si_compflags, STRLEN(spin->si_compflags), 1, fd); } // SN_NOBREAK: NOBREAK flag @@ -6904,7 +6892,7 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) putc(0, fd); // <sectionflags> // It's empty, the presence of the section flags the feature. - put_bytes(fd, (long_u)0, 4); // <sectionlen> + put_bytes(fd, 0, 4); // <sectionlen> } // SN_SYLLABLE: syllable info. @@ -6914,10 +6902,9 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) putc(SN_SYLLABLE, fd); // <sectionID> putc(0, fd); // <sectionflags> - l = (int)STRLEN(spin->si_syllable); - put_bytes(fd, (long_u)l, 4); // <sectionlen> - fwv &= fwrite(spin->si_syllable, (size_t)l, (size_t)1, fd); - // <syllable> + size_t l = STRLEN(spin->si_syllable); + put_bytes(fd, l, 4); // <sectionlen> + fwv &= fwrite(spin->si_syllable, l, 1, fd); // <syllable> } // end of <SECTIONS> @@ -6926,7 +6913,8 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) // <LWORDTREE> <KWORDTREE> <PREFIXTREE> spin->si_memtot = 0; - for (round = 1; round <= 3; ++round) { + for (unsigned int round = 1; round <= 3; ++round) { + wordnode_T *tree; if (round == 1) tree = spin->si_foldroot->wn_sibling; else if (round == 2) @@ -6940,11 +6928,12 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) // Count the number of nodes. Needed to be able to allocate the // memory when reading the nodes. Also fills in index for shared // nodes. - nodecount = put_node(NULL, tree, 0, regionmask, round == 3); + size_t nodecount = (size_t)put_node(NULL, tree, 0, regionmask, round == 3); // number of nodes in 4 bytes - put_bytes(fd, (long_u)nodecount, 4); // <nodecount> - spin->si_memtot += nodecount + nodecount * sizeof(int); + put_bytes(fd, nodecount, 4); // <nodecount> + assert(nodecount + nodecount * sizeof(int) < INT_MAX); + spin->si_memtot += (int)(nodecount + nodecount * sizeof(int)); // Write the nodes. (void)put_node(fd, tree, 0, regionmask, round == 3); @@ -7002,11 +6991,6 @@ put_node ( bool prefixtree // true for PREFIXTREE ) { - int newindex = idx; - int siblingcount = 0; - wordnode_T *np; - int flags; - // If "node" is zero the tree is empty. if (node == NULL) return 0; @@ -7015,7 +6999,8 @@ put_node ( node->wn_u1.index = idx; // Count the number of siblings. - for (np = node; np != NULL; np = np->wn_sibling) + int siblingcount = 0; + for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) ++siblingcount; // Write the sibling count. @@ -7023,7 +7008,7 @@ put_node ( putc(siblingcount, fd); // <siblingcount> // Write each sibling byte and optionally extra info. - for (np = node; np != NULL; np = np->wn_sibling) { + for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) { if (np->wn_byte == 0) { if (fd != NULL) { // For a NUL byte (end of word) write the flags etc. @@ -7039,10 +7024,10 @@ put_node ( putc(np->wn_flags, fd); // <pflags> } putc(np->wn_affixID, fd); // <affixID> - put_bytes(fd, (long_u)np->wn_region, 2); // <prefcondnr> + put_bytes(fd, (uintmax_t)np->wn_region, 2); // <prefcondnr> } else { // For word trees we write the flag/region items. - flags = np->wn_flags; + int flags = np->wn_flags; if (regionmask != 0 && np->wn_region != regionmask) flags |= WF_REGION; if (np->wn_affixID != 0) @@ -7054,7 +7039,7 @@ put_node ( if (np->wn_flags >= 0x100) { putc(BY_FLAGS2, fd); // <byte> putc(flags, fd); // <flags> - putc((unsigned)flags >> 8, fd); // <flags2> + putc((int)((unsigned)flags >> 8), fd); // <flags2> } else { putc(BY_FLAGS, fd); // <byte> putc(flags, fd); // <flags> @@ -7071,9 +7056,8 @@ put_node ( && np->wn_child->wn_u2.wnode != node) { // The child is written elsewhere, write the reference. if (fd != NULL) { - putc(BY_INDEX, fd); // <byte> - // <nodeidx> - put_bytes(fd, (long_u)np->wn_child->wn_u1.index, 3); + putc(BY_INDEX, fd); // <byte> + put_bytes(fd, (uintmax_t)np->wn_child->wn_u1.index, 3); // <nodeidx> } } else if (np->wn_child->wn_u2.wnode == NULL) // We will write the child below and give it an index. @@ -7089,10 +7073,10 @@ put_node ( // Space used in the array when reading: one for each sibling and one for // the count. - newindex += siblingcount + 1; + int newindex = idx + siblingcount + 1; // Recursively dump the children of each sibling. - for (np = node; np != NULL; np = np->wn_sibling) + for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node) newindex = put_node(fd, np->wn_child, newindex, regionmask, prefixtree); @@ -7440,16 +7424,8 @@ static int bytes2offset(char_u **pp) // Write the .sug file in "fname". static void sug_write(spellinfo_T *spin, char_u *fname) { - FILE *fd; - wordnode_T *tree; - int nodecount; - int wcount; - char_u *line; - linenr_T lnum; - int len; - // Create the file. Note that an existing file is silently overwritten! - fd = mch_fopen((char *)fname, "w"); + FILE *fd = mch_fopen((char *)fname, "w"); if (fd == NULL) { EMSG2(_(e_notopen), fname); return; @@ -7471,7 +7447,7 @@ static void sug_write(spellinfo_T *spin, char_u *fname) // <SUGWORDTREE> spin->si_memtot = 0; - tree = spin->si_foldroot->wn_sibling; + wordnode_T *tree = spin->si_foldroot->wn_sibling; // Clear the index and wnode fields in the tree. clear_node(tree); @@ -7479,28 +7455,31 @@ static void sug_write(spellinfo_T *spin, char_u *fname) // Count the number of nodes. Needed to be able to allocate the // memory when reading the nodes. Also fills in index for shared // nodes. - nodecount = put_node(NULL, tree, 0, 0, false); + size_t nodecount = (size_t)put_node(NULL, tree, 0, 0, false); // number of nodes in 4 bytes - put_bytes(fd, (long_u)nodecount, 4); // <nodecount> - spin->si_memtot += nodecount + nodecount * sizeof(int); + put_bytes(fd, nodecount, 4); // <nodecount> + assert(nodecount + nodecount * sizeof(int) < INT_MAX); + spin->si_memtot += (int)(nodecount + nodecount * sizeof(int)); // Write the nodes. (void)put_node(fd, tree, 0, 0, false); // <SUGTABLE>: <sugwcount> <sugline> ... - wcount = spin->si_spellbuf->b_ml.ml_line_count; - put_bytes(fd, (long_u)wcount, 4); // <sugwcount> + linenr_T wcount = spin->si_spellbuf->b_ml.ml_line_count; + assert(wcount >= 0); + put_bytes(fd, (uintmax_t)wcount, 4); // <sugwcount> - for (lnum = 1; lnum <= (linenr_T)wcount; ++lnum) { + for (linenr_T lnum = 1; lnum <= wcount; ++lnum) { // <sugline>: <sugnr> ... NUL - line = ml_get_buf(spin->si_spellbuf, lnum, FALSE); - len = (int)STRLEN(line) + 1; - if (fwrite(line, (size_t)len, (size_t)1, fd) == 0) { + char_u *line = ml_get_buf(spin->si_spellbuf, lnum, FALSE); + size_t len = STRLEN(line) + 1; + if (fwrite(line, len, 1, fd) == 0) { EMSG(_(e_write)); goto theend; } - spin->si_memtot += len; + assert((size_t)spin->si_memtot + len <= INT_MAX); + spin->si_memtot += (int)len; } // Write another byte to check for errors. @@ -8286,31 +8265,30 @@ static bool spell_iswordp_w(int *p, win_T *wp) // When "fd" is NULL only count the length of what is written. static int write_spell_prefcond(FILE *fd, garray_T *gap) { - char_u *p; - int len; - int totlen; - size_t x = 1; // collect return value of fwrite() + assert(gap->ga_len >= 0); if (fd != NULL) - put_bytes(fd, (long_u)gap->ga_len, 2); // <prefcondcnt> - - totlen = 2 + gap->ga_len; // length of <prefcondcnt> and <condlen> bytes + put_bytes(fd, (uintmax_t)gap->ga_len, 2); // <prefcondcnt> + size_t totlen = 2 + (size_t)gap->ga_len; // <prefcondcnt> and <condlen> bytes + size_t x = 1; // collect return value of fwrite() for (int i = 0; i < gap->ga_len; ++i) { // <prefcond> : <condlen> <condstr> - p = ((char_u **)gap->ga_data)[i]; + char_u *p = ((char_u **)gap->ga_data)[i]; if (p != NULL) { - len = (int)STRLEN(p); + size_t len = STRLEN(p); if (fd != NULL) { - fputc(len, fd); - x &= fwrite(p, (size_t)len, (size_t)1, fd); + assert(len <= INT_MAX); + fputc((int)len, fd); + x &= fwrite(p, len, 1, fd); } totlen += len; } else if (fd != NULL) fputc(0, fd); } - return totlen; + assert(totlen <= INT_MAX); + return (int)totlen; } // Case-fold "str[len]" into "buf[buflen]". The result is NUL terminated. diff --git a/src/nvim/testdir/test63.in b/src/nvim/testdir/test63.in index db347a0a87..7fbe0ac434 100644 --- a/src/nvim/testdir/test63.in +++ b/src/nvim/testdir/test63.in @@ -7,9 +7,9 @@ STARTTEST :" --- Check that "matcharg()" returns the correct group and pattern if a match :" --- is defined. :let @r = "*** Test 1: " -:highlight MyGroup1 ctermbg=red guibg=red -:highlight MyGroup2 ctermbg=green guibg=green -:highlight MyGroup3 ctermbg=blue guibg=blue +:highlight MyGroup1 term=bold ctermbg=red guibg=red +:highlight MyGroup2 term=italic ctermbg=green guibg=green +:highlight MyGroup3 term=underline ctermbg=blue guibg=blue :match MyGroup1 /TODO/ :2match MyGroup2 /FIXME/ :3match MyGroup3 /XXX/ diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 9a3da5bcdb..59920cfbe1 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -82,6 +82,7 @@ #include <assert.h> #include <inttypes.h> +#include <limits.h> #include <errno.h> #include <stdbool.h> #include <string.h> @@ -569,7 +570,7 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) } if (size > 0) { - uep->ue_array = xmalloc(sizeof(char_u *) * size); + uep->ue_array = xmalloc(sizeof(char_u *) * (size_t)size); for (i = 0, lnum = top + 1; i < size; ++i) { fast_breakcheck(); if (got_int) { @@ -638,7 +639,6 @@ char_u *u_get_undo_file_name(char_u *buf_ffname, int reading) char_u dir_name[IOSIZE + 1]; char_u *munged_name = NULL; char_u *undo_file_name = NULL; - int dir_len; char_u *p; char_u *ffname = buf_ffname; #ifdef HAVE_READLINK @@ -659,11 +659,11 @@ char_u *u_get_undo_file_name(char_u *buf_ffname, int reading) * When not reading use the first directory that exists or ".". */ dirp = p_udir; while (*dirp != NUL) { - dir_len = copy_option_part(&dirp, dir_name, IOSIZE, ","); + size_t dir_len = copy_option_part(&dirp, dir_name, IOSIZE, ","); if (dir_len == 1 && dir_name[0] == '.') { /* Use same directory as the ffname, * "dir/name" -> "dir/.name.un~" */ - undo_file_name = vim_strnsave(ffname, (int)(STRLEN(ffname) + 5)); + undo_file_name = vim_strnsave(ffname, STRLEN(ffname) + 5); p = path_tail(undo_file_name); memmove(p + 1, p, STRLEN(p) + 1); *p = '.'; @@ -715,42 +715,40 @@ static void u_free_uhp(u_header_T *uhp) static int serialize_header(FILE *fp, buf_T *buf, char_u *hash) { - int len; - /* Start writing, first the magic marker and undo info version. */ - if (fwrite(UF_START_MAGIC, (size_t)UF_START_MAGIC_LEN, (size_t)1, fp) != 1) + if (fwrite(UF_START_MAGIC, UF_START_MAGIC_LEN, 1, fp) != 1) return FAIL; - put_bytes(fp, (long_u)UF_VERSION, 2); + put_bytes(fp, UF_VERSION, 2); /* Write a hash of the buffer text, so that we can verify it is still the * same when reading the buffer text. */ - if (fwrite(hash, (size_t)UNDO_HASH_SIZE, (size_t)1, fp) != 1) + if (fwrite(hash, UNDO_HASH_SIZE, 1, fp) != 1) return FAIL; /* buffer-specific data */ - put_bytes(fp, (long_u)buf->b_ml.ml_line_count, 4); - len = buf->b_u_line_ptr != NULL ? (int)STRLEN(buf->b_u_line_ptr) : 0; - put_bytes(fp, (long_u)len, 4); + put_bytes(fp, (uintmax_t)buf->b_ml.ml_line_count, 4); + size_t len = buf->b_u_line_ptr ? STRLEN(buf->b_u_line_ptr) : 0; + put_bytes(fp, len, 4); if (len > 0 && fwrite(buf->b_u_line_ptr, len, 1, fp) != 1) return FAIL; - put_bytes(fp, (long_u)buf->b_u_line_lnum, 4); - put_bytes(fp, (long_u)buf->b_u_line_colnr, 4); + put_bytes(fp, (uintmax_t)buf->b_u_line_lnum, 4); + put_bytes(fp, (uintmax_t)buf->b_u_line_colnr, 4); /* Undo structures header data */ put_header_ptr(fp, buf->b_u_oldhead); put_header_ptr(fp, buf->b_u_newhead); put_header_ptr(fp, buf->b_u_curhead); - put_bytes(fp, (long_u)buf->b_u_numhead, 4); - put_bytes(fp, (long_u)buf->b_u_seq_last, 4); - put_bytes(fp, (long_u)buf->b_u_seq_cur, 4); + put_bytes(fp, (uintmax_t)buf->b_u_numhead, 4); + put_bytes(fp, (uintmax_t)buf->b_u_seq_last, 4); + put_bytes(fp, (uintmax_t)buf->b_u_seq_cur, 4); put_time(fp, buf->b_u_time_cur); /* Optional fields. */ putc(4, fp); putc(UF_LAST_SAVE_NR, fp); - put_bytes(fp, (long_u)buf->b_u_save_nr_last, 4); + put_bytes(fp, (uintmax_t)buf->b_u_save_nr_last, 4); putc(0, fp); /* end marker */ @@ -759,22 +757,19 @@ static int serialize_header(FILE *fp, buf_T *buf, char_u *hash) static int serialize_uhp(FILE *fp, buf_T *buf, u_header_T *uhp) { - int i; - u_entry_T *uep; - - if (put_bytes(fp, (long_u)UF_HEADER_MAGIC, 2) == FAIL) + if (put_bytes(fp, UF_HEADER_MAGIC, 2) == FAIL) return FAIL; put_header_ptr(fp, uhp->uh_next.ptr); put_header_ptr(fp, uhp->uh_prev.ptr); put_header_ptr(fp, uhp->uh_alt_next.ptr); put_header_ptr(fp, uhp->uh_alt_prev.ptr); - put_bytes(fp, uhp->uh_seq, 4); + put_bytes(fp, (uintmax_t)uhp->uh_seq, 4); serialize_pos(uhp->uh_cursor, fp); - put_bytes(fp, (long_u)uhp->uh_cursor_vcol, 4); - put_bytes(fp, (long_u)uhp->uh_flags, 2); + put_bytes(fp, (uintmax_t)uhp->uh_cursor_vcol, 4); + put_bytes(fp, (uintmax_t)uhp->uh_flags, 2); /* Assume NMARKS will stay the same. */ - for (i = 0; i < NMARKS; ++i) + for (size_t i = 0; i < NMARKS; ++i) serialize_pos(uhp->uh_namedm[i], fp); serialize_visualinfo(&uhp->uh_visual, fp); put_time(fp, uhp->uh_time); @@ -782,17 +777,17 @@ static int serialize_uhp(FILE *fp, buf_T *buf, u_header_T *uhp) /* Optional fields. */ putc(4, fp); putc(UHP_SAVE_NR, fp); - put_bytes(fp, (long_u)uhp->uh_save_nr, 4); + put_bytes(fp, (uintmax_t)uhp->uh_save_nr, 4); putc(0, fp); /* end marker */ /* Write all the entries. */ - for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next) { - put_bytes(fp, (long_u)UF_ENTRY_MAGIC, 2); + for (u_entry_T *uep = uhp->uh_entry; uep; uep = uep->ue_next) { + put_bytes(fp, UF_ENTRY_MAGIC, 2); if (serialize_uep(fp, buf, uep) == FAIL) return FAIL; } - put_bytes(fp, (long_u)UF_ENTRY_END_MAGIC, 2); + put_bytes(fp, UF_ENTRY_END_MAGIC, 2); return OK; } @@ -875,16 +870,13 @@ static u_header_T *unserialize_uhp(FILE *fp, char_u *file_name) */ static int serialize_uep(FILE *fp, buf_T *buf, u_entry_T *uep) { - int i; - size_t len; - - put_bytes(fp, (long_u)uep->ue_top, 4); - put_bytes(fp, (long_u)uep->ue_bot, 4); - put_bytes(fp, (long_u)uep->ue_lcount, 4); - put_bytes(fp, (long_u)uep->ue_size, 4); - for (i = 0; i < uep->ue_size; ++i) { - len = STRLEN(uep->ue_array[i]); - if (put_bytes(fp, (long_u)len, 4) == FAIL) + put_bytes(fp, (uintmax_t)uep->ue_top, 4); + put_bytes(fp, (uintmax_t)uep->ue_bot, 4); + put_bytes(fp, (uintmax_t)uep->ue_lcount, 4); + put_bytes(fp, (uintmax_t)uep->ue_size, 4); + for (size_t i = 0; i < (size_t)uep->ue_size; ++i) { + size_t len = STRLEN(uep->ue_array[i]); + if (put_bytes(fp, len, 4) == FAIL) return FAIL; if (len > 0 && fwrite(uep->ue_array[i], len, 1, fp) != 1) return FAIL; @@ -910,8 +902,8 @@ static u_entry_T *unserialize_uep(FILE *fp, int *error, char_u *file_name) uep->ue_lcount = get4c(fp); uep->ue_size = get4c(fp); if (uep->ue_size > 0) { - array = xmalloc(sizeof(char_u *) * uep->ue_size); - memset(array, 0, sizeof(char_u *) * uep->ue_size); + array = xmalloc(sizeof(char_u *) * (size_t)uep->ue_size); + memset(array, 0, sizeof(char_u *) * (size_t)uep->ue_size); } else array = NULL; uep->ue_array = array; @@ -938,9 +930,9 @@ static u_entry_T *unserialize_uep(FILE *fp, int *error, char_u *file_name) */ static void serialize_pos(pos_T pos, FILE *fp) { - put_bytes(fp, (long_u)pos.lnum, 4); - put_bytes(fp, (long_u)pos.col, 4); - put_bytes(fp, (long_u)pos.coladd, 4); + put_bytes(fp, (uintmax_t)pos.lnum, 4); + put_bytes(fp, (uintmax_t)pos.col, 4); + put_bytes(fp, (uintmax_t)pos.coladd, 4); } /* @@ -966,8 +958,8 @@ static void serialize_visualinfo(visualinfo_T *info, FILE *fp) { serialize_pos(info->vi_start, fp); serialize_pos(info->vi_end, fp); - put_bytes(fp, (long_u)info->vi_mode, 4); - put_bytes(fp, (long_u)info->vi_curswant, 4); + put_bytes(fp, (uintmax_t)info->vi_mode, 4); + put_bytes(fp, (uintmax_t)info->vi_curswant, 4); } /* @@ -987,7 +979,7 @@ static void unserialize_visualinfo(visualinfo_T *info, FILE *fp) * pointers when reading. */ static void put_header_ptr(FILE *fp, u_header_T *uhp) { - put_bytes(fp, (long_u)(uhp != NULL ? uhp->uh_seq : 0), 4); + put_bytes(fp, (uintmax_t)(uhp != NULL ? uhp->uh_seq : 0), 4); } /* @@ -1061,9 +1053,7 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash) goto theend; } else { char_u mbuf[UF_START_MAGIC_LEN]; - int len; - - len = read_eintr(fd, mbuf, UF_START_MAGIC_LEN); + ssize_t len = read_eintr(fd, mbuf, UF_START_MAGIC_LEN); close(fd); if (len < UF_START_MAGIC_LEN || memcmp(mbuf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0) { @@ -1121,7 +1111,7 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash) && os_fileinfo((char *)buf->b_ffname, &file_info_old) && os_fileinfo((char *)file_name, &file_info_new) && file_info_old.stat.st_gid != file_info_new.stat.st_gid - && os_fchown(fd, -1, file_info_old.stat.st_gid) != 0) { + && os_fchown(fd, (uv_uid_t)-1, (uv_gid_t)file_info_old.stat.st_gid)) { os_setperm(file_name, (perm & 0707) | ((perm & 07) << 3)); } # ifdef HAVE_SELINUX @@ -1178,7 +1168,7 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash) uhp = uhp->uh_next.ptr; } - if (put_bytes(fp, (long_u)UF_HEADER_END_MAGIC, 2) == OK) + if (put_bytes(fp, UF_HEADER_END_MAGIC, 2) == OK) write_ok = true; #ifdef U_DEBUG if (headers_written != buf->b_u_numhead) { @@ -1358,7 +1348,7 @@ void u_read_undo(char_u *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) { - uhp_table = xmalloc(num_head * sizeof(u_header_T *)); + uhp_table = xmalloc((size_t)num_head * sizeof(u_header_T *)); } while ((c = get2c(fp)) == UF_HEADER_MAGIC) { @@ -1433,15 +1423,18 @@ void u_read_undo(char_u *name, char_u *hash, char_u *orig_name) break; } if (old_header_seq > 0 && old_idx < 0 && uhp->uh_seq == old_header_seq) { - old_idx = i; + assert(i <= SHRT_MAX); + old_idx = (short)i; SET_FLAG(i); } if (new_header_seq > 0 && new_idx < 0 && uhp->uh_seq == new_header_seq) { - new_idx = i; + assert(i <= SHRT_MAX); + new_idx = (short)i; SET_FLAG(i); } if (cur_header_seq > 0 && cur_idx < 0 && uhp->uh_seq == cur_header_seq) { - cur_idx = i; + assert(i <= SHRT_MAX); + cur_idx = (short)i; SET_FLAG(i); } } @@ -1993,7 +1986,7 @@ static void u_undoredo(int undo) /* delete the lines between top and bot and save them in newarray */ if (oldsize > 0) { - newarray = xmalloc(sizeof(char_u *) * oldsize); + newarray = xmalloc(sizeof(char_u *) * (size_t)oldsize); /* delete backwards, it goes faster in most cases */ for (lnum = bot - 1, i = oldsize; --i >= 0; --lnum) { /* what can we do when we run out of memory? */ diff --git a/src/nvim/version.c b/src/nvim/version.c index 3e7450c139..8a0ab1c7e3 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -191,18 +191,18 @@ static int included_patches[] = { //550, //549, //548 NA - //547, + 547, //546, - //545, + 545, //544 NA 543, //542, //541, //540 NA //539, - //538, + 538, //537, - //536, + 536, //535, //534 NA //533, @@ -217,7 +217,7 @@ static int included_patches[] = { //524, //523 NA //522, - //521, + 521, 520, //519, 518, @@ -250,12 +250,12 @@ static int included_patches[] = { 491, //490, 489, - //488, + 488, //487, - //486, - //485, + 486, + 485, //484 NA - //483, + 483, //482 NA //481 NA //480 NA @@ -287,7 +287,7 @@ static int included_patches[] = { //453 NA 452, //451, - //450, + 450, 449, //448 NA 447, diff --git a/test/functional/legacy/mapping_spec.lua b/test/functional/legacy/mapping_spec.lua new file mode 100644 index 0000000000..46d29d1692 --- /dev/null +++ b/test/functional/legacy/mapping_spec.lua @@ -0,0 +1,26 @@ +-- Test for mappings and abbreviations + +local helpers = require('test.functional.helpers') +local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert +local execute, expect = helpers.execute, helpers.expect + +describe('mapping', function() + setup(clear) + + it('is working', function() + insert([[ + test starts here: + ]]) + + execute('set encoding=utf-8') + + -- Abbreviations with р (0x80) should work. + execute('inoreab чкпр vim') + feed('GAчкпр <cr><esc>') + + -- Assert buffer contents. + expect([[ + test starts here: + vim]]) + end) +end) |