blob: 97088f01e80762d33319b92ac96f2b080c57fc53 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001" Vim script language tests
2" Author: Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com>
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01003" Last Change: 2019 Jan 13
Bram Moolenaar071d4272004-06-13 20:20:40 +00004
5"-------------------------------------------------------------------------------
6" Test environment {{{1
7"-------------------------------------------------------------------------------
8
9
10" Adding new tests easily. {{{2
11"
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").
15"
16" To get the abbreviations, execute the command
17"
18" :let test49_set_env = 1 | source test49.vim
19"
20" To get them always (from src/testdir), put a line
21"
22" au! BufRead test49.vim let test49_set_env = 1 | source test49.vim
23"
24" into the local .vimrc file in the src/testdir directory.
25"
26if exists("test49_set_env") && test49_set_env
27
28 " Automatic argument generation for the test environment commands.
29
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
37
38 function! Xcheck()
39 let g:Xsum=0
40 ?XpathINIT?,.call Xsum()
41 exec "norm A "
42 return g:Xsum
43 endfunction
44
45 iab Xcheck Xcheck<Space><C-R>=Xcheck()<CR><C-O>x
46
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
58
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
76
77 iab Xloop Xloop<Space><C-R>=Xloop()<CR><C-O>x
78
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
111
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
114
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
125
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
131
132 do BufEnter <sfile>
133
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
141
142endif
143
144
145" Commands for recording the execution path. {{{2
146"
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
Bram Moolenaarbc045ea2005-06-05 22:01:26 +0000150" execution of a loop. Permitted values are 2^0 to 2^30, so that 31 execution
Bram Moolenaar071d4272004-06-13 20:20:40 +0000151" points (multiply counted inside loops) can be tested.
152"
153" Note that the arguments of the following commands can be generated
154" automatically, see below.
155"
156" Usage: {{{3
157"
158" - Use XpathINIT at the beginning of the test.
159"
160" - Use Xpath to check if a line is executed.
161" Argument: power of 2 (decimal).
162"
163" - To check multiple execution of loops use Xloop for automatically
164" computing Xpath values:
165"
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.
174"
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).
182"
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.
188"
189" Nested loops are not supported.
190"
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>.
203"
204" - In order to add additional information to the test output file, use the
205" Xout command. Argument(s) like ":echo".
206"
207" Automatic argument generation: {{{3
208"
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.
214"
215" Implementation: {{{3
216" XpathINIT, Xpath, XloopINIT, Xloop, XloopNEXT, Xcheck, Xout.
217"
218" The variants for existing g:ExtraVimResult are needed when executing a script
219" in an extra Vim process, see ExtraVim below.
220
221" EXTRA_VIM_START - do not change or remove this line.
222
223com! XpathINIT let g:Xpath = 0
224
225if exists("g:ExtraVimResult")
226 com! -count -bar Xpath exec "!echo <count> >>" . g:ExtraVimResult
227else
228 com! -count -bar Xpath let g:Xpath = g:Xpath + <count>
229endif
230
231com! -count -nargs=1 -bang
232 \ XloopINIT let g:Xnext = <count> |
233 \ let g:Xfactor = <args> |
234 \ let g:Xskip = strlen("<bang>")
235
236if exists("g:ExtraVimResult")
237 com! -count=1 -bar Xloop exec "!echo " . (g:Xnext * <count>) . " >>" .
238 \ g:ExtraVimResult
239else
240 com! -count=1 -bar Xloop let g:Xpath = g:Xpath + g:Xnext * <count>
241endif
242
243com! XloopNEXT let g:Xnext = g:Xnext *
244 \ (g:Xskip ? 1 : g:Xfactor) |
245 \ let g:Xskip = 0
246
247let @r = ""
248let Xtest = 1
249com! -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
258
259if exists("g:ExtraVimResult")
Bram Moolenaarbc045ea2005-06-05 22:01:26 +0000260 com! -nargs=+ Xoutq exec "!echo @R:'" .
261 \ substitute(substitute(<q-args>,
262 \ "'", '&\\&&', "g"), "\n", "@NL@", "g")
263 \ . "' >>" . g:ExtraVimResult
Bram Moolenaar071d4272004-06-13 20:20:40 +0000264else
Bram Moolenaarbc045ea2005-06-05 22:01:26 +0000265 com! -nargs=+ Xoutq let @R = "--- Test " .
Bram Moolenaar071d4272004-06-13 20:20:40 +0000266 \ (g:Xtest<10?" ":g:Xtest<100?" ":"") .
Bram Moolenaarbc045ea2005-06-05 22:01:26 +0000267 \ g:Xtest . ": " . substitute(<q-args>,
268 \ "\n", "&\t ", "g") . "\n"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000269endif
Bram Moolenaarbc045ea2005-06-05 22:01:26 +0000270com! -nargs=+ Xout exec 'Xoutq' <args>
Bram Moolenaar071d4272004-06-13 20:20:40 +0000271
272" Switch off storing of lines for undoing changes. Speeds things up a little.
273set undolevels=-1
274
275" EXTRA_VIM_STOP - do not change or remove this line.
276
277
278" ExtraVim() - Run a script file in an extra Vim process. {{{2
279"
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.
284"
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).
293"
294" This function is only called in normal modus ("g:ExtraVimResult" undefined).
295"
296" Tests to be executed as an extra script should be written as follows:
297"
298" column 1 column 1
299" | |
300" v v
301"
302" XpathINIT XpathINIT
303" if ExtraVim() if ExtraVim()
304" ... " ...
305" ... " ...
306" endif endif
307" Xcheck <number> Xcheck <number>
308"
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.
313"
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.
316"
317let ExtraVimCount = 0
318let ExtraVimBase = expand("<sfile>")
319let ExtraVimTestEnv = ""
320"
Bram Moolenaar1e115362019-01-09 23:01:02 +0100321function ExtraVim(...)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000322 " Count how often this function is called.
323 let g:ExtraVimCount = g:ExtraVimCount + 1
324
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
329
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
346
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
353
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
360
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
366
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', "")
Bram Moolenaar071d4272004-06-13 20:20:40 +0000385 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 " .
Bram Moolenaare224ffa2006-03-01 00:01:28 +0000409 \ (line(".") - func_start) . " " .
Bram Moolenaar071d4272004-06-13 20:20:40 +0000410 \ 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
445
446 " Close the buffer for the script and create an (empty) resultfile.
447 bwipeout
448 let resultfile = tempname()
449 exec "!>" . resultfile
450
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
Bram Moolenaarbc045ea2005-06-05 22:01:26 +0000455 " continuation ("C" in 'cpo'). Add "nviminfo" to 'viminfo' to avoid
Bram Moolenaar071d4272004-06-13 20:20:40 +0000456 " 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
464
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
483
484 " Delete the extra script and the resultfile.
485 call delete(extra_script)
486 call delete(resultfile)
487
488 " Switch back to the buffer that was active when this function was entered.
489 exec "buffer" current_buffnr
490
491 " Return 0. This protects extra scripts from being run in the main Vim
492 " process.
493 return 0
494endfunction
495
496
497" ExtraVimThrowpoint() - Relative throwpoint in ExtraVim script {{{2
498"
Bram Moolenaarbc045ea2005-06-05 22:01:26 +0000499" Evaluates v:throwpoint and returns the throwpoint relative to the beginning of
Bram Moolenaar071d4272004-06-13 20:20:40 +0000500" an ExtraVim script as passed by ExtraVim() in ExtraVimBegin.
501"
502" EXTRA_VIM_START - do not change or remove this line.
Bram Moolenaar1e115362019-01-09 23:01:02 +0100503function ExtraVimThrowpoint()
Bram Moolenaar071d4272004-06-13 20:20:40 +0000504 if !exists("g:ExtraVimBegin")
505 Xout "ExtraVimThrowpoint() used outside ExtraVim() script."
506 return v:throwpoint
507 endif
508
509 if v:throwpoint =~ '^function\>'
510 return v:throwpoint
511 endif
512
513 return "line " .
514 \ (substitute(v:throwpoint, '.*, line ', '', "") - g:ExtraVimBegin) .
515 \ " of ExtraVim() script"
516endfunction
517" EXTRA_VIM_STOP - do not change or remove this line.
518
519
520" MakeScript() - Make a script file from a function. {{{2
521"
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.
528"
529" In order to execute a function specifying an INTERRUPT location (see ExtraVim)
530" as a script file, use ExecAsScript below.
531"
532" EXTRA_VIM_START - do not change or remove this line.
Bram Moolenaar1e115362019-01-09 23:01:02 +0100533function MakeScript(funcname, ...)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000534 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
558endfunction
559" EXTRA_VIM_STOP - do not change or remove this line.
560
561
562" ExecAsScript - Source a temporary script made from a function. {{{2
563"
564" Make a temporary script file from the function a:funcname, ":source" it, and
565" delete it afterwards.
566"
567" When inside ":if ExtraVim()", add a file breakpoint for each INTERRUPT
568" location specified in the function.
569"
570" EXTRA_VIM_START - do not change or remove this line.
Bram Moolenaar1e115362019-01-09 23:01:02 +0100571function ExecAsScript(funcname)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000572 " Make a script from the function passed as argument.
573 let script = MakeScript(a:funcname)
574
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
598
599 " Source and delete the script.
600 exec "source" script
601 call delete(script)
602endfunction
603
604com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
605" EXTRA_VIM_STOP - do not change or remove this line.
606
607
608" END_OF_TEST_ENVIRONMENT - do not change or remove this line.
609
610
Bram Moolenaarb544f3c2017-02-23 19:03:28 +0100611" Tests 1 to 15 were moved to test_vimscript.vim
Bram Moolenaara2cce862016-01-02 19:50:04 +0100612let Xtest = 16
Bram Moolenaar071d4272004-06-13 20:20:40 +0000613
614"-------------------------------------------------------------------------------
615" Test 16: Double :else or :elseif after :else {{{1
616"
617" Multiple :elses or an :elseif after an :else are forbidden.
618"-------------------------------------------------------------------------------
619
620XpathINIT
621
622function! F() abort
623 if 0
624 Xpath 1 " X: 0
625 else
626 Xpath 2 " X: 2
627 else " aborts function
628 Xpath 4 " X: 0
629 endif
630endfunction
631
632function! G() abort
633 if 0
634 Xpath 8 " X: 0
635 else
636 Xpath 16 " X: 16
637 elseif 1 " aborts function
638 Xpath 32 " X: 0
639 else
640 Xpath 64 " X: 0
641 endif
642endfunction
643
644function! H() abort
645 if 0
646 Xpath 128 " X: 0
647 elseif 0
648 Xpath 256 " X: 0
649 else
650 Xpath 512 " X: 512
651 else " aborts function
652 Xpath 1024 " X: 0
653 endif
654endfunction
655
656function! I() abort
657 if 0
658 Xpath 2048 " X: 0
659 elseif 0
660 Xpath 4096 " X: 0
661 else
662 Xpath 8192 " X: 8192
663 elseif 1 " aborts function
664 Xpath 16384 " X: 0
665 else
666 Xpath 32768 " X: 0
667 endif
668endfunction
669
670call F()
671call G()
672call H()
673call I()
674
675delfunction F
676delfunction G
677delfunction H
678delfunction I
679
680Xcheck 8722
681
682
683"-------------------------------------------------------------------------------
684" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1
685"
686" The :while/:endwhile takes precedence in nesting over an unclosed
687" :if or an unopened :endif.
688"-------------------------------------------------------------------------------
689
690XpathINIT
691
692function! MSG(enr, emsg)
693 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
694 if a:enr == ""
695 Xout "TODO: Add message number for:" a:emsg
696 let v:errmsg = ":" . v:errmsg
697 endif
698 let match = 1
699 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
700 let match = 0
701 if v:errmsg == ""
702 Xout "Message missing."
703 else
704 let v:errmsg = escape(v:errmsg, '"')
705 Xout "Unexpected message:" v:errmsg
706 endif
707 endif
708 return match
709endfunction
710
711let messages = ""
712
713" While loops inside a function are continued on error.
714function! F()
715 let v:errmsg = ""
716 XloopINIT 1 16
717 let loops = 3
718 while loops > 0
719 let loops = loops - 1 " 2: 1: 0:
720 Xloop 1 " X: 1 + 1*16 + 1*16*16
721 if (loops == 1)
722 Xloop 2 " X: 2*16
723 XloopNEXT
724 continue
725 elseif (loops == 0)
726 Xloop 4 " X: 4*16*16
727 break
728 elseif 1
729 Xloop 8 " X: 8
730 XloopNEXT
731 " endif missing!
732 endwhile " :endwhile after :if 1
733 Xpath 4096 " X: 16*16*16
734 if MSG('E171', "Missing :endif")
735 let g:messages = g:messages . "A"
736 endif
737
738 let v:errmsg = ""
739 XloopINIT! 8192 4
740 let loops = 2
741 while loops > 0 " 2: 1:
742 XloopNEXT
743 let loops = loops - 1
744 Xloop 1 " X: 8192 + 8192*4
745 if 0
746 Xloop 2 " X: 0
747 " endif missing
748 endwhile " :endwhile after :if 0
749 Xpath 131072 " X: 8192*4*4
750 if MSG('E171', "Missing :endif")
751 let g:messages = g:messages . "B"
752 endif
753
754 let v:errmsg = ""
755 XloopINIT 262144 4
756 let loops = 2
757 while loops > 0 " 2: 1:
758 let loops = loops - 1
759 Xloop 1 " X: 262144 + 262144 * 4
760 " if missing!
761 endif " :endif without :if in while
762 Xloop 2 " X: 524288 + 524288 * 4
763 XloopNEXT
764 endwhile
765 Xpath 4194304 " X: 262144*4*4
766 if MSG('E580', ":endif without :if")
767 let g:messages = g:messages . "C"
768 endif
769endfunction
770
771call F()
772
773" Error continuation outside a function is at the outermost :endwhile or :endif.
774let v:errmsg = ""
775XloopINIT! 8388608 4
776let loops = 2
777while loops > 0 " 2: 1:
778 XloopNEXT
779 let loops = loops - 1
780 Xloop 1 " X: 8388608 + 0 * 4
781 if 0
782 Xloop 2 " X: 0
783 " endif missing! Following :endwhile fails.
784endwhile | Xpath 134217728 " X: 0
785Xpath 268435456 " X: 2*8388608*4*4
786if MSG('E171', "Missing :endif")
787 let messages = g:messages . "D"
788endif
789
790if messages != "ABCD"
791 Xpath 536870912 " X: 0
792 Xout "messages is" messages "instead of ABCD"
793endif
794
795unlet loops messages
796delfunction F
797delfunction MSG
798
799Xcheck 285127993
800
801
802"-------------------------------------------------------------------------------
803" Test 18: Interrupt (Ctrl-C pressed) {{{1
804"
805" On an interrupt, the script processing is terminated immediately.
806"-------------------------------------------------------------------------------
807
808XpathINIT
809
810if ExtraVim()
811 if 1
812 Xpath 1 " X: 1
813 while 1
814 Xpath 2 " X: 2
815 if 1
816 Xpath 4 " X: 4
817 "INTERRUPT
818 Xpath 8 " X: 0
819 break
820 finish
821 endif | Xpath 16 " X: 0
822 Xpath 32 " X: 0
823 endwhile | Xpath 64 " X: 0
824 Xpath 128 " X: 0
825 endif | Xpath 256 " X: 0
826 Xpath 512 " X: 0
827endif
828
829if ExtraVim()
830 try
831 Xpath 1024 " X: 1024
832 "INTERRUPT
833 Xpath 2048 " X: 0
834 endtry | Xpath 4096 " X: 0
835 Xpath 8192 " X: 0
836endif
837
838if ExtraVim()
839 function! F()
840 if 1
841 Xpath 16384 " X: 16384
842 while 1
843 Xpath 32768 " X: 32768
844 if 1
845 Xpath 65536 " X: 65536
846 "INTERRUPT
847 Xpath 131072 " X: 0
848 break
849 return
850 endif | Xpath 262144 " X: 0
851 Xpath Xpath 524288 " X: 0
852 endwhile | Xpath 1048576 " X: 0
853 Xpath Xpath 2097152 " X: 0
854 endif | Xpath Xpath 4194304 " X: 0
855 Xpath Xpath 8388608 " X: 0
856 endfunction
857
858 call F() | Xpath 16777216 " X: 0
859 Xpath 33554432 " X: 0
860endif
861
862if ExtraVim()
863 function! G()
864 try
865 Xpath 67108864 " X: 67108864
866 "INTERRUPT
867 Xpath 134217728 " X: 0
868 endtry | Xpath 268435456 " X: 0
869 Xpath 536870912 " X: 0
870 endfunction
871
872 call G() | Xpath 1073741824 " X: 0
873 " The Xpath command does not accept 2^31 (negative); display explicitly:
874 exec "!echo 2147483648 >>" . g:ExtraVimResult
875 " X: 0
876endif
877
878Xcheck 67224583
879
880
881"-------------------------------------------------------------------------------
882" Test 19: Aborting on errors inside :try/:endtry {{{1
883"
884" An error in a command dynamically enclosed in a :try/:endtry region
885" aborts script processing immediately. It does not matter whether
886" the failing command is outside or inside a function and whether a
887" function has an "abort" attribute.
888"-------------------------------------------------------------------------------
889
890XpathINIT
891
892if ExtraVim()
893 function! F() abort
894 Xpath 1 " X: 1
895 asdf
896 Xpath 2 " X: 0
897 endfunction
898
899 try
900 Xpath 4 " X: 4
901 call F()
902 Xpath 8 " X: 0
903 endtry | Xpath 16 " X: 0
904 Xpath 32 " X: 0
905endif
906
907if ExtraVim()
908 function! G()
909 Xpath 64 " X: 64
910 asdf
911 Xpath 128 " X: 0
912 endfunction
913
914 try
915 Xpath 256 " X: 256
916 call G()
917 Xpath 512 " X: 0
918 endtry | Xpath 1024 " X: 0
919 Xpath 2048 " X: 0
920endif
921
922if ExtraVim()
923 try
924 Xpath 4096 " X: 4096
925 asdf
926 Xpath 8192 " X: 0
927 endtry | Xpath 16384 " X: 0
928 Xpath 32768 " X: 0
929endif
930
931if ExtraVim()
932 if 1
933 try
934 Xpath 65536 " X: 65536
935 asdf
936 Xpath 131072 " X: 0
937 endtry | Xpath 262144 " X: 0
938 endif | Xpath 524288 " X: 0
939 Xpath 1048576 " X: 0
940endif
941
942if ExtraVim()
943 let p = 1
944 while p
945 let p = 0
946 try
947 Xpath 2097152 " X: 2097152
948 asdf
949 Xpath 4194304 " X: 0
950 endtry | Xpath 8388608 " X: 0
951 endwhile | Xpath 16777216 " X: 0
952 Xpath 33554432 " X: 0
953endif
954
955if ExtraVim()
956 let p = 1
957 while p
958 let p = 0
959" try
960 Xpath 67108864 " X: 67108864
961 endwhile | Xpath 134217728 " X: 0
962 Xpath 268435456 " X: 0
963endif
964
965Xcheck 69275973
966"-------------------------------------------------------------------------------
967" Test 20: Aborting on errors after :try/:endtry {{{1
968"
969" When an error occurs after the last active :try/:endtry region has
970" been left, termination behavior is as if no :try/:endtry has been
971" seen.
972"-------------------------------------------------------------------------------
973
974XpathINIT
975
976if ExtraVim()
977 let p = 1
978 while p
979 let p = 0
980 try
981 Xpath 1 " X: 1
982 endtry
983 asdf
984 endwhile | Xpath 2 " X: 0
985 Xpath 4 " X: 4
986endif
987
988if ExtraVim()
989 while 1
990 try
991 Xpath 8 " X: 8
992 break
993 Xpath 16 " X: 0
994 endtry
995 endwhile
996 Xpath 32 " X: 32
997 asdf
998 Xpath 64 " X: 64
999endif
1000
1001if ExtraVim()
1002 while 1
1003 try
1004 Xpath 128 " X: 128
1005 break
1006 Xpath 256 " X: 0
1007 finally
1008 Xpath 512 " X: 512
1009 endtry
1010 endwhile
1011 Xpath 1024 " X: 1024
1012 asdf
1013 Xpath 2048 " X: 2048
1014endif
1015
1016if ExtraVim()
1017 while 1
1018 try
1019 Xpath 4096 " X: 4096
1020 finally
1021 Xpath 8192 " X: 8192
1022 break
1023 Xpath 16384 " X: 0
1024 endtry
1025 endwhile
1026 Xpath 32768 " X: 32768
1027 asdf
1028 Xpath 65536 " X: 65536
1029endif
1030
1031if ExtraVim()
1032 let p = 1
1033 while p
1034 let p = 0
1035 try
1036 Xpath 131072 " X: 131072
1037 continue
1038 Xpath 262144 " X: 0
1039 endtry
1040 endwhile
1041 Xpath 524288 " X: 524288
1042 asdf
1043 Xpath 1048576 " X: 1048576
1044endif
1045
1046if ExtraVim()
1047 let p = 1
1048 while p
1049 let p = 0
1050 try
1051 Xpath 2097152 " X: 2097152
1052 continue
1053 Xpath 4194304 " X: 0
1054 finally
1055 Xpath 8388608 " X: 8388608
1056 endtry
1057 endwhile
1058 Xpath 16777216 " X: 16777216
1059 asdf
1060 Xpath 33554432 " X: 33554432
1061endif
1062
1063if ExtraVim()
1064 let p = 1
1065 while p
1066 let p = 0
1067 try
1068 Xpath 67108864 " X: 67108864
1069 finally
1070 Xpath 134217728 " X: 134217728
1071 continue
1072 Xpath 268435456 " X: 0
1073 endtry
1074 endwhile
1075 Xpath 536870912 " X: 536870912
1076 asdf
1077 Xpath 1073741824 " X: 1073741824
1078endif
1079
1080Xcheck 1874575085
1081
1082
1083"-------------------------------------------------------------------------------
1084" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1
1085"
1086" If a :try conditional stays inactive due to a preceding :continue,
1087" :break, :return, or :finish, its :finally clause should not be
1088" executed.
1089"-------------------------------------------------------------------------------
1090
1091XpathINIT
1092
1093if ExtraVim()
1094 function F()
1095 let loops = 2
1096 XloopINIT! 1 256
1097 while loops > 0
1098 XloopNEXT
1099 let loops = loops - 1
1100 try
1101 if loops == 1
1102 Xloop 1 " X: 1
1103 continue
1104 Xloop 2 " X: 0
1105 elseif loops == 0
1106 Xloop 4 " X: 4*256
1107 break
1108 Xloop 8 " X: 0
1109 endif
1110
1111 try " inactive
1112 Xloop 16 " X: 0
1113 finally
1114 Xloop 32 " X: 0
1115 endtry
1116 finally
1117 Xloop 64 " X: 64 + 64*256
1118 endtry
1119 Xloop 128 " X: 0
1120 endwhile
1121
1122 try
1123 Xpath 65536 " X: 65536
1124 return
1125 Xpath 131072 " X: 0
1126 try " inactive
1127 Xpath 262144 " X: 0
1128 finally
1129 Xpath 524288 " X: 0
1130 endtry
1131 finally
1132 Xpath 1048576 " X: 1048576
1133 endtry
1134 Xpath 2097152 " X: 0
1135 endfunction
1136
1137 try
1138 Xpath 4194304 " X: 4194304
1139 call F()
1140 Xpath 8388608 " X: 8388608
1141 finish
1142 Xpath 16777216 " X: 0
1143 try " inactive
1144 Xpath 33554432 " X: 0
1145 finally
1146 Xpath 67108864 " X: 0
1147 endtry
1148 finally
1149 Xpath 134217728 " X: 134217728
1150 endtry
1151 Xpath 268435456 " X: 0
1152endif
1153
1154Xcheck 147932225
1155
1156
1157"-------------------------------------------------------------------------------
1158" Test 22: :finally for a :try after an error/interrupt/:throw {{{1
1159"
1160" If a :try conditional stays inactive due to a preceding error or
1161" interrupt or :throw, its :finally clause should not be executed.
1162"-------------------------------------------------------------------------------
1163
1164XpathINIT
1165
1166if ExtraVim()
1167 function! Error()
1168 try
1169 asdf " aborting error, triggering error exception
1170 endtry
1171 endfunction
1172
1173 Xpath 1 " X: 1
1174 call Error()
1175 Xpath 2 " X: 0
1176
1177 if 1 " not active due to error
1178 try " not active since :if inactive
1179 Xpath 4 " X: 0
1180 finally
1181 Xpath 8 " X: 0
1182 endtry
1183 endif
1184
1185 try " not active due to error
1186 Xpath 16 " X: 0
1187 finally
1188 Xpath 32 " X: 0
1189 endtry
1190endif
1191
1192if ExtraVim()
1193 function! Interrupt()
1194 try
1195 "INTERRUPT " triggering interrupt exception
1196 endtry
1197 endfunction
1198
1199 Xpath 64 " X: 64
1200 call Interrupt()
1201 Xpath 128 " X: 0
1202
1203 if 1 " not active due to interrupt
1204 try " not active since :if inactive
1205 Xpath 256 " X: 0
1206 finally
1207 Xpath 512 " X: 0
1208 endtry
1209 endif
1210
1211 try " not active due to interrupt
1212 Xpath 1024 " X: 0
1213 finally
1214 Xpath 2048 " X: 0
1215 endtry
1216endif
1217
1218if ExtraVim()
1219 function! Throw()
1220 throw "xyz"
1221 endfunction
1222
1223 Xpath 4096 " X: 4096
1224 call Throw()
1225 Xpath 8192 " X: 0
1226
1227 if 1 " not active due to :throw
1228 try " not active since :if inactive
1229 Xpath 16384 " X: 0
1230 finally
1231 Xpath 32768 " X: 0
1232 endtry
1233 endif
1234
1235 try " not active due to :throw
1236 Xpath 65536 " X: 0
1237 finally
1238 Xpath 131072 " X: 0
1239 endtry
1240endif
1241
1242Xcheck 4161
1243
1244
1245"-------------------------------------------------------------------------------
1246" Test 23: :catch clauses for a :try after a :throw {{{1
1247"
1248" If a :try conditional stays inactive due to a preceding :throw,
1249" none of its :catch clauses should be executed.
1250"-------------------------------------------------------------------------------
1251
1252XpathINIT
1253
1254if ExtraVim()
1255 try
1256 Xpath 1 " X: 1
1257 throw "xyz"
1258 Xpath 2 " X: 0
1259
1260 if 1 " not active due to :throw
1261 try " not active since :if inactive
1262 Xpath 4 " X: 0
1263 catch /xyz/
1264 Xpath 8 " X: 0
1265 endtry
1266 endif
1267 catch /xyz/
1268 Xpath 16 " X: 16
1269 endtry
1270
1271 Xpath 32 " X: 32
1272 throw "abc"
1273 Xpath 64 " X: 0
1274
1275 try " not active due to :throw
1276 Xpath 128 " X: 0
1277 catch /abc/
1278 Xpath 256 " X: 0
1279 endtry
1280endif
1281
1282Xcheck 49
1283
1284
1285"-------------------------------------------------------------------------------
1286" Test 24: :endtry for a :try after a :throw {{{1
1287"
1288" If a :try conditional stays inactive due to a preceding :throw,
1289" its :endtry should not rethrow the exception to the next surrounding
1290" active :try conditional.
1291"-------------------------------------------------------------------------------
1292
1293XpathINIT
1294
1295if ExtraVim()
1296 try " try 1
1297 try " try 2
1298 Xpath 1 " X: 1
1299 throw "xyz" " makes try 2 inactive
1300 Xpath 2 " X: 0
1301
1302 try " try 3
1303 Xpath 4 " X: 0
1304 endtry " no rethrow to try 1
1305 catch /xyz/ " should catch although try 2 inactive
1306 Xpath 8 " X: 8
1307 endtry
1308 catch /xyz/ " try 1 active, but exception already caught
1309 Xpath 16 " X: 0
1310 endtry
1311 Xpath 32 " X: 32
1312endif
1313
1314Xcheck 41
1315
1316
1317"-------------------------------------------------------------------------------
1318" Test 25: Executing :finally clauses on normal control flow {{{1
1319"
1320" Control flow in a :try conditional should always fall through to its
1321" :finally clause. A :finally clause of a :try conditional inside an
1322" inactive conditional should never be executed.
1323"-------------------------------------------------------------------------------
1324
1325XpathINIT
1326
1327function! F()
1328 let loops = 3
1329 XloopINIT 1 256
1330 while loops > 0 " 3: 2: 1:
1331 Xloop 1 " X: 1 + 1*256 + 1*256*256
1332 if loops >= 2
1333 try
1334 Xloop 2 " X: 2 + 2*256
1335 if loops == 2
1336 try
1337 Xloop 4 " X: 4*256
1338 finally
1339 Xloop 8 " X: 8*256
1340 endtry
1341 endif
1342 finally
1343 Xloop 16 " X: 16 + 16*256
1344 if loops == 2
1345 try
1346 Xloop 32 " X: 32*256
1347 finally
1348 Xloop 64 " X: 64*256
1349 endtry
1350 endif
1351 endtry
1352 endif
1353 Xloop 128 " X: 128 + 128*256 + 128*256*256
1354 let loops = loops - 1
1355 XloopNEXT
1356 endwhile
1357 Xpath 16777216 " X: 16777216
1358endfunction
1359
1360if 1
1361 try
1362 Xpath 33554432 " X: 33554432
1363 call F()
1364 Xpath 67108864 " X: 67108864
1365 finally
1366 Xpath 134217728 " X: 134217728
1367 endtry
1368else
1369 try
1370 Xpath 268435456 " X: 0
1371 finally
1372 Xpath 536870912 " X: 0
1373 endtry
1374endif
1375
1376delfunction F
1377
1378Xcheck 260177811
1379
1380
1381"-------------------------------------------------------------------------------
1382" Test 26: Executing :finally clauses after :continue or :break {{{1
1383"
1384" For a :continue or :break dynamically enclosed in a :try/:endtry
1385" region inside the next surrounding :while/:endwhile, if the
1386" :continue/:break is before the :finally, the :finally clause is
1387" executed first. If the :continue/:break is after the :finally, the
1388" :finally clause is broken (like an :if/:endif region).
1389"-------------------------------------------------------------------------------
1390
1391XpathINIT
1392
1393try
1394 let loops = 3
1395 XloopINIT! 1 32
1396 while loops > 0
1397 XloopNEXT
1398 try
1399 try
1400 if loops == 2 " 3: 2: 1:
1401 Xloop 1 " X: 1*32
1402 let loops = loops - 1
1403 continue
1404 elseif loops == 1
1405 Xloop 2 " X: 2*32*32
1406 break
1407 finish
1408 endif
1409 Xloop 4 " X: 4
1410 endtry
1411 finally
1412 Xloop 8 " X: 8 + 8*32 + 8*32*32
1413 endtry
1414 Xloop 16 " X: 16
1415 let loops = loops - 1
1416 endwhile
1417 Xpath 32768 " X: 32768
1418finally
1419 Xpath 65536 " X: 65536
1420 let loops = 3
1421 XloopINIT 131072 16
1422 while loops > 0
1423 try
1424 finally
1425 try
1426 if loops == 2
1427 Xloop 1 " X: 131072*16
1428 let loops = loops - 1
1429 XloopNEXT
1430 continue
1431 elseif loops == 1
1432 Xloop 2 " X: 131072*2*16*16
1433 break
1434 finish
1435 endif
1436 endtry
1437 Xloop 4 " X: 131072*4
1438 endtry
1439 Xloop 8 " X: 131072*8
1440 let loops = loops - 1
1441 XloopNEXT
1442 endwhile
1443 Xpath 536870912 " X: 536870912
1444endtry
1445Xpath 1073741824 " X: 1073741824
1446
1447unlet loops
1448
1449Xcheck 1681500476
1450
1451
1452"-------------------------------------------------------------------------------
1453" Test 27: Executing :finally clauses after :return {{{1
1454"
1455" For a :return command dynamically enclosed in a :try/:endtry region,
1456" :finally clauses are executed and the called function is ended.
1457"-------------------------------------------------------------------------------
1458
1459XpathINIT
1460
1461function! F()
1462 try
1463 Xpath 1 " X: 1
1464 try
1465 Xpath 2 " X: 2
1466 return
1467 Xpath 4 " X: 0
1468 finally
1469 Xpath 8 " X: 8
1470 endtry
1471 Xpath 16 " X: 0
1472 finally
1473 Xpath 32 " X: 32
1474 endtry
1475 Xpath 64 " X: 0
1476endfunction
1477
1478function! G()
1479 try
1480 Xpath 128 " X: 128
1481 return
1482 Xpath 256 " X: 0
1483 finally
1484 Xpath 512 " X: 512
1485 call F()
1486 Xpath 1024 " X: 1024
1487 endtry
1488 Xpath 2048 " X: 0
1489endfunction
1490
1491function! H()
1492 try
1493 Xpath 4096 " X: 4096
1494 call G()
1495 Xpath 8192 " X: 8192
1496 finally
1497 Xpath 16384 " X: 16384
1498 return
1499 Xpath 32768 " X: 0
1500 endtry
1501 Xpath 65536 " X: 0
1502endfunction
1503
1504try
1505 Xpath 131072 " X: 131072
1506 call H()
1507 Xpath 262144 " X: 262144
1508finally
1509 Xpath 524288 " X: 524288
1510endtry
1511Xpath 1048576 " X: 1048576
1512
1513Xcheck 1996459
1514
1515" Leave F, G, and H for execution as scripts in the next test.
1516
1517
1518"-------------------------------------------------------------------------------
1519" Test 28: Executing :finally clauses after :finish {{{1
1520"
1521" For a :finish command dynamically enclosed in a :try/:endtry region,
1522" :finally clauses are executed and the sourced file is finished.
1523"
1524" This test executes the bodies of the functions F, G, and H from the
1525" previous test as script files (:return replaced by :finish).
1526"-------------------------------------------------------------------------------
1527
1528XpathINIT
1529
1530let scriptF = MakeScript("F") " X: 1 + 2 + 8 + 32
1531let scriptG = MakeScript("G", scriptF) " X: 128 + 512 + 1024
1532let scriptH = MakeScript("H", scriptG) " X: 4096 + 8192 + 16384
1533
1534try
1535 Xpath 131072 " X: 131072
1536 exec "source" scriptH
1537 Xpath 262144 " X: 262144
1538finally
1539 Xpath 524288 " X: 524288
1540endtry
1541Xpath 1048576 " X: 1048576
1542
1543call delete(scriptF)
1544call delete(scriptG)
1545call delete(scriptH)
1546unlet scriptF scriptG scriptH
1547delfunction F
1548delfunction G
1549delfunction H
1550
1551Xcheck 1996459
1552
1553
1554"-------------------------------------------------------------------------------
1555" Test 29: Executing :finally clauses on errors {{{1
1556"
1557" After an error in a command dynamically enclosed in a :try/:endtry
1558" region, :finally clauses are executed and the script processing is
1559" terminated.
1560"-------------------------------------------------------------------------------
1561
1562XpathINIT
1563
1564if ExtraVim()
1565 function! F()
1566 while 1
1567 try
1568 Xpath 1 " X: 1
1569 while 1
1570 try
1571 Xpath 2 " X: 2
1572 asdf " error
1573 Xpath 4 " X: 0
1574 finally
1575 Xpath 8 " X: 8
1576 endtry | Xpath 16 " X: 0
1577 Xpath 32 " X: 0
1578 break
1579 endwhile
1580 Xpath 64 " X: 0
1581 finally
1582 Xpath 128 " X: 128
1583 endtry | Xpath 256 " X: 0
1584 Xpath 512 " X: 0
1585 break
1586 endwhile
1587 Xpath 1024 " X: 0
1588 endfunction
1589
1590 while 1
1591 try
1592 Xpath 2048 " X: 2048
1593 while 1
1594 call F()
1595 Xpath 4096 " X: 0
1596 break
1597 endwhile | Xpath 8192 " X: 0
1598 Xpath 16384 " X: 0
1599 finally
1600 Xpath 32768 " X: 32768
1601 endtry | Xpath 65536 " X: 0
1602 endwhile | Xpath 131072 " X: 0
1603 Xpath 262144 " X: 0
1604endif
1605
1606if ExtraVim()
1607 function! G() abort
1608 if 1
1609 try
1610 Xpath 524288 " X: 524288
1611 asdf " error
1612 Xpath 1048576 " X: 0
1613 finally
1614 Xpath 2097152 " X: 2097152
1615 endtry | Xpath 4194304 " X: 0
1616 endif | Xpath 8388608 " X: 0
1617 Xpath 16777216 " X: 0
1618 endfunction
1619
1620 if 1
1621 try
1622 Xpath 33554432 " X: 33554432
1623 call G()
1624 Xpath 67108864 " X: 0
1625 finally
1626 Xpath 134217728 " X: 134217728
1627 endtry | Xpath 268435456 " X: 0
1628 endif | Xpath 536870912 " X: 0
1629 Xpath 1073741824 " X: 0
1630endif
1631
1632Xcheck 170428555
1633
1634
1635"-------------------------------------------------------------------------------
1636" Test 30: Executing :finally clauses on interrupt {{{1
1637"
1638" After an interrupt in a command dynamically enclosed in
1639" a :try/:endtry region, :finally clauses are executed and the
1640" script processing is terminated.
1641"-------------------------------------------------------------------------------
1642
1643XpathINIT
1644
1645if ExtraVim()
1646 XloopINIT 1 16
1647
1648 function! F()
1649 try
1650 Xloop 1 " X: 1 + 1*16
1651 "INTERRUPT
1652 Xloop 2 " X: 0
1653 finally
1654 Xloop 4 " X: 4 + 4*16
1655 endtry
1656 Xloop 8 " X: 0
1657 endfunction
1658
1659 try
1660 Xpath 256 " X: 256
1661 try
1662 Xpath 512 " X: 512
1663 "INTERRUPT
1664 Xpath 1024 " X: 0
1665 finally
1666 Xpath 2048 " X: 2048
1667 try
1668 Xpath 4096 " X: 4096
1669 try
1670 Xpath 8192 " X: 8192
1671 finally
1672 Xpath 16384 " X: 16384
1673 try
1674 Xpath 32768 " X: 32768
1675 "INTERRUPT
1676 Xpath 65536 " X: 0
1677 endtry
1678 Xpath 131072 " X: 0
1679 endtry
1680 Xpath 262144 " X: 0
1681 endtry
1682 Xpath 524288 " X: 0
1683 endtry
1684 Xpath 1048576 " X: 0
1685 finally
1686 Xpath 2097152 " X: 2097152
1687 try
1688 Xpath 4194304 " X: 4194304
1689 call F()
1690 Xpath 8388608 " X: 0
1691 finally
1692 Xpath 16777216 " X: 16777216
1693 try
1694 Xpath 33554432 " X: 33554432
1695 XloopNEXT
1696 ExecAsScript F
1697 Xpath 67108864 " X: 0
1698 finally
1699 Xpath 134217728 " X: 134217728
1700 endtry
1701 Xpath 268435456 " X: 0
1702 endtry
1703 Xpath 536870912 " X: 0
1704 endtry
1705 Xpath 1073741824 " X: 0
1706endif
1707
1708Xcheck 190905173
1709
1710
1711"-------------------------------------------------------------------------------
1712" Test 31: Executing :finally clauses after :throw {{{1
1713"
1714" After a :throw dynamically enclosed in a :try/:endtry region,
1715" :finally clauses are executed and the script processing is
1716" terminated.
1717"-------------------------------------------------------------------------------
1718
1719XpathINIT
1720
1721if ExtraVim()
1722 XloopINIT 1 16
1723
1724 function! F()
1725 try
1726 Xloop 1 " X: 1 + 1*16
1727 throw "exception"
1728 Xloop 2 " X: 0
1729 finally
1730 Xloop 4 " X: 4 + 4*16
1731 endtry
1732 Xloop 8 " X: 0
1733 endfunction
1734
1735 try
1736 Xpath 256 " X: 256
1737 try
1738 Xpath 512 " X: 512
1739 throw "exception"
1740 Xpath 1024 " X: 0
1741 finally
1742 Xpath 2048 " X: 2048
1743 try
1744 Xpath 4096 " X: 4096
1745 try
1746 Xpath 8192 " X: 8192
1747 finally
1748 Xpath 16384 " X: 16384
1749 try
1750 Xpath 32768 " X: 32768
1751 throw "exception"
1752 Xpath 65536 " X: 0
1753 endtry
1754 Xpath 131072 " X: 0
1755 endtry
1756 Xpath 262144 " X: 0
1757 endtry
1758 Xpath 524288 " X: 0
1759 endtry
1760 Xpath 1048576 " X: 0
1761 finally
1762 Xpath 2097152 " X: 2097152
1763 try
1764 Xpath 4194304 " X: 4194304
1765 call F()
1766 Xpath 8388608 " X: 0
1767 finally
1768 Xpath 16777216 " X: 16777216
1769 try
1770 Xpath 33554432 " X: 33554432
1771 XloopNEXT
1772 ExecAsScript F
1773 Xpath 67108864 " X: 0
1774 finally
1775 Xpath 134217728 " X: 134217728
1776 endtry
1777 Xpath 268435456 " X: 0
1778 endtry
1779 Xpath 536870912 " X: 0
1780 endtry
1781 Xpath 1073741824 " X: 0
1782endif
1783
1784Xcheck 190905173
1785
1786
1787"-------------------------------------------------------------------------------
1788" Test 32: Remembering the :return value on :finally {{{1
1789"
1790" If a :finally clause is executed due to a :return specifying
1791" a value, this is the value visible to the caller if not overwritten
1792" by a new :return in the :finally clause. A :return without a value
1793" in the :finally clause overwrites with value 0.
1794"-------------------------------------------------------------------------------
1795
1796XpathINIT
1797
1798function! F()
1799 try
1800 Xpath 1 " X: 1
1801 try
1802 Xpath 2 " X: 2
1803 return "ABCD"
1804 Xpath 4 " X: 0
1805 finally
1806 Xpath 8 " X: 8
1807 endtry
1808 Xpath 16 " X: 0
1809 finally
1810 Xpath 32 " X: 32
1811 endtry
1812 Xpath 64 " X: 0
1813endfunction
1814
1815function! G()
1816 try
1817 Xpath 128 " X: 128
1818 return 8
1819 Xpath 256 " X: 0
1820 finally
1821 Xpath 512 " X: 512
1822 return 16 + strlen(F())
1823 Xpath 1024 " X: 0
1824 endtry
1825 Xpath 2048 " X: 0
1826endfunction
1827
1828function! H()
1829 try
1830 Xpath 4096 " X: 4096
1831 return 32
1832 Xpath 8192 " X: 0
1833 finally
1834 Xpath 16384 " X: 16384
1835 return
1836 Xpath 32768 " X: 0
1837 endtry
1838 Xpath 65536 " X: 0
1839endfunction
1840
1841function! I()
1842 try
1843 Xpath 131072 " X: 131072
1844 finally
1845 Xpath 262144 " X: 262144
1846 return G() + H() + 64
1847 Xpath 524288 " X: 0
1848 endtry
1849 Xpath 1048576 " X: 0
1850endfunction
1851
1852let retcode = I()
1853Xpath 2097152 " X: 2097152
1854
1855if retcode < 0
1856 Xpath 4194304 " X: 0
1857endif
1858if retcode % 4
1859 Xpath 8388608 " X: 0
1860endif
1861if (retcode/4) % 2
1862 Xpath 16777216 " X: 16777216
1863endif
1864if (retcode/8) % 2
1865 Xpath 33554432 " X: 0
1866endif
1867if (retcode/16) % 2
1868 Xpath 67108864 " X: 67108864
1869endif
1870if (retcode/32) % 2
1871 Xpath 134217728 " X: 0
1872endif
1873if (retcode/64) % 2
1874 Xpath 268435456 " X: 268435456
1875endif
1876if retcode/128
1877 Xpath 536870912 " X: 0
1878endif
1879
1880unlet retcode
1881delfunction F
1882delfunction G
1883delfunction H
1884delfunction I
1885
1886Xcheck 354833067
1887
1888
1889"-------------------------------------------------------------------------------
1890" Test 33: :return under :execute or user command and :finally {{{1
1891"
1892" A :return command may be executed under an ":execute" or from
1893" a user command. Executing of :finally clauses and passing through
1894" the return code works also then.
1895"-------------------------------------------------------------------------------
1896XpathINIT
1897
1898command! -nargs=? RETURN
1899 \ try | return <args> | finally | return <args> * 2 | endtry
1900
1901function! F()
1902 try
1903 RETURN 8
1904 Xpath 1 " X: 0
1905 finally
1906 Xpath 2 " X: 2
1907 endtry
1908 Xpath 4 " X: 0
1909endfunction
1910
1911function! G()
1912 try
1913 RETURN 32
1914 Xpath 8 " X: 0
1915 finally
1916 Xpath 16 " X: 16
1917 RETURN 128
1918 Xpath 32 " X: 0
1919 endtry
1920 Xpath 64 " X: 0
1921endfunction
1922
1923function! H()
1924 try
1925 execute "try | return 512 | finally | return 1024 | endtry"
1926 Xpath 128 " X: 0
1927 finally
1928 Xpath 256 " X: 256
1929 endtry
1930 Xpath 512 " X: 0
1931endfunction
1932
1933function! I()
1934 try
1935 execute "try | return 2048 | finally | return 4096 | endtry"
1936 Xpath 1024 " X: 0
1937 finally
1938 Xpath 2048 " X: 2048
1939 execute "try | return 8192 | finally | return 16384 | endtry"
1940 Xpath 4096 " X: 0
1941 endtry
1942 Xpath 8192 " X: 0
1943endfunction
1944
1945function! J()
1946 try
1947 RETURN 32768
1948 Xpath 16384 " X: 0
1949 finally
1950 Xpath 32768 " X: 32768
1951 return
1952 Xpath 65536 " X: 0
1953 endtry
1954 Xpath 131072 " X: 0
1955endfunction
1956
1957function! K()
1958 try
1959 execute "try | return 131072 | finally | return 262144 | endtry"
1960 Xpath 262144 " X: 0
1961 finally
1962 Xpath 524288 " X: 524288
1963 execute "try | return 524288 | finally | return | endtry"
1964 Xpath 1048576 " X: 0
1965 endtry
1966 Xpath 2097152 " X: 0
1967endfunction
1968
1969function! L()
1970 try
1971 return
1972 Xpath 4194304 " X: 0
1973 finally
1974 Xpath 8388608 " X: 8388608
1975 RETURN 1048576
1976 Xpath 16777216 " X: 0
1977 endtry
1978 Xpath 33554432 " X: 0
1979endfunction
1980
1981function! M()
1982 try
1983 return
1984 Xpath 67108864 " X: 0
1985 finally
1986 Xpath 134217728 " X: 134217728
1987 execute "try | return 4194304 | finally | return 8388608 | endtry"
1988 Xpath 268435456 " X: 0
1989 endtry
1990 Xpath 536870912 " X: 0
1991endfunction
1992
1993function! N()
1994 RETURN 16777216
1995endfunction
1996
1997function! O()
1998 execute "try | return 67108864 | finally | return 134217728 | endtry"
1999endfunction
2000
2001let sum = F() + G() + H() + I() + J() + K() + L() + M()
2002let expected = 16 + 256 + 1024 + 16384 + 0 + 0 + 2097152 + 8388608
2003let sum = sum + N() + O()
2004let expected = expected + 33554432 + 134217728
2005
2006if sum == expected
2007 Xout "sum = " . sum . " (ok)"
2008else
2009 Xout "sum = " . sum . ", expected: " . expected
2010endif
2011
2012Xpath 1073741824 " X: 1073741824
2013
2014if sum != expected
2015 " The Xpath command does not accept 2^31 (negative); add explicitly:
2016 let Xpath = Xpath + 2147483648 " X: 0
2017endif
2018
2019unlet sum expected
2020delfunction F
2021delfunction G
2022delfunction H
2023delfunction I
2024delfunction J
2025delfunction K
2026delfunction L
2027delfunction M
2028delfunction N
2029delfunction O
2030
2031Xcheck 1216907538
2032
2033
2034"-------------------------------------------------------------------------------
2035" Test 34: :finally reason discarded by :continue {{{1
2036"
2037" When a :finally clause is executed due to a :continue, :break,
2038" :return, :finish, error, interrupt or :throw, the jump reason is
2039" discarded by a :continue in the finally clause.
2040"-------------------------------------------------------------------------------
2041
2042XpathINIT
2043
2044if ExtraVim()
2045
2046 XloopINIT! 1 8
2047
2048 function! C(jump)
2049 XloopNEXT
2050 let loop = 0
2051 while loop < 2
2052 let loop = loop + 1
2053 if loop == 1
2054 try
2055 if a:jump == "continue"
2056 continue
2057 elseif a:jump == "break"
2058 break
2059 elseif a:jump == "return" || a:jump == "finish"
2060 return
2061 elseif a:jump == "error"
2062 asdf
2063 elseif a:jump == "interrupt"
2064 "INTERRUPT
2065 let dummy = 0
2066 elseif a:jump == "throw"
2067 throw "abc"
2068 endif
2069 finally
2070 continue " discards jump that caused the :finally
2071 Xloop 1 " X: 0
2072 endtry
2073 Xloop 2 " X: 0
2074 elseif loop == 2
2075 Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144)
2076 endif
2077 endwhile
2078 endfunction
2079
2080 call C("continue")
2081 Xpath 2097152 " X: 2097152
2082 call C("break")
2083 Xpath 4194304 " X: 4194304
2084 call C("return")
2085 Xpath 8388608 " X: 8388608
2086 let g:jump = "finish"
2087 ExecAsScript C
2088 unlet g:jump
2089 Xpath 16777216 " X: 16777216
2090 try
2091 call C("error")
2092 Xpath 33554432 " X: 33554432
2093 finally
2094 Xpath 67108864 " X: 67108864
2095 try
2096 call C("interrupt")
2097 Xpath 134217728 " X: 134217728
2098 finally
2099 Xpath 268435456 " X: 268435456
2100 call C("throw")
2101 Xpath 536870912 " X: 536870912
2102 endtry
2103 endtry
2104 Xpath 1073741824 " X: 1073741824
2105
2106 delfunction C
2107
2108endif
2109
2110Xcheck 2146584868
2111
2112
2113"-------------------------------------------------------------------------------
2114" Test 35: :finally reason discarded by :break {{{1
2115"
2116" When a :finally clause is executed due to a :continue, :break,
2117" :return, :finish, error, interrupt or :throw, the jump reason is
2118" discarded by a :break in the finally clause.
2119"-------------------------------------------------------------------------------
2120
2121XpathINIT
2122
2123if ExtraVim()
2124
2125 XloopINIT! 1 8
2126
2127 function! B(jump)
2128 XloopNEXT
2129 let loop = 0
2130 while loop < 2
2131 let loop = loop + 1
2132 if loop == 1
2133 try
2134 if a:jump == "continue"
2135 continue
2136 elseif a:jump == "break"
2137 break
2138 elseif a:jump == "return" || a:jump == "finish"
2139 return
2140 elseif a:jump == "error"
2141 asdf
2142 elseif a:jump == "interrupt"
2143 "INTERRUPT
2144 let dummy = 0
2145 elseif a:jump == "throw"
2146 throw "abc"
2147 endif
2148 finally
2149 break " discards jump that caused the :finally
2150 Xloop 1 " X: 0
2151 endtry
2152 elseif loop == 2
2153 Xloop 2 " X: 0
2154 endif
2155 endwhile
2156 Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144)
2157 endfunction
2158
2159 call B("continue")
2160 Xpath 2097152 " X: 2097152
2161 call B("break")
2162 Xpath 4194304 " X: 4194304
2163 call B("return")
2164 Xpath 8388608 " X: 8388608
2165 let g:jump = "finish"
2166 ExecAsScript B
2167 unlet g:jump
2168 Xpath 16777216 " X: 16777216
2169 try
2170 call B("error")
2171 Xpath 33554432 " X: 33554432
2172 finally
2173 Xpath 67108864 " X: 67108864
2174 try
2175 call B("interrupt")
2176 Xpath 134217728 " X: 134217728
2177 finally
2178 Xpath 268435456 " X: 268435456
2179 call B("throw")
2180 Xpath 536870912 " X: 536870912
2181 endtry
2182 endtry
2183 Xpath 1073741824 " X: 1073741824
2184
2185 delfunction B
2186
2187endif
2188
2189Xcheck 2146584868
2190
2191
2192"-------------------------------------------------------------------------------
2193" Test 36: :finally reason discarded by :return {{{1
2194"
2195" When a :finally clause is executed due to a :continue, :break,
2196" :return, :finish, error, interrupt or :throw, the jump reason is
2197" discarded by a :return in the finally clause.
2198"-------------------------------------------------------------------------------
2199
2200XpathINIT
2201
2202if ExtraVim()
2203
2204 XloopINIT! 1 8
2205
2206 function! R(jump, retval) abort
2207 XloopNEXT
2208 let loop = 0
2209 while loop < 2
2210 let loop = loop + 1
2211 if loop == 1
2212 try
2213 if a:jump == "continue"
2214 continue
2215 elseif a:jump == "break"
2216 break
2217 elseif a:jump == "return"
2218 return
2219 elseif a:jump == "error"
2220 asdf
2221 elseif a:jump == "interrupt"
2222 "INTERRUPT
2223 let dummy = 0
2224 elseif a:jump == "throw"
2225 throw "abc"
2226 endif
2227 finally
2228 return a:retval " discards jump that caused the :finally
2229 Xloop 1 " X: 0
2230 endtry
2231 elseif loop == 2
2232 Xloop 2 " X: 0
2233 endif
2234 endwhile
2235 Xloop 4 " X: 0
2236 endfunction
2237
2238 let sum = -R("continue", -8)
2239 Xpath 2097152 " X: 2097152
2240 let sum = sum - R("break", -16)
2241 Xpath 4194304 " X: 4194304
2242 let sum = sum - R("return", -32)
2243 Xpath 8388608 " X: 8388608
2244 try
2245 let sum = sum - R("error", -64)
2246 Xpath 16777216 " X: 16777216
2247 finally
2248 Xpath 33554432 " X: 33554432
2249 try
2250 let sum = sum - R("interrupt", -128)
2251 Xpath 67108864 " X: 67108864
2252 finally
2253 Xpath 134217728 " X: 134217728
2254 let sum = sum - R("throw", -256)
2255 Xpath 268435456 " X: 268435456
2256 endtry
2257 endtry
2258 Xpath 536870912 " X: 536870912
2259
2260 let expected = 8 + 16 + 32 + 64 + 128 + 256
2261 if sum != expected
2262 Xpath 1073741824 " X: 0
2263 Xout "sum =" . sum . ", expected: " . expected
2264 endif
2265
2266 unlet sum expected
2267 delfunction R
2268
2269endif
2270
2271Xcheck 1071644672
2272
2273
2274"-------------------------------------------------------------------------------
2275" Test 37: :finally reason discarded by :finish {{{1
2276"
2277" When a :finally clause is executed due to a :continue, :break,
2278" :return, :finish, error, interrupt or :throw, the jump reason is
2279" discarded by a :finish in the finally clause.
2280"-------------------------------------------------------------------------------
2281
2282XpathINIT
2283
2284if ExtraVim()
2285
2286 XloopINIT! 1 8
2287
2288 function! F(jump) " not executed as function, transformed to a script
2289 XloopNEXT
2290 let loop = 0
2291 while loop < 2
2292 let loop = loop + 1
2293 if loop == 1
2294 try
2295 if a:jump == "continue"
2296 continue
2297 elseif a:jump == "break"
2298 break
2299 elseif a:jump == "finish"
2300 finish
2301 elseif a:jump == "error"
2302 asdf
2303 elseif a:jump == "interrupt"
2304 "INTERRUPT
2305 let dummy = 0
2306 elseif a:jump == "throw"
2307 throw "abc"
2308 endif
2309 finally
2310 finish " discards jump that caused the :finally
2311 Xloop 1 " X: 0
2312 endtry
2313 elseif loop == 2
2314 Xloop 2 " X: 0
2315 endif
2316 endwhile
2317 Xloop 4 " X: 0
2318 endfunction
2319
2320 let scriptF = MakeScript("F")
2321 delfunction F
2322
2323 let g:jump = "continue"
2324 exec "source" scriptF
2325 Xpath 2097152 " X: 2097152
2326 let g:jump = "break"
2327 exec "source" scriptF
2328 Xpath 4194304 " X: 4194304
2329 let g:jump = "finish"
2330 exec "source" scriptF
2331 Xpath 8388608 " X: 8388608
2332 try
2333 let g:jump = "error"
2334 exec "source" scriptF
2335 Xpath 16777216 " X: 16777216
2336 finally
2337 Xpath 33554432 " X: 33554432
2338 try
2339 let g:jump = "interrupt"
2340 exec "source" scriptF
2341 Xpath 67108864 " X: 67108864
2342 finally
2343 Xpath 134217728 " X: 134217728
2344 try
2345 let g:jump = "throw"
2346 exec "source" scriptF
2347 Xpath 268435456 " X: 268435456
2348 finally
2349 Xpath 536870912 " X: 536870912
2350 endtry
2351 endtry
2352 endtry
2353 unlet g:jump
2354
2355 call delete(scriptF)
2356 unlet scriptF
2357
2358endif
2359
2360Xcheck 1071644672
2361
2362
2363"-------------------------------------------------------------------------------
2364" Test 38: :finally reason discarded by an error {{{1
2365"
2366" When a :finally clause is executed due to a :continue, :break,
2367" :return, :finish, error, interrupt or :throw, the jump reason is
2368" discarded by an error in the finally clause.
2369"-------------------------------------------------------------------------------
2370
2371XpathINIT
2372
2373if ExtraVim()
2374
2375 XloopINIT! 1 4
2376
2377 function! E(jump)
2378 XloopNEXT
2379 let loop = 0
2380 while loop < 2
2381 let loop = loop + 1
2382 if loop == 1
2383 try
2384 if a:jump == "continue"
2385 continue
2386 elseif a:jump == "break"
2387 break
2388 elseif a:jump == "return" || a:jump == "finish"
2389 return
2390 elseif a:jump == "error"
2391 asdf
2392 elseif a:jump == "interrupt"
2393 "INTERRUPT
2394 let dummy = 0
2395 elseif a:jump == "throw"
2396 throw "abc"
2397 endif
2398 finally
2399 asdf " error; discards jump that caused the :finally
2400 endtry
2401 elseif loop == 2
2402 Xloop 1 " X: 0
2403 endif
2404 endwhile
2405 Xloop 2 " X: 0
2406 endfunction
2407
2408 try
2409 Xpath 16384 " X: 16384
2410 call E("continue")
2411 Xpath 32768 " X: 0
2412 finally
2413 try
2414 Xpath 65536 " X: 65536
2415 call E("break")
2416 Xpath 131072 " X: 0
2417 finally
2418 try
2419 Xpath 262144 " X: 262144
2420 call E("return")
2421 Xpath 524288 " X: 0
2422 finally
2423 try
2424 Xpath 1048576 " X: 1048576
2425 let g:jump = "finish"
2426 ExecAsScript E
2427 Xpath 2097152 " X: 0
2428 finally
2429 unlet g:jump
2430 try
2431 Xpath 4194304 " X: 4194304
2432 call E("error")
2433 Xpath 8388608 " X: 0
2434 finally
2435 try
2436 Xpath 16777216 " X: 16777216
2437 call E("interrupt")
2438 Xpath 33554432 " X: 0
2439 finally
2440 try
2441 Xpath 67108864 " X: 67108864
2442 call E("throw")
2443 Xpath 134217728 " X: 0
2444 finally
2445 Xpath 268435456 " X: 268435456
2446 delfunction E
2447 endtry
2448 endtry
2449 endtry
2450 endtry
2451 endtry
2452 endtry
2453 endtry
2454 Xpath 536870912 " X: 0
2455
2456endif
2457
2458Xcheck 357908480
2459
2460
2461"-------------------------------------------------------------------------------
2462" Test 39: :finally reason discarded by an interrupt {{{1
2463"
2464" When a :finally clause is executed due to a :continue, :break,
2465" :return, :finish, error, interrupt or :throw, the jump reason is
2466" discarded by an interrupt in the finally clause.
2467"-------------------------------------------------------------------------------
2468
2469XpathINIT
2470
2471if ExtraVim()
2472
2473 XloopINIT! 1 4
2474
2475 function! I(jump)
2476 XloopNEXT
2477 let loop = 0
2478 while loop < 2
2479 let loop = loop + 1
2480 if loop == 1
2481 try
2482 if a:jump == "continue"
2483 continue
2484 elseif a:jump == "break"
2485 break
2486 elseif a:jump == "return" || a:jump == "finish"
2487 return
2488 elseif a:jump == "error"
2489 asdf
2490 elseif a:jump == "interrupt"
2491 "INTERRUPT
2492 let dummy = 0
2493 elseif a:jump == "throw"
2494 throw "abc"
2495 endif
2496 finally
2497 "INTERRUPT - discards jump that caused the :finally
2498 let dummy = 0
2499 endtry
2500 elseif loop == 2
2501 Xloop 1 " X: 0
2502 endif
2503 endwhile
2504 Xloop 2 " X: 0
2505 endfunction
2506
2507 try
2508 Xpath 16384 " X: 16384
2509 call I("continue")
2510 Xpath 32768 " X: 0
2511 finally
2512 try
2513 Xpath 65536 " X: 65536
2514 call I("break")
2515 Xpath 131072 " X: 0
2516 finally
2517 try
2518 Xpath 262144 " X: 262144
2519 call I("return")
2520 Xpath 524288 " X: 0
2521 finally
2522 try
2523 Xpath 1048576 " X: 1048576
2524 let g:jump = "finish"
2525 ExecAsScript I
2526 Xpath 2097152 " X: 0
2527 finally
2528 unlet g:jump
2529 try
2530 Xpath 4194304 " X: 4194304
2531 call I("error")
2532 Xpath 8388608 " X: 0
2533 finally
2534 try
2535 Xpath 16777216 " X: 16777216
2536 call I("interrupt")
2537 Xpath 33554432 " X: 0
2538 finally
2539 try
2540 Xpath 67108864 " X: 67108864
2541 call I("throw")
2542 Xpath 134217728 " X: 0
2543 finally
2544 Xpath 268435456 " X: 268435456
2545 delfunction I
2546 endtry
2547 endtry
2548 endtry
2549 endtry
2550 endtry
2551 endtry
2552 endtry
2553 Xpath 536870912 " X: 0
2554
2555endif
2556
2557Xcheck 357908480
2558
2559
2560"-------------------------------------------------------------------------------
2561" Test 40: :finally reason discarded by :throw {{{1
2562"
2563" When a :finally clause is executed due to a :continue, :break,
2564" :return, :finish, error, interrupt or :throw, the jump reason is
2565" discarded by a :throw in the finally clause.
2566"-------------------------------------------------------------------------------
2567
2568XpathINIT
2569
2570if ExtraVim()
2571
2572 XloopINIT! 1 4
2573
2574 function! T(jump)
2575 XloopNEXT
2576 let loop = 0
2577 while loop < 2
2578 let loop = loop + 1
2579 if loop == 1
2580 try
2581 if a:jump == "continue"
2582 continue
2583 elseif a:jump == "break"
2584 break
2585 elseif a:jump == "return" || a:jump == "finish"
2586 return
2587 elseif a:jump == "error"
2588 asdf
2589 elseif a:jump == "interrupt"
2590 "INTERRUPT
2591 let dummy = 0
2592 elseif a:jump == "throw"
2593 throw "abc"
2594 endif
2595 finally
2596 throw "xyz" " discards jump that caused the :finally
2597 endtry
2598 elseif loop == 2
2599 Xloop 1 " X: 0
2600 endif
2601 endwhile
2602 Xloop 2 " X: 0
2603 endfunction
2604
2605 try
2606 Xpath 16384 " X: 16384
2607 call T("continue")
2608 Xpath 32768 " X: 0
2609 finally
2610 try
2611 Xpath 65536 " X: 65536
2612 call T("break")
2613 Xpath 131072 " X: 0
2614 finally
2615 try
2616 Xpath 262144 " X: 262144
2617 call T("return")
2618 Xpath 524288 " X: 0
2619 finally
2620 try
2621 Xpath 1048576 " X: 1048576
2622 let g:jump = "finish"
2623 ExecAsScript T
2624 Xpath 2097152 " X: 0
2625 finally
2626 unlet g:jump
2627 try
2628 Xpath 4194304 " X: 4194304
2629 call T("error")
2630 Xpath 8388608 " X: 0
2631 finally
2632 try
2633 Xpath 16777216 " X: 16777216
2634 call T("interrupt")
2635 Xpath 33554432 " X: 0
2636 finally
2637 try
2638 Xpath 67108864 " X: 67108864
2639 call T("throw")
2640 Xpath 134217728 " X: 0
2641 finally
2642 Xpath 268435456 " X: 268435456
2643 delfunction T
2644 endtry
2645 endtry
2646 endtry
2647 endtry
2648 endtry
2649 endtry
2650 endtry
2651 Xpath 536870912 " X: 0
2652
2653endif
2654
2655Xcheck 357908480
2656
2657
2658"-------------------------------------------------------------------------------
2659" Test 41: Skipped :throw finding next command {{{1
2660"
2661" A :throw in an inactive conditional must not hide a following
2662" command.
2663"-------------------------------------------------------------------------------
2664
2665XpathINIT
2666
2667function! F()
2668 Xpath 1 " X: 1
2669 if 0 | throw "never" | endif | Xpath 2 " X: 2
2670 Xpath 4 " X: 4
2671endfunction
2672
2673function! G()
2674 Xpath 8 " X: 8
2675 while 0 | throw "never" | endwhile | Xpath 16 " X: 16
2676 Xpath 32 " X: 32
2677endfunction
2678
2679function H()
2680 Xpath 64 " X: 64
2681 if 0 | try | throw "never" | endtry | endif | Xpath 128 " X: 128
2682 Xpath 256 " X: 256
2683endfunction
2684
2685Xpath 512 " X: 512
2686
2687try
2688 Xpath 1024 " X: 1024
2689 call F()
2690 Xpath 2048 " X: 2048
2691catch /.*/
2692 Xpath 4096 " X: 0
2693 Xout v:exception "in" v:throwpoint
2694endtry
2695
2696Xpath 8192 " X: 8192
2697
2698try
2699 Xpath 16384 " X: 16384
2700 call G()
2701 Xpath 32768 " X: 32768
2702catch /.*/
2703 Xpath 65536 " X: 0
2704 Xout v:exception "in" v:throwpoint
2705endtry
2706
2707Xpath 131072 " X: 131072
2708
2709try
2710 Xpath 262144 " X: 262144
2711 call H()
2712 Xpath 524288 " X: 524288
2713catch /.*/
2714 Xpath 1048576 " X: 0
2715 Xout v:exception "in" v:throwpoint
2716endtry
2717
2718Xpath 2097152 " X: 2097152
2719
2720delfunction F
2721delfunction G
2722delfunction H
2723
2724Xcheck 3076095
2725
2726
2727"-------------------------------------------------------------------------------
2728" Test 42: Catching number and string exceptions {{{1
2729"
2730" When a number is thrown, it is converted to a string exception.
2731" Numbers and strings may be caught by specifying a regular exception
2732" as argument to the :catch command.
2733"-------------------------------------------------------------------------------
2734
2735XpathINIT
2736
2737try
2738
2739 try
2740 Xpath 1 " X: 1
2741 throw 4711
2742 Xpath 2 " X: 0
2743 catch /4711/
2744 Xpath 4 " X: 4
2745 endtry
2746
2747 try
2748 Xpath 8 " X: 8
2749 throw 4711
2750 Xpath 16 " X: 0
2751 catch /^4711$/
2752 Xpath 32 " X: 32
2753 endtry
2754
2755 try
2756 Xpath 64 " X: 64
2757 throw 4711
2758 Xpath 128 " X: 0
2759 catch /\d/
2760 Xpath 256 " X: 256
2761 endtry
2762
2763 try
2764 Xpath 512 " X: 512
2765 throw 4711
2766 Xpath 1024 " X: 0
2767 catch /^\d\+$/
2768 Xpath 2048 " X: 2048
2769 endtry
2770
2771 try
2772 Xpath 4096 " X: 4096
2773 throw "arrgh"
2774 Xpath 8192 " X: 0
2775 catch /arrgh/
2776 Xpath 16384 " X: 16384
2777 endtry
2778
2779 try
2780 Xpath 32768 " X: 32768
2781 throw "arrgh"
2782 Xpath 65536 " X: 0
2783 catch /^arrgh$/
2784 Xpath 131072 " X: 131072
2785 endtry
2786
2787 try
2788 Xpath 262144 " X: 262144
2789 throw "arrgh"
2790 Xpath 524288 " X: 0
2791 catch /\l/
2792 Xpath 1048576 " X: 1048576
2793 endtry
2794
2795 try
2796 Xpath 2097152 " X: 2097152
2797 throw "arrgh"
2798 Xpath 4194304 " X: 0
2799 catch /^\l\+$/
2800 Xpath 8388608 " X: 8388608
2801 endtry
2802
2803 try
2804 try
2805 Xpath 16777216 " X: 16777216
2806 throw "ARRGH"
2807 Xpath 33554432 " X: 0
2808 catch /^arrgh$/
2809 Xpath 67108864 " X: 0
2810 endtry
2811 catch /^\carrgh$/
2812 Xpath 134217728 " X: 134217728
2813 endtry
2814
2815 try
2816 Xpath 268435456 " X: 268435456
2817 throw ""
2818 Xpath 536870912 " X: 0
2819 catch /^$/
2820 Xpath 1073741824 " X: 1073741824
2821 endtry
2822
2823catch /.*/
2824 " The Xpath command does not accept 2^31 (negative); add explicitly:
2825 let Xpath = Xpath + 2147483648 " X: 0
2826 Xout v:exception "in" v:throwpoint
2827endtry
2828
2829Xcheck 1505155949
2830
2831
2832"-------------------------------------------------------------------------------
2833" Test 43: Selecting the correct :catch clause {{{1
2834"
2835" When an exception is thrown and there are multiple :catch clauses,
2836" the first matching one is taken.
2837"-------------------------------------------------------------------------------
2838
2839XpathINIT
2840
2841XloopINIT 1 1024
2842let loops = 3
2843while loops > 0
2844 try
2845 if loops == 3
2846 Xloop 1 " X: 1
2847 throw "a"
2848 Xloop 2 " X: 0
2849 elseif loops == 2
2850 Xloop 4 " X: 4*1024
2851 throw "ab"
2852 Xloop 8 " X: 0
2853 elseif loops == 1
2854 Xloop 16 " X: 16*1024*1024
2855 throw "abc"
2856 Xloop 32 " X: 0
2857 endif
2858 catch /abc/
2859 Xloop 64 " X: 64*1024*1024
2860 catch /ab/
2861 Xloop 128 " X: 128*1024
2862 catch /.*/
2863 Xloop 256 " X: 256
2864 catch /a/
2865 Xloop 512 " X: 0
2866 endtry
2867
2868 let loops = loops - 1
2869 XloopNEXT
2870endwhile
2871Xpath 1073741824 " X: 1073741824
2872
2873unlet loops
2874
2875Xcheck 1157763329
2876
2877
2878"-------------------------------------------------------------------------------
2879" Test 44: Missing or empty :catch patterns {{{1
2880"
2881" A missing or empty :catch pattern means the same as /.*/, that is,
2882" catches everything. To catch only empty exceptions, /^$/ must be
2883" used. A :catch with missing, empty, or /.*/ argument also works
2884" when followed by another command separated by a bar on the same
2885" line. :catch patterns cannot be specified between ||. But other
2886" pattern separators can be used instead of //.
2887"-------------------------------------------------------------------------------
2888
2889XpathINIT
2890
2891try
2892 try
2893 Xpath 1 " X: 1
2894 throw ""
2895 catch /^$/
2896 Xpath 2 " X: 2
2897 endtry
2898
2899 try
2900 Xpath 4 " X: 4
2901 throw ""
2902 catch /.*/
2903 Xpath 8 " X: 8
2904 endtry
2905
2906 try
2907 Xpath 16 " X: 16
2908 throw ""
2909 catch //
2910 Xpath 32 " X: 32
2911 endtry
2912
2913 try
2914 Xpath 64 " X: 64
2915 throw ""
2916 catch
2917 Xpath 128 " X: 128
2918 endtry
2919
2920 try
2921 Xpath 256 " X: 256
2922 throw "oops"
2923 catch /^$/
2924 Xpath 512 " X: 0
2925 catch /.*/
2926 Xpath 1024 " X: 1024
2927 endtry
2928
2929 try
2930 Xpath 2048 " X: 2048
2931 throw "arrgh"
2932 catch /^$/
2933 Xpath 4096 " X: 0
2934 catch //
2935 Xpath 8192 " X: 8192
2936 endtry
2937
2938 try
2939 Xpath 16384 " X: 16384
2940 throw "brrr"
2941 catch /^$/
2942 Xpath 32768 " X: 0
2943 catch
2944 Xpath 65536 " X: 65536
2945 endtry
2946
2947 try | Xpath 131072 | throw "x" | catch /.*/ | Xpath 262144 | endtry
2948 " X: 131072 + 262144
2949
2950 try | Xpath 524288 | throw "y" | catch // | Xpath 1048576 | endtry
2951 " X: 524288 + 1048576
2952
2953 while 1
2954 try
2955 let caught = 0
2956 let v:errmsg = ""
2957 " Extra try level: if ":catch" without arguments below raises
2958 " a syntax error because it misinterprets the "Xpath" as a pattern,
2959 " let it be caught by the ":catch /.*/" below.
2960 try
2961 try | Xpath 2097152 | throw "z" | catch | Xpath 4194304 | :
2962 endtry " X: 2097152 + 4194304
2963 endtry
2964 catch /.*/
2965 let caught = 1
2966 Xout v:exception "in" v:throwpoint
2967 finally
2968 if $VIMNOERRTHROW && v:errmsg != ""
2969 Xout v:errmsg
2970 endif
2971 if caught || $VIMNOERRTHROW && v:errmsg != ""
2972 Xpath 8388608 " X: 0
2973 endif
2974 break " discard error for $VIMNOERRTHROW
2975 endtry
2976 endwhile
2977
2978 let cologne = 4711
2979 try
2980 try
2981 Xpath 16777216 " X: 16777216
2982 throw "throw cologne"
2983 " Next lines catches all and throws 4711:
2984 catch |throw cologne|
2985 Xpath 33554432 " X: 0
2986 endtry
2987 catch /4711/
2988 Xpath 67108864 " X: 67108864
2989 endtry
2990
2991 try
2992 Xpath 134217728 " X: 134217728
2993 throw "plus"
2994 catch +plus+
2995 Xpath 268435456 " X: 268435456
2996 endtry
2997
2998 Xpath 536870912 " X: 536870912
2999catch /.*/
3000 Xpath 1073741824 " X: 0
3001 Xout v:exception "in" v:throwpoint
3002endtry
3003
3004unlet! caught cologne
3005
3006Xcheck 1031761407
3007
3008
3009"-------------------------------------------------------------------------------
3010" Test 45: Catching exceptions from nested :try blocks {{{1
3011"
3012" When :try blocks are nested, an exception is caught by the innermost
3013" try conditional that has a matching :catch clause.
3014"-------------------------------------------------------------------------------
3015
3016XpathINIT
3017
3018XloopINIT 1 1024
3019let loops = 3
3020while loops > 0
3021 try
3022 try
3023 try
3024 try
3025 if loops == 3
3026 Xloop 1 " X: 1
3027 throw "a"
3028 Xloop 2 " X: 0
3029 elseif loops == 2
3030 Xloop 4 " X: 4*1024
3031 throw "ab"
3032 Xloop 8 " X: 0
3033 elseif loops == 1
3034 Xloop 16 " X: 16*1024*1024
3035 throw "abc"
3036 Xloop 32 " X: 0
3037 endif
3038 catch /abc/
3039 Xloop 64 " X: 64*1024*1024
3040 endtry
3041 catch /ab/
3042 Xloop 128 " X: 128*1024
3043 endtry
3044 catch /.*/
3045 Xloop 256 " X: 256
3046 endtry
3047 catch /a/
3048 Xloop 512 " X: 0
3049 endtry
3050
3051 let loops = loops - 1
3052 XloopNEXT
3053endwhile
3054Xpath 1073741824 " X: 1073741824
3055
3056unlet loops
3057
3058Xcheck 1157763329
3059
3060
3061"-------------------------------------------------------------------------------
3062" Test 46: Executing :finally after a :throw in nested :try {{{1
3063"
3064" When an exception is thrown from within nested :try blocks, the
3065" :finally clauses of the non-catching try conditionals should be
3066" executed before the matching :catch of the next surrounding :try
3067" gets the control. If this also has a :finally clause, it is
3068" executed afterwards.
3069"-------------------------------------------------------------------------------
3070
3071XpathINIT
3072
3073let sum = 0
3074
3075try
3076 Xpath 1 " X: 1
3077 try
3078 Xpath 2 " X: 2
3079 try
3080 Xpath 4 " X: 4
3081 try
3082 Xpath 8 " X: 8
3083 throw "ABC"
3084 Xpath 16 " X: 0
3085 catch /xyz/
3086 Xpath 32 " X: 0
3087 finally
3088 Xpath 64 " X: 64
3089 if sum != 0
3090 Xpath 128 " X: 0
3091 endif
3092 let sum = sum + 1
3093 endtry
3094 Xpath 256 " X: 0
3095 catch /123/
3096 Xpath 512 " X: 0
3097 catch /321/
3098 Xpath 1024 " X: 0
3099 finally
3100 Xpath 2048 " X: 2048
3101 if sum != 1
3102 Xpath 4096 " X: 0
3103 endif
3104 let sum = sum + 2
3105 endtry
3106 Xpath 8192 " X: 0
3107 finally
3108 Xpath 16384 " X: 16384
3109 if sum != 3
3110 Xpath 32768 " X: 0
3111 endif
3112 let sum = sum + 4
3113 endtry
3114 Xpath 65536 " X: 0
3115catch /ABC/
3116 Xpath 131072 " X: 131072
3117 if sum != 7
3118 Xpath 262144 " X: 0
3119 endif
3120 let sum = sum + 8
3121finally
3122 Xpath 524288 " X: 524288
3123 if sum != 15
3124 Xpath 1048576 " X: 0
3125 endif
3126 let sum = sum + 16
3127endtry
3128Xpath 65536 " X: 65536
3129if sum != 31
3130 Xpath 131072 " X: 0
3131endif
3132
3133unlet sum
3134
3135Xcheck 739407
3136
3137
3138"-------------------------------------------------------------------------------
3139" Test 47: Throwing exceptions from a :catch clause {{{1
3140"
3141" When an exception is thrown from a :catch clause, it should not be
3142" caught by a :catch of the same :try conditional. After executing
3143" the :finally clause (if present), surrounding try conditionals
3144" should be checked for a matching :catch.
3145"-------------------------------------------------------------------------------
3146
3147XpathINIT
3148
3149Xpath 1 " X: 1
3150try
3151 Xpath 2 " X: 2
3152 try
3153 Xpath 4 " X: 4
3154 try
3155 Xpath 8 " X: 8
3156 throw "x1"
3157 Xpath 16 " X: 0
3158 catch /x1/
3159 Xpath 32 " X: 32
3160 try
3161 Xpath 64 " X: 64
3162 throw "x2"
3163 Xpath 128 " X: 0
3164 catch /x1/
3165 Xpath 256 " X: 0
3166 catch /x2/
3167 Xpath 512 " X: 512
3168 try
3169 Xpath 1024 " X: 1024
3170 throw "x3"
3171 Xpath 2048 " X: 0
3172 catch /x1/
3173 Xpath 4096 " X: 0
3174 catch /x2/
3175 Xpath 8192 " X: 0
3176 finally
3177 Xpath 16384 " X: 16384
3178 endtry
3179 Xpath 32768 " X: 0
3180 catch /x3/
3181 Xpath 65536 " X: 0
3182 endtry
3183 Xpath 131072 " X: 0
3184 catch /x1/
3185 Xpath 262144 " X: 0
3186 catch /x2/
3187 Xpath 524288 " X: 0
3188 catch /x3/
3189 Xpath 1048576 " X: 0
3190 finally
3191 Xpath 2097152 " X: 2097152
3192 endtry
3193 Xpath 4194304 " X: 0
3194 catch /x1/
3195 Xpath 8388608 " X: 0
3196 catch /x2/
3197 Xpath 16777216 " X: 0
3198 catch /x3/
3199 Xpath 33554432 " X: 33554432
3200 endtry
3201 Xpath 67108864 " X: 67108864
3202catch /.*/
3203 Xpath 134217728 " X: 0
3204 Xout v:exception "in" v:throwpoint
3205endtry
3206Xpath 268435456 " X: 268435456
3207
3208Xcheck 371213935
3209
3210
3211"-------------------------------------------------------------------------------
3212" Test 48: Throwing exceptions from a :finally clause {{{1
3213"
3214" When an exception is thrown from a :finally clause, it should not be
3215" caught by a :catch of the same :try conditional. Surrounding try
3216" conditionals should be checked for a matching :catch. A previously
3217" thrown exception is discarded.
3218"-------------------------------------------------------------------------------
3219
3220XpathINIT
3221
3222try
3223
3224 try
3225 try
3226 Xpath 1 " X: 1
3227 catch /x1/
3228 Xpath 2 " X: 0
3229 finally
3230 Xpath 4 " X: 4
3231 throw "x1"
3232 Xpath 8 " X: 0
3233 endtry
3234 Xpath 16 " X: 0
3235 catch /x1/
3236 Xpath 32 " X: 32
3237 endtry
3238 Xpath 64 " X: 64
3239
3240 try
3241 try
3242 Xpath 128 " X: 128
3243 throw "x2"
3244 Xpath 256 " X: 0
3245 catch /x2/
3246 Xpath 512 " X: 512
3247 catch /x3/
3248 Xpath 1024 " X: 0
3249 finally
3250 Xpath 2048 " X: 2048
3251 throw "x3"
3252 Xpath 4096 " X: 0
3253 endtry
3254 Xpath 8192 " X: 0
3255 catch /x2/
3256 Xpath 16384 " X: 0
3257 catch /x3/
3258 Xpath 32768 " X: 32768
3259 endtry
3260 Xpath 65536 " X: 65536
3261
3262 try
3263 try
3264 try
3265 Xpath 131072 " X: 131072
3266 throw "x4"
3267 Xpath 262144 " X: 0
3268 catch /x5/
3269 Xpath 524288 " X: 0
3270 finally
3271 Xpath 1048576 " X: 1048576
3272 throw "x5" " discards "x4"
3273 Xpath 2097152 " X: 0
3274 endtry
3275 Xpath 4194304 " X: 0
3276 catch /x4/
3277 Xpath 8388608 " X: 0
3278 finally
3279 Xpath 16777216 " X: 16777216
3280 endtry
3281 Xpath 33554432 " X: 0
3282 catch /x5/
3283 Xpath 67108864 " X: 67108864
3284 endtry
3285 Xpath 134217728 " X: 134217728
3286
3287catch /.*/
3288 Xpath 268435456 " X: 0
3289 Xout v:exception "in" v:throwpoint
3290endtry
3291Xpath 536870912 " X: 536870912
3292
3293Xcheck 756255461
3294
3295
3296"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003297" Test 49: Throwing exceptions across functions {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00003298"
3299" When an exception is thrown but not caught inside a function, the
3300" caller is checked for a matching :catch clause.
3301"-------------------------------------------------------------------------------
3302
3303XpathINIT
3304
3305function! C()
3306 try
3307 Xpath 1 " X: 1
3308 throw "arrgh"
3309 Xpath 2 " X: 0
3310 catch /arrgh/
3311 Xpath 4 " X: 4
3312 endtry
3313 Xpath 8 " X: 8
3314endfunction
3315
3316XloopINIT! 16 16
3317
3318function! T1()
3319 XloopNEXT
3320 try
3321 Xloop 1 " X: 16 + 16*16
3322 throw "arrgh"
3323 Xloop 2 " X: 0
3324 finally
3325 Xloop 4 " X: 64 + 64*16
3326 endtry
3327 Xloop 8 " X: 0
3328endfunction
3329
3330function! T2()
3331 try
3332 Xpath 4096 " X: 4096
3333 call T1()
3334 Xpath 8192 " X: 0
3335 finally
3336 Xpath 16384 " X: 16384
3337 endtry
3338 Xpath 32768 " X: 0
3339endfunction
3340
3341try
3342 Xpath 65536 " X: 65536
3343 call C() " throw and catch
3344 Xpath 131072 " X: 131072
3345catch /.*/
3346 Xpath 262144 " X: 0
3347 Xout v:exception "in" v:throwpoint
3348endtry
3349
3350try
3351 Xpath 524288 " X: 524288
3352 call T1() " throw, one level
3353 Xpath 1048576 " X: 0
3354catch /arrgh/
3355 Xpath 2097152 " X: 2097152
3356catch /.*/
3357 Xpath 4194304 " X: 0
3358 Xout v:exception "in" v:throwpoint
3359endtry
3360
3361try
3362 Xpath 8388608 " X: 8388608
3363 call T2() " throw, two levels
3364 Xpath 16777216 " X: 0
3365catch /arrgh/
3366 Xpath 33554432 " X: 33554432
3367catch /.*/
3368 Xpath 67108864 " X: 0
3369 Xout v:exception "in" v:throwpoint
3370endtry
3371Xpath 134217728 " X: 134217728
3372
3373Xcheck 179000669
3374
3375" Leave C, T1, and T2 for execution as scripts in the next test.
3376
3377
3378"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003379" Test 50: Throwing exceptions across script files {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00003380"
3381" When an exception is thrown but not caught inside a script file,
3382" the sourcing script or function is checked for a matching :catch
3383" clause.
3384"
3385" This test executes the bodies of the functions C, T1, and T2 from
3386" the previous test as script files (:return replaced by :finish).
3387"-------------------------------------------------------------------------------
3388
3389XpathINIT
3390
3391let scriptC = MakeScript("C") " X: 1 + 4 + 8
3392delfunction C
3393
3394XloopINIT! 16 16
3395
3396let scriptT1 = MakeScript("T1") " X: 16 + 64 + 16*16 + 64*16
3397delfunction T1
3398
3399let scriptT2 = MakeScript("T2", scriptT1) " X: 4096 + 16384
3400delfunction T2
3401
3402function! F()
3403 try
3404 Xpath 65536 " X: 65536
3405 exec "source" g:scriptC
3406 Xpath 131072 " X: 131072
3407 catch /.*/
3408 Xpath 262144 " X: 0
3409 Xout v:exception "in" v:throwpoint
3410 endtry
3411
3412 try
3413 Xpath 524288 " X: 524288
3414 exec "source" g:scriptT1
3415 Xpath 1048576 " X: 0
3416 catch /arrgh/
3417 Xpath 2097152 " X: 2097152
3418 catch /.*/
3419 Xpath 4194304 " X: 0
3420 Xout v:exception "in" v:throwpoint
3421 endtry
3422endfunction
3423
3424try
3425 Xpath 8388608 " X: 8388608
3426 call F()
3427 Xpath 16777216 " X: 16777216
3428 exec "source" scriptT2
3429 Xpath 33554432 " X: 0
3430catch /arrgh/
3431 Xpath 67108864 " X: 67108864
3432catch /.*/
3433 Xpath 134217728 " X: 0
3434 Xout v:exception "in" v:throwpoint
3435endtry
3436Xpath 268435456 " X: 268435456
3437
3438call delete(scriptC)
3439call delete(scriptT1)
3440call delete(scriptT2)
3441unlet scriptC scriptT1 scriptT2
3442delfunction F
3443
3444Xcheck 363550045
3445
3446
3447"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003448" Test 51: Throwing exceptions across :execute and user commands {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00003449"
3450" A :throw command may be executed under an ":execute" or from
3451" a user command.
3452"-------------------------------------------------------------------------------
3453
3454XpathINIT
3455
3456command! -nargs=? THROW1 throw <args> | throw 1
3457command! -nargs=? THROW2 try | throw <args> | endtry | throw 2
3458command! -nargs=? THROW3 try | throw 3 | catch /3/ | throw <args> | endtry
3459command! -nargs=? THROW4 try | throw 4 | finally | throw <args> | endtry
3460
3461try
3462
3463 try
3464 try
3465 Xpath 1 " X: 1
3466 THROW1 "A"
3467 catch /A/
3468 Xpath 2 " X: 2
3469 endtry
3470 catch /1/
3471 Xpath 4 " X: 0
3472 endtry
3473
3474 try
3475 try
3476 Xpath 8 " X: 8
3477 THROW2 "B"
3478 catch /B/
3479 Xpath 16 " X: 16
3480 endtry
3481 catch /2/
3482 Xpath 32 " X: 0
3483 endtry
3484
3485 try
3486 try
3487 Xpath 64 " X: 64
3488 THROW3 "C"
3489 catch /C/
3490 Xpath 128 " X: 128
3491 endtry
3492 catch /3/
3493 Xpath 256 " X: 0
3494 endtry
3495
3496 try
3497 try
3498 Xpath 512 " X: 512
3499 THROW4 "D"
3500 catch /D/
3501 Xpath 1024 " X: 1024
3502 endtry
3503 catch /4/
3504 Xpath 2048 " X: 0
3505 endtry
3506
3507 try
3508 try
3509 Xpath 4096 " X: 4096
3510 execute 'throw "E" | throw 5'
3511 catch /E/
3512 Xpath 8192 " X: 8192
3513 endtry
3514 catch /5/
3515 Xpath 16384 " X: 0
3516 endtry
3517
3518 try
3519 try
3520 Xpath 32768 " X: 32768
3521 execute 'try | throw "F" | endtry | throw 6'
3522 catch /F/
3523 Xpath 65536 " X: 65536
3524 endtry
3525 catch /6/
3526 Xpath 131072 " X: 0
3527 endtry
3528
3529 try
3530 try
3531 Xpath 262144 " X: 262144
3532 execute'try | throw 7 | catch /7/ | throw "G" | endtry'
3533 catch /G/
3534 Xpath 524288 " X: 524288
3535 endtry
3536 catch /7/
3537 Xpath 1048576 " X: 0
3538 endtry
3539
3540 try
3541 try
3542 Xpath 2097152 " X: 2097152
3543 execute 'try | throw 8 | finally | throw "H" | endtry'
3544 catch /H/
3545 Xpath 4194304 " X: 4194304
3546 endtry
3547 catch /8/
3548 Xpath 8388608 " X: 0
3549 endtry
3550
3551catch /.*/
3552 Xpath 16777216 " X: 0
3553 Xout v:exception "in" v:throwpoint
3554endtry
3555
3556Xpath 33554432 " X: 33554432
3557
3558delcommand THROW1
3559delcommand THROW2
3560delcommand THROW3
3561delcommand THROW4
3562
3563Xcheck 40744667
3564
3565
3566"-------------------------------------------------------------------------------
3567" Test 52: Uncaught exceptions {{{1
3568"
3569" When an exception is thrown but not caught, an error message is
3570" displayed when the script is terminated. In case of an interrupt
3571" or error exception, the normal interrupt or error message(s) are
3572" displayed.
3573"-------------------------------------------------------------------------------
3574
3575XpathINIT
3576
3577let msgfile = tempname()
3578
3579function! MESSAGES(...)
3580 try
3581 exec "edit" g:msgfile
3582 catch /^Vim(edit):/
3583 return 0
3584 endtry
3585
3586 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
3587 let match = 1
3588 norm gg
3589
3590 let num = a:0 / 2
3591 let cnt = 1
3592 while cnt <= num
3593 let enr = a:{2*cnt - 1}
3594 let emsg= a:{2*cnt}
3595 let cnt = cnt + 1
3596
3597 if enr == ""
3598 Xout "TODO: Add message number for:" emsg
3599 elseif enr == "INT"
3600 let enr = ""
3601 endif
3602 if enr == "" && !english
3603 continue
3604 endif
3605 let pattern = (enr != "") ? enr . ':.*' : ''
3606 if english
3607 let pattern = pattern . emsg
3608 endif
3609 if !search(pattern, "W")
3610 let match = 0
3611 Xout "No match for:" pattern
3612 endif
3613 norm $
3614 endwhile
3615
3616 bwipeout!
3617 return match
3618endfunction
3619
3620if ExtraVim(msgfile)
3621 Xpath 1 " X: 1
3622 throw "arrgh"
3623endif
3624
3625Xpath 2 " X: 2
3626if !MESSAGES('E605', "Exception not caught")
3627 Xpath 4 " X: 0
3628endif
3629
3630if ExtraVim(msgfile)
3631 try
3632 Xpath 8 " X: 8
3633 throw "oops"
3634 catch /arrgh/
3635 Xpath 16 " X: 0
3636 endtry
3637 Xpath 32 " X: 0
3638endif
3639
3640Xpath 64 " X: 64
3641if !MESSAGES('E605', "Exception not caught")
3642 Xpath 128 " X: 0
3643endif
3644
3645if ExtraVim(msgfile)
3646 function! T()
3647 throw "brrr"
3648 endfunction
3649
3650 try
3651 Xpath 256 " X: 256
3652 throw "arrgh"
3653 catch /.*/
3654 Xpath 512 " X: 512
3655 call T()
3656 endtry
3657 Xpath 1024 " X: 0
3658endif
3659
3660Xpath 2048 " X: 2048
3661if !MESSAGES('E605', "Exception not caught")
3662 Xpath 4096 " X: 0
3663endif
3664
3665if ExtraVim(msgfile)
3666 try
3667 Xpath 8192 " X: 8192
3668 throw "arrgh"
3669 finally
3670 Xpath 16384 " X: 16384
3671 throw "brrr"
3672 endtry
3673 Xpath 32768 " X: 0
3674endif
3675
3676Xpath 65536 " X: 65536
3677if !MESSAGES('E605', "Exception not caught")
3678 Xpath 131072 " X: 0
3679endif
3680
3681if ExtraVim(msgfile)
3682 try
3683 Xpath 262144 " X: 262144
3684 "INTERRUPT
3685 endtry
3686 Xpath 524288 " X: 0
3687endif
3688
3689Xpath 1048576 " X: 1048576
3690if !MESSAGES('INT', "Interrupted")
3691 Xpath 2097152 " X: 0
3692endif
3693
3694if ExtraVim(msgfile)
3695 try
3696 Xpath 4194304 " X: 4194304
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01003697 let x = novar " error E121; exception: E121
Bram Moolenaar071d4272004-06-13 20:20:40 +00003698 catch /E15:/ " should not catch
3699 Xpath 8388608 " X: 0
3700 endtry
3701 Xpath 16777216 " X: 0
3702endif
3703
3704Xpath 33554432 " X: 33554432
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01003705if !MESSAGES('E121', "Undefined variable")
Bram Moolenaar071d4272004-06-13 20:20:40 +00003706 Xpath 67108864 " X: 0
3707endif
3708
3709if ExtraVim(msgfile)
3710 try
3711 Xpath 134217728 " X: 134217728
3712" unlet novar # " error E108/E488; exception: E488
3713 catch /E108:/ " should not catch
3714 Xpath 268435456 " X: 0
3715 endtry
3716 Xpath 536870912 " X: 0
3717endif
3718
3719Xpath 1073741824 " X: 1073741824
3720if !MESSAGES('E108', "No such variable", 'E488', "Trailing characters")
3721 " The Xpath command does not accept 2^31 (negative); add explicitly:
3722 let Xpath = Xpath + 2147483648 " X: 0
3723endif
3724
3725call delete(msgfile)
3726unlet msgfile
3727
3728Xcheck 1247112011
3729
3730" Leave MESSAGES() for the next tests.
3731
3732
3733"-------------------------------------------------------------------------------
3734" Test 53: Nesting errors: :endif/:else/:elseif {{{1
3735"
3736" For nesting errors of :if conditionals the correct error messages
3737" should be given.
3738"
3739" This test reuses the function MESSAGES() from the previous test.
3740" This functions checks the messages in g:msgfile.
3741"-------------------------------------------------------------------------------
3742
3743XpathINIT
3744
3745let msgfile = tempname()
3746
3747if ExtraVim(msgfile)
3748" endif
3749endif
3750if MESSAGES('E580', ":endif without :if")
3751 Xpath 1 " X: 1
3752endif
3753
3754if ExtraVim(msgfile)
3755" while 1
3756" endif
3757" endwhile
3758endif
3759if MESSAGES('E580', ":endif without :if")
3760 Xpath 2 " X: 2
3761endif
3762
3763if ExtraVim(msgfile)
3764" try
3765" finally
3766" endif
3767" endtry
3768endif
3769if MESSAGES('E580', ":endif without :if")
3770 Xpath 4 " X: 4
3771endif
3772
3773if ExtraVim(msgfile)
3774" try
3775" endif
3776" endtry
3777endif
3778if MESSAGES('E580', ":endif without :if")
3779 Xpath 8 " X: 8
3780endif
3781
3782if ExtraVim(msgfile)
3783" try
3784" throw "a"
3785" catch /a/
3786" endif
3787" endtry
3788endif
3789if MESSAGES('E580', ":endif without :if")
3790 Xpath 16 " X: 16
3791endif
3792
3793if ExtraVim(msgfile)
3794" else
3795endif
3796if MESSAGES('E581', ":else without :if")
3797 Xpath 32 " X: 32
3798endif
3799
3800if ExtraVim(msgfile)
3801" while 1
3802" else
3803" endwhile
3804endif
3805if MESSAGES('E581', ":else without :if")
3806 Xpath 64 " X: 64
3807endif
3808
3809if ExtraVim(msgfile)
3810" try
3811" finally
3812" else
3813" endtry
3814endif
3815if MESSAGES('E581', ":else without :if")
3816 Xpath 128 " X: 128
3817endif
3818
3819if ExtraVim(msgfile)
3820" try
3821" else
3822" endtry
3823endif
3824if MESSAGES('E581', ":else without :if")
3825 Xpath 256 " X: 256
3826endif
3827
3828if ExtraVim(msgfile)
3829" try
3830" throw "a"
3831" catch /a/
3832" else
3833" endtry
3834endif
3835if MESSAGES('E581', ":else without :if")
3836 Xpath 512 " X: 512
3837endif
3838
3839if ExtraVim(msgfile)
3840" elseif
3841endif
3842if MESSAGES('E582', ":elseif without :if")
3843 Xpath 1024 " X: 1024
3844endif
3845
3846if ExtraVim(msgfile)
3847" while 1
3848" elseif
3849" endwhile
3850endif
3851if MESSAGES('E582', ":elseif without :if")
3852 Xpath 2048 " X: 2048
3853endif
3854
3855if ExtraVim(msgfile)
3856" try
3857" finally
3858" elseif
3859" endtry
3860endif
3861if MESSAGES('E582', ":elseif without :if")
3862 Xpath 4096 " X: 4096
3863endif
3864
3865if ExtraVim(msgfile)
3866" try
3867" elseif
3868" endtry
3869endif
3870if MESSAGES('E582', ":elseif without :if")
3871 Xpath 8192 " X: 8192
3872endif
3873
3874if ExtraVim(msgfile)
3875" try
3876" throw "a"
3877" catch /a/
3878" elseif
3879" endtry
3880endif
3881if MESSAGES('E582', ":elseif without :if")
3882 Xpath 16384 " X: 16384
3883endif
3884
3885if ExtraVim(msgfile)
3886" if 1
3887" else
3888" else
3889" endif
3890endif
3891if MESSAGES('E583', "multiple :else")
3892 Xpath 32768 " X: 32768
3893endif
3894
3895if ExtraVim(msgfile)
3896" if 1
3897" else
3898" elseif 1
3899" endif
3900endif
3901if MESSAGES('E584', ":elseif after :else")
3902 Xpath 65536 " X: 65536
3903endif
3904
3905call delete(msgfile)
3906unlet msgfile
3907
3908Xcheck 131071
3909
3910" Leave MESSAGES() for the next test.
3911
3912
3913"-------------------------------------------------------------------------------
3914" Test 54: Nesting errors: :while/:endwhile {{{1
3915"
3916" For nesting errors of :while conditionals the correct error messages
3917" should be given.
3918"
3919" This test reuses the function MESSAGES() from the previous test.
3920" This functions checks the messages in g:msgfile.
3921"-------------------------------------------------------------------------------
3922
3923XpathINIT
3924
3925let msgfile = tempname()
3926
3927if ExtraVim(msgfile)
3928" endwhile
3929endif
3930if MESSAGES('E588', ":endwhile without :while")
3931 Xpath 1 " X: 1
3932endif
3933
3934if ExtraVim(msgfile)
3935" if 1
3936" endwhile
3937" endif
3938endif
3939if MESSAGES('E588', ":endwhile without :while")
3940 Xpath 2 " X: 2
3941endif
3942
3943if ExtraVim(msgfile)
3944" while 1
3945" if 1
3946" endwhile
3947endif
3948if MESSAGES('E171', "Missing :endif")
3949 Xpath 4 " X: 4
3950endif
3951
3952if ExtraVim(msgfile)
3953" try
3954" finally
3955" endwhile
3956" endtry
3957endif
3958if MESSAGES('E588', ":endwhile without :while")
3959 Xpath 8 " X: 8
3960endif
3961
3962if ExtraVim(msgfile)
3963" while 1
3964" try
3965" finally
3966" endwhile
3967endif
3968if MESSAGES('E600', "Missing :endtry")
3969 Xpath 16 " X: 16
3970endif
3971
3972if ExtraVim(msgfile)
3973" while 1
3974" if 1
3975" try
3976" finally
3977" endwhile
3978endif
3979if MESSAGES('E600', "Missing :endtry")
3980 Xpath 32 " X: 32
3981endif
3982
3983if ExtraVim(msgfile)
3984" while 1
3985" try
3986" finally
3987" if 1
3988" endwhile
3989endif
3990if MESSAGES('E171', "Missing :endif")
3991 Xpath 64 " X: 64
3992endif
3993
3994if ExtraVim(msgfile)
3995" try
3996" endwhile
3997" endtry
3998endif
3999if MESSAGES('E588', ":endwhile without :while")
4000 Xpath 128 " X: 128
4001endif
4002
4003if ExtraVim(msgfile)
4004" while 1
4005" try
4006" endwhile
4007" endtry
4008" endwhile
4009endif
4010if MESSAGES('E588', ":endwhile without :while")
4011 Xpath 256 " X: 256
4012endif
4013
4014if ExtraVim(msgfile)
4015" try
4016" throw "a"
4017" catch /a/
4018" endwhile
4019" endtry
4020endif
4021if MESSAGES('E588', ":endwhile without :while")
4022 Xpath 512 " X: 512
4023endif
4024
4025if ExtraVim(msgfile)
4026" while 1
4027" try
4028" throw "a"
4029" catch /a/
4030" endwhile
4031" endtry
4032" endwhile
4033endif
4034if MESSAGES('E588', ":endwhile without :while")
4035 Xpath 1024 " X: 1024
4036endif
4037
4038
4039call delete(msgfile)
4040unlet msgfile
4041
4042Xcheck 2047
4043
4044" Leave MESSAGES() for the next test.
4045
4046
4047"-------------------------------------------------------------------------------
4048" Test 55: Nesting errors: :continue/:break {{{1
4049"
4050" For nesting errors of :continue and :break commands the correct
4051" error messages should be given.
4052"
4053" This test reuses the function MESSAGES() from the previous test.
4054" This functions checks the messages in g:msgfile.
4055"-------------------------------------------------------------------------------
4056
4057XpathINIT
4058
4059let msgfile = tempname()
4060
4061if ExtraVim(msgfile)
4062" continue
4063endif
4064if MESSAGES('E586', ":continue without :while")
4065 Xpath 1 " X: 1
4066endif
4067
4068if ExtraVim(msgfile)
4069" if 1
4070" continue
4071" endif
4072endif
4073if MESSAGES('E586', ":continue without :while")
4074 Xpath 2 " X: 2
4075endif
4076
4077if ExtraVim(msgfile)
4078" try
4079" finally
4080" continue
4081" endtry
4082endif
4083if MESSAGES('E586', ":continue without :while")
4084 Xpath 4 " X: 4
4085endif
4086
4087if ExtraVim(msgfile)
4088" try
4089" continue
4090" endtry
4091endif
4092if MESSAGES('E586', ":continue without :while")
4093 Xpath 8 " X: 8
4094endif
4095
4096if ExtraVim(msgfile)
4097" try
4098" throw "a"
4099" catch /a/
4100" continue
4101" endtry
4102endif
4103if MESSAGES('E586', ":continue without :while")
4104 Xpath 16 " X: 16
4105endif
4106
4107if ExtraVim(msgfile)
4108" break
4109endif
4110if MESSAGES('E587', ":break without :while")
4111 Xpath 32 " X: 32
4112endif
4113
4114if ExtraVim(msgfile)
4115" if 1
4116" break
4117" endif
4118endif
4119if MESSAGES('E587', ":break without :while")
4120 Xpath 64 " X: 64
4121endif
4122
4123if ExtraVim(msgfile)
4124" try
4125" finally
4126" break
4127" endtry
4128endif
4129if MESSAGES('E587', ":break without :while")
4130 Xpath 128 " X: 128
4131endif
4132
4133if ExtraVim(msgfile)
4134" try
4135" break
4136" endtry
4137endif
4138if MESSAGES('E587', ":break without :while")
4139 Xpath 256 " X: 256
4140endif
4141
4142if ExtraVim(msgfile)
4143" try
4144" throw "a"
4145" catch /a/
4146" break
4147" endtry
4148endif
4149if MESSAGES('E587', ":break without :while")
4150 Xpath 512 " X: 512
4151endif
4152
4153call delete(msgfile)
4154unlet msgfile
4155
4156Xcheck 1023
4157
4158" Leave MESSAGES() for the next test.
4159
4160
4161"-------------------------------------------------------------------------------
4162" Test 56: Nesting errors: :endtry {{{1
4163"
4164" For nesting errors of :try conditionals the correct error messages
4165" should be given.
4166"
4167" This test reuses the function MESSAGES() from the previous test.
4168" This functions checks the messages in g:msgfile.
4169"-------------------------------------------------------------------------------
4170
4171XpathINIT
4172
4173let msgfile = tempname()
4174
4175if ExtraVim(msgfile)
4176" endtry
4177endif
4178if MESSAGES('E602', ":endtry without :try")
4179 Xpath 1 " X: 1
4180endif
4181
4182if ExtraVim(msgfile)
4183" if 1
4184" endtry
4185" endif
4186endif
4187if MESSAGES('E602', ":endtry without :try")
4188 Xpath 2 " X: 2
4189endif
4190
4191if ExtraVim(msgfile)
4192" while 1
4193" endtry
4194" endwhile
4195endif
4196if MESSAGES('E602', ":endtry without :try")
4197 Xpath 4 " X: 4
4198endif
4199
4200if ExtraVim(msgfile)
4201" try
4202" if 1
4203" endtry
4204endif
4205if MESSAGES('E171', "Missing :endif")
4206 Xpath 8 " X: 8
4207endif
4208
4209if ExtraVim(msgfile)
4210" try
4211" while 1
4212" endtry
4213endif
4214if MESSAGES('E170', "Missing :endwhile")
4215 Xpath 16 " X: 16
4216endif
4217
4218if ExtraVim(msgfile)
4219" try
4220" finally
4221" if 1
4222" endtry
4223endif
4224if MESSAGES('E171', "Missing :endif")
4225 Xpath 32 " X: 32
4226endif
4227
4228if ExtraVim(msgfile)
4229" try
4230" finally
4231" while 1
4232" endtry
4233endif
4234if MESSAGES('E170', "Missing :endwhile")
4235 Xpath 64 " X: 64
4236endif
4237
4238if ExtraVim(msgfile)
4239" try
4240" throw "a"
4241" catch /a/
4242" if 1
4243" endtry
4244endif
4245if MESSAGES('E171', "Missing :endif")
4246 Xpath 128 " X: 128
4247endif
4248
4249if ExtraVim(msgfile)
4250" try
4251" throw "a"
4252" catch /a/
4253" while 1
4254" endtry
4255endif
4256if MESSAGES('E170', "Missing :endwhile")
4257 Xpath 256 " X: 256
4258endif
4259
4260call delete(msgfile)
4261unlet msgfile
4262
4263delfunction MESSAGES
4264
4265Xcheck 511
4266
4267
4268"-------------------------------------------------------------------------------
4269" Test 57: v:exception and v:throwpoint for user exceptions {{{1
4270"
4271" v:exception evaluates to the value of the exception that was caught
4272" most recently and is not finished. (A caught exception is finished
4273" when the next ":catch", ":finally", or ":endtry" is reached.)
4274" v:throwpoint evaluates to the script/function name and line number
4275" where that exception has been thrown.
4276"-------------------------------------------------------------------------------
4277
4278XpathINIT
4279
4280function! FuncException()
4281 let g:exception = v:exception
4282endfunction
4283
4284function! FuncThrowpoint()
4285 let g:throwpoint = v:throwpoint
4286endfunction
4287
4288let scriptException = MakeScript("FuncException")
4289let scriptThrowPoint = MakeScript("FuncThrowpoint")
4290
4291command! CmdException let g:exception = v:exception
4292command! CmdThrowpoint let g:throwpoint = v:throwpoint
4293
4294XloopINIT! 1 2
4295
4296function! CHECK(n, exception, throwname, throwline)
4297 XloopNEXT
4298 let error = 0
4299 if v:exception != a:exception
4300 Xout a:n.": v:exception is" v:exception "instead of" a:exception
4301 let error = 1
4302 endif
4303 if v:throwpoint !~ a:throwname
4304 let name = escape(a:throwname, '\')
4305 Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" name
4306 let error = 1
4307 endif
4308 if v:throwpoint !~ a:throwline
4309 let line = escape(a:throwline, '\')
4310 Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
4311 let error = 1
4312 endif
4313 if error
4314 Xloop 1 " X: 0
4315 endif
4316endfunction
4317
4318function! T(arg, line)
4319 if a:line == 2
4320 throw a:arg " in line 2
4321 elseif a:line == 4
4322 throw a:arg " in line 4
4323 elseif a:line == 6
4324 throw a:arg " in line 6
4325 elseif a:line == 8
4326 throw a:arg " in line 8
4327 endif
4328endfunction
4329
4330function! G(arg, line)
4331 call T(a:arg, a:line)
4332endfunction
4333
4334function! F(arg, line)
4335 call G(a:arg, a:line)
4336endfunction
4337
4338let scriptT = MakeScript("T")
4339let scriptG = MakeScript("G", scriptT)
4340let scriptF = MakeScript("F", scriptG)
4341
4342try
4343 Xpath 32768 " X: 32768
4344 call F("oops", 2)
4345catch /.*/
4346 Xpath 65536 " X: 65536
4347 let exception = v:exception
4348 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02004349 call CHECK(1, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00004350 exec "let exception = v:exception"
4351 exec "let throwpoint = v:throwpoint"
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02004352 call CHECK(2, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00004353 CmdException
4354 CmdThrowpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02004355 call CHECK(3, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00004356 call FuncException()
4357 call FuncThrowpoint()
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02004358 call CHECK(4, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00004359 exec "source" scriptException
4360 exec "source" scriptThrowPoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02004361 call CHECK(5, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00004362 try
4363 Xpath 131072 " X: 131072
4364 call G("arrgh", 4)
4365 catch /.*/
4366 Xpath 262144 " X: 262144
4367 let exception = v:exception
4368 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02004369 call CHECK(6, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00004370 try
4371 Xpath 524288 " X: 524288
4372 let g:arg = "autsch"
4373 let g:line = 6
4374 exec "source" scriptF
4375 catch /.*/
4376 Xpath 1048576 " X: 1048576
4377 let exception = v:exception
4378 let throwpoint = v:throwpoint
4379 " Symbolic links in tempname()s are not resolved, whereas resolving
4380 " is done for v:throwpoint. Resolve the temporary file name for
4381 " scriptT, so that it can be matched against v:throwpoint.
4382 call CHECK(7, "autsch", resolve(scriptT), '\<6\>')
4383 finally
4384 Xpath 2097152 " X: 2097152
4385 let exception = v:exception
4386 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02004387 call CHECK(8, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00004388 try
4389 Xpath 4194304 " X: 4194304
4390 let g:arg = "brrrr"
4391 let g:line = 8
4392 exec "source" scriptG
4393 catch /.*/
4394 Xpath 8388608 " X: 8388608
4395 let exception = v:exception
4396 let throwpoint = v:throwpoint
4397 " Resolve scriptT for matching it against v:throwpoint.
4398 call CHECK(9, "brrrr", resolve(scriptT), '\<8\>')
4399 finally
4400 Xpath 16777216 " X: 16777216
4401 let exception = v:exception
4402 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02004403 call CHECK(10, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00004404 endtry
4405 Xpath 33554432 " X: 33554432
4406 let exception = v:exception
4407 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02004408 call CHECK(11, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00004409 endtry
4410 Xpath 67108864 " X: 67108864
4411 let exception = v:exception
4412 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02004413 call CHECK(12, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00004414 finally
4415 Xpath 134217728 " X: 134217728
4416 let exception = v:exception
4417 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02004418 call CHECK(13, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00004419 endtry
4420 Xpath 268435456 " X: 268435456
4421 let exception = v:exception
4422 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02004423 call CHECK(14, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00004424finally
4425 Xpath 536870912 " X: 536870912
4426 let exception = v:exception
4427 let throwpoint = v:throwpoint
4428 call CHECK(15, "", '^$', '^$')
4429endtry
4430
4431Xpath 1073741824 " X: 1073741824
4432
4433unlet exception throwpoint
4434delfunction FuncException
4435delfunction FuncThrowpoint
4436call delete(scriptException)
4437call delete(scriptThrowPoint)
4438unlet scriptException scriptThrowPoint
4439delcommand CmdException
4440delcommand CmdThrowpoint
4441delfunction T
4442delfunction G
4443delfunction F
4444call delete(scriptT)
4445call delete(scriptG)
4446call delete(scriptF)
4447unlet scriptT scriptG scriptF
4448
4449Xcheck 2147450880
4450
4451
4452"-------------------------------------------------------------------------------
4453"
4454" Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1
4455"
4456" v:exception and v:throwpoint work also for error and interrupt
4457" exceptions.
4458"-------------------------------------------------------------------------------
4459
4460XpathINIT
4461
4462if ExtraVim()
4463
4464 function! T(line)
4465 if a:line == 2
4466 delfunction T " error (function in use) in line 2
4467 elseif a:line == 4
4468 let dummy = 0 " INTERRUPT1 - interrupt in line 4
4469 endif
4470 endfunction
4471
4472 while 1
4473 try
4474 Xpath 1 " X: 1
4475 let caught = 0
4476 call T(2)
4477 catch /.*/
4478 let caught = 1
4479 if v:exception !~ 'Vim(delfunction):'
4480 Xpath 2 " X: 0
4481 endif
4482 if v:throwpoint !~ '\<T\>'
4483 Xpath 4 " X: 0
4484 endif
4485 if v:throwpoint !~ '\<2\>'
4486 Xpath 8 " X: 0
4487 endif
4488 finally
4489 Xpath 16 " X: 16
4490 if caught || $VIMNOERRTHROW
4491 Xpath 32 " X: 32
4492 endif
4493 if v:exception != ""
4494 Xpath 64 " X: 0
4495 endif
4496 if v:throwpoint != ""
4497 Xpath 128 " X: 0
4498 endif
4499 break " discard error for $VIMNOERRTHROW
4500 endtry
4501 endwhile
4502
4503 Xpath 256 " X: 256
4504 if v:exception != ""
4505 Xpath 512 " X: 0
4506 endif
4507 if v:throwpoint != ""
4508 Xpath 1024 " X: 0
4509 endif
4510
4511 while 1
4512 try
4513 Xpath 2048 " X: 2048
4514 let caught = 0
4515 call T(4)
4516 catch /.*/
4517 let caught = 1
4518 if v:exception != 'Vim:Interrupt'
4519 Xpath 4096 " X: 0
4520 endif
4521 if v:throwpoint !~ '\<T\>'
4522 Xpath 8192 " X: 0
4523 endif
4524 if v:throwpoint !~ '\<4\>'
4525 Xpath 16384 " X: 0
4526 endif
4527 finally
4528 Xpath 32768 " X: 32768
4529 if caught || $VIMNOINTTHROW
4530 Xpath 65536 " X: 65536
4531 endif
4532 if v:exception != ""
4533 Xpath 131072 " X: 0
4534 endif
4535 if v:throwpoint != ""
4536 Xpath 262144 " X: 0
4537 endif
4538 break " discard error for $VIMNOERRTHROW
4539 endtry
4540 endwhile
4541
4542 Xpath 524288 " X: 524288
4543 if v:exception != ""
4544 Xpath 1048576 " X: 0
4545 endif
4546 if v:throwpoint != ""
4547 Xpath 2097152 " X: 0
4548 endif
4549
4550endif
4551
4552Xcheck 624945
4553
4554
4555"-------------------------------------------------------------------------------
4556"
4557" Test 59: v:exception and v:throwpoint when discarding exceptions {{{1
4558"
4559" When a :catch clause is left by a ":break" etc or an error or
4560" interrupt exception, v:exception and v:throwpoint are reset. They
4561" are not affected by an exception that is discarded before being
4562" caught.
4563"-------------------------------------------------------------------------------
4564
4565XpathINIT
4566
4567if ExtraVim()
4568
4569 XloopINIT! 1 2
4570
4571 let sfile = expand("<sfile>")
4572
4573 function! LineNumber()
4574 return substitute(substitute(v:throwpoint, g:sfile, '', ""),
4575 \ '\D*\(\d*\).*', '\1', "")
4576 endfunction
4577
4578 command! -nargs=1 SetLineNumber
4579 \ try | throw "line" | catch /.*/ | let <args> = LineNumber() | endtry
4580
4581 " Check v:exception/v:throwpoint against second/fourth parameter if
4582 " specified, check for being empty else.
4583 function! CHECK(n, ...)
4584 XloopNEXT
4585 let exception = a:0 != 0 ? a:1 : "" " second parameter (optional)
4586 let emsg = a:0 != 0 ? a:2 : "" " third parameter (optional)
4587 let line = a:0 != 0 ? a:3 : 0 " fourth parameter (optional)
4588 let error = 0
4589 if emsg != ""
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004590 " exception is the error number, emsg the English error message text
Bram Moolenaar071d4272004-06-13 20:20:40 +00004591 if exception !~ '^E\d\+$'
4592 Xout "TODO: Add message number for:" emsg
4593 elseif v:lang == "C" || v:lang =~ '^[Ee]n'
4594 if exception == "E492" && emsg == "Not an editor command"
4595 let exception = '^Vim:' . exception . ': ' . emsg
4596 else
4597 let exception = '^Vim(\a\+):' . exception . ': ' . emsg
4598 endif
4599 else
4600 if exception == "E492"
4601 let exception = '^Vim:' . exception
4602 else
4603 let exception = '^Vim(\a\+):' . exception
4604 endif
4605 endif
4606 endif
4607 if exception == "" && v:exception != ""
4608 Xout a:n.": v:exception is set:" v:exception
4609 let error = 1
4610 elseif exception != "" && v:exception !~ exception
4611 Xout a:n.": v:exception (".v:exception.") does not match" exception
4612 let error = 1
4613 endif
4614 if line == 0 && v:throwpoint != ""
4615 Xout a:n.": v:throwpoint is set:" v:throwpoint
4616 let error = 1
4617 elseif line != 0 && v:throwpoint !~ '\<' . line . '\>'
4618 Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
4619 let error = 1
4620 endif
4621 if !error
4622 Xloop 1 " X: 2097151
4623 endif
4624 endfunction
4625
4626 while 1
4627 try
4628 throw "x1"
4629 catch /.*/
4630 break
4631 endtry
4632 endwhile
4633 call CHECK(1)
4634
4635 while 1
4636 try
4637 throw "x2"
4638 catch /.*/
4639 break
4640 finally
4641 call CHECK(2)
4642 endtry
4643 break
4644 endwhile
4645 call CHECK(3)
4646
4647 while 1
4648 try
4649 let errcaught = 0
4650 try
4651 try
4652 throw "x3"
4653 catch /.*/
4654 SetLineNumber line_before_error
4655 asdf
4656 endtry
4657 catch /.*/
4658 let errcaught = 1
4659 call CHECK(4, 'E492', "Not an editor command",
4660 \ line_before_error + 1)
4661 endtry
4662 finally
4663 if !errcaught && $VIMNOERRTHROW
4664 call CHECK(4)
4665 endif
4666 break " discard error for $VIMNOERRTHROW
4667 endtry
4668 endwhile
4669 call CHECK(5)
4670
4671 Xpath 2097152 " X: 2097152
4672
4673 while 1
4674 try
4675 let intcaught = 0
4676 try
4677 try
4678 throw "x4"
4679 catch /.*/
4680 SetLineNumber two_lines_before_interrupt
4681 "INTERRUPT
4682 let dummy = 0
4683 endtry
4684 catch /.*/
4685 let intcaught = 1
4686 call CHECK(6, "Vim:Interrupt", '',
4687 \ two_lines_before_interrupt + 2)
4688 endtry
4689 finally
4690 if !intcaught && $VIMNOINTTHROW
4691 call CHECK(6)
4692 endif
4693 break " discard interrupt for $VIMNOINTTHROW
4694 endtry
4695 endwhile
4696 call CHECK(7)
4697
4698 Xpath 4194304 " X: 4194304
4699
4700 while 1
4701 try
4702 let errcaught = 0
4703 try
4704 try
4705" if 1
4706 SetLineNumber line_before_throw
4707 throw "x5"
4708 " missing endif
4709 catch /.*/
4710 Xpath 8388608 " X: 0
4711 endtry
4712 catch /.*/
4713 let errcaught = 1
4714 call CHECK(8, 'E171', "Missing :endif", line_before_throw + 3)
4715 endtry
4716 finally
4717 if !errcaught && $VIMNOERRTHROW
4718 call CHECK(8)
4719 endif
4720 break " discard error for $VIMNOERRTHROW
4721 endtry
4722 endwhile
4723 call CHECK(9)
4724
4725 Xpath 16777216 " X: 16777216
4726
4727 try
4728 while 1
4729 try
4730 throw "x6"
4731 finally
4732 break
4733 endtry
4734 break
4735 endwhile
4736 catch /.*/
4737 Xpath 33554432 " X: 0
4738 endtry
4739 call CHECK(10)
4740
4741 try
4742 while 1
4743 try
4744 throw "x7"
4745 finally
4746 break
4747 endtry
4748 break
4749 endwhile
4750 catch /.*/
4751 Xpath 67108864 " X: 0
4752 finally
4753 call CHECK(11)
4754 endtry
4755 call CHECK(12)
4756
4757 while 1
4758 try
4759 let errcaught = 0
4760 try
4761 try
4762 throw "x8"
4763 finally
4764 SetLineNumber line_before_error
4765 asdf
4766 endtry
4767 catch /.*/
4768 let errcaught = 1
4769 call CHECK(13, 'E492', "Not an editor command",
4770 \ line_before_error + 1)
4771 endtry
4772 finally
4773 if !errcaught && $VIMNOERRTHROW
4774 call CHECK(13)
4775 endif
4776 break " discard error for $VIMNOERRTHROW
4777 endtry
4778 endwhile
4779 call CHECK(14)
4780
4781 Xpath 134217728 " X: 134217728
4782
4783 while 1
4784 try
4785 let intcaught = 0
4786 try
4787 try
4788 throw "x9"
4789 finally
4790 SetLineNumber two_lines_before_interrupt
4791 "INTERRUPT
4792 endtry
4793 catch /.*/
4794 let intcaught = 1
4795 call CHECK(15, "Vim:Interrupt", '',
4796 \ two_lines_before_interrupt + 2)
4797 endtry
4798 finally
4799 if !intcaught && $VIMNOINTTHROW
4800 call CHECK(15)
4801 endif
4802 break " discard interrupt for $VIMNOINTTHROW
4803 endtry
4804 endwhile
4805 call CHECK(16)
4806
4807 Xpath 268435456 " X: 268435456
4808
4809 while 1
4810 try
4811 let errcaught = 0
4812 try
4813 try
4814" if 1
4815 SetLineNumber line_before_throw
4816 throw "x10"
4817 " missing endif
4818 finally
4819 call CHECK(17)
4820 endtry
4821 catch /.*/
4822 let errcaught = 1
4823 call CHECK(18, 'E171', "Missing :endif", line_before_throw + 3)
4824 endtry
4825 finally
4826 if !errcaught && $VIMNOERRTHROW
4827 call CHECK(18)
4828 endif
4829 break " discard error for $VIMNOERRTHROW
4830 endtry
4831 endwhile
4832 call CHECK(19)
4833
4834 Xpath 536870912 " X: 536870912
4835
4836 while 1
4837 try
4838 let errcaught = 0
4839 try
4840 try
4841" if 1
4842 SetLineNumber line_before_throw
4843 throw "x11"
4844 " missing endif
4845 endtry
4846 catch /.*/
4847 let errcaught = 1
4848 call CHECK(20, 'E171', "Missing :endif", line_before_throw + 3)
4849 endtry
4850 finally
4851 if !errcaught && $VIMNOERRTHROW
4852 call CHECK(20)
4853 endif
4854 break " discard error for $VIMNOERRTHROW
4855 endtry
4856 endwhile
4857 call CHECK(21)
4858
4859 Xpath 1073741824 " X: 1073741824
4860
4861endif
4862
4863Xcheck 2038431743
4864
4865
4866"-------------------------------------------------------------------------------
4867"
4868" Test 60: (Re)throwing v:exception; :echoerr. {{{1
4869"
4870" A user exception can be rethrown after catching by throwing
4871" v:exception. An error or interrupt exception cannot be rethrown
4872" because Vim exceptions cannot be faked. A Vim exception using the
4873" value of v:exception can, however, be triggered by the :echoerr
4874" command.
4875"-------------------------------------------------------------------------------
4876
4877XpathINIT
4878
4879try
4880 try
4881 Xpath 1 " X: 1
4882 throw "oops"
4883 catch /oops/
4884 Xpath 2 " X: 2
4885 throw v:exception " rethrow user exception
4886 catch /.*/
4887 Xpath 4 " X: 0
4888 endtry
4889catch /^oops$/ " catches rethrown user exception
4890 Xpath 8 " X: 8
4891catch /.*/
4892 Xpath 16 " X: 0
4893endtry
4894
4895function! F()
4896 try
4897 let caught = 0
4898 try
4899 Xpath 32 " X: 32
4900 write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e
4901 Xpath 64 " X: 0
4902 Xout "did_emsg was reset before executing " .
4903 \ "BufWritePost autocommands."
4904 catch /^Vim(write):/
4905 let caught = 1
4906 throw v:exception " throw error: cannot fake Vim exception
4907 catch /.*/
4908 Xpath 128 " X: 0
4909 finally
4910 Xpath 256 " X: 256
4911 if !caught && !$VIMNOERRTHROW
4912 Xpath 512 " X: 0
4913 endif
4914 endtry
4915 catch /^Vim(throw):/ " catches throw error
4916 let caught = caught + 1
4917 catch /.*/
4918 Xpath 1024 " X: 0
4919 finally
4920 Xpath 2048 " X: 2048
4921 if caught != 2
4922 if !caught && !$VIMNOERRTHROW
4923 Xpath 4096 " X: 0
4924 elseif caught
4925 Xpath 8192 " X: 0
4926 endif
4927 return | " discard error for $VIMNOERRTHROW
4928 endif
4929 endtry
4930endfunction
4931
4932call F()
4933delfunction F
4934
4935function! G()
4936 try
4937 let caught = 0
4938 try
4939 Xpath 16384 " X: 16384
4940 asdf
4941 catch /^Vim/ " catch error exception
4942 let caught = 1
4943 " Trigger Vim error exception with value specified after :echoerr
4944 let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
4945 echoerr value
4946 catch /.*/
4947 Xpath 32768 " X: 0
4948 finally
4949 Xpath 65536 " X: 65536
4950 if !caught
4951 if !$VIMNOERRTHROW
4952 Xpath 131072 " X: 0
4953 else
4954 let value = "Error"
4955 echoerr value
4956 endif
4957 endif
4958 endtry
4959 catch /^Vim(echoerr):/
4960 let caught = caught + 1
4961 if v:exception !~ value
4962 Xpath 262144 " X: 0
4963 endif
4964 catch /.*/
4965 Xpath 524288 " X: 0
4966 finally
4967 Xpath 1048576 " X: 1048576
4968 if caught != 2
4969 if !caught && !$VIMNOERRTHROW
4970 Xpath 2097152 " X: 0
4971 elseif caught
4972 Xpath 4194304 " X: 0
4973 endif
4974 return | " discard error for $VIMNOERRTHROW
4975 endif
4976 endtry
4977endfunction
4978
4979call G()
4980delfunction G
4981
4982unlet! value caught
4983
4984if ExtraVim()
4985 try
4986 let errcaught = 0
4987 try
4988 Xpath 8388608 " X: 8388608
4989 let intcaught = 0
4990 "INTERRUPT
4991 catch /^Vim:/ " catch interrupt exception
4992 let intcaught = 1
4993 " Trigger Vim error exception with value specified after :echoerr
4994 echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
4995 catch /.*/
4996 Xpath 16777216 " X: 0
4997 finally
4998 Xpath 33554432 " X: 33554432
4999 if !intcaught
5000 if !$VIMNOINTTHROW
5001 Xpath 67108864 " X: 0
5002 else
5003 echoerr "Interrupt"
5004 endif
5005 endif
5006 endtry
5007 catch /^Vim(echoerr):/
5008 let errcaught = 1
5009 if v:exception !~ "Interrupt"
5010 Xpath 134217728 " X: 0
5011 endif
5012 finally
5013 Xpath 268435456 " X: 268435456
5014 if !errcaught && !$VIMNOERRTHROW
5015 Xpath 536870912 " X: 0
5016 endif
5017 endtry
5018endif
5019
5020Xcheck 311511339
5021
5022
5023"-------------------------------------------------------------------------------
5024" Test 61: Catching interrupt exceptions {{{1
5025"
5026" When an interrupt occurs inside a :try/:endtry region, an
5027" interrupt exception is thrown and can be caught. Its value is
5028" "Vim:Interrupt". If the interrupt occurs after an error or a :throw
5029" but before a matching :catch is reached, all following :catches of
5030" that try block are ignored, but the interrupt exception can be
5031" caught by the next surrounding try conditional. An interrupt is
5032" ignored when there is a previous interrupt that has not been caught
5033" or causes a :finally clause to be executed.
5034"-------------------------------------------------------------------------------
5035
5036XpathINIT
5037
5038if ExtraVim()
5039
5040 while 1
5041 try
5042 try
5043 Xpath 1 " X: 1
5044 let caught = 0
5045 "INTERRUPT
5046 Xpath 2 " X: 0
5047 catch /^Vim:Interrupt$/
5048 let caught = 1
5049 finally
5050 Xpath 4 " X: 4
5051 if caught || $VIMNOINTTHROW
5052 Xpath 8 " X: 8
5053 endif
5054 endtry
5055 catch /.*/
5056 Xpath 16 " X: 0
5057 Xout v:exception "in" v:throwpoint
5058 finally
5059 break " discard interrupt for $VIMNOINTTHROW
5060 endtry
5061 endwhile
5062
5063 while 1
5064 try
5065 try
5066 let caught = 0
5067 try
5068 Xpath 32 " X: 32
5069 asdf
5070 Xpath 64 " X: 0
5071 catch /do_not_catch/
5072 Xpath 128 " X: 0
5073 catch /.*/ "INTERRUPT - throw interrupt if !$VIMNOERRTHROW
5074 Xpath 256 " X: 0
5075 catch /.*/
5076 Xpath 512 " X: 0
5077 finally "INTERRUPT - throw interrupt if $VIMNOERRTHROW
5078 Xpath 1024 " X: 1024
5079 endtry
5080 catch /^Vim:Interrupt$/
5081 let caught = 1
5082 finally
5083 Xpath 2048 " X: 2048
5084 if caught || $VIMNOINTTHROW
5085 Xpath 4096 " X: 4096
5086 endif
5087 endtry
5088 catch /.*/
5089 Xpath 8192 " X: 0
5090 Xout v:exception "in" v:throwpoint
5091 finally
5092 break " discard interrupt for $VIMNOINTTHROW
5093 endtry
5094 endwhile
5095
5096 while 1
5097 try
5098 try
5099 let caught = 0
5100 try
5101 Xpath 16384 " X: 16384
5102 throw "x"
5103 Xpath 32768 " X: 0
5104 catch /do_not_catch/
5105 Xpath 65536 " X: 0
5106 catch /x/ "INTERRUPT
5107 Xpath 131072 " X: 0
5108 catch /.*/
5109 Xpath 262144 " X: 0
5110 endtry
5111 catch /^Vim:Interrupt$/
5112 let caught = 1
5113 finally
5114 Xpath 524288 " X: 524288
5115 if caught || $VIMNOINTTHROW
5116 Xpath 1048576 " X: 1048576
5117 endif
5118 endtry
5119 catch /.*/
5120 Xpath 2097152 " X: 0
5121 Xout v:exception "in" v:throwpoint
5122 finally
5123 break " discard interrupt for $VIMNOINTTHROW
5124 endtry
5125 endwhile
5126
5127 while 1
5128 try
5129 let caught = 0
5130 try
5131 Xpath 4194304 " X: 4194304
5132 "INTERRUPT
5133 Xpath 8388608 " X: 0
5134 catch /do_not_catch/ "INTERRUPT
5135 Xpath 16777216 " X: 0
5136 catch /^Vim:Interrupt$/
5137 let caught = 1
5138 finally
5139 Xpath 33554432 " X: 33554432
5140 if caught || $VIMNOINTTHROW
5141 Xpath 67108864 " X: 67108864
5142 endif
5143 endtry
5144 catch /.*/
5145 Xpath 134217728 " X: 0
5146 Xout v:exception "in" v:throwpoint
5147 finally
5148 break " discard interrupt for $VIMNOINTTHROW
5149 endtry
5150 endwhile
5151
5152 Xpath 268435456 " X: 268435456
5153
5154endif
5155
5156Xcheck 374889517
5157
5158
5159"-------------------------------------------------------------------------------
5160" Test 62: Catching error exceptions {{{1
5161"
5162" An error inside a :try/:endtry region is converted to an exception
5163" and can be caught. The error exception has a "Vim(cmdname):" prefix
5164" where cmdname is the name of the failing command, or a "Vim:" prefix
5165" if no command name is known. The "Vim" prefixes cannot be faked.
5166"-------------------------------------------------------------------------------
5167
5168XpathINIT
5169
5170function! MSG(enr, emsg)
5171 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
5172 if a:enr == ""
5173 Xout "TODO: Add message number for:" a:emsg
5174 let v:errmsg = ":" . v:errmsg
5175 endif
5176 let match = 1
5177 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
5178 let match = 0
5179 if v:errmsg == ""
5180 Xout "Message missing."
5181 else
5182 let v:errmsg = escape(v:errmsg, '"')
5183 Xout "Unexpected message:" v:errmsg
5184 endif
5185 endif
5186 return match
5187endfunction
5188
5189while 1
5190 try
5191 try
5192 let caught = 0
5193 unlet novar
5194 catch /^Vim(unlet):/
5195 let caught = 1
5196 let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "")
5197 finally
5198 Xpath 1 " X: 1
5199 if !caught && !$VIMNOERRTHROW
5200 Xpath 2 " X: 0
5201 endif
5202 if !MSG('E108', "No such variable")
5203 Xpath 4 " X: 0
5204 endif
5205 endtry
5206 catch /.*/
5207 Xpath 8 " X: 0
5208 Xout v:exception "in" v:throwpoint
5209 finally
5210 break " discard error for $VIMNOERRTHROW
5211 endtry
5212endwhile
5213
5214while 1
5215 try
5216 try
5217 let caught = 0
5218 throw novar " error in :throw
5219 catch /^Vim(throw):/
5220 let caught = 1
5221 let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
5222 finally
5223 Xpath 16 " X: 16
5224 if !caught && !$VIMNOERRTHROW
5225 Xpath 32 " X: 0
5226 endif
5227 if caught ? !MSG('E121', "Undefined variable")
5228 \ : !MSG('E15', "Invalid expression")
5229 Xpath 64 " X: 0
5230 endif
5231 endtry
5232 catch /.*/
5233 Xpath 128 " X: 0
5234 Xout v:exception "in" v:throwpoint
5235 finally
5236 break " discard error for $VIMNOERRTHROW
5237 endtry
5238endwhile
5239
5240while 1
5241 try
5242 try
5243 let caught = 0
5244 throw "Vim:faked" " error: cannot fake Vim exception
5245 catch /^Vim(throw):/
5246 let caught = 1
5247 let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
5248 finally
5249 Xpath 256 " X: 256
5250 if !caught && !$VIMNOERRTHROW
5251 Xpath 512 " X: 0
5252 endif
5253 if !MSG('E608', "Cannot :throw exceptions with 'Vim' prefix")
5254 Xpath 1024 " X: 0
5255 endif
5256 endtry
5257 catch /.*/
5258 Xpath 2048 " X: 0
5259 Xout v:exception "in" v:throwpoint
5260 finally
5261 break " discard error for $VIMNOERRTHROW
5262 endtry
5263endwhile
5264
5265function! F()
5266 while 1
5267 " Missing :endwhile
5268endfunction
5269
5270while 1
5271 try
5272 try
5273 let caught = 0
5274 call F()
5275 catch /^Vim(endfunction):/
5276 let caught = 1
5277 let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "")
5278 finally
5279 Xpath 4096 " X: 4096
5280 if !caught && !$VIMNOERRTHROW
5281 Xpath 8192 " X: 0
5282 endif
5283 if !MSG('E170', "Missing :endwhile")
5284 Xpath 16384 " X: 0
5285 endif
5286 endtry
5287 catch /.*/
5288 Xpath 32768 " X: 0
5289 Xout v:exception "in" v:throwpoint
5290 finally
5291 break " discard error for $VIMNOERRTHROW
5292 endtry
5293endwhile
5294
5295while 1
5296 try
5297 try
5298 let caught = 0
5299 ExecAsScript F
5300 catch /^Vim:/
5301 let caught = 1
5302 let v:errmsg = substitute(v:exception, '^Vim:', '', "")
5303 finally
5304 Xpath 65536 " X: 65536
5305 if !caught && !$VIMNOERRTHROW
5306 Xpath 131072 " X: 0
5307 endif
5308 if !MSG('E170', "Missing :endwhile")
5309 Xpath 262144 " X: 0
5310 endif
5311 endtry
5312 catch /.*/
5313 Xpath 524288 " X: 0
5314 Xout v:exception "in" v:throwpoint
5315 finally
5316 break " discard error for $VIMNOERRTHROW
5317 endtry
5318endwhile
5319
5320function! G()
5321 call G()
5322endfunction
5323
5324while 1
5325 try
5326 let mfd_save = &mfd
5327 set mfd=3
5328 try
5329 let caught = 0
5330 call G()
5331 catch /^Vim(call):/
5332 let caught = 1
5333 let v:errmsg = substitute(v:exception, '^Vim(call):', '', "")
5334 finally
5335 Xpath 1048576 " X: 1048576
5336 if !caught && !$VIMNOERRTHROW
5337 Xpath 2097152 " X: 0
5338 endif
5339 if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
5340 Xpath 4194304 " X: 0
5341 endif
5342 endtry
5343 catch /.*/
5344 Xpath 8388608 " X: 0
5345 Xout v:exception "in" v:throwpoint
5346 finally
5347 let &mfd = mfd_save
5348 break " discard error for $VIMNOERRTHROW
5349 endtry
5350endwhile
5351
5352function! H()
5353 return H()
5354endfunction
5355
5356while 1
5357 try
5358 let mfd_save = &mfd
5359 set mfd=3
5360 try
5361 let caught = 0
5362 call H()
5363 catch /^Vim(return):/
5364 let caught = 1
5365 let v:errmsg = substitute(v:exception, '^Vim(return):', '', "")
5366 finally
5367 Xpath 16777216 " X: 16777216
5368 if !caught && !$VIMNOERRTHROW
5369 Xpath 33554432 " X: 0
5370 endif
5371 if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
5372 Xpath 67108864 " X: 0
5373 endif
5374 endtry
5375 catch /.*/
5376 Xpath 134217728 " X: 0
5377 Xout v:exception "in" v:throwpoint
5378 finally
5379 let &mfd = mfd_save
5380 break " discard error for $VIMNOERRTHROW
5381 endtry
5382endwhile
5383
5384unlet! caught mfd_save
5385delfunction F
5386delfunction G
5387delfunction H
5388Xpath 268435456 " X: 268435456
5389
5390Xcheck 286331153
5391
5392" Leave MSG() for the next test.
5393
5394
5395"-------------------------------------------------------------------------------
5396" Test 63: Suppressing error exceptions by :silent!. {{{1
5397"
5398" A :silent! command inside a :try/:endtry region suppresses the
5399" conversion of errors to an exception and the immediate abortion on
5400" error. When the commands executed by the :silent! themselves open
5401" a new :try/:endtry region, conversion of errors to exception and
5402" immediate abortion is switched on again - until the next :silent!
5403" etc. The :silent! has the effect of setting v:errmsg to the error
5404" message text (without displaying it) and continuing with the next
5405" script line.
5406"
5407" When a command triggering autocommands is executed by :silent!
5408" inside a :try/:endtry, the autocommand execution is not suppressed
5409" on error.
5410"
5411" This test reuses the function MSG() from the previous test.
5412"-------------------------------------------------------------------------------
5413
5414XpathINIT
5415
5416XloopINIT! 1 4
5417
5418let taken = ""
5419
5420function! S(n) abort
5421 XloopNEXT
5422 let g:taken = g:taken . "E" . a:n
5423 let v:errmsg = ""
5424 exec "asdf" . a:n
5425
5426 " Check that ":silent!" continues:
5427 Xloop 1
5428
5429 " Check that ":silent!" sets "v:errmsg":
5430 if MSG('E492', "Not an editor command")
5431 Xloop 2
5432 endif
5433endfunction
5434
5435function! Foo()
5436 while 1
5437 try
5438 try
5439 let caught = 0
5440 " This is not silent:
5441 call S(3) " X: 0 * 16
5442 catch /^Vim:/
5443 let caught = 1
5444 let errmsg3 = substitute(v:exception, '^Vim:', '', "")
5445 silent! call S(4) " X: 3 * 64
5446 finally
5447 if !caught
5448 let errmsg3 = v:errmsg
5449 " Do call S(4) here if not executed in :catch.
5450 silent! call S(4)
5451 endif
5452 Xpath 1048576 " X: 1048576
5453 if !caught && !$VIMNOERRTHROW
5454 Xpath 2097152 " X: 0
5455 endif
5456 let v:errmsg = errmsg3
5457 if !MSG('E492', "Not an editor command")
5458 Xpath 4194304 " X: 0
5459 endif
5460 silent! call S(5) " X: 3 * 256
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005461 " Break out of try conditionals that cover ":silent!". This also
Bram Moolenaar071d4272004-06-13 20:20:40 +00005462 " discards the aborting error when $VIMNOERRTHROW is non-zero.
5463 break
5464 endtry
5465 catch /.*/
5466 Xpath 8388608 " X: 0
5467 Xout v:exception "in" v:throwpoint
5468 endtry
5469 endwhile
5470 " This is a double ":silent!" (see caller).
5471 silent! call S(6) " X: 3 * 1024
5472endfunction
5473
5474function! Bar()
5475 try
5476 silent! call S(2) " X: 3 * 4
5477 " X: 3 * 4096
5478 silent! execute "call Foo() | call S(7)"
5479 silent! call S(8) " X: 3 * 16384
5480 endtry " normal end of try cond that covers ":silent!"
5481 " This has a ":silent!" from the caller:
5482 call S(9) " X: 3 * 65536
5483endfunction
5484
5485silent! call S(1) " X: 3 * 1
5486silent! call Bar()
5487silent! call S(10) " X: 3 * 262144
5488
5489let expected = "E1E2E3E4E5E6E7E8E9E10"
5490if taken != expected
5491 Xpath 16777216 " X: 0
5492 Xout "'taken' is" taken "instead of" expected
5493endif
5494
5495augroup TMP
5496 autocmd BufWritePost * Xpath 33554432 " X: 33554432
5497augroup END
5498
5499Xpath 67108864 " X: 67108864
5500write /i/m/p/o/s/s/i/b/l/e
5501Xpath 134217728 " X: 134217728
5502
5503autocmd! TMP
5504unlet! caught errmsg3 taken expected
5505delfunction S
5506delfunction Foo
5507delfunction Bar
5508delfunction MSG
5509
5510Xcheck 236978127
5511
5512
5513"-------------------------------------------------------------------------------
5514" Test 64: Error exceptions after error, interrupt or :throw {{{1
5515"
5516" When an error occurs after an interrupt or a :throw but before
5517" a matching :catch is reached, all following :catches of that try
5518" block are ignored, but the error exception can be caught by the next
5519" surrounding try conditional. Any previous error exception is
5520" discarded. An error is ignored when there is a previous error that
5521" has not been caught.
5522"-------------------------------------------------------------------------------
5523
5524XpathINIT
5525
5526if ExtraVim()
5527
5528 while 1
5529 try
5530 try
5531 Xpath 1 " X: 1
5532 let caught = 0
5533 while 1
5534" if 1
5535 " Missing :endif
5536 endwhile " throw error exception
5537 catch /^Vim(/
5538 let caught = 1
5539 finally
5540 Xpath 2 " X: 2
5541 if caught || $VIMNOERRTHROW
5542 Xpath 4 " X: 4
5543 endif
5544 endtry
5545 catch /.*/
5546 Xpath 8 " X: 0
5547 Xout v:exception "in" v:throwpoint
5548 finally
5549 break " discard error for $VIMNOERRTHROW
5550 endtry
5551 endwhile
5552
5553 while 1
5554 try
5555 try
5556 Xpath 16 " X: 16
5557 let caught = 0
5558 try
5559" if 1
5560 " Missing :endif
5561 catch /.*/ " throw error exception
5562 Xpath 32 " X: 0
5563 catch /.*/
5564 Xpath 64 " X: 0
5565 endtry
5566 catch /^Vim(/
5567 let caught = 1
5568 finally
5569 Xpath 128 " X: 128
5570 if caught || $VIMNOERRTHROW
5571 Xpath 256 " X: 256
5572 endif
5573 endtry
5574 catch /.*/
5575 Xpath 512 " X: 0
5576 Xout v:exception "in" v:throwpoint
5577 finally
5578 break " discard error for $VIMNOERRTHROW
5579 endtry
5580 endwhile
5581
5582 while 1
5583 try
5584 try
5585 let caught = 0
5586 try
5587 Xpath 1024 " X: 1024
5588 "INTERRUPT
5589 catch /do_not_catch/
5590 Xpath 2048 " X: 0
5591" if 1
5592 " Missing :endif
5593 catch /.*/ " throw error exception
5594 Xpath 4096 " X: 0
5595 catch /.*/
5596 Xpath 8192 " X: 0
5597 endtry
5598 catch /^Vim(/
5599 let caught = 1
5600 finally
5601 Xpath 16384 " X: 16384
5602 if caught || $VIMNOERRTHROW
5603 Xpath 32768 " X: 32768
5604 endif
5605 endtry
5606 catch /.*/
5607 Xpath 65536 " X: 0
5608 Xout v:exception "in" v:throwpoint
5609 finally
5610 break " discard error for $VIMNOERRTHROW
5611 endtry
5612 endwhile
5613
5614 while 1
5615 try
5616 try
5617 let caught = 0
5618 try
5619 Xpath 131072 " X: 131072
5620 throw "x"
5621 catch /do_not_catch/
5622 Xpath 262144 " X: 0
5623" if 1
5624 " Missing :endif
5625 catch /x/ " throw error exception
5626 Xpath 524288 " X: 0
5627 catch /.*/
5628 Xpath 1048576 " X: 0
5629 endtry
5630 catch /^Vim(/
5631 let caught = 1
5632 finally
5633 Xpath 2097152 " X: 2097152
5634 if caught || $VIMNOERRTHROW
5635 Xpath 4194304 " X: 4194304
5636 endif
5637 endtry
5638 catch /.*/
5639 Xpath 8388608 " X: 0
5640 Xout v:exception "in" v:throwpoint
5641 finally
5642 break " discard error for $VIMNOERRTHROW
5643 endtry
5644 endwhile
5645
5646 while 1
5647 try
5648 try
5649 let caught = 0
5650 Xpath 16777216 " X: 16777216
5651" endif " :endif without :if; throw error exception
5652" if 1
5653 " Missing :endif
5654 catch /do_not_catch/ " ignore new error
5655 Xpath 33554432 " X: 0
5656 catch /^Vim(endif):/
5657 let caught = 1
5658 catch /^Vim(/
5659 Xpath 67108864 " X: 0
5660 finally
5661 Xpath 134217728 " X: 134217728
5662 if caught || $VIMNOERRTHROW
5663 Xpath 268435456 " X: 268435456
5664 endif
5665 endtry
5666 catch /.*/
5667 Xpath 536870912 " X: 0
5668 Xout v:exception "in" v:throwpoint
5669 finally
5670 break " discard error for $VIMNOERRTHROW
5671 endtry
5672 endwhile
5673
5674 Xpath 1073741824 " X: 1073741824
5675
5676endif
5677
5678Xcheck 1499645335
5679
5680
5681"-------------------------------------------------------------------------------
5682" Test 65: Errors in the /pattern/ argument of a :catch {{{1
5683"
5684" On an error in the /pattern/ argument of a :catch, the :catch does
5685" not match. Any following :catches of the same :try/:endtry don't
5686" match either. Finally clauses are executed.
5687"-------------------------------------------------------------------------------
5688
5689XpathINIT
5690
5691function! MSG(enr, emsg)
5692 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
5693 if a:enr == ""
5694 Xout "TODO: Add message number for:" a:emsg
5695 let v:errmsg = ":" . v:errmsg
5696 endif
5697 let match = 1
5698 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
5699 let match = 0
5700 if v:errmsg == ""
5701 Xout "Message missing."
5702 else
5703 let v:errmsg = escape(v:errmsg, '"')
5704 Xout "Unexpected message:" v:errmsg
5705 endif
5706 endif
5707 return match
5708endfunction
5709
5710try
5711 try
5712 Xpath 1 " X: 1
5713 throw "oops"
5714 catch /^oops$/
5715 Xpath 2 " X: 2
5716 catch /\)/ " not checked; exception has already been caught
5717 Xpath 4 " X: 0
5718 endtry
5719 Xpath 8 " X: 8
5720catch /.*/
5721 Xpath 16 " X: 0
5722 Xout v:exception "in" v:throwpoint
5723endtry
5724
5725function! F()
5726 try
5727 let caught = 0
5728 try
5729 try
5730 Xpath 32 " X: 32
5731 throw "ab"
5732 catch /abc/ " does not catch
5733 Xpath 64 " X: 0
5734 catch /\)/ " error; discards exception
5735 Xpath 128 " X: 0
5736 catch /.*/ " not checked
5737 Xpath 256 " X: 0
5738 finally
5739 Xpath 512 " X: 512
5740 endtry
5741 Xpath 1024 " X: 0
5742 catch /^ab$/ " checked, but original exception is discarded
5743 Xpath 2048 " X: 0
5744 catch /^Vim(catch):/
5745 let caught = 1
5746 let v:errmsg = substitute(v:exception, '^Vim(catch):', '', "")
5747 finally
5748 Xpath 4096 " X: 4096
5749 if !caught && !$VIMNOERRTHROW
5750 Xpath 8192 " X: 0
5751 endif
Bram Moolenaardc94a262016-02-07 20:29:00 +01005752 if !MSG('E475', "Invalid argument")
Bram Moolenaar071d4272004-06-13 20:20:40 +00005753 Xpath 16384 " X: 0
5754 endif
5755 if !caught
5756 return | " discard error
5757 endif
5758 endtry
5759 catch /.*/
5760 Xpath 32768 " X: 0
5761 Xout v:exception "in" v:throwpoint
5762 endtry
5763endfunction
5764
5765call F()
5766Xpath 65536 " X: 65536
5767
5768delfunction MSG
5769delfunction F
5770unlet! caught
5771
5772Xcheck 70187
5773
5774
5775"-------------------------------------------------------------------------------
5776" Test 66: Stop range :call on error, interrupt, or :throw {{{1
5777"
5778" When a function which is multiply called for a range since it
5779" doesn't handle the range itself has an error in a command
5780" dynamically enclosed by :try/:endtry or gets an interrupt or
5781" executes a :throw, no more calls for the remaining lines in the
5782" range are made. On an error in a command not dynamically enclosed
5783" by :try/:endtry, the function is executed again for the remaining
5784" lines in the range.
5785"-------------------------------------------------------------------------------
5786
5787XpathINIT
5788
5789if ExtraVim()
5790
5791 let file = tempname()
5792 exec "edit" file
5793
5794 insert
5795line 1
5796line 2
5797line 3
5798.
5799
5800 XloopINIT! 1 2
5801
5802 let taken = ""
5803 let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)"
5804
5805 function! F(reason, n) abort
5806 let g:taken = g:taken . "F" . a:n .
5807 \ substitute(a:reason, '\(\l\).*', '\u\1', "") .
5808 \ "(" . line(".") . ")"
5809
5810 if a:reason == "error"
5811 asdf
5812 elseif a:reason == "interrupt"
5813 "INTERRUPT
5814 let dummy = 0
5815 elseif a:reason == "throw"
5816 throw "xyz"
5817 elseif a:reason == "aborting error"
5818 XloopNEXT
5819 if g:taken != g:expected
5820 Xloop 1 " X: 0
5821 Xout "'taken' is" g:taken "instead of" g:expected
5822 endif
5823 try
5824 bwipeout!
5825 call delete(file)
5826 asdf
5827 endtry
5828 endif
5829 endfunction
5830
5831 function! G(reason, n)
5832 let g:taken = g:taken . "G" . a:n .
5833 \ substitute(a:reason, '\(\l\).*', '\u\1', "")
5834 1,3call F(a:reason, a:n)
5835 endfunction
5836
5837 Xpath 8 " X: 8
5838 call G("error", 1)
5839 try
5840 Xpath 16 " X: 16
5841 try
5842 call G("error", 2)
5843 Xpath 32 " X: 0
5844 finally
5845 Xpath 64 " X: 64
5846 try
5847 call G("interrupt", 3)
5848 Xpath 128 " X: 0
5849 finally
5850 Xpath 256 " X: 256
5851 try
5852 call G("throw", 4)
5853 Xpath 512 " X: 0
5854 endtry
5855 endtry
5856 endtry
5857 catch /xyz/
5858 Xpath 1024 " X: 1024
5859 catch /.*/
5860 Xpath 2048 " X: 0
5861 Xout v:exception "in" ExtraVimThrowpoint()
5862 endtry
5863 Xpath 4096 " X: 4096
5864 call G("aborting error", 5)
5865 Xpath 8192 " X: 0
5866 Xout "'taken' is" taken "instead of" expected
5867
5868endif
5869
5870Xcheck 5464
5871
5872
5873"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005874" Test 67: :throw across :call command {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00005875"
5876" On a call command, an exception might be thrown when evaluating the
5877" function name, during evaluation of the arguments, or when the
5878" function is being executed. The exception can be caught by the
5879" caller.
5880"-------------------------------------------------------------------------------
5881
5882XpathINIT
5883
5884function! THROW(x, n)
5885 if a:n == 1
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005886 Xpath 1 " X: 1
Bram Moolenaar071d4272004-06-13 20:20:40 +00005887 elseif a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005888 Xpath 2 " X: 2
Bram Moolenaar071d4272004-06-13 20:20:40 +00005889 elseif a:n == 3
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005890 Xpath 4 " X: 4
Bram Moolenaar071d4272004-06-13 20:20:40 +00005891 endif
5892 throw a:x
5893endfunction
5894
5895function! NAME(x, n)
5896 if a:n == 1
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005897 Xpath 8 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00005898 elseif a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005899 Xpath 16 " X: 16
Bram Moolenaar071d4272004-06-13 20:20:40 +00005900 elseif a:n == 3
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005901 Xpath 32 " X: 32
Bram Moolenaar071d4272004-06-13 20:20:40 +00005902 elseif a:n == 4
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005903 Xpath 64 " X: 64
Bram Moolenaar071d4272004-06-13 20:20:40 +00005904 endif
5905 return a:x
5906endfunction
5907
5908function! ARG(x, n)
5909 if a:n == 1
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005910 Xpath 128 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00005911 elseif a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005912 Xpath 256 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00005913 elseif a:n == 3
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005914 Xpath 512 " X: 512
Bram Moolenaar071d4272004-06-13 20:20:40 +00005915 elseif a:n == 4
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005916 Xpath 1024 " X: 1024
Bram Moolenaar071d4272004-06-13 20:20:40 +00005917 endif
5918 return a:x
5919endfunction
5920
5921function! F(x, n)
5922 if a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005923 Xpath 2048 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00005924 elseif a:n == 4
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005925 Xpath 4096 " X: 4096
Bram Moolenaar071d4272004-06-13 20:20:40 +00005926 endif
5927endfunction
5928
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005929while 1
Bram Moolenaar071d4272004-06-13 20:20:40 +00005930 try
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005931 let error = 0
5932 let v:errmsg = ""
Bram Moolenaar071d4272004-06-13 20:20:40 +00005933
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005934 while 1
5935 try
5936 Xpath 8192 " X: 8192
5937 call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
5938 Xpath 16384 " X: 0
5939 catch /^name$/
5940 Xpath 32768 " X: 32768
5941 catch /.*/
5942 let error = 1
5943 Xout "1:" v:exception "in" v:throwpoint
5944 finally
5945 if !error && $VIMNOERRTHROW && v:errmsg != ""
5946 let error = 1
5947 Xout "1:" v:errmsg
5948 endif
5949 if error
5950 Xpath 65536 " X: 0
5951 endif
5952 let error = 0
5953 let v:errmsg = ""
5954 break " discard error for $VIMNOERRTHROW
5955 endtry
5956 endwhile
Bram Moolenaar071d4272004-06-13 20:20:40 +00005957
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005958 while 1
5959 try
5960 Xpath 131072 " X: 131072
5961 call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
5962 Xpath 262144 " X: 0
5963 catch /^arg$/
5964 Xpath 524288 " X: 524288
5965 catch /.*/
5966 let error = 1
5967 Xout "2:" v:exception "in" v:throwpoint
5968 finally
5969 if !error && $VIMNOERRTHROW && v:errmsg != ""
5970 let error = 1
5971 Xout "2:" v:errmsg
5972 endif
5973 if error
5974 Xpath 1048576 " X: 0
5975 endif
5976 let error = 0
5977 let v:errmsg = ""
5978 break " discard error for $VIMNOERRTHROW
5979 endtry
5980 endwhile
5981
5982 while 1
5983 try
5984 Xpath 2097152 " X: 2097152
5985 call {NAME("THROW", 3)}(ARG("call", 3), 3)
5986 Xpath 4194304 " X: 0
5987 catch /^call$/
5988 Xpath 8388608 " X: 8388608
5989 catch /^0$/ " default return value
5990 Xpath 16777216 " X: 0
5991 Xout "3:" v:throwpoint
5992 catch /.*/
5993 let error = 1
5994 Xout "3:" v:exception "in" v:throwpoint
5995 finally
5996 if !error && $VIMNOERRTHROW && v:errmsg != ""
5997 let error = 1
5998 Xout "3:" v:errmsg
5999 endif
6000 if error
6001 Xpath 33554432 " X: 0
6002 endif
6003 let error = 0
6004 let v:errmsg = ""
6005 break " discard error for $VIMNOERRTHROW
6006 endtry
6007 endwhile
6008
6009 while 1
6010 try
6011 Xpath 67108864 " X: 67108864
6012 call {NAME("F", 4)}(ARG(4711, 4), 4)
6013 Xpath 134217728 " X: 134217728
6014 catch /.*/
6015 let error = 1
6016 Xout "4:" v:exception "in" v:throwpoint
6017 finally
6018 if !error && $VIMNOERRTHROW && v:errmsg != ""
6019 let error = 1
6020 Xout "4:" v:errmsg
6021 endif
6022 if error
6023 Xpath 268435456 " X: 0
6024 endif
6025 let error = 0
6026 let v:errmsg = ""
6027 break " discard error for $VIMNOERRTHROW
6028 endtry
6029 endwhile
6030
Bram Moolenaar071d4272004-06-13 20:20:40 +00006031 catch /^0$/ " default return value
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006032 Xpath 536870912 " X: 0
6033 Xout v:throwpoint
Bram Moolenaar071d4272004-06-13 20:20:40 +00006034 catch /.*/
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006035 let error = 1
6036 Xout v:exception "in" v:throwpoint
6037 finally
6038 if !error && $VIMNOERRTHROW && v:errmsg != ""
6039 let error = 1
6040 Xout v:errmsg
6041 endif
6042 if error
6043 Xpath 1073741824 " X: 0
6044 endif
6045 break " discard error for $VIMNOERRTHROW
Bram Moolenaar071d4272004-06-13 20:20:40 +00006046 endtry
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006047endwhile
Bram Moolenaar071d4272004-06-13 20:20:40 +00006048
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006049unlet error
Bram Moolenaar071d4272004-06-13 20:20:40 +00006050delfunction F
6051
6052Xcheck 212514423
6053
6054" Leave THROW(), NAME(), and ARG() for the next test.
6055
6056
6057"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006058" Test 68: :throw across function calls in expressions {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00006059"
6060" On a function call within an expression, an exception might be
6061" thrown when evaluating the function name, during evaluation of the
6062" arguments, or when the function is being executed. The exception
6063" can be caught by the caller.
6064"
6065" This test reuses the functions THROW(), NAME(), and ARG() from the
6066" previous test.
6067"-------------------------------------------------------------------------------
6068
6069XpathINIT
6070
6071function! F(x, n)
6072 if a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006073 Xpath 2048 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00006074 elseif a:n == 4
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006075 Xpath 4096 " X: 4096
Bram Moolenaar071d4272004-06-13 20:20:40 +00006076 endif
6077 return a:x
6078endfunction
6079
6080unlet! var1 var2 var3 var4
6081
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006082while 1
Bram Moolenaar071d4272004-06-13 20:20:40 +00006083 try
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006084 let error = 0
6085 let v:errmsg = ""
Bram Moolenaar071d4272004-06-13 20:20:40 +00006086
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006087 while 1
6088 try
6089 Xpath 8192 " X: 8192
6090 let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
6091 Xpath 16384 " X: 0
6092 catch /^name$/
6093 Xpath 32768 " X: 32768
6094 catch /.*/
6095 let error = 1
6096 Xout "1:" v:exception "in" v:throwpoint
6097 finally
6098 if !error && $VIMNOERRTHROW && v:errmsg != ""
6099 let error = 1
6100 Xout "1:" v:errmsg
6101 endif
6102 if error
6103 Xpath 65536 " X: 0
6104 endif
6105 let error = 0
6106 let v:errmsg = ""
6107 break " discard error for $VIMNOERRTHROW
6108 endtry
6109 endwhile
Bram Moolenaar071d4272004-06-13 20:20:40 +00006110
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006111 while 1
6112 try
6113 Xpath 131072 " X: 131072
6114 let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
6115 Xpath 262144 " X: 0
6116 catch /^arg$/
6117 Xpath 524288 " X: 524288
6118 catch /.*/
6119 let error = 1
6120 Xout "2:" v:exception "in" v:throwpoint
6121 finally
6122 if !error && $VIMNOERRTHROW && v:errmsg != ""
6123 let error = 1
6124 Xout "2:" v:errmsg
6125 endif
6126 if error
6127 Xpath 1048576 " X: 0
6128 endif
6129 let error = 0
6130 let v:errmsg = ""
6131 break " discard error for $VIMNOERRTHROW
6132 endtry
6133 endwhile
6134
6135 while 1
6136 try
6137 Xpath 2097152 " X: 2097152
6138 let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3)
6139 Xpath 4194304 " X: 0
6140 catch /^call$/
6141 Xpath 8388608 " X: 8388608
6142 catch /^0$/ " default return value
6143 Xpath 16777216 " X: 0
6144 Xout "3:" v:throwpoint
6145 catch /.*/
6146 let error = 1
6147 Xout "3:" v:exception "in" v:throwpoint
6148 finally
6149 if !error && $VIMNOERRTHROW && v:errmsg != ""
6150 let error = 1
6151 Xout "3:" v:errmsg
6152 endif
6153 if error
6154 Xpath 33554432 " X: 0
6155 endif
6156 let error = 0
6157 let v:errmsg = ""
6158 break " discard error for $VIMNOERRTHROW
6159 endtry
6160 endwhile
6161
6162 while 1
6163 try
6164 Xpath 67108864 " X: 67108864
6165 let var4 = {NAME("F", 4)}(ARG(4711, 4), 4)
6166 Xpath 134217728 " X: 134217728
6167 catch /.*/
6168 let error = 1
6169 Xout "4:" v:exception "in" v:throwpoint
6170 finally
6171 if !error && $VIMNOERRTHROW && v:errmsg != ""
6172 let error = 1
6173 Xout "4:" v:errmsg
6174 endif
6175 if error
6176 Xpath 268435456 " X: 0
6177 endif
6178 let error = 0
6179 let v:errmsg = ""
6180 break " discard error for $VIMNOERRTHROW
6181 endtry
6182 endwhile
6183
Bram Moolenaar071d4272004-06-13 20:20:40 +00006184 catch /^0$/ " default return value
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006185 Xpath 536870912 " X: 0
6186 Xout v:throwpoint
Bram Moolenaar071d4272004-06-13 20:20:40 +00006187 catch /.*/
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006188 let error = 1
6189 Xout v:exception "in" v:throwpoint
6190 finally
6191 if !error && $VIMNOERRTHROW && v:errmsg != ""
6192 let error = 1
6193 Xout v:errmsg
6194 endif
6195 if error
6196 Xpath 1073741824 " X: 0
6197 endif
6198 break " discard error for $VIMNOERRTHROW
Bram Moolenaar071d4272004-06-13 20:20:40 +00006199 endtry
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006200endwhile
Bram Moolenaar071d4272004-06-13 20:20:40 +00006201
6202if exists("var1") || exists("var2") || exists("var3") ||
6203 \ !exists("var4") || var4 != 4711
6204 " The Xpath command does not accept 2^31 (negative); add explicitly:
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006205 let Xpath = Xpath + 2147483648 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00006206 if exists("var1")
6207 Xout "var1 =" var1
6208 endif
6209 if exists("var2")
6210 Xout "var2 =" var2
6211 endif
6212 if exists("var3")
6213 Xout "var3 =" var3
6214 endif
6215 if !exists("var4")
6216 Xout "var4 unset"
6217 elseif var4 != 4711
6218 Xout "var4 =" var4
6219 endif
6220endif
6221
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006222unlet! error var1 var2 var3 var4
Bram Moolenaar071d4272004-06-13 20:20:40 +00006223delfunction THROW
6224delfunction NAME
6225delfunction ARG
6226delfunction F
6227
6228Xcheck 212514423
6229
6230
6231"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006232" Test 69: :throw across :if, :elseif, :while {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00006233"
6234" On an :if, :elseif, or :while command, an exception might be thrown
6235" during evaluation of the expression to test. The exception can be
6236" caught by the script.
6237"-------------------------------------------------------------------------------
6238
6239XpathINIT
6240
6241XloopINIT! 1 2
6242
6243function! THROW(x)
6244 XloopNEXT
6245 Xloop 1 " X: 1 + 2 + 4
6246 throw a:x
6247endfunction
6248
6249try
6250
6251 try
6252 Xpath 8 " X: 8
6253 if 4711 == THROW("if") + 111
6254 Xpath 16 " X: 0
6255 else
6256 Xpath 32 " X: 0
6257 endif
6258 Xpath 64 " X: 0
6259 catch /^if$/
6260 Xpath 128 " X: 128
6261 catch /.*/
6262 Xpath 256 " X: 0
6263 Xout "if:" v:exception "in" v:throwpoint
6264 endtry
6265
6266 try
6267 Xpath 512 " X: 512
6268 if 4711 == 4 + 7 + 1 + 1
6269 Xpath 1024 " X: 0
6270 elseif 4711 == THROW("elseif") + 222
6271 Xpath 2048 " X: 0
6272 else
6273 Xpath 4096 " X: 0
6274 endif
6275 Xpath 8192 " X: 0
6276 catch /^elseif$/
6277 Xpath 16384 " X: 16384
6278 catch /.*/
6279 Xpath 32768 " X: 0
6280 Xout "elseif:" v:exception "in" v:throwpoint
6281 endtry
6282
6283 try
6284 Xpath 65536 " X: 65536
6285 while 4711 == THROW("while") + 4711
6286 Xpath 131072 " X: 0
6287 break
6288 endwhile
6289 Xpath 262144 " X: 0
6290 catch /^while$/
6291 Xpath 524288 " X: 524288
6292 catch /.*/
6293 Xpath 1048576 " X: 0
6294 Xout "while:" v:exception "in" v:throwpoint
6295 endtry
6296
6297catch /^0$/ " default return value
6298 Xpath 2097152 " X: 0
6299 Xout v:throwpoint
6300catch /.*/
6301 Xout v:exception "in" v:throwpoint
6302 Xpath 4194304 " X: 0
6303endtry
6304
6305Xpath 8388608 " X: 8388608
6306
6307delfunction THROW
6308
6309Xcheck 8995471
6310
6311
6312"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006313" Test 70: :throw across :return or :throw {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00006314"
6315" On a :return or :throw command, an exception might be thrown during
6316" evaluation of the expression to return or throw, respectively. The
6317" exception can be caught by the script.
6318"-------------------------------------------------------------------------------
6319
6320XpathINIT
6321
6322let taken = ""
6323
6324function! THROW(x, n)
6325 let g:taken = g:taken . "T" . a:n
6326 throw a:x
6327endfunction
6328
6329function! F(x, y, n)
6330 let g:taken = g:taken . "F" . a:n
6331 return a:x + THROW(a:y, a:n)
6332endfunction
6333
6334function! G(x, y, n)
6335 let g:taken = g:taken . "G" . a:n
6336 throw a:x . THROW(a:y, a:n)
6337 return a:x
6338endfunction
6339
6340try
6341 try
6342 Xpath 1 " X: 1
6343 call F(4711, "return", 1)
6344 Xpath 2 " X: 0
6345 catch /^return$/
6346 Xpath 4 " X: 4
6347 catch /.*/
6348 Xpath 8 " X: 0
6349 Xout "return:" v:exception "in" v:throwpoint
6350 endtry
6351
6352 try
6353 Xpath 16 " X: 16
6354 let var = F(4712, "return-var", 2)
6355 Xpath 32 " X: 0
6356 catch /^return-var$/
6357 Xpath 64 " X: 64
6358 catch /.*/
6359 Xpath 128 " X: 0
6360 Xout "return-var:" v:exception "in" v:throwpoint
6361 finally
6362 unlet! var
6363 endtry
6364
6365 try
6366 Xpath 256 " X: 256
6367 throw "except1" . THROW("throw1", 3)
6368 Xpath 512 " X: 0
6369 catch /^except1/
6370 Xpath 1024 " X: 0
6371 catch /^throw1$/
6372 Xpath 2048 " X: 2048
6373 catch /.*/
6374 Xpath 4096 " X: 0
6375 Xout "throw1:" v:exception "in" v:throwpoint
6376 endtry
6377
6378 try
6379 Xpath 8192 " X: 8192
6380 call G("except2", "throw2", 4)
6381 Xpath 16384 " X: 0
6382 catch /^except2/
6383 Xpath 32768 " X: 0
6384 catch /^throw2$/
6385 Xpath 65536 " X: 65536
6386 catch /.*/
6387 Xpath 131072 " X: 0
6388 Xout "throw2:" v:exception "in" v:throwpoint
6389 endtry
6390
6391 try
6392 Xpath 262144 " X: 262144
6393 let var = G("except3", "throw3", 5)
6394 Xpath 524288 " X: 0
6395 catch /^except3/
6396 Xpath 1048576 " X: 0
6397 catch /^throw3$/
6398 Xpath 2097152 " X: 2097152
6399 catch /.*/
6400 Xpath 4194304 " X: 0
6401 Xout "throw3:" v:exception "in" v:throwpoint
6402 finally
6403 unlet! var
6404 endtry
6405
6406 let expected = "F1T1F2T2T3G4T4G5T5"
6407 if taken != expected
6408 Xpath 8388608 " X: 0
6409 Xout "'taken' is" taken "instead of" expected
6410 endif
6411
6412catch /^0$/ " default return value
6413 Xpath 16777216 " X: 0
6414 Xout v:throwpoint
6415catch /.*/
6416 Xpath 33554432 " X: 0
6417 Xout v:exception "in" v:throwpoint
6418endtry
6419
6420Xpath 67108864 " X: 67108864
6421
6422unlet taken expected
6423delfunction THROW
6424delfunction F
6425delfunction G
6426
6427Xcheck 69544277
6428
6429
6430"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006431" Test 71: :throw across :echo variants and :execute {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00006432"
6433" On an :echo, :echon, :echomsg, :echoerr, or :execute command, an
6434" exception might be thrown during evaluation of the arguments to
6435" be displayed or executed as a command, respectively. Any following
6436" arguments are not evaluated, then. The exception can be caught by
6437" the script.
6438"-------------------------------------------------------------------------------
6439
6440XpathINIT
6441
6442let taken = ""
6443
6444function! THROW(x, n)
6445 let g:taken = g:taken . "T" . a:n
6446 throw a:x
6447endfunction
6448
6449function! F(n)
6450 let g:taken = g:taken . "F" . a:n
6451 return "F" . a:n
6452endfunction
6453
6454try
6455 try
6456 Xpath 1 " X: 1
6457 echo "echo" . THROW("echo-except", 1) F(1)
6458 Xpath 2 " X: 0
6459 catch /^echo-except$/
6460 Xpath 4 " X: 4
6461 catch /.*/
6462 Xpath 8 " X: 0
6463 Xout "echo:" v:exception "in" v:throwpoint
6464 endtry
6465
6466 try
6467 Xpath 16 " X: 16
6468 echon "echon" . THROW("echon-except", 2) F(2)
6469 Xpath 32 " X: 0
6470 catch /^echon-except$/
6471 Xpath 64 " X: 64
6472 catch /.*/
6473 Xpath 128 " X: 0
6474 Xout "echon:" v:exception "in" v:throwpoint
6475 endtry
6476
6477 try
6478 Xpath 256 " X: 256
6479 echomsg "echomsg" . THROW("echomsg-except", 3) F(3)
6480 Xpath 512 " X: 0
6481 catch /^echomsg-except$/
6482 Xpath 1024 " X: 1024
6483 catch /.*/
6484 Xpath 2048 " X: 0
6485 Xout "echomsg:" v:exception "in" v:throwpoint
6486 endtry
6487
6488 try
6489 Xpath 4096 " X: 4096
6490 echoerr "echoerr" . THROW("echoerr-except", 4) F(4)
6491 Xpath 8192 " X: 0
6492 catch /^echoerr-except$/
6493 Xpath 16384 " X: 16384
6494 catch /Vim/
6495 Xpath 32768 " X: 0
6496 catch /echoerr/
6497 Xpath 65536 " X: 0
6498 catch /.*/
6499 Xpath 131072 " X: 0
6500 Xout "echoerr:" v:exception "in" v:throwpoint
6501 endtry
6502
6503 try
6504 Xpath 262144 " X: 262144
6505 execute "echo 'execute" . THROW("execute-except", 5) F(5) "'"
6506 Xpath 524288 " X: 0
6507 catch /^execute-except$/
6508 Xpath 1048576 " X: 1048576
6509 catch /.*/
6510 Xpath 2097152 " X: 0
6511 Xout "execute:" v:exception "in" v:throwpoint
6512 endtry
6513
6514 let expected = "T1T2T3T4T5"
6515 if taken != expected
6516 Xpath 4194304 " X: 0
6517 Xout "'taken' is" taken "instead of" expected
6518 endif
6519
6520catch /^0$/ " default return value
6521 Xpath 8388608 " X: 0
6522 Xout v:throwpoint
6523catch /.*/
6524 Xpath 16777216 " X: 0
6525 Xout v:exception "in" v:throwpoint
6526endtry
6527
6528Xpath 33554432 " X: 33554432
6529
6530unlet taken expected
6531delfunction THROW
6532delfunction F
6533
6534Xcheck 34886997
6535
6536
6537"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006538" Test 72: :throw across :let or :unlet {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00006539"
6540" On a :let command, an exception might be thrown during evaluation
6541" of the expression to assign. On an :let or :unlet command, the
6542" evaluation of the name of the variable to be assigned or list or
6543" deleted, respectively, may throw an exception. Any following
6544" arguments are not evaluated, then. The exception can be caught by
6545" the script.
6546"-------------------------------------------------------------------------------
6547
6548XpathINIT
6549
6550let throwcount = 0
6551
6552function! THROW(x)
6553 let g:throwcount = g:throwcount + 1
6554 throw a:x
6555endfunction
6556
6557try
6558 try
6559 let $VAR = "old_value"
6560 Xpath 1 " X: 1
6561 let $VAR = "let(" . THROW("var") . ")"
6562 Xpath 2 " X: 0
6563 catch /^var$/
6564 Xpath 4 " X: 4
6565 finally
6566 if $VAR != "old_value"
6567 Xpath 8 " X: 0
6568 endif
6569 endtry
6570
6571 try
6572 let @a = "old_value"
6573 Xpath 16 " X: 16
6574 let @a = "let(" . THROW("reg") . ")"
6575 Xpath 32 " X: 0
6576 catch /^reg$/
6577 try
6578 Xpath 64 " X: 64
6579 let @A = "let(" . THROW("REG") . ")"
6580 Xpath 128 " X: 0
6581 catch /^REG$/
6582 Xpath 256 " X: 256
6583 endtry
6584 finally
6585 if @a != "old_value"
6586 Xpath 512 " X: 0
6587 endif
6588 if @A != "old_value"
6589 Xpath 1024 " X: 0
6590 endif
6591 endtry
6592
6593 try
6594 let saved_gpath = &g:path
6595 let saved_lpath = &l:path
6596 Xpath 2048 " X: 2048
6597 let &path = "let(" . THROW("opt") . ")"
6598 Xpath 4096 " X: 0
6599 catch /^opt$/
6600 try
6601 Xpath 8192 " X: 8192
6602 let &g:path = "let(" . THROW("gopt") . ")"
6603 Xpath 16384 " X: 0
6604 catch /^gopt$/
6605 try
6606 Xpath 32768 " X: 32768
6607 let &l:path = "let(" . THROW("lopt") . ")"
6608 Xpath 65536 " X: 0
6609 catch /^lopt$/
6610 Xpath 131072 " X: 131072
6611 endtry
6612 endtry
6613 finally
6614 if &g:path != saved_gpath || &l:path != saved_lpath
6615 Xpath 262144 " X: 0
6616 endif
6617 let &g:path = saved_gpath
6618 let &l:path = saved_lpath
6619 endtry
6620
6621 unlet! var1 var2 var3
6622
6623 try
6624 Xpath 524288 " X: 524288
6625 let var1 = "let(" . THROW("var1") . ")"
6626 Xpath 1048576 " X: 0
6627 catch /^var1$/
6628 Xpath 2097152 " X: 2097152
6629 finally
6630 if exists("var1")
6631 Xpath 4194304 " X: 0
6632 endif
6633 endtry
6634
6635 try
6636 let var2 = "old_value"
6637 Xpath 8388608 " X: 8388608
6638 let var2 = "let(" . THROW("var2"). ")"
6639 Xpath 16777216 " X: 0
6640 catch /^var2$/
6641 Xpath 33554432 " X: 33554432
6642 finally
6643 if var2 != "old_value"
6644 Xpath 67108864 " X: 0
6645 endif
6646 endtry
6647
6648 try
6649 Xpath 134217728 " X: 134217728
6650 let var{THROW("var3")} = 4711
6651 Xpath 268435456 " X: 0
6652 catch /^var3$/
6653 Xpath 536870912 " X: 536870912
6654 endtry
6655
6656 let addpath = ""
6657
6658 function ADDPATH(p)
6659 let g:addpath = g:addpath . a:p
6660 endfunction
6661
6662 try
6663 call ADDPATH("T1")
6664 let var{THROW("var4")} var{ADDPATH("T2")} | call ADDPATH("T3")
6665 call ADDPATH("T4")
6666 catch /^var4$/
6667 call ADDPATH("T5")
6668 endtry
6669
6670 try
6671 call ADDPATH("T6")
6672 unlet var{THROW("var5")} var{ADDPATH("T7")} | call ADDPATH("T8")
6673 call ADDPATH("T9")
6674 catch /^var5$/
6675 call ADDPATH("T10")
6676 endtry
6677
6678 if addpath != "T1T5T6T10" || throwcount != 11
6679 throw "addpath: " . addpath . ", throwcount: " . throwcount
6680 endif
6681
6682 Xpath 1073741824 " X: 1073741824
6683
6684catch /.*/
6685 " The Xpath command does not accept 2^31 (negative); add explicitly:
6686 let Xpath = Xpath + 2147483648 " X: 0
6687 Xout v:exception "in" v:throwpoint
6688endtry
6689
6690unlet! var1 var2 var3 addpath throwcount
6691delfunction THROW
6692
6693Xcheck 1789569365
6694
6695
6696"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006697" Test 73: :throw across :function, :delfunction {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00006698"
6699" The :function and :delfunction commands may cause an expression
6700" specified in braces to be evaluated. During evaluation, an
6701" exception might be thrown. The exception can be caught by the
6702" script.
6703"-------------------------------------------------------------------------------
6704
6705XpathINIT
6706
6707let taken = ""
6708
6709function! THROW(x, n)
6710 let g:taken = g:taken . "T" . a:n
6711 throw a:x
6712endfunction
6713
6714function! EXPR(x, n)
6715 let g:taken = g:taken . "E" . a:n
6716 if a:n % 2 == 0
6717 call THROW(a:x, a:n)
6718 endif
6719 return 2 - a:n % 2
6720endfunction
6721
6722try
6723 try
6724 " Define function.
6725 Xpath 1 " X: 1
6726 function! F0()
6727 endfunction
6728 Xpath 2 " X: 2
6729 function! F{EXPR("function-def-ok", 1)}()
6730 endfunction
6731 Xpath 4 " X: 4
6732 function! F{EXPR("function-def", 2)}()
6733 endfunction
6734 Xpath 8 " X: 0
6735 catch /^function-def-ok$/
6736 Xpath 16 " X: 0
6737 catch /^function-def$/
6738 Xpath 32 " X: 32
6739 catch /.*/
6740 Xpath 64 " X: 0
6741 Xout "def:" v:exception "in" v:throwpoint
6742 endtry
6743
6744 try
6745 " List function.
6746 Xpath 128 " X: 128
6747 function F0
6748 Xpath 256 " X: 256
6749 function F{EXPR("function-lst-ok", 3)}
6750 Xpath 512 " X: 512
6751 function F{EXPR("function-lst", 4)}
6752 Xpath 1024 " X: 0
6753 catch /^function-lst-ok$/
6754 Xpath 2048 " X: 0
6755 catch /^function-lst$/
6756 Xpath 4096 " X: 4096
6757 catch /.*/
6758 Xpath 8192 " X: 0
6759 Xout "lst:" v:exception "in" v:throwpoint
6760 endtry
6761
6762 try
6763 " Delete function
6764 Xpath 16384 " X: 16384
6765 delfunction F0
6766 Xpath 32768 " X: 32768
6767 delfunction F{EXPR("function-del-ok", 5)}
6768 Xpath 65536 " X: 65536
6769 delfunction F{EXPR("function-del", 6)}
6770 Xpath 131072 " X: 0
6771 catch /^function-del-ok$/
6772 Xpath 262144 " X: 0
6773 catch /^function-del$/
6774 Xpath 524288 " X: 524288
6775 catch /.*/
6776 Xpath 1048576 " X: 0
6777 Xout "del:" v:exception "in" v:throwpoint
6778 endtry
6779
6780 let expected = "E1E2T2E3E4T4E5E6T6"
6781 if taken != expected
6782 Xpath 2097152 " X: 0
6783 Xout "'taken' is" taken "instead of" expected
6784 endif
6785
6786catch /.*/
6787 Xpath 4194304 " X: 0
6788 Xout v:exception "in" v:throwpoint
6789endtry
6790
6791Xpath 8388608 " X: 8388608
6792
6793unlet taken expected
6794delfunction THROW
6795delfunction EXPR
6796
6797Xcheck 9032615
6798
6799
6800"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006801" Test 74: :throw across builtin functions and commands {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00006802"
6803" Some functions like exists(), searchpair() take expression
6804" arguments, other functions or commands like substitute() or
6805" :substitute cause an expression (specified in the regular
6806" expression) to be evaluated. During evaluation an exception
6807" might be thrown. The exception can be caught by the script.
6808"-------------------------------------------------------------------------------
6809
6810XpathINIT
6811
6812let taken = ""
6813
6814function! THROW(x, n)
6815 let g:taken = g:taken . "T" . a:n
6816 throw a:x
6817endfunction
6818
6819function! EXPR(x, n)
6820 let g:taken = g:taken . "E" . a:n
6821 call THROW(a:x . a:n, a:n)
6822 return "EXPR"
6823endfunction
6824
6825function! SKIP(x, n)
6826 let g:taken = g:taken . "S" . a:n . "(" . line(".")
6827 let theline = getline(".")
6828 if theline =~ "skip"
6829 let g:taken = g:taken . "s)"
6830 return 1
6831 elseif theline =~ "throw"
6832 let g:taken = g:taken . "t)"
6833 call THROW(a:x . a:n, a:n)
6834 else
6835 let g:taken = g:taken . ")"
6836 return 0
6837 endif
6838endfunction
6839
6840function! SUBST(x, n)
6841 let g:taken = g:taken . "U" . a:n . "(" . line(".")
6842 let theline = getline(".")
6843 if theline =~ "not" " SUBST() should not be called for this line
6844 let g:taken = g:taken . "n)"
6845 call THROW(a:x . a:n, a:n)
6846 elseif theline =~ "throw"
6847 let g:taken = g:taken . "t)"
6848 call THROW(a:x . a:n, a:n)
6849 else
6850 let g:taken = g:taken . ")"
6851 return "replaced"
6852 endif
6853endfunction
6854
6855try
6856 try
6857 Xpath 1 " X: 1
6858 let result = exists('*{EXPR("exists", 1)}')
6859 Xpath 2 " X: 0
6860 catch /^exists1$/
6861 Xpath 4 " X: 4
6862 try
6863 let result = exists('{EXPR("exists", 2)}')
6864 Xpath 8 " X: 0
6865 catch /^exists2$/
6866 Xpath 16 " X: 16
6867 catch /.*/
6868 Xpath 32 " X: 0
6869 Xout "exists2:" v:exception "in" v:throwpoint
6870 endtry
6871 catch /.*/
6872 Xpath 64 " X: 0
6873 Xout "exists1:" v:exception "in" v:throwpoint
6874 endtry
6875
6876 try
6877 let file = tempname()
6878 exec "edit" file
6879 insert
6880begin
6881 xx
6882middle 3
6883 xx
6884middle 5 skip
6885 xx
6886middle 7 throw
6887 xx
6888end
6889.
6890 normal! gg
6891 Xpath 128 " X: 128
6892 let result =
6893 \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 3)')
6894 Xpath 256 " X: 256
6895 let result =
6896 \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 4)')
6897 Xpath 512 " X: 0
6898 let result =
6899 \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 5)')
6900 Xpath 1024 " X: 0
6901 catch /^searchpair[35]$/
6902 Xpath 2048 " X: 0
6903 catch /^searchpair4$/
6904 Xpath 4096 " X: 4096
6905 catch /.*/
6906 Xpath 8192 " X: 0
6907 Xout "searchpair:" v:exception "in" v:throwpoint
6908 finally
6909 bwipeout!
6910 call delete(file)
6911 endtry
6912
6913 try
6914 let file = tempname()
6915 exec "edit" file
6916 insert
6917subst 1
6918subst 2
6919not
6920subst 4
6921subst throw
6922subst 6
6923.
6924 normal! gg
6925 Xpath 16384 " X: 16384
6926 1,2substitute/subst/\=SUBST("substitute", 6)/
6927 try
6928 Xpath 32768 " X: 32768
6929 try
6930 let v:errmsg = ""
6931 3substitute/subst/\=SUBST("substitute", 7)/
6932 finally
6933 if v:errmsg != ""
6934 " If exceptions are not thrown on errors, fake the error
6935 " exception in order to get the same execution path.
6936 throw "faked Vim(substitute)"
6937 endif
6938 endtry
6939 catch /Vim(substitute)/ " Pattern not found ('e' flag missing)
6940 Xpath 65536 " X: 65536
6941 3substitute/subst/\=SUBST("substitute", 8)/e
6942 Xpath 131072 " X: 131072
6943 endtry
6944 Xpath 262144 " X: 262144
6945 4,6substitute/subst/\=SUBST("substitute", 9)/
6946 Xpath 524288 " X: 0
6947 catch /^substitute[678]/
6948 Xpath 1048576 " X: 0
6949 catch /^substitute9/
6950 Xpath 2097152 " X: 2097152
6951 finally
6952 bwipeout!
6953 call delete(file)
6954 endtry
6955
6956 try
6957 Xpath 4194304 " X: 4194304
6958 let var = substitute("sub", "sub", '\=THROW("substitute()y", 10)', '')
6959 Xpath 8388608 " X: 0
6960 catch /substitute()y/
6961 Xpath 16777216 " X: 16777216
6962 catch /.*/
6963 Xpath 33554432 " X: 0
6964 Xout "substitute()y:" v:exception "in" v:throwpoint
6965 endtry
6966
6967 try
6968 Xpath 67108864 " X: 67108864
6969 let var = substitute("not", "sub", '\=THROW("substitute()n", 11)', '')
6970 Xpath 134217728 " X: 134217728
6971 catch /substitute()n/
6972 Xpath 268435456 " X: 0
6973 catch /.*/
6974 Xpath 536870912 " X: 0
6975 Xout "substitute()n:" v:exception "in" v:throwpoint
6976 endtry
6977
6978 let expected = "E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10"
6979 if taken != expected
6980 Xpath 1073741824 " X: 0
6981 Xout "'taken' is" taken "instead of" expected
6982 endif
6983
6984catch /.*/
6985 " The Xpath command does not accept 2^31 (negative); add explicitly:
6986 let Xpath = Xpath + 2147483648 " X: 0
6987 Xout v:exception "in" v:throwpoint
6988endtry
6989
6990unlet result var taken expected
6991delfunction THROW
6992delfunction EXPR
6993delfunction SKIP
6994delfunction SUBST
6995
6996Xcheck 224907669
6997
6998
6999"-------------------------------------------------------------------------------
7000" Test 75: Errors in builtin functions. {{{1
7001"
7002" On an error in a builtin function called inside a :try/:endtry
7003" region, the evaluation of the expression calling that function and
7004" the command containing that expression are abandoned. The error can
7005" be caught as an exception.
7006"
7007" A simple :call of the builtin function is a trivial case. If the
7008" builtin function is called in the argument list of another function,
7009" no further arguments are evaluated, and the other function is not
7010" executed. If the builtin function is called from the argument of
7011" a :return command, the :return command is not executed. If the
7012" builtin function is called from the argument of a :throw command,
7013" the :throw command is not executed. The evaluation of the
7014" expression calling the builtin function is abandoned.
7015"-------------------------------------------------------------------------------
7016
7017XpathINIT
7018
7019function! F1(arg1)
7020 Xpath 1 " X: 0
7021endfunction
7022
7023function! F2(arg1, arg2)
7024 Xpath 2 " X: 0
7025endfunction
7026
7027function! G()
7028 Xpath 4 " X: 0
7029endfunction
7030
7031function! H()
7032 Xpath 8 " X: 0
7033endfunction
7034
7035function! R()
7036 while 1
7037 try
7038 let caught = 0
7039 let v:errmsg = ""
7040 Xpath 16 " X: 16
7041 return append(1, "s")
7042 catch /E21/
7043 let caught = 1
7044 catch /.*/
7045 Xpath 32 " X: 0
7046 finally
7047 Xpath 64 " X: 64
7048 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
7049 Xpath 128 " X: 128
7050 endif
7051 break " discard error for $VIMNOERRTHROW
7052 endtry
7053 endwhile
7054 Xpath 256 " X: 256
7055endfunction
7056
7057try
7058 set noma " let append() fail with "E21"
7059
7060 while 1
7061 try
7062 let caught = 0
7063 let v:errmsg = ""
7064 Xpath 512 " X: 512
7065 call append(1, "s")
7066 catch /E21/
7067 let caught = 1
7068 catch /.*/
7069 Xpath 1024 " X: 0
7070 finally
7071 Xpath 2048 " X: 2048
7072 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
7073 Xpath 4096 " X: 4096
7074 endif
7075 break " discard error for $VIMNOERRTHROW
7076 endtry
7077 endwhile
7078
7079 while 1
7080 try
7081 let caught = 0
7082 let v:errmsg = ""
7083 Xpath 8192 " X: 8192
7084 call F1('x' . append(1, "s"))
7085 catch /E21/
7086 let caught = 1
7087 catch /.*/
7088 Xpath 16384 " X: 0
7089 finally
7090 Xpath 32768 " X: 32768
7091 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
7092 Xpath 65536 " X: 65536
7093 endif
7094 break " discard error for $VIMNOERRTHROW
7095 endtry
7096 endwhile
7097
7098 while 1
7099 try
7100 let caught = 0
7101 let v:errmsg = ""
7102 Xpath 131072 " X: 131072
7103 call F2('x' . append(1, "s"), G())
7104 catch /E21/
7105 let caught = 1
7106 catch /.*/
7107 Xpath 262144 " X: 0
7108 finally
7109 Xpath 524288 " X: 524288
7110 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
7111 Xpath 1048576 " X: 1048576
7112 endif
7113 break " discard error for $VIMNOERRTHROW
7114 endtry
7115 endwhile
7116
7117 call R()
7118
7119 while 1
7120 try
7121 let caught = 0
7122 let v:errmsg = ""
7123 Xpath 2097152 " X: 2097152
7124 throw "T" . append(1, "s")
7125 catch /E21/
7126 let caught = 1
7127 catch /^T.*/
7128 Xpath 4194304 " X: 0
7129 catch /.*/
7130 Xpath 8388608 " X: 0
7131 finally
7132 Xpath 16777216 " X: 16777216
7133 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
7134 Xpath 33554432 " X: 33554432
7135 endif
7136 break " discard error for $VIMNOERRTHROW
7137 endtry
7138 endwhile
7139
7140 while 1
7141 try
7142 let caught = 0
7143 let v:errmsg = ""
7144 Xpath 67108864 " X: 67108864
7145 let x = "a"
7146 let x = x . "b" . append(1, "s") . H()
7147 catch /E21/
7148 let caught = 1
7149 catch /.*/
7150 Xpath 134217728 " X: 0
7151 finally
7152 Xpath 268435456 " X: 268435456
7153 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
7154 Xpath 536870912 " X: 536870912
7155 endif
7156 if x == "a"
7157 Xpath 1073741824 " X: 1073741824
7158 endif
7159 break " discard error for $VIMNOERRTHROW
7160 endtry
7161 endwhile
7162catch /.*/
7163 " The Xpath command does not accept 2^31 (negative); add explicitly:
7164 let Xpath = Xpath + 2147483648 " X: 0
7165 Xout v:exception "in" v:throwpoint
7166finally
7167 set ma&
7168endtry
7169
7170unlet! caught x
7171delfunction F1
7172delfunction F2
7173delfunction G
7174delfunction H
7175delfunction R
7176
7177Xcheck 2000403408
7178
7179
7180"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00007181" Test 76: Errors, interrupts, :throw during expression evaluation {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00007182"
7183" When a function call made during expression evaluation is aborted
7184" due to an error inside a :try/:endtry region or due to an interrupt
7185" or a :throw, the expression evaluation is aborted as well. No
7186" message is displayed for the cancelled expression evaluation. On an
7187" error not inside :try/:endtry, the expression evaluation continues.
7188"-------------------------------------------------------------------------------
7189
7190XpathINIT
7191
7192if ExtraVim()
7193
7194 let taken = ""
7195
7196 function! ERR(n)
7197 let g:taken = g:taken . "E" . a:n
7198 asdf
7199 endfunction
7200
7201 function! ERRabort(n) abort
7202 let g:taken = g:taken . "A" . a:n
7203 asdf
Bram Moolenaare13305e2005-06-19 22:54:15 +00007204 endfunction " returns -1; may cause follow-up msg for illegal var/func name
7205
7206 function! WRAP(n, arg)
7207 let g:taken = g:taken . "W" . a:n
7208 let g:saved_errmsg = v:errmsg
7209 return arg
7210 endfunction
Bram Moolenaar071d4272004-06-13 20:20:40 +00007211
7212 function! INT(n)
7213 let g:taken = g:taken . "I" . a:n
7214 "INTERRUPT9
7215 let dummy = 0
7216 endfunction
7217
7218 function! THR(n)
7219 let g:taken = g:taken . "T" . a:n
7220 throw "should not be caught"
7221 endfunction
7222
7223 function! CONT(n)
7224 let g:taken = g:taken . "C" . a:n
7225 endfunction
7226
7227 function! MSG(n)
7228 let g:taken = g:taken . "M" . a:n
Bram Moolenaare13305e2005-06-19 22:54:15 +00007229 let errmsg = (a:n >= 37 && a:n <= 44) ? g:saved_errmsg : v:errmsg
7230 let msgptn = (a:n >= 10 && a:n <= 27) ? "^$" : "asdf"
7231 if errmsg !~ msgptn
7232 let g:taken = g:taken . "x"
7233 Xout "Expr" a:n.": Unexpected message:" v:errmsg
Bram Moolenaar071d4272004-06-13 20:20:40 +00007234 endif
7235 let v:errmsg = ""
Bram Moolenaare13305e2005-06-19 22:54:15 +00007236 let g:saved_errmsg = ""
Bram Moolenaar071d4272004-06-13 20:20:40 +00007237 endfunction
7238
7239 let v:errmsg = ""
7240
7241 try
7242 let t = 1
7243 XloopINIT 1 2
7244 while t <= 9
7245 Xloop 1 " X: 511
7246 try
7247 if t == 1
7248 let v{ERR(t) + CONT(t)} = 0
7249 elseif t == 2
7250 let v{ERR(t) + CONT(t)}
7251 elseif t == 3
7252 let var = exists('v{ERR(t) + CONT(t)}')
7253 elseif t == 4
7254 unlet v{ERR(t) + CONT(t)}
7255 elseif t == 5
7256 function F{ERR(t) + CONT(t)}()
7257 endfunction
7258 elseif t == 6
7259 function F{ERR(t) + CONT(t)}
7260 elseif t == 7
7261 let var = exists('*F{ERR(t) + CONT(t)}')
7262 elseif t == 8
7263 delfunction F{ERR(t) + CONT(t)}
7264 elseif t == 9
7265 let var = ERR(t) + CONT(t)
7266 endif
7267 catch /asdf/
7268 " v:errmsg is not set when the error message is converted to an
7269 " exception. Set it to the original error message.
7270 let v:errmsg = substitute(v:exception, '^Vim:', '', "")
7271 catch /^Vim\((\a\+)\)\=:/
7272 " An error exception has been thrown after the original error.
7273 let v:errmsg = ""
7274 finally
7275 call MSG(t)
7276 let t = t + 1
7277 XloopNEXT
7278 continue " discard an aborting error
7279 endtry
7280 endwhile
7281 catch /.*/
7282 Xpath 512 " X: 0
7283 Xout v:exception "in" ExtraVimThrowpoint()
7284 endtry
7285
7286 try
7287 let t = 10
7288 XloopINIT 1024 2
7289 while t <= 18
7290 Xloop 1 " X: 1024 * 511
7291 try
7292 if t == 10
7293 let v{INT(t) + CONT(t)} = 0
7294 elseif t == 11
7295 let v{INT(t) + CONT(t)}
7296 elseif t == 12
7297 let var = exists('v{INT(t) + CONT(t)}')
7298 elseif t == 13
7299 unlet v{INT(t) + CONT(t)}
7300 elseif t == 14
7301 function F{INT(t) + CONT(t)}()
7302 endfunction
7303 elseif t == 15
7304 function F{INT(t) + CONT(t)}
7305 elseif t == 16
7306 let var = exists('*F{INT(t) + CONT(t)}')
7307 elseif t == 17
7308 delfunction F{INT(t) + CONT(t)}
7309 elseif t == 18
7310 let var = INT(t) + CONT(t)
7311 endif
7312 catch /^Vim\((\a\+)\)\=:\(Interrupt\)\@!/
7313 " An error exception has been triggered after the interrupt.
7314 let v:errmsg = substitute(v:exception,
7315 \ '^Vim\((\a\+)\)\=:', '', "")
7316 finally
7317 call MSG(t)
7318 let t = t + 1
7319 XloopNEXT
7320 continue " discard interrupt
7321 endtry
7322 endwhile
7323 catch /.*/
7324 Xpath 524288 " X: 0
7325 Xout v:exception "in" ExtraVimThrowpoint()
7326 endtry
7327
7328 try
7329 let t = 19
7330 XloopINIT 1048576 2
7331 while t <= 27
7332 Xloop 1 " X: 1048576 * 511
7333 try
7334 if t == 19
7335 let v{THR(t) + CONT(t)} = 0
7336 elseif t == 20
7337 let v{THR(t) + CONT(t)}
7338 elseif t == 21
7339 let var = exists('v{THR(t) + CONT(t)}')
7340 elseif t == 22
7341 unlet v{THR(t) + CONT(t)}
7342 elseif t == 23
7343 function F{THR(t) + CONT(t)}()
7344 endfunction
7345 elseif t == 24
7346 function F{THR(t) + CONT(t)}
7347 elseif t == 25
7348 let var = exists('*F{THR(t) + CONT(t)}')
7349 elseif t == 26
7350 delfunction F{THR(t) + CONT(t)}
7351 elseif t == 27
7352 let var = THR(t) + CONT(t)
7353 endif
7354 catch /^Vim\((\a\+)\)\=:/
7355 " An error exception has been triggered after the :throw.
7356 let v:errmsg = substitute(v:exception,
7357 \ '^Vim\((\a\+)\)\=:', '', "")
7358 finally
7359 call MSG(t)
7360 let t = t + 1
7361 XloopNEXT
7362 continue " discard exception
7363 endtry
7364 endwhile
7365 catch /.*/
7366 Xpath 536870912 " X: 0
7367 Xout v:exception "in" ExtraVimThrowpoint()
7368 endtry
7369
7370 let v{ERR(28) + CONT(28)} = 0
7371 call MSG(28)
7372 let v{ERR(29) + CONT(29)}
7373 call MSG(29)
7374 let var = exists('v{ERR(30) + CONT(30)}')
7375 call MSG(30)
7376 unlet v{ERR(31) + CONT(31)}
7377 call MSG(31)
7378 function F{ERR(32) + CONT(32)}()
7379 endfunction
7380 call MSG(32)
7381 function F{ERR(33) + CONT(33)}
7382 call MSG(33)
7383 let var = exists('*F{ERR(34) + CONT(34)}')
7384 call MSG(34)
7385 delfunction F{ERR(35) + CONT(35)}
7386 call MSG(35)
7387 let var = ERR(36) + CONT(36)
7388 call MSG(36)
7389
Bram Moolenaare13305e2005-06-19 22:54:15 +00007390 let saved_errmsg = ""
7391
7392 let v{WRAP(37, ERRabort(37)) + CONT(37)} = 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00007393 call MSG(37)
Bram Moolenaare13305e2005-06-19 22:54:15 +00007394 let v{WRAP(38, ERRabort(38)) + CONT(38)}
Bram Moolenaar071d4272004-06-13 20:20:40 +00007395 call MSG(38)
Bram Moolenaare13305e2005-06-19 22:54:15 +00007396 let var = exists('v{WRAP(39, ERRabort(39)) + CONT(39)}')
Bram Moolenaar071d4272004-06-13 20:20:40 +00007397 call MSG(39)
Bram Moolenaare13305e2005-06-19 22:54:15 +00007398 unlet v{WRAP(40, ERRabort(40)) + CONT(40)}
Bram Moolenaar071d4272004-06-13 20:20:40 +00007399 call MSG(40)
Bram Moolenaare13305e2005-06-19 22:54:15 +00007400 function F{WRAP(41, ERRabort(41)) + CONT(41)}()
Bram Moolenaar071d4272004-06-13 20:20:40 +00007401 endfunction
7402 call MSG(41)
Bram Moolenaare13305e2005-06-19 22:54:15 +00007403 function F{WRAP(42, ERRabort(42)) + CONT(42)}
Bram Moolenaar071d4272004-06-13 20:20:40 +00007404 call MSG(42)
Bram Moolenaare13305e2005-06-19 22:54:15 +00007405 let var = exists('*F{WRAP(43, ERRabort(43)) + CONT(43)}')
Bram Moolenaar071d4272004-06-13 20:20:40 +00007406 call MSG(43)
Bram Moolenaare13305e2005-06-19 22:54:15 +00007407 delfunction F{WRAP(44, ERRabort(44)) + CONT(44)}
Bram Moolenaar071d4272004-06-13 20:20:40 +00007408 call MSG(44)
7409 let var = ERRabort(45) + CONT(45)
7410 call MSG(45)
7411
7412 Xpath 1073741824 " X: 1073741824
7413
7414 let expected = ""
7415 \ . "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9"
7416 \ . "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18"
7417 \ . "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27"
7418 \ . "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33"
7419 \ . "E34C34M34E35C35M35E36C36M36"
Bram Moolenaare13305e2005-06-19 22:54:15 +00007420 \ . "A37W37C37M37A38W38C38M38A39W39C39M39A40W40C40M40A41W41C41M41"
7421 \ . "A42W42C42M42A43W43C43M43A44W44C44M44A45C45M45"
Bram Moolenaar071d4272004-06-13 20:20:40 +00007422
7423 if taken != expected
7424 " The Xpath command does not accept 2^31 (negative); display explicitly:
7425 exec "!echo 2147483648 >>" . g:ExtraVimResult
7426 " X: 0
7427 Xout "'taken' is" taken "instead of" expected
7428 if substitute(taken,
7429 \ '\(.*\)E3C3M3x\(.*\)E30C30M30x\(.*\)A39C39M39x\(.*\)',
7430 \ '\1E3M3\2E30C30M30\3A39C39M39\4',
7431 \ "") == expected
7432 Xout "Is ++emsg_skip for var with expr_start non-NULL"
7433 \ "in f_exists ok?"
7434 endif
7435 endif
7436
Bram Moolenaare13305e2005-06-19 22:54:15 +00007437 unlet! v var saved_errmsg taken expected
Bram Moolenaar071d4272004-06-13 20:20:40 +00007438 call delete(WA_t5)
7439 call delete(WA_t14)
7440 call delete(WA_t23)
7441 unlet! WA_t5 WA_t14 WA_t23
7442 delfunction WA_t5
7443 delfunction WA_t14
7444 delfunction WA_t23
7445
7446endif
7447
7448Xcheck 1610087935
7449
7450
7451"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00007452" Test 77: Errors, interrupts, :throw in name{brace-expression} {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00007453"
7454" When a function call made during evaluation of an expression in
7455" braces as part of a function name after ":function" is aborted due
7456" to an error inside a :try/:endtry region or due to an interrupt or
7457" a :throw, the expression evaluation is aborted as well, and the
7458" function definition is ignored, skipping all commands to the
7459" ":endfunction". On an error not inside :try/:endtry, the expression
7460" evaluation continues and the function gets defined, and can be
7461" called and deleted.
7462"-------------------------------------------------------------------------------
7463
7464XpathINIT
7465
7466XloopINIT 1 4
7467
7468function! ERR() abort
7469 Xloop 1 " X: 1 + 4 + 16 + 64
7470 asdf
7471endfunction " returns -1
7472
7473function! OK()
7474 Xloop 2 " X: 2 * (1 + 4 + 16)
7475 let v:errmsg = ""
7476 return 0
7477endfunction
7478
7479let v:errmsg = ""
7480
7481Xpath 4096 " X: 4096
7482function! F{1 + ERR() + OK()}(arg)
7483 " F0 should be defined.
7484 if exists("a:arg") && a:arg == "calling"
7485 Xpath 8192 " X: 8192
7486 else
7487 Xpath 16384 " X: 0
7488 endif
7489endfunction
7490if v:errmsg != ""
7491 Xpath 32768 " X: 0
7492endif
7493XloopNEXT
7494
7495Xpath 65536 " X: 65536
7496call F{1 + ERR() + OK()}("calling")
7497if v:errmsg != ""
7498 Xpath 131072 " X: 0
7499endif
7500XloopNEXT
7501
7502Xpath 262144 " X: 262144
7503delfunction F{1 + ERR() + OK()}
7504if v:errmsg != ""
7505 Xpath 524288 " X: 0
7506endif
7507XloopNEXT
7508
7509try
7510 while 1
7511 let caught = 0
7512 try
7513 Xpath 1048576 " X: 1048576
7514 function! G{1 + ERR() + OK()}(arg)
7515 " G0 should not be defined, and the function body should be
7516 " skipped.
7517 if exists("a:arg") && a:arg == "calling"
7518 Xpath 2097152 " X: 0
7519 else
7520 Xpath 4194304 " X: 0
7521 endif
7522 " Use an unmatched ":finally" to check whether the body is
7523 " skipped when an error occurs in ERR(). This works whether or
7524 " not the exception is converted to an exception.
7525 finally
7526 Xpath 8388608 " X: 0
7527 Xout "Body of G{1 + ERR() + OK()}() not skipped"
7528 " Discard the aborting error or exception, and break the
7529 " while loop.
7530 break
7531 " End the try conditional and start a new one to avoid
7532 " ":catch after :finally" errors.
7533 endtry
7534 try
7535 Xpath 16777216 " X: 0
7536 endfunction
7537
7538 " When the function was not defined, this won't be reached - whether
7539 " the body was skipped or not. When the function was defined, it
7540 " can be called and deleted here.
7541 Xpath 33554432 " X: 0
7542 Xout "G0() has been defined"
7543 XloopNEXT
7544 try
7545 call G{1 + ERR() + OK()}("calling")
7546 catch /.*/
7547 Xpath 67108864 " X: 0
7548 endtry
7549 Xpath 134217728 " X: 0
7550 XloopNEXT
7551 try
7552 delfunction G{1 + ERR() + OK()}
7553 catch /.*/
7554 Xpath 268435456 " X: 0
7555 endtry
7556 catch /asdf/
7557 " Jumped to when the function is not defined and the body is
7558 " skipped.
7559 let caught = 1
7560 catch /.*/
7561 Xpath 536870912 " X: 0
7562 finally
7563 if !caught && !$VIMNOERRTHROW
7564 Xpath 1073741824 " X: 0
7565 endif
7566 break " discard error for $VIMNOERRTHROW
7567 endtry " jumped to when the body is not skipped
7568 endwhile
7569catch /.*/
7570 " The Xpath command does not accept 2^31 (negative); add explicitly:
7571 let Xpath = Xpath + 2147483648 " X: 0
7572 Xout "Body of G{1 + ERR() + OK()}() not skipped, exception caught"
7573 Xout v:exception "in" v:throwpoint
7574endtry
7575
7576Xcheck 1388671
7577
7578
7579"-------------------------------------------------------------------------------
7580" Test 78: Messages on parsing errors in expression evaluation {{{1
7581"
7582" When an expression evaluation detects a parsing error, an error
7583" message is given and converted to an exception, and the expression
7584" evaluation is aborted.
7585"-------------------------------------------------------------------------------
7586
7587XpathINIT
7588
7589if ExtraVim()
7590
7591 let taken = ""
7592
7593 function! F(n)
7594 let g:taken = g:taken . "F" . a:n
7595 endfunction
7596
7597 function! MSG(n, enr, emsg)
7598 let g:taken = g:taken . "M" . a:n
7599 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
7600 if a:enr == ""
7601 Xout "TODO: Add message number for:" a:emsg
7602 let v:errmsg = ":" . v:errmsg
7603 endif
7604 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
7605 if v:errmsg == ""
7606 Xout "Expr" a:n.": Message missing."
7607 let g:taken = g:taken . "x"
7608 else
7609 let v:errmsg = escape(v:errmsg, '"')
7610 Xout "Expr" a:n.": Unexpected message:" v:errmsg
Bram Moolenaar383f9bc2005-01-19 22:18:32 +00007611 Xout "Expected: " . a:enr . ': ' . a:emsg
Bram Moolenaar071d4272004-06-13 20:20:40 +00007612 let g:taken = g:taken . "X"
7613 endif
7614 endif
7615 endfunction
7616
7617 function! CONT(n)
7618 let g:taken = g:taken . "C" . a:n
7619 endfunction
7620
7621 let v:errmsg = ""
7622 XloopINIT 1 2
7623
7624 try
7625 let t = 1
7626 while t <= 14
7627 let g:taken = g:taken . "T" . t
7628 let v:errmsg = ""
7629 try
7630 let caught = 0
7631 if t == 1
7632 let v{novar + CONT(t)} = 0
7633 elseif t == 2
7634 let v{novar + CONT(t)}
7635 elseif t == 3
7636 let var = exists('v{novar + CONT(t)}')
7637 elseif t == 4
7638 unlet v{novar + CONT(t)}
7639 elseif t == 5
7640 function F{novar + CONT(t)}()
7641 endfunction
7642 elseif t == 6
7643 function F{novar + CONT(t)}
7644 elseif t == 7
7645 let var = exists('*F{novar + CONT(t)}')
7646 elseif t == 8
7647 delfunction F{novar + CONT(t)}
7648 elseif t == 9
7649 echo novar + CONT(t)
7650 elseif t == 10
7651 echo v{novar + CONT(t)}
7652 elseif t == 11
7653 echo F{novar + CONT(t)}
7654 elseif t == 12
7655 let var = novar + CONT(t)
7656 elseif t == 13
7657 let var = v{novar + CONT(t)}
7658 elseif t == 14
7659 let var = F{novar + CONT(t)}()
7660 endif
7661 catch /^Vim\((\a\+)\)\=:/
7662 " v:errmsg is not set when the error message is converted to an
7663 " exception. Set it to the original error message.
7664 let v:errmsg = substitute(v:exception,
7665 \ '^Vim\((\a\+)\)\=:', '', "")
7666 let caught = 1
7667 finally
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00007668 if t <= 8 && t != 3 && t != 7
7669 call MSG(t, 'E475', 'Invalid argument\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00007670 else
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00007671 if !caught " no error exceptions ($VIMNOERRTHROW set)
7672 call MSG(t, 'E15', "Invalid expression")
Bram Moolenaar071d4272004-06-13 20:20:40 +00007673 else
7674 call MSG(t, 'E121', "Undefined variable")
7675 endif
7676 endif
7677 let t = t + 1
7678 XloopNEXT
7679 continue " discard an aborting error
7680 endtry
7681 endwhile
7682 catch /.*/
7683 Xloop 1 " X: 0
7684 Xout t.":" v:exception "in" ExtraVimThrowpoint()
7685 endtry
7686
7687 function! T(n, expr, enr, emsg)
7688 try
7689 let g:taken = g:taken . "T" . a:n
7690 let v:errmsg = ""
7691 try
7692 let caught = 0
7693 execute "let var = " . a:expr
7694 catch /^Vim\((\a\+)\)\=:/
7695 " v:errmsg is not set when the error message is converted to an
7696 " exception. Set it to the original error message.
7697 let v:errmsg = substitute(v:exception,
7698 \ '^Vim\((\a\+)\)\=:', '', "")
7699 let caught = 1
7700 finally
7701 if !caught " no error exceptions ($VIMNOERRTHROW set)
7702 call MSG(a:n, 'E15', "Invalid expression")
7703 else
7704 call MSG(a:n, a:enr, a:emsg)
7705 endif
7706 XloopNEXT
7707 " Discard an aborting error:
7708 return
7709 endtry
7710 catch /.*/
7711 Xloop 1 " X: 0
7712 Xout a:n.":" v:exception "in" ExtraVimThrowpoint()
7713 endtry
7714 endfunction
7715
7716 call T(15, 'Nofunc() + CONT(15)', 'E117', "Unknown function")
7717 call T(16, 'F(1 2 + CONT(16))', 'E116', "Invalid arguments")
7718 call T(17, 'F(1, 2) + CONT(17)', 'E118', "Too many arguments")
7719 call T(18, 'F() + CONT(18)', 'E119', "Not enough arguments")
7720 call T(19, '{(1} + CONT(19)', 'E110', "Missing ')'")
7721 call T(20, '("abc"[1) + CONT(20)', 'E111', "Missing ']'")
7722 call T(21, '(1 +) + CONT(21)', 'E15', "Invalid expression")
7723 call T(22, '1 2 + CONT(22)', 'E15', "Invalid expression")
7724 call T(23, '(1 ? 2) + CONT(23)', 'E109', "Missing ':' after '?'")
7725 call T(24, '("abc) + CONT(24)', 'E114', "Missing quote")
7726 call T(25, "('abc) + CONT(25)", 'E115', "Missing quote")
Bram Moolenaar2fda12f2005-01-15 22:14:15 +00007727 call T(26, '& + CONT(26)', 'E112', "Option name missing")
Bram Moolenaar071d4272004-06-13 20:20:40 +00007728 call T(27, '&asdf + CONT(27)', 'E113', "Unknown option")
7729
7730 Xpath 134217728 " X: 134217728
7731
7732 let expected = ""
7733 \ . "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14"
7734 \ . "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25"
7735 \ . "T26M26T27M27"
7736
7737 if taken != expected
7738 Xpath 268435456 " X: 0
7739 Xout "'taken' is" taken "instead of" expected
7740 if substitute(taken, '\(.*\)T3M3x\(.*\)', '\1T3M3\2', "") == expected
7741 Xout "Is ++emsg_skip for var with expr_start non-NULL"
7742 \ "in f_exists ok?"
7743 endif
7744 endif
7745
7746 unlet! var caught taken expected
7747 call delete(WA_t5)
7748 unlet! WA_t5
7749 delfunction WA_t5
7750
7751endif
7752
7753Xcheck 134217728
7754
7755
7756"-------------------------------------------------------------------------------
7757" Test 79: Throwing one of several errors for the same command {{{1
7758"
7759" When several errors appear in a row (for instance during expression
7760" evaluation), the first as the most specific one is used when
7761" throwing an error exception. If, however, a syntax error is
7762" detected afterwards, this one is used for the error exception.
7763" On a syntax error, the next command is not executed, on a normal
7764" error, however, it is (relevant only in a function without the
7765" "abort" flag). v:errmsg is not set.
7766"
7767" If throwing error exceptions is configured off, v:errmsg is always
7768" set to the latest error message, that is, to the more general
7769" message or the syntax error, respectively.
7770"-------------------------------------------------------------------------------
7771
7772XpathINIT
7773
7774XloopINIT 1 2
7775
7776function! NEXT(cmd)
7777 exec a:cmd . " | Xloop 1"
7778endfunction
7779
7780call NEXT('echo novar') " X: 1 * 1 (checks nextcmd)
7781XloopNEXT
7782call NEXT('let novar #') " X: 0 * 2 (skips nextcmd)
7783XloopNEXT
7784call NEXT('unlet novar #') " X: 0 * 4 (skips nextcmd)
7785XloopNEXT
7786call NEXT('let {novar}') " X: 0 * 8 (skips nextcmd)
7787XloopNEXT
7788call NEXT('unlet{ novar}') " X: 0 * 16 (skips nextcmd)
7789
7790function! EXEC(cmd)
7791 exec a:cmd
7792endfunction
7793
7794function! MATCH(expected, msg, enr, emsg)
7795 let msg = a:msg
7796 if a:enr == ""
7797 Xout "TODO: Add message number for:" a:emsg
7798 let msg = ":" . msg
7799 endif
7800 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
7801 if msg !~ '^'.a:enr.':' || (english && msg !~ a:emsg)
7802 let match = 0
7803 if a:expected " no match although expected
7804 if a:msg == ""
7805 Xout "Message missing."
7806 else
7807 let msg = escape(msg, '"')
7808 Xout "Unexpected message:" msg
Bram Moolenaar9cd15162005-01-16 22:02:49 +00007809 Xout "Expected:" a:enr . ": " . a:emsg
Bram Moolenaar071d4272004-06-13 20:20:40 +00007810 endif
7811 endif
7812 else
7813 let match = 1
7814 if !a:expected " match although not expected
7815 let msg = escape(msg, '"')
7816 Xout "Unexpected message:" msg
Bram Moolenaar9cd15162005-01-16 22:02:49 +00007817 Xout "Expected none."
Bram Moolenaar071d4272004-06-13 20:20:40 +00007818 endif
7819 endif
7820 return match
7821endfunction
7822
7823try
7824
7825 while 1 " dummy loop
7826 try
7827 let v:errmsg = ""
7828 let caught = 0
7829 let thrmsg = ""
7830 call EXEC('echo novar') " normal error
7831 catch /^Vim\((\a\+)\)\=:/
7832 let caught = 1
7833 let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
7834 finally
7835 Xpath 32 " X: 32
7836 if !caught
7837 if !$VIMNOERRTHROW
7838 Xpath 64 " X: 0
7839 endif
7840 elseif !MATCH(1, thrmsg, 'E121', "Undefined variable")
7841 \ || v:errmsg != ""
7842 Xpath 128 " X: 0
7843 endif
7844 if !caught && !MATCH(1, v:errmsg, 'E15', "Invalid expression")
7845 Xpath 256 " X: 0
7846 endif
7847 break " discard error if $VIMNOERRTHROW == 1
7848 endtry
7849 endwhile
7850
7851 Xpath 512 " X: 512
7852 let cmd = "let"
7853 XloopINIT 1024 32
7854 while cmd != ""
7855 try
7856 let v:errmsg = ""
7857 let caught = 0
7858 let thrmsg = ""
7859 call EXEC(cmd . ' novar #') " normal plus syntax error
7860 catch /^Vim\((\a\+)\)\=:/
7861 let caught = 1
7862 let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
7863 finally
7864 Xloop 1 " X: 1024 * (1 + 32)
7865 if !caught
7866 if !$VIMNOERRTHROW
7867 Xloop 2 " X: 0
7868 endif
7869 else
7870 if cmd == "let"
Bram Moolenaar39676922010-09-29 16:55:49 +02007871 let match = MATCH(0, thrmsg, 'E121', "Undefined variable")
Bram Moolenaar071d4272004-06-13 20:20:40 +00007872 elseif cmd == "unlet"
7873 let match = MATCH(0, thrmsg, 'E108', "No such variable")
7874 endif
7875 if match " normal error
7876 Xloop 4 " X: 0
7877 endif
7878 if !MATCH(1, thrmsg, 'E488', "Trailing characters")
7879 \|| v:errmsg != ""
7880 " syntax error
7881 Xloop 8 " X: 0
7882 endif
7883 endif
7884 if !caught && !MATCH(1, v:errmsg, 'E488', "Trailing characters")
7885 " last error
7886 Xloop 16 " X: 0
7887 endif
7888 if cmd == "let"
7889 let cmd = "unlet"
7890 else
7891 let cmd = ""
7892 endif
7893 XloopNEXT
7894 continue " discard error if $VIMNOERRTHROW == 1
7895 endtry
7896 endwhile
7897
7898 Xpath 1048576 " X: 1048576
7899 let cmd = "let"
7900 XloopINIT 2097152 32
7901 while cmd != ""
7902 try
7903 let v:errmsg = ""
7904 let caught = 0
7905 let thrmsg = ""
7906 call EXEC(cmd . ' {novar}') " normal plus syntax error
7907 catch /^Vim\((\a\+)\)\=:/
7908 let caught = 1
7909 let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
7910 finally
7911 Xloop 1 " X: 2097152 * (1 + 32)
7912 if !caught
7913 if !$VIMNOERRTHROW
7914 Xloop 2 " X: 0
7915 endif
7916 else
7917 if MATCH(0, thrmsg, 'E121', "Undefined variable") " normal error
7918 Xloop 4 " X: 0
7919 endif
7920 if !MATCH(1, thrmsg, 'E475', 'Invalid argument\>')
7921 \ || v:errmsg != "" " syntax error
7922 Xloop 8 " X: 0
7923 endif
7924 endif
7925 if !caught && !MATCH(1, v:errmsg, 'E475', 'Invalid argument\>')
7926 " last error
7927 Xloop 16 " X: 0
7928 endif
7929 if cmd == "let"
7930 let cmd = "unlet"
7931 else
7932 let cmd = ""
7933 endif
7934 XloopNEXT
7935 continue " discard error if $VIMNOERRTHROW == 1
7936 endtry
7937 endwhile
7938
7939catch /.*/
7940 " The Xpath command does not accept 2^31 (negative); add explicitly:
7941 let Xpath = Xpath + 2147483648 " X: 0
7942 Xout v:exception "in" v:throwpoint
7943endtry
7944
7945unlet! next_command thrmsg match
7946delfunction NEXT
7947delfunction EXEC
7948delfunction MATCH
7949
7950Xcheck 70288929
7951
7952
7953"-------------------------------------------------------------------------------
7954" Test 80: Syntax error in expression for illegal :elseif {{{1
7955"
7956" If there is a syntax error in the expression after an illegal
7957" :elseif, an error message is given (or an error exception thrown)
7958" for the illegal :elseif rather than the expression error.
7959"-------------------------------------------------------------------------------
7960
7961XpathINIT
7962
7963function! MSG(enr, emsg)
7964 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
7965 if a:enr == ""
7966 Xout "TODO: Add message number for:" a:emsg
7967 let v:errmsg = ":" . v:errmsg
7968 endif
7969 let match = 1
7970 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
7971 let match = 0
7972 if v:errmsg == ""
7973 Xout "Message missing."
7974 else
7975 let v:errmsg = escape(v:errmsg, '"')
7976 Xout "Unexpected message:" v:errmsg
7977 endif
7978 endif
7979 return match
7980endfunction
7981
7982let v:errmsg = ""
7983if 0
7984else
7985elseif 1 ||| 2
7986endif
7987Xpath 1 " X: 1
7988if !MSG('E584', ":elseif after :else")
7989 Xpath 2 " X: 0
7990endif
7991
7992let v:errmsg = ""
7993if 1
7994else
7995elseif 1 ||| 2
7996endif
7997Xpath 4 " X: 4
7998if !MSG('E584', ":elseif after :else")
7999 Xpath 8 " X: 0
8000endif
8001
8002let v:errmsg = ""
8003elseif 1 ||| 2
8004Xpath 16 " X: 16
8005if !MSG('E582', ":elseif without :if")
8006 Xpath 32 " X: 0
8007endif
8008
8009let v:errmsg = ""
8010while 1
8011 elseif 1 ||| 2
8012endwhile
8013Xpath 64 " X: 64
8014if !MSG('E582', ":elseif without :if")
8015 Xpath 128 " X: 0
8016endif
8017
8018while 1
8019 try
8020 try
8021 let v:errmsg = ""
8022 let caught = 0
8023 if 0
8024 else
8025 elseif 1 ||| 2
8026 endif
8027 catch /^Vim\((\a\+)\)\=:/
8028 let caught = 1
8029 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
8030 finally
8031 Xpath 256 " X: 256
8032 if !caught && !$VIMNOERRTHROW
8033 Xpath 512 " X: 0
8034 endif
8035 if !MSG('E584', ":elseif after :else")
8036 Xpath 1024 " X: 0
8037 endif
8038 endtry
8039 catch /.*/
8040 Xpath 2048 " X: 0
8041 Xout v:exception "in" v:throwpoint
8042 finally
8043 break " discard error for $VIMNOERRTHROW
8044 endtry
8045endwhile
8046
8047while 1
8048 try
8049 try
8050 let v:errmsg = ""
8051 let caught = 0
8052 if 1
8053 else
8054 elseif 1 ||| 2
8055 endif
8056 catch /^Vim\((\a\+)\)\=:/
8057 let caught = 1
8058 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
8059 finally
8060 Xpath 4096 " X: 4096
8061 if !caught && !$VIMNOERRTHROW
8062 Xpath 8192 " X: 0
8063 endif
8064 if !MSG('E584', ":elseif after :else")
8065 Xpath 16384 " X: 0
8066 endif
8067 endtry
8068 catch /.*/
8069 Xpath 32768 " X: 0
8070 Xout v:exception "in" v:throwpoint
8071 finally
8072 break " discard error for $VIMNOERRTHROW
8073 endtry
8074endwhile
8075
8076while 1
8077 try
8078 try
8079 let v:errmsg = ""
8080 let caught = 0
8081 elseif 1 ||| 2
8082 catch /^Vim\((\a\+)\)\=:/
8083 let caught = 1
8084 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
8085 finally
8086 Xpath 65536 " X: 65536
8087 if !caught && !$VIMNOERRTHROW
8088 Xpath 131072 " X: 0
8089 endif
8090 if !MSG('E582', ":elseif without :if")
8091 Xpath 262144 " X: 0
8092 endif
8093 endtry
8094 catch /.*/
8095 Xpath 524288 " X: 0
8096 Xout v:exception "in" v:throwpoint
8097 finally
8098 break " discard error for $VIMNOERRTHROW
8099 endtry
8100endwhile
8101
8102while 1
8103 try
8104 try
8105 let v:errmsg = ""
8106 let caught = 0
8107 while 1
8108 elseif 1 ||| 2
8109 endwhile
8110 catch /^Vim\((\a\+)\)\=:/
8111 let caught = 1
8112 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
8113 finally
8114 Xpath 1048576 " X: 1048576
8115 if !caught && !$VIMNOERRTHROW
8116 Xpath 2097152 " X: 0
8117 endif
8118 if !MSG('E582', ":elseif without :if")
8119 Xpath 4194304 " X: 0
8120 endif
8121 endtry
8122 catch /.*/
8123 Xpath 8388608 " X: 0
8124 Xout v:exception "in" v:throwpoint
8125 finally
8126 break " discard error for $VIMNOERRTHROW
8127 endtry
8128endwhile
8129
8130Xpath 16777216 " X: 16777216
8131
8132unlet! caught
8133delfunction MSG
8134
8135Xcheck 17895765
8136
8137
8138"-------------------------------------------------------------------------------
8139" Test 81: Discarding exceptions after an error or interrupt {{{1
8140"
8141" When an exception is thrown from inside a :try conditional without
8142" :catch and :finally clauses and an error or interrupt occurs before
8143" the :endtry is reached, the exception is discarded.
8144"-------------------------------------------------------------------------------
8145
8146XpathINIT
8147
8148if ExtraVim()
8149 try
8150 Xpath 1 " X: 1
8151 try
8152 Xpath 2 " X: 2
8153 throw "arrgh"
8154 Xpath 4 " X: 0
8155" if 1
8156 Xpath 8 " X: 0
8157 " error after :throw: missing :endif
8158 endtry
8159 Xpath 16 " X: 0
8160 catch /arrgh/
8161 Xpath 32 " X: 0
8162 endtry
8163 Xpath 64 " X: 0
8164endif
8165
8166if ExtraVim()
8167 try
8168 Xpath 128 " X: 128
8169 try
8170 Xpath 256 " X: 256
8171 throw "arrgh"
8172 Xpath 512 " X: 0
8173 endtry " INTERRUPT
8174 Xpath 1024 " X: 0
8175 catch /arrgh/
8176 Xpath 2048 " X: 0
8177 endtry
8178 Xpath 4096 " X: 0
8179endif
8180
8181Xcheck 387
8182
8183
8184"-------------------------------------------------------------------------------
8185" Test 82: Ignoring :catch clauses after an error or interrupt {{{1
8186"
8187" When an exception is thrown and an error or interrupt occurs before
8188" the matching :catch clause is reached, the exception is discarded
8189" and the :catch clause is ignored (also for the error or interrupt
8190" exception being thrown then).
8191"-------------------------------------------------------------------------------
8192
8193XpathINIT
8194
8195if ExtraVim()
8196 try
8197 try
8198 Xpath 1 " X: 1
8199 throw "arrgh"
8200 Xpath 2 " X: 0
8201" if 1
8202 Xpath 4 " X: 0
8203 " error after :throw: missing :endif
8204 catch /.*/
8205 Xpath 8 " X: 0
8206 Xout v:exception "in" ExtraVimThrowpoint()
8207 catch /.*/
8208 Xpath 16 " X: 0
8209 Xout v:exception "in" ExtraVimThrowpoint()
8210 endtry
8211 Xpath 32 " X: 0
8212 catch /arrgh/
8213 Xpath 64 " X: 0
8214 endtry
8215 Xpath 128 " X: 0
8216endif
8217
8218if ExtraVim()
8219 function! E()
8220 try
8221 try
8222 Xpath 256 " X: 256
8223 throw "arrgh"
8224 Xpath 512 " X: 0
8225" if 1
8226 Xpath 1024 " X: 0
8227 " error after :throw: missing :endif
8228 catch /.*/
8229 Xpath 2048 " X: 0
8230 Xout v:exception "in" ExtraVimThrowpoint()
8231 catch /.*/
8232 Xpath 4096 " X: 0
8233 Xout v:exception "in" ExtraVimThrowpoint()
8234 endtry
8235 Xpath 8192 " X: 0
8236 catch /arrgh/
8237 Xpath 16384 " X: 0
8238 endtry
8239 endfunction
8240
8241 call E()
8242 Xpath 32768 " X: 0
8243endif
8244
8245if ExtraVim()
8246 try
8247 try
8248 Xpath 65536 " X: 65536
8249 throw "arrgh"
8250 Xpath 131072 " X: 0
8251 catch /.*/ "INTERRUPT
8252 Xpath 262144 " X: 0
8253 Xout v:exception "in" ExtraVimThrowpoint()
8254 catch /.*/
8255 Xpath 524288 " X: 0
8256 Xout v:exception "in" ExtraVimThrowpoint()
8257 endtry
8258 Xpath 1048576 " X: 0
8259 catch /arrgh/
8260 Xpath 2097152 " X: 0
8261 endtry
8262 Xpath 4194304 " X: 0
8263endif
8264
8265if ExtraVim()
8266 function I()
8267 try
8268 try
8269 Xpath 8388608 " X: 8388608
8270 throw "arrgh"
8271 Xpath 16777216 " X: 0
8272 catch /.*/ "INTERRUPT
8273 Xpath 33554432 " X: 0
8274 Xout v:exception "in" ExtraVimThrowpoint()
8275 catch /.*/
8276 Xpath 67108864 " X: 0
8277 Xout v:exception "in" ExtraVimThrowpoint()
8278 endtry
8279 Xpath 134217728 " X: 0
8280 catch /arrgh/
8281 Xpath 268435456 " X: 0
8282 endtry
8283 endfunction
8284
8285 call I()
8286 Xpath 536870912 " X: 0
8287endif
8288
8289Xcheck 8454401
8290
8291
8292"-------------------------------------------------------------------------------
8293" Test 83: Executing :finally clauses after an error or interrupt {{{1
8294"
8295" When an exception is thrown and an error or interrupt occurs before
8296" the :finally of the innermost :try is reached, the exception is
8297" discarded and the :finally clause is executed.
8298"-------------------------------------------------------------------------------
8299
8300XpathINIT
8301
8302if ExtraVim()
8303 try
8304 Xpath 1 " X: 1
8305 try
8306 Xpath 2 " X: 2
8307 throw "arrgh"
8308 Xpath 4 " X: 0
8309" if 1
8310 Xpath 8 " X: 0
8311 " error after :throw: missing :endif
8312 finally
8313 Xpath 16 " X: 16
8314 endtry
8315 Xpath 32 " X: 0
8316 catch /arrgh/
8317 Xpath 64 " X: 0
8318 endtry
8319 Xpath 128 " X: 0
8320endif
8321
8322if ExtraVim()
8323 try
8324 Xpath 256 " X: 256
8325 try
8326 Xpath 512 " X: 512
8327 throw "arrgh"
8328 Xpath 1024 " X: 0
8329 finally "INTERRUPT
8330 Xpath 2048 " X: 2048
8331 endtry
8332 Xpath 4096 " X: 0
8333 catch /arrgh/
8334 Xpath 8192 " X: 0
8335 endtry
8336 Xpath 16384 " X: 0
8337endif
8338
8339Xcheck 2835
8340
8341
8342"-------------------------------------------------------------------------------
8343" Test 84: Exceptions in autocommand sequences. {{{1
8344"
8345" When an exception occurs in a sequence of autocommands for
8346" a specific event, the rest of the sequence is not executed. The
8347" command that triggered the autocommand execution aborts, and the
8348" exception is propagated to the caller.
8349"
8350" For the FuncUndefined event under a function call expression or
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00008351" :call command, the function is not executed, even when it has
Bram Moolenaar071d4272004-06-13 20:20:40 +00008352" been defined by the autocommands before the exception occurred.
8353"-------------------------------------------------------------------------------
8354
8355XpathINIT
8356
8357if ExtraVim()
8358
8359 function! INT()
8360 "INTERRUPT
8361 let dummy = 0
8362 endfunction
8363
8364 aug TMP
8365 autocmd!
8366
8367 autocmd User x1 Xpath 1 " X: 1
8368 autocmd User x1 throw "x1"
8369 autocmd User x1 Xpath 2 " X: 0
8370
8371 autocmd User x2 Xpath 4 " X: 4
8372 autocmd User x2 asdf
8373 autocmd User x2 Xpath 8 " X: 0
8374
8375 autocmd User x3 Xpath 16 " X: 16
8376 autocmd User x3 call INT()
8377 autocmd User x3 Xpath 32 " X: 0
8378
8379 autocmd FuncUndefined U1 function! U1()
8380 autocmd FuncUndefined U1 Xpath 64 " X: 0
8381 autocmd FuncUndefined U1 endfunction
8382 autocmd FuncUndefined U1 Xpath 128 " X: 128
8383 autocmd FuncUndefined U1 throw "U1"
8384 autocmd FuncUndefined U1 Xpath 256 " X: 0
8385
8386 autocmd FuncUndefined U2 function! U2()
8387 autocmd FuncUndefined U2 Xpath 512 " X: 0
8388 autocmd FuncUndefined U2 endfunction
8389 autocmd FuncUndefined U2 Xpath 1024 " X: 1024
8390 autocmd FuncUndefined U2 ASDF
8391 autocmd FuncUndefined U2 Xpath 2048 " X: 0
8392
8393 autocmd FuncUndefined U3 function! U3()
8394 autocmd FuncUndefined U3 Xpath 4096 " X: 0
8395 autocmd FuncUndefined U3 endfunction
8396 autocmd FuncUndefined U3 Xpath 8192 " X: 8192
8397 autocmd FuncUndefined U3 call INT()
8398 autocmd FuncUndefined U3 Xpath 16384 " X: 0
8399 aug END
8400
8401 try
8402 try
8403 Xpath 32768 " X: 32768
8404 doautocmd User x1
8405 catch /x1/
8406 Xpath 65536 " X: 65536
8407 endtry
8408
8409 while 1
8410 try
8411 Xpath 131072 " X: 131072
8412 let caught = 0
8413 doautocmd User x2
8414 catch /asdf/
8415 let caught = 1
8416 finally
8417 Xpath 262144 " X: 262144
8418 if !caught && !$VIMNOERRTHROW
8419 Xpath 524288 " X: 0
8420 " Propagate uncaught error exception,
8421 else
8422 " ... but break loop for caught error exception,
8423 " or discard error and break loop if $VIMNOERRTHROW
8424 break
8425 endif
8426 endtry
8427 endwhile
8428
8429 while 1
8430 try
8431 Xpath 1048576 " X: 1048576
8432 let caught = 0
8433 doautocmd User x3
8434 catch /Vim:Interrupt/
8435 let caught = 1
8436 finally
8437 Xpath 2097152 " X: 2097152
8438 if !caught && !$VIMNOINTTHROW
8439 Xpath 4194304 " X: 0
8440 " Propagate uncaught interrupt exception,
8441 else
8442 " ... but break loop for caught interrupt exception,
8443 " or discard interrupt and break loop if $VIMNOINTTHROW
8444 break
8445 endif
8446 endtry
8447 endwhile
8448
8449 if exists("*U1") | delfunction U1 | endif
8450 if exists("*U2") | delfunction U2 | endif
8451 if exists("*U3") | delfunction U3 | endif
8452
8453 try
8454 Xpath 8388608 " X: 8388608
8455 call U1()
8456 catch /U1/
8457 Xpath 16777216 " X: 16777216
8458 endtry
8459
8460 while 1
8461 try
8462 Xpath 33554432 " X: 33554432
8463 let caught = 0
8464 call U2()
8465 catch /ASDF/
8466 let caught = 1
8467 finally
8468 Xpath 67108864 " X: 67108864
8469 if !caught && !$VIMNOERRTHROW
8470 Xpath 134217728 " X: 0
8471 " Propagate uncaught error exception,
8472 else
8473 " ... but break loop for caught error exception,
8474 " or discard error and break loop if $VIMNOERRTHROW
8475 break
8476 endif
8477 endtry
8478 endwhile
8479
8480 while 1
8481 try
8482 Xpath 268435456 " X: 268435456
8483 let caught = 0
8484 call U3()
8485 catch /Vim:Interrupt/
8486 let caught = 1
8487 finally
8488 Xpath 536870912 " X: 536870912
8489 if !caught && !$VIMNOINTTHROW
8490 Xpath 1073741824 " X: 0
8491 " Propagate uncaught interrupt exception,
8492 else
8493 " ... but break loop for caught interrupt exception,
8494 " or discard interrupt and break loop if $VIMNOINTTHROW
8495 break
8496 endif
8497 endtry
8498 endwhile
8499 catch /.*/
8500 " The Xpath command does not accept 2^31 (negative); display explicitly:
8501 exec "!echo 2147483648 >>" . g:ExtraVimResult
8502 Xout "Caught" v:exception "in" v:throwpoint
8503 endtry
8504
8505 unlet caught
8506 delfunction INT
8507 delfunction U1
8508 delfunction U2
8509 delfunction U3
8510 au! TMP
8511 aug! TMP
8512endif
8513
8514Xcheck 934782101
8515
8516
8517"-------------------------------------------------------------------------------
8518" Test 85: Error exceptions in autocommands for I/O command events {{{1
8519"
8520" When an I/O command is inside :try/:endtry, autocommands to be
8521" executed after it should be skipped on an error (exception) in the
8522" command itself or in autocommands to be executed before the command.
8523" In the latter case, the I/O command should not be executed either.
8524" Example 1: BufWritePre, :write, BufWritePost
8525" Example 2: FileReadPre, :read, FileReadPost.
8526"-------------------------------------------------------------------------------
8527
8528XpathINIT
8529
8530function! MSG(enr, emsg)
8531 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
8532 if a:enr == ""
8533 Xout "TODO: Add message number for:" a:emsg
8534 let v:errmsg = ":" . v:errmsg
8535 endif
8536 let match = 1
8537 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
8538 let match = 0
8539 if v:errmsg == ""
8540 Xout "Message missing."
8541 else
8542 let v:errmsg = escape(v:errmsg, '"')
8543 Xout "Unexpected message:" v:errmsg
8544 endif
8545 endif
8546 return match
8547endfunction
8548
8549" Remove the autocommands for the events specified as arguments in all used
8550" autogroups.
Bram Moolenaar1e115362019-01-09 23:01:02 +01008551function Delete_autocommands(...)
Bram Moolenaar071d4272004-06-13 20:20:40 +00008552 let augfile = tempname()
8553 while 1
8554 try
8555 exec "redir >" . augfile
8556 aug
8557 redir END
8558 exec "edit" augfile
8559 g/^$/d
8560 norm G$
8561 let wrap = "w"
8562 while search('\%( \|^\)\@<=.\{-}\%( \)\@=', wrap) > 0
8563 let wrap = "W"
8564 exec "norm y/ \n"
8565 let argno = 1
8566 while argno <= a:0
8567 exec "au!" escape(@", " ") a:{argno}
8568 let argno = argno + 1
8569 endwhile
8570 endwhile
8571 catch /.*/
8572 finally
8573 bwipeout!
8574 call delete(augfile)
8575 break " discard errors for $VIMNOERRTHROW
8576 endtry
8577 endwhile
8578endfunction
8579
8580call Delete_autocommands("BufWritePre", "BufWritePost")
8581
8582while 1
8583 try
8584 try
8585 let post = 0
8586 aug TMP
8587 au! BufWritePost * let post = 1
8588 aug END
8589 let caught = 0
8590 write /n/o/n/e/x/i/s/t/e/n/t
8591 catch /^Vim(write):/
8592 let caught = 1
8593 let v:errmsg = substitute(v:exception, '^Vim(write):', '', "")
8594 finally
8595 Xpath 1 " X: 1
8596 if !caught && !$VIMNOERRTHROW
8597 Xpath 2 " X: 0
8598 endif
8599 let v:errmsg = substitute(v:errmsg, '^"/n/o/n/e/x/i/s/t/e/n/t" ',
8600 \ '', "")
8601 if !MSG('E212', "Can't open file for writing")
8602 Xpath 4 " X: 0
8603 endif
8604 if post
8605 Xpath 8 " X: 0
8606 Xout "BufWritePost commands executed after write error"
8607 endif
8608 au! TMP
8609 aug! TMP
8610 endtry
8611 catch /.*/
8612 Xpath 16 " X: 0
8613 Xout v:exception "in" v:throwpoint
8614 finally
8615 break " discard error for $VIMNOERRTHROW
8616 endtry
8617endwhile
8618
8619while 1
8620 try
8621 try
8622 let post = 0
8623 aug TMP
8624 au! BufWritePre * asdf
8625 au! BufWritePost * let post = 1
8626 aug END
8627 let tmpfile = tempname()
8628 let caught = 0
8629 exec "write" tmpfile
8630 catch /^Vim\((write)\)\=:/
8631 let caught = 1
8632 let v:errmsg = substitute(v:exception, '^Vim\((write)\)\=:', '', "")
8633 finally
8634 Xpath 32 " X: 32
8635 if !caught && !$VIMNOERRTHROW
8636 Xpath 64 " X: 0
8637 endif
8638 let v:errmsg = substitute(v:errmsg, '^"'.tmpfile.'" ', '', "")
8639 if !MSG('E492', "Not an editor command")
8640 Xpath 128 " X: 0
8641 endif
8642 if filereadable(tmpfile)
8643 Xpath 256 " X: 0
8644 Xout ":write command not suppressed after BufWritePre error"
8645 endif
8646 if post
8647 Xpath 512 " X: 0
8648 Xout "BufWritePost commands executed after BufWritePre error"
8649 endif
8650 au! TMP
8651 aug! TMP
8652 endtry
8653 catch /.*/
8654 Xpath 1024 " X: 0
8655 Xout v:exception "in" v:throwpoint
8656 finally
8657 break " discard error for $VIMNOERRTHROW
8658 endtry
8659endwhile
8660
8661call delete(tmpfile)
8662
8663call Delete_autocommands("BufWritePre", "BufWritePost",
8664 \ "BufReadPre", "BufReadPost", "FileReadPre", "FileReadPost")
8665
8666while 1
8667 try
8668 try
8669 let post = 0
8670 aug TMP
8671 au! FileReadPost * let post = 1
8672 aug END
8673 let caught = 0
8674 read /n/o/n/e/x/i/s/t/e/n/t
8675 catch /^Vim(read):/
8676 let caught = 1
8677 let v:errmsg = substitute(v:exception, '^Vim(read):', '', "")
8678 finally
8679 Xpath 2048 " X: 2048
8680 if !caught && !$VIMNOERRTHROW
8681 Xpath 4096 " X: 0
8682 endif
8683 let v:errmsg = substitute(v:errmsg, ' /n/o/n/e/x/i/s/t/e/n/t$',
8684 \ '', "")
8685 if !MSG('E484', "Can't open file")
8686 Xpath 8192 " X: 0
8687 endif
8688 if post
8689 Xpath 16384 " X: 0
8690 Xout "FileReadPost commands executed after write error"
8691 endif
8692 au! TMP
8693 aug! TMP
8694 endtry
8695 catch /.*/
8696 Xpath 32768 " X: 0
8697 Xout v:exception "in" v:throwpoint
8698 finally
8699 break " discard error for $VIMNOERRTHROW
8700 endtry
8701endwhile
8702
8703while 1
8704 try
8705 let infile = tempname()
8706 let tmpfile = tempname()
8707 exec "!echo XYZ >" . infile
8708 exec "edit" tmpfile
8709 try
8710 Xpath 65536 " X: 65536
8711 try
8712 let post = 0
8713 aug TMP
8714 au! FileReadPre * asdf
8715 au! FileReadPost * let post = 1
8716 aug END
8717 let caught = 0
8718 exec "0read" infile
8719 catch /^Vim\((read)\)\=:/
8720 let caught = 1
8721 let v:errmsg = substitute(v:exception, '^Vim\((read)\)\=:', '',
8722 \ "")
8723 finally
8724 Xpath 131072 " X: 131072
8725 if !caught && !$VIMNOERRTHROW
8726 Xpath 262144 " X: 0
8727 endif
8728 let v:errmsg = substitute(v:errmsg, ' '.infile.'$', '', "")
8729 if !MSG('E492', "Not an editor command")
8730 Xpath 524288 " X: 0
8731 endif
8732 if getline("1") == "XYZ"
8733 Xpath 1048576 " X: 0
8734 Xout ":read command not suppressed after FileReadPre error"
8735 endif
8736 if post
8737 Xpath 2097152 " X: 0
8738 Xout "FileReadPost commands executed after " .
8739 \ "FileReadPre error"
8740 endif
8741 au! TMP
8742 aug! TMP
8743 endtry
8744 finally
8745 bwipeout!
8746 endtry
8747 catch /.*/
8748 Xpath 4194304 " X: 0
8749 Xout v:exception "in" v:throwpoint
8750 finally
8751 break " discard error for $VIMNOERRTHROW
8752 endtry
8753endwhile
8754
8755call delete(infile)
8756call delete(tmpfile)
8757unlet! caught post infile tmpfile
8758delfunction MSG
8759delfunction Delete_autocommands
8760
8761Xcheck 198689
8762
Bram Moolenaar41b884b2012-11-14 22:38:08 +01008763"-------------------------------------------------------------------------------
Bram Moolenaar32c8f1c2012-12-05 19:00:06 +01008764" Test 86: setloclist crash {{{1
Bram Moolenaar41b884b2012-11-14 22:38:08 +01008765"
8766" Executing a setloclist() on BufUnload shouldn't crash Vim
8767"-------------------------------------------------------------------------------
8768
8769func F
8770 au BufUnload * :call setloclist(0, [{'bufnr':1, 'lnum':1, 'col':1, 'text': 'tango down'}])
8771
Bram Moolenaarcc908ad2013-06-06 18:55:49 +02008772 :lvimgrep /.*/ *.mak
Bram Moolenaar41b884b2012-11-14 22:38:08 +01008773endfunc
8774
8775XpathINIT
8776
8777ExecAsScript F
8778
8779delfunction F
8780Xout "No Crash for vimgrep on BufUnload"
8781Xcheck 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00008782
8783"-------------------------------------------------------------------------------
Bram Moolenaarb8f84612013-02-26 22:54:11 +01008784" Test 87 using (expr) ? funcref : funcref {{{1
8785"
8786" Vim needs to correctly parse the funcref and even when it does
8787" not execute the funcref, it needs to consume the trailing ()
8788"-------------------------------------------------------------------------------
8789
8790XpathINIT
8791
8792func Add2(x1, x2)
8793 return a:x1 + a:x2
8794endfu
8795
8796func GetStr()
8797 return "abcdefghijklmnopqrstuvwxyp"
8798endfu
8799
8800echo function('Add2')(2,3)
8801
8802Xout 1 ? function('Add2')(1,2) : function('Add2')(2,3)
8803Xout 0 ? function('Add2')(1,2) : function('Add2')(2,3)
8804" Make sure, GetStr() still works.
8805Xout GetStr()[0:10]
8806
8807
8808delfunction GetStr
8809delfunction Add2
8810Xout "Successfully executed funcref Add2"
8811
8812Xcheck 0
8813
8814"-------------------------------------------------------------------------------
8815" Test 88: $VIMNOERRTHROW and $VIMNOINTTHROW support {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00008816"
8817" It is possible to configure Vim for throwing exceptions on error
8818" or interrupt, controlled by variables $VIMNOERRTHROW and
8819" $VIMNOINTTHROW. This is just for increasing the number of tests.
8820" All tests here should run for all four combinations of setting
8821" these variables to 0 or 1. The variables are intended for the
8822" development phase only. In the final release, Vim should be
8823" configured to always use error and interrupt exceptions.
8824"
8825" The test result is "OK",
8826"
8827" - if the $VIMNOERRTHROW and the $VIMNOINTTHROW control are not
8828" configured and exceptions are thrown on error and on
8829" interrupt.
8830"
8831" - if the $VIMNOERRTHROW or the $VIMNOINTTHROW control is
8832" configured and works as intended.
8833"
8834" What actually happens, is shown in the test output.
8835"
8836" Otherwise, the test result is "FAIL", and the test output describes
8837" the problem.
8838"
8839" IMPORTANT: This must be the last test because it sets $VIMNOERRTHROW and
8840" $VIMNOINTTHROW.
8841"-------------------------------------------------------------------------------
8842
8843XpathINIT
8844
8845if ExtraVim()
8846
8847 function! ThrowOnError()
8848 XloopNEXT
8849 let caught = 0
8850 try
8851 Xloop 1 " X: 1 + 8 + 64
8852 asdf
8853 catch /.*/
8854 let caught = 1 " error exception caught
8855 finally
8856 Xloop 2 " X: 2 + 16 + 128
8857 return caught " discard aborting error
8858 endtry
8859 Xloop 4 " X: 0
8860 endfunction
8861
8862 let quits_skipped = 0
8863
8864 function! ThrowOnInterrupt()
8865 XloopNEXT
8866 let caught = 0
8867 try
8868 Xloop 1 " X: (1 + 8 + 64) * 512
8869 "INTERRUPT3
8870 let dummy = 0
8871 let g:quits_skipped = g:quits_skipped + 1
8872 catch /.*/
8873 let caught = 1 " interrupt exception caught
8874 finally
8875 Xloop 2 " X: (2 + 16 + 128) * 512
8876 return caught " discard interrupt
8877 endtry
8878 Xloop 4 " X: 0
8879 endfunction
8880
8881 function! CheckThrow(Type)
8882 execute 'return ThrowOn' . a:Type . '()'
8883 endfunction
8884
8885 function! CheckConfiguration(type) " type is "error" or "interrupt"
8886
8887 let type = a:type
8888 let Type = substitute(type, '.*', '\u&', "")
8889 let VAR = '$VIMNO' . substitute(type, '\(...\).*', '\U\1', "") . 'THROW'
8890
8891 if type == "error"
8892 XloopINIT! 1 8
8893 elseif type == "interrupt"
8894 XloopINIT! 512 8
8895 endif
8896
8897 exec 'let requested_for_tests = exists(VAR) && ' . VAR . ' == 0'
8898 exec 'let suppressed_for_tests = ' . VAR . ' != 0'
8899 let used_in_tests = CheckThrow(Type)
8900
8901 exec 'let ' . VAR . ' = 0'
8902 let request_works = CheckThrow(Type)
8903
8904 exec 'let ' . VAR . ' = 1'
8905 let suppress_works = !CheckThrow(Type)
8906
8907 if type == "error"
8908 XloopINIT! 262144 8
8909 elseif type == "interrupt"
8910 XloopINIT! 2097152 8
8911
8912 if g:quits_skipped != 0
8913 Xloop 1 " X: 0*2097152
8914 Xout "Test environment error. Interrupt breakpoints skipped: "
8915 \ . g:quits_skipped . ".\n"
8916 \ . "Cannot check whether interrupt exceptions are thrown."
8917 return
8918 endif
8919 endif
8920
8921 let failure =
8922 \ !suppressed_for_tests && !used_in_tests
8923 \ || !request_works
8924
8925 let contradiction =
8926 \ used_in_tests
8927 \ ? suppressed_for_tests && !request_works
8928 \ : !suppressed_for_tests
8929
8930 if failure
8931 " Failure in configuration.
8932 Xloop 2 " X: 0 * 2* (262144 + 2097152)
8933 elseif contradiction
8934 " Failure in test logic. Should not happen.
8935 Xloop 4 " X: 0 * 4 * (262144 + 2097152)
8936 endif
8937
8938 let var_control_configured =
8939 \ request_works != used_in_tests
8940 \ || suppress_works == used_in_tests
8941
8942 let var_control_not_configured =
8943 \ requested_for_tests || suppressed_for_tests
8944 \ ? request_works && !suppress_works
8945 \ : request_works == used_in_tests
8946 \ && suppress_works != used_in_tests
8947
8948 let with = used_in_tests ? "with" : "without"
8949
8950 let set = suppressed_for_tests ? "non-zero" :
8951 \ requested_for_tests ? "0" : "unset"
8952
8953 let although = contradiction && !var_control_not_configured
8954 \ ? ",\nalthough "
8955 \ : ".\n"
8956
8957 let output = "All tests were run " . with . " throwing exceptions on "
8958 \ . type . although
8959
8960 if !var_control_not_configured
8961 let output = output . VAR . " was " . set . "."
8962
8963 if !request_works && !requested_for_tests
8964 let output = output .
8965 \ "\n" . Type . " exceptions are not thrown when " . VAR .
8966 \ " is\nset to 0."
8967 endif
8968
8969 if !suppress_works && (!used_in_tests ||
8970 \ !request_works &&
8971 \ !requested_for_tests && !suppressed_for_tests)
8972 let output = output .
8973 \ "\n" . Type . " exceptions are thrown when " . VAR .
8974 \ " is set to 1."
8975 endif
8976
8977 if !failure && var_control_configured
8978 let output = output .
8979 \ "\nRun tests also with " . substitute(VAR, '^\$', '', "")
8980 \ . "=" . used_in_tests . "."
8981 \ . "\nThis is for testing in the development phase only."
8982 \ . " Remove the \n"
8983 \ . VAR . " control in the final release."
8984 endif
8985 else
8986 let output = output .
8987 \ "The " . VAR . " control is not configured."
8988 endif
8989
8990 Xout output
8991 endfunction
8992
8993 call CheckConfiguration("error")
8994 Xpath 16777216 " X: 16777216
8995 call CheckConfiguration("interrupt")
8996 Xpath 33554432 " X: 33554432
8997endif
8998
8999Xcheck 50443995
9000
9001" IMPORTANT: No test should be added after this test because it changes
9002" $VIMNOERRTHROW and $VIMNOINTTHROW.
9003
9004
9005"-------------------------------------------------------------------------------
9006" Modelines {{{1
9007" vim: ts=8 sw=4 tw=80 fdm=marker
9008" vim: fdt=substitute(substitute(foldtext(),\ '\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\ \\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\ '\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "")
9009"-------------------------------------------------------------------------------