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