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