Merged from the latest developing branch.
[MacVim.git] / src / testdir / test49.vim
blob3b0982a68502a0b8632277f15032f9a945f81a02
1 " Vim script language tests
2 " Author:       Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com>
3 " Last Change:  2006 Apr 28
5 "-------------------------------------------------------------------------------
6 " Test environment                                                          {{{1
7 "-------------------------------------------------------------------------------
10 " Adding new tests easily.                                                  {{{2
12 " Writing new tests is eased considerably with the following functions and
13 " abbreviations (see "Commands for recording the execution path", "Automatic
14 " argument generation").
16 " To get the abbreviations, execute the command
18 "    :let test49_set_env = 1 | source test49.vim
20 " To get them always (from src/testdir), put a line
22 "    au! BufRead test49.vim let test49_set_env = 1 | source test49.vim
24 " into the local .vimrc file in the src/testdir directory.
26 if exists("test49_set_env") && test49_set_env
28     " Automatic argument generation for the test environment commands.
30     function! Xsum()
31         let addend = substitute(getline("."), '^.*"\s*X:\s*\|^.*', '', "")
32         " Evaluate arithmetic expression.
33         if addend != ""
34             exec "let g:Xsum = g:Xsum + " . addend
35         endif
36     endfunction
38     function! Xcheck()
39         let g:Xsum=0
40         ?XpathINIT?,.call Xsum()
41         exec "norm A "
42         return g:Xsum
43     endfunction
45     iab Xcheck Xcheck<Space><C-R>=Xcheck()<CR><C-O>x
47     function! Xcomment(num)
48         let str = ""
49         let tabwidth = &sts ? &sts : &ts
50         let tabs = (48+tabwidth - a:num - virtcol(".")) / tabwidth
51         while tabs > 0
52             let str = str . "\t"
53             let tabs = tabs - 1
54         endwhile
55         let str = str . '" X:'
56         return str
57     endfunction
59     function! Xloop()
60         let back = line(".") . "|norm" . virtcol(".") . "|"
61         norm 0
62         let last = search('X\(loop\|path\)INIT\|Xloop\>', "bW")
63         exec back
64         let theline = getline(last)
65         if theline =~ 'X\(loop\|path\)INIT'
66             let num = 1
67         else
68             let num = 2 * substitute(theline, '.*Xloop\s*\(\d\+\).*', '\1', "")
69         endif
70         ?X\(loop\|path\)INIT?
71             \s/\(XloopINIT!\=\s*\d\+\s\+\)\@<=\(\d\+\)/\=2*submatch(2)/
72         exec back
73         exec "norm a "
74         return num . Xcomment(strlen(num))
75     endfunction
77     iab Xloop Xloop<Space><C-R>=Xloop()<CR><C-O>x
79     function! Xpath(loopinit)
80         let back = line(".") . "|norm" . virtcol(".") . "|"
81         norm 0
82         let last = search('XpathINIT\|Xpath\>\|XloopINIT', "bW")
83         exec back
84         let theline = getline(last)
85         if theline =~ 'XpathINIT'
86             let num = 1
87         elseif theline =~ 'Xpath\>'
88             let num = 2 * substitute(theline, '.*Xpath\s*\(\d\+\).*', '\1', "")
89         else
90             let pattern = '.*XloopINIT!\=\s*\(\d\+\)\s*\(\d\+\).*'
91             let num = substitute(theline, pattern, '\1', "")
92             let factor = substitute(theline, pattern, '\2', "")
93             " The "<C-O>x" from the "Xpath" iab and the character triggering its
94             " expansion are in the input buffer.  Save and clear typeahead so
95             " that it is not read away by the call to "input()" below.  Restore
96             " afterwards.
97             call inputsave()
98             let loops = input("Number of iterations in previous loop? ")
99             call inputrestore()
100             while (loops > 0)
101                 let num = num * factor
102                 let loops = loops - 1
103             endwhile
104         endif
105         exec "norm a "
106         if a:loopinit
107             return num . " 1"
108         endif
109         return num . Xcomment(strlen(num))
110     endfunction
112     iab Xpath Xpath<Space><C-R>=Xpath(0)<CR><C-O>x
113     iab XloopINIT XloopINIT<Space><C-R>=Xpath(1)<CR><C-O>x
115     " Also useful (see ExtraVim below):
116     aug ExtraVim
117         au!
118         au  BufEnter <sfile> syn region ExtraVim
119                     \ start=+^if\s\+ExtraVim(.*)+ end=+^endif+
120                     \ transparent keepend
121         au  BufEnter <sfile> syn match ExtraComment /^"/
122                     \ contained containedin=ExtraVim
123         au  BufEnter <sfile> hi link ExtraComment vimComment
124     aug END
126     aug Xpath
127         au  BufEnter <sfile> syn keyword Xpath
128                     \ XpathINIT Xpath XloopINIT Xloop XloopNEXT Xcheck Xout
129         au  BufEnter <sfile> hi link Xpath Special
130     aug END
132     do BufEnter <sfile>
134     " Do not execute the tests when sourcing this file for getting the functions
135     " and abbreviations above, which are intended for easily adding new test
136     " cases; they are not needed for test execution.  Unlet the variable
137     " controlling this so that an explicit ":source" command for this file will
138     " execute the tests.
139     unlet test49_set_env
140     finish
142 endif
145 " Commands for recording the execution path.                                {{{2
147 " The Xpath/Xloop commands can be used for computing the eXecution path by
148 " adding (different) powers of 2 from those script lines, for which the
149 " execution should be checked.  Xloop provides different addends for each
150 " execution of a loop.  Permitted values are 2^0 to 2^30, so that 31 execution
151 " points (multiply counted inside loops) can be tested.
153 " Note that the arguments of the following commands can be generated
154 " automatically, see below.
156 " Usage:                                                                    {{{3
158 "   - Use XpathINIT at the beginning of the test.
160 "   - Use Xpath to check if a line is executed.
161 "     Argument: power of 2 (decimal).
163 "   - To check multiple execution of loops use Xloop for automatically
164 "     computing Xpath values:
166 "       - Use XloopINIT before the loop.
167 "         Two arguments:
168 "               - the first Xpath value (power of 2) to be used (Xnext),
169 "               - factor for computing a new Xnext value when reexecuting a loop
170 "                 (by a ":continue" or ":endwhile"); this should be 2^n where
171 "                 n is the number of Xloop commands inside the loop.
172 "         If XloopINIT! is used, the first execution of XloopNEXT is
173 "         a no-operation.
175 "       - Use Xloop inside the loop:
176 "         One argument:
177 "               The argument and the Xnext value are multiplied to build the
178 "               next Xpath value.  No new Xnext value is prepared.  The argument
179 "               should be 2^(n-1) for the nth Xloop command inside the loop.
180 "               If the loop has only one Xloop command, the argument can be
181 "               ommitted (default: 1).
183 "       - Use XloopNEXT before ":continue" and ":endwhile".  This computes a new
184 "         Xnext value for the next execution of the loop by multiplying the old
185 "         one with the factor specified in the XloopINIT command.  No Argument.
186 "         Alternatively, when XloopINIT! is used, a single XloopNEXT at the
187 "         beginning of the loop can be used.
189 "     Nested loops are not supported.
191 "   - Use Xcheck at end of each test.  It prints the test number, the expected
192 "     execution path value, the test result ("OK" or "FAIL"), and, if the tests
193 "     fails, the actual execution path.
194 "     One argument:
195 "           Expected Xpath/Xloop sum for the correct execution path.
196 "           In order that this value can be computed automatically, do the
197 "           following: For each line in the test with an Xpath and Xloop
198 "           command, add a comment starting with "X:" and specifying an
199 "           expression that evaluates to the value contributed by this line to
200 "           the correct execution path.  (For copying an Xpath argument of at
201 "           least two digits into the comment, press <C-P>.)  At the end of the
202 "           test, just type "Xcheck" and press <Esc>.
204 "   - In order to add additional information to the test output file, use the
205 "     Xout command.  Argument(s) like ":echo".
207 " Automatic argument generation:                                            {{{3
209 "   The arguments of the Xpath, XloopINIT, Xloop, and Xcheck commands can be
210 "   generated automatically, so that new tests can easily be written without
211 "   mental arithmetic.  The Xcheck argument is computed from the "X:" comments
212 "   of the preceding Xpath and Xloop commands.  See the commands and
213 "   abbreviations at the beginning of this file.
215 " Implementation:                                                           {{{3
216 "     XpathINIT, Xpath, XloopINIT, Xloop, XloopNEXT, Xcheck, Xout.
218 " The variants for existing g:ExtraVimResult are needed when executing a script
219 " in an extra Vim process, see ExtraVim below.
221 " EXTRA_VIM_START - do not change or remove this line.
223 com!                XpathINIT   let g:Xpath = 0
225 if exists("g:ExtraVimResult")
226     com! -count -bar    Xpath   exec "!echo <count> >>" . g:ExtraVimResult
227 else
228     com! -count -bar    Xpath   let g:Xpath = g:Xpath + <count>
229 endif
231 com! -count -nargs=1 -bang
232                   \ XloopINIT   let g:Xnext = <count> |
233                                     \ let g:Xfactor = <args> |
234                                     \ let g:Xskip = strlen("<bang>")
236 if exists("g:ExtraVimResult")
237     com! -count=1 -bar  Xloop   exec "!echo " . (g:Xnext * <count>) . " >>" .
238                                     \ g:ExtraVimResult
239 else
240     com! -count=1 -bar  Xloop   let g:Xpath = g:Xpath + g:Xnext * <count>
241 endif
243 com!                XloopNEXT   let g:Xnext = g:Xnext *
244                                     \ (g:Xskip ? 1 : g:Xfactor) |
245                                     \ let g:Xskip = 0
247 let @r = ""
248 let Xtest = 1
249 com! -count         Xcheck      let Xresult = "*** Test " .
250                                     \ (Xtest<10?"  ":Xtest<100?" ":"") .
251                                     \ Xtest . ": " . (
252                                     \ (Xpath==<count>) ? "OK (".Xpath.")" :
253                                         \ "FAIL (".Xpath." instead of <count>)"
254                                     \ ) |
255                                     \ let @R = Xresult . "\n" |
256                                     \ echo Xresult |
257                                     \ let Xtest = Xtest + 1
259 if exists("g:ExtraVimResult")
260     com! -nargs=+    Xoutq      exec "!echo @R:'" .
261                                     \ substitute(substitute(<q-args>,
262                                     \ "'", '&\\&&', "g"), "\n", "@NL@", "g")
263                                     \ . "' >>" . g:ExtraVimResult
264 else
265     com! -nargs=+    Xoutq      let @R = "--- Test " .
266                                     \ (g:Xtest<10?"  ":g:Xtest<100?" ":"") .
267                                     \ g:Xtest . ": " . substitute(<q-args>,
268                                     \ "\n", "&\t      ", "g") . "\n"
269 endif
270 com! -nargs=+       Xout        exec 'Xoutq' <args>
272 " Switch off storing of lines for undoing changes.  Speeds things up a little.
273 set undolevels=-1
275 " EXTRA_VIM_STOP - do not change or remove this line.
278 " ExtraVim() - Run a script file in an extra Vim process.                   {{{2
280 " This is useful for testing immediate abortion of the script processing due to
281 " an error in a command dynamically enclosed by a :try/:tryend region or when an
282 " exception is thrown but not caught or when an interrupt occurs.  It can also
283 " be used for testing :finish.
285 " An interrupt location can be specified by an "INTERRUPT" comment.  A number
286 " telling how often this location is reached (in a loop or in several function
287 " calls) should be specified as argument.  When missing, once per script
288 " invocation or function call is assumed.  INTERRUPT locations are tested by
289 " setting a breakpoint in that line and using the ">quit" debug command when
290 " the breakpoint is reached.  A function for which an INTERRUPT location is
291 " specified must be defined before calling it (or executing it as a script by
292 " using ExecAsScript below).
294 " This function is only called in normal modus ("g:ExtraVimResult" undefined).
296 " Tests to be executed as an extra script should be written as follows:
298 "       column 1                        column 1
299 "       |                               |
300 "       v                               v
302 "       XpathINIT                       XpathINIT
303 "       if ExtraVim()                   if ExtraVim()
304 "           ...                         "   ...
305 "           ...                         "   ...
306 "       endif                           endif
307 "       Xcheck <number>                 Xcheck <number>
309 " Double quotes in column 1 are removed before the script is executed.
310 " They should be used if the test has unbalanced conditionals (:if/:endif,
311 " :while:/endwhile, :try/:endtry) or for a line with a syntax error.  The
312 " extra script may use Xpath, XloopINIT, Xloop, XloopNEXT, and Xout as usual.
314 " A file name may be specified as argument.  All messages of the extra Vim
315 " process are then redirected to the file.  An existing file is overwritten.
317 let ExtraVimCount = 0
318 let ExtraVimBase = expand("<sfile>")
319 let ExtraVimTestEnv = ""
321 function! ExtraVim(...)
322     " Count how often this function is called.
323     let g:ExtraVimCount = g:ExtraVimCount + 1
325     " Disable folds to prevent that the ranges in the ":write" commands below
326     " are extended up to the end of a closed fold.  This also speeds things up
327     " considerably.
328     set nofoldenable
330     " Open a buffer for this test script and copy the test environment to
331     " a temporary file.  Take account of parts relevant for the extra script
332     " execution only.
333     let current_buffnr = bufnr("%")
334     execute "view +1" g:ExtraVimBase
335     if g:ExtraVimCount == 1
336         let g:ExtraVimTestEnv = tempname()
337         execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w"
338                     \ g:ExtraVimTestEnv "|']+"
339         execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>"
340                     \ g:ExtraVimTestEnv "|']+"
341         execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>"
342                     \ g:ExtraVimTestEnv "|']+"
343         execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>"
344                     \ g:ExtraVimTestEnv "|']+"
345     endif
347     " Start the extra Vim script with a ":source" command for the test
348     " environment.  The source line number where the extra script will be
349     " appended, needs to be passed as variable "ExtraVimBegin" to the script.
350     let extra_script = tempname()
351     exec "!echo 'source " . g:ExtraVimTestEnv . "' >" . extra_script
352     let extra_begin = 1
354     " Starting behind the test environment, skip over the first g:ExtraVimCount
355     " occurrences of "if ExtraVim()" and copy the following lines up to the
356     " matching "endif" to the extra Vim script.
357     execute "/E" . "ND_OF_TEST_ENVIRONMENT/"
358     exec 'norm ' . g:ExtraVimCount . '/^\s*if\s\+ExtraVim(.*)/+' . "\n"
359     execute ".,/^endif/-write >>" . extra_script
361     " Open a buffer for the extra Vim script, delete all ^", and write the
362     " script if was actually modified.
363     execute "edit +" . (extra_begin + 1) extra_script
364     ,$s/^"//e
365     update
367     " Count the INTERRUPTs and build the breakpoint and quit commands.
368     let breakpoints = ""
369     let debug_quits = ""
370     let in_func = 0
371     exec extra_begin
372     while search(
373             \ '"\s*INTERRUPT\h\@!\|^\s*fu\%[nction]\>!\=\s*\%(\u\|s:\)\w*\s*(\|'
374             \ . '^\s*\\\|^\s*endf\%[unction]\>\|'
375             \ . '\%(^\s*fu\%[nction]!\=\s*\)\@<!\%(\u\|s:\)\w*\s*(\|'
376             \ . 'ExecAsScript\s\+\%(\u\|s:\)\w*',
377             \ "W") > 0
378         let theline = getline(".")
379         if theline =~ '^\s*fu'
380             " Function definition.
381             let in_func = 1
382             let func_start = line(".")
383             let func_name = substitute(theline,
384                 \ '^\s*fu\%[nction]!\=\s*\(\%(\u\|s:\)\w*\).*', '\1', "")
385         elseif theline =~ '^\s*endf'
386             " End of function definition.
387             let in_func = 0
388         else
389             let finding = substitute(theline, '.*\(\%' . col(".") . 'c.*\)',
390                 \ '\1', "")
391             if finding =~ '^"\s*INTERRUPT\h\@!'
392                 " Interrupt comment.  Compose as many quit commands as
393                 " specified.
394                 let cnt = substitute(finding,
395                     \ '^"\s*INTERRUPT\s*\(\d*\).*$', '\1', "")
396                 let quits = ""
397                 while cnt > 0
398                     " Use "\r" rather than "\n" to separate the quit commands.
399                     " "\r" is not interpreted as command separator by the ":!"
400                     " command below but works to separate commands in the
401                     " external vim.
402                     let quits = quits . "q\r"
403                     let cnt = cnt - 1
404                 endwhile
405                 if in_func
406                     " Add the function breakpoint and note the number of quits
407                     " to be used, if specified, or one for every call else.
408                     let breakpoints = breakpoints . " -c 'breakadd func " .
409                         \ (line(".") - func_start) . " " .
410                         \ func_name . "'"
411                     if quits != ""
412                         let debug_quits = debug_quits . quits
413                     elseif !exists("quits{func_name}")
414                         let quits{func_name} = "q\r"
415                     else
416                         let quits{func_name} = quits{func_name} . "q\r"
417                     endif
418                 else
419                     " Add the file breakpoint and the quits to be used for it.
420                     let breakpoints = breakpoints . " -c 'breakadd file " .
421                         \ line(".") . " " . extra_script . "'"
422                     if quits == ""
423                         let quits = "q\r"
424                     endif
425                     let debug_quits = debug_quits . quits
426                 endif
427             else
428                 " Add the quits to be used for calling the function or executing
429                 " it as script file.
430                 if finding =~ '^ExecAsScript'
431                     " Sourcing function as script.
432                     let finding = substitute(finding,
433                         \ '^ExecAsScript\s\+\(\%(\u\|s:\)\w*\).*', '\1', "")
434                 else
435                     " Function call.
436                     let finding = substitute(finding,
437                         \ '^\(\%(\u\|s:\)\w*\).*', '\1', "")
438                 endif
439                 if exists("quits{finding}")
440                     let debug_quits = debug_quits . quits{finding}
441                 endif
442             endif
443         endif
444     endwhile
446     " Close the buffer for the script and create an (empty) resultfile.
447     bwipeout
448     let resultfile = tempname()
449     exec "!>" . resultfile
451     " Run the script in an extra vim.  Switch to extra modus by passing the
452     " resultfile in ExtraVimResult.  Redirect messages to the file specified as
453     " argument if any.  Use ":debuggreedy" so that the commands provided on the
454     " pipe are consumed at the debug prompt.  Use "-N" to enable command-line
455     " continuation ("C" in 'cpo').  Add "nviminfo" to 'viminfo' to avoid
456     " messing up the user's viminfo file.
457     let redirect = a:0 ?
458         \ " -c 'au VimLeave * redir END' -c 'redir\\! >" . a:1 . "'" : ""
459     exec "!echo '" . debug_quits . "q' | ../vim -u NONE -N -Xes" . redirect .
460         \ " -c 'debuggreedy|set viminfo+=nviminfo'" .
461         \ " -c 'let ExtraVimBegin = " . extra_begin . "'" .
462         \ " -c 'let ExtraVimResult = \"" . resultfile . "\"'" . breakpoints .
463         \ " -S " . extra_script
465     " Build the resulting sum for resultfile and add it to g:Xpath.  Add Xout
466     " information provided by the extra Vim process to the test output.
467     let sum = 0
468     exec "edit" resultfile
469     let line = 1
470     while line <= line("$")
471         let theline = getline(line)
472         if theline =~ '^@R:'
473             exec 'Xout "' . substitute(substitute(
474                 \ escape(escape(theline, '"'), '\"'),
475                 \ '^@R:', '', ""), '@NL@', "\n", "g") . '"'
476         else
477             let sum = sum + getline(line)
478         endif
479         let line = line + 1
480     endwhile
481     bwipeout
482     let g:Xpath = g:Xpath + sum
484     " Delete the extra script and the resultfile.
485     call delete(extra_script)
486     call delete(resultfile)
488     " Switch back to the buffer that was active when this function was entered.
489     exec "buffer" current_buffnr
491     " Return 0.  This protects extra scripts from being run in the main Vim
492     " process.
493     return 0
494 endfunction
497 " ExtraVimThrowpoint() - Relative throwpoint in ExtraVim script             {{{2
499 " Evaluates v:throwpoint and returns the throwpoint relative to the beginning of
500 " an ExtraVim script as passed by ExtraVim() in ExtraVimBegin.
502 " EXTRA_VIM_START - do not change or remove this line.
503 function! ExtraVimThrowpoint()
504     if !exists("g:ExtraVimBegin")
505         Xout "ExtraVimThrowpoint() used outside ExtraVim() script."
506         return v:throwpoint
507     endif
509     if v:throwpoint =~ '^function\>'
510         return v:throwpoint
511     endif
513     return "line " .
514         \ (substitute(v:throwpoint, '.*, line ', '', "") - g:ExtraVimBegin) .
515         \ " of ExtraVim() script"
516 endfunction
517 " EXTRA_VIM_STOP - do not change or remove this line.
520 " MakeScript() - Make a script file from a function.                        {{{2
522 " Create a script that consists of the body of the function a:funcname.
523 " Replace any ":return" by a ":finish", any argument variable by a global
524 " variable, and and every ":call" by a ":source" for the next following argument
525 " in the variable argument list.  This function is useful if similar tests are
526 " to be made for a ":return" from a function call or a ":finish" in a script
527 " file.
529 " In order to execute a function specifying an INTERRUPT location (see ExtraVim)
530 " as a script file, use ExecAsScript below.
532 " EXTRA_VIM_START - do not change or remove this line.
533 function! MakeScript(funcname, ...)
534     let script = tempname()
535     execute "redir! >" . script
536     execute "function" a:funcname
537     redir END
538     execute "edit" script
539     " Delete the "function" and the "endfunction" lines.  Do not include the
540     " word "function" in the pattern since it might be translated if LANG is
541     " set.  When MakeScript() is being debugged, this deletes also the debugging
542     " output of its line 3 and 4.
543     exec '1,/.*' . a:funcname . '(.*)/d'
544     /^\d*\s*endfunction\>/,$d
545     %s/^\d*//e
546     %s/return/finish/e
547     %s/\<a:\(\h\w*\)/g:\1/ge
548     normal gg0
549     let cnt = 0
550     while search('\<call\s*\%(\u\|s:\)\w*\s*(.*)', 'W') > 0
551         let cnt = cnt + 1
552         s/\<call\s*\%(\u\|s:\)\w*\s*(.*)/\='source ' . a:{cnt}/
553     endwhile
554     g/^\s*$/d
555     write
556     bwipeout
557     return script
558 endfunction
559 " EXTRA_VIM_STOP - do not change or remove this line.
562 " ExecAsScript - Source a temporary script made from a function.            {{{2
564 " Make a temporary script file from the function a:funcname, ":source" it, and
565 " delete it afterwards.
567 " When inside ":if ExtraVim()", add a file breakpoint for each INTERRUPT
568 " location specified in the function.
570 " EXTRA_VIM_START - do not change or remove this line.
571 function! ExecAsScript(funcname)
572     " Make a script from the function passed as argument.
573     let script = MakeScript(a:funcname)
575     " When running in an extra Vim process, add a file breakpoint for each
576     " function breakpoint set when the extra Vim process was invoked by
577     " ExtraVim().
578     if exists("g:ExtraVimResult")
579         let bplist = tempname()
580         execute "redir! >" . bplist
581         breaklist
582         redir END
583         execute "edit" bplist
584         " Get the line number from the function breakpoint.  Works also when
585         " LANG is set.
586         execute 'v/^\s*\d\+\s\+func\s\+' . a:funcname . '\s.*/d'
587         %s/^\s*\d\+\s\+func\s\+\%(\u\|s:\)\w*\s\D*\(\d*\).*/\1/e
588         let cnt = 0
589         while cnt < line("$")
590             let cnt = cnt + 1
591             if getline(cnt) != ""
592                 execute "breakadd file" getline(cnt) script
593             endif
594         endwhile
595         bwipeout!
596         call delete(bplist)
597     endif
599     " Source and delete the script.
600     exec "source" script
601     call delete(script)
602 endfunction
604 com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
605 " EXTRA_VIM_STOP - do not change or remove this line.
608 " END_OF_TEST_ENVIRONMENT - do not change or remove this line.
611 "-------------------------------------------------------------------------------
612 " Test 1:   :endwhile in function                                           {{{1
614 "           Detect if a broken loop is (incorrectly) reactivated by the
615 "           :endwhile.  Use a :return to prevent an endless loop, and make
616 "           this test first to get a meaningful result on an error before other
617 "           tests will hang.
618 "-------------------------------------------------------------------------------
620 XpathINIT
622 function! F()
623     Xpath 1                                     " X: 1
624     let first = 1
625     XloopINIT 2 8
626     while 1
627         Xloop 1                                 " X: 2      + 0 * 16
628         if first
629             Xloop 2                             " X: 4      + 0 * 32
630             let first = 0
631             XloopNEXT
632             break
633         else
634             Xloop 4                             " X: 0      + 0 * 64
635             return
636         endif
637     endwhile
638 endfunction
640 call F()
641 Xpath 128                                       " X: 128
643 function! G()
644     Xpath 256                                   " X: 256    + 0 * 2048
645     let first = 1
646     XloopINIT 512 8
647     while 1
648         Xloop 1                                 " X: 512    + 0 * 4096
649         if first
650             Xloop 2                             " X: 1024   + 0 * 8192
651             let first = 0
652             XloopNEXT
653             break
654         else
655             Xloop 4                             " X: 0      + 0 * 16384
656             return
657         endif
658         if 1    " unmatched :if
659     endwhile
660 endfunction
662 call G()
663 Xpath 32768                                     " X: 32768
665 Xcheck 34695
667 " Leave F and G for execution as scripts in the next test.
670 "-------------------------------------------------------------------------------
671 " Test 2:   :endwhile in script                                             {{{1
673 "           Detect if a broken loop is (incorrectly) reactivated by the
674 "           :endwhile.  Use a :finish to prevent an endless loop, and place
675 "           this test before others that might hang to get a meaningful result
676 "           on an error.
678 "           This test executes the bodies of the functions F and G from the
679 "           previous test as script files (:return replaced by :finish).
680 "-------------------------------------------------------------------------------
682 XpathINIT
684 ExecAsScript F                                  " X: 1 + 2 + 4
685 Xpath 128                                       " X: 128
687 ExecAsScript G                                  " X: 256 + 512 + 1024
688 Xpath 32768                                     " X: 32768
690 unlet first
691 delfunction F
692 delfunction G
694 Xcheck 34695
697 "-------------------------------------------------------------------------------
698 " Test 3:   :if, :elseif, :while, :continue, :break                         {{{1
699 "-------------------------------------------------------------------------------
701 XpathINIT
702 if 1
703     Xpath 1                                     " X: 1
704     let loops = 3
705     XloopINIT 2 512
706     while loops > -1        " main loop: loops == 3, 2, 1 (which breaks)
707         if loops <= 0
708             let break_err = 1
709             let loops = -1
710         else                                    "    3:  2:      1:
711             Xloop 1                             " X: 2 + 2*512 + 2*512*512
712         endif
713         if (loops == 2)
714             while loops == 2 " dummy loop
715                 Xloop 2                         " X:     4*512
716                 let loops = loops - 1
717                 continue    " stop dummy loop
718                 Xloop 4                         " X:     0
719             endwhile
720             XloopNEXT
721             continue        " continue main loop
722             Xloop 8                             " X:     0
723         elseif (loops == 1)
724             let p = 1
725             while p         " dummy loop
726                 Xloop 16                        " X:             32*512*512
727                 let p = 0
728                 break       " break dummy loop
729                 Xloop 32                        " X:             0
730             endwhile
731             Xloop 64                            " X:             128*512*512
732             unlet p
733             break           " break main loop
734             Xloop 128                           " X:             0
735         endif
736         if (loops > 0)
737             Xloop 256                           " X: 512
738         endif
739         while loops == 3    " dummy loop
740             let loops = loops - 1
741         endwhile            " end dummy loop
742         XloopNEXT
743     endwhile                " end main loop
744     Xpath 268435456                             " X: 1024*512*512
745 else
746     Xpath 536870912                             " X: 0
747 endif
748 Xpath 1073741824                                " X: 4096*512*512
749 if exists("break_err")
750     " The Xpath command does not accept 2^31 (negative); add explicitly:
751     let Xpath = Xpath + 2147483648              " X: 0
752     unlet break_err
753 endif
755 unlet loops
757 Xcheck 1384648195
760 "-------------------------------------------------------------------------------
761 " Test 4:   :return                                                         {{{1
762 "-------------------------------------------------------------------------------
764 XpathINIT
766 function! F()
767     if 1
768         Xpath 1                                 " X: 1
769         let loops = 3
770         XloopINIT 2 16
771         while loops > 0                         "    3:  2:     1:
772             Xloop 1                             " X: 2 + 2*16 + 0*16*16
773             if (loops == 2)
774                 Xloop 2                         " X:     4*16
775                 return
776                 Xloop 4                         " X:     0
777             endif
778             Xloop 8                             " X: 16
779             let loops = loops - 1
780             XloopNEXT
781         endwhile
782         Xpath 8192                              " X: 0
783     else
784         Xpath 16384                             " X: 0
785     endif
786 endfunction
788 call F()
789 Xpath 32768                                     " X: 8*16*16*16
791 Xcheck 32883
793 " Leave F for execution as a script in the next test.
796 "-------------------------------------------------------------------------------
797 " Test 5:   :finish                                                         {{{1
799 "           This test executes the body of the function F from the previous test
800 "           as a script file (:return replaced by :finish).
801 "-------------------------------------------------------------------------------
803 XpathINIT
805 ExecAsScript F                                  " X: 1 + 2 + 2*16 + 4*16 + 16
806 Xpath 32768                                     " X: 32768
808 unlet loops
809 delfunction F
811 Xcheck 32883
814 "-------------------------------------------------------------------------------
815 " Test 6:   Defining functions in :while loops                              {{{1
817 "            Functions can be defined inside other functions.  An inner function
818 "            gets defined when the outer function is executed.  Functions may
819 "            also be defined inside while loops.  Expressions in braces for
820 "            defining the function name are allowed.
821 "-------------------------------------------------------------------------------
823 XpathINIT
825 if ExtraVim()
827     " The command CALL collects the argument of all its invocations in "calls"
828     " when used from a function (that is, when the global variable "calls" needs
829     " the "g:" prefix).  This is to check that the function code is skipped when
830     " the function is defined.  For inner functions, do so only if the outer
831     " function is not being executed.
832     "
833     let calls = ""
834     com! -nargs=1 CALL
835                 \ if !exists("calls") && !exists("outer") |
836                 \ let g:calls = g:calls . <args> |
837                 \ endif
840     XloopINIT! 1 16
842     let i = 0
843     while i < 3
845         XloopNEXT
846         let i = i + 1
848         if i == 1
849             Xloop 1                             " X: 1
850             function! F1(arg)
851                 CALL a:arg
852                 let outer = 1
854                 XloopINIT! 4096 4
855                 let j = 0
856                 while j < 1
857                     XloopNEXT
858                     Xloop 1                     " X: 4096
859                     let j = j + 1
860                     function! G1(arg)
861                         CALL a:arg
862                     endfunction
863                     Xloop 2                     " X: 8192
864                 endwhile
865             endfunction
866             Xloop 2                             " X: 2
868             continue
869         endif
871         Xloop 4                                 " X: 4 * (16 + 256)
872         function! F{i}(i, arg)
873             CALL a:arg
874             let outer = 1
876             XloopINIT! 16384 4
877             if a:i == 3
878                 XloopNEXT
879                 XloopNEXT
880                 XloopNEXT
881             endif
882             let k = 0
883             while k < 3
884                 XloopNEXT
885                 Xloop 1                         " X: 16384*(1+4+16+64+256+1024)
886                 let k = k + 1
887                 function! G{a:i}{k}(arg)
888                     CALL a:arg
889                 endfunction
890                 Xloop 2                         " X: 32768*(1+4+16+64+256+1024)
891             endwhile
892         endfunction
893         Xloop 8                                 " X: 8 * (16 + 256)
895     endwhile
897     if exists("*G1")
898         Xpath 67108864                          " X: 0
899     endif
900     if exists("*F1")
901         call F1("F1")
902         if exists("*G1")
903             call G1("G1")
904         endif
905     endif
907     if exists("G21") || exists("G21") || exists("G21")
908         Xpath 134217728                         " X: 0
909     endif
910     if exists("*F2")
911         call F2(2, "F2")
912         if exists("*G21")
913             call G21("G21")
914         endif
915         if exists("*G22")
916             call G22("G22")
917         endif
918         if exists("*G23")
919             call G23("G23")
920         endif
921     endif
923     if exists("G31") || exists("G31") || exists("G31")
924         Xpath 268435456                         " X: 0
925     endif
926     if exists("*F3")
927         call F3(3, "F3")
928         if exists("*G31")
929             call G31("G31")
930         endif
931         if exists("*G32")
932             call G32("G32")
933         endif
934         if exists("*G33")
935             call G33("G33")
936         endif
937     endif
939     Xpath 536870912                             " X: 536870912
941     if calls != "F1G1F2G21G22G23F3G31G32G33"
942         Xpath 1073741824                        " X: 0
943         Xout "calls is" calls
944     endif
946     delfunction F1
947     delfunction G1
948     delfunction F2
949     delfunction G21
950     delfunction G22
951     delfunction G23
952     delfunction G31
953     delfunction G32
954     delfunction G33
956 endif
958 Xcheck 603978947
961 "-------------------------------------------------------------------------------
962 " Test 7:   Continuing on errors outside functions                          {{{1
964 "           On an error outside a function, the script processing continues
965 "           at the line following the outermost :endif or :endwhile.  When not
966 "           inside an :if or :while, the script processing continues at the next
967 "           line.
968 "-------------------------------------------------------------------------------
970 XpathINIT
972 if 1
973     Xpath 1                                     " X: 1
974     while 1
975         Xpath 2                                 " X: 2
976         asdf
977         Xpath 4                                 " X: 0
978         break
979     endwhile | Xpath 8                          " X: 0
980     Xpath 16                                    " X: 0
981 endif | Xpath 32                                " X: 0
982 Xpath 64                                        " X: 64
984 while 1
985     Xpath 128                                   " X: 128
986     if 1
987         Xpath 256                               " X: 256
988         asdf
989         Xpath 512                               " X: 0
990     endif | Xpath 1024                          " X: 0
991     Xpath 2048                                  " X: 0
992     break
993 endwhile | Xpath 4096                           " X: 0
994 Xpath 8192                                      " X: 8192
996 asdf
997 Xpath 16384                                     " X: 16384
999 asdf | Xpath 32768                              " X: 0
1000 Xpath 65536                                     " X: 65536
1002 Xcheck 90563
1005 "-------------------------------------------------------------------------------
1006 " Test 8:   Aborting and continuing on errors inside functions              {{{1
1008 "           On an error inside a function without the "abort" attribute, the
1009 "           script processing continues at the next line (unless the error was
1010 "           in a :return command).  On an error inside a function with the
1011 "           "abort" attribute, the function is aborted and the script processing
1012 "           continues after the function call; the value -1 is returned then.
1013 "-------------------------------------------------------------------------------
1015 XpathINIT
1017 function! F()
1018     if 1
1019         Xpath 1                                 " X: 1
1020         while 1
1021             Xpath 2                             " X: 2
1022             asdf
1023             Xpath 4                             " X: 4
1024             asdf | Xpath 8                      " X: 0
1025             Xpath 16                            " X: 16
1026             break
1027         endwhile
1028         Xpath 32                                " X: 32
1029     endif | Xpath 64                            " X: 64
1030     Xpath 128                                   " X: 128
1032     while 1
1033         Xpath 256                               " X: 256
1034         if 1
1035             Xpath 512                           " X: 512
1036             asdf
1037             Xpath 1024                          " X: 1024
1038             asdf | Xpath 2048                   " X: 0
1039             Xpath 4096                          " X: 4096
1040         endif
1041         Xpath 8192                              " X: 8192
1042         break
1043     endwhile | Xpath 16384                      " X: 16384
1044     Xpath 32768                                 " X: 32768
1046     return novar                " returns (default return value 0)
1047     Xpath 65536                                 " X: 0
1048     return 1                    " not reached
1049 endfunction
1051 function! G() abort
1052     if 1
1053         Xpath 131072                            " X: 131072
1054         while 1
1055             Xpath 262144                        " X: 262144
1056             asdf                " returns -1
1057             Xpath 524288                        " X: 0
1058             break
1059         endwhile
1060         Xpath 1048576                           " X: 0
1061     endif | Xpath 2097152                       " X: 0
1062     Xpath Xpath 4194304                         " X: 0
1064     return -4                   " not reached
1065 endfunction
1067 function! H() abort
1068     while 1
1069         Xpath 8388608                           " X: 8388608
1070         if 1
1071             Xpath 16777216                      " X: 16777216
1072             asdf                " returns -1
1073             Xpath 33554432                      " X: 0
1074         endif
1075         Xpath 67108864                          " X: 0
1076         break
1077     endwhile | Xpath 134217728                  " X: 0
1078     Xpath 268435456                             " X: 0
1080     return -4                   " not reached
1081 endfunction
1083 " Aborted functions (G and H) return -1.
1084 let sum = (F() + 1) - 4*G() - 8*H()
1085 Xpath 536870912                                 " X: 536870912
1086 if sum != 13
1087     Xpath 1073741824                            " X: 0
1088     Xout "sum is" sum
1089 endif
1091 unlet sum
1092 delfunction F
1093 delfunction G
1094 delfunction H
1096 Xcheck 562493431
1099 "-------------------------------------------------------------------------------
1100 " Test 9:   Continuing after aborted functions                              {{{1
1102 "           When a function with the "abort" attribute is aborted due to an
1103 "           error, the next function back in the call hierarchy without an
1104 "           "abort" attribute continues; the value -1 is returned then.
1105 "-------------------------------------------------------------------------------
1107 XpathINIT
1109 function! F() abort
1110     Xpath 1                                     " X: 1
1111     let result = G()    " not aborted
1112     Xpath 2                                     " X: 2
1113     if result != 2
1114         Xpath 4                                 " X: 0
1115     endif
1116     return 1
1117 endfunction
1119 function! G()           " no abort attribute
1120     Xpath 8                                     " X: 8
1121     if H() != -1        " aborted
1122         Xpath 16                                " X: 0
1123     endif
1124     Xpath 32                                    " X: 32
1125     return 2
1126 endfunction
1128 function! H() abort
1129     Xpath 64                                    " X: 64
1130     call I()            " aborted
1131     Xpath 128                                   " X: 0
1132     return 4
1133 endfunction
1135 function! I() abort
1136     Xpath 256                                   " X: 256
1137     asdf                " error
1138     Xpath 512                                   " X: 0
1139     return 8
1140 endfunction
1142 if F() != 1
1143     Xpath 1024                                  " X: 0
1144 endif
1146 delfunction F
1147 delfunction G
1148 delfunction H
1149 delfunction I
1151 Xcheck 363
1154 "-------------------------------------------------------------------------------
1155 " Test 10:  :if, :elseif, :while argument parsing                           {{{1
1157 "           A '"' or '|' in an argument expression must not be mixed up with
1158 "           a comment or a next command after a bar.  Parsing errors should
1159 "           be recognized.
1160 "-------------------------------------------------------------------------------
1162 XpathINIT
1164 function! MSG(enr, emsg)
1165     let english = v:lang == "C" || v:lang =~ '^[Ee]n'
1166     if a:enr == ""
1167         Xout "TODO: Add message number for:" a:emsg
1168         let v:errmsg = ":" . v:errmsg
1169     endif
1170     let match = 1
1171     if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
1172         let match = 0
1173         if v:errmsg == ""
1174             Xout "Message missing."
1175         else
1176             let v:errmsg = escape(v:errmsg, '"')
1177             Xout "Unexpected message:" v:errmsg
1178         endif
1179     endif
1180     return match
1181 endfunction
1183 if 1 || strlen("\"") | Xpath 1                  " X: 1
1184     Xpath 2                                     " X: 2
1185 endif
1186 Xpath 4                                         " X: 4
1188 if 0
1189 elseif 1 || strlen("\"") | Xpath 8              " X: 8
1190     Xpath 16                                    " X: 16
1191 endif
1192 Xpath 32                                        " X: 32
1194 while 1 || strlen("\"") | Xpath 64              " X: 64
1195     Xpath 128                                   " X: 128
1196     break
1197 endwhile
1198 Xpath 256                                       " X: 256
1200 let v:errmsg = ""
1201 if 1 ||| strlen("\"") | Xpath 512               " X: 0
1202     Xpath 1024                                  " X: 0
1203 endif
1204 Xpath 2048                                      " X: 2048
1205 if !MSG('E15', "Invalid expression")
1206     Xpath 4096                                  " X: 0
1207 endif
1209 let v:errmsg = ""
1210 if 0
1211 elseif 1 ||| strlen("\"") | Xpath 8192          " X: 0
1212     Xpath 16384                                 " X: 0
1213 endif
1214 Xpath 32768                                     " X: 32768
1215 if !MSG('E15', "Invalid expression")
1216     Xpath 65536                                 " X: 0
1217 endif
1219 let v:errmsg = ""
1220 while 1 ||| strlen("\"") | Xpath 131072         " X: 0
1221     Xpath 262144                                " X: 0
1222     break
1223 endwhile
1224 Xpath 524288                                    " X: 524288
1225 if !MSG('E15', "Invalid expression")
1226     Xpath 1048576                               " X: 0
1227 endif
1229 delfunction MSG
1231 Xcheck 559615
1234 "-------------------------------------------------------------------------------
1235 " Test 11:  :if, :elseif, :while argument evaluation after abort            {{{1
1237 "           When code is skipped over due to an error, the boolean argument to
1238 "           an :if, :elseif, or :while must not be evaluated.
1239 "-------------------------------------------------------------------------------
1241 XpathINIT
1243 let calls = 0
1245 function! P(num)
1246     let g:calls = g:calls + a:num   " side effect on call
1247     return 0
1248 endfunction
1250 if 1
1251     Xpath 1                                     " X: 1
1252     asdf                " error
1253     Xpath 2                                     " X: 0
1254     if P(1)             " should not be called
1255         Xpath 4                                 " X: 0
1256     elseif !P(2)        " should not be called
1257         Xpath 8                                 " X: 0
1258     else
1259         Xpath 16                                " X: 0
1260     endif
1261     Xpath 32                                    " X: 0
1262     while P(4)          " should not be called
1263         Xpath 64                                " X: 0
1264     endwhile
1265     Xpath 128                                   " X: 0
1266 endif
1268 if calls % 2
1269     Xpath 256                                   " X: 0
1270 endif
1271 if (calls/2) % 2
1272     Xpath 512                                   " X: 0
1273 endif
1274 if (calls/4) % 2
1275     Xpath 1024                                  " X: 0
1276 endif
1277 Xpath 2048                                      " X: 2048
1279 unlet calls
1280 delfunction P
1282 Xcheck 2049
1285 "-------------------------------------------------------------------------------
1286 " Test 12:  Expressions in braces in skipped code                           {{{1
1288 "           In code skipped over due to an error or inactive conditional,
1289 "           an expression in braces as part of a variable or function name
1290 "           should not be evaluated.
1291 "-------------------------------------------------------------------------------
1293 XpathINIT
1295 XloopINIT 1 8
1297 function! NULL()
1298     Xloop 1                                     " X: 0
1299     return 0
1300 endfunction
1302 function! ZERO()
1303     Xloop 2                                     " X: 0
1304     return 0
1305 endfunction
1307 function! F0()
1308     Xloop 4                                     " X: 0
1309 endfunction
1311 function! F1(arg)
1312     Xpath 4096                                  " X: 0
1313 endfunction
1315 let V0 = 1
1317 Xpath 8192                                      " X: 8192
1318 echo 0 ? F{NULL() + V{ZERO()}}() : 1
1319 XloopNEXT
1321 Xpath 16384                                     " X: 16384
1322 if 0
1323     Xpath 32768                                 " X: 0
1324     call F{NULL() + V{ZERO()}}()
1325 endif
1326 XloopNEXT
1328 Xpath 65536                                     " X: 65536
1329 if 1
1330     asdf                " error
1331     Xpath 131072                                " X: 0
1332     call F1(F{NULL() + V{ZERO()}}())
1333 endif
1334 XloopNEXT
1336 Xpath 262144                                    " X: 262144
1337 if 1
1338     asdf                " error
1339     Xpath 524288                                " X: 0
1340     call F{NULL() + V{ZERO()}}()
1341 endif
1343 Xcheck 352256
1346 "-------------------------------------------------------------------------------
1347 " Test 13:  Failure in argument evaluation for :while                       {{{1
1349 "           A failure in the expression evaluation for the condition of a :while
1350 "           causes the whole :while loop until the matching :endwhile being
1351 "           ignored.  Continuation is at the next following line.
1352 "-------------------------------------------------------------------------------
1354 XpathINIT
1356 Xpath 1                                         " X: 1
1357 while asdf
1358     Xpath 2                                     " X: 0
1359     while 1
1360         Xpath 4                                 " X: 0
1361         break
1362     endwhile
1363     Xpath 8                                     " X: 0
1364     break
1365 endwhile
1366 Xpath 16                                        " X: 16
1368 while asdf | Xpath 32 | endwhile | Xpath 64     " X: 0
1369 Xpath 128                                       " X: 128
1371 Xcheck 145
1374 "-------------------------------------------------------------------------------
1375 " Test 14:  Failure in argument evaluation for :if                          {{{1
1377 "           A failure in the expression evaluation for the condition of an :if
1378 "           does not cause the corresponding :else or :endif being matched to
1379 "           a previous :if/:elseif.  Neither of both branches of the failed :if
1380 "           are executed.
1381 "-------------------------------------------------------------------------------
1383 XpathINIT
1384 XloopINIT 1 256
1386 function! F()
1387     Xloop 1                                     " X: 1      + 256 * 1
1388     let x = 0
1389     if x                " false
1390         Xloop 2                                 " X: 0      + 256 * 0
1391     elseif !x           " always true
1392         Xloop 4                                 " X: 4      + 256 * 4
1393         let x = 1
1394         if g:boolvar    " possibly undefined
1395             Xloop 8                             " X: 8      + 256 * 0
1396         else
1397             Xloop 16                            " X: 0      + 256 * 0
1398         endif
1399         Xloop 32                                " X: 32     + 256 * 32
1400     elseif x            " never executed
1401         Xloop 64                                " X: 0      + 256 * 0
1402     endif
1403     Xloop 128                                   " X: 128    + 256 * 128
1404 endfunction
1406 let boolvar = 1
1407 call F()
1409 XloopNEXT
1410 unlet boolvar
1411 call F()
1413 delfunction F
1415 Xcheck 42413
1418 "-------------------------------------------------------------------------------
1419 " Test 15:  Failure in argument evaluation for :if (bar)                    {{{1
1421 "           Like previous test, except that the failing :if ... | ... | :endif
1422 "           is in a single line.
1423 "-------------------------------------------------------------------------------
1425 XpathINIT
1426 XloopINIT 1 256
1428 function! F()
1429     Xloop 1                                     " X: 1      + 256 * 1
1430     let x = 0
1431     if x                " false
1432         Xloop 2                                 " X: 0      + 256 * 0
1433     elseif !x           " always true
1434         Xloop 4                                 " X: 4      + 256 * 4
1435         let x = 1
1436         if g:boolvar | Xloop 8 | else | Xloop 16 | endif    " X: 8
1437         Xloop 32                                " X: 32     + 256 * 32
1438     elseif x            " never executed
1439         Xloop 64                                " X: 0      + 256 * 0
1440     endif
1441     Xloop 128                                   " X: 128    + 256 * 128
1442 endfunction
1444 let boolvar = 1
1445 call F()
1447 XloopNEXT
1448 unlet boolvar
1449 call F()
1451 delfunction F
1453 Xcheck 42413
1456 "-------------------------------------------------------------------------------
1457 " Test 16:  Double :else or :elseif after :else                             {{{1
1459 "           Multiple :elses or an :elseif after an :else are forbidden.
1460 "-------------------------------------------------------------------------------
1462 XpathINIT
1464 function! F() abort
1465     if 0
1466         Xpath 1                                 " X: 0
1467     else
1468         Xpath 2                                 " X: 2
1469     else                " aborts function
1470         Xpath 4                                 " X: 0
1471     endif
1472 endfunction
1474 function! G() abort
1475     if 0
1476         Xpath 8                                 " X: 0
1477     else
1478         Xpath 16                                " X: 16
1479     elseif 1            " aborts function
1480         Xpath 32                                " X: 0
1481     else
1482         Xpath 64                                " X: 0
1483     endif
1484 endfunction
1486 function! H() abort
1487     if 0
1488         Xpath 128                               " X: 0
1489     elseif 0
1490         Xpath 256                               " X: 0
1491     else
1492         Xpath 512                               " X: 512
1493     else                " aborts function
1494         Xpath 1024                              " X: 0
1495     endif
1496 endfunction
1498 function! I() abort
1499     if 0
1500         Xpath 2048                              " X: 0
1501     elseif 0
1502         Xpath 4096                              " X: 0
1503     else
1504         Xpath 8192                              " X: 8192
1505     elseif 1            " aborts function
1506         Xpath 16384                             " X: 0
1507     else
1508         Xpath 32768                             " X: 0
1509     endif
1510 endfunction
1512 call F()
1513 call G()
1514 call H()
1515 call I()
1517 delfunction F
1518 delfunction G
1519 delfunction H
1520 delfunction I
1522 Xcheck 8722
1525 "-------------------------------------------------------------------------------
1526 " Test 17:  Nesting of unmatched :if or :endif inside a :while              {{{1
1528 "           The :while/:endwhile takes precedence in nesting over an unclosed
1529 "           :if or an unopened :endif.
1530 "-------------------------------------------------------------------------------
1532 XpathINIT
1534 function! MSG(enr, emsg)
1535     let english = v:lang == "C" || v:lang =~ '^[Ee]n'
1536     if a:enr == ""
1537         Xout "TODO: Add message number for:" a:emsg
1538         let v:errmsg = ":" . v:errmsg
1539     endif
1540     let match = 1
1541     if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
1542         let match = 0
1543         if v:errmsg == ""
1544             Xout "Message missing."
1545         else
1546             let v:errmsg = escape(v:errmsg, '"')
1547             Xout "Unexpected message:" v:errmsg
1548         endif
1549     endif
1550     return match
1551 endfunction
1553 let messages = ""
1555 " While loops inside a function are continued on error.
1556 function! F()
1557     let v:errmsg = ""
1558     XloopINIT 1 16
1559     let loops = 3
1560     while loops > 0
1561         let loops = loops - 1                   "    2:  1:     0:
1562         Xloop 1                                 " X: 1 + 1*16 + 1*16*16
1563         if (loops == 1)
1564             Xloop 2                             " X:     2*16
1565             XloopNEXT
1566             continue
1567         elseif (loops == 0)
1568             Xloop 4                             " X:            4*16*16
1569             break
1570         elseif 1
1571             Xloop 8                             " X: 8
1572             XloopNEXT
1573         " endif missing!
1574     endwhile    " :endwhile after :if 1
1575     Xpath 4096                                  " X: 16*16*16
1576     if MSG('E171', "Missing :endif")
1577         let g:messages = g:messages . "A"
1578     endif
1580     let v:errmsg = ""
1581     XloopINIT! 8192 4
1582     let loops = 2
1583     while loops > 0                             "    2:     1:
1584         XloopNEXT
1585         let loops = loops - 1
1586         Xloop 1                                 " X: 8192 + 8192*4
1587         if 0
1588             Xloop 2                             " X: 0
1589         " endif missing
1590     endwhile    " :endwhile after :if 0
1591     Xpath 131072                                " X: 8192*4*4
1592     if MSG('E171', "Missing :endif")
1593         let g:messages = g:messages . "B"
1594     endif
1596     let v:errmsg = ""
1597     XloopINIT 262144 4
1598     let loops = 2
1599     while loops > 0                             "    2:     1:
1600         let loops = loops - 1
1601         Xloop 1                                 " X: 262144 + 262144 * 4
1602         " if missing!
1603         endif   " :endif without :if in while
1604         Xloop 2                                 " X: 524288 + 524288 * 4
1605         XloopNEXT
1606     endwhile
1607     Xpath 4194304                               " X: 262144*4*4
1608     if MSG('E580', ":endif without :if")
1609         let g:messages = g:messages . "C"
1610     endif
1611 endfunction
1613 call F()
1615 " Error continuation outside a function is at the outermost :endwhile or :endif.
1616 let v:errmsg = ""
1617 XloopINIT! 8388608 4
1618 let loops = 2
1619 while loops > 0                                 "    2:         1:
1620     XloopNEXT
1621     let loops = loops - 1
1622     Xloop 1                                     " X: 8388608 + 0 * 4
1623     if 0
1624         Xloop 2                                 " X: 0
1625     " endif missing! Following :endwhile fails.
1626 endwhile | Xpath 134217728                      " X: 0
1627 Xpath 268435456                                 " X: 2*8388608*4*4
1628 if MSG('E171', "Missing :endif")
1629     let messages = g:messages . "D"
1630 endif
1632 if messages != "ABCD"
1633     Xpath 536870912                             " X: 0
1634     Xout "messages is" messages "instead of ABCD"
1635 endif
1637 unlet loops messages
1638 delfunction F
1639 delfunction MSG
1641 Xcheck 285127993
1644 "-------------------------------------------------------------------------------
1645 " Test 18:  Interrupt (Ctrl-C pressed)                                      {{{1
1647 "           On an interrupt, the script processing is terminated immediately.
1648 "-------------------------------------------------------------------------------
1650 XpathINIT
1652 if ExtraVim()
1653     if 1
1654         Xpath 1                                 " X: 1
1655         while 1
1656             Xpath 2                             " X: 2
1657             if 1
1658                 Xpath 4                         " X: 4
1659                 "INTERRUPT
1660                 Xpath 8                         " X: 0
1661                 break
1662                 finish
1663             endif | Xpath 16                    " X: 0
1664             Xpath 32                            " X: 0
1665         endwhile | Xpath 64                     " X: 0
1666         Xpath 128                               " X: 0
1667     endif | Xpath 256                           " X: 0
1668     Xpath 512                                   " X: 0
1669 endif
1671 if ExtraVim()
1672     try
1673         Xpath 1024                              " X: 1024
1674         "INTERRUPT
1675         Xpath 2048                              " X: 0
1676     endtry | Xpath 4096                         " X: 0
1677     Xpath 8192                                  " X: 0
1678 endif
1680 if ExtraVim()
1681     function! F()
1682         if 1
1683             Xpath 16384                         " X: 16384
1684             while 1
1685                 Xpath 32768                     " X: 32768
1686                 if 1
1687                     Xpath 65536                 " X: 65536
1688                     "INTERRUPT
1689                     Xpath 131072                " X: 0
1690                     break
1691                     return
1692                 endif | Xpath 262144            " X: 0
1693                 Xpath Xpath 524288              " X: 0
1694             endwhile | Xpath 1048576            " X: 0
1695             Xpath Xpath 2097152                 " X: 0
1696         endif | Xpath Xpath 4194304             " X: 0
1697         Xpath Xpath 8388608                     " X: 0
1698     endfunction
1700     call F() | Xpath 16777216                   " X: 0
1701     Xpath 33554432                              " X: 0
1702 endif
1704 if ExtraVim()
1705     function! G()
1706         try
1707             Xpath 67108864                      " X: 67108864
1708             "INTERRUPT
1709             Xpath 134217728                     " X: 0
1710         endtry | Xpath 268435456                " X: 0
1711         Xpath 536870912                         " X: 0
1712     endfunction
1714     call G() | Xpath 1073741824                 " X: 0
1715     " The Xpath command does not accept 2^31 (negative); display explicitly:
1716     exec "!echo 2147483648 >>" . g:ExtraVimResult
1717                                                 " X: 0
1718 endif
1720 Xcheck 67224583
1723 "-------------------------------------------------------------------------------
1724 " Test 19:  Aborting on errors inside :try/:endtry                          {{{1
1726 "           An error in a command dynamically enclosed in a :try/:endtry region
1727 "           aborts script processing immediately.  It does not matter whether
1728 "           the failing command is outside or inside a function and whether a
1729 "           function has an "abort" attribute.
1730 "-------------------------------------------------------------------------------
1732 XpathINIT
1734 if ExtraVim()
1735     function! F() abort
1736         Xpath 1                                 " X: 1
1737         asdf
1738         Xpath 2                                 " X: 0
1739     endfunction
1741     try
1742         Xpath 4                                 " X: 4
1743         call F()
1744         Xpath 8                                 " X: 0
1745     endtry | Xpath 16                           " X: 0
1746     Xpath 32                                    " X: 0
1747 endif
1749 if ExtraVim()
1750     function! G()
1751         Xpath 64                                " X: 64
1752         asdf
1753         Xpath 128                               " X: 0
1754     endfunction
1756     try
1757         Xpath 256                               " X: 256
1758         call G()
1759         Xpath 512                               " X: 0
1760     endtry | Xpath 1024                         " X: 0
1761     Xpath 2048                                  " X: 0
1762 endif
1764 if ExtraVim()
1765     try
1766         Xpath 4096                              " X: 4096
1767         asdf
1768         Xpath 8192                              " X: 0
1769     endtry | Xpath 16384                        " X: 0
1770     Xpath 32768                                 " X: 0
1771 endif
1773 if ExtraVim()
1774     if 1
1775         try
1776             Xpath 65536                         " X: 65536
1777             asdf
1778             Xpath 131072                        " X: 0
1779         endtry | Xpath 262144                   " X: 0
1780     endif | Xpath 524288                        " X: 0
1781     Xpath 1048576                               " X: 0
1782 endif
1784 if ExtraVim()
1785     let p = 1
1786     while p
1787         let p = 0
1788         try
1789             Xpath 2097152                       " X: 2097152
1790             asdf
1791             Xpath 4194304                       " X: 0
1792         endtry | Xpath 8388608                  " X: 0
1793     endwhile | Xpath 16777216                   " X: 0
1794     Xpath 33554432                              " X: 0
1795 endif
1797 if ExtraVim()
1798     let p = 1
1799     while p
1800         let p = 0
1801 "       try
1802             Xpath 67108864                      " X: 67108864
1803     endwhile | Xpath 134217728                  " X: 0
1804     Xpath 268435456                             " X: 0
1805 endif
1807 Xcheck 69275973
1808 "-------------------------------------------------------------------------------
1809 " Test 20:  Aborting on errors after :try/:endtry                           {{{1
1811 "           When an error occurs after the last active :try/:endtry region has
1812 "           been left, termination behavior is as if no :try/:endtry has been
1813 "           seen.
1814 "-------------------------------------------------------------------------------
1816 XpathINIT
1818 if ExtraVim()
1819     let p = 1
1820     while p
1821         let p = 0
1822         try
1823             Xpath 1                             " X: 1
1824         endtry
1825         asdf
1826     endwhile | Xpath 2                          " X: 0
1827     Xpath 4                                     " X: 4
1828 endif
1830 if ExtraVim()
1831     while 1
1832         try
1833             Xpath 8                             " X: 8
1834             break
1835             Xpath 16                            " X: 0
1836         endtry
1837     endwhile
1838     Xpath 32                                    " X: 32
1839     asdf
1840     Xpath 64                                    " X: 64
1841 endif
1843 if ExtraVim()
1844     while 1
1845         try
1846             Xpath 128                           " X: 128
1847             break
1848             Xpath 256                           " X: 0
1849         finally
1850             Xpath 512                           " X: 512
1851         endtry
1852     endwhile
1853     Xpath 1024                                  " X: 1024
1854     asdf
1855     Xpath 2048                                  " X: 2048
1856 endif
1858 if ExtraVim()
1859     while 1
1860         try
1861             Xpath 4096                          " X: 4096
1862         finally
1863             Xpath 8192                          " X: 8192
1864             break
1865             Xpath 16384                         " X: 0
1866         endtry
1867     endwhile
1868     Xpath 32768                                 " X: 32768
1869     asdf
1870     Xpath 65536                                 " X: 65536
1871 endif
1873 if ExtraVim()
1874     let p = 1
1875     while p
1876         let p = 0
1877         try
1878             Xpath 131072                        " X: 131072
1879             continue
1880             Xpath 262144                        " X: 0
1881         endtry
1882     endwhile
1883     Xpath 524288                                " X: 524288
1884     asdf
1885     Xpath 1048576                               " X: 1048576
1886 endif
1888 if ExtraVim()
1889     let p = 1
1890     while p
1891         let p = 0
1892         try
1893             Xpath 2097152                       " X: 2097152
1894             continue
1895             Xpath 4194304                       " X: 0
1896         finally
1897             Xpath 8388608                       " X: 8388608
1898         endtry
1899     endwhile
1900     Xpath 16777216                              " X: 16777216
1901     asdf
1902     Xpath 33554432                              " X: 33554432
1903 endif
1905 if ExtraVim()
1906     let p = 1
1907     while p
1908         let p = 0
1909         try
1910             Xpath 67108864                      " X: 67108864
1911         finally
1912             Xpath 134217728                     " X: 134217728
1913             continue
1914             Xpath 268435456                     " X: 0
1915         endtry
1916     endwhile
1917     Xpath 536870912                             " X: 536870912
1918     asdf
1919     Xpath 1073741824                            " X: 1073741824
1920 endif
1922 Xcheck 1874575085
1925 "-------------------------------------------------------------------------------
1926 " Test 21:  :finally for :try after :continue/:break/:return/:finish        {{{1
1928 "           If a :try conditional stays inactive due to a preceding :continue,
1929 "           :break, :return, or :finish, its :finally clause should not be
1930 "           executed.
1931 "-------------------------------------------------------------------------------
1933 XpathINIT
1935 if ExtraVim()
1936     function F()
1937         let loops = 2
1938         XloopINIT! 1 256
1939         while loops > 0
1940             XloopNEXT
1941             let loops = loops - 1
1942             try
1943                 if loops == 1
1944                     Xloop 1                     " X: 1
1945                     continue
1946                     Xloop 2                     " X: 0
1947                 elseif loops == 0
1948                     Xloop 4                     " X: 4*256
1949                     break
1950                     Xloop 8                     " X: 0
1951                 endif
1953                 try             " inactive
1954                     Xloop 16                    " X: 0
1955                 finally
1956                     Xloop 32                    " X: 0
1957                 endtry
1958             finally
1959                 Xloop 64                        " X: 64 + 64*256
1960             endtry
1961             Xloop 128                           " X: 0
1962         endwhile
1964         try
1965             Xpath 65536                         " X: 65536
1966             return
1967             Xpath 131072                        " X: 0
1968             try             " inactive
1969                 Xpath 262144                    " X: 0
1970             finally
1971                 Xpath 524288                    " X: 0
1972             endtry
1973         finally
1974             Xpath 1048576                       " X: 1048576
1975         endtry
1976         Xpath 2097152                           " X: 0
1977     endfunction
1979     try
1980         Xpath 4194304                           " X: 4194304
1981         call F()
1982         Xpath 8388608                           " X: 8388608
1983         finish
1984         Xpath 16777216                          " X: 0
1985         try             " inactive
1986             Xpath 33554432                      " X: 0
1987         finally
1988             Xpath 67108864                      " X: 0
1989         endtry
1990     finally
1991         Xpath 134217728                         " X: 134217728
1992     endtry
1993     Xpath 268435456                             " X: 0
1994 endif
1996 Xcheck 147932225
1999 "-------------------------------------------------------------------------------
2000 " Test 22:  :finally for a :try after an error/interrupt/:throw             {{{1
2002 "           If a :try conditional stays inactive due to a preceding error or
2003 "           interrupt or :throw, its :finally clause should not be executed.
2004 "-------------------------------------------------------------------------------
2006 XpathINIT
2008 if ExtraVim()
2009     function! Error()
2010         try
2011             asdf    " aborting error, triggering error exception
2012         endtry
2013     endfunction
2015     Xpath 1                                     " X: 1
2016     call Error()
2017     Xpath 2                                     " X: 0
2019     if 1        " not active due to error
2020         try     " not active since :if inactive
2021             Xpath 4                             " X: 0
2022         finally
2023             Xpath 8                             " X: 0
2024         endtry
2025     endif
2027     try         " not active due to error
2028         Xpath 16                                " X: 0
2029     finally
2030         Xpath 32                                " X: 0
2031     endtry
2032 endif
2034 if ExtraVim()
2035     function! Interrupt()
2036         try
2037             "INTERRUPT  " triggering interrupt exception
2038         endtry
2039     endfunction
2041     Xpath 64                                    " X: 64
2042     call Interrupt()
2043     Xpath 128                                   " X: 0
2045     if 1        " not active due to interrupt
2046         try     " not active since :if inactive
2047             Xpath 256                           " X: 0
2048         finally
2049             Xpath 512                           " X: 0
2050         endtry
2051     endif
2053     try         " not active due to interrupt
2054         Xpath 1024                              " X: 0
2055     finally
2056         Xpath 2048                              " X: 0
2057     endtry
2058 endif
2060 if ExtraVim()
2061     function! Throw()
2062         throw "xyz"
2063     endfunction
2065     Xpath 4096                                  " X: 4096
2066     call Throw()
2067     Xpath 8192                                  " X: 0
2069     if 1        " not active due to :throw
2070         try     " not active since :if inactive
2071             Xpath 16384                         " X: 0
2072         finally
2073             Xpath 32768                         " X: 0
2074         endtry
2075     endif
2077     try         " not active due to :throw
2078         Xpath 65536                             " X: 0
2079     finally
2080         Xpath 131072                            " X: 0
2081     endtry
2082 endif
2084 Xcheck 4161
2087 "-------------------------------------------------------------------------------
2088 " Test 23:  :catch clauses for a :try after a :throw                        {{{1
2090 "           If a :try conditional stays inactive due to a preceding :throw,
2091 "           none of its :catch clauses should be executed.
2092 "-------------------------------------------------------------------------------
2094 XpathINIT
2096 if ExtraVim()
2097     try
2098         Xpath 1                                 " X: 1
2099         throw "xyz"
2100         Xpath 2                                 " X: 0
2102         if 1    " not active due to :throw
2103             try " not active since :if inactive
2104                 Xpath 4                         " X: 0
2105             catch /xyz/
2106                 Xpath 8                         " X: 0
2107             endtry
2108         endif
2109     catch /xyz/
2110         Xpath 16                                " X: 16
2111     endtry
2113     Xpath 32                                    " X: 32
2114     throw "abc"
2115     Xpath 64                                    " X: 0
2117     try         " not active due to :throw
2118         Xpath 128                               " X: 0
2119     catch /abc/
2120         Xpath 256                               " X: 0
2121     endtry
2122 endif
2124 Xcheck 49
2127 "-------------------------------------------------------------------------------
2128 " Test 24:  :endtry for a :try after a :throw                               {{{1
2130 "           If a :try conditional stays inactive due to a preceding :throw,
2131 "           its :endtry should not rethrow the exception to the next surrounding
2132 "           active :try conditional.
2133 "-------------------------------------------------------------------------------
2135 XpathINIT
2137 if ExtraVim()
2138     try                 " try 1
2139         try             " try 2
2140             Xpath 1                             " X: 1
2141             throw "xyz" " makes try 2 inactive
2142             Xpath 2                             " X: 0
2144             try         " try 3
2145                 Xpath 4                         " X: 0
2146             endtry      " no rethrow to try 1
2147         catch /xyz/     " should catch although try 2 inactive
2148             Xpath 8                             " X: 8
2149         endtry
2150     catch /xyz/         " try 1 active, but exception already caught
2151         Xpath 16                                " X: 0
2152     endtry
2153     Xpath 32                                    " X: 32
2154 endif
2156 Xcheck 41
2159 "-------------------------------------------------------------------------------
2160 " Test 25:  Executing :finally clauses on normal control flow               {{{1
2162 "           Control flow in a :try conditional should always fall through to its
2163 "           :finally clause.  A :finally clause of a :try conditional inside an
2164 "           inactive conditional should never be executed.
2165 "-------------------------------------------------------------------------------
2167 XpathINIT
2169 function! F()
2170     let loops = 3
2171     XloopINIT 1 256
2172     while loops > 0                             "     3:   2:       1:
2173         Xloop 1                                 " X:  1 +  1*256 + 1*256*256
2174         if loops >= 2
2175             try
2176                 Xloop 2                         " X:  2 +  2*256
2177                 if loops == 2
2178                     try
2179                         Xloop 4                 " X:       4*256
2180                     finally
2181                         Xloop 8                 " X:       8*256
2182                     endtry
2183                 endif
2184             finally
2185                 Xloop 16                        " X: 16 + 16*256
2186                 if loops == 2
2187                     try
2188                         Xloop 32                " X:      32*256
2189                     finally
2190                         Xloop 64                " X:      64*256
2191                     endtry
2192                 endif
2193             endtry
2194         endif
2195         Xloop 128                               " X: 128 + 128*256 + 128*256*256
2196         let loops = loops - 1
2197         XloopNEXT
2198     endwhile
2199     Xpath 16777216                              " X: 16777216
2200 endfunction
2202 if 1
2203     try
2204         Xpath 33554432                          " X: 33554432
2205         call F()
2206         Xpath 67108864                          " X: 67108864
2207     finally
2208         Xpath 134217728                         " X: 134217728
2209     endtry
2210 else
2211     try
2212         Xpath 268435456                         " X: 0
2213     finally
2214         Xpath 536870912                         " X: 0
2215     endtry
2216 endif
2218 delfunction F
2220 Xcheck 260177811
2223 "-------------------------------------------------------------------------------
2224 " Test 26:  Executing :finally clauses after :continue or :break            {{{1
2226 "           For a :continue or :break dynamically enclosed in a :try/:endtry
2227 "           region inside the next surrounding :while/:endwhile, if the
2228 "           :continue/:break is before the :finally, the :finally clause is
2229 "           executed first.  If the :continue/:break is after the :finally, the
2230 "           :finally clause is broken (like an :if/:endif region).
2231 "-------------------------------------------------------------------------------
2233 XpathINIT
2236     let loops = 3
2237     XloopINIT! 1 32
2238     while loops > 0
2239         XloopNEXT
2240         try
2241             try
2242                 if loops == 2                   "    3:   2:     1:
2243                     Xloop 1                     " X:      1*32
2244                     let loops = loops - 1
2245                     continue
2246                 elseif loops == 1
2247                     Xloop 2                     " X:             2*32*32
2248                     break
2249                     finish
2250                 endif
2251                 Xloop 4                         " X: 4
2252             endtry
2253         finally
2254             Xloop 8                             " X: 8  + 8*32 + 8*32*32
2255         endtry
2256         Xloop 16                                " X: 16
2257         let loops = loops - 1
2258     endwhile
2259     Xpath 32768                                 " X: 32768
2260 finally
2261     Xpath 65536                                 " X: 65536
2262     let loops = 3
2263     XloopINIT 131072 16
2264     while loops > 0
2265         try
2266         finally
2267             try
2268                 if loops == 2
2269                     Xloop 1                     " X: 131072*16
2270                     let loops = loops - 1
2271                     XloopNEXT
2272                     continue
2273                 elseif loops == 1
2274                     Xloop 2                     " X: 131072*2*16*16
2275                     break
2276                     finish
2277                 endif
2278             endtry
2279             Xloop 4                             " X: 131072*4
2280         endtry
2281         Xloop 8                                 " X: 131072*8
2282         let loops = loops - 1
2283         XloopNEXT
2284     endwhile
2285     Xpath 536870912                             " X: 536870912
2286 endtry
2287 Xpath 1073741824                                " X: 1073741824
2289 unlet loops
2291 Xcheck 1681500476
2294 "-------------------------------------------------------------------------------
2295 " Test 27:  Executing :finally clauses after :return                        {{{1
2297 "           For a :return command dynamically enclosed in a :try/:endtry region,
2298 "           :finally clauses are executed and the called function is ended.
2299 "-------------------------------------------------------------------------------
2301 XpathINIT
2303 function! F()
2304     try
2305         Xpath 1                                 " X: 1
2306         try
2307             Xpath 2                             " X: 2
2308             return
2309             Xpath 4                             " X: 0
2310         finally
2311             Xpath 8                             " X: 8
2312         endtry
2313         Xpath 16                                " X: 0
2314     finally
2315         Xpath 32                                " X: 32
2316     endtry
2317     Xpath 64                                    " X: 0
2318 endfunction
2320 function! G()
2321     try
2322         Xpath 128                               " X: 128
2323         return
2324         Xpath 256                               " X: 0
2325     finally
2326         Xpath 512                               " X: 512
2327         call F()
2328         Xpath 1024                              " X: 1024
2329     endtry
2330     Xpath 2048                                  " X: 0
2331 endfunction
2333 function! H()
2334     try
2335         Xpath 4096                              " X: 4096
2336         call G()
2337         Xpath 8192                              " X: 8192
2338     finally
2339         Xpath 16384                             " X: 16384
2340         return
2341         Xpath 32768                             " X: 0
2342     endtry
2343     Xpath 65536                                 " X: 0
2344 endfunction
2347     Xpath 131072                                " X: 131072
2348     call H()
2349     Xpath 262144                                " X: 262144
2350 finally
2351     Xpath 524288                                " X: 524288
2352 endtry
2353 Xpath 1048576                                   " X: 1048576
2355 Xcheck 1996459
2357 " Leave F, G, and H for execution as scripts in the next test.
2360 "-------------------------------------------------------------------------------
2361 " Test 28:  Executing :finally clauses after :finish                        {{{1
2363 "           For a :finish command dynamically enclosed in a :try/:endtry region,
2364 "           :finally clauses are executed and the sourced file is finished.
2366 "           This test executes the bodies of the functions F, G, and H from the
2367 "           previous test as script files (:return replaced by :finish).
2368 "-------------------------------------------------------------------------------
2370 XpathINIT
2372 let scriptF = MakeScript("F")                   " X: 1 + 2 + 8 + 32
2373 let scriptG = MakeScript("G", scriptF)          " X: 128 + 512 + 1024
2374 let scriptH = MakeScript("H", scriptG)          " X: 4096 + 8192 + 16384
2377     Xpath 131072                                " X: 131072
2378     exec "source" scriptH
2379     Xpath 262144                                " X: 262144
2380 finally
2381     Xpath 524288                                " X: 524288
2382 endtry
2383 Xpath 1048576                                   " X: 1048576
2385 call delete(scriptF)
2386 call delete(scriptG)
2387 call delete(scriptH)
2388 unlet scriptF scriptG scriptH
2389 delfunction F
2390 delfunction G
2391 delfunction H
2393 Xcheck 1996459
2396 "-------------------------------------------------------------------------------
2397 " Test 29:  Executing :finally clauses on errors                            {{{1
2399 "           After an error in a command dynamically enclosed in a :try/:endtry
2400 "           region, :finally clauses are executed and the script processing is
2401 "           terminated.
2402 "-------------------------------------------------------------------------------
2404 XpathINIT
2406 if ExtraVim()
2407     function! F()
2408         while 1
2409             try
2410                 Xpath 1                         " X: 1
2411                 while 1
2412                     try
2413                         Xpath 2                 " X: 2
2414                         asdf        " error
2415                         Xpath 4                 " X: 0
2416                     finally
2417                         Xpath 8                 " X: 8
2418                     endtry | Xpath 16           " X: 0
2419                     Xpath 32                    " X: 0
2420                     break
2421                 endwhile
2422                 Xpath 64                        " X: 0
2423             finally
2424                 Xpath 128                       " X: 128
2425             endtry | Xpath 256                  " X: 0
2426             Xpath 512                           " X: 0
2427             break
2428         endwhile
2429         Xpath 1024                              " X: 0
2430     endfunction
2432     while 1
2433         try
2434             Xpath 2048                          " X: 2048
2435             while 1
2436                 call F()
2437                 Xpath 4096                      " X: 0
2438                 break
2439             endwhile  | Xpath 8192              " X: 0
2440             Xpath 16384                         " X: 0
2441         finally
2442             Xpath 32768                         " X: 32768
2443         endtry | Xpath 65536                    " X: 0
2444     endwhile | Xpath 131072                     " X: 0
2445     Xpath 262144                                " X: 0
2446 endif
2448 if ExtraVim()
2449     function! G() abort
2450         if 1
2451             try
2452                 Xpath 524288                    " X: 524288
2453                 asdf        " error
2454                 Xpath 1048576                   " X: 0
2455             finally
2456                 Xpath 2097152                   " X: 2097152
2457             endtry | Xpath 4194304              " X: 0
2458         endif | Xpath 8388608                   " X: 0
2459         Xpath 16777216                          " X: 0
2460     endfunction
2462     if 1
2463         try
2464             Xpath 33554432                      " X: 33554432
2465             call G()
2466             Xpath 67108864                      " X: 0
2467         finally
2468             Xpath 134217728                     " X: 134217728
2469         endtry | Xpath 268435456                " X: 0
2470     endif | Xpath 536870912                     " X: 0
2471     Xpath 1073741824                            " X: 0
2472 endif
2474 Xcheck 170428555
2477 "-------------------------------------------------------------------------------
2478 " Test 30:  Executing :finally clauses on interrupt                         {{{1
2480 "           After an interrupt in a command dynamically enclosed in
2481 "           a :try/:endtry region, :finally clauses are executed and the
2482 "           script processing is terminated.
2483 "-------------------------------------------------------------------------------
2485 XpathINIT
2487 if ExtraVim()
2488     XloopINIT 1 16
2490     function! F()
2491         try
2492             Xloop 1                             " X: 1 + 1*16
2493             "INTERRUPT
2494             Xloop 2                             " X: 0
2495         finally
2496             Xloop 4                             " X: 4 + 4*16
2497         endtry
2498         Xloop 8                                 " X: 0
2499     endfunction
2501     try
2502         Xpath 256                               " X: 256
2503         try
2504             Xpath 512                           " X: 512
2505             "INTERRUPT
2506             Xpath 1024                          " X: 0
2507         finally
2508             Xpath 2048                          " X: 2048
2509             try
2510                 Xpath 4096                      " X: 4096
2511                 try
2512                     Xpath 8192                  " X: 8192
2513                 finally
2514                     Xpath 16384                 " X: 16384
2515                     try
2516                         Xpath 32768             " X: 32768
2517                         "INTERRUPT
2518                         Xpath 65536             " X: 0
2519                     endtry
2520                     Xpath 131072                " X: 0
2521                 endtry
2522                 Xpath 262144                    " X: 0
2523             endtry
2524             Xpath 524288                        " X: 0
2525         endtry
2526         Xpath 1048576                           " X: 0
2527     finally
2528         Xpath 2097152                           " X: 2097152
2529         try
2530             Xpath 4194304                       " X: 4194304
2531             call F()
2532             Xpath 8388608                       " X: 0
2533         finally
2534             Xpath 16777216                      " X: 16777216
2535             try
2536                 Xpath 33554432                  " X: 33554432
2537                 XloopNEXT
2538                 ExecAsScript F
2539                 Xpath 67108864                  " X: 0
2540             finally
2541                 Xpath 134217728                 " X: 134217728
2542             endtry
2543             Xpath 268435456                     " X: 0
2544         endtry
2545         Xpath 536870912                         " X: 0
2546     endtry
2547     Xpath 1073741824                            " X: 0
2548 endif
2550 Xcheck 190905173
2553 "-------------------------------------------------------------------------------
2554 " Test 31:  Executing :finally clauses after :throw                         {{{1
2556 "           After a :throw dynamically enclosed in a :try/:endtry region,
2557 "           :finally clauses are executed and the script processing is
2558 "           terminated.
2559 "-------------------------------------------------------------------------------
2561 XpathINIT
2563 if ExtraVim()
2564     XloopINIT 1 16
2566     function! F()
2567         try
2568             Xloop 1                             " X: 1 + 1*16
2569             throw "exception"
2570             Xloop 2                             " X: 0
2571         finally
2572             Xloop 4                             " X: 4 + 4*16
2573         endtry
2574         Xloop 8                                 " X: 0
2575     endfunction
2577     try
2578         Xpath 256                               " X: 256
2579         try
2580             Xpath 512                           " X: 512
2581             throw "exception"
2582             Xpath 1024                          " X: 0
2583         finally
2584             Xpath 2048                          " X: 2048
2585             try
2586                 Xpath 4096                      " X: 4096
2587                 try
2588                     Xpath 8192                  " X: 8192
2589                 finally
2590                     Xpath 16384                 " X: 16384
2591                     try
2592                         Xpath 32768             " X: 32768
2593                         throw "exception"
2594                         Xpath 65536             " X: 0
2595                     endtry
2596                     Xpath 131072                " X: 0
2597                 endtry
2598                 Xpath 262144                    " X: 0
2599             endtry
2600             Xpath 524288                        " X: 0
2601         endtry
2602         Xpath 1048576                           " X: 0
2603     finally
2604         Xpath 2097152                           " X: 2097152
2605         try
2606             Xpath 4194304                       " X: 4194304
2607             call F()
2608             Xpath 8388608                       " X: 0
2609         finally
2610             Xpath 16777216                      " X: 16777216
2611             try
2612                 Xpath 33554432                  " X: 33554432
2613                 XloopNEXT
2614                 ExecAsScript F
2615                 Xpath 67108864                  " X: 0
2616             finally
2617                 Xpath 134217728                 " X: 134217728
2618             endtry
2619             Xpath 268435456                     " X: 0
2620         endtry
2621         Xpath 536870912                         " X: 0
2622     endtry
2623     Xpath 1073741824                            " X: 0
2624 endif
2626 Xcheck 190905173
2629 "-------------------------------------------------------------------------------
2630 " Test 32:  Remembering the :return value on :finally                       {{{1
2632 "           If a :finally clause is executed due to a :return specifying
2633 "           a value, this is the value visible to the caller if not overwritten
2634 "           by a new :return in the :finally clause.  A :return without a value
2635 "           in the :finally clause overwrites with value 0.
2636 "-------------------------------------------------------------------------------
2638 XpathINIT
2640 function! F()
2641     try
2642         Xpath 1                                 " X: 1
2643         try
2644             Xpath 2                             " X: 2
2645             return "ABCD"
2646             Xpath 4                             " X: 0
2647         finally
2648             Xpath 8                             " X: 8
2649         endtry
2650         Xpath 16                                " X: 0
2651     finally
2652         Xpath 32                                " X: 32
2653     endtry
2654     Xpath 64                                    " X: 0
2655 endfunction
2657 function! G()
2658     try
2659         Xpath 128                               " X: 128
2660         return 8
2661         Xpath 256                               " X: 0
2662     finally
2663         Xpath 512                               " X: 512
2664         return 16 + strlen(F())
2665         Xpath 1024                              " X: 0
2666     endtry
2667     Xpath 2048                                  " X: 0
2668 endfunction
2670 function! H()
2671     try
2672         Xpath 4096                              " X: 4096
2673         return 32
2674         Xpath 8192                              " X: 0
2675     finally
2676         Xpath 16384                             " X: 16384
2677         return
2678         Xpath 32768                             " X: 0
2679     endtry
2680     Xpath 65536                                 " X: 0
2681 endfunction
2683 function! I()
2684     try
2685         Xpath 131072                            " X: 131072
2686     finally
2687         Xpath 262144                            " X: 262144
2688         return G() + H() + 64
2689         Xpath 524288                            " X: 0
2690     endtry
2691     Xpath 1048576                               " X: 0
2692 endfunction
2694 let retcode = I()
2695 Xpath 2097152                                   " X: 2097152
2697 if retcode < 0
2698     Xpath 4194304                               " X: 0
2699 endif
2700 if retcode % 4
2701     Xpath 8388608                               " X: 0
2702 endif
2703 if (retcode/4) % 2
2704     Xpath 16777216                              " X: 16777216
2705 endif
2706 if (retcode/8) % 2
2707     Xpath 33554432                              " X: 0
2708 endif
2709 if (retcode/16) % 2
2710     Xpath 67108864                              " X: 67108864
2711 endif
2712 if (retcode/32) % 2
2713     Xpath 134217728                             " X: 0
2714 endif
2715 if (retcode/64) % 2
2716     Xpath 268435456                             " X: 268435456
2717 endif
2718 if retcode/128
2719     Xpath 536870912                             " X: 0
2720 endif
2722 unlet retcode
2723 delfunction F
2724 delfunction G
2725 delfunction H
2726 delfunction I
2728 Xcheck 354833067
2731 "-------------------------------------------------------------------------------
2732 " Test 33:  :return under :execute or user command and :finally             {{{1
2734 "           A :return command may be executed under an ":execute" or from
2735 "           a user command.  Executing of :finally clauses and passing through
2736 "           the return code works also then.
2737 "-------------------------------------------------------------------------------
2738 XpathINIT
2740 command! -nargs=? RETURN
2741     \ try | return <args> | finally | return <args> * 2 | endtry
2743 function! F()
2744     try
2745         RETURN 8
2746         Xpath 1                                 " X: 0
2747     finally
2748         Xpath 2                                 " X: 2
2749     endtry
2750     Xpath 4                                     " X: 0
2751 endfunction
2753 function! G()
2754     try
2755         RETURN 32
2756         Xpath 8                                 " X: 0
2757     finally
2758         Xpath 16                                " X: 16
2759         RETURN 128
2760         Xpath 32                                " X: 0
2761     endtry
2762     Xpath 64                                    " X: 0
2763 endfunction
2765 function! H()
2766     try
2767         execute "try | return 512 | finally | return 1024 | endtry"
2768         Xpath 128                               " X: 0
2769     finally
2770         Xpath 256                               " X: 256
2771     endtry
2772     Xpath 512                                   " X: 0
2773 endfunction
2775 function! I()
2776     try
2777         execute "try | return 2048 | finally | return 4096 | endtry"
2778         Xpath 1024                              " X: 0
2779     finally
2780         Xpath 2048                              " X: 2048
2781         execute "try | return 8192 | finally | return 16384 | endtry"
2782         Xpath 4096                              " X: 0
2783     endtry
2784     Xpath 8192                                  " X: 0
2785 endfunction
2787 function! J()
2788     try
2789         RETURN 32768
2790         Xpath 16384                             " X: 0
2791     finally
2792         Xpath 32768                             " X: 32768
2793         return
2794         Xpath 65536                             " X: 0
2795     endtry
2796     Xpath 131072                                " X: 0
2797 endfunction
2799 function! K()
2800     try
2801         execute "try | return 131072 | finally | return 262144 | endtry"
2802         Xpath 262144                            " X: 0
2803     finally
2804         Xpath 524288                            " X: 524288
2805         execute "try | return 524288 | finally | return | endtry"
2806         Xpath 1048576                           " X: 0
2807     endtry
2808     Xpath 2097152                               " X: 0
2809 endfunction
2811 function! L()
2812     try
2813         return
2814         Xpath 4194304                           " X: 0
2815     finally
2816         Xpath 8388608                           " X: 8388608
2817         RETURN 1048576
2818         Xpath 16777216                          " X: 0
2819     endtry
2820     Xpath 33554432                              " X: 0
2821 endfunction
2823 function! M()
2824     try
2825         return
2826         Xpath 67108864                          " X: 0
2827     finally
2828         Xpath 134217728                         " X: 134217728
2829         execute "try | return 4194304 | finally | return 8388608 | endtry"
2830         Xpath 268435456                         " X: 0
2831     endtry
2832     Xpath 536870912                             " X: 0
2833 endfunction
2835 function! N()
2836     RETURN 16777216
2837 endfunction
2839 function! O()
2840     execute "try | return 67108864 | finally | return 134217728 | endtry"
2841 endfunction
2843 let sum      = F() + G() + H()  + I()   + J() + K() + L()     + M()
2844 let expected = 16  + 256 + 1024 + 16384 + 0   + 0   + 2097152 + 8388608
2845 let sum      = sum      + N()      + O()
2846 let expected = expected + 33554432 + 134217728
2848 if sum == expected
2849     Xout "sum = " . sum . " (ok)"
2850 else
2851     Xout "sum = " . sum . ", expected: " . expected
2852 endif
2854 Xpath 1073741824                                " X: 1073741824
2856 if sum != expected
2857     " The Xpath command does not accept 2^31 (negative); add explicitly:
2858     let Xpath = Xpath + 2147483648              " X: 0
2859 endif
2861 unlet sum expected
2862 delfunction F
2863 delfunction G
2864 delfunction H
2865 delfunction I
2866 delfunction J
2867 delfunction K
2868 delfunction L
2869 delfunction M
2870 delfunction N
2871 delfunction O
2873 Xcheck 1216907538
2876 "-------------------------------------------------------------------------------
2877 " Test 34:  :finally reason discarded by :continue                          {{{1
2879 "           When a :finally clause is executed due to a :continue, :break,
2880 "           :return, :finish, error, interrupt or :throw, the jump reason is
2881 "           discarded by a :continue in the finally clause.
2882 "-------------------------------------------------------------------------------
2884 XpathINIT
2886 if ExtraVim()
2888     XloopINIT! 1 8
2890     function! C(jump)
2891         XloopNEXT
2892         let loop = 0
2893         while loop < 2
2894             let loop = loop + 1
2895             if loop == 1
2896                 try
2897                     if a:jump == "continue"
2898                         continue
2899                     elseif a:jump == "break"
2900                         break
2901                     elseif a:jump == "return" || a:jump == "finish"
2902                         return
2903                     elseif a:jump == "error"
2904                         asdf
2905                     elseif a:jump == "interrupt"
2906                         "INTERRUPT
2907                         let dummy = 0
2908                     elseif a:jump == "throw"
2909                         throw "abc"
2910                     endif
2911                 finally
2912                     continue    " discards jump that caused the :finally
2913                     Xloop 1             " X: 0
2914                 endtry
2915                 Xloop 2                 " X: 0
2916             elseif loop == 2
2917                 Xloop 4                 " X: 4*(1+8+64+512+4096+32768+262144)
2918             endif
2919         endwhile
2920     endfunction
2922     call C("continue")
2923     Xpath 2097152                               " X: 2097152
2924     call C("break")
2925     Xpath 4194304                               " X: 4194304
2926     call C("return")
2927     Xpath 8388608                               " X: 8388608
2928     let g:jump = "finish"
2929     ExecAsScript C
2930     unlet g:jump
2931     Xpath 16777216                              " X: 16777216
2932     try
2933         call C("error")
2934         Xpath 33554432                          " X: 33554432
2935     finally
2936         Xpath 67108864                          " X: 67108864
2937         try
2938             call C("interrupt")
2939             Xpath 134217728                     " X: 134217728
2940         finally
2941             Xpath 268435456                     " X: 268435456
2942             call C("throw")
2943             Xpath 536870912                     " X: 536870912
2944         endtry
2945     endtry
2946     Xpath 1073741824                            " X: 1073741824
2948     delfunction C
2950 endif
2952 Xcheck 2146584868
2955 "-------------------------------------------------------------------------------
2956 " Test 35:  :finally reason discarded by :break                             {{{1
2958 "           When a :finally clause is executed due to a :continue, :break,
2959 "           :return, :finish, error, interrupt or :throw, the jump reason is
2960 "           discarded by a :break in the finally clause.
2961 "-------------------------------------------------------------------------------
2963 XpathINIT
2965 if ExtraVim()
2967     XloopINIT! 1 8
2969     function! B(jump)
2970         XloopNEXT
2971         let loop = 0
2972         while loop < 2
2973             let loop = loop + 1
2974             if loop == 1
2975                 try
2976                     if a:jump == "continue"
2977                         continue
2978                     elseif a:jump == "break"
2979                         break
2980                     elseif a:jump == "return" || a:jump == "finish"
2981                         return
2982                     elseif a:jump == "error"
2983                         asdf
2984                     elseif a:jump == "interrupt"
2985                         "INTERRUPT
2986                         let dummy = 0
2987                     elseif a:jump == "throw"
2988                         throw "abc"
2989                     endif
2990                 finally
2991                     break       " discards jump that caused the :finally
2992                     Xloop 1             " X: 0
2993                 endtry
2994             elseif loop == 2
2995                 Xloop 2                 " X: 0
2996             endif
2997         endwhile
2998         Xloop 4                         " X: 4*(1+8+64+512+4096+32768+262144)
2999     endfunction
3001     call B("continue")
3002     Xpath 2097152                               " X: 2097152
3003     call B("break")
3004     Xpath 4194304                               " X: 4194304
3005     call B("return")
3006     Xpath 8388608                               " X: 8388608
3007     let g:jump = "finish"
3008     ExecAsScript B
3009     unlet g:jump
3010     Xpath 16777216                              " X: 16777216
3011     try
3012         call B("error")
3013         Xpath 33554432                          " X: 33554432
3014     finally
3015         Xpath 67108864                          " X: 67108864
3016         try
3017             call B("interrupt")
3018             Xpath 134217728                     " X: 134217728
3019         finally
3020             Xpath 268435456                     " X: 268435456
3021             call B("throw")
3022             Xpath 536870912                     " X: 536870912
3023         endtry
3024     endtry
3025     Xpath 1073741824                            " X: 1073741824
3027     delfunction B
3029 endif
3031 Xcheck 2146584868
3034 "-------------------------------------------------------------------------------
3035 " Test 36:  :finally reason discarded by :return                            {{{1
3037 "           When a :finally clause is executed due to a :continue, :break,
3038 "           :return, :finish, error, interrupt or :throw, the jump reason is
3039 "           discarded by a :return in the finally clause.
3040 "-------------------------------------------------------------------------------
3042 XpathINIT
3044 if ExtraVim()
3046     XloopINIT! 1 8
3048     function! R(jump, retval) abort
3049         XloopNEXT
3050         let loop = 0
3051         while loop < 2
3052             let loop = loop + 1
3053             if loop == 1
3054                 try
3055                     if a:jump == "continue"
3056                         continue
3057                     elseif a:jump == "break"
3058                         break
3059                     elseif a:jump == "return"
3060                         return
3061                     elseif a:jump == "error"
3062                         asdf
3063                     elseif a:jump == "interrupt"
3064                         "INTERRUPT
3065                         let dummy = 0
3066                     elseif a:jump == "throw"
3067                         throw "abc"
3068                     endif
3069                 finally
3070                     return a:retval     " discards jump that caused the :finally
3071                     Xloop 1                     " X: 0
3072                 endtry
3073             elseif loop == 2
3074                 Xloop 2                         " X: 0
3075             endif
3076         endwhile
3077         Xloop 4                                 " X: 0
3078     endfunction
3080     let sum =  -R("continue", -8)
3081     Xpath 2097152                               " X: 2097152
3082     let sum = sum - R("break", -16)
3083     Xpath 4194304                               " X: 4194304
3084     let sum = sum - R("return", -32)
3085     Xpath 8388608                               " X: 8388608
3086     try
3087         let sum = sum - R("error", -64)
3088         Xpath 16777216                          " X: 16777216
3089     finally
3090         Xpath 33554432                          " X: 33554432
3091         try
3092             let sum = sum - R("interrupt", -128)
3093             Xpath 67108864                      " X: 67108864
3094         finally
3095             Xpath 134217728                     " X: 134217728
3096             let sum = sum - R("throw", -256)
3097             Xpath 268435456                     " X: 268435456
3098         endtry
3099     endtry
3100     Xpath 536870912                             " X: 536870912
3102     let expected = 8 + 16 + 32 + 64 + 128 + 256
3103     if sum != expected
3104         Xpath 1073741824                        " X: 0
3105         Xout "sum =" . sum . ", expected: " . expected
3106     endif
3108     unlet sum expected
3109     delfunction R
3111 endif
3113 Xcheck 1071644672
3116 "-------------------------------------------------------------------------------
3117 " Test 37:  :finally reason discarded by :finish                            {{{1
3119 "           When a :finally clause is executed due to a :continue, :break,
3120 "           :return, :finish, error, interrupt or :throw, the jump reason is
3121 "           discarded by a :finish in the finally clause.
3122 "-------------------------------------------------------------------------------
3124 XpathINIT
3126 if ExtraVim()
3128     XloopINIT! 1 8
3130     function! F(jump)   " not executed as function, transformed to a script
3131         XloopNEXT
3132         let loop = 0
3133         while loop < 2
3134             let loop = loop + 1
3135             if loop == 1
3136                 try
3137                     if a:jump == "continue"
3138                         continue
3139                     elseif a:jump == "break"
3140                         break
3141                     elseif a:jump == "finish"
3142                         finish
3143                     elseif a:jump == "error"
3144                         asdf
3145                     elseif a:jump == "interrupt"
3146                         "INTERRUPT
3147                         let dummy = 0
3148                     elseif a:jump == "throw"
3149                         throw "abc"
3150                     endif
3151                 finally
3152                     finish      " discards jump that caused the :finally
3153                     Xloop 1                     " X: 0
3154                 endtry
3155             elseif loop == 2
3156                 Xloop 2                         " X: 0
3157             endif
3158         endwhile
3159         Xloop 4                                 " X: 0
3160     endfunction
3162     let scriptF = MakeScript("F")
3163     delfunction F
3165     let g:jump = "continue"
3166     exec "source" scriptF
3167     Xpath 2097152                               " X: 2097152
3168     let g:jump = "break"
3169     exec "source" scriptF
3170     Xpath 4194304                               " X: 4194304
3171     let g:jump = "finish"
3172     exec "source" scriptF
3173     Xpath 8388608                               " X: 8388608
3174     try
3175         let g:jump = "error"
3176         exec "source" scriptF
3177         Xpath 16777216                          " X: 16777216
3178     finally
3179         Xpath 33554432                          " X: 33554432
3180         try
3181             let g:jump = "interrupt"
3182             exec "source" scriptF
3183             Xpath 67108864                      " X: 67108864
3184         finally
3185             Xpath 134217728                     " X: 134217728
3186             try
3187                 let g:jump = "throw"
3188                 exec "source" scriptF
3189                 Xpath 268435456                 " X: 268435456
3190             finally
3191                 Xpath 536870912                 " X: 536870912
3192             endtry
3193         endtry
3194     endtry
3195     unlet g:jump
3197     call delete(scriptF)
3198     unlet scriptF
3200 endif
3202 Xcheck 1071644672
3205 "-------------------------------------------------------------------------------
3206 " Test 38:  :finally reason discarded by an error                           {{{1
3208 "           When a :finally clause is executed due to a :continue, :break,
3209 "           :return, :finish, error, interrupt or :throw, the jump reason is
3210 "           discarded by an error in the finally clause.
3211 "-------------------------------------------------------------------------------
3213 XpathINIT
3215 if ExtraVim()
3217     XloopINIT! 1 4
3219     function! E(jump)
3220         XloopNEXT
3221         let loop = 0
3222         while loop < 2
3223             let loop = loop + 1
3224             if loop == 1
3225                 try
3226                     if a:jump == "continue"
3227                         continue
3228                     elseif a:jump == "break"
3229                         break
3230                     elseif a:jump == "return" || a:jump == "finish"
3231                         return
3232                     elseif a:jump == "error"
3233                         asdf
3234                     elseif a:jump == "interrupt"
3235                         "INTERRUPT
3236                         let dummy = 0
3237                     elseif a:jump == "throw"
3238                         throw "abc"
3239                     endif
3240                 finally
3241                     asdf        " error; discards jump that caused the :finally
3242                 endtry
3243             elseif loop == 2
3244                 Xloop 1                         " X: 0
3245             endif
3246         endwhile
3247         Xloop 2                                 " X: 0
3248     endfunction
3250     try
3251         Xpath 16384                             " X: 16384
3252         call E("continue")
3253         Xpath 32768                             " X: 0
3254     finally
3255         try
3256             Xpath 65536                         " X: 65536
3257             call E("break")
3258             Xpath 131072                        " X: 0
3259         finally
3260             try
3261                 Xpath 262144                    " X: 262144
3262                 call E("return")
3263                 Xpath 524288                    " X: 0
3264             finally
3265                 try
3266                     Xpath 1048576               " X: 1048576
3267                     let g:jump = "finish"
3268                     ExecAsScript E
3269                     Xpath 2097152               " X: 0
3270                 finally
3271                     unlet g:jump
3272                     try
3273                         Xpath 4194304           " X: 4194304
3274                         call E("error")
3275                         Xpath 8388608           " X: 0
3276                     finally
3277                         try
3278                             Xpath 16777216      " X: 16777216
3279                             call E("interrupt")
3280                             Xpath 33554432      " X: 0
3281                         finally
3282                             try
3283                                 Xpath 67108864  " X: 67108864
3284                                 call E("throw")
3285                                 Xpath 134217728 " X: 0
3286                             finally
3287                                 Xpath 268435456 " X: 268435456
3288                                 delfunction E
3289                             endtry
3290                         endtry
3291                     endtry
3292                 endtry
3293             endtry
3294         endtry
3295     endtry
3296     Xpath 536870912                             " X: 0
3298 endif
3300 Xcheck 357908480
3303 "-------------------------------------------------------------------------------
3304 " Test 39:  :finally reason discarded by an interrupt                       {{{1
3306 "           When a :finally clause is executed due to a :continue, :break,
3307 "           :return, :finish, error, interrupt or :throw, the jump reason is
3308 "           discarded by an interrupt in the finally clause.
3309 "-------------------------------------------------------------------------------
3311 XpathINIT
3313 if ExtraVim()
3315     XloopINIT! 1 4
3317     function! I(jump)
3318         XloopNEXT
3319         let loop = 0
3320         while loop < 2
3321             let loop = loop + 1
3322             if loop == 1
3323                 try
3324                     if a:jump == "continue"
3325                         continue
3326                     elseif a:jump == "break"
3327                         break
3328                     elseif a:jump == "return" || a:jump == "finish"
3329                         return
3330                     elseif a:jump == "error"
3331                         asdf
3332                     elseif a:jump == "interrupt"
3333                         "INTERRUPT
3334                         let dummy = 0
3335                     elseif a:jump == "throw"
3336                         throw "abc"
3337                     endif
3338                 finally
3339                     "INTERRUPT - discards jump that caused the :finally
3340                     let dummy = 0
3341                 endtry
3342             elseif loop == 2
3343                 Xloop 1                         " X: 0
3344             endif
3345         endwhile
3346         Xloop 2                                 " X: 0
3347     endfunction
3349     try
3350         Xpath 16384                             " X: 16384
3351         call I("continue")
3352         Xpath 32768                             " X: 0
3353     finally
3354         try
3355             Xpath 65536                         " X: 65536
3356             call I("break")
3357             Xpath 131072                        " X: 0
3358         finally
3359             try
3360                 Xpath 262144                    " X: 262144
3361                 call I("return")
3362                 Xpath 524288                    " X: 0
3363             finally
3364                 try
3365                     Xpath 1048576               " X: 1048576
3366                     let g:jump = "finish"
3367                     ExecAsScript I
3368                     Xpath 2097152               " X: 0
3369                 finally
3370                     unlet g:jump
3371                     try
3372                         Xpath 4194304           " X: 4194304
3373                         call I("error")
3374                         Xpath 8388608           " X: 0
3375                     finally
3376                         try
3377                             Xpath 16777216      " X: 16777216
3378                             call I("interrupt")
3379                             Xpath 33554432      " X: 0
3380                         finally
3381                             try
3382                                 Xpath 67108864  " X: 67108864
3383                                 call I("throw")
3384                                 Xpath 134217728 " X: 0
3385                             finally
3386                                 Xpath 268435456 " X: 268435456
3387                                 delfunction I
3388                             endtry
3389                         endtry
3390                     endtry
3391                 endtry
3392             endtry
3393         endtry
3394     endtry
3395     Xpath 536870912                             " X: 0
3397 endif
3399 Xcheck 357908480
3402 "-------------------------------------------------------------------------------
3403 " Test 40:  :finally reason discarded by :throw                             {{{1
3405 "           When a :finally clause is executed due to a :continue, :break,
3406 "           :return, :finish, error, interrupt or :throw, the jump reason is
3407 "           discarded by a :throw in the finally clause.
3408 "-------------------------------------------------------------------------------
3410 XpathINIT
3412 if ExtraVim()
3414     XloopINIT! 1 4
3416     function! T(jump)
3417         XloopNEXT
3418         let loop = 0
3419         while loop < 2
3420             let loop = loop + 1
3421             if loop == 1
3422                 try
3423                     if a:jump == "continue"
3424                         continue
3425                     elseif a:jump == "break"
3426                         break
3427                     elseif a:jump == "return" || a:jump == "finish"
3428                         return
3429                     elseif a:jump == "error"
3430                         asdf
3431                     elseif a:jump == "interrupt"
3432                         "INTERRUPT
3433                         let dummy = 0
3434                     elseif a:jump == "throw"
3435                         throw "abc"
3436                     endif
3437                 finally
3438                     throw "xyz" " discards jump that caused the :finally
3439                 endtry
3440             elseif loop == 2
3441                 Xloop 1                         " X: 0
3442             endif
3443         endwhile
3444         Xloop 2                                 " X: 0
3445     endfunction
3447     try
3448         Xpath 16384                             " X: 16384
3449         call T("continue")
3450         Xpath 32768                             " X: 0
3451     finally
3452         try
3453             Xpath 65536                         " X: 65536
3454             call T("break")
3455             Xpath 131072                        " X: 0
3456         finally
3457             try
3458                 Xpath 262144                    " X: 262144
3459                 call T("return")
3460                 Xpath 524288                    " X: 0
3461             finally
3462                 try
3463                     Xpath 1048576               " X: 1048576
3464                     let g:jump = "finish"
3465                     ExecAsScript T
3466                     Xpath 2097152               " X: 0
3467                 finally
3468                     unlet g:jump
3469                     try
3470                         Xpath 4194304           " X: 4194304
3471                         call T("error")
3472                         Xpath 8388608           " X: 0
3473                     finally
3474                         try
3475                             Xpath 16777216      " X: 16777216
3476                             call T("interrupt")
3477                             Xpath 33554432      " X: 0
3478                         finally
3479                             try
3480                                 Xpath 67108864  " X: 67108864
3481                                 call T("throw")
3482                                 Xpath 134217728 " X: 0
3483                             finally
3484                                 Xpath 268435456 " X: 268435456
3485                                 delfunction T
3486                             endtry
3487                         endtry
3488                     endtry
3489                 endtry
3490             endtry
3491         endtry
3492     endtry
3493     Xpath 536870912                             " X: 0
3495 endif
3497 Xcheck 357908480
3500 "-------------------------------------------------------------------------------
3501 " Test 41:  Skipped :throw finding next command                             {{{1
3503 "           A :throw in an inactive conditional must not hide a following
3504 "           command.
3505 "-------------------------------------------------------------------------------
3507 XpathINIT
3509 function! F()
3510     Xpath 1                                     " X: 1
3511     if 0 | throw "never" | endif | Xpath 2      " X: 2
3512     Xpath 4                                     " X: 4
3513 endfunction
3515 function! G()
3516     Xpath 8                                         " X: 8
3517     while 0 | throw "never" | endwhile | Xpath 16   " X: 16
3518     Xpath 32                                        " X: 32
3519 endfunction
3521 function H()
3522     Xpath 64                                                " X: 64
3523     if 0 | try | throw "never" | endtry | endif | Xpath 128 " X: 128
3524     Xpath 256                                               " X: 256
3525 endfunction
3527 Xpath 512                                       " X: 512
3530     Xpath 1024                                  " X: 1024
3531     call F()
3532     Xpath 2048                                  " X: 2048
3533 catch /.*/
3534     Xpath 4096                                  " X: 0
3535     Xout v:exception "in" v:throwpoint
3536 endtry
3538 Xpath 8192                                      " X: 8192
3541     Xpath 16384                                 " X: 16384
3542     call G()
3543     Xpath 32768                                 " X: 32768
3544 catch /.*/
3545     Xpath 65536                                 " X: 0
3546     Xout v:exception "in" v:throwpoint
3547 endtry
3549 Xpath 131072                                    " X: 131072
3552     Xpath 262144                                " X: 262144
3553     call H()
3554     Xpath 524288                                " X: 524288
3555 catch /.*/
3556     Xpath 1048576                               " X: 0
3557     Xout v:exception "in" v:throwpoint
3558 endtry
3560 Xpath 2097152                                   " X: 2097152
3562 delfunction F
3563 delfunction G
3564 delfunction H
3566 Xcheck 3076095
3569 "-------------------------------------------------------------------------------
3570 " Test 42:  Catching number and string exceptions                           {{{1
3572 "           When a number is thrown, it is converted to a string exception.
3573 "           Numbers and strings may be caught by specifying a regular exception
3574 "           as argument to the :catch command.
3575 "-------------------------------------------------------------------------------
3577 XpathINIT
3581     try
3582         Xpath 1                                 " X: 1
3583         throw 4711
3584         Xpath 2                                 " X: 0
3585     catch /4711/
3586         Xpath 4                                 " X: 4
3587     endtry
3589     try
3590         Xpath 8                                 " X: 8
3591         throw 4711
3592         Xpath 16                                " X: 0
3593     catch /^4711$/
3594         Xpath 32                                " X: 32
3595     endtry
3597     try
3598         Xpath 64                                " X: 64
3599         throw 4711
3600         Xpath 128                               " X: 0
3601     catch /\d/
3602         Xpath 256                               " X: 256
3603     endtry
3605     try
3606         Xpath 512                               " X: 512
3607         throw 4711
3608         Xpath 1024                              " X: 0
3609     catch /^\d\+$/
3610         Xpath 2048                              " X: 2048
3611     endtry
3613     try
3614         Xpath 4096                              " X: 4096
3615         throw "arrgh"
3616         Xpath 8192                              " X: 0
3617     catch /arrgh/
3618         Xpath 16384                             " X: 16384
3619     endtry
3621     try
3622         Xpath 32768                             " X: 32768
3623         throw "arrgh"
3624         Xpath 65536                             " X: 0
3625     catch /^arrgh$/
3626         Xpath 131072                            " X: 131072
3627     endtry
3629     try
3630         Xpath 262144                            " X: 262144
3631         throw "arrgh"
3632         Xpath 524288                            " X: 0
3633     catch /\l/
3634         Xpath 1048576                           " X: 1048576
3635     endtry
3637     try
3638         Xpath 2097152                           " X: 2097152
3639         throw "arrgh"
3640         Xpath 4194304                           " X: 0
3641     catch /^\l\+$/
3642         Xpath 8388608                           " X: 8388608
3643     endtry
3645     try
3646         try
3647             Xpath 16777216                      " X: 16777216
3648             throw "ARRGH"
3649             Xpath 33554432                      " X: 0
3650         catch /^arrgh$/
3651             Xpath 67108864                      " X: 0
3652         endtry
3653     catch /^\carrgh$/
3654         Xpath 134217728                         " X: 134217728
3655     endtry
3657     try
3658         Xpath 268435456                         " X: 268435456
3659         throw ""
3660         Xpath 536870912                         " X: 0
3661     catch /^$/
3662         Xpath 1073741824                        " X: 1073741824
3663     endtry
3665 catch /.*/
3666     " The Xpath command does not accept 2^31 (negative); add explicitly:
3667     let Xpath = Xpath + 2147483648              " X: 0
3668     Xout v:exception "in" v:throwpoint
3669 endtry
3671 Xcheck 1505155949
3674 "-------------------------------------------------------------------------------
3675 " Test 43:  Selecting the correct :catch clause                             {{{1
3677 "           When an exception is thrown and there are multiple :catch clauses,
3678 "           the first matching one is taken.
3679 "-------------------------------------------------------------------------------
3681 XpathINIT
3683 XloopINIT 1 1024
3684 let loops = 3
3685 while loops > 0
3686     try
3687         if loops == 3
3688             Xloop 1                             " X: 1
3689             throw "a"
3690             Xloop 2                             " X: 0
3691         elseif loops == 2
3692             Xloop 4                             " X: 4*1024
3693             throw "ab"
3694             Xloop 8                             " X: 0
3695         elseif loops == 1
3696             Xloop 16                            " X: 16*1024*1024
3697             throw "abc"
3698             Xloop 32                            " X: 0
3699         endif
3700     catch /abc/
3701         Xloop 64                                " X: 64*1024*1024
3702     catch /ab/
3703         Xloop 128                               " X: 128*1024
3704     catch /.*/
3705         Xloop 256                               " X: 256
3706     catch /a/
3707         Xloop 512                               " X: 0
3708     endtry
3710     let loops = loops - 1
3711     XloopNEXT
3712 endwhile
3713 Xpath 1073741824                                " X: 1073741824
3715 unlet loops
3717 Xcheck 1157763329
3720 "-------------------------------------------------------------------------------
3721 " Test 44:  Missing or empty :catch patterns                                {{{1
3723 "           A missing or empty :catch pattern means the same as /.*/, that is,
3724 "           catches everything.  To catch only empty exceptions, /^$/ must be
3725 "           used.  A :catch with missing, empty, or /.*/ argument also works
3726 "           when followed by another command separated by a bar on the same
3727 "           line.  :catch patterns cannot be specified between ||.  But other
3728 "           pattern separators can be used instead of //.
3729 "-------------------------------------------------------------------------------
3731 XpathINIT
3734     try
3735         Xpath 1                                 " X: 1
3736         throw ""
3737     catch /^$/
3738         Xpath 2                                 " X: 2
3739     endtry
3741     try
3742         Xpath 4                                 " X: 4
3743         throw ""
3744     catch /.*/
3745         Xpath 8                                 " X: 8
3746     endtry
3748     try
3749         Xpath 16                                " X: 16
3750         throw ""
3751     catch //
3752         Xpath 32                                " X: 32
3753     endtry
3755     try
3756         Xpath 64                                " X: 64
3757         throw ""
3758     catch
3759         Xpath 128                               " X: 128
3760     endtry
3762     try
3763         Xpath 256                               " X: 256
3764         throw "oops"
3765     catch /^$/
3766         Xpath 512                               " X: 0
3767     catch /.*/
3768         Xpath 1024                              " X: 1024
3769     endtry
3771     try
3772         Xpath 2048                              " X: 2048
3773         throw "arrgh"
3774     catch /^$/
3775         Xpath 4096                              " X: 0
3776     catch //
3777         Xpath 8192                              " X: 8192
3778     endtry
3780     try
3781         Xpath 16384                             " X: 16384
3782         throw "brrr"
3783     catch /^$/
3784         Xpath 32768                             " X: 0
3785     catch
3786         Xpath 65536                             " X: 65536
3787     endtry
3789     try | Xpath 131072 | throw "x" | catch /.*/ | Xpath 262144 | endtry
3790                                                 " X: 131072 + 262144
3792     try | Xpath 524288 | throw "y" | catch // | Xpath 1048576 | endtry
3793                                                 " X: 524288 + 1048576
3795     while 1
3796         try
3797             let caught = 0
3798             let v:errmsg = ""
3799             " Extra try level:  if ":catch" without arguments below raises
3800             " a syntax error because it misinterprets the "Xpath" as a pattern,
3801             " let it be caught by the ":catch /.*/" below.
3802             try
3803                 try | Xpath 2097152 | throw "z" | catch | Xpath 4194304 | :
3804                 endtry                          " X: 2097152 + 4194304
3805             endtry
3806         catch /.*/
3807             let caught = 1
3808             Xout v:exception "in" v:throwpoint
3809         finally
3810             if $VIMNOERRTHROW && v:errmsg != ""
3811                 Xout v:errmsg
3812             endif
3813             if caught || $VIMNOERRTHROW && v:errmsg != ""
3814                 Xpath 8388608                           " X: 0
3815             endif
3816             break               " discard error for $VIMNOERRTHROW
3817         endtry
3818     endwhile
3820     let cologne = 4711
3821     try
3822         try
3823             Xpath 16777216                      " X: 16777216
3824             throw "throw cologne"
3825         " Next lines catches all and throws 4711:
3826         catch |throw cologne|
3827             Xpath 33554432                      " X: 0
3828         endtry
3829     catch /4711/
3830         Xpath 67108864                          " X: 67108864
3831     endtry
3833     try
3834         Xpath 134217728                         " X: 134217728
3835         throw "plus"
3836     catch +plus+
3837         Xpath 268435456                         " X: 268435456
3838     endtry
3840     Xpath 536870912                             " X: 536870912
3841 catch /.*/
3842     Xpath 1073741824                            " X: 0
3843     Xout v:exception "in" v:throwpoint
3844 endtry
3846 unlet! caught cologne
3848 Xcheck 1031761407
3851 "-------------------------------------------------------------------------------
3852 " Test 45:  Catching exceptions from nested :try blocks                     {{{1
3854 "           When :try blocks are nested, an exception is caught by the innermost
3855 "           try conditional that has a matching :catch clause.
3856 "-------------------------------------------------------------------------------
3858 XpathINIT
3860 XloopINIT 1 1024
3861 let loops = 3
3862 while loops > 0
3863     try
3864         try
3865             try
3866                 try
3867                     if loops == 3
3868                         Xloop 1                 " X: 1
3869                         throw "a"
3870                         Xloop 2                 " X: 0
3871                     elseif loops == 2
3872                         Xloop 4                 " X: 4*1024
3873                         throw "ab"
3874                         Xloop 8                 " X: 0
3875                     elseif loops == 1
3876                         Xloop 16                " X: 16*1024*1024
3877                         throw "abc"
3878                         Xloop 32                " X: 0
3879                     endif
3880                 catch /abc/
3881                     Xloop 64                    " X: 64*1024*1024
3882                 endtry
3883             catch /ab/
3884                 Xloop 128                       " X: 128*1024
3885             endtry
3886         catch /.*/
3887             Xloop 256                           " X: 256
3888         endtry
3889     catch /a/
3890         Xloop 512                               " X: 0
3891     endtry
3893     let loops = loops - 1
3894     XloopNEXT
3895 endwhile
3896 Xpath 1073741824                                " X: 1073741824
3898 unlet loops
3900 Xcheck 1157763329
3903 "-------------------------------------------------------------------------------
3904 " Test 46:  Executing :finally after a :throw in nested :try                {{{1
3906 "           When an exception is thrown from within nested :try blocks, the
3907 "           :finally clauses of the non-catching try conditionals should be
3908 "           executed before the matching :catch of the next surrounding :try
3909 "           gets the control.  If this also has a :finally clause, it is
3910 "           executed afterwards.
3911 "-------------------------------------------------------------------------------
3913 XpathINIT
3915 let sum = 0
3918     Xpath 1                                     " X: 1
3919     try
3920         Xpath 2                                 " X: 2
3921         try
3922             Xpath 4                             " X: 4
3923             try
3924                 Xpath 8                         " X: 8
3925                 throw "ABC"
3926                 Xpath 16                        " X: 0
3927             catch /xyz/
3928                 Xpath 32                        " X: 0
3929             finally
3930                 Xpath 64                        " X: 64
3931                 if sum != 0
3932                     Xpath 128                   " X: 0
3933                 endif
3934                 let sum = sum + 1
3935             endtry
3936             Xpath 256                           " X: 0
3937         catch /123/
3938             Xpath 512                           " X: 0
3939         catch /321/
3940             Xpath 1024                          " X: 0
3941         finally
3942             Xpath 2048                          " X: 2048
3943             if sum != 1
3944                 Xpath 4096                      " X: 0
3945             endif
3946             let sum = sum + 2
3947         endtry
3948         Xpath 8192                              " X: 0
3949     finally
3950         Xpath 16384                             " X: 16384
3951         if sum != 3
3952             Xpath 32768                         " X: 0
3953         endif
3954         let sum = sum + 4
3955     endtry
3956     Xpath 65536                                 " X: 0
3957 catch /ABC/
3958     Xpath 131072                                " X: 131072
3959     if sum != 7
3960         Xpath 262144                            " X: 0
3961     endif
3962     let sum = sum + 8
3963 finally
3964     Xpath 524288                                " X: 524288
3965     if sum != 15
3966         Xpath 1048576                           " X: 0
3967     endif
3968     let sum = sum + 16
3969 endtry
3970 Xpath 65536                                     " X: 65536
3971 if sum != 31
3972     Xpath 131072                                " X: 0
3973 endif
3975 unlet sum
3977 Xcheck 739407
3980 "-------------------------------------------------------------------------------
3981 " Test 47:  Throwing exceptions from a :catch clause                        {{{1
3983 "           When an exception is thrown from a :catch clause, it should not be
3984 "           caught by a :catch of the same :try conditional.  After executing
3985 "           the :finally clause (if present), surrounding try conditionals
3986 "           should be checked for a matching :catch.
3987 "-------------------------------------------------------------------------------
3989 XpathINIT
3991 Xpath 1                                         " X: 1
3993     Xpath 2                                     " X: 2
3994     try
3995         Xpath 4                                 " X: 4
3996         try
3997             Xpath 8                             " X: 8
3998             throw "x1"
3999             Xpath 16                            " X: 0
4000         catch /x1/
4001             Xpath 32                            " X: 32
4002             try
4003                 Xpath 64                        " X: 64
4004                 throw "x2"
4005                 Xpath 128                       " X: 0
4006             catch /x1/
4007                 Xpath 256                       " X: 0
4008             catch /x2/
4009                 Xpath 512                       " X: 512
4010                 try
4011                     Xpath 1024                  " X: 1024
4012                     throw "x3"
4013                     Xpath 2048                  " X: 0
4014                 catch /x1/
4015                     Xpath 4096                  " X: 0
4016                 catch /x2/
4017                     Xpath 8192                  " X: 0
4018                 finally
4019                     Xpath 16384                 " X: 16384
4020                 endtry
4021                 Xpath 32768                     " X: 0
4022             catch /x3/
4023                 Xpath 65536                     " X: 0
4024             endtry
4025             Xpath 131072                        " X: 0
4026         catch /x1/
4027             Xpath 262144                        " X: 0
4028         catch /x2/
4029             Xpath 524288                        " X: 0
4030         catch /x3/
4031             Xpath 1048576                       " X: 0
4032         finally
4033             Xpath 2097152                       " X: 2097152
4034         endtry
4035         Xpath 4194304                           " X: 0
4036     catch /x1/
4037         Xpath 8388608                           " X: 0
4038     catch /x2/
4039         Xpath 16777216                          " X: 0
4040     catch /x3/
4041         Xpath 33554432                          " X: 33554432
4042     endtry
4043     Xpath 67108864                              " X: 67108864
4044 catch /.*/
4045     Xpath 134217728                             " X: 0
4046     Xout v:exception "in" v:throwpoint
4047 endtry
4048 Xpath 268435456                                 " X: 268435456
4050 Xcheck 371213935
4053 "-------------------------------------------------------------------------------
4054 " Test 48:  Throwing exceptions from a :finally clause                      {{{1
4056 "           When an exception is thrown from a :finally clause, it should not be
4057 "           caught by a :catch of the same :try conditional.  Surrounding try
4058 "           conditionals should be checked for a matching :catch.  A previously
4059 "           thrown exception is discarded.
4060 "-------------------------------------------------------------------------------
4062 XpathINIT
4066     try
4067         try
4068             Xpath 1                             " X: 1
4069         catch /x1/
4070             Xpath 2                             " X: 0
4071         finally
4072             Xpath 4                             " X: 4
4073             throw "x1"
4074             Xpath 8                             " X: 0
4075         endtry
4076         Xpath 16                                " X: 0
4077     catch /x1/
4078         Xpath 32                                " X: 32
4079     endtry
4080     Xpath 64                                    " X: 64
4082     try
4083         try
4084             Xpath 128                           " X: 128
4085             throw "x2"
4086             Xpath 256                           " X: 0
4087         catch /x2/
4088             Xpath 512                           " X: 512
4089         catch /x3/
4090             Xpath 1024                          " X: 0
4091         finally
4092             Xpath 2048                          " X: 2048
4093             throw "x3"
4094             Xpath 4096                          " X: 0
4095         endtry
4096         Xpath 8192                              " X: 0
4097     catch /x2/
4098         Xpath 16384                             " X: 0
4099     catch /x3/
4100         Xpath 32768                             " X: 32768
4101     endtry
4102     Xpath 65536                                 " X: 65536
4104     try
4105         try
4106             try
4107                 Xpath 131072                    " X: 131072
4108                 throw "x4"
4109                 Xpath 262144                    " X: 0
4110             catch /x5/
4111                 Xpath 524288                    " X: 0
4112             finally
4113                 Xpath 1048576                   " X: 1048576
4114                 throw "x5"      " discards "x4"
4115                 Xpath 2097152                   " X: 0
4116             endtry
4117             Xpath 4194304                       " X: 0
4118         catch /x4/
4119             Xpath 8388608                       " X: 0
4120         finally
4121             Xpath 16777216                      " X: 16777216
4122         endtry
4123         Xpath 33554432                          " X: 0
4124     catch /x5/
4125         Xpath 67108864                          " X: 67108864
4126     endtry
4127     Xpath 134217728                             " X: 134217728
4129 catch /.*/
4130     Xpath 268435456                             " X: 0
4131     Xout v:exception "in" v:throwpoint
4132 endtry
4133 Xpath 536870912                                 " X: 536870912
4135 Xcheck 756255461
4138 "-------------------------------------------------------------------------------
4139 " Test 49:  Throwing exceptions across functions                            {{{1
4141 "           When an exception is thrown but not caught inside a function, the
4142 "           caller is checked for a matching :catch clause.
4143 "-------------------------------------------------------------------------------
4145 XpathINIT
4147 function! C()
4148     try
4149         Xpath 1                                 " X: 1
4150         throw "arrgh"
4151         Xpath 2                                 " X: 0
4152     catch /arrgh/
4153         Xpath 4                                 " X: 4
4154     endtry
4155     Xpath 8                                     " X: 8
4156 endfunction
4158 XloopINIT! 16 16
4160 function! T1()
4161     XloopNEXT
4162     try
4163         Xloop 1                                 " X: 16 + 16*16
4164         throw "arrgh"
4165         Xloop 2                                 " X: 0
4166     finally
4167         Xloop 4                                 " X: 64 + 64*16
4168     endtry
4169     Xloop 8                                     " X: 0
4170 endfunction
4172 function! T2()
4173     try
4174         Xpath 4096                              " X: 4096
4175         call T1()
4176         Xpath 8192                              " X: 0
4177     finally
4178         Xpath 16384                             " X: 16384
4179     endtry
4180     Xpath 32768                                 " X: 0
4181 endfunction
4184     Xpath 65536                                 " X: 65536
4185     call C()    " throw and catch
4186     Xpath 131072                                " X: 131072
4187 catch /.*/
4188     Xpath 262144                                " X: 0
4189     Xout v:exception "in" v:throwpoint
4190 endtry
4193     Xpath 524288                                " X: 524288
4194     call T1()  " throw, one level
4195     Xpath 1048576                               " X: 0
4196 catch /arrgh/
4197     Xpath 2097152                               " X: 2097152
4198 catch /.*/
4199     Xpath 4194304                               " X: 0
4200     Xout v:exception "in" v:throwpoint
4201 endtry
4204     Xpath 8388608                               " X: 8388608
4205     call T2()   " throw, two levels
4206     Xpath 16777216                              " X: 0
4207 catch /arrgh/
4208     Xpath 33554432                              " X: 33554432
4209 catch /.*/
4210     Xpath 67108864                              " X: 0
4211     Xout v:exception "in" v:throwpoint
4212 endtry
4213 Xpath 134217728                                 " X: 134217728
4215 Xcheck 179000669
4217 " Leave C, T1, and T2 for execution as scripts in the next test.
4220 "-------------------------------------------------------------------------------
4221 " Test 50:  Throwing exceptions across script files                         {{{1
4223 "           When an exception is thrown but not caught inside a script file,
4224 "           the sourcing script or function is checked for a matching :catch
4225 "           clause.
4227 "           This test executes the bodies of the functions C, T1, and T2 from
4228 "           the previous test as script files (:return replaced by :finish).
4229 "-------------------------------------------------------------------------------
4231 XpathINIT
4233 let scriptC = MakeScript("C")                   " X: 1 + 4 + 8
4234 delfunction C
4236 XloopINIT! 16 16
4238 let scriptT1 = MakeScript("T1")                 " X: 16 + 64 + 16*16 + 64*16
4239 delfunction T1
4241 let scriptT2 = MakeScript("T2", scriptT1)       " X: 4096 + 16384
4242 delfunction T2
4244 function! F()
4245     try
4246         Xpath 65536                             " X: 65536
4247         exec "source" g:scriptC
4248         Xpath 131072                            " X: 131072
4249     catch /.*/
4250         Xpath 262144                            " X: 0
4251         Xout v:exception "in" v:throwpoint
4252     endtry
4254     try
4255         Xpath 524288                            " X: 524288
4256         exec "source" g:scriptT1
4257         Xpath 1048576                           " X: 0
4258     catch /arrgh/
4259         Xpath 2097152                           " X: 2097152
4260     catch /.*/
4261         Xpath 4194304                           " X: 0
4262         Xout v:exception "in" v:throwpoint
4263     endtry
4264 endfunction
4267     Xpath 8388608                               " X: 8388608
4268     call F()
4269     Xpath 16777216                              " X: 16777216
4270     exec "source" scriptT2
4271     Xpath 33554432                              " X: 0
4272 catch /arrgh/
4273     Xpath 67108864                              " X: 67108864
4274 catch /.*/
4275     Xpath 134217728                             " X: 0
4276     Xout v:exception "in" v:throwpoint
4277 endtry
4278 Xpath 268435456                                 " X: 268435456
4280 call delete(scriptC)
4281 call delete(scriptT1)
4282 call delete(scriptT2)
4283 unlet scriptC scriptT1 scriptT2
4284 delfunction F
4286 Xcheck 363550045
4289 "-------------------------------------------------------------------------------
4290 " Test 51:  Throwing exceptions across :execute and user commands           {{{1
4292 "           A :throw command may be executed under an ":execute" or from
4293 "           a user command.
4294 "-------------------------------------------------------------------------------
4296 XpathINIT
4298 command! -nargs=? THROW1    throw <args> | throw 1
4299 command! -nargs=? THROW2    try | throw <args> | endtry | throw 2
4300 command! -nargs=? THROW3    try | throw 3 | catch /3/ | throw <args> | endtry
4301 command! -nargs=? THROW4    try | throw 4 | finally   | throw <args> | endtry
4305     try
4306         try
4307             Xpath 1                             " X: 1
4308             THROW1 "A"
4309         catch /A/
4310             Xpath 2                             " X: 2
4311         endtry
4312     catch /1/
4313         Xpath 4                                 " X: 0
4314     endtry
4316     try
4317         try
4318             Xpath 8                             " X: 8
4319             THROW2 "B"
4320         catch /B/
4321             Xpath 16                            " X: 16
4322         endtry
4323     catch /2/
4324         Xpath 32                                " X: 0
4325     endtry
4327     try
4328         try
4329             Xpath 64                            " X: 64
4330             THROW3 "C"
4331         catch /C/
4332             Xpath 128                           " X: 128
4333         endtry
4334     catch /3/
4335         Xpath 256                               " X: 0
4336     endtry
4338     try
4339         try
4340             Xpath 512                           " X: 512
4341             THROW4 "D"
4342         catch /D/
4343             Xpath 1024                          " X: 1024
4344         endtry
4345     catch /4/
4346         Xpath 2048                              " X: 0
4347     endtry
4349     try
4350         try
4351             Xpath 4096                          " X: 4096
4352             execute 'throw "E" | throw 5'
4353         catch /E/
4354             Xpath 8192                          " X: 8192
4355         endtry
4356     catch /5/
4357         Xpath 16384                             " X: 0
4358     endtry
4360     try
4361         try
4362             Xpath 32768                         " X: 32768
4363             execute 'try | throw "F" | endtry | throw 6'
4364         catch /F/
4365             Xpath 65536                         " X: 65536
4366         endtry
4367     catch /6/
4368         Xpath 131072                            " X: 0
4369     endtry
4371     try
4372         try
4373             Xpath 262144                        " X: 262144
4374             execute'try | throw 7 | catch /7/ | throw "G" | endtry'
4375         catch /G/
4376             Xpath 524288                        " X: 524288
4377         endtry
4378     catch /7/
4379         Xpath 1048576                           " X: 0
4380     endtry
4382     try
4383         try
4384             Xpath 2097152                       " X: 2097152
4385             execute 'try | throw 8 | finally   | throw "H" | endtry'
4386         catch /H/
4387             Xpath 4194304                       " X: 4194304
4388         endtry
4389     catch /8/
4390         Xpath 8388608                           " X: 0
4391     endtry
4393 catch /.*/
4394     Xpath 16777216                              " X: 0
4395     Xout v:exception "in" v:throwpoint
4396 endtry
4398 Xpath 33554432                                  " X: 33554432
4400 delcommand THROW1
4401 delcommand THROW2
4402 delcommand THROW3
4403 delcommand THROW4
4405 Xcheck 40744667
4408 "-------------------------------------------------------------------------------
4409 " Test 52:  Uncaught exceptions                                             {{{1
4411 "           When an exception is thrown but not caught, an error message is
4412 "           displayed when the script is terminated.  In case of an interrupt
4413 "           or error exception, the normal interrupt or error message(s) are
4414 "           displayed.
4415 "-------------------------------------------------------------------------------
4417 XpathINIT
4419 let msgfile = tempname()
4421 function! MESSAGES(...)
4422     try
4423         exec "edit" g:msgfile
4424     catch /^Vim(edit):/
4425         return 0
4426     endtry
4428     let english = v:lang == "C" || v:lang =~ '^[Ee]n'
4429     let match = 1
4430     norm gg
4432     let num = a:0 / 2
4433     let cnt = 1
4434     while cnt <= num
4435         let enr = a:{2*cnt - 1}
4436         let emsg= a:{2*cnt}
4437         let cnt = cnt + 1
4439         if enr == ""
4440             Xout "TODO: Add message number for:" emsg
4441         elseif enr == "INT"
4442             let enr = ""
4443         endif
4444         if enr == "" && !english
4445             continue
4446         endif
4447         let pattern = (enr != "") ? enr . ':.*' : ''
4448         if english
4449             let pattern = pattern . emsg
4450         endif
4451         if !search(pattern, "W")
4452             let match = 0
4453             Xout "No match for:" pattern
4454         endif
4455         norm $
4456     endwhile
4458     bwipeout!
4459     return match
4460 endfunction
4462 if ExtraVim(msgfile)
4463     Xpath 1                                     " X: 1
4464     throw "arrgh"
4465 endif
4467 Xpath 2                                         " X: 2
4468 if !MESSAGES('E605', "Exception not caught")
4469     Xpath 4                                     " X: 0
4470 endif
4472 if ExtraVim(msgfile)
4473     try
4474         Xpath 8                                 " X: 8
4475         throw "oops"
4476     catch /arrgh/
4477         Xpath 16                                " X: 0
4478     endtry
4479     Xpath 32                                    " X: 0
4480 endif
4482 Xpath 64                                        " X: 64
4483 if !MESSAGES('E605', "Exception not caught")
4484     Xpath 128                                   " X: 0
4485 endif
4487 if ExtraVim(msgfile)
4488     function! T()
4489         throw "brrr"
4490     endfunction
4492     try
4493         Xpath 256                               " X: 256
4494         throw "arrgh"
4495     catch /.*/
4496         Xpath 512                               " X: 512
4497         call T()
4498     endtry
4499     Xpath 1024                                  " X: 0
4500 endif
4502 Xpath 2048                                      " X: 2048
4503 if !MESSAGES('E605', "Exception not caught")
4504     Xpath 4096                                  " X: 0
4505 endif
4507 if ExtraVim(msgfile)
4508     try
4509         Xpath 8192                              " X: 8192
4510         throw "arrgh"
4511     finally
4512         Xpath 16384                             " X: 16384
4513         throw "brrr"
4514     endtry
4515     Xpath 32768                                 " X: 0
4516 endif
4518 Xpath 65536                                     " X: 65536
4519 if !MESSAGES('E605', "Exception not caught")
4520     Xpath 131072                                " X: 0
4521 endif
4523 if ExtraVim(msgfile)
4524     try
4525         Xpath 262144                            " X: 262144
4526         "INTERRUPT
4527     endtry
4528     Xpath 524288                                " X: 0
4529 endif
4531 Xpath 1048576                                   " X: 1048576
4532 if !MESSAGES('INT', "Interrupted")
4533     Xpath 2097152                               " X: 0
4534 endif
4536 if ExtraVim(msgfile)
4537     try
4538         Xpath 4194304                           " X: 4194304
4539         let x = novar   " error E121/E15; exception: E121
4540     catch /E15:/        " should not catch
4541         Xpath 8388608                           " X: 0
4542     endtry
4543     Xpath 16777216                              " X: 0
4544 endif
4546 Xpath 33554432                                  " X: 33554432
4547 if !MESSAGES('E121', "Undefined variable", 'E15', "Invalid expression")
4548     Xpath 67108864                              " X: 0
4549 endif
4551 if ExtraVim(msgfile)
4552     try
4553         Xpath 134217728                         " X: 134217728
4554 "       unlet novar #   " error E108/E488; exception: E488
4555     catch /E108:/       " should not catch
4556         Xpath 268435456                         " X: 0
4557     endtry
4558     Xpath 536870912                             " X: 0
4559 endif
4561 Xpath 1073741824                                " X: 1073741824
4562 if !MESSAGES('E108', "No such variable", 'E488', "Trailing characters")
4563     " The Xpath command does not accept 2^31 (negative); add explicitly:
4564     let Xpath = Xpath + 2147483648              " X: 0
4565 endif
4567 call delete(msgfile)
4568 unlet msgfile
4570 Xcheck 1247112011
4572 " Leave MESSAGES() for the next tests.
4575 "-------------------------------------------------------------------------------
4576 " Test 53:  Nesting errors: :endif/:else/:elseif                            {{{1
4578 "           For nesting errors of :if conditionals the correct error messages
4579 "           should be given.
4581 "           This test reuses the function MESSAGES() from the previous test.
4582 "           This functions checks the messages in g:msgfile.
4583 "-------------------------------------------------------------------------------
4585 XpathINIT
4587 let msgfile = tempname()
4589 if ExtraVim(msgfile)
4590 "   endif
4591 endif
4592 if MESSAGES('E580', ":endif without :if")
4593     Xpath 1                                     " X: 1
4594 endif
4596 if ExtraVim(msgfile)
4597 "   while 1
4598 "       endif
4599 "   endwhile
4600 endif
4601 if MESSAGES('E580', ":endif without :if")
4602     Xpath 2                                     " X: 2
4603 endif
4605 if ExtraVim(msgfile)
4606 "   try
4607 "   finally
4608 "       endif
4609 "   endtry
4610 endif
4611 if MESSAGES('E580', ":endif without :if")
4612     Xpath 4                                     " X: 4
4613 endif
4615 if ExtraVim(msgfile)
4616 "   try
4617 "       endif
4618 "   endtry
4619 endif
4620 if MESSAGES('E580', ":endif without :if")
4621     Xpath 8                                     " X: 8
4622 endif
4624 if ExtraVim(msgfile)
4625 "   try
4626 "       throw "a"
4627 "   catch /a/
4628 "       endif
4629 "   endtry
4630 endif
4631 if MESSAGES('E580', ":endif without :if")
4632     Xpath 16                                    " X: 16
4633 endif
4635 if ExtraVim(msgfile)
4636 "   else
4637 endif
4638 if MESSAGES('E581', ":else without :if")
4639     Xpath 32                                    " X: 32
4640 endif
4642 if ExtraVim(msgfile)
4643 "   while 1
4644 "       else
4645 "   endwhile
4646 endif
4647 if MESSAGES('E581', ":else without :if")
4648     Xpath 64                                    " X: 64
4649 endif
4651 if ExtraVim(msgfile)
4652 "   try
4653 "   finally
4654 "       else
4655 "   endtry
4656 endif
4657 if MESSAGES('E581', ":else without :if")
4658     Xpath 128                                   " X: 128
4659 endif
4661 if ExtraVim(msgfile)
4662 "   try
4663 "       else
4664 "   endtry
4665 endif
4666 if MESSAGES('E581', ":else without :if")
4667     Xpath 256                                   " X: 256
4668 endif
4670 if ExtraVim(msgfile)
4671 "   try
4672 "       throw "a"
4673 "   catch /a/
4674 "       else
4675 "   endtry
4676 endif
4677 if MESSAGES('E581', ":else without :if")
4678     Xpath 512                                   " X: 512
4679 endif
4681 if ExtraVim(msgfile)
4682 "   elseif
4683 endif
4684 if MESSAGES('E582', ":elseif without :if")
4685     Xpath 1024                                  " X: 1024
4686 endif
4688 if ExtraVim(msgfile)
4689 "   while 1
4690 "       elseif
4691 "   endwhile
4692 endif
4693 if MESSAGES('E582', ":elseif without :if")
4694     Xpath 2048                                  " X: 2048
4695 endif
4697 if ExtraVim(msgfile)
4698 "   try
4699 "   finally
4700 "       elseif
4701 "   endtry
4702 endif
4703 if MESSAGES('E582', ":elseif without :if")
4704     Xpath 4096                                  " X: 4096
4705 endif
4707 if ExtraVim(msgfile)
4708 "   try
4709 "       elseif
4710 "   endtry
4711 endif
4712 if MESSAGES('E582', ":elseif without :if")
4713     Xpath 8192                                  " X: 8192
4714 endif
4716 if ExtraVim(msgfile)
4717 "   try
4718 "       throw "a"
4719 "   catch /a/
4720 "       elseif
4721 "   endtry
4722 endif
4723 if MESSAGES('E582', ":elseif without :if")
4724     Xpath 16384                                 " X: 16384
4725 endif
4727 if ExtraVim(msgfile)
4728 "   if 1
4729 "   else
4730 "   else
4731 "   endif
4732 endif
4733 if MESSAGES('E583', "multiple :else")
4734     Xpath 32768                                 " X: 32768
4735 endif
4737 if ExtraVim(msgfile)
4738 "   if 1
4739 "   else
4740 "   elseif 1
4741 "   endif
4742 endif
4743 if MESSAGES('E584', ":elseif after :else")
4744     Xpath 65536                                 " X: 65536
4745 endif
4747 call delete(msgfile)
4748 unlet msgfile
4750 Xcheck 131071
4752 " Leave MESSAGES() for the next test.
4755 "-------------------------------------------------------------------------------
4756 " Test 54:  Nesting errors: :while/:endwhile                                {{{1
4758 "           For nesting errors of :while conditionals the correct error messages
4759 "           should be given.
4761 "           This test reuses the function MESSAGES() from the previous test.
4762 "           This functions checks the messages in g:msgfile.
4763 "-------------------------------------------------------------------------------
4765 XpathINIT
4767 let msgfile = tempname()
4769 if ExtraVim(msgfile)
4770 "   endwhile
4771 endif
4772 if MESSAGES('E588', ":endwhile without :while")
4773     Xpath 1                                     " X: 1
4774 endif
4776 if ExtraVim(msgfile)
4777 "   if 1
4778 "       endwhile
4779 "   endif
4780 endif
4781 if MESSAGES('E588', ":endwhile without :while")
4782     Xpath 2                                     " X: 2
4783 endif
4785 if ExtraVim(msgfile)
4786 "   while 1
4787 "       if 1
4788 "   endwhile
4789 endif
4790 if MESSAGES('E171', "Missing :endif")
4791     Xpath 4                                     " X: 4
4792 endif
4794 if ExtraVim(msgfile)
4795 "   try
4796 "   finally
4797 "       endwhile
4798 "   endtry
4799 endif
4800 if MESSAGES('E588', ":endwhile without :while")
4801     Xpath 8                                     " X: 8
4802 endif
4804 if ExtraVim(msgfile)
4805 "   while 1
4806 "       try
4807 "       finally
4808 "   endwhile
4809 endif
4810 if MESSAGES('E600', "Missing :endtry")
4811     Xpath 16                                    " X: 16
4812 endif
4814 if ExtraVim(msgfile)
4815 "   while 1
4816 "       if 1
4817 "           try
4818 "           finally
4819 "   endwhile
4820 endif
4821 if MESSAGES('E600', "Missing :endtry")
4822     Xpath 32                                    " X: 32
4823 endif
4825 if ExtraVim(msgfile)
4826 "   while 1
4827 "       try
4828 "       finally
4829 "           if 1
4830 "   endwhile
4831 endif
4832 if MESSAGES('E171', "Missing :endif")
4833     Xpath 64                                    " X: 64
4834 endif
4836 if ExtraVim(msgfile)
4837 "   try
4838 "       endwhile
4839 "   endtry
4840 endif
4841 if MESSAGES('E588', ":endwhile without :while")
4842     Xpath 128                                   " X: 128
4843 endif
4845 if ExtraVim(msgfile)
4846 "   while 1
4847 "       try
4848 "           endwhile
4849 "       endtry
4850 "   endwhile
4851 endif
4852 if MESSAGES('E588', ":endwhile without :while")
4853     Xpath 256                                   " X: 256
4854 endif
4856 if ExtraVim(msgfile)
4857 "   try
4858 "       throw "a"
4859 "   catch /a/
4860 "       endwhile
4861 "   endtry
4862 endif
4863 if MESSAGES('E588', ":endwhile without :while")
4864     Xpath 512                                   " X: 512
4865 endif
4867 if ExtraVim(msgfile)
4868 "   while 1
4869 "       try
4870 "           throw "a"
4871 "       catch /a/
4872 "           endwhile
4873 "       endtry
4874 "   endwhile
4875 endif
4876 if MESSAGES('E588', ":endwhile without :while")
4877     Xpath 1024                                  " X: 1024
4878 endif
4881 call delete(msgfile)
4882 unlet msgfile
4884 Xcheck 2047
4886 " Leave MESSAGES() for the next test.
4889 "-------------------------------------------------------------------------------
4890 " Test 55:  Nesting errors: :continue/:break                                {{{1
4892 "           For nesting errors of :continue and :break commands the correct
4893 "           error messages should be given.
4895 "           This test reuses the function MESSAGES() from the previous test.
4896 "           This functions checks the messages in g:msgfile.
4897 "-------------------------------------------------------------------------------
4899 XpathINIT
4901 let msgfile = tempname()
4903 if ExtraVim(msgfile)
4904 "   continue
4905 endif
4906 if MESSAGES('E586', ":continue without :while")
4907     Xpath 1                                     " X: 1
4908 endif
4910 if ExtraVim(msgfile)
4911 "   if 1
4912 "       continue
4913 "   endif
4914 endif
4915 if MESSAGES('E586', ":continue without :while")
4916     Xpath 2                                     " X: 2
4917 endif
4919 if ExtraVim(msgfile)
4920 "   try
4921 "   finally
4922 "       continue
4923 "   endtry
4924 endif
4925 if MESSAGES('E586', ":continue without :while")
4926     Xpath 4                                     " X: 4
4927 endif
4929 if ExtraVim(msgfile)
4930 "   try
4931 "       continue
4932 "   endtry
4933 endif
4934 if MESSAGES('E586', ":continue without :while")
4935     Xpath 8                                     " X: 8
4936 endif
4938 if ExtraVim(msgfile)
4939 "   try
4940 "       throw "a"
4941 "   catch /a/
4942 "       continue
4943 "   endtry
4944 endif
4945 if MESSAGES('E586', ":continue without :while")
4946     Xpath 16                                    " X: 16
4947 endif
4949 if ExtraVim(msgfile)
4950 "   break
4951 endif
4952 if MESSAGES('E587', ":break without :while")
4953     Xpath 32                                    " X: 32
4954 endif
4956 if ExtraVim(msgfile)
4957 "   if 1
4958 "       break
4959 "   endif
4960 endif
4961 if MESSAGES('E587', ":break without :while")
4962     Xpath 64                                    " X: 64
4963 endif
4965 if ExtraVim(msgfile)
4966 "   try
4967 "   finally
4968 "       break
4969 "   endtry
4970 endif
4971 if MESSAGES('E587', ":break without :while")
4972     Xpath 128                                   " X: 128
4973 endif
4975 if ExtraVim(msgfile)
4976 "   try
4977 "       break
4978 "   endtry
4979 endif
4980 if MESSAGES('E587', ":break without :while")
4981     Xpath 256                                   " X: 256
4982 endif
4984 if ExtraVim(msgfile)
4985 "   try
4986 "       throw "a"
4987 "   catch /a/
4988 "       break
4989 "   endtry
4990 endif
4991 if MESSAGES('E587', ":break without :while")
4992     Xpath 512                                   " X: 512
4993 endif
4995 call delete(msgfile)
4996 unlet msgfile
4998 Xcheck 1023
5000 " Leave MESSAGES() for the next test.
5003 "-------------------------------------------------------------------------------
5004 " Test 56:  Nesting errors: :endtry                                         {{{1
5006 "           For nesting errors of :try conditionals the correct error messages
5007 "           should be given.
5009 "           This test reuses the function MESSAGES() from the previous test.
5010 "           This functions checks the messages in g:msgfile.
5011 "-------------------------------------------------------------------------------
5013 XpathINIT
5015 let msgfile = tempname()
5017 if ExtraVim(msgfile)
5018 "   endtry
5019 endif
5020 if MESSAGES('E602', ":endtry without :try")
5021     Xpath 1                                     " X: 1
5022 endif
5024 if ExtraVim(msgfile)
5025 "   if 1
5026 "       endtry
5027 "   endif
5028 endif
5029 if MESSAGES('E602', ":endtry without :try")
5030     Xpath 2                                     " X: 2
5031 endif
5033 if ExtraVim(msgfile)
5034 "   while 1
5035 "       endtry
5036 "   endwhile
5037 endif
5038 if MESSAGES('E602', ":endtry without :try")
5039     Xpath 4                                     " X: 4
5040 endif
5042 if ExtraVim(msgfile)
5043 "   try
5044 "       if 1
5045 "   endtry
5046 endif
5047 if MESSAGES('E171', "Missing :endif")
5048     Xpath 8                                     " X: 8
5049 endif
5051 if ExtraVim(msgfile)
5052 "   try
5053 "       while 1
5054 "   endtry
5055 endif
5056 if MESSAGES('E170', "Missing :endwhile")
5057     Xpath 16                                    " X: 16
5058 endif
5060 if ExtraVim(msgfile)
5061 "   try
5062 "   finally
5063 "       if 1
5064 "   endtry
5065 endif
5066 if MESSAGES('E171', "Missing :endif")
5067     Xpath 32                                    " X: 32
5068 endif
5070 if ExtraVim(msgfile)
5071 "   try
5072 "   finally
5073 "       while 1
5074 "   endtry
5075 endif
5076 if MESSAGES('E170', "Missing :endwhile")
5077     Xpath 64                                    " X: 64
5078 endif
5080 if ExtraVim(msgfile)
5081 "   try
5082 "       throw "a"
5083 "   catch /a/
5084 "       if 1
5085 "   endtry
5086 endif
5087 if MESSAGES('E171', "Missing :endif")
5088     Xpath 128                                   " X: 128
5089 endif
5091 if ExtraVim(msgfile)
5092 "   try
5093 "       throw "a"
5094 "   catch /a/
5095 "       while 1
5096 "   endtry
5097 endif
5098 if MESSAGES('E170', "Missing :endwhile")
5099     Xpath 256                                   " X: 256
5100 endif
5102 call delete(msgfile)
5103 unlet msgfile
5105 delfunction MESSAGES
5107 Xcheck 511
5110 "-------------------------------------------------------------------------------
5111 " Test 57:  v:exception and v:throwpoint for user exceptions                {{{1
5113 "           v:exception evaluates to the value of the exception that was caught
5114 "           most recently and is not finished.  (A caught exception is finished
5115 "           when the next ":catch", ":finally", or ":endtry" is reached.)
5116 "           v:throwpoint evaluates to the script/function name and line number
5117 "           where that exception has been thrown.
5118 "-------------------------------------------------------------------------------
5120 XpathINIT
5122 function! FuncException()
5123     let g:exception = v:exception
5124 endfunction
5126 function! FuncThrowpoint()
5127     let g:throwpoint = v:throwpoint
5128 endfunction
5130 let scriptException  = MakeScript("FuncException")
5131 let scriptThrowPoint = MakeScript("FuncThrowpoint")
5133 command! CmdException  let g:exception  = v:exception
5134 command! CmdThrowpoint let g:throwpoint = v:throwpoint
5136 XloopINIT! 1 2
5138 function! CHECK(n, exception, throwname, throwline)
5139     XloopNEXT
5140     let error = 0
5141     if v:exception != a:exception
5142         Xout a:n.": v:exception is" v:exception "instead of" a:exception
5143         let error = 1
5144     endif
5145     if v:throwpoint !~ a:throwname
5146         let name = escape(a:throwname, '\')
5147         Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" name
5148         let error = 1
5149     endif
5150     if v:throwpoint !~ a:throwline
5151         let line = escape(a:throwline, '\')
5152         Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
5153         let error = 1
5154     endif
5155     if error
5156         Xloop 1                                 " X: 0
5157     endif
5158 endfunction
5160 function! T(arg, line)
5161     if a:line == 2
5162         throw a:arg             " in line 2
5163     elseif a:line == 4
5164         throw a:arg             " in line 4
5165     elseif a:line == 6
5166         throw a:arg             " in line 6
5167     elseif a:line == 8
5168         throw a:arg             " in line 8
5169     endif
5170 endfunction
5172 function! G(arg, line)
5173     call T(a:arg, a:line)
5174 endfunction
5176 function! F(arg, line)
5177     call G(a:arg, a:line)
5178 endfunction
5180 let scriptT = MakeScript("T")
5181 let scriptG = MakeScript("G", scriptT)
5182 let scriptF = MakeScript("F", scriptG)
5185     Xpath 32768                                 " X: 32768
5186     call F("oops", 2)
5187 catch /.*/
5188     Xpath 65536                                 " X: 65536
5189     let exception  = v:exception
5190     let throwpoint = v:throwpoint
5191     call CHECK(1, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
5192     exec "let exception  = v:exception"
5193     exec "let throwpoint = v:throwpoint"
5194     call CHECK(2, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
5195     CmdException
5196     CmdThrowpoint
5197     call CHECK(3, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
5198     call FuncException()
5199     call FuncThrowpoint()
5200     call CHECK(4, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
5201     exec "source" scriptException
5202     exec "source" scriptThrowPoint
5203     call CHECK(5, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
5204     try
5205         Xpath 131072                            " X: 131072
5206         call G("arrgh", 4)
5207     catch /.*/
5208         Xpath 262144                            " X: 262144
5209         let exception  = v:exception
5210         let throwpoint = v:throwpoint
5211         call CHECK(6, "arrgh", '\<G\.\.T\>', '\<4\>')
5212         try
5213             Xpath 524288                        " X: 524288
5214             let g:arg = "autsch"
5215             let g:line = 6
5216             exec "source" scriptF
5217         catch /.*/
5218             Xpath 1048576                       " X: 1048576
5219             let exception  = v:exception
5220             let throwpoint = v:throwpoint
5221             " Symbolic links in tempname()s are not resolved, whereas resolving
5222             " is done for v:throwpoint.  Resolve the temporary file name for
5223             " scriptT, so that it can be matched against v:throwpoint.
5224             call CHECK(7, "autsch", resolve(scriptT), '\<6\>')
5225         finally
5226             Xpath 2097152                       " X: 2097152
5227             let exception  = v:exception
5228             let throwpoint = v:throwpoint
5229             call CHECK(8, "arrgh", '\<G\.\.T\>', '\<4\>')
5230             try
5231                 Xpath 4194304                   " X: 4194304
5232                 let g:arg = "brrrr"
5233                 let g:line = 8
5234                 exec "source" scriptG
5235             catch /.*/
5236                 Xpath 8388608                   " X: 8388608
5237                 let exception  = v:exception
5238                 let throwpoint = v:throwpoint
5239                 " Resolve scriptT for matching it against v:throwpoint.
5240                 call CHECK(9, "brrrr", resolve(scriptT), '\<8\>')
5241             finally
5242                 Xpath 16777216                  " X: 16777216
5243                 let exception  = v:exception
5244                 let throwpoint = v:throwpoint
5245                 call CHECK(10, "arrgh", '\<G\.\.T\>', '\<4\>')
5246             endtry
5247             Xpath 33554432                      " X: 33554432
5248             let exception  = v:exception
5249             let throwpoint = v:throwpoint
5250             call CHECK(11, "arrgh", '\<G\.\.T\>', '\<4\>')
5251         endtry
5252         Xpath 67108864                          " X: 67108864
5253         let exception  = v:exception
5254         let throwpoint = v:throwpoint
5255         call CHECK(12, "arrgh", '\<G\.\.T\>', '\<4\>')
5256     finally
5257         Xpath 134217728                         " X: 134217728
5258         let exception  = v:exception
5259         let throwpoint = v:throwpoint
5260         call CHECK(13, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
5261     endtry
5262     Xpath 268435456                             " X: 268435456
5263     let exception  = v:exception
5264     let throwpoint = v:throwpoint
5265     call CHECK(14, "oops", '\<F\.\.G\.\.T\>', '\<2\>')
5266 finally
5267     Xpath 536870912                             " X: 536870912
5268     let exception  = v:exception
5269     let throwpoint = v:throwpoint
5270     call CHECK(15, "", '^$', '^$')
5271 endtry
5273 Xpath 1073741824                                " X: 1073741824
5275 unlet exception throwpoint
5276 delfunction FuncException
5277 delfunction FuncThrowpoint
5278 call delete(scriptException)
5279 call delete(scriptThrowPoint)
5280 unlet scriptException scriptThrowPoint
5281 delcommand CmdException
5282 delcommand CmdThrowpoint
5283 delfunction T
5284 delfunction G
5285 delfunction F
5286 call delete(scriptT)
5287 call delete(scriptG)
5288 call delete(scriptF)
5289 unlet scriptT scriptG scriptF
5291 Xcheck 2147450880
5294 "-------------------------------------------------------------------------------
5296 " Test 58:  v:exception and v:throwpoint for error/interrupt exceptions     {{{1
5298 "           v:exception and v:throwpoint work also for error and interrupt
5299 "           exceptions.
5300 "-------------------------------------------------------------------------------
5302 XpathINIT
5304 if ExtraVim()
5306     function! T(line)
5307         if a:line == 2
5308             delfunction T               " error (function in use) in line 2
5309         elseif a:line == 4
5310             let dummy = 0               " INTERRUPT1 - interrupt in line 4
5311         endif
5312     endfunction
5314     while 1
5315         try
5316             Xpath 1                             " X: 1
5317             let caught = 0
5318             call T(2)
5319         catch /.*/
5320             let caught = 1
5321             if v:exception !~ 'Vim(delfunction):'
5322                 Xpath 2                         " X: 0
5323             endif
5324             if v:throwpoint !~ '\<T\>'
5325                 Xpath 4                         " X: 0
5326             endif
5327             if v:throwpoint !~ '\<2\>'
5328                 Xpath 8                         " X: 0
5329             endif
5330         finally
5331             Xpath 16                            " X: 16
5332             if caught || $VIMNOERRTHROW
5333                 Xpath 32                        " X: 32
5334             endif
5335             if v:exception != ""
5336                 Xpath 64                        " X: 0
5337             endif
5338             if v:throwpoint != ""
5339                 Xpath 128                       " X: 0
5340             endif
5341             break               " discard error for $VIMNOERRTHROW
5342         endtry
5343     endwhile
5345     Xpath 256                                   " X: 256
5346     if v:exception != ""
5347         Xpath 512                               " X: 0
5348     endif
5349     if v:throwpoint != ""
5350         Xpath 1024                              " X: 0
5351     endif
5353     while 1
5354         try
5355             Xpath 2048                          " X: 2048
5356             let caught = 0
5357             call T(4)
5358         catch /.*/
5359             let caught = 1
5360             if v:exception != 'Vim:Interrupt'
5361                 Xpath 4096                      " X: 0
5362             endif
5363             if v:throwpoint !~ '\<T\>'
5364                 Xpath 8192                      " X: 0
5365             endif
5366             if v:throwpoint !~ '\<4\>'
5367                 Xpath 16384                     " X: 0
5368             endif
5369         finally
5370             Xpath 32768                         " X: 32768
5371             if caught || $VIMNOINTTHROW
5372                 Xpath 65536                     " X: 65536
5373             endif
5374             if v:exception != ""
5375                 Xpath 131072                    " X: 0
5376             endif
5377             if v:throwpoint != ""
5378                 Xpath 262144                    " X: 0
5379             endif
5380             break               " discard error for $VIMNOERRTHROW
5381         endtry
5382     endwhile
5384     Xpath 524288                                " X: 524288
5385     if v:exception != ""
5386         Xpath 1048576                           " X: 0
5387     endif
5388     if v:throwpoint != ""
5389         Xpath 2097152                           " X: 0
5390     endif
5392 endif
5394 Xcheck 624945
5397 "-------------------------------------------------------------------------------
5399 " Test 59:  v:exception and v:throwpoint when discarding exceptions         {{{1
5401 "           When a :catch clause is left by a ":break" etc or an error or
5402 "           interrupt exception, v:exception and v:throwpoint are reset.  They
5403 "           are not affected by an exception that is discarded before being
5404 "           caught.
5405 "-------------------------------------------------------------------------------
5407 XpathINIT
5409 if ExtraVim()
5411     XloopINIT! 1 2
5413     let sfile = expand("<sfile>")
5415     function! LineNumber()
5416         return substitute(substitute(v:throwpoint, g:sfile, '', ""),
5417             \ '\D*\(\d*\).*', '\1', "")
5418     endfunction
5420     command! -nargs=1 SetLineNumber
5421         \ try | throw "line" | catch /.*/ | let <args> =  LineNumber() | endtry
5423     " Check v:exception/v:throwpoint against second/fourth parameter if
5424     " specified, check for being empty else.
5425     function! CHECK(n, ...)
5426         XloopNEXT
5427         let exception = a:0 != 0 ? a:1 : ""     " second parameter (optional)
5428         let emsg      = a:0 != 0 ? a:2 : ""     " third parameter (optional)
5429         let line      = a:0 != 0 ? a:3 : 0      " fourth parameter (optional)
5430         let error = 0
5431         if emsg != ""
5432             " exception is the error number, emsg the English error message text
5433             if exception !~ '^E\d\+$'
5434                 Xout "TODO: Add message number for:" emsg
5435             elseif v:lang == "C" || v:lang =~ '^[Ee]n'
5436                 if exception == "E492" && emsg == "Not an editor command"
5437                     let exception = '^Vim:' . exception . ': ' . emsg
5438                 else
5439                     let exception = '^Vim(\a\+):' . exception . ': ' . emsg
5440                 endif
5441             else
5442                 if exception == "E492"
5443                     let exception = '^Vim:' . exception
5444                 else
5445                     let exception = '^Vim(\a\+):' . exception
5446                 endif
5447             endif
5448         endif
5449         if exception == "" && v:exception != ""
5450             Xout a:n.": v:exception is set:" v:exception
5451             let error = 1
5452         elseif exception != "" && v:exception !~ exception
5453             Xout a:n.": v:exception (".v:exception.") does not match" exception
5454             let error = 1
5455         endif
5456         if line == 0 && v:throwpoint != ""
5457             Xout a:n.": v:throwpoint is set:" v:throwpoint
5458             let error = 1
5459         elseif line != 0 && v:throwpoint !~ '\<' . line . '\>'
5460             Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
5461             let error = 1
5462         endif
5463         if !error
5464             Xloop 1                             " X: 2097151
5465         endif
5466     endfunction
5468     while 1
5469         try
5470             throw "x1"
5471         catch /.*/
5472             break
5473         endtry
5474     endwhile
5475     call CHECK(1)
5477     while 1
5478         try
5479             throw "x2"
5480         catch /.*/
5481             break
5482         finally
5483             call CHECK(2)
5484         endtry
5485         break
5486     endwhile
5487     call CHECK(3)
5489     while 1
5490         try
5491             let errcaught = 0
5492             try
5493                 try
5494                     throw "x3"
5495                 catch /.*/
5496                     SetLineNumber line_before_error
5497                     asdf
5498                 endtry
5499             catch /.*/
5500                 let errcaught = 1
5501                 call CHECK(4, 'E492', "Not an editor command",
5502                     \ line_before_error + 1)
5503             endtry
5504         finally
5505             if !errcaught && $VIMNOERRTHROW
5506                 call CHECK(4)
5507             endif
5508             break               " discard error for $VIMNOERRTHROW
5509         endtry
5510     endwhile
5511     call CHECK(5)
5513     Xpath 2097152                               " X: 2097152
5515     while 1
5516         try
5517             let intcaught = 0
5518             try
5519                 try
5520                     throw "x4"
5521                 catch /.*/
5522                     SetLineNumber two_lines_before_interrupt
5523                     "INTERRUPT
5524                     let dummy = 0
5525                 endtry
5526             catch /.*/
5527                 let intcaught = 1
5528                 call CHECK(6, "Vim:Interrupt", '',
5529                     \ two_lines_before_interrupt + 2)
5530             endtry
5531         finally
5532             if !intcaught && $VIMNOINTTHROW
5533                 call CHECK(6)
5534             endif
5535             break               " discard interrupt for $VIMNOINTTHROW
5536         endtry
5537     endwhile
5538     call CHECK(7)
5540     Xpath 4194304                               " X: 4194304
5542     while 1
5543         try
5544             let errcaught = 0
5545             try
5546                 try
5547 "                   if 1
5548                         SetLineNumber line_before_throw
5549                         throw "x5"
5550                     " missing endif
5551                 catch /.*/
5552                     Xpath 8388608                       " X: 0
5553                 endtry
5554             catch /.*/
5555                 let errcaught = 1
5556                 call CHECK(8, 'E171', "Missing :endif", line_before_throw + 3)
5557             endtry
5558         finally
5559             if !errcaught && $VIMNOERRTHROW
5560                 call CHECK(8)
5561             endif
5562             break               " discard error for $VIMNOERRTHROW
5563         endtry
5564     endwhile
5565     call CHECK(9)
5567     Xpath 16777216                              " X: 16777216
5569     try
5570         while 1
5571             try
5572                 throw "x6"
5573             finally
5574                 break
5575             endtry
5576             break
5577         endwhile
5578     catch /.*/
5579         Xpath 33554432                          " X: 0
5580     endtry
5581     call CHECK(10)
5583     try
5584         while 1
5585             try
5586                 throw "x7"
5587             finally
5588                 break
5589             endtry
5590             break
5591         endwhile
5592     catch /.*/
5593         Xpath 67108864                          " X: 0
5594     finally
5595         call CHECK(11)
5596     endtry
5597     call CHECK(12)
5599     while 1
5600         try
5601             let errcaught = 0
5602             try
5603                 try
5604                     throw "x8"
5605                 finally
5606                     SetLineNumber line_before_error
5607                     asdf
5608                 endtry
5609             catch /.*/
5610                 let errcaught = 1
5611                 call CHECK(13, 'E492', "Not an editor command",
5612                     \ line_before_error + 1)
5613             endtry
5614         finally
5615             if !errcaught && $VIMNOERRTHROW
5616                 call CHECK(13)
5617             endif
5618             break               " discard error for $VIMNOERRTHROW
5619         endtry
5620     endwhile
5621     call CHECK(14)
5623     Xpath 134217728                             " X: 134217728
5625     while 1
5626         try
5627             let intcaught = 0
5628             try
5629                 try
5630                     throw "x9"
5631                 finally
5632                     SetLineNumber two_lines_before_interrupt
5633                     "INTERRUPT
5634                 endtry
5635             catch /.*/
5636                 let intcaught = 1
5637                 call CHECK(15, "Vim:Interrupt", '',
5638                     \ two_lines_before_interrupt + 2)
5639             endtry
5640         finally
5641             if !intcaught && $VIMNOINTTHROW
5642                 call CHECK(15)
5643             endif
5644             break               " discard interrupt for $VIMNOINTTHROW
5645         endtry
5646     endwhile
5647     call CHECK(16)
5649     Xpath 268435456                             " X: 268435456
5651     while 1
5652         try
5653             let errcaught = 0
5654             try
5655                 try
5656 "                   if 1
5657                         SetLineNumber line_before_throw
5658                         throw "x10"
5659                     " missing endif
5660                 finally
5661                     call CHECK(17)
5662                 endtry
5663             catch /.*/
5664                 let errcaught = 1
5665                 call CHECK(18, 'E171', "Missing :endif", line_before_throw + 3)
5666             endtry
5667         finally
5668             if !errcaught && $VIMNOERRTHROW
5669                 call CHECK(18)
5670             endif
5671             break               " discard error for $VIMNOERRTHROW
5672         endtry
5673     endwhile
5674     call CHECK(19)
5676     Xpath 536870912                             " X: 536870912
5678     while 1
5679         try
5680             let errcaught = 0
5681             try
5682                 try
5683 "                   if 1
5684                         SetLineNumber line_before_throw
5685                         throw "x11"
5686                     " missing endif
5687                 endtry
5688             catch /.*/
5689                 let errcaught = 1
5690                 call CHECK(20, 'E171', "Missing :endif", line_before_throw + 3)
5691             endtry
5692         finally
5693             if !errcaught && $VIMNOERRTHROW
5694                 call CHECK(20)
5695             endif
5696             break               " discard error for $VIMNOERRTHROW
5697         endtry
5698     endwhile
5699     call CHECK(21)
5701     Xpath 1073741824                            " X: 1073741824
5703 endif
5705 Xcheck 2038431743
5708 "-------------------------------------------------------------------------------
5710 " Test 60:  (Re)throwing v:exception; :echoerr.                             {{{1
5712 "           A user exception can be rethrown after catching by throwing
5713 "           v:exception.  An error or interrupt exception cannot be rethrown
5714 "           because Vim exceptions cannot be faked.  A Vim exception using the
5715 "           value of v:exception can, however, be triggered by the :echoerr
5716 "           command.
5717 "-------------------------------------------------------------------------------
5719 XpathINIT
5722     try
5723         Xpath 1                                 " X: 1
5724         throw "oops"
5725     catch /oops/
5726         Xpath 2                                 " X: 2
5727         throw v:exception       " rethrow user exception
5728     catch /.*/
5729         Xpath 4                                 " X: 0
5730     endtry
5731 catch /^oops$/                  " catches rethrown user exception
5732     Xpath 8                                     " X: 8
5733 catch /.*/
5734     Xpath 16                                    " X: 0
5735 endtry
5737 function! F()
5738     try
5739         let caught = 0
5740         try
5741             Xpath 32                            " X: 32
5742             write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e
5743             Xpath 64                            " X: 0
5744             Xout "did_emsg was reset before executing " .
5745                 \ "BufWritePost autocommands."
5746         catch /^Vim(write):/
5747             let caught = 1
5748             throw v:exception   " throw error: cannot fake Vim exception
5749         catch /.*/
5750             Xpath 128                           " X: 0
5751         finally
5752             Xpath 256                           " X: 256
5753             if !caught && !$VIMNOERRTHROW
5754                 Xpath 512                       " X: 0
5755             endif
5756         endtry
5757     catch /^Vim(throw):/        " catches throw error
5758         let caught = caught + 1
5759     catch /.*/
5760         Xpath 1024                              " X: 0
5761     finally
5762         Xpath 2048                              " X: 2048
5763         if caught != 2
5764             if !caught && !$VIMNOERRTHROW
5765                 Xpath 4096                      " X: 0
5766             elseif caught
5767                 Xpath 8192                      " X: 0
5768             endif
5769             return              | " discard error for $VIMNOERRTHROW
5770         endif
5771     endtry
5772 endfunction
5774 call F()
5775 delfunction F
5777 function! G()
5778     try
5779         let caught = 0
5780         try
5781             Xpath 16384                         " X: 16384
5782             asdf
5783         catch /^Vim/            " catch error exception
5784             let caught = 1
5785             " Trigger Vim error exception with value specified after :echoerr
5786             let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
5787             echoerr value
5788         catch /.*/
5789             Xpath 32768                         " X: 0
5790         finally
5791             Xpath 65536                         " X: 65536
5792             if !caught
5793                 if !$VIMNOERRTHROW
5794                     Xpath 131072                " X: 0
5795                 else
5796                     let value = "Error"
5797                     echoerr value
5798                 endif
5799             endif
5800         endtry
5801     catch /^Vim(echoerr):/
5802         let caught = caught + 1
5803         if v:exception !~ value
5804             Xpath 262144                        " X: 0
5805         endif
5806     catch /.*/
5807         Xpath 524288                            " X: 0
5808     finally
5809         Xpath 1048576                           " X: 1048576
5810         if caught != 2
5811             if !caught && !$VIMNOERRTHROW
5812                 Xpath 2097152                   " X: 0
5813             elseif caught
5814                 Xpath 4194304                   " X: 0
5815             endif
5816             return              | " discard error for $VIMNOERRTHROW
5817         endif
5818     endtry
5819 endfunction
5821 call G()
5822 delfunction G
5824 unlet! value caught
5826 if ExtraVim()
5827     try
5828         let errcaught = 0
5829         try
5830             Xpath 8388608                       " X: 8388608
5831             let intcaught = 0
5832             "INTERRUPT
5833         catch /^Vim:/           " catch interrupt exception
5834             let intcaught = 1
5835             " Trigger Vim error exception with value specified after :echoerr
5836             echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
5837         catch /.*/
5838             Xpath 16777216                      " X: 0
5839         finally
5840             Xpath 33554432                      " X: 33554432
5841             if !intcaught
5842                 if !$VIMNOINTTHROW
5843                     Xpath 67108864              " X: 0
5844                 else
5845                     echoerr "Interrupt"
5846                 endif
5847             endif
5848         endtry
5849     catch /^Vim(echoerr):/
5850         let errcaught = 1
5851         if v:exception !~ "Interrupt"
5852             Xpath 134217728                     " X: 0
5853         endif
5854     finally
5855         Xpath 268435456                         " X: 268435456
5856         if !errcaught && !$VIMNOERRTHROW
5857             Xpath 536870912                     " X: 0
5858         endif
5859     endtry
5860 endif
5862 Xcheck 311511339
5865 "-------------------------------------------------------------------------------
5866 " Test 61:  Catching interrupt exceptions                                   {{{1
5868 "           When an interrupt occurs inside a :try/:endtry region, an
5869 "           interrupt exception is thrown and can be caught.  Its value is
5870 "           "Vim:Interrupt".  If the interrupt occurs after an error or a :throw
5871 "           but before a matching :catch is reached, all following :catches of
5872 "           that try block are ignored, but the interrupt exception can be
5873 "           caught by the next surrounding try conditional.  An interrupt is
5874 "           ignored when there is a previous interrupt that has not been caught
5875 "           or causes a :finally clause to be executed.
5876 "-------------------------------------------------------------------------------
5878 XpathINIT
5880 if ExtraVim()
5882     while 1
5883         try
5884             try
5885                 Xpath 1                         " X: 1
5886                 let caught = 0
5887                 "INTERRUPT
5888                 Xpath 2                         " X: 0
5889             catch /^Vim:Interrupt$/
5890                 let caught = 1
5891             finally
5892                 Xpath 4                         " X: 4
5893                 if caught || $VIMNOINTTHROW
5894                     Xpath 8                     " X: 8
5895                 endif
5896             endtry
5897         catch /.*/
5898             Xpath 16                            " X: 0
5899             Xout v:exception "in" v:throwpoint
5900         finally
5901             break               " discard interrupt for $VIMNOINTTHROW
5902         endtry
5903     endwhile
5905     while 1
5906         try
5907             try
5908                 let caught = 0
5909                 try
5910                     Xpath 32                    " X: 32
5911                     asdf
5912                     Xpath 64                    " X: 0
5913                 catch /do_not_catch/
5914                     Xpath 128                   " X: 0
5915                 catch /.*/      "INTERRUPT - throw interrupt if !$VIMNOERRTHROW
5916                     Xpath 256                   " X: 0
5917                 catch /.*/
5918                     Xpath 512                   " X: 0
5919                 finally         "INTERRUPT - throw interrupt if $VIMNOERRTHROW
5920                     Xpath 1024                  " X: 1024
5921                 endtry
5922             catch /^Vim:Interrupt$/
5923                 let caught = 1
5924             finally
5925                 Xpath 2048                      " X: 2048
5926                 if caught || $VIMNOINTTHROW
5927                     Xpath 4096                  " X: 4096
5928                 endif
5929             endtry
5930         catch /.*/
5931             Xpath 8192                          " X: 0
5932             Xout v:exception "in" v:throwpoint
5933         finally
5934             break               " discard interrupt for $VIMNOINTTHROW
5935         endtry
5936     endwhile
5938     while 1
5939         try
5940             try
5941                 let caught = 0
5942                 try
5943                     Xpath 16384                 " X: 16384
5944                     throw "x"
5945                     Xpath 32768                 " X: 0
5946                 catch /do_not_catch/
5947                     Xpath 65536                 " X: 0
5948                 catch /x/       "INTERRUPT
5949                     Xpath 131072                " X: 0
5950                 catch /.*/
5951                     Xpath 262144                " X: 0
5952                 endtry
5953             catch /^Vim:Interrupt$/
5954                 let caught = 1
5955             finally
5956                 Xpath 524288                    " X: 524288
5957                 if caught || $VIMNOINTTHROW
5958                     Xpath 1048576               " X: 1048576
5959                 endif
5960             endtry
5961         catch /.*/
5962             Xpath 2097152                       " X: 0
5963             Xout v:exception "in" v:throwpoint
5964         finally
5965             break               " discard interrupt for $VIMNOINTTHROW
5966         endtry
5967     endwhile
5969     while 1
5970         try
5971             let caught = 0
5972             try
5973                 Xpath 4194304                   " X: 4194304
5974                 "INTERRUPT
5975                 Xpath 8388608                   " X: 0
5976             catch /do_not_catch/ "INTERRUPT
5977                 Xpath 16777216                  " X: 0
5978             catch /^Vim:Interrupt$/
5979                 let caught = 1
5980             finally
5981                 Xpath 33554432                  " X: 33554432
5982                 if caught || $VIMNOINTTHROW
5983                     Xpath 67108864              " X: 67108864
5984                 endif
5985             endtry
5986         catch /.*/
5987             Xpath 134217728                     " X: 0
5988             Xout v:exception "in" v:throwpoint
5989         finally
5990             break               " discard interrupt for $VIMNOINTTHROW
5991         endtry
5992     endwhile
5994     Xpath 268435456                             " X: 268435456
5996 endif
5998 Xcheck 374889517
6001 "-------------------------------------------------------------------------------
6002 " Test 62:  Catching error exceptions                                       {{{1
6004 "           An error inside a :try/:endtry region is converted to an exception
6005 "           and can be caught.  The error exception has a "Vim(cmdname):" prefix
6006 "           where cmdname is the name of the failing command, or a "Vim:" prefix
6007 "           if no command name is known.  The "Vim" prefixes cannot be faked.
6008 "-------------------------------------------------------------------------------
6010 XpathINIT
6012 function! MSG(enr, emsg)
6013     let english = v:lang == "C" || v:lang =~ '^[Ee]n'
6014     if a:enr == ""
6015         Xout "TODO: Add message number for:" a:emsg
6016         let v:errmsg = ":" . v:errmsg
6017     endif
6018     let match = 1
6019     if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
6020         let match = 0
6021         if v:errmsg == ""
6022             Xout "Message missing."
6023         else
6024             let v:errmsg = escape(v:errmsg, '"')
6025             Xout "Unexpected message:" v:errmsg
6026         endif
6027     endif
6028     return match
6029 endfunction
6031 while 1
6032     try
6033         try
6034             let caught = 0
6035             unlet novar
6036         catch /^Vim(unlet):/
6037             let caught = 1
6038             let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "")
6039         finally
6040             Xpath 1                             " X: 1
6041             if !caught && !$VIMNOERRTHROW
6042                 Xpath 2                         " X: 0
6043             endif
6044             if !MSG('E108', "No such variable")
6045                 Xpath 4                         " X: 0
6046             endif
6047         endtry
6048     catch /.*/
6049         Xpath 8                                 " X: 0
6050         Xout v:exception "in" v:throwpoint
6051     finally
6052         break           " discard error for $VIMNOERRTHROW
6053     endtry
6054 endwhile
6056 while 1
6057     try
6058         try
6059             let caught = 0
6060             throw novar                 " error in :throw
6061         catch /^Vim(throw):/
6062             let caught = 1
6063             let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
6064         finally
6065             Xpath 16                            " X: 16
6066             if !caught && !$VIMNOERRTHROW
6067                 Xpath 32                        " X: 0
6068             endif
6069             if caught ? !MSG('E121', "Undefined variable")
6070                         \ : !MSG('E15', "Invalid expression")
6071                 Xpath 64                        " X: 0
6072             endif
6073         endtry
6074     catch /.*/
6075         Xpath 128                               " X: 0
6076         Xout v:exception "in" v:throwpoint
6077     finally
6078         break           " discard error for $VIMNOERRTHROW
6079     endtry
6080 endwhile
6082 while 1
6083     try
6084         try
6085             let caught = 0
6086             throw "Vim:faked"           " error: cannot fake Vim exception
6087         catch /^Vim(throw):/
6088             let caught = 1
6089             let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
6090         finally
6091             Xpath 256                           " X: 256
6092             if !caught && !$VIMNOERRTHROW
6093                 Xpath 512                       " X: 0
6094             endif
6095             if !MSG('E608', "Cannot :throw exceptions with 'Vim' prefix")
6096                 Xpath 1024                      " X: 0
6097             endif
6098         endtry
6099     catch /.*/
6100         Xpath 2048                              " X: 0
6101         Xout v:exception "in" v:throwpoint
6102     finally
6103         break           " discard error for $VIMNOERRTHROW
6104     endtry
6105 endwhile
6107 function! F()
6108     while 1
6109     " Missing :endwhile
6110 endfunction
6112 while 1
6113     try
6114         try
6115             let caught = 0
6116             call F()
6117         catch /^Vim(endfunction):/
6118             let caught = 1
6119             let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "")
6120         finally
6121             Xpath 4096                          " X: 4096
6122             if !caught && !$VIMNOERRTHROW
6123                 Xpath 8192                      " X: 0
6124             endif
6125             if !MSG('E170', "Missing :endwhile")
6126                 Xpath 16384                     " X: 0
6127             endif
6128         endtry
6129     catch /.*/
6130         Xpath 32768                             " X: 0
6131         Xout v:exception "in" v:throwpoint
6132     finally
6133         break           " discard error for $VIMNOERRTHROW
6134     endtry
6135 endwhile
6137 while 1
6138     try
6139         try
6140             let caught = 0
6141             ExecAsScript F
6142         catch /^Vim:/
6143             let caught = 1
6144             let v:errmsg = substitute(v:exception, '^Vim:', '', "")
6145         finally
6146             Xpath 65536                         " X: 65536
6147             if !caught && !$VIMNOERRTHROW
6148                 Xpath 131072                    " X: 0
6149             endif
6150             if !MSG('E170', "Missing :endwhile")
6151                 Xpath 262144                    " X: 0
6152             endif
6153         endtry
6154     catch /.*/
6155         Xpath 524288                            " X: 0
6156         Xout v:exception "in" v:throwpoint
6157     finally
6158         break           " discard error for $VIMNOERRTHROW
6159     endtry
6160 endwhile
6162 function! G()
6163     call G()
6164 endfunction
6166 while 1
6167     try
6168         let mfd_save = &mfd
6169         set mfd=3
6170         try
6171             let caught = 0
6172             call G()
6173         catch /^Vim(call):/
6174             let caught = 1
6175             let v:errmsg = substitute(v:exception, '^Vim(call):', '', "")
6176         finally
6177             Xpath 1048576                       " X: 1048576
6178             if !caught && !$VIMNOERRTHROW
6179                 Xpath 2097152                   " X: 0
6180             endif
6181             if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
6182                 Xpath 4194304                   " X: 0
6183             endif
6184         endtry
6185     catch /.*/
6186         Xpath 8388608                           " X: 0
6187         Xout v:exception "in" v:throwpoint
6188     finally
6189         let &mfd = mfd_save
6190         break           " discard error for $VIMNOERRTHROW
6191     endtry
6192 endwhile
6194 function! H()
6195     return H()
6196 endfunction
6198 while 1
6199     try
6200         let mfd_save = &mfd
6201         set mfd=3
6202         try
6203             let caught = 0
6204             call H()
6205         catch /^Vim(return):/
6206             let caught = 1
6207             let v:errmsg = substitute(v:exception, '^Vim(return):', '', "")
6208         finally
6209             Xpath 16777216                      " X: 16777216
6210             if !caught && !$VIMNOERRTHROW
6211                 Xpath 33554432                  " X: 0
6212             endif
6213             if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
6214                 Xpath 67108864                  " X: 0
6215             endif
6216         endtry
6217     catch /.*/
6218         Xpath 134217728                         " X: 0
6219         Xout v:exception "in" v:throwpoint
6220     finally
6221         let &mfd = mfd_save
6222         break           " discard error for $VIMNOERRTHROW
6223     endtry
6224 endwhile
6226 unlet! caught mfd_save
6227 delfunction F
6228 delfunction G
6229 delfunction H
6230 Xpath 268435456                                 " X: 268435456
6232 Xcheck 286331153
6234 " Leave MSG() for the next test.
6237 "-------------------------------------------------------------------------------
6238 " Test 63:  Suppressing error exceptions by :silent!.                       {{{1
6240 "           A :silent! command inside a :try/:endtry region suppresses the
6241 "           conversion of errors to an exception and the immediate abortion on
6242 "           error.  When the commands executed by the :silent! themselves open
6243 "           a new :try/:endtry region, conversion of errors to exception and
6244 "           immediate abortion is switched on again - until the next :silent!
6245 "           etc.  The :silent! has the effect of setting v:errmsg to the error
6246 "           message text (without displaying it) and continuing with the next
6247 "           script line.
6249 "           When a command triggering autocommands is executed by :silent!
6250 "           inside a :try/:endtry, the autocommand execution is not suppressed
6251 "           on error.
6253 "           This test reuses the function MSG() from the previous test.
6254 "-------------------------------------------------------------------------------
6256 XpathINIT
6258 XloopINIT! 1 4
6260 let taken = ""
6262 function! S(n) abort
6263     XloopNEXT
6264     let g:taken = g:taken . "E" . a:n
6265     let v:errmsg = ""
6266     exec "asdf" . a:n
6268     " Check that ":silent!" continues:
6269     Xloop 1
6271     " Check that ":silent!" sets "v:errmsg":
6272     if MSG('E492', "Not an editor command")
6273         Xloop 2
6274     endif
6275 endfunction
6277 function! Foo()
6278     while 1
6279         try
6280             try
6281                 let caught = 0
6282                 " This is not silent:
6283                 call S(3)                               " X: 0 * 16
6284             catch /^Vim:/
6285                 let caught = 1
6286                 let errmsg3 = substitute(v:exception, '^Vim:', '', "")
6287                 silent! call S(4)                       " X: 3 * 64
6288             finally
6289                 if !caught
6290                     let errmsg3 = v:errmsg
6291                     " Do call S(4) here if not executed in :catch.
6292                     silent! call S(4)
6293                 endif
6294                 Xpath 1048576                   " X: 1048576
6295                 if !caught && !$VIMNOERRTHROW
6296                     Xpath 2097152               " X: 0
6297                 endif
6298                 let v:errmsg = errmsg3
6299                 if !MSG('E492', "Not an editor command")
6300                     Xpath 4194304               " X: 0
6301                 endif
6302                 silent! call S(5)                       " X: 3 * 256
6303                 " Break out of try conditionals that cover ":silent!".  This also
6304                 " discards the aborting error when $VIMNOERRTHROW is non-zero.
6305                 break
6306             endtry
6307         catch /.*/
6308             Xpath 8388608                       " X: 0
6309             Xout v:exception "in" v:throwpoint
6310         endtry
6311     endwhile
6312     " This is a double ":silent!" (see caller).
6313     silent! call S(6)                                   " X: 3 * 1024
6314 endfunction
6316 function! Bar()
6317     try
6318         silent! call S(2)                               " X: 3 * 4
6319                                                         " X: 3 * 4096
6320         silent! execute "call Foo() | call S(7)"
6321         silent! call S(8)                               " X: 3 * 16384
6322     endtry      " normal end of try cond that covers ":silent!"
6323     " This has a ":silent!" from the caller:
6324     call S(9)                                           " X: 3 * 65536
6325 endfunction
6327 silent! call S(1)                                       " X: 3 * 1
6328 silent! call Bar()
6329 silent! call S(10)                                      " X: 3 * 262144
6331 let expected = "E1E2E3E4E5E6E7E8E9E10"
6332 if taken != expected
6333     Xpath 16777216                              " X: 0
6334     Xout "'taken' is" taken "instead of" expected
6335 endif
6337 augroup TMP
6338     autocmd BufWritePost * Xpath 33554432       " X: 33554432
6339 augroup END
6341 Xpath 67108864                                  " X: 67108864
6342 write /i/m/p/o/s/s/i/b/l/e
6343 Xpath 134217728                                 " X: 134217728
6345 autocmd! TMP
6346 unlet! caught errmsg3 taken expected
6347 delfunction S
6348 delfunction Foo
6349 delfunction Bar
6350 delfunction MSG
6352 Xcheck 236978127
6355 "-------------------------------------------------------------------------------
6356 " Test 64:  Error exceptions after error, interrupt or :throw               {{{1
6358 "           When an error occurs after an interrupt or a :throw but before
6359 "           a matching :catch is reached, all following :catches of that try
6360 "           block are ignored, but the error exception can be caught by the next
6361 "           surrounding try conditional.  Any previous error exception is
6362 "           discarded.  An error is ignored when there is a previous error that
6363 "           has not been caught.
6364 "-------------------------------------------------------------------------------
6366 XpathINIT
6368 if ExtraVim()
6370     while 1
6371         try
6372             try
6373                 Xpath 1                         " X: 1
6374                 let caught = 0
6375                 while 1
6376 "                   if 1
6377                     " Missing :endif
6378                 endwhile        " throw error exception
6379             catch /^Vim(/
6380                 let caught = 1
6381             finally
6382                 Xpath 2                         " X: 2
6383                 if caught || $VIMNOERRTHROW
6384                     Xpath 4                     " X: 4
6385                 endif
6386             endtry
6387         catch /.*/
6388             Xpath 8                             " X: 0
6389             Xout v:exception "in" v:throwpoint
6390         finally
6391             break               " discard error for $VIMNOERRTHROW
6392         endtry
6393     endwhile
6395     while 1
6396         try
6397             try
6398                 Xpath 16                        " X: 16
6399                 let caught = 0
6400                 try
6401 "                   if 1
6402                     " Missing :endif
6403                 catch /.*/      " throw error exception
6404                     Xpath 32                    " X: 0
6405                 catch /.*/
6406                     Xpath 64                    " X: 0
6407                 endtry
6408             catch /^Vim(/
6409                 let caught = 1
6410             finally
6411                 Xpath 128                       " X: 128
6412                 if caught || $VIMNOERRTHROW
6413                     Xpath 256                   " X: 256
6414                 endif
6415             endtry
6416         catch /.*/
6417             Xpath 512                           " X: 0
6418             Xout v:exception "in" v:throwpoint
6419         finally
6420             break               " discard error for $VIMNOERRTHROW
6421         endtry
6422     endwhile
6424     while 1
6425         try
6426             try
6427                 let caught = 0
6428                 try
6429                     Xpath 1024                  " X: 1024
6430                     "INTERRUPT
6431                 catch /do_not_catch/
6432                     Xpath 2048                  " X: 0
6433 "                   if 1
6434                     " Missing :endif
6435                 catch /.*/      " throw error exception
6436                     Xpath 4096                  " X: 0
6437                 catch /.*/
6438                     Xpath 8192                  " X: 0
6439                 endtry
6440             catch /^Vim(/
6441                 let caught = 1
6442             finally
6443                 Xpath 16384                     " X: 16384
6444                 if caught || $VIMNOERRTHROW
6445                     Xpath 32768                 " X: 32768
6446                 endif
6447             endtry
6448         catch /.*/
6449             Xpath 65536                         " X: 0
6450             Xout v:exception "in" v:throwpoint
6451         finally
6452             break               " discard error for $VIMNOERRTHROW
6453         endtry
6454     endwhile
6456     while 1
6457         try
6458             try
6459                 let caught = 0
6460                 try
6461                     Xpath 131072                " X: 131072
6462                     throw "x"
6463                 catch /do_not_catch/
6464                     Xpath 262144                " X: 0
6465 "                   if 1
6466                     " Missing :endif
6467                 catch /x/       " throw error exception
6468                     Xpath 524288                " X: 0
6469                 catch /.*/
6470                    Xpath 1048576                " X: 0
6471                 endtry
6472             catch /^Vim(/
6473                 let caught = 1
6474             finally
6475                 Xpath 2097152                   " X: 2097152
6476                 if caught || $VIMNOERRTHROW
6477                     Xpath 4194304               " X: 4194304
6478                 endif
6479             endtry
6480         catch /.*/
6481             Xpath 8388608                       " X: 0
6482             Xout v:exception "in" v:throwpoint
6483         finally
6484             break               " discard error for $VIMNOERRTHROW
6485         endtry
6486     endwhile
6488     while 1
6489         try
6490             try
6491                 let caught = 0
6492                 Xpath 16777216                  " X: 16777216
6493 "               endif           " :endif without :if; throw error exception
6494 "               if 1
6495                 " Missing :endif
6496             catch /do_not_catch/ " ignore new error
6497                 Xpath 33554432                  " X: 0
6498             catch /^Vim(endif):/
6499                 let caught = 1
6500             catch /^Vim(/
6501                 Xpath 67108864                  " X: 0
6502             finally
6503                 Xpath 134217728                 " X: 134217728
6504                 if caught || $VIMNOERRTHROW
6505                     Xpath 268435456             " X: 268435456
6506                 endif
6507             endtry
6508         catch /.*/
6509             Xpath 536870912                     " X: 0
6510             Xout v:exception "in" v:throwpoint
6511         finally
6512             break               " discard error for $VIMNOERRTHROW
6513         endtry
6514     endwhile
6516     Xpath 1073741824                            " X: 1073741824
6518 endif
6520 Xcheck 1499645335
6523 "-------------------------------------------------------------------------------
6524 " Test 65:  Errors in the /pattern/ argument of a :catch                    {{{1
6526 "           On an error in the /pattern/ argument of a :catch, the :catch does
6527 "           not match.  Any following :catches of the same :try/:endtry don't
6528 "           match either.  Finally clauses are executed.
6529 "-------------------------------------------------------------------------------
6531 XpathINIT
6533 function! MSG(enr, emsg)
6534     let english = v:lang == "C" || v:lang =~ '^[Ee]n'
6535     if a:enr == ""
6536         Xout "TODO: Add message number for:" a:emsg
6537         let v:errmsg = ":" . v:errmsg
6538     endif
6539     let match = 1
6540     if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
6541         let match = 0
6542         if v:errmsg == ""
6543             Xout "Message missing."
6544         else
6545             let v:errmsg = escape(v:errmsg, '"')
6546             Xout "Unexpected message:" v:errmsg
6547         endif
6548     endif
6549     return match
6550 endfunction
6553     try
6554         Xpath 1                                 " X: 1
6555         throw "oops"
6556     catch /^oops$/
6557         Xpath 2                                 " X: 2
6558     catch /\)/          " not checked; exception has already been caught
6559         Xpath 4                                 " X: 0
6560     endtry
6561     Xpath 8                                     " X: 8
6562 catch /.*/
6563     Xpath 16                                    " X: 0
6564     Xout v:exception "in" v:throwpoint
6565 endtry
6567 function! F()
6568     try
6569         let caught = 0
6570         try
6571             try
6572                 Xpath 32                        " X: 32
6573                 throw "ab"
6574             catch /abc/ " does not catch
6575                 Xpath 64                        " X: 0
6576             catch /\)/  " error; discards exception
6577                 Xpath 128                       " X: 0
6578             catch /.*/  " not checked
6579                 Xpath 256                       " X: 0
6580             finally
6581                 Xpath 512                       " X: 512
6582             endtry
6583             Xpath 1024                          " X: 0
6584         catch /^ab$/    " checked, but original exception is discarded
6585             Xpath 2048                          " X: 0
6586         catch /^Vim(catch):/
6587             let caught = 1
6588             let v:errmsg = substitute(v:exception, '^Vim(catch):', '', "")
6589         finally
6590             Xpath 4096                          " X: 4096
6591             if !caught && !$VIMNOERRTHROW
6592                 Xpath 8192                      " X: 0
6593             endif
6594             if caught ? !MSG('E55', 'Unmatched \\)')
6595                         \ : !MSG('E475', "Invalid argument")
6596                 Xpath 16384                     " X: 0
6597             endif
6598             if !caught
6599                 return  | " discard error
6600             endif
6601         endtry
6602     catch /.*/
6603         Xpath 32768                             " X: 0
6604         Xout v:exception "in" v:throwpoint
6605     endtry
6606 endfunction
6608 call F()
6609 Xpath 65536                                     " X: 65536
6611 delfunction MSG
6612 delfunction F
6613 unlet! caught
6615 Xcheck 70187
6618 "-------------------------------------------------------------------------------
6619 " Test 66:  Stop range :call on error, interrupt, or :throw                 {{{1
6621 "           When a function which is multiply called for a range since it
6622 "           doesn't handle the range itself has an error in a command
6623 "           dynamically enclosed by :try/:endtry or gets an interrupt or
6624 "           executes a :throw, no more calls for the remaining lines in the
6625 "           range are made.  On an error in a command not dynamically enclosed
6626 "           by :try/:endtry, the function is executed again for the remaining
6627 "           lines in the range.
6628 "-------------------------------------------------------------------------------
6630 XpathINIT
6632 if ExtraVim()
6634     let file = tempname()
6635     exec "edit" file
6637     insert
6638 line 1
6639 line 2
6640 line 3
6643     XloopINIT! 1 2
6645     let taken = ""
6646     let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)"
6648     function! F(reason, n) abort
6649         let g:taken = g:taken . "F" . a:n .
6650             \ substitute(a:reason, '\(\l\).*', '\u\1', "") .
6651             \ "(" . line(".") . ")"
6653         if a:reason == "error"
6654             asdf
6655         elseif a:reason == "interrupt"
6656             "INTERRUPT
6657             let dummy = 0
6658         elseif a:reason == "throw"
6659             throw "xyz"
6660         elseif a:reason == "aborting error"
6661             XloopNEXT
6662             if g:taken != g:expected
6663                 Xloop 1                         " X: 0
6664                 Xout "'taken' is" g:taken "instead of" g:expected
6665             endif
6666             try
6667                 bwipeout!
6668                 call delete(file)
6669                 asdf
6670             endtry
6671         endif
6672     endfunction
6674     function! G(reason, n)
6675         let g:taken = g:taken . "G" . a:n .
6676             \ substitute(a:reason, '\(\l\).*', '\u\1', "")
6677         1,3call F(a:reason, a:n)
6678     endfunction
6680     Xpath 8                                     " X: 8
6681     call G("error", 1)
6682     try
6683         Xpath 16                                " X: 16
6684         try
6685             call G("error", 2)
6686             Xpath 32                            " X: 0
6687         finally
6688             Xpath 64                            " X: 64
6689             try
6690                 call G("interrupt", 3)
6691                 Xpath 128                       " X: 0
6692             finally
6693                 Xpath 256                       " X: 256
6694                 try
6695                     call G("throw", 4)
6696                     Xpath 512                   " X: 0
6697                 endtry
6698             endtry
6699         endtry
6700     catch /xyz/
6701         Xpath 1024                              " X: 1024
6702     catch /.*/
6703         Xpath 2048                              " X: 0
6704         Xout v:exception "in" ExtraVimThrowpoint()
6705     endtry
6706     Xpath 4096                                  " X: 4096
6707     call G("aborting error", 5)
6708     Xpath 8192                                  " X: 0
6709     Xout "'taken' is" taken "instead of" expected
6711 endif
6713 Xcheck 5464
6716 "-------------------------------------------------------------------------------
6717 " Test 67:  :throw across :call command                                     {{{1
6719 "           On a call command, an exception might be thrown when evaluating the
6720 "           function name, during evaluation of the arguments, or when the
6721 "           function is being executed.  The exception can be caught by the
6722 "           caller.
6723 "-------------------------------------------------------------------------------
6725 XpathINIT
6727 function! THROW(x, n)
6728     if a:n == 1
6729         Xpath 1                                         " X: 1
6730     elseif a:n == 2
6731         Xpath 2                                         " X: 2
6732     elseif a:n == 3
6733         Xpath 4                                         " X: 4
6734     endif
6735     throw a:x
6736 endfunction
6738 function! NAME(x, n)
6739     if a:n == 1
6740         Xpath 8                                         " X: 0
6741     elseif a:n == 2
6742         Xpath 16                                        " X: 16
6743     elseif a:n == 3
6744         Xpath 32                                        " X: 32
6745     elseif a:n == 4
6746         Xpath 64                                        " X: 64
6747     endif
6748     return a:x
6749 endfunction
6751 function! ARG(x, n)
6752     if a:n == 1
6753         Xpath 128                                       " X: 0
6754     elseif a:n == 2
6755         Xpath 256                                       " X: 0
6756     elseif a:n == 3
6757         Xpath 512                                       " X: 512
6758     elseif a:n == 4
6759         Xpath 1024                                      " X: 1024
6760     endif
6761     return a:x
6762 endfunction
6764 function! F(x, n)
6765     if a:n == 2
6766         Xpath 2048                                      " X: 0
6767     elseif a:n == 4
6768         Xpath 4096                                      " X: 4096
6769     endif
6770 endfunction
6772 while 1
6773     try
6774         let error = 0
6775         let v:errmsg = ""
6777         while 1
6778             try
6779                 Xpath 8192                              " X: 8192
6780                 call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
6781                 Xpath 16384                             " X: 0
6782             catch /^name$/
6783                 Xpath 32768                             " X: 32768
6784             catch /.*/
6785                 let error = 1
6786                 Xout "1:" v:exception "in" v:throwpoint
6787             finally
6788                 if !error && $VIMNOERRTHROW && v:errmsg != ""
6789                     let error = 1
6790                     Xout "1:" v:errmsg
6791                 endif
6792                 if error
6793                     Xpath 65536                         " X: 0
6794                 endif
6795                 let error = 0
6796                 let v:errmsg = ""
6797                 break           " discard error for $VIMNOERRTHROW
6798             endtry
6799         endwhile
6801         while 1
6802             try
6803                 Xpath 131072                            " X: 131072
6804                 call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
6805                 Xpath 262144                            " X: 0
6806             catch /^arg$/
6807                 Xpath 524288                            " X: 524288
6808             catch /.*/
6809                 let error = 1
6810                 Xout "2:" v:exception "in" v:throwpoint
6811             finally
6812                 if !error && $VIMNOERRTHROW && v:errmsg != ""
6813                     let error = 1
6814                     Xout "2:" v:errmsg
6815                 endif
6816                 if error
6817                     Xpath 1048576                       " X: 0
6818                 endif
6819                 let error = 0
6820                 let v:errmsg = ""
6821                 break           " discard error for $VIMNOERRTHROW
6822             endtry
6823         endwhile
6825         while 1
6826             try
6827                 Xpath 2097152                           " X: 2097152
6828                 call {NAME("THROW", 3)}(ARG("call", 3), 3)
6829                 Xpath 4194304                           " X: 0
6830             catch /^call$/
6831                 Xpath 8388608                           " X: 8388608
6832             catch /^0$/     " default return value
6833                 Xpath 16777216                          " X: 0
6834                 Xout "3:" v:throwpoint
6835             catch /.*/
6836                 let error = 1
6837                 Xout "3:" v:exception "in" v:throwpoint
6838             finally
6839                 if !error && $VIMNOERRTHROW && v:errmsg != ""
6840                     let error = 1
6841                     Xout "3:" v:errmsg
6842                 endif
6843                 if error
6844                     Xpath 33554432                      " X: 0
6845                 endif
6846                 let error = 0
6847                 let v:errmsg = ""
6848                 break           " discard error for $VIMNOERRTHROW
6849             endtry
6850         endwhile
6852         while 1
6853             try
6854                 Xpath 67108864                          " X: 67108864
6855                 call {NAME("F", 4)}(ARG(4711, 4), 4)
6856                 Xpath 134217728                         " X: 134217728
6857             catch /.*/
6858                 let error = 1
6859                 Xout "4:" v:exception "in" v:throwpoint
6860             finally
6861                 if !error && $VIMNOERRTHROW && v:errmsg != ""
6862                     let error = 1
6863                     Xout "4:" v:errmsg
6864                 endif
6865                 if error
6866                     Xpath 268435456                     " X: 0
6867                 endif
6868                 let error = 0
6869                 let v:errmsg = ""
6870                 break           " discard error for $VIMNOERRTHROW
6871             endtry
6872         endwhile
6874     catch /^0$/     " default return value
6875         Xpath 536870912                                 " X: 0
6876         Xout v:throwpoint
6877     catch /.*/
6878         let error = 1
6879         Xout v:exception "in" v:throwpoint
6880     finally
6881         if !error && $VIMNOERRTHROW && v:errmsg != ""
6882             let error = 1
6883             Xout v:errmsg
6884         endif
6885         if error
6886             Xpath 1073741824                            " X: 0
6887         endif
6888         break           " discard error for $VIMNOERRTHROW
6889     endtry
6890 endwhile
6892 unlet error
6893 delfunction F
6895 Xcheck 212514423
6897 " Leave THROW(), NAME(), and ARG() for the next test.
6900 "-------------------------------------------------------------------------------
6901 " Test 68:  :throw across function calls in expressions                     {{{1
6903 "           On a function call within an expression, an exception might be
6904 "           thrown when evaluating the function name, during evaluation of the
6905 "           arguments, or when the function is being executed.  The exception
6906 "           can be caught by the caller.
6908 "           This test reuses the functions THROW(), NAME(), and ARG() from the
6909 "           previous test.
6910 "-------------------------------------------------------------------------------
6912 XpathINIT
6914 function! F(x, n)
6915     if a:n == 2
6916         Xpath 2048                                      " X: 0
6917     elseif a:n == 4
6918         Xpath 4096                                      " X: 4096
6919     endif
6920     return a:x
6921 endfunction
6923 unlet! var1 var2 var3 var4
6925 while 1
6926     try
6927         let error = 0
6928         let v:errmsg = ""
6930         while 1
6931             try
6932                 Xpath 8192                              " X: 8192
6933                 let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
6934                 Xpath 16384                             " X: 0
6935             catch /^name$/
6936                 Xpath 32768                             " X: 32768
6937             catch /.*/
6938                 let error = 1
6939                 Xout "1:" v:exception "in" v:throwpoint
6940             finally
6941                 if !error && $VIMNOERRTHROW && v:errmsg != ""
6942                     let error = 1
6943                     Xout "1:" v:errmsg
6944                 endif
6945                 if error
6946                     Xpath 65536                         " X: 0
6947                 endif
6948                 let error = 0
6949                 let v:errmsg = ""
6950                 break           " discard error for $VIMNOERRTHROW
6951             endtry
6952         endwhile
6954         while 1
6955             try
6956                 Xpath 131072                            " X: 131072
6957                 let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
6958                 Xpath 262144                            " X: 0
6959             catch /^arg$/
6960                 Xpath 524288                            " X: 524288
6961             catch /.*/
6962                 let error = 1
6963                 Xout "2:" v:exception "in" v:throwpoint
6964             finally
6965                 if !error && $VIMNOERRTHROW && v:errmsg != ""
6966                     let error = 1
6967                     Xout "2:" v:errmsg
6968                 endif
6969                 if error
6970                     Xpath 1048576                       " X: 0
6971                 endif
6972                 let error = 0
6973                 let v:errmsg = ""
6974                 break           " discard error for $VIMNOERRTHROW
6975             endtry
6976         endwhile
6978         while 1
6979             try
6980                 Xpath 2097152                           " X: 2097152
6981                 let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3)
6982                 Xpath 4194304                           " X: 0
6983             catch /^call$/
6984                 Xpath 8388608                           " X: 8388608
6985             catch /^0$/     " default return value
6986                 Xpath 16777216                          " X: 0
6987                 Xout "3:" v:throwpoint
6988             catch /.*/
6989                 let error = 1
6990                 Xout "3:" v:exception "in" v:throwpoint
6991             finally
6992                 if !error && $VIMNOERRTHROW && v:errmsg != ""
6993                     let error = 1
6994                     Xout "3:" v:errmsg
6995                 endif
6996                 if error
6997                     Xpath 33554432                      " X: 0
6998                 endif
6999                 let error = 0
7000                 let v:errmsg = ""
7001                 break           " discard error for $VIMNOERRTHROW
7002             endtry
7003         endwhile
7005         while 1
7006             try
7007                 Xpath 67108864                          " X: 67108864
7008                 let var4 = {NAME("F", 4)}(ARG(4711, 4), 4)
7009                 Xpath 134217728                         " X: 134217728
7010             catch /.*/
7011                 let error = 1
7012                 Xout "4:" v:exception "in" v:throwpoint
7013             finally
7014                 if !error && $VIMNOERRTHROW && v:errmsg != ""
7015                     let error = 1
7016                     Xout "4:" v:errmsg
7017                 endif
7018                 if error
7019                     Xpath 268435456                     " X: 0
7020                 endif
7021                 let error = 0
7022                 let v:errmsg = ""
7023                 break           " discard error for $VIMNOERRTHROW
7024             endtry
7025         endwhile
7027     catch /^0$/     " default return value
7028         Xpath 536870912                                 " X: 0
7029         Xout v:throwpoint
7030     catch /.*/
7031         let error = 1
7032         Xout v:exception "in" v:throwpoint
7033     finally
7034         if !error && $VIMNOERRTHROW && v:errmsg != ""
7035             let error = 1
7036             Xout v:errmsg
7037         endif
7038         if error
7039             Xpath 1073741824                            " X: 0
7040         endif
7041         break           " discard error for $VIMNOERRTHROW
7042     endtry
7043 endwhile
7045 if exists("var1") || exists("var2") || exists("var3") ||
7046             \ !exists("var4") || var4 != 4711
7047     " The Xpath command does not accept 2^31 (negative); add explicitly:
7048     let Xpath = Xpath + 2147483648                      " X: 0
7049     if exists("var1")
7050         Xout "var1 =" var1
7051     endif
7052     if exists("var2")
7053         Xout "var2 =" var2
7054     endif
7055     if exists("var3")
7056         Xout "var3 =" var3
7057     endif
7058     if !exists("var4")
7059         Xout "var4 unset"
7060     elseif var4 != 4711
7061         Xout "var4 =" var4
7062     endif
7063 endif
7065 unlet! error var1 var2 var3 var4
7066 delfunction THROW
7067 delfunction NAME
7068 delfunction ARG
7069 delfunction F
7071 Xcheck 212514423
7074 "-------------------------------------------------------------------------------
7075 " Test 69:  :throw across :if, :elseif, :while                              {{{1
7077 "           On an :if, :elseif, or :while command, an exception might be thrown
7078 "           during evaluation of the expression to test.  The exception can be
7079 "           caught by the script.
7080 "-------------------------------------------------------------------------------
7082 XpathINIT
7084 XloopINIT! 1 2
7086 function! THROW(x)
7087     XloopNEXT
7088     Xloop 1                                     " X: 1 + 2 + 4
7089     throw a:x
7090 endfunction
7094     try
7095         Xpath 8                                 " X: 8
7096         if 4711 == THROW("if") + 111
7097             Xpath 16                            " X: 0
7098         else
7099             Xpath 32                            " X: 0
7100         endif
7101         Xpath 64                                " X: 0
7102     catch /^if$/
7103         Xpath 128                               " X: 128
7104     catch /.*/
7105         Xpath 256                               " X: 0
7106         Xout "if:" v:exception "in" v:throwpoint
7107     endtry
7109     try
7110         Xpath 512                               " X: 512
7111         if 4711 == 4 + 7 + 1 + 1
7112             Xpath 1024                          " X: 0
7113         elseif 4711 == THROW("elseif") + 222
7114             Xpath 2048                          " X: 0
7115         else
7116             Xpath 4096                          " X: 0
7117         endif
7118         Xpath 8192                              " X: 0
7119     catch /^elseif$/
7120         Xpath 16384                             " X: 16384
7121     catch /.*/
7122         Xpath 32768                             " X: 0
7123         Xout "elseif:" v:exception "in" v:throwpoint
7124     endtry
7126     try
7127         Xpath 65536                             " X: 65536
7128         while 4711 == THROW("while") + 4711
7129             Xpath 131072                        " X: 0
7130             break
7131         endwhile
7132         Xpath 262144                            " X: 0
7133     catch /^while$/
7134         Xpath 524288                            " X: 524288
7135     catch /.*/
7136         Xpath 1048576                           " X: 0
7137         Xout "while:" v:exception "in" v:throwpoint
7138     endtry
7140 catch /^0$/         " default return value
7141     Xpath 2097152                               " X: 0
7142     Xout v:throwpoint
7143 catch /.*/
7144     Xout v:exception "in" v:throwpoint
7145     Xpath 4194304                               " X: 0
7146 endtry
7148 Xpath 8388608                                   " X: 8388608
7150 delfunction THROW
7152 Xcheck 8995471
7155 "-------------------------------------------------------------------------------
7156 " Test 70:  :throw across :return or :throw                                 {{{1
7158 "           On a :return or :throw command, an exception might be thrown during
7159 "           evaluation of the expression to return or throw, respectively.  The
7160 "           exception can be caught by the script.
7161 "-------------------------------------------------------------------------------
7163 XpathINIT
7165 let taken = ""
7167 function! THROW(x, n)
7168     let g:taken = g:taken . "T" . a:n
7169     throw a:x
7170 endfunction
7172 function! F(x, y, n)
7173     let g:taken = g:taken . "F" . a:n
7174     return a:x + THROW(a:y, a:n)
7175 endfunction
7177 function! G(x, y, n)
7178     let g:taken = g:taken . "G" . a:n
7179     throw a:x . THROW(a:y, a:n)
7180     return a:x
7181 endfunction
7184     try
7185         Xpath 1                                 " X: 1
7186         call F(4711, "return", 1)
7187         Xpath 2                                 " X: 0
7188     catch /^return$/
7189         Xpath 4                                 " X: 4
7190     catch /.*/
7191         Xpath 8                                 " X: 0
7192         Xout "return:" v:exception "in" v:throwpoint
7193     endtry
7195     try
7196         Xpath 16                                " X: 16
7197         let var = F(4712, "return-var", 2)
7198         Xpath 32                                " X: 0
7199     catch /^return-var$/
7200         Xpath 64                                " X: 64
7201     catch /.*/
7202         Xpath 128                               " X: 0
7203         Xout "return-var:" v:exception "in" v:throwpoint
7204     finally
7205         unlet! var
7206     endtry
7208     try
7209         Xpath 256                               " X: 256
7210         throw "except1" . THROW("throw1", 3)
7211         Xpath 512                               " X: 0
7212     catch /^except1/
7213         Xpath 1024                              " X: 0
7214     catch /^throw1$/
7215         Xpath 2048                              " X: 2048
7216     catch /.*/
7217         Xpath 4096                              " X: 0
7218         Xout "throw1:" v:exception "in" v:throwpoint
7219     endtry
7221     try
7222         Xpath 8192                              " X: 8192
7223         call G("except2", "throw2", 4)
7224         Xpath 16384                             " X: 0
7225     catch /^except2/
7226         Xpath 32768                             " X: 0
7227     catch /^throw2$/
7228         Xpath 65536                             " X: 65536
7229     catch /.*/
7230         Xpath 131072                            " X: 0
7231         Xout "throw2:" v:exception "in" v:throwpoint
7232     endtry
7234     try
7235         Xpath 262144                            " X: 262144
7236         let var = G("except3", "throw3", 5)
7237         Xpath 524288                            " X: 0
7238     catch /^except3/
7239         Xpath 1048576                           " X: 0
7240     catch /^throw3$/
7241         Xpath 2097152                           " X: 2097152
7242     catch /.*/
7243         Xpath 4194304                           " X: 0
7244         Xout "throw3:" v:exception "in" v:throwpoint
7245     finally
7246         unlet! var
7247     endtry
7249     let expected = "F1T1F2T2T3G4T4G5T5"
7250     if taken != expected
7251         Xpath 8388608                           " X: 0
7252         Xout "'taken' is" taken "instead of" expected
7253     endif
7255 catch /^0$/         " default return value
7256     Xpath 16777216                              " X: 0
7257     Xout v:throwpoint
7258 catch /.*/
7259     Xpath 33554432                              " X: 0
7260     Xout v:exception "in" v:throwpoint
7261 endtry
7263 Xpath 67108864                                  " X: 67108864
7265 unlet taken expected
7266 delfunction THROW
7267 delfunction F
7268 delfunction G
7270 Xcheck 69544277
7273 "-------------------------------------------------------------------------------
7274 " Test 71:  :throw across :echo variants and :execute                       {{{1
7276 "           On an :echo, :echon, :echomsg, :echoerr, or :execute command, an
7277 "           exception might be thrown during evaluation of the arguments to
7278 "           be displayed or executed as a command, respectively.  Any following
7279 "           arguments are not evaluated, then.  The exception can be caught by
7280 "           the script.
7281 "-------------------------------------------------------------------------------
7283 XpathINIT
7285 let taken = ""
7287 function! THROW(x, n)
7288     let g:taken = g:taken . "T" . a:n
7289     throw a:x
7290 endfunction
7292 function! F(n)
7293     let g:taken = g:taken . "F" . a:n
7294     return "F" . a:n
7295 endfunction
7298     try
7299         Xpath 1                                 " X: 1
7300         echo "echo" . THROW("echo-except", 1) F(1)
7301         Xpath 2                                 " X: 0
7302     catch /^echo-except$/
7303         Xpath 4                                 " X: 4
7304     catch /.*/
7305         Xpath 8                                 " X: 0
7306         Xout "echo:" v:exception "in" v:throwpoint
7307     endtry
7309     try
7310         Xpath 16                                " X: 16
7311         echon "echon" . THROW("echon-except", 2) F(2)
7312         Xpath 32                                " X: 0
7313     catch /^echon-except$/
7314         Xpath 64                                " X: 64
7315     catch /.*/
7316         Xpath 128                               " X: 0
7317         Xout "echon:" v:exception "in" v:throwpoint
7318     endtry
7320     try
7321         Xpath 256                               " X: 256
7322         echomsg "echomsg" . THROW("echomsg-except", 3) F(3)
7323         Xpath 512                               " X: 0
7324     catch /^echomsg-except$/
7325         Xpath 1024                              " X: 1024
7326     catch /.*/
7327         Xpath 2048                              " X: 0
7328         Xout "echomsg:" v:exception "in" v:throwpoint
7329     endtry
7331     try
7332         Xpath 4096                              " X: 4096
7333         echoerr "echoerr" . THROW("echoerr-except", 4) F(4)
7334         Xpath 8192                              " X: 0
7335     catch /^echoerr-except$/
7336         Xpath 16384                             " X: 16384
7337     catch /Vim/
7338         Xpath 32768                             " X: 0
7339     catch /echoerr/
7340         Xpath 65536                             " X: 0
7341     catch /.*/
7342         Xpath 131072                            " X: 0
7343         Xout "echoerr:" v:exception "in" v:throwpoint
7344     endtry
7346     try
7347         Xpath 262144                            " X: 262144
7348         execute "echo 'execute" . THROW("execute-except", 5) F(5) "'"
7349         Xpath 524288                            " X: 0
7350     catch /^execute-except$/
7351         Xpath 1048576                           " X: 1048576
7352     catch /.*/
7353         Xpath 2097152                           " X: 0
7354         Xout "execute:" v:exception "in" v:throwpoint
7355     endtry
7357     let expected = "T1T2T3T4T5"
7358     if taken != expected
7359         Xpath 4194304                           " X: 0
7360         Xout "'taken' is" taken "instead of" expected
7361     endif
7363 catch /^0$/         " default return value
7364     Xpath 8388608                               " X: 0
7365     Xout v:throwpoint
7366 catch /.*/
7367     Xpath 16777216                              " X: 0
7368     Xout v:exception "in" v:throwpoint
7369 endtry
7371 Xpath 33554432                                  " X: 33554432
7373 unlet taken expected
7374 delfunction THROW
7375 delfunction F
7377 Xcheck 34886997
7380 "-------------------------------------------------------------------------------
7381 " Test 72:  :throw across :let or :unlet                                    {{{1
7383 "           On a :let command, an exception might be thrown during evaluation
7384 "           of the expression to assign.  On an :let or :unlet command, the
7385 "           evaluation of the name of the variable to be assigned or list or
7386 "           deleted, respectively, may throw an exception.  Any following
7387 "           arguments are not evaluated, then.  The exception can be caught by
7388 "           the script.
7389 "-------------------------------------------------------------------------------
7391 XpathINIT
7393 let throwcount = 0
7395 function! THROW(x)
7396     let g:throwcount = g:throwcount + 1
7397     throw a:x
7398 endfunction
7401     try
7402         let $VAR = "old_value"
7403         Xpath 1                                 " X: 1
7404         let $VAR = "let(" . THROW("var") . ")"
7405         Xpath 2                                 " X: 0
7406     catch /^var$/
7407         Xpath 4                                 " X: 4
7408     finally
7409         if $VAR != "old_value"
7410             Xpath 8                             " X: 0
7411         endif
7412     endtry
7414     try
7415         let @a = "old_value"
7416         Xpath 16                                " X: 16
7417         let @a = "let(" . THROW("reg") . ")"
7418         Xpath 32                                " X: 0
7419     catch /^reg$/
7420         try
7421             Xpath 64                            " X: 64
7422             let @A = "let(" . THROW("REG") . ")"
7423             Xpath 128                           " X: 0
7424         catch /^REG$/
7425             Xpath 256                           " X: 256
7426         endtry
7427     finally
7428         if @a != "old_value"
7429             Xpath 512                           " X: 0
7430         endif
7431         if @A != "old_value"
7432             Xpath 1024                          " X: 0
7433         endif
7434     endtry
7436     try
7437         let saved_gpath = &g:path
7438         let saved_lpath = &l:path
7439         Xpath 2048                              " X: 2048
7440         let &path = "let(" . THROW("opt") . ")"
7441         Xpath 4096                              " X: 0
7442     catch /^opt$/
7443         try
7444             Xpath 8192                          " X: 8192
7445             let &g:path = "let(" . THROW("gopt") . ")"
7446             Xpath 16384                         " X: 0
7447         catch /^gopt$/
7448             try
7449                 Xpath 32768                     " X: 32768
7450                 let &l:path = "let(" . THROW("lopt") . ")"
7451                 Xpath 65536                     " X: 0
7452             catch /^lopt$/
7453                 Xpath 131072                    " X: 131072
7454             endtry
7455         endtry
7456     finally
7457         if &g:path != saved_gpath || &l:path != saved_lpath
7458             Xpath 262144                        " X: 0
7459         endif
7460         let &g:path = saved_gpath
7461         let &l:path = saved_lpath
7462     endtry
7464     unlet! var1 var2 var3
7466     try
7467         Xpath 524288                            " X: 524288
7468         let var1 = "let(" . THROW("var1") . ")"
7469         Xpath 1048576                           " X: 0
7470     catch /^var1$/
7471         Xpath 2097152                           " X: 2097152
7472     finally
7473         if exists("var1")
7474             Xpath 4194304                       " X: 0
7475         endif
7476     endtry
7478     try
7479         let var2 = "old_value"
7480         Xpath 8388608                           " X: 8388608
7481         let var2 = "let(" . THROW("var2"). ")"
7482         Xpath 16777216                          " X: 0
7483     catch /^var2$/
7484         Xpath 33554432                          " X: 33554432
7485     finally
7486         if var2 != "old_value"
7487             Xpath 67108864                      " X: 0
7488         endif
7489     endtry
7491     try
7492         Xpath 134217728                         " X: 134217728
7493         let var{THROW("var3")} = 4711
7494         Xpath 268435456                         " X: 0
7495     catch /^var3$/
7496         Xpath 536870912                         " X: 536870912
7497     endtry
7499     let addpath = ""
7501     function ADDPATH(p)
7502         let g:addpath = g:addpath . a:p
7503     endfunction
7505     try
7506         call ADDPATH("T1")
7507         let var{THROW("var4")} var{ADDPATH("T2")} | call ADDPATH("T3")
7508         call ADDPATH("T4")
7509     catch /^var4$/
7510         call ADDPATH("T5")
7511     endtry
7513     try
7514         call ADDPATH("T6")
7515         unlet var{THROW("var5")} var{ADDPATH("T7")} | call ADDPATH("T8")
7516         call ADDPATH("T9")
7517     catch /^var5$/
7518         call ADDPATH("T10")
7519     endtry
7521     if addpath != "T1T5T6T10" || throwcount != 11
7522         throw "addpath: " . addpath . ", throwcount: " . throwcount
7523     endif
7525     Xpath 1073741824                            " X: 1073741824
7527 catch /.*/
7528     " The Xpath command does not accept 2^31 (negative); add explicitly:
7529     let Xpath = Xpath + 2147483648              " X: 0
7530     Xout v:exception "in" v:throwpoint
7531 endtry
7533 unlet! var1 var2 var3 addpath throwcount
7534 delfunction THROW
7536 Xcheck 1789569365
7539 "-------------------------------------------------------------------------------
7540 " Test 73:  :throw across :function, :delfunction                           {{{1
7542 "           The :function and :delfunction commands may cause an expression
7543 "           specified in braces to be evaluated.  During evaluation, an
7544 "           exception might be thrown.  The exception can be caught by the
7545 "           script.
7546 "-------------------------------------------------------------------------------
7548 XpathINIT
7550 let taken = ""
7552 function! THROW(x, n)
7553     let g:taken = g:taken . "T" . a:n
7554     throw a:x
7555 endfunction
7557 function! EXPR(x, n)
7558     let g:taken = g:taken . "E" . a:n
7559     if a:n % 2 == 0
7560         call THROW(a:x, a:n)
7561     endif
7562     return 2 - a:n % 2
7563 endfunction
7566     try
7567         " Define function.
7568         Xpath 1                                 " X: 1
7569         function! F0()
7570         endfunction
7571         Xpath 2                                 " X: 2
7572         function! F{EXPR("function-def-ok", 1)}()
7573         endfunction
7574         Xpath 4                                 " X: 4
7575         function! F{EXPR("function-def", 2)}()
7576         endfunction
7577         Xpath 8                                 " X: 0
7578     catch /^function-def-ok$/
7579         Xpath 16                                " X: 0
7580     catch /^function-def$/
7581         Xpath 32                                " X: 32
7582     catch /.*/
7583         Xpath 64                                " X: 0
7584         Xout "def:" v:exception "in" v:throwpoint
7585     endtry
7587     try
7588         " List function.
7589         Xpath 128                               " X: 128
7590         function F0
7591         Xpath 256                               " X: 256
7592         function F{EXPR("function-lst-ok", 3)}
7593         Xpath 512                               " X: 512
7594         function F{EXPR("function-lst", 4)}
7595         Xpath 1024                              " X: 0
7596     catch /^function-lst-ok$/
7597         Xpath 2048                              " X: 0
7598     catch /^function-lst$/
7599         Xpath 4096                              " X: 4096
7600     catch /.*/
7601         Xpath 8192                              " X: 0
7602         Xout "lst:" v:exception "in" v:throwpoint
7603     endtry
7605     try
7606         " Delete function
7607         Xpath 16384                             " X: 16384
7608         delfunction F0
7609         Xpath 32768                             " X: 32768
7610         delfunction F{EXPR("function-del-ok", 5)}
7611         Xpath 65536                             " X: 65536
7612         delfunction F{EXPR("function-del", 6)}
7613         Xpath 131072                            " X: 0
7614     catch /^function-del-ok$/
7615         Xpath 262144                            " X: 0
7616     catch /^function-del$/
7617         Xpath 524288                            " X: 524288
7618     catch /.*/
7619         Xpath 1048576                           " X: 0
7620         Xout "del:" v:exception "in" v:throwpoint
7621     endtry
7623     let expected = "E1E2T2E3E4T4E5E6T6"
7624     if taken != expected
7625         Xpath 2097152                           " X: 0
7626         Xout "'taken' is" taken "instead of" expected
7627     endif
7629 catch /.*/
7630     Xpath 4194304                               " X: 0
7631     Xout v:exception "in" v:throwpoint
7632 endtry
7634 Xpath 8388608                                   " X: 8388608
7636 unlet taken expected
7637 delfunction THROW
7638 delfunction EXPR
7640 Xcheck 9032615
7643 "-------------------------------------------------------------------------------
7644 " Test 74:  :throw across builtin functions and commands                    {{{1
7646 "           Some functions like exists(), searchpair() take expression
7647 "           arguments, other functions or commands like substitute() or
7648 "           :substitute cause an expression (specified in the regular
7649 "           expression) to be evaluated.  During evaluation an exception
7650 "           might be thrown.  The exception can be caught by the script.
7651 "-------------------------------------------------------------------------------
7653 XpathINIT
7655 let taken = ""
7657 function! THROW(x, n)
7658     let g:taken = g:taken . "T" . a:n
7659     throw a:x
7660 endfunction
7662 function! EXPR(x, n)
7663     let g:taken = g:taken . "E" . a:n
7664     call THROW(a:x . a:n, a:n)
7665     return "EXPR"
7666 endfunction
7668 function! SKIP(x, n)
7669     let g:taken = g:taken . "S" . a:n . "(" . line(".")
7670     let theline = getline(".")
7671     if theline =~ "skip"
7672         let g:taken = g:taken . "s)"
7673         return 1
7674     elseif theline =~ "throw"
7675         let g:taken = g:taken . "t)"
7676         call THROW(a:x . a:n, a:n)
7677     else
7678         let g:taken = g:taken . ")"
7679         return 0
7680     endif
7681 endfunction
7683 function! SUBST(x, n)
7684     let g:taken = g:taken . "U" . a:n . "(" . line(".")
7685     let theline = getline(".")
7686     if theline =~ "not"     " SUBST() should not be called for this line
7687         let g:taken = g:taken . "n)"
7688         call THROW(a:x . a:n, a:n)
7689     elseif theline =~ "throw"
7690         let g:taken = g:taken . "t)"
7691         call THROW(a:x . a:n, a:n)
7692     else
7693         let g:taken = g:taken . ")"
7694         return "replaced"
7695     endif
7696 endfunction
7699     try
7700         Xpath 1                                 " X: 1
7701         let result = exists('*{EXPR("exists", 1)}')
7702         Xpath 2                                 " X: 0
7703     catch /^exists1$/
7704         Xpath 4                                 " X: 4
7705         try
7706             let result = exists('{EXPR("exists", 2)}')
7707             Xpath 8                             " X: 0
7708         catch /^exists2$/
7709             Xpath 16                            " X: 16
7710         catch /.*/
7711             Xpath 32                            " X: 0
7712             Xout "exists2:" v:exception "in" v:throwpoint
7713         endtry
7714     catch /.*/
7715         Xpath 64                                " X: 0
7716         Xout "exists1:" v:exception "in" v:throwpoint
7717     endtry
7719     try
7720         let file = tempname()
7721         exec "edit" file
7722         insert
7723 begin
7724     xx
7725 middle 3
7726     xx
7727 middle 5 skip
7728     xx
7729 middle 7 throw
7730     xx
7733         normal! gg
7734         Xpath 128                               " X: 128
7735         let result =
7736             \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 3)')
7737         Xpath 256                               " X: 256
7738         let result =
7739             \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 4)')
7740         Xpath 512                               " X: 0
7741         let result =
7742             \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 5)')
7743         Xpath 1024                              " X: 0
7744     catch /^searchpair[35]$/
7745         Xpath 2048                              " X: 0
7746     catch /^searchpair4$/
7747         Xpath 4096                              " X: 4096
7748     catch /.*/
7749         Xpath 8192                              " X: 0
7750         Xout "searchpair:" v:exception "in" v:throwpoint
7751     finally
7752         bwipeout!
7753         call delete(file)
7754     endtry
7756     try
7757         let file = tempname()
7758         exec "edit" file
7759         insert
7760 subst 1
7761 subst 2
7763 subst 4
7764 subst throw
7765 subst 6
7767         normal! gg
7768         Xpath 16384                             " X: 16384
7769         1,2substitute/subst/\=SUBST("substitute", 6)/
7770         try
7771             Xpath 32768                         " X: 32768
7772             try
7773                 let v:errmsg = ""
7774                 3substitute/subst/\=SUBST("substitute", 7)/
7775             finally
7776                 if v:errmsg != ""
7777                     " If exceptions are not thrown on errors, fake the error
7778                     " exception in order to get the same execution path.
7779                     throw "faked Vim(substitute)"
7780                 endif
7781             endtry
7782         catch /Vim(substitute)/     " Pattern not found ('e' flag missing)
7783             Xpath 65536                         " X: 65536
7784             3substitute/subst/\=SUBST("substitute", 8)/e
7785             Xpath 131072                        " X: 131072
7786         endtry
7787         Xpath 262144                            " X: 262144
7788         4,6substitute/subst/\=SUBST("substitute", 9)/
7789         Xpath 524288                            " X: 0
7790     catch /^substitute[678]/
7791         Xpath 1048576                           " X: 0
7792     catch /^substitute9/
7793         Xpath 2097152                           " X: 2097152
7794     finally
7795         bwipeout!
7796         call delete(file)
7797     endtry
7799     try
7800         Xpath 4194304                           " X: 4194304
7801         let var = substitute("sub", "sub", '\=THROW("substitute()y", 10)', '')
7802         Xpath 8388608                           " X: 0
7803     catch /substitute()y/
7804         Xpath 16777216                          " X: 16777216
7805     catch /.*/
7806         Xpath 33554432                          " X: 0
7807         Xout "substitute()y:" v:exception "in" v:throwpoint
7808     endtry
7810     try
7811         Xpath 67108864                          " X: 67108864
7812         let var = substitute("not", "sub", '\=THROW("substitute()n", 11)', '')
7813         Xpath 134217728                         " X: 134217728
7814     catch /substitute()n/
7815         Xpath 268435456                         " X: 0
7816     catch /.*/
7817         Xpath 536870912                         " X: 0
7818         Xout "substitute()n:" v:exception "in" v:throwpoint
7819     endtry
7821     let expected = "E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10"
7822     if taken != expected
7823         Xpath 1073741824                        " X: 0
7824         Xout "'taken' is" taken "instead of" expected
7825     endif
7827 catch /.*/
7828     " The Xpath command does not accept 2^31 (negative); add explicitly:
7829     let Xpath = Xpath + 2147483648              " X: 0
7830     Xout v:exception "in" v:throwpoint
7831 endtry
7833 unlet result var taken expected
7834 delfunction THROW
7835 delfunction EXPR
7836 delfunction SKIP
7837 delfunction SUBST
7839 Xcheck 224907669
7842 "-------------------------------------------------------------------------------
7843 " Test 75:  Errors in builtin functions.                                    {{{1
7845 "           On an error in a builtin function called inside a :try/:endtry
7846 "           region, the evaluation of the expression calling that function and
7847 "           the command containing that expression are abandoned.  The error can
7848 "           be caught as an exception.
7850 "           A simple :call of the builtin function is a trivial case.  If the
7851 "           builtin function is called in the argument list of another function,
7852 "           no further arguments are evaluated, and the other function is not
7853 "           executed.  If the builtin function is called from the argument of
7854 "           a :return command, the :return command is not executed.  If the
7855 "           builtin function is called from the argument of a :throw command,
7856 "           the :throw command is not executed.  The evaluation of the
7857 "           expression calling the builtin function is abandoned.
7858 "-------------------------------------------------------------------------------
7860 XpathINIT
7862 function! F1(arg1)
7863     Xpath 1                                     " X: 0
7864 endfunction
7866 function! F2(arg1, arg2)
7867     Xpath 2                                     " X: 0
7868 endfunction
7870 function! G()
7871     Xpath 4                                     " X: 0
7872 endfunction
7874 function! H()
7875     Xpath 8                                     " X: 0
7876 endfunction
7878 function! R()
7879     while 1
7880         try
7881             let caught = 0
7882             let v:errmsg = ""
7883             Xpath 16                            " X: 16
7884             return append(1, "s")
7885         catch /E21/
7886             let caught = 1
7887         catch /.*/
7888             Xpath 32                            " X: 0
7889         finally
7890             Xpath 64                            " X: 64
7891             if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
7892                 Xpath 128                       " X: 128
7893             endif
7894             break               " discard error for $VIMNOERRTHROW
7895         endtry
7896     endwhile
7897     Xpath 256                                   " X: 256
7898 endfunction
7901     set noma    " let append() fail with "E21"
7903     while 1
7904         try
7905             let caught = 0
7906             let v:errmsg = ""
7907             Xpath 512                           " X: 512
7908             call append(1, "s")
7909         catch /E21/
7910             let caught = 1
7911         catch /.*/
7912             Xpath 1024                          " X: 0
7913         finally
7914             Xpath 2048                          " X: 2048
7915             if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
7916                 Xpath 4096                      " X: 4096
7917             endif
7918             break               " discard error for $VIMNOERRTHROW
7919         endtry
7920     endwhile
7922     while 1
7923         try
7924             let caught = 0
7925             let v:errmsg = ""
7926             Xpath 8192                          " X: 8192
7927             call F1('x' . append(1, "s"))
7928         catch /E21/
7929             let caught = 1
7930         catch /.*/
7931             Xpath 16384                         " X: 0
7932         finally
7933             Xpath 32768                         " X: 32768
7934             if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
7935                 Xpath 65536                     " X: 65536
7936             endif
7937             break               " discard error for $VIMNOERRTHROW
7938         endtry
7939     endwhile
7941     while 1
7942         try
7943             let caught = 0
7944             let v:errmsg = ""
7945             Xpath 131072                        " X: 131072
7946             call F2('x' . append(1, "s"), G())
7947         catch /E21/
7948             let caught = 1
7949         catch /.*/
7950             Xpath 262144                        " X: 0
7951         finally
7952             Xpath 524288                        " X: 524288
7953             if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
7954                 Xpath 1048576                   " X: 1048576
7955             endif
7956             break               " discard error for $VIMNOERRTHROW
7957         endtry
7958     endwhile
7960     call R()
7962     while 1
7963         try
7964             let caught = 0
7965             let v:errmsg = ""
7966             Xpath 2097152                       " X: 2097152
7967             throw "T" . append(1, "s")
7968         catch /E21/
7969             let caught = 1
7970         catch /^T.*/
7971             Xpath 4194304                       " X: 0
7972         catch /.*/
7973             Xpath 8388608                       " X: 0
7974         finally
7975             Xpath 16777216                      " X: 16777216
7976             if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
7977                 Xpath 33554432                  " X: 33554432
7978             endif
7979             break               " discard error for $VIMNOERRTHROW
7980         endtry
7981     endwhile
7983     while 1
7984         try
7985             let caught = 0
7986             let v:errmsg = ""
7987             Xpath 67108864                      " X: 67108864
7988             let x = "a"
7989             let x = x . "b" . append(1, "s") . H()
7990         catch /E21/
7991             let caught = 1
7992         catch /.*/
7993             Xpath 134217728                     " X: 0
7994         finally
7995             Xpath 268435456                     " X: 268435456
7996             if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
7997                 Xpath 536870912                 " X: 536870912
7998             endif
7999             if x == "a"
8000                 Xpath 1073741824                " X: 1073741824
8001             endif
8002             break               " discard error for $VIMNOERRTHROW
8003         endtry
8004     endwhile
8005 catch /.*/
8006     " The Xpath command does not accept 2^31 (negative); add explicitly:
8007     let Xpath = Xpath + 2147483648              " X: 0
8008     Xout v:exception "in" v:throwpoint
8009 finally
8010     set ma&
8011 endtry
8013 unlet! caught x
8014 delfunction F1
8015 delfunction F2
8016 delfunction G
8017 delfunction H
8018 delfunction R
8020 Xcheck 2000403408
8023 "-------------------------------------------------------------------------------
8024 " Test 76:  Errors, interrupts, :throw during expression evaluation         {{{1
8026 "           When a function call made during expression evaluation is aborted
8027 "           due to an error inside a :try/:endtry region or due to an interrupt
8028 "           or a :throw, the expression evaluation is aborted as well.  No
8029 "           message is displayed for the cancelled expression evaluation.  On an
8030 "           error not inside :try/:endtry, the expression evaluation continues.
8031 "-------------------------------------------------------------------------------
8033 XpathINIT
8035 if ExtraVim()
8037     let taken = ""
8039     function! ERR(n)
8040         let g:taken = g:taken . "E" . a:n
8041         asdf
8042     endfunction
8044     function! ERRabort(n) abort
8045         let g:taken = g:taken . "A" . a:n
8046         asdf
8047     endfunction " returns -1; may cause follow-up msg for illegal var/func name
8049     function! WRAP(n, arg)
8050         let g:taken = g:taken . "W" . a:n
8051         let g:saved_errmsg = v:errmsg
8052         return arg
8053     endfunction
8055     function! INT(n)
8056         let g:taken = g:taken . "I" . a:n
8057         "INTERRUPT9
8058         let dummy = 0
8059     endfunction
8061     function! THR(n)
8062         let g:taken = g:taken . "T" . a:n
8063         throw "should not be caught"
8064     endfunction
8066     function! CONT(n)
8067         let g:taken = g:taken . "C" . a:n
8068     endfunction
8070     function! MSG(n)
8071         let g:taken = g:taken . "M" . a:n
8072         let errmsg = (a:n >= 37 && a:n <= 44) ? g:saved_errmsg : v:errmsg
8073         let msgptn = (a:n >= 10 && a:n <= 27) ? "^$" : "asdf"
8074         if errmsg !~ msgptn
8075             let g:taken = g:taken . "x"
8076             Xout "Expr" a:n.": Unexpected message:" v:errmsg
8077         endif
8078         let v:errmsg = ""
8079         let g:saved_errmsg = ""
8080     endfunction
8082     let v:errmsg = ""
8084     try
8085         let t = 1
8086         XloopINIT 1 2
8087         while t <= 9
8088             Xloop 1                             " X: 511
8089             try
8090                 if t == 1
8091                     let v{ERR(t) + CONT(t)} = 0
8092                 elseif t == 2
8093                     let v{ERR(t) + CONT(t)}
8094                 elseif t == 3
8095                     let var = exists('v{ERR(t) + CONT(t)}')
8096                 elseif t == 4
8097                     unlet v{ERR(t) + CONT(t)}
8098                 elseif t == 5
8099                     function F{ERR(t) + CONT(t)}()
8100                     endfunction
8101                 elseif t == 6
8102                     function F{ERR(t) + CONT(t)}
8103                 elseif t == 7
8104                     let var = exists('*F{ERR(t) + CONT(t)}')
8105                 elseif t == 8
8106                     delfunction F{ERR(t) + CONT(t)}
8107                 elseif t == 9
8108                     let var = ERR(t) + CONT(t)
8109                 endif
8110             catch /asdf/
8111                 " v:errmsg is not set when the error message is converted to an
8112                 " exception.  Set it to the original error message.
8113                 let v:errmsg = substitute(v:exception, '^Vim:', '', "")
8114             catch /^Vim\((\a\+)\)\=:/
8115                 " An error exception has been thrown after the original error.
8116                 let v:errmsg = ""
8117             finally
8118                 call MSG(t)
8119                 let t = t + 1
8120                 XloopNEXT
8121                 continue        " discard an aborting error
8122             endtry
8123         endwhile
8124     catch /.*/
8125         Xpath 512                               " X: 0
8126         Xout v:exception "in" ExtraVimThrowpoint()
8127     endtry
8129     try
8130         let t = 10
8131         XloopINIT 1024 2
8132         while t <= 18
8133             Xloop 1                             " X: 1024 * 511
8134             try
8135                 if t == 10
8136                     let v{INT(t) + CONT(t)} = 0
8137                 elseif t == 11
8138                     let v{INT(t) + CONT(t)}
8139                 elseif t == 12
8140                     let var = exists('v{INT(t) + CONT(t)}')
8141                 elseif t == 13
8142                     unlet v{INT(t) + CONT(t)}
8143                 elseif t == 14
8144                     function F{INT(t) + CONT(t)}()
8145                     endfunction
8146                 elseif t == 15
8147                     function F{INT(t) + CONT(t)}
8148                 elseif t == 16
8149                     let var = exists('*F{INT(t) + CONT(t)}')
8150                 elseif t == 17
8151                     delfunction F{INT(t) + CONT(t)}
8152                 elseif t == 18
8153                     let var = INT(t) + CONT(t)
8154                 endif
8155             catch /^Vim\((\a\+)\)\=:\(Interrupt\)\@!/
8156                 " An error exception has been triggered after the interrupt.
8157                 let v:errmsg = substitute(v:exception,
8158                     \ '^Vim\((\a\+)\)\=:', '', "")
8159             finally
8160                 call MSG(t)
8161                 let t = t + 1
8162                 XloopNEXT
8163                 continue        " discard interrupt
8164             endtry
8165         endwhile
8166     catch /.*/
8167         Xpath 524288                            " X: 0
8168         Xout v:exception "in" ExtraVimThrowpoint()
8169     endtry
8171     try
8172         let t = 19
8173         XloopINIT 1048576 2
8174         while t <= 27
8175             Xloop 1                             " X: 1048576 * 511
8176             try
8177                 if t == 19
8178                     let v{THR(t) + CONT(t)} = 0
8179                 elseif t == 20
8180                     let v{THR(t) + CONT(t)}
8181                 elseif t == 21
8182                     let var = exists('v{THR(t) + CONT(t)}')
8183                 elseif t == 22
8184                     unlet v{THR(t) + CONT(t)}
8185                 elseif t == 23
8186                     function F{THR(t) + CONT(t)}()
8187                     endfunction
8188                 elseif t == 24
8189                     function F{THR(t) + CONT(t)}
8190                 elseif t == 25
8191                     let var = exists('*F{THR(t) + CONT(t)}')
8192                 elseif t == 26
8193                     delfunction F{THR(t) + CONT(t)}
8194                 elseif t == 27
8195                     let var = THR(t) + CONT(t)
8196                 endif
8197             catch /^Vim\((\a\+)\)\=:/
8198                 " An error exception has been triggered after the :throw.
8199                 let v:errmsg = substitute(v:exception,
8200                     \ '^Vim\((\a\+)\)\=:', '', "")
8201             finally
8202                 call MSG(t)
8203                 let t = t + 1
8204                 XloopNEXT
8205                 continue        " discard exception
8206             endtry
8207         endwhile
8208     catch /.*/
8209         Xpath 536870912                         " X: 0
8210         Xout v:exception "in" ExtraVimThrowpoint()
8211     endtry
8213     let v{ERR(28) + CONT(28)} = 0
8214     call MSG(28)
8215     let v{ERR(29) + CONT(29)}
8216     call MSG(29)
8217     let var = exists('v{ERR(30) + CONT(30)}')
8218     call MSG(30)
8219     unlet v{ERR(31) + CONT(31)}
8220     call MSG(31)
8221     function F{ERR(32) + CONT(32)}()
8222     endfunction
8223     call MSG(32)
8224     function F{ERR(33) + CONT(33)}
8225     call MSG(33)
8226     let var = exists('*F{ERR(34) + CONT(34)}')
8227     call MSG(34)
8228     delfunction F{ERR(35) + CONT(35)}
8229     call MSG(35)
8230     let var = ERR(36) + CONT(36)
8231     call MSG(36)
8233     let saved_errmsg = ""
8235     let v{WRAP(37, ERRabort(37)) + CONT(37)} = 0
8236     call MSG(37)
8237     let v{WRAP(38, ERRabort(38)) + CONT(38)}
8238     call MSG(38)
8239     let var = exists('v{WRAP(39, ERRabort(39)) + CONT(39)}')
8240     call MSG(39)
8241     unlet v{WRAP(40, ERRabort(40)) + CONT(40)}
8242     call MSG(40)
8243     function F{WRAP(41, ERRabort(41)) + CONT(41)}()
8244     endfunction
8245     call MSG(41)
8246     function F{WRAP(42, ERRabort(42)) + CONT(42)}
8247     call MSG(42)
8248     let var = exists('*F{WRAP(43, ERRabort(43)) + CONT(43)}')
8249     call MSG(43)
8250     delfunction F{WRAP(44, ERRabort(44)) + CONT(44)}
8251     call MSG(44)
8252     let var = ERRabort(45) + CONT(45)
8253     call MSG(45)
8255     Xpath 1073741824                            " X: 1073741824
8257     let expected = ""
8258         \ . "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9"
8259         \ . "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18"
8260         \ . "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27"
8261         \ . "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33"
8262         \ . "E34C34M34E35C35M35E36C36M36"
8263         \ . "A37W37C37M37A38W38C38M38A39W39C39M39A40W40C40M40A41W41C41M41"
8264         \ . "A42W42C42M42A43W43C43M43A44W44C44M44A45C45M45"
8266     if taken != expected
8267         " The Xpath command does not accept 2^31 (negative); display explicitly:
8268         exec "!echo 2147483648 >>" . g:ExtraVimResult
8269                                                 " X: 0
8270         Xout "'taken' is" taken "instead of" expected
8271         if substitute(taken,
8272         \ '\(.*\)E3C3M3x\(.*\)E30C30M30x\(.*\)A39C39M39x\(.*\)',
8273         \ '\1E3M3\2E30C30M30\3A39C39M39\4',
8274         \ "") == expected
8275             Xout "Is ++emsg_skip for var with expr_start non-NULL"
8276                 \ "in f_exists ok?"
8277         endif
8278     endif
8280     unlet! v var saved_errmsg taken expected
8281     call delete(WA_t5)
8282     call delete(WA_t14)
8283     call delete(WA_t23)
8284     unlet! WA_t5 WA_t14 WA_t23
8285     delfunction WA_t5
8286     delfunction WA_t14
8287     delfunction WA_t23
8289 endif
8291 Xcheck 1610087935
8294 "-------------------------------------------------------------------------------
8295 " Test 77:  Errors, interrupts, :throw in name{brace-expression}            {{{1
8297 "           When a function call made during evaluation of an expression in
8298 "           braces as part of a function name after ":function" is aborted due
8299 "           to an error inside a :try/:endtry region or due to an interrupt or
8300 "           a :throw, the expression evaluation is aborted as well, and the
8301 "           function definition is ignored, skipping all commands to the
8302 "           ":endfunction".  On an error not inside :try/:endtry, the expression
8303 "           evaluation continues and the function gets defined, and can be
8304 "           called and deleted.
8305 "-------------------------------------------------------------------------------
8307 XpathINIT
8309 XloopINIT 1 4
8311 function! ERR() abort
8312     Xloop 1                                     " X: 1 + 4 + 16 + 64
8313     asdf
8314 endfunction             " returns -1
8316 function! OK()
8317     Xloop 2                                     " X: 2 * (1 + 4 + 16)
8318     let v:errmsg = ""
8319     return 0
8320 endfunction
8322 let v:errmsg = ""
8324 Xpath 4096                                      " X: 4096
8325 function! F{1 + ERR() + OK()}(arg)
8326     " F0 should be defined.
8327     if exists("a:arg") && a:arg == "calling"
8328         Xpath 8192                              " X: 8192
8329     else
8330         Xpath 16384                             " X: 0
8331     endif
8332 endfunction
8333 if v:errmsg != ""
8334     Xpath 32768                                 " X: 0
8335 endif
8336 XloopNEXT
8338 Xpath 65536                                     " X: 65536
8339 call F{1 + ERR() + OK()}("calling")
8340 if v:errmsg != ""
8341     Xpath 131072                                " X: 0
8342 endif
8343 XloopNEXT
8345 Xpath 262144                                    " X: 262144
8346 delfunction F{1 + ERR() + OK()}
8347 if v:errmsg != ""
8348     Xpath 524288                                " X: 0
8349 endif
8350 XloopNEXT
8353     while 1
8354         let caught = 0
8355         try
8356             Xpath 1048576                       " X: 1048576
8357             function! G{1 + ERR() + OK()}(arg)
8358                 " G0 should not be defined, and the function body should be
8359                 " skipped.
8360                 if exists("a:arg") && a:arg == "calling"
8361                     Xpath 2097152               " X: 0
8362                 else
8363                     Xpath 4194304               " X: 0
8364                 endif
8365                 " Use an unmatched ":finally" to check whether the body is
8366                 " skipped when an error occurs in ERR().  This works whether or
8367                 " not the exception is converted to an exception.
8368                 finally
8369                     Xpath 8388608               " X: 0
8370                     Xout "Body of G{1 + ERR() + OK()}() not skipped"
8371                     " Discard the aborting error or exception, and break the
8372                     " while loop.
8373                     break
8374                 " End the try conditional and start a new one to avoid
8375                 " ":catch after :finally" errors.
8376                 endtry
8377                 try
8378                 Xpath 16777216                  " X: 0
8379             endfunction
8381             " When the function was not defined, this won't be reached - whether
8382             " the body was skipped or not.  When the function was defined, it
8383             " can be called and deleted here.
8384             Xpath 33554432                      " X: 0
8385             Xout "G0() has been defined"
8386             XloopNEXT
8387             try
8388                 call G{1 + ERR() + OK()}("calling")
8389             catch /.*/
8390                 Xpath 67108864                  " X: 0
8391             endtry
8392             Xpath 134217728                     " X: 0
8393             XloopNEXT
8394             try
8395                 delfunction G{1 + ERR() + OK()}
8396             catch /.*/
8397                 Xpath 268435456                 " X: 0
8398             endtry
8399         catch /asdf/
8400             " Jumped to when the function is not defined and the body is
8401             " skipped.
8402             let caught = 1
8403         catch /.*/
8404             Xpath 536870912                     " X: 0
8405         finally
8406             if !caught && !$VIMNOERRTHROW
8407                 Xpath 1073741824                " X: 0
8408             endif
8409             break               " discard error for $VIMNOERRTHROW
8410         endtry                  " jumped to when the body is not skipped
8411     endwhile
8412 catch /.*/
8413     " The Xpath command does not accept 2^31 (negative); add explicitly:
8414     let Xpath = Xpath + 2147483648              " X: 0
8415     Xout "Body of G{1 + ERR() + OK()}() not skipped, exception caught"
8416     Xout v:exception "in" v:throwpoint
8417 endtry
8419 Xcheck 1388671
8422 "-------------------------------------------------------------------------------
8423 " Test 78:  Messages on parsing errors in expression evaluation             {{{1
8425 "           When an expression evaluation detects a parsing error, an error
8426 "           message is given and converted to an exception, and the expression
8427 "           evaluation is aborted.
8428 "-------------------------------------------------------------------------------
8430 XpathINIT
8432 if ExtraVim()
8434     let taken = ""
8436     function! F(n)
8437         let g:taken = g:taken . "F" . a:n
8438     endfunction
8440     function! MSG(n, enr, emsg)
8441         let g:taken = g:taken . "M" . a:n
8442         let english = v:lang == "C" || v:lang =~ '^[Ee]n'
8443         if a:enr == ""
8444             Xout "TODO: Add message number for:" a:emsg
8445             let v:errmsg = ":" . v:errmsg
8446         endif
8447         if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
8448             if v:errmsg == ""
8449                 Xout "Expr" a:n.": Message missing."
8450                 let g:taken = g:taken . "x"
8451             else
8452                 let v:errmsg = escape(v:errmsg, '"')
8453                 Xout "Expr" a:n.": Unexpected message:" v:errmsg
8454                 Xout "Expected: " . a:enr . ': ' . a:emsg
8455                 let g:taken = g:taken . "X"
8456             endif
8457         endif
8458     endfunction
8460     function! CONT(n)
8461         let g:taken = g:taken . "C" . a:n
8462     endfunction
8464     let v:errmsg = ""
8465     XloopINIT 1 2
8467     try
8468         let t = 1
8469         while t <= 14
8470             let g:taken = g:taken . "T" . t
8471             let v:errmsg = ""
8472             try
8473                 let caught = 0
8474                 if t == 1
8475                     let v{novar + CONT(t)} = 0
8476                 elseif t == 2
8477                     let v{novar + CONT(t)}
8478                 elseif t == 3
8479                     let var = exists('v{novar + CONT(t)}')
8480                 elseif t == 4
8481                     unlet v{novar + CONT(t)}
8482                 elseif t == 5
8483                     function F{novar + CONT(t)}()
8484                     endfunction
8485                 elseif t == 6
8486                     function F{novar + CONT(t)}
8487                 elseif t == 7
8488                     let var = exists('*F{novar + CONT(t)}')
8489                 elseif t == 8
8490                     delfunction F{novar + CONT(t)}
8491                 elseif t == 9
8492                     echo novar + CONT(t)
8493                 elseif t == 10
8494                     echo v{novar + CONT(t)}
8495                 elseif t == 11
8496                     echo F{novar + CONT(t)}
8497                 elseif t == 12
8498                     let var = novar + CONT(t)
8499                 elseif t == 13
8500                     let var = v{novar + CONT(t)}
8501                 elseif t == 14
8502                     let var = F{novar + CONT(t)}()
8503                 endif
8504             catch /^Vim\((\a\+)\)\=:/
8505                 " v:errmsg is not set when the error message is converted to an
8506                 " exception.  Set it to the original error message.
8507                 let v:errmsg = substitute(v:exception,
8508                     \ '^Vim\((\a\+)\)\=:', '', "")
8509                 let caught = 1
8510             finally
8511                 if t <= 8 && t != 3 && t != 7
8512                     call MSG(t, 'E475', 'Invalid argument\>')
8513                 else
8514                     if !caught  " no error exceptions ($VIMNOERRTHROW set)
8515                         call MSG(t, 'E15', "Invalid expression")
8516                     else
8517                         call MSG(t, 'E121', "Undefined variable")
8518                     endif
8519                 endif
8520                 let t = t + 1
8521                 XloopNEXT
8522                 continue        " discard an aborting error
8523             endtry
8524         endwhile
8525     catch /.*/
8526         Xloop 1                                 " X: 0
8527         Xout t.":" v:exception "in" ExtraVimThrowpoint()
8528     endtry
8530     function! T(n, expr, enr, emsg)
8531         try
8532             let g:taken = g:taken . "T" . a:n
8533             let v:errmsg = ""
8534             try
8535                 let caught = 0
8536                 execute "let var = " . a:expr
8537             catch /^Vim\((\a\+)\)\=:/
8538                 " v:errmsg is not set when the error message is converted to an
8539                 " exception.  Set it to the original error message.
8540                 let v:errmsg = substitute(v:exception,
8541                     \ '^Vim\((\a\+)\)\=:', '', "")
8542                 let caught = 1
8543             finally
8544                 if !caught      " no error exceptions ($VIMNOERRTHROW set)
8545                     call MSG(a:n, 'E15', "Invalid expression")
8546                 else
8547                     call MSG(a:n, a:enr, a:emsg)
8548                 endif
8549                 XloopNEXT
8550                 " Discard an aborting error:
8551                 return
8552             endtry
8553         catch /.*/
8554             Xloop 1                             " X: 0
8555             Xout a:n.":" v:exception "in" ExtraVimThrowpoint()
8556         endtry
8557     endfunction
8559     call T(15, 'Nofunc() + CONT(15)',   'E117', "Unknown function")
8560     call T(16, 'F(1 2 + CONT(16))',     'E116', "Invalid arguments")
8561     call T(17, 'F(1, 2) + CONT(17)',    'E118', "Too many arguments")
8562     call T(18, 'F() + CONT(18)',        'E119', "Not enough arguments")
8563     call T(19, '{(1} + CONT(19)',       'E110', "Missing ')'")
8564     call T(20, '("abc"[1) + CONT(20)',  'E111', "Missing ']'")
8565     call T(21, '(1 +) + CONT(21)',      'E15',  "Invalid expression")
8566     call T(22, '1 2 + CONT(22)',        'E15',  "Invalid expression")
8567     call T(23, '(1 ? 2) + CONT(23)',    'E109', "Missing ':' after '?'")
8568     call T(24, '("abc) + CONT(24)',     'E114', "Missing quote")
8569     call T(25, "('abc) + CONT(25)",     'E115', "Missing quote")
8570     call T(26, '& + CONT(26)',          'E112', "Option name missing")
8571     call T(27, '&asdf + CONT(27)',      'E113', "Unknown option")
8573     Xpath 134217728                             " X: 134217728
8575     let expected = ""
8576         \ . "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14"
8577         \ . "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25"
8578         \ . "T26M26T27M27"
8580     if taken != expected
8581         Xpath 268435456                         " X: 0
8582         Xout "'taken' is" taken "instead of" expected
8583         if substitute(taken, '\(.*\)T3M3x\(.*\)', '\1T3M3\2', "") == expected
8584             Xout "Is ++emsg_skip for var with expr_start non-NULL"
8585                 \ "in f_exists ok?"
8586         endif
8587     endif
8589     unlet! var caught taken expected
8590     call delete(WA_t5)
8591     unlet! WA_t5
8592     delfunction WA_t5
8594 endif
8596 Xcheck 134217728
8599 "-------------------------------------------------------------------------------
8600 " Test 79:  Throwing one of several errors for the same command             {{{1
8602 "           When several errors appear in a row (for instance during expression
8603 "           evaluation), the first as the most specific one is used when
8604 "           throwing an error exception.  If, however, a syntax error is
8605 "           detected afterwards, this one is used for the error exception.
8606 "           On a syntax error, the next command is not executed, on a normal
8607 "           error, however, it is (relevant only in a function without the
8608 "           "abort" flag).  v:errmsg is not set.
8610 "           If throwing error exceptions is configured off, v:errmsg is always
8611 "           set to the latest error message, that is, to the more general
8612 "           message or the syntax error, respectively.
8613 "-------------------------------------------------------------------------------
8615 XpathINIT
8617 XloopINIT 1 2
8619 function! NEXT(cmd)
8620     exec a:cmd . " | Xloop 1"
8621 endfunction
8623 call NEXT('echo novar')                         " X: 1 *  1  (checks nextcmd)
8624 XloopNEXT
8625 call NEXT('let novar #')                        " X: 0 *  2  (skips nextcmd)
8626 XloopNEXT
8627 call NEXT('unlet novar #')                      " X: 0 *  4  (skips nextcmd)
8628 XloopNEXT
8629 call NEXT('let {novar}')                        " X: 0 *  8  (skips nextcmd)
8630 XloopNEXT
8631 call NEXT('unlet{ novar}')                      " X: 0 * 16  (skips nextcmd)
8633 function! EXEC(cmd)
8634     exec a:cmd
8635 endfunction
8637 function! MATCH(expected, msg, enr, emsg)
8638     let msg = a:msg
8639     if a:enr == ""
8640         Xout "TODO: Add message number for:" a:emsg
8641         let msg = ":" . msg
8642     endif
8643     let english = v:lang == "C" || v:lang =~ '^[Ee]n'
8644     if msg !~ '^'.a:enr.':' || (english && msg !~ a:emsg)
8645         let match =  0
8646         if a:expected           " no match although expected
8647             if a:msg == ""
8648                 Xout "Message missing."
8649             else
8650                 let msg = escape(msg, '"')
8651                 Xout "Unexpected message:" msg
8652                 Xout "Expected:" a:enr . ": " . a:emsg
8653             endif
8654         endif
8655     else
8656         let match =  1
8657         if !a:expected          " match although not expected
8658             let msg = escape(msg, '"')
8659             Xout "Unexpected message:" msg
8660             Xout "Expected none."
8661         endif
8662     endif
8663     return match
8664 endfunction
8668     while 1                             " dummy loop
8669         try
8670             let v:errmsg = ""
8671             let caught = 0
8672             let thrmsg = ""
8673             call EXEC('echo novar')     " normal error
8674         catch /^Vim\((\a\+)\)\=:/
8675             let caught = 1
8676             let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
8677         finally
8678             Xpath 32                            " X: 32
8679             if !caught
8680                 if !$VIMNOERRTHROW
8681                     Xpath 64                    " X: 0
8682                 endif
8683             elseif !MATCH(1, thrmsg, 'E121', "Undefined variable")
8684             \ || v:errmsg != ""
8685                 Xpath 128                       " X: 0
8686             endif
8687             if !caught && !MATCH(1, v:errmsg, 'E15', "Invalid expression")
8688                 Xpath 256                       " X: 0
8689             endif
8690             break                       " discard error if $VIMNOERRTHROW == 1
8691         endtry
8692     endwhile
8694     Xpath 512                                   " X: 512
8695     let cmd = "let"
8696     XloopINIT 1024 32
8697     while cmd != ""
8698         try
8699             let v:errmsg = ""
8700             let caught = 0
8701             let thrmsg = ""
8702             call EXEC(cmd . ' novar #')         " normal plus syntax error
8703         catch /^Vim\((\a\+)\)\=:/
8704             let caught = 1
8705             let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
8706         finally
8707             Xloop 1                             " X: 1024 * (1 + 32)
8708             if !caught
8709                 if !$VIMNOERRTHROW
8710                     Xloop 2                     " X: 0
8711                 endif
8712             else
8713                 if cmd == "let"
8714                     let match = MATCH(0, thrmsg, 'E106', "Unknown variable")
8715                 elseif cmd == "unlet"
8716                     let match = MATCH(0, thrmsg, 'E108', "No such variable")
8717                 endif
8718                 if match                                        " normal error
8719                     Xloop 4                     " X: 0
8720                 endif
8721                 if !MATCH(1, thrmsg, 'E488', "Trailing characters")
8722                 \|| v:errmsg != ""
8723                                                                 " syntax error
8724                     Xloop 8                     " X: 0
8725                 endif
8726             endif
8727             if !caught && !MATCH(1, v:errmsg, 'E488', "Trailing characters")
8728                                                                 " last error
8729                 Xloop 16                        " X: 0
8730             endif
8731             if cmd == "let"
8732                 let cmd = "unlet"
8733             else
8734                 let cmd = ""
8735             endif
8736             XloopNEXT
8737             continue                    " discard error if $VIMNOERRTHROW == 1
8738         endtry
8739     endwhile
8741     Xpath 1048576                               " X: 1048576
8742     let cmd = "let"
8743     XloopINIT 2097152 32
8744     while cmd != ""
8745         try
8746             let v:errmsg = ""
8747             let caught = 0
8748             let thrmsg = ""
8749             call EXEC(cmd . ' {novar}')         " normal plus syntax error
8750         catch /^Vim\((\a\+)\)\=:/
8751             let caught = 1
8752             let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
8753         finally
8754             Xloop 1                             " X: 2097152 * (1 + 32)
8755             if !caught
8756                 if !$VIMNOERRTHROW
8757                     Xloop 2                     " X: 0
8758                 endif
8759             else
8760                 if MATCH(0, thrmsg, 'E121', "Undefined variable") " normal error
8761                     Xloop 4                     " X: 0
8762                 endif
8763                 if !MATCH(1, thrmsg, 'E475', 'Invalid argument\>')
8764                 \ || v:errmsg != ""                               " syntax error
8765                     Xloop 8                     " X: 0
8766                 endif
8767             endif
8768             if !caught && !MATCH(1, v:errmsg, 'E475', 'Invalid argument\>')
8769                                                                 " last error
8770                 Xloop 16                        " X: 0
8771             endif
8772             if cmd == "let"
8773                 let cmd = "unlet"
8774             else
8775                 let cmd = ""
8776             endif
8777             XloopNEXT
8778             continue                    " discard error if $VIMNOERRTHROW == 1
8779         endtry
8780     endwhile
8782 catch /.*/
8783     " The Xpath command does not accept 2^31 (negative); add explicitly:
8784     let Xpath = Xpath + 2147483648              " X: 0
8785     Xout v:exception "in" v:throwpoint
8786 endtry
8788 unlet! next_command thrmsg match
8789 delfunction NEXT
8790 delfunction EXEC
8791 delfunction MATCH
8793 Xcheck 70288929
8796 "-------------------------------------------------------------------------------
8797 " Test 80:  Syntax error in expression for illegal :elseif                  {{{1
8799 "           If there is a syntax error in the expression after an illegal
8800 "           :elseif, an error message is given (or an error exception thrown)
8801 "           for the illegal :elseif rather than the expression error.
8802 "-------------------------------------------------------------------------------
8804 XpathINIT
8806 function! MSG(enr, emsg)
8807     let english = v:lang == "C" || v:lang =~ '^[Ee]n'
8808     if a:enr == ""
8809         Xout "TODO: Add message number for:" a:emsg
8810         let v:errmsg = ":" . v:errmsg
8811     endif
8812     let match = 1
8813     if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
8814         let match = 0
8815         if v:errmsg == ""
8816             Xout "Message missing."
8817         else
8818             let v:errmsg = escape(v:errmsg, '"')
8819             Xout "Unexpected message:" v:errmsg
8820         endif
8821     endif
8822     return match
8823 endfunction
8825 let v:errmsg = ""
8826 if 0
8827 else
8828 elseif 1 ||| 2
8829 endif
8830 Xpath 1                                         " X: 1
8831 if !MSG('E584', ":elseif after :else")
8832     Xpath 2                                     " X: 0
8833 endif
8835 let v:errmsg = ""
8836 if 1
8837 else
8838 elseif 1 ||| 2
8839 endif
8840 Xpath 4                                         " X: 4
8841 if !MSG('E584', ":elseif after :else")
8842     Xpath 8                                     " X: 0
8843 endif
8845 let v:errmsg = ""
8846 elseif 1 ||| 2
8847 Xpath 16                                        " X: 16
8848 if !MSG('E582', ":elseif without :if")
8849     Xpath 32                                    " X: 0
8850 endif
8852 let v:errmsg = ""
8853 while 1
8854     elseif 1 ||| 2
8855 endwhile
8856 Xpath 64                                        " X: 64
8857 if !MSG('E582', ":elseif without :if")
8858     Xpath 128                                   " X: 0
8859 endif
8861 while 1
8862     try
8863         try
8864             let v:errmsg = ""
8865             let caught = 0
8866             if 0
8867             else
8868             elseif 1 ||| 2
8869             endif
8870         catch /^Vim\((\a\+)\)\=:/
8871             let caught = 1
8872             let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
8873         finally
8874             Xpath 256                           " X: 256
8875             if !caught && !$VIMNOERRTHROW
8876                 Xpath 512                       " X: 0
8877             endif
8878             if !MSG('E584', ":elseif after :else")
8879                 Xpath 1024                      " X: 0
8880             endif
8881         endtry
8882     catch /.*/
8883         Xpath 2048                              " X: 0
8884         Xout v:exception "in" v:throwpoint
8885     finally
8886         break           " discard error for $VIMNOERRTHROW
8887     endtry
8888 endwhile
8890 while 1
8891     try
8892         try
8893             let v:errmsg = ""
8894             let caught = 0
8895             if 1
8896             else
8897             elseif 1 ||| 2
8898             endif
8899         catch /^Vim\((\a\+)\)\=:/
8900             let caught = 1
8901             let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
8902         finally
8903             Xpath 4096                          " X: 4096
8904             if !caught && !$VIMNOERRTHROW
8905                 Xpath 8192                      " X: 0
8906             endif
8907             if !MSG('E584', ":elseif after :else")
8908                 Xpath 16384                     " X: 0
8909             endif
8910         endtry
8911     catch /.*/
8912         Xpath 32768                             " X: 0
8913         Xout v:exception "in" v:throwpoint
8914     finally
8915         break           " discard error for $VIMNOERRTHROW
8916     endtry
8917 endwhile
8919 while 1
8920     try
8921         try
8922             let v:errmsg = ""
8923             let caught = 0
8924             elseif 1 ||| 2
8925         catch /^Vim\((\a\+)\)\=:/
8926             let caught = 1
8927             let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
8928         finally
8929             Xpath 65536                         " X: 65536
8930             if !caught && !$VIMNOERRTHROW
8931                 Xpath 131072                    " X: 0
8932             endif
8933             if !MSG('E582', ":elseif without :if")
8934                 Xpath 262144                    " X: 0
8935             endif
8936         endtry
8937     catch /.*/
8938         Xpath 524288                            " X: 0
8939         Xout v:exception "in" v:throwpoint
8940     finally
8941         break           " discard error for $VIMNOERRTHROW
8942     endtry
8943 endwhile
8945 while 1
8946     try
8947         try
8948             let v:errmsg = ""
8949             let caught = 0
8950             while 1
8951                 elseif 1 ||| 2
8952             endwhile
8953         catch /^Vim\((\a\+)\)\=:/
8954             let caught = 1
8955             let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
8956         finally
8957             Xpath 1048576                       " X: 1048576
8958             if !caught && !$VIMNOERRTHROW
8959                 Xpath 2097152                   " X: 0
8960             endif
8961             if !MSG('E582', ":elseif without :if")
8962                 Xpath 4194304                   " X: 0
8963             endif
8964         endtry
8965     catch /.*/
8966         Xpath 8388608                           " X: 0
8967         Xout v:exception "in" v:throwpoint
8968     finally
8969         break           " discard error for $VIMNOERRTHROW
8970     endtry
8971 endwhile
8973 Xpath 16777216                                  " X: 16777216
8975 unlet! caught
8976 delfunction MSG
8978 Xcheck 17895765
8981 "-------------------------------------------------------------------------------
8982 " Test 81:  Discarding exceptions after an error or interrupt               {{{1
8984 "           When an exception is thrown from inside a :try conditional without
8985 "           :catch and :finally clauses and an error or interrupt occurs before
8986 "           the :endtry is reached, the exception is discarded.
8987 "-------------------------------------------------------------------------------
8989 XpathINIT
8991 if ExtraVim()
8992     try
8993         Xpath 1                                 " X: 1
8994         try
8995             Xpath 2                             " X: 2
8996             throw "arrgh"
8997             Xpath 4                             " X: 0
8998 "           if 1
8999                 Xpath 8                         " X: 0
9000             " error after :throw: missing :endif
9001         endtry
9002         Xpath 16                                " X: 0
9003     catch /arrgh/
9004         Xpath 32                                " X: 0
9005     endtry
9006     Xpath 64                                    " X: 0
9007 endif
9009 if ExtraVim()
9010     try
9011         Xpath 128                               " X: 128
9012         try
9013             Xpath 256                           " X: 256
9014             throw "arrgh"
9015             Xpath 512                           " X: 0
9016         endtry          " INTERRUPT
9017         Xpath 1024                              " X: 0
9018     catch /arrgh/
9019         Xpath 2048                              " X: 0
9020     endtry
9021     Xpath 4096                                  " X: 0
9022 endif
9024 Xcheck 387
9027 "-------------------------------------------------------------------------------
9028 " Test 82:  Ignoring :catch clauses after an error or interrupt             {{{1
9030 "           When an exception is thrown and an error or interrupt occurs before
9031 "           the matching :catch clause is reached, the exception is discarded
9032 "           and the :catch clause is ignored (also for the error or interrupt
9033 "           exception being thrown then).
9034 "-------------------------------------------------------------------------------
9036 XpathINIT
9038 if ExtraVim()
9039     try
9040         try
9041             Xpath 1                             " X: 1
9042             throw "arrgh"
9043             Xpath 2                             " X: 0
9044 "           if 1
9045                 Xpath 4                         " X: 0
9046                 " error after :throw: missing :endif
9047         catch /.*/
9048             Xpath 8                             " X: 0
9049             Xout v:exception "in" ExtraVimThrowpoint()
9050         catch /.*/
9051             Xpath 16                            " X: 0
9052             Xout v:exception "in" ExtraVimThrowpoint()
9053         endtry
9054         Xpath 32                                " X: 0
9055     catch /arrgh/
9056         Xpath 64                                " X: 0
9057     endtry
9058     Xpath 128                                   " X: 0
9059 endif
9061 if ExtraVim()
9062     function! E()
9063         try
9064             try
9065                 Xpath 256                       " X: 256
9066                 throw "arrgh"
9067                 Xpath 512                       " X: 0
9068 "               if 1
9069                     Xpath 1024                  " X: 0
9070                     " error after :throw: missing :endif
9071             catch /.*/
9072                 Xpath 2048                      " X: 0
9073                 Xout v:exception "in" ExtraVimThrowpoint()
9074             catch /.*/
9075                 Xpath 4096                      " X: 0
9076                 Xout v:exception "in" ExtraVimThrowpoint()
9077             endtry
9078             Xpath 8192                          " X: 0
9079         catch /arrgh/
9080             Xpath 16384                         " X: 0
9081         endtry
9082     endfunction
9084     call E()
9085     Xpath 32768                                 " X: 0
9086 endif
9088 if ExtraVim()
9089     try
9090         try
9091             Xpath 65536                         " X: 65536
9092             throw "arrgh"
9093             Xpath 131072                        " X: 0
9094         catch /.*/      "INTERRUPT
9095             Xpath 262144                        " X: 0
9096             Xout v:exception "in" ExtraVimThrowpoint()
9097         catch /.*/
9098             Xpath 524288                        " X: 0
9099             Xout v:exception "in" ExtraVimThrowpoint()
9100         endtry
9101         Xpath 1048576                           " X: 0
9102     catch /arrgh/
9103         Xpath 2097152                           " X: 0
9104     endtry
9105     Xpath 4194304                               " X: 0
9106 endif
9108 if ExtraVim()
9109     function I()
9110         try
9111             try
9112                 Xpath 8388608                   " X: 8388608
9113                 throw "arrgh"
9114                 Xpath 16777216                  " X: 0
9115             catch /.*/  "INTERRUPT
9116                 Xpath 33554432                  " X: 0
9117                 Xout v:exception "in" ExtraVimThrowpoint()
9118             catch /.*/
9119                 Xpath 67108864                  " X: 0
9120                 Xout v:exception "in" ExtraVimThrowpoint()
9121             endtry
9122             Xpath 134217728                     " X: 0
9123         catch /arrgh/
9124             Xpath 268435456                     " X: 0
9125         endtry
9126     endfunction
9128     call I()
9129     Xpath 536870912                             " X: 0
9130 endif
9132 Xcheck 8454401
9135 "-------------------------------------------------------------------------------
9136 " Test 83:  Executing :finally clauses after an error or interrupt          {{{1
9138 "           When an exception is thrown and an error or interrupt occurs before
9139 "           the :finally of the innermost :try is reached, the exception is
9140 "           discarded and the :finally clause is executed.
9141 "-------------------------------------------------------------------------------
9143 XpathINIT
9145 if ExtraVim()
9146     try
9147         Xpath 1                                 " X: 1
9148         try
9149             Xpath 2                             " X: 2
9150             throw "arrgh"
9151             Xpath 4                             " X: 0
9152 "           if 1
9153                 Xpath 8                         " X: 0
9154             " error after :throw: missing :endif
9155         finally
9156             Xpath 16                            " X: 16
9157         endtry
9158         Xpath 32                                " X: 0
9159     catch /arrgh/
9160         Xpath 64                                " X: 0
9161     endtry
9162     Xpath 128                                   " X: 0
9163 endif
9165 if ExtraVim()
9166     try
9167         Xpath 256                               " X: 256
9168         try
9169             Xpath 512                           " X: 512
9170             throw "arrgh"
9171             Xpath 1024                          " X: 0
9172         finally         "INTERRUPT
9173             Xpath 2048                          " X: 2048
9174         endtry
9175         Xpath 4096                              " X: 0
9176     catch /arrgh/
9177         Xpath 8192                              " X: 0
9178     endtry
9179     Xpath 16384                                 " X: 0
9180 endif
9182 Xcheck 2835
9185 "-------------------------------------------------------------------------------
9186 " Test 84:  Exceptions in autocommand sequences.                            {{{1
9188 "           When an exception occurs in a sequence of autocommands for
9189 "           a specific event, the rest of the sequence is not executed.  The
9190 "           command that triggered the autocommand execution aborts, and the
9191 "           exception is propagated to the caller.
9193 "           For the FuncUndefined event under a function call expression or
9194 "           :call command, the function is not executed, even when it has
9195 "           been defined by the autocommands before the exception occurred.
9196 "-------------------------------------------------------------------------------
9198 XpathINIT
9200 if ExtraVim()
9202     function! INT()
9203         "INTERRUPT
9204         let dummy = 0
9205     endfunction
9207     aug TMP
9208         autocmd!
9210         autocmd User x1 Xpath 1                 " X: 1
9211         autocmd User x1 throw "x1"
9212         autocmd User x1 Xpath 2                 " X: 0
9214         autocmd User x2 Xpath 4                 " X: 4
9215         autocmd User x2 asdf
9216         autocmd User x2 Xpath 8                 " X: 0
9218         autocmd User x3 Xpath 16                " X: 16
9219         autocmd User x3 call INT()
9220         autocmd User x3 Xpath 32                " X: 0
9222         autocmd FuncUndefined U1 function! U1()
9223         autocmd FuncUndefined U1     Xpath 64   " X: 0
9224         autocmd FuncUndefined U1 endfunction
9225         autocmd FuncUndefined U1 Xpath 128      " X: 128
9226         autocmd FuncUndefined U1 throw "U1"
9227         autocmd FuncUndefined U1 Xpath 256      " X: 0
9229         autocmd FuncUndefined U2 function! U2()
9230         autocmd FuncUndefined U2     Xpath 512  " X: 0
9231         autocmd FuncUndefined U2 endfunction
9232         autocmd FuncUndefined U2 Xpath 1024     " X: 1024
9233         autocmd FuncUndefined U2 ASDF
9234         autocmd FuncUndefined U2 Xpath 2048     " X: 0
9236         autocmd FuncUndefined U3 function! U3()
9237         autocmd FuncUndefined U3     Xpath 4096 " X: 0
9238         autocmd FuncUndefined U3 endfunction
9239         autocmd FuncUndefined U3 Xpath 8192     " X: 8192
9240         autocmd FuncUndefined U3 call INT()
9241         autocmd FuncUndefined U3 Xpath 16384    " X: 0
9242     aug END
9244     try
9245         try
9246             Xpath 32768                         " X: 32768
9247             doautocmd User x1
9248         catch /x1/
9249             Xpath 65536                         " X: 65536
9250         endtry
9252         while 1
9253             try
9254                 Xpath 131072                    " X: 131072
9255                 let caught = 0
9256                 doautocmd User x2
9257             catch /asdf/
9258                 let caught = 1
9259             finally
9260                 Xpath 262144                    " X: 262144
9261                 if !caught && !$VIMNOERRTHROW
9262                     Xpath 524288                " X: 0
9263                     " Propagate uncaught error exception,
9264                 else
9265                     " ... but break loop for caught error exception,
9266                     " or discard error and break loop if $VIMNOERRTHROW
9267                     break
9268                 endif
9269             endtry
9270         endwhile
9272         while 1
9273             try
9274                 Xpath 1048576                   " X: 1048576
9275                 let caught = 0
9276                 doautocmd User x3
9277             catch /Vim:Interrupt/
9278                 let caught = 1
9279             finally
9280                 Xpath 2097152                   " X: 2097152
9281                 if !caught && !$VIMNOINTTHROW
9282                     Xpath 4194304               " X: 0
9283                     " Propagate uncaught interrupt exception,
9284                 else
9285                     " ... but break loop for caught interrupt exception,
9286                     " or discard interrupt and break loop if $VIMNOINTTHROW
9287                     break
9288                 endif
9289             endtry
9290         endwhile
9292         if exists("*U1") | delfunction U1 | endif
9293         if exists("*U2") | delfunction U2 | endif
9294         if exists("*U3") | delfunction U3 | endif
9296         try
9297             Xpath 8388608                       " X: 8388608
9298             call U1()
9299         catch /U1/
9300             Xpath 16777216                      " X: 16777216
9301         endtry
9303         while 1
9304             try
9305                 Xpath 33554432                  " X: 33554432
9306                 let caught = 0
9307                 call U2()
9308             catch /ASDF/
9309                 let caught = 1
9310             finally
9311                 Xpath 67108864                  " X: 67108864
9312                 if !caught && !$VIMNOERRTHROW
9313                     Xpath 134217728             " X: 0
9314                     " Propagate uncaught error exception,
9315                 else
9316                     " ... but break loop for caught error exception,
9317                     " or discard error and break loop if $VIMNOERRTHROW
9318                     break
9319                 endif
9320             endtry
9321         endwhile
9323         while 1
9324             try
9325                 Xpath 268435456                 " X: 268435456
9326                 let caught = 0
9327                 call U3()
9328             catch /Vim:Interrupt/
9329                 let caught = 1
9330             finally
9331                 Xpath 536870912                 " X: 536870912
9332                 if !caught && !$VIMNOINTTHROW
9333                     Xpath 1073741824            " X: 0
9334                     " Propagate uncaught interrupt exception,
9335                 else
9336                     " ... but break loop for caught interrupt exception,
9337                     " or discard interrupt and break loop if $VIMNOINTTHROW
9338                     break
9339                 endif
9340             endtry
9341         endwhile
9342     catch /.*/
9343         " The Xpath command does not accept 2^31 (negative); display explicitly:
9344         exec "!echo 2147483648 >>" . g:ExtraVimResult
9345         Xout "Caught" v:exception "in" v:throwpoint
9346     endtry
9348     unlet caught
9349     delfunction INT
9350     delfunction U1
9351     delfunction U2
9352     delfunction U3
9353     au! TMP
9354     aug! TMP
9355 endif
9357 Xcheck 934782101
9360 "-------------------------------------------------------------------------------
9361 " Test 85:  Error exceptions in autocommands for I/O command events         {{{1
9363 "           When an I/O command is inside :try/:endtry, autocommands to be
9364 "           executed after it should be skipped on an error (exception) in the
9365 "           command itself or in autocommands to be executed before the command.
9366 "           In the latter case, the I/O command should not be executed either.
9367 "           Example 1: BufWritePre, :write, BufWritePost
9368 "           Example 2: FileReadPre, :read, FileReadPost.
9369 "-------------------------------------------------------------------------------
9371 XpathINIT
9373 function! MSG(enr, emsg)
9374     let english = v:lang == "C" || v:lang =~ '^[Ee]n'
9375     if a:enr == ""
9376         Xout "TODO: Add message number for:" a:emsg
9377         let v:errmsg = ":" . v:errmsg
9378     endif
9379     let match = 1
9380     if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
9381         let match = 0
9382         if v:errmsg == ""
9383             Xout "Message missing."
9384         else
9385             let v:errmsg = escape(v:errmsg, '"')
9386             Xout "Unexpected message:" v:errmsg
9387         endif
9388     endif
9389     return match
9390 endfunction
9392 " Remove the autocommands for the events specified as arguments in all used
9393 " autogroups.
9394 function! Delete_autocommands(...)
9395     let augfile = tempname()
9396     while 1
9397         try
9398             exec "redir >" . augfile
9399             aug
9400             redir END
9401             exec "edit" augfile
9402             g/^$/d
9403             norm G$
9404             let wrap = "w"
9405             while search('\%(  \|^\)\@<=.\{-}\%(  \)\@=', wrap) > 0
9406                 let wrap = "W"
9407                 exec "norm y/  \n"
9408                 let argno = 1
9409                 while argno <= a:0
9410                     exec "au!" escape(@", " ") a:{argno}
9411                     let argno = argno + 1
9412                 endwhile
9413             endwhile
9414         catch /.*/
9415         finally
9416             bwipeout!
9417             call delete(augfile)
9418             break               " discard errors for $VIMNOERRTHROW
9419         endtry
9420     endwhile
9421 endfunction
9423 call Delete_autocommands("BufWritePre", "BufWritePost")
9425 while 1
9426     try
9427         try
9428             let post = 0
9429             aug TMP
9430                 au! BufWritePost * let post = 1
9431             aug END
9432             let caught = 0
9433             write /n/o/n/e/x/i/s/t/e/n/t
9434         catch /^Vim(write):/
9435             let caught = 1
9436             let v:errmsg = substitute(v:exception, '^Vim(write):', '', "")
9437         finally
9438             Xpath 1                             " X: 1
9439             if !caught && !$VIMNOERRTHROW
9440                 Xpath 2                         " X: 0
9441             endif
9442             let v:errmsg = substitute(v:errmsg, '^"/n/o/n/e/x/i/s/t/e/n/t" ',
9443                 \ '', "")
9444             if !MSG('E212', "Can't open file for writing")
9445                 Xpath 4                         " X: 0
9446             endif
9447             if post
9448                 Xpath 8                         " X: 0
9449                 Xout "BufWritePost commands executed after write error"
9450             endif
9451             au! TMP
9452             aug! TMP
9453         endtry
9454     catch /.*/
9455         Xpath 16                                " X: 0
9456         Xout v:exception "in" v:throwpoint
9457     finally
9458         break           " discard error for $VIMNOERRTHROW
9459     endtry
9460 endwhile
9462 while 1
9463     try
9464         try
9465             let post = 0
9466             aug TMP
9467                 au! BufWritePre  * asdf
9468                 au! BufWritePost * let post = 1
9469             aug END
9470             let tmpfile = tempname()
9471             let caught = 0
9472             exec "write" tmpfile
9473         catch /^Vim\((write)\)\=:/
9474             let caught = 1
9475             let v:errmsg = substitute(v:exception, '^Vim\((write)\)\=:', '', "")
9476         finally
9477             Xpath 32                            " X: 32
9478             if !caught && !$VIMNOERRTHROW
9479                 Xpath 64                        " X: 0
9480             endif
9481             let v:errmsg = substitute(v:errmsg, '^"'.tmpfile.'" ', '', "")
9482             if !MSG('E492', "Not an editor command")
9483                 Xpath 128                       " X: 0
9484             endif
9485             if filereadable(tmpfile)
9486                 Xpath 256                       " X: 0
9487                 Xout ":write command not suppressed after BufWritePre error"
9488             endif
9489             if post
9490                 Xpath 512                       " X: 0
9491                 Xout "BufWritePost commands executed after BufWritePre error"
9492             endif
9493             au! TMP
9494             aug! TMP
9495         endtry
9496     catch /.*/
9497         Xpath 1024                              " X: 0
9498         Xout v:exception "in" v:throwpoint
9499     finally
9500         break           " discard error for $VIMNOERRTHROW
9501     endtry
9502 endwhile
9504 call delete(tmpfile)
9506 call Delete_autocommands("BufWritePre", "BufWritePost",
9507     \ "BufReadPre", "BufReadPost", "FileReadPre", "FileReadPost")
9509 while 1
9510     try
9511         try
9512             let post = 0
9513             aug TMP
9514                 au! FileReadPost * let post = 1
9515             aug END
9516             let caught = 0
9517             read /n/o/n/e/x/i/s/t/e/n/t
9518         catch /^Vim(read):/
9519             let caught = 1
9520             let v:errmsg = substitute(v:exception, '^Vim(read):', '', "")
9521         finally
9522             Xpath 2048                          " X: 2048
9523             if !caught && !$VIMNOERRTHROW
9524                 Xpath 4096                      " X: 0
9525             endif
9526             let v:errmsg = substitute(v:errmsg, ' /n/o/n/e/x/i/s/t/e/n/t$',
9527                 \ '', "")
9528             if !MSG('E484', "Can't open file")
9529                 Xpath 8192                      " X: 0
9530             endif
9531             if post
9532                 Xpath 16384                     " X: 0
9533                 Xout "FileReadPost commands executed after write error"
9534             endif
9535             au! TMP
9536             aug! TMP
9537         endtry
9538     catch /.*/
9539         Xpath 32768                             " X: 0
9540         Xout v:exception "in" v:throwpoint
9541     finally
9542         break           " discard error for $VIMNOERRTHROW
9543     endtry
9544 endwhile
9546 while 1
9547     try
9548         let infile = tempname()
9549         let tmpfile = tempname()
9550         exec "!echo XYZ >" . infile
9551         exec "edit" tmpfile
9552         try
9553             Xpath 65536                         " X: 65536
9554             try
9555                 let post = 0
9556                 aug TMP
9557                     au! FileReadPre  * asdf
9558                     au! FileReadPost * let post = 1
9559                 aug END
9560                 let caught = 0
9561                 exec "0read" infile
9562             catch /^Vim\((read)\)\=:/
9563                 let caught = 1
9564                 let v:errmsg = substitute(v:exception, '^Vim\((read)\)\=:', '',
9565                     \ "")
9566             finally
9567                 Xpath 131072                    " X: 131072
9568                 if !caught && !$VIMNOERRTHROW
9569                     Xpath 262144                " X: 0
9570                 endif
9571                 let v:errmsg = substitute(v:errmsg, ' '.infile.'$', '', "")
9572                 if !MSG('E492', "Not an editor command")
9573                     Xpath 524288                " X: 0
9574                 endif
9575                 if getline("1") == "XYZ"
9576                     Xpath 1048576               " X: 0
9577                     Xout ":read command not suppressed after FileReadPre error"
9578                 endif
9579                 if post
9580                     Xpath 2097152               " X: 0
9581                     Xout "FileReadPost commands executed after " .
9582                         \ "FileReadPre error"
9583                 endif
9584                 au! TMP
9585                 aug! TMP
9586             endtry
9587         finally
9588             bwipeout!
9589         endtry
9590     catch /.*/
9591         Xpath 4194304                           " X: 0
9592         Xout v:exception "in" v:throwpoint
9593     finally
9594         break           " discard error for $VIMNOERRTHROW
9595     endtry
9596 endwhile
9598 call delete(infile)
9599 call delete(tmpfile)
9600 unlet! caught post infile tmpfile
9601 delfunction MSG
9602 delfunction Delete_autocommands
9604 Xcheck 198689
9607 "-------------------------------------------------------------------------------
9608 " Test 86:  $VIMNOERRTHROW and $VIMNOINTTHROW support                       {{{1
9610 "           It is possible to configure Vim for throwing exceptions on error
9611 "           or interrupt, controlled by variables $VIMNOERRTHROW and
9612 "           $VIMNOINTTHROW.  This is just for increasing the number of tests.
9613 "           All tests here should run for all four combinations of setting
9614 "           these variables to 0 or 1.  The variables are intended for the
9615 "           development phase only.  In the final release, Vim should be
9616 "           configured to always use error and interrupt exceptions.
9618 "           The test result is "OK",
9620 "               - if the $VIMNOERRTHROW and the $VIMNOINTTHROW control are not
9621 "                 configured and exceptions are thrown on error and on
9622 "                 interrupt.
9624 "               - if the $VIMNOERRTHROW or the $VIMNOINTTHROW control is
9625 "                 configured and works as intended.
9627 "           What actually happens, is shown in the test output.
9629 "           Otherwise, the test result is "FAIL", and the test output describes
9630 "           the problem.
9632 " IMPORTANT:  This must be the last test because it sets $VIMNOERRTHROW and
9633 "             $VIMNOINTTHROW.
9634 "-------------------------------------------------------------------------------
9636 XpathINIT
9638 if ExtraVim()
9640     function! ThrowOnError()
9641         XloopNEXT
9642         let caught = 0
9643         try
9644             Xloop 1                             " X: 1 + 8 + 64
9645             asdf
9646         catch /.*/
9647             let caught = 1      " error exception caught
9648         finally
9649             Xloop 2                             " X: 2 + 16 + 128
9650             return caught       " discard aborting error
9651         endtry
9652         Xloop 4                                 " X: 0
9653     endfunction
9655     let quits_skipped = 0
9657     function! ThrowOnInterrupt()
9658         XloopNEXT
9659         let caught = 0
9660         try
9661             Xloop 1                             " X: (1 + 8 + 64) * 512
9662             "INTERRUPT3
9663             let dummy = 0
9664             let g:quits_skipped = g:quits_skipped + 1
9665         catch /.*/
9666             let caught = 1      " interrupt exception caught
9667         finally
9668             Xloop 2                             " X: (2 + 16 + 128) * 512
9669             return caught       " discard interrupt
9670         endtry
9671         Xloop 4                                 " X: 0
9672     endfunction
9674     function! CheckThrow(Type)
9675         execute 'return ThrowOn' . a:Type . '()'
9676     endfunction
9678     function! CheckConfiguration(type)      " type is "error" or "interrupt"
9680         let type = a:type
9681         let Type = substitute(type, '.*', '\u&', "")
9682         let VAR = '$VIMNO' . substitute(type, '\(...\).*', '\U\1', "") . 'THROW'
9684         if type == "error"
9685             XloopINIT! 1 8
9686         elseif type == "interrupt"
9687             XloopINIT! 512 8
9688         endif
9690         exec 'let requested_for_tests = exists(VAR) && ' . VAR . ' == 0'
9691         exec 'let suppressed_for_tests = ' . VAR . ' != 0'
9692         let used_in_tests = CheckThrow(Type)
9694         exec 'let ' . VAR . ' = 0'
9695         let request_works = CheckThrow(Type)
9697         exec 'let ' . VAR . ' = 1'
9698         let suppress_works = !CheckThrow(Type)
9700         if type == "error"
9701             XloopINIT! 262144 8
9702         elseif type == "interrupt"
9703             XloopINIT! 2097152 8
9705             if g:quits_skipped != 0
9706                 Xloop 1                         " X: 0*2097152
9707                 Xout "Test environment error.  Interrupt breakpoints skipped: "
9708                     \ . g:quits_skipped . ".\n"
9709                     \ . "Cannot check whether interrupt exceptions are thrown."
9710                 return
9711             endif
9712         endif
9714         let failure =
9715             \ !suppressed_for_tests && !used_in_tests
9716             \ || !request_works
9718         let contradiction =
9719             \ used_in_tests
9720                 \ ? suppressed_for_tests && !request_works
9721                 \ : !suppressed_for_tests
9723         if failure
9724             " Failure in configuration.
9725             Xloop 2                             " X: 0 * 2*  (262144 + 2097152)
9726         elseif contradiction
9727             " Failure in test logic.  Should not happen.
9728             Xloop 4                             " X: 0 * 4 * (262144 + 2097152)
9729         endif
9731         let var_control_configured =
9732             \ request_works != used_in_tests
9733             \ || suppress_works == used_in_tests
9735         let var_control_not_configured =
9736             \ requested_for_tests || suppressed_for_tests
9737                 \ ? request_works && !suppress_works
9738                 \ : request_works == used_in_tests
9739                     \ && suppress_works != used_in_tests
9741         let with = used_in_tests ? "with" : "without"
9743         let set = suppressed_for_tests ? "non-zero" :
9744             \ requested_for_tests ? "0" : "unset"
9746         let although = contradiction && !var_control_not_configured
9747             \ ? ",\nalthough "
9748             \ : ".\n"
9750         let output = "All tests were run " . with . " throwing exceptions on "
9751             \ . type . although
9753         if !var_control_not_configured
9754             let output = output . VAR . " was " . set . "."
9756             if !request_works && !requested_for_tests
9757                 let output = output .
9758                     \ "\n" . Type . " exceptions are not thrown when " . VAR .
9759                     \ " is\nset to 0."
9760             endif
9762             if !suppress_works && (!used_in_tests ||
9763             \ !request_works &&
9764             \ !requested_for_tests && !suppressed_for_tests)
9765                 let output = output .
9766                     \ "\n" . Type . " exceptions are thrown when " . VAR .
9767                     \ " is set to 1."
9768             endif
9770             if !failure && var_control_configured
9771                 let output = output .
9772                     \ "\nRun tests also with " . substitute(VAR, '^\$', '', "")
9773                     \ . "=" . used_in_tests . "."
9774                     \ . "\nThis is for testing in the development phase only."
9775                     \ . "  Remove the \n"
9776                     \ . VAR . " control in the final release."
9777             endif
9778         else
9779             let output = output .
9780                 \ "The " . VAR . " control is not configured."
9781         endif
9783         Xout output
9784     endfunction
9786     call CheckConfiguration("error")
9787     Xpath 16777216                              " X: 16777216
9788     call CheckConfiguration("interrupt")
9789     Xpath 33554432                              " X: 33554432
9790 endif
9792 Xcheck 50443995
9794 " IMPORTANT: No test should be added after this test because it changes
9795 "            $VIMNOERRTHROW and $VIMNOINTTHROW.
9798 "-------------------------------------------------------------------------------
9799 " Modelines                                                                 {{{1
9800 " vim: ts=8 sw=4 tw=80 fdm=marker
9801 " vim: fdt=substitute(substitute(foldtext(),\ '\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\ \\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\ '\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "")
9802 "-------------------------------------------------------------------------------