エラー
type: Variable
package: editor
file: errors.l
first-error/next-errorで使用するエラー発生位置の表記形式を変更することが可能です。
*error-regexp-list*の形式は以下のとおりです。
((正規表現1 ファイル名のマッチ位置1 行のマッチ位置1)
(正規表現2 ファイル名のマッチ位置2 行のマッチ位置2)
...
(正規表現N ファイル名のマッチ位置N 行のマッチ位置N))
[xyzzy:05447]で亀井さんが示しているとおり、pushを使って追加するのが無難です。
(push (list (compile-regexp "^\"\\([^\"\n]+\\)\", line \\([0-9]+\\):") 1 2)
*error-regexp-list*)
seealso: next-error
seealso: first-error
type: Macro
arguments: define-condition NAME (PARENT-TYPE) &rest BODY
package: lisp
file: condition.l
新しいコンディションを定義します。
新しく定義したコンディションは error で投げたり
handler-case で処理したりできます。
コンディションは構造体からできています。
親となるコンディションにスロットが定義されている場合、
新しいコンディションにもそれらのスロットが引き継がれます。
NAME : コンディションの名前
PARENT-TYPE : 親となるコンディション
BODY
第一要素 コンディションに追加するスロットの名前のリスト
それ以降 以下のどれか一つを car として持つリスト
:documentation コンディションの説明を設定します。
:report エラー報告用の関数を指定します。
:important important な構造体になる?(詳細不明)
使用例:
;; lisp/condition.l より
(define-condition check-type-error (type-error)
(string place)
(:report (lambda (c s)
(format s "`~A'の値`~S'は~:[~S~;~:*~A~]ではありません"
(check-type-error-place c)
(check-type-error-datum c)
(check-type-error-string c)
(check-type-error-expected-type c)))))
;; 自分で定義してみる
(define-condition my-error (error)
(string) ; 新しいスロット :string を追加
(:documentation "自分で定義したコンディション")
(:report (lambda (c s) ; c はコンディション、s は出力ストリーム
(format s "エラーです: ~A"
(my-error-string c))))
(:important t))
=> t
(error 'my-error :string "test")
=> エラーです: test
(documentation 'my-error 'type)
=> "自分で定義したコンディション"
seealso: handler-case
seealso: error
seealso: エラー処理関係
seealso: make-condition
type: Function
arguments: error DATUM &rest ARGS
package: lisp
file: handler.l
例外を発生します。
発生させた例外は上位の階層でハンドリングすることができます。
ハンドリングの方法はhandler-caseを参照して下さい。
seealso: handler-case
seealso: ignore-errors
seealso: unwind-protect
seealso: エラー処理関係
seealso: stack-trace
seealso: make-condition
seealso: si:*condition-string
seealso: si:*throw-error
type: Function
arguments: first-error &optional ARG WRAP
package: editor
file: errors.l
grep後の*compilation*バッファ上で実行すると、該当行へジャンプ可能です。[F10]
以後は、next-error([F11], [C-x `])を押すことで次々と該当行へジャンプ可能です。
各種コンパイラの出力結果に応じてジャンプすることも可能です。
また、コンパイラのエラー出力が標準に対応していなくても、
*error-regexp-list*を変更することで対応が可能な場合があります。
seealso: next-error
seealso: *error-regexp-list*
type: Macro
arguments: handler-case FORM &rest CASES
package: lisp
file: handler.l
例外をキャッチします。
詳細はエラー処理関連を参照してください。キャッチした例外は
si:*condition-stringで対応する文字列を取得できるようです。
(handler-case
例外が発生しそうな処理
(エラーのシンボル1 (仮引数1) エラー処理1)
(エラーのシンボル2 (仮引数2) エラー処理2)
(エラーのシンボル3 (仮引数3) エラー処理3))
例えば、例外が発生しそうな処理で(error エラーシンボル2)が起きると、途中
の処理をすっとばして、エラー処理2が実行されます。そこで対応出来れば処理
を継続しますが、対応できなければ(error 仮引数2)を実行して、より上位の
handler-caseに対応をお願いします。どこまでいっても対応できなければ、
xyzzyがエラーダイアログを出して処理を終了します。
使用例:
;;; 例外が出ても、個々に対応しつつ処理を継続する場合
;;; with-output-to-stringを使ってるのは変数が煩わしいから
(with-output-to-string (out)
(dolist (i '((6 3) (6 0) (6 "a")))
(handler-case
(/ (car i) (cadr i))
(division-by-zero (c)
(format out "division-by-zero: ~a~%" (si:*condition-string c)))
(error (c)
(format out "error:\t ~a~%" (si:*condition-string c))))))
=> "division-by-zero: 0で除算しました: /: (6 0)
error: 不正なデータ型です: \"a\": number"
seealso: ignore-errors
seealso: trap-errors
seealso: unwind-protect
seealso: error
seealso: エラー処理関係
type: Macro
arguments: ignore-errors &body BODY
package: lisp
file: handler.l
本体を評価したときに発生するエラーを全て無視します。
エラーが発生した場合には、ignore-errorsはnilとそのコンディションを多値で
返します。
C++の場合:
try {
return resolve_shortcut("c:\\autoexec.bat");
} catch (...) {
return nil;
}
xyzzyの場合:
(ignore-errors (resolve-shortcut "c:/autoexec.bat"))
=>nil
=>#S(file-error pathname "c:/autoexec.bat" datum ショートカットではありません)
seealso: trap-errors
seealso: handler-case
seealso: unwind-protect
seealso: エラー処理関係
type: Function
arguments: make-condition TYPE &rest ARGS
package: lisp
file: condition.l
TYPE 型のコンディションを作成して返します。
作成するだけで、エラーにはなりません。
エラーを発生させるには error などで投げる必要があります。
使用例:
(make-condition 'simple-error)
=> #S(simple-error format-string nil format-arguments nil)
seealso: handler-case
seealso: error
seealso: エラー処理関係
seealso: define-condition
type: Function
arguments: next-error &optional ARG
package: editor
file: errors.l
次のエラーの該当行にジャンプします。[F11], [C-x `]
seealso: *error-regexp-list*
seealso: first-error
type: Function
arguments: plain-error &rest REST
package: lisp
file: misc.l
(詳細不明)
type: Function
arguments: quit
package: editor
file: cmds.l
コマンドの実行などを中止します。[C-g]
実行に時間がかかりすぎる場合や無限ループに陥ったときなどに使われます。
seealso: error
type: Function
arguments: toggle-trace-on-error &optional (ARG () SVAR)
package: editor
file: misc.l
エラーをトレースするかどうかをトグルします。
On にする時にトレース用のバッファ *Trace Output* が無ければ新しく作ります。
前置引数をつけた場合、toggle-mode と同じような挙動をします。
seealso: ed::toggle-mode
type: Macro
arguments: trap-errors &body BODY
package: editor
file: misc.l
BODY 内でエラーが起こった場合もしくは中断(quit)された場合、
キャッチして trap-errors の外に影響がでないようにします。
handler-case の簡易版といえます。
ignore-errors と違い、エラーが発生したら表示されます。
使用例:
;; エラーが起きたらとりあえずキャッチして、その後の処理は続ける。
(progn
(trap-errors
(/ 1 0))
(msgbox "done."))
seealso: handler-case
seealso: ignore-errors
type: Tips
エラーの種類のツリー(階層)です。
condition
├simple-condition
├serious-condition
│├error
││├simple-error
│││└plain-error
││├arithmetic-error
│││├division-by-zero
│││├floating-point-overflow
│││├floating-point-underflow
│││├domain-error
│││├bignum-overflow
│││└power-number-too-large
││├cell-error
│││├unbound-variable
│││├modify-constant
│││└undefined-function
││├control-error
│││└target-missing
││├file-error
│││├file-not-found
│││├path-not-found
│││├access-denied
│││├invalid-drive
│││├current-directory
│││├not-same-device
│││├write-protected
│││├bad-unit
│││├device-not-ready
│││├sharing-violation
│││├lock-violation
│││├wrong-disk
│││├file-exists
│││├not-empty
│││├archiver-error
│││├network-error
│││└file-lost-error
││├package-error
│││└simple-package-error
││├program-error
│││├no-target
│││├bad-macro-form
│││├invalid-function
│││├invalid-variable-list
│││├invalid-lambda-list
│││└invalid-keyword-list
││├type-error
││├range-error
││├stream-error
│││└end-of-file
││├reader-error
││├too-few-arguments
││├too-many-arguments
││├bad-type-specifier
││├read-only-buffer
││└dde-error
││ ├dde-timeout
││ ├dde-busy
││ ├dde-low-memory
││ ├dde-no-conv
││ ├dde-not-processed
││ ├dde-server-died
││ └dde-terminated-transaction
│├storage-condition
│├stack-overflow
│└invalid-byte-code
├quit
│└silent-quit
└warning
└simple-warning
| xyzzyはもちろん、Emacs Lispでなくて Common Lispに合わせているんですよね。
そうです。コンディションタイプには独自のがありますけど。Stallman先生は、
直接ではないですがCommonのコンディションシステムに影響を与えているらしい
ので、仕組み的には似てます。
| コンディションって何ですか?
Commonでは、エラーと言わずにコンディションと言うらしいです(エラー以外も
投げられるから?)。簡単に言うとC++のtry-catchと同じです(多分、C++がパクっ
たんだろうけど)。
class condition {};
class serious_condition: public condition {};
class error: public serious_condition {};
class arithmetic_error: public error {};
class division_by_zero: public arithmetic_error {};
ってのがある場合、
throw division_by_zero;
とすると、
try {...} catch (division_by_zero &) {...}
でも、
try {...} catch (error &) {...}
でも、
try {...} catch (condition &) {...}
でも捕まえられますよね?
それと同様に
(error 'division-by-zero)
は、
(handler-case ... (division-by-zero (c) ...))
(handler-case ... (error (c) ...))
(handler-case ... (condition (c) ...))
どれででも捕まえることができます。ま、名前が違うだけでEmacsの
condition-caseと同じです(多分)。catch&throwのタグに継承関係を付けた
のとも同じかも。
また、Emacsでできるかどうかは知りませんが、↓な感じで次のキャッチャにコ
ンディションを渡すこともできます。
(handler-case
(any-expression)
(error (c)
(some-expression)
(error c)))
C++での
try
{
any-expression;
}
catch (error &)
{
some-expression;
throw;
}
と同じですけど。