To: vim_dev@googlegroups.com Subject: Patch 8.2.1420 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1420 Problem: Test 49 is old style. Solution: Convert remaining parts to new style. Remove obsolete items. (Yegappan Lakshmanan, closes #6683) Files: Filelist, runtime/doc/testing.txt, src/Make_mvc.mak, src/Makefile, src/testdir/Make_all.mak, src/testdir/Make_amiga.mak, src/testdir/Make_dos.mak, src/testdir/Make_ming.mak, src/testdir/Make_vms.mms, src/testdir/Makefile, src/testdir/README.txt, src/testdir/test49.in, src/testdir/test49.ok, src/testdir/test49.vim, src/testdir/test_quickfix.vim, src/testdir/test_vimscript.vim *** ../vim-8.2.1419/Filelist 2020-08-09 15:24:52.161418771 +0200 --- Filelist 2020-08-11 20:33:54.229066138 +0200 *************** *** 158,164 **** src/testdir/gen_opt_test.vim \ src/testdir/README.txt \ src/testdir/Make_all.mak \ ! src/testdir/*.in \ src/testdir/*.py \ src/testdir/lsan-suppress.txt \ src/testdir/sautest/autoload/*.vim \ --- 158,166 ---- src/testdir/gen_opt_test.vim \ src/testdir/README.txt \ src/testdir/Make_all.mak \ ! src/testdir/dotest.in \ ! src/testdir/test1.in \ ! src/testdir/test77a.in \ src/testdir/*.py \ src/testdir/lsan-suppress.txt \ src/testdir/sautest/autoload/*.vim \ *************** *** 177,185 **** src/testdir/summarize.vim \ src/testdir/term_util.vim \ src/testdir/view_util.vim \ ! src/testdir/test[0-9]*.ok \ ! src/testdir/test[0-9]*a.ok \ ! src/testdir/test49.vim \ src/testdir/test83-tags? \ src/testdir/test77a.com \ src/testdir/test_*.vim \ --- 179,186 ---- src/testdir/summarize.vim \ src/testdir/term_util.vim \ src/testdir/view_util.vim \ ! - src/testdir/test1.ok \ ! src/testdir/test77a.ok \ src/testdir/test83-tags? \ src/testdir/test77a.com \ src/testdir/test_*.vim \ *** ../vim-8.2.1419/runtime/doc/testing.txt 2020-07-11 22:14:54.310422225 +0200 --- runtime/doc/testing.txt 2020-08-11 19:29:37.978754232 +0200 *************** *** 20,37 **** Vim can be tested after building it, usually with "make test". The tests are located in the directory "src/testdir". - There are several types of tests added over time: - test33.in oldest, don't add any of these - test_something.in old style tests - test_something.vim new style tests - *new-style-testing* ! New tests should be added as new style tests. These use functions such as ! |assert_equal()| to keep the test commands and the expected result in one ! place. ! *old-style-testing* ! In some cases an old style test needs to be used. E.g. when testing Vim ! without the |+eval| feature. Find more information in the file src/testdir/README.txt. --- 20,30 ---- Vim can be tested after building it, usually with "make test". The tests are located in the directory "src/testdir". *new-style-testing* ! New tests should be added as new style tests. The test scripts are named ! test_.vim (replace with the feature under test). These use ! functions such as |assert_equal()| to keep the test commands and the expected ! result in one place. Find more information in the file src/testdir/README.txt. *** ../vim-8.2.1419/src/Make_mvc.mak 2020-08-09 15:24:52.165418739 +0200 --- src/Make_mvc.mak 2020-08-11 19:56:51.880200584 +0200 *************** *** 1326,1339 **** # Target to run individual tests. VIMTESTTARGET = $(VIM).exe - OLD_TEST_OUTFILES = \ - $(SCRIPTS_FIRST) \ - $(SCRIPTS_ALL) \ - $(SCRIPTS_MORE1) \ - $(SCRIPTS_MORE4) \ - $(SCRIPTS_WIN32) \ - $(SCRIPTS_GUI) - all: $(MAIN_TARGET) \ vimrun.exe \ install.exe \ --- 1326,1331 ---- *************** *** 1485,1493 **** $(MAKE) /NOLOGO -f Make_dos.mak clean cd .. ! # Run individual OLD style test. # These do not depend on the executable, compile it when needed. ! $(OLD_TEST_OUTFILES:.out=): cd testdir - if exist $@.out del $@.out $(MAKE) /NOLOGO -f Make_dos.mak VIMPROG=..\$(VIMTESTTARGET) nolog --- 1477,1485 ---- $(MAKE) /NOLOGO -f Make_dos.mak clean cd .. ! # Run test1 to bootstrap tests # These do not depend on the executable, compile it when needed. ! $(SCRIPTS_FIRST:.out=): cd testdir - if exist $@.out del $@.out $(MAKE) /NOLOGO -f Make_dos.mak VIMPROG=..\$(VIMTESTTARGET) nolog *** ../vim-8.2.1419/src/Makefile 2020-08-09 15:24:52.165418739 +0200 --- src/Makefile 2020-08-11 20:36:08.384410205 +0200 *************** *** 2259,2266 **** # # This will produce a lot of garbage on your screen, including a few error # messages. Don't worry about that. - # If there is a real error, there will be a difference between "testXX.out" and - # a "testXX.ok" file. # If everything is alright, the final message will be "ALL DONE". If not you # get "TEST FAILURE". # --- 2259,2264 ---- *************** *** 2311,2319 **** CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)"; \ fi ! # Run individual OLD style test. ! # These do not depend on the executable, compile it when needed. ! test1 test49: cd testdir; rm -f $@.out; $(MAKE) -f Makefile $@.out VIMPROG=../$(VIMTESTTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE) # Run individual NEW style test. --- 2309,2317 ---- CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)"; \ fi ! # Run test1, used to bootstrap tests. ! # This does not depend on the executable, compile first it when needed. ! test1: cd testdir; rm -f $@.out; $(MAKE) -f Makefile $@.out VIMPROG=../$(VIMTESTTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE) # Run individual NEW style test. *** ../vim-8.2.1419/src/testdir/Make_all.mak 2020-08-02 16:10:02.355921894 +0200 --- src/testdir/Make_all.mak 2020-08-11 20:00:29.251039951 +0200 *************** *** 10,33 **** # The first script creates small.vim. SCRIPTS_FIRST = test1.out - # Tests that run on all systems. - SCRIPTS_ALL = - - # Tests that run on most systems, but not on Amiga. - SCRIPTS_MORE1 = - - # Tests that run on most systems, but not on Amiga and DOS/Windows. - SCRIPTS_MORE2 = test49.out - - # Tests that run on most systems, but not on VMS - SCRIPTS_MORE4 = - - # Tests specifically for MS-Windows. - SCRIPTS_WIN32 = - - # Tests for the GUI. - SCRIPTS_GUI = - # Tests for Vim9 script. TEST_VIM9 = \ test_vim9_cmd \ --- 10,15 ---- *** ../vim-8.2.1419/src/testdir/Make_amiga.mak 2020-07-27 20:02:21.008597321 +0200 --- src/testdir/Make_amiga.mak 2020-08-11 20:37:08.800114855 +0200 *************** *** 9,22 **** include Make_all.mak ! SCRIPTS = $(SCRIPTS_ALL) $(SCRIPTS_MORE4) ! # Must run test1 first to create small.vim. ! $(SCRIPTS) $(SCRIPTS_GUI) $(NEW_TESTS_RES): $(SCRIPTS_FIRST) ! ! .SUFFIXES: .in .out ! ! nongui: /tmp $(SCRIPTS_FIRST) $(SCRIPTS) csh -c echo ALL DONE clean: --- 9,17 ---- include Make_all.mak ! .SUFFIXES: .in .out .res .vim ! nongui: /tmp $(SCRIPTS_FIRST) csh -c echo ALL DONE clean: *** ../vim-8.2.1419/src/testdir/Make_dos.mak 2020-07-29 16:08:13.457861141 +0200 --- src/testdir/Make_dos.mak 2020-08-11 20:07:38.464837783 +0200 *************** *** 9,33 **** !include Make_all.mak ! # Omitted: ! # test49 fails in various ways ! ! SCRIPTS = $(SCRIPTS_ALL) $(SCRIPTS_MORE1) $(SCRIPTS_MORE4) ! ! TEST_OUTFILES = $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_WIN32) $(SCRIPTS_GUI) DOSTMP = dostmp DOSTMP_OUTFILES = $(TEST_OUTFILES:test=dostmp\test) DOSTMP_INFILES = $(DOSTMP_OUTFILES:.out=.in) .SUFFIXES: .in .out .res .vim ! nongui: nolog $(SCRIPTS_FIRST) $(SCRIPTS) newtests report small: nolog report ! gui: nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_GUI) newtests report ! win32: nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_WIN32) newtests report # Copy the input files to dostmp, changing the fileformat to dos. $(DOSTMP_INFILES): $(*B).in --- 9,28 ---- !include Make_all.mak ! TEST_OUTFILES = $(SCRIPTS_FIRST) DOSTMP = dostmp DOSTMP_OUTFILES = $(TEST_OUTFILES:test=dostmp\test) DOSTMP_INFILES = $(DOSTMP_OUTFILES:.out=.in) .SUFFIXES: .in .out .res .vim ! nongui: nolog $(SCRIPTS_FIRST) newtests report small: nolog report ! gui: nolog $(SCRIPTS_FIRST) newtests report ! win32: nolog $(SCRIPTS_FIRST) newtests report # Copy the input files to dostmp, changing the fileformat to dos. $(DOSTMP_INFILES): $(*B).in *** ../vim-8.2.1419/src/testdir/Make_ming.mak 2020-07-29 16:08:13.457861141 +0200 --- src/testdir/Make_ming.mak 2020-08-11 20:38:53.855601381 +0200 *************** *** 28,46 **** include Make_all.mak - SCRIPTS = $(SCRIPTS_ALL) $(SCRIPTS_MORE1) $(SCRIPTS_MORE4) $(SCRIPTS_WIN32) - SCRIPTS_BENCH = test_bench_regexp.res # Must run test1 first to create small.vim. ! $(SCRIPTS) $(SCRIPTS_GUI) $(SCRIPTS_WIN32) $(NEW_TESTS_RES): $(SCRIPTS_FIRST) .SUFFIXES: .in .out .res .vim ! vimall: fixff $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_GUI) $(SCRIPTS_WIN32) newtests @echo ALL DONE ! nongui: fixff nolog $(SCRIPTS_FIRST) $(SCRIPTS) newtests @echo ALL DONE benchmark: $(SCRIPTS_BENCH) --- 28,44 ---- include Make_all.mak SCRIPTS_BENCH = test_bench_regexp.res # Must run test1 first to create small.vim. ! $(NEW_TESTS_RES): $(SCRIPTS_FIRST) .SUFFIXES: .in .out .res .vim ! vimall: fixff $(SCRIPTS_FIRST) newtests @echo ALL DONE ! nongui: fixff nolog $(SCRIPTS_FIRST) newtests @echo ALL DONE benchmark: $(SCRIPTS_BENCH) *************** *** 48,57 **** small: nolog @echo ALL DONE ! gui: fixff nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_GUI) newtests @echo ALL DONE ! win32: fixff nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_WIN32) newtests @echo ALL DONE # TODO: find a way to avoid changing the distributed files. --- 46,55 ---- small: nolog @echo ALL DONE ! gui: fixff nolog $(SCRIPTS_FIRST) newtests @echo ALL DONE ! win32: fixff nolog $(SCRIPTS_FIRST) newtests @echo ALL DONE # TODO: find a way to avoid changing the distributed files. *************** *** 88,106 **** -@if exist test.out $(DEL) test.out -@if exist viminfo $(DEL) viminfo - .in.out: - -@if exist $*.ok $(CP) $*.ok test.ok - $(VIMPROG) -u dos.vim $(NO_INITS) -s dotest.in $*.in - @diff test.out $*.ok - -@if exist $*.out $(DEL) $*.out - @$(MV) test.out $*.out - -@if exist Xdir1 $(DELDIR) Xdir1 - -@if exist Xfind $(DELDIR) Xfind - -@if exist XfakeHOME $(DELDIR) XfakeHOME - -@if exist X* $(DEL) X* - -@if exist test.ok $(DEL) test.ok - -@if exist viminfo $(DEL) viminfo - nolog: -@if exist test.log $(DEL) test.log -@if exist messages $(DEL) messages --- 86,91 ---- *** ../vim-8.2.1419/src/testdir/Make_vms.mms 2020-08-02 16:10:02.355921894 +0200 --- src/testdir/Make_vms.mms 2020-08-11 19:29:37.982754214 +0200 *************** *** 27,52 **** # Uncomment if you want tests in GUI mode. Terminal mode is default. # WANT_GUI = YES - # Comment out if you want to run Unix specific tests as well, but please - # be aware, that on OpenVMS will fail, because of cat, rm, etc commands - # and directory handling. - # WANT_UNIX = YES - - # Comment out if you have gzip on your system - # HAVE_GZIP = YES - - # Comment out if you have GNU compatible diff on your system - # HAVE_GDIFF = YES - - # Comment out if you have ICONV support - # HAVE_ICONV = YES - - # Comment out if you have LUA support - # HAVE_LUA = YES - - # Comment out if you have PYTHON support - # HAVE_PYTHON = YES - ####################################################################### # End of configuration section. # --- 27,32 ---- *************** *** 57,72 **** .SUFFIXES : .out .in ! SCRIPT = test1.out test49.out test77a.out .IFDEF WANT_GUI GUI_OPTION = -g .ENDIF - .IFDEF WANT_UNIX - SCRIPT_UNIX = test49.out - .ENDIF - .in.out : -@ !clean up before doing the test -@ if "''F$SEARCH("test.out.*")'" .NES. "" then delete/noconfirm/nolog test.out.* --- 37,48 ---- .SUFFIXES : .out .in ! SCRIPT = test1.out test77a.out .IFDEF WANT_GUI GUI_OPTION = -g .ENDIF .in.out : -@ !clean up before doing the test -@ if "''F$SEARCH("test.out.*")'" .NES. "" then delete/noconfirm/nolog test.out.* *************** *** 87,93 **** -@ if "''F$SEARCH("Xdotest.*")'" .NES. "" then delete/noconfirm/nolog Xdotest.*.* -@ if "''F$SEARCH("Xtest.*")'" .NES. "" then delete/noconfirm/nolog Xtest.*.* ! all : clean nolog $(START_WITH) $(SCRIPT) $(SCRIPT_UNIX) nolog -@ write sys$output " " -@ write sys$output "-----------------------------------------------" -@ write sys$output " All done" --- 63,69 ---- -@ if "''F$SEARCH("Xdotest.*")'" .NES. "" then delete/noconfirm/nolog Xdotest.*.* -@ if "''F$SEARCH("Xtest.*")'" .NES. "" then delete/noconfirm/nolog Xtest.*.* ! all : clean nolog $(START_WITH) $(SCRIPT) nolog -@ write sys$output " " -@ write sys$output "-----------------------------------------------" -@ write sys$output " All done" *************** *** 111,122 **** -@ write sys$output "-----------------------------------------------" -@ write sys$output "MAKE_VMS.MMS options:" -@ write sys$output " WANT_GUI = ""$(WANT_GUI)"" " - -@ write sys$output " WANT_UNIX = ""$(WANT_UNIX)"" " - -@ write sys$output " HAVE_GZIP = ""$(HAVE_GZIP)"" " - -@ write sys$output " HAVE_GDIFF = ""$(HAVE_GDIFF)"" " - -@ write sys$output " HAVE_ICONV = ""$(HAVE_ICONV)"" " - -@ write sys$output " HAVE_LUA = ""$(HAVE_LUA)"" " - -@ write sys$output " HAVE_PYTHON= ""$(HAVE_PYTHON)"" " -@ write sys$output "Default vimrc file is VMS.VIM:" -@ write sys$output "-----------------------------------------------" -@ type VMS.VIM --- 87,92 ---- *** ../vim-8.2.1419/src/testdir/Makefile 2020-07-01 21:53:33.411476027 +0200 --- src/testdir/Makefile 2020-08-11 20:14:56.194653843 +0200 *************** *** 23,50 **** default: nongui # The list of tests is common to all systems. ! # This defines NEW_TESTS, NEW_TESTS_RES, SCRIPTS_ALL, SCRIPTS_MORE* and ! # SCRIPTS_GUI. include Make_all.mak - - SCRIPTS = $(SCRIPTS_ALL) \ - $(SCRIPTS_MORE1) \ - $(SCRIPTS_MORE2) \ - $(SCRIPTS_MORE4) - # Explicit dependencies. - test49.out: test49.vim - test_options.res test_alot.res: opt_test.vim SCRIPTS_BENCH = test_bench_regexp.res .SUFFIXES: .in .out .res .vim ! nongui: nolog $(SCRIPTS_FIRST) $(SCRIPTS) newtests report ! gui: nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_GUI) newtests report benchmark: $(SCRIPTS_BENCH) --- 23,41 ---- default: nongui # The list of tests is common to all systems. ! # This defines SCRIPTS_FIRST, NEW_TESTS and NEW_TESTS_RES include Make_all.mak # Explicit dependencies. test_options.res test_alot.res: opt_test.vim SCRIPTS_BENCH = test_bench_regexp.res .SUFFIXES: .in .out .res .vim ! nongui: nolog $(SCRIPTS_FIRST) newtests report ! gui: nolog $(SCRIPTS_FIRST) newtests report benchmark: $(SCRIPTS_BENCH) *************** *** 63,72 **** else echo ALL DONE; \ fi" ! $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_GUI) $(NEW_TESTS_RES): $(VIMPROG) # Must run test1 first to create small.vim. ! $(SCRIPTS) $(SCRIPTS_GUI) $(NEW_TESTS_RES): $(SCRIPTS_FIRST) # Execute an individual new style test, e.g.: --- 54,63 ---- else echo ALL DONE; \ fi" ! $(SCRIPTS_FIRST) $(NEW_TESTS_RES): $(VIMPROG) # Must run test1 first to create small.vim. ! $(NEW_TESTS_RES): $(SCRIPTS_FIRST) # Execute an individual new style test, e.g.: *************** *** 116,152 **** echo; exit 1; fi" -rm -rf X* viminfo - .in.out: - -rm -rf $*.failed test.ok $(RM_ON_RUN) - cp $*.ok test.ok - # Sleep a moment to avoid that the xterm title is messed up. - # 200 msec is sufficient, but only modern sleep supports a fraction of - # a second, fall back to a second if it fails. - @-/bin/sh -c "sleep .2 > /dev/null 2>&1 || sleep 1" - $(RUN_VIM) $*.in $(REDIR_TEST_TO_NULL) - - # For flaky tests retry one time. No tests at the moment. - #@/bin/sh -c "if test -f test.out -a $* = test61; then \ - # if diff test.out $*.ok; \ - # then echo flaky test ok first time; \ - # else rm -rf $*.failed $(RM_ON_RUN); \ - # $(RUN_VIM) $*.in; \ - # fi \ - # fi" - - # Check if the test.out file matches test.ok. - @/bin/sh -c "if test -f test.out; then \ - if diff test.out $*.ok; \ - then mv -f test.out $*.out; \ - else echo $* FAILED >>test.log; mv -f test.out $*.failed; \ - fi \ - else echo $* NO OUTPUT >>test.log; \ - fi" - @/bin/sh -c "if test -f valgrind; then\ - mv -f valgrind valgrind.$*; \ - fi" - -rm -rf X* test.ok viminfo - nolog: -rm -f test.log messages --- 107,112 ---- *** ../vim-8.2.1419/src/testdir/README.txt 2020-02-20 22:34:59.264986542 +0100 --- src/testdir/README.txt 2020-08-11 19:29:37.982754214 +0200 *************** *** 4,17 **** If it makes sense, add a new test method to an already existing file. You may want to separate it from other tests with comment lines. - The numbered tests are older, we have switched to named tests. Don't add any - more numbered tests. - - And then you can choose between a new style test, which is a Vim script, or an - old style test, which uses Normal mode commands. Use a new style test if you - can. Use an old style test when it needs to run without the +eval feature. - - TO ADD A NEW STYLE TEST: 1) Create a test_.vim file. --- 4,9 ---- *************** *** 57,72 **** Mostly the same as writing a new style test. Additionally, see help on "terminal-dumptest". Put the reference dump in "dumps/Test_func_name.dump". - - TO ADD AN OLD STYLE TEST: - - 1) Create test_.in and test_.ok files. - 2) Add test_.out to SCRIPTS_ALL in Make_all.mak in alphabetical order. - 3) Use make test_.out to run a single test in src/testdir/. - Use make test_ to run a single test in src/. - 4) Also add an entry in src/Makefile. - - Keep in mind that the files are used as if everything was typed: - - To add comments use: :" (that's an Ex command comment) - - A line break is like pressing Enter. If that happens on the last line - you'll hear a beep! --- 49,51 ---- *** ../vim-8.2.1419/src/testdir/test49.in 2019-05-24 17:30:54.000000000 +0200 --- src/testdir/test49.in 1970-01-01 01:00:00.000000000 +0100 *************** *** 1,32 **** - This is a test of the script language. - - If after adding a new test, the test output doesn't appear properly in - test49.failed, try to add one or more "G"s at the line ending in "test.out" - - STARTTEST - :so small.vim - :se nocp nomore viminfo+=nviminfo - :lang mess C - :so test49.vim - :" Go back to this file and append the results from register r. - :buf test49.in - G"rp:/^Results/,$w! test.out - :" - :" make valgrind happy - :redir => funclist - :silent func - :redir END - :for line in split(funclist, "\n") - : let name = matchstr(line, 'function \zs[A-Z]\w*\ze(') - : if name != '' - : exe "delfunc " . name - : endif - :endfor - :for v in keys(g:) - : silent! exe "unlet " . v - :endfor - :unlet v - :qa! - ENDTEST - - Results of test49.vim: --- 0 ---- *** ../vim-8.2.1419/src/testdir/test49.ok 2020-08-10 22:15:25.555054221 +0200 --- src/testdir/test49.ok 1970-01-01 01:00:00.000000000 +0100 *************** *** 1,12 **** - Results of test49.vim: - *** Test 82: OK (8454401) - *** Test 83: OK (2835) - *** Test 84: OK (934782101) - *** Test 85: OK (198689) - --- Test 86: No Crash for vimgrep on BufUnload - *** Test 86: OK (0) - --- Test 88: All tests were run with throwing exceptions on error. - The $VIMNOERRTHROW control is not configured. - --- Test 88: All tests were run with throwing exceptions on interrupt. - The $VIMNOINTTHROW control is not configured. - *** Test 88: OK (50443995) --- 0 ---- *** ../vim-8.2.1419/src/testdir/test49.vim 2020-08-10 22:15:25.555054221 +0200 --- src/testdir/test49.vim 1970-01-01 01:00:00.000000000 +0100 *************** *** 1,1454 **** - " Vim script language tests - " Author: Servatius Brandt - " Last Change: 2020 Jun 07 - - "------------------------------------------------------------------------------- - " Test environment {{{1 - "------------------------------------------------------------------------------- - - - " Adding new tests easily. {{{2 - " - " Writing new tests is eased considerably with the following functions and - " abbreviations (see "Commands for recording the execution path", "Automatic - " argument generation"). - " - " To get the abbreviations, execute the command - " - " :let test49_set_env = 1 | source test49.vim - " - " To get them always (from src/testdir), put a line - " - " au! BufRead test49.vim let test49_set_env = 1 | source test49.vim - " - " into the local .vimrc file in the src/testdir directory. - " - if exists("test49_set_env") && test49_set_env - - " Automatic argument generation for the test environment commands. - - function! Xsum() - let addend = substitute(getline("."), '^.*"\s*X:\s*\|^.*', '', "") - " Evaluate arithmetic expression. - if addend != "" - exec "let g:Xsum = g:Xsum + " . addend - endif - endfunction - - function! Xcheck() - let g:Xsum=0 - ?XpathINIT?,.call Xsum() - exec "norm A " - return g:Xsum - endfunction - - iab Xcheck Xcheck=Xcheck()x - - function! Xcomment(num) - let str = "" - let tabwidth = &sts ? &sts : &ts - let tabs = (48+tabwidth - a:num - virtcol(".")) / tabwidth - while tabs > 0 - let str = str . "\t" - let tabs = tabs - 1 - endwhile - let str = str . '" X:' - return str - endfunction - - function! Xloop() - let back = line(".") . "|norm" . virtcol(".") . "|" - norm 0 - let last = search('X\(loop\|path\)INIT\|Xloop\>', "bW") - exec back - let theline = getline(last) - if theline =~ 'X\(loop\|path\)INIT' - let num = 1 - else - let num = 2 * substitute(theline, '.*Xloop\s*\(\d\+\).*', '\1', "") - endif - ?X\(loop\|path\)INIT? - \s/\(XloopINIT!\=\s*\d\+\s\+\)\@<=\(\d\+\)/\=2*submatch(2)/ - exec back - exec "norm a " - return num . Xcomment(strlen(num)) - endfunction - - iab Xloop Xloop=Xloop()x - - function! Xpath(loopinit) - let back = line(".") . "|norm" . virtcol(".") . "|" - norm 0 - let last = search('XpathINIT\|Xpath\>\|XloopINIT', "bW") - exec back - let theline = getline(last) - if theline =~ 'XpathINIT' - let num = 1 - elseif theline =~ 'Xpath\>' - let num = 2 * substitute(theline, '.*Xpath\s*\(\d\+\).*', '\1', "") - else - let pattern = '.*XloopINIT!\=\s*\(\d\+\)\s*\(\d\+\).*' - let num = substitute(theline, pattern, '\1', "") - let factor = substitute(theline, pattern, '\2', "") - " The "x" from the "Xpath" iab and the character triggering its - " expansion are in the input buffer. Save and clear typeahead so - " that it is not read away by the call to "input()" below. Restore - " afterwards. - call inputsave() - let loops = input("Number of iterations in previous loop? ") - call inputrestore() - while (loops > 0) - let num = num * factor - let loops = loops - 1 - endwhile - endif - exec "norm a " - if a:loopinit - return num . " 1" - endif - return num . Xcomment(strlen(num)) - endfunction - - iab Xpath Xpath=Xpath(0)x - iab XloopINIT XloopINIT=Xpath(1)x - - " Also useful (see ExtraVim below): - aug ExtraVim - au! - au BufEnter syn region ExtraVim - \ start=+^if\s\+ExtraVim(.*)+ end=+^endif+ - \ transparent keepend - au BufEnter syn match ExtraComment /^"/ - \ contained containedin=ExtraVim - au BufEnter hi link ExtraComment vimComment - aug END - - aug Xpath - au BufEnter syn keyword Xpath - \ XpathINIT Xpath XloopINIT Xloop XloopNEXT Xcheck Xout - au BufEnter hi link Xpath Special - aug END - - do BufEnter - - " Do not execute the tests when sourcing this file for getting the functions - " and abbreviations above, which are intended for easily adding new test - " cases; they are not needed for test execution. Unlet the variable - " controlling this so that an explicit ":source" command for this file will - " execute the tests. - unlet test49_set_env - finish - - endif - - - " Commands for recording the execution path. {{{2 - " - " The Xpath/Xloop commands can be used for computing the eXecution path by - " adding (different) powers of 2 from those script lines, for which the - " execution should be checked. Xloop provides different addends for each - " execution of a loop. Permitted values are 2^0 to 2^30, so that 31 execution - " points (multiply counted inside loops) can be tested. - " - " Note that the arguments of the following commands can be generated - " automatically, see below. - " - " Usage: {{{3 - " - " - Use XpathINIT at the beginning of the test. - " - " - Use Xpath to check if a line is executed. - " Argument: power of 2 (decimal). - " - " - To check multiple execution of loops use Xloop for automatically - " computing Xpath values: - " - " - Use XloopINIT before the loop. - " Two arguments: - " - the first Xpath value (power of 2) to be used (Xnext), - " - factor for computing a new Xnext value when reexecuting a loop - " (by a ":continue" or ":endwhile"); this should be 2^n where - " n is the number of Xloop commands inside the loop. - " If XloopINIT! is used, the first execution of XloopNEXT is - " a no-operation. - " - " - Use Xloop inside the loop: - " One argument: - " The argument and the Xnext value are multiplied to build the - " next Xpath value. No new Xnext value is prepared. The argument - " should be 2^(n-1) for the nth Xloop command inside the loop. - " If the loop has only one Xloop command, the argument can be - " omitted (default: 1). - " - " - Use XloopNEXT before ":continue" and ":endwhile". This computes a new - " Xnext value for the next execution of the loop by multiplying the old - " one with the factor specified in the XloopINIT command. No Argument. - " Alternatively, when XloopINIT! is used, a single XloopNEXT at the - " beginning of the loop can be used. - " - " Nested loops are not supported. - " - " - Use Xcheck at end of each test. It prints the test number, the expected - " execution path value, the test result ("OK" or "FAIL"), and, if the tests - " fails, the actual execution path. - " One argument: - " Expected Xpath/Xloop sum for the correct execution path. - " In order that this value can be computed automatically, do the - " following: For each line in the test with an Xpath and Xloop - " command, add a comment starting with "X:" and specifying an - " expression that evaluates to the value contributed by this line to - " the correct execution path. (For copying an Xpath argument of at - " least two digits into the comment, press .) At the end of the - " test, just type "Xcheck" and press . - " - " - In order to add additional information to the test output file, use the - " Xout command. Argument(s) like ":echo". - " - " Automatic argument generation: {{{3 - " - " The arguments of the Xpath, XloopINIT, Xloop, and Xcheck commands can be - " generated automatically, so that new tests can easily be written without - " mental arithmetic. The Xcheck argument is computed from the "X:" comments - " of the preceding Xpath and Xloop commands. See the commands and - " abbreviations at the beginning of this file. - " - " Implementation: {{{3 - " XpathINIT, Xpath, XloopINIT, Xloop, XloopNEXT, Xcheck, Xout. - " - " The variants for existing g:ExtraVimResult are needed when executing a script - " in an extra Vim process, see ExtraVim below. - - " EXTRA_VIM_START - do not change or remove this line. - - com! XpathINIT let g:Xpath = 0 - - if exists("g:ExtraVimResult") - com! -count -bar Xpath exec "!echo >>" . g:ExtraVimResult - else - com! -count -bar Xpath let g:Xpath = g:Xpath + - endif - - com! -count -nargs=1 -bang - \ XloopINIT let g:Xnext = | - \ let g:Xfactor = | - \ let g:Xskip = strlen("") - - if exists("g:ExtraVimResult") - com! -count=1 -bar Xloop exec "!echo " . (g:Xnext * ) . " >>" . - \ g:ExtraVimResult - else - com! -count=1 -bar Xloop let g:Xpath = g:Xpath + g:Xnext * - endif - - com! XloopNEXT let g:Xnext = g:Xnext * - \ (g:Xskip ? 1 : g:Xfactor) | - \ let g:Xskip = 0 - - let @r = "" - let Xtest = 1 - com! -count Xcheck let Xresult = "*** Test " . - \ (Xtest<10?" ":Xtest<100?" ":"") . - \ Xtest . ": " . ( - \ (Xpath==) ? "OK (".Xpath.")" : - \ "FAIL (".Xpath." instead of )" - \ ) | - \ let @R = Xresult . "\n" | - \ echo Xresult | - \ let Xtest = Xtest + 1 - - if exists("g:ExtraVimResult") - com! -nargs=+ Xoutq exec "!echo @R:'" . - \ substitute(substitute(, - \ "'", '&\\&&', "g"), "\n", "@NL@", "g") - \ . "' >>" . g:ExtraVimResult - else - com! -nargs=+ Xoutq let @R = "--- Test " . - \ (g:Xtest<10?" ":g:Xtest<100?" ":"") . - \ g:Xtest . ": " . substitute(, - \ "\n", "&\t ", "g") . "\n" - endif - com! -nargs=+ Xout exec 'Xoutq' - - " Switch off storing of lines for undoing changes. Speeds things up a little. - set undolevels=-1 - - " EXTRA_VIM_STOP - do not change or remove this line. - - - " ExtraVim() - Run a script file in an extra Vim process. {{{2 - " - " This is useful for testing immediate abortion of the script processing due to - " an error in a command dynamically enclosed by a :try/:tryend region or when an - " exception is thrown but not caught or when an interrupt occurs. It can also - " be used for testing :finish. - " - " An interrupt location can be specified by an "INTERRUPT" comment. A number - " telling how often this location is reached (in a loop or in several function - " calls) should be specified as argument. When missing, once per script - " invocation or function call is assumed. INTERRUPT locations are tested by - " setting a breakpoint in that line and using the ">quit" debug command when - " the breakpoint is reached. A function for which an INTERRUPT location is - " specified must be defined before calling it (or executing it as a script by - " using ExecAsScript below). - " - " This function is only called in normal modus ("g:ExtraVimResult" undefined). - " - " Tests to be executed as an extra script should be written as follows: - " - " column 1 column 1 - " | | - " v v - " - " XpathINIT XpathINIT - " if ExtraVim() if ExtraVim() - " ... " ... - " ... " ... - " endif endif - " Xcheck Xcheck - " - " Double quotes in column 1 are removed before the script is executed. - " They should be used if the test has unbalanced conditionals (:if/:endif, - " :while:/endwhile, :try/:endtry) or for a line with a syntax error. The - " extra script may use Xpath, XloopINIT, Xloop, XloopNEXT, and Xout as usual. - " - " A file name may be specified as argument. All messages of the extra Vim - " process are then redirected to the file. An existing file is overwritten. - " - let ExtraVimCount = 0 - let ExtraVimBase = expand("") - let ExtraVimTestEnv = "" - " - function ExtraVim(...) - " Count how often this function is called. - let g:ExtraVimCount = g:ExtraVimCount + 1 - - " Disable folds to prevent that the ranges in the ":write" commands below - " are extended up to the end of a closed fold. This also speeds things up - " considerably. - set nofoldenable - - " Open a buffer for this test script and copy the test environment to - " a temporary file. Take account of parts relevant for the extra script - " execution only. - let current_buffnr = bufnr("%") - execute "view +1" g:ExtraVimBase - if g:ExtraVimCount == 1 - let g:ExtraVimTestEnv = tempname() - execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w" - \ g:ExtraVimTestEnv "|']+" - execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>" - \ g:ExtraVimTestEnv "|']+" - execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>" - \ g:ExtraVimTestEnv "|']+" - execute "/E" . "XTRA_VIM_START/+,/E" . "XTRA_VIM_STOP/-w >>" - \ g:ExtraVimTestEnv "|']+" - endif - - " Start the extra Vim script with a ":source" command for the test - " environment. The source line number where the extra script will be - " appended, needs to be passed as variable "ExtraVimBegin" to the script. - let extra_script = tempname() - exec "!echo 'source " . g:ExtraVimTestEnv . "' >" . extra_script - let extra_begin = 1 - - " Starting behind the test environment, skip over the first g:ExtraVimCount - " occurrences of "if ExtraVim()" and copy the following lines up to the - " matching "endif" to the extra Vim script. - execute "/E" . "ND_OF_TEST_ENVIRONMENT/" - exec 'norm ' . g:ExtraVimCount . '/^\s*if\s\+ExtraVim(.*)/+' . "\n" - execute ".,/^endif/-write >>" . extra_script - - " Open a buffer for the extra Vim script, delete all ^", and write the - " script if was actually modified. - execute "edit +" . (extra_begin + 1) extra_script - ,$s/^"//e - update - - " Count the INTERRUPTs and build the breakpoint and quit commands. - let breakpoints = "" - let debug_quits = "" - let in_func = 0 - exec extra_begin - while search( - \ '"\s*INTERRUPT\h\@!\|^\s*fu\%[nction]\>!\=\s*\%(\u\|s:\)\w*\s*(\|' - \ . '^\s*\\\|^\s*endf\%[unction]\>\|' - \ . '\%(^\s*fu\%[nction]!\=\s*\)\@ 0 - let theline = getline(".") - if theline =~ '^\s*fu' - " Function definition. - let in_func = 1 - let func_start = line(".") - let func_name = substitute(theline, - \ '^\s*fu\%[nction]!\=\s*\(\%(\u\|s:\)\w*\).*', '\1', "") - elseif theline =~ '^\s*endf' - " End of function definition. - let in_func = 0 - else - let finding = substitute(theline, '.*\(\%' . col(".") . 'c.*\)', - \ '\1', "") - if finding =~ '^"\s*INTERRUPT\h\@!' - " Interrupt comment. Compose as many quit commands as - " specified. - let cnt = substitute(finding, - \ '^"\s*INTERRUPT\s*\(\d*\).*$', '\1', "") - let quits = "" - while cnt > 0 - " Use "\r" rather than "\n" to separate the quit commands. - " "\r" is not interpreted as command separator by the ":!" - " command below but works to separate commands in the - " external vim. - let quits = quits . "q\r" - let cnt = cnt - 1 - endwhile - if in_func - " Add the function breakpoint and note the number of quits - " to be used, if specified, or one for every call else. - let breakpoints = breakpoints . " -c 'breakadd func " . - \ (line(".") - func_start) . " " . - \ func_name . "'" - if quits != "" - let debug_quits = debug_quits . quits - elseif !exists("quits{func_name}") - let quits{func_name} = "q\r" - else - let quits{func_name} = quits{func_name} . "q\r" - endif - else - " Add the file breakpoint and the quits to be used for it. - let breakpoints = breakpoints . " -c 'breakadd file " . - \ line(".") . " " . extra_script . "'" - if quits == "" - let quits = "q\r" - endif - let debug_quits = debug_quits . quits - endif - else - " Add the quits to be used for calling the function or executing - " it as script file. - if finding =~ '^ExecAsScript' - " Sourcing function as script. - let finding = substitute(finding, - \ '^ExecAsScript\s\+\(\%(\u\|s:\)\w*\).*', '\1', "") - else - " Function call. - let finding = substitute(finding, - \ '^\(\%(\u\|s:\)\w*\).*', '\1', "") - endif - if exists("quits{finding}") - let debug_quits = debug_quits . quits{finding} - endif - endif - endif - endwhile - - " Close the buffer for the script and create an (empty) resultfile. - bwipeout - let resultfile = tempname() - exec "!>" . resultfile - - " Run the script in an extra vim. Switch to extra modus by passing the - " resultfile in ExtraVimResult. Redirect messages to the file specified as - " argument if any. Use ":debuggreedy" so that the commands provided on the - " pipe are consumed at the debug prompt. Use "-N" to enable command-line - " continuation ("C" in 'cpo'). Add "nviminfo" to 'viminfo' to avoid - " messing up the user's viminfo file. - let redirect = a:0 ? - \ " -c 'au VimLeave * redir END' -c 'redir\\! >" . a:1 . "'" : "" - exec "!echo '" . debug_quits . "q' | " .. v:progpath .. " -u NONE -N -Xes" . redirect . - \ " -c 'debuggreedy|set viminfo+=nviminfo'" . - \ " -c 'let ExtraVimBegin = " . extra_begin . "'" . - \ " -c 'let ExtraVimResult = \"" . resultfile . "\"'" . breakpoints . - \ " -S " . extra_script - - " Build the resulting sum for resultfile and add it to g:Xpath. Add Xout - " information provided by the extra Vim process to the test output. - let sum = 0 - exec "edit" resultfile - let line = 1 - while line <= line("$") - let theline = getline(line) - if theline =~ '^@R:' - exec 'Xout "' . substitute(substitute( - \ escape(escape(theline, '"'), '\"'), - \ '^@R:', '', ""), '@NL@', "\n", "g") . '"' - else - let sum = sum + getline(line) - endif - let line = line + 1 - endwhile - bwipeout - let g:Xpath = g:Xpath + sum - - " Delete the extra script and the resultfile. - call delete(extra_script) - call delete(resultfile) - - " Switch back to the buffer that was active when this function was entered. - exec "buffer" current_buffnr - - " Return 0. This protects extra scripts from being run in the main Vim - " process. - return 0 - endfunction - - - " ExtraVimThrowpoint() - Relative throwpoint in ExtraVim script {{{2 - " - " Evaluates v:throwpoint and returns the throwpoint relative to the beginning of - " an ExtraVim script as passed by ExtraVim() in ExtraVimBegin. - " - " EXTRA_VIM_START - do not change or remove this line. - function ExtraVimThrowpoint() - if !exists("g:ExtraVimBegin") - Xout "ExtraVimThrowpoint() used outside ExtraVim() script." - return v:throwpoint - endif - - if v:throwpoint =~ '^function\>' - return v:throwpoint - endif - - return "line " . - \ (substitute(v:throwpoint, '.*, line ', '', "") - g:ExtraVimBegin) . - \ " of ExtraVim() script" - endfunction - " EXTRA_VIM_STOP - do not change or remove this line. - - - " MakeScript() - Make a script file from a function. {{{2 - " - " Create a script that consists of the body of the function a:funcname. - " Replace any ":return" by a ":finish", any argument variable by a global - " variable, and every ":call" by a ":source" for the next following argument - " in the variable argument list. This function is useful if similar tests are - " to be made for a ":return" from a function call or a ":finish" in a script - " file. - " - " In order to execute a function specifying an INTERRUPT location (see ExtraVim) - " as a script file, use ExecAsScript below. - " - " EXTRA_VIM_START - do not change or remove this line. - function MakeScript(funcname, ...) - let script = tempname() - execute "redir! >" . script - execute "function" a:funcname - redir END - execute "edit" script - " Delete the "function" and the "endfunction" lines. Do not include the - " word "function" in the pattern since it might be translated if LANG is - " set. When MakeScript() is being debugged, this deletes also the debugging - " output of its line 3 and 4. - exec '1,/.*' . a:funcname . '(.*)/d' - /^\d*\s*endfunction\>/,$d - %s/^\d*//e - %s/return/finish/e - %s/\ 0 - let cnt = cnt + 1 - s/\" . bplist - breaklist - redir END - execute "edit" bplist - " Get the line number from the function breakpoint. Works also when - " LANG is set. - execute 'v/^\s*\d\+\s\+func\s\+' . a:funcname . '\s.*/d' - %s/^\s*\d\+\s\+func\s\+\%(\u\|s:\)\w*\s\D*\(\d*\).*/\1/e - let cnt = 0 - while cnt < line("$") - let cnt = cnt + 1 - if getline(cnt) != "" - execute "breakadd file" getline(cnt) script - endif - endwhile - bwipeout! - call delete(bplist) - endif - - " Source and delete the script. - exec "source" script - call delete(script) - endfunction - - com! -nargs=1 -bar ExecAsScript call ExecAsScript() - " EXTRA_VIM_STOP - do not change or remove this line. - - - " END_OF_TEST_ENVIRONMENT - do not change or remove this line. - - function! MESSAGES(...) - try - exec "edit" g:msgfile - catch /^Vim(edit):/ - return 0 - endtry - - let english = v:lang == "C" || v:lang =~ '^[Ee]n' - let match = 1 - norm gg - - let num = a:0 / 2 - let cnt = 1 - while cnt <= num - let enr = a:{2*cnt - 1} - let emsg= a:{2*cnt} - let cnt = cnt + 1 - - if enr == "" - Xout "TODO: Add message number for:" emsg - elseif enr == "INT" - let enr = "" - endif - if enr == "" && !english - continue - endif - let pattern = (enr != "") ? enr . ':.*' : '' - if english - let pattern = pattern . emsg - endif - if !search(pattern, "W") - let match = 0 - Xout "No match for:" pattern - endif - norm $ - endwhile - - bwipeout! - return match - endfunction - - " Following tests were moved to test_vimscript.vim: - " 1-24, 27-31, 34-40, 49-50, 52-68, 76-81, 87 - " Following tests were moved to test_trycatch.vim: - " 25-26, 32-33, 41-48, 51, 69-75 - let Xtest = 82 - - "------------------------------------------------------------------------------- - " Test 82: Ignoring :catch clauses after an error or interrupt {{{1 - " - " When an exception is thrown and an error or interrupt occurs before - " the matching :catch clause is reached, the exception is discarded - " and the :catch clause is ignored (also for the error or interrupt - " exception being thrown then). - "------------------------------------------------------------------------------- - - XpathINIT - - if ExtraVim() - try - try - Xpath 1 " X: 1 - throw "arrgh" - Xpath 2 " X: 0 - " if 1 - Xpath 4 " X: 0 - " error after :throw: missing :endif - catch /.*/ - Xpath 8 " X: 0 - Xout v:exception "in" ExtraVimThrowpoint() - catch /.*/ - Xpath 16 " X: 0 - Xout v:exception "in" ExtraVimThrowpoint() - endtry - Xpath 32 " X: 0 - catch /arrgh/ - Xpath 64 " X: 0 - endtry - Xpath 128 " X: 0 - endif - - if ExtraVim() - function! E() - try - try - Xpath 256 " X: 256 - throw "arrgh" - Xpath 512 " X: 0 - " if 1 - Xpath 1024 " X: 0 - " error after :throw: missing :endif - catch /.*/ - Xpath 2048 " X: 0 - Xout v:exception "in" ExtraVimThrowpoint() - catch /.*/ - Xpath 4096 " X: 0 - Xout v:exception "in" ExtraVimThrowpoint() - endtry - Xpath 8192 " X: 0 - catch /arrgh/ - Xpath 16384 " X: 0 - endtry - endfunction - - call E() - Xpath 32768 " X: 0 - endif - - if ExtraVim() - try - try - Xpath 65536 " X: 65536 - throw "arrgh" - Xpath 131072 " X: 0 - catch /.*/ "INTERRUPT - Xpath 262144 " X: 0 - Xout v:exception "in" ExtraVimThrowpoint() - catch /.*/ - Xpath 524288 " X: 0 - Xout v:exception "in" ExtraVimThrowpoint() - endtry - Xpath 1048576 " X: 0 - catch /arrgh/ - Xpath 2097152 " X: 0 - endtry - Xpath 4194304 " X: 0 - endif - - if ExtraVim() - function I() - try - try - Xpath 8388608 " X: 8388608 - throw "arrgh" - Xpath 16777216 " X: 0 - catch /.*/ "INTERRUPT - Xpath 33554432 " X: 0 - Xout v:exception "in" ExtraVimThrowpoint() - catch /.*/ - Xpath 67108864 " X: 0 - Xout v:exception "in" ExtraVimThrowpoint() - endtry - Xpath 134217728 " X: 0 - catch /arrgh/ - Xpath 268435456 " X: 0 - endtry - endfunction - - call I() - Xpath 536870912 " X: 0 - endif - - Xcheck 8454401 - - - "------------------------------------------------------------------------------- - " Test 83: Executing :finally clauses after an error or interrupt {{{1 - " - " When an exception is thrown and an error or interrupt occurs before - " the :finally of the innermost :try is reached, the exception is - " discarded and the :finally clause is executed. - "------------------------------------------------------------------------------- - - XpathINIT - - if ExtraVim() - try - Xpath 1 " X: 1 - try - Xpath 2 " X: 2 - throw "arrgh" - Xpath 4 " X: 0 - " if 1 - Xpath 8 " X: 0 - " error after :throw: missing :endif - finally - Xpath 16 " X: 16 - endtry - Xpath 32 " X: 0 - catch /arrgh/ - Xpath 64 " X: 0 - endtry - Xpath 128 " X: 0 - endif - - if ExtraVim() - try - Xpath 256 " X: 256 - try - Xpath 512 " X: 512 - throw "arrgh" - Xpath 1024 " X: 0 - finally "INTERRUPT - Xpath 2048 " X: 2048 - endtry - Xpath 4096 " X: 0 - catch /arrgh/ - Xpath 8192 " X: 0 - endtry - Xpath 16384 " X: 0 - endif - - Xcheck 2835 - - - "------------------------------------------------------------------------------- - " Test 84: Exceptions in autocommand sequences. {{{1 - " - " When an exception occurs in a sequence of autocommands for - " a specific event, the rest of the sequence is not executed. The - " command that triggered the autocommand execution aborts, and the - " exception is propagated to the caller. - " - " For the FuncUndefined event under a function call expression or - " :call command, the function is not executed, even when it has - " been defined by the autocommands before the exception occurred. - "------------------------------------------------------------------------------- - - XpathINIT - - if ExtraVim() - - function! INT() - "INTERRUPT - let dummy = 0 - endfunction - - aug TMP - autocmd! - - autocmd User x1 Xpath 1 " X: 1 - autocmd User x1 throw "x1" - autocmd User x1 Xpath 2 " X: 0 - - autocmd User x2 Xpath 4 " X: 4 - autocmd User x2 asdf - autocmd User x2 Xpath 8 " X: 0 - - autocmd User x3 Xpath 16 " X: 16 - autocmd User x3 call INT() - autocmd User x3 Xpath 32 " X: 0 - - autocmd FuncUndefined U1 function! U1() - autocmd FuncUndefined U1 Xpath 64 " X: 0 - autocmd FuncUndefined U1 endfunction - autocmd FuncUndefined U1 Xpath 128 " X: 128 - autocmd FuncUndefined U1 throw "U1" - autocmd FuncUndefined U1 Xpath 256 " X: 0 - - autocmd FuncUndefined U2 function! U2() - autocmd FuncUndefined U2 Xpath 512 " X: 0 - autocmd FuncUndefined U2 endfunction - autocmd FuncUndefined U2 Xpath 1024 " X: 1024 - autocmd FuncUndefined U2 ASDF - autocmd FuncUndefined U2 Xpath 2048 " X: 0 - - autocmd FuncUndefined U3 function! U3() - autocmd FuncUndefined U3 Xpath 4096 " X: 0 - autocmd FuncUndefined U3 endfunction - autocmd FuncUndefined U3 Xpath 8192 " X: 8192 - autocmd FuncUndefined U3 call INT() - autocmd FuncUndefined U3 Xpath 16384 " X: 0 - aug END - - try - try - Xpath 32768 " X: 32768 - doautocmd User x1 - catch /x1/ - Xpath 65536 " X: 65536 - endtry - - while 1 - try - Xpath 131072 " X: 131072 - let caught = 0 - doautocmd User x2 - catch /asdf/ - let caught = 1 - finally - Xpath 262144 " X: 262144 - if !caught && !$VIMNOERRTHROW - Xpath 524288 " X: 0 - " Propagate uncaught error exception, - else - " ... but break loop for caught error exception, - " or discard error and break loop if $VIMNOERRTHROW - break - endif - endtry - endwhile - - while 1 - try - Xpath 1048576 " X: 1048576 - let caught = 0 - doautocmd User x3 - catch /Vim:Interrupt/ - let caught = 1 - finally - Xpath 2097152 " X: 2097152 - if !caught && !$VIMNOINTTHROW - Xpath 4194304 " X: 0 - " Propagate uncaught interrupt exception, - else - " ... but break loop for caught interrupt exception, - " or discard interrupt and break loop if $VIMNOINTTHROW - break - endif - endtry - endwhile - - if exists("*U1") | delfunction U1 | endif - if exists("*U2") | delfunction U2 | endif - if exists("*U3") | delfunction U3 | endif - - try - Xpath 8388608 " X: 8388608 - call U1() - catch /U1/ - Xpath 16777216 " X: 16777216 - endtry - - while 1 - try - Xpath 33554432 " X: 33554432 - let caught = 0 - call U2() - catch /ASDF/ - let caught = 1 - finally - Xpath 67108864 " X: 67108864 - if !caught && !$VIMNOERRTHROW - Xpath 134217728 " X: 0 - " Propagate uncaught error exception, - else - " ... but break loop for caught error exception, - " or discard error and break loop if $VIMNOERRTHROW - break - endif - endtry - endwhile - - while 1 - try - Xpath 268435456 " X: 268435456 - let caught = 0 - call U3() - catch /Vim:Interrupt/ - let caught = 1 - finally - Xpath 536870912 " X: 536870912 - if !caught && !$VIMNOINTTHROW - Xpath 1073741824 " X: 0 - " Propagate uncaught interrupt exception, - else - " ... but break loop for caught interrupt exception, - " or discard interrupt and break loop if $VIMNOINTTHROW - break - endif - endtry - endwhile - catch /.*/ - " The Xpath command does not accept 2^31 (negative); display explicitly: - exec "!echo 2147483648 >>" . g:ExtraVimResult - Xout "Caught" v:exception "in" v:throwpoint - endtry - - unlet caught - delfunction INT - delfunction U1 - delfunction U2 - delfunction U3 - au! TMP - aug! TMP - endif - - Xcheck 934782101 - - - "------------------------------------------------------------------------------- - " Test 85: Error exceptions in autocommands for I/O command events {{{1 - " - " When an I/O command is inside :try/:endtry, autocommands to be - " executed after it should be skipped on an error (exception) in the - " command itself or in autocommands to be executed before the command. - " In the latter case, the I/O command should not be executed either. - " Example 1: BufWritePre, :write, BufWritePost - " Example 2: FileReadPre, :read, FileReadPost. - "------------------------------------------------------------------------------- - - XpathINIT - - function! MSG(enr, emsg) - let english = v:lang == "C" || v:lang =~ '^[Ee]n' - if a:enr == "" - Xout "TODO: Add message number for:" a:emsg - let v:errmsg = ":" . v:errmsg - endif - let match = 1 - if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) - let match = 0 - if v:errmsg == "" - Xout "Message missing." - else - let v:errmsg = escape(v:errmsg, '"') - Xout "Unexpected message:" v:errmsg - endif - endif - return match - endfunction - - " Remove the autocommands for the events specified as arguments in all used - " autogroups. - function Delete_autocommands(...) - let augfile = tempname() - while 1 - try - exec "redir >" . augfile - aug - redir END - exec "edit" augfile - g/^$/d - norm G$ - let wrap = "w" - while search('\%( \|^\)\@<=.\{-}\%( \)\@=', wrap) > 0 - let wrap = "W" - exec "norm y/ \n" - let argno = 1 - while argno <= a:0 - exec "au!" escape(@", " ") a:{argno} - let argno = argno + 1 - endwhile - endwhile - catch /.*/ - finally - bwipeout! - call delete(augfile) - break " discard errors for $VIMNOERRTHROW - endtry - endwhile - endfunction - - call Delete_autocommands("BufWritePre", "BufWritePost") - - while 1 - try - try - let post = 0 - aug TMP - au! BufWritePost * let post = 1 - aug END - let caught = 0 - write /n/o/n/e/x/i/s/t/e/n/t - catch /^Vim(write):/ - let caught = 1 - let v:errmsg = substitute(v:exception, '^Vim(write):', '', "") - finally - Xpath 1 " X: 1 - if !caught && !$VIMNOERRTHROW - Xpath 2 " X: 0 - endif - let v:errmsg = substitute(v:errmsg, '^"/n/o/n/e/x/i/s/t/e/n/t" ', - \ '', "") - if !MSG('E212', "Can't open file for writing") - Xpath 4 " X: 0 - endif - if post - Xpath 8 " X: 0 - Xout "BufWritePost commands executed after write error" - endif - au! TMP - aug! TMP - endtry - catch /.*/ - Xpath 16 " X: 0 - Xout v:exception "in" v:throwpoint - finally - break " discard error for $VIMNOERRTHROW - endtry - endwhile - - while 1 - try - try - let post = 0 - aug TMP - au! BufWritePre * asdf - au! BufWritePost * let post = 1 - aug END - let tmpfile = tempname() - let caught = 0 - exec "write" tmpfile - catch /^Vim\((write)\)\=:/ - let caught = 1 - let v:errmsg = substitute(v:exception, '^Vim\((write)\)\=:', '', "") - finally - Xpath 32 " X: 32 - if !caught && !$VIMNOERRTHROW - Xpath 64 " X: 0 - endif - let v:errmsg = substitute(v:errmsg, '^"'.tmpfile.'" ', '', "") - if !MSG('E492', "Not an editor command") - Xpath 128 " X: 0 - endif - if filereadable(tmpfile) - Xpath 256 " X: 0 - Xout ":write command not suppressed after BufWritePre error" - endif - if post - Xpath 512 " X: 0 - Xout "BufWritePost commands executed after BufWritePre error" - endif - au! TMP - aug! TMP - endtry - catch /.*/ - Xpath 1024 " X: 0 - Xout v:exception "in" v:throwpoint - finally - break " discard error for $VIMNOERRTHROW - endtry - endwhile - - call delete(tmpfile) - - call Delete_autocommands("BufWritePre", "BufWritePost", - \ "BufReadPre", "BufReadPost", "FileReadPre", "FileReadPost") - - while 1 - try - try - let post = 0 - aug TMP - au! FileReadPost * let post = 1 - aug END - let caught = 0 - read /n/o/n/e/x/i/s/t/e/n/t - catch /^Vim(read):/ - let caught = 1 - let v:errmsg = substitute(v:exception, '^Vim(read):', '', "") - finally - Xpath 2048 " X: 2048 - if !caught && !$VIMNOERRTHROW - Xpath 4096 " X: 0 - endif - let v:errmsg = substitute(v:errmsg, ' /n/o/n/e/x/i/s/t/e/n/t$', - \ '', "") - if !MSG('E484', "Can't open file") - Xpath 8192 " X: 0 - endif - if post - Xpath 16384 " X: 0 - Xout "FileReadPost commands executed after write error" - endif - au! TMP - aug! TMP - endtry - catch /.*/ - Xpath 32768 " X: 0 - Xout v:exception "in" v:throwpoint - finally - break " discard error for $VIMNOERRTHROW - endtry - endwhile - - while 1 - try - let infile = tempname() - let tmpfile = tempname() - exec "!echo XYZ >" . infile - exec "edit" tmpfile - try - Xpath 65536 " X: 65536 - try - let post = 0 - aug TMP - au! FileReadPre * asdf - au! FileReadPost * let post = 1 - aug END - let caught = 0 - exec "0read" infile - catch /^Vim\((read)\)\=:/ - let caught = 1 - let v:errmsg = substitute(v:exception, '^Vim\((read)\)\=:', '', - \ "") - finally - Xpath 131072 " X: 131072 - if !caught && !$VIMNOERRTHROW - Xpath 262144 " X: 0 - endif - let v:errmsg = substitute(v:errmsg, ' '.infile.'$', '', "") - if !MSG('E492', "Not an editor command") - Xpath 524288 " X: 0 - endif - if getline("1") == "XYZ" - Xpath 1048576 " X: 0 - Xout ":read command not suppressed after FileReadPre error" - endif - if post - Xpath 2097152 " X: 0 - Xout "FileReadPost commands executed after " . - \ "FileReadPre error" - endif - au! TMP - aug! TMP - endtry - finally - bwipeout! - endtry - catch /.*/ - Xpath 4194304 " X: 0 - Xout v:exception "in" v:throwpoint - finally - break " discard error for $VIMNOERRTHROW - endtry - endwhile - - call delete(infile) - call delete(tmpfile) - unlet! caught post infile tmpfile - delfunction MSG - delfunction Delete_autocommands - - Xcheck 198689 - - "------------------------------------------------------------------------------- - " Test 86: setloclist crash {{{1 - " - " Executing a setloclist() on BufUnload shouldn't crash Vim - "------------------------------------------------------------------------------- - - func F - au BufUnload * :call setloclist(0, [{'bufnr':1, 'lnum':1, 'col':1, 'text': 'tango down'}]) - - :lvimgrep /.*/ *.mak - endfunc - - XpathINIT - - ExecAsScript F - - delfunction F - Xout "No Crash for vimgrep on BufUnload" - Xcheck 0 - - " Test 87 was moved to test_vimscript.vim - let Xtest = 88 - - - "------------------------------------------------------------------------------- - " Test 88: $VIMNOERRTHROW and $VIMNOINTTHROW support {{{1 - " - " It is possible to configure Vim for throwing exceptions on error - " or interrupt, controlled by variables $VIMNOERRTHROW and - " $VIMNOINTTHROW. This is just for increasing the number of tests. - " All tests here should run for all four combinations of setting - " these variables to 0 or 1. The variables are intended for the - " development phase only. In the final release, Vim should be - " configured to always use error and interrupt exceptions. - " - " The test result is "OK", - " - " - if the $VIMNOERRTHROW and the $VIMNOINTTHROW control are not - " configured and exceptions are thrown on error and on - " interrupt. - " - " - if the $VIMNOERRTHROW or the $VIMNOINTTHROW control is - " configured and works as intended. - " - " What actually happens, is shown in the test output. - " - " Otherwise, the test result is "FAIL", and the test output describes - " the problem. - " - " IMPORTANT: This must be the last test because it sets $VIMNOERRTHROW and - " $VIMNOINTTHROW. - "------------------------------------------------------------------------------- - - XpathINIT - - if ExtraVim() - - function! ThrowOnError() - XloopNEXT - let caught = 0 - try - Xloop 1 " X: 1 + 8 + 64 - asdf - catch /.*/ - let caught = 1 " error exception caught - finally - Xloop 2 " X: 2 + 16 + 128 - return caught " discard aborting error - endtry - Xloop 4 " X: 0 - endfunction - - let quits_skipped = 0 - - function! ThrowOnInterrupt() - XloopNEXT - let caught = 0 - try - Xloop 1 " X: (1 + 8 + 64) * 512 - "INTERRUPT3 - let dummy = 0 - let g:quits_skipped = g:quits_skipped + 1 - catch /.*/ - let caught = 1 " interrupt exception caught - finally - Xloop 2 " X: (2 + 16 + 128) * 512 - return caught " discard interrupt - endtry - Xloop 4 " X: 0 - endfunction - - function! CheckThrow(Type) - execute 'return ThrowOn' . a:Type . '()' - endfunction - - function! CheckConfiguration(type) " type is "error" or "interrupt" - - let type = a:type - let Type = substitute(type, '.*', '\u&', "") - let VAR = '$VIMNO' . substitute(type, '\(...\).*', '\U\1', "") . 'THROW' - - if type == "error" - XloopINIT! 1 8 - elseif type == "interrupt" - XloopINIT! 512 8 - endif - - exec 'let requested_for_tests = exists(VAR) && ' . VAR . ' == 0' - exec 'let suppressed_for_tests = ' . VAR . ' != 0' - let used_in_tests = CheckThrow(Type) - - exec 'let ' . VAR . ' = 0' - let request_works = CheckThrow(Type) - - exec 'let ' . VAR . ' = 1' - let suppress_works = !CheckThrow(Type) - - if type == "error" - XloopINIT! 262144 8 - elseif type == "interrupt" - XloopINIT! 2097152 8 - - if g:quits_skipped != 0 - Xloop 1 " X: 0*2097152 - Xout "Test environment error. Interrupt breakpoints skipped: " - \ . g:quits_skipped . ".\n" - \ . "Cannot check whether interrupt exceptions are thrown." - return - endif - endif - - let failure = - \ !suppressed_for_tests && !used_in_tests - \ || !request_works - - let contradiction = - \ used_in_tests - \ ? suppressed_for_tests && !request_works - \ : !suppressed_for_tests - - if failure - " Failure in configuration. - Xloop 2 " X: 0 * 2* (262144 + 2097152) - elseif contradiction - " Failure in test logic. Should not happen. - Xloop 4 " X: 0 * 4 * (262144 + 2097152) - endif - - let var_control_configured = - \ request_works != used_in_tests - \ || suppress_works == used_in_tests - - let var_control_not_configured = - \ requested_for_tests || suppressed_for_tests - \ ? request_works && !suppress_works - \ : request_works == used_in_tests - \ && suppress_works != used_in_tests - - let with = used_in_tests ? "with" : "without" - - let set = suppressed_for_tests ? "non-zero" : - \ requested_for_tests ? "0" : "unset" - - let although = contradiction && !var_control_not_configured - \ ? ",\nalthough " - \ : ".\n" - - let output = "All tests were run " . with . " throwing exceptions on " - \ . type . although - - if !var_control_not_configured - let output = output . VAR . " was " . set . "." - - if !request_works && !requested_for_tests - let output = output . - \ "\n" . Type . " exceptions are not thrown when " . VAR . - \ " is\nset to 0." - endif - - if !suppress_works && (!used_in_tests || - \ !request_works && - \ !requested_for_tests && !suppressed_for_tests) - let output = output . - \ "\n" . Type . " exceptions are thrown when " . VAR . - \ " is set to 1." - endif - - if !failure && var_control_configured - let output = output . - \ "\nRun tests also with " . substitute(VAR, '^\$', '', "") - \ . "=" . used_in_tests . "." - \ . "\nThis is for testing in the development phase only." - \ . " Remove the \n" - \ . VAR . " control in the final release." - endif - else - let output = output . - \ "The " . VAR . " control is not configured." - endif - - Xout output - endfunction - - call CheckConfiguration("error") - Xpath 16777216 " X: 16777216 - call CheckConfiguration("interrupt") - Xpath 33554432 " X: 33554432 - endif - - Xcheck 50443995 - - " IMPORTANT: No test should be added after this test because it changes - " $VIMNOERRTHROW and $VIMNOINTTHROW. - - - "------------------------------------------------------------------------------- - " Modelines {{{1 - " vim: ts=8 sw=4 tw=80 fdm=marker - "------------------------------------------------------------------------------- --- 0 ---- *** ../vim-8.2.1419/src/testdir/test_quickfix.vim 2020-08-07 18:12:14.426099006 +0200 --- src/testdir/test_quickfix.vim 2020-08-11 19:29:37.982754214 +0200 *************** *** 5040,5043 **** --- 5040,5066 ---- new | only! endfunc + " Test for the crash fixed by 7.3.715 + func Test_setloclist_crash() + %bw! + let g:BufNum = bufnr() + augroup QF_Test + au! + au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}]) + augroup END + + try + lvimgrep /.*/ *.mak + catch /E926:/ + endtry + call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text) + call assert_equal(1, getloclist(0, {'size' : 0}).size) + + augroup QF_Test + au! + augroup END + unlet g:BufNum + %bw! + endfunc + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.1419/src/testdir/test_vimscript.vim 2020-08-10 22:15:25.559054214 +0200 --- src/testdir/test_vimscript.vim 2020-08-11 19:29:37.982754214 +0200 *************** *** 1,5 **** " Test various aspects of the Vim script language. ! " Most of this was formerly in test49. source check.vim source shared.vim --- 1,6 ---- " Test various aspects of the Vim script language. ! " Most of this was formerly in test49.vim (developed by Servatius Brandt ! " ) source check.vim source shared.vim *************** *** 5868,5874 **** call RunInNewVim(test, verify) endfunc ! " TODO: Not able inject an interrupt after throwing an exception func Disable_Test_discard_exception_after_error_2() let test =<< trim [CODE] try --- 5869,5875 ---- call RunInNewVim(test, verify) endfunc ! " TODO: Need to interrupt the code before the endtry is invoked func Disable_Test_discard_exception_after_error_2() let test =<< trim [CODE] try *************** *** 5890,5895 **** --- 5891,6397 ---- [CODE] call RunInNewVim(test, verify) endfunc + + "------------------------------------------------------------------------------- + " Test 82: Ignoring :catch clauses after an error or interrupt {{{1 + " + " When an exception is thrown and an error or interrupt occurs before + " the matching :catch clause is reached, the exception is discarded + " and the :catch clause is ignored (also for the error or interrupt + " exception being thrown then). + "------------------------------------------------------------------------------- + + func Test_ignore_catch_after_error_1() + let test =<< trim [CODE] + try + try + Xpath 'a' + throw "arrgh" + call assert_report('should not get here') + if 1 + call assert_report('should not get here') + " error after :throw: missing :endif + catch /.*/ + call assert_report('should not get here') + catch /.*/ + call assert_report('should not get here') + endtry + call assert_report('should not get here') + catch /arrgh/ + call assert_report('should not get here') + endtry + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('a', g:Xpath) + [CODE] + call RunInNewVim(test, verify) + endfunc + + func Test_ignore_catch_after_error_2() + let test =<< trim [CODE] + func E() + try + try + Xpath 'a' + throw "arrgh" + call assert_report('should not get here') + if 1 + call assert_report('should not get here') + " error after :throw: missing :endif + catch /.*/ + call assert_report('should not get here') + catch /.*/ + call assert_report('should not get here') + endtry + call assert_report('should not get here') + catch /arrgh/ + call assert_report('should not get here') + endtry + endfunc + + call E() + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('a', g:Xpath) + [CODE] + call RunInNewVim(test, verify) + endfunc + + " TODO: Need to interrupt the code right before the catch is invoked + func FIXME_Test_ignore_catch_after_intr_1() + let test =<< trim [CODE] + try + try + Xpath 'a' + throw "arrgh" + call assert_report('should not get here') + catch /.*/ " TODO: Need to interrupt before this catch is + call interrupt() " invoked + call assert_report('should not get here') + catch /.*/ + call assert_report('should not get here') + endtry + call assert_report('should not get here') + catch /arrgh/ + call assert_report('should not get here') + endtry + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('a', g:Xpath) + [CODE] + call RunInNewVim(test, verify) + endfunc + + " TODO: Need to interrupt the code right before the catch is invoked + func FIXME_Test_ignore_catch_after_intr_2() + let test =<< trim [CODE] + func I() + try + try + Xpath 'a' + throw "arrgh" + call assert_report('should not get here') + catch /.*/ " TODO: Need to interrupt before this catch is + " invoked + call interrupt() + call assert_report('should not get here') + catch /.*/ + call assert_report('should not get here') + endtry + call assert_report('should not get here') + catch /arrgh/ + call assert_report('should not get here') + endtry + endfunc + + call I() + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('a', g:Xpath) + [CODE] + call RunInNewVim(test, verify) + endfunc + + "------------------------------------------------------------------------------- + " Test 83: Executing :finally clauses after an error or interrupt {{{1 + " + " When an exception is thrown and an error or interrupt occurs before + " the :finally of the innermost :try is reached, the exception is + " discarded and the :finally clause is executed. + "------------------------------------------------------------------------------- + + func Test_finally_after_error() + let test =<< trim [CODE] + try + Xpath 'a' + try + Xpath 'b' + throw "arrgh" + call assert_report('should not get here') + if 1 + call assert_report('should not get here') + " error after :throw: missing :endif + finally + Xpath 'c' + endtry + call assert_report('should not get here') + catch /arrgh/ + call assert_report('should not get here') + endtry + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('abc', g:Xpath) + [CODE] + call RunInNewVim(test, verify) + endfunc + + " TODO: Need to interrupt the code right before the finally is invoked + func FIXME_Test_finally_after_intr() + let test =<< trim [CODE] + try + Xpath 'a' + try + Xpath 'b' + throw "arrgh" + call assert_report('should not get here') + finally " TODO: Need to interrupt before the finally is invoked + Xpath 'c' + endtry + call assert_report('should not get here') + catch /arrgh/ + call assert_report('should not get here') + endtry + call assert_report('should not get here') + [CODE] + let verify =<< trim [CODE] + call assert_equal('abc', g:Xpath) + [CODE] + call RunInNewVim(test, verify) + endfunc + + "------------------------------------------------------------------------------- + " Test 84: Exceptions in autocommand sequences. {{{1 + " + " When an exception occurs in a sequence of autocommands for + " a specific event, the rest of the sequence is not executed. The + " command that triggered the autocommand execution aborts, and the + " exception is propagated to the caller. + " + " For the FuncUndefined event under a function call expression or + " :call command, the function is not executed, even when it has + " been defined by the autocommands before the exception occurred. + "------------------------------------------------------------------------------- + + func Test_autocmd_exception() + let test =<< trim [CODE] + func INT() + call interrupt() + endfunc + + aug TMP + autocmd! + + autocmd User x1 Xpath 'a' + autocmd User x1 throw "x1" + autocmd User x1 call assert_report('should not get here') + + autocmd User x2 Xpath 'b' + autocmd User x2 asdf + autocmd User x2 call assert_report('should not get here') + + autocmd User x3 Xpath 'c' + autocmd User x3 call INT() + autocmd User x3 call assert_report('should not get here') + + autocmd FuncUndefined U1 func U1() + autocmd FuncUndefined U1 call assert_report('should not get here') + autocmd FuncUndefined U1 endfunc + autocmd FuncUndefined U1 Xpath 'd' + autocmd FuncUndefined U1 throw "U1" + autocmd FuncUndefined U1 call assert_report('should not get here') + + autocmd FuncUndefined U2 func U2() + autocmd FuncUndefined U2 call assert_report('should not get here') + autocmd FuncUndefined U2 endfunc + autocmd FuncUndefined U2 Xpath 'e' + autocmd FuncUndefined U2 ASDF + autocmd FuncUndefined U2 call assert_report('should not get here') + + autocmd FuncUndefined U3 func U3() + autocmd FuncUndefined U3 call assert_report('should not get here') + autocmd FuncUndefined U3 endfunc + autocmd FuncUndefined U3 Xpath 'f' + autocmd FuncUndefined U3 call INT() + autocmd FuncUndefined U3 call assert_report('should not get here') + aug END + + try + try + Xpath 'g' + doautocmd User x1 + catch /x1/ + Xpath 'h' + endtry + + while 1 + try + Xpath 'i' + doautocmd User x2 + catch /asdf/ + Xpath 'j' + finally + Xpath 'k' + break + endtry + endwhile + + while 1 + try + Xpath 'l' + doautocmd User x3 + catch /Vim:Interrupt/ + Xpath 'm' + finally + Xpath 'n' + " ... but break loop for caught interrupt exception, + " or discard interrupt and break loop if $VIMNOINTTHROW + break + endtry + endwhile + + if exists("*U1") | delfunction U1 | endif + if exists("*U2") | delfunction U2 | endif + if exists("*U3") | delfunction U3 | endif + + try + Xpath 'o' + call U1() + catch /U1/ + Xpath 'p' + endtry + + while 1 + try + Xpath 'q' + call U2() + catch /ASDF/ + Xpath 'r' + finally + Xpath 's' + " ... but break loop for caught error exception, + " or discard error and break loop if $VIMNOERRTHROW + break + endtry + endwhile + + while 1 + try + Xpath 't' + call U3() + catch /Vim:Interrupt/ + Xpath 'u' + finally + Xpath 'v' + " ... but break loop for caught interrupt exception, + " or discard interrupt and break loop if $VIMNOINTTHROW + break + endtry + endwhile + catch /.*/ + call assert_report('should not get here') + endtry + Xpath 'w' + [CODE] + let verify =<< trim [CODE] + call assert_equal('gahibjklcmnodpqerstfuvw', g:Xpath) + [CODE] + call RunInNewVim(test, verify) + endfunc + + "------------------------------------------------------------------------------- + " Test 85: Error exceptions in autocommands for I/O command events {{{1 + " + " When an I/O command is inside :try/:endtry, autocommands to be + " executed after it should be skipped on an error (exception) in the + " command itself or in autocommands to be executed before the command. + " In the latter case, the I/O command should not be executed either. + " Example 1: BufWritePre, :write, BufWritePost + " Example 2: FileReadPre, :read, FileReadPost. + "------------------------------------------------------------------------------- + + func Test_autocmd_error_io_exception() + let test =<< trim [CODE] + " Remove the autocommands for the events specified as arguments in all used + " autogroups. + func Delete_autocommands(...) + let augfile = tempname() + while 1 + try + exec "redir >" . augfile + aug + redir END + exec "edit" augfile + g/^$/d + norm G$ + let wrap = "w" + while search('\%( \|^\)\@<=.\{-}\%( \)\@=', wrap) > 0 + let wrap = "W" + exec "norm y/ \n" + let argno = 1 + while argno <= a:0 + exec "au!" escape(@", " ") a:{argno} + let argno = argno + 1 + endwhile + endwhile + catch /.*/ + finally + bwipeout! + call delete(augfile) + break + endtry + endwhile + endfunc + + call Delete_autocommands("BufWritePre", "BufWritePost") + + while 1 + try + try + let post = 0 + aug TMP + au! BufWritePost * let post = 1 + aug END + write /n/o/n/e/x/i/s/t/e/n/t + catch /^Vim(write):/ + Xpath 'a' + call assert_match("E212: Can't open file for writing", v:exception) + finally + Xpath 'b' + call assert_equal(0, post) + au! TMP + aug! TMP + endtry + catch /.*/ + call assert_report('should not get here') + finally + Xpath 'c' + break + endtry + endwhile + + while 1 + try + try + let post = 0 + aug TMP + au! BufWritePre * asdf + au! BufWritePost * let post = 1 + aug END + let tmpfile = tempname() + exec "write" tmpfile + catch /^Vim\((write)\)\=:/ + Xpath 'd' + call assert_match('E492: Not an editor command', v:exception) + finally + Xpath 'e' + if filereadable(tmpfile) + call assert_report('should not get here') + endif + call assert_equal(0, post) + au! TMP + aug! TMP + endtry + catch /.*/ + call assert_report('should not get here') + finally + Xpath 'f' + break + endtry + endwhile + + call delete(tmpfile) + + call Delete_autocommands("BufWritePre", "BufWritePost", + \ "BufReadPre", "BufReadPost", "FileReadPre", "FileReadPost") + + while 1 + try + try + let post = 0 + aug TMP + au! FileReadPost * let post = 1 + aug END + let caught = 0 + read /n/o/n/e/x/i/s/t/e/n/t + catch /^Vim(read):/ + Xpath 'g' + call assert_match("E484: Can't open file", v:exception) + finally + Xpath 'h' + call assert_equal(0, post) + au! TMP + aug! TMP + endtry + catch /.*/ + call assert_report('should not get here') + finally + Xpath 'i' + break + endtry + endwhile + + while 1 + try + let infile = tempname() + let tmpfile = tempname() + call writefile(["XYZ"], infile) + exec "edit" tmpfile + try + Xpath 'j' + try + let post = 0 + aug TMP + au! FileReadPre * asdf + au! FileReadPost * let post = 1 + aug END + exec "0read" infile + catch /^Vim\((read)\)\=:/ + Xpath 'k' + call assert_match('E492: Not an editor command', v:exception) + finally + Xpath 'l' + if getline("1") == "XYZ" + call assert_report('should not get here') + endif + call assert_equal(0, post) + au! TMP + aug! TMP + endtry + finally + Xpath 'm' + bwipeout! + endtry + catch /.*/ + call assert_report('should not get here') + finally + Xpath 'n' + break + endtry + endwhile + + call delete(infile) + call delete(tmpfile) + [CODE] + let verify =<< trim [CODE] + call assert_equal('abcdefghijklmn', g:Xpath) + [CODE] + call RunInNewVim(test, verify) + endfunc "------------------------------------------------------------------------------- " Test 87 using (expr) ? funcref : funcref {{{1 *** ../vim-8.2.1419/src/version.c 2020-08-10 23:09:33.761270906 +0200 --- src/version.c 2020-08-11 19:30:21.626575809 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1420, /**/ -- hundred-and-one symptoms of being an internet addict: 173. You keep tracking down the email addresses of all your friends (even childhood friends). /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///