Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add >>IMP INCLUDE directive #143

Open
wants to merge 11 commits into
base: gcos4gnucobol-3.x
Choose a base branch
from
7 changes: 7 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ NEWS - user visible changes -*- outline -*-

* New GnuCOBOL features

** the leading space for all internal directives is removed in the lexer.
Source previously processed may need to be ajusted to be processed by
GnuCOBOL 3.3.

** cobc now checks for binary and multi-byte encoded files and early exit
parsing those; the error output for format errors (for example invalid
indicator column) is now limitted to 5 per source file
Expand Down Expand Up @@ -52,6 +56,9 @@ NEWS - user visible changes -*- outline -*-
calls to externals. The files are put into quotes, unless they start by
'<'. Quoted files are expected to have absolute paths, as the C compiler
is called in a temp directory instead of the project directory.
The directive >>IMP INCLUDE "file.h", >>IMP INCLUDE "<file.h>",
>>IMP INCLUDE <file.h> or >>IMP INCLUDE file.h can be used as an alternative
to this compiler option.

** output of unlimited errors may be requested by -fmax-errors=0,
to stop compiliation at first error use -Wfatal-errors
Expand Down
6 changes: 6 additions & 0 deletions cobc/ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@
compiler aborts on broken expressions, bugs #933, #938 and #966
* typeck.c: minor refactoring within functions

2024-04-25 Boris Eng <boris.eng@ocamlpro.com>

* pplex.l, ppparse.y, scanner.l, cobc.h, codegen.c:
new >>IMP INCLUDE directive to include one or multiple header files in
the generated C code (same behavior as the --include compiler option)

2024-04-24 Fabrice Le Fessant <fabrice.le_fessant@ocamlpro.com>

* replace.c: optimize speed and memory usage. For speed, we add two
Expand Down
6 changes: 4 additions & 2 deletions cobc/cobc.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ enum cb_sub_check {
struct cb_text_list {
struct cb_text_list *next; /* next pointer */
struct cb_text_list *last;
const char *text;
char *text;
};

/* Structure for extended filenames */
Expand Down Expand Up @@ -478,8 +478,10 @@ extern int cb_depend_keep_missing;
extern int cb_flag_copybook_deps;
extern struct cb_text_list *cb_depend_list;
extern struct cb_text_list *cb_copy_list;
extern struct cb_text_list *cb_include_file_list;
extern struct cb_text_list *cb_include_file_list; /* global */
extern struct cb_text_list *cb_include_file_list_directive; /* temporary */
extern struct cb_text_list *cb_include_list;
extern struct cb_text_list *cb_include_file_list_directive;
extern struct cb_text_list *cb_intrinsic_list;
extern struct cb_text_list *cb_extension_list;
extern struct cb_text_list *cb_static_call_list;
Expand Down
15 changes: 11 additions & 4 deletions cobc/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1833,16 +1833,23 @@ output_gnucobol_defines (const char *formatted_date)
output_line ("#define COB_MODULE_TIME\t\t%d", i);

{
struct cb_text_list *l = cb_include_file_list ;
for (;l;l=l->next){
if (l->text[0] == '<'){
struct cb_text_list *l;
for (l = cb_include_file_list; l; l = l->next) {
if (l->text[0] == '<') {
output_line ("#include %s", l->text);
} else {
output_line ("#include \"%s\"", l->text);
}
}
}

for (l = cb_include_file_list_directive; l; l = l->next) {
if (l->text[0] == '<') {
output_line ("#include %s", l->text);
} else {
output_line ("#include \"%s\"", l->text);
}
}
}
}

/* CALL cache */
Expand Down
16 changes: 16 additions & 0 deletions cobc/pplex.l
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ ALNUM_LITERAL_A "\'"([^''\n]|("\'"[0-9][0-9, ]+"\'"))*"\'"
ALNUM_LITERAL {ALNUM_LITERAL_Q}|{ALNUM_LITERAL_A}
SET_PAREN_LIT \([^()\n]*\)
DEFNUM_LITERAL [+-]?[0-9]*[\.]*[0-9]+
RAW_SEQ [^ \n]+

AREA_A [ ]?#
MAYBE_AREA_A [ ]?#?
Expand All @@ -224,6 +225,7 @@ MAYBE_AREA_A [ ]?#?
%x ALNUM_LITERAL_STATE
%x CONTROL_STATEMENT_STATE
%x DISPLAY_DIRECTIVE_STATE
%x IMP_DIRECTIVE_STATE

%%

Expand Down Expand Up @@ -357,6 +359,11 @@ MAYBE_AREA_A [ ]?#?
return CALL_DIRECTIVE;
}

^{MAYBE_AREA_A}[ ]*">>"[ ]?"IMP" {
BEGIN IMP_DIRECTIVE_STATE;
return IMP_DIRECTIVE;
}

^{MAYBE_AREA_A}[ ]*">>"[ ]*\n {
/* empty 2002+ style directive */
cb_plex_warning (COBC_WARN_FILLER, newline_count,
Expand Down Expand Up @@ -721,6 +728,7 @@ ELSE_DIRECTIVE_STATE,
ENDIF_DIRECTIVE_STATE,
ALNUM_LITERAL_STATE,
CONTROL_STATEMENT_STATE,
IMP_DIRECTIVE_STATE,
COBOL_WORDS_DIRECTIVE_STATE>{
\n {
BEGIN INITIAL;
Expand Down Expand Up @@ -990,6 +998,14 @@ ENDIF_DIRECTIVE_STATE>{
}
}

<IMP_DIRECTIVE_STATE>{
"INCLUDE" { return INCLUDE; } /* GnuCOBOL 3.3 extension */
{RAW_SEQ} {
pplval.s = cobc_plex_strdup (yytext);
return TOKEN;
}
}

<IF_DIRECTIVE_STATE>{
"IS" { return IS; }
"NOT" { return NOT; }
Expand Down
33 changes: 33 additions & 0 deletions cobc/ppparse.y
Original file line number Diff line number Diff line change
Expand Up @@ -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 <s> TOKEN "Word or Literal"
Expand Down Expand Up @@ -768,6 +771,7 @@ ppparse_clear_vars (const struct cb_define_struct *p)
%type <l> alnum_equality_list
%type <l> ec_list
%type <s> unquoted_literal
%type <l> imp_include_sources

%type <r> _copy_replacing
%type <r> replacing_list
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1368,6 +1373,34 @@ leap_second_directive:
| OFF
;

imp_directive:
/* GnuCOBOL 3.3 extension */
INCLUDE
{
cb_error (_("invalid %s directive"), "IMP INCLUDE");
yyerrok;
}
| INCLUDE imp_include_sources
{
struct cb_text_list *p = $2;
while (p != NULL) {
fprintf (ppout, "#INCLUDE %s\n", p->text);
p = p->next;
}
}
;
engboris marked this conversation as resolved.
Show resolved Hide resolved

imp_include_sources:
TOKEN
{
$$ = ppp_list_add (NULL, fix_filename ($1));
}
| imp_include_sources TOKEN
{
$$ = ppp_list_add ($1, fix_filename ($2));
}
;

turn_directive:
ec_list CHECKING on_or_off
{
Expand Down
58 changes: 42 additions & 16 deletions cobc/scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ static size_t pic2_size;
static unsigned int inside_bracket = 0;
static char err_msg[COB_MINI_BUFF];

struct cb_text_list *cb_include_file_list_directive = NULL;

/* Function declarations */
static void read_literal (const char, const enum cb_literal_type);
static int scan_x (const char *, const char *);
Expand All @@ -189,6 +191,7 @@ static void copy_two_words_in_quotes (char ** const, char ** const);
static void add_synonym (const int, const int);
static void make_synonym (void);
static void clear_constants (void);
static struct cb_text_list *scan_list_add (struct cb_text_list *, const char *);

%}

Expand Down Expand Up @@ -217,7 +220,7 @@ AREA_A "#AREA_A"\n
cobc_in_area_a = 0;
%}

<*>^[ ]?"#CALLFH".*\n {
<*>^"#CALLFH".*\n {
if (current_program) {
const char *p1;
char *p2;
Expand All @@ -240,37 +243,37 @@ AREA_A "#AREA_A"\n
}


<*>^[ ]?"#DEFLIT".*\n {
<*>^"#DEFLIT".*\n {
scan_define_options (yytext);
}

<*>^[ ]?"#ADDRSV".*\n {
<*>^"#ADDRSV".*\n {
char *word;

copy_word_in_quotes (&word);
add_reserved_word_now (word, NULL);
cobc_free (word);
}

<*>^[ ]?"#ADDSYN-STD".*\n {
<*>^"#ADDSYN-STD".*\n {
add_synonym (1, 0);
}
<*>^[ ]?"#ADDSYN".*\n {
<*>^"#ADDSYN".*\n {
add_synonym (0, 0);
}

<*>^[ ]?"#MAKESYN".*\n {
<*>^"#MAKESYN".*\n {
make_synonym ();
}

<*>^[ ]?"#OVERRIDE-STD".*\n {
<*>^"#OVERRIDE-STD".*\n {
add_synonym (1, 1);
}
<*>^[ ]?"#OVERRIDE".*\n {
<*>^"#OVERRIDE".*\n {
add_synonym (0, 1);
}

<*>^[ ]?"#REMOVE-STD".*\n {
<*>^"#REMOVE-STD".*\n {
char *word;

copy_word_in_quotes (&word);
Expand All @@ -283,27 +286,27 @@ AREA_A "#AREA_A"\n
cobc_free (word);
}

<*>^[ ]?"#REMOVE".*\n {
<*>^"#REMOVE".*\n {
char *word;

copy_word_in_quotes (&word);
remove_reserved_word_now (word);
cobc_free (word);
}

<*>^[ ]?"#REFMOD_ZERO "[0-9]\n {
<*>^"#REFMOD_ZERO "[0-9]\n {
cb_ref_mod_zero_length = (yytext[13] - '0');
}

<*>^[ ]?"#ODOSLIDE "[0-1]\n {
<*>^"#ODOSLIDE "[0-1]\n {
cb_odoslide = (yytext[10] - '0');
}

<*>^[ ]?"#ASSIGN "[0-9]\n {
<*>^"#ASSIGN "[0-9]\n {
cb_assign_type_default = (enum cb_assign_type)(yytext[8] - '0');
}

<*>^[ ]?"#TURN".*\n {
<*>^"#TURN".*\n {
struct cb_turn_list *l;

for (l = cb_turn_list; l && l->line != -1; l = l->next);
Expand All @@ -312,14 +315,21 @@ AREA_A "#AREA_A"\n
}
}

<*>^[ ]?"#AREACHECK"\n {
<*>^"#AREACHECK"\n {
cobc_areacheck = 1;
}

<*>^[ ]?"#NOAREACHECK"\n {
<*>^"#NOAREACHECK"\n {
cobc_areacheck = 0;
}

<*>^"#INCLUDE".*/\n {
cb_include_file_list_directive = scan_list_add (
cb_include_file_list_directive,
yytext + 9
);
}

<*>^{AREA_A}[ ]*/"." {
count_lines (yytext + 9); /* skip "\n#area_a\n" */
if (cobc_in_procedure && cobc_areacheck) {
Expand Down Expand Up @@ -2580,6 +2590,22 @@ clear_constants (void)
top_78_ptr = NULL;
}

static struct cb_text_list *
scan_list_add (struct cb_text_list *list, const char *text)
{
struct cb_text_list *p;

p = cobc_parse_malloc (sizeof (struct cb_text_list));
p->text = cobc_parse_strdup (text);
if (!list) {
p->last = p;
return p;
}
list->last->next = p;
list->last = p;
return list;
}

/* Global functions */

void
Expand Down
2 changes: 2 additions & 0 deletions doc/gnucobol.texi
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,8 @@ Add a @code{#include} @file{file.h} at the beginning of the generated
C source file. The file name is put into quotes, unless it starts by
@code{<}. Quoted files should be absolute paths, since C files are compiled
in temporary directories.
The directive @code{>>IMP INCLUDE "FILE.h"} or @code{>>IMP INCLUDE <FILE.h>}
can be used as an alternative to this compiler option.
The option also implies @option{-fno-gen-c-decl-static-call}.
This option can be used to check function prototypes when
static calls are used. When this option is used, the source file is
Expand Down
Loading
Loading