Class | dc_error |
In: |
dc_error.f90
|
プログラムの部品は必ずエラーの取り扱いを明確に規定すべきものです。 エラーとは当該部品への入力が不適切であるとか、 期待される動作をすることができないといった事態を指します。
gt4f90io ライブラリがユーザに提供する手続 (手続とはサブルーチンまたは関数の総称) はほとんどの場合、 以下の 2 つの方式のいずれかで呼び出し元にエラーを報告します。
これらの処理はすべて dc_error モジュールの StoreError サブルーチンで行っています。引用仕様などに関しては StoreError を参照してください。
gt4f90io ライブラリにコードを追加するプログラマは適切な エラーコードで StoreError を呼び出すようにしなければなりません。 そこで、 新しいエラーコードを定義する必要があるかどうかを 判定するために、 エラーコードの値と対応するメッセージを一覧します。 エラーコードニーモニックを使用するためには、 NF_E で始まる名前については netcdf_f77 モジュールを引用するか include ‘netcdf.inc’ を行い(後者は推奨しません)、 GT_E で始まる名前については dc_error モジュールを引用してください。 また USR_E で始まる名前は各々のユーザが定義して 良いエラーコードです。
エラーではない状態を表す非エラーコードは DC_NOERR (数値 0) です。
エラーコードの数値の欄を設けたのは、新たなエラーコードを 割り当てる際の指針を示すためです。 コードではエラーコードをニーモニックで与えるべきであり、 数値をハードコードすることは厳に慎んで下さい。
正の整数値はエラーコードとして使用しません。
NetCDF ライブラリは libc のエラーコード errno を返す可能性があり、 errno の数値には移植性がないため、全ての正の整数値は errno の仕様のために予約されているべきだからです。
以下の非エラーコードに関しては dc_error モジュールを引用することで 利用してください。
数値 : | [ ニーモニック ] |
0 : | [ DC_NOERR ] |
以下のエラーコードに関しては netcdf_f77 モジュールを引用することで 利用してください。
数値 : | [ ニーモニック ] エラーメッセージ | ||
0 : | [ NF_NOERR ]
| ||
-33 : | [ NF_EBADID ]
| ||
-34 : | [ NF_ENFILE ]
| ||
-35 : | [ NF_EEXIST ]
| ||
-36 : | [ NF_EINVAL ]
| ||
-37 : | [ NF_EPERM ]
| ||
-38 : | [ NF_ENOTINDEFINE ]
| ||
-39 : | [ NF_EINDEFINE ]
| ||
-40 : | [ NF_EINVALCOORDS ]
| ||
-41 : | [ NF_EMAXDIMS ]
| ||
-42 : | [ NF_ENAMEINUSE ]
| ||
-43 : | [ NF_ENOTATT ]
| ||
-44 : | [ NF_EMAXATTS ]
| ||
-45 : | [ NF_EBADTYPE ]
| ||
-46 : | [ NF_EBADDIM ]
| ||
-47 : | [ NF_EUNLIMPOS ]
| ||
-48 : | [ NF_EMAXVARS ]
| ||
-49 : | [ NF_ENOTVAR ]
| ||
-50 : | [ NF_EGLOBAL ]
| ||
-51 : | [ NF_ENOTNC ]
| ||
-52 : | [ NF_ESTS ]
| ||
-53 : | [ NF_EMAXNAME ]
| ||
-54 : | [ NF_EUNLIMIT ]
| ||
-55 : | [ NF_ENORECVARS ]
| ||
-56 : | [ NF_ECHAR ]
| ||
-57 : | [ NF_EEDGE ]
| ||
-58 : | [ NF_ESTRIDE ]
| ||
-59 : | [ NF_EBADNAME ]
| ||
-60 : | [ NF_ERANGE ]
| ||
-61 : | [ NF_ENOMEM ]
| ||
-62〜-99: |
|
以下のエラーコードに関しては dc_error モジュールを引用することで 利用してください。
数値 : | [ ニーモニック ] エラーメッセージ | ||
-100 : | [ GT_EFAKE ]
| ||
-101 : | [ GT_ENOMOREDIMS ]
| ||
-102 : | [ GT_EDIMNODIM ]
| ||
-103 : | [ GT_EDIMMULTIDIM ]
| ||
-104 : | [ GT_EDIMOTHERDIM ]
| ||
-105 : | [ GT_EBADDIMNAME ]
| ||
-106 : | [ GT_ENOTVAR ]
| ||
-107 : | [ GT_ENOMEM ]
| ||
-108 : | [ GT_EOTHERFILE ]
| ||
-109 : | [ GT_EARGSIZEMISMATCH ]
| ||
-110 : | [ GT_ENOMATCHDIM ]
| ||
-111 : | [ GT_ELIMITED ]
| ||
-112 : | [ GT_EBADVAR ]
| ||
-113 : | [ GT_ECHARSHORT ]
| ||
-114 : | [ GT_ENOUNLIMITDIM ]
| ||
-115 : | [ GT_EBADATTRNAME ]
| ||
-116 : | [ GT_EBADHISTORY ]
| ||
-117 : | [ GT_EBADALLOCATESIZE ]
| ||
-118 : | [ GT_ERANKMISMATCH ]
| ||
〜-299 : |
|
以下のエラーコードに関しては dc_error モジュールを引用することで 利用してください。
数値 : | [ ニーモニック ] エラーメッセージ | ||
-300 : | [ GR_ENOTGR ]
| ||
〜-399 : |
|
以下のエラーコードは今後の拡張も考えて予約してある部分です。
数値 : | [ ニーモニック ] エラーメッセージ | ||
-400〜-999 : |
|
以下のエラーコードを含む -1000 よりも小さいエラーコードは、 gt4f90io の上位のプログラムが利用するエラーコードとして空けてあります。
数値 : | [ ニーモニック ] エラーメッセージ | ||
-1000 : | [ USR_ECHAR ]
| ||
-1001 : | [ USR_EINT ]
|
Subroutine : |
GetErrorMessage からエラーメッセージを取得後、 それを sysdep#AbortProgram に渡してプログラムを終了させます。
Original external subprogram is dc_error.f90#DumpError
Function : | |
result : | integer |
現在設定されているエラーコードを返します。
integer function ErrorCode() result(result) ! ! 現在設定されているエラーコードを返します。 ! result = errno end function ErrorCode
Subroutine : | |
msg : | character(len = *), intent(out) |
現在設定されているエラーコードから対応するメッセージを返します。
subroutine GetErrorMessage(msg) ! ! 現在設定されているエラーコードから対応するメッセージを返します。 ! use netcdf_f77, only: nf_strerror use dc_string , only: toChar character(len = *), intent(out):: msg character(len = 180):: message continue select case(errno) case(GT_EFAKE) msg = " function not implemented" ! ! -101 以下: データ構造のエラー ! case(GT_ENOMOREDIMS) write(message, "(': dimension number', i4, ' is out of range')") cause_int msg = trim(message) case(GT_EBADDIMNAME) msg = '(' // trim(cause_string) // '): unknown dimension name' case(GT_ENOTVAR) msg = " variable not opened" case(GT_ENOMEM) msg = " allocate/deallocate error" case(GT_EDIMNODIM) msg = " dimension variable has no dimension" case(GT_EDIMMULTIDIM) msg = " dimension variable has many dimensions" case(GT_EDIMOTHERDIM) msg = " dimension variable has another dimension" case(GT_EOTHERFILE) msg = " specified dimensional variable not on the same file" case(GT_EARGSIZEMISMATCH) msg = " arguments (" // trim(cause_string) //") array size mismatch" case(GT_ENOMATCHDIM) msg = " dimension matching failed" case(GT_ELIMITED) msg = " variable already limited" case(GT_EBADVAR) msg = " variable type not supported" case(GT_ECHARSHORT) msg = " character length not enough" case(GT_ENOUNLIMITDIM) msg = " NC_UNLIMITED dimension is not found" case(GT_EBADATTRNAME) msg = " invalid attribute name" case(GT_EBADALLOCATESIZE) msg = " invalid allocated size" case(GT_ERANKMISMATCH) msg = " rank of data and argument are mismatch (" // trim(cause_string) // ")" ! ! -300 以下: GrADS 入出力のエラー ! case(GR_ENOTGR) msg = " invalid GrADS file" ! ! -1000 以下: ユーザー定義 ! case(USR_ECHAR) msg = trim(cause_string) case(USR_EINT) msg = trim(cause_string) // ' (' // trim(toChar(cause_int)) // ')' case default goto 999 end select msg = '*** ERROR (Code ' // trim(toChar(errno)) // ') [' // trim(cause_location) // '] *** ' // trim(msg) return 999 continue if (len(cause_string) > 0) then message = nf_strerror(errno) msg = '*** ERROR (Code ' // trim(toChar(errno)) // ') [' // trim(cause_location) // '(' // trim(cause_string) // ')] *** ' // trim(message) else if (cause_int /= 0) then message = nf_strerror(errno) msg = '*** ERROR (Code ' // trim(toChar(errno)) // ') [' // trim(cause_location) // '(' // trim(toChar(cause_int)) // ')] *** ' // trim(message) else message = nf_strerror(errno) msg = '*** ERROR (Code ' // trim(toChar(errno)) // ') [' // trim(cause_location) // '] *** ' // trim(message) endif end subroutine GetErrorMessage
Constant : | |
NF_EINVAL = -36 : | integer, parameter |
Original external subprogram is netcdf_f77#NF_EINVAL
Constant : | |
NF_ENOTVAR = -49 : | integer, parameter |
Original external subprogram is netcdf_f77#NF_ENOTVAR
Subroutine : | |||
number : | integer, intent(in)
| ||
where : | character(len = *), intent(in)
| ||
err : | logical, intent(out), optional
| ||
cause_c : | character(len = *), intent(in), optional
| ||
cause_i : | integer, intent(in), optional
|
必要な引数は2つであり、第1引数 number は整数型のエラーコード、 第2引数 where は文字型でエラーの発生した手続名を与えます。 デフォルトでは以下の形式の文字列が標準出力 に表示されてプログラム は終了します。 エラーメッセージ error_message はエラーコードから自動的に決まります。 対応表がエラーコード一覧にあるので参照してください。
*** ERROR (Code number) [where] *** error_message *** ERROR (Code number) [where(cause_c)] *** error_message
なお、gt4f90io の ライブラリ外 からユーザがエラー処理用ツール として StoreError を用いることを想定し、USR_ECHAR および USR_EINT を用意してあります。 このエラーコードを用いると、 StoreError は以下の形式の文字列を装置 "*" に出力してプログラムを 終了させます。 なお、より安易に使えるラッパーとして dc_message モジュールを用意してあるのでそちらも参照してください。
*** ERROR (Code USR_ECHAR) [where] *** cause_c *** ERROR (Code USR_EINT) [where] *** cause_c (cause_i)
subroutine StoreError(number, where, err, cause_c, cause_i) ! !== 典型的ライブラリ関数のために作られたエラー処理関数 ! ! 必要な引数は2つであり、第1引数 number は整数型のエラーコード、 ! 第2引数 where は文字型でエラーの発生した手続名を与えます。 ! デフォルトでは以下の形式の文字列が標準出力 に表示されてプログラム ! は終了します。 エラーメッセージ error_message ! はエラーコードから自動的に決まります。 ! 対応表がエラーコード一覧にあるので参照してください。 ! ! ! *** ERROR (Code number) [where] *** error_message ! ! *** ERROR (Code number) [where(cause_c)] *** error_message ! ! なお、gt4f90io の ライブラリ外 からユーザがエラー処理用ツール ! として StoreError を用いることを想定し、USR_ECHAR および USR_EINT ! を用意してあります。 このエラーコードを用いると、 ! StoreError は以下の形式の文字列を装置 "*" に出力してプログラムを ! 終了させます。 なお、より安易に使えるラッパーとして ! dc_message モジュールを用意してあるのでそちらも参照してください。 ! ! ! *** ERROR (Code USR_ECHAR) [where] *** cause_c ! ! *** ERROR (Code USR_EINT) [where] *** cause_c (cause_i) ! ! use dc_string, only: assignment(=) integer, intent(in) :: number ! エラーコード character(len = *), intent(in) :: where ! エラー発生個所 logical, intent(out), optional :: err ! この論理型変数が与えられた場合は、 ! エラー時にはそれを <tt>.true.</tt> ! にします。この変数が省略され、 ! 且つエラーが発生する場合は ! メッセージを表示してプログラムを ! 終了します。 character(len = *), intent(in), optional :: cause_c ! 文字型メッセージ integer, intent(in), optional :: cause_i ! 整数型メッセージ continue errno = number cause_location = where if (present(cause_c)) then cause_string = trim(cause_c) else cause_string = "" endif if (present(cause_i)) cause_int = cause_i if (present(err)) then err = (number /= DC_NOERR) return endif if (number == DC_NOERR) return call DumpError end subroutine StoreError