blob: b3215dfa6f6cc3c6342f57d942e36ee879a55f04 [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 Moolenaara6296202020-08-05 11:23:13 +02003" Last Change: 2020 Jun 07
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
Bram Moolenaarf48ee3c2019-12-06 22:18:20 +0100181" omitted (default: 1).
Bram Moolenaar071d4272004-06-13 20:20:40 +0000182"
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
Bram Moolenaara6296202020-08-05 11:23:13 +0200610" Tests 1 to 50, 87 were moved to test_vimscript.vim
611" Tests 25, 26, 32, 33, 41-48, 51, 69-75 were moved to test_trycatch.vim
Bram Moolenaar1f068232019-11-03 16:17:26 +0100612let Xtest = 52
Bram Moolenaar071d4272004-06-13 20:20:40 +0000613
Bram Moolenaar071d4272004-06-13 20:20:40 +0000614"-------------------------------------------------------------------------------
615" Test 52: Uncaught exceptions {{{1
616"
617" When an exception is thrown but not caught, an error message is
618" displayed when the script is terminated. In case of an interrupt
619" or error exception, the normal interrupt or error message(s) are
620" displayed.
621"-------------------------------------------------------------------------------
622
623XpathINIT
624
625let msgfile = tempname()
626
627function! MESSAGES(...)
628 try
629 exec "edit" g:msgfile
630 catch /^Vim(edit):/
631 return 0
632 endtry
633
634 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
635 let match = 1
636 norm gg
637
638 let num = a:0 / 2
639 let cnt = 1
640 while cnt <= num
641 let enr = a:{2*cnt - 1}
642 let emsg= a:{2*cnt}
643 let cnt = cnt + 1
644
645 if enr == ""
646 Xout "TODO: Add message number for:" emsg
647 elseif enr == "INT"
648 let enr = ""
649 endif
650 if enr == "" && !english
651 continue
652 endif
653 let pattern = (enr != "") ? enr . ':.*' : ''
654 if english
655 let pattern = pattern . emsg
656 endif
657 if !search(pattern, "W")
658 let match = 0
659 Xout "No match for:" pattern
660 endif
661 norm $
662 endwhile
663
664 bwipeout!
665 return match
666endfunction
667
668if ExtraVim(msgfile)
669 Xpath 1 " X: 1
670 throw "arrgh"
671endif
672
673Xpath 2 " X: 2
674if !MESSAGES('E605', "Exception not caught")
675 Xpath 4 " X: 0
676endif
677
678if ExtraVim(msgfile)
679 try
680 Xpath 8 " X: 8
681 throw "oops"
682 catch /arrgh/
683 Xpath 16 " X: 0
684 endtry
685 Xpath 32 " X: 0
686endif
687
688Xpath 64 " X: 64
689if !MESSAGES('E605', "Exception not caught")
690 Xpath 128 " X: 0
691endif
692
693if ExtraVim(msgfile)
694 function! T()
695 throw "brrr"
696 endfunction
697
698 try
699 Xpath 256 " X: 256
700 throw "arrgh"
701 catch /.*/
702 Xpath 512 " X: 512
703 call T()
704 endtry
705 Xpath 1024 " X: 0
706endif
707
708Xpath 2048 " X: 2048
709if !MESSAGES('E605', "Exception not caught")
710 Xpath 4096 " X: 0
711endif
712
713if ExtraVim(msgfile)
714 try
715 Xpath 8192 " X: 8192
716 throw "arrgh"
717 finally
718 Xpath 16384 " X: 16384
719 throw "brrr"
720 endtry
721 Xpath 32768 " X: 0
722endif
723
724Xpath 65536 " X: 65536
725if !MESSAGES('E605', "Exception not caught")
726 Xpath 131072 " X: 0
727endif
728
729if ExtraVim(msgfile)
730 try
731 Xpath 262144 " X: 262144
732 "INTERRUPT
733 endtry
734 Xpath 524288 " X: 0
735endif
736
737Xpath 1048576 " X: 1048576
738if !MESSAGES('INT', "Interrupted")
739 Xpath 2097152 " X: 0
740endif
741
742if ExtraVim(msgfile)
743 try
744 Xpath 4194304 " X: 4194304
Bram Moolenaarc0f5a782019-01-13 15:16:13 +0100745 let x = novar " error E121; exception: E121
Bram Moolenaar071d4272004-06-13 20:20:40 +0000746 catch /E15:/ " should not catch
747 Xpath 8388608 " X: 0
748 endtry
749 Xpath 16777216 " X: 0
750endif
751
752Xpath 33554432 " X: 33554432
Bram Moolenaarc0f5a782019-01-13 15:16:13 +0100753if !MESSAGES('E121', "Undefined variable")
Bram Moolenaar071d4272004-06-13 20:20:40 +0000754 Xpath 67108864 " X: 0
755endif
756
757if ExtraVim(msgfile)
758 try
759 Xpath 134217728 " X: 134217728
760" unlet novar # " error E108/E488; exception: E488
761 catch /E108:/ " should not catch
762 Xpath 268435456 " X: 0
763 endtry
764 Xpath 536870912 " X: 0
765endif
766
767Xpath 1073741824 " X: 1073741824
768if !MESSAGES('E108', "No such variable", 'E488', "Trailing characters")
769 " The Xpath command does not accept 2^31 (negative); add explicitly:
770 let Xpath = Xpath + 2147483648 " X: 0
771endif
772
773call delete(msgfile)
774unlet msgfile
775
776Xcheck 1247112011
777
778" Leave MESSAGES() for the next tests.
779
780
781"-------------------------------------------------------------------------------
782" Test 53: Nesting errors: :endif/:else/:elseif {{{1
783"
784" For nesting errors of :if conditionals the correct error messages
785" should be given.
786"
787" This test reuses the function MESSAGES() from the previous test.
788" This functions checks the messages in g:msgfile.
789"-------------------------------------------------------------------------------
790
791XpathINIT
792
793let msgfile = tempname()
794
795if ExtraVim(msgfile)
796" endif
797endif
798if MESSAGES('E580', ":endif without :if")
799 Xpath 1 " X: 1
800endif
801
802if ExtraVim(msgfile)
803" while 1
804" endif
805" endwhile
806endif
807if MESSAGES('E580', ":endif without :if")
808 Xpath 2 " X: 2
809endif
810
811if ExtraVim(msgfile)
812" try
813" finally
814" endif
815" endtry
816endif
817if MESSAGES('E580', ":endif without :if")
818 Xpath 4 " X: 4
819endif
820
821if ExtraVim(msgfile)
822" try
823" endif
824" endtry
825endif
826if MESSAGES('E580', ":endif without :if")
827 Xpath 8 " X: 8
828endif
829
830if ExtraVim(msgfile)
831" try
832" throw "a"
833" catch /a/
834" endif
835" endtry
836endif
837if MESSAGES('E580', ":endif without :if")
838 Xpath 16 " X: 16
839endif
840
841if ExtraVim(msgfile)
842" else
843endif
844if MESSAGES('E581', ":else without :if")
845 Xpath 32 " X: 32
846endif
847
848if ExtraVim(msgfile)
849" while 1
850" else
851" endwhile
852endif
853if MESSAGES('E581', ":else without :if")
854 Xpath 64 " X: 64
855endif
856
857if ExtraVim(msgfile)
858" try
859" finally
860" else
861" endtry
862endif
863if MESSAGES('E581', ":else without :if")
864 Xpath 128 " X: 128
865endif
866
867if ExtraVim(msgfile)
868" try
869" else
870" endtry
871endif
872if MESSAGES('E581', ":else without :if")
873 Xpath 256 " X: 256
874endif
875
876if ExtraVim(msgfile)
877" try
878" throw "a"
879" catch /a/
880" else
881" endtry
882endif
883if MESSAGES('E581', ":else without :if")
884 Xpath 512 " X: 512
885endif
886
887if ExtraVim(msgfile)
888" elseif
889endif
890if MESSAGES('E582', ":elseif without :if")
891 Xpath 1024 " X: 1024
892endif
893
894if ExtraVim(msgfile)
895" while 1
896" elseif
897" endwhile
898endif
899if MESSAGES('E582', ":elseif without :if")
900 Xpath 2048 " X: 2048
901endif
902
903if ExtraVim(msgfile)
904" try
905" finally
906" elseif
907" endtry
908endif
909if MESSAGES('E582', ":elseif without :if")
910 Xpath 4096 " X: 4096
911endif
912
913if ExtraVim(msgfile)
914" try
915" elseif
916" endtry
917endif
918if MESSAGES('E582', ":elseif without :if")
919 Xpath 8192 " X: 8192
920endif
921
922if ExtraVim(msgfile)
923" try
924" throw "a"
925" catch /a/
926" elseif
927" endtry
928endif
929if MESSAGES('E582', ":elseif without :if")
930 Xpath 16384 " X: 16384
931endif
932
933if ExtraVim(msgfile)
934" if 1
935" else
936" else
937" endif
938endif
939if MESSAGES('E583', "multiple :else")
940 Xpath 32768 " X: 32768
941endif
942
943if ExtraVim(msgfile)
944" if 1
945" else
946" elseif 1
947" endif
948endif
949if MESSAGES('E584', ":elseif after :else")
950 Xpath 65536 " X: 65536
951endif
952
953call delete(msgfile)
954unlet msgfile
955
956Xcheck 131071
957
958" Leave MESSAGES() for the next test.
959
960
961"-------------------------------------------------------------------------------
962" Test 54: Nesting errors: :while/:endwhile {{{1
963"
964" For nesting errors of :while conditionals the correct error messages
965" should be given.
966"
967" This test reuses the function MESSAGES() from the previous test.
968" This functions checks the messages in g:msgfile.
969"-------------------------------------------------------------------------------
970
971XpathINIT
972
973let msgfile = tempname()
974
975if ExtraVim(msgfile)
976" endwhile
977endif
978if MESSAGES('E588', ":endwhile without :while")
979 Xpath 1 " X: 1
980endif
981
982if ExtraVim(msgfile)
983" if 1
984" endwhile
985" endif
986endif
987if MESSAGES('E588', ":endwhile without :while")
988 Xpath 2 " X: 2
989endif
990
991if ExtraVim(msgfile)
992" while 1
993" if 1
994" endwhile
995endif
996if MESSAGES('E171', "Missing :endif")
997 Xpath 4 " X: 4
998endif
999
1000if ExtraVim(msgfile)
1001" try
1002" finally
1003" endwhile
1004" endtry
1005endif
1006if MESSAGES('E588', ":endwhile without :while")
1007 Xpath 8 " X: 8
1008endif
1009
1010if ExtraVim(msgfile)
1011" while 1
1012" try
1013" finally
1014" endwhile
1015endif
1016if MESSAGES('E600', "Missing :endtry")
1017 Xpath 16 " X: 16
1018endif
1019
1020if ExtraVim(msgfile)
1021" while 1
1022" if 1
1023" try
1024" finally
1025" endwhile
1026endif
1027if MESSAGES('E600', "Missing :endtry")
1028 Xpath 32 " X: 32
1029endif
1030
1031if ExtraVim(msgfile)
1032" while 1
1033" try
1034" finally
1035" if 1
1036" endwhile
1037endif
1038if MESSAGES('E171', "Missing :endif")
1039 Xpath 64 " X: 64
1040endif
1041
1042if ExtraVim(msgfile)
1043" try
1044" endwhile
1045" endtry
1046endif
1047if MESSAGES('E588', ":endwhile without :while")
1048 Xpath 128 " X: 128
1049endif
1050
1051if ExtraVim(msgfile)
1052" while 1
1053" try
1054" endwhile
1055" endtry
1056" endwhile
1057endif
1058if MESSAGES('E588', ":endwhile without :while")
1059 Xpath 256 " X: 256
1060endif
1061
1062if ExtraVim(msgfile)
1063" try
1064" throw "a"
1065" catch /a/
1066" endwhile
1067" endtry
1068endif
1069if MESSAGES('E588', ":endwhile without :while")
1070 Xpath 512 " X: 512
1071endif
1072
1073if ExtraVim(msgfile)
1074" while 1
1075" try
1076" throw "a"
1077" catch /a/
1078" endwhile
1079" endtry
1080" endwhile
1081endif
1082if MESSAGES('E588', ":endwhile without :while")
1083 Xpath 1024 " X: 1024
1084endif
1085
1086
1087call delete(msgfile)
1088unlet msgfile
1089
1090Xcheck 2047
1091
1092" Leave MESSAGES() for the next test.
1093
1094
1095"-------------------------------------------------------------------------------
1096" Test 55: Nesting errors: :continue/:break {{{1
1097"
1098" For nesting errors of :continue and :break commands the correct
1099" error messages should be given.
1100"
1101" This test reuses the function MESSAGES() from the previous test.
1102" This functions checks the messages in g:msgfile.
1103"-------------------------------------------------------------------------------
1104
1105XpathINIT
1106
1107let msgfile = tempname()
1108
1109if ExtraVim(msgfile)
1110" continue
1111endif
1112if MESSAGES('E586', ":continue without :while")
1113 Xpath 1 " X: 1
1114endif
1115
1116if ExtraVim(msgfile)
1117" if 1
1118" continue
1119" endif
1120endif
1121if MESSAGES('E586', ":continue without :while")
1122 Xpath 2 " X: 2
1123endif
1124
1125if ExtraVim(msgfile)
1126" try
1127" finally
1128" continue
1129" endtry
1130endif
1131if MESSAGES('E586', ":continue without :while")
1132 Xpath 4 " X: 4
1133endif
1134
1135if ExtraVim(msgfile)
1136" try
1137" continue
1138" endtry
1139endif
1140if MESSAGES('E586', ":continue without :while")
1141 Xpath 8 " X: 8
1142endif
1143
1144if ExtraVim(msgfile)
1145" try
1146" throw "a"
1147" catch /a/
1148" continue
1149" endtry
1150endif
1151if MESSAGES('E586', ":continue without :while")
1152 Xpath 16 " X: 16
1153endif
1154
1155if ExtraVim(msgfile)
1156" break
1157endif
1158if MESSAGES('E587', ":break without :while")
1159 Xpath 32 " X: 32
1160endif
1161
1162if ExtraVim(msgfile)
1163" if 1
1164" break
1165" endif
1166endif
1167if MESSAGES('E587', ":break without :while")
1168 Xpath 64 " X: 64
1169endif
1170
1171if ExtraVim(msgfile)
1172" try
1173" finally
1174" break
1175" endtry
1176endif
1177if MESSAGES('E587', ":break without :while")
1178 Xpath 128 " X: 128
1179endif
1180
1181if ExtraVim(msgfile)
1182" try
1183" break
1184" endtry
1185endif
1186if MESSAGES('E587', ":break without :while")
1187 Xpath 256 " X: 256
1188endif
1189
1190if ExtraVim(msgfile)
1191" try
1192" throw "a"
1193" catch /a/
1194" break
1195" endtry
1196endif
1197if MESSAGES('E587', ":break without :while")
1198 Xpath 512 " X: 512
1199endif
1200
1201call delete(msgfile)
1202unlet msgfile
1203
1204Xcheck 1023
1205
1206" Leave MESSAGES() for the next test.
1207
1208
1209"-------------------------------------------------------------------------------
1210" Test 56: Nesting errors: :endtry {{{1
1211"
1212" For nesting errors of :try conditionals the correct error messages
1213" should be given.
1214"
1215" This test reuses the function MESSAGES() from the previous test.
1216" This functions checks the messages in g:msgfile.
1217"-------------------------------------------------------------------------------
1218
1219XpathINIT
1220
1221let msgfile = tempname()
1222
1223if ExtraVim(msgfile)
1224" endtry
1225endif
1226if MESSAGES('E602', ":endtry without :try")
1227 Xpath 1 " X: 1
1228endif
1229
1230if ExtraVim(msgfile)
1231" if 1
1232" endtry
1233" endif
1234endif
1235if MESSAGES('E602', ":endtry without :try")
1236 Xpath 2 " X: 2
1237endif
1238
1239if ExtraVim(msgfile)
1240" while 1
1241" endtry
1242" endwhile
1243endif
1244if MESSAGES('E602', ":endtry without :try")
1245 Xpath 4 " X: 4
1246endif
1247
1248if ExtraVim(msgfile)
1249" try
1250" if 1
1251" endtry
1252endif
1253if MESSAGES('E171', "Missing :endif")
1254 Xpath 8 " X: 8
1255endif
1256
1257if ExtraVim(msgfile)
1258" try
1259" while 1
1260" endtry
1261endif
1262if MESSAGES('E170', "Missing :endwhile")
1263 Xpath 16 " X: 16
1264endif
1265
1266if ExtraVim(msgfile)
1267" try
1268" finally
1269" if 1
1270" endtry
1271endif
1272if MESSAGES('E171', "Missing :endif")
1273 Xpath 32 " X: 32
1274endif
1275
1276if ExtraVim(msgfile)
1277" try
1278" finally
1279" while 1
1280" endtry
1281endif
1282if MESSAGES('E170', "Missing :endwhile")
1283 Xpath 64 " X: 64
1284endif
1285
1286if ExtraVim(msgfile)
1287" try
1288" throw "a"
1289" catch /a/
1290" if 1
1291" endtry
1292endif
1293if MESSAGES('E171', "Missing :endif")
1294 Xpath 128 " X: 128
1295endif
1296
1297if ExtraVim(msgfile)
1298" try
1299" throw "a"
1300" catch /a/
1301" while 1
1302" endtry
1303endif
1304if MESSAGES('E170', "Missing :endwhile")
1305 Xpath 256 " X: 256
1306endif
1307
1308call delete(msgfile)
1309unlet msgfile
1310
1311delfunction MESSAGES
1312
1313Xcheck 511
1314
1315
1316"-------------------------------------------------------------------------------
1317" Test 57: v:exception and v:throwpoint for user exceptions {{{1
1318"
1319" v:exception evaluates to the value of the exception that was caught
1320" most recently and is not finished. (A caught exception is finished
1321" when the next ":catch", ":finally", or ":endtry" is reached.)
1322" v:throwpoint evaluates to the script/function name and line number
1323" where that exception has been thrown.
1324"-------------------------------------------------------------------------------
1325
1326XpathINIT
1327
1328function! FuncException()
1329 let g:exception = v:exception
1330endfunction
1331
1332function! FuncThrowpoint()
1333 let g:throwpoint = v:throwpoint
1334endfunction
1335
1336let scriptException = MakeScript("FuncException")
1337let scriptThrowPoint = MakeScript("FuncThrowpoint")
1338
1339command! CmdException let g:exception = v:exception
1340command! CmdThrowpoint let g:throwpoint = v:throwpoint
1341
1342XloopINIT! 1 2
1343
1344function! CHECK(n, exception, throwname, throwline)
1345 XloopNEXT
1346 let error = 0
1347 if v:exception != a:exception
1348 Xout a:n.": v:exception is" v:exception "instead of" a:exception
1349 let error = 1
1350 endif
1351 if v:throwpoint !~ a:throwname
1352 let name = escape(a:throwname, '\')
1353 Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" name
1354 let error = 1
1355 endif
1356 if v:throwpoint !~ a:throwline
1357 let line = escape(a:throwline, '\')
1358 Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
1359 let error = 1
1360 endif
1361 if error
1362 Xloop 1 " X: 0
1363 endif
1364endfunction
1365
1366function! T(arg, line)
1367 if a:line == 2
1368 throw a:arg " in line 2
1369 elseif a:line == 4
1370 throw a:arg " in line 4
1371 elseif a:line == 6
1372 throw a:arg " in line 6
1373 elseif a:line == 8
1374 throw a:arg " in line 8
1375 endif
1376endfunction
1377
1378function! G(arg, line)
1379 call T(a:arg, a:line)
1380endfunction
1381
1382function! F(arg, line)
1383 call G(a:arg, a:line)
1384endfunction
1385
1386let scriptT = MakeScript("T")
1387let scriptG = MakeScript("G", scriptT)
1388let scriptF = MakeScript("F", scriptG)
1389
1390try
1391 Xpath 32768 " X: 32768
1392 call F("oops", 2)
1393catch /.*/
1394 Xpath 65536 " X: 65536
1395 let exception = v:exception
1396 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02001397 call CHECK(1, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001398 exec "let exception = v:exception"
1399 exec "let throwpoint = v:throwpoint"
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02001400 call CHECK(2, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001401 CmdException
1402 CmdThrowpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02001403 call CHECK(3, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001404 call FuncException()
1405 call FuncThrowpoint()
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02001406 call CHECK(4, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001407 exec "source" scriptException
1408 exec "source" scriptThrowPoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02001409 call CHECK(5, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001410 try
1411 Xpath 131072 " X: 131072
1412 call G("arrgh", 4)
1413 catch /.*/
1414 Xpath 262144 " X: 262144
1415 let exception = v:exception
1416 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02001417 call CHECK(6, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001418 try
1419 Xpath 524288 " X: 524288
1420 let g:arg = "autsch"
1421 let g:line = 6
1422 exec "source" scriptF
1423 catch /.*/
1424 Xpath 1048576 " X: 1048576
1425 let exception = v:exception
1426 let throwpoint = v:throwpoint
1427 " Symbolic links in tempname()s are not resolved, whereas resolving
1428 " is done for v:throwpoint. Resolve the temporary file name for
1429 " scriptT, so that it can be matched against v:throwpoint.
1430 call CHECK(7, "autsch", resolve(scriptT), '\<6\>')
1431 finally
1432 Xpath 2097152 " X: 2097152
1433 let exception = v:exception
1434 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02001435 call CHECK(8, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001436 try
1437 Xpath 4194304 " X: 4194304
1438 let g:arg = "brrrr"
1439 let g:line = 8
1440 exec "source" scriptG
1441 catch /.*/
1442 Xpath 8388608 " X: 8388608
1443 let exception = v:exception
1444 let throwpoint = v:throwpoint
1445 " Resolve scriptT for matching it against v:throwpoint.
1446 call CHECK(9, "brrrr", resolve(scriptT), '\<8\>')
1447 finally
1448 Xpath 16777216 " X: 16777216
1449 let exception = v:exception
1450 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02001451 call CHECK(10, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001452 endtry
1453 Xpath 33554432 " X: 33554432
1454 let exception = v:exception
1455 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02001456 call CHECK(11, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001457 endtry
1458 Xpath 67108864 " X: 67108864
1459 let exception = v:exception
1460 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02001461 call CHECK(12, "arrgh", '\<G\[1]\.\.T\>', '\<4\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001462 finally
1463 Xpath 134217728 " X: 134217728
1464 let exception = v:exception
1465 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02001466 call CHECK(13, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001467 endtry
1468 Xpath 268435456 " X: 268435456
1469 let exception = v:exception
1470 let throwpoint = v:throwpoint
Bram Moolenaar0a777ab2015-09-25 17:56:50 +02001471 call CHECK(14, "oops", '\<F\[1]\.\.G\[1]\.\.T\>', '\<2\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001472finally
1473 Xpath 536870912 " X: 536870912
1474 let exception = v:exception
1475 let throwpoint = v:throwpoint
1476 call CHECK(15, "", '^$', '^$')
1477endtry
1478
1479Xpath 1073741824 " X: 1073741824
1480
1481unlet exception throwpoint
1482delfunction FuncException
1483delfunction FuncThrowpoint
1484call delete(scriptException)
1485call delete(scriptThrowPoint)
1486unlet scriptException scriptThrowPoint
1487delcommand CmdException
1488delcommand CmdThrowpoint
1489delfunction T
1490delfunction G
1491delfunction F
1492call delete(scriptT)
1493call delete(scriptG)
1494call delete(scriptF)
1495unlet scriptT scriptG scriptF
1496
1497Xcheck 2147450880
1498
1499
1500"-------------------------------------------------------------------------------
1501"
1502" Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1
1503"
1504" v:exception and v:throwpoint work also for error and interrupt
1505" exceptions.
1506"-------------------------------------------------------------------------------
1507
1508XpathINIT
1509
1510if ExtraVim()
1511
1512 function! T(line)
1513 if a:line == 2
1514 delfunction T " error (function in use) in line 2
1515 elseif a:line == 4
1516 let dummy = 0 " INTERRUPT1 - interrupt in line 4
1517 endif
1518 endfunction
1519
1520 while 1
1521 try
1522 Xpath 1 " X: 1
1523 let caught = 0
1524 call T(2)
1525 catch /.*/
1526 let caught = 1
1527 if v:exception !~ 'Vim(delfunction):'
1528 Xpath 2 " X: 0
1529 endif
1530 if v:throwpoint !~ '\<T\>'
1531 Xpath 4 " X: 0
1532 endif
1533 if v:throwpoint !~ '\<2\>'
1534 Xpath 8 " X: 0
1535 endif
1536 finally
1537 Xpath 16 " X: 16
1538 if caught || $VIMNOERRTHROW
1539 Xpath 32 " X: 32
1540 endif
1541 if v:exception != ""
1542 Xpath 64 " X: 0
1543 endif
1544 if v:throwpoint != ""
1545 Xpath 128 " X: 0
1546 endif
1547 break " discard error for $VIMNOERRTHROW
1548 endtry
1549 endwhile
1550
1551 Xpath 256 " X: 256
1552 if v:exception != ""
1553 Xpath 512 " X: 0
1554 endif
1555 if v:throwpoint != ""
1556 Xpath 1024 " X: 0
1557 endif
1558
1559 while 1
1560 try
1561 Xpath 2048 " X: 2048
1562 let caught = 0
1563 call T(4)
1564 catch /.*/
1565 let caught = 1
1566 if v:exception != 'Vim:Interrupt'
1567 Xpath 4096 " X: 0
1568 endif
1569 if v:throwpoint !~ '\<T\>'
1570 Xpath 8192 " X: 0
1571 endif
1572 if v:throwpoint !~ '\<4\>'
1573 Xpath 16384 " X: 0
1574 endif
1575 finally
1576 Xpath 32768 " X: 32768
1577 if caught || $VIMNOINTTHROW
1578 Xpath 65536 " X: 65536
1579 endif
1580 if v:exception != ""
1581 Xpath 131072 " X: 0
1582 endif
1583 if v:throwpoint != ""
1584 Xpath 262144 " X: 0
1585 endif
1586 break " discard error for $VIMNOERRTHROW
1587 endtry
1588 endwhile
1589
1590 Xpath 524288 " X: 524288
1591 if v:exception != ""
1592 Xpath 1048576 " X: 0
1593 endif
1594 if v:throwpoint != ""
1595 Xpath 2097152 " X: 0
1596 endif
1597
1598endif
1599
1600Xcheck 624945
1601
1602
1603"-------------------------------------------------------------------------------
1604"
1605" Test 59: v:exception and v:throwpoint when discarding exceptions {{{1
1606"
1607" When a :catch clause is left by a ":break" etc or an error or
1608" interrupt exception, v:exception and v:throwpoint are reset. They
1609" are not affected by an exception that is discarded before being
1610" caught.
1611"-------------------------------------------------------------------------------
1612
1613XpathINIT
1614
1615if ExtraVim()
1616
1617 XloopINIT! 1 2
1618
1619 let sfile = expand("<sfile>")
1620
1621 function! LineNumber()
1622 return substitute(substitute(v:throwpoint, g:sfile, '', ""),
1623 \ '\D*\(\d*\).*', '\1', "")
1624 endfunction
1625
1626 command! -nargs=1 SetLineNumber
1627 \ try | throw "line" | catch /.*/ | let <args> = LineNumber() | endtry
1628
1629 " Check v:exception/v:throwpoint against second/fourth parameter if
1630 " specified, check for being empty else.
1631 function! CHECK(n, ...)
1632 XloopNEXT
1633 let exception = a:0 != 0 ? a:1 : "" " second parameter (optional)
1634 let emsg = a:0 != 0 ? a:2 : "" " third parameter (optional)
1635 let line = a:0 != 0 ? a:3 : 0 " fourth parameter (optional)
1636 let error = 0
1637 if emsg != ""
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00001638 " exception is the error number, emsg the English error message text
Bram Moolenaar071d4272004-06-13 20:20:40 +00001639 if exception !~ '^E\d\+$'
1640 Xout "TODO: Add message number for:" emsg
1641 elseif v:lang == "C" || v:lang =~ '^[Ee]n'
1642 if exception == "E492" && emsg == "Not an editor command"
1643 let exception = '^Vim:' . exception . ': ' . emsg
1644 else
1645 let exception = '^Vim(\a\+):' . exception . ': ' . emsg
1646 endif
1647 else
1648 if exception == "E492"
1649 let exception = '^Vim:' . exception
1650 else
1651 let exception = '^Vim(\a\+):' . exception
1652 endif
1653 endif
1654 endif
1655 if exception == "" && v:exception != ""
1656 Xout a:n.": v:exception is set:" v:exception
1657 let error = 1
1658 elseif exception != "" && v:exception !~ exception
1659 Xout a:n.": v:exception (".v:exception.") does not match" exception
1660 let error = 1
1661 endif
1662 if line == 0 && v:throwpoint != ""
1663 Xout a:n.": v:throwpoint is set:" v:throwpoint
1664 let error = 1
1665 elseif line != 0 && v:throwpoint !~ '\<' . line . '\>'
1666 Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line
1667 let error = 1
1668 endif
1669 if !error
1670 Xloop 1 " X: 2097151
1671 endif
1672 endfunction
1673
1674 while 1
1675 try
1676 throw "x1"
1677 catch /.*/
1678 break
1679 endtry
1680 endwhile
1681 call CHECK(1)
1682
1683 while 1
1684 try
1685 throw "x2"
1686 catch /.*/
1687 break
1688 finally
1689 call CHECK(2)
1690 endtry
1691 break
1692 endwhile
1693 call CHECK(3)
1694
1695 while 1
1696 try
1697 let errcaught = 0
1698 try
1699 try
1700 throw "x3"
1701 catch /.*/
1702 SetLineNumber line_before_error
1703 asdf
1704 endtry
1705 catch /.*/
1706 let errcaught = 1
1707 call CHECK(4, 'E492', "Not an editor command",
1708 \ line_before_error + 1)
1709 endtry
1710 finally
1711 if !errcaught && $VIMNOERRTHROW
1712 call CHECK(4)
1713 endif
1714 break " discard error for $VIMNOERRTHROW
1715 endtry
1716 endwhile
1717 call CHECK(5)
1718
1719 Xpath 2097152 " X: 2097152
1720
1721 while 1
1722 try
1723 let intcaught = 0
1724 try
1725 try
1726 throw "x4"
1727 catch /.*/
1728 SetLineNumber two_lines_before_interrupt
1729 "INTERRUPT
1730 let dummy = 0
1731 endtry
1732 catch /.*/
1733 let intcaught = 1
1734 call CHECK(6, "Vim:Interrupt", '',
1735 \ two_lines_before_interrupt + 2)
1736 endtry
1737 finally
1738 if !intcaught && $VIMNOINTTHROW
1739 call CHECK(6)
1740 endif
1741 break " discard interrupt for $VIMNOINTTHROW
1742 endtry
1743 endwhile
1744 call CHECK(7)
1745
1746 Xpath 4194304 " X: 4194304
1747
1748 while 1
1749 try
1750 let errcaught = 0
1751 try
1752 try
1753" if 1
1754 SetLineNumber line_before_throw
1755 throw "x5"
1756 " missing endif
1757 catch /.*/
1758 Xpath 8388608 " X: 0
1759 endtry
1760 catch /.*/
1761 let errcaught = 1
1762 call CHECK(8, 'E171', "Missing :endif", line_before_throw + 3)
1763 endtry
1764 finally
1765 if !errcaught && $VIMNOERRTHROW
1766 call CHECK(8)
1767 endif
1768 break " discard error for $VIMNOERRTHROW
1769 endtry
1770 endwhile
1771 call CHECK(9)
1772
1773 Xpath 16777216 " X: 16777216
1774
1775 try
1776 while 1
1777 try
1778 throw "x6"
1779 finally
1780 break
1781 endtry
1782 break
1783 endwhile
1784 catch /.*/
1785 Xpath 33554432 " X: 0
1786 endtry
1787 call CHECK(10)
1788
1789 try
1790 while 1
1791 try
1792 throw "x7"
1793 finally
1794 break
1795 endtry
1796 break
1797 endwhile
1798 catch /.*/
1799 Xpath 67108864 " X: 0
1800 finally
1801 call CHECK(11)
1802 endtry
1803 call CHECK(12)
1804
1805 while 1
1806 try
1807 let errcaught = 0
1808 try
1809 try
1810 throw "x8"
1811 finally
1812 SetLineNumber line_before_error
1813 asdf
1814 endtry
1815 catch /.*/
1816 let errcaught = 1
1817 call CHECK(13, 'E492', "Not an editor command",
1818 \ line_before_error + 1)
1819 endtry
1820 finally
1821 if !errcaught && $VIMNOERRTHROW
1822 call CHECK(13)
1823 endif
1824 break " discard error for $VIMNOERRTHROW
1825 endtry
1826 endwhile
1827 call CHECK(14)
1828
1829 Xpath 134217728 " X: 134217728
1830
1831 while 1
1832 try
1833 let intcaught = 0
1834 try
1835 try
1836 throw "x9"
1837 finally
1838 SetLineNumber two_lines_before_interrupt
1839 "INTERRUPT
1840 endtry
1841 catch /.*/
1842 let intcaught = 1
1843 call CHECK(15, "Vim:Interrupt", '',
1844 \ two_lines_before_interrupt + 2)
1845 endtry
1846 finally
1847 if !intcaught && $VIMNOINTTHROW
1848 call CHECK(15)
1849 endif
1850 break " discard interrupt for $VIMNOINTTHROW
1851 endtry
1852 endwhile
1853 call CHECK(16)
1854
1855 Xpath 268435456 " X: 268435456
1856
1857 while 1
1858 try
1859 let errcaught = 0
1860 try
1861 try
1862" if 1
1863 SetLineNumber line_before_throw
1864 throw "x10"
1865 " missing endif
1866 finally
1867 call CHECK(17)
1868 endtry
1869 catch /.*/
1870 let errcaught = 1
1871 call CHECK(18, 'E171', "Missing :endif", line_before_throw + 3)
1872 endtry
1873 finally
1874 if !errcaught && $VIMNOERRTHROW
1875 call CHECK(18)
1876 endif
1877 break " discard error for $VIMNOERRTHROW
1878 endtry
1879 endwhile
1880 call CHECK(19)
1881
1882 Xpath 536870912 " X: 536870912
1883
1884 while 1
1885 try
1886 let errcaught = 0
1887 try
1888 try
1889" if 1
1890 SetLineNumber line_before_throw
1891 throw "x11"
1892 " missing endif
1893 endtry
1894 catch /.*/
1895 let errcaught = 1
1896 call CHECK(20, 'E171', "Missing :endif", line_before_throw + 3)
1897 endtry
1898 finally
1899 if !errcaught && $VIMNOERRTHROW
1900 call CHECK(20)
1901 endif
1902 break " discard error for $VIMNOERRTHROW
1903 endtry
1904 endwhile
1905 call CHECK(21)
1906
1907 Xpath 1073741824 " X: 1073741824
1908
1909endif
1910
1911Xcheck 2038431743
1912
1913
1914"-------------------------------------------------------------------------------
1915"
1916" Test 60: (Re)throwing v:exception; :echoerr. {{{1
1917"
1918" A user exception can be rethrown after catching by throwing
1919" v:exception. An error or interrupt exception cannot be rethrown
1920" because Vim exceptions cannot be faked. A Vim exception using the
1921" value of v:exception can, however, be triggered by the :echoerr
1922" command.
1923"-------------------------------------------------------------------------------
1924
1925XpathINIT
1926
1927try
1928 try
1929 Xpath 1 " X: 1
1930 throw "oops"
1931 catch /oops/
1932 Xpath 2 " X: 2
1933 throw v:exception " rethrow user exception
1934 catch /.*/
1935 Xpath 4 " X: 0
1936 endtry
1937catch /^oops$/ " catches rethrown user exception
1938 Xpath 8 " X: 8
1939catch /.*/
1940 Xpath 16 " X: 0
1941endtry
1942
1943function! F()
1944 try
1945 let caught = 0
1946 try
1947 Xpath 32 " X: 32
1948 write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e
1949 Xpath 64 " X: 0
1950 Xout "did_emsg was reset before executing " .
1951 \ "BufWritePost autocommands."
1952 catch /^Vim(write):/
1953 let caught = 1
1954 throw v:exception " throw error: cannot fake Vim exception
1955 catch /.*/
1956 Xpath 128 " X: 0
1957 finally
1958 Xpath 256 " X: 256
1959 if !caught && !$VIMNOERRTHROW
1960 Xpath 512 " X: 0
1961 endif
1962 endtry
1963 catch /^Vim(throw):/ " catches throw error
1964 let caught = caught + 1
1965 catch /.*/
1966 Xpath 1024 " X: 0
1967 finally
1968 Xpath 2048 " X: 2048
1969 if caught != 2
1970 if !caught && !$VIMNOERRTHROW
1971 Xpath 4096 " X: 0
1972 elseif caught
1973 Xpath 8192 " X: 0
1974 endif
1975 return | " discard error for $VIMNOERRTHROW
1976 endif
1977 endtry
1978endfunction
1979
1980call F()
1981delfunction F
1982
1983function! G()
1984 try
1985 let caught = 0
1986 try
1987 Xpath 16384 " X: 16384
1988 asdf
1989 catch /^Vim/ " catch error exception
1990 let caught = 1
1991 " Trigger Vim error exception with value specified after :echoerr
1992 let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
1993 echoerr value
1994 catch /.*/
1995 Xpath 32768 " X: 0
1996 finally
1997 Xpath 65536 " X: 65536
1998 if !caught
1999 if !$VIMNOERRTHROW
2000 Xpath 131072 " X: 0
2001 else
2002 let value = "Error"
2003 echoerr value
2004 endif
2005 endif
2006 endtry
2007 catch /^Vim(echoerr):/
2008 let caught = caught + 1
2009 if v:exception !~ value
2010 Xpath 262144 " X: 0
2011 endif
2012 catch /.*/
2013 Xpath 524288 " X: 0
2014 finally
2015 Xpath 1048576 " X: 1048576
2016 if caught != 2
2017 if !caught && !$VIMNOERRTHROW
2018 Xpath 2097152 " X: 0
2019 elseif caught
2020 Xpath 4194304 " X: 0
2021 endif
2022 return | " discard error for $VIMNOERRTHROW
2023 endif
2024 endtry
2025endfunction
2026
2027call G()
2028delfunction G
2029
2030unlet! value caught
2031
2032if ExtraVim()
2033 try
2034 let errcaught = 0
2035 try
2036 Xpath 8388608 " X: 8388608
2037 let intcaught = 0
2038 "INTERRUPT
2039 catch /^Vim:/ " catch interrupt exception
2040 let intcaught = 1
2041 " Trigger Vim error exception with value specified after :echoerr
2042 echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "")
2043 catch /.*/
2044 Xpath 16777216 " X: 0
2045 finally
2046 Xpath 33554432 " X: 33554432
2047 if !intcaught
2048 if !$VIMNOINTTHROW
2049 Xpath 67108864 " X: 0
2050 else
2051 echoerr "Interrupt"
2052 endif
2053 endif
2054 endtry
2055 catch /^Vim(echoerr):/
2056 let errcaught = 1
2057 if v:exception !~ "Interrupt"
2058 Xpath 134217728 " X: 0
2059 endif
2060 finally
2061 Xpath 268435456 " X: 268435456
2062 if !errcaught && !$VIMNOERRTHROW
2063 Xpath 536870912 " X: 0
2064 endif
2065 endtry
2066endif
2067
2068Xcheck 311511339
2069
2070
2071"-------------------------------------------------------------------------------
2072" Test 61: Catching interrupt exceptions {{{1
2073"
2074" When an interrupt occurs inside a :try/:endtry region, an
2075" interrupt exception is thrown and can be caught. Its value is
2076" "Vim:Interrupt". If the interrupt occurs after an error or a :throw
2077" but before a matching :catch is reached, all following :catches of
2078" that try block are ignored, but the interrupt exception can be
2079" caught by the next surrounding try conditional. An interrupt is
2080" ignored when there is a previous interrupt that has not been caught
2081" or causes a :finally clause to be executed.
2082"-------------------------------------------------------------------------------
2083
2084XpathINIT
2085
2086if ExtraVim()
2087
2088 while 1
2089 try
2090 try
2091 Xpath 1 " X: 1
2092 let caught = 0
2093 "INTERRUPT
2094 Xpath 2 " X: 0
2095 catch /^Vim:Interrupt$/
2096 let caught = 1
2097 finally
2098 Xpath 4 " X: 4
2099 if caught || $VIMNOINTTHROW
2100 Xpath 8 " X: 8
2101 endif
2102 endtry
2103 catch /.*/
2104 Xpath 16 " X: 0
2105 Xout v:exception "in" v:throwpoint
2106 finally
2107 break " discard interrupt for $VIMNOINTTHROW
2108 endtry
2109 endwhile
2110
2111 while 1
2112 try
2113 try
2114 let caught = 0
2115 try
2116 Xpath 32 " X: 32
2117 asdf
2118 Xpath 64 " X: 0
2119 catch /do_not_catch/
2120 Xpath 128 " X: 0
2121 catch /.*/ "INTERRUPT - throw interrupt if !$VIMNOERRTHROW
2122 Xpath 256 " X: 0
2123 catch /.*/
2124 Xpath 512 " X: 0
2125 finally "INTERRUPT - throw interrupt if $VIMNOERRTHROW
2126 Xpath 1024 " X: 1024
2127 endtry
2128 catch /^Vim:Interrupt$/
2129 let caught = 1
2130 finally
2131 Xpath 2048 " X: 2048
2132 if caught || $VIMNOINTTHROW
2133 Xpath 4096 " X: 4096
2134 endif
2135 endtry
2136 catch /.*/
2137 Xpath 8192 " X: 0
2138 Xout v:exception "in" v:throwpoint
2139 finally
2140 break " discard interrupt for $VIMNOINTTHROW
2141 endtry
2142 endwhile
2143
2144 while 1
2145 try
2146 try
2147 let caught = 0
2148 try
2149 Xpath 16384 " X: 16384
2150 throw "x"
2151 Xpath 32768 " X: 0
2152 catch /do_not_catch/
2153 Xpath 65536 " X: 0
2154 catch /x/ "INTERRUPT
2155 Xpath 131072 " X: 0
2156 catch /.*/
2157 Xpath 262144 " X: 0
2158 endtry
2159 catch /^Vim:Interrupt$/
2160 let caught = 1
2161 finally
2162 Xpath 524288 " X: 524288
2163 if caught || $VIMNOINTTHROW
2164 Xpath 1048576 " X: 1048576
2165 endif
2166 endtry
2167 catch /.*/
2168 Xpath 2097152 " X: 0
2169 Xout v:exception "in" v:throwpoint
2170 finally
2171 break " discard interrupt for $VIMNOINTTHROW
2172 endtry
2173 endwhile
2174
2175 while 1
2176 try
2177 let caught = 0
2178 try
2179 Xpath 4194304 " X: 4194304
2180 "INTERRUPT
2181 Xpath 8388608 " X: 0
2182 catch /do_not_catch/ "INTERRUPT
2183 Xpath 16777216 " X: 0
2184 catch /^Vim:Interrupt$/
2185 let caught = 1
2186 finally
2187 Xpath 33554432 " X: 33554432
2188 if caught || $VIMNOINTTHROW
2189 Xpath 67108864 " X: 67108864
2190 endif
2191 endtry
2192 catch /.*/
2193 Xpath 134217728 " X: 0
2194 Xout v:exception "in" v:throwpoint
2195 finally
2196 break " discard interrupt for $VIMNOINTTHROW
2197 endtry
2198 endwhile
2199
2200 Xpath 268435456 " X: 268435456
2201
2202endif
2203
2204Xcheck 374889517
2205
2206
2207"-------------------------------------------------------------------------------
2208" Test 62: Catching error exceptions {{{1
2209"
2210" An error inside a :try/:endtry region is converted to an exception
2211" and can be caught. The error exception has a "Vim(cmdname):" prefix
2212" where cmdname is the name of the failing command, or a "Vim:" prefix
2213" if no command name is known. The "Vim" prefixes cannot be faked.
2214"-------------------------------------------------------------------------------
2215
2216XpathINIT
2217
2218function! MSG(enr, emsg)
2219 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
2220 if a:enr == ""
2221 Xout "TODO: Add message number for:" a:emsg
2222 let v:errmsg = ":" . v:errmsg
2223 endif
2224 let match = 1
2225 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
2226 let match = 0
2227 if v:errmsg == ""
2228 Xout "Message missing."
2229 else
2230 let v:errmsg = escape(v:errmsg, '"')
2231 Xout "Unexpected message:" v:errmsg
2232 endif
2233 endif
2234 return match
2235endfunction
2236
2237while 1
2238 try
2239 try
2240 let caught = 0
2241 unlet novar
2242 catch /^Vim(unlet):/
2243 let caught = 1
2244 let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "")
2245 finally
2246 Xpath 1 " X: 1
2247 if !caught && !$VIMNOERRTHROW
2248 Xpath 2 " X: 0
2249 endif
2250 if !MSG('E108', "No such variable")
2251 Xpath 4 " X: 0
2252 endif
2253 endtry
2254 catch /.*/
2255 Xpath 8 " X: 0
2256 Xout v:exception "in" v:throwpoint
2257 finally
2258 break " discard error for $VIMNOERRTHROW
2259 endtry
2260endwhile
2261
2262while 1
2263 try
2264 try
2265 let caught = 0
2266 throw novar " error in :throw
2267 catch /^Vim(throw):/
2268 let caught = 1
2269 let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
2270 finally
2271 Xpath 16 " X: 16
2272 if !caught && !$VIMNOERRTHROW
2273 Xpath 32 " X: 0
2274 endif
2275 if caught ? !MSG('E121', "Undefined variable")
2276 \ : !MSG('E15', "Invalid expression")
2277 Xpath 64 " X: 0
2278 endif
2279 endtry
2280 catch /.*/
2281 Xpath 128 " X: 0
2282 Xout v:exception "in" v:throwpoint
2283 finally
2284 break " discard error for $VIMNOERRTHROW
2285 endtry
2286endwhile
2287
2288while 1
2289 try
2290 try
2291 let caught = 0
2292 throw "Vim:faked" " error: cannot fake Vim exception
2293 catch /^Vim(throw):/
2294 let caught = 1
2295 let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "")
2296 finally
2297 Xpath 256 " X: 256
2298 if !caught && !$VIMNOERRTHROW
2299 Xpath 512 " X: 0
2300 endif
2301 if !MSG('E608', "Cannot :throw exceptions with 'Vim' prefix")
2302 Xpath 1024 " X: 0
2303 endif
2304 endtry
2305 catch /.*/
2306 Xpath 2048 " X: 0
2307 Xout v:exception "in" v:throwpoint
2308 finally
2309 break " discard error for $VIMNOERRTHROW
2310 endtry
2311endwhile
2312
2313function! F()
2314 while 1
2315 " Missing :endwhile
2316endfunction
2317
2318while 1
2319 try
2320 try
2321 let caught = 0
2322 call F()
2323 catch /^Vim(endfunction):/
2324 let caught = 1
2325 let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "")
2326 finally
2327 Xpath 4096 " X: 4096
2328 if !caught && !$VIMNOERRTHROW
2329 Xpath 8192 " X: 0
2330 endif
2331 if !MSG('E170', "Missing :endwhile")
2332 Xpath 16384 " X: 0
2333 endif
2334 endtry
2335 catch /.*/
2336 Xpath 32768 " X: 0
2337 Xout v:exception "in" v:throwpoint
2338 finally
2339 break " discard error for $VIMNOERRTHROW
2340 endtry
2341endwhile
2342
2343while 1
2344 try
2345 try
2346 let caught = 0
2347 ExecAsScript F
2348 catch /^Vim:/
2349 let caught = 1
2350 let v:errmsg = substitute(v:exception, '^Vim:', '', "")
2351 finally
2352 Xpath 65536 " X: 65536
2353 if !caught && !$VIMNOERRTHROW
2354 Xpath 131072 " X: 0
2355 endif
2356 if !MSG('E170', "Missing :endwhile")
2357 Xpath 262144 " X: 0
2358 endif
2359 endtry
2360 catch /.*/
2361 Xpath 524288 " X: 0
2362 Xout v:exception "in" v:throwpoint
2363 finally
2364 break " discard error for $VIMNOERRTHROW
2365 endtry
2366endwhile
2367
2368function! G()
2369 call G()
2370endfunction
2371
2372while 1
2373 try
2374 let mfd_save = &mfd
2375 set mfd=3
2376 try
2377 let caught = 0
2378 call G()
2379 catch /^Vim(call):/
2380 let caught = 1
2381 let v:errmsg = substitute(v:exception, '^Vim(call):', '', "")
2382 finally
2383 Xpath 1048576 " X: 1048576
2384 if !caught && !$VIMNOERRTHROW
2385 Xpath 2097152 " X: 0
2386 endif
2387 if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
2388 Xpath 4194304 " X: 0
2389 endif
2390 endtry
2391 catch /.*/
2392 Xpath 8388608 " X: 0
2393 Xout v:exception "in" v:throwpoint
2394 finally
2395 let &mfd = mfd_save
2396 break " discard error for $VIMNOERRTHROW
2397 endtry
2398endwhile
2399
2400function! H()
2401 return H()
2402endfunction
2403
2404while 1
2405 try
2406 let mfd_save = &mfd
2407 set mfd=3
2408 try
2409 let caught = 0
2410 call H()
2411 catch /^Vim(return):/
2412 let caught = 1
2413 let v:errmsg = substitute(v:exception, '^Vim(return):', '', "")
2414 finally
2415 Xpath 16777216 " X: 16777216
2416 if !caught && !$VIMNOERRTHROW
2417 Xpath 33554432 " X: 0
2418 endif
2419 if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'")
2420 Xpath 67108864 " X: 0
2421 endif
2422 endtry
2423 catch /.*/
2424 Xpath 134217728 " X: 0
2425 Xout v:exception "in" v:throwpoint
2426 finally
2427 let &mfd = mfd_save
2428 break " discard error for $VIMNOERRTHROW
2429 endtry
2430endwhile
2431
2432unlet! caught mfd_save
2433delfunction F
2434delfunction G
2435delfunction H
2436Xpath 268435456 " X: 268435456
2437
2438Xcheck 286331153
2439
2440" Leave MSG() for the next test.
2441
2442
2443"-------------------------------------------------------------------------------
2444" Test 63: Suppressing error exceptions by :silent!. {{{1
2445"
2446" A :silent! command inside a :try/:endtry region suppresses the
2447" conversion of errors to an exception and the immediate abortion on
2448" error. When the commands executed by the :silent! themselves open
2449" a new :try/:endtry region, conversion of errors to exception and
2450" immediate abortion is switched on again - until the next :silent!
2451" etc. The :silent! has the effect of setting v:errmsg to the error
2452" message text (without displaying it) and continuing with the next
2453" script line.
2454"
2455" When a command triggering autocommands is executed by :silent!
2456" inside a :try/:endtry, the autocommand execution is not suppressed
2457" on error.
2458"
2459" This test reuses the function MSG() from the previous test.
2460"-------------------------------------------------------------------------------
2461
2462XpathINIT
2463
2464XloopINIT! 1 4
2465
2466let taken = ""
2467
2468function! S(n) abort
2469 XloopNEXT
2470 let g:taken = g:taken . "E" . a:n
2471 let v:errmsg = ""
2472 exec "asdf" . a:n
2473
2474 " Check that ":silent!" continues:
2475 Xloop 1
2476
2477 " Check that ":silent!" sets "v:errmsg":
2478 if MSG('E492', "Not an editor command")
2479 Xloop 2
2480 endif
2481endfunction
2482
2483function! Foo()
2484 while 1
2485 try
2486 try
2487 let caught = 0
2488 " This is not silent:
2489 call S(3) " X: 0 * 16
2490 catch /^Vim:/
2491 let caught = 1
2492 let errmsg3 = substitute(v:exception, '^Vim:', '', "")
2493 silent! call S(4) " X: 3 * 64
2494 finally
2495 if !caught
2496 let errmsg3 = v:errmsg
2497 " Do call S(4) here if not executed in :catch.
2498 silent! call S(4)
2499 endif
2500 Xpath 1048576 " X: 1048576
2501 if !caught && !$VIMNOERRTHROW
2502 Xpath 2097152 " X: 0
2503 endif
2504 let v:errmsg = errmsg3
2505 if !MSG('E492', "Not an editor command")
2506 Xpath 4194304 " X: 0
2507 endif
2508 silent! call S(5) " X: 3 * 256
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002509 " Break out of try conditionals that cover ":silent!". This also
Bram Moolenaar071d4272004-06-13 20:20:40 +00002510 " discards the aborting error when $VIMNOERRTHROW is non-zero.
2511 break
2512 endtry
2513 catch /.*/
2514 Xpath 8388608 " X: 0
2515 Xout v:exception "in" v:throwpoint
2516 endtry
2517 endwhile
2518 " This is a double ":silent!" (see caller).
2519 silent! call S(6) " X: 3 * 1024
2520endfunction
2521
2522function! Bar()
2523 try
2524 silent! call S(2) " X: 3 * 4
2525 " X: 3 * 4096
2526 silent! execute "call Foo() | call S(7)"
2527 silent! call S(8) " X: 3 * 16384
2528 endtry " normal end of try cond that covers ":silent!"
2529 " This has a ":silent!" from the caller:
2530 call S(9) " X: 3 * 65536
2531endfunction
2532
2533silent! call S(1) " X: 3 * 1
2534silent! call Bar()
2535silent! call S(10) " X: 3 * 262144
2536
2537let expected = "E1E2E3E4E5E6E7E8E9E10"
2538if taken != expected
2539 Xpath 16777216 " X: 0
2540 Xout "'taken' is" taken "instead of" expected
2541endif
2542
2543augroup TMP
2544 autocmd BufWritePost * Xpath 33554432 " X: 33554432
2545augroup END
2546
2547Xpath 67108864 " X: 67108864
2548write /i/m/p/o/s/s/i/b/l/e
2549Xpath 134217728 " X: 134217728
2550
2551autocmd! TMP
2552unlet! caught errmsg3 taken expected
2553delfunction S
2554delfunction Foo
2555delfunction Bar
2556delfunction MSG
2557
2558Xcheck 236978127
2559
2560
2561"-------------------------------------------------------------------------------
2562" Test 64: Error exceptions after error, interrupt or :throw {{{1
2563"
2564" When an error occurs after an interrupt or a :throw but before
2565" a matching :catch is reached, all following :catches of that try
2566" block are ignored, but the error exception can be caught by the next
2567" surrounding try conditional. Any previous error exception is
2568" discarded. An error is ignored when there is a previous error that
2569" has not been caught.
2570"-------------------------------------------------------------------------------
2571
2572XpathINIT
2573
2574if ExtraVim()
2575
2576 while 1
2577 try
2578 try
2579 Xpath 1 " X: 1
2580 let caught = 0
2581 while 1
2582" if 1
2583 " Missing :endif
2584 endwhile " throw error exception
2585 catch /^Vim(/
2586 let caught = 1
2587 finally
2588 Xpath 2 " X: 2
2589 if caught || $VIMNOERRTHROW
2590 Xpath 4 " X: 4
2591 endif
2592 endtry
2593 catch /.*/
2594 Xpath 8 " X: 0
2595 Xout v:exception "in" v:throwpoint
2596 finally
2597 break " discard error for $VIMNOERRTHROW
2598 endtry
2599 endwhile
2600
2601 while 1
2602 try
2603 try
2604 Xpath 16 " X: 16
2605 let caught = 0
2606 try
2607" if 1
2608 " Missing :endif
2609 catch /.*/ " throw error exception
2610 Xpath 32 " X: 0
2611 catch /.*/
2612 Xpath 64 " X: 0
2613 endtry
2614 catch /^Vim(/
2615 let caught = 1
2616 finally
2617 Xpath 128 " X: 128
2618 if caught || $VIMNOERRTHROW
2619 Xpath 256 " X: 256
2620 endif
2621 endtry
2622 catch /.*/
2623 Xpath 512 " X: 0
2624 Xout v:exception "in" v:throwpoint
2625 finally
2626 break " discard error for $VIMNOERRTHROW
2627 endtry
2628 endwhile
2629
2630 while 1
2631 try
2632 try
2633 let caught = 0
2634 try
2635 Xpath 1024 " X: 1024
2636 "INTERRUPT
2637 catch /do_not_catch/
2638 Xpath 2048 " X: 0
2639" if 1
2640 " Missing :endif
2641 catch /.*/ " throw error exception
2642 Xpath 4096 " X: 0
2643 catch /.*/
2644 Xpath 8192 " X: 0
2645 endtry
2646 catch /^Vim(/
2647 let caught = 1
2648 finally
2649 Xpath 16384 " X: 16384
2650 if caught || $VIMNOERRTHROW
2651 Xpath 32768 " X: 32768
2652 endif
2653 endtry
2654 catch /.*/
2655 Xpath 65536 " X: 0
2656 Xout v:exception "in" v:throwpoint
2657 finally
2658 break " discard error for $VIMNOERRTHROW
2659 endtry
2660 endwhile
2661
2662 while 1
2663 try
2664 try
2665 let caught = 0
2666 try
2667 Xpath 131072 " X: 131072
2668 throw "x"
2669 catch /do_not_catch/
2670 Xpath 262144 " X: 0
2671" if 1
2672 " Missing :endif
2673 catch /x/ " throw error exception
2674 Xpath 524288 " X: 0
2675 catch /.*/
2676 Xpath 1048576 " X: 0
2677 endtry
2678 catch /^Vim(/
2679 let caught = 1
2680 finally
2681 Xpath 2097152 " X: 2097152
2682 if caught || $VIMNOERRTHROW
2683 Xpath 4194304 " X: 4194304
2684 endif
2685 endtry
2686 catch /.*/
2687 Xpath 8388608 " X: 0
2688 Xout v:exception "in" v:throwpoint
2689 finally
2690 break " discard error for $VIMNOERRTHROW
2691 endtry
2692 endwhile
2693
2694 while 1
2695 try
2696 try
2697 let caught = 0
2698 Xpath 16777216 " X: 16777216
2699" endif " :endif without :if; throw error exception
2700" if 1
2701 " Missing :endif
2702 catch /do_not_catch/ " ignore new error
2703 Xpath 33554432 " X: 0
2704 catch /^Vim(endif):/
2705 let caught = 1
2706 catch /^Vim(/
2707 Xpath 67108864 " X: 0
2708 finally
2709 Xpath 134217728 " X: 134217728
2710 if caught || $VIMNOERRTHROW
2711 Xpath 268435456 " X: 268435456
2712 endif
2713 endtry
2714 catch /.*/
2715 Xpath 536870912 " X: 0
2716 Xout v:exception "in" v:throwpoint
2717 finally
2718 break " discard error for $VIMNOERRTHROW
2719 endtry
2720 endwhile
2721
2722 Xpath 1073741824 " X: 1073741824
2723
2724endif
2725
2726Xcheck 1499645335
2727
2728
2729"-------------------------------------------------------------------------------
2730" Test 65: Errors in the /pattern/ argument of a :catch {{{1
2731"
2732" On an error in the /pattern/ argument of a :catch, the :catch does
2733" not match. Any following :catches of the same :try/:endtry don't
2734" match either. Finally clauses are executed.
2735"-------------------------------------------------------------------------------
2736
2737XpathINIT
2738
2739function! MSG(enr, emsg)
2740 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
2741 if a:enr == ""
2742 Xout "TODO: Add message number for:" a:emsg
2743 let v:errmsg = ":" . v:errmsg
2744 endif
2745 let match = 1
2746 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
2747 let match = 0
2748 if v:errmsg == ""
2749 Xout "Message missing."
2750 else
2751 let v:errmsg = escape(v:errmsg, '"')
2752 Xout "Unexpected message:" v:errmsg
2753 endif
2754 endif
2755 return match
2756endfunction
2757
2758try
2759 try
2760 Xpath 1 " X: 1
2761 throw "oops"
2762 catch /^oops$/
2763 Xpath 2 " X: 2
2764 catch /\)/ " not checked; exception has already been caught
2765 Xpath 4 " X: 0
2766 endtry
2767 Xpath 8 " X: 8
2768catch /.*/
2769 Xpath 16 " X: 0
2770 Xout v:exception "in" v:throwpoint
2771endtry
2772
2773function! F()
2774 try
2775 let caught = 0
2776 try
2777 try
2778 Xpath 32 " X: 32
2779 throw "ab"
2780 catch /abc/ " does not catch
2781 Xpath 64 " X: 0
2782 catch /\)/ " error; discards exception
2783 Xpath 128 " X: 0
2784 catch /.*/ " not checked
2785 Xpath 256 " X: 0
2786 finally
2787 Xpath 512 " X: 512
2788 endtry
2789 Xpath 1024 " X: 0
2790 catch /^ab$/ " checked, but original exception is discarded
2791 Xpath 2048 " X: 0
2792 catch /^Vim(catch):/
2793 let caught = 1
2794 let v:errmsg = substitute(v:exception, '^Vim(catch):', '', "")
2795 finally
2796 Xpath 4096 " X: 4096
2797 if !caught && !$VIMNOERRTHROW
2798 Xpath 8192 " X: 0
2799 endif
Bram Moolenaardc94a262016-02-07 20:29:00 +01002800 if !MSG('E475', "Invalid argument")
Bram Moolenaar071d4272004-06-13 20:20:40 +00002801 Xpath 16384 " X: 0
2802 endif
2803 if !caught
2804 return | " discard error
2805 endif
2806 endtry
2807 catch /.*/
2808 Xpath 32768 " X: 0
2809 Xout v:exception "in" v:throwpoint
2810 endtry
2811endfunction
2812
2813call F()
2814Xpath 65536 " X: 65536
2815
2816delfunction MSG
2817delfunction F
2818unlet! caught
2819
2820Xcheck 70187
2821
2822
2823"-------------------------------------------------------------------------------
2824" Test 66: Stop range :call on error, interrupt, or :throw {{{1
2825"
2826" When a function which is multiply called for a range since it
2827" doesn't handle the range itself has an error in a command
2828" dynamically enclosed by :try/:endtry or gets an interrupt or
2829" executes a :throw, no more calls for the remaining lines in the
2830" range are made. On an error in a command not dynamically enclosed
2831" by :try/:endtry, the function is executed again for the remaining
2832" lines in the range.
2833"-------------------------------------------------------------------------------
2834
2835XpathINIT
2836
2837if ExtraVim()
2838
2839 let file = tempname()
2840 exec "edit" file
2841
2842 insert
2843line 1
2844line 2
2845line 3
2846.
2847
2848 XloopINIT! 1 2
2849
2850 let taken = ""
2851 let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)"
2852
2853 function! F(reason, n) abort
2854 let g:taken = g:taken . "F" . a:n .
2855 \ substitute(a:reason, '\(\l\).*', '\u\1', "") .
2856 \ "(" . line(".") . ")"
2857
2858 if a:reason == "error"
2859 asdf
2860 elseif a:reason == "interrupt"
2861 "INTERRUPT
2862 let dummy = 0
2863 elseif a:reason == "throw"
2864 throw "xyz"
2865 elseif a:reason == "aborting error"
2866 XloopNEXT
2867 if g:taken != g:expected
2868 Xloop 1 " X: 0
2869 Xout "'taken' is" g:taken "instead of" g:expected
2870 endif
2871 try
2872 bwipeout!
2873 call delete(file)
2874 asdf
2875 endtry
2876 endif
2877 endfunction
2878
2879 function! G(reason, n)
2880 let g:taken = g:taken . "G" . a:n .
2881 \ substitute(a:reason, '\(\l\).*', '\u\1', "")
2882 1,3call F(a:reason, a:n)
2883 endfunction
2884
2885 Xpath 8 " X: 8
2886 call G("error", 1)
2887 try
2888 Xpath 16 " X: 16
2889 try
2890 call G("error", 2)
2891 Xpath 32 " X: 0
2892 finally
2893 Xpath 64 " X: 64
2894 try
2895 call G("interrupt", 3)
2896 Xpath 128 " X: 0
2897 finally
2898 Xpath 256 " X: 256
2899 try
2900 call G("throw", 4)
2901 Xpath 512 " X: 0
2902 endtry
2903 endtry
2904 endtry
2905 catch /xyz/
2906 Xpath 1024 " X: 1024
2907 catch /.*/
2908 Xpath 2048 " X: 0
2909 Xout v:exception "in" ExtraVimThrowpoint()
2910 endtry
2911 Xpath 4096 " X: 4096
2912 call G("aborting error", 5)
2913 Xpath 8192 " X: 0
2914 Xout "'taken' is" taken "instead of" expected
2915
2916endif
2917
2918Xcheck 5464
2919
2920
2921"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002922" Test 67: :throw across :call command {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00002923"
2924" On a call command, an exception might be thrown when evaluating the
2925" function name, during evaluation of the arguments, or when the
2926" function is being executed. The exception can be caught by the
2927" caller.
2928"-------------------------------------------------------------------------------
2929
2930XpathINIT
2931
2932function! THROW(x, n)
2933 if a:n == 1
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002934 Xpath 1 " X: 1
Bram Moolenaar071d4272004-06-13 20:20:40 +00002935 elseif a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002936 Xpath 2 " X: 2
Bram Moolenaar071d4272004-06-13 20:20:40 +00002937 elseif a:n == 3
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002938 Xpath 4 " X: 4
Bram Moolenaar071d4272004-06-13 20:20:40 +00002939 endif
2940 throw a:x
2941endfunction
2942
2943function! NAME(x, n)
2944 if a:n == 1
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002945 Xpath 8 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00002946 elseif a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002947 Xpath 16 " X: 16
Bram Moolenaar071d4272004-06-13 20:20:40 +00002948 elseif a:n == 3
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002949 Xpath 32 " X: 32
Bram Moolenaar071d4272004-06-13 20:20:40 +00002950 elseif a:n == 4
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002951 Xpath 64 " X: 64
Bram Moolenaar071d4272004-06-13 20:20:40 +00002952 endif
2953 return a:x
2954endfunction
2955
2956function! ARG(x, n)
2957 if a:n == 1
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002958 Xpath 128 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00002959 elseif a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002960 Xpath 256 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00002961 elseif a:n == 3
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002962 Xpath 512 " X: 512
Bram Moolenaar071d4272004-06-13 20:20:40 +00002963 elseif a:n == 4
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002964 Xpath 1024 " X: 1024
Bram Moolenaar071d4272004-06-13 20:20:40 +00002965 endif
2966 return a:x
2967endfunction
2968
2969function! F(x, n)
2970 if a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002971 Xpath 2048 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00002972 elseif a:n == 4
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002973 Xpath 4096 " X: 4096
Bram Moolenaar071d4272004-06-13 20:20:40 +00002974 endif
2975endfunction
2976
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002977while 1
Bram Moolenaar071d4272004-06-13 20:20:40 +00002978 try
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002979 let error = 0
2980 let v:errmsg = ""
Bram Moolenaar071d4272004-06-13 20:20:40 +00002981
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00002982 while 1
2983 try
2984 Xpath 8192 " X: 8192
2985 call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
2986 Xpath 16384 " X: 0
2987 catch /^name$/
2988 Xpath 32768 " X: 32768
2989 catch /.*/
2990 let error = 1
2991 Xout "1:" v:exception "in" v:throwpoint
2992 finally
2993 if !error && $VIMNOERRTHROW && v:errmsg != ""
2994 let error = 1
2995 Xout "1:" v:errmsg
2996 endif
2997 if error
2998 Xpath 65536 " X: 0
2999 endif
3000 let error = 0
3001 let v:errmsg = ""
3002 break " discard error for $VIMNOERRTHROW
3003 endtry
3004 endwhile
Bram Moolenaar071d4272004-06-13 20:20:40 +00003005
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003006 while 1
3007 try
3008 Xpath 131072 " X: 131072
3009 call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
3010 Xpath 262144 " X: 0
3011 catch /^arg$/
3012 Xpath 524288 " X: 524288
3013 catch /.*/
3014 let error = 1
3015 Xout "2:" v:exception "in" v:throwpoint
3016 finally
3017 if !error && $VIMNOERRTHROW && v:errmsg != ""
3018 let error = 1
3019 Xout "2:" v:errmsg
3020 endif
3021 if error
3022 Xpath 1048576 " X: 0
3023 endif
3024 let error = 0
3025 let v:errmsg = ""
3026 break " discard error for $VIMNOERRTHROW
3027 endtry
3028 endwhile
3029
3030 while 1
3031 try
3032 Xpath 2097152 " X: 2097152
3033 call {NAME("THROW", 3)}(ARG("call", 3), 3)
3034 Xpath 4194304 " X: 0
3035 catch /^call$/
3036 Xpath 8388608 " X: 8388608
3037 catch /^0$/ " default return value
3038 Xpath 16777216 " X: 0
3039 Xout "3:" v:throwpoint
3040 catch /.*/
3041 let error = 1
3042 Xout "3:" v:exception "in" v:throwpoint
3043 finally
3044 if !error && $VIMNOERRTHROW && v:errmsg != ""
3045 let error = 1
3046 Xout "3:" v:errmsg
3047 endif
3048 if error
3049 Xpath 33554432 " X: 0
3050 endif
3051 let error = 0
3052 let v:errmsg = ""
3053 break " discard error for $VIMNOERRTHROW
3054 endtry
3055 endwhile
3056
3057 while 1
3058 try
3059 Xpath 67108864 " X: 67108864
3060 call {NAME("F", 4)}(ARG(4711, 4), 4)
3061 Xpath 134217728 " X: 134217728
3062 catch /.*/
3063 let error = 1
3064 Xout "4:" v:exception "in" v:throwpoint
3065 finally
3066 if !error && $VIMNOERRTHROW && v:errmsg != ""
3067 let error = 1
3068 Xout "4:" v:errmsg
3069 endif
3070 if error
3071 Xpath 268435456 " X: 0
3072 endif
3073 let error = 0
3074 let v:errmsg = ""
3075 break " discard error for $VIMNOERRTHROW
3076 endtry
3077 endwhile
3078
Bram Moolenaar071d4272004-06-13 20:20:40 +00003079 catch /^0$/ " default return value
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003080 Xpath 536870912 " X: 0
3081 Xout v:throwpoint
Bram Moolenaar071d4272004-06-13 20:20:40 +00003082 catch /.*/
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003083 let error = 1
3084 Xout v:exception "in" v:throwpoint
3085 finally
3086 if !error && $VIMNOERRTHROW && v:errmsg != ""
3087 let error = 1
3088 Xout v:errmsg
3089 endif
3090 if error
3091 Xpath 1073741824 " X: 0
3092 endif
3093 break " discard error for $VIMNOERRTHROW
Bram Moolenaar071d4272004-06-13 20:20:40 +00003094 endtry
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003095endwhile
Bram Moolenaar071d4272004-06-13 20:20:40 +00003096
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003097unlet error
Bram Moolenaar071d4272004-06-13 20:20:40 +00003098delfunction F
3099
3100Xcheck 212514423
3101
3102" Leave THROW(), NAME(), and ARG() for the next test.
3103
3104
3105"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003106" Test 68: :throw across function calls in expressions {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00003107"
3108" On a function call within an expression, an exception might be
3109" thrown when evaluating the function name, during evaluation of the
3110" arguments, or when the function is being executed. The exception
3111" can be caught by the caller.
3112"
3113" This test reuses the functions THROW(), NAME(), and ARG() from the
3114" previous test.
3115"-------------------------------------------------------------------------------
3116
3117XpathINIT
3118
3119function! F(x, n)
3120 if a:n == 2
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003121 Xpath 2048 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00003122 elseif a:n == 4
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003123 Xpath 4096 " X: 4096
Bram Moolenaar071d4272004-06-13 20:20:40 +00003124 endif
3125 return a:x
3126endfunction
3127
3128unlet! var1 var2 var3 var4
3129
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003130while 1
Bram Moolenaar071d4272004-06-13 20:20:40 +00003131 try
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003132 let error = 0
3133 let v:errmsg = ""
Bram Moolenaar071d4272004-06-13 20:20:40 +00003134
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003135 while 1
3136 try
3137 Xpath 8192 " X: 8192
3138 let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1)
3139 Xpath 16384 " X: 0
3140 catch /^name$/
3141 Xpath 32768 " X: 32768
3142 catch /.*/
3143 let error = 1
3144 Xout "1:" v:exception "in" v:throwpoint
3145 finally
3146 if !error && $VIMNOERRTHROW && v:errmsg != ""
3147 let error = 1
3148 Xout "1:" v:errmsg
3149 endif
3150 if error
3151 Xpath 65536 " X: 0
3152 endif
3153 let error = 0
3154 let v:errmsg = ""
3155 break " discard error for $VIMNOERRTHROW
3156 endtry
3157 endwhile
Bram Moolenaar071d4272004-06-13 20:20:40 +00003158
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003159 while 1
3160 try
3161 Xpath 131072 " X: 131072
3162 let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2)
3163 Xpath 262144 " X: 0
3164 catch /^arg$/
3165 Xpath 524288 " X: 524288
3166 catch /.*/
3167 let error = 1
3168 Xout "2:" v:exception "in" v:throwpoint
3169 finally
3170 if !error && $VIMNOERRTHROW && v:errmsg != ""
3171 let error = 1
3172 Xout "2:" v:errmsg
3173 endif
3174 if error
3175 Xpath 1048576 " X: 0
3176 endif
3177 let error = 0
3178 let v:errmsg = ""
3179 break " discard error for $VIMNOERRTHROW
3180 endtry
3181 endwhile
3182
3183 while 1
3184 try
3185 Xpath 2097152 " X: 2097152
3186 let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3)
3187 Xpath 4194304 " X: 0
3188 catch /^call$/
3189 Xpath 8388608 " X: 8388608
3190 catch /^0$/ " default return value
3191 Xpath 16777216 " X: 0
3192 Xout "3:" v:throwpoint
3193 catch /.*/
3194 let error = 1
3195 Xout "3:" v:exception "in" v:throwpoint
3196 finally
3197 if !error && $VIMNOERRTHROW && v:errmsg != ""
3198 let error = 1
3199 Xout "3:" v:errmsg
3200 endif
3201 if error
3202 Xpath 33554432 " X: 0
3203 endif
3204 let error = 0
3205 let v:errmsg = ""
3206 break " discard error for $VIMNOERRTHROW
3207 endtry
3208 endwhile
3209
3210 while 1
3211 try
3212 Xpath 67108864 " X: 67108864
3213 let var4 = {NAME("F", 4)}(ARG(4711, 4), 4)
3214 Xpath 134217728 " X: 134217728
3215 catch /.*/
3216 let error = 1
3217 Xout "4:" v:exception "in" v:throwpoint
3218 finally
3219 if !error && $VIMNOERRTHROW && v:errmsg != ""
3220 let error = 1
3221 Xout "4:" v:errmsg
3222 endif
3223 if error
3224 Xpath 268435456 " X: 0
3225 endif
3226 let error = 0
3227 let v:errmsg = ""
3228 break " discard error for $VIMNOERRTHROW
3229 endtry
3230 endwhile
3231
Bram Moolenaar071d4272004-06-13 20:20:40 +00003232 catch /^0$/ " default return value
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003233 Xpath 536870912 " X: 0
3234 Xout v:throwpoint
Bram Moolenaar071d4272004-06-13 20:20:40 +00003235 catch /.*/
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003236 let error = 1
3237 Xout v:exception "in" v:throwpoint
3238 finally
3239 if !error && $VIMNOERRTHROW && v:errmsg != ""
3240 let error = 1
3241 Xout v:errmsg
3242 endif
3243 if error
3244 Xpath 1073741824 " X: 0
3245 endif
3246 break " discard error for $VIMNOERRTHROW
Bram Moolenaar071d4272004-06-13 20:20:40 +00003247 endtry
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003248endwhile
Bram Moolenaar071d4272004-06-13 20:20:40 +00003249
3250if exists("var1") || exists("var2") || exists("var3") ||
3251 \ !exists("var4") || var4 != 4711
3252 " The Xpath command does not accept 2^31 (negative); add explicitly:
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003253 let Xpath = Xpath + 2147483648 " X: 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00003254 if exists("var1")
3255 Xout "var1 =" var1
3256 endif
3257 if exists("var2")
3258 Xout "var2 =" var2
3259 endif
3260 if exists("var3")
3261 Xout "var3 =" var3
3262 endif
3263 if !exists("var4")
3264 Xout "var4 unset"
3265 elseif var4 != 4711
3266 Xout "var4 =" var4
3267 endif
3268endif
3269
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003270unlet! error var1 var2 var3 var4
Bram Moolenaar071d4272004-06-13 20:20:40 +00003271delfunction THROW
3272delfunction NAME
3273delfunction ARG
3274delfunction F
3275
3276Xcheck 212514423
3277
Bram Moolenaar1f068232019-11-03 16:17:26 +01003278" Tests 69 to 75 were moved to test_trycatch.vim
3279let Xtest = 76
Bram Moolenaar071d4272004-06-13 20:20:40 +00003280
3281
3282"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003283" Test 76: Errors, interrupts, :throw during expression evaluation {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00003284"
3285" When a function call made during expression evaluation is aborted
3286" due to an error inside a :try/:endtry region or due to an interrupt
3287" or a :throw, the expression evaluation is aborted as well. No
3288" message is displayed for the cancelled expression evaluation. On an
3289" error not inside :try/:endtry, the expression evaluation continues.
3290"-------------------------------------------------------------------------------
3291
3292XpathINIT
3293
3294if ExtraVim()
3295
3296 let taken = ""
3297
3298 function! ERR(n)
3299 let g:taken = g:taken . "E" . a:n
3300 asdf
3301 endfunction
3302
3303 function! ERRabort(n) abort
3304 let g:taken = g:taken . "A" . a:n
3305 asdf
Bram Moolenaare13305e2005-06-19 22:54:15 +00003306 endfunction " returns -1; may cause follow-up msg for illegal var/func name
3307
3308 function! WRAP(n, arg)
3309 let g:taken = g:taken . "W" . a:n
3310 let g:saved_errmsg = v:errmsg
3311 return arg
3312 endfunction
Bram Moolenaar071d4272004-06-13 20:20:40 +00003313
3314 function! INT(n)
3315 let g:taken = g:taken . "I" . a:n
3316 "INTERRUPT9
3317 let dummy = 0
3318 endfunction
3319
3320 function! THR(n)
3321 let g:taken = g:taken . "T" . a:n
3322 throw "should not be caught"
3323 endfunction
3324
3325 function! CONT(n)
3326 let g:taken = g:taken . "C" . a:n
3327 endfunction
3328
3329 function! MSG(n)
3330 let g:taken = g:taken . "M" . a:n
Bram Moolenaare13305e2005-06-19 22:54:15 +00003331 let errmsg = (a:n >= 37 && a:n <= 44) ? g:saved_errmsg : v:errmsg
3332 let msgptn = (a:n >= 10 && a:n <= 27) ? "^$" : "asdf"
3333 if errmsg !~ msgptn
3334 let g:taken = g:taken . "x"
3335 Xout "Expr" a:n.": Unexpected message:" v:errmsg
Bram Moolenaar071d4272004-06-13 20:20:40 +00003336 endif
3337 let v:errmsg = ""
Bram Moolenaare13305e2005-06-19 22:54:15 +00003338 let g:saved_errmsg = ""
Bram Moolenaar071d4272004-06-13 20:20:40 +00003339 endfunction
3340
3341 let v:errmsg = ""
3342
3343 try
3344 let t = 1
3345 XloopINIT 1 2
3346 while t <= 9
3347 Xloop 1 " X: 511
3348 try
3349 if t == 1
3350 let v{ERR(t) + CONT(t)} = 0
3351 elseif t == 2
3352 let v{ERR(t) + CONT(t)}
3353 elseif t == 3
3354 let var = exists('v{ERR(t) + CONT(t)}')
3355 elseif t == 4
3356 unlet v{ERR(t) + CONT(t)}
3357 elseif t == 5
3358 function F{ERR(t) + CONT(t)}()
3359 endfunction
3360 elseif t == 6
3361 function F{ERR(t) + CONT(t)}
3362 elseif t == 7
3363 let var = exists('*F{ERR(t) + CONT(t)}')
3364 elseif t == 8
3365 delfunction F{ERR(t) + CONT(t)}
3366 elseif t == 9
3367 let var = ERR(t) + CONT(t)
3368 endif
3369 catch /asdf/
3370 " v:errmsg is not set when the error message is converted to an
3371 " exception. Set it to the original error message.
3372 let v:errmsg = substitute(v:exception, '^Vim:', '', "")
3373 catch /^Vim\((\a\+)\)\=:/
3374 " An error exception has been thrown after the original error.
3375 let v:errmsg = ""
3376 finally
3377 call MSG(t)
3378 let t = t + 1
3379 XloopNEXT
3380 continue " discard an aborting error
3381 endtry
3382 endwhile
3383 catch /.*/
3384 Xpath 512 " X: 0
3385 Xout v:exception "in" ExtraVimThrowpoint()
3386 endtry
3387
3388 try
3389 let t = 10
3390 XloopINIT 1024 2
3391 while t <= 18
3392 Xloop 1 " X: 1024 * 511
3393 try
3394 if t == 10
3395 let v{INT(t) + CONT(t)} = 0
3396 elseif t == 11
3397 let v{INT(t) + CONT(t)}
3398 elseif t == 12
3399 let var = exists('v{INT(t) + CONT(t)}')
3400 elseif t == 13
3401 unlet v{INT(t) + CONT(t)}
3402 elseif t == 14
3403 function F{INT(t) + CONT(t)}()
3404 endfunction
3405 elseif t == 15
3406 function F{INT(t) + CONT(t)}
3407 elseif t == 16
3408 let var = exists('*F{INT(t) + CONT(t)}')
3409 elseif t == 17
3410 delfunction F{INT(t) + CONT(t)}
3411 elseif t == 18
3412 let var = INT(t) + CONT(t)
3413 endif
3414 catch /^Vim\((\a\+)\)\=:\(Interrupt\)\@!/
3415 " An error exception has been triggered after the interrupt.
3416 let v:errmsg = substitute(v:exception,
3417 \ '^Vim\((\a\+)\)\=:', '', "")
3418 finally
3419 call MSG(t)
3420 let t = t + 1
3421 XloopNEXT
3422 continue " discard interrupt
3423 endtry
3424 endwhile
3425 catch /.*/
3426 Xpath 524288 " X: 0
3427 Xout v:exception "in" ExtraVimThrowpoint()
3428 endtry
3429
3430 try
3431 let t = 19
3432 XloopINIT 1048576 2
3433 while t <= 27
3434 Xloop 1 " X: 1048576 * 511
3435 try
3436 if t == 19
3437 let v{THR(t) + CONT(t)} = 0
3438 elseif t == 20
3439 let v{THR(t) + CONT(t)}
3440 elseif t == 21
3441 let var = exists('v{THR(t) + CONT(t)}')
3442 elseif t == 22
3443 unlet v{THR(t) + CONT(t)}
3444 elseif t == 23
3445 function F{THR(t) + CONT(t)}()
3446 endfunction
3447 elseif t == 24
3448 function F{THR(t) + CONT(t)}
3449 elseif t == 25
3450 let var = exists('*F{THR(t) + CONT(t)}')
3451 elseif t == 26
3452 delfunction F{THR(t) + CONT(t)}
3453 elseif t == 27
3454 let var = THR(t) + CONT(t)
3455 endif
3456 catch /^Vim\((\a\+)\)\=:/
3457 " An error exception has been triggered after the :throw.
3458 let v:errmsg = substitute(v:exception,
3459 \ '^Vim\((\a\+)\)\=:', '', "")
3460 finally
3461 call MSG(t)
3462 let t = t + 1
3463 XloopNEXT
3464 continue " discard exception
3465 endtry
3466 endwhile
3467 catch /.*/
3468 Xpath 536870912 " X: 0
3469 Xout v:exception "in" ExtraVimThrowpoint()
3470 endtry
3471
3472 let v{ERR(28) + CONT(28)} = 0
3473 call MSG(28)
3474 let v{ERR(29) + CONT(29)}
3475 call MSG(29)
3476 let var = exists('v{ERR(30) + CONT(30)}')
3477 call MSG(30)
3478 unlet v{ERR(31) + CONT(31)}
3479 call MSG(31)
3480 function F{ERR(32) + CONT(32)}()
3481 endfunction
3482 call MSG(32)
3483 function F{ERR(33) + CONT(33)}
3484 call MSG(33)
3485 let var = exists('*F{ERR(34) + CONT(34)}')
3486 call MSG(34)
3487 delfunction F{ERR(35) + CONT(35)}
3488 call MSG(35)
3489 let var = ERR(36) + CONT(36)
3490 call MSG(36)
3491
Bram Moolenaare13305e2005-06-19 22:54:15 +00003492 let saved_errmsg = ""
3493
3494 let v{WRAP(37, ERRabort(37)) + CONT(37)} = 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00003495 call MSG(37)
Bram Moolenaare13305e2005-06-19 22:54:15 +00003496 let v{WRAP(38, ERRabort(38)) + CONT(38)}
Bram Moolenaar071d4272004-06-13 20:20:40 +00003497 call MSG(38)
Bram Moolenaare13305e2005-06-19 22:54:15 +00003498 let var = exists('v{WRAP(39, ERRabort(39)) + CONT(39)}')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003499 call MSG(39)
Bram Moolenaare13305e2005-06-19 22:54:15 +00003500 unlet v{WRAP(40, ERRabort(40)) + CONT(40)}
Bram Moolenaar071d4272004-06-13 20:20:40 +00003501 call MSG(40)
Bram Moolenaare13305e2005-06-19 22:54:15 +00003502 function F{WRAP(41, ERRabort(41)) + CONT(41)}()
Bram Moolenaar071d4272004-06-13 20:20:40 +00003503 endfunction
3504 call MSG(41)
Bram Moolenaare13305e2005-06-19 22:54:15 +00003505 function F{WRAP(42, ERRabort(42)) + CONT(42)}
Bram Moolenaar071d4272004-06-13 20:20:40 +00003506 call MSG(42)
Bram Moolenaare13305e2005-06-19 22:54:15 +00003507 let var = exists('*F{WRAP(43, ERRabort(43)) + CONT(43)}')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003508 call MSG(43)
Bram Moolenaare13305e2005-06-19 22:54:15 +00003509 delfunction F{WRAP(44, ERRabort(44)) + CONT(44)}
Bram Moolenaar071d4272004-06-13 20:20:40 +00003510 call MSG(44)
3511 let var = ERRabort(45) + CONT(45)
3512 call MSG(45)
3513
3514 Xpath 1073741824 " X: 1073741824
3515
3516 let expected = ""
3517 \ . "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9"
3518 \ . "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18"
3519 \ . "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27"
3520 \ . "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33"
3521 \ . "E34C34M34E35C35M35E36C36M36"
Bram Moolenaare13305e2005-06-19 22:54:15 +00003522 \ . "A37W37C37M37A38W38C38M38A39W39C39M39A40W40C40M40A41W41C41M41"
3523 \ . "A42W42C42M42A43W43C43M43A44W44C44M44A45C45M45"
Bram Moolenaar071d4272004-06-13 20:20:40 +00003524
3525 if taken != expected
3526 " The Xpath command does not accept 2^31 (negative); display explicitly:
3527 exec "!echo 2147483648 >>" . g:ExtraVimResult
3528 " X: 0
3529 Xout "'taken' is" taken "instead of" expected
3530 if substitute(taken,
3531 \ '\(.*\)E3C3M3x\(.*\)E30C30M30x\(.*\)A39C39M39x\(.*\)',
3532 \ '\1E3M3\2E30C30M30\3A39C39M39\4',
3533 \ "") == expected
3534 Xout "Is ++emsg_skip for var with expr_start non-NULL"
3535 \ "in f_exists ok?"
3536 endif
3537 endif
3538
Bram Moolenaare13305e2005-06-19 22:54:15 +00003539 unlet! v var saved_errmsg taken expected
Bram Moolenaar071d4272004-06-13 20:20:40 +00003540 call delete(WA_t5)
3541 call delete(WA_t14)
3542 call delete(WA_t23)
3543 unlet! WA_t5 WA_t14 WA_t23
3544 delfunction WA_t5
3545 delfunction WA_t14
3546 delfunction WA_t23
3547
3548endif
3549
3550Xcheck 1610087935
3551
3552
3553"-------------------------------------------------------------------------------
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003554" Test 77: Errors, interrupts, :throw in name{brace-expression} {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00003555"
3556" When a function call made during evaluation of an expression in
3557" braces as part of a function name after ":function" is aborted due
3558" to an error inside a :try/:endtry region or due to an interrupt or
3559" a :throw, the expression evaluation is aborted as well, and the
3560" function definition is ignored, skipping all commands to the
3561" ":endfunction". On an error not inside :try/:endtry, the expression
3562" evaluation continues and the function gets defined, and can be
3563" called and deleted.
3564"-------------------------------------------------------------------------------
3565
3566XpathINIT
3567
3568XloopINIT 1 4
3569
3570function! ERR() abort
3571 Xloop 1 " X: 1 + 4 + 16 + 64
3572 asdf
3573endfunction " returns -1
3574
3575function! OK()
3576 Xloop 2 " X: 2 * (1 + 4 + 16)
3577 let v:errmsg = ""
3578 return 0
3579endfunction
3580
3581let v:errmsg = ""
3582
3583Xpath 4096 " X: 4096
3584function! F{1 + ERR() + OK()}(arg)
3585 " F0 should be defined.
3586 if exists("a:arg") && a:arg == "calling"
3587 Xpath 8192 " X: 8192
3588 else
3589 Xpath 16384 " X: 0
3590 endif
3591endfunction
3592if v:errmsg != ""
3593 Xpath 32768 " X: 0
3594endif
3595XloopNEXT
3596
3597Xpath 65536 " X: 65536
3598call F{1 + ERR() + OK()}("calling")
3599if v:errmsg != ""
3600 Xpath 131072 " X: 0
3601endif
3602XloopNEXT
3603
3604Xpath 262144 " X: 262144
3605delfunction F{1 + ERR() + OK()}
3606if v:errmsg != ""
3607 Xpath 524288 " X: 0
3608endif
3609XloopNEXT
3610
3611try
3612 while 1
3613 let caught = 0
3614 try
3615 Xpath 1048576 " X: 1048576
3616 function! G{1 + ERR() + OK()}(arg)
3617 " G0 should not be defined, and the function body should be
3618 " skipped.
3619 if exists("a:arg") && a:arg == "calling"
3620 Xpath 2097152 " X: 0
3621 else
3622 Xpath 4194304 " X: 0
3623 endif
3624 " Use an unmatched ":finally" to check whether the body is
3625 " skipped when an error occurs in ERR(). This works whether or
3626 " not the exception is converted to an exception.
3627 finally
3628 Xpath 8388608 " X: 0
3629 Xout "Body of G{1 + ERR() + OK()}() not skipped"
3630 " Discard the aborting error or exception, and break the
3631 " while loop.
3632 break
3633 " End the try conditional and start a new one to avoid
3634 " ":catch after :finally" errors.
3635 endtry
3636 try
3637 Xpath 16777216 " X: 0
3638 endfunction
3639
3640 " When the function was not defined, this won't be reached - whether
3641 " the body was skipped or not. When the function was defined, it
3642 " can be called and deleted here.
3643 Xpath 33554432 " X: 0
3644 Xout "G0() has been defined"
3645 XloopNEXT
3646 try
3647 call G{1 + ERR() + OK()}("calling")
3648 catch /.*/
3649 Xpath 67108864 " X: 0
3650 endtry
3651 Xpath 134217728 " X: 0
3652 XloopNEXT
3653 try
3654 delfunction G{1 + ERR() + OK()}
3655 catch /.*/
3656 Xpath 268435456 " X: 0
3657 endtry
3658 catch /asdf/
3659 " Jumped to when the function is not defined and the body is
3660 " skipped.
3661 let caught = 1
3662 catch /.*/
3663 Xpath 536870912 " X: 0
3664 finally
3665 if !caught && !$VIMNOERRTHROW
3666 Xpath 1073741824 " X: 0
3667 endif
3668 break " discard error for $VIMNOERRTHROW
3669 endtry " jumped to when the body is not skipped
3670 endwhile
3671catch /.*/
3672 " The Xpath command does not accept 2^31 (negative); add explicitly:
3673 let Xpath = Xpath + 2147483648 " X: 0
3674 Xout "Body of G{1 + ERR() + OK()}() not skipped, exception caught"
3675 Xout v:exception "in" v:throwpoint
3676endtry
3677
3678Xcheck 1388671
3679
3680
3681"-------------------------------------------------------------------------------
3682" Test 78: Messages on parsing errors in expression evaluation {{{1
3683"
3684" When an expression evaluation detects a parsing error, an error
3685" message is given and converted to an exception, and the expression
3686" evaluation is aborted.
3687"-------------------------------------------------------------------------------
3688
3689XpathINIT
3690
3691if ExtraVim()
3692
3693 let taken = ""
3694
3695 function! F(n)
3696 let g:taken = g:taken . "F" . a:n
3697 endfunction
3698
3699 function! MSG(n, enr, emsg)
3700 let g:taken = g:taken . "M" . a:n
3701 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
3702 if a:enr == ""
3703 Xout "TODO: Add message number for:" a:emsg
3704 let v:errmsg = ":" . v:errmsg
3705 endif
3706 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
3707 if v:errmsg == ""
3708 Xout "Expr" a:n.": Message missing."
3709 let g:taken = g:taken . "x"
3710 else
3711 let v:errmsg = escape(v:errmsg, '"')
3712 Xout "Expr" a:n.": Unexpected message:" v:errmsg
Bram Moolenaar383f9bc2005-01-19 22:18:32 +00003713 Xout "Expected: " . a:enr . ': ' . a:emsg
Bram Moolenaar071d4272004-06-13 20:20:40 +00003714 let g:taken = g:taken . "X"
3715 endif
3716 endif
3717 endfunction
3718
3719 function! CONT(n)
3720 let g:taken = g:taken . "C" . a:n
3721 endfunction
3722
3723 let v:errmsg = ""
3724 XloopINIT 1 2
3725
3726 try
3727 let t = 1
3728 while t <= 14
3729 let g:taken = g:taken . "T" . t
3730 let v:errmsg = ""
3731 try
3732 let caught = 0
3733 if t == 1
3734 let v{novar + CONT(t)} = 0
3735 elseif t == 2
3736 let v{novar + CONT(t)}
3737 elseif t == 3
3738 let var = exists('v{novar + CONT(t)}')
3739 elseif t == 4
3740 unlet v{novar + CONT(t)}
3741 elseif t == 5
3742 function F{novar + CONT(t)}()
3743 endfunction
3744 elseif t == 6
3745 function F{novar + CONT(t)}
3746 elseif t == 7
3747 let var = exists('*F{novar + CONT(t)}')
3748 elseif t == 8
3749 delfunction F{novar + CONT(t)}
3750 elseif t == 9
3751 echo novar + CONT(t)
3752 elseif t == 10
3753 echo v{novar + CONT(t)}
3754 elseif t == 11
3755 echo F{novar + CONT(t)}
3756 elseif t == 12
3757 let var = novar + CONT(t)
3758 elseif t == 13
3759 let var = v{novar + CONT(t)}
3760 elseif t == 14
3761 let var = F{novar + CONT(t)}()
3762 endif
3763 catch /^Vim\((\a\+)\)\=:/
3764 " v:errmsg is not set when the error message is converted to an
3765 " exception. Set it to the original error message.
3766 let v:errmsg = substitute(v:exception,
3767 \ '^Vim\((\a\+)\)\=:', '', "")
3768 let caught = 1
3769 finally
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003770 if t <= 8 && t != 3 && t != 7
3771 call MSG(t, 'E475', 'Invalid argument\>')
Bram Moolenaar071d4272004-06-13 20:20:40 +00003772 else
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00003773 if !caught " no error exceptions ($VIMNOERRTHROW set)
3774 call MSG(t, 'E15', "Invalid expression")
Bram Moolenaar071d4272004-06-13 20:20:40 +00003775 else
3776 call MSG(t, 'E121', "Undefined variable")
3777 endif
3778 endif
3779 let t = t + 1
3780 XloopNEXT
3781 continue " discard an aborting error
3782 endtry
3783 endwhile
3784 catch /.*/
3785 Xloop 1 " X: 0
3786 Xout t.":" v:exception "in" ExtraVimThrowpoint()
3787 endtry
3788
3789 function! T(n, expr, enr, emsg)
3790 try
3791 let g:taken = g:taken . "T" . a:n
3792 let v:errmsg = ""
3793 try
3794 let caught = 0
3795 execute "let var = " . a:expr
3796 catch /^Vim\((\a\+)\)\=:/
3797 " v:errmsg is not set when the error message is converted to an
3798 " exception. Set it to the original error message.
3799 let v:errmsg = substitute(v:exception,
3800 \ '^Vim\((\a\+)\)\=:', '', "")
3801 let caught = 1
3802 finally
3803 if !caught " no error exceptions ($VIMNOERRTHROW set)
3804 call MSG(a:n, 'E15', "Invalid expression")
3805 else
3806 call MSG(a:n, a:enr, a:emsg)
3807 endif
3808 XloopNEXT
3809 " Discard an aborting error:
3810 return
3811 endtry
3812 catch /.*/
3813 Xloop 1 " X: 0
3814 Xout a:n.":" v:exception "in" ExtraVimThrowpoint()
3815 endtry
3816 endfunction
3817
3818 call T(15, 'Nofunc() + CONT(15)', 'E117', "Unknown function")
3819 call T(16, 'F(1 2 + CONT(16))', 'E116', "Invalid arguments")
3820 call T(17, 'F(1, 2) + CONT(17)', 'E118', "Too many arguments")
3821 call T(18, 'F() + CONT(18)', 'E119', "Not enough arguments")
3822 call T(19, '{(1} + CONT(19)', 'E110', "Missing ')'")
3823 call T(20, '("abc"[1) + CONT(20)', 'E111', "Missing ']'")
3824 call T(21, '(1 +) + CONT(21)', 'E15', "Invalid expression")
3825 call T(22, '1 2 + CONT(22)', 'E15', "Invalid expression")
3826 call T(23, '(1 ? 2) + CONT(23)', 'E109', "Missing ':' after '?'")
3827 call T(24, '("abc) + CONT(24)', 'E114', "Missing quote")
3828 call T(25, "('abc) + CONT(25)", 'E115', "Missing quote")
Bram Moolenaar2fda12f2005-01-15 22:14:15 +00003829 call T(26, '& + CONT(26)', 'E112', "Option name missing")
Bram Moolenaar071d4272004-06-13 20:20:40 +00003830 call T(27, '&asdf + CONT(27)', 'E113', "Unknown option")
3831
3832 Xpath 134217728 " X: 134217728
3833
3834 let expected = ""
3835 \ . "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14"
3836 \ . "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25"
3837 \ . "T26M26T27M27"
3838
3839 if taken != expected
3840 Xpath 268435456 " X: 0
3841 Xout "'taken' is" taken "instead of" expected
3842 if substitute(taken, '\(.*\)T3M3x\(.*\)', '\1T3M3\2', "") == expected
3843 Xout "Is ++emsg_skip for var with expr_start non-NULL"
3844 \ "in f_exists ok?"
3845 endif
3846 endif
3847
3848 unlet! var caught taken expected
3849 call delete(WA_t5)
3850 unlet! WA_t5
3851 delfunction WA_t5
3852
3853endif
3854
3855Xcheck 134217728
3856
3857
3858"-------------------------------------------------------------------------------
3859" Test 79: Throwing one of several errors for the same command {{{1
3860"
3861" When several errors appear in a row (for instance during expression
3862" evaluation), the first as the most specific one is used when
3863" throwing an error exception. If, however, a syntax error is
3864" detected afterwards, this one is used for the error exception.
3865" On a syntax error, the next command is not executed, on a normal
3866" error, however, it is (relevant only in a function without the
3867" "abort" flag). v:errmsg is not set.
3868"
3869" If throwing error exceptions is configured off, v:errmsg is always
3870" set to the latest error message, that is, to the more general
3871" message or the syntax error, respectively.
3872"-------------------------------------------------------------------------------
3873
3874XpathINIT
3875
3876XloopINIT 1 2
3877
3878function! NEXT(cmd)
3879 exec a:cmd . " | Xloop 1"
3880endfunction
3881
3882call NEXT('echo novar') " X: 1 * 1 (checks nextcmd)
3883XloopNEXT
3884call NEXT('let novar #') " X: 0 * 2 (skips nextcmd)
3885XloopNEXT
3886call NEXT('unlet novar #') " X: 0 * 4 (skips nextcmd)
3887XloopNEXT
3888call NEXT('let {novar}') " X: 0 * 8 (skips nextcmd)
3889XloopNEXT
3890call NEXT('unlet{ novar}') " X: 0 * 16 (skips nextcmd)
3891
3892function! EXEC(cmd)
3893 exec a:cmd
3894endfunction
3895
3896function! MATCH(expected, msg, enr, emsg)
3897 let msg = a:msg
3898 if a:enr == ""
3899 Xout "TODO: Add message number for:" a:emsg
3900 let msg = ":" . msg
3901 endif
3902 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
3903 if msg !~ '^'.a:enr.':' || (english && msg !~ a:emsg)
3904 let match = 0
3905 if a:expected " no match although expected
3906 if a:msg == ""
3907 Xout "Message missing."
3908 else
3909 let msg = escape(msg, '"')
3910 Xout "Unexpected message:" msg
Bram Moolenaar9cd15162005-01-16 22:02:49 +00003911 Xout "Expected:" a:enr . ": " . a:emsg
Bram Moolenaar071d4272004-06-13 20:20:40 +00003912 endif
3913 endif
3914 else
3915 let match = 1
3916 if !a:expected " match although not expected
3917 let msg = escape(msg, '"')
3918 Xout "Unexpected message:" msg
Bram Moolenaar9cd15162005-01-16 22:02:49 +00003919 Xout "Expected none."
Bram Moolenaar071d4272004-06-13 20:20:40 +00003920 endif
3921 endif
3922 return match
3923endfunction
3924
3925try
3926
3927 while 1 " dummy loop
3928 try
3929 let v:errmsg = ""
3930 let caught = 0
3931 let thrmsg = ""
3932 call EXEC('echo novar') " normal error
3933 catch /^Vim\((\a\+)\)\=:/
3934 let caught = 1
3935 let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
3936 finally
3937 Xpath 32 " X: 32
3938 if !caught
3939 if !$VIMNOERRTHROW
3940 Xpath 64 " X: 0
3941 endif
3942 elseif !MATCH(1, thrmsg, 'E121', "Undefined variable")
3943 \ || v:errmsg != ""
3944 Xpath 128 " X: 0
3945 endif
3946 if !caught && !MATCH(1, v:errmsg, 'E15', "Invalid expression")
3947 Xpath 256 " X: 0
3948 endif
3949 break " discard error if $VIMNOERRTHROW == 1
3950 endtry
3951 endwhile
3952
3953 Xpath 512 " X: 512
3954 let cmd = "let"
3955 XloopINIT 1024 32
3956 while cmd != ""
3957 try
3958 let v:errmsg = ""
3959 let caught = 0
3960 let thrmsg = ""
3961 call EXEC(cmd . ' novar #') " normal plus syntax error
3962 catch /^Vim\((\a\+)\)\=:/
3963 let caught = 1
3964 let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
3965 finally
3966 Xloop 1 " X: 1024 * (1 + 32)
3967 if !caught
3968 if !$VIMNOERRTHROW
3969 Xloop 2 " X: 0
3970 endif
3971 else
3972 if cmd == "let"
Bram Moolenaar39676922010-09-29 16:55:49 +02003973 let match = MATCH(0, thrmsg, 'E121', "Undefined variable")
Bram Moolenaar071d4272004-06-13 20:20:40 +00003974 elseif cmd == "unlet"
3975 let match = MATCH(0, thrmsg, 'E108', "No such variable")
3976 endif
3977 if match " normal error
3978 Xloop 4 " X: 0
3979 endif
3980 if !MATCH(1, thrmsg, 'E488', "Trailing characters")
3981 \|| v:errmsg != ""
3982 " syntax error
3983 Xloop 8 " X: 0
3984 endif
3985 endif
3986 if !caught && !MATCH(1, v:errmsg, 'E488', "Trailing characters")
3987 " last error
3988 Xloop 16 " X: 0
3989 endif
3990 if cmd == "let"
3991 let cmd = "unlet"
3992 else
3993 let cmd = ""
3994 endif
3995 XloopNEXT
3996 continue " discard error if $VIMNOERRTHROW == 1
3997 endtry
3998 endwhile
3999
4000 Xpath 1048576 " X: 1048576
4001 let cmd = "let"
4002 XloopINIT 2097152 32
4003 while cmd != ""
4004 try
4005 let v:errmsg = ""
4006 let caught = 0
4007 let thrmsg = ""
4008 call EXEC(cmd . ' {novar}') " normal plus syntax error
4009 catch /^Vim\((\a\+)\)\=:/
4010 let caught = 1
4011 let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
4012 finally
4013 Xloop 1 " X: 2097152 * (1 + 32)
4014 if !caught
4015 if !$VIMNOERRTHROW
4016 Xloop 2 " X: 0
4017 endif
4018 else
4019 if MATCH(0, thrmsg, 'E121', "Undefined variable") " normal error
4020 Xloop 4 " X: 0
4021 endif
4022 if !MATCH(1, thrmsg, 'E475', 'Invalid argument\>')
4023 \ || v:errmsg != "" " syntax error
4024 Xloop 8 " X: 0
4025 endif
4026 endif
4027 if !caught && !MATCH(1, v:errmsg, 'E475', 'Invalid argument\>')
4028 " last error
4029 Xloop 16 " X: 0
4030 endif
4031 if cmd == "let"
4032 let cmd = "unlet"
4033 else
4034 let cmd = ""
4035 endif
4036 XloopNEXT
4037 continue " discard error if $VIMNOERRTHROW == 1
4038 endtry
4039 endwhile
4040
4041catch /.*/
4042 " The Xpath command does not accept 2^31 (negative); add explicitly:
4043 let Xpath = Xpath + 2147483648 " X: 0
4044 Xout v:exception "in" v:throwpoint
4045endtry
4046
4047unlet! next_command thrmsg match
4048delfunction NEXT
4049delfunction EXEC
4050delfunction MATCH
4051
4052Xcheck 70288929
4053
4054
4055"-------------------------------------------------------------------------------
4056" Test 80: Syntax error in expression for illegal :elseif {{{1
4057"
4058" If there is a syntax error in the expression after an illegal
4059" :elseif, an error message is given (or an error exception thrown)
4060" for the illegal :elseif rather than the expression error.
4061"-------------------------------------------------------------------------------
4062
4063XpathINIT
4064
4065function! MSG(enr, emsg)
4066 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
4067 if a:enr == ""
4068 Xout "TODO: Add message number for:" a:emsg
4069 let v:errmsg = ":" . v:errmsg
4070 endif
4071 let match = 1
4072 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
4073 let match = 0
4074 if v:errmsg == ""
4075 Xout "Message missing."
4076 else
4077 let v:errmsg = escape(v:errmsg, '"')
4078 Xout "Unexpected message:" v:errmsg
4079 endif
4080 endif
4081 return match
4082endfunction
4083
4084let v:errmsg = ""
4085if 0
4086else
4087elseif 1 ||| 2
4088endif
4089Xpath 1 " X: 1
4090if !MSG('E584', ":elseif after :else")
4091 Xpath 2 " X: 0
4092endif
4093
4094let v:errmsg = ""
4095if 1
4096else
4097elseif 1 ||| 2
4098endif
4099Xpath 4 " X: 4
4100if !MSG('E584', ":elseif after :else")
4101 Xpath 8 " X: 0
4102endif
4103
4104let v:errmsg = ""
4105elseif 1 ||| 2
4106Xpath 16 " X: 16
4107if !MSG('E582', ":elseif without :if")
4108 Xpath 32 " X: 0
4109endif
4110
4111let v:errmsg = ""
4112while 1
4113 elseif 1 ||| 2
4114endwhile
4115Xpath 64 " X: 64
4116if !MSG('E582', ":elseif without :if")
4117 Xpath 128 " X: 0
4118endif
4119
4120while 1
4121 try
4122 try
4123 let v:errmsg = ""
4124 let caught = 0
4125 if 0
4126 else
4127 elseif 1 ||| 2
4128 endif
4129 catch /^Vim\((\a\+)\)\=:/
4130 let caught = 1
4131 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
4132 finally
4133 Xpath 256 " X: 256
4134 if !caught && !$VIMNOERRTHROW
4135 Xpath 512 " X: 0
4136 endif
4137 if !MSG('E584', ":elseif after :else")
4138 Xpath 1024 " X: 0
4139 endif
4140 endtry
4141 catch /.*/
4142 Xpath 2048 " X: 0
4143 Xout v:exception "in" v:throwpoint
4144 finally
4145 break " discard error for $VIMNOERRTHROW
4146 endtry
4147endwhile
4148
4149while 1
4150 try
4151 try
4152 let v:errmsg = ""
4153 let caught = 0
4154 if 1
4155 else
4156 elseif 1 ||| 2
4157 endif
4158 catch /^Vim\((\a\+)\)\=:/
4159 let caught = 1
4160 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
4161 finally
4162 Xpath 4096 " X: 4096
4163 if !caught && !$VIMNOERRTHROW
4164 Xpath 8192 " X: 0
4165 endif
4166 if !MSG('E584', ":elseif after :else")
4167 Xpath 16384 " X: 0
4168 endif
4169 endtry
4170 catch /.*/
4171 Xpath 32768 " X: 0
4172 Xout v:exception "in" v:throwpoint
4173 finally
4174 break " discard error for $VIMNOERRTHROW
4175 endtry
4176endwhile
4177
4178while 1
4179 try
4180 try
4181 let v:errmsg = ""
4182 let caught = 0
4183 elseif 1 ||| 2
4184 catch /^Vim\((\a\+)\)\=:/
4185 let caught = 1
4186 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
4187 finally
4188 Xpath 65536 " X: 65536
4189 if !caught && !$VIMNOERRTHROW
4190 Xpath 131072 " X: 0
4191 endif
4192 if !MSG('E582', ":elseif without :if")
4193 Xpath 262144 " X: 0
4194 endif
4195 endtry
4196 catch /.*/
4197 Xpath 524288 " X: 0
4198 Xout v:exception "in" v:throwpoint
4199 finally
4200 break " discard error for $VIMNOERRTHROW
4201 endtry
4202endwhile
4203
4204while 1
4205 try
4206 try
4207 let v:errmsg = ""
4208 let caught = 0
4209 while 1
4210 elseif 1 ||| 2
4211 endwhile
4212 catch /^Vim\((\a\+)\)\=:/
4213 let caught = 1
4214 let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "")
4215 finally
4216 Xpath 1048576 " X: 1048576
4217 if !caught && !$VIMNOERRTHROW
4218 Xpath 2097152 " X: 0
4219 endif
4220 if !MSG('E582', ":elseif without :if")
4221 Xpath 4194304 " X: 0
4222 endif
4223 endtry
4224 catch /.*/
4225 Xpath 8388608 " X: 0
4226 Xout v:exception "in" v:throwpoint
4227 finally
4228 break " discard error for $VIMNOERRTHROW
4229 endtry
4230endwhile
4231
4232Xpath 16777216 " X: 16777216
4233
4234unlet! caught
4235delfunction MSG
4236
4237Xcheck 17895765
4238
4239
4240"-------------------------------------------------------------------------------
4241" Test 81: Discarding exceptions after an error or interrupt {{{1
4242"
4243" When an exception is thrown from inside a :try conditional without
4244" :catch and :finally clauses and an error or interrupt occurs before
4245" the :endtry is reached, the exception is discarded.
4246"-------------------------------------------------------------------------------
4247
4248XpathINIT
4249
4250if ExtraVim()
4251 try
4252 Xpath 1 " X: 1
4253 try
4254 Xpath 2 " X: 2
4255 throw "arrgh"
4256 Xpath 4 " X: 0
4257" if 1
4258 Xpath 8 " X: 0
4259 " error after :throw: missing :endif
4260 endtry
4261 Xpath 16 " X: 0
4262 catch /arrgh/
4263 Xpath 32 " X: 0
4264 endtry
4265 Xpath 64 " X: 0
4266endif
4267
4268if ExtraVim()
4269 try
4270 Xpath 128 " X: 128
4271 try
4272 Xpath 256 " X: 256
4273 throw "arrgh"
4274 Xpath 512 " X: 0
4275 endtry " INTERRUPT
4276 Xpath 1024 " X: 0
4277 catch /arrgh/
4278 Xpath 2048 " X: 0
4279 endtry
4280 Xpath 4096 " X: 0
4281endif
4282
4283Xcheck 387
4284
4285
4286"-------------------------------------------------------------------------------
4287" Test 82: Ignoring :catch clauses after an error or interrupt {{{1
4288"
4289" When an exception is thrown and an error or interrupt occurs before
4290" the matching :catch clause is reached, the exception is discarded
4291" and the :catch clause is ignored (also for the error or interrupt
4292" exception being thrown then).
4293"-------------------------------------------------------------------------------
4294
4295XpathINIT
4296
4297if ExtraVim()
4298 try
4299 try
4300 Xpath 1 " X: 1
4301 throw "arrgh"
4302 Xpath 2 " X: 0
4303" if 1
4304 Xpath 4 " X: 0
4305 " error after :throw: missing :endif
4306 catch /.*/
4307 Xpath 8 " X: 0
4308 Xout v:exception "in" ExtraVimThrowpoint()
4309 catch /.*/
4310 Xpath 16 " X: 0
4311 Xout v:exception "in" ExtraVimThrowpoint()
4312 endtry
4313 Xpath 32 " X: 0
4314 catch /arrgh/
4315 Xpath 64 " X: 0
4316 endtry
4317 Xpath 128 " X: 0
4318endif
4319
4320if ExtraVim()
4321 function! E()
4322 try
4323 try
4324 Xpath 256 " X: 256
4325 throw "arrgh"
4326 Xpath 512 " X: 0
4327" if 1
4328 Xpath 1024 " X: 0
4329 " error after :throw: missing :endif
4330 catch /.*/
4331 Xpath 2048 " X: 0
4332 Xout v:exception "in" ExtraVimThrowpoint()
4333 catch /.*/
4334 Xpath 4096 " X: 0
4335 Xout v:exception "in" ExtraVimThrowpoint()
4336 endtry
4337 Xpath 8192 " X: 0
4338 catch /arrgh/
4339 Xpath 16384 " X: 0
4340 endtry
4341 endfunction
4342
4343 call E()
4344 Xpath 32768 " X: 0
4345endif
4346
4347if ExtraVim()
4348 try
4349 try
4350 Xpath 65536 " X: 65536
4351 throw "arrgh"
4352 Xpath 131072 " X: 0
4353 catch /.*/ "INTERRUPT
4354 Xpath 262144 " X: 0
4355 Xout v:exception "in" ExtraVimThrowpoint()
4356 catch /.*/
4357 Xpath 524288 " X: 0
4358 Xout v:exception "in" ExtraVimThrowpoint()
4359 endtry
4360 Xpath 1048576 " X: 0
4361 catch /arrgh/
4362 Xpath 2097152 " X: 0
4363 endtry
4364 Xpath 4194304 " X: 0
4365endif
4366
4367if ExtraVim()
4368 function I()
4369 try
4370 try
4371 Xpath 8388608 " X: 8388608
4372 throw "arrgh"
4373 Xpath 16777216 " X: 0
4374 catch /.*/ "INTERRUPT
4375 Xpath 33554432 " X: 0
4376 Xout v:exception "in" ExtraVimThrowpoint()
4377 catch /.*/
4378 Xpath 67108864 " X: 0
4379 Xout v:exception "in" ExtraVimThrowpoint()
4380 endtry
4381 Xpath 134217728 " X: 0
4382 catch /arrgh/
4383 Xpath 268435456 " X: 0
4384 endtry
4385 endfunction
4386
4387 call I()
4388 Xpath 536870912 " X: 0
4389endif
4390
4391Xcheck 8454401
4392
4393
4394"-------------------------------------------------------------------------------
4395" Test 83: Executing :finally clauses after an error or interrupt {{{1
4396"
4397" When an exception is thrown and an error or interrupt occurs before
4398" the :finally of the innermost :try is reached, the exception is
4399" discarded and the :finally clause is executed.
4400"-------------------------------------------------------------------------------
4401
4402XpathINIT
4403
4404if ExtraVim()
4405 try
4406 Xpath 1 " X: 1
4407 try
4408 Xpath 2 " X: 2
4409 throw "arrgh"
4410 Xpath 4 " X: 0
4411" if 1
4412 Xpath 8 " X: 0
4413 " error after :throw: missing :endif
4414 finally
4415 Xpath 16 " X: 16
4416 endtry
4417 Xpath 32 " X: 0
4418 catch /arrgh/
4419 Xpath 64 " X: 0
4420 endtry
4421 Xpath 128 " X: 0
4422endif
4423
4424if ExtraVim()
4425 try
4426 Xpath 256 " X: 256
4427 try
4428 Xpath 512 " X: 512
4429 throw "arrgh"
4430 Xpath 1024 " X: 0
4431 finally "INTERRUPT
4432 Xpath 2048 " X: 2048
4433 endtry
4434 Xpath 4096 " X: 0
4435 catch /arrgh/
4436 Xpath 8192 " X: 0
4437 endtry
4438 Xpath 16384 " X: 0
4439endif
4440
4441Xcheck 2835
4442
4443
4444"-------------------------------------------------------------------------------
4445" Test 84: Exceptions in autocommand sequences. {{{1
4446"
4447" When an exception occurs in a sequence of autocommands for
4448" a specific event, the rest of the sequence is not executed. The
4449" command that triggered the autocommand execution aborts, and the
4450" exception is propagated to the caller.
4451"
4452" For the FuncUndefined event under a function call expression or
Bram Moolenaarbc045ea2005-06-05 22:01:26 +00004453" :call command, the function is not executed, even when it has
Bram Moolenaar071d4272004-06-13 20:20:40 +00004454" been defined by the autocommands before the exception occurred.
4455"-------------------------------------------------------------------------------
4456
4457XpathINIT
4458
4459if ExtraVim()
4460
4461 function! INT()
4462 "INTERRUPT
4463 let dummy = 0
4464 endfunction
4465
4466 aug TMP
4467 autocmd!
4468
4469 autocmd User x1 Xpath 1 " X: 1
4470 autocmd User x1 throw "x1"
4471 autocmd User x1 Xpath 2 " X: 0
4472
4473 autocmd User x2 Xpath 4 " X: 4
4474 autocmd User x2 asdf
4475 autocmd User x2 Xpath 8 " X: 0
4476
4477 autocmd User x3 Xpath 16 " X: 16
4478 autocmd User x3 call INT()
4479 autocmd User x3 Xpath 32 " X: 0
4480
4481 autocmd FuncUndefined U1 function! U1()
4482 autocmd FuncUndefined U1 Xpath 64 " X: 0
4483 autocmd FuncUndefined U1 endfunction
4484 autocmd FuncUndefined U1 Xpath 128 " X: 128
4485 autocmd FuncUndefined U1 throw "U1"
4486 autocmd FuncUndefined U1 Xpath 256 " X: 0
4487
4488 autocmd FuncUndefined U2 function! U2()
4489 autocmd FuncUndefined U2 Xpath 512 " X: 0
4490 autocmd FuncUndefined U2 endfunction
4491 autocmd FuncUndefined U2 Xpath 1024 " X: 1024
4492 autocmd FuncUndefined U2 ASDF
4493 autocmd FuncUndefined U2 Xpath 2048 " X: 0
4494
4495 autocmd FuncUndefined U3 function! U3()
4496 autocmd FuncUndefined U3 Xpath 4096 " X: 0
4497 autocmd FuncUndefined U3 endfunction
4498 autocmd FuncUndefined U3 Xpath 8192 " X: 8192
4499 autocmd FuncUndefined U3 call INT()
4500 autocmd FuncUndefined U3 Xpath 16384 " X: 0
4501 aug END
4502
4503 try
4504 try
4505 Xpath 32768 " X: 32768
4506 doautocmd User x1
4507 catch /x1/
4508 Xpath 65536 " X: 65536
4509 endtry
4510
4511 while 1
4512 try
4513 Xpath 131072 " X: 131072
4514 let caught = 0
4515 doautocmd User x2
4516 catch /asdf/
4517 let caught = 1
4518 finally
4519 Xpath 262144 " X: 262144
4520 if !caught && !$VIMNOERRTHROW
4521 Xpath 524288 " X: 0
4522 " Propagate uncaught error exception,
4523 else
4524 " ... but break loop for caught error exception,
4525 " or discard error and break loop if $VIMNOERRTHROW
4526 break
4527 endif
4528 endtry
4529 endwhile
4530
4531 while 1
4532 try
4533 Xpath 1048576 " X: 1048576
4534 let caught = 0
4535 doautocmd User x3
4536 catch /Vim:Interrupt/
4537 let caught = 1
4538 finally
4539 Xpath 2097152 " X: 2097152
4540 if !caught && !$VIMNOINTTHROW
4541 Xpath 4194304 " X: 0
4542 " Propagate uncaught interrupt exception,
4543 else
4544 " ... but break loop for caught interrupt exception,
4545 " or discard interrupt and break loop if $VIMNOINTTHROW
4546 break
4547 endif
4548 endtry
4549 endwhile
4550
4551 if exists("*U1") | delfunction U1 | endif
4552 if exists("*U2") | delfunction U2 | endif
4553 if exists("*U3") | delfunction U3 | endif
4554
4555 try
4556 Xpath 8388608 " X: 8388608
4557 call U1()
4558 catch /U1/
4559 Xpath 16777216 " X: 16777216
4560 endtry
4561
4562 while 1
4563 try
4564 Xpath 33554432 " X: 33554432
4565 let caught = 0
4566 call U2()
4567 catch /ASDF/
4568 let caught = 1
4569 finally
4570 Xpath 67108864 " X: 67108864
4571 if !caught && !$VIMNOERRTHROW
4572 Xpath 134217728 " X: 0
4573 " Propagate uncaught error exception,
4574 else
4575 " ... but break loop for caught error exception,
4576 " or discard error and break loop if $VIMNOERRTHROW
4577 break
4578 endif
4579 endtry
4580 endwhile
4581
4582 while 1
4583 try
4584 Xpath 268435456 " X: 268435456
4585 let caught = 0
4586 call U3()
4587 catch /Vim:Interrupt/
4588 let caught = 1
4589 finally
4590 Xpath 536870912 " X: 536870912
4591 if !caught && !$VIMNOINTTHROW
4592 Xpath 1073741824 " X: 0
4593 " Propagate uncaught interrupt exception,
4594 else
4595 " ... but break loop for caught interrupt exception,
4596 " or discard interrupt and break loop if $VIMNOINTTHROW
4597 break
4598 endif
4599 endtry
4600 endwhile
4601 catch /.*/
4602 " The Xpath command does not accept 2^31 (negative); display explicitly:
4603 exec "!echo 2147483648 >>" . g:ExtraVimResult
4604 Xout "Caught" v:exception "in" v:throwpoint
4605 endtry
4606
4607 unlet caught
4608 delfunction INT
4609 delfunction U1
4610 delfunction U2
4611 delfunction U3
4612 au! TMP
4613 aug! TMP
4614endif
4615
4616Xcheck 934782101
4617
4618
4619"-------------------------------------------------------------------------------
4620" Test 85: Error exceptions in autocommands for I/O command events {{{1
4621"
4622" When an I/O command is inside :try/:endtry, autocommands to be
4623" executed after it should be skipped on an error (exception) in the
4624" command itself or in autocommands to be executed before the command.
4625" In the latter case, the I/O command should not be executed either.
4626" Example 1: BufWritePre, :write, BufWritePost
4627" Example 2: FileReadPre, :read, FileReadPost.
4628"-------------------------------------------------------------------------------
4629
4630XpathINIT
4631
4632function! MSG(enr, emsg)
4633 let english = v:lang == "C" || v:lang =~ '^[Ee]n'
4634 if a:enr == ""
4635 Xout "TODO: Add message number for:" a:emsg
4636 let v:errmsg = ":" . v:errmsg
4637 endif
4638 let match = 1
4639 if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
4640 let match = 0
4641 if v:errmsg == ""
4642 Xout "Message missing."
4643 else
4644 let v:errmsg = escape(v:errmsg, '"')
4645 Xout "Unexpected message:" v:errmsg
4646 endif
4647 endif
4648 return match
4649endfunction
4650
4651" Remove the autocommands for the events specified as arguments in all used
4652" autogroups.
Bram Moolenaar1e115362019-01-09 23:01:02 +01004653function Delete_autocommands(...)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004654 let augfile = tempname()
4655 while 1
4656 try
4657 exec "redir >" . augfile
4658 aug
4659 redir END
4660 exec "edit" augfile
4661 g/^$/d
4662 norm G$
4663 let wrap = "w"
4664 while search('\%( \|^\)\@<=.\{-}\%( \)\@=', wrap) > 0
4665 let wrap = "W"
4666 exec "norm y/ \n"
4667 let argno = 1
4668 while argno <= a:0
4669 exec "au!" escape(@", " ") a:{argno}
4670 let argno = argno + 1
4671 endwhile
4672 endwhile
4673 catch /.*/
4674 finally
4675 bwipeout!
4676 call delete(augfile)
4677 break " discard errors for $VIMNOERRTHROW
4678 endtry
4679 endwhile
4680endfunction
4681
4682call Delete_autocommands("BufWritePre", "BufWritePost")
4683
4684while 1
4685 try
4686 try
4687 let post = 0
4688 aug TMP
4689 au! BufWritePost * let post = 1
4690 aug END
4691 let caught = 0
4692 write /n/o/n/e/x/i/s/t/e/n/t
4693 catch /^Vim(write):/
4694 let caught = 1
4695 let v:errmsg = substitute(v:exception, '^Vim(write):', '', "")
4696 finally
4697 Xpath 1 " X: 1
4698 if !caught && !$VIMNOERRTHROW
4699 Xpath 2 " X: 0
4700 endif
4701 let v:errmsg = substitute(v:errmsg, '^"/n/o/n/e/x/i/s/t/e/n/t" ',
4702 \ '', "")
4703 if !MSG('E212', "Can't open file for writing")
4704 Xpath 4 " X: 0
4705 endif
4706 if post
4707 Xpath 8 " X: 0
4708 Xout "BufWritePost commands executed after write error"
4709 endif
4710 au! TMP
4711 aug! TMP
4712 endtry
4713 catch /.*/
4714 Xpath 16 " X: 0
4715 Xout v:exception "in" v:throwpoint
4716 finally
4717 break " discard error for $VIMNOERRTHROW
4718 endtry
4719endwhile
4720
4721while 1
4722 try
4723 try
4724 let post = 0
4725 aug TMP
4726 au! BufWritePre * asdf
4727 au! BufWritePost * let post = 1
4728 aug END
4729 let tmpfile = tempname()
4730 let caught = 0
4731 exec "write" tmpfile
4732 catch /^Vim\((write)\)\=:/
4733 let caught = 1
4734 let v:errmsg = substitute(v:exception, '^Vim\((write)\)\=:', '', "")
4735 finally
4736 Xpath 32 " X: 32
4737 if !caught && !$VIMNOERRTHROW
4738 Xpath 64 " X: 0
4739 endif
4740 let v:errmsg = substitute(v:errmsg, '^"'.tmpfile.'" ', '', "")
4741 if !MSG('E492', "Not an editor command")
4742 Xpath 128 " X: 0
4743 endif
4744 if filereadable(tmpfile)
4745 Xpath 256 " X: 0
4746 Xout ":write command not suppressed after BufWritePre error"
4747 endif
4748 if post
4749 Xpath 512 " X: 0
4750 Xout "BufWritePost commands executed after BufWritePre error"
4751 endif
4752 au! TMP
4753 aug! TMP
4754 endtry
4755 catch /.*/
4756 Xpath 1024 " X: 0
4757 Xout v:exception "in" v:throwpoint
4758 finally
4759 break " discard error for $VIMNOERRTHROW
4760 endtry
4761endwhile
4762
4763call delete(tmpfile)
4764
4765call Delete_autocommands("BufWritePre", "BufWritePost",
4766 \ "BufReadPre", "BufReadPost", "FileReadPre", "FileReadPost")
4767
4768while 1
4769 try
4770 try
4771 let post = 0
4772 aug TMP
4773 au! FileReadPost * let post = 1
4774 aug END
4775 let caught = 0
4776 read /n/o/n/e/x/i/s/t/e/n/t
4777 catch /^Vim(read):/
4778 let caught = 1
4779 let v:errmsg = substitute(v:exception, '^Vim(read):', '', "")
4780 finally
4781 Xpath 2048 " X: 2048
4782 if !caught && !$VIMNOERRTHROW
4783 Xpath 4096 " X: 0
4784 endif
4785 let v:errmsg = substitute(v:errmsg, ' /n/o/n/e/x/i/s/t/e/n/t$',
4786 \ '', "")
4787 if !MSG('E484', "Can't open file")
4788 Xpath 8192 " X: 0
4789 endif
4790 if post
4791 Xpath 16384 " X: 0
4792 Xout "FileReadPost commands executed after write error"
4793 endif
4794 au! TMP
4795 aug! TMP
4796 endtry
4797 catch /.*/
4798 Xpath 32768 " X: 0
4799 Xout v:exception "in" v:throwpoint
4800 finally
4801 break " discard error for $VIMNOERRTHROW
4802 endtry
4803endwhile
4804
4805while 1
4806 try
4807 let infile = tempname()
4808 let tmpfile = tempname()
4809 exec "!echo XYZ >" . infile
4810 exec "edit" tmpfile
4811 try
4812 Xpath 65536 " X: 65536
4813 try
4814 let post = 0
4815 aug TMP
4816 au! FileReadPre * asdf
4817 au! FileReadPost * let post = 1
4818 aug END
4819 let caught = 0
4820 exec "0read" infile
4821 catch /^Vim\((read)\)\=:/
4822 let caught = 1
4823 let v:errmsg = substitute(v:exception, '^Vim\((read)\)\=:', '',
4824 \ "")
4825 finally
4826 Xpath 131072 " X: 131072
4827 if !caught && !$VIMNOERRTHROW
4828 Xpath 262144 " X: 0
4829 endif
4830 let v:errmsg = substitute(v:errmsg, ' '.infile.'$', '', "")
4831 if !MSG('E492', "Not an editor command")
4832 Xpath 524288 " X: 0
4833 endif
4834 if getline("1") == "XYZ"
4835 Xpath 1048576 " X: 0
4836 Xout ":read command not suppressed after FileReadPre error"
4837 endif
4838 if post
4839 Xpath 2097152 " X: 0
4840 Xout "FileReadPost commands executed after " .
4841 \ "FileReadPre error"
4842 endif
4843 au! TMP
4844 aug! TMP
4845 endtry
4846 finally
4847 bwipeout!
4848 endtry
4849 catch /.*/
4850 Xpath 4194304 " X: 0
4851 Xout v:exception "in" v:throwpoint
4852 finally
4853 break " discard error for $VIMNOERRTHROW
4854 endtry
4855endwhile
4856
4857call delete(infile)
4858call delete(tmpfile)
4859unlet! caught post infile tmpfile
4860delfunction MSG
4861delfunction Delete_autocommands
4862
4863Xcheck 198689
4864
Bram Moolenaar41b884b2012-11-14 22:38:08 +01004865"-------------------------------------------------------------------------------
Bram Moolenaar32c8f1c2012-12-05 19:00:06 +01004866" Test 86: setloclist crash {{{1
Bram Moolenaar41b884b2012-11-14 22:38:08 +01004867"
4868" Executing a setloclist() on BufUnload shouldn't crash Vim
4869"-------------------------------------------------------------------------------
4870
4871func F
4872 au BufUnload * :call setloclist(0, [{'bufnr':1, 'lnum':1, 'col':1, 'text': 'tango down'}])
4873
Bram Moolenaarcc908ad2013-06-06 18:55:49 +02004874 :lvimgrep /.*/ *.mak
Bram Moolenaar41b884b2012-11-14 22:38:08 +01004875endfunc
4876
4877XpathINIT
4878
4879ExecAsScript F
4880
4881delfunction F
4882Xout "No Crash for vimgrep on BufUnload"
4883Xcheck 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00004884
Bram Moolenaar1f068232019-11-03 16:17:26 +01004885" Test 87 was moved to test_vimscript.vim
4886let Xtest = 88
Bram Moolenaarb8f84612013-02-26 22:54:11 +01004887
Bram Moolenaarb8f84612013-02-26 22:54:11 +01004888
4889"-------------------------------------------------------------------------------
4890" Test 88: $VIMNOERRTHROW and $VIMNOINTTHROW support {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +00004891"
4892" It is possible to configure Vim for throwing exceptions on error
4893" or interrupt, controlled by variables $VIMNOERRTHROW and
4894" $VIMNOINTTHROW. This is just for increasing the number of tests.
4895" All tests here should run for all four combinations of setting
4896" these variables to 0 or 1. The variables are intended for the
4897" development phase only. In the final release, Vim should be
4898" configured to always use error and interrupt exceptions.
4899"
4900" The test result is "OK",
4901"
4902" - if the $VIMNOERRTHROW and the $VIMNOINTTHROW control are not
4903" configured and exceptions are thrown on error and on
4904" interrupt.
4905"
4906" - if the $VIMNOERRTHROW or the $VIMNOINTTHROW control is
4907" configured and works as intended.
4908"
4909" What actually happens, is shown in the test output.
4910"
4911" Otherwise, the test result is "FAIL", and the test output describes
4912" the problem.
4913"
4914" IMPORTANT: This must be the last test because it sets $VIMNOERRTHROW and
4915" $VIMNOINTTHROW.
4916"-------------------------------------------------------------------------------
4917
4918XpathINIT
4919
4920if ExtraVim()
4921
4922 function! ThrowOnError()
4923 XloopNEXT
4924 let caught = 0
4925 try
4926 Xloop 1 " X: 1 + 8 + 64
4927 asdf
4928 catch /.*/
4929 let caught = 1 " error exception caught
4930 finally
4931 Xloop 2 " X: 2 + 16 + 128
4932 return caught " discard aborting error
4933 endtry
4934 Xloop 4 " X: 0
4935 endfunction
4936
4937 let quits_skipped = 0
4938
4939 function! ThrowOnInterrupt()
4940 XloopNEXT
4941 let caught = 0
4942 try
4943 Xloop 1 " X: (1 + 8 + 64) * 512
4944 "INTERRUPT3
4945 let dummy = 0
4946 let g:quits_skipped = g:quits_skipped + 1
4947 catch /.*/
4948 let caught = 1 " interrupt exception caught
4949 finally
4950 Xloop 2 " X: (2 + 16 + 128) * 512
4951 return caught " discard interrupt
4952 endtry
4953 Xloop 4 " X: 0
4954 endfunction
4955
4956 function! CheckThrow(Type)
4957 execute 'return ThrowOn' . a:Type . '()'
4958 endfunction
4959
4960 function! CheckConfiguration(type) " type is "error" or "interrupt"
4961
4962 let type = a:type
4963 let Type = substitute(type, '.*', '\u&', "")
4964 let VAR = '$VIMNO' . substitute(type, '\(...\).*', '\U\1', "") . 'THROW'
4965
4966 if type == "error"
4967 XloopINIT! 1 8
4968 elseif type == "interrupt"
4969 XloopINIT! 512 8
4970 endif
4971
4972 exec 'let requested_for_tests = exists(VAR) && ' . VAR . ' == 0'
4973 exec 'let suppressed_for_tests = ' . VAR . ' != 0'
4974 let used_in_tests = CheckThrow(Type)
4975
4976 exec 'let ' . VAR . ' = 0'
4977 let request_works = CheckThrow(Type)
4978
4979 exec 'let ' . VAR . ' = 1'
4980 let suppress_works = !CheckThrow(Type)
4981
4982 if type == "error"
4983 XloopINIT! 262144 8
4984 elseif type == "interrupt"
4985 XloopINIT! 2097152 8
4986
4987 if g:quits_skipped != 0
4988 Xloop 1 " X: 0*2097152
4989 Xout "Test environment error. Interrupt breakpoints skipped: "
4990 \ . g:quits_skipped . ".\n"
4991 \ . "Cannot check whether interrupt exceptions are thrown."
4992 return
4993 endif
4994 endif
4995
4996 let failure =
4997 \ !suppressed_for_tests && !used_in_tests
4998 \ || !request_works
4999
5000 let contradiction =
5001 \ used_in_tests
5002 \ ? suppressed_for_tests && !request_works
5003 \ : !suppressed_for_tests
5004
5005 if failure
5006 " Failure in configuration.
5007 Xloop 2 " X: 0 * 2* (262144 + 2097152)
5008 elseif contradiction
5009 " Failure in test logic. Should not happen.
5010 Xloop 4 " X: 0 * 4 * (262144 + 2097152)
5011 endif
5012
5013 let var_control_configured =
5014 \ request_works != used_in_tests
5015 \ || suppress_works == used_in_tests
5016
5017 let var_control_not_configured =
5018 \ requested_for_tests || suppressed_for_tests
5019 \ ? request_works && !suppress_works
5020 \ : request_works == used_in_tests
5021 \ && suppress_works != used_in_tests
5022
5023 let with = used_in_tests ? "with" : "without"
5024
5025 let set = suppressed_for_tests ? "non-zero" :
5026 \ requested_for_tests ? "0" : "unset"
5027
5028 let although = contradiction && !var_control_not_configured
5029 \ ? ",\nalthough "
5030 \ : ".\n"
5031
5032 let output = "All tests were run " . with . " throwing exceptions on "
5033 \ . type . although
5034
5035 if !var_control_not_configured
5036 let output = output . VAR . " was " . set . "."
5037
5038 if !request_works && !requested_for_tests
5039 let output = output .
5040 \ "\n" . Type . " exceptions are not thrown when " . VAR .
5041 \ " is\nset to 0."
5042 endif
5043
5044 if !suppress_works && (!used_in_tests ||
5045 \ !request_works &&
5046 \ !requested_for_tests && !suppressed_for_tests)
5047 let output = output .
5048 \ "\n" . Type . " exceptions are thrown when " . VAR .
5049 \ " is set to 1."
5050 endif
5051
5052 if !failure && var_control_configured
5053 let output = output .
5054 \ "\nRun tests also with " . substitute(VAR, '^\$', '', "")
5055 \ . "=" . used_in_tests . "."
5056 \ . "\nThis is for testing in the development phase only."
5057 \ . " Remove the \n"
5058 \ . VAR . " control in the final release."
5059 endif
5060 else
5061 let output = output .
5062 \ "The " . VAR . " control is not configured."
5063 endif
5064
5065 Xout output
5066 endfunction
5067
5068 call CheckConfiguration("error")
5069 Xpath 16777216 " X: 16777216
5070 call CheckConfiguration("interrupt")
5071 Xpath 33554432 " X: 33554432
5072endif
5073
5074Xcheck 50443995
5075
5076" IMPORTANT: No test should be added after this test because it changes
5077" $VIMNOERRTHROW and $VIMNOINTTHROW.
5078
5079
5080"-------------------------------------------------------------------------------
5081" Modelines {{{1
5082" vim: ts=8 sw=4 tw=80 fdm=marker
Bram Moolenaar071d4272004-06-13 20:20:40 +00005083"-------------------------------------------------------------------------------