aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorAndrea Corallo2021-04-19 18:46:50 +0200
committerAndrea Corallo2021-04-19 18:46:50 +0200
commitb5c76530fab4b99e76249bfb9a105b30bef4ce67 (patch)
tree319d7a65b6f818cebed9833534a423fbcb79a9b5 /src/eval.c
parente54066f3d459f67a1ee4e44552bf0356d010e03f (diff)
parent0a4dc70830f5e8286b47120cabc750cca07a75c1 (diff)
downloademacs-b5c76530fab4b99e76249bfb9a105b30bef4ce67.tar.gz
emacs-b5c76530fab4b99e76249bfb9a105b30bef4ce67.zip
Merge remote-tracking branch 'savannah/master' into native-comp
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/src/eval.c b/src/eval.c
index cf5ca3b4bbd..aeedcc50cc0 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1310,7 +1310,7 @@ DEFUN ("condition-case", Fcondition_case, Scondition_case, 2, UNEVALLED, 0,
1310 doc: /* Regain control when an error is signaled. 1310 doc: /* Regain control when an error is signaled.
1311Executes BODYFORM and returns its value if no error happens. 1311Executes BODYFORM and returns its value if no error happens.
1312Each element of HANDLERS looks like (CONDITION-NAME BODY...) 1312Each element of HANDLERS looks like (CONDITION-NAME BODY...)
1313where the BODY is made of Lisp expressions. 1313or (:success BODY...), where the BODY is made of Lisp expressions.
1314 1314
1315A handler is applicable to an error if CONDITION-NAME is one of the 1315A handler is applicable to an error if CONDITION-NAME is one of the
1316error's condition names. Handlers may also apply when non-error 1316error's condition names. Handlers may also apply when non-error
@@ -1332,6 +1332,10 @@ with VAR bound to (ERROR-SYMBOL . SIGNAL-DATA) from the error.
1332Then the value of the last BODY form is returned from the `condition-case' 1332Then the value of the last BODY form is returned from the `condition-case'
1333expression. 1333expression.
1334 1334
1335The special handler (:success BODY...) is invoked if BODYFORM terminated
1336without signalling an error. BODY is then evaluated with VAR bound to
1337the value returned by BODYFORM.
1338
1335See also the function `signal' for more info. 1339See also the function `signal' for more info.
1336usage: (condition-case VAR BODYFORM &rest HANDLERS) */) 1340usage: (condition-case VAR BODYFORM &rest HANDLERS) */)
1337 (Lisp_Object args) 1341 (Lisp_Object args)
@@ -1355,16 +1359,21 @@ internal_lisp_condition_case (Lisp_Object var, Lisp_Object bodyform,
1355 1359
1356 CHECK_SYMBOL (var); 1360 CHECK_SYMBOL (var);
1357 1361
1362 Lisp_Object success_handler = Qnil;
1363
1358 for (Lisp_Object tail = handlers; CONSP (tail); tail = XCDR (tail)) 1364 for (Lisp_Object tail = handlers; CONSP (tail); tail = XCDR (tail))
1359 { 1365 {
1360 Lisp_Object tem = XCAR (tail); 1366 Lisp_Object tem = XCAR (tail);
1361 clausenb++;
1362 if (! (NILP (tem) 1367 if (! (NILP (tem)
1363 || (CONSP (tem) 1368 || (CONSP (tem)
1364 && (SYMBOLP (XCAR (tem)) 1369 && (SYMBOLP (XCAR (tem))
1365 || CONSP (XCAR (tem)))))) 1370 || CONSP (XCAR (tem))))))
1366 error ("Invalid condition handler: %s", 1371 error ("Invalid condition handler: %s",
1367 SDATA (Fprin1_to_string (tem, Qt))); 1372 SDATA (Fprin1_to_string (tem, Qt)));
1373 if (EQ (XCAR (tem), QCsuccess))
1374 success_handler = XCDR (tem);
1375 else
1376 clausenb++;
1368 } 1377 }
1369 1378
1370 /* The first clause is the one that should be checked first, so it 1379 /* The first clause is the one that should be checked first, so it
@@ -1378,7 +1387,8 @@ internal_lisp_condition_case (Lisp_Object var, Lisp_Object bodyform,
1378 Lisp_Object volatile *clauses = alloca (clausenb * sizeof *clauses); 1387 Lisp_Object volatile *clauses = alloca (clausenb * sizeof *clauses);
1379 clauses += clausenb; 1388 clauses += clausenb;
1380 for (Lisp_Object tail = handlers; CONSP (tail); tail = XCDR (tail)) 1389 for (Lisp_Object tail = handlers; CONSP (tail); tail = XCDR (tail))
1381 *--clauses = XCAR (tail); 1390 if (!EQ (XCAR (XCAR (tail)), QCsuccess))
1391 *--clauses = XCAR (tail);
1382 for (ptrdiff_t i = 0; i < clausenb; i++) 1392 for (ptrdiff_t i = 0; i < clausenb; i++)
1383 { 1393 {
1384 Lisp_Object clause = clauses[i]; 1394 Lisp_Object clause = clauses[i];
@@ -1418,6 +1428,23 @@ internal_lisp_condition_case (Lisp_Object var, Lisp_Object bodyform,
1418 1428
1419 Lisp_Object result = eval_sub (bodyform); 1429 Lisp_Object result = eval_sub (bodyform);
1420 handlerlist = oldhandlerlist; 1430 handlerlist = oldhandlerlist;
1431 if (!NILP (success_handler))
1432 {
1433 if (NILP (var))
1434 return Fprogn (success_handler);
1435
1436 Lisp_Object handler_var = var;
1437 if (!NILP (Vinternal_interpreter_environment))
1438 {
1439 result = Fcons (Fcons (var, result),
1440 Vinternal_interpreter_environment);
1441 handler_var = Qinternal_interpreter_environment;
1442 }
1443
1444 ptrdiff_t count = SPECPDL_INDEX ();
1445 specbind (handler_var, result);
1446 return unbind_to (count, Fprogn (success_handler));
1447 }
1421 return result; 1448 return result;
1422} 1449}
1423 1450
@@ -4490,6 +4517,7 @@ alist of active lexical bindings. */);
4490 defsubr (&Sthrow); 4517 defsubr (&Sthrow);
4491 defsubr (&Sunwind_protect); 4518 defsubr (&Sunwind_protect);
4492 defsubr (&Scondition_case); 4519 defsubr (&Scondition_case);
4520 DEFSYM (QCsuccess, ":success");
4493 defsubr (&Ssignal); 4521 defsubr (&Ssignal);
4494 defsubr (&Scommandp); 4522 defsubr (&Scommandp);
4495 defsubr (&Sautoload); 4523 defsubr (&Sautoload);