9009 lines
202 KiB
VimL
9009 lines
202 KiB
VimL
" Vim script language tests
|
|
" Author: Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com>
|
|
" Last Change: 2019 May 24
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test environment {{{1
|
|
"-------------------------------------------------------------------------------
|
|
|
|
|
|
" Adding new tests easily. {{{2
|
|
"
|
|
" Writing new tests is eased considerably with the following functions and
|
|
" abbreviations (see "Commands for recording the execution path", "Automatic
|
|
" argument generation").
|
|
"
|
|
" To get the abbreviations, execute the command
|
|
"
|
|
" :let test49_set_env = 1 | source test49.vim
|
|
"
|
|
" To get them always (from src/nvim/testdir), put a line
|
|
"
|
|
" au! BufRead test49.vim let test49_set_env = 1 | source test49.vim
|
|
"
|
|
" into the local .vimrc file in the src/nvim/testdir directory.
|
|
"
|
|
if exists("test49_set_env") && test49_set_env
|
|
|
|
" Automatic argument generation for the test environment commands.
|
|
|
|
function! Xsum()
|
|
let addend = substitute(getline("."), '^.*"\s*X:\s*\|^.*', '', "")
|
|
" Evaluate arithmetic expression.
|
|
if addend != ""
|
|
exec "let g:Xsum = g:Xsum + " . addend
|
|
endif
|
|
endfunction
|
|
|
|
function! Xcheck()
|
|
let g:Xsum=0
|
|
?XpathINIT?,.call Xsum()
|
|
exec "norm A "
|
|
return g:Xsum
|
|
endfunction
|
|
|
|
iab Xcheck Xcheck<Space><C-R>=Xcheck()<CR><C-O>x
|
|
|
|
function! Xcomment(num)
|
|
let str = ""
|
|
let tabwidth = &sts ? &sts : &ts
|
|
let tabs = (48+tabwidth - a:num - virtcol(".")) / tabwidth
|
|
while tabs > 0
|
|
let str = str . "\t"
|
|
let tabs = tabs - 1
|
|
endwhile
|
|
let str = str . '" X:'
|
|
return str
|
|
endfunction
|
|
|
|
function! Xloop()
|
|
let back = line(".") . "|norm" . virtcol(".") . "|"
|
|
norm 0
|
|
let last = search('X\(loop\|path\)INIT\|Xloop\>', "bW")
|
|
exec back
|
|
let theline = getline(last)
|
|
if theline =~ 'X\(loop\|path\)INIT'
|
|
let num = 1
|
|
else
|
|
let num = 2 * substitute(theline, '.*Xloop\s*\(\d\+\).*', '\1', "")
|
|
endif
|
|
?X\(loop\|path\)INIT?
|
|
\s/\(XloopINIT!\=\s*\d\+\s\+\)\@<=\(\d\+\)/\=2*submatch(2)/
|
|
exec back
|
|
exec "norm a "
|
|
return num . Xcomment(strlen(num))
|
|
endfunction
|
|
|
|
iab Xloop Xloop<Space><C-R>=Xloop()<CR><C-O>x
|
|
|
|
function! Xpath(loopinit)
|
|
let back = line(".") . "|norm" . virtcol(".") . "|"
|
|
norm 0
|
|
let last = search('XpathINIT\|Xpath\>\|XloopINIT', "bW")
|
|
exec back
|
|
let theline = getline(last)
|
|
if theline =~ 'XpathINIT'
|
|
let num = 1
|
|
elseif theline =~ 'Xpath\>'
|
|
let num = 2 * substitute(theline, '.*Xpath\s*\(\d\+\).*', '\1', "")
|
|
else
|
|
let pattern = '.*XloopINIT!\=\s*\(\d\+\)\s*\(\d\+\).*'
|
|
let num = substitute(theline, pattern, '\1', "")
|
|
let factor = substitute(theline, pattern, '\2', "")
|
|
" The "<C-O>x" from the "Xpath" iab and the character triggering its
|
|
" expansion are in the input buffer. Save and clear typeahead so
|
|
" that it is not read away by the call to "input()" below. Restore
|
|
" afterwards.
|
|
call inputsave()
|
|
let loops = input("Number of iterations in previous loop? ")
|
|
call inputrestore()
|
|
while (loops > 0)
|
|
let num = num * factor
|
|
let loops = loops - 1
|
|
endwhile
|
|
endif
|
|
exec "norm a "
|
|
if a:loopinit
|
|
return num . " 1"
|
|
endif
|
|
return num . Xcomment(strlen(num))
|
|
endfunction
|
|
|
|
iab Xpath Xpath<Space><C-R>=Xpath(0)<CR><C-O>x
|
|
iab XloopINIT XloopINIT<Space><C-R>=Xpath(1)<CR><C-O>x
|
|
|
|
" Also useful (see ExtraVim below):
|
|
aug ExtraVim
|
|
au!
|
|
au BufEnter <sfile> syn region ExtraVim
|
|
\ start=+^if\s\+ExtraVim(.*)+ end=+^endif+
|
|
\ transparent keepend
|
|
au BufEnter <sfile> syn match ExtraComment /^"/
|
|
\ contained containedin=ExtraVim
|
|
au BufEnter <sfile> hi link ExtraComment vimComment
|
|
aug END
|
|
|
|
aug Xpath
|
|
au BufEnter <sfile> syn keyword Xpath
|
|
\ XpathINIT Xpath XloopINIT Xloop XloopNEXT Xcheck Xout
|
|
au BufEnter <sfile> hi link Xpath Special
|
|
aug END
|
|
|
|
do BufEnter <sfile>
|
|
|
|
" Do not execute the tests when sourcing this file for getting the functions
|
|
" and abbreviations above, which are intended for easily adding new test
|
|
" cases; they are not needed for test execution. Unlet the variable
|
|
" controlling this so that an explicit ":source" command for this file will
|
|
" execute the tests.
|
|
unlet test49_set_env
|
|
finish
|
|
|
|
endif
|
|
|
|
|
|
" Commands for recording the execution path. {{{2
|
|
"
|
|
" The Xpath/Xloop commands can be used for computing the eXecution path by
|
|
" adding (different) powers of 2 from those script lines, for which the
|
|
" execution should be checked. Xloop provides different addends for each
|
|
" execution of a loop. Permitted values are 2^0 to 2^30, so that 31 execution
|
|
" points (multiply counted inside loops) can be tested.
|
|
"
|
|
" Note that the arguments of the following commands can be generated
|
|
" automatically, see below.
|
|
"
|
|
" Usage: {{{3
|
|
"
|
|
" - Use XpathINIT at the beginning of the test.
|
|
"
|
|
" - Use Xpath to check if a line is executed.
|
|
" Argument: power of 2 (decimal).
|
|
"
|
|
" - To check multiple execution of loops use Xloop for automatically
|
|
" computing Xpath values:
|
|
"
|
|
" - Use XloopINIT before the loop.
|
|
" Two arguments:
|
|
" - the first Xpath value (power of 2) to be used (Xnext),
|
|
" - factor for computing a new Xnext value when reexecuting a loop
|
|
" (by a ":continue" or ":endwhile"); this should be 2^n where
|
|
" n is the number of Xloop commands inside the loop.
|
|
" If XloopINIT! is used, the first execution of XloopNEXT is
|
|
" a no-operation.
|
|
"
|
|
" - Use Xloop inside the loop:
|
|
" One argument:
|
|
" The argument and the Xnext value are multiplied to build the
|
|
" next Xpath value. No new Xnext value is prepared. The argument
|
|
" should be 2^(n-1) for the nth Xloop command inside the loop.
|
|
" If the loop has only one Xloop command, the argument can be
|
|
" omitted (default: 1).
|
|
"
|
|
" - Use XloopNEXT before ":continue" and ":endwhile". This computes a new
|
|
" Xnext value for the next execution of the loop by multiplying the old
|
|
" one with the factor specified in the XloopINIT command. No Argument.
|
|
" Alternatively, when XloopINIT! is used, a single XloopNEXT at the
|
|
" beginning of the loop can be used.
|
|
"
|
|
" Nested loops are not supported.
|
|
"
|
|
" - Use Xcheck at end of each test. It prints the test number, the expected
|
|
" execution path value, the test result ("OK" or "FAIL"), and, if the tests
|
|
" fails, the actual execution path.
|
|
" One argument:
|
|
" Expected Xpath/Xloop sum for the correct execution path.
|
|
" In order that this value can be computed automatically, do the
|
|
" following: For each line in the test with an Xpath and Xloop
|
|
" command, add a comment starting with "X:" and specifying an
|
|
" expression that evaluates to the value contributed by this line to
|
|
" the correct execution path. (For copying an Xpath argument of at
|
|
" least two digits into the comment, press <C-P>.) At the end of the
|
|
" test, just type "Xcheck" and press <Esc>.
|
|
"
|
|
" - In order to add additional information to the test output file, use the
|
|
" Xout command. Argument(s) like ":echo".
|
|
"
|
|
" Automatic argument generation: {{{3
|
|
"
|
|
" The arguments of the Xpath, XloopINIT, Xloop, and Xcheck commands can be
|
|
" generated automatically, so that new tests can easily be written without
|
|
" mental arithmetic. The Xcheck argument is computed from the "X:" comments
|
|
" of the preceding Xpath and Xloop commands. See the commands and
|
|
" abbreviations at the beginning of this file.
|
|
"
|
|
" Implementation: {{{3
|
|
" XpathINIT, Xpath, XloopINIT, Xloop, XloopNEXT, Xcheck, Xout.
|
|
"
|
|
" The variants for existing g:ExtraVimResult are needed when executing a script
|
|
" in an extra Vim process, see ExtraVim below.
|
|
|
|
" EXTRA_VIM_START - do not change or remove this line.
|
|
|
|
com! XpathINIT let g:Xpath = 0
|
|
|
|
if exists("g:ExtraVimResult")
|
|
com! -count -bar Xpath exec "!echo <count> >>" . g:ExtraVimResult
|
|
else
|
|
com! -count -bar Xpath let g:Xpath = g:Xpath + <count>
|
|
endif
|
|
|
|
com! -count -nargs=1 -bang
|
|
\ XloopINIT let g:Xnext = <count> |
|
|
\ let g:Xfactor = <args> |
|
|
\ let g:Xskip = strlen("<bang>")
|
|
|
|
if exists("g:ExtraVimResult")
|
|
com! -count=1 -bar Xloop exec "!echo " . (g:Xnext * <count>) . " >>" .
|
|
\ g:ExtraVimResult
|
|
else
|
|
com! -count=1 -bar Xloop let g:Xpath = g:Xpath + g:Xnext * <count>
|
|
endif
|
|
|
|
com! XloopNEXT let g:Xnext = g:Xnext *
|
|
\ (g:Xskip ? 1 : g:Xfactor) |
|
|
\ let g:Xskip = 0
|
|
|
|
let @r = ""
|
|
let Xtest = 1
|
|
com! -count Xcheck let Xresult = "*** Test " .
|
|
\ (Xtest<10?" ":Xtest<100?" ":"") .
|
|
\ Xtest . ": " . (
|
|
\ (Xpath==<count>) ? "OK (".Xpath.")" :
|
|
\ "FAIL (".Xpath." instead of <count>)"
|
|
\ ) |
|
|
\ let @R = Xresult . "\n" |
|
|
\ echo Xresult |
|
|
\ let Xtest = Xtest + 1
|
|
|
|
if exists("g:ExtraVimResult")
|
|
com! -nargs=+ Xoutq exec "!echo @R:'" .
|
|
\ substitute(substitute(<q-args>,
|
|
\ "'", '&\\&&', "g"), "\n", "@NL@", "g")
|
|
\ . "' >>" . g:ExtraVimResult
|
|
else
|
|
com! -nargs=+ Xoutq let @R = "--- Test " .
|
|
\ (g:Xtest<10?" ":g:Xtest<100?" ":"") .
|
|
\ g:Xtest . ": " . substitute(<q-args>,
|
|
\ "\n", "&\t ", "g") . "\n"
|
|
endif
|
|
com! -nargs=+ Xout exec 'Xoutq' <args>
|
|
|
|
" Switch off storing of lines for undoing changes. Speeds things up a little.
|
|
set undolevels=-1
|
|
|
|
" EXTRA_VIM_STOP - do not change or remove this line.
|
|
|
|
|
|
" ExtraVim() - Run a script file in an extra Vim process. {{{2
|
|
"
|
|
" This is useful for testing immediate abortion of the script processing due to
|
|
" an error in a command dynamically enclosed by a :try/:tryend region or when an
|
|
" exception is thrown but not caught or when an interrupt occurs. It can also
|
|
" be used for testing :finish.
|
|
"
|
|
" An interrupt location can be specified by an "INTERRUPT" comment. A number
|
|
" telling how often this location is reached (in a loop or in several function
|
|
" calls) should be specified as argument. When missing, once per script
|
|
" invocation or function call is assumed. INTERRUPT locations are tested by
|
|
" setting a breakpoint in that line and using the ">quit" debug command when
|
|
" the breakpoint is reached. A function for which an INTERRUPT location is
|
|
" specified must be defined before calling it (or executing it as a script by
|
|
" using ExecAsScript below).
|
|
"
|
|
" This function is only called in normal modus ("g:ExtraVimResult" undefined).
|
|
"
|
|
" Tests to be executed as an extra script should be written as follows:
|
|
"
|
|
" column 1 column 1
|
|
" | |
|
|
" v v
|
|
"
|
|
" XpathINIT XpathINIT
|
|
" if ExtraVim() if ExtraVim()
|
|
" ... " ...
|
|
" ... " ...
|
|
" endif endif
|
|
" Xcheck <number> Xcheck <number>
|
|
"
|
|
" Double quotes in column 1 are removed before the script is executed.
|
|
" They should be used if the test has unbalanced conditionals (:if/:endif,
|
|
" :while:/endwhile, :try/:endtry) or for a line with a syntax error. The
|
|
" extra script may use Xpath, XloopINIT, Xloop, XloopNEXT, and Xout as usual.
|
|
"
|
|
" A file name may be specified as argument. All messages of the extra Vim
|
|
" process are then redirected to the file. An existing file is overwritten.
|
|
"
|
|
let ExtraVimCount = 0
|
|
let ExtraVimBase = expand("<sfile>")
|
|
let ExtraVimTestEnv = ""
|
|
"
|
|
function! ExtraVim(...)
|
|
" Count how often this function is called.
|
|
let g:ExtraVimCount = g:ExtraVimCount + 1
|
|
|
|
" Disable folds to prevent that the ranges in the ":write" commands below
|
|
" are extended up to the end of a closed fold. This also speeds things up
|
|
" considerably.
|
|
set nofoldenable
|
|
|
|
" Open a buffer for this test script and copy the test environment to
|
|
" a temporary file. Take account of parts relevant for the extra script
|
|
" execution only.
|
|
let current_buffnr = bufnr("%")
|
|
execute "view +1" g:ExtraVimBase
|
|
if g:ExtraVimCount == 1
|
|
let g:ExtraVimTestEnv = tempname()
|
|
execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w"
|
|
\ g:ExtraVimTestEnv "|']+"
|
|
execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>"
|
|
\ g:ExtraVimTestEnv "|']+"
|
|
execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>"
|
|
\ g:ExtraVimTestEnv "|']+"
|
|
execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>"
|
|
\ g:ExtraVimTestEnv "|']+"
|
|
endif
|
|
|
|
" Start the extra Vim script with a ":source" command for the test
|
|
" environment. The source line number where the extra script will be
|
|
" appended, needs to be passed as variable "ExtraVimBegin" to the script.
|
|
let extra_script = tempname()
|
|
exec "!echo 'source " . g:ExtraVimTestEnv . "' >" . extra_script
|
|
let extra_begin = 1
|
|
|
|
" Starting behind the test environment, skip over the first g:ExtraVimCount
|
|
" occurrences of "if ExtraVim()" and copy the following lines up to the
|
|
" matching "endif" to the extra Vim script.
|
|
execute "/E" . "ND_OF_TEST_ENVIRONMENT/"
|
|
exec 'norm ' . g:ExtraVimCount . '/^\s*if\s\+ExtraVim(.*)/+' . "\n"
|
|
execute ".,/^endif/-write >>" . extra_script
|
|
|
|
" Open a buffer for the extra Vim script, delete all ^", and write the
|
|
" script if was actually modified.
|
|
execute "edit +" . (extra_begin + 1) extra_script
|
|
,$s/^"//e
|
|
update
|
|
|
|
" Count the INTERRUPTs and build the breakpoint and quit commands.
|
|
let breakpoints = ""
|
|
let debug_quits = ""
|
|
let in_func = 0
|
|
exec extra_begin
|
|
while search(
|
|
\ '"\s*INTERRUPT\h\@!\|^\s*fu\%[nction]\>!\=\s*\%(\u\|s:\)\w*\s*(\|'
|
|
\ . '^\s*\\\|^\s*endf\%[unction]\>\|'
|
|
\ . '\%(^\s*fu\%[nction]!\=\s*\)\@<!\%(\u\|s:\)\w*\s*(\|'
|
|
\ . 'ExecAsScript\s\+\%(\u\|s:\)\w*',
|
|
\ "W") > 0
|
|
let theline = getline(".")
|
|
if theline =~ '^\s*fu'
|
|
" Function definition.
|
|
let in_func = 1
|
|
let func_start = line(".")
|
|
let func_name = substitute(theline,
|
|
\ '^\s*fu\%[nction]!\=\s*\(\%(\u\|s:\)\w*\).*', '\1', "")
|
|
elseif theline =~ '^\s*endf'
|
|
" End of function definition.
|
|
let in_func = 0
|
|
else
|
|
let finding = substitute(theline, '.*\(\%' . col(".") . 'c.*\)',
|
|
\ '\1', "")
|
|
if finding =~ '^"\s*INTERRUPT\h\@!'
|
|
" Interrupt comment. Compose as many quit commands as
|
|
" specified.
|
|
let cnt = substitute(finding,
|
|
\ '^"\s*INTERRUPT\s*\(\d*\).*$', '\1', "")
|
|
let quits = ""
|
|
while cnt > 0
|
|
" Use "\r" rather than "\n" to separate the quit commands.
|
|
" "\r" is not interpreted as command separator by the ":!"
|
|
" command below but works to separate commands in the
|
|
" external vim.
|
|
let quits = quits . "q\r"
|
|
let cnt = cnt - 1
|
|
endwhile
|
|
if in_func
|
|
" Add the function breakpoint and note the number of quits
|
|
" to be used, if specified, or one for every call else.
|
|
let breakpoints = breakpoints . " -c 'breakadd func " .
|
|
\ (line(".") - func_start) . " " .
|
|
\ func_name . "'"
|
|
if quits != ""
|
|
let debug_quits = debug_quits . quits
|
|
elseif !exists("quits{func_name}")
|
|
let quits{func_name} = "q\r"
|
|
else
|
|
let quits{func_name} = quits{func_name} . "q\r"
|
|
endif
|
|
else
|
|
" Add the file breakpoint and the quits to be used for it.
|
|
let breakpoints = breakpoints . " -c 'breakadd file " .
|
|
\ line(".") . " " . extra_script . "'"
|
|
if quits == ""
|
|
let quits = "q\r"
|
|
endif
|
|
let debug_quits = debug_quits . quits
|
|
endif
|
|
else
|
|
" Add the quits to be used for calling the function or executing
|
|
" it as script file.
|
|
if finding =~ '^ExecAsScript'
|
|
" Sourcing function as script.
|
|
let finding = substitute(finding,
|
|
\ '^ExecAsScript\s\+\(\%(\u\|s:\)\w*\).*', '\1', "")
|
|
else
|
|
" Function call.
|
|
let finding = substitute(finding,
|
|
\ '^\(\%(\u\|s:\)\w*\).*', '\1', "")
|
|
endif
|
|
if exists("quits{finding}")
|
|
let debug_quits = debug_quits . quits{finding}
|
|
endif
|
|
endif
|
|
endif
|
|
endwhile
|
|
|
|
" Close the buffer for the script and create an (empty) resultfile.
|
|
bwipeout
|
|
let resultfile = tempname()
|
|
exec "!>" . resultfile
|
|
|
|
" Run the script in an extra vim. Switch to extra modus by passing the
|
|
" resultfile in ExtraVimResult. Redirect messages to the file specified as
|
|
" argument if any. Use ":debuggreedy" so that the commands provided on the
|
|
" pipe are consumed at the debug prompt. Use "-N" to enable command-line
|
|
" continuation ("C" in 'cpo'). Add "nviminfo" to 'viminfo' to avoid
|
|
" messing up the user's viminfo file.
|
|
let redirect = a:0 ?
|
|
\ " -c 'au VimLeave * redir END' -c 'redir\\! >" . a:1 . "'" : ""
|
|
exec "!echo '" . debug_quits . "q' | $NVIM_PRG -u NONE -N -es" . redirect .
|
|
\ " -c 'debuggreedy|set viminfo+=nviminfo'" .
|
|
\ " -c 'let ExtraVimBegin = " . extra_begin . "'" .
|
|
\ " -c 'let ExtraVimResult = \"" . resultfile . "\"'" . breakpoints .
|
|
\ " -S " . extra_script
|
|
|
|
" Build the resulting sum for resultfile and add it to g:Xpath. Add Xout
|
|
" information provided by the extra Vim process to the test output.
|
|
let sum = 0
|
|
exec "edit" resultfile
|
|
let line = 1
|
|
while line <= line("$")
|
|
let theline = getline(line)
|
|
if theline =~ '^@R:'
|
|
exec 'Xout "' . substitute(substitute(
|
|
\ escape(escape(theline, '"'), '\"'),
|
|
\ '^@R:', '', ""), '@NL@', "\n", "g") . '"'
|
|
else
|
|
let sum = sum + getline(line)
|
|
endif
|
|
let line = line + 1
|
|
endwhile
|
|
bwipeout
|
|
let g:Xpath = g:Xpath + sum
|
|
|
|
" Delete the extra script and the resultfile.
|
|
call delete(extra_script)
|
|
call delete(resultfile)
|
|
|
|
" Switch back to the buffer that was active when this function was entered.
|
|
exec "buffer" current_buffnr
|
|
|
|
" Return 0. This protects extra scripts from being run in the main Vim
|
|
" process.
|
|
return 0
|
|
endfunction
|
|
|
|
|
|
" ExtraVimThrowpoint() - Relative throwpoint in ExtraVim script {{{2
|
|
"
|
|
" Evaluates v:throwpoint and returns the throwpoint relative to the beginning of
|
|
" an ExtraVim script as passed by ExtraVim() in ExtraVimBegin.
|
|
"
|
|
" EXTRA_VIM_START - do not change or remove this line.
|
|
function! ExtraVimThrowpoint()
|
|
if !exists("g:ExtraVimBegin")
|
|
Xout "ExtraVimThrowpoint() used outside ExtraVim() script."
|
|
return v:throwpoint
|
|
endif
|
|
|
|
if v:throwpoint =~ '^function\>'
|
|
return v:throwpoint
|
|
endif
|
|
|
|
return "line " .
|
|
\ (substitute(v:throwpoint, '.*, line ', '', "") - g:ExtraVimBegin) .
|
|
\ " of ExtraVim() script"
|
|
endfunction
|
|
" EXTRA_VIM_STOP - do not change or remove this line.
|
|
|
|
|
|
" MakeScript() - Make a script file from a function. {{{2
|
|
"
|
|
" Create a script that consists of the body of the function a:funcname.
|
|
" Replace any ":return" by a ":finish", any argument variable by a global
|
|
" variable, and and every ":call" by a ":source" for the next following argument
|
|
" in the variable argument list. This function is useful if similar tests are
|
|
" to be made for a ":return" from a function call or a ":finish" in a script
|
|
" file.
|
|
"
|
|
" In order to execute a function specifying an INTERRUPT location (see ExtraVim)
|
|
" as a script file, use ExecAsScript below.
|
|
"
|
|
" EXTRA_VIM_START - do not change or remove this line.
|
|
function! MakeScript(funcname, ...)
|
|
let script = tempname()
|
|
execute "redir! >" . script
|
|
execute "function" a:funcname
|
|
redir END
|
|
execute "edit" script
|
|
" Delete the "function" and the "endfunction" lines. Do not include the
|
|
" word "function" in the pattern since it might be translated if LANG is
|
|
" set. When MakeScript() is being debugged, this deletes also the debugging
|
|
" output of its line 3 and 4.
|
|
exec '1,/.*' . a:funcname . '(.*)/d'
|
|
/^\d*\s*endfunction\>/,$d
|
|
%s/^\d*//e
|
|
%s/return/finish/e
|
|
%s/\<a:\(\h\w*\)/g:\1/ge
|
|
normal gg0
|
|
let cnt = 0
|
|
while search('\<call\s*\%(\u\|s:\)\w*\s*(.*)', 'W') > 0
|
|
let cnt = cnt + 1
|
|
s/\<call\s*\%(\u\|s:\)\w*\s*(.*)/\='source ' . a:{cnt}/
|
|
endwhile
|
|
g/^\s*$/d
|
|
write
|
|
bwipeout
|
|
return script
|
|
endfunction
|
|
" EXTRA_VIM_STOP - do not change or remove this line.
|
|
|
|
|
|
" ExecAsScript - Source a temporary script made from a function. {{{2
|
|
"
|
|
" Make a temporary script file from the function a:funcname, ":source" it, and
|
|
" delete it afterwards.
|
|
"
|
|
" When inside ":if ExtraVim()", add a file breakpoint for each INTERRUPT
|
|
" location specified in the function.
|
|
"
|
|
" EXTRA_VIM_START - do not change or remove this line.
|
|
function! ExecAsScript(funcname)
|
|
" Make a script from the function passed as argument.
|
|
let script = MakeScript(a:funcname)
|
|
|
|
" When running in an extra Vim process, add a file breakpoint for each
|
|
" function breakpoint set when the extra Vim process was invoked by
|
|
" ExtraVim().
|
|
if exists("g:ExtraVimResult")
|
|
let bplist = tempname()
|
|
execute "redir! >" . bplist
|
|
breaklist
|
|
redir END
|
|
execute "edit" bplist
|
|
" Get the line number from the function breakpoint. Works also when
|
|
" LANG is set.
|
|
execute 'v/^\s*\d\+\s\+func\s\+' . a:funcname . '\s.*/d'
|
|
%s/^\s*\d\+\s\+func\s\+\%(\u\|s:\)\w*\s\D*\(\d*\).*/\1/e
|
|
let cnt = 0
|
|
while cnt < line("$")
|
|
let cnt = cnt + 1
|
|
if getline(cnt) != ""
|
|
execute "breakadd file" getline(cnt) script
|
|
endif
|
|
endwhile
|
|
bwipeout!
|
|
call delete(bplist)
|
|
endif
|
|
|
|
" Source and delete the script.
|
|
exec "source" script
|
|
call delete(script)
|
|
endfunction
|
|
|
|
com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
|
|
" EXTRA_VIM_STOP - do not change or remove this line.
|
|
|
|
|
|
" END_OF_TEST_ENVIRONMENT - do not change or remove this line.
|
|
|
|
|
|
" Tests 1 to 15 were moved to test_vimscript.vim
|
|
let Xtest = 16
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 16: Double :else or :elseif after :else {{{1
|
|
"
|
|
" Multiple :elses or an :elseif after an :else are forbidden.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! F() abort
|
|
if 0
|
|
Xpath 1 " X: 0
|
|
else
|
|
Xpath 2 " X: 2
|
|
else " aborts function
|
|
Xpath 4 " X: 0
|
|
endif
|
|
endfunction
|
|
|
|
function! G() abort
|
|
if 0
|
|
Xpath 8 " X: 0
|
|
else
|
|
Xpath 16 " X: 16
|
|
elseif 1 " aborts function
|
|
Xpath 32 " X: 0
|
|
else
|
|
Xpath 64 " X: 0
|
|
endif
|
|
endfunction
|
|
|
|
function! H() abort
|
|
if 0
|
|
Xpath 128 " X: 0
|
|
elseif 0
|
|
Xpath 256 " X: 0
|
|
else
|
|
Xpath 512 " X: 512
|
|
else " aborts function
|
|
Xpath 1024 " X: 0
|
|
endif
|
|
endfunction
|
|
|
|
function! I() abort
|
|
if 0
|
|
Xpath 2048 " X: 0
|
|
elseif 0
|
|
Xpath 4096 " X: 0
|
|
else
|
|
Xpath 8192 " X: 8192
|
|
elseif 1 " aborts function
|
|
Xpath 16384 " X: 0
|
|
else
|
|
Xpath 32768 " X: 0
|
|
endif
|
|
endfunction
|
|
|
|
call F()
|
|
call G()
|
|
call H()
|
|
call I()
|
|
|
|
delfunction F
|
|
delfunction G
|
|
delfunction H
|
|
delfunction I
|
|
|
|
Xcheck 8722
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1
|
|
"
|
|
" The :while/:endwhile takes precedence in nesting over an unclosed
|
|
" :if or an unopened :endif.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! MSG(enr, emsg)
|
|
let english = v:lang == "C" || v:lang =~ '^[Ee]n'
|
|
if a:enr == ""
|
|
Xout "TODO: Add message number for:" a:emsg
|
|
let v:errmsg = ":" . v:errmsg
|
|
endif
|
|
let match = 1
|
|
if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
|
|
let match = 0
|
|
if v:errmsg == ""
|
|
Xout "Message missing."
|
|
else
|
|
let v:errmsg = escape(v:errmsg, '"')
|
|
Xout "Unexpected message:" v:errmsg
|
|
endif
|
|
endif
|
|
return match
|
|
endfunction
|
|
|
|
let messages = ""
|
|
|
|
" While loops inside a function are continued on error.
|
|
function! F()
|
|
let v:errmsg = ""
|
|
XloopINIT 1 16
|
|
let loops = 3
|
|
while loops > 0
|
|
let loops = loops - 1 " 2: 1: 0:
|
|
Xloop 1 " X: 1 + 1*16 + 1*16*16
|
|
if (loops == 1)
|
|
Xloop 2 " X: 2*16
|
|
XloopNEXT
|
|
continue
|
|
elseif (loops == 0)
|
|
Xloop 4 " X: 4*16*16
|
|
break
|
|
elseif 1
|
|
Xloop 8 " X: 8
|
|
XloopNEXT
|
|
" endif missing!
|
|
endwhile " :endwhile after :if 1
|
|
Xpath 4096 " X: 16*16*16
|
|
if MSG('E171', "Missing :endif")
|
|
let g:messages = g:messages . "A"
|
|
endif
|
|
|
|
let v:errmsg = ""
|
|
XloopINIT! 8192 4
|
|
let loops = 2
|
|
while loops > 0 " 2: 1:
|
|
XloopNEXT
|
|
let loops = loops - 1
|
|
Xloop 1 " X: 8192 + 8192*4
|
|
if 0
|
|
Xloop 2 " X: 0
|
|
" endif missing
|
|
endwhile " :endwhile after :if 0
|
|
Xpath 131072 " X: 8192*4*4
|
|
if MSG('E171', "Missing :endif")
|
|
let g:messages = g:messages . "B"
|
|
endif
|
|
|
|
let v:errmsg = ""
|
|
XloopINIT 262144 4
|
|
let loops = 2
|
|
while loops > 0 " 2: 1:
|
|
let loops = loops - 1
|
|
Xloop 1 " X: 262144 + 262144 * 4
|
|
" if missing!
|
|
endif " :endif without :if in while
|
|
Xloop 2 " X: 524288 + 524288 * 4
|
|
XloopNEXT
|
|
endwhile
|
|
Xpath 4194304 " X: 262144*4*4
|
|
if MSG('E580', ":endif without :if")
|
|
let g:messages = g:messages . "C"
|
|
endif
|
|
endfunction
|
|
|
|
call F()
|
|
|
|
" Error continuation outside a function is at the outermost :endwhile or :endif.
|
|
let v:errmsg = ""
|
|
XloopINIT! 8388608 4
|
|
let loops = 2
|
|
while loops > 0 " 2: 1:
|
|
XloopNEXT
|
|
let loops = loops - 1
|
|
Xloop 1 " X: 8388608 + 0 * 4
|
|
if 0
|
|
Xloop 2 " X: 0
|
|
" endif missing! Following :endwhile fails.
|
|
endwhile | Xpath 134217728 " X: 0
|
|
Xpath 268435456 " X: 2*8388608*4*4
|
|
if MSG('E171', "Missing :endif")
|
|
let messages = g:messages . "D"
|
|
endif
|
|
|
|
if messages != "ABCD"
|
|
Xpath 536870912 " X: 0
|
|
Xout "messages is" messages "instead of ABCD"
|
|
endif
|
|
|
|
unlet loops messages
|
|
delfunction F
|
|
delfunction MSG
|
|
|
|
Xcheck 285127993
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 18: Interrupt (Ctrl-C pressed) {{{1
|
|
"
|
|
" On an interrupt, the script processing is terminated immediately.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
if 1
|
|
Xpath 1 " X: 1
|
|
while 1
|
|
Xpath 2 " X: 2
|
|
if 1
|
|
Xpath 4 " X: 4
|
|
"INTERRUPT
|
|
Xpath 8 " X: 0
|
|
break
|
|
finish
|
|
endif | Xpath 16 " X: 0
|
|
Xpath 32 " X: 0
|
|
endwhile | Xpath 64 " X: 0
|
|
Xpath 128 " X: 0
|
|
endif | Xpath 256 " X: 0
|
|
Xpath 512 " X: 0
|
|
endif
|
|
|
|
if ExtraVim()
|
|
try
|
|
Xpath 1024 " X: 1024
|
|
"INTERRUPT
|
|
Xpath 2048 " X: 0
|
|
endtry | Xpath 4096 " X: 0
|
|
Xpath 8192 " X: 0
|
|
endif
|
|
|
|
if ExtraVim()
|
|
function! F()
|
|
if 1
|
|
Xpath 16384 " X: 16384
|
|
while 1
|
|
Xpath 32768 " X: 32768
|
|
if 1
|
|
Xpath 65536 " X: 65536
|
|
"INTERRUPT
|
|
Xpath 131072 " X: 0
|
|
break
|
|
return
|
|
endif | Xpath 262144 " X: 0
|
|
Xpath Xpath 524288 " X: 0
|
|
endwhile | Xpath 1048576 " X: 0
|
|
Xpath Xpath 2097152 " X: 0
|
|
endif | Xpath Xpath 4194304 " X: 0
|
|
Xpath Xpath 8388608 " X: 0
|
|
endfunction
|
|
|
|
call F() | Xpath 16777216 " X: 0
|
|
Xpath 33554432 " X: 0
|
|
endif
|
|
|
|
if ExtraVim()
|
|
function! G()
|
|
try
|
|
Xpath 67108864 " X: 67108864
|
|
"INTERRUPT
|
|
Xpath 134217728 " X: 0
|
|
endtry | Xpath 268435456 " X: 0
|
|
Xpath 536870912 " X: 0
|
|
endfunction
|
|
|
|
call G() | Xpath 1073741824 " X: 0
|
|
" The Xpath command does not accept 2^31 (negative); display explicitly:
|
|
exec "!echo 2147483648 >>" . g:ExtraVimResult
|
|
" X: 0
|
|
endif
|
|
|
|
Xcheck 67224583
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 19: Aborting on errors inside :try/:endtry {{{1
|
|
"
|
|
" An error in a command dynamically enclosed in a :try/:endtry region
|
|
" aborts script processing immediately. It does not matter whether
|
|
" the failing command is outside or inside a function and whether a
|
|
" function has an "abort" attribute.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
function! F() abort
|
|
Xpath 1 " X: 1
|
|
asdf
|
|
Xpath 2 " X: 0
|
|
endfunction
|
|
|
|
try
|
|
Xpath 4 " X: 4
|
|
call F()
|
|
Xpath 8 " X: 0
|
|
endtry | Xpath 16 " X: 0
|
|
Xpath 32 " X: 0
|
|
endif
|
|
|
|
if ExtraVim()
|
|
function! G()
|
|
Xpath 64 " X: 64
|
|
asdf
|
|
Xpath 128 " X: 0
|
|
endfunction
|
|
|
|
try
|
|
Xpath 256 " X: 256
|
|
call G()
|
|
Xpath 512 " X: 0
|
|
endtry | Xpath 1024 " X: 0
|
|
Xpath 2048 " X: 0
|
|
endif
|
|
|
|
if ExtraVim()
|
|
try
|
|
Xpath 4096 " X: 4096
|
|
asdf
|
|
Xpath 8192 " X: 0
|
|
endtry | Xpath 16384 " X: 0
|
|
Xpath 32768 " X: 0
|
|
endif
|
|
|
|
if ExtraVim()
|
|
if 1
|
|
try
|
|
Xpath 65536 " X: 65536
|
|
asdf
|
|
Xpath 131072 " X: 0
|
|
endtry | Xpath 262144 " X: 0
|
|
endif | Xpath 524288 " X: 0
|
|
Xpath 1048576 " X: 0
|
|
endif
|
|
|
|
if ExtraVim()
|
|
let p = 1
|
|
while p
|
|
let p = 0
|
|
try
|
|
Xpath 2097152 " X: 2097152
|
|
asdf
|
|
Xpath 4194304 " X: 0
|
|
endtry | Xpath 8388608 " X: 0
|
|
endwhile | Xpath 16777216 " X: 0
|
|
Xpath 33554432 " X: 0
|
|
endif
|
|
|
|
if ExtraVim()
|
|
let p = 1
|
|
while p
|
|
let p = 0
|
|
" try
|
|
Xpath 67108864 " X: 67108864
|
|
endwhile | Xpath 134217728 " X: 0
|
|
Xpath 268435456 " X: 0
|
|
endif
|
|
|
|
Xcheck 69275973
|
|
"-------------------------------------------------------------------------------
|
|
" Test 20: Aborting on errors after :try/:endtry {{{1
|
|
"
|
|
" When an error occurs after the last active :try/:endtry region has
|
|
" been left, termination behavior is as if no :try/:endtry has been
|
|
" seen.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
let p = 1
|
|
while p
|
|
let p = 0
|
|
try
|
|
Xpath 1 " X: 1
|
|
endtry
|
|
asdf
|
|
endwhile | Xpath 2 " X: 0
|
|
Xpath 4 " X: 4
|
|
endif
|
|
|
|
if ExtraVim()
|
|
while 1
|
|
try
|
|
Xpath 8 " X: 8
|
|
break
|
|
Xpath 16 " X: 0
|
|
endtry
|
|
endwhile
|
|
Xpath 32 " X: 32
|
|
asdf
|
|
Xpath 64 " X: 64
|
|
endif
|
|
|
|
if ExtraVim()
|
|
while 1
|
|
try
|
|
Xpath 128 " X: 128
|
|
break
|
|
Xpath 256 " X: 0
|
|
finally
|
|
Xpath 512 " X: 512
|
|
endtry
|
|
endwhile
|
|
Xpath 1024 " X: 1024
|
|
asdf
|
|
Xpath 2048 " X: 2048
|
|
endif
|
|
|
|
if ExtraVim()
|
|
while 1
|
|
try
|
|
Xpath 4096 " X: 4096
|
|
finally
|
|
Xpath 8192 " X: 8192
|
|
break
|
|
Xpath 16384 " X: 0
|
|
endtry
|
|
endwhile
|
|
Xpath 32768 " X: 32768
|
|
asdf
|
|
Xpath 65536 " X: 65536
|
|
endif
|
|
|
|
if ExtraVim()
|
|
let p = 1
|
|
while p
|
|
let p = 0
|
|
try
|
|
Xpath 131072 " X: 131072
|
|
continue
|
|
Xpath 262144 " X: 0
|
|
endtry
|
|
endwhile
|
|
Xpath 524288 " X: 524288
|
|
asdf
|
|
Xpath 1048576 " X: 1048576
|
|
endif
|
|
|
|
if ExtraVim()
|
|
let p = 1
|
|
while p
|
|
let p = 0
|
|
try
|
|
Xpath 2097152 " X: 2097152
|
|
continue
|
|
Xpath 4194304 " X: 0
|
|
finally
|
|
Xpath 8388608 " X: 8388608
|
|
endtry
|
|
endwhile
|
|
Xpath 16777216 " X: 16777216
|
|
asdf
|
|
Xpath 33554432 " X: 33554432
|
|
endif
|
|
|
|
if ExtraVim()
|
|
let p = 1
|
|
while p
|
|
let p = 0
|
|
try
|
|
Xpath 67108864 " X: 67108864
|
|
finally
|
|
Xpath 134217728 " X: 134217728
|
|
continue
|
|
Xpath 268435456 " X: 0
|
|
endtry
|
|
endwhile
|
|
Xpath 536870912 " X: 536870912
|
|
asdf
|
|
Xpath 1073741824 " X: 1073741824
|
|
endif
|
|
|
|
Xcheck 1874575085
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1
|
|
"
|
|
" If a :try conditional stays inactive due to a preceding :continue,
|
|
" :break, :return, or :finish, its :finally clause should not be
|
|
" executed.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
function F()
|
|
let loops = 2
|
|
XloopINIT! 1 256
|
|
while loops > 0
|
|
XloopNEXT
|
|
let loops = loops - 1
|
|
try
|
|
if loops == 1
|
|
Xloop 1 " X: 1
|
|
continue
|
|
Xloop 2 " X: 0
|
|
elseif loops == 0
|
|
Xloop 4 " X: 4*256
|
|
break
|
|
Xloop 8 " X: 0
|
|
endif
|
|
|
|
try " inactive
|
|
Xloop 16 " X: 0
|
|
finally
|
|
Xloop 32 " X: 0
|
|
endtry
|
|
finally
|
|
Xloop 64 " X: 64 + 64*256
|
|
endtry
|
|
Xloop 128 " X: 0
|
|
endwhile
|
|
|
|
try
|
|
Xpath 65536 " X: 65536
|
|
return
|
|
Xpath 131072 " X: 0
|
|
try " inactive
|
|
Xpath 262144 " X: 0
|
|
finally
|
|
Xpath 524288 " X: 0
|
|
endtry
|
|
finally
|
|
Xpath 1048576 " X: 1048576
|
|
endtry
|
|
Xpath 2097152 " X: 0
|
|
endfunction
|
|
|
|
try
|
|
Xpath 4194304 " X: 4194304
|
|
call F()
|
|
Xpath 8388608 " X: 8388608
|
|
finish
|
|
Xpath 16777216 " X: 0
|
|
try " inactive
|
|
Xpath 33554432 " X: 0
|
|
finally
|
|
Xpath 67108864 " X: 0
|
|
endtry
|
|
finally
|
|
Xpath 134217728 " X: 134217728
|
|
endtry
|
|
Xpath 268435456 " X: 0
|
|
endif
|
|
|
|
Xcheck 147932225
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 22: :finally for a :try after an error/interrupt/:throw {{{1
|
|
"
|
|
" If a :try conditional stays inactive due to a preceding error or
|
|
" interrupt or :throw, its :finally clause should not be executed.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
function! Error()
|
|
try
|
|
asdf " aborting error, triggering error exception
|
|
endtry
|
|
endfunction
|
|
|
|
Xpath 1 " X: 1
|
|
call Error()
|
|
Xpath 2 " X: 0
|
|
|
|
if 1 " not active due to error
|
|
try " not active since :if inactive
|
|
Xpath 4 " X: 0
|
|
finally
|
|
Xpath 8 " X: 0
|
|
endtry
|
|
endif
|
|
|
|
try " not active due to error
|
|
Xpath 16 " X: 0
|
|
finally
|
|
Xpath 32 " X: 0
|
|
endtry
|
|
endif
|
|
|
|
if ExtraVim()
|
|
function! Interrupt()
|
|
try
|
|
"INTERRUPT " triggering interrupt exception
|
|
endtry
|
|
endfunction
|
|
|
|
Xpath 64 " X: 64
|
|
call Interrupt()
|
|
Xpath 128 " X: 0
|
|
|
|
if 1 " not active due to interrupt
|
|
try " not active since :if inactive
|
|
Xpath 256 " X: 0
|
|
finally
|
|
Xpath 512 " X: 0
|
|
endtry
|
|
endif
|
|
|
|
try " not active due to interrupt
|
|
Xpath 1024 " X: 0
|
|
finally
|
|
Xpath 2048 " X: 0
|
|
endtry
|
|
endif
|
|
|
|
if ExtraVim()
|
|
function! Throw()
|
|
throw "xyz"
|
|
endfunction
|
|
|
|
Xpath 4096 " X: 4096
|
|
call Throw()
|
|
Xpath 8192 " X: 0
|
|
|
|
if 1 " not active due to :throw
|
|
try " not active since :if inactive
|
|
Xpath 16384 " X: 0
|
|
finally
|
|
Xpath 32768 " X: 0
|
|
endtry
|
|
endif
|
|
|
|
try " not active due to :throw
|
|
Xpath 65536 " X: 0
|
|
finally
|
|
Xpath 131072 " X: 0
|
|
endtry
|
|
endif
|
|
|
|
Xcheck 4161
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 23: :catch clauses for a :try after a :throw {{{1
|
|
"
|
|
" If a :try conditional stays inactive due to a preceding :throw,
|
|
" none of its :catch clauses should be executed.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
try
|
|
Xpath 1 " X: 1
|
|
throw "xyz"
|
|
Xpath 2 " X: 0
|
|
|
|
if 1 " not active due to :throw
|
|
try " not active since :if inactive
|
|
Xpath 4 " X: 0
|
|
catch /xyz/
|
|
Xpath 8 " X: 0
|
|
endtry
|
|
endif
|
|
catch /xyz/
|
|
Xpath 16 " X: 16
|
|
endtry
|
|
|
|
Xpath 32 " X: 32
|
|
throw "abc"
|
|
Xpath 64 " X: 0
|
|
|
|
try " not active due to :throw
|
|
Xpath 128 " X: 0
|
|
catch /abc/
|
|
Xpath 256 " X: 0
|
|
endtry
|
|
endif
|
|
|
|
Xcheck 49
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 24: :endtry for a :try after a :throw {{{1
|
|
"
|
|
" If a :try conditional stays inactive due to a preceding :throw,
|
|
" its :endtry should not rethrow the exception to the next surrounding
|
|
" active :try conditional.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
try " try 1
|
|
try " try 2
|
|
Xpath 1 " X: 1
|
|
throw "xyz" " makes try 2 inactive
|
|
Xpath 2 " X: 0
|
|
|
|
try " try 3
|
|
Xpath 4 " X: 0
|
|
endtry " no rethrow to try 1
|
|
catch /xyz/ " should catch although try 2 inactive
|
|
Xpath 8 " X: 8
|
|
endtry
|
|
catch /xyz/ " try 1 active, but exception already caught
|
|
Xpath 16 " X: 0
|
|
endtry
|
|
Xpath 32 " X: 32
|
|
endif
|
|
|
|
Xcheck 41
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 25: Executing :finally clauses on normal control flow {{{1
|
|
"
|
|
" Control flow in a :try conditional should always fall through to its
|
|
" :finally clause. A :finally clause of a :try conditional inside an
|
|
" inactive conditional should never be executed.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! F()
|
|
let loops = 3
|
|
XloopINIT 1 256
|
|
while loops > 0 " 3: 2: 1:
|
|
Xloop 1 " X: 1 + 1*256 + 1*256*256
|
|
if loops >= 2
|
|
try
|
|
Xloop 2 " X: 2 + 2*256
|
|
if loops == 2
|
|
try
|
|
Xloop 4 " X: 4*256
|
|
finally
|
|
Xloop 8 " X: 8*256
|
|
endtry
|
|
endif
|
|
finally
|
|
Xloop 16 " X: 16 + 16*256
|
|
if loops == 2
|
|
try
|
|
Xloop 32 " X: 32*256
|
|
finally
|
|
Xloop 64 " X: 64*256
|
|
endtry
|
|
endif
|
|
endtry
|
|
endif
|
|
Xloop 128 " X: 128 + 128*256 + 128*256*256
|
|
let loops = loops - 1
|
|
XloopNEXT
|
|
endwhile
|
|
Xpath 16777216 " X: 16777216
|
|
endfunction
|
|
|
|
if 1
|
|
try
|
|
Xpath 33554432 " X: 33554432
|
|
call F()
|
|
Xpath 67108864 " X: 67108864
|
|
finally
|
|
Xpath 134217728 " X: 134217728
|
|
endtry
|
|
else
|
|
try
|
|
Xpath 268435456 " X: 0
|
|
finally
|
|
Xpath 536870912 " X: 0
|
|
endtry
|
|
endif
|
|
|
|
delfunction F
|
|
|
|
Xcheck 260177811
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 26: Executing :finally clauses after :continue or :break {{{1
|
|
"
|
|
" For a :continue or :break dynamically enclosed in a :try/:endtry
|
|
" region inside the next surrounding :while/:endwhile, if the
|
|
" :continue/:break is before the :finally, the :finally clause is
|
|
" executed first. If the :continue/:break is after the :finally, the
|
|
" :finally clause is broken (like an :if/:endif region).
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
try
|
|
let loops = 3
|
|
XloopINIT! 1 32
|
|
while loops > 0
|
|
XloopNEXT
|
|
try
|
|
try
|
|
if loops == 2 " 3: 2: 1:
|
|
Xloop 1 " X: 1*32
|
|
let loops = loops - 1
|
|
continue
|
|
elseif loops == 1
|
|
Xloop 2 " X: 2*32*32
|
|
break
|
|
finish
|
|
endif
|
|
Xloop 4 " X: 4
|
|
endtry
|
|
finally
|
|
Xloop 8 " X: 8 + 8*32 + 8*32*32
|
|
endtry
|
|
Xloop 16 " X: 16
|
|
let loops = loops - 1
|
|
endwhile
|
|
Xpath 32768 " X: 32768
|
|
finally
|
|
Xpath 65536 " X: 65536
|
|
let loops = 3
|
|
XloopINIT 131072 16
|
|
while loops > 0
|
|
try
|
|
finally
|
|
try
|
|
if loops == 2
|
|
Xloop 1 " X: 131072*16
|
|
let loops = loops - 1
|
|
XloopNEXT
|
|
continue
|
|
elseif loops == 1
|
|
Xloop 2 " X: 131072*2*16*16
|
|
break
|
|
finish
|
|
endif
|
|
endtry
|
|
Xloop 4 " X: 131072*4
|
|
endtry
|
|
Xloop 8 " X: 131072*8
|
|
let loops = loops - 1
|
|
XloopNEXT
|
|
endwhile
|
|
Xpath 536870912 " X: 536870912
|
|
endtry
|
|
Xpath 1073741824 " X: 1073741824
|
|
|
|
unlet loops
|
|
|
|
Xcheck 1681500476
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 27: Executing :finally clauses after :return {{{1
|
|
"
|
|
" For a :return command dynamically enclosed in a :try/:endtry region,
|
|
" :finally clauses are executed and the called function is ended.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! F()
|
|
try
|
|
Xpath 1 " X: 1
|
|
try
|
|
Xpath 2 " X: 2
|
|
return
|
|
Xpath 4 " X: 0
|
|
finally
|
|
Xpath 8 " X: 8
|
|
endtry
|
|
Xpath 16 " X: 0
|
|
finally
|
|
Xpath 32 " X: 32
|
|
endtry
|
|
Xpath 64 " X: 0
|
|
endfunction
|
|
|
|
function! G()
|
|
try
|
|
Xpath 128 " X: 128
|
|
return
|
|
Xpath 256 " X: 0
|
|
finally
|
|
Xpath 512 " X: 512
|
|
call F()
|
|
Xpath 1024 " X: 1024
|
|
endtry
|
|
Xpath 2048 " X: 0
|
|
endfunction
|
|
|
|
function! H()
|
|
try
|
|
Xpath 4096 " X: 4096
|
|
call G()
|
|
Xpath 8192 " X: 8192
|
|
finally
|
|
Xpath 16384 " X: 16384
|
|
return
|
|
Xpath 32768 " X: 0
|
|
endtry
|
|
Xpath 65536 " X: 0
|
|
endfunction
|
|
|
|
try
|
|
Xpath 131072 " X: 131072
|
|
call H()
|
|
Xpath 262144 " X: 262144
|
|
finally
|
|
Xpath 524288 " X: 524288
|
|
endtry
|
|
Xpath 1048576 " X: 1048576
|
|
|
|
Xcheck 1996459
|
|
|
|
" Leave F, G, and H for execution as scripts in the next test.
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 28: Executing :finally clauses after :finish {{{1
|
|
"
|
|
" For a :finish command dynamically enclosed in a :try/:endtry region,
|
|
" :finally clauses are executed and the sourced file is finished.
|
|
"
|
|
" This test executes the bodies of the functions F, G, and H from the
|
|
" previous test as script files (:return replaced by :finish).
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
let scriptF = MakeScript("F") " X: 1 + 2 + 8 + 32
|
|
let scriptG = MakeScript("G", scriptF) " X: 128 + 512 + 1024
|
|
let scriptH = MakeScript("H", scriptG) " X: 4096 + 8192 + 16384
|
|
|
|
try
|
|
Xpath 131072 " X: 131072
|
|
exec "source" scriptH
|
|
Xpath 262144 " X: 262144
|
|
finally
|
|
Xpath 524288 " X: 524288
|
|
endtry
|
|
Xpath 1048576 " X: 1048576
|
|
|
|
call delete(scriptF)
|
|
call delete(scriptG)
|
|
call delete(scriptH)
|
|
unlet scriptF scriptG scriptH
|
|
delfunction F
|
|
delfunction G
|
|
delfunction H
|
|
|
|
Xcheck 1996459
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 29: Executing :finally clauses on errors {{{1
|
|
"
|
|
" After an error in a command dynamically enclosed in a :try/:endtry
|
|
" region, :finally clauses are executed and the script processing is
|
|
" terminated.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
function! F()
|
|
while 1
|
|
try
|
|
Xpath 1 " X: 1
|
|
while 1
|
|
try
|
|
Xpath 2 " X: 2
|
|
asdf " error
|
|
Xpath 4 " X: 0
|
|
finally
|
|
Xpath 8 " X: 8
|
|
endtry | Xpath 16 " X: 0
|
|
Xpath 32 " X: 0
|
|
break
|
|
endwhile
|
|
Xpath 64 " X: 0
|
|
finally
|
|
Xpath 128 " X: 128
|
|
endtry | Xpath 256 " X: 0
|
|
Xpath 512 " X: 0
|
|
break
|
|
endwhile
|
|
Xpath 1024 " X: 0
|
|
endfunction
|
|
|
|
while 1
|
|
try
|
|
Xpath 2048 " X: 2048
|
|
while 1
|
|
call F()
|
|
Xpath 4096 " X: 0
|
|
break
|
|
endwhile | Xpath 8192 " X: 0
|
|
Xpath 16384 " X: 0
|
|
finally
|
|
Xpath 32768 " X: 32768
|
|
endtry | Xpath 65536 " X: 0
|
|
endwhile | Xpath 131072 " X: 0
|
|
Xpath 262144 " X: 0
|
|
endif
|
|
|
|
if ExtraVim()
|
|
function! G() abort
|
|
if 1
|
|
try
|
|
Xpath 524288 " X: 524288
|
|
asdf " error
|
|
Xpath 1048576 " X: 0
|
|
finally
|
|
Xpath 2097152 " X: 2097152
|
|
endtry | Xpath 4194304 " X: 0
|
|
endif | Xpath 8388608 " X: 0
|
|
Xpath 16777216 " X: 0
|
|
endfunction
|
|
|
|
if 1
|
|
try
|
|
Xpath 33554432 " X: 33554432
|
|
call G()
|
|
Xpath 67108864 " X: 0
|
|
finally
|
|
Xpath 134217728 " X: 134217728
|
|
endtry | Xpath 268435456 " X: 0
|
|
endif | Xpath 536870912 " X: 0
|
|
Xpath 1073741824 " X: 0
|
|
endif
|
|
|
|
Xcheck 170428555
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 30: Executing :finally clauses on interrupt {{{1
|
|
"
|
|
" After an interrupt in a command dynamically enclosed in
|
|
" a :try/:endtry region, :finally clauses are executed and the
|
|
" script processing is terminated.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
XloopINIT 1 16
|
|
|
|
function! F()
|
|
try
|
|
Xloop 1 " X: 1 + 1*16
|
|
"INTERRUPT
|
|
Xloop 2 " X: 0
|
|
finally
|
|
Xloop 4 " X: 4 + 4*16
|
|
endtry
|
|
Xloop 8 " X: 0
|
|
endfunction
|
|
|
|
try
|
|
Xpath 256 " X: 256
|
|
try
|
|
Xpath 512 " X: 512
|
|
"INTERRUPT
|
|
Xpath 1024 " X: 0
|
|
finally
|
|
Xpath 2048 " X: 2048
|
|
try
|
|
Xpath 4096 " X: 4096
|
|
try
|
|
Xpath 8192 " X: 8192
|
|
finally
|
|
Xpath 16384 " X: 16384
|
|
try
|
|
Xpath 32768 " X: 32768
|
|
"INTERRUPT
|
|
Xpath 65536 " X: 0
|
|
endtry
|
|
Xpath 131072 " X: 0
|
|
endtry
|
|
Xpath 262144 " X: 0
|
|
endtry
|
|
Xpath 524288 " X: 0
|
|
endtry
|
|
Xpath 1048576 " X: 0
|
|
finally
|
|
Xpath 2097152 " X: 2097152
|
|
try
|
|
Xpath 4194304 " X: 4194304
|
|
call F()
|
|
Xpath 8388608 " X: 0
|
|
finally
|
|
Xpath 16777216 " X: 16777216
|
|
try
|
|
Xpath 33554432 " X: 33554432
|
|
XloopNEXT
|
|
ExecAsScript F
|
|
Xpath 67108864 " X: 0
|
|
finally
|
|
Xpath 134217728 " X: 134217728
|
|
endtry
|
|
Xpath 268435456 " X: 0
|
|
endtry
|
|
Xpath 536870912 " X: 0
|
|
endtry
|
|
Xpath 1073741824 " X: 0
|
|
endif
|
|
|
|
Xcheck 190905173
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 31: Executing :finally clauses after :throw {{{1
|
|
"
|
|
" After a :throw dynamically enclosed in a :try/:endtry region,
|
|
" :finally clauses are executed and the script processing is
|
|
" terminated.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
XloopINIT 1 16
|
|
|
|
function! F()
|
|
try
|
|
Xloop 1 " X: 1 + 1*16
|
|
throw "exception"
|
|
Xloop 2 " X: 0
|
|
finally
|
|
Xloop 4 " X: 4 + 4*16
|
|
endtry
|
|
Xloop 8 " X: 0
|
|
endfunction
|
|
|
|
try
|
|
Xpath 256 " X: 256
|
|
try
|
|
Xpath 512 " X: 512
|
|
throw "exception"
|
|
Xpath 1024 " X: 0
|
|
finally
|
|
Xpath 2048 " X: 2048
|
|
try
|
|
Xpath 4096 " X: 4096
|
|
try
|
|
Xpath 8192 " X: 8192
|
|
finally
|
|
Xpath 16384 " X: 16384
|
|
try
|
|
Xpath 32768 " X: 32768
|
|
throw "exception"
|
|
Xpath 65536 " X: 0
|
|
endtry
|
|
Xpath 131072 " X: 0
|
|
endtry
|
|
Xpath 262144 " X: 0
|
|
endtry
|
|
Xpath 524288 " X: 0
|
|
endtry
|
|
Xpath 1048576 " X: 0
|
|
finally
|
|
Xpath 2097152 " X: 2097152
|
|
try
|
|
Xpath 4194304 " X: 4194304
|
|
call F()
|
|
Xpath 8388608 " X: 0
|
|
finally
|
|
Xpath 16777216 " X: 16777216
|
|
try
|
|
Xpath 33554432 " X: 33554432
|
|
XloopNEXT
|
|
ExecAsScript F
|
|
Xpath 67108864 " X: 0
|
|
finally
|
|
Xpath 134217728 " X: 134217728
|
|
endtry
|
|
Xpath 268435456 " X: 0
|
|
endtry
|
|
Xpath 536870912 " X: 0
|
|
endtry
|
|
Xpath 1073741824 " X: 0
|
|
endif
|
|
|
|
Xcheck 190905173
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 32: Remembering the :return value on :finally {{{1
|
|
"
|
|
" If a :finally clause is executed due to a :return specifying
|
|
" a value, this is the value visible to the caller if not overwritten
|
|
" by a new :return in the :finally clause. A :return without a value
|
|
" in the :finally clause overwrites with value 0.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! F()
|
|
try
|
|
Xpath 1 " X: 1
|
|
try
|
|
Xpath 2 " X: 2
|
|
return "ABCD"
|
|
Xpath 4 " X: 0
|
|
finally
|
|
Xpath 8 " X: 8
|
|
endtry
|
|
Xpath 16 " X: 0
|
|
finally
|
|
Xpath 32 " X: 32
|
|
endtry
|
|
Xpath 64 " X: 0
|
|
endfunction
|
|
|
|
function! G()
|
|
try
|
|
Xpath 128 " X: 128
|
|
return 8
|
|
Xpath 256 " X: 0
|
|
finally
|
|
Xpath 512 " X: 512
|
|
return 16 + strlen(F())
|
|
Xpath 1024 " X: 0
|
|
endtry
|
|
Xpath 2048 " X: 0
|
|
endfunction
|
|
|
|
function! H()
|
|
try
|
|
Xpath 4096 " X: 4096
|
|
return 32
|
|
Xpath 8192 " X: 0
|
|
finally
|
|
Xpath 16384 " X: 16384
|
|
return
|
|
Xpath 32768 " X: 0
|
|
endtry
|
|
Xpath 65536 " X: 0
|
|
endfunction
|
|
|
|
function! I()
|
|
try
|
|
Xpath 131072 " X: 131072
|
|
finally
|
|
Xpath 262144 " X: 262144
|
|
return G() + H() + 64
|
|
Xpath 524288 " X: 0
|
|
endtry
|
|
Xpath 1048576 " X: 0
|
|
endfunction
|
|
|
|
let retcode = I()
|
|
Xpath 2097152 " X: 2097152
|
|
|
|
if retcode < 0
|
|
Xpath 4194304 " X: 0
|
|
endif
|
|
if retcode % 4
|
|
Xpath 8388608 " X: 0
|
|
endif
|
|
if (retcode/4) % 2
|
|
Xpath 16777216 " X: 16777216
|
|
endif
|
|
if (retcode/8) % 2
|
|
Xpath 33554432 " X: 0
|
|
endif
|
|
if (retcode/16) % 2
|
|
Xpath 67108864 " X: 67108864
|
|
endif
|
|
if (retcode/32) % 2
|
|
Xpath 134217728 " X: 0
|
|
endif
|
|
if (retcode/64) % 2
|
|
Xpath 268435456 " X: 268435456
|
|
endif
|
|
if retcode/128
|
|
Xpath 536870912 " X: 0
|
|
endif
|
|
|
|
unlet retcode
|
|
delfunction F
|
|
delfunction G
|
|
delfunction H
|
|
delfunction I
|
|
|
|
Xcheck 354833067
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 33: :return under :execute or user command and :finally {{{1
|
|
"
|
|
" A :return command may be executed under an ":execute" or from
|
|
" a user command. Executing of :finally clauses and passing through
|
|
" the return code works also then.
|
|
"-------------------------------------------------------------------------------
|
|
XpathINIT
|
|
|
|
command! -nargs=? RETURN
|
|
\ try | return <args> | finally | return <args> * 2 | endtry
|
|
|
|
function! F()
|
|
try
|
|
RETURN 8
|
|
Xpath 1 " X: 0
|
|
finally
|
|
Xpath 2 " X: 2
|
|
endtry
|
|
Xpath 4 " X: 0
|
|
endfunction
|
|
|
|
function! G()
|
|
try
|
|
RETURN 32
|
|
Xpath 8 " X: 0
|
|
finally
|
|
Xpath 16 " X: 16
|
|
RETURN 128
|
|
Xpath 32 " X: 0
|
|
endtry
|
|
Xpath 64 " X: 0
|
|
endfunction
|
|
|
|
function! H()
|
|
try
|
|
execute "try | return 512 | finally | return 1024 | endtry"
|
|
Xpath 128 " X: 0
|
|
finally
|
|
Xpath 256 " X: 256
|
|
endtry
|
|
Xpath 512 " X: 0
|
|
endfunction
|
|
|
|
function! I()
|
|
try
|
|
execute "try | return 2048 | finally | return 4096 | endtry"
|
|
Xpath 1024 " X: 0
|
|
finally
|
|
Xpath 2048 " X: 2048
|
|
execute "try | return 8192 | finally | return 16384 | endtry"
|
|
Xpath 4096 " X: 0
|
|
endtry
|
|
Xpath 8192 " X: 0
|
|
endfunction
|
|
|
|
function! J()
|
|
try
|
|
RETURN 32768
|
|
Xpath 16384 " X: 0
|
|
finally
|
|
Xpath 32768 " X: 32768
|
|
return
|
|
Xpath 65536 " X: 0
|
|
endtry
|
|
Xpath 131072 " X: 0
|
|
endfunction
|
|
|
|
function! K()
|
|
try
|
|
execute "try | return 131072 | finally | return 262144 | endtry"
|
|
Xpath 262144 " X: 0
|
|
finally
|
|
Xpath 524288 " X: 524288
|
|
execute "try | return 524288 | finally | return | endtry"
|
|
Xpath 1048576 " X: 0
|
|
endtry
|
|
Xpath 2097152 " X: 0
|
|
endfunction
|
|
|
|
function! L()
|
|
try
|
|
return
|
|
Xpath 4194304 " X: 0
|
|
finally
|
|
Xpath 8388608 " X: 8388608
|
|
RETURN 1048576
|
|
Xpath 16777216 " X: 0
|
|
endtry
|
|
Xpath 33554432 " X: 0
|
|
endfunction
|
|
|
|
function! M()
|
|
try
|
|
return
|
|
Xpath 67108864 " X: 0
|
|
finally
|
|
Xpath 134217728 " X: 134217728
|
|
execute "try | return 4194304 | finally | return 8388608 | endtry"
|
|
Xpath 268435456 " X: 0
|
|
endtry
|
|
Xpath 536870912 " X: 0
|
|
endfunction
|
|
|
|
function! N()
|
|
RETURN 16777216
|
|
endfunction
|
|
|
|
function! O()
|
|
execute "try | return 67108864 | finally | return 134217728 | endtry"
|
|
endfunction
|
|
|
|
let sum = F() + G() + H() + I() + J() + K() + L() + M()
|
|
let expected = 16 + 256 + 1024 + 16384 + 0 + 0 + 2097152 + 8388608
|
|
let sum = sum + N() + O()
|
|
let expected = expected + 33554432 + 134217728
|
|
|
|
if sum == expected
|
|
Xout "sum = " . sum . " (ok)"
|
|
else
|
|
Xout "sum = " . sum . ", expected: " . expected
|
|
endif
|
|
|
|
Xpath 1073741824 " X: 1073741824
|
|
|
|
if sum != expected
|
|
" The Xpath command does not accept 2^31 (negative); add explicitly:
|
|
let Xpath = Xpath + 2147483648 " X: 0
|
|
endif
|
|
|
|
unlet sum expected
|
|
delfunction F
|
|
delfunction G
|
|
delfunction H
|
|
delfunction I
|
|
delfunction J
|
|
delfunction K
|
|
delfunction L
|
|
delfunction M
|
|
delfunction N
|
|
delfunction O
|
|
|
|
Xcheck 1216907538
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 34: :finally reason discarded by :continue {{{1
|
|
"
|
|
" When a :finally clause is executed due to a :continue, :break,
|
|
" :return, :finish, error, interrupt or :throw, the jump reason is
|
|
" discarded by a :continue in the finally clause.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
XloopINIT! 1 8
|
|
|
|
function! C(jump)
|
|
XloopNEXT
|
|
let loop = 0
|
|
while loop < 2
|
|
let loop = loop + 1
|
|
if loop == 1
|
|
try
|
|
if a:jump == "continue"
|
|
continue
|
|
elseif a:jump == "break"
|
|
break
|
|
elseif a:jump == "return" || a:jump == "finish"
|
|
return
|
|
elseif a:jump == "error"
|
|
asdf
|
|
elseif a:jump == "interrupt"
|
|
"INTERRUPT
|
|
let dummy = 0
|
|
elseif a:jump == "throw"
|
|
throw "abc"
|
|
endif
|
|
finally
|
|
continue " discards jump that caused the :finally
|
|
Xloop 1 " X: 0
|
|
endtry
|
|
Xloop 2 " X: 0
|
|
elseif loop == 2
|
|
Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144)
|
|
endif
|
|
endwhile
|
|
endfunction
|
|
|
|
call C("continue")
|
|
Xpath 2097152 " X: 2097152
|
|
call C("break")
|
|
Xpath 4194304 " X: 4194304
|
|
call C("return")
|
|
Xpath 8388608 " X: 8388608
|
|
let g:jump = "finish"
|
|
ExecAsScript C
|
|
unlet g:jump
|
|
Xpath 16777216 " X: 16777216
|
|
try
|
|
call C("error")
|
|
Xpath 33554432 " X: 33554432
|
|
finally
|
|
Xpath 67108864 " X: 67108864
|
|
try
|
|
call C("interrupt")
|
|
Xpath 134217728 " X: 134217728
|
|
finally
|
|
Xpath 268435456 " X: 268435456
|
|
call C("throw")
|
|
Xpath 536870912 " X: 536870912
|
|
endtry
|
|
endtry
|
|
Xpath 1073741824 " X: 1073741824
|
|
|
|
delfunction C
|
|
|
|
endif
|
|
|
|
Xcheck 2146584868
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 35: :finally reason discarded by :break {{{1
|
|
"
|
|
" When a :finally clause is executed due to a :continue, :break,
|
|
" :return, :finish, error, interrupt or :throw, the jump reason is
|
|
" discarded by a :break in the finally clause.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
XloopINIT! 1 8
|
|
|
|
function! B(jump)
|
|
XloopNEXT
|
|
let loop = 0
|
|
while loop < 2
|
|
let loop = loop + 1
|
|
if loop == 1
|
|
try
|
|
if a:jump == "continue"
|
|
continue
|
|
elseif a:jump == "break"
|
|
break
|
|
elseif a:jump == "return" || a:jump == "finish"
|
|
return
|
|
elseif a:jump == "error"
|
|
asdf
|
|
elseif a:jump == "interrupt"
|
|
"INTERRUPT
|
|
let dummy = 0
|
|
elseif a:jump == "throw"
|
|
throw "abc"
|
|
endif
|
|
finally
|
|
break " discards jump that caused the :finally
|
|
Xloop 1 " X: 0
|
|
endtry
|
|
elseif loop == 2
|
|
Xloop 2 " X: 0
|
|
endif
|
|
endwhile
|
|
Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144)
|
|
endfunction
|
|
|
|
call B("continue")
|
|
Xpath 2097152 " X: 2097152
|
|
call B("break")
|
|
Xpath 4194304 " X: 4194304
|
|
call B("return")
|
|
Xpath 8388608 " X: 8388608
|
|
let g:jump = "finish"
|
|
ExecAsScript B
|
|
unlet g:jump
|
|
Xpath 16777216 " X: 16777216
|
|
try
|
|
call B("error")
|
|
Xpath 33554432 " X: 33554432
|
|
finally
|
|
Xpath 67108864 " X: 67108864
|
|
try
|
|
call B("interrupt")
|
|
Xpath 134217728 " X: 134217728
|
|
finally
|
|
Xpath 268435456 " X: 268435456
|
|
call B("throw")
|
|
Xpath 536870912 " X: 536870912
|
|
endtry
|
|
endtry
|
|
Xpath 1073741824 " X: 1073741824
|
|
|
|
delfunction B
|
|
|
|
endif
|
|
|
|
Xcheck 2146584868
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 36: :finally reason discarded by :return {{{1
|
|
"
|
|
" When a :finally clause is executed due to a :continue, :break,
|
|
" :return, :finish, error, interrupt or :throw, the jump reason is
|
|
" discarded by a :return in the finally clause.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
XloopINIT! 1 8
|
|
|
|
function! R(jump, retval) abort
|
|
XloopNEXT
|
|
let loop = 0
|
|
while loop < 2
|
|
let loop = loop + 1
|
|
if loop == 1
|
|
try
|
|
if a:jump == "continue"
|
|
continue
|
|
elseif a:jump == "break"
|
|
break
|
|
elseif a:jump == "return"
|
|
return
|
|
elseif a:jump == "error"
|
|
asdf
|
|
elseif a:jump == "interrupt"
|
|
"INTERRUPT
|
|
let dummy = 0
|
|
elseif a:jump == "throw"
|
|
throw "abc"
|
|
endif
|
|
finally
|
|
return a:retval " discards jump that caused the :finally
|
|
Xloop 1 " X: 0
|
|
endtry
|
|
elseif loop == 2
|
|
Xloop 2 " X: 0
|
|
endif
|
|
endwhile
|
|
Xloop 4 " X: 0
|
|
endfunction
|
|
|
|
let sum = -R("continue", -8)
|
|
Xpath 2097152 " X: 2097152
|
|
let sum = sum - R("break", -16)
|
|
Xpath 4194304 " X: 4194304
|
|
let sum = sum - R("return", -32)
|
|
Xpath 8388608 " X: 8388608
|
|
try
|
|
let sum = sum - R("error", -64)
|
|
Xpath 16777216 " X: 16777216
|
|
finally
|
|
Xpath 33554432 " X: 33554432
|
|
try
|
|
let sum = sum - R("interrupt", -128)
|
|
Xpath 67108864 " X: 67108864
|
|
finally
|
|
Xpath 134217728 " X: 134217728
|
|
let sum = sum - R("throw", -256)
|
|
Xpath 268435456 " X: 268435456
|
|
endtry
|
|
endtry
|
|
Xpath 536870912 " X: 536870912
|
|
|
|
let expected = 8 + 16 + 32 + 64 + 128 + 256
|
|
if sum != expected
|
|
Xpath 1073741824 " X: 0
|
|
Xout "sum =" . sum . ", expected: " . expected
|
|
endif
|
|
|
|
unlet sum expected
|
|
delfunction R
|
|
|
|
endif
|
|
|
|
Xcheck 1071644672
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 37: :finally reason discarded by :finish {{{1
|
|
"
|
|
" When a :finally clause is executed due to a :continue, :break,
|
|
" :return, :finish, error, interrupt or :throw, the jump reason is
|
|
" discarded by a :finish in the finally clause.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
XloopINIT! 1 8
|
|
|
|
function! F(jump) " not executed as function, transformed to a script
|
|
XloopNEXT
|
|
let loop = 0
|
|
while loop < 2
|
|
let loop = loop + 1
|
|
if loop == 1
|
|
try
|
|
if a:jump == "continue"
|
|
continue
|
|
elseif a:jump == "break"
|
|
break
|
|
elseif a:jump == "finish"
|
|
finish
|
|
elseif a:jump == "error"
|
|
asdf
|
|
elseif a:jump == "interrupt"
|
|
"INTERRUPT
|
|
let dummy = 0
|
|
elseif a:jump == "throw"
|
|
throw "abc"
|
|
endif
|
|
finally
|
|
finish " discards jump that caused the :finally
|
|
Xloop 1 " X: 0
|
|
endtry
|
|
elseif loop == 2
|
|
Xloop 2 " X: 0
|
|
endif
|
|
endwhile
|
|
Xloop 4 " X: 0
|
|
endfunction
|
|
|
|
let scriptF = MakeScript("F")
|
|
delfunction F
|
|
|
|
let g:jump = "continue"
|
|
exec "source" scriptF
|
|
Xpath 2097152 " X: 2097152
|
|
let g:jump = "break"
|
|
exec "source" scriptF
|
|
Xpath 4194304 " X: 4194304
|
|
let g:jump = "finish"
|
|
exec "source" scriptF
|
|
Xpath 8388608 " X: 8388608
|
|
try
|
|
let g:jump = "error"
|
|
exec "source" scriptF
|
|
Xpath 16777216 " X: 16777216
|
|
finally
|
|
Xpath 33554432 " X: 33554432
|
|
try
|
|
let g:jump = "interrupt"
|
|
exec "source" scriptF
|
|
Xpath 67108864 " X: 67108864
|
|
finally
|
|
Xpath 134217728 " X: 134217728
|
|
try
|
|
let g:jump = "throw"
|
|
exec "source" scriptF
|
|
Xpath 268435456 " X: 268435456
|
|
finally
|
|
Xpath 536870912 " X: 536870912
|
|
endtry
|
|
endtry
|
|
endtry
|
|
unlet g:jump
|
|
|
|
call delete(scriptF)
|
|
unlet scriptF
|
|
|
|
endif
|
|
|
|
Xcheck 1071644672
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 38: :finally reason discarded by an error {{{1
|
|
"
|
|
" When a :finally clause is executed due to a :continue, :break,
|
|
" :return, :finish, error, interrupt or :throw, the jump reason is
|
|
" discarded by an error in the finally clause.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
XloopINIT! 1 4
|
|
|
|
function! E(jump)
|
|
XloopNEXT
|
|
let loop = 0
|
|
while loop < 2
|
|
let loop = loop + 1
|
|
if loop == 1
|
|
try
|
|
if a:jump == "continue"
|
|
continue
|
|
elseif a:jump == "break"
|
|
break
|
|
elseif a:jump == "return" || a:jump == "finish"
|
|
return
|
|
elseif a:jump == "error"
|
|
asdf
|
|
elseif a:jump == "interrupt"
|
|
"INTERRUPT
|
|
let dummy = 0
|
|
elseif a:jump == "throw"
|
|
throw "abc"
|
|
endif
|
|
finally
|
|
asdf " error; discards jump that caused the :finally
|
|
endtry
|
|
elseif loop == 2
|
|
Xloop 1 " X: 0
|
|
endif
|
|
endwhile
|
|
Xloop 2 " X: 0
|
|
endfunction
|
|
|
|
try
|
|
Xpath 16384 " X: 16384
|
|
call E("continue")
|
|
Xpath 32768 " X: 0
|
|
finally
|
|
try
|
|
Xpath 65536 " X: 65536
|
|
call E("break")
|
|
Xpath 131072 " X: 0
|
|
finally
|
|
try
|
|
Xpath 262144 " X: 262144
|
|
call E("return")
|
|
Xpath 524288 " X: 0
|
|
finally
|
|
try
|
|
Xpath 1048576 " X: 1048576
|
|
let g:jump = "finish"
|
|
ExecAsScript E
|
|
Xpath 2097152 " X: 0
|
|
finally
|
|
unlet g:jump
|
|
try
|
|
Xpath 4194304 " X: 4194304
|
|
call E("error")
|
|
Xpath 8388608 " X: 0
|
|
finally
|
|
try
|
|
Xpath 16777216 " X: 16777216
|
|
call E("interrupt")
|
|
Xpath 33554432 " X: 0
|
|
finally
|
|
try
|
|
Xpath 67108864 " X: 67108864
|
|
call E("throw")
|
|
Xpath 134217728 " X: 0
|
|
finally
|
|
Xpath 268435456 " X: 268435456
|
|
delfunction E
|
|
endtry
|
|
endtry
|
|
endtry
|
|
endtry
|
|
endtry
|
|
endtry
|
|
endtry
|
|
Xpath 536870912 " X: 0
|
|
|
|
endif
|
|
|
|
Xcheck 357908480
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 39: :finally reason discarded by an interrupt {{{1
|
|
"
|
|
" When a :finally clause is executed due to a :continue, :break,
|
|
" :return, :finish, error, interrupt or :throw, the jump reason is
|
|
" discarded by an interrupt in the finally clause.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
XloopINIT! 1 4
|
|
|
|
function! I(jump)
|
|
XloopNEXT
|
|
let loop = 0
|
|
while loop < 2
|
|
let loop = loop + 1
|
|
if loop == 1
|
|
try
|
|
if a:jump == "continue"
|
|
continue
|
|
elseif a:jump == "break"
|
|
break
|
|
elseif a:jump == "return" || a:jump == "finish"
|
|
return
|
|
elseif a:jump == "error"
|
|
asdf
|
|
elseif a:jump == "interrupt"
|
|
"INTERRUPT
|
|
let dummy = 0
|
|
elseif a:jump == "throw"
|
|
throw "abc"
|
|
endif
|
|
finally
|
|
"INTERRUPT - discards jump that caused the :finally
|
|
let dummy = 0
|
|
endtry
|
|
elseif loop == 2
|
|
Xloop 1 " X: 0
|
|
endif
|
|
endwhile
|
|
Xloop 2 " X: 0
|
|
endfunction
|
|
|
|
try
|
|
Xpath 16384 " X: 16384
|
|
call I("continue")
|
|
Xpath 32768 " X: 0
|
|
finally
|
|
try
|
|
Xpath 65536 " X: 65536
|
|
call I("break")
|
|
Xpath 131072 " X: 0
|
|
finally
|
|
try
|
|
Xpath 262144 " X: 262144
|
|
call I("return")
|
|
Xpath 524288 " X: 0
|
|
finally
|
|
try
|
|
Xpath 1048576 " X: 1048576
|
|
let g:jump = "finish"
|
|
ExecAsScript I
|
|
Xpath 2097152 " X: 0
|
|
finally
|
|
unlet g:jump
|
|
try
|
|
Xpath 4194304 " X: 4194304
|
|
call I("error")
|
|
Xpath 8388608 " X: 0
|
|
finally
|
|
try
|
|
Xpath 16777216 " X: 16777216
|
|
call I("interrupt")
|
|
Xpath 33554432 " X: 0
|
|
finally
|
|
try
|
|
Xpath 67108864 " X: 67108864
|
|
call I("throw")
|
|
Xpath 134217728 " X: 0
|
|
finally
|
|
Xpath 268435456 " X: 268435456
|
|
delfunction I
|
|
endtry
|
|
endtry
|
|
endtry
|
|
endtry
|
|
endtry
|
|
endtry
|
|
endtry
|
|
Xpath 536870912 " X: 0
|
|
|
|
endif
|
|
|
|
Xcheck 357908480
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 40: :finally reason discarded by :throw {{{1
|
|
"
|
|
" When a :finally clause is executed due to a :continue, :break,
|
|
" :return, :finish, error, interrupt or :throw, the jump reason is
|
|
" discarded by a :throw in the finally clause.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
XloopINIT! 1 4
|
|
|
|
function! T(jump)
|
|
XloopNEXT
|
|
let loop = 0
|
|
while loop < 2
|
|
let loop = loop + 1
|
|
if loop == 1
|
|
try
|
|
if a:jump == "continue"
|
|
continue
|
|
elseif a:jump == "break"
|
|
break
|
|
elseif a:jump == "return" || a:jump == "finish"
|
|
return
|
|
elseif a:jump == "error"
|
|
asdf
|
|
elseif a:jump == "interrupt"
|
|
"INTERRUPT
|
|
let dummy = 0
|
|
elseif a:jump == "throw"
|
|
throw "abc"
|
|
endif
|
|
finally
|
|
throw "xyz" " discards jump that caused the :finally
|
|
endtry
|
|
elseif loop == 2
|
|
Xloop 1 " X: 0
|
|
endif
|
|
endwhile
|
|
Xloop 2 " X: 0
|
|
endfunction
|
|
|
|
try
|
|
Xpath 16384 " X: 16384
|
|
call T("continue")
|
|
Xpath 32768 " X: 0
|
|
finally
|
|
try
|
|
Xpath 65536 " X: 65536
|
|
call T("break")
|
|
Xpath 131072 " X: 0
|
|
finally
|
|
try
|
|
Xpath 262144 " X: 262144
|
|
call T("return")
|
|
Xpath 524288 " X: 0
|
|
finally
|
|
try
|
|
Xpath 1048576 " X: 1048576
|
|
let g:jump = "finish"
|
|
ExecAsScript T
|
|
Xpath 2097152 " X: 0
|
|
finally
|
|
unlet g:jump
|
|
try
|
|
Xpath 4194304 " X: 4194304
|
|
call T("error")
|
|
Xpath 8388608 " X: 0
|
|
finally
|
|
try
|
|
Xpath 16777216 " X: 16777216
|
|
call T("interrupt")
|
|
Xpath 33554432 " X: 0
|
|
finally
|
|
try
|
|
Xpath 67108864 " X: 67108864
|
|
call T("throw")
|
|
Xpath 134217728 " X: 0
|
|
finally
|
|
Xpath 268435456 " X: 268435456
|
|
delfunction T
|
|
endtry
|
|
endtry
|
|
endtry
|
|
endtry
|
|
endtry
|
|
endtry
|
|
endtry
|
|
Xpath 536870912 " X: 0
|
|
|
|
endif
|
|
|
|
Xcheck 357908480
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 41: Skipped :throw finding next command {{{1
|
|
"
|
|
" A :throw in an inactive conditional must not hide a following
|
|
" command.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! F()
|
|
Xpath 1 " X: 1
|
|
if 0 | throw "never" | endif | Xpath 2 " X: 2
|
|
Xpath 4 " X: 4
|
|
endfunction
|
|
|
|
function! G()
|
|
Xpath 8 " X: 8
|
|
while 0 | throw "never" | endwhile | Xpath 16 " X: 16
|
|
Xpath 32 " X: 32
|
|
endfunction
|
|
|
|
function H()
|
|
Xpath 64 " X: 64
|
|
if 0 | try | throw "never" | endtry | endif | Xpath 128 " X: 128
|
|
Xpath 256 " X: 256
|
|
endfunction
|
|
|
|
Xpath 512 " X: 512
|
|
|
|
try
|
|
Xpath 1024 " X: 1024
|
|
call F()
|
|
Xpath 2048 " X: 2048
|
|
catch /.*/
|
|
Xpath 4096 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
Xpath 8192 " X: 8192
|
|
|
|
try
|
|
Xpath 16384 " X: 16384
|
|
call G()
|
|
Xpath 32768 " X: 32768
|
|
catch /.*/
|
|
Xpath 65536 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
Xpath 131072 " X: 131072
|
|
|
|
try
|
|
Xpath 262144 " X: 262144
|
|
call H()
|
|
Xpath 524288 " X: 524288
|
|
catch /.*/
|
|
Xpath 1048576 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
Xpath 2097152 " X: 2097152
|
|
|
|
delfunction F
|
|
delfunction G
|
|
delfunction H
|
|
|
|
Xcheck 3076095
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 42: Catching number and string exceptions {{{1
|
|
"
|
|
" When a number is thrown, it is converted to a string exception.
|
|
" Numbers and strings may be caught by specifying a regular exception
|
|
" as argument to the :catch command.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
try
|
|
|
|
try
|
|
Xpath 1 " X: 1
|
|
throw 4711
|
|
Xpath 2 " X: 0
|
|
catch /4711/
|
|
Xpath 4 " X: 4
|
|
endtry
|
|
|
|
try
|
|
Xpath 8 " X: 8
|
|
throw 4711
|
|
Xpath 16 " X: 0
|
|
catch /^4711$/
|
|
Xpath 32 " X: 32
|
|
endtry
|
|
|
|
try
|
|
Xpath 64 " X: 64
|
|
throw 4711
|
|
Xpath 128 " X: 0
|
|
catch /\d/
|
|
Xpath 256 " X: 256
|
|
endtry
|
|
|
|
try
|
|
Xpath 512 " X: 512
|
|
throw 4711
|
|
Xpath 1024 " X: 0
|
|
catch /^\d\+$/
|
|
Xpath 2048 " X: 2048
|
|
endtry
|
|
|
|
try
|
|
Xpath 4096 " X: 4096
|
|
throw "arrgh"
|
|
Xpath 8192 " X: 0
|
|
catch /arrgh/
|
|
Xpath 16384 " X: 16384
|
|
endtry
|
|
|
|
try
|
|
Xpath 32768 " X: 32768
|
|
throw "arrgh"
|
|
Xpath 65536 " X: 0
|
|
catch /^arrgh$/
|
|
Xpath 131072 " X: 131072
|
|
endtry
|
|
|
|
try
|
|
Xpath 262144 " X: 262144
|
|
throw "arrgh"
|
|
Xpath 524288 " X: 0
|
|
catch /\l/
|
|
Xpath 1048576 " X: 1048576
|
|
endtry
|
|
|
|
try
|
|
Xpath 2097152 " X: 2097152
|
|
throw "arrgh"
|
|
Xpath 4194304 " X: 0
|
|
catch /^\l\+$/
|
|
Xpath 8388608 " X: 8388608
|
|
endtry
|
|
|
|
try
|
|
try
|
|
Xpath 16777216 " X: 16777216
|
|
throw "ARRGH"
|
|
Xpath 33554432 " X: 0
|
|
catch /^arrgh$/
|
|
Xpath 67108864 " X: 0
|
|
endtry
|
|
catch /^\carrgh$/
|
|
Xpath 134217728 " X: 134217728
|
|
endtry
|
|
|
|
try
|
|
Xpath 268435456 " X: 268435456
|
|
throw ""
|
|
Xpath 536870912 " X: 0
|
|
catch /^$/
|
|
Xpath 1073741824 " X: 1073741824
|
|
endtry
|
|
|
|
catch /.*/
|
|
" The Xpath command does not accept 2^31 (negative); add explicitly:
|
|
let Xpath = Xpath + 2147483648 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
Xcheck 1505155949
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 43: Selecting the correct :catch clause {{{1
|
|
"
|
|
" When an exception is thrown and there are multiple :catch clauses,
|
|
" the first matching one is taken.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
XloopINIT 1 1024
|
|
let loops = 3
|
|
while loops > 0
|
|
try
|
|
if loops == 3
|
|
Xloop 1 " X: 1
|
|
throw "a"
|
|
Xloop 2 " X: 0
|
|
elseif loops == 2
|
|
Xloop 4 " X: 4*1024
|
|
throw "ab"
|
|
Xloop 8 " X: 0
|
|
elseif loops == 1
|
|
Xloop 16 " X: 16*1024*1024
|
|
throw "abc"
|
|
Xloop 32 " X: 0
|
|
endif
|
|
catch /abc/
|
|
Xloop 64 " X: 64*1024*1024
|
|
catch /ab/
|
|
Xloop 128 " X: 128*1024
|
|
catch /.*/
|
|
Xloop 256 " X: 256
|
|
catch /a/
|
|
Xloop 512 " X: 0
|
|
endtry
|
|
|
|
let loops = loops - 1
|
|
XloopNEXT
|
|
endwhile
|
|
Xpath 1073741824 " X: 1073741824
|
|
|
|
unlet loops
|
|
|
|
Xcheck 1157763329
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 44: Missing or empty :catch patterns {{{1
|
|
"
|
|
" A missing or empty :catch pattern means the same as /.*/, that is,
|
|
" catches everything. To catch only empty exceptions, /^$/ must be
|
|
" used. A :catch with missing, empty, or /.*/ argument also works
|
|
" when followed by another command separated by a bar on the same
|
|
" line. :catch patterns cannot be specified between ||. But other
|
|
" pattern separators can be used instead of //.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
try
|
|
try
|
|
Xpath 1 " X: 1
|
|
throw ""
|
|
catch /^$/
|
|
Xpath 2 " X: 2
|
|
endtry
|
|
|
|
try
|
|
Xpath 4 " X: 4
|
|
throw ""
|
|
catch /.*/
|
|
Xpath 8 " X: 8
|
|
endtry
|
|
|
|
try
|
|
Xpath 16 " X: 16
|
|
throw ""
|
|
catch //
|
|
Xpath 32 " X: 32
|
|
endtry
|
|
|
|
try
|
|
Xpath 64 " X: 64
|
|
throw ""
|
|
catch
|
|
Xpath 128 " X: 128
|
|
endtry
|
|
|
|
try
|
|
Xpath 256 " X: 256
|
|
throw "oops"
|
|
catch /^$/
|
|
Xpath 512 " X: 0
|
|
catch /.*/
|
|
Xpath 1024 " X: 1024
|
|
endtry
|
|
|
|
try
|
|
Xpath 2048 " X: 2048
|
|
throw "arrgh"
|
|
catch /^$/
|
|
Xpath 4096 " X: 0
|
|
catch //
|
|
Xpath 8192 " X: 8192
|
|
endtry
|
|
|
|
try
|
|
Xpath 16384 " X: 16384
|
|
throw "brrr"
|
|
catch /^$/
|
|
Xpath 32768 " X: 0
|
|
catch
|
|
Xpath 65536 " X: 65536
|
|
endtry
|
|
|
|
try | Xpath 131072 | throw "x" | catch /.*/ | Xpath 262144 | endtry
|
|
" X: 131072 + 262144
|
|
|
|
try | Xpath 524288 | throw "y" | catch // | Xpath 1048576 | endtry
|
|
" X: 524288 + 1048576
|
|
|
|
while 1
|
|
try
|
|
let caught = 0
|
|
let v:errmsg = ""
|
|
" Extra try level: if ":catch" without arguments below raises
|
|
" a syntax error because it misinterprets the "Xpath" as a pattern,
|
|
" let it be caught by the ":catch /.*/" below.
|
|
try
|
|
try | Xpath 2097152 | throw "z" | catch | Xpath 4194304 | :
|
|
endtry " X: 2097152 + 4194304
|
|
endtry
|
|
catch /.*/
|
|
let caught = 1
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
if $VIMNOERRTHROW && v:errmsg != ""
|
|
Xout v:errmsg
|
|
endif
|
|
if caught || $VIMNOERRTHROW && v:errmsg != ""
|
|
Xpath 8388608 " X: 0
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
let cologne = 4711
|
|
try
|
|
try
|
|
Xpath 16777216 " X: 16777216
|
|
throw "throw cologne"
|
|
" Next lines catches all and throws 4711:
|
|
catch |throw cologne|
|
|
Xpath 33554432 " X: 0
|
|
endtry
|
|
catch /4711/
|
|
Xpath 67108864 " X: 67108864
|
|
endtry
|
|
|
|
try
|
|
Xpath 134217728 " X: 134217728
|
|
throw "plus"
|
|
catch +plus+
|
|
Xpath 268435456 " X: 268435456
|
|
endtry
|
|
|
|
Xpath 536870912 " X: 536870912
|
|
catch /.*/
|
|
Xpath 1073741824 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
unlet! caught cologne
|
|
|
|
Xcheck 1031761407
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 45: Catching exceptions from nested :try blocks {{{1
|
|
"
|
|
" When :try blocks are nested, an exception is caught by the innermost
|
|
" try conditional that has a matching :catch clause.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
XloopINIT 1 1024
|
|
let loops = 3
|
|
while loops > 0
|
|
try
|
|
try
|
|
try
|
|
try
|
|
if loops == 3
|
|
Xloop 1 " X: 1
|
|
throw "a"
|
|
Xloop 2 " X: 0
|
|
elseif loops == 2
|
|
Xloop 4 " X: 4*1024
|
|
throw "ab"
|
|
Xloop 8 " X: 0
|
|
elseif loops == 1
|
|
Xloop 16 " X: 16*1024*1024
|
|
throw "abc"
|
|
Xloop 32 " X: 0
|
|
endif
|
|
catch /abc/
|
|
Xloop 64 " X: 64*1024*1024
|
|
endtry
|
|
catch /ab/
|
|
Xloop 128 " X: 128*1024
|
|
endtry
|
|
catch /.*/
|
|
Xloop 256 " X: 256
|
|
endtry
|
|
catch /a/
|
|
Xloop 512 " X: 0
|
|
endtry
|
|
|
|
let loops = loops - 1
|
|
XloopNEXT
|
|
endwhile
|
|
Xpath 1073741824 " X: 1073741824
|
|
|
|
unlet loops
|
|
|
|
Xcheck 1157763329
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 46: Executing :finally after a :throw in nested :try {{{1
|
|
"
|
|
" When an exception is thrown from within nested :try blocks, the
|
|
" :finally clauses of the non-catching try conditionals should be
|
|
" executed before the matching :catch of the next surrounding :try
|
|
" gets the control. If this also has a :finally clause, it is
|
|
" executed afterwards.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
let sum = 0
|
|
|
|
try
|
|
Xpath 1 " X: 1
|
|
try
|
|
Xpath 2 " X: 2
|
|
try
|
|
Xpath 4 " X: 4
|
|
try
|
|
Xpath 8 " X: 8
|
|
throw "ABC"
|
|
Xpath 16 " X: 0
|
|
catch /xyz/
|
|
Xpath 32 " X: 0
|
|
finally
|
|
Xpath 64 " X: 64
|
|
if sum != 0
|
|
Xpath 128 " X: 0
|
|
endif
|
|
let sum = sum + 1
|
|
endtry
|
|
Xpath 256 " X: 0
|
|
catch /123/
|
|
Xpath 512 " X: 0
|
|
catch /321/
|
|
Xpath 1024 " X: 0
|
|
finally
|
|
Xpath 2048 " X: 2048
|
|
if sum != 1
|
|
Xpath 4096 " X: 0
|
|
endif
|
|
let sum = sum + 2
|
|
endtry
|
|
Xpath 8192 " X: 0
|
|
finally
|
|
Xpath 16384 " X: 16384
|
|
if sum != 3
|
|
Xpath 32768 " X: 0
|
|
endif
|
|
let sum = sum + 4
|
|
endtry
|
|
Xpath 65536 " X: 0
|
|
catch /ABC/
|
|
Xpath 131072 " X: 131072
|
|
if sum != 7
|
|
Xpath 262144 " X: 0
|
|
endif
|
|
let sum = sum + 8
|
|
finally
|
|
Xpath 524288 " X: 524288
|
|
if sum != 15
|
|
Xpath 1048576 " X: 0
|
|
endif
|
|
let sum = sum + 16
|
|
endtry
|
|
Xpath 65536 " X: 65536
|
|
if sum != 31
|
|
Xpath 131072 " X: 0
|
|
endif
|
|
|
|
unlet sum
|
|
|
|
Xcheck 739407
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 47: Throwing exceptions from a :catch clause {{{1
|
|
"
|
|
" When an exception is thrown from a :catch clause, it should not be
|
|
" caught by a :catch of the same :try conditional. After executing
|
|
" the :finally clause (if present), surrounding try conditionals
|
|
" should be checked for a matching :catch.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
Xpath 1 " X: 1
|
|
try
|
|
Xpath 2 " X: 2
|
|
try
|
|
Xpath 4 " X: 4
|
|
try
|
|
Xpath 8 " X: 8
|
|
throw "x1"
|
|
Xpath 16 " X: 0
|
|
catch /x1/
|
|
Xpath 32 " X: 32
|
|
try
|
|
Xpath 64 " X: 64
|
|
throw "x2"
|
|
Xpath 128 " X: 0
|
|
catch /x1/
|
|
Xpath 256 " X: 0
|
|
catch /x2/
|
|
Xpath 512 " X: 512
|
|
try
|
|
Xpath 1024 " X: 1024
|
|
throw "x3"
|
|
Xpath 2048 " X: 0
|
|
catch /x1/
|
|
Xpath 4096 " X: 0
|
|
catch /x2/
|
|
Xpath 8192 " X: 0
|
|
finally
|
|
Xpath 16384 " X: 16384
|
|
endtry
|
|
Xpath 32768 " X: 0
|
|
catch /x3/
|
|
Xpath 65536 " X: 0
|
|
endtry
|
|
Xpath 131072 " X: 0
|
|
catch /x1/
|
|
Xpath 262144 " X: 0
|
|
catch /x2/
|
|
Xpath 524288 " X: 0
|
|
catch /x3/
|
|
Xpath 1048576 " X: 0
|
|
finally
|
|
Xpath 2097152 " X: 2097152
|
|
endtry
|
|
Xpath 4194304 " X: 0
|
|
catch /x1/
|
|
Xpath 8388608 " X: 0
|
|
catch /x2/
|
|
Xpath 16777216 " X: 0
|
|
catch /x3/
|
|
Xpath 33554432 " X: 33554432
|
|
endtry
|
|
Xpath 67108864 " X: 67108864
|
|
catch /.*/
|
|
Xpath 134217728 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
Xpath 268435456 " X: 268435456
|
|
|
|
Xcheck 371213935
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 48: Throwing exceptions from a :finally clause {{{1
|
|
"
|
|
" When an exception is thrown from a :finally clause, it should not be
|
|
" caught by a :catch of the same :try conditional. Surrounding try
|
|
" conditionals should be checked for a matching :catch. A previously
|
|
" thrown exception is discarded.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
try
|
|
|
|
try
|
|
try
|
|
Xpath 1 " X: 1
|
|
catch /x1/
|
|
Xpath 2 " X: 0
|
|
finally
|
|
Xpath 4 " X: 4
|
|
throw "x1"
|
|
Xpath 8 " X: 0
|
|
endtry
|
|
Xpath 16 " X: 0
|
|
catch /x1/
|
|
Xpath 32 " X: 32
|
|
endtry
|
|
Xpath 64 " X: 64
|
|
|
|
try
|
|
try
|
|
Xpath 128 " X: 128
|
|
throw "x2"
|
|
Xpath 256 " X: 0
|
|
catch /x2/
|
|
Xpath 512 " X: 512
|
|
catch /x3/
|
|
Xpath 1024 " X: 0
|
|
finally
|
|
Xpath 2048 " X: 2048
|
|
throw "x3"
|
|
Xpath 4096 " X: 0
|
|
endtry
|
|
Xpath 8192 " X: 0
|
|
catch /x2/
|
|
Xpath 16384 " X: 0
|
|
catch /x3/
|
|
Xpath 32768 " X: 32768
|
|
endtry
|
|
Xpath 65536 " X: 65536
|
|
|
|
try
|
|
try
|
|
try
|
|
Xpath 131072 " X: 131072
|
|
throw "x4"
|
|
Xpath 262144 " X: 0
|
|
catch /x5/
|
|
Xpath 524288 " X: 0
|
|
finally
|
|
Xpath 1048576 " X: 1048576
|
|
throw "x5" " discards "x4"
|
|
Xpath 2097152 " X: 0
|
|
endtry
|
|
Xpath 4194304 " X: 0
|
|
catch /x4/
|
|
Xpath 8388608 " X: 0
|
|
finally
|
|
Xpath 16777216 " X: 16777216
|
|
endtry
|
|
Xpath 33554432 " X: 0
|
|
catch /x5/
|
|
Xpath 67108864 " X: 67108864
|
|
endtry
|
|
Xpath 134217728 " X: 134217728
|
|
|
|
catch /.*/
|
|
Xpath 268435456 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
Xpath 536870912 " X: 536870912
|
|
|
|
Xcheck 756255461
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 49: Throwing exceptions across functions {{{1
|
|
"
|
|
" When an exception is thrown but not caught inside a function, the
|
|
" caller is checked for a matching :catch clause.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! C()
|
|
try
|
|
Xpath 1 " X: 1
|
|
throw "arrgh"
|
|
Xpath 2 " X: 0
|
|
catch /arrgh/
|
|
Xpath 4 " X: 4
|
|
endtry
|
|
Xpath 8 " X: 8
|
|
endfunction
|
|
|
|
XloopINIT! 16 16
|
|
|
|
function! T1()
|
|
XloopNEXT
|
|
try
|
|
Xloop 1 " X: 16 + 16*16
|
|
throw "arrgh"
|
|
Xloop 2 " X: 0
|
|
finally
|
|
Xloop 4 " X: 64 + 64*16
|
|
endtry
|
|
Xloop 8 " X: 0
|
|
endfunction
|
|
|
|
function! T2()
|
|
try
|
|
Xpath 4096 " X: 4096
|
|
call T1()
|
|
Xpath 8192 " X: 0
|
|
finally
|
|
Xpath 16384 " X: 16384
|
|
endtry
|
|
Xpath 32768 " X: 0
|
|
endfunction
|
|
|
|
try
|
|
Xpath 65536 " X: 65536
|
|
call C() " throw and catch
|
|
Xpath 131072 " X: 131072
|
|
catch /.*/
|
|
Xpath 262144 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
Xpath 524288 " X: 524288
|
|
call T1() " throw, one level
|
|
Xpath 1048576 " X: 0
|
|
catch /arrgh/
|
|
Xpath 2097152 " X: 2097152
|
|
catch /.*/
|
|
Xpath 4194304 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
Xpath 8388608 " X: 8388608
|
|
call T2() " throw, two levels
|
|
Xpath 16777216 " X: 0
|
|
catch /arrgh/
|
|
Xpath 33554432 " X: 33554432
|
|
catch /.*/
|
|
Xpath 67108864 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
Xpath 134217728 " X: 134217728
|
|
|
|
Xcheck 179000669
|
|
|
|
" Leave C, T1, and T2 for execution as scripts in the next test.
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 50: Throwing exceptions across script files {{{1
|
|
"
|
|
" When an exception is thrown but not caught inside a script file,
|
|
" the sourcing script or function is checked for a matching :catch
|
|
" clause.
|
|
"
|
|
" This test executes the bodies of the functions C, T1, and T2 from
|
|
" the previous test as script files (:return replaced by :finish).
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
let scriptC = MakeScript("C") " X: 1 + 4 + 8
|
|
delfunction C
|
|
|
|
XloopINIT! 16 16
|
|
|
|
let scriptT1 = MakeScript("T1") " X: 16 + 64 + 16*16 + 64*16
|
|
delfunction T1
|
|
|
|
let scriptT2 = MakeScript("T2", scriptT1) " X: 4096 + 16384
|
|
delfunction T2
|
|
|
|
function! F()
|
|
try
|
|
Xpath 65536 " X: 65536
|
|
exec "source" g:scriptC
|
|
Xpath 131072 " X: 131072
|
|
catch /.*/
|
|
Xpath 262144 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
Xpath 524288 " X: 524288
|
|
exec "source" g:scriptT1
|
|
Xpath 1048576 " X: 0
|
|
catch /arrgh/
|
|
Xpath 2097152 " X: 2097152
|
|
catch /.*/
|
|
Xpath 4194304 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
endfunction
|
|
|
|
try
|
|
Xpath 8388608 " X: 8388608
|
|
call F()
|
|
Xpath 16777216 " X: 16777216
|
|
exec "source" scriptT2
|
|
Xpath 33554432 " X: 0
|
|
catch /arrgh/
|
|
Xpath 67108864 " X: 67108864
|
|
catch /.*/
|
|
Xpath 134217728 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
Xpath 268435456 " X: 268435456
|
|
|
|
call delete(scriptC)
|
|
call delete(scriptT1)
|
|
call delete(scriptT2)
|
|
unlet scriptC scriptT1 scriptT2
|
|
delfunction F
|
|
|
|
Xcheck 363550045
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 51: Throwing exceptions across :execute and user commands {{{1
|
|
"
|
|
" A :throw command may be executed under an ":execute" or from
|
|
" a user command.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
command! -nargs=? THROW1 throw <args> | throw 1
|
|
command! -nargs=? THROW2 try | throw <args> | endtry | throw 2
|
|
command! -nargs=? THROW3 try | throw 3 | catch /3/ | throw <args> | endtry
|
|
command! -nargs=? THROW4 try | throw 4 | finally | throw <args> | endtry
|
|
|
|
try
|
|
|
|
try
|
|
try
|
|
Xpath 1 " X: 1
|
|
THROW1 "A"
|
|
catch /A/
|
|
Xpath 2 " X: 2
|
|
endtry
|
|
catch /1/
|
|
Xpath 4 " X: 0
|
|
endtry
|
|
|
|
try
|
|
try
|
|
Xpath 8 " X: 8
|
|
THROW2 "B"
|
|
catch /B/
|
|
Xpath 16 " X: 16
|
|
endtry
|
|
catch /2/
|
|
Xpath 32 " X: 0
|
|
endtry
|
|
|
|
try
|
|
try
|
|
Xpath 64 " X: 64
|
|
THROW3 "C"
|
|
catch /C/
|
|
Xpath 128 " X: 128
|
|
endtry
|
|
catch /3/
|
|
Xpath 256 " X: 0
|
|
endtry
|
|
|
|
try
|
|
try
|
|
Xpath 512 " X: 512
|
|
THROW4 "D"
|
|
catch /D/
|
|
Xpath 1024 " X: 1024
|
|
endtry
|
|
catch /4/
|
|
Xpath 2048 " X: 0
|
|
endtry
|
|
|
|
try
|
|
try
|
|
Xpath 4096 " X: 4096
|
|
execute 'throw "E" | throw 5'
|
|
catch /E/
|
|
Xpath 8192 " X: 8192
|
|
endtry
|
|
catch /5/
|
|
Xpath 16384 " X: 0
|
|
endtry
|
|
|
|
try
|
|
try
|
|
Xpath 32768 " X: 32768
|
|
execute 'try | throw "F" | endtry | throw 6'
|
|
catch /F/
|
|
Xpath 65536 " X: 65536
|
|
endtry
|
|
catch /6/
|
|
Xpath 131072 " X: 0
|
|
endtry
|
|
|
|
try
|
|
try
|
|
Xpath 262144 " X: 262144
|
|
execute'try | throw 7 | catch /7/ | throw "G" | endtry'
|
|
catch /G/
|
|
Xpath 524288 " X: 524288
|
|
endtry
|
|
catch /7/
|
|
Xpath 1048576 " X: 0
|
|
endtry
|
|
|
|
try
|
|
try
|
|
Xpath 2097152 " X: 2097152
|
|
execute 'try | throw 8 | finally | throw "H" | endtry'
|
|
catch /H/
|
|
Xpath 4194304 " X: 4194304
|
|
endtry
|
|
catch /8/
|
|
Xpath 8388608 " X: 0
|
|
endtry
|
|
|
|
catch /.*/
|
|
Xpath 16777216 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
Xpath 33554432 " X: 33554432
|
|
|
|
delcommand THROW1
|
|
delcommand THROW2
|
|
delcommand THROW3
|
|
delcommand THROW4
|
|
|
|
Xcheck 40744667
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 52: Uncaught exceptions {{{1
|
|
"
|
|
" When an exception is thrown but not caught, an error message is
|
|
" displayed when the script is terminated. In case of an interrupt
|
|
" or error exception, the normal interrupt or error message(s) are
|
|
" displayed.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
let msgfile = tempname()
|
|
|
|
function! MESSAGES(...)
|
|
try
|
|
exec "edit" g:msgfile
|
|
catch /^Vim(edit):/
|
|
return 0
|
|
endtry
|
|
|
|
let english = v:lang == "C" || v:lang =~ '^[Ee]n'
|
|
let match = 1
|
|
norm gg
|
|
|
|
let num = a:0 / 2
|
|
let cnt = 1
|
|
while cnt <= num
|
|
let enr = a:{2*cnt - 1}
|
|
let emsg= a:{2*cnt}
|
|
let cnt = cnt + 1
|
|
|
|
if enr == ""
|
|
Xout "TODO: Add message number for:" emsg
|
|
elseif enr == "INT"
|
|
let enr = ""
|
|
endif
|
|
if enr == "" && !english
|
|
continue
|
|
endif
|
|
let pattern = (enr != "") ? enr . ':.*' : ''
|
|
if english
|
|
let pattern = pattern . emsg
|
|
endif
|
|
if !search(pattern, "W")
|
|
let match = 0
|
|
Xout "No match for:" pattern
|
|
endif
|
|
norm $
|
|
endwhile
|
|
|
|
bwipeout!
|
|
return match
|
|
endfunction
|
|
|
|
if ExtraVim(msgfile)
|
|
Xpath 1 " X: 1
|
|
throw "arrgh"
|
|
endif
|
|
|
|
Xpath 2 " X: 2
|
|
if !MESSAGES('E605', "Exception not caught")
|
|
Xpath 4 " X: 0
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
try
|
|
Xpath 8 " X: 8
|
|
throw "oops"
|
|
catch /arrgh/
|
|
Xpath 16 " X: 0
|
|
endtry
|
|
Xpath 32 " X: 0
|
|
endif
|
|
|
|
Xpath 64 " X: 64
|
|
if !MESSAGES('E605', "Exception not caught")
|
|
Xpath 128 " X: 0
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
function! T()
|
|
throw "brrr"
|
|
endfunction
|
|
|
|
try
|
|
Xpath 256 " X: 256
|
|
throw "arrgh"
|
|
catch /.*/
|
|
Xpath 512 " X: 512
|
|
call T()
|
|
endtry
|
|
Xpath 1024 " X: 0
|
|
endif
|
|
|
|
Xpath 2048 " X: 2048
|
|
if !MESSAGES('E605', "Exception not caught")
|
|
Xpath 4096 " X: 0
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
try
|
|
Xpath 8192 " X: 8192
|
|
throw "arrgh"
|
|
finally
|
|
Xpath 16384 " X: 16384
|
|
throw "brrr"
|
|
endtry
|
|
Xpath 32768 " X: 0
|
|
endif
|
|
|
|
Xpath 65536 " X: 65536
|
|
if !MESSAGES('E605', "Exception not caught")
|
|
Xpath 131072 " X: 0
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
try
|
|
Xpath 262144 " X: 262144
|
|
"INTERRUPT
|
|
endtry
|
|
Xpath 524288 " X: 0
|
|
endif
|
|
|
|
Xpath 1048576 " X: 1048576
|
|
if !MESSAGES('INT', "Interrupted")
|
|
Xpath 2097152 " X: 0
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
try
|
|
Xpath 4194304 " X: 4194304
|
|
let x = novar " error E121/E15; exception: E121
|
|
catch /E15:/ " should not catch
|
|
Xpath 8388608 " X: 0
|
|
endtry
|
|
Xpath 16777216 " X: 0
|
|
endif
|
|
|
|
Xpath 33554432 " X: 33554432
|
|
if !MESSAGES('E121', "Undefined variable", 'E15', "Invalid expression")
|
|
Xpath 67108864 " X: 0
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
try
|
|
Xpath 134217728 " X: 134217728
|
|
" unlet novar # " error E108/E488; exception: E488
|
|
catch /E108:/ " should not catch
|
|
Xpath 268435456 " X: 0
|
|
endtry
|
|
Xpath 536870912 " X: 0
|
|
endif
|
|
|
|
Xpath 1073741824 " X: 1073741824
|
|
if !MESSAGES('E108', "No such variable", 'E488', "Trailing characters")
|
|
" The Xpath command does not accept 2^31 (negative); add explicitly:
|
|
let Xpath = Xpath + 2147483648 " X: 0
|
|
endif
|
|
|
|
call delete(msgfile)
|
|
unlet msgfile
|
|
|
|
Xcheck 1247112011
|
|
|
|
" Leave MESSAGES() for the next tests.
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 53: Nesting errors: :endif/:else/:elseif {{{1
|
|
"
|
|
" For nesting errors of :if conditionals the correct error messages
|
|
" should be given.
|
|
"
|
|
" This test reuses the function MESSAGES() from the previous test.
|
|
" This functions checks the messages in g:msgfile.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
let msgfile = tempname()
|
|
|
|
if ExtraVim(msgfile)
|
|
" endif
|
|
endif
|
|
if MESSAGES('E580', ":endif without :if")
|
|
Xpath 1 " X: 1
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" while 1
|
|
" endif
|
|
" endwhile
|
|
endif
|
|
if MESSAGES('E580', ":endif without :if")
|
|
Xpath 2 " X: 2
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" finally
|
|
" endif
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E580', ":endif without :if")
|
|
Xpath 4 " X: 4
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" endif
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E580', ":endif without :if")
|
|
Xpath 8 " X: 8
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" throw "a"
|
|
" catch /a/
|
|
" endif
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E580', ":endif without :if")
|
|
Xpath 16 " X: 16
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" else
|
|
endif
|
|
if MESSAGES('E581', ":else without :if")
|
|
Xpath 32 " X: 32
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" while 1
|
|
" else
|
|
" endwhile
|
|
endif
|
|
if MESSAGES('E581', ":else without :if")
|
|
Xpath 64 " X: 64
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" finally
|
|
" else
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E581', ":else without :if")
|
|
Xpath 128 " X: 128
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" else
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E581', ":else without :if")
|
|
Xpath 256 " X: 256
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" throw "a"
|
|
" catch /a/
|
|
" else
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E581', ":else without :if")
|
|
Xpath 512 " X: 512
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" elseif
|
|
endif
|
|
if MESSAGES('E582', ":elseif without :if")
|
|
Xpath 1024 " X: 1024
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" while 1
|
|
" elseif
|
|
" endwhile
|
|
endif
|
|
if MESSAGES('E582', ":elseif without :if")
|
|
Xpath 2048 " X: 2048
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" finally
|
|
" elseif
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E582', ":elseif without :if")
|
|
Xpath 4096 " X: 4096
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" elseif
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E582', ":elseif without :if")
|
|
Xpath 8192 " X: 8192
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" throw "a"
|
|
" catch /a/
|
|
" elseif
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E582', ":elseif without :if")
|
|
Xpath 16384 " X: 16384
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" if 1
|
|
" else
|
|
" else
|
|
" endif
|
|
endif
|
|
if MESSAGES('E583', "multiple :else")
|
|
Xpath 32768 " X: 32768
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" if 1
|
|
" else
|
|
" elseif 1
|
|
" endif
|
|
endif
|
|
if MESSAGES('E584', ":elseif after :else")
|
|
Xpath 65536 " X: 65536
|
|
endif
|
|
|
|
call delete(msgfile)
|
|
unlet msgfile
|
|
|
|
Xcheck 131071
|
|
|
|
" Leave MESSAGES() for the next test.
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 54: Nesting errors: :while/:endwhile {{{1
|
|
"
|
|
" For nesting errors of :while conditionals the correct error messages
|
|
" should be given.
|
|
"
|
|
" This test reuses the function MESSAGES() from the previous test.
|
|
" This functions checks the messages in g:msgfile.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
let msgfile = tempname()
|
|
|
|
if ExtraVim(msgfile)
|
|
" endwhile
|
|
endif
|
|
if MESSAGES('E588', ":endwhile without :while")
|
|
Xpath 1 " X: 1
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" if 1
|
|
" endwhile
|
|
" endif
|
|
endif
|
|
if MESSAGES('E588', ":endwhile without :while")
|
|
Xpath 2 " X: 2
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" while 1
|
|
" if 1
|
|
" endwhile
|
|
endif
|
|
if MESSAGES('E171', "Missing :endif")
|
|
Xpath 4 " X: 4
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" finally
|
|
" endwhile
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E588', ":endwhile without :while")
|
|
Xpath 8 " X: 8
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" while 1
|
|
" try
|
|
" finally
|
|
" endwhile
|
|
endif
|
|
if MESSAGES('E600', "Missing :endtry")
|
|
Xpath 16 " X: 16
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" while 1
|
|
" if 1
|
|
" try
|
|
" finally
|
|
" endwhile
|
|
endif
|
|
if MESSAGES('E600', "Missing :endtry")
|
|
Xpath 32 " X: 32
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" while 1
|
|
" try
|
|
" finally
|
|
" if 1
|
|
" endwhile
|
|
endif
|
|
if MESSAGES('E171', "Missing :endif")
|
|
Xpath 64 " X: 64
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" endwhile
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E588', ":endwhile without :while")
|
|
Xpath 128 " X: 128
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" while 1
|
|
" try
|
|
" endwhile
|
|
" endtry
|
|
" endwhile
|
|
endif
|
|
if MESSAGES('E588', ":endwhile without :while")
|
|
Xpath 256 " X: 256
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" throw "a"
|
|
" catch /a/
|
|
" endwhile
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E588', ":endwhile without :while")
|
|
Xpath 512 " X: 512
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" while 1
|
|
" try
|
|
" throw "a"
|
|
" catch /a/
|
|
" endwhile
|
|
" endtry
|
|
" endwhile
|
|
endif
|
|
if MESSAGES('E588', ":endwhile without :while")
|
|
Xpath 1024 " X: 1024
|
|
endif
|
|
|
|
|
|
call delete(msgfile)
|
|
unlet msgfile
|
|
|
|
Xcheck 2047
|
|
|
|
" Leave MESSAGES() for the next test.
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 55: Nesting errors: :continue/:break {{{1
|
|
"
|
|
" For nesting errors of :continue and :break commands the correct
|
|
" error messages should be given.
|
|
"
|
|
" This test reuses the function MESSAGES() from the previous test.
|
|
" This functions checks the messages in g:msgfile.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
let msgfile = tempname()
|
|
|
|
if ExtraVim(msgfile)
|
|
" continue
|
|
endif
|
|
if MESSAGES('E586', ":continue without :while")
|
|
Xpath 1 " X: 1
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" if 1
|
|
" continue
|
|
" endif
|
|
endif
|
|
if MESSAGES('E586', ":continue without :while")
|
|
Xpath 2 " X: 2
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" finally
|
|
" continue
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E586', ":continue without :while")
|
|
Xpath 4 " X: 4
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" continue
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E586', ":continue without :while")
|
|
Xpath 8 " X: 8
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" throw "a"
|
|
" catch /a/
|
|
" continue
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E586', ":continue without :while")
|
|
Xpath 16 " X: 16
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" break
|
|
endif
|
|
if MESSAGES('E587', ":break without :while")
|
|
Xpath 32 " X: 32
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" if 1
|
|
" break
|
|
" endif
|
|
endif
|
|
if MESSAGES('E587', ":break without :while")
|
|
Xpath 64 " X: 64
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" finally
|
|
" break
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E587', ":break without :while")
|
|
Xpath 128 " X: 128
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" break
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E587', ":break without :while")
|
|
Xpath 256 " X: 256
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" throw "a"
|
|
" catch /a/
|
|
" break
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E587', ":break without :while")
|
|
Xpath 512 " X: 512
|
|
endif
|
|
|
|
call delete(msgfile)
|
|
unlet msgfile
|
|
|
|
Xcheck 1023
|
|
|
|
" Leave MESSAGES() for the next test.
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 56: Nesting errors: :endtry {{{1
|
|
"
|
|
" For nesting errors of :try conditionals the correct error messages
|
|
" should be given.
|
|
"
|
|
" This test reuses the function MESSAGES() from the previous test.
|
|
" This functions checks the messages in g:msgfile.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
let msgfile = tempname()
|
|
|
|
if ExtraVim(msgfile)
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E602', ":endtry without :try")
|
|
Xpath 1 " X: 1
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" if 1
|
|
" endtry
|
|
" endif
|
|
endif
|
|
if MESSAGES('E602', ":endtry without :try")
|
|
Xpath 2 " X: 2
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" while 1
|
|
" endtry
|
|
" endwhile
|
|
endif
|
|
if MESSAGES('E602', ":endtry without :try")
|
|
Xpath 4 " X: 4
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" if 1
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E171', "Missing :endif")
|
|
Xpath 8 " X: 8
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" while 1
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E170', "Missing :endwhile")
|
|
Xpath 16 " X: 16
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" finally
|
|
" if 1
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E171', "Missing :endif")
|
|
Xpath 32 " X: 32
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" finally
|
|
" while 1
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E170', "Missing :endwhile")
|
|
Xpath 64 " X: 64
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" throw "a"
|
|
" catch /a/
|
|
" if 1
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E171', "Missing :endif")
|
|
Xpath 128 " X: 128
|
|
endif
|
|
|
|
if ExtraVim(msgfile)
|
|
" try
|
|
" throw "a"
|
|
" catch /a/
|
|
" while 1
|
|
" endtry
|
|
endif
|
|
if MESSAGES('E170', "Missing :endwhile")
|
|
Xpath 256 " X: 256
|
|
endif
|
|
|
|
call delete(msgfile)
|
|
unlet msgfile
|
|
|
|
delfunction MESSAGES
|
|
|
|
Xcheck 511
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 57: v:exception and v:throwpoint for user exceptions {{{1
|
|
"
|
|
" v:exception evaluates to the value of the exception that was caught
|
|
" most recently and is not finished. (A caught exception is finished
|
|
" when the next ":catch", ":finally", or ":endtry" is reached.)
|
|
" v:throwpoint evaluates to the script/function name and line number
|
|
" where that exception has been thrown.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! FuncException()
|
|
let g:exception = v:exception
|
|
endfunction
|
|
|
|
function! FuncThrowpoint()
|
|
let g:throwpoint = v:throwpoint
|
|
endfunction
|
|
|
|
let scriptException = MakeScript("FuncException")
|
|
let scriptThrowPoint = MakeScript("FuncThrowpoint")
|
|
|
|
command! CmdException let g:exception = v:exception
|
|
command! CmdThrowpoint let g:throwpoint = v:throwpoint
|
|
|
|
XloopINIT! 1 2
|
|
|
|
function! CHECK(n, exception, throwname, throwline)
|
|
XloopNEXT
|
|
let error = 0
|
|
if v:exception != a:exception
|
|
Xout a:n.": v:exception is" v:exception "instead of" a:exception
|
|
let error = 1
|
|
endif
|
|
if v:throwpoint !~ a:throwname
|
|
let name = escape(a:throwname, '\')
|
|
Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" name
|
|
let error = 1
|
|
endif
|
|
if v:throwpoint !~ a:throwline
|
|
let line = escape(a:throwline, '\')
|
|
Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
|
|
let error = 1
|
|
endif
|
|
if error
|
|
Xloop 1 " X: 0
|
|
endif
|
|
endfunction
|
|
|
|
function! T(arg, line)
|
|
if a:line == 2
|
|
throw a:arg " in line 2
|
|
elseif a:line == 4
|
|
throw a:arg " in line 4
|
|
elseif a:line == 6
|
|
throw a:arg " in line 6
|
|
elseif a:line == 8
|
|
throw a:arg " in line 8
|
|
endif
|
|
endfunction
|
|
|
|
function! G(arg, line)
|
|
call T(a:arg, a:line)
|
|
endfunction
|
|
|
|
function! F(arg, line)
|
|
call G(a:arg, a:line)
|
|
endfunction
|
|
|
|
let scriptT = MakeScript("T")
|
|
let scriptG = MakeScript("G", scriptT)
|
|
let scriptF = MakeScript("F", scriptG)
|
|
|
|
try
|
|
Xpath 32768 " X: 32768
|
|
call F("oops", 2)
|
|
catch /.*/
|
|
Xpath 65536 " X: 65536
|
|
let exception = v:exception
|
|
let throwpoint = v:throwpoint
|
|
call CHECK(1, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
|
|
exec "let exception = v:exception"
|
|
exec "let throwpoint = v:throwpoint"
|
|
call CHECK(2, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
|
|
CmdException
|
|
CmdThrowpoint
|
|
call CHECK(3, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
|
|
call FuncException()
|
|
call FuncThrowpoint()
|
|
call CHECK(4, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
|
|
exec "source" scriptException
|
|
exec "source" scriptThrowPoint
|
|
call CHECK(5, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
|
|
try
|
|
Xpath 131072 " X: 131072
|
|
call G("arrgh", 4)
|
|
catch /.*/
|
|
Xpath 262144 " X: 262144
|
|
let exception = v:exception
|
|
let throwpoint = v:throwpoint
|
|
call CHECK(6, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
|
|
try
|
|
Xpath 524288 " X: 524288
|
|
let g:arg = "autsch"
|
|
let g:line = 6
|
|
exec "source" scriptF
|
|
catch /.*/
|
|
Xpath 1048576 " X: 1048576
|
|
let exception = v:exception
|
|
let throwpoint = v:throwpoint
|
|
" Symbolic links in tempname()s are not resolved, whereas resolving
|
|
" is done for v:throwpoint. Resolve the temporary file name for
|
|
" scriptT, so that it can be matched against v:throwpoint.
|
|
call CHECK(7, "autsch", resolve(scriptT), '\<6\>')
|
|
finally
|
|
Xpath 2097152 " X: 2097152
|
|
let exception = v:exception
|
|
let throwpoint = v:throwpoint
|
|
call CHECK(8, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
|
|
try
|
|
Xpath 4194304 " X: 4194304
|
|
let g:arg = "brrrr"
|
|
let g:line = 8
|
|
exec "source" scriptG
|
|
catch /.*/
|
|
Xpath 8388608 " X: 8388608
|
|
let exception = v:exception
|
|
let throwpoint = v:throwpoint
|
|
" Resolve scriptT for matching it against v:throwpoint.
|
|
call CHECK(9, "brrrr", resolve(scriptT), '\<8\>')
|
|
finally
|
|
Xpath 16777216 " X: 16777216
|
|
let exception = v:exception
|
|
let throwpoint = v:throwpoint
|
|
call CHECK(10, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
|
|
endtry
|
|
Xpath 33554432 " X: 33554432
|
|
let exception = v:exception
|
|
let throwpoint = v:throwpoint
|
|
call CHECK(11, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
|
|
endtry
|
|
Xpath 67108864 " X: 67108864
|
|
let exception = v:exception
|
|
let throwpoint = v:throwpoint
|
|
call CHECK(12, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
|
|
finally
|
|
Xpath 134217728 " X: 134217728
|
|
let exception = v:exception
|
|
let throwpoint = v:throwpoint
|
|
call CHECK(13, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
|
|
endtry
|
|
Xpath 268435456 " X: 268435456
|
|
let exception = v:exception
|
|
let throwpoint = v:throwpoint
|
|
call CHECK(14, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
|
|
finally
|
|
Xpath 536870912 " X: 536870912
|
|
let exception = v:exception
|
|
let throwpoint = v:throwpoint
|
|
call CHECK(15, "", '^$', '^$')
|
|
endtry
|
|
|
|
Xpath 1073741824 " X: 1073741824
|
|
|
|
unlet exception throwpoint
|
|
delfunction FuncException
|
|
delfunction FuncThrowpoint
|
|
call delete(scriptException)
|
|
call delete(scriptThrowPoint)
|
|
unlet scriptException scriptThrowPoint
|
|
delcommand CmdException
|
|
delcommand CmdThrowpoint
|
|
delfunction T
|
|
delfunction G
|
|
delfunction F
|
|
call delete(scriptT)
|
|
call delete(scriptG)
|
|
call delete(scriptF)
|
|
unlet scriptT scriptG scriptF
|
|
|
|
Xcheck 2147450880
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
"
|
|
" Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1
|
|
"
|
|
" v:exception and v:throwpoint work also for error and interrupt
|
|
" exceptions.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
function! T(line)
|
|
if a:line == 2
|
|
delfunction T " error (function in use) in line 2
|
|
elseif a:line == 4
|
|
let dummy = 0 " INTERRUPT1 - interrupt in line 4
|
|
endif
|
|
endfunction
|
|
|
|
while 1
|
|
try
|
|
Xpath 1 " X: 1
|
|
let caught = 0
|
|
call T(2)
|
|
catch /.*/
|
|
let caught = 1
|
|
if v:exception !~ 'Vim(delfunction):'
|
|
Xpath 2 " X: 0
|
|
endif
|
|
if v:throwpoint !~ '\<T\>'
|
|
Xpath 4 " X: 0
|
|
endif
|
|
if v:throwpoint !~ '\<2\>'
|
|
Xpath 8 " X: 0
|
|
endif
|
|
finally
|
|
Xpath 16 " X: 16
|
|
if caught || $VIMNOERRTHROW
|
|
Xpath 32 " X: 32
|
|
endif
|
|
if v:exception != ""
|
|
Xpath 64 " X: 0
|
|
endif
|
|
if v:throwpoint != ""
|
|
Xpath 128 " X: 0
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
Xpath 256 " X: 256
|
|
if v:exception != ""
|
|
Xpath 512 " X: 0
|
|
endif
|
|
if v:throwpoint != ""
|
|
Xpath 1024 " X: 0
|
|
endif
|
|
|
|
while 1
|
|
try
|
|
Xpath 2048 " X: 2048
|
|
let caught = 0
|
|
call T(4)
|
|
catch /.*/
|
|
let caught = 1
|
|
if v:exception != 'Vim:Interrupt'
|
|
Xpath 4096 " X: 0
|
|
endif
|
|
if v:throwpoint !~ '\<T\>'
|
|
Xpath 8192 " X: 0
|
|
endif
|
|
if v:throwpoint !~ '\<4\>'
|
|
Xpath 16384 " X: 0
|
|
endif
|
|
finally
|
|
Xpath 32768 " X: 32768
|
|
if caught || $VIMNOINTTHROW
|
|
Xpath 65536 " X: 65536
|
|
endif
|
|
if v:exception != ""
|
|
Xpath 131072 " X: 0
|
|
endif
|
|
if v:throwpoint != ""
|
|
Xpath 262144 " X: 0
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
Xpath 524288 " X: 524288
|
|
if v:exception != ""
|
|
Xpath 1048576 " X: 0
|
|
endif
|
|
if v:throwpoint != ""
|
|
Xpath 2097152 " X: 0
|
|
endif
|
|
|
|
endif
|
|
|
|
Xcheck 624945
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
"
|
|
" Test 59: v:exception and v:throwpoint when discarding exceptions {{{1
|
|
"
|
|
" When a :catch clause is left by a ":break" etc or an error or
|
|
" interrupt exception, v:exception and v:throwpoint are reset. They
|
|
" are not affected by an exception that is discarded before being
|
|
" caught.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
XloopINIT! 1 2
|
|
|
|
let sfile = expand("<sfile>")
|
|
|
|
function! LineNumber()
|
|
return substitute(substitute(v:throwpoint, g:sfile, '', ""),
|
|
\ '\D*\(\d*\).*', '\1', "")
|
|
endfunction
|
|
|
|
command! -nargs=1 SetLineNumber
|
|
\ try | throw "line" | catch /.*/ | let <args> = LineNumber() | endtry
|
|
|
|
" Check v:exception/v:throwpoint against second/fourth parameter if
|
|
" specified, check for being empty else.
|
|
function! CHECK(n, ...)
|
|
XloopNEXT
|
|
let exception = a:0 != 0 ? a:1 : "" " second parameter (optional)
|
|
let emsg = a:0 != 0 ? a:2 : "" " third parameter (optional)
|
|
let line = a:0 != 0 ? a:3 : 0 " fourth parameter (optional)
|
|
let error = 0
|
|
if emsg != ""
|
|
" exception is the error number, emsg the English error message text
|
|
if exception !~ '^E\d\+$'
|
|
Xout "TODO: Add message number for:" emsg
|
|
elseif v:lang == "C" || v:lang =~ '^[Ee]n'
|
|
if exception == "E492" && emsg == "Not an editor command"
|
|
let exception = '^Vim:' . exception . ': ' . emsg
|
|
else
|
|
let exception = '^Vim(\a\+):' . exception . ': ' . emsg
|
|
endif
|
|
else
|
|
if exception == "E492"
|
|
let exception = '^Vim:' . exception
|
|
else
|
|
let exception = '^Vim(\a\+):' . exception
|
|
endif
|
|
endif
|
|
endif
|
|
if exception == "" && v:exception != ""
|
|
Xout a:n.": v:exception is set:" v:exception
|
|
let error = 1
|
|
elseif exception != "" && v:exception !~ exception
|
|
Xout a:n.": v:exception (".v:exception.") does not match" exception
|
|
let error = 1
|
|
endif
|
|
if line == 0 && v:throwpoint != ""
|
|
Xout a:n.": v:throwpoint is set:" v:throwpoint
|
|
let error = 1
|
|
elseif line != 0 && v:throwpoint !~ '\<' . line . '\>'
|
|
Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
|
|
let error = 1
|
|
endif
|
|
if !error
|
|
Xloop 1 " X: 2097151
|
|
endif
|
|
endfunction
|
|
|
|
while 1
|
|
try
|
|
throw "x1"
|
|
catch /.*/
|
|
break
|
|
endtry
|
|
endwhile
|
|
call CHECK(1)
|
|
|
|
while 1
|
|
try
|
|
throw "x2"
|
|
catch /.*/
|
|
break
|
|
finally
|
|
call CHECK(2)
|
|
endtry
|
|
break
|
|
endwhile
|
|
call CHECK(3)
|
|
|
|
while 1
|
|
try
|
|
let errcaught = 0
|
|
try
|
|
try
|
|
throw "x3"
|
|
catch /.*/
|
|
SetLineNumber line_before_error
|
|
asdf
|
|
endtry
|
|
catch /.*/
|
|
let errcaught = 1
|
|
call CHECK(4, 'E492', "Not an editor command",
|
|
\ line_before_error + 1)
|
|
endtry
|
|
finally
|
|
if !errcaught && $VIMNOERRTHROW
|
|
call CHECK(4)
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
call CHECK(5)
|
|
|
|
Xpath 2097152 " X: 2097152
|
|
|
|
while 1
|
|
try
|
|
let intcaught = 0
|
|
try
|
|
try
|
|
throw "x4"
|
|
catch /.*/
|
|
SetLineNumber two_lines_before_interrupt
|
|
"INTERRUPT
|
|
let dummy = 0
|
|
endtry
|
|
catch /.*/
|
|
let intcaught = 1
|
|
call CHECK(6, "Vim:Interrupt", '',
|
|
\ two_lines_before_interrupt + 2)
|
|
endtry
|
|
finally
|
|
if !intcaught && $VIMNOINTTHROW
|
|
call CHECK(6)
|
|
endif
|
|
break " discard interrupt for $VIMNOINTTHROW
|
|
endtry
|
|
endwhile
|
|
call CHECK(7)
|
|
|
|
Xpath 4194304 " X: 4194304
|
|
|
|
while 1
|
|
try
|
|
let errcaught = 0
|
|
try
|
|
try
|
|
" if 1
|
|
SetLineNumber line_before_throw
|
|
throw "x5"
|
|
" missing endif
|
|
catch /.*/
|
|
Xpath 8388608 " X: 0
|
|
endtry
|
|
catch /.*/
|
|
let errcaught = 1
|
|
call CHECK(8, 'E171', "Missing :endif", line_before_throw + 3)
|
|
endtry
|
|
finally
|
|
if !errcaught && $VIMNOERRTHROW
|
|
call CHECK(8)
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
call CHECK(9)
|
|
|
|
Xpath 16777216 " X: 16777216
|
|
|
|
try
|
|
while 1
|
|
try
|
|
throw "x6"
|
|
finally
|
|
break
|
|
endtry
|
|
break
|
|
endwhile
|
|
catch /.*/
|
|
Xpath 33554432 " X: 0
|
|
endtry
|
|
call CHECK(10)
|
|
|
|
try
|
|
while 1
|
|
try
|
|
throw "x7"
|
|
finally
|
|
break
|
|
endtry
|
|
break
|
|
endwhile
|
|
catch /.*/
|
|
Xpath 67108864 " X: 0
|
|
finally
|
|
call CHECK(11)
|
|
endtry
|
|
call CHECK(12)
|
|
|
|
while 1
|
|
try
|
|
let errcaught = 0
|
|
try
|
|
try
|
|
throw "x8"
|
|
finally
|
|
SetLineNumber line_before_error
|
|
asdf
|
|
endtry
|
|
catch /.*/
|
|
let errcaught = 1
|
|
call CHECK(13, 'E492', "Not an editor command",
|
|
\ line_before_error + 1)
|
|
endtry
|
|
finally
|
|
if !errcaught && $VIMNOERRTHROW
|
|
call CHECK(13)
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
call CHECK(14)
|
|
|
|
Xpath 134217728 " X: 134217728
|
|
|
|
while 1
|
|
try
|
|
let intcaught = 0
|
|
try
|
|
try
|
|
throw "x9"
|
|
finally
|
|
SetLineNumber two_lines_before_interrupt
|
|
"INTERRUPT
|
|
endtry
|
|
catch /.*/
|
|
let intcaught = 1
|
|
call CHECK(15, "Vim:Interrupt", '',
|
|
\ two_lines_before_interrupt + 2)
|
|
endtry
|
|
finally
|
|
if !intcaught && $VIMNOINTTHROW
|
|
call CHECK(15)
|
|
endif
|
|
break " discard interrupt for $VIMNOINTTHROW
|
|
endtry
|
|
endwhile
|
|
call CHECK(16)
|
|
|
|
Xpath 268435456 " X: 268435456
|
|
|
|
while 1
|
|
try
|
|
let errcaught = 0
|
|
try
|
|
try
|
|
" if 1
|
|
SetLineNumber line_before_throw
|
|
throw "x10"
|
|
" missing endif
|
|
finally
|
|
call CHECK(17)
|
|
endtry
|
|
catch /.*/
|
|
let errcaught = 1
|
|
call CHECK(18, 'E171', "Missing :endif", line_before_throw + 3)
|
|
endtry
|
|
finally
|
|
if !errcaught && $VIMNOERRTHROW
|
|
call CHECK(18)
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
call CHECK(19)
|
|
|
|
Xpath 536870912 " X: 536870912
|
|
|
|
while 1
|
|
try
|
|
let errcaught = 0
|
|
try
|
|
try
|
|
" if 1
|
|
SetLineNumber line_before_throw
|
|
throw "x11"
|
|
" missing endif
|
|
endtry
|
|
catch /.*/
|
|
let errcaught = 1
|
|
call CHECK(20, 'E171', "Missing :endif", line_before_throw + 3)
|
|
endtry
|
|
finally
|
|
if !errcaught && $VIMNOERRTHROW
|
|
call CHECK(20)
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
call CHECK(21)
|
|
|
|
Xpath 1073741824 " X: 1073741824
|
|
|
|
endif
|
|
|
|
Xcheck 2038431743
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
"
|
|
" Test 60: (Re)throwing v:exception; :echoerr. {{{1
|
|
"
|
|
" A user exception can be rethrown after catching by throwing
|
|
" v:exception. An error or interrupt exception cannot be rethrown
|
|
" because Vim exceptions cannot be faked. A Vim exception using the
|
|
" value of v:exception can, however, be triggered by the :echoerr
|
|
" command.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
try
|
|
try
|
|
Xpath 1 " X: 1
|
|
throw "oops"
|
|
catch /oops/
|
|
Xpath 2 " X: 2
|
|
throw v:exception " rethrow user exception
|
|
catch /.*/
|
|
Xpath 4 " X: 0
|
|
endtry
|
|
catch /^oops$/ " catches rethrown user exception
|
|
Xpath 8 " X: 8
|
|
catch /.*/
|
|
Xpath 16 " X: 0
|
|
endtry
|
|
|
|
function! F()
|
|
try
|
|
let caught = 0
|
|
try
|
|
Xpath 32 " X: 32
|
|
write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e
|
|
Xpath 64 " X: 0
|
|
Xout "did_emsg was reset before executing " .
|
|
\ "BufWritePost autocommands."
|
|
catch /^Vim(write):/
|
|
let caught = 1
|
|
throw v:exception " throw error: cannot fake Vim exception
|
|
catch /.*/
|
|
Xpath 128 " X: 0
|
|
finally
|
|
Xpath 256 " X: 256
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 512 " X: 0
|
|
endif
|
|
endtry
|
|
catch /^Vim(throw):/ " catches throw error
|
|
let caught = caught + 1
|
|
catch /.*/
|
|
Xpath 1024 " X: 0
|
|
finally
|
|
Xpath 2048 " X: 2048
|
|
if caught != 2
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 4096 " X: 0
|
|
elseif caught
|
|
Xpath 8192 " X: 0
|
|
endif
|
|
return | " discard error for $VIMNOERRTHROW
|
|
endif
|
|
endtry
|
|
endfunction
|
|
|
|
call F()
|
|
delfunction F
|
|
|
|
function! G()
|
|
try
|
|
let caught = 0
|
|
try
|
|
Xpath 16384 " X: 16384
|
|
asdf
|
|
catch /^Vim/ " catch error exception
|
|
let caught = 1
|
|
" Trigger Vim error exception with value specified after :echoerr
|
|
let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
|
|
echoerr value
|
|
catch /.*/
|
|
Xpath 32768 " X: 0
|
|
finally
|
|
Xpath 65536 " X: 65536
|
|
if !caught
|
|
if !$VIMNOERRTHROW
|
|
Xpath 131072 " X: 0
|
|
else
|
|
let value = "Error"
|
|
echoerr value
|
|
endif
|
|
endif
|
|
endtry
|
|
catch /^Vim(echoerr):/
|
|
let caught = caught + 1
|
|
if v:exception !~ value
|
|
Xpath 262144 " X: 0
|
|
endif
|
|
catch /.*/
|
|
Xpath 524288 " X: 0
|
|
finally
|
|
Xpath 1048576 " X: 1048576
|
|
if caught != 2
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 2097152 " X: 0
|
|
elseif caught
|
|
Xpath 4194304 " X: 0
|
|
endif
|
|
return | " discard error for $VIMNOERRTHROW
|
|
endif
|
|
endtry
|
|
endfunction
|
|
|
|
call G()
|
|
delfunction G
|
|
|
|
unlet! value caught
|
|
|
|
if ExtraVim()
|
|
try
|
|
let errcaught = 0
|
|
try
|
|
Xpath 8388608 " X: 8388608
|
|
let intcaught = 0
|
|
"INTERRUPT
|
|
catch /^Vim:/ " catch interrupt exception
|
|
let intcaught = 1
|
|
" Trigger Vim error exception with value specified after :echoerr
|
|
echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
|
|
catch /.*/
|
|
Xpath 16777216 " X: 0
|
|
finally
|
|
Xpath 33554432 " X: 33554432
|
|
if !intcaught
|
|
if !$VIMNOINTTHROW
|
|
Xpath 67108864 " X: 0
|
|
else
|
|
echoerr "Interrupt"
|
|
endif
|
|
endif
|
|
endtry
|
|
catch /^Vim(echoerr):/
|
|
let errcaught = 1
|
|
if v:exception !~ "Interrupt"
|
|
Xpath 134217728 " X: 0
|
|
endif
|
|
finally
|
|
Xpath 268435456 " X: 268435456
|
|
if !errcaught && !$VIMNOERRTHROW
|
|
Xpath 536870912 " X: 0
|
|
endif
|
|
endtry
|
|
endif
|
|
|
|
Xcheck 311511339
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 61: Catching interrupt exceptions {{{1
|
|
"
|
|
" When an interrupt occurs inside a :try/:endtry region, an
|
|
" interrupt exception is thrown and can be caught. Its value is
|
|
" "Vim:Interrupt". If the interrupt occurs after an error or a :throw
|
|
" but before a matching :catch is reached, all following :catches of
|
|
" that try block are ignored, but the interrupt exception can be
|
|
" caught by the next surrounding try conditional. An interrupt is
|
|
" ignored when there is a previous interrupt that has not been caught
|
|
" or causes a :finally clause to be executed.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
while 1
|
|
try
|
|
try
|
|
Xpath 1 " X: 1
|
|
let caught = 0
|
|
"INTERRUPT
|
|
Xpath 2 " X: 0
|
|
catch /^Vim:Interrupt$/
|
|
let caught = 1
|
|
finally
|
|
Xpath 4 " X: 4
|
|
if caught || $VIMNOINTTHROW
|
|
Xpath 8 " X: 8
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 16 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard interrupt for $VIMNOINTTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let caught = 0
|
|
try
|
|
Xpath 32 " X: 32
|
|
asdf
|
|
Xpath 64 " X: 0
|
|
catch /do_not_catch/
|
|
Xpath 128 " X: 0
|
|
catch /.*/ "INTERRUPT - throw interrupt if !$VIMNOERRTHROW
|
|
Xpath 256 " X: 0
|
|
catch /.*/
|
|
Xpath 512 " X: 0
|
|
finally "INTERRUPT - throw interrupt if $VIMNOERRTHROW
|
|
Xpath 1024 " X: 1024
|
|
endtry
|
|
catch /^Vim:Interrupt$/
|
|
let caught = 1
|
|
finally
|
|
Xpath 2048 " X: 2048
|
|
if caught || $VIMNOINTTHROW
|
|
Xpath 4096 " X: 4096
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 8192 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard interrupt for $VIMNOINTTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let caught = 0
|
|
try
|
|
Xpath 16384 " X: 16384
|
|
throw "x"
|
|
Xpath 32768 " X: 0
|
|
catch /do_not_catch/
|
|
Xpath 65536 " X: 0
|
|
catch /x/ "INTERRUPT
|
|
Xpath 131072 " X: 0
|
|
catch /.*/
|
|
Xpath 262144 " X: 0
|
|
endtry
|
|
catch /^Vim:Interrupt$/
|
|
let caught = 1
|
|
finally
|
|
Xpath 524288 " X: 524288
|
|
if caught || $VIMNOINTTHROW
|
|
Xpath 1048576 " X: 1048576
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 2097152 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard interrupt for $VIMNOINTTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
let caught = 0
|
|
try
|
|
Xpath 4194304 " X: 4194304
|
|
"INTERRUPT
|
|
Xpath 8388608 " X: 0
|
|
catch /do_not_catch/ "INTERRUPT
|
|
Xpath 16777216 " X: 0
|
|
catch /^Vim:Interrupt$/
|
|
let caught = 1
|
|
finally
|
|
Xpath 33554432 " X: 33554432
|
|
if caught || $VIMNOINTTHROW
|
|
Xpath 67108864 " X: 67108864
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 134217728 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard interrupt for $VIMNOINTTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
Xpath 268435456 " X: 268435456
|
|
|
|
endif
|
|
|
|
Xcheck 374889517
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 62: Catching error exceptions {{{1
|
|
"
|
|
" An error inside a :try/:endtry region is converted to an exception
|
|
" and can be caught. The error exception has a "Vim(cmdname):" prefix
|
|
" where cmdname is the name of the failing command, or a "Vim:" prefix
|
|
" if no command name is known. The "Vim" prefixes cannot be faked.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! MSG(enr, emsg)
|
|
let english = v:lang == "C" || v:lang =~ '^[Ee]n'
|
|
if a:enr == ""
|
|
Xout "TODO: Add message number for:" a:emsg
|
|
let v:errmsg = ":" . v:errmsg
|
|
endif
|
|
let match = 1
|
|
if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
|
|
let match = 0
|
|
if v:errmsg == ""
|
|
Xout "Message missing."
|
|
else
|
|
let v:errmsg = escape(v:errmsg, '"')
|
|
Xout "Unexpected message:" v:errmsg
|
|
endif
|
|
endif
|
|
return match
|
|
endfunction
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let caught = 0
|
|
unlet novar
|
|
catch /^Vim(unlet):/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "")
|
|
finally
|
|
Xpath 1 " X: 1
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 2 " X: 0
|
|
endif
|
|
if !MSG('E108', "No such variable")
|
|
Xpath 4 " X: 0
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 8 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let caught = 0
|
|
throw novar " error in :throw
|
|
catch /^Vim(throw):/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
|
|
finally
|
|
Xpath 16 " X: 16
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 32 " X: 0
|
|
endif
|
|
if caught ? !MSG('E121', "Undefined variable")
|
|
\ : !MSG('E15', "Invalid expression")
|
|
Xpath 64 " X: 0
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 128 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let caught = 0
|
|
throw "Vim:faked" " error: cannot fake Vim exception
|
|
catch /^Vim(throw):/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
|
|
finally
|
|
Xpath 256 " X: 256
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 512 " X: 0
|
|
endif
|
|
if !MSG('E608', "Cannot :throw exceptions with 'Vim' prefix")
|
|
Xpath 1024 " X: 0
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 2048 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
function! F()
|
|
while 1
|
|
" Missing :endwhile
|
|
endfunction
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let caught = 0
|
|
call F()
|
|
catch /^Vim(endfunction):/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "")
|
|
finally
|
|
Xpath 4096 " X: 4096
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 8192 " X: 0
|
|
endif
|
|
if !MSG('E170', "Missing :endwhile")
|
|
Xpath 16384 " X: 0
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 32768 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let caught = 0
|
|
ExecAsScript F
|
|
catch /^Vim:/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim:', '', "")
|
|
finally
|
|
Xpath 65536 " X: 65536
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 131072 " X: 0
|
|
endif
|
|
if !MSG('E170', "Missing :endwhile")
|
|
Xpath 262144 " X: 0
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 524288 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
function! G()
|
|
call G()
|
|
endfunction
|
|
|
|
while 1
|
|
try
|
|
let mfd_save = &mfd
|
|
set mfd=3
|
|
try
|
|
let caught = 0
|
|
call G()
|
|
catch /^Vim(call):/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim(call):', '', "")
|
|
finally
|
|
Xpath 1048576 " X: 1048576
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 2097152 " X: 0
|
|
endif
|
|
if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
|
|
Xpath 4194304 " X: 0
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 8388608 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
let &mfd = mfd_save
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
function! H()
|
|
return H()
|
|
endfunction
|
|
|
|
while 1
|
|
try
|
|
let mfd_save = &mfd
|
|
set mfd=3
|
|
try
|
|
let caught = 0
|
|
call H()
|
|
catch /^Vim(return):/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim(return):', '', "")
|
|
finally
|
|
Xpath 16777216 " X: 16777216
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 33554432 " X: 0
|
|
endif
|
|
if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
|
|
Xpath 67108864 " X: 0
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 134217728 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
let &mfd = mfd_save
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
unlet! caught mfd_save
|
|
delfunction F
|
|
delfunction G
|
|
delfunction H
|
|
Xpath 268435456 " X: 268435456
|
|
|
|
Xcheck 286331153
|
|
|
|
" Leave MSG() for the next test.
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 63: Suppressing error exceptions by :silent!. {{{1
|
|
"
|
|
" A :silent! command inside a :try/:endtry region suppresses the
|
|
" conversion of errors to an exception and the immediate abortion on
|
|
" error. When the commands executed by the :silent! themselves open
|
|
" a new :try/:endtry region, conversion of errors to exception and
|
|
" immediate abortion is switched on again - until the next :silent!
|
|
" etc. The :silent! has the effect of setting v:errmsg to the error
|
|
" message text (without displaying it) and continuing with the next
|
|
" script line.
|
|
"
|
|
" When a command triggering autocommands is executed by :silent!
|
|
" inside a :try/:endtry, the autocommand execution is not suppressed
|
|
" on error.
|
|
"
|
|
" This test reuses the function MSG() from the previous test.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
XloopINIT! 1 4
|
|
|
|
let taken = ""
|
|
|
|
function! S(n) abort
|
|
XloopNEXT
|
|
let g:taken = g:taken . "E" . a:n
|
|
let v:errmsg = ""
|
|
exec "asdf" . a:n
|
|
|
|
" Check that ":silent!" continues:
|
|
Xloop 1
|
|
|
|
" Check that ":silent!" sets "v:errmsg":
|
|
if MSG('E492', "Not an editor command")
|
|
Xloop 2
|
|
endif
|
|
endfunction
|
|
|
|
function! Foo()
|
|
while 1
|
|
try
|
|
try
|
|
let caught = 0
|
|
" This is not silent:
|
|
call S(3) " X: 0 * 16
|
|
catch /^Vim:/
|
|
let caught = 1
|
|
let errmsg3 = substitute(v:exception, '^Vim:', '', "")
|
|
silent! call S(4) " X: 3 * 64
|
|
finally
|
|
if !caught
|
|
let errmsg3 = v:errmsg
|
|
" Do call S(4) here if not executed in :catch.
|
|
silent! call S(4)
|
|
endif
|
|
Xpath 1048576 " X: 1048576
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 2097152 " X: 0
|
|
endif
|
|
let v:errmsg = errmsg3
|
|
if !MSG('E492', "Not an editor command")
|
|
Xpath 4194304 " X: 0
|
|
endif
|
|
silent! call S(5) " X: 3 * 256
|
|
" Break out of try conditionals that cover ":silent!". This also
|
|
" discards the aborting error when $VIMNOERRTHROW is non-zero.
|
|
break
|
|
endtry
|
|
catch /.*/
|
|
Xpath 8388608 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
endwhile
|
|
" This is a double ":silent!" (see caller).
|
|
silent! call S(6) " X: 3 * 1024
|
|
endfunction
|
|
|
|
function! Bar()
|
|
try
|
|
silent! call S(2) " X: 3 * 4
|
|
" X: 3 * 4096
|
|
silent! execute "call Foo() | call S(7)"
|
|
silent! call S(8) " X: 3 * 16384
|
|
endtry " normal end of try cond that covers ":silent!"
|
|
" This has a ":silent!" from the caller:
|
|
call S(9) " X: 3 * 65536
|
|
endfunction
|
|
|
|
silent! call S(1) " X: 3 * 1
|
|
silent! call Bar()
|
|
silent! call S(10) " X: 3 * 262144
|
|
|
|
let expected = "E1E2E3E4E5E6E7E8E9E10"
|
|
if taken != expected
|
|
Xpath 16777216 " X: 0
|
|
Xout "'taken' is" taken "instead of" expected
|
|
endif
|
|
|
|
augroup TMP
|
|
autocmd BufWritePost * Xpath 33554432 " X: 33554432
|
|
augroup END
|
|
|
|
Xpath 67108864 " X: 67108864
|
|
write /i/m/p/o/s/s/i/b/l/e
|
|
Xpath 134217728 " X: 134217728
|
|
|
|
autocmd! TMP
|
|
unlet! caught errmsg3 taken expected
|
|
delfunction S
|
|
delfunction Foo
|
|
delfunction Bar
|
|
delfunction MSG
|
|
|
|
Xcheck 236978127
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 64: Error exceptions after error, interrupt or :throw {{{1
|
|
"
|
|
" When an error occurs after an interrupt or a :throw but before
|
|
" a matching :catch is reached, all following :catches of that try
|
|
" block are ignored, but the error exception can be caught by the next
|
|
" surrounding try conditional. Any previous error exception is
|
|
" discarded. An error is ignored when there is a previous error that
|
|
" has not been caught.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
while 1
|
|
try
|
|
try
|
|
Xpath 1 " X: 1
|
|
let caught = 0
|
|
while 1
|
|
" if 1
|
|
" Missing :endif
|
|
endwhile " throw error exception
|
|
catch /^Vim(/
|
|
let caught = 1
|
|
finally
|
|
Xpath 2 " X: 2
|
|
if caught || $VIMNOERRTHROW
|
|
Xpath 4 " X: 4
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 8 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
try
|
|
Xpath 16 " X: 16
|
|
let caught = 0
|
|
try
|
|
" if 1
|
|
" Missing :endif
|
|
catch /.*/ " throw error exception
|
|
Xpath 32 " X: 0
|
|
catch /.*/
|
|
Xpath 64 " X: 0
|
|
endtry
|
|
catch /^Vim(/
|
|
let caught = 1
|
|
finally
|
|
Xpath 128 " X: 128
|
|
if caught || $VIMNOERRTHROW
|
|
Xpath 256 " X: 256
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 512 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let caught = 0
|
|
try
|
|
Xpath 1024 " X: 1024
|
|
"INTERRUPT
|
|
catch /do_not_catch/
|
|
Xpath 2048 " X: 0
|
|
" if 1
|
|
" Missing :endif
|
|
catch /.*/ " throw error exception
|
|
Xpath 4096 " X: 0
|
|
catch /.*/
|
|
Xpath 8192 " X: 0
|
|
endtry
|
|
catch /^Vim(/
|
|
let caught = 1
|
|
finally
|
|
Xpath 16384 " X: 16384
|
|
if caught || $VIMNOERRTHROW
|
|
Xpath 32768 " X: 32768
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 65536 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let caught = 0
|
|
try
|
|
Xpath 131072 " X: 131072
|
|
throw "x"
|
|
catch /do_not_catch/
|
|
Xpath 262144 " X: 0
|
|
" if 1
|
|
" Missing :endif
|
|
catch /x/ " throw error exception
|
|
Xpath 524288 " X: 0
|
|
catch /.*/
|
|
Xpath 1048576 " X: 0
|
|
endtry
|
|
catch /^Vim(/
|
|
let caught = 1
|
|
finally
|
|
Xpath 2097152 " X: 2097152
|
|
if caught || $VIMNOERRTHROW
|
|
Xpath 4194304 " X: 4194304
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 8388608 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let caught = 0
|
|
Xpath 16777216 " X: 16777216
|
|
" endif " :endif without :if; throw error exception
|
|
" if 1
|
|
" Missing :endif
|
|
catch /do_not_catch/ " ignore new error
|
|
Xpath 33554432 " X: 0
|
|
catch /^Vim(endif):/
|
|
let caught = 1
|
|
catch /^Vim(/
|
|
Xpath 67108864 " X: 0
|
|
finally
|
|
Xpath 134217728 " X: 134217728
|
|
if caught || $VIMNOERRTHROW
|
|
Xpath 268435456 " X: 268435456
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 536870912 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
Xpath 1073741824 " X: 1073741824
|
|
|
|
endif
|
|
|
|
Xcheck 1499645335
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 65: Errors in the /pattern/ argument of a :catch {{{1
|
|
"
|
|
" On an error in the /pattern/ argument of a :catch, the :catch does
|
|
" not match. Any following :catches of the same :try/:endtry don't
|
|
" match either. Finally clauses are executed.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! MSG(enr, emsg)
|
|
let english = v:lang == "C" || v:lang =~ '^[Ee]n'
|
|
if a:enr == ""
|
|
Xout "TODO: Add message number for:" a:emsg
|
|
let v:errmsg = ":" . v:errmsg
|
|
endif
|
|
let match = 1
|
|
if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
|
|
let match = 0
|
|
if v:errmsg == ""
|
|
Xout "Message missing."
|
|
else
|
|
let v:errmsg = escape(v:errmsg, '"')
|
|
Xout "Unexpected message:" v:errmsg
|
|
endif
|
|
endif
|
|
return match
|
|
endfunction
|
|
|
|
try
|
|
try
|
|
Xpath 1 " X: 1
|
|
throw "oops"
|
|
catch /^oops$/
|
|
Xpath 2 " X: 2
|
|
catch /\)/ " not checked; exception has already been caught
|
|
Xpath 4 " X: 0
|
|
endtry
|
|
Xpath 8 " X: 8
|
|
catch /.*/
|
|
Xpath 16 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
function! F()
|
|
try
|
|
let caught = 0
|
|
try
|
|
try
|
|
Xpath 32 " X: 32
|
|
throw "ab"
|
|
catch /abc/ " does not catch
|
|
Xpath 64 " X: 0
|
|
catch /\)/ " error; discards exception
|
|
Xpath 128 " X: 0
|
|
catch /.*/ " not checked
|
|
Xpath 256 " X: 0
|
|
finally
|
|
Xpath 512 " X: 512
|
|
endtry
|
|
Xpath 1024 " X: 0
|
|
catch /^ab$/ " checked, but original exception is discarded
|
|
Xpath 2048 " X: 0
|
|
catch /^Vim(catch):/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim(catch):', '', "")
|
|
finally
|
|
Xpath 4096 " X: 4096
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 8192 " X: 0
|
|
endif
|
|
if !MSG('E475', "Invalid argument")
|
|
Xpath 16384 " X: 0
|
|
endif
|
|
if !caught
|
|
return | " discard error
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 32768 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
endfunction
|
|
|
|
call F()
|
|
Xpath 65536 " X: 65536
|
|
|
|
delfunction MSG
|
|
delfunction F
|
|
unlet! caught
|
|
|
|
Xcheck 70187
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 66: Stop range :call on error, interrupt, or :throw {{{1
|
|
"
|
|
" When a function which is multiply called for a range since it
|
|
" doesn't handle the range itself has an error in a command
|
|
" dynamically enclosed by :try/:endtry or gets an interrupt or
|
|
" executes a :throw, no more calls for the remaining lines in the
|
|
" range are made. On an error in a command not dynamically enclosed
|
|
" by :try/:endtry, the function is executed again for the remaining
|
|
" lines in the range.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
let file = tempname()
|
|
exec "edit" file
|
|
|
|
insert
|
|
line 1
|
|
line 2
|
|
line 3
|
|
.
|
|
|
|
XloopINIT! 1 2
|
|
|
|
let taken = ""
|
|
let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)"
|
|
|
|
function! F(reason, n) abort
|
|
let g:taken = g:taken . "F" . a:n .
|
|
\ substitute(a:reason, '\(\l\).*', '\u\1', "") .
|
|
\ "(" . line(".") . ")"
|
|
|
|
if a:reason == "error"
|
|
asdf
|
|
elseif a:reason == "interrupt"
|
|
"INTERRUPT
|
|
let dummy = 0
|
|
elseif a:reason == "throw"
|
|
throw "xyz"
|
|
elseif a:reason == "aborting error"
|
|
XloopNEXT
|
|
if g:taken != g:expected
|
|
Xloop 1 " X: 0
|
|
Xout "'taken' is" g:taken "instead of" g:expected
|
|
endif
|
|
try
|
|
bwipeout!
|
|
call delete(file)
|
|
asdf
|
|
endtry
|
|
endif
|
|
endfunction
|
|
|
|
function! G(reason, n)
|
|
let g:taken = g:taken . "G" . a:n .
|
|
\ substitute(a:reason, '\(\l\).*', '\u\1', "")
|
|
1,3call F(a:reason, a:n)
|
|
endfunction
|
|
|
|
Xpath 8 " X: 8
|
|
call G("error", 1)
|
|
try
|
|
Xpath 16 " X: 16
|
|
try
|
|
call G("error", 2)
|
|
Xpath 32 " X: 0
|
|
finally
|
|
Xpath 64 " X: 64
|
|
try
|
|
call G("interrupt", 3)
|
|
Xpath 128 " X: 0
|
|
finally
|
|
Xpath 256 " X: 256
|
|
try
|
|
call G("throw", 4)
|
|
Xpath 512 " X: 0
|
|
endtry
|
|
endtry
|
|
endtry
|
|
catch /xyz/
|
|
Xpath 1024 " X: 1024
|
|
catch /.*/
|
|
Xpath 2048 " X: 0
|
|
Xout v:exception "in" ExtraVimThrowpoint()
|
|
endtry
|
|
Xpath 4096 " X: 4096
|
|
call G("aborting error", 5)
|
|
Xpath 8192 " X: 0
|
|
Xout "'taken' is" taken "instead of" expected
|
|
|
|
endif
|
|
|
|
Xcheck 5464
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 67: :throw across :call command {{{1
|
|
"
|
|
" On a call command, an exception might be thrown when evaluating the
|
|
" function name, during evaluation of the arguments, or when the
|
|
" function is being executed. The exception can be caught by the
|
|
" caller.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! THROW(x, n)
|
|
if a:n == 1
|
|
Xpath 1 " X: 1
|
|
elseif a:n == 2
|
|
Xpath 2 " X: 2
|
|
elseif a:n == 3
|
|
Xpath 4 " X: 4
|
|
endif
|
|
throw a:x
|
|
endfunction
|
|
|
|
function! NAME(x, n)
|
|
if a:n == 1
|
|
Xpath 8 " X: 0
|
|
elseif a:n == 2
|
|
Xpath 16 " X: 16
|
|
elseif a:n == 3
|
|
Xpath 32 " X: 32
|
|
elseif a:n == 4
|
|
Xpath 64 " X: 64
|
|
endif
|
|
return a:x
|
|
endfunction
|
|
|
|
function! ARG(x, n)
|
|
if a:n == 1
|
|
Xpath 128 " X: 0
|
|
elseif a:n == 2
|
|
Xpath 256 " X: 0
|
|
elseif a:n == 3
|
|
Xpath 512 " X: 512
|
|
elseif a:n == 4
|
|
Xpath 1024 " X: 1024
|
|
endif
|
|
return a:x
|
|
endfunction
|
|
|
|
function! F(x, n)
|
|
if a:n == 2
|
|
Xpath 2048 " X: 0
|
|
elseif a:n == 4
|
|
Xpath 4096 " X: 4096
|
|
endif
|
|
endfunction
|
|
|
|
while 1
|
|
try
|
|
let error = 0
|
|
let v:errmsg = ""
|
|
|
|
while 1
|
|
try
|
|
Xpath 8192 " X: 8192
|
|
call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
|
|
Xpath 16384 " X: 0
|
|
catch /^name$/
|
|
Xpath 32768 " X: 32768
|
|
catch /.*/
|
|
let error = 1
|
|
Xout "1:" v:exception "in" v:throwpoint
|
|
finally
|
|
if !error && $VIMNOERRTHROW && v:errmsg != ""
|
|
let error = 1
|
|
Xout "1:" v:errmsg
|
|
endif
|
|
if error
|
|
Xpath 65536 " X: 0
|
|
endif
|
|
let error = 0
|
|
let v:errmsg = ""
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
Xpath 131072 " X: 131072
|
|
call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
|
|
Xpath 262144 " X: 0
|
|
catch /^arg$/
|
|
Xpath 524288 " X: 524288
|
|
catch /.*/
|
|
let error = 1
|
|
Xout "2:" v:exception "in" v:throwpoint
|
|
finally
|
|
if !error && $VIMNOERRTHROW && v:errmsg != ""
|
|
let error = 1
|
|
Xout "2:" v:errmsg
|
|
endif
|
|
if error
|
|
Xpath 1048576 " X: 0
|
|
endif
|
|
let error = 0
|
|
let v:errmsg = ""
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
Xpath 2097152 " X: 2097152
|
|
call {NAME("THROW", 3)}(ARG("call", 3), 3)
|
|
Xpath 4194304 " X: 0
|
|
catch /^call$/
|
|
Xpath 8388608 " X: 8388608
|
|
catch /^0$/ " default return value
|
|
Xpath 16777216 " X: 0
|
|
Xout "3:" v:throwpoint
|
|
catch /.*/
|
|
let error = 1
|
|
Xout "3:" v:exception "in" v:throwpoint
|
|
finally
|
|
if !error && $VIMNOERRTHROW && v:errmsg != ""
|
|
let error = 1
|
|
Xout "3:" v:errmsg
|
|
endif
|
|
if error
|
|
Xpath 33554432 " X: 0
|
|
endif
|
|
let error = 0
|
|
let v:errmsg = ""
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
Xpath 67108864 " X: 67108864
|
|
call {NAME("F", 4)}(ARG(4711, 4), 4)
|
|
Xpath 134217728 " X: 134217728
|
|
catch /.*/
|
|
let error = 1
|
|
Xout "4:" v:exception "in" v:throwpoint
|
|
finally
|
|
if !error && $VIMNOERRTHROW && v:errmsg != ""
|
|
let error = 1
|
|
Xout "4:" v:errmsg
|
|
endif
|
|
if error
|
|
Xpath 268435456 " X: 0
|
|
endif
|
|
let error = 0
|
|
let v:errmsg = ""
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
catch /^0$/ " default return value
|
|
Xpath 536870912 " X: 0
|
|
Xout v:throwpoint
|
|
catch /.*/
|
|
let error = 1
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
if !error && $VIMNOERRTHROW && v:errmsg != ""
|
|
let error = 1
|
|
Xout v:errmsg
|
|
endif
|
|
if error
|
|
Xpath 1073741824 " X: 0
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
unlet error
|
|
delfunction F
|
|
|
|
Xcheck 212514423
|
|
|
|
" Leave THROW(), NAME(), and ARG() for the next test.
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 68: :throw across function calls in expressions {{{1
|
|
"
|
|
" On a function call within an expression, an exception might be
|
|
" thrown when evaluating the function name, during evaluation of the
|
|
" arguments, or when the function is being executed. The exception
|
|
" can be caught by the caller.
|
|
"
|
|
" This test reuses the functions THROW(), NAME(), and ARG() from the
|
|
" previous test.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! F(x, n)
|
|
if a:n == 2
|
|
Xpath 2048 " X: 0
|
|
elseif a:n == 4
|
|
Xpath 4096 " X: 4096
|
|
endif
|
|
return a:x
|
|
endfunction
|
|
|
|
unlet! var1 var2 var3 var4
|
|
|
|
while 1
|
|
try
|
|
let error = 0
|
|
let v:errmsg = ""
|
|
|
|
while 1
|
|
try
|
|
Xpath 8192 " X: 8192
|
|
let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
|
|
Xpath 16384 " X: 0
|
|
catch /^name$/
|
|
Xpath 32768 " X: 32768
|
|
catch /.*/
|
|
let error = 1
|
|
Xout "1:" v:exception "in" v:throwpoint
|
|
finally
|
|
if !error && $VIMNOERRTHROW && v:errmsg != ""
|
|
let error = 1
|
|
Xout "1:" v:errmsg
|
|
endif
|
|
if error
|
|
Xpath 65536 " X: 0
|
|
endif
|
|
let error = 0
|
|
let v:errmsg = ""
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
Xpath 131072 " X: 131072
|
|
let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
|
|
Xpath 262144 " X: 0
|
|
catch /^arg$/
|
|
Xpath 524288 " X: 524288
|
|
catch /.*/
|
|
let error = 1
|
|
Xout "2:" v:exception "in" v:throwpoint
|
|
finally
|
|
if !error && $VIMNOERRTHROW && v:errmsg != ""
|
|
let error = 1
|
|
Xout "2:" v:errmsg
|
|
endif
|
|
if error
|
|
Xpath 1048576 " X: 0
|
|
endif
|
|
let error = 0
|
|
let v:errmsg = ""
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
Xpath 2097152 " X: 2097152
|
|
let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3)
|
|
Xpath 4194304 " X: 0
|
|
catch /^call$/
|
|
Xpath 8388608 " X: 8388608
|
|
catch /^0$/ " default return value
|
|
Xpath 16777216 " X: 0
|
|
Xout "3:" v:throwpoint
|
|
catch /.*/
|
|
let error = 1
|
|
Xout "3:" v:exception "in" v:throwpoint
|
|
finally
|
|
if !error && $VIMNOERRTHROW && v:errmsg != ""
|
|
let error = 1
|
|
Xout "3:" v:errmsg
|
|
endif
|
|
if error
|
|
Xpath 33554432 " X: 0
|
|
endif
|
|
let error = 0
|
|
let v:errmsg = ""
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
Xpath 67108864 " X: 67108864
|
|
let var4 = {NAME("F", 4)}(ARG(4711, 4), 4)
|
|
Xpath 134217728 " X: 134217728
|
|
catch /.*/
|
|
let error = 1
|
|
Xout "4:" v:exception "in" v:throwpoint
|
|
finally
|
|
if !error && $VIMNOERRTHROW && v:errmsg != ""
|
|
let error = 1
|
|
Xout "4:" v:errmsg
|
|
endif
|
|
if error
|
|
Xpath 268435456 " X: 0
|
|
endif
|
|
let error = 0
|
|
let v:errmsg = ""
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
catch /^0$/ " default return value
|
|
Xpath 536870912 " X: 0
|
|
Xout v:throwpoint
|
|
catch /.*/
|
|
let error = 1
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
if !error && $VIMNOERRTHROW && v:errmsg != ""
|
|
let error = 1
|
|
Xout v:errmsg
|
|
endif
|
|
if error
|
|
Xpath 1073741824 " X: 0
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
if exists("var1") || exists("var2") || exists("var3") ||
|
|
\ !exists("var4") || var4 != 4711
|
|
" The Xpath command does not accept 2^31 (negative); add explicitly:
|
|
let Xpath = Xpath + 2147483648 " X: 0
|
|
if exists("var1")
|
|
Xout "var1 =" var1
|
|
endif
|
|
if exists("var2")
|
|
Xout "var2 =" var2
|
|
endif
|
|
if exists("var3")
|
|
Xout "var3 =" var3
|
|
endif
|
|
if !exists("var4")
|
|
Xout "var4 unset"
|
|
elseif var4 != 4711
|
|
Xout "var4 =" var4
|
|
endif
|
|
endif
|
|
|
|
unlet! error var1 var2 var3 var4
|
|
delfunction THROW
|
|
delfunction NAME
|
|
delfunction ARG
|
|
delfunction F
|
|
|
|
Xcheck 212514423
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 69: :throw across :if, :elseif, :while {{{1
|
|
"
|
|
" On an :if, :elseif, or :while command, an exception might be thrown
|
|
" during evaluation of the expression to test. The exception can be
|
|
" caught by the script.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
XloopINIT! 1 2
|
|
|
|
function! THROW(x)
|
|
XloopNEXT
|
|
Xloop 1 " X: 1 + 2 + 4
|
|
throw a:x
|
|
endfunction
|
|
|
|
try
|
|
|
|
try
|
|
Xpath 8 " X: 8
|
|
if 4711 == THROW("if") + 111
|
|
Xpath 16 " X: 0
|
|
else
|
|
Xpath 32 " X: 0
|
|
endif
|
|
Xpath 64 " X: 0
|
|
catch /^if$/
|
|
Xpath 128 " X: 128
|
|
catch /.*/
|
|
Xpath 256 " X: 0
|
|
Xout "if:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
Xpath 512 " X: 512
|
|
if 4711 == 4 + 7 + 1 + 1
|
|
Xpath 1024 " X: 0
|
|
elseif 4711 == THROW("elseif") + 222
|
|
Xpath 2048 " X: 0
|
|
else
|
|
Xpath 4096 " X: 0
|
|
endif
|
|
Xpath 8192 " X: 0
|
|
catch /^elseif$/
|
|
Xpath 16384 " X: 16384
|
|
catch /.*/
|
|
Xpath 32768 " X: 0
|
|
Xout "elseif:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
Xpath 65536 " X: 65536
|
|
while 4711 == THROW("while") + 4711
|
|
Xpath 131072 " X: 0
|
|
break
|
|
endwhile
|
|
Xpath 262144 " X: 0
|
|
catch /^while$/
|
|
Xpath 524288 " X: 524288
|
|
catch /.*/
|
|
Xpath 1048576 " X: 0
|
|
Xout "while:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
catch /^0$/ " default return value
|
|
Xpath 2097152 " X: 0
|
|
Xout v:throwpoint
|
|
catch /.*/
|
|
Xout v:exception "in" v:throwpoint
|
|
Xpath 4194304 " X: 0
|
|
endtry
|
|
|
|
Xpath 8388608 " X: 8388608
|
|
|
|
delfunction THROW
|
|
|
|
Xcheck 8995471
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 70: :throw across :return or :throw {{{1
|
|
"
|
|
" On a :return or :throw command, an exception might be thrown during
|
|
" evaluation of the expression to return or throw, respectively. The
|
|
" exception can be caught by the script.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
let taken = ""
|
|
|
|
function! THROW(x, n)
|
|
let g:taken = g:taken . "T" . a:n
|
|
throw a:x
|
|
endfunction
|
|
|
|
function! F(x, y, n)
|
|
let g:taken = g:taken . "F" . a:n
|
|
return a:x + THROW(a:y, a:n)
|
|
endfunction
|
|
|
|
function! G(x, y, n)
|
|
let g:taken = g:taken . "G" . a:n
|
|
throw a:x . THROW(a:y, a:n)
|
|
return a:x
|
|
endfunction
|
|
|
|
try
|
|
try
|
|
Xpath 1 " X: 1
|
|
call F(4711, "return", 1)
|
|
Xpath 2 " X: 0
|
|
catch /^return$/
|
|
Xpath 4 " X: 4
|
|
catch /.*/
|
|
Xpath 8 " X: 0
|
|
Xout "return:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
Xpath 16 " X: 16
|
|
let var = F(4712, "return-var", 2)
|
|
Xpath 32 " X: 0
|
|
catch /^return-var$/
|
|
Xpath 64 " X: 64
|
|
catch /.*/
|
|
Xpath 128 " X: 0
|
|
Xout "return-var:" v:exception "in" v:throwpoint
|
|
finally
|
|
unlet! var
|
|
endtry
|
|
|
|
try
|
|
Xpath 256 " X: 256
|
|
throw "except1" . THROW("throw1", 3)
|
|
Xpath 512 " X: 0
|
|
catch /^except1/
|
|
Xpath 1024 " X: 0
|
|
catch /^throw1$/
|
|
Xpath 2048 " X: 2048
|
|
catch /.*/
|
|
Xpath 4096 " X: 0
|
|
Xout "throw1:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
Xpath 8192 " X: 8192
|
|
call G("except2", "throw2", 4)
|
|
Xpath 16384 " X: 0
|
|
catch /^except2/
|
|
Xpath 32768 " X: 0
|
|
catch /^throw2$/
|
|
Xpath 65536 " X: 65536
|
|
catch /.*/
|
|
Xpath 131072 " X: 0
|
|
Xout "throw2:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
Xpath 262144 " X: 262144
|
|
let var = G("except3", "throw3", 5)
|
|
Xpath 524288 " X: 0
|
|
catch /^except3/
|
|
Xpath 1048576 " X: 0
|
|
catch /^throw3$/
|
|
Xpath 2097152 " X: 2097152
|
|
catch /.*/
|
|
Xpath 4194304 " X: 0
|
|
Xout "throw3:" v:exception "in" v:throwpoint
|
|
finally
|
|
unlet! var
|
|
endtry
|
|
|
|
let expected = "F1T1F2T2T3G4T4G5T5"
|
|
if taken != expected
|
|
Xpath 8388608 " X: 0
|
|
Xout "'taken' is" taken "instead of" expected
|
|
endif
|
|
|
|
catch /^0$/ " default return value
|
|
Xpath 16777216 " X: 0
|
|
Xout v:throwpoint
|
|
catch /.*/
|
|
Xpath 33554432 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
Xpath 67108864 " X: 67108864
|
|
|
|
unlet taken expected
|
|
delfunction THROW
|
|
delfunction F
|
|
delfunction G
|
|
|
|
Xcheck 69544277
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 71: :throw across :echo variants and :execute {{{1
|
|
"
|
|
" On an :echo, :echon, :echomsg, :echoerr, or :execute command, an
|
|
" exception might be thrown during evaluation of the arguments to
|
|
" be displayed or executed as a command, respectively. Any following
|
|
" arguments are not evaluated, then. The exception can be caught by
|
|
" the script.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
let taken = ""
|
|
|
|
function! THROW(x, n)
|
|
let g:taken = g:taken . "T" . a:n
|
|
throw a:x
|
|
endfunction
|
|
|
|
function! F(n)
|
|
let g:taken = g:taken . "F" . a:n
|
|
return "F" . a:n
|
|
endfunction
|
|
|
|
try
|
|
try
|
|
Xpath 1 " X: 1
|
|
echo "echo" . THROW("echo-except", 1) F(1)
|
|
Xpath 2 " X: 0
|
|
catch /^echo-except$/
|
|
Xpath 4 " X: 4
|
|
catch /.*/
|
|
Xpath 8 " X: 0
|
|
Xout "echo:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
Xpath 16 " X: 16
|
|
echon "echon" . THROW("echon-except", 2) F(2)
|
|
Xpath 32 " X: 0
|
|
catch /^echon-except$/
|
|
Xpath 64 " X: 64
|
|
catch /.*/
|
|
Xpath 128 " X: 0
|
|
Xout "echon:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
Xpath 256 " X: 256
|
|
echomsg "echomsg" . THROW("echomsg-except", 3) F(3)
|
|
Xpath 512 " X: 0
|
|
catch /^echomsg-except$/
|
|
Xpath 1024 " X: 1024
|
|
catch /.*/
|
|
Xpath 2048 " X: 0
|
|
Xout "echomsg:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
Xpath 4096 " X: 4096
|
|
echoerr "echoerr" . THROW("echoerr-except", 4) F(4)
|
|
Xpath 8192 " X: 0
|
|
catch /^echoerr-except$/
|
|
Xpath 16384 " X: 16384
|
|
catch /Vim/
|
|
Xpath 32768 " X: 0
|
|
catch /echoerr/
|
|
Xpath 65536 " X: 0
|
|
catch /.*/
|
|
Xpath 131072 " X: 0
|
|
Xout "echoerr:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
Xpath 262144 " X: 262144
|
|
execute "echo 'execute" . THROW("execute-except", 5) F(5) "'"
|
|
Xpath 524288 " X: 0
|
|
catch /^execute-except$/
|
|
Xpath 1048576 " X: 1048576
|
|
catch /.*/
|
|
Xpath 2097152 " X: 0
|
|
Xout "execute:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
let expected = "T1T2T3T4T5"
|
|
if taken != expected
|
|
Xpath 4194304 " X: 0
|
|
Xout "'taken' is" taken "instead of" expected
|
|
endif
|
|
|
|
catch /^0$/ " default return value
|
|
Xpath 8388608 " X: 0
|
|
Xout v:throwpoint
|
|
catch /.*/
|
|
Xpath 16777216 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
Xpath 33554432 " X: 33554432
|
|
|
|
unlet taken expected
|
|
delfunction THROW
|
|
delfunction F
|
|
|
|
Xcheck 34886997
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 72: :throw across :let or :unlet {{{1
|
|
"
|
|
" On a :let command, an exception might be thrown during evaluation
|
|
" of the expression to assign. On an :let or :unlet command, the
|
|
" evaluation of the name of the variable to be assigned or list or
|
|
" deleted, respectively, may throw an exception. Any following
|
|
" arguments are not evaluated, then. The exception can be caught by
|
|
" the script.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
let throwcount = 0
|
|
|
|
function! THROW(x)
|
|
let g:throwcount = g:throwcount + 1
|
|
throw a:x
|
|
endfunction
|
|
|
|
try
|
|
try
|
|
let $VAR = "old_value"
|
|
Xpath 1 " X: 1
|
|
let $VAR = "let(" . THROW("var") . ")"
|
|
Xpath 2 " X: 0
|
|
catch /^var$/
|
|
Xpath 4 " X: 4
|
|
finally
|
|
if $VAR != "old_value"
|
|
Xpath 8 " X: 0
|
|
endif
|
|
endtry
|
|
|
|
try
|
|
let @a = "old_value"
|
|
Xpath 16 " X: 16
|
|
let @a = "let(" . THROW("reg") . ")"
|
|
Xpath 32 " X: 0
|
|
catch /^reg$/
|
|
try
|
|
Xpath 64 " X: 64
|
|
let @A = "let(" . THROW("REG") . ")"
|
|
Xpath 128 " X: 0
|
|
catch /^REG$/
|
|
Xpath 256 " X: 256
|
|
endtry
|
|
finally
|
|
if @a != "old_value"
|
|
Xpath 512 " X: 0
|
|
endif
|
|
if @A != "old_value"
|
|
Xpath 1024 " X: 0
|
|
endif
|
|
endtry
|
|
|
|
try
|
|
let saved_gpath = &g:path
|
|
let saved_lpath = &l:path
|
|
Xpath 2048 " X: 2048
|
|
let &path = "let(" . THROW("opt") . ")"
|
|
Xpath 4096 " X: 0
|
|
catch /^opt$/
|
|
try
|
|
Xpath 8192 " X: 8192
|
|
let &g:path = "let(" . THROW("gopt") . ")"
|
|
Xpath 16384 " X: 0
|
|
catch /^gopt$/
|
|
try
|
|
Xpath 32768 " X: 32768
|
|
let &l:path = "let(" . THROW("lopt") . ")"
|
|
Xpath 65536 " X: 0
|
|
catch /^lopt$/
|
|
Xpath 131072 " X: 131072
|
|
endtry
|
|
endtry
|
|
finally
|
|
if &g:path != saved_gpath || &l:path != saved_lpath
|
|
Xpath 262144 " X: 0
|
|
endif
|
|
let &g:path = saved_gpath
|
|
let &l:path = saved_lpath
|
|
endtry
|
|
|
|
unlet! var1 var2 var3
|
|
|
|
try
|
|
Xpath 524288 " X: 524288
|
|
let var1 = "let(" . THROW("var1") . ")"
|
|
Xpath 1048576 " X: 0
|
|
catch /^var1$/
|
|
Xpath 2097152 " X: 2097152
|
|
finally
|
|
if exists("var1")
|
|
Xpath 4194304 " X: 0
|
|
endif
|
|
endtry
|
|
|
|
try
|
|
let var2 = "old_value"
|
|
Xpath 8388608 " X: 8388608
|
|
let var2 = "let(" . THROW("var2"). ")"
|
|
Xpath 16777216 " X: 0
|
|
catch /^var2$/
|
|
Xpath 33554432 " X: 33554432
|
|
finally
|
|
if var2 != "old_value"
|
|
Xpath 67108864 " X: 0
|
|
endif
|
|
endtry
|
|
|
|
try
|
|
Xpath 134217728 " X: 134217728
|
|
let var{THROW("var3")} = 4711
|
|
Xpath 268435456 " X: 0
|
|
catch /^var3$/
|
|
Xpath 536870912 " X: 536870912
|
|
endtry
|
|
|
|
let addpath = ""
|
|
|
|
function ADDPATH(p)
|
|
let g:addpath = g:addpath . a:p
|
|
endfunction
|
|
|
|
try
|
|
call ADDPATH("T1")
|
|
let var{THROW("var4")} var{ADDPATH("T2")} | call ADDPATH("T3")
|
|
call ADDPATH("T4")
|
|
catch /^var4$/
|
|
call ADDPATH("T5")
|
|
endtry
|
|
|
|
try
|
|
call ADDPATH("T6")
|
|
unlet var{THROW("var5")} var{ADDPATH("T7")} | call ADDPATH("T8")
|
|
call ADDPATH("T9")
|
|
catch /^var5$/
|
|
call ADDPATH("T10")
|
|
endtry
|
|
|
|
if addpath != "T1T5T6T10" || throwcount != 11
|
|
throw "addpath: " . addpath . ", throwcount: " . throwcount
|
|
endif
|
|
|
|
Xpath 1073741824 " X: 1073741824
|
|
|
|
catch /.*/
|
|
" The Xpath command does not accept 2^31 (negative); add explicitly:
|
|
let Xpath = Xpath + 2147483648 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
unlet! var1 var2 var3 addpath throwcount
|
|
delfunction THROW
|
|
|
|
Xcheck 1789569365
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 73: :throw across :function, :delfunction {{{1
|
|
"
|
|
" The :function and :delfunction commands may cause an expression
|
|
" specified in braces to be evaluated. During evaluation, an
|
|
" exception might be thrown. The exception can be caught by the
|
|
" script.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
let taken = ""
|
|
|
|
function! THROW(x, n)
|
|
let g:taken = g:taken . "T" . a:n
|
|
throw a:x
|
|
endfunction
|
|
|
|
function! EXPR(x, n)
|
|
let g:taken = g:taken . "E" . a:n
|
|
if a:n % 2 == 0
|
|
call THROW(a:x, a:n)
|
|
endif
|
|
return 2 - a:n % 2
|
|
endfunction
|
|
|
|
try
|
|
try
|
|
" Define function.
|
|
Xpath 1 " X: 1
|
|
function! F0()
|
|
endfunction
|
|
Xpath 2 " X: 2
|
|
function! F{EXPR("function-def-ok", 1)}()
|
|
endfunction
|
|
Xpath 4 " X: 4
|
|
function! F{EXPR("function-def", 2)}()
|
|
endfunction
|
|
Xpath 8 " X: 0
|
|
catch /^function-def-ok$/
|
|
Xpath 16 " X: 0
|
|
catch /^function-def$/
|
|
Xpath 32 " X: 32
|
|
catch /.*/
|
|
Xpath 64 " X: 0
|
|
Xout "def:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
" List function.
|
|
Xpath 128 " X: 128
|
|
function F0
|
|
Xpath 256 " X: 256
|
|
function F{EXPR("function-lst-ok", 3)}
|
|
Xpath 512 " X: 512
|
|
function F{EXPR("function-lst", 4)}
|
|
Xpath 1024 " X: 0
|
|
catch /^function-lst-ok$/
|
|
Xpath 2048 " X: 0
|
|
catch /^function-lst$/
|
|
Xpath 4096 " X: 4096
|
|
catch /.*/
|
|
Xpath 8192 " X: 0
|
|
Xout "lst:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
" Delete function
|
|
Xpath 16384 " X: 16384
|
|
delfunction F0
|
|
Xpath 32768 " X: 32768
|
|
delfunction F{EXPR("function-del-ok", 5)}
|
|
Xpath 65536 " X: 65536
|
|
delfunction F{EXPR("function-del", 6)}
|
|
Xpath 131072 " X: 0
|
|
catch /^function-del-ok$/
|
|
Xpath 262144 " X: 0
|
|
catch /^function-del$/
|
|
Xpath 524288 " X: 524288
|
|
catch /.*/
|
|
Xpath 1048576 " X: 0
|
|
Xout "del:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
let expected = "E1E2T2E3E4T4E5E6T6"
|
|
if taken != expected
|
|
Xpath 2097152 " X: 0
|
|
Xout "'taken' is" taken "instead of" expected
|
|
endif
|
|
|
|
catch /.*/
|
|
Xpath 4194304 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
Xpath 8388608 " X: 8388608
|
|
|
|
unlet taken expected
|
|
delfunction THROW
|
|
delfunction EXPR
|
|
|
|
Xcheck 9032615
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 74: :throw across builtin functions and commands {{{1
|
|
"
|
|
" Some functions like exists(), searchpair() take expression
|
|
" arguments, other functions or commands like substitute() or
|
|
" :substitute cause an expression (specified in the regular
|
|
" expression) to be evaluated. During evaluation an exception
|
|
" might be thrown. The exception can be caught by the script.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
let taken = ""
|
|
|
|
function! THROW(x, n)
|
|
let g:taken = g:taken . "T" . a:n
|
|
throw a:x
|
|
endfunction
|
|
|
|
function! EXPR(x, n)
|
|
let g:taken = g:taken . "E" . a:n
|
|
call THROW(a:x . a:n, a:n)
|
|
return "EXPR"
|
|
endfunction
|
|
|
|
function! SKIP(x, n)
|
|
let g:taken = g:taken . "S" . a:n . "(" . line(".")
|
|
let theline = getline(".")
|
|
if theline =~ "skip"
|
|
let g:taken = g:taken . "s)"
|
|
return 1
|
|
elseif theline =~ "throw"
|
|
let g:taken = g:taken . "t)"
|
|
call THROW(a:x . a:n, a:n)
|
|
else
|
|
let g:taken = g:taken . ")"
|
|
return 0
|
|
endif
|
|
endfunction
|
|
|
|
function! SUBST(x, n)
|
|
let g:taken = g:taken . "U" . a:n . "(" . line(".")
|
|
let theline = getline(".")
|
|
if theline =~ "not" " SUBST() should not be called for this line
|
|
let g:taken = g:taken . "n)"
|
|
call THROW(a:x . a:n, a:n)
|
|
elseif theline =~ "throw"
|
|
let g:taken = g:taken . "t)"
|
|
call THROW(a:x . a:n, a:n)
|
|
else
|
|
let g:taken = g:taken . ")"
|
|
return "replaced"
|
|
endif
|
|
endfunction
|
|
|
|
try
|
|
try
|
|
Xpath 1 " X: 1
|
|
let result = exists('*{EXPR("exists", 1)}')
|
|
Xpath 2 " X: 0
|
|
catch /^exists1$/
|
|
Xpath 4 " X: 4
|
|
try
|
|
let result = exists('{EXPR("exists", 2)}')
|
|
Xpath 8 " X: 0
|
|
catch /^exists2$/
|
|
Xpath 16 " X: 16
|
|
catch /.*/
|
|
Xpath 32 " X: 0
|
|
Xout "exists2:" v:exception "in" v:throwpoint
|
|
endtry
|
|
catch /.*/
|
|
Xpath 64 " X: 0
|
|
Xout "exists1:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
let file = tempname()
|
|
exec "edit" file
|
|
insert
|
|
begin
|
|
xx
|
|
middle 3
|
|
xx
|
|
middle 5 skip
|
|
xx
|
|
middle 7 throw
|
|
xx
|
|
end
|
|
.
|
|
normal! gg
|
|
Xpath 128 " X: 128
|
|
let result =
|
|
\ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 3)')
|
|
Xpath 256 " X: 256
|
|
let result =
|
|
\ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 4)')
|
|
Xpath 512 " X: 0
|
|
let result =
|
|
\ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 5)')
|
|
Xpath 1024 " X: 0
|
|
catch /^searchpair[35]$/
|
|
Xpath 2048 " X: 0
|
|
catch /^searchpair4$/
|
|
Xpath 4096 " X: 4096
|
|
catch /.*/
|
|
Xpath 8192 " X: 0
|
|
Xout "searchpair:" v:exception "in" v:throwpoint
|
|
finally
|
|
bwipeout!
|
|
call delete(file)
|
|
endtry
|
|
|
|
try
|
|
let file = tempname()
|
|
exec "edit" file
|
|
insert
|
|
subst 1
|
|
subst 2
|
|
not
|
|
subst 4
|
|
subst throw
|
|
subst 6
|
|
.
|
|
normal! gg
|
|
Xpath 16384 " X: 16384
|
|
1,2substitute/subst/\=SUBST("substitute", 6)/
|
|
try
|
|
Xpath 32768 " X: 32768
|
|
try
|
|
let v:errmsg = ""
|
|
3substitute/subst/\=SUBST("substitute", 7)/
|
|
finally
|
|
if v:errmsg != ""
|
|
" If exceptions are not thrown on errors, fake the error
|
|
" exception in order to get the same execution path.
|
|
throw "faked Vim(substitute)"
|
|
endif
|
|
endtry
|
|
catch /Vim(substitute)/ " Pattern not found ('e' flag missing)
|
|
Xpath 65536 " X: 65536
|
|
3substitute/subst/\=SUBST("substitute", 8)/e
|
|
Xpath 131072 " X: 131072
|
|
endtry
|
|
Xpath 262144 " X: 262144
|
|
4,6substitute/subst/\=SUBST("substitute", 9)/
|
|
Xpath 524288 " X: 0
|
|
catch /^substitute[678]/
|
|
Xpath 1048576 " X: 0
|
|
catch /^substitute9/
|
|
Xpath 2097152 " X: 2097152
|
|
finally
|
|
bwipeout!
|
|
call delete(file)
|
|
endtry
|
|
|
|
try
|
|
Xpath 4194304 " X: 4194304
|
|
let var = substitute("sub", "sub", '\=THROW("substitute()y", 10)', '')
|
|
Xpath 8388608 " X: 0
|
|
catch /substitute()y/
|
|
Xpath 16777216 " X: 16777216
|
|
catch /.*/
|
|
Xpath 33554432 " X: 0
|
|
Xout "substitute()y:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
try
|
|
Xpath 67108864 " X: 67108864
|
|
let var = substitute("not", "sub", '\=THROW("substitute()n", 11)', '')
|
|
Xpath 134217728 " X: 134217728
|
|
catch /substitute()n/
|
|
Xpath 268435456 " X: 0
|
|
catch /.*/
|
|
Xpath 536870912 " X: 0
|
|
Xout "substitute()n:" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
let expected = "E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10"
|
|
if taken != expected
|
|
Xpath 1073741824 " X: 0
|
|
Xout "'taken' is" taken "instead of" expected
|
|
endif
|
|
|
|
catch /.*/
|
|
" The Xpath command does not accept 2^31 (negative); add explicitly:
|
|
let Xpath = Xpath + 2147483648 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
unlet result var taken expected
|
|
delfunction THROW
|
|
delfunction EXPR
|
|
delfunction SKIP
|
|
delfunction SUBST
|
|
|
|
Xcheck 224907669
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 75: Errors in builtin functions. {{{1
|
|
"
|
|
" On an error in a builtin function called inside a :try/:endtry
|
|
" region, the evaluation of the expression calling that function and
|
|
" the command containing that expression are abandoned. The error can
|
|
" be caught as an exception.
|
|
"
|
|
" A simple :call of the builtin function is a trivial case. If the
|
|
" builtin function is called in the argument list of another function,
|
|
" no further arguments are evaluated, and the other function is not
|
|
" executed. If the builtin function is called from the argument of
|
|
" a :return command, the :return command is not executed. If the
|
|
" builtin function is called from the argument of a :throw command,
|
|
" the :throw command is not executed. The evaluation of the
|
|
" expression calling the builtin function is abandoned.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! F1(arg1)
|
|
Xpath 1 " X: 0
|
|
endfunction
|
|
|
|
function! F2(arg1, arg2)
|
|
Xpath 2 " X: 0
|
|
endfunction
|
|
|
|
function! G()
|
|
Xpath 4 " X: 0
|
|
endfunction
|
|
|
|
function! H()
|
|
Xpath 8 " X: 0
|
|
endfunction
|
|
|
|
function! R()
|
|
while 1
|
|
try
|
|
let caught = 0
|
|
let v:errmsg = ""
|
|
Xpath 16 " X: 16
|
|
return append(1, "s")
|
|
catch /E21/
|
|
let caught = 1
|
|
catch /.*/
|
|
Xpath 32 " X: 0
|
|
finally
|
|
Xpath 64 " X: 64
|
|
if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
|
|
Xpath 128 " X: 128
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
Xpath 256 " X: 256
|
|
endfunction
|
|
|
|
try
|
|
set noma " let append() fail with "E21"
|
|
|
|
while 1
|
|
try
|
|
let caught = 0
|
|
let v:errmsg = ""
|
|
Xpath 512 " X: 512
|
|
call append(1, "s")
|
|
catch /E21/
|
|
let caught = 1
|
|
catch /.*/
|
|
Xpath 1024 " X: 0
|
|
finally
|
|
Xpath 2048 " X: 2048
|
|
if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
|
|
Xpath 4096 " X: 4096
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
let caught = 0
|
|
let v:errmsg = ""
|
|
Xpath 8192 " X: 8192
|
|
call F1('x' . append(1, "s"))
|
|
catch /E21/
|
|
let caught = 1
|
|
catch /.*/
|
|
Xpath 16384 " X: 0
|
|
finally
|
|
Xpath 32768 " X: 32768
|
|
if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
|
|
Xpath 65536 " X: 65536
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
let caught = 0
|
|
let v:errmsg = ""
|
|
Xpath 131072 " X: 131072
|
|
call F2('x' . append(1, "s"), G())
|
|
catch /E21/
|
|
let caught = 1
|
|
catch /.*/
|
|
Xpath 262144 " X: 0
|
|
finally
|
|
Xpath 524288 " X: 524288
|
|
if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
|
|
Xpath 1048576 " X: 1048576
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
call R()
|
|
|
|
while 1
|
|
try
|
|
let caught = 0
|
|
let v:errmsg = ""
|
|
Xpath 2097152 " X: 2097152
|
|
throw "T" . append(1, "s")
|
|
catch /E21/
|
|
let caught = 1
|
|
catch /^T.*/
|
|
Xpath 4194304 " X: 0
|
|
catch /.*/
|
|
Xpath 8388608 " X: 0
|
|
finally
|
|
Xpath 16777216 " X: 16777216
|
|
if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
|
|
Xpath 33554432 " X: 33554432
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
let caught = 0
|
|
let v:errmsg = ""
|
|
Xpath 67108864 " X: 67108864
|
|
let x = "a"
|
|
let x = x . "b" . append(1, "s") . H()
|
|
catch /E21/
|
|
let caught = 1
|
|
catch /.*/
|
|
Xpath 134217728 " X: 0
|
|
finally
|
|
Xpath 268435456 " X: 268435456
|
|
if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
|
|
Xpath 536870912 " X: 536870912
|
|
endif
|
|
if x == "a"
|
|
Xpath 1073741824 " X: 1073741824
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
catch /.*/
|
|
" The Xpath command does not accept 2^31 (negative); add explicitly:
|
|
let Xpath = Xpath + 2147483648 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
set ma&
|
|
endtry
|
|
|
|
unlet! caught x
|
|
delfunction F1
|
|
delfunction F2
|
|
delfunction G
|
|
delfunction H
|
|
delfunction R
|
|
|
|
Xcheck 2000403408
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 76: Errors, interrupts, :throw during expression evaluation {{{1
|
|
"
|
|
" When a function call made during expression evaluation is aborted
|
|
" due to an error inside a :try/:endtry region or due to an interrupt
|
|
" or a :throw, the expression evaluation is aborted as well. No
|
|
" message is displayed for the cancelled expression evaluation. On an
|
|
" error not inside :try/:endtry, the expression evaluation continues.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
let taken = ""
|
|
|
|
function! ERR(n)
|
|
let g:taken = g:taken . "E" . a:n
|
|
asdf
|
|
endfunction
|
|
|
|
function! ERRabort(n) abort
|
|
let g:taken = g:taken . "A" . a:n
|
|
asdf
|
|
endfunction " returns -1; may cause follow-up msg for illegal var/func name
|
|
|
|
function! WRAP(n, arg)
|
|
let g:taken = g:taken . "W" . a:n
|
|
let g:saved_errmsg = v:errmsg
|
|
return arg
|
|
endfunction
|
|
|
|
function! INT(n)
|
|
let g:taken = g:taken . "I" . a:n
|
|
"INTERRUPT9
|
|
let dummy = 0
|
|
endfunction
|
|
|
|
function! THR(n)
|
|
let g:taken = g:taken . "T" . a:n
|
|
throw "should not be caught"
|
|
endfunction
|
|
|
|
function! CONT(n)
|
|
let g:taken = g:taken . "C" . a:n
|
|
endfunction
|
|
|
|
function! MSG(n)
|
|
let g:taken = g:taken . "M" . a:n
|
|
let errmsg = (a:n >= 37 && a:n <= 44) ? g:saved_errmsg : v:errmsg
|
|
let msgptn = (a:n >= 10 && a:n <= 27) ? "^$" : "asdf"
|
|
if errmsg !~ msgptn
|
|
let g:taken = g:taken . "x"
|
|
Xout "Expr" a:n.": Unexpected message:" v:errmsg
|
|
endif
|
|
let v:errmsg = ""
|
|
let g:saved_errmsg = ""
|
|
endfunction
|
|
|
|
let v:errmsg = ""
|
|
|
|
try
|
|
let t = 1
|
|
XloopINIT 1 2
|
|
while t <= 9
|
|
Xloop 1 " X: 511
|
|
try
|
|
if t == 1
|
|
let v{ERR(t) + CONT(t)} = 0
|
|
elseif t == 2
|
|
let v{ERR(t) + CONT(t)}
|
|
elseif t == 3
|
|
let var = exists('v{ERR(t) + CONT(t)}')
|
|
elseif t == 4
|
|
unlet v{ERR(t) + CONT(t)}
|
|
elseif t == 5
|
|
function F{ERR(t) + CONT(t)}()
|
|
endfunction
|
|
elseif t == 6
|
|
function F{ERR(t) + CONT(t)}
|
|
elseif t == 7
|
|
let var = exists('*F{ERR(t) + CONT(t)}')
|
|
elseif t == 8
|
|
delfunction F{ERR(t) + CONT(t)}
|
|
elseif t == 9
|
|
let var = ERR(t) + CONT(t)
|
|
endif
|
|
catch /asdf/
|
|
" v:errmsg is not set when the error message is converted to an
|
|
" exception. Set it to the original error message.
|
|
let v:errmsg = substitute(v:exception, '^Vim:', '', "")
|
|
catch /^Vim\((\a\+)\)\=:/
|
|
" An error exception has been thrown after the original error.
|
|
let v:errmsg = ""
|
|
finally
|
|
call MSG(t)
|
|
let t = t + 1
|
|
XloopNEXT
|
|
continue " discard an aborting error
|
|
endtry
|
|
endwhile
|
|
catch /.*/
|
|
Xpath 512 " X: 0
|
|
Xout v:exception "in" ExtraVimThrowpoint()
|
|
endtry
|
|
|
|
try
|
|
let t = 10
|
|
XloopINIT 1024 2
|
|
while t <= 18
|
|
Xloop 1 " X: 1024 * 511
|
|
try
|
|
if t == 10
|
|
let v{INT(t) + CONT(t)} = 0
|
|
elseif t == 11
|
|
let v{INT(t) + CONT(t)}
|
|
elseif t == 12
|
|
let var = exists('v{INT(t) + CONT(t)}')
|
|
elseif t == 13
|
|
unlet v{INT(t) + CONT(t)}
|
|
elseif t == 14
|
|
function F{INT(t) + CONT(t)}()
|
|
endfunction
|
|
elseif t == 15
|
|
function F{INT(t) + CONT(t)}
|
|
elseif t == 16
|
|
let var = exists('*F{INT(t) + CONT(t)}')
|
|
elseif t == 17
|
|
delfunction F{INT(t) + CONT(t)}
|
|
elseif t == 18
|
|
let var = INT(t) + CONT(t)
|
|
endif
|
|
catch /^Vim\((\a\+)\)\=:\(Interrupt\)\@!/
|
|
" An error exception has been triggered after the interrupt.
|
|
let v:errmsg = substitute(v:exception,
|
|
\ '^Vim\((\a\+)\)\=:', '', "")
|
|
finally
|
|
call MSG(t)
|
|
let t = t + 1
|
|
XloopNEXT
|
|
continue " discard interrupt
|
|
endtry
|
|
endwhile
|
|
catch /.*/
|
|
Xpath 524288 " X: 0
|
|
Xout v:exception "in" ExtraVimThrowpoint()
|
|
endtry
|
|
|
|
try
|
|
let t = 19
|
|
XloopINIT 1048576 2
|
|
while t <= 27
|
|
Xloop 1 " X: 1048576 * 511
|
|
try
|
|
if t == 19
|
|
let v{THR(t) + CONT(t)} = 0
|
|
elseif t == 20
|
|
let v{THR(t) + CONT(t)}
|
|
elseif t == 21
|
|
let var = exists('v{THR(t) + CONT(t)}')
|
|
elseif t == 22
|
|
unlet v{THR(t) + CONT(t)}
|
|
elseif t == 23
|
|
function F{THR(t) + CONT(t)}()
|
|
endfunction
|
|
elseif t == 24
|
|
function F{THR(t) + CONT(t)}
|
|
elseif t == 25
|
|
let var = exists('*F{THR(t) + CONT(t)}')
|
|
elseif t == 26
|
|
delfunction F{THR(t) + CONT(t)}
|
|
elseif t == 27
|
|
let var = THR(t) + CONT(t)
|
|
endif
|
|
catch /^Vim\((\a\+)\)\=:/
|
|
" An error exception has been triggered after the :throw.
|
|
let v:errmsg = substitute(v:exception,
|
|
\ '^Vim\((\a\+)\)\=:', '', "")
|
|
finally
|
|
call MSG(t)
|
|
let t = t + 1
|
|
XloopNEXT
|
|
continue " discard exception
|
|
endtry
|
|
endwhile
|
|
catch /.*/
|
|
Xpath 536870912 " X: 0
|
|
Xout v:exception "in" ExtraVimThrowpoint()
|
|
endtry
|
|
|
|
let v{ERR(28) + CONT(28)} = 0
|
|
call MSG(28)
|
|
let v{ERR(29) + CONT(29)}
|
|
call MSG(29)
|
|
let var = exists('v{ERR(30) + CONT(30)}')
|
|
call MSG(30)
|
|
unlet v{ERR(31) + CONT(31)}
|
|
call MSG(31)
|
|
function F{ERR(32) + CONT(32)}()
|
|
endfunction
|
|
call MSG(32)
|
|
function F{ERR(33) + CONT(33)}
|
|
call MSG(33)
|
|
let var = exists('*F{ERR(34) + CONT(34)}')
|
|
call MSG(34)
|
|
delfunction F{ERR(35) + CONT(35)}
|
|
call MSG(35)
|
|
let var = ERR(36) + CONT(36)
|
|
call MSG(36)
|
|
|
|
let saved_errmsg = ""
|
|
|
|
let v{WRAP(37, ERRabort(37)) + CONT(37)} = 0
|
|
call MSG(37)
|
|
let v{WRAP(38, ERRabort(38)) + CONT(38)}
|
|
call MSG(38)
|
|
let var = exists('v{WRAP(39, ERRabort(39)) + CONT(39)}')
|
|
call MSG(39)
|
|
unlet v{WRAP(40, ERRabort(40)) + CONT(40)}
|
|
call MSG(40)
|
|
function F{WRAP(41, ERRabort(41)) + CONT(41)}()
|
|
endfunction
|
|
call MSG(41)
|
|
function F{WRAP(42, ERRabort(42)) + CONT(42)}
|
|
call MSG(42)
|
|
let var = exists('*F{WRAP(43, ERRabort(43)) + CONT(43)}')
|
|
call MSG(43)
|
|
delfunction F{WRAP(44, ERRabort(44)) + CONT(44)}
|
|
call MSG(44)
|
|
let var = ERRabort(45) + CONT(45)
|
|
call MSG(45)
|
|
|
|
Xpath 1073741824 " X: 1073741824
|
|
|
|
let expected = ""
|
|
\ . "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9"
|
|
\ . "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18"
|
|
\ . "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27"
|
|
\ . "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33"
|
|
\ . "E34C34M34E35C35M35E36C36M36"
|
|
\ . "A37W37C37M37A38W38C38M38A39W39C39M39A40W40C40M40A41W41C41M41"
|
|
\ . "A42W42C42M42A43W43C43M43A44W44C44M44A45C45M45"
|
|
|
|
if taken != expected
|
|
" The Xpath command does not accept 2^31 (negative); display explicitly:
|
|
exec "!echo 2147483648 >>" . g:ExtraVimResult
|
|
" X: 0
|
|
Xout "'taken' is" taken "instead of" expected
|
|
if substitute(taken,
|
|
\ '\(.*\)E3C3M3x\(.*\)E30C30M30x\(.*\)A39C39M39x\(.*\)',
|
|
\ '\1E3M3\2E30C30M30\3A39C39M39\4',
|
|
\ "") == expected
|
|
Xout "Is ++emsg_skip for var with expr_start non-NULL"
|
|
\ "in f_exists ok?"
|
|
endif
|
|
endif
|
|
|
|
unlet! v var saved_errmsg taken expected
|
|
call delete(WA_t5)
|
|
call delete(WA_t14)
|
|
call delete(WA_t23)
|
|
unlet! WA_t5 WA_t14 WA_t23
|
|
delfunction WA_t5
|
|
delfunction WA_t14
|
|
delfunction WA_t23
|
|
|
|
endif
|
|
|
|
Xcheck 1610087935
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 77: Errors, interrupts, :throw in name{brace-expression} {{{1
|
|
"
|
|
" When a function call made during evaluation of an expression in
|
|
" braces as part of a function name after ":function" is aborted due
|
|
" to an error inside a :try/:endtry region or due to an interrupt or
|
|
" a :throw, the expression evaluation is aborted as well, and the
|
|
" function definition is ignored, skipping all commands to the
|
|
" ":endfunction". On an error not inside :try/:endtry, the expression
|
|
" evaluation continues and the function gets defined, and can be
|
|
" called and deleted.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
XloopINIT 1 4
|
|
|
|
function! ERR() abort
|
|
Xloop 1 " X: 1 + 4 + 16 + 64
|
|
asdf
|
|
endfunction " returns -1
|
|
|
|
function! OK()
|
|
Xloop 2 " X: 2 * (1 + 4 + 16)
|
|
let v:errmsg = ""
|
|
return 0
|
|
endfunction
|
|
|
|
let v:errmsg = ""
|
|
|
|
Xpath 4096 " X: 4096
|
|
function! F{1 + ERR() + OK()}(arg)
|
|
" F0 should be defined.
|
|
if exists("a:arg") && a:arg == "calling"
|
|
Xpath 8192 " X: 8192
|
|
else
|
|
Xpath 16384 " X: 0
|
|
endif
|
|
endfunction
|
|
if v:errmsg != ""
|
|
Xpath 32768 " X: 0
|
|
endif
|
|
XloopNEXT
|
|
|
|
Xpath 65536 " X: 65536
|
|
call F{1 + ERR() + OK()}("calling")
|
|
if v:errmsg != ""
|
|
Xpath 131072 " X: 0
|
|
endif
|
|
XloopNEXT
|
|
|
|
Xpath 262144 " X: 262144
|
|
delfunction F{1 + ERR() + OK()}
|
|
if v:errmsg != ""
|
|
Xpath 524288 " X: 0
|
|
endif
|
|
XloopNEXT
|
|
|
|
try
|
|
while 1
|
|
let caught = 0
|
|
try
|
|
Xpath 1048576 " X: 1048576
|
|
function! G{1 + ERR() + OK()}(arg)
|
|
" G0 should not be defined, and the function body should be
|
|
" skipped.
|
|
if exists("a:arg") && a:arg == "calling"
|
|
Xpath 2097152 " X: 0
|
|
else
|
|
Xpath 4194304 " X: 0
|
|
endif
|
|
" Use an unmatched ":finally" to check whether the body is
|
|
" skipped when an error occurs in ERR(). This works whether or
|
|
" not the exception is converted to an exception.
|
|
finally
|
|
Xpath 8388608 " X: 0
|
|
Xout "Body of G{1 + ERR() + OK()}() not skipped"
|
|
" Discard the aborting error or exception, and break the
|
|
" while loop.
|
|
break
|
|
" End the try conditional and start a new one to avoid
|
|
" ":catch after :finally" errors.
|
|
endtry
|
|
try
|
|
Xpath 16777216 " X: 0
|
|
endfunction
|
|
|
|
" When the function was not defined, this won't be reached - whether
|
|
" the body was skipped or not. When the function was defined, it
|
|
" can be called and deleted here.
|
|
Xpath 33554432 " X: 0
|
|
Xout "G0() has been defined"
|
|
XloopNEXT
|
|
try
|
|
call G{1 + ERR() + OK()}("calling")
|
|
catch /.*/
|
|
Xpath 67108864 " X: 0
|
|
endtry
|
|
Xpath 134217728 " X: 0
|
|
XloopNEXT
|
|
try
|
|
delfunction G{1 + ERR() + OK()}
|
|
catch /.*/
|
|
Xpath 268435456 " X: 0
|
|
endtry
|
|
catch /asdf/
|
|
" Jumped to when the function is not defined and the body is
|
|
" skipped.
|
|
let caught = 1
|
|
catch /.*/
|
|
Xpath 536870912 " X: 0
|
|
finally
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 1073741824 " X: 0
|
|
endif
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry " jumped to when the body is not skipped
|
|
endwhile
|
|
catch /.*/
|
|
" The Xpath command does not accept 2^31 (negative); add explicitly:
|
|
let Xpath = Xpath + 2147483648 " X: 0
|
|
Xout "Body of G{1 + ERR() + OK()}() not skipped, exception caught"
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
Xcheck 1388671
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 78: Messages on parsing errors in expression evaluation {{{1
|
|
"
|
|
" When an expression evaluation detects a parsing error, an error
|
|
" message is given and converted to an exception, and the expression
|
|
" evaluation is aborted.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
let taken = ""
|
|
|
|
function! F(n)
|
|
let g:taken = g:taken . "F" . a:n
|
|
endfunction
|
|
|
|
function! MSG(n, enr, emsg)
|
|
let g:taken = g:taken . "M" . a:n
|
|
let english = v:lang == "C" || v:lang =~ '^[Ee]n'
|
|
if a:enr == ""
|
|
Xout "TODO: Add message number for:" a:emsg
|
|
let v:errmsg = ":" . v:errmsg
|
|
endif
|
|
if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
|
|
if v:errmsg == ""
|
|
Xout "Expr" a:n.": Message missing."
|
|
let g:taken = g:taken . "x"
|
|
else
|
|
let v:errmsg = escape(v:errmsg, '"')
|
|
Xout "Expr" a:n.": Unexpected message:" v:errmsg
|
|
Xout "Expected: " . a:enr . ': ' . a:emsg
|
|
let g:taken = g:taken . "X"
|
|
endif
|
|
endif
|
|
endfunction
|
|
|
|
function! CONT(n)
|
|
let g:taken = g:taken . "C" . a:n
|
|
endfunction
|
|
|
|
let v:errmsg = ""
|
|
XloopINIT 1 2
|
|
|
|
try
|
|
let t = 1
|
|
while t <= 14
|
|
let g:taken = g:taken . "T" . t
|
|
let v:errmsg = ""
|
|
try
|
|
let caught = 0
|
|
if t == 1
|
|
let v{novar + CONT(t)} = 0
|
|
elseif t == 2
|
|
let v{novar + CONT(t)}
|
|
elseif t == 3
|
|
let var = exists('v{novar + CONT(t)}')
|
|
elseif t == 4
|
|
unlet v{novar + CONT(t)}
|
|
elseif t == 5
|
|
function F{novar + CONT(t)}()
|
|
endfunction
|
|
elseif t == 6
|
|
function F{novar + CONT(t)}
|
|
elseif t == 7
|
|
let var = exists('*F{novar + CONT(t)}')
|
|
elseif t == 8
|
|
delfunction F{novar + CONT(t)}
|
|
elseif t == 9
|
|
echo novar + CONT(t)
|
|
elseif t == 10
|
|
echo v{novar + CONT(t)}
|
|
elseif t == 11
|
|
echo F{novar + CONT(t)}
|
|
elseif t == 12
|
|
let var = novar + CONT(t)
|
|
elseif t == 13
|
|
let var = v{novar + CONT(t)}
|
|
elseif t == 14
|
|
let var = F{novar + CONT(t)}()
|
|
endif
|
|
catch /^Vim\((\a\+)\)\=:/
|
|
" v:errmsg is not set when the error message is converted to an
|
|
" exception. Set it to the original error message.
|
|
let v:errmsg = substitute(v:exception,
|
|
\ '^Vim\((\a\+)\)\=:', '', "")
|
|
let caught = 1
|
|
finally
|
|
if t <= 8 && t != 3 && t != 7
|
|
call MSG(t, 'E475', 'Invalid argument\>')
|
|
else
|
|
if !caught " no error exceptions ($VIMNOERRTHROW set)
|
|
call MSG(t, 'E15', "Invalid expression")
|
|
else
|
|
call MSG(t, 'E121', "Undefined variable")
|
|
endif
|
|
endif
|
|
let t = t + 1
|
|
XloopNEXT
|
|
continue " discard an aborting error
|
|
endtry
|
|
endwhile
|
|
catch /.*/
|
|
Xloop 1 " X: 0
|
|
Xout t.":" v:exception "in" ExtraVimThrowpoint()
|
|
endtry
|
|
|
|
function! T(n, expr, enr, emsg)
|
|
try
|
|
let g:taken = g:taken . "T" . a:n
|
|
let v:errmsg = ""
|
|
try
|
|
let caught = 0
|
|
execute "let var = " . a:expr
|
|
catch /^Vim\((\a\+)\)\=:/
|
|
" v:errmsg is not set when the error message is converted to an
|
|
" exception. Set it to the original error message.
|
|
let v:errmsg = substitute(v:exception,
|
|
\ '^Vim\((\a\+)\)\=:', '', "")
|
|
let caught = 1
|
|
finally
|
|
if !caught " no error exceptions ($VIMNOERRTHROW set)
|
|
call MSG(a:n, 'E15', "Invalid expression")
|
|
else
|
|
call MSG(a:n, a:enr, a:emsg)
|
|
endif
|
|
XloopNEXT
|
|
" Discard an aborting error:
|
|
return
|
|
endtry
|
|
catch /.*/
|
|
Xloop 1 " X: 0
|
|
Xout a:n.":" v:exception "in" ExtraVimThrowpoint()
|
|
endtry
|
|
endfunction
|
|
|
|
call T(15, 'Nofunc() + CONT(15)', 'E117', "Unknown function")
|
|
call T(16, 'F(1 2 + CONT(16))', 'E116', "Invalid arguments")
|
|
call T(17, 'F(1, 2) + CONT(17)', 'E118', "Too many arguments")
|
|
call T(18, 'F() + CONT(18)', 'E119', "Not enough arguments")
|
|
call T(19, '{(1} + CONT(19)', 'E110', "Missing ')'")
|
|
call T(20, '("abc"[1) + CONT(20)', 'E111', "Missing ']'")
|
|
call T(21, '(1 +) + CONT(21)', 'E15', "Invalid expression")
|
|
call T(22, '1 2 + CONT(22)', 'E15', "Invalid expression")
|
|
call T(23, '(1 ? 2) + CONT(23)', 'E109', "Missing ':' after '?'")
|
|
call T(24, '("abc) + CONT(24)', 'E114', "Missing quote")
|
|
call T(25, "('abc) + CONT(25)", 'E115', "Missing quote")
|
|
call T(26, '& + CONT(26)', 'E112', "Option name missing")
|
|
call T(27, '&asdf + CONT(27)', 'E113', "Unknown option")
|
|
|
|
Xpath 134217728 " X: 134217728
|
|
|
|
let expected = ""
|
|
\ . "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14"
|
|
\ . "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25"
|
|
\ . "T26M26T27M27"
|
|
|
|
if taken != expected
|
|
Xpath 268435456 " X: 0
|
|
Xout "'taken' is" taken "instead of" expected
|
|
if substitute(taken, '\(.*\)T3M3x\(.*\)', '\1T3M3\2', "") == expected
|
|
Xout "Is ++emsg_skip for var with expr_start non-NULL"
|
|
\ "in f_exists ok?"
|
|
endif
|
|
endif
|
|
|
|
unlet! var caught taken expected
|
|
call delete(WA_t5)
|
|
unlet! WA_t5
|
|
delfunction WA_t5
|
|
|
|
endif
|
|
|
|
Xcheck 134217728
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 79: Throwing one of several errors for the same command {{{1
|
|
"
|
|
" When several errors appear in a row (for instance during expression
|
|
" evaluation), the first as the most specific one is used when
|
|
" throwing an error exception. If, however, a syntax error is
|
|
" detected afterwards, this one is used for the error exception.
|
|
" On a syntax error, the next command is not executed, on a normal
|
|
" error, however, it is (relevant only in a function without the
|
|
" "abort" flag). v:errmsg is not set.
|
|
"
|
|
" If throwing error exceptions is configured off, v:errmsg is always
|
|
" set to the latest error message, that is, to the more general
|
|
" message or the syntax error, respectively.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
XloopINIT 1 2
|
|
|
|
function! NEXT(cmd)
|
|
exec a:cmd . " | Xloop 1"
|
|
endfunction
|
|
|
|
call NEXT('echo novar') " X: 1 * 1 (checks nextcmd)
|
|
XloopNEXT
|
|
call NEXT('let novar #') " X: 0 * 2 (skips nextcmd)
|
|
XloopNEXT
|
|
call NEXT('unlet novar #') " X: 0 * 4 (skips nextcmd)
|
|
XloopNEXT
|
|
call NEXT('let {novar}') " X: 0 * 8 (skips nextcmd)
|
|
XloopNEXT
|
|
call NEXT('unlet{ novar}') " X: 0 * 16 (skips nextcmd)
|
|
|
|
function! EXEC(cmd)
|
|
exec a:cmd
|
|
endfunction
|
|
|
|
function! MATCH(expected, msg, enr, emsg)
|
|
let msg = a:msg
|
|
if a:enr == ""
|
|
Xout "TODO: Add message number for:" a:emsg
|
|
let msg = ":" . msg
|
|
endif
|
|
let english = v:lang == "C" || v:lang =~ '^[Ee]n'
|
|
if msg !~ '^'.a:enr.':' || (english && msg !~ a:emsg)
|
|
let match = 0
|
|
if a:expected " no match although expected
|
|
if a:msg == ""
|
|
Xout "Message missing."
|
|
else
|
|
let msg = escape(msg, '"')
|
|
Xout "Unexpected message:" msg
|
|
Xout "Expected:" a:enr . ": " . a:emsg
|
|
endif
|
|
endif
|
|
else
|
|
let match = 1
|
|
if !a:expected " match although not expected
|
|
let msg = escape(msg, '"')
|
|
Xout "Unexpected message:" msg
|
|
Xout "Expected none."
|
|
endif
|
|
endif
|
|
return match
|
|
endfunction
|
|
|
|
try
|
|
|
|
while 1 " dummy loop
|
|
try
|
|
let v:errmsg = ""
|
|
let caught = 0
|
|
let thrmsg = ""
|
|
call EXEC('echo novar') " normal error
|
|
catch /^Vim\((\a\+)\)\=:/
|
|
let caught = 1
|
|
let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
|
|
finally
|
|
Xpath 32 " X: 32
|
|
if !caught
|
|
if !$VIMNOERRTHROW
|
|
Xpath 64 " X: 0
|
|
endif
|
|
elseif !MATCH(1, thrmsg, 'E121', "Undefined variable")
|
|
\ || v:errmsg != ""
|
|
Xpath 128 " X: 0
|
|
endif
|
|
if !caught && !MATCH(1, v:errmsg, 'E15', "Invalid expression")
|
|
Xpath 256 " X: 0
|
|
endif
|
|
break " discard error if $VIMNOERRTHROW == 1
|
|
endtry
|
|
endwhile
|
|
|
|
Xpath 512 " X: 512
|
|
let cmd = "let"
|
|
XloopINIT 1024 32
|
|
while cmd != ""
|
|
try
|
|
let v:errmsg = ""
|
|
let caught = 0
|
|
let thrmsg = ""
|
|
call EXEC(cmd . ' novar #') " normal plus syntax error
|
|
catch /^Vim\((\a\+)\)\=:/
|
|
let caught = 1
|
|
let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
|
|
finally
|
|
Xloop 1 " X: 1024 * (1 + 32)
|
|
if !caught
|
|
if !$VIMNOERRTHROW
|
|
Xloop 2 " X: 0
|
|
endif
|
|
else
|
|
if cmd == "let"
|
|
let match = MATCH(0, thrmsg, 'E121', "Undefined variable")
|
|
elseif cmd == "unlet"
|
|
let match = MATCH(0, thrmsg, 'E108', "No such variable")
|
|
endif
|
|
if match " normal error
|
|
Xloop 4 " X: 0
|
|
endif
|
|
if !MATCH(1, thrmsg, 'E488', "Trailing characters")
|
|
\|| v:errmsg != ""
|
|
" syntax error
|
|
Xloop 8 " X: 0
|
|
endif
|
|
endif
|
|
if !caught && !MATCH(1, v:errmsg, 'E488', "Trailing characters")
|
|
" last error
|
|
Xloop 16 " X: 0
|
|
endif
|
|
if cmd == "let"
|
|
let cmd = "unlet"
|
|
else
|
|
let cmd = ""
|
|
endif
|
|
XloopNEXT
|
|
continue " discard error if $VIMNOERRTHROW == 1
|
|
endtry
|
|
endwhile
|
|
|
|
Xpath 1048576 " X: 1048576
|
|
let cmd = "let"
|
|
XloopINIT 2097152 32
|
|
while cmd != ""
|
|
try
|
|
let v:errmsg = ""
|
|
let caught = 0
|
|
let thrmsg = ""
|
|
call EXEC(cmd . ' {novar}') " normal plus syntax error
|
|
catch /^Vim\((\a\+)\)\=:/
|
|
let caught = 1
|
|
let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
|
|
finally
|
|
Xloop 1 " X: 2097152 * (1 + 32)
|
|
if !caught
|
|
if !$VIMNOERRTHROW
|
|
Xloop 2 " X: 0
|
|
endif
|
|
else
|
|
if MATCH(0, thrmsg, 'E121', "Undefined variable") " normal error
|
|
Xloop 4 " X: 0
|
|
endif
|
|
if !MATCH(1, thrmsg, 'E475', 'Invalid argument\>')
|
|
\ || v:errmsg != "" " syntax error
|
|
Xloop 8 " X: 0
|
|
endif
|
|
endif
|
|
if !caught && !MATCH(1, v:errmsg, 'E475', 'Invalid argument\>')
|
|
" last error
|
|
Xloop 16 " X: 0
|
|
endif
|
|
if cmd == "let"
|
|
let cmd = "unlet"
|
|
else
|
|
let cmd = ""
|
|
endif
|
|
XloopNEXT
|
|
continue " discard error if $VIMNOERRTHROW == 1
|
|
endtry
|
|
endwhile
|
|
|
|
catch /.*/
|
|
" The Xpath command does not accept 2^31 (negative); add explicitly:
|
|
let Xpath = Xpath + 2147483648 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
unlet! next_command thrmsg match
|
|
delfunction NEXT
|
|
delfunction EXEC
|
|
delfunction MATCH
|
|
|
|
Xcheck 70288929
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 80: Syntax error in expression for illegal :elseif {{{1
|
|
"
|
|
" If there is a syntax error in the expression after an illegal
|
|
" :elseif, an error message is given (or an error exception thrown)
|
|
" for the illegal :elseif rather than the expression error.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! MSG(enr, emsg)
|
|
let english = v:lang == "C" || v:lang =~ '^[Ee]n'
|
|
if a:enr == ""
|
|
Xout "TODO: Add message number for:" a:emsg
|
|
let v:errmsg = ":" . v:errmsg
|
|
endif
|
|
let match = 1
|
|
if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
|
|
let match = 0
|
|
if v:errmsg == ""
|
|
Xout "Message missing."
|
|
else
|
|
let v:errmsg = escape(v:errmsg, '"')
|
|
Xout "Unexpected message:" v:errmsg
|
|
endif
|
|
endif
|
|
return match
|
|
endfunction
|
|
|
|
let v:errmsg = ""
|
|
if 0
|
|
else
|
|
elseif 1 ||| 2
|
|
endif
|
|
Xpath 1 " X: 1
|
|
if !MSG('E584', ":elseif after :else")
|
|
Xpath 2 " X: 0
|
|
endif
|
|
|
|
let v:errmsg = ""
|
|
if 1
|
|
else
|
|
elseif 1 ||| 2
|
|
endif
|
|
Xpath 4 " X: 4
|
|
if !MSG('E584', ":elseif after :else")
|
|
Xpath 8 " X: 0
|
|
endif
|
|
|
|
let v:errmsg = ""
|
|
elseif 1 ||| 2
|
|
Xpath 16 " X: 16
|
|
if !MSG('E582', ":elseif without :if")
|
|
Xpath 32 " X: 0
|
|
endif
|
|
|
|
let v:errmsg = ""
|
|
while 1
|
|
elseif 1 ||| 2
|
|
endwhile
|
|
Xpath 64 " X: 64
|
|
if !MSG('E582', ":elseif without :if")
|
|
Xpath 128 " X: 0
|
|
endif
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let v:errmsg = ""
|
|
let caught = 0
|
|
if 0
|
|
else
|
|
elseif 1 ||| 2
|
|
endif
|
|
catch /^Vim\((\a\+)\)\=:/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
|
|
finally
|
|
Xpath 256 " X: 256
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 512 " X: 0
|
|
endif
|
|
if !MSG('E584', ":elseif after :else")
|
|
Xpath 1024 " X: 0
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 2048 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let v:errmsg = ""
|
|
let caught = 0
|
|
if 1
|
|
else
|
|
elseif 1 ||| 2
|
|
endif
|
|
catch /^Vim\((\a\+)\)\=:/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
|
|
finally
|
|
Xpath 4096 " X: 4096
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 8192 " X: 0
|
|
endif
|
|
if !MSG('E584', ":elseif after :else")
|
|
Xpath 16384 " X: 0
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 32768 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let v:errmsg = ""
|
|
let caught = 0
|
|
elseif 1 ||| 2
|
|
catch /^Vim\((\a\+)\)\=:/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
|
|
finally
|
|
Xpath 65536 " X: 65536
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 131072 " X: 0
|
|
endif
|
|
if !MSG('E582', ":elseif without :if")
|
|
Xpath 262144 " X: 0
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 524288 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let v:errmsg = ""
|
|
let caught = 0
|
|
while 1
|
|
elseif 1 ||| 2
|
|
endwhile
|
|
catch /^Vim\((\a\+)\)\=:/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
|
|
finally
|
|
Xpath 1048576 " X: 1048576
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 2097152 " X: 0
|
|
endif
|
|
if !MSG('E582', ":elseif without :if")
|
|
Xpath 4194304 " X: 0
|
|
endif
|
|
endtry
|
|
catch /.*/
|
|
Xpath 8388608 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
Xpath 16777216 " X: 16777216
|
|
|
|
unlet! caught
|
|
delfunction MSG
|
|
|
|
Xcheck 17895765
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 81: Discarding exceptions after an error or interrupt {{{1
|
|
"
|
|
" When an exception is thrown from inside a :try conditional without
|
|
" :catch and :finally clauses and an error or interrupt occurs before
|
|
" the :endtry is reached, the exception is discarded.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
try
|
|
Xpath 1 " X: 1
|
|
try
|
|
Xpath 2 " X: 2
|
|
throw "arrgh"
|
|
Xpath 4 " X: 0
|
|
" if 1
|
|
Xpath 8 " X: 0
|
|
" error after :throw: missing :endif
|
|
endtry
|
|
Xpath 16 " X: 0
|
|
catch /arrgh/
|
|
Xpath 32 " X: 0
|
|
endtry
|
|
Xpath 64 " X: 0
|
|
endif
|
|
|
|
if ExtraVim()
|
|
try
|
|
Xpath 128 " X: 128
|
|
try
|
|
Xpath 256 " X: 256
|
|
throw "arrgh"
|
|
Xpath 512 " X: 0
|
|
endtry " INTERRUPT
|
|
Xpath 1024 " X: 0
|
|
catch /arrgh/
|
|
Xpath 2048 " X: 0
|
|
endtry
|
|
Xpath 4096 " X: 0
|
|
endif
|
|
|
|
Xcheck 387
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 82: Ignoring :catch clauses after an error or interrupt {{{1
|
|
"
|
|
" When an exception is thrown and an error or interrupt occurs before
|
|
" the matching :catch clause is reached, the exception is discarded
|
|
" and the :catch clause is ignored (also for the error or interrupt
|
|
" exception being thrown then).
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
try
|
|
try
|
|
Xpath 1 " X: 1
|
|
throw "arrgh"
|
|
Xpath 2 " X: 0
|
|
" if 1
|
|
Xpath 4 " X: 0
|
|
" error after :throw: missing :endif
|
|
catch /.*/
|
|
Xpath 8 " X: 0
|
|
Xout v:exception "in" ExtraVimThrowpoint()
|
|
catch /.*/
|
|
Xpath 16 " X: 0
|
|
Xout v:exception "in" ExtraVimThrowpoint()
|
|
endtry
|
|
Xpath 32 " X: 0
|
|
catch /arrgh/
|
|
Xpath 64 " X: 0
|
|
endtry
|
|
Xpath 128 " X: 0
|
|
endif
|
|
|
|
if ExtraVim()
|
|
function! E()
|
|
try
|
|
try
|
|
Xpath 256 " X: 256
|
|
throw "arrgh"
|
|
Xpath 512 " X: 0
|
|
" if 1
|
|
Xpath 1024 " X: 0
|
|
" error after :throw: missing :endif
|
|
catch /.*/
|
|
Xpath 2048 " X: 0
|
|
Xout v:exception "in" ExtraVimThrowpoint()
|
|
catch /.*/
|
|
Xpath 4096 " X: 0
|
|
Xout v:exception "in" ExtraVimThrowpoint()
|
|
endtry
|
|
Xpath 8192 " X: 0
|
|
catch /arrgh/
|
|
Xpath 16384 " X: 0
|
|
endtry
|
|
endfunction
|
|
|
|
call E()
|
|
Xpath 32768 " X: 0
|
|
endif
|
|
|
|
if ExtraVim()
|
|
try
|
|
try
|
|
Xpath 65536 " X: 65536
|
|
throw "arrgh"
|
|
Xpath 131072 " X: 0
|
|
catch /.*/ "INTERRUPT
|
|
Xpath 262144 " X: 0
|
|
Xout v:exception "in" ExtraVimThrowpoint()
|
|
catch /.*/
|
|
Xpath 524288 " X: 0
|
|
Xout v:exception "in" ExtraVimThrowpoint()
|
|
endtry
|
|
Xpath 1048576 " X: 0
|
|
catch /arrgh/
|
|
Xpath 2097152 " X: 0
|
|
endtry
|
|
Xpath 4194304 " X: 0
|
|
endif
|
|
|
|
if ExtraVim()
|
|
function I()
|
|
try
|
|
try
|
|
Xpath 8388608 " X: 8388608
|
|
throw "arrgh"
|
|
Xpath 16777216 " X: 0
|
|
catch /.*/ "INTERRUPT
|
|
Xpath 33554432 " X: 0
|
|
Xout v:exception "in" ExtraVimThrowpoint()
|
|
catch /.*/
|
|
Xpath 67108864 " X: 0
|
|
Xout v:exception "in" ExtraVimThrowpoint()
|
|
endtry
|
|
Xpath 134217728 " X: 0
|
|
catch /arrgh/
|
|
Xpath 268435456 " X: 0
|
|
endtry
|
|
endfunction
|
|
|
|
call I()
|
|
Xpath 536870912 " X: 0
|
|
endif
|
|
|
|
Xcheck 8454401
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 83: Executing :finally clauses after an error or interrupt {{{1
|
|
"
|
|
" When an exception is thrown and an error or interrupt occurs before
|
|
" the :finally of the innermost :try is reached, the exception is
|
|
" discarded and the :finally clause is executed.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
try
|
|
Xpath 1 " X: 1
|
|
try
|
|
Xpath 2 " X: 2
|
|
throw "arrgh"
|
|
Xpath 4 " X: 0
|
|
" if 1
|
|
Xpath 8 " X: 0
|
|
" error after :throw: missing :endif
|
|
finally
|
|
Xpath 16 " X: 16
|
|
endtry
|
|
Xpath 32 " X: 0
|
|
catch /arrgh/
|
|
Xpath 64 " X: 0
|
|
endtry
|
|
Xpath 128 " X: 0
|
|
endif
|
|
|
|
if ExtraVim()
|
|
try
|
|
Xpath 256 " X: 256
|
|
try
|
|
Xpath 512 " X: 512
|
|
throw "arrgh"
|
|
Xpath 1024 " X: 0
|
|
finally "INTERRUPT
|
|
Xpath 2048 " X: 2048
|
|
endtry
|
|
Xpath 4096 " X: 0
|
|
catch /arrgh/
|
|
Xpath 8192 " X: 0
|
|
endtry
|
|
Xpath 16384 " X: 0
|
|
endif
|
|
|
|
Xcheck 2835
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 84: Exceptions in autocommand sequences. {{{1
|
|
"
|
|
" When an exception occurs in a sequence of autocommands for
|
|
" a specific event, the rest of the sequence is not executed. The
|
|
" command that triggered the autocommand execution aborts, and the
|
|
" exception is propagated to the caller.
|
|
"
|
|
" For the FuncUndefined event under a function call expression or
|
|
" :call command, the function is not executed, even when it has
|
|
" been defined by the autocommands before the exception occurred.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
function! INT()
|
|
"INTERRUPT
|
|
let dummy = 0
|
|
endfunction
|
|
|
|
aug TMP
|
|
autocmd!
|
|
|
|
autocmd User x1 Xpath 1 " X: 1
|
|
autocmd User x1 throw "x1"
|
|
autocmd User x1 Xpath 2 " X: 0
|
|
|
|
autocmd User x2 Xpath 4 " X: 4
|
|
autocmd User x2 asdf
|
|
autocmd User x2 Xpath 8 " X: 0
|
|
|
|
autocmd User x3 Xpath 16 " X: 16
|
|
autocmd User x3 call INT()
|
|
autocmd User x3 Xpath 32 " X: 0
|
|
|
|
autocmd FuncUndefined U1 function! U1()
|
|
autocmd FuncUndefined U1 Xpath 64 " X: 0
|
|
autocmd FuncUndefined U1 endfunction
|
|
autocmd FuncUndefined U1 Xpath 128 " X: 128
|
|
autocmd FuncUndefined U1 throw "U1"
|
|
autocmd FuncUndefined U1 Xpath 256 " X: 0
|
|
|
|
autocmd FuncUndefined U2 function! U2()
|
|
autocmd FuncUndefined U2 Xpath 512 " X: 0
|
|
autocmd FuncUndefined U2 endfunction
|
|
autocmd FuncUndefined U2 Xpath 1024 " X: 1024
|
|
autocmd FuncUndefined U2 ASDF
|
|
autocmd FuncUndefined U2 Xpath 2048 " X: 0
|
|
|
|
autocmd FuncUndefined U3 function! U3()
|
|
autocmd FuncUndefined U3 Xpath 4096 " X: 0
|
|
autocmd FuncUndefined U3 endfunction
|
|
autocmd FuncUndefined U3 Xpath 8192 " X: 8192
|
|
autocmd FuncUndefined U3 call INT()
|
|
autocmd FuncUndefined U3 Xpath 16384 " X: 0
|
|
aug END
|
|
|
|
try
|
|
try
|
|
Xpath 32768 " X: 32768
|
|
doautocmd User x1
|
|
catch /x1/
|
|
Xpath 65536 " X: 65536
|
|
endtry
|
|
|
|
while 1
|
|
try
|
|
Xpath 131072 " X: 131072
|
|
let caught = 0
|
|
doautocmd User x2
|
|
catch /asdf/
|
|
let caught = 1
|
|
finally
|
|
Xpath 262144 " X: 262144
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 524288 " X: 0
|
|
" Propagate uncaught error exception,
|
|
else
|
|
" ... but break loop for caught error exception,
|
|
" or discard error and break loop if $VIMNOERRTHROW
|
|
break
|
|
endif
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
Xpath 1048576 " X: 1048576
|
|
let caught = 0
|
|
doautocmd User x3
|
|
catch /Vim:Interrupt/
|
|
let caught = 1
|
|
finally
|
|
Xpath 2097152 " X: 2097152
|
|
if !caught && !$VIMNOINTTHROW
|
|
Xpath 4194304 " X: 0
|
|
" Propagate uncaught interrupt exception,
|
|
else
|
|
" ... but break loop for caught interrupt exception,
|
|
" or discard interrupt and break loop if $VIMNOINTTHROW
|
|
break
|
|
endif
|
|
endtry
|
|
endwhile
|
|
|
|
if exists("*U1") | delfunction U1 | endif
|
|
if exists("*U2") | delfunction U2 | endif
|
|
if exists("*U3") | delfunction U3 | endif
|
|
|
|
try
|
|
Xpath 8388608 " X: 8388608
|
|
call U1()
|
|
catch /U1/
|
|
Xpath 16777216 " X: 16777216
|
|
endtry
|
|
|
|
while 1
|
|
try
|
|
Xpath 33554432 " X: 33554432
|
|
let caught = 0
|
|
call U2()
|
|
catch /ASDF/
|
|
let caught = 1
|
|
finally
|
|
Xpath 67108864 " X: 67108864
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 134217728 " X: 0
|
|
" Propagate uncaught error exception,
|
|
else
|
|
" ... but break loop for caught error exception,
|
|
" or discard error and break loop if $VIMNOERRTHROW
|
|
break
|
|
endif
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
Xpath 268435456 " X: 268435456
|
|
let caught = 0
|
|
call U3()
|
|
catch /Vim:Interrupt/
|
|
let caught = 1
|
|
finally
|
|
Xpath 536870912 " X: 536870912
|
|
if !caught && !$VIMNOINTTHROW
|
|
Xpath 1073741824 " X: 0
|
|
" Propagate uncaught interrupt exception,
|
|
else
|
|
" ... but break loop for caught interrupt exception,
|
|
" or discard interrupt and break loop if $VIMNOINTTHROW
|
|
break
|
|
endif
|
|
endtry
|
|
endwhile
|
|
catch /.*/
|
|
" The Xpath command does not accept 2^31 (negative); display explicitly:
|
|
exec "!echo 2147483648 >>" . g:ExtraVimResult
|
|
Xout "Caught" v:exception "in" v:throwpoint
|
|
endtry
|
|
|
|
unlet caught
|
|
delfunction INT
|
|
delfunction U1
|
|
delfunction U2
|
|
delfunction U3
|
|
au! TMP
|
|
aug! TMP
|
|
endif
|
|
|
|
Xcheck 934782101
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 85: Error exceptions in autocommands for I/O command events {{{1
|
|
"
|
|
" When an I/O command is inside :try/:endtry, autocommands to be
|
|
" executed after it should be skipped on an error (exception) in the
|
|
" command itself or in autocommands to be executed before the command.
|
|
" In the latter case, the I/O command should not be executed either.
|
|
" Example 1: BufWritePre, :write, BufWritePost
|
|
" Example 2: FileReadPre, :read, FileReadPost.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
function! MSG(enr, emsg)
|
|
let english = v:lang == "C" || v:lang =~ '^[Ee]n'
|
|
if a:enr == ""
|
|
Xout "TODO: Add message number for:" a:emsg
|
|
let v:errmsg = ":" . v:errmsg
|
|
endif
|
|
let match = 1
|
|
if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
|
|
let match = 0
|
|
if v:errmsg == ""
|
|
Xout "Message missing."
|
|
else
|
|
let v:errmsg = escape(v:errmsg, '"')
|
|
Xout "Unexpected message:" v:errmsg
|
|
endif
|
|
endif
|
|
return match
|
|
endfunction
|
|
|
|
" Remove the autocommands for the events specified as arguments in all used
|
|
" autogroups.
|
|
function! Delete_autocommands(...)
|
|
let augfile = tempname()
|
|
while 1
|
|
try
|
|
exec "redir >" . augfile
|
|
aug
|
|
redir END
|
|
exec "edit" augfile
|
|
g/^$/d
|
|
norm G$
|
|
let wrap = "w"
|
|
while search('\%( \|^\)\@<=.\{-}\%( \)\@=', wrap) > 0
|
|
let wrap = "W"
|
|
exec "norm y/ \n"
|
|
let argno = 1
|
|
while argno <= a:0
|
|
exec "au!" escape(@", " ") a:{argno}
|
|
let argno = argno + 1
|
|
endwhile
|
|
endwhile
|
|
catch /.*/
|
|
finally
|
|
bwipeout!
|
|
call delete(augfile)
|
|
break " discard errors for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
endfunction
|
|
|
|
call Delete_autocommands("BufWritePre", "BufWritePost")
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let post = 0
|
|
aug TMP
|
|
au! BufWritePost * let post = 1
|
|
aug END
|
|
let caught = 0
|
|
write /n/o/n/e/x/i/s/t/e/n/t
|
|
catch /^Vim(write):/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim(write):', '', "")
|
|
finally
|
|
Xpath 1 " X: 1
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 2 " X: 0
|
|
endif
|
|
let v:errmsg = substitute(v:errmsg, '^"/n/o/n/e/x/i/s/t/e/n/t" ',
|
|
\ '', "")
|
|
if !MSG('E212', "Can't open file for writing")
|
|
Xpath 4 " X: 0
|
|
endif
|
|
if post
|
|
Xpath 8 " X: 0
|
|
Xout "BufWritePost commands executed after write error"
|
|
endif
|
|
au! TMP
|
|
aug! TMP
|
|
endtry
|
|
catch /.*/
|
|
Xpath 16 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let post = 0
|
|
aug TMP
|
|
au! BufWritePre * asdf
|
|
au! BufWritePost * let post = 1
|
|
aug END
|
|
let tmpfile = tempname()
|
|
let caught = 0
|
|
exec "write" tmpfile
|
|
catch /^Vim\((write)\)\=:/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim\((write)\)\=:', '', "")
|
|
finally
|
|
Xpath 32 " X: 32
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 64 " X: 0
|
|
endif
|
|
let v:errmsg = substitute(v:errmsg, '^"'.tmpfile.'" ', '', "")
|
|
if !MSG('E492', "Not an editor command")
|
|
Xpath 128 " X: 0
|
|
endif
|
|
if filereadable(tmpfile)
|
|
Xpath 256 " X: 0
|
|
Xout ":write command not suppressed after BufWritePre error"
|
|
endif
|
|
if post
|
|
Xpath 512 " X: 0
|
|
Xout "BufWritePost commands executed after BufWritePre error"
|
|
endif
|
|
au! TMP
|
|
aug! TMP
|
|
endtry
|
|
catch /.*/
|
|
Xpath 1024 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
call delete(tmpfile)
|
|
|
|
call Delete_autocommands("BufWritePre", "BufWritePost",
|
|
\ "BufReadPre", "BufReadPost", "FileReadPre", "FileReadPost")
|
|
|
|
while 1
|
|
try
|
|
try
|
|
let post = 0
|
|
aug TMP
|
|
au! FileReadPost * let post = 1
|
|
aug END
|
|
let caught = 0
|
|
read /n/o/n/e/x/i/s/t/e/n/t
|
|
catch /^Vim(read):/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim(read):', '', "")
|
|
finally
|
|
Xpath 2048 " X: 2048
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 4096 " X: 0
|
|
endif
|
|
let v:errmsg = substitute(v:errmsg, ' /n/o/n/e/x/i/s/t/e/n/t$',
|
|
\ '', "")
|
|
if !MSG('E484', "Can't open file")
|
|
Xpath 8192 " X: 0
|
|
endif
|
|
if post
|
|
Xpath 16384 " X: 0
|
|
Xout "FileReadPost commands executed after write error"
|
|
endif
|
|
au! TMP
|
|
aug! TMP
|
|
endtry
|
|
catch /.*/
|
|
Xpath 32768 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
while 1
|
|
try
|
|
let infile = tempname()
|
|
let tmpfile = tempname()
|
|
exec "!echo XYZ >" . infile
|
|
exec "edit" tmpfile
|
|
try
|
|
Xpath 65536 " X: 65536
|
|
try
|
|
let post = 0
|
|
aug TMP
|
|
au! FileReadPre * asdf
|
|
au! FileReadPost * let post = 1
|
|
aug END
|
|
let caught = 0
|
|
exec "0read" infile
|
|
catch /^Vim\((read)\)\=:/
|
|
let caught = 1
|
|
let v:errmsg = substitute(v:exception, '^Vim\((read)\)\=:', '',
|
|
\ "")
|
|
finally
|
|
Xpath 131072 " X: 131072
|
|
if !caught && !$VIMNOERRTHROW
|
|
Xpath 262144 " X: 0
|
|
endif
|
|
let v:errmsg = substitute(v:errmsg, ' '.infile.'$', '', "")
|
|
if !MSG('E492', "Not an editor command")
|
|
Xpath 524288 " X: 0
|
|
endif
|
|
if getline("1") == "XYZ"
|
|
Xpath 1048576 " X: 0
|
|
Xout ":read command not suppressed after FileReadPre error"
|
|
endif
|
|
if post
|
|
Xpath 2097152 " X: 0
|
|
Xout "FileReadPost commands executed after " .
|
|
\ "FileReadPre error"
|
|
endif
|
|
au! TMP
|
|
aug! TMP
|
|
endtry
|
|
finally
|
|
bwipeout!
|
|
endtry
|
|
catch /.*/
|
|
Xpath 4194304 " X: 0
|
|
Xout v:exception "in" v:throwpoint
|
|
finally
|
|
break " discard error for $VIMNOERRTHROW
|
|
endtry
|
|
endwhile
|
|
|
|
call delete(infile)
|
|
call delete(tmpfile)
|
|
unlet! caught post infile tmpfile
|
|
delfunction MSG
|
|
delfunction Delete_autocommands
|
|
|
|
Xcheck 198689
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 86: setloclist crash {{{1
|
|
"
|
|
" Executing a setloclist() on BufUnload shouldn't crash Vim
|
|
"-------------------------------------------------------------------------------
|
|
|
|
func F
|
|
au BufUnload * :call setloclist(0, [{'bufnr':1, 'lnum':1, 'col':1, 'text': 'tango down'}])
|
|
|
|
:lvimgrep /.*/ *.mak
|
|
endfunc
|
|
|
|
XpathINIT
|
|
|
|
ExecAsScript F
|
|
|
|
delfunction F
|
|
Xout "No Crash for vimgrep on BufUnload"
|
|
Xcheck 0
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 87 using (expr) ? funcref : funcref {{{1
|
|
"
|
|
" Vim needs to correctly parse the funcref and even when it does
|
|
" not execute the funcref, it needs to consume the trailing ()
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
func Add2(x1, x2)
|
|
return a:x1 + a:x2
|
|
endfu
|
|
|
|
func GetStr()
|
|
return "abcdefghijklmnopqrstuvwxyp"
|
|
endfu
|
|
|
|
echo function('Add2')(2,3)
|
|
|
|
Xout 1 ? function('Add2')(1,2) : function('Add2')(2,3)
|
|
Xout 0 ? function('Add2')(1,2) : function('Add2')(2,3)
|
|
" Make sure, GetStr() still works.
|
|
Xout GetStr()[0:10]
|
|
|
|
|
|
delfunction GetStr
|
|
delfunction Add2
|
|
Xout "Successfully executed funcref Add2"
|
|
|
|
Xcheck 0
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Test 88: $VIMNOERRTHROW and $VIMNOINTTHROW support {{{1
|
|
"
|
|
" It is possible to configure Vim for throwing exceptions on error
|
|
" or interrupt, controlled by variables $VIMNOERRTHROW and
|
|
" $VIMNOINTTHROW. This is just for increasing the number of tests.
|
|
" All tests here should run for all four combinations of setting
|
|
" these variables to 0 or 1. The variables are intended for the
|
|
" development phase only. In the final release, Vim should be
|
|
" configured to always use error and interrupt exceptions.
|
|
"
|
|
" The test result is "OK",
|
|
"
|
|
" - if the $VIMNOERRTHROW and the $VIMNOINTTHROW control are not
|
|
" configured and exceptions are thrown on error and on
|
|
" interrupt.
|
|
"
|
|
" - if the $VIMNOERRTHROW or the $VIMNOINTTHROW control is
|
|
" configured and works as intended.
|
|
"
|
|
" What actually happens, is shown in the test output.
|
|
"
|
|
" Otherwise, the test result is "FAIL", and the test output describes
|
|
" the problem.
|
|
"
|
|
" IMPORTANT: This must be the last test because it sets $VIMNOERRTHROW and
|
|
" $VIMNOINTTHROW.
|
|
"-------------------------------------------------------------------------------
|
|
|
|
XpathINIT
|
|
|
|
if ExtraVim()
|
|
|
|
function! ThrowOnError()
|
|
XloopNEXT
|
|
let caught = 0
|
|
try
|
|
Xloop 1 " X: 1 + 8 + 64
|
|
asdf
|
|
catch /.*/
|
|
let caught = 1 " error exception caught
|
|
finally
|
|
Xloop 2 " X: 2 + 16 + 128
|
|
return caught " discard aborting error
|
|
endtry
|
|
Xloop 4 " X: 0
|
|
endfunction
|
|
|
|
let quits_skipped = 0
|
|
|
|
function! ThrowOnInterrupt()
|
|
XloopNEXT
|
|
let caught = 0
|
|
try
|
|
Xloop 1 " X: (1 + 8 + 64) * 512
|
|
"INTERRUPT3
|
|
let dummy = 0
|
|
let g:quits_skipped = g:quits_skipped + 1
|
|
catch /.*/
|
|
let caught = 1 " interrupt exception caught
|
|
finally
|
|
Xloop 2 " X: (2 + 16 + 128) * 512
|
|
return caught " discard interrupt
|
|
endtry
|
|
Xloop 4 " X: 0
|
|
endfunction
|
|
|
|
function! CheckThrow(Type)
|
|
execute 'return ThrowOn' . a:Type . '()'
|
|
endfunction
|
|
|
|
function! CheckConfiguration(type) " type is "error" or "interrupt"
|
|
|
|
let type = a:type
|
|
let Type = substitute(type, '.*', '\u&', "")
|
|
let VAR = '$VIMNO' . substitute(type, '\(...\).*', '\U\1', "") . 'THROW'
|
|
|
|
if type == "error"
|
|
XloopINIT! 1 8
|
|
elseif type == "interrupt"
|
|
XloopINIT! 512 8
|
|
endif
|
|
|
|
exec 'let requested_for_tests = exists(VAR) && ' . VAR . ' == 0'
|
|
exec 'let suppressed_for_tests = ' . VAR . ' != 0'
|
|
let used_in_tests = CheckThrow(Type)
|
|
|
|
exec 'let ' . VAR . ' = 0'
|
|
let request_works = CheckThrow(Type)
|
|
|
|
exec 'let ' . VAR . ' = 1'
|
|
let suppress_works = !CheckThrow(Type)
|
|
|
|
if type == "error"
|
|
XloopINIT! 262144 8
|
|
elseif type == "interrupt"
|
|
XloopINIT! 2097152 8
|
|
|
|
if g:quits_skipped != 0
|
|
Xloop 1 " X: 0*2097152
|
|
Xout "Test environment error. Interrupt breakpoints skipped: "
|
|
\ . g:quits_skipped . ".\n"
|
|
\ . "Cannot check whether interrupt exceptions are thrown."
|
|
return
|
|
endif
|
|
endif
|
|
|
|
let failure =
|
|
\ !suppressed_for_tests && !used_in_tests
|
|
\ || !request_works
|
|
|
|
let contradiction =
|
|
\ used_in_tests
|
|
\ ? suppressed_for_tests && !request_works
|
|
\ : !suppressed_for_tests
|
|
|
|
if failure
|
|
" Failure in configuration.
|
|
Xloop 2 " X: 0 * 2* (262144 + 2097152)
|
|
elseif contradiction
|
|
" Failure in test logic. Should not happen.
|
|
Xloop 4 " X: 0 * 4 * (262144 + 2097152)
|
|
endif
|
|
|
|
let var_control_configured =
|
|
\ request_works != used_in_tests
|
|
\ || suppress_works == used_in_tests
|
|
|
|
let var_control_not_configured =
|
|
\ requested_for_tests || suppressed_for_tests
|
|
\ ? request_works && !suppress_works
|
|
\ : request_works == used_in_tests
|
|
\ && suppress_works != used_in_tests
|
|
|
|
let with = used_in_tests ? "with" : "without"
|
|
|
|
let set = suppressed_for_tests ? "non-zero" :
|
|
\ requested_for_tests ? "0" : "unset"
|
|
|
|
let although = contradiction && !var_control_not_configured
|
|
\ ? ",\nalthough "
|
|
\ : ".\n"
|
|
|
|
let output = "All tests were run " . with . " throwing exceptions on "
|
|
\ . type . although
|
|
|
|
if !var_control_not_configured
|
|
let output = output . VAR . " was " . set . "."
|
|
|
|
if !request_works && !requested_for_tests
|
|
let output = output .
|
|
\ "\n" . Type . " exceptions are not thrown when " . VAR .
|
|
\ " is\nset to 0."
|
|
endif
|
|
|
|
if !suppress_works && (!used_in_tests ||
|
|
\ !request_works &&
|
|
\ !requested_for_tests && !suppressed_for_tests)
|
|
let output = output .
|
|
\ "\n" . Type . " exceptions are thrown when " . VAR .
|
|
\ " is set to 1."
|
|
endif
|
|
|
|
if !failure && var_control_configured
|
|
let output = output .
|
|
\ "\nRun tests also with " . substitute(VAR, '^\$', '', "")
|
|
\ . "=" . used_in_tests . "."
|
|
\ . "\nThis is for testing in the development phase only."
|
|
\ . " Remove the \n"
|
|
\ . VAR . " control in the final release."
|
|
endif
|
|
else
|
|
let output = output .
|
|
\ "The " . VAR . " control is not configured."
|
|
endif
|
|
|
|
Xout output
|
|
endfunction
|
|
|
|
call CheckConfiguration("error")
|
|
Xpath 16777216 " X: 16777216
|
|
call CheckConfiguration("interrupt")
|
|
Xpath 33554432 " X: 33554432
|
|
endif
|
|
|
|
Xcheck 50443995
|
|
|
|
" IMPORTANT: No test should be added after this test because it changes
|
|
" $VIMNOERRTHROW and $VIMNOINTTHROW.
|
|
|
|
|
|
"-------------------------------------------------------------------------------
|
|
" Modelines {{{1
|
|
" vim: ts=8 sw=4 tw=80 fdm=marker
|
|
"-------------------------------------------------------------------------------
|