11f068233SBram Moolenaar" Test try-catch-finally exception handling
21f068233SBram Moolenaar" Most of this was formerly in test49.
31f068233SBram Moolenaar
41f068233SBram Moolenaarsource check.vim
51f068233SBram Moolenaarsource shared.vim
61f068233SBram Moolenaar
71f068233SBram Moolenaar"-------------------------------------------------------------------------------
81f068233SBram Moolenaar" Test environment							    {{{1
91f068233SBram Moolenaar"-------------------------------------------------------------------------------
101f068233SBram Moolenaar
111f068233SBram Moolenaarcom!		   XpathINIT  let g:Xpath = ''
121f068233SBram Moolenaarcom! -nargs=1 -bar Xpath      let g:Xpath = g:Xpath . <args>
131f068233SBram Moolenaar
141f068233SBram Moolenaar" Test 25:  Executing :finally clauses on normal control flow		    {{{1
151f068233SBram Moolenaar"
161f068233SBram Moolenaar"	    Control flow in a :try conditional should always fall through to its
171f068233SBram Moolenaar"	    :finally clause.  A :finally clause of a :try conditional inside an
181f068233SBram Moolenaar"	    inactive conditional should never be executed.
191f068233SBram Moolenaar"-------------------------------------------------------------------------------
201f068233SBram Moolenaar
211f068233SBram Moolenaarfunc T25_F()
221f068233SBram Moolenaar  let loops = 3
231f068233SBram Moolenaar  while loops > 0
241f068233SBram Moolenaar    Xpath 'a' . loops
251f068233SBram Moolenaar    if loops >= 2
261f068233SBram Moolenaar      try
271f068233SBram Moolenaar        Xpath 'b' . loops
281f068233SBram Moolenaar        if loops == 2
291f068233SBram Moolenaar          try
301f068233SBram Moolenaar            Xpath 'c' . loops
311f068233SBram Moolenaar          finally
321f068233SBram Moolenaar            Xpath 'd' . loops
331f068233SBram Moolenaar          endtry
341f068233SBram Moolenaar        endif
351f068233SBram Moolenaar      finally
361f068233SBram Moolenaar        Xpath 'e' . loops
371f068233SBram Moolenaar        if loops == 2
381f068233SBram Moolenaar          try
391f068233SBram Moolenaar            Xpath 'f' . loops
40373863edSBram Moolenaar          final
411f068233SBram Moolenaar            Xpath 'g' . loops
421f068233SBram Moolenaar          endtry
431f068233SBram Moolenaar        endif
441f068233SBram Moolenaar      endtry
451f068233SBram Moolenaar    endif
461f068233SBram Moolenaar    Xpath 'h' . loops
471f068233SBram Moolenaar    let loops = loops - 1
481f068233SBram Moolenaar  endwhile
491f068233SBram Moolenaar  Xpath 'i'
501f068233SBram Moolenaarendfunc
511f068233SBram Moolenaar
52373863edSBram Moolenaar" Also try using "fina" and "final" and "finall" as abbraviations.
531f068233SBram Moolenaarfunc T25_G()
541f068233SBram Moolenaar  if 1
551f068233SBram Moolenaar    try
561f068233SBram Moolenaar      Xpath 'A'
571f068233SBram Moolenaar      call T25_F()
581f068233SBram Moolenaar      Xpath 'B'
59373863edSBram Moolenaar    fina
601f068233SBram Moolenaar      Xpath 'C'
611f068233SBram Moolenaar    endtry
621f068233SBram Moolenaar  else
631f068233SBram Moolenaar    try
641f068233SBram Moolenaar      Xpath 'D'
65373863edSBram Moolenaar    finall
661f068233SBram Moolenaar      Xpath 'E'
671f068233SBram Moolenaar    endtry
681f068233SBram Moolenaar  endif
691f068233SBram Moolenaarendfunc
701f068233SBram Moolenaar
711f068233SBram Moolenaarfunc Test_finally()
721f068233SBram Moolenaar  XpathINIT
731f068233SBram Moolenaar  call T25_G()
741f068233SBram Moolenaar  call assert_equal('Aa3b3e3h3a2b2c2d2e2f2g2h2a1h1iBC', g:Xpath)
751f068233SBram Moolenaarendfunc
761f068233SBram Moolenaar
771f068233SBram Moolenaar
781f068233SBram Moolenaar"-------------------------------------------------------------------------------
791f068233SBram Moolenaar" Test 26:  Executing :finally clauses after :continue or :break	    {{{1
801f068233SBram Moolenaar"
811f068233SBram Moolenaar"	    For a :continue or :break dynamically enclosed in a :try/:endtry
821f068233SBram Moolenaar"	    region inside the next surrounding :while/:endwhile, if the
831f068233SBram Moolenaar"	    :continue/:break is before the :finally, the :finally clause is
841f068233SBram Moolenaar"	    executed first.  If the :continue/:break is after the :finally, the
851f068233SBram Moolenaar"	    :finally clause is broken (like an :if/:endif region).
861f068233SBram Moolenaar"-------------------------------------------------------------------------------
871f068233SBram Moolenaar
881f068233SBram Moolenaarfunc T26_F()
891f068233SBram Moolenaar  try
901f068233SBram Moolenaar    let loops = 3
911f068233SBram Moolenaar    while loops > 0
921f068233SBram Moolenaar      try
931f068233SBram Moolenaar        try
941f068233SBram Moolenaar          if loops == 2
951f068233SBram Moolenaar            Xpath 'a' . loops
961f068233SBram Moolenaar            let loops = loops - 1
971f068233SBram Moolenaar            continue
981f068233SBram Moolenaar          elseif loops == 1
991f068233SBram Moolenaar            Xpath 'b' . loops
1001f068233SBram Moolenaar            break
1011f068233SBram Moolenaar            finish
1021f068233SBram Moolenaar          endif
1031f068233SBram Moolenaar          Xpath 'c' . loops
1041f068233SBram Moolenaar        endtry
1051f068233SBram Moolenaar      finally
1061f068233SBram Moolenaar        Xpath 'd' . loops
1071f068233SBram Moolenaar      endtry
1081f068233SBram Moolenaar      Xpath 'e' . loops
1091f068233SBram Moolenaar      let loops = loops - 1
1101f068233SBram Moolenaar    endwhile
1111f068233SBram Moolenaar    Xpath 'f'
1121f068233SBram Moolenaar  finally
1131f068233SBram Moolenaar    Xpath 'g'
1141f068233SBram Moolenaar    let loops = 3
1151f068233SBram Moolenaar    while loops > 0
1161f068233SBram Moolenaar      try
1171f068233SBram Moolenaar      finally
1181f068233SBram Moolenaar        try
1191f068233SBram Moolenaar          if loops == 2
1201f068233SBram Moolenaar            Xpath 'h' . loops
1211f068233SBram Moolenaar            let loops = loops - 1
1221f068233SBram Moolenaar            continue
1231f068233SBram Moolenaar          elseif loops == 1
1241f068233SBram Moolenaar            Xpath 'i' . loops
1251f068233SBram Moolenaar            break
1261f068233SBram Moolenaar            finish
1271f068233SBram Moolenaar          endif
1281f068233SBram Moolenaar        endtry
1291f068233SBram Moolenaar        Xpath 'j' . loops
1301f068233SBram Moolenaar      endtry
1311f068233SBram Moolenaar      Xpath 'k' . loops
1321f068233SBram Moolenaar      let loops = loops - 1
1331f068233SBram Moolenaar    endwhile
1341f068233SBram Moolenaar    Xpath 'l'
1351f068233SBram Moolenaar  endtry
1361f068233SBram Moolenaar  Xpath 'm'
1371f068233SBram Moolenaarendfunc
1381f068233SBram Moolenaar
1391f068233SBram Moolenaarfunc Test_finally_after_continue()
1401f068233SBram Moolenaar  XpathINIT
1411f068233SBram Moolenaar  call T26_F()
1421f068233SBram Moolenaar  call assert_equal('c3d3e3a2d1b1d1fgj3k3h2i1lm', g:Xpath)
1431f068233SBram Moolenaarendfunc
1441f068233SBram Moolenaar
1451f068233SBram Moolenaar
1461f068233SBram Moolenaar"-------------------------------------------------------------------------------
1471f068233SBram Moolenaar" Test 32:  Remembering the :return value on :finally			    {{{1
1481f068233SBram Moolenaar"
1491f068233SBram Moolenaar"	    If a :finally clause is executed due to a :return specifying
1501f068233SBram Moolenaar"	    a value, this is the value visible to the caller if not overwritten
1511f068233SBram Moolenaar"	    by a new :return in the :finally clause.  A :return without a value
1521f068233SBram Moolenaar"	    in the :finally clause overwrites with value 0.
1531f068233SBram Moolenaar"-------------------------------------------------------------------------------
1541f068233SBram Moolenaar
1551f068233SBram Moolenaarfunc T32_F()
1561f068233SBram Moolenaar  try
1571f068233SBram Moolenaar    Xpath 'a'
1581f068233SBram Moolenaar    try
1591f068233SBram Moolenaar      Xpath 'b'
1601f068233SBram Moolenaar      return "ABCD"
1611f068233SBram Moolenaar      Xpath 'c'
1621f068233SBram Moolenaar    finally
1631f068233SBram Moolenaar      Xpath 'd'
1641f068233SBram Moolenaar    endtry
1651f068233SBram Moolenaar    Xpath 'e'
1661f068233SBram Moolenaar  finally
1671f068233SBram Moolenaar    Xpath 'f'
1681f068233SBram Moolenaar  endtry
1691f068233SBram Moolenaar  Xpath 'g'
1701f068233SBram Moolenaarendfunc
1711f068233SBram Moolenaar
1721f068233SBram Moolenaarfunc T32_G()
1731f068233SBram Moolenaar  try
1741f068233SBram Moolenaar    Xpath 'h'
1751f068233SBram Moolenaar    return 8
1761f068233SBram Moolenaar    Xpath 'i'
1771f068233SBram Moolenaar  finally
1781f068233SBram Moolenaar    Xpath 'j'
1791f068233SBram Moolenaar    return 16 + strlen(T32_F())
1801f068233SBram Moolenaar    Xpath 'k'
1811f068233SBram Moolenaar  endtry
1821f068233SBram Moolenaar  Xpath 'l'
1831f068233SBram Moolenaarendfunc
1841f068233SBram Moolenaar
1851f068233SBram Moolenaarfunc T32_H()
1861f068233SBram Moolenaar  try
1871f068233SBram Moolenaar    Xpath 'm'
1881f068233SBram Moolenaar    return 32
1891f068233SBram Moolenaar    Xpath 'n'
1901f068233SBram Moolenaar  finally
1911f068233SBram Moolenaar    Xpath 'o'
1921f068233SBram Moolenaar    return
1931f068233SBram Moolenaar    Xpath 'p'
1941f068233SBram Moolenaar  endtry
1951f068233SBram Moolenaar  Xpath 'q'
1961f068233SBram Moolenaarendfunc
1971f068233SBram Moolenaar
1981f068233SBram Moolenaarfunc T32_I()
1991f068233SBram Moolenaar  try
2001f068233SBram Moolenaar    Xpath 'r'
2011f068233SBram Moolenaar  finally
2021f068233SBram Moolenaar    Xpath 's'
2031f068233SBram Moolenaar    return T32_G() + T32_H() + 64
2041f068233SBram Moolenaar    Xpath 't'
2051f068233SBram Moolenaar  endtry
2061f068233SBram Moolenaar  Xpath 'u'
2071f068233SBram Moolenaarendfunc
2081f068233SBram Moolenaar
2091f068233SBram Moolenaarfunc Test_finally_return()
2101f068233SBram Moolenaar  XpathINIT
2111f068233SBram Moolenaar  call assert_equal(84, T32_I())
2121f068233SBram Moolenaar  call assert_equal('rshjabdfmo', g:Xpath)
2131f068233SBram Moolenaarendfunc
2141f068233SBram Moolenaar
2151f068233SBram Moolenaar"-------------------------------------------------------------------------------
2161f068233SBram Moolenaar" Test 33:  :return under :execute or user command and :finally		    {{{1
2171f068233SBram Moolenaar"
2181f068233SBram Moolenaar"	    A :return command may be executed under an ":execute" or from
2191f068233SBram Moolenaar"	    a user command.  Executing of :finally clauses and passing through
2201f068233SBram Moolenaar"	    the return code works also then.
2211f068233SBram Moolenaar"-------------------------------------------------------------------------------
2221f068233SBram Moolenaar
2231f068233SBram Moolenaarfunc T33_F()
2241f068233SBram Moolenaar  try
2251f068233SBram Moolenaar    RETURN 10
2261f068233SBram Moolenaar    Xpath 'a'
2271f068233SBram Moolenaar  finally
2281f068233SBram Moolenaar    Xpath 'b'
2291f068233SBram Moolenaar  endtry
2301f068233SBram Moolenaar  Xpath 'c'
2311f068233SBram Moolenaarendfunc
2321f068233SBram Moolenaar
2331f068233SBram Moolenaarfunc T33_G()
2341f068233SBram Moolenaar  try
2351f068233SBram Moolenaar    RETURN 20
2361f068233SBram Moolenaar    Xpath 'd'
2371f068233SBram Moolenaar  finally
2381f068233SBram Moolenaar    Xpath 'e'
2391f068233SBram Moolenaar    RETURN 30
2401f068233SBram Moolenaar    Xpath 'f'
2411f068233SBram Moolenaar  endtry
2421f068233SBram Moolenaar  Xpath 'g'
2431f068233SBram Moolenaarendfunc
2441f068233SBram Moolenaar
2451f068233SBram Moolenaarfunc T33_H()
2461f068233SBram Moolenaar  try
2471f068233SBram Moolenaar    execute "try | return 40 | finally | return 50 | endtry"
2481f068233SBram Moolenaar    Xpath 'h'
2491f068233SBram Moolenaar  finally
2501f068233SBram Moolenaar    Xpath 'i'
2511f068233SBram Moolenaar  endtry
2521f068233SBram Moolenaar  Xpath 'j'
2531f068233SBram Moolenaarendfunc
2541f068233SBram Moolenaar
2551f068233SBram Moolenaarfunc T33_I()
2561f068233SBram Moolenaar  try
2571f068233SBram Moolenaar    execute "try | return 60 | finally | return 70 | endtry"
2581f068233SBram Moolenaar    Xpath 'k'
2591f068233SBram Moolenaar  finally
2601f068233SBram Moolenaar    Xpath 'l'
2611f068233SBram Moolenaar    execute "try | return 80 | finally | return 90 | endtry"
2621f068233SBram Moolenaar    Xpath 'm'
2631f068233SBram Moolenaar  endtry
2641f068233SBram Moolenaar  Xpath 'n'
2651f068233SBram Moolenaarendfunc
2661f068233SBram Moolenaar
2671f068233SBram Moolenaarfunc T33_J()
2681f068233SBram Moolenaar  try
2691f068233SBram Moolenaar    RETURN 100
2701f068233SBram Moolenaar    Xpath 'o'
2711f068233SBram Moolenaar  finally
2721f068233SBram Moolenaar    Xpath 'p'
2731f068233SBram Moolenaar    return
2741f068233SBram Moolenaar    Xpath 'q'
2751f068233SBram Moolenaar  endtry
2761f068233SBram Moolenaar  Xpath 'r'
2771f068233SBram Moolenaarendfunc
2781f068233SBram Moolenaar
2791f068233SBram Moolenaarfunc T33_K()
2801f068233SBram Moolenaar  try
2811f068233SBram Moolenaar    execute "try | return 110 | finally | return 120 | endtry"
2821f068233SBram Moolenaar    Xpath 's'
2831f068233SBram Moolenaar  finally
2841f068233SBram Moolenaar    Xpath 't'
2851f068233SBram Moolenaar    execute "try | return 130 | finally | return | endtry"
2861f068233SBram Moolenaar    Xpath 'u'
2871f068233SBram Moolenaar  endtry
2881f068233SBram Moolenaar  Xpath 'v'
2891f068233SBram Moolenaarendfunc
2901f068233SBram Moolenaar
2911f068233SBram Moolenaarfunc T33_L()
2921f068233SBram Moolenaar  try
2931f068233SBram Moolenaar    return
2941f068233SBram Moolenaar    Xpath 'w'
2951f068233SBram Moolenaar  finally
2961f068233SBram Moolenaar    Xpath 'x'
2971f068233SBram Moolenaar    RETURN 140
2981f068233SBram Moolenaar    Xpath 'y'
2991f068233SBram Moolenaar  endtry
3001f068233SBram Moolenaar  Xpath 'z'
3011f068233SBram Moolenaarendfunc
3021f068233SBram Moolenaar
3031f068233SBram Moolenaarfunc T33_M()
3041f068233SBram Moolenaar  try
3051f068233SBram Moolenaar    return
3061f068233SBram Moolenaar    Xpath 'A'
3071f068233SBram Moolenaar  finally
3081f068233SBram Moolenaar    Xpath 'B'
3091f068233SBram Moolenaar    execute "try | return 150 | finally | return 160 | endtry"
3101f068233SBram Moolenaar    Xpath 'C'
3111f068233SBram Moolenaar  endtry
3121f068233SBram Moolenaar  Xpath 'D'
3131f068233SBram Moolenaarendfunc
3141f068233SBram Moolenaar
3151f068233SBram Moolenaarfunc T33_N()
3161f068233SBram Moolenaar  RETURN 170
3171f068233SBram Moolenaarendfunc
3181f068233SBram Moolenaar
3191f068233SBram Moolenaarfunc T33_O()
3201f068233SBram Moolenaar  execute "try | return 180 | finally | return 190 | endtry"
3211f068233SBram Moolenaarendfunc
3221f068233SBram Moolenaar
3231f068233SBram Moolenaarfunc Test_finally_cmd_return()
3241f068233SBram Moolenaar  command! -nargs=? RETURN
3251f068233SBram Moolenaar        \ try | return <args> | finally | return <args> * 2 | endtry
3261f068233SBram Moolenaar  XpathINIT
3271f068233SBram Moolenaar  call assert_equal(20, T33_F())
3281f068233SBram Moolenaar  call assert_equal(60, T33_G())
3291f068233SBram Moolenaar  call assert_equal(50, T33_H())
3301f068233SBram Moolenaar  call assert_equal(90, T33_I())
3311f068233SBram Moolenaar  call assert_equal(0, T33_J())
3321f068233SBram Moolenaar  call assert_equal(0, T33_K())
3331f068233SBram Moolenaar  call assert_equal(280, T33_L())
3341f068233SBram Moolenaar  call assert_equal(160, T33_M())
3351f068233SBram Moolenaar  call assert_equal(340, T33_N())
3361f068233SBram Moolenaar  call assert_equal(190, T33_O())
3371f068233SBram Moolenaar  call assert_equal('beilptxB', g:Xpath)
3381f068233SBram Moolenaar  delcommand RETURN
3391f068233SBram Moolenaarendfunc
3401f068233SBram Moolenaar
3411f068233SBram Moolenaar
3421f068233SBram Moolenaar"-------------------------------------------------------------------------------
3431f068233SBram Moolenaar" Test 41:  Skipped :throw finding next command				    {{{1
3441f068233SBram Moolenaar"
3451f068233SBram Moolenaar"	    A :throw in an inactive conditional must not hide a following
3461f068233SBram Moolenaar"	    command.
3471f068233SBram Moolenaar"-------------------------------------------------------------------------------
3481f068233SBram Moolenaar
3491f068233SBram Moolenaarfunc T41_F()
3501f068233SBram Moolenaar  Xpath 'a'
3511f068233SBram Moolenaar  if 0 | throw 'never' | endif | Xpath 'b'
3521f068233SBram Moolenaar  Xpath 'c'
3531f068233SBram Moolenaarendfunc
3541f068233SBram Moolenaar
3551f068233SBram Moolenaarfunc T41_G()
3561f068233SBram Moolenaar  Xpath 'd'
3571f068233SBram Moolenaar  while 0 | throw 'never' | endwhile | Xpath 'e'
3581f068233SBram Moolenaar  Xpath 'f'
3591f068233SBram Moolenaarendfunc
3601f068233SBram Moolenaar
3611f068233SBram Moolenaarfunc T41_H()
3621f068233SBram Moolenaar  Xpath 'g'
3631f068233SBram Moolenaar  if 0 | try | throw 'never' | endtry | endif | Xpath 'h'
3641f068233SBram Moolenaar  Xpath 'i'
3651f068233SBram Moolenaarendfunc
3661f068233SBram Moolenaar
3671f068233SBram Moolenaarfunc Test_throw_inactive_cond()
3681f068233SBram Moolenaar  XpathINIT
3691f068233SBram Moolenaar  try
3701f068233SBram Moolenaar    Xpath 'j'
3711f068233SBram Moolenaar    call T41_F()
3721f068233SBram Moolenaar    Xpath 'k'
3731f068233SBram Moolenaar  catch /.*/
3741f068233SBram Moolenaar    Xpath 'l'
3751f068233SBram Moolenaar    call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
3761f068233SBram Moolenaar  endtry
3771f068233SBram Moolenaar
3781f068233SBram Moolenaar  try
3791f068233SBram Moolenaar    Xpath 'm'
3801f068233SBram Moolenaar    call T41_G()
3811f068233SBram Moolenaar    Xpath 'n'
3821f068233SBram Moolenaar  catch /.*/
3831f068233SBram Moolenaar    Xpath 'o'
3841f068233SBram Moolenaar    call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
3851f068233SBram Moolenaar  endtry
3861f068233SBram Moolenaar
3871f068233SBram Moolenaar  try
3881f068233SBram Moolenaar    Xpath 'p'
3891f068233SBram Moolenaar    call T41_H()
3901f068233SBram Moolenaar    Xpath 'q'
3911f068233SBram Moolenaar  catch /.*/
3921f068233SBram Moolenaar    Xpath 'r'
3931f068233SBram Moolenaar    call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
3941f068233SBram Moolenaar  endtry
3951f068233SBram Moolenaar
3961f068233SBram Moolenaar  call assert_equal('jabckmdefnpghiq', g:Xpath)
3971f068233SBram Moolenaarendfunc
3981f068233SBram Moolenaar
3991f068233SBram Moolenaar
4001f068233SBram Moolenaar"-------------------------------------------------------------------------------
4011f068233SBram Moolenaar" Test 42:  Catching number and string exceptions			    {{{1
4021f068233SBram Moolenaar"
4031f068233SBram Moolenaar"	    When a number is thrown, it is converted to a string exception.
4041f068233SBram Moolenaar"	    Numbers and strings may be caught by specifying a regular exception
4051f068233SBram Moolenaar"	    as argument to the :catch command.
4061f068233SBram Moolenaar"-------------------------------------------------------------------------------
4071f068233SBram Moolenaar
4081f068233SBram Moolenaar
4091f068233SBram Moolenaarfunc T42_F()
4101f068233SBram Moolenaar  try
4111f068233SBram Moolenaar
4121f068233SBram Moolenaar    try
4131f068233SBram Moolenaar      Xpath 'a'
4141f068233SBram Moolenaar      throw 4711
4151f068233SBram Moolenaar      Xpath 'b'
4161f068233SBram Moolenaar    catch /4711/
4171f068233SBram Moolenaar      Xpath 'c'
4181f068233SBram Moolenaar    endtry
4191f068233SBram Moolenaar
4201f068233SBram Moolenaar    try
4211f068233SBram Moolenaar      Xpath 'd'
4221f068233SBram Moolenaar      throw 4711
4231f068233SBram Moolenaar      Xpath 'e'
4241f068233SBram Moolenaar    catch /^4711$/
4251f068233SBram Moolenaar      Xpath 'f'
4261f068233SBram Moolenaar    endtry
4271f068233SBram Moolenaar
4281f068233SBram Moolenaar    try
4291f068233SBram Moolenaar      Xpath 'g'
4301f068233SBram Moolenaar      throw 4711
4311f068233SBram Moolenaar      Xpath 'h'
4321f068233SBram Moolenaar    catch /\d/
4331f068233SBram Moolenaar      Xpath 'i'
4341f068233SBram Moolenaar    endtry
4351f068233SBram Moolenaar
4361f068233SBram Moolenaar    try
4371f068233SBram Moolenaar      Xpath 'j'
4381f068233SBram Moolenaar      throw 4711
4391f068233SBram Moolenaar      Xpath 'k'
4401f068233SBram Moolenaar    catch /^\d\+$/
4411f068233SBram Moolenaar      Xpath 'l'
4421f068233SBram Moolenaar    endtry
4431f068233SBram Moolenaar
4441f068233SBram Moolenaar    try
4451f068233SBram Moolenaar      Xpath 'm'
4461f068233SBram Moolenaar      throw "arrgh"
4471f068233SBram Moolenaar      Xpath 'n'
4481f068233SBram Moolenaar    catch /arrgh/
4491f068233SBram Moolenaar      Xpath 'o'
4501f068233SBram Moolenaar    endtry
4511f068233SBram Moolenaar
4521f068233SBram Moolenaar    try
4531f068233SBram Moolenaar      Xpath 'p'
4541f068233SBram Moolenaar      throw "arrgh"
4551f068233SBram Moolenaar      Xpath 'q'
4561f068233SBram Moolenaar    catch /^arrgh$/
4571f068233SBram Moolenaar      Xpath 'r'
4581f068233SBram Moolenaar    endtry
4591f068233SBram Moolenaar
4601f068233SBram Moolenaar    try
4611f068233SBram Moolenaar      Xpath 's'
4621f068233SBram Moolenaar      throw "arrgh"
4631f068233SBram Moolenaar      Xpath 't'
4641f068233SBram Moolenaar    catch /\l/
4651f068233SBram Moolenaar      Xpath 'u'
4661f068233SBram Moolenaar    endtry
4671f068233SBram Moolenaar
4681f068233SBram Moolenaar    try
4691f068233SBram Moolenaar      Xpath 'v'
4701f068233SBram Moolenaar      throw "arrgh"
4711f068233SBram Moolenaar      Xpath 'w'
4721f068233SBram Moolenaar    catch /^\l\+$/
4731f068233SBram Moolenaar      Xpath 'x'
4741f068233SBram Moolenaar    endtry
4751f068233SBram Moolenaar
4761f068233SBram Moolenaar    try
4771f068233SBram Moolenaar      try
4781f068233SBram Moolenaar        Xpath 'y'
4791f068233SBram Moolenaar        throw "ARRGH"
4801f068233SBram Moolenaar        Xpath 'z'
4811f068233SBram Moolenaar      catch /^arrgh$/
4821f068233SBram Moolenaar        Xpath 'A'
4831f068233SBram Moolenaar      endtry
4841f068233SBram Moolenaar    catch /^\carrgh$/
4851f068233SBram Moolenaar      Xpath 'B'
4861f068233SBram Moolenaar    endtry
4871f068233SBram Moolenaar
4881f068233SBram Moolenaar    try
4891f068233SBram Moolenaar      Xpath 'C'
4901f068233SBram Moolenaar      throw ""
4911f068233SBram Moolenaar      Xpath 'D'
4921f068233SBram Moolenaar    catch /^$/
4931f068233SBram Moolenaar      Xpath 'E'
4941f068233SBram Moolenaar    endtry
4951f068233SBram Moolenaar
4961f068233SBram Moolenaar  catch /.*/
4971f068233SBram Moolenaar    Xpath 'F'
4981f068233SBram Moolenaar    call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
4991f068233SBram Moolenaar  endtry
5001f068233SBram Moolenaarendfunc
5011f068233SBram Moolenaar
5021f068233SBram Moolenaarfunc Test_catch_number_string()
5031f068233SBram Moolenaar  XpathINIT
5041f068233SBram Moolenaar  call T42_F()
5051f068233SBram Moolenaar  call assert_equal('acdfgijlmoprsuvxyBCE', g:Xpath)
5061f068233SBram Moolenaarendfunc
5071f068233SBram Moolenaar
5081f068233SBram Moolenaar
5091f068233SBram Moolenaar"-------------------------------------------------------------------------------
5101f068233SBram Moolenaar" Test 43:  Selecting the correct :catch clause				    {{{1
5111f068233SBram Moolenaar"
5121f068233SBram Moolenaar"	    When an exception is thrown and there are multiple :catch clauses,
5131f068233SBram Moolenaar"	    the first matching one is taken.
5141f068233SBram Moolenaar"-------------------------------------------------------------------------------
5151f068233SBram Moolenaar
5161f068233SBram Moolenaarfunc T43_F()
5171f068233SBram Moolenaar  let loops = 3
5181f068233SBram Moolenaar  while loops > 0
5191f068233SBram Moolenaar    try
5201f068233SBram Moolenaar      if loops == 3
5211f068233SBram Moolenaar        Xpath 'a' . loops
5221f068233SBram Moolenaar        throw "a"
5231f068233SBram Moolenaar        Xpath 'b' . loops
5241f068233SBram Moolenaar      elseif loops == 2
5251f068233SBram Moolenaar        Xpath 'c' . loops
5261f068233SBram Moolenaar        throw "ab"
5271f068233SBram Moolenaar        Xpath 'd' . loops
5281f068233SBram Moolenaar      elseif loops == 1
5291f068233SBram Moolenaar        Xpath 'e' . loops
5301f068233SBram Moolenaar        throw "abc"
5311f068233SBram Moolenaar        Xpath 'f' . loops
5321f068233SBram Moolenaar      endif
5331f068233SBram Moolenaar    catch /abc/
5341f068233SBram Moolenaar      Xpath 'g' . loops
5351f068233SBram Moolenaar    catch /ab/
5361f068233SBram Moolenaar      Xpath 'h' . loops
5371f068233SBram Moolenaar    catch /.*/
5381f068233SBram Moolenaar      Xpath 'i' . loops
5391f068233SBram Moolenaar    catch /a/
5401f068233SBram Moolenaar      Xpath 'j' . loops
5411f068233SBram Moolenaar    endtry
5421f068233SBram Moolenaar
5431f068233SBram Moolenaar    let loops = loops - 1
5441f068233SBram Moolenaar  endwhile
5451f068233SBram Moolenaar  Xpath 'k'
5461f068233SBram Moolenaarendfunc
5471f068233SBram Moolenaar
5481f068233SBram Moolenaarfunc Test_multi_catch()
5491f068233SBram Moolenaar  XpathINIT
5501f068233SBram Moolenaar  call T43_F()
5511f068233SBram Moolenaar  call assert_equal('a3i3c2h2e1g1k', g:Xpath)
5521f068233SBram Moolenaarendfunc
5531f068233SBram Moolenaar
5541f068233SBram Moolenaar
5551f068233SBram Moolenaar"-------------------------------------------------------------------------------
5561f068233SBram Moolenaar" Test 44:  Missing or empty :catch patterns				    {{{1
5571f068233SBram Moolenaar"
5581f068233SBram Moolenaar"	    A missing or empty :catch pattern means the same as /.*/, that is,
5591f068233SBram Moolenaar"	    catches everything.  To catch only empty exceptions, /^$/ must be
5601f068233SBram Moolenaar"	    used.  A :catch with missing, empty, or /.*/ argument also works
5611f068233SBram Moolenaar"	    when followed by another command separated by a bar on the same
5621f068233SBram Moolenaar"	    line.  :catch patterns cannot be specified between ||.  But other
5631f068233SBram Moolenaar"	    pattern separators can be used instead of //.
5641f068233SBram Moolenaar"-------------------------------------------------------------------------------
5651f068233SBram Moolenaar
5661f068233SBram Moolenaarfunc T44_F()
5671f068233SBram Moolenaar  try
5681f068233SBram Moolenaar    try
5691f068233SBram Moolenaar      Xpath 'a'
5701f068233SBram Moolenaar      throw ""
5711f068233SBram Moolenaar    catch /^$/
5721f068233SBram Moolenaar      Xpath 'b'
5731f068233SBram Moolenaar    endtry
5741f068233SBram Moolenaar
5751f068233SBram Moolenaar    try
5761f068233SBram Moolenaar      Xpath 'c'
5771f068233SBram Moolenaar      throw ""
5781f068233SBram Moolenaar    catch /.*/
5791f068233SBram Moolenaar      Xpath 'd'
5801f068233SBram Moolenaar    endtry
5811f068233SBram Moolenaar
5821f068233SBram Moolenaar    try
5831f068233SBram Moolenaar      Xpath 'e'
5841f068233SBram Moolenaar      throw ""
5851f068233SBram Moolenaar    catch //
5861f068233SBram Moolenaar      Xpath 'f'
5871f068233SBram Moolenaar    endtry
5881f068233SBram Moolenaar
5891f068233SBram Moolenaar    try
5901f068233SBram Moolenaar      Xpath 'g'
5911f068233SBram Moolenaar      throw ""
5921f068233SBram Moolenaar    catch
5931f068233SBram Moolenaar      Xpath 'h'
5941f068233SBram Moolenaar    endtry
5951f068233SBram Moolenaar
5961f068233SBram Moolenaar    try
5971f068233SBram Moolenaar      Xpath 'i'
5981f068233SBram Moolenaar      throw "oops"
5991f068233SBram Moolenaar    catch /^$/
6001f068233SBram Moolenaar      Xpath 'j'
6011f068233SBram Moolenaar    catch /.*/
6021f068233SBram Moolenaar      Xpath 'k'
6031f068233SBram Moolenaar    endtry
6041f068233SBram Moolenaar
6051f068233SBram Moolenaar    try
6061f068233SBram Moolenaar      Xpath 'l'
6071f068233SBram Moolenaar      throw "arrgh"
6081f068233SBram Moolenaar    catch /^$/
6091f068233SBram Moolenaar      Xpath 'm'
6101f068233SBram Moolenaar    catch //
6111f068233SBram Moolenaar      Xpath 'n'
6121f068233SBram Moolenaar    endtry
6131f068233SBram Moolenaar
6141f068233SBram Moolenaar    try
6151f068233SBram Moolenaar      Xpath 'o'
6161f068233SBram Moolenaar      throw "brrr"
6171f068233SBram Moolenaar    catch /^$/
6181f068233SBram Moolenaar      Xpath 'p'
6191f068233SBram Moolenaar    catch
6201f068233SBram Moolenaar      Xpath 'q'
6211f068233SBram Moolenaar    endtry
6221f068233SBram Moolenaar
6231f068233SBram Moolenaar    try | Xpath 'r' | throw "x" | catch /.*/ | Xpath 's' | endtry
6241f068233SBram Moolenaar
6251f068233SBram Moolenaar    try | Xpath 't' | throw "y" | catch // | Xpath 'u' | endtry
6261f068233SBram Moolenaar
6271f068233SBram Moolenaar    while 1
6281f068233SBram Moolenaar      try
6291f068233SBram Moolenaar        let caught = 0
6301f068233SBram Moolenaar        let v:errmsg = ""
6311f068233SBram Moolenaar        " Extra try level:  if ":catch" without arguments below raises
6321f068233SBram Moolenaar        " a syntax error because it misinterprets the "Xpath" as a pattern,
6331f068233SBram Moolenaar        " let it be caught by the ":catch /.*/" below.
6341f068233SBram Moolenaar        try
6351f068233SBram Moolenaar          try | Xpath 'v' | throw "z" | catch | Xpath 'w' | :
6361f068233SBram Moolenaar          endtry
6371f068233SBram Moolenaar        endtry
6381f068233SBram Moolenaar      catch /.*/
6391f068233SBram Moolenaar        let caught = 1
6401f068233SBram Moolenaar        call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
6411f068233SBram Moolenaar      finally
6421f068233SBram Moolenaar        if $VIMNOERRTHROW && v:errmsg != ""
6431f068233SBram Moolenaar          call assert_report(v:errmsg)
6441f068233SBram Moolenaar        endif
6451f068233SBram Moolenaar        if caught || $VIMNOERRTHROW && v:errmsg != ""
6461f068233SBram Moolenaar          Xpath 'x'
6471f068233SBram Moolenaar        endif
6481f068233SBram Moolenaar        break		" discard error for $VIMNOERRTHROW
6491f068233SBram Moolenaar      endtry
6501f068233SBram Moolenaar    endwhile
6511f068233SBram Moolenaar
6521f068233SBram Moolenaar    let cologne = 4711
6531f068233SBram Moolenaar    try
6541f068233SBram Moolenaar      try
6551f068233SBram Moolenaar        Xpath 'y'
6561f068233SBram Moolenaar        throw "throw cologne"
6571f068233SBram Moolenaar        " Next lines catches all and throws 4711:
6581f068233SBram Moolenaar      catch |throw cologne|
6591f068233SBram Moolenaar        Xpath 'z'
6601f068233SBram Moolenaar      endtry
6611f068233SBram Moolenaar    catch /4711/
6621f068233SBram Moolenaar      Xpath 'A'
6631f068233SBram Moolenaar    endtry
6641f068233SBram Moolenaar
6651f068233SBram Moolenaar    try
6661f068233SBram Moolenaar      Xpath 'B'
6671f068233SBram Moolenaar      throw "plus"
6681f068233SBram Moolenaar    catch +plus+
6691f068233SBram Moolenaar      Xpath 'C'
6701f068233SBram Moolenaar    endtry
6711f068233SBram Moolenaar
6721f068233SBram Moolenaar    Xpath 'D'
6731f068233SBram Moolenaar  catch /.*/
6741f068233SBram Moolenaar    Xpath 'E'
6751f068233SBram Moolenaar    call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
6761f068233SBram Moolenaar  endtry
6771f068233SBram Moolenaarendfunc
6781f068233SBram Moolenaar
6791f068233SBram Moolenaarfunc Test_empty_catch()
6801f068233SBram Moolenaar  XpathINIT
6811f068233SBram Moolenaar  call T44_F()
6821f068233SBram Moolenaar  call assert_equal('abcdefghiklnoqrstuvwyABCD', g:Xpath)
6831f068233SBram Moolenaarendfunc
6841f068233SBram Moolenaar
6851f068233SBram Moolenaar
6861f068233SBram Moolenaar"-------------------------------------------------------------------------------
6871f068233SBram Moolenaar" Test 45:  Catching exceptions from nested :try blocks			    {{{1
6881f068233SBram Moolenaar"
6891f068233SBram Moolenaar"	    When :try blocks are nested, an exception is caught by the innermost
6901f068233SBram Moolenaar"	    try conditional that has a matching :catch clause.
6911f068233SBram Moolenaar"-------------------------------------------------------------------------------
6921f068233SBram Moolenaar
6931f068233SBram Moolenaarfunc T45_F()
6941f068233SBram Moolenaar  let loops = 3
6951f068233SBram Moolenaar  while loops > 0
6961f068233SBram Moolenaar    try
6971f068233SBram Moolenaar      try
6981f068233SBram Moolenaar        try
6991f068233SBram Moolenaar          try
7001f068233SBram Moolenaar            if loops == 3
7011f068233SBram Moolenaar              Xpath 'a' . loops
7021f068233SBram Moolenaar              throw "a"
7031f068233SBram Moolenaar              Xpath 'b' . loops
7041f068233SBram Moolenaar            elseif loops == 2
7051f068233SBram Moolenaar              Xpath 'c' . loops
7061f068233SBram Moolenaar              throw "ab"
7071f068233SBram Moolenaar              Xpath 'd' . loops
7081f068233SBram Moolenaar            elseif loops == 1
7091f068233SBram Moolenaar              Xpath 'e' . loops
7101f068233SBram Moolenaar              throw "abc"
7111f068233SBram Moolenaar              Xpath 'f' . loops
7121f068233SBram Moolenaar            endif
7131f068233SBram Moolenaar          catch /abc/
7141f068233SBram Moolenaar            Xpath 'g' . loops
7151f068233SBram Moolenaar          endtry
7161f068233SBram Moolenaar        catch /ab/
7171f068233SBram Moolenaar          Xpath 'h' . loops
7181f068233SBram Moolenaar        endtry
7191f068233SBram Moolenaar      catch /.*/
7201f068233SBram Moolenaar        Xpath 'i' . loops
7211f068233SBram Moolenaar      endtry
7221f068233SBram Moolenaar    catch /a/
7231f068233SBram Moolenaar      Xpath 'j' . loops
7241f068233SBram Moolenaar    endtry
7251f068233SBram Moolenaar
7261f068233SBram Moolenaar    let loops = loops - 1
7271f068233SBram Moolenaar  endwhile
7281f068233SBram Moolenaar  Xpath 'k'
7291f068233SBram Moolenaarendfunc
7301f068233SBram Moolenaar
7311f068233SBram Moolenaarfunc Test_catch_from_nested_try()
7321f068233SBram Moolenaar  XpathINIT
7331f068233SBram Moolenaar  call T45_F()
7341f068233SBram Moolenaar  call assert_equal('a3i3c2h2e1g1k', g:Xpath)
7351f068233SBram Moolenaarendfunc
7361f068233SBram Moolenaar
7371f068233SBram Moolenaar
7381f068233SBram Moolenaar"-------------------------------------------------------------------------------
7391f068233SBram Moolenaar" Test 46:  Executing :finally after a :throw in nested :try		    {{{1
7401f068233SBram Moolenaar"
7411f068233SBram Moolenaar"	    When an exception is thrown from within nested :try blocks, the
7421f068233SBram Moolenaar"	    :finally clauses of the non-catching try conditionals should be
7431f068233SBram Moolenaar"	    executed before the matching :catch of the next surrounding :try
7441f068233SBram Moolenaar"	    gets the control.  If this also has a :finally clause, it is
7451f068233SBram Moolenaar"	    executed afterwards.
7461f068233SBram Moolenaar"-------------------------------------------------------------------------------
7471f068233SBram Moolenaar
7481f068233SBram Moolenaarfunc T46_F()
7491f068233SBram Moolenaar  let sum = 0
7501f068233SBram Moolenaar
7511f068233SBram Moolenaar  try
7521f068233SBram Moolenaar    Xpath 'a'
7531f068233SBram Moolenaar    try
7541f068233SBram Moolenaar      Xpath 'b'
7551f068233SBram Moolenaar      try
7561f068233SBram Moolenaar        Xpath 'c'
7571f068233SBram Moolenaar        try
7581f068233SBram Moolenaar          Xpath 'd'
7591f068233SBram Moolenaar          throw "ABC"
7601f068233SBram Moolenaar          Xpath 'e'
7611f068233SBram Moolenaar        catch /xyz/
7621f068233SBram Moolenaar          Xpath 'f'
7631f068233SBram Moolenaar        finally
7641f068233SBram Moolenaar          Xpath 'g'
7651f068233SBram Moolenaar          if sum != 0
7661f068233SBram Moolenaar            Xpath 'h'
7671f068233SBram Moolenaar          endif
7681f068233SBram Moolenaar          let sum = sum + 1
7691f068233SBram Moolenaar        endtry
7701f068233SBram Moolenaar        Xpath 'i'
7711f068233SBram Moolenaar      catch /123/
7721f068233SBram Moolenaar        Xpath 'j'
7731f068233SBram Moolenaar      catch /321/
7741f068233SBram Moolenaar        Xpath 'k'
7751f068233SBram Moolenaar      finally
7761f068233SBram Moolenaar        Xpath 'l'
7771f068233SBram Moolenaar        if sum != 1
7781f068233SBram Moolenaar          Xpath 'm'
7791f068233SBram Moolenaar        endif
7801f068233SBram Moolenaar        let sum = sum + 2
7811f068233SBram Moolenaar      endtry
7821f068233SBram Moolenaar      Xpath 'n'
7831f068233SBram Moolenaar    finally
7841f068233SBram Moolenaar      Xpath 'o'
7851f068233SBram Moolenaar      if sum != 3
7861f068233SBram Moolenaar        Xpath 'p'
7871f068233SBram Moolenaar      endif
7881f068233SBram Moolenaar      let sum = sum + 4
7891f068233SBram Moolenaar    endtry
7901f068233SBram Moolenaar    Xpath 'q'
7911f068233SBram Moolenaar  catch /ABC/
7921f068233SBram Moolenaar    Xpath 'r'
7931f068233SBram Moolenaar    if sum != 7
7941f068233SBram Moolenaar      Xpath 's'
7951f068233SBram Moolenaar    endif
7961f068233SBram Moolenaar    let sum = sum + 8
7971f068233SBram Moolenaar  finally
7981f068233SBram Moolenaar    Xpath 't'
7991f068233SBram Moolenaar    if sum != 15
8001f068233SBram Moolenaar      Xpath 'u'
8011f068233SBram Moolenaar    endif
8021f068233SBram Moolenaar    let sum = sum + 16
8031f068233SBram Moolenaar  endtry
8041f068233SBram Moolenaar  Xpath 'v'
8051f068233SBram Moolenaar  if sum != 31
8061f068233SBram Moolenaar    Xpath 'w'
8071f068233SBram Moolenaar  endif
8081f068233SBram Moolenaarendfunc
8091f068233SBram Moolenaar
8101f068233SBram Moolenaarfunc Test_finally_after_throw()
8111f068233SBram Moolenaar  XpathINIT
8121f068233SBram Moolenaar  call T46_F()
8131f068233SBram Moolenaar  call assert_equal('abcdglortv', g:Xpath)
8141f068233SBram Moolenaarendfunc
8151f068233SBram Moolenaar
8161f068233SBram Moolenaar
8171f068233SBram Moolenaar"-------------------------------------------------------------------------------
8181f068233SBram Moolenaar" Test 47:  Throwing exceptions from a :catch clause			    {{{1
8191f068233SBram Moolenaar"
8201f068233SBram Moolenaar"	    When an exception is thrown from a :catch clause, it should not be
8211f068233SBram Moolenaar"	    caught by a :catch of the same :try conditional.  After executing
8221f068233SBram Moolenaar"	    the :finally clause (if present), surrounding try conditionals
8231f068233SBram Moolenaar"	    should be checked for a matching :catch.
8241f068233SBram Moolenaar"-------------------------------------------------------------------------------
8251f068233SBram Moolenaar
8261f068233SBram Moolenaarfunc T47_F()
8271f068233SBram Moolenaar  Xpath 'a'
8281f068233SBram Moolenaar  try
8291f068233SBram Moolenaar    Xpath 'b'
8301f068233SBram Moolenaar    try
8311f068233SBram Moolenaar      Xpath 'c'
8321f068233SBram Moolenaar      try
8331f068233SBram Moolenaar        Xpath 'd'
8341f068233SBram Moolenaar        throw "x1"
8351f068233SBram Moolenaar        Xpath 'e'
8361f068233SBram Moolenaar      catch /x1/
8371f068233SBram Moolenaar        Xpath 'f'
8381f068233SBram Moolenaar        try
8391f068233SBram Moolenaar          Xpath 'g'
8401f068233SBram Moolenaar          throw "x2"
8411f068233SBram Moolenaar          Xpath 'h'
8421f068233SBram Moolenaar        catch /x1/
8431f068233SBram Moolenaar          Xpath 'i'
8441f068233SBram Moolenaar        catch /x2/
8451f068233SBram Moolenaar          Xpath 'j'
8461f068233SBram Moolenaar          try
8471f068233SBram Moolenaar            Xpath 'k'
8481f068233SBram Moolenaar            throw "x3"
8491f068233SBram Moolenaar            Xpath 'l'
8501f068233SBram Moolenaar          catch /x1/
8511f068233SBram Moolenaar            Xpath 'm'
8521f068233SBram Moolenaar          catch /x2/
8531f068233SBram Moolenaar            Xpath 'n'
8541f068233SBram Moolenaar          finally
8551f068233SBram Moolenaar            Xpath 'o'
8561f068233SBram Moolenaar          endtry
8571f068233SBram Moolenaar          Xpath 'p'
8581f068233SBram Moolenaar        catch /x3/
8591f068233SBram Moolenaar          Xpath 'q'
8601f068233SBram Moolenaar        endtry
8611f068233SBram Moolenaar        Xpath 'r'
8621f068233SBram Moolenaar      catch /x1/
8631f068233SBram Moolenaar        Xpath 's'
8641f068233SBram Moolenaar      catch /x2/
8651f068233SBram Moolenaar        Xpath 't'
8661f068233SBram Moolenaar      catch /x3/
8671f068233SBram Moolenaar        Xpath 'u'
8681f068233SBram Moolenaar      finally
8691f068233SBram Moolenaar        Xpath 'v'
8701f068233SBram Moolenaar      endtry
8711f068233SBram Moolenaar      Xpath 'w'
8721f068233SBram Moolenaar    catch /x1/
8731f068233SBram Moolenaar      Xpath 'x'
8741f068233SBram Moolenaar    catch /x2/
8751f068233SBram Moolenaar      Xpath 'y'
8761f068233SBram Moolenaar    catch /x3/
8771f068233SBram Moolenaar      Xpath 'z'
8781f068233SBram Moolenaar    endtry
8791f068233SBram Moolenaar    Xpath 'A'
8801f068233SBram Moolenaar  catch /.*/
8811f068233SBram Moolenaar    Xpath 'B'
8821f068233SBram Moolenaar    call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
8831f068233SBram Moolenaar  endtry
8841f068233SBram Moolenaar  Xpath 'C'
8851f068233SBram Moolenaarendfunc
8861f068233SBram Moolenaar
8871f068233SBram Moolenaarfunc Test_throw_from_catch()
8881f068233SBram Moolenaar  XpathINIT
8891f068233SBram Moolenaar  call T47_F()
8901f068233SBram Moolenaar  call assert_equal('abcdfgjkovzAC', g:Xpath)
8911f068233SBram Moolenaarendfunc
8921f068233SBram Moolenaar
8931f068233SBram Moolenaar
8941f068233SBram Moolenaar"-------------------------------------------------------------------------------
8951f068233SBram Moolenaar" Test 48:  Throwing exceptions from a :finally clause			    {{{1
8961f068233SBram Moolenaar"
8971f068233SBram Moolenaar"	    When an exception is thrown from a :finally clause, it should not be
8981f068233SBram Moolenaar"	    caught by a :catch of the same :try conditional.  Surrounding try
8991f068233SBram Moolenaar"	    conditionals should be checked for a matching :catch.  A previously
9001f068233SBram Moolenaar"	    thrown exception is discarded.
9011f068233SBram Moolenaar"-------------------------------------------------------------------------------
9021f068233SBram Moolenaar
9031f068233SBram Moolenaarfunc T48_F()
9041f068233SBram Moolenaar  try
9051f068233SBram Moolenaar
9061f068233SBram Moolenaar    try
9071f068233SBram Moolenaar      try
9081f068233SBram Moolenaar        Xpath 'a'
9091f068233SBram Moolenaar      catch /x1/
9101f068233SBram Moolenaar        Xpath 'b'
9111f068233SBram Moolenaar      finally
9121f068233SBram Moolenaar        Xpath 'c'
9131f068233SBram Moolenaar        throw "x1"
9141f068233SBram Moolenaar        Xpath 'd'
9151f068233SBram Moolenaar      endtry
9161f068233SBram Moolenaar      Xpath 'e'
9171f068233SBram Moolenaar    catch /x1/
9181f068233SBram Moolenaar      Xpath 'f'
9191f068233SBram Moolenaar    endtry
9201f068233SBram Moolenaar    Xpath 'g'
9211f068233SBram Moolenaar
9221f068233SBram Moolenaar    try
9231f068233SBram Moolenaar      try
9241f068233SBram Moolenaar        Xpath 'h'
9251f068233SBram Moolenaar        throw "x2"
9261f068233SBram Moolenaar        Xpath 'i'
9271f068233SBram Moolenaar      catch /x2/
9281f068233SBram Moolenaar        Xpath 'j'
9291f068233SBram Moolenaar      catch /x3/
9301f068233SBram Moolenaar        Xpath 'k'
9311f068233SBram Moolenaar      finally
9321f068233SBram Moolenaar        Xpath 'l'
9331f068233SBram Moolenaar        throw "x3"
9341f068233SBram Moolenaar        Xpath 'm'
9351f068233SBram Moolenaar      endtry
9361f068233SBram Moolenaar      Xpath 'n'
9371f068233SBram Moolenaar    catch /x2/
9381f068233SBram Moolenaar      Xpath 'o'
9391f068233SBram Moolenaar    catch /x3/
9401f068233SBram Moolenaar      Xpath 'p'
9411f068233SBram Moolenaar    endtry
9421f068233SBram Moolenaar    Xpath 'q'
9431f068233SBram Moolenaar
9441f068233SBram Moolenaar    try
9451f068233SBram Moolenaar      try
9461f068233SBram Moolenaar        try
9471f068233SBram Moolenaar          Xpath 'r'
9481f068233SBram Moolenaar          throw "x4"
9491f068233SBram Moolenaar          Xpath 's'
9501f068233SBram Moolenaar        catch /x5/
9511f068233SBram Moolenaar          Xpath 't'
9521f068233SBram Moolenaar        finally
9531f068233SBram Moolenaar          Xpath 'u'
9541f068233SBram Moolenaar          throw "x5"	" discards 'x4'
9551f068233SBram Moolenaar          Xpath 'v'
9561f068233SBram Moolenaar        endtry
9571f068233SBram Moolenaar        Xpath 'w'
9581f068233SBram Moolenaar      catch /x4/
9591f068233SBram Moolenaar        Xpath 'x'
9601f068233SBram Moolenaar      finally
9611f068233SBram Moolenaar        Xpath 'y'
9621f068233SBram Moolenaar      endtry
9631f068233SBram Moolenaar      Xpath 'z'
9641f068233SBram Moolenaar    catch /x5/
9651f068233SBram Moolenaar      Xpath 'A'
9661f068233SBram Moolenaar    endtry
9671f068233SBram Moolenaar    Xpath 'B'
9681f068233SBram Moolenaar
9691f068233SBram Moolenaar  catch /.*/
9701f068233SBram Moolenaar    Xpath 'C'
9711f068233SBram Moolenaar    call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
9721f068233SBram Moolenaar  endtry
9731f068233SBram Moolenaar  Xpath 'D'
9741f068233SBram Moolenaarendfunc
9751f068233SBram Moolenaar
9761f068233SBram Moolenaarfunc Test_throw_from_finally()
9771f068233SBram Moolenaar  XpathINIT
9781f068233SBram Moolenaar  call T48_F()
9791f068233SBram Moolenaar  call assert_equal('acfghjlpqruyABD', g:Xpath)
9801f068233SBram Moolenaarendfunc
9811f068233SBram Moolenaar
9821f068233SBram Moolenaar
9831f068233SBram Moolenaar"-------------------------------------------------------------------------------
9841f068233SBram Moolenaar" Test 51:  Throwing exceptions across :execute and user commands	    {{{1
9851f068233SBram Moolenaar"
9861f068233SBram Moolenaar"	    A :throw command may be executed under an ":execute" or from
9871f068233SBram Moolenaar"	    a user command.
9881f068233SBram Moolenaar"-------------------------------------------------------------------------------
9891f068233SBram Moolenaar
9901f068233SBram Moolenaarfunc T51_F()
9911f068233SBram Moolenaar  command! -nargs=? THROW1    throw <args> | throw 1
9921f068233SBram Moolenaar  command! -nargs=? THROW2    try | throw <args> | endtry | throw 2
9931f068233SBram Moolenaar  command! -nargs=? THROW3    try | throw 3 | catch /3/ | throw <args> | endtry
9941f068233SBram Moolenaar  command! -nargs=? THROW4    try | throw 4 | finally   | throw <args> | endtry
9951f068233SBram Moolenaar
9961f068233SBram Moolenaar  try
9971f068233SBram Moolenaar
9981f068233SBram Moolenaar    try
9991f068233SBram Moolenaar      try
10001f068233SBram Moolenaar        Xpath 'a'
10011f068233SBram Moolenaar        THROW1 "A"
10021f068233SBram Moolenaar      catch /A/
10031f068233SBram Moolenaar        Xpath 'b'
10041f068233SBram Moolenaar      endtry
10051f068233SBram Moolenaar    catch /1/
10061f068233SBram Moolenaar      Xpath 'c'
10071f068233SBram Moolenaar    endtry
10081f068233SBram Moolenaar
10091f068233SBram Moolenaar    try
10101f068233SBram Moolenaar      try
10111f068233SBram Moolenaar        Xpath 'd'
10121f068233SBram Moolenaar        THROW2 "B"
10131f068233SBram Moolenaar      catch /B/
10141f068233SBram Moolenaar        Xpath 'e'
10151f068233SBram Moolenaar      endtry
10161f068233SBram Moolenaar    catch /2/
10171f068233SBram Moolenaar      Xpath 'f'
10181f068233SBram Moolenaar    endtry
10191f068233SBram Moolenaar
10201f068233SBram Moolenaar    try
10211f068233SBram Moolenaar      try
10221f068233SBram Moolenaar        Xpath 'g'
10231f068233SBram Moolenaar        THROW3 "C"
10241f068233SBram Moolenaar      catch /C/
10251f068233SBram Moolenaar        Xpath 'h'
10261f068233SBram Moolenaar      endtry
10271f068233SBram Moolenaar    catch /3/
10281f068233SBram Moolenaar      Xpath 'i'
10291f068233SBram Moolenaar    endtry
10301f068233SBram Moolenaar
10311f068233SBram Moolenaar    try
10321f068233SBram Moolenaar      try
10331f068233SBram Moolenaar        Xpath 'j'
10341f068233SBram Moolenaar        THROW4 "D"
10351f068233SBram Moolenaar      catch /D/
10361f068233SBram Moolenaar        Xpath 'k'
10371f068233SBram Moolenaar      endtry
10381f068233SBram Moolenaar    catch /4/
10391f068233SBram Moolenaar      Xpath 'l'
10401f068233SBram Moolenaar    endtry
10411f068233SBram Moolenaar
10421f068233SBram Moolenaar    try
10431f068233SBram Moolenaar      try
10441f068233SBram Moolenaar        Xpath 'm'
10451f068233SBram Moolenaar        execute 'throw "E" | throw 5'
10461f068233SBram Moolenaar      catch /E/
10471f068233SBram Moolenaar        Xpath 'n'
10481f068233SBram Moolenaar      endtry
10491f068233SBram Moolenaar    catch /5/
10501f068233SBram Moolenaar      Xpath 'o'
10511f068233SBram Moolenaar    endtry
10521f068233SBram Moolenaar
10531f068233SBram Moolenaar    try
10541f068233SBram Moolenaar      try
10551f068233SBram Moolenaar        Xpath 'p'
10561f068233SBram Moolenaar        execute 'try | throw "F" | endtry | throw 6'
10571f068233SBram Moolenaar      catch /F/
10581f068233SBram Moolenaar        Xpath 'q'
10591f068233SBram Moolenaar      endtry
10601f068233SBram Moolenaar    catch /6/
10611f068233SBram Moolenaar      Xpath 'r'
10621f068233SBram Moolenaar    endtry
10631f068233SBram Moolenaar
10641f068233SBram Moolenaar    try
10651f068233SBram Moolenaar      try
10661f068233SBram Moolenaar        Xpath 's'
10671f068233SBram Moolenaar        execute'try | throw 7 | catch /7/ | throw "G" | endtry'
10681f068233SBram Moolenaar      catch /G/
10691f068233SBram Moolenaar        Xpath 't'
10701f068233SBram Moolenaar      endtry
10711f068233SBram Moolenaar    catch /7/
10721f068233SBram Moolenaar      Xpath 'u'
10731f068233SBram Moolenaar    endtry
10741f068233SBram Moolenaar
10751f068233SBram Moolenaar    try
10761f068233SBram Moolenaar      try
10771f068233SBram Moolenaar        Xpath 'v'
10781f068233SBram Moolenaar        execute 'try | throw 8 | finally   | throw "H" | endtry'
10791f068233SBram Moolenaar      catch /H/
10801f068233SBram Moolenaar        Xpath 'w'
10811f068233SBram Moolenaar      endtry
10821f068233SBram Moolenaar    catch /8/
10831f068233SBram Moolenaar      Xpath 'x'
10841f068233SBram Moolenaar    endtry
10851f068233SBram Moolenaar
10861f068233SBram Moolenaar  catch /.*/
10871f068233SBram Moolenaar    Xpath 'y'
10881f068233SBram Moolenaar    call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
10891f068233SBram Moolenaar  endtry
10901f068233SBram Moolenaar
10911f068233SBram Moolenaar  Xpath 'z'
10921f068233SBram Moolenaar
10931f068233SBram Moolenaar  delcommand THROW1
10941f068233SBram Moolenaar  delcommand THROW2
10951f068233SBram Moolenaar  delcommand THROW3
10961f068233SBram Moolenaar  delcommand THROW4
10971f068233SBram Moolenaarendfunc
10981f068233SBram Moolenaar
10991f068233SBram Moolenaarfunc Test_throw_across_commands()
11001f068233SBram Moolenaar  XpathINIT
11011f068233SBram Moolenaar  call T51_F()
11021f068233SBram Moolenaar  call assert_equal('abdeghjkmnpqstvwz', g:Xpath)
11031f068233SBram Moolenaarendfunc
11041f068233SBram Moolenaar
11051f068233SBram Moolenaar
11061f068233SBram Moolenaar
11071f068233SBram Moolenaar"-------------------------------------------------------------------------------
11081f068233SBram Moolenaar" Test 69:  :throw across :if, :elseif, :while				    {{{1
11091f068233SBram Moolenaar"
11101f068233SBram Moolenaar"	    On an :if, :elseif, or :while command, an exception might be thrown
11111f068233SBram Moolenaar"	    during evaluation of the expression to test.  The exception can be
11121f068233SBram Moolenaar"	    caught by the script.
11131f068233SBram Moolenaar"-------------------------------------------------------------------------------
11141f068233SBram Moolenaar
11151f068233SBram Moolenaarfunc T69_throw(x)
11161f068233SBram Moolenaar  Xpath 'x'
11171f068233SBram Moolenaar  throw a:x
11181f068233SBram Moolenaarendfunc
11191f068233SBram Moolenaar
11201f068233SBram Moolenaarfunc Test_throw_ifelsewhile()
11211f068233SBram Moolenaar  XpathINIT
11221f068233SBram Moolenaar
11231f068233SBram Moolenaar  try
11241f068233SBram Moolenaar    try
11251f068233SBram Moolenaar      Xpath 'a'
11261f068233SBram Moolenaar      if 111 == T69_throw("if") + 111
11271f068233SBram Moolenaar        Xpath 'b'
11281f068233SBram Moolenaar      else
11291f068233SBram Moolenaar        Xpath 'c'
11301f068233SBram Moolenaar      endif
11311f068233SBram Moolenaar      Xpath 'd'
11321f068233SBram Moolenaar    catch /^if$/
11331f068233SBram Moolenaar      Xpath 'e'
11341f068233SBram Moolenaar    catch /.*/
11351f068233SBram Moolenaar      Xpath 'f'
11361f068233SBram Moolenaar      call assert_report("if: " . v:exception . " in " . v:throwpoint)
11371f068233SBram Moolenaar    endtry
11381f068233SBram Moolenaar
11391f068233SBram Moolenaar    try
11401f068233SBram Moolenaar      Xpath 'g'
11411f068233SBram Moolenaar      if v:false
11421f068233SBram Moolenaar        Xpath 'h'
11431f068233SBram Moolenaar      elseif 222 == T69_throw("elseif") + 222
11441f068233SBram Moolenaar        Xpath 'i'
11451f068233SBram Moolenaar      else
11461f068233SBram Moolenaar        Xpath 'j'
11471f068233SBram Moolenaar      endif
11481f068233SBram Moolenaar      Xpath 'k'
11491f068233SBram Moolenaar    catch /^elseif$/
11501f068233SBram Moolenaar      Xpath 'l'
11511f068233SBram Moolenaar    catch /.*/
11521f068233SBram Moolenaar      Xpath 'm'
11531f068233SBram Moolenaar      call assert_report("elseif: " . v:exception . " in " . v:throwpoint)
11541f068233SBram Moolenaar    endtry
11551f068233SBram Moolenaar
11561f068233SBram Moolenaar    try
11571f068233SBram Moolenaar      Xpath 'n'
11581f068233SBram Moolenaar      while 333 == T69_throw("while") + 333
11591f068233SBram Moolenaar        Xpath 'o'
11601f068233SBram Moolenaar        break
11611f068233SBram Moolenaar      endwhile
11621f068233SBram Moolenaar      Xpath 'p'
11631f068233SBram Moolenaar    catch /^while$/
11641f068233SBram Moolenaar      Xpath 'q'
11651f068233SBram Moolenaar    catch /.*/
11661f068233SBram Moolenaar      Xpath 'r'
11671f068233SBram Moolenaar      call assert_report("while: " .. v:exception .. " in " .. v:throwpoint)
11681f068233SBram Moolenaar    endtry
11691f068233SBram Moolenaar  catch /^0$/	    " default return value
11701f068233SBram Moolenaar    Xpath 's'
11711f068233SBram Moolenaar    call assert_report(v:throwpoint)
11721f068233SBram Moolenaar  catch /.*/
11731f068233SBram Moolenaar    call assert_report(v:exception .. " in " .. v:throwpoint)
11741f068233SBram Moolenaar    Xpath 't'
11751f068233SBram Moolenaar  endtry
11761f068233SBram Moolenaar
11771f068233SBram Moolenaar  call assert_equal('axegxlnxq', g:Xpath)
11781f068233SBram Moolenaarendfunc
11791f068233SBram Moolenaar
11801f068233SBram Moolenaar
11811f068233SBram Moolenaar"-------------------------------------------------------------------------------
11821f068233SBram Moolenaar" Test 70:  :throw across :return or :throw				    {{{1
11831f068233SBram Moolenaar"
11841f068233SBram Moolenaar"	    On a :return or :throw command, an exception might be thrown during
11851f068233SBram Moolenaar"	    evaluation of the expression to return or throw, respectively.  The
11861f068233SBram Moolenaar"	    exception can be caught by the script.
11871f068233SBram Moolenaar"-------------------------------------------------------------------------------
11881f068233SBram Moolenaar
11891f068233SBram Moolenaarlet T70_taken = ""
11901f068233SBram Moolenaar
11911f068233SBram Moolenaarfunc T70_throw(x, n)
11921f068233SBram Moolenaar    let g:T70_taken = g:T70_taken . "T" . a:n
11931f068233SBram Moolenaar    throw a:x
11941f068233SBram Moolenaarendfunc
11951f068233SBram Moolenaar
11961f068233SBram Moolenaarfunc T70_F(x, y, n)
11971f068233SBram Moolenaar    let g:T70_taken = g:T70_taken . "F" . a:n
11981f068233SBram Moolenaar    return a:x + T70_throw(a:y, a:n)
11991f068233SBram Moolenaarendfunc
12001f068233SBram Moolenaar
12011f068233SBram Moolenaarfunc T70_G(x, y, n)
12021f068233SBram Moolenaar    let g:T70_taken = g:T70_taken . "G" . a:n
12031f068233SBram Moolenaar    throw a:x . T70_throw(a:y, a:n)
12041f068233SBram Moolenaar    return a:x
12051f068233SBram Moolenaarendfunc
12061f068233SBram Moolenaar
12071f068233SBram Moolenaarfunc Test_throwreturn()
12081f068233SBram Moolenaar  XpathINIT
12091f068233SBram Moolenaar
12101f068233SBram Moolenaar  try
12111f068233SBram Moolenaar    try
12121f068233SBram Moolenaar      Xpath 'a'
12131f068233SBram Moolenaar      call T70_F(4711, "return", 1)
12141f068233SBram Moolenaar      Xpath 'b'
12151f068233SBram Moolenaar    catch /^return$/
12161f068233SBram Moolenaar      Xpath 'c'
12171f068233SBram Moolenaar    catch /.*/
12181f068233SBram Moolenaar      Xpath 'd'
12191f068233SBram Moolenaar      call assert_report("return: " .. v:exception .. " in " .. v:throwpoint)
12201f068233SBram Moolenaar    endtry
12211f068233SBram Moolenaar
12221f068233SBram Moolenaar    try
12231f068233SBram Moolenaar      Xpath 'e'
12241f068233SBram Moolenaar      let var = T70_F(4712, "return-var", 2)
12251f068233SBram Moolenaar      Xpath 'f'
12261f068233SBram Moolenaar    catch /^return-var$/
12271f068233SBram Moolenaar      Xpath 'g'
12281f068233SBram Moolenaar    catch /.*/
12291f068233SBram Moolenaar      Xpath 'h'
12301f068233SBram Moolenaar      call assert_report("return-var: " . v:exception . " in " . v:throwpoint)
12311f068233SBram Moolenaar    finally
12321f068233SBram Moolenaar      unlet! var
12331f068233SBram Moolenaar    endtry
12341f068233SBram Moolenaar
12351f068233SBram Moolenaar    try
12361f068233SBram Moolenaar      Xpath 'i'
12371f068233SBram Moolenaar      throw "except1" . T70_throw("throw1", 3)
12381f068233SBram Moolenaar      Xpath 'j'
12391f068233SBram Moolenaar    catch /^except1/
12401f068233SBram Moolenaar      Xpath 'k'
12411f068233SBram Moolenaar    catch /^throw1$/
12421f068233SBram Moolenaar      Xpath 'l'
12431f068233SBram Moolenaar    catch /.*/
12441f068233SBram Moolenaar      Xpath 'm'
12451f068233SBram Moolenaar      call assert_report("throw1: " .. v:exception .. " in " .. v:throwpoint)
12461f068233SBram Moolenaar    endtry
12471f068233SBram Moolenaar
12481f068233SBram Moolenaar    try
12491f068233SBram Moolenaar      Xpath 'n'
12501f068233SBram Moolenaar      call T70_G("except2", "throw2", 4)
12511f068233SBram Moolenaar      Xpath 'o'
12521f068233SBram Moolenaar    catch /^except2/
12531f068233SBram Moolenaar      Xpath 'p'
12541f068233SBram Moolenaar    catch /^throw2$/
12551f068233SBram Moolenaar      Xpath 'q'
12561f068233SBram Moolenaar    catch /.*/
12571f068233SBram Moolenaar      Xpath 'r'
12581f068233SBram Moolenaar      call assert_report("throw2: " .. v:exception .. " in " .. v:throwpoint)
12591f068233SBram Moolenaar    endtry
12601f068233SBram Moolenaar
12611f068233SBram Moolenaar    try
12621f068233SBram Moolenaar      Xpath 's'
12631f068233SBram Moolenaar      let var = T70_G("except3", "throw3", 5)
12641f068233SBram Moolenaar      Xpath 't'
12651f068233SBram Moolenaar    catch /^except3/
12661f068233SBram Moolenaar      Xpath 'u'
12671f068233SBram Moolenaar    catch /^throw3$/
12681f068233SBram Moolenaar      Xpath 'v'
12691f068233SBram Moolenaar    catch /.*/
12701f068233SBram Moolenaar      Xpath 'w'
12711f068233SBram Moolenaar      call assert_report("throw3: " .. v:exception .. " in " .. v:throwpoint)
12721f068233SBram Moolenaar    finally
12731f068233SBram Moolenaar      unlet! var
12741f068233SBram Moolenaar    endtry
12751f068233SBram Moolenaar
12761f068233SBram Moolenaar    call assert_equal('F1T1F2T2T3G4T4G5T5', g:T70_taken)
12771f068233SBram Moolenaar    Xpath 'x'
12781f068233SBram Moolenaar  catch /^0$/	    " default return value
12791f068233SBram Moolenaar    Xpath 'y'
12801f068233SBram Moolenaar    call assert_report(v:throwpoint)
12811f068233SBram Moolenaar  catch /.*/
12821f068233SBram Moolenaar    Xpath 'z'
12831f068233SBram Moolenaar    call assert_report('Caught' .. v:exception .. ' in ' .. v:throwpoint)
12841f068233SBram Moolenaar  endtry
12851f068233SBram Moolenaar
12861f068233SBram Moolenaar  call assert_equal('acegilnqsvx', g:Xpath)
12871f068233SBram Moolenaarendfunc
12881f068233SBram Moolenaar
12891f068233SBram Moolenaar"-------------------------------------------------------------------------------
12901f068233SBram Moolenaar" Test 71:  :throw across :echo variants and :execute			    {{{1
12911f068233SBram Moolenaar"
12921f068233SBram Moolenaar"	    On an :echo, :echon, :echomsg, :echoerr, or :execute command, an
12931f068233SBram Moolenaar"	    exception might be thrown during evaluation of the arguments to
12941f068233SBram Moolenaar"	    be displayed or executed as a command, respectively.  Any following
12951f068233SBram Moolenaar"	    arguments are not evaluated, then.  The exception can be caught by
12961f068233SBram Moolenaar"	    the script.
12971f068233SBram Moolenaar"-------------------------------------------------------------------------------
12981f068233SBram Moolenaar
12991f068233SBram Moolenaarlet T71_taken = ""
13001f068233SBram Moolenaar
13011f068233SBram Moolenaarfunc T71_throw(x, n)
13021f068233SBram Moolenaar    let g:T71_taken = g:T71_taken . "T" . a:n
13031f068233SBram Moolenaar    throw a:x
13041f068233SBram Moolenaarendfunc
13051f068233SBram Moolenaar
13061f068233SBram Moolenaarfunc T71_F(n)
13071f068233SBram Moolenaar    let g:T71_taken = g:T71_taken . "F" . a:n
13081f068233SBram Moolenaar    return "F" . a:n
13091f068233SBram Moolenaarendfunc
13101f068233SBram Moolenaar
13111f068233SBram Moolenaarfunc Test_throw_echo()
13121f068233SBram Moolenaar  XpathINIT
13131f068233SBram Moolenaar
13141f068233SBram Moolenaar  try
13151f068233SBram Moolenaar    try
13161f068233SBram Moolenaar      Xpath 'a'
13171f068233SBram Moolenaar      echo 'echo ' . T71_throw("echo-except", 1) . T71_F(1)
13181f068233SBram Moolenaar      Xpath 'b'
13191f068233SBram Moolenaar    catch /^echo-except$/
13201f068233SBram Moolenaar      Xpath 'c'
13211f068233SBram Moolenaar    catch /.*/
13221f068233SBram Moolenaar      Xpath 'd'
13231f068233SBram Moolenaar      call assert_report("echo: " .. v:exception .. " in " .. v:throwpoint)
13241f068233SBram Moolenaar    endtry
13251f068233SBram Moolenaar
13261f068233SBram Moolenaar    try
13271f068233SBram Moolenaar      Xpath 'e'
13281f068233SBram Moolenaar      echon "echon " . T71_throw("echon-except", 2) . T71_F(2)
13291f068233SBram Moolenaar      Xpath 'f'
13301f068233SBram Moolenaar    catch /^echon-except$/
13311f068233SBram Moolenaar      Xpath 'g'
13321f068233SBram Moolenaar    catch /.*/
13331f068233SBram Moolenaar      Xpath 'h'
13341f068233SBram Moolenaar      call assert_report('echon: ' . v:exception . ' in ' . v:throwpoint)
13351f068233SBram Moolenaar    endtry
13361f068233SBram Moolenaar
13371f068233SBram Moolenaar    try
13381f068233SBram Moolenaar      Xpath 'i'
13391f068233SBram Moolenaar      echomsg "echomsg " . T71_throw("echomsg-except", 3) . T71_F(3)
13401f068233SBram Moolenaar      Xpath 'j'
13411f068233SBram Moolenaar    catch /^echomsg-except$/
13421f068233SBram Moolenaar      Xpath 'k'
13431f068233SBram Moolenaar    catch /.*/
13441f068233SBram Moolenaar      Xpath 'l'
13451f068233SBram Moolenaar      call assert_report('echomsg: ' . v:exception . ' in ' . v:throwpoint)
13461f068233SBram Moolenaar    endtry
13471f068233SBram Moolenaar
13481f068233SBram Moolenaar    try
13491f068233SBram Moolenaar      Xpath 'm'
13501f068233SBram Moolenaar      echoerr "echoerr " . T71_throw("echoerr-except", 4) . T71_F(4)
13511f068233SBram Moolenaar      Xpath 'n'
13521f068233SBram Moolenaar    catch /^echoerr-except$/
13531f068233SBram Moolenaar      Xpath 'o'
13541f068233SBram Moolenaar    catch /Vim/
13551f068233SBram Moolenaar      Xpath 'p'
13561f068233SBram Moolenaar    catch /echoerr/
13571f068233SBram Moolenaar      Xpath 'q'
13581f068233SBram Moolenaar    catch /.*/
13591f068233SBram Moolenaar      Xpath 'r'
13601f068233SBram Moolenaar      call assert_report('echoerr: ' . v:exception . ' in ' . v:throwpoint)
13611f068233SBram Moolenaar    endtry
13621f068233SBram Moolenaar
13631f068233SBram Moolenaar    try
13641f068233SBram Moolenaar      Xpath 's'
13651f068233SBram Moolenaar      execute "echo 'execute " . T71_throw("execute-except", 5) . T71_F(5) "'"
13661f068233SBram Moolenaar      Xpath 't'
13671f068233SBram Moolenaar    catch /^execute-except$/
13681f068233SBram Moolenaar      Xpath 'u'
13691f068233SBram Moolenaar    catch /.*/
13701f068233SBram Moolenaar      Xpath 'v'
13711f068233SBram Moolenaar      call assert_report('execute: ' . v:exception . ' in ' . v:throwpoint)
13721f068233SBram Moolenaar    endtry
13731f068233SBram Moolenaar
13741f068233SBram Moolenaar    call assert_equal('T1T2T3T4T5', g:T71_taken)
13751f068233SBram Moolenaar    Xpath 'w'
13761f068233SBram Moolenaar  catch /^0$/	    " default return value
13771f068233SBram Moolenaar    Xpath 'x'
13781f068233SBram Moolenaar    call assert_report(v:throwpoint)
13791f068233SBram Moolenaar  catch /.*/
13801f068233SBram Moolenaar    Xpath 'y'
13811f068233SBram Moolenaar    call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
13821f068233SBram Moolenaar  endtry
13831f068233SBram Moolenaar
13841f068233SBram Moolenaar  call assert_equal('acegikmosuw', g:Xpath)
13851f068233SBram Moolenaarendfunc
13861f068233SBram Moolenaar
13871f068233SBram Moolenaar
13881f068233SBram Moolenaar"-------------------------------------------------------------------------------
13891f068233SBram Moolenaar" Test 72:  :throw across :let or :unlet				    {{{1
13901f068233SBram Moolenaar"
13911f068233SBram Moolenaar"	    On a :let command, an exception might be thrown during evaluation
13921f068233SBram Moolenaar"	    of the expression to assign.  On an :let or :unlet command, the
13931f068233SBram Moolenaar"	    evaluation of the name of the variable to be assigned or list or
13941f068233SBram Moolenaar"	    deleted, respectively, may throw an exception.  Any following
13951f068233SBram Moolenaar"	    arguments are not evaluated, then.  The exception can be caught by
13961f068233SBram Moolenaar"	    the script.
13971f068233SBram Moolenaar"-------------------------------------------------------------------------------
13981f068233SBram Moolenaar
13991f068233SBram Moolenaarlet throwcount = 0
14001f068233SBram Moolenaar
14011f068233SBram Moolenaarfunc T72_throw(x)
14021f068233SBram Moolenaar  let g:throwcount = g:throwcount + 1
14031f068233SBram Moolenaar  throw a:x
14041f068233SBram Moolenaarendfunc
14051f068233SBram Moolenaar
14061f068233SBram Moolenaarlet T72_addpath = ''
14071f068233SBram Moolenaar
14081f068233SBram Moolenaarfunc T72_addpath(p)
14091f068233SBram Moolenaar  let g:T72_addpath = g:T72_addpath . a:p
14101f068233SBram Moolenaarendfunc
14111f068233SBram Moolenaar
14121f068233SBram Moolenaarfunc Test_throw_let()
14131f068233SBram Moolenaar  XpathINIT
14141f068233SBram Moolenaar
14151f068233SBram Moolenaar  try
14161f068233SBram Moolenaar    try
14171f068233SBram Moolenaar      let $VAR = 'old_value'
14181f068233SBram Moolenaar      Xpath 'a'
14191f068233SBram Moolenaar      let $VAR = 'let(' . T72_throw('var') . ')'
14201f068233SBram Moolenaar      Xpath 'b'
14211f068233SBram Moolenaar    catch /^var$/
14221f068233SBram Moolenaar      Xpath 'c'
14231f068233SBram Moolenaar    finally
14241f068233SBram Moolenaar      call assert_equal('old_value', $VAR)
14251f068233SBram Moolenaar    endtry
14261f068233SBram Moolenaar
14271f068233SBram Moolenaar    try
14281f068233SBram Moolenaar      let @a = 'old_value'
14291f068233SBram Moolenaar      Xpath 'd'
14301f068233SBram Moolenaar      let @a = 'let(' . T72_throw('reg') . ')'
14311f068233SBram Moolenaar      Xpath 'e'
14321f068233SBram Moolenaar    catch /^reg$/
14331f068233SBram Moolenaar      try
14341f068233SBram Moolenaar        Xpath 'f'
14351f068233SBram Moolenaar        let @A = 'let(' . T72_throw('REG') . ')'
14361f068233SBram Moolenaar        Xpath 'g'
14371f068233SBram Moolenaar      catch /^REG$/
14381f068233SBram Moolenaar        Xpath 'h'
14391f068233SBram Moolenaar      endtry
14401f068233SBram Moolenaar    finally
14411f068233SBram Moolenaar      call assert_equal('old_value', @a)
14421f068233SBram Moolenaar      call assert_equal('old_value', @A)
14431f068233SBram Moolenaar    endtry
14441f068233SBram Moolenaar
14451f068233SBram Moolenaar    try
14461f068233SBram Moolenaar      let saved_gpath = &g:path
14471f068233SBram Moolenaar      let saved_lpath = &l:path
14481f068233SBram Moolenaar      Xpath 'i'
14491f068233SBram Moolenaar      let &path = 'let(' . T72_throw('opt') . ')'
14501f068233SBram Moolenaar      Xpath 'j'
14511f068233SBram Moolenaar    catch /^opt$/
14521f068233SBram Moolenaar      try
14531f068233SBram Moolenaar        Xpath 'k'
14541f068233SBram Moolenaar        let &g:path = 'let(' . T72_throw('gopt') . ')'
14551f068233SBram Moolenaar        Xpath 'l'
14561f068233SBram Moolenaar      catch /^gopt$/
14571f068233SBram Moolenaar        try
14581f068233SBram Moolenaar          Xpath 'm'
14591f068233SBram Moolenaar          let &l:path = 'let(' . T72_throw('lopt') . ')'
14601f068233SBram Moolenaar          Xpath 'n'
14611f068233SBram Moolenaar        catch /^lopt$/
14621f068233SBram Moolenaar          Xpath 'o'
14631f068233SBram Moolenaar        endtry
14641f068233SBram Moolenaar      endtry
14651f068233SBram Moolenaar    finally
14661f068233SBram Moolenaar      call assert_equal(saved_gpath, &g:path)
14671f068233SBram Moolenaar      call assert_equal(saved_lpath, &l:path)
14681f068233SBram Moolenaar      let &g:path = saved_gpath
14691f068233SBram Moolenaar      let &l:path = saved_lpath
14701f068233SBram Moolenaar    endtry
14711f068233SBram Moolenaar
14721f068233SBram Moolenaar    unlet! var1 var2 var3
14731f068233SBram Moolenaar
14741f068233SBram Moolenaar    try
14751f068233SBram Moolenaar      Xpath 'p'
14761f068233SBram Moolenaar      let var1 = 'let(' . T72_throw('var1') . ')'
14771f068233SBram Moolenaar      Xpath 'q'
14781f068233SBram Moolenaar    catch /^var1$/
14791f068233SBram Moolenaar      Xpath 'r'
14801f068233SBram Moolenaar    finally
14811f068233SBram Moolenaar      call assert_true(!exists('var1'))
14821f068233SBram Moolenaar    endtry
14831f068233SBram Moolenaar
14841f068233SBram Moolenaar    try
14851f068233SBram Moolenaar      let var2 = 'old_value'
14861f068233SBram Moolenaar      Xpath 's'
14871f068233SBram Moolenaar      let var2 = 'let(' . T72_throw('var2'). ')'
14881f068233SBram Moolenaar      Xpath 't'
14891f068233SBram Moolenaar    catch /^var2$/
14901f068233SBram Moolenaar      Xpath 'u'
14911f068233SBram Moolenaar    finally
14921f068233SBram Moolenaar      call assert_equal('old_value', var2)
14931f068233SBram Moolenaar    endtry
14941f068233SBram Moolenaar
14951f068233SBram Moolenaar    try
14961f068233SBram Moolenaar      Xpath 'v'
14971f068233SBram Moolenaar      let var{T72_throw('var3')} = 4711
14981f068233SBram Moolenaar      Xpath 'w'
14991f068233SBram Moolenaar    catch /^var3$/
15001f068233SBram Moolenaar      Xpath 'x'
15011f068233SBram Moolenaar    endtry
15021f068233SBram Moolenaar
15031f068233SBram Moolenaar    try
15041f068233SBram Moolenaar      call T72_addpath('T1')
15051f068233SBram Moolenaar      let var{T72_throw('var4')} var{T72_addpath('T2')} | call T72_addpath('T3')
15061f068233SBram Moolenaar      call T72_addpath('T4')
15071f068233SBram Moolenaar    catch /^var4$/
15081f068233SBram Moolenaar      call T72_addpath('T5')
15091f068233SBram Moolenaar    endtry
15101f068233SBram Moolenaar
15111f068233SBram Moolenaar    try
15121f068233SBram Moolenaar      call T72_addpath('T6')
15131f068233SBram Moolenaar      unlet var{T72_throw('var5')} var{T72_addpath('T7')}
15141f068233SBram Moolenaar            \ | call T72_addpath('T8')
15151f068233SBram Moolenaar      call T72_addpath('T9')
15161f068233SBram Moolenaar    catch /^var5$/
15171f068233SBram Moolenaar      call T72_addpath('T10')
15181f068233SBram Moolenaar    endtry
15191f068233SBram Moolenaar
15201f068233SBram Moolenaar    call assert_equal('T1T5T6T10', g:T72_addpath)
15211f068233SBram Moolenaar    call assert_equal(11, g:throwcount)
15221f068233SBram Moolenaar  catch /.*/
15231f068233SBram Moolenaar    call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
15241f068233SBram Moolenaar  endtry
15251f068233SBram Moolenaar
15261f068233SBram Moolenaar  call assert_equal('acdfhikmoprsuvx', g:Xpath)
15271f068233SBram Moolenaarendfunc
15281f068233SBram Moolenaar
15291f068233SBram Moolenaar
15301f068233SBram Moolenaar"-------------------------------------------------------------------------------
15311f068233SBram Moolenaar" Test 73:  :throw across :function, :delfunction			    {{{1
15321f068233SBram Moolenaar"
15331f068233SBram Moolenaar"	    The :function and :delfunction commands may cause an expression
15341f068233SBram Moolenaar"	    specified in braces to be evaluated.  During evaluation, an
15351f068233SBram Moolenaar"	    exception might be thrown.  The exception can be caught by the
15361f068233SBram Moolenaar"	    script.
15371f068233SBram Moolenaar"-------------------------------------------------------------------------------
15381f068233SBram Moolenaar
15391f068233SBram Moolenaarlet T73_taken = ''
15401f068233SBram Moolenaar
15411f068233SBram Moolenaarfunc T73_throw(x, n)
15421f068233SBram Moolenaar  let g:T73_taken = g:T73_taken . 'T' . a:n
15431f068233SBram Moolenaar  throw a:x
15441f068233SBram Moolenaarendfunc
15451f068233SBram Moolenaar
15461f068233SBram Moolenaarfunc T73_expr(x, n)
15471f068233SBram Moolenaar  let g:T73_taken = g:T73_taken . 'E' . a:n
15481f068233SBram Moolenaar  if a:n % 2 == 0
15491f068233SBram Moolenaar    call T73_throw(a:x, a:n)
15501f068233SBram Moolenaar  endif
15511f068233SBram Moolenaar  return 2 - a:n % 2
15521f068233SBram Moolenaarendfunc
15531f068233SBram Moolenaar
15541f068233SBram Moolenaarfunc Test_throw_func()
15551f068233SBram Moolenaar  XpathINIT
15561f068233SBram Moolenaar
15571f068233SBram Moolenaar  try
15581f068233SBram Moolenaar    try
15591f068233SBram Moolenaar      " Define function.
15601f068233SBram Moolenaar      Xpath 'a'
15611f068233SBram Moolenaar      function! F0()
15621f068233SBram Moolenaar      endfunction
15631f068233SBram Moolenaar      Xpath 'b'
15641f068233SBram Moolenaar      function! F{T73_expr('function-def-ok', 1)}()
15651f068233SBram Moolenaar      endfunction
15661f068233SBram Moolenaar      Xpath 'c'
15671f068233SBram Moolenaar      function! F{T73_expr('function-def', 2)}()
15681f068233SBram Moolenaar      endfunction
15691f068233SBram Moolenaar      Xpath 'd'
15701f068233SBram Moolenaar    catch /^function-def-ok$/
15711f068233SBram Moolenaar      Xpath 'e'
15721f068233SBram Moolenaar    catch /^function-def$/
15731f068233SBram Moolenaar      Xpath 'f'
15741f068233SBram Moolenaar    catch /.*/
15751f068233SBram Moolenaar      call assert_report('def: ' . v:exception . ' in ' . v:throwpoint)
15761f068233SBram Moolenaar    endtry
15771f068233SBram Moolenaar
15781f068233SBram Moolenaar    try
15791f068233SBram Moolenaar      " List function.
15801f068233SBram Moolenaar      Xpath 'g'
15811f068233SBram Moolenaar      function F0
15821f068233SBram Moolenaar      Xpath 'h'
15831f068233SBram Moolenaar      function F{T73_expr('function-lst-ok', 3)}
15841f068233SBram Moolenaar      Xpath 'i'
15851f068233SBram Moolenaar      function F{T73_expr('function-lst', 4)}
15861f068233SBram Moolenaar      Xpath 'j'
15871f068233SBram Moolenaar    catch /^function-lst-ok$/
15881f068233SBram Moolenaar      Xpath 'k'
15891f068233SBram Moolenaar    catch /^function-lst$/
15901f068233SBram Moolenaar      Xpath 'l'
15911f068233SBram Moolenaar    catch /.*/
15921f068233SBram Moolenaar      call assert_report('lst: ' . v:exception . ' in ' . v:throwpoint)
15931f068233SBram Moolenaar    endtry
15941f068233SBram Moolenaar
15951f068233SBram Moolenaar    try
15961f068233SBram Moolenaar      " Delete function
15971f068233SBram Moolenaar      Xpath 'm'
15981f068233SBram Moolenaar      delfunction F0
15991f068233SBram Moolenaar      Xpath 'n'
16001f068233SBram Moolenaar      delfunction F{T73_expr('function-del-ok', 5)}
16011f068233SBram Moolenaar      Xpath 'o'
16021f068233SBram Moolenaar      delfunction F{T73_expr('function-del', 6)}
16031f068233SBram Moolenaar      Xpath 'p'
16041f068233SBram Moolenaar    catch /^function-del-ok$/
16051f068233SBram Moolenaar      Xpath 'q'
16061f068233SBram Moolenaar    catch /^function-del$/
16071f068233SBram Moolenaar      Xpath 'r'
16081f068233SBram Moolenaar    catch /.*/
16091f068233SBram Moolenaar      call assert_report('del: ' . v:exception . ' in ' . v:throwpoint)
16101f068233SBram Moolenaar    endtry
16111f068233SBram Moolenaar    call assert_equal('E1E2T2E3E4T4E5E6T6', g:T73_taken)
16121f068233SBram Moolenaar  catch /.*/
16131f068233SBram Moolenaar    call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
16141f068233SBram Moolenaar  endtry
16151f068233SBram Moolenaar
16161f068233SBram Moolenaar  call assert_equal('abcfghilmnor', g:Xpath)
16171f068233SBram Moolenaarendfunc
16181f068233SBram Moolenaar
16191f068233SBram Moolenaar
16201f068233SBram Moolenaar"-------------------------------------------------------------------------------
16211f068233SBram Moolenaar" Test 74:  :throw across builtin functions and commands		    {{{1
16221f068233SBram Moolenaar"
16231f068233SBram Moolenaar"	    Some functions like exists(), searchpair() take expression
16241f068233SBram Moolenaar"	    arguments, other functions or commands like substitute() or
16251f068233SBram Moolenaar"	    :substitute cause an expression (specified in the regular
16261f068233SBram Moolenaar"	    expression) to be evaluated.  During evaluation an exception
16271f068233SBram Moolenaar"	    might be thrown.  The exception can be caught by the script.
16281f068233SBram Moolenaar"-------------------------------------------------------------------------------
16291f068233SBram Moolenaar
16301f068233SBram Moolenaarlet T74_taken = ""
16311f068233SBram Moolenaar
16321f068233SBram Moolenaarfunc T74_throw(x, n)
16331f068233SBram Moolenaar  let g:T74_taken = g:T74_taken . "T" . a:n
16341f068233SBram Moolenaar  throw a:x
16351f068233SBram Moolenaarendfunc
16361f068233SBram Moolenaar
16371f068233SBram Moolenaarfunc T74_expr(x, n)
16381f068233SBram Moolenaar  let g:T74_taken = g:T74_taken . "E" . a:n
16391f068233SBram Moolenaar  call T74_throw(a:x . a:n, a:n)
16401f068233SBram Moolenaar  return "EXPR"
16411f068233SBram Moolenaarendfunc
16421f068233SBram Moolenaar
16431f068233SBram Moolenaarfunc T74_skip(x, n)
16441f068233SBram Moolenaar  let g:T74_taken = g:T74_taken . "S" . a:n . "(" . line(".")
16451f068233SBram Moolenaar  let theline = getline(".")
16461f068233SBram Moolenaar  if theline =~ "skip"
16471f068233SBram Moolenaar    let g:T74_taken = g:T74_taken . "s)"
16481f068233SBram Moolenaar    return 1
16491f068233SBram Moolenaar  elseif theline =~ "throw"
16501f068233SBram Moolenaar    let g:T74_taken = g:T74_taken . "t)"
16511f068233SBram Moolenaar    call T74_throw(a:x . a:n, a:n)
16521f068233SBram Moolenaar  else
16531f068233SBram Moolenaar    let g:T74_taken = g:T74_taken . ")"
16541f068233SBram Moolenaar    return 0
16551f068233SBram Moolenaar  endif
16561f068233SBram Moolenaarendfunc
16571f068233SBram Moolenaar
16581f068233SBram Moolenaarfunc T74_subst(x, n)
16591f068233SBram Moolenaar  let g:T74_taken = g:T74_taken . "U" . a:n . "(" . line(".")
16601f068233SBram Moolenaar  let theline = getline(".")
16611f068233SBram Moolenaar  if theline =~ "not"       " T74_subst() should not be called for this line
16621f068233SBram Moolenaar    let g:T74_taken = g:T74_taken . "n)"
16631f068233SBram Moolenaar    call T74_throw(a:x . a:n, a:n)
16641f068233SBram Moolenaar  elseif theline =~ "throw"
16651f068233SBram Moolenaar    let g:T74_taken = g:T74_taken . "t)"
16661f068233SBram Moolenaar    call T74_throw(a:x . a:n, a:n)
16671f068233SBram Moolenaar  else
16681f068233SBram Moolenaar    let g:T74_taken = g:T74_taken . ")"
16691f068233SBram Moolenaar    return "replaced"
16701f068233SBram Moolenaar  endif
16711f068233SBram Moolenaarendfunc
16721f068233SBram Moolenaar
16731f068233SBram Moolenaarfunc Test_throw_builtin_func()
16741f068233SBram Moolenaar  XpathINIT
16751f068233SBram Moolenaar
16761f068233SBram Moolenaar  try
16771f068233SBram Moolenaar    try
16781f068233SBram Moolenaar      Xpath 'a'
16791f068233SBram Moolenaar      let result = exists('*{T74_expr("exists", 1)}')
16801f068233SBram Moolenaar      Xpath 'b'
16811f068233SBram Moolenaar    catch /^exists1$/
16821f068233SBram Moolenaar      Xpath 'c'
16831f068233SBram Moolenaar      try
16841f068233SBram Moolenaar        let result = exists('{T74_expr("exists", 2)}')
16851f068233SBram Moolenaar        Xpath 'd'
16861f068233SBram Moolenaar      catch /^exists2$/
16871f068233SBram Moolenaar        Xpath 'e'
16881f068233SBram Moolenaar      catch /.*/
16891f068233SBram Moolenaar        call assert_report('exists2: ' . v:exception . ' in ' . v:throwpoint)
16901f068233SBram Moolenaar      endtry
16911f068233SBram Moolenaar    catch /.*/
16921f068233SBram Moolenaar      call assert_report('exists1: ' . v:exception . ' in ' . v:throwpoint)
16931f068233SBram Moolenaar    endtry
16941f068233SBram Moolenaar
16951f068233SBram Moolenaar    try
16961f068233SBram Moolenaar      let file = tempname()
16971f068233SBram Moolenaar      exec "edit" file
16981f068233SBram Moolenaar      call append(0, [
16991f068233SBram Moolenaar            \ 'begin',
17001f068233SBram Moolenaar            \ 'xx',
17011f068233SBram Moolenaar            \ 'middle 3',
17021f068233SBram Moolenaar            \ 'xx',
17031f068233SBram Moolenaar            \ 'middle 5 skip',
17041f068233SBram Moolenaar            \ 'xx',
17051f068233SBram Moolenaar            \ 'middle 7 throw',
17061f068233SBram Moolenaar            \ 'xx',
17071f068233SBram Moolenaar            \ 'end'])
17081f068233SBram Moolenaar      normal! gg
17091f068233SBram Moolenaar      Xpath 'f'
17101f068233SBram Moolenaar      let result = searchpair("begin", "middle", "end", '',
17111f068233SBram Moolenaar            \ 'T74_skip("searchpair", 3)')
17121f068233SBram Moolenaar      Xpath 'g'
17131f068233SBram Moolenaar      let result = searchpair("begin", "middle", "end", '',
17141f068233SBram Moolenaar            \ 'T74_skip("searchpair", 4)')
17151f068233SBram Moolenaar      Xpath 'h'
17161f068233SBram Moolenaar      let result = searchpair("begin", "middle", "end", '',
17171f068233SBram Moolenaar            \ 'T74_skip("searchpair", 5)')
17181f068233SBram Moolenaar      Xpath 'i'
17191f068233SBram Moolenaar    catch /^searchpair[35]$/
17201f068233SBram Moolenaar      Xpath 'j'
17211f068233SBram Moolenaar    catch /^searchpair4$/
17221f068233SBram Moolenaar      Xpath 'k'
17231f068233SBram Moolenaar    catch /.*/
17241f068233SBram Moolenaar      call assert_report('searchpair: ' . v:exception . ' in ' . v:throwpoint)
17251f068233SBram Moolenaar    finally
17261f068233SBram Moolenaar      bwipeout!
17271f068233SBram Moolenaar      call delete(file)
17281f068233SBram Moolenaar    endtry
17291f068233SBram Moolenaar
17301f068233SBram Moolenaar    try
17311f068233SBram Moolenaar      let file = tempname()
17321f068233SBram Moolenaar      exec "edit" file
17331f068233SBram Moolenaar      call append(0, [
17341f068233SBram Moolenaar            \ 'subst 1',
17351f068233SBram Moolenaar            \ 'subst 2',
17361f068233SBram Moolenaar            \ 'not',
17371f068233SBram Moolenaar            \ 'subst 4',
17381f068233SBram Moolenaar            \ 'subst throw',
17391f068233SBram Moolenaar            \ 'subst 6'])
17401f068233SBram Moolenaar      normal! gg
17411f068233SBram Moolenaar      Xpath 'l'
17421f068233SBram Moolenaar      1,2substitute/subst/\=T74_subst("substitute", 6)/
17431f068233SBram Moolenaar      try
17441f068233SBram Moolenaar        Xpath 'm'
17451f068233SBram Moolenaar        try
17461f068233SBram Moolenaar          let v:errmsg = ""
17471f068233SBram Moolenaar          3substitute/subst/\=T74_subst("substitute", 7)/
17481f068233SBram Moolenaar        finally
17491f068233SBram Moolenaar          if v:errmsg != ""
17501f068233SBram Moolenaar            " If exceptions are not thrown on errors, fake the error
17511f068233SBram Moolenaar            " exception in order to get the same execution path.
17521f068233SBram Moolenaar            throw "faked Vim(substitute)"
17531f068233SBram Moolenaar          endif
17541f068233SBram Moolenaar        endtry
17551f068233SBram Moolenaar      catch /Vim(substitute)/	    " Pattern not found ('e' flag missing)
17561f068233SBram Moolenaar        Xpath 'n'
17571f068233SBram Moolenaar        3substitute/subst/\=T74_subst("substitute", 8)/e
17581f068233SBram Moolenaar        Xpath 'o'
17591f068233SBram Moolenaar      endtry
17601f068233SBram Moolenaar      Xpath 'p'
17611f068233SBram Moolenaar      4,6substitute/subst/\=T74_subst("substitute", 9)/
17621f068233SBram Moolenaar      Xpath 'q'
17631f068233SBram Moolenaar    catch /^substitute[678]/
17641f068233SBram Moolenaar      Xpath 'r'
17651f068233SBram Moolenaar    catch /^substitute9/
17661f068233SBram Moolenaar      Xpath 's'
17671f068233SBram Moolenaar    finally
17681f068233SBram Moolenaar      bwipeout!
17691f068233SBram Moolenaar      call delete(file)
17701f068233SBram Moolenaar    endtry
17711f068233SBram Moolenaar
17721f068233SBram Moolenaar    try
17731f068233SBram Moolenaar      Xpath 't'
17741f068233SBram Moolenaar      let var = substitute("sub", "sub", '\=T74_throw("substitute()y", 10)', '')
17751f068233SBram Moolenaar      Xpath 'u'
17761f068233SBram Moolenaar    catch /substitute()y/
17771f068233SBram Moolenaar      Xpath 'v'
17781f068233SBram Moolenaar    catch /.*/
17791f068233SBram Moolenaar      call assert_report('substitute()y: ' . v:exception . ' in '
17801f068233SBram Moolenaar            \ . v:throwpoint)
17811f068233SBram Moolenaar    endtry
17821f068233SBram Moolenaar
17831f068233SBram Moolenaar    try
17841f068233SBram Moolenaar      Xpath 'w'
17851f068233SBram Moolenaar      let var = substitute("not", "sub", '\=T74_throw("substitute()n", 11)', '')
17861f068233SBram Moolenaar      Xpath 'x'
17871f068233SBram Moolenaar    catch /substitute()n/
17881f068233SBram Moolenaar      Xpath 'y'
17891f068233SBram Moolenaar    catch /.*/
17901f068233SBram Moolenaar      call assert_report('substitute()n: ' . v:exception . ' in '
17911f068233SBram Moolenaar            \ . v:throwpoint)
17921f068233SBram Moolenaar    endtry
17931f068233SBram Moolenaar
17941f068233SBram Moolenaar    call assert_equal('E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10',
17951f068233SBram Moolenaar          \ g:T74_taken)
17961f068233SBram Moolenaar
17971f068233SBram Moolenaar  catch /.*/
17981f068233SBram Moolenaar    call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
17991f068233SBram Moolenaar  endtry
18001f068233SBram Moolenaar
18011f068233SBram Moolenaar  call assert_equal('acefgklmnopstvwx', g:Xpath)
18021f068233SBram Moolenaarendfunc
18031f068233SBram Moolenaar
18041f068233SBram Moolenaar
18051f068233SBram Moolenaar"-------------------------------------------------------------------------------
18061f068233SBram Moolenaar" Test 75:  Errors in builtin functions.				    {{{1
18071f068233SBram Moolenaar"
18081f068233SBram Moolenaar"	    On an error in a builtin function called inside a :try/:endtry
18091f068233SBram Moolenaar"	    region, the evaluation of the expression calling that function and
18101f068233SBram Moolenaar"	    the command containing that expression are abandoned.  The error can
18111f068233SBram Moolenaar"	    be caught as an exception.
18121f068233SBram Moolenaar"
18131f068233SBram Moolenaar"	    A simple :call of the builtin function is a trivial case.  If the
18141f068233SBram Moolenaar"	    builtin function is called in the argument list of another function,
18151f068233SBram Moolenaar"	    no further arguments are evaluated, and the other function is not
18161f068233SBram Moolenaar"	    executed.  If the builtin function is called from the argument of
18171f068233SBram Moolenaar"	    a :return command, the :return command is not executed.  If the
18181f068233SBram Moolenaar"	    builtin function is called from the argument of a :throw command,
18191f068233SBram Moolenaar"	    the :throw command is not executed.  The evaluation of the
18201f068233SBram Moolenaar"	    expression calling the builtin function is abandoned.
18211f068233SBram Moolenaar"-------------------------------------------------------------------------------
18221f068233SBram Moolenaar
18231f068233SBram Moolenaarfunc T75_F1(arg1)
18241f068233SBram Moolenaar  Xpath 'a'
18251f068233SBram Moolenaarendfunc
18261f068233SBram Moolenaar
18271f068233SBram Moolenaarfunc T75_F2(arg1, arg2)
18281f068233SBram Moolenaar  Xpath 'b'
18291f068233SBram Moolenaarendfunc
18301f068233SBram Moolenaar
18311f068233SBram Moolenaarfunc T75_G()
18321f068233SBram Moolenaar  Xpath 'c'
18331f068233SBram Moolenaarendfunc
18341f068233SBram Moolenaar
18351f068233SBram Moolenaarfunc T75_H()
18361f068233SBram Moolenaar  Xpath 'd'
18371f068233SBram Moolenaarendfunc
18381f068233SBram Moolenaar
18391f068233SBram Moolenaarfunc T75_R()
18401f068233SBram Moolenaar  while 1
18411f068233SBram Moolenaar    try
18421f068233SBram Moolenaar      let caught = 0
18431f068233SBram Moolenaar      let v:errmsg = ""
18441f068233SBram Moolenaar      Xpath 'e'
18451f068233SBram Moolenaar      return append(1, "s")
18461f068233SBram Moolenaar    catch /E21/
18471f068233SBram Moolenaar      let caught = 1
18481f068233SBram Moolenaar    catch /.*/
18491f068233SBram Moolenaar      Xpath 'f'
18501f068233SBram Moolenaar    finally
18511f068233SBram Moolenaar      Xpath 'g'
18521f068233SBram Moolenaar      if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
18531f068233SBram Moolenaar        Xpath 'h'
18541f068233SBram Moolenaar      endif
18551f068233SBram Moolenaar      break		" discard error for $VIMNOERRTHROW
18561f068233SBram Moolenaar    endtry
18571f068233SBram Moolenaar  endwhile
18581f068233SBram Moolenaar  Xpath 'i'
18591f068233SBram Moolenaarendfunc
18601f068233SBram Moolenaar
18611f068233SBram Moolenaarfunc Test_builtin_func_error()
18621f068233SBram Moolenaar  XpathINIT
18631f068233SBram Moolenaar
18641f068233SBram Moolenaar  try
18651f068233SBram Moolenaar    set noma	" let append() fail with "E21"
18661f068233SBram Moolenaar
18671f068233SBram Moolenaar    while 1
18681f068233SBram Moolenaar      try
18691f068233SBram Moolenaar        let caught = 0
18701f068233SBram Moolenaar        let v:errmsg = ""
18711f068233SBram Moolenaar        Xpath 'j'
18721f068233SBram Moolenaar        call append(1, "s")
18731f068233SBram Moolenaar      catch /E21/
18741f068233SBram Moolenaar        let caught = 1
18751f068233SBram Moolenaar      catch /.*/
18761f068233SBram Moolenaar        Xpath 'k'
18771f068233SBram Moolenaar      finally
18781f068233SBram Moolenaar        Xpath 'l'
18791f068233SBram Moolenaar        if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
18801f068233SBram Moolenaar          Xpath 'm'
18811f068233SBram Moolenaar        endif
18821f068233SBram Moolenaar        break		" discard error for $VIMNOERRTHROW
18831f068233SBram Moolenaar      endtry
18841f068233SBram Moolenaar    endwhile
18851f068233SBram Moolenaar
18861f068233SBram Moolenaar    while 1
18871f068233SBram Moolenaar      try
18881f068233SBram Moolenaar        let caught = 0
18891f068233SBram Moolenaar        let v:errmsg = ""
18901f068233SBram Moolenaar        Xpath 'n'
18911f068233SBram Moolenaar        call T75_F1('x' . append(1, "s"))
18921f068233SBram Moolenaar      catch /E21/
18931f068233SBram Moolenaar        let caught = 1
18941f068233SBram Moolenaar      catch /.*/
18951f068233SBram Moolenaar        Xpath 'o'
18961f068233SBram Moolenaar      finally
18971f068233SBram Moolenaar        Xpath 'p'
18981f068233SBram Moolenaar        if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
18991f068233SBram Moolenaar          Xpath 'q'
19001f068233SBram Moolenaar        endif
19011f068233SBram Moolenaar        break		" discard error for $VIMNOERRTHROW
19021f068233SBram Moolenaar      endtry
19031f068233SBram Moolenaar    endwhile
19041f068233SBram Moolenaar
19051f068233SBram Moolenaar    while 1
19061f068233SBram Moolenaar      try
19071f068233SBram Moolenaar        let caught = 0
19081f068233SBram Moolenaar        let v:errmsg = ""
19091f068233SBram Moolenaar        Xpath 'r'
19101f068233SBram Moolenaar        call T75_F2('x' . append(1, "s"), T75_G())
19111f068233SBram Moolenaar      catch /E21/
19121f068233SBram Moolenaar        let caught = 1
19131f068233SBram Moolenaar      catch /.*/
19141f068233SBram Moolenaar        Xpath 's'
19151f068233SBram Moolenaar      finally
19161f068233SBram Moolenaar        Xpath 't'
19171f068233SBram Moolenaar        if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
19181f068233SBram Moolenaar          Xpath 'u'
19191f068233SBram Moolenaar        endif
19201f068233SBram Moolenaar        break		" discard error for $VIMNOERRTHROW
19211f068233SBram Moolenaar      endtry
19221f068233SBram Moolenaar    endwhile
19231f068233SBram Moolenaar
19241f068233SBram Moolenaar    call T75_R()
19251f068233SBram Moolenaar
19261f068233SBram Moolenaar    while 1
19271f068233SBram Moolenaar      try
19281f068233SBram Moolenaar        let caught = 0
19291f068233SBram Moolenaar        let v:errmsg = ""
19301f068233SBram Moolenaar        Xpath 'v'
19311f068233SBram Moolenaar        throw "T" . append(1, "s")
19321f068233SBram Moolenaar      catch /E21/
19331f068233SBram Moolenaar        let caught = 1
19341f068233SBram Moolenaar      catch /^T.*/
19351f068233SBram Moolenaar        Xpath 'w'
19361f068233SBram Moolenaar      catch /.*/
19371f068233SBram Moolenaar        Xpath 'x'
19381f068233SBram Moolenaar      finally
19391f068233SBram Moolenaar        Xpath 'y'
19401f068233SBram Moolenaar        if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
19411f068233SBram Moolenaar          Xpath 'z'
19421f068233SBram Moolenaar        endif
19431f068233SBram Moolenaar        break		" discard error for $VIMNOERRTHROW
19441f068233SBram Moolenaar      endtry
19451f068233SBram Moolenaar    endwhile
19461f068233SBram Moolenaar
19471f068233SBram Moolenaar    while 1
19481f068233SBram Moolenaar      try
19491f068233SBram Moolenaar        let caught = 0
19501f068233SBram Moolenaar        let v:errmsg = ""
19511f068233SBram Moolenaar        Xpath 'A'
19521f068233SBram Moolenaar        let x = "a"
19531f068233SBram Moolenaar        let x = x . "b" . append(1, "s") . T75_H()
19541f068233SBram Moolenaar      catch /E21/
19551f068233SBram Moolenaar        let caught = 1
19561f068233SBram Moolenaar      catch /.*/
19571f068233SBram Moolenaar        Xpath 'B'
19581f068233SBram Moolenaar      finally
19591f068233SBram Moolenaar        Xpath 'C'
19601f068233SBram Moolenaar        if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
19611f068233SBram Moolenaar          Xpath 'D'
19621f068233SBram Moolenaar        endif
19631f068233SBram Moolenaar        call assert_equal('a', x)
19641f068233SBram Moolenaar        break		" discard error for $VIMNOERRTHROW
19651f068233SBram Moolenaar      endtry
19661f068233SBram Moolenaar    endwhile
19671f068233SBram Moolenaar  catch /.*/
19681f068233SBram Moolenaar    call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
19691f068233SBram Moolenaar  finally
19701f068233SBram Moolenaar    set ma&
19711f068233SBram Moolenaar  endtry
19721f068233SBram Moolenaar
19731f068233SBram Moolenaar  call assert_equal('jlmnpqrtueghivyzACD', g:Xpath)
19741f068233SBram Moolenaarendfunc
19751f068233SBram Moolenaar
1976a6e8f888SBram Moolenaarfunc Test_reload_in_try_catch()
1977a6e8f888SBram Moolenaar  call writefile(['x'], 'Xreload')
1978a6e8f888SBram Moolenaar  set autoread
1979a6e8f888SBram Moolenaar  edit Xreload
1980a6e8f888SBram Moolenaar  tabnew
1981a6e8f888SBram Moolenaar  call writefile(['xx'], 'Xreload')
1982a6e8f888SBram Moolenaar  augroup ReLoad
1983a6e8f888SBram Moolenaar    au FileReadPost Xreload let x = doesnotexist
1984a6e8f888SBram Moolenaar    au BufReadPost Xreload let x = doesnotexist
1985a6e8f888SBram Moolenaar  augroup END
1986a6e8f888SBram Moolenaar  try
1987a6e8f888SBram Moolenaar    edit Xreload
1988a6e8f888SBram Moolenaar  catch
1989a6e8f888SBram Moolenaar  endtry
1990a6e8f888SBram Moolenaar  tabnew
1991a6e8f888SBram Moolenaar
1992a6e8f888SBram Moolenaar  tabclose
1993a6e8f888SBram Moolenaar  tabclose
1994a6e8f888SBram Moolenaar  autocmd! ReLoad
1995a6e8f888SBram Moolenaar  set noautoread
1996a6e8f888SBram Moolenaar  bwipe! Xreload
1997a6e8f888SBram Moolenaar  call delete('Xreload')
1998a6e8f888SBram Moolenaarendfunc
1999a6e8f888SBram Moolenaar
2000818fc9adSBram Moolenaar" Test for errors with :catch, :throw, :finally                            {{{1
2001818fc9adSBram Moolenaarfunc Test_try_catch_errors()
2002818fc9adSBram Moolenaar  call assert_fails('throw |', 'E471:')
2003818fc9adSBram Moolenaar  call assert_fails("throw \n ", 'E471:')
20049b7bf9e9SBram Moolenaar  call assert_fails('catch abc', 'E654:')
2005818fc9adSBram Moolenaar  call assert_fails('try | let i = 1| finally | catch | endtry', 'E604:')
2006818fc9adSBram Moolenaar  call assert_fails('finally', 'E606:')
2007818fc9adSBram Moolenaar  call assert_fails('try | finally | finally | endtry', 'E607:')
2008818fc9adSBram Moolenaar  call assert_fails('try | for i in range(5) | endif | endtry', 'E580:')
2009818fc9adSBram Moolenaar  call assert_fails('try | while v:true | endtry', 'E170:')
2010818fc9adSBram Moolenaar  call assert_fails('try | if v:true | endtry', 'E171:')
2011818fc9adSBram Moolenaarendfunc
2012818fc9adSBram Moolenaar
2013818fc9adSBram Moolenaar" Test for verbose messages with :try :catch, and :finally                 {{{1
2014818fc9adSBram Moolenaarfunc Test_try_catch_verbose()
2015818fc9adSBram Moolenaar  " This test works only when the language is English
2016cde0ff39SBram Moolenaar  CheckEnglish
2017818fc9adSBram Moolenaar
2018818fc9adSBram Moolenaar  set verbose=14
2019b654103aSBram Moolenaar
2020b654103aSBram Moolenaar  " Test for verbose messages displayed when an exception is caught
2021818fc9adSBram Moolenaar  redir => msg
2022818fc9adSBram Moolenaar  try
2023818fc9adSBram Moolenaar    echo i
2024818fc9adSBram Moolenaar  catch /E121:/
2025818fc9adSBram Moolenaar  finally
2026818fc9adSBram Moolenaar  endtry
2027818fc9adSBram Moolenaar  redir END
2028818fc9adSBram Moolenaar  let expected = [
2029b654103aSBram Moolenaar        \ 'Exception thrown: Vim(echo):E121: Undefined variable: i', '',
2030b654103aSBram Moolenaar        \ 'Exception caught: Vim(echo):E121: Undefined variable: i', '',
2031b654103aSBram Moolenaar        \ 'Exception finished: Vim(echo):E121: Undefined variable: i']
2032818fc9adSBram Moolenaar  call assert_equal(expected, split(msg, "\n"))
2033b654103aSBram Moolenaar
2034b654103aSBram Moolenaar  " Test for verbose messages displayed when an exception is discarded
2035b654103aSBram Moolenaar  redir => msg
2036b654103aSBram Moolenaar  try
2037b654103aSBram Moolenaar    try
2038b654103aSBram Moolenaar      throw 'abc'
2039b654103aSBram Moolenaar    finally
2040b654103aSBram Moolenaar      throw 'xyz'
2041b654103aSBram Moolenaar    endtry
2042b654103aSBram Moolenaar  catch
2043b654103aSBram Moolenaar  endtry
2044b654103aSBram Moolenaar  redir END
2045b654103aSBram Moolenaar  let expected = [
2046b654103aSBram Moolenaar        \ 'Exception thrown: abc', '',
2047b654103aSBram Moolenaar        \ 'Exception made pending: abc', '',
2048b654103aSBram Moolenaar        \ 'Exception thrown: xyz', '',
2049b654103aSBram Moolenaar        \ 'Exception discarded: abc', '',
2050b654103aSBram Moolenaar        \ 'Exception caught: xyz', '',
2051b654103aSBram Moolenaar        \ 'Exception finished: xyz']
2052b654103aSBram Moolenaar  call assert_equal(expected, split(msg, "\n"))
2053b654103aSBram Moolenaar
2054b654103aSBram Moolenaar  " Test for messages displayed when :throw is resumed after :finally
2055b654103aSBram Moolenaar  redir => msg
2056b654103aSBram Moolenaar  try
2057b654103aSBram Moolenaar    try
2058b654103aSBram Moolenaar      throw 'abc'
2059b654103aSBram Moolenaar    finally
2060b654103aSBram Moolenaar    endtry
2061b654103aSBram Moolenaar  catch
2062b654103aSBram Moolenaar  endtry
2063b654103aSBram Moolenaar  redir END
2064b654103aSBram Moolenaar  let expected = [
2065b654103aSBram Moolenaar        \ 'Exception thrown: abc', '',
2066b654103aSBram Moolenaar        \ 'Exception made pending: abc', '',
2067b654103aSBram Moolenaar        \ 'Exception resumed: abc', '',
2068b654103aSBram Moolenaar        \ 'Exception caught: abc', '',
2069b654103aSBram Moolenaar        \ 'Exception finished: abc']
2070b654103aSBram Moolenaar  call assert_equal(expected, split(msg, "\n"))
2071b654103aSBram Moolenaar
2072b654103aSBram Moolenaar  " Test for messages displayed when :break is resumed after :finally
2073b654103aSBram Moolenaar  redir => msg
2074b654103aSBram Moolenaar  for i in range(1)
2075b654103aSBram Moolenaar    try
2076b654103aSBram Moolenaar      break
2077b654103aSBram Moolenaar    finally
2078b654103aSBram Moolenaar    endtry
2079b654103aSBram Moolenaar  endfor
2080b654103aSBram Moolenaar  redir END
2081b654103aSBram Moolenaar  let expected = [':break made pending', '', ':break resumed']
2082b654103aSBram Moolenaar  call assert_equal(expected, split(msg, "\n"))
2083b654103aSBram Moolenaar
2084b654103aSBram Moolenaar  " Test for messages displayed when :continue is resumed after :finally
2085b654103aSBram Moolenaar  redir => msg
2086b654103aSBram Moolenaar  for i in range(1)
2087b654103aSBram Moolenaar    try
2088b654103aSBram Moolenaar      continue
2089b654103aSBram Moolenaar    finally
2090b654103aSBram Moolenaar    endtry
2091b654103aSBram Moolenaar  endfor
2092b654103aSBram Moolenaar  redir END
2093b654103aSBram Moolenaar  let expected = [':continue made pending', '', ':continue resumed']
2094b654103aSBram Moolenaar  call assert_equal(expected, split(msg, "\n"))
2095b654103aSBram Moolenaar
2096b654103aSBram Moolenaar  " Test for messages displayed when :return is resumed after :finally
2097b654103aSBram Moolenaar  func Xtest()
2098b654103aSBram Moolenaar    try
2099b654103aSBram Moolenaar      return 'vim'
2100b654103aSBram Moolenaar    finally
2101b654103aSBram Moolenaar    endtry
2102b654103aSBram Moolenaar  endfunc
2103b654103aSBram Moolenaar  redir => msg
2104b654103aSBram Moolenaar  call Xtest()
2105b654103aSBram Moolenaar  redir END
2106b654103aSBram Moolenaar  let expected = [
2107b654103aSBram Moolenaar        \ 'calling Xtest()', '',
2108b654103aSBram Moolenaar        \ ':return vim made pending', '',
2109b654103aSBram Moolenaar        \ ':return vim resumed', '',
2110b654103aSBram Moolenaar        \ 'Xtest returning ''vim''', '',
2111b654103aSBram Moolenaar        \ 'continuing in Test_try_catch_verbose']
2112b654103aSBram Moolenaar  call assert_equal(expected, split(msg, "\n"))
2113b654103aSBram Moolenaar  delfunc Xtest
2114b654103aSBram Moolenaar
2115b654103aSBram Moolenaar  " Test for messages displayed when :finish is resumed after :finally
2116b654103aSBram Moolenaar  call writefile(['try', 'finish', 'finally', 'endtry'], 'Xscript')
2117b654103aSBram Moolenaar  redir => msg
2118b654103aSBram Moolenaar  source Xscript
2119b654103aSBram Moolenaar  redir END
2120b654103aSBram Moolenaar  let expected = [
2121b654103aSBram Moolenaar        \ ':finish made pending', '',
2122b654103aSBram Moolenaar        \ ':finish resumed', '',
2123b654103aSBram Moolenaar        \ 'finished sourcing Xscript',
2124b654103aSBram Moolenaar        \ 'continuing in Test_try_catch_verbose']
2125b654103aSBram Moolenaar  call assert_equal(expected, split(msg, "\n")[1:])
2126b654103aSBram Moolenaar  call delete('Xscript')
2127b654103aSBram Moolenaar
2128b654103aSBram Moolenaar  " Test for messages displayed when a pending :continue is discarded by an
2129b654103aSBram Moolenaar  " exception in a finally handler
2130b654103aSBram Moolenaar  redir => msg
2131b654103aSBram Moolenaar  try
2132b654103aSBram Moolenaar    for i in range(1)
2133b654103aSBram Moolenaar      try
2134b654103aSBram Moolenaar        continue
2135b654103aSBram Moolenaar      finally
2136b654103aSBram Moolenaar        throw 'abc'
2137b654103aSBram Moolenaar      endtry
2138b654103aSBram Moolenaar    endfor
2139b654103aSBram Moolenaar  catch
2140b654103aSBram Moolenaar  endtry
2141b654103aSBram Moolenaar  redir END
2142b654103aSBram Moolenaar  let expected = [
2143b654103aSBram Moolenaar        \ ':continue made pending', '',
2144b654103aSBram Moolenaar        \ 'Exception thrown: abc', '',
2145b654103aSBram Moolenaar        \ ':continue discarded', '',
2146b654103aSBram Moolenaar        \ 'Exception caught: abc', '',
2147b654103aSBram Moolenaar        \ 'Exception finished: abc']
2148b654103aSBram Moolenaar  call assert_equal(expected, split(msg, "\n"))
2149b654103aSBram Moolenaar
2150818fc9adSBram Moolenaar  set verbose&
2151818fc9adSBram Moolenaarendfunc
2152818fc9adSBram Moolenaar
2153b654103aSBram Moolenaar" Test for throwing an exception from a BufEnter autocmd                   {{{1
2154b654103aSBram Moolenaarfunc Test_BufEnter_exception()
2155b654103aSBram Moolenaar  augroup bufenter_exception
2156b654103aSBram Moolenaar    au!
2157b654103aSBram Moolenaar    autocmd BufEnter Xfile1 throw 'abc'
2158b654103aSBram Moolenaar  augroup END
2159b654103aSBram Moolenaar
2160b654103aSBram Moolenaar  let caught_abc = 0
2161b654103aSBram Moolenaar  try
2162b654103aSBram Moolenaar    sp Xfile1
2163b654103aSBram Moolenaar  catch /^abc/
2164b654103aSBram Moolenaar    let caught_abc = 1
2165b654103aSBram Moolenaar  endtry
2166b654103aSBram Moolenaar  call assert_equal(1, caught_abc)
2167b654103aSBram Moolenaar  call assert_equal(1, winnr('$'))
2168b654103aSBram Moolenaar
2169b654103aSBram Moolenaar  augroup bufenter_exception
2170b654103aSBram Moolenaar    au!
2171b654103aSBram Moolenaar  augroup END
2172b654103aSBram Moolenaar  augroup! bufenter_exception
2173b654103aSBram Moolenaar  %bwipe!
2174b654103aSBram Moolenaar
2175b654103aSBram Moolenaar  " Test for recursively throwing exceptions in autocmds
2176b654103aSBram Moolenaar  augroup bufenter_exception
2177b654103aSBram Moolenaar    au!
2178b654103aSBram Moolenaar    autocmd BufEnter Xfile1 throw 'bufenter'
2179b654103aSBram Moolenaar    autocmd BufLeave Xfile1 throw 'bufleave'
2180b654103aSBram Moolenaar  augroup END
2181b654103aSBram Moolenaar
2182b654103aSBram Moolenaar  let ex_count = 0
2183b654103aSBram Moolenaar  try
2184b654103aSBram Moolenaar    try
2185b654103aSBram Moolenaar      sp Xfile1
2186b654103aSBram Moolenaar    catch /^bufenter/
2187b654103aSBram Moolenaar      let ex_count += 1
2188b654103aSBram Moolenaar    endtry
2189b654103aSBram Moolenaar  catch /^bufleave/
2190b654103aSBram Moolenaar      let ex_count += 10
2191b654103aSBram Moolenaar  endtry
2192b654103aSBram Moolenaar  call assert_equal(10, ex_count)
2193b654103aSBram Moolenaar  call assert_equal(2, winnr('$'))
2194b654103aSBram Moolenaar
2195b654103aSBram Moolenaar  augroup bufenter_exception
2196b654103aSBram Moolenaar    au!
2197b654103aSBram Moolenaar  augroup END
2198b654103aSBram Moolenaar  augroup! bufenter_exception
2199b654103aSBram Moolenaar  %bwipe!
2200b654103aSBram Moolenaarendfunc
2201b654103aSBram Moolenaar
22028143a53cSBram Moolenaar" Test for using try/catch in a user command with a failing expression    {{{1
22038143a53cSBram Moolenaarfunc Test_user_command_try_catch()
22048143a53cSBram Moolenaar  let lines =<< trim END
22058143a53cSBram Moolenaar      function s:throw() abort
22068143a53cSBram Moolenaar        throw 'error'
22078143a53cSBram Moolenaar      endfunction
22088143a53cSBram Moolenaar
22098143a53cSBram Moolenaar      command! Execute
22108143a53cSBram Moolenaar      \   try
22118143a53cSBram Moolenaar      \ |   let s:x = s:throw()
22128143a53cSBram Moolenaar      \ | catch
22138143a53cSBram Moolenaar      \ |   let g:caught = 'caught'
22148143a53cSBram Moolenaar      \ | endtry
22158143a53cSBram Moolenaar
22168143a53cSBram Moolenaar      let g:caught = 'no'
22178143a53cSBram Moolenaar      Execute
22188143a53cSBram Moolenaar      call assert_equal('caught', g:caught)
22198143a53cSBram Moolenaar  END
22208143a53cSBram Moolenaar  call writefile(lines, 'XtestTryCatch')
22218143a53cSBram Moolenaar  source XtestTryCatch
22228143a53cSBram Moolenaar
22238143a53cSBram Moolenaar  call delete('XtestTryCatch')
22248143a53cSBram Moolenaar  unlet g:caught
22258143a53cSBram Moolenaarendfunc
22268143a53cSBram Moolenaar
222736f691f5SBram Moolenaar" Test for using throw in a called function with following error    {{{1
222836f691f5SBram Moolenaarfunc Test_user_command_throw_in_function_call()
222936f691f5SBram Moolenaar  let lines =<< trim END
223036f691f5SBram Moolenaar      function s:get_dict() abort
223136f691f5SBram Moolenaar        throw 'my_error'
223236f691f5SBram Moolenaar      endfunction
223336f691f5SBram Moolenaar
223436f691f5SBram Moolenaar      try
223536f691f5SBram Moolenaar        call s:get_dict().foo()
223636f691f5SBram Moolenaar      catch /my_error/
223736f691f5SBram Moolenaar        let caught = 'yes'
223836f691f5SBram Moolenaar      catch
22391d34189eSBram Moolenaar        let caught = v:exception
224036f691f5SBram Moolenaar      endtry
224136f691f5SBram Moolenaar      call assert_equal('yes', caught)
224236f691f5SBram Moolenaar  END
224336f691f5SBram Moolenaar  call writefile(lines, 'XtestThrow')
224436f691f5SBram Moolenaar  source XtestThrow
224536f691f5SBram Moolenaar
224636f691f5SBram Moolenaar  call delete('XtestThrow')
224736f691f5SBram Moolenaar  unlet g:caught
224836f691f5SBram Moolenaarendfunc
224936f691f5SBram Moolenaar
22501d34189eSBram Moolenaar" Test for using throw in a called function with following endtry    {{{1
22511d34189eSBram Moolenaarfunc Test_user_command_function_call_with_endtry()
22521d34189eSBram Moolenaar  let lines =<< trim END
22531d34189eSBram Moolenaar      funct s:throw(msg) abort
22541d34189eSBram Moolenaar        throw a:msg
22551d34189eSBram Moolenaar      endfunc
22561d34189eSBram Moolenaar      func s:main() abort
22571d34189eSBram Moolenaar        try
22581d34189eSBram Moolenaar          try
22591d34189eSBram Moolenaar            throw 'err1'
22601d34189eSBram Moolenaar          catch
22611d34189eSBram Moolenaar            call s:throw('err2') | endtry
22621d34189eSBram Moolenaar          catch
22631d34189eSBram Moolenaar            let s:caught = 'yes'
22641d34189eSBram Moolenaar        endtry
22651d34189eSBram Moolenaar      endfunc
22661d34189eSBram Moolenaar
22671d34189eSBram Moolenaar      call s:main()
22681d34189eSBram Moolenaar      call assert_equal('yes', s:caught)
22691d34189eSBram Moolenaar  END
22701d34189eSBram Moolenaar  call writefile(lines, 'XtestThrow')
22711d34189eSBram Moolenaar  source XtestThrow
22721d34189eSBram Moolenaar
22731d34189eSBram Moolenaar  call delete('XtestThrow')
22741d34189eSBram Moolenaarendfunc
22751d34189eSBram Moolenaar
2276a684a684SBram Moolenaarfunc ThisWillFail()
2277949de97dSDominique Pelle
2278949de97dSDominique Pelleendfunc
2279949de97dSDominique Pelle
2280949de97dSDominique Pelle" This was crashing prior to the fix in 8.2.3478.
2281949de97dSDominique Pellefunc Test_error_in_catch_and_finally()
2282949de97dSDominique Pelle  let lines =<< trim END
2283a684a684SBram Moolenaar    try
2284949de97dSDominique Pelle      echo x
2285a684a684SBram Moolenaar    catch
2286a684a684SBram Moolenaar      for l in []
2287a684a684SBram Moolenaar    finally
2288949de97dSDominique Pelle  END
2289949de97dSDominique Pelle  call writefile(lines, 'XtestCatchAndFinally')
2290949de97dSDominique Pelle  try
2291949de97dSDominique Pelle    source XtestCatchAndFinally
2292949de97dSDominique Pelle  catch /E600:/
2293949de97dSDominique Pelle  endtry
2294a684a684SBram Moolenaar
2295949de97dSDominique Pelle  call delete('XtestCatchAndFinally')
2296a684a684SBram Moolenaarendfunc
2297a684a684SBram Moolenaar
2298*cce81e96SBram Moolenaar" This was causing an illegal memory access
2299*cce81e96SBram Moolenaarfunc Test_leave_block_in_endtry_not_called()
2300*cce81e96SBram Moolenaar  let lines =<< trim END
2301*cce81e96SBram Moolenaar      vim9script
2302*cce81e96SBram Moolenaar      try #
2303*cce81e96SBram Moolenaar      for x in []
2304*cce81e96SBram Moolenaar      if
2305*cce81e96SBram Moolenaar      endwhile
2306*cce81e96SBram Moolenaar      if
2307*cce81e96SBram Moolenaar      endtry
2308*cce81e96SBram Moolenaar  END
2309*cce81e96SBram Moolenaar  call writefile(lines, 'XtestEndtry')
2310*cce81e96SBram Moolenaar  try
2311*cce81e96SBram Moolenaar    source XtestEndtry
2312*cce81e96SBram Moolenaar  catch /E171:/
2313*cce81e96SBram Moolenaar  endtry
2314*cce81e96SBram Moolenaar
2315*cce81e96SBram Moolenaar  call delete('XtestEndtry')
2316*cce81e96SBram Moolenaarendfunc
2317*cce81e96SBram Moolenaar
2318a6e8f888SBram Moolenaar" Modeline								    {{{1
23191f068233SBram Moolenaar" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
2320