| 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 です。
エラーコードの数値の欄を設けたのは、新たなエラーコードを 割り当てる際の指針を示すためです。 コードではエラーコードをニーモニックで与えるべきであり、 数値をハードコードすることは厳に慎んで下さい。
正の整数値はエラーコードとして使用しません。
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 : |
|
以下のエラーコードに関しては dc_error モジュールを引用することで 利用してください。
| 数値 : | [ ニーモニック ] エラーメッセージ | ||
| -400 : | [ DC_ENOTINIT ]
| ||
| -401 : | [ DC_EBADUNIT ]
| ||
| -402 : | [ DC_EBADCALTYPE ]
| ||
| -403 : | [ DC_EBADTIMEZONE ]
| ||
| -402〜-499 : |
|
以下のエラーコードは今後の拡張も考えて予約してある部分です。
| 数値 : | [ ニーモニック ] エラーメッセージ | ||
| -500〜-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"
!
! -400 以下: DC ユーティリティのエラー
!
case(DC_ENOTINIT)
msg = " object (" // trim(cause_string) //") is not initialized"
case(DC_EBADUNIT)
msg = " unit (" // trim(cause_string) //") is invalid"
case(DC_EBADCALTYPE)
write(message, "(' calendar type (', i4, ') is invalid')") cause_int
msg = trim(message)
case(DC_EBADTIMEZONE)
msg = " time zone (" // trim(cause_string) //") is invalid"
!
! -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)
!
!
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