From aed5a53d5f4188e54facf2ccd34dc12961c13b36 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Wed, 21 Oct 2020 00:02:31 -0400 Subject: test/old: cherry-pick patch 8.1.0711 changes for test_trycatch.vim --- src/nvim/testdir/test_system.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/testdir/test_system.vim b/src/nvim/testdir/test_system.vim index 424cb4abd0..9cf8690d57 100644 --- a/src/nvim/testdir/test_system.vim +++ b/src/nvim/testdir/test_system.vim @@ -3,7 +3,7 @@ source shared.vim source check.vim -function! Test_System() +func Test_System() if !executable('echo') || !executable('cat') || !executable('wc') return endif -- cgit From cb8e0d07b3d947251775eb8f96d14af8c1295f9e Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Wed, 21 Oct 2020 00:03:36 -0400 Subject: test/old: cherry-pick patch v8.1.1955 changes for test_trycatch.vim --- src/nvim/testdir/runtest.vim | 2 +- src/nvim/testdir/test49.vim | 2 +- src/nvim/testdir/test_const.vim | 2 +- src/nvim/testdir/test_quickfix.vim | 2 +- src/nvim/testdir/test_search.vim | 2 +- src/nvim/testdir/test_tabpage.vim | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim index b02514143c..275edece1e 100644 --- a/src/nvim/testdir/runtest.vim +++ b/src/nvim/testdir/runtest.vim @@ -414,7 +414,7 @@ for s:test in sort(s:tests) " Repeat a flaky test. Give up when: " - it fails again with the same message - " - it fails five times (with a different mesage) + " - it fails five times (with a different message) if len(v:errors) > 0 \ && (index(s:flaky_tests, s:test) >= 0 \ || v:errors[0] =~ s:flaky_errors_re) diff --git a/src/nvim/testdir/test49.vim b/src/nvim/testdir/test49.vim index 5468f7c4aa..3322d25cd8 100644 --- a/src/nvim/testdir/test49.vim +++ b/src/nvim/testdir/test49.vim @@ -521,7 +521,7 @@ endfunction " " Create a script that consists of the body of the function a:funcname. " Replace any ":return" by a ":finish", any argument variable by a global -" variable, and and every ":call" by a ":source" for the next following argument +" 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. diff --git a/src/nvim/testdir/test_const.vim b/src/nvim/testdir/test_const.vim index fc7ea71f6e..ea69c8cba4 100644 --- a/src/nvim/testdir/test_const.vim +++ b/src/nvim/testdir/test_const.vim @@ -109,7 +109,7 @@ func Test_define_script_var_with_lock() unlet s:x endfunc -func Test_descructuring_with_lock() +func Test_destructuring_with_lock() const [a, b, c] = [1, 1.1, 'vim'] call assert_fails('let a = 1', 'E741:') diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index e06c4f59da..5323b1acf3 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -1744,7 +1744,7 @@ func Test_switchbuf() call assert_equal(1, bufwinnr('Xqftestfile3')) " If only quickfix window is open in the current tabpage, jumping to an - " entry with 'switchubf' set to 'usetab' should search in other tabpages. + " entry with 'switchbuf' set to 'usetab' should search in other tabpages. enew | only set switchbuf=usetab tabedit Xqftestfile1 diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim index 8d71ada551..0703a6b141 100644 --- a/src/nvim/testdir/test_search.vim +++ b/src/nvim/testdir/test_search.vim @@ -270,7 +270,7 @@ func Test_search_cmdline2() " nor "/foo\\" works to delete the commandline. " In that case Vim should return "E35 no previous regular expression", " but it looks like Vim still sees /foo and therefore the test fails. - " Therefore, disableing this test + " Therefore, disabling this test "call assert_fails(feedkeys("/foo\\", 'tx'), 'E35') "call assert_equal({'lnum': 1, 'leftcol': 0, 'col': 0, 'topfill': 0, 'topline': 1, 'coladd': 0, 'skipcol': 0, 'curswant': 0}, winsaveview()) diff --git a/src/nvim/testdir/test_tabpage.vim b/src/nvim/testdir/test_tabpage.vim index 55dff3d476..bc7c69d920 100644 --- a/src/nvim/testdir/test_tabpage.vim +++ b/src/nvim/testdir/test_tabpage.vim @@ -58,7 +58,7 @@ function Test_tabpage() q " " - " Test for ":tab drop multi-opend-file" to keep current tabpage and window. + " Test for ":tab drop multi-opened-file" to keep current tabpage and window. new test1 tabnew new test1 -- cgit From da5c547ee3fa590159a82461bc0cd108d9e0ab3b Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Wed, 21 Oct 2020 00:04:27 -0400 Subject: vim-patch:8.1.2246: some tests are still in old style Problem: Some tests are still in old style. Solution: Change a few tests to new style. (Yegappan Lakshmanan) https://github.com/vim/vim/commit/1f068233c101ecf5966e6df14853fe68f08175a7 --- src/nvim/testdir/test49.ok | 28 - src/nvim/testdir/test49.vim | 6904 ++++++++++++----------------------- src/nvim/testdir/test_trycatch.vim | 1977 ++++++++++ src/nvim/testdir/test_vimscript.vim | 198 +- 4 files changed, 4483 insertions(+), 4624 deletions(-) create mode 100644 src/nvim/testdir/test_trycatch.vim (limited to 'src') diff --git a/src/nvim/testdir/test49.ok b/src/nvim/testdir/test49.ok index 50fc5d2cef..9f283e808b 100644 --- a/src/nvim/testdir/test49.ok +++ b/src/nvim/testdir/test49.ok @@ -1,6 +1,4 @@ Results of test49.vim: -*** Test 16: OK (8722) -*** Test 17: OK (285127993) *** Test 18: OK (67224583) *** Test 19: OK (69275973) *** Test 20: OK (1874575085) @@ -8,16 +6,11 @@ Results of test49.vim: *** Test 22: OK (4161) *** Test 23: OK (49) *** Test 24: OK (41) -*** Test 25: OK (260177811) -*** Test 26: OK (1681500476) *** Test 27: OK (1996459) *** Test 28: OK (1996459) *** Test 29: OK (170428555) *** Test 30: OK (190905173) *** Test 31: OK (190905173) -*** Test 32: OK (354833067) ---- Test 33: sum = 178275600 (ok) -*** Test 33: OK (1216907538) *** Test 34: OK (2146584868) *** Test 35: OK (2146584868) *** Test 36: OK (1071644672) @@ -25,17 +18,8 @@ Results of test49.vim: *** Test 38: OK (357908480) *** Test 39: OK (357908480) *** Test 40: OK (357908480) -*** Test 41: OK (3076095) -*** Test 42: OK (1505155949) -*** Test 43: OK (1157763329) -*** Test 44: OK (1031761407) -*** Test 45: OK (1157763329) -*** Test 46: OK (739407) -*** Test 47: OK (371213935) -*** Test 48: OK (756255461) *** Test 49: OK (179000669) *** Test 50: OK (363550045) -*** Test 51: OK (40744667) *** Test 52: OK (1247112011) *** Test 53: OK (131071) *** Test 54: OK (2047) @@ -53,13 +37,6 @@ Results of test49.vim: *** Test 66: OK (5464) *** Test 67: OK (212514423) *** Test 68: OK (212514423) -*** Test 69: OK (8995471) -*** Test 70: OK (69544277) -*** Test 71: OK (34886997) -*** Test 72: OK (1789569365) -*** Test 73: OK (9032615) -*** Test 74: OK (224907669) -*** Test 75: OK (2000403408) *** Test 76: OK (1610087935) *** Test 77: OK (1388671) *** Test 78: OK (134217728) @@ -72,11 +49,6 @@ Results of test49.vim: *** Test 85: OK (198689) --- Test 86: No Crash for vimgrep on BufUnload *** Test 86: OK (0) ---- Test 87: 3 ---- Test 87: 5 ---- Test 87: abcdefghijk ---- Test 87: Successfully executed funcref Add2 -*** Test 87: OK (0) --- Test 88: All tests were run with throwing exceptions on error. The $VIMNOERRTHROW control is not configured. --- Test 88: All tests were run with throwing exceptions on interrupt. diff --git a/src/nvim/testdir/test49.vim b/src/nvim/testdir/test49.vim index 3322d25cd8..3ee5e9ff7c 100644 --- a/src/nvim/testdir/test49.vim +++ b/src/nvim/testdir/test49.vim @@ -1,6 +1,6 @@ " Vim script language tests " Author: Servatius Brandt -" Last Change: 2019 Oct 08 +" Last Change: 2019 Nov 03 "------------------------------------------------------------------------------- " Test environment {{{1 @@ -608,196 +608,8 @@ com! -nargs=1 -bar ExecAsScript call ExecAsScript() " END_OF_TEST_ENVIRONMENT - do not change or remove this line. -" Tests 1 to 15 were moved to test_vimscript.vim -let Xtest = 16 - -"------------------------------------------------------------------------------- -" Test 16: Double :else or :elseif after :else {{{1 -" -" Multiple :elses or an :elseif after an :else are forbidden. -"------------------------------------------------------------------------------- - -XpathINIT - -function! F() abort - if 0 - Xpath 1 " X: 0 - else - Xpath 2 " X: 2 - else " aborts function - Xpath 4 " X: 0 - endif -endfunction - -function! G() abort - if 0 - Xpath 8 " X: 0 - else - Xpath 16 " X: 16 - elseif 1 " aborts function - Xpath 32 " X: 0 - else - Xpath 64 " X: 0 - endif -endfunction - -function! H() abort - if 0 - Xpath 128 " X: 0 - elseif 0 - Xpath 256 " X: 0 - else - Xpath 512 " X: 512 - else " aborts function - Xpath 1024 " X: 0 - endif -endfunction - -function! I() abort - if 0 - Xpath 2048 " X: 0 - elseif 0 - Xpath 4096 " X: 0 - else - Xpath 8192 " X: 8192 - elseif 1 " aborts function - Xpath 16384 " X: 0 - else - Xpath 32768 " X: 0 - endif -endfunction - -call F() -call G() -call H() -call I() - -delfunction F -delfunction G -delfunction H -delfunction I - -Xcheck 8722 - - -"------------------------------------------------------------------------------- -" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1 -" -" The :while/:endwhile takes precedence in nesting over an unclosed -" :if or an unopened :endif. -"------------------------------------------------------------------------------- - -XpathINIT - -function! MSG(enr, emsg) - let english = v:lang == "C" || v:lang =~ '^[Ee]n' - if a:enr == "" - Xout "TODO: Add message number for:" a:emsg - let v:errmsg = ":" . v:errmsg - endif - let match = 1 - if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) - let match = 0 - if v:errmsg == "" - Xout "Message missing." - else - let v:errmsg = escape(v:errmsg, '"') - Xout "Unexpected message:" v:errmsg - endif - endif - return match -endfunction - -let messages = "" - -" While loops inside a function are continued on error. -function! F() - let v:errmsg = "" - XloopINIT 1 16 - let loops = 3 - while loops > 0 - let loops = loops - 1 " 2: 1: 0: - Xloop 1 " X: 1 + 1*16 + 1*16*16 - if (loops == 1) - Xloop 2 " X: 2*16 - XloopNEXT - continue - elseif (loops == 0) - Xloop 4 " X: 4*16*16 - break - elseif 1 - Xloop 8 " X: 8 - XloopNEXT - " endif missing! - endwhile " :endwhile after :if 1 - Xpath 4096 " X: 16*16*16 - if MSG('E171', "Missing :endif") - let g:messages = g:messages . "A" - endif - - let v:errmsg = "" - XloopINIT! 8192 4 - let loops = 2 - while loops > 0 " 2: 1: - XloopNEXT - let loops = loops - 1 - Xloop 1 " X: 8192 + 8192*4 - if 0 - Xloop 2 " X: 0 - " endif missing - endwhile " :endwhile after :if 0 - Xpath 131072 " X: 8192*4*4 - if MSG('E171', "Missing :endif") - let g:messages = g:messages . "B" - endif - - let v:errmsg = "" - XloopINIT 262144 4 - let loops = 2 - while loops > 0 " 2: 1: - let loops = loops - 1 - Xloop 1 " X: 262144 + 262144 * 4 - " if missing! - endif " :endif without :if in while - Xloop 2 " X: 524288 + 524288 * 4 - XloopNEXT - endwhile - Xpath 4194304 " X: 262144*4*4 - if MSG('E580', ":endif without :if") - let g:messages = g:messages . "C" - endif -endfunction - -call F() - -" Error continuation outside a function is at the outermost :endwhile or :endif. -let v:errmsg = "" -XloopINIT! 8388608 4 -let loops = 2 -while loops > 0 " 2: 1: - XloopNEXT - let loops = loops - 1 - Xloop 1 " X: 8388608 + 0 * 4 - if 0 - Xloop 2 " X: 0 - " endif missing! Following :endwhile fails. -endwhile | Xpath 134217728 " X: 0 -Xpath 268435456 " X: 2*8388608*4*4 -if MSG('E171', "Missing :endif") - let messages = g:messages . "D" -endif - -if messages != "ABCD" - Xpath 536870912 " X: 0 - Xout "messages is" messages "instead of ABCD" -endif - -unlet loops messages -delfunction F -delfunction MSG - -Xcheck 285127993 - +" Tests 1 to 17 were moved to test_vimscript.vim +let Xtest = 18 "------------------------------------------------------------------------------- " Test 18: Interrupt (Ctrl-C pressed) {{{1 @@ -1313,140 +1125,8 @@ endif Xcheck 41 - -"------------------------------------------------------------------------------- -" Test 25: Executing :finally clauses on normal control flow {{{1 -" -" Control flow in a :try conditional should always fall through to its -" :finally clause. A :finally clause of a :try conditional inside an -" inactive conditional should never be executed. -"------------------------------------------------------------------------------- - -XpathINIT - -function! F() - let loops = 3 - XloopINIT 1 256 - while loops > 0 " 3: 2: 1: - Xloop 1 " X: 1 + 1*256 + 1*256*256 - if loops >= 2 - try - Xloop 2 " X: 2 + 2*256 - if loops == 2 - try - Xloop 4 " X: 4*256 - finally - Xloop 8 " X: 8*256 - endtry - endif - finally - Xloop 16 " X: 16 + 16*256 - if loops == 2 - try - Xloop 32 " X: 32*256 - finally - Xloop 64 " X: 64*256 - endtry - endif - endtry - endif - Xloop 128 " X: 128 + 128*256 + 128*256*256 - let loops = loops - 1 - XloopNEXT - endwhile - Xpath 16777216 " X: 16777216 -endfunction - -if 1 - try - Xpath 33554432 " X: 33554432 - call F() - Xpath 67108864 " X: 67108864 - finally - Xpath 134217728 " X: 134217728 - endtry -else - try - Xpath 268435456 " X: 0 - finally - Xpath 536870912 " X: 0 - endtry -endif - -delfunction F - -Xcheck 260177811 - - -"------------------------------------------------------------------------------- -" Test 26: Executing :finally clauses after :continue or :break {{{1 -" -" For a :continue or :break dynamically enclosed in a :try/:endtry -" region inside the next surrounding :while/:endwhile, if the -" :continue/:break is before the :finally, the :finally clause is -" executed first. If the :continue/:break is after the :finally, the -" :finally clause is broken (like an :if/:endif region). -"------------------------------------------------------------------------------- - -XpathINIT - -try - let loops = 3 - XloopINIT! 1 32 - while loops > 0 - XloopNEXT - try - try - if loops == 2 " 3: 2: 1: - Xloop 1 " X: 1*32 - let loops = loops - 1 - continue - elseif loops == 1 - Xloop 2 " X: 2*32*32 - break - finish - endif - Xloop 4 " X: 4 - endtry - finally - Xloop 8 " X: 8 + 8*32 + 8*32*32 - endtry - Xloop 16 " X: 16 - let loops = loops - 1 - endwhile - Xpath 32768 " X: 32768 -finally - Xpath 65536 " X: 65536 - let loops = 3 - XloopINIT 131072 16 - while loops > 0 - try - finally - try - if loops == 2 - Xloop 1 " X: 131072*16 - let loops = loops - 1 - XloopNEXT - continue - elseif loops == 1 - Xloop 2 " X: 131072*2*16*16 - break - finish - endif - endtry - Xloop 4 " X: 131072*4 - endtry - Xloop 8 " X: 131072*8 - let loops = loops - 1 - XloopNEXT - endwhile - Xpath 536870912 " X: 536870912 -endtry -Xpath 1073741824 " X: 1073741824 - -unlet loops - -Xcheck 1681500476 +" Tests 25 and 26 were moved to test_trycatch.vim +let Xtest = 27 "------------------------------------------------------------------------------- @@ -1783,322 +1463,78 @@ endif Xcheck 190905173 +" Tests 32 and 33 were moved to test_trycatch.vim +let Xtest = 34 + "------------------------------------------------------------------------------- -" Test 32: Remembering the :return value on :finally {{{1 +" Test 34: :finally reason discarded by :continue {{{1 " -" If a :finally clause is executed due to a :return specifying -" a value, this is the value visible to the caller if not overwritten -" by a new :return in the :finally clause. A :return without a value -" in the :finally clause overwrites with value 0. +" 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 -function! F() +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 - Xpath 1 " X: 1 + call C("error") + Xpath 33554432 " X: 33554432 + finally + Xpath 67108864 " X: 67108864 try - Xpath 2 " X: 2 - return "ABCD" - Xpath 4 " X: 0 + call C("interrupt") + Xpath 134217728 " X: 134217728 finally - Xpath 8 " X: 8 - endtry - Xpath 16 " X: 0 - finally - Xpath 32 " X: 32 - endtry - Xpath 64 " X: 0 -endfunction - -function! G() - try - Xpath 128 " X: 128 - return 8 - Xpath 256 " X: 0 - finally - Xpath 512 " X: 512 - return 16 + strlen(F()) - Xpath 1024 " X: 0 - endtry - Xpath 2048 " X: 0 -endfunction - -function! H() - try - Xpath 4096 " X: 4096 - return 32 - Xpath 8192 " X: 0 - finally - Xpath 16384 " X: 16384 - return - Xpath 32768 " X: 0 - endtry - Xpath 65536 " X: 0 -endfunction - -function! I() - try - Xpath 131072 " X: 131072 - finally - Xpath 262144 " X: 262144 - return G() + H() + 64 - Xpath 524288 " X: 0 - endtry - Xpath 1048576 " X: 0 -endfunction - -let retcode = I() -Xpath 2097152 " X: 2097152 - -if retcode < 0 - Xpath 4194304 " X: 0 -endif -if retcode % 4 - Xpath 8388608 " X: 0 -endif -if (retcode/4) % 2 - Xpath 16777216 " X: 16777216 -endif -if (retcode/8) % 2 - Xpath 33554432 " X: 0 -endif -if (retcode/16) % 2 - Xpath 67108864 " X: 67108864 -endif -if (retcode/32) % 2 - Xpath 134217728 " X: 0 -endif -if (retcode/64) % 2 - Xpath 268435456 " X: 268435456 -endif -if retcode/128 - Xpath 536870912 " X: 0 -endif - -unlet retcode -delfunction F -delfunction G -delfunction H -delfunction I - -Xcheck 354833067 - - -"------------------------------------------------------------------------------- -" Test 33: :return under :execute or user command and :finally {{{1 -" -" A :return command may be executed under an ":execute" or from -" a user command. Executing of :finally clauses and passing through -" the return code works also then. -"------------------------------------------------------------------------------- -XpathINIT - -command! -nargs=? RETURN - \ try | return | finally | return * 2 | endtry - -function! F() - try - RETURN 8 - Xpath 1 " X: 0 - finally - Xpath 2 " X: 2 - endtry - Xpath 4 " X: 0 -endfunction - -function! G() - try - RETURN 32 - Xpath 8 " X: 0 - finally - Xpath 16 " X: 16 - RETURN 128 - Xpath 32 " X: 0 - endtry - Xpath 64 " X: 0 -endfunction - -function! H() - try - execute "try | return 512 | finally | return 1024 | endtry" - Xpath 128 " X: 0 - finally - Xpath 256 " X: 256 - endtry - Xpath 512 " X: 0 -endfunction - -function! I() - try - execute "try | return 2048 | finally | return 4096 | endtry" - Xpath 1024 " X: 0 - finally - Xpath 2048 " X: 2048 - execute "try | return 8192 | finally | return 16384 | endtry" - Xpath 4096 " X: 0 - endtry - Xpath 8192 " X: 0 -endfunction - -function! J() - try - RETURN 32768 - Xpath 16384 " X: 0 - finally - Xpath 32768 " X: 32768 - return - Xpath 65536 " X: 0 - endtry - Xpath 131072 " X: 0 -endfunction - -function! K() - try - execute "try | return 131072 | finally | return 262144 | endtry" - Xpath 262144 " X: 0 - finally - Xpath 524288 " X: 524288 - execute "try | return 524288 | finally | return | endtry" - Xpath 1048576 " X: 0 - endtry - Xpath 2097152 " X: 0 -endfunction - -function! L() - try - return - Xpath 4194304 " X: 0 - finally - Xpath 8388608 " X: 8388608 - RETURN 1048576 - Xpath 16777216 " X: 0 - endtry - Xpath 33554432 " X: 0 -endfunction - -function! M() - try - return - Xpath 67108864 " X: 0 - finally - Xpath 134217728 " X: 134217728 - execute "try | return 4194304 | finally | return 8388608 | endtry" - Xpath 268435456 " X: 0 - endtry - Xpath 536870912 " X: 0 -endfunction - -function! N() - RETURN 16777216 -endfunction - -function! O() - execute "try | return 67108864 | finally | return 134217728 | endtry" -endfunction - -let sum = F() + G() + H() + I() + J() + K() + L() + M() -let expected = 16 + 256 + 1024 + 16384 + 0 + 0 + 2097152 + 8388608 -let sum = sum + N() + O() -let expected = expected + 33554432 + 134217728 - -if sum == expected - Xout "sum = " . sum . " (ok)" -else - Xout "sum = " . sum . ", expected: " . expected -endif - -Xpath 1073741824 " X: 1073741824 - -if sum != expected - " The Xpath command does not accept 2^31 (negative); add explicitly: - let Xpath = Xpath + 2147483648 " X: 0 -endif - -unlet sum expected -delfunction F -delfunction G -delfunction H -delfunction I -delfunction J -delfunction K -delfunction L -delfunction M -delfunction N -delfunction O - -Xcheck 1216907538 - - -"------------------------------------------------------------------------------- -" Test 34: :finally reason discarded by :continue {{{1 -" -" When a :finally clause is executed due to a :continue, :break, -" :return, :finish, error, interrupt or :throw, the jump reason is -" discarded by a :continue in the finally clause. -"------------------------------------------------------------------------------- - -XpathINIT - -if ExtraVim() - - XloopINIT! 1 8 - - function! C(jump) - XloopNEXT - let loop = 0 - while loop < 2 - let loop = loop + 1 - if loop == 1 - try - if a:jump == "continue" - continue - elseif a:jump == "break" - break - elseif a:jump == "return" || a:jump == "finish" - return - elseif a:jump == "error" - asdf - elseif a:jump == "interrupt" - "INTERRUPT - let dummy = 0 - elseif a:jump == "throw" - throw "abc" - endif - finally - continue " discards jump that caused the :finally - Xloop 1 " X: 0 - endtry - Xloop 2 " X: 0 - elseif loop == 2 - Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144) - endif - endwhile - endfunction - - call C("continue") - Xpath 2097152 " X: 2097152 - call C("break") - Xpath 4194304 " X: 4194304 - call C("return") - Xpath 8388608 " X: 8388608 - let g:jump = "finish" - ExecAsScript C - unlet g:jump - Xpath 16777216 " X: 16777216 - try - call C("error") - Xpath 33554432 " X: 33554432 - finally - Xpath 67108864 " X: 67108864 - try - call C("interrupt") - Xpath 134217728 " X: 134217728 - finally - Xpath 268435456 " X: 268435456 - call C("throw") - Xpath 536870912 " X: 536870912 + Xpath 268435456 " X: 268435456 + call C("throw") + Xpath 536870912 " X: 536870912 endtry endtry Xpath 1073741824 " X: 1073741824 @@ -2654,1041 +2090,834 @@ endif Xcheck 357908480 +" Tests 41 to 48 were moved to test_trycatch.vim +let Xtest = 49 + "------------------------------------------------------------------------------- -" Test 41: Skipped :throw finding next command {{{1 +" Test 49: Throwing exceptions across functions {{{1 " -" A :throw in an inactive conditional must not hide a following -" command. +" When an exception is thrown but not caught inside a function, the +" caller is checked for a matching :catch clause. "------------------------------------------------------------------------------- XpathINIT -function! F() - Xpath 1 " X: 1 - if 0 | throw "never" | endif | Xpath 2 " X: 2 - Xpath 4 " X: 4 -endfunction - -function! G() - Xpath 8 " X: 8 - while 0 | throw "never" | endwhile | Xpath 16 " X: 16 - Xpath 32 " X: 32 -endfunction - -function H() - Xpath 64 " X: 64 - if 0 | try | throw "never" | endtry | endif | Xpath 128 " X: 128 - Xpath 256 " X: 256 +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 -Xpath 512 " X: 512 +XloopINIT! 16 16 -try - Xpath 1024 " X: 1024 - call F() - Xpath 2048 " X: 2048 -catch /.*/ - Xpath 4096 " X: 0 - Xout v:exception "in" v:throwpoint -endtry +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 -Xpath 8192 " X: 8192 +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 16384 " X: 16384 - call G() - Xpath 32768 " X: 32768 + Xpath 65536 " X: 65536 + call C() " throw and catch + Xpath 131072 " X: 131072 catch /.*/ - Xpath 65536 " X: 0 + Xpath 262144 " X: 0 Xout v:exception "in" v:throwpoint endtry -Xpath 131072 " X: 131072 - try - Xpath 262144 " X: 262144 - call H() Xpath 524288 " X: 524288 -catch /.*/ + 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 -Xpath 2097152 " X: 2097152 +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 -delfunction F -delfunction G -delfunction H +Xcheck 179000669 -Xcheck 3076095 +" Leave C, T1, and T2 for execution as scripts in the next test. "------------------------------------------------------------------------------- -" Test 42: Catching number and string exceptions {{{1 +" 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. " -" When a number is thrown, it is converted to a string exception. -" Numbers and strings may be caught by specifying a regular exception -" as argument to the :catch command. +" This test executes the bodies of the functions C, T1, and T2 from +" the previous test as script files (:return replaced by :finish). "------------------------------------------------------------------------------- XpathINIT -try - - try - Xpath 1 " X: 1 - throw 4711 - Xpath 2 " X: 0 - catch /4711/ - Xpath 4 " X: 4 - endtry - - try - Xpath 8 " X: 8 - throw 4711 - Xpath 16 " X: 0 - catch /^4711$/ - Xpath 32 " X: 32 - endtry +let scriptC = MakeScript("C") " X: 1 + 4 + 8 +delfunction C - try - Xpath 64 " X: 64 - throw 4711 - Xpath 128 " X: 0 - catch /\d/ - Xpath 256 " X: 256 - endtry +XloopINIT! 16 16 - try - Xpath 512 " X: 512 - throw 4711 - Xpath 1024 " X: 0 - catch /^\d\+$/ - Xpath 2048 " X: 2048 - endtry +let scriptT1 = MakeScript("T1") " X: 16 + 64 + 16*16 + 64*16 +delfunction T1 - try - Xpath 4096 " X: 4096 - throw "arrgh" - Xpath 8192 " X: 0 - catch /arrgh/ - Xpath 16384 " X: 16384 - endtry +let scriptT2 = MakeScript("T2", scriptT1) " X: 4096 + 16384 +delfunction T2 +function! F() try - Xpath 32768 " X: 32768 - throw "arrgh" - Xpath 65536 " X: 0 - catch /^arrgh$/ + 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 262144 " X: 262144 - throw "arrgh" - Xpath 524288 " X: 0 - catch /\l/ - Xpath 1048576 " X: 1048576 - endtry - - try + Xpath 524288 " X: 524288 + exec "source" g:scriptT1 + Xpath 1048576 " X: 0 + catch /arrgh/ Xpath 2097152 " X: 2097152 - throw "arrgh" + catch /.*/ Xpath 4194304 " X: 0 - catch /^\l\+$/ - Xpath 8388608 " X: 8388608 - endtry - - try - try - Xpath 16777216 " X: 16777216 - throw "ARRGH" - Xpath 33554432 " X: 0 - catch /^arrgh$/ - Xpath 67108864 " X: 0 - endtry - catch /^\carrgh$/ - Xpath 134217728 " X: 134217728 - endtry - - try - Xpath 268435456 " X: 268435456 - throw "" - Xpath 536870912 " X: 0 - catch /^$/ - Xpath 1073741824 " X: 1073741824 + 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 /.*/ - " The Xpath command does not accept 2^31 (negative); add explicitly: - let Xpath = Xpath + 2147483648 " X: 0 + 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 -Xcheck 1505155949 +" Test 51 was moved to test_trycatch.vim +let Xtest = 52 "------------------------------------------------------------------------------- -" Test 43: Selecting the correct :catch clause {{{1 +" Test 52: Uncaught exceptions {{{1 " -" When an exception is thrown and there are multiple :catch clauses, -" the first matching one is taken. +" 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 -XloopINIT 1 1024 -let loops = 3 -while loops > 0 +let msgfile = tempname() + +function! MESSAGES(...) try - if loops == 3 - Xloop 1 " X: 1 - throw "a" - Xloop 2 " X: 0 - elseif loops == 2 - Xloop 4 " X: 4*1024 - throw "ab" - Xloop 8 " X: 0 - elseif loops == 1 - Xloop 16 " X: 16*1024*1024 - throw "abc" - Xloop 32 " X: 0 - endif - catch /abc/ - Xloop 64 " X: 64*1024*1024 - catch /ab/ - Xloop 128 " X: 128*1024 - catch /.*/ - Xloop 256 " X: 256 - catch /a/ - Xloop 512 " X: 0 + exec "edit" g:msgfile + catch /^Vim(edit):/ + return 0 endtry - let loops = loops - 1 - XloopNEXT -endwhile -Xpath 1073741824 " X: 1073741824 - -unlet loops + let english = v:lang == "C" || v:lang =~ '^[Ee]n' + let match = 1 + norm gg -Xcheck 1157763329 + let num = a:0 / 2 + let cnt = 1 + while cnt <= num + let enr = a:{2*cnt - 1} + let emsg= a:{2*cnt} + let cnt = cnt + 1 + if enr == "" + Xout "TODO: Add message number for:" emsg + elseif enr == "INT" + let enr = "" + endif + if enr == "" && !english + continue + endif + let pattern = (enr != "") ? enr . ':.*' : '' + if english + let pattern = pattern . emsg + endif + if !search(pattern, "W") + let match = 0 + Xout "No match for:" pattern + endif + norm $ + endwhile -"------------------------------------------------------------------------------- -" Test 44: Missing or empty :catch patterns {{{1 -" -" A missing or empty :catch pattern means the same as /.*/, that is, -" catches everything. To catch only empty exceptions, /^$/ must be -" used. A :catch with missing, empty, or /.*/ argument also works -" when followed by another command separated by a bar on the same -" line. :catch patterns cannot be specified between ||. But other -" pattern separators can be used instead of //. -"------------------------------------------------------------------------------- + bwipeout! + return match +endfunction -XpathINIT +if ExtraVim(msgfile) + Xpath 1 " X: 1 + throw "arrgh" +endif -try - try - Xpath 1 " X: 1 - throw "" - catch /^$/ - Xpath 2 " X: 2 - endtry +Xpath 2 " X: 2 +if !MESSAGES('E605', "Exception not caught") + Xpath 4 " X: 0 +endif +if ExtraVim(msgfile) try - Xpath 4 " X: 4 - throw "" - catch /.*/ Xpath 8 " X: 8 + throw "oops" + catch /arrgh/ + Xpath 16 " X: 0 endtry + Xpath 32 " X: 0 +endif - try - Xpath 16 " X: 16 - throw "" - catch // - Xpath 32 " X: 32 - endtry +Xpath 64 " X: 64 +if !MESSAGES('E605', "Exception not caught") + Xpath 128 " X: 0 +endif - try - Xpath 64 " X: 64 - throw "" - catch - Xpath 128 " X: 128 - endtry +if ExtraVim(msgfile) + function! T() + throw "brrr" + endfunction try Xpath 256 " X: 256 - throw "oops" - catch /^$/ - Xpath 512 " X: 0 + throw "arrgh" catch /.*/ - Xpath 1024 " X: 1024 + Xpath 512 " X: 512 + call T() endtry + Xpath 1024 " X: 0 +endif - try - Xpath 2048 " X: 2048 - throw "arrgh" - catch /^$/ - Xpath 4096 " X: 0 - catch // - Xpath 8192 " X: 8192 - endtry +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" - catch /^$/ - Xpath 32768 " X: 0 - catch - Xpath 65536 " X: 65536 endtry + Xpath 32768 " X: 0 +endif - try | Xpath 131072 | throw "x" | catch /.*/ | Xpath 262144 | endtry - " X: 131072 + 262144 +Xpath 65536 " X: 65536 +if !MESSAGES('E605', "Exception not caught") + Xpath 131072 " X: 0 +endif - try | Xpath 524288 | throw "y" | catch // | Xpath 1048576 | endtry - " X: 524288 + 1048576 +if ExtraVim(msgfile) + try + Xpath 262144 " X: 262144 + "INTERRUPT + endtry + Xpath 524288 " X: 0 +endif - while 1 - try - let caught = 0 - let v:errmsg = "" - " Extra try level: if ":catch" without arguments below raises - " a syntax error because it misinterprets the "Xpath" as a pattern, - " let it be caught by the ":catch /.*/" below. - try - try | Xpath 2097152 | throw "z" | catch | Xpath 4194304 | : - endtry " X: 2097152 + 4194304 - endtry - catch /.*/ - let caught = 1 - Xout v:exception "in" v:throwpoint - finally - if $VIMNOERRTHROW && v:errmsg != "" - Xout v:errmsg - endif - if caught || $VIMNOERRTHROW && v:errmsg != "" - Xpath 8388608 " X: 0 - endif - break " discard error for $VIMNOERRTHROW - endtry - endwhile +Xpath 1048576 " X: 1048576 +if !MESSAGES('INT', "Interrupted") + Xpath 2097152 " X: 0 +endif - let cologne = 4711 +if ExtraVim(msgfile) try - try - Xpath 16777216 " X: 16777216 - throw "throw cologne" - " Next lines catches all and throws 4711: - catch |throw cologne| - Xpath 33554432 " X: 0 - endtry - catch /4711/ - Xpath 67108864 " X: 67108864 + 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 - throw "plus" - catch +plus+ - Xpath 268435456 " X: 268435456 +" unlet novar # " error E108/E488; exception: E488 + catch /E108:/ " should not catch + Xpath 268435456 " X: 0 endtry + Xpath 536870912 " X: 0 +endif - Xpath 536870912 " X: 536870912 -catch /.*/ - Xpath 1073741824 " X: 0 - Xout v:exception "in" v:throwpoint -endtry +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 -unlet! caught cologne +Xcheck 1247112011 -Xcheck 1031761407 +" Leave MESSAGES() for the next tests. "------------------------------------------------------------------------------- -" Test 45: Catching exceptions from nested :try blocks {{{1 +" Test 53: Nesting errors: :endif/:else/:elseif {{{1 " -" When :try blocks are nested, an exception is caught by the innermost -" try conditional that has a matching :catch clause. +" 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 -XloopINIT 1 1024 -let loops = 3 -while loops > 0 - try - try - try - try - if loops == 3 - Xloop 1 " X: 1 - throw "a" - Xloop 2 " X: 0 - elseif loops == 2 - Xloop 4 " X: 4*1024 - throw "ab" - Xloop 8 " X: 0 - elseif loops == 1 - Xloop 16 " X: 16*1024*1024 - throw "abc" - Xloop 32 " X: 0 - endif - catch /abc/ - Xloop 64 " X: 64*1024*1024 - endtry - catch /ab/ - Xloop 128 " X: 128*1024 - endtry - catch /.*/ - Xloop 256 " X: 256 - endtry - catch /a/ - Xloop 512 " X: 0 - endtry - - let loops = loops - 1 - XloopNEXT -endwhile -Xpath 1073741824 " X: 1073741824 +let msgfile = tempname() -unlet loops +if ExtraVim(msgfile) +" endif +endif +if MESSAGES('E580', ":endif without :if") + Xpath 1 " X: 1 +endif -Xcheck 1157763329 +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 -"------------------------------------------------------------------------------- -" Test 46: Executing :finally after a :throw in nested :try {{{1 -" -" When an exception is thrown from within nested :try blocks, the -" :finally clauses of the non-catching try conditionals should be -" executed before the matching :catch of the next surrounding :try -" gets the control. If this also has a :finally clause, it is -" executed afterwards. -"------------------------------------------------------------------------------- +if ExtraVim(msgfile) +" try +" endif +" endtry +endif +if MESSAGES('E580', ":endif without :if") + Xpath 8 " X: 8 +endif -XpathINIT +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" endif +" endtry +endif +if MESSAGES('E580', ":endif without :if") + Xpath 16 " X: 16 +endif -let sum = 0 +if ExtraVim(msgfile) +" else +endif +if MESSAGES('E581', ":else without :if") + Xpath 32 " X: 32 +endif -try - Xpath 1 " X: 1 - try - Xpath 2 " X: 2 - try - Xpath 4 " X: 4 - try - Xpath 8 " X: 8 - throw "ABC" - Xpath 16 " X: 0 - catch /xyz/ - Xpath 32 " X: 0 - finally - Xpath 64 " X: 64 - if sum != 0 - Xpath 128 " X: 0 - endif - let sum = sum + 1 - endtry - Xpath 256 " X: 0 - catch /123/ - Xpath 512 " X: 0 - catch /321/ - Xpath 1024 " X: 0 - finally - Xpath 2048 " X: 2048 - if sum != 1 - Xpath 4096 " X: 0 - endif - let sum = sum + 2 - endtry - Xpath 8192 " X: 0 - finally - Xpath 16384 " X: 16384 - if sum != 3 - Xpath 32768 " X: 0 - endif - let sum = sum + 4 - endtry - Xpath 65536 " X: 0 -catch /ABC/ - Xpath 131072 " X: 131072 - if sum != 7 - Xpath 262144 " X: 0 - endif - let sum = sum + 8 -finally - Xpath 524288 " X: 524288 - if sum != 15 - Xpath 1048576 " X: 0 - endif - let sum = sum + 16 -endtry -Xpath 65536 " X: 65536 -if sum != 31 - Xpath 131072 " X: 0 +if ExtraVim(msgfile) +" while 1 +" else +" endwhile +endif +if MESSAGES('E581', ":else without :if") + Xpath 64 " X: 64 endif -unlet sum +if ExtraVim(msgfile) +" try +" finally +" else +" endtry +endif +if MESSAGES('E581', ":else without :if") + Xpath 128 " X: 128 +endif -Xcheck 739407 +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 -"------------------------------------------------------------------------------- -" Test 47: Throwing exceptions from a :catch clause {{{1 -" -" When an exception is thrown from a :catch clause, it should not be -" caught by a :catch of the same :try conditional. After executing -" the :finally clause (if present), surrounding try conditionals -" should be checked for a matching :catch. -"------------------------------------------------------------------------------- +if ExtraVim(msgfile) +" elseif +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 1024 " X: 1024 +endif -XpathINIT +if ExtraVim(msgfile) +" while 1 +" elseif +" endwhile +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 2048 " X: 2048 +endif -Xpath 1 " X: 1 -try - Xpath 2 " X: 2 - try - Xpath 4 " X: 4 - try - Xpath 8 " X: 8 - throw "x1" - Xpath 16 " X: 0 - catch /x1/ - Xpath 32 " X: 32 - try - Xpath 64 " X: 64 - throw "x2" - Xpath 128 " X: 0 - catch /x1/ - Xpath 256 " X: 0 - catch /x2/ - Xpath 512 " X: 512 - try - Xpath 1024 " X: 1024 - throw "x3" - Xpath 2048 " X: 0 - catch /x1/ - Xpath 4096 " X: 0 - catch /x2/ - Xpath 8192 " X: 0 - finally - Xpath 16384 " X: 16384 - endtry - Xpath 32768 " X: 0 - catch /x3/ - Xpath 65536 " X: 0 - endtry - Xpath 131072 " X: 0 - catch /x1/ - Xpath 262144 " X: 0 - catch /x2/ - Xpath 524288 " X: 0 - catch /x3/ - Xpath 1048576 " X: 0 - finally - Xpath 2097152 " X: 2097152 - endtry - Xpath 4194304 " X: 0 - catch /x1/ - Xpath 8388608 " X: 0 - catch /x2/ - Xpath 16777216 " X: 0 - catch /x3/ - Xpath 33554432 " X: 33554432 - endtry - Xpath 67108864 " X: 67108864 -catch /.*/ - Xpath 134217728 " X: 0 - Xout v:exception "in" v:throwpoint -endtry -Xpath 268435456 " X: 268435456 - -Xcheck 371213935 - - -"------------------------------------------------------------------------------- -" Test 48: Throwing exceptions from a :finally clause {{{1 -" -" When an exception is thrown from a :finally clause, it should not be -" caught by a :catch of the same :try conditional. Surrounding try -" conditionals should be checked for a matching :catch. A previously -" thrown exception is discarded. -"------------------------------------------------------------------------------- +if ExtraVim(msgfile) +" try +" finally +" elseif +" endtry +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 4096 " X: 4096 +endif -XpathINIT +if ExtraVim(msgfile) +" try +" elseif +" endtry +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 8192 " X: 8192 +endif -try +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" elseif +" endtry +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 16384 " X: 16384 +endif - try - try - Xpath 1 " X: 1 - catch /x1/ - Xpath 2 " X: 0 - finally - Xpath 4 " X: 4 - throw "x1" - Xpath 8 " X: 0 - endtry - Xpath 16 " X: 0 - catch /x1/ - Xpath 32 " X: 32 - endtry - Xpath 64 " X: 64 +if ExtraVim(msgfile) +" if 1 +" else +" else +" endif +endif +if MESSAGES('E583', "multiple :else") + Xpath 32768 " X: 32768 +endif - try - try - Xpath 128 " X: 128 - throw "x2" - Xpath 256 " X: 0 - catch /x2/ - Xpath 512 " X: 512 - catch /x3/ - Xpath 1024 " X: 0 - finally - Xpath 2048 " X: 2048 - throw "x3" - Xpath 4096 " X: 0 - endtry - Xpath 8192 " X: 0 - catch /x2/ - Xpath 16384 " X: 0 - catch /x3/ - Xpath 32768 " X: 32768 - endtry +if ExtraVim(msgfile) +" if 1 +" else +" elseif 1 +" endif +endif +if MESSAGES('E584', ":elseif after :else") Xpath 65536 " X: 65536 +endif - try - try - try - Xpath 131072 " X: 131072 - throw "x4" - Xpath 262144 " X: 0 - catch /x5/ - Xpath 524288 " X: 0 - finally - Xpath 1048576 " X: 1048576 - throw "x5" " discards "x4" - Xpath 2097152 " X: 0 - endtry - Xpath 4194304 " X: 0 - catch /x4/ - Xpath 8388608 " X: 0 - finally - Xpath 16777216 " X: 16777216 - endtry - Xpath 33554432 " X: 0 - catch /x5/ - Xpath 67108864 " X: 67108864 - endtry - Xpath 134217728 " X: 134217728 +call delete(msgfile) +unlet msgfile -catch /.*/ - Xpath 268435456 " X: 0 - Xout v:exception "in" v:throwpoint -endtry -Xpath 536870912 " X: 536870912 +Xcheck 131071 -Xcheck 756255461 +" Leave MESSAGES() for the next test. "------------------------------------------------------------------------------- -" Test 49: Throwing exceptions across functions {{{1 +" Test 54: Nesting errors: :while/:endwhile {{{1 " -" When an exception is thrown but not caught inside a function, the -" caller is checked for a matching :catch clause. +" 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 -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 +let msgfile = tempname() -function! T2() - try - Xpath 4096 " X: 4096 - call T1() - Xpath 8192 " X: 0 - finally - Xpath 16384 " X: 16384 - endtry - Xpath 32768 " X: 0 -endfunction +if ExtraVim(msgfile) +" endwhile +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 1 " X: 1 +endif -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 +if ExtraVim(msgfile) +" if 1 +" endwhile +" endif +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 2 " X: 2 +endif -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 +if ExtraVim(msgfile) +" while 1 +" if 1 +" endwhile +endif +if MESSAGES('E171', "Missing :endif") + Xpath 4 " X: 4 +endif -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 +if ExtraVim(msgfile) +" try +" finally +" endwhile +" endtry +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 8 " X: 8 +endif -Xcheck 179000669 +if ExtraVim(msgfile) +" while 1 +" try +" finally +" endwhile +endif +if MESSAGES('E600', "Missing :endtry") + Xpath 16 " X: 16 +endif -" Leave C, T1, and T2 for execution as scripts in the next test. +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 50: Throwing exceptions across script files {{{1 +" Test 55: Nesting errors: :continue/:break {{{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. +" For nesting errors of :continue and :break commands the correct +" error messages should be given. " -" This test executes the bodies of the functions C, T1, and T2 from -" the previous test as script files (:return replaced by :finish). +" This test reuses the function MESSAGES() from the previous test. +" This functions checks the messages in g:msgfile. "------------------------------------------------------------------------------- XpathINIT -let scriptC = MakeScript("C") " X: 1 + 4 + 8 -delfunction C +let msgfile = tempname() -XloopINIT! 16 16 +if ExtraVim(msgfile) +" continue +endif +if MESSAGES('E586', ":continue without :while") + Xpath 1 " X: 1 +endif -let scriptT1 = MakeScript("T1") " X: 16 + 64 + 16*16 + 64*16 -delfunction T1 +if ExtraVim(msgfile) +" if 1 +" continue +" endif +endif +if MESSAGES('E586', ":continue without :while") + Xpath 2 " X: 2 +endif -let scriptT2 = MakeScript("T2", scriptT1) " X: 4096 + 16384 -delfunction T2 +if ExtraVim(msgfile) +" try +" finally +" continue +" endtry +endif +if MESSAGES('E586', ":continue without :while") + Xpath 4 " X: 4 +endif -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 +if ExtraVim(msgfile) +" try +" continue +" endtry +endif +if MESSAGES('E586', ":continue without :while") + Xpath 8 " X: 8 +endif - 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 +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" continue +" endtry +endif +if MESSAGES('E586', ":continue without :while") + Xpath 16 " X: 16 +endif -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 +if ExtraVim(msgfile) +" break +endif +if MESSAGES('E587', ":break without :while") + Xpath 32 " X: 32 +endif -call delete(scriptC) -call delete(scriptT1) -call delete(scriptT2) -unlet scriptC scriptT1 scriptT2 -delfunction F +if ExtraVim(msgfile) +" if 1 +" break +" endif +endif +if MESSAGES('E587', ":break without :while") + Xpath 64 " X: 64 +endif -Xcheck 363550045 +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 51: Throwing exceptions across :execute and user commands {{{1 +" Test 56: Nesting errors: :endtry {{{1 +" +" For nesting errors of :try conditionals the correct error messages +" should be given. " -" A :throw command may be executed under an ":execute" or from -" a user command. +" This test reuses the function MESSAGES() from the previous test. +" This functions checks the messages in g:msgfile. "------------------------------------------------------------------------------- XpathINIT -command! -nargs=? THROW1 throw | throw 1 -command! -nargs=? THROW2 try | throw | endtry | throw 2 -command! -nargs=? THROW3 try | throw 3 | catch /3/ | throw | endtry -command! -nargs=? THROW4 try | throw 4 | finally | throw | endtry +let msgfile = tempname() -try +if ExtraVim(msgfile) +" endtry +endif +if MESSAGES('E602', ":endtry without :try") + Xpath 1 " X: 1 +endif - try - try - Xpath 1 " X: 1 - THROW1 "A" - catch /A/ - Xpath 2 " X: 2 - endtry - catch /1/ - Xpath 4 " X: 0 - endtry - - try - try - Xpath 8 " X: 8 - THROW2 "B" - catch /B/ - Xpath 16 " X: 16 - endtry - catch /2/ - Xpath 32 " X: 0 - endtry - - try - try - Xpath 64 " X: 64 - THROW3 "C" - catch /C/ - Xpath 128 " X: 128 - endtry - catch /3/ - Xpath 256 " X: 0 - endtry - - try - try - Xpath 512 " X: 512 - THROW4 "D" - catch /D/ - Xpath 1024 " X: 1024 - endtry - catch /4/ - Xpath 2048 " X: 0 - endtry - - try - try - Xpath 4096 " X: 4096 - execute 'throw "E" | throw 5' - catch /E/ - Xpath 8192 " X: 8192 - endtry - catch /5/ - Xpath 16384 " X: 0 - endtry - - try - try - Xpath 32768 " X: 32768 - execute 'try | throw "F" | endtry | throw 6' - catch /F/ - Xpath 65536 " X: 65536 - endtry - catch /6/ - Xpath 131072 " X: 0 - endtry - - try - try - Xpath 262144 " X: 262144 - execute'try | throw 7 | catch /7/ | throw "G" | endtry' - catch /G/ - Xpath 524288 " X: 524288 - endtry - catch /7/ - Xpath 1048576 " X: 0 - endtry - - try - try - Xpath 2097152 " X: 2097152 - execute 'try | throw 8 | finally | throw "H" | endtry' - catch /H/ - Xpath 4194304 " X: 4194304 - endtry - catch /8/ - Xpath 8388608 " X: 0 - endtry - -catch /.*/ - Xpath 16777216 " X: 0 - Xout v:exception "in" v:throwpoint -endtry - -Xpath 33554432 " X: 33554432 - -delcommand THROW1 -delcommand THROW2 -delcommand THROW3 -delcommand THROW4 - -Xcheck 40744667 - - -"------------------------------------------------------------------------------- -" Test 52: Uncaught exceptions {{{1 -" -" When an exception is thrown but not caught, an error message is -" displayed when the script is terminated. In case of an interrupt -" or error exception, the normal interrupt or error message(s) are -" displayed. -"------------------------------------------------------------------------------- - -XpathINIT - -let msgfile = tempname() - -function! MESSAGES(...) - try - exec "edit" g:msgfile - catch /^Vim(edit):/ - return 0 - endtry - - let english = v:lang == "C" || v:lang =~ '^[Ee]n' - let match = 1 - norm gg - - let num = a:0 / 2 - let cnt = 1 - while cnt <= num - let enr = a:{2*cnt - 1} - let emsg= a:{2*cnt} - let cnt = cnt + 1 - - if enr == "" - Xout "TODO: Add message number for:" emsg - elseif enr == "INT" - let enr = "" - endif - if enr == "" && !english - continue - endif - let pattern = (enr != "") ? enr . ':.*' : '' - if english - let pattern = pattern . emsg - endif - if !search(pattern, "W") - let match = 0 - Xout "No match for:" pattern - endif - norm $ - endwhile - - bwipeout! - return match -endfunction +if ExtraVim(msgfile) +" if 1 +" endtry +" endif +endif +if MESSAGES('E602', ":endtry without :try") + Xpath 2 " X: 2 +endif if ExtraVim(msgfile) - Xpath 1 " X: 1 - throw "arrgh" +" while 1 +" endtry +" endwhile endif - -Xpath 2 " X: 2 -if !MESSAGES('E605', "Exception not caught") - Xpath 4 " X: 0 +if MESSAGES('E602', ":endtry without :try") + Xpath 4 " X: 4 endif if ExtraVim(msgfile) - try - Xpath 8 " X: 8 - throw "oops" - catch /arrgh/ - Xpath 16 " X: 0 - endtry - Xpath 32 " X: 0 +" try +" if 1 +" endtry endif - -Xpath 64 " X: 64 -if !MESSAGES('E605', "Exception not caught") - Xpath 128 " X: 0 +if MESSAGES('E171', "Missing :endif") + Xpath 8 " X: 8 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 +" try +" while 1 +" endtry endif - -Xpath 2048 " X: 2048 -if !MESSAGES('E605', "Exception not caught") - Xpath 4096 " X: 0 +if MESSAGES('E170', "Missing :endwhile") + Xpath 16 " X: 16 endif if ExtraVim(msgfile) - try - Xpath 8192 " X: 8192 - throw "arrgh" - finally - Xpath 16384 " X: 16384 - throw "brrr" - endtry - Xpath 32768 " X: 0 +" try +" finally +" if 1 +" endtry endif - -Xpath 65536 " X: 65536 -if !MESSAGES('E605', "Exception not caught") - Xpath 131072 " X: 0 +if MESSAGES('E171', "Missing :endif") + Xpath 32 " X: 32 endif if ExtraVim(msgfile) - try - Xpath 262144 " X: 262144 - "INTERRUPT - endtry - Xpath 524288 " X: 0 +" try +" finally +" while 1 +" endtry endif - -Xpath 1048576 " X: 1048576 -if !MESSAGES('INT', "Interrupted") - Xpath 2097152 " X: 0 +if MESSAGES('E170', "Missing :endwhile") + Xpath 64 " X: 64 endif if ExtraVim(msgfile) @@ -3707,1907 +2936,816 @@ if !MESSAGES('E121', "Undefined variable") 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 +" try +" throw "a" +" catch /a/ +" while 1 +" endtry 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 +if MESSAGES('E170', "Missing :endwhile") + Xpath 256 " X: 256 endif call delete(msgfile) unlet msgfile -Xcheck 1247112011 +delfunction MESSAGES -" Leave MESSAGES() for the next tests. +Xcheck 511 "------------------------------------------------------------------------------- -" Test 53: Nesting errors: :endif/:else/:elseif {{{1 -" -" For nesting errors of :if conditionals the correct error messages -" should be given. +" Test 57: v:exception and v:throwpoint for user exceptions {{{1 " -" This test reuses the function MESSAGES() from the previous test. -" This functions checks the messages in g:msgfile. +" 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 -let msgfile = tempname() +function! FuncException() + let g:exception = v:exception +endfunction -if ExtraVim(msgfile) -" endif -endif -if MESSAGES('E580', ":endif without :if") - Xpath 1 " X: 1 -endif +function! FuncThrowpoint() + let g:throwpoint = v:throwpoint +endfunction -if ExtraVim(msgfile) -" while 1 -" endif -" endwhile -endif -if MESSAGES('E580', ":endif without :if") - Xpath 2 " X: 2 -endif +let scriptException = MakeScript("FuncException") +let scriptThrowPoint = MakeScript("FuncThrowpoint") -if ExtraVim(msgfile) -" try -" finally -" endif -" endtry -endif -if MESSAGES('E580', ":endif without :if") - Xpath 4 " X: 4 -endif - -if ExtraVim(msgfile) -" try -" endif -" endtry -endif -if MESSAGES('E580', ":endif without :if") - Xpath 8 " X: 8 -endif - -if ExtraVim(msgfile) -" try -" throw "a" -" catch /a/ -" endif -" endtry -endif -if MESSAGES('E580', ":endif without :if") - Xpath 16 " X: 16 -endif - -if ExtraVim(msgfile) -" else -endif -if MESSAGES('E581', ":else without :if") - Xpath 32 " X: 32 -endif - -if ExtraVim(msgfile) -" while 1 -" else -" endwhile -endif -if MESSAGES('E581', ":else without :if") - Xpath 64 " X: 64 -endif - -if ExtraVim(msgfile) -" try -" finally -" else -" endtry -endif -if MESSAGES('E581', ":else without :if") - Xpath 128 " X: 128 -endif - -if ExtraVim(msgfile) -" try -" else -" endtry -endif -if MESSAGES('E581', ":else without :if") - Xpath 256 " X: 256 -endif - -if ExtraVim(msgfile) -" try -" throw "a" -" catch /a/ -" else -" endtry -endif -if MESSAGES('E581', ":else without :if") - Xpath 512 " X: 512 -endif - -if ExtraVim(msgfile) -" elseif -endif -if MESSAGES('E582', ":elseif without :if") - Xpath 1024 " X: 1024 -endif - -if ExtraVim(msgfile) -" while 1 -" elseif -" endwhile -endif -if MESSAGES('E582', ":elseif without :if") - Xpath 2048 " X: 2048 -endif - -if ExtraVim(msgfile) -" try -" finally -" elseif -" endtry -endif -if MESSAGES('E582', ":elseif without :if") - Xpath 4096 " X: 4096 -endif - -if ExtraVim(msgfile) -" try -" elseif -" endtry -endif -if MESSAGES('E582', ":elseif without :if") - Xpath 8192 " X: 8192 -endif - -if ExtraVim(msgfile) -" try -" throw "a" -" catch /a/ -" elseif -" endtry -endif -if MESSAGES('E582', ":elseif without :if") - Xpath 16384 " X: 16384 -endif - -if ExtraVim(msgfile) -" if 1 -" else -" else -" endif -endif -if MESSAGES('E583', "multiple :else") - Xpath 32768 " X: 32768 -endif - -if ExtraVim(msgfile) -" if 1 -" else -" elseif 1 -" endif -endif -if MESSAGES('E584', ":elseif after :else") - Xpath 65536 " X: 65536 -endif - -call delete(msgfile) -unlet msgfile - -Xcheck 131071 - -" Leave MESSAGES() for the next test. - - -"------------------------------------------------------------------------------- -" Test 54: Nesting errors: :while/:endwhile {{{1 -" -" For nesting errors of :while conditionals the correct error messages -" should be given. -" -" This test reuses the function MESSAGES() from the previous test. -" This functions checks the messages in g:msgfile. -"------------------------------------------------------------------------------- - -XpathINIT - -let msgfile = tempname() - -if ExtraVim(msgfile) -" endwhile -endif -if MESSAGES('E588', ":endwhile without :while") - Xpath 1 " X: 1 -endif - -if ExtraVim(msgfile) -" if 1 -" endwhile -" endif -endif -if MESSAGES('E588', ":endwhile without :while") - Xpath 2 " X: 2 -endif - -if ExtraVim(msgfile) -" while 1 -" if 1 -" endwhile -endif -if MESSAGES('E171', "Missing :endif") - Xpath 4 " X: 4 -endif - -if ExtraVim(msgfile) -" try -" finally -" endwhile -" endtry -endif -if MESSAGES('E588', ":endwhile without :while") - Xpath 8 " X: 8 -endif - -if ExtraVim(msgfile) -" while 1 -" try -" finally -" endwhile -endif -if MESSAGES('E600', "Missing :endtry") - Xpath 16 " X: 16 -endif - -if ExtraVim(msgfile) -" while 1 -" if 1 -" try -" finally -" endwhile -endif -if MESSAGES('E600', "Missing :endtry") - Xpath 32 " X: 32 -endif - -if ExtraVim(msgfile) -" while 1 -" try -" finally -" if 1 -" endwhile -endif -if MESSAGES('E171', "Missing :endif") - Xpath 64 " X: 64 -endif - -if ExtraVim(msgfile) -" try -" endwhile -" endtry -endif -if MESSAGES('E588', ":endwhile without :while") - Xpath 128 " X: 128 -endif - -if ExtraVim(msgfile) -" while 1 -" try -" endwhile -" endtry -" endwhile -endif -if MESSAGES('E588', ":endwhile without :while") - Xpath 256 " X: 256 -endif - -if ExtraVim(msgfile) -" try -" throw "a" -" catch /a/ -" endwhile -" endtry -endif -if MESSAGES('E588', ":endwhile without :while") - Xpath 512 " X: 512 -endif - -if ExtraVim(msgfile) -" while 1 -" try -" throw "a" -" catch /a/ -" endwhile -" endtry -" endwhile -endif -if MESSAGES('E588', ":endwhile without :while") - Xpath 1024 " X: 1024 -endif - - -call delete(msgfile) -unlet msgfile - -Xcheck 2047 - -" Leave MESSAGES() for the next test. - - -"------------------------------------------------------------------------------- -" Test 55: Nesting errors: :continue/:break {{{1 -" -" For nesting errors of :continue and :break commands the correct -" error messages should be given. -" -" This test reuses the function MESSAGES() from the previous test. -" This functions checks the messages in g:msgfile. -"------------------------------------------------------------------------------- - -XpathINIT - -let msgfile = tempname() - -if ExtraVim(msgfile) -" continue -endif -if MESSAGES('E586', ":continue without :while") - Xpath 1 " X: 1 -endif - -if ExtraVim(msgfile) -" if 1 -" continue -" endif -endif -if MESSAGES('E586', ":continue without :while") - Xpath 2 " X: 2 -endif - -if ExtraVim(msgfile) -" try -" finally -" continue -" endtry -endif -if MESSAGES('E586', ":continue without :while") - Xpath 4 " X: 4 -endif - -if ExtraVim(msgfile) -" try -" continue -" endtry -endif -if MESSAGES('E586', ":continue without :while") - Xpath 8 " X: 8 -endif - -if ExtraVim(msgfile) -" try -" throw "a" -" catch /a/ -" continue -" endtry -endif -if MESSAGES('E586', ":continue without :while") - Xpath 16 " X: 16 -endif - -if ExtraVim(msgfile) -" break -endif -if MESSAGES('E587', ":break without :while") - Xpath 32 " X: 32 -endif - -if ExtraVim(msgfile) -" if 1 -" break -" endif -endif -if MESSAGES('E587', ":break without :while") - Xpath 64 " X: 64 -endif - -if ExtraVim(msgfile) -" try -" finally -" break -" endtry -endif -if MESSAGES('E587', ":break without :while") - Xpath 128 " X: 128 -endif - -if ExtraVim(msgfile) -" try -" break -" endtry -endif -if MESSAGES('E587', ":break without :while") - Xpath 256 " X: 256 -endif - -if ExtraVim(msgfile) -" try -" throw "a" -" catch /a/ -" break -" endtry -endif -if MESSAGES('E587', ":break without :while") - Xpath 512 " X: 512 -endif - -call delete(msgfile) -unlet msgfile - -Xcheck 1023 - -" Leave MESSAGES() for the next test. - - -"------------------------------------------------------------------------------- -" Test 56: Nesting errors: :endtry {{{1 -" -" For nesting errors of :try conditionals the correct error messages -" should be given. -" -" This test reuses the function MESSAGES() from the previous test. -" This functions checks the messages in g:msgfile. -"------------------------------------------------------------------------------- - -XpathINIT - -let msgfile = tempname() - -if ExtraVim(msgfile) -" endtry -endif -if MESSAGES('E602', ":endtry without :try") - Xpath 1 " X: 1 -endif - -if ExtraVim(msgfile) -" if 1 -" endtry -" endif -endif -if MESSAGES('E602', ":endtry without :try") - Xpath 2 " X: 2 -endif - -if ExtraVim(msgfile) -" while 1 -" endtry -" endwhile -endif -if MESSAGES('E602', ":endtry without :try") - Xpath 4 " X: 4 -endif - -if ExtraVim(msgfile) -" try -" if 1 -" endtry -endif -if MESSAGES('E171', "Missing :endif") - Xpath 8 " X: 8 -endif - -if ExtraVim(msgfile) -" try -" while 1 -" endtry -endif -if MESSAGES('E170', "Missing :endwhile") - Xpath 16 " X: 16 -endif - -if ExtraVim(msgfile) -" try -" finally -" if 1 -" endtry -endif -if MESSAGES('E171', "Missing :endif") - Xpath 32 " X: 32 -endif - -if ExtraVim(msgfile) -" try -" finally -" while 1 -" endtry -endif -if MESSAGES('E170', "Missing :endwhile") - Xpath 64 " X: 64 -endif - -if ExtraVim(msgfile) -" try -" throw "a" -" catch /a/ -" if 1 -" endtry -endif -if MESSAGES('E171', "Missing :endif") - Xpath 128 " X: 128 -endif - -if ExtraVim(msgfile) -" try -" throw "a" -" catch /a/ -" while 1 -" endtry -endif -if MESSAGES('E170', "Missing :endwhile") - Xpath 256 " X: 256 -endif - -call delete(msgfile) -unlet msgfile - -delfunction MESSAGES - -Xcheck 511 - - -"------------------------------------------------------------------------------- -" Test 57: v:exception and v:throwpoint for user exceptions {{{1 -" -" v:exception evaluates to the value of the exception that was caught -" most recently and is not finished. (A caught exception is finished -" when the next ":catch", ":finally", or ":endtry" is reached.) -" v:throwpoint evaluates to the script/function name and line number -" where that exception has been thrown. -"------------------------------------------------------------------------------- - -XpathINIT - -function! FuncException() - let g:exception = v:exception -endfunction - -function! FuncThrowpoint() - let g:throwpoint = v:throwpoint -endfunction - -let scriptException = MakeScript("FuncException") -let scriptThrowPoint = MakeScript("FuncThrowpoint") - -command! CmdException let g:exception = v:exception -command! CmdThrowpoint let g:throwpoint = v:throwpoint - -XloopINIT! 1 2 - -function! CHECK(n, exception, throwname, throwline) - XloopNEXT - let error = 0 - if v:exception != a:exception - Xout a:n.": v:exception is" v:exception "instead of" a:exception - let error = 1 - endif - if v:throwpoint !~ a:throwname - let name = escape(a:throwname, '\') - Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" name - let error = 1 - endif - if v:throwpoint !~ a:throwline - let line = escape(a:throwline, '\') - Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line - let error = 1 - endif - if error - Xloop 1 " X: 0 - endif -endfunction - -function! T(arg, line) - if a:line == 2 - throw a:arg " in line 2 - elseif a:line == 4 - throw a:arg " in line 4 - elseif a:line == 6 - throw a:arg " in line 6 - elseif a:line == 8 - throw a:arg " in line 8 - endif -endfunction - -function! G(arg, line) - call T(a:arg, a:line) -endfunction - -function! F(arg, line) - call G(a:arg, a:line) -endfunction - -let scriptT = MakeScript("T") -let scriptG = MakeScript("G", scriptT) -let scriptF = MakeScript("F", scriptG) - -try - Xpath 32768 " X: 32768 - call F("oops", 2) -catch /.*/ - Xpath 65536 " X: 65536 - let exception = v:exception - let throwpoint = v:throwpoint - call CHECK(1, "oops", '\', '\<2\>') - exec "let exception = v:exception" - exec "let throwpoint = v:throwpoint" - call CHECK(2, "oops", '\', '\<2\>') - CmdException - CmdThrowpoint - call CHECK(3, "oops", '\', '\<2\>') - call FuncException() - call FuncThrowpoint() - call CHECK(4, "oops", '\', '\<2\>') - exec "source" scriptException - exec "source" scriptThrowPoint - call CHECK(5, "oops", '\', '\<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", '\', '\<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", '\', '\<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", '\', '\<4\>') - endtry - Xpath 33554432 " X: 33554432 - let exception = v:exception - let throwpoint = v:throwpoint - call CHECK(11, "arrgh", '\', '\<4\>') - endtry - Xpath 67108864 " X: 67108864 - let exception = v:exception - let throwpoint = v:throwpoint - call CHECK(12, "arrgh", '\', '\<4\>') - finally - Xpath 134217728 " X: 134217728 - let exception = v:exception - let throwpoint = v:throwpoint - call CHECK(13, "oops", '\', '\<2\>') - endtry - Xpath 268435456 " X: 268435456 - let exception = v:exception - let throwpoint = v:throwpoint - call CHECK(14, "oops", '\', '\<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 !~ '\' - 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 +command! CmdException let g:exception = v:exception +command! CmdThrowpoint let g:throwpoint = v:throwpoint - 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 !~ '\' - 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 +XloopINIT! 1 2 - Xpath 524288 " X: 524288 - if v:exception != "" - Xpath 1048576 " X: 0 +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 != "" - Xpath 2097152 " X: 0 + 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 -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("") - - function! LineNumber() - return substitute(substitute(v:throwpoint, g:sfile, '', ""), - \ '\D*\(\d*\).*', '\1', "") - endfunction - - command! -nargs=1 SetLineNumber - \ try | throw "line" | catch /.*/ | let = 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 +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 - try - while 1 - try - throw "x6" - finally - break - endtry - break - endwhile - catch /.*/ - Xpath 33554432 " X: 0 - endtry - call CHECK(10) +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", '\', '\<2\>') + exec "let exception = v:exception" + exec "let throwpoint = v:throwpoint" + call CHECK(2, "oops", '\', '\<2\>') + CmdException + CmdThrowpoint + call CHECK(3, "oops", '\', '\<2\>') + call FuncException() + call FuncThrowpoint() + call CHECK(4, "oops", '\', '\<2\>') + exec "source" scriptException + exec "source" scriptThrowPoint + call CHECK(5, "oops", '\', '\<2\>') try - while 1 - try - throw "x7" - finally - break - endtry - break - endwhile + Xpath 131072 " X: 131072 + call G("arrgh", 4) catch /.*/ - Xpath 67108864 " X: 0 - finally - call CHECK(11) - endtry - call CHECK(12) - - while 1 + Xpath 262144 " X: 262144 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(6, "arrgh", '\', '\<4\>') try - let errcaught = 0 + 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", '\', '\<4\>') try - try - throw "x8" - finally - SetLineNumber line_before_error - asdf - endtry + Xpath 4194304 " X: 4194304 + let g:arg = "brrrr" + let g:line = 8 + exec "source" scriptG catch /.*/ - let errcaught = 1 - call CHECK(13, 'E492', "Not an editor command", - \ line_before_error + 1) + 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", '\', '\<4\>') endtry - finally - if !errcaught && $VIMNOERRTHROW - call CHECK(13) - endif - break " discard error for $VIMNOERRTHROW + Xpath 33554432 " X: 33554432 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(11, "arrgh", '\', '\<4\>') endtry - endwhile - call CHECK(14) + Xpath 67108864 " X: 67108864 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(12, "arrgh", '\', '\<4\>') + finally + Xpath 134217728 " X: 134217728 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(13, "oops", '\', '\<2\>') + endtry + Xpath 268435456 " X: 268435456 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(14, "oops", '\', '\<2\>') +finally + Xpath 536870912 " X: 536870912 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(15, "", '^$', '^$') +endtry - Xpath 134217728 " X: 134217728 +Xpath 1073741824 " X: 1073741824 - 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) +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 - Xpath 268435456 " X: 268435456 +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 - 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 + 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 !~ '\' + Xpath 4 " X: 0 + endif + if v:throwpoint !~ '\<2\>' + Xpath 8 " X: 0 + endif finally - if !errcaught && $VIMNOERRTHROW - call CHECK(18) + 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 - call CHECK(19) - Xpath 536870912 " X: 536870912 + Xpath 256 " X: 256 + if v:exception != "" + Xpath 512 " X: 0 + endif + if v:throwpoint != "" + Xpath 1024 " X: 0 + endif 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 + 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 !~ '\' + Xpath 8192 " X: 0 + endif + if v:throwpoint !~ '\<4\>' + Xpath 16384 " X: 0 + endif finally - if !errcaught && $VIMNOERRTHROW - call CHECK(20) + 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 - call CHECK(21) - Xpath 1073741824 " X: 1073741824 + Xpath 524288 " X: 524288 + if v:exception != "" + Xpath 1048576 " X: 0 + endif + if v:throwpoint != "" + Xpath 2097152 " X: 0 + endif endif -Xcheck 2038431743 +Xcheck 624945 "------------------------------------------------------------------------------- " -" Test 60: (Re)throwing v:exception; :echoerr. {{{1 +" Test 59: v:exception and v:throwpoint when discarding exceptions {{{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. +" 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 -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 +if ExtraVim() -call F() -delfunction F + XloopINIT! 1 2 -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 + let sfile = expand("") -call G() -delfunction G + function! LineNumber() + return substitute(substitute(v:throwpoint, g:sfile, '', ""), + \ '\D*\(\d*\).*', '\1', "") + endfunction -unlet! value caught + command! -nargs=1 SetLineNumber + \ try | throw "line" | catch /.*/ | let = LineNumber() | endtry -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 + " 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 - echoerr "Interrupt" + let exception = '^Vim(\a\+):' . exception . ': ' . emsg + endif + else + if exception == "E492" + let exception = '^Vim:' . exception + else + let exception = '^Vim(\a\+):' . exception 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 + 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 - 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() + 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 - 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 + throw "x1" catch /.*/ - Xpath 16 " X: 0 - Xout v:exception "in" v:throwpoint - finally - break " discard interrupt for $VIMNOINTTHROW + break endtry endwhile + call CHECK(1) 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 + throw "x2" catch /.*/ - Xpath 8192 " X: 0 - Xout v:exception "in" v:throwpoint + break finally - break " discard interrupt for $VIMNOINTTHROW + call CHECK(2) endtry + break endwhile + call CHECK(3) while 1 try + let errcaught = 0 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 + throw "x3" catch /.*/ - Xpath 262144 " X: 0 + SetLineNumber line_before_error + asdf endtry - catch /^Vim:Interrupt$/ - let caught = 1 - finally - Xpath 524288 " X: 524288 - if caught || $VIMNOINTTHROW - Xpath 1048576 " X: 1048576 - endif + catch /.*/ + let errcaught = 1 + call CHECK(4, 'E492', "Not an editor command", + \ line_before_error + 1) endtry - catch /.*/ - Xpath 2097152 " X: 0 - Xout v:exception "in" v:throwpoint finally - break " discard interrupt for $VIMNOINTTHROW + 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 caught = 0 + let intcaught = 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 + 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 - catch /.*/ - Xpath 134217728 " X: 0 - Xout v:exception "in" v:throwpoint finally + if !intcaught && $VIMNOINTTHROW + call CHECK(6) + endif break " discard interrupt for $VIMNOINTTHROW endtry endwhile + call CHECK(7) - 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 + Xpath 4194304 " X: 4194304 -while 1 - try + while 1 try - let caught = 0 - unlet novar - catch /^Vim(unlet):/ - let caught = 1 - let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "") + 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 - Xpath 1 " X: 1 - if !caught && !$VIMNOERRTHROW - Xpath 2 " X: 0 - endif - if !MSG('E108', "No such variable") - Xpath 4 " X: 0 + if !errcaught && $VIMNOERRTHROW + call CHECK(8) endif + break " discard error for $VIMNOERRTHROW endtry - catch /.*/ - Xpath 8 " X: 0 - Xout v:exception "in" v:throwpoint - finally - break " discard error for $VIMNOERRTHROW - endtry -endwhile + endwhile + call CHECK(9) -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 + Xpath 16777216 " X: 16777216 -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 + while 1 + try + throw "x6" + finally + break + endtry + break + endwhile + catch /.*/ + Xpath 33554432 " X: 0 endtry -endwhile - -function! F() - while 1 - " Missing :endwhile -endfunction + call CHECK(10) -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 + while 1 + try + throw "x7" + finally + break + endtry + break + endwhile catch /.*/ - Xpath 32768 " X: 0 - Xout v:exception "in" v:throwpoint + Xpath 67108864 " X: 0 finally - break " discard error for $VIMNOERRTHROW + call CHECK(11) endtry -endwhile + call CHECK(12) -while 1 - try + while 1 try - let caught = 0 - ExecAsScript F - catch /^Vim:/ - let caught = 1 - let v:errmsg = substitute(v:exception, '^Vim:', '', "") + 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 - Xpath 65536 " X: 65536 - if !caught && !$VIMNOERRTHROW - Xpath 131072 " X: 0 - endif - if !MSG('E170', "Missing :endwhile") - Xpath 262144 " X: 0 + if !errcaught && $VIMNOERRTHROW + call CHECK(13) endif + break " discard error for $VIMNOERRTHROW endtry - catch /.*/ - Xpath 524288 " X: 0 - Xout v:exception "in" v:throwpoint - finally - break " discard error for $VIMNOERRTHROW - endtry -endwhile + endwhile + call CHECK(14) -function! G() - call G() -endfunction + Xpath 134217728 " X: 134217728 -while 1 - try - let mfd_save = &mfd - set mfd=3 + while 1 try - let caught = 0 - call G() - catch /^Vim(call):/ - let caught = 1 - let v:errmsg = substitute(v:exception, '^Vim(call):', '', "") + 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 - 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 + if !intcaught && $VIMNOINTTHROW + call CHECK(15) endif + break " discard interrupt for $VIMNOINTTHROW endtry - catch /.*/ - Xpath 8388608 " X: 0 - Xout v:exception "in" v:throwpoint - finally - let &mfd = mfd_save - break " discard error for $VIMNOERRTHROW - endtry -endwhile + endwhile + call CHECK(16) -function! H() - return H() -endfunction + Xpath 268435456 " X: 268435456 -while 1 - try - let mfd_save = &mfd - set mfd=3 + while 1 try - let caught = 0 - call H() - catch /^Vim(return):/ - let caught = 1 - let v:errmsg = substitute(v:exception, '^Vim(return):', '', "") + 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 - 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 + if !errcaught && $VIMNOERRTHROW + call CHECK(18) endif + break " discard error for $VIMNOERRTHROW 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 + endwhile + call CHECK(19) - " Check that ":silent!" sets "v:errmsg": - if MSG('E492', "Not an editor command") - Xloop 2 - endif -endfunction + Xpath 536870912 " X: 536870912 -function! Foo() while 1 try + let errcaught = 0 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 + 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 - catch /.*/ - Xpath 8388608 " X: 0 - Xout v:exception "in" v:throwpoint + finally + if !errcaught && $VIMNOERRTHROW + call CHECK(20) + endif + break " discard error for $VIMNOERRTHROW 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 + call CHECK(21) -silent! call S(1) " X: 3 * 1 -silent! call Bar() -silent! call S(10) " X: 3 * 262144 + Xpath 1073741824 " X: 1073741824 -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 +Xcheck 2038431743 "------------------------------------------------------------------------------- -" 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. +" 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 -if ExtraVim() +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 - while 1 +function! F() + try + let caught = 0 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 + 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 8 " X: 0 - Xout v:exception "in" v:throwpoint + Xpath 128 " X: 0 finally - break " discard error for $VIMNOERRTHROW + Xpath 256 " X: 256 + if !caught && !$VIMNOERRTHROW + Xpath 512 " X: 0 + endif endtry - endwhile + 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 - while 1 +call F() +delfunction F + +function! G() + try + let caught = 0 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 + 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 - endtry + 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 512 " X: 0 - Xout v:exception "in" v:throwpoint + Xpath 16777216 " X: 0 finally - break " discard error for $VIMNOERRTHROW + Xpath 33554432 " X: 33554432 + if !intcaught + if !$VIMNOINTTHROW + Xpath 67108864 " X: 0 + else + echoerr "Interrupt" + endif + endif endtry - endwhile + 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 - 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(/ + "INTERRUPT + Xpath 2 " X: 0 + catch /^Vim:Interrupt$/ let caught = 1 finally - Xpath 16384 " X: 16384 - if caught || $VIMNOERRTHROW - Xpath 32768 " X: 32768 + Xpath 4 " X: 4 + if caught || $VIMNOINTTHROW + Xpath 8 " X: 8 endif endtry catch /.*/ - Xpath 65536 " X: 0 + Xpath 16 " X: 0 Xout v:exception "in" v:throwpoint finally - break " discard error for $VIMNOERRTHROW + break " discard interrupt for $VIMNOINTTHROW endtry endwhile @@ -5616,30 +3754,31 @@ if ExtraVim() try let caught = 0 try - Xpath 131072 " X: 131072 - throw "x" + Xpath 32 " X: 32 + asdf + Xpath 64 " X: 0 catch /do_not_catch/ - Xpath 262144 " X: 0 -" if 1 - " Missing :endif - catch /x/ " throw error exception - Xpath 524288 " X: 0 + Xpath 128 " X: 0 + catch /.*/ "INTERRUPT - throw interrupt if !$VIMNOERRTHROW + Xpath 256 " X: 0 catch /.*/ - Xpath 1048576 " X: 0 + Xpath 512 " X: 0 + finally "INTERRUPT - throw interrupt if $VIMNOERRTHROW + Xpath 1024 " X: 1024 endtry - catch /^Vim(/ + catch /^Vim:Interrupt$/ let caught = 1 finally - Xpath 2097152 " X: 2097152 - if caught || $VIMNOERRTHROW - Xpath 4194304 " X: 4194304 + Xpath 2048 " X: 2048 + if caught || $VIMNOINTTHROW + Xpath 4096 " X: 4096 endif endtry catch /.*/ - Xpath 8388608 " X: 0 + Xpath 8192 " X: 0 Xout v:exception "in" v:throwpoint finally - break " discard error for $VIMNOERRTHROW + break " discard interrupt for $VIMNOINTTHROW endtry endwhile @@ -5647,1534 +3786,1138 @@ if ExtraVim() 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):/ + 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 - catch /^Vim(/ - Xpath 67108864 " X: 0 finally - Xpath 134217728 " X: 134217728 - if caught || $VIMNOERRTHROW - Xpath 268435456 " X: 268435456 + Xpath 524288 " X: 524288 + if caught || $VIMNOINTTHROW + Xpath 1048576 " X: 1048576 endif endtry catch /.*/ - Xpath 536870912 " X: 0 + Xpath 2097152 " 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 + finally + break " discard interrupt for $VIMNOINTTHROW + endtry + endwhile - Xpath 8 " X: 8 - call G("error", 1) - try - Xpath 16 " X: 16 + while 1 try - call G("error", 2) - Xpath 32 " X: 0 - finally - Xpath 64 " X: 64 + let caught = 0 try - call G("interrupt", 3) - Xpath 128 " X: 0 + 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 256 " X: 256 - try - call G("throw", 4) - Xpath 512 " X: 0 - endtry + 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 - 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 + endwhile + + Xpath 268435456 " X: 268435456 endif -Xcheck 5464 +Xcheck 374889517 "------------------------------------------------------------------------------- -" Test 67: :throw across :call command {{{1 +" Test 62: Catching error exceptions {{{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. +" 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! 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 +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 - return a:x -endfunction - -function! F(x, n) - if a:n == 2 - Xpath 2048 " X: 0 - elseif a:n == 4 - Xpath 4096 " X: 4096 + 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 - 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 + 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 - catch /^0$/ " default return value - Xpath 536870912 " X: 0 - Xout v:throwpoint +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 /.*/ - let error = 1 + Xpath 128 " X: 0 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 +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(x, n) - if a:n == 2 - Xpath 2048 " X: 0 - elseif a:n == 4 - Xpath 4096 " X: 4096 - endif - return a:x +function! F() + while 1 + " Missing :endwhile endfunction -unlet! var1 var2 var3 var4 - while 1 try - let error = 0 - let v:errmsg = "" + 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 - 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 + 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 - 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 +function! G() + call G() +endfunction - 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 + 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 - 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 +function! H() + return H() +endfunction - catch /^0$/ " default return value - Xpath 536870912 " X: 0 - Xout v:throwpoint +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 /.*/ - let error = 1 + Xpath 134217728 " X: 0 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 + let &mfd = mfd_save 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 +unlet! caught mfd_save delfunction F +delfunction G +delfunction H +Xpath 268435456 " X: 268435456 -Xcheck 212514423 +Xcheck 286331153 + +" Leave MSG() for the next test. "------------------------------------------------------------------------------- -" Test 69: :throw across :if, :elseif, :while {{{1 +" 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. " -" On an :if, :elseif, or :while command, an exception might be thrown -" during evaluation of the expression to test. The exception can be -" caught by the script. +" This test reuses the function MSG() from the previous test. "------------------------------------------------------------------------------- XpathINIT -XloopINIT! 1 2 +XloopINIT! 1 4 + +let taken = "" -function! THROW(x) +function! S(n) abort XloopNEXT - Xloop 1 " X: 1 + 2 + 4 - throw a:x + 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 -try +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 - Xpath 8 " X: 8 - if 4711 == THROW("if") + 111 - Xpath 16 " X: 0 - else - Xpath 32 " X: 0 - endif - Xpath 64 " X: 0 - catch /^if$/ - Xpath 128 " X: 128 - catch /.*/ - Xpath 256 " X: 0 - Xout "if:" v:exception "in" v:throwpoint - endtry + 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 - try - Xpath 512 " X: 512 - if 4711 == 4 + 7 + 1 + 1 - Xpath 1024 " X: 0 - elseif 4711 == THROW("elseif") + 222 - Xpath 2048 " X: 0 - else - Xpath 4096 " X: 0 - endif - Xpath 8192 " X: 0 - catch /^elseif$/ - Xpath 16384 " X: 16384 - catch /.*/ - Xpath 32768 " X: 0 - Xout "elseif:" v:exception "in" v:throwpoint - endtry +silent! call S(1) " X: 3 * 1 +silent! call Bar() +silent! call S(10) " X: 3 * 262144 - try - Xpath 65536 " X: 65536 - while 4711 == THROW("while") + 4711 - Xpath 131072 " X: 0 - break - endwhile - Xpath 262144 " X: 0 - catch /^while$/ - Xpath 524288 " X: 524288 - catch /.*/ - Xpath 1048576 " X: 0 - Xout "while:" v:exception "in" v:throwpoint - endtry +let expected = "E1E2E3E4E5E6E7E8E9E10" +if taken != expected + Xpath 16777216 " X: 0 + Xout "'taken' is" taken "instead of" expected +endif -catch /^0$/ " default return value - Xpath 2097152 " X: 0 - Xout v:throwpoint -catch /.*/ - Xout v:exception "in" v:throwpoint - Xpath 4194304 " X: 0 -endtry +augroup TMP + autocmd BufWritePost * Xpath 33554432 " X: 33554432 +augroup END -Xpath 8388608 " X: 8388608 +Xpath 67108864 " X: 67108864 +write /i/m/p/o/s/s/i/b/l/e +Xpath 134217728 " X: 134217728 -delfunction THROW +autocmd! TMP +unlet! caught errmsg3 taken expected +delfunction S +delfunction Foo +delfunction Bar +delfunction MSG -Xcheck 8995471 +Xcheck 236978127 "------------------------------------------------------------------------------- -" Test 70: :throw across :return or :throw {{{1 +" Test 64: Error exceptions after error, interrupt or :throw {{{1 " -" On a :return or :throw command, an exception might be thrown during -" evaluation of the expression to return or throw, respectively. The -" exception can be caught by the script. +" 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 -let taken = "" - -function! THROW(x, n) - let g:taken = g:taken . "T" . a:n - throw a:x -endfunction - -function! F(x, y, n) - let g:taken = g:taken . "F" . a:n - return a:x + THROW(a:y, a:n) -endfunction - -function! G(x, y, n) - let g:taken = g:taken . "G" . a:n - throw a:x . THROW(a:y, a:n) - return a:x -endfunction - -try - try - Xpath 1 " X: 1 - call F(4711, "return", 1) - Xpath 2 " X: 0 - catch /^return$/ - Xpath 4 " X: 4 - catch /.*/ - Xpath 8 " X: 0 - Xout "return:" v:exception "in" v:throwpoint - endtry - - try - Xpath 16 " X: 16 - let var = F(4712, "return-var", 2) - Xpath 32 " X: 0 - catch /^return-var$/ - Xpath 64 " X: 64 - catch /.*/ - Xpath 128 " X: 0 - Xout "return-var:" v:exception "in" v:throwpoint - finally - unlet! var - endtry +if ExtraVim() - try - Xpath 256 " X: 256 - throw "except1" . THROW("throw1", 3) - Xpath 512 " X: 0 - catch /^except1/ - Xpath 1024 " X: 0 - catch /^throw1$/ - Xpath 2048 " X: 2048 - catch /.*/ - Xpath 4096 " X: 0 - Xout "throw1:" v:exception "in" v:throwpoint - endtry + 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 - try - Xpath 8192 " X: 8192 - call G("except2", "throw2", 4) - Xpath 16384 " X: 0 - catch /^except2/ - Xpath 32768 " X: 0 - catch /^throw2$/ - Xpath 65536 " X: 65536 - catch /.*/ - Xpath 131072 " X: 0 - Xout "throw2:" v:exception "in" v:throwpoint - endtry + 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 - try - Xpath 262144 " X: 262144 - let var = G("except3", "throw3", 5) - Xpath 524288 " X: 0 - catch /^except3/ - Xpath 1048576 " X: 0 - catch /^throw3$/ - Xpath 2097152 " X: 2097152 - catch /.*/ - Xpath 4194304 " X: 0 - Xout "throw3:" v:exception "in" v:throwpoint - finally - unlet! var - endtry + 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 - let expected = "F1T1F2T2T3G4T4G5T5" - if taken != expected - Xpath 8388608 " X: 0 - Xout "'taken' is" taken "instead of" expected - endif + 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 -catch /^0$/ " default return value - Xpath 16777216 " X: 0 - Xout v:throwpoint -catch /.*/ - Xpath 33554432 " X: 0 - Xout v:exception "in" v:throwpoint -endtry + 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 67108864 " X: 67108864 + Xpath 1073741824 " X: 1073741824 -unlet taken expected -delfunction THROW -delfunction F -delfunction G +endif -Xcheck 69544277 +Xcheck 1499645335 "------------------------------------------------------------------------------- -" Test 71: :throw across :echo variants and :execute {{{1 +" Test 65: Errors in the /pattern/ argument of a :catch {{{1 " -" On an :echo, :echon, :echomsg, :echoerr, or :execute command, an -" exception might be thrown during evaluation of the arguments to -" be displayed or executed as a command, respectively. Any following -" arguments are not evaluated, then. The exception can be caught by -" the script. +" 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 -let taken = "" - -function! THROW(x, n) - let g:taken = g:taken . "T" . a:n - throw a:x -endfunction - -function! F(n) - let g:taken = g:taken . "F" . a:n - return "F" . a:n +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 - echo "echo" . THROW("echo-except", 1) F(1) - Xpath 2 " X: 0 - catch /^echo-except$/ - Xpath 4 " X: 4 - catch /.*/ - Xpath 8 " X: 0 - Xout "echo:" v:exception "in" v:throwpoint - endtry - - try - Xpath 16 " X: 16 - echon "echon" . THROW("echon-except", 2) F(2) - Xpath 32 " X: 0 - catch /^echon-except$/ - Xpath 64 " X: 64 - catch /.*/ - Xpath 128 " X: 0 - Xout "echon:" v:exception "in" v:throwpoint - endtry - - try - Xpath 256 " X: 256 - echomsg "echomsg" . THROW("echomsg-except", 3) F(3) - Xpath 512 " X: 0 - catch /^echomsg-except$/ - Xpath 1024 " X: 1024 - catch /.*/ - Xpath 2048 " X: 0 - Xout "echomsg:" v:exception "in" v:throwpoint - endtry - - try - Xpath 4096 " X: 4096 - echoerr "echoerr" . THROW("echoerr-except", 4) F(4) - Xpath 8192 " X: 0 - catch /^echoerr-except$/ - Xpath 16384 " X: 16384 - catch /Vim/ - Xpath 32768 " X: 0 - catch /echoerr/ - Xpath 65536 " X: 0 - catch /.*/ - Xpath 131072 " X: 0 - Xout "echoerr:" v:exception "in" v:throwpoint + 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 - Xpath 262144 " X: 262144 - execute "echo 'execute" . THROW("execute-except", 5) F(5) "'" - Xpath 524288 " X: 0 - catch /^execute-except$/ - Xpath 1048576 " X: 1048576 + 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 2097152 " X: 0 - Xout "execute:" v:exception "in" v:throwpoint + Xpath 32768 " X: 0 + Xout v:exception "in" v:throwpoint endtry +endfunction - let expected = "T1T2T3T4T5" - if taken != expected - Xpath 4194304 " X: 0 - Xout "'taken' is" taken "instead of" expected - endif - -catch /^0$/ " default return value - Xpath 8388608 " X: 0 - Xout v:throwpoint -catch /.*/ - Xpath 16777216 " X: 0 - Xout v:exception "in" v:throwpoint -endtry - -Xpath 33554432 " X: 33554432 +call F() +Xpath 65536 " X: 65536 -unlet taken expected -delfunction THROW +delfunction MSG delfunction F +unlet! caught -Xcheck 34886997 +Xcheck 70187 "------------------------------------------------------------------------------- -" Test 72: :throw across :let or :unlet {{{1 +" Test 66: Stop range :call on error, interrupt, or :throw {{{1 " -" On a :let command, an exception might be thrown during evaluation -" of the expression to assign. On an :let or :unlet command, the -" evaluation of the name of the variable to be assigned or list or -" deleted, respectively, may throw an exception. Any following -" arguments are not evaluated, then. The exception can be caught by -" the script. +" 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 -let throwcount = 0 +if ExtraVim() -function! THROW(x) - let g:throwcount = g:throwcount + 1 - throw a:x -endfunction + let file = tempname() + exec "edit" file -try - try - let $VAR = "old_value" - Xpath 1 " X: 1 - let $VAR = "let(" . THROW("var") . ")" - Xpath 2 " X: 0 - catch /^var$/ - Xpath 4 " X: 4 - finally - if $VAR != "old_value" - Xpath 8 " X: 0 + 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 - endtry + 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 - let @a = "old_value" Xpath 16 " X: 16 - let @a = "let(" . THROW("reg") . ")" - Xpath 32 " X: 0 - catch /^reg$/ try + call G("error", 2) + Xpath 32 " X: 0 + finally Xpath 64 " X: 64 - let @A = "let(" . THROW("REG") . ")" - Xpath 128 " X: 0 - catch /^REG$/ - Xpath 256 " X: 256 + 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 - finally - if @a != "old_value" - Xpath 512 " X: 0 - endif - if @A != "old_value" - Xpath 1024 " X: 0 - endif + 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 saved_gpath = &g:path - let saved_lpath = &l:path - Xpath 2048 " X: 2048 - let &path = "let(" . THROW("opt") . ")" - Xpath 4096 " X: 0 - catch /^opt$/ - try - Xpath 8192 " X: 8192 - let &g:path = "let(" . THROW("gopt") . ")" - Xpath 16384 " X: 0 - catch /^gopt$/ + let error = 0 + let v:errmsg = "" + + while 1 try - Xpath 32768 " X: 32768 - let &l:path = "let(" . THROW("lopt") . ")" - Xpath 65536 " X: 0 - catch /^lopt$/ - Xpath 131072 " X: 131072 + 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 - endtry - finally - if &g:path != saved_gpath || &l:path != saved_lpath - Xpath 262144 " X: 0 - endif - let &g:path = saved_gpath - let &l:path = saved_lpath - endtry + endwhile - unlet! var1 var2 var3 + 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 - try - Xpath 524288 " X: 524288 - let var1 = "let(" . THROW("var1") . ")" - Xpath 1048576 " X: 0 - catch /^var1$/ - Xpath 2097152 " X: 2097152 + catch /^0$/ " default return value + Xpath 536870912 " X: 0 + Xout v:throwpoint + catch /.*/ + let error = 1 + Xout v:exception "in" v:throwpoint finally - if exists("var1") - Xpath 4194304 " X: 0 + if !error && $VIMNOERRTHROW && v:errmsg != "" + let error = 1 + Xout v:errmsg endif - endtry - - try - let var2 = "old_value" - Xpath 8388608 " X: 8388608 - let var2 = "let(" . THROW("var2"). ")" - Xpath 16777216 " X: 0 - catch /^var2$/ - Xpath 33554432 " X: 33554432 - finally - if var2 != "old_value" - Xpath 67108864 " X: 0 + if error + Xpath 1073741824 " X: 0 endif + break " discard error for $VIMNOERRTHROW endtry +endwhile - try - Xpath 134217728 " X: 134217728 - let var{THROW("var3")} = 4711 - Xpath 268435456 " X: 0 - catch /^var3$/ - Xpath 536870912 " X: 536870912 - endtry - - let addpath = "" - - function ADDPATH(p) - let g:addpath = g:addpath . a:p - endfunction - - try - call ADDPATH("T1") - let var{THROW("var4")} var{ADDPATH("T2")} | call ADDPATH("T3") - call ADDPATH("T4") - catch /^var4$/ - call ADDPATH("T5") - endtry - - try - call ADDPATH("T6") - unlet var{THROW("var5")} var{ADDPATH("T7")} | call ADDPATH("T8") - call ADDPATH("T9") - catch /^var5$/ - call ADDPATH("T10") - endtry - - if addpath != "T1T5T6T10" || throwcount != 11 - throw "addpath: " . addpath . ", throwcount: " . throwcount - endif - - Xpath 1073741824 " X: 1073741824 - -catch /.*/ - " The Xpath command does not accept 2^31 (negative); add explicitly: - let Xpath = Xpath + 2147483648 " X: 0 - Xout v:exception "in" v:throwpoint -endtry +unlet error +delfunction F -unlet! var1 var2 var3 addpath throwcount -delfunction THROW +Xcheck 212514423 -Xcheck 1789569365 +" Leave THROW(), NAME(), and ARG() for the next test. "------------------------------------------------------------------------------- -" Test 73: :throw across :function, :delfunction {{{1 +" 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. " -" The :function and :delfunction commands may cause an expression -" specified in braces to be evaluated. During evaluation, an -" exception might be thrown. The exception can be caught by the -" script. +" This test reuses the functions THROW(), NAME(), and ARG() from the +" previous test. "------------------------------------------------------------------------------- XpathINIT -let taken = "" - -function! THROW(x, n) - let g:taken = g:taken . "T" . a:n - throw a:x -endfunction - -function! EXPR(x, n) - let g:taken = g:taken . "E" . a:n - if a:n % 2 == 0 - call THROW(a:x, a:n) +function! F(x, n) + if a:n == 2 + Xpath 2048 " X: 0 + elseif a:n == 4 + Xpath 4096 " X: 4096 endif - return 2 - a:n % 2 + return a:x endfunction -try - try - " Define function. - Xpath 1 " X: 1 - function! F0() - endfunction - Xpath 2 " X: 2 - function! F{EXPR("function-def-ok", 1)}() - endfunction - Xpath 4 " X: 4 - function! F{EXPR("function-def", 2)}() - endfunction - Xpath 8 " X: 0 - catch /^function-def-ok$/ - Xpath 16 " X: 0 - catch /^function-def$/ - Xpath 32 " X: 32 - catch /.*/ - Xpath 64 " X: 0 - Xout "def:" v:exception "in" v:throwpoint - endtry - - try - " List function. - Xpath 128 " X: 128 - function F0 - Xpath 256 " X: 256 - function F{EXPR("function-lst-ok", 3)} - Xpath 512 " X: 512 - function F{EXPR("function-lst", 4)} - Xpath 1024 " X: 0 - catch /^function-lst-ok$/ - Xpath 2048 " X: 0 - catch /^function-lst$/ - Xpath 4096 " X: 4096 - catch /.*/ - Xpath 8192 " X: 0 - Xout "lst:" v:exception "in" v:throwpoint - endtry +unlet! var1 var2 var3 var4 +while 1 try - " Delete function - Xpath 16384 " X: 16384 - delfunction F0 - Xpath 32768 " X: 32768 - delfunction F{EXPR("function-del-ok", 5)} - Xpath 65536 " X: 65536 - delfunction F{EXPR("function-del", 6)} - Xpath 131072 " X: 0 - catch /^function-del-ok$/ - Xpath 262144 " X: 0 - catch /^function-del$/ - Xpath 524288 " X: 524288 - catch /.*/ - Xpath 1048576 " X: 0 - Xout "del:" v:exception "in" v:throwpoint - endtry - - let expected = "E1E2T2E3E4T4E5E6T6" - if taken != expected - Xpath 2097152 " X: 0 - Xout "'taken' is" taken "instead of" expected - endif - -catch /.*/ - Xpath 4194304 " X: 0 - Xout v:exception "in" v:throwpoint -endtry - -Xpath 8388608 " X: 8388608 - -unlet taken expected -delfunction THROW -delfunction EXPR - -Xcheck 9032615 - - -"------------------------------------------------------------------------------- -" Test 74: :throw across builtin functions and commands {{{1 -" -" Some functions like exists(), searchpair() take expression -" arguments, other functions or commands like substitute() or -" :substitute cause an expression (specified in the regular -" expression) to be evaluated. During evaluation an exception -" might be thrown. The exception can be caught by the script. -"------------------------------------------------------------------------------- - -XpathINIT - -let taken = "" - -function! THROW(x, n) - let g:taken = g:taken . "T" . a:n - throw a:x -endfunction - -function! EXPR(x, n) - let g:taken = g:taken . "E" . a:n - call THROW(a:x . a:n, a:n) - return "EXPR" -endfunction - -function! SKIP(x, n) - let g:taken = g:taken . "S" . a:n . "(" . line(".") - let theline = getline(".") - if theline =~ "skip" - let g:taken = g:taken . "s)" - return 1 - elseif theline =~ "throw" - let g:taken = g:taken . "t)" - call THROW(a:x . a:n, a:n) - else - let g:taken = g:taken . ")" - return 0 - endif -endfunction + let error = 0 + let v:errmsg = "" -function! SUBST(x, n) - let g:taken = g:taken . "U" . a:n . "(" . line(".") - let theline = getline(".") - if theline =~ "not" " SUBST() should not be called for this line - let g:taken = g:taken . "n)" - call THROW(a:x . a:n, a:n) - elseif theline =~ "throw" - let g:taken = g:taken . "t)" - call THROW(a:x . a:n, a:n) - else - let g:taken = g:taken . ")" - return "replaced" - endif -endfunction + 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 -try - try - Xpath 1 " X: 1 - let result = exists('*{EXPR("exists", 1)}') - Xpath 2 " X: 0 - catch /^exists1$/ - Xpath 4 " X: 4 - try - let result = exists('{EXPR("exists", 2)}') - Xpath 8 " X: 0 - catch /^exists2$/ - Xpath 16 " X: 16 - catch /.*/ - Xpath 32 " X: 0 - Xout "exists2:" v:exception "in" v:throwpoint - endtry - catch /.*/ - Xpath 64 " X: 0 - Xout "exists1:" v:exception "in" v:throwpoint - endtry + 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 - try - let file = tempname() - exec "edit" file - insert -begin - xx -middle 3 - xx -middle 5 skip - xx -middle 7 throw - xx -end -. - normal! gg - Xpath 128 " X: 128 - let result = - \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 3)') - Xpath 256 " X: 256 - let result = - \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 4)') - Xpath 512 " X: 0 - let result = - \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 5)') - Xpath 1024 " X: 0 - catch /^searchpair[35]$/ - Xpath 2048 " X: 0 - catch /^searchpair4$/ - Xpath 4096 " X: 4096 - catch /.*/ - Xpath 8192 " X: 0 - Xout "searchpair:" v:exception "in" v:throwpoint - finally - bwipeout! - call delete(file) - endtry + 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 - try - let file = tempname() - exec "edit" file - insert -subst 1 -subst 2 -not -subst 4 -subst throw -subst 6 -. - normal! gg - Xpath 16384 " X: 16384 - 1,2substitute/subst/\=SUBST("substitute", 6)/ - try - Xpath 32768 " X: 32768 + while 1 try - let v:errmsg = "" - 3substitute/subst/\=SUBST("substitute", 7)/ + 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 v:errmsg != "" - " If exceptions are not thrown on errors, fake the error - " exception in order to get the same execution path. - throw "faked Vim(substitute)" + 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 - catch /Vim(substitute)/ " Pattern not found ('e' flag missing) - Xpath 65536 " X: 65536 - 3substitute/subst/\=SUBST("substitute", 8)/e - Xpath 131072 " X: 131072 - endtry - Xpath 262144 " X: 262144 - 4,6substitute/subst/\=SUBST("substitute", 9)/ - Xpath 524288 " X: 0 - catch /^substitute[678]/ - Xpath 1048576 " X: 0 - catch /^substitute9/ - Xpath 2097152 " X: 2097152 - finally - bwipeout! - call delete(file) - endtry - - try - Xpath 4194304 " X: 4194304 - let var = substitute("sub", "sub", '\=THROW("substitute()y", 10)', '') - Xpath 8388608 " X: 0 - catch /substitute()y/ - Xpath 16777216 " X: 16777216 - catch /.*/ - Xpath 33554432 " X: 0 - Xout "substitute()y:" v:exception "in" v:throwpoint - endtry + endwhile - try - Xpath 67108864 " X: 67108864 - let var = substitute("not", "sub", '\=THROW("substitute()n", 11)', '') - Xpath 134217728 " X: 134217728 - catch /substitute()n/ - Xpath 268435456 " X: 0 + catch /^0$/ " default return value + Xpath 536870912 " X: 0 + Xout v:throwpoint catch /.*/ - Xpath 536870912 " X: 0 - Xout "substitute()n:" v:exception "in" v:throwpoint + 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 - let expected = "E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10" - if taken != expected - Xpath 1073741824 " X: 0 - Xout "'taken' is" taken "instead of" expected - endif - -catch /.*/ +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 - Xout v:exception "in" v:throwpoint -endtry + 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 result var taken expected +unlet! error var1 var2 var3 var4 delfunction THROW -delfunction EXPR -delfunction SKIP -delfunction SUBST - -Xcheck 224907669 - - -"------------------------------------------------------------------------------- -" Test 75: Errors in builtin functions. {{{1 -" -" On an error in a builtin function called inside a :try/:endtry -" region, the evaluation of the expression calling that function and -" the command containing that expression are abandoned. The error can -" be caught as an exception. -" -" A simple :call of the builtin function is a trivial case. If the -" builtin function is called in the argument list of another function, -" no further arguments are evaluated, and the other function is not -" executed. If the builtin function is called from the argument of -" a :return command, the :return command is not executed. If the -" builtin function is called from the argument of a :throw command, -" the :throw command is not executed. The evaluation of the -" expression calling the builtin function is abandoned. -"------------------------------------------------------------------------------- - -XpathINIT - -function! F1(arg1) - Xpath 1 " X: 0 -endfunction - -function! F2(arg1, arg2) - Xpath 2 " X: 0 -endfunction - -function! G() - Xpath 4 " X: 0 -endfunction - -function! H() - Xpath 8 " X: 0 -endfunction - -function! R() - while 1 - try - let caught = 0 - let v:errmsg = "" - Xpath 16 " X: 16 - return append(1, "s") - catch /E21/ - let caught = 1 - catch /.*/ - Xpath 32 " X: 0 - finally - Xpath 64 " X: 64 - if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' - Xpath 128 " X: 128 - endif - break " discard error for $VIMNOERRTHROW - endtry - endwhile - Xpath 256 " X: 256 -endfunction - -try - set noma " let append() fail with "E21" - - while 1 - try - let caught = 0 - let v:errmsg = "" - Xpath 512 " X: 512 - call append(1, "s") - catch /E21/ - let caught = 1 - catch /.*/ - Xpath 1024 " X: 0 - finally - Xpath 2048 " X: 2048 - if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' - Xpath 4096 " X: 4096 - endif - break " discard error for $VIMNOERRTHROW - endtry - endwhile - - while 1 - try - let caught = 0 - let v:errmsg = "" - Xpath 8192 " X: 8192 - call F1('x' . append(1, "s")) - catch /E21/ - let caught = 1 - catch /.*/ - Xpath 16384 " X: 0 - finally - Xpath 32768 " X: 32768 - if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' - Xpath 65536 " X: 65536 - endif - break " discard error for $VIMNOERRTHROW - endtry - endwhile - - while 1 - try - let caught = 0 - let v:errmsg = "" - Xpath 131072 " X: 131072 - call F2('x' . append(1, "s"), G()) - catch /E21/ - let caught = 1 - catch /.*/ - Xpath 262144 " X: 0 - finally - Xpath 524288 " X: 524288 - if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' - Xpath 1048576 " X: 1048576 - endif - break " discard error for $VIMNOERRTHROW - endtry - endwhile - - call R() - - while 1 - try - let caught = 0 - let v:errmsg = "" - Xpath 2097152 " X: 2097152 - throw "T" . append(1, "s") - catch /E21/ - let caught = 1 - catch /^T.*/ - Xpath 4194304 " X: 0 - catch /.*/ - Xpath 8388608 " X: 0 - finally - Xpath 16777216 " X: 16777216 - if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' - Xpath 33554432 " X: 33554432 - endif - break " discard error for $VIMNOERRTHROW - endtry - endwhile - - while 1 - try - let caught = 0 - let v:errmsg = "" - Xpath 67108864 " X: 67108864 - let x = "a" - let x = x . "b" . append(1, "s") . H() - catch /E21/ - let caught = 1 - catch /.*/ - Xpath 134217728 " X: 0 - finally - Xpath 268435456 " X: 268435456 - if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' - Xpath 536870912 " X: 536870912 - endif - if x == "a" - Xpath 1073741824 " X: 1073741824 - endif - break " discard error for $VIMNOERRTHROW - endtry - endwhile -catch /.*/ - " The Xpath command does not accept 2^31 (negative); add explicitly: - let Xpath = Xpath + 2147483648 " X: 0 - Xout v:exception "in" v:throwpoint -finally - set ma& -endtry +delfunction NAME +delfunction ARG +delfunction F -unlet! caught x -delfunction F1 -delfunction F2 -delfunction G -delfunction H -delfunction R +Xcheck 212514423 -Xcheck 2000403408 +" Tests 69 to 75 were moved to test_trycatch.vim +let Xtest = 76 "------------------------------------------------------------------------------- @@ -8780,36 +6523,9 @@ delfunction F Xout "No Crash for vimgrep on BufUnload" Xcheck 0 -"------------------------------------------------------------------------------- -" Test 87 using (expr) ? funcref : funcref {{{1 -" -" Vim needs to correctly parse the funcref and even when it does -" not execute the funcref, it needs to consume the trailing () -"------------------------------------------------------------------------------- - -XpathINIT - -func Add2(x1, x2) - return a:x1 + a:x2 -endfu - -func GetStr() - return "abcdefghijklmnopqrstuvwxyp" -endfu - -echo function('Add2')(2,3) +" Test 87 was moved to test_vimscript.vim +let Xtest = 88 -Xout 1 ? function('Add2')(1,2) : function('Add2')(2,3) -Xout 0 ? function('Add2')(1,2) : function('Add2')(2,3) -" Make sure, GetStr() still works. -Xout GetStr()[0:10] - - -delfunction GetStr -delfunction Add2 -Xout "Successfully executed funcref Add2" - -Xcheck 0 "------------------------------------------------------------------------------- " Test 88: $VIMNOERRTHROW and $VIMNOINTTHROW support {{{1 diff --git a/src/nvim/testdir/test_trycatch.vim b/src/nvim/testdir/test_trycatch.vim new file mode 100644 index 0000000000..7e513180a3 --- /dev/null +++ b/src/nvim/testdir/test_trycatch.vim @@ -0,0 +1,1977 @@ +" Test try-catch-finally exception handling +" Most of this was formerly in test49. + +source check.vim +source shared.vim + +"------------------------------------------------------------------------------- +" Test environment {{{1 +"------------------------------------------------------------------------------- + +com! XpathINIT let g:Xpath = '' +com! -nargs=1 -bar Xpath let g:Xpath = g:Xpath . + +" Test 25: Executing :finally clauses on normal control flow {{{1 +" +" Control flow in a :try conditional should always fall through to its +" :finally clause. A :finally clause of a :try conditional inside an +" inactive conditional should never be executed. +"------------------------------------------------------------------------------- + +func T25_F() + let loops = 3 + while loops > 0 + Xpath 'a' . loops + if loops >= 2 + try + Xpath 'b' . loops + if loops == 2 + try + Xpath 'c' . loops + finally + Xpath 'd' . loops + endtry + endif + finally + Xpath 'e' . loops + if loops == 2 + try + Xpath 'f' . loops + finally + Xpath 'g' . loops + endtry + endif + endtry + endif + Xpath 'h' . loops + let loops = loops - 1 + endwhile + Xpath 'i' +endfunc + +func T25_G() + if 1 + try + Xpath 'A' + call T25_F() + Xpath 'B' + finally + Xpath 'C' + endtry + else + try + Xpath 'D' + finally + Xpath 'E' + endtry + endif +endfunc + +func Test_finally() + XpathINIT + call T25_G() + call assert_equal('Aa3b3e3h3a2b2c2d2e2f2g2h2a1h1iBC', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 26: Executing :finally clauses after :continue or :break {{{1 +" +" For a :continue or :break dynamically enclosed in a :try/:endtry +" region inside the next surrounding :while/:endwhile, if the +" :continue/:break is before the :finally, the :finally clause is +" executed first. If the :continue/:break is after the :finally, the +" :finally clause is broken (like an :if/:endif region). +"------------------------------------------------------------------------------- + +func T26_F() + try + let loops = 3 + while loops > 0 + try + try + if loops == 2 + Xpath 'a' . loops + let loops = loops - 1 + continue + elseif loops == 1 + Xpath 'b' . loops + break + finish + endif + Xpath 'c' . loops + endtry + finally + Xpath 'd' . loops + endtry + Xpath 'e' . loops + let loops = loops - 1 + endwhile + Xpath 'f' + finally + Xpath 'g' + let loops = 3 + while loops > 0 + try + finally + try + if loops == 2 + Xpath 'h' . loops + let loops = loops - 1 + continue + elseif loops == 1 + Xpath 'i' . loops + break + finish + endif + endtry + Xpath 'j' . loops + endtry + Xpath 'k' . loops + let loops = loops - 1 + endwhile + Xpath 'l' + endtry + Xpath 'm' +endfunc + +func Test_finally_after_continue() + XpathINIT + call T26_F() + call assert_equal('c3d3e3a2d1b1d1fgj3k3h2i1lm', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 32: Remembering the :return value on :finally {{{1 +" +" If a :finally clause is executed due to a :return specifying +" a value, this is the value visible to the caller if not overwritten +" by a new :return in the :finally clause. A :return without a value +" in the :finally clause overwrites with value 0. +"------------------------------------------------------------------------------- + +func T32_F() + try + Xpath 'a' + try + Xpath 'b' + return "ABCD" + Xpath 'c' + finally + Xpath 'd' + endtry + Xpath 'e' + finally + Xpath 'f' + endtry + Xpath 'g' +endfunc + +func T32_G() + try + Xpath 'h' + return 8 + Xpath 'i' + finally + Xpath 'j' + return 16 + strlen(T32_F()) + Xpath 'k' + endtry + Xpath 'l' +endfunc + +func T32_H() + try + Xpath 'm' + return 32 + Xpath 'n' + finally + Xpath 'o' + return + Xpath 'p' + endtry + Xpath 'q' +endfunc + +func T32_I() + try + Xpath 'r' + finally + Xpath 's' + return T32_G() + T32_H() + 64 + Xpath 't' + endtry + Xpath 'u' +endfunc + +func Test_finally_return() + XpathINIT + call assert_equal(84, T32_I()) + call assert_equal('rshjabdfmo', g:Xpath) +endfunc + +"------------------------------------------------------------------------------- +" Test 33: :return under :execute or user command and :finally {{{1 +" +" A :return command may be executed under an ":execute" or from +" a user command. Executing of :finally clauses and passing through +" the return code works also then. +"------------------------------------------------------------------------------- + +func T33_F() + try + RETURN 10 + Xpath 'a' + finally + Xpath 'b' + endtry + Xpath 'c' +endfunc + +func T33_G() + try + RETURN 20 + Xpath 'd' + finally + Xpath 'e' + RETURN 30 + Xpath 'f' + endtry + Xpath 'g' +endfunc + +func T33_H() + try + execute "try | return 40 | finally | return 50 | endtry" + Xpath 'h' + finally + Xpath 'i' + endtry + Xpath 'j' +endfunc + +func T33_I() + try + execute "try | return 60 | finally | return 70 | endtry" + Xpath 'k' + finally + Xpath 'l' + execute "try | return 80 | finally | return 90 | endtry" + Xpath 'm' + endtry + Xpath 'n' +endfunc + +func T33_J() + try + RETURN 100 + Xpath 'o' + finally + Xpath 'p' + return + Xpath 'q' + endtry + Xpath 'r' +endfunc + +func T33_K() + try + execute "try | return 110 | finally | return 120 | endtry" + Xpath 's' + finally + Xpath 't' + execute "try | return 130 | finally | return | endtry" + Xpath 'u' + endtry + Xpath 'v' +endfunc + +func T33_L() + try + return + Xpath 'w' + finally + Xpath 'x' + RETURN 140 + Xpath 'y' + endtry + Xpath 'z' +endfunc + +func T33_M() + try + return + Xpath 'A' + finally + Xpath 'B' + execute "try | return 150 | finally | return 160 | endtry" + Xpath 'C' + endtry + Xpath 'D' +endfunc + +func T33_N() + RETURN 170 +endfunc + +func T33_O() + execute "try | return 180 | finally | return 190 | endtry" +endfunc + +func Test_finally_cmd_return() + command! -nargs=? RETURN + \ try | return | finally | return * 2 | endtry + XpathINIT + call assert_equal(20, T33_F()) + call assert_equal(60, T33_G()) + call assert_equal(50, T33_H()) + call assert_equal(90, T33_I()) + call assert_equal(0, T33_J()) + call assert_equal(0, T33_K()) + call assert_equal(280, T33_L()) + call assert_equal(160, T33_M()) + call assert_equal(340, T33_N()) + call assert_equal(190, T33_O()) + call assert_equal('beilptxB', g:Xpath) + delcommand RETURN +endfunc + + +"------------------------------------------------------------------------------- +" Test 41: Skipped :throw finding next command {{{1 +" +" A :throw in an inactive conditional must not hide a following +" command. +"------------------------------------------------------------------------------- + +func T41_F() + Xpath 'a' + if 0 | throw 'never' | endif | Xpath 'b' + Xpath 'c' +endfunc + +func T41_G() + Xpath 'd' + while 0 | throw 'never' | endwhile | Xpath 'e' + Xpath 'f' +endfunc + +func T41_H() + Xpath 'g' + if 0 | try | throw 'never' | endtry | endif | Xpath 'h' + Xpath 'i' +endfunc + +func Test_throw_inactive_cond() + XpathINIT + try + Xpath 'j' + call T41_F() + Xpath 'k' + catch /.*/ + Xpath 'l' + call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) + endtry + + try + Xpath 'm' + call T41_G() + Xpath 'n' + catch /.*/ + Xpath 'o' + call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) + endtry + + try + Xpath 'p' + call T41_H() + Xpath 'q' + catch /.*/ + Xpath 'r' + call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) + endtry + + call assert_equal('jabckmdefnpghiq', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 42: Catching number and string exceptions {{{1 +" +" When a number is thrown, it is converted to a string exception. +" Numbers and strings may be caught by specifying a regular exception +" as argument to the :catch command. +"------------------------------------------------------------------------------- + + +func T42_F() + try + + try + Xpath 'a' + throw 4711 + Xpath 'b' + catch /4711/ + Xpath 'c' + endtry + + try + Xpath 'd' + throw 4711 + Xpath 'e' + catch /^4711$/ + Xpath 'f' + endtry + + try + Xpath 'g' + throw 4711 + Xpath 'h' + catch /\d/ + Xpath 'i' + endtry + + try + Xpath 'j' + throw 4711 + Xpath 'k' + catch /^\d\+$/ + Xpath 'l' + endtry + + try + Xpath 'm' + throw "arrgh" + Xpath 'n' + catch /arrgh/ + Xpath 'o' + endtry + + try + Xpath 'p' + throw "arrgh" + Xpath 'q' + catch /^arrgh$/ + Xpath 'r' + endtry + + try + Xpath 's' + throw "arrgh" + Xpath 't' + catch /\l/ + Xpath 'u' + endtry + + try + Xpath 'v' + throw "arrgh" + Xpath 'w' + catch /^\l\+$/ + Xpath 'x' + endtry + + try + try + Xpath 'y' + throw "ARRGH" + Xpath 'z' + catch /^arrgh$/ + Xpath 'A' + endtry + catch /^\carrgh$/ + Xpath 'B' + endtry + + try + Xpath 'C' + throw "" + Xpath 'D' + catch /^$/ + Xpath 'E' + endtry + + catch /.*/ + Xpath 'F' + call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) + endtry +endfunc + +func Test_catch_number_string() + XpathINIT + call T42_F() + call assert_equal('acdfgijlmoprsuvxyBCE', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 43: Selecting the correct :catch clause {{{1 +" +" When an exception is thrown and there are multiple :catch clauses, +" the first matching one is taken. +"------------------------------------------------------------------------------- + +func T43_F() + let loops = 3 + while loops > 0 + try + if loops == 3 + Xpath 'a' . loops + throw "a" + Xpath 'b' . loops + elseif loops == 2 + Xpath 'c' . loops + throw "ab" + Xpath 'd' . loops + elseif loops == 1 + Xpath 'e' . loops + throw "abc" + Xpath 'f' . loops + endif + catch /abc/ + Xpath 'g' . loops + catch /ab/ + Xpath 'h' . loops + catch /.*/ + Xpath 'i' . loops + catch /a/ + Xpath 'j' . loops + endtry + + let loops = loops - 1 + endwhile + Xpath 'k' +endfunc + +func Test_multi_catch() + XpathINIT + call T43_F() + call assert_equal('a3i3c2h2e1g1k', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 44: Missing or empty :catch patterns {{{1 +" +" A missing or empty :catch pattern means the same as /.*/, that is, +" catches everything. To catch only empty exceptions, /^$/ must be +" used. A :catch with missing, empty, or /.*/ argument also works +" when followed by another command separated by a bar on the same +" line. :catch patterns cannot be specified between ||. But other +" pattern separators can be used instead of //. +"------------------------------------------------------------------------------- + +func T44_F() + try + try + Xpath 'a' + throw "" + catch /^$/ + Xpath 'b' + endtry + + try + Xpath 'c' + throw "" + catch /.*/ + Xpath 'd' + endtry + + try + Xpath 'e' + throw "" + catch // + Xpath 'f' + endtry + + try + Xpath 'g' + throw "" + catch + Xpath 'h' + endtry + + try + Xpath 'i' + throw "oops" + catch /^$/ + Xpath 'j' + catch /.*/ + Xpath 'k' + endtry + + try + Xpath 'l' + throw "arrgh" + catch /^$/ + Xpath 'm' + catch // + Xpath 'n' + endtry + + try + Xpath 'o' + throw "brrr" + catch /^$/ + Xpath 'p' + catch + Xpath 'q' + endtry + + try | Xpath 'r' | throw "x" | catch /.*/ | Xpath 's' | endtry + + try | Xpath 't' | throw "y" | catch // | Xpath 'u' | endtry + + while 1 + try + let caught = 0 + let v:errmsg = "" + " Extra try level: if ":catch" without arguments below raises + " a syntax error because it misinterprets the "Xpath" as a pattern, + " let it be caught by the ":catch /.*/" below. + try + try | Xpath 'v' | throw "z" | catch | Xpath 'w' | : + endtry + endtry + catch /.*/ + let caught = 1 + call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) + finally + if $VIMNOERRTHROW && v:errmsg != "" + call assert_report(v:errmsg) + endif + if caught || $VIMNOERRTHROW && v:errmsg != "" + Xpath 'x' + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + let cologne = 4711 + try + try + Xpath 'y' + throw "throw cologne" + " Next lines catches all and throws 4711: + catch |throw cologne| + Xpath 'z' + endtry + catch /4711/ + Xpath 'A' + endtry + + try + Xpath 'B' + throw "plus" + catch +plus+ + Xpath 'C' + endtry + + Xpath 'D' + catch /.*/ + Xpath 'E' + call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) + endtry +endfunc + +func Test_empty_catch() + XpathINIT + call T44_F() + call assert_equal('abcdefghiklnoqrstuvwyABCD', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 45: Catching exceptions from nested :try blocks {{{1 +" +" When :try blocks are nested, an exception is caught by the innermost +" try conditional that has a matching :catch clause. +"------------------------------------------------------------------------------- + +func T45_F() + let loops = 3 + while loops > 0 + try + try + try + try + if loops == 3 + Xpath 'a' . loops + throw "a" + Xpath 'b' . loops + elseif loops == 2 + Xpath 'c' . loops + throw "ab" + Xpath 'd' . loops + elseif loops == 1 + Xpath 'e' . loops + throw "abc" + Xpath 'f' . loops + endif + catch /abc/ + Xpath 'g' . loops + endtry + catch /ab/ + Xpath 'h' . loops + endtry + catch /.*/ + Xpath 'i' . loops + endtry + catch /a/ + Xpath 'j' . loops + endtry + + let loops = loops - 1 + endwhile + Xpath 'k' +endfunc + +func Test_catch_from_nested_try() + XpathINIT + call T45_F() + call assert_equal('a3i3c2h2e1g1k', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 46: Executing :finally after a :throw in nested :try {{{1 +" +" When an exception is thrown from within nested :try blocks, the +" :finally clauses of the non-catching try conditionals should be +" executed before the matching :catch of the next surrounding :try +" gets the control. If this also has a :finally clause, it is +" executed afterwards. +"------------------------------------------------------------------------------- + +func T46_F() + let sum = 0 + + try + Xpath 'a' + try + Xpath 'b' + try + Xpath 'c' + try + Xpath 'd' + throw "ABC" + Xpath 'e' + catch /xyz/ + Xpath 'f' + finally + Xpath 'g' + if sum != 0 + Xpath 'h' + endif + let sum = sum + 1 + endtry + Xpath 'i' + catch /123/ + Xpath 'j' + catch /321/ + Xpath 'k' + finally + Xpath 'l' + if sum != 1 + Xpath 'm' + endif + let sum = sum + 2 + endtry + Xpath 'n' + finally + Xpath 'o' + if sum != 3 + Xpath 'p' + endif + let sum = sum + 4 + endtry + Xpath 'q' + catch /ABC/ + Xpath 'r' + if sum != 7 + Xpath 's' + endif + let sum = sum + 8 + finally + Xpath 't' + if sum != 15 + Xpath 'u' + endif + let sum = sum + 16 + endtry + Xpath 'v' + if sum != 31 + Xpath 'w' + endif +endfunc + +func Test_finally_after_throw() + XpathINIT + call T46_F() + call assert_equal('abcdglortv', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 47: Throwing exceptions from a :catch clause {{{1 +" +" When an exception is thrown from a :catch clause, it should not be +" caught by a :catch of the same :try conditional. After executing +" the :finally clause (if present), surrounding try conditionals +" should be checked for a matching :catch. +"------------------------------------------------------------------------------- + +func T47_F() + Xpath 'a' + try + Xpath 'b' + try + Xpath 'c' + try + Xpath 'd' + throw "x1" + Xpath 'e' + catch /x1/ + Xpath 'f' + try + Xpath 'g' + throw "x2" + Xpath 'h' + catch /x1/ + Xpath 'i' + catch /x2/ + Xpath 'j' + try + Xpath 'k' + throw "x3" + Xpath 'l' + catch /x1/ + Xpath 'm' + catch /x2/ + Xpath 'n' + finally + Xpath 'o' + endtry + Xpath 'p' + catch /x3/ + Xpath 'q' + endtry + Xpath 'r' + catch /x1/ + Xpath 's' + catch /x2/ + Xpath 't' + catch /x3/ + Xpath 'u' + finally + Xpath 'v' + endtry + Xpath 'w' + catch /x1/ + Xpath 'x' + catch /x2/ + Xpath 'y' + catch /x3/ + Xpath 'z' + endtry + Xpath 'A' + catch /.*/ + Xpath 'B' + call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) + endtry + Xpath 'C' +endfunc + +func Test_throw_from_catch() + XpathINIT + call T47_F() + call assert_equal('abcdfgjkovzAC', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 48: Throwing exceptions from a :finally clause {{{1 +" +" When an exception is thrown from a :finally clause, it should not be +" caught by a :catch of the same :try conditional. Surrounding try +" conditionals should be checked for a matching :catch. A previously +" thrown exception is discarded. +"------------------------------------------------------------------------------- + +func T48_F() + try + + try + try + Xpath 'a' + catch /x1/ + Xpath 'b' + finally + Xpath 'c' + throw "x1" + Xpath 'd' + endtry + Xpath 'e' + catch /x1/ + Xpath 'f' + endtry + Xpath 'g' + + try + try + Xpath 'h' + throw "x2" + Xpath 'i' + catch /x2/ + Xpath 'j' + catch /x3/ + Xpath 'k' + finally + Xpath 'l' + throw "x3" + Xpath 'm' + endtry + Xpath 'n' + catch /x2/ + Xpath 'o' + catch /x3/ + Xpath 'p' + endtry + Xpath 'q' + + try + try + try + Xpath 'r' + throw "x4" + Xpath 's' + catch /x5/ + Xpath 't' + finally + Xpath 'u' + throw "x5" " discards 'x4' + Xpath 'v' + endtry + Xpath 'w' + catch /x4/ + Xpath 'x' + finally + Xpath 'y' + endtry + Xpath 'z' + catch /x5/ + Xpath 'A' + endtry + Xpath 'B' + + catch /.*/ + Xpath 'C' + call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) + endtry + Xpath 'D' +endfunc + +func Test_throw_from_finally() + XpathINIT + call T48_F() + call assert_equal('acfghjlpqruyABD', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 51: Throwing exceptions across :execute and user commands {{{1 +" +" A :throw command may be executed under an ":execute" or from +" a user command. +"------------------------------------------------------------------------------- + +func T51_F() + command! -nargs=? THROW1 throw | throw 1 + command! -nargs=? THROW2 try | throw | endtry | throw 2 + command! -nargs=? THROW3 try | throw 3 | catch /3/ | throw | endtry + command! -nargs=? THROW4 try | throw 4 | finally | throw | endtry + + try + + try + try + Xpath 'a' + THROW1 "A" + catch /A/ + Xpath 'b' + endtry + catch /1/ + Xpath 'c' + endtry + + try + try + Xpath 'd' + THROW2 "B" + catch /B/ + Xpath 'e' + endtry + catch /2/ + Xpath 'f' + endtry + + try + try + Xpath 'g' + THROW3 "C" + catch /C/ + Xpath 'h' + endtry + catch /3/ + Xpath 'i' + endtry + + try + try + Xpath 'j' + THROW4 "D" + catch /D/ + Xpath 'k' + endtry + catch /4/ + Xpath 'l' + endtry + + try + try + Xpath 'm' + execute 'throw "E" | throw 5' + catch /E/ + Xpath 'n' + endtry + catch /5/ + Xpath 'o' + endtry + + try + try + Xpath 'p' + execute 'try | throw "F" | endtry | throw 6' + catch /F/ + Xpath 'q' + endtry + catch /6/ + Xpath 'r' + endtry + + try + try + Xpath 's' + execute'try | throw 7 | catch /7/ | throw "G" | endtry' + catch /G/ + Xpath 't' + endtry + catch /7/ + Xpath 'u' + endtry + + try + try + Xpath 'v' + execute 'try | throw 8 | finally | throw "H" | endtry' + catch /H/ + Xpath 'w' + endtry + catch /8/ + Xpath 'x' + endtry + + catch /.*/ + Xpath 'y' + call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) + endtry + + Xpath 'z' + + delcommand THROW1 + delcommand THROW2 + delcommand THROW3 + delcommand THROW4 +endfunc + +func Test_throw_across_commands() + XpathINIT + call T51_F() + call assert_equal('abdeghjkmnpqstvwz', g:Xpath) +endfunc + + + +"------------------------------------------------------------------------------- +" Test 69: :throw across :if, :elseif, :while {{{1 +" +" On an :if, :elseif, or :while command, an exception might be thrown +" during evaluation of the expression to test. The exception can be +" caught by the script. +"------------------------------------------------------------------------------- + +func T69_throw(x) + Xpath 'x' + throw a:x +endfunc + +func Test_throw_ifelsewhile() + XpathINIT + + try + try + Xpath 'a' + if 111 == T69_throw("if") + 111 + Xpath 'b' + else + Xpath 'c' + endif + Xpath 'd' + catch /^if$/ + Xpath 'e' + catch /.*/ + Xpath 'f' + call assert_report("if: " . v:exception . " in " . v:throwpoint) + endtry + + try + Xpath 'g' + if v:false + Xpath 'h' + elseif 222 == T69_throw("elseif") + 222 + Xpath 'i' + else + Xpath 'j' + endif + Xpath 'k' + catch /^elseif$/ + Xpath 'l' + catch /.*/ + Xpath 'm' + call assert_report("elseif: " . v:exception . " in " . v:throwpoint) + endtry + + try + Xpath 'n' + while 333 == T69_throw("while") + 333 + Xpath 'o' + break + endwhile + Xpath 'p' + catch /^while$/ + Xpath 'q' + catch /.*/ + Xpath 'r' + call assert_report("while: " .. v:exception .. " in " .. v:throwpoint) + endtry + catch /^0$/ " default return value + Xpath 's' + call assert_report(v:throwpoint) + catch /.*/ + call assert_report(v:exception .. " in " .. v:throwpoint) + Xpath 't' + endtry + + call assert_equal('axegxlnxq', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 70: :throw across :return or :throw {{{1 +" +" On a :return or :throw command, an exception might be thrown during +" evaluation of the expression to return or throw, respectively. The +" exception can be caught by the script. +"------------------------------------------------------------------------------- + +let T70_taken = "" + +func T70_throw(x, n) + let g:T70_taken = g:T70_taken . "T" . a:n + throw a:x +endfunc + +func T70_F(x, y, n) + let g:T70_taken = g:T70_taken . "F" . a:n + return a:x + T70_throw(a:y, a:n) +endfunc + +func T70_G(x, y, n) + let g:T70_taken = g:T70_taken . "G" . a:n + throw a:x . T70_throw(a:y, a:n) + return a:x +endfunc + +func Test_throwreturn() + XpathINIT + + try + try + Xpath 'a' + call T70_F(4711, "return", 1) + Xpath 'b' + catch /^return$/ + Xpath 'c' + catch /.*/ + Xpath 'd' + call assert_report("return: " .. v:exception .. " in " .. v:throwpoint) + endtry + + try + Xpath 'e' + let var = T70_F(4712, "return-var", 2) + Xpath 'f' + catch /^return-var$/ + Xpath 'g' + catch /.*/ + Xpath 'h' + call assert_report("return-var: " . v:exception . " in " . v:throwpoint) + finally + unlet! var + endtry + + try + Xpath 'i' + throw "except1" . T70_throw("throw1", 3) + Xpath 'j' + catch /^except1/ + Xpath 'k' + catch /^throw1$/ + Xpath 'l' + catch /.*/ + Xpath 'm' + call assert_report("throw1: " .. v:exception .. " in " .. v:throwpoint) + endtry + + try + Xpath 'n' + call T70_G("except2", "throw2", 4) + Xpath 'o' + catch /^except2/ + Xpath 'p' + catch /^throw2$/ + Xpath 'q' + catch /.*/ + Xpath 'r' + call assert_report("throw2: " .. v:exception .. " in " .. v:throwpoint) + endtry + + try + Xpath 's' + let var = T70_G("except3", "throw3", 5) + Xpath 't' + catch /^except3/ + Xpath 'u' + catch /^throw3$/ + Xpath 'v' + catch /.*/ + Xpath 'w' + call assert_report("throw3: " .. v:exception .. " in " .. v:throwpoint) + finally + unlet! var + endtry + + call assert_equal('F1T1F2T2T3G4T4G5T5', g:T70_taken) + Xpath 'x' + catch /^0$/ " default return value + Xpath 'y' + call assert_report(v:throwpoint) + catch /.*/ + Xpath 'z' + call assert_report('Caught' .. v:exception .. ' in ' .. v:throwpoint) + endtry + + call assert_equal('acegilnqsvx', g:Xpath) +endfunc + +"------------------------------------------------------------------------------- +" Test 71: :throw across :echo variants and :execute {{{1 +" +" On an :echo, :echon, :echomsg, :echoerr, or :execute command, an +" exception might be thrown during evaluation of the arguments to +" be displayed or executed as a command, respectively. Any following +" arguments are not evaluated, then. The exception can be caught by +" the script. +"------------------------------------------------------------------------------- + +let T71_taken = "" + +func T71_throw(x, n) + let g:T71_taken = g:T71_taken . "T" . a:n + throw a:x +endfunc + +func T71_F(n) + let g:T71_taken = g:T71_taken . "F" . a:n + return "F" . a:n +endfunc + +func Test_throw_echo() + XpathINIT + + try + try + Xpath 'a' + echo 'echo ' . T71_throw("echo-except", 1) . T71_F(1) + Xpath 'b' + catch /^echo-except$/ + Xpath 'c' + catch /.*/ + Xpath 'd' + call assert_report("echo: " .. v:exception .. " in " .. v:throwpoint) + endtry + + try + Xpath 'e' + echon "echon " . T71_throw("echon-except", 2) . T71_F(2) + Xpath 'f' + catch /^echon-except$/ + Xpath 'g' + catch /.*/ + Xpath 'h' + call assert_report('echon: ' . v:exception . ' in ' . v:throwpoint) + endtry + + try + Xpath 'i' + echomsg "echomsg " . T71_throw("echomsg-except", 3) . T71_F(3) + Xpath 'j' + catch /^echomsg-except$/ + Xpath 'k' + catch /.*/ + Xpath 'l' + call assert_report('echomsg: ' . v:exception . ' in ' . v:throwpoint) + endtry + + try + Xpath 'm' + echoerr "echoerr " . T71_throw("echoerr-except", 4) . T71_F(4) + Xpath 'n' + catch /^echoerr-except$/ + Xpath 'o' + catch /Vim/ + Xpath 'p' + catch /echoerr/ + Xpath 'q' + catch /.*/ + Xpath 'r' + call assert_report('echoerr: ' . v:exception . ' in ' . v:throwpoint) + endtry + + try + Xpath 's' + execute "echo 'execute " . T71_throw("execute-except", 5) . T71_F(5) "'" + Xpath 't' + catch /^execute-except$/ + Xpath 'u' + catch /.*/ + Xpath 'v' + call assert_report('execute: ' . v:exception . ' in ' . v:throwpoint) + endtry + + call assert_equal('T1T2T3T4T5', g:T71_taken) + Xpath 'w' + catch /^0$/ " default return value + Xpath 'x' + call assert_report(v:throwpoint) + catch /.*/ + Xpath 'y' + call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) + endtry + + call assert_equal('acegikmosuw', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 72: :throw across :let or :unlet {{{1 +" +" On a :let command, an exception might be thrown during evaluation +" of the expression to assign. On an :let or :unlet command, the +" evaluation of the name of the variable to be assigned or list or +" deleted, respectively, may throw an exception. Any following +" arguments are not evaluated, then. The exception can be caught by +" the script. +"------------------------------------------------------------------------------- + +let throwcount = 0 + +func T72_throw(x) + let g:throwcount = g:throwcount + 1 + throw a:x +endfunc + +let T72_addpath = '' + +func T72_addpath(p) + let g:T72_addpath = g:T72_addpath . a:p +endfunc + +func Test_throw_let() + XpathINIT + + try + try + let $VAR = 'old_value' + Xpath 'a' + let $VAR = 'let(' . T72_throw('var') . ')' + Xpath 'b' + catch /^var$/ + Xpath 'c' + finally + call assert_equal('old_value', $VAR) + endtry + + try + let @a = 'old_value' + Xpath 'd' + let @a = 'let(' . T72_throw('reg') . ')' + Xpath 'e' + catch /^reg$/ + try + Xpath 'f' + let @A = 'let(' . T72_throw('REG') . ')' + Xpath 'g' + catch /^REG$/ + Xpath 'h' + endtry + finally + call assert_equal('old_value', @a) + call assert_equal('old_value', @A) + endtry + + try + let saved_gpath = &g:path + let saved_lpath = &l:path + Xpath 'i' + let &path = 'let(' . T72_throw('opt') . ')' + Xpath 'j' + catch /^opt$/ + try + Xpath 'k' + let &g:path = 'let(' . T72_throw('gopt') . ')' + Xpath 'l' + catch /^gopt$/ + try + Xpath 'm' + let &l:path = 'let(' . T72_throw('lopt') . ')' + Xpath 'n' + catch /^lopt$/ + Xpath 'o' + endtry + endtry + finally + call assert_equal(saved_gpath, &g:path) + call assert_equal(saved_lpath, &l:path) + let &g:path = saved_gpath + let &l:path = saved_lpath + endtry + + unlet! var1 var2 var3 + + try + Xpath 'p' + let var1 = 'let(' . T72_throw('var1') . ')' + Xpath 'q' + catch /^var1$/ + Xpath 'r' + finally + call assert_true(!exists('var1')) + endtry + + try + let var2 = 'old_value' + Xpath 's' + let var2 = 'let(' . T72_throw('var2'). ')' + Xpath 't' + catch /^var2$/ + Xpath 'u' + finally + call assert_equal('old_value', var2) + endtry + + try + Xpath 'v' + let var{T72_throw('var3')} = 4711 + Xpath 'w' + catch /^var3$/ + Xpath 'x' + endtry + + try + call T72_addpath('T1') + let var{T72_throw('var4')} var{T72_addpath('T2')} | call T72_addpath('T3') + call T72_addpath('T4') + catch /^var4$/ + call T72_addpath('T5') + endtry + + try + call T72_addpath('T6') + unlet var{T72_throw('var5')} var{T72_addpath('T7')} + \ | call T72_addpath('T8') + call T72_addpath('T9') + catch /^var5$/ + call T72_addpath('T10') + endtry + + call assert_equal('T1T5T6T10', g:T72_addpath) + call assert_equal(11, g:throwcount) + catch /.*/ + call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) + endtry + + call assert_equal('acdfhikmoprsuvx', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 73: :throw across :function, :delfunction {{{1 +" +" The :function and :delfunction commands may cause an expression +" specified in braces to be evaluated. During evaluation, an +" exception might be thrown. The exception can be caught by the +" script. +"------------------------------------------------------------------------------- + +let T73_taken = '' + +func T73_throw(x, n) + let g:T73_taken = g:T73_taken . 'T' . a:n + throw a:x +endfunc + +func T73_expr(x, n) + let g:T73_taken = g:T73_taken . 'E' . a:n + if a:n % 2 == 0 + call T73_throw(a:x, a:n) + endif + return 2 - a:n % 2 +endfunc + +func Test_throw_func() + XpathINIT + + try + try + " Define function. + Xpath 'a' + function! F0() + endfunction + Xpath 'b' + function! F{T73_expr('function-def-ok', 1)}() + endfunction + Xpath 'c' + function! F{T73_expr('function-def', 2)}() + endfunction + Xpath 'd' + catch /^function-def-ok$/ + Xpath 'e' + catch /^function-def$/ + Xpath 'f' + catch /.*/ + call assert_report('def: ' . v:exception . ' in ' . v:throwpoint) + endtry + + try + " List function. + Xpath 'g' + function F0 + Xpath 'h' + function F{T73_expr('function-lst-ok', 3)} + Xpath 'i' + function F{T73_expr('function-lst', 4)} + Xpath 'j' + catch /^function-lst-ok$/ + Xpath 'k' + catch /^function-lst$/ + Xpath 'l' + catch /.*/ + call assert_report('lst: ' . v:exception . ' in ' . v:throwpoint) + endtry + + try + " Delete function + Xpath 'm' + delfunction F0 + Xpath 'n' + delfunction F{T73_expr('function-del-ok', 5)} + Xpath 'o' + delfunction F{T73_expr('function-del', 6)} + Xpath 'p' + catch /^function-del-ok$/ + Xpath 'q' + catch /^function-del$/ + Xpath 'r' + catch /.*/ + call assert_report('del: ' . v:exception . ' in ' . v:throwpoint) + endtry + call assert_equal('E1E2T2E3E4T4E5E6T6', g:T73_taken) + catch /.*/ + call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) + endtry + + call assert_equal('abcfghilmnor', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 74: :throw across builtin functions and commands {{{1 +" +" Some functions like exists(), searchpair() take expression +" arguments, other functions or commands like substitute() or +" :substitute cause an expression (specified in the regular +" expression) to be evaluated. During evaluation an exception +" might be thrown. The exception can be caught by the script. +"------------------------------------------------------------------------------- + +let T74_taken = "" + +func T74_throw(x, n) + let g:T74_taken = g:T74_taken . "T" . a:n + throw a:x +endfunc + +func T74_expr(x, n) + let g:T74_taken = g:T74_taken . "E" . a:n + call T74_throw(a:x . a:n, a:n) + return "EXPR" +endfunc + +func T74_skip(x, n) + let g:T74_taken = g:T74_taken . "S" . a:n . "(" . line(".") + let theline = getline(".") + if theline =~ "skip" + let g:T74_taken = g:T74_taken . "s)" + return 1 + elseif theline =~ "throw" + let g:T74_taken = g:T74_taken . "t)" + call T74_throw(a:x . a:n, a:n) + else + let g:T74_taken = g:T74_taken . ")" + return 0 + endif +endfunc + +func T74_subst(x, n) + let g:T74_taken = g:T74_taken . "U" . a:n . "(" . line(".") + let theline = getline(".") + if theline =~ "not" " T74_subst() should not be called for this line + let g:T74_taken = g:T74_taken . "n)" + call T74_throw(a:x . a:n, a:n) + elseif theline =~ "throw" + let g:T74_taken = g:T74_taken . "t)" + call T74_throw(a:x . a:n, a:n) + else + let g:T74_taken = g:T74_taken . ")" + return "replaced" + endif +endfunc + +func Test_throw_builtin_func() + XpathINIT + + try + try + Xpath 'a' + let result = exists('*{T74_expr("exists", 1)}') + Xpath 'b' + catch /^exists1$/ + Xpath 'c' + try + let result = exists('{T74_expr("exists", 2)}') + Xpath 'd' + catch /^exists2$/ + Xpath 'e' + catch /.*/ + call assert_report('exists2: ' . v:exception . ' in ' . v:throwpoint) + endtry + catch /.*/ + call assert_report('exists1: ' . v:exception . ' in ' . v:throwpoint) + endtry + + try + let file = tempname() + exec "edit" file + call append(0, [ + \ 'begin', + \ 'xx', + \ 'middle 3', + \ 'xx', + \ 'middle 5 skip', + \ 'xx', + \ 'middle 7 throw', + \ 'xx', + \ 'end']) + normal! gg + Xpath 'f' + let result = searchpair("begin", "middle", "end", '', + \ 'T74_skip("searchpair", 3)') + Xpath 'g' + let result = searchpair("begin", "middle", "end", '', + \ 'T74_skip("searchpair", 4)') + Xpath 'h' + let result = searchpair("begin", "middle", "end", '', + \ 'T74_skip("searchpair", 5)') + Xpath 'i' + catch /^searchpair[35]$/ + Xpath 'j' + catch /^searchpair4$/ + Xpath 'k' + catch /.*/ + call assert_report('searchpair: ' . v:exception . ' in ' . v:throwpoint) + finally + bwipeout! + call delete(file) + endtry + + try + let file = tempname() + exec "edit" file + call append(0, [ + \ 'subst 1', + \ 'subst 2', + \ 'not', + \ 'subst 4', + \ 'subst throw', + \ 'subst 6']) + normal! gg + Xpath 'l' + 1,2substitute/subst/\=T74_subst("substitute", 6)/ + try + Xpath 'm' + try + let v:errmsg = "" + 3substitute/subst/\=T74_subst("substitute", 7)/ + finally + if v:errmsg != "" + " If exceptions are not thrown on errors, fake the error + " exception in order to get the same execution path. + throw "faked Vim(substitute)" + endif + endtry + catch /Vim(substitute)/ " Pattern not found ('e' flag missing) + Xpath 'n' + 3substitute/subst/\=T74_subst("substitute", 8)/e + Xpath 'o' + endtry + Xpath 'p' + 4,6substitute/subst/\=T74_subst("substitute", 9)/ + Xpath 'q' + catch /^substitute[678]/ + Xpath 'r' + catch /^substitute9/ + Xpath 's' + finally + bwipeout! + call delete(file) + endtry + + try + Xpath 't' + let var = substitute("sub", "sub", '\=T74_throw("substitute()y", 10)', '') + Xpath 'u' + catch /substitute()y/ + Xpath 'v' + catch /.*/ + call assert_report('substitute()y: ' . v:exception . ' in ' + \ . v:throwpoint) + endtry + + try + Xpath 'w' + let var = substitute("not", "sub", '\=T74_throw("substitute()n", 11)', '') + Xpath 'x' + catch /substitute()n/ + Xpath 'y' + catch /.*/ + call assert_report('substitute()n: ' . v:exception . ' in ' + \ . v:throwpoint) + endtry + + call assert_equal('E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10', + \ g:T74_taken) + + catch /.*/ + call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) + endtry + + call assert_equal('acefgklmnopstvwx', g:Xpath) +endfunc + + +"------------------------------------------------------------------------------- +" Test 75: Errors in builtin functions. {{{1 +" +" On an error in a builtin function called inside a :try/:endtry +" region, the evaluation of the expression calling that function and +" the command containing that expression are abandoned. The error can +" be caught as an exception. +" +" A simple :call of the builtin function is a trivial case. If the +" builtin function is called in the argument list of another function, +" no further arguments are evaluated, and the other function is not +" executed. If the builtin function is called from the argument of +" a :return command, the :return command is not executed. If the +" builtin function is called from the argument of a :throw command, +" the :throw command is not executed. The evaluation of the +" expression calling the builtin function is abandoned. +"------------------------------------------------------------------------------- + +func T75_F1(arg1) + Xpath 'a' +endfunc + +func T75_F2(arg1, arg2) + Xpath 'b' +endfunc + +func T75_G() + Xpath 'c' +endfunc + +func T75_H() + Xpath 'd' +endfunc + +func T75_R() + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 'e' + return append(1, "s") + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 'f' + finally + Xpath 'g' + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 'h' + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + Xpath 'i' +endfunc + +func Test_builtin_func_error() + XpathINIT + + try + set noma " let append() fail with "E21" + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 'j' + call append(1, "s") + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 'k' + finally + Xpath 'l' + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 'm' + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 'n' + call T75_F1('x' . append(1, "s")) + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 'o' + finally + Xpath 'p' + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 'q' + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 'r' + call T75_F2('x' . append(1, "s"), T75_G()) + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 's' + finally + Xpath 't' + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 'u' + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + call T75_R() + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 'v' + throw "T" . append(1, "s") + catch /E21/ + let caught = 1 + catch /^T.*/ + Xpath 'w' + catch /.*/ + Xpath 'x' + finally + Xpath 'y' + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 'z' + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 'A' + let x = "a" + let x = x . "b" . append(1, "s") . T75_H() + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 'B' + finally + Xpath 'C' + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 'D' + endif + call assert_equal('a', x) + break " discard error for $VIMNOERRTHROW + endtry + endwhile + catch /.*/ + call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint) + finally + set ma& + endtry + + call assert_equal('jlmnpqrtueghivyzACD', g:Xpath) +endfunc + +" Modelines {{{1 +" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker +"------------------------------------------------------------------------------- diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim index 4edf8308e7..43907de1d9 100644 --- a/src/nvim/testdir/test_vimscript.vim +++ b/src/nvim/testdir/test_vimscript.vim @@ -919,9 +919,203 @@ func Test_if_bar_fail() call assert_equal('acdfh-acfh', g:test15_result) endfunc +"------------------------------------------------------------------------------- +" Test 16: Double :else or :elseif after :else {{{1 +" +" Multiple :elses or an :elseif after an :else are forbidden. +"------------------------------------------------------------------------------- + +func T16_F() abort + if 0 + Xpath 'a' + else + Xpath 'b' + else " aborts function + Xpath 'c' + endif + Xpath 'd' +endfunc + +func T16_G() abort + if 0 + Xpath 'a' + else + Xpath 'b' + elseif 1 " aborts function + Xpath 'c' + else + Xpath 'd' + endif + Xpath 'e' +endfunc + +func T16_H() abort + if 0 + Xpath 'a' + elseif 0 + Xpath 'b' + else + Xpath 'c' + else " aborts function + Xpath 'd' + endif + Xpath 'e' +endfunc + +func T16_I() abort + if 0 + Xpath 'a' + elseif 0 + Xpath 'b' + else + Xpath 'c' + elseif 1 " aborts function + Xpath 'd' + else + Xpath 'e' + endif + Xpath 'f' +endfunc + +func Test_Multi_Else() + XpathINIT + try + call T16_F() + catch /E583:/ + Xpath 'e' + endtry + call assert_equal('be', g:Xpath) + + XpathINIT + try + call T16_G() + catch /E584:/ + Xpath 'f' + endtry + call assert_equal('bf', g:Xpath) + + XpathINIT + try + call T16_H() + catch /E583:/ + Xpath 'f' + endtry + call assert_equal('cf', g:Xpath) + + XpathINIT + try + call T16_I() + catch /E584:/ + Xpath 'g' + endtry + call assert_equal('cg', g:Xpath) +endfunc + +"------------------------------------------------------------------------------- +" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1 +" +" The :while/:endwhile takes precedence in nesting over an unclosed +" :if or an unopened :endif. +"------------------------------------------------------------------------------- + +" While loops inside a function are continued on error. +func T17_F() + let loops = 3 + while loops > 0 + let loops -= 1 + Xpath 'a' . loops + if (loops == 1) + Xpath 'b' . loops + continue + elseif (loops == 0) + Xpath 'c' . loops + break + elseif 1 + Xpath 'd' . loops + " endif missing! + endwhile " :endwhile after :if 1 + Xpath 'e' +endfunc + +func T17_G() + let loops = 2 + while loops > 0 + let loops -= 1 + Xpath 'a' . loops + if 0 + Xpath 'b' . loops + " endif missing + endwhile " :endwhile after :if 0 +endfunc + +func T17_H() + let loops = 2 + while loops > 0 + let loops -= 1 + Xpath 'a' . loops + " if missing! + endif " :endif without :if in while + Xpath 'b' . loops + endwhile +endfunc + +" Error continuation outside a function is at the outermost :endwhile or :endif. +XpathINIT +let v:errmsg = '' +let loops = 2 +while loops > 0 + let loops -= 1 + Xpath 'a' . loops + if 0 + Xpath 'b' . loops + " endif missing! Following :endwhile fails. +endwhile | Xpath 'c' +Xpath 'd' +call assert_match('E171:', v:errmsg) +call assert_equal('a1d', g:Xpath) + +func Test_unmatched_if_in_while() + XpathINIT + call assert_fails('call T17_F()', 'E171:') + call assert_equal('a2d2a1b1a0c0e', g:Xpath) + + XpathINIT + call assert_fails('call T17_G()', 'E171:') + call assert_equal('a1a0', g:Xpath) + + XpathINIT + call assert_fails('call T17_H()', 'E580:') + call assert_equal('a1b1a0b0', g:Xpath) +endfunc + +"------------------------------------------------------------------------------- +"------------------------------------------------------------------------------- +"------------------------------------------------------------------------------- +" Test 87 using (expr) ? funcref : funcref {{{1 +" +" Vim needs to correctly parse the funcref and even when it does +" not execute the funcref, it needs to consume the trailing () +"------------------------------------------------------------------------------- + +func Add2(x1, x2) + return a:x1 + a:x2 +endfu + +func GetStr() + return "abcdefghijklmnopqrstuvwxyp" +endfu + +func Test_funcref_with_condexpr() + call assert_equal(5, function('Add2')(2,3)) + + call assert_equal(3, 1 ? function('Add2')(1,2) : function('Add2')(2,3)) + call assert_equal(5, 0 ? function('Add2')(1,2) : function('Add2')(2,3)) + " Make sure, GetStr() still works. + call assert_equal('abcdefghijk', GetStr()[0:10]) +endfunc "------------------------------------------------------------------------------- -" Test 16: Recognizing {} in variable name. {{{1 +" Test 90: Recognizing {} in variable name. {{{1 "------------------------------------------------------------------------------- func Test_curlies() @@ -1490,5 +1684,5 @@ endfunc "------------------------------------------------------------------------------- " Modelines {{{1 -" vim: ts=8 sw=4 tw=80 fdm=marker +" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker "------------------------------------------------------------------------------- -- cgit