Mercurial > vim
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 /* |