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