blob: f19b9db5baf4eda5d069e9d522379e3fdfecdd58 [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 Moolenaar1f068232019-11-03 16:17:26 +01003" Last Change: 2019 Nov 03
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 . "'" : ""
Bram Moolenaar1ac41a52019-10-10 13:30:12 +0200459 exec "!echo '" . debug_quits . "q' | " .. v:progpath .. " -u NONE -N -Xes" . redirect .
Bram Moolenaar071d4272004-06-13 20:20:40 +0000460 \ " -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
Bram Moolenaar1bc353b2019-09-01 14:45:28 +0200524" variable, and every ":call" by a ":source" for the next following argument
Bram Moolenaar071d4272004-06-13 20:20:40 +0000525" 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 Moolenaar1f068232019-11-03 16:17:26 +0100611" Tests 1 to 17 were moved to test_vimscript.vim
612let Xtest = 18
Bram Moolenaar071d4272004-06-13 20:20:40 +0000613
614"-------------------------------------------------------------------------------
615" Test 18: Interrupt (Ctrl-C pressed) {{{1
616"
617" On an interrupt, the script processing is terminated immediately.
618"-------------------------------------------------------------------------------
619
620XpathINIT
621
622if ExtraVim()
623 if 1
624 Xpath 1 " X: 1
625 while 1
626 Xpath 2 " X: 2
627 if 1
628 Xpath 4 " X: 4
629 "INTERRUPT
630 Xpath 8 " X: 0
631 break
632 finish
633 endif | Xpath 16 " X: 0
634 Xpath 32 " X: 0
635 endwhile | Xpath 64 " X: 0
636 Xpath 128 " X: 0
637 endif | Xpath 256 " X: 0
638 Xpath 512 " X: 0
639endif
640
641if ExtraVim()
642 try
643 Xpath 1024 " X: 1024
644 "INTERRUPT
645 Xpath 2048 " X: 0
646 endtry | Xpath 4096 " X: 0
647 Xpath 8192 " X: 0
648endif
649
650if ExtraVim()
651 function! F()
652 if 1
653 Xpath 16384 " X: 16384
654 while 1
655 Xpath 32768 " X: 32768
656 if 1
657 Xpath 65536 " X: 65536
658 "INTERRUPT
659 Xpath 131072 " X: 0
660 break
661 return
662 endif | Xpath 262144 " X: 0
663 Xpath Xpath 524288 " X: 0
664 endwhile | Xpath 1048576 " X: 0
665 Xpath Xpath 2097152 " X: 0
666 endif | Xpath Xpath 4194304 " X: 0
667 Xpath Xpath 8388608 " X: 0
668 endfunction
669
670 call F() | Xpath 16777216 " X: 0
671 Xpath 33554432 " X: 0
672endif
673
674if ExtraVim()
675 function! G()
676 try
677 Xpath 67108864 " X: 67108864
678 "INTERRUPT
679 Xpath 134217728 " X: 0
680 endtry | Xpath 268435456 " X: 0
681 Xpath 536870912 " X: 0
682 endfunction
683
684 call G() | Xpath 1073741824 " X: 0
685 " The Xpath command does not accept 2^31 (negative); display explicitly:
686 exec "!echo 2147483648 >>" . g:ExtraVimResult
687 " X: 0
688endif
689
690Xcheck 67224583
691
692
693"-------------------------------------------------------------------------------
694" Test 19: Aborting on errors inside :try/:endtry {{{1
695"
696" An error in a command dynamically enclosed in a :try/:endtry region
697" aborts script processing immediately. It does not matter whether
698" the failing command is outside or inside a function and whether a
699" function has an "abort" attribute.
700"-------------------------------------------------------------------------------
701
702XpathINIT
703
704if ExtraVim()
705 function! F() abort
706 Xpath 1 " X: 1
707 asdf
708 Xpath 2 " X: 0
709 endfunction
710
711 try
712 Xpath 4 " X: 4
713 call F()
714 Xpath 8 " X: 0
715 endtry | Xpath 16 " X: 0
716 Xpath 32 " X: 0
717endif
718
719if ExtraVim()
720 function! G()
721 Xpath 64 " X: 64
722 asdf
723 Xpath 128 " X: 0
724 endfunction
725
726 try
727 Xpath 256 " X: 256
728 call G()
729 Xpath 512 " X: 0
730 endtry | Xpath 1024 " X: 0
731 Xpath 2048 " X: 0
732endif
733
734if ExtraVim()
735 try
736 Xpath 4096 " X: 4096
737 asdf
738 Xpath 8192 " X: 0
739 endtry | Xpath 16384 " X: 0
740 Xpath 32768 " X: 0
741endif
742
743if ExtraVim()
744 if 1
745 try
746 Xpath 65536 " X: 65536
747 asdf
748 Xpath 131072 " X: 0
749 endtry | Xpath 262144 " X: 0
750 endif | Xpath 524288 " X: 0
751 Xpath 1048576 " X: 0
752endif
753
754if ExtraVim()
755 let p = 1
756 while p
757 let p = 0
758 try
759 Xpath 2097152 " X: 2097152
760 asdf
761 Xpath 4194304 " X: 0
762 endtry | Xpath 8388608 " X: 0
763 endwhile | Xpath 16777216 " X: 0
764 Xpath 33554432 " X: 0
765endif
766
767if ExtraVim()
768 let p = 1
769 while p
770 let p = 0
771" try
772 Xpath 67108864 " X: 67108864
773 endwhile | Xpath 134217728 " X: 0
774 Xpath 268435456 " X: 0
775endif
776
777Xcheck 69275973
778"-------------------------------------------------------------------------------
779" Test 20: Aborting on errors after :try/:endtry {{{1
780"
781" When an error occurs after the last active :try/:endtry region has
782" been left, termination behavior is as if no :try/:endtry has been
783" seen.
784"-------------------------------------------------------------------------------
785
786XpathINIT
787
788if ExtraVim()
789 let p = 1
790 while p
791 let p = 0
792 try
793 Xpath 1 " X: 1
794 endtry
795 asdf
796 endwhile | Xpath 2 " X: 0
797 Xpath 4 " X: 4
798endif
799
800if ExtraVim()
801 while 1
802 try
803 Xpath 8 " X: 8
804 break
805 Xpath 16 " X: 0
806 endtry
807 endwhile
808 Xpath 32 " X: 32
809 asdf
810 Xpath 64 " X: 64
811endif
812
813if ExtraVim()
814 while 1
815 try
816 Xpath 128 " X: 128
817 break
818 Xpath 256 " X: 0
819 finally
820 Xpath 512 " X: 512
821 endtry
822 endwhile
823 Xpath 1024 " X: 1024
824 asdf
825 Xpath 2048 " X: 2048
826endif
827
828if ExtraVim()
829 while 1
830 try
831 Xpath 4096 " X: 4096
832 finally
833 Xpath 8192 " X: 8192
834 break
835 Xpath 16384 " X: 0
836 endtry
837 endwhile
838 Xpath 32768 " X: 32768
839 asdf
840 Xpath 65536 " X: 65536
841endif
842
843if ExtraVim()
844 let p = 1
845 while p
846 let p = 0
847 try
848 Xpath 131072 " X: 131072
849 continue
850 Xpath 262144 " X: 0
851 endtry
852 endwhile
853 Xpath 524288 " X: 524288
854 asdf
855 Xpath 1048576 " X: 1048576
856endif
857
858if ExtraVim()
859 let p = 1
860 while p
861 let p = 0
862 try
863 Xpath 2097152 " X: 2097152
864 continue
865 Xpath 4194304 " X: 0
866 finally
867 Xpath 8388608 " X: 8388608
868 endtry
869 endwhile
870 Xpath 16777216 " X: 16777216
871 asdf
872 Xpath 33554432 " X: 33554432
873endif
874
875if ExtraVim()
876 let p = 1
877 while p
878 let p = 0
879 try
880 Xpath 67108864 " X: 67108864
881 finally
882 Xpath 134217728 " X: 134217728
883 continue
884 Xpath 268435456 " X: 0
885 endtry
886 endwhile
887 Xpath 536870912 " X: 536870912
888 asdf
889 Xpath 1073741824 " X: 1073741824
890endif
891
892Xcheck 1874575085
893
894
895"-------------------------------------------------------------------------------
896" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1
897"
898" If a :try conditional stays inactive due to a preceding :continue,
899" :break, :return, or :finish, its :finally clause should not be
900" executed.
901"-------------------------------------------------------------------------------
902
903XpathINIT
904
905if ExtraVim()
906 function F()
907 let loops = 2
908 XloopINIT! 1 256
909 while loops > 0
910 XloopNEXT
911 let loops = loops - 1
912 try
913 if loops == 1
914 Xloop 1 " X: 1
915 continue
916 Xloop 2 " X: 0
917 elseif loops == 0
918 Xloop 4 " X: 4*256
919 break
920 Xloop 8 " X: 0
921 endif
922
923 try " inactive
924 Xloop 16 " X: 0
925 finally
926 Xloop 32 " X: 0
927 endtry
928 finally
929 Xloop 64 " X: 64 + 64*256
930 endtry
931 Xloop 128 " X: 0
932 endwhile
933
934 try
935 Xpath 65536 " X: 65536
936 return
937 Xpath 131072 " X: 0
938 try " inactive
939 Xpath 262144 " X: 0
940 finally
941 Xpath 524288 " X: 0
942 endtry
943 finally
944 Xpath 1048576 " X: 1048576
945 endtry
946 Xpath 2097152 " X: 0
947 endfunction
948
949 try
950 Xpath 4194304 " X: 4194304
951 call F()
952 Xpath 8388608 " X: 8388608
953 finish
954 Xpath 16777216 " X: 0
955 try " inactive
956 Xpath 33554432 " X: 0
957 finally
958 Xpath 67108864 " X: 0
959 endtry
960 finally
961 Xpath 134217728 " X: 134217728
962 endtry
963 Xpath 268435456 " X: 0
964endif
965
966Xcheck 147932225
967
968
969"-------------------------------------------------------------------------------
970" Test 22: :finally for a :try after an error/interrupt/:throw {{{1
971"
972" If a :try conditional stays inactive due to a preceding error or
973" interrupt or :throw, its :finally clause should not be executed.
974"-------------------------------------------------------------------------------
975
976XpathINIT
977
978if ExtraVim()
979 function! Error()
980 try
981 asdf " aborting error, triggering error exception
982 endtry
983 endfunction
984
985 Xpath 1 " X: 1
986 call Error()
987 Xpath 2 " X: 0
988
989 if 1 " not active due to error
990 try " not active since :if inactive
991 Xpath 4 " X: 0
992 finally
993 Xpath 8 " X: 0
994 endtry
995 endif
996
997 try " not active due to error
998 Xpath 16 " X: 0
999 finally
1000 Xpath 32 " X: 0
1001 endtry
1002endif
1003
1004if ExtraVim()
1005 function! Interrupt()
1006 try
1007 "INTERRUPT " triggering interrupt exception
1008 endtry
1009 endfunction
1010
1011 Xpath 64 " X: 64
1012 call Interrupt()
1013 Xpath 128 " X: 0
1014
1015 if 1 " not active due to interrupt
1016 try " not active since :if inactive
1017 Xpath 256 " X: 0
1018 finally
1019 Xpath 512 " X: 0
1020 endtry
1021 endif
1022
1023 try " not active due to interrupt
1024 Xpath 1024 " X: 0
1025 finally
1026 Xpath 2048 " X: 0
1027 endtry
1028endif
1029
1030if ExtraVim()
1031 function! Throw()
1032 throw "xyz"
1033 endfunction
1034
1035 Xpath 4096 " X: 4096
1036 call Throw()
1037 Xpath 8192 " X: 0
1038
1039 if 1 " not active due to :throw
1040 try " not active since :if inactive
1041 Xpath 16384 " X: 0
1042 finally
1043 Xpath 32768 " X: 0
1044 endtry
1045 endif
1046
1047 try " not active due to :throw
1048 Xpath 65536 " X: 0
1049 finally
1050 Xpath 131072 " X: 0
1051 endtry
1052endif
1053
1054Xcheck 4161
1055
1056
1057"-------------------------------------------------------------------------------
1058" Test 23: :catch clauses for a :try after a :throw {{{1
1059"
1060" If a :try conditional stays inactive due to a preceding :throw,
1061" none of its :catch clauses should be executed.
1062"-------------------------------------------------------------------------------
1063
1064XpathINIT
1065
1066if ExtraVim()
1067 try
1068 Xpath 1 " X: 1
1069 throw "xyz"
1070 Xpath 2 " X: 0
1071
1072 if 1 " not active due to :throw
1073 try " not active since :if inactive
1074 Xpath 4 " X: 0
1075 catch /xyz/
1076 Xpath 8 " X: 0
1077 endtry
1078 endif
1079 catch /xyz/
1080 Xpath 16 " X: 16
1081 endtry
1082
1083 Xpath 32 " X: 32
1084 throw "abc"
1085 Xpath 64 " X: 0
1086
1087 try " not active due to :throw
1088 Xpath 128 " X: 0
1089 catch /abc/
1090 Xpath 256 " X: 0
1091 endtry
1092endif
1093
1094Xcheck 49
1095
1096
1097"-------------------------------------------------------------------------------
1098" Test 24: :endtry for a :try after a :throw {{{1
1099"
1100" If a :try conditional stays inactive due to a preceding :throw,
1101" its :endtry should not rethrow the exception to the next surrounding
1102" active :try conditional.
1103"-------------------------------------------------------------------------------
1104
1105XpathINIT
1106
1107if ExtraVim()
1108 try " try 1
1109 try " try 2
1110 Xpath 1 " X: 1
1111 throw "xyz" " makes try 2 inactive
1112 Xpath 2 " X: 0
1113
1114 try " try 3
1115 Xpath 4 " X: 0
1116 endtry " no rethrow to try 1
1117 catch /xyz/ " should catch although try 2 inactive
1118 Xpath 8 " X: 8
1119 endtry
1120 catch /xyz/ " try 1 active, but exception already caught
1121 Xpath 16 " X: 0
1122 endtry
1123 Xpath 32 " X: 32
1124endif
1125
1126Xcheck 41
1127
Bram Moolenaar1f068232019-11-03 16:17:26 +01001128" Tests 25 and 26 were moved to test_trycatch.vim
1129let Xtest = 27
Bram Moolenaar071d4272004-06-13 20:20:40 +00001130
1131
1132"-------------------------------------------------------------------------------
1133" Test 27: Executing :finally clauses after :return {{{1
1134"
1135" For a :return command dynamically enclosed in a :try/:endtry region,
1136" :finally clauses are executed and the called function is ended.
1137"-------------------------------------------------------------------------------
1138
1139XpathINIT
1140
1141function! F()
1142 try
1143 Xpath 1 " X: 1
1144 try
1145 Xpath 2 " X: 2
1146 return
1147 Xpath 4 " X: 0
1148 finally
1149 Xpath 8 " X: 8
1150 endtry
1151 Xpath 16 " X: 0
1152 finally
1153 Xpath 32 " X: 32
1154 endtry
1155 Xpath 64 " X: 0
1156endfunction
1157
1158function! G()
1159 try
1160 Xpath 128 " X: 128
1161 return
1162 Xpath 256 " X: 0
1163 finally
1164 Xpath 512 " X: 512
1165 call F()
1166 Xpath 1024 " X: 1024
1167 endtry
1168 Xpath 2048 " X: 0
1169endfunction
1170
1171function! H()
1172 try
1173 Xpath 4096 " X: 4096
1174 call G()
1175 Xpath 8192 " X: 8192
1176 finally
1177 Xpath 16384 " X: 16384
1178 return
1179 Xpath 32768 " X: 0
1180 endtry
1181 Xpath 65536 " X: 0
1182endfunction
1183
1184try
1185 Xpath 131072 " X: 131072
1186 call H()
1187 Xpath 262144 " X: 262144
1188finally
1189 Xpath 524288 " X: 524288
1190endtry
1191Xpath 1048576 " X: 1048576
1192
1193Xcheck 1996459
1194
1195" Leave F, G, and H for execution as scripts in the next test.
1196
1197
1198"-------------------------------------------------------------------------------
1199" Test 28: Executing :finally clauses after :finish {{{1
1200"
1201" For a :finish command dynamically enclosed in a :try/:endtry region,
1202" :finally clauses are executed and the sourced file is finished.
1203"
1204" This test executes the bodies of the functions F, G, and H from the
1205" previous test as script files (:return replaced by :finish).
1206"-------------------------------------------------------------------------------
1207
1208XpathINIT
1209
1210let scriptF = MakeScript("F") " X: 1 + 2 + 8 + 32
1211let scriptG = MakeScript("G", scriptF) " X: 128 + 512 + 1024
1212let scriptH = MakeScript("H", scriptG) " X: 4096 + 8192 + 16384
1213
1214try
1215 Xpath 131072 " X: 131072
1216 exec "source" scriptH
1217 Xpath 262144 " X: 262144
1218finally
1219 Xpath 524288 " X: 524288
1220endtry
1221Xpath 1048576 " X: 1048576
1222
1223call delete(scriptF)
1224call delete(scriptG)
1225call delete(scriptH)
1226unlet scriptF scriptG scriptH
1227delfunction F
1228delfunction G
1229delfunction H
1230
1231Xcheck 1996459
1232
1233
1234"-------------------------------------------------------------------------------
1235" Test 29: Executing :finally clauses on errors {{{1
1236"
1237" After an error in a command dynamically enclosed in a :try/:endtry
1238" region, :finally clauses are executed and the script processing is
1239" terminated.
1240"-------------------------------------------------------------------------------
1241
1242XpathINIT
1243
1244if ExtraVim()
1245 function! F()
1246 while 1
1247 try
1248 Xpath 1 " X: 1
1249 while 1
1250 try
1251 Xpath 2 " X: 2
1252 asdf " error
1253 Xpath 4 " X: 0
1254 finally
1255 Xpath 8 " X: 8
1256 endtry | Xpath 16 " X: 0
1257 Xpath 32 " X: 0
1258 break
1259 endwhile
1260 Xpath 64 " X: 0
1261 finally
1262 Xpath 128 " X: 128
1263 endtry | Xpath 256 " X: 0
1264 Xpath 512 " X: 0
1265 break
1266 endwhile
1267 Xpath 1024 " X: 0
1268 endfunction
1269
1270 while 1
1271 try
1272 Xpath 2048 " X: 2048
1273 while 1
1274 call F()
1275 Xpath 4096 " X: 0
1276 break
1277 endwhile | Xpath 8192 " X: 0
1278 Xpath 16384 " X: 0
1279 finally
1280 Xpath 32768 " X: 32768
1281 endtry | Xpath 65536 " X: 0
1282 endwhile | Xpath 131072 " X: 0
1283 Xpath 262144 " X: 0
1284endif
1285
1286if ExtraVim()
1287 function! G() abort
1288 if 1
1289 try
1290 Xpath 524288 " X: 524288
1291 asdf " error
1292 Xpath 1048576 " X: 0
1293 finally
1294 Xpath 2097152 " X: 2097152
1295 endtry | Xpath 4194304 " X: 0
1296 endif | Xpath 8388608 " X: 0
1297 Xpath 16777216 " X: 0
1298 endfunction
1299
1300 if 1
1301 try
1302 Xpath 33554432 " X: 33554432
1303 call G()
1304 Xpath 67108864 " X: 0
1305 finally
1306 Xpath 134217728 " X: 134217728
1307 endtry | Xpath 268435456 " X: 0
1308 endif | Xpath 536870912 " X: 0
1309 Xpath 1073741824 " X: 0
1310endif
1311
1312Xcheck 170428555
1313
1314
1315"-------------------------------------------------------------------------------
1316" Test 30: Executing :finally clauses on interrupt {{{1
1317"
1318" After an interrupt in a command dynamically enclosed in
1319" a :try/:endtry region, :finally clauses are executed and the
1320" script processing is terminated.
1321"-------------------------------------------------------------------------------
1322
1323XpathINIT
1324
1325if ExtraVim()
1326 XloopINIT 1 16
1327
1328 function! F()
1329 try
1330 Xloop 1 " X: 1 + 1*16
1331 "INTERRUPT
1332 Xloop 2 " X: 0
1333 finally
1334 Xloop 4 " X: 4 + 4*16
1335 endtry
1336 Xloop 8 " X: 0
1337 endfunction
1338
1339 try
1340 Xpath 256 " X: 256
1341 try
1342 Xpath 512 " X: 512
1343 "INTERRUPT
1344 Xpath 1024 " X: 0
1345 finally
1346 Xpath 2048 " X: 2048
1347 try
1348 Xpath 4096 " X: 4096
1349 try
1350 Xpath 8192 " X: 8192
1351 finally
1352 Xpath 16384 " X: 16384
1353 try
1354 Xpath 32768 " X: 32768
1355 "INTERRUPT
1356 Xpath 65536 " X: 0
1357 endtry
1358 Xpath 131072 " X: 0
1359 endtry
1360 Xpath 262144 " X: 0
1361 endtry
1362 Xpath 524288 " X: 0
1363 endtry
1364 Xpath 1048576 " X: 0
1365 finally
1366 Xpath 2097152 " X: 2097152
1367 try
1368 Xpath 4194304 " X: 4194304
1369 call F()
1370 Xpath 8388608 " X: 0
1371 finally
1372 Xpath 16777216 " X: 16777216
1373 try
1374 Xpath 33554432 " X: 33554432
1375 XloopNEXT
1376 ExecAsScript F
1377 Xpath 67108864 " X: 0
1378 finally
1379 Xpath 134217728 " X: 134217728
1380 endtry
1381 Xpath 268435456 " X: 0
1382 endtry
1383 Xpath 536870912 " X: 0
1384 endtry
1385 Xpath 1073741824 " X: 0
1386endif
1387
1388Xcheck 190905173
1389
1390
1391"-------------------------------------------------------------------------------
1392" Test 31: Executing :finally clauses after :throw {{{1
1393"
1394" After a :throw dynamically enclosed in a :try/:endtry region,
1395" :finally clauses are executed and the script processing is
1396" terminated.
1397"-------------------------------------------------------------------------------
1398
1399XpathINIT
1400
1401if ExtraVim()
1402 XloopINIT 1 16
1403
1404 function! F()
1405 try
1406 Xloop 1 " X: 1 + 1*16
1407 throw "exception"
1408 Xloop 2 " X: 0
1409 finally
1410 Xloop 4 " X: 4 + 4*16
1411 endtry
1412 Xloop 8 " X: 0
1413 endfunction
1414
1415 try
1416 Xpath 256 " X: 256
1417 try
1418 Xpath 512 " X: 512
1419 throw "exception"
1420 Xpath 1024 " X: 0
1421 finally
1422 Xpath 2048 " X: 2048
1423 try
1424 Xpath 4096 " X: 4096
1425 try
1426 Xpath 8192 " X: 8192
1427 finally
1428 Xpath 16384 " X: 16384
1429 try
1430 Xpath 32768 " X: 32768
1431 throw "exception"
1432 Xpath 65536 " X: 0
1433 endtry
1434 Xpath 131072 " X: 0
1435 endtry
1436 Xpath 262144 " X: 0
1437 endtry
1438 Xpath 524288 " X: 0
1439 endtry
1440 Xpath 1048576 " X: 0
1441 finally
1442 Xpath 2097152 " X: 2097152
1443 try
1444 Xpath 4194304 " X: 4194304
1445 call F()
1446 Xpath 8388608 " X: 0
1447 finally
1448 Xpath 16777216 " X: 16777216
1449 try
1450 Xpath 33554432 " X: 33554432
1451 XloopNEXT
1452 ExecAsScript F
1453 Xpath 67108864 " X: 0
1454 finally
1455 Xpath 134217728 " X: 134217728
1456 endtry
1457 Xpath 268435456 " X: 0
1458 endtry
1459 Xpath 536870912 " X: 0
1460 endtry
1461 Xpath 1073741824 " X: 0
1462endif
1463
1464Xcheck 190905173
1465
Bram Moolenaar1f068232019-11-03 16:17:26 +01001466" Tests 32 and 33 were moved to test_trycatch.vim
1467let Xtest = 34
Bram Moolenaar071d4272004-06-13 20:20:40 +00001468
1469
1470"-------------------------------------------------------------------------------
1471" Test 34: :finally reason discarded by :continue {{{1
1472"
1473" When a :finally clause is executed due to a :continue, :break,
1474" :return, :finish, error, interrupt or :throw, the jump reason is
1475" discarded by a :continue in the finally clause.
1476"-------------------------------------------------------------------------------
1477
1478XpathINIT
1479
1480if ExtraVim()
1481
1482 XloopINIT! 1 8
1483
1484 function! C(jump)
1485 XloopNEXT
1486 let loop = 0
1487 while loop < 2
1488 let loop = loop + 1
1489 if loop == 1
1490 try
1491 if a:jump == "continue"
1492 continue
1493 elseif a:jump == "break"
1494 break
1495 elseif a:jump == "return" || a:jump == "finish"
1496 return
1497 elseif a:jump == "error"
1498 asdf
1499 elseif a:jump == "interrupt"
1500 "INTERRUPT
1501 let dummy = 0
1502 elseif a:jump == "throw"
1503 throw "abc"
1504 endif
1505 finally
1506 continue " discards jump that caused the :finally
1507 Xloop 1 " X: 0
1508 endtry
1509 Xloop 2 " X: 0
1510 elseif loop == 2
1511 Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144)
1512 endif
1513 endwhile
1514 endfunction
1515
1516 call C("continue")
1517 Xpath 2097152 " X: 2097152
1518 call C("break")
1519 Xpath 4194304 " X: 4194304
1520 call C("return")
1521 Xpath 8388608 " X: 8388608
1522 let g:jump = "finish"
1523 ExecAsScript C
1524 unlet g:jump
1525 Xpath 16777216 " X: 16777216
1526 try
1527 call C("error")
1528 Xpath 33554432 " X: 33554432
1529 finally
1530 Xpath 67108864 " X: 67108864
1531 try
1532 call C("interrupt")
1533 Xpath 134217728 " X: 134217728
1534 finally
1535 Xpath 268435456 " X: 268435456
1536 call C("throw")
1537 Xpath 536870912 " X: 536870912
1538 endtry
1539 endtry
1540 Xpath 1073741824 " X: 1073741824
1541
1542 delfunction C
1543
1544endif
1545
1546Xcheck 2146584868
1547
1548
1549"-------------------------------------------------------------------------------
1550" Test 35: :finally reason discarded by :break {{{1
1551"
1552" When a :finally clause is executed due to a :continue, :break,
1553" :return, :finish, error, interrupt or :throw, the jump reason is
1554" discarded by a :break in the finally clause.
1555"-------------------------------------------------------------------------------
1556
1557XpathINIT
1558
1559if ExtraVim()
1560
1561 XloopINIT! 1 8
1562
1563 function! B(jump)
1564 XloopNEXT
1565 let loop = 0
1566 while loop < 2
1567 let loop = loop + 1
1568 if loop == 1
1569 try
1570 if a:jump == "continue"
1571 continue
1572 elseif a:jump == "break"
1573 break
1574 elseif a:jump == "return" || a:jump == "finish"
1575 return
1576 elseif a:jump == "error"
1577 asdf
1578 elseif a:jump == "interrupt"
1579 "INTERRUPT
1580 let dummy = 0
1581 elseif a:jump == "throw"
1582 throw "abc"
1583 endif
1584 finally
1585 break " discards jump that caused the :finally
1586 Xloop 1 " X: 0
1587 endtry
1588 elseif loop == 2
1589 Xloop 2 " X: 0
1590 endif
1591 endwhile
1592 Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144)
1593 endfunction
1594
1595 call B("continue")
1596 Xpath 2097152 " X: 2097152
1597 call B("break")
1598 Xpath 4194304 " X: 4194304
1599 call B("return")
1600 Xpath 8388608 " X: 8388608
1601 let g:jump = "finish"
1602 ExecAsScript B
1603 unlet g:jump
1604 Xpath 16777216 " X: 16777216
1605 try
1606 call B("error")
1607 Xpath 33554432 " X: 33554432
1608 finally
1609 Xpath 67108864 " X: 67108864
1610 try
1611 call B("interrupt")
1612 Xpath 134217728 " X: 134217728
1613 finally
1614 Xpath 268435456 " X: 268435456
1615 call B("throw")
1616 Xpath 536870912 " X: 536870912
1617 endtry
1618 endtry
1619 Xpath 1073741824 " X: 1073741824
1620
1621 delfunction B
1622
1623endif
1624
1625Xcheck 2146584868
1626
1627
1628"-------------------------------------------------------------------------------
1629" Test 36: :finally reason discarded by :return {{{1
1630"
1631" When a :finally clause is executed due to a :continue, :break,
1632" :return, :finish, error, interrupt or :throw, the jump reason is
1633" discarded by a :return in the finally clause.
1634"-------------------------------------------------------------------------------
1635
1636XpathINIT
1637
1638if ExtraVim()
1639
1640 XloopINIT! 1 8
1641
1642 function! R(jump, retval) abort
1643 XloopNEXT
1644 let loop = 0
1645 while loop < 2
1646 let loop = loop + 1
1647 if loop == 1
1648 try
1649 if a:jump == "continue"
1650 continue
1651 elseif a:jump == "break"
1652 break
1653 elseif a:jump == "return"
1654 return
1655 elseif a:jump == "error"
1656 asdf
1657 elseif a:jump == "interrupt"
1658 "INTERRUPT
1659 let dummy = 0
1660 elseif a:jump == "throw"
1661 throw "abc"
1662 endif
1663 finally
1664 return a:retval " discards jump that caused the :finally
1665 Xloop 1 " X: 0
1666 endtry
1667 elseif loop == 2
1668 Xloop 2 " X: 0
1669 endif
1670 endwhile
1671 Xloop 4 " X: 0
1672 endfunction
1673
1674 let sum = -R("continue", -8)
1675 Xpath 2097152 " X: 2097152
1676 let sum = sum - R("break", -16)
1677 Xpath 4194304 " X: 4194304
1678 let sum = sum - R("return", -32)
1679 Xpath 8388608 " X: 8388608
1680 try
1681 let sum = sum - R("error", -64)
1682 Xpath 16777216 " X: 16777216
1683 finally
1684 Xpath 33554432 " X: 33554432
1685 try
1686 let sum = sum - R("interrupt", -128)
1687 Xpath 67108864 " X: 67108864
1688 finally
1689 Xpath 134217728 " X: 134217728
1690 let sum = sum - R("throw", -256)
1691 Xpath 268435456 " X: 268435456
1692 endtry
1693 endtry
1694 Xpath 536870912 " X: 536870912
1695
1696 let expected = 8 + 16 + 32 + 64 + 128 + 256
1697 if sum != expected
1698 Xpath 1073741824 " X: 0
1699 Xout "sum =" . sum . ", expected: " . expected
1700 endif
1701
1702 unlet sum expected
1703 delfunction R
1704
1705endif
1706
1707Xcheck 1071644672
1708
1709
1710"-------------------------------------------------------------------------------
1711" Test 37: :finally reason discarded by :finish {{{1
1712"
1713" When a :finally clause is executed due to a :continue, :break,
1714" :return, :finish, error, interrupt or :throw, the jump reason is
1715" discarded by a :finish in the finally clause.
1716"-------------------------------------------------------------------------------
1717
1718XpathINIT
1719
1720if ExtraVim()
1721
1722 XloopINIT! 1 8
1723
1724 function! F(jump) " not executed as function, transformed to a script
1725 XloopNEXT
1726 let loop = 0
1727 while loop < 2
1728 let loop = loop + 1
1729 if loop == 1
1730 try
1731 if a:jump == "continue"
1732 continue
1733 elseif a:jump == "break"
1734 break
1735 elseif a:jump == "finish"
1736 finish
1737 elseif a:jump == "error"
1738 asdf
1739 elseif a:jump == "interrupt"
1740 "INTERRUPT
1741 let dummy = 0
1742 elseif a:jump == "throw"
1743 throw "abc"
1744 endif
1745 finally
1746 finish " discards jump that caused the :finally
1747 Xloop 1 " X: 0
1748 endtry
1749 elseif loop == 2
1750 Xloop 2 " X: 0
1751 endif
1752 endwhile
1753 Xloop 4 " X: 0
1754 endfunction
1755
1756 let scriptF = MakeScript("F")
1757 delfunction F
1758
1759 let g:jump = "continue"
1760 exec "source" scriptF
1761 Xpath 2097152 " X: 2097152
1762 let g:jump = "break"
1763 exec "source" scriptF
1764 Xpath 4194304 " X: 4194304
1765 let g:jump = "finish"
1766 exec "source" scriptF
1767 Xpath 8388608 " X: 8388608
1768 try
1769 let g:jump = "error"
1770 exec "source" scriptF
1771 Xpath 16777216 " X: 16777216
1772 finally
1773 Xpath 33554432 " X: 33554432
1774 try
1775 let g:jump = "interrupt"
1776 exec "source" scriptF
1777 Xpath 67108864 " X: 67108864
1778 finally
1779 Xpath 134217728 " X: 134217728
1780 try
1781 let g:jump = "throw"
1782 exec "source" scriptF
1783 Xpath 268435456 " X: 268435456
1784 finally
1785 Xpath 536870912 " X: 536870912
1786 endtry
1787 endtry
1788 endtry
1789 unlet g:jump
1790
1791 call delete(scriptF)
1792 unlet scriptF
1793
1794endif
1795
1796Xcheck 1071644672
1797
1798
1799"-------------------------------------------------------------------------------
1800" Test 38: :finally reason discarded by an error {{{1
1801"
1802" When a :finally clause is executed due to a :continue, :break,
1803" :return, :finish, error, interrupt or :throw, the jump reason is
1804" discarded by an error in the finally clause.
1805"-------------------------------------------------------------------------------
1806
1807XpathINIT
1808
1809if ExtraVim()
1810
1811 XloopINIT! 1 4
1812
1813 function! E(jump)
1814 XloopNEXT
1815 let loop = 0
1816 while loop < 2
1817 let loop = loop + 1
1818 if loop == 1
1819 try
1820 if a:jump == "continue"
1821 continue
1822 elseif a:jump == "break"
1823 break
1824 elseif a:jump == "return" || a:jump == "finish"
1825 return
1826 elseif a:jump == "error"
1827 asdf
1828 elseif a:jump == "interrupt"
1829 "INTERRUPT
1830 let dummy = 0
1831 elseif a:jump == "throw"
1832 throw "abc"
1833 endif
1834 finally
1835 asdf " error; discards jump that caused the :finally
1836 endtry
1837 elseif loop == 2
1838 Xloop 1 " X: 0
1839 endif
1840 endwhile
1841 Xloop 2 " X: 0
1842 endfunction
1843
1844 try
1845 Xpath 16384 " X: 16384
1846 call E("continue")
1847 Xpath 32768 " X: 0
1848 finally
1849 try
1850 Xpath 65536 " X: 65536
1851 call E("break")
1852 Xpath 131072 " X: 0
1853 finally
1854 try
1855 Xpath 262144 " X: 262144
1856 call E("return")
1857 Xpath 524288 " X: 0
1858 finally
1859 try
1860 Xpath 1048576 " X: 1048576
1861 let g:jump = "finish"
1862 ExecAsScript E
1863 Xpath 2097152 " X: 0
1864 finally
1865 unlet g:jump
1866 try
1867 Xpath 4194304 " X: 4194304
1868 call E("error")
1869 Xpath 8388608 " X: 0
1870 finally
1871 try
1872 Xpath 16777216 " X: 16777216
1873 call E("interrupt")
1874 Xpath 33554432 " X: 0
1875 finally
1876 try
1877 Xpath 67108864 " X: 67108864
1878 call E("throw")
1879 Xpath 134217728 " X: 0
1880 finally
1881 Xpath 268435456 " X: 268435456
1882 delfunction E
1883 endtry
1884 endtry
1885 endtry
1886 endtry
1887 endtry
1888 endtry
1889 endtry
1890 Xpath 536870912 " X: 0
1891
1892endif
1893
1894Xcheck 357908480
1895
1896
1897"-------------------------------------------------------------------------------
1898" Test 39: :finally reason discarded by an interrupt {{{1
1899"
1900" When a :finally clause is executed due to a :continue, :break,
1901" :return, :finish, error, interrupt or :throw, the jump reason is
1902" discarded by an interrupt in the finally clause.
1903"-------------------------------------------------------------------------------
1904
1905XpathINIT
1906
1907if ExtraVim()
1908
1909 XloopINIT! 1 4
1910
1911 function! I(jump)
1912 XloopNEXT
1913 let loop = 0
1914 while loop < 2
1915 let loop = loop + 1
1916 if loop == 1
1917 try
1918 if a:jump == "continue"
1919 continue
1920 elseif a:jump == "break"
1921 break
1922 elseif a:jump == "return" || a:jump == "finish"
1923 return
1924 elseif a:jump == "error"
1925 asdf
1926 elseif a:jump == "interrupt"
1927 "INTERRUPT
1928 let dummy = 0
1929 elseif a:jump == "throw"
1930 throw "abc"
1931 endif
1932 finally
1933 "INTERRUPT - discards jump that caused the :finally
1934 let dummy = 0
1935 endtry
1936 elseif loop == 2
1937 Xloop 1 " X: 0
1938 endif
1939 endwhile
1940 Xloop 2 " X: 0
1941 endfunction
1942
1943 try
1944 Xpath 16384 " X: 16384
1945 call I("continue")
1946 Xpath 32768 " X: 0
1947 finally
1948 try
1949 Xpath 65536 " X: 65536
1950 call I("break")
1951 Xpath 131072 " X: 0
1952 finally
1953 try
1954 Xpath 262144 " X: 262144
1955 call I("return")
1956 Xpath 524288 " X: 0
1957 finally
1958 try
1959 Xpath 1048576 " X: 1048576
1960 let g:jump = "finish"
1961 ExecAsScript I
1962 Xpath 2097152 " X: 0
1963 finally
1964 unlet g:jump
1965 try
1966 Xpath 4194304 " X: 4194304
1967 call I("error")
1968 Xpath 8388608 " X: 0
1969 finally
1970 try
1971 Xpath 16777216 " X: 16777216
1972 call I("interrupt")
1973 Xpath 33554432 " X: 0
1974 finally
1975 try
1976 Xpath 67108864 " X: 67108864
1977 call I("throw")
1978 Xpath 134217728 " X: 0
1979 finally
1980 Xpath 268435456 " X: 268435456
1981 delfunction I
1982 endtry
1983 endtry
1984 endtry
1985 endtry
1986 endtry
1987 endtry
1988 endtry
1989 Xpath 536870912 " X: 0
1990
1991endif
1992
1993Xcheck 357908480
1994
1995
1996"-------------------------------------------------------------------------------
1997" Test 40: :finally reason discarded by :throw {{{1
1998"
1999" When a :finally clause is executed due to a :continue, :break,
2000" :return, :finish, error, interrupt or :throw, the jump reason is
2001" discarded by a :throw in the finally clause.
2002"-------------------------------------------------------------------------------
2003
2004XpathINIT
2005
2006if ExtraVim()
2007
2008 XloopINIT! 1 4
2009
2010 function! T(jump)
2011 XloopNEXT
2012 let loop = 0
2013 while loop < 2
2014 let loop = loop + 1
2015 if loop == 1
2016 try
2017 if a:jump == "continue"
2018 continue
2019 elseif a:jump == "break"
2020 break
2021 elseif a:jump == "return" || a:jump == "finish"
2022 return
2023 elseif a:jump == "error"
2024 asdf
2025 elseif a:jump == "interrupt"
2026 "INTERRUPT
2027 let dummy = 0
2028 elseif a:jump == "throw"
2029 throw "abc"
2030 endif
2031 finally
2032 throw "xyz" " discards jump that caused the :finally
2033 endtry
2034 elseif loop == 2
2035 Xloop 1 " X: 0
2036 endif
2037 endwhile
2038 Xloop 2 " X: 0
2039 endfunction
2040
2041 try
2042 Xpath 16384 " X: 16384
2043 call T("continue")
2044 Xpath 32768 " X: 0
2045 finally
2046 try
2047 Xpath 65536 " X: 65536
2048 call T("break")
2049 Xpath 131072 " X: 0
2050 finally
2051 try
2052 Xpath 262144 " X: 262144
2053 call T("return")
2054 Xpath 524288 " X: 0
2055 finally
2056 try
2057 Xpath 1048576 " X: 1048576
2058 let g:jump = "finish"
2059 ExecAsScript T
2060 Xpath 2097152 " X: 0
2061 finally
2062 unlet g:jump
2063 try
2064 Xpath 4194304 " X: 4194304
2065 call T("error")
2066 Xpath 8388608 " X: 0
2067 finally
2068 try
2069 Xpath 16777216 " X: 16777216
2070 call T("interrupt")
2071 Xpath 33554432 " X: 0
2072 finally
2073 try
2074 Xpath 67108864 " X: 67108864
2075 call T("throw")
2076 Xpath 134217728 " X: 0
2077 finally
2078 Xpath 268435456 " X: 268435456
2079 delfunction T
2080 endtry
2081 endtry
2082 endtry
2083 endtry
2084 endtry
2085 endtry
2086 endtry
2087 Xpath 536870912 " X: 0
2088
2089endif
2090
2091Xcheck 357908480
2092
Bram Moolenaar1f068232019-11-03 16:17:26 +01002093" Tests 41 to 48 were moved to test_trycatch.vim
2094let Xtest = 49
Bram Moolenaar071d4272004-06-13 20:20:40 +00002095
2096
2097"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002098" Test 49: Throwing exceptions across functions {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00002099"
2100" When an exception is thrown but not caught inside a function, the
2101" caller is checked for a matching :catch clause.
2102"-------------------------------------------------------------------------------
2103
2104XpathINIT
2105
2106function! C()
2107 try
2108 Xpath 1 " X: 1
2109 throw "arrgh"
2110 Xpath 2 " X: 0
2111 catch /arrgh/
2112 Xpath 4 " X: 4
2113 endtry
2114 Xpath 8 " X: 8
2115endfunction
2116
2117XloopINIT! 16 16
2118
2119function! T1()
2120 XloopNEXT
2121 try
2122 Xloop 1 " X: 16 + 16*16
2123 throw "arrgh"
2124 Xloop 2 " X: 0
2125 finally
2126 Xloop 4 " X: 64 + 64*16
2127 endtry
2128 Xloop 8 " X: 0
2129endfunction
2130
2131function! T2()
2132 try
2133 Xpath 4096 " X: 4096
2134 call T1()
2135 Xpath 8192 " X: 0
2136 finally
2137 Xpath 16384 " X: 16384
2138 endtry
2139 Xpath 32768 " X: 0
2140endfunction
2141
2142try
2143 Xpath 65536 " X: 65536
2144 call C() " throw and catch
2145 Xpath 131072 " X: 131072
2146catch /.*/
2147 Xpath 262144 " X: 0
2148 Xout v:exception "in" v:throwpoint
2149endtry
2150
2151try
2152 Xpath 524288 " X: 524288
2153 call T1() " throw, one level
2154 Xpath 1048576 " X: 0
2155catch /arrgh/
2156 Xpath 2097152 " X: 2097152
2157catch /.*/
2158 Xpath 4194304 " X: 0
2159 Xout v:exception "in" v:throwpoint
2160endtry
2161
2162try
2163 Xpath 8388608 " X: 8388608
2164 call T2() " throw, two levels
2165 Xpath 16777216 " X: 0
2166catch /arrgh/
2167 Xpath 33554432 " X: 33554432
2168catch /.*/
2169 Xpath 67108864 " X: 0
2170 Xout v:exception "in" v:throwpoint
2171endtry
2172Xpath 134217728 " X: 134217728
2173
2174Xcheck 179000669
2175
2176" Leave C, T1, and T2 for execution as scripts in the next test.
2177
2178
2179"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002180" Test 50: Throwing exceptions across script files {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00002181"
2182" When an exception is thrown but not caught inside a script file,
2183" the sourcing script or function is checked for a matching :catch
2184" clause.
2185"
2186" This test executes the bodies of the functions C, T1, and T2 from
2187" the previous test as script files (:return replaced by :finish).
2188"-------------------------------------------------------------------------------
2189
2190XpathINIT
2191
2192let scriptC = MakeScript("C") " X: 1 + 4 + 8
2193delfunction C
2194
2195XloopINIT! 16 16
2196
2197let scriptT1 = MakeScript("T1") " X: 16 + 64 + 16*16 + 64*16
2198delfunction T1
2199
2200let scriptT2 = MakeScript("T2", scriptT1) " X: 4096 + 16384
2201delfunction T2
2202
2203function! F()
2204 try
2205 Xpath 65536 " X: 65536
2206 exec "source" g:scriptC
2207 Xpath 131072 " X: 131072
2208 catch /.*/
2209 Xpath 262144 " X: 0
2210 Xout v:exception "in" v:throwpoint
2211 endtry
2212
2213 try
2214 Xpath 524288 " X: 524288
2215 exec "source" g:scriptT1
2216 Xpath 1048576 " X: 0
2217 catch /arrgh/
2218 Xpath 2097152 " X: 2097152
2219 catch /.*/
2220 Xpath 4194304 " X: 0
2221 Xout v:exception "in" v:throwpoint
2222 endtry
2223endfunction
2224
2225try
2226 Xpath 8388608 " X: 8388608
2227 call F()
2228 Xpath 16777216 " X: 16777216
2229 exec "source" scriptT2
2230 Xpath 33554432 " X: 0
2231catch /arrgh/
2232 Xpath 67108864 " X: 67108864
2233catch /.*/
2234 Xpath 134217728 " X: 0
2235 Xout v:exception "in" v:throwpoint
2236endtry
2237Xpath 268435456 " X: 268435456
2238
2239call delete(scriptC)
2240call delete(scriptT1)
2241call delete(scriptT2)
2242unlet scriptC scriptT1 scriptT2
2243delfunction F
2244
2245Xcheck 363550045
2246
Bram Moolenaar1f068232019-11-03 16:17:26 +01002247" Test 51 was moved to test_trycatch.vim
2248let Xtest = 52
Bram Moolenaar071d4272004-06-13 20:20:40 +00002249
2250
2251"-------------------------------------------------------------------------------
2252" Test 52: Uncaught exceptions {{{1
2253"
2254" When an exception is thrown but not caught, an error message is
2255" displayed when the script is terminated. In case of an interrupt
2256" or error exception, the normal interrupt or error message(s) are
2257" displayed.
2258"-------------------------------------------------------------------------------
2259
2260XpathINIT
2261
2262let msgfile = tempname()
2263
2264function! MESSAGES(...)
2265 try
2266 exec "edit" g:msgfile
2267 catch /^Vim(edit):/
2268 return 0
2269 endtry
2270
2271 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
2272 let match = 1
2273 norm gg
2274
2275 let num = a:0 / 2
2276 let cnt = 1
2277 while cnt <= num
2278 let enr = a:{2*cnt - 1}
2279 let emsg= a:{2*cnt}
2280 let cnt = cnt + 1
2281
2282 if enr == ""
2283 Xout "TODO: Add message number for:" emsg
2284 elseif enr == "INT"
2285 let enr = ""
2286 endif
2287 if enr == "" && !english
2288 continue
2289 endif
2290 let pattern = (enr != "") ? enr . ':.*' : ''
2291 if english
2292 let pattern = pattern . emsg
2293 endif
2294 if !search(pattern, "W")
2295 let match = 0
2296 Xout "No match for:" pattern
2297 endif
2298 norm $
2299 endwhile
2300
2301 bwipeout!
2302 return match
2303endfunction
2304
2305if ExtraVim(msgfile)
2306 Xpath 1 " X: 1
2307 throw "arrgh"
2308endif
2309
2310Xpath 2 " X: 2
2311if !MESSAGES('E605', "Exception not caught")
2312 Xpath 4 " X: 0
2313endif
2314
2315if ExtraVim(msgfile)
2316 try
2317 Xpath 8 " X: 8
2318 throw "oops"
2319 catch /arrgh/
2320 Xpath 16 " X: 0
2321 endtry
2322 Xpath 32 " X: 0
2323endif
2324
2325Xpath 64 " X: 64
2326if !MESSAGES('E605', "Exception not caught")
2327 Xpath 128 " X: 0
2328endif
2329
2330if ExtraVim(msgfile)
2331 function! T()
2332 throw "brrr"
2333 endfunction
2334
2335 try
2336 Xpath 256 " X: 256
2337 throw "arrgh"
2338 catch /.*/
2339 Xpath 512 " X: 512
2340 call T()
2341 endtry
2342 Xpath 1024 " X: 0
2343endif
2344
2345Xpath 2048 " X: 2048
2346if !MESSAGES('E605', "Exception not caught")
2347 Xpath 4096 " X: 0
2348endif
2349
2350if ExtraVim(msgfile)
2351 try
2352 Xpath 8192 " X: 8192
2353 throw "arrgh"
2354 finally
2355 Xpath 16384 " X: 16384
2356 throw "brrr"
2357 endtry
2358 Xpath 32768 " X: 0
2359endif
2360
2361Xpath 65536 " X: 65536
2362if !MESSAGES('E605', "Exception not caught")
2363 Xpath 131072 " X: 0
2364endif
2365
2366if ExtraVim(msgfile)
2367 try
2368 Xpath 262144 " X: 262144
2369 "INTERRUPT
2370 endtry
2371 Xpath 524288 " X: 0
2372endif
2373
2374Xpath 1048576 " X: 1048576
2375if !MESSAGES('INT', "Interrupted")
2376 Xpath 2097152 " X: 0
2377endif
2378
2379if ExtraVim(msgfile)
2380 try
2381 Xpath 4194304 " X: 4194304
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01002382 let x = novar " error E121; exception: E121
Bram Moolenaar071d4272004-06-13 20:20:40 +00002383 catch /E15:/ " should not catch
2384 Xpath 8388608 " X: 0
2385 endtry
2386 Xpath 16777216 " X: 0
2387endif
2388
2389Xpath 33554432 " X: 33554432
Bram Moolenaarc0f5a782019-01-13 15:16:13 +01002390if !MESSAGES('E121', "Undefined variable")
Bram Moolenaar071d4272004-06-13 20:20:40 +00002391 Xpath 67108864 " X: 0
2392endif
2393
2394if ExtraVim(msgfile)
2395 try
2396 Xpath 134217728 " X: 134217728
2397" unlet novar # " error E108/E488; exception: E488
2398 catch /E108:/ " should not catch
2399 Xpath 268435456 " X: 0
2400 endtry
2401 Xpath 536870912 " X: 0
2402endif
2403
2404Xpath 1073741824 " X: 1073741824
2405if !MESSAGES('E108', "No such variable", 'E488', "Trailing characters")
2406 " The Xpath command does not accept 2^31 (negative); add explicitly:
2407 let Xpath = Xpath + 2147483648 " X: 0
2408endif
2409
2410call delete(msgfile)
2411unlet msgfile
2412
2413Xcheck 1247112011
2414
2415" Leave MESSAGES() for the next tests.
2416
2417
2418"-------------------------------------------------------------------------------
2419" Test 53: Nesting errors: :endif/:else/:elseif {{{1
2420"
2421" For nesting errors of :if conditionals the correct error messages
2422" should be given.
2423"
2424" This test reuses the function MESSAGES() from the previous test.
2425" This functions checks the messages in g:msgfile.
2426"-------------------------------------------------------------------------------
2427
2428XpathINIT
2429
2430let msgfile = tempname()
2431
2432if ExtraVim(msgfile)
2433" endif
2434endif
2435if MESSAGES('E580', ":endif without :if")
2436 Xpath 1 " X: 1
2437endif
2438
2439if ExtraVim(msgfile)
2440" while 1
2441" endif
2442" endwhile
2443endif
2444if MESSAGES('E580', ":endif without :if")
2445 Xpath 2 " X: 2
2446endif
2447
2448if ExtraVim(msgfile)
2449" try
2450" finally
2451" endif
2452" endtry
2453endif
2454if MESSAGES('E580', ":endif without :if")
2455 Xpath 4 " X: 4
2456endif
2457
2458if ExtraVim(msgfile)
2459" try
2460" endif
2461" endtry
2462endif
2463if MESSAGES('E580', ":endif without :if")
2464 Xpath 8 " X: 8
2465endif
2466
2467if ExtraVim(msgfile)
2468" try
2469" throw "a"
2470" catch /a/
2471" endif
2472" endtry
2473endif
2474if MESSAGES('E580', ":endif without :if")
2475 Xpath 16 " X: 16
2476endif
2477
2478if ExtraVim(msgfile)
2479" else
2480endif
2481if MESSAGES('E581', ":else without :if")
2482 Xpath 32 " X: 32
2483endif
2484
2485if ExtraVim(msgfile)
2486" while 1
2487" else
2488" endwhile
2489endif
2490if MESSAGES('E581', ":else without :if")
2491 Xpath 64 " X: 64
2492endif
2493
2494if ExtraVim(msgfile)
2495" try
2496" finally
2497" else
2498" endtry
2499endif
2500if MESSAGES('E581', ":else without :if")
2501 Xpath 128 " X: 128
2502endif
2503
2504if ExtraVim(msgfile)
2505" try
2506" else
2507" endtry
2508endif
2509if MESSAGES('E581', ":else without :if")
2510 Xpath 256 " X: 256
2511endif
2512
2513if ExtraVim(msgfile)
2514" try
2515" throw "a"
2516" catch /a/
2517" else
2518" endtry
2519endif
2520if MESSAGES('E581', ":else without :if")
2521 Xpath 512 " X: 512
2522endif
2523
2524if ExtraVim(msgfile)
2525" elseif
2526endif
2527if MESSAGES('E582', ":elseif without :if")
2528 Xpath 1024 " X: 1024
2529endif
2530
2531if ExtraVim(msgfile)
2532" while 1
2533" elseif
2534" endwhile
2535endif
2536if MESSAGES('E582', ":elseif without :if")
2537 Xpath 2048 " X: 2048
2538endif
2539
2540if ExtraVim(msgfile)
2541" try
2542" finally
2543" elseif
2544" endtry
2545endif
2546if MESSAGES('E582', ":elseif without :if")
2547 Xpath 4096 " X: 4096
2548endif
2549
2550if ExtraVim(msgfile)
2551" try
2552" elseif
2553" endtry
2554endif
2555if MESSAGES('E582', ":elseif without :if")
2556 Xpath 8192 " X: 8192
2557endif
2558
2559if ExtraVim(msgfile)
2560" try
2561" throw "a"
2562" catch /a/
2563" elseif
2564" endtry
2565endif
2566if MESSAGES('E582', ":elseif without :if")
2567 Xpath 16384 " X: 16384
2568endif
2569
2570if ExtraVim(msgfile)
2571" if 1
2572" else
2573" else
2574" endif
2575endif
2576if MESSAGES('E583', "multiple :else")
2577 Xpath 32768 " X: 32768
2578endif
2579
2580if ExtraVim(msgfile)
2581" if 1
2582" else
2583" elseif 1
2584" endif
2585endif
2586if MESSAGES('E584', ":elseif after :else")
2587 Xpath 65536 " X: 65536
2588endif
2589
2590call delete(msgfile)
2591unlet msgfile
2592
2593Xcheck 131071
2594
2595" Leave MESSAGES() for the next test.
2596
2597
2598"-------------------------------------------------------------------------------
2599" Test 54: Nesting errors: :while/:endwhile {{{1
2600"
2601" For nesting errors of :while conditionals the correct error messages
2602" should be given.
2603"
2604" This test reuses the function MESSAGES() from the previous test.
2605" This functions checks the messages in g:msgfile.
2606"-------------------------------------------------------------------------------
2607
2608XpathINIT
2609
2610let msgfile = tempname()
2611
2612if ExtraVim(msgfile)
2613" endwhile
2614endif
2615if MESSAGES('E588', ":endwhile without :while")
2616 Xpath 1 " X: 1
2617endif
2618
2619if ExtraVim(msgfile)
2620" if 1
2621" endwhile
2622" endif
2623endif
2624if MESSAGES('E588', ":endwhile without :while")
2625 Xpath 2 " X: 2
2626endif
2627
2628if ExtraVim(msgfile)
2629" while 1
2630" if 1
2631" endwhile
2632endif
2633if MESSAGES('E171', "Missing :endif")
2634 Xpath 4 " X: 4
2635endif
2636
2637if ExtraVim(msgfile)
2638" try
2639" finally
2640" endwhile
2641" endtry
2642endif
2643if MESSAGES('E588', ":endwhile without :while")
2644 Xpath 8 " X: 8
2645endif
2646
2647if ExtraVim(msgfile)
2648" while 1
2649" try
2650" finally
2651" endwhile
2652endif
2653if MESSAGES('E600', "Missing :endtry")
2654 Xpath 16 " X: 16
2655endif
2656
2657if ExtraVim(msgfile)
2658" while 1
2659" if 1
2660" try
2661" finally
2662" endwhile
2663endif
2664if MESSAGES('E600', "Missing :endtry")
2665 Xpath 32 " X: 32
2666endif
2667
2668if ExtraVim(msgfile)
2669" while 1
2670" try
2671" finally
2672" if 1
2673" endwhile
2674endif
2675if MESSAGES('E171', "Missing :endif")
2676 Xpath 64 " X: 64
2677endif
2678
2679if ExtraVim(msgfile)
2680" try
2681" endwhile
2682" endtry
2683endif
2684if MESSAGES('E588', ":endwhile without :while")
2685 Xpath 128 " X: 128
2686endif
2687
2688if ExtraVim(msgfile)
2689" while 1
2690" try
2691" endwhile
2692" endtry
2693" endwhile
2694endif
2695if MESSAGES('E588', ":endwhile without :while")
2696 Xpath 256 " X: 256
2697endif
2698
2699if ExtraVim(msgfile)
2700" try
2701" throw "a"
2702" catch /a/
2703" endwhile
2704" endtry
2705endif
2706if MESSAGES('E588', ":endwhile without :while")
2707 Xpath 512 " X: 512
2708endif
2709
2710if ExtraVim(msgfile)
2711" while 1
2712" try
2713" throw "a"
2714" catch /a/
2715" endwhile
2716" endtry
2717" endwhile
2718endif
2719if MESSAGES('E588', ":endwhile without :while")
2720 Xpath 1024 " X: 1024
2721endif
2722
2723
2724call delete(msgfile)
2725unlet msgfile
2726
2727Xcheck 2047
2728
2729" Leave MESSAGES() for the next test.
2730
2731
2732"-------------------------------------------------------------------------------
2733" Test 55: Nesting errors: :continue/:break {{{1
2734"
2735" For nesting errors of :continue and :break commands the correct
2736" error messages should be given.
2737"
2738" This test reuses the function MESSAGES() from the previous test.
2739" This functions checks the messages in g:msgfile.
2740"-------------------------------------------------------------------------------
2741
2742XpathINIT
2743
2744let msgfile = tempname()
2745
2746if ExtraVim(msgfile)
2747" continue
2748endif
2749if MESSAGES('E586', ":continue without :while")
2750 Xpath 1 " X: 1
2751endif
2752
2753if ExtraVim(msgfile)
2754" if 1
2755" continue
2756" endif
2757endif
2758if MESSAGES('E586', ":continue without :while")
2759 Xpath 2 " X: 2
2760endif
2761
2762if ExtraVim(msgfile)
2763" try
2764" finally
2765" continue
2766" endtry
2767endif
2768if MESSAGES('E586', ":continue without :while")
2769 Xpath 4 " X: 4
2770endif
2771
2772if ExtraVim(msgfile)
2773" try
2774" continue
2775" endtry
2776endif
2777if MESSAGES('E586', ":continue without :while")
2778 Xpath 8 " X: 8
2779endif
2780
2781if ExtraVim(msgfile)
2782" try
2783" throw "a"
2784" catch /a/
2785" continue
2786" endtry
2787endif
2788if MESSAGES('E586', ":continue without :while")
2789 Xpath 16 " X: 16
2790endif
2791
2792if ExtraVim(msgfile)
2793" break
2794endif
2795if MESSAGES('E587', ":break without :while")
2796 Xpath 32 " X: 32
2797endif
2798
2799if ExtraVim(msgfile)
2800" if 1
2801" break
2802" endif
2803endif
2804if MESSAGES('E587', ":break without :while")
2805 Xpath 64 " X: 64
2806endif
2807
2808if ExtraVim(msgfile)
2809" try
2810" finally
2811" break
2812" endtry
2813endif
2814if MESSAGES('E587', ":break without :while")
2815 Xpath 128 " X: 128
2816endif
2817
2818if ExtraVim(msgfile)
2819" try
2820" break
2821" endtry
2822endif
2823if MESSAGES('E587', ":break without :while")
2824 Xpath 256 " X: 256
2825endif
2826
2827if ExtraVim(msgfile)
2828" try
2829" throw "a"
2830" catch /a/
2831" break
2832" endtry
2833endif
2834if MESSAGES('E587', ":break without :while")
2835 Xpath 512 " X: 512
2836endif
2837
2838call delete(msgfile)
2839unlet msgfile
2840
2841Xcheck 1023
2842
2843" Leave MESSAGES() for the next test.
2844
2845
2846"-------------------------------------------------------------------------------
2847" Test 56: Nesting errors: :endtry {{{1
2848"
2849" For nesting errors of :try conditionals the correct error messages
2850" should be given.
2851"
2852" This test reuses the function MESSAGES() from the previous test.
2853" This functions checks the messages in g:msgfile.
2854"-------------------------------------------------------------------------------
2855
2856XpathINIT
2857
2858let msgfile = tempname()
2859
2860if ExtraVim(msgfile)
2861" endtry
2862endif
2863if MESSAGES('E602', ":endtry without :try")
2864 Xpath 1 " X: 1
2865endif
2866
2867if ExtraVim(msgfile)
2868" if 1
2869" endtry
2870" endif
2871endif
2872if MESSAGES('E602', ":endtry without :try")
2873 Xpath 2 " X: 2
2874endif
2875
2876if ExtraVim(msgfile)
2877" while 1
2878" endtry
2879" endwhile
2880endif
2881if MESSAGES('E602', ":endtry without :try")
2882 Xpath 4 " X: 4
2883endif
2884
2885if ExtraVim(msgfile)
2886" try
2887" if 1
2888" endtry
2889endif
2890if MESSAGES('E171', "Missing :endif")
2891 Xpath 8 " X: 8
2892endif
2893
2894if ExtraVim(msgfile)
2895" try
2896" while 1
2897" endtry
2898endif
2899if MESSAGES('E170', "Missing :endwhile")
2900 Xpath 16 " X: 16
2901endif
2902
2903if ExtraVim(msgfile)
2904" try
2905" finally
2906" if 1
2907" endtry
2908endif
2909if MESSAGES('E171', "Missing :endif")
2910 Xpath 32 " X: 32
2911endif
2912
2913if ExtraVim(msgfile)
2914" try
2915" finally
2916" while 1
2917" endtry
2918endif
2919if MESSAGES('E170', "Missing :endwhile")
2920 Xpath 64 " X: 64
2921endif
2922
2923if ExtraVim(msgfile)
2924" try
2925" throw "a"
2926" catch /a/
2927" if 1
2928" endtry
2929endif
2930if MESSAGES('E171', "Missing :endif")
2931 Xpath 128 " X: 128
2932endif
2933
2934if ExtraVim(msgfile)
2935" try
2936" throw "a"
2937" catch /a/
2938" while 1
2939" endtry
2940endif
2941if MESSAGES('E170', "Missing :endwhile")
2942 Xpath 256 " X: 256
2943endif
2944
2945call delete(msgfile)
2946unlet msgfile
2947
2948delfunction MESSAGES
2949
2950Xcheck 511
2951
2952
2953"-------------------------------------------------------------------------------
2954" Test 57: v:exception and v:throwpoint for user exceptions {{{1
2955"
2956" v:exception evaluates to the value of the exception that was caught
2957" most recently and is not finished. (A caught exception is finished
2958" when the next ":catch", ":finally", or ":endtry" is reached.)
2959" v:throwpoint evaluates to the script/function name and line number
2960" where that exception has been thrown.
2961"-------------------------------------------------------------------------------
2962
2963XpathINIT
2964
2965function! FuncException()
2966 let g:exception = v:exception
2967endfunction
2968
2969function! FuncThrowpoint()
2970 let g:throwpoint = v:throwpoint
2971endfunction
2972
2973let scriptException = MakeScript("FuncException")
2974let scriptThrowPoint = MakeScript("FuncThrowpoint")
2975
2976command! CmdException let g:exception = v:exception
2977command! CmdThrowpoint let g:throwpoint = v:throwpoint
2978
2979XloopINIT! 1 2
2980
2981function! CHECK(n, exception, throwname, throwline)
2982 XloopNEXT
2983 let error = 0
2984 if v:exception != a:exception
2985 Xout a:n.": v:exception is" v:exception "instead of" a:exception
2986 let error = 1
2987 endif
2988 if v:throwpoint !~ a:throwname
2989 let name = escape(a:throwname, '\')
2990 Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" name
2991 let error = 1
2992 endif
2993 if v:throwpoint !~ a:throwline
2994 let line = escape(a:throwline, '\')
2995 Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
2996 let error = 1
2997 endif
2998 if error
2999 Xloop 1 " X: 0
3000 endif
3001endfunction
3002
3003function! T(arg, line)
3004 if a:line == 2
3005 throw a:arg " in line 2
3006 elseif a:line == 4
3007 throw a:arg " in line 4
3008 elseif a:line == 6
3009 throw a:arg " in line 6
3010 elseif a:line == 8
3011 throw a:arg " in line 8
3012 endif
3013endfunction
3014
3015function! G(arg, line)
3016 call T(a:arg, a:line)
3017endfunction
3018
3019function! F(arg, line)
3020 call G(a:arg, a:line)
3021endfunction
3022
3023let scriptT = MakeScript("T")
3024let scriptG = MakeScript("G", scriptT)
3025let scriptF = MakeScript("F", scriptG)
3026
3027try
3028 Xpath 32768 " X: 32768
3029 call F("oops", 2)
3030catch /.*/
3031 Xpath 65536 " X: 65536
3032 let exception = v:exception
3033 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02003034 call CHECK(1, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003035 exec "let exception = v:exception"
3036 exec "let throwpoint = v:throwpoint"
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02003037 call CHECK(2, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003038 CmdException
3039 CmdThrowpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02003040 call CHECK(3, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003041 call FuncException()
3042 call FuncThrowpoint()
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02003043 call CHECK(4, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003044 exec "source" scriptException
3045 exec "source" scriptThrowPoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02003046 call CHECK(5, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003047 try
3048 Xpath 131072 " X: 131072
3049 call G("arrgh", 4)
3050 catch /.*/
3051 Xpath 262144 " X: 262144
3052 let exception = v:exception
3053 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02003054 call CHECK(6, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003055 try
3056 Xpath 524288 " X: 524288
3057 let g:arg = "autsch"
3058 let g:line = 6
3059 exec "source" scriptF
3060 catch /.*/
3061 Xpath 1048576 " X: 1048576
3062 let exception = v:exception
3063 let throwpoint = v:throwpoint
3064 " Symbolic links in tempname()s are not resolved, whereas resolving
3065 " is done for v:throwpoint. Resolve the temporary file name for
3066 " scriptT, so that it can be matched against v:throwpoint.
3067 call CHECK(7, "autsch", resolve(scriptT), '\<6\>')
3068 finally
3069 Xpath 2097152 " X: 2097152
3070 let exception = v:exception
3071 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02003072 call CHECK(8, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003073 try
3074 Xpath 4194304 " X: 4194304
3075 let g:arg = "brrrr"
3076 let g:line = 8
3077 exec "source" scriptG
3078 catch /.*/
3079 Xpath 8388608 " X: 8388608
3080 let exception = v:exception
3081 let throwpoint = v:throwpoint
3082 " Resolve scriptT for matching it against v:throwpoint.
3083 call CHECK(9, "brrrr", resolve(scriptT), '\<8\>')
3084 finally
3085 Xpath 16777216 " X: 16777216
3086 let exception = v:exception
3087 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02003088 call CHECK(10, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003089 endtry
3090 Xpath 33554432 " X: 33554432
3091 let exception = v:exception
3092 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02003093 call CHECK(11, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003094 endtry
3095 Xpath 67108864 " X: 67108864
3096 let exception = v:exception
3097 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02003098 call CHECK(12, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003099 finally
3100 Xpath 134217728 " X: 134217728
3101 let exception = v:exception
3102 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02003103 call CHECK(13, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003104 endtry
3105 Xpath 268435456 " X: 268435456
3106 let exception = v:exception
3107 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02003108 call CHECK(14, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003109finally
3110 Xpath 536870912 " X: 536870912
3111 let exception = v:exception
3112 let throwpoint = v:throwpoint
3113 call CHECK(15, "", '^$', '^$')
3114endtry
3115
3116Xpath 1073741824 " X: 1073741824
3117
3118unlet exception throwpoint
3119delfunction FuncException
3120delfunction FuncThrowpoint
3121call delete(scriptException)
3122call delete(scriptThrowPoint)
3123unlet scriptException scriptThrowPoint
3124delcommand CmdException
3125delcommand CmdThrowpoint
3126delfunction T
3127delfunction G
3128delfunction F
3129call delete(scriptT)
3130call delete(scriptG)
3131call delete(scriptF)
3132unlet scriptT scriptG scriptF
3133
3134Xcheck 2147450880
3135
3136
3137"-------------------------------------------------------------------------------
3138"
3139" Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1
3140"
3141" v:exception and v:throwpoint work also for error and interrupt
3142" exceptions.
3143"-------------------------------------------------------------------------------
3144
3145XpathINIT
3146
3147if ExtraVim()
3148
3149 function! T(line)
3150 if a:line == 2
3151 delfunction T " error (function in use) in line 2
3152 elseif a:line == 4
3153 let dummy = 0 " INTERRUPT1 - interrupt in line 4
3154 endif
3155 endfunction
3156
3157 while 1
3158 try
3159 Xpath 1 " X: 1
3160 let caught = 0
3161 call T(2)
3162 catch /.*/
3163 let caught = 1
3164 if v:exception !~ 'Vim(delfunction):'
3165 Xpath 2 " X: 0
3166 endif
3167 if v:throwpoint !~ '\<T\>'
3168 Xpath 4 " X: 0
3169 endif
3170 if v:throwpoint !~ '\<2\>'
3171 Xpath 8 " X: 0
3172 endif
3173 finally
3174 Xpath 16 " X: 16
3175 if caught || $VIMNOERRTHROW
3176 Xpath 32 " X: 32
3177 endif
3178 if v:exception != ""
3179 Xpath 64 " X: 0
3180 endif
3181 if v:throwpoint != ""
3182 Xpath 128 " X: 0
3183 endif
3184 break " discard error for $VIMNOERRTHROW
3185 endtry
3186 endwhile
3187
3188 Xpath 256 " X: 256
3189 if v:exception != ""
3190 Xpath 512 " X: 0
3191 endif
3192 if v:throwpoint != ""
3193 Xpath 1024 " X: 0
3194 endif
3195
3196 while 1
3197 try
3198 Xpath 2048 " X: 2048
3199 let caught = 0
3200 call T(4)
3201 catch /.*/
3202 let caught = 1
3203 if v:exception != 'Vim:Interrupt'
3204 Xpath 4096 " X: 0
3205 endif
3206 if v:throwpoint !~ '\<T\>'
3207 Xpath 8192 " X: 0
3208 endif
3209 if v:throwpoint !~ '\<4\>'
3210 Xpath 16384 " X: 0
3211 endif
3212 finally
3213 Xpath 32768 " X: 32768
3214 if caught || $VIMNOINTTHROW
3215 Xpath 65536 " X: 65536
3216 endif
3217 if v:exception != ""
3218 Xpath 131072 " X: 0
3219 endif
3220 if v:throwpoint != ""
3221 Xpath 262144 " X: 0
3222 endif
3223 break " discard error for $VIMNOERRTHROW
3224 endtry
3225 endwhile
3226
3227 Xpath 524288 " X: 524288
3228 if v:exception != ""
3229 Xpath 1048576 " X: 0
3230 endif
3231 if v:throwpoint != ""
3232 Xpath 2097152 " X: 0
3233 endif
3234
3235endif
3236
3237Xcheck 624945
3238
3239
3240"-------------------------------------------------------------------------------
3241"
3242" Test 59: v:exception and v:throwpoint when discarding exceptions {{{1
3243"
3244" When a :catch clause is left by a ":break" etc or an error or
3245" interrupt exception, v:exception and v:throwpoint are reset. They
3246" are not affected by an exception that is discarded before being
3247" caught.
3248"-------------------------------------------------------------------------------
3249
3250XpathINIT
3251
3252if ExtraVim()
3253
3254 XloopINIT! 1 2
3255
3256 let sfile = expand("<sfile>")
3257
3258 function! LineNumber()
3259 return substitute(substitute(v:throwpoint, g:sfile, '', ""),
3260 \ '\D*\(\d*\).*', '\1', "")
3261 endfunction
3262
3263 command! -nargs=1 SetLineNumber
3264 \ try | throw "line" | catch /.*/ | let <args> = LineNumber() | endtry
3265
3266 " Check v:exception/v:throwpoint against second/fourth parameter if
3267 " specified, check for being empty else.
3268 function! CHECK(n, ...)
3269 XloopNEXT
3270 let exception = a:0 != 0 ? a:1 : "" " second parameter (optional)
3271 let emsg = a:0 != 0 ? a:2 : "" " third parameter (optional)
3272 let line = a:0 != 0 ? a:3 : 0 " fourth parameter (optional)
3273 let error = 0
3274 if emsg != ""
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003275 " exception is the error number, emsg the English error message text
Bram Moolenaar071d4272004-06-13 20:20:40 +00003276 if exception !~ '^E\d\+$'
3277 Xout "TODO: Add message number for:" emsg
3278 elseif v:lang == "C" || v:lang =~ '^[Ee]n'
3279 if exception == "E492" && emsg == "Not an editor command"
3280 let exception = '^Vim:' . exception . ': ' . emsg
3281 else
3282 let exception = '^Vim(\a\+):' . exception . ': ' . emsg
3283 endif
3284 else
3285 if exception == "E492"
3286 let exception = '^Vim:' . exception
3287 else
3288 let exception = '^Vim(\a\+):' . exception
3289 endif
3290 endif
3291 endif
3292 if exception == "" && v:exception != ""
3293 Xout a:n.": v:exception is set:" v:exception
3294 let error = 1
3295 elseif exception != "" && v:exception !~ exception
3296 Xout a:n.": v:exception (".v:exception.") does not match" exception
3297 let error = 1
3298 endif
3299 if line == 0 && v:throwpoint != ""
3300 Xout a:n.": v:throwpoint is set:" v:throwpoint
3301 let error = 1
3302 elseif line != 0 && v:throwpoint !~ '\<' . line . '\>'
3303 Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
3304 let error = 1
3305 endif
3306 if !error
3307 Xloop 1 " X: 2097151
3308 endif
3309 endfunction
3310
3311 while 1
3312 try
3313 throw "x1"
3314 catch /.*/
3315 break
3316 endtry
3317 endwhile
3318 call CHECK(1)
3319
3320 while 1
3321 try
3322 throw "x2"
3323 catch /.*/
3324 break
3325 finally
3326 call CHECK(2)
3327 endtry
3328 break
3329 endwhile
3330 call CHECK(3)
3331
3332 while 1
3333 try
3334 let errcaught = 0
3335 try
3336 try
3337 throw "x3"
3338 catch /.*/
3339 SetLineNumber line_before_error
3340 asdf
3341 endtry
3342 catch /.*/
3343 let errcaught = 1
3344 call CHECK(4, 'E492', "Not an editor command",
3345 \ line_before_error + 1)
3346 endtry
3347 finally
3348 if !errcaught && $VIMNOERRTHROW
3349 call CHECK(4)
3350 endif
3351 break " discard error for $VIMNOERRTHROW
3352 endtry
3353 endwhile
3354 call CHECK(5)
3355
3356 Xpath 2097152 " X: 2097152
3357
3358 while 1
3359 try
3360 let intcaught = 0
3361 try
3362 try
3363 throw "x4"
3364 catch /.*/
3365 SetLineNumber two_lines_before_interrupt
3366 "INTERRUPT
3367 let dummy = 0
3368 endtry
3369 catch /.*/
3370 let intcaught = 1
3371 call CHECK(6, "Vim:Interrupt", '',
3372 \ two_lines_before_interrupt + 2)
3373 endtry
3374 finally
3375 if !intcaught && $VIMNOINTTHROW
3376 call CHECK(6)
3377 endif
3378 break " discard interrupt for $VIMNOINTTHROW
3379 endtry
3380 endwhile
3381 call CHECK(7)
3382
3383 Xpath 4194304 " X: 4194304
3384
3385 while 1
3386 try
3387 let errcaught = 0
3388 try
3389 try
3390" if 1
3391 SetLineNumber line_before_throw
3392 throw "x5"
3393 " missing endif
3394 catch /.*/
3395 Xpath 8388608 " X: 0
3396 endtry
3397 catch /.*/
3398 let errcaught = 1
3399 call CHECK(8, 'E171', "Missing :endif", line_before_throw + 3)
3400 endtry
3401 finally
3402 if !errcaught && $VIMNOERRTHROW
3403 call CHECK(8)
3404 endif
3405 break " discard error for $VIMNOERRTHROW
3406 endtry
3407 endwhile
3408 call CHECK(9)
3409
3410 Xpath 16777216 " X: 16777216
3411
3412 try
3413 while 1
3414 try
3415 throw "x6"
3416 finally
3417 break
3418 endtry
3419 break
3420 endwhile
3421 catch /.*/
3422 Xpath 33554432 " X: 0
3423 endtry
3424 call CHECK(10)
3425
3426 try
3427 while 1
3428 try
3429 throw "x7"
3430 finally
3431 break
3432 endtry
3433 break
3434 endwhile
3435 catch /.*/
3436 Xpath 67108864 " X: 0
3437 finally
3438 call CHECK(11)
3439 endtry
3440 call CHECK(12)
3441
3442 while 1
3443 try
3444 let errcaught = 0
3445 try
3446 try
3447 throw "x8"
3448 finally
3449 SetLineNumber line_before_error
3450 asdf
3451 endtry
3452 catch /.*/
3453 let errcaught = 1
3454 call CHECK(13, 'E492', "Not an editor command",
3455 \ line_before_error + 1)
3456 endtry
3457 finally
3458 if !errcaught && $VIMNOERRTHROW
3459 call CHECK(13)
3460 endif
3461 break " discard error for $VIMNOERRTHROW
3462 endtry
3463 endwhile
3464 call CHECK(14)
3465
3466 Xpath 134217728 " X: 134217728
3467
3468 while 1
3469 try
3470 let intcaught = 0
3471 try
3472 try
3473 throw "x9"
3474 finally
3475 SetLineNumber two_lines_before_interrupt
3476 "INTERRUPT
3477 endtry
3478 catch /.*/
3479 let intcaught = 1
3480 call CHECK(15, "Vim:Interrupt", '',
3481 \ two_lines_before_interrupt + 2)
3482 endtry
3483 finally
3484 if !intcaught && $VIMNOINTTHROW
3485 call CHECK(15)
3486 endif
3487 break " discard interrupt for $VIMNOINTTHROW
3488 endtry
3489 endwhile
3490 call CHECK(16)
3491
3492 Xpath 268435456 " X: 268435456
3493
3494 while 1
3495 try
3496 let errcaught = 0
3497 try
3498 try
3499" if 1
3500 SetLineNumber line_before_throw
3501 throw "x10"
3502 " missing endif
3503 finally
3504 call CHECK(17)
3505 endtry
3506 catch /.*/
3507 let errcaught = 1
3508 call CHECK(18, 'E171', "Missing :endif", line_before_throw + 3)
3509 endtry
3510 finally
3511 if !errcaught && $VIMNOERRTHROW
3512 call CHECK(18)
3513 endif
3514 break " discard error for $VIMNOERRTHROW
3515 endtry
3516 endwhile
3517 call CHECK(19)
3518
3519 Xpath 536870912 " X: 536870912
3520
3521 while 1
3522 try
3523 let errcaught = 0
3524 try
3525 try
3526" if 1
3527 SetLineNumber line_before_throw
3528 throw "x11"
3529 " missing endif
3530 endtry
3531 catch /.*/
3532 let errcaught = 1
3533 call CHECK(20, 'E171', "Missing :endif", line_before_throw + 3)
3534 endtry
3535 finally
3536 if !errcaught && $VIMNOERRTHROW
3537 call CHECK(20)
3538 endif
3539 break " discard error for $VIMNOERRTHROW
3540 endtry
3541 endwhile
3542 call CHECK(21)
3543
3544 Xpath 1073741824 " X: 1073741824
3545
3546endif
3547
3548Xcheck 2038431743
3549
3550
3551"-------------------------------------------------------------------------------
3552"
3553" Test 60: (Re)throwing v:exception; :echoerr. {{{1
3554"
3555" A user exception can be rethrown after catching by throwing
3556" v:exception. An error or interrupt exception cannot be rethrown
3557" because Vim exceptions cannot be faked. A Vim exception using the
3558" value of v:exception can, however, be triggered by the :echoerr
3559" command.
3560"-------------------------------------------------------------------------------
3561
3562XpathINIT
3563
3564try
3565 try
3566 Xpath 1 " X: 1
3567 throw "oops"
3568 catch /oops/
3569 Xpath 2 " X: 2
3570 throw v:exception " rethrow user exception
3571 catch /.*/
3572 Xpath 4 " X: 0
3573 endtry
3574catch /^oops$/ " catches rethrown user exception
3575 Xpath 8 " X: 8
3576catch /.*/
3577 Xpath 16 " X: 0
3578endtry
3579
3580function! F()
3581 try
3582 let caught = 0
3583 try
3584 Xpath 32 " X: 32
3585 write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e
3586 Xpath 64 " X: 0
3587 Xout "did_emsg was reset before executing " .
3588 \ "BufWritePost autocommands."
3589 catch /^Vim(write):/
3590 let caught = 1
3591 throw v:exception " throw error: cannot fake Vim exception
3592 catch /.*/
3593 Xpath 128 " X: 0
3594 finally
3595 Xpath 256 " X: 256
3596 if !caught && !$VIMNOERRTHROW
3597 Xpath 512 " X: 0
3598 endif
3599 endtry
3600 catch /^Vim(throw):/ " catches throw error
3601 let caught = caught + 1
3602 catch /.*/
3603 Xpath 1024 " X: 0
3604 finally
3605 Xpath 2048 " X: 2048
3606 if caught != 2
3607 if !caught && !$VIMNOERRTHROW
3608 Xpath 4096 " X: 0
3609 elseif caught
3610 Xpath 8192 " X: 0
3611 endif
3612 return | " discard error for $VIMNOERRTHROW
3613 endif
3614 endtry
3615endfunction
3616
3617call F()
3618delfunction F
3619
3620function! G()
3621 try
3622 let caught = 0
3623 try
3624 Xpath 16384 " X: 16384
3625 asdf
3626 catch /^Vim/ " catch error exception
3627 let caught = 1
3628 " Trigger Vim error exception with value specified after :echoerr
3629 let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
3630 echoerr value
3631 catch /.*/
3632 Xpath 32768 " X: 0
3633 finally
3634 Xpath 65536 " X: 65536
3635 if !caught
3636 if !$VIMNOERRTHROW
3637 Xpath 131072 " X: 0
3638 else
3639 let value = "Error"
3640 echoerr value
3641 endif
3642 endif
3643 endtry
3644 catch /^Vim(echoerr):/
3645 let caught = caught + 1
3646 if v:exception !~ value
3647 Xpath 262144 " X: 0
3648 endif
3649 catch /.*/
3650 Xpath 524288 " X: 0
3651 finally
3652 Xpath 1048576 " X: 1048576
3653 if caught != 2
3654 if !caught && !$VIMNOERRTHROW
3655 Xpath 2097152 " X: 0
3656 elseif caught
3657 Xpath 4194304 " X: 0
3658 endif
3659 return | " discard error for $VIMNOERRTHROW
3660 endif
3661 endtry
3662endfunction
3663
3664call G()
3665delfunction G
3666
3667unlet! value caught
3668
3669if ExtraVim()
3670 try
3671 let errcaught = 0
3672 try
3673 Xpath 8388608 " X: 8388608
3674 let intcaught = 0
3675 "INTERRUPT
3676 catch /^Vim:/ " catch interrupt exception
3677 let intcaught = 1
3678 " Trigger Vim error exception with value specified after :echoerr
3679 echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
3680 catch /.*/
3681 Xpath 16777216 " X: 0
3682 finally
3683 Xpath 33554432 " X: 33554432
3684 if !intcaught
3685 if !$VIMNOINTTHROW
3686 Xpath 67108864 " X: 0
3687 else
3688 echoerr "Interrupt"
3689 endif
3690 endif
3691 endtry
3692 catch /^Vim(echoerr):/
3693 let errcaught = 1
3694 if v:exception !~ "Interrupt"
3695 Xpath 134217728 " X: 0
3696 endif
3697 finally
3698 Xpath 268435456 " X: 268435456
3699 if !errcaught && !$VIMNOERRTHROW
3700 Xpath 536870912 " X: 0
3701 endif
3702 endtry
3703endif
3704
3705Xcheck 311511339
3706
3707
3708"-------------------------------------------------------------------------------
3709" Test 61: Catching interrupt exceptions {{{1
3710"
3711" When an interrupt occurs inside a :try/:endtry region, an
3712" interrupt exception is thrown and can be caught. Its value is
3713" "Vim:Interrupt". If the interrupt occurs after an error or a :throw
3714" but before a matching :catch is reached, all following :catches of
3715" that try block are ignored, but the interrupt exception can be
3716" caught by the next surrounding try conditional. An interrupt is
3717" ignored when there is a previous interrupt that has not been caught
3718" or causes a :finally clause to be executed.
3719"-------------------------------------------------------------------------------
3720
3721XpathINIT
3722
3723if ExtraVim()
3724
3725 while 1
3726 try
3727 try
3728 Xpath 1 " X: 1
3729 let caught = 0
3730 "INTERRUPT
3731 Xpath 2 " X: 0
3732 catch /^Vim:Interrupt$/
3733 let caught = 1
3734 finally
3735 Xpath 4 " X: 4
3736 if caught || $VIMNOINTTHROW
3737 Xpath 8 " X: 8
3738 endif
3739 endtry
3740 catch /.*/
3741 Xpath 16 " X: 0
3742 Xout v:exception "in" v:throwpoint
3743 finally
3744 break " discard interrupt for $VIMNOINTTHROW
3745 endtry
3746 endwhile
3747
3748 while 1
3749 try
3750 try
3751 let caught = 0
3752 try
3753 Xpath 32 " X: 32
3754 asdf
3755 Xpath 64 " X: 0
3756 catch /do_not_catch/
3757 Xpath 128 " X: 0
3758 catch /.*/ "INTERRUPT - throw interrupt if !$VIMNOERRTHROW
3759 Xpath 256 " X: 0
3760 catch /.*/
3761 Xpath 512 " X: 0
3762 finally "INTERRUPT - throw interrupt if $VIMNOERRTHROW
3763 Xpath 1024 " X: 1024
3764 endtry
3765 catch /^Vim:Interrupt$/
3766 let caught = 1
3767 finally
3768 Xpath 2048 " X: 2048
3769 if caught || $VIMNOINTTHROW
3770 Xpath 4096 " X: 4096
3771 endif
3772 endtry
3773 catch /.*/
3774 Xpath 8192 " X: 0
3775 Xout v:exception "in" v:throwpoint
3776 finally
3777 break " discard interrupt for $VIMNOINTTHROW
3778 endtry
3779 endwhile
3780
3781 while 1
3782 try
3783 try
3784 let caught = 0
3785 try
3786 Xpath 16384 " X: 16384
3787 throw "x"
3788 Xpath 32768 " X: 0
3789 catch /do_not_catch/
3790 Xpath 65536 " X: 0
3791 catch /x/ "INTERRUPT
3792 Xpath 131072 " X: 0
3793 catch /.*/
3794 Xpath 262144 " X: 0
3795 endtry
3796 catch /^Vim:Interrupt$/
3797 let caught = 1
3798 finally
3799 Xpath 524288 " X: 524288
3800 if caught || $VIMNOINTTHROW
3801 Xpath 1048576 " X: 1048576
3802 endif
3803 endtry
3804 catch /.*/
3805 Xpath 2097152 " X: 0
3806 Xout v:exception "in" v:throwpoint
3807 finally
3808 break " discard interrupt for $VIMNOINTTHROW
3809 endtry
3810 endwhile
3811
3812 while 1
3813 try
3814 let caught = 0
3815 try
3816 Xpath 4194304 " X: 4194304
3817 "INTERRUPT
3818 Xpath 8388608 " X: 0
3819 catch /do_not_catch/ "INTERRUPT
3820 Xpath 16777216 " X: 0
3821 catch /^Vim:Interrupt$/
3822 let caught = 1
3823 finally
3824 Xpath 33554432 " X: 33554432
3825 if caught || $VIMNOINTTHROW
3826 Xpath 67108864 " X: 67108864
3827 endif
3828 endtry
3829 catch /.*/
3830 Xpath 134217728 " X: 0
3831 Xout v:exception "in" v:throwpoint
3832 finally
3833 break " discard interrupt for $VIMNOINTTHROW
3834 endtry
3835 endwhile
3836
3837 Xpath 268435456 " X: 268435456
3838
3839endif
3840
3841Xcheck 374889517
3842
3843
3844"-------------------------------------------------------------------------------
3845" Test 62: Catching error exceptions {{{1
3846"
3847" An error inside a :try/:endtry region is converted to an exception
3848" and can be caught. The error exception has a "Vim(cmdname):" prefix
3849" where cmdname is the name of the failing command, or a "Vim:" prefix
3850" if no command name is known. The "Vim" prefixes cannot be faked.
3851"-------------------------------------------------------------------------------
3852
3853XpathINIT
3854
3855function! MSG(enr, emsg)
3856 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
3857 if a:enr == ""
3858 Xout "TODO: Add message number for:" a:emsg
3859 let v:errmsg = ":" . v:errmsg
3860 endif
3861 let match = 1
3862 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
3863 let match = 0
3864 if v:errmsg == ""
3865 Xout "Message missing."
3866 else
3867 let v:errmsg = escape(v:errmsg, '"')
3868 Xout "Unexpected message:" v:errmsg
3869 endif
3870 endif
3871 return match
3872endfunction
3873
3874while 1
3875 try
3876 try
3877 let caught = 0
3878 unlet novar
3879 catch /^Vim(unlet):/
3880 let caught = 1
3881 let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "")
3882 finally
3883 Xpath 1 " X: 1
3884 if !caught && !$VIMNOERRTHROW
3885 Xpath 2 " X: 0
3886 endif
3887 if !MSG('E108', "No such variable")
3888 Xpath 4 " X: 0
3889 endif
3890 endtry
3891 catch /.*/
3892 Xpath 8 " X: 0
3893 Xout v:exception "in" v:throwpoint
3894 finally
3895 break " discard error for $VIMNOERRTHROW
3896 endtry
3897endwhile
3898
3899while 1
3900 try
3901 try
3902 let caught = 0
3903 throw novar " error in :throw
3904 catch /^Vim(throw):/
3905 let caught = 1
3906 let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
3907 finally
3908 Xpath 16 " X: 16
3909 if !caught && !$VIMNOERRTHROW
3910 Xpath 32 " X: 0
3911 endif
3912 if caught ? !MSG('E121', "Undefined variable")
3913 \ : !MSG('E15', "Invalid expression")
3914 Xpath 64 " X: 0
3915 endif
3916 endtry
3917 catch /.*/
3918 Xpath 128 " X: 0
3919 Xout v:exception "in" v:throwpoint
3920 finally
3921 break " discard error for $VIMNOERRTHROW
3922 endtry
3923endwhile
3924
3925while 1
3926 try
3927 try
3928 let caught = 0
3929 throw "Vim:faked" " error: cannot fake Vim exception
3930 catch /^Vim(throw):/
3931 let caught = 1
3932 let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
3933 finally
3934 Xpath 256 " X: 256
3935 if !caught && !$VIMNOERRTHROW
3936 Xpath 512 " X: 0
3937 endif
3938 if !MSG('E608', "Cannot :throw exceptions with 'Vim' prefix")
3939 Xpath 1024 " X: 0
3940 endif
3941 endtry
3942 catch /.*/
3943 Xpath 2048 " X: 0
3944 Xout v:exception "in" v:throwpoint
3945 finally
3946 break " discard error for $VIMNOERRTHROW
3947 endtry
3948endwhile
3949
3950function! F()
3951 while 1
3952 " Missing :endwhile
3953endfunction
3954
3955while 1
3956 try
3957 try
3958 let caught = 0
3959 call F()
3960 catch /^Vim(endfunction):/
3961 let caught = 1
3962 let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "")
3963 finally
3964 Xpath 4096 " X: 4096
3965 if !caught && !$VIMNOERRTHROW
3966 Xpath 8192 " X: 0
3967 endif
3968 if !MSG('E170', "Missing :endwhile")
3969 Xpath 16384 " X: 0
3970 endif
3971 endtry
3972 catch /.*/
3973 Xpath 32768 " X: 0
3974 Xout v:exception "in" v:throwpoint
3975 finally
3976 break " discard error for $VIMNOERRTHROW
3977 endtry
3978endwhile
3979
3980while 1
3981 try
3982 try
3983 let caught = 0
3984 ExecAsScript F
3985 catch /^Vim:/
3986 let caught = 1
3987 let v:errmsg = substitute(v:exception, '^Vim:', '', "")
3988 finally
3989 Xpath 65536 " X: 65536
3990 if !caught && !$VIMNOERRTHROW
3991 Xpath 131072 " X: 0
3992 endif
3993 if !MSG('E170', "Missing :endwhile")
3994 Xpath 262144 " X: 0
3995 endif
3996 endtry
3997 catch /.*/
3998 Xpath 524288 " X: 0
3999 Xout v:exception "in" v:throwpoint
4000 finally
4001 break " discard error for $VIMNOERRTHROW
4002 endtry
4003endwhile
4004
4005function! G()
4006 call G()
4007endfunction
4008
4009while 1
4010 try
4011 let mfd_save = &mfd
4012 set mfd=3
4013 try
4014 let caught = 0
4015 call G()
4016 catch /^Vim(call):/
4017 let caught = 1
4018 let v:errmsg = substitute(v:exception, '^Vim(call):', '', "")
4019 finally
4020 Xpath 1048576 " X: 1048576
4021 if !caught && !$VIMNOERRTHROW
4022 Xpath 2097152 " X: 0
4023 endif
4024 if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
4025 Xpath 4194304 " X: 0
4026 endif
4027 endtry
4028 catch /.*/
4029 Xpath 8388608 " X: 0
4030 Xout v:exception "in" v:throwpoint
4031 finally
4032 let &mfd = mfd_save
4033 break " discard error for $VIMNOERRTHROW
4034 endtry
4035endwhile
4036
4037function! H()
4038 return H()
4039endfunction
4040
4041while 1
4042 try
4043 let mfd_save = &mfd
4044 set mfd=3
4045 try
4046 let caught = 0
4047 call H()
4048 catch /^Vim(return):/
4049 let caught = 1
4050 let v:errmsg = substitute(v:exception, '^Vim(return):', '', "")
4051 finally
4052 Xpath 16777216 " X: 16777216
4053 if !caught && !$VIMNOERRTHROW
4054 Xpath 33554432 " X: 0
4055 endif
4056 if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
4057 Xpath 67108864 " X: 0
4058 endif
4059 endtry
4060 catch /.*/
4061 Xpath 134217728 " X: 0
4062 Xout v:exception "in" v:throwpoint
4063 finally
4064 let &mfd = mfd_save
4065 break " discard error for $VIMNOERRTHROW
4066 endtry
4067endwhile
4068
4069unlet! caught mfd_save
4070delfunction F
4071delfunction G
4072delfunction H
4073Xpath 268435456 " X: 268435456
4074
4075Xcheck 286331153
4076
4077" Leave MSG() for the next test.
4078
4079
4080"-------------------------------------------------------------------------------
4081" Test 63: Suppressing error exceptions by :silent!. {{{1
4082"
4083" A :silent! command inside a :try/:endtry region suppresses the
4084" conversion of errors to an exception and the immediate abortion on
4085" error. When the commands executed by the :silent! themselves open
4086" a new :try/:endtry region, conversion of errors to exception and
4087" immediate abortion is switched on again - until the next :silent!
4088" etc. The :silent! has the effect of setting v:errmsg to the error
4089" message text (without displaying it) and continuing with the next
4090" script line.
4091"
4092" When a command triggering autocommands is executed by :silent!
4093" inside a :try/:endtry, the autocommand execution is not suppressed
4094" on error.
4095"
4096" This test reuses the function MSG() from the previous test.
4097"-------------------------------------------------------------------------------
4098
4099XpathINIT
4100
4101XloopINIT! 1 4
4102
4103let taken = ""
4104
4105function! S(n) abort
4106 XloopNEXT
4107 let g:taken = g:taken . "E" . a:n
4108 let v:errmsg = ""
4109 exec "asdf" . a:n
4110
4111 " Check that ":silent!" continues:
4112 Xloop 1
4113
4114 " Check that ":silent!" sets "v:errmsg":
4115 if MSG('E492', "Not an editor command")
4116 Xloop 2
4117 endif
4118endfunction
4119
4120function! Foo()
4121 while 1
4122 try
4123 try
4124 let caught = 0
4125 " This is not silent:
4126 call S(3) " X: 0 * 16
4127 catch /^Vim:/
4128 let caught = 1
4129 let errmsg3 = substitute(v:exception, '^Vim:', '', "")
4130 silent! call S(4) " X: 3 * 64
4131 finally
4132 if !caught
4133 let errmsg3 = v:errmsg
4134 " Do call S(4) here if not executed in :catch.
4135 silent! call S(4)
4136 endif
4137 Xpath 1048576 " X: 1048576
4138 if !caught && !$VIMNOERRTHROW
4139 Xpath 2097152 " X: 0
4140 endif
4141 let v:errmsg = errmsg3
4142 if !MSG('E492', "Not an editor command")
4143 Xpath 4194304 " X: 0
4144 endif
4145 silent! call S(5) " X: 3 * 256
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004146 " Break out of try conditionals that cover ":silent!". This also
Bram Moolenaar071d4272004-06-13 20:20:40 +00004147 " discards the aborting error when $VIMNOERRTHROW is non-zero.
4148 break
4149 endtry
4150 catch /.*/
4151 Xpath 8388608 " X: 0
4152 Xout v:exception "in" v:throwpoint
4153 endtry
4154 endwhile
4155 " This is a double ":silent!" (see caller).
4156 silent! call S(6) " X: 3 * 1024
4157endfunction
4158
4159function! Bar()
4160 try
4161 silent! call S(2) " X: 3 * 4
4162 " X: 3 * 4096
4163 silent! execute "call Foo() | call S(7)"
4164 silent! call S(8) " X: 3 * 16384
4165 endtry " normal end of try cond that covers ":silent!"
4166 " This has a ":silent!" from the caller:
4167 call S(9) " X: 3 * 65536
4168endfunction
4169
4170silent! call S(1) " X: 3 * 1
4171silent! call Bar()
4172silent! call S(10) " X: 3 * 262144
4173
4174let expected = "E1E2E3E4E5E6E7E8E9E10"
4175if taken != expected
4176 Xpath 16777216 " X: 0
4177 Xout "'taken' is" taken "instead of" expected
4178endif
4179
4180augroup TMP
4181 autocmd BufWritePost * Xpath 33554432 " X: 33554432
4182augroup END
4183
4184Xpath 67108864 " X: 67108864
4185write /i/m/p/o/s/s/i/b/l/e
4186Xpath 134217728 " X: 134217728
4187
4188autocmd! TMP
4189unlet! caught errmsg3 taken expected
4190delfunction S
4191delfunction Foo
4192delfunction Bar
4193delfunction MSG
4194
4195Xcheck 236978127
4196
4197
4198"-------------------------------------------------------------------------------
4199" Test 64: Error exceptions after error, interrupt or :throw {{{1
4200"
4201" When an error occurs after an interrupt or a :throw but before
4202" a matching :catch is reached, all following :catches of that try
4203" block are ignored, but the error exception can be caught by the next
4204" surrounding try conditional. Any previous error exception is
4205" discarded. An error is ignored when there is a previous error that
4206" has not been caught.
4207"-------------------------------------------------------------------------------
4208
4209XpathINIT
4210
4211if ExtraVim()
4212
4213 while 1
4214 try
4215 try
4216 Xpath 1 " X: 1
4217 let caught = 0
4218 while 1
4219" if 1
4220 " Missing :endif
4221 endwhile " throw error exception
4222 catch /^Vim(/
4223 let caught = 1
4224 finally
4225 Xpath 2 " X: 2
4226 if caught || $VIMNOERRTHROW
4227 Xpath 4 " X: 4
4228 endif
4229 endtry
4230 catch /.*/
4231 Xpath 8 " X: 0
4232 Xout v:exception "in" v:throwpoint
4233 finally
4234 break " discard error for $VIMNOERRTHROW
4235 endtry
4236 endwhile
4237
4238 while 1
4239 try
4240 try
4241 Xpath 16 " X: 16
4242 let caught = 0
4243 try
4244" if 1
4245 " Missing :endif
4246 catch /.*/ " throw error exception
4247 Xpath 32 " X: 0
4248 catch /.*/
4249 Xpath 64 " X: 0
4250 endtry
4251 catch /^Vim(/
4252 let caught = 1
4253 finally
4254 Xpath 128 " X: 128
4255 if caught || $VIMNOERRTHROW
4256 Xpath 256 " X: 256
4257 endif
4258 endtry
4259 catch /.*/
4260 Xpath 512 " X: 0
4261 Xout v:exception "in" v:throwpoint
4262 finally
4263 break " discard error for $VIMNOERRTHROW
4264 endtry
4265 endwhile
4266
4267 while 1
4268 try
4269 try
4270 let caught = 0
4271 try
4272 Xpath 1024 " X: 1024
4273 "INTERRUPT
4274 catch /do_not_catch/
4275 Xpath 2048 " X: 0
4276" if 1
4277 " Missing :endif
4278 catch /.*/ " throw error exception
4279 Xpath 4096 " X: 0
4280 catch /.*/
4281 Xpath 8192 " X: 0
4282 endtry
4283 catch /^Vim(/
4284 let caught = 1
4285 finally
4286 Xpath 16384 " X: 16384
4287 if caught || $VIMNOERRTHROW
4288 Xpath 32768 " X: 32768
4289 endif
4290 endtry
4291 catch /.*/
4292 Xpath 65536 " X: 0
4293 Xout v:exception "in" v:throwpoint
4294 finally
4295 break " discard error for $VIMNOERRTHROW
4296 endtry
4297 endwhile
4298
4299 while 1
4300 try
4301 try
4302 let caught = 0
4303 try
4304 Xpath 131072 " X: 131072
4305 throw "x"
4306 catch /do_not_catch/
4307 Xpath 262144 " X: 0
4308" if 1
4309 " Missing :endif
4310 catch /x/ " throw error exception
4311 Xpath 524288 " X: 0
4312 catch /.*/
4313 Xpath 1048576 " X: 0
4314 endtry
4315 catch /^Vim(/
4316 let caught = 1
4317 finally
4318 Xpath 2097152 " X: 2097152
4319 if caught || $VIMNOERRTHROW
4320 Xpath 4194304 " X: 4194304
4321 endif
4322 endtry
4323 catch /.*/
4324 Xpath 8388608 " X: 0
4325 Xout v:exception "in" v:throwpoint
4326 finally
4327 break " discard error for $VIMNOERRTHROW
4328 endtry
4329 endwhile
4330
4331 while 1
4332 try
4333 try
4334 let caught = 0
4335 Xpath 16777216 " X: 16777216
4336" endif " :endif without :if; throw error exception
4337" if 1
4338 " Missing :endif
4339 catch /do_not_catch/ " ignore new error
4340 Xpath 33554432 " X: 0
4341 catch /^Vim(endif):/
4342 let caught = 1
4343 catch /^Vim(/
4344 Xpath 67108864 " X: 0
4345 finally
4346 Xpath 134217728 " X: 134217728
4347 if caught || $VIMNOERRTHROW
4348 Xpath 268435456 " X: 268435456
4349 endif
4350 endtry
4351 catch /.*/
4352 Xpath 536870912 " X: 0
4353 Xout v:exception "in" v:throwpoint
4354 finally
4355 break " discard error for $VIMNOERRTHROW
4356 endtry
4357 endwhile
4358
4359 Xpath 1073741824 " X: 1073741824
4360
4361endif
4362
4363Xcheck 1499645335
4364
4365
4366"-------------------------------------------------------------------------------
4367" Test 65: Errors in the /pattern/ argument of a :catch {{{1
4368"
4369" On an error in the /pattern/ argument of a :catch, the :catch does
4370" not match. Any following :catches of the same :try/:endtry don't
4371" match either. Finally clauses are executed.
4372"-------------------------------------------------------------------------------
4373
4374XpathINIT
4375
4376function! MSG(enr, emsg)
4377 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
4378 if a:enr == ""
4379 Xout "TODO: Add message number for:" a:emsg
4380 let v:errmsg = ":" . v:errmsg
4381 endif
4382 let match = 1
4383 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
4384 let match = 0
4385 if v:errmsg == ""
4386 Xout "Message missing."
4387 else
4388 let v:errmsg = escape(v:errmsg, '"')
4389 Xout "Unexpected message:" v:errmsg
4390 endif
4391 endif
4392 return match
4393endfunction
4394
4395try
4396 try
4397 Xpath 1 " X: 1
4398 throw "oops"
4399 catch /^oops$/
4400 Xpath 2 " X: 2
4401 catch /\)/ " not checked; exception has already been caught
4402 Xpath 4 " X: 0
4403 endtry
4404 Xpath 8 " X: 8
4405catch /.*/
4406 Xpath 16 " X: 0
4407 Xout v:exception "in" v:throwpoint
4408endtry
4409
4410function! F()
4411 try
4412 let caught = 0
4413 try
4414 try
4415 Xpath 32 " X: 32
4416 throw "ab"
4417 catch /abc/ " does not catch
4418 Xpath 64 " X: 0
4419 catch /\)/ " error; discards exception
4420 Xpath 128 " X: 0
4421 catch /.*/ " not checked
4422 Xpath 256 " X: 0
4423 finally
4424 Xpath 512 " X: 512
4425 endtry
4426 Xpath 1024 " X: 0
4427 catch /^ab$/ " checked, but original exception is discarded
4428 Xpath 2048 " X: 0
4429 catch /^Vim(catch):/
4430 let caught = 1
4431 let v:errmsg = substitute(v:exception, '^Vim(catch):', '', "")
4432 finally
4433 Xpath 4096 " X: 4096
4434 if !caught && !$VIMNOERRTHROW
4435 Xpath 8192 " X: 0
4436 endif
Bram Moolenaardc94a262016-02-07 20:29:00 +01004437 if !MSG('E475', "Invalid argument")
Bram Moolenaar071d4272004-06-13 20:20:40 +00004438 Xpath 16384 " X: 0
4439 endif
4440 if !caught
4441 return | " discard error
4442 endif
4443 endtry
4444 catch /.*/
4445 Xpath 32768 " X: 0
4446 Xout v:exception "in" v:throwpoint
4447 endtry
4448endfunction
4449
4450call F()
4451Xpath 65536 " X: 65536
4452
4453delfunction MSG
4454delfunction F
4455unlet! caught
4456
4457Xcheck 70187
4458
4459
4460"-------------------------------------------------------------------------------
4461" Test 66: Stop range :call on error, interrupt, or :throw {{{1
4462"
4463" When a function which is multiply called for a range since it
4464" doesn't handle the range itself has an error in a command
4465" dynamically enclosed by :try/:endtry or gets an interrupt or
4466" executes a :throw, no more calls for the remaining lines in the
4467" range are made. On an error in a command not dynamically enclosed
4468" by :try/:endtry, the function is executed again for the remaining
4469" lines in the range.
4470"-------------------------------------------------------------------------------
4471
4472XpathINIT
4473
4474if ExtraVim()
4475
4476 let file = tempname()
4477 exec "edit" file
4478
4479 insert
4480line 1
4481line 2
4482line 3
4483.
4484
4485 XloopINIT! 1 2
4486
4487 let taken = ""
4488 let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)"
4489
4490 function! F(reason, n) abort
4491 let g:taken = g:taken . "F" . a:n .
4492 \ substitute(a:reason, '\(\l\).*', '\u\1', "") .
4493 \ "(" . line(".") . ")"
4494
4495 if a:reason == "error"
4496 asdf
4497 elseif a:reason == "interrupt"
4498 "INTERRUPT
4499 let dummy = 0
4500 elseif a:reason == "throw"
4501 throw "xyz"
4502 elseif a:reason == "aborting error"
4503 XloopNEXT
4504 if g:taken != g:expected
4505 Xloop 1 " X: 0
4506 Xout "'taken' is" g:taken "instead of" g:expected
4507 endif
4508 try
4509 bwipeout!
4510 call delete(file)
4511 asdf
4512 endtry
4513 endif
4514 endfunction
4515
4516 function! G(reason, n)
4517 let g:taken = g:taken . "G" . a:n .
4518 \ substitute(a:reason, '\(\l\).*', '\u\1', "")
4519 1,3call F(a:reason, a:n)
4520 endfunction
4521
4522 Xpath 8 " X: 8
4523 call G("error", 1)
4524 try
4525 Xpath 16 " X: 16
4526 try
4527 call G("error", 2)
4528 Xpath 32 " X: 0
4529 finally
4530 Xpath 64 " X: 64
4531 try
4532 call G("interrupt", 3)
4533 Xpath 128 " X: 0
4534 finally
4535 Xpath 256 " X: 256
4536 try
4537 call G("throw", 4)
4538 Xpath 512 " X: 0
4539 endtry
4540 endtry
4541 endtry
4542 catch /xyz/
4543 Xpath 1024 " X: 1024
4544 catch /.*/
4545 Xpath 2048 " X: 0
4546 Xout v:exception "in" ExtraVimThrowpoint()
4547 endtry
4548 Xpath 4096 " X: 4096
4549 call G("aborting error", 5)
4550 Xpath 8192 " X: 0
4551 Xout "'taken' is" taken "instead of" expected
4552
4553endif
4554
4555Xcheck 5464
4556
4557
4558"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004559" Test 67: :throw across :call command {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00004560"
4561" On a call command, an exception might be thrown when evaluating the
4562" function name, during evaluation of the arguments, or when the
4563" function is being executed. The exception can be caught by the
4564" caller.
4565"-------------------------------------------------------------------------------
4566
4567XpathINIT
4568
4569function! THROW(x, n)
4570 if a:n == 1
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004571 Xpath 1 " X: 1
Bram Moolenaar071d4272004-06-13 20:20:40 +00004572 elseif a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004573 Xpath 2 " X: 2
Bram Moolenaar071d4272004-06-13 20:20:40 +00004574 elseif a:n == 3
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004575 Xpath 4 " X: 4
Bram Moolenaar071d4272004-06-13 20:20:40 +00004576 endif
4577 throw a:x
4578endfunction
4579
4580function! NAME(x, n)
4581 if a:n == 1
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004582 Xpath 8 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00004583 elseif a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004584 Xpath 16 " X: 16
Bram Moolenaar071d4272004-06-13 20:20:40 +00004585 elseif a:n == 3
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004586 Xpath 32 " X: 32
Bram Moolenaar071d4272004-06-13 20:20:40 +00004587 elseif a:n == 4
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004588 Xpath 64 " X: 64
Bram Moolenaar071d4272004-06-13 20:20:40 +00004589 endif
4590 return a:x
4591endfunction
4592
4593function! ARG(x, n)
4594 if a:n == 1
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004595 Xpath 128 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00004596 elseif a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004597 Xpath 256 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00004598 elseif a:n == 3
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004599 Xpath 512 " X: 512
Bram Moolenaar071d4272004-06-13 20:20:40 +00004600 elseif a:n == 4
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004601 Xpath 1024 " X: 1024
Bram Moolenaar071d4272004-06-13 20:20:40 +00004602 endif
4603 return a:x
4604endfunction
4605
4606function! F(x, n)
4607 if a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004608 Xpath 2048 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00004609 elseif a:n == 4
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004610 Xpath 4096 " X: 4096
Bram Moolenaar071d4272004-06-13 20:20:40 +00004611 endif
4612endfunction
4613
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004614while 1
Bram Moolenaar071d4272004-06-13 20:20:40 +00004615 try
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004616 let error = 0
4617 let v:errmsg = ""
Bram Moolenaar071d4272004-06-13 20:20:40 +00004618
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004619 while 1
4620 try
4621 Xpath 8192 " X: 8192
4622 call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
4623 Xpath 16384 " X: 0
4624 catch /^name$/
4625 Xpath 32768 " X: 32768
4626 catch /.*/
4627 let error = 1
4628 Xout "1:" v:exception "in" v:throwpoint
4629 finally
4630 if !error && $VIMNOERRTHROW && v:errmsg != ""
4631 let error = 1
4632 Xout "1:" v:errmsg
4633 endif
4634 if error
4635 Xpath 65536 " X: 0
4636 endif
4637 let error = 0
4638 let v:errmsg = ""
4639 break " discard error for $VIMNOERRTHROW
4640 endtry
4641 endwhile
Bram Moolenaar071d4272004-06-13 20:20:40 +00004642
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004643 while 1
4644 try
4645 Xpath 131072 " X: 131072
4646 call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
4647 Xpath 262144 " X: 0
4648 catch /^arg$/
4649 Xpath 524288 " X: 524288
4650 catch /.*/
4651 let error = 1
4652 Xout "2:" v:exception "in" v:throwpoint
4653 finally
4654 if !error && $VIMNOERRTHROW && v:errmsg != ""
4655 let error = 1
4656 Xout "2:" v:errmsg
4657 endif
4658 if error
4659 Xpath 1048576 " X: 0
4660 endif
4661 let error = 0
4662 let v:errmsg = ""
4663 break " discard error for $VIMNOERRTHROW
4664 endtry
4665 endwhile
4666
4667 while 1
4668 try
4669 Xpath 2097152 " X: 2097152
4670 call {NAME("THROW", 3)}(ARG("call", 3), 3)
4671 Xpath 4194304 " X: 0
4672 catch /^call$/
4673 Xpath 8388608 " X: 8388608
4674 catch /^0$/ " default return value
4675 Xpath 16777216 " X: 0
4676 Xout "3:" v:throwpoint
4677 catch /.*/
4678 let error = 1
4679 Xout "3:" v:exception "in" v:throwpoint
4680 finally
4681 if !error && $VIMNOERRTHROW && v:errmsg != ""
4682 let error = 1
4683 Xout "3:" v:errmsg
4684 endif
4685 if error
4686 Xpath 33554432 " X: 0
4687 endif
4688 let error = 0
4689 let v:errmsg = ""
4690 break " discard error for $VIMNOERRTHROW
4691 endtry
4692 endwhile
4693
4694 while 1
4695 try
4696 Xpath 67108864 " X: 67108864
4697 call {NAME("F", 4)}(ARG(4711, 4), 4)
4698 Xpath 134217728 " X: 134217728
4699 catch /.*/
4700 let error = 1
4701 Xout "4:" v:exception "in" v:throwpoint
4702 finally
4703 if !error && $VIMNOERRTHROW && v:errmsg != ""
4704 let error = 1
4705 Xout "4:" v:errmsg
4706 endif
4707 if error
4708 Xpath 268435456 " X: 0
4709 endif
4710 let error = 0
4711 let v:errmsg = ""
4712 break " discard error for $VIMNOERRTHROW
4713 endtry
4714 endwhile
4715
Bram Moolenaar071d4272004-06-13 20:20:40 +00004716 catch /^0$/ " default return value
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004717 Xpath 536870912 " X: 0
4718 Xout v:throwpoint
Bram Moolenaar071d4272004-06-13 20:20:40 +00004719 catch /.*/
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004720 let error = 1
4721 Xout v:exception "in" v:throwpoint
4722 finally
4723 if !error && $VIMNOERRTHROW && v:errmsg != ""
4724 let error = 1
4725 Xout v:errmsg
4726 endif
4727 if error
4728 Xpath 1073741824 " X: 0
4729 endif
4730 break " discard error for $VIMNOERRTHROW
Bram Moolenaar071d4272004-06-13 20:20:40 +00004731 endtry
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004732endwhile
Bram Moolenaar071d4272004-06-13 20:20:40 +00004733
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004734unlet error
Bram Moolenaar071d4272004-06-13 20:20:40 +00004735delfunction F
4736
4737Xcheck 212514423
4738
4739" Leave THROW(), NAME(), and ARG() for the next test.
4740
4741
4742"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004743" Test 68: :throw across function calls in expressions {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00004744"
4745" On a function call within an expression, an exception might be
4746" thrown when evaluating the function name, during evaluation of the
4747" arguments, or when the function is being executed. The exception
4748" can be caught by the caller.
4749"
4750" This test reuses the functions THROW(), NAME(), and ARG() from the
4751" previous test.
4752"-------------------------------------------------------------------------------
4753
4754XpathINIT
4755
4756function! F(x, n)
4757 if a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004758 Xpath 2048 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00004759 elseif a:n == 4
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004760 Xpath 4096 " X: 4096
Bram Moolenaar071d4272004-06-13 20:20:40 +00004761 endif
4762 return a:x
4763endfunction
4764
4765unlet! var1 var2 var3 var4
4766
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004767while 1
Bram Moolenaar071d4272004-06-13 20:20:40 +00004768 try
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004769 let error = 0
4770 let v:errmsg = ""
Bram Moolenaar071d4272004-06-13 20:20:40 +00004771
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004772 while 1
4773 try
4774 Xpath 8192 " X: 8192
4775 let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
4776 Xpath 16384 " X: 0
4777 catch /^name$/
4778 Xpath 32768 " X: 32768
4779 catch /.*/
4780 let error = 1
4781 Xout "1:" v:exception "in" v:throwpoint
4782 finally
4783 if !error && $VIMNOERRTHROW && v:errmsg != ""
4784 let error = 1
4785 Xout "1:" v:errmsg
4786 endif
4787 if error
4788 Xpath 65536 " X: 0
4789 endif
4790 let error = 0
4791 let v:errmsg = ""
4792 break " discard error for $VIMNOERRTHROW
4793 endtry
4794 endwhile
Bram Moolenaar071d4272004-06-13 20:20:40 +00004795
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004796 while 1
4797 try
4798 Xpath 131072 " X: 131072
4799 let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
4800 Xpath 262144 " X: 0
4801 catch /^arg$/
4802 Xpath 524288 " X: 524288
4803 catch /.*/
4804 let error = 1
4805 Xout "2:" v:exception "in" v:throwpoint
4806 finally
4807 if !error && $VIMNOERRTHROW && v:errmsg != ""
4808 let error = 1
4809 Xout "2:" v:errmsg
4810 endif
4811 if error
4812 Xpath 1048576 " X: 0
4813 endif
4814 let error = 0
4815 let v:errmsg = ""
4816 break " discard error for $VIMNOERRTHROW
4817 endtry
4818 endwhile
4819
4820 while 1
4821 try
4822 Xpath 2097152 " X: 2097152
4823 let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3)
4824 Xpath 4194304 " X: 0
4825 catch /^call$/
4826 Xpath 8388608 " X: 8388608
4827 catch /^0$/ " default return value
4828 Xpath 16777216 " X: 0
4829 Xout "3:" v:throwpoint
4830 catch /.*/
4831 let error = 1
4832 Xout "3:" v:exception "in" v:throwpoint
4833 finally
4834 if !error && $VIMNOERRTHROW && v:errmsg != ""
4835 let error = 1
4836 Xout "3:" v:errmsg
4837 endif
4838 if error
4839 Xpath 33554432 " X: 0
4840 endif
4841 let error = 0
4842 let v:errmsg = ""
4843 break " discard error for $VIMNOERRTHROW
4844 endtry
4845 endwhile
4846
4847 while 1
4848 try
4849 Xpath 67108864 " X: 67108864
4850 let var4 = {NAME("F", 4)}(ARG(4711, 4), 4)
4851 Xpath 134217728 " X: 134217728
4852 catch /.*/
4853 let error = 1
4854 Xout "4:" v:exception "in" v:throwpoint
4855 finally
4856 if !error && $VIMNOERRTHROW && v:errmsg != ""
4857 let error = 1
4858 Xout "4:" v:errmsg
4859 endif
4860 if error
4861 Xpath 268435456 " X: 0
4862 endif
4863 let error = 0
4864 let v:errmsg = ""
4865 break " discard error for $VIMNOERRTHROW
4866 endtry
4867 endwhile
4868
Bram Moolenaar071d4272004-06-13 20:20:40 +00004869 catch /^0$/ " default return value
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004870 Xpath 536870912 " X: 0
4871 Xout v:throwpoint
Bram Moolenaar071d4272004-06-13 20:20:40 +00004872 catch /.*/
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004873 let error = 1
4874 Xout v:exception "in" v:throwpoint
4875 finally
4876 if !error && $VIMNOERRTHROW && v:errmsg != ""
4877 let error = 1
4878 Xout v:errmsg
4879 endif
4880 if error
4881 Xpath 1073741824 " X: 0
4882 endif
4883 break " discard error for $VIMNOERRTHROW
Bram Moolenaar071d4272004-06-13 20:20:40 +00004884 endtry
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004885endwhile
Bram Moolenaar071d4272004-06-13 20:20:40 +00004886
4887if exists("var1") || exists("var2") || exists("var3") ||
4888 \ !exists("var4") || var4 != 4711
4889 " The Xpath command does not accept 2^31 (negative); add explicitly:
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004890 let Xpath = Xpath + 2147483648 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00004891 if exists("var1")
4892 Xout "var1 =" var1
4893 endif
4894 if exists("var2")
4895 Xout "var2 =" var2
4896 endif
4897 if exists("var3")
4898 Xout "var3 =" var3
4899 endif
4900 if !exists("var4")
4901 Xout "var4 unset"
4902 elseif var4 != 4711
4903 Xout "var4 =" var4
4904 endif
4905endif
4906
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004907unlet! error var1 var2 var3 var4
Bram Moolenaar071d4272004-06-13 20:20:40 +00004908delfunction THROW
4909delfunction NAME
4910delfunction ARG
4911delfunction F
4912
4913Xcheck 212514423
4914
Bram Moolenaar1f068232019-11-03 16:17:26 +01004915" Tests 69 to 75 were moved to test_trycatch.vim
4916let Xtest = 76
Bram Moolenaar071d4272004-06-13 20:20:40 +00004917
4918
4919"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004920" Test 76: Errors, interrupts, :throw during expression evaluation {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00004921"
4922" When a function call made during expression evaluation is aborted
4923" due to an error inside a :try/:endtry region or due to an interrupt
4924" or a :throw, the expression evaluation is aborted as well. No
4925" message is displayed for the cancelled expression evaluation. On an
4926" error not inside :try/:endtry, the expression evaluation continues.
4927"-------------------------------------------------------------------------------
4928
4929XpathINIT
4930
4931if ExtraVim()
4932
4933 let taken = ""
4934
4935 function! ERR(n)
4936 let g:taken = g:taken . "E" . a:n
4937 asdf
4938 endfunction
4939
4940 function! ERRabort(n) abort
4941 let g:taken = g:taken . "A" . a:n
4942 asdf
Bram Moolenaare13305e2005-06-19 22:54:15 +00004943 endfunction " returns -1; may cause follow-up msg for illegal var/func name
4944
4945 function! WRAP(n, arg)
4946 let g:taken = g:taken . "W" . a:n
4947 let g:saved_errmsg = v:errmsg
4948 return arg
4949 endfunction
Bram Moolenaar071d4272004-06-13 20:20:40 +00004950
4951 function! INT(n)
4952 let g:taken = g:taken . "I" . a:n
4953 "INTERRUPT9
4954 let dummy = 0
4955 endfunction
4956
4957 function! THR(n)
4958 let g:taken = g:taken . "T" . a:n
4959 throw "should not be caught"
4960 endfunction
4961
4962 function! CONT(n)
4963 let g:taken = g:taken . "C" . a:n
4964 endfunction
4965
4966 function! MSG(n)
4967 let g:taken = g:taken . "M" . a:n
Bram Moolenaare13305e2005-06-19 22:54:15 +00004968 let errmsg = (a:n >= 37 && a:n <= 44) ? g:saved_errmsg : v:errmsg
4969 let msgptn = (a:n >= 10 && a:n <= 27) ? "^$" : "asdf"
4970 if errmsg !~ msgptn
4971 let g:taken = g:taken . "x"
4972 Xout "Expr" a:n.": Unexpected message:" v:errmsg
Bram Moolenaar071d4272004-06-13 20:20:40 +00004973 endif
4974 let v:errmsg = ""
Bram Moolenaare13305e2005-06-19 22:54:15 +00004975 let g:saved_errmsg = ""
Bram Moolenaar071d4272004-06-13 20:20:40 +00004976 endfunction
4977
4978 let v:errmsg = ""
4979
4980 try
4981 let t = 1
4982 XloopINIT 1 2
4983 while t <= 9
4984 Xloop 1 " X: 511
4985 try
4986 if t == 1
4987 let v{ERR(t) + CONT(t)} = 0
4988 elseif t == 2
4989 let v{ERR(t) + CONT(t)}
4990 elseif t == 3
4991 let var = exists('v{ERR(t) + CONT(t)}')
4992 elseif t == 4
4993 unlet v{ERR(t) + CONT(t)}
4994 elseif t == 5
4995 function F{ERR(t) + CONT(t)}()
4996 endfunction
4997 elseif t == 6
4998 function F{ERR(t) + CONT(t)}
4999 elseif t == 7
5000 let var = exists('*F{ERR(t) + CONT(t)}')
5001 elseif t == 8
5002 delfunction F{ERR(t) + CONT(t)}
5003 elseif t == 9
5004 let var = ERR(t) + CONT(t)
5005 endif
5006 catch /asdf/
5007 " v:errmsg is not set when the error message is converted to an
5008 " exception. Set it to the original error message.
5009 let v:errmsg = substitute(v:exception, '^Vim:', '', "")
5010 catch /^Vim\((\a\+)\)\=:/
5011 " An error exception has been thrown after the original error.
5012 let v:errmsg = ""
5013 finally
5014 call MSG(t)
5015 let t = t + 1
5016 XloopNEXT
5017 continue " discard an aborting error
5018 endtry
5019 endwhile
5020 catch /.*/
5021 Xpath 512 " X: 0
5022 Xout v:exception "in" ExtraVimThrowpoint()
5023 endtry
5024
5025 try
5026 let t = 10
5027 XloopINIT 1024 2
5028 while t <= 18
5029 Xloop 1 " X: 1024 * 511
5030 try
5031 if t == 10
5032 let v{INT(t) + CONT(t)} = 0
5033 elseif t == 11
5034 let v{INT(t) + CONT(t)}
5035 elseif t == 12
5036 let var = exists('v{INT(t) + CONT(t)}')
5037 elseif t == 13
5038 unlet v{INT(t) + CONT(t)}
5039 elseif t == 14
5040 function F{INT(t) + CONT(t)}()
5041 endfunction
5042 elseif t == 15
5043 function F{INT(t) + CONT(t)}
5044 elseif t == 16
5045 let var = exists('*F{INT(t) + CONT(t)}')
5046 elseif t == 17
5047 delfunction F{INT(t) + CONT(t)}
5048 elseif t == 18
5049 let var = INT(t) + CONT(t)
5050 endif
5051 catch /^Vim\((\a\+)\)\=:\(Interrupt\)\@!/
5052 " An error exception has been triggered after the interrupt.
5053 let v:errmsg = substitute(v:exception,
5054 \ '^Vim\((\a\+)\)\=:', '', "")
5055 finally
5056 call MSG(t)
5057 let t = t + 1
5058 XloopNEXT
5059 continue " discard interrupt
5060 endtry
5061 endwhile
5062 catch /.*/
5063 Xpath 524288 " X: 0
5064 Xout v:exception "in" ExtraVimThrowpoint()
5065 endtry
5066
5067 try
5068 let t = 19
5069 XloopINIT 1048576 2
5070 while t <= 27
5071 Xloop 1 " X: 1048576 * 511
5072 try
5073 if t == 19
5074 let v{THR(t) + CONT(t)} = 0
5075 elseif t == 20
5076 let v{THR(t) + CONT(t)}
5077 elseif t == 21
5078 let var = exists('v{THR(t) + CONT(t)}')
5079 elseif t == 22
5080 unlet v{THR(t) + CONT(t)}
5081 elseif t == 23
5082 function F{THR(t) + CONT(t)}()
5083 endfunction
5084 elseif t == 24
5085 function F{THR(t) + CONT(t)}
5086 elseif t == 25
5087 let var = exists('*F{THR(t) + CONT(t)}')
5088 elseif t == 26
5089 delfunction F{THR(t) + CONT(t)}
5090 elseif t == 27
5091 let var = THR(t) + CONT(t)
5092 endif
5093 catch /^Vim\((\a\+)\)\=:/
5094 " An error exception has been triggered after the :throw.
5095 let v:errmsg = substitute(v:exception,
5096 \ '^Vim\((\a\+)\)\=:', '', "")
5097 finally
5098 call MSG(t)
5099 let t = t + 1
5100 XloopNEXT
5101 continue " discard exception
5102 endtry
5103 endwhile
5104 catch /.*/
5105 Xpath 536870912 " X: 0
5106 Xout v:exception "in" ExtraVimThrowpoint()
5107 endtry
5108
5109 let v{ERR(28) + CONT(28)} = 0
5110 call MSG(28)
5111 let v{ERR(29) + CONT(29)}
5112 call MSG(29)
5113 let var = exists('v{ERR(30) + CONT(30)}')
5114 call MSG(30)
5115 unlet v{ERR(31) + CONT(31)}
5116 call MSG(31)
5117 function F{ERR(32) + CONT(32)}()
5118 endfunction
5119 call MSG(32)
5120 function F{ERR(33) + CONT(33)}
5121 call MSG(33)
5122 let var = exists('*F{ERR(34) + CONT(34)}')
5123 call MSG(34)
5124 delfunction F{ERR(35) + CONT(35)}
5125 call MSG(35)
5126 let var = ERR(36) + CONT(36)
5127 call MSG(36)
5128
Bram Moolenaare13305e2005-06-19 22:54:15 +00005129 let saved_errmsg = ""
5130
5131 let v{WRAP(37, ERRabort(37)) + CONT(37)} = 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00005132 call MSG(37)
Bram Moolenaare13305e2005-06-19 22:54:15 +00005133 let v{WRAP(38, ERRabort(38)) + CONT(38)}
Bram Moolenaar071d4272004-06-13 20:20:40 +00005134 call MSG(38)
Bram Moolenaare13305e2005-06-19 22:54:15 +00005135 let var = exists('v{WRAP(39, ERRabort(39)) + CONT(39)}')
Bram Moolenaar071d4272004-06-13 20:20:40 +00005136 call MSG(39)
Bram Moolenaare13305e2005-06-19 22:54:15 +00005137 unlet v{WRAP(40, ERRabort(40)) + CONT(40)}
Bram Moolenaar071d4272004-06-13 20:20:40 +00005138 call MSG(40)
Bram Moolenaare13305e2005-06-19 22:54:15 +00005139 function F{WRAP(41, ERRabort(41)) + CONT(41)}()
Bram Moolenaar071d4272004-06-13 20:20:40 +00005140 endfunction
5141 call MSG(41)
Bram Moolenaare13305e2005-06-19 22:54:15 +00005142 function F{WRAP(42, ERRabort(42)) + CONT(42)}
Bram Moolenaar071d4272004-06-13 20:20:40 +00005143 call MSG(42)
Bram Moolenaare13305e2005-06-19 22:54:15 +00005144 let var = exists('*F{WRAP(43, ERRabort(43)) + CONT(43)}')
Bram Moolenaar071d4272004-06-13 20:20:40 +00005145 call MSG(43)
Bram Moolenaare13305e2005-06-19 22:54:15 +00005146 delfunction F{WRAP(44, ERRabort(44)) + CONT(44)}
Bram Moolenaar071d4272004-06-13 20:20:40 +00005147 call MSG(44)
5148 let var = ERRabort(45) + CONT(45)
5149 call MSG(45)
5150
5151 Xpath 1073741824 " X: 1073741824
5152
5153 let expected = ""
5154 \ . "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9"
5155 \ . "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18"
5156 \ . "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27"
5157 \ . "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33"
5158 \ . "E34C34M34E35C35M35E36C36M36"
Bram Moolenaare13305e2005-06-19 22:54:15 +00005159 \ . "A37W37C37M37A38W38C38M38A39W39C39M39A40W40C40M40A41W41C41M41"
5160 \ . "A42W42C42M42A43W43C43M43A44W44C44M44A45C45M45"
Bram Moolenaar071d4272004-06-13 20:20:40 +00005161
5162 if taken != expected
5163 " The Xpath command does not accept 2^31 (negative); display explicitly:
5164 exec "!echo 2147483648 >>" . g:ExtraVimResult
5165 " X: 0
5166 Xout "'taken' is" taken "instead of" expected
5167 if substitute(taken,
5168 \ '\(.*\)E3C3M3x\(.*\)E30C30M30x\(.*\)A39C39M39x\(.*\)',
5169 \ '\1E3M3\2E30C30M30\3A39C39M39\4',
5170 \ "") == expected
5171 Xout "Is ++emsg_skip for var with expr_start non-NULL"
5172 \ "in f_exists ok?"
5173 endif
5174 endif
5175
Bram Moolenaare13305e2005-06-19 22:54:15 +00005176 unlet! v var saved_errmsg taken expected
Bram Moolenaar071d4272004-06-13 20:20:40 +00005177 call delete(WA_t5)
5178 call delete(WA_t14)
5179 call delete(WA_t23)
5180 unlet! WA_t5 WA_t14 WA_t23
5181 delfunction WA_t5
5182 delfunction WA_t14
5183 delfunction WA_t23
5184
5185endif
5186
5187Xcheck 1610087935
5188
5189
5190"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005191" Test 77: Errors, interrupts, :throw in name{brace-expression} {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00005192"
5193" When a function call made during evaluation of an expression in
5194" braces as part of a function name after ":function" is aborted due
5195" to an error inside a :try/:endtry region or due to an interrupt or
5196" a :throw, the expression evaluation is aborted as well, and the
5197" function definition is ignored, skipping all commands to the
5198" ":endfunction". On an error not inside :try/:endtry, the expression
5199" evaluation continues and the function gets defined, and can be
5200" called and deleted.
5201"-------------------------------------------------------------------------------
5202
5203XpathINIT
5204
5205XloopINIT 1 4
5206
5207function! ERR() abort
5208 Xloop 1 " X: 1 + 4 + 16 + 64
5209 asdf
5210endfunction " returns -1
5211
5212function! OK()
5213 Xloop 2 " X: 2 * (1 + 4 + 16)
5214 let v:errmsg = ""
5215 return 0
5216endfunction
5217
5218let v:errmsg = ""
5219
5220Xpath 4096 " X: 4096
5221function! F{1 + ERR() + OK()}(arg)
5222 " F0 should be defined.
5223 if exists("a:arg") && a:arg == "calling"
5224 Xpath 8192 " X: 8192
5225 else
5226 Xpath 16384 " X: 0
5227 endif
5228endfunction
5229if v:errmsg != ""
5230 Xpath 32768 " X: 0
5231endif
5232XloopNEXT
5233
5234Xpath 65536 " X: 65536
5235call F{1 + ERR() + OK()}("calling")
5236if v:errmsg != ""
5237 Xpath 131072 " X: 0
5238endif
5239XloopNEXT
5240
5241Xpath 262144 " X: 262144
5242delfunction F{1 + ERR() + OK()}
5243if v:errmsg != ""
5244 Xpath 524288 " X: 0
5245endif
5246XloopNEXT
5247
5248try
5249 while 1
5250 let caught = 0
5251 try
5252 Xpath 1048576 " X: 1048576
5253 function! G{1 + ERR() + OK()}(arg)
5254 " G0 should not be defined, and the function body should be
5255 " skipped.
5256 if exists("a:arg") && a:arg == "calling"
5257 Xpath 2097152 " X: 0
5258 else
5259 Xpath 4194304 " X: 0
5260 endif
5261 " Use an unmatched ":finally" to check whether the body is
5262 " skipped when an error occurs in ERR(). This works whether or
5263 " not the exception is converted to an exception.
5264 finally
5265 Xpath 8388608 " X: 0
5266 Xout "Body of G{1 + ERR() + OK()}() not skipped"
5267 " Discard the aborting error or exception, and break the
5268 " while loop.
5269 break
5270 " End the try conditional and start a new one to avoid
5271 " ":catch after :finally" errors.
5272 endtry
5273 try
5274 Xpath 16777216 " X: 0
5275 endfunction
5276
5277 " When the function was not defined, this won't be reached - whether
5278 " the body was skipped or not. When the function was defined, it
5279 " can be called and deleted here.
5280 Xpath 33554432 " X: 0
5281 Xout "G0() has been defined"
5282 XloopNEXT
5283 try
5284 call G{1 + ERR() + OK()}("calling")
5285 catch /.*/
5286 Xpath 67108864 " X: 0
5287 endtry
5288 Xpath 134217728 " X: 0
5289 XloopNEXT
5290 try
5291 delfunction G{1 + ERR() + OK()}
5292 catch /.*/
5293 Xpath 268435456 " X: 0
5294 endtry
5295 catch /asdf/
5296 " Jumped to when the function is not defined and the body is
5297 " skipped.
5298 let caught = 1
5299 catch /.*/
5300 Xpath 536870912 " X: 0
5301 finally
5302 if !caught && !$VIMNOERRTHROW
5303 Xpath 1073741824 " X: 0
5304 endif
5305 break " discard error for $VIMNOERRTHROW
5306 endtry " jumped to when the body is not skipped
5307 endwhile
5308catch /.*/
5309 " The Xpath command does not accept 2^31 (negative); add explicitly:
5310 let Xpath = Xpath + 2147483648 " X: 0
5311 Xout "Body of G{1 + ERR() + OK()}() not skipped, exception caught"
5312 Xout v:exception "in" v:throwpoint
5313endtry
5314
5315Xcheck 1388671
5316
5317
5318"-------------------------------------------------------------------------------
5319" Test 78: Messages on parsing errors in expression evaluation {{{1
5320"
5321" When an expression evaluation detects a parsing error, an error
5322" message is given and converted to an exception, and the expression
5323" evaluation is aborted.
5324"-------------------------------------------------------------------------------
5325
5326XpathINIT
5327
5328if ExtraVim()
5329
5330 let taken = ""
5331
5332 function! F(n)
5333 let g:taken = g:taken . "F" . a:n
5334 endfunction
5335
5336 function! MSG(n, enr, emsg)
5337 let g:taken = g:taken . "M" . a:n
5338 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
5339 if a:enr == ""
5340 Xout "TODO: Add message number for:" a:emsg
5341 let v:errmsg = ":" . v:errmsg
5342 endif
5343 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
5344 if v:errmsg == ""
5345 Xout "Expr" a:n.": Message missing."
5346 let g:taken = g:taken . "x"
5347 else
5348 let v:errmsg = escape(v:errmsg, '"')
5349 Xout "Expr" a:n.": Unexpected message:" v:errmsg
Bram Moolenaar383f9bc2005-01-19 22:18:32 +00005350 Xout "Expected: " . a:enr . ': ' . a:emsg
Bram Moolenaar071d4272004-06-13 20:20:40 +00005351 let g:taken = g:taken . "X"
5352 endif
5353 endif
5354 endfunction
5355
5356 function! CONT(n)
5357 let g:taken = g:taken . "C" . a:n
5358 endfunction
5359
5360 let v:errmsg = ""
5361 XloopINIT 1 2
5362
5363 try
5364 let t = 1
5365 while t <= 14
5366 let g:taken = g:taken . "T" . t
5367 let v:errmsg = ""
5368 try
5369 let caught = 0
5370 if t == 1
5371 let v{novar + CONT(t)} = 0
5372 elseif t == 2
5373 let v{novar + CONT(t)}
5374 elseif t == 3
5375 let var = exists('v{novar + CONT(t)}')
5376 elseif t == 4
5377 unlet v{novar + CONT(t)}
5378 elseif t == 5
5379 function F{novar + CONT(t)}()
5380 endfunction
5381 elseif t == 6
5382 function F{novar + CONT(t)}
5383 elseif t == 7
5384 let var = exists('*F{novar + CONT(t)}')
5385 elseif t == 8
5386 delfunction F{novar + CONT(t)}
5387 elseif t == 9
5388 echo novar + CONT(t)
5389 elseif t == 10
5390 echo v{novar + CONT(t)}
5391 elseif t == 11
5392 echo F{novar + CONT(t)}
5393 elseif t == 12
5394 let var = novar + CONT(t)
5395 elseif t == 13
5396 let var = v{novar + CONT(t)}
5397 elseif t == 14
5398 let var = F{novar + CONT(t)}()
5399 endif
5400 catch /^Vim\((\a\+)\)\=:/
5401 " v:errmsg is not set when the error message is converted to an
5402 " exception. Set it to the original error message.
5403 let v:errmsg = substitute(v:exception,
5404 \ '^Vim\((\a\+)\)\=:', '', "")
5405 let caught = 1
5406 finally
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005407 if t <= 8 && t != 3 && t != 7
5408 call MSG(t, 'E475', 'Invalid argument\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00005409 else
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00005410 if !caught " no error exceptions ($VIMNOERRTHROW set)
5411 call MSG(t, 'E15', "Invalid expression")
Bram Moolenaar071d4272004-06-13 20:20:40 +00005412 else
5413 call MSG(t, 'E121', "Undefined variable")
5414 endif
5415 endif
5416 let t = t + 1
5417 XloopNEXT
5418 continue " discard an aborting error
5419 endtry
5420 endwhile
5421 catch /.*/
5422 Xloop 1 " X: 0
5423 Xout t.":" v:exception "in" ExtraVimThrowpoint()
5424 endtry
5425
5426 function! T(n, expr, enr, emsg)
5427 try
5428 let g:taken = g:taken . "T" . a:n
5429 let v:errmsg = ""
5430 try
5431 let caught = 0
5432 execute "let var = " . a:expr
5433 catch /^Vim\((\a\+)\)\=:/
5434 " v:errmsg is not set when the error message is converted to an
5435 " exception. Set it to the original error message.
5436 let v:errmsg = substitute(v:exception,
5437 \ '^Vim\((\a\+)\)\=:', '', "")
5438 let caught = 1
5439 finally
5440 if !caught " no error exceptions ($VIMNOERRTHROW set)
5441 call MSG(a:n, 'E15', "Invalid expression")
5442 else
5443 call MSG(a:n, a:enr, a:emsg)
5444 endif
5445 XloopNEXT
5446 " Discard an aborting error:
5447 return
5448 endtry
5449 catch /.*/
5450 Xloop 1 " X: 0
5451 Xout a:n.":" v:exception "in" ExtraVimThrowpoint()
5452 endtry
5453 endfunction
5454
5455 call T(15, 'Nofunc() + CONT(15)', 'E117', "Unknown function")
5456 call T(16, 'F(1 2 + CONT(16))', 'E116', "Invalid arguments")
5457 call T(17, 'F(1, 2) + CONT(17)', 'E118', "Too many arguments")
5458 call T(18, 'F() + CONT(18)', 'E119', "Not enough arguments")
5459 call T(19, '{(1} + CONT(19)', 'E110', "Missing ')'")
5460 call T(20, '("abc"[1) + CONT(20)', 'E111', "Missing ']'")
5461 call T(21, '(1 +) + CONT(21)', 'E15', "Invalid expression")
5462 call T(22, '1 2 + CONT(22)', 'E15', "Invalid expression")
5463 call T(23, '(1 ? 2) + CONT(23)', 'E109', "Missing ':' after '?'")
5464 call T(24, '("abc) + CONT(24)', 'E114', "Missing quote")
5465 call T(25, "('abc) + CONT(25)", 'E115', "Missing quote")
Bram Moolenaar2fda12f2005-01-15 22:14:15 +00005466 call T(26, '& + CONT(26)', 'E112', "Option name missing")
Bram Moolenaar071d4272004-06-13 20:20:40 +00005467 call T(27, '&asdf + CONT(27)', 'E113', "Unknown option")
5468
5469 Xpath 134217728 " X: 134217728
5470
5471 let expected = ""
5472 \ . "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14"
5473 \ . "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25"
5474 \ . "T26M26T27M27"
5475
5476 if taken != expected
5477 Xpath 268435456 " X: 0
5478 Xout "'taken' is" taken "instead of" expected
5479 if substitute(taken, '\(.*\)T3M3x\(.*\)', '\1T3M3\2', "") == expected
5480 Xout "Is ++emsg_skip for var with expr_start non-NULL"
5481 \ "in f_exists ok?"
5482 endif
5483 endif
5484
5485 unlet! var caught taken expected
5486 call delete(WA_t5)
5487 unlet! WA_t5
5488 delfunction WA_t5
5489
5490endif
5491
5492Xcheck 134217728
5493
5494
5495"-------------------------------------------------------------------------------
5496" Test 79: Throwing one of several errors for the same command {{{1
5497"
5498" When several errors appear in a row (for instance during expression
5499" evaluation), the first as the most specific one is used when
5500" throwing an error exception. If, however, a syntax error is
5501" detected afterwards, this one is used for the error exception.
5502" On a syntax error, the next command is not executed, on a normal
5503" error, however, it is (relevant only in a function without the
5504" "abort" flag). v:errmsg is not set.
5505"
5506" If throwing error exceptions is configured off, v:errmsg is always
5507" set to the latest error message, that is, to the more general
5508" message or the syntax error, respectively.
5509"-------------------------------------------------------------------------------
5510
5511XpathINIT
5512
5513XloopINIT 1 2
5514
5515function! NEXT(cmd)
5516 exec a:cmd . " | Xloop 1"
5517endfunction
5518
5519call NEXT('echo novar') " X: 1 * 1 (checks nextcmd)
5520XloopNEXT
5521call NEXT('let novar #') " X: 0 * 2 (skips nextcmd)
5522XloopNEXT
5523call NEXT('unlet novar #') " X: 0 * 4 (skips nextcmd)
5524XloopNEXT
5525call NEXT('let {novar}') " X: 0 * 8 (skips nextcmd)
5526XloopNEXT
5527call NEXT('unlet{ novar}') " X: 0 * 16 (skips nextcmd)
5528
5529function! EXEC(cmd)
5530 exec a:cmd
5531endfunction
5532
5533function! MATCH(expected, msg, enr, emsg)
5534 let msg = a:msg
5535 if a:enr == ""
5536 Xout "TODO: Add message number for:" a:emsg
5537 let msg = ":" . msg
5538 endif
5539 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
5540 if msg !~ '^'.a:enr.':' || (english && msg !~ a:emsg)
5541 let match = 0
5542 if a:expected " no match although expected
5543 if a:msg == ""
5544 Xout "Message missing."
5545 else
5546 let msg = escape(msg, '"')
5547 Xout "Unexpected message:" msg
Bram Moolenaar9cd15162005-01-16 22:02:49 +00005548 Xout "Expected:" a:enr . ": " . a:emsg
Bram Moolenaar071d4272004-06-13 20:20:40 +00005549 endif
5550 endif
5551 else
5552 let match = 1
5553 if !a:expected " match although not expected
5554 let msg = escape(msg, '"')
5555 Xout "Unexpected message:" msg
Bram Moolenaar9cd15162005-01-16 22:02:49 +00005556 Xout "Expected none."
Bram Moolenaar071d4272004-06-13 20:20:40 +00005557 endif
5558 endif
5559 return match
5560endfunction
5561
5562try
5563
5564 while 1 " dummy loop
5565 try
5566 let v:errmsg = ""
5567 let caught = 0
5568 let thrmsg = ""
5569 call EXEC('echo novar') " normal error
5570 catch /^Vim\((\a\+)\)\=:/
5571 let caught = 1
5572 let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
5573 finally
5574 Xpath 32 " X: 32
5575 if !caught
5576 if !$VIMNOERRTHROW
5577 Xpath 64 " X: 0
5578 endif
5579 elseif !MATCH(1, thrmsg, 'E121', "Undefined variable")
5580 \ || v:errmsg != ""
5581 Xpath 128 " X: 0
5582 endif
5583 if !caught && !MATCH(1, v:errmsg, 'E15', "Invalid expression")
5584 Xpath 256 " X: 0
5585 endif
5586 break " discard error if $VIMNOERRTHROW == 1
5587 endtry
5588 endwhile
5589
5590 Xpath 512 " X: 512
5591 let cmd = "let"
5592 XloopINIT 1024 32
5593 while cmd != ""
5594 try
5595 let v:errmsg = ""
5596 let caught = 0
5597 let thrmsg = ""
5598 call EXEC(cmd . ' novar #') " normal plus syntax error
5599 catch /^Vim\((\a\+)\)\=:/
5600 let caught = 1
5601 let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
5602 finally
5603 Xloop 1 " X: 1024 * (1 + 32)
5604 if !caught
5605 if !$VIMNOERRTHROW
5606 Xloop 2 " X: 0
5607 endif
5608 else
5609 if cmd == "let"
Bram Moolenaar39676922010-09-29 16:55:49 +02005610 let match = MATCH(0, thrmsg, 'E121', "Undefined variable")
Bram Moolenaar071d4272004-06-13 20:20:40 +00005611 elseif cmd == "unlet"
5612 let match = MATCH(0, thrmsg, 'E108', "No such variable")
5613 endif
5614 if match " normal error
5615 Xloop 4 " X: 0
5616 endif
5617 if !MATCH(1, thrmsg, 'E488', "Trailing characters")
5618 \|| v:errmsg != ""
5619 " syntax error
5620 Xloop 8 " X: 0
5621 endif
5622 endif
5623 if !caught && !MATCH(1, v:errmsg, 'E488', "Trailing characters")
5624 " last error
5625 Xloop 16 " X: 0
5626 endif
5627 if cmd == "let"
5628 let cmd = "unlet"
5629 else
5630 let cmd = ""
5631 endif
5632 XloopNEXT
5633 continue " discard error if $VIMNOERRTHROW == 1
5634 endtry
5635 endwhile
5636
5637 Xpath 1048576 " X: 1048576
5638 let cmd = "let"
5639 XloopINIT 2097152 32
5640 while cmd != ""
5641 try
5642 let v:errmsg = ""
5643 let caught = 0
5644 let thrmsg = ""
5645 call EXEC(cmd . ' {novar}') " normal plus syntax error
5646 catch /^Vim\((\a\+)\)\=:/
5647 let caught = 1
5648 let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
5649 finally
5650 Xloop 1 " X: 2097152 * (1 + 32)
5651 if !caught
5652 if !$VIMNOERRTHROW
5653 Xloop 2 " X: 0
5654 endif
5655 else
5656 if MATCH(0, thrmsg, 'E121', "Undefined variable") " normal error
5657 Xloop 4 " X: 0
5658 endif
5659 if !MATCH(1, thrmsg, 'E475', 'Invalid argument\>')
5660 \ || v:errmsg != "" " syntax error
5661 Xloop 8 " X: 0
5662 endif
5663 endif
5664 if !caught && !MATCH(1, v:errmsg, 'E475', 'Invalid argument\>')
5665 " last error
5666 Xloop 16 " X: 0
5667 endif
5668 if cmd == "let"
5669 let cmd = "unlet"
5670 else
5671 let cmd = ""
5672 endif
5673 XloopNEXT
5674 continue " discard error if $VIMNOERRTHROW == 1
5675 endtry
5676 endwhile
5677
5678catch /.*/
5679 " The Xpath command does not accept 2^31 (negative); add explicitly:
5680 let Xpath = Xpath + 2147483648 " X: 0
5681 Xout v:exception "in" v:throwpoint
5682endtry
5683
5684unlet! next_command thrmsg match
5685delfunction NEXT
5686delfunction EXEC
5687delfunction MATCH
5688
5689Xcheck 70288929
5690
5691
5692"-------------------------------------------------------------------------------
5693" Test 80: Syntax error in expression for illegal :elseif {{{1
5694"
5695" If there is a syntax error in the expression after an illegal
5696" :elseif, an error message is given (or an error exception thrown)
5697" for the illegal :elseif rather than the expression error.
5698"-------------------------------------------------------------------------------
5699
5700XpathINIT
5701
5702function! MSG(enr, emsg)
5703 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
5704 if a:enr == ""
5705 Xout "TODO: Add message number for:" a:emsg
5706 let v:errmsg = ":" . v:errmsg
5707 endif
5708 let match = 1
5709 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
5710 let match = 0
5711 if v:errmsg == ""
5712 Xout "Message missing."
5713 else
5714 let v:errmsg = escape(v:errmsg, '"')
5715 Xout "Unexpected message:" v:errmsg
5716 endif
5717 endif
5718 return match
5719endfunction
5720
5721let v:errmsg = ""
5722if 0
5723else
5724elseif 1 ||| 2
5725endif
5726Xpath 1 " X: 1
5727if !MSG('E584', ":elseif after :else")
5728 Xpath 2 " X: 0
5729endif
5730
5731let v:errmsg = ""
5732if 1
5733else
5734elseif 1 ||| 2
5735endif
5736Xpath 4 " X: 4
5737if !MSG('E584', ":elseif after :else")
5738 Xpath 8 " X: 0
5739endif
5740
5741let v:errmsg = ""
5742elseif 1 ||| 2
5743Xpath 16 " X: 16
5744if !MSG('E582', ":elseif without :if")
5745 Xpath 32 " X: 0
5746endif
5747
5748let v:errmsg = ""
5749while 1
5750 elseif 1 ||| 2
5751endwhile
5752Xpath 64 " X: 64
5753if !MSG('E582', ":elseif without :if")
5754 Xpath 128 " X: 0
5755endif
5756
5757while 1
5758 try
5759 try
5760 let v:errmsg = ""
5761 let caught = 0
5762 if 0
5763 else
5764 elseif 1 ||| 2
5765 endif
5766 catch /^Vim\((\a\+)\)\=:/
5767 let caught = 1
5768 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
5769 finally
5770 Xpath 256 " X: 256
5771 if !caught && !$VIMNOERRTHROW
5772 Xpath 512 " X: 0
5773 endif
5774 if !MSG('E584', ":elseif after :else")
5775 Xpath 1024 " X: 0
5776 endif
5777 endtry
5778 catch /.*/
5779 Xpath 2048 " X: 0
5780 Xout v:exception "in" v:throwpoint
5781 finally
5782 break " discard error for $VIMNOERRTHROW
5783 endtry
5784endwhile
5785
5786while 1
5787 try
5788 try
5789 let v:errmsg = ""
5790 let caught = 0
5791 if 1
5792 else
5793 elseif 1 ||| 2
5794 endif
5795 catch /^Vim\((\a\+)\)\=:/
5796 let caught = 1
5797 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
5798 finally
5799 Xpath 4096 " X: 4096
5800 if !caught && !$VIMNOERRTHROW
5801 Xpath 8192 " X: 0
5802 endif
5803 if !MSG('E584', ":elseif after :else")
5804 Xpath 16384 " X: 0
5805 endif
5806 endtry
5807 catch /.*/
5808 Xpath 32768 " X: 0
5809 Xout v:exception "in" v:throwpoint
5810 finally
5811 break " discard error for $VIMNOERRTHROW
5812 endtry
5813endwhile
5814
5815while 1
5816 try
5817 try
5818 let v:errmsg = ""
5819 let caught = 0
5820 elseif 1 ||| 2
5821 catch /^Vim\((\a\+)\)\=:/
5822 let caught = 1
5823 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
5824 finally
5825 Xpath 65536 " X: 65536
5826 if !caught && !$VIMNOERRTHROW
5827 Xpath 131072 " X: 0
5828 endif
5829 if !MSG('E582', ":elseif without :if")
5830 Xpath 262144 " X: 0
5831 endif
5832 endtry
5833 catch /.*/
5834 Xpath 524288 " X: 0
5835 Xout v:exception "in" v:throwpoint
5836 finally
5837 break " discard error for $VIMNOERRTHROW
5838 endtry
5839endwhile
5840
5841while 1
5842 try
5843 try
5844 let v:errmsg = ""
5845 let caught = 0
5846 while 1
5847 elseif 1 ||| 2
5848 endwhile
5849 catch /^Vim\((\a\+)\)\=:/
5850 let caught = 1
5851 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
5852 finally
5853 Xpath 1048576 " X: 1048576
5854 if !caught && !$VIMNOERRTHROW
5855 Xpath 2097152 " X: 0
5856 endif
5857 if !MSG('E582', ":elseif without :if")
5858 Xpath 4194304 " X: 0
5859 endif
5860 endtry
5861 catch /.*/
5862 Xpath 8388608 " X: 0
5863 Xout v:exception "in" v:throwpoint
5864 finally
5865 break " discard error for $VIMNOERRTHROW
5866 endtry
5867endwhile
5868
5869Xpath 16777216 " X: 16777216
5870
5871unlet! caught
5872delfunction MSG
5873
5874Xcheck 17895765
5875
5876
5877"-------------------------------------------------------------------------------
5878" Test 81: Discarding exceptions after an error or interrupt {{{1
5879"
5880" When an exception is thrown from inside a :try conditional without
5881" :catch and :finally clauses and an error or interrupt occurs before
5882" the :endtry is reached, the exception is discarded.
5883"-------------------------------------------------------------------------------
5884
5885XpathINIT
5886
5887if ExtraVim()
5888 try
5889 Xpath 1 " X: 1
5890 try
5891 Xpath 2 " X: 2
5892 throw "arrgh"
5893 Xpath 4 " X: 0
5894" if 1
5895 Xpath 8 " X: 0
5896 " error after :throw: missing :endif
5897 endtry
5898 Xpath 16 " X: 0
5899 catch /arrgh/
5900 Xpath 32 " X: 0
5901 endtry
5902 Xpath 64 " X: 0
5903endif
5904
5905if ExtraVim()
5906 try
5907 Xpath 128 " X: 128
5908 try
5909 Xpath 256 " X: 256
5910 throw "arrgh"
5911 Xpath 512 " X: 0
5912 endtry " INTERRUPT
5913 Xpath 1024 " X: 0
5914 catch /arrgh/
5915 Xpath 2048 " X: 0
5916 endtry
5917 Xpath 4096 " X: 0
5918endif
5919
5920Xcheck 387
5921
5922
5923"-------------------------------------------------------------------------------
5924" Test 82: Ignoring :catch clauses after an error or interrupt {{{1
5925"
5926" When an exception is thrown and an error or interrupt occurs before
5927" the matching :catch clause is reached, the exception is discarded
5928" and the :catch clause is ignored (also for the error or interrupt
5929" exception being thrown then).
5930"-------------------------------------------------------------------------------
5931
5932XpathINIT
5933
5934if ExtraVim()
5935 try
5936 try
5937 Xpath 1 " X: 1
5938 throw "arrgh"
5939 Xpath 2 " X: 0
5940" if 1
5941 Xpath 4 " X: 0
5942 " error after :throw: missing :endif
5943 catch /.*/
5944 Xpath 8 " X: 0
5945 Xout v:exception "in" ExtraVimThrowpoint()
5946 catch /.*/
5947 Xpath 16 " X: 0
5948 Xout v:exception "in" ExtraVimThrowpoint()
5949 endtry
5950 Xpath 32 " X: 0
5951 catch /arrgh/
5952 Xpath 64 " X: 0
5953 endtry
5954 Xpath 128 " X: 0
5955endif
5956
5957if ExtraVim()
5958 function! E()
5959 try
5960 try
5961 Xpath 256 " X: 256
5962 throw "arrgh"
5963 Xpath 512 " X: 0
5964" if 1
5965 Xpath 1024 " X: 0
5966 " error after :throw: missing :endif
5967 catch /.*/
5968 Xpath 2048 " X: 0
5969 Xout v:exception "in" ExtraVimThrowpoint()
5970 catch /.*/
5971 Xpath 4096 " X: 0
5972 Xout v:exception "in" ExtraVimThrowpoint()
5973 endtry
5974 Xpath 8192 " X: 0
5975 catch /arrgh/
5976 Xpath 16384 " X: 0
5977 endtry
5978 endfunction
5979
5980 call E()
5981 Xpath 32768 " X: 0
5982endif
5983
5984if ExtraVim()
5985 try
5986 try
5987 Xpath 65536 " X: 65536
5988 throw "arrgh"
5989 Xpath 131072 " X: 0
5990 catch /.*/ "INTERRUPT
5991 Xpath 262144 " X: 0
5992 Xout v:exception "in" ExtraVimThrowpoint()
5993 catch /.*/
5994 Xpath 524288 " X: 0
5995 Xout v:exception "in" ExtraVimThrowpoint()
5996 endtry
5997 Xpath 1048576 " X: 0
5998 catch /arrgh/
5999 Xpath 2097152 " X: 0
6000 endtry
6001 Xpath 4194304 " X: 0
6002endif
6003
6004if ExtraVim()
6005 function I()
6006 try
6007 try
6008 Xpath 8388608 " X: 8388608
6009 throw "arrgh"
6010 Xpath 16777216 " X: 0
6011 catch /.*/ "INTERRUPT
6012 Xpath 33554432 " X: 0
6013 Xout v:exception "in" ExtraVimThrowpoint()
6014 catch /.*/
6015 Xpath 67108864 " X: 0
6016 Xout v:exception "in" ExtraVimThrowpoint()
6017 endtry
6018 Xpath 134217728 " X: 0
6019 catch /arrgh/
6020 Xpath 268435456 " X: 0
6021 endtry
6022 endfunction
6023
6024 call I()
6025 Xpath 536870912 " X: 0
6026endif
6027
6028Xcheck 8454401
6029
6030
6031"-------------------------------------------------------------------------------
6032" Test 83: Executing :finally clauses after an error or interrupt {{{1
6033"
6034" When an exception is thrown and an error or interrupt occurs before
6035" the :finally of the innermost :try is reached, the exception is
6036" discarded and the :finally clause is executed.
6037"-------------------------------------------------------------------------------
6038
6039XpathINIT
6040
6041if ExtraVim()
6042 try
6043 Xpath 1 " X: 1
6044 try
6045 Xpath 2 " X: 2
6046 throw "arrgh"
6047 Xpath 4 " X: 0
6048" if 1
6049 Xpath 8 " X: 0
6050 " error after :throw: missing :endif
6051 finally
6052 Xpath 16 " X: 16
6053 endtry
6054 Xpath 32 " X: 0
6055 catch /arrgh/
6056 Xpath 64 " X: 0
6057 endtry
6058 Xpath 128 " X: 0
6059endif
6060
6061if ExtraVim()
6062 try
6063 Xpath 256 " X: 256
6064 try
6065 Xpath 512 " X: 512
6066 throw "arrgh"
6067 Xpath 1024 " X: 0
6068 finally "INTERRUPT
6069 Xpath 2048 " X: 2048
6070 endtry
6071 Xpath 4096 " X: 0
6072 catch /arrgh/
6073 Xpath 8192 " X: 0
6074 endtry
6075 Xpath 16384 " X: 0
6076endif
6077
6078Xcheck 2835
6079
6080
6081"-------------------------------------------------------------------------------
6082" Test 84: Exceptions in autocommand sequences. {{{1
6083"
6084" When an exception occurs in a sequence of autocommands for
6085" a specific event, the rest of the sequence is not executed. The
6086" command that triggered the autocommand execution aborts, and the
6087" exception is propagated to the caller.
6088"
6089" For the FuncUndefined event under a function call expression or
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00006090" :call command, the function is not executed, even when it has
Bram Moolenaar071d4272004-06-13 20:20:40 +00006091" been defined by the autocommands before the exception occurred.
6092"-------------------------------------------------------------------------------
6093
6094XpathINIT
6095
6096if ExtraVim()
6097
6098 function! INT()
6099 "INTERRUPT
6100 let dummy = 0
6101 endfunction
6102
6103 aug TMP
6104 autocmd!
6105
6106 autocmd User x1 Xpath 1 " X: 1
6107 autocmd User x1 throw "x1"
6108 autocmd User x1 Xpath 2 " X: 0
6109
6110 autocmd User x2 Xpath 4 " X: 4
6111 autocmd User x2 asdf
6112 autocmd User x2 Xpath 8 " X: 0
6113
6114 autocmd User x3 Xpath 16 " X: 16
6115 autocmd User x3 call INT()
6116 autocmd User x3 Xpath 32 " X: 0
6117
6118 autocmd FuncUndefined U1 function! U1()
6119 autocmd FuncUndefined U1 Xpath 64 " X: 0
6120 autocmd FuncUndefined U1 endfunction
6121 autocmd FuncUndefined U1 Xpath 128 " X: 128
6122 autocmd FuncUndefined U1 throw "U1"
6123 autocmd FuncUndefined U1 Xpath 256 " X: 0
6124
6125 autocmd FuncUndefined U2 function! U2()
6126 autocmd FuncUndefined U2 Xpath 512 " X: 0
6127 autocmd FuncUndefined U2 endfunction
6128 autocmd FuncUndefined U2 Xpath 1024 " X: 1024
6129 autocmd FuncUndefined U2 ASDF
6130 autocmd FuncUndefined U2 Xpath 2048 " X: 0
6131
6132 autocmd FuncUndefined U3 function! U3()
6133 autocmd FuncUndefined U3 Xpath 4096 " X: 0
6134 autocmd FuncUndefined U3 endfunction
6135 autocmd FuncUndefined U3 Xpath 8192 " X: 8192
6136 autocmd FuncUndefined U3 call INT()
6137 autocmd FuncUndefined U3 Xpath 16384 " X: 0
6138 aug END
6139
6140 try
6141 try
6142 Xpath 32768 " X: 32768
6143 doautocmd User x1
6144 catch /x1/
6145 Xpath 65536 " X: 65536
6146 endtry
6147
6148 while 1
6149 try
6150 Xpath 131072 " X: 131072
6151 let caught = 0
6152 doautocmd User x2
6153 catch /asdf/
6154 let caught = 1
6155 finally
6156 Xpath 262144 " X: 262144
6157 if !caught && !$VIMNOERRTHROW
6158 Xpath 524288 " X: 0
6159 " Propagate uncaught error exception,
6160 else
6161 " ... but break loop for caught error exception,
6162 " or discard error and break loop if $VIMNOERRTHROW
6163 break
6164 endif
6165 endtry
6166 endwhile
6167
6168 while 1
6169 try
6170 Xpath 1048576 " X: 1048576
6171 let caught = 0
6172 doautocmd User x3
6173 catch /Vim:Interrupt/
6174 let caught = 1
6175 finally
6176 Xpath 2097152 " X: 2097152
6177 if !caught && !$VIMNOINTTHROW
6178 Xpath 4194304 " X: 0
6179 " Propagate uncaught interrupt exception,
6180 else
6181 " ... but break loop for caught interrupt exception,
6182 " or discard interrupt and break loop if $VIMNOINTTHROW
6183 break
6184 endif
6185 endtry
6186 endwhile
6187
6188 if exists("*U1") | delfunction U1 | endif
6189 if exists("*U2") | delfunction U2 | endif
6190 if exists("*U3") | delfunction U3 | endif
6191
6192 try
6193 Xpath 8388608 " X: 8388608
6194 call U1()
6195 catch /U1/
6196 Xpath 16777216 " X: 16777216
6197 endtry
6198
6199 while 1
6200 try
6201 Xpath 33554432 " X: 33554432
6202 let caught = 0
6203 call U2()
6204 catch /ASDF/
6205 let caught = 1
6206 finally
6207 Xpath 67108864 " X: 67108864
6208 if !caught && !$VIMNOERRTHROW
6209 Xpath 134217728 " X: 0
6210 " Propagate uncaught error exception,
6211 else
6212 " ... but break loop for caught error exception,
6213 " or discard error and break loop if $VIMNOERRTHROW
6214 break
6215 endif
6216 endtry
6217 endwhile
6218
6219 while 1
6220 try
6221 Xpath 268435456 " X: 268435456
6222 let caught = 0
6223 call U3()
6224 catch /Vim:Interrupt/
6225 let caught = 1
6226 finally
6227 Xpath 536870912 " X: 536870912
6228 if !caught && !$VIMNOINTTHROW
6229 Xpath 1073741824 " X: 0
6230 " Propagate uncaught interrupt exception,
6231 else
6232 " ... but break loop for caught interrupt exception,
6233 " or discard interrupt and break loop if $VIMNOINTTHROW
6234 break
6235 endif
6236 endtry
6237 endwhile
6238 catch /.*/
6239 " The Xpath command does not accept 2^31 (negative); display explicitly:
6240 exec "!echo 2147483648 >>" . g:ExtraVimResult
6241 Xout "Caught" v:exception "in" v:throwpoint
6242 endtry
6243
6244 unlet caught
6245 delfunction INT
6246 delfunction U1
6247 delfunction U2
6248 delfunction U3
6249 au! TMP
6250 aug! TMP
6251endif
6252
6253Xcheck 934782101
6254
6255
6256"-------------------------------------------------------------------------------
6257" Test 85: Error exceptions in autocommands for I/O command events {{{1
6258"
6259" When an I/O command is inside :try/:endtry, autocommands to be
6260" executed after it should be skipped on an error (exception) in the
6261" command itself or in autocommands to be executed before the command.
6262" In the latter case, the I/O command should not be executed either.
6263" Example 1: BufWritePre, :write, BufWritePost
6264" Example 2: FileReadPre, :read, FileReadPost.
6265"-------------------------------------------------------------------------------
6266
6267XpathINIT
6268
6269function! MSG(enr, emsg)
6270 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
6271 if a:enr == ""
6272 Xout "TODO: Add message number for:" a:emsg
6273 let v:errmsg = ":" . v:errmsg
6274 endif
6275 let match = 1
6276 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
6277 let match = 0
6278 if v:errmsg == ""
6279 Xout "Message missing."
6280 else
6281 let v:errmsg = escape(v:errmsg, '"')
6282 Xout "Unexpected message:" v:errmsg
6283 endif
6284 endif
6285 return match
6286endfunction
6287
6288" Remove the autocommands for the events specified as arguments in all used
6289" autogroups.
Bram Moolenaar1e115362019-01-09 23:01:02 +01006290function Delete_autocommands(...)
Bram Moolenaar071d4272004-06-13 20:20:40 +00006291 let augfile = tempname()
6292 while 1
6293 try
6294 exec "redir >" . augfile
6295 aug
6296 redir END
6297 exec "edit" augfile
6298 g/^$/d
6299 norm G$
6300 let wrap = "w"
6301 while search('\%( \|^\)\@<=.\{-}\%( \)\@=', wrap) > 0
6302 let wrap = "W"
6303 exec "norm y/ \n"
6304 let argno = 1
6305 while argno <= a:0
6306 exec "au!" escape(@", " ") a:{argno}
6307 let argno = argno + 1
6308 endwhile
6309 endwhile
6310 catch /.*/
6311 finally
6312 bwipeout!
6313 call delete(augfile)
6314 break " discard errors for $VIMNOERRTHROW
6315 endtry
6316 endwhile
6317endfunction
6318
6319call Delete_autocommands("BufWritePre", "BufWritePost")
6320
6321while 1
6322 try
6323 try
6324 let post = 0
6325 aug TMP
6326 au! BufWritePost * let post = 1
6327 aug END
6328 let caught = 0
6329 write /n/o/n/e/x/i/s/t/e/n/t
6330 catch /^Vim(write):/
6331 let caught = 1
6332 let v:errmsg = substitute(v:exception, '^Vim(write):', '', "")
6333 finally
6334 Xpath 1 " X: 1
6335 if !caught && !$VIMNOERRTHROW
6336 Xpath 2 " X: 0
6337 endif
6338 let v:errmsg = substitute(v:errmsg, '^"/n/o/n/e/x/i/s/t/e/n/t" ',
6339 \ '', "")
6340 if !MSG('E212', "Can't open file for writing")
6341 Xpath 4 " X: 0
6342 endif
6343 if post
6344 Xpath 8 " X: 0
6345 Xout "BufWritePost commands executed after write error"
6346 endif
6347 au! TMP
6348 aug! TMP
6349 endtry
6350 catch /.*/
6351 Xpath 16 " X: 0
6352 Xout v:exception "in" v:throwpoint
6353 finally
6354 break " discard error for $VIMNOERRTHROW
6355 endtry
6356endwhile
6357
6358while 1
6359 try
6360 try
6361 let post = 0
6362 aug TMP
6363 au! BufWritePre * asdf
6364 au! BufWritePost * let post = 1
6365 aug END
6366 let tmpfile = tempname()
6367 let caught = 0
6368 exec "write" tmpfile
6369 catch /^Vim\((write)\)\=:/
6370 let caught = 1
6371 let v:errmsg = substitute(v:exception, '^Vim\((write)\)\=:', '', "")
6372 finally
6373 Xpath 32 " X: 32
6374 if !caught && !$VIMNOERRTHROW
6375 Xpath 64 " X: 0
6376 endif
6377 let v:errmsg = substitute(v:errmsg, '^"'.tmpfile.'" ', '', "")
6378 if !MSG('E492', "Not an editor command")
6379 Xpath 128 " X: 0
6380 endif
6381 if filereadable(tmpfile)
6382 Xpath 256 " X: 0
6383 Xout ":write command not suppressed after BufWritePre error"
6384 endif
6385 if post
6386 Xpath 512 " X: 0
6387 Xout "BufWritePost commands executed after BufWritePre error"
6388 endif
6389 au! TMP
6390 aug! TMP
6391 endtry
6392 catch /.*/
6393 Xpath 1024 " X: 0
6394 Xout v:exception "in" v:throwpoint
6395 finally
6396 break " discard error for $VIMNOERRTHROW
6397 endtry
6398endwhile
6399
6400call delete(tmpfile)
6401
6402call Delete_autocommands("BufWritePre", "BufWritePost",
6403 \ "BufReadPre", "BufReadPost", "FileReadPre", "FileReadPost")
6404
6405while 1
6406 try
6407 try
6408 let post = 0
6409 aug TMP
6410 au! FileReadPost * let post = 1
6411 aug END
6412 let caught = 0
6413 read /n/o/n/e/x/i/s/t/e/n/t
6414 catch /^Vim(read):/
6415 let caught = 1
6416 let v:errmsg = substitute(v:exception, '^Vim(read):', '', "")
6417 finally
6418 Xpath 2048 " X: 2048
6419 if !caught && !$VIMNOERRTHROW
6420 Xpath 4096 " X: 0
6421 endif
6422 let v:errmsg = substitute(v:errmsg, ' /n/o/n/e/x/i/s/t/e/n/t$',
6423 \ '', "")
6424 if !MSG('E484', "Can't open file")
6425 Xpath 8192 " X: 0
6426 endif
6427 if post
6428 Xpath 16384 " X: 0
6429 Xout "FileReadPost commands executed after write error"
6430 endif
6431 au! TMP
6432 aug! TMP
6433 endtry
6434 catch /.*/
6435 Xpath 32768 " X: 0
6436 Xout v:exception "in" v:throwpoint
6437 finally
6438 break " discard error for $VIMNOERRTHROW
6439 endtry
6440endwhile
6441
6442while 1
6443 try
6444 let infile = tempname()
6445 let tmpfile = tempname()
6446 exec "!echo XYZ >" . infile
6447 exec "edit" tmpfile
6448 try
6449 Xpath 65536 " X: 65536
6450 try
6451 let post = 0
6452 aug TMP
6453 au! FileReadPre * asdf
6454 au! FileReadPost * let post = 1
6455 aug END
6456 let caught = 0
6457 exec "0read" infile
6458 catch /^Vim\((read)\)\=:/
6459 let caught = 1
6460 let v:errmsg = substitute(v:exception, '^Vim\((read)\)\=:', '',
6461 \ "")
6462 finally
6463 Xpath 131072 " X: 131072
6464 if !caught && !$VIMNOERRTHROW
6465 Xpath 262144 " X: 0
6466 endif
6467 let v:errmsg = substitute(v:errmsg, ' '.infile.'$', '', "")
6468 if !MSG('E492', "Not an editor command")
6469 Xpath 524288 " X: 0
6470 endif
6471 if getline("1") == "XYZ"
6472 Xpath 1048576 " X: 0
6473 Xout ":read command not suppressed after FileReadPre error"
6474 endif
6475 if post
6476 Xpath 2097152 " X: 0
6477 Xout "FileReadPost commands executed after " .
6478 \ "FileReadPre error"
6479 endif
6480 au! TMP
6481 aug! TMP
6482 endtry
6483 finally
6484 bwipeout!
6485 endtry
6486 catch /.*/
6487 Xpath 4194304 " X: 0
6488 Xout v:exception "in" v:throwpoint
6489 finally
6490 break " discard error for $VIMNOERRTHROW
6491 endtry
6492endwhile
6493
6494call delete(infile)
6495call delete(tmpfile)
6496unlet! caught post infile tmpfile
6497delfunction MSG
6498delfunction Delete_autocommands
6499
6500Xcheck 198689
6501
Bram Moolenaar41b884b2012-11-14 22:38:08 +01006502"-------------------------------------------------------------------------------
Bram Moolenaar32c8f1c2012-12-05 19:00:06 +01006503" Test 86: setloclist crash {{{1
Bram Moolenaar41b884b2012-11-14 22:38:08 +01006504"
6505" Executing a setloclist() on BufUnload shouldn't crash Vim
6506"-------------------------------------------------------------------------------
6507
6508func F
6509 au BufUnload * :call setloclist(0, [{'bufnr':1, 'lnum':1, 'col':1, 'text': 'tango down'}])
6510
Bram Moolenaarcc908ad2013-06-06 18:55:49 +02006511 :lvimgrep /.*/ *.mak
Bram Moolenaar41b884b2012-11-14 22:38:08 +01006512endfunc
6513
6514XpathINIT
6515
6516ExecAsScript F
6517
6518delfunction F
6519Xout "No Crash for vimgrep on BufUnload"
6520Xcheck 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00006521
Bram Moolenaar1f068232019-11-03 16:17:26 +01006522" Test 87 was moved to test_vimscript.vim
6523let Xtest = 88
Bram Moolenaarb8f84612013-02-26 22:54:11 +01006524
Bram Moolenaarb8f84612013-02-26 22:54:11 +01006525
6526"-------------------------------------------------------------------------------
6527" Test 88: $VIMNOERRTHROW and $VIMNOINTTHROW support {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00006528"
6529" It is possible to configure Vim for throwing exceptions on error
6530" or interrupt, controlled by variables $VIMNOERRTHROW and
6531" $VIMNOINTTHROW. This is just for increasing the number of tests.
6532" All tests here should run for all four combinations of setting
6533" these variables to 0 or 1. The variables are intended for the
6534" development phase only. In the final release, Vim should be
6535" configured to always use error and interrupt exceptions.
6536"
6537" The test result is "OK",
6538"
6539" - if the $VIMNOERRTHROW and the $VIMNOINTTHROW control are not
6540" configured and exceptions are thrown on error and on
6541" interrupt.
6542"
6543" - if the $VIMNOERRTHROW or the $VIMNOINTTHROW control is
6544" configured and works as intended.
6545"
6546" What actually happens, is shown in the test output.
6547"
6548" Otherwise, the test result is "FAIL", and the test output describes
6549" the problem.
6550"
6551" IMPORTANT: This must be the last test because it sets $VIMNOERRTHROW and
6552" $VIMNOINTTHROW.
6553"-------------------------------------------------------------------------------
6554
6555XpathINIT
6556
6557if ExtraVim()
6558
6559 function! ThrowOnError()
6560 XloopNEXT
6561 let caught = 0
6562 try
6563 Xloop 1 " X: 1 + 8 + 64
6564 asdf
6565 catch /.*/
6566 let caught = 1 " error exception caught
6567 finally
6568 Xloop 2 " X: 2 + 16 + 128
6569 return caught " discard aborting error
6570 endtry
6571 Xloop 4 " X: 0
6572 endfunction
6573
6574 let quits_skipped = 0
6575
6576 function! ThrowOnInterrupt()
6577 XloopNEXT
6578 let caught = 0
6579 try
6580 Xloop 1 " X: (1 + 8 + 64) * 512
6581 "INTERRUPT3
6582 let dummy = 0
6583 let g:quits_skipped = g:quits_skipped + 1
6584 catch /.*/
6585 let caught = 1 " interrupt exception caught
6586 finally
6587 Xloop 2 " X: (2 + 16 + 128) * 512
6588 return caught " discard interrupt
6589 endtry
6590 Xloop 4 " X: 0
6591 endfunction
6592
6593 function! CheckThrow(Type)
6594 execute 'return ThrowOn' . a:Type . '()'
6595 endfunction
6596
6597 function! CheckConfiguration(type) " type is "error" or "interrupt"
6598
6599 let type = a:type
6600 let Type = substitute(type, '.*', '\u&', "")
6601 let VAR = '$VIMNO' . substitute(type, '\(...\).*', '\U\1', "") . 'THROW'
6602
6603 if type == "error"
6604 XloopINIT! 1 8
6605 elseif type == "interrupt"
6606 XloopINIT! 512 8
6607 endif
6608
6609 exec 'let requested_for_tests = exists(VAR) && ' . VAR . ' == 0'
6610 exec 'let suppressed_for_tests = ' . VAR . ' != 0'
6611 let used_in_tests = CheckThrow(Type)
6612
6613 exec 'let ' . VAR . ' = 0'
6614 let request_works = CheckThrow(Type)
6615
6616 exec 'let ' . VAR . ' = 1'
6617 let suppress_works = !CheckThrow(Type)
6618
6619 if type == "error"
6620 XloopINIT! 262144 8
6621 elseif type == "interrupt"
6622 XloopINIT! 2097152 8
6623
6624 if g:quits_skipped != 0
6625 Xloop 1 " X: 0*2097152
6626 Xout "Test environment error. Interrupt breakpoints skipped: "
6627 \ . g:quits_skipped . ".\n"
6628 \ . "Cannot check whether interrupt exceptions are thrown."
6629 return
6630 endif
6631 endif
6632
6633 let failure =
6634 \ !suppressed_for_tests && !used_in_tests
6635 \ || !request_works
6636
6637 let contradiction =
6638 \ used_in_tests
6639 \ ? suppressed_for_tests && !request_works
6640 \ : !suppressed_for_tests
6641
6642 if failure
6643 " Failure in configuration.
6644 Xloop 2 " X: 0 * 2* (262144 + 2097152)
6645 elseif contradiction
6646 " Failure in test logic. Should not happen.
6647 Xloop 4 " X: 0 * 4 * (262144 + 2097152)
6648 endif
6649
6650 let var_control_configured =
6651 \ request_works != used_in_tests
6652 \ || suppress_works == used_in_tests
6653
6654 let var_control_not_configured =
6655 \ requested_for_tests || suppressed_for_tests
6656 \ ? request_works && !suppress_works
6657 \ : request_works == used_in_tests
6658 \ && suppress_works != used_in_tests
6659
6660 let with = used_in_tests ? "with" : "without"
6661
6662 let set = suppressed_for_tests ? "non-zero" :
6663 \ requested_for_tests ? "0" : "unset"
6664
6665 let although = contradiction && !var_control_not_configured
6666 \ ? ",\nalthough "
6667 \ : ".\n"
6668
6669 let output = "All tests were run " . with . " throwing exceptions on "
6670 \ . type . although
6671
6672 if !var_control_not_configured
6673 let output = output . VAR . " was " . set . "."
6674
6675 if !request_works && !requested_for_tests
6676 let output = output .
6677 \ "\n" . Type . " exceptions are not thrown when " . VAR .
6678 \ " is\nset to 0."
6679 endif
6680
6681 if !suppress_works && (!used_in_tests ||
6682 \ !request_works &&
6683 \ !requested_for_tests && !suppressed_for_tests)
6684 let output = output .
6685 \ "\n" . Type . " exceptions are thrown when " . VAR .
6686 \ " is set to 1."
6687 endif
6688
6689 if !failure && var_control_configured
6690 let output = output .
6691 \ "\nRun tests also with " . substitute(VAR, '^\$', '', "")
6692 \ . "=" . used_in_tests . "."
6693 \ . "\nThis is for testing in the development phase only."
6694 \ . " Remove the \n"
6695 \ . VAR . " control in the final release."
6696 endif
6697 else
6698 let output = output .
6699 \ "The " . VAR . " control is not configured."
6700 endif
6701
6702 Xout output
6703 endfunction
6704
6705 call CheckConfiguration("error")
6706 Xpath 16777216 " X: 16777216
6707 call CheckConfiguration("interrupt")
6708 Xpath 33554432 " X: 33554432
6709endif
6710
6711Xcheck 50443995
6712
6713" IMPORTANT: No test should be added after this test because it changes
6714" $VIMNOERRTHROW and $VIMNOINTTHROW.
6715
6716
6717"-------------------------------------------------------------------------------
6718" Modelines {{{1
6719" vim: ts=8 sw=4 tw=80 fdm=marker
Bram Moolenaar071d4272004-06-13 20:20:40 +00006720"-------------------------------------------------------------------------------