annotate src/ex_eval.c @ 4444:ccecb03e5e8b v7.3.970

updated for version 7.3.970 Problem: Syntax highlighting can be slow. Solution: Include the NFA regexp engine. Add the 'regexpengine' option to select which one is used. (various authors, including Ken Takata, Andrei Aiordachioaie, Russ Cox, Xiaozhou Liua, Ian Young)
author Bram Moolenaar <bram@vim.org>
date Sun, 19 May 2013 19:40:29 +0200
parents 04736b4030ec
children 66803af09906
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1 /* vi:set ts=8 sts=4 sw=4:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2 *
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
3 * VIM - Vi IMproved by Bram Moolenaar
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
4 *
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
5 * Do ":help uganda" in Vim to read copying and usage conditions.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
6 * Do ":help credits" in Vim to see a list of people who contributed.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
7 * See README.txt for an overview of the Vim source code.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
8 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
9
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
10 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
11 * ex_eval.c: functions for Ex command line for the +eval feature.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
12 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
13
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
14 #include "vim.h"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
15
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
16 #if defined(FEAT_EVAL) || defined(PROTO)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
17
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
18 static void free_msglist __ARGS((struct msglist *l));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
19 static int throw_exception __ARGS((void *, int, char_u *));
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
20 static char_u *get_end_emsg __ARGS((struct condstack *cstack));
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
21
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
22 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
23 * Exception handling terms:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
24 *
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
25 * :try ":try" command \
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
26 * ... try block |
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
27 * :catch RE ":catch" command |
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
28 * ... catch clause |- try conditional
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
29 * :finally ":finally" command |
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
30 * ... finally clause |
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
31 * :endtry ":endtry" command /
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
32 *
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
33 * The try conditional may have any number of catch clauses and at most one
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
34 * finally clause. A ":throw" command can be inside the try block, a catch
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
35 * clause, the finally clause, or in a function called or script sourced from
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
36 * there or even outside the try conditional. Try conditionals may be nested.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
37 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
38
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
39 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
40 * Configuration whether an exception is thrown on error or interrupt. When
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
41 * the preprocessor macros below evaluate to FALSE, an error (did_emsg) or
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
42 * interrupt (got_int) under an active try conditional terminates the script
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
43 * after the non-active finally clauses of all active try conditionals have been
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
44 * executed. Otherwise, errors and/or interrupts are converted into catchable
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
45 * exceptions (did_throw additionally set), which terminate the script only if
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
46 * not caught. For user exceptions, only did_throw is set. (Note: got_int can
4352
04736b4030ec updated for version 7.3.925
Bram Moolenaar <bram@vim.org>
parents: 1880
diff changeset
47 * be set asynchronously afterwards by a SIGINT, so did_throw && got_int is not
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
48 * a reliant test that the exception currently being thrown is an interrupt
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
49 * exception. Similarly, did_emsg can be set afterwards on an error in an
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
50 * (unskipped) conditional command inside an inactive conditional, so did_throw
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
51 * && did_emsg is not a reliant test that the exception currently being thrown
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
52 * is an error exception.) - The macros can be defined as expressions checking
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
53 * for a variable that is allowed to be changed during execution of a script.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
54 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
55 #if 0
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
56 /* Expressions used for testing during the development phase. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
57 # define THROW_ON_ERROR (!eval_to_number("$VIMNOERRTHROW"))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
58 # define THROW_ON_INTERRUPT (!eval_to_number("$VIMNOINTTHROW"))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
59 # define THROW_TEST
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
60 #else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
61 /* Values used for the Vim release. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
62 # define THROW_ON_ERROR TRUE
1880
e5602d92da8c updated for version 7.2-177
vimboss
parents: 1447
diff changeset
63 # define THROW_ON_ERROR_TRUE
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
64 # define THROW_ON_INTERRUPT TRUE
1880
e5602d92da8c updated for version 7.2-177
vimboss
parents: 1447
diff changeset
65 # define THROW_ON_INTERRUPT_TRUE
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
66 #endif
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
67
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
68 static void catch_exception __ARGS((except_T *excp));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
69 static void finish_exception __ARGS((except_T *excp));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
70 static void discard_exception __ARGS((except_T *excp, int was_finished));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
71 static void report_pending __ARGS((int action, int pending, void *value));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
72
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
73 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
74 * When several errors appear in a row, setting "force_abort" is delayed until
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
75 * the failing command returned. "cause_abort" is set to TRUE meanwhile, in
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
76 * order to indicate that situation. This is useful when "force_abort" was set
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
77 * during execution of a function call from an expression: the aborting of the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
78 * expression evaluation is done without producing any error messages, but all
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
79 * error messages on parsing errors during the expression evaluation are given
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
80 * (even if a try conditional is active).
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
81 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
82 static int cause_abort = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
83
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
84 /*
1214
a91a2e0c4108 updated for version 7.1b
vimboss
parents: 1046
diff changeset
85 * Return TRUE when immediately aborting on error, or when an interrupt
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
86 * occurred or an exception was thrown but not caught. Use for ":{range}call"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
87 * to check whether an aborted function that does not handle a range itself
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
88 * should be called again for the next line in the range. Also used for
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
89 * cancelling expression evaluation after a function call caused an immediate
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
90 * abort. Note that the first emsg() call temporarily resets "force_abort"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
91 * until the throw point for error messages has been reached. That is, during
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
92 * cancellation of an expression evaluation after an aborting function call or
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
93 * due to a parsing error, aborting() always returns the same value.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
94 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
95 int
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
96 aborting()
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
97 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
98 return (did_emsg && force_abort) || got_int || did_throw;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
99 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
100
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
101 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
102 * The value of "force_abort" is temporarily reset by the first emsg() call
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
103 * during an expression evaluation, and "cause_abort" is used instead. It might
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
104 * be necessary to restore "force_abort" even before the throw point for the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
105 * error message has been reached. update_force_abort() should be called then.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
106 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
107 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
108 update_force_abort()
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
109 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
110 if (cause_abort)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
111 force_abort = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
112 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
113
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
114 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
115 * Return TRUE if a command with a subcommand resulting in "retcode" should
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
116 * abort the script processing. Can be used to suppress an autocommand after
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
117 * execution of a failing subcommand as long as the error message has not been
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
118 * displayed and actually caused the abortion.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
119 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
120 int
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
121 should_abort(retcode)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
122 int retcode;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
123 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
124 return ((retcode == FAIL && trylevel != 0 && !emsg_silent) || aborting());
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
125 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
126
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
127 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
128 * Return TRUE if a function with the "abort" flag should not be considered
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
129 * ended on an error. This means that parsing commands is continued in order
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
130 * to find finally clauses to be executed, and that some errors in skipped
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
131 * commands are still reported.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
132 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
133 int
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
134 aborted_in_try()
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
135 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
136 /* This function is only called after an error. In this case, "force_abort"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
137 * determines whether searching for finally clauses is necessary. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
138 return force_abort;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
139 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
140
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
141 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
142 * cause_errthrow(): Cause a throw of an error exception if appropriate.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
143 * Return TRUE if the error message should not be displayed by emsg().
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
144 * Sets "ignore", if the emsg() call should be ignored completely.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
145 *
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
146 * When several messages appear in the same command, the first is usually the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
147 * most specific one and used as the exception value. The "severe" flag can be
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
148 * set to TRUE, if a later but severer message should be used instead.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
149 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
150 int
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
151 cause_errthrow(mesg, severe, ignore)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
152 char_u *mesg;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
153 int severe;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
154 int *ignore;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
155 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
156 struct msglist *elem;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
157 struct msglist **plist;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
158
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
159 /*
839
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
160 * Do nothing when displaying the interrupt message or reporting an
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
161 * uncaught exception (which has already been discarded then) at the top
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
162 * level. Also when no exception can be thrown. The message will be
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
163 * displayed by emsg().
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
164 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
165 if (suppress_errthrow)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
166 return FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
167
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
168 /*
839
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
169 * If emsg() has not been called previously, temporarily reset
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
170 * "force_abort" until the throw point for error messages has been
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
171 * reached. This ensures that aborting() returns the same value for all
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
172 * errors that appear in the same command. This means particularly that
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
173 * for parsing errors during expression evaluation emsg() will be called
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
174 * multiply, even when the expression is evaluated from a finally clause
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
175 * that was activated due to an aborting error, interrupt, or exception.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
176 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
177 if (!did_emsg)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
178 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
179 cause_abort = force_abort;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
180 force_abort = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
181 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
182
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
183 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
184 * If no try conditional is active and no exception is being thrown and
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
185 * there has not been an error in a try conditional or a throw so far, do
839
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
186 * nothing (for compatibility of non-EH scripts). The message will then
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
187 * be displayed by emsg(). When ":silent!" was used and we are not
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
188 * currently throwing an exception, do nothing. The message text will
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
189 * then be stored to v:errmsg by emsg() without displaying it.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
190 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
191 if (((trylevel == 0 && !cause_abort) || emsg_silent) && !did_throw)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
192 return FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
193
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
194 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
195 * Ignore an interrupt message when inside a try conditional or when an
839
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
196 * exception is being thrown or when an error in a try conditional or
1f3b1021f002 updated for version 7.0e05
vimboss
parents: 835
diff changeset
197 * throw has been detected previously. This is important in order that an
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
198 * interrupt exception is catchable by the innermost try conditional and
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
199 * not replaced by an interrupt message error exception.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
200 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
201 if (mesg == (char_u *)_(e_interr))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
202 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
203 *ignore = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
204 return TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
205 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
206
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
207 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
208 * Ensure that all commands in nested function calls and sourced files
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
209 * are aborted immediately.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
210 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
211 cause_abort = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
212
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
213 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
214 * When an exception is being thrown, some commands (like conditionals) are
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
215 * not skipped. Errors in those commands may affect what of the subsequent
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
216 * commands are regarded part of catch and finally clauses. Catching the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
217 * exception would then cause execution of commands not intended by the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
218 * user, who wouldn't even get aware of the problem. Therefor, discard the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
219 * exception currently being thrown to prevent it from being caught. Just
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
220 * execute finally clauses and terminate.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
221 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
222 if (did_throw)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
223 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
224 /* When discarding an interrupt exception, reset got_int to prevent the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
225 * same interrupt being converted to an exception again and discarding
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
226 * the error exception we are about to throw here. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
227 if (current_exception->type == ET_INTERRUPT)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
228 got_int = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
229 discard_current_exception();
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
230 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
231
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
232 #ifdef THROW_TEST
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
233 if (!THROW_ON_ERROR)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
234 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
235 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
236 * Print error message immediately without searching for a matching
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
237 * catch clause; just finally clauses are executed before the script
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
238 * is terminated.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
239 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
240 return FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
241 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
242 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
243 #endif
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
244 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
245 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
246 * Prepare the throw of an error exception, so that everything will
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
247 * be aborted (except for executing finally clauses), until the error
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
248 * exception is caught; if still uncaught at the top level, the error
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
249 * message will be displayed and the script processing terminated
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
250 * then. - This function has no access to the conditional stack.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
251 * Thus, the actual throw is made after the failing command has
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
252 * returned. - Throw only the first of several errors in a row, except
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
253 * a severe error is following.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
254 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
255 if (msg_list != NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
256 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
257 plist = msg_list;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
258 while (*plist != NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
259 plist = &(*plist)->next;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
260
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
261 elem = (struct msglist *)alloc((unsigned)sizeof(struct msglist));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
262 if (elem == NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
263 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
264 suppress_errthrow = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
265 EMSG(_(e_outofmem));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
266 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
267 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
268 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
269 elem->msg = vim_strsave(mesg);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
270 if (elem->msg == NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
271 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
272 vim_free(elem);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
273 suppress_errthrow = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
274 EMSG(_(e_outofmem));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
275 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
276 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
277 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
278 elem->next = NULL;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
279 elem->throw_msg = NULL;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
280 *plist = elem;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
281 if (plist == msg_list || severe)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
282 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
283 char_u *tmsg;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
284
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
285 /* Skip the extra "Vim " prefix for message "E458". */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
286 tmsg = elem->msg;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
287 if (STRNCMP(tmsg, "Vim E", 5) == 0
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
288 && VIM_ISDIGIT(tmsg[5])
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
289 && VIM_ISDIGIT(tmsg[6])
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
290 && VIM_ISDIGIT(tmsg[7])
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
291 && tmsg[8] == ':'
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
292 && tmsg[9] == ' ')
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
293 (*msg_list)->throw_msg = &tmsg[4];
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
294 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
295 (*msg_list)->throw_msg = tmsg;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
296 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
297 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
298 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
299 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
300 return TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
301 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
302 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
303
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
304 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
305 * Free a "msg_list" and the messages it contains.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
306 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
307 static void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
308 free_msglist(l)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
309 struct msglist *l;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
310 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
311 struct msglist *messages, *next;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
312
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
313 messages = l;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
314 while (messages != NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
315 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
316 next = messages->next;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
317 vim_free(messages->msg);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
318 vim_free(messages);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
319 messages = next;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
320 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
321 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
322
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
323 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
324 * Throw the message specified in the call to cause_errthrow() above as an
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
325 * error exception. If cstack is NULL, postpone the throw until do_cmdline()
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
326 * has returned (see do_one_cmd()).
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
327 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
328 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
329 do_errthrow(cstack, cmdname)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
330 struct condstack *cstack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
331 char_u *cmdname;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
332 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
333 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
334 * Ensure that all commands in nested function calls and sourced files
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
335 * are aborted immediately.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
336 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
337 if (cause_abort)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
338 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
339 cause_abort = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
340 force_abort = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
341 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
342
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
343 /* If no exception is to be thrown or the conversion should be done after
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
344 * returning to a previous invocation of do_one_cmd(), do nothing. */
1046
26ff011aec2d updated for version 7.0-172
vimboss
parents: 840
diff changeset
345 if (msg_list == NULL || *msg_list == NULL)
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
346 return;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
347
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
348 if (throw_exception(*msg_list, ET_ERROR, cmdname) == FAIL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
349 free_msglist(*msg_list);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
350 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
351 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
352 if (cstack != NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
353 do_throw(cstack);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
354 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
355 need_rethrow = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
356 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
357 *msg_list = NULL;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
358 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
359
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
360 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
361 * do_intthrow(): Replace the current exception by an interrupt or interrupt
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
362 * exception if appropriate. Return TRUE if the current exception is discarded,
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
363 * FALSE otherwise.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
364 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
365 int
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
366 do_intthrow(cstack)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
367 struct condstack *cstack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
368 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
369 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
370 * If no interrupt occurred or no try conditional is active and no exception
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
371 * is being thrown, do nothing (for compatibility of non-EH scripts).
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
372 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
373 if (!got_int || (trylevel == 0 && !did_throw))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
374 return FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
375
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
376 #ifdef THROW_TEST /* avoid warning for condition always true */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
377 if (!THROW_ON_INTERRUPT)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
378 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
379 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
380 * The interrupt aborts everything except for executing finally clauses.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
381 * Discard any user or error or interrupt exception currently being
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
382 * thrown.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
383 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
384 if (did_throw)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
385 discard_current_exception();
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
386 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
387 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
388 #endif
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
389 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
390 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
391 * Throw an interrupt exception, so that everything will be aborted
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
392 * (except for executing finally clauses), until the interrupt exception
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
393 * is caught; if still uncaught at the top level, the script processing
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
394 * will be terminated then. - If an interrupt exception is already
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
395 * being thrown, do nothing.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
396 *
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
397 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
398 if (did_throw)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
399 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
400 if (current_exception->type == ET_INTERRUPT)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
401 return FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
402
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
403 /* An interrupt exception replaces any user or error exception. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
404 discard_current_exception();
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
405 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
406 if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) != FAIL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
407 do_throw(cstack);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
408 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
409
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
410 return TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
411 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
412
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
413
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
414 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
415 * Throw a new exception. Return FAIL when out of memory or it was tried to
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
416 * throw an illegal user exception. "value" is the exception string for a user
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
417 * or interrupt exception, or points to a message list in case of an error
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
418 * exception.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
419 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
420 static int
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
421 throw_exception(value, type, cmdname)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
422 void *value;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
423 int type;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
424 char_u *cmdname;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
425 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
426 except_T *excp;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
427 char_u *p, *mesg, *val;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
428 int cmdlen;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
429
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
430 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
431 * Disallow faking Interrupt or error exceptions as user exceptions. They
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
432 * would be treated differently from real interrupt or error exceptions when
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
433 * no active try block is found, see do_cmdline().
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
434 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
435 if (type == ET_USER)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
436 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
437 if (STRNCMP((char_u *)value, "Vim", 3) == 0 &&
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
438 (((char_u *)value)[3] == NUL || ((char_u *)value)[3] == ':' ||
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
439 ((char_u *)value)[3] == '('))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
440 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
441 EMSG(_("E608: Cannot :throw exceptions with 'Vim' prefix"));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
442 goto fail;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
443 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
444 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
445
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
446 excp = (except_T *)alloc((unsigned)sizeof(except_T));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
447 if (excp == NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
448 goto nomem;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
449
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
450 if (type == ET_ERROR)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
451 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
452 /* Store the original message and prefix the exception value with
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
453 * "Vim:" or, if a command name is given, "Vim(cmdname):". */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
454 excp->messages = (struct msglist *)value;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
455 mesg = excp->messages->throw_msg;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
456 if (cmdname != NULL && *cmdname != NUL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
457 {
835
8bebcabccc2c updated for version 7.0e01
vimboss
parents: 359
diff changeset
458 cmdlen = (int)STRLEN(cmdname);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
459 excp->value = vim_strnsave((char_u *)"Vim(",
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
460 4 + cmdlen + 2 + (int)STRLEN(mesg));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
461 if (excp->value == NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
462 goto nomem;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
463 STRCPY(&excp->value[4], cmdname);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
464 STRCPY(&excp->value[4 + cmdlen], "):");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
465 val = excp->value + 4 + cmdlen + 2;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
466 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
467 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
468 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
469 excp->value = vim_strnsave((char_u *)"Vim:", 4 + (int)STRLEN(mesg));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
470 if (excp->value == NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
471 goto nomem;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
472 val = excp->value + 4;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
473 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
474
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
475 /* msg_add_fname may have been used to prefix the message with a file
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
476 * name in quotes. In the exception value, put the file name in
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
477 * parentheses and move it to the end. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
478 for (p = mesg; ; p++)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
479 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
480 if (*p == NUL
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
481 || (*p == 'E'
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
482 && VIM_ISDIGIT(p[1])
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
483 && (p[2] == ':'
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
484 || (VIM_ISDIGIT(p[2])
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
485 && (p[3] == ':'
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
486 || (VIM_ISDIGIT(p[3])
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
487 && p[4] == ':'))))))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
488 {
273
2463194c8cdd updated for version 7.0073
vimboss
parents: 114
diff changeset
489 if (*p == NUL || p == mesg)
2463194c8cdd updated for version 7.0073
vimboss
parents: 114
diff changeset
490 STRCAT(val, mesg); /* 'E123' missing or at beginning */
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
491 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
492 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
493 /* '"filename" E123: message text' */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
494 if (mesg[0] != '"' || p-2 < &mesg[1] ||
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
495 p[-2] != '"' || p[-1] != ' ')
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
496 /* "E123:" is part of the file name. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
497 continue;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
498
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
499 STRCAT(val, p);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
500 p[-2] = NUL;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
501 sprintf((char *)(val + STRLEN(p)), " (%s)", &mesg[1]);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
502 p[-2] = '"';
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
503 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
504 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
505 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
506 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
507 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
508 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
509 excp->value = value;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
510
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
511 excp->type = type;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
512 excp->throw_name = vim_strsave(sourcing_name == NULL
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
513 ? (char_u *)"" : sourcing_name);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
514 if (excp->throw_name == NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
515 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
516 if (type == ET_ERROR)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
517 vim_free(excp->value);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
518 goto nomem;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
519 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
520 excp->throw_lnum = sourcing_lnum;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
521
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
522 if (p_verbose >= 13 || debug_break_level > 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
523 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
524 int save_msg_silent = msg_silent;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
525
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
526 if (debug_break_level > 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
527 msg_silent = FALSE; /* display messages */
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
528 else
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
529 verbose_enter();
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
530 ++no_wait_return;
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
531 if (debug_break_level > 0 || *p_vfile == NUL)
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
532 msg_scroll = TRUE; /* always scroll up, don't overwrite */
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
533
273
2463194c8cdd updated for version 7.0073
vimboss
parents: 114
diff changeset
534 smsg((char_u *)_("Exception thrown: %s"), excp->value);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
535 msg_puts((char_u *)"\n"); /* don't overwrite this either */
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
536
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
537 if (debug_break_level > 0 || *p_vfile == NUL)
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
538 cmdline_row = msg_row;
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
539 --no_wait_return;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
540 if (debug_break_level > 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
541 msg_silent = save_msg_silent;
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
542 else
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
543 verbose_leave();
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
544 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
545
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
546 current_exception = excp;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
547 return OK;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
548
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
549 nomem:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
550 vim_free(excp);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
551 suppress_errthrow = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
552 EMSG(_(e_outofmem));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
553 fail:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
554 current_exception = NULL;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
555 return FAIL;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
556 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
557
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
558 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
559 * Discard an exception. "was_finished" is set when the exception has been
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
560 * caught and the catch clause has been ended normally.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
561 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
562 static void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
563 discard_exception(excp, was_finished)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
564 except_T *excp;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
565 int was_finished;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
566 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
567 char_u *saved_IObuff;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
568
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
569 if (excp == NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
570 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
571 EMSG(_(e_internal));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
572 return;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
573 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
574
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
575 if (p_verbose >= 13 || debug_break_level > 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
576 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
577 int save_msg_silent = msg_silent;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
578
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
579 saved_IObuff = vim_strsave(IObuff);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
580 if (debug_break_level > 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
581 msg_silent = FALSE; /* display messages */
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
582 else
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
583 verbose_enter();
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
584 ++no_wait_return;
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
585 if (debug_break_level > 0 || *p_vfile == NUL)
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
586 msg_scroll = TRUE; /* always scroll up, don't overwrite */
273
2463194c8cdd updated for version 7.0073
vimboss
parents: 114
diff changeset
587 smsg(was_finished
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
588 ? (char_u *)_("Exception finished: %s")
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
589 : (char_u *)_("Exception discarded: %s"),
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
590 excp->value);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
591 msg_puts((char_u *)"\n"); /* don't overwrite this either */
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
592 if (debug_break_level > 0 || *p_vfile == NUL)
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
593 cmdline_row = msg_row;
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
594 --no_wait_return;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
595 if (debug_break_level > 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
596 msg_silent = save_msg_silent;
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
597 else
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
598 verbose_leave();
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
599 STRCPY(IObuff, saved_IObuff);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
600 vim_free(saved_IObuff);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
601 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
602 if (excp->type != ET_INTERRUPT)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
603 vim_free(excp->value);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
604 if (excp->type == ET_ERROR)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
605 free_msglist(excp->messages);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
606 vim_free(excp->throw_name);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
607 vim_free(excp);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
608 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
609
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
610 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
611 * Discard the exception currently being thrown.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
612 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
613 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
614 discard_current_exception()
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
615 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
616 discard_exception(current_exception, FALSE);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
617 current_exception = NULL;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
618 did_throw = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
619 need_rethrow = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
620 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
621
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
622 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
623 * Put an exception on the caught stack.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
624 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
625 static void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
626 catch_exception(excp)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
627 except_T *excp;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
628 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
629 excp->caught = caught_stack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
630 caught_stack = excp;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
631 set_vim_var_string(VV_EXCEPTION, excp->value, -1);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
632 if (*excp->throw_name != NUL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
633 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
634 if (excp->throw_lnum != 0)
273
2463194c8cdd updated for version 7.0073
vimboss
parents: 114
diff changeset
635 vim_snprintf((char *)IObuff, IOSIZE, _("%s, line %ld"),
2463194c8cdd updated for version 7.0073
vimboss
parents: 114
diff changeset
636 excp->throw_name, (long)excp->throw_lnum);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
637 else
273
2463194c8cdd updated for version 7.0073
vimboss
parents: 114
diff changeset
638 vim_snprintf((char *)IObuff, IOSIZE, "%s", excp->throw_name);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
639 set_vim_var_string(VV_THROWPOINT, IObuff, -1);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
640 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
641 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
642 /* throw_name not set on an exception from a command that was typed. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
643 set_vim_var_string(VV_THROWPOINT, NULL, -1);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
644
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
645 if (p_verbose >= 13 || debug_break_level > 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
646 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
647 int save_msg_silent = msg_silent;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
648
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
649 if (debug_break_level > 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
650 msg_silent = FALSE; /* display messages */
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
651 else
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
652 verbose_enter();
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
653 ++no_wait_return;
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
654 if (debug_break_level > 0 || *p_vfile == NUL)
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
655 msg_scroll = TRUE; /* always scroll up, don't overwrite */
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
656
273
2463194c8cdd updated for version 7.0073
vimboss
parents: 114
diff changeset
657 smsg((char_u *)_("Exception caught: %s"), excp->value);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
658 msg_puts((char_u *)"\n"); /* don't overwrite this either */
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
659
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
660 if (debug_break_level > 0 || *p_vfile == NUL)
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
661 cmdline_row = msg_row;
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
662 --no_wait_return;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
663 if (debug_break_level > 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
664 msg_silent = save_msg_silent;
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
665 else
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
666 verbose_leave();
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
667 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
668 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
669
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
670 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
671 * Remove an exception from the caught stack.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
672 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
673 static void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
674 finish_exception(excp)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
675 except_T *excp;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
676 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
677 if (excp != caught_stack)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
678 EMSG(_(e_internal));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
679 caught_stack = caught_stack->caught;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
680 if (caught_stack != NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
681 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
682 set_vim_var_string(VV_EXCEPTION, caught_stack->value, -1);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
683 if (*caught_stack->throw_name != NUL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
684 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
685 if (caught_stack->throw_lnum != 0)
273
2463194c8cdd updated for version 7.0073
vimboss
parents: 114
diff changeset
686 vim_snprintf((char *)IObuff, IOSIZE,
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
687 _("%s, line %ld"), caught_stack->throw_name,
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
688 (long)caught_stack->throw_lnum);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
689 else
273
2463194c8cdd updated for version 7.0073
vimboss
parents: 114
diff changeset
690 vim_snprintf((char *)IObuff, IOSIZE, "%s",
2463194c8cdd updated for version 7.0073
vimboss
parents: 114
diff changeset
691 caught_stack->throw_name);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
692 set_vim_var_string(VV_THROWPOINT, IObuff, -1);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
693 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
694 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
695 /* throw_name not set on an exception from a command that was
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
696 * typed. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
697 set_vim_var_string(VV_THROWPOINT, NULL, -1);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
698 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
699 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
700 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
701 set_vim_var_string(VV_EXCEPTION, NULL, -1);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
702 set_vim_var_string(VV_THROWPOINT, NULL, -1);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
703 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
704
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
705 /* Discard the exception, but use the finish message for 'verbose'. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
706 discard_exception(excp, TRUE);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
707 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
708
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
709 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
710 * Flags specifying the message displayed by report_pending.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
711 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
712 #define RP_MAKE 0
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
713 #define RP_RESUME 1
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
714 #define RP_DISCARD 2
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
715
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
716 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
717 * Report information about something pending in a finally clause if required by
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
718 * the 'verbose' option or when debugging. "action" tells whether something is
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
719 * made pending or something pending is resumed or discarded. "pending" tells
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
720 * what is pending. "value" specifies the return value for a pending ":return"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
721 * or the exception value for a pending exception.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
722 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
723 static void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
724 report_pending(action, pending, value)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
725 int action;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
726 int pending;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
727 void *value;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
728 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
729 char_u *mesg;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
730 char *s;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
731 int save_msg_silent;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
732
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
733
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
734 switch (action)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
735 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
736 case RP_MAKE:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
737 mesg = (char_u *)_("%s made pending");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
738 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
739 case RP_RESUME:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
740 mesg = (char_u *)_("%s resumed");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
741 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
742 /* case RP_DISCARD: */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
743 default:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
744 mesg = (char_u *)_("%s discarded");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
745 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
746 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
747
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
748 switch (pending)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
749 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
750 case CSTP_NONE:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
751 return;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
752
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
753 case CSTP_CONTINUE:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
754 s = ":continue";
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
755 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
756 case CSTP_BREAK:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
757 s = ":break";
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
758 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
759 case CSTP_FINISH:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
760 s = ":finish";
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
761 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
762 case CSTP_RETURN:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
763 /* ":return" command producing value, allocated */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
764 s = (char *)get_return_cmd(value);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
765 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
766
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
767 default:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
768 if (pending & CSTP_THROW)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
769 {
273
2463194c8cdd updated for version 7.0073
vimboss
parents: 114
diff changeset
770 vim_snprintf((char *)IObuff, IOSIZE,
2463194c8cdd updated for version 7.0073
vimboss
parents: 114
diff changeset
771 (char *)mesg, _("Exception"));
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
772 mesg = vim_strnsave(IObuff, (int)STRLEN(IObuff) + 4);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
773 STRCAT(mesg, ": %s");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
774 s = (char *)((except_T *)value)->value;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
775 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
776 else if ((pending & CSTP_ERROR) && (pending & CSTP_INTERRUPT))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
777 s = _("Error and interrupt");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
778 else if (pending & CSTP_ERROR)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
779 s = _("Error");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
780 else /* if (pending & CSTP_INTERRUPT) */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
781 s = _("Interrupt");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
782 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
783
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
784 save_msg_silent = msg_silent;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
785 if (debug_break_level > 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
786 msg_silent = FALSE; /* display messages */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
787 ++no_wait_return;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
788 msg_scroll = TRUE; /* always scroll up, don't overwrite */
273
2463194c8cdd updated for version 7.0073
vimboss
parents: 114
diff changeset
789 smsg(mesg, (char_u *)s);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
790 msg_puts((char_u *)"\n"); /* don't overwrite this either */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
791 cmdline_row = msg_row;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
792 --no_wait_return;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
793 if (debug_break_level > 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
794 msg_silent = save_msg_silent;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
795
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
796 if (pending == CSTP_RETURN)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
797 vim_free(s);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
798 else if (pending & CSTP_THROW)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
799 vim_free(mesg);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
800 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
801
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
802 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
803 * If something is made pending in a finally clause, report it if required by
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
804 * the 'verbose' option or when debugging.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
805 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
806 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
807 report_make_pending(pending, value)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
808 int pending;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
809 void *value;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
810 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
811 if (p_verbose >= 14 || debug_break_level > 0)
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
812 {
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
813 if (debug_break_level <= 0)
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
814 verbose_enter();
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
815 report_pending(RP_MAKE, pending, value);
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
816 if (debug_break_level <= 0)
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
817 verbose_leave();
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
818 }
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
819 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
820
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
821 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
822 * If something pending in a finally clause is resumed at the ":endtry", report
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
823 * it if required by the 'verbose' option or when debugging.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
824 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
825 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
826 report_resume_pending(pending, value)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
827 int pending;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
828 void *value;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
829 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
830 if (p_verbose >= 14 || debug_break_level > 0)
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
831 {
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
832 if (debug_break_level <= 0)
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
833 verbose_enter();
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
834 report_pending(RP_RESUME, pending, value);
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
835 if (debug_break_level <= 0)
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
836 verbose_leave();
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
837 }
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
838 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
839
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
840 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
841 * If something pending in a finally clause is discarded, report it if required
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
842 * by the 'verbose' option or when debugging.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
843 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
844 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
845 report_discard_pending(pending, value)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
846 int pending;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
847 void *value;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
848 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
849 if (p_verbose >= 14 || debug_break_level > 0)
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
850 {
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
851 if (debug_break_level <= 0)
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
852 verbose_enter();
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
853 report_pending(RP_DISCARD, pending, value);
293
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
854 if (debug_break_level <= 0)
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
855 verbose_leave();
f811be6fa9b5 updated for version 7.0077
vimboss
parents: 273
diff changeset
856 }
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
857 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
858
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
859
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
860 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
861 * ":if".
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
862 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
863 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
864 ex_if(eap)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
865 exarg_T *eap;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
866 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
867 int error;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
868 int skip;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
869 int result;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
870 struct condstack *cstack = eap->cstack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
871
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
872 if (cstack->cs_idx == CSTACK_LEN - 1)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
873 eap->errmsg = (char_u *)N_("E579: :if nesting too deep");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
874 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
875 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
876 ++cstack->cs_idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
877 cstack->cs_flags[cstack->cs_idx] = 0;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
878
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
879 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
880 * Don't do something after an error, interrupt, or throw, or when there
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
881 * is a surrounding conditional and it was not active.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
882 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
883 skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
884 && !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
885
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
886 result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
887
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
888 if (!skip && !error)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
889 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
890 if (result)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
891 cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE | CSF_TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
892 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
893 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
894 /* set TRUE, so this conditional will never get active */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
895 cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
896 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
897 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
898
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
899 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
900 * ":endif".
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
901 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
902 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
903 ex_endif(eap)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
904 exarg_T *eap;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
905 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
906 did_endif = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
907 if (eap->cstack->cs_idx < 0
79
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
908 || (eap->cstack->cs_flags[eap->cstack->cs_idx]
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
909 & (CSF_WHILE | CSF_FOR | CSF_TRY)))
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
910 eap->errmsg = (char_u *)N_("E580: :endif without :if");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
911 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
912 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
913 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
914 * When debugging or a breakpoint was encountered, display the debug
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
915 * prompt (if not already done). This shows the user that an ":endif"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
916 * is executed when the ":if" or a previous ":elseif" was not TRUE.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
917 * Handle a ">quit" debug command as if an interrupt had occurred before
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
918 * the ":endif". That is, throw an interrupt exception if appropriate.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
919 * Doing this here prevents an exception for a parsing error being
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
920 * discarded by throwing the interrupt exception later on.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
921 */
359
6c62b9b939bd updated for version 7.0093
vimboss
parents: 293
diff changeset
922 if (!(eap->cstack->cs_flags[eap->cstack->cs_idx] & CSF_TRUE)
6c62b9b939bd updated for version 7.0093
vimboss
parents: 293
diff changeset
923 && dbg_check_skipped(eap))
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
924 (void)do_intthrow(eap->cstack);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
925
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
926 --eap->cstack->cs_idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
927 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
928 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
929
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
930 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
931 * ":else" and ":elseif".
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
932 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
933 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
934 ex_else(eap)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
935 exarg_T *eap;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
936 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
937 int error;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
938 int skip;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
939 int result;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
940 struct condstack *cstack = eap->cstack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
941
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
942 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
943 * Don't do something after an error, interrupt, or throw, or when there is
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
944 * a surrounding conditional and it was not active.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
945 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
946 skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
947 && !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
948
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
949 if (cstack->cs_idx < 0
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
950 || (cstack->cs_flags[cstack->cs_idx]
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
951 & (CSF_WHILE | CSF_FOR | CSF_TRY)))
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
952 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
953 if (eap->cmdidx == CMD_else)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
954 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
955 eap->errmsg = (char_u *)N_("E581: :else without :if");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
956 return;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
957 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
958 eap->errmsg = (char_u *)N_("E582: :elseif without :if");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
959 skip = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
960 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
961 else if (cstack->cs_flags[cstack->cs_idx] & CSF_ELSE)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
962 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
963 if (eap->cmdidx == CMD_else)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
964 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
965 eap->errmsg = (char_u *)N_("E583: multiple :else");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
966 return;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
967 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
968 eap->errmsg = (char_u *)N_("E584: :elseif after :else");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
969 skip = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
970 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
971
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
972 /* if skipping or the ":if" was TRUE, reset ACTIVE, otherwise set it */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
973 if (skip || cstack->cs_flags[cstack->cs_idx] & CSF_TRUE)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
974 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
975 if (eap->errmsg == NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
976 cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
977 skip = TRUE; /* don't evaluate an ":elseif" */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
978 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
979 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
980 cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
981
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
982 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
983 * When debugging or a breakpoint was encountered, display the debug prompt
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
984 * (if not already done). This shows the user that an ":else" or ":elseif"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
985 * is executed when the ":if" or previous ":elseif" was not TRUE. Handle
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
986 * a ">quit" debug command as if an interrupt had occurred before the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
987 * ":else" or ":elseif". That is, set "skip" and throw an interrupt
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
988 * exception if appropriate. Doing this here prevents that an exception
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
989 * for a parsing errors is discarded when throwing the interrupt exception
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
990 * later on.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
991 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
992 if (!skip && dbg_check_skipped(eap) && got_int)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
993 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
994 (void)do_intthrow(cstack);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
995 skip = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
996 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
997
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
998 if (eap->cmdidx == CMD_elseif)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
999 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1000 result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1001 /* When throwing error exceptions, we want to throw always the first
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1002 * of several errors in a row. This is what actually happens when
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1003 * a conditional error was detected above and there is another failure
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1004 * when parsing the expression. Since the skip flag is set in this
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1005 * case, the parsing error will be ignored by emsg(). */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1006
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1007 if (!skip && !error)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1008 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1009 if (result)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1010 cstack->cs_flags[cstack->cs_idx] = CSF_ACTIVE | CSF_TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1011 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1012 cstack->cs_flags[cstack->cs_idx] = 0;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1013 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1014 else if (eap->errmsg == NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1015 /* set TRUE, so this conditional will never get active */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1016 cstack->cs_flags[cstack->cs_idx] = CSF_TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1017 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1018 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1019 cstack->cs_flags[cstack->cs_idx] |= CSF_ELSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1020 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1021
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1022 /*
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1023 * Handle ":while" and ":for".
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1024 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1025 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1026 ex_while(eap)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1027 exarg_T *eap;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1028 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1029 int error;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1030 int skip;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1031 int result;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1032 struct condstack *cstack = eap->cstack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1033
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1034 if (cstack->cs_idx == CSTACK_LEN - 1)
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1035 eap->errmsg = (char_u *)N_("E585: :while/:for nesting too deep");
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1036 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1037 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1038 /*
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1039 * The loop flag is set when we have jumped back from the matching
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1040 * ":endwhile" or ":endfor". When not set, need to initialise this
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1041 * cstack entry.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1042 */
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1043 if ((cstack->cs_lflags & CSL_HAD_LOOP) == 0)
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1044 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1045 ++cstack->cs_idx;
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1046 ++cstack->cs_looplevel;
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1047 cstack->cs_line[cstack->cs_idx] = -1;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1048 }
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1049 cstack->cs_flags[cstack->cs_idx] =
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1050 eap->cmdidx == CMD_while ? CSF_WHILE : CSF_FOR;
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1051
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1052 /*
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1053 * Don't do something after an error, interrupt, or throw, or when
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1054 * there is a surrounding conditional and it was not active.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1055 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1056 skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1057 && !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE));
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1058 if (eap->cmdidx == CMD_while)
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1059 {
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1060 /*
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1061 * ":while bool-expr"
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1062 */
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1063 result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1064 }
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1065 else
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1066 {
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1067 void *fi;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1068
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1069 /*
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1070 * ":for var in list-expr"
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1071 */
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1072 if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0)
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1073 {
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1074 /* Jumping here from a ":continue" or ":endfor": use the
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1075 * previously evaluated list. */
79
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
1076 fi = cstack->cs_forinfo[cstack->cs_idx];
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1077 error = FALSE;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1078 }
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1079 else
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1080 {
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1081 /* Evaluate the argument and get the info in a structure. */
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1082 fi = eval_for_line(eap->arg, &error, &eap->nextcmd, skip);
79
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
1083 cstack->cs_forinfo[cstack->cs_idx] = fi;
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1084 }
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1085
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1086 /* use the element at the start of the list and advance */
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1087 if (!error && fi != NULL && !skip)
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1088 result = next_for_item(fi, eap->arg);
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1089 else
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1090 result = FALSE;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1091
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1092 if (!result)
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1093 {
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1094 free_for_info(fi);
79
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
1095 cstack->cs_forinfo[cstack->cs_idx] = NULL;
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1096 }
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1097 }
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1098
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1099 /*
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1100 * If this cstack entry was just initialised and is active, set the
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1101 * loop flag, so do_cmdline() will set the line number in cs_line[].
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1102 * If executing the command a second time, clear the loop flag.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1103 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1104 if (!skip && !error && result)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1105 {
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1106 cstack->cs_flags[cstack->cs_idx] |= (CSF_ACTIVE | CSF_TRUE);
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1107 cstack->cs_lflags ^= CSL_HAD_LOOP;
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1108 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1109 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1110 {
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1111 cstack->cs_lflags &= ~CSL_HAD_LOOP;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1112 /* If the ":while" evaluates to FALSE or ":for" is past the end of
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1113 * the list, show the debug prompt at the ":endwhile"/":endfor" as
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1114 * if there was a ":break" in a ":while"/":for" evaluating to
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1115 * TRUE. */
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1116 if (!skip && !error)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1117 cstack->cs_flags[cstack->cs_idx] |= CSF_TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1118 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1119 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1120 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1121
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1122 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1123 * ":continue"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1124 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1125 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1126 ex_continue(eap)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1127 exarg_T *eap;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1128 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1129 int idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1130 struct condstack *cstack = eap->cstack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1131
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1132 if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1133 eap->errmsg = (char_u *)N_("E586: :continue without :while or :for");
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1134 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1135 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1136 /* Try to find the matching ":while". This might stop at a try
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1137 * conditional not in its finally clause (which is then to be executed
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1138 * next). Therefor, inactivate all conditionals except the ":while"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1139 * itself (if reached). */
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1140 idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE);
840
2c885fab04e3 updated for version 7.0e06
vimboss
parents: 839
diff changeset
1141 if (idx >= 0 && (cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR)))
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1142 {
79
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
1143 rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1144
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1145 /*
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1146 * Set CSL_HAD_CONT, so do_cmdline() will jump back to the
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1147 * matching ":while".
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1148 */
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1149 cstack->cs_lflags |= CSL_HAD_CONT; /* let do_cmdline() handle it */
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1150 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1151 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1152 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1153 /* If a try conditional not in its finally clause is reached first,
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1154 * make the ":continue" pending for execution at the ":endtry". */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1155 cstack->cs_pending[idx] = CSTP_CONTINUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1156 report_make_pending(CSTP_CONTINUE, NULL);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1157 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1158 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1159 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1160
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1161 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1162 * ":break"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1163 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1164 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1165 ex_break(eap)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1166 exarg_T *eap;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1167 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1168 int idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1169 struct condstack *cstack = eap->cstack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1170
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1171 if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1172 eap->errmsg = (char_u *)N_("E587: :break without :while or :for");
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1173 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1174 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1175 /* Inactivate conditionals until the matching ":while" or a try
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1176 * conditional not in its finally clause (which is then to be
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1177 * executed next) is found. In the latter case, make the ":break"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1178 * pending for execution at the ":endtry". */
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1179 idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, TRUE);
840
2c885fab04e3 updated for version 7.0e06
vimboss
parents: 839
diff changeset
1180 if (idx >= 0 && !(cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR)))
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1181 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1182 cstack->cs_pending[idx] = CSTP_BREAK;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1183 report_make_pending(CSTP_BREAK, NULL);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1184 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1185 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1186 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1187
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1188 /*
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1189 * ":endwhile" and ":endfor"
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1190 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1191 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1192 ex_endwhile(eap)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1193 exarg_T *eap;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1194 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1195 struct condstack *cstack = eap->cstack;
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1196 int idx;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1197 char_u *err;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1198 int csf;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1199 int fl;
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1200
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1201 if (eap->cmdidx == CMD_endwhile)
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1202 {
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1203 err = e_while;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1204 csf = CSF_WHILE;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1205 }
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1206 else
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1207 {
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1208 err = e_for;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1209 csf = CSF_FOR;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1210 }
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1211
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1212 if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1213 eap->errmsg = err;
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1214 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1215 {
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1216 fl = cstack->cs_flags[cstack->cs_idx];
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1217 if (!(fl & csf))
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1218 {
114
f6e567606d47 updated for version 7.0041
vimboss
parents: 79
diff changeset
1219 /* If we are in a ":while" or ":for" but used the wrong endloop
f6e567606d47 updated for version 7.0041
vimboss
parents: 79
diff changeset
1220 * command, do not rewind to the next enclosing ":for"/":while". */
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1221 if (fl & CSF_WHILE)
114
f6e567606d47 updated for version 7.0041
vimboss
parents: 79
diff changeset
1222 eap->errmsg = (char_u *)_("E732: Using :endfor with :while");
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1223 else if (fl & CSF_FOR)
114
f6e567606d47 updated for version 7.0041
vimboss
parents: 79
diff changeset
1224 eap->errmsg = (char_u *)_("E733: Using :endwhile with :for");
f6e567606d47 updated for version 7.0041
vimboss
parents: 79
diff changeset
1225 }
f6e567606d47 updated for version 7.0041
vimboss
parents: 79
diff changeset
1226 if (!(fl & (CSF_WHILE | CSF_FOR)))
f6e567606d47 updated for version 7.0041
vimboss
parents: 79
diff changeset
1227 {
f6e567606d47 updated for version 7.0041
vimboss
parents: 79
diff changeset
1228 if (!(fl & CSF_TRY))
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1229 eap->errmsg = e_endif;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1230 else if (fl & CSF_FINALLY)
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1231 eap->errmsg = e_endtry;
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1232 /* Try to find the matching ":while" and report what's missing. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1233 for (idx = cstack->cs_idx; idx > 0; --idx)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1234 {
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1235 fl = cstack->cs_flags[idx];
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1236 if ((fl & CSF_TRY) && !(fl & CSF_FINALLY))
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1237 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1238 /* Give up at a try conditional not in its finally clause.
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1239 * Ignore the ":endwhile"/":endfor". */
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1240 eap->errmsg = err;
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1241 return;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1242 }
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1243 if (fl & csf)
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1244 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1245 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1246 /* Cleanup and rewind all contained (and unclosed) conditionals. */
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1247 (void)cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1248 rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1249 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1250
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1251 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1252 * When debugging or a breakpoint was encountered, display the debug
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1253 * prompt (if not already done). This shows the user that an
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1254 * ":endwhile"/":endfor" is executed when the ":while" was not TRUE or
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1255 * after a ":break". Handle a ">quit" debug command as if an
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1256 * interrupt had occurred before the ":endwhile"/":endfor". That is,
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1257 * throw an interrupt exception if appropriate. Doing this here
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1258 * prevents that an exception for a parsing error is discarded when
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1259 * throwing the interrupt exception later on.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1260 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1261 else if (cstack->cs_flags[cstack->cs_idx] & CSF_TRUE
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1262 && !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1263 && dbg_check_skipped(eap))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1264 (void)do_intthrow(cstack);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1265
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1266 /*
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1267 * Set loop flag, so do_cmdline() will jump back to the matching
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1268 * ":while" or ":for".
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1269 */
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1270 cstack->cs_lflags |= CSL_HAD_ENDLOOP;
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1271 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1272 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1273
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1274
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1275 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1276 * ":throw expr"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1277 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1278 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1279 ex_throw(eap)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1280 exarg_T *eap;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1281 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1282 char_u *arg = eap->arg;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1283 char_u *value;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1284
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1285 if (*arg != NUL && *arg != '|' && *arg != '\n')
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1286 value = eval_to_string_skip(arg, &eap->nextcmd, eap->skip);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1287 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1288 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1289 EMSG(_(e_argreq));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1290 value = NULL;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1291 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1292
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1293 /* On error or when an exception is thrown during argument evaluation, do
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1294 * not throw. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1295 if (!eap->skip && value != NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1296 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1297 if (throw_exception(value, ET_USER, NULL) == FAIL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1298 vim_free(value);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1299 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1300 do_throw(eap->cstack);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1301 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1302 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1303
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1304 /*
21
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1305 * Throw the current exception through the specified cstack. Common routine
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1306 * for ":throw" (user exception) and error and interrupt exceptions. Also
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1307 * used for rethrowing an uncaught exception.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1308 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1309 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1310 do_throw(cstack)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1311 struct condstack *cstack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1312 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1313 int idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1314 int inactivate_try = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1315
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1316 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1317 * Cleanup and inactivate up to the next surrounding try conditional that
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1318 * is not in its finally clause. Normally, do not inactivate the try
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1319 * conditional itself, so that its ACTIVE flag can be tested below. But
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1320 * if a previous error or interrupt has not been converted to an exception,
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1321 * inactivate the try conditional, too, as if the conversion had been done,
21
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1322 * and reset the did_emsg or got_int flag, so this won't happen again at
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1323 * the next surrounding try conditional.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1324 */
1880
e5602d92da8c updated for version 7.2-177
vimboss
parents: 1447
diff changeset
1325 #ifndef THROW_ON_ERROR_TRUE
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1326 if (did_emsg && !THROW_ON_ERROR)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1327 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1328 inactivate_try = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1329 did_emsg = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1330 }
1880
e5602d92da8c updated for version 7.2-177
vimboss
parents: 1447
diff changeset
1331 #endif
e5602d92da8c updated for version 7.2-177
vimboss
parents: 1447
diff changeset
1332 #ifndef THROW_ON_INTERRUPT_TRUE
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1333 if (got_int && !THROW_ON_INTERRUPT)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1334 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1335 inactivate_try = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1336 got_int = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1337 }
1880
e5602d92da8c updated for version 7.2-177
vimboss
parents: 1447
diff changeset
1338 #endif
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1339 idx = cleanup_conditionals(cstack, 0, inactivate_try);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1340 if (idx >= 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1341 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1342 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1343 * If this try conditional is active and we are before its first
21
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1344 * ":catch", set THROWN so that the ":catch" commands will check
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1345 * whether the exception matches. When the exception came from any of
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1346 * the catch clauses, it will be made pending at the ":finally" (if
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1347 * present) and rethrown at the ":endtry". This will also happen if
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1348 * the try conditional is inactive. This is the case when we are
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1349 * throwing an exception due to an error or interrupt on the way from
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1350 * a preceding ":continue", ":break", ":return", ":finish", error or
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1351 * interrupt (not converted to an exception) to the finally clause or
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1352 * from a preceding throw of a user or error or interrupt exception to
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1353 * the matching catch clause or the finally clause.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1354 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1355 if (!(cstack->cs_flags[idx] & CSF_CAUGHT))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1356 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1357 if (cstack->cs_flags[idx] & CSF_ACTIVE)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1358 cstack->cs_flags[idx] |= CSF_THROWN;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1359 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1360 /* THROWN may have already been set for a catchable exception
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1361 * that has been discarded. Ensure it is reset for the new
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1362 * exception. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1363 cstack->cs_flags[idx] &= ~CSF_THROWN;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1364 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1365 cstack->cs_flags[idx] &= ~CSF_ACTIVE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1366 cstack->cs_exception[idx] = current_exception;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1367 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1368 #if 0
21
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1369 /* TODO: Add optimization below. Not yet done because of interface
db5102f7e29f updated for version 7.0013
vimboss
parents: 7
diff changeset
1370 * problems to eval.c and ex_cmds2.c. (Servatius) */
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1371 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1372 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1373 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1374 * There are no catch clauses to check or finally clauses to execute.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1375 * End the current script or function. The exception will be rethrown
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1376 * in the caller.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1377 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1378 if (getline_equal(eap->getline, eap->cookie, get_func_line))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1379 current_funccal->returned = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1380 elseif (eap->get_func_line == getsourceline)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1381 ((struct source_cookie *)eap->cookie)->finished = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1382 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1383 #endif
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1384
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1385 did_throw = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1386 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1387
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1388 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1389 * ":try"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1390 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1391 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1392 ex_try(eap)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1393 exarg_T *eap;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1394 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1395 int skip;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1396 struct condstack *cstack = eap->cstack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1397
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1398 if (cstack->cs_idx == CSTACK_LEN - 1)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1399 eap->errmsg = (char_u *)N_("E601: :try nesting too deep");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1400 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1401 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1402 ++cstack->cs_idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1403 ++cstack->cs_trylevel;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1404 cstack->cs_flags[cstack->cs_idx] = CSF_TRY;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1405 cstack->cs_pending[cstack->cs_idx] = CSTP_NONE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1406
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1407 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1408 * Don't do something after an error, interrupt, or throw, or when there
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1409 * is a surrounding conditional and it was not active.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1410 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1411 skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1412 && !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1413
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1414 if (!skip)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1415 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1416 /* Set ACTIVE and TRUE. TRUE means that the corresponding ":catch"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1417 * commands should check for a match if an exception is thrown and
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1418 * that the finally clause needs to be executed. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1419 cstack->cs_flags[cstack->cs_idx] |= CSF_ACTIVE | CSF_TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1420
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1421 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1422 * ":silent!", even when used in a try conditional, disables
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1423 * displaying of error messages and conversion of errors to
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1424 * exceptions. When the silent commands again open a try
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1425 * conditional, save "emsg_silent" and reset it so that errors are
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1426 * again converted to exceptions. The value is restored when that
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1427 * try conditional is left. If it is left normally, the commands
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1428 * following the ":endtry" are again silent. If it is left by
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1429 * a ":continue", ":break", ":return", or ":finish", the commands
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1430 * executed next are again silent. If it is left due to an
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1431 * aborting error, an interrupt, or an exception, restoring
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1432 * "emsg_silent" does not matter since we are already in the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1433 * aborting state and/or the exception has already been thrown.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1434 * The effect is then just freeing the memory that was allocated
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1435 * to save the value.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1436 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1437 if (emsg_silent)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1438 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1439 eslist_T *elem;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1440
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1441 elem = (eslist_T *)alloc((unsigned)sizeof(struct eslist_elem));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1442 if (elem == NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1443 EMSG(_(e_outofmem));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1444 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1445 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1446 elem->saved_emsg_silent = emsg_silent;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1447 elem->next = cstack->cs_emsg_silent_list;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1448 cstack->cs_emsg_silent_list = elem;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1449 cstack->cs_flags[cstack->cs_idx] |= CSF_SILENT;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1450 emsg_silent = 0;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1451 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1452 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1453 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1454
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1455 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1456 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1457
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1458 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1459 * ":catch /{pattern}/" and ":catch"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1460 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1461 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1462 ex_catch(eap)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1463 exarg_T *eap;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1464 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1465 int idx = 0;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1466 int give_up = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1467 int skip = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1468 int caught = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1469 char_u *end;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1470 int save_char = 0;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1471 char_u *save_cpo;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1472 regmatch_T regmatch;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1473 int prev_got_int;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1474 struct condstack *cstack = eap->cstack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1475 char_u *pat;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1476
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1477 if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1478 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1479 eap->errmsg = (char_u *)N_("E603: :catch without :try");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1480 give_up = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1481 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1482 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1483 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1484 if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1485 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1486 /* Report what's missing if the matching ":try" is not in its
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1487 * finally clause. */
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1488 eap->errmsg = get_end_emsg(cstack);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1489 skip = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1490 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1491 for (idx = cstack->cs_idx; idx > 0; --idx)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1492 if (cstack->cs_flags[idx] & CSF_TRY)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1493 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1494 if (cstack->cs_flags[idx] & CSF_FINALLY)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1495 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1496 /* Give up for a ":catch" after ":finally" and ignore it.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1497 * Just parse. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1498 eap->errmsg = (char_u *)N_("E604: :catch after :finally");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1499 give_up = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1500 }
79
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
1501 else
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1502 rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1503 &cstack->cs_looplevel);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1504 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1505
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1506 if (ends_excmd(*eap->arg)) /* no argument, catch all errors */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1507 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1508 pat = (char_u *)".*";
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1509 end = NULL;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1510 eap->nextcmd = find_nextcmd(eap->arg);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1511 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1512 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1513 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1514 pat = eap->arg + 1;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1515 end = skip_regexp(pat, *eap->arg, TRUE, NULL);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1516 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1517
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1518 if (!give_up)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1519 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1520 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1521 * Don't do something when no exception has been thrown or when the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1522 * corresponding try block never got active (because of an inactive
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1523 * surrounding conditional or after an error or interrupt or throw).
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1524 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1525 if (!did_throw || !(cstack->cs_flags[idx] & CSF_TRUE))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1526 skip = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1527
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1528 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1529 * Check for a match only if an exception is thrown but not caught by
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1530 * a previous ":catch". An exception that has replaced a discarded
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1531 * exception is not checked (THROWN is not set then).
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1532 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1533 if (!skip && (cstack->cs_flags[idx] & CSF_THROWN)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1534 && !(cstack->cs_flags[idx] & CSF_CAUGHT))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1535 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1536 if (end != NULL && *end != NUL && !ends_excmd(*skipwhite(end + 1)))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1537 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1538 EMSG(_(e_trailing));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1539 return;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1540 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1541
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1542 /* When debugging or a breakpoint was encountered, display the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1543 * debug prompt (if not already done) before checking for a match.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1544 * This is a helpful hint for the user when the regular expression
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1545 * matching fails. Handle a ">quit" debug command as if an
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1546 * interrupt had occurred before the ":catch". That is, discard
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1547 * the original exception, replace it by an interrupt exception,
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1548 * and don't catch it in this try block. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1549 if (!dbg_check_skipped(eap) || !do_intthrow(cstack))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1550 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1551 /* Terminate the pattern and avoid the 'l' flag in 'cpoptions'
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1552 * while compiling it. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1553 if (end != NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1554 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1555 save_char = *end;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1556 *end = NUL;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1557 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1558 save_cpo = p_cpo;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1559 p_cpo = (char_u *)"";
1333
01762f635bab updated for version 7.1-047
vimboss
parents: 1214
diff changeset
1560 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1561 regmatch.rm_ic = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1562 if (end != NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1563 *end = save_char;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1564 p_cpo = save_cpo;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1565 if (regmatch.regprog == NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1566 EMSG2(_(e_invarg2), pat);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1567 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1568 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1569 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1570 * Save the value of got_int and reset it. We don't want
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1571 * a previous interruption cancel matching, only hitting
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1572 * CTRL-C while matching should abort it.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1573 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1574 prev_got_int = got_int;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1575 got_int = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1576 caught = vim_regexec_nl(&regmatch, current_exception->value,
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1577 (colnr_T)0);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1578 got_int |= prev_got_int;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1579 vim_free(regmatch.regprog);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1580 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1581 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1582 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1583
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1584 if (caught)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1585 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1586 /* Make this ":catch" clause active and reset did_emsg, got_int,
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1587 * and did_throw. Put the exception on the caught stack. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1588 cstack->cs_flags[idx] |= CSF_ACTIVE | CSF_CAUGHT;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1589 did_emsg = got_int = did_throw = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1590 catch_exception((except_T *)cstack->cs_exception[idx]);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1591 /* It's mandatory that the current exception is stored in the cstack
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1592 * so that it can be discarded at the next ":catch", ":finally", or
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1593 * ":endtry" or when the catch clause is left by a ":continue",
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1594 * ":break", ":return", ":finish", error, interrupt, or another
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1595 * exception. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1596 if (cstack->cs_exception[cstack->cs_idx] != current_exception)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1597 EMSG(_(e_internal));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1598 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1599 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1600 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1601 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1602 * If there is a preceding catch clause and it caught the exception,
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1603 * finish the exception now. This happens also after errors except
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1604 * when this ":catch" was after the ":finally" or not within
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1605 * a ":try". Make the try conditional inactive so that the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1606 * following catch clauses are skipped. On an error or interrupt
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1607 * after the preceding try block or catch clause was left by
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1608 * a ":continue", ":break", ":return", or ":finish", discard the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1609 * pending action.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1610 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1611 cleanup_conditionals(cstack, CSF_TRY, TRUE);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1612 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1613 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1614
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1615 if (end != NULL)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1616 eap->nextcmd = find_nextcmd(end);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1617 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1618
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1619 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1620 * ":finally"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1621 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1622 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1623 ex_finally(eap)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1624 exarg_T *eap;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1625 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1626 int idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1627 int skip = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1628 int pending = CSTP_NONE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1629 struct condstack *cstack = eap->cstack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1630
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1631 if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1632 eap->errmsg = (char_u *)N_("E606: :finally without :try");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1633 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1634 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1635 if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1636 {
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1637 eap->errmsg = get_end_emsg(cstack);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1638 for (idx = cstack->cs_idx - 1; idx > 0; --idx)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1639 if (cstack->cs_flags[idx] & CSF_TRY)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1640 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1641 /* Make this error pending, so that the commands in the following
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1642 * finally clause can be executed. This overrules also a pending
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1643 * ":continue", ":break", ":return", or ":finish". */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1644 pending = CSTP_ERROR;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1645 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1646 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1647 idx = cstack->cs_idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1648
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1649 if (cstack->cs_flags[idx] & CSF_FINALLY)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1650 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1651 /* Give up for a multiple ":finally" and ignore it. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1652 eap->errmsg = (char_u *)N_("E607: multiple :finally");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1653 return;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1654 }
79
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
1655 rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1656 &cstack->cs_looplevel);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1657
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1658 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1659 * Don't do something when the corresponding try block never got active
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1660 * (because of an inactive surrounding conditional or after an error or
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1661 * interrupt or throw) or for a ":finally" without ":try" or a multiple
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1662 * ":finally". After every other error (did_emsg or the conditional
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1663 * errors detected above) or after an interrupt (got_int) or an
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1664 * exception (did_throw), the finally clause must be executed.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1665 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1666 skip = !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1667
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1668 if (!skip)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1669 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1670 /* When debugging or a breakpoint was encountered, display the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1671 * debug prompt (if not already done). The user then knows that the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1672 * finally clause is executed. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1673 if (dbg_check_skipped(eap))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1674 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1675 /* Handle a ">quit" debug command as if an interrupt had
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1676 * occurred before the ":finally". That is, discard the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1677 * original exception and replace it by an interrupt
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1678 * exception. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1679 (void)do_intthrow(cstack);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1680 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1681
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1682 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1683 * If there is a preceding catch clause and it caught the exception,
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1684 * finish the exception now. This happens also after errors except
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1685 * when this is a multiple ":finally" or one not within a ":try".
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1686 * After an error or interrupt, this also discards a pending
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1687 * ":continue", ":break", ":finish", or ":return" from the preceding
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1688 * try block or catch clause.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1689 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1690 cleanup_conditionals(cstack, CSF_TRY, FALSE);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1691
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1692 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1693 * Make did_emsg, got_int, did_throw pending. If set, they overrule
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1694 * a pending ":continue", ":break", ":return", or ":finish". Then
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1695 * we have particularly to discard a pending return value (as done
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1696 * by the call to cleanup_conditionals() above when did_emsg or
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1697 * got_int is set). The pending values are restored by the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1698 * ":endtry", except if there is a new error, interrupt, exception,
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1699 * ":continue", ":break", ":return", or ":finish" in the following
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1700 * finally clause. A missing ":endwhile", ":endfor" or ":endif"
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1701 * detected here is treated as if did_emsg and did_throw had
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1702 * already been set, respectively in case that the error is not
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1703 * converted to an exception, did_throw had already been unset.
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1704 * We must not set did_emsg here since that would suppress the
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1705 * error message.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1706 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1707 if (pending == CSTP_ERROR || did_emsg || got_int || did_throw)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1708 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1709 if (cstack->cs_pending[cstack->cs_idx] == CSTP_RETURN)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1710 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1711 report_discard_pending(CSTP_RETURN,
68
a97c6902ecd9 updated for version 7.0030
vimboss
parents: 36
diff changeset
1712 cstack->cs_rettv[cstack->cs_idx]);
a97c6902ecd9 updated for version 7.0030
vimboss
parents: 36
diff changeset
1713 discard_pending_return(cstack->cs_rettv[cstack->cs_idx]);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1714 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1715 if (pending == CSTP_ERROR && !did_emsg)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1716 pending |= (THROW_ON_ERROR) ? CSTP_THROW : 0;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1717 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1718 pending |= did_throw ? CSTP_THROW : 0;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1719 pending |= did_emsg ? CSTP_ERROR : 0;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1720 pending |= got_int ? CSTP_INTERRUPT : 0;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1721 cstack->cs_pending[cstack->cs_idx] = pending;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1722
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1723 /* It's mandatory that the current exception is stored in the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1724 * cstack so that it can be rethrown at the ":endtry" or be
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1725 * discarded if the finally clause is left by a ":continue",
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1726 * ":break", ":return", ":finish", error, interrupt, or another
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1727 * exception. When emsg() is called for a missing ":endif" or
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1728 * a missing ":endwhile"/":endfor" detected here, the
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1729 * exception will be discarded. */
79
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
1730 if (did_throw && cstack->cs_exception[cstack->cs_idx]
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
1731 != current_exception)
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1732 EMSG(_(e_internal));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1733 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1734
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1735 /*
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1736 * Set CSL_HAD_FINA, so do_cmdline() will reset did_emsg,
22
cc049b00ee70 updated for version 7.0014
vimboss
parents: 21
diff changeset
1737 * got_int, and did_throw and make the finally clause active.
cc049b00ee70 updated for version 7.0014
vimboss
parents: 21
diff changeset
1738 * This will happen after emsg() has been called for a missing
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1739 * ":endif" or a missing ":endwhile"/":endfor" detected here, so
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1740 * that the following finally clause will be executed even then.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1741 */
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1742 cstack->cs_lflags |= CSL_HAD_FINA;
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1743 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1744 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1745 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1746
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1747 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1748 * ":endtry"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1749 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1750 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1751 ex_endtry(eap)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1752 exarg_T *eap;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1753 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1754 int idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1755 int skip;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1756 int rethrow = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1757 int pending = CSTP_NONE;
68
a97c6902ecd9 updated for version 7.0030
vimboss
parents: 36
diff changeset
1758 void *rettv = NULL;
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1759 struct condstack *cstack = eap->cstack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1760
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1761 if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1762 eap->errmsg = (char_u *)N_("E602: :endtry without :try");
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1763 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1764 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1765 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1766 * Don't do something after an error, interrupt or throw in the try
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1767 * block, catch clause, or finally clause preceding this ":endtry" or
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1768 * when an error or interrupt occurred after a ":continue", ":break",
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1769 * ":return", or ":finish" in a try block or catch clause preceding this
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1770 * ":endtry" or when the try block never got active (because of an
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1771 * inactive surrounding conditional or after an error or interrupt or
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1772 * throw) or when there is a surrounding conditional and it has been
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1773 * made inactive by a ":continue", ":break", ":return", or ":finish" in
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1774 * the finally clause. The latter case need not be tested since then
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1775 * anything pending has already been discarded. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1776 skip = did_emsg || got_int || did_throw ||
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1777 !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1778
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1779 if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1780 {
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1781 eap->errmsg = get_end_emsg(cstack);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1782 /* Find the matching ":try" and report what's missing. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1783 idx = cstack->cs_idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1784 do
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1785 --idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1786 while (idx > 0 && !(cstack->cs_flags[idx] & CSF_TRY));
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1787 rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
1788 &cstack->cs_looplevel);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1789 skip = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1790
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1791 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1792 * If an exception is being thrown, discard it to prevent it from
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1793 * being rethrown at the end of this function. It would be
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1794 * discarded by the error message, anyway. Resets did_throw.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1795 * This does not affect the script termination due to the error
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1796 * since "trylevel" is decremented after emsg() has been called.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1797 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1798 if (did_throw)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1799 discard_current_exception();
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1800 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1801 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1802 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1803 idx = cstack->cs_idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1804
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1805 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1806 * If we stopped with the exception currently being thrown at this
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1807 * try conditional since we didn't know that it doesn't have
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1808 * a finally clause, we need to rethrow it after closing the try
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1809 * conditional.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1810 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1811 if (did_throw && (cstack->cs_flags[idx] & CSF_TRUE)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1812 && !(cstack->cs_flags[idx] & CSF_FINALLY))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1813 rethrow = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1814 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1815
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1816 /* If there was no finally clause, show the user when debugging or
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1817 * a breakpoint was encountered that the end of the try conditional has
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1818 * been reached: display the debug prompt (if not already done). Do
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1819 * this on normal control flow or when an exception was thrown, but not
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1820 * on an interrupt or error not converted to an exception or when
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1821 * a ":break", ":continue", ":return", or ":finish" is pending. These
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1822 * actions are carried out immediately.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1823 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1824 if ((rethrow || (!skip
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1825 && !(cstack->cs_flags[idx] & CSF_FINALLY)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1826 && !cstack->cs_pending[idx]))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1827 && dbg_check_skipped(eap))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1828 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1829 /* Handle a ">quit" debug command as if an interrupt had occurred
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1830 * before the ":endtry". That is, throw an interrupt exception and
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1831 * set "skip" and "rethrow". */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1832 if (got_int)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1833 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1834 skip = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1835 (void)do_intthrow(cstack);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1836 /* The do_intthrow() call may have reset did_throw or
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1837 * cstack->cs_pending[idx].*/
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1838 rethrow = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1839 if (did_throw && !(cstack->cs_flags[idx] & CSF_FINALLY))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1840 rethrow = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1841 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1842 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1843
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1844 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1845 * If a ":return" is pending, we need to resume it after closing the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1846 * try conditional; remember the return value. If there was a finally
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1847 * clause making an exception pending, we need to rethrow it. Make it
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1848 * the exception currently being thrown.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1849 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1850 if (!skip)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1851 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1852 pending = cstack->cs_pending[idx];
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1853 cstack->cs_pending[idx] = CSTP_NONE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1854 if (pending == CSTP_RETURN)
68
a97c6902ecd9 updated for version 7.0030
vimboss
parents: 36
diff changeset
1855 rettv = cstack->cs_rettv[idx];
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1856 else if (pending & CSTP_THROW)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1857 current_exception = cstack->cs_exception[idx];
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1858 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1859
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1860 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1861 * Discard anything pending on an error, interrupt, or throw in the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1862 * finally clause. If there was no ":finally", discard a pending
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1863 * ":continue", ":break", ":return", or ":finish" if an error or
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1864 * interrupt occurred afterwards, but before the ":endtry" was reached.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1865 * If an exception was caught by the last of the catch clauses and there
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1866 * was no finally clause, finish the exception now. This happens also
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1867 * after errors except when this ":endtry" is not within a ":try".
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1868 * Restore "emsg_silent" if it has been reset by this try conditional.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1869 */
840
2c885fab04e3 updated for version 7.0e06
vimboss
parents: 839
diff changeset
1870 (void)cleanup_conditionals(cstack, CSF_TRY | CSF_SILENT, TRUE);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1871
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1872 --cstack->cs_idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1873 --cstack->cs_trylevel;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1874
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1875 if (!skip)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1876 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1877 report_resume_pending(pending,
68
a97c6902ecd9 updated for version 7.0030
vimboss
parents: 36
diff changeset
1878 (pending == CSTP_RETURN) ? rettv :
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1879 (pending & CSTP_THROW) ? (void *)current_exception : NULL);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1880 switch (pending)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1881 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1882 case CSTP_NONE:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1883 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1884
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1885 /* Reactivate a pending ":continue", ":break", ":return",
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1886 * ":finish" from the try block or a catch clause of this try
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1887 * conditional. This is skipped, if there was an error in an
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1888 * (unskipped) conditional command or an interrupt afterwards
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1889 * or if the finally clause is present and executed a new error,
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1890 * interrupt, throw, ":continue", ":break", ":return", or
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1891 * ":finish". */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1892 case CSTP_CONTINUE:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1893 ex_continue(eap);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1894 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1895 case CSTP_BREAK:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1896 ex_break(eap);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1897 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1898 case CSTP_RETURN:
68
a97c6902ecd9 updated for version 7.0030
vimboss
parents: 36
diff changeset
1899 do_return(eap, FALSE, FALSE, rettv);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1900 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1901 case CSTP_FINISH:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1902 do_finish(eap, FALSE);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1903 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1904
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1905 /* When the finally clause was entered due to an error,
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1906 * interrupt or throw (as opposed to a ":continue", ":break",
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1907 * ":return", or ":finish"), restore the pending values of
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1908 * did_emsg, got_int, and did_throw. This is skipped, if there
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1909 * was a new error, interrupt, throw, ":continue", ":break",
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1910 * ":return", or ":finish". in the finally clause. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1911 default:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1912 if (pending & CSTP_ERROR)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1913 did_emsg = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1914 if (pending & CSTP_INTERRUPT)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1915 got_int = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1916 if (pending & CSTP_THROW)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1917 rethrow = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1918 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1919 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1920 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1921
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1922 if (rethrow)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1923 /* Rethrow the current exception (within this cstack). */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1924 do_throw(cstack);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1925 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1926 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1927
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
1928 /*
36
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1929 * enter_cleanup() and leave_cleanup()
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1930 *
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1931 * Functions to be called before/after invoking a sequence of autocommands for
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1932 * cleanup for a failed command. (Failure means here that a call to emsg()
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1933 * has been made, an interrupt occurred, or there is an uncaught exception
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1934 * from a previous autocommand execution of the same command.)
24
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1935 *
36
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1936 * Call enter_cleanup() with a pointer to a cleanup_T and pass the same
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1937 * pointer to leave_cleanup(). The cleanup_T structure stores the pending
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1938 * error/interrupt/exception state.
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1939 */
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1940
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1941 /*
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1942 * This function works a bit like ex_finally() except that there was not
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1943 * actually an extra try block around the part that failed and an error or
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1944 * interrupt has not (yet) been converted to an exception. This function
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1945 * saves the error/interrupt/ exception state and prepares for the call to
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1946 * do_cmdline() that is going to be made for the cleanup autocommand
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1947 * execution.
24
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1948 */
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1949 void
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1950 enter_cleanup(csp)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1951 cleanup_T *csp;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1952 {
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1953 int pending = CSTP_NONE;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1954
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1955 /*
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1956 * Postpone did_emsg, got_int, did_throw. The pending values will be
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1957 * restored by leave_cleanup() except if there was an aborting error,
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1958 * interrupt, or uncaught exception after this function ends.
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1959 */
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1960 if (did_emsg || got_int || did_throw || need_rethrow)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1961 {
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1962 csp->pending = (did_emsg ? CSTP_ERROR : 0)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1963 | (got_int ? CSTP_INTERRUPT : 0)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1964 | (did_throw ? CSTP_THROW : 0)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1965 | (need_rethrow ? CSTP_THROW : 0);
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1966
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1967 /* If we are currently throwing an exception (did_throw), save it as
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1968 * well. On an error not yet converted to an exception, update
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1969 * "force_abort" and reset "cause_abort" (as do_errthrow() would do).
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1970 * This is needed for the do_cmdline() call that is going to be made
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1971 * for autocommand execution. We need not save *msg_list because
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1972 * there is an extra instance for every call of do_cmdline(), anyway.
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1973 */
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1974 if (did_throw || need_rethrow)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1975 csp->exception = current_exception;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1976 else
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1977 {
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1978 csp->exception = NULL;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1979 if (did_emsg)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1980 {
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1981 force_abort |= cause_abort;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1982 cause_abort = FALSE;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1983 }
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1984 }
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1985 did_emsg = got_int = did_throw = need_rethrow = FALSE;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1986
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1987 /* Report if required by the 'verbose' option or when debugging. */
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1988 report_make_pending(pending, csp->exception);
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1989 }
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1990 else
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1991 {
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1992 csp->pending = CSTP_NONE;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1993 csp->exception = NULL;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1994 }
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1995 }
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1996
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
1997 /*
36
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1998 * See comment above enter_cleanup() for how this function is used.
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
1999 *
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
2000 * This function is a bit like ex_endtry() except that there was not actually
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
2001 * an extra try block around the part that failed and an error or interrupt
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
2002 * had not (yet) been converted to an exception when the cleanup autocommand
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
2003 * sequence was invoked.
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
2004 *
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
2005 * This function has to be called with the address of the cleanup_T structure
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
2006 * filled by enter_cleanup() as an argument; it restores the error/interrupt/
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
2007 * exception state saved by that function - except there was an aborting
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
2008 * error, an interrupt or an uncaught exception during execution of the
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
2009 * cleanup autocommands. In the latter case, the saved error/interrupt/
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
2010 * exception state is discarded.
24
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2011 */
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2012 void
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2013 leave_cleanup(csp)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2014 cleanup_T *csp;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2015 {
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2016 int pending = csp->pending;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2017
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2018 if (pending == CSTP_NONE) /* nothing to do */
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2019 return;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2020
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2021 /* If there was an aborting error, an interrupt, or an uncaught exception
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2022 * after the corresponding call to enter_cleanup(), discard what has been
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2023 * made pending by it. Report this to the user if required by the
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2024 * 'verbose' option or when debugging. */
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2025 if (aborting() || need_rethrow)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2026 {
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2027 if (pending & CSTP_THROW)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2028 /* Cancel the pending exception (includes report). */
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2029 discard_exception((except_T *)csp->exception, FALSE);
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2030 else
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2031 report_discard_pending(pending, NULL);
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2032
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2033 /* If an error was about to be converted to an exception when
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2034 * enter_cleanup() was called, free the message list. */
1046
26ff011aec2d updated for version 7.0-172
vimboss
parents: 840
diff changeset
2035 if (msg_list != NULL)
26ff011aec2d updated for version 7.0-172
vimboss
parents: 840
diff changeset
2036 {
26ff011aec2d updated for version 7.0-172
vimboss
parents: 840
diff changeset
2037 free_msglist(*msg_list);
26ff011aec2d updated for version 7.0-172
vimboss
parents: 840
diff changeset
2038 *msg_list = NULL;
26ff011aec2d updated for version 7.0-172
vimboss
parents: 840
diff changeset
2039 }
24
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2040 }
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2041
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2042 /*
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2043 * If there was no new error, interrupt, or throw between the calls
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2044 * to enter_cleanup() and leave_cleanup(), restore the pending
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2045 * error/interrupt/exception state.
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2046 */
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2047 else
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2048 {
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2049 /*
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2050 * If there was an exception being thrown when enter_cleanup() was
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2051 * called, we need to rethrow it. Make it the exception currently
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2052 * being thrown.
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2053 */
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2054 if (pending & CSTP_THROW)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2055 current_exception = csp->exception;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2056
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2057 /*
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2058 * If an error was about to be converted to an exception when
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2059 * enter_cleanup() was called, let "cause_abort" take the part of
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2060 * "force_abort" (as done by cause_errthrow()).
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2061 */
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2062 else if (pending & CSTP_ERROR)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2063 {
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2064 cause_abort = force_abort;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2065 force_abort = FALSE;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2066 }
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2067
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2068 /*
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2069 * Restore the pending values of did_emsg, got_int, and did_throw.
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2070 */
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2071 if (pending & CSTP_ERROR)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2072 did_emsg = TRUE;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2073 if (pending & CSTP_INTERRUPT)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2074 got_int = TRUE;
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2075 if (pending & CSTP_THROW)
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2076 need_rethrow = TRUE; /* did_throw will be set by do_one_cmd() */
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2077
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2078 /* Report if required by the 'verbose' option or when debugging. */
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2079 report_resume_pending(pending,
36
125e80798a85 updated for version 7.0021
vimboss
parents: 24
diff changeset
2080 (pending & CSTP_THROW) ? (void *)current_exception : NULL);
24
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2081 }
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2082 }
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2083
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2084
8ff7fd162d3c updated for version 7.0016
vimboss
parents: 22
diff changeset
2085 /*
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2086 * Make conditionals inactive and discard what's pending in finally clauses
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2087 * until the conditional type searched for or a try conditional not in its
79
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
2088 * finally clause is reached. If this is in an active catch clause, finish
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
2089 * the caught exception.
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
2090 * Return the cstack index where the search stopped.
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2091 * Values used for "searched_cond" are (CSF_WHILE | CSF_FOR) or CSF_TRY or 0,
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2092 * the latter meaning the innermost try conditional not in its finally clause.
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2093 * "inclusive" tells whether the conditional searched for should be made
4352
04736b4030ec updated for version 7.3.925
Bram Moolenaar <bram@vim.org>
parents: 1880
diff changeset
2094 * inactive itself (a try conditional not in its finally clause possibly find
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2095 * before is always made inactive). If "inclusive" is TRUE and
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2096 * "searched_cond" is CSF_TRY|CSF_SILENT, the saved former value of
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2097 * "emsg_silent", if reset when the try conditional finally reached was
4352
04736b4030ec updated for version 7.3.925
Bram Moolenaar <bram@vim.org>
parents: 1880
diff changeset
2098 * entered, is restored (used by ex_endtry()). This is normally done only
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2099 * when such a try conditional is left.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2100 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2101 int
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2102 cleanup_conditionals(cstack, searched_cond, inclusive)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2103 struct condstack *cstack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2104 int searched_cond;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2105 int inclusive;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2106 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2107 int idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2108 int stop = FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2109
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2110 for (idx = cstack->cs_idx; idx >= 0; --idx)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2111 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2112 if (cstack->cs_flags[idx] & CSF_TRY)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2113 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2114 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2115 * Discard anything pending in a finally clause and continue the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2116 * search. There may also be a pending ":continue", ":break",
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2117 * ":return", or ":finish" before the finally clause. We must not
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2118 * discard it, unless an error or interrupt occurred afterwards.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2119 */
359
6c62b9b939bd updated for version 7.0093
vimboss
parents: 293
diff changeset
2120 if (did_emsg || got_int || (cstack->cs_flags[idx] & CSF_FINALLY))
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2121 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2122 switch (cstack->cs_pending[idx])
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2123 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2124 case CSTP_NONE:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2125 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2126
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2127 case CSTP_CONTINUE:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2128 case CSTP_BREAK:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2129 case CSTP_FINISH:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2130 report_discard_pending(cstack->cs_pending[idx], NULL);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2131 cstack->cs_pending[idx] = CSTP_NONE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2132 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2133
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2134 case CSTP_RETURN:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2135 report_discard_pending(CSTP_RETURN,
68
a97c6902ecd9 updated for version 7.0030
vimboss
parents: 36
diff changeset
2136 cstack->cs_rettv[idx]);
a97c6902ecd9 updated for version 7.0030
vimboss
parents: 36
diff changeset
2137 discard_pending_return(cstack->cs_rettv[idx]);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2138 cstack->cs_pending[idx] = CSTP_NONE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2139 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2140
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2141 default:
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2142 if (cstack->cs_flags[idx] & CSF_FINALLY)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2143 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2144 if (cstack->cs_pending[idx] & CSTP_THROW)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2145 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2146 /* Cancel the pending exception. This is in the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2147 * finally clause, so that the stack of the
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2148 * caught exceptions is not involved. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2149 discard_exception((except_T *)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2150 cstack->cs_exception[idx],
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2151 FALSE);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2152 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2153 else
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2154 report_discard_pending(cstack->cs_pending[idx],
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2155 NULL);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2156 cstack->cs_pending[idx] = CSTP_NONE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2157 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2158 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2159 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2160 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2161
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2162 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2163 * Stop at a try conditional not in its finally clause. If this try
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2164 * conditional is in an active catch clause, finish the caught
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2165 * exception.
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2166 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2167 if (!(cstack->cs_flags[idx] & CSF_FINALLY))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2168 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2169 if ((cstack->cs_flags[idx] & CSF_ACTIVE)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2170 && (cstack->cs_flags[idx] & CSF_CAUGHT))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2171 finish_exception((except_T *)cstack->cs_exception[idx]);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2172 /* Stop at this try conditional - except the try block never
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2173 * got active (because of an inactive surrounding conditional
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2174 * or when the ":try" appeared after an error or interrupt or
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2175 * throw). */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2176 if (cstack->cs_flags[idx] & CSF_TRUE)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2177 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2178 if (searched_cond == 0 && !inclusive)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2179 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2180 stop = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2181 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2182 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2183 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2184
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2185 /* Stop on the searched conditional type (even when the surrounding
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2186 * conditional is not active or something has been made pending).
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2187 * If "inclusive" is TRUE and "searched_cond" is CSF_TRY|CSF_SILENT,
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2188 * check first whether "emsg_silent" needs to be restored. */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2189 if (cstack->cs_flags[idx] & searched_cond)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2190 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2191 if (!inclusive)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2192 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2193 stop = TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2194 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2195 cstack->cs_flags[idx] &= ~CSF_ACTIVE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2196 if (stop && searched_cond != (CSF_TRY | CSF_SILENT))
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2197 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2198
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2199 /*
1214
a91a2e0c4108 updated for version 7.1b
vimboss
parents: 1046
diff changeset
2200 * When leaving a try conditional that reset "emsg_silent" on its
a91a2e0c4108 updated for version 7.1b
vimboss
parents: 1046
diff changeset
2201 * entry after saving the original value, restore that value here and
a91a2e0c4108 updated for version 7.1b
vimboss
parents: 1046
diff changeset
2202 * free the memory used to store it.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2203 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2204 if ((cstack->cs_flags[idx] & CSF_TRY)
359
6c62b9b939bd updated for version 7.0093
vimboss
parents: 293
diff changeset
2205 && (cstack->cs_flags[idx] & CSF_SILENT))
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2206 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2207 eslist_T *elem;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2208
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2209 elem = cstack->cs_emsg_silent_list;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2210 cstack->cs_emsg_silent_list = elem->next;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2211 emsg_silent = elem->saved_emsg_silent;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2212 vim_free(elem);
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2213 cstack->cs_flags[idx] &= ~CSF_SILENT;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2214 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2215 if (stop)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2216 break;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2217 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2218 return idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2219 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2220
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2221 /*
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2222 * Return an appropriate error message for a missing endwhile/endfor/endif.
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2223 */
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2224 static char_u *
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2225 get_end_emsg(cstack)
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2226 struct condstack *cstack;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2227 {
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2228 if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE)
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2229 return e_endwhile;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2230 if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR)
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2231 return e_endfor;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2232 return e_endif;
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2233 }
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2234
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2235
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2236 /*
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2237 * Rewind conditionals until index "idx" is reached. "cond_type" and
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2238 * "cond_level" specify a conditional type and the address of a level variable
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2239 * which is to be decremented with each skipped conditional of the specified
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2240 * type.
79
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
2241 * Also free "for info" structures where needed.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2242 */
79
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
2243 void
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2244 rewind_conditionals(cstack, idx, cond_type, cond_level)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2245 struct condstack *cstack;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2246 int idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2247 int cond_type;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2248 int *cond_level;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2249 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2250 while (cstack->cs_idx > idx)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2251 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2252 if (cstack->cs_flags[cstack->cs_idx] & cond_type)
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2253 --*cond_level;
79
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
2254 if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR)
e918d3e340a4 updated for version 7.0032
vimboss
parents: 75
diff changeset
2255 free_for_info(cstack->cs_forinfo[cstack->cs_idx]);
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2256 --cstack->cs_idx;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2257 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2258 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2259
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2260 /*
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2261 * ":endfunction" when not after a ":function"
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2262 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2263 void
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2264 ex_endfunction(eap)
1880
e5602d92da8c updated for version 7.2-177
vimboss
parents: 1447
diff changeset
2265 exarg_T *eap UNUSED;
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2266 {
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2267 EMSG(_("E193: :endfunction not inside a function"));
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2268 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2269
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2270 /*
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2271 * Return TRUE if the string "p" looks like a ":while" or ":for" command.
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2272 */
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2273 int
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2274 has_loop_cmd(p)
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2275 char_u *p;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2276 {
1447
dac5006b4443 updated for version 7.1-162
vimboss
parents: 1333
diff changeset
2277 int len;
dac5006b4443 updated for version 7.1-162
vimboss
parents: 1333
diff changeset
2278
dac5006b4443 updated for version 7.1-162
vimboss
parents: 1333
diff changeset
2279 /* skip modifiers, white space and ':' */
dac5006b4443 updated for version 7.1-162
vimboss
parents: 1333
diff changeset
2280 for (;;)
dac5006b4443 updated for version 7.1-162
vimboss
parents: 1333
diff changeset
2281 {
dac5006b4443 updated for version 7.1-162
vimboss
parents: 1333
diff changeset
2282 while (*p == ' ' || *p == '\t' || *p == ':')
dac5006b4443 updated for version 7.1-162
vimboss
parents: 1333
diff changeset
2283 ++p;
dac5006b4443 updated for version 7.1-162
vimboss
parents: 1333
diff changeset
2284 len = modifier_len(p);
dac5006b4443 updated for version 7.1-162
vimboss
parents: 1333
diff changeset
2285 if (len == 0)
dac5006b4443 updated for version 7.1-162
vimboss
parents: 1333
diff changeset
2286 break;
dac5006b4443 updated for version 7.1-162
vimboss
parents: 1333
diff changeset
2287 p += len;
dac5006b4443 updated for version 7.1-162
vimboss
parents: 1333
diff changeset
2288 }
75
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2289 if ((p[0] == 'w' && p[1] == 'h')
388f285bda1b updated for version 7.0031
vimboss
parents: 68
diff changeset
2290 || (p[0] == 'f' && p[1] == 'o' && p[2] == 'r'))
7
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2291 return TRUE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2292 return FALSE;
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2293 }
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2294
3fc0f57ecb91 updated for version 7.0001
vimboss
parents:
diff changeset
2295 #endif /* FEAT_EVAL */