【テクニカル・上級編】ON ENDFILEユニットによるストリーム入出力の終了制御 – PL/Iの基本構文とデータ制御実践ガイド

PL/Iの深淵:`ON ENDFILE`による制御フローと、次世代移行を見据えた「終わらせ方」の美学

メインフレームのバッチ処理において、ファイル読み込みの「幕引き」は、単なるループ脱出以上の意味を持ちます。特に、PL/Iで書かれた数十万行のレガシーコードを紐解く際、`ON ENDFILE`ユニットの挙動を正しく理解していない設計者は、移行先(JavaやC#)で必ずと言っていいほど「例外処理の設計破綻」に直面します。

今日は、単なる文法解説ではなく、コンパイラの実装レベルから見た`ON ENDFILE`の挙動と、モダンなシステム設計への橋渡しについて語りましょう。

1. `ON ENDFILE`は単なる「終了」ではない

多くの開発者は、`ON ENDFILE`を「ファイルが終わったらここに来る」というだけのイベントハンドラだと誤解しています。しかし、これはIBMのコンパイラが提供する「条件処理機能(Condition Handling)」の一種です。

実装の勘所

1
/ ファイル終了時のハンドラ定義 /
ON ENDFILE(INPUT_FILE) BEGIN;
/ 終了フラグを立てる等の後処理 /
EOF_FLG = ‘1’B;
/ 制御を戻す場所を明示する必要がある /
GOTO READ_LOOP_EXIT;
END;

READ_LOOP: DO WHILE(EOF_FLG = ‘0’B);
READ FILE(INPUT_FILE) INTO(REC_BUFFER);
/ 処理ロジック /
END;

READ_LOOP_EXIT: ;
/ 終了後のクリーンアップ処理 /

ここで重要なのは、`GOTO`の使用です。`ON`ユニットから正常に復帰(`SYSTEM`または`SNAP`を伴わない場合)すると、制御は「`READ`文の直後の命令」に戻ろうとします。しかし、ファイル末尾に達した状態で再度`READ`が走れば、再び`ENDFILE`条件が発火し、無限ループの地獄へ真っ逆さまです。

2. メモリ管理とポインタの罠:動的構造体の危険な誘惑

基幹システムのバッチでは、入力レコードの可変長対応のために、ベース付き変数(`BASED`)とポインタを多用します。ここで`ENDFILE`と絡むのが「ダングリングポインタ」の問題です。

1
DCL REC_PTR PTR;
DCL REC_BUF CHAR(100) BASED(REC_PTR);

/ 動的割り当て /
ALLOCATE REC_BUF;

/ 終了処理時にポインタをクリアし忘れると /
/ 次のバッチプロセスでメモリダンプ(S0C4)の餌食になる /

マイグレーション時にJavaのガベージコレクションに慣れ切った若手エンジニアが最も苦戦するのがこの部分です。PL/Iはメモリの「所有権」をプログラマが完全に制御します。`ENDFILE`が発火した際、確実に`FREE`を呼び出し、ポインタを`NULL()`に置換する。この「後始末の作法」をコードに埋め込まなければ、移行先でのメモリリークは必至です。

3. 移行設計の観点:DB2やCICSとの「整合性」

もしこのコードがCICS環境で動いているなら、`ENDFILE`ハンドラ内で`EXEC CICS SYNCPOINT`や`ROLLBACK`を打つ必要があるかもしれません。

特に注意すべきはパックデシマル(PIC S9(7)V99 COMP-3)の符号反転です。EBCDICからASCII/UTF-8に変換する際、あるいはデータ移行時のバイナリ変換で、最下位ニブルの符号ビットが破壊されることがあります。これに`ENDFILE`制御が絡むと、「最後の1レコードが処理されないまま異常終了する」といった非常に追跡困難なバグを引き起こします。

移行スペシャリストへの提言

Javaへの移行を検討しているなら、`ON ENDFILE`ユニットを「例外処理のcatchブロック」へと安直に変換してはいけません。

1. 状態遷移の可視化: PL/Iの`ON`ユニットは非局所的な分岐(Non-local jump)を伴います。これをJavaの`try-catch`に直す際、読み込み状態を保持するStateパターンを導入し、制御フローを明確に分離してください。
2. ダンプ解析の備え: 本番環境で`S0C7`や`S0C4`が発生した際、コンパイラの最適化(`OPTIMIZE(2)`など)が掛かっていると、レジスタの値とソースコードが一致しません。移行先でも、ログ出力の粒度を「どのレコードのどのフィールドで例外が起きたか」をトレースできるレベルまで高めておくことが、信頼性担保の鍵となります。

結びに:レガシーは「生き物」である

PL/Iのコードを書き換えるということは、単なるプログラミング言語の変換ではありません。そのシステムが何十年もかけて蓄積してきた「ビジネスロジックの重み」を、現代的なアーキテクチャへと脱皮させる作業です。

`ON ENDFILE`という小さな構文一つを取っても、その背後にはメモリ管理、例外の階層構造、そしてハードウェアの仕様が詰まっています。この「泥臭い仕様」を愛し、理解した上で次世代へ繋ぐことこそが、私たちメインフレームアーキテクトに課せられた矜持ではないでしょうか。

もし今、あなたの手元のコードで`ENDFILE`が怪しい挙動を見せているなら、それはシステムが「もっと丁寧に扱ってくれ」と叫んでいる証拠です。深層を覗き込み、正しく制御してやってください。

タイトルとURLをコピーしました