set_io_err_handler() は、ユーザー定義のルーチンを宣言し、特定の入力論理装置でエラーが検出されたときにそのルーチンを呼び出せるようにします。
get_io_err_handler() は、現在宣言されているエラー処理ルーチンのアドレスを戻します。
これらのルーチンはモジュール化されたサブルーチンで、呼び出し側のルーチンに USE SUN_IO_HANDLERS が示されている場合のみアクセスすることができます。
USE SUN_IO_HANDLERS call set_io_err_handler(iu, subr_name, istat) |
|||
iu |
INTEGER*8 |
入力 |
論理装置番号 |
subr_name |
EXTERNAL |
入力 |
ユーザーが提供するエラーハンドラサブルーチンの名前 |
istat |
INTEGER*4 |
出力 |
状態を戻す |
USE SUN_IO_HANDLERS call get_io_err_handler(iu, subr_pointer, istat) |
|||
iu |
INTEGER*8 |
入力 |
論理装置番号 |
subr_pointer |
POINTER |
出力 |
宣言されているハンドラルーチンのアドレス |
istat |
INTEGER*4 |
出力 |
状態を戻す |
SET_IO_ERR_HANDLER は、論理装置 iu で入力エラーが発生したときに入出力エラーハンドラとして使用できるようにユーザー定義のサブルーチン subr_name を設定します。iu は、フォーマットされたファイル用に接続された Fortran 論理装置である必要があります。エラーの場合は istat に 0 以外の値が設定され、エラー以外の場合は 0 が設定されます。
たとえば、論理装置 iu をオープンする前に SET_IO_ERR_HANDLER を呼び出すと、istat には 1001 ("不正な装置") が設定されます。subr_name に何も指定しない場合は、ユーザーのエラー処理がオフになり、プログラムは Fortran のデフォルトエラー処理に戻ります。
対象の論理装置のエラーハンドラとして現在使用されている関数のアドレスを取得するには、GET_IO_ERR_HANDLER を使用します。たとえば、ほかのハンドラルーチンに切り替える前に現在の入出力を保存するには、GET_IO_ERR_HANDLER を呼び出します。エラーハンドラはあとで、保存されていた値まで戻ることができます。
subr_name は、特定の論理装置 iu で入出力エラーを処理するためのユーザー定義ルーチンの名前です。実行時入出力ライブラリは、関連するすべての情報を subr_name へ渡し、ルーチンで問題点を診断し、可能であれば問題を修正してから処理を続行します。
ユーザー定義のエラーハンドラルーチンに対するインタフェースは次のとおりです。
SUBROUTINE SUB_NAME(UNIT, SRC_FILE, SRC_LINE, DATA_FILE, FILE_POS, CURR_BUFF, CURR_ITEM, CORR_CHAR, CORR_ACTION ) INTENT (IN) UNIT, SRC_FILE, SRC_LINE, DATA_FILE INTENT (IN) FILE_POS, CURR_BUFF, CURR_ITEM INTENT (OUT) CORR_CHAR, CORR_ACTION |
|||
UNIT |
INTEGER*8 |
入力 |
エラーが検出された入力ファイルの論理装置番号 |
SRC_FILE |
CHARACTER*(*) |
入力 |
入力操作を行なった、Fortran のソースファイル名 |
SRC_LINE |
INTEGER*8 |
入力 |
SRC_FILE で入力操作のエラーが検出された行番号 |
DATA_FILE |
CHARACTER*(*) |
入力 |
読み取り中のデータファルの名前。このパラメータは、ファイルが、オープンされた外部ファイルの場合のみ使用できる。名前が無効 (論理装置 5 など) の場合は、 DATA_FILE に長さゼロの文字データ項目が設定される。 |
FILE_POS |
INTEGER*8 |
入力 |
入力ファイルの現在の位置 (バイト)。DATA_FILE の名前がわかっている場合のみ定義される。 |
CURR_BUFF |
CHARACTER*(*) |
入力 |
入力レコードの残りのデータが含まれている文字列。文字列の先頭が不正な文字となっている。 |
CURR_ITEM |
INTEGER*8 |
入力 |
読み取られたレコードの入力項目数 (エラーが検出された場合の項目数も含む)。例: READ(12,10)L,(ARR(I),I=1,L) CURR_ITEM の値が 15 の場合は、 ARR の 14 番目の要素の読み取り中にエラーが発生したことを表す。L は最初の項目、ARR(1) は 2 番目の項目、のように順次に表す。 |
CORR_CHAR |
CHARACTER |
出力 |
ハンドラが返すように指定された、ユーザー定義の正しい文字。この値は、CORR_ACTION がゼロ以外の場合のみ使用する。CORR_CHAR が不正な文字の場合は、正しい文字が返されるまでハンドラが繰り返し呼び出される。これにより無限ループが発生する可能性があるが、無限ループにならないように注意する必要がある。 |
CORR_ACTION |
INTEGER |
出力 |
入出力ライブラリで行う修正措置を指定する。値がゼロの場合は特別な処理は不要で、ライブラリはデフォルトのエラー処理に戻る。値が 1 の場合は、入出力エラー処理ルーチンに CORR_CHAR を戻す。 |
入出力ハンドラでできる処理は、1 文字をほかの文字に置き換えることだけです。1 文字を 複数の文字に置き換えることはできません。
エラーリカバリのアルゴリズムでは、読み取り中の不正な文字を置き換えることのみ可能で、別のコンテキストですでに不正な文字として読み取られた文字を置き換えることはできません。たとえば、並びによる読み取りで、正しい入力が "1.2345 9.8765" である場合に入力が "1.234509.8765" であると、これは有効な数字でないため、入出力ライブラリは 2 つめのピリオドでエラーになります。ただし、その時点までは、後ろに戻って '0' を空白に戻すことはできません。
現在は、このエラー処理の機能は、namelist のとおりに読み取った入力に対しては機能していません。namelist のとおりに読み取った入力を処理している場合は、エラーが発生しても、指定した入出力エラーハンドラは呼び出されません。
入出力エラーハンドラは、(内部ファイルではなく) 外部ファイルに対してのみ設定されます。これは、内部ファイルには、関連付けられる論理装置がないためです。
入出力エラーハンドラは、構文エラーに対してのみ呼び出されます。システムエラーやセマンティックエラー (入力値のオーバーフローなど) では呼び出されません。
ユーザー定義の入出力エラーハンドラが、入出力ライブラリに不正な文字を渡すようになっている場合は、ユーザー定義の入出力エラーハンドラを繰り返し呼び出すことになり、無限ループが発生することがあります。ファイルの同じ位置でエラーが発生する場合、エラーハンドラは終了するべきです。このようにするには、CORR_ACTION をゼロに設定する方法があります。このようにすると、入出力ライブラリは通常のエラー処理を続行します。