モジュール境界の決め方
ソースファイルへの分割単位は原則として 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 環境での大文字小文字問題を避ける |
コピーブックの整理と重複排除
コピーブックは複数のプログラムから参照されるため、重複した定義が存在することがあります。以下の手順で整理します。
# 各ソースファイルでの 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 オプションの指定順)を確認し、意図したコピーブックが使われているか検証してください。
分割作業を自動化するスクリプト例
#!/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) ファイル生成"