Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions cobc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@

2026-03-16 Uttam Singh Bhadauriya <uttamsinghbhadoriya23@gmail.com>

* pplex.l: add EXEC_STATE exclusive start condition to
tokenize EXEC <TAG> ... END-EXEC blocks; add AREA_A lookahead
rule for EXEC; return INCLUDE token for INCLUDE keyword,
plain TOKEN for words; consume all other content silently
* ppparse.y: add exec_statement grammar rule dispatched
from statement_no_replace; EXEC TAG INCLUDE handled as COPY
(full copybook expansion with -I and -ffold-copy support);
all other EXEC TAG blocks warn at "unsupported" level
(defaulting to error) and are ignored; add _exec_token_list
to consume body tokens for parsing purposes only

2025-12-29 Roger Bowler <rbowler@snipix.net>

* tree.c (finalize_file): if file is EXTFH enabled then don't warn for
Expand Down
15 changes: 15 additions & 0 deletions cobc/pplex.l
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ MAYBE_AREA_A [ ]?#?
%x CONTROL_STATEMENT_STATE
%x DISPLAY_DIRECTIVE_STATE
%x IMP_DIRECTIVE_STATE
%X EXEC_STATE

%%

Expand Down Expand Up @@ -501,6 +502,7 @@ MAYBE_AREA_A [ ]?#?
^{AREA_A}[ \n]*/"COPY"[ ,;\n] { count_newlines (yytext); }
^{AREA_A}[ \n]*/"INCLUDE"[ ,;\n] { count_newlines (yytext); }
^{AREA_A}[ \n]*/"REPLACE"[ ,;\n] { count_newlines (yytext); }
^{AREA_A}[ \n]*/"EXEC"[ ,;\n] { count_newlines (yytext); }

"COPY"/[ ,;\n] {
yy_push_state (COPY_STATE);
Expand All @@ -525,6 +527,11 @@ MAYBE_AREA_A [ ]?#?
return REPLACE;
}

"EXEC"/[ ,;\n] {
BEGIN(EXEC_STATE);
return EXEC;
}

^{MAYBE_AREA_A}.{6}[ ]*"*CONTROL" |
^{MAYBE_AREA_A}.{6}[ ]*"*CBL" {
BEGIN CONTROL_STATEMENT_STATE;
Expand Down Expand Up @@ -569,6 +576,14 @@ MAYBE_AREA_A [ ]?#?
}
}

<EXEC_STATE>{
"END-EXEC"([ \t]*\.)? { BEGIN (INITIAL); return END_EXEC; }
"INCLUDE" { return INCLUDE; }
[A-Za-z0-9][A-Za-z0-9-]* { pplval.s = cobc_plex_strdup (yytext); return TOKEN; }
\n { newline_count++; }
. { /* silently consumed */ }
}

<SUBSTITUTION_SECTION_STATE,
CONTROL_DIVISION_STATE>{
"REPLACE" {
Expand Down
32 changes: 32 additions & 0 deletions cobc/ppparse.y
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,9 @@ ppparse_clear_vars (const struct cb_define_struct *p)
%token <s> VARIABLE_NAME "Variable"
%token <s> LITERAL "Literal"

%token EXEC
%token END_EXEC "END_EXEC"

%type <s> _copy_in
%type <s> copy_source
%type <s> _literal
Expand Down Expand Up @@ -830,6 +833,7 @@ statement:

statement_no_replace:
copy_statement
| exec_statement
| directive TERMINATOR
| listing_statement
| CONTROL_STATEMENT control_options _dot TERMINATOR
Expand Down Expand Up @@ -1726,6 +1730,34 @@ replacing_list:
}
;

_exec_token_list:
/* empty */
| _exec_token_list TOKEN
{
/* should be handled by preparser, ignored
if seen here purely for parsing reasons */
}
;

exec_statement:
EXEC TOKEN INCLUDE copy_source END_EXEC
{
/* EXEC TAG INCLUDE copybook — handle as COPY */
fputc ('\n', ppout);
ppcopy ($4, NULL, NULL);
}
| EXEC TOKEN _exec_token_list END_EXEC
{
/* EXEC TAG ... END-EXEC — warn and ignore */
cb_warning (cb_warn_unsupported,
_("EXEC %s statement ignored - no preprocessor configured"), $2);
}
| EXEC error END_EXEC
{
yyerrok;
}
;

text_src:
EQEQ token_list EQEQ
{
Expand Down
88 changes: 88 additions & 0 deletions tests/testsuite.src/syn_definition.at
Original file line number Diff line number Diff line change
Expand Up @@ -2947,3 +2947,91 @@ AT_DATA([prog.cob], [

AT_CHECK([$COMPILE_ONLY -Wno-unfinished prog.cob], [0], [], [])
AT_CLEANUP


### GnuCOBOL Test Suite - EXEC block handling


AT_SETUP([EXEC empty block])
AT_KEYWORDS([exec extensions])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
PROCEDURE DIVISION.
EXEC END-EXEC.
STOP RUN.
])

AT_CHECK([$COMPILE_ONLY prog.cob], [1], [],
[prog.cob:5: error: syntax error, unexpected END_EXEC, expecting Word or Literal
])

AT_CLEANUP


AT_SETUP([EXEC SQL empty block])
AT_KEYWORDS([exec sql extensions])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
PROCEDURE DIVISION.
EXEC SQL END-EXEC.
STOP RUN.
])

AT_CHECK([$COMPILE_ONLY -Werror=unsupported prog.cob], [1], [],
[prog.cob:5: error: EXEC SQL statement ignored - no preprocessor configured
])

AT_CLEANUP


AT_SETUP([EXEC SQL statement ignored])
AT_KEYWORDS([exec sql extensions])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
PROCEDURE DIVISION.
EXEC SQL CONNECT RESET END-EXEC.
STOP RUN.
])

AT_CHECK([$COMPILE_ONLY -Werror=unsupported prog.cob], [1], [],
[prog.cob:5: error: EXEC SQL statement ignored - no preprocessor configured
])

AT_CLEANUP


AT_SETUP([EXEC SQL INCLUDE sqlca and copybook])
AT_KEYWORDS([exec sql include sqlca extensions])

AT_DATA([emprec.cpy], [
01 EMP-TABLE.
03 ENO PIC S9(4) COMP.
03 LNAME PIC X(10).
])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
DATA DIVISION.
WORKING-STORAGE SECTION.
EXEC SQL
INCLUDE SQLCA
END-EXEC.
EXEC SQL
INCLUDE EMPREC
END-EXEC.
PROCEDURE DIVISION.
DISPLAY SQLCODE.
MOVE 1 TO ENO.
STOP RUN.
])

AT_CHECK([$COMPILE_ONLY -ffold-copy=LOWER prog.cob], [0], [], [])

AT_CLEANUP
Loading