changeset 18504:ece46bd3c9af v8.1.2246

patch 8.1.2246: some tests are still in old style Commit: https://github.com/vim/vim/commit/1f068233c101ecf5966e6df14853fe68f08175a7 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Nov 3 16:17:26 2019 +0100 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)
author Bram Moolenaar <Bram@vim.org>
date Sun, 03 Nov 2019 16:30:03 +0100
parents d946c71f8b4c
children 81ee9de74877
files src/testdir/Make_all.mak src/testdir/test49.ok src/testdir/test49.vim src/testdir/test_trycatch.vim src/testdir/test_vimscript.vim src/version.c
diffstat 6 files changed, 2192 insertions(+), 2333 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -267,6 +267,7 @@ NEW_TESTS = \
 	test_textprop \
 	test_timers \
 	test_true_false \
+	test_trycatch \
 	test_undo \
 	test_unlet \
 	test_user_func \
@@ -433,6 +434,7 @@ NEW_TESTS_RES = \
 	test_textformat.res \
 	test_textobjects.res \
 	test_textprop.res \
+	test_trycatch.res \
 	test_undo.res \
 	test_user_func.res \
 	test_usercommands.res \
--- a/src/testdir/test49.ok
+++ b/src/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.
--- a/src/testdir/test49.vim
+++ b/src/testdir/test49.vim
@@ -1,6 +1,6 @@
 " Vim script language tests
 " Author:	Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com>
-" Last Change:	2019 Oct 08
+" Last Change:	2019 Nov 03
 
 "-------------------------------------------------------------------------------
 " Test environment							    {{{1
@@ -608,196 +608,8 @@ com! -nargs=1 -bar ExecAsScript call Exe
 " 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,252 +1463,8 @@ endif
 
 Xcheck 190905173
 
-
-"-------------------------------------------------------------------------------
-" Test 32:  Remembering the :return value on :finally			    {{{1
-"
-"	    If a :finally clause is executed due to a :return specifying
-"	    a value, this is the value visible to the caller if not overwritten
-"	    by a new :return in the :finally clause.  A :return without a value
-"	    in the :finally clause overwrites with value 0.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-function! F()
-    try
-	Xpath 1					" X: 1
-	try
-	    Xpath 2				" X: 2
-	    return "ABCD"
-	    Xpath 4				" X: 0
-	finally
-	    Xpath 8				" X: 8
-	endtry
-	Xpath 16				" X: 0
-    finally
-	Xpath 32				" X: 32
-    endtry
-    Xpath 64					" X: 0
-endfunction
-
-function! G()
-    try
-	Xpath 128				" X: 128
-	return 8
-	Xpath 256				" X: 0
-    finally
-	Xpath 512				" X: 512
-	return 16 + strlen(F())
-	Xpath 1024				" X: 0
-    endtry
-    Xpath 2048					" X: 0
-endfunction
-
-function! H()
-    try
-	Xpath 4096				" X: 4096
-	return 32
-	Xpath 8192				" X: 0
-    finally
-	Xpath 16384				" X: 16384
-	return
-	Xpath 32768				" X: 0
-    endtry
-    Xpath 65536					" X: 0
-endfunction
-
-function! I()
-    try
-	Xpath 131072				" X: 131072
-    finally
-	Xpath 262144				" X: 262144
-	return G() + H() + 64
-	Xpath 524288				" X: 0
-    endtry
-    Xpath 1048576				" X: 0
-endfunction
-
-let retcode = I()
-Xpath 2097152					" X: 2097152
-
-if retcode < 0
-    Xpath 4194304				" X: 0
-endif
-if retcode % 4
-    Xpath 8388608				" X: 0
-endif
-if (retcode/4) % 2
-    Xpath 16777216				" X: 16777216
-endif
-if (retcode/8) % 2
-    Xpath 33554432				" X: 0
-endif
-if (retcode/16) % 2
-    Xpath 67108864				" X: 67108864
-endif
-if (retcode/32) % 2
-    Xpath 134217728				" X: 0
-endif
-if (retcode/64) % 2
-    Xpath 268435456				" X: 268435456
-endif
-if retcode/128
-    Xpath 536870912				" X: 0
-endif
-
-unlet retcode
-delfunction F
-delfunction G
-delfunction H
-delfunction I
-
-Xcheck 354833067
-
-
-"-------------------------------------------------------------------------------
-" Test 33:  :return under :execute or user command and :finally		    {{{1
-"
-"	    A :return command may be executed under an ":execute" or from
-"	    a user command.  Executing of :finally clauses and passing through
-"	    the return code works also then.
-"-------------------------------------------------------------------------------
-XpathINIT
-
-command! -nargs=? RETURN
-    \ try | return <args> | finally | return <args> * 2 | endtry
-
-function! F()
-    try
-	RETURN 8
-	Xpath 1					" X: 0
-    finally
-	Xpath 2					" X: 2
-    endtry
-    Xpath 4					" X: 0
-endfunction
-
-function! G()
-    try
-	RETURN 32
-	Xpath 8					" X: 0
-    finally
-	Xpath 16				" X: 16
-	RETURN 128
-	Xpath 32				" X: 0
-    endtry
-    Xpath 64					" X: 0
-endfunction
-
-function! H()
-    try
-	execute "try | return 512 | finally | return 1024 | endtry"
-	Xpath 128				" X: 0
-    finally
-	Xpath 256				" X: 256
-    endtry
-    Xpath 512					" X: 0
-endfunction
-
-function! I()
-    try
-	execute "try | return 2048 | finally | return 4096 | endtry"
-	Xpath 1024				" X: 0
-    finally
-	Xpath 2048				" X: 2048
-	execute "try | return 8192 | finally | return 16384 | endtry"
-	Xpath 4096				" X: 0
-    endtry
-    Xpath 8192					" X: 0
-endfunction
-
-function! J()
-    try
-	RETURN 32768
-	Xpath 16384				" X: 0
-    finally
-	Xpath 32768				" X: 32768
-	return
-	Xpath 65536				" X: 0
-    endtry
-    Xpath 131072				" X: 0
-endfunction
-
-function! K()
-    try
-	execute "try | return 131072 | finally | return 262144 | endtry"
-	Xpath 262144				" X: 0
-    finally
-	Xpath 524288				" X: 524288
-	execute "try | return 524288 | finally | return | endtry"
-	Xpath 1048576				" X: 0
-    endtry
-    Xpath 2097152				" X: 0
-endfunction
-
-function! L()
-    try
-	return
-	Xpath 4194304				" X: 0
-    finally
-	Xpath 8388608				" X: 8388608
-	RETURN 1048576
-	Xpath 16777216				" X: 0
-    endtry
-    Xpath 33554432				" X: 0
-endfunction
-
-function! M()
-    try
-	return
-	Xpath 67108864				" X: 0
-    finally
-	Xpath 134217728				" X: 134217728
-	execute "try | return 4194304 | finally | return 8388608 | endtry"
-	Xpath 268435456				" X: 0
-    endtry
-    Xpath 536870912				" X: 0
-endfunction
-
-function! N()
-    RETURN 16777216
-endfunction
-
-function! O()
-    execute "try | return 67108864 | finally | return 134217728 | endtry"
-endfunction
-
-let sum	     = F() + G() + H()  + I()   + J() + K() + L()     + M()
-let expected = 16  + 256 + 1024 + 16384 + 0   + 0   + 2097152 + 8388608
-let sum	     = sum      + N()      + O()
-let expected = expected + 33554432 + 134217728
-
-if sum == expected
-    Xout "sum = " . sum . " (ok)"
-else
-    Xout "sum = " . sum . ", expected: " . expected
-endif
-
-Xpath 1073741824				" X: 1073741824
-
-if sum != expected
-    " The Xpath command does not accept 2^31 (negative); add explicitly:
-    let Xpath = Xpath + 2147483648		" X: 0
-endif
-
-unlet sum expected
-delfunction F
-delfunction G
-delfunction H
-delfunction I
-delfunction J
-delfunction K
-delfunction L
-delfunction M
-delfunction N
-delfunction O
-
-Xcheck 1216907538
+" Tests 32 and 33 were moved to test_trycatch.vim
+let Xtest = 34
 
 
 "-------------------------------------------------------------------------------
@@ -2654,643 +2090,8 @@ endif
 
 Xcheck 357908480
 
-
-"-------------------------------------------------------------------------------
-" Test 41:  Skipped :throw finding next command				    {{{1
-"
-"	    A :throw in an inactive conditional must not hide a following
-"	    command.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-function! F()
-    Xpath 1					" X: 1
-    if 0 | throw "never" | endif | Xpath 2	" X: 2
-    Xpath 4					" X: 4
-endfunction
-
-function! G()
-    Xpath 8					    " X: 8
-    while 0 | throw "never" | endwhile | Xpath 16   " X: 16
-    Xpath 32					    " X: 32
-endfunction
-
-function H()
-    Xpath 64						    " X: 64
-    if 0 | try | throw "never" | endtry | endif | Xpath 128 " X: 128
-    Xpath 256						    " X: 256
-endfunction
-
-Xpath 512					" X: 512
-
-try
-    Xpath 1024					" X: 1024
-    call F()
-    Xpath 2048					" X: 2048
-catch /.*/
-    Xpath 4096					" X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-Xpath 8192					" X: 8192
-
-try
-    Xpath 16384					" X: 16384
-    call G()
-    Xpath 32768					" X: 32768
-catch /.*/
-    Xpath 65536					" X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-Xpath 131072					" X: 131072
-
-try
-    Xpath 262144				" X: 262144
-    call H()
-    Xpath 524288				" X: 524288
-catch /.*/
-    Xpath 1048576				" X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-Xpath 2097152					" X: 2097152
-
-delfunction F
-delfunction G
-delfunction H
-
-Xcheck 3076095
-
-
-"-------------------------------------------------------------------------------
-" Test 42:  Catching number and string exceptions			    {{{1
-"
-"	    When a number is thrown, it is converted to a string exception.
-"	    Numbers and strings may be caught by specifying a regular exception
-"	    as argument to the :catch command.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-try
-
-    try
-	Xpath 1					" X: 1
-	throw 4711
-	Xpath 2					" X: 0
-    catch /4711/
-	Xpath 4					" X: 4
-    endtry
-
-    try
-	Xpath 8					" X: 8
-	throw 4711
-	Xpath 16				" X: 0
-    catch /^4711$/
-	Xpath 32				" X: 32
-    endtry
-
-    try
-	Xpath 64				" X: 64
-	throw 4711
-	Xpath 128				" X: 0
-    catch /\d/
-	Xpath 256				" X: 256
-    endtry
-
-    try
-	Xpath 512				" X: 512
-	throw 4711
-	Xpath 1024				" X: 0
-    catch /^\d\+$/
-	Xpath 2048				" X: 2048
-    endtry
-
-    try
-	Xpath 4096				" X: 4096
-	throw "arrgh"
-	Xpath 8192				" X: 0
-    catch /arrgh/
-	Xpath 16384				" X: 16384
-    endtry
-
-    try
-	Xpath 32768				" X: 32768
-	throw "arrgh"
-	Xpath 65536				" X: 0
-    catch /^arrgh$/
-	Xpath 131072				" X: 131072
-    endtry
-
-    try
-	Xpath 262144				" X: 262144
-	throw "arrgh"
-	Xpath 524288				" X: 0
-    catch /\l/
-	Xpath 1048576				" X: 1048576
-    endtry
-
-    try
-	Xpath 2097152				" X: 2097152
-	throw "arrgh"
-	Xpath 4194304				" X: 0
-    catch /^\l\+$/
-	Xpath 8388608				" X: 8388608
-    endtry
-
-    try
-	try
-	    Xpath 16777216			" X: 16777216
-	    throw "ARRGH"
-	    Xpath 33554432			" X: 0
-	catch /^arrgh$/
-	    Xpath 67108864			" X: 0
-	endtry
-    catch /^\carrgh$/
-	Xpath 134217728				" X: 134217728
-    endtry
-
-    try
-	Xpath 268435456				" X: 268435456
-	throw ""
-	Xpath 536870912				" X: 0
-    catch /^$/
-	Xpath 1073741824			" X: 1073741824
-    endtry
-
-catch /.*/
-    " The Xpath command does not accept 2^31 (negative); add explicitly:
-    let Xpath = Xpath + 2147483648		" X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-Xcheck 1505155949
-
-
-"-------------------------------------------------------------------------------
-" Test 43:  Selecting the correct :catch clause				    {{{1
-"
-"	    When an exception is thrown and there are multiple :catch clauses,
-"	    the first matching one is taken.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-XloopINIT 1 1024
-let loops = 3
-while loops > 0
-    try
-	if loops == 3
-	    Xloop 1				" X: 1
-	    throw "a"
-	    Xloop 2				" X: 0
-	elseif loops == 2
-	    Xloop 4				" X: 4*1024
-	    throw "ab"
-	    Xloop 8				" X: 0
-	elseif loops == 1
-	    Xloop 16				" X: 16*1024*1024
-	    throw "abc"
-	    Xloop 32				" X: 0
-	endif
-    catch /abc/
-	Xloop 64				" X: 64*1024*1024
-    catch /ab/
-	Xloop 128				" X: 128*1024
-    catch /.*/
-	Xloop 256				" X: 256
-    catch /a/
-	Xloop 512				" X: 0
-    endtry
-
-    let loops = loops - 1
-    XloopNEXT
-endwhile
-Xpath 1073741824				" X: 1073741824
-
-unlet loops
-
-Xcheck 1157763329
-
-
-"-------------------------------------------------------------------------------
-" Test 44:  Missing or empty :catch patterns				    {{{1
-"
-"	    A missing or empty :catch pattern means the same as /.*/, that is,
-"	    catches everything.  To catch only empty exceptions, /^$/ must be
-"	    used.  A :catch with missing, empty, or /.*/ argument also works
-"	    when followed by another command separated by a bar on the same
-"	    line.  :catch patterns cannot be specified between ||.  But other
-"	    pattern separators can be used instead of //.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-try
-    try
-	Xpath 1					" X: 1
-	throw ""
-    catch /^$/
-	Xpath 2					" X: 2
-    endtry
-
-    try
-	Xpath 4					" X: 4
-	throw ""
-    catch /.*/
-	Xpath 8					" X: 8
-    endtry
-
-    try
-	Xpath 16				" X: 16
-	throw ""
-    catch //
-	Xpath 32				" X: 32
-    endtry
-
-    try
-	Xpath 64				" X: 64
-	throw ""
-    catch
-	Xpath 128				" X: 128
-    endtry
-
-    try
-	Xpath 256				" X: 256
-	throw "oops"
-    catch /^$/
-	Xpath 512				" X: 0
-    catch /.*/
-	Xpath 1024				" X: 1024
-    endtry
-
-    try
-	Xpath 2048				" X: 2048
-	throw "arrgh"
-    catch /^$/
-	Xpath 4096				" X: 0
-    catch //
-	Xpath 8192				" X: 8192
-    endtry
-
-    try
-	Xpath 16384				" X: 16384
-	throw "brrr"
-    catch /^$/
-	Xpath 32768				" X: 0
-    catch
-	Xpath 65536				" X: 65536
-    endtry
-
-    try | Xpath 131072 | throw "x" | catch /.*/ | Xpath 262144 | endtry
-						" X: 131072 + 262144
-
-    try | Xpath 524288 | throw "y" | catch // | Xpath 1048576 | endtry
-						" X: 524288 + 1048576
-
-    while 1
-	try
-	    let caught = 0
-	    let v:errmsg = ""
-	    " Extra try level:  if ":catch" without arguments below raises
-	    " a syntax error because it misinterprets the "Xpath" as a pattern,
-	    " let it be caught by the ":catch /.*/" below.
-	    try
-		try | Xpath 2097152 | throw "z" | catch | Xpath 4194304 | :
-		endtry				" X: 2097152 + 4194304
-	    endtry
-	catch /.*/
-	    let caught = 1
-	    Xout v:exception "in" v:throwpoint
-	finally
-	    if $VIMNOERRTHROW && v:errmsg != ""
-		Xout v:errmsg
-	    endif
-	    if caught || $VIMNOERRTHROW && v:errmsg != ""
-		Xpath 8388608				" X: 0
-	    endif
-	    break		" discard error for $VIMNOERRTHROW
-	endtry
-    endwhile
-
-    let cologne = 4711
-    try
-	try
-	    Xpath 16777216			" X: 16777216
-	    throw "throw cologne"
-	" Next lines catches all and throws 4711:
-	catch |throw cologne|
-	    Xpath 33554432			" X: 0
-	endtry
-    catch /4711/
-	Xpath 67108864				" X: 67108864
-    endtry
-
-    try
-	Xpath 134217728				" X: 134217728
-	throw "plus"
-    catch +plus+
-	Xpath 268435456				" X: 268435456
-    endtry
-
-    Xpath 536870912				" X: 536870912
-catch /.*/
-    Xpath 1073741824				" X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-unlet! caught cologne
-
-Xcheck 1031761407
-
-
-"-------------------------------------------------------------------------------
-" Test 45:  Catching exceptions from nested :try blocks			    {{{1
-"
-"	    When :try blocks are nested, an exception is caught by the innermost
-"	    try conditional that has a matching :catch clause.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-XloopINIT 1 1024
-let loops = 3
-while loops > 0
-    try
-	try
-	    try
-		try
-		    if loops == 3
-			Xloop 1			" X: 1
-			throw "a"
-			Xloop 2			" X: 0
-		    elseif loops == 2
-			Xloop 4			" X: 4*1024
-			throw "ab"
-			Xloop 8			" X: 0
-		    elseif loops == 1
-			Xloop 16		" X: 16*1024*1024
-			throw "abc"
-			Xloop 32		" X: 0
-		    endif
-		catch /abc/
-		    Xloop 64			" X: 64*1024*1024
-		endtry
-	    catch /ab/
-		Xloop 128			" X: 128*1024
-	    endtry
-	catch /.*/
-	    Xloop 256				" X: 256
-	endtry
-    catch /a/
-	Xloop 512				" X: 0
-    endtry
-
-    let loops = loops - 1
-    XloopNEXT
-endwhile
-Xpath 1073741824				" X: 1073741824
-
-unlet loops
-
-Xcheck 1157763329
-
-
-"-------------------------------------------------------------------------------
-" Test 46:  Executing :finally after a :throw in nested :try		    {{{1
-"
-"	    When an exception is thrown from within nested :try blocks, the
-"	    :finally clauses of the non-catching try conditionals should be
-"	    executed before the matching :catch of the next surrounding :try
-"	    gets the control.  If this also has a :finally clause, it is
-"	    executed afterwards.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-let sum = 0
-
-try
-    Xpath 1					" X: 1
-    try
-	Xpath 2					" X: 2
-	try
-	    Xpath 4				" X: 4
-	    try
-		Xpath 8				" X: 8
-		throw "ABC"
-		Xpath 16			" X: 0
-	    catch /xyz/
-		Xpath 32			" X: 0
-	    finally
-		Xpath 64			" X: 64
-		if sum != 0
-		    Xpath 128			" X: 0
-		endif
-		let sum = sum + 1
-	    endtry
-	    Xpath 256				" X: 0
-	catch /123/
-	    Xpath 512				" X: 0
-	catch /321/
-	    Xpath 1024				" X: 0
-	finally
-	    Xpath 2048				" X: 2048
-	    if sum != 1
-		Xpath 4096			" X: 0
-	    endif
-	    let sum = sum + 2
-	endtry
-	Xpath 8192				" X: 0
-    finally
-	Xpath 16384				" X: 16384
-	if sum != 3
-	    Xpath 32768				" X: 0
-	endif
-	let sum = sum + 4
-    endtry
-    Xpath 65536					" X: 0
-catch /ABC/
-    Xpath 131072				" X: 131072
-    if sum != 7
-	Xpath 262144				" X: 0
-    endif
-    let sum = sum + 8
-finally
-    Xpath 524288				" X: 524288
-    if sum != 15
-	Xpath 1048576				" X: 0
-    endif
-    let sum = sum + 16
-endtry
-Xpath 65536					" X: 65536
-if sum != 31
-    Xpath 131072				" X: 0
-endif
-
-unlet sum
-
-Xcheck 739407
-
-
-"-------------------------------------------------------------------------------
-" Test 47:  Throwing exceptions from a :catch clause			    {{{1
-"
-"	    When an exception is thrown from a :catch clause, it should not be
-"	    caught by a :catch of the same :try conditional.  After executing
-"	    the :finally clause (if present), surrounding try conditionals
-"	    should be checked for a matching :catch.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-Xpath 1						" X: 1
-try
-    Xpath 2					" X: 2
-    try
-	Xpath 4					" X: 4
-	try
-	    Xpath 8				" X: 8
-	    throw "x1"
-	    Xpath 16				" X: 0
-	catch /x1/
-	    Xpath 32				" X: 32
-	    try
-		Xpath 64			" X: 64
-		throw "x2"
-		Xpath 128			" X: 0
-	    catch /x1/
-		Xpath 256			" X: 0
-	    catch /x2/
-		Xpath 512			" X: 512
-		try
-		    Xpath 1024			" X: 1024
-		    throw "x3"
-		    Xpath 2048			" X: 0
-		catch /x1/
-		    Xpath 4096			" X: 0
-		catch /x2/
-		    Xpath 8192			" X: 0
-		finally
-		    Xpath 16384			" X: 16384
-		endtry
-		Xpath 32768			" X: 0
-	    catch /x3/
-		Xpath 65536			" X: 0
-	    endtry
-	    Xpath 131072			" X: 0
-	catch /x1/
-	    Xpath 262144			" X: 0
-	catch /x2/
-	    Xpath 524288			" X: 0
-	catch /x3/
-	    Xpath 1048576			" X: 0
-	finally
-	    Xpath 2097152			" X: 2097152
-	endtry
-	Xpath 4194304				" X: 0
-    catch /x1/
-	Xpath 8388608				" X: 0
-    catch /x2/
-	Xpath 16777216				" X: 0
-    catch /x3/
-	Xpath 33554432				" X: 33554432
-    endtry
-    Xpath 67108864				" X: 67108864
-catch /.*/
-    Xpath 134217728				" X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-Xpath 268435456					" X: 268435456
-
-Xcheck 371213935
-
-
-"-------------------------------------------------------------------------------
-" Test 48:  Throwing exceptions from a :finally clause			    {{{1
-"
-"	    When an exception is thrown from a :finally clause, it should not be
-"	    caught by a :catch of the same :try conditional.  Surrounding try
-"	    conditionals should be checked for a matching :catch.  A previously
-"	    thrown exception is discarded.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-try
-
-    try
-	try
-	    Xpath 1				" X: 1
-	catch /x1/
-	    Xpath 2				" X: 0
-	finally
-	    Xpath 4				" X: 4
-	    throw "x1"
-	    Xpath 8				" X: 0
-	endtry
-	Xpath 16				" X: 0
-    catch /x1/
-	Xpath 32				" X: 32
-    endtry
-    Xpath 64					" X: 64
-
-    try
-	try
-	    Xpath 128				" X: 128
-	    throw "x2"
-	    Xpath 256				" X: 0
-	catch /x2/
-	    Xpath 512				" X: 512
-	catch /x3/
-	    Xpath 1024				" X: 0
-	finally
-	    Xpath 2048				" X: 2048
-	    throw "x3"
-	    Xpath 4096				" X: 0
-	endtry
-	Xpath 8192				" X: 0
-    catch /x2/
-	Xpath 16384				" X: 0
-    catch /x3/
-	Xpath 32768				" X: 32768
-    endtry
-    Xpath 65536					" X: 65536
-
-    try
-	try
-	    try
-		Xpath 131072			" X: 131072
-		throw "x4"
-		Xpath 262144			" X: 0
-	    catch /x5/
-		Xpath 524288			" X: 0
-	    finally
-		Xpath 1048576			" X: 1048576
-		throw "x5"	" discards "x4"
-		Xpath 2097152			" X: 0
-	    endtry
-	    Xpath 4194304			" X: 0
-	catch /x4/
-	    Xpath 8388608			" X: 0
-	finally
-	    Xpath 16777216			" X: 16777216
-	endtry
-	Xpath 33554432				" X: 0
-    catch /x5/
-	Xpath 67108864				" X: 67108864
-    endtry
-    Xpath 134217728				" X: 134217728
-
-catch /.*/
-    Xpath 268435456				" X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-Xpath 536870912					" X: 536870912
-
-Xcheck 756255461
+" Tests 41 to 48 were moved to test_trycatch.vim
+let Xtest = 49
 
 
 "-------------------------------------------------------------------------------
@@ -3443,124 +2244,8 @@ delfunction F
 
 Xcheck 363550045
 
-
-"-------------------------------------------------------------------------------
-" Test 51:  Throwing exceptions across :execute and user commands	    {{{1
-"
-"	    A :throw command may be executed under an ":execute" or from
-"	    a user command.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-command! -nargs=? THROW1    throw <args> | throw 1
-command! -nargs=? THROW2    try | throw <args> | endtry | throw 2
-command! -nargs=? THROW3    try | throw 3 | catch /3/ | throw <args> | endtry
-command! -nargs=? THROW4    try | throw 4 | finally   | throw <args> | endtry
-
-try
-
-    try
-	try
-	    Xpath 1				" X: 1
-	    THROW1 "A"
-	catch /A/
-	    Xpath 2				" X: 2
-	endtry
-    catch /1/
-	Xpath 4					" X: 0
-    endtry
-
-    try
-	try
-	    Xpath 8				" X: 8
-	    THROW2 "B"
-	catch /B/
-	    Xpath 16				" X: 16
-	endtry
-    catch /2/
-	Xpath 32				" X: 0
-    endtry
-
-    try
-	try
-	    Xpath 64				" X: 64
-	    THROW3 "C"
-	catch /C/
-	    Xpath 128				" X: 128
-	endtry
-    catch /3/
-	Xpath 256				" X: 0
-    endtry
-
-    try
-	try
-	    Xpath 512				" X: 512
-	    THROW4 "D"
-	catch /D/
-	    Xpath 1024				" X: 1024
-	endtry
-    catch /4/
-	Xpath 2048				" X: 0
-    endtry
-
-    try
-	try
-	    Xpath 4096				" X: 4096
-	    execute 'throw "E" | throw 5'
-	catch /E/
-	    Xpath 8192				" X: 8192
-	endtry
-    catch /5/
-	Xpath 16384				" X: 0
-    endtry
-
-    try
-	try
-	    Xpath 32768				" X: 32768
-	    execute 'try | throw "F" | endtry | throw 6'
-	catch /F/
-	    Xpath 65536				" X: 65536
-	endtry
-    catch /6/
-	Xpath 131072				" X: 0
-    endtry
-
-    try
-	try
-	    Xpath 262144			" X: 262144
-	    execute'try | throw 7 | catch /7/ | throw "G" | endtry'
-	catch /G/
-	    Xpath 524288			" X: 524288
-	endtry
-    catch /7/
-	Xpath 1048576				" X: 0
-    endtry
-
-    try
-	try
-	    Xpath 2097152			" X: 2097152
-	    execute 'try | throw 8 | finally   | throw "H" | endtry'
-	catch /H/
-	    Xpath 4194304			" X: 4194304
-	endtry
-    catch /8/
-	Xpath 8388608				" X: 0
-    endtry
-
-catch /.*/
-    Xpath 16777216				" X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-Xpath 33554432					" X: 33554432
-
-delcommand THROW1
-delcommand THROW2
-delcommand THROW3
-delcommand THROW4
-
-Xcheck 40744667
+" Test 51 was moved to test_trycatch.vim
+let Xtest = 52
 
 
 "-------------------------------------------------------------------------------
@@ -6227,954 +4912,8 @@ delfunction F
 
 Xcheck 212514423
 
-
-"-------------------------------------------------------------------------------
-" Test 69:  :throw across :if, :elseif, :while				    {{{1
-"
-"	    On an :if, :elseif, or :while command, an exception might be thrown
-"	    during evaluation of the expression to test.  The exception can be
-"	    caught by the script.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-XloopINIT! 1 2
-
-function! THROW(x)
-    XloopNEXT
-    Xloop 1					" X: 1 + 2 + 4
-    throw a:x
-endfunction
-
-try
-
-    try
-	Xpath 8					" X: 8
-	if 4711 == THROW("if") + 111
-	    Xpath 16				" X: 0
-	else
-	    Xpath 32				" X: 0
-	endif
-	Xpath 64				" X: 0
-    catch /^if$/
-	Xpath 128				" X: 128
-    catch /.*/
-	Xpath 256				" X: 0
-	Xout "if:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-	Xpath 512				" X: 512
-	if 4711 == 4 + 7 + 1 + 1
-	    Xpath 1024				" X: 0
-	elseif 4711 == THROW("elseif") + 222
-	    Xpath 2048				" X: 0
-	else
-	    Xpath 4096				" X: 0
-	endif
-	Xpath 8192				" X: 0
-    catch /^elseif$/
-	Xpath 16384				" X: 16384
-    catch /.*/
-	Xpath 32768				" X: 0
-	Xout "elseif:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-	Xpath 65536				" X: 65536
-	while 4711 == THROW("while") + 4711
-	    Xpath 131072			" X: 0
-	    break
-	endwhile
-	Xpath 262144				" X: 0
-    catch /^while$/
-	Xpath 524288				" X: 524288
-    catch /.*/
-	Xpath 1048576				" X: 0
-	Xout "while:" v:exception "in" v:throwpoint
-    endtry
-
-catch /^0$/	    " default return value
-    Xpath 2097152				" X: 0
-    Xout v:throwpoint
-catch /.*/
-    Xout v:exception "in" v:throwpoint
-    Xpath 4194304				" X: 0
-endtry
-
-Xpath 8388608					" X: 8388608
-
-delfunction THROW
-
-Xcheck 8995471
-
-
-"-------------------------------------------------------------------------------
-" Test 70:  :throw across :return or :throw				    {{{1
-"
-"	    On a :return or :throw command, an exception might be thrown during
-"	    evaluation of the expression to return or throw, respectively.  The
-"	    exception can be caught by the script.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-let taken = ""
-
-function! THROW(x, n)
-    let g:taken = g:taken . "T" . a:n
-    throw a:x
-endfunction
-
-function! F(x, y, n)
-    let g:taken = g:taken . "F" . a:n
-    return a:x + THROW(a:y, a:n)
-endfunction
-
-function! G(x, y, n)
-    let g:taken = g:taken . "G" . a:n
-    throw a:x . THROW(a:y, a:n)
-    return a:x
-endfunction
-
-try
-    try
-	Xpath 1					" X: 1
-	call F(4711, "return", 1)
-	Xpath 2					" X: 0
-    catch /^return$/
-	Xpath 4					" X: 4
-    catch /.*/
-	Xpath 8					" X: 0
-	Xout "return:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-	Xpath 16				" X: 16
-	let var = F(4712, "return-var", 2)
-	Xpath 32				" X: 0
-    catch /^return-var$/
-	Xpath 64				" X: 64
-    catch /.*/
-	Xpath 128				" X: 0
-	Xout "return-var:" v:exception "in" v:throwpoint
-    finally
-	unlet! var
-    endtry
-
-    try
-	Xpath 256				" X: 256
-	throw "except1" . THROW("throw1", 3)
-	Xpath 512				" X: 0
-    catch /^except1/
-	Xpath 1024				" X: 0
-    catch /^throw1$/
-	Xpath 2048				" X: 2048
-    catch /.*/
-	Xpath 4096				" X: 0
-	Xout "throw1:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-	Xpath 8192				" X: 8192
-	call G("except2", "throw2", 4)
-	Xpath 16384				" X: 0
-    catch /^except2/
-	Xpath 32768				" X: 0
-    catch /^throw2$/
-	Xpath 65536				" X: 65536
-    catch /.*/
-	Xpath 131072				" X: 0
-	Xout "throw2:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-	Xpath 262144				" X: 262144
-	let var = G("except3", "throw3", 5)
-	Xpath 524288				" X: 0
-    catch /^except3/
-	Xpath 1048576				" X: 0
-    catch /^throw3$/
-	Xpath 2097152				" X: 2097152
-    catch /.*/
-	Xpath 4194304				" X: 0
-	Xout "throw3:" v:exception "in" v:throwpoint
-    finally
-	unlet! var
-    endtry
-
-    let expected = "F1T1F2T2T3G4T4G5T5"
-    if taken != expected
-	Xpath 8388608				" X: 0
-	Xout "'taken' is" taken "instead of" expected
-    endif
-
-catch /^0$/	    " default return value
-    Xpath 16777216				" X: 0
-    Xout v:throwpoint
-catch /.*/
-    Xpath 33554432				" X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-Xpath 67108864					" X: 67108864
-
-unlet taken expected
-delfunction THROW
-delfunction F
-delfunction G
-
-Xcheck 69544277
-
-
-"-------------------------------------------------------------------------------
-" Test 71:  :throw across :echo variants and :execute			    {{{1
-"
-"	    On an :echo, :echon, :echomsg, :echoerr, or :execute command, an
-"	    exception might be thrown during evaluation of the arguments to
-"	    be displayed or executed as a command, respectively.  Any following
-"	    arguments are not evaluated, then.  The exception can be caught by
-"	    the script.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-let taken = ""
-
-function! THROW(x, n)
-    let g:taken = g:taken . "T" . a:n
-    throw a:x
-endfunction
-
-function! F(n)
-    let g:taken = g:taken . "F" . a:n
-    return "F" . a:n
-endfunction
-
-try
-    try
-	Xpath 1					" X: 1
-	echo "echo" . THROW("echo-except", 1) F(1)
-	Xpath 2					" X: 0
-    catch /^echo-except$/
-	Xpath 4					" X: 4
-    catch /.*/
-	Xpath 8					" X: 0
-	Xout "echo:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-	Xpath 16				" X: 16
-	echon "echon" . THROW("echon-except", 2) F(2)
-	Xpath 32				" X: 0
-    catch /^echon-except$/
-	Xpath 64				" X: 64
-    catch /.*/
-	Xpath 128				" X: 0
-	Xout "echon:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-	Xpath 256				" X: 256
-	echomsg "echomsg" . THROW("echomsg-except", 3) F(3)
-	Xpath 512				" X: 0
-    catch /^echomsg-except$/
-	Xpath 1024				" X: 1024
-    catch /.*/
-	Xpath 2048				" X: 0
-	Xout "echomsg:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-	Xpath 4096				" X: 4096
-	echoerr "echoerr" . THROW("echoerr-except", 4) F(4)
-	Xpath 8192				" X: 0
-    catch /^echoerr-except$/
-	Xpath 16384				" X: 16384
-    catch /Vim/
-	Xpath 32768				" X: 0
-    catch /echoerr/
-	Xpath 65536				" X: 0
-    catch /.*/
-	Xpath 131072				" X: 0
-	Xout "echoerr:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-	Xpath 262144				" X: 262144
-	execute "echo 'execute" . THROW("execute-except", 5) F(5) "'"
-	Xpath 524288				" X: 0
-    catch /^execute-except$/
-	Xpath 1048576				" X: 1048576
-    catch /.*/
-	Xpath 2097152				" X: 0
-	Xout "execute:" v:exception "in" v:throwpoint
-    endtry
-
-    let expected = "T1T2T3T4T5"
-    if taken != expected
-	Xpath 4194304				" X: 0
-	Xout "'taken' is" taken "instead of" expected
-    endif
-
-catch /^0$/	    " default return value
-    Xpath 8388608				" X: 0
-    Xout v:throwpoint
-catch /.*/
-    Xpath 16777216				" X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-Xpath 33554432					" X: 33554432
-
-unlet taken expected
-delfunction THROW
-delfunction F
-
-Xcheck 34886997
-
-
-"-------------------------------------------------------------------------------
-" Test 72:  :throw across :let or :unlet				    {{{1
-"
-"	    On a :let command, an exception might be thrown during evaluation
-"	    of the expression to assign.  On an :let or :unlet command, the
-"	    evaluation of the name of the variable to be assigned or list or
-"	    deleted, respectively, may throw an exception.  Any following
-"	    arguments are not evaluated, then.  The exception can be caught by
-"	    the script.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-let throwcount = 0
-
-function! THROW(x)
-    let g:throwcount = g:throwcount + 1
-    throw a:x
-endfunction
-
-try
-    try
-	let $VAR = "old_value"
-	Xpath 1					" X: 1
-	let $VAR = "let(" . THROW("var") . ")"
-	Xpath 2					" X: 0
-    catch /^var$/
-	Xpath 4					" X: 4
-    finally
-	if $VAR != "old_value"
-	    Xpath 8				" X: 0
-	endif
-    endtry
-
-    try
-	let @a = "old_value"
-	Xpath 16				" X: 16
-	let @a = "let(" . THROW("reg") . ")"
-	Xpath 32				" X: 0
-    catch /^reg$/
-	try
-	    Xpath 64				" X: 64
-	    let @A = "let(" . THROW("REG") . ")"
-	    Xpath 128				" X: 0
-	catch /^REG$/
-	    Xpath 256				" X: 256
-	endtry
-    finally
-	if @a != "old_value"
-	    Xpath 512				" X: 0
-	endif
-	if @A != "old_value"
-	    Xpath 1024				" X: 0
-	endif
-    endtry
-
-    try
-	let saved_gpath = &g:path
-	let saved_lpath = &l:path
-	Xpath 2048				" X: 2048
-	let &path = "let(" . THROW("opt") . ")"
-	Xpath 4096				" X: 0
-    catch /^opt$/
-	try
-	    Xpath 8192				" X: 8192
-	    let &g:path = "let(" . THROW("gopt") . ")"
-	    Xpath 16384				" X: 0
-	catch /^gopt$/
-	    try
-		Xpath 32768			" X: 32768
-		let &l:path = "let(" . THROW("lopt") . ")"
-		Xpath 65536			" X: 0
-	    catch /^lopt$/
-		Xpath 131072			" X: 131072
-	    endtry
-	endtry
-    finally
-	if &g:path != saved_gpath || &l:path != saved_lpath
-	    Xpath 262144			" X: 0
-	endif
-	let &g:path = saved_gpath
-	let &l:path = saved_lpath
-    endtry
-
-    unlet! var1 var2 var3
-
-    try
-	Xpath 524288				" X: 524288
-	let var1 = "let(" . THROW("var1") . ")"
-	Xpath 1048576				" X: 0
-    catch /^var1$/
-	Xpath 2097152				" X: 2097152
-    finally
-	if exists("var1")
-	    Xpath 4194304			" X: 0
-	endif
-    endtry
-
-    try
-	let var2 = "old_value"
-	Xpath 8388608				" X: 8388608
-	let var2 = "let(" . THROW("var2"). ")"
-	Xpath 16777216				" X: 0
-    catch /^var2$/
-	Xpath 33554432				" X: 33554432
-    finally
-	if var2 != "old_value"
-	    Xpath 67108864			" X: 0
-	endif
-    endtry
-
-    try
-	Xpath 134217728				" X: 134217728
-	let var{THROW("var3")} = 4711
-	Xpath 268435456				" X: 0
-    catch /^var3$/
-	Xpath 536870912				" X: 536870912
-    endtry
-
-    let addpath = ""
-
-    function ADDPATH(p)
-	let g:addpath = g:addpath . a:p
-    endfunction
-
-    try
-	call ADDPATH("T1")
-	let var{THROW("var4")} var{ADDPATH("T2")} | call ADDPATH("T3")
-	call ADDPATH("T4")
-    catch /^var4$/
-	call ADDPATH("T5")
-    endtry
-
-    try
-	call ADDPATH("T6")
-	unlet var{THROW("var5")} var{ADDPATH("T7")} | call ADDPATH("T8")
-	call ADDPATH("T9")
-    catch /^var5$/
-	call ADDPATH("T10")
-    endtry
-
-    if addpath != "T1T5T6T10" || throwcount != 11
-	throw "addpath: " . addpath . ", throwcount: " . throwcount
-    endif
-
-    Xpath 1073741824				" X: 1073741824
-
-catch /.*/
-    " The Xpath command does not accept 2^31 (negative); add explicitly:
-    let Xpath = Xpath + 2147483648		" X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-unlet! var1 var2 var3 addpath throwcount
-delfunction THROW
-
-Xcheck 1789569365
-
-
-"-------------------------------------------------------------------------------
-" Test 73:  :throw across :function, :delfunction			    {{{1
-"
-"	    The :function and :delfunction commands may cause an expression
-"	    specified in braces to be evaluated.  During evaluation, an
-"	    exception might be thrown.  The exception can be caught by the
-"	    script.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-let taken = ""
-
-function! THROW(x, n)
-    let g:taken = g:taken . "T" . a:n
-    throw a:x
-endfunction
-
-function! EXPR(x, n)
-    let g:taken = g:taken . "E" . a:n
-    if a:n % 2 == 0
-	call THROW(a:x, a:n)
-    endif
-    return 2 - a:n % 2
-endfunction
-
-try
-    try
-	" Define function.
-	Xpath 1					" X: 1
-	function! F0()
-	endfunction
-	Xpath 2					" X: 2
-	function! F{EXPR("function-def-ok", 1)}()
-	endfunction
-	Xpath 4					" X: 4
-	function! F{EXPR("function-def", 2)}()
-	endfunction
-	Xpath 8					" X: 0
-    catch /^function-def-ok$/
-	Xpath 16				" X: 0
-    catch /^function-def$/
-	Xpath 32				" X: 32
-    catch /.*/
-	Xpath 64				" X: 0
-	Xout "def:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-	" List function.
-	Xpath 128				" X: 128
-	function F0
-	Xpath 256				" X: 256
-	function F{EXPR("function-lst-ok", 3)}
-	Xpath 512				" X: 512
-	function F{EXPR("function-lst", 4)}
-	Xpath 1024				" X: 0
-    catch /^function-lst-ok$/
-	Xpath 2048				" X: 0
-    catch /^function-lst$/
-	Xpath 4096				" X: 4096
-    catch /.*/
-	Xpath 8192				" X: 0
-	Xout "lst:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-	" Delete function
-	Xpath 16384				" X: 16384
-	delfunction F0
-	Xpath 32768				" X: 32768
-	delfunction F{EXPR("function-del-ok", 5)}
-	Xpath 65536				" X: 65536
-	delfunction F{EXPR("function-del", 6)}
-	Xpath 131072				" X: 0
-    catch /^function-del-ok$/
-	Xpath 262144				" X: 0
-    catch /^function-del$/
-	Xpath 524288				" X: 524288
-    catch /.*/
-	Xpath 1048576				" X: 0
-	Xout "del:" v:exception "in" v:throwpoint
-    endtry
-
-    let expected = "E1E2T2E3E4T4E5E6T6"
-    if taken != expected
-	Xpath 2097152				" X: 0
-	Xout "'taken' is" taken "instead of" expected
-    endif
-
-catch /.*/
-    Xpath 4194304				" X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-Xpath 8388608					" X: 8388608
-
-unlet taken expected
-delfunction THROW
-delfunction EXPR
-
-Xcheck 9032615
-
-
-"-------------------------------------------------------------------------------
-" Test 74:  :throw across builtin functions and commands		    {{{1
-"
-"	    Some functions like exists(), searchpair() take expression
-"	    arguments, other functions or commands like substitute() or
-"	    :substitute cause an expression (specified in the regular
-"	    expression) to be evaluated.  During evaluation an exception
-"	    might be thrown.  The exception can be caught by the script.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-let taken = ""
-
-function! THROW(x, n)
-    let g:taken = g:taken . "T" . a:n
-    throw a:x
-endfunction
-
-function! EXPR(x, n)
-    let g:taken = g:taken . "E" . a:n
-    call THROW(a:x . a:n, a:n)
-    return "EXPR"
-endfunction
-
-function! SKIP(x, n)
-    let g:taken = g:taken . "S" . a:n . "(" . line(".")
-    let theline = getline(".")
-    if theline =~ "skip"
-	let g:taken = g:taken . "s)"
-	return 1
-    elseif theline =~ "throw"
-	let g:taken = g:taken . "t)"
-	call THROW(a:x . a:n, a:n)
-    else
-	let g:taken = g:taken . ")"
-	return 0
-    endif
-endfunction
-
-function! SUBST(x, n)
-    let g:taken = g:taken . "U" . a:n . "(" . line(".")
-    let theline = getline(".")
-    if theline =~ "not"	    " SUBST() should not be called for this line
-	let g:taken = g:taken . "n)"
-	call THROW(a:x . a:n, a:n)
-    elseif theline =~ "throw"
-	let g:taken = g:taken . "t)"
-	call THROW(a:x . a:n, a:n)
-    else
-	let g:taken = g:taken . ")"
-	return "replaced"
-    endif
-endfunction
-
-try
-    try
-	Xpath 1					" X: 1
-	let result = exists('*{EXPR("exists", 1)}')
-	Xpath 2					" X: 0
-    catch /^exists1$/
-	Xpath 4					" X: 4
-	try
-	    let result = exists('{EXPR("exists", 2)}')
-	    Xpath 8				" X: 0
-	catch /^exists2$/
-	    Xpath 16				" X: 16
-	catch /.*/
-	    Xpath 32				" X: 0
-	    Xout "exists2:" v:exception "in" v:throwpoint
-	endtry
-    catch /.*/
-	Xpath 64				" X: 0
-	Xout "exists1:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-	let file = tempname()
-	exec "edit" file
-	insert
-begin
-    xx
-middle 3
-    xx
-middle 5 skip
-    xx
-middle 7 throw
-    xx
-end
-.
-	normal! gg
-	Xpath 128				" X: 128
-	let result =
-	    \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 3)')
-	Xpath 256				" X: 256
-	let result =
-	    \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 4)')
-	Xpath 512				" X: 0
-	let result =
-	    \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 5)')
-	Xpath 1024				" X: 0
-    catch /^searchpair[35]$/
-	Xpath 2048				" X: 0
-    catch /^searchpair4$/
-	Xpath 4096				" X: 4096
-    catch /.*/
-	Xpath 8192				" X: 0
-	Xout "searchpair:" v:exception "in" v:throwpoint
-    finally
-	bwipeout!
-	call delete(file)
-    endtry
-
-    try
-	let file = tempname()
-	exec "edit" file
-	insert
-subst 1
-subst 2
-not
-subst 4
-subst throw
-subst 6
-.
-	normal! gg
-	Xpath 16384				" X: 16384
-	1,2substitute/subst/\=SUBST("substitute", 6)/
-	try
-	    Xpath 32768				" X: 32768
-	    try
-		let v:errmsg = ""
-		3substitute/subst/\=SUBST("substitute", 7)/
-	    finally
-		if v:errmsg != ""
-		    " If exceptions are not thrown on errors, fake the error
-		    " exception in order to get the same execution path.
-		    throw "faked Vim(substitute)"
-		endif
-	    endtry
-	catch /Vim(substitute)/	    " Pattern not found ('e' flag missing)
-	    Xpath 65536				" X: 65536
-	    3substitute/subst/\=SUBST("substitute", 8)/e
-	    Xpath 131072			" X: 131072
-	endtry
-	Xpath 262144				" X: 262144
-	4,6substitute/subst/\=SUBST("substitute", 9)/
-	Xpath 524288				" X: 0
-    catch /^substitute[678]/
-	Xpath 1048576				" X: 0
-    catch /^substitute9/
-	Xpath 2097152				" X: 2097152
-    finally
-	bwipeout!
-	call delete(file)
-    endtry
-
-    try
-	Xpath 4194304				" X: 4194304
-	let var = substitute("sub", "sub", '\=THROW("substitute()y", 10)', '')
-	Xpath 8388608				" X: 0
-    catch /substitute()y/
-	Xpath 16777216				" X: 16777216
-    catch /.*/
-	Xpath 33554432				" X: 0
-	Xout "substitute()y:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-	Xpath 67108864				" X: 67108864
-	let var = substitute("not", "sub", '\=THROW("substitute()n", 11)', '')
-	Xpath 134217728				" X: 134217728
-    catch /substitute()n/
-	Xpath 268435456				" X: 0
-    catch /.*/
-	Xpath 536870912				" X: 0
-	Xout "substitute()n:" v:exception "in" v:throwpoint
-    endtry
-
-    let expected = "E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10"
-    if taken != expected
-	Xpath 1073741824			" X: 0
-	Xout "'taken' is" taken "instead of" expected
-    endif
-
-catch /.*/
-    " The Xpath command does not accept 2^31 (negative); add explicitly:
-    let Xpath = Xpath + 2147483648		" X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-unlet result var taken expected
-delfunction THROW
-delfunction EXPR
-delfunction SKIP
-delfunction SUBST
-
-Xcheck 224907669
-
-
-"-------------------------------------------------------------------------------
-" Test 75:  Errors in builtin functions.				    {{{1
-"
-"	    On an error in a builtin function called inside a :try/:endtry
-"	    region, the evaluation of the expression calling that function and
-"	    the command containing that expression are abandoned.  The error can
-"	    be caught as an exception.
-"
-"	    A simple :call of the builtin function is a trivial case.  If the
-"	    builtin function is called in the argument list of another function,
-"	    no further arguments are evaluated, and the other function is not
-"	    executed.  If the builtin function is called from the argument of
-"	    a :return command, the :return command is not executed.  If the
-"	    builtin function is called from the argument of a :throw command,
-"	    the :throw command is not executed.  The evaluation of the
-"	    expression calling the builtin function is abandoned.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-function! F1(arg1)
-    Xpath 1					" X: 0
-endfunction
-
-function! F2(arg1, arg2)
-    Xpath 2					" X: 0
-endfunction
-
-function! G()
-    Xpath 4					" X: 0
-endfunction
-
-function! H()
-    Xpath 8					" X: 0
-endfunction
-
-function! R()
-    while 1
-	try
-	    let caught = 0
-	    let v:errmsg = ""
-	    Xpath 16				" X: 16
-	    return append(1, "s")
-	catch /E21/
-	    let caught = 1
-	catch /.*/
-	    Xpath 32				" X: 0
-	finally
-	    Xpath 64				" X: 64
-	    if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
-		Xpath 128			" X: 128
-	    endif
-	    break		" discard error for $VIMNOERRTHROW
-	endtry
-    endwhile
-    Xpath 256					" X: 256
-endfunction
-
-try
-    set noma	" let append() fail with "E21"
-
-    while 1
-	try
-	    let caught = 0
-	    let v:errmsg = ""
-	    Xpath 512				" X: 512
-	    call append(1, "s")
-	catch /E21/
-	    let caught = 1
-	catch /.*/
-	    Xpath 1024				" X: 0
-	finally
-	    Xpath 2048				" X: 2048
-	    if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
-		Xpath 4096			" X: 4096
-	    endif
-	    break		" discard error for $VIMNOERRTHROW
-	endtry
-    endwhile
-
-    while 1
-	try
-	    let caught = 0
-	    let v:errmsg = ""
-	    Xpath 8192				" X: 8192
-	    call F1('x' . append(1, "s"))
-	catch /E21/
-	    let caught = 1
-	catch /.*/
-	    Xpath 16384				" X: 0
-	finally
-	    Xpath 32768				" X: 32768
-	    if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
-		Xpath 65536			" X: 65536
-	    endif
-	    break		" discard error for $VIMNOERRTHROW
-	endtry
-    endwhile
-
-    while 1
-	try
-	    let caught = 0
-	    let v:errmsg = ""
-	    Xpath 131072			" X: 131072
-	    call F2('x' . append(1, "s"), G())
-	catch /E21/
-	    let caught = 1
-	catch /.*/
-	    Xpath 262144			" X: 0
-	finally
-	    Xpath 524288			" X: 524288
-	    if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
-		Xpath 1048576			" X: 1048576
-	    endif
-	    break		" discard error for $VIMNOERRTHROW
-	endtry
-    endwhile
-
-    call R()
-
-    while 1
-	try
-	    let caught = 0
-	    let v:errmsg = ""
-	    Xpath 2097152			" X: 2097152
-	    throw "T" . append(1, "s")
-	catch /E21/
-	    let caught = 1
-	catch /^T.*/
-	    Xpath 4194304			" X: 0
-	catch /.*/
-	    Xpath 8388608			" X: 0
-	finally
-	    Xpath 16777216			" X: 16777216
-	    if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
-		Xpath 33554432			" X: 33554432
-	    endif
-	    break		" discard error for $VIMNOERRTHROW
-	endtry
-    endwhile
-
-    while 1
-	try
-	    let caught = 0
-	    let v:errmsg = ""
-	    Xpath 67108864			" X: 67108864
-	    let x = "a"
-	    let x = x . "b" . append(1, "s") . H()
-	catch /E21/
-	    let caught = 1
-	catch /.*/
-	    Xpath 134217728			" X: 0
-	finally
-	    Xpath 268435456			" X: 268435456
-	    if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
-		Xpath 536870912			" X: 536870912
-	    endif
-	    if x == "a"
-		Xpath 1073741824		" X: 1073741824
-	    endif
-	    break		" discard error for $VIMNOERRTHROW
-	endtry
-    endwhile
-catch /.*/
-    " The Xpath command does not accept 2^31 (negative); add explicitly:
-    let Xpath = Xpath + 2147483648		" X: 0
-    Xout v:exception "in" v:throwpoint
-finally
-    set ma&
-endtry
-
-unlet! caught x
-delfunction F1
-delfunction F2
-delfunction G
-delfunction H
-delfunction R
-
-Xcheck 2000403408
+" Tests 69 to 75 were moved to test_trycatch.vim
+let Xtest = 76
 
 
 "-------------------------------------------------------------------------------
@@ -8780,36 +6519,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)
-
-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 87 was moved to test_vimscript.vim
+let Xtest = 88
+
 
 "-------------------------------------------------------------------------------
 " Test 88:  $VIMNOERRTHROW and $VIMNOINTTHROW support			    {{{1
new file mode 100644
--- /dev/null
+++ b/src/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 . <args>
+
+" 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 <args> | finally | return <args> * 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 <args> | throw 1
+  command! -nargs=? THROW2    try | throw <args> | endtry | throw 2
+  command! -nargs=? THROW3    try | throw 3 | catch /3/ | throw <args> | endtry
+  command! -nargs=? THROW4    try | throw 4 | finally   | throw <args> | endtry
+
+  try
+
+    try
+      try
+        Xpath '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
+"-------------------------------------------------------------------------------
--- a/src/testdir/test_vimscript.vim
+++ b/src/testdir/test_vimscript.vim
@@ -923,6 +923,200 @@ func Test_if_bar_fail()
 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 90:  Recognizing {} in variable name.			    {{{1
 "-------------------------------------------------------------------------------
 
@@ -1752,5 +1946,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
 "-------------------------------------------------------------------------------
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2246,
+/**/
     2245,
 /**/
     2244,