]> granicus.if.org Git - vim/commitdiff
patch 8.1.2246: some tests are still in old style v8.1.2246
authorBram Moolenaar <Bram@vim.org>
Sun, 3 Nov 2019 15:17:26 +0000 (16:17 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 3 Nov 2019 15:17:26 +0000 (16:17 +0100)
Problem:    Some tests are still in old style.
Solution:   Change a few tests to new style. (Yegappan Lakshmanan)

src/testdir/Make_all.mak
src/testdir/test49.ok
src/testdir/test49.vim
src/testdir/test_trycatch.vim [new file with mode: 0644]
src/testdir/test_vimscript.vim
src/version.c

index c22ce3bd6fba1c76ada866ebbceba6654b60b19e..f3906ac947d65a1a364998b8c031fe8af84b7a5d 100644 (file)
@@ -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 \
index 50fc5d2cefb5988d0927bb7e405b26edb81f0b34..9f283e808b28296ab662f1fe4fcac19b8a041c9d 100644 (file)
@@ -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.
index b6f6f6b5dcf773359a9150e4031241a4b71513c9..f19b9db5baf4eda5d069e9d522379e3fdfecdd58 100644 (file)
@@ -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 ExecAsScript(<f-args>)
 " END_OF_TEST_ENVIRONMENT - do not change or remove this line.
 
 
-" Tests 1 to 15 were moved to test_vimscript.vim
-let Xtest = 16
-
-"-------------------------------------------------------------------------------
-" Test 16:  Double :else or :elseif after :else                                    {{{1
-"
-"          Multiple :elses or an :elseif after an :else are forbidden.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-function! F() abort
-    if 0
-       Xpath 1                                 " X: 0
-    else
-       Xpath 2                                 " X: 2
-    else               " aborts function
-       Xpath 4                                 " X: 0
-    endif
-endfunction
-
-function! G() abort
-    if 0
-       Xpath 8                                 " X: 0
-    else
-       Xpath 16                                " X: 16
-    elseif 1           " aborts function
-       Xpath 32                                " X: 0
-    else
-       Xpath 64                                " X: 0
-    endif
-endfunction
-
-function! H() abort
-    if 0
-       Xpath 128                               " X: 0
-    elseif 0
-       Xpath 256                               " X: 0
-    else
-       Xpath 512                               " X: 512
-    else               " aborts function
-       Xpath 1024                              " X: 0
-    endif
-endfunction
-
-function! I() abort
-    if 0
-       Xpath 2048                              " X: 0
-    elseif 0
-       Xpath 4096                              " X: 0
-    else
-       Xpath 8192                              " X: 8192
-    elseif 1           " aborts function
-       Xpath 16384                             " X: 0
-    else
-       Xpath 32768                             " X: 0
-    endif
-endfunction
-
-call F()
-call G()
-call H()
-call I()
-
-delfunction F
-delfunction G
-delfunction H
-delfunction I
-
-Xcheck 8722
-
-
-"-------------------------------------------------------------------------------
-" Test 17:  Nesting of unmatched :if or :endif inside a :while             {{{1
-"
-"          The :while/:endwhile takes precedence in nesting over an unclosed
-"          :if or an unopened :endif.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-function! MSG(enr, emsg)
-    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
-    if a:enr == ""
-       Xout "TODO: Add message number for:" a:emsg
-       let v:errmsg = ":" . v:errmsg
-    endif
-    let match = 1
-    if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
-       let match = 0
-       if v:errmsg == ""
-           Xout "Message missing."
-       else
-           let v:errmsg = escape(v:errmsg, '"')
-           Xout "Unexpected message:" v:errmsg
-       endif
-    endif
-    return match
-endfunction
-
-let messages = ""
-
-" While loops inside a function are continued on error.
-function! F()
-    let v:errmsg = ""
-    XloopINIT 1 16
-    let loops = 3
-    while loops > 0
-       let loops = loops - 1                   "    2:  1:     0:
-       Xloop 1                                 " X: 1 + 1*16 + 1*16*16
-       if (loops == 1)
-           Xloop 2                             " X:     2*16
-           XloopNEXT
-           continue
-       elseif (loops == 0)
-           Xloop 4                             " X:            4*16*16
-           break
-       elseif 1
-           Xloop 8                             " X: 8
-           XloopNEXT
-       " endif missing!
-    endwhile   " :endwhile after :if 1
-    Xpath 4096                                 " X: 16*16*16
-    if MSG('E171', "Missing :endif")
-       let g:messages = g:messages . "A"
-    endif
-
-    let v:errmsg = ""
-    XloopINIT! 8192 4
-    let loops = 2
-    while loops > 0                            "    2:     1:
-       XloopNEXT
-       let loops = loops - 1
-       Xloop 1                                 " X: 8192 + 8192*4
-       if 0
-           Xloop 2                             " X: 0
-       " endif missing
-    endwhile   " :endwhile after :if 0
-    Xpath 131072                               " X: 8192*4*4
-    if MSG('E171', "Missing :endif")
-       let g:messages = g:messages . "B"
-    endif
-
-    let v:errmsg = ""
-    XloopINIT 262144 4
-    let loops = 2
-    while loops > 0                            "    2:     1:
-       let loops = loops - 1
-       Xloop 1                                 " X: 262144 + 262144 * 4
-       " if missing!
-       endif   " :endif without :if in while
-       Xloop 2                                 " X: 524288 + 524288 * 4
-       XloopNEXT
-    endwhile
-    Xpath 4194304                              " X: 262144*4*4
-    if MSG('E580', ":endif without :if")
-       let g:messages = g:messages . "C"
-    endif
-endfunction
-
-call F()
-
-" Error continuation outside a function is at the outermost :endwhile or :endif.
-let v:errmsg = ""
-XloopINIT! 8388608 4
-let loops = 2
-while loops > 0                                        "    2:         1:
-    XloopNEXT
-    let loops = loops - 1
-    Xloop 1                                    " X: 8388608 + 0 * 4
-    if 0
-       Xloop 2                                 " X: 0
-    " endif missing! Following :endwhile fails.
-endwhile | Xpath 134217728                     " X: 0
-Xpath 268435456                                        " X: 2*8388608*4*4
-if MSG('E171', "Missing :endif")
-    let messages = g:messages . "D"
-endif
-
-if messages != "ABCD"
-    Xpath 536870912                            " X: 0
-    Xout "messages is" messages "instead of ABCD"
-endif
-
-unlet loops messages
-delfunction F
-delfunction MSG
-
-Xcheck 285127993
-
+" Tests 1 to 17 were moved to test_vimscript.vim
+let Xtest = 18
 
 "-------------------------------------------------------------------------------
 " Test 18:  Interrupt (Ctrl-C pressed)                                     {{{1
@@ -1313,140 +1125,8 @@ endif
 
 Xcheck 41
 
-
-"-------------------------------------------------------------------------------
-" Test 25:  Executing :finally clauses on normal control flow              {{{1
-"
-"          Control flow in a :try conditional should always fall through to its
-"          :finally clause.  A :finally clause of a :try conditional inside an
-"          inactive conditional should never be executed.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-function! F()
-    let loops = 3
-    XloopINIT 1 256
-    while loops > 0                            "     3:   2:       1:
-       Xloop 1                                 " X:  1 +  1*256 + 1*256*256
-       if loops >= 2
-           try
-               Xloop 2                         " X:  2 +  2*256
-               if loops == 2
-                   try
-                       Xloop 4                 " X:       4*256
-                   finally
-                       Xloop 8                 " X:       8*256
-                   endtry
-               endif
-           finally
-               Xloop 16                        " X: 16 + 16*256
-               if loops == 2
-                   try
-                       Xloop 32                " X:      32*256
-                   finally
-                       Xloop 64                " X:      64*256
-                   endtry
-               endif
-           endtry
-       endif
-       Xloop 128                               " X: 128 + 128*256 + 128*256*256
-       let loops = loops - 1
-       XloopNEXT
-    endwhile
-    Xpath 16777216                             " X: 16777216
-endfunction
-
-if 1
-    try
-       Xpath 33554432                          " X: 33554432
-       call F()
-       Xpath 67108864                          " X: 67108864
-    finally
-       Xpath 134217728                         " X: 134217728
-    endtry
-else
-    try
-       Xpath 268435456                         " X: 0
-    finally
-       Xpath 536870912                         " X: 0
-    endtry
-endif
-
-delfunction F
-
-Xcheck 260177811
-
-
-"-------------------------------------------------------------------------------
-" Test 26:  Executing :finally clauses after :continue or :break           {{{1
-"
-"          For a :continue or :break dynamically enclosed in a :try/:endtry
-"          region inside the next surrounding :while/:endwhile, if the
-"          :continue/:break is before the :finally, the :finally clause is
-"          executed first.  If the :continue/:break is after the :finally, the
-"          :finally clause is broken (like an :if/:endif region).
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-try
-    let loops = 3
-    XloopINIT! 1 32
-    while loops > 0
-       XloopNEXT
-       try
-           try
-               if loops == 2                   "    3:   2:     1:
-                   Xloop 1                     " X:      1*32
-                   let loops = loops - 1
-                   continue
-               elseif loops == 1
-                   Xloop 2                     " X:             2*32*32
-                   break
-                   finish
-               endif
-               Xloop 4                         " X: 4
-           endtry
-       finally
-           Xloop 8                             " X: 8  + 8*32 + 8*32*32
-       endtry
-       Xloop 16                                " X: 16
-       let loops = loops - 1
-    endwhile
-    Xpath 32768                                        " X: 32768
-finally
-    Xpath 65536                                        " X: 65536
-    let loops = 3
-    XloopINIT 131072 16
-    while loops > 0
-       try
-       finally
-           try
-               if loops == 2
-                   Xloop 1                     " X: 131072*16
-                   let loops = loops - 1
-                   XloopNEXT
-                   continue
-               elseif loops == 1
-                   Xloop 2                     " X: 131072*2*16*16
-                   break
-                   finish
-               endif
-           endtry
-           Xloop 4                             " X: 131072*4
-       endtry
-       Xloop 8                                 " X: 131072*8
-       let loops = loops - 1
-       XloopNEXT
-    endwhile
-    Xpath 536870912                            " X: 536870912
-endtry
-Xpath 1073741824                               " X: 1073741824
-
-unlet loops
-
-Xcheck 1681500476
+" Tests 25 and 26 were moved to test_trycatch.vim
+let Xtest = 27
 
 
 "-------------------------------------------------------------------------------
@@ -1783,322 +1463,78 @@ endif
 
 Xcheck 190905173
 
+" Tests 32 and 33 were moved to test_trycatch.vim
+let Xtest = 34
+
 
 "-------------------------------------------------------------------------------
-" Test 32:  Remembering the :return value on :finally                      {{{1
+" Test 34:  :finally reason discarded by :continue                         {{{1
 "
-"          If a :finally clause is executed due to a :return specifying
-"          a value, this is the value visible to the caller if not overwritten
-"          by a new :return in the :finally clause.  A :return without a value
-"          in the :finally clause overwrites with value 0.
+"          When a :finally clause is executed due to a :continue, :break,
+"          :return, :finish, error, interrupt or :throw, the jump reason is
+"          discarded by a :continue in the finally clause.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-function! F()
+if ExtraVim()
+
+    XloopINIT! 1 8
+
+    function! C(jump)
+       XloopNEXT
+       let loop = 0
+       while loop < 2
+           let loop = loop + 1
+           if loop == 1
+               try
+                   if a:jump == "continue"
+                       continue
+                   elseif a:jump == "break"
+                       break
+                   elseif a:jump == "return" || a:jump == "finish"
+                       return
+                   elseif a:jump == "error"
+                       asdf
+                   elseif a:jump == "interrupt"
+                       "INTERRUPT
+                       let dummy = 0
+                   elseif a:jump == "throw"
+                       throw "abc"
+                   endif
+               finally
+                   continue    " discards jump that caused the :finally
+                   Xloop 1             " X: 0
+               endtry
+               Xloop 2                 " X: 0
+           elseif loop == 2
+               Xloop 4                 " X: 4*(1+8+64+512+4096+32768+262144)
+           endif
+       endwhile
+    endfunction
+
+    call C("continue")
+    Xpath 2097152                              " X: 2097152
+    call C("break")
+    Xpath 4194304                              " X: 4194304
+    call C("return")
+    Xpath 8388608                              " X: 8388608
+    let g:jump = "finish"
+    ExecAsScript C
+    unlet g:jump
+    Xpath 16777216                             " X: 16777216
     try
-       Xpath 1                                 " X: 1
+       call C("error")
+       Xpath 33554432                          " X: 33554432
+    finally
+       Xpath 67108864                          " X: 67108864
        try
-           Xpath 2                             " X: 2
-           return "ABCD"
-           Xpath 4                             " X: 0
+           call C("interrupt")
+           Xpath 134217728                     " X: 134217728
        finally
-           Xpath 8                             " X: 8
-       endtry
-       Xpath 16                                " X: 0
-    finally
-       Xpath 32                                " X: 32
-    endtry
-    Xpath 64                                   " X: 0
-endfunction
-
-function! G()
-    try
-       Xpath 128                               " X: 128
-       return 8
-       Xpath 256                               " X: 0
-    finally
-       Xpath 512                               " X: 512
-       return 16 + strlen(F())
-       Xpath 1024                              " X: 0
-    endtry
-    Xpath 2048                                 " X: 0
-endfunction
-
-function! H()
-    try
-       Xpath 4096                              " X: 4096
-       return 32
-       Xpath 8192                              " X: 0
-    finally
-       Xpath 16384                             " X: 16384
-       return
-       Xpath 32768                             " X: 0
-    endtry
-    Xpath 65536                                        " X: 0
-endfunction
-
-function! I()
-    try
-       Xpath 131072                            " X: 131072
-    finally
-       Xpath 262144                            " X: 262144
-       return G() + H() + 64
-       Xpath 524288                            " X: 0
-    endtry
-    Xpath 1048576                              " X: 0
-endfunction
-
-let retcode = I()
-Xpath 2097152                                  " X: 2097152
-
-if retcode < 0
-    Xpath 4194304                              " X: 0
-endif
-if retcode % 4
-    Xpath 8388608                              " X: 0
-endif
-if (retcode/4) % 2
-    Xpath 16777216                             " X: 16777216
-endif
-if (retcode/8) % 2
-    Xpath 33554432                             " X: 0
-endif
-if (retcode/16) % 2
-    Xpath 67108864                             " X: 67108864
-endif
-if (retcode/32) % 2
-    Xpath 134217728                            " X: 0
-endif
-if (retcode/64) % 2
-    Xpath 268435456                            " X: 268435456
-endif
-if retcode/128
-    Xpath 536870912                            " X: 0
-endif
-
-unlet retcode
-delfunction F
-delfunction G
-delfunction H
-delfunction I
-
-Xcheck 354833067
-
-
-"-------------------------------------------------------------------------------
-" Test 33:  :return under :execute or user command and :finally                    {{{1
-"
-"          A :return command may be executed under an ":execute" or from
-"          a user command.  Executing of :finally clauses and passing through
-"          the return code works also then.
-"-------------------------------------------------------------------------------
-XpathINIT
-
-command! -nargs=? RETURN
-    \ try | return <args> | finally | return <args> * 2 | endtry
-
-function! F()
-    try
-       RETURN 8
-       Xpath 1                                 " X: 0
-    finally
-       Xpath 2                                 " X: 2
-    endtry
-    Xpath 4                                    " X: 0
-endfunction
-
-function! G()
-    try
-       RETURN 32
-       Xpath 8                                 " X: 0
-    finally
-       Xpath 16                                " X: 16
-       RETURN 128
-       Xpath 32                                " X: 0
-    endtry
-    Xpath 64                                   " X: 0
-endfunction
-
-function! H()
-    try
-       execute "try | return 512 | finally | return 1024 | endtry"
-       Xpath 128                               " X: 0
-    finally
-       Xpath 256                               " X: 256
-    endtry
-    Xpath 512                                  " X: 0
-endfunction
-
-function! I()
-    try
-       execute "try | return 2048 | finally | return 4096 | endtry"
-       Xpath 1024                              " X: 0
-    finally
-       Xpath 2048                              " X: 2048
-       execute "try | return 8192 | finally | return 16384 | endtry"
-       Xpath 4096                              " X: 0
-    endtry
-    Xpath 8192                                 " X: 0
-endfunction
-
-function! J()
-    try
-       RETURN 32768
-       Xpath 16384                             " X: 0
-    finally
-       Xpath 32768                             " X: 32768
-       return
-       Xpath 65536                             " X: 0
-    endtry
-    Xpath 131072                               " X: 0
-endfunction
-
-function! K()
-    try
-       execute "try | return 131072 | finally | return 262144 | endtry"
-       Xpath 262144                            " X: 0
-    finally
-       Xpath 524288                            " X: 524288
-       execute "try | return 524288 | finally | return | endtry"
-       Xpath 1048576                           " X: 0
-    endtry
-    Xpath 2097152                              " X: 0
-endfunction
-
-function! L()
-    try
-       return
-       Xpath 4194304                           " X: 0
-    finally
-       Xpath 8388608                           " X: 8388608
-       RETURN 1048576
-       Xpath 16777216                          " X: 0
-    endtry
-    Xpath 33554432                             " X: 0
-endfunction
-
-function! M()
-    try
-       return
-       Xpath 67108864                          " X: 0
-    finally
-       Xpath 134217728                         " X: 134217728
-       execute "try | return 4194304 | finally | return 8388608 | endtry"
-       Xpath 268435456                         " X: 0
-    endtry
-    Xpath 536870912                            " X: 0
-endfunction
-
-function! N()
-    RETURN 16777216
-endfunction
-
-function! O()
-    execute "try | return 67108864 | finally | return 134217728 | endtry"
-endfunction
-
-let sum             = F() + G() + H()  + I()   + J() + K() + L()     + M()
-let expected = 16  + 256 + 1024 + 16384 + 0   + 0   + 2097152 + 8388608
-let sum             = sum      + N()      + O()
-let expected = expected + 33554432 + 134217728
-
-if sum == expected
-    Xout "sum = " . sum . " (ok)"
-else
-    Xout "sum = " . sum . ", expected: " . expected
-endif
-
-Xpath 1073741824                               " X: 1073741824
-
-if sum != expected
-    " The Xpath command does not accept 2^31 (negative); add explicitly:
-    let Xpath = Xpath + 2147483648             " X: 0
-endif
-
-unlet sum expected
-delfunction F
-delfunction G
-delfunction H
-delfunction I
-delfunction J
-delfunction K
-delfunction L
-delfunction M
-delfunction N
-delfunction O
-
-Xcheck 1216907538
-
-
-"-------------------------------------------------------------------------------
-" Test 34:  :finally reason discarded by :continue                         {{{1
-"
-"          When a :finally clause is executed due to a :continue, :break,
-"          :return, :finish, error, interrupt or :throw, the jump reason is
-"          discarded by a :continue in the finally clause.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-if ExtraVim()
-
-    XloopINIT! 1 8
-
-    function! C(jump)
-       XloopNEXT
-       let loop = 0
-       while loop < 2
-           let loop = loop + 1
-           if loop == 1
-               try
-                   if a:jump == "continue"
-                       continue
-                   elseif a:jump == "break"
-                       break
-                   elseif a:jump == "return" || a:jump == "finish"
-                       return
-                   elseif a:jump == "error"
-                       asdf
-                   elseif a:jump == "interrupt"
-                       "INTERRUPT
-                       let dummy = 0
-                   elseif a:jump == "throw"
-                       throw "abc"
-                   endif
-               finally
-                   continue    " discards jump that caused the :finally
-                   Xloop 1             " X: 0
-               endtry
-               Xloop 2                 " X: 0
-           elseif loop == 2
-               Xloop 4                 " X: 4*(1+8+64+512+4096+32768+262144)
-           endif
-       endwhile
-    endfunction
-
-    call C("continue")
-    Xpath 2097152                              " X: 2097152
-    call C("break")
-    Xpath 4194304                              " X: 4194304
-    call C("return")
-    Xpath 8388608                              " X: 8388608
-    let g:jump = "finish"
-    ExecAsScript C
-    unlet g:jump
-    Xpath 16777216                             " X: 16777216
-    try
-       call C("error")
-       Xpath 33554432                          " X: 33554432
-    finally
-       Xpath 67108864                          " X: 67108864
-       try
-           call C("interrupt")
-           Xpath 134217728                     " X: 134217728
-       finally
-           Xpath 268435456                     " X: 268435456
-           call C("throw")
-           Xpath 536870912                     " X: 536870912
+           Xpath 268435456                     " X: 268435456
+           call C("throw")
+           Xpath 536870912                     " X: 536870912
        endtry
     endtry
     Xpath 1073741824                           " X: 1073741824
@@ -2654,2960 +2090,1658 @@ endif
 
 Xcheck 357908480
 
+" Tests 41 to 48 were moved to test_trycatch.vim
+let Xtest = 49
+
 
 "-------------------------------------------------------------------------------
-" Test 41:  Skipped :throw finding next command                                    {{{1
+" Test 49:  Throwing exceptions across functions                           {{{1
 "
-"          A :throw in an inactive conditional must not hide a following
-"          command.
+"          When an exception is thrown but not caught inside a function, the
+"          caller is checked for a matching :catch clause.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-function! F()
-    Xpath 1                                    " X: 1
-    if 0 | throw "never" | endif | Xpath 2     " X: 2
-    Xpath 4                                    " X: 4
-endfunction
-
-function! G()
-    Xpath 8                                        " X: 8
-    while 0 | throw "never" | endwhile | Xpath 16   " X: 16
-    Xpath 32                                       " X: 32
-endfunction
-
-function H()
-    Xpath 64                                               " X: 64
-    if 0 | try | throw "never" | endtry | endif | Xpath 128 " X: 128
-    Xpath 256                                              " X: 256
+function! C()
+    try
+       Xpath 1                                 " X: 1
+       throw "arrgh"
+       Xpath 2                                 " X: 0
+    catch /arrgh/
+       Xpath 4                                 " X: 4
+    endtry
+    Xpath 8                                    " X: 8
 endfunction
 
-Xpath 512                                      " X: 512
+XloopINIT! 16 16
 
-try
-    Xpath 1024                                 " X: 1024
-    call F()
-    Xpath 2048                                 " X: 2048
-catch /.*/
-    Xpath 4096                                 " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
+function! T1()
+    XloopNEXT
+    try
+       Xloop 1                                 " X: 16 + 16*16
+       throw "arrgh"
+       Xloop 2                                 " X: 0
+    finally
+       Xloop 4                                 " X: 64 + 64*16
+    endtry
+    Xloop 8                                    " X: 0
+endfunction
 
-Xpath 8192                                     " X: 8192
+function! T2()
+    try
+       Xpath 4096                              " X: 4096
+       call T1()
+       Xpath 8192                              " X: 0
+    finally
+       Xpath 16384                             " X: 16384
+    endtry
+    Xpath 32768                                        " X: 0
+endfunction
 
 try
-    Xpath 16384                                        " X: 16384
-    call G()
-    Xpath 32768                                        " X: 32768
+    Xpath 65536                                        " X: 65536
+    call C()   " throw and catch
+    Xpath 131072                               " X: 131072
 catch /.*/
-    Xpath 65536                                        " X: 0
+    Xpath 262144                               " X: 0
     Xout v:exception "in" v:throwpoint
 endtry
 
-Xpath 131072                                   " X: 131072
-
 try
-    Xpath 262144                               " X: 262144
-    call H()
     Xpath 524288                               " X: 524288
-catch /.*/
+    call T1()  " throw, one level
     Xpath 1048576                              " X: 0
+catch /arrgh/
+    Xpath 2097152                              " X: 2097152
+catch /.*/
+    Xpath 4194304                              " X: 0
     Xout v:exception "in" v:throwpoint
 endtry
 
-Xpath 2097152                                  " X: 2097152
+try
+    Xpath 8388608                              " X: 8388608
+    call T2()  " throw, two levels
+    Xpath 16777216                             " X: 0
+catch /arrgh/
+    Xpath 33554432                             " X: 33554432
+catch /.*/
+    Xpath 67108864                             " X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
+Xpath 134217728                                        " X: 134217728
 
-delfunction F
-delfunction G
-delfunction H
+Xcheck 179000669
 
-Xcheck 3076095
+" Leave C, T1, and T2 for execution as scripts in the next test.
 
 
 "-------------------------------------------------------------------------------
-" Test 42:  Catching number and string exceptions                          {{{1
+" Test 50:  Throwing exceptions across script files                        {{{1
+"
+"          When an exception is thrown but not caught inside a script file,
+"          the sourcing script or function is checked for a matching :catch
+"          clause.
 "
-"          When a number is thrown, it is converted to a string exception.
-"          Numbers and strings may be caught by specifying a regular exception
-"          as argument to the :catch command.
+"          This test executes the bodies of the functions C, T1, and T2 from
+"          the previous test as script files (:return replaced by :finish).
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-try
-
-    try
-       Xpath 1                                 " X: 1
-       throw 4711
-       Xpath 2                                 " X: 0
-    catch /4711/
-       Xpath 4                                 " X: 4
-    endtry
-
-    try
-       Xpath 8                                 " X: 8
-       throw 4711
-       Xpath 16                                " X: 0
-    catch /^4711$/
-       Xpath 32                                " X: 32
-    endtry
+let scriptC = MakeScript("C")                  " X: 1 + 4 + 8
+delfunction C
 
-    try
-       Xpath 64                                " X: 64
-       throw 4711
-       Xpath 128                               " X: 0
-    catch /\d/
-       Xpath 256                               " X: 256
-    endtry
+XloopINIT! 16 16
 
-    try
-       Xpath 512                               " X: 512
-       throw 4711
-       Xpath 1024                              " X: 0
-    catch /^\d\+$/
-       Xpath 2048                              " X: 2048
-    endtry
+let scriptT1 = MakeScript("T1")                        " X: 16 + 64 + 16*16 + 64*16
+delfunction T1
 
-    try
-       Xpath 4096                              " X: 4096
-       throw "arrgh"
-       Xpath 8192                              " X: 0
-    catch /arrgh/
-       Xpath 16384                             " X: 16384
-    endtry
+let scriptT2 = MakeScript("T2", scriptT1)      " X: 4096 + 16384
+delfunction T2
 
+function! F()
     try
-       Xpath 32768                             " X: 32768
-       throw "arrgh"
-       Xpath 65536                             " X: 0
-    catch /^arrgh$/
+       Xpath 65536                             " X: 65536
+       exec "source" g:scriptC
        Xpath 131072                            " X: 131072
+    catch /.*/
+       Xpath 262144                            " X: 0
+       Xout v:exception "in" v:throwpoint
     endtry
 
     try
-       Xpath 262144                            " X: 262144
-       throw "arrgh"
-       Xpath 524288                            " X: 0
-    catch /\l/
-       Xpath 1048576                           " X: 1048576
-    endtry
-
-    try
+       Xpath 524288                            " X: 524288
+       exec "source" g:scriptT1
+       Xpath 1048576                           " X: 0
+    catch /arrgh/
        Xpath 2097152                           " X: 2097152
-       throw "arrgh"
+    catch /.*/
        Xpath 4194304                           " X: 0
-    catch /^\l\+$/
-       Xpath 8388608                           " X: 8388608
-    endtry
-
-    try
-       try
-           Xpath 16777216                      " X: 16777216
-           throw "ARRGH"
-           Xpath 33554432                      " X: 0
-       catch /^arrgh$/
-           Xpath 67108864                      " X: 0
-       endtry
-    catch /^\carrgh$/
-       Xpath 134217728                         " X: 134217728
-    endtry
-
-    try
-       Xpath 268435456                         " X: 268435456
-       throw ""
-       Xpath 536870912                         " X: 0
-    catch /^$/
-       Xpath 1073741824                        " X: 1073741824
+       Xout v:exception "in" v:throwpoint
     endtry
+endfunction
 
+try
+    Xpath 8388608                              " X: 8388608
+    call F()
+    Xpath 16777216                             " X: 16777216
+    exec "source" scriptT2
+    Xpath 33554432                             " X: 0
+catch /arrgh/
+    Xpath 67108864                             " X: 67108864
 catch /.*/
-    " The Xpath command does not accept 2^31 (negative); add explicitly:
-    let Xpath = Xpath + 2147483648             " X: 0
+    Xpath 134217728                            " X: 0
     Xout v:exception "in" v:throwpoint
 endtry
+Xpath 268435456                                        " X: 268435456
+
+call delete(scriptC)
+call delete(scriptT1)
+call delete(scriptT2)
+unlet scriptC scriptT1 scriptT2
+delfunction F
+
+Xcheck 363550045
 
-Xcheck 1505155949
+" Test 51 was moved to test_trycatch.vim
+let Xtest = 52
 
 
 "-------------------------------------------------------------------------------
-" Test 43:  Selecting the correct :catch clause                                    {{{1
+" Test 52:  Uncaught exceptions                                                    {{{1
 "
-"          When an exception is thrown and there are multiple :catch clauses,
-"          the first matching one is taken.
+"          When an exception is thrown but not caught, an error message is
+"          displayed when the script is terminated.  In case of an interrupt
+"          or error exception, the normal interrupt or error message(s) are
+"          displayed.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-XloopINIT 1 1024
-let loops = 3
-while loops > 0
+let msgfile = tempname()
+
+function! MESSAGES(...)
     try
-       if loops == 3
-           Xloop 1                             " X: 1
-           throw "a"
-           Xloop 2                             " X: 0
-       elseif loops == 2
-           Xloop 4                             " X: 4*1024
-           throw "ab"
-           Xloop 8                             " X: 0
-       elseif loops == 1
-           Xloop 16                            " X: 16*1024*1024
-           throw "abc"
-           Xloop 32                            " X: 0
-       endif
-    catch /abc/
-       Xloop 64                                " X: 64*1024*1024
-    catch /ab/
-       Xloop 128                               " X: 128*1024
-    catch /.*/
-       Xloop 256                               " X: 256
-    catch /a/
-       Xloop 512                               " X: 0
+       exec "edit" g:msgfile
+    catch /^Vim(edit):/
+       return 0
     endtry
 
-    let loops = loops - 1
-    XloopNEXT
-endwhile
-Xpath 1073741824                               " X: 1073741824
-
-unlet loops
+    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+    let match = 1
+    norm gg
 
-Xcheck 1157763329
+    let num = a:0 / 2
+    let cnt = 1
+    while cnt <= num
+       let enr = a:{2*cnt - 1}
+       let emsg= a:{2*cnt}
+       let cnt = cnt + 1
 
+       if enr == ""
+           Xout "TODO: Add message number for:" emsg
+       elseif enr == "INT"
+           let enr = ""
+       endif
+       if enr == "" && !english
+           continue
+       endif
+       let pattern = (enr != "") ? enr . ':.*' : ''
+       if english
+           let pattern = pattern . emsg
+       endif
+       if !search(pattern, "W")
+           let match = 0
+           Xout "No match for:" pattern
+       endif
+       norm $
+    endwhile
 
-"-------------------------------------------------------------------------------
-" Test 44:  Missing or empty :catch patterns                               {{{1
-"
-"          A missing or empty :catch pattern means the same as /.*/, that is,
-"          catches everything.  To catch only empty exceptions, /^$/ must be
-"          used.  A :catch with missing, empty, or /.*/ argument also works
-"          when followed by another command separated by a bar on the same
-"          line.  :catch patterns cannot be specified between ||.  But other
-"          pattern separators can be used instead of //.
-"-------------------------------------------------------------------------------
+    bwipeout!
+    return match
+endfunction
 
-XpathINIT
+if ExtraVim(msgfile)
+    Xpath 1                                    " X: 1
+    throw "arrgh"
+endif
 
-try
-    try
-       Xpath 1                                 " X: 1
-       throw ""
-    catch /^$/
-       Xpath 2                                 " X: 2
-    endtry
+Xpath 2                                                " X: 2
+if !MESSAGES('E605', "Exception not caught")
+    Xpath 4                                    " X: 0
+endif
 
+if ExtraVim(msgfile)
     try
-       Xpath 4                                 " X: 4
-       throw ""
-    catch /.*/
        Xpath 8                                 " X: 8
+       throw "oops"
+    catch /arrgh/
+       Xpath 16                                " X: 0
     endtry
+    Xpath 32                                   " X: 0
+endif
 
-    try
-       Xpath 16                                " X: 16
-       throw ""
-    catch //
-       Xpath 32                                " X: 32
-    endtry
+Xpath 64                                       " X: 64
+if !MESSAGES('E605', "Exception not caught")
+    Xpath 128                                  " X: 0
+endif
 
-    try
-       Xpath 64                                " X: 64
-       throw ""
-    catch
-       Xpath 128                               " X: 128
-    endtry
+if ExtraVim(msgfile)
+    function! T()
+       throw "brrr"
+    endfunction
 
     try
        Xpath 256                               " X: 256
-       throw "oops"
-    catch /^$/
-       Xpath 512                               " X: 0
+       throw "arrgh"
     catch /.*/
-       Xpath 1024                              " X: 1024
+       Xpath 512                               " X: 512
+       call T()
     endtry
+    Xpath 1024                                 " X: 0
+endif
 
-    try
-       Xpath 2048                              " X: 2048
-       throw "arrgh"
-    catch /^$/
-       Xpath 4096                              " X: 0
-    catch //
-       Xpath 8192                              " X: 8192
-    endtry
+Xpath 2048                                     " X: 2048
+if !MESSAGES('E605', "Exception not caught")
+    Xpath 4096                                 " X: 0
+endif
 
+if ExtraVim(msgfile)
     try
+       Xpath 8192                              " X: 8192
+       throw "arrgh"
+    finally
        Xpath 16384                             " X: 16384
        throw "brrr"
-    catch /^$/
-       Xpath 32768                             " X: 0
-    catch
-       Xpath 65536                             " X: 65536
     endtry
+    Xpath 32768                                        " X: 0
+endif
 
-    try | Xpath 131072 | throw "x" | catch /.*/ | Xpath 262144 | endtry
-                                               " X: 131072 + 262144
+Xpath 65536                                    " X: 65536
+if !MESSAGES('E605', "Exception not caught")
+    Xpath 131072                               " X: 0
+endif
 
-    try | Xpath 524288 | throw "y" | catch // | Xpath 1048576 | endtry
-                                               " X: 524288 + 1048576
+if ExtraVim(msgfile)
+    try
+       Xpath 262144                            " X: 262144
+       "INTERRUPT
+    endtry
+    Xpath 524288                               " X: 0
+endif
 
-    while 1
-       try
-           let caught = 0
-           let v:errmsg = ""
-           " Extra try level:  if ":catch" without arguments below raises
-           " a syntax error because it misinterprets the "Xpath" as a pattern,
-           " let it be caught by the ":catch /.*/" below.
-           try
-               try | Xpath 2097152 | throw "z" | catch | Xpath 4194304 | :
-               endtry                          " X: 2097152 + 4194304
-           endtry
-       catch /.*/
-           let caught = 1
-           Xout v:exception "in" v:throwpoint
-       finally
-           if $VIMNOERRTHROW && v:errmsg != ""
-               Xout v:errmsg
-           endif
-           if caught || $VIMNOERRTHROW && v:errmsg != ""
-               Xpath 8388608                           " X: 0
-           endif
-           break               " discard error for $VIMNOERRTHROW
-       endtry
-    endwhile
+Xpath 1048576                                  " X: 1048576
+if !MESSAGES('INT', "Interrupted")
+    Xpath 2097152                              " X: 0
+endif
 
-    let cologne = 4711
+if ExtraVim(msgfile)
     try
-       try
-           Xpath 16777216                      " X: 16777216
-           throw "throw cologne"
-       " Next lines catches all and throws 4711:
-       catch |throw cologne|
-           Xpath 33554432                      " X: 0
-       endtry
-    catch /4711/
-       Xpath 67108864                          " X: 67108864
+       Xpath 4194304                           " X: 4194304
+       let x = novar   " error E121; exception: E121
+    catch /E15:/       " should not catch
+       Xpath 8388608                           " X: 0
     endtry
+    Xpath 16777216                             " X: 0
+endif
+
+Xpath 33554432                                 " X: 33554432
+if !MESSAGES('E121', "Undefined variable")
+    Xpath 67108864                             " X: 0
+endif
 
+if ExtraVim(msgfile)
     try
        Xpath 134217728                         " X: 134217728
-       throw "plus"
-    catch +plus+
-       Xpath 268435456                         " X: 268435456
+"      unlet novar #   " error E108/E488; exception: E488
+    catch /E108:/      " should not catch
+       Xpath 268435456                         " X: 0
     endtry
+    Xpath 536870912                            " X: 0
+endif
 
-    Xpath 536870912                            " X: 536870912
-catch /.*/
-    Xpath 1073741824                           " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
+Xpath 1073741824                               " X: 1073741824
+if !MESSAGES('E108', "No such variable", 'E488', "Trailing characters")
+    " The Xpath command does not accept 2^31 (negative); add explicitly:
+    let Xpath = Xpath + 2147483648             " X: 0
+endif
 
-unlet! caught cologne
+call delete(msgfile)
+unlet msgfile
+
+Xcheck 1247112011
 
-Xcheck 1031761407
+" Leave MESSAGES() for the next tests.
 
 
 "-------------------------------------------------------------------------------
-" Test 45:  Catching exceptions from nested :try blocks                            {{{1
+" Test 53:  Nesting errors: :endif/:else/:elseif                           {{{1
+"
+"          For nesting errors of :if conditionals the correct error messages
+"          should be given.
 "
-"          When :try blocks are nested, an exception is caught by the innermost
-"          try conditional that has a matching :catch clause.
+"          This test reuses the function MESSAGES() from the previous test.
+"          This functions checks the messages in g:msgfile.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-XloopINIT 1 1024
-let loops = 3
-while loops > 0
-    try
-       try
-           try
-               try
-                   if loops == 3
-                       Xloop 1                 " X: 1
-                       throw "a"
-                       Xloop 2                 " X: 0
-                   elseif loops == 2
-                       Xloop 4                 " X: 4*1024
-                       throw "ab"
-                       Xloop 8                 " X: 0
-                   elseif loops == 1
-                       Xloop 16                " X: 16*1024*1024
-                       throw "abc"
-                       Xloop 32                " X: 0
-                   endif
-               catch /abc/
-                   Xloop 64                    " X: 64*1024*1024
-               endtry
-           catch /ab/
-               Xloop 128                       " X: 128*1024
-           endtry
-       catch /.*/
-           Xloop 256                           " X: 256
-       endtry
-    catch /a/
-       Xloop 512                               " X: 0
-    endtry
-
-    let loops = loops - 1
-    XloopNEXT
-endwhile
-Xpath 1073741824                               " X: 1073741824
+let msgfile = tempname()
 
-unlet loops
+if ExtraVim(msgfile)
+"   endif
+endif
+if MESSAGES('E580', ":endif without :if")
+    Xpath 1                                    " X: 1
+endif
 
-Xcheck 1157763329
+if ExtraVim(msgfile)
+"   while 1
+"       endif
+"   endwhile
+endif
+if MESSAGES('E580', ":endif without :if")
+    Xpath 2                                    " X: 2
+endif
 
+if ExtraVim(msgfile)
+"   try
+"   finally
+"       endif
+"   endtry
+endif
+if MESSAGES('E580', ":endif without :if")
+    Xpath 4                                    " X: 4
+endif
 
-"-------------------------------------------------------------------------------
-" Test 46:  Executing :finally after a :throw in nested :try               {{{1
-"
-"          When an exception is thrown from within nested :try blocks, the
-"          :finally clauses of the non-catching try conditionals should be
-"          executed before the matching :catch of the next surrounding :try
-"          gets the control.  If this also has a :finally clause, it is
-"          executed afterwards.
-"-------------------------------------------------------------------------------
+if ExtraVim(msgfile)
+"   try
+"       endif
+"   endtry
+endif
+if MESSAGES('E580', ":endif without :if")
+    Xpath 8                                    " X: 8
+endif
 
-XpathINIT
+if ExtraVim(msgfile)
+"   try
+"       throw "a"
+"   catch /a/
+"       endif
+"   endtry
+endif
+if MESSAGES('E580', ":endif without :if")
+    Xpath 16                                   " X: 16
+endif
 
-let sum = 0
+if ExtraVim(msgfile)
+"   else
+endif
+if MESSAGES('E581', ":else without :if")
+    Xpath 32                                   " X: 32
+endif
 
-try
-    Xpath 1                                    " X: 1
-    try
-       Xpath 2                                 " X: 2
-       try
-           Xpath 4                             " X: 4
-           try
-               Xpath 8                         " X: 8
-               throw "ABC"
-               Xpath 16                        " X: 0
-           catch /xyz/
-               Xpath 32                        " X: 0
-           finally
-               Xpath 64                        " X: 64
-               if sum != 0
-                   Xpath 128                   " X: 0
-               endif
-               let sum = sum + 1
-           endtry
-           Xpath 256                           " X: 0
-       catch /123/
-           Xpath 512                           " X: 0
-       catch /321/
-           Xpath 1024                          " X: 0
-       finally
-           Xpath 2048                          " X: 2048
-           if sum != 1
-               Xpath 4096                      " X: 0
-           endif
-           let sum = sum + 2
-       endtry
-       Xpath 8192                              " X: 0
-    finally
-       Xpath 16384                             " X: 16384
-       if sum != 3
-           Xpath 32768                         " X: 0
-       endif
-       let sum = sum + 4
-    endtry
-    Xpath 65536                                        " X: 0
-catch /ABC/
-    Xpath 131072                               " X: 131072
-    if sum != 7
-       Xpath 262144                            " X: 0
-    endif
-    let sum = sum + 8
-finally
-    Xpath 524288                               " X: 524288
-    if sum != 15
-       Xpath 1048576                           " X: 0
-    endif
-    let sum = sum + 16
-endtry
-Xpath 65536                                    " X: 65536
-if sum != 31
-    Xpath 131072                               " X: 0
+if ExtraVim(msgfile)
+"   while 1
+"       else
+"   endwhile
+endif
+if MESSAGES('E581', ":else without :if")
+    Xpath 64                                   " X: 64
 endif
 
-unlet sum
+if ExtraVim(msgfile)
+"   try
+"   finally
+"       else
+"   endtry
+endif
+if MESSAGES('E581', ":else without :if")
+    Xpath 128                                  " X: 128
+endif
 
-Xcheck 739407
+if ExtraVim(msgfile)
+"   try
+"       else
+"   endtry
+endif
+if MESSAGES('E581', ":else without :if")
+    Xpath 256                                  " X: 256
+endif
 
+if ExtraVim(msgfile)
+"   try
+"       throw "a"
+"   catch /a/
+"       else
+"   endtry
+endif
+if MESSAGES('E581', ":else without :if")
+    Xpath 512                                  " X: 512
+endif
 
-"-------------------------------------------------------------------------------
-" Test 47:  Throwing exceptions from a :catch clause                       {{{1
-"
-"          When an exception is thrown from a :catch clause, it should not be
-"          caught by a :catch of the same :try conditional.  After executing
-"          the :finally clause (if present), surrounding try conditionals
-"          should be checked for a matching :catch.
-"-------------------------------------------------------------------------------
+if ExtraVim(msgfile)
+"   elseif
+endif
+if MESSAGES('E582', ":elseif without :if")
+    Xpath 1024                                 " X: 1024
+endif
 
-XpathINIT
+if ExtraVim(msgfile)
+"   while 1
+"       elseif
+"   endwhile
+endif
+if MESSAGES('E582', ":elseif without :if")
+    Xpath 2048                                 " X: 2048
+endif
 
-Xpath 1                                                " X: 1
-try
-    Xpath 2                                    " X: 2
-    try
-       Xpath 4                                 " X: 4
-       try
-           Xpath 8                             " X: 8
-           throw "x1"
-           Xpath 16                            " X: 0
-       catch /x1/
-           Xpath 32                            " X: 32
-           try
-               Xpath 64                        " X: 64
-               throw "x2"
-               Xpath 128                       " X: 0
-           catch /x1/
-               Xpath 256                       " X: 0
-           catch /x2/
-               Xpath 512                       " X: 512
-               try
-                   Xpath 1024                  " X: 1024
-                   throw "x3"
-                   Xpath 2048                  " X: 0
-               catch /x1/
-                   Xpath 4096                  " X: 0
-               catch /x2/
-                   Xpath 8192                  " X: 0
-               finally
-                   Xpath 16384                 " X: 16384
-               endtry
-               Xpath 32768                     " X: 0
-           catch /x3/
-               Xpath 65536                     " X: 0
-           endtry
-           Xpath 131072                        " X: 0
-       catch /x1/
-           Xpath 262144                        " X: 0
-       catch /x2/
-           Xpath 524288                        " X: 0
-       catch /x3/
-           Xpath 1048576                       " X: 0
-       finally
-           Xpath 2097152                       " X: 2097152
-       endtry
-       Xpath 4194304                           " X: 0
-    catch /x1/
-       Xpath 8388608                           " X: 0
-    catch /x2/
-       Xpath 16777216                          " X: 0
-    catch /x3/
-       Xpath 33554432                          " X: 33554432
-    endtry
-    Xpath 67108864                             " X: 67108864
-catch /.*/
-    Xpath 134217728                            " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-Xpath 268435456                                        " X: 268435456
-
-Xcheck 371213935
-
-
-"-------------------------------------------------------------------------------
-" Test 48:  Throwing exceptions from a :finally clause                     {{{1
-"
-"          When an exception is thrown from a :finally clause, it should not be
-"          caught by a :catch of the same :try conditional.  Surrounding try
-"          conditionals should be checked for a matching :catch.  A previously
-"          thrown exception is discarded.
-"-------------------------------------------------------------------------------
+if ExtraVim(msgfile)
+"   try
+"   finally
+"       elseif
+"   endtry
+endif
+if MESSAGES('E582', ":elseif without :if")
+    Xpath 4096                                 " X: 4096
+endif
 
-XpathINIT
+if ExtraVim(msgfile)
+"   try
+"       elseif
+"   endtry
+endif
+if MESSAGES('E582', ":elseif without :if")
+    Xpath 8192                                 " X: 8192
+endif
 
-try
+if ExtraVim(msgfile)
+"   try
+"       throw "a"
+"   catch /a/
+"       elseif
+"   endtry
+endif
+if MESSAGES('E582', ":elseif without :if")
+    Xpath 16384                                        " X: 16384
+endif
 
-    try
-       try
-           Xpath 1                             " X: 1
-       catch /x1/
-           Xpath 2                             " X: 0
-       finally
-           Xpath 4                             " X: 4
-           throw "x1"
-           Xpath 8                             " X: 0
-       endtry
-       Xpath 16                                " X: 0
-    catch /x1/
-       Xpath 32                                " X: 32
-    endtry
-    Xpath 64                                   " X: 64
+if ExtraVim(msgfile)
+"   if 1
+"   else
+"   else
+"   endif
+endif
+if MESSAGES('E583', "multiple :else")
+    Xpath 32768                                        " X: 32768
+endif
 
-    try
-       try
-           Xpath 128                           " X: 128
-           throw "x2"
-           Xpath 256                           " X: 0
-       catch /x2/
-           Xpath 512                           " X: 512
-       catch /x3/
-           Xpath 1024                          " X: 0
-       finally
-           Xpath 2048                          " X: 2048
-           throw "x3"
-           Xpath 4096                          " X: 0
-       endtry
-       Xpath 8192                              " X: 0
-    catch /x2/
-       Xpath 16384                             " X: 0
-    catch /x3/
-       Xpath 32768                             " X: 32768
-    endtry
+if ExtraVim(msgfile)
+"   if 1
+"   else
+"   elseif 1
+"   endif
+endif
+if MESSAGES('E584', ":elseif after :else")
     Xpath 65536                                        " X: 65536
+endif
 
-    try
-       try
-           try
-               Xpath 131072                    " X: 131072
-               throw "x4"
-               Xpath 262144                    " X: 0
-           catch /x5/
-               Xpath 524288                    " X: 0
-           finally
-               Xpath 1048576                   " X: 1048576
-               throw "x5"      " discards "x4"
-               Xpath 2097152                   " X: 0
-           endtry
-           Xpath 4194304                       " X: 0
-       catch /x4/
-           Xpath 8388608                       " X: 0
-       finally
-           Xpath 16777216                      " X: 16777216
-       endtry
-       Xpath 33554432                          " X: 0
-    catch /x5/
-       Xpath 67108864                          " X: 67108864
-    endtry
-    Xpath 134217728                            " X: 134217728
+call delete(msgfile)
+unlet msgfile
 
-catch /.*/
-    Xpath 268435456                            " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-Xpath 536870912                                        " X: 536870912
+Xcheck 131071
 
-Xcheck 756255461
+" Leave MESSAGES() for the next test.
 
 
 "-------------------------------------------------------------------------------
-" Test 49:  Throwing exceptions across functions                           {{{1
+" Test 54:  Nesting errors: :while/:endwhile                               {{{1
 "
-"          When an exception is thrown but not caught inside a function, the
-"          caller is checked for a matching :catch clause.
+"          For nesting errors of :while conditionals the correct error messages
+"          should be given.
+"
+"          This test reuses the function MESSAGES() from the previous test.
+"          This functions checks the messages in g:msgfile.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-function! C()
-    try
-       Xpath 1                                 " X: 1
-       throw "arrgh"
-       Xpath 2                                 " X: 0
-    catch /arrgh/
-       Xpath 4                                 " X: 4
-    endtry
-    Xpath 8                                    " X: 8
-endfunction
-
-XloopINIT! 16 16
+let msgfile = tempname()
 
-function! T1()
-    XloopNEXT
-    try
-       Xloop 1                                 " X: 16 + 16*16
-       throw "arrgh"
-       Xloop 2                                 " X: 0
-    finally
-       Xloop 4                                 " X: 64 + 64*16
-    endtry
-    Xloop 8                                    " X: 0
-endfunction
+if ExtraVim(msgfile)
+"   endwhile
+endif
+if MESSAGES('E588', ":endwhile without :while")
+    Xpath 1                                    " X: 1
+endif
 
-function! T2()
-    try
-       Xpath 4096                              " X: 4096
-       call T1()
-       Xpath 8192                              " X: 0
-    finally
-       Xpath 16384                             " X: 16384
-    endtry
-    Xpath 32768                                        " X: 0
-endfunction
+if ExtraVim(msgfile)
+"   if 1
+"       endwhile
+"   endif
+endif
+if MESSAGES('E588', ":endwhile without :while")
+    Xpath 2                                    " X: 2
+endif
 
-try
-    Xpath 65536                                        " X: 65536
-    call C()   " throw and catch
-    Xpath 131072                               " X: 131072
-catch /.*/
-    Xpath 262144                               " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
+if ExtraVim(msgfile)
+"   while 1
+"       if 1
+"   endwhile
+endif
+if MESSAGES('E171', "Missing :endif")
+    Xpath 4                                    " X: 4
+endif
 
-try
-    Xpath 524288                               " X: 524288
-    call T1()  " throw, one level
-    Xpath 1048576                              " X: 0
-catch /arrgh/
-    Xpath 2097152                              " X: 2097152
-catch /.*/
-    Xpath 4194304                              " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
+if ExtraVim(msgfile)
+"   try
+"   finally
+"       endwhile
+"   endtry
+endif
+if MESSAGES('E588', ":endwhile without :while")
+    Xpath 8                                    " X: 8
+endif
 
-try
-    Xpath 8388608                              " X: 8388608
-    call T2()  " throw, two levels
-    Xpath 16777216                             " X: 0
-catch /arrgh/
-    Xpath 33554432                             " X: 33554432
-catch /.*/
-    Xpath 67108864                             " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-Xpath 134217728                                        " X: 134217728
+if ExtraVim(msgfile)
+"   while 1
+"       try
+"       finally
+"   endwhile
+endif
+if MESSAGES('E600', "Missing :endtry")
+    Xpath 16                                   " X: 16
+endif
 
-Xcheck 179000669
+if ExtraVim(msgfile)
+"   while 1
+"       if 1
+"          try
+"          finally
+"   endwhile
+endif
+if MESSAGES('E600', "Missing :endtry")
+    Xpath 32                                   " X: 32
+endif
 
-" Leave C, T1, and T2 for execution as scripts in the next test.
+if ExtraVim(msgfile)
+"   while 1
+"       try
+"       finally
+"          if 1
+"   endwhile
+endif
+if MESSAGES('E171', "Missing :endif")
+    Xpath 64                                   " X: 64
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       endwhile
+"   endtry
+endif
+if MESSAGES('E588', ":endwhile without :while")
+    Xpath 128                                  " X: 128
+endif
+
+if ExtraVim(msgfile)
+"   while 1
+"       try
+"          endwhile
+"       endtry
+"   endwhile
+endif
+if MESSAGES('E588', ":endwhile without :while")
+    Xpath 256                                  " X: 256
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       throw "a"
+"   catch /a/
+"       endwhile
+"   endtry
+endif
+if MESSAGES('E588', ":endwhile without :while")
+    Xpath 512                                  " X: 512
+endif
+
+if ExtraVim(msgfile)
+"   while 1
+"       try
+"          throw "a"
+"      catch /a/
+"          endwhile
+"       endtry
+"   endwhile
+endif
+if MESSAGES('E588', ":endwhile without :while")
+    Xpath 1024                                 " X: 1024
+endif
+
+
+call delete(msgfile)
+unlet msgfile
+
+Xcheck 2047
+
+" Leave MESSAGES() for the next test.
 
 
 "-------------------------------------------------------------------------------
-" Test 50:  Throwing exceptions across script files                        {{{1
+" Test 55:  Nesting errors: :continue/:break                               {{{1
 "
-"          When an exception is thrown but not caught inside a script file,
-"          the sourcing script or function is checked for a matching :catch
-"          clause.
+"          For nesting errors of :continue and :break commands the correct
+"          error messages should be given.
 "
-"          This test executes the bodies of the functions C, T1, and T2 from
-"          the previous test as script files (:return replaced by :finish).
+"          This test reuses the function MESSAGES() from the previous test.
+"          This functions checks the messages in g:msgfile.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-let scriptC = MakeScript("C")                  " X: 1 + 4 + 8
-delfunction C
+let msgfile = tempname()
 
-XloopINIT! 16 16
+if ExtraVim(msgfile)
+"   continue
+endif
+if MESSAGES('E586', ":continue without :while")
+    Xpath 1                                    " X: 1
+endif
 
-let scriptT1 = MakeScript("T1")                        " X: 16 + 64 + 16*16 + 64*16
-delfunction T1
+if ExtraVim(msgfile)
+"   if 1
+"       continue
+"   endif
+endif
+if MESSAGES('E586', ":continue without :while")
+    Xpath 2                                    " X: 2
+endif
 
-let scriptT2 = MakeScript("T2", scriptT1)      " X: 4096 + 16384
-delfunction T2
+if ExtraVim(msgfile)
+"   try
+"   finally
+"       continue
+"   endtry
+endif
+if MESSAGES('E586', ":continue without :while")
+    Xpath 4                                    " X: 4
+endif
 
-function! F()
-    try
-       Xpath 65536                             " X: 65536
-       exec "source" g:scriptC
-       Xpath 131072                            " X: 131072
-    catch /.*/
-       Xpath 262144                            " X: 0
-       Xout v:exception "in" v:throwpoint
-    endtry
+if ExtraVim(msgfile)
+"   try
+"       continue
+"   endtry
+endif
+if MESSAGES('E586', ":continue without :while")
+    Xpath 8                                    " X: 8
+endif
 
-    try
-       Xpath 524288                            " X: 524288
-       exec "source" g:scriptT1
-       Xpath 1048576                           " X: 0
-    catch /arrgh/
-       Xpath 2097152                           " X: 2097152
-    catch /.*/
-       Xpath 4194304                           " X: 0
-       Xout v:exception "in" v:throwpoint
-    endtry
-endfunction
+if ExtraVim(msgfile)
+"   try
+"       throw "a"
+"   catch /a/
+"       continue
+"   endtry
+endif
+if MESSAGES('E586', ":continue without :while")
+    Xpath 16                                   " X: 16
+endif
 
-try
-    Xpath 8388608                              " X: 8388608
-    call F()
-    Xpath 16777216                             " X: 16777216
-    exec "source" scriptT2
-    Xpath 33554432                             " X: 0
-catch /arrgh/
-    Xpath 67108864                             " X: 67108864
-catch /.*/
-    Xpath 134217728                            " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-Xpath 268435456                                        " X: 268435456
+if ExtraVim(msgfile)
+"   break
+endif
+if MESSAGES('E587', ":break without :while")
+    Xpath 32                                   " X: 32
+endif
 
-call delete(scriptC)
-call delete(scriptT1)
-call delete(scriptT2)
-unlet scriptC scriptT1 scriptT2
-delfunction F
+if ExtraVim(msgfile)
+"   if 1
+"       break
+"   endif
+endif
+if MESSAGES('E587', ":break without :while")
+    Xpath 64                                   " X: 64
+endif
 
-Xcheck 363550045
+if ExtraVim(msgfile)
+"   try
+"   finally
+"       break
+"   endtry
+endif
+if MESSAGES('E587', ":break without :while")
+    Xpath 128                                  " X: 128
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       break
+"   endtry
+endif
+if MESSAGES('E587', ":break without :while")
+    Xpath 256                                  " X: 256
+endif
+
+if ExtraVim(msgfile)
+"   try
+"       throw "a"
+"   catch /a/
+"       break
+"   endtry
+endif
+if MESSAGES('E587', ":break without :while")
+    Xpath 512                                  " X: 512
+endif
+
+call delete(msgfile)
+unlet msgfile
+
+Xcheck 1023
+
+" Leave MESSAGES() for the next test.
 
 
 "-------------------------------------------------------------------------------
-" Test 51:  Throwing exceptions across :execute and user commands          {{{1
+" Test 56:  Nesting errors: :endtry                                        {{{1
+"
+"          For nesting errors of :try conditionals the correct error messages
+"          should be given.
 "
-"          A :throw command may be executed under an ":execute" or from
-"          a user command.
+"          This test reuses the function MESSAGES() from the previous test.
+"          This functions checks the messages in g:msgfile.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-command! -nargs=? THROW1    throw <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
+let msgfile = tempname()
 
-try
+if ExtraVim(msgfile)
+"   endtry
+endif
+if MESSAGES('E602', ":endtry without :try")
+    Xpath 1                                    " X: 1
+endif
 
-    try
-       try
-           Xpath 1                             " X: 1
-           THROW1 "A"
-       catch /A/
-           Xpath 2                             " X: 2
-       endtry
-    catch /1/
-       Xpath 4                                 " X: 0
-    endtry
-
-    try
-       try
-           Xpath 8                             " X: 8
-           THROW2 "B"
-       catch /B/
-           Xpath 16                            " X: 16
-       endtry
-    catch /2/
-       Xpath 32                                " X: 0
-    endtry
-
-    try
-       try
-           Xpath 64                            " X: 64
-           THROW3 "C"
-       catch /C/
-           Xpath 128                           " X: 128
-       endtry
-    catch /3/
-       Xpath 256                               " X: 0
-    endtry
-
-    try
-       try
-           Xpath 512                           " X: 512
-           THROW4 "D"
-       catch /D/
-           Xpath 1024                          " X: 1024
-       endtry
-    catch /4/
-       Xpath 2048                              " X: 0
-    endtry
-
-    try
-       try
-           Xpath 4096                          " X: 4096
-           execute 'throw "E" | throw 5'
-       catch /E/
-           Xpath 8192                          " X: 8192
-       endtry
-    catch /5/
-       Xpath 16384                             " X: 0
-    endtry
-
-    try
-       try
-           Xpath 32768                         " X: 32768
-           execute 'try | throw "F" | endtry | throw 6'
-       catch /F/
-           Xpath 65536                         " X: 65536
-       endtry
-    catch /6/
-       Xpath 131072                            " X: 0
-    endtry
-
-    try
-       try
-           Xpath 262144                        " X: 262144
-           execute'try | throw 7 | catch /7/ | throw "G" | endtry'
-       catch /G/
-           Xpath 524288                        " X: 524288
-       endtry
-    catch /7/
-       Xpath 1048576                           " X: 0
-    endtry
-
-    try
-       try
-           Xpath 2097152                       " X: 2097152
-           execute 'try | throw 8 | finally   | throw "H" | endtry'
-       catch /H/
-           Xpath 4194304                       " X: 4194304
-       endtry
-    catch /8/
-       Xpath 8388608                           " X: 0
-    endtry
-
-catch /.*/
-    Xpath 16777216                             " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-Xpath 33554432                                 " X: 33554432
-
-delcommand THROW1
-delcommand THROW2
-delcommand THROW3
-delcommand THROW4
-
-Xcheck 40744667
-
-
-"-------------------------------------------------------------------------------
-" Test 52:  Uncaught exceptions                                                    {{{1
-"
-"          When an exception is thrown but not caught, an error message is
-"          displayed when the script is terminated.  In case of an interrupt
-"          or error exception, the normal interrupt or error message(s) are
-"          displayed.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-let msgfile = tempname()
-
-function! MESSAGES(...)
-    try
-       exec "edit" g:msgfile
-    catch /^Vim(edit):/
-       return 0
-    endtry
-
-    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
-    let match = 1
-    norm gg
-
-    let num = a:0 / 2
-    let cnt = 1
-    while cnt <= num
-       let enr = a:{2*cnt - 1}
-       let emsg= a:{2*cnt}
-       let cnt = cnt + 1
-
-       if enr == ""
-           Xout "TODO: Add message number for:" emsg
-       elseif enr == "INT"
-           let enr = ""
-       endif
-       if enr == "" && !english
-           continue
-       endif
-       let pattern = (enr != "") ? enr . ':.*' : ''
-       if english
-           let pattern = pattern . emsg
-       endif
-       if !search(pattern, "W")
-           let match = 0
-           Xout "No match for:" pattern
-       endif
-       norm $
-    endwhile
-
-    bwipeout!
-    return match
-endfunction
+if ExtraVim(msgfile)
+"   if 1
+"       endtry
+"   endif
+endif
+if MESSAGES('E602', ":endtry without :try")
+    Xpath 2                                    " X: 2
+endif
 
 if ExtraVim(msgfile)
-    Xpath 1                                    " X: 1
-    throw "arrgh"
+"   while 1
+"       endtry
+"   endwhile
 endif
-
-Xpath 2                                                " X: 2
-if !MESSAGES('E605', "Exception not caught")
-    Xpath 4                                    " X: 0
+if MESSAGES('E602', ":endtry without :try")
+    Xpath 4                                    " X: 4
 endif
 
 if ExtraVim(msgfile)
-    try
-       Xpath 8                                 " X: 8
-       throw "oops"
-    catch /arrgh/
-       Xpath 16                                " X: 0
-    endtry
-    Xpath 32                                   " X: 0
+"   try
+"       if 1
+"   endtry
 endif
-
-Xpath 64                                       " X: 64
-if !MESSAGES('E605', "Exception not caught")
-    Xpath 128                                  " X: 0
+if MESSAGES('E171', "Missing :endif")
+    Xpath 8                                    " X: 8
 endif
 
 if ExtraVim(msgfile)
-    function! T()
-       throw "brrr"
-    endfunction
-
-    try
-       Xpath 256                               " X: 256
-       throw "arrgh"
-    catch /.*/
-       Xpath 512                               " X: 512
-       call T()
-    endtry
-    Xpath 1024                                 " X: 0
+"   try
+"       while 1
+"   endtry
 endif
-
-Xpath 2048                                     " X: 2048
-if !MESSAGES('E605', "Exception not caught")
-    Xpath 4096                                 " X: 0
+if MESSAGES('E170', "Missing :endwhile")
+    Xpath 16                                   " X: 16
 endif
 
 if ExtraVim(msgfile)
-    try
-       Xpath 8192                              " X: 8192
-       throw "arrgh"
-    finally
-       Xpath 16384                             " X: 16384
-       throw "brrr"
-    endtry
-    Xpath 32768                                        " X: 0
+"   try
+"   finally
+"       if 1
+"   endtry
 endif
-
-Xpath 65536                                    " X: 65536
-if !MESSAGES('E605', "Exception not caught")
-    Xpath 131072                               " X: 0
+if MESSAGES('E171', "Missing :endif")
+    Xpath 32                                   " X: 32
 endif
 
 if ExtraVim(msgfile)
-    try
-       Xpath 262144                            " X: 262144
-       "INTERRUPT
-    endtry
-    Xpath 524288                               " X: 0
+"   try
+"   finally
+"       while 1
+"   endtry
 endif
-
-Xpath 1048576                                  " X: 1048576
-if !MESSAGES('INT', "Interrupted")
-    Xpath 2097152                              " X: 0
+if MESSAGES('E170', "Missing :endwhile")
+    Xpath 64                                   " X: 64
 endif
 
 if ExtraVim(msgfile)
-    try
-       Xpath 4194304                           " X: 4194304
-       let x = novar   " error E121; exception: E121
-    catch /E15:/       " should not catch
-       Xpath 8388608                           " X: 0
-    endtry
-    Xpath 16777216                             " X: 0
+"   try
+"       throw "a"
+"   catch /a/
+"       if 1
+"   endtry
 endif
-
-Xpath 33554432                                 " X: 33554432
-if !MESSAGES('E121', "Undefined variable")
-    Xpath 67108864                             " X: 0
+if MESSAGES('E171', "Missing :endif")
+    Xpath 128                                  " X: 128
 endif
 
 if ExtraVim(msgfile)
-    try
-       Xpath 134217728                         " X: 134217728
-"      unlet novar #   " error E108/E488; exception: E488
-    catch /E108:/      " should not catch
-       Xpath 268435456                         " X: 0
-    endtry
-    Xpath 536870912                            " X: 0
+"   try
+"       throw "a"
+"   catch /a/
+"       while 1
+"   endtry
 endif
-
-Xpath 1073741824                               " X: 1073741824
-if !MESSAGES('E108', "No such variable", 'E488', "Trailing characters")
-    " The Xpath command does not accept 2^31 (negative); add explicitly:
-    let Xpath = Xpath + 2147483648             " X: 0
+if MESSAGES('E170', "Missing :endwhile")
+    Xpath 256                                  " X: 256
 endif
 
 call delete(msgfile)
 unlet msgfile
 
-Xcheck 1247112011
+delfunction MESSAGES
 
-" Leave MESSAGES() for the next tests.
+Xcheck 511
 
 
 "-------------------------------------------------------------------------------
-" Test 53:  Nesting errors: :endif/:else/:elseif                           {{{1
-"
-"          For nesting errors of :if conditionals the correct error messages
-"          should be given.
+" Test 57:  v:exception and v:throwpoint for user exceptions               {{{1
 "
-"          This test reuses the function MESSAGES() from the previous test.
-"          This functions checks the messages in g:msgfile.
+"          v:exception evaluates to the value of the exception that was caught
+"          most recently and is not finished.  (A caught exception is finished
+"          when the next ":catch", ":finally", or ":endtry" is reached.)
+"          v:throwpoint evaluates to the script/function name and line number
+"          where that exception has been thrown.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-let msgfile = tempname()
+function! FuncException()
+    let g:exception = v:exception
+endfunction
 
-if ExtraVim(msgfile)
-"   endif
-endif
-if MESSAGES('E580', ":endif without :if")
-    Xpath 1                                    " X: 1
-endif
-
-if ExtraVim(msgfile)
-"   while 1
-"       endif
-"   endwhile
-endif
-if MESSAGES('E580', ":endif without :if")
-    Xpath 2                                    " X: 2
-endif
-
-if ExtraVim(msgfile)
-"   try
-"   finally
-"       endif
-"   endtry
-endif
-if MESSAGES('E580', ":endif without :if")
-    Xpath 4                                    " X: 4
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       endif
-"   endtry
-endif
-if MESSAGES('E580', ":endif without :if")
-    Xpath 8                                    " X: 8
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       throw "a"
-"   catch /a/
-"       endif
-"   endtry
-endif
-if MESSAGES('E580', ":endif without :if")
-    Xpath 16                                   " X: 16
-endif
-
-if ExtraVim(msgfile)
-"   else
-endif
-if MESSAGES('E581', ":else without :if")
-    Xpath 32                                   " X: 32
-endif
-
-if ExtraVim(msgfile)
-"   while 1
-"       else
-"   endwhile
-endif
-if MESSAGES('E581', ":else without :if")
-    Xpath 64                                   " X: 64
-endif
-
-if ExtraVim(msgfile)
-"   try
-"   finally
-"       else
-"   endtry
-endif
-if MESSAGES('E581', ":else without :if")
-    Xpath 128                                  " X: 128
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       else
-"   endtry
-endif
-if MESSAGES('E581', ":else without :if")
-    Xpath 256                                  " X: 256
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       throw "a"
-"   catch /a/
-"       else
-"   endtry
-endif
-if MESSAGES('E581', ":else without :if")
-    Xpath 512                                  " X: 512
-endif
-
-if ExtraVim(msgfile)
-"   elseif
-endif
-if MESSAGES('E582', ":elseif without :if")
-    Xpath 1024                                 " X: 1024
-endif
-
-if ExtraVim(msgfile)
-"   while 1
-"       elseif
-"   endwhile
-endif
-if MESSAGES('E582', ":elseif without :if")
-    Xpath 2048                                 " X: 2048
-endif
-
-if ExtraVim(msgfile)
-"   try
-"   finally
-"       elseif
-"   endtry
-endif
-if MESSAGES('E582', ":elseif without :if")
-    Xpath 4096                                 " X: 4096
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       elseif
-"   endtry
-endif
-if MESSAGES('E582', ":elseif without :if")
-    Xpath 8192                                 " X: 8192
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       throw "a"
-"   catch /a/
-"       elseif
-"   endtry
-endif
-if MESSAGES('E582', ":elseif without :if")
-    Xpath 16384                                        " X: 16384
-endif
-
-if ExtraVim(msgfile)
-"   if 1
-"   else
-"   else
-"   endif
-endif
-if MESSAGES('E583', "multiple :else")
-    Xpath 32768                                        " X: 32768
-endif
-
-if ExtraVim(msgfile)
-"   if 1
-"   else
-"   elseif 1
-"   endif
-endif
-if MESSAGES('E584', ":elseif after :else")
-    Xpath 65536                                        " X: 65536
-endif
-
-call delete(msgfile)
-unlet msgfile
-
-Xcheck 131071
-
-" Leave MESSAGES() for the next test.
-
-
-"-------------------------------------------------------------------------------
-" Test 54:  Nesting errors: :while/:endwhile                               {{{1
-"
-"          For nesting errors of :while conditionals the correct error messages
-"          should be given.
-"
-"          This test reuses the function MESSAGES() from the previous test.
-"          This functions checks the messages in g:msgfile.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-let msgfile = tempname()
-
-if ExtraVim(msgfile)
-"   endwhile
-endif
-if MESSAGES('E588', ":endwhile without :while")
-    Xpath 1                                    " X: 1
-endif
-
-if ExtraVim(msgfile)
-"   if 1
-"       endwhile
-"   endif
-endif
-if MESSAGES('E588', ":endwhile without :while")
-    Xpath 2                                    " X: 2
-endif
-
-if ExtraVim(msgfile)
-"   while 1
-"       if 1
-"   endwhile
-endif
-if MESSAGES('E171', "Missing :endif")
-    Xpath 4                                    " X: 4
-endif
-
-if ExtraVim(msgfile)
-"   try
-"   finally
-"       endwhile
-"   endtry
-endif
-if MESSAGES('E588', ":endwhile without :while")
-    Xpath 8                                    " X: 8
-endif
-
-if ExtraVim(msgfile)
-"   while 1
-"       try
-"       finally
-"   endwhile
-endif
-if MESSAGES('E600', "Missing :endtry")
-    Xpath 16                                   " X: 16
-endif
-
-if ExtraVim(msgfile)
-"   while 1
-"       if 1
-"          try
-"          finally
-"   endwhile
-endif
-if MESSAGES('E600', "Missing :endtry")
-    Xpath 32                                   " X: 32
-endif
-
-if ExtraVim(msgfile)
-"   while 1
-"       try
-"       finally
-"          if 1
-"   endwhile
-endif
-if MESSAGES('E171', "Missing :endif")
-    Xpath 64                                   " X: 64
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       endwhile
-"   endtry
-endif
-if MESSAGES('E588', ":endwhile without :while")
-    Xpath 128                                  " X: 128
-endif
-
-if ExtraVim(msgfile)
-"   while 1
-"       try
-"          endwhile
-"       endtry
-"   endwhile
-endif
-if MESSAGES('E588', ":endwhile without :while")
-    Xpath 256                                  " X: 256
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       throw "a"
-"   catch /a/
-"       endwhile
-"   endtry
-endif
-if MESSAGES('E588', ":endwhile without :while")
-    Xpath 512                                  " X: 512
-endif
-
-if ExtraVim(msgfile)
-"   while 1
-"       try
-"          throw "a"
-"      catch /a/
-"          endwhile
-"       endtry
-"   endwhile
-endif
-if MESSAGES('E588', ":endwhile without :while")
-    Xpath 1024                                 " X: 1024
-endif
-
-
-call delete(msgfile)
-unlet msgfile
-
-Xcheck 2047
-
-" Leave MESSAGES() for the next test.
-
-
-"-------------------------------------------------------------------------------
-" Test 55:  Nesting errors: :continue/:break                               {{{1
-"
-"          For nesting errors of :continue and :break commands the correct
-"          error messages should be given.
-"
-"          This test reuses the function MESSAGES() from the previous test.
-"          This functions checks the messages in g:msgfile.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-let msgfile = tempname()
-
-if ExtraVim(msgfile)
-"   continue
-endif
-if MESSAGES('E586', ":continue without :while")
-    Xpath 1                                    " X: 1
-endif
-
-if ExtraVim(msgfile)
-"   if 1
-"       continue
-"   endif
-endif
-if MESSAGES('E586', ":continue without :while")
-    Xpath 2                                    " X: 2
-endif
-
-if ExtraVim(msgfile)
-"   try
-"   finally
-"       continue
-"   endtry
-endif
-if MESSAGES('E586', ":continue without :while")
-    Xpath 4                                    " X: 4
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       continue
-"   endtry
-endif
-if MESSAGES('E586', ":continue without :while")
-    Xpath 8                                    " X: 8
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       throw "a"
-"   catch /a/
-"       continue
-"   endtry
-endif
-if MESSAGES('E586', ":continue without :while")
-    Xpath 16                                   " X: 16
-endif
-
-if ExtraVim(msgfile)
-"   break
-endif
-if MESSAGES('E587', ":break without :while")
-    Xpath 32                                   " X: 32
-endif
-
-if ExtraVim(msgfile)
-"   if 1
-"       break
-"   endif
-endif
-if MESSAGES('E587', ":break without :while")
-    Xpath 64                                   " X: 64
-endif
-
-if ExtraVim(msgfile)
-"   try
-"   finally
-"       break
-"   endtry
-endif
-if MESSAGES('E587', ":break without :while")
-    Xpath 128                                  " X: 128
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       break
-"   endtry
-endif
-if MESSAGES('E587', ":break without :while")
-    Xpath 256                                  " X: 256
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       throw "a"
-"   catch /a/
-"       break
-"   endtry
-endif
-if MESSAGES('E587', ":break without :while")
-    Xpath 512                                  " X: 512
-endif
-
-call delete(msgfile)
-unlet msgfile
-
-Xcheck 1023
-
-" Leave MESSAGES() for the next test.
-
-
-"-------------------------------------------------------------------------------
-" Test 56:  Nesting errors: :endtry                                        {{{1
-"
-"          For nesting errors of :try conditionals the correct error messages
-"          should be given.
-"
-"          This test reuses the function MESSAGES() from the previous test.
-"          This functions checks the messages in g:msgfile.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-let msgfile = tempname()
-
-if ExtraVim(msgfile)
-"   endtry
-endif
-if MESSAGES('E602', ":endtry without :try")
-    Xpath 1                                    " X: 1
-endif
-
-if ExtraVim(msgfile)
-"   if 1
-"       endtry
-"   endif
-endif
-if MESSAGES('E602', ":endtry without :try")
-    Xpath 2                                    " X: 2
-endif
-
-if ExtraVim(msgfile)
-"   while 1
-"       endtry
-"   endwhile
-endif
-if MESSAGES('E602', ":endtry without :try")
-    Xpath 4                                    " X: 4
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       if 1
-"   endtry
-endif
-if MESSAGES('E171', "Missing :endif")
-    Xpath 8                                    " X: 8
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       while 1
-"   endtry
-endif
-if MESSAGES('E170', "Missing :endwhile")
-    Xpath 16                                   " X: 16
-endif
-
-if ExtraVim(msgfile)
-"   try
-"   finally
-"       if 1
-"   endtry
-endif
-if MESSAGES('E171', "Missing :endif")
-    Xpath 32                                   " X: 32
-endif
-
-if ExtraVim(msgfile)
-"   try
-"   finally
-"       while 1
-"   endtry
-endif
-if MESSAGES('E170', "Missing :endwhile")
-    Xpath 64                                   " X: 64
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       throw "a"
-"   catch /a/
-"       if 1
-"   endtry
-endif
-if MESSAGES('E171', "Missing :endif")
-    Xpath 128                                  " X: 128
-endif
-
-if ExtraVim(msgfile)
-"   try
-"       throw "a"
-"   catch /a/
-"       while 1
-"   endtry
-endif
-if MESSAGES('E170', "Missing :endwhile")
-    Xpath 256                                  " X: 256
-endif
-
-call delete(msgfile)
-unlet msgfile
-
-delfunction MESSAGES
-
-Xcheck 511
-
-
-"-------------------------------------------------------------------------------
-" Test 57:  v:exception and v:throwpoint for user exceptions               {{{1
-"
-"          v:exception evaluates to the value of the exception that was caught
-"          most recently and is not finished.  (A caught exception is finished
-"          when the next ":catch", ":finally", or ":endtry" is reached.)
-"          v:throwpoint evaluates to the script/function name and line number
-"          where that exception has been thrown.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-function! FuncException()
-    let g:exception = v:exception
-endfunction
-
-function! FuncThrowpoint()
-    let g:throwpoint = v:throwpoint
-endfunction
-
-let scriptException  = MakeScript("FuncException")
-let scriptThrowPoint = MakeScript("FuncThrowpoint")
-
-command! CmdException  let g:exception  = v:exception
-command! CmdThrowpoint let g:throwpoint = v:throwpoint
-
-XloopINIT! 1 2
-
-function! CHECK(n, exception, throwname, throwline)
-    XloopNEXT
-    let error = 0
-    if v:exception != a:exception
-       Xout a:n.": v:exception is" v:exception "instead of" a:exception
-       let error = 1
-    endif
-    if v:throwpoint !~ a:throwname
-       let name = escape(a:throwname, '\')
-       Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" name
-       let error = 1
-    endif
-    if v:throwpoint !~ a:throwline
-       let line = escape(a:throwline, '\')
-       Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
-       let error = 1
-    endif
-    if error
-       Xloop 1                                 " X: 0
-    endif
-endfunction
-
-function! T(arg, line)
-    if a:line == 2
-       throw a:arg             " in line 2
-    elseif a:line == 4
-       throw a:arg             " in line 4
-    elseif a:line == 6
-       throw a:arg             " in line 6
-    elseif a:line == 8
-       throw a:arg             " in line 8
-    endif
-endfunction
-
-function! G(arg, line)
-    call T(a:arg, a:line)
-endfunction
-
-function! F(arg, line)
-    call G(a:arg, a:line)
-endfunction
-
-let scriptT = MakeScript("T")
-let scriptG = MakeScript("G", scriptT)
-let scriptF = MakeScript("F", scriptG)
-
-try
-    Xpath 32768                                        " X: 32768
-    call F("oops", 2)
-catch /.*/
-    Xpath 65536                                        " X: 65536
-    let exception  = v:exception
-    let throwpoint = v:throwpoint
-    call CHECK(1, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
-    exec "let exception  = v:exception"
-    exec "let throwpoint = v:throwpoint"
-    call CHECK(2, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
-    CmdException
-    CmdThrowpoint
-    call CHECK(3, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
-    call FuncException()
-    call FuncThrowpoint()
-    call CHECK(4, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
-    exec "source" scriptException
-    exec "source" scriptThrowPoint
-    call CHECK(5, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
-    try
-       Xpath 131072                            " X: 131072
-       call G("arrgh", 4)
-    catch /.*/
-       Xpath 262144                            " X: 262144
-       let exception  = v:exception
-       let throwpoint = v:throwpoint
-       call CHECK(6, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
-       try
-           Xpath 524288                        " X: 524288
-           let g:arg = "autsch"
-           let g:line = 6
-           exec "source" scriptF
-       catch /.*/
-           Xpath 1048576                       " X: 1048576
-           let exception  = v:exception
-           let throwpoint = v:throwpoint
-           " Symbolic links in tempname()s are not resolved, whereas resolving
-           " is done for v:throwpoint.  Resolve the temporary file name for
-           " scriptT, so that it can be matched against v:throwpoint.
-           call CHECK(7, "autsch", resolve(scriptT), '\<6\>')
-       finally
-           Xpath 2097152                       " X: 2097152
-           let exception  = v:exception
-           let throwpoint = v:throwpoint
-           call CHECK(8, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
-           try
-               Xpath 4194304                   " X: 4194304
-               let g:arg = "brrrr"
-               let g:line = 8
-               exec "source" scriptG
-           catch /.*/
-               Xpath 8388608                   " X: 8388608
-               let exception  = v:exception
-               let throwpoint = v:throwpoint
-               " Resolve scriptT for matching it against v:throwpoint.
-               call CHECK(9, "brrrr", resolve(scriptT), '\<8\>')
-           finally
-               Xpath 16777216                  " X: 16777216
-               let exception  = v:exception
-               let throwpoint = v:throwpoint
-               call CHECK(10, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
-           endtry
-           Xpath 33554432                      " X: 33554432
-           let exception  = v:exception
-           let throwpoint = v:throwpoint
-           call CHECK(11, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
-       endtry
-       Xpath 67108864                          " X: 67108864
-       let exception  = v:exception
-       let throwpoint = v:throwpoint
-       call CHECK(12, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
-    finally
-       Xpath 134217728                         " X: 134217728
-       let exception  = v:exception
-       let throwpoint = v:throwpoint
-       call CHECK(13, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
-    endtry
-    Xpath 268435456                            " X: 268435456
-    let exception  = v:exception
-    let throwpoint = v:throwpoint
-    call CHECK(14, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
-finally
-    Xpath 536870912                            " X: 536870912
-    let exception  = v:exception
-    let throwpoint = v:throwpoint
-    call CHECK(15, "", '^$', '^$')
-endtry
-
-Xpath 1073741824                               " X: 1073741824
-
-unlet exception throwpoint
-delfunction FuncException
-delfunction FuncThrowpoint
-call delete(scriptException)
-call delete(scriptThrowPoint)
-unlet scriptException scriptThrowPoint
-delcommand CmdException
-delcommand CmdThrowpoint
-delfunction T
-delfunction G
-delfunction F
-call delete(scriptT)
-call delete(scriptG)
-call delete(scriptF)
-unlet scriptT scriptG scriptF
-
-Xcheck 2147450880
-
-
-"-------------------------------------------------------------------------------
-"
-" Test 58:  v:exception and v:throwpoint for error/interrupt exceptions            {{{1
-"
-"          v:exception and v:throwpoint work also for error and interrupt
-"          exceptions.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-if ExtraVim()
-
-    function! T(line)
-       if a:line == 2
-           delfunction T               " error (function in use) in line 2
-       elseif a:line == 4
-           let dummy = 0               " INTERRUPT1 - interrupt in line 4
-       endif
-    endfunction
-
-    while 1
-       try
-           Xpath 1                             " X: 1
-           let caught = 0
-           call T(2)
-       catch /.*/
-           let caught = 1
-           if v:exception !~ 'Vim(delfunction):'
-               Xpath 2                         " X: 0
-           endif
-           if v:throwpoint !~ '\<T\>'
-               Xpath 4                         " X: 0
-           endif
-           if v:throwpoint !~ '\<2\>'
-               Xpath 8                         " X: 0
-           endif
-       finally
-           Xpath 16                            " X: 16
-           if caught || $VIMNOERRTHROW
-               Xpath 32                        " X: 32
-           endif
-           if v:exception != ""
-               Xpath 64                        " X: 0
-           endif
-           if v:throwpoint != ""
-               Xpath 128                       " X: 0
-           endif
-           break               " discard error for $VIMNOERRTHROW
-       endtry
-    endwhile
+function! FuncThrowpoint()
+    let g:throwpoint = v:throwpoint
+endfunction
 
-    Xpath 256                                  " X: 256
-    if v:exception != ""
-       Xpath 512                               " X: 0
-    endif
-    if v:throwpoint != ""
-       Xpath 1024                              " X: 0
-    endif
+let scriptException  = MakeScript("FuncException")
+let scriptThrowPoint = MakeScript("FuncThrowpoint")
 
-    while 1
-       try
-           Xpath 2048                          " X: 2048
-           let caught = 0
-           call T(4)
-       catch /.*/
-           let caught = 1
-           if v:exception != 'Vim:Interrupt'
-               Xpath 4096                      " X: 0
-           endif
-           if v:throwpoint !~ '\<T\>'
-               Xpath 8192                      " X: 0
-           endif
-           if v:throwpoint !~ '\<4\>'
-               Xpath 16384                     " X: 0
-           endif
-       finally
-           Xpath 32768                         " X: 32768
-           if caught || $VIMNOINTTHROW
-               Xpath 65536                     " X: 65536
-           endif
-           if v:exception != ""
-               Xpath 131072                    " X: 0
-           endif
-           if v:throwpoint != ""
-               Xpath 262144                    " X: 0
-           endif
-           break               " discard error for $VIMNOERRTHROW
-       endtry
-    endwhile
+command! CmdException  let g:exception  = v:exception
+command! CmdThrowpoint let g:throwpoint = v:throwpoint
 
-    Xpath 524288                               " X: 524288
-    if v:exception != ""
-       Xpath 1048576                           " X: 0
+XloopINIT! 1 2
+
+function! CHECK(n, exception, throwname, throwline)
+    XloopNEXT
+    let error = 0
+    if v:exception != a:exception
+       Xout a:n.": v:exception is" v:exception "instead of" a:exception
+       let error = 1
     endif
-    if v:throwpoint != ""
-       Xpath 2097152                           " X: 0
+    if v:throwpoint !~ a:throwname
+       let name = escape(a:throwname, '\')
+       Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" name
+       let error = 1
     endif
+    if v:throwpoint !~ a:throwline
+       let line = escape(a:throwline, '\')
+       Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
+       let error = 1
+    endif
+    if error
+       Xloop 1                                 " X: 0
+    endif
+endfunction
 
-endif
-
-Xcheck 624945
-
-
-"-------------------------------------------------------------------------------
-"
-" Test 59:  v:exception and v:throwpoint when discarding exceptions        {{{1
-"
-"          When a :catch clause is left by a ":break" etc or an error or
-"          interrupt exception, v:exception and v:throwpoint are reset.  They
-"          are not affected by an exception that is discarded before being
-"          caught.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-if ExtraVim()
-
-    XloopINIT! 1 2
-
-    let sfile = expand("<sfile>")
-
-    function! LineNumber()
-       return substitute(substitute(v:throwpoint, g:sfile, '', ""),
-           \ '\D*\(\d*\).*', '\1', "")
-    endfunction
-
-    command! -nargs=1 SetLineNumber
-       \ try | throw "line" | catch /.*/ | let <args> =  LineNumber() | endtry
-
-    " Check v:exception/v:throwpoint against second/fourth parameter if
-    " specified, check for being empty else.
-    function! CHECK(n, ...)
-       XloopNEXT
-       let exception = a:0 != 0 ? a:1 : ""     " second parameter (optional)
-       let emsg      = a:0 != 0 ? a:2 : ""     " third parameter (optional)
-       let line      = a:0 != 0 ? a:3 : 0      " fourth parameter (optional)
-       let error = 0
-       if emsg != ""
-           " exception is the error number, emsg the English error message text
-           if exception !~ '^E\d\+$'
-               Xout "TODO: Add message number for:" emsg
-           elseif v:lang == "C" || v:lang =~ '^[Ee]n'
-               if exception == "E492" && emsg == "Not an editor command"
-                   let exception = '^Vim:' . exception . ': ' . emsg
-               else
-                   let exception = '^Vim(\a\+):' . exception . ': ' . emsg
-               endif
-           else
-               if exception == "E492"
-                   let exception = '^Vim:' . exception
-               else
-                   let exception = '^Vim(\a\+):' . exception
-               endif
-           endif
-       endif
-       if exception == "" && v:exception != ""
-           Xout a:n.": v:exception is set:" v:exception
-           let error = 1
-       elseif exception != "" && v:exception !~ exception
-           Xout a:n.": v:exception (".v:exception.") does not match" exception
-           let error = 1
-       endif
-       if line == 0 && v:throwpoint != ""
-           Xout a:n.": v:throwpoint is set:" v:throwpoint
-           let error = 1
-       elseif line != 0 && v:throwpoint !~ '\<' . line . '\>'
-           Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
-           let error = 1
-       endif
-       if !error
-           Xloop 1                             " X: 2097151
-       endif
-    endfunction
-
-    while 1
-       try
-           throw "x1"
-       catch /.*/
-           break
-       endtry
-    endwhile
-    call CHECK(1)
-
-    while 1
-       try
-           throw "x2"
-       catch /.*/
-           break
-       finally
-           call CHECK(2)
-       endtry
-       break
-    endwhile
-    call CHECK(3)
-
-    while 1
-       try
-           let errcaught = 0
-           try
-               try
-                   throw "x3"
-               catch /.*/
-                   SetLineNumber line_before_error
-                   asdf
-               endtry
-           catch /.*/
-               let errcaught = 1
-               call CHECK(4, 'E492', "Not an editor command",
-                   \ line_before_error + 1)
-           endtry
-       finally
-           if !errcaught && $VIMNOERRTHROW
-               call CHECK(4)
-           endif
-           break               " discard error for $VIMNOERRTHROW
-       endtry
-    endwhile
-    call CHECK(5)
-
-    Xpath 2097152                              " X: 2097152
-
-    while 1
-       try
-           let intcaught = 0
-           try
-               try
-                   throw "x4"
-               catch /.*/
-                   SetLineNumber two_lines_before_interrupt
-                   "INTERRUPT
-                   let dummy = 0
-               endtry
-           catch /.*/
-               let intcaught = 1
-               call CHECK(6, "Vim:Interrupt", '',
-                   \ two_lines_before_interrupt + 2)
-           endtry
-       finally
-           if !intcaught && $VIMNOINTTHROW
-               call CHECK(6)
-           endif
-           break               " discard interrupt for $VIMNOINTTHROW
-       endtry
-    endwhile
-    call CHECK(7)
-
-    Xpath 4194304                              " X: 4194304
-
-    while 1
-       try
-           let errcaught = 0
-           try
-               try
-"                  if 1
-                       SetLineNumber line_before_throw
-                       throw "x5"
-                   " missing endif
-               catch /.*/
-                   Xpath 8388608                       " X: 0
-               endtry
-           catch /.*/
-               let errcaught = 1
-               call CHECK(8, 'E171', "Missing :endif", line_before_throw + 3)
-           endtry
-       finally
-           if !errcaught && $VIMNOERRTHROW
-               call CHECK(8)
-           endif
-           break               " discard error for $VIMNOERRTHROW
-       endtry
-    endwhile
-    call CHECK(9)
-
-    Xpath 16777216                             " X: 16777216
+function! T(arg, line)
+    if a:line == 2
+       throw a:arg             " in line 2
+    elseif a:line == 4
+       throw a:arg             " in line 4
+    elseif a:line == 6
+       throw a:arg             " in line 6
+    elseif a:line == 8
+       throw a:arg             " in line 8
+    endif
+endfunction
 
-    try
-       while 1
-           try
-               throw "x6"
-           finally
-               break
-           endtry
-           break
-       endwhile
-    catch /.*/
-       Xpath 33554432                          " X: 0
-    endtry
-    call CHECK(10)
+function! G(arg, line)
+    call T(a:arg, a:line)
+endfunction
+
+function! F(arg, line)
+    call G(a:arg, a:line)
+endfunction
+
+let scriptT = MakeScript("T")
+let scriptG = MakeScript("G", scriptT)
+let scriptF = MakeScript("F", scriptG)
 
+try
+    Xpath 32768                                        " X: 32768
+    call F("oops", 2)
+catch /.*/
+    Xpath 65536                                        " X: 65536
+    let exception  = v:exception
+    let throwpoint = v:throwpoint
+    call CHECK(1, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
+    exec "let exception  = v:exception"
+    exec "let throwpoint = v:throwpoint"
+    call CHECK(2, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
+    CmdException
+    CmdThrowpoint
+    call CHECK(3, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
+    call FuncException()
+    call FuncThrowpoint()
+    call CHECK(4, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
+    exec "source" scriptException
+    exec "source" scriptThrowPoint
+    call CHECK(5, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
     try
-       while 1
-           try
-               throw "x7"
-           finally
-               break
-           endtry
-           break
-       endwhile
+       Xpath 131072                            " X: 131072
+       call G("arrgh", 4)
     catch /.*/
-       Xpath 67108864                          " X: 0
-    finally
-       call CHECK(11)
-    endtry
-    call CHECK(12)
-
-    while 1
+       Xpath 262144                            " X: 262144
+       let exception  = v:exception
+       let throwpoint = v:throwpoint
+       call CHECK(6, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
        try
-           let errcaught = 0
+           Xpath 524288                        " X: 524288
+           let g:arg = "autsch"
+           let g:line = 6
+           exec "source" scriptF
+       catch /.*/
+           Xpath 1048576                       " X: 1048576
+           let exception  = v:exception
+           let throwpoint = v:throwpoint
+           " Symbolic links in tempname()s are not resolved, whereas resolving
+           " is done for v:throwpoint.  Resolve the temporary file name for
+           " scriptT, so that it can be matched against v:throwpoint.
+           call CHECK(7, "autsch", resolve(scriptT), '\<6\>')
+       finally
+           Xpath 2097152                       " X: 2097152
+           let exception  = v:exception
+           let throwpoint = v:throwpoint
+           call CHECK(8, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
            try
-               try
-                   throw "x8"
-               finally
-                   SetLineNumber line_before_error
-                   asdf
-               endtry
+               Xpath 4194304                   " X: 4194304
+               let g:arg = "brrrr"
+               let g:line = 8
+               exec "source" scriptG
            catch /.*/
-               let errcaught = 1
-               call CHECK(13, 'E492', "Not an editor command",
-                   \ line_before_error + 1)
+               Xpath 8388608                   " X: 8388608
+               let exception  = v:exception
+               let throwpoint = v:throwpoint
+               " Resolve scriptT for matching it against v:throwpoint.
+               call CHECK(9, "brrrr", resolve(scriptT), '\<8\>')
+           finally
+               Xpath 16777216                  " X: 16777216
+               let exception  = v:exception
+               let throwpoint = v:throwpoint
+               call CHECK(10, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
            endtry
-       finally
-           if !errcaught && $VIMNOERRTHROW
-               call CHECK(13)
-           endif
-           break               " discard error for $VIMNOERRTHROW
+           Xpath 33554432                      " X: 33554432
+           let exception  = v:exception
+           let throwpoint = v:throwpoint
+           call CHECK(11, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
        endtry
-    endwhile
-    call CHECK(14)
+       Xpath 67108864                          " X: 67108864
+       let exception  = v:exception
+       let throwpoint = v:throwpoint
+       call CHECK(12, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
+    finally
+       Xpath 134217728                         " X: 134217728
+       let exception  = v:exception
+       let throwpoint = v:throwpoint
+       call CHECK(13, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
+    endtry
+    Xpath 268435456                            " X: 268435456
+    let exception  = v:exception
+    let throwpoint = v:throwpoint
+    call CHECK(14, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
+finally
+    Xpath 536870912                            " X: 536870912
+    let exception  = v:exception
+    let throwpoint = v:throwpoint
+    call CHECK(15, "", '^$', '^$')
+endtry
 
-    Xpath 134217728                            " X: 134217728
+Xpath 1073741824                               " X: 1073741824
 
-    while 1
-       try
-           let intcaught = 0
-           try
-               try
-                   throw "x9"
-               finally
-                   SetLineNumber two_lines_before_interrupt
-                   "INTERRUPT
-               endtry
-           catch /.*/
-               let intcaught = 1
-               call CHECK(15, "Vim:Interrupt", '',
-                   \ two_lines_before_interrupt + 2)
-           endtry
-       finally
-           if !intcaught && $VIMNOINTTHROW
-               call CHECK(15)
-           endif
-           break               " discard interrupt for $VIMNOINTTHROW
-       endtry
-    endwhile
-    call CHECK(16)
+unlet exception throwpoint
+delfunction FuncException
+delfunction FuncThrowpoint
+call delete(scriptException)
+call delete(scriptThrowPoint)
+unlet scriptException scriptThrowPoint
+delcommand CmdException
+delcommand CmdThrowpoint
+delfunction T
+delfunction G
+delfunction F
+call delete(scriptT)
+call delete(scriptG)
+call delete(scriptF)
+unlet scriptT scriptG scriptF
 
-    Xpath 268435456                            " X: 268435456
+Xcheck 2147450880
+
+
+"-------------------------------------------------------------------------------
+"
+" Test 58:  v:exception and v:throwpoint for error/interrupt exceptions            {{{1
+"
+"          v:exception and v:throwpoint work also for error and interrupt
+"          exceptions.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
+
+    function! T(line)
+       if a:line == 2
+           delfunction T               " error (function in use) in line 2
+       elseif a:line == 4
+           let dummy = 0               " INTERRUPT1 - interrupt in line 4
+       endif
+    endfunction
 
     while 1
        try
-           let errcaught = 0
-           try
-               try
-"                  if 1
-                       SetLineNumber line_before_throw
-                       throw "x10"
-                   " missing endif
-               finally
-                   call CHECK(17)
-               endtry
-           catch /.*/
-               let errcaught = 1
-               call CHECK(18, 'E171', "Missing :endif", line_before_throw + 3)
-           endtry
+           Xpath 1                             " X: 1
+           let caught = 0
+           call T(2)
+       catch /.*/
+           let caught = 1
+           if v:exception !~ 'Vim(delfunction):'
+               Xpath 2                         " X: 0
+           endif
+           if v:throwpoint !~ '\<T\>'
+               Xpath 4                         " X: 0
+           endif
+           if v:throwpoint !~ '\<2\>'
+               Xpath 8                         " X: 0
+           endif
        finally
-           if !errcaught && $VIMNOERRTHROW
-               call CHECK(18)
+           Xpath 16                            " X: 16
+           if caught || $VIMNOERRTHROW
+               Xpath 32                        " X: 32
+           endif
+           if v:exception != ""
+               Xpath 64                        " X: 0
+           endif
+           if v:throwpoint != ""
+               Xpath 128                       " X: 0
            endif
            break               " discard error for $VIMNOERRTHROW
        endtry
     endwhile
-    call CHECK(19)
 
-    Xpath 536870912                            " X: 536870912
+    Xpath 256                                  " X: 256
+    if v:exception != ""
+       Xpath 512                               " X: 0
+    endif
+    if v:throwpoint != ""
+       Xpath 1024                              " X: 0
+    endif
 
     while 1
        try
-           let errcaught = 0
-           try
-               try
-"                  if 1
-                       SetLineNumber line_before_throw
-                       throw "x11"
-                   " missing endif
-               endtry
-           catch /.*/
-               let errcaught = 1
-               call CHECK(20, 'E171', "Missing :endif", line_before_throw + 3)
-           endtry
+           Xpath 2048                          " X: 2048
+           let caught = 0
+           call T(4)
+       catch /.*/
+           let caught = 1
+           if v:exception != 'Vim:Interrupt'
+               Xpath 4096                      " X: 0
+           endif
+           if v:throwpoint !~ '\<T\>'
+               Xpath 8192                      " X: 0
+           endif
+           if v:throwpoint !~ '\<4\>'
+               Xpath 16384                     " X: 0
+           endif
        finally
-           if !errcaught && $VIMNOERRTHROW
-               call CHECK(20)
+           Xpath 32768                         " X: 32768
+           if caught || $VIMNOINTTHROW
+               Xpath 65536                     " X: 65536
+           endif
+           if v:exception != ""
+               Xpath 131072                    " X: 0
+           endif
+           if v:throwpoint != ""
+               Xpath 262144                    " X: 0
            endif
            break               " discard error for $VIMNOERRTHROW
        endtry
     endwhile
-    call CHECK(21)
 
-    Xpath 1073741824                           " X: 1073741824
+    Xpath 524288                               " X: 524288
+    if v:exception != ""
+       Xpath 1048576                           " X: 0
+    endif
+    if v:throwpoint != ""
+       Xpath 2097152                           " X: 0
+    endif
 
 endif
 
-Xcheck 2038431743
+Xcheck 624945
 
 
 "-------------------------------------------------------------------------------
 "
-" Test 60:  (Re)throwing v:exception; :echoerr.                                    {{{1
+" Test 59:  v:exception and v:throwpoint when discarding exceptions        {{{1
 "
-"          A user exception can be rethrown after catching by throwing
-"          v:exception.  An error or interrupt exception cannot be rethrown
-"          because Vim exceptions cannot be faked.  A Vim exception using the
-"          value of v:exception can, however, be triggered by the :echoerr
-"          command.
+"          When a :catch clause is left by a ":break" etc or an error or
+"          interrupt exception, v:exception and v:throwpoint are reset.  They
+"          are not affected by an exception that is discarded before being
+"          caught.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-try
-    try
-       Xpath 1                                 " X: 1
-       throw "oops"
-    catch /oops/
-       Xpath 2                                 " X: 2
-       throw v:exception       " rethrow user exception
-    catch /.*/
-       Xpath 4                                 " X: 0
-    endtry
-catch /^oops$/                 " catches rethrown user exception
-    Xpath 8                                    " X: 8
-catch /.*/
-    Xpath 16                                   " X: 0
-endtry
-
-function! F()
-    try
-       let caught = 0
-       try
-           Xpath 32                            " X: 32
-           write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e
-           Xpath 64                            " X: 0
-           Xout "did_emsg was reset before executing " .
-               \ "BufWritePost autocommands."
-       catch /^Vim(write):/
-           let caught = 1
-           throw v:exception   " throw error: cannot fake Vim exception
-       catch /.*/
-           Xpath 128                           " X: 0
-       finally
-           Xpath 256                           " X: 256
-           if !caught && !$VIMNOERRTHROW
-               Xpath 512                       " X: 0
-           endif
-       endtry
-    catch /^Vim(throw):/       " catches throw error
-       let caught = caught + 1
-    catch /.*/
-       Xpath 1024                              " X: 0
-    finally
-       Xpath 2048                              " X: 2048
-       if caught != 2
-           if !caught && !$VIMNOERRTHROW
-               Xpath 4096                      " X: 0
-           elseif caught
-               Xpath 8192                      " X: 0
-           endif
-           return              | " discard error for $VIMNOERRTHROW
-       endif
-    endtry
-endfunction
+if ExtraVim()
 
-call F()
-delfunction F
+    XloopINIT! 1 2
 
-function! G()
-    try
-       let caught = 0
-       try
-           Xpath 16384                         " X: 16384
-           asdf
-       catch /^Vim/            " catch error exception
-           let caught = 1
-           " Trigger Vim error exception with value specified after :echoerr
-           let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
-           echoerr value
-       catch /.*/
-           Xpath 32768                         " X: 0
-       finally
-           Xpath 65536                         " X: 65536
-           if !caught
-               if !$VIMNOERRTHROW
-                   Xpath 131072                " X: 0
-               else
-                   let value = "Error"
-                   echoerr value
-               endif
-           endif
-       endtry
-    catch /^Vim(echoerr):/
-       let caught = caught + 1
-       if v:exception !~ value
-           Xpath 262144                        " X: 0
-       endif
-    catch /.*/
-       Xpath 524288                            " X: 0
-    finally
-       Xpath 1048576                           " X: 1048576
-       if caught != 2
-           if !caught && !$VIMNOERRTHROW
-               Xpath 2097152                   " X: 0
-           elseif caught
-               Xpath 4194304                   " X: 0
-           endif
-           return              | " discard error for $VIMNOERRTHROW
-       endif
-    endtry
-endfunction
+    let sfile = expand("<sfile>")
 
-call G()
-delfunction G
+    function! LineNumber()
+       return substitute(substitute(v:throwpoint, g:sfile, '', ""),
+           \ '\D*\(\d*\).*', '\1', "")
+    endfunction
 
-unlet! value caught
+    command! -nargs=1 SetLineNumber
+       \ try | throw "line" | catch /.*/ | let <args> =  LineNumber() | endtry
 
-if ExtraVim()
-    try
-       let errcaught = 0
-       try
-           Xpath 8388608                       " X: 8388608
-           let intcaught = 0
-           "INTERRUPT
-       catch /^Vim:/           " catch interrupt exception
-           let intcaught = 1
-           " Trigger Vim error exception with value specified after :echoerr
-           echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
-       catch /.*/
-           Xpath 16777216                      " X: 0
-       finally
-           Xpath 33554432                      " X: 33554432
-           if !intcaught
-               if !$VIMNOINTTHROW
-                   Xpath 67108864              " X: 0
+    " Check v:exception/v:throwpoint against second/fourth parameter if
+    " specified, check for being empty else.
+    function! CHECK(n, ...)
+       XloopNEXT
+       let exception = a:0 != 0 ? a:1 : ""     " second parameter (optional)
+       let emsg      = a:0 != 0 ? a:2 : ""     " third parameter (optional)
+       let line      = a:0 != 0 ? a:3 : 0      " fourth parameter (optional)
+       let error = 0
+       if emsg != ""
+           " exception is the error number, emsg the English error message text
+           if exception !~ '^E\d\+$'
+               Xout "TODO: Add message number for:" emsg
+           elseif v:lang == "C" || v:lang =~ '^[Ee]n'
+               if exception == "E492" && emsg == "Not an editor command"
+                   let exception = '^Vim:' . exception . ': ' . emsg
                else
-                   echoerr "Interrupt"
+                   let exception = '^Vim(\a\+):' . exception . ': ' . emsg
+               endif
+           else
+               if exception == "E492"
+                   let exception = '^Vim:' . exception
+               else
+                   let exception = '^Vim(\a\+):' . exception
                endif
            endif
-       endtry
-    catch /^Vim(echoerr):/
-       let errcaught = 1
-       if v:exception !~ "Interrupt"
-           Xpath 134217728                     " X: 0
        endif
-    finally
-       Xpath 268435456                         " X: 268435456
-       if !errcaught && !$VIMNOERRTHROW
-           Xpath 536870912                     " X: 0
+       if exception == "" && v:exception != ""
+           Xout a:n.": v:exception is set:" v:exception
+           let error = 1
+       elseif exception != "" && v:exception !~ exception
+           Xout a:n.": v:exception (".v:exception.") does not match" exception
+           let error = 1
        endif
-    endtry
-endif
-
-Xcheck 311511339
-
-
-"-------------------------------------------------------------------------------
-" Test 61:  Catching interrupt exceptions                                  {{{1
-"
-"          When an interrupt occurs inside a :try/:endtry region, an
-"          interrupt exception is thrown and can be caught.  Its value is
-"          "Vim:Interrupt".  If the interrupt occurs after an error or a :throw
-"          but before a matching :catch is reached, all following :catches of
-"          that try block are ignored, but the interrupt exception can be
-"          caught by the next surrounding try conditional.  An interrupt is
-"          ignored when there is a previous interrupt that has not been caught
-"          or causes a :finally clause to be executed.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-if ExtraVim()
+       if line == 0 && v:throwpoint != ""
+           Xout a:n.": v:throwpoint is set:" v:throwpoint
+           let error = 1
+       elseif line != 0 && v:throwpoint !~ '\<' . line . '\>'
+           Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
+           let error = 1
+       endif
+       if !error
+           Xloop 1                             " X: 2097151
+       endif
+    endfunction
 
     while 1
        try
-           try
-               Xpath 1                         " X: 1
-               let caught = 0
-               "INTERRUPT
-               Xpath 2                         " X: 0
-           catch /^Vim:Interrupt$/
-               let caught = 1
-           finally
-               Xpath 4                         " X: 4
-               if caught || $VIMNOINTTHROW
-                   Xpath 8                     " X: 8
-               endif
-           endtry
+           throw "x1"
        catch /.*/
-           Xpath 16                            " X: 0
-           Xout v:exception "in" v:throwpoint
-       finally
-           break               " discard interrupt for $VIMNOINTTHROW
+           break
        endtry
     endwhile
+    call CHECK(1)
 
     while 1
        try
-           try
-               let caught = 0
-               try
-                   Xpath 32                    " X: 32
-                   asdf
-                   Xpath 64                    " X: 0
-               catch /do_not_catch/
-                   Xpath 128                   " X: 0
-               catch /.*/      "INTERRUPT - throw interrupt if !$VIMNOERRTHROW
-                   Xpath 256                   " X: 0
-               catch /.*/
-                   Xpath 512                   " X: 0
-               finally         "INTERRUPT - throw interrupt if $VIMNOERRTHROW
-                   Xpath 1024                  " X: 1024
-               endtry
-           catch /^Vim:Interrupt$/
-               let caught = 1
-           finally
-               Xpath 2048                      " X: 2048
-               if caught || $VIMNOINTTHROW
-                   Xpath 4096                  " X: 4096
-               endif
-           endtry
+           throw "x2"
        catch /.*/
-           Xpath 8192                          " X: 0
-           Xout v:exception "in" v:throwpoint
+           break
        finally
-           break               " discard interrupt for $VIMNOINTTHROW
+           call CHECK(2)
        endtry
+       break
     endwhile
+    call CHECK(3)
 
     while 1
        try
+           let errcaught = 0
            try
-               let caught = 0
                try
-                   Xpath 16384                 " X: 16384
-                   throw "x"
-                   Xpath 32768                 " X: 0
-               catch /do_not_catch/
-                   Xpath 65536                 " X: 0
-               catch /x/       "INTERRUPT
-                   Xpath 131072                " X: 0
+                   throw "x3"
                catch /.*/
-                   Xpath 262144                " X: 0
+                   SetLineNumber line_before_error
+                   asdf
                endtry
-           catch /^Vim:Interrupt$/
-               let caught = 1
-           finally
-               Xpath 524288                    " X: 524288
-               if caught || $VIMNOINTTHROW
-                   Xpath 1048576               " X: 1048576
-               endif
+           catch /.*/
+               let errcaught = 1
+               call CHECK(4, 'E492', "Not an editor command",
+                   \ line_before_error + 1)
            endtry
-       catch /.*/
-           Xpath 2097152                       " X: 0
-           Xout v:exception "in" v:throwpoint
        finally
-           break               " discard interrupt for $VIMNOINTTHROW
+           if !errcaught && $VIMNOERRTHROW
+               call CHECK(4)
+           endif
+           break               " discard error for $VIMNOERRTHROW
        endtry
     endwhile
+    call CHECK(5)
+
+    Xpath 2097152                              " X: 2097152
 
     while 1
        try
-           let caught = 0
+           let intcaught = 0
            try
-               Xpath 4194304                   " X: 4194304
-               "INTERRUPT
-               Xpath 8388608                   " X: 0
-           catch /do_not_catch/ "INTERRUPT
-               Xpath 16777216                  " X: 0
-           catch /^Vim:Interrupt$/
-               let caught = 1
-           finally
-               Xpath 33554432                  " X: 33554432
-               if caught || $VIMNOINTTHROW
-                   Xpath 67108864              " X: 67108864
-               endif
+               try
+                   throw "x4"
+               catch /.*/
+                   SetLineNumber two_lines_before_interrupt
+                   "INTERRUPT
+                   let dummy = 0
+               endtry
+           catch /.*/
+               let intcaught = 1
+               call CHECK(6, "Vim:Interrupt", '',
+                   \ two_lines_before_interrupt + 2)
            endtry
-       catch /.*/
-           Xpath 134217728                     " X: 0
-           Xout v:exception "in" v:throwpoint
        finally
+           if !intcaught && $VIMNOINTTHROW
+               call CHECK(6)
+           endif
            break               " discard interrupt for $VIMNOINTTHROW
        endtry
     endwhile
+    call CHECK(7)
 
-    Xpath 268435456                            " X: 268435456
-
-endif
-
-Xcheck 374889517
-
-
-"-------------------------------------------------------------------------------
-" Test 62:  Catching error exceptions                                      {{{1
-"
-"          An error inside a :try/:endtry region is converted to an exception
-"          and can be caught.  The error exception has a "Vim(cmdname):" prefix
-"          where cmdname is the name of the failing command, or a "Vim:" prefix
-"          if no command name is known.  The "Vim" prefixes cannot be faked.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-function! MSG(enr, emsg)
-    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
-    if a:enr == ""
-       Xout "TODO: Add message number for:" a:emsg
-       let v:errmsg = ":" . v:errmsg
-    endif
-    let match = 1
-    if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
-       let match = 0
-       if v:errmsg == ""
-           Xout "Message missing."
-       else
-           let v:errmsg = escape(v:errmsg, '"')
-           Xout "Unexpected message:" v:errmsg
-       endif
-    endif
-    return match
-endfunction
+    Xpath 4194304                              " X: 4194304
 
-while 1
-    try
+    while 1
        try
-           let caught = 0
-           unlet novar
-       catch /^Vim(unlet):/
-           let caught = 1
-           let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "")
+           let errcaught = 0
+           try
+               try
+"                  if 1
+                       SetLineNumber line_before_throw
+                       throw "x5"
+                   " missing endif
+               catch /.*/
+                   Xpath 8388608                       " X: 0
+               endtry
+           catch /.*/
+               let errcaught = 1
+               call CHECK(8, 'E171', "Missing :endif", line_before_throw + 3)
+           endtry
        finally
-           Xpath 1                             " X: 1
-           if !caught && !$VIMNOERRTHROW
-               Xpath 2                         " X: 0
-           endif
-           if !MSG('E108', "No such variable")
-               Xpath 4                         " X: 0
+           if !errcaught && $VIMNOERRTHROW
+               call CHECK(8)
            endif
+           break               " discard error for $VIMNOERRTHROW
        endtry
-    catch /.*/
-       Xpath 8                                 " X: 0
-       Xout v:exception "in" v:throwpoint
-    finally
-       break           " discard error for $VIMNOERRTHROW
-    endtry
-endwhile
+    endwhile
+    call CHECK(9)
 
-while 1
-    try
-       try
-           let caught = 0
-           throw novar                 " error in :throw
-       catch /^Vim(throw):/
-           let caught = 1
-           let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
-       finally
-           Xpath 16                            " X: 16
-           if !caught && !$VIMNOERRTHROW
-               Xpath 32                        " X: 0
-           endif
-           if caught ? !MSG('E121', "Undefined variable")
-                       \ : !MSG('E15', "Invalid expression")
-               Xpath 64                        " X: 0
-           endif
-       endtry
-    catch /.*/
-       Xpath 128                               " X: 0
-       Xout v:exception "in" v:throwpoint
-    finally
-       break           " discard error for $VIMNOERRTHROW
-    endtry
-endwhile
+    Xpath 16777216                             " X: 16777216
 
-while 1
     try
-       try
-           let caught = 0
-           throw "Vim:faked"           " error: cannot fake Vim exception
-       catch /^Vim(throw):/
-           let caught = 1
-           let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
-       finally
-           Xpath 256                           " X: 256
-           if !caught && !$VIMNOERRTHROW
-               Xpath 512                       " X: 0
-           endif
-           if !MSG('E608', "Cannot :throw exceptions with 'Vim' prefix")
-               Xpath 1024                      " X: 0
-           endif
-       endtry
-    catch /.*/
-       Xpath 2048                              " X: 0
-       Xout v:exception "in" v:throwpoint
-    finally
-       break           " discard error for $VIMNOERRTHROW
+       while 1
+           try
+               throw "x6"
+           finally
+               break
+           endtry
+           break
+       endwhile
+    catch /.*/
+       Xpath 33554432                          " X: 0
     endtry
-endwhile
-
-function! F()
-    while 1
-    " Missing :endwhile
-endfunction
+    call CHECK(10)
 
-while 1
     try
-       try
-           let caught = 0
-           call F()
-       catch /^Vim(endfunction):/
-           let caught = 1
-           let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "")
-       finally
-           Xpath 4096                          " X: 4096
-           if !caught && !$VIMNOERRTHROW
-               Xpath 8192                      " X: 0
-           endif
-           if !MSG('E170', "Missing :endwhile")
-               Xpath 16384                     " X: 0
-           endif
-       endtry
+       while 1
+           try
+               throw "x7"
+           finally
+               break
+           endtry
+           break
+       endwhile
     catch /.*/
-       Xpath 32768                             " X: 0
-       Xout v:exception "in" v:throwpoint
+       Xpath 67108864                          " X: 0
     finally
-       break           " discard error for $VIMNOERRTHROW
+       call CHECK(11)
     endtry
-endwhile
+    call CHECK(12)
 
-while 1
-    try
+    while 1
        try
-           let caught = 0
-           ExecAsScript F
-       catch /^Vim:/
-           let caught = 1
-           let v:errmsg = substitute(v:exception, '^Vim:', '', "")
+           let errcaught = 0
+           try
+               try
+                   throw "x8"
+               finally
+                   SetLineNumber line_before_error
+                   asdf
+               endtry
+           catch /.*/
+               let errcaught = 1
+               call CHECK(13, 'E492', "Not an editor command",
+                   \ line_before_error + 1)
+           endtry
        finally
-           Xpath 65536                         " X: 65536
-           if !caught && !$VIMNOERRTHROW
-               Xpath 131072                    " X: 0
-           endif
-           if !MSG('E170', "Missing :endwhile")
-               Xpath 262144                    " X: 0
+           if !errcaught && $VIMNOERRTHROW
+               call CHECK(13)
            endif
+           break               " discard error for $VIMNOERRTHROW
        endtry
-    catch /.*/
-       Xpath 524288                            " X: 0
-       Xout v:exception "in" v:throwpoint
-    finally
-       break           " discard error for $VIMNOERRTHROW
-    endtry
-endwhile
+    endwhile
+    call CHECK(14)
 
-function! G()
-    call G()
-endfunction
+    Xpath 134217728                            " X: 134217728
 
-while 1
-    try
-       let mfd_save = &mfd
-       set mfd=3
+    while 1
        try
-           let caught = 0
-           call G()
-       catch /^Vim(call):/
-           let caught = 1
-           let v:errmsg = substitute(v:exception, '^Vim(call):', '', "")
+           let intcaught = 0
+           try
+               try
+                   throw "x9"
+               finally
+                   SetLineNumber two_lines_before_interrupt
+                   "INTERRUPT
+               endtry
+           catch /.*/
+               let intcaught = 1
+               call CHECK(15, "Vim:Interrupt", '',
+                   \ two_lines_before_interrupt + 2)
+           endtry
        finally
-           Xpath 1048576                       " X: 1048576
-           if !caught && !$VIMNOERRTHROW
-               Xpath 2097152                   " X: 0
-           endif
-           if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
-               Xpath 4194304                   " X: 0
+           if !intcaught && $VIMNOINTTHROW
+               call CHECK(15)
            endif
+           break               " discard interrupt for $VIMNOINTTHROW
        endtry
-    catch /.*/
-       Xpath 8388608                           " X: 0
-       Xout v:exception "in" v:throwpoint
-    finally
-       let &mfd = mfd_save
-       break           " discard error for $VIMNOERRTHROW
-    endtry
-endwhile
+    endwhile
+    call CHECK(16)
 
-function! H()
-    return H()
-endfunction
+    Xpath 268435456                            " X: 268435456
 
-while 1
-    try
-       let mfd_save = &mfd
-       set mfd=3
+    while 1
        try
-           let caught = 0
-           call H()
-       catch /^Vim(return):/
-           let caught = 1
-           let v:errmsg = substitute(v:exception, '^Vim(return):', '', "")
+           let errcaught = 0
+           try
+               try
+"                  if 1
+                       SetLineNumber line_before_throw
+                       throw "x10"
+                   " missing endif
+               finally
+                   call CHECK(17)
+               endtry
+           catch /.*/
+               let errcaught = 1
+               call CHECK(18, 'E171', "Missing :endif", line_before_throw + 3)
+           endtry
        finally
-           Xpath 16777216                      " X: 16777216
-           if !caught && !$VIMNOERRTHROW
-               Xpath 33554432                  " X: 0
-           endif
-           if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
-               Xpath 67108864                  " X: 0
+           if !errcaught && $VIMNOERRTHROW
+               call CHECK(18)
            endif
+           break               " discard error for $VIMNOERRTHROW
        endtry
-    catch /.*/
-       Xpath 134217728                         " X: 0
-       Xout v:exception "in" v:throwpoint
-    finally
-       let &mfd = mfd_save
-       break           " discard error for $VIMNOERRTHROW
-    endtry
-endwhile
-
-unlet! caught mfd_save
-delfunction F
-delfunction G
-delfunction H
-Xpath 268435456                                        " X: 268435456
-
-Xcheck 286331153
-
-" Leave MSG() for the next test.
-
-
-"-------------------------------------------------------------------------------
-" Test 63:  Suppressing error exceptions by :silent!.                      {{{1
-"
-"          A :silent! command inside a :try/:endtry region suppresses the
-"          conversion of errors to an exception and the immediate abortion on
-"          error.  When the commands executed by the :silent! themselves open
-"          a new :try/:endtry region, conversion of errors to exception and
-"          immediate abortion is switched on again - until the next :silent!
-"          etc.  The :silent! has the effect of setting v:errmsg to the error
-"          message text (without displaying it) and continuing with the next
-"          script line.
-"
-"          When a command triggering autocommands is executed by :silent!
-"          inside a :try/:endtry, the autocommand execution is not suppressed
-"          on error.
-"
-"          This test reuses the function MSG() from the previous test.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-XloopINIT! 1 4
-
-let taken = ""
-
-function! S(n) abort
-    XloopNEXT
-    let g:taken = g:taken . "E" . a:n
-    let v:errmsg = ""
-    exec "asdf" . a:n
-
-    " Check that ":silent!" continues:
-    Xloop 1
+    endwhile
+    call CHECK(19)
 
-    " Check that ":silent!" sets "v:errmsg":
-    if MSG('E492', "Not an editor command")
-       Xloop 2
-    endif
-endfunction
+    Xpath 536870912                            " X: 536870912
 
-function! Foo()
     while 1
        try
+           let errcaught = 0
            try
-               let caught = 0
-               " This is not silent:
-               call S(3)                               " X: 0 * 16
-           catch /^Vim:/
-               let caught = 1
-               let errmsg3 = substitute(v:exception, '^Vim:', '', "")
-               silent! call S(4)                       " X: 3 * 64
-           finally
-               if !caught
-                   let errmsg3 = v:errmsg
-                   " Do call S(4) here if not executed in :catch.
-                   silent! call S(4)
-               endif
-               Xpath 1048576                   " X: 1048576
-               if !caught && !$VIMNOERRTHROW
-                   Xpath 2097152               " X: 0
-               endif
-               let v:errmsg = errmsg3
-               if !MSG('E492', "Not an editor command")
-                   Xpath 4194304               " X: 0
-               endif
-               silent! call S(5)                       " X: 3 * 256
-               " Break out of try conditionals that cover ":silent!".  This also
-               " discards the aborting error when $VIMNOERRTHROW is non-zero.
-               break
+               try
+"                  if 1
+                       SetLineNumber line_before_throw
+                       throw "x11"
+                   " missing endif
+               endtry
+           catch /.*/
+               let errcaught = 1
+               call CHECK(20, 'E171', "Missing :endif", line_before_throw + 3)
            endtry
-       catch /.*/
-           Xpath 8388608                       " X: 0
-           Xout v:exception "in" v:throwpoint
+       finally
+           if !errcaught && $VIMNOERRTHROW
+               call CHECK(20)
+           endif
+           break               " discard error for $VIMNOERRTHROW
        endtry
     endwhile
-    " This is a double ":silent!" (see caller).
-    silent! call S(6)                                  " X: 3 * 1024
-endfunction
-
-function! Bar()
-    try
-       silent! call S(2)                               " X: 3 * 4
-                                                       " X: 3 * 4096
-       silent! execute "call Foo() | call S(7)"
-       silent! call S(8)                               " X: 3 * 16384
-    endtry     " normal end of try cond that covers ":silent!"
-    " This has a ":silent!" from the caller:
-    call S(9)                                          " X: 3 * 65536
-endfunction
+    call CHECK(21)
 
-silent! call S(1)                                      " X: 3 * 1
-silent! call Bar()
-silent! call S(10)                                     " X: 3 * 262144
+    Xpath 1073741824                           " X: 1073741824
 
-let expected = "E1E2E3E4E5E6E7E8E9E10"
-if taken != expected
-    Xpath 16777216                             " X: 0
-    Xout "'taken' is" taken "instead of" expected
 endif
 
-augroup TMP
-    autocmd BufWritePost * Xpath 33554432      " X: 33554432
-augroup END
-
-Xpath 67108864                                 " X: 67108864
-write /i/m/p/o/s/s/i/b/l/e
-Xpath 134217728                                        " X: 134217728
-
-autocmd! TMP
-unlet! caught errmsg3 taken expected
-delfunction S
-delfunction Foo
-delfunction Bar
-delfunction MSG
-
-Xcheck 236978127
+Xcheck 2038431743
 
 
 "-------------------------------------------------------------------------------
-" Test 64:  Error exceptions after error, interrupt or :throw              {{{1
 "
-"          When an error occurs after an interrupt or a :throw but before
-"          a matching :catch is reached, all following :catches of that try
-"          block are ignored, but the error exception can be caught by the next
-"          surrounding try conditional.  Any previous error exception is
-"          discarded.  An error is ignored when there is a previous error that
-"          has not been caught.
+" Test 60:  (Re)throwing v:exception; :echoerr.                                    {{{1
+"
+"          A user exception can be rethrown after catching by throwing
+"          v:exception.  An error or interrupt exception cannot be rethrown
+"          because Vim exceptions cannot be faked.  A Vim exception using the
+"          value of v:exception can, however, be triggered by the :echoerr
+"          command.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-if ExtraVim()
+try
+    try
+       Xpath 1                                 " X: 1
+       throw "oops"
+    catch /oops/
+       Xpath 2                                 " X: 2
+       throw v:exception       " rethrow user exception
+    catch /.*/
+       Xpath 4                                 " X: 0
+    endtry
+catch /^oops$/                 " catches rethrown user exception
+    Xpath 8                                    " X: 8
+catch /.*/
+    Xpath 16                                   " X: 0
+endtry
 
-    while 1
+function! F()
+    try
+       let caught = 0
        try
-           try
-               Xpath 1                         " X: 1
-               let caught = 0
-               while 1
-"                  if 1
-                   " Missing :endif
-               endwhile        " throw error exception
-           catch /^Vim(/
-               let caught = 1
-           finally
-               Xpath 2                         " X: 2
-               if caught || $VIMNOERRTHROW
-                   Xpath 4                     " X: 4
-               endif
-           endtry
+           Xpath 32                            " X: 32
+           write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e
+           Xpath 64                            " X: 0
+           Xout "did_emsg was reset before executing " .
+               \ "BufWritePost autocommands."
+       catch /^Vim(write):/
+           let caught = 1
+           throw v:exception   " throw error: cannot fake Vim exception
        catch /.*/
-           Xpath 8                             " X: 0
-           Xout v:exception "in" v:throwpoint
+           Xpath 128                           " X: 0
        finally
-           break               " discard error for $VIMNOERRTHROW
+           Xpath 256                           " X: 256
+           if !caught && !$VIMNOERRTHROW
+               Xpath 512                       " X: 0
+           endif
        endtry
-    endwhile
+    catch /^Vim(throw):/       " catches throw error
+       let caught = caught + 1
+    catch /.*/
+       Xpath 1024                              " X: 0
+    finally
+       Xpath 2048                              " X: 2048
+       if caught != 2
+           if !caught && !$VIMNOERRTHROW
+               Xpath 4096                      " X: 0
+           elseif caught
+               Xpath 8192                      " X: 0
+           endif
+           return              | " discard error for $VIMNOERRTHROW
+       endif
+    endtry
+endfunction
 
-    while 1
+call F()
+delfunction F
+
+function! G()
+    try
+       let caught = 0
        try
-           try
-               Xpath 16                        " X: 16
-               let caught = 0
-               try
-"                  if 1
-                   " Missing :endif
-               catch /.*/      " throw error exception
-                   Xpath 32                    " X: 0
-               catch /.*/
-                   Xpath 64                    " X: 0
-               endtry
-           catch /^Vim(/
-               let caught = 1
-           finally
-               Xpath 128                       " X: 128
-               if caught || $VIMNOERRTHROW
-                   Xpath 256                   " X: 256
+           Xpath 16384                         " X: 16384
+           asdf
+       catch /^Vim/            " catch error exception
+           let caught = 1
+           " Trigger Vim error exception with value specified after :echoerr
+           let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
+           echoerr value
+       catch /.*/
+           Xpath 32768                         " X: 0
+       finally
+           Xpath 65536                         " X: 65536
+           if !caught
+               if !$VIMNOERRTHROW
+                   Xpath 131072                " X: 0
+               else
+                   let value = "Error"
+                   echoerr value
                endif
-           endtry
+           endif
+       endtry
+    catch /^Vim(echoerr):/
+       let caught = caught + 1
+       if v:exception !~ value
+           Xpath 262144                        " X: 0
+       endif
+    catch /.*/
+       Xpath 524288                            " X: 0
+    finally
+       Xpath 1048576                           " X: 1048576
+       if caught != 2
+           if !caught && !$VIMNOERRTHROW
+               Xpath 2097152                   " X: 0
+           elseif caught
+               Xpath 4194304                   " X: 0
+           endif
+           return              | " discard error for $VIMNOERRTHROW
+       endif
+    endtry
+endfunction
+
+call G()
+delfunction G
+
+unlet! value caught
+
+if ExtraVim()
+    try
+       let errcaught = 0
+       try
+           Xpath 8388608                       " X: 8388608
+           let intcaught = 0
+           "INTERRUPT
+       catch /^Vim:/           " catch interrupt exception
+           let intcaught = 1
+           " Trigger Vim error exception with value specified after :echoerr
+           echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
        catch /.*/
-           Xpath 512                           " X: 0
-           Xout v:exception "in" v:throwpoint
+           Xpath 16777216                      " X: 0
        finally
-           break               " discard error for $VIMNOERRTHROW
+           Xpath 33554432                      " X: 33554432
+           if !intcaught
+               if !$VIMNOINTTHROW
+                   Xpath 67108864              " X: 0
+               else
+                   echoerr "Interrupt"
+               endif
+           endif
        endtry
-    endwhile
+    catch /^Vim(echoerr):/
+       let errcaught = 1
+       if v:exception !~ "Interrupt"
+           Xpath 134217728                     " X: 0
+       endif
+    finally
+       Xpath 268435456                         " X: 268435456
+       if !errcaught && !$VIMNOERRTHROW
+           Xpath 536870912                     " X: 0
+       endif
+    endtry
+endif
+
+Xcheck 311511339
+
+
+"-------------------------------------------------------------------------------
+" Test 61:  Catching interrupt exceptions                                  {{{1
+"
+"          When an interrupt occurs inside a :try/:endtry region, an
+"          interrupt exception is thrown and can be caught.  Its value is
+"          "Vim:Interrupt".  If the interrupt occurs after an error or a :throw
+"          but before a matching :catch is reached, all following :catches of
+"          that try block are ignored, but the interrupt exception can be
+"          caught by the next surrounding try conditional.  An interrupt is
+"          ignored when there is a previous interrupt that has not been caught
+"          or causes a :finally clause to be executed.
+"-------------------------------------------------------------------------------
+
+XpathINIT
+
+if ExtraVim()
 
     while 1
        try
            try
+               Xpath 1                         " X: 1
                let caught = 0
-               try
-                   Xpath 1024                  " X: 1024
-                   "INTERRUPT
-               catch /do_not_catch/
-                   Xpath 2048                  " X: 0
-"                  if 1
-                   " Missing :endif
-               catch /.*/      " throw error exception
-                   Xpath 4096                  " X: 0
-               catch /.*/
-                   Xpath 8192                  " X: 0
-               endtry
-           catch /^Vim(/
+               "INTERRUPT
+               Xpath 2                         " X: 0
+           catch /^Vim:Interrupt$/
                let caught = 1
            finally
-               Xpath 16384                     " X: 16384
-               if caught || $VIMNOERRTHROW
-                   Xpath 32768                 " X: 32768
+               Xpath 4                         " X: 4
+               if caught || $VIMNOINTTHROW
+                   Xpath 8                     " X: 8
                endif
            endtry
        catch /.*/
-           Xpath 65536                         " X: 0
+           Xpath 16                            " X: 0
            Xout v:exception "in" v:throwpoint
        finally
-           break               " discard error for $VIMNOERRTHROW
+           break               " discard interrupt for $VIMNOINTTHROW
        endtry
     endwhile
 
@@ -5616,30 +3750,31 @@ if ExtraVim()
            try
                let caught = 0
                try
-                   Xpath 131072                " X: 131072
-                   throw "x"
+                   Xpath 32                    " X: 32
+                   asdf
+                   Xpath 64                    " X: 0
                catch /do_not_catch/
-                   Xpath 262144                " X: 0
-"                  if 1
-                   " Missing :endif
-               catch /x/       " throw error exception
-                   Xpath 524288                " X: 0
+                   Xpath 128                   " X: 0
+               catch /.*/      "INTERRUPT - throw interrupt if !$VIMNOERRTHROW
+                   Xpath 256                   " X: 0
                catch /.*/
-                  Xpath 1048576                " X: 0
+                   Xpath 512                   " X: 0
+               finally         "INTERRUPT - throw interrupt if $VIMNOERRTHROW
+                   Xpath 1024                  " X: 1024
                endtry
-           catch /^Vim(/
+           catch /^Vim:Interrupt$/
                let caught = 1
            finally
-               Xpath 2097152                   " X: 2097152
-               if caught || $VIMNOERRTHROW
-                   Xpath 4194304               " X: 4194304
+               Xpath 2048                      " X: 2048
+               if caught || $VIMNOINTTHROW
+                   Xpath 4096                  " X: 4096
                endif
            endtry
        catch /.*/
-           Xpath 8388608                       " X: 0
+           Xpath 8192                          " X: 0
            Xout v:exception "in" v:throwpoint
        finally
-           break               " discard error for $VIMNOERRTHROW
+           break               " discard interrupt for $VIMNOINTTHROW
        endtry
     endwhile
 
@@ -5647,1534 +3782,1138 @@ if ExtraVim()
        try
            try
                let caught = 0
-               Xpath 16777216                  " X: 16777216
-"              endif           " :endif without :if; throw error exception
-"              if 1
-               " Missing :endif
-           catch /do_not_catch/ " ignore new error
-               Xpath 33554432                  " X: 0
-           catch /^Vim(endif):/
+               try
+                   Xpath 16384                 " X: 16384
+                   throw "x"
+                   Xpath 32768                 " X: 0
+               catch /do_not_catch/
+                   Xpath 65536                 " X: 0
+               catch /x/       "INTERRUPT
+                   Xpath 131072                " X: 0
+               catch /.*/
+                   Xpath 262144                " X: 0
+               endtry
+           catch /^Vim:Interrupt$/
                let caught = 1
-           catch /^Vim(/
-               Xpath 67108864                  " X: 0
            finally
-               Xpath 134217728                 " X: 134217728
-               if caught || $VIMNOERRTHROW
-                   Xpath 268435456             " X: 268435456
+               Xpath 524288                    " X: 524288
+               if caught || $VIMNOINTTHROW
+                   Xpath 1048576               " X: 1048576
                endif
            endtry
        catch /.*/
-           Xpath 536870912                     " X: 0
+           Xpath 2097152                       " X: 0
            Xout v:exception "in" v:throwpoint
-       finally
-           break               " discard error for $VIMNOERRTHROW
-       endtry
-    endwhile
-
-    Xpath 1073741824                           " X: 1073741824
-
-endif
-
-Xcheck 1499645335
-
-
-"-------------------------------------------------------------------------------
-" Test 65:  Errors in the /pattern/ argument of a :catch                   {{{1
-"
-"          On an error in the /pattern/ argument of a :catch, the :catch does
-"          not match.  Any following :catches of the same :try/:endtry don't
-"          match either.  Finally clauses are executed.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-function! MSG(enr, emsg)
-    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
-    if a:enr == ""
-       Xout "TODO: Add message number for:" a:emsg
-       let v:errmsg = ":" . v:errmsg
-    endif
-    let match = 1
-    if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
-       let match = 0
-       if v:errmsg == ""
-           Xout "Message missing."
-       else
-           let v:errmsg = escape(v:errmsg, '"')
-           Xout "Unexpected message:" v:errmsg
-       endif
-    endif
-    return match
-endfunction
-
-try
-    try
-       Xpath 1                                 " X: 1
-       throw "oops"
-    catch /^oops$/
-       Xpath 2                                 " X: 2
-    catch /\)/         " not checked; exception has already been caught
-       Xpath 4                                 " X: 0
-    endtry
-    Xpath 8                                    " X: 8
-catch /.*/
-    Xpath 16                                   " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-function! F()
-    try
-       let caught = 0
-       try
-           try
-               Xpath 32                        " X: 32
-               throw "ab"
-           catch /abc/ " does not catch
-               Xpath 64                        " X: 0
-           catch /\)/  " error; discards exception
-               Xpath 128                       " X: 0
-           catch /.*/  " not checked
-               Xpath 256                       " X: 0
-           finally
-               Xpath 512                       " X: 512
-           endtry
-           Xpath 1024                          " X: 0
-       catch /^ab$/    " checked, but original exception is discarded
-           Xpath 2048                          " X: 0
-       catch /^Vim(catch):/
-           let caught = 1
-           let v:errmsg = substitute(v:exception, '^Vim(catch):', '', "")
-       finally
-           Xpath 4096                          " X: 4096
-           if !caught && !$VIMNOERRTHROW
-               Xpath 8192                      " X: 0
-           endif
-           if !MSG('E475', "Invalid argument")
-               Xpath 16384                     " X: 0
-           endif
-           if !caught
-               return  | " discard error
-           endif
-       endtry
-    catch /.*/
-       Xpath 32768                             " X: 0
-       Xout v:exception "in" v:throwpoint
-    endtry
-endfunction
-
-call F()
-Xpath 65536                                    " X: 65536
-
-delfunction MSG
-delfunction F
-unlet! caught
-
-Xcheck 70187
-
-
-"-------------------------------------------------------------------------------
-" Test 66:  Stop range :call on error, interrupt, or :throw                {{{1
-"
-"          When a function which is multiply called for a range since it
-"          doesn't handle the range itself has an error in a command
-"          dynamically enclosed by :try/:endtry or gets an interrupt or
-"          executes a :throw, no more calls for the remaining lines in the
-"          range are made.  On an error in a command not dynamically enclosed
-"          by :try/:endtry, the function is executed again for the remaining
-"          lines in the range.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-if ExtraVim()
-
-    let file = tempname()
-    exec "edit" file
-
-    insert
-line 1
-line 2
-line 3
-.
-
-    XloopINIT! 1 2
-
-    let taken = ""
-    let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)"
-
-    function! F(reason, n) abort
-       let g:taken = g:taken . "F" . a:n .
-           \ substitute(a:reason, '\(\l\).*', '\u\1', "") .
-           \ "(" . line(".") . ")"
-
-       if a:reason == "error"
-           asdf
-       elseif a:reason == "interrupt"
-           "INTERRUPT
-           let dummy = 0
-       elseif a:reason == "throw"
-           throw "xyz"
-       elseif a:reason == "aborting error"
-           XloopNEXT
-           if g:taken != g:expected
-               Xloop 1                         " X: 0
-               Xout "'taken' is" g:taken "instead of" g:expected
-           endif
-           try
-               bwipeout!
-               call delete(file)
-               asdf
-           endtry
-       endif
-    endfunction
-
-    function! G(reason, n)
-       let g:taken = g:taken . "G" . a:n .
-           \ substitute(a:reason, '\(\l\).*', '\u\1', "")
-       1,3call F(a:reason, a:n)
-    endfunction
+       finally
+           break               " discard interrupt for $VIMNOINTTHROW
+       endtry
+    endwhile
 
-    Xpath 8                                    " X: 8
-    call G("error", 1)
-    try
-       Xpath 16                                " X: 16
+    while 1
        try
-           call G("error", 2)
-           Xpath 32                            " X: 0
-       finally
-           Xpath 64                            " X: 64
+           let caught = 0
            try
-               call G("interrupt", 3)
-               Xpath 128                       " X: 0
+               Xpath 4194304                   " X: 4194304
+               "INTERRUPT
+               Xpath 8388608                   " X: 0
+           catch /do_not_catch/ "INTERRUPT
+               Xpath 16777216                  " X: 0
+           catch /^Vim:Interrupt$/
+               let caught = 1
            finally
-               Xpath 256                       " X: 256
-               try
-                   call G("throw", 4)
-                   Xpath 512                   " X: 0
-               endtry
+               Xpath 33554432                  " X: 33554432
+               if caught || $VIMNOINTTHROW
+                   Xpath 67108864              " X: 67108864
+               endif
            endtry
+       catch /.*/
+           Xpath 134217728                     " X: 0
+           Xout v:exception "in" v:throwpoint
+       finally
+           break               " discard interrupt for $VIMNOINTTHROW
        endtry
-    catch /xyz/
-       Xpath 1024                              " X: 1024
-    catch /.*/
-       Xpath 2048                              " X: 0
-       Xout v:exception "in" ExtraVimThrowpoint()
-    endtry
-    Xpath 4096                                 " X: 4096
-    call G("aborting error", 5)
-    Xpath 8192                                 " X: 0
-    Xout "'taken' is" taken "instead of" expected
+    endwhile
+
+    Xpath 268435456                            " X: 268435456
 
 endif
 
-Xcheck 5464
+Xcheck 374889517
 
 
 "-------------------------------------------------------------------------------
-" Test 67:  :throw across :call command                                            {{{1
+" Test 62:  Catching error exceptions                                      {{{1
 "
-"          On a call command, an exception might be thrown when evaluating the
-"          function name, during evaluation of the arguments, or when the
-"          function is being executed.  The exception can be caught by the
-"          caller.
+"          An error inside a :try/:endtry region is converted to an exception
+"          and can be caught.  The error exception has a "Vim(cmdname):" prefix
+"          where cmdname is the name of the failing command, or a "Vim:" prefix
+"          if no command name is known.  The "Vim" prefixes cannot be faked.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-function! THROW(x, n)
-    if a:n == 1
-       Xpath 1                                         " X: 1
-    elseif a:n == 2
-       Xpath 2                                         " X: 2
-    elseif a:n == 3
-       Xpath 4                                         " X: 4
-    endif
-    throw a:x
-endfunction
-
-function! NAME(x, n)
-    if a:n == 1
-       Xpath 8                                         " X: 0
-    elseif a:n == 2
-       Xpath 16                                        " X: 16
-    elseif a:n == 3
-       Xpath 32                                        " X: 32
-    elseif a:n == 4
-       Xpath 64                                        " X: 64
-    endif
-    return a:x
-endfunction
-
-function! ARG(x, n)
-    if a:n == 1
-       Xpath 128                                       " X: 0
-    elseif a:n == 2
-       Xpath 256                                       " X: 0
-    elseif a:n == 3
-       Xpath 512                                       " X: 512
-    elseif a:n == 4
-       Xpath 1024                                      " X: 1024
+function! MSG(enr, emsg)
+    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+    if a:enr == ""
+       Xout "TODO: Add message number for:" a:emsg
+       let v:errmsg = ":" . v:errmsg
     endif
-    return a:x
-endfunction
-
-function! F(x, n)
-    if a:n == 2
-       Xpath 2048                                      " X: 0
-    elseif a:n == 4
-       Xpath 4096                                      " X: 4096
+    let match = 1
+    if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+       let match = 0
+       if v:errmsg == ""
+           Xout "Message missing."
+       else
+           let v:errmsg = escape(v:errmsg, '"')
+           Xout "Unexpected message:" v:errmsg
+       endif
     endif
+    return match
 endfunction
 
 while 1
     try
-       let error = 0
-       let v:errmsg = ""
-
-       while 1
-           try
-               Xpath 8192                              " X: 8192
-               call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
-               Xpath 16384                             " X: 0
-           catch /^name$/
-               Xpath 32768                             " X: 32768
-           catch /.*/
-               let error = 1
-               Xout "1:" v:exception "in" v:throwpoint
-           finally
-               if !error && $VIMNOERRTHROW && v:errmsg != ""
-                   let error = 1
-                   Xout "1:" v:errmsg
-               endif
-               if error
-                   Xpath 65536                         " X: 0
-               endif
-               let error = 0
-               let v:errmsg = ""
-               break           " discard error for $VIMNOERRTHROW
-           endtry
-       endwhile
-
-       while 1
-           try
-               Xpath 131072                            " X: 131072
-               call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
-               Xpath 262144                            " X: 0
-           catch /^arg$/
-               Xpath 524288                            " X: 524288
-           catch /.*/
-               let error = 1
-               Xout "2:" v:exception "in" v:throwpoint
-           finally
-               if !error && $VIMNOERRTHROW && v:errmsg != ""
-                   let error = 1
-                   Xout "2:" v:errmsg
-               endif
-               if error
-                   Xpath 1048576                       " X: 0
-               endif
-               let error = 0
-               let v:errmsg = ""
-               break           " discard error for $VIMNOERRTHROW
-           endtry
-       endwhile
-
-       while 1
-           try
-               Xpath 2097152                           " X: 2097152
-               call {NAME("THROW", 3)}(ARG("call", 3), 3)
-               Xpath 4194304                           " X: 0
-           catch /^call$/
-               Xpath 8388608                           " X: 8388608
-           catch /^0$/     " default return value
-               Xpath 16777216                          " X: 0
-               Xout "3:" v:throwpoint
-           catch /.*/
-               let error = 1
-               Xout "3:" v:exception "in" v:throwpoint
-           finally
-               if !error && $VIMNOERRTHROW && v:errmsg != ""
-                   let error = 1
-                   Xout "3:" v:errmsg
-               endif
-               if error
-                   Xpath 33554432                      " X: 0
-               endif
-               let error = 0
-               let v:errmsg = ""
-               break           " discard error for $VIMNOERRTHROW
-           endtry
-       endwhile
-
-       while 1
-           try
-               Xpath 67108864                          " X: 67108864
-               call {NAME("F", 4)}(ARG(4711, 4), 4)
-               Xpath 134217728                         " X: 134217728
-           catch /.*/
-               let error = 1
-               Xout "4:" v:exception "in" v:throwpoint
-           finally
-               if !error && $VIMNOERRTHROW && v:errmsg != ""
-                   let error = 1
-                   Xout "4:" v:errmsg
-               endif
-               if error
-                   Xpath 268435456                     " X: 0
-               endif
-               let error = 0
-               let v:errmsg = ""
-               break           " discard error for $VIMNOERRTHROW
-           endtry
-       endwhile
+       try
+           let caught = 0
+           unlet novar
+       catch /^Vim(unlet):/
+           let caught = 1
+           let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "")
+       finally
+           Xpath 1                             " X: 1
+           if !caught && !$VIMNOERRTHROW
+               Xpath 2                         " X: 0
+           endif
+           if !MSG('E108', "No such variable")
+               Xpath 4                         " X: 0
+           endif
+       endtry
+    catch /.*/
+       Xpath 8                                 " X: 0
+       Xout v:exception "in" v:throwpoint
+    finally
+       break           " discard error for $VIMNOERRTHROW
+    endtry
+endwhile
 
-    catch /^0$/            " default return value
-       Xpath 536870912                                 " X: 0
-       Xout v:throwpoint
+while 1
+    try
+       try
+           let caught = 0
+           throw novar                 " error in :throw
+       catch /^Vim(throw):/
+           let caught = 1
+           let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
+       finally
+           Xpath 16                            " X: 16
+           if !caught && !$VIMNOERRTHROW
+               Xpath 32                        " X: 0
+           endif
+           if caught ? !MSG('E121', "Undefined variable")
+                       \ : !MSG('E15', "Invalid expression")
+               Xpath 64                        " X: 0
+           endif
+       endtry
     catch /.*/
-       let error = 1
+       Xpath 128                               " X: 0
        Xout v:exception "in" v:throwpoint
     finally
-       if !error && $VIMNOERRTHROW && v:errmsg != ""
-           let error = 1
-           Xout v:errmsg
-       endif
-       if error
-           Xpath 1073741824                            " X: 0
-       endif
        break           " discard error for $VIMNOERRTHROW
     endtry
 endwhile
 
-unlet error
-delfunction F
-
-Xcheck 212514423
-
-" Leave THROW(), NAME(), and ARG() for the next test.
-
-
-"-------------------------------------------------------------------------------
-" Test 68:  :throw across function calls in expressions                            {{{1
-"
-"          On a function call within an expression, an exception might be
-"          thrown when evaluating the function name, during evaluation of the
-"          arguments, or when the function is being executed.  The exception
-"          can be caught by the caller.
-"
-"          This test reuses the functions THROW(), NAME(), and ARG() from the
-"          previous test.
-"-------------------------------------------------------------------------------
-
-XpathINIT
+while 1
+    try
+       try
+           let caught = 0
+           throw "Vim:faked"           " error: cannot fake Vim exception
+       catch /^Vim(throw):/
+           let caught = 1
+           let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
+       finally
+           Xpath 256                           " X: 256
+           if !caught && !$VIMNOERRTHROW
+               Xpath 512                       " X: 0
+           endif
+           if !MSG('E608', "Cannot :throw exceptions with 'Vim' prefix")
+               Xpath 1024                      " X: 0
+           endif
+       endtry
+    catch /.*/
+       Xpath 2048                              " X: 0
+       Xout v:exception "in" v:throwpoint
+    finally
+       break           " discard error for $VIMNOERRTHROW
+    endtry
+endwhile
 
-function! F(x, n)
-    if a:n == 2
-       Xpath 2048                                      " X: 0
-    elseif a:n == 4
-       Xpath 4096                                      " X: 4096
-    endif
-    return a:x
+function! F()
+    while 1
+    " Missing :endwhile
 endfunction
 
-unlet! var1 var2 var3 var4
-
 while 1
     try
-       let error = 0
-       let v:errmsg = ""
+       try
+           let caught = 0
+           call F()
+       catch /^Vim(endfunction):/
+           let caught = 1
+           let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "")
+       finally
+           Xpath 4096                          " X: 4096
+           if !caught && !$VIMNOERRTHROW
+               Xpath 8192                      " X: 0
+           endif
+           if !MSG('E170', "Missing :endwhile")
+               Xpath 16384                     " X: 0
+           endif
+       endtry
+    catch /.*/
+       Xpath 32768                             " X: 0
+       Xout v:exception "in" v:throwpoint
+    finally
+       break           " discard error for $VIMNOERRTHROW
+    endtry
+endwhile
 
-       while 1
-           try
-               Xpath 8192                              " X: 8192
-               let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
-               Xpath 16384                             " X: 0
-           catch /^name$/
-               Xpath 32768                             " X: 32768
-           catch /.*/
-               let error = 1
-               Xout "1:" v:exception "in" v:throwpoint
-           finally
-               if !error && $VIMNOERRTHROW && v:errmsg != ""
-                   let error = 1
-                   Xout "1:" v:errmsg
-               endif
-               if error
-                   Xpath 65536                         " X: 0
-               endif
-               let error = 0
-               let v:errmsg = ""
-               break           " discard error for $VIMNOERRTHROW
-           endtry
-       endwhile
+while 1
+    try
+       try
+           let caught = 0
+           ExecAsScript F
+       catch /^Vim:/
+           let caught = 1
+           let v:errmsg = substitute(v:exception, '^Vim:', '', "")
+       finally
+           Xpath 65536                         " X: 65536
+           if !caught && !$VIMNOERRTHROW
+               Xpath 131072                    " X: 0
+           endif
+           if !MSG('E170', "Missing :endwhile")
+               Xpath 262144                    " X: 0
+           endif
+       endtry
+    catch /.*/
+       Xpath 524288                            " X: 0
+       Xout v:exception "in" v:throwpoint
+    finally
+       break           " discard error for $VIMNOERRTHROW
+    endtry
+endwhile
 
-       while 1
-           try
-               Xpath 131072                            " X: 131072
-               let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
-               Xpath 262144                            " X: 0
-           catch /^arg$/
-               Xpath 524288                            " X: 524288
-           catch /.*/
-               let error = 1
-               Xout "2:" v:exception "in" v:throwpoint
-           finally
-               if !error && $VIMNOERRTHROW && v:errmsg != ""
-                   let error = 1
-                   Xout "2:" v:errmsg
-               endif
-               if error
-                   Xpath 1048576                       " X: 0
-               endif
-               let error = 0
-               let v:errmsg = ""
-               break           " discard error for $VIMNOERRTHROW
-           endtry
-       endwhile
+function! G()
+    call G()
+endfunction
 
-       while 1
-           try
-               Xpath 2097152                           " X: 2097152
-               let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3)
-               Xpath 4194304                           " X: 0
-           catch /^call$/
-               Xpath 8388608                           " X: 8388608
-           catch /^0$/     " default return value
-               Xpath 16777216                          " X: 0
-               Xout "3:" v:throwpoint
-           catch /.*/
-               let error = 1
-               Xout "3:" v:exception "in" v:throwpoint
-           finally
-               if !error && $VIMNOERRTHROW && v:errmsg != ""
-                   let error = 1
-                   Xout "3:" v:errmsg
-               endif
-               if error
-                   Xpath 33554432                      " X: 0
-               endif
-               let error = 0
-               let v:errmsg = ""
-               break           " discard error for $VIMNOERRTHROW
-           endtry
-       endwhile
+while 1
+    try
+       let mfd_save = &mfd
+       set mfd=3
+       try
+           let caught = 0
+           call G()
+       catch /^Vim(call):/
+           let caught = 1
+           let v:errmsg = substitute(v:exception, '^Vim(call):', '', "")
+       finally
+           Xpath 1048576                       " X: 1048576
+           if !caught && !$VIMNOERRTHROW
+               Xpath 2097152                   " X: 0
+           endif
+           if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
+               Xpath 4194304                   " X: 0
+           endif
+       endtry
+    catch /.*/
+       Xpath 8388608                           " X: 0
+       Xout v:exception "in" v:throwpoint
+    finally
+       let &mfd = mfd_save
+       break           " discard error for $VIMNOERRTHROW
+    endtry
+endwhile
 
-       while 1
-           try
-               Xpath 67108864                          " X: 67108864
-               let var4 = {NAME("F", 4)}(ARG(4711, 4), 4)
-               Xpath 134217728                         " X: 134217728
-           catch /.*/
-               let error = 1
-               Xout "4:" v:exception "in" v:throwpoint
-           finally
-               if !error && $VIMNOERRTHROW && v:errmsg != ""
-                   let error = 1
-                   Xout "4:" v:errmsg
-               endif
-               if error
-                   Xpath 268435456                     " X: 0
-               endif
-               let error = 0
-               let v:errmsg = ""
-               break           " discard error for $VIMNOERRTHROW
-           endtry
-       endwhile
+function! H()
+    return H()
+endfunction
 
-    catch /^0$/            " default return value
-       Xpath 536870912                                 " X: 0
-       Xout v:throwpoint
+while 1
+    try
+       let mfd_save = &mfd
+       set mfd=3
+       try
+           let caught = 0
+           call H()
+       catch /^Vim(return):/
+           let caught = 1
+           let v:errmsg = substitute(v:exception, '^Vim(return):', '', "")
+       finally
+           Xpath 16777216                      " X: 16777216
+           if !caught && !$VIMNOERRTHROW
+               Xpath 33554432                  " X: 0
+           endif
+           if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
+               Xpath 67108864                  " X: 0
+           endif
+       endtry
     catch /.*/
-       let error = 1
+       Xpath 134217728                         " X: 0
        Xout v:exception "in" v:throwpoint
     finally
-       if !error && $VIMNOERRTHROW && v:errmsg != ""
-           let error = 1
-           Xout v:errmsg
-       endif
-       if error
-           Xpath 1073741824                            " X: 0
-       endif
+       let &mfd = mfd_save
        break           " discard error for $VIMNOERRTHROW
     endtry
 endwhile
 
-if exists("var1") || exists("var2") || exists("var3") ||
-           \ !exists("var4") || var4 != 4711
-    " The Xpath command does not accept 2^31 (negative); add explicitly:
-    let Xpath = Xpath + 2147483648                     " X: 0
-    if exists("var1")
-       Xout "var1 =" var1
-    endif
-    if exists("var2")
-       Xout "var2 =" var2
-    endif
-    if exists("var3")
-       Xout "var3 =" var3
-    endif
-    if !exists("var4")
-       Xout "var4 unset"
-    elseif var4 != 4711
-       Xout "var4 =" var4
-    endif
-endif
-
-unlet! error var1 var2 var3 var4
-delfunction THROW
-delfunction NAME
-delfunction ARG
+unlet! caught mfd_save
 delfunction F
+delfunction G
+delfunction H
+Xpath 268435456                                        " X: 268435456
 
-Xcheck 212514423
+Xcheck 286331153
+
+" Leave MSG() for the next test.
 
 
 "-------------------------------------------------------------------------------
-" Test 69:  :throw across :if, :elseif, :while                             {{{1
+" Test 63:  Suppressing error exceptions by :silent!.                      {{{1
+"
+"          A :silent! command inside a :try/:endtry region suppresses the
+"          conversion of errors to an exception and the immediate abortion on
+"          error.  When the commands executed by the :silent! themselves open
+"          a new :try/:endtry region, conversion of errors to exception and
+"          immediate abortion is switched on again - until the next :silent!
+"          etc.  The :silent! has the effect of setting v:errmsg to the error
+"          message text (without displaying it) and continuing with the next
+"          script line.
+"
+"          When a command triggering autocommands is executed by :silent!
+"          inside a :try/:endtry, the autocommand execution is not suppressed
+"          on error.
 "
-"          On an :if, :elseif, or :while command, an exception might be thrown
-"          during evaluation of the expression to test.  The exception can be
-"          caught by the script.
+"          This test reuses the function MSG() from the previous test.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-XloopINIT! 1 2
+XloopINIT! 1 4
+
+let taken = ""
 
-function! THROW(x)
+function! S(n) abort
     XloopNEXT
-    Xloop 1                                    " X: 1 + 2 + 4
-    throw a:x
+    let g:taken = g:taken . "E" . a:n
+    let v:errmsg = ""
+    exec "asdf" . a:n
+
+    " Check that ":silent!" continues:
+    Xloop 1
+
+    " Check that ":silent!" sets "v:errmsg":
+    if MSG('E492', "Not an editor command")
+       Xloop 2
+    endif
 endfunction
 
-try
+function! Foo()
+    while 1
+       try
+           try
+               let caught = 0
+               " This is not silent:
+               call S(3)                               " X: 0 * 16
+           catch /^Vim:/
+               let caught = 1
+               let errmsg3 = substitute(v:exception, '^Vim:', '', "")
+               silent! call S(4)                       " X: 3 * 64
+           finally
+               if !caught
+                   let errmsg3 = v:errmsg
+                   " Do call S(4) here if not executed in :catch.
+                   silent! call S(4)
+               endif
+               Xpath 1048576                   " X: 1048576
+               if !caught && !$VIMNOERRTHROW
+                   Xpath 2097152               " X: 0
+               endif
+               let v:errmsg = errmsg3
+               if !MSG('E492', "Not an editor command")
+                   Xpath 4194304               " X: 0
+               endif
+               silent! call S(5)                       " X: 3 * 256
+               " Break out of try conditionals that cover ":silent!".  This also
+               " discards the aborting error when $VIMNOERRTHROW is non-zero.
+               break
+           endtry
+       catch /.*/
+           Xpath 8388608                       " X: 0
+           Xout v:exception "in" v:throwpoint
+       endtry
+    endwhile
+    " This is a double ":silent!" (see caller).
+    silent! call S(6)                                  " X: 3 * 1024
+endfunction
 
+function! Bar()
     try
-       Xpath 8                                 " X: 8
-       if 4711 == THROW("if") + 111
-           Xpath 16                            " X: 0
-       else
-           Xpath 32                            " X: 0
-       endif
-       Xpath 64                                " X: 0
-    catch /^if$/
-       Xpath 128                               " X: 128
-    catch /.*/
-       Xpath 256                               " X: 0
-       Xout "if:" v:exception "in" v:throwpoint
-    endtry
+       silent! call S(2)                               " X: 3 * 4
+                                                       " X: 3 * 4096
+       silent! execute "call Foo() | call S(7)"
+       silent! call S(8)                               " X: 3 * 16384
+    endtry     " normal end of try cond that covers ":silent!"
+    " This has a ":silent!" from the caller:
+    call S(9)                                          " X: 3 * 65536
+endfunction
 
-    try
-       Xpath 512                               " X: 512
-       if 4711 == 4 + 7 + 1 + 1
-           Xpath 1024                          " X: 0
-       elseif 4711 == THROW("elseif") + 222
-           Xpath 2048                          " X: 0
-       else
-           Xpath 4096                          " X: 0
-       endif
-       Xpath 8192                              " X: 0
-    catch /^elseif$/
-       Xpath 16384                             " X: 16384
-    catch /.*/
-       Xpath 32768                             " X: 0
-       Xout "elseif:" v:exception "in" v:throwpoint
-    endtry
+silent! call S(1)                                      " X: 3 * 1
+silent! call Bar()
+silent! call S(10)                                     " X: 3 * 262144
 
-    try
-       Xpath 65536                             " X: 65536
-       while 4711 == THROW("while") + 4711
-           Xpath 131072                        " X: 0
-           break
-       endwhile
-       Xpath 262144                            " X: 0
-    catch /^while$/
-       Xpath 524288                            " X: 524288
-    catch /.*/
-       Xpath 1048576                           " X: 0
-       Xout "while:" v:exception "in" v:throwpoint
-    endtry
+let expected = "E1E2E3E4E5E6E7E8E9E10"
+if taken != expected
+    Xpath 16777216                             " X: 0
+    Xout "'taken' is" taken "instead of" expected
+endif
 
-catch /^0$/        " default return value
-    Xpath 2097152                              " X: 0
-    Xout v:throwpoint
-catch /.*/
-    Xout v:exception "in" v:throwpoint
-    Xpath 4194304                              " X: 0
-endtry
+augroup TMP
+    autocmd BufWritePost * Xpath 33554432      " X: 33554432
+augroup END
 
-Xpath 8388608                                  " X: 8388608
+Xpath 67108864                                 " X: 67108864
+write /i/m/p/o/s/s/i/b/l/e
+Xpath 134217728                                        " X: 134217728
 
-delfunction THROW
+autocmd! TMP
+unlet! caught errmsg3 taken expected
+delfunction S
+delfunction Foo
+delfunction Bar
+delfunction MSG
 
-Xcheck 8995471
+Xcheck 236978127
 
 
 "-------------------------------------------------------------------------------
-" Test 70:  :throw across :return or :throw                                {{{1
+" Test 64:  Error exceptions after error, interrupt or :throw              {{{1
 "
-"          On a :return or :throw command, an exception might be thrown during
-"          evaluation of the expression to return or throw, respectively.  The
-"          exception can be caught by the script.
+"          When an error occurs after an interrupt or a :throw but before
+"          a matching :catch is reached, all following :catches of that try
+"          block are ignored, but the error exception can be caught by the next
+"          surrounding try conditional.  Any previous error exception is
+"          discarded.  An error is ignored when there is a previous error that
+"          has not been caught.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-let taken = ""
-
-function! THROW(x, n)
-    let g:taken = g:taken . "T" . a:n
-    throw a:x
-endfunction
-
-function! F(x, y, n)
-    let g:taken = g:taken . "F" . a:n
-    return a:x + THROW(a:y, a:n)
-endfunction
-
-function! G(x, y, n)
-    let g:taken = g:taken . "G" . a:n
-    throw a:x . THROW(a:y, a:n)
-    return a:x
-endfunction
-
-try
-    try
-       Xpath 1                                 " X: 1
-       call F(4711, "return", 1)
-       Xpath 2                                 " X: 0
-    catch /^return$/
-       Xpath 4                                 " X: 4
-    catch /.*/
-       Xpath 8                                 " X: 0
-       Xout "return:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-       Xpath 16                                " X: 16
-       let var = F(4712, "return-var", 2)
-       Xpath 32                                " X: 0
-    catch /^return-var$/
-       Xpath 64                                " X: 64
-    catch /.*/
-       Xpath 128                               " X: 0
-       Xout "return-var:" v:exception "in" v:throwpoint
-    finally
-       unlet! var
-    endtry
+if ExtraVim()
 
-    try
-       Xpath 256                               " X: 256
-       throw "except1" . THROW("throw1", 3)
-       Xpath 512                               " X: 0
-    catch /^except1/
-       Xpath 1024                              " X: 0
-    catch /^throw1$/
-       Xpath 2048                              " X: 2048
-    catch /.*/
-       Xpath 4096                              " X: 0
-       Xout "throw1:" v:exception "in" v:throwpoint
-    endtry
+    while 1
+       try
+           try
+               Xpath 1                         " X: 1
+               let caught = 0
+               while 1
+"                  if 1
+                   " Missing :endif
+               endwhile        " throw error exception
+           catch /^Vim(/
+               let caught = 1
+           finally
+               Xpath 2                         " X: 2
+               if caught || $VIMNOERRTHROW
+                   Xpath 4                     " X: 4
+               endif
+           endtry
+       catch /.*/
+           Xpath 8                             " X: 0
+           Xout v:exception "in" v:throwpoint
+       finally
+           break               " discard error for $VIMNOERRTHROW
+       endtry
+    endwhile
 
-    try
-       Xpath 8192                              " X: 8192
-       call G("except2", "throw2", 4)
-       Xpath 16384                             " X: 0
-    catch /^except2/
-       Xpath 32768                             " X: 0
-    catch /^throw2$/
-       Xpath 65536                             " X: 65536
-    catch /.*/
-       Xpath 131072                            " X: 0
-       Xout "throw2:" v:exception "in" v:throwpoint
-    endtry
+    while 1
+       try
+           try
+               Xpath 16                        " X: 16
+               let caught = 0
+               try
+"                  if 1
+                   " Missing :endif
+               catch /.*/      " throw error exception
+                   Xpath 32                    " X: 0
+               catch /.*/
+                   Xpath 64                    " X: 0
+               endtry
+           catch /^Vim(/
+               let caught = 1
+           finally
+               Xpath 128                       " X: 128
+               if caught || $VIMNOERRTHROW
+                   Xpath 256                   " X: 256
+               endif
+           endtry
+       catch /.*/
+           Xpath 512                           " X: 0
+           Xout v:exception "in" v:throwpoint
+       finally
+           break               " discard error for $VIMNOERRTHROW
+       endtry
+    endwhile
 
-    try
-       Xpath 262144                            " X: 262144
-       let var = G("except3", "throw3", 5)
-       Xpath 524288                            " X: 0
-    catch /^except3/
-       Xpath 1048576                           " X: 0
-    catch /^throw3$/
-       Xpath 2097152                           " X: 2097152
-    catch /.*/
-       Xpath 4194304                           " X: 0
-       Xout "throw3:" v:exception "in" v:throwpoint
-    finally
-       unlet! var
-    endtry
+    while 1
+       try
+           try
+               let caught = 0
+               try
+                   Xpath 1024                  " X: 1024
+                   "INTERRUPT
+               catch /do_not_catch/
+                   Xpath 2048                  " X: 0
+"                  if 1
+                   " Missing :endif
+               catch /.*/      " throw error exception
+                   Xpath 4096                  " X: 0
+               catch /.*/
+                   Xpath 8192                  " X: 0
+               endtry
+           catch /^Vim(/
+               let caught = 1
+           finally
+               Xpath 16384                     " X: 16384
+               if caught || $VIMNOERRTHROW
+                   Xpath 32768                 " X: 32768
+               endif
+           endtry
+       catch /.*/
+           Xpath 65536                         " X: 0
+           Xout v:exception "in" v:throwpoint
+       finally
+           break               " discard error for $VIMNOERRTHROW
+       endtry
+    endwhile
 
-    let expected = "F1T1F2T2T3G4T4G5T5"
-    if taken != expected
-       Xpath 8388608                           " X: 0
-       Xout "'taken' is" taken "instead of" expected
-    endif
+    while 1
+       try
+           try
+               let caught = 0
+               try
+                   Xpath 131072                " X: 131072
+                   throw "x"
+               catch /do_not_catch/
+                   Xpath 262144                " X: 0
+"                  if 1
+                   " Missing :endif
+               catch /x/       " throw error exception
+                   Xpath 524288                " X: 0
+               catch /.*/
+                  Xpath 1048576                " X: 0
+               endtry
+           catch /^Vim(/
+               let caught = 1
+           finally
+               Xpath 2097152                   " X: 2097152
+               if caught || $VIMNOERRTHROW
+                   Xpath 4194304               " X: 4194304
+               endif
+           endtry
+       catch /.*/
+           Xpath 8388608                       " X: 0
+           Xout v:exception "in" v:throwpoint
+       finally
+           break               " discard error for $VIMNOERRTHROW
+       endtry
+    endwhile
 
-catch /^0$/        " default return value
-    Xpath 16777216                             " X: 0
-    Xout v:throwpoint
-catch /.*/
-    Xpath 33554432                             " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
+    while 1
+       try
+           try
+               let caught = 0
+               Xpath 16777216                  " X: 16777216
+"              endif           " :endif without :if; throw error exception
+"              if 1
+               " Missing :endif
+           catch /do_not_catch/ " ignore new error
+               Xpath 33554432                  " X: 0
+           catch /^Vim(endif):/
+               let caught = 1
+           catch /^Vim(/
+               Xpath 67108864                  " X: 0
+           finally
+               Xpath 134217728                 " X: 134217728
+               if caught || $VIMNOERRTHROW
+                   Xpath 268435456             " X: 268435456
+               endif
+           endtry
+       catch /.*/
+           Xpath 536870912                     " X: 0
+           Xout v:exception "in" v:throwpoint
+       finally
+           break               " discard error for $VIMNOERRTHROW
+       endtry
+    endwhile
 
-Xpath 67108864                                 " X: 67108864
+    Xpath 1073741824                           " X: 1073741824
 
-unlet taken expected
-delfunction THROW
-delfunction F
-delfunction G
+endif
 
-Xcheck 69544277
+Xcheck 1499645335
 
 
 "-------------------------------------------------------------------------------
-" Test 71:  :throw across :echo variants and :execute                      {{{1
+" Test 65:  Errors in the /pattern/ argument of a :catch                   {{{1
 "
-"          On an :echo, :echon, :echomsg, :echoerr, or :execute command, an
-"          exception might be thrown during evaluation of the arguments to
-"          be displayed or executed as a command, respectively.  Any following
-"          arguments are not evaluated, then.  The exception can be caught by
-"          the script.
+"          On an error in the /pattern/ argument of a :catch, the :catch does
+"          not match.  Any following :catches of the same :try/:endtry don't
+"          match either.  Finally clauses are executed.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-let taken = ""
-
-function! THROW(x, n)
-    let g:taken = g:taken . "T" . a:n
-    throw a:x
-endfunction
-
-function! F(n)
-    let g:taken = g:taken . "F" . a:n
-    return "F" . a:n
+function! MSG(enr, emsg)
+    let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+    if a:enr == ""
+       Xout "TODO: Add message number for:" a:emsg
+       let v:errmsg = ":" . v:errmsg
+    endif
+    let match = 1
+    if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+       let match = 0
+       if v:errmsg == ""
+           Xout "Message missing."
+       else
+           let v:errmsg = escape(v:errmsg, '"')
+           Xout "Unexpected message:" v:errmsg
+       endif
+    endif
+    return match
 endfunction
 
 try
     try
        Xpath 1                                 " X: 1
-       echo "echo" . THROW("echo-except", 1) F(1)
-       Xpath 2                                 " X: 0
-    catch /^echo-except$/
-       Xpath 4                                 " X: 4
-    catch /.*/
-       Xpath 8                                 " X: 0
-       Xout "echo:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-       Xpath 16                                " X: 16
-       echon "echon" . THROW("echon-except", 2) F(2)
-       Xpath 32                                " X: 0
-    catch /^echon-except$/
-       Xpath 64                                " X: 64
-    catch /.*/
-       Xpath 128                               " X: 0
-       Xout "echon:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-       Xpath 256                               " X: 256
-       echomsg "echomsg" . THROW("echomsg-except", 3) F(3)
-       Xpath 512                               " X: 0
-    catch /^echomsg-except$/
-       Xpath 1024                              " X: 1024
-    catch /.*/
-       Xpath 2048                              " X: 0
-       Xout "echomsg:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-       Xpath 4096                              " X: 4096
-       echoerr "echoerr" . THROW("echoerr-except", 4) F(4)
-       Xpath 8192                              " X: 0
-    catch /^echoerr-except$/
-       Xpath 16384                             " X: 16384
-    catch /Vim/
-       Xpath 32768                             " X: 0
-    catch /echoerr/
-       Xpath 65536                             " X: 0
-    catch /.*/
-       Xpath 131072                            " X: 0
-       Xout "echoerr:" v:exception "in" v:throwpoint
+       throw "oops"
+    catch /^oops$/
+       Xpath 2                                 " X: 2
+    catch /\)/         " not checked; exception has already been caught
+       Xpath 4                                 " X: 0
     endtry
+    Xpath 8                                    " X: 8
+catch /.*/
+    Xpath 16                                   " X: 0
+    Xout v:exception "in" v:throwpoint
+endtry
 
+function! F()
     try
-       Xpath 262144                            " X: 262144
-       execute "echo 'execute" . THROW("execute-except", 5) F(5) "'"
-       Xpath 524288                            " X: 0
-    catch /^execute-except$/
-       Xpath 1048576                           " X: 1048576
+       let caught = 0
+       try
+           try
+               Xpath 32                        " X: 32
+               throw "ab"
+           catch /abc/ " does not catch
+               Xpath 64                        " X: 0
+           catch /\)/  " error; discards exception
+               Xpath 128                       " X: 0
+           catch /.*/  " not checked
+               Xpath 256                       " X: 0
+           finally
+               Xpath 512                       " X: 512
+           endtry
+           Xpath 1024                          " X: 0
+       catch /^ab$/    " checked, but original exception is discarded
+           Xpath 2048                          " X: 0
+       catch /^Vim(catch):/
+           let caught = 1
+           let v:errmsg = substitute(v:exception, '^Vim(catch):', '', "")
+       finally
+           Xpath 4096                          " X: 4096
+           if !caught && !$VIMNOERRTHROW
+               Xpath 8192                      " X: 0
+           endif
+           if !MSG('E475', "Invalid argument")
+               Xpath 16384                     " X: 0
+           endif
+           if !caught
+               return  | " discard error
+           endif
+       endtry
     catch /.*/
-       Xpath 2097152                           " X: 0
-       Xout "execute:" v:exception "in" v:throwpoint
+       Xpath 32768                             " X: 0
+       Xout v:exception "in" v:throwpoint
     endtry
+endfunction
 
-    let expected = "T1T2T3T4T5"
-    if taken != expected
-       Xpath 4194304                           " X: 0
-       Xout "'taken' is" taken "instead of" expected
-    endif
-
-catch /^0$/        " default return value
-    Xpath 8388608                              " X: 0
-    Xout v:throwpoint
-catch /.*/
-    Xpath 16777216                             " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-Xpath 33554432                                 " X: 33554432
+call F()
+Xpath 65536                                    " X: 65536
 
-unlet taken expected
-delfunction THROW
+delfunction MSG
 delfunction F
+unlet! caught
 
-Xcheck 34886997
+Xcheck 70187
 
 
 "-------------------------------------------------------------------------------
-" Test 72:  :throw across :let or :unlet                                   {{{1
+" Test 66:  Stop range :call on error, interrupt, or :throw                {{{1
 "
-"          On a :let command, an exception might be thrown during evaluation
-"          of the expression to assign.  On an :let or :unlet command, the
-"          evaluation of the name of the variable to be assigned or list or
-"          deleted, respectively, may throw an exception.  Any following
-"          arguments are not evaluated, then.  The exception can be caught by
-"          the script.
+"          When a function which is multiply called for a range since it
+"          doesn't handle the range itself has an error in a command
+"          dynamically enclosed by :try/:endtry or gets an interrupt or
+"          executes a :throw, no more calls for the remaining lines in the
+"          range are made.  On an error in a command not dynamically enclosed
+"          by :try/:endtry, the function is executed again for the remaining
+"          lines in the range.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-let throwcount = 0
+if ExtraVim()
 
-function! THROW(x)
-    let g:throwcount = g:throwcount + 1
-    throw a:x
-endfunction
+    let file = tempname()
+    exec "edit" file
 
-try
-    try
-       let $VAR = "old_value"
-       Xpath 1                                 " X: 1
-       let $VAR = "let(" . THROW("var") . ")"
-       Xpath 2                                 " X: 0
-    catch /^var$/
-       Xpath 4                                 " X: 4
-    finally
-       if $VAR != "old_value"
-           Xpath 8                             " X: 0
+    insert
+line 1
+line 2
+line 3
+.
+
+    XloopINIT! 1 2
+
+    let taken = ""
+    let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)"
+
+    function! F(reason, n) abort
+       let g:taken = g:taken . "F" . a:n .
+           \ substitute(a:reason, '\(\l\).*', '\u\1', "") .
+           \ "(" . line(".") . ")"
+
+       if a:reason == "error"
+           asdf
+       elseif a:reason == "interrupt"
+           "INTERRUPT
+           let dummy = 0
+       elseif a:reason == "throw"
+           throw "xyz"
+       elseif a:reason == "aborting error"
+           XloopNEXT
+           if g:taken != g:expected
+               Xloop 1                         " X: 0
+               Xout "'taken' is" g:taken "instead of" g:expected
+           endif
+           try
+               bwipeout!
+               call delete(file)
+               asdf
+           endtry
        endif
-    endtry
+    endfunction
+
+    function! G(reason, n)
+       let g:taken = g:taken . "G" . a:n .
+           \ substitute(a:reason, '\(\l\).*', '\u\1', "")
+       1,3call F(a:reason, a:n)
+    endfunction
 
+    Xpath 8                                    " X: 8
+    call G("error", 1)
     try
-       let @a = "old_value"
        Xpath 16                                " X: 16
-       let @a = "let(" . THROW("reg") . ")"
-       Xpath 32                                " X: 0
-    catch /^reg$/
        try
+           call G("error", 2)
+           Xpath 32                            " X: 0
+       finally
            Xpath 64                            " X: 64
-           let @A = "let(" . THROW("REG") . ")"
-           Xpath 128                           " X: 0
-       catch /^REG$/
-           Xpath 256                           " X: 256
+           try
+               call G("interrupt", 3)
+               Xpath 128                       " X: 0
+           finally
+               Xpath 256                       " X: 256
+               try
+                   call G("throw", 4)
+                   Xpath 512                   " X: 0
+               endtry
+           endtry
        endtry
-    finally
-       if @a != "old_value"
-           Xpath 512                           " X: 0
-       endif
-       if @A != "old_value"
-           Xpath 1024                          " X: 0
-       endif
+    catch /xyz/
+       Xpath 1024                              " X: 1024
+    catch /.*/
+       Xpath 2048                              " X: 0
+       Xout v:exception "in" ExtraVimThrowpoint()
     endtry
+    Xpath 4096                                 " X: 4096
+    call G("aborting error", 5)
+    Xpath 8192                                 " X: 0
+    Xout "'taken' is" taken "instead of" expected
+
+endif
+
+Xcheck 5464
+
+
+"-------------------------------------------------------------------------------
+" Test 67:  :throw across :call command                                            {{{1
+"
+"          On a call command, an exception might be thrown when evaluating the
+"          function name, during evaluation of the arguments, or when the
+"          function is being executed.  The exception can be caught by the
+"          caller.
+"-------------------------------------------------------------------------------
 
+XpathINIT
+
+function! THROW(x, n)
+    if a:n == 1
+       Xpath 1                                         " X: 1
+    elseif a:n == 2
+       Xpath 2                                         " X: 2
+    elseif a:n == 3
+       Xpath 4                                         " X: 4
+    endif
+    throw a:x
+endfunction
+
+function! NAME(x, n)
+    if a:n == 1
+       Xpath 8                                         " X: 0
+    elseif a:n == 2
+       Xpath 16                                        " X: 16
+    elseif a:n == 3
+       Xpath 32                                        " X: 32
+    elseif a:n == 4
+       Xpath 64                                        " X: 64
+    endif
+    return a:x
+endfunction
+
+function! ARG(x, n)
+    if a:n == 1
+       Xpath 128                                       " X: 0
+    elseif a:n == 2
+       Xpath 256                                       " X: 0
+    elseif a:n == 3
+       Xpath 512                                       " X: 512
+    elseif a:n == 4
+       Xpath 1024                                      " X: 1024
+    endif
+    return a:x
+endfunction
+
+function! F(x, n)
+    if a:n == 2
+       Xpath 2048                                      " X: 0
+    elseif a:n == 4
+       Xpath 4096                                      " X: 4096
+    endif
+endfunction
+
+while 1
     try
-       let saved_gpath = &g:path
-       let saved_lpath = &l:path
-       Xpath 2048                              " X: 2048
-       let &path = "let(" . THROW("opt") . ")"
-       Xpath 4096                              " X: 0
-    catch /^opt$/
-       try
-           Xpath 8192                          " X: 8192
-           let &g:path = "let(" . THROW("gopt") . ")"
-           Xpath 16384                         " X: 0
-       catch /^gopt$/
+       let error = 0
+       let v:errmsg = ""
+
+       while 1
            try
-               Xpath 32768                     " X: 32768
-               let &l:path = "let(" . THROW("lopt") . ")"
-               Xpath 65536                     " X: 0
-           catch /^lopt$/
-               Xpath 131072                    " X: 131072
+               Xpath 8192                              " X: 8192
+               call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
+               Xpath 16384                             " X: 0
+           catch /^name$/
+               Xpath 32768                             " X: 32768
+           catch /.*/
+               let error = 1
+               Xout "1:" v:exception "in" v:throwpoint
+           finally
+               if !error && $VIMNOERRTHROW && v:errmsg != ""
+                   let error = 1
+                   Xout "1:" v:errmsg
+               endif
+               if error
+                   Xpath 65536                         " X: 0
+               endif
+               let error = 0
+               let v:errmsg = ""
+               break           " discard error for $VIMNOERRTHROW
+           endtry
+       endwhile
+
+       while 1
+           try
+               Xpath 131072                            " X: 131072
+               call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
+               Xpath 262144                            " X: 0
+           catch /^arg$/
+               Xpath 524288                            " X: 524288
+           catch /.*/
+               let error = 1
+               Xout "2:" v:exception "in" v:throwpoint
+           finally
+               if !error && $VIMNOERRTHROW && v:errmsg != ""
+                   let error = 1
+                   Xout "2:" v:errmsg
+               endif
+               if error
+                   Xpath 1048576                       " X: 0
+               endif
+               let error = 0
+               let v:errmsg = ""
+               break           " discard error for $VIMNOERRTHROW
+           endtry
+       endwhile
+
+       while 1
+           try
+               Xpath 2097152                           " X: 2097152
+               call {NAME("THROW", 3)}(ARG("call", 3), 3)
+               Xpath 4194304                           " X: 0
+           catch /^call$/
+               Xpath 8388608                           " X: 8388608
+           catch /^0$/     " default return value
+               Xpath 16777216                          " X: 0
+               Xout "3:" v:throwpoint
+           catch /.*/
+               let error = 1
+               Xout "3:" v:exception "in" v:throwpoint
+           finally
+               if !error && $VIMNOERRTHROW && v:errmsg != ""
+                   let error = 1
+                   Xout "3:" v:errmsg
+               endif
+               if error
+                   Xpath 33554432                      " X: 0
+               endif
+               let error = 0
+               let v:errmsg = ""
+               break           " discard error for $VIMNOERRTHROW
            endtry
-       endtry
-    finally
-       if &g:path != saved_gpath || &l:path != saved_lpath
-           Xpath 262144                        " X: 0
-       endif
-       let &g:path = saved_gpath
-       let &l:path = saved_lpath
-    endtry
+       endwhile
 
-    unlet! var1 var2 var3
+       while 1
+           try
+               Xpath 67108864                          " X: 67108864
+               call {NAME("F", 4)}(ARG(4711, 4), 4)
+               Xpath 134217728                         " X: 134217728
+           catch /.*/
+               let error = 1
+               Xout "4:" v:exception "in" v:throwpoint
+           finally
+               if !error && $VIMNOERRTHROW && v:errmsg != ""
+                   let error = 1
+                   Xout "4:" v:errmsg
+               endif
+               if error
+                   Xpath 268435456                     " X: 0
+               endif
+               let error = 0
+               let v:errmsg = ""
+               break           " discard error for $VIMNOERRTHROW
+           endtry
+       endwhile
 
-    try
-       Xpath 524288                            " X: 524288
-       let var1 = "let(" . THROW("var1") . ")"
-       Xpath 1048576                           " X: 0
-    catch /^var1$/
-       Xpath 2097152                           " X: 2097152
+    catch /^0$/            " default return value
+       Xpath 536870912                                 " X: 0
+       Xout v:throwpoint
+    catch /.*/
+       let error = 1
+       Xout v:exception "in" v:throwpoint
     finally
-       if exists("var1")
-           Xpath 4194304                       " X: 0
+       if !error && $VIMNOERRTHROW && v:errmsg != ""
+           let error = 1
+           Xout v:errmsg
        endif
-    endtry
-
-    try
-       let var2 = "old_value"
-       Xpath 8388608                           " X: 8388608
-       let var2 = "let(" . THROW("var2"). ")"
-       Xpath 16777216                          " X: 0
-    catch /^var2$/
-       Xpath 33554432                          " X: 33554432
-    finally
-       if var2 != "old_value"
-           Xpath 67108864                      " X: 0
+       if error
+           Xpath 1073741824                            " X: 0
        endif
+       break           " discard error for $VIMNOERRTHROW
     endtry
+endwhile
 
-    try
-       Xpath 134217728                         " X: 134217728
-       let var{THROW("var3")} = 4711
-       Xpath 268435456                         " X: 0
-    catch /^var3$/
-       Xpath 536870912                         " X: 536870912
-    endtry
-
-    let addpath = ""
-
-    function ADDPATH(p)
-       let g:addpath = g:addpath . a:p
-    endfunction
-
-    try
-       call ADDPATH("T1")
-       let var{THROW("var4")} var{ADDPATH("T2")} | call ADDPATH("T3")
-       call ADDPATH("T4")
-    catch /^var4$/
-       call ADDPATH("T5")
-    endtry
-
-    try
-       call ADDPATH("T6")
-       unlet var{THROW("var5")} var{ADDPATH("T7")} | call ADDPATH("T8")
-       call ADDPATH("T9")
-    catch /^var5$/
-       call ADDPATH("T10")
-    endtry
-
-    if addpath != "T1T5T6T10" || throwcount != 11
-       throw "addpath: " . addpath . ", throwcount: " . throwcount
-    endif
-
-    Xpath 1073741824                           " X: 1073741824
-
-catch /.*/
-    " The Xpath command does not accept 2^31 (negative); add explicitly:
-    let Xpath = Xpath + 2147483648             " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
+unlet error
+delfunction F
 
-unlet! var1 var2 var3 addpath throwcount
-delfunction THROW
+Xcheck 212514423
 
-Xcheck 1789569365
+" Leave THROW(), NAME(), and ARG() for the next test.
 
 
 "-------------------------------------------------------------------------------
-" Test 73:  :throw across :function, :delfunction                          {{{1
+" Test 68:  :throw across function calls in expressions                            {{{1
+"
+"          On a function call within an expression, an exception might be
+"          thrown when evaluating the function name, during evaluation of the
+"          arguments, or when the function is being executed.  The exception
+"          can be caught by the caller.
 "
-"          The :function and :delfunction commands may cause an expression
-"          specified in braces to be evaluated.  During evaluation, an
-"          exception might be thrown.  The exception can be caught by the
-"          script.
+"          This test reuses the functions THROW(), NAME(), and ARG() from the
+"          previous test.
 "-------------------------------------------------------------------------------
 
 XpathINIT
 
-let taken = ""
-
-function! THROW(x, n)
-    let g:taken = g:taken . "T" . a:n
-    throw a:x
-endfunction
-
-function! EXPR(x, n)
-    let g:taken = g:taken . "E" . a:n
-    if a:n % 2 == 0
-       call THROW(a:x, a:n)
+function! F(x, n)
+    if a:n == 2
+       Xpath 2048                                      " X: 0
+    elseif a:n == 4
+       Xpath 4096                                      " X: 4096
     endif
-    return 2 - a:n % 2
+    return a:x
 endfunction
 
-try
-    try
-       " Define function.
-       Xpath 1                                 " X: 1
-       function! F0()
-       endfunction
-       Xpath 2                                 " X: 2
-       function! F{EXPR("function-def-ok", 1)}()
-       endfunction
-       Xpath 4                                 " X: 4
-       function! F{EXPR("function-def", 2)}()
-       endfunction
-       Xpath 8                                 " X: 0
-    catch /^function-def-ok$/
-       Xpath 16                                " X: 0
-    catch /^function-def$/
-       Xpath 32                                " X: 32
-    catch /.*/
-       Xpath 64                                " X: 0
-       Xout "def:" v:exception "in" v:throwpoint
-    endtry
-
-    try
-       " List function.
-       Xpath 128                               " X: 128
-       function F0
-       Xpath 256                               " X: 256
-       function F{EXPR("function-lst-ok", 3)}
-       Xpath 512                               " X: 512
-       function F{EXPR("function-lst", 4)}
-       Xpath 1024                              " X: 0
-    catch /^function-lst-ok$/
-       Xpath 2048                              " X: 0
-    catch /^function-lst$/
-       Xpath 4096                              " X: 4096
-    catch /.*/
-       Xpath 8192                              " X: 0
-       Xout "lst:" v:exception "in" v:throwpoint
-    endtry
+unlet! var1 var2 var3 var4
 
+while 1
     try
-       " Delete function
-       Xpath 16384                             " X: 16384
-       delfunction F0
-       Xpath 32768                             " X: 32768
-       delfunction F{EXPR("function-del-ok", 5)}
-       Xpath 65536                             " X: 65536
-       delfunction F{EXPR("function-del", 6)}
-       Xpath 131072                            " X: 0
-    catch /^function-del-ok$/
-       Xpath 262144                            " X: 0
-    catch /^function-del$/
-       Xpath 524288                            " X: 524288
-    catch /.*/
-       Xpath 1048576                           " X: 0
-       Xout "del:" v:exception "in" v:throwpoint
-    endtry
-
-    let expected = "E1E2T2E3E4T4E5E6T6"
-    if taken != expected
-       Xpath 2097152                           " X: 0
-       Xout "'taken' is" taken "instead of" expected
-    endif
-
-catch /.*/
-    Xpath 4194304                              " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
-
-Xpath 8388608                                  " X: 8388608
-
-unlet taken expected
-delfunction THROW
-delfunction EXPR
-
-Xcheck 9032615
-
-
-"-------------------------------------------------------------------------------
-" Test 74:  :throw across builtin functions and commands                   {{{1
-"
-"          Some functions like exists(), searchpair() take expression
-"          arguments, other functions or commands like substitute() or
-"          :substitute cause an expression (specified in the regular
-"          expression) to be evaluated.  During evaluation an exception
-"          might be thrown.  The exception can be caught by the script.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-let taken = ""
-
-function! THROW(x, n)
-    let g:taken = g:taken . "T" . a:n
-    throw a:x
-endfunction
-
-function! EXPR(x, n)
-    let g:taken = g:taken . "E" . a:n
-    call THROW(a:x . a:n, a:n)
-    return "EXPR"
-endfunction
-
-function! SKIP(x, n)
-    let g:taken = g:taken . "S" . a:n . "(" . line(".")
-    let theline = getline(".")
-    if theline =~ "skip"
-       let g:taken = g:taken . "s)"
-       return 1
-    elseif theline =~ "throw"
-       let g:taken = g:taken . "t)"
-       call THROW(a:x . a:n, a:n)
-    else
-       let g:taken = g:taken . ")"
-       return 0
-    endif
-endfunction
+       let error = 0
+       let v:errmsg = ""
 
-function! SUBST(x, n)
-    let g:taken = g:taken . "U" . a:n . "(" . line(".")
-    let theline = getline(".")
-    if theline =~ "not"            " SUBST() should not be called for this line
-       let g:taken = g:taken . "n)"
-       call THROW(a:x . a:n, a:n)
-    elseif theline =~ "throw"
-       let g:taken = g:taken . "t)"
-       call THROW(a:x . a:n, a:n)
-    else
-       let g:taken = g:taken . ")"
-       return "replaced"
-    endif
-endfunction
+       while 1
+           try
+               Xpath 8192                              " X: 8192
+               let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
+               Xpath 16384                             " X: 0
+           catch /^name$/
+               Xpath 32768                             " X: 32768
+           catch /.*/
+               let error = 1
+               Xout "1:" v:exception "in" v:throwpoint
+           finally
+               if !error && $VIMNOERRTHROW && v:errmsg != ""
+                   let error = 1
+                   Xout "1:" v:errmsg
+               endif
+               if error
+                   Xpath 65536                         " X: 0
+               endif
+               let error = 0
+               let v:errmsg = ""
+               break           " discard error for $VIMNOERRTHROW
+           endtry
+       endwhile
 
-try
-    try
-       Xpath 1                                 " X: 1
-       let result = exists('*{EXPR("exists", 1)}')
-       Xpath 2                                 " X: 0
-    catch /^exists1$/
-       Xpath 4                                 " X: 4
-       try
-           let result = exists('{EXPR("exists", 2)}')
-           Xpath 8                             " X: 0
-       catch /^exists2$/
-           Xpath 16                            " X: 16
-       catch /.*/
-           Xpath 32                            " X: 0
-           Xout "exists2:" v:exception "in" v:throwpoint
-       endtry
-    catch /.*/
-       Xpath 64                                " X: 0
-       Xout "exists1:" v:exception "in" v:throwpoint
-    endtry
+       while 1
+           try
+               Xpath 131072                            " X: 131072
+               let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
+               Xpath 262144                            " X: 0
+           catch /^arg$/
+               Xpath 524288                            " X: 524288
+           catch /.*/
+               let error = 1
+               Xout "2:" v:exception "in" v:throwpoint
+           finally
+               if !error && $VIMNOERRTHROW && v:errmsg != ""
+                   let error = 1
+                   Xout "2:" v:errmsg
+               endif
+               if error
+                   Xpath 1048576                       " X: 0
+               endif
+               let error = 0
+               let v:errmsg = ""
+               break           " discard error for $VIMNOERRTHROW
+           endtry
+       endwhile
 
-    try
-       let file = tempname()
-       exec "edit" file
-       insert
-begin
-    xx
-middle 3
-    xx
-middle 5 skip
-    xx
-middle 7 throw
-    xx
-end
-.
-       normal! gg
-       Xpath 128                               " X: 128
-       let result =
-           \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 3)')
-       Xpath 256                               " X: 256
-       let result =
-           \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 4)')
-       Xpath 512                               " X: 0
-       let result =
-           \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 5)')
-       Xpath 1024                              " X: 0
-    catch /^searchpair[35]$/
-       Xpath 2048                              " X: 0
-    catch /^searchpair4$/
-       Xpath 4096                              " X: 4096
-    catch /.*/
-       Xpath 8192                              " X: 0
-       Xout "searchpair:" v:exception "in" v:throwpoint
-    finally
-       bwipeout!
-       call delete(file)
-    endtry
+       while 1
+           try
+               Xpath 2097152                           " X: 2097152
+               let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3)
+               Xpath 4194304                           " X: 0
+           catch /^call$/
+               Xpath 8388608                           " X: 8388608
+           catch /^0$/     " default return value
+               Xpath 16777216                          " X: 0
+               Xout "3:" v:throwpoint
+           catch /.*/
+               let error = 1
+               Xout "3:" v:exception "in" v:throwpoint
+           finally
+               if !error && $VIMNOERRTHROW && v:errmsg != ""
+                   let error = 1
+                   Xout "3:" v:errmsg
+               endif
+               if error
+                   Xpath 33554432                      " X: 0
+               endif
+               let error = 0
+               let v:errmsg = ""
+               break           " discard error for $VIMNOERRTHROW
+           endtry
+       endwhile
 
-    try
-       let file = tempname()
-       exec "edit" file
-       insert
-subst 1
-subst 2
-not
-subst 4
-subst throw
-subst 6
-.
-       normal! gg
-       Xpath 16384                             " X: 16384
-       1,2substitute/subst/\=SUBST("substitute", 6)/
-       try
-           Xpath 32768                         " X: 32768
+       while 1
            try
-               let v:errmsg = ""
-               3substitute/subst/\=SUBST("substitute", 7)/
+               Xpath 67108864                          " X: 67108864
+               let var4 = {NAME("F", 4)}(ARG(4711, 4), 4)
+               Xpath 134217728                         " X: 134217728
+           catch /.*/
+               let error = 1
+               Xout "4:" v:exception "in" v:throwpoint
            finally
-               if v:errmsg != ""
-                   " If exceptions are not thrown on errors, fake the error
-                   " exception in order to get the same execution path.
-                   throw "faked Vim(substitute)"
+               if !error && $VIMNOERRTHROW && v:errmsg != ""
+                   let error = 1
+                   Xout "4:" v:errmsg
+               endif
+               if error
+                   Xpath 268435456                     " X: 0
                endif
+               let error = 0
+               let v:errmsg = ""
+               break           " discard error for $VIMNOERRTHROW
            endtry
-       catch /Vim(substitute)/     " Pattern not found ('e' flag missing)
-           Xpath 65536                         " X: 65536
-           3substitute/subst/\=SUBST("substitute", 8)/e
-           Xpath 131072                        " X: 131072
-       endtry
-       Xpath 262144                            " X: 262144
-       4,6substitute/subst/\=SUBST("substitute", 9)/
-       Xpath 524288                            " X: 0
-    catch /^substitute[678]/
-       Xpath 1048576                           " X: 0
-    catch /^substitute9/
-       Xpath 2097152                           " X: 2097152
-    finally
-       bwipeout!
-       call delete(file)
-    endtry
-
-    try
-       Xpath 4194304                           " X: 4194304
-       let var = substitute("sub", "sub", '\=THROW("substitute()y", 10)', '')
-       Xpath 8388608                           " X: 0
-    catch /substitute()y/
-       Xpath 16777216                          " X: 16777216
-    catch /.*/
-       Xpath 33554432                          " X: 0
-       Xout "substitute()y:" v:exception "in" v:throwpoint
-    endtry
+       endwhile
 
-    try
-       Xpath 67108864                          " X: 67108864
-       let var = substitute("not", "sub", '\=THROW("substitute()n", 11)', '')
-       Xpath 134217728                         " X: 134217728
-    catch /substitute()n/
-       Xpath 268435456                         " X: 0
+    catch /^0$/            " default return value
+       Xpath 536870912                                 " X: 0
+       Xout v:throwpoint
     catch /.*/
-       Xpath 536870912                         " X: 0
-       Xout "substitute()n:" v:exception "in" v:throwpoint
+       let error = 1
+       Xout v:exception "in" v:throwpoint
+    finally
+       if !error && $VIMNOERRTHROW && v:errmsg != ""
+           let error = 1
+           Xout v:errmsg
+       endif
+       if error
+           Xpath 1073741824                            " X: 0
+       endif
+       break           " discard error for $VIMNOERRTHROW
     endtry
+endwhile
 
-    let expected = "E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10"
-    if taken != expected
-       Xpath 1073741824                        " X: 0
-       Xout "'taken' is" taken "instead of" expected
-    endif
-
-catch /.*/
+if exists("var1") || exists("var2") || exists("var3") ||
+           \ !exists("var4") || var4 != 4711
     " The Xpath command does not accept 2^31 (negative); add explicitly:
-    let Xpath = Xpath + 2147483648             " X: 0
-    Xout v:exception "in" v:throwpoint
-endtry
+    let Xpath = Xpath + 2147483648                     " X: 0
+    if exists("var1")
+       Xout "var1 =" var1
+    endif
+    if exists("var2")
+       Xout "var2 =" var2
+    endif
+    if exists("var3")
+       Xout "var3 =" var3
+    endif
+    if !exists("var4")
+       Xout "var4 unset"
+    elseif var4 != 4711
+       Xout "var4 =" var4
+    endif
+endif
 
-unlet result var taken expected
+unlet! error var1 var2 var3 var4
 delfunction THROW
-delfunction EXPR
-delfunction SKIP
-delfunction SUBST
-
-Xcheck 224907669
-
-
-"-------------------------------------------------------------------------------
-" Test 75:  Errors in builtin functions.                                   {{{1
-"
-"          On an error in a builtin function called inside a :try/:endtry
-"          region, the evaluation of the expression calling that function and
-"          the command containing that expression are abandoned.  The error can
-"          be caught as an exception.
-"
-"          A simple :call of the builtin function is a trivial case.  If the
-"          builtin function is called in the argument list of another function,
-"          no further arguments are evaluated, and the other function is not
-"          executed.  If the builtin function is called from the argument of
-"          a :return command, the :return command is not executed.  If the
-"          builtin function is called from the argument of a :throw command,
-"          the :throw command is not executed.  The evaluation of the
-"          expression calling the builtin function is abandoned.
-"-------------------------------------------------------------------------------
-
-XpathINIT
-
-function! F1(arg1)
-    Xpath 1                                    " X: 0
-endfunction
-
-function! F2(arg1, arg2)
-    Xpath 2                                    " X: 0
-endfunction
-
-function! G()
-    Xpath 4                                    " X: 0
-endfunction
-
-function! H()
-    Xpath 8                                    " X: 0
-endfunction
-
-function! R()
-    while 1
-       try
-           let caught = 0
-           let v:errmsg = ""
-           Xpath 16                            " X: 16
-           return append(1, "s")
-       catch /E21/
-           let caught = 1
-       catch /.*/
-           Xpath 32                            " X: 0
-       finally
-           Xpath 64                            " X: 64
-           if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
-               Xpath 128                       " X: 128
-           endif
-           break               " discard error for $VIMNOERRTHROW
-       endtry
-    endwhile
-    Xpath 256                                  " X: 256
-endfunction
-
-try
-    set noma   " let append() fail with "E21"
-
-    while 1
-       try
-           let caught = 0
-           let v:errmsg = ""
-           Xpath 512                           " X: 512
-           call append(1, "s")
-       catch /E21/
-           let caught = 1
-       catch /.*/
-           Xpath 1024                          " X: 0
-       finally
-           Xpath 2048                          " X: 2048
-           if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
-               Xpath 4096                      " X: 4096
-           endif
-           break               " discard error for $VIMNOERRTHROW
-       endtry
-    endwhile
-
-    while 1
-       try
-           let caught = 0
-           let v:errmsg = ""
-           Xpath 8192                          " X: 8192
-           call F1('x' . append(1, "s"))
-       catch /E21/
-           let caught = 1
-       catch /.*/
-           Xpath 16384                         " X: 0
-       finally
-           Xpath 32768                         " X: 32768
-           if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
-               Xpath 65536                     " X: 65536
-           endif
-           break               " discard error for $VIMNOERRTHROW
-       endtry
-    endwhile
-
-    while 1
-       try
-           let caught = 0
-           let v:errmsg = ""
-           Xpath 131072                        " X: 131072
-           call F2('x' . append(1, "s"), G())
-       catch /E21/
-           let caught = 1
-       catch /.*/
-           Xpath 262144                        " X: 0
-       finally
-           Xpath 524288                        " X: 524288
-           if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
-               Xpath 1048576                   " X: 1048576
-           endif
-           break               " discard error for $VIMNOERRTHROW
-       endtry
-    endwhile
-
-    call R()
-
-    while 1
-       try
-           let caught = 0
-           let v:errmsg = ""
-           Xpath 2097152                       " X: 2097152
-           throw "T" . append(1, "s")
-       catch /E21/
-           let caught = 1
-       catch /^T.*/
-           Xpath 4194304                       " X: 0
-       catch /.*/
-           Xpath 8388608                       " X: 0
-       finally
-           Xpath 16777216                      " X: 16777216
-           if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
-               Xpath 33554432                  " X: 33554432
-           endif
-           break               " discard error for $VIMNOERRTHROW
-       endtry
-    endwhile
-
-    while 1
-       try
-           let caught = 0
-           let v:errmsg = ""
-           Xpath 67108864                      " X: 67108864
-           let x = "a"
-           let x = x . "b" . append(1, "s") . H()
-       catch /E21/
-           let caught = 1
-       catch /.*/
-           Xpath 134217728                     " X: 0
-       finally
-           Xpath 268435456                     " X: 268435456
-           if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
-               Xpath 536870912                 " X: 536870912
-           endif
-           if x == "a"
-               Xpath 1073741824                " X: 1073741824
-           endif
-           break               " discard error for $VIMNOERRTHROW
-       endtry
-    endwhile
-catch /.*/
-    " The Xpath command does not accept 2^31 (negative); add explicitly:
-    let Xpath = Xpath + 2147483648             " X: 0
-    Xout v:exception "in" v:throwpoint
-finally
-    set ma&
-endtry
+delfunction NAME
+delfunction ARG
+delfunction F
 
-unlet! caught x
-delfunction F1
-delfunction F2
-delfunction G
-delfunction H
-delfunction R
+Xcheck 212514423
 
-Xcheck 2000403408
+" Tests 69 to 75 were moved to test_trycatch.vim
+let Xtest = 76
 
 
 "-------------------------------------------------------------------------------
@@ -8780,36 +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)
+" Test 87 was moved to test_vimscript.vim
+let Xtest = 88
 
-Xout 1 ? function('Add2')(1,2) : function('Add2')(2,3)
-Xout 0 ? function('Add2')(1,2) : function('Add2')(2,3)
-" Make sure, GetStr() still works.
-Xout GetStr()[0:10]
-
-
-delfunction GetStr
-delfunction Add2
-Xout  "Successfully executed funcref Add2"
-
-Xcheck 0 
 
 "-------------------------------------------------------------------------------
 " Test 88:  $VIMNOERRTHROW and $VIMNOINTTHROW support                      {{{1
diff --git a/src/testdir/test_trycatch.vim b/src/testdir/test_trycatch.vim
new file mode 100644 (file)
index 0000000..7e51318
--- /dev/null
@@ -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
+"-------------------------------------------------------------------------------
index 18790d24ca09c63ed2150f250f0833203b7fb900..f1f6fd0b87a38fc581a94c9d0bcbcca5db1fbc63 100644 (file)
@@ -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
 "-------------------------------------------------------------------------------
index d7c8c8b430fb73f216b91f2c1178e0974ecf1fd3..5089d7d8b75861ae680da07b34b5d391cd2c34f1 100644 (file)
@@ -741,6 +741,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2246,
 /**/
     2245,
 /**/