Files
cobol-java-v3/runners/cobol_runner.py
T
hangshuo652 40e8a50ab4 fix: gcov Windows本地化 + runner合并 + 决策覆盖率修复
- gcov从WSL 15.2改为Windows MinGW 9.2.0,消除.gcno格式不匹配
- coverage.py去除leaf_stats复位bug(决策覆盖率恢复)
- runner.py合并V3编译+SOURCE分组执行+出力保存
- __init__.py gcov条件/outdir解析修复
2026-07-02 21:26:51 +08:00

116 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import subprocess
from pathlib import Path
from runners.runner import BuildResult, RunResult
class CobolRunner:
"""COBOL 程序编译·执行器。
非DB程序(KIN系)使用 ``compile_with_links()`` + ``run_file_based()``。
DB程序/旧式调用保持 ``compile()`` + ``run()`` 不变。
"""
# ── 旧式(orchestrator.py 互換)──
def compile(self, src: str, dialect="ibm", gcov: bool = False) -> BuildResult:
"""旧式编译(-std=ibm-strict)。orchestrator.py 用,不修改。"""
stem = Path(src).stem
out = str(Path(src).parent / stem)
cmd = ["cobc", "-x", f"-std={dialect}-strict", "-o", out, src]
if gcov:
cmd = ["cobc", "-x", f"-std={dialect}-strict", "--coverage", "-o", out, src]
p = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
return BuildResult(success=p.returncode == 0, artifact_path=out, log=p.stdout + p.stderr)
def run(self, binary: str, input_path: str, output_path: str) -> RunResult:
"""旧式执行(stdin→stdout)。orchestrator.py 用。"""
with open(input_path, "rb") as f:
data = f.read()
p = subprocess.run([binary], input=data, capture_output=True, timeout=30)
Path(output_path).write_bytes(p.stdout)
return RunResult(success=p.returncode == 0)
# ── 新式(非DB KIN系向け)──
def compile_with_links(self, src: str, work_dir: str,
copybook_dirs: list[str] | None = None,
sub_objects: list[str] | None = None,
gcov: bool = False) -> BuildResult:
"""编译主程序 + 链接 SUB.o,不使用 -std=ibm-strict。
Args:
src: COBOL 源文件路径。
work_dir: 编译工作目录(.gcno 产出位置,必须提前存在)。
copybook_dirs: COPYBOOK 搜索路径列表(映射为 -I 参数)。
sub_objects: SUB*.o 文件路径列表(静态链接)。
gcov: 是否启用 ``--coverage``。
Returns:
BuildResultartifact_path 指向 .exe 的绝对路径。
"""
work_path = Path(work_dir).resolve()
work_path.mkdir(parents=True, exist_ok=True)
stem = Path(src).stem
exe_path = work_path / f'{stem}.exe'
cmd = ["cobc", "-x", "-g"]
if gcov:
cmd.append("--coverage")
for cpy in (copybook_dirs or []):
cmd.extend(["-I", str(cpy)])
cmd.extend(["-o", str(exe_path), str(src)])
cmd.extend(str(o) for o in (sub_objects or []))
orig = os.getcwd()
try:
os.chdir(str(work_path))
p = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
finally:
os.chdir(orig)
return BuildResult(
success=p.returncode == 0,
artifact_path=str(exe_path),
log=(p.stdout + p.stderr)[:2000],
)
def run_file_based(self, binary: str, run_dir: str,
input_files: dict[str, str] | None = None,
timeout: int = 60) -> RunResult:
"""基于文件的执行。将输入文件复制到 run_dir 后启动程序。
Args:
binary: 可执行文件路径。
run_dir: 执行目录(CWD,输入文件在此,输出文件也在此)。
input_files: {assign_name: source_path} 的映射。
如 ``{"KIN04R01": "/path/to/input/KIN04R01"}``。
timeout: 超时秒数。
Returns:
RunResult。
"""
run_path = Path(run_dir).resolve()
run_path.mkdir(parents=True, exist_ok=True)
# 入力ファイル配置
for assign_name, src_path in (input_files or {}).items():
src = Path(src_path)
if src.exists():
dst = run_path / assign_name
import shutil
shutil.copy2(str(src), str(dst))
orig = os.getcwd()
try:
os.chdir(str(run_path))
p = subprocess.run([str(binary)], capture_output=True, text=True, timeout=timeout)
finally:
os.chdir(orig)
return RunResult(
success=p.returncode == 0,
log=(p.stdout + p.stderr)[:2000],
)