comparison src/testdir/test_trycatch.vim @ 18504:ece46bd3c9af v8.1.2246

patch 8.1.2246: some tests are still in old style Commit: https://github.com/vim/vim/commit/1f068233c101ecf5966e6df14853fe68f08175a7 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Nov 3 16:17:26 2019 +0100 patch 8.1.2246: some tests are still in old style Problem: Some tests are still in old style. Solution: Change a few tests to new style. (Yegappan Lakshmanan)
author Bram Moolenaar <Bram@vim.org>
date Sun, 03 Nov 2019 16:30:03 +0100
parents
children 050f5eaa9e50
comparison
equal deleted inserted replaced
18503:d946c71f8b4c 18504:ece46bd3c9af
1 " Test try-catch-finally exception handling
2 " Most of this was formerly in test49.
3
4 source check.vim
5 source shared.vim
6
7 "-------------------------------------------------------------------------------
8 " Test environment {{{1
9 "-------------------------------------------------------------------------------
10
11 com! XpathINIT let g:Xpath = ''
12 com! -nargs=1 -bar Xpath let g:Xpath = g:Xpath . <args>
13
14 " Test 25: Executing :finally clauses on normal control flow {{{1
15 "
16 " Control flow in a :try conditional should always fall through to its
17 " :finally clause. A :finally clause of a :try conditional inside an
18 " inactive conditional should never be executed.
19 "-------------------------------------------------------------------------------
20
21 func T25_F()
22 let loops = 3
23 while loops > 0
24 Xpath 'a' . loops
25 if loops >= 2
26 try
27 Xpath 'b' . loops
28 if loops == 2
29 try
30 Xpath 'c' . loops
31 finally
32 Xpath 'd' . loops
33 endtry
34 endif
35 finally
36 Xpath 'e' . loops
37 if loops == 2
38 try
39 Xpath 'f' . loops
40 finally
41 Xpath 'g' . loops
42 endtry
43 endif
44 endtry
45 endif
46 Xpath 'h' . loops
47 let loops = loops - 1
48 endwhile
49 Xpath 'i'
50 endfunc
51
52 func T25_G()
53 if 1
54 try
55 Xpath 'A'
56 call T25_F()
57 Xpath 'B'
58 finally
59 Xpath 'C'
60 endtry
61 else
62 try
63 Xpath 'D'
64 finally
65 Xpath 'E'
66 endtry
67 endif
68 endfunc
69
70 func Test_finally()
71 XpathINIT
72 call T25_G()
73 call assert_equal('Aa3b3e3h3a2b2c2d2e2f2g2h2a1h1iBC', g:Xpath)
74 endfunc
75
76
77 "-------------------------------------------------------------------------------
78 " Test 26: Executing :finally clauses after :continue or :break {{{1
79 "
80 " For a :continue or :break dynamically enclosed in a :try/:endtry
81 " region inside the next surrounding :while/:endwhile, if the
82 " :continue/:break is before the :finally, the :finally clause is
83 " executed first. If the :continue/:break is after the :finally, the
84 " :finally clause is broken (like an :if/:endif region).
85 "-------------------------------------------------------------------------------
86
87 func T26_F()
88 try
89 let loops = 3
90 while loops > 0
91 try
92 try
93 if loops == 2
94 Xpath 'a' . loops
95 let loops = loops - 1
96 continue
97 elseif loops == 1
98 Xpath 'b' . loops
99 break
100 finish
101 endif
102 Xpath 'c' . loops
103 endtry
104 finally
105 Xpath 'd' . loops
106 endtry
107 Xpath 'e' . loops
108 let loops = loops - 1
109 endwhile
110 Xpath 'f'
111 finally
112 Xpath 'g'
113 let loops = 3
114 while loops > 0
115 try
116 finally
117 try
118 if loops == 2
119 Xpath 'h' . loops
120 let loops = loops - 1
121 continue
122 elseif loops == 1
123 Xpath 'i' . loops
124 break
125 finish
126 endif
127 endtry
128 Xpath 'j' . loops
129 endtry
130 Xpath 'k' . loops
131 let loops = loops - 1
132 endwhile
133 Xpath 'l'
134 endtry
135 Xpath 'm'
136 endfunc
137
138 func Test_finally_after_continue()
139 XpathINIT
140 call T26_F()
141 call assert_equal('c3d3e3a2d1b1d1fgj3k3h2i1lm', g:Xpath)
142 endfunc
143
144
145 "-------------------------------------------------------------------------------
146 " Test 32: Remembering the :return value on :finally {{{1
147 "
148 " If a :finally clause is executed due to a :return specifying
149 " a value, this is the value visible to the caller if not overwritten
150 " by a new :return in the :finally clause. A :return without a value
151 " in the :finally clause overwrites with value 0.
152 "-------------------------------------------------------------------------------
153
154 func T32_F()
155 try
156 Xpath 'a'
157 try
158 Xpath 'b'
159 return "ABCD"
160 Xpath 'c'
161 finally
162 Xpath 'd'
163 endtry
164 Xpath 'e'
165 finally
166 Xpath 'f'
167 endtry
168 Xpath 'g'
169 endfunc
170
171 func T32_G()
172 try
173 Xpath 'h'
174 return 8
175 Xpath 'i'
176 finally
177 Xpath 'j'
178 return 16 + strlen(T32_F())
179 Xpath 'k'
180 endtry
181 Xpath 'l'
182 endfunc
183
184 func T32_H()
185 try
186 Xpath 'm'
187 return 32
188 Xpath 'n'
189 finally
190 Xpath 'o'
191 return
192 Xpath 'p'
193 endtry
194 Xpath 'q'
195 endfunc
196
197 func T32_I()
198 try
199 Xpath 'r'
200 finally
201 Xpath 's'
202 return T32_G() + T32_H() + 64
203 Xpath 't'
204 endtry
205 Xpath 'u'
206 endfunc
207
208 func Test_finally_return()
209 XpathINIT
210 call assert_equal(84, T32_I())
211 call assert_equal('rshjabdfmo', g:Xpath)
212 endfunc
213
214 "-------------------------------------------------------------------------------
215 " Test 33: :return under :execute or user command and :finally {{{1
216 "
217 " A :return command may be executed under an ":execute" or from
218 " a user command. Executing of :finally clauses and passing through
219 " the return code works also then.
220 "-------------------------------------------------------------------------------
221
222 func T33_F()
223 try
224 RETURN 10
225 Xpath 'a'
226 finally
227 Xpath 'b'
228 endtry
229 Xpath 'c'
230 endfunc
231
232 func T33_G()
233 try
234 RETURN 20
235 Xpath 'd'
236 finally
237 Xpath 'e'
238 RETURN 30
239 Xpath 'f'
240 endtry
241 Xpath 'g'
242 endfunc
243
244 func T33_H()
245 try
246 execute "try | return 40 | finally | return 50 | endtry"
247 Xpath 'h'
248 finally
249 Xpath 'i'
250 endtry
251 Xpath 'j'
252 endfunc
253
254 func T33_I()
255 try
256 execute "try | return 60 | finally | return 70 | endtry"
257 Xpath 'k'
258 finally
259 Xpath 'l'
260 execute "try | return 80 | finally | return 90 | endtry"
261 Xpath 'm'
262 endtry
263 Xpath 'n'
264 endfunc
265
266 func T33_J()
267 try
268 RETURN 100
269 Xpath 'o'
270 finally
271 Xpath 'p'
272 return
273 Xpath 'q'
274 endtry
275 Xpath 'r'
276 endfunc
277
278 func T33_K()
279 try
280 execute "try | return 110 | finally | return 120 | endtry"
281 Xpath 's'
282 finally
283 Xpath 't'
284 execute "try | return 130 | finally | return | endtry"
285 Xpath 'u'
286 endtry
287 Xpath 'v'
288 endfunc
289
290 func T33_L()
291 try
292 return
293 Xpath 'w'
294 finally
295 Xpath 'x'
296 RETURN 140
297 Xpath 'y'
298 endtry
299 Xpath 'z'
300 endfunc
301
302 func T33_M()
303 try
304 return
305 Xpath 'A'
306 finally
307 Xpath 'B'
308 execute "try | return 150 | finally | return 160 | endtry"
309 Xpath 'C'
310 endtry
311 Xpath 'D'
312 endfunc
313
314 func T33_N()
315 RETURN 170
316 endfunc
317
318 func T33_O()
319 execute "try | return 180 | finally | return 190 | endtry"
320 endfunc
321
322 func Test_finally_cmd_return()
323 command! -nargs=? RETURN
324 \ try | return <args> | finally | return <args> * 2 | endtry
325 XpathINIT
326 call assert_equal(20, T33_F())
327 call assert_equal(60, T33_G())
328 call assert_equal(50, T33_H())
329 call assert_equal(90, T33_I())
330 call assert_equal(0, T33_J())
331 call assert_equal(0, T33_K())
332 call assert_equal(280, T33_L())
333 call assert_equal(160, T33_M())
334 call assert_equal(340, T33_N())
335 call assert_equal(190, T33_O())
336 call assert_equal('beilptxB', g:Xpath)
337 delcommand RETURN
338 endfunc
339
340
341 "-------------------------------------------------------------------------------
342 " Test 41: Skipped :throw finding next command {{{1
343 "
344 " A :throw in an inactive conditional must not hide a following
345 " command.
346 "-------------------------------------------------------------------------------
347
348 func T41_F()
349 Xpath 'a'
350 if 0 | throw 'never' | endif | Xpath 'b'
351 Xpath 'c'
352 endfunc
353
354 func T41_G()
355 Xpath 'd'
356 while 0 | throw 'never' | endwhile | Xpath 'e'
357 Xpath 'f'
358 endfunc
359
360 func T41_H()
361 Xpath 'g'
362 if 0 | try | throw 'never' | endtry | endif | Xpath 'h'
363 Xpath 'i'
364 endfunc
365
366 func Test_throw_inactive_cond()
367 XpathINIT
368 try
369 Xpath 'j'
370 call T41_F()
371 Xpath 'k'
372 catch /.*/
373 Xpath 'l'
374 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
375 endtry
376
377 try
378 Xpath 'm'
379 call T41_G()
380 Xpath 'n'
381 catch /.*/
382 Xpath 'o'
383 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
384 endtry
385
386 try
387 Xpath 'p'
388 call T41_H()
389 Xpath 'q'
390 catch /.*/
391 Xpath 'r'
392 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
393 endtry
394
395 call assert_equal('jabckmdefnpghiq', g:Xpath)
396 endfunc
397
398
399 "-------------------------------------------------------------------------------
400 " Test 42: Catching number and string exceptions {{{1
401 "
402 " When a number is thrown, it is converted to a string exception.
403 " Numbers and strings may be caught by specifying a regular exception
404 " as argument to the :catch command.
405 "-------------------------------------------------------------------------------
406
407
408 func T42_F()
409 try
410
411 try
412 Xpath 'a'
413 throw 4711
414 Xpath 'b'
415 catch /4711/
416 Xpath 'c'
417 endtry
418
419 try
420 Xpath 'd'
421 throw 4711
422 Xpath 'e'
423 catch /^4711$/
424 Xpath 'f'
425 endtry
426
427 try
428 Xpath 'g'
429 throw 4711
430 Xpath 'h'
431 catch /\d/
432 Xpath 'i'
433 endtry
434
435 try
436 Xpath 'j'
437 throw 4711
438 Xpath 'k'
439 catch /^\d\+$/
440 Xpath 'l'
441 endtry
442
443 try
444 Xpath 'm'
445 throw "arrgh"
446 Xpath 'n'
447 catch /arrgh/
448 Xpath 'o'
449 endtry
450
451 try
452 Xpath 'p'
453 throw "arrgh"
454 Xpath 'q'
455 catch /^arrgh$/
456 Xpath 'r'
457 endtry
458
459 try
460 Xpath 's'
461 throw "arrgh"
462 Xpath 't'
463 catch /\l/
464 Xpath 'u'
465 endtry
466
467 try
468 Xpath 'v'
469 throw "arrgh"
470 Xpath 'w'
471 catch /^\l\+$/
472 Xpath 'x'
473 endtry
474
475 try
476 try
477 Xpath 'y'
478 throw "ARRGH"
479 Xpath 'z'
480 catch /^arrgh$/
481 Xpath 'A'
482 endtry
483 catch /^\carrgh$/
484 Xpath 'B'
485 endtry
486
487 try
488 Xpath 'C'
489 throw ""
490 Xpath 'D'
491 catch /^$/
492 Xpath 'E'
493 endtry
494
495 catch /.*/
496 Xpath 'F'
497 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
498 endtry
499 endfunc
500
501 func Test_catch_number_string()
502 XpathINIT
503 call T42_F()
504 call assert_equal('acdfgijlmoprsuvxyBCE', g:Xpath)
505 endfunc
506
507
508 "-------------------------------------------------------------------------------
509 " Test 43: Selecting the correct :catch clause {{{1
510 "
511 " When an exception is thrown and there are multiple :catch clauses,
512 " the first matching one is taken.
513 "-------------------------------------------------------------------------------
514
515 func T43_F()
516 let loops = 3
517 while loops > 0
518 try
519 if loops == 3
520 Xpath 'a' . loops
521 throw "a"
522 Xpath 'b' . loops
523 elseif loops == 2
524 Xpath 'c' . loops
525 throw "ab"
526 Xpath 'd' . loops
527 elseif loops == 1
528 Xpath 'e' . loops
529 throw "abc"
530 Xpath 'f' . loops
531 endif
532 catch /abc/
533 Xpath 'g' . loops
534 catch /ab/
535 Xpath 'h' . loops
536 catch /.*/
537 Xpath 'i' . loops
538 catch /a/
539 Xpath 'j' . loops
540 endtry
541
542 let loops = loops - 1
543 endwhile
544 Xpath 'k'
545 endfunc
546
547 func Test_multi_catch()
548 XpathINIT
549 call T43_F()
550 call assert_equal('a3i3c2h2e1g1k', g:Xpath)
551 endfunc
552
553
554 "-------------------------------------------------------------------------------
555 " Test 44: Missing or empty :catch patterns {{{1
556 "
557 " A missing or empty :catch pattern means the same as /.*/, that is,
558 " catches everything. To catch only empty exceptions, /^$/ must be
559 " used. A :catch with missing, empty, or /.*/ argument also works
560 " when followed by another command separated by a bar on the same
561 " line. :catch patterns cannot be specified between ||. But other
562 " pattern separators can be used instead of //.
563 "-------------------------------------------------------------------------------
564
565 func T44_F()
566 try
567 try
568 Xpath 'a'
569 throw ""
570 catch /^$/
571 Xpath 'b'
572 endtry
573
574 try
575 Xpath 'c'
576 throw ""
577 catch /.*/
578 Xpath 'd'
579 endtry
580
581 try
582 Xpath 'e'
583 throw ""
584 catch //
585 Xpath 'f'
586 endtry
587
588 try
589 Xpath 'g'
590 throw ""
591 catch
592 Xpath 'h'
593 endtry
594
595 try
596 Xpath 'i'
597 throw "oops"
598 catch /^$/
599 Xpath 'j'
600 catch /.*/
601 Xpath 'k'
602 endtry
603
604 try
605 Xpath 'l'
606 throw "arrgh"
607 catch /^$/
608 Xpath 'm'
609 catch //
610 Xpath 'n'
611 endtry
612
613 try
614 Xpath 'o'
615 throw "brrr"
616 catch /^$/
617 Xpath 'p'
618 catch
619 Xpath 'q'
620 endtry
621
622 try | Xpath 'r' | throw "x" | catch /.*/ | Xpath 's' | endtry
623
624 try | Xpath 't' | throw "y" | catch // | Xpath 'u' | endtry
625
626 while 1
627 try
628 let caught = 0
629 let v:errmsg = ""
630 " Extra try level: if ":catch" without arguments below raises
631 " a syntax error because it misinterprets the "Xpath" as a pattern,
632 " let it be caught by the ":catch /.*/" below.
633 try
634 try | Xpath 'v' | throw "z" | catch | Xpath 'w' | :
635 endtry
636 endtry
637 catch /.*/
638 let caught = 1
639 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
640 finally
641 if $VIMNOERRTHROW && v:errmsg != ""
642 call assert_report(v:errmsg)
643 endif
644 if caught || $VIMNOERRTHROW && v:errmsg != ""
645 Xpath 'x'
646 endif
647 break " discard error for $VIMNOERRTHROW
648 endtry
649 endwhile
650
651 let cologne = 4711
652 try
653 try
654 Xpath 'y'
655 throw "throw cologne"
656 " Next lines catches all and throws 4711:
657 catch |throw cologne|
658 Xpath 'z'
659 endtry
660 catch /4711/
661 Xpath 'A'
662 endtry
663
664 try
665 Xpath 'B'
666 throw "plus"
667 catch +plus+
668 Xpath 'C'
669 endtry
670
671 Xpath 'D'
672 catch /.*/
673 Xpath 'E'
674 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
675 endtry
676 endfunc
677
678 func Test_empty_catch()
679 XpathINIT
680 call T44_F()
681 call assert_equal('abcdefghiklnoqrstuvwyABCD', g:Xpath)
682 endfunc
683
684
685 "-------------------------------------------------------------------------------
686 " Test 45: Catching exceptions from nested :try blocks {{{1
687 "
688 " When :try blocks are nested, an exception is caught by the innermost
689 " try conditional that has a matching :catch clause.
690 "-------------------------------------------------------------------------------
691
692 func T45_F()
693 let loops = 3
694 while loops > 0
695 try
696 try
697 try
698 try
699 if loops == 3
700 Xpath 'a' . loops
701 throw "a"
702 Xpath 'b' . loops
703 elseif loops == 2
704 Xpath 'c' . loops
705 throw "ab"
706 Xpath 'd' . loops
707 elseif loops == 1
708 Xpath 'e' . loops
709 throw "abc"
710 Xpath 'f' . loops
711 endif
712 catch /abc/
713 Xpath 'g' . loops
714 endtry
715 catch /ab/
716 Xpath 'h' . loops
717 endtry
718 catch /.*/
719 Xpath 'i' . loops
720 endtry
721 catch /a/
722 Xpath 'j' . loops
723 endtry
724
725 let loops = loops - 1
726 endwhile
727 Xpath 'k'
728 endfunc
729
730 func Test_catch_from_nested_try()
731 XpathINIT
732 call T45_F()
733 call assert_equal('a3i3c2h2e1g1k', g:Xpath)
734 endfunc
735
736
737 "-------------------------------------------------------------------------------
738 " Test 46: Executing :finally after a :throw in nested :try {{{1
739 "
740 " When an exception is thrown from within nested :try blocks, the
741 " :finally clauses of the non-catching try conditionals should be
742 " executed before the matching :catch of the next surrounding :try
743 " gets the control. If this also has a :finally clause, it is
744 " executed afterwards.
745 "-------------------------------------------------------------------------------
746
747 func T46_F()
748 let sum = 0
749
750 try
751 Xpath 'a'
752 try
753 Xpath 'b'
754 try
755 Xpath 'c'
756 try
757 Xpath 'd'
758 throw "ABC"
759 Xpath 'e'
760 catch /xyz/
761 Xpath 'f'
762 finally
763 Xpath 'g'
764 if sum != 0
765 Xpath 'h'
766 endif
767 let sum = sum + 1
768 endtry
769 Xpath 'i'
770 catch /123/
771 Xpath 'j'
772 catch /321/
773 Xpath 'k'
774 finally
775 Xpath 'l'
776 if sum != 1
777 Xpath 'm'
778 endif
779 let sum = sum + 2
780 endtry
781 Xpath 'n'
782 finally
783 Xpath 'o'
784 if sum != 3
785 Xpath 'p'
786 endif
787 let sum = sum + 4
788 endtry
789 Xpath 'q'
790 catch /ABC/
791 Xpath 'r'
792 if sum != 7
793 Xpath 's'
794 endif
795 let sum = sum + 8
796 finally
797 Xpath 't'
798 if sum != 15
799 Xpath 'u'
800 endif
801 let sum = sum + 16
802 endtry
803 Xpath 'v'
804 if sum != 31
805 Xpath 'w'
806 endif
807 endfunc
808
809 func Test_finally_after_throw()
810 XpathINIT
811 call T46_F()
812 call assert_equal('abcdglortv', g:Xpath)
813 endfunc
814
815
816 "-------------------------------------------------------------------------------
817 " Test 47: Throwing exceptions from a :catch clause {{{1
818 "
819 " When an exception is thrown from a :catch clause, it should not be
820 " caught by a :catch of the same :try conditional. After executing
821 " the :finally clause (if present), surrounding try conditionals
822 " should be checked for a matching :catch.
823 "-------------------------------------------------------------------------------
824
825 func T47_F()
826 Xpath 'a'
827 try
828 Xpath 'b'
829 try
830 Xpath 'c'
831 try
832 Xpath 'd'
833 throw "x1"
834 Xpath 'e'
835 catch /x1/
836 Xpath 'f'
837 try
838 Xpath 'g'
839 throw "x2"
840 Xpath 'h'
841 catch /x1/
842 Xpath 'i'
843 catch /x2/
844 Xpath 'j'
845 try
846 Xpath 'k'
847 throw "x3"
848 Xpath 'l'
849 catch /x1/
850 Xpath 'm'
851 catch /x2/
852 Xpath 'n'
853 finally
854 Xpath 'o'
855 endtry
856 Xpath 'p'
857 catch /x3/
858 Xpath 'q'
859 endtry
860 Xpath 'r'
861 catch /x1/
862 Xpath 's'
863 catch /x2/
864 Xpath 't'
865 catch /x3/
866 Xpath 'u'
867 finally
868 Xpath 'v'
869 endtry
870 Xpath 'w'
871 catch /x1/
872 Xpath 'x'
873 catch /x2/
874 Xpath 'y'
875 catch /x3/
876 Xpath 'z'
877 endtry
878 Xpath 'A'
879 catch /.*/
880 Xpath 'B'
881 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
882 endtry
883 Xpath 'C'
884 endfunc
885
886 func Test_throw_from_catch()
887 XpathINIT
888 call T47_F()
889 call assert_equal('abcdfgjkovzAC', g:Xpath)
890 endfunc
891
892
893 "-------------------------------------------------------------------------------
894 " Test 48: Throwing exceptions from a :finally clause {{{1
895 "
896 " When an exception is thrown from a :finally clause, it should not be
897 " caught by a :catch of the same :try conditional. Surrounding try
898 " conditionals should be checked for a matching :catch. A previously
899 " thrown exception is discarded.
900 "-------------------------------------------------------------------------------
901
902 func T48_F()
903 try
904
905 try
906 try
907 Xpath 'a'
908 catch /x1/
909 Xpath 'b'
910 finally
911 Xpath 'c'
912 throw "x1"
913 Xpath 'd'
914 endtry
915 Xpath 'e'
916 catch /x1/
917 Xpath 'f'
918 endtry
919 Xpath 'g'
920
921 try
922 try
923 Xpath 'h'
924 throw "x2"
925 Xpath 'i'
926 catch /x2/
927 Xpath 'j'
928 catch /x3/
929 Xpath 'k'
930 finally
931 Xpath 'l'
932 throw "x3"
933 Xpath 'm'
934 endtry
935 Xpath 'n'
936 catch /x2/
937 Xpath 'o'
938 catch /x3/
939 Xpath 'p'
940 endtry
941 Xpath 'q'
942
943 try
944 try
945 try
946 Xpath 'r'
947 throw "x4"
948 Xpath 's'
949 catch /x5/
950 Xpath 't'
951 finally
952 Xpath 'u'
953 throw "x5" " discards 'x4'
954 Xpath 'v'
955 endtry
956 Xpath 'w'
957 catch /x4/
958 Xpath 'x'
959 finally
960 Xpath 'y'
961 endtry
962 Xpath 'z'
963 catch /x5/
964 Xpath 'A'
965 endtry
966 Xpath 'B'
967
968 catch /.*/
969 Xpath 'C'
970 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
971 endtry
972 Xpath 'D'
973 endfunc
974
975 func Test_throw_from_finally()
976 XpathINIT
977 call T48_F()
978 call assert_equal('acfghjlpqruyABD', g:Xpath)
979 endfunc
980
981
982 "-------------------------------------------------------------------------------
983 " Test 51: Throwing exceptions across :execute and user commands {{{1
984 "
985 " A :throw command may be executed under an ":execute" or from
986 " a user command.
987 "-------------------------------------------------------------------------------
988
989 func T51_F()
990 command! -nargs=? THROW1 throw <args> | throw 1
991 command! -nargs=? THROW2 try | throw <args> | endtry | throw 2
992 command! -nargs=? THROW3 try | throw 3 | catch /3/ | throw <args> | endtry
993 command! -nargs=? THROW4 try | throw 4 | finally | throw <args> | endtry
994
995 try
996
997 try
998 try
999 Xpath 'a'
1000 THROW1 "A"
1001 catch /A/
1002 Xpath 'b'
1003 endtry
1004 catch /1/
1005 Xpath 'c'
1006 endtry
1007
1008 try
1009 try
1010 Xpath 'd'
1011 THROW2 "B"
1012 catch /B/
1013 Xpath 'e'
1014 endtry
1015 catch /2/
1016 Xpath 'f'
1017 endtry
1018
1019 try
1020 try
1021 Xpath 'g'
1022 THROW3 "C"
1023 catch /C/
1024 Xpath 'h'
1025 endtry
1026 catch /3/
1027 Xpath 'i'
1028 endtry
1029
1030 try
1031 try
1032 Xpath 'j'
1033 THROW4 "D"
1034 catch /D/
1035 Xpath 'k'
1036 endtry
1037 catch /4/
1038 Xpath 'l'
1039 endtry
1040
1041 try
1042 try
1043 Xpath 'm'
1044 execute 'throw "E" | throw 5'
1045 catch /E/
1046 Xpath 'n'
1047 endtry
1048 catch /5/
1049 Xpath 'o'
1050 endtry
1051
1052 try
1053 try
1054 Xpath 'p'
1055 execute 'try | throw "F" | endtry | throw 6'
1056 catch /F/
1057 Xpath 'q'
1058 endtry
1059 catch /6/
1060 Xpath 'r'
1061 endtry
1062
1063 try
1064 try
1065 Xpath 's'
1066 execute'try | throw 7 | catch /7/ | throw "G" | endtry'
1067 catch /G/
1068 Xpath 't'
1069 endtry
1070 catch /7/
1071 Xpath 'u'
1072 endtry
1073
1074 try
1075 try
1076 Xpath 'v'
1077 execute 'try | throw 8 | finally | throw "H" | endtry'
1078 catch /H/
1079 Xpath 'w'
1080 endtry
1081 catch /8/
1082 Xpath 'x'
1083 endtry
1084
1085 catch /.*/
1086 Xpath 'y'
1087 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
1088 endtry
1089
1090 Xpath 'z'
1091
1092 delcommand THROW1
1093 delcommand THROW2
1094 delcommand THROW3
1095 delcommand THROW4
1096 endfunc
1097
1098 func Test_throw_across_commands()
1099 XpathINIT
1100 call T51_F()
1101 call assert_equal('abdeghjkmnpqstvwz', g:Xpath)
1102 endfunc
1103
1104
1105
1106 "-------------------------------------------------------------------------------
1107 " Test 69: :throw across :if, :elseif, :while {{{1
1108 "
1109 " On an :if, :elseif, or :while command, an exception might be thrown
1110 " during evaluation of the expression to test. The exception can be
1111 " caught by the script.
1112 "-------------------------------------------------------------------------------
1113
1114 func T69_throw(x)
1115 Xpath 'x'
1116 throw a:x
1117 endfunc
1118
1119 func Test_throw_ifelsewhile()
1120 XpathINIT
1121
1122 try
1123 try
1124 Xpath 'a'
1125 if 111 == T69_throw("if") + 111
1126 Xpath 'b'
1127 else
1128 Xpath 'c'
1129 endif
1130 Xpath 'd'
1131 catch /^if$/
1132 Xpath 'e'
1133 catch /.*/
1134 Xpath 'f'
1135 call assert_report("if: " . v:exception . " in " . v:throwpoint)
1136 endtry
1137
1138 try
1139 Xpath 'g'
1140 if v:false
1141 Xpath 'h'
1142 elseif 222 == T69_throw("elseif") + 222
1143 Xpath 'i'
1144 else
1145 Xpath 'j'
1146 endif
1147 Xpath 'k'
1148 catch /^elseif$/
1149 Xpath 'l'
1150 catch /.*/
1151 Xpath 'm'
1152 call assert_report("elseif: " . v:exception . " in " . v:throwpoint)
1153 endtry
1154
1155 try
1156 Xpath 'n'
1157 while 333 == T69_throw("while") + 333
1158 Xpath 'o'
1159 break
1160 endwhile
1161 Xpath 'p'
1162 catch /^while$/
1163 Xpath 'q'
1164 catch /.*/
1165 Xpath 'r'
1166 call assert_report("while: " .. v:exception .. " in " .. v:throwpoint)
1167 endtry
1168 catch /^0$/ " default return value
1169 Xpath 's'
1170 call assert_report(v:throwpoint)
1171 catch /.*/
1172 call assert_report(v:exception .. " in " .. v:throwpoint)
1173 Xpath 't'
1174 endtry
1175
1176 call assert_equal('axegxlnxq', g:Xpath)
1177 endfunc
1178
1179
1180 "-------------------------------------------------------------------------------
1181 " Test 70: :throw across :return or :throw {{{1
1182 "
1183 " On a :return or :throw command, an exception might be thrown during
1184 " evaluation of the expression to return or throw, respectively. The
1185 " exception can be caught by the script.
1186 "-------------------------------------------------------------------------------
1187
1188 let T70_taken = ""
1189
1190 func T70_throw(x, n)
1191 let g:T70_taken = g:T70_taken . "T" . a:n
1192 throw a:x
1193 endfunc
1194
1195 func T70_F(x, y, n)
1196 let g:T70_taken = g:T70_taken . "F" . a:n
1197 return a:x + T70_throw(a:y, a:n)
1198 endfunc
1199
1200 func T70_G(x, y, n)
1201 let g:T70_taken = g:T70_taken . "G" . a:n
1202 throw a:x . T70_throw(a:y, a:n)
1203 return a:x
1204 endfunc
1205
1206 func Test_throwreturn()
1207 XpathINIT
1208
1209 try
1210 try
1211 Xpath 'a'
1212 call T70_F(4711, "return", 1)
1213 Xpath 'b'
1214 catch /^return$/
1215 Xpath 'c'
1216 catch /.*/
1217 Xpath 'd'
1218 call assert_report("return: " .. v:exception .. " in " .. v:throwpoint)
1219 endtry
1220
1221 try
1222 Xpath 'e'
1223 let var = T70_F(4712, "return-var", 2)
1224 Xpath 'f'
1225 catch /^return-var$/
1226 Xpath 'g'
1227 catch /.*/
1228 Xpath 'h'
1229 call assert_report("return-var: " . v:exception . " in " . v:throwpoint)
1230 finally
1231 unlet! var
1232 endtry
1233
1234 try
1235 Xpath 'i'
1236 throw "except1" . T70_throw("throw1", 3)
1237 Xpath 'j'
1238 catch /^except1/
1239 Xpath 'k'
1240 catch /^throw1$/
1241 Xpath 'l'
1242 catch /.*/
1243 Xpath 'm'
1244 call assert_report("throw1: " .. v:exception .. " in " .. v:throwpoint)
1245 endtry
1246
1247 try
1248 Xpath 'n'
1249 call T70_G("except2", "throw2", 4)
1250 Xpath 'o'
1251 catch /^except2/
1252 Xpath 'p'
1253 catch /^throw2$/
1254 Xpath 'q'
1255 catch /.*/
1256 Xpath 'r'
1257 call assert_report("throw2: " .. v:exception .. " in " .. v:throwpoint)
1258 endtry
1259
1260 try
1261 Xpath 's'
1262 let var = T70_G("except3", "throw3", 5)
1263 Xpath 't'
1264 catch /^except3/
1265 Xpath 'u'
1266 catch /^throw3$/
1267 Xpath 'v'
1268 catch /.*/
1269 Xpath 'w'
1270 call assert_report("throw3: " .. v:exception .. " in " .. v:throwpoint)
1271 finally
1272 unlet! var
1273 endtry
1274
1275 call assert_equal('F1T1F2T2T3G4T4G5T5', g:T70_taken)
1276 Xpath 'x'
1277 catch /^0$/ " default return value
1278 Xpath 'y'
1279 call assert_report(v:throwpoint)
1280 catch /.*/
1281 Xpath 'z'
1282 call assert_report('Caught' .. v:exception .. ' in ' .. v:throwpoint)
1283 endtry
1284
1285 call assert_equal('acegilnqsvx', g:Xpath)
1286 endfunc
1287
1288 "-------------------------------------------------------------------------------
1289 " Test 71: :throw across :echo variants and :execute {{{1
1290 "
1291 " On an :echo, :echon, :echomsg, :echoerr, or :execute command, an
1292 " exception might be thrown during evaluation of the arguments to
1293 " be displayed or executed as a command, respectively. Any following
1294 " arguments are not evaluated, then. The exception can be caught by
1295 " the script.
1296 "-------------------------------------------------------------------------------
1297
1298 let T71_taken = ""
1299
1300 func T71_throw(x, n)
1301 let g:T71_taken = g:T71_taken . "T" . a:n
1302 throw a:x
1303 endfunc
1304
1305 func T71_F(n)
1306 let g:T71_taken = g:T71_taken . "F" . a:n
1307 return "F" . a:n
1308 endfunc
1309
1310 func Test_throw_echo()
1311 XpathINIT
1312
1313 try
1314 try
1315 Xpath 'a'
1316 echo 'echo ' . T71_throw("echo-except", 1) . T71_F(1)
1317 Xpath 'b'
1318 catch /^echo-except$/
1319 Xpath 'c'
1320 catch /.*/
1321 Xpath 'd'
1322 call assert_report("echo: " .. v:exception .. " in " .. v:throwpoint)
1323 endtry
1324
1325 try
1326 Xpath 'e'
1327 echon "echon " . T71_throw("echon-except", 2) . T71_F(2)
1328 Xpath 'f'
1329 catch /^echon-except$/
1330 Xpath 'g'
1331 catch /.*/
1332 Xpath 'h'
1333 call assert_report('echon: ' . v:exception . ' in ' . v:throwpoint)
1334 endtry
1335
1336 try
1337 Xpath 'i'
1338 echomsg "echomsg " . T71_throw("echomsg-except", 3) . T71_F(3)
1339 Xpath 'j'
1340 catch /^echomsg-except$/
1341 Xpath 'k'
1342 catch /.*/
1343 Xpath 'l'
1344 call assert_report('echomsg: ' . v:exception . ' in ' . v:throwpoint)
1345 endtry
1346
1347 try
1348 Xpath 'm'
1349 echoerr "echoerr " . T71_throw("echoerr-except", 4) . T71_F(4)
1350 Xpath 'n'
1351 catch /^echoerr-except$/
1352 Xpath 'o'
1353 catch /Vim/
1354 Xpath 'p'
1355 catch /echoerr/
1356 Xpath 'q'
1357 catch /.*/
1358 Xpath 'r'
1359 call assert_report('echoerr: ' . v:exception . ' in ' . v:throwpoint)
1360 endtry
1361
1362 try
1363 Xpath 's'
1364 execute "echo 'execute " . T71_throw("execute-except", 5) . T71_F(5) "'"
1365 Xpath 't'
1366 catch /^execute-except$/
1367 Xpath 'u'
1368 catch /.*/
1369 Xpath 'v'
1370 call assert_report('execute: ' . v:exception . ' in ' . v:throwpoint)
1371 endtry
1372
1373 call assert_equal('T1T2T3T4T5', g:T71_taken)
1374 Xpath 'w'
1375 catch /^0$/ " default return value
1376 Xpath 'x'
1377 call assert_report(v:throwpoint)
1378 catch /.*/
1379 Xpath 'y'
1380 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
1381 endtry
1382
1383 call assert_equal('acegikmosuw', g:Xpath)
1384 endfunc
1385
1386
1387 "-------------------------------------------------------------------------------
1388 " Test 72: :throw across :let or :unlet {{{1
1389 "
1390 " On a :let command, an exception might be thrown during evaluation
1391 " of the expression to assign. On an :let or :unlet command, the
1392 " evaluation of the name of the variable to be assigned or list or
1393 " deleted, respectively, may throw an exception. Any following
1394 " arguments are not evaluated, then. The exception can be caught by
1395 " the script.
1396 "-------------------------------------------------------------------------------
1397
1398 let throwcount = 0
1399
1400 func T72_throw(x)
1401 let g:throwcount = g:throwcount + 1
1402 throw a:x
1403 endfunc
1404
1405 let T72_addpath = ''
1406
1407 func T72_addpath(p)
1408 let g:T72_addpath = g:T72_addpath . a:p
1409 endfunc
1410
1411 func Test_throw_let()
1412 XpathINIT
1413
1414 try
1415 try
1416 let $VAR = 'old_value'
1417 Xpath 'a'
1418 let $VAR = 'let(' . T72_throw('var') . ')'
1419 Xpath 'b'
1420 catch /^var$/
1421 Xpath 'c'
1422 finally
1423 call assert_equal('old_value', $VAR)
1424 endtry
1425
1426 try
1427 let @a = 'old_value'
1428 Xpath 'd'
1429 let @a = 'let(' . T72_throw('reg') . ')'
1430 Xpath 'e'
1431 catch /^reg$/
1432 try
1433 Xpath 'f'
1434 let @A = 'let(' . T72_throw('REG') . ')'
1435 Xpath 'g'
1436 catch /^REG$/
1437 Xpath 'h'
1438 endtry
1439 finally
1440 call assert_equal('old_value', @a)
1441 call assert_equal('old_value', @A)
1442 endtry
1443
1444 try
1445 let saved_gpath = &g:path
1446 let saved_lpath = &l:path
1447 Xpath 'i'
1448 let &path = 'let(' . T72_throw('opt') . ')'
1449 Xpath 'j'
1450 catch /^opt$/
1451 try
1452 Xpath 'k'
1453 let &g:path = 'let(' . T72_throw('gopt') . ')'
1454 Xpath 'l'
1455 catch /^gopt$/
1456 try
1457 Xpath 'm'
1458 let &l:path = 'let(' . T72_throw('lopt') . ')'
1459 Xpath 'n'
1460 catch /^lopt$/
1461 Xpath 'o'
1462 endtry
1463 endtry
1464 finally
1465 call assert_equal(saved_gpath, &g:path)
1466 call assert_equal(saved_lpath, &l:path)
1467 let &g:path = saved_gpath
1468 let &l:path = saved_lpath
1469 endtry
1470
1471 unlet! var1 var2 var3
1472
1473 try
1474 Xpath 'p'
1475 let var1 = 'let(' . T72_throw('var1') . ')'
1476 Xpath 'q'
1477 catch /^var1$/
1478 Xpath 'r'
1479 finally
1480 call assert_true(!exists('var1'))
1481 endtry
1482
1483 try
1484 let var2 = 'old_value'
1485 Xpath 's'
1486 let var2 = 'let(' . T72_throw('var2'). ')'
1487 Xpath 't'
1488 catch /^var2$/
1489 Xpath 'u'
1490 finally
1491 call assert_equal('old_value', var2)
1492 endtry
1493
1494 try
1495 Xpath 'v'
1496 let var{T72_throw('var3')} = 4711
1497 Xpath 'w'
1498 catch /^var3$/
1499 Xpath 'x'
1500 endtry
1501
1502 try
1503 call T72_addpath('T1')
1504 let var{T72_throw('var4')} var{T72_addpath('T2')} | call T72_addpath('T3')
1505 call T72_addpath('T4')
1506 catch /^var4$/
1507 call T72_addpath('T5')
1508 endtry
1509
1510 try
1511 call T72_addpath('T6')
1512 unlet var{T72_throw('var5')} var{T72_addpath('T7')}
1513 \ | call T72_addpath('T8')
1514 call T72_addpath('T9')
1515 catch /^var5$/
1516 call T72_addpath('T10')
1517 endtry
1518
1519 call assert_equal('T1T5T6T10', g:T72_addpath)
1520 call assert_equal(11, g:throwcount)
1521 catch /.*/
1522 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
1523 endtry
1524
1525 call assert_equal('acdfhikmoprsuvx', g:Xpath)
1526 endfunc
1527
1528
1529 "-------------------------------------------------------------------------------
1530 " Test 73: :throw across :function, :delfunction {{{1
1531 "
1532 " The :function and :delfunction commands may cause an expression
1533 " specified in braces to be evaluated. During evaluation, an
1534 " exception might be thrown. The exception can be caught by the
1535 " script.
1536 "-------------------------------------------------------------------------------
1537
1538 let T73_taken = ''
1539
1540 func T73_throw(x, n)
1541 let g:T73_taken = g:T73_taken . 'T' . a:n
1542 throw a:x
1543 endfunc
1544
1545 func T73_expr(x, n)
1546 let g:T73_taken = g:T73_taken . 'E' . a:n
1547 if a:n % 2 == 0
1548 call T73_throw(a:x, a:n)
1549 endif
1550 return 2 - a:n % 2
1551 endfunc
1552
1553 func Test_throw_func()
1554 XpathINIT
1555
1556 try
1557 try
1558 " Define function.
1559 Xpath 'a'
1560 function! F0()
1561 endfunction
1562 Xpath 'b'
1563 function! F{T73_expr('function-def-ok', 1)}()
1564 endfunction
1565 Xpath 'c'
1566 function! F{T73_expr('function-def', 2)}()
1567 endfunction
1568 Xpath 'd'
1569 catch /^function-def-ok$/
1570 Xpath 'e'
1571 catch /^function-def$/
1572 Xpath 'f'
1573 catch /.*/
1574 call assert_report('def: ' . v:exception . ' in ' . v:throwpoint)
1575 endtry
1576
1577 try
1578 " List function.
1579 Xpath 'g'
1580 function F0
1581 Xpath 'h'
1582 function F{T73_expr('function-lst-ok', 3)}
1583 Xpath 'i'
1584 function F{T73_expr('function-lst', 4)}
1585 Xpath 'j'
1586 catch /^function-lst-ok$/
1587 Xpath 'k'
1588 catch /^function-lst$/
1589 Xpath 'l'
1590 catch /.*/
1591 call assert_report('lst: ' . v:exception . ' in ' . v:throwpoint)
1592 endtry
1593
1594 try
1595 " Delete function
1596 Xpath 'm'
1597 delfunction F0
1598 Xpath 'n'
1599 delfunction F{T73_expr('function-del-ok', 5)}
1600 Xpath 'o'
1601 delfunction F{T73_expr('function-del', 6)}
1602 Xpath 'p'
1603 catch /^function-del-ok$/
1604 Xpath 'q'
1605 catch /^function-del$/
1606 Xpath 'r'
1607 catch /.*/
1608 call assert_report('del: ' . v:exception . ' in ' . v:throwpoint)
1609 endtry
1610 call assert_equal('E1E2T2E3E4T4E5E6T6', g:T73_taken)
1611 catch /.*/
1612 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
1613 endtry
1614
1615 call assert_equal('abcfghilmnor', g:Xpath)
1616 endfunc
1617
1618
1619 "-------------------------------------------------------------------------------
1620 " Test 74: :throw across builtin functions and commands {{{1
1621 "
1622 " Some functions like exists(), searchpair() take expression
1623 " arguments, other functions or commands like substitute() or
1624 " :substitute cause an expression (specified in the regular
1625 " expression) to be evaluated. During evaluation an exception
1626 " might be thrown. The exception can be caught by the script.
1627 "-------------------------------------------------------------------------------
1628
1629 let T74_taken = ""
1630
1631 func T74_throw(x, n)
1632 let g:T74_taken = g:T74_taken . "T" . a:n
1633 throw a:x
1634 endfunc
1635
1636 func T74_expr(x, n)
1637 let g:T74_taken = g:T74_taken . "E" . a:n
1638 call T74_throw(a:x . a:n, a:n)
1639 return "EXPR"
1640 endfunc
1641
1642 func T74_skip(x, n)
1643 let g:T74_taken = g:T74_taken . "S" . a:n . "(" . line(".")
1644 let theline = getline(".")
1645 if theline =~ "skip"
1646 let g:T74_taken = g:T74_taken . "s)"
1647 return 1
1648 elseif theline =~ "throw"
1649 let g:T74_taken = g:T74_taken . "t)"
1650 call T74_throw(a:x . a:n, a:n)
1651 else
1652 let g:T74_taken = g:T74_taken . ")"
1653 return 0
1654 endif
1655 endfunc
1656
1657 func T74_subst(x, n)
1658 let g:T74_taken = g:T74_taken . "U" . a:n . "(" . line(".")
1659 let theline = getline(".")
1660 if theline =~ "not" " T74_subst() should not be called for this line
1661 let g:T74_taken = g:T74_taken . "n)"
1662 call T74_throw(a:x . a:n, a:n)
1663 elseif theline =~ "throw"
1664 let g:T74_taken = g:T74_taken . "t)"
1665 call T74_throw(a:x . a:n, a:n)
1666 else
1667 let g:T74_taken = g:T74_taken . ")"
1668 return "replaced"
1669 endif
1670 endfunc
1671
1672 func Test_throw_builtin_func()
1673 XpathINIT
1674
1675 try
1676 try
1677 Xpath 'a'
1678 let result = exists('*{T74_expr("exists", 1)}')
1679 Xpath 'b'
1680 catch /^exists1$/
1681 Xpath 'c'
1682 try
1683 let result = exists('{T74_expr("exists", 2)}')
1684 Xpath 'd'
1685 catch /^exists2$/
1686 Xpath 'e'
1687 catch /.*/
1688 call assert_report('exists2: ' . v:exception . ' in ' . v:throwpoint)
1689 endtry
1690 catch /.*/
1691 call assert_report('exists1: ' . v:exception . ' in ' . v:throwpoint)
1692 endtry
1693
1694 try
1695 let file = tempname()
1696 exec "edit" file
1697 call append(0, [
1698 \ 'begin',
1699 \ 'xx',
1700 \ 'middle 3',
1701 \ 'xx',
1702 \ 'middle 5 skip',
1703 \ 'xx',
1704 \ 'middle 7 throw',
1705 \ 'xx',
1706 \ 'end'])
1707 normal! gg
1708 Xpath 'f'
1709 let result = searchpair("begin", "middle", "end", '',
1710 \ 'T74_skip("searchpair", 3)')
1711 Xpath 'g'
1712 let result = searchpair("begin", "middle", "end", '',
1713 \ 'T74_skip("searchpair", 4)')
1714 Xpath 'h'
1715 let result = searchpair("begin", "middle", "end", '',
1716 \ 'T74_skip("searchpair", 5)')
1717 Xpath 'i'
1718 catch /^searchpair[35]$/
1719 Xpath 'j'
1720 catch /^searchpair4$/
1721 Xpath 'k'
1722 catch /.*/
1723 call assert_report('searchpair: ' . v:exception . ' in ' . v:throwpoint)
1724 finally
1725 bwipeout!
1726 call delete(file)
1727 endtry
1728
1729 try
1730 let file = tempname()
1731 exec "edit" file
1732 call append(0, [
1733 \ 'subst 1',
1734 \ 'subst 2',
1735 \ 'not',
1736 \ 'subst 4',
1737 \ 'subst throw',
1738 \ 'subst 6'])
1739 normal! gg
1740 Xpath 'l'
1741 1,2substitute/subst/\=T74_subst("substitute", 6)/
1742 try
1743 Xpath 'm'
1744 try
1745 let v:errmsg = ""
1746 3substitute/subst/\=T74_subst("substitute", 7)/
1747 finally
1748 if v:errmsg != ""
1749 " If exceptions are not thrown on errors, fake the error
1750 " exception in order to get the same execution path.
1751 throw "faked Vim(substitute)"
1752 endif
1753 endtry
1754 catch /Vim(substitute)/ " Pattern not found ('e' flag missing)
1755 Xpath 'n'
1756 3substitute/subst/\=T74_subst("substitute", 8)/e
1757 Xpath 'o'
1758 endtry
1759 Xpath 'p'
1760 4,6substitute/subst/\=T74_subst("substitute", 9)/
1761 Xpath 'q'
1762 catch /^substitute[678]/
1763 Xpath 'r'
1764 catch /^substitute9/
1765 Xpath 's'
1766 finally
1767 bwipeout!
1768 call delete(file)
1769 endtry
1770
1771 try
1772 Xpath 't'
1773 let var = substitute("sub", "sub", '\=T74_throw("substitute()y", 10)', '')
1774 Xpath 'u'
1775 catch /substitute()y/
1776 Xpath 'v'
1777 catch /.*/
1778 call assert_report('substitute()y: ' . v:exception . ' in '
1779 \ . v:throwpoint)
1780 endtry
1781
1782 try
1783 Xpath 'w'
1784 let var = substitute("not", "sub", '\=T74_throw("substitute()n", 11)', '')
1785 Xpath 'x'
1786 catch /substitute()n/
1787 Xpath 'y'
1788 catch /.*/
1789 call assert_report('substitute()n: ' . v:exception . ' in '
1790 \ . v:throwpoint)
1791 endtry
1792
1793 call assert_equal('E1T1E2T2S3(3)S4(5s)S4(7t)T4U6(1)U6(2)U9(4)U9(5t)T9T10',
1794 \ g:T74_taken)
1795
1796 catch /.*/
1797 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
1798 endtry
1799
1800 call assert_equal('acefgklmnopstvwx', g:Xpath)
1801 endfunc
1802
1803
1804 "-------------------------------------------------------------------------------
1805 " Test 75: Errors in builtin functions. {{{1
1806 "
1807 " On an error in a builtin function called inside a :try/:endtry
1808 " region, the evaluation of the expression calling that function and
1809 " the command containing that expression are abandoned. The error can
1810 " be caught as an exception.
1811 "
1812 " A simple :call of the builtin function is a trivial case. If the
1813 " builtin function is called in the argument list of another function,
1814 " no further arguments are evaluated, and the other function is not
1815 " executed. If the builtin function is called from the argument of
1816 " a :return command, the :return command is not executed. If the
1817 " builtin function is called from the argument of a :throw command,
1818 " the :throw command is not executed. The evaluation of the
1819 " expression calling the builtin function is abandoned.
1820 "-------------------------------------------------------------------------------
1821
1822 func T75_F1(arg1)
1823 Xpath 'a'
1824 endfunc
1825
1826 func T75_F2(arg1, arg2)
1827 Xpath 'b'
1828 endfunc
1829
1830 func T75_G()
1831 Xpath 'c'
1832 endfunc
1833
1834 func T75_H()
1835 Xpath 'd'
1836 endfunc
1837
1838 func T75_R()
1839 while 1
1840 try
1841 let caught = 0
1842 let v:errmsg = ""
1843 Xpath 'e'
1844 return append(1, "s")
1845 catch /E21/
1846 let caught = 1
1847 catch /.*/
1848 Xpath 'f'
1849 finally
1850 Xpath 'g'
1851 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
1852 Xpath 'h'
1853 endif
1854 break " discard error for $VIMNOERRTHROW
1855 endtry
1856 endwhile
1857 Xpath 'i'
1858 endfunc
1859
1860 func Test_builtin_func_error()
1861 XpathINIT
1862
1863 try
1864 set noma " let append() fail with "E21"
1865
1866 while 1
1867 try
1868 let caught = 0
1869 let v:errmsg = ""
1870 Xpath 'j'
1871 call append(1, "s")
1872 catch /E21/
1873 let caught = 1
1874 catch /.*/
1875 Xpath 'k'
1876 finally
1877 Xpath 'l'
1878 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
1879 Xpath 'm'
1880 endif
1881 break " discard error for $VIMNOERRTHROW
1882 endtry
1883 endwhile
1884
1885 while 1
1886 try
1887 let caught = 0
1888 let v:errmsg = ""
1889 Xpath 'n'
1890 call T75_F1('x' . append(1, "s"))
1891 catch /E21/
1892 let caught = 1
1893 catch /.*/
1894 Xpath 'o'
1895 finally
1896 Xpath 'p'
1897 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
1898 Xpath 'q'
1899 endif
1900 break " discard error for $VIMNOERRTHROW
1901 endtry
1902 endwhile
1903
1904 while 1
1905 try
1906 let caught = 0
1907 let v:errmsg = ""
1908 Xpath 'r'
1909 call T75_F2('x' . append(1, "s"), T75_G())
1910 catch /E21/
1911 let caught = 1
1912 catch /.*/
1913 Xpath 's'
1914 finally
1915 Xpath 't'
1916 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
1917 Xpath 'u'
1918 endif
1919 break " discard error for $VIMNOERRTHROW
1920 endtry
1921 endwhile
1922
1923 call T75_R()
1924
1925 while 1
1926 try
1927 let caught = 0
1928 let v:errmsg = ""
1929 Xpath 'v'
1930 throw "T" . append(1, "s")
1931 catch /E21/
1932 let caught = 1
1933 catch /^T.*/
1934 Xpath 'w'
1935 catch /.*/
1936 Xpath 'x'
1937 finally
1938 Xpath 'y'
1939 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
1940 Xpath 'z'
1941 endif
1942 break " discard error for $VIMNOERRTHROW
1943 endtry
1944 endwhile
1945
1946 while 1
1947 try
1948 let caught = 0
1949 let v:errmsg = ""
1950 Xpath 'A'
1951 let x = "a"
1952 let x = x . "b" . append(1, "s") . T75_H()
1953 catch /E21/
1954 let caught = 1
1955 catch /.*/
1956 Xpath 'B'
1957 finally
1958 Xpath 'C'
1959 if caught || $VIMNOERRTHROW && v:errmsg =~ 'E21'
1960 Xpath 'D'
1961 endif
1962 call assert_equal('a', x)
1963 break " discard error for $VIMNOERRTHROW
1964 endtry
1965 endwhile
1966 catch /.*/
1967 call assert_report('Caught ' . v:exception . ' in ' . v:throwpoint)
1968 finally
1969 set ma&
1970 endtry
1971
1972 call assert_equal('jlmnpqrtueghivyzACD', g:Xpath)
1973 endfunc
1974
1975 " Modelines {{{1
1976 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
1977 "-------------------------------------------------------------------------------