Skip to content

Commit

Permalink
Add option --include FILE.h to add a #include in the generated C code
Browse files Browse the repository at this point in the history
This option has two side-effect:
* the C file is compiled in the project directory (so that the included file
  can be found locally)
* no prototype is generated, so the new header file must contain a prototype
  for all statically called functions
  • Loading branch information
lefessan committed Jan 22, 2024
1 parent 024ef4c commit 2f012f0
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 2 deletions.
11 changes: 11 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ NEWS - user visible changes -*- outline -*-

* Changes to the COBOL compiler (cobc) options:

** New option --copy COPYBOOK to load copybooks before parsing files. This
option can typically be used to perform replacements without modifying
the source code

** New option --include FILE.h to add a #include in the generated C file.
This option can typically be used to force the C compiler to check static
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.

** output of unlimited errors may be requested by -fmax-errors=0,
to stop compiliation at first error use -Wfatal-errors
** default value for -fmax-errors was changed from 128 to 20
Expand All @@ -29,6 +39,7 @@ NEWS - user visible changes -*- outline -*-
INSPECT CONVERTING (and "simple" INSPECT REPLACING), in general
and especially if both from and to are constants

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

GnuCOBOL 3.2 (20230728)
GnuCOBOL 3.2rc1 (20230118)
Expand Down
9 changes: 9 additions & 0 deletions cobc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@

2023-10-12 Fabrice Le Fessant <[email protected]>

* cobc.c, codegen.c: new option --include FILE, to #include
additional files in the C generated code. Such files can be
used to statically check the number of arguments in static
calls, for example. The files are put into quotes, unless
they start by '<'. Since C files are compiled in a temp dir,
quoted files should be absolute paths.

2023-10-11 Fabrice Le Fessant <[email protected]>

* cobc.c, pplex.l: new option --copy COPYBOOK, to include a COPYBOOK
Expand Down
15 changes: 14 additions & 1 deletion cobc/cobc.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ enum compile_level {
#define CB_FLAG_GETOPT_DEFAULT_COLSEQ 15
#define CB_FLAG_GETOPT_MEMORY_CHECK 16
#define CB_FLAG_GETOPT_COPY_FILE 17
#define CB_FLAG_GETOPT_INCLUDE_FILE 18


/* Info display limits */
Expand Down Expand Up @@ -234,6 +235,7 @@ const char *demangle_name = NULL;
const char *cb_storage_file_name = NULL;
const char *cb_call_extfh = NULL;
struct cb_text_list *cb_copy_list = NULL;
struct cb_text_list *cb_include_file_list = NULL;
struct cb_text_list *cb_include_list = NULL;
struct cb_text_list *cb_depend_list = NULL;
struct cb_text_list *cb_intrinsic_list = NULL;
Expand Down Expand Up @@ -598,6 +600,7 @@ static const struct option long_options[] = {
{"std", CB_RQ_ARG, NULL, '$'},
{"conf", CB_RQ_ARG, NULL, '&'},
{"copy", CB_RQ_ARG, NULL, CB_FLAG_GETOPT_COPY_FILE},
{"include", CB_RQ_ARG, NULL, CB_FLAG_GETOPT_INCLUDE_FILE},
{"debug", CB_NO_ARG, NULL, 'd'},
{"ext", CB_RQ_ARG, NULL, 'e'}, /* note: kept *undocumented* until GC4, will be changed to '.' */
{"free", CB_NO_ARG, NULL, 'F'}, /* note: not assigned directly as this is only valid for */
Expand Down Expand Up @@ -3909,6 +3912,16 @@ process_command_line (const int argc, char **argv)
cobc_strdup (cob_optarg));
break;

case CB_FLAG_GETOPT_INCLUDE_FILE: /* 18 */
/* -include=<file.h> : add #include "file.h" to
generated C file */
{
char *file = cobc_strdup (cob_optarg);
cb_flag_c_decl_for_static_call = 0;
CB_TEXT_LIST_ADD (cb_include_file_list, file);
break;
}

case 'A':
/* -A <xx> : Add options to C compile phase */
COBC_ADD_STR (cobc_cflags, " ", cob_optarg, NULL);
Expand Down Expand Up @@ -4456,7 +4469,7 @@ process_filename (const char *filename)
fn->translate = cobc_main_strdup (output_name);
} else
if (save_all_src || save_temps || save_c_src
|| cb_compile_level == CB_LEVEL_TRANSLATE) {
|| cb_compile_level == CB_LEVEL_TRANSLATE) {
fn->translate = cobc_main_stradd_dup (fbasename, ".c");
} else {
fn->translate = cobc_main_malloc (COB_FILE_MAX);
Expand Down
1 change: 1 addition & 0 deletions cobc/cobc.h
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ extern FILE *cb_src_list_file;
extern FILE *cb_depend_file;
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_list;
extern struct cb_text_list *cb_intrinsic_list;
extern struct cb_text_list *cb_extension_list;
Expand Down
11 changes: 11 additions & 0 deletions cobc/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1829,6 +1829,17 @@ output_gnucobol_defines (const char *formatted_date)
current_compile_tm.tm_sec;
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] == '<'){
output_line ("#include %s", l->text);
} else {
output_line ("#include \"%s\"", l->text);
}
}
}

}

/* CALL cache */
Expand Down
5 changes: 4 additions & 1 deletion cobc/help.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,11 @@ cobc_print_usage_common_options (void)
puts (_(" -X, --Xref specify cross reference in listing"));
#endif
puts (_(" -I <directory> add <directory> to copy/include search path"));
puts (_(" --copy <copybook> include <copybook> at beginning of file, as would COPY copybook."));
puts (_(" --copy <copybook> include <copybook> at beginning of file,\n"
" as would COPY copybook."));
puts (_(" -L <directory> add <directory> to library search path"));
puts (_(" --include <file.h> add a #include \"file.h\" at the beginning of the C\n"
" generated file (implies -fno-gen-c-decl-static-call)"));
puts (_(" -l <lib> link the library <lib>"));
puts (_(" -K <entry> generate CALL to <entry> as static"));
puts (_(" -D <define> define <define> for COBOL compilation"));
Expand Down
12 changes: 12 additions & 0 deletions doc/gnucobol.texi
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,18 @@ another process. You can manually set an output file using @option{-o}.
Include @file{copybook} at the beginning of the source code, as if
@code{COPY copybook} had been parsed.

@item --include @var{file.h}
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 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
compiled in the project directory (instead of the temp directory), and
no prototypes are generated, so ALL static call functions must appear
in the header file, with GnuCOBOL compatible types.

@item -C
Translation only. COBOL source files are translated into C files.
The output is saved in file @file{*.c}.
Expand Down
36 changes: 36 additions & 0 deletions tests/testsuite.src/used_binaries.at
Original file line number Diff line number Diff line change
Expand Up @@ -1011,3 +1011,39 @@ AT_CHECK([$COBC -fdiagnostics-plain-output -fdiagnostics-show-caret -Wno-others

AT_CLEANUP


AT_SETUP([check include header file])
AT_KEYWORDS([-include])

AT_DATA([file.h], [
extern void f(char *, long );
])

AT_DATA([prog.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
PROCEDURE DIVISION.
CALL "f" USING "Hello".
])

# No check, program seems correct
AT_CHECK([$COBC -m -fstatic-call prog.cob], [0])

# We ignore the error output, as it depends on the C compiler in use
AT_CHECK([$COBC -m --include "$PWD/file.h" -fstatic-call prog.cob], [1], [], [ignore])

AT_DATA([prog2.cob], [
IDENTIFICATION DIVISION.
PROGRAM-ID. prog.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 long USAGE BINARY-C-LONG.
PROCEDURE DIVISION.
CALL "f" USING "Hello" BY VALUE long RETURNING NOTHING.
])

AT_CHECK([$COBC -m --include "$PWD/file.h" -fstatic-call prog2.cob], [0], [], [])

AT_CHECK([$COBC -I . -m --include "file.h" -fstatic-call prog2.cob], [0], [], [])

AT_CLEANUP

0 comments on commit 2f012f0

Please sign in to comment.