Mercurial > vim
comparison src/ex_eval.c @ 75:388f285bda1b
updated for version 7.0031
author | vimboss |
---|---|
date | Wed, 05 Jan 2005 22:16:17 +0000 |
parents | a97c6902ecd9 |
children | e918d3e340a4 |
comparison
equal
deleted
inserted
replaced
74:1154524da1cd | 75:388f285bda1b |
---|---|
15 | 15 |
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 void rewind_conditionals __ARGS((struct condstack *, | 21 static void rewind_conditionals __ARGS((struct condstack *, |
21 int, int, int *)); | 22 int, int, int *)); |
22 | 23 |
23 /* | 24 /* |
24 * Exception handling terms: | 25 * Exception handling terms: |
861 exarg_T *eap; | 862 exarg_T *eap; |
862 { | 863 { |
863 did_endif = TRUE; | 864 did_endif = TRUE; |
864 if (eap->cstack->cs_idx < 0 | 865 if (eap->cstack->cs_idx < 0 |
865 || (eap->cstack->cs_flags[eap->cstack->cs_idx] & | 866 || (eap->cstack->cs_flags[eap->cstack->cs_idx] & |
866 (CSF_WHILE | CSF_TRY))) | 867 (CSF_WHILE | CSF_FOR | CSF_TRY))) |
867 eap->errmsg = (char_u *)N_("E580: :endif without :if"); | 868 eap->errmsg = (char_u *)N_("E580: :endif without :if"); |
868 else | 869 else |
869 { | 870 { |
870 /* | 871 /* |
871 * When debugging or a breakpoint was encountered, display the debug | 872 * When debugging or a breakpoint was encountered, display the debug |
902 */ | 903 */ |
903 skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0 | 904 skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0 |
904 && !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE)); | 905 && !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE)); |
905 | 906 |
906 if (cstack->cs_idx < 0 | 907 if (cstack->cs_idx < 0 |
907 || (cstack->cs_flags[cstack->cs_idx] & (CSF_WHILE | CSF_TRY))) | 908 || (cstack->cs_flags[cstack->cs_idx] |
909 & (CSF_WHILE | CSF_FOR | CSF_TRY))) | |
908 { | 910 { |
909 if (eap->cmdidx == CMD_else) | 911 if (eap->cmdidx == CMD_else) |
910 { | 912 { |
911 eap->errmsg = (char_u *)N_("E581: :else without :if"); | 913 eap->errmsg = (char_u *)N_("E581: :else without :if"); |
912 return; | 914 return; |
974 else | 976 else |
975 cstack->cs_flags[cstack->cs_idx] |= CSF_ELSE; | 977 cstack->cs_flags[cstack->cs_idx] |= CSF_ELSE; |
976 } | 978 } |
977 | 979 |
978 /* | 980 /* |
979 * Handle ":while". | 981 * Handle ":while" and ":for". |
980 */ | 982 */ |
981 void | 983 void |
982 ex_while(eap) | 984 ex_while(eap) |
983 exarg_T *eap; | 985 exarg_T *eap; |
984 { | 986 { |
986 int skip; | 988 int skip; |
987 int result; | 989 int result; |
988 struct condstack *cstack = eap->cstack; | 990 struct condstack *cstack = eap->cstack; |
989 | 991 |
990 if (cstack->cs_idx == CSTACK_LEN - 1) | 992 if (cstack->cs_idx == CSTACK_LEN - 1) |
991 eap->errmsg = (char_u *)N_("E585: :while nesting too deep"); | 993 eap->errmsg = (char_u *)N_("E585: :while/:for nesting too deep"); |
992 else | 994 else |
993 { | 995 { |
994 /* | 996 /* |
995 * cs_had_while is set when we have jumped back from the matching | 997 * The loop flag is set when we have jumped back from the matching |
996 * ":endwhile". When not set, need to initialise this cstack entry. | 998 * ":endwhile" or ":endfor". When not set, need to initialise this |
997 */ | 999 * cstack entry. |
998 if (!cstack->cs_had_while) | 1000 */ |
1001 if ((cstack->cs_lflags & CSL_HAD_LOOP) == 0) | |
999 { | 1002 { |
1000 ++cstack->cs_idx; | 1003 ++cstack->cs_idx; |
1001 ++cstack->cs_whilelevel; | 1004 ++cstack->cs_looplevel; |
1002 cstack->cs_line[cstack->cs_idx] = -1; | 1005 cstack->cs_line[cstack->cs_idx] = -1; |
1003 } | 1006 } |
1004 cstack->cs_flags[cstack->cs_idx] = CSF_WHILE; | 1007 cstack->cs_flags[cstack->cs_idx] = |
1005 | 1008 eap->cmdidx == CMD_while ? CSF_WHILE : CSF_FOR; |
1006 /* | 1009 |
1007 * Don't do something after an error, interrupt, or throw, or when there | 1010 /* |
1008 * is a surrounding conditional and it was not active. | 1011 * Don't do something after an error, interrupt, or throw, or when |
1012 * there is a surrounding conditional and it was not active. | |
1009 */ | 1013 */ |
1010 skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0 | 1014 skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0 |
1011 && !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE)); | 1015 && !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE)); |
1012 result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip); | 1016 if (eap->cmdidx == CMD_while) |
1013 | 1017 { |
1014 /* | 1018 /* |
1015 * If this cstack entry was just initialised and is active, set | 1019 * ":while bool-expr" |
1016 * cs_had_while flag, so do_cmdline() will set the line number | 1020 */ |
1017 * in cs_line[]. | 1021 result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip); |
1022 } | |
1023 else | |
1024 { | |
1025 void *fi; | |
1026 | |
1027 /* | |
1028 * ":for var in list-expr" | |
1029 */ | |
1030 if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0) | |
1031 { | |
1032 /* Jumping here from a ":continue" or ":endfor": use the | |
1033 * previously evaluated list. */ | |
1034 fi = cstack->cs_fors[cstack->cs_idx]; | |
1035 error = FALSE; | |
1036 } | |
1037 else | |
1038 { | |
1039 /* Evaluate the argument and get the info in a structure. */ | |
1040 fi = eval_for_line(eap->arg, &error, &eap->nextcmd, skip); | |
1041 cstack->cs_fors[cstack->cs_idx] = fi; | |
1042 } | |
1043 | |
1044 /* use the element at the start of the list and advance */ | |
1045 if (!error && fi != NULL && !skip) | |
1046 result = next_for_item(fi, eap->arg); | |
1047 else | |
1048 result = FALSE; | |
1049 | |
1050 if (!result) | |
1051 { | |
1052 free_for_info(fi); | |
1053 cstack->cs_fors[cstack->cs_idx] = NULL; | |
1054 } | |
1055 } | |
1056 | |
1057 /* | |
1058 * If this cstack entry was just initialised and is active, set the | |
1059 * loop flag, so do_cmdline() will set the line number in cs_line[]. | |
1060 * If executing the command a second time, clear the loop flag. | |
1018 */ | 1061 */ |
1019 if (!skip && !error && result) | 1062 if (!skip && !error && result) |
1020 { | 1063 { |
1021 cstack->cs_flags[cstack->cs_idx] |= CSF_ACTIVE | CSF_TRUE; | 1064 cstack->cs_flags[cstack->cs_idx] |= (CSF_ACTIVE | CSF_TRUE); |
1022 cstack->cs_had_while = !cstack->cs_had_while; | 1065 cstack->cs_lflags ^= CSL_HAD_LOOP; |
1023 } | 1066 } |
1024 else | 1067 else |
1025 { | 1068 { |
1026 cstack->cs_had_while = FALSE; | 1069 cstack->cs_lflags &= ~CSL_HAD_LOOP; |
1027 /* If the ":while" evaluates to FALSE, show the debug prompt at the | 1070 /* If the ":while" evaluates to FALSE or ":for" is past the end of |
1028 * ":endwhile" as if there was a ":break" in a ":while" evaluating | 1071 * the list, show the debug prompt at the ":endwhile"/":endfor" as |
1029 * to TRUE. */ | 1072 * if there was a ":break" in a ":while"/":for" evaluating to |
1073 * TRUE. */ | |
1030 if (!skip && !error) | 1074 if (!skip && !error) |
1031 cstack->cs_flags[cstack->cs_idx] |= CSF_TRUE; | 1075 cstack->cs_flags[cstack->cs_idx] |= CSF_TRUE; |
1032 } | 1076 } |
1033 } | 1077 } |
1034 } | 1078 } |
1041 exarg_T *eap; | 1085 exarg_T *eap; |
1042 { | 1086 { |
1043 int idx; | 1087 int idx; |
1044 struct condstack *cstack = eap->cstack; | 1088 struct condstack *cstack = eap->cstack; |
1045 | 1089 |
1046 if (cstack->cs_whilelevel <= 0 || cstack->cs_idx < 0) | 1090 if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) |
1047 eap->errmsg = (char_u *)N_("E586: :continue without :while"); | 1091 eap->errmsg = (char_u *)N_("E586: :continue without :while or :for"); |
1048 else | 1092 else |
1049 { | 1093 { |
1050 /* Try to find the matching ":while". This might stop at a try | 1094 /* Try to find the matching ":while". This might stop at a try |
1051 * conditional not in its finally clause (which is then to be executed | 1095 * conditional not in its finally clause (which is then to be executed |
1052 * next). Therefor, inactivate all conditionals except the ":while" | 1096 * next). Therefor, inactivate all conditionals except the ":while" |
1053 * itself (if reached). */ | 1097 * itself (if reached). */ |
1054 idx = cleanup_conditionals(cstack, CSF_WHILE, FALSE); | 1098 idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE); |
1055 if ((cstack->cs_flags[idx] & CSF_WHILE)) | 1099 if ((cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR))) |
1056 { | 1100 { |
1057 if (cstack->cs_idx > idx) | 1101 if (cstack->cs_idx > idx) |
1058 rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel); | 1102 rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel); |
1059 | 1103 |
1060 /* | 1104 /* |
1061 * Set cs_had_continue, so do_cmdline() will jump back to the | 1105 * Set CSL_HAD_CONT, so do_cmdline() will jump back to the |
1062 * matching ":while". | 1106 * matching ":while". |
1063 */ | 1107 */ |
1064 cstack->cs_had_continue = TRUE; /* let do_cmdline() handle it */ | 1108 cstack->cs_lflags |= CSL_HAD_CONT; /* let do_cmdline() handle it */ |
1065 } | 1109 } |
1066 else | 1110 else |
1067 { | 1111 { |
1068 /* If a try conditional not in its finally clause is reached first, | 1112 /* If a try conditional not in its finally clause is reached first, |
1069 * make the ":continue" pending for execution at the ":endtry". */ | 1113 * make the ":continue" pending for execution at the ":endtry". */ |
1081 exarg_T *eap; | 1125 exarg_T *eap; |
1082 { | 1126 { |
1083 int idx; | 1127 int idx; |
1084 struct condstack *cstack = eap->cstack; | 1128 struct condstack *cstack = eap->cstack; |
1085 | 1129 |
1086 if (cstack->cs_whilelevel <= 0 || cstack->cs_idx < 0) | 1130 if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) |
1087 eap->errmsg = (char_u *)N_("E587: :break without :while"); | 1131 eap->errmsg = (char_u *)N_("E587: :break without :while or :for"); |
1088 else | 1132 else |
1089 { | 1133 { |
1090 /* Inactivate conditionals until the matching ":while" or a try | 1134 /* Inactivate conditionals until the matching ":while" or a try |
1091 * conditional not in its finally clause (which is then to be | 1135 * conditional not in its finally clause (which is then to be |
1092 * executed next) is found. In the latter case, make the ":break" | 1136 * executed next) is found. In the latter case, make the ":break" |
1093 * pending for execution at the ":endtry". */ | 1137 * pending for execution at the ":endtry". */ |
1094 idx = cleanup_conditionals(cstack, CSF_WHILE, TRUE); | 1138 idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, TRUE); |
1095 if (!(cstack->cs_flags[idx] & CSF_WHILE)) | 1139 if (!(cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR))) |
1096 { | 1140 { |
1097 cstack->cs_pending[idx] = CSTP_BREAK; | 1141 cstack->cs_pending[idx] = CSTP_BREAK; |
1098 report_make_pending(CSTP_BREAK, NULL); | 1142 report_make_pending(CSTP_BREAK, NULL); |
1099 } | 1143 } |
1100 } | 1144 } |
1101 } | 1145 } |
1102 | 1146 |
1103 /* | 1147 /* |
1104 * ":endwhile" | 1148 * ":endwhile" and ":endfor" |
1105 */ | 1149 */ |
1106 void | 1150 void |
1107 ex_endwhile(eap) | 1151 ex_endwhile(eap) |
1108 exarg_T *eap; | 1152 exarg_T *eap; |
1109 { | 1153 { |
1110 struct condstack *cstack = eap->cstack; | 1154 struct condstack *cstack = eap->cstack; |
1111 int idx; | 1155 int idx; |
1112 | 1156 char_u *err; |
1113 if (cstack->cs_whilelevel <= 0 || cstack->cs_idx < 0) | 1157 int csf; |
1114 eap->errmsg = e_while; | 1158 int fl; |
1115 else | 1159 |
1116 { | 1160 if (eap->cmdidx == CMD_endwhile) |
1117 if (!(cstack->cs_flags[cstack->cs_idx] & CSF_WHILE)) | 1161 { |
1118 { | 1162 err = e_while; |
1163 csf = CSF_WHILE; | |
1164 } | |
1165 else | |
1166 { | |
1167 err = e_for; | |
1168 csf = CSF_FOR; | |
1169 } | |
1170 | |
1171 if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0) | |
1172 eap->errmsg = err; | |
1173 else | |
1174 { | |
1175 fl = cstack->cs_flags[cstack->cs_idx]; | |
1176 if (!(fl & csf)) | |
1177 { | |
1178 if (fl & CSF_WHILE) | |
1179 eap->errmsg = (char_u *)_("E999: Using :endfor with :while"); | |
1180 else if (fl & CSF_FOR) | |
1181 eap->errmsg = (char_u *)_("E999: Using :endwhile with :for"); | |
1182 else if (!(fl & CSF_TRY)) | |
1183 eap->errmsg = e_endif; | |
1184 else if (fl & CSF_FINALLY) | |
1185 eap->errmsg = e_endtry; | |
1119 /* Try to find the matching ":while" and report what's missing. */ | 1186 /* Try to find the matching ":while" and report what's missing. */ |
1120 if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) | |
1121 eap->errmsg = e_endif; | |
1122 else if (cstack->cs_flags[cstack->cs_idx] & CSF_FINALLY) | |
1123 eap->errmsg = e_endtry; | |
1124 for (idx = cstack->cs_idx; idx > 0; --idx) | 1187 for (idx = cstack->cs_idx; idx > 0; --idx) |
1125 { | 1188 { |
1126 if ((cstack->cs_flags[idx] & CSF_TRY) | 1189 fl = cstack->cs_flags[idx]; |
1127 && !(cstack->cs_flags[idx] & CSF_FINALLY)) | 1190 if ((fl & CSF_TRY) && !(fl & CSF_FINALLY)) |
1128 { | 1191 { |
1129 /* Give up at a try conditional not in its finally clause. | 1192 /* Give up at a try conditional not in its finally clause. |
1130 * Ignore the ":endwhile". */ | 1193 * Ignore the ":endwhile"/":endfor". */ |
1131 eap->errmsg = e_while; | 1194 eap->errmsg = err; |
1132 return; | 1195 return; |
1133 } | 1196 } |
1134 if (cstack->cs_flags[idx] & CSF_WHILE) | 1197 if (fl & csf) |
1135 break; | 1198 break; |
1136 } | 1199 } |
1137 /* Cleanup and rewind all contained (and unclosed) conditionals. */ | 1200 /* Cleanup and rewind all contained (and unclosed) conditionals. */ |
1138 (void)cleanup_conditionals(cstack, CSF_WHILE, FALSE); | 1201 (void)cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE); |
1139 rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel); | 1202 rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel); |
1140 } | 1203 } |
1141 | 1204 |
1142 /* | 1205 /* |
1143 * When debugging or a breakpoint was encountered, display the debug | 1206 * When debugging or a breakpoint was encountered, display the debug |
1144 * prompt (if not already done). This shows the user that an | 1207 * prompt (if not already done). This shows the user that an |
1145 * ":enwhile" is executed when the ":while" was not TRUE or after | 1208 * ":endwhile"/":endfor" is executed when the ":while" was not TRUE or |
1146 * a ":break". Handle a ">quit" debug command as if an interrupt | 1209 * after a ":break". Handle a ">quit" debug command as if an |
1147 * had occurred before the ":endwhile". That is, throw an interrupt | 1210 * interrupt had occurred before the ":endwhile"/":endfor". That is, |
1148 * exception if appropriate. Doing this here prevents that an | 1211 * throw an interrupt exception if appropriate. Doing this here |
1149 * exception for a parsing error is discarded when throwing the | 1212 * prevents that an exception for a parsing error is discarded when |
1150 * interrupt exception later on. | 1213 * throwing the interrupt exception later on. |
1151 */ | 1214 */ |
1152 else if (cstack->cs_flags[cstack->cs_idx] & CSF_TRUE | 1215 else if (cstack->cs_flags[cstack->cs_idx] & CSF_TRUE |
1153 && !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE) | 1216 && !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE) |
1154 && dbg_check_skipped(eap)) | 1217 && dbg_check_skipped(eap)) |
1155 (void)do_intthrow(cstack); | 1218 (void)do_intthrow(cstack); |
1156 | 1219 |
1157 /* | 1220 /* |
1158 * Set cs_had_endwhile, so do_cmdline() will jump back to the matching | 1221 * Set loop flag, so do_cmdline() will jump back to the matching |
1159 * ":while". | 1222 * ":while" or ":for". |
1160 */ | 1223 */ |
1161 cstack->cs_had_endwhile = TRUE; | 1224 cstack->cs_lflags |= CSL_HAD_ENDLOOP; |
1162 } | 1225 } |
1163 } | 1226 } |
1164 | 1227 |
1165 | 1228 |
1166 /* | 1229 /* |
1370 { | 1433 { |
1371 if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) | 1434 if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) |
1372 { | 1435 { |
1373 /* Report what's missing if the matching ":try" is not in its | 1436 /* Report what's missing if the matching ":try" is not in its |
1374 * finally clause. */ | 1437 * finally clause. */ |
1375 if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE) | 1438 eap->errmsg = get_end_emsg(cstack); |
1376 eap->errmsg = e_endwhile; | |
1377 else | |
1378 eap->errmsg = e_endif; | |
1379 skip = TRUE; | 1439 skip = TRUE; |
1380 } | 1440 } |
1381 for (idx = cstack->cs_idx; idx > 0; --idx) | 1441 for (idx = cstack->cs_idx; idx > 0; --idx) |
1382 if (cstack->cs_flags[idx] & CSF_TRY) | 1442 if (cstack->cs_flags[idx] & CSF_TRY) |
1383 break; | 1443 break; |
1387 * Just parse. */ | 1447 * Just parse. */ |
1388 eap->errmsg = (char_u *)N_("E604: :catch after :finally"); | 1448 eap->errmsg = (char_u *)N_("E604: :catch after :finally"); |
1389 give_up = TRUE; | 1449 give_up = TRUE; |
1390 } | 1450 } |
1391 else if (cstack->cs_idx > idx) | 1451 else if (cstack->cs_idx > idx) |
1392 rewind_conditionals(cstack, idx, CSF_WHILE, &cstack->cs_whilelevel); | 1452 rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR, |
1453 &cstack->cs_looplevel); | |
1393 } | 1454 } |
1394 | 1455 |
1395 if (ends_excmd(*eap->arg)) /* no argument, catch all errors */ | 1456 if (ends_excmd(*eap->arg)) /* no argument, catch all errors */ |
1396 { | 1457 { |
1397 pat = (char_u *)".*"; | 1458 pat = (char_u *)".*"; |
1521 eap->errmsg = (char_u *)N_("E606: :finally without :try"); | 1582 eap->errmsg = (char_u *)N_("E606: :finally without :try"); |
1522 else | 1583 else |
1523 { | 1584 { |
1524 if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) | 1585 if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) |
1525 { | 1586 { |
1526 /* Find the matching ":try" and report what's missing. */ | 1587 eap->errmsg = get_end_emsg(cstack); |
1527 if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE) | |
1528 eap->errmsg = e_endwhile; | |
1529 else | |
1530 eap->errmsg = e_endif; | |
1531 for (idx = cstack->cs_idx - 1; idx > 0; --idx) | 1588 for (idx = cstack->cs_idx - 1; idx > 0; --idx) |
1532 if (cstack->cs_flags[idx] & CSF_TRY) | 1589 if (cstack->cs_flags[idx] & CSF_TRY) |
1533 break; | 1590 break; |
1534 /* Make this error pending, so that the commands in the following | 1591 /* Make this error pending, so that the commands in the following |
1535 * finally clause can be executed. This overrules also a pending | 1592 * finally clause can be executed. This overrules also a pending |
1544 /* Give up for a multiple ":finally" and ignore it. */ | 1601 /* Give up for a multiple ":finally" and ignore it. */ |
1545 eap->errmsg = (char_u *)N_("E607: multiple :finally"); | 1602 eap->errmsg = (char_u *)N_("E607: multiple :finally"); |
1546 return; | 1603 return; |
1547 } | 1604 } |
1548 if (cstack->cs_idx > idx) | 1605 if (cstack->cs_idx > idx) |
1549 rewind_conditionals(cstack, idx, CSF_WHILE, &cstack->cs_whilelevel); | 1606 rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR, |
1607 &cstack->cs_looplevel); | |
1550 | 1608 |
1551 /* | 1609 /* |
1552 * Don't do something when the corresponding try block never got active | 1610 * Don't do something when the corresponding try block never got active |
1553 * (because of an inactive surrounding conditional or after an error or | 1611 * (because of an inactive surrounding conditional or after an error or |
1554 * interrupt or throw) or for a ":finally" without ":try" or a multiple | 1612 * interrupt or throw) or for a ":finally" without ":try" or a multiple |
1588 * we have particularly to discard a pending return value (as done | 1646 * we have particularly to discard a pending return value (as done |
1589 * by the call to cleanup_conditionals() above when did_emsg or | 1647 * by the call to cleanup_conditionals() above when did_emsg or |
1590 * got_int is set). The pending values are restored by the | 1648 * got_int is set). The pending values are restored by the |
1591 * ":endtry", except if there is a new error, interrupt, exception, | 1649 * ":endtry", except if there is a new error, interrupt, exception, |
1592 * ":continue", ":break", ":return", or ":finish" in the following | 1650 * ":continue", ":break", ":return", or ":finish" in the following |
1593 * finally clause. A missing ":endwhile" or ":endif" detected here | 1651 * finally clause. A missing ":endwhile", ":endfor" or ":endif" |
1594 * is treated as if did_emsg and did_throw had already been set, | 1652 * detected here is treated as if did_emsg and did_throw had |
1595 * respectively in case that the error is not converted to an | 1653 * already been set, respectively in case that the error is not |
1596 * exception, did_throw had already been unset. We must not set | 1654 * converted to an exception, did_throw had already been unset. |
1597 * did_emsg here since that would suppress the error message. | 1655 * We must not set did_emsg here since that would suppress the |
1656 * error message. | |
1598 */ | 1657 */ |
1599 if (pending == CSTP_ERROR || did_emsg || got_int || did_throw) | 1658 if (pending == CSTP_ERROR || did_emsg || got_int || did_throw) |
1600 { | 1659 { |
1601 if (cstack->cs_pending[cstack->cs_idx] == CSTP_RETURN) | 1660 if (cstack->cs_pending[cstack->cs_idx] == CSTP_RETURN) |
1602 { | 1661 { |
1615 /* It's mandatory that the current exception is stored in the | 1674 /* It's mandatory that the current exception is stored in the |
1616 * cstack so that it can be rethrown at the ":endtry" or be | 1675 * cstack so that it can be rethrown at the ":endtry" or be |
1617 * discarded if the finally clause is left by a ":continue", | 1676 * discarded if the finally clause is left by a ":continue", |
1618 * ":break", ":return", ":finish", error, interrupt, or another | 1677 * ":break", ":return", ":finish", error, interrupt, or another |
1619 * exception. When emsg() is called for a missing ":endif" or | 1678 * exception. When emsg() is called for a missing ":endif" or |
1620 * a missing ":endwhile" detected here, the exception will be | 1679 * a missing ":endwhile"/":endfor" detected here, the |
1621 * discarded. */ | 1680 * exception will be discarded. */ |
1622 if (did_throw && cstack->cs_exception[cstack->cs_idx] != | 1681 if (did_throw && cstack->cs_exception[cstack->cs_idx] != |
1623 current_exception) | 1682 current_exception) |
1624 EMSG(_(e_internal)); | 1683 EMSG(_(e_internal)); |
1625 } | 1684 } |
1626 | 1685 |
1627 /* | 1686 /* |
1628 * Set cs_had_finally, so do_cmdline() will reset did_emsg, | 1687 * Set CSL_HAD_FINA, so do_cmdline() will reset did_emsg, |
1629 * got_int, and did_throw and make the finally clause active. | 1688 * got_int, and did_throw and make the finally clause active. |
1630 * This will happen after emsg() has been called for a missing | 1689 * This will happen after emsg() has been called for a missing |
1631 * ":endif" or a missing ":endwhile" detected here, so that the | 1690 * ":endif" or a missing ":endwhile"/":endfor" detected here, so |
1632 * following finally clause will be executed even then. | 1691 * that the following finally clause will be executed even then. |
1633 */ | 1692 */ |
1634 cstack->cs_had_finally = TRUE; | 1693 cstack->cs_lflags |= CSL_HAD_FINA; |
1635 } | 1694 } |
1636 } | 1695 } |
1637 } | 1696 } |
1638 | 1697 |
1639 /* | 1698 /* |
1668 skip = did_emsg || got_int || did_throw || | 1727 skip = did_emsg || got_int || did_throw || |
1669 !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE); | 1728 !(cstack->cs_flags[cstack->cs_idx] & CSF_TRUE); |
1670 | 1729 |
1671 if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) | 1730 if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY)) |
1672 { | 1731 { |
1732 eap->errmsg = get_end_emsg(cstack); | |
1673 /* Find the matching ":try" and report what's missing. */ | 1733 /* Find the matching ":try" and report what's missing. */ |
1674 if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE) | |
1675 eap->errmsg = e_endwhile; | |
1676 else | |
1677 eap->errmsg = e_endif; | |
1678 idx = cstack->cs_idx; | 1734 idx = cstack->cs_idx; |
1679 do | 1735 do |
1680 --idx; | 1736 --idx; |
1681 while (idx > 0 && !(cstack->cs_flags[idx] & CSF_TRY)); | 1737 while (idx > 0 && !(cstack->cs_flags[idx] & CSF_TRY)); |
1682 rewind_conditionals(cstack, idx, CSF_WHILE, &cstack->cs_whilelevel); | 1738 rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR, |
1739 &cstack->cs_looplevel); | |
1683 skip = TRUE; | 1740 skip = TRUE; |
1684 | 1741 |
1685 /* | 1742 /* |
1686 * If an exception is being thrown, discard it to prevent it from | 1743 * If an exception is being thrown, discard it to prevent it from |
1687 * being rethrown at the end of this function. It would be | 1744 * being rethrown at the end of this function. It would be |
1975 | 2032 |
1976 /* | 2033 /* |
1977 * Make conditionals inactive and discard what's pending in finally clauses | 2034 * Make conditionals inactive and discard what's pending in finally clauses |
1978 * until the conditional type searched for or a try conditional not in its | 2035 * until the conditional type searched for or a try conditional not in its |
1979 * finally clause is reached. If this is in an active catch clause, finish the | 2036 * finally clause is reached. If this is in an active catch clause, finish the |
1980 * caught exception. Return the cstack index where the search stopped. Values | 2037 * caught exception. Return the cstack index where the search stopped. |
1981 * used for "searched_cond" are CSF_WHILE or CSF_TRY or 0, the latter meaning | 2038 * Values used for "searched_cond" are (CSF_WHILE | CSF_FOR) or CSF_TRY or 0, |
1982 * the innermost try conditional not in its finally clause. "inclusive" tells | 2039 * the latter meaning the innermost try conditional not in its finally clause. |
1983 * whether the conditional searched for should be made inactive itself (a try | 2040 * "inclusive" tells whether the conditional searched for should be made |
1984 * conditional not in its finally claused possibly find before is always made | 2041 * inactive itself (a try conditional not in its finally claused possibly find |
1985 * inactive). If "inclusive" is TRUE and "searched_cond" is CSF_TRY|CSF_SILENT, | 2042 * before is always made inactive). If "inclusive" is TRUE and |
1986 * the saved former value of "emsg_silent", if reset when the try conditional | 2043 * "searched_cond" is CSF_TRY|CSF_SILENT, the saved former value of |
1987 * finally reached was entered, is restored (unsed by ex_endtry()). This is | 2044 * "emsg_silent", if reset when the try conditional finally reached was |
1988 * normally done only when such a try conditional is left. | 2045 * entered, is restored (unsed by ex_endtry()). This is normally done only |
2046 * when such a try conditional is left. | |
1989 */ | 2047 */ |
1990 int | 2048 int |
1991 cleanup_conditionals(cstack, searched_cond, inclusive) | 2049 cleanup_conditionals(cstack, searched_cond, inclusive) |
1992 struct condstack *cstack; | 2050 struct condstack *cstack; |
1993 int searched_cond; | 2051 int searched_cond; |
2107 } | 2165 } |
2108 return idx; | 2166 return idx; |
2109 } | 2167 } |
2110 | 2168 |
2111 /* | 2169 /* |
2170 * Return an appropriate error message for a missing endwhile/endfor/endif. | |
2171 */ | |
2172 static char_u * | |
2173 get_end_emsg(cstack) | |
2174 struct condstack *cstack; | |
2175 { | |
2176 if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE) | |
2177 return e_endwhile; | |
2178 if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR) | |
2179 return e_endfor; | |
2180 return e_endif; | |
2181 } | |
2182 | |
2183 | |
2184 /* | |
2112 * Rewind conditionals until index "idx" is reached. "cond_type" and | 2185 * Rewind conditionals until index "idx" is reached. "cond_type" and |
2113 * "cond_level" specify a conditional type and the address of a level variable | 2186 * "cond_level" specify a conditional type and the address of a level variable |
2114 * which is to be decremented with each skipped conditional of the specified | 2187 * which is to be decremented with each skipped conditional of the specified |
2115 * type. | 2188 * type. |
2116 */ | 2189 */ |
2139 { | 2212 { |
2140 EMSG(_("E193: :endfunction not inside a function")); | 2213 EMSG(_("E193: :endfunction not inside a function")); |
2141 } | 2214 } |
2142 | 2215 |
2143 /* | 2216 /* |
2144 * Return TRUE if the string "p" looks like a ":while" command. | 2217 * Return TRUE if the string "p" looks like a ":while" or ":for" command. |
2145 */ | 2218 */ |
2146 int | 2219 int |
2147 has_while_cmd(p) | 2220 has_loop_cmd(p) |
2148 char_u *p; | 2221 char_u *p; |
2149 { | 2222 { |
2150 p = skipwhite(p); | 2223 p = skipwhite(p); |
2151 while (*p == ':') | 2224 while (*p == ':') |
2152 p = skipwhite(p + 1); | 2225 p = skipwhite(p + 1); |
2153 if (p[0] == 'w' && p[1] == 'h') | 2226 if ((p[0] == 'w' && p[1] == 'h') |
2227 || (p[0] == 'f' && p[1] == 'o' && p[2] == 'r')) | |
2154 return TRUE; | 2228 return TRUE; |
2155 return FALSE; | 2229 return FALSE; |
2156 } | 2230 } |
2157 | 2231 |
2158 #endif /* FEAT_EVAL */ | 2232 #endif /* FEAT_EVAL */ |