エラー


*error-regexp-list*

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
[ Intro | 目次 | 索引 | 目的別 | エラー ]

define-condition

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
[ Intro | 目次 | 索引 | 目的別 | エラー ]

error

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
[ Intro | 目次 | 索引 | 目的別 | エラー ]

first-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*
[ Intro | 目次 | 索引 | 目的別 | エラー ]

handler-case

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: エラー処理関係
[ Intro | 目次 | 索引 | 目的別 | エラー ]

ignore-errors

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: エラー処理関係
[ Intro | 目次 | 索引 | 目的別 | エラー ]

make-condition

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
[ Intro | 目次 | 索引 | 目的別 | エラー ]

next-error

type: Function
arguments: next-error &optional ARG
package: editor
file: errors.l
次のエラーの該当行にジャンプします。[F11], [C-x `]

seealso: *error-regexp-list*
seealso: first-error
[ Intro | 目次 | 索引 | 目的別 | エラー ]

plain-error

type: Function
arguments: plain-error &rest REST
package: lisp
file: misc.l
(詳細不明)

[ Intro | 目次 | 索引 | 目的別 | エラー ]

quit

type: Function
arguments: quit
package: editor
file: cmds.l
コマンドの実行などを中止します。[C-g]

実行に時間がかかりすぎる場合や無限ループに陥ったときなどに使われます。

seealso: error
[ Intro | 目次 | 索引 | 目的別 | エラー ]

toggle-trace-on-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
[ Intro | 目次 | 索引 | 目的別 | エラー ]

trap-errors

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
[ Intro | 目次 | 索引 | 目的別 | エラー ]

エラー処理関係

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;
    }
と同じですけど。

[ Intro | 目次 | 索引 | 目的別 | エラー ]