aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/ex_docmd.c1
-rw-r--r--src/nvim/testdir/shared.vim15
-rw-r--r--src/nvim/testdir/test49.ok44
-rw-r--r--src/nvim/testdir/test49.vim5284
-rw-r--r--src/nvim/testdir/test_vimscript.vim4997
-rw-r--r--test/functional/legacy/vimscript_spec.lua90
-rw-r--r--test/functional/vimscript/eval_spec.lua74
7 files changed, 5018 insertions, 5487 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index ed74993b84..dc2b7247f1 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -807,6 +807,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
next = messages->next;
emsg(messages->msg);
xfree(messages->msg);
+ xfree(messages->sfile);
xfree(messages);
messages = next;
} while (messages != NULL);
diff --git a/src/nvim/testdir/shared.vim b/src/nvim/testdir/shared.vim
index c2809844ac..ef7cc4ac5f 100644
--- a/src/nvim/testdir/shared.vim
+++ b/src/nvim/testdir/shared.vim
@@ -364,4 +364,19 @@ func GetMessages()
return msg_list
endfunc
+" Run the list of commands in 'cmds' and look for 'errstr' in exception.
+" Note that assert_fails() cannot be used in some places and this function
+" can be used.
+func AssertException(cmds, errstr)
+ let save_exception = ''
+ try
+ for cmd in a:cmds
+ exe cmd
+ endfor
+ catch
+ let save_exception = v:exception
+ endtry
+ call assert_match(a:errstr, save_exception)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/test49.ok b/src/nvim/testdir/test49.ok
index 9f283e808b..d687f5bc77 100644
--- a/src/nvim/testdir/test49.ok
+++ b/src/nvim/testdir/test49.ok
@@ -1,48 +1,4 @@
Results of test49.vim:
-*** Test 18: OK (67224583)
-*** Test 19: OK (69275973)
-*** Test 20: OK (1874575085)
-*** Test 21: OK (147932225)
-*** Test 22: OK (4161)
-*** Test 23: OK (49)
-*** Test 24: OK (41)
-*** Test 27: OK (1996459)
-*** Test 28: OK (1996459)
-*** Test 29: OK (170428555)
-*** Test 30: OK (190905173)
-*** Test 31: OK (190905173)
-*** Test 34: OK (2146584868)
-*** Test 35: OK (2146584868)
-*** Test 36: OK (1071644672)
-*** Test 37: OK (1071644672)
-*** Test 38: OK (357908480)
-*** Test 39: OK (357908480)
-*** Test 40: OK (357908480)
-*** Test 49: OK (179000669)
-*** Test 50: OK (363550045)
-*** Test 52: OK (1247112011)
-*** Test 53: OK (131071)
-*** Test 54: OK (2047)
-*** Test 55: OK (1023)
-*** Test 56: OK (511)
-*** Test 57: OK (2147450880)
-*** Test 58: OK (624945)
-*** Test 59: OK (2038431743)
-*** Test 60: OK (311511339)
-*** Test 61: OK (374889517)
-*** Test 62: OK (286331153)
-*** Test 63: OK (236978127)
-*** Test 64: OK (1499645335)
-*** Test 65: OK (70187)
-*** Test 66: OK (5464)
-*** Test 67: OK (212514423)
-*** Test 68: OK (212514423)
-*** Test 76: OK (1610087935)
-*** Test 77: OK (1388671)
-*** Test 78: OK (134217728)
-*** Test 79: OK (70288929)
-*** Test 80: OK (17895765)
-*** Test 81: OK (387)
*** Test 82: OK (8454401)
*** Test 83: OK (2835)
*** Test 84: OK (934782101)
diff --git a/src/nvim/testdir/test49.vim b/src/nvim/testdir/test49.vim
index 3ee5e9ff7c..d5f8cd3b60 100644
--- a/src/nvim/testdir/test49.vim
+++ b/src/nvim/testdir/test49.vim
@@ -1,6 +1,6 @@
" Vim script language tests
" Author: Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com>
-" Last Change: 2019 Nov 03
+" Last Change: 2020 Jun 07
"-------------------------------------------------------------------------------
" Test environment {{{1
@@ -456,7 +456,7 @@ function ExtraVim(...)
" 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' | " .. v:progpath .. " -u NONE -N -es" . redirect .
+ exec "!echo '" . debug_quits . "q' | " .. v:progpath .. " -u NONE -N -Xes" . redirect .
\ " -c 'debuggreedy|set viminfo+=nviminfo'" .
\ " -c 'let ExtraVimBegin = " . extra_begin . "'" .
\ " -c 'let ExtraVimResult = \"" . resultfile . "\"'" . breakpoints .
@@ -607,1660 +607,6 @@ com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
" END_OF_TEST_ENVIRONMENT - do not change or remove this line.
-
-" Tests 1 to 17 were moved to test_vimscript.vim
-let Xtest = 18
-
-"-------------------------------------------------------------------------------
-" 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
-
-" Tests 25 and 26 were moved to test_trycatch.vim
-let Xtest = 27
-
-
-"-------------------------------------------------------------------------------
-" 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
-
-" Tests 32 and 33 were moved to test_trycatch.vim
-let Xtest = 34
-
-
-"-------------------------------------------------------------------------------
-" 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
-
-" Tests 41 to 48 were moved to test_trycatch.vim
-let Xtest = 49
-
-
-"-------------------------------------------------------------------------------
-" 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 was moved to test_trycatch.vim
-let Xtest = 52
-
-
-"-------------------------------------------------------------------------------
-" 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
@@ -2302,3627 +648,11 @@ function! MESSAGES(...)
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
- Xpath 4194304 " X: 4194304
- let x = novar " error E121; 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")
- Xpath 67108864 " X: 0
-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
-
-" Tests 69 to 75 were moved to test_trycatch.vim
-let Xtest = 76
-
-
-"-------------------------------------------------------------------------------
-" 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
-
+" Following tests were moved to test_vimscript.vim:
+" 1-24, 27-31, 34-40, 49-50, 52-68, 76-81, 87
+" Following tests were moved to test_trycatch.vim:
+" 25-26, 32-33, 41-48, 51, 69-75
+let Xtest = 82
"-------------------------------------------------------------------------------
" Test 82: Ignoring :catch clauses after an error or interrupt {{{1
diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim
index 3a6baaf1f0..8faa9135e5 100644
--- a/src/nvim/testdir/test_vimscript.vim
+++ b/src/nvim/testdir/test_vimscript.vim
@@ -3,14 +3,12 @@
source check.vim
source shared.vim
+source script_util.vim
"-------------------------------------------------------------------------------
" Test environment {{{1
"-------------------------------------------------------------------------------
-com! XpathINIT let g:Xpath = ''
-com! -nargs=1 -bar Xpath let g:Xpath = g:Xpath . <args>
-
" Append a message to the "messages" file
func Xout(text)
split messages
@@ -20,67 +18,31 @@ endfunc
com! -nargs=1 Xout call Xout(<args>)
-" 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 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.
-func 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
-endfunc
-
-" 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. However, if an exception is thrown the file may remain,
-" the caller should call DeleteTheScript() afterwards.
-let s:script_name = ''
-function! ExecAsScript(funcname)
- " Make a script from the function passed as argument.
- let s:script_name = MakeScript(a:funcname)
-
- " Source and delete the script.
- exec "source" s:script_name
- call delete(s:script_name)
- let s:script_name = ''
-endfunction
-
-function! DeleteTheScript()
- if s:script_name
- call delete(s:script_name)
- let s:script_name = ''
- endif
+" Create a new instance of Vim and run the commands in 'test' and then 'verify'
+" The commands in 'test' are expected to store the test results in the Xtest.out
+" file. If the test passes successfully, then Xtest.out should be empty.
+func RunInNewVim(test, verify)
+ let init =<< trim END
+ set cpo-=C " support line-continuation in sourced script
+ source script_util.vim
+ XpathINIT
+ XloopINIT
+ END
+ let cleanup =<< trim END
+ call writefile(v:errors, 'Xtest.out')
+ qall
+ END
+ call writefile(init, 'Xtest.vim')
+ call writefile(a:test, 'Xtest.vim', 'a')
+ call writefile(a:verify, 'Xverify.vim')
+ call writefile(cleanup, 'Xverify.vim', 'a')
+ call RunVim([], [], "-S Xtest.vim -S Xverify.vim")
+ call assert_equal([], readfile('Xtest.out'))
+ call delete('Xtest.out')
+ call delete('Xtest.vim')
+ call delete('Xverify.vim')
endfunc
-com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
-
-
"-------------------------------------------------------------------------------
" Test 1: :endwhile in function {{{1
"
@@ -90,7 +52,7 @@ com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
" tests will hang.
"-------------------------------------------------------------------------------
-function! T1_F()
+func T1_F()
Xpath 'a'
let first = 1
while 1
@@ -104,9 +66,9 @@ function! T1_F()
return
endif
endwhile
-endfunction
+endfunc
-function! T1_G()
+func T1_G()
Xpath 'h'
let first = 1
while 1
@@ -121,7 +83,7 @@ function! T1_G()
endif
if 1 " unmatched :if
endwhile
-endfunction
+endfunc
func Test_endwhile_function()
XpathINIT
@@ -175,7 +137,7 @@ endfunc
" Test 3: :if, :elseif, :while, :continue, :break {{{1
"-------------------------------------------------------------------------------
-function Test_if_while()
+func Test_if_while()
XpathINIT
if 1
Xpath 'a'
@@ -235,7 +197,7 @@ endfunc
" Test 4: :return {{{1
"-------------------------------------------------------------------------------
-function! T4_F()
+func T4_F()
if 1
Xpath 'a'
let loops = 3
@@ -253,15 +215,15 @@ function! T4_F()
else
Xpath 'g'
endif
-endfunction
+endfunc
-function Test_return()
+func Test_return()
XpathINIT
call T4_F()
Xpath '4'
call assert_equal('ab3e3b2c24', g:Xpath)
-endfunction
+endfunc
"-------------------------------------------------------------------------------
@@ -271,14 +233,14 @@ endfunction
" test as a script file (:return replaced by :finish).
"-------------------------------------------------------------------------------
-function Test_finish()
+func Test_finish()
XpathINIT
ExecAsScript T4_F
Xpath '5'
call DeleteTheScript()
call assert_equal('ab3e3b2c25', g:Xpath)
-endfunction
+endfunc
@@ -412,7 +374,7 @@ delfunction G31
delfunction G32
delfunction G33
-function Test_defining_functions()
+func Test_defining_functions()
call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result)
call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls)
endfunc
@@ -476,7 +438,7 @@ endfunc
XpathINIT
-function! T8_F()
+func T8_F()
if 1
Xpath 'a'
while 1
@@ -508,9 +470,9 @@ function! T8_F()
return novar " returns (default return value 0)
Xpath 'q'
return 1 " not reached
-endfunction
+endfunc
-function! T8_G() abort
+func T8_G() abort
if 1
Xpath 'r'
while 1
@@ -524,9 +486,9 @@ function! T8_G() abort
Xpath 'x'
return -4 " not reached
-endfunction
+endfunc
-function! T8_H() abort
+func T8_H() abort
while 1
Xpath 'A'
if 1
@@ -540,7 +502,7 @@ function! T8_H() abort
Xpath 'F'
return -4 " not reached
-endfunction
+endfunc
" Aborted functions (T8_G and T8_H) return -1.
let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H()
@@ -567,7 +529,7 @@ endfunc
XpathINIT
-function! F() abort
+func F() abort
Xpath 'a'
let result = G() " not aborted
Xpath 'b'
@@ -575,30 +537,30 @@ function! F() abort
Xpath 'c'
endif
return 1
-endfunction
+endfunc
-function! G() " no abort attribute
+func G() " no abort attribute
Xpath 'd'
if H() != -1 " aborted
Xpath 'e'
endif
Xpath 'f'
return 2
-endfunction
+endfunc
-function! H() abort
+func H() abort
Xpath 'g'
call I() " aborted
Xpath 'h'
return 4
-endfunction
+endfunc
-function! I() abort
+func I() abort
Xpath 'i'
asdf " error
Xpath 'j'
return 8
-endfunction
+endfunc
if F() != 1
Xpath 'k'
@@ -626,7 +588,7 @@ endfunc
XpathINIT
-function! MSG(enr, emsg)
+func MSG(enr, emsg)
let english = v:lang == "C" || v:lang =~ '^[Ee]n'
if a:enr == ""
Xout "TODO: Add message number for:" a:emsg
@@ -710,10 +672,10 @@ XpathINIT
let calls = 0
-function! P(num)
+func P(num)
let g:calls = g:calls + a:num " side effect on call
return 0
-endfunction
+endfunc
if 1
Xpath 'a'
@@ -1092,7 +1054,4843 @@ func Test_unmatched_if_in_while()
endfunc
"-------------------------------------------------------------------------------
+" Test 18: Interrupt (Ctrl-C pressed) {{{1
+"
+" On an interrupt, the script processing is terminated immediately.
+"-------------------------------------------------------------------------------
+
+func Test_interrupt_while_if()
+ let test =<< trim [CODE]
+ try
+ if 1
+ Xpath 'a'
+ while 1
+ Xpath 'b'
+ if 1
+ Xpath 'c'
+ call interrupt()
+ call assert_report('should not get here')
+ break
+ finish
+ endif | call assert_report('should not get here')
+ call assert_report('should not get here')
+ endwhile | call assert_report('should not get here')
+ call assert_report('should not get here')
+ endif | call assert_report('should not get here')
+ call assert_report('should not get here')
+ catch /^Vim:Interrupt$/
+ Xpath 'd'
+ endtry | Xpath 'e'
+ Xpath 'f'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcdef', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_interrupt_try()
+ let test =<< trim [CODE]
+ try
+ try
+ Xpath 'a'
+ call interrupt()
+ call assert_report('should not get here')
+ endtry | call assert_report('should not get here')
+ call assert_report('should not get here')
+ catch /^Vim:Interrupt$/
+ Xpath 'b'
+ endtry | Xpath 'c'
+ Xpath 'd'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcd', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_interrupt_func_while_if()
+ let test =<< trim [CODE]
+ func F()
+ if 1
+ Xpath 'a'
+ while 1
+ Xpath 'b'
+ if 1
+ Xpath 'c'
+ call interrupt()
+ call assert_report('should not get here')
+ break
+ return
+ endif | call assert_report('should not get here')
+ call assert_report('should not get here')
+ endwhile | call assert_report('should not get here')
+ call assert_report('should not get here')
+ endif | call assert_report('should not get here')
+ call assert_report('should not get here')
+ endfunc
+
+ Xpath 'd'
+ try
+ call F() | call assert_report('should not get here')
+ catch /^Vim:Interrupt$/
+ Xpath 'e'
+ endtry | Xpath 'f'
+ Xpath 'g'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('dabcefg', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_interrupt_func_try()
+ let test =<< trim [CODE]
+ func G()
+ try
+ Xpath 'a'
+ call interrupt()
+ call assert_report('should not get here')
+ endtry | call assert_report('should not get here')
+ call assert_report('should not get here')
+ endfunc
+
+ Xpath 'b'
+ try
+ call G() | call assert_report('should not get here')
+ catch /^Vim:Interrupt$/
+ Xpath 'c'
+ endtry | Xpath 'd'
+ Xpath 'e'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('bacde', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_try_error_abort_1()
+ let test =<< trim [CODE]
+ func F() abort
+ Xpath 'a'
+ asdf
+ call assert_report('should not get here')
+ endfunc
+
+ try
+ Xpath 'b'
+ call F()
+ call assert_report('should not get here')
+ endtry | call assert_report('should not get here')
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('ba', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_try_error_abort_2()
+ let test =<< trim [CODE]
+ func G()
+ Xpath 'a'
+ asdf
+ call assert_report('should not get here')
+ endfunc
+
+ try
+ Xpath 'b'
+ call G()
+ call assert_report('should not get here')
+ endtry | call assert_report('should not get here')
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('ba', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_try_error_abort_3()
+ let test =<< trim [CODE]
+ try
+ Xpath 'a'
+ asdf
+ call assert_report('should not get here')
+ endtry | call assert_report('should not get here')
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('a', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_try_error_abort_4()
+ let test =<< trim [CODE]
+ if 1
+ try
+ Xpath 'a'
+ asdf
+ call assert_report('should not get here')
+ endtry | call assert_report('should not get here')
+ endif | call assert_report('should not get here')
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('a', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_try_error_abort_5()
+ let test =<< trim [CODE]
+ let p = 1
+ while p
+ let p = 0
+ try
+ Xpath 'a'
+ asdf
+ call assert_report('should not get here')
+ endtry | call assert_report('should not get here')
+ endwhile | call assert_report('should not get here')
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('a', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_try_error_abort_6()
+ let test =<< trim [CODE]
+ let p = 1
+ Xpath 'a'
+ while p
+ Xpath 'b'
+ let p = 0
+ try
+ Xpath 'c'
+ endwhile | call assert_report('should not get here')
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abc', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_error_after_try_1()
+ let test =<< trim [CODE]
+ let p = 1
+ while p
+ let p = 0
+ Xpath 'a'
+ try
+ Xpath 'b'
+ endtry
+ asdf
+ call assert_report('should not get here')
+ endwhile | call assert_report('should not get here')
+ Xpath 'c'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abc', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_error_after_try_2()
+ let test =<< trim [CODE]
+ while 1
+ try
+ Xpath 'a'
+ break
+ call assert_report('should not get here')
+ endtry
+ endwhile
+ Xpath 'b'
+ asdf
+ Xpath 'c'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abc', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_error_after_try_3()
+ let test =<< trim [CODE]
+ while 1
+ try
+ Xpath 'a'
+ break
+ call assert_report('should not get here')
+ finally
+ Xpath 'b'
+ endtry
+ endwhile
+ Xpath 'c'
+ asdf
+ Xpath 'd'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcd', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_error_after_try_4()
+ let test =<< trim [CODE]
+ while 1
+ try
+ Xpath 'a'
+ finally
+ Xpath 'b'
+ break
+ call assert_report('should not get here')
+ endtry
+ endwhile
+ Xpath 'c'
+ asdf
+ Xpath 'd'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcd', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_error_after_try_5()
+ let test =<< trim [CODE]
+ let p = 1
+ while p
+ let p = 0
+ try
+ Xpath 'a'
+ continue
+ call assert_report('should not get here')
+ endtry
+ endwhile
+ Xpath 'b'
+ asdf
+ Xpath 'c'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abc', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_error_after_try_6()
+ let test =<< trim [CODE]
+ let p = 1
+ while p
+ let p = 0
+ try
+ Xpath 'a'
+ continue
+ call assert_report('should not get here')
+ finally
+ Xpath 'b'
+ endtry
+ endwhile
+ Xpath 'c'
+ asdf
+ Xpath 'd'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcd', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_error_after_try_7()
+ let test =<< trim [CODE]
+ let p = 1
+ while p
+ let p = 0
+ try
+ Xpath 'a'
+ finally
+ Xpath 'b'
+ continue
+ call assert_report('should not get here')
+ endtry
+ endwhile
+ Xpath 'c'
+ asdf
+ Xpath 'd'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcd', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_finally_after_loop_ctrl_statement()
+ let test =<< trim [CODE]
+ func F()
+ let loops = 2
+ while loops > 0
+ XloopNEXT
+ let loops = loops - 1
+ try
+ if loops == 1
+ Xloop 'a'
+ continue
+ call assert_report('should not get here')
+ elseif loops == 0
+ Xloop 'b'
+ break
+ call assert_report('should not get here')
+ endif
+
+ try " inactive
+ call assert_report('should not get here')
+ finally
+ call assert_report('should not get here')
+ endtry
+ finally
+ Xloop 'c'
+ endtry
+ call assert_report('should not get here')
+ endwhile
+
+ try
+ Xpath 'd'
+ return
+ call assert_report('should not get here')
+ try " inactive
+ call assert_report('should not get here')
+ finally
+ call assert_report('should not get here')
+ endtry
+ finally
+ Xpath 'e'
+ endtry
+ call assert_report('should not get here')
+ endfunc
+
+ try
+ Xpath 'f'
+ call F()
+ Xpath 'g'
+ finish
+ call assert_report('should not get here')
+ try " inactive
+ call assert_report('should not get here')
+ finally
+ call assert_report('should not get here')
+ endtry
+ finally
+ Xpath 'h'
+ endtry
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('fa2c2b3c3degh', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_finally_after_error_in_func()
+ let test =<< trim [CODE]
+ func Error()
+ try
+ Xpath 'b'
+ asdf " aborting error, triggering error exception
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ endfunc
+
+ Xpath 'a'
+ call Error()
+ call assert_report('should not get here')
+
+ if 1 " not active due to error
+ try " not active since :if inactive
+ call assert_report('should not get here')
+ finally
+ call assert_report('should not get here')
+ endtry
+ endif
+
+ try " not active due to error
+ call assert_report('should not get here')
+ finally
+ call assert_report('should not get here')
+ endtry
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('ab', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_finally_after_interrupt()
+ let test =<< trim [CODE]
+ func Interrupt()
+ try
+ Xpath 'a'
+ call interrupt() " triggering interrupt exception
+ call assert_report('should not get here')
+ endtry
+ endfunc
+
+ Xpath 'b'
+ try
+ call Interrupt()
+ catch /^Vim:Interrupt$/
+ Xpath 'c'
+ finish
+ endtry
+ call assert_report('should not get here')
+
+ if 1 " not active due to interrupt
+ try " not active since :if inactive
+ call assert_report('should not get here')
+ finally
+ call assert_report('should not get here')
+ endtry
+ endif
+
+ try " not active due to interrupt
+ call assert_report('should not get here')
+ finally
+ call assert_report('should not get here')
+ endtry
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('bac', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_finally_after_throw()
+ let test =<< trim [CODE]
+ func Throw()
+ Xpath 'a'
+ throw 'xyz'
+ endfunc
+
+ Xpath 'b'
+ call Throw()
+ call assert_report('should not get here')
+
+ if 1 " not active due to :throw
+ try " not active since :if inactive
+ call assert_report('should not get here')
+ finally
+ call assert_report('should not get here')
+ endtry
+ endif
+
+ try " not active due to :throw
+ call assert_report('should not get here')
+ finally
+ call assert_report('should not get here')
+ endtry
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('ba', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_catch_after_throw()
+ let test =<< trim [CODE]
+ try
+ Xpath 'a'
+ throw "xyz"
+ call assert_report('should not get here')
+
+ if 1 " not active due to :throw
+ try " not active since :if inactive
+ call assert_report('should not get here')
+ catch /xyz/
+ call assert_report('should not get here')
+ endtry
+ endif
+ catch /xyz/
+ Xpath 'b'
+ endtry
+
+ Xpath 'c'
+ throw "abc"
+ call assert_report('should not get here')
+
+ try " not active due to :throw
+ call assert_report('should not get here')
+ catch /abc/
+ call assert_report('should not get here')
+ endtry
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abc', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_endtry_after_throw()
+ let test =<< trim [CODE]
+ try " try 1
+ try " try 2
+ Xpath 'a'
+ throw "xyz" " makes try 2 inactive
+ call assert_report('should not get here')
+
+ try " try 3
+ call assert_report('should not get here')
+ endtry " no rethrow to try 1
+ catch /xyz/ " should catch although try 2 inactive
+ Xpath 'b'
+ endtry
+ catch /xyz/ " try 1 active, but exception already caught
+ call assert_report('should not get here')
+ endtry
+ Xpath 'c'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abc', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func T27_F()
+ try
+ Xpath 'a'
+ try
+ Xpath 'b'
+ return
+ call assert_report('should not get here')
+ finally
+ Xpath 'c'
+ endtry
+ Xpath 'd'
+ finally
+ Xpath 'e'
+ endtry
+ call assert_report('should not get here')
+endfunc
+
+func T27_G()
+ try
+ Xpath 'f'
+ return
+ call assert_report('should not get here')
+ finally
+ Xpath 'g'
+ call T27_F()
+ Xpath 'h'
+ endtry
+ call assert_report('should not get here')
+endfunc
+
+func T27_H()
+ try
+ Xpath 'i'
+ call T27_G()
+ Xpath 'j'
+ finally
+ Xpath 'k'
+ return
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+endfunction
+
+func Test_finally_after_return()
+ XpathINIT
+ try
+ Xpath 'l'
+ call T27_H()
+ Xpath 'm'
+ finally
+ Xpath 'n'
+ endtry
+ call assert_equal('lifgabcehjkmn', g:Xpath)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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).
+"-------------------------------------------------------------------------------
+
+func Test_finally_after_finish()
+ XpathINIT
+
+ let scriptF = MakeScript("T27_F")
+ let scriptG = MakeScript("T27_G", scriptF)
+ let scriptH = MakeScript("T27_H", scriptG)
+
+ try
+ Xpath 'A'
+ exec "source" scriptH
+ Xpath 'B'
+ finally
+ Xpath 'C'
+ endtry
+ Xpath 'D'
+ call assert_equal('AifgabcehjkBCD', g:Xpath)
+ call delete(scriptF)
+ call delete(scriptG)
+ call delete(scriptH)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_finally_after_error_1()
+ let test =<< trim [CODE]
+ func F()
+ while 1
+ try
+ Xpath 'a'
+ while 1
+ try
+ Xpath 'b'
+ asdf " error
+ call assert_report('should not get here')
+ finally
+ Xpath 'c'
+ endtry | call assert_report('should not get here')
+ call assert_report('should not get here')
+ break
+ endwhile
+ call assert_report('should not get here')
+ finally
+ Xpath 'd'
+ endtry | call assert_report('should not get here')
+ call assert_report('should not get here')
+ break
+ endwhile
+ call assert_report('should not get here')
+ endfunc
+
+ while 1
+ try
+ Xpath 'e'
+ while 1
+ call F()
+ call assert_report('should not get here')
+ break
+ endwhile | call assert_report('should not get here')
+ call assert_report('should not get here')
+ finally
+ Xpath 'f'
+ endtry | call assert_report('should not get here')
+ endwhile | call assert_report('should not get here')
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('eabcdf', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_finally_after_error_2()
+ let test =<< trim [CODE]
+ func G() abort
+ if 1
+ try
+ Xpath 'a'
+ asdf " error
+ call assert_report('should not get here')
+ finally
+ Xpath 'b'
+ endtry | Xpath 'c'
+ endif | Xpath 'd'
+ call assert_report('should not get here')
+ endfunc
+
+ if 1
+ try
+ Xpath 'e'
+ call G()
+ call assert_report('should not get here')
+ finally
+ Xpath 'f'
+ endtry | call assert_report('should not get here')
+ endif | call assert_report('should not get here')
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('eabf', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_finally_on_interrupt()
+ let test =<< trim [CODE]
+ func F()
+ try
+ Xloop 'a'
+ call interrupt()
+ call assert_report('should not get here')
+ finally
+ Xloop 'b'
+ endtry
+ call assert_report('should not get here')
+ endfunc
+
+ try
+ try
+ Xpath 'c'
+ try
+ Xpath 'd'
+ call interrupt()
+ call assert_report('should not get here')
+ finally
+ Xpath 'e'
+ try
+ Xpath 'f'
+ try
+ Xpath 'g'
+ finally
+ Xpath 'h'
+ try
+ Xpath 'i'
+ call interrupt()
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ finally
+ Xpath 'j'
+ try
+ Xpath 'k'
+ call F()
+ call assert_report('should not get here')
+ finally
+ Xpath 'l'
+ try
+ Xpath 'm'
+ XloopNEXT
+ ExecAsScript F
+ call assert_report('should not get here')
+ finally
+ Xpath 'n'
+ endtry
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ catch /^Vim:Interrupt$/
+ Xpath 'o'
+ endtry
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('cdefghijka1b1lma2b2no', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_finally_after_throw_2()
+ let test =<< trim [CODE]
+ func F()
+ try
+ Xloop 'a'
+ throw "exception"
+ call assert_report('should not get here')
+ finally
+ Xloop 'b'
+ endtry
+ call assert_report('should not get here')
+ endfunc
+
+ try
+ Xpath 'c'
+ try
+ Xpath 'd'
+ throw "exception"
+ call assert_report('should not get here')
+ finally
+ Xpath 'e'
+ try
+ Xpath 'f'
+ try
+ Xpath 'g'
+ finally
+ Xpath 'h'
+ try
+ Xpath 'i'
+ throw "exception"
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ finally
+ Xpath 'j'
+ try
+ Xpath 'k'
+ call F()
+ call assert_report('should not get here')
+ finally
+ Xpath 'l'
+ try
+ Xpath 'm'
+ XloopNEXT
+ ExecAsScript F
+ call assert_report('should not get here')
+ finally
+ Xpath 'n'
+ endtry
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('cdefghijka1b1lma2b2n', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_finally_after_continue()
+ let test =<< trim [CODE]
+ func 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"
+ call interrupt()
+ let dummy = 0
+ elseif a:jump == "throw"
+ throw "abc"
+ endif
+ finally
+ continue " discards jump that caused the :finally
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ elseif loop == 2
+ Xloop 'a'
+ endif
+ endwhile
+ endfunc
+
+ call C("continue")
+ Xpath 'b'
+ call C("break")
+ Xpath 'c'
+ call C("return")
+ Xpath 'd'
+ let g:jump = "finish"
+ ExecAsScript C
+ unlet g:jump
+ Xpath 'e'
+ try
+ call C("error")
+ Xpath 'f'
+ finally
+ Xpath 'g'
+ try
+ call C("interrupt")
+ Xpath 'h'
+ finally
+ Xpath 'i'
+ call C("throw")
+ Xpath 'j'
+ endtry
+ endtry
+ Xpath 'k'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_finally_discard_by_break()
+ let test =<< trim [CODE]
+ func 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"
+ call interrupt()
+ let dummy = 0
+ elseif a:jump == "throw"
+ throw "abc"
+ endif
+ finally
+ break " discards jump that caused the :finally
+ call assert_report('should not get here')
+ endtry
+ elseif loop == 2
+ call assert_report('should not get here')
+ endif
+ endwhile
+ Xloop 'a'
+ endfunc
+
+ call B("continue")
+ Xpath 'b'
+ call B("break")
+ Xpath 'c'
+ call B("return")
+ Xpath 'd'
+ let g:jump = "finish"
+ ExecAsScript B
+ unlet g:jump
+ Xpath 'e'
+ try
+ call B("error")
+ Xpath 'f'
+ finally
+ Xpath 'g'
+ try
+ call B("interrupt")
+ Xpath 'h'
+ finally
+ Xpath 'i'
+ call B("throw")
+ Xpath 'j'
+ endtry
+ endtry
+ Xpath 'k'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('a2ba3ca4da5ea6fga7hia8jk', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_finally_discard_by_return()
+ let test =<< trim [CODE]
+ func R(jump, retval) abort
+ 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"
+ call interrupt()
+ let dummy = 0
+ elseif a:jump == "throw"
+ throw "abc"
+ endif
+ finally
+ return a:retval " discards jump that caused the :finally
+ call assert_report('should not get here')
+ endtry
+ elseif loop == 2
+ call assert_report('should not get here')
+ endif
+ endwhile
+ call assert_report('should not get here')
+ endfunc
+
+ let sum = -R("continue", -8)
+ Xpath 'a'
+ let sum = sum - R("break", -16)
+ Xpath 'b'
+ let sum = sum - R("return", -32)
+ Xpath 'c'
+ try
+ let sum = sum - R("error", -64)
+ Xpath 'd'
+ finally
+ Xpath 'e'
+ try
+ let sum = sum - R("interrupt", -128)
+ Xpath 'f'
+ finally
+ Xpath 'g'
+ let sum = sum - R("throw", -256)
+ Xpath 'h'
+ endtry
+ endtry
+ Xpath 'i'
+
+ let expected = 8 + 16 + 32 + 64 + 128 + 256
+ call assert_equal(sum, expected)
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcdefghi', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_finally_discard_by_finish()
+ let test =<< trim [CODE]
+ func F(jump) " not executed as function, transformed to a script
+ 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"
+ call interrupt()
+ let dummy = 0
+ elseif a:jump == "throw"
+ throw "abc"
+ endif
+ finally
+ finish " discards jump that caused the :finally
+ call assert_report('should not get here')
+ endtry
+ elseif loop == 2
+ call assert_report('should not get here')
+ endif
+ endwhile
+ call assert_report('should not get here')
+ endfunc
+
+ let scriptF = MakeScript("F")
+ delfunction F
+
+ let g:jump = "continue"
+ exec "source" scriptF
+ Xpath 'a'
+ let g:jump = "break"
+ exec "source" scriptF
+ Xpath 'b'
+ let g:jump = "finish"
+ exec "source" scriptF
+ Xpath 'c'
+ try
+ let g:jump = "error"
+ exec "source" scriptF
+ Xpath 'd'
+ finally
+ Xpath 'e'
+ try
+ let g:jump = "interrupt"
+ exec "source" scriptF
+ Xpath 'f'
+ finally
+ Xpath 'g'
+ try
+ let g:jump = "throw"
+ exec "source" scriptF
+ Xpath 'h'
+ finally
+ Xpath 'i'
+ endtry
+ endtry
+ endtry
+ unlet g:jump
+ call delete(scriptF)
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcdefghi', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_finally_discard_by_error()
+ let test =<< trim [CODE]
+ func E(jump)
+ 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"
+ call interrupt()
+ let dummy = 0
+ elseif a:jump == "throw"
+ throw "abc"
+ endif
+ finally
+ asdf " error; discards jump that caused the :finally
+ endtry
+ elseif loop == 2
+ call assert_report('should not get here')
+ endif
+ endwhile
+ call assert_report('should not get here')
+ endfunc
+
+ try
+ Xpath 'a'
+ call E("continue")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'b'
+ call E("break")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'c'
+ call E("return")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'd'
+ let g:jump = "finish"
+ ExecAsScript E
+ call assert_report('should not get here')
+ finally
+ unlet g:jump
+ try
+ Xpath 'e'
+ call E("error")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'f'
+ call E("interrupt")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'g'
+ call E("throw")
+ call assert_report('should not get here')
+ finally
+ Xpath 'h'
+ delfunction E
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcdefgh', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_finally_discarded_by_interrupt()
+ let test =<< trim [CODE]
+ func I(jump)
+ 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"
+ call interrupt()
+ let dummy = 0
+ elseif a:jump == "throw"
+ throw "abc"
+ endif
+ finally
+ call interrupt()
+ let dummy = 0
+ endtry
+ elseif loop == 2
+ call assert_report('should not get here')
+ endif
+ endwhile
+ call assert_report('should not get here')
+ endfunc
+
+ try
+ try
+ Xpath 'a'
+ call I("continue")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'b'
+ call I("break")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'c'
+ call I("return")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'd'
+ let g:jump = "finish"
+ ExecAsScript I
+ call assert_report('should not get here')
+ finally
+ unlet g:jump
+ try
+ Xpath 'e'
+ call I("error")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'f'
+ call I("interrupt")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'g'
+ call I("throw")
+ call assert_report('should not get here')
+ finally
+ Xpath 'h'
+ delfunction I
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ call assert_report('should not get here')
+ catch /^Vim:Interrupt$/
+ Xpath 'A'
+ endtry
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcdefghA', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_finally_discard_by_throw()
+ let test =<< trim [CODE]
+ func T(jump)
+ 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"
+ call interrupt()
+ let dummy = 0
+ elseif a:jump == "throw"
+ throw "abc"
+ endif
+ finally
+ throw "xyz" " discards jump that caused the :finally
+ endtry
+ elseif loop == 2
+ call assert_report('should not get here')
+ endif
+ endwhile
+ call assert_report('should not get here')
+ endfunc
+
+ try
+ Xpath 'a'
+ call T("continue")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'b'
+ call T("break")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'c'
+ call T("return")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'd'
+ let g:jump = "finish"
+ ExecAsScript T
+ call assert_report('should not get here')
+ finally
+ unlet g:jump
+ try
+ Xpath 'e'
+ call T("error")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'f'
+ call T("interrupt")
+ call assert_report('should not get here')
+ finally
+ try
+ Xpath 'g'
+ call T("throw")
+ call assert_report('should not get here')
+ finally
+ Xpath 'h'
+ delfunction T
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ endtry
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcdefgh', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func T49_C()
+ try
+ Xpath 'a'
+ throw "arrgh"
+ call assert_report('should not get here')
+ catch /arrgh/
+ Xpath 'b'
+ endtry
+ Xpath 'c'
+endfunc
+
+func T49_T1()
+ XloopNEXT
+ try
+ Xloop 'd'
+ throw "arrgh"
+ call assert_report('should not get here')
+ finally
+ Xloop 'e'
+ endtry
+ Xloop 'f'
+endfunc
+
+func T49_T2()
+ try
+ Xpath 'g'
+ call T49_T1()
+ call assert_report('should not get here')
+ finally
+ Xpath 'h'
+ endtry
+ call assert_report('should not get here')
+endfunc
+
+func Test_throw_exception_across_funcs()
+ XpathINIT
+ XloopINIT
+ try
+ Xpath 'i'
+ call T49_C() " throw and catch
+ Xpath 'j'
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+
+ try
+ Xpath 'k'
+ call T49_T1() " throw, one level
+ call assert_report('should not get here')
+ catch /arrgh/
+ Xpath 'l'
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+
+ try
+ Xpath 'm'
+ call T49_T2() " throw, two levels
+ call assert_report('should not get here')
+ catch /arrgh/
+ Xpath 'n'
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ Xpath 'o'
+
+ call assert_equal('iabcjkd2e2lmgd3e3hno', g:Xpath)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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).
"-------------------------------------------------------------------------------
+
+func T50_F()
+ try
+ Xpath 'A'
+ exec "source" g:scriptC
+ Xpath 'B'
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+
+ try
+ Xpath 'C'
+ exec "source" g:scriptT1
+ call assert_report('should not get here')
+ catch /arrgh/
+ Xpath 'D'
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+endfunc
+
+func Test_throw_across_script()
+ XpathINIT
+ XloopINIT
+ let g:scriptC = MakeScript("T49_C")
+ let g:scriptT1 = MakeScript("T49_T1")
+ let scriptT2 = MakeScript("T49_T2", g:scriptT1)
+
+ try
+ Xpath 'E'
+ call T50_F()
+ Xpath 'F'
+ exec "source" scriptT2
+ call assert_report('should not get here')
+ catch /arrgh/
+ Xpath 'G'
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ Xpath 'H'
+ call assert_equal('EAabcBCd2e2DFgd3e3hGH', g:Xpath)
+
+ call delete(g:scriptC)
+ call delete(g:scriptT1)
+ call delete(scriptT2)
+ unlet g:scriptC g:scriptT1 scriptT2
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_uncaught_exception_1()
+ CheckEnglish
+
+ let test =<< trim [CODE]
+ Xpath 'a'
+ throw "arrgh"
+ call assert_report('should not get here')`
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('E605: Exception not caught: arrgh', v:errmsg)
+ call assert_equal('a', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_uncaught_exception_2()
+ CheckEnglish
+
+ let test =<< trim [CODE]
+ try
+ Xpath 'a'
+ throw "oops"
+ call assert_report('should not get here')`
+ catch /arrgh/
+ call assert_report('should not get here')`
+ endtry
+ call assert_report('should not get here')`
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('E605: Exception not caught: oops', v:errmsg)
+ call assert_equal('a', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_uncaught_exception_3()
+ CheckEnglish
+
+ let test =<< trim [CODE]
+ func T()
+ Xpath 'c'
+ throw "brrr"
+ call assert_report('should not get here')`
+ endfunc
+
+ try
+ Xpath 'a'
+ throw "arrgh"
+ call assert_report('should not get here')`
+ catch /.*/
+ Xpath 'b'
+ call T()
+ call assert_report('should not get here')`
+ endtry
+ call assert_report('should not get here')`
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('E605: Exception not caught: brrr', v:errmsg)
+ call assert_equal('abc', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_uncaught_exception_4()
+ CheckEnglish
+
+ let test =<< trim [CODE]
+ try
+ Xpath 'a'
+ throw "arrgh"
+ call assert_report('should not get here')`
+ finally
+ Xpath 'b'
+ throw "brrr"
+ call assert_report('should not get here')`
+ endtry
+ call assert_report('should not get here')`
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('E605: Exception not caught: brrr', v:errmsg)
+ call assert_equal('ab', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_uncaught_exception_5()
+ CheckEnglish
+
+ " Need to catch and handle interrupt, otherwise the test will wait for the
+ " user to press <Enter> to continue
+ let test =<< trim [CODE]
+ try
+ try
+ Xpath 'a'
+ call interrupt()
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ catch /^Vim:Interrupt$/
+ Xpath 'b'
+ endtry
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('ab', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_uncaught_exception_6()
+ CheckEnglish
+
+ let test =<< trim [CODE]
+ try
+ Xpath 'a'
+ let x = novar " error E121; exception: E121
+ catch /E15:/ " should not catch
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('a', g:Xpath)
+ call assert_equal('E121: Undefined variable: novar', v:errmsg)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+func Test_uncaught_exception_7()
+ CheckEnglish
+
+ let test =<< trim [CODE]
+ try
+ Xpath 'a'
+ " error E108/E488; exception: E488
+ unlet novar #
+ catch /E108:/ " should not catch
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('a', g:Xpath)
+ call assert_equal('E488: Trailing characters: #', v:errmsg)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" Test 53: Nesting errors: :endif/:else/:elseif {{{1
+"
+" For nesting errors of :if conditionals the correct error messages
+" should be given.
+"-------------------------------------------------------------------------------
+
+func Test_nested_if_else_errors()
+ CheckEnglish
+
+ " :endif without :if
+ let code =<< trim END
+ endif
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
+
+ " :endif without :if
+ let code =<< trim END
+ while 1
+ endif
+ endwhile
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
+
+ " :endif without :if
+ let code =<< trim END
+ try
+ finally
+ endif
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
+
+ " :endif without :if
+ let code =<< trim END
+ try
+ endif
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
+
+ " :endif without :if
+ let code =<< trim END
+ try
+ throw "a"
+ catch /a/
+ endif
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endif):E580: :endif without :if')
+
+ " :else without :if
+ let code =<< trim END
+ else
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
+
+ " :else without :if
+ let code =<< trim END
+ while 1
+ else
+ endwhile
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
+
+ " :else without :if
+ let code =<< trim END
+ try
+ finally
+ else
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
+
+ " :else without :if
+ let code =<< trim END
+ try
+ else
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
+
+ " :else without :if
+ let code =<< trim END
+ try
+ throw "a"
+ catch /a/
+ else
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(else):E581: :else without :if')
+
+ " :elseif without :if
+ let code =<< trim END
+ elseif
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
+
+ " :elseif without :if
+ let code =<< trim END
+ while 1
+ elseif
+ endwhile
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
+
+ " :elseif without :if
+ let code =<< trim END
+ try
+ finally
+ elseif
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
+
+ " :elseif without :if
+ let code =<< trim END
+ try
+ elseif
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
+
+ " :elseif without :if
+ let code =<< trim END
+ try
+ throw "a"
+ catch /a/
+ elseif
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(elseif):E582: :elseif without :if')
+
+ " multiple :else
+ let code =<< trim END
+ if 1
+ else
+ else
+ endif
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(else):E583: multiple :else')
+
+ " :elseif after :else
+ let code =<< trim END
+ if 1
+ else
+ elseif 1
+ endif
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(elseif):E584: :elseif after :else')
+
+ call delete('Xtest')
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_nested_while_error()
+ CheckEnglish
+
+ " :endwhile without :while
+ let code =<< trim END
+ endwhile
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
+
+ " :endwhile without :while
+ let code =<< trim END
+ if 1
+ endwhile
+ endif
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
+
+ " Missing :endif
+ let code =<< trim END
+ while 1
+ if 1
+ endwhile
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif')
+
+ " :endwhile without :while
+ let code =<< trim END
+ try
+ finally
+ endwhile
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
+
+ " Missing :endtry
+ let code =<< trim END
+ while 1
+ try
+ finally
+ endwhile
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry')
+
+ " Missing :endtry
+ let code =<< trim END
+ while 1
+ if 1
+ try
+ finally
+ endwhile
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endwhile):E600: Missing :endtry')
+
+ " Missing :endif
+ let code =<< trim END
+ while 1
+ try
+ finally
+ if 1
+ endwhile
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endwhile):E171: Missing :endif')
+
+ " :endwhile without :while
+ let code =<< trim END
+ try
+ endwhile
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
+
+ " :endwhile without :while
+ let code =<< trim END
+ while 1
+ try
+ endwhile
+ endtry
+ endwhile
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
+
+ " :endwhile without :while
+ let code =<< trim END
+ try
+ throw "a"
+ catch /a/
+ endwhile
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
+
+ " :endwhile without :while
+ let code =<< trim END
+ while 1
+ try
+ throw "a"
+ catch /a/
+ endwhile
+ endtry
+ endwhile
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endwhile):E588: :endwhile without :while')
+
+ call delete('Xtest')
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_nested_cont_break_error()
+ CheckEnglish
+
+ " :continue without :while
+ let code =<< trim END
+ continue
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
+
+ " :continue without :while
+ let code =<< trim END
+ if 1
+ continue
+ endif
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
+
+ " :continue without :while
+ let code =<< trim END
+ try
+ finally
+ continue
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
+
+ " :continue without :while
+ let code =<< trim END
+ try
+ continue
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
+
+ " :continue without :while
+ let code =<< trim END
+ try
+ throw "a"
+ catch /a/
+ continue
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(continue):E586: :continue without :while or :for')
+
+ " :break without :while
+ let code =<< trim END
+ break
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
+
+ " :break without :while
+ let code =<< trim END
+ if 1
+ break
+ endif
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
+
+ " :break without :while
+ let code =<< trim END
+ try
+ finally
+ break
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
+
+ " :break without :while
+ let code =<< trim END
+ try
+ break
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
+
+ " :break without :while
+ let code =<< trim END
+ try
+ throw "a"
+ catch /a/
+ break
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(break):E587: :break without :while or :for')
+
+ call delete('Xtest')
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_nested_endtry_error()
+ CheckEnglish
+
+ " :endtry without :try
+ let code =<< trim END
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
+
+ " :endtry without :try
+ let code =<< trim END
+ if 1
+ endtry
+ endif
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
+
+ " :endtry without :try
+ let code =<< trim END
+ while 1
+ endtry
+ endwhile
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endtry):E602: :endtry without :try')
+
+ " Missing :endif
+ let code =<< trim END
+ try
+ if 1
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
+
+ " Missing :endwhile
+ let code =<< trim END
+ try
+ while 1
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
+
+ " Missing :endif
+ let code =<< trim END
+ try
+ finally
+ if 1
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
+
+ " Missing :endwhile
+ let code =<< trim END
+ try
+ finally
+ while 1
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
+
+ " Missing :endif
+ let code =<< trim END
+ try
+ throw "a"
+ catch /a/
+ if 1
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endtry):E171: Missing :endif')
+
+ " Missing :endwhile
+ let code =<< trim END
+ try
+ throw "a"
+ catch /a/
+ while 1
+ endtry
+ END
+ call writefile(code, 'Xtest')
+ call AssertException(['source Xtest'], 'Vim(endtry):E170: Missing :endwhile')
+
+ call delete('Xtest')
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_user_exception_info()
+ CheckEnglish
+
+ XpathINIT
+ XloopINIT
+
+ func FuncException()
+ let g:exception = v:exception
+ endfunc
+
+ func FuncThrowpoint()
+ let g:throwpoint = v:throwpoint
+ endfunc
+
+ let scriptException = MakeScript("FuncException")
+ let scriptThrowPoint = MakeScript("FuncThrowpoint")
+
+ command! CmdException let g:exception = v:exception
+ command! CmdThrowpoint let g:throwpoint = v:throwpoint
+
+ func 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
+ endfunc
+
+ func G(arg, line)
+ call T(a:arg, a:line)
+ endfunc
+
+ func F(arg, line)
+ call G(a:arg, a:line)
+ endfunc
+
+ let scriptT = MakeScript("T")
+ let scriptG = MakeScript("G", scriptT)
+ let scriptF = MakeScript("F", scriptG)
+
+ try
+ Xpath 'a'
+ call F("oops", 2)
+ catch /.*/
+ Xpath 'b'
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call assert_equal("oops", v:exception)
+ call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
+ call assert_match('\<2\>', v:throwpoint)
+
+ exec "let exception = v:exception"
+ exec "let throwpoint = v:throwpoint"
+ call assert_equal("oops", v:exception)
+ call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
+ call assert_match('\<2\>', v:throwpoint)
+
+ CmdException
+ CmdThrowpoint
+ call assert_equal("oops", v:exception)
+ call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
+ call assert_match('\<2\>', v:throwpoint)
+
+ call FuncException()
+ call FuncThrowpoint()
+ call assert_equal("oops", v:exception)
+ call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
+ call assert_match('\<2\>', v:throwpoint)
+
+ exec "source" scriptException
+ exec "source" scriptThrowPoint
+ call assert_equal("oops", v:exception)
+ call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
+ call assert_match('\<2\>', v:throwpoint)
+
+ try
+ Xpath 'c'
+ call G("arrgh", 4)
+ catch /.*/
+ Xpath 'd'
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call assert_equal("arrgh", v:exception)
+ call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
+ call assert_match('\<4\>', v:throwpoint)
+
+ try
+ Xpath 'e'
+ let g:arg = "autsch"
+ let g:line = 6
+ exec "source" scriptF
+ catch /.*/
+ Xpath 'f'
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call assert_equal("autsch", v:exception)
+ call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint)
+ call assert_match('\<6\>', v:throwpoint)
+ finally
+ Xpath 'g'
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call assert_equal("arrgh", v:exception)
+ call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
+ call assert_match('\<4\>', v:throwpoint)
+ try
+ Xpath 'h'
+ let g:arg = "brrrr"
+ let g:line = 8
+ exec "source" scriptG
+ catch /.*/
+ Xpath 'i'
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ " Resolve scriptT for matching it against v:throwpoint.
+ call assert_equal("brrrr", v:exception)
+ call assert_match(fnamemodify(scriptT, ':t'), v:throwpoint)
+ call assert_match('\<8\>', v:throwpoint)
+ finally
+ Xpath 'j'
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call assert_equal("arrgh", v:exception)
+ call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
+ call assert_match('\<4\>', v:throwpoint)
+ endtry
+ Xpath 'k'
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call assert_equal("arrgh", v:exception)
+ call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
+ call assert_match('\<4\>', v:throwpoint)
+ endtry
+ Xpath 'l'
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call assert_equal("arrgh", v:exception)
+ call assert_match('\<G\[1]\.\.T\>', v:throwpoint)
+ call assert_match('\<4\>', v:throwpoint)
+ finally
+ Xpath 'm'
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call assert_equal("oops", v:exception)
+ call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
+ call assert_match('\<2\>', v:throwpoint)
+ endtry
+ Xpath 'n'
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call assert_equal("oops", v:exception)
+ call assert_match('\<F\[1]\.\.G\[1]\.\.T\>', v:throwpoint)
+ call assert_match('\<2\>', v:throwpoint)
+ finally
+ Xpath 'o'
+ let exception = v:exception
+ let throwpoint = v:throwpoint
+ call assert_equal("", v:exception)
+ call assert_match('^$', v:throwpoint)
+ call assert_match('^$', v:throwpoint)
+ endtry
+
+ call assert_equal('abcdefghijklmno', g:Xpath)
+
+ 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
+endfunc
+
+"-------------------------------------------------------------------------------
+"
+" Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1
+"
+" v:exception and v:throwpoint work also for error and interrupt
+" exceptions.
+"-------------------------------------------------------------------------------
+
+func Test_execption_info_for_error()
+ CheckEnglish
+
+ let test =<< trim [CODE]
+ func T(line)
+ if a:line == 2
+ delfunction T " error (function in use) in line 2
+ elseif a:line == 4
+ call interrupt()
+ endif
+ endfunc
+
+ while 1
+ try
+ Xpath 'a'
+ call T(2)
+ call assert_report('should not get here')
+ catch /.*/
+ Xpath 'b'
+ if v:exception !~ 'Vim(delfunction):'
+ call assert_report('should not get here')
+ endif
+ if v:throwpoint !~ '\<T\>'
+ call assert_report('should not get here')
+ endif
+ if v:throwpoint !~ '\<2\>'
+ call assert_report('should not get here')
+ endif
+ finally
+ Xpath 'c'
+ if v:exception != ""
+ call assert_report('should not get here')
+ endif
+ if v:throwpoint != ""
+ call assert_report('should not get here')
+ endif
+ break
+ endtry
+ endwhile
+
+ Xpath 'd'
+ if v:exception != ""
+ call assert_report('should not get here')
+ endif
+ if v:throwpoint != ""
+ call assert_report('should not get here')
+ endif
+
+ while 1
+ try
+ Xpath 'e'
+ call T(4)
+ call assert_report('should not get here')
+ catch /.*/
+ Xpath 'f'
+ if v:exception != 'Vim:Interrupt'
+ call assert_report('should not get here')
+ endif
+ if v:throwpoint !~ 'function T'
+ call assert_report('should not get here')
+ endif
+ if v:throwpoint !~ '\<4\>'
+ call assert_report('should not get here')
+ endif
+ finally
+ Xpath 'g'
+ if v:exception != ""
+ call assert_report('should not get here')
+ endif
+ if v:throwpoint != ""
+ call assert_report('should not get here')
+ endif
+ break
+ endtry
+ endwhile
+
+ Xpath 'h'
+ if v:exception != ""
+ call assert_report('should not get here')
+ endif
+ if v:throwpoint != ""
+ call assert_report('should not get here')
+ endif
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcdefgh', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+"
+" 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.
+"-------------------------------------------------------------------------------
+func Test_exception_info_on_discard()
+ CheckEnglish
+
+ let test =<< trim [CODE]
+ let sfile = expand("<sfile>")
+
+ while 1
+ try
+ throw "x1"
+ catch /.*/
+ break
+ endtry
+ endwhile
+ call assert_equal('', v:exception)
+ call assert_equal('', v:throwpoint)
+
+ while 1
+ try
+ throw "x2"
+ catch /.*/
+ break
+ finally
+ call assert_equal('', v:exception)
+ call assert_equal('', v:throwpoint)
+ endtry
+ break
+ endwhile
+ call assert_equal('', v:exception)
+ call assert_equal('', v:throwpoint)
+
+ while 1
+ try
+ let errcaught = 0
+ try
+ try
+ throw "x3"
+ catch /.*/
+ let lnum = expand("<sflnum>")
+ asdf
+ endtry
+ catch /.*/
+ let errcaught = 1
+ call assert_match('Vim:E492: Not an editor command:', v:exception)
+ call assert_match('line ' .. (lnum + 1), v:throwpoint)
+ endtry
+ finally
+ call assert_equal(1, errcaught)
+ break
+ endtry
+ endwhile
+ call assert_equal('', v:exception)
+ call assert_equal('', v:throwpoint)
+
+ Xpath 'a'
+
+ while 1
+ try
+ let intcaught = 0
+ try
+ try
+ throw "x4"
+ catch /.*/
+ let lnum = expand("<sflnum>")
+ call interrupt()
+ endtry
+ catch /.*/
+ let intcaught = 1
+ call assert_match('Vim:Interrupt', v:exception)
+ call assert_match('line ' .. (lnum + 1), v:throwpoint)
+ endtry
+ finally
+ call assert_equal(1, intcaught)
+ break
+ endtry
+ endwhile
+ call assert_equal('', v:exception)
+ call assert_equal('', v:throwpoint)
+
+ Xpath 'b'
+
+ while 1
+ try
+ let errcaught = 0
+ try
+ try
+ if 1
+ let lnum = expand("<sflnum>")
+ throw "x5"
+ " missing endif
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ catch /.*/
+ let errcaught = 1
+ call assert_match('Vim(catch):E171: Missing :endif:', v:exception)
+ call assert_match('line ' .. (lnum + 3), v:throwpoint)
+ endtry
+ finally
+ call assert_equal(1, errcaught)
+ break
+ endtry
+ endwhile
+ call assert_equal('', v:exception)
+ call assert_equal('', v:throwpoint)
+
+ Xpath 'c'
+
+ try
+ while 1
+ try
+ throw "x6"
+ finally
+ break
+ endtry
+ break
+ endwhile
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ call assert_equal('', v:exception)
+ call assert_equal('', v:throwpoint)
+
+ try
+ while 1
+ try
+ throw "x7"
+ finally
+ break
+ endtry
+ break
+ endwhile
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ call assert_equal('', v:exception)
+ call assert_equal('', v:throwpoint)
+ endtry
+ call assert_equal('', v:exception)
+ call assert_equal('', v:throwpoint)
+
+ while 1
+ try
+ let errcaught = 0
+ try
+ try
+ throw "x8"
+ finally
+ let lnum = expand("<sflnum>")
+ asdf
+ endtry
+ catch /.*/
+ let errcaught = 1
+ call assert_match('Vim:E492: Not an editor command:', v:exception)
+ call assert_match('line ' .. (lnum + 1), v:throwpoint)
+ endtry
+ finally
+ call assert_equal(1, errcaught)
+ break
+ endtry
+ endwhile
+ call assert_equal('', v:exception)
+ call assert_equal('', v:throwpoint)
+
+ Xpath 'd'
+
+ while 1
+ try
+ let intcaught = 0
+ try
+ try
+ throw "x9"
+ finally
+ let lnum = expand("<sflnum>")
+ call interrupt()
+ endtry
+ catch /.*/
+ let intcaught = 1
+ call assert_match('Vim:Interrupt', v:exception)
+ call assert_match('line ' .. (lnum + 1), v:throwpoint)
+ endtry
+ finally
+ call assert_equal(1, intcaught)
+ break
+ endtry
+ endwhile
+ call assert_equal('', v:exception)
+ call assert_equal('', v:throwpoint)
+
+ Xpath 'e'
+
+ while 1
+ try
+ let errcaught = 0
+ try
+ try
+ if 1
+ let lnum = expand("<sflnum>")
+ throw "x10"
+ " missing endif
+ finally
+ call assert_equal('', v:exception)
+ call assert_equal('', v:throwpoint)
+ endtry
+ catch /.*/
+ let errcaught = 1
+ call assert_match('Vim(finally):E171: Missing :endif:', v:exception)
+ call assert_match('line ' .. (lnum + 3), v:throwpoint)
+ endtry
+ finally
+ call assert_equal(1, errcaught)
+ break
+ endtry
+ endwhile
+ call assert_equal('', v:exception)
+ call assert_equal('', v:throwpoint)
+
+ Xpath 'f'
+
+ while 1
+ try
+ let errcaught = 0
+ try
+ try
+ if 1
+ let lnum = expand("<sflnum>")
+ throw "x11"
+ " missing endif
+ endtry
+ catch /.*/
+ let errcaught = 1
+ call assert_match('Vim(endtry):E171: Missing :endif:', v:exception)
+ call assert_match('line ' .. (lnum + 3), v:throwpoint)
+ endtry
+ finally
+ call assert_equal(1, errcaught)
+ break
+ endtry
+ endwhile
+ call assert_equal('', v:exception)
+ call assert_equal('', v:throwpoint)
+
+ Xpath 'g'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcdefg', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+"
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_rethrow_exception_1()
+ XpathINIT
+ try
+ try
+ Xpath 'a'
+ throw "oops"
+ catch /oops/
+ Xpath 'b'
+ throw v:exception " rethrow user exception
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ catch /^oops$/ " catches rethrown user exception
+ Xpath 'c'
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ call assert_equal('abc', g:Xpath)
+endfunc
+
+func Test_rethrow_exception_2()
+ XpathINIT
+ try
+ let caught = 0
+ try
+ Xpath 'a'
+ write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e
+ call assert_report('should not get here')
+ catch /^Vim(write):/
+ let caught = 1
+ throw v:exception " throw error: cannot fake Vim exception
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'b'
+ call assert_equal(1, caught)
+ endtry
+ catch /^Vim(throw):/ " catches throw error
+ let caught = caught + 1
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'c'
+ call assert_equal(2, caught)
+ endtry
+ call assert_equal('abc', g:Xpath)
+endfunc
+
+func Test_rethrow_exception_3()
+ XpathINIT
+ try
+ let caught = 0
+ try
+ Xpath 'a'
+ 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 /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'b'
+ call assert_equal(1, caught)
+ endtry
+ catch /^Vim(echoerr):/
+ let caught = caught + 1
+ call assert_match(value, v:exception)
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'c'
+ call assert_equal(2, caught)
+ endtry
+ call assert_equal('abc', g:Xpath)
+endfunc
+
+func Test_rethrow_exception_3()
+ XpathINIT
+ try
+ let errcaught = 0
+ try
+ Xpath 'a'
+ let intcaught = 0
+ call interrupt()
+ catch /^Vim:/ " catch interrupt exception
+ let intcaught = 1
+ " Trigger Vim error exception with value specified after :echoerr
+ echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'b'
+ call assert_equal(1, intcaught)
+ endtry
+ catch /^Vim(echoerr):/
+ let errcaught = 1
+ call assert_match('Interrupt', v:exception)
+ finally
+ Xpath 'c'
+ call assert_equal(1, errcaught)
+ endtry
+ call assert_equal('abc', g:Xpath)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_catch_intr_exception()
+ let test =<< trim [CODE]
+ while 1
+ try
+ try
+ Xpath 'a'
+ call interrupt()
+ call assert_report('should not get here')
+ catch /^Vim:Interrupt$/
+ Xpath 'b'
+ finally
+ Xpath 'c'
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'd'
+ break
+ endtry
+ endwhile
+
+ while 1
+ try
+ try
+ try
+ Xpath 'e'
+ asdf
+ call assert_report('should not get here')
+ catch /do_not_catch/
+ call assert_report('should not get here')
+ catch /.*/
+ Xpath 'f'
+ call interrupt()
+ call assert_report('should not get here')
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'g'
+ call interrupt()
+ call assert_report('should not get here')
+ endtry
+ catch /^Vim:Interrupt$/
+ Xpath 'h'
+ finally
+ Xpath 'i'
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'j'
+ break
+ endtry
+ endwhile
+
+ while 1
+ try
+ try
+ try
+ Xpath 'k'
+ throw "x"
+ call assert_report('should not get here')
+ catch /do_not_catch/
+ call assert_report('should not get here')
+ catch /x/
+ Xpath 'l'
+ call interrupt()
+ call assert_report('should not get here')
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ catch /^Vim:Interrupt$/
+ Xpath 'm'
+ finally
+ Xpath 'n'
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'o'
+ break
+ endtry
+ endwhile
+
+ while 1
+ try
+ try
+ Xpath 'p'
+ call interrupt()
+ call assert_report('should not get here')
+ catch /do_not_catch/
+ call interrupt()
+ call assert_report('should not get here')
+ catch /^Vim:Interrupt$/
+ Xpath 'q'
+ finally
+ Xpath 'r'
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 's'
+ break
+ endtry
+ endwhile
+
+ Xpath 't'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcdefghijklmnopqrst', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_catch_err_exception_1()
+ XpathINIT
+ while 1
+ try
+ try
+ let caught = 0
+ unlet novar
+ catch /^Vim(unlet):/
+ Xpath 'a'
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "")
+ finally
+ Xpath 'b'
+ call assert_equal(1, caught)
+ call assert_match('E108: No such variable: "novar"', v:errmsg)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'c'
+ break
+ endtry
+ call assert_report('should not get here')
+ endwhile
+ call assert_equal('abc', g:Xpath)
+endfunc
+
+func Test_catch_err_exception_2()
+ XpathINIT
+ while 1
+ try
+ try
+ let caught = 0
+ throw novar " error in :throw
+ catch /^Vim(throw):/
+ Xpath 'a'
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
+ finally
+ Xpath 'b'
+ call assert_equal(1, caught)
+ call assert_match('E121: Undefined variable: novar', v:errmsg)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'c'
+ break
+ endtry
+ call assert_report('should not get here')
+ endwhile
+ call assert_equal('abc', g:Xpath)
+endfunc
+
+func Test_catch_err_exception_3()
+ XpathINIT
+ while 1
+ try
+ try
+ let caught = 0
+ throw "Vim:faked" " error: cannot fake Vim exception
+ catch /^Vim(throw):/
+ Xpath 'a'
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
+ finally
+ Xpath 'b'
+ call assert_equal(1, caught)
+ call assert_match("E608: Cannot :throw exceptions with 'Vim' prefix",
+ \ v:errmsg)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'c'
+ break
+ endtry
+ call assert_report('should not get here')
+ endwhile
+ call assert_equal('abc', g:Xpath)
+endfunc
+
+func Test_catch_err_exception_4()
+ XpathINIT
+ func F()
+ while 1
+ " Missing :endwhile
+ endfunc
+
+ while 1
+ try
+ try
+ let caught = 0
+ call F()
+ catch /^Vim(endfunction):/
+ Xpath 'a'
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "")
+ finally
+ Xpath 'b'
+ call assert_equal(1, caught)
+ call assert_match("E170: Missing :endwhile", v:errmsg)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'c'
+ break
+ endtry
+ call assert_report('should not get here')
+ endwhile
+ call assert_equal('abc', g:Xpath)
+ delfunc F
+endfunc
+
+func Test_catch_err_exception_5()
+ XpathINIT
+ func F()
+ while 1
+ " Missing :endwhile
+ endfunc
+
+ while 1
+ try
+ try
+ let caught = 0
+ ExecAsScript F
+ catch /^Vim:/
+ Xpath 'a'
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim:', '', "")
+ finally
+ Xpath 'b'
+ call assert_equal(1, caught)
+ call assert_match("E170: Missing :endwhile", v:errmsg)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'c'
+ break
+ endtry
+ call assert_report('should not get here')
+ endwhile
+ call assert_equal('abc', g:Xpath)
+ delfunc F
+endfunc
+
+func Test_catch_err_exception_6()
+ XpathINIT
+ func G()
+ call G()
+ endfunc
+
+ while 1
+ try
+ let mfd_save = &mfd
+ set mfd=3
+ try
+ let caught = 0
+ call G()
+ catch /^Vim(call):/
+ Xpath 'a'
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(call):', '', "")
+ finally
+ Xpath 'b'
+ call assert_equal(1, caught)
+ call assert_match("E132: Function call depth is higher than 'maxfuncdepth'", v:errmsg)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'c'
+ let &mfd = mfd_save
+ break
+ endtry
+ call assert_report('should not get here')
+ endwhile
+ call assert_equal('abc', g:Xpath)
+ delfunc G
+endfunc
+
+func Test_catch_err_exception_7()
+ XpathINIT
+ func H()
+ return H()
+ endfunc
+
+ while 1
+ try
+ let mfd_save = &mfd
+ set mfd=3
+ try
+ let caught = 0
+ call H()
+ catch /^Vim(return):/
+ Xpath 'a'
+ let caught = 1
+ let v:errmsg = substitute(v:exception, '^Vim(return):', '', "")
+ finally
+ Xpath 'b'
+ call assert_equal(1, caught)
+ call assert_match("E132: Function call depth is higher than 'maxfuncdepth'", v:errmsg)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'c'
+ let &mfd = mfd_save
+ break " discard error for $VIMNOERRTHROW
+ endtry
+ call assert_report('should not get here')
+ endwhile
+
+ call assert_equal('abc', g:Xpath)
+ delfunc H
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_silent_exception()
+ XpathINIT
+ XloopINIT
+ let g:taken = ""
+
+ func S(n) abort
+ XloopNEXT
+ let g:taken = g:taken . "E" . a:n
+ let v:errmsg = ""
+ exec "asdf" . a:n
+
+ " Check that ":silent!" continues:
+ Xloop 'a'
+
+ " Check that ":silent!" sets "v:errmsg":
+ call assert_match("E492: Not an editor command", v:errmsg)
+ endfunc
+
+ func Foo()
+ while 1
+ try
+ try
+ let caught = 0
+ " This is not silent:
+ call S(3)
+ catch /^Vim:/
+ Xpath 'b'
+ let caught = 1
+ let errmsg3 = substitute(v:exception, '^Vim:', '', "")
+ silent! call S(4)
+ finally
+ call assert_equal(1, caught)
+ Xpath 'c'
+ call assert_match("E492: Not an editor command", errmsg3)
+ silent! call S(5)
+ " Break out of try conditionals that cover ":silent!". This also
+ " discards the aborting error when $VIMNOERRTHROW is non-zero.
+ break
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ endwhile
+ " This is a double ":silent!" (see caller).
+ silent! call S(6)
+ endfunc
+
+ func Bar()
+ try
+ silent! call S(2)
+ silent! execute "call Foo() | call S(7)"
+ silent! call S(8)
+ endtry " normal end of try cond that covers ":silent!"
+ " This has a ":silent!" from the caller:
+ call S(9)
+ endfunc
+
+ silent! call S(1)
+ silent! call Bar()
+ silent! call S(10)
+
+ call assert_equal("E1E2E3E4E5E6E7E8E9E10", g:taken)
+
+ augroup TMP
+ au!
+ autocmd BufWritePost * Xpath 'd'
+ augroup END
+
+ Xpath 'e'
+ silent! write /i/m/p/o/s/s/i/b/l/e
+ Xpath 'f'
+
+ call assert_equal('a2a3ba5ca6a7a8a9a10a11edf', g:Xpath)
+
+ augroup TMP
+ au!
+ augroup END
+ augroup! TMP
+ delfunction S
+ delfunction Foo
+ delfunction Bar
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_exception_after_error_1()
+ XpathINIT
+ while 1
+ try
+ try
+ Xpath 'a'
+ let caught = 0
+ while 1
+ if 1
+ " Missing :endif
+ endwhile " throw error exception
+ catch /^Vim(/
+ Xpath 'b'
+ let caught = 1
+ finally
+ Xpath 'c'
+ call assert_equal(1, caught)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'd'
+ break
+ endtry
+ call assert_report('should not get here')
+ endwhile
+ call assert_equal('abcd', g:Xpath)
+endfunc
+
+func Test_exception_after_error_2()
+ XpathINIT
+ while 1
+ try
+ try
+ Xpath 'a'
+ let caught = 0
+ try
+ if 1
+ " Missing :endif
+ catch /.*/ " throw error exception
+ call assert_report('should not get here')
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ catch /^Vim(/
+ Xpath 'b'
+ let caught = 1
+ finally
+ Xpath 'c'
+ call assert_equal(1, caught)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'd'
+ break
+ endtry
+ call assert_report('should not get here')
+ endwhile
+ call assert_equal('abcd', g:Xpath)
+endfunc
+
+func Test_exception_after_error_3()
+ XpathINIT
+ while 1
+ try
+ try
+ let caught = 0
+ try
+ Xpath 'a'
+ call interrupt()
+ catch /do_not_catch/
+ call assert_report('should not get here')
+ if 1
+ " Missing :endif
+ catch /.*/ " throw error exception
+ call assert_report('should not get here')
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ catch /^Vim(/
+ Xpath 'b'
+ let caught = 1
+ finally
+ Xpath 'c'
+ call assert_equal(1, caught)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'd'
+ break
+ endtry
+ call assert_report('should not get here')
+ endwhile
+ call assert_equal('abcd', g:Xpath)
+endfunc
+
+func Test_exception_after_error_4()
+ XpathINIT
+ while 1
+ try
+ try
+ let caught = 0
+ try
+ Xpath 'a'
+ throw "x"
+ catch /do_not_catch/
+ call assert_report('should not get here')
+ if 1
+ " Missing :endif
+ catch /x/ " throw error exception
+ call assert_report('should not get here')
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ catch /^Vim(/
+ Xpath 'b'
+ let caught = 1
+ finally
+ Xpath 'c'
+ call assert_equal(1, caught)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'd'
+ break
+ endtry
+ call assert_report('should not get here')
+ endwhile
+ call assert_equal('abcd', g:Xpath)
+endfunc
+
+func Test_exception_after_error_5()
+ XpathINIT
+ while 1
+ try
+ try
+ let caught = 0
+ Xpath 'a'
+ endif " :endif without :if; throw error exception
+ if 1
+ " Missing :endif
+ catch /do_not_catch/ " ignore new error
+ call assert_report('should not get here')
+ catch /^Vim(endif):/
+ Xpath 'b'
+ let caught = 1
+ catch /^Vim(/
+ call assert_report('should not get here')
+ finally
+ Xpath 'c'
+ call assert_equal(1, caught)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'd'
+ break
+ endtry
+ call assert_report('should not get here')
+ endwhile
+ call assert_equal('abcd', g:Xpath)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_catch_pattern_error()
+ CheckEnglish
+ XpathINIT
+
+ try
+ try
+ Xpath 'a'
+ throw "oops"
+ catch /^oops$/
+ Xpath 'b'
+ catch /\)/ " not checked; exception has already been caught
+ call assert_report('should not get here')
+ endtry
+ Xpath 'c'
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ call assert_equal('abc', g:Xpath)
+
+ XpathINIT
+ func F()
+ try
+ try
+ try
+ Xpath 'a'
+ throw "ab"
+ catch /abc/ " does not catch
+ call assert_report('should not get here')
+ catch /\)/ " error; discards exception
+ call assert_report('should not get here')
+ catch /.*/ " not checked
+ call assert_report('should not get here')
+ finally
+ Xpath 'b'
+ endtry
+ call assert_report('should not get here')
+ catch /^ab$/ " checked, but original exception is discarded
+ call assert_report('should not get here')
+ catch /^Vim(catch):/
+ Xpath 'c'
+ call assert_match('Vim(catch):E475: Invalid argument:', v:exception)
+ finally
+ Xpath 'd'
+ endtry
+ Xpath 'e'
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ Xpath 'f'
+ endfunc
+
+ call F()
+ call assert_equal('abcdef', g:Xpath)
+
+ delfunc F
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_stop_range_on_error()
+ let test =<< trim [CODE]
+ let file = tempname()
+ exec "edit" file
+ call setline(1, ['line 1', 'line 2', 'line 3'])
+ let taken = ""
+ let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)"
+
+ func 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"
+ call interrupt()
+ elseif a:reason == "throw"
+ throw "xyz"
+ elseif a:reason == "aborting error"
+ XloopNEXT
+ call assert_equal(g:taken, g:expected)
+ try
+ bwipeout!
+ call delete(g:file)
+ asdf
+ endtry
+ endif
+ endfunc
+
+ func G(reason, n)
+ let g:taken = g:taken .. "G" .. a:n ..
+ \ substitute(a:reason, '\(\l\).*', '\u\1', "")
+ 1,3call F(a:reason, a:n)
+ endfunc
+
+ Xpath 'a'
+ call G("error", 1)
+ try
+ Xpath 'b'
+ try
+ call G("error", 2)
+ call assert_report('should not get here')
+ finally
+ Xpath 'c'
+ try
+ call G("interrupt", 3)
+ call assert_report('should not get here')
+ finally
+ Xpath 'd'
+ try
+ call G("throw", 4)
+ call assert_report('should not get here')
+ endtry
+ endtry
+ endtry
+ catch /xyz/
+ Xpath 'e'
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ Xpath 'f'
+ call G("aborting error", 5)
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcdef', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func THROW(x, n)
+ if a:n == 1
+ Xpath 'A'
+ elseif a:n == 2
+ Xpath 'B'
+ elseif a:n == 3
+ Xpath 'C'
+ endif
+ throw a:x
+endfunc
+
+func NAME(x, n)
+ if a:n == 1
+ call assert_report('should not get here')
+ elseif a:n == 2
+ Xpath 'D'
+ elseif a:n == 3
+ Xpath 'E'
+ elseif a:n == 4
+ Xpath 'F'
+ endif
+ return a:x
+endfunc
+
+func ARG(x, n)
+ if a:n == 1
+ call assert_report('should not get here')
+ elseif a:n == 2
+ call assert_report('should not get here')
+ elseif a:n == 3
+ Xpath 'G'
+ elseif a:n == 4
+ Xpath 'I'
+ endif
+ return a:x
+endfunc
+
+func Test_throw_across_call_cmd()
+ XpathINIT
+
+ func F(x, n)
+ if a:n == 2
+ call assert_report('should not get here')
+ elseif a:n == 4
+ Xpath 'a'
+ endif
+ endfunc
+
+ while 1
+ try
+ let v:errmsg = ""
+
+ while 1
+ try
+ Xpath 'b'
+ call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
+ call assert_report('should not get here')
+ catch /^name$/
+ Xpath 'c'
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ call assert_equal("", v:errmsg)
+ let v:errmsg = ""
+ break
+ endtry
+ endwhile
+
+ while 1
+ try
+ Xpath 'd'
+ call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
+ call assert_report('should not get here')
+ catch /^arg$/
+ Xpath 'e'
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ call assert_equal("", v:errmsg)
+ let v:errmsg = ""
+ break
+ endtry
+ endwhile
+
+ while 1
+ try
+ Xpath 'f'
+ call {NAME("THROW", 3)}(ARG("call", 3), 3)
+ call assert_report('should not get here')
+ catch /^call$/
+ Xpath 'g'
+ catch /^0$/ " default return value
+ call assert_report('should not get here')
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ call assert_equal("", v:errmsg)
+ let v:errmsg = ""
+ break
+ endtry
+ endwhile
+
+ while 1
+ try
+ Xpath 'h'
+ call {NAME("F", 4)}(ARG(4711, 4), 4)
+ Xpath 'i'
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ call assert_equal("", v:errmsg)
+ let v:errmsg = ""
+ break
+ endtry
+ endwhile
+
+ catch /^0$/ " default return value
+ call assert_report('should not get here')
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ call assert_equal("", v:errmsg)
+ let v:errmsg = ""
+ break
+ endtry
+ endwhile
+
+ call assert_equal('bAcdDBefEGCghFIai', g:Xpath)
+ delfunction F
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_throw_across_call_expr()
+ XpathINIT
+
+ func F(x, n)
+ if a:n == 2
+ call assert_report('should not get here')
+ elseif a:n == 4
+ Xpath 'a'
+ endif
+ return a:x
+ endfunction
+
+ while 1
+ try
+ let error = 0
+ let v:errmsg = ""
+
+ while 1
+ try
+ Xpath 'b'
+ let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
+ call assert_report('should not get here')
+ catch /^name$/
+ Xpath 'c'
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ call assert_equal("", v:errmsg)
+ let v:errmsg = ""
+ break
+ endtry
+ endwhile
+ call assert_true(!exists('var1'))
+
+ while 1
+ try
+ Xpath 'd'
+ let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
+ call assert_report('should not get here')
+ catch /^arg$/
+ Xpath 'e'
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ call assert_equal("", v:errmsg)
+ let v:errmsg = ""
+ break
+ endtry
+ endwhile
+ call assert_true(!exists('var2'))
+
+ while 1
+ try
+ Xpath 'f'
+ let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3)
+ call assert_report('should not get here')
+ catch /^call$/
+ Xpath 'g'
+ catch /^0$/ " default return value
+ call assert_report('should not get here')
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ call assert_equal("", v:errmsg)
+ let v:errmsg = ""
+ break
+ endtry
+ endwhile
+ call assert_true(!exists('var3'))
+
+ while 1
+ try
+ Xpath 'h'
+ let var4 = {NAME("F", 4)}(ARG(4711, 4), 4)
+ Xpath 'i'
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ call assert_equal("", v:errmsg)
+ let v:errmsg = ""
+ break
+ endtry
+ endwhile
+ call assert_true(exists('var4') && var4 == 4711)
+
+ catch /^0$/ " default return value
+ call assert_report('should not get here')
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ call assert_equal("", v:errmsg)
+ break
+ endtry
+ endwhile
+
+ call assert_equal('bAcdDBefEGCghFIai', g:Xpath)
+ delfunc F
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_expr_eval_error()
+ let test =<< trim [CODE]
+ let taken = ""
+
+ func ERR(n)
+ let g:taken = g:taken .. "E" .. a:n
+ asdf
+ endfunc
+
+ func ERRabort(n) abort
+ let g:taken = g:taken .. "A" .. a:n
+ asdf
+ endfunc " returns -1; may cause follow-up msg for illegal var/func name
+
+ func WRAP(n, arg)
+ let g:taken = g:taken .. "W" .. a:n
+ let g:saved_errmsg = v:errmsg
+ return arg
+ endfunc
+
+ func INT(n)
+ let g:taken = g:taken .. "I" .. a:n
+ call interrupt()
+ endfunc
+
+ func THR(n)
+ let g:taken = g:taken .. "T" .. a:n
+ throw "should not be caught"
+ endfunc
+
+ func CONT(n)
+ let g:taken = g:taken .. "C" .. a:n
+ endfunc
+
+ func 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"
+ call assert_match(msgptn, errmsg)
+ let v:errmsg = ""
+ let g:saved_errmsg = ""
+ endfunc
+
+ let v:errmsg = ""
+
+ try
+ let t = 1
+ while t <= 9
+ Xloop 'a'
+ 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 /.*/
+ call assert_report('should not get here')
+ endtry
+
+ try
+ let t = 10
+ while t <= 18
+ Xloop 'b'
+ 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 /.*/
+ call assert_report('should not get here')
+ endtry
+
+ try
+ let t = 19
+ while t <= 27
+ Xloop 'c'
+ 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 /.*/
+ call assert_report('should not get here')
+ 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 'd'
+
+ let expected = ""
+ \ .. "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9"
+ \ .. "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18"
+ \ .. "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27"
+ \ .. "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33"
+ \ .. "E34C34M34E35C35M35E36C36M36"
+ \ .. "A37W37C37M37A38W38C38M38A39W39C39M39A40W40C40M40A41W41C41M41"
+ \ .. "A42W42C42M42A43W43C43M43A44W44C44M44A45C45M45"
+ call assert_equal(expected, taken)
+ [CODE]
+ let verify =<< trim [CODE]
+ let expected = "a1a2a3a4a5a6a7a8a9"
+ \ .. "b10b11b12b13b14b15b16b17b18"
+ \ .. "c19c20c21c22c23c24c25c26c27d"
+ call assert_equal(expected, g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+func Test_brace_expr_error()
+ let test =<< trim [CODE]
+ func ERR() abort
+ Xloop 'a'
+ asdf
+ endfunc " returns -1
+
+ func OK()
+ Xloop 'b'
+ let v:errmsg = ""
+ return 0
+ endfunc
+
+ let v:errmsg = ""
+
+ Xpath 'c'
+ func F{1 + ERR() + OK()}(arg)
+ " F0 should be defined.
+ if exists("a:arg") && a:arg == "calling"
+ Xpath 'd'
+ else
+ call assert_report('should not get here')
+ endif
+ endfunction
+ call assert_equal("", v:errmsg)
+ XloopNEXT
+
+ Xpath 'e'
+ call F{1 + ERR() + OK()}("calling")
+ call assert_equal("", v:errmsg)
+ XloopNEXT
+
+ Xpath 'f'
+ delfunction F{1 + ERR() + OK()}
+ call assert_equal("", v:errmsg)
+ XloopNEXT
+
+ try
+ while 1
+ try
+ Xpath 'g'
+ func G{1 + ERR() + OK()}(arg)
+ " G0 should not be defined, and the function body should be
+ " skipped.
+ call assert_report('should not get here')
+ " 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
+ call assert_report('should not get here')
+ endtry
+ try
+ call assert_report('should not get here')
+ endfunction
+
+ call assert_report('should not get here')
+ catch /asdf/
+ " Jumped to when the function is not defined and the body is
+ " skipped.
+ Xpath 'h'
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'i'
+ break
+ endtry " jumped to when the body is not skipped
+ endwhile
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('ca1b1ea2b2dfa3b3ga4hi', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+func Test_expr_eval_error_msg()
+ CheckEnglish
+
+ let test =<< trim [CODE]
+ let taken = ""
+
+ func F(n)
+ let g:taken = g:taken . "F" . a:n
+ endfunc
+
+ func MSG(n, enr, emsg)
+ let g:taken = g:taken . "M" . a:n
+ call assert_match('^' .. a:enr .. ':', v:errmsg)
+ call assert_match(a:emsg, v:errmsg)
+ endfunc
+
+ func CONT(n)
+ let g:taken = g:taken . "C" . a:n
+ endfunc
+
+ let v:errmsg = ""
+ try
+ let t = 1
+ while t <= 14
+ let g:taken = g:taken . "T" . t
+ let v:errmsg = ""
+ try
+ 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\+)\)\=:/
+ Xloop '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\+)\)\=:', '', "")
+ finally
+ Xloop 'b'
+ if t <= 8 && t != 3 && t != 7
+ call MSG(t, 'E475', 'Invalid argument\>')
+ else
+ call MSG(t, 'E121', "Undefined variable")
+ endif
+ let t = t + 1
+ XloopNEXT
+ continue " discard an aborting error
+ endtry
+ endwhile
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+
+ func T(n, expr, enr, emsg)
+ try
+ let g:taken = g:taken . "T" . a:n
+ let v:errmsg = ""
+ try
+ execute "let var = " . a:expr
+ catch /^Vim\((\a\+)\)\=:/
+ Xloop 'c'
+ " 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\+)\)\=:', '', "")
+ finally
+ Xloop 'd'
+ call MSG(a:n, a:enr, a:emsg)
+ XloopNEXT
+ " Discard an aborting error:
+ return
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ endfunc
+
+ 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")
+
+ let expected = ""
+ \ .. "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14"
+ \ .. "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25"
+ \ .. "T26M26T27M27"
+
+ call assert_equal(expected, taken)
+ [CODE]
+ let verify =<< trim [CODE]
+ let expected = "a1b1a2b2a3b3a4b4a5b5a6b6a7b7a8b8a9b9a10b10a11b11a12b12"
+ \ .. "a13b13a14b14c15d15c16d16c17d17c18d18c19d19c20d20"
+ \ .. "c21d21c22d22c23d23c24d24c25d25c26d26c27d27"
+ call assert_equal(expected, g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+func Test_throw_multi_error()
+ CheckEnglish
+
+ let test =<< trim [CODE]
+ func NEXT(cmd)
+ exec a:cmd . " | Xloop 'a'"
+ endfun
+
+ call NEXT('echo novar') " (checks nextcmd)
+ XloopNEXT
+ call NEXT('let novar #') " (skips nextcmd)
+ XloopNEXT
+ call NEXT('unlet novar #') " (skips nextcmd)
+ XloopNEXT
+ call NEXT('let {novar}') " (skips nextcmd)
+ XloopNEXT
+ call NEXT('unlet{ novar}') " (skips nextcmd)
+
+ call assert_equal('a1', g:Xpath)
+ XpathINIT
+ XloopINIT
+
+ func EXEC(cmd)
+ exec a:cmd
+ endfunc
+
+ try
+ while 1 " dummy loop
+ try
+ let v:errmsg = ""
+ call EXEC('echo novar') " normal error
+ catch /^Vim\((\a\+)\)\=:/
+ Xpath 'b'
+ call assert_match('E121: Undefined variable: novar', v:exception)
+ finally
+ Xpath 'c'
+ call assert_equal("", v:errmsg)
+ break
+ endtry
+ endwhile
+
+ Xpath 'd'
+ let cmd = "let"
+ while cmd != ""
+ try
+ let v:errmsg = ""
+ call EXEC(cmd . ' novar #') " normal plus syntax error
+ catch /^Vim\((\a\+)\)\=:/
+ Xloop 'e'
+ call assert_match('E488: Trailing characters', v:exception)
+ finally
+ Xloop 'f'
+ call assert_equal("", v:errmsg)
+ if cmd == "let"
+ let cmd = "unlet"
+ else
+ let cmd = ""
+ endif
+ XloopNEXT
+ continue
+ endtry
+ endwhile
+
+ Xpath 'g'
+ let cmd = "let"
+ while cmd != ""
+ try
+ let v:errmsg = ""
+ call EXEC(cmd . ' {novar}') " normal plus syntax error
+ catch /^Vim\((\a\+)\)\=:/
+ Xloop 'h'
+ call assert_match('E475: Invalid argument: {novar}', v:exception)
+ finally
+ Xloop 'i'
+ call assert_equal("", v:errmsg)
+ if cmd == "let"
+ let cmd = "unlet"
+ else
+ let cmd = ""
+ endif
+ XloopNEXT
+ continue
+ endtry
+ endwhile
+ catch /.*/
+ call assert_report('should not get here')
+ endtry
+ Xpath 'j'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('bcde1f1e2f2gh3i3h4i4j', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+func Test_if_syntax_error()
+ CheckEnglish
+
+ let test =<< trim [CODE]
+ let v:errmsg = ""
+ if 0
+ else
+ elseif 1 ||| 2
+ endif
+ Xpath 'a'
+ call assert_match('E584: :elseif after :else', v:errmsg)
+
+ let v:errmsg = ""
+ if 1
+ else
+ elseif 1 ||| 2
+ endif
+ Xpath 'b'
+ call assert_match('E584: :elseif after :else', v:errmsg)
+
+ let v:errmsg = ""
+ elseif 1 ||| 2
+ Xpath 'c'
+ call assert_match('E582: :elseif without :if', v:errmsg)
+
+ let v:errmsg = ""
+ while 1
+ elseif 1 ||| 2
+ endwhile
+ Xpath 'd'
+ call assert_match('E582: :elseif without :if', v:errmsg)
+
+ while 1
+ try
+ try
+ let v:errmsg = ""
+ if 0
+ else
+ elseif 1 ||| 2
+ endif
+ catch /^Vim\((\a\+)\)\=:/
+ Xpath 'e'
+ call assert_match('E584: :elseif after :else', v:exception)
+ finally
+ Xpath 'f'
+ call assert_equal("", v:errmsg)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'g'
+ break
+ endtry
+ endwhile
+
+ while 1
+ try
+ try
+ let v:errmsg = ""
+ if 1
+ else
+ elseif 1 ||| 2
+ endif
+ catch /^Vim\((\a\+)\)\=:/
+ Xpath 'h'
+ call assert_match('E584: :elseif after :else', v:exception)
+ finally
+ Xpath 'i'
+ call assert_equal("", v:errmsg)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'j'
+ break
+ endtry
+ endwhile
+
+ while 1
+ try
+ try
+ let v:errmsg = ""
+ elseif 1 ||| 2
+ catch /^Vim\((\a\+)\)\=:/
+ Xpath 'k'
+ call assert_match('E582: :elseif without :if', v:exception)
+ finally
+ Xpath 'l'
+ call assert_equal("", v:errmsg)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'm'
+ break
+ endtry
+ endwhile
+
+ while 1
+ try
+ try
+ let v:errmsg = ""
+ while 1
+ elseif 1 ||| 2
+ endwhile
+ catch /^Vim\((\a\+)\)\=:/
+ Xpath 'n'
+ call assert_match('E582: :elseif without :if', v:exception)
+ finally
+ Xpath 'o'
+ call assert_equal("", v:errmsg)
+ endtry
+ catch /.*/
+ call assert_report('should not get here')
+ finally
+ Xpath 'p'
+ break
+ endtry
+ endwhile
+ Xpath 'q'
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('abcdefghijklmnopq', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+"-------------------------------------------------------------------------------
+" 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.
+"-------------------------------------------------------------------------------
+
+func Test_discard_exception_after_error_1()
+ let test =<< trim [CODE]
+ try
+ Xpath 'a'
+ try
+ Xpath 'b'
+ throw "arrgh"
+ call assert_report('should not get here')
+ if 1
+ call assert_report('should not get here')
+ " error after :throw: missing :endif
+ endtry
+ call assert_report('should not get here')
+ catch /arrgh/
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('ab', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
+" TODO: Not able inject an interrupt after throwing an exception
+func Disable_Test_discard_exception_after_error_2()
+ let test =<< trim [CODE]
+ try
+ Xpath 'a'
+ try
+ Xpath 'b'
+ throw "arrgh"
+ call interrupt() " FIXME: throw is not interrupted here
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ catch /arrgh/
+ call assert_report('should not get here')
+ endtry
+ call assert_report('should not get here')
+ [CODE]
+ let verify =<< trim [CODE]
+ call assert_equal('ab', g:Xpath)
+ [CODE]
+ call RunInNewVim(test, verify)
+endfunc
+
"-------------------------------------------------------------------------------
" Test 87 using (expr) ? funcref : funcref {{{1
"
@@ -1810,6 +6608,7 @@ func Test_float_conversion_errors()
endif
endfunc
+" invalid function names {{{1
func Test_invalid_function_names()
" function name not starting with capital
let caught_e128 = 0
@@ -1870,7 +6669,7 @@ func Test_invalid_function_names()
call delete('Xscript')
endfunc
-" substring and variable name
+" substring and variable name {{{1
func Test_substring_var()
let str = 'abcdef'
let n = 3
@@ -1890,6 +6689,20 @@ func Test_substring_var()
unlet b:nn
endfunc
+" Test using s: with a typed command {{{1
+func Test_typed_script_var()
+ CheckRunVimInTerminal
+
+ let buf = RunVimInTerminal('', {'rows': 6})
+
+ " Deep nesting of if ... endif
+ call term_sendkeys(buf, ":echo get(s:, 'foo', 'x')\n")
+ call TermWait(buf)
+ call WaitForAssert({-> assert_match('^E116:', term_getline(buf, 5))})
+
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_for_over_string()
let res = ''
for c in 'aéc̀d'
diff --git a/test/functional/legacy/vimscript_spec.lua b/test/functional/legacy/vimscript_spec.lua
new file mode 100644
index 0000000000..f59a87f824
--- /dev/null
+++ b/test/functional/legacy/vimscript_spec.lua
@@ -0,0 +1,90 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local clear = helpers.clear
+local exec = helpers.exec
+local feed = helpers.feed
+local meths = helpers.meths
+
+before_each(clear)
+
+describe('Vim script', function()
+ -- oldtest: Test_deep_nest()
+ it('Error when if/for/while/try/function is nested too deep',function()
+ local screen = Screen.new(80, 24)
+ screen:attach()
+ meths.set_option('laststatus', 2)
+ exec([[
+ " Deep nesting of if ... endif
+ func Test1()
+ let @a = join(repeat(['if v:true'], 51), "\n")
+ let @a ..= "\n"
+ let @a ..= join(repeat(['endif'], 51), "\n")
+ @a
+ let @a = ''
+ endfunc
+
+ " Deep nesting of for ... endfor
+ func Test2()
+ let @a = join(repeat(['for i in [1]'], 51), "\n")
+ let @a ..= "\n"
+ let @a ..= join(repeat(['endfor'], 51), "\n")
+ @a
+ let @a = ''
+ endfunc
+
+ " Deep nesting of while ... endwhile
+ func Test3()
+ let @a = join(repeat(['while v:true'], 51), "\n")
+ let @a ..= "\n"
+ let @a ..= join(repeat(['endwhile'], 51), "\n")
+ @a
+ let @a = ''
+ endfunc
+
+ " Deep nesting of try ... endtry
+ func Test4()
+ let @a = join(repeat(['try'], 51), "\n")
+ let @a ..= "\necho v:true\n"
+ let @a ..= join(repeat(['endtry'], 51), "\n")
+ @a
+ let @a = ''
+ endfunc
+
+ " Deep nesting of function ... endfunction
+ func Test5()
+ let @a = join(repeat(['function X()'], 51), "\n")
+ let @a ..= "\necho v:true\n"
+ let @a ..= join(repeat(['endfunction'], 51), "\n")
+ @a
+ let @a = ''
+ endfunc
+ ]])
+ screen:expect({any = '%[No Name%]'})
+ feed(':call Test1()<CR>')
+ screen:expect({any = 'E579: '})
+ feed('<C-C>')
+ screen:expect({any = '%[No Name%]'})
+ feed(':call Test2()<CR>')
+ screen:expect({any = 'E585: '})
+ feed('<C-C>')
+ screen:expect({any = '%[No Name%]'})
+ feed(':call Test3()<CR>')
+ screen:expect({any = 'E585: '})
+ feed('<C-C>')
+ screen:expect({any = '%[No Name%]'})
+ feed(':call Test4()<CR>')
+ screen:expect({any = 'E601: '})
+ feed('<C-C>')
+ screen:expect({any = '%[No Name%]'})
+ feed(':call Test5()<CR>')
+ screen:expect({any = 'E1058: '})
+ end)
+
+ -- oldtest: Test_typed_script_var()
+ it('using s: with a typed command', function()
+ local screen = Screen.new(80, 24)
+ screen:attach()
+ feed(":echo get(s:, 'foo', 'x')\n")
+ screen:expect({any = 'E116: '})
+ end)
+end)
diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua
index 64a3cf5471..9b0ace0882 100644
--- a/test/functional/vimscript/eval_spec.lua
+++ b/test/functional/vimscript/eval_spec.lua
@@ -16,7 +16,6 @@ local lfs = require('lfs')
local clear = helpers.clear
local eq = helpers.eq
local exc_exec = helpers.exc_exec
-local exec = helpers.exec
local exec_lua = helpers.exec_lua
local exec_capture = helpers.exec_capture
local eval = helpers.eval
@@ -152,79 +151,6 @@ describe('List support code', function()
end)
end)
--- oldtest: Test_deep_nest()
-it('Error when if/for/while/try/function is nested too deep',function()
- clear()
- local screen = Screen.new(80, 24)
- screen:attach()
- meths.set_option('laststatus', 2)
- exec([[
- " Deep nesting of if ... endif
- func Test1()
- let @a = join(repeat(['if v:true'], 51), "\n")
- let @a ..= "\n"
- let @a ..= join(repeat(['endif'], 51), "\n")
- @a
- let @a = ''
- endfunc
-
- " Deep nesting of for ... endfor
- func Test2()
- let @a = join(repeat(['for i in [1]'], 51), "\n")
- let @a ..= "\n"
- let @a ..= join(repeat(['endfor'], 51), "\n")
- @a
- let @a = ''
- endfunc
-
- " Deep nesting of while ... endwhile
- func Test3()
- let @a = join(repeat(['while v:true'], 51), "\n")
- let @a ..= "\n"
- let @a ..= join(repeat(['endwhile'], 51), "\n")
- @a
- let @a = ''
- endfunc
-
- " Deep nesting of try ... endtry
- func Test4()
- let @a = join(repeat(['try'], 51), "\n")
- let @a ..= "\necho v:true\n"
- let @a ..= join(repeat(['endtry'], 51), "\n")
- @a
- let @a = ''
- endfunc
-
- " Deep nesting of function ... endfunction
- func Test5()
- let @a = join(repeat(['function X()'], 51), "\n")
- let @a ..= "\necho v:true\n"
- let @a ..= join(repeat(['endfunction'], 51), "\n")
- @a
- let @a = ''
- endfunc
- ]])
- screen:expect({any = '%[No Name%]'})
- feed(':call Test1()<CR>')
- screen:expect({any = 'E579: '})
- feed('<C-C>')
- screen:expect({any = '%[No Name%]'})
- feed(':call Test2()<CR>')
- screen:expect({any = 'E585: '})
- feed('<C-C>')
- screen:expect({any = '%[No Name%]'})
- feed(':call Test3()<CR>')
- screen:expect({any = 'E585: '})
- feed('<C-C>')
- screen:expect({any = '%[No Name%]'})
- feed(':call Test4()<CR>')
- screen:expect({any = 'E601: '})
- feed('<C-C>')
- screen:expect({any = '%[No Name%]'})
- feed(':call Test5()<CR>')
- screen:expect({any = 'E1058: '})
-end)
-
describe("uncaught exception", function()
before_each(clear)
after_each(function()