diff --git a/gitgalaxy/standards/language_standards/languages/cobol.py b/gitgalaxy/standards/language_standards/languages/cobol.py index 0bdb91e1e..1059a15b0 100644 --- a/gitgalaxy/standards/language_standards/languages/cobol.py +++ b/gitgalaxy/standards/language_standards/languages/cobol.py @@ -142,7 +142,27 @@ # `CONTINUE.` is `.`, not a paragraph header. Confirmed FP against # language-crucible v1.2.0 (che-che4z_nist_ccvs85/IF4014.2.cbl:30 etc., # cobol-sample_SAMPLE1.cbl). Same class as LOCAL-STORAGE (#1890). - r"DELETE|OPEN|CLOSE|CONTINUE|PROGRAM-ID|CLASS-ID|SECTION|DIVISION|END-[A-Za-z0-9_-]+)(?=[ \t\n.]))" + r"DELETE|OPEN|CLOSE|CONTINUE|" + # #2538: CEE3DMP/CEEMOUT/CEEDUMP are Language Environment (LE) + # runtime diagnostic service names -- already recognized elsewhere + # in this file as the `telemetry` class (see that rule below) -- not + # paragraph names. A bare `CEE3DMP.` statement call sitting on its + # own line, indented into Area B, was being swept up as a paragraph + # header: this shield had no entry for them, and the post-sequence- + # area slot (`[ \t]*`, item 1 above) tolerates any horizontal + # indent to support genuinely free-format source, so it doesn't + # distinguish Area A (paragraph names, columns 8-11) from Area B on + # its own. Confirmed FP: `data/cobol/b.cpy` (che-che4z #1096 control + # corpus) planted `CEE3DMP.`/`CEEMOUT.` in Area B and both were + # captured as extra paragraphs (func_start=5 for 3 real paragraphs). + # Scoped narrowly to these three known LE tokens, same fix class as + # CONTINUE/LOCAL-STORAGE above, rather than a general Area-A column + # anchor: the sequence-area consumer in item 1 can't reliably tell + # a genuine fixed-format sequence number from 6 free-format leading + # spaces, so a real structural fix needs file-level fixed/free- + # format detection -- out of scope for this narrow token exclusion. + r"CEE3DMP|CEEMOUT|CEEDUMP|" + r"PROGRAM-ID|CLASS-ID|SECTION|DIVISION|END-[A-Za-z0-9_-]+)(?=[ \t\n.]))" # 4. THE DIVISION/SECTION HEADER SHIELD # Bans any word followed immediately by DIVISION (e.g., "PROCEDURE DIVISION"). # Upgraded to `[ \t\n]+` to prevent vertical ghosting. diff --git a/tests/extraction/languages/test_cobol.py b/tests/extraction/languages/test_cobol.py index bde3126a0..57510667d 100644 --- a/tests/extraction/languages/test_cobol.py +++ b/tests/extraction/languages/test_cobol.py @@ -66,6 +66,9 @@ " * TargetFunc.", # column-7 comment marker "123456* TargetFunc.", # column-7 comment with real sequence numbers " *> TargetFunc.", # free-format inline comment marker + "000600 CEE3DMP.", # #2538: LE diagnostic call, Area B, not a paragraph + "000700 CEEMOUT.", # #2538: LE diagnostic call, Area B, not a paragraph + " CEEDUMP.", # #2538: same LE-service class, free-format indent ], "pathological": [ ("TargetFunc \n SECTION.", "TargetFunc"), # carried-forward: margin-hugging + vertical split diff --git a/tests/extraction/languages/test_cobol_strict.py b/tests/extraction/languages/test_cobol_strict.py index a835bcc14..86c346d36 100644 --- a/tests/extraction/languages/test_cobol_strict.py +++ b/tests/extraction/languages/test_cobol_strict.py @@ -365,6 +365,11 @@ def test_cobol_func_start_excludes_reserved_verbs_and_headers(): WRITE, EXIT, GOBACK, STOP, DISPLAY, DIVISION, SECTION headers) -- these are false alarms from the sweep picking up func_start's own exclusion list text, not a real double-match risk. + + #2538 extends this same list: CEE3DMP/CEEMOUT/CEEDUMP (the `telemetry` + rule's LE runtime diagnostic service names) share the same "bare + token + period" shape as a paragraph header when indented into Area B, + with nothing in the old shield to exclude them. """ func_start = COBOL_RULES["func_start"] for reserved in ( @@ -375,6 +380,9 @@ def test_cobol_func_start_excludes_reserved_verbs_and_headers(): " PROCEDURE DIVISION.", " STOP RUN.", " GOBACK.", + " CEE3DMP.", + " CEEMOUT.", + " CEEDUMP.", ): assert not func_start.search(reserved), f"func_start incorrectly matched reserved line {reserved!r}"