diff options
author | Bram Moolenaar <Bram@vim.org> | 2004-06-13 20:20:40 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2004-06-13 20:20:40 +0000 |
commit | 071d4279d6ab81b7187b48f3a0fc61e587b6db6c (patch) | |
tree | 221cbe3c40e043163c06f61c52a7ba2eb41e12ce /src/testdir | |
parent | b4210b3bc14e2918f153a7307530fbe6eba659e1 (diff) | |
download | vim-git-071d4279d6ab81b7187b48f3a0fc61e587b6db6c.tar.gz |
updated for version 7.0001v7.0001
Diffstat (limited to 'src/testdir')
121 files changed, 15553 insertions, 0 deletions
diff --git a/src/testdir/Make_amiga.mak b/src/testdir/Make_amiga.mak new file mode 100644 index 000000000..0970b729f --- /dev/null +++ b/src/testdir/Make_amiga.mak @@ -0,0 +1,97 @@ +# +# Makefile to run al tests for Vim, on Amiga +# +# Requires "rm", "csh" and "diff"! + +VIMPROG = /vim + +# These tests don't work (yet): +# test2 "\\tmp" doesn't work +# test10 'errorformat' is different +# test11 "cat" doesn't work properly +# test12 can't unlink a swap file +# test25 uses symbolic link +# test27 can't edit file with "*" +# test52 only for Win32 + +SCRIPTS = test1.out test3.out test4.out test5.out test6.out \ + test7.out test8.out test9.out \ + test13.out test14.out test15.out test17.out \ + test18.out test19.out test20.out test21.out test22.out \ + test23.out test24.out test26.out \ + test28.out test29.out test30.out test31.out test32.out \ + test33.out test34.out test35.out test36.out test37.out \ + test38.out test39.out test40.out test41.out test42.out \ + test43.out test44.out test45.out test46.out test47.out \ + test48.out test51.out + +.SUFFIXES: .in .out + +nongui: /tmp $(SCRIPTS) + csh -c echo ALL DONE + +clean: + csh -c \rm -rf *.out /tmp/* Xdotest small.vim tiny.vim mbyte.vim test.ok viminfo + +.in.out: + copy $*.ok test.ok + $(VIMPROG) -u amiga.vim -U NONE --noplugin -s dotest.in $*.in + diff test.out $*.ok + rename test.out $*.out + -delete X#? ALL QUIET + -delete test.ok + +# Create a directory for temp files +/tmp: + makedir /tmp + +# Manx requires all dependencies... +test1.out: test1.in +test2.out: test2.in +test3.out: test3.in +test4.out: test4.in +test5.out: test5.in +test6.out: test6.in +test7.out: test7.in +test8.out: test8.in +test9.out: test9.in +test10.out: test10.in +test11.out: test11.in +test12.out: test12.in +test13.out: test13.in +test14.out: test14.in +test15.out: test15.in +test16.out: test16.in +test17.out: test17.in +test18.out: test18.in +test19.out: test19.in +test20.out: test20.in +test21.out: test21.in +test22.out: test22.in +test23.out: test23.in +test24.out: test24.in +test25.out: test25.in +test26.out: test26.in +test27.out: test27.in +test28.out: test28.in +test29.out: test29.in +test30.out: test30.in +test31.out: test31.in +test32.out: test32.in +test33.out: test33.in +test34.out: test34.in +test35.out: test35.in +test36.out: test36.in +test37.out: test37.in +test38.out: test38.in +test39.out: test39.in +test40.out: test40.in +test41.out: test41.in +test42.out: test42.in +test43.out: test43.in +test44.out: test44.in +test45.out: test45.in +test46.out: test46.in +test47.out: test47.in +test48.out: test48.in +test51.out: test51.in diff --git a/src/testdir/Make_dos.mak b/src/testdir/Make_dos.mak new file mode 100644 index 000000000..b15951e6d --- /dev/null +++ b/src/testdir/Make_dos.mak @@ -0,0 +1,64 @@ +# +# Makefile to run al tests for Vim, on Dos-like machines. +# +# Requires a set of Unix tools: echo, diff, etc. + +VIMPROG = ..\\vim + +# Omitted: +# test2 "\\tmp" doesn't work. +# test10 'errorformat' is different +# test12 can't unlink a swap file +# test25 uses symbolic link +# test27 can't edit file with "*" in file name +# test31 16 bit version runs out of memory... + +SCRIPTS16 = test1.out test19.out test20.out test22.out \ + test23.out test24.out test28.out test29.out \ + test35.out test36.out test43.out \ + test44.out test45.out test46.out test47.out \ + test48.out test51.out + +SCRIPTS = test3.out test4.out test5.out test6.out test7.out \ + test8.out test9.out test11.out test13.out test14.out \ + test15.out test17.out test18.out test21.out test26.out \ + test30.out test31.out test32.out test33.out test34.out \ + test37.out test38.out test39.out test40.out test41.out \ + test42.out test52.out + +SCRIPTS32 = test50.out + +SCRIPTS_GUI = test16.out + +.SUFFIXES: .in .out + +nongui: $(SCRIPTS16) $(SCRIPTS) + echo ALL DONE + +small: $(SCRIPTS16) + echo ALL DONE + +gui: $(SCRIPTS16) $(SCRIPTS) $(SCRIPTS_GUI) + echo ALL DONE + +win32: $(SCRIPTS16) $(SCRIPTS) $(SCRIPTS32) + echo ALL DONE + +clean: + -del *.out + -del test.ok + -del small.vim + -del tiny.vim + -del mbyte.vim + -del X* + -del viminfo + +.in.out: + copy $*.ok test.ok + $(VIMPROG) -u dos.vim -U NONE --noplugin -s dotest.in $*.in + diff test.out $*.ok + -del $*.out + rename test.out $*.out + -del X* + -del test.ok + -del viminfo diff --git a/src/testdir/Make_os2.mak b/src/testdir/Make_os2.mak new file mode 100644 index 000000000..af582023a --- /dev/null +++ b/src/testdir/Make_os2.mak @@ -0,0 +1,52 @@ +# +# Makefile to run al tests for Vim, on OS/2 +# +# Requires a set of Unix tools: echo, diff, etc. + +VIMPROG = ../vim.exe + +# Omitted: +# test2 "\\tmp" doesn't work. +# test10 'errorformat' is different +# test11 requires sed +# test12 can't unlink a swap file +# test25 uses symbolic link +# test27 can't edit file with "*" in file name +# test52 only for Win32 + +SCRIPTS = test1.out test3.out test4.out test5.out test6.out \ + test7.out test8.out test9.out \ + test13.out test14.out test15.out test17.out \ + test18.out test19.out test20.out test21.out test22.out \ + test23.out test24.out test26.out \ + test28.out test29.out test30.out test31.out test32.out \ + test33.out test34.out test35.out test36.out test37.out \ + test38.out test39.out test40.out test41.out test42.out \ + test43.out test44.out test45.out test46.out test47.out \ + test48.out test51.out + +.SUFFIXES: .in .out + +all: /tmp $(SCRIPTS) + @echo ALL DONE + +$(SCRIPTS): $(VIMPROG) + +clean: + -rm -rf *.out Xdotest test.ok tiny.vim small.vim mbyte.vim viminfo + +# Make sure all .in and .out files are in DOS fileformat. +.in.out: + $(VIMPROG) -u NONE -s todos.vim $*.in + $(VIMPROG) -u NONE -s todos.vim $*.ok + copy $*.ok test.ok + $(VIMPROG) -u os2.vim --noplugin -s dotest.in $*.in + $(VIMPROG) -u NONE -s todos.vim test.out + diff test.out $*.ok + rename test.out $*.out + -rm -rf X* viminfo + -del test.ok + +# Create a directory for temp files +/tmp: + -mkdir /tmp diff --git a/src/testdir/Make_vms.mms b/src/testdir/Make_vms.mms new file mode 100644 index 000000000..23b0b26fc --- /dev/null +++ b/src/testdir/Make_vms.mms @@ -0,0 +1,124 @@ +# +# Makefile to run all tests for Vim on VMS +# +# Authors: Zoltan Arpadffy, <arpadffy@polarhome.com> +# Sandor Kopanyi, <sandor.kopanyi@mailbox.hu> +# +# Last change: 2004 May 03 +# +# This has been tested on VMS 6.2 to 7.2 on DEC Alpha and VAX. +# Edit the lines in the Configuration section below to select. +# +# Execute with: +# mms/descrip=Make_vms.mms +# Cleanup with: +# mms/descrip=Make_vms.mms clean +# +# Make files are MMK compatible. +# +# NOTE: You can run this script just in X/Window environment. It will +# create a new terminals, therefore you have to set up your DISPLAY +# logical. More info in VMS documentation or with: help set disp. +# +####################################################################### +# Configuration section. +####################################################################### + +# 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 + +####################################################################### +# End of configuration section. +# +# Please, do not change anything below without programming experience. +####################################################################### + +VIMPROG = <->vim.exe + +.SUFFIXES : .out .in + +SCRIPT = test1.out test2.out test3.out test4.out test5.out \ + test6.out test7.out test8.out test9.out test10a.out\ + test13.out test14.out test15.out test17.out \ + test18.out test19.out test20.out test21.out test22.out \ + test23.out test24.out test26.out \ + test28.out test29.out test31.out test32.out \ + test33.out test34.out test35.out test36.out test37.out \ + test38.out test39.out test40.out test41.out test42.out \ + test43.out test44.out test45.out test46.out \ + test48.out test51.out + +.IFDEF WANT_GUI +SCRIPT_GUI = test16.out +GUI_OPTION = -g +.ENDIF + +.IFDEF WANT_UNIX +SCRIPT_UNIX = test10.out test12.out test25.out test27.out test30.out test49.out +.ENDIF + +.IFDEF HAVE_GZIP +SCRIPT_GZIP = test11.out +.ENDIF + +.IFDEF HAVE_GDIFF +SCRIPT_GDIFF = test47.out +.ENDIF + +.in.out : + -@ write sys$output " " + -@ write sys$output "-----------------------------------------------" + -@ write sys$output " "$*" " + -@ write sys$output "-----------------------------------------------" + -@ create/term/wait mcr $(VIMPROG) $(GUI_OPTION) -u vms.vim --noplugin -s dotest.in $*.in + -@ if "''F$SEARCH("test.out.*")'" .NES. "" then differences test.out $*.ok; + -@ if "''F$SEARCH("test.out.*")'" .NES. "" then rename test.out $*.out + -@ if "''F$SEARCH("Xdotest.*")'" .NES. "" then delete/noconfirm/nolog Xdotest.*.* + +all : clean nolog $(SCRIPT) $(SCRIPT_GUI) $(SCRIPT_UNIX) $(SCRIPT_GZIP) $(SCRIPT_GDIFF) + -@ write sys$output " " + -@ write sys$output "-----------------------------------------------" + -@ write sys$output " All done" + -@ write sys$output "-----------------------------------------------" + -@ deassign sys$output + -@ delete/noconfirm/nolog x*.*.* + -@ type test.log + +nolog : + -@ define sys$output test.log + -@ write sys$output "-----------------------------------------------" + -@ write sys$output " Standard VIM test cases" + -@ write sys$output "-----------------------------------------------" + -@ write sys$output " OpenVMS version: ''F$GETSYI("VERSION")'" + -@ write sys$output " Vim version:" + -@ mcr $(VIMPROG) --version + -@ write sys$output " Test date:" + -@ show time + -@ write sys$output "-----------------------------------------------" + -@ write sys$output " Test results:" + -@ 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 "Default vimrc file is VMS.VIM: + -@ write sys$output "-----------------------------------------------" + -@ type VMS.VIM + +clean : + -@ if "''F$SEARCH("*.out")'" .NES. "" then delete/noconfirm/nolog *.out.* + -@ if "''F$SEARCH("test.log")'" .NES. "" then delete/noconfirm/nolog test.log.* + -@ if "''F$SEARCH("Xdotest.*")'" .NES. "" then delete/noconfirm/nolog Xdotest.*.* + -@ if "''F$SEARCH("*.*_sw*")'" .NES. "" then delete/noconfirm/nolog *.*_sw*.* diff --git a/src/testdir/Makefile b/src/testdir/Makefile new file mode 100644 index 000000000..7ed97fe21 --- /dev/null +++ b/src/testdir/Makefile @@ -0,0 +1,58 @@ +# +# Makefile to run al tests for Vim +# + +VIMPROG = ../vim + +SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \ + test7.out test8.out test9.out test10.out test11.out \ + test12.out test13.out test14.out test15.out test17.out \ + test18.out test19.out test20.out test21.out test22.out \ + test23.out test24.out test25.out test26.out test27.out \ + test28.out test29.out test30.out test31.out test32.out \ + test33.out test34.out test35.out test36.out test37.out \ + test38.out test39.out test40.out test41.out test42.out \ + test43.out test44.out test45.out test46.out test47.out \ + test48.out test49.out test51.out test52.out + +SCRIPTS_GUI = test16.out + +.SUFFIXES: .in .out + +nongui: nolog $(SCRIPTS) + @echo + @cat test.log + @echo ALL DONE + +gui: nolog $(SCRIPTS) $(SCRIPTS_GUI) + @echo + @cat test.log + @echo ALL DONE + +$(SCRIPTS) $(SCRIPTS_GUI): $(VIMPROG) + +clean: + -rm -rf *.out *.rej *.orig test.log tiny.vim small.vim mbyte.vim test.ok X* viminfo + +test1.out: test1.in + -rm -f $*.failed tiny.vim small.vim mbyte.vim test.ok X* viminfo + $(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in + @/bin/sh -c "if diff test.out $*.ok; \ + then mv -f test.out $*.out; \ + else echo; \ + echo test1 FAILED - Something basic is wrong; \ + echo; exit 1; fi" + -rm -rf X* viminfo + +.in.out: + -rm -f $*.failed test.ok X* + cp $*.ok test.ok + $(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in + @/bin/sh -c "if diff test.out $*.ok; \ + then mv -f test.out $*.out; \ + else echo $* FAILED >>test.log; mv -f test.out $*.failed; \ + fi" + -rm -rf X* test.ok viminfo + +nolog: + -echo Test results: >test.log diff --git a/src/testdir/amiga.vim b/src/testdir/amiga.vim new file mode 100644 index 000000000..e0ca47a8e --- /dev/null +++ b/src/testdir/amiga.vim @@ -0,0 +1,4 @@ +" Settings for test script execution +set shell=csh +map! /tmp t: +cmap !rm !Delete all diff --git a/src/testdir/dos.vim b/src/testdir/dos.vim new file mode 100644 index 000000000..27764db9d --- /dev/null +++ b/src/testdir/dos.vim @@ -0,0 +1,7 @@ +" Settings for test script execution +" Always use "COMMAND.COM", don't use the value of "$SHELL". +set shell=c:\COMMAND.COM shellquote= shellxquote= shellcmdflag=/c shellredir=> +" This is used only when the +eval feature is available. +if executable("cmd.exe") + set shell=cmd.exe +endif diff --git a/src/testdir/dotest.in b/src/testdir/dotest.in new file mode 100644 index 000000000..b2a0e1a68 --- /dev/null +++ b/src/testdir/dotest.in @@ -0,0 +1,3 @@ +:set cp +:map dotest /^STARTTEST
j:set ff=unix cpo-=A
:.,/ENDTEST/-1w! Xdotest
:set ff& cpo+=A
nj0:so! Xdotest
dotest +dotest diff --git a/src/testdir/main.aap b/src/testdir/main.aap new file mode 100644 index 000000000..0293b92f8 --- /dev/null +++ b/src/testdir/main.aap @@ -0,0 +1,58 @@ +# +# Makefile to run al tests for Vim +# + +VimProg ?= ../vim + +Scripts = test1.out test2.out test3.out test4.out test5.out test6.out + test7.out test8.out test9.out test10.out test11.out + test12.out test13.out test14.out test15.out test17.out + test18.out test19.out test20.out test21.out test22.out + test23.out test24.out test25.out test26.out test27.out + test28.out test29.out test30.out test31.out test32.out + test33.out test34.out test35.out test36.out test37.out + test38.out test39.out test40.out test41.out test42.out + test43.out test44.out test45.out test46.out test47.out + test48.out test49.out + +ScriptsGUI = test16.out + +# Build "nongui" when no target was specified. +nongui: newlog $Scripts + :print + :cat test.log + :print ALL DONE + +# Build "ngui" when specified. +gui: newlog $Scripts $ScriptsGUI + :print + :cat test.log + :print ALL DONE + +$Scripts $ScriptsGUI: $VimProg + +clean: + :del {r}{force} *.out test.log tiny.vim small.vim mbyte.vim test.ok X* + +# test1 is special, it checks for features +test1.out: test1.in + :del {force} test1.failed tiny.vim small.vim mbyte.vim + :sys {i} $VimProg -u unix.vim -U NONE --noplugin -s dotest.in test1.in + @if os.system("diff test.out test1.ok") != 0: + :error test1 FAILED - Something basic is wrong + :move {force} test.out test1.out + :del {r}{force} X* + +:rule %.out : %.in + :del {force} $(match).failed test.ok + :copy $(match).ok test.ok + :sys {i} $VimProg -u unix.vim -U NONE --noplugin -s dotest.in $(match).in + @if os.system("diff test.out " + match + ".ok") != 0: + :print $match FAILED >>test.log + :move {force} test.out $(match).failed + @else: + :move {force} test.out $(match).out + :del {r}{force} X* test.ok + +newlog: + :print Test results: >! test.log diff --git a/src/testdir/os2.vim b/src/testdir/os2.vim new file mode 100644 index 000000000..c97ba5d00 --- /dev/null +++ b/src/testdir/os2.vim @@ -0,0 +1,3 @@ +" Settings for test script execution +" Always use "CMD.EXE", don't use the value of "$SHELL". +set shell=CMD.EXE shellquote= shellxquote= shellcmdflag=/c shellredir=> diff --git a/src/testdir/test1.in b/src/testdir/test1.in new file mode 100644 index 000000000..6d1bddee9 --- /dev/null +++ b/src/testdir/test1.in @@ -0,0 +1,40 @@ + +First a simple test to check if the test script works. + +If Vim was not compiled with the +eval feature, the small.vim script will be +set to copy the test.ok file to test.out, so that it looks like the test +succeeded. Otherwise an empty small.vim is written. small.vim is sourced by +tests that require the +eval feature or other features that are missing in the +small version. + +If Vim was not compiled with the +windows feature, the tiny.vim script will be +set like small.vim above. tiny.vim is sourced by tests that require the ++windows feature or other features that are missing in the tiny version. + +If Vim was not compiled with the +multi_byte feature, the mbyte.vim script will be set like small.vim above. mbyte.vim is sourced by tests that require the ++multi_byte feature. + +STARTTEST +:" Write a single line to test.out to check if testing works at all. +:%d +athis is a test:w! test.out +:" Create small.vim and tiny.vim empty, create mbyte.vim to skip the test. +0D:w! small.vim +:w! tiny.vim +ae! test.ok +w! test.out +qa! +:w! mbyte.vim +:" If +multi_byte feature supported, make mbyte.vim empty. +:if has("multi_byte") | sp another | w! mbyte.vim | q | endif +:" If +eval feature supported quit here, leaving tiny.vim and small.vim empty. +:" Otherwise write small.vim to skip the test. +:if 1 | q! | endif +:w! small.vim +:" If +windows feature not supported :sp will fail and tiny.vim will be +:" written to skip the test. +:sp another +:wq! tiny.vim +:qa! +ENDTEST + diff --git a/src/testdir/test1.ok b/src/testdir/test1.ok new file mode 100644 index 000000000..90bfcb510 --- /dev/null +++ b/src/testdir/test1.ok @@ -0,0 +1 @@ +this is a test diff --git a/src/testdir/test10.in b/src/testdir/test10.in new file mode 100644 index 000000000..f15c4f5d2 --- /dev/null +++ b/src/testdir/test10.in @@ -0,0 +1,57 @@ +Test for 'errorformat'. + +STARTTEST +:so small.vim +:/start of errorfile/,/end of errorfile/w! Xerrorfile +:/start of testfile/,/end of testfile/w! Xtestfile +:cf Xerrorfile +rA +:cn +rB +:cn +rC +:cn +rD +:cn +rE +:w! test.out " Write contents of this file +:qa! +ENDTEST + +start of errorfile +"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set. +"Xtestfile", line 7 col 19; this is an error +gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c +Xtestfile:13: parse error before `asd' +make: *** [vim] Error 1 +in file "Xtestfile" linenr 16: there is an error + +2 returned +"Xtestfile", linenr 19: yet another problem + +Does anyone know what is the problem and how to correction it? +end of errorfile + +start of testfile +line 2 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 4 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 8 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 10 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 11 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 12 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 13 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 14 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 15 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 16 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 17 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 18 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 19 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 20 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 21 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 22 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +end of testfile diff --git a/src/testdir/test10.ok b/src/testdir/test10.ok new file mode 100644 index 000000000..2c86889c1 --- /dev/null +++ b/src/testdir/test10.ok @@ -0,0 +1,23 @@ +start of testfile +line 2 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 4 xxxAxxxxxxxxxxxxxxxxxxxxxxxxxx +line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 7 xxxxxxxxxxBxxxxxxxxxxxxxxxxxxx +line 8 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 10 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 11 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 12 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +Cine 13 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 14 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 15 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +Dine 16 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 17 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 18 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +Eine 19 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 20 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 21 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 22 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +end of testfile diff --git a/src/testdir/test10a.in b/src/testdir/test10a.in new file mode 100644 index 000000000..19e8652fe --- /dev/null +++ b/src/testdir/test10a.in @@ -0,0 +1,73 @@ +Test for 'errorformat'. + +STARTTEST +:so small.vim +:/start of errorfile/,/end of errorfile/w! Xerrorfile +:/start of testfile/,/end of testfile/w! Xtestfile +:cf Xerrorfile +rA +:cn +rB +:cn +rC +:cn +rD +:cn +rE +:w! test.out " Write contents of this file +:qa! +ENDTEST + +start of errorfile + + printf(" %d \n", (number/other)%10 ); +..................^ +%CC-E-NOSEMI, Missing ";". +at line number 4 in file SYS$DISK:XTESTFILE + + other=10000000; +.............^ +%CC-E-UNDECLARED, In this statement, "oszt" is not declared. +at line number 7 in file SYS$DISK:XTESTFILE + + for (i = 0; i<7 ; i++ ){ +..................^ +%CC-E-UNDECLARED, In this statement, "i" is not declared. +at line number 16 in file SYS$DISK:XTESTFILE + +some other error somewhere here. +...........................^ +%CC-W-WARRING, Sorry, but no expalnation for such an warring. +at line number 19 in file SYS$DISK:XTESTFILE + +and finally some other error exactly here. +.....................................^ +%CC-I-INFORMATIONAL, It should be some informational message. +at line number 20 in file SYS$DISK:XTESTFILE + +Does anyone know what is the problem and how to correct ?? :) +end of errorfile + +start of testfile +01234567890123456789012345678901234567 +line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 4 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 8 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 10 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 11 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 12 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 13 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 14 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 15 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 16 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 17 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 18 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 19 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 20 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 21 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 22 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +end of testfile diff --git a/src/testdir/test10a.ok b/src/testdir/test10a.ok new file mode 100644 index 000000000..10e78c923 --- /dev/null +++ b/src/testdir/test10a.ok @@ -0,0 +1,23 @@ +start of testfile +01234567890123456789012345678901234567 +line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 4 xxxxxxxxxxAxxxxxxxxxxxxxxxxxxx +line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 7 xxxxxBxxxxxxxxxxxxxxxxxxxxxxxx +line 8 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 10 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 11 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 12 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 13 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 14 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 15 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 16 xxxxxxxxxxCxxxxxxxxxxxxxxxxxxx +line 17 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 18 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 19 xxxxxxxxxxxxxxxxxxxDxxxxxxxxxx +line 20 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxE +line 21 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 22 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +end of testfile diff --git a/src/testdir/test11.in b/src/testdir/test11.in new file mode 100644 index 000000000..6b296fd4e --- /dev/null +++ b/src/testdir/test11.in @@ -0,0 +1,77 @@ +Tests for autocommands: +- FileWritePre writing a compressed file +- FileReadPost reading a compressed file +- BufNewFile reading a file template +- BufReadPre decompressing the file to be read +- FilterReadPre substituting characters in the temp file +- FilterReadPost substituting characters after filtering +- FileReadPre set options for decompression +- FileReadPost decompress the file + +Note: This test will fail if "gzip" is not available. +$GZIP is made empty, "-v" would cause trouble. +Use a FileChangedShell autocommand to avoid a prompt for "Xtestfile.gz" being +modified outside of Vim (noticed on Solaris). + +STARTTEST +:so small.vim +:let $GZIP = "" +:au FileChangedShell * echo "caught FileChangedShell" +:set bin +:au FileWritePre *.gz '[,']!gzip +:au FileWritePost *.gz undo +:/start of testfile/,/end of testfile/w! Xtestfile.gz +:au FileReadPost *.gz '[,']!gzip -d +:$r Xtestfile.gz " Read and decompress the testfile +:?startstart?,$w! test.out " Write contents of this file +:au BufNewFile *.c read Xtest.c +gg/^end of testfile +:/start of test.c/+1,/end of test.c/-1w! Xtest.c +:e! foo.c " Will load Xtest.c +:au FileAppendPre *.out '[,']s/new/NEW/ +:au FileAppendPost *.out !cat Xtest.c >>test.out +:w>>test.out " Append it to the output file +:au! FileAppendPre +:" setup autocommands to decompress before reading and re-compress afterwards +:au BufReadPre *.gz !gzip -d <afile> +:au BufReadPre *.gz call rename(expand("<afile>:r"), expand("<afile>")) +:au BufReadPost *.gz call rename(expand("<afile>"), expand("<afile>:r")) +:au BufReadPost *.gz !gzip <afile>:r +:e! Xtestfile.gz " Edit compressed file +:w>>test.out " Append it to the output file +:au FilterReadPre *.out call rename(expand("<afile>"), expand("<afile>").".t") +:au FilterReadPre *.out !sed s/e/E/ <afile>.t ><afile> +:au FilterReadPre *.out !rm <afile>.t +:au FilterReadPost *.out '[,']s/x/X/g +:e! test.out " Edit the output file +:23,$!cat +:au! FileReadPre *.gz !gzip -d <afile> +:au FileReadPre *.gz call rename(expand("<afile>:r"), expand("<afile>")) +:au! FileReadPost *.gz '[,']s/l/L/ +:$r Xtestfile.gz " Read compressed file +:w " write it, after filtering +:au! " remove all autocommands +:e " Edit test.out again +:set nobin ff& " use the default fileformat for writing +:w +:qa! +ENDTEST + +startstart +start of testfile +line 2 Abcdefghijklmnopqrstuvwxyz +line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 4 Abcdefghijklmnopqrstuvwxyz +line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 6 Abcdefghijklmnopqrstuvwxyz +line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 8 Abcdefghijklmnopqrstuvwxyz +line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 10 Abcdefghijklmnopqrstuvwxyz +end of testfile + +start of test.c +/* + * Here is a new .c file + */ +end of test.c diff --git a/src/testdir/test11.ok b/src/testdir/test11.ok new file mode 100644 index 000000000..af8c5ce26 --- /dev/null +++ b/src/testdir/test11.ok @@ -0,0 +1,61 @@ +startstart +start of testfile +line 2 Abcdefghijklmnopqrstuvwxyz +line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 4 Abcdefghijklmnopqrstuvwxyz +line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 6 Abcdefghijklmnopqrstuvwxyz +line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 8 Abcdefghijklmnopqrstuvwxyz +line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 10 Abcdefghijklmnopqrstuvwxyz +end of testfile + +start of test.c +/* + * Here is a new .c file + */ +end of test.c +start of testfile +line 2 Abcdefghijklmnopqrstuvwxyz +line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +line 4 Abcdefghijklmnopqrstuvwxyz +linE 5 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +linE 6 AbcdefghijklmnopqrstuvwXyz +linE 7 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +linE 8 AbcdefghijklmnopqrstuvwXyz +linE 9 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +linE 10 AbcdefghijklmnopqrstuvwXyz +End of testfile + +/* + * HEre is a NEW .c file + */ +/* + * HEre is a new .c file + */ +start of tEstfile +linE 2 AbcdefghijklmnopqrstuvwXyz +linE 3 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +linE 4 AbcdefghijklmnopqrstuvwXyz +linE 5 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +linE 6 AbcdefghijklmnopqrstuvwXyz +linE 7 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +linE 8 AbcdefghijklmnopqrstuvwXyz +linE 9 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX +linE 10 AbcdefghijklmnopqrstuvwXyz +End of testfile +/* + * HEre is a new .c file + */ +start of testfiLe +Line 2 Abcdefghijklmnopqrstuvwxyz +Line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +Line 4 Abcdefghijklmnopqrstuvwxyz +Line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +Line 6 Abcdefghijklmnopqrstuvwxyz +Line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +Line 8 Abcdefghijklmnopqrstuvwxyz +Line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +Line 10 Abcdefghijklmnopqrstuvwxyz +end of testfiLe diff --git a/src/testdir/test12.in b/src/testdir/test12.in new file mode 100644 index 000000000..46e9c45b8 --- /dev/null +++ b/src/testdir/test12.in @@ -0,0 +1,52 @@ +Tests for 'directory' option. +- ".", in same dir as file +- "./dir", in directory relative to file +- "dir", in directory relative to current dir + +STARTTEST +:so small.vim +:set nocompatible viminfo+=nviminfo +:set dir=.,~ +:/start of testfile/,/end of testfile/w! Xtest1 +:" do an ls of the current dir to find the swap file (should not be there) +:if has("unix") +: !ls .X*.swp >test.out +:else +: r !ls X*.swp >test.out +:endif +:!echo first line >>test.out +:e Xtest1 +:if has("unix") +:" Do an ls of the current dir to find the swap file, remove the leading dot +:" to make the result the same for all systems. +: r!ls .X*.swp +: s/\.*X/X/ +: .w >>test.out +: undo +:else +: !ls X*.swp >>test.out +:endif +:!echo under Xtest1.swp >>test.out +:!mkdir Xtest2 +:set dir=./Xtest2,.,~ +:e Xtest1 +:!ls X*.swp >>test.out +:!echo under under >>test.out +:!ls Xtest2 >>test.out +:!echo under Xtest1.swp >>test.out +:!mkdir Xtest.je +:/start of testfile/,/end of testfile/w! Xtest2/Xtest3 +:set dir=Xtest.je,~ +:e Xtest2/Xtest3 +:swap +:!ls Xtest2 >>test.out +:!echo under Xtest3 >>test.out +:!ls Xtest.je >>test.out +:!echo under Xtest3.swp >>test.out +:qa! +ENDTEST + +start of testfile +line 2 Abcdefghij +line 3 Abcdefghij +end of testfile diff --git a/src/testdir/test12.ok b/src/testdir/test12.ok new file mode 100644 index 000000000..605623b11 --- /dev/null +++ b/src/testdir/test12.ok @@ -0,0 +1,10 @@ +first line +Xtest1.swp +under Xtest1.swp +under under +Xtest1.swp +under Xtest1.swp +Xtest3 +under Xtest3 +Xtest3.swp +under Xtest3.swp diff --git a/src/testdir/test13.in b/src/testdir/test13.in new file mode 100644 index 000000000..cb8a6fff8 --- /dev/null +++ b/src/testdir/test13.in @@ -0,0 +1,58 @@ +Tests for autocommands on :close command + +Write three files and open them, each in a window. +Then go to next window, with autocommand that deletes the previous one. +Do this twice, writing the file. + +Also test deleting the buffer on a Unload event. If this goes wrong there +will be the ATTENTION prompt. + +Also test changing buffers in a BufDel autocommand. If this goes wrong there +are ml_line errors and/or a Crash. + +STARTTEST +:so small.vim +:/^start of testfile/,/^end of testfile/w! Xtestje1 +:/^start of testfile/,/^end of testfile/w! Xtestje2 +:/^start of testfile/,/^end of testfile/w! Xtestje3 +:e Xtestje1 +otestje1 +:w +:sp Xtestje2 +otestje2 +:w +:sp Xtestje3 +otestje3 +:w + +:au WinLeave Xtestje2 bwipe + +:w! test.out +:au WinLeave Xtestje1 bwipe Xtestje3 +:close +:w >>test.out +:e Xtestje1 +:bwipe Xtestje2 Xtestje3 test.out +:au! +:au! BufUnload Xtestje1 bwipe +:e Xtestje3 +:w >>test.out +:e Xtestje2 +:sp Xtestje1 +:e +:w >>test.out +:au! +:only +:e Xtestje1 +:bwipe Xtestje2 Xtestje3 test.out test13.in +:au BufWipeout Xtestje1 buf Xtestje1 +:bwipe +:w >>test.out +:qa! +ENDTEST + +start of testfile + contents + contents + contents +end of testfile diff --git a/src/testdir/test13.ok b/src/testdir/test13.ok new file mode 100644 index 000000000..0f1fc347a --- /dev/null +++ b/src/testdir/test13.ok @@ -0,0 +1,30 @@ +start of testfile +testje1 + contents + contents + contents +end of testfile +start of testfile +testje1 + contents + contents + contents +end of testfile +start of testfile +testje3 + contents + contents + contents +end of testfile +start of testfile +testje2 + contents + contents + contents +end of testfile +start of testfile +testje1 + contents + contents + contents +end of testfile diff --git a/src/testdir/test14.in b/src/testdir/test14.in new file mode 100644 index 000000000..57fb9573f --- /dev/null +++ b/src/testdir/test14.in @@ -0,0 +1,65 @@ +Tests for "vaBiB", end could be wrong. +Also test ":s/pat/sub/" with different ~s in sub. +Also test for ^Vxff and ^Vo123 in Insert mode. +Also test "[m", "]m", "[M" and "]M" + +STARTTEST +:so small.vim +/Start cursor here +vaBiBD:?Bug?,/Piece/-2w! test.out +/^- Bug +:s/u/~u~/ +:s/i/~u~/ +:s/o/~~~/ +:.w >>test.out +:if has("ebcdic") +: let tt = "o\<C-V>193\<C-V>xc2\<C-V>o303 \<C-V>90a\<C-V>xfg\<C-V>o578\<Esc>" +:else +: let tt = "o\<C-V>65\<C-V>x42\<C-V>o103 \<C-V>33a\<C-V>xfg\<C-V>o78\<Esc>" +:endif +:exe "normal " . tt +:.w >>test.out +:set vb +/^Piece +2]maA:.w >>test.out +j]maB:.w >>test.out +]maC:.w >>test.out +[maD:.w >>test.out +k2[maE:.w >>test.out +3[maF:.w >>test.out +]MaG:.w >>test.out +j2]MaH:.w >>test.out +]M]MaI:.w >>test.out +2[MaJ:.w >>test.out +k[MaK:.w >>test.out +3[MaL:.w >>test.out +:qa! +ENDTEST + +- Bug in "vPPPP" on this text (Webb): + { + cmd; + { + cmd; /* <-- Start cursor here */ + { + } + } + } + +Piece of Java +{ + tt m1 { + t1; + } e1 + + tt m2 { + t2; + } e2 + + tt m3 { + if (x) + { + t3; + } + } e3 +} diff --git a/src/testdir/test14.ok b/src/testdir/test14.ok new file mode 100644 index 000000000..e893ba803 --- /dev/null +++ b/src/testdir/test14.ok @@ -0,0 +1,17 @@ +- Bug in "vPPPP" on this text (Webb): + { + } +- Bug uuun "vPPPP" uuuuuuuuun this text (Webb): +ABC !ag8 + tt m1 {A + tt m2 {B + tt m3 {C + tt m3 {DC + tt m1 {EA +{F + }G e1 + }H e3 +}I + }JH e3 + }K e2 +{LF diff --git a/src/testdir/test15.in b/src/testdir/test15.in new file mode 100644 index 000000000..366529a55 --- /dev/null +++ b/src/testdir/test15.in @@ -0,0 +1,136 @@ +Tests for :right on text with embedded TAB. +Also test formatting a paragraph. +Also test undo after ":%s" and formatting. + +STARTTEST +:so small.vim +:set tw=65 + +:/^\s*test for :left/,/^\s*test for :center/ left +:/^\s*test for :center/,/^\s*test for :right/ center +:/^\s*test for :right/,/^xxx/-1 right +:set fo+=tcroql tw=72 +/xxxxxxxx$ +0gq6kk +:set nocp viminfo+=nviminfo +:" undo/redo here to make the next undo only work on the following changes +u +:map gg :.,.+2s/^/x/<CR>kk:set tw=3<CR>gqq +/^aa +ggu +:?test for :left?,$w! test.out +:qa! +ENDTEST + + test for :left + a a + fa a + dfa a + sdfa a + asdfa a + xasdfa a +asxxdfa a + + test for :center + a a + fa afd asdf + dfa a + sdfa afd asdf + asdfa a + xasdfa asdfasdfasdfasdfasdf +asxxdfa a + + test for :right + a a + fa a + dfa a + sdfa a + asdfa a + xasdfa a + asxxdfa a + asxa;ofa a + asdfaqwer a + a ax + fa ax + dfa ax + sdfa ax + asdfa ax + xasdfa ax + asxxdfa ax + asxa;ofa ax + asdfaqwer ax + a axx + fa axx + dfa axx + sdfa axx + asdfa axx + xasdfa axx + asxxdfa axx + asxa;ofa axx + asdfaqwer axx + a axxx + fa axxx + dfa axxx + sdfa axxx + asdfa axxx + xasdfa axxx + asxxdfa axxx + asxa;ofa axxx + asdfaqwer axxx + a axxxo + fa axxxo + dfa axxxo + sdfa axxxo + asdfa axxxo + xasdfa axxxo + asxxdfa axxxo + asxa;ofa axxxo + asdfaqwer axxxo + a axxxoi + fa axxxoi + dfa axxxoi + sdfa axxxoi + asdfa axxxoi + xasdfa axxxoi + asxxdfa axxxoi + asxa;ofa axxxoi + asdfaqwer axxxoi + a axxxoik + fa axxxoik + dfa axxxoik + sdfa axxxoik + asdfa axxxoik + xasdfa axxxoik + asxxdfa axxxoik + asxa;ofa axxxoik + asdfaqwer axxxoik + a axxxoike + fa axxxoike + dfa axxxoike + sdfa axxxoike + asdfa axxxoike + xasdfa axxxoike + asxxdfa axxxoike + asxa;ofa axxxoike + asdfaqwer axxxoike + a axxxoikey + fa axxxoikey + dfa axxxoikey + sdfa axxxoikey + asdfa axxxoikey + xasdfa axxxoikey + asxxdfa axxxoikey + asxa;ofa axxxoikey + asdfaqwer axxxoikey + +xxxxx xx xxxxxx +xxxxxxx xxxxxxxxx xxx xxxx xxxxx xxxxx xxx xx +xxxxxxxxxxxxxxxxxx xxxxx xxxx, xxxx xxxx xxxx xxxx xxx xx xx +xx xxxxxxx. xxxx xxxx. + +> xx xx, xxxx xxxx xxx xxxx xxx xxxxx xxx xxx xxxxxxx xxx xxxxx +> xxxxxx xxxxxxx: xxxx xxxxxxx, xx xxxxxx xxxx xxxxxxxxxx + +aa aa aa aa +bb bb bb bb +cc cc cc cc diff --git a/src/testdir/test15.ok b/src/testdir/test15.ok new file mode 100644 index 000000000..bc09f5e7d --- /dev/null +++ b/src/testdir/test15.ok @@ -0,0 +1,111 @@ +test for :left +a a +fa a +dfa a +sdfa a +asdfa a +xasdfa a +asxxdfa a + + test for :center + a a + fa afd asdf + dfa a + sdfa afd asdf + asdfa a + xasdfa asdfasdfasdfasdfasdf + asxxdfa a + + test for :right + a a + fa a + dfa a + sdfa a + asdfa a + xasdfa a + asxxdfa a + asxa;ofa a + asdfaqwer a + a ax + fa ax + dfa ax + sdfa ax + asdfa ax + xasdfa ax + asxxdfa ax + asxa;ofa ax + asdfaqwer ax + a axx + fa axx + dfa axx + sdfa axx + asdfa axx + xasdfa axx + asxxdfa axx + asxa;ofa axx + asdfaqwer axx + a axxx + fa axxx + dfa axxx + sdfa axxx + asdfa axxx + xasdfa axxx + asxxdfa axxx + asxa;ofa axxx + asdfaqwer axxx + a axxxo + fa axxxo + dfa axxxo + sdfa axxxo + asdfa axxxo + xasdfa axxxo + asxxdfa axxxo + asxa;ofa axxxo + asdfaqwer axxxo + a axxxoi + fa axxxoi + dfa axxxoi + sdfa axxxoi + asdfa axxxoi + xasdfa axxxoi + asxxdfa axxxoi + asxa;ofa axxxoi + asdfaqwer axxxoi + a axxxoik + fa axxxoik + dfa axxxoik + sdfa axxxoik + asdfa axxxoik + xasdfa axxxoik + asxxdfa axxxoik + asxa;ofa axxxoik + asdfaqwer axxxoik + a axxxoike + fa axxxoike + dfa axxxoike + sdfa axxxoike + asdfa axxxoike + xasdfa axxxoike + asxxdfa axxxoike + asxa;ofa axxxoike + asdfaqwer axxxoike + a axxxoikey + fa axxxoikey + dfa axxxoikey + sdfa axxxoikey + asdfa axxxoikey + xasdfa axxxoikey + asxxdfa axxxoikey + asxa;ofa axxxoikey + asdfaqwer axxxoikey + +xxxxx xx xxxxxx xxxxxxx xxxxxxxxx xxx xxxx xxxxx xxxxx xxx xx +xxxxxxxxxxxxxxxxxx xxxxx xxxx, xxxx xxxx xxxx xxxx xxx xx xx xx xxxxxxx. +xxxx xxxx. + +> xx xx, xxxx xxxx xxx xxxx xxx xxxxx xxx xxx xxxxxxx xxx xxxxx xxxxxx +> xxxxxxx: xxxx xxxxxxx, xx xxxxxx xxxx xxxxxxxxxx + +aa aa aa aa +bb bb bb bb +cc cc cc cc diff --git a/src/testdir/test16.in b/src/testdir/test16.in new file mode 100644 index 000000000..7fc0d50cf --- /dev/null +++ b/src/testdir/test16.in @@ -0,0 +1,10 @@ +Tests for resetting "secure" flag after GUI has started. + +STARTTEST +:set exrc secure +:gui -f +:.,$w! test.out +:qa! +ENDTEST + + just some text diff --git a/src/testdir/test16.ok b/src/testdir/test16.ok new file mode 100644 index 000000000..25e2eea5c --- /dev/null +++ b/src/testdir/test16.ok @@ -0,0 +1,2 @@ + + just some text diff --git a/src/testdir/test17.in b/src/testdir/test17.in new file mode 100644 index 000000000..e59144ffb --- /dev/null +++ b/src/testdir/test17.in @@ -0,0 +1,27 @@ +Tests for "gf" on ${VAR} + +STARTTEST +:so small.vim +:if has("ebcdic") +: set isfname=@,240-249,/,.,-,_,+,,,$,:,~,{,} +:else +: set isfname=@,48-57,/,.,-,_,+,,,$,:,~,{,} +:endif +:if has("unix") +:let $CDIR = "." +/CDIR +:else +:if has("amiga") +:let $TDIR = "/testdir" +:else +:let $TDIR = "." +:endif +/TDIR +:endif +gf +:w! test.out +:qa! +ENDTEST + + ${CDIR}/test17a.in + $TDIR/test17a.in diff --git a/src/testdir/test17.ok b/src/testdir/test17.ok new file mode 100644 index 000000000..58c3504ad --- /dev/null +++ b/src/testdir/test17.ok @@ -0,0 +1,3 @@ +This file is just to test "gf" in test 17. +The contents is not importent. +Just testing! diff --git a/src/testdir/test17a.in b/src/testdir/test17a.in new file mode 100644 index 000000000..58c3504ad --- /dev/null +++ b/src/testdir/test17a.in @@ -0,0 +1,3 @@ +This file is just to test "gf" in test 17. +The contents is not importent. +Just testing! diff --git a/src/testdir/test18.in b/src/testdir/test18.in new file mode 100644 index 000000000..9bfd92234 --- /dev/null +++ b/src/testdir/test18.in @@ -0,0 +1,16 @@ +Tests for not doing smart indenting when it isn't set. + +STARTTEST +:so small.vim +:set nocin nosi ai +/some +2cc#test +:?start?,$w! test.out +:qa! +ENDTEST + +start text + some test text + test text +test text + test text diff --git a/src/testdir/test18.ok b/src/testdir/test18.ok new file mode 100644 index 000000000..e71971378 --- /dev/null +++ b/src/testdir/test18.ok @@ -0,0 +1,4 @@ +start text + #test +test text + test text diff --git a/src/testdir/test19.in b/src/testdir/test19.in new file mode 100644 index 000000000..0d9b421a2 --- /dev/null +++ b/src/testdir/test19.in @@ -0,0 +1,23 @@ +Tests for "r<Tab>" with 'smarttab' and 'expandtab' set/not set. + +STARTTEST +:set smarttab expandtab ts=8 sw=4 +/some +r :set noexpandtab +/other +r +:" Test replacing with Tabs and then backspacing to undo it +0wR +:" Test replacing with Tabs +0wR +:?^start?,$w! test.out +:qa! +ENDTEST + +start text + some test text +test text + other test text + a cde + f ghi +test text diff --git a/src/testdir/test19.ok b/src/testdir/test19.ok new file mode 100644 index 000000000..ba4eb63be --- /dev/null +++ b/src/testdir/test19.ok @@ -0,0 +1,7 @@ +start text + ome test text +test text + ther test text + a cde + hi +test text diff --git a/src/testdir/test2.in b/src/testdir/test2.in new file mode 100644 index 000000000..b7b5a5106 --- /dev/null +++ b/src/testdir/test2.in @@ -0,0 +1,29 @@ + +This is a test if a URL is recognized by "gf", with the cursor before and +after the "://". Also test ":\\". + +STARTTEST +:so small.vim +/^first +/tmp +:call append(0, expand("<cfile>")) +/^second +/URL +:call append(1, expand("<cfile>")) +:if has("ebcdic") +: set isf=@,240-249,/,.,-,_,+,,,$,:,~,\ +:else +: set isf=@,48-57,/,.,-,_,+,,,$,:,~,\ +:endif +/^third +/name +:call append(2, expand("<cfile>")) +/^fourth +/URL +:call append(3, expand("<cfile>")) +5GdG:wq! test.out +ENDTEST +first test for URL://machine.name/tmp/vimtest2a and other text +second test for URL://machine.name/tmp/vimtest2b. And other text +third test for URL:\\machine.name\vimtest2c and other text +fourth test for URL:\\machine.name\tmp\vimtest2d, and other text diff --git a/src/testdir/test2.ok b/src/testdir/test2.ok new file mode 100644 index 000000000..32978825f --- /dev/null +++ b/src/testdir/test2.ok @@ -0,0 +1,4 @@ +URL://machine.name/tmp/vimtest2a +URL://machine.name/tmp/vimtest2b +URL:\\machine.name\vimtest2c +URL:\\machine.name\tmp\vimtest2d diff --git a/src/testdir/test20.in b/src/testdir/test20.in new file mode 100644 index 000000000..7201c75c2 --- /dev/null +++ b/src/testdir/test20.in @@ -0,0 +1,22 @@ +Tests Blockwise Visual when there are TABs before the text. +First test for undo working properly when executing commands from a register. +Also test this in an empty buffer. + +STARTTEST +:so tiny.vim +G0"ay$k@au +:new +@auY:quit! +GP +/start here$ +jjlld +:/here$/,$-1w! test.out +:qa! +ENDTEST + +test text test tex start here + some text + test text +test text + +OxjAykdd diff --git a/src/testdir/test20.ok b/src/testdir/test20.ok new file mode 100644 index 000000000..2604e7cc8 --- /dev/null +++ b/src/testdir/test20.ok @@ -0,0 +1,6 @@ +test text test tex rt here + somext + tesext +test text + + diff --git a/src/testdir/test21.in b/src/testdir/test21.in new file mode 100644 index 000000000..491b9f740 --- /dev/null +++ b/src/testdir/test21.in @@ -0,0 +1,19 @@ +Tests for [ CTRL-I with a count and CTRL-W CTRL-I with a count + +STARTTEST +:so small.vim +/start +6[ :.w! test.out +?start here +6 :.w >>test.out +:qa! +ENDTEST + +#include test21.in + +/* test text test tex start here + some text + test text + start OK if found this line + start found wrong line +test text diff --git a/src/testdir/test21.ok b/src/testdir/test21.ok new file mode 100644 index 000000000..d9f1b759c --- /dev/null +++ b/src/testdir/test21.ok @@ -0,0 +1,2 @@ + start OK if found this line + start OK if found this line diff --git a/src/testdir/test22.in b/src/testdir/test22.in new file mode 100644 index 000000000..f5cc046c6 --- /dev/null +++ b/src/testdir/test22.in @@ -0,0 +1,13 @@ +Tests for file with some lines ending in CTRL-M, some not
+
+STARTTEST +:set ta tx +:e! +:$-3,$w! test.out +:qa! +ENDTEST + +this lines ends in a
+this one doesn't +this one does
+and the last one doesn't diff --git a/src/testdir/test22.ok b/src/testdir/test22.ok new file mode 100644 index 000000000..38ff89eaf --- /dev/null +++ b/src/testdir/test22.ok @@ -0,0 +1,4 @@ +this lines ends in a
+this one doesn't +this one does
+and the last one doesn't diff --git a/src/testdir/test23.in b/src/testdir/test23.in new file mode 100644 index 000000000..0e0e60553 --- /dev/null +++ b/src/testdir/test23.in @@ -0,0 +1,15 @@ +Tests for complicated + argument to :edit command + +STARTTEST +:$-1w! Xfile1 +:$w! Xfile2 +:edit +1|s/|/PIPE/|w Xfile1| e Xfile2|1 | s/\//SLASH/|w +:w! test.out +:e Xfile1 +:w >> test.out +:qa! +ENDTEST + +The result should be in Xfile1: "fooPIPEbar", in Xfile2: "fooSLASHbar" +foo|bar +foo/bar diff --git a/src/testdir/test23.ok b/src/testdir/test23.ok new file mode 100644 index 000000000..f1930abad --- /dev/null +++ b/src/testdir/test23.ok @@ -0,0 +1,2 @@ +fooSLASHbar +fooPIPEbar diff --git a/src/testdir/test24.in b/src/testdir/test24.in new file mode 100644 index 000000000..84721d992 --- /dev/null +++ b/src/testdir/test24.in @@ -0,0 +1,21 @@ +Tests for regexp with backslash and other special characters inside [] + +STARTTEST +:set nocompatible viminfo+=nviminfo +/[\x] +x/[\t\]] +x/[]y] +x/[\]] +x/[y^] +x/[$y] +x:?start?,$w! test.out +:qa! +ENDTEST + +start +test \text test text +test text test text +test text ]test text +test ]text test text +test text te^st text +test te$xt test text diff --git a/src/testdir/test24.ok b/src/testdir/test24.ok new file mode 100644 index 000000000..896b50ae5 --- /dev/null +++ b/src/testdir/test24.ok @@ -0,0 +1,7 @@ +start +test text test text +test text test text +test text test text +test text test text +test text test text +test text test text diff --git a/src/testdir/test25.in b/src/testdir/test25.in new file mode 100644 index 000000000..4139865da --- /dev/null +++ b/src/testdir/test25.in @@ -0,0 +1,31 @@ +Test for jumping to a tag with 'hidden' set, with symbolic link in path of tag. +This only works for Unix, because of the symbolic link. + +STARTTEST +:so small.vim +:set hidden +:" Create a link from test25.dir to the current directory. +:!rm -f test25.dir +:!ln -s . test25.dir +:" Create tags.text, with the current directory name inserted. +/tags line +:r !pwd +d$/test +hP:.w! tags.test +:" Try jumping to a tag in the current file, but with a path that contains a +:" symbolic link. When wrong, this will give the ATTENTION message. The next +:" space will then be eaten by hit-return, instead of moving the cursor to 'd'. +:set tags=tags.test +G x:.w! test.out +:!rm -f test25.dir tags.test +:qa! +ENDTEST + +tags line: +SECTION_OFF /test25.dir/test25.in /^#define SECTION_OFF 3$/ + +/*tx.c*/ +#define SECTION_OFF 3 +#define NUM_SECTIONS 3 + +SECTION_OFF diff --git a/src/testdir/test25.ok b/src/testdir/test25.ok new file mode 100644 index 000000000..08fc070b7 --- /dev/null +++ b/src/testdir/test25.ok @@ -0,0 +1 @@ +#efine SECTION_OFF 3 diff --git a/src/testdir/test26.in b/src/testdir/test26.in new file mode 100644 index 000000000..df572c897 --- /dev/null +++ b/src/testdir/test26.in @@ -0,0 +1,43 @@ +Test for :execute, :while and :if + +STARTTEST +:so small.vim +mt:let i = 0 +:while i < 12 +: let i = i + 1 +: if has("ebcdic") +: execute "normal o" . i . "\047" +: else +: execute "normal o" . i . "\033" +: endif +: if i % 2 +: normal Ax +: if i == 9 +: break +: endif +: if i == 5 +: continue +: else +: let j = 9 +: while j > 0 +: if has("ebcdic") +: execute "normal" j . "a" . j . "\x27" +: else +: execute "normal" j . "a" . j . "\x1b" +: endif +: let j = j - 1 +: endwhile +: endif +: endif +: if i == 9 +: if has("ebcdic") +: execute "normal Az\047" +: else +: execute "normal Az\033" +: endif +: endif +:endwhile +:'t,$w! test.out +:qa! +ENDTEST + diff --git a/src/testdir/test26.ok b/src/testdir/test26.ok new file mode 100644 index 000000000..bc4476118 --- /dev/null +++ b/src/testdir/test26.ok @@ -0,0 +1,10 @@ + +1x999999999888888887777777666666555554444333221 +2 +3x999999999888888887777777666666555554444333221 +4 +5x +6 +7x999999999888888887777777666666555554444333221 +8 +9x diff --git a/src/testdir/test27.in b/src/testdir/test27.in new file mode 100644 index 000000000..2df16d9ef --- /dev/null +++ b/src/testdir/test27.in @@ -0,0 +1,20 @@ +Test for expanding file names + +STARTTEST +:!mkdir Xdir1 +:!mkdir Xdir2 +:!mkdir Xdir3 +:cd Xdir3 +:!mkdir Xdir4 +:cd .. +:w Xdir1/file +:w Xdir3/Xdir4/file +:n Xdir?/*/file +Go%:.w! test.out +:n! Xdir?/*/nofile +Go%:.w >>test.out +:e! xx +:!rm -rf Xdir1 Xdir2 Xdir3 +:qa! +ENDTEST + diff --git a/src/testdir/test27.ok b/src/testdir/test27.ok new file mode 100644 index 000000000..c35f2438a --- /dev/null +++ b/src/testdir/test27.ok @@ -0,0 +1,2 @@ +Xdir3/Xdir4/file +Xdir?/*/nofile diff --git a/src/testdir/test28.in b/src/testdir/test28.in Binary files differnew file mode 100644 index 000000000..5542c9266 --- /dev/null +++ b/src/testdir/test28.in diff --git a/src/testdir/test28.ok b/src/testdir/test28.ok new file mode 100644 index 000000000..911d85465 --- /dev/null +++ b/src/testdir/test28.ok @@ -0,0 +1,2 @@ +sd +map __2 asdsecondsdsd0map __5 asd0fifth diff --git a/src/testdir/test29.in b/src/testdir/test29.in new file mode 100644 index 000000000..de93ccc22 --- /dev/null +++ b/src/testdir/test29.in @@ -0,0 +1,67 @@ +Test for joining lines with 'joinspaces' set or not + +STARTTEST +:set nojoinspaces +/firstline/ +jJjJjJjJjJjJjJjJjJjJjJjJjJjJ:set joinspaces +jJjJjJjJjJjJjJjJjJjJjJjJjJjJ:?firstline?+1,$w! test.out +:qa! +ENDTEST + +firstline +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf. +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf +asdfasdf +asdf diff --git a/src/testdir/test29.ok b/src/testdir/test29.ok new file mode 100644 index 000000000..076f77c98 --- /dev/null +++ b/src/testdir/test29.ok @@ -0,0 +1,28 @@ +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf. asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf +asdfasdf asdf diff --git a/src/testdir/test3.in b/src/testdir/test3.in new file mode 100644 index 000000000..cd725bffb --- /dev/null +++ b/src/testdir/test3.in @@ -0,0 +1,1217 @@ +/* vim: set cin ts=4 sw=4 : */ + +Test for 'cindent' + +STARTTEST +:so small.vim +:set nocompatible viminfo+=nviminfo +:edit " read modeline +/start of AUTO +=/end of AUTO +ENDTEST + +/* start of AUTO matically checked */ +{ + if (test) + cmd1; + cmd2; +} + +{ + if (test) + cmd1; + else + cmd2; +} + +{ + if (test) + { + cmd1; + cmd2; + } +} + +{ + if (test) + { + cmd1; + else + } +} + +{ + while (this) + if (test) + cmd1; + cmd2; +} + +{ + while (this) + if (test) + cmd1; + else + cmd2; +} + +{ + if (test) + { + cmd; + } + + if (test) + cmd; +} + +{ + if (test) { + cmd; + } + + if (test) cmd; +} + +{ + cmd1; + for (blah) + while (this) + if (test) + cmd2; + cmd3; +} + +{ + cmd1; + for (blah) + while (this) + if (test) + cmd2; + cmd3; + + if (test) + { + cmd1; + cmd2; + cmd3; + } +} + + +/* Test for 'cindent' do/while mixed with if/else: */ + +{ + do + if (asdf) + asdfasd; + while (cond); + + do + if (asdf) + while (asdf) + asdf; + while (asdf); +} + +/* Test for 'cindent' with two ) on a continuation line */ +{ + if (asdfasdf;asldkfj asdlkfj as;ldkfj sal;d + aal;sdkjf ( ;asldfkja;sldfk + al;sdjfka ;slkdf ) sa;ldkjfsa dlk;) + line up here; +} + + +/* C++ tests: */ + +// foo() these three lines should remain in column 0 +// { +// } + +/* Test for continuation and unterminated lines: */ +{ + i = 99 + 14325 + + 21345 + + 21345 + + 21345 + ( 21345 + + 21345) + + 2345 + + 1234; + c = 1; +} + +/* + testje for indent with empty line + + here */ + +{ + if (testing && + not a joke || + line up here) + hay; + if (testing && + (not a joke || testing + )line up here) + hay; + if (testing && + (not a joke || testing + line up here)) + hay; +} + + +{ + switch (c) + { + case xx: + do + if (asdf) + do + asdfasdf; + while (asdf); + else + asdfasdf; + while (cond); + case yy: + case xx: + case zz: + testing; + } +} + +{ + if (cond) { + foo; + } + else + { + bar; + } +} + +{ + if (alskdfj ;alsdkfjal;skdjf (;sadlkfsa ;dlkf j;alksdfj ;alskdjf + alsdkfj (asldk;fj + awith cino=(0 ;lf this one goes to below the paren with == + ;laksjfd ;lsakdjf ;alskdf asd) + asdfasdf;))) + asdfasdf; +} + + int +func(a, b) + int a; + int c; +{ + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3) + ) +} + +{ + while (asd) + { + if (asdf) + if (test) + if (that) + { + if (asdf) + do + cdasd; + while (as + df); + } + else + if (asdf) + asdf; + else + asdf; + asdf; + } +} + +{ + s = "/*"; b = ';' + s = "/*"; b = ';'; + a = b; +} + +{ + switch (a) + { + case a: + switch (t) + { + case 1: + cmd; + break; + case 2: + cmd; + break; + } + cmd; + break; + case b: + { + int i; + cmd; + } + break; + case c: { + int i; + cmd; + } + case d: if (cond && + test) { /* this line doesn't work right */ + int i; + cmd; + } + break; + } +} + +{ + if (!(vim_strchr(p_cpo, CPO_BUFOPTGLOB) != NULL && entering) && + (bp_to->b_p_initialized || + (!entering && vim_strchr(p_cpo, CPO_BUFOPT) != NULL))) + return; +label : + asdf = asdf ? + asdf : asdf; + asdf = asdf ? + asdf: asdf; +} + +/* Special Comments : This function has the added complexity (compared */ +/* : to addtolist) of having to check for a detail */ +/* : texture and add that to the list first. */ + +char *(array[100]) = { + "testje", + "foo", + "bar", +} + +enum soppie +{ + yes = 0, + no, + maybe +}; + +typedef enum soppie +{ + yes = 0, + no, + maybe +}; + +{ + int a, + b; +} + +{ + struct Type + { + int i; + char *str; + } var[] = + { + 0, "zero", + 1, "one", + 2, "two", + 3, "three" + }; + + float matrix[3][3] = + { + { + 0, + 1, + 2 + }, + { + 3, + 4, + 5 + }, + { + 6, + 7, + 8 + } + }; +} + +{ + /* blah ( blah */ + /* where does this go? */ + + /* blah ( blah */ + cmd; + + func(arg1, + /* comment */ + arg2); + a; + { + b; + { + c; /* Hey, NOW it indents?! */ + } + } + + { + func(arg1, + arg2, + arg3); + /* Hey, what am I doing here? Is this coz of the ","? */ + } +} + +main () +{ + if (cond) + { + a = b; + } + if (cond) { + a = c; + } + if (cond) + a = d; + return; +} + +{ + case 2: if (asdf && + asdfasdf) + aasdf; + a = 9; + case 3: if (asdf) + aasdf; + a = 9; + case 4: x = 1; + y = 2; + +label: if (asdf) + here; + +label: if (asdf && + asdfasdf) + { + } + +label: if (asdf && + asdfasdf) { + there; + } + +label: if (asdf && + asdfasdf) + there; +} + +{ + /* + hello with ":set comments= cino=c5" + */ + + /* + hello with ":set comments= cino=" + */ +} + + +{ + if (a < b) { + a = a + 1; + } else + a = a + 2; + + if (a) + do { + testing; + } while (asdfasdf); + a = b + 1; + asdfasdf +} + +class bob +{ + int foo() {return 1;} + int bar; +} + +main() +{ +while(1) +if (foo) +{ +bar; +} +else { +asdf; +} +misplacedline; +} + +{ + if (clipboard.state == SELECT_DONE + && ((row == clipboard.start.lnum + && col >= clipboard.start.col) + || row > clipboard.start.lnum)) +} + +{ +if (1) {i += 4;} +where_am_i; +return 0; +} + +{ +{ +} // sdf(asdf +if (asdf) +asd; +} + +{ +label1: +label2: +} + +{ +int fooRet = foo(pBar1, false /*fKB*/, + true /*fPTB*/, 3 /*nT*/, false /*fDF*/); +f() { +for ( i = 0; + i < m; + /* c */ i++ ) { +a = b; +} +} +} + +{ + f1(/*comment*/); + f2(); +} + +{ +do { +if (foo) { +} else +; +} while (foo); +foo(); // was wrong +} + +int x; // no extra indent because of the ; +void func() +{ +} + +char *tab[] = {"aaa", + "};", /* }; */ NULL} + int indented; +{} + +char *a[] = {"aaa", "bbb", + "ccc", NULL}; +// here + +char *tab[] = {"aaa", + "xx", /* xx */}; /* asdf */ +int not_indented; + +{ + do { + switch (bla) + { + case 1: if (foo) + bar; + } + } while (boo); + wrong; +} + +int foo, + bar; +int foo; + +#if defined(foo) \ + && defined(bar) +char * xx = "asdf\ + foo\ + bor"; +int x; + +char *foo = "asdf\ + asdf\ + asdf", + *bar; + +void f() +{ +#if defined(foo) \ + && defined(bar) +char *foo = "asdf\ + asdf\ + asdf", + *bar; + { + int i; +char *foo = "asdf\ + asdf\ + asdf", + *bar; + } +#endif +} +#endif + +int y; // comment + // comment + + // comment + +{ + Constructor(int a, + int b ) : BaseClass(a) + { + } +} + +void foo() +{ + char one, + two; + struct bla piet, + jan; + enum foo kees, + jannie; + static unsigned sdf, + krap; + unsigned int piet, + jan; + int + kees, + jan; +} + +{ + t(int f, + int d); // ) + d(); +} + +Constructor::Constructor(int a, + int b + ) : + BaseClass(a, + b, + c), + mMember(b), +{ +} + +Constructor::Constructor(int a, + int b ) : + BaseClass(a) +{ +} + +Constructor::Constructor(int a, + int b ) /*x*/ : /*x*/ BaseClass(a), + member(b) +{ +} + +class CAbc : + public BaseClass1, + protected BaseClass2 +{ + int Test() { return FALSE; } + int Test1() { return TRUE; } + + CAbc(int a, int b ) : + BaseClass(a) + { + switch(xxx) + { + case abc: + asdf(); + break; + + case 999: + baer(); + break; + } + } + +public: // <-- this was incoreectly indented before!! + void testfall(); +protected: + void testfall(); +}; + +class CAbc : public BaseClass1, + protected BaseClass2 +{ +}; + +static struct +{ + int a; + int b; +} variable[COUNT] = +{ + { + 123, + 456 + }, + { + 123, + 456 + } +}; + +static struct +{ + int a; + int b; +} variable[COUNT] = +{ + { 123, 456 }, + { 123, 456 } +}; + +void asdf() /* ind_maxparen may cause trouble here */ +{ + if ((0 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1)) break; +} + +/* end of AUTO */ + +STARTTEST +:set tw=0 wm=60 columns=80 noai fo=croq +/serious/e +a about life, the universe, and the rest +ENDTEST + +{ + +/* this is + * a real serious important big + * comment + */ + /* insert " about life, the universe, and the rest" after "serious" */ +} + +STARTTEST +:set nocin +/comments +joabout life/happens +jothere/below +oline/this +Ohello +ENDTEST + +{ + /* + * Testing for comments, without 'cin' set + */ + +/* +* what happens here? +*/ + + /* + the end of the comment, try inserting a line below */ + + /* how about + this one */ +} + +STARTTEST +:set cin +/vec2 +== +ENDTEST + +{ + var = this + that + vec[0] * vec[0] + + vec[1] * vec[1] + + vec2[2] * vec[2]; +} + +STARTTEST +:set cin +:set cino=}4 +/testing1 +k2==/testing2 +k2== +ENDTEST + +{ + asdf asdflkajds f; + if (tes & ting) { + asdf asdf asdf ; + asdfa sdf asdf; + } + testing1; + if (tes & ting) + { + asdf asdf asdf ; + asdfa sdf asdf; + } + testing2; +} + +STARTTEST +:set cin +:set cino=(0,)20 +/main +=][ +ENDTEST + +main ( int first_par, /* + * Comment for + * first par + */ + int second_par /* + * Comment for + * second par + */ + ) +{ + func( first_par, /* + * Comment for + * first par + */ + second_par /* + * Comment for + * second par + */ + ); + +} + +STARTTEST +:set cin +:set cino= +]]=][ +ENDTEST + +{ + do + { + if () + { + if () + asdf; + else + asdf; + } + } while (); + cmd; /* this should go under the } */ +} + +STARTTEST +]]=][ +ENDTEST + +void f() +{ + if ( k() ) { + l(); + + } else { /* Start (two words) end */ + m(); + } + + n(); +} + +STARTTEST +:set cino={s,e-s +]]=][ +ENDTEST + +void f() +{ + if ( k() ) + { + l(); + } else { /* Start (two words) end */ + m(); + } + n(); /* should be under the if () */ +} + +STARTTEST +:set cino={s,fs +]]=/ foo +ENDTEST + +void bar(void) +{ + static array[2][2] = + { + { 1, 2 }, + { 3, 4 }, + } + + while (a) + { + foo(&a); + } + + { + int a; + { + a = a + 1; + } + } + b = a; + } + +void func(void) + { + a = 1; + { + b = 2; + } + c = 3; + d = 4; + } +/* foo */ + +STARTTEST +:set cino= +/while +ohere +ENDTEST + +a() +{ + do { + a = a + + a; + } while ( a ); /* add text under this line */ + if ( a ) + a; +} + +STARTTEST +:set cino= com= +/comment +olabel2: b();
label3 /* post */:
/* pre */ label4:
f(/*com*/);
if (/*com*/)
cmd(); +ENDTEST + +a() +{ +label1: + /* hmm */ + // comment +} + +STARTTEST +:set comments& comments^=s:/*,m:**,ex:*/ +/simple +=5j +ENDTEST + +/* + * A simple comment + */ + +/* + ** A different comment + */ + +STARTTEST +:set cino=c0 +:set comments& comments-=s1:/* comments^=s0:/* +2kdd]]=][ +ENDTEST + +void f() +{ + + /********* + A comment. +*********/ +} + +STARTTEST +:set cino=c0,C1 +:set comments& comments-=s1:/* comments^=s0:/* +2kdd]]=][ +ENDTEST + +void f() +{ + + /********* + A comment. +*********/ +} + +STARTTEST +:set cino= +]]=][ +ENDTEST + +void f() +{ + c = c1 && + ( + c2 || + c3 + ) && c4; +} + +STARTTEST +:set cino=(s +2kdd]]=][ +ENDTEST + +void f() +{ + c = c1 && + ( + c2 || + c3 + ) && c4; +} + +STARTTEST +:set cino=(s,U1 +2kdd]]=][ +ENDTEST + +void f() +{ + c = c1 && + ( + c2 || + c3 + ) && c4; +} + +STARTTEST +:set cino=(0 +2kdd]]=][ +ENDTEST + +void f() +{ + if ( c1 + && ( c2 + || c3)) + foo; +} + +STARTTEST +:set cino=(0,w1 +2kdd]]=][ +ENDTEST + +void f() +{ + if ( c1 + && ( c2 + || c3)) + foo; +} + +STARTTEST +:set cino=(s +2kdd]]=][ +ENDTEST + +void f() +{ + c = c1 && ( + c2 || + c3 + ) && c4; + if ( + c1 && c2 + ) + foo; +} + +STARTTEST +:set cino=(s,m1 +2kdd]]=][ +ENDTEST + +void f() +{ + c = c1 && ( + c2 || + c3 + ) && c4; + if ( + c1 && c2 + ) + foo; +} + +STARTTEST +:set cino=b1 +2kdd]]=][ +ENDTEST + +void f() +{ + switch (x) + { + case 1: + a = b; + break; + default: + a = 0; + break; + } +} + +STARTTEST +:set cino=(0,W5 +2kdd]]=][ +ENDTEST + +void f() +{ + invokeme( + argu, + ment); + invokeme( + argu, + ment + ); + invokeme(argu, + ment + ); +} + +STARTTEST +:set cino=/6 +2kdd]]=][ +ENDTEST + +void f() +{ + statement; + // comment 1 + // comment 2 +} + +STARTTEST +:set cino= +2kdd]]/comment 1/+1 +== +ENDTEST + +void f() +{ + statement; + // comment 1 + // comment 2 +} + +STARTTEST +:set cino=g0 +2kdd]]=][ +ENDTEST + +class CAbc +{ + int Test() { return FALSE; } + +public: // comment + void testfall(); +protected: + void testfall(); +}; + +STARTTEST +:set cino=(0,W2s +2kdd]]=][ +ENDTEST + +{ + averylongfunctionnamelongfunctionnameaverylongfunctionname()->asd( + asdasdf, + func(asdf, + asdfadsf), + asdfasdf + ); + + /* those are ugly, but consequent */ + + func()->asd(asdasdf, + averylongfunctionname( + abc, + dec)->averylongfunctionname( + asdfadsf, + asdfasdf, + asdfasdf, + ), + func(asdfadf, + asdfasdf + ), + asdasdf + ); + + averylongfunctionnameaverylongfunctionnameavery()->asd(fasdf( + abc, + dec)->asdfasdfasdf( + asdfadsf, + asdfasdf, + asdfasdf, + ), + func(asdfadf, + asdfasdf), + asdasdf + ); +} + +STARTTEST +:g/^STARTTEST/.,/^ENDTEST/d +:1;/start of AUTO/,$wq! test.out +ENDTEST diff --git a/src/testdir/test3.ok b/src/testdir/test3.ok new file mode 100644 index 000000000..570f8f63d --- /dev/null +++ b/src/testdir/test3.ok @@ -0,0 +1,1090 @@ +/* start of AUTO matically checked */ +{ + if (test) + cmd1; + cmd2; +} + +{ + if (test) + cmd1; + else + cmd2; +} + +{ + if (test) + { + cmd1; + cmd2; + } +} + +{ + if (test) + { + cmd1; + else + } +} + +{ + while (this) + if (test) + cmd1; + cmd2; +} + +{ + while (this) + if (test) + cmd1; + else + cmd2; +} + +{ + if (test) + { + cmd; + } + + if (test) + cmd; +} + +{ + if (test) { + cmd; + } + + if (test) cmd; +} + +{ + cmd1; + for (blah) + while (this) + if (test) + cmd2; + cmd3; +} + +{ + cmd1; + for (blah) + while (this) + if (test) + cmd2; + cmd3; + + if (test) + { + cmd1; + cmd2; + cmd3; + } +} + + +/* Test for 'cindent' do/while mixed with if/else: */ + +{ + do + if (asdf) + asdfasd; + while (cond); + + do + if (asdf) + while (asdf) + asdf; + while (asdf); +} + +/* Test for 'cindent' with two ) on a continuation line */ +{ + if (asdfasdf;asldkfj asdlkfj as;ldkfj sal;d + aal;sdkjf ( ;asldfkja;sldfk + al;sdjfka ;slkdf ) sa;ldkjfsa dlk;) + line up here; +} + + +/* C++ tests: */ + +// foo() these three lines should remain in column 0 +// { +// } + +/* Test for continuation and unterminated lines: */ +{ + i = 99 + 14325 + + 21345 + + 21345 + + 21345 + ( 21345 + + 21345) + + 2345 + + 1234; + c = 1; +} + +/* + testje for indent with empty line + + here */ + +{ + if (testing && + not a joke || + line up here) + hay; + if (testing && + (not a joke || testing + )line up here) + hay; + if (testing && + (not a joke || testing + line up here)) + hay; +} + + +{ + switch (c) + { + case xx: + do + if (asdf) + do + asdfasdf; + while (asdf); + else + asdfasdf; + while (cond); + case yy: + case xx: + case zz: + testing; + } +} + +{ + if (cond) { + foo; + } + else + { + bar; + } +} + +{ + if (alskdfj ;alsdkfjal;skdjf (;sadlkfsa ;dlkf j;alksdfj ;alskdjf + alsdkfj (asldk;fj + awith cino=(0 ;lf this one goes to below the paren with == + ;laksjfd ;lsakdjf ;alskdf asd) + asdfasdf;))) + asdfasdf; +} + + int +func(a, b) + int a; + int c; +{ + if (c1 && (c2 || + c3)) + foo; + if (c1 && + (c2 || c3) + ) +} + +{ + while (asd) + { + if (asdf) + if (test) + if (that) + { + if (asdf) + do + cdasd; + while (as + df); + } + else + if (asdf) + asdf; + else + asdf; + asdf; + } +} + +{ + s = "/*"; b = ';' + s = "/*"; b = ';'; + a = b; +} + +{ + switch (a) + { + case a: + switch (t) + { + case 1: + cmd; + break; + case 2: + cmd; + break; + } + cmd; + break; + case b: + { + int i; + cmd; + } + break; + case c: { + int i; + cmd; + } + case d: if (cond && + test) { /* this line doesn't work right */ + int i; + cmd; + } + break; + } +} + +{ + if (!(vim_strchr(p_cpo, CPO_BUFOPTGLOB) != NULL && entering) && + (bp_to->b_p_initialized || + (!entering && vim_strchr(p_cpo, CPO_BUFOPT) != NULL))) + return; +label : + asdf = asdf ? + asdf : asdf; + asdf = asdf ? + asdf: asdf; +} + +/* Special Comments : This function has the added complexity (compared */ +/* : to addtolist) of having to check for a detail */ +/* : texture and add that to the list first. */ + +char *(array[100]) = { + "testje", + "foo", + "bar", +} + +enum soppie +{ + yes = 0, + no, + maybe +}; + +typedef enum soppie +{ + yes = 0, + no, + maybe +}; + +{ + int a, + b; +} + +{ + struct Type + { + int i; + char *str; + } var[] = + { + 0, "zero", + 1, "one", + 2, "two", + 3, "three" + }; + + float matrix[3][3] = + { + { + 0, + 1, + 2 + }, + { + 3, + 4, + 5 + }, + { + 6, + 7, + 8 + } + }; +} + +{ + /* blah ( blah */ + /* where does this go? */ + + /* blah ( blah */ + cmd; + + func(arg1, + /* comment */ + arg2); + a; + { + b; + { + c; /* Hey, NOW it indents?! */ + } + } + + { + func(arg1, + arg2, + arg3); + /* Hey, what am I doing here? Is this coz of the ","? */ + } +} + +main () +{ + if (cond) + { + a = b; + } + if (cond) { + a = c; + } + if (cond) + a = d; + return; +} + +{ + case 2: if (asdf && + asdfasdf) + aasdf; + a = 9; + case 3: if (asdf) + aasdf; + a = 9; + case 4: x = 1; + y = 2; + +label: if (asdf) + here; + +label: if (asdf && + asdfasdf) + { + } + +label: if (asdf && + asdfasdf) { + there; + } + +label: if (asdf && + asdfasdf) + there; +} + +{ + /* + hello with ":set comments= cino=c5" + */ + + /* + hello with ":set comments= cino=" + */ +} + + +{ + if (a < b) { + a = a + 1; + } else + a = a + 2; + + if (a) + do { + testing; + } while (asdfasdf); + a = b + 1; + asdfasdf +} + +class bob +{ + int foo() {return 1;} + int bar; +} + +main() +{ + while(1) + if (foo) + { + bar; + } + else { + asdf; + } + misplacedline; +} + +{ + if (clipboard.state == SELECT_DONE + && ((row == clipboard.start.lnum + && col >= clipboard.start.col) + || row > clipboard.start.lnum)) +} + +{ + if (1) {i += 4;} + where_am_i; + return 0; +} + +{ + { + } // sdf(asdf + if (asdf) + asd; +} + +{ +label1: +label2: +} + +{ + int fooRet = foo(pBar1, false /*fKB*/, + true /*fPTB*/, 3 /*nT*/, false /*fDF*/); + f() { + for ( i = 0; + i < m; + /* c */ i++ ) { + a = b; + } + } +} + +{ + f1(/*comment*/); + f2(); +} + +{ + do { + if (foo) { + } else + ; + } while (foo); + foo(); // was wrong +} + +int x; // no extra indent because of the ; +void func() +{ +} + +char *tab[] = {"aaa", + "};", /* }; */ NULL} + int indented; +{} + +char *a[] = {"aaa", "bbb", + "ccc", NULL}; +// here + +char *tab[] = {"aaa", + "xx", /* xx */}; /* asdf */ +int not_indented; + +{ + do { + switch (bla) + { + case 1: if (foo) + bar; + } + } while (boo); + wrong; +} + +int foo, + bar; +int foo; + +#if defined(foo) \ + && defined(bar) +char * xx = "asdf\ + foo\ + bor"; +int x; + +char *foo = "asdf\ + asdf\ + asdf", + *bar; + +void f() +{ +#if defined(foo) \ + && defined(bar) + char *foo = "asdf\ + asdf\ + asdf", + *bar; + { + int i; + char *foo = "asdf\ + asdf\ + asdf", + *bar; + } +#endif +} +#endif + +int y; // comment +// comment + +// comment + +{ + Constructor(int a, + int b ) : BaseClass(a) + { + } +} + +void foo() +{ + char one, + two; + struct bla piet, + jan; + enum foo kees, + jannie; + static unsigned sdf, + krap; + unsigned int piet, + jan; + int + kees, + jan; +} + +{ + t(int f, + int d); // ) + d(); +} + +Constructor::Constructor(int a, + int b + ) : + BaseClass(a, + b, + c), + mMember(b), +{ +} + +Constructor::Constructor(int a, + int b ) : + BaseClass(a) +{ +} + +Constructor::Constructor(int a, + int b ) /*x*/ : /*x*/ BaseClass(a), + member(b) +{ +} + +class CAbc : + public BaseClass1, + protected BaseClass2 +{ + int Test() { return FALSE; } + int Test1() { return TRUE; } + + CAbc(int a, int b ) : + BaseClass(a) + { + switch(xxx) + { + case abc: + asdf(); + break; + + case 999: + baer(); + break; + } + } + + public: // <-- this was incoreectly indented before!! + void testfall(); + protected: + void testfall(); +}; + +class CAbc : public BaseClass1, + protected BaseClass2 +{ +}; + +static struct +{ + int a; + int b; +} variable[COUNT] = +{ + { + 123, + 456 + }, + { + 123, + 456 + } +}; + +static struct +{ + int a; + int b; +} variable[COUNT] = +{ + { 123, 456 }, + { 123, 456 } +}; + +void asdf() /* ind_maxparen may cause trouble here */ +{ + if ((0 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1 + && 1)) break; +} + +/* end of AUTO */ + + +{ + +/* this is + * a real serious + * about life, the + * universe, and the + * rest important big + * comment + */ + /* insert " about life, the universe, and the rest" after "serious" */ +} + + +{ + /* + * Testing for comments, without 'cin' set + */ +about life + +/* +* what happens here? +*/ +there + + /* + the end of the comment, try inserting a line below */ +line + + /* how about +hello + this one */ +} + + +{ + var = this + that + vec[0] * vec[0] + + vec[1] * vec[1] + + vec2[2] * vec[2]; +} + + +{ + asdf asdflkajds f; + if (tes & ting) { + asdf asdf asdf ; + asdfa sdf asdf; + } + testing1; + if (tes & ting) + { + asdf asdf asdf ; + asdfa sdf asdf; + } + testing2; +} + + +main ( int first_par, /* + * Comment for + * first par + */ + int second_par /* + * Comment for + * second par + */ + ) +{ + func( first_par, /* + * Comment for + * first par + */ + second_par /* + * Comment for + * second par + */ + ); + +} + + +{ + do + { + if () + { + if () + asdf; + else + asdf; + } + } while (); + cmd; /* this should go under the } */ +} + + +void f() +{ + if ( k() ) { + l(); + + } else { /* Start (two words) end */ + m(); + } + + n(); +} + + +void f() + { + if ( k() ) + { + l(); + } else { /* Start (two words) end */ + m(); + } + n(); /* should be under the if () */ +} + + +void bar(void) + { + static array[2][2] = + { + { 1, 2 }, + { 3, 4 }, + } + + while (a) + { + foo(&a); + } + + { + int a; + { + a = a + 1; + } + } + b = a; + } + +void func(void) + { + a = 1; + { + b = 2; + } + c = 3; + d = 4; + } +/* foo */ + + +a() +{ + do { + a = a + + a; + } while ( a ); /* add text under this line */ + here + if ( a ) + a; +} + + +a() +{ +label1: + /* hmm */ + // comment +label2: b(); +label3 /* post */: +/* pre */ label4: + f(/*com*/); + if (/*com*/) + cmd(); +} + + +/* + * A simple comment + */ + +/* +** A different comment +*/ + + +void f() +{ + + /********* + A comment. + *********/ +} + + +void f() +{ + + /********* + A comment. + *********/ +} + + +void f() +{ + c = c1 && + ( + c2 || + c3 + ) && c4; +} + + +void f() +{ + c = c1 && + ( + c2 || + c3 + ) && c4; +} + + +void f() +{ + c = c1 && + ( + c2 || + c3 + ) && c4; +} + + +void f() +{ + if ( c1 + && ( c2 + || c3)) + foo; +} + + +void f() +{ + if ( c1 + && ( c2 + || c3)) + foo; +} + + +void f() +{ + c = c1 && ( + c2 || + c3 + ) && c4; + if ( + c1 && c2 + ) + foo; +} + + +void f() +{ + c = c1 && ( + c2 || + c3 + ) && c4; + if ( + c1 && c2 + ) + foo; +} + + +void f() +{ + switch (x) + { + case 1: + a = b; + break; + default: + a = 0; + break; + } +} + + +void f() +{ + invokeme( + argu, + ment); + invokeme( + argu, + ment + ); + invokeme(argu, + ment + ); +} + + +void f() +{ + statement; + // comment 1 + // comment 2 +} + + +void f() +{ + statement; + // comment 1 + // comment 2 +} + + +class CAbc +{ + int Test() { return FALSE; } + +public: // comment + void testfall(); +protected: + void testfall(); +}; + + +{ + averylongfunctionnamelongfunctionnameaverylongfunctionname()->asd( + asdasdf, + func(asdf, + asdfadsf), + asdfasdf + ); + + /* those are ugly, but consequent */ + + func()->asd(asdasdf, + averylongfunctionname( + abc, + dec)->averylongfunctionname( + asdfadsf, + asdfasdf, + asdfasdf, + ), + func(asdfadf, + asdfasdf + ), + asdasdf + ); + + averylongfunctionnameaverylongfunctionnameavery()->asd(fasdf( + abc, + dec)->asdfasdfasdf( + asdfadsf, + asdfasdf, + asdfasdf, + ), + func(asdfadf, + asdfasdf), + asdasdf + ); +} + diff --git a/src/testdir/test30.in b/src/testdir/test30.in new file mode 100644 index 000000000..4e92741c8 --- /dev/null +++ b/src/testdir/test30.in @@ -0,0 +1,183 @@ +Test for a lot of variations of the 'fileformats' option + +STARTTEST +:so small.vim +:" first write three test files, one in each format +:set fileformat=unix +:set fileformats= +:/^1/w! XX1 +:/^2/w! XX2 +:/^3/w! XX3 +:/^4/w! XX4 +:/^5/w! XX5 +:/^6/w! XX6 +:/^7/w! XX7 +:/^8/w! XX8 +:/^9/w! XX9 +:/^10/w! XX10 +:/^unix/;/eof/-1w! XXUnix +:/^dos/;/eof/-1w! XXDos +:set bin noeol +:$w! XXMac +:set nobin eol +:bwipe XXUnix XXDos XXMac +:" create mixed format files +:!cat XXUnix XXDos >XXUxDs +:!cat XXUnix XXMac >XXUxMac +:!cat XXDos XXMac >XXDosMac +:!cat XXUnix XXDos XXMac >XXUxDsMc +:" +:" try reading and writing with 'fileformats' empty +:set fileformat=unix +:e! XXUnix +:w! test.out +:e! XXDos +:w! XXtt +:!cat XXtt >>test.out +:e! XXMac +:w! XXtt +:!cat XXtt >>test.out +:!cat XX1 >>test.out +:bwipe XXUnix XXDos XXMac +:set fileformat=dos +:e! XXUnix +:w! XXtt +:!cat XXtt >>test.out +:e! XXDos +:w! XXtt +:!cat XXtt >>test.out +:e! XXMac +:w! XXtt +:!cat XXtt >>test.out +:!cat XX2 >>test.out +:bwipe XXUnix XXDos XXMac +:set fileformat=mac +:e! XXUnix +:w! XXtt +:!cat XXtt >>test.out +:e! XXDos +:w! XXtt +:!cat XXtt >>test.out +:e! XXMac +:w! XXtt +:!cat XXtt >>test.out +:!cat XX3 >>test.out +:bwipe XXUnix XXDos XXMac +:" +:" try reading and writing with 'fileformats' set to one format +:set fileformats=unix +:e! XXUxDsMc +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXUxDsMc +:set fileformats=dos +:e! XXUxDsMc +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXUxDsMc +:set fileformats=mac +:e! XXUxDsMc +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXUxDsMc +:!cat XX4 >>test.out +:" +:" try reading and writing with 'fileformats' set to two formats +:set fileformats=unix,dos +:e! XXUxDsMc +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXUxDsMc +:e! XXUxMac +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXUxMac +:e! XXDosMac +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXDosMac +:!cat XX5 >>test.out +:set fileformats=unix,mac +:e! XXUxDs +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXUxDs +:e! XXUxDsMc +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXUxDsMc +:e! XXDosMac +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXDosMac +:!cat XX6 >>test.out +:set fileformats=dos,mac +:e! XXUxDs +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXUxDs +:e! XXUxMac +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXUxMac +:e! XXUxDsMc +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXUxDsMc +:!cat XX7 >>test.out +:" +:" try reading and writing with 'fileformats' set to three formats +:set fileformats=unix,dos,mac +:e! XXUxDsMc +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXUxDsMc +:!cat XX8 >>test.out +:set fileformats=mac,dos,unix +:e! XXUxDsMc +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXUxDsMc +:!cat XX9 >>test.out +:" try with 'binary' set +:set fileformats=mac,unix,dos +:set binary +:e! XXUxDsMc +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXUxDsMc +:set fileformats=mac +:e! XXUxDsMc +:w! XXtt +:!cat XXtt >>test.out +:bwipe XXUxDsMc +:set fileformats=dos +:e! XXUxDsMc +:w! XXtt +:!cat XXtt >>test.out +:!cat XX10 >>test.out +:" add a newline at the end +:!cat XXUnix >>test.out +:qa! +ENDTEST + +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 + +unix +unix +eof + +dos
+dos
+eof + +mac
mac
diff --git a/src/testdir/test30.ok b/src/testdir/test30.ok new file mode 100644 index 000000000..c294483bd --- /dev/null +++ b/src/testdir/test30.ok @@ -0,0 +1,96 @@ +unix +unix +dos
+dos
+mac
mac
+1 +unix
+unix
+dos
+dos
+mac
mac
+2 +unix +unix +
dos
+dos
+
mac
mac
3 +unix +unix +dos
+dos
+mac
mac
+unix
+unix
+dos
+dos
+mac
mac
+unix +unix +dos
+dos
+mac
mac
4 +unix +unix +dos
+dos
+mac
mac
+unix +unix +mac
mac
+dos
+dos
+mac
mac
+5 +unix +unix +dos
+dos
+unix +unix +dos
+dos
+mac
mac
+dos
+dos
+mac
mac
6 +unix
+unix
+dos
+dos
+unix
+unix
+mac
mac
+unix
+unix
+dos
+dos
+mac
mac
+7 +unix +unix +dos
+dos
+mac
mac
+8 +unix +unix +dos
+dos
+mac
mac
+9 +unix +unix +dos
+dos
+mac
mac
unix +unix +dos
+dos
+mac
mac
unix +unix +dos
+dos
+mac
mac
10 +unix +unix diff --git a/src/testdir/test31.in b/src/testdir/test31.in new file mode 100644 index 000000000..cd4d08e81 --- /dev/null +++ b/src/testdir/test31.in @@ -0,0 +1,68 @@ +Test for commands that close windows and/or buffers: +:quit +:close +:hide +:only +:sall +:all +:ball +:buf +:edit + +STARTTEST +:so tiny.vim +GA 1:$w! Xtest1 +$r2:$w! Xtest2 +$r3:$w! Xtest3 +:n! Xtest1 Xtest2 +A 1:set hidden +:" test for working :n when hidden set; write "testtext 2" +:n +:w! test.out +:" test for failing :rew when hidden not set; write "testtext 2 2" +:set nohidden +A 2:rew +:w >>test.out +:" test for working :rew when hidden set; write "testtext 1 1" +:set hidden +:rew +:w >>test.out +:" test for :all keeping a buffer when it's modified; write "testtext 1 1 1" +:set nohidden +A 1:sp +:n Xtest2 Xtest3 +:all +:w >>test.out +:" test abandoning changed buffer, should be unloaded even when 'hidden' set +:" write "testtext 2 2" twice +:set hidden +A 1:q! +:w >>test.out +:unhide +:w >>test.out +:" test ":hide" hides anyway when 'hidden' not set; write "testtext 3" +:set nohidden +A 2:hide +:w >>test.out +:" test ":edit" failing in modified buffer when 'hidden' not set +:" write "testtext 3 3" +A 3:e Xtest1 +:w >>test.out +:" test ":edit" working in modified buffer when 'hidden' set; write "testtext 1" +:set hidden +:e Xtest1 +:w >>test.out +:" test ":close" not hiding when 'hidden' not set in modified buffer; +:" write "testtext 3 3 3" +:sp Xtest3 +:set nohidden +A 3:close +:w >>test.out +:" test ":close!" does hide when 'hidden' not set in modified buffer; +:" write "testtext 1" +A 3:close! +:w >>test.out +:qa! +ENDTEST + +testtext diff --git a/src/testdir/test31.ok b/src/testdir/test31.ok new file mode 100644 index 000000000..3311ad5df --- /dev/null +++ b/src/testdir/test31.ok @@ -0,0 +1,11 @@ +testtext 2 +testtext 2 2 +testtext 1 1 +testtext 1 1 1 +testtext 2 2 +testtext 2 2 +testtext 3 +testtext 3 3 +testtext 1 +testtext 3 3 3 +testtext 1 diff --git a/src/testdir/test32.in b/src/testdir/test32.in new file mode 100644 index 000000000..0d5405184 --- /dev/null +++ b/src/testdir/test32.in @@ -0,0 +1,56 @@ +Test for insert expansion + +:se cpt=.,w +* add-expands (word from next line) from other window +* add-expands (current buffer first) +* Local expansion, ends in an empty line (unless it becomes a global expansion) +* starts Local and switches to global add-expansion +:se cpt=.,w,i +* i-add-expands and switches to local +* add-expands lines (it would end in an empty line if it didn't ignored it self) +:se cpt=kXtestfile +* checks k-expansion, and file expansion (use Xtest11 instead of test11, +* because TEST11.OUT may match first on DOS) +:se cpt=w +* checks make_cyclic in other window +:se cpt=u nohid +* checks unloaded buffer expansion +* checks adding mode abortion +:se cpt=t,d +* tag expansion, define add-expansion interrupted +* t-expansion + +STARTTEST +:so small.vim +:se nocp viminfo+=nviminfo cpt=.,w ff=unix | $-2,$w!Xtestfile | set ff& +nO#include "Xtestfile" +ru +O + + +:se cpt=.,w,i +kOM + +:se cpt=kXtestfile +:w Xtest11.one +:w Xtest11.two +OIXA +:se cpt=w +OST +:se cpt=u nohid +oOEN +unl +:se cpt=t,d def=^\\k* tags=Xtestfile notagbsearch +O +a +:wq! test.out +ENDTEST + +start of testfile +run1 +run2 +end of testfile + +test11 36Gepeto /Tag/ +asd test11file 36G +Makefile to run diff --git a/src/testdir/test32.ok b/src/testdir/test32.ok new file mode 100644 index 000000000..afc4463fa --- /dev/null +++ b/src/testdir/test32.ok @@ -0,0 +1,15 @@ +#include "Xtestfile" +run1 run3 +run3 run3 + +Makefile to run3 +Makefile to run3 +Makefile to run3 +Xtest11.two +STARTTEST +ENDTEST +unless +test11file 36Gepeto /Tag/ asd +asd +run1 run2 + diff --git a/src/testdir/test33.in b/src/testdir/test33.in new file mode 100644 index 000000000..564476040 --- /dev/null +++ b/src/testdir/test33.in @@ -0,0 +1,34 @@ +Test for 'lisp' +If the lisp feature is not enabled, this will fail! + +STARTTEST +:so small.vim +:set lisp +/^(defun +=G:/^(defun/,$w! test.out +:q! +ENDTEST + +(defun html-file (base) +(format nil "~(~A~).html" base)) + +(defmacro page (name title &rest body) +(let ((ti (gensym))) +`(with-open-file (*standard-output* +(html-file ,name) +:direction :output +:if-exists :supersede) +(let ((,ti ,title)) +(as title ,ti) +(with center +(as h2 (string-upcase ,ti))) +(brs 3) +,@body)))) + +;;; Utilities for generating links + +(defmacro with-link (dest &rest body) +`(progn +(format t "<a href=\"~A\">" (html-file ,dest)) +,@body +(princ "</a>"))) diff --git a/src/testdir/test33.ok b/src/testdir/test33.ok new file mode 100644 index 000000000..cd1d87a14 --- /dev/null +++ b/src/testdir/test33.ok @@ -0,0 +1,23 @@ +(defun html-file (base) + (format nil "~(~A~).html" base)) + +(defmacro page (name title &rest body) + (let ((ti (gensym))) + `(with-open-file (*standard-output* + (html-file ,name) + :direction :output + :if-exists :supersede) + (let ((,ti ,title)) + (as title ,ti) + (with center + (as h2 (string-upcase ,ti))) + (brs 3) + ,@body)))) + +;;; Utilities for generating links + +(defmacro with-link (dest &rest body) + `(progn + (format t "<a href=\"~A\">" (html-file ,dest)) + ,@body + (princ "</a>"))) diff --git a/src/testdir/test34.in b/src/testdir/test34.in new file mode 100644 index 000000000..676070075 --- /dev/null +++ b/src/testdir/test34.in @@ -0,0 +1,31 @@ +Test for user functions + +STARTTEST +:so small.vim +:function Table(title, ...) +: let ret = a:title +: let idx = 1 +: while idx <= a:0 +: exe "let ret = ret . a:" . idx +: let idx = idx + 1 +: endwhile +: return ret +:endfunction +:function Compute(n1, n2, divname) +: if a:n2 == 0 +: return "fail" +: endif +: exe "let g:" . a:divname . " = ". a:n1 / a:n2 +: return "ok" +:endfunction +:let retval = "nop" +/^here +C=Table("xxx", 4, "asdf") + =Compute(45, 0, "retval") + =retval + =Compute(45, 5, "retval") + =retval +:.wq! test.out +ENDTEST + +here diff --git a/src/testdir/test34.ok b/src/testdir/test34.ok new file mode 100644 index 000000000..6dab52f1d --- /dev/null +++ b/src/testdir/test34.ok @@ -0,0 +1 @@ +xxx4asdf fail nop ok 9 diff --git a/src/testdir/test35.in b/src/testdir/test35.in new file mode 100644 index 000000000..ba97911a1 --- /dev/null +++ b/src/testdir/test35.in @@ -0,0 +1,21 @@ +Test Ctrl-A and Ctrl-X, which increment and decrement decimal, hexadecimal, +and octal numbers. + +STARTTEST +/^start-here +:set nrformats=octal,hex +j102ll64128$ +:set nrformats=octal +0102l2w65129blx6lD +:set nrformats=hex +0101l257Txldt +:set nrformats= +0200l100w78k +:$-3,$wq! test.out +ENDTEST + +start-here +100 0x100 077 0 +100 0x100 077 +100 0x100 077 0xfF 0xFf +100 0x100 077 diff --git a/src/testdir/test35.ok b/src/testdir/test35.ok new file mode 100644 index 000000000..093ad958a --- /dev/null +++ b/src/testdir/test35.ok @@ -0,0 +1,4 @@ +0 0x0ff 0000 -1 +0 1x100 0777777 +-1 0x0 078 0xFE 0xfe +-100 -100x100 000 diff --git a/src/testdir/test36.in b/src/testdir/test36.in new file mode 100644 index 000000000..4c3b6b42f --- /dev/null +++ b/src/testdir/test36.in @@ -0,0 +1,40 @@ +Test character classes in regexp + +STARTTEST +/^start-here +j:s/\d//g +j:s/\D//g +j:s/\o//g +j:s/\O//g +j:s/\x//g +j:s/\X//g +j:s/\w//g +j:s/\W//g +j:s/\h//g +j:s/\H//g +j:s/\a//g +j:s/\A//g +j:s/\l//g +j:s/\L//g +j:s/\u//g +j:s/\U//g +:/^start-here/+1,$wq! test.out +ENDTEST + +start-here +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ diff --git a/src/testdir/test36.ok b/src/testdir/test36.ok new file mode 100644 index 000000000..5f70fc205 --- /dev/null +++ b/src/testdir/test36.ok @@ -0,0 +1,16 @@ +
!"#$%&'()#+'-./:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +0123456789 +
!"#$%&'()#+'-./89:;<=>?@ABCDEFGHIXYZ[\]^_`abcdefghiwxyz{|}~ +01234567 +
!"#$%&'()#+'-./:;<=>?@GHIXYZ[\]^_`ghiwxyz{|}~ +0123456789ABCDEFabcdef +
!"#$%&'()#+'-./:;<=>?@[\]^`{|}~ +0123456789ABCDEFGHIXYZ_abcdefghiwxyz +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^`{|}~ +ABCDEFGHIXYZ_abcdefghiwxyz +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^_`{|}~ +ABCDEFGHIXYZabcdefghiwxyz +
!"#$%&'()#+'-./0123456789:;<=>?@ABCDEFGHIXYZ[\]^_`{|}~ +abcdefghiwxyz +
!"#$%&'()#+'-./0123456789:;<=>?@[\]^_`abcdefghiwxyz{|}~ +ABCDEFGHIXYZ diff --git a/src/testdir/test37.in b/src/testdir/test37.in new file mode 100644 index 000000000..daaea32d0 --- /dev/null +++ b/src/testdir/test37.in @@ -0,0 +1,116 @@ +Test for 'scrollbind'. <eralston@computer.org> +STARTTEST +:so small.vim +:set noscrollbind +:set scrollopt=ver,jump +:set scrolloff=2 +:set nowrap +:set noequalalways +:set splitbelow +:" TEST using two windows open to one buffer, one extra empty window +:split +:new +t: +:resize 8 +/^start of window 1$/ +zt: +:set scrollbind +j: +:resize 7 +/^start of window 2$/ +zt: +:set scrollbind +:" -- start of tests -- +:" TEST scrolling down +L5jHyybpr0tHyybpr1tL6jHyybpr2kHyybpr3: +:" TEST scrolling up +tH4kjHtHyybpr4kHyybpr5k3ktHjHyybpr6tHyybpr7: +:" TEST horizontal scrolling +:set scrollopt+=hor +gg"zyyG"zpGt015zly$bp"zpGky$bp"zpG: +k10jH7zhg0y$bp"zpGtHg0y$bp"zpG: +:set scrollopt-=hor +:" ****** tests using two different buffers ***** +tj: +:close +t: +:set noscrollbind +:/^start of window 2$/,/^end of window 2$/y +:new +tj4"zpGp: +t/^start of window 1$/ +zt: +:set scrollbind +j: +/^start of window 2$/ +zt: +:set scrollbind +:" -- start of tests -- +:" TEST scrolling down +L5jHyybpr0tHyybpr1tL6jHyybpr2kHyybpr3: +:" TEST scrolling up +tH4kjHtHyybpr4kHyybpr5k3ktHjHyybpr6tHyybpr7: +:" TEST horizontal scrolling +:set scrollopt+=hor +gg"zyyG"zpGt015zly$bp"zpGky$bp"zpG: +k10jH7zhg0y$bp"zpGtHg0y$bp"zpG: +:set scrollopt-=hor +:" TEST syncbind +t:set noscb +ggLj:set noscb +ggL:set scb +t:set scb +GjG:syncbind +HktHjHyybptyybp: +t:set noscb +ggLj:set noscb +ggL:set scb +t:set scb +tGjGt:syncbind +HkjHtHyybptjyybp: +tH3kjHtHyybptjyybp: +:" ***** done with tests ***** +:w! test.out " Write contents of this file +:qa! +ENDTEST + + +start of window 1 +. line 01 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 01 +. line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02 +. line 03 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 03 +. line 04 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 04 +. line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05 +. line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06 +. line 07 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 07 +. line 08 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 08 +. line 09 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 09 +. line 10 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 10 +. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11 +. line 12 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 12 +. line 13 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 13 +. line 14 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 14 +. line 15 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 15 +end of window 1 + + +start of window 2 +. line 01 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 01 +. line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02 +. line 03 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 03 +. line 04 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 04 +. line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05 +. line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06 +. line 07 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 07 +. line 08 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 08 +. line 09 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 09 +. line 10 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 10 +. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11 +. line 12 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 12 +. line 13 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 13 +. line 14 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 14 +. line 15 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 15 +. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16 +end of window 2 + +end of test37.in (please don't delete this line) diff --git a/src/testdir/test37.ok b/src/testdir/test37.ok new file mode 100644 index 000000000..a9092a402 --- /dev/null +++ b/src/testdir/test37.ok @@ -0,0 +1,33 @@ + +0 line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05 +1 line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05 +2 line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11 +3 line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11 +4 line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06 +5 line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06 +6 line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02 +7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02 +56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02 +UTSRQPONMLKJIHGREDCBA9876543210 02 +. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11 +. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11 + +0 line 05 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 05 +1 line 05 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 05 +2 line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11 +3 line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11 +4 line 06 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 06 +5 line 06 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 06 +6 line 02 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 02 +7 line 02 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02 +56789ABCDEFGHIJKLMNOPQRSTUVWXYZ 02 +UTSRQPONMLKJIHGREDCBA9876543210 02 +. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11 +. line 11 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ 11 + +. line 16 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 16 +:set scrollbind +zt: +. line 15 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 15 +:set scrollbind +. line 11 ZYXWVUTSRQPONMLKJIHGREDCBA9876543210 11 diff --git a/src/testdir/test38.in b/src/testdir/test38.in new file mode 100644 index 000000000..885bd0967 --- /dev/null +++ b/src/testdir/test38.in @@ -0,0 +1,33 @@ + +Test Virtual replace mode. + +STARTTEST +:so small.vim +ggdGa +abcdefghi +jk lmn + opq rst +uvwxyz +gg:set ai +:set bs=2 +gR0 1 +A +BCDEFGHIJ + KL +MNO +PQRG:ka +o0 +abcdefghi +jk lmn + opq rst +uvwxyz +'ajgR0 1 +A +BCDEFGHIJ + KL +MNO +PQR:$ +iab cdefghi jkl0gRAB......CDEFGHI.Jo: +iabcdefghijklmnopqrst0gRAB IJKLMNO QR:wq! test.out +ENDTEST + diff --git a/src/testdir/test38.ok b/src/testdir/test38.ok new file mode 100644 index 000000000..e10209667 --- /dev/null +++ b/src/testdir/test38.ok @@ -0,0 +1,13 @@ + 1 + A + BCDEFGHIJ + KL + MNO + PQR + 1 +abcdefghi +jk lmn + opq rst +uvwxyz +AB......CDEFGHI.Jkl +AB IJKLMNO QRst diff --git a/src/testdir/test39.in b/src/testdir/test39.in new file mode 100644 index 000000000..d7f294b3c --- /dev/null +++ b/src/testdir/test39.in @@ -0,0 +1,24 @@ + +Test Visual block mode commands + +STARTTEST +:so small.vim +/^abcde +:" Test shift-right of a block +jlllljj>wlljlll> +:" Test shift-left of a block +G$hhhhkk< +:" Test block-insert +GklkkkIxyz +:" Test block-replace +Gllllkkklllrq +:" Test block-change +G$khhhhhkkcmno +:$-4,$wq! test.out +ENDTEST + +abcdefghijklm +abcdefghijklm +abcdefghijklm +abcdefghijklm +abcdefghijklm diff --git a/src/testdir/test39.ok b/src/testdir/test39.ok new file mode 100644 index 000000000..6fa2867eb --- /dev/null +++ b/src/testdir/test39.ok @@ -0,0 +1,5 @@ +axyzbcdefghijklm +axyzqqqq mno ghijklm +axyzqqqqef mno ghijklm +axyzqqqqefgmnoklm +abcdqqqqijklm diff --git a/src/testdir/test4.in b/src/testdir/test4.in new file mode 100644 index 000000000..4aa2fe5a8 --- /dev/null +++ b/src/testdir/test4.in @@ -0,0 +1,31 @@ +Test for autocommand that changes current buffer on BufEnter event. +Check if modelines are interpreted for the correct buffer. + +STARTTEST +:so small.vim +:set nocompatible viminfo+=nviminfo +:au BufEnter Xxx brew +/start of +:.,/end of/w! Xxx " write test file Xxx +:set ai modeline modelines=3 +:sp Xxx " split to Xxx, autocmd will do :brew +G?this is a +othis should be auto-indented +: " Append text with autoindent to this file +:au! BufEnter Xxx +:buf Xxx " go to Xxx, no autocmd anymore +G?this is a +othis should be in column 1:wq " append text without autoindent to Xxx +G:r Xxx " include Xxx in the current file +:?startstart?,$w! test.out +:qa! +ENDTEST + +startstart +start of test file Xxx +vim: set noai : + this is a test + this is a test + this is a test + this is a test +end of test file Xxx diff --git a/src/testdir/test4.ok b/src/testdir/test4.ok new file mode 100644 index 000000000..dffecda4d --- /dev/null +++ b/src/testdir/test4.ok @@ -0,0 +1,17 @@ +startstart +start of test file Xxx +vim: set noai : + this is a test + this is a test + this is a test + this is a test + this should be auto-indented +end of test file Xxx +start of test file Xxx +vim: set noai : + this is a test + this is a test + this is a test + this is a test +this should be in column 1 +end of test file Xxx diff --git a/src/testdir/test40.in b/src/testdir/test40.in new file mode 100644 index 000000000..f6fb61245 --- /dev/null +++ b/src/testdir/test40.in @@ -0,0 +1,63 @@ +Test for "*Cmd" autocommands + +STARTTEST +:so small.vim +:/^start/,$w! Xxx " write lines below to Xxx +:au BufReadCmd testA 0r Xxx|$del +:e testA " will read text of Xxd instead +:au BufWriteCmd testA call append(line("$"), "write") +:w " will append a line to the file +:r testA " should not read anything +: " now we have: +: " 1 start of Xxx +: " 2 test40 +: " 3 end of Xxx +: " 4 write +:au FileReadCmd testB '[r Xxx +:2r testB " will read Xxx below line 2 instead +: " 1 start of Xxx +: " 2 test40 +: " 3 start of Xxx +: " 4 test40 +: " 5 end of Xxx +: " 6 end of Xxx +: " 7 write +:au FileWriteCmd testC '[,']copy $ +4GA1 +:4,5w testC " will copy lines 4 and 5 to the end +:r testC " should not read anything +: " 1 start of Xxx +: " 2 test40 +: " 3 start of Xxx +: " 4 test401 +: " 5 end of Xxx +: " 6 end of Xxx +: " 7 write +: " 8 test401 +: " 9 end of Xxx +:au FILEAppendCmd testD '[,']w! test.out +:w >>testD " will write all lines to test.out +:$r testD " should not read anything +:$w >>test.out " append "end of Xxx" to test.out +:au BufReadCmd testE 0r test.out|$del +:sp testE " split window with test.out +5Goasdf:" +:au BufWriteCmd testE w! test.out +:wall " will write other window to test.out +: " 1 start of Xxx +: " 2 test40 +: " 3 start of Xxx +: " 4 test401 +: " 5 end of Xxx +: " 6 asdf +: " 7 end of Xxx +: " 8 write +: " 9 test401 +: " 10 end of Xxx +: " 11 end of Xxx +:qa! +ENDTEST + +start of Xxx + test40 +end of Xxx diff --git a/src/testdir/test40.ok b/src/testdir/test40.ok new file mode 100644 index 000000000..b6501394f --- /dev/null +++ b/src/testdir/test40.ok @@ -0,0 +1,11 @@ +start of Xxx + test40 +start of Xxx + test401 +end of Xxx +asdf +end of Xxx +write + test401 +end of Xxx +end of Xxx diff --git a/src/testdir/test41.in b/src/testdir/test41.in new file mode 100644 index 000000000..2d294cae0 --- /dev/null +++ b/src/testdir/test41.in @@ -0,0 +1,24 @@ +Test for writing and reading a file of over 100 Kbyte + +1 line: "This is the start" +3001 lines: "This is the leader" +1 line: "This is the middle" +3001 lines: "This is the trailer" +1 line: "This is the end" + +STARTTEST +:%d +aThis is the start +This is the leader +This is the middle +This is the trailer +This is the endkY3000p2GY3000p +:w! Xtest +:%d +:e! Xtest +:.w! test.out +3003G:.w >>test.out +6005G:.w >>test.out +:qa! +ENDTEST + diff --git a/src/testdir/test41.ok b/src/testdir/test41.ok new file mode 100644 index 000000000..988e5f24b --- /dev/null +++ b/src/testdir/test41.ok @@ -0,0 +1,3 @@ +This is the start +This is the middle +This is the end diff --git a/src/testdir/test42.in b/src/testdir/test42.in Binary files differnew file mode 100644 index 000000000..c35569a76 --- /dev/null +++ b/src/testdir/test42.in diff --git a/src/testdir/test42.ok b/src/testdir/test42.ok Binary files differnew file mode 100644 index 000000000..16f41e46e --- /dev/null +++ b/src/testdir/test42.ok diff --git a/src/testdir/test43.in b/src/testdir/test43.in new file mode 100644 index 000000000..26f0e0c9a --- /dev/null +++ b/src/testdir/test43.in @@ -0,0 +1,27 @@ +Tests for regexp with various magic settings. + +STARTTEST +:set nocompatible viminfo+=nviminfo +/^1 +/a*b\{2}c\+/e +x/\Md\*e\{2}f\+/e +x:set nomagic +/g\*h\{2}i\+/e +x/\mj*k\{2}l\+/e +x/\vm*n{2}o+/e +x/\V^aa$ +x:set magic +/\v(a)(b)\2\1\1/e +x/\V[ab]\(\[xy]\)\1 +x:?^1?,$w! test.out +:qa! +ENDTEST + +1 a aa abb abbccc +2 d dd dee deefff +3 g gg ghh ghhiii +4 j jj jkk jkklll +5 m mm mnn mnnooo +6 x ^aa$ x +7 (a)(b) abbaa +8 axx [ab]xx diff --git a/src/testdir/test43.ok b/src/testdir/test43.ok new file mode 100644 index 000000000..425316b68 --- /dev/null +++ b/src/testdir/test43.ok @@ -0,0 +1,8 @@ +1 a aa abb abbcc +2 d dd dee deeff +3 g gg ghh ghhii +4 j jj jkk jkkll +5 m mm mnn mnnoo +6 x aa$ x +7 (a)(b) abba +8 axx ab]xx diff --git a/src/testdir/test44.in b/src/testdir/test44.in new file mode 100644 index 000000000..d90a962d3 --- /dev/null +++ b/src/testdir/test44.in @@ -0,0 +1,37 @@ +Tests for regexp with multi-byte encoding and various magic settings. + +STARTTEST +:so mbyte.vim +:set nocompatible encoding=utf-8 termencoding=latin1 viminfo+=nviminfo +/^1 +/a*b\{2}c\+/e +x/\Md\*e\{2}f\+/e +x:set nomagic +/g\*h\{2}i\+/e +x/\mj*k\{2}l\+/e +x/\vm*n{2}o+/e +x/\V^aa$ +x:set magic +/\v(a)(b)\2\1\1/e +x/\V[ab]\(\[xy]\)\1 +x:" Now search for multi-byte without composing char +/ม +x:" Now search for multi-byte with composing char +/ม่ +x:" find word by change of word class +/ち\<カヨ\>は +x:?^1?,$w! test.out +:qa! +ENDTEST + +1 a aa abb abbccc +2 d dd dee deefff +3 g gg ghh ghhiii +4 j jj jkk jkklll +5 m mm mnn mnnooo +6 x ^aa$ x +7 (a)(b) abbaa +8 axx [ab]xx +9 หม่x อมx +a อมx หม่x +b ちカヨは diff --git a/src/testdir/test44.ok b/src/testdir/test44.ok new file mode 100644 index 000000000..af8507606 --- /dev/null +++ b/src/testdir/test44.ok @@ -0,0 +1,11 @@ +1 a aa abb abbcc +2 d dd dee deeff +3 g gg ghh ghhii +4 j jj jkk jkkll +5 m mm mnn mnnoo +6 x aa$ x +7 (a)(b) abba +8 axx ab]xx +9 หม่x อx +a อมx หx +b カヨは diff --git a/src/testdir/test45.in b/src/testdir/test45.in new file mode 100644 index 000000000..58537f33d --- /dev/null +++ b/src/testdir/test45.in @@ -0,0 +1,72 @@ +Tests for folding. vim: set ft=vim : + +STARTTEST +:so small.vim +:" We also need the +syntax feature here. +:if !has("syntax") + e! test.ok + w! test.out + qa! +:endif +:" basic test if a fold can be created, opened, moving to the end and closed +/^1 +zf2j:call append("$", "manual " . getline(foldclosed("."))) +zo:call append("$", foldclosed(".")) +]z:call append("$", getline(".")) +zc:call append("$", getline(foldclosed("."))) +:" test folding with markers. +:set fdm=marker fdl=1 fdc=3 +/^5 +:call append("$", "marker " . foldlevel(".")) +[z:call append("$", foldlevel(".")) +jo{{ r{jj:call append("$", foldlevel(".")) +kYpj:call append("$", foldlevel(".")) +:" test folding with indent +:set fdm=indent sw=2 +/^2 b +i jI :call append("$", "indent " . foldlevel(".")) +k:call append("$", foldlevel(".")) +:" test syntax folding +:set fdm=syntax fdl=0 +:syn region Hup start="dd" end="hh" fold +Gzk:call append("$", "folding " . getline(".")) +k:call append("$", getline(".")) +:" test expression folding +:fun Flvl() + let l = getline(v:lnum) + if l =~ "bb$" + return 2 + elseif l =~ "gg$" + return "s1" + elseif l =~ "ii$" + return ">2" + elseif l =~ "kk$" + return "0" + endif + return "=" +endfun +:set fdm=expr fde=Flvl() +/bb$ +:call append("$", "expr " . foldlevel(".")) +/hh$ +:call append("$", foldlevel(".")) +/ii$ +:call append("$", foldlevel(".")) +/kk$ +:call append("$", foldlevel(".")) +:/^last/+1,$w! test.out +:qa! +ENDTEST + +1 aa +2 bb +3 cc +4 dd {{{ +5 ee {{{ }}} +6 ff }}} +7 gg +8 hh +9 ii +a jj +b kk +last diff --git a/src/testdir/test45.ok b/src/testdir/test45.ok new file mode 100644 index 000000000..f5a1380e5 --- /dev/null +++ b/src/testdir/test45.ok @@ -0,0 +1,16 @@ +manual 1 aa +-1 +3 cc +1 aa +marker 2 +1 +1 +0 +indent 2 +1 +folding 8 hh + 3 cc +expr 2 +1 +2 +0 diff --git a/src/testdir/test46.in b/src/testdir/test46.in new file mode 100644 index 000000000..9a9db74d6 --- /dev/null +++ b/src/testdir/test46.in @@ -0,0 +1,27 @@ +Tests for multi-line regexps with ":s". vim: set ft=vim : + +STARTTEST +:" test if replacing a line break works with a back reference +:/^1/,/^2/s/\n\(.\)/ \1/ +:" test if inserting a line break works with a back reference +:/^3/,/^4/s/\(.\)$/\r\1/ +:" test if replacing a line break with another line break works +:/^5/,/^6/s/\(\_d\{3}\)/x\1x/ +:/^1/,$w! test.out +:qa! +ENDTEST + +1 aa +bb +cc +2 dd +ee +3 ef +gh +4 ij +5 a8 +8b c9 +9d +6 e7 +77f +xxxxx diff --git a/src/testdir/test46.ok b/src/testdir/test46.ok new file mode 100644 index 000000000..71b353df1 --- /dev/null +++ b/src/testdir/test46.ok @@ -0,0 +1,13 @@ +1 aa bb cc 2 dd ee +3 e +f +g +h +4 i +j +5 ax8 +8xb cx9 +9xd +6 ex7 +7x7f +xxxxx diff --git a/src/testdir/test47.in b/src/testdir/test47.in new file mode 100644 index 000000000..35bb9f260 --- /dev/null +++ b/src/testdir/test47.in @@ -0,0 +1,44 @@ +Tests for vertical splits and filler lines in diff mode + +STARTTEST +:so small.vim +/^1 +yG:new +pkdd:w! Xtest +ddGpkkrXoxxx:w! Xtest2 +:file Nop +ggoyyyjjjozzzz +:vert diffsplit Xtest +:vert diffsplit Xtest2 +:" jump to second window for a moment to have filler line appear at start of +:" first window +ggpgg:let one = winline() +j:let one = one . "-" . winline() +j:let one = one . "-" . winline() +j:let one = one . "-" . winline() +j:let one = one . "-" . winline() +j:let one = one . "-" . winline() +gg:let two = winline() +j:let two = two . "-" . winline() +j:let two = two . "-" . winline() +j:let two = two . "-" . winline() +j:let two = two . "-" . winline() +gg:let three = winline() +j:let three = three . "-" . winline() +j:let three = three . "-" . winline() +j:let three = three . "-" . winline() +j:let three = three . "-" . winline() +j:let three = three . "-" . winline() +j:let three = three . "-" . winline() +:call append("$", one) +:call append("$", two) +:call append("$", three) +:$-2,$w! test.out +:qa! +ENDTEST + +1 aa +2 bb +3 cc +4 dd +5 ee diff --git a/src/testdir/test47.ok b/src/testdir/test47.ok new file mode 100644 index 000000000..3307b934e --- /dev/null +++ b/src/testdir/test47.ok @@ -0,0 +1,3 @@ +2-4-5-6-8-9 +1-2-4-5-8 +2-3-4-5-6-7-8 diff --git a/src/testdir/test48.in b/src/testdir/test48.in new file mode 100644 index 000000000..2179fe664 --- /dev/null +++ b/src/testdir/test48.in @@ -0,0 +1,74 @@ +This is a test of 'virtualedit'. + +STARTTEST +:so small.vim +:set noswf +:set ve=all +-dgg +:" +:" Insert "keyword keyw", ESC, C CTRL-N, shows "keyword ykeyword". +:" Repeating CTRL-N fixes it. (Mary Ellen Foster) +2/w +C +:" +:" Using "C" then then <CR> moves the last remaining character to the next +:" line. (Mary Ellen Foster) +j^/are +C
are belong to vim +:" +:" When past the end of a line that ends in a single character "b" skips +:" that word. +^$15lbC7 +:" +:" Make sure 'i' works +$4li<-- should be 3 ' ' +:" +:" Make sure 'C' works +$4lC<-- should be 3 ' ' +:" +:" Make sure 'a' works +$4la<-- should be 4 ' ' +:" +:" Make sure 'A' works +$4lA<-- should be 0 ' ' +:" +:" Make sure 'D' works +$4lDi<-- 'D' should be intact +:" +:" Test for yank bug reported by Mark Waggoner. +:set ve=block +^2w3jyGp +:" +:" Test "r" beyond the end of the line +:set ve=all +/^"r" +$5lrxa<-- should be 'x' +:" +:" Test to make sure 'x' can delete control characters +:set display=uhex +^xxxxxxi[This line should contain only the text between the brackets.] +:set display= +:" +:" Test for ^Y/^E due to bad w_virtcol value, reported by +:" Roy <royl@netropolis.net>. +^O3li4li4li <-- should show the name of a noted text editor +^o4li4li4li <-- and its version number-dd +:" +:wq! test.out +ENDTEST +keyword keyw +all your base are belong to us +1 2 3 4 5 6 +'i' +'C' +'a' +'A' +'D' +this is a test +this is a test +this is a test +"r" +ab
sd +abcv6efi.him0kl + + diff --git a/src/testdir/test48.ok b/src/testdir/test48.ok new file mode 100644 index 000000000..4fcbe5086 --- /dev/null +++ b/src/testdir/test48.ok @@ -0,0 +1,21 @@ +keyword keyword +all your base +are belong to vim +1 2 3 4 5 7 +'i' <-- should be 3 ' ' +'C' <-- should be 3 ' ' +'a' <-- should be 4 ' ' +'A'<-- should be 0 ' ' +'D' <-- 'D' should be intact +this is a test +this is a test +this is a test +"r" x<-- should be 'x' +[This line should contain only the text between the brackets.] + v i m <-- should show the name of a noted text editor + 6 . 0 <-- and its version number + +a +a +a + diff --git a/src/testdir/test49.in b/src/testdir/test49.in new file mode 100644 index 000000000..ec17d2134 --- /dev/null +++ b/src/testdir/test49.in @@ -0,0 +1,13 @@ +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 ore more "G"s at the line before ENDTEST. + +STARTTEST +:so small.vim +:se nocp nomore viminfo+=nviminfo +:so test49.vim +GGGGGGGGGG"rp:.-,$wq! test.out +ENDTEST + +Results of test49.vim: diff --git a/src/testdir/test49.ok b/src/testdir/test49.ok new file mode 100644 index 000000000..1842af259 --- /dev/null +++ b/src/testdir/test49.ok @@ -0,0 +1,92 @@ +Results of test49.vim: +*** Test 1: OK (34695) +*** Test 2: OK (34695) +*** Test 3: OK (1384648195) +*** Test 4: OK (32883) +*** Test 5: OK (32883) +*** Test 6: OK (603978947) +*** Test 7: OK (90563) +*** Test 8: OK (562493431) +*** Test 9: OK (363) +*** Test 10: OK (559615) +*** Test 11: OK (2049) +*** Test 12: OK (352256) +*** Test 13: OK (145) +*** Test 14: OK (42413) +*** Test 15: OK (42413) +*** Test 16: OK (8722) +*** Test 17: OK (285127993) +*** Test 18: OK (67224583) +*** Test 19: OK (69275973) +*** Test 20: OK (1874575085) +*** Test 21: OK (147932225) +*** Test 22: OK (4161) +*** Test 23: OK (49) +*** Test 24: OK (41) +*** Test 25: OK (260177811) +*** Test 26: OK (1681500476) +*** Test 27: OK (1996459) +*** Test 28: OK (1996459) +*** Test 29: OK (170428555) +*** Test 30: OK (190905173) +*** Test 31: OK (190905173) +*** Test 32: OK (354833067) +--- Test 33: sum = 178275600 (ok) +*** Test 33: OK (1216907538) +*** Test 34: OK (2146584868) +*** Test 35: OK (2146584868) +*** Test 36: OK (1071644672) +*** Test 37: OK (1071644672) +*** Test 38: OK (357908480) +*** Test 39: OK (357908480) +*** Test 40: OK (357908480) +*** Test 41: OK (3076095) +*** Test 42: OK (1505155949) +*** Test 43: OK (1157763329) +*** Test 44: OK (1031761407) +*** Test 45: OK (1157763329) +*** Test 46: OK (739407) +*** Test 47: OK (371213935) +*** Test 48: OK (756255461) +*** Test 49: OK (179000669) +*** Test 50: OK (363550045) +*** Test 51: OK (40744667) +*** Test 52: OK (1247112011) +*** Test 53: OK (131071) +*** Test 54: OK (2047) +*** Test 55: OK (1023) +*** Test 56: OK (511) +*** Test 57: OK (2147450880) +*** Test 58: OK (624945) +*** Test 59: OK (2038431743) +*** Test 60: OK (311511339) +*** Test 61: OK (374889517) +*** Test 62: OK (286331153) +*** Test 63: OK (236978127) +*** Test 64: OK (1499645335) +*** Test 65: OK (70187) +*** Test 66: OK (5464) +*** Test 67: OK (212514423) +*** Test 68: OK (212514423) +*** Test 69: OK (8995471) +*** Test 70: OK (69544277) +*** Test 71: OK (34886997) +*** Test 72: OK (1789569365) +*** Test 73: OK (9032615) +*** Test 74: OK (224907669) +*** Test 75: OK (2000403408) +*** Test 76: OK (1610087935) +*** Test 77: OK (1388671) +*** Test 78: OK (134217728) +*** Test 79: OK (70288929) +*** Test 80: OK (17895765) +*** Test 81: OK (387) +*** Test 82: OK (8454401) +*** Test 83: OK (2835) +*** Test 84: OK (934782101) +*** Test 85: OK (198689) +--- Test 86: All tests were run with throwing exceptions on error. + The $VIMNOERRTHROW control is not configured. +--- Test 86: All tests were run with throwing exceptions on interrupt. + The $VIMNOINTTHROW control is not configured. +*** Test 86: OK (50443995) diff --git a/src/testdir/test49.vim b/src/testdir/test49.vim new file mode 100644 index 000000000..e742a9622 --- /dev/null +++ b/src/testdir/test49.vim @@ -0,0 +1,9666 @@ +" Vim script language tests +" Author: Servatius Brandt <Servatius.Brandt@fujitsu-siemens.com> +" Last Change: 2004 Apr 03 + +"------------------------------------------------------------------------------- +" 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. Permittable 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 +" ommitted (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=+ Xout exec "exec \"!echo @R:'\" ." + \ 'substitute(substitute("' . <args> . + \ '", "' . "'" . '", ' . "'" . '&\\&&' . "'" + \ . ', "g"), "\n", "@NL@", "g")' + \ ". \"' >>\" . g:ExtraVimResult" +else + com! -nargs=+ Xout exec 'let @R = "--- Test ' . + \ (g:Xtest<10?" ":g:Xtest<100?" ":"") . + \ g:Xtest . ": " . + \ '" . substitute("' . <args> . + \ '", "\n", "&\t ", "g") . "\n"' +endif + +" 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', "") + let func_conts = 0 + elseif theline =~ '^\s*\\' + if in_func + let func_conts = func_conts + 1 + endif + 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_conts) . " " . + \ 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 + " contiunation ("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' | ../vim -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 relativ 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 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. + + +"------------------------------------------------------------------------------- +" Test 1: :endwhile in function {{{1 +" +" Detect if a broken loop is (incorrectly) reactivated by the +" :endwhile. Use a :return to prevent an endless loop, and make +" this test first to get a meaningful result on an error before other +" tests will hang. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() + Xpath 1 " X: 1 + let first = 1 + XloopINIT 2 8 + while 1 + Xloop 1 " X: 2 + 0 * 16 + if first + Xloop 2 " X: 4 + 0 * 32 + let first = 0 + XloopNEXT + break + else + Xloop 4 " X: 0 + 0 * 64 + return + endif + endwhile +endfunction + +call F() +Xpath 128 " X: 128 + +function! G() + Xpath 256 " X: 256 + 0 * 2048 + let first = 1 + XloopINIT 512 8 + while 1 + Xloop 1 " X: 512 + 0 * 4096 + if first + Xloop 2 " X: 1024 + 0 * 8192 + let first = 0 + XloopNEXT + break + else + Xloop 4 " X: 0 + 0 * 16384 + return + endif + if 1 " unmatched :if + endwhile +endfunction + +call G() +Xpath 32768 " X: 32768 + +Xcheck 34695 + +" Leave F and G for execution as scripts in the next test. + + +"------------------------------------------------------------------------------- +" Test 2: :endwhile in script {{{1 +" +" Detect if a broken loop is (incorrectly) reactivated by the +" :endwhile. Use a :finish to prevent an endless loop, and place +" this test before others that might hang to get a meaningful result +" on an error. +" +" This test executes the bodies of the functions F and G from the +" previous test as script files (:return replaced by :finish). +"------------------------------------------------------------------------------- + +XpathINIT + +ExecAsScript F " X: 1 + 2 + 4 +Xpath 128 " X: 128 + +ExecAsScript G " X: 256 + 512 + 1024 +Xpath 32768 " X: 32768 + +unlet first +delfunction F +delfunction G + +Xcheck 34695 + + +"------------------------------------------------------------------------------- +" Test 3: :if, :elseif, :while, :continue, :break {{{1 +"------------------------------------------------------------------------------- + +XpathINIT +if 1 + Xpath 1 " X: 1 + let loops = 3 + XloopINIT 2 512 + while loops > -1 " main loop: loops == 3, 2, 1 (which breaks) + if loops <= 0 + let break_err = 1 + let loops = -1 + else " 3: 2: 1: + Xloop 1 " X: 2 + 2*512 + 2*512*512 + endif + if (loops == 2) + while loops == 2 " dummy loop + Xloop 2 " X: 4*512 + let loops = loops - 1 + continue " stop dummy loop + Xloop 4 " X: 0 + endwhile + XloopNEXT + continue " continue main loop + Xloop 8 " X: 0 + elseif (loops == 1) + let p = 1 + while p " dummy loop + Xloop 16 " X: 32*512*512 + let p = 0 + break " break dummy loop + Xloop 32 " X: 0 + endwhile + Xloop 64 " X: 128*512*512 + unlet p + break " break main loop + Xloop 128 " X: 0 + endif + if (loops > 0) + Xloop 256 " X: 512 + endif + while loops == 3 " dummy loop + let loops = loops - 1 + endwhile " end dummy loop + XloopNEXT + endwhile " end main loop + Xpath 268435456 " X: 1024*512*512 +else + Xpath 536870912 " X: 0 +endif +Xpath 1073741824 " X: 4096*512*512 +if exists("break_err") + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + unlet break_err +endif + +unlet loops + +Xcheck 1384648195 + + +"------------------------------------------------------------------------------- +" Test 4: :return {{{1 +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() + if 1 + Xpath 1 " X: 1 + let loops = 3 + XloopINIT 2 16 + while loops > 0 " 3: 2: 1: + Xloop 1 " X: 2 + 2*16 + 0*16*16 + if (loops == 2) + Xloop 2 " X: 4*16 + return + Xloop 4 " X: 0 + endif + Xloop 8 " X: 16 + let loops = loops - 1 + XloopNEXT + endwhile + Xpath 8192 " X: 0 + else + Xpath 16384 " X: 0 + endif +endfunction + +call F() +Xpath 32768 " X: 8*16*16*16 + +Xcheck 32883 + +" Leave F for execution as a script in the next test. + + +"------------------------------------------------------------------------------- +" Test 5: :finish {{{1 +" +" This test executes the body of the function F from the previous test +" as a script file (:return replaced by :finish). +"------------------------------------------------------------------------------- + +XpathINIT + +ExecAsScript F " X: 1 + 2 + 2*16 + 4*16 + 16 +Xpath 32768 " X: 32768 + +unlet loops +delfunction F + +Xcheck 32883 + + +"------------------------------------------------------------------------------- +" Test 6: Defining functions in :while loops {{{1 +" +" Functions can be defined inside other functions. An inner function +" gets defined when the outer function is executed. Functions may +" also be defined inside while loops. Expressions in braces for +" defining the function name are allowed. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + " The command CALL collects the argument of all its invocations in "calls" + " when used from a function (that is, when the global variable "calls" needs + " the "g:" prefix). This is to check that the function code is skipped when + " the function is defined. For inner functions, do so only if the outer + " function is not being executed. + " + let calls = "" + com! -nargs=1 CALL + \ if !exists("calls") && !exists("outer") | + \ let g:calls = g:calls . <args> | + \ endif + + + XloopINIT! 1 16 + + let i = 0 + while i < 3 + + XloopNEXT + let i = i + 1 + + if i == 1 + Xloop 1 " X: 1 + function! F1(arg) + CALL a:arg + let outer = 1 + + XloopINIT! 4096 4 + let j = 0 + while j < 1 + XloopNEXT + Xloop 1 " X: 4096 + let j = j + 1 + function! G1(arg) + CALL a:arg + endfunction + Xloop 2 " X: 8192 + endwhile + endfunction + Xloop 2 " X: 2 + + continue + endif + + Xloop 4 " X: 4 * (16 + 256) + function! F{i}(i, arg) + CALL a:arg + let outer = 1 + + XloopINIT! 16384 4 + if a:i == 3 + XloopNEXT + XloopNEXT + XloopNEXT + endif + let k = 0 + while k < 3 + XloopNEXT + Xloop 1 " X: 16384*(1+4+16+64+256+1024) + let k = k + 1 + function! G{a:i}{k}(arg) + CALL a:arg + endfunction + Xloop 2 " X: 32768*(1+4+16+64+256+1024) + endwhile + endfunction + Xloop 8 " X: 8 * (16 + 256) + + endwhile + + if exists("*G1") + Xpath 67108864 " X: 0 + endif + if exists("*F1") + call F1("F1") + if exists("*G1") + call G1("G1") + endif + endif + + if exists("G21") || exists("G21") || exists("G21") + Xpath 134217728 " X: 0 + endif + if exists("*F2") + call F2(2, "F2") + if exists("*G21") + call G21("G21") + endif + if exists("*G22") + call G22("G22") + endif + if exists("*G23") + call G23("G23") + endif + endif + + if exists("G31") || exists("G31") || exists("G31") + Xpath 268435456 " X: 0 + endif + if exists("*F3") + call F3(3, "F3") + if exists("*G31") + call G31("G31") + endif + if exists("*G32") + call G32("G32") + endif + if exists("*G33") + call G33("G33") + endif + endif + + Xpath 536870912 " X: 536870912 + + if calls != "F1G1F2G21G22G23F3G31G32G33" + Xpath 1073741824 " X: 0 + Xout "calls is" calls + endif + + delfunction F1 + delfunction G1 + delfunction F2 + delfunction G21 + delfunction G22 + delfunction G23 + delfunction G31 + delfunction G32 + delfunction G33 + +endif + +Xcheck 603978947 + + +"------------------------------------------------------------------------------- +" Test 7: Continuing on errors outside functions {{{1 +" +" On an error outside a function, the script processing continues +" at the line following the outermost :endif or :endwhile. When not +" inside an :if or :while, the script processing continues at the next +" line. +"------------------------------------------------------------------------------- + +XpathINIT + +if 1 + Xpath 1 " X: 1 + while 1 + Xpath 2 " X: 2 + asdf + Xpath 4 " X: 0 + break + endwhile | Xpath 8 " X: 0 + Xpath 16 " X: 0 +endif | Xpath 32 " X: 0 +Xpath 64 " X: 64 + +while 1 + Xpath 128 " X: 128 + if 1 + Xpath 256 " X: 256 + asdf + Xpath 512 " X: 0 + endif | Xpath 1024 " X: 0 + Xpath 2048 " X: 0 + break +endwhile | Xpath 4096 " X: 0 +Xpath 8192 " X: 8192 + +asdf +Xpath 16384 " X: 16384 + +asdf | Xpath 32768 " X: 0 +Xpath 65536 " X: 65536 + +Xcheck 90563 + + +"------------------------------------------------------------------------------- +" Test 8: Aborting and continuing on errors inside functions {{{1 +" +" On an error inside a function without the "abort" attribute, the +" script processing continues at the next line (unless the error was +" in a :return command). On an error inside a function with the +" "abort" attribute, the function is aborted and the script processing +" continues after the function call; the value -1 is returned then. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() + if 1 + Xpath 1 " X: 1 + while 1 + Xpath 2 " X: 2 + asdf + Xpath 4 " X: 4 + asdf | Xpath 8 " X: 0 + Xpath 16 " X: 16 + break + endwhile + Xpath 32 " X: 32 + endif | Xpath 64 " X: 64 + Xpath 128 " X: 128 + + while 1 + Xpath 256 " X: 256 + if 1 + Xpath 512 " X: 512 + asdf + Xpath 1024 " X: 1024 + asdf | Xpath 2048 " X: 0 + Xpath 4096 " X: 4096 + endif + Xpath 8192 " X: 8192 + break + endwhile | Xpath 16384 " X: 16384 + Xpath 32768 " X: 32768 + + return novar " returns (default return value 0) + Xpath 65536 " X: 0 + return 1 " not reached +endfunction + +function! G() abort + if 1 + Xpath 131072 " X: 131072 + while 1 + Xpath 262144 " X: 262144 + asdf " returns -1 + Xpath 524288 " X: 0 + break + endwhile + Xpath 1048576 " X: 0 + endif | Xpath 2097152 " X: 0 + Xpath Xpath 4194304 " X: 0 + + return -4 " not reached +endfunction + +function! H() abort + while 1 + Xpath 8388608 " X: 8388608 + if 1 + Xpath 16777216 " X: 16777216 + asdf " returns -1 + Xpath 33554432 " X: 0 + endif + Xpath 67108864 " X: 0 + break + endwhile | Xpath 134217728 " X: 0 + Xpath 268435456 " X: 0 + + return -4 " not reached +endfunction + +" Aborted functions (G and H) return -1. +let sum = (F() + 1) - 4*G() - 8*H() +Xpath 536870912 " X: 536870912 +if sum != 13 + Xpath 1073741824 " X: 0 + Xout "sum is" sum +endif + +unlet sum +delfunction F +delfunction G +delfunction H + +Xcheck 562493431 + + +"------------------------------------------------------------------------------- +" Test 9: Continuing after aborted functions {{{1 +" +" When a function with the "abort" attribute is aborted due to an +" error, the next function back in the call hierarchy without an +" "abort" attribute continues; the value -1 is returned then. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() abort + Xpath 1 " X: 1 + let result = G() " not aborted + Xpath 2 " X: 2 + if result != 2 + Xpath 4 " X: 0 + endif + return 1 +endfunction + +function! G() " no abort attribute + Xpath 8 " X: 8 + if H() != -1 " aborted + Xpath 16 " X: 0 + endif + Xpath 32 " X: 32 + return 2 +endfunction + +function! H() abort + Xpath 64 " X: 64 + call I() " aborted + Xpath 128 " X: 0 + return 4 +endfunction + +function! I() abort + Xpath 256 " X: 256 + asdf " error + Xpath 512 " X: 0 + return 8 +endfunction + +if F() != 1 + Xpath 1024 " X: 0 +endif + +delfunction F +delfunction G +delfunction H +delfunction I + +Xcheck 363 + + +"------------------------------------------------------------------------------- +" Test 10: :if, :elseif, :while argument parsing {{{1 +" +" A '"' or '|' in an argument expression must not be mixed up with +" a comment or a next command after a bar. Parsing errors should +" be recognized. +"------------------------------------------------------------------------------- + +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 + +if 1 || strlen("\"") | Xpath 1 " X: 1 + Xpath 2 " X: 2 +endif +Xpath 4 " X: 4 + +if 0 +elseif 1 || strlen("\"") | Xpath 8 " X: 8 + Xpath 16 " X: 16 +endif +Xpath 32 " X: 32 + +while 1 || strlen("\"") | Xpath 64 " X: 64 + Xpath 128 " X: 128 + break +endwhile +Xpath 256 " X: 256 + +let v:errmsg = "" +if 1 ||| strlen("\"") | Xpath 512 " X: 0 + Xpath 1024 " X: 0 +endif +Xpath 2048 " X: 2048 +if !MSG('E15', "Invalid expression") + Xpath 4096 " X: 0 +endif + +let v:errmsg = "" +if 0 +elseif 1 ||| strlen("\"") | Xpath 8192 " X: 0 + Xpath 16384 " X: 0 +endif +Xpath 32768 " X: 32768 +if !MSG('E15', "Invalid expression") + Xpath 65536 " X: 0 +endif + +let v:errmsg = "" +while 1 ||| strlen("\"") | Xpath 131072 " X: 0 + Xpath 262144 " X: 0 + break +endwhile +Xpath 524288 " X: 524288 +if !MSG('E15', "Invalid expression") + Xpath 1048576 " X: 0 +endif + +delfunction MSG + +Xcheck 559615 + + +"------------------------------------------------------------------------------- +" Test 11: :if, :elseif, :while argument evaluation after abort {{{1 +" +" When code is skipped over due to an error, the boolean argument to +" an :if, :elseif, or :while must not be evaluated. +"------------------------------------------------------------------------------- + +XpathINIT + +let calls = 0 + +function! P(num) + let g:calls = g:calls + a:num " side effect on call + return 0 +endfunction + +if 1 + Xpath 1 " X: 1 + asdf " error + Xpath 2 " X: 0 + if P(1) " should not be called + Xpath 4 " X: 0 + elseif !P(2) " should not be called + Xpath 8 " X: 0 + else + Xpath 16 " X: 0 + endif + Xpath 32 " X: 0 + while P(4) " should not be called + Xpath 64 " X: 0 + endwhile + Xpath 128 " X: 0 +endif + +if calls % 2 + Xpath 256 " X: 0 +endif +if (calls/2) % 2 + Xpath 512 " X: 0 +endif +if (calls/4) % 2 + Xpath 1024 " X: 0 +endif +Xpath 2048 " X: 2048 + +unlet calls +delfunction P + +Xcheck 2049 + + +"------------------------------------------------------------------------------- +" Test 12: Expressions in braces in skipped code {{{1 +" +" In code skipped over due to an error or inactive conditional, +" an expression in braces as part of a variable or function name +" should not be evaluated. +"------------------------------------------------------------------------------- + +XpathINIT + +XloopINIT 1 8 + +function! NULL() + Xloop 1 " X: 0 + return 0 +endfunction + +function! ZERO() + Xloop 2 " X: 0 + return 0 +endfunction + +function! F0() + Xloop 4 " X: 0 +endfunction + +function! F1(arg) + Xpath 4096 " X: 0 +endfunction + +let V0 = 1 + +Xpath 8192 " X: 8192 +echo 0 ? F{NULL() + V{ZERO()}}() : 1 +XloopNEXT + +Xpath 16384 " X: 16384 +if 0 + Xpath 32768 " X: 0 + call F{NULL() + V{ZERO()}}() +endif +XloopNEXT + +Xpath 65536 " X: 65536 +if 1 + asdf " error + Xpath 131072 " X: 0 + call F1(F{NULL() + V{ZERO()}}()) +endif +XloopNEXT + +Xpath 262144 " X: 262144 +if 1 + asdf " error + Xpath 524288 " X: 0 + call F{NULL() + V{ZERO()}}() +endif + +Xcheck 352256 + + +"------------------------------------------------------------------------------- +" Test 13: Failure in argument evaluation for :while {{{1 +" +" A failure in the expression evaluation for the condition of a :while +" causes the whole :while loop until the matching :endwhile being +" ignored. Continuation is at the next following line. +"------------------------------------------------------------------------------- + +XpathINIT + +Xpath 1 " X: 1 +while asdf + Xpath 2 " X: 0 + while 1 + Xpath 4 " X: 0 + break + endwhile + Xpath 8 " X: 0 + break +endwhile +Xpath 16 " X: 16 + +while asdf | Xpath 32 | endwhile | Xpath 64 " X: 0 +Xpath 128 " X: 128 + +Xcheck 145 + + +"------------------------------------------------------------------------------- +" Test 14: Failure in argument evaluation for :if {{{1 +" +" A failure in the expression evaluation for the condition of an :if +" does not cause the corresponding :else or :endif being matched to +" a previous :if/:elseif. Neither of both branches of the failed :if +" are executed. +"------------------------------------------------------------------------------- + +XpathINIT +XloopINIT 1 256 + +function! F() + Xloop 1 " X: 1 + 256 * 1 + let x = 0 + if x " false + Xloop 2 " X: 0 + 256 * 0 + elseif !x " always true + Xloop 4 " X: 4 + 256 * 4 + let x = 1 + if g:boolvar " possibly undefined + Xloop 8 " X: 8 + 256 * 0 + else + Xloop 16 " X: 0 + 256 * 0 + endif + Xloop 32 " X: 32 + 256 * 32 + elseif x " never executed + Xloop 64 " X: 0 + 256 * 0 + endif + Xloop 128 " X: 128 + 256 * 128 +endfunction + +let boolvar = 1 +call F() + +XloopNEXT +unlet boolvar +call F() + +delfunction F + +Xcheck 42413 + + +"------------------------------------------------------------------------------- +" Test 15: Failure in argument evaluation for :if (bar) {{{1 +" +" Like previous test, except that the failing :if ... | ... | :endif +" is in a single line. +"------------------------------------------------------------------------------- + +XpathINIT +XloopINIT 1 256 + +function! F() + Xloop 1 " X: 1 + 256 * 1 + let x = 0 + if x " false + Xloop 2 " X: 0 + 256 * 0 + elseif !x " always true + Xloop 4 " X: 4 + 256 * 4 + let x = 1 + if g:boolvar | Xloop 8 | else | Xloop 16 | endif " X: 8 + Xloop 32 " X: 32 + 256 * 32 + elseif x " never executed + Xloop 64 " X: 0 + 256 * 0 + endif + Xloop 128 " X: 128 + 256 * 128 +endfunction + +let boolvar = 1 +call F() + +XloopNEXT +unlet boolvar +call F() + +delfunction F + +Xcheck 42413 + + +"------------------------------------------------------------------------------- +" Test 16: Double :else or :elseif after :else {{{1 +" +" Multiple :elses or an :elseif after an :else are forbidden. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() abort + if 0 + Xpath 1 " X: 0 + else + Xpath 2 " X: 2 + else " aborts function + Xpath 4 " X: 0 + endif +endfunction + +function! G() abort + if 0 + Xpath 8 " X: 0 + else + Xpath 16 " X: 16 + elseif 1 " aborts function + Xpath 32 " X: 0 + else + Xpath 64 " X: 0 + endif +endfunction + +function! H() abort + if 0 + Xpath 128 " X: 0 + elseif 0 + Xpath 256 " X: 0 + else + Xpath 512 " X: 512 + else " aborts function + Xpath 1024 " X: 0 + endif +endfunction + +function! I() abort + if 0 + Xpath 2048 " X: 0 + elseif 0 + Xpath 4096 " X: 0 + else + Xpath 8192 " X: 8192 + elseif 1 " aborts function + Xpath 16384 " X: 0 + else + Xpath 32768 " X: 0 + endif +endfunction + +call F() +call G() +call H() +call I() + +delfunction F +delfunction G +delfunction H +delfunction I + +Xcheck 8722 + + +"------------------------------------------------------------------------------- +" Test 17: Nesting of unmatched :if or :endif inside a :while {{{1 +" +" The :while/:endwhile takes precedence in nesting over an unclosed +" :if or an unopened :endif. +"------------------------------------------------------------------------------- + +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 + +let messages = "" + +" While loops inside a function are continued on error. +function! F() + let v:errmsg = "" + XloopINIT 1 16 + let loops = 3 + while loops > 0 + let loops = loops - 1 " 2: 1: 0: + Xloop 1 " X: 1 + 1*16 + 1*16*16 + if (loops == 1) + Xloop 2 " X: 2*16 + XloopNEXT + continue + elseif (loops == 0) + Xloop 4 " X: 4*16*16 + break + elseif 1 + Xloop 8 " X: 8 + XloopNEXT + " endif missing! + endwhile " :endwhile after :if 1 + Xpath 4096 " X: 16*16*16 + if MSG('E171', "Missing :endif") + let g:messages = g:messages . "A" + endif + + let v:errmsg = "" + XloopINIT! 8192 4 + let loops = 2 + while loops > 0 " 2: 1: + XloopNEXT + let loops = loops - 1 + Xloop 1 " X: 8192 + 8192*4 + if 0 + Xloop 2 " X: 0 + " endif missing + endwhile " :endwhile after :if 0 + Xpath 131072 " X: 8192*4*4 + if MSG('E171', "Missing :endif") + let g:messages = g:messages . "B" + endif + + let v:errmsg = "" + XloopINIT 262144 4 + let loops = 2 + while loops > 0 " 2: 1: + let loops = loops - 1 + Xloop 1 " X: 262144 + 262144 * 4 + " if missing! + endif " :endif without :if in while + Xloop 2 " X: 524288 + 524288 * 4 + XloopNEXT + endwhile + Xpath 4194304 " X: 262144*4*4 + if MSG('E580', ":endif without :if") + let g:messages = g:messages . "C" + endif +endfunction + +call F() + +" Error continuation outside a function is at the outermost :endwhile or :endif. +let v:errmsg = "" +XloopINIT! 8388608 4 +let loops = 2 +while loops > 0 " 2: 1: + XloopNEXT + let loops = loops - 1 + Xloop 1 " X: 8388608 + 0 * 4 + if 0 + Xloop 2 " X: 0 + " endif missing! Following :endwhile fails. +endwhile | Xpath 134217728 " X: 0 +Xpath 268435456 " X: 2*8388608*4*4 +if MSG('E171', "Missing :endif") + let messages = g:messages . "D" +endif + +if messages != "ABCD" + Xpath 536870912 " X: 0 + Xout "messages is" messages "instead of ABCD" +endif + +unlet loops messages +delfunction F +delfunction MSG + +Xcheck 285127993 + + +"------------------------------------------------------------------------------- +" Test 18: Interrupt (Ctrl-C pressed) {{{1 +" +" On an interrupt, the script processing is terminated immediately. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + if 1 + Xpath 1 " X: 1 + while 1 + Xpath 2 " X: 2 + if 1 + Xpath 4 " X: 4 + "INTERRUPT + Xpath 8 " X: 0 + break + finish + endif | Xpath 16 " X: 0 + Xpath 32 " X: 0 + endwhile | Xpath 64 " X: 0 + Xpath 128 " X: 0 + endif | Xpath 256 " X: 0 + Xpath 512 " X: 0 +endif + +if ExtraVim() + try + Xpath 1024 " X: 1024 + "INTERRUPT + Xpath 2048 " X: 0 + endtry | Xpath 4096 " X: 0 + Xpath 8192 " X: 0 +endif + +if ExtraVim() + function! F() + if 1 + Xpath 16384 " X: 16384 + while 1 + Xpath 32768 " X: 32768 + if 1 + Xpath 65536 " X: 65536 + "INTERRUPT + Xpath 131072 " X: 0 + break + return + endif | Xpath 262144 " X: 0 + Xpath Xpath 524288 " X: 0 + endwhile | Xpath 1048576 " X: 0 + Xpath Xpath 2097152 " X: 0 + endif | Xpath Xpath 4194304 " X: 0 + Xpath Xpath 8388608 " X: 0 + endfunction + + call F() | Xpath 16777216 " X: 0 + Xpath 33554432 " X: 0 +endif + +if ExtraVim() + function! G() + try + Xpath 67108864 " X: 67108864 + "INTERRUPT + Xpath 134217728 " X: 0 + endtry | Xpath 268435456 " X: 0 + Xpath 536870912 " X: 0 + endfunction + + call G() | Xpath 1073741824 " X: 0 + " The Xpath command does not accept 2^31 (negative); display explicitly: + exec "!echo 2147483648 >>" . g:ExtraVimResult + " X: 0 +endif + +Xcheck 67224583 + + +"------------------------------------------------------------------------------- +" Test 19: Aborting on errors inside :try/:endtry {{{1 +" +" An error in a command dynamically enclosed in a :try/:endtry region +" aborts script processing immediately. It does not matter whether +" the failing command is outside or inside a function and whether a +" function has an "abort" attribute. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + function! F() abort + Xpath 1 " X: 1 + asdf + Xpath 2 " X: 0 + endfunction + + try + Xpath 4 " X: 4 + call F() + Xpath 8 " X: 0 + endtry | Xpath 16 " X: 0 + Xpath 32 " X: 0 +endif + +if ExtraVim() + function! G() + Xpath 64 " X: 64 + asdf + Xpath 128 " X: 0 + endfunction + + try + Xpath 256 " X: 256 + call G() + Xpath 512 " X: 0 + endtry | Xpath 1024 " X: 0 + Xpath 2048 " X: 0 +endif + +if ExtraVim() + try + Xpath 4096 " X: 4096 + asdf + Xpath 8192 " X: 0 + endtry | Xpath 16384 " X: 0 + Xpath 32768 " X: 0 +endif + +if ExtraVim() + if 1 + try + Xpath 65536 " X: 65536 + asdf + Xpath 131072 " X: 0 + endtry | Xpath 262144 " X: 0 + endif | Xpath 524288 " X: 0 + Xpath 1048576 " X: 0 +endif + +if ExtraVim() + let p = 1 + while p + let p = 0 + try + Xpath 2097152 " X: 2097152 + asdf + Xpath 4194304 " X: 0 + endtry | Xpath 8388608 " X: 0 + endwhile | Xpath 16777216 " X: 0 + Xpath 33554432 " X: 0 +endif + +if ExtraVim() + let p = 1 + while p + let p = 0 +" try + Xpath 67108864 " X: 67108864 + endwhile | Xpath 134217728 " X: 0 + Xpath 268435456 " X: 0 +endif + +Xcheck 69275973 +"------------------------------------------------------------------------------- +" Test 20: Aborting on errors after :try/:endtry {{{1 +" +" When an error occurs after the last active :try/:endtry region has +" been left, termination behavior is as if no :try/:endtry has been +" seen. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + let p = 1 + while p + let p = 0 + try + Xpath 1 " X: 1 + endtry + asdf + endwhile | Xpath 2 " X: 0 + Xpath 4 " X: 4 +endif + +if ExtraVim() + while 1 + try + Xpath 8 " X: 8 + break + Xpath 16 " X: 0 + endtry + endwhile + Xpath 32 " X: 32 + asdf + Xpath 64 " X: 64 +endif + +if ExtraVim() + while 1 + try + Xpath 128 " X: 128 + break + Xpath 256 " X: 0 + finally + Xpath 512 " X: 512 + endtry + endwhile + Xpath 1024 " X: 1024 + asdf + Xpath 2048 " X: 2048 +endif + +if ExtraVim() + while 1 + try + Xpath 4096 " X: 4096 + finally + Xpath 8192 " X: 8192 + break + Xpath 16384 " X: 0 + endtry + endwhile + Xpath 32768 " X: 32768 + asdf + Xpath 65536 " X: 65536 +endif + +if ExtraVim() + let p = 1 + while p + let p = 0 + try + Xpath 131072 " X: 131072 + continue + Xpath 262144 " X: 0 + endtry + endwhile + Xpath 524288 " X: 524288 + asdf + Xpath 1048576 " X: 1048576 +endif + +if ExtraVim() + let p = 1 + while p + let p = 0 + try + Xpath 2097152 " X: 2097152 + continue + Xpath 4194304 " X: 0 + finally + Xpath 8388608 " X: 8388608 + endtry + endwhile + Xpath 16777216 " X: 16777216 + asdf + Xpath 33554432 " X: 33554432 +endif + +if ExtraVim() + let p = 1 + while p + let p = 0 + try + Xpath 67108864 " X: 67108864 + finally + Xpath 134217728 " X: 134217728 + continue + Xpath 268435456 " X: 0 + endtry + endwhile + Xpath 536870912 " X: 536870912 + asdf + Xpath 1073741824 " X: 1073741824 +endif + +Xcheck 1874575085 + + +"------------------------------------------------------------------------------- +" Test 21: :finally for :try after :continue/:break/:return/:finish {{{1 +" +" If a :try conditional stays inactive due to a preceding :continue, +" :break, :return, or :finish, its :finally clause should not be +" executed. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + function F() + let loops = 2 + XloopINIT! 1 256 + while loops > 0 + XloopNEXT + let loops = loops - 1 + try + if loops == 1 + Xloop 1 " X: 1 + continue + Xloop 2 " X: 0 + elseif loops == 0 + Xloop 4 " X: 4*256 + break + Xloop 8 " X: 0 + endif + + try " inactive + Xloop 16 " X: 0 + finally + Xloop 32 " X: 0 + endtry + finally + Xloop 64 " X: 64 + 64*256 + endtry + Xloop 128 " X: 0 + endwhile + + try + Xpath 65536 " X: 65536 + return + Xpath 131072 " X: 0 + try " inactive + Xpath 262144 " X: 0 + finally + Xpath 524288 " X: 0 + endtry + finally + Xpath 1048576 " X: 1048576 + endtry + Xpath 2097152 " X: 0 + endfunction + + try + Xpath 4194304 " X: 4194304 + call F() + Xpath 8388608 " X: 8388608 + finish + Xpath 16777216 " X: 0 + try " inactive + Xpath 33554432 " X: 0 + finally + Xpath 67108864 " X: 0 + endtry + finally + Xpath 134217728 " X: 134217728 + endtry + Xpath 268435456 " X: 0 +endif + +Xcheck 147932225 + + +"------------------------------------------------------------------------------- +" Test 22: :finally for a :try after an error/interrupt/:throw {{{1 +" +" If a :try conditional stays inactive due to a preceding error or +" interrupt or :throw, its :finally clause should not be executed. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + function! Error() + try + asdf " aborting error, triggering error exception + endtry + endfunction + + Xpath 1 " X: 1 + call Error() + Xpath 2 " X: 0 + + if 1 " not active due to error + try " not active since :if inactive + Xpath 4 " X: 0 + finally + Xpath 8 " X: 0 + endtry + endif + + try " not active due to error + Xpath 16 " X: 0 + finally + Xpath 32 " X: 0 + endtry +endif + +if ExtraVim() + function! Interrupt() + try + "INTERRUPT " triggering interrupt exception + endtry + endfunction + + Xpath 64 " X: 64 + call Interrupt() + Xpath 128 " X: 0 + + if 1 " not active due to interrupt + try " not active since :if inactive + Xpath 256 " X: 0 + finally + Xpath 512 " X: 0 + endtry + endif + + try " not active due to interrupt + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 0 + endtry +endif + +if ExtraVim() + function! Throw() + throw "xyz" + endfunction + + Xpath 4096 " X: 4096 + call Throw() + Xpath 8192 " X: 0 + + if 1 " not active due to :throw + try " not active since :if inactive + Xpath 16384 " X: 0 + finally + Xpath 32768 " X: 0 + endtry + endif + + try " not active due to :throw + Xpath 65536 " X: 0 + finally + Xpath 131072 " X: 0 + endtry +endif + +Xcheck 4161 + + +"------------------------------------------------------------------------------- +" Test 23: :catch clauses for a :try after a :throw {{{1 +" +" If a :try conditional stays inactive due to a preceding :throw, +" none of its :catch clauses should be executed. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + try + Xpath 1 " X: 1 + throw "xyz" + Xpath 2 " X: 0 + + if 1 " not active due to :throw + try " not active since :if inactive + Xpath 4 " X: 0 + catch /xyz/ + Xpath 8 " X: 0 + endtry + endif + catch /xyz/ + Xpath 16 " X: 16 + endtry + + Xpath 32 " X: 32 + throw "abc" + Xpath 64 " X: 0 + + try " not active due to :throw + Xpath 128 " X: 0 + catch /abc/ + Xpath 256 " X: 0 + endtry +endif + +Xcheck 49 + + +"------------------------------------------------------------------------------- +" Test 24: :endtry for a :try after a :throw {{{1 +" +" If a :try conditional stays inactive due to a preceding :throw, +" its :endtry should not rethrow the exception to the next surrounding +" active :try conditional. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + try " try 1 + try " try 2 + Xpath 1 " X: 1 + throw "xyz" " makes try 2 inactive + Xpath 2 " X: 0 + + try " try 3 + Xpath 4 " X: 0 + endtry " no rethrow to try 1 + catch /xyz/ " should catch although try 2 inactive + Xpath 8 " X: 8 + endtry + catch /xyz/ " try 1 active, but exception already caught + Xpath 16 " X: 0 + endtry + Xpath 32 " X: 32 +endif + +Xcheck 41 + + +"------------------------------------------------------------------------------- +" Test 25: Executing :finally clauses on normal control flow {{{1 +" +" Control flow in a :try conditional should always fall through to its +" :finally clause. A :finally clause of a :try conditional inside an +" inactive conditional should never be executed. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() + let loops = 3 + XloopINIT 1 256 + while loops > 0 " 3: 2: 1: + Xloop 1 " X: 1 + 1*256 + 1*256*256 + if loops >= 2 + try + Xloop 2 " X: 2 + 2*256 + if loops == 2 + try + Xloop 4 " X: 4*256 + finally + Xloop 8 " X: 8*256 + endtry + endif + finally + Xloop 16 " X: 16 + 16*256 + if loops == 2 + try + Xloop 32 " X: 32*256 + finally + Xloop 64 " X: 64*256 + endtry + endif + endtry + endif + Xloop 128 " X: 128 + 128*256 + 128*256*256 + let loops = loops - 1 + XloopNEXT + endwhile + Xpath 16777216 " X: 16777216 +endfunction + +if 1 + try + Xpath 33554432 " X: 33554432 + call F() + Xpath 67108864 " X: 67108864 + finally + Xpath 134217728 " X: 134217728 + endtry +else + try + Xpath 268435456 " X: 0 + finally + Xpath 536870912 " X: 0 + endtry +endif + +delfunction F + +Xcheck 260177811 + + +"------------------------------------------------------------------------------- +" Test 26: Executing :finally clauses after :continue or :break {{{1 +" +" For a :continue or :break dynamically enclosed in a :try/:endtry +" region inside the next surrounding :while/:endwhile, if the +" :continue/:break is before the :finally, the :finally clause is +" executed first. If the :continue/:break is after the :finally, the +" :finally clause is broken (like an :if/:endif region). +"------------------------------------------------------------------------------- + +XpathINIT + +try + let loops = 3 + XloopINIT! 1 32 + while loops > 0 + XloopNEXT + try + try + if loops == 2 " 3: 2: 1: + Xloop 1 " X: 1*32 + let loops = loops - 1 + continue + elseif loops == 1 + Xloop 2 " X: 2*32*32 + break + finish + endif + Xloop 4 " X: 4 + endtry + finally + Xloop 8 " X: 8 + 8*32 + 8*32*32 + endtry + Xloop 16 " X: 16 + let loops = loops - 1 + endwhile + Xpath 32768 " X: 32768 +finally + Xpath 65536 " X: 65536 + let loops = 3 + XloopINIT 131072 16 + while loops > 0 + try + finally + try + if loops == 2 + Xloop 1 " X: 131072*16 + let loops = loops - 1 + XloopNEXT + continue + elseif loops == 1 + Xloop 2 " X: 131072*2*16*16 + break + finish + endif + endtry + Xloop 4 " X: 131072*4 + endtry + Xloop 8 " X: 131072*8 + let loops = loops - 1 + XloopNEXT + endwhile + Xpath 536870912 " X: 536870912 +endtry +Xpath 1073741824 " X: 1073741824 + +unlet loops + +Xcheck 1681500476 + + +"------------------------------------------------------------------------------- +" Test 27: Executing :finally clauses after :return {{{1 +" +" For a :return command dynamically enclosed in a :try/:endtry region, +" :finally clauses are executed and the called function is ended. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() + try + Xpath 1 " X: 1 + try + Xpath 2 " X: 2 + return + Xpath 4 " X: 0 + finally + Xpath 8 " X: 8 + endtry + Xpath 16 " X: 0 + finally + Xpath 32 " X: 32 + endtry + Xpath 64 " X: 0 +endfunction + +function! G() + try + Xpath 128 " X: 128 + return + Xpath 256 " X: 0 + finally + Xpath 512 " X: 512 + call F() + Xpath 1024 " X: 1024 + endtry + Xpath 2048 " X: 0 +endfunction + +function! H() + try + Xpath 4096 " X: 4096 + call G() + Xpath 8192 " X: 8192 + finally + Xpath 16384 " X: 16384 + return + Xpath 32768 " X: 0 + endtry + Xpath 65536 " X: 0 +endfunction + +try + Xpath 131072 " X: 131072 + call H() + Xpath 262144 " X: 262144 +finally + Xpath 524288 " X: 524288 +endtry +Xpath 1048576 " X: 1048576 + +Xcheck 1996459 + +" Leave F, G, and H for execution as scripts in the next test. + + +"------------------------------------------------------------------------------- +" Test 28: Executing :finally clauses after :finish {{{1 +" +" For a :finish command dynamically enclosed in a :try/:endtry region, +" :finally clauses are executed and the sourced file is finished. +" +" This test executes the bodies of the functions F, G, and H from the +" previous test as script files (:return replaced by :finish). +"------------------------------------------------------------------------------- + +XpathINIT + +let scriptF = MakeScript("F") " X: 1 + 2 + 8 + 32 +let scriptG = MakeScript("G", scriptF) " X: 128 + 512 + 1024 +let scriptH = MakeScript("H", scriptG) " X: 4096 + 8192 + 16384 + +try + Xpath 131072 " X: 131072 + exec "source" scriptH + Xpath 262144 " X: 262144 +finally + Xpath 524288 " X: 524288 +endtry +Xpath 1048576 " X: 1048576 + +call delete(scriptF) +call delete(scriptG) +call delete(scriptH) +unlet scriptF scriptG scriptH +delfunction F +delfunction G +delfunction H + +Xcheck 1996459 + + +"------------------------------------------------------------------------------- +" Test 29: Executing :finally clauses on errors {{{1 +" +" After an error in a command dynamically enclosed in a :try/:endtry +" region, :finally clauses are executed and the script processing is +" terminated. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + function! F() + while 1 + try + Xpath 1 " X: 1 + while 1 + try + Xpath 2 " X: 2 + asdf " error + Xpath 4 " X: 0 + finally + Xpath 8 " X: 8 + endtry | Xpath 16 " X: 0 + Xpath 32 " X: 0 + break + endwhile + Xpath 64 " X: 0 + finally + Xpath 128 " X: 128 + endtry | Xpath 256 " X: 0 + Xpath 512 " X: 0 + break + endwhile + Xpath 1024 " X: 0 + endfunction + + while 1 + try + Xpath 2048 " X: 2048 + while 1 + call F() + Xpath 4096 " X: 0 + break + endwhile | Xpath 8192 " X: 0 + Xpath 16384 " X: 0 + finally + Xpath 32768 " X: 32768 + endtry | Xpath 65536 " X: 0 + endwhile | Xpath 131072 " X: 0 + Xpath 262144 " X: 0 +endif + +if ExtraVim() + function! G() abort + if 1 + try + Xpath 524288 " X: 524288 + asdf " error + Xpath 1048576 " X: 0 + finally + Xpath 2097152 " X: 2097152 + endtry | Xpath 4194304 " X: 0 + endif | Xpath 8388608 " X: 0 + Xpath 16777216 " X: 0 + endfunction + + if 1 + try + Xpath 33554432 " X: 33554432 + call G() + Xpath 67108864 " X: 0 + finally + Xpath 134217728 " X: 134217728 + endtry | Xpath 268435456 " X: 0 + endif | Xpath 536870912 " X: 0 + Xpath 1073741824 " X: 0 +endif + +Xcheck 170428555 + + +"------------------------------------------------------------------------------- +" Test 30: Executing :finally clauses on interrupt {{{1 +" +" After an interrupt in a command dynamically enclosed in +" a :try/:endtry region, :finally clauses are executed and the +" script processing is terminated. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + XloopINIT 1 16 + + function! F() + try + Xloop 1 " X: 1 + 1*16 + "INTERRUPT + Xloop 2 " X: 0 + finally + Xloop 4 " X: 4 + 4*16 + endtry + Xloop 8 " X: 0 + endfunction + + try + Xpath 256 " X: 256 + try + Xpath 512 " X: 512 + "INTERRUPT + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 2048 + try + Xpath 4096 " X: 4096 + try + Xpath 8192 " X: 8192 + finally + Xpath 16384 " X: 16384 + try + Xpath 32768 " X: 32768 + "INTERRUPT + Xpath 65536 " X: 0 + endtry + Xpath 131072 " X: 0 + endtry + Xpath 262144 " X: 0 + endtry + Xpath 524288 " X: 0 + endtry + Xpath 1048576 " X: 0 + finally + Xpath 2097152 " X: 2097152 + try + Xpath 4194304 " X: 4194304 + call F() + Xpath 8388608 " X: 0 + finally + Xpath 16777216 " X: 16777216 + try + Xpath 33554432 " X: 33554432 + XloopNEXT + ExecAsScript F + Xpath 67108864 " X: 0 + finally + Xpath 134217728 " X: 134217728 + endtry + Xpath 268435456 " X: 0 + endtry + Xpath 536870912 " X: 0 + endtry + Xpath 1073741824 " X: 0 +endif + +Xcheck 190905173 + + +"------------------------------------------------------------------------------- +" Test 31: Executing :finally clauses after :throw {{{1 +" +" After a :throw dynamically enclosed in a :try/:endtry region, +" :finally clauses are executed and the script processing is +" terminated. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + XloopINIT 1 16 + + function! F() + try + Xloop 1 " X: 1 + 1*16 + throw "exception" + Xloop 2 " X: 0 + finally + Xloop 4 " X: 4 + 4*16 + endtry + Xloop 8 " X: 0 + endfunction + + try + Xpath 256 " X: 256 + try + Xpath 512 " X: 512 + throw "exception" + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 2048 + try + Xpath 4096 " X: 4096 + try + Xpath 8192 " X: 8192 + finally + Xpath 16384 " X: 16384 + try + Xpath 32768 " X: 32768 + throw "exception" + Xpath 65536 " X: 0 + endtry + Xpath 131072 " X: 0 + endtry + Xpath 262144 " X: 0 + endtry + Xpath 524288 " X: 0 + endtry + Xpath 1048576 " X: 0 + finally + Xpath 2097152 " X: 2097152 + try + Xpath 4194304 " X: 4194304 + call F() + Xpath 8388608 " X: 0 + finally + Xpath 16777216 " X: 16777216 + try + Xpath 33554432 " X: 33554432 + XloopNEXT + ExecAsScript F + Xpath 67108864 " X: 0 + finally + Xpath 134217728 " X: 134217728 + endtry + Xpath 268435456 " X: 0 + endtry + Xpath 536870912 " X: 0 + endtry + Xpath 1073741824 " X: 0 +endif + +Xcheck 190905173 + + +"------------------------------------------------------------------------------- +" Test 32: Remembering the :return value on :finally {{{1 +" +" If a :finally clause is executed due to a :return specifying +" a value, this is the value visible to the caller if not overwritten +" by a new :return in the :finally clause. A :return without a value +" in the :finally clause overwrites with value 0. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() + try + Xpath 1 " X: 1 + try + Xpath 2 " X: 2 + return "ABCD" + Xpath 4 " X: 0 + finally + Xpath 8 " X: 8 + endtry + Xpath 16 " X: 0 + finally + Xpath 32 " X: 32 + endtry + Xpath 64 " X: 0 +endfunction + +function! G() + try + Xpath 128 " X: 128 + return 8 + Xpath 256 " X: 0 + finally + Xpath 512 " X: 512 + return 16 + strlen(F()) + Xpath 1024 " X: 0 + endtry + Xpath 2048 " X: 0 +endfunction + +function! H() + try + Xpath 4096 " X: 4096 + return 32 + Xpath 8192 " X: 0 + finally + Xpath 16384 " X: 16384 + return + Xpath 32768 " X: 0 + endtry + Xpath 65536 " X: 0 +endfunction + +function! I() + try + Xpath 131072 " X: 131072 + finally + Xpath 262144 " X: 262144 + return G() + H() + 64 + Xpath 524288 " X: 0 + endtry + Xpath 1048576 " X: 0 +endfunction + +let retcode = I() +Xpath 2097152 " X: 2097152 + +if retcode < 0 + Xpath 4194304 " X: 0 +endif +if retcode % 4 + Xpath 8388608 " X: 0 +endif +if (retcode/4) % 2 + Xpath 16777216 " X: 16777216 +endif +if (retcode/8) % 2 + Xpath 33554432 " X: 0 +endif +if (retcode/16) % 2 + Xpath 67108864 " X: 67108864 +endif +if (retcode/32) % 2 + Xpath 134217728 " X: 0 +endif +if (retcode/64) % 2 + Xpath 268435456 " X: 268435456 +endif +if retcode/128 + Xpath 536870912 " X: 0 +endif + +unlet retcode +delfunction F +delfunction G +delfunction H +delfunction I + +Xcheck 354833067 + + +"------------------------------------------------------------------------------- +" Test 33: :return under :execute or user command and :finally {{{1 +" +" A :return command may be executed under an ":execute" or from +" a user command. Executing of :finally clauses and passing through +" the return code works also then. +"------------------------------------------------------------------------------- +XpathINIT + +command! -nargs=? RETURN + \ try | return <args> | finally | return <args> * 2 | endtry + +function! F() + try + RETURN 8 + Xpath 1 " X: 0 + finally + Xpath 2 " X: 2 + endtry + Xpath 4 " X: 0 +endfunction + +function! G() + try + RETURN 32 + Xpath 8 " X: 0 + finally + Xpath 16 " X: 16 + RETURN 128 + Xpath 32 " X: 0 + endtry + Xpath 64 " X: 0 +endfunction + +function! H() + try + execute "try | return 512 | finally | return 1024 | endtry" + Xpath 128 " X: 0 + finally + Xpath 256 " X: 256 + endtry + Xpath 512 " X: 0 +endfunction + +function! I() + try + execute "try | return 2048 | finally | return 4096 | endtry" + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 2048 + execute "try | return 8192 | finally | return 16384 | endtry" + Xpath 4096 " X: 0 + endtry + Xpath 8192 " X: 0 +endfunction + +function! J() + try + RETURN 32768 + Xpath 16384 " X: 0 + finally + Xpath 32768 " X: 32768 + return + Xpath 65536 " X: 0 + endtry + Xpath 131072 " X: 0 +endfunction + +function! K() + try + execute "try | return 131072 | finally | return 262144 | endtry" + Xpath 262144 " X: 0 + finally + Xpath 524288 " X: 524288 + execute "try | return 524288 | finally | return | endtry" + Xpath 1048576 " X: 0 + endtry + Xpath 2097152 " X: 0 +endfunction + +function! L() + try + return + Xpath 4194304 " X: 0 + finally + Xpath 8388608 " X: 8388608 + RETURN 1048576 + Xpath 16777216 " X: 0 + endtry + Xpath 33554432 " X: 0 +endfunction + +function! M() + try + return + Xpath 67108864 " X: 0 + finally + Xpath 134217728 " X: 134217728 + execute "try | return 4194304 | finally | return 8388608 | endtry" + Xpath 268435456 " X: 0 + endtry + Xpath 536870912 " X: 0 +endfunction + +function! N() + RETURN 16777216 +endfunction + +function! O() + execute "try | return 67108864 | finally | return 134217728 | endtry" +endfunction + +let sum = F() + G() + H() + I() + J() + K() + L() + M() +let expected = 16 + 256 + 1024 + 16384 + 0 + 0 + 2097152 + 8388608 +let sum = sum + N() + O() +let expected = expected + 33554432 + 134217728 + +if sum == expected + Xout "sum = " . sum . " (ok)" +else + Xout "sum = " . sum . ", expected: " . expected +endif + +Xpath 1073741824 " X: 1073741824 + +if sum != expected + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 +endif + +unlet sum expected +delfunction F +delfunction G +delfunction H +delfunction I +delfunction J +delfunction K +delfunction L +delfunction M +delfunction N +delfunction O + +Xcheck 1216907538 + + +"------------------------------------------------------------------------------- +" Test 34: :finally reason discarded by :continue {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :continue in the finally clause. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 8 + + function! C(jump) + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + continue " discards jump that caused the :finally + Xloop 1 " X: 0 + endtry + Xloop 2 " X: 0 + elseif loop == 2 + Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144) + endif + endwhile + endfunction + + call C("continue") + Xpath 2097152 " X: 2097152 + call C("break") + Xpath 4194304 " X: 4194304 + call C("return") + Xpath 8388608 " X: 8388608 + let g:jump = "finish" + ExecAsScript C + unlet g:jump + Xpath 16777216 " X: 16777216 + try + call C("error") + Xpath 33554432 " X: 33554432 + finally + Xpath 67108864 " X: 67108864 + try + call C("interrupt") + Xpath 134217728 " X: 134217728 + finally + Xpath 268435456 " X: 268435456 + call C("throw") + Xpath 536870912 " X: 536870912 + endtry + endtry + Xpath 1073741824 " X: 1073741824 + + delfunction C + +endif + +Xcheck 2146584868 + + +"------------------------------------------------------------------------------- +" Test 35: :finally reason discarded by :break {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :break in the finally clause. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 8 + + function! B(jump) + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + break " discards jump that caused the :finally + Xloop 1 " X: 0 + endtry + elseif loop == 2 + Xloop 2 " X: 0 + endif + endwhile + Xloop 4 " X: 4*(1+8+64+512+4096+32768+262144) + endfunction + + call B("continue") + Xpath 2097152 " X: 2097152 + call B("break") + Xpath 4194304 " X: 4194304 + call B("return") + Xpath 8388608 " X: 8388608 + let g:jump = "finish" + ExecAsScript B + unlet g:jump + Xpath 16777216 " X: 16777216 + try + call B("error") + Xpath 33554432 " X: 33554432 + finally + Xpath 67108864 " X: 67108864 + try + call B("interrupt") + Xpath 134217728 " X: 134217728 + finally + Xpath 268435456 " X: 268435456 + call B("throw") + Xpath 536870912 " X: 536870912 + endtry + endtry + Xpath 1073741824 " X: 1073741824 + + delfunction B + +endif + +Xcheck 2146584868 + + +"------------------------------------------------------------------------------- +" Test 36: :finally reason discarded by :return {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :return in the finally clause. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 8 + + function! R(jump, retval) abort + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + return a:retval " discards jump that caused the :finally + Xloop 1 " X: 0 + endtry + elseif loop == 2 + Xloop 2 " X: 0 + endif + endwhile + Xloop 4 " X: 0 + endfunction + + let sum = -R("continue", -8) + Xpath 2097152 " X: 2097152 + let sum = sum - R("break", -16) + Xpath 4194304 " X: 4194304 + let sum = sum - R("return", -32) + Xpath 8388608 " X: 8388608 + try + let sum = sum - R("error", -64) + Xpath 16777216 " X: 16777216 + finally + Xpath 33554432 " X: 33554432 + try + let sum = sum - R("interrupt", -128) + Xpath 67108864 " X: 67108864 + finally + Xpath 134217728 " X: 134217728 + let sum = sum - R("throw", -256) + Xpath 268435456 " X: 268435456 + endtry + endtry + Xpath 536870912 " X: 536870912 + + let expected = 8 + 16 + 32 + 64 + 128 + 256 + if sum != expected + Xpath 1073741824 " X: 0 + Xout "sum =" . sum . ", expected: " . expected + endif + + unlet sum expected + delfunction R + +endif + +Xcheck 1071644672 + + +"------------------------------------------------------------------------------- +" Test 37: :finally reason discarded by :finish {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :finish in the finally clause. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 8 + + function! F(jump) " not executed as function, transformed to a script + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "finish" + finish + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + finish " discards jump that caused the :finally + Xloop 1 " X: 0 + endtry + elseif loop == 2 + Xloop 2 " X: 0 + endif + endwhile + Xloop 4 " X: 0 + endfunction + + let scriptF = MakeScript("F") + delfunction F + + let g:jump = "continue" + exec "source" scriptF + Xpath 2097152 " X: 2097152 + let g:jump = "break" + exec "source" scriptF + Xpath 4194304 " X: 4194304 + let g:jump = "finish" + exec "source" scriptF + Xpath 8388608 " X: 8388608 + try + let g:jump = "error" + exec "source" scriptF + Xpath 16777216 " X: 16777216 + finally + Xpath 33554432 " X: 33554432 + try + let g:jump = "interrupt" + exec "source" scriptF + Xpath 67108864 " X: 67108864 + finally + Xpath 134217728 " X: 134217728 + try + let g:jump = "throw" + exec "source" scriptF + Xpath 268435456 " X: 268435456 + finally + Xpath 536870912 " X: 536870912 + endtry + endtry + endtry + unlet g:jump + + call delete(scriptF) + unlet scriptF + +endif + +Xcheck 1071644672 + + +"------------------------------------------------------------------------------- +" Test 38: :finally reason discarded by an error {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by an error in the finally clause. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 4 + + function! E(jump) + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + asdf " error; discards jump that caused the :finally + endtry + elseif loop == 2 + Xloop 1 " X: 0 + endif + endwhile + Xloop 2 " X: 0 + endfunction + + try + Xpath 16384 " X: 16384 + call E("continue") + Xpath 32768 " X: 0 + finally + try + Xpath 65536 " X: 65536 + call E("break") + Xpath 131072 " X: 0 + finally + try + Xpath 262144 " X: 262144 + call E("return") + Xpath 524288 " X: 0 + finally + try + Xpath 1048576 " X: 1048576 + let g:jump = "finish" + ExecAsScript E + Xpath 2097152 " X: 0 + finally + unlet g:jump + try + Xpath 4194304 " X: 4194304 + call E("error") + Xpath 8388608 " X: 0 + finally + try + Xpath 16777216 " X: 16777216 + call E("interrupt") + Xpath 33554432 " X: 0 + finally + try + Xpath 67108864 " X: 67108864 + call E("throw") + Xpath 134217728 " X: 0 + finally + Xpath 268435456 " X: 268435456 + delfunction E + endtry + endtry + endtry + endtry + endtry + endtry + endtry + Xpath 536870912 " X: 0 + +endif + +Xcheck 357908480 + + +"------------------------------------------------------------------------------- +" Test 39: :finally reason discarded by an interrupt {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by an interrupt in the finally clause. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 4 + + function! I(jump) + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + "INTERRUPT - discards jump that caused the :finally + let dummy = 0 + endtry + elseif loop == 2 + Xloop 1 " X: 0 + endif + endwhile + Xloop 2 " X: 0 + endfunction + + try + Xpath 16384 " X: 16384 + call I("continue") + Xpath 32768 " X: 0 + finally + try + Xpath 65536 " X: 65536 + call I("break") + Xpath 131072 " X: 0 + finally + try + Xpath 262144 " X: 262144 + call I("return") + Xpath 524288 " X: 0 + finally + try + Xpath 1048576 " X: 1048576 + let g:jump = "finish" + ExecAsScript I + Xpath 2097152 " X: 0 + finally + unlet g:jump + try + Xpath 4194304 " X: 4194304 + call I("error") + Xpath 8388608 " X: 0 + finally + try + Xpath 16777216 " X: 16777216 + call I("interrupt") + Xpath 33554432 " X: 0 + finally + try + Xpath 67108864 " X: 67108864 + call I("throw") + Xpath 134217728 " X: 0 + finally + Xpath 268435456 " X: 268435456 + delfunction I + endtry + endtry + endtry + endtry + endtry + endtry + endtry + Xpath 536870912 " X: 0 + +endif + +Xcheck 357908480 + + +"------------------------------------------------------------------------------- +" Test 40: :finally reason discarded by :throw {{{1 +" +" When a :finally clause is executed due to a :continue, :break, +" :return, :finish, error, interrupt or :throw, the jump reason is +" discarded by a :throw in the finally clause. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 4 + + function! T(jump) + XloopNEXT + let loop = 0 + while loop < 2 + let loop = loop + 1 + if loop == 1 + try + if a:jump == "continue" + continue + elseif a:jump == "break" + break + elseif a:jump == "return" || a:jump == "finish" + return + elseif a:jump == "error" + asdf + elseif a:jump == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:jump == "throw" + throw "abc" + endif + finally + throw "xyz" " discards jump that caused the :finally + endtry + elseif loop == 2 + Xloop 1 " X: 0 + endif + endwhile + Xloop 2 " X: 0 + endfunction + + try + Xpath 16384 " X: 16384 + call T("continue") + Xpath 32768 " X: 0 + finally + try + Xpath 65536 " X: 65536 + call T("break") + Xpath 131072 " X: 0 + finally + try + Xpath 262144 " X: 262144 + call T("return") + Xpath 524288 " X: 0 + finally + try + Xpath 1048576 " X: 1048576 + let g:jump = "finish" + ExecAsScript T + Xpath 2097152 " X: 0 + finally + unlet g:jump + try + Xpath 4194304 " X: 4194304 + call T("error") + Xpath 8388608 " X: 0 + finally + try + Xpath 16777216 " X: 16777216 + call T("interrupt") + Xpath 33554432 " X: 0 + finally + try + Xpath 67108864 " X: 67108864 + call T("throw") + Xpath 134217728 " X: 0 + finally + Xpath 268435456 " X: 268435456 + delfunction T + endtry + endtry + endtry + endtry + endtry + endtry + endtry + Xpath 536870912 " X: 0 + +endif + +Xcheck 357908480 + + +"------------------------------------------------------------------------------- +" Test 41: Skipped :throw finding next command {{{1 +" +" A :throw in an inactive conditional must not hide a following +" command. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F() + Xpath 1 " X: 1 + if 0 | throw "never" | endif | Xpath 2 " X: 2 + Xpath 4 " X: 4 +endfunction + +function! G() + Xpath 8 " X: 8 + while 0 | throw "never" | endwhile | Xpath 16 " X: 16 + Xpath 32 " X: 32 +endfunction + +function H() + Xpath 64 " X: 64 + if 0 | try | throw "never" | endtry | endif | Xpath 128 " X: 128 + Xpath 256 " X: 256 +endfunction + +Xpath 512 " X: 512 + +try + Xpath 1024 " X: 1024 + call F() + Xpath 2048 " X: 2048 +catch /.*/ + Xpath 4096 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xpath 8192 " X: 8192 + +try + Xpath 16384 " X: 16384 + call G() + Xpath 32768 " X: 32768 +catch /.*/ + Xpath 65536 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xpath 131072 " X: 131072 + +try + Xpath 262144 " X: 262144 + call H() + Xpath 524288 " X: 524288 +catch /.*/ + Xpath 1048576 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xpath 2097152 " X: 2097152 + +delfunction F +delfunction G +delfunction H + +Xcheck 3076095 + + +"------------------------------------------------------------------------------- +" Test 42: Catching number and string exceptions {{{1 +" +" When a number is thrown, it is converted to a string exception. +" Numbers and strings may be caught by specifying a regular exception +" as argument to the :catch command. +"------------------------------------------------------------------------------- + +XpathINIT + +try + + try + Xpath 1 " X: 1 + throw 4711 + Xpath 2 " X: 0 + catch /4711/ + Xpath 4 " X: 4 + endtry + + try + Xpath 8 " X: 8 + throw 4711 + Xpath 16 " X: 0 + catch /^4711$/ + Xpath 32 " X: 32 + endtry + + try + Xpath 64 " X: 64 + throw 4711 + Xpath 128 " X: 0 + catch /\d/ + Xpath 256 " X: 256 + endtry + + try + Xpath 512 " X: 512 + throw 4711 + Xpath 1024 " X: 0 + catch /^\d\+$/ + Xpath 2048 " X: 2048 + endtry + + try + Xpath 4096 " X: 4096 + throw "arrgh" + Xpath 8192 " X: 0 + catch /arrgh/ + Xpath 16384 " X: 16384 + endtry + + try + Xpath 32768 " X: 32768 + throw "arrgh" + Xpath 65536 " X: 0 + catch /^arrgh$/ + Xpath 131072 " X: 131072 + endtry + + try + Xpath 262144 " X: 262144 + throw "arrgh" + Xpath 524288 " X: 0 + catch /\l/ + Xpath 1048576 " X: 1048576 + endtry + + try + Xpath 2097152 " X: 2097152 + throw "arrgh" + Xpath 4194304 " X: 0 + catch /^\l\+$/ + Xpath 8388608 " X: 8388608 + endtry + + try + try + Xpath 16777216 " X: 16777216 + throw "ARRGH" + Xpath 33554432 " X: 0 + catch /^arrgh$/ + Xpath 67108864 " X: 0 + endtry + catch /^\carrgh$/ + Xpath 134217728 " X: 134217728 + endtry + + try + Xpath 268435456 " X: 268435456 + throw "" + Xpath 536870912 " X: 0 + catch /^$/ + Xpath 1073741824 " X: 1073741824 + endtry + +catch /.*/ + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xcheck 1505155949 + + +"------------------------------------------------------------------------------- +" Test 43: Selecting the correct :catch clause {{{1 +" +" When an exception is thrown and there are multiple :catch clauses, +" the first matching one is taken. +"------------------------------------------------------------------------------- + +XpathINIT + +XloopINIT 1 1024 +let loops = 3 +while loops > 0 + try + if loops == 3 + Xloop 1 " X: 1 + throw "a" + Xloop 2 " X: 0 + elseif loops == 2 + Xloop 4 " X: 4*1024 + throw "ab" + Xloop 8 " X: 0 + elseif loops == 1 + Xloop 16 " X: 16*1024*1024 + throw "abc" + Xloop 32 " X: 0 + endif + catch /abc/ + Xloop 64 " X: 64*1024*1024 + catch /ab/ + Xloop 128 " X: 128*1024 + catch /.*/ + Xloop 256 " X: 256 + catch /a/ + Xloop 512 " X: 0 + endtry + + let loops = loops - 1 + XloopNEXT +endwhile +Xpath 1073741824 " X: 1073741824 + +unlet loops + +Xcheck 1157763329 + + +"------------------------------------------------------------------------------- +" Test 44: Missing or empty :catch patterns {{{1 +" +" A missing or empty :catch pattern means the same as /.*/, that is, +" catches everything. To catch only empty exceptions, /^$/ must be +" used. A :catch with missing, empty, or /.*/ argument also works +" when followed by another command separated by a bar on the same +" line. :catch patterns cannot be specified between ||. But other +" pattern separators can be used instead of //. +"------------------------------------------------------------------------------- + +XpathINIT + +try + try + Xpath 1 " X: 1 + throw "" + catch /^$/ + Xpath 2 " X: 2 + endtry + + try + Xpath 4 " X: 4 + throw "" + catch /.*/ + Xpath 8 " X: 8 + endtry + + try + Xpath 16 " X: 16 + throw "" + catch // + Xpath 32 " X: 32 + endtry + + try + Xpath 64 " X: 64 + throw "" + catch + Xpath 128 " X: 128 + endtry + + try + Xpath 256 " X: 256 + throw "oops" + catch /^$/ + Xpath 512 " X: 0 + catch /.*/ + Xpath 1024 " X: 1024 + endtry + + try + Xpath 2048 " X: 2048 + throw "arrgh" + catch /^$/ + Xpath 4096 " X: 0 + catch // + Xpath 8192 " X: 8192 + endtry + + try + Xpath 16384 " X: 16384 + throw "brrr" + catch /^$/ + Xpath 32768 " X: 0 + catch + Xpath 65536 " X: 65536 + endtry + + try | Xpath 131072 | throw "x" | catch /.*/ | Xpath 262144 | endtry + " X: 131072 + 262144 + + try | Xpath 524288 | throw "y" | catch // | Xpath 1048576 | endtry + " X: 524288 + 1048576 + + while 1 + try + let caught = 0 + let v:errmsg = "" + " Extra try level: if ":catch" without arguments below raises + " a syntax error because it misinterprets the "Xpath" as a pattern, + " let it be caught by the ":catch /.*/" below. + try + try | Xpath 2097152 | throw "z" | catch | Xpath 4194304 | : + endtry " X: 2097152 + 4194304 + endtry + catch /.*/ + let caught = 1 + Xout v:exception "in" v:throwpoint + finally + if $VIMNOERRTHROW && v:errmsg != "" + Xout v:errmsg + endif + if caught || $VIMNOERRTHROW && v:errmsg != "" + Xpath 8388608 " X: 0 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + let cologne = 4711 + try + try + Xpath 16777216 " X: 16777216 + throw "throw cologne" + " Next lines catches all and throws 4711: + catch |throw cologne| + Xpath 33554432 " X: 0 + endtry + catch /4711/ + Xpath 67108864 " X: 67108864 + endtry + + try + Xpath 134217728 " X: 134217728 + throw "plus" + catch +plus+ + Xpath 268435456 " X: 268435456 + endtry + + Xpath 536870912 " X: 536870912 +catch /.*/ + Xpath 1073741824 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +unlet! caught cologne + +Xcheck 1031761407 + + +"------------------------------------------------------------------------------- +" Test 45: Catching exceptions from nested :try blocks {{{1 +" +" When :try blocks are nested, an exception is caught by the innermost +" try conditional that has a matching :catch clause. +"------------------------------------------------------------------------------- + +XpathINIT + +XloopINIT 1 1024 +let loops = 3 +while loops > 0 + try + try + try + try + if loops == 3 + Xloop 1 " X: 1 + throw "a" + Xloop 2 " X: 0 + elseif loops == 2 + Xloop 4 " X: 4*1024 + throw "ab" + Xloop 8 " X: 0 + elseif loops == 1 + Xloop 16 " X: 16*1024*1024 + throw "abc" + Xloop 32 " X: 0 + endif + catch /abc/ + Xloop 64 " X: 64*1024*1024 + endtry + catch /ab/ + Xloop 128 " X: 128*1024 + endtry + catch /.*/ + Xloop 256 " X: 256 + endtry + catch /a/ + Xloop 512 " X: 0 + endtry + + let loops = loops - 1 + XloopNEXT +endwhile +Xpath 1073741824 " X: 1073741824 + +unlet loops + +Xcheck 1157763329 + + +"------------------------------------------------------------------------------- +" Test 46: Executing :finally after a :throw in nested :try {{{1 +" +" When an exception is thrown from within nested :try blocks, the +" :finally clauses of the non-catching try conditionals should be +" executed before the matching :catch of the next surrounding :try +" gets the control. If this also has a :finally clause, it is +" executed afterwards. +"------------------------------------------------------------------------------- + +XpathINIT + +let sum = 0 + +try + Xpath 1 " X: 1 + try + Xpath 2 " X: 2 + try + Xpath 4 " X: 4 + try + Xpath 8 " X: 8 + throw "ABC" + Xpath 16 " X: 0 + catch /xyz/ + Xpath 32 " X: 0 + finally + Xpath 64 " X: 64 + if sum != 0 + Xpath 128 " X: 0 + endif + let sum = sum + 1 + endtry + Xpath 256 " X: 0 + catch /123/ + Xpath 512 " X: 0 + catch /321/ + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 2048 + if sum != 1 + Xpath 4096 " X: 0 + endif + let sum = sum + 2 + endtry + Xpath 8192 " X: 0 + finally + Xpath 16384 " X: 16384 + if sum != 3 + Xpath 32768 " X: 0 + endif + let sum = sum + 4 + endtry + Xpath 65536 " X: 0 +catch /ABC/ + Xpath 131072 " X: 131072 + if sum != 7 + Xpath 262144 " X: 0 + endif + let sum = sum + 8 +finally + Xpath 524288 " X: 524288 + if sum != 15 + Xpath 1048576 " X: 0 + endif + let sum = sum + 16 +endtry +Xpath 65536 " X: 65536 +if sum != 31 + Xpath 131072 " X: 0 +endif + +unlet sum + +Xcheck 739407 + + +"------------------------------------------------------------------------------- +" Test 47: Throwing exceptions from a :catch clause {{{1 +" +" When an exception is thrown from a :catch clause, it should not be +" caught by a :catch of the same :try conditional. After executing +" the :finally clause (if present), surrounding try conditionals +" should be checked for a matching :catch. +"------------------------------------------------------------------------------- + +XpathINIT + +Xpath 1 " X: 1 +try + Xpath 2 " X: 2 + try + Xpath 4 " X: 4 + try + Xpath 8 " X: 8 + throw "x1" + Xpath 16 " X: 0 + catch /x1/ + Xpath 32 " X: 32 + try + Xpath 64 " X: 64 + throw "x2" + Xpath 128 " X: 0 + catch /x1/ + Xpath 256 " X: 0 + catch /x2/ + Xpath 512 " X: 512 + try + Xpath 1024 " X: 1024 + throw "x3" + Xpath 2048 " X: 0 + catch /x1/ + Xpath 4096 " X: 0 + catch /x2/ + Xpath 8192 " X: 0 + finally + Xpath 16384 " X: 16384 + endtry + Xpath 32768 " X: 0 + catch /x3/ + Xpath 65536 " X: 0 + endtry + Xpath 131072 " X: 0 + catch /x1/ + Xpath 262144 " X: 0 + catch /x2/ + Xpath 524288 " X: 0 + catch /x3/ + Xpath 1048576 " X: 0 + finally + Xpath 2097152 " X: 2097152 + endtry + Xpath 4194304 " X: 0 + catch /x1/ + Xpath 8388608 " X: 0 + catch /x2/ + Xpath 16777216 " X: 0 + catch /x3/ + Xpath 33554432 " X: 33554432 + endtry + Xpath 67108864 " X: 67108864 +catch /.*/ + Xpath 134217728 " X: 0 + Xout v:exception "in" v:throwpoint +endtry +Xpath 268435456 " X: 268435456 + +Xcheck 371213935 + + +"------------------------------------------------------------------------------- +" Test 48: Throwing exceptions from a :finally clause {{{1 +" +" When an exception is thrown from a :finally clause, it should not be +" caught by a :catch of the same :try conditional. Surrounding try +" conditionals should be checked for a matching :catch. A previously +" thrown exception is discarded. +"------------------------------------------------------------------------------- + +XpathINIT + +try + + try + try + Xpath 1 " X: 1 + catch /x1/ + Xpath 2 " X: 0 + finally + Xpath 4 " X: 4 + throw "x1" + Xpath 8 " X: 0 + endtry + Xpath 16 " X: 0 + catch /x1/ + Xpath 32 " X: 32 + endtry + Xpath 64 " X: 64 + + try + try + Xpath 128 " X: 128 + throw "x2" + Xpath 256 " X: 0 + catch /x2/ + Xpath 512 " X: 512 + catch /x3/ + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 2048 + throw "x3" + Xpath 4096 " X: 0 + endtry + Xpath 8192 " X: 0 + catch /x2/ + Xpath 16384 " X: 0 + catch /x3/ + Xpath 32768 " X: 32768 + endtry + Xpath 65536 " X: 65536 + + try + try + try + Xpath 131072 " X: 131072 + throw "x4" + Xpath 262144 " X: 0 + catch /x5/ + Xpath 524288 " X: 0 + finally + Xpath 1048576 " X: 1048576 + throw "x5" " discards "x4" + Xpath 2097152 " X: 0 + endtry + Xpath 4194304 " X: 0 + catch /x4/ + Xpath 8388608 " X: 0 + finally + Xpath 16777216 " X: 16777216 + endtry + Xpath 33554432 " X: 0 + catch /x5/ + Xpath 67108864 " X: 67108864 + endtry + Xpath 134217728 " X: 134217728 + +catch /.*/ + Xpath 268435456 " X: 0 + Xout v:exception "in" v:throwpoint +endtry +Xpath 536870912 " X: 536870912 + +Xcheck 756255461 + + +"------------------------------------------------------------------------------- +" Test 49: Throwing exceptions accross functions {{{1 +" +" When an exception is thrown but not caught inside a function, the +" caller is checked for a matching :catch clause. +"------------------------------------------------------------------------------- + +XpathINIT + +function! C() + try + Xpath 1 " X: 1 + throw "arrgh" + Xpath 2 " X: 0 + catch /arrgh/ + Xpath 4 " X: 4 + endtry + Xpath 8 " X: 8 +endfunction + +XloopINIT! 16 16 + +function! T1() + XloopNEXT + try + Xloop 1 " X: 16 + 16*16 + throw "arrgh" + Xloop 2 " X: 0 + finally + Xloop 4 " X: 64 + 64*16 + endtry + Xloop 8 " X: 0 +endfunction + +function! T2() + try + Xpath 4096 " X: 4096 + call T1() + Xpath 8192 " X: 0 + finally + Xpath 16384 " X: 16384 + endtry + Xpath 32768 " X: 0 +endfunction + +try + Xpath 65536 " X: 65536 + call C() " throw and catch + Xpath 131072 " X: 131072 +catch /.*/ + Xpath 262144 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +try + Xpath 524288 " X: 524288 + call T1() " throw, one level + Xpath 1048576 " X: 0 +catch /arrgh/ + Xpath 2097152 " X: 2097152 +catch /.*/ + Xpath 4194304 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +try + Xpath 8388608 " X: 8388608 + call T2() " throw, two levels + Xpath 16777216 " X: 0 +catch /arrgh/ + Xpath 33554432 " X: 33554432 +catch /.*/ + Xpath 67108864 " X: 0 + Xout v:exception "in" v:throwpoint +endtry +Xpath 134217728 " X: 134217728 + +Xcheck 179000669 + +" Leave C, T1, and T2 for execution as scripts in the next test. + + +"------------------------------------------------------------------------------- +" Test 50: Throwing exceptions accross script files {{{1 +" +" When an exception is thrown but not caught inside a script file, +" the sourcing script or function is checked for a matching :catch +" clause. +" +" This test executes the bodies of the functions C, T1, and T2 from +" the previous test as script files (:return replaced by :finish). +"------------------------------------------------------------------------------- + +XpathINIT + +let scriptC = MakeScript("C") " X: 1 + 4 + 8 +delfunction C + +XloopINIT! 16 16 + +let scriptT1 = MakeScript("T1") " X: 16 + 64 + 16*16 + 64*16 +delfunction T1 + +let scriptT2 = MakeScript("T2", scriptT1) " X: 4096 + 16384 +delfunction T2 + +function! F() + try + Xpath 65536 " X: 65536 + exec "source" g:scriptC + Xpath 131072 " X: 131072 + catch /.*/ + Xpath 262144 " X: 0 + Xout v:exception "in" v:throwpoint + endtry + + try + Xpath 524288 " X: 524288 + exec "source" g:scriptT1 + Xpath 1048576 " X: 0 + catch /arrgh/ + Xpath 2097152 " X: 2097152 + catch /.*/ + Xpath 4194304 " X: 0 + Xout v:exception "in" v:throwpoint + endtry +endfunction + +try + Xpath 8388608 " X: 8388608 + call F() + Xpath 16777216 " X: 16777216 + exec "source" scriptT2 + Xpath 33554432 " X: 0 +catch /arrgh/ + Xpath 67108864 " X: 67108864 +catch /.*/ + Xpath 134217728 " X: 0 + Xout v:exception "in" v:throwpoint +endtry +Xpath 268435456 " X: 268435456 + +call delete(scriptC) +call delete(scriptT1) +call delete(scriptT2) +unlet scriptC scriptT1 scriptT2 +delfunction F + +Xcheck 363550045 + + +"------------------------------------------------------------------------------- +" Test 51: Throwing exceptions accross :execute and user commands {{{1 +" +" A :throw command may be executed under an ":execute" or from +" a user command. +"------------------------------------------------------------------------------- + +XpathINIT + +command! -nargs=? THROW1 throw <args> | throw 1 +command! -nargs=? THROW2 try | throw <args> | endtry | throw 2 +command! -nargs=? THROW3 try | throw 3 | catch /3/ | throw <args> | endtry +command! -nargs=? THROW4 try | throw 4 | finally | throw <args> | endtry + +try + + try + try + Xpath 1 " X: 1 + THROW1 "A" + catch /A/ + Xpath 2 " X: 2 + endtry + catch /1/ + Xpath 4 " X: 0 + endtry + + try + try + Xpath 8 " X: 8 + THROW2 "B" + catch /B/ + Xpath 16 " X: 16 + endtry + catch /2/ + Xpath 32 " X: 0 + endtry + + try + try + Xpath 64 " X: 64 + THROW3 "C" + catch /C/ + Xpath 128 " X: 128 + endtry + catch /3/ + Xpath 256 " X: 0 + endtry + + try + try + Xpath 512 " X: 512 + THROW4 "D" + catch /D/ + Xpath 1024 " X: 1024 + endtry + catch /4/ + Xpath 2048 " X: 0 + endtry + + try + try + Xpath 4096 " X: 4096 + execute 'throw "E" | throw 5' + catch /E/ + Xpath 8192 " X: 8192 + endtry + catch /5/ + Xpath 16384 " X: 0 + endtry + + try + try + Xpath 32768 " X: 32768 + execute 'try | throw "F" | endtry | throw 6' + catch /F/ + Xpath 65536 " X: 65536 + endtry + catch /6/ + Xpath 131072 " X: 0 + endtry + + try + try + Xpath 262144 " X: 262144 + execute'try | throw 7 | catch /7/ | throw "G" | endtry' + catch /G/ + Xpath 524288 " X: 524288 + endtry + catch /7/ + Xpath 1048576 " X: 0 + endtry + + try + try + Xpath 2097152 " X: 2097152 + execute 'try | throw 8 | finally | throw "H" | endtry' + catch /H/ + Xpath 4194304 " X: 4194304 + endtry + catch /8/ + Xpath 8388608 " X: 0 + endtry + +catch /.*/ + Xpath 16777216 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xpath 33554432 " X: 33554432 + +delcommand THROW1 +delcommand THROW2 +delcommand THROW3 +delcommand THROW4 + +Xcheck 40744667 + + +"------------------------------------------------------------------------------- +" Test 52: Uncaught exceptions {{{1 +" +" When an exception is thrown but not caught, an error message is +" displayed when the script is terminated. In case of an interrupt +" or error exception, the normal interrupt or error message(s) are +" displayed. +"------------------------------------------------------------------------------- + +XpathINIT + +let msgfile = tempname() + +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 + +if ExtraVim(msgfile) + Xpath 1 " X: 1 + throw "arrgh" +endif + +Xpath 2 " X: 2 +if !MESSAGES('E605', "Exception not caught") + Xpath 4 " X: 0 +endif + +if ExtraVim(msgfile) + try + Xpath 8 " X: 8 + throw "oops" + catch /arrgh/ + Xpath 16 " X: 0 + endtry + Xpath 32 " X: 0 +endif + +Xpath 64 " X: 64 +if !MESSAGES('E605', "Exception not caught") + Xpath 128 " X: 0 +endif + +if ExtraVim(msgfile) + function! T() + throw "brrr" + endfunction + + try + Xpath 256 " X: 256 + throw "arrgh" + catch /.*/ + Xpath 512 " X: 512 + call T() + endtry + Xpath 1024 " X: 0 +endif + +Xpath 2048 " X: 2048 +if !MESSAGES('E605', "Exception not caught") + Xpath 4096 " X: 0 +endif + +if ExtraVim(msgfile) + try + Xpath 8192 " X: 8192 + throw "arrgh" + finally + Xpath 16384 " X: 16384 + throw "brrr" + endtry + Xpath 32768 " X: 0 +endif + +Xpath 65536 " X: 65536 +if !MESSAGES('E605', "Exception not caught") + Xpath 131072 " X: 0 +endif + +if ExtraVim(msgfile) + try + Xpath 262144 " X: 262144 + "INTERRUPT + endtry + Xpath 524288 " X: 0 +endif + +Xpath 1048576 " X: 1048576 +if !MESSAGES('INT', "Interrupted") + Xpath 2097152 " X: 0 +endif + +if ExtraVim(msgfile) + try + Xpath 4194304 " X: 4194304 + let x = novar " error E121/E15; exception: E121 + catch /E15:/ " should not catch + Xpath 8388608 " X: 0 + endtry + Xpath 16777216 " X: 0 +endif + +Xpath 33554432 " X: 33554432 +if !MESSAGES('E121', "Undefined variable", 'E15', "Invalid expression") + Xpath 67108864 " X: 0 +endif + +if ExtraVim(msgfile) + try + Xpath 134217728 " X: 134217728 +" unlet novar # " error E108/E488; exception: E488 + catch /E108:/ " should not catch + Xpath 268435456 " X: 0 + endtry + Xpath 536870912 " X: 0 +endif + +Xpath 1073741824 " X: 1073741824 +if !MESSAGES('E108', "No such variable", 'E488', "Trailing characters") + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 +endif + +call delete(msgfile) +unlet msgfile + +Xcheck 1247112011 + +" Leave MESSAGES() for the next tests. + + +"------------------------------------------------------------------------------- +" Test 53: Nesting errors: :endif/:else/:elseif {{{1 +" +" For nesting errors of :if conditionals the correct error messages +" should be given. +" +" This test reuses the function MESSAGES() from the previous test. +" This functions checks the messages in g:msgfile. +"------------------------------------------------------------------------------- + +XpathINIT + +let msgfile = tempname() + +if ExtraVim(msgfile) +" endif +endif +if MESSAGES('E580', ":endif without :if") + Xpath 1 " X: 1 +endif + +if ExtraVim(msgfile) +" while 1 +" endif +" endwhile +endif +if MESSAGES('E580', ":endif without :if") + Xpath 2 " X: 2 +endif + +if ExtraVim(msgfile) +" try +" finally +" endif +" endtry +endif +if MESSAGES('E580', ":endif without :if") + Xpath 4 " X: 4 +endif + +if ExtraVim(msgfile) +" try +" endif +" endtry +endif +if MESSAGES('E580', ":endif without :if") + Xpath 8 " X: 8 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" endif +" endtry +endif +if MESSAGES('E580', ":endif without :if") + Xpath 16 " X: 16 +endif + +if ExtraVim(msgfile) +" else +endif +if MESSAGES('E581', ":else without :if") + Xpath 32 " X: 32 +endif + +if ExtraVim(msgfile) +" while 1 +" else +" endwhile +endif +if MESSAGES('E581', ":else without :if") + Xpath 64 " X: 64 +endif + +if ExtraVim(msgfile) +" try +" finally +" else +" endtry +endif +if MESSAGES('E581', ":else without :if") + Xpath 128 " X: 128 +endif + +if ExtraVim(msgfile) +" try +" else +" endtry +endif +if MESSAGES('E581', ":else without :if") + Xpath 256 " X: 256 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" else +" endtry +endif +if MESSAGES('E581', ":else without :if") + Xpath 512 " X: 512 +endif + +if ExtraVim(msgfile) +" elseif +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 1024 " X: 1024 +endif + +if ExtraVim(msgfile) +" while 1 +" elseif +" endwhile +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 2048 " X: 2048 +endif + +if ExtraVim(msgfile) +" try +" finally +" elseif +" endtry +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 4096 " X: 4096 +endif + +if ExtraVim(msgfile) +" try +" elseif +" endtry +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 8192 " X: 8192 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" elseif +" endtry +endif +if MESSAGES('E582', ":elseif without :if") + Xpath 16384 " X: 16384 +endif + +if ExtraVim(msgfile) +" if 1 +" else +" else +" endif +endif +if MESSAGES('E583', "multiple :else") + Xpath 32768 " X: 32768 +endif + +if ExtraVim(msgfile) +" if 1 +" else +" elseif 1 +" endif +endif +if MESSAGES('E584', ":elseif after :else") + Xpath 65536 " X: 65536 +endif + +call delete(msgfile) +unlet msgfile + +Xcheck 131071 + +" Leave MESSAGES() for the next test. + + +"------------------------------------------------------------------------------- +" Test 54: Nesting errors: :while/:endwhile {{{1 +" +" For nesting errors of :while conditionals the correct error messages +" should be given. +" +" This test reuses the function MESSAGES() from the previous test. +" This functions checks the messages in g:msgfile. +"------------------------------------------------------------------------------- + +XpathINIT + +let msgfile = tempname() + +if ExtraVim(msgfile) +" endwhile +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 1 " X: 1 +endif + +if ExtraVim(msgfile) +" if 1 +" endwhile +" endif +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 2 " X: 2 +endif + +if ExtraVim(msgfile) +" while 1 +" if 1 +" endwhile +endif +if MESSAGES('E171', "Missing :endif") + Xpath 4 " X: 4 +endif + +if ExtraVim(msgfile) +" try +" finally +" endwhile +" endtry +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 8 " X: 8 +endif + +if ExtraVim(msgfile) +" while 1 +" try +" finally +" endwhile +endif +if MESSAGES('E600', "Missing :endtry") + Xpath 16 " X: 16 +endif + +if ExtraVim(msgfile) +" while 1 +" if 1 +" try +" finally +" endwhile +endif +if MESSAGES('E600', "Missing :endtry") + Xpath 32 " X: 32 +endif + +if ExtraVim(msgfile) +" while 1 +" try +" finally +" if 1 +" endwhile +endif +if MESSAGES('E171', "Missing :endif") + Xpath 64 " X: 64 +endif + +if ExtraVim(msgfile) +" try +" endwhile +" endtry +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 128 " X: 128 +endif + +if ExtraVim(msgfile) +" while 1 +" try +" endwhile +" endtry +" endwhile +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 256 " X: 256 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" endwhile +" endtry +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 512 " X: 512 +endif + +if ExtraVim(msgfile) +" while 1 +" try +" throw "a" +" catch /a/ +" endwhile +" endtry +" endwhile +endif +if MESSAGES('E588', ":endwhile without :while") + Xpath 1024 " X: 1024 +endif + + +call delete(msgfile) +unlet msgfile + +Xcheck 2047 + +" Leave MESSAGES() for the next test. + + +"------------------------------------------------------------------------------- +" Test 55: Nesting errors: :continue/:break {{{1 +" +" For nesting errors of :continue and :break commands the correct +" error messages should be given. +" +" This test reuses the function MESSAGES() from the previous test. +" This functions checks the messages in g:msgfile. +"------------------------------------------------------------------------------- + +XpathINIT + +let msgfile = tempname() + +if ExtraVim(msgfile) +" continue +endif +if MESSAGES('E586', ":continue without :while") + Xpath 1 " X: 1 +endif + +if ExtraVim(msgfile) +" if 1 +" continue +" endif +endif +if MESSAGES('E586', ":continue without :while") + Xpath 2 " X: 2 +endif + +if ExtraVim(msgfile) +" try +" finally +" continue +" endtry +endif +if MESSAGES('E586', ":continue without :while") + Xpath 4 " X: 4 +endif + +if ExtraVim(msgfile) +" try +" continue +" endtry +endif +if MESSAGES('E586', ":continue without :while") + Xpath 8 " X: 8 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" continue +" endtry +endif +if MESSAGES('E586', ":continue without :while") + Xpath 16 " X: 16 +endif + +if ExtraVim(msgfile) +" break +endif +if MESSAGES('E587', ":break without :while") + Xpath 32 " X: 32 +endif + +if ExtraVim(msgfile) +" if 1 +" break +" endif +endif +if MESSAGES('E587', ":break without :while") + Xpath 64 " X: 64 +endif + +if ExtraVim(msgfile) +" try +" finally +" break +" endtry +endif +if MESSAGES('E587', ":break without :while") + Xpath 128 " X: 128 +endif + +if ExtraVim(msgfile) +" try +" break +" endtry +endif +if MESSAGES('E587', ":break without :while") + Xpath 256 " X: 256 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" break +" endtry +endif +if MESSAGES('E587', ":break without :while") + Xpath 512 " X: 512 +endif + +call delete(msgfile) +unlet msgfile + +Xcheck 1023 + +" Leave MESSAGES() for the next test. + + +"------------------------------------------------------------------------------- +" Test 56: Nesting errors: :endtry {{{1 +" +" For nesting errors of :try conditionals the correct error messages +" should be given. +" +" This test reuses the function MESSAGES() from the previous test. +" This functions checks the messages in g:msgfile. +"------------------------------------------------------------------------------- + +XpathINIT + +let msgfile = tempname() + +if ExtraVim(msgfile) +" endtry +endif +if MESSAGES('E602', ":endtry without :try") + Xpath 1 " X: 1 +endif + +if ExtraVim(msgfile) +" if 1 +" endtry +" endif +endif +if MESSAGES('E602', ":endtry without :try") + Xpath 2 " X: 2 +endif + +if ExtraVim(msgfile) +" while 1 +" endtry +" endwhile +endif +if MESSAGES('E602', ":endtry without :try") + Xpath 4 " X: 4 +endif + +if ExtraVim(msgfile) +" try +" if 1 +" endtry +endif +if MESSAGES('E171', "Missing :endif") + Xpath 8 " X: 8 +endif + +if ExtraVim(msgfile) +" try +" while 1 +" endtry +endif +if MESSAGES('E170', "Missing :endwhile") + Xpath 16 " X: 16 +endif + +if ExtraVim(msgfile) +" try +" finally +" if 1 +" endtry +endif +if MESSAGES('E171', "Missing :endif") + Xpath 32 " X: 32 +endif + +if ExtraVim(msgfile) +" try +" finally +" while 1 +" endtry +endif +if MESSAGES('E170', "Missing :endwhile") + Xpath 64 " X: 64 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" if 1 +" endtry +endif +if MESSAGES('E171', "Missing :endif") + Xpath 128 " X: 128 +endif + +if ExtraVim(msgfile) +" try +" throw "a" +" catch /a/ +" while 1 +" endtry +endif +if MESSAGES('E170', "Missing :endwhile") + Xpath 256 " X: 256 +endif + +call delete(msgfile) +unlet msgfile + +delfunction MESSAGES + +Xcheck 511 + + +"------------------------------------------------------------------------------- +" Test 57: v:exception and v:throwpoint for user exceptions {{{1 +" +" v:exception evaluates to the value of the exception that was caught +" most recently and is not finished. (A caught exception is finished +" when the next ":catch", ":finally", or ":endtry" is reached.) +" v:throwpoint evaluates to the script/function name and line number +" where that exception has been thrown. +"------------------------------------------------------------------------------- + +XpathINIT + +function! FuncException() + let g:exception = v:exception +endfunction + +function! FuncThrowpoint() + let g:throwpoint = v:throwpoint +endfunction + +let scriptException = MakeScript("FuncException") +let scriptThrowPoint = MakeScript("FuncThrowpoint") + +command! CmdException let g:exception = v:exception +command! CmdThrowpoint let g:throwpoint = v:throwpoint + +XloopINIT! 1 2 + +function! CHECK(n, exception, throwname, throwline) + XloopNEXT + let error = 0 + if v:exception != a:exception + Xout a:n.": v:exception is" v:exception "instead of" a:exception + let error = 1 + endif + if v:throwpoint !~ a:throwname + let name = escape(a:throwname, '\') + Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" name + let error = 1 + endif + if v:throwpoint !~ a:throwline + let line = escape(a:throwline, '\') + Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line + let error = 1 + endif + if error + Xloop 1 " X: 0 + endif +endfunction + +function! T(arg, line) + if a:line == 2 + throw a:arg " in line 2 + elseif a:line == 4 + throw a:arg " in line 4 + elseif a:line == 6 + throw a:arg " in line 6 + elseif a:line == 8 + throw a:arg " in line 8 + endif +endfunction + +function! G(arg, line) + call T(a:arg, a:line) +endfunction + +function! F(arg, line) + call G(a:arg, a:line) +endfunction + +let scriptT = MakeScript("T") +let scriptG = MakeScript("G", scriptT) +let scriptF = MakeScript("F", scriptG) + +try + Xpath 32768 " X: 32768 + call F("oops", 2) +catch /.*/ + Xpath 65536 " X: 65536 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(1, "oops", '\<F\.\.G\.\.T\>', '\<2\>') + exec "let exception = v:exception" + exec "let throwpoint = v:throwpoint" + call CHECK(2, "oops", '\<F\.\.G\.\.T\>', '\<2\>') + CmdException + CmdThrowpoint + call CHECK(3, "oops", '\<F\.\.G\.\.T\>', '\<2\>') + call FuncException() + call FuncThrowpoint() + call CHECK(4, "oops", '\<F\.\.G\.\.T\>', '\<2\>') + exec "source" scriptException + exec "source" scriptThrowPoint + call CHECK(5, "oops", '\<F\.\.G\.\.T\>', '\<2\>') + try + Xpath 131072 " X: 131072 + call G("arrgh", 4) + catch /.*/ + Xpath 262144 " X: 262144 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(6, "arrgh", '\<G\.\.T\>', '\<4\>') + try + Xpath 524288 " X: 524288 + let g:arg = "autsch" + let g:line = 6 + exec "source" scriptF + catch /.*/ + Xpath 1048576 " X: 1048576 + let exception = v:exception + let throwpoint = v:throwpoint + " Symbolic links in tempname()s are not resolved, whereas resolving + " is done for v:throwpoint. Resolve the temporary file name for + " scriptT, so that it can be matched against v:throwpoint. + call CHECK(7, "autsch", resolve(scriptT), '\<6\>') + finally + Xpath 2097152 " X: 2097152 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(8, "arrgh", '\<G\.\.T\>', '\<4\>') + try + Xpath 4194304 " X: 4194304 + let g:arg = "brrrr" + let g:line = 8 + exec "source" scriptG + catch /.*/ + Xpath 8388608 " X: 8388608 + let exception = v:exception + let throwpoint = v:throwpoint + " Resolve scriptT for matching it against v:throwpoint. + call CHECK(9, "brrrr", resolve(scriptT), '\<8\>') + finally + Xpath 16777216 " X: 16777216 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(10, "arrgh", '\<G\.\.T\>', '\<4\>') + endtry + Xpath 33554432 " X: 33554432 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(11, "arrgh", '\<G\.\.T\>', '\<4\>') + endtry + Xpath 67108864 " X: 67108864 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(12, "arrgh", '\<G\.\.T\>', '\<4\>') + finally + Xpath 134217728 " X: 134217728 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(13, "oops", '\<F\.\.G\.\.T\>', '\<2\>') + endtry + Xpath 268435456 " X: 268435456 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(14, "oops", '\<F\.\.G\.\.T\>', '\<2\>') +finally + Xpath 536870912 " X: 536870912 + let exception = v:exception + let throwpoint = v:throwpoint + call CHECK(15, "", '^$', '^$') +endtry + +Xpath 1073741824 " X: 1073741824 + +unlet exception throwpoint +delfunction FuncException +delfunction FuncThrowpoint +call delete(scriptException) +call delete(scriptThrowPoint) +unlet scriptException scriptThrowPoint +delcommand CmdException +delcommand CmdThrowpoint +delfunction T +delfunction G +delfunction F +call delete(scriptT) +call delete(scriptG) +call delete(scriptF) +unlet scriptT scriptG scriptF + +Xcheck 2147450880 + + +"------------------------------------------------------------------------------- +" +" Test 58: v:exception and v:throwpoint for error/interrupt exceptions {{{1 +" +" v:exception and v:throwpoint work also for error and interrupt +" exceptions. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + function! T(line) + if a:line == 2 + delfunction T " error (function in use) in line 2 + elseif a:line == 4 + let dummy = 0 " INTERRUPT1 - interrupt in line 4 + endif + endfunction + + while 1 + try + Xpath 1 " X: 1 + let caught = 0 + call T(2) + catch /.*/ + let caught = 1 + if v:exception !~ 'Vim(delfunction):' + Xpath 2 " X: 0 + endif + if v:throwpoint !~ '\<T\>' + Xpath 4 " X: 0 + endif + if v:throwpoint !~ '\<2\>' + Xpath 8 " X: 0 + endif + finally + Xpath 16 " X: 16 + if caught || $VIMNOERRTHROW + Xpath 32 " X: 32 + endif + if v:exception != "" + Xpath 64 " X: 0 + endif + if v:throwpoint != "" + Xpath 128 " X: 0 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + Xpath 256 " X: 256 + if v:exception != "" + Xpath 512 " X: 0 + endif + if v:throwpoint != "" + Xpath 1024 " X: 0 + endif + + while 1 + try + Xpath 2048 " X: 2048 + let caught = 0 + call T(4) + catch /.*/ + let caught = 1 + if v:exception != 'Vim:Interrupt' + Xpath 4096 " X: 0 + endif + if v:throwpoint !~ '\<T\>' + Xpath 8192 " X: 0 + endif + if v:throwpoint !~ '\<4\>' + Xpath 16384 " X: 0 + endif + finally + Xpath 32768 " X: 32768 + if caught || $VIMNOINTTHROW + Xpath 65536 " X: 65536 + endif + if v:exception != "" + Xpath 131072 " X: 0 + endif + if v:throwpoint != "" + Xpath 262144 " X: 0 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + Xpath 524288 " X: 524288 + if v:exception != "" + Xpath 1048576 " X: 0 + endif + if v:throwpoint != "" + Xpath 2097152 " X: 0 + endif + +endif + +Xcheck 624945 + + +"------------------------------------------------------------------------------- +" +" Test 59: v:exception and v:throwpoint when discarding exceptions {{{1 +" +" When a :catch clause is left by a ":break" etc or an error or +" interrupt exception, v:exception and v:throwpoint are reset. They +" are not affected by an exception that is discarded before being +" caught. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + XloopINIT! 1 2 + + let sfile = expand("<sfile>") + + function! LineNumber() + return substitute(substitute(v:throwpoint, g:sfile, '', ""), + \ '\D*\(\d*\).*', '\1', "") + endfunction + + command! -nargs=1 SetLineNumber + \ try | throw "line" | catch /.*/ | let <args> = LineNumber() | endtry + + " Check v:exception/v:throwpoint against second/fourth parameter if + " specified, check for being empty else. + function! CHECK(n, ...) + XloopNEXT + let exception = a:0 != 0 ? a:1 : "" " second parameter (optional) + let emsg = a:0 != 0 ? a:2 : "" " third parameter (optional) + let line = a:0 != 0 ? a:3 : 0 " fourth parameter (optional) + let error = 0 + if emsg != "" + " exception is the error number, emsg the english error message text + if exception !~ '^E\d\+$' + Xout "TODO: Add message number for:" emsg + elseif v:lang == "C" || v:lang =~ '^[Ee]n' + if exception == "E492" && emsg == "Not an editor command" + let exception = '^Vim:' . exception . ': ' . emsg + else + let exception = '^Vim(\a\+):' . exception . ': ' . emsg + endif + else + if exception == "E492" + let exception = '^Vim:' . exception + else + let exception = '^Vim(\a\+):' . exception + endif + endif + endif + if exception == "" && v:exception != "" + Xout a:n.": v:exception is set:" v:exception + let error = 1 + elseif exception != "" && v:exception !~ exception + Xout a:n.": v:exception (".v:exception.") does not match" exception + let error = 1 + endif + if line == 0 && v:throwpoint != "" + Xout a:n.": v:throwpoint is set:" v:throwpoint + let error = 1 + elseif line != 0 && v:throwpoint !~ '\<' . line . '\>' + Xout a:n.": v:throwpoint (".v:throwpoint.") does not match" line + let error = 1 + endif + if !error + Xloop 1 " X: 2097151 + endif + endfunction + + while 1 + try + throw "x1" + catch /.*/ + break + endtry + endwhile + call CHECK(1) + + while 1 + try + throw "x2" + catch /.*/ + break + finally + call CHECK(2) + endtry + break + endwhile + call CHECK(3) + + while 1 + try + let errcaught = 0 + try + try + throw "x3" + catch /.*/ + SetLineNumber line_before_error + asdf + endtry + catch /.*/ + let errcaught = 1 + call CHECK(4, 'E492', "Not an editor command", + \ line_before_error + 1) + endtry + finally + if !errcaught && $VIMNOERRTHROW + call CHECK(4) + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + call CHECK(5) + + Xpath 2097152 " X: 2097152 + + while 1 + try + let intcaught = 0 + try + try + throw "x4" + catch /.*/ + SetLineNumber two_lines_before_interrupt + "INTERRUPT + let dummy = 0 + endtry + catch /.*/ + let intcaught = 1 + call CHECK(6, "Vim:Interrupt", '', + \ two_lines_before_interrupt + 2) + endtry + finally + if !intcaught && $VIMNOINTTHROW + call CHECK(6) + endif + break " discard interrupt for $VIMNOINTTHROW + endtry + endwhile + call CHECK(7) + + Xpath 4194304 " X: 4194304 + + while 1 + try + let errcaught = 0 + try + try +" if 1 + SetLineNumber line_before_throw + throw "x5" + " missing endif + catch /.*/ + Xpath 8388608 " X: 0 + endtry + catch /.*/ + let errcaught = 1 + call CHECK(8, 'E171', "Missing :endif", line_before_throw + 3) + endtry + finally + if !errcaught && $VIMNOERRTHROW + call CHECK(8) + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + call CHECK(9) + + Xpath 16777216 " X: 16777216 + + try + while 1 + try + throw "x6" + finally + break + endtry + break + endwhile + catch /.*/ + Xpath 33554432 " X: 0 + endtry + call CHECK(10) + + try + while 1 + try + throw "x7" + finally + break + endtry + break + endwhile + catch /.*/ + Xpath 67108864 " X: 0 + finally + call CHECK(11) + endtry + call CHECK(12) + + while 1 + try + let errcaught = 0 + try + try + throw "x8" + finally + SetLineNumber line_before_error + asdf + endtry + catch /.*/ + let errcaught = 1 + call CHECK(13, 'E492', "Not an editor command", + \ line_before_error + 1) + endtry + finally + if !errcaught && $VIMNOERRTHROW + call CHECK(13) + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + call CHECK(14) + + Xpath 134217728 " X: 134217728 + + while 1 + try + let intcaught = 0 + try + try + throw "x9" + finally + SetLineNumber two_lines_before_interrupt + "INTERRUPT + endtry + catch /.*/ + let intcaught = 1 + call CHECK(15, "Vim:Interrupt", '', + \ two_lines_before_interrupt + 2) + endtry + finally + if !intcaught && $VIMNOINTTHROW + call CHECK(15) + endif + break " discard interrupt for $VIMNOINTTHROW + endtry + endwhile + call CHECK(16) + + Xpath 268435456 " X: 268435456 + + while 1 + try + let errcaught = 0 + try + try +" if 1 + SetLineNumber line_before_throw + throw "x10" + " missing endif + finally + call CHECK(17) + endtry + catch /.*/ + let errcaught = 1 + call CHECK(18, 'E171', "Missing :endif", line_before_throw + 3) + endtry + finally + if !errcaught && $VIMNOERRTHROW + call CHECK(18) + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + call CHECK(19) + + Xpath 536870912 " X: 536870912 + + while 1 + try + let errcaught = 0 + try + try +" if 1 + SetLineNumber line_before_throw + throw "x11" + " missing endif + endtry + catch /.*/ + let errcaught = 1 + call CHECK(20, 'E171', "Missing :endif", line_before_throw + 3) + endtry + finally + if !errcaught && $VIMNOERRTHROW + call CHECK(20) + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + call CHECK(21) + + Xpath 1073741824 " X: 1073741824 + +endif + +Xcheck 2038431743 + + +"------------------------------------------------------------------------------- +" +" Test 60: (Re)throwing v:exception; :echoerr. {{{1 +" +" A user exception can be rethrown after catching by throwing +" v:exception. An error or interrupt exception cannot be rethrown +" because Vim exceptions cannot be faked. A Vim exception using the +" value of v:exception can, however, be triggered by the :echoerr +" command. +"------------------------------------------------------------------------------- + +XpathINIT + +try + try + Xpath 1 " X: 1 + throw "oops" + catch /oops/ + Xpath 2 " X: 2 + throw v:exception " rethrow user exception + catch /.*/ + Xpath 4 " X: 0 + endtry +catch /^oops$/ " catches rethrown user exception + Xpath 8 " X: 8 +catch /.*/ + Xpath 16 " X: 0 +endtry + +function! F() + try + let caught = 0 + try + Xpath 32 " X: 32 + write /n/o/n/w/r/i/t/a/b/l/e/_/f/i/l/e + Xpath 64 " X: 0 + Xout "did_emsg was reset before executing " . + \ "BufWritePost autocommands." + catch /^Vim(write):/ + let caught = 1 + throw v:exception " throw error: cannot fake Vim exception + catch /.*/ + Xpath 128 " X: 0 + finally + Xpath 256 " X: 256 + if !caught && !$VIMNOERRTHROW + Xpath 512 " X: 0 + endif + endtry + catch /^Vim(throw):/ " catches throw error + let caught = caught + 1 + catch /.*/ + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 2048 + if caught != 2 + if !caught && !$VIMNOERRTHROW + Xpath 4096 " X: 0 + elseif caught + Xpath 8192 " X: 0 + endif + return | " discard error for $VIMNOERRTHROW + endif + endtry +endfunction + +call F() +delfunction F + +function! G() + try + let caught = 0 + try + Xpath 16384 " X: 16384 + asdf + catch /^Vim/ " catch error exception + let caught = 1 + " Trigger Vim error exception with value specified after :echoerr + let value = substitute(v:exception, '^Vim\((.*)\)\=:', '', "") + echoerr value + catch /.*/ + Xpath 32768 " X: 0 + finally + Xpath 65536 " X: 65536 + if !caught + if !$VIMNOERRTHROW + Xpath 131072 " X: 0 + else + let value = "Error" + echoerr value + endif + endif + endtry + catch /^Vim(echoerr):/ + let caught = caught + 1 + if v:exception !~ value + Xpath 262144 " X: 0 + endif + catch /.*/ + Xpath 524288 " X: 0 + finally + Xpath 1048576 " X: 1048576 + if caught != 2 + if !caught && !$VIMNOERRTHROW + Xpath 2097152 " X: 0 + elseif caught + Xpath 4194304 " X: 0 + endif + return | " discard error for $VIMNOERRTHROW + endif + endtry +endfunction + +call G() +delfunction G + +unlet! value caught + +if ExtraVim() + try + let errcaught = 0 + try + Xpath 8388608 " X: 8388608 + let intcaught = 0 + "INTERRUPT + catch /^Vim:/ " catch interrupt exception + let intcaught = 1 + " Trigger Vim error exception with value specified after :echoerr + echoerr substitute(v:exception, '^Vim\((.*)\)\=:', '', "") + catch /.*/ + Xpath 16777216 " X: 0 + finally + Xpath 33554432 " X: 33554432 + if !intcaught + if !$VIMNOINTTHROW + Xpath 67108864 " X: 0 + else + echoerr "Interrupt" + endif + endif + endtry + catch /^Vim(echoerr):/ + let errcaught = 1 + if v:exception !~ "Interrupt" + Xpath 134217728 " X: 0 + endif + finally + Xpath 268435456 " X: 268435456 + if !errcaught && !$VIMNOERRTHROW + Xpath 536870912 " X: 0 + endif + endtry +endif + +Xcheck 311511339 + + +"------------------------------------------------------------------------------- +" Test 61: Catching interrupt exceptions {{{1 +" +" When an interrupt occurs inside a :try/:endtry region, an +" interrupt exception is thrown and can be caught. Its value is +" "Vim:Interrupt". If the interrupt occurs after an error or a :throw +" but before a matching :catch is reached, all following :catches of +" that try block are ignored, but the interrupt exception can be +" caught by the next surrounding try conditional. An interrupt is +" ignored when there is a previous interrupt that has not been caught +" or causes a :finally clause to be executed. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + while 1 + try + try + Xpath 1 " X: 1 + let caught = 0 + "INTERRUPT + Xpath 2 " X: 0 + catch /^Vim:Interrupt$/ + let caught = 1 + finally + Xpath 4 " X: 4 + if caught || $VIMNOINTTHROW + Xpath 8 " X: 8 + endif + endtry + catch /.*/ + Xpath 16 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard interrupt for $VIMNOINTTHROW + endtry + endwhile + + while 1 + try + try + let caught = 0 + try + Xpath 32 " X: 32 + asdf + Xpath 64 " X: 0 + catch /do_not_catch/ + Xpath 128 " X: 0 + catch /.*/ "INTERRUPT - throw interrupt if !$VIMNOERRTHROW + Xpath 256 " X: 0 + catch /.*/ + Xpath 512 " X: 0 + finally "INTERRUPT - throw interrupt if $VIMNOERRTHROW + Xpath 1024 " X: 1024 + endtry + catch /^Vim:Interrupt$/ + let caught = 1 + finally + Xpath 2048 " X: 2048 + if caught || $VIMNOINTTHROW + Xpath 4096 " X: 4096 + endif + endtry + catch /.*/ + Xpath 8192 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard interrupt for $VIMNOINTTHROW + endtry + endwhile + + while 1 + try + try + let caught = 0 + try + Xpath 16384 " X: 16384 + throw "x" + Xpath 32768 " X: 0 + catch /do_not_catch/ + Xpath 65536 " X: 0 + catch /x/ "INTERRUPT + Xpath 131072 " X: 0 + catch /.*/ + Xpath 262144 " X: 0 + endtry + catch /^Vim:Interrupt$/ + let caught = 1 + finally + Xpath 524288 " X: 524288 + if caught || $VIMNOINTTHROW + Xpath 1048576 " X: 1048576 + endif + endtry + catch /.*/ + Xpath 2097152 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard interrupt for $VIMNOINTTHROW + endtry + endwhile + + while 1 + try + let caught = 0 + try + Xpath 4194304 " X: 4194304 + "INTERRUPT + Xpath 8388608 " X: 0 + catch /do_not_catch/ "INTERRUPT + Xpath 16777216 " X: 0 + catch /^Vim:Interrupt$/ + let caught = 1 + finally + Xpath 33554432 " X: 33554432 + if caught || $VIMNOINTTHROW + Xpath 67108864 " X: 67108864 + endif + endtry + catch /.*/ + Xpath 134217728 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard interrupt for $VIMNOINTTHROW + endtry + endwhile + + Xpath 268435456 " X: 268435456 + +endif + +Xcheck 374889517 + + +"------------------------------------------------------------------------------- +" Test 62: Catching error exceptions {{{1 +" +" An error inside a :try/:endtry region is converted to an exception +" and can be caught. The error exception has a "Vim(cmdname):" prefix +" where cmdname is the name of the failing command, or a "Vim:" prefix +" if no command name is known. The "Vim" prefixes cannot be faked. +"------------------------------------------------------------------------------- + +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 + +while 1 + try + try + let caught = 0 + unlet novar + catch /^Vim(unlet):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(unlet):', '', "") + finally + Xpath 1 " X: 1 + if !caught && !$VIMNOERRTHROW + Xpath 2 " X: 0 + endif + if !MSG('E108', "No such variable") + Xpath 4 " X: 0 + endif + endtry + catch /.*/ + Xpath 8 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +while 1 + try + try + let caught = 0 + throw novar " error in :throw + catch /^Vim(throw):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "") + finally + Xpath 16 " X: 16 + if !caught && !$VIMNOERRTHROW + Xpath 32 " X: 0 + endif + if caught ? !MSG('E121', "Undefined variable") + \ : !MSG('E15', "Invalid expression") + Xpath 64 " X: 0 + endif + endtry + catch /.*/ + Xpath 128 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +while 1 + try + try + let caught = 0 + throw "Vim:faked" " error: cannot fake Vim exception + catch /^Vim(throw):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(throw):', '', "") + finally + Xpath 256 " X: 256 + if !caught && !$VIMNOERRTHROW + Xpath 512 " X: 0 + endif + if !MSG('E608', "Cannot :throw exceptions with 'Vim' prefix") + Xpath 1024 " X: 0 + endif + endtry + catch /.*/ + Xpath 2048 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +function! F() + while 1 + " Missing :endwhile +endfunction + +while 1 + try + try + let caught = 0 + call F() + catch /^Vim(endfunction):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(endfunction):', '', "") + finally + Xpath 4096 " X: 4096 + if !caught && !$VIMNOERRTHROW + Xpath 8192 " X: 0 + endif + if !MSG('E170', "Missing :endwhile") + Xpath 16384 " X: 0 + endif + endtry + catch /.*/ + Xpath 32768 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +while 1 + try + try + let caught = 0 + ExecAsScript F + catch /^Vim:/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim:', '', "") + finally + Xpath 65536 " X: 65536 + if !caught && !$VIMNOERRTHROW + Xpath 131072 " X: 0 + endif + if !MSG('E170', "Missing :endwhile") + Xpath 262144 " X: 0 + endif + endtry + catch /.*/ + Xpath 524288 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +function! G() + call G() +endfunction + +while 1 + try + let mfd_save = &mfd + set mfd=3 + try + let caught = 0 + call G() + catch /^Vim(call):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(call):', '', "") + finally + Xpath 1048576 " X: 1048576 + if !caught && !$VIMNOERRTHROW + Xpath 2097152 " X: 0 + endif + if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'") + Xpath 4194304 " X: 0 + endif + endtry + catch /.*/ + Xpath 8388608 " X: 0 + Xout v:exception "in" v:throwpoint + finally + let &mfd = mfd_save + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +function! H() + return H() +endfunction + +while 1 + try + let mfd_save = &mfd + set mfd=3 + try + let caught = 0 + call H() + catch /^Vim(return):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(return):', '', "") + finally + Xpath 16777216 " X: 16777216 + if !caught && !$VIMNOERRTHROW + Xpath 33554432 " X: 0 + endif + if !MSG('E132', "Function call depth is higher than 'maxfuncdepth'") + Xpath 67108864 " X: 0 + endif + endtry + catch /.*/ + Xpath 134217728 " X: 0 + Xout v:exception "in" v:throwpoint + finally + let &mfd = mfd_save + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +unlet! caught mfd_save +delfunction F +delfunction G +delfunction H +Xpath 268435456 " X: 268435456 + +Xcheck 286331153 + +" Leave MSG() for the next test. + + +"------------------------------------------------------------------------------- +" Test 63: Suppressing error exceptions by :silent!. {{{1 +" +" A :silent! command inside a :try/:endtry region suppresses the +" conversion of errors to an exception and the immediate abortion on +" error. When the commands executed by the :silent! themselves open +" a new :try/:endtry region, conversion of errors to exception and +" immediate abortion is switched on again - until the next :silent! +" etc. The :silent! has the effect of setting v:errmsg to the error +" message text (without displaying it) and continuing with the next +" script line. +" +" When a command triggering autocommands is executed by :silent! +" inside a :try/:endtry, the autocommand execution is not suppressed +" on error. +" +" This test reuses the function MSG() from the previous test. +"------------------------------------------------------------------------------- + +XpathINIT + +XloopINIT! 1 4 + +let taken = "" + +function! S(n) abort + XloopNEXT + let g:taken = g:taken . "E" . a:n + let v:errmsg = "" + exec "asdf" . a:n + + " Check that ":silent!" continues: + Xloop 1 + + " Check that ":silent!" sets "v:errmsg": + if MSG('E492', "Not an editor command") + Xloop 2 + endif +endfunction + +function! Foo() + while 1 + try + try + let caught = 0 + " This is not silent: + call S(3) " X: 0 * 16 + catch /^Vim:/ + let caught = 1 + let errmsg3 = substitute(v:exception, '^Vim:', '', "") + silent! call S(4) " X: 3 * 64 + finally + if !caught + let errmsg3 = v:errmsg + " Do call S(4) here if not executed in :catch. + silent! call S(4) + endif + Xpath 1048576 " X: 1048576 + if !caught && !$VIMNOERRTHROW + Xpath 2097152 " X: 0 + endif + let v:errmsg = errmsg3 + if !MSG('E492', "Not an editor command") + Xpath 4194304 " X: 0 + endif + silent! call S(5) " X: 3 * 256 + " Break out of try conds that cover ":silent!". This also + " discards the aborting error when $VIMNOERRTHROW is non-zero. + break + endtry + catch /.*/ + Xpath 8388608 " X: 0 + Xout v:exception "in" v:throwpoint + endtry + endwhile + " This is a double ":silent!" (see caller). + silent! call S(6) " X: 3 * 1024 +endfunction + +function! Bar() + try + silent! call S(2) " X: 3 * 4 + " X: 3 * 4096 + silent! execute "call Foo() | call S(7)" + silent! call S(8) " X: 3 * 16384 + endtry " normal end of try cond that covers ":silent!" + " This has a ":silent!" from the caller: + call S(9) " X: 3 * 65536 +endfunction + +silent! call S(1) " X: 3 * 1 +silent! call Bar() +silent! call S(10) " X: 3 * 262144 + +let expected = "E1E2E3E4E5E6E7E8E9E10" +if taken != expected + Xpath 16777216 " X: 0 + Xout "'taken' is" taken "instead of" expected +endif + +augroup TMP + autocmd BufWritePost * Xpath 33554432 " X: 33554432 +augroup END + +Xpath 67108864 " X: 67108864 +write /i/m/p/o/s/s/i/b/l/e +Xpath 134217728 " X: 134217728 + +autocmd! TMP +unlet! caught errmsg3 taken expected +delfunction S +delfunction Foo +delfunction Bar +delfunction MSG + +Xcheck 236978127 + + +"------------------------------------------------------------------------------- +" Test 64: Error exceptions after error, interrupt or :throw {{{1 +" +" When an error occurs after an interrupt or a :throw but before +" a matching :catch is reached, all following :catches of that try +" block are ignored, but the error exception can be caught by the next +" surrounding try conditional. Any previous error exception is +" discarded. An error is ignored when there is a previous error that +" has not been caught. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + while 1 + try + try + Xpath 1 " X: 1 + let caught = 0 + while 1 +" if 1 + " Missing :endif + endwhile " throw error exception + catch /^Vim(/ + let caught = 1 + finally + Xpath 2 " X: 2 + if caught || $VIMNOERRTHROW + Xpath 4 " X: 4 + endif + endtry + catch /.*/ + Xpath 8 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + try + Xpath 16 " X: 16 + let caught = 0 + try +" if 1 + " Missing :endif + catch /.*/ " throw error exception + Xpath 32 " X: 0 + catch /.*/ + Xpath 64 " X: 0 + endtry + catch /^Vim(/ + let caught = 1 + finally + Xpath 128 " X: 128 + if caught || $VIMNOERRTHROW + Xpath 256 " X: 256 + endif + endtry + catch /.*/ + Xpath 512 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + try + let caught = 0 + try + Xpath 1024 " X: 1024 + "INTERRUPT + catch /do_not_catch/ + Xpath 2048 " X: 0 +" if 1 + " Missing :endif + catch /.*/ " throw error exception + Xpath 4096 " X: 0 + catch /.*/ + Xpath 8192 " X: 0 + endtry + catch /^Vim(/ + let caught = 1 + finally + Xpath 16384 " X: 16384 + if caught || $VIMNOERRTHROW + Xpath 32768 " X: 32768 + endif + endtry + catch /.*/ + Xpath 65536 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + try + let caught = 0 + try + Xpath 131072 " X: 131072 + throw "x" + catch /do_not_catch/ + Xpath 262144 " X: 0 +" if 1 + " Missing :endif + catch /x/ " throw error exception + Xpath 524288 " X: 0 + catch /.*/ + Xpath 1048576 " X: 0 + endtry + catch /^Vim(/ + let caught = 1 + finally + Xpath 2097152 " X: 2097152 + if caught || $VIMNOERRTHROW + Xpath 4194304 " X: 4194304 + endif + endtry + catch /.*/ + Xpath 8388608 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + try + let caught = 0 + Xpath 16777216 " X: 16777216 +" endif " :endif without :if; throw error exception +" if 1 + " Missing :endif + catch /do_not_catch/ " ignore new error + Xpath 33554432 " X: 0 + catch /^Vim(endif):/ + let caught = 1 + catch /^Vim(/ + Xpath 67108864 " X: 0 + finally + Xpath 134217728 " X: 134217728 + if caught || $VIMNOERRTHROW + Xpath 268435456 " X: 268435456 + endif + endtry + catch /.*/ + Xpath 536870912 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + Xpath 1073741824 " X: 1073741824 + +endif + +Xcheck 1499645335 + + +"------------------------------------------------------------------------------- +" Test 65: Errors in the /pattern/ argument of a :catch {{{1 +" +" On an error in the /pattern/ argument of a :catch, the :catch does +" not match. Any following :catches of the same :try/:endtry don't +" match either. Finally clauses are executed. +"------------------------------------------------------------------------------- + +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 + +try + try + Xpath 1 " X: 1 + throw "oops" + catch /^oops$/ + Xpath 2 " X: 2 + catch /\)/ " not checked; exception has already been caught + Xpath 4 " X: 0 + endtry + Xpath 8 " X: 8 +catch /.*/ + Xpath 16 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +function! F() + try + let caught = 0 + try + try + Xpath 32 " X: 32 + throw "ab" + catch /abc/ " does not catch + Xpath 64 " X: 0 + catch /\)/ " error; discards exception + Xpath 128 " X: 0 + catch /.*/ " not checked + Xpath 256 " X: 0 + finally + Xpath 512 " X: 512 + endtry + Xpath 1024 " X: 0 + catch /^ab$/ " checked, but original exception is discarded + Xpath 2048 " X: 0 + catch /^Vim(catch):/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim(catch):', '', "") + finally + Xpath 4096 " X: 4096 + if !caught && !$VIMNOERRTHROW + Xpath 8192 " X: 0 + endif + if caught ? !MSG('E55', 'Unmatched \\)') + \ : !MSG('E475', "Invalid argument") + Xpath 16384 " X: 0 + endif + if !caught + return | " discard error + endif + endtry + catch /.*/ + Xpath 32768 " X: 0 + Xout v:exception "in" v:throwpoint + endtry +endfunction + +call F() +Xpath 65536 " X: 65536 + +delfunction MSG +delfunction F +unlet! caught + +Xcheck 70187 + + +"------------------------------------------------------------------------------- +" Test 66: Stop range :call on error, interrupt, or :throw {{{1 +" +" When a function which is multiply called for a range since it +" doesn't handle the range itself has an error in a command +" dynamically enclosed by :try/:endtry or gets an interrupt or +" executes a :throw, no more calls for the remaining lines in the +" range are made. On an error in a command not dynamically enclosed +" by :try/:endtry, the function is executed again for the remaining +" lines in the range. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + let file = tempname() + exec "edit" file + + insert +line 1 +line 2 +line 3 +. + + XloopINIT! 1 2 + + let taken = "" + let expected = "G1EF1E(1)F1E(2)F1E(3)G2EF2E(1)G3IF3I(1)G4TF4T(1)G5AF5A(1)" + + function! F(reason, n) abort + let g:taken = g:taken . "F" . a:n . + \ substitute(a:reason, '\(\l\).*', '\u\1', "") . + \ "(" . line(".") . ")" + + if a:reason == "error" + asdf + elseif a:reason == "interrupt" + "INTERRUPT + let dummy = 0 + elseif a:reason == "throw" + throw "xyz" + elseif a:reason == "aborting error" + XloopNEXT + if g:taken != g:expected + Xloop 1 " X: 0 + Xout "'taken' is" g:taken "instead of" g:expected + endif + try + bwipeout! + call delete(file) + asdf + endtry + endif + endfunction + + function! G(reason, n) + let g:taken = g:taken . "G" . a:n . + \ substitute(a:reason, '\(\l\).*', '\u\1', "") + 1,3call F(a:reason, a:n) + endfunction + + Xpath 8 " X: 8 + call G("error", 1) + try + Xpath 16 " X: 16 + try + call G("error", 2) + Xpath 32 " X: 0 + finally + Xpath 64 " X: 64 + try + call G("interrupt", 3) + Xpath 128 " X: 0 + finally + Xpath 256 " X: 256 + try + call G("throw", 4) + Xpath 512 " X: 0 + endtry + endtry + endtry + catch /xyz/ + Xpath 1024 " X: 1024 + catch /.*/ + Xpath 2048 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + endtry + Xpath 4096 " X: 4096 + call G("aborting error", 5) + Xpath 8192 " X: 0 + Xout "'taken' is" taken "instead of" expected + +endif + +Xcheck 5464 + + +"------------------------------------------------------------------------------- +" Test 67: :throw accross :call command {{{1 +" +" On a call command, an exception might be thrown when evaluating the +" function name, during evaluation of the arguments, or when the +" function is being executed. The exception can be caught by the +" caller. +"------------------------------------------------------------------------------- + +XpathINIT + +function! THROW(x, n) + if a:n == 1 + Xpath 1 " X: 1 + elseif a:n == 2 + Xpath 2 " X: 2 + elseif a:n == 3 + Xpath 4 " X: 4 + endif + throw a:x +endfunction + +function! NAME(x, n) + if a:n == 1 + Xpath 8 " X: 0 + elseif a:n == 2 + Xpath 16 " X: 16 + elseif a:n == 3 + Xpath 32 " X: 32 + elseif a:n == 4 + Xpath 64 " X: 64 + endif + return a:x +endfunction + +function! ARG(x, n) + if a:n == 1 + Xpath 128 " X: 0 + elseif a:n == 2 + Xpath 256 " X: 0 + elseif a:n == 3 + Xpath 512 " X: 512 + elseif a:n == 4 + Xpath 1024 " X: 1024 + endif + return a:x +endfunction + +function! F(x, n) + if a:n == 2 + Xpath 2048 " X: 0 + elseif a:n == 4 + Xpath 4096 " X: 4096 + endif +endfunction + +try + + try + Xpath 8192 " X: 8192 + call {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1) + Xpath 16384 " X: 0 + catch /^name$/ + Xpath 32768 " X: 32768 + catch /.*/ + Xpath 65536 " X: 0 + Xout "1:" v:exception "in" v:throwpoint + endtry + + try + Xpath 131072 " X: 131072 + call {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2) + Xpath 262144 " X: 0 + catch /^arg$/ + Xpath 524288 " X: 524288 + catch /.*/ + Xpath 1048576 " X: 0 + Xout "2:" v:exception "in" v:throwpoint + endtry + + try + Xpath 2097152 " X: 2097152 + call {NAME("THROW", 3)}(ARG("call", 3), 3) + Xpath 4194304 " X: 0 + catch /^call$/ + Xpath 8388608 " X: 8388608 + catch /^0$/ " default return value + Xpath 16777216 " X: 0 + Xout "3:" v:throwpoint + catch /.*/ + Xpath 33554432 " X: 0 + Xout "3:" v:exception "in" v:throwpoint + endtry + + try + Xpath 67108864 " X: 67108864 + call {NAME("F", 4)}(ARG(4711, 4), 4) + Xpath 134217728 " X: 134217728 + catch /.*/ + Xpath 268435456 " X: 0 + Xout "4:" v:exception "in" v:throwpoint + endtry + +catch /^0$/ " default return value + Xpath 536870912 " X: 0 + Xout v:throwpoint +catch /.*/ + Xpath 1073741824 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +delfunction F + +Xcheck 212514423 + +" Leave THROW(), NAME(), and ARG() for the next test. + + +"------------------------------------------------------------------------------- +" Test 68: :throw accross function calls in expressions {{{1 +" +" On a function call within an expression, an exception might be +" thrown when evaluating the function name, during evaluation of the +" arguments, or when the function is being executed. The exception +" can be caught by the caller. +" +" This test reuses the functions THROW(), NAME(), and ARG() from the +" previous test. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F(x, n) + if a:n == 2 + Xpath 2048 " X: 0 + elseif a:n == 4 + Xpath 4096 " X: 4096 + endif + return a:x +endfunction + +unlet! var1 var2 var3 var4 + +try + + try + Xpath 8192 " X: 8192 + let var1 = {NAME(THROW("name", 1), 1)}(ARG(4711, 1), 1) + Xpath 16384 " X: 0 + catch /^name$/ + Xpath 32768 " X: 32768 + catch /.*/ + Xpath 65536 " X: 0 + Xout "1:" v:exception "in" v:throwpoint + endtry + + try + Xpath 131072 " X: 131072 + let var2 = {NAME("F", 2)}(ARG(THROW("arg", 2), 2), 2) + Xpath 262144 " X: 0 + catch /^arg$/ + Xpath 524288 " X: 524288 + catch /.*/ + Xpath 1048576 " X: 0 + Xout "2:" v:exception "in" v:throwpoint + endtry + + try + Xpath 2097152 " X: 2097152 + let var3 = {NAME("THROW", 3)}(ARG("call", 3), 3) + Xpath 4194304 " X: 0 + catch /^call$/ + Xpath 8388608 " X: 8388608 + catch /^0$/ " default return value + Xpath 16777216 " X: 0 + Xout "3:" v:throwpoint + catch /.*/ + Xpath 33554432 " X: 0 + Xout "3:" v:exception "in" v:throwpoint + endtry + + try + Xpath 67108864 " X: 67108864 + let var4 = {NAME("F", 4)}(ARG(4711, 4), 4) + Xpath 134217728 " X: 134217728 + catch /.*/ + Xpath 268435456 " X: 0 + Xout "4:" v:exception "in" v:throwpoint + endtry + +catch /^0$/ " default return value + Xpath 536870912 " X: 0 + Xout v:throwpoint +catch /.*/ + Xpath 1073741824 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +if exists("var1") || exists("var2") || exists("var3") || + \ !exists("var4") || var4 != 4711 + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + if exists("var1") + Xout "var1 =" var1 + endif + if exists("var2") + Xout "var2 =" var2 + endif + if exists("var3") + Xout "var3 =" var3 + endif + if !exists("var4") + Xout "var4 unset" + elseif var4 != 4711 + Xout "var4 =" var4 + endif +endif + +unlet! var1 var2 var3 var4 +delfunction THROW +delfunction NAME +delfunction ARG +delfunction F + +Xcheck 212514423 + + +"------------------------------------------------------------------------------- +" Test 69: :throw accross :if, :elseif, :while {{{1 +" +" On an :if, :elseif, or :while command, an exception might be thrown +" during evaluation of the expression to test. The exception can be +" caught by the script. +"------------------------------------------------------------------------------- + +XpathINIT + +XloopINIT! 1 2 + +function! THROW(x) + XloopNEXT + Xloop 1 " X: 1 + 2 + 4 + throw a:x +endfunction + +try + + try + Xpath 8 " X: 8 + if 4711 == THROW("if") + 111 + Xpath 16 " X: 0 + else + Xpath 32 " X: 0 + endif + Xpath 64 " X: 0 + catch /^if$/ + Xpath 128 " X: 128 + catch /.*/ + Xpath 256 " X: 0 + Xout "if:" v:exception "in" v:throwpoint + endtry + + try + Xpath 512 " X: 512 + if 4711 == 4 + 7 + 1 + 1 + Xpath 1024 " X: 0 + elseif 4711 == THROW("elseif") + 222 + Xpath 2048 " X: 0 + else + Xpath 4096 " X: 0 + endif + Xpath 8192 " X: 0 + catch /^elseif$/ + Xpath 16384 " X: 16384 + catch /.*/ + Xpath 32768 " X: 0 + Xout "elseif:" v:exception "in" v:throwpoint + endtry + + try + Xpath 65536 " X: 65536 + while 4711 == THROW("while") + 4711 + Xpath 131072 " X: 0 + break + endwhile + Xpath 262144 " X: 0 + catch /^while$/ + Xpath 524288 " X: 524288 + catch /.*/ + Xpath 1048576 " X: 0 + Xout "while:" v:exception "in" v:throwpoint + endtry + +catch /^0$/ " default return value + Xpath 2097152 " X: 0 + Xout v:throwpoint +catch /.*/ + Xout v:exception "in" v:throwpoint + Xpath 4194304 " X: 0 +endtry + +Xpath 8388608 " X: 8388608 + +delfunction THROW + +Xcheck 8995471 + + +"------------------------------------------------------------------------------- +" Test 70: :throw accross :return or :throw {{{1 +" +" On a :return or :throw command, an exception might be thrown during +" evaluation of the expression to return or throw, respectively. The +" exception can be caught by the script. +"------------------------------------------------------------------------------- + +XpathINIT + +let taken = "" + +function! THROW(x, n) + let g:taken = g:taken . "T" . a:n + throw a:x +endfunction + +function! F(x, y, n) + let g:taken = g:taken . "F" . a:n + return a:x + THROW(a:y, a:n) +endfunction + +function! G(x, y, n) + let g:taken = g:taken . "G" . a:n + throw a:x . THROW(a:y, a:n) + return a:x +endfunction + +try + try + Xpath 1 " X: 1 + call F(4711, "return", 1) + Xpath 2 " X: 0 + catch /^return$/ + Xpath 4 " X: 4 + catch /.*/ + Xpath 8 " X: 0 + Xout "return:" v:exception "in" v:throwpoint + endtry + + try + Xpath 16 " X: 16 + let var = F(4712, "return-var", 2) + Xpath 32 " X: 0 + catch /^return-var$/ + Xpath 64 " X: 64 + catch /.*/ + Xpath 128 " X: 0 + Xout "return-var:" v:exception "in" v:throwpoint + finally + unlet! var + endtry + + try + Xpath 256 " X: 256 + throw "except1" . THROW("throw1", 3) + Xpath 512 " X: 0 + catch /^except1/ + Xpath 1024 " X: 0 + catch /^throw1$/ + Xpath 2048 " X: 2048 + catch /.*/ + Xpath 4096 " X: 0 + Xout "throw1:" v:exception "in" v:throwpoint + endtry + + try + Xpath 8192 " X: 8192 + call G("except2", "throw2", 4) + Xpath 16384 " X: 0 + catch /^except2/ + Xpath 32768 " X: 0 + catch /^throw2$/ + Xpath 65536 " X: 65536 + catch /.*/ + Xpath 131072 " X: 0 + Xout "throw2:" v:exception "in" v:throwpoint + endtry + + try + Xpath 262144 " X: 262144 + let var = G("except3", "throw3", 5) + Xpath 524288 " X: 0 + catch /^except3/ + Xpath 1048576 " X: 0 + catch /^throw3$/ + Xpath 2097152 " X: 2097152 + catch /.*/ + Xpath 4194304 " X: 0 + Xout "throw3:" v:exception "in" v:throwpoint + finally + unlet! var + endtry + + let expected = "F1T1F2T2T3G4T4G5T5" + if taken != expected + Xpath 8388608 " X: 0 + Xout "'taken' is" taken "instead of" expected + endif + +catch /^0$/ " default return value + Xpath 16777216 " X: 0 + Xout v:throwpoint +catch /.*/ + Xpath 33554432 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xpath 67108864 " X: 67108864 + +unlet taken expected +delfunction THROW +delfunction F +delfunction G + +Xcheck 69544277 + + +"------------------------------------------------------------------------------- +" Test 71: :throw accross :echo variants and :execute {{{1 +" +" On an :echo, :echon, :echomsg, :echoerr, or :execute command, an +" exception might be thrown during evaluation of the arguments to +" be displayed or executed as a command, respectively. Any following +" arguments are not evaluated, then. The exception can be caught by +" the script. +"------------------------------------------------------------------------------- + +XpathINIT + +let taken = "" + +function! THROW(x, n) + let g:taken = g:taken . "T" . a:n + throw a:x +endfunction + +function! F(n) + let g:taken = g:taken . "F" . a:n + return "F" . a:n +endfunction + +try + try + Xpath 1 " X: 1 + echo "echo" . THROW("echo-except", 1) F(1) + Xpath 2 " X: 0 + catch /^echo-except$/ + Xpath 4 " X: 4 + catch /.*/ + Xpath 8 " X: 0 + Xout "echo:" v:exception "in" v:throwpoint + endtry + + try + Xpath 16 " X: 16 + echon "echon" . THROW("echon-except", 2) F(2) + Xpath 32 " X: 0 + catch /^echon-except$/ + Xpath 64 " X: 64 + catch /.*/ + Xpath 128 " X: 0 + Xout "echon:" v:exception "in" v:throwpoint + endtry + + try + Xpath 256 " X: 256 + echomsg "echomsg" . THROW("echomsg-except", 3) F(3) + Xpath 512 " X: 0 + catch /^echomsg-except$/ + Xpath 1024 " X: 1024 + catch /.*/ + Xpath 2048 " X: 0 + Xout "echomsg:" v:exception "in" v:throwpoint + endtry + + try + Xpath 4096 " X: 4096 + echoerr "echoerr" . THROW("echoerr-except", 4) F(4) + Xpath 8192 " X: 0 + catch /^echoerr-except$/ + Xpath 16384 " X: 16384 + catch /Vim/ + Xpath 32768 " X: 0 + catch /echoerr/ + Xpath 65536 " X: 0 + catch /.*/ + Xpath 131072 " X: 0 + Xout "echoerr:" v:exception "in" v:throwpoint + endtry + + try + Xpath 262144 " X: 262144 + execute "echo 'execute" . THROW("execute-except", 5) F(5) "'" + Xpath 524288 " X: 0 + catch /^execute-except$/ + Xpath 1048576 " X: 1048576 + catch /.*/ + Xpath 2097152 " X: 0 + Xout "execute:" v:exception "in" v:throwpoint + endtry + + let expected = "T1T2T3T4T5" + if taken != expected + Xpath 4194304 " X: 0 + Xout "'taken' is" taken "instead of" expected + endif + +catch /^0$/ " default return value + Xpath 8388608 " X: 0 + Xout v:throwpoint +catch /.*/ + Xpath 16777216 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xpath 33554432 " X: 33554432 + +unlet taken expected +delfunction THROW +delfunction F + +Xcheck 34886997 + + +"------------------------------------------------------------------------------- +" Test 72: :throw accross :let or :unlet {{{1 +" +" On a :let command, an exception might be thrown during evaluation +" of the expression to assign. On an :let or :unlet command, the +" evaluation of the name of the variable to be assigned or list or +" deleted, respectively, may throw an exception. Any following +" arguments are not evaluated, then. The exception can be caught by +" the script. +"------------------------------------------------------------------------------- + +XpathINIT + +let throwcount = 0 + +function! THROW(x) + let g:throwcount = g:throwcount + 1 + throw a:x +endfunction + +try + try + let $VAR = "old_value" + Xpath 1 " X: 1 + let $VAR = "let(" . THROW("var") . ")" + Xpath 2 " X: 0 + catch /^var$/ + Xpath 4 " X: 4 + finally + if $VAR != "old_value" + Xpath 8 " X: 0 + endif + endtry + + try + let @a = "old_value" + Xpath 16 " X: 16 + let @a = "let(" . THROW("reg") . ")" + Xpath 32 " X: 0 + catch /^reg$/ + try + Xpath 64 " X: 64 + let @A = "let(" . THROW("REG") . ")" + Xpath 128 " X: 0 + catch /^REG$/ + Xpath 256 " X: 256 + endtry + finally + if @a != "old_value" + Xpath 512 " X: 0 + endif + if @A != "old_value" + Xpath 1024 " X: 0 + endif + endtry + + try + let saved_gpath = &g:path + let saved_lpath = &l:path + Xpath 2048 " X: 2048 + let &path = "let(" . THROW("opt") . ")" + Xpath 4096 " X: 0 + catch /^opt$/ + try + Xpath 8192 " X: 8192 + let &g:path = "let(" . THROW("gopt") . ")" + Xpath 16384 " X: 0 + catch /^gopt$/ + try + Xpath 32768 " X: 32768 + let &l:path = "let(" . THROW("lopt") . ")" + Xpath 65536 " X: 0 + catch /^lopt$/ + Xpath 131072 " X: 131072 + endtry + endtry + finally + if &g:path != saved_gpath || &l:path != saved_lpath + Xpath 262144 " X: 0 + endif + let &g:path = saved_gpath + let &l:path = saved_lpath + endtry + + unlet! var1 var2 var3 + + try + Xpath 524288 " X: 524288 + let var1 = "let(" . THROW("var1") . ")" + Xpath 1048576 " X: 0 + catch /^var1$/ + Xpath 2097152 " X: 2097152 + finally + if exists("var1") + Xpath 4194304 " X: 0 + endif + endtry + + try + let var2 = "old_value" + Xpath 8388608 " X: 8388608 + let var2 = "let(" . THROW("var2"). ")" + Xpath 16777216 " X: 0 + catch /^var2$/ + Xpath 33554432 " X: 33554432 + finally + if var2 != "old_value" + Xpath 67108864 " X: 0 + endif + endtry + + try + Xpath 134217728 " X: 134217728 + let var{THROW("var3")} = 4711 + Xpath 268435456 " X: 0 + catch /^var3$/ + Xpath 536870912 " X: 536870912 + endtry + + let addpath = "" + + function ADDPATH(p) + let g:addpath = g:addpath . a:p + endfunction + + try + call ADDPATH("T1") + let var{THROW("var4")} var{ADDPATH("T2")} | call ADDPATH("T3") + call ADDPATH("T4") + catch /^var4$/ + call ADDPATH("T5") + endtry + + try + call ADDPATH("T6") + unlet var{THROW("var5")} var{ADDPATH("T7")} | call ADDPATH("T8") + call ADDPATH("T9") + catch /^var5$/ + call ADDPATH("T10") + endtry + + if addpath != "T1T5T6T10" || throwcount != 11 + throw "addpath: " . addpath . ", throwcount: " . throwcount + endif + + Xpath 1073741824 " X: 1073741824 + +catch /.*/ + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +unlet! var1 var2 var3 addpath throwcount +delfunction THROW + +Xcheck 1789569365 + + +"------------------------------------------------------------------------------- +" Test 73: :throw accross :function, :delfunction {{{1 +" +" The :function and :delfunction commands may cause an expression +" specified in braces to be evaluated. During evaluation, an +" exception might be thrown. The exception can be caught by the +" script. +"------------------------------------------------------------------------------- + +XpathINIT + +let taken = "" + +function! THROW(x, n) + let g:taken = g:taken . "T" . a:n + throw a:x +endfunction + +function! EXPR(x, n) + let g:taken = g:taken . "E" . a:n + if a:n % 2 == 0 + call THROW(a:x, a:n) + endif + return 2 - a:n % 2 +endfunction + +try + try + " Define function. + Xpath 1 " X: 1 + function! F0() + endfunction + Xpath 2 " X: 2 + function! F{EXPR("function-def-ok", 1)}() + endfunction + Xpath 4 " X: 4 + function! F{EXPR("function-def", 2)}() + endfunction + Xpath 8 " X: 0 + catch /^function-def-ok$/ + Xpath 16 " X: 0 + catch /^function-def$/ + Xpath 32 " X: 32 + catch /.*/ + Xpath 64 " X: 0 + Xout "def:" v:exception "in" v:throwpoint + endtry + + try + " List function. + Xpath 128 " X: 128 + function F0 + Xpath 256 " X: 256 + function F{EXPR("function-lst-ok", 3)} + Xpath 512 " X: 512 + function F{EXPR("function-lst", 4)} + Xpath 1024 " X: 0 + catch /^function-lst-ok$/ + Xpath 2048 " X: 0 + catch /^function-lst$/ + Xpath 4096 " X: 4096 + catch /.*/ + Xpath 8192 " X: 0 + Xout "lst:" v:exception "in" v:throwpoint + endtry + + try + " Delete function + Xpath 16384 " X: 16384 + delfunction F0 + Xpath 32768 " X: 32768 + delfunction F{EXPR("function-del-ok", 5)} + Xpath 65536 " X: 65536 + delfunction F{EXPR("function-del", 6)} + Xpath 131072 " X: 0 + catch /^function-del-ok$/ + Xpath 262144 " X: 0 + catch /^function-del$/ + Xpath 524288 " X: 524288 + catch /.*/ + Xpath 1048576 " X: 0 + Xout "del:" v:exception "in" v:throwpoint + endtry + + let expected = "E1E2T2E3E4T4E5E6T6" + if taken != expected + Xpath 2097152 " X: 0 + Xout "'taken' is" taken "instead of" expected + endif + +catch /.*/ + Xpath 4194304 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +Xpath 8388608 " X: 8388608 + +unlet taken expected +delfunction THROW +delfunction EXPR + +Xcheck 9032615 + + +"------------------------------------------------------------------------------- +" Test 74: :throw accross builtin functions and commands {{{1 +" +" Some functions like exists(), searchpair() take expression +" arguments, other functions or commands like substitute() or +" :substitute cause an expression (specified in the regular +" expression) to be evaluated. During evaluation an exception +" might be thrown. The exception can be caught by the script. +"------------------------------------------------------------------------------- + +XpathINIT + +let taken = "" + +function! THROW(x, n) + let g:taken = g:taken . "T" . a:n + throw a:x +endfunction + +function! EXPR(x, n) + let g:taken = g:taken . "E" . a:n + call THROW(a:x . a:n, a:n) + return "EXPR" +endfunction + +function! SKIP(x, n) + let g:taken = g:taken . "S" . a:n . "(" . line(".") + let theline = getline(".") + if theline =~ "skip" + let g:taken = g:taken . "s)" + return 1 + elseif theline =~ "throw" + let g:taken = g:taken . "t)" + call THROW(a:x . a:n, a:n) + else + let g:taken = g:taken . ")" + return 0 + endif +endfunction + +function! SUBST(x, n) + let g:taken = g:taken . "U" . a:n . "(" . line(".") + let theline = getline(".") + if theline =~ "not" " SUBST() should not be called for this line + let g:taken = g:taken . "n)" + call THROW(a:x . a:n, a:n) + elseif theline =~ "throw" + let g:taken = g:taken . "t)" + call THROW(a:x . a:n, a:n) + else + let g:taken = g:taken . ")" + return "replaced" + endif +endfunction + +try + try + Xpath 1 " X: 1 + let result = exists('*{EXPR("exists", 1)}') + Xpath 2 " X: 0 + catch /^exists1$/ + Xpath 4 " X: 4 + try + let result = exists('{EXPR("exists", 2)}') + Xpath 8 " X: 0 + catch /^exists2$/ + Xpath 16 " X: 16 + catch /.*/ + Xpath 32 " X: 0 + Xout "exists2:" v:exception "in" v:throwpoint + endtry + catch /.*/ + Xpath 64 " X: 0 + Xout "exists1:" v:exception "in" v:throwpoint + endtry + + try + let file = tempname() + exec "edit" file + insert +begin + xx +middle 3 + xx +middle 5 skip + xx +middle 7 throw + xx +end +. + normal! gg + Xpath 128 " X: 128 + let result = + \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 3)') + Xpath 256 " X: 256 + let result = + \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 4)') + Xpath 512 " X: 0 + let result = + \ searchpair("begin", "middle", "end", '', 'SKIP("searchpair", 5)') + Xpath 1024 " X: 0 + catch /^searchpair[35]$/ + Xpath 2048 " X: 0 + catch /^searchpair4$/ + Xpath 4096 " X: 4096 + catch /.*/ + Xpath 8192 " X: 0 + Xout "searchpair:" v:exception "in" v:throwpoint + finally + bwipeout! + call delete(file) + endtry + + try + let file = tempname() + exec "edit" file + insert +subst 1 +subst 2 +not +subst 4 +subst throw +subst 6 +. + normal! gg + Xpath 16384 " X: 16384 + 1,2substitute/subst/\=SUBST("substitute", 6)/ + try + Xpath 32768 " X: 32768 + try + let v:errmsg = "" + 3substitute/subst/\=SUBST("substitute", 7)/ + finally + if v:errmsg != "" + " If exceptions are not thrown on errors, fake the error + " exception in order to get the same execution path. + throw "faked Vim(substitute)" + endif + endtry + catch /Vim(substitute)/ " Pattern not found ('e' flag missing) + Xpath 65536 " X: 65536 + 3substitute/subst/\=SUBST("substitute", 8)/e + Xpath 131072 " X: 131072 + endtry + Xpath 262144 " X: 262144 + 4,6substitute/subst/\=SUBST("substitute", 9)/ + Xpath 524288 " X: 0 + catch /^substitute[678]/ + Xpath 1048576 " X: 0 + catch /^substitute9/ + Xpath 2097152 " X: 2097152 + finally + bwipeout! + call delete(file) + endtry + + try + Xpath 4194304 " X: 4194304 + let var = substitute("sub", "sub", '\=THROW("substitute()y", 10)', '') + Xpath 8388608 " X: 0 + catch /substitute()y/ + Xpath 16777216 " X: 16777216 + catch /.*/ + Xpath 33554432 " X: 0 + Xout "substitute()y:" v:exception "in" v:throwpoint + endtry + + try + Xpath 67108864 " X: 67108864 + let var = substitute("not", "sub", '\=THROW("substitute()n", 11)', '') + Xpath 134217728 " X: 134217728 + catch /substitute()n/ + Xpath 268435456 " X: 0 + catch /.*/ + Xpath 536870912 " X: 0 + Xout "substitute()n:" v:exception "in" v:throwpoint + endtry + + let expected = "E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10" + if taken != expected + Xpath 1073741824 " X: 0 + Xout "'taken' is" taken "instead of" expected + endif + +catch /.*/ + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +unlet result var taken expected +delfunction THROW +delfunction EXPR +delfunction SKIP +delfunction SUBST + +Xcheck 224907669 + + +"------------------------------------------------------------------------------- +" Test 75: Errors in builtin functions. {{{1 +" +" On an error in a builtin function called inside a :try/:endtry +" region, the evaluation of the expression calling that function and +" the command containing that expression are abandoned. The error can +" be caught as an exception. +" +" A simple :call of the builtin function is a trivial case. If the +" builtin function is called in the argument list of another function, +" no further arguments are evaluated, and the other function is not +" executed. If the builtin function is called from the argument of +" a :return command, the :return command is not executed. If the +" builtin function is called from the argument of a :throw command, +" the :throw command is not executed. The evaluation of the +" expression calling the builtin function is abandoned. +"------------------------------------------------------------------------------- + +XpathINIT + +function! F1(arg1) + Xpath 1 " X: 0 +endfunction + +function! F2(arg1, arg2) + Xpath 2 " X: 0 +endfunction + +function! G() + Xpath 4 " X: 0 +endfunction + +function! H() + Xpath 8 " X: 0 +endfunction + +function! R() + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 16 " X: 16 + return append(1, "s") + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 32 " X: 0 + finally + Xpath 64 " X: 64 + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 128 " X: 128 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + Xpath 256 " X: 256 +endfunction + +try + set noma " let append() fail with "E21" + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 512 " X: 512 + call append(1, "s") + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 1024 " X: 0 + finally + Xpath 2048 " X: 2048 + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 4096 " X: 4096 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 8192 " X: 8192 + call F1('x' . append(1, "s")) + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 16384 " X: 0 + finally + Xpath 32768 " X: 32768 + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 65536 " X: 65536 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 131072 " X: 131072 + call F2('x' . append(1, "s"), G()) + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 262144 " X: 0 + finally + Xpath 524288 " X: 524288 + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 1048576 " X: 1048576 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + call R() + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 2097152 " X: 2097152 + throw "T" . append(1, "s") + catch /E21/ + let caught = 1 + catch /^T.*/ + Xpath 4194304 " X: 0 + catch /.*/ + Xpath 8388608 " X: 0 + finally + Xpath 16777216 " X: 16777216 + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 33554432 " X: 33554432 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile + + while 1 + try + let caught = 0 + let v:errmsg = "" + Xpath 67108864 " X: 67108864 + let x = "a" + let x = x . "b" . append(1, "s") . H() + catch /E21/ + let caught = 1 + catch /.*/ + Xpath 134217728 " X: 0 + finally + Xpath 268435456 " X: 268435456 + if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21' + Xpath 536870912 " X: 536870912 + endif + if x == "a" + Xpath 1073741824 " X: 1073741824 + endif + break " discard error for $VIMNOERRTHROW + endtry + endwhile +catch /.*/ + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + Xout v:exception "in" v:throwpoint +finally + set ma& +endtry + +unlet! caught x +delfunction F1 +delfunction F2 +delfunction G +delfunction H +delfunction R + +Xcheck 2000403408 + + +"------------------------------------------------------------------------------- +" Test 76: Errors, interupts, :throw during expression evaluation {{{1 +" +" When a function call made during expression evaluation is aborted +" due to an error inside a :try/:endtry region or due to an interrupt +" or a :throw, the expression evaluation is aborted as well. No +" message is displayed for the cancelled expression evaluation. On an +" error not inside :try/:endtry, the expression evaluation continues. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + let taken = "" + + function! ERR(n) + let g:taken = g:taken . "E" . a:n + asdf + endfunction + + function! ERRabort(n) abort + let g:taken = g:taken . "A" . a:n + asdf + endfunction " returns -1 + + function! INT(n) + let g:taken = g:taken . "I" . a:n + "INTERRUPT9 + let dummy = 0 + endfunction + + function! THR(n) + let g:taken = g:taken . "T" . a:n + throw "should not be caught" + endfunction + + function! CONT(n) + let g:taken = g:taken . "C" . a:n + endfunction + + function! MSG(n) + let g:taken = g:taken . "M" . a:n + if (a:n >= 10 && a:n <= 27) ? v:errmsg != "" : v:errmsg !~ "asdf" + let g:taken = g:taken . "x" + endif + let v:errmsg = "" + endfunction + + let v:errmsg = "" + + try + let t = 1 + XloopINIT 1 2 + while t <= 9 + Xloop 1 " X: 511 + try + if t == 1 + let v{ERR(t) + CONT(t)} = 0 + elseif t == 2 + let v{ERR(t) + CONT(t)} + elseif t == 3 + let var = exists('v{ERR(t) + CONT(t)}') + elseif t == 4 + unlet v{ERR(t) + CONT(t)} + elseif t == 5 + function F{ERR(t) + CONT(t)}() + endfunction + elseif t == 6 + function F{ERR(t) + CONT(t)} + elseif t == 7 + let var = exists('*F{ERR(t) + CONT(t)}') + elseif t == 8 + delfunction F{ERR(t) + CONT(t)} + elseif t == 9 + let var = ERR(t) + CONT(t) + endif + catch /asdf/ + " v:errmsg is not set when the error message is converted to an + " exception. Set it to the original error message. + let v:errmsg = substitute(v:exception, '^Vim:', '', "") + catch /^Vim\((\a\+)\)\=:/ + " An error exception has been thrown after the original error. + let v:errmsg = "" + finally + call MSG(t) + let t = t + 1 + XloopNEXT + continue " discard an aborting error + endtry + endwhile + catch /.*/ + Xpath 512 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + endtry + + try + let t = 10 + XloopINIT 1024 2 + while t <= 18 + Xloop 1 " X: 1024 * 511 + try + if t == 10 + let v{INT(t) + CONT(t)} = 0 + elseif t == 11 + let v{INT(t) + CONT(t)} + elseif t == 12 + let var = exists('v{INT(t) + CONT(t)}') + elseif t == 13 + unlet v{INT(t) + CONT(t)} + elseif t == 14 + function F{INT(t) + CONT(t)}() + endfunction + elseif t == 15 + function F{INT(t) + CONT(t)} + elseif t == 16 + let var = exists('*F{INT(t) + CONT(t)}') + elseif t == 17 + delfunction F{INT(t) + CONT(t)} + elseif t == 18 + let var = INT(t) + CONT(t) + endif + catch /^Vim\((\a\+)\)\=:\(Interrupt\)\@!/ + " An error exception has been triggered after the interrupt. + let v:errmsg = substitute(v:exception, + \ '^Vim\((\a\+)\)\=:', '', "") + finally + call MSG(t) + let t = t + 1 + XloopNEXT + continue " discard interrupt + endtry + endwhile + catch /.*/ + Xpath 524288 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + endtry + + try + let t = 19 + XloopINIT 1048576 2 + while t <= 27 + Xloop 1 " X: 1048576 * 511 + try + if t == 19 + let v{THR(t) + CONT(t)} = 0 + elseif t == 20 + let v{THR(t) + CONT(t)} + elseif t == 21 + let var = exists('v{THR(t) + CONT(t)}') + elseif t == 22 + unlet v{THR(t) + CONT(t)} + elseif t == 23 + function F{THR(t) + CONT(t)}() + endfunction + elseif t == 24 + function F{THR(t) + CONT(t)} + elseif t == 25 + let var = exists('*F{THR(t) + CONT(t)}') + elseif t == 26 + delfunction F{THR(t) + CONT(t)} + elseif t == 27 + let var = THR(t) + CONT(t) + endif + catch /^Vim\((\a\+)\)\=:/ + " An error exception has been triggered after the :throw. + let v:errmsg = substitute(v:exception, + \ '^Vim\((\a\+)\)\=:', '', "") + finally + call MSG(t) + let t = t + 1 + XloopNEXT + continue " discard exception + endtry + endwhile + catch /.*/ + Xpath 536870912 " X: 0 + Xout v:exception "in" ExtraVimThrowpoint() + endtry + + let v{ERR(28) + CONT(28)} = 0 + call MSG(28) + let v{ERR(29) + CONT(29)} + call MSG(29) + let var = exists('v{ERR(30) + CONT(30)}') + call MSG(30) + unlet v{ERR(31) + CONT(31)} + call MSG(31) + function F{ERR(32) + CONT(32)}() + endfunction + call MSG(32) + function F{ERR(33) + CONT(33)} + call MSG(33) + let var = exists('*F{ERR(34) + CONT(34)}') + call MSG(34) + delfunction F{ERR(35) + CONT(35)} + call MSG(35) + let var = ERR(36) + CONT(36) + call MSG(36) + + let v{ERRabort(37) + CONT(37)} = 0 + call MSG(37) + let v{ERRabort(38) + CONT(38)} + call MSG(38) + let var = exists('v{ERRabort(39) + CONT(39)}') + call MSG(39) + unlet v{ERRabort(40) + CONT(40)} + call MSG(40) + function F{ERRabort(41) + CONT(41)}() + endfunction + call MSG(41) + function F{ERRabort(42) + CONT(42)} + call MSG(42) + let var = exists('*F{ERRabort(43) + CONT(43)}') + call MSG(43) + delfunction F{ERRabort(44) + CONT(44)} + call MSG(44) + let var = ERRabort(45) + CONT(45) + call MSG(45) + + Xpath 1073741824 " X: 1073741824 + + let expected = "" + \ . "E1M1E2M2E3M3E4M4E5M5E6M6E7M7E8M8E9M9" + \ . "I10M10I11M11I12M12I13M13I14M14I15M15I16M16I17M17I18M18" + \ . "T19M19T20M20T21M21T22M22T23M23T24M24T25M25T26M26T27M27" + \ . "E28C28M28E29C29M29E30C30M30E31C31M31E32C32M32E33C33M33" + \ . "E34C34M34E35C35M35E36C36M36" + \ . "A37C37M37A38C38M38A39C39M39A40C40M40A41C41M41A42C42M42" + \ . "A43C43M43A44C44M44A45C45M45" + + if taken != expected + " The Xpath command does not accept 2^31 (negative); display explicitly: + exec "!echo 2147483648 >>" . g:ExtraVimResult + " X: 0 + Xout "'taken' is" taken "instead of" expected + if substitute(taken, + \ '\(.*\)E3C3M3x\(.*\)E30C30M30x\(.*\)A39C39M39x\(.*\)', + \ '\1E3M3\2E30C30M30\3A39C39M39\4', + \ "") == expected + Xout "Is ++emsg_skip for var with expr_start non-NULL" + \ "in f_exists ok?" + endif + endif + + unlet! var taken expected + call delete(WA_t5) + call delete(WA_t14) + call delete(WA_t23) + unlet! WA_t5 WA_t14 WA_t23 + delfunction WA_t5 + delfunction WA_t14 + delfunction WA_t23 + +endif + +Xcheck 1610087935 + + +"------------------------------------------------------------------------------- +" Test 77: Errors, interupts, :throw in name{brace-expression} {{{1 +" +" When a function call made during evaluation of an expression in +" braces as part of a function name after ":function" is aborted due +" to an error inside a :try/:endtry region or due to an interrupt or +" a :throw, the expression evaluation is aborted as well, and the +" function definition is ignored, skipping all commands to the +" ":endfunction". On an error not inside :try/:endtry, the expression +" evaluation continues and the function gets defined, and can be +" called and deleted. +"------------------------------------------------------------------------------- + +XpathINIT + +XloopINIT 1 4 + +function! ERR() abort + Xloop 1 " X: 1 + 4 + 16 + 64 + asdf +endfunction " returns -1 + +function! OK() + Xloop 2 " X: 2 * (1 + 4 + 16) + let v:errmsg = "" + return 0 +endfunction + +let v:errmsg = "" + +Xpath 4096 " X: 4096 +function! F{1 + ERR() + OK()}(arg) + " F0 should be defined. + if exists("a:arg") && a:arg == "calling" + Xpath 8192 " X: 8192 + else + Xpath 16384 " X: 0 + endif +endfunction +if v:errmsg != "" + Xpath 32768 " X: 0 +endif +XloopNEXT + +Xpath 65536 " X: 65536 +call F{1 + ERR() + OK()}("calling") +if v:errmsg != "" + Xpath 131072 " X: 0 +endif +XloopNEXT + +Xpath 262144 " X: 262144 +delfunction F{1 + ERR() + OK()} +if v:errmsg != "" + Xpath 524288 " X: 0 +endif +XloopNEXT + +try + while 1 + let caught = 0 + try + Xpath 1048576 " X: 1048576 + function! G{1 + ERR() + OK()}(arg) + " G0 should not be defined, and the function body should be + " skipped. + if exists("a:arg") && a:arg == "calling" + Xpath 2097152 " X: 0 + else + Xpath 4194304 " X: 0 + endif + " Use an unmatched ":finally" to check whether the body is + " skipped when an error occurs in ERR(). This works whether or + " not the exception is converted to an exception. + finally + Xpath 8388608 " X: 0 + Xout "Body of G{1 + ERR() + OK()}() not skipped" + " Discard the aborting error or exception, and break the + " while loop. + break + " End the try conditional and start a new one to avoid + " ":catch after :finally" errors. + endtry + try + Xpath 16777216 " X: 0 + endfunction + + " When the function was not defined, this won't be reached - whether + " the body was skipped or not. When the function was defined, it + " can be called and deleted here. + Xpath 33554432 " X: 0 + Xout "G0() has been defined" + XloopNEXT + try + call G{1 + ERR() + OK()}("calling") + catch /.*/ + Xpath 67108864 " X: 0 + endtry + Xpath 134217728 " X: 0 + XloopNEXT + try + delfunction G{1 + ERR() + OK()} + catch /.*/ + Xpath 268435456 " X: 0 + endtry + catch /asdf/ + " Jumped to when the function is not defined and the body is + " skipped. + let caught = 1 + catch /.*/ + Xpath 536870912 " X: 0 + finally + if !caught && !$VIMNOERRTHROW + Xpath 1073741824 " X: 0 + endif + break " discard error for $VIMNOERRTHROW + endtry " jumped to when the body is not skipped + endwhile +catch /.*/ + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + Xout "Body of G{1 + ERR() + OK()}() not skipped, exception caught" + Xout v:exception "in" v:throwpoint +endtry + +Xcheck 1388671 + + +"------------------------------------------------------------------------------- +" Test 78: Messages on parsing errors in expression evaluation {{{1 +" +" When an expression evaluation detects a parsing error, an error +" message is given and converted to an exception, and the expression +" evaluation is aborted. +"------------------------------------------------------------------------------- + +XpathINIT + +if ExtraVim() + + let taken = "" + + function! F(n) + let g:taken = g:taken . "F" . a:n + endfunction + + function! MSG(n, enr, emsg) + let g:taken = g:taken . "M" . a:n + 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 + if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg) + if v:errmsg == "" + Xout "Expr" a:n.": Message missing." + let g:taken = g:taken . "x" + else + let v:errmsg = escape(v:errmsg, '"') + Xout "Expr" a:n.": Unexpected message:" v:errmsg + let g:taken = g:taken . "X" + endif + endif + endfunction + + function! CONT(n) + let g:taken = g:taken . "C" . a:n + endfunction + + let v:errmsg = "" + XloopINIT 1 2 + + try + let t = 1 + while t <= 14 + let g:taken = g:taken . "T" . t + let v:errmsg = "" + try + let caught = 0 + if t == 1 + let v{novar + CONT(t)} = 0 + elseif t == 2 + let v{novar + CONT(t)} + elseif t == 3 + let var = exists('v{novar + CONT(t)}') + elseif t == 4 + unlet v{novar + CONT(t)} + elseif t == 5 + function F{novar + CONT(t)}() + endfunction + elseif t == 6 + function F{novar + CONT(t)} + elseif t == 7 + let var = exists('*F{novar + CONT(t)}') + elseif t == 8 + delfunction F{novar + CONT(t)} + elseif t == 9 + echo novar + CONT(t) + elseif t == 10 + echo v{novar + CONT(t)} + elseif t == 11 + echo F{novar + CONT(t)} + elseif t == 12 + let var = novar + CONT(t) + elseif t == 13 + let var = v{novar + CONT(t)} + elseif t == 14 + let var = F{novar + CONT(t)}() + endif + catch /^Vim\((\a\+)\)\=:/ + " v:errmsg is not set when the error message is converted to an + " exception. Set it to the original error message. + let v:errmsg = substitute(v:exception, + \ '^Vim\((\a\+)\)\=:', '', "") + let caught = 1 + finally + if !caught " no error exceptions ($VIMNOERRTHROW set) + if t <= 8 && t != 3 + call MSG(t, 'E475', 'Invalid argument\>') + else + call MSG(t, 'E15', "Invalid expression") + endif + else + if t == 2 || t == 4 + call MSG(t, 'E475', 'Invalid argument\>') + else + call MSG(t, 'E121', "Undefined variable") + endif + endif + let t = t + 1 + XloopNEXT + continue " discard an aborting error + endtry + endwhile + catch /.*/ + Xloop 1 " X: 0 + Xout t.":" v:exception "in" ExtraVimThrowpoint() + endtry + + function! T(n, expr, enr, emsg) + try + let g:taken = g:taken . "T" . a:n + let v:errmsg = "" + try + let caught = 0 + execute "let var = " . a:expr + catch /^Vim\((\a\+)\)\=:/ + " v:errmsg is not set when the error message is converted to an + " exception. Set it to the original error message. + let v:errmsg = substitute(v:exception, + \ '^Vim\((\a\+)\)\=:', '', "") + let caught = 1 + finally + if !caught " no error exceptions ($VIMNOERRTHROW set) + call MSG(a:n, 'E15', "Invalid expression") + else + call MSG(a:n, a:enr, a:emsg) + endif + XloopNEXT + " Discard an aborting error: + return + endtry + catch /.*/ + Xloop 1 " X: 0 + Xout a:n.":" v:exception "in" ExtraVimThrowpoint() + endtry + endfunction + + call T(15, 'Nofunc() + CONT(15)', 'E117', "Unknown function") + call T(16, 'F(1 2 + CONT(16))', 'E116', "Invalid arguments") + call T(17, 'F(1, 2) + CONT(17)', 'E118', "Too many arguments") + call T(18, 'F() + CONT(18)', 'E119', "Not enough arguments") + call T(19, '{(1} + CONT(19)', 'E110', "Missing ')'") + call T(20, '("abc"[1) + CONT(20)', 'E111', "Missing ']'") + call T(21, '(1 +) + CONT(21)', 'E15', "Invalid expression") + call T(22, '1 2 + CONT(22)', 'E15', "Invalid expression") + call T(23, '(1 ? 2) + CONT(23)', 'E109', "Missing ':' after '?'") + call T(24, '("abc) + CONT(24)', 'E114', "Missing quote") + call T(25, "('abc) + CONT(25)", 'E115', "Missing quote") + call T(26, '& + CONT(26)', 'E112', "Option name missing") + call T(27, '&asdf + CONT(27)', 'E113', "Unknown option") + + Xpath 134217728 " X: 134217728 + + let expected = "" + \ . "T1M1T2M2T3M3T4M4T5M5T6M6T7M7T8M8T9M9T10M10T11M11T12M12T13M13T14M14" + \ . "T15M15T16M16T17M17T18M18T19M19T20M20T21M21T22M22T23M23T24M24T25M25" + \ . "T26M26T27M27" + + if taken != expected + Xpath 268435456 " X: 0 + Xout "'taken' is" taken "instead of" expected + if substitute(taken, '\(.*\)T3M3x\(.*\)', '\1T3M3\2', "") == expected + Xout "Is ++emsg_skip for var with expr_start non-NULL" + \ "in f_exists ok?" + endif + endif + + unlet! var caught taken expected + call delete(WA_t5) + unlet! WA_t5 + delfunction WA_t5 + +endif + +Xcheck 134217728 + + +"------------------------------------------------------------------------------- +" Test 79: Throwing one of several errors for the same command {{{1 +" +" When several errors appear in a row (for instance during expression +" evaluation), the first as the most specific one is used when +" throwing an error exception. If, however, a syntax error is +" detected afterwards, this one is used for the error exception. +" On a syntax error, the next command is not executed, on a normal +" error, however, it is (relevant only in a function without the +" "abort" flag). v:errmsg is not set. +" +" If throwing error exceptions is configured off, v:errmsg is always +" set to the latest error message, that is, to the more general +" message or the syntax error, respectively. +"------------------------------------------------------------------------------- + +XpathINIT + +XloopINIT 1 2 + +function! NEXT(cmd) + exec a:cmd . " | Xloop 1" +endfunction + +call NEXT('echo novar') " X: 1 * 1 (checks nextcmd) +XloopNEXT +call NEXT('let novar #') " X: 0 * 2 (skips nextcmd) +XloopNEXT +call NEXT('unlet novar #') " X: 0 * 4 (skips nextcmd) +XloopNEXT +call NEXT('let {novar}') " X: 0 * 8 (skips nextcmd) +XloopNEXT +call NEXT('unlet{ novar}') " X: 0 * 16 (skips nextcmd) + +function! EXEC(cmd) + exec a:cmd +endfunction + +function! MATCH(expected, msg, enr, emsg) + let msg = a:msg + if a:enr == "" + Xout "TODO: Add message number for:" a:emsg + let msg = ":" . msg + endif + let english = v:lang == "C" || v:lang =~ '^[Ee]n' + if msg !~ '^'.a:enr.':' || (english && msg !~ a:emsg) + let match = 0 + if a:expected " no match although expected + if a:msg == "" + Xout "Message missing." + else + let msg = escape(msg, '"') + Xout "Unexpected message:" msg + endif + endif + else + let match = 1 + if !a:expected " match although not expected + let msg = escape(msg, '"') + Xout "Unexpected message:" msg + endif + endif + return match +endfunction + +try + + while 1 " dummy loop + try + let v:errmsg = "" + let caught = 0 + let thrmsg = "" + call EXEC('echo novar') " normal error + catch /^Vim\((\a\+)\)\=:/ + let caught = 1 + let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") + finally + Xpath 32 " X: 32 + if !caught + if !$VIMNOERRTHROW + Xpath 64 " X: 0 + endif + elseif !MATCH(1, thrmsg, 'E121', "Undefined variable") + \ || v:errmsg != "" + Xpath 128 " X: 0 + endif + if !caught && !MATCH(1, v:errmsg, 'E15', "Invalid expression") + Xpath 256 " X: 0 + endif + break " discard error if $VIMNOERRTHROW == 1 + endtry + endwhile + + Xpath 512 " X: 512 + let cmd = "let" + XloopINIT 1024 32 + while cmd != "" + try + let v:errmsg = "" + let caught = 0 + let thrmsg = "" + call EXEC(cmd . ' novar #') " normal plus syntax error + catch /^Vim\((\a\+)\)\=:/ + let caught = 1 + let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") + finally + Xloop 1 " X: 1024 * (1 + 32) + if !caught + if !$VIMNOERRTHROW + Xloop 2 " X: 0 + endif + else + if cmd == "let" + let match = MATCH(0, thrmsg, 'E106', "Unknown variable") + elseif cmd == "unlet" + let match = MATCH(0, thrmsg, 'E108', "No such variable") + endif + if match " normal error + Xloop 4 " X: 0 + endif + if !MATCH(1, thrmsg, 'E488', "Trailing characters") + \|| v:errmsg != "" + " syntax error + Xloop 8 " X: 0 + endif + endif + if !caught && !MATCH(1, v:errmsg, 'E488', "Trailing characters") + " last error + Xloop 16 " X: 0 + endif + if cmd == "let" + let cmd = "unlet" + else + let cmd = "" + endif + XloopNEXT + continue " discard error if $VIMNOERRTHROW == 1 + endtry + endwhile + + Xpath 1048576 " X: 1048576 + let cmd = "let" + XloopINIT 2097152 32 + while cmd != "" + try + let v:errmsg = "" + let caught = 0 + let thrmsg = "" + call EXEC(cmd . ' {novar}') " normal plus syntax error + catch /^Vim\((\a\+)\)\=:/ + let caught = 1 + let thrmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") + finally + Xloop 1 " X: 2097152 * (1 + 32) + if !caught + if !$VIMNOERRTHROW + Xloop 2 " X: 0 + endif + else + if MATCH(0, thrmsg, 'E121', "Undefined variable") " normal error + Xloop 4 " X: 0 + endif + if !MATCH(1, thrmsg, 'E475', 'Invalid argument\>') + \ || v:errmsg != "" " syntax error + Xloop 8 " X: 0 + endif + endif + if !caught && !MATCH(1, v:errmsg, 'E475', 'Invalid argument\>') + " last error + Xloop 16 " X: 0 + endif + if cmd == "let" + let cmd = "unlet" + else + let cmd = "" + endif + XloopNEXT + continue " discard error if $VIMNOERRTHROW == 1 + endtry + endwhile + +catch /.*/ + " The Xpath command does not accept 2^31 (negative); add explicitly: + let Xpath = Xpath + 2147483648 " X: 0 + Xout v:exception "in" v:throwpoint +endtry + +unlet! next_command thrmsg match +delfunction NEXT +delfunction EXEC +delfunction MATCH + +Xcheck 70288929 + + +"------------------------------------------------------------------------------- +" Test 80: Syntax error in expression for illegal :elseif {{{1 +" +" If there is a syntax error in the expression after an illegal +" :elseif, an error message is given (or an error exception thrown) +" for the illegal :elseif rather than the expression error. +"------------------------------------------------------------------------------- + +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 + +let v:errmsg = "" +if 0 +else +elseif 1 ||| 2 +endif +Xpath 1 " X: 1 +if !MSG('E584', ":elseif after :else") + Xpath 2 " X: 0 +endif + +let v:errmsg = "" +if 1 +else +elseif 1 ||| 2 +endif +Xpath 4 " X: 4 +if !MSG('E584', ":elseif after :else") + Xpath 8 " X: 0 +endif + +let v:errmsg = "" +elseif 1 ||| 2 +Xpath 16 " X: 16 +if !MSG('E582', ":elseif without :if") + Xpath 32 " X: 0 +endif + +let v:errmsg = "" +while 1 + elseif 1 ||| 2 +endwhile +Xpath 64 " X: 64 +if !MSG('E582', ":elseif without :if") + Xpath 128 " X: 0 +endif + +while 1 + try + try + let v:errmsg = "" + let caught = 0 + if 0 + else + elseif 1 ||| 2 + endif + catch /^Vim\((\a\+)\)\=:/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") + finally + Xpath 256 " X: 256 + if !caught && !$VIMNOERRTHROW + Xpath 512 " X: 0 + endif + if !MSG('E584', ":elseif after :else") + Xpath 1024 " X: 0 + endif + endtry + catch /.*/ + Xpath 2048 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +while 1 + try + try + let v:errmsg = "" + let caught = 0 + if 1 + else + elseif 1 ||| 2 + endif + catch /^Vim\((\a\+)\)\=:/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") + finally + Xpath 4096 " X: 4096 + if !caught && !$VIMNOERRTHROW + Xpath 8192 " X: 0 + endif + if !MSG('E584', ":elseif after :else") + Xpath 16384 " X: 0 + endif + endtry + catch /.*/ + Xpath 32768 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +while 1 + try + try + let v:errmsg = "" + let caught = 0 + elseif 1 ||| 2 + catch /^Vim\((\a\+)\)\=:/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") + finally + Xpath 65536 " X: 65536 + if !caught && !$VIMNOERRTHROW + Xpath 131072 " X: 0 + endif + if !MSG('E582', ":elseif without :if") + Xpath 262144 " X: 0 + endif + endtry + catch /.*/ + Xpath 524288 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +while 1 + try + try + let v:errmsg = "" + let caught = 0 + while 1 + elseif 1 ||| 2 + endwhile + catch /^Vim\((\a\+)\)\=:/ + let caught = 1 + let v:errmsg = substitute(v:exception, '^Vim\((\a\+)\)\=:', '', "") + finally + Xpath 1048576 " X: 1048576 + if !caught && !$VIMNOERRTHROW + Xpath 2097152 " X: 0 + endif + if !MSG('E582', ":elseif without :if") + Xpath 4194304 " X: 0 + endif + endtry + catch /.*/ + Xpath 8388608 " X: 0 + Xout v:exception "in" v:throwpoint + finally + break " discard error for $VIMNOERRTHROW + endtry +endwhile + +Xpath 16777216 " X: 16777216 + +unlet! caught +delfunction MSG + +Xcheck 17895765 + + +"------------------------------------------------------------------------------- +" Test 81: Discarding exceptions after an error or interrupt {{{1 +" +" When an exception is thrown from inside a :try conditional without +" :catch and :finally clauses and an error or interrupt occurs before +" the :endtry is reached, the exception is discarded. +"------------------------------------------------------------------------------- + +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 + endtry + Xpath 16 " X: 0 + catch /arrgh/ + Xpath 32 " X: 0 + endtry + Xpath 64 " X: 0 +endif + +if ExtraVim() + try + Xpath 128 " X: 128 + try + Xpath 256 " X: 256 + throw "arrgh" + Xpath 512 " X: 0 + endtry " INTERRUPT + Xpath 1024 " X: 0 + catch /arrgh/ + Xpath 2048 " X: 0 + endtry + Xpath 4096 " X: 0 +endif + +Xcheck 387 + + +"------------------------------------------------------------------------------- +" 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 exexecuted, 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: $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 +" vim: fdt=substitute(substitute(foldtext(),\ '\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\ \\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\ '\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "") +"------------------------------------------------------------------------------- diff --git a/src/testdir/test5.in b/src/testdir/test5.in new file mode 100644 index 000000000..e19e20d59 --- /dev/null +++ b/src/testdir/test5.in @@ -0,0 +1,29 @@ +Test for autocommand that deletes the current buffer on BufLeave event. +Also test deleting the last buffer, should give a new, empty buffer. + +STARTTEST +:so small.vim +:au BufLeave Xxx bwipe +/start of +:.,/end of/w! Xxx " write test file Xxx +:sp Xxx " split to Xxx +:bwipe " delete buffer Xxx, now we're back here +G?this is a +othis is some more text +: " Append some text to this file +:?start?,$w! test.out " Write current file contents +:bwipe test.out " delete alternate buffer +:au bufleave test5.in bwipe +:bwipe! " delete current buffer, get an empty one +ithis is another test line:w >>test.out +: " append an extra line to the output file +:qa! +ENDTEST + +start of test file Xxx +vim: set noai : + this is a test + this is a test + this is a test + this is a test +end of test file Xxx diff --git a/src/testdir/test5.ok b/src/testdir/test5.ok new file mode 100644 index 000000000..674306079 --- /dev/null +++ b/src/testdir/test5.ok @@ -0,0 +1,9 @@ +start of test file Xxx +vim: set noai : + this is a test + this is a test + this is a test + this is a test +this is some more text +end of test file Xxx +this is another test line diff --git a/src/testdir/test50.in b/src/testdir/test50.in new file mode 100644 index 000000000..d78ac8e8f --- /dev/null +++ b/src/testdir/test50.in @@ -0,0 +1,85 @@ +Test for shortpathname ':8' extension. +Only for use on Win32 systems! + +STARTTEST +:so small.vim +:fun! TestIt(file, bits, expected) + let res=fnamemodify(a:file,a:bits) + if a:expected == '' + echo "'".a:file."'->(".a:bits.")->'".res."'" + else + if substitute(res,'/','\\', 'g') != substitute( a:expected, '/','\\', 'g') + echo "FAILED: '".a:file."'->(".a:bits.")->'".res."'" + echo "Expected: '".a:expected."'" + else + echo "OK" + endif + endif +endfun +:fun! MakeDir( dirname ) + "exe '!mkdir '.substitute(a:dirname,'/','\\','g') + call system('mkdir '.substitute(a:dirname,'/','\\','g')) +endfun +:fun! RMDir( dirname) + "exe '!rmdir '.substitute(a:dirname,'/','\\','g') + call system('rmdir '.substitute(a:dirname,'/','\\','g')) +endfun +:fun! MakeFile( filename) + "exe '!copy nul '.substitute(a:filename,'/','\\','g') + call system('copy nul '.substitute(a:filename,'/','\\','g')) +endfun +:fun! TestColonEight() + redir! >test.out + " This could change for CygWin to //cygdrive/c + let dir1='c:/x.x.y' + if filereadable(dir1) || isdirectory(dir1) + call confirm( "'".dir1."' exists, cannot run test" ) + return + endif + let file1=dir1.'/zz.y.txt' + let nofile1=dir1.'/z.y.txt' + let dir2=dir1.'/VimIsTheGreatestSinceSlicedBread' + let file2=dir2.'/z.txt' + let nofile2=dir2.'/zz.txt' + let resdir1='c:/XX2235~1.Y' + let resfile1=resdir1.'/ZZY~1.TXT' + let resnofile1=resdir1.'/z.y.txt' + let resdir2=resdir1.'/VIMIST~1' + let resfile2=resdir2.'/z.txt' + let resnofile2=resdir2.'/zz.txt' + call MakeDir( dir1 ) + call MakeDir( dir2 ) + call MakeFile( file1 ) + call MakeFile( file2 ) + call TestIt(file1, ':p:8', resfile1) + call TestIt(nofile1, ':p:8', resnofile1) + call TestIt(file2, ':p:8', resfile2) + call TestIt(nofile2, ':p:8', resnofile2) + call TestIt(nofile2, ':p:8:h', fnamemodify(resnofile2,':h')) + exe 'cd '.dir1 + call TestIt(file1, ':.:8', strpart(resfile1,strlen(resdir1)+1)) + call TestIt(nofile1, ':.:8', strpart(resnofile1,strlen(resdir1)+1)) + call TestIt(file2, ':.:8', strpart(resfile2,strlen(resdir1)+1)) + call TestIt(nofile2, ':.:8', strpart(resnofile2,strlen(resdir1)+1)) + let $HOME=dir1 + call TestIt(file1, ':~:8', '~'.strpart(resfile1,strlen(resdir1))) + call TestIt(nofile1, ':~:8', '~'.strpart(resnofile1,strlen(resdir1))) + call TestIt(file2, ':~:8', '~'.strpart(resfile2,strlen(resdir1))) + call TestIt(nofile2, ':~:8', '~'.strpart(resnofile2,strlen(resdir1))) + cd c:/ + call delete( file2 ) + call delete( file1 ) + call RMDir( dir2 ) + call RMDir( dir1 ) + echo + redir END +endfun +:let dir = getcwd() +:call TestColonEight() +:exe "cd " . dir +:edit! test.out +:set ff=dos +:w +:qa! +ENDTEST + diff --git a/src/testdir/test50.ok b/src/testdir/test50.ok new file mode 100644 index 000000000..91ef1d660 --- /dev/null +++ b/src/testdir/test50.ok @@ -0,0 +1,14 @@ + +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK +OK diff --git a/src/testdir/test51.in b/src/testdir/test51.in new file mode 100644 index 000000000..a158c8691 --- /dev/null +++ b/src/testdir/test51.in @@ -0,0 +1,34 @@ +Tests for ":highlight". vim: set ft=vim : + +STARTTEST +:so small.vim +:" basic test if ":highlight" doesn't crash +:highlight +:hi Search +:" test setting colors. +:" test clearing one color and all doesn't generate error or warning +:hi NewGroup term=bold cterm=italic ctermfg=DarkBlue ctermbg=Grey gui= guifg=#00ff00 guibg=Cyan +:hi Group2 term= cterm= +:hi Group3 term=underline cterm=bold +:redir >test.out +:hi NewGroup +:hi Group2 +:hi Group3 +:hi clear NewGroup +:hi NewGroup +:hi Group2 +:hi Group2 NONE +:hi Group2 +:hi clear +:hi Group3 +:hi Crash term='asdf +:redir END +:" filter ctermfg and ctermbg, the numbers depend on the terminal +:e test.out +:%s/ctermfg=\d*/ctermfg=2/ +:%s/ctermbg=\d*/ctermbg=3/ +:" filter out possibly translated error message +:%s/E475: [^:]*:/E475:/ +:wq! +ENDTEST + diff --git a/src/testdir/test51.ok b/src/testdir/test51.ok new file mode 100644 index 000000000..fae83936c --- /dev/null +++ b/src/testdir/test51.ok @@ -0,0 +1,15 @@ + + +NewGroup xxx term=bold cterm=italic ctermfg=2 ctermbg=3 + + +Group3 xxx term=underline cterm=bold + + + + + + + + +E475: term='asdf diff --git a/src/testdir/test52.in b/src/testdir/test52.in new file mode 100644 index 000000000..206b65a1f --- /dev/null +++ b/src/testdir/test52.in @@ -0,0 +1,65 @@ +Tests for reading and writing files with conversion for Win32. + +STARTTEST +:so mbyte.vim +:" make this a dummy test for non-Win32 systems +:if !has("win32") | e! test.ok | wq! test.out | endif +:" +:" write tests: +:" combine three values for 'encoding' with three values for 'fileencoding' +:" also write files for read tests +/^1 +:set encoding=utf-8 +:.w! ++enc=utf-8 test.out +:.w ++enc=cp1251 >>test.out +:.w ++enc=cp866 >>test.out +:.w! ++enc=utf-8 Xutf8 +/^2 +:set encoding=cp1251 +:.w ++enc=utf-8 >>test.out +:.w ++enc=cp1251 >>test.out +:.w ++enc=cp866 >>test.out +:.w! ++enc=cp1251 Xcp1251 +/^3 +:set encoding=cp866 +:.w ++enc=utf-8 >>test.out +:.w ++enc=cp1251 >>test.out +:.w ++enc=cp866 >>test.out +:.w! ++enc=cp866 Xcp866 +:" +:" read three 'fileencoding's with utf-8 'encoding' +:set encoding=utf-8 fencs=utf-8,cp1251 +:e Xutf8 +:.w ++enc=utf-8 >>test.out +:e Xcp1251 +:.w ++enc=utf-8 >>test.out +:set fencs=utf-8,cp866 +:e Xcp866 +:.w ++enc=utf-8 >>test.out +:" +:" read three 'fileencoding's with cp1251 'encoding' +:set encoding=utf-8 fencs=utf-8,cp1251 +:e Xutf8 +:.w ++enc=cp1251 >>test.out +:e Xcp1251 +:.w ++enc=cp1251 >>test.out +:set fencs=utf-8,cp866 +:e Xcp866 +:.w ++enc=cp1251 >>test.out +:" +:" read three 'fileencoding's with cp866 'encoding' +:set encoding=cp866 fencs=utf-8,cp1251 +:e Xutf8 +:.w ++enc=cp866 >>test.out +:e Xcp1251 +:.w ++enc=cp866 >>test.out +:set fencs=utf-8,cp866 +:e Xcp866 +:.w ++enc=cp866 >>test.out +:" +:qa! +ENDTEST + +1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01 +2 cp1251 text: Vim version 6.2. : 1970 Jan 01 +3 cp866 text: Vim version 6.2. : 1970 Jan 01 diff --git a/src/testdir/test52.ok b/src/testdir/test52.ok new file mode 100644 index 000000000..90b516508 --- /dev/null +++ b/src/testdir/test52.ok @@ -0,0 +1,18 @@ +1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01 +1 utf-8 text: Vim version 6.2. : 1970 Jan 01 +1 utf-8 text: Vim version 6.2. : 1970 Jan 01 +2 cp1251 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01 +2 cp1251 text: Vim version 6.2. : 1970 Jan 01 +2 cp1251 text: Vim version 6.2. : 1970 Jan 01 +3 cp866 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01 +3 cp866 text: Vim version 6.2. : 1970 Jan 01 +3 cp866 text: Vim version 6.2. : 1970 Jan 01 +1 utf-8 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01 +2 cp1251 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01 +3 cp866 text: Для Vim version 6.2. Последнее изменение: 1970 Jan 01 +1 utf-8 text: Vim version 6.2. : 1970 Jan 01 +2 cp1251 text: Vim version 6.2. : 1970 Jan 01 +3 cp866 text: Vim version 6.2. : 1970 Jan 01 +1 utf-8 text: Vim version 6.2. : 1970 Jan 01 +2 cp1251 text: Vim version 6.2. : 1970 Jan 01 +3 cp866 text: Vim version 6.2. : 1970 Jan 01 diff --git a/src/testdir/test6.in b/src/testdir/test6.in new file mode 100644 index 000000000..1ebbe2fa5 --- /dev/null +++ b/src/testdir/test6.in @@ -0,0 +1,24 @@ +Test for autocommand that redefines the argument list, when doing ":all". + +STARTTEST +:so small.vim +:au BufReadPost Xxx2 next Xxx2 Xxx1 +/^start of +A1:.,/end of/w! Xxx1 " write test file Xxx1 +$r2:.,/end of/w! Xxx2 " write test file Xxx2 +$r3:.,/end of/w! Xxx3 " write test file Xxx3 +:next! Xxx1 Xxx2 Xxx3 " redefine arglist; go to Xxx1 +:all " open window for all args +:w! test.out " Write contents of Xxx1 +:w >>test.out " Append contents of last window (Xxx1) +:rew " should now be in Xxx2 +:w >>test.out " Append contents of Xxx2 +:qa! +ENDTEST + +start of test file Xxx + this is a test + this is a test + this is a test + this is a test +end of test file Xxx diff --git a/src/testdir/test6.ok b/src/testdir/test6.ok new file mode 100644 index 000000000..b6b0c93e4 --- /dev/null +++ b/src/testdir/test6.ok @@ -0,0 +1,18 @@ +start of test file Xxx1 + this is a test + this is a test + this is a test + this is a test +end of test file Xxx +start of test file Xxx1 + this is a test + this is a test + this is a test + this is a test +end of test file Xxx +start of test file Xxx2 + this is a test + this is a test + this is a test + this is a test +end of test file Xxx diff --git a/src/testdir/test7.in b/src/testdir/test7.in new file mode 100644 index 000000000..b9cc0585f --- /dev/null +++ b/src/testdir/test7.in @@ -0,0 +1,26 @@ +Test for autocommand that changes the buffer list, when doing ":ball". + +STARTTEST +:so small.vim +/^start of +A1:.,/end of/w! Xxx1 " write test file Xxx1 +:sp Xxx1 +:close +$r2:.,/end of/w! Xxx2 " write test file Xxx2 +:sp Xxx2 +:close +$r3:.,/end of/w! Xxx3 " write test file Xxx3 +:sp Xxx3 +:close +:au BufReadPost Xxx2 bwipe +$r4:ball " open window for all args, close Xxx2 +:.,$w! test.out " Write contents of this file +:w >>test.out " Append contents of second window (Xxx1) +:/^start of/,$w >>test.out " Append contents of last window (this file) +:qa! +ENDTEST + +start of test file Xxx + this is a test + this is a test +end of test file Xxx diff --git a/src/testdir/test7.ok b/src/testdir/test7.ok new file mode 100644 index 000000000..a0d1ff94a --- /dev/null +++ b/src/testdir/test7.ok @@ -0,0 +1,12 @@ +start of test file Xxx4 + this is a test + this is a test +end of test file Xxx +start of test file Xxx1 + this is a test + this is a test +end of test file Xxx +start of test file Xxx4 + this is a test + this is a test +end of test file Xxx diff --git a/src/testdir/test8.in b/src/testdir/test8.in new file mode 100644 index 000000000..6fe171546 --- /dev/null +++ b/src/testdir/test8.in @@ -0,0 +1,24 @@ +Test for BufWritePre autocommand that deletes or unloads the buffer. + +STARTTEST +:so small.vim +:au BufWritePre Xxx1 bunload +:au BufWritePre Xxx2 bwipe +/^start of +A1:.,/end of/w! Xxx1 " write test file Xxx1 +$r2:.,/end of/w! Xxx2 " write test file Xxx2 +:e! Xxx2 " edit Xxx2 +:bdel test8.in " delete this file from the buffer list +:e Xxx1 " edit Xxx1 +:w " write it, will unload it and give an error msg +:w! test.out " Write contents of this file +:e! Xxx2 " start editing Xxx2 +:bwipe test.out " remove test.out from the buffer list +:w " write it, will delete the buffer and give an error msg +:w >>test.out " Append contents of this file +:qa! +ENDTEST + +start of Xxx + test +end of Xxx diff --git a/src/testdir/test8.ok b/src/testdir/test8.ok new file mode 100644 index 000000000..29b066a13 --- /dev/null +++ b/src/testdir/test8.ok @@ -0,0 +1,6 @@ +start of Xxx2 + test +end of Xxx +start of Xxx1 + test +end of Xxx diff --git a/src/testdir/test9.in b/src/testdir/test9.in new file mode 100644 index 000000000..84e17943c --- /dev/null +++ b/src/testdir/test9.in @@ -0,0 +1,12 @@ +Test for Bufleave autocommand that deletes the buffer we are about to edit. + +STARTTEST +:so small.vim +:au BufLeave test9.in bwipe yy +:e yy +:/^start of/,$w! test.out " Write contents of this file +:qa! +ENDTEST + +start of test file xx +end of test file xx diff --git a/src/testdir/test9.ok b/src/testdir/test9.ok new file mode 100644 index 000000000..cccb5f3ef --- /dev/null +++ b/src/testdir/test9.ok @@ -0,0 +1,2 @@ +start of test file xx +end of test file xx diff --git a/src/testdir/todos.vim b/src/testdir/todos.vim new file mode 100644 index 000000000..0256a51c8 --- /dev/null +++ b/src/testdir/todos.vim @@ -0,0 +1,3 @@ +:" Script to make sure a file is in "dos" file format. +:set ff=dos +:wq diff --git a/src/testdir/unix.vim b/src/testdir/unix.vim new file mode 100644 index 000000000..f766e74c3 --- /dev/null +++ b/src/testdir/unix.vim @@ -0,0 +1,3 @@ +" Settings for test script execution +" Always use "sh", don't use the value of "$SHELL". +set shell=sh diff --git a/src/testdir/vms.vim b/src/testdir/vms.vim new file mode 100644 index 000000000..3305a77c2 --- /dev/null +++ b/src/testdir/vms.vim @@ -0,0 +1,4 @@ +" Settings for test script execution under OpenVMS + +" Do not make any swap files +set noswapfile |