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