Встроенная обработка ошибок ECL lisp

Задача: Встроить ECL lisp в мой проект, настроить обработку ошибок и подробные отчеты об ошибках (где произошла, тип ошибки и т.д.)

Я пытался сделать это так:

cl_def_c_function_va(
    c_string_to_object("SYSTEM:UNIVERSAL-ERROR-HANDLER"),
    LispErrorHandler);

У ECL нет документации по встроенному API и нет документации по обработке ошибок...

Не подскажете, как это реализовать?


person The Architect    schedule 13.10.2011    source источник


Ответы (1)


Глобального обработчика ошибок нет, потому что это не философия Common Lisp. Если вы хотите обрабатывать ошибки, делайте это с помощью лиспа.

1) Создайте функцию, которая использует HANDLER-CASE или HANDLER-BIND, чтобы настроить соответствующие обработчики ошибок и перехватывать ошибки вокруг формы, которая должна быть оценена. Что-то типа

(DEFUN MY-EVAL (FORM) (HANDLER-CASE (EVAL FORM) (ERROR (C) ...) (MY-ERROR (C) ...) ...))

Эта функция может быть определена в вашем коде C и вызвана.

2) Используйте функции, которые создает ECL, которые перехватывают все ошибки. Самый важный из них — si_safe_eval(form, environment, error_value). Он оценивает ФОРМУ lisp в ОКРУЖЕНИИ (обычно Cnil) и возвращает свой результат или ERROR_VALUE, если он получил какую-то ошибку.

Несколько примеров, использующих тот или иной метод: http://thread.gmane.org/gmane.lisp.ecl.general/5365 (2-е сообщение) http://thread.gmane.org/gmane.lisp.ecl.general/8526/focus=8529

person Juanjo    schedule 13.10.2011
comment
...Но попробуйте оценить (defun SYSTEM:UNIVERSAL-ERROR-HANDLER (a1 a2 a3) t), а затем (qwertyuiop), сообщение об ошибке подразумевало, что функция существует (1) и может быть закодирована/изменена (2). Вы уверены, что мы не можемt use that? It is not a 'tedium', but 'scientific' interest, you may not answer, if you donзахотеть ;) Еще раз спасибо! - person The Architect; 14.10.2011
comment
system:universal-error-handler не следует путать, пожалуйста. Если вы хотите изменить обработчик ошибок, используйте стандарт Common Lisp. Эта функция существует только для внутренних целей, и вы пытаетесь догадаться, что ее можно переопределить, когда это невозможно. Он используется внутри SIGNAL Common Lisp таким способом, который не должен быть доступен пользователю. Его перехват не приводит к тому, что ошибки просто исчезают — везде в ECL ожидается правильная обработка ошибок. Что произойдет, если вы переопределите эту функцию, а затем оцените (SIN Hello)? - person Juanjo; 13.11.2011