| 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_ERRNO 番より小さい値は、 各々のユーザが適宜エラーコードを 定義して利用するために空けてあります。
エラーではない状態を表す非エラーコードは 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_ERRNO  ] 
 | 
| 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
    character(len = *), intent(out):: msg
    character(len = 180):: message
    character(len = 20):: errno_c
    character(len = 20):: cause_int_c
  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_ERRNO)
      if (len(trim(adjustl(cause_string))) < 1) then
        cause_string = 'Unknown error'
      end if
      if (cause_int_valid) then
        write(cause_int_c, "(i8)") cause_int
        msg = trim(cause_string) // ' (' // trim(adjustl(cause_int_c)) // ')'
      else
        msg = trim(cause_string)
      end if
    case default
      goto 999
    end select
    write(errno_c, "(i8)") errno
    msg =  '*** ERROR (Code ' // trim(adjustl(errno_c))  // ') [' // trim(cause_location) // '] ***  ' // trim(msg)
    return
999 continue
    if (len(cause_string) > 0) then
      message = nf_strerror(errno)
      write(errno_c, "(i8)") errno
      msg =  '*** ERROR (Code ' // trim(adjustl(errno_c)) // ') [' // trim(cause_location)             // '('   // trim(cause_string) // ')] ***  ' // trim(message)
    else if (cause_int_valid) then
      message = nf_strerror(errno)
      write(errno_c, "(i8)") errno
      write(cause_int_c, "(i8)") cause_int
      msg =  '*** ERROR (Code ' // trim(adjustl(errno_c)) // ') [' // trim(cause_location)             // '('   // trim(adjustl(cause_int_c)) // ')] ***  ' // trim(message)
    else
      message = nf_strerror(errno)
      write(errno_c, "(i8)") errno
      msg =  '*** ERROR (Code ' // trim(adjustl(errno_c))  // ') [' // 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_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
| 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_ERRNO 番より小さい エラーコードは空けてあります。USR_ERRNO より小さい値をエラーコードに与えると, StoreError は以下の形式の文字列を装置 "*" に出力してプログラムを 終了させます。より安易に使えるメッセージ出力およびエラー発生の ためのモジュールとして dc_message も用意してあるので そちらも参照してください。
     
    *** ERROR (Code number) [where] ***  cause_c
     
    *** ERROR (Code number) [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_ERRNO 番より小さい
    ! エラーコードは空けてあります。<b><tt>USR_ERRNO</tt></b>
    ! より小さい値をエラーコードに与えると,
    ! StoreError は以下の形式の文字列を装置 "*" に出力してプログラムを
    ! 終了させます。より安易に使えるメッセージ出力およびエラー発生の
    ! ためのモジュールとして *dc_message* も用意してあるので
    ! そちらも参照してください。
    !
    !      
    !     *** ERROR (Code number) [where] ***  cause_c
    !      
    !     *** ERROR (Code number) [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)) then
      cause_int = cause_i
      cause_int_valid = .true.
    else
      cause_int_valid = .false.
    end if
    if (present(err)) then
      err = (number /= DC_NOERR)
      return
    endif
    if (number == DC_NOERR) return
    call DumpError
  end subroutine StoreError