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