モジュール境界の決め方

ソースファイルへの分割単位は原則として PROGRAM-ID 単位とします。ただし ENTRY 文が使われている場合は ENTRY 文ごとに別モジュールとして扱うことも検討してください。

分割単位条件注意点
PROGRAM-ID 単位 基本。IDENTIFICATION DIVISION から END PROGRAM まで1ファイル。 ネストされたプログラム(NESTED PROGRAM)は一緒に残すか分離するか方針を決める。
ENTRY 文単位 1つの PROGRAM-ID に複数の ENTRY 文が存在し、それぞれ独立して CALL される場合。 DATA DIVISION は共有されるため、分離後も1ファイルにまとめた方が安全な場合がある。
機能単位(論理分割) 処理の意味的なまとまりで分割したい場合(マイグレーション目的)。 元のバイナリ境界とは一致しないため、検証コストが増大する。モダナイゼーション工程で行う。

命名規則とディレクトリ設計

project-root/ ├── src/ # ソースコード │ ├── main/ # メインプログラム(CALL される側でないもの) │ │ ├── ORDMAIN.cbl # PROGRAM-ID. ORDMAIN │ │ └── INVMAIN.cbl │ └── sub/ # サブプログラム(CALL される側) │ ├── ORDSUB01.cbl │ └── ORDSUB02.cbl ├── copybook/ # コピーブック(共通定義) │ ├── ORDSTRC.cpy # 受注データ構造 │ └── COMCONST.cpy # 共通定数 ├── jcl/ # JCL(メインフレームの場合) │ └── COMPILE.jcl └── test/ # テストデータ・検証スクリプト ├── input-sample.dat └── expected-output.dat
対象命名規則の例理由
ソースファイル名 PROGRAM-ID の値.cbl(大文字) PROGRAM-ID と1対1対応にすることで検索性が上がる
コピーブックファイル名 共通定義名.cpy COPY 文で指定する名前と合わせる
ディレクトリ 小文字・ハイフン区切り(src/ copybook/ Linux 環境での大文字小文字問題を避ける

コピーブックの整理と重複排除

コピーブックは複数のプログラムから参照されるため、重複した定義が存在することがあります。以下の手順で整理します。

Shell — コピーブックの重複定義検出
# 各ソースファイルでの COPY 文参照先を一覧化
grep -ih "^\s*COPY\b" src/**/*.cbl | grep -oiE "'[A-Z0-9-]+'" | tr -d "'" | sort | uniq -c | sort -rn

# 同名コピーブックが複数箇所に存在しないか確認
find . -name "*.cpy" -o -name "*.CPY" | xargs -I{} basename {} | sort | uniq -d

# 内容が同一のコピーブックを検出(md5sum比較)
find copybook/ -type f | xargs md5sum | sort | awk '{print $1}' | uniq -d

⚠️ 同名・内容違いのコピーブックに注意

同じ名前でも環境ごと(テスト用・本番用)に内容が違うコピーブックが存在することがあります。COPY 文のライブラリ検索順序(-I オプションの指定順)を確認し、意図したコピーブックが使われているか検証してください。

分割作業を自動化するスクリプト例

Shell — コンパイルリストからPROGRAM-ID単位でファイル分割
#!/bin/bash
# 1つの大きな .lst ファイルを PROGRAM-ID 単位に分割して .cbl を生成する

INPUT="combined.lst"
OUTDIR="src"
mkdir -p "$OUTDIR"

current_prog=""
current_file=""

while IFS= read -r line; do
  # PROGRAM-ID 行を検出
  if echo "$line" | grep -qi "PROGRAM-ID\.\s*\([A-Z0-9-]\+\)"; then
    prog=$(echo "$line" | grep -oiE "[A-Z0-9-]{2,30}\." | tail -1 | tr -d ".")
    if [ -n "$prog" ]; then
      current_prog="$prog"
      current_file="$OUTDIR/${prog}.cbl"
      echo "       IDENTIFICATION DIVISION." > "$current_file"
    fi
  fi
  # 現在のプログラムに追記
  if [ -n "$current_file" ]; then
    echo "$line" >> "$current_file"
  fi
done < "$INPUT"

echo "分割完了: $(ls $OUTDIR/*.cbl | wc -l) ファイル生成"

次の章では…

PART 07 では、再構成したソースコードを再コンパイルして元のロードモジュールと等価であることを確認する「検証」フェーズを解説します。

→ PART 07 — 分離結果の検証へ