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