diff --git a/cobc/ChangeLog b/cobc/ChangeLog index f95300de1..f972a4419 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -1,4 +1,10 @@ +2024-04-25 Boris Eng + + * cobc.h, pplex.l, ppparse.y: new >>IMP INCLUDE directive to include + multiple header files in the C generated code. Has the same behavior as the + --include compiler option. + 2024-03-17 Fabrice Le Fessant Emilien Lemaire diff --git a/cobc/cobc.h b/cobc/cobc.h index 7b5f30bbd..33f7245a6 100644 --- a/cobc/cobc.h +++ b/cobc/cobc.h @@ -597,6 +597,7 @@ extern unsigned int ppparse_verify (const enum cb_support tag, extern void ppparse_error (const char *); extern int cobc_deciph_source_format (const char *); +extern int cobc_deciph_header_filename (const char *); extern void cobc_set_source_format (const enum cb_format); extern enum cb_format cobc_get_source_format (void) COB_A_PURE; extern int cobc_get_indicator_column (void) COB_A_PURE; diff --git a/cobc/pplex.l b/cobc/pplex.l index 02bb2640c..ade23acdf 100644 --- a/cobc/pplex.l +++ b/cobc/pplex.l @@ -227,6 +227,7 @@ MAYBE_AREA_A [ ]?#? %x ALNUM_LITERAL_STATE %x CONTROL_STATEMENT_STATE %x DISPLAY_DIRECTIVE_STATE +%x IMP_DIRECTIVE_STATE %% @@ -360,6 +361,12 @@ MAYBE_AREA_A [ ]?#? return CALL_DIRECTIVE; } +^{MAYBE_AREA_A}[ ]*">>"[ ]?"IMP" { + /* GnuCOBOL 3.3 extension */ + BEGIN IMP_DIRECTIVE_STATE; + return IMP_DIRECTIVE; +} + ^{MAYBE_AREA_A}[ ]*">>"[ ]*\n { /* empty 2002+ style directive */ cb_plex_warning (COBC_WARN_FILLER, newline_count, @@ -724,6 +731,7 @@ ELSE_DIRECTIVE_STATE, ENDIF_DIRECTIVE_STATE, ALNUM_LITERAL_STATE, CONTROL_STATEMENT_STATE, +IMP_DIRECTIVE_STATE, COBOL_WORDS_DIRECTIVE_STATE>{ \n { BEGIN INITIAL; @@ -993,6 +1001,14 @@ ENDIF_DIRECTIVE_STATE>{ } } +{ + "INCLUDE" { return INCLUDE; } + {ALNUM_LITERAL} { + pplval.s = cobc_plex_strdup (yytext); + return TOKEN; + } +} + { "IS" { return IS; } "NOT" { return NOT; } @@ -1867,6 +1883,14 @@ int cobc_deciph_source_format (const char *sfname) { return 1; } +int cobc_deciph_header_filename (const char *filename) { + size_t n = strlen(filename); + if (filename[n-2] == '.' && filename[n-1] == 'h') { + return 0; + } + return 1; +} + void plex_clear_vars (void) { diff --git a/cobc/ppparse.y b/cobc/ppparse.y index 76b3c9a58..fbac2ea84 100644 --- a/cobc/ppparse.y +++ b/cobc/ppparse.y @@ -741,6 +741,9 @@ ppparse_clear_vars (const struct cb_define_struct *p) %token WITH %token LOCATION +%token IMP_DIRECTIVE +%token INCLUDE + %token TERMINATOR "end of line" %token TOKEN "Word or Literal" @@ -768,6 +771,7 @@ ppparse_clear_vars (const struct cb_define_struct *p) %type alnum_equality_list %type ec_list %type unquoted_literal +%type imp_include_sources %type _copy_replacing %type replacing_list @@ -838,6 +842,7 @@ directive: | TURN_DIRECTIVE turn_directive | LISTING_DIRECTIVE listing_directive | LEAP_SECOND_DIRECTIVE leap_second_directive +| IMP_DIRECTIVE imp_directive | IF_DIRECTIVE { current_cmd = PLEX_ACT_IF; @@ -1368,6 +1373,30 @@ leap_second_directive: | OFF ; +imp_directive: + _include imp_include_sources + { + cb_include_file_list = ppp_list_append(cb_include_file_list, $2); + } +; + +imp_include_sources: + TOKEN + { + char *f = fix_filename ($1); + if (cobc_deciph_header_filename (f) != 0) + ppp_error_invalid_option ("IMP", f); + $$ = ppp_list_add (NULL, f); + } +| imp_include_sources TOKEN + { + char *f = fix_filename ($2); + if (cobc_deciph_header_filename (f) != 0) + ppp_error_invalid_option ("IMP", f); + $$ = ppp_list_add ($1, f); + } +; + turn_directive: ec_list CHECKING on_or_off { @@ -1895,5 +1924,6 @@ _printing: | PRINTING ; _on: | ON ; _than: | THAN ; _to: | TO ; +_include: | INCLUDE ; %%