comparison src/ex_eval.c @ 79:e918d3e340a4

updated for version 7.0032
author vimboss
date Thu, 06 Jan 2005 23:24:37 +0000
parents 388f285bda1b
children f6e567606d47
comparison
equal deleted inserted replaced
78:b00be47310ed 79:e918d3e340a4
16 #if defined(FEAT_EVAL) || defined(PROTO) 16 #if defined(FEAT_EVAL) || defined(PROTO)
17 17
18 static void free_msglist __ARGS((struct msglist *l)); 18 static void free_msglist __ARGS((struct msglist *l));
19 static int throw_exception __ARGS((void *, int, char_u *)); 19 static int throw_exception __ARGS((void *, int, char_u *));
20 static char_u *get_end_emsg __ARGS((struct condstack *cstack)); 20 static char_u *get_end_emsg __ARGS((struct condstack *cstack));
21 static void rewind_conditionals __ARGS((struct condstack *,
22 int, int, int *));
23 21
24 /* 22 /*
25 * Exception handling terms: 23 * Exception handling terms:
26 * 24 *
27 * :try ":try" command \ 25 * :try ":try" command \
861 ex_endif(eap) 859 ex_endif(eap)
862 exarg_T *eap; 860 exarg_T *eap;
863 { 861 {
864 did_endif = TRUE; 862 did_endif = TRUE;
865 if (eap->cstack->cs_idx < 0 863 if (eap->cstack->cs_idx < 0
866 || (eap->cstack->cs_flags[eap->cstack->cs_idx] & 864 || (eap->cstack->cs_flags[eap->cstack->cs_idx]
867 (CSF_WHILE | CSF_FOR | CSF_TRY))) 865 & (CSF_WHILE | CSF_FOR | CSF_TRY)))
868 eap->errmsg = (char_u *)N_("E580: :endif without :if"); 866 eap->errmsg = (char_u *)N_("E580: :endif without :if");
869 else 867 else
870 { 868 {
871 /* 869 /*
872 * When debugging or a breakpoint was encountered, display the debug 870 * When debugging or a breakpoint was encountered, display the debug
1029 */ 1027 */
1030 if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0) 1028 if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0)
1031 { 1029 {
1032 /* Jumping here from a ":continue" or ":endfor": use the 1030 /* Jumping here from a ":continue" or ":endfor": use the
1033 * previously evaluated list. */ 1031 * previously evaluated list. */
1034 fi = cstack->cs_fors[cstack->cs_idx]; 1032 fi = cstack->cs_forinfo[cstack->cs_idx];
1035 error = FALSE; 1033 error = FALSE;
1036 } 1034 }
1037 else 1035 else
1038 { 1036 {
1039 /* Evaluate the argument and get the info in a structure. */ 1037 /* Evaluate the argument and get the info in a structure. */
1040 fi = eval_for_line(eap->arg, &error, &eap->nextcmd, skip); 1038 fi = eval_for_line(eap->arg, &error, &eap->nextcmd, skip);
1041 cstack->cs_fors[cstack->cs_idx] = fi; 1039 cstack->cs_forinfo[cstack->cs_idx] = fi;
1042 } 1040 }
1043 1041
1044 /* use the element at the start of the list and advance */ 1042 /* use the element at the start of the list and advance */
1045 if (!error && fi != NULL && !skip) 1043 if (!error && fi != NULL && !skip)
1046 result = next_for_item(fi, eap->arg); 1044 result = next_for_item(fi, eap->arg);
1048 result = FALSE; 1046 result = FALSE;
1049 1047
1050 if (!result) 1048 if (!result)
1051 { 1049 {
1052 free_for_info(fi); 1050 free_for_info(fi);
1053 cstack->cs_fors[cstack->cs_idx] = NULL; 1051 cstack->cs_forinfo[cstack->cs_idx] = NULL;
1054 } 1052 }
1055 } 1053 }
1056 1054
1057 /* 1055 /*
1058 * If this cstack entry was just initialised and is active, set the 1056 * If this cstack entry was just initialised and is active, set the
1096 * next). Therefor, inactivate all conditionals except the ":while" 1094 * next). Therefor, inactivate all conditionals except the ":while"
1097 * itself (if reached). */ 1095 * itself (if reached). */
1098 idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE); 1096 idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE);
1099 if ((cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR))) 1097 if ((cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR)))
1100 { 1098 {
1101 if (cstack->cs_idx > idx) 1099 rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
1102 rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
1103 1100
1104 /* 1101 /*
1105 * Set CSL_HAD_CONT, so do_cmdline() will jump back to the 1102 * Set CSL_HAD_CONT, so do_cmdline() will jump back to the
1106 * matching ":while". 1103 * matching ":while".
1107 */ 1104 */
1446 /* Give up for a ":catch" after ":finally" and ignore it. 1443 /* Give up for a ":catch" after ":finally" and ignore it.
1447 * Just parse. */ 1444 * Just parse. */
1448 eap->errmsg = (char_u *)N_("E604: :catch after :finally"); 1445 eap->errmsg = (char_u *)N_("E604: :catch after :finally");
1449 give_up = TRUE; 1446 give_up = TRUE;
1450 } 1447 }
1451 else if (cstack->cs_idx > idx) 1448 else
1452 rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR, 1449 rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
1453 &cstack->cs_looplevel); 1450 &cstack->cs_looplevel);
1454 } 1451 }
1455 1452
1456 if (ends_excmd(*eap->arg)) /* no argument, catch all errors */ 1453 if (ends_excmd(*eap->arg)) /* no argument, catch all errors */
1600 { 1597 {
1601 /* Give up for a multiple ":finally" and ignore it. */ 1598 /* Give up for a multiple ":finally" and ignore it. */
1602 eap->errmsg = (char_u *)N_("E607: multiple :finally"); 1599 eap->errmsg = (char_u *)N_("E607: multiple :finally");
1603 return; 1600 return;
1604 } 1601 }
1605 if (cstack->cs_idx > idx) 1602 rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
1606 rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
1607 &cstack->cs_looplevel); 1603 &cstack->cs_looplevel);
1608 1604
1609 /* 1605 /*
1610 * Don't do something when the corresponding try block never got active 1606 * Don't do something when the corresponding try block never got active
1611 * (because of an inactive surrounding conditional or after an error or 1607 * (because of an inactive surrounding conditional or after an error or
1676 * discarded if the finally clause is left by a ":continue", 1672 * discarded if the finally clause is left by a ":continue",
1677 * ":break", ":return", ":finish", error, interrupt, or another 1673 * ":break", ":return", ":finish", error, interrupt, or another
1678 * exception. When emsg() is called for a missing ":endif" or 1674 * exception. When emsg() is called for a missing ":endif" or
1679 * a missing ":endwhile"/":endfor" detected here, the 1675 * a missing ":endwhile"/":endfor" detected here, the
1680 * exception will be discarded. */ 1676 * exception will be discarded. */
1681 if (did_throw && cstack->cs_exception[cstack->cs_idx] != 1677 if (did_throw && cstack->cs_exception[cstack->cs_idx]
1682 current_exception) 1678 != current_exception)
1683 EMSG(_(e_internal)); 1679 EMSG(_(e_internal));
1684 } 1680 }
1685 1681
1686 /* 1682 /*
1687 * Set CSL_HAD_FINA, so do_cmdline() will reset did_emsg, 1683 * Set CSL_HAD_FINA, so do_cmdline() will reset did_emsg,
2031 2027
2032 2028
2033 /* 2029 /*
2034 * Make conditionals inactive and discard what's pending in finally clauses 2030 * Make conditionals inactive and discard what's pending in finally clauses
2035 * until the conditional type searched for or a try conditional not in its 2031 * until the conditional type searched for or a try conditional not in its
2036 * finally clause is reached. If this is in an active catch clause, finish the 2032 * finally clause is reached. If this is in an active catch clause, finish
2037 * caught exception. Return the cstack index where the search stopped. 2033 * the caught exception.
2034 * Return the cstack index where the search stopped.
2038 * Values used for "searched_cond" are (CSF_WHILE | CSF_FOR) or CSF_TRY or 0, 2035 * Values used for "searched_cond" are (CSF_WHILE | CSF_FOR) or CSF_TRY or 0,
2039 * the latter meaning the innermost try conditional not in its finally clause. 2036 * the latter meaning the innermost try conditional not in its finally clause.
2040 * "inclusive" tells whether the conditional searched for should be made 2037 * "inclusive" tells whether the conditional searched for should be made
2041 * inactive itself (a try conditional not in its finally claused possibly find 2038 * inactive itself (a try conditional not in its finally claused possibly find
2042 * before is always made inactive). If "inclusive" is TRUE and 2039 * before is always made inactive). If "inclusive" is TRUE and
2184 /* 2181 /*
2185 * Rewind conditionals until index "idx" is reached. "cond_type" and 2182 * Rewind conditionals until index "idx" is reached. "cond_type" and
2186 * "cond_level" specify a conditional type and the address of a level variable 2183 * "cond_level" specify a conditional type and the address of a level variable
2187 * which is to be decremented with each skipped conditional of the specified 2184 * which is to be decremented with each skipped conditional of the specified
2188 * type. 2185 * type.
2189 */ 2186 * Also free "for info" structures where needed.
2190 static void 2187 */
2188 void
2191 rewind_conditionals(cstack, idx, cond_type, cond_level) 2189 rewind_conditionals(cstack, idx, cond_type, cond_level)
2192 struct condstack *cstack; 2190 struct condstack *cstack;
2193 int idx; 2191 int idx;
2194 int cond_type; 2192 int cond_type;
2195 int *cond_level; 2193 int *cond_level;
2196 { 2194 {
2197 while (cstack->cs_idx > idx) 2195 while (cstack->cs_idx > idx)
2198 { 2196 {
2199 if (cstack->cs_flags[cstack->cs_idx] & cond_type) 2197 if (cstack->cs_flags[cstack->cs_idx] & cond_type)
2200 --*cond_level; 2198 --*cond_level;
2199 if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR)
2200 free_for_info(cstack->cs_forinfo[cstack->cs_idx]);
2201 --cstack->cs_idx; 2201 --cstack->cs_idx;
2202 } 2202 }
2203 } 2203 }
2204 2204
2205 /* 2205 /*