diff options
| author | Andrea Corallo | 2021-04-19 18:46:50 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2021-04-19 18:46:50 +0200 |
| commit | b5c76530fab4b99e76249bfb9a105b30bef4ce67 (patch) | |
| tree | 319d7a65b6f818cebed9833534a423fbcb79a9b5 /src/eval.c | |
| parent | e54066f3d459f67a1ee4e44552bf0356d010e03f (diff) | |
| parent | 0a4dc70830f5e8286b47120cabc750cca07a75c1 (diff) | |
| download | emacs-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.c | 34 |
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. |
| 1311 | Executes BODYFORM and returns its value if no error happens. | 1311 | Executes BODYFORM and returns its value if no error happens. |
| 1312 | Each element of HANDLERS looks like (CONDITION-NAME BODY...) | 1312 | Each element of HANDLERS looks like (CONDITION-NAME BODY...) |
| 1313 | where the BODY is made of Lisp expressions. | 1313 | or (:success BODY...), where the BODY is made of Lisp expressions. |
| 1314 | 1314 | ||
| 1315 | A handler is applicable to an error if CONDITION-NAME is one of the | 1315 | A handler is applicable to an error if CONDITION-NAME is one of the |
| 1316 | error's condition names. Handlers may also apply when non-error | 1316 | error'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. | |||
| 1332 | Then the value of the last BODY form is returned from the `condition-case' | 1332 | Then the value of the last BODY form is returned from the `condition-case' |
| 1333 | expression. | 1333 | expression. |
| 1334 | 1334 | ||
| 1335 | The special handler (:success BODY...) is invoked if BODYFORM terminated | ||
| 1336 | without signalling an error. BODY is then evaluated with VAR bound to | ||
| 1337 | the value returned by BODYFORM. | ||
| 1338 | |||
| 1335 | See also the function `signal' for more info. | 1339 | See also the function `signal' for more info. |
| 1336 | usage: (condition-case VAR BODYFORM &rest HANDLERS) */) | 1340 | usage: (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); |