summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-08-11 20:42:19 +0200
committerBram Moolenaar <Bram@vim.org>2020-08-11 20:42:19 +0200
commitf7c4d83609acdfe0e4d0fec9413697ac97c0c3f9 (patch)
tree7872b2cb248f6e0bd9624bee8a0885185d9e82e1
parent59eccb92e3c68f65525e08d2113213ff7d7ed00a (diff)
downloadvim-git-f7c4d83609acdfe0e4d0fec9413697ac97c0c3f9.tar.gz
patch 8.2.1420: test 49 is old stylev8.2.1420
Problem: Test 49 is old style. Solution: Convert remaining parts to new style. Remove obsolete items. (Yegappan Lakshmanan, closes #6683)
-rw-r--r--Filelist9
-rw-r--r--runtime/doc/testing.txt15
-rw-r--r--src/Make_mvc.mak12
-rw-r--r--src/Makefile8
-rw-r--r--src/testdir/Make_all.mak18
-rw-r--r--src/testdir/Make_amiga.mak9
-rw-r--r--src/testdir/Make_dos.mak13
-rw-r--r--src/testdir/Make_ming.mak25
-rw-r--r--src/testdir/Make_vms.mms34
-rw-r--r--src/testdir/Makefile50
-rw-r--r--src/testdir/README.txt21
-rw-r--r--src/testdir/test49.in32
-rw-r--r--src/testdir/test49.ok12
-rw-r--r--src/testdir/test49.vim1454
-rw-r--r--src/testdir/test_quickfix.vim23
-rw-r--r--src/testdir/test_vimscript.vim506
-rw-r--r--src/version.c2
17 files changed, 561 insertions, 1682 deletions
diff --git a/Filelist b/Filelist
index 37f1d8c77..02574e9a1 100644
--- a/Filelist
+++ b/Filelist
@@ -158,7 +158,9 @@ SRC_ALL = \
src/testdir/gen_opt_test.vim \
src/testdir/README.txt \
src/testdir/Make_all.mak \
- src/testdir/*.in \
+ 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,9 +179,8 @@ SRC_ALL = \
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/test1.ok \
+ src/testdir/test77a.ok \
src/testdir/test83-tags? \
src/testdir/test77a.com \
src/testdir/test_*.vim \
diff --git a/runtime/doc/testing.txt b/runtime/doc/testing.txt
index f1173a1f0..1147673d5 100644
--- a/runtime/doc/testing.txt
+++ b/runtime/doc/testing.txt
@@ -20,18 +20,11 @@ and for testing plugins.
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.
+New tests should be added as new style tests. The test scripts are named
+test_<feature>.vim (replace <feature> 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.
diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak
index 9c3deb62d..8ac39e22b 100644
--- a/src/Make_mvc.mak
+++ b/src/Make_mvc.mak
@@ -1326,14 +1326,6 @@ MAIN_TARGET = $(VIM).exe
# 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 \
@@ -1485,9 +1477,9 @@ testclean:
$(MAKE) /NOLOGO -f Make_dos.mak clean
cd ..
-# Run individual OLD style test.
+# Run test1 to bootstrap tests
# These do not depend on the executable, compile it when needed.
-$(OLD_TEST_OUTFILES:.out=):
+$(SCRIPTS_FIRST:.out=):
cd testdir
- if exist $@.out del $@.out
$(MAKE) /NOLOGO -f Make_dos.mak VIMPROG=..\$(VIMTESTTARGET) nolog
diff --git a/src/Makefile b/src/Makefile
index 55c366472..5d73fc91a 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2259,8 +2259,6 @@ test check: unittests $(TERM_TEST) scripttests
#
# 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".
#
@@ -2311,9 +2309,9 @@ test_libvterm:
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:
+# 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.
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 0900a6cfd..57ba651c6 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -10,24 +10,6 @@ NO_INITS = -U NONE $(NO_PLUGINS)
# 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 \
diff --git a/src/testdir/Make_amiga.mak b/src/testdir/Make_amiga.mak
index e6e55e3b4..efd580842 100644
--- a/src/testdir/Make_amiga.mak
+++ b/src/testdir/Make_amiga.mak
@@ -9,14 +9,9 @@ default: nongui
include Make_all.mak
-SCRIPTS = $(SCRIPTS_ALL) $(SCRIPTS_MORE4)
+.SUFFIXES: .in .out .res .vim
-# Must run test1 first to create small.vim.
-$(SCRIPTS) $(SCRIPTS_GUI) $(NEW_TESTS_RES): $(SCRIPTS_FIRST)
-
-.SUFFIXES: .in .out
-
-nongui: /tmp $(SCRIPTS_FIRST) $(SCRIPTS)
+nongui: /tmp $(SCRIPTS_FIRST)
csh -c echo ALL DONE
clean:
diff --git a/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak
index f97b3e9bb..5931da25d 100644
--- a/src/testdir/Make_dos.mak
+++ b/src/testdir/Make_dos.mak
@@ -9,25 +9,20 @@ default: nongui
!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)
+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) $(SCRIPTS) newtests report
+nongui: nolog $(SCRIPTS_FIRST) newtests report
small: nolog report
-gui: nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_GUI) newtests report
+gui: nolog $(SCRIPTS_FIRST) newtests report
-win32: nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_WIN32) newtests report
+win32: nolog $(SCRIPTS_FIRST) newtests report
# Copy the input files to dostmp, changing the fileformat to dos.
$(DOSTMP_INFILES): $(*B).in
diff --git a/src/testdir/Make_ming.mak b/src/testdir/Make_ming.mak
index e1f346749..b34ae1d2c 100644
--- a/src/testdir/Make_ming.mak
+++ b/src/testdir/Make_ming.mak
@@ -28,19 +28,17 @@ default: vimall
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)
+$(NEW_TESTS_RES): $(SCRIPTS_FIRST)
.SUFFIXES: .in .out .res .vim
-vimall: fixff $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_GUI) $(SCRIPTS_WIN32) newtests
+vimall: fixff $(SCRIPTS_FIRST) newtests
@echo ALL DONE
-nongui: fixff nolog $(SCRIPTS_FIRST) $(SCRIPTS) newtests
+nongui: fixff nolog $(SCRIPTS_FIRST) newtests
@echo ALL DONE
benchmark: $(SCRIPTS_BENCH)
@@ -48,10 +46,10 @@ benchmark: $(SCRIPTS_BENCH)
small: nolog
@echo ALL DONE
-gui: fixff nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_GUI) newtests
+gui: fixff nolog $(SCRIPTS_FIRST) newtests
@echo ALL DONE
-win32: fixff nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_WIN32) newtests
+win32: fixff nolog $(SCRIPTS_FIRST) newtests
@echo ALL DONE
# TODO: find a way to avoid changing the distributed files.
@@ -88,19 +86,6 @@ test1.out: test1.in
-@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
diff --git a/src/testdir/Make_vms.mms b/src/testdir/Make_vms.mms
index 59da981b3..f36ae6edd 100644
--- a/src/testdir/Make_vms.mms
+++ b/src/testdir/Make_vms.mms
@@ -27,26 +27,6 @@
# 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.
#
@@ -57,16 +37,12 @@ VIMPROG = <->vim.exe
.SUFFIXES : .out .in
-SCRIPT = test1.out test49.out test77a.out
+SCRIPT = test1.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.*
@@ -87,7 +63,7 @@ SCRIPT_UNIX = test49.out
-@ 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
+all : clean nolog $(START_WITH) $(SCRIPT) nolog
-@ write sys$output " "
-@ write sys$output "-----------------------------------------------"
-@ write sys$output " All done"
@@ -111,12 +87,6 @@ nolog :
-@ 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
diff --git a/src/testdir/Makefile b/src/testdir/Makefile
index 7f9ef0434..0d51fde3e 100644
--- a/src/testdir/Makefile
+++ b/src/testdir/Makefile
@@ -23,28 +23,19 @@ REDIR_TEST_TO_NULL = --cmd 'au SwapExists * let v:swapchoice = "e"' > /dev/null
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.
+# This defines SCRIPTS_FIRST, NEW_TESTS and NEW_TESTS_RES
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
+nongui: nolog $(SCRIPTS_FIRST) newtests report
-gui: nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_GUI) newtests report
+gui: nolog $(SCRIPTS_FIRST) newtests report
benchmark: $(SCRIPTS_BENCH)
@@ -63,10 +54,10 @@ report:
else echo ALL DONE; \
fi"
-$(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_GUI) $(NEW_TESTS_RES): $(VIMPROG)
+$(SCRIPTS_FIRST) $(NEW_TESTS_RES): $(VIMPROG)
# Must run test1 first to create small.vim.
-$(SCRIPTS) $(SCRIPTS_GUI) $(NEW_TESTS_RES): $(SCRIPTS_FIRST)
+$(NEW_TESTS_RES): $(SCRIPTS_FIRST)
# Execute an individual new style test, e.g.:
@@ -116,37 +107,6 @@ test1.out: test1.in
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
diff --git a/src/testdir/README.txt b/src/testdir/README.txt
index d63914676..8bfe47582 100644
--- a/src/testdir/README.txt
+++ b/src/testdir/README.txt
@@ -4,14 +4,6 @@ For testing an indent script see runtime/indent/testdir/README.txt.
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_<subject>.vim file.
@@ -57,16 +49,3 @@ TO ADD A SCREEN DUMP TEST:
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_<subject>.in and test_<subject>.ok files.
-2) Add test_<subject>.out to SCRIPTS_ALL in Make_all.mak in alphabetical order.
-3) Use make test_<subject>.out to run a single test in src/testdir/.
- Use make test_<subject> 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!
diff --git a/src/testdir/test49.in b/src/testdir/test49.in
deleted file mode 100644
index 79f13f6a5..000000000
--- a/src/testdir/test49.in
+++ /dev/null
@@ -1,32 +0,0 @@
-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:
diff --git a/src/testdir/test49.ok b/src/testdir/test49.ok
deleted file mode 100644
index d687f5bc7..000000000
--- a/src/testdir/test49.ok
+++ /dev/null
@@ -1,12 +0,0 @@
-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)
diff --git a/src/testdir/test49.vim b/src/testdir/test49.vim
deleted file mode 100644
index bc3cfc83d..000000000
--- a/src/testdir/test49.vim
+++ /dev/null
@@ -1,1454 +0,0 @@
-" Vim script language tests
-" Author: Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com>
-" 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<Space><C-R>=Xcheck()<CR><C-O>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<Space><C-R>=Xloop()<CR><C-O>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 "<C-O>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<Space><C-R>=Xpath(0)<CR><C-O>x
- iab XloopINIT XloopINIT<Space><C-R>=Xpath(1)<CR><C-O>x
-
- " Also useful (see ExtraVim below):
- aug ExtraVim
- au!
- au BufEnter <sfile> syn region ExtraVim
- \ start=+^if\s\+ExtraVim(.*)+ end=+^endif+
- \ transparent keepend
- au BufEnter <sfile> syn match ExtraComment /^"/
- \ contained containedin=ExtraVim
- au BufEnter <sfile> hi link ExtraComment vimComment
- aug END
-
- aug Xpath
- au BufEnter <sfile> syn keyword Xpath
- \ XpathINIT Xpath XloopINIT Xloop XloopNEXT Xcheck Xout
- au BufEnter <sfile> hi link Xpath Special
- aug END
-
- do BufEnter <sfile>
-
- " 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 <C-P>.) At the end of the
-" test, just type "Xcheck" and press <Esc>.
-"
-" - 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 <count> >>" . g:ExtraVimResult
-else
- com! -count -bar Xpath let g:Xpath = g:Xpath + <count>
-endif
-
-com! -count -nargs=1 -bang
- \ XloopINIT let g:Xnext = <count> |
- \ let g:Xfactor = <args> |
- \ let g:Xskip = strlen("<bang>")
-
-if exists("g:ExtraVimResult")
- com! -count=1 -bar Xloop exec "!echo " . (g:Xnext * <count>) . " >>" .
- \ g:ExtraVimResult
-else
- com! -count=1 -bar Xloop let g:Xpath = g:Xpath + g:Xnext * <count>
-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==<count>) ? "OK (".Xpath.")" :
- \ "FAIL (".Xpath." instead of <count>)"
- \ ) |
- \ let @R = Xresult . "\n" |
- \ echo Xresult |
- \ let Xtest = Xtest + 1
-
-if exists("g:ExtraVimResult")
- com! -nargs=+ Xoutq exec "!echo @R:'" .
- \ substitute(substitute(<q-args>,
- \ "'", '&\\&&', "g"), "\n", "@NL@", "g")
- \ . "' >>" . g:ExtraVimResult
-else
- com! -nargs=+ Xoutq let @R = "--- Test " .
- \ (g:Xtest<10?" ":g:Xtest<100?" ":"") .
- \ g:Xtest . ": " . substitute(<q-args>,
- \ "\n", "&\t ", "g") . "\n"
-endif
-com! -nargs=+ Xout exec 'Xoutq' <args>
-
-" 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 <number> Xcheck <number>
-"
-" 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("<sfile>")
-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*\)\@<!\%(\u\|s:\)\w*\s*(\|'
- \ . 'ExecAsScript\s\+\%(\u\|s:\)\w*',
- \ "W") > 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/\<a:\(\h\w*\)/g:\1/ge
- normal gg0
- let cnt = 0
- while search('\<call\s*\%(\u\|s:\)\w*\s*(.*)', 'W') > 0
- let cnt = cnt + 1
- s/\<call\s*\%(\u\|s:\)\w*\s*(.*)/\='source ' . a:{cnt}/
- endwhile
- g/^\s*$/d
- write
- bwipeout
- return script
-endfunction
-" EXTRA_VIM_STOP - do not change or remove this line.
-
-
-" ExecAsScript - Source a temporary script made from a function. {{{2
-"
-" Make a temporary script file from the function a:funcname, ":source" it, and
-" delete it afterwards.
-"
-" When inside ":if ExtraVim()", add a file breakpoint for each INTERRUPT
-" location specified in the function.
-"
-" EXTRA_VIM_START - do not change or remove this line.
-function ExecAsScript(funcname)
- " Make a script from the function passed as argument.
- let script = MakeScript(a:funcname)
-
- " When running in an extra Vim process, add a file breakpoint for each
- " function breakpoint set when the extra Vim process was invoked by
- " ExtraVim().
- if exists("g:ExtraVimResult")
- let bplist = tempname()
- execute "redir! >" . 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(<f-args>)
-" 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
-"-------------------------------------------------------------------------------
diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim
index e71a3dfde..6a86b1d77 100644
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -5040,4 +5040,27 @@ func Test_lhelpgrep_from_help_window()
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
diff --git a/src/testdir/test_vimscript.vim b/src/testdir/test_vimscript.vim
index e63f647bb..1b00fc9e7 100644
--- a/src/testdir/test_vimscript.vim
+++ b/src/testdir/test_vimscript.vim
@@ -1,5 +1,6 @@
" Test various aspects of the Vim script language.
-" Most of this was formerly in test49.
+" Most of this was formerly in test49.vim (developed by Servatius Brandt
+" <Servatius.Brandt@fujitsu-siemens.com>)
source check.vim
source shared.vim
@@ -5868,7 +5869,7 @@ func Test_discard_exception_after_error_1()
call RunInNewVim(test, verify)
endfunc
-" TODO: Not able inject an interrupt after throwing an exception
+" TODO: Need to interrupt the code before the endtry is invoked
func Disable_Test_discard_exception_after_error_2()
let test =<< trim [CODE]
try
@@ -5892,6 +5893,507 @@ func Disable_Test_discard_exception_after_error_2()
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 needs to correctly parse the funcref and even when it does
diff --git a/src/version.c b/src/version.c
index 990b945ab..a31436bd0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1420,
+/**/
1419,
/**/
1418,