diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index e238d741a..3fcc8bfe3 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -79,15 +79,16 @@ jobs: path: _build/install.log - name: check - continue-on-error: true run: | cd _build/tests - make check TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" || (echo "not all tests passed") + make check TESTSUITEFLAGS="--jobs=$(($(nproc)+1))" make test shell: msys2 {0} + - name: Upload testsuite.log uses: actions/upload-artifact@v3 + if: failure() with: name: testsuite.log path: _build/tests/testsuite.log diff --git a/cobc/ChangeLog b/cobc/ChangeLog index 6df472887..1448ddd71 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -1,4 +1,20 @@ +2023-08-17 Fabrice Le Fessant + + * cobc.c: add new flags to output dependencies following gcc: -M to + output deps only, -MD to output deps while compiling (in .d files), + -MP to output phony targets, -MG to keep missing copybooks, + -MQ to Makefile-quote target + +2023-08-16 Fabrice Le Fessant + + * cobc.c, flags.def: add new flags to output dependencies: + -foneline-deps outputs all dependencies on a single line instead of + multiple lines; -fcopybook-deps outputs only copybook names instead + of file paths. -fcopybook-deps also forces -E, -foneline-deps, + -MT=copybooks, disables errors on missing copybooks and removes + output on stdout. + 2024-01-25 David Declerck FR #459: support COLLATING SEQUENCE clause on SELECT / INDEXED files diff --git a/cobc/cobc.c b/cobc/cobc.c index d89878c7d..088af6f47 100644 --- a/cobc/cobc.c +++ b/cobc/cobc.c @@ -109,7 +109,13 @@ enum compile_level { #define CB_FLAG_GETOPT_MEMORY_CHECK 17 #define CB_FLAG_GETOPT_COPY_FILE 18 #define CB_FLAG_GETOPT_INCLUDE_FILE 19 - +#define CB_FLAG_GETOPT_DEPEND_OUTPUT 20 +#define CB_FLAG_GETOPT_DEPEND_TARGET 21 +#define CB_FLAG_GETOPT_DEPEND_ESCAPE_TARGET 22 +#define CB_FLAG_GETOPT_DEPEND_OUTPUT_FILE 23 +#define CB_FLAG_GETOPT_DEPEND_ADD_PHONY 24 +#define CB_FLAG_GETOPT_DEPEND_KEEP_MISSING 25 +#define CB_FLAG_GETOPT_DEPEND_ON_THE_SIDE 26 /* Info display limits */ #define CB_IMSG_SIZE 24 @@ -249,6 +255,11 @@ FILE *cb_storage_file = NULL; FILE *cb_listing_file = NULL; FILE *cb_depend_file = NULL; const char *cb_ebcdic_table = NULL; +int cb_depend_output = 0; +int cb_depend_output_only = 0; +int cb_depend_add_phony = 0; +int cb_depend_keep_missing = 0; +int cb_depend_target_auto = 0; /* set by option -fttitle= */ char *cb_listing_with_title = NULL; @@ -386,8 +397,9 @@ static char *cobc_libs; /* -l... */ static char *cobc_lib_paths; /* -L... */ static char *cobc_include; /* -I... */ static char *cobc_ldflags; /* -Q / COB_LDFLAGS */ -static char *cb_depend_target; /* -MT <target>... */ +static char *cb_depend_target; /* -MT <target>... */ +static const char *cb_depend_filename; /* -MF <file> */ static size_t cobc_cflags_size; static size_t cobc_libs_size; static size_t cobc_lib_paths_size; @@ -612,8 +624,13 @@ static const struct option long_options[] = { {"j", CB_OP_ARG, NULL, 'j'}, {"Q", CB_RQ_ARG, NULL, 'Q'}, {"A", CB_RQ_ARG, NULL, 'A'}, - {"MT", CB_RQ_ARG, NULL, '!'}, - {"MF", CB_RQ_ARG, NULL, '@'}, + {"M", CB_NO_ARG, NULL, CB_FLAG_GETOPT_DEPEND_OUTPUT }, + {"MT", CB_RQ_ARG, NULL, CB_FLAG_GETOPT_DEPEND_TARGET}, + {"MQ", CB_RQ_ARG, NULL, CB_FLAG_GETOPT_DEPEND_ESCAPE_TARGET}, + {"MF", CB_RQ_ARG, NULL, CB_FLAG_GETOPT_DEPEND_OUTPUT_FILE}, + {"MP", CB_NO_ARG, NULL, CB_FLAG_GETOPT_DEPEND_ADD_PHONY}, + {"MG", CB_NO_ARG, NULL, CB_FLAG_GETOPT_DEPEND_KEEP_MISSING}, + {"MD", CB_NO_ARG, NULL, CB_FLAG_GETOPT_DEPEND_ON_THE_SIDE}, {"coverage", CB_NO_ARG, &cb_coverage_enabled, 1}, {"P", CB_OP_ARG, NULL, 'P'}, {"Xref", CB_NO_ARG, NULL, 'X'}, @@ -3001,6 +3018,74 @@ remove_trailing_slash (char *data) } } +static int string_is_dash (const char*s){ + return ( strcmp (s, COB_DASH) == 0 ); +} + +static void add_depend_target (const char* s){ + if (!cb_depend_target) { + cb_depend_target = cobc_strdup (s); + } else { + /* multiple invocations add to the list */ + const size_t orig_len = strlen (cb_depend_target); + const size_t new_len = strlen (s); + const size_t buff_len = orig_len + 1 + new_len + 1; + cb_depend_target = cobc_realloc (cb_depend_target, buff_len); + memset (cb_depend_target + orig_len, ' ', 1); + memcpy (cb_depend_target + orig_len + 1, s, new_len); + memset (cb_depend_target + orig_len + 1 + new_len, 0, 1); + } +} + +static void add_depend_escape_target (const char* s) +{ + int i, len, nchars; + len = strlen (s); + nchars = 0; + for (i=0; i<len; i++){ + char c = s[i]; + if (c == '$' || c == '#' || c == '*') nchars++; + } + if (nchars){ + char *new_s = cobc_malloc (len+nchars+1); + char *cur_s = new_s ; + for (i=0; i<len; i++){ + char c = s[i]; + if (c == '$'){ + *cur_s++ = '$'; + } else + if (c == '#' || c == '*'){ + *cur_s++ = '\\'; + } + *cur_s++ = c; + } + *cur_s = 0; + add_depend_target (new_s); + cobc_free (new_s); + } else { + add_depend_target (s); + } +} + +static const char* file_replace_extension (const char* file, const char* ext) +{ + int len = strlen (file); + int extlen = strlen (ext); + int i; + for (i=len; i>0; i--){ + char c = file[i]; + if (c == '.'){ + int newlen = i+extlen+1; + char* new_file = cobc_malloc(newlen); + memcpy (new_file, file, i); + memcpy (new_file+i, ext, extlen+1); + return new_file; + } + if (c == '/') break; + } + return cobc_main_stradd_dup (file, ext); +} + /* process command line options */ static int process_command_line (const int argc, char **argv) @@ -3643,28 +3728,29 @@ process_command_line (const int argc, char **argv) cb_define_list = p; break; - case '!': - /* -MT <target> */ - if (!cb_depend_target) { - cb_depend_target = cobc_strdup (cob_optarg); - } else { - /* multiple invocations add to the list */ - const size_t orig_len = strlen (cb_depend_target); - const size_t new_len = strlen (cob_optarg); - const size_t buff_len = orig_len + 1 + new_len + 1; - cb_depend_target = cobc_realloc (cb_depend_target, buff_len); - memset (cb_depend_target + orig_len, ' ', 1); - memcpy (cb_depend_target + orig_len + 1, cob_optarg, new_len); - memset (cb_depend_target + orig_len + 1 + new_len, 0, 1); - } + case CB_FLAG_GETOPT_DEPEND_OUTPUT: /* -M */ + cb_depend_output = 1; + cb_depend_output_only = 1; + cb_compile_level = CB_LEVEL_PREPROCESS; break; - - case '@': - /* -MF <file> */ - cb_depend_file = fopen (cob_optarg, "w"); - if (!cb_depend_file) { - cb_perror (0, "cobc: %s: %s", cob_optarg, cb_get_strerror ()); - } + case CB_FLAG_GETOPT_DEPEND_ON_THE_SIDE: /* -MD */ + cb_depend_output = 1; + cb_depend_target_auto = 1; + break; + case CB_FLAG_GETOPT_DEPEND_ADD_PHONY: /* -MP */ + cb_depend_add_phony = 1; + break; + case CB_FLAG_GETOPT_DEPEND_KEEP_MISSING: /* -MG */ + cb_depend_keep_missing = 1; + break; + case CB_FLAG_GETOPT_DEPEND_TARGET: /* -MT <target> */ + add_depend_target (cob_optarg); + break; + case CB_FLAG_GETOPT_DEPEND_ESCAPE_TARGET: /* -MQ <target> */ + add_depend_escape_target (cob_optarg); + break; + case CB_FLAG_GETOPT_DEPEND_OUTPUT_FILE: /* -MF <file> */ + cb_depend_filename = cobc_strdup(cob_optarg); break; case 'I': @@ -4058,6 +4144,23 @@ process_command_line (const int argc, char **argv) } } + if (cb_flag_copybook_deps){ + /* same as -M, but only COPYBOOK names */ + cb_depend_output = 1; + cb_depend_output_only = 1; + cb_depend_keep_missing = 1; + cb_depend_add_phony = 0; + cb_compile_level = CB_LEVEL_PREPROCESS; + } + if (!cb_depend_output && + ( cb_depend_filename || cb_depend_add_phony || cb_depend_target + || cb_depend_keep_missing) ){ + cobc_err_exit ("dependency options require -M or -MD"); + } + if (cb_depend_output_only && cb_compile_level != CB_LEVEL_PREPROCESS){ + cobc_err_exit ("-M is compatible only with -E. Use -MD instead."); + } + /* Load reserved words from fixed word-list if specified */ if (cb_reserved_words != NULL) { cb_load_words(); @@ -4112,7 +4215,29 @@ process_command_line (const int argc, char **argv) } #endif - if (output_name && strcmp (output_name, COB_DASH) == 0) { + if (cb_depend_target_auto){ + if (!cb_depend_filename){ + if (output_name){ + cb_depend_filename = + file_replace_extension (output_name, ".d"); + } + } + } + if (cb_depend_output_only){ + if (cb_depend_filename){ + if (output_name){ + cb_depend_output_only = 0; + } + } else { + if (output_name){ + cb_depend_filename = output_name; + output_name = NULL; + } else + cb_depend_filename = cobc_strdup(COB_DASH); + } + } + + if (output_name && string_is_dash (output_name)) { cb_src_list_file = stdout; if (cb_compile_level != CB_LEVEL_PREPROCESS) { cobc_err_exit (_("output to stdout only valid for preprocess")); @@ -4120,17 +4245,16 @@ process_command_line (const int argc, char **argv) cobc_main_free (output_name); cobc_main_free (output_name_buff); } - -#if 0 /* TODO: */ - if (cb_compile_level == CB_LEVEL_PREPROCESS && output_name && strcmp (output_name, COB_DASH) != 0)) { - cb_depend_file = output_file; - } -#endif - /* TODO: add -M and -MD (breaking change "per GCC" already announced) */ - if (cb_depend_file && !cb_depend_target) { - fclose (cb_depend_file); - cb_depend_file = NULL; - cobc_err_exit (_("-MT must be given to specify target file")); + + if (cb_depend_filename){ + if (string_is_dash(cb_depend_filename)){ + cb_depend_file = stdout; + } else { + cb_depend_file = fopen (cb_depend_filename, "w"); + if (!cb_depend_file) { + cb_perror (0, "cobc: %s: %s", cb_depend_filename, cb_get_strerror ()); + } + } } /* debug: Turn on all exception conditions @@ -4355,7 +4479,7 @@ process_filename (const char *filename) char *full_path; #endif - if (strcmp (filename, COB_DASH) == 0) { + if ( string_is_dash (filename) ) { if (cobc_seen_stdin == 0) { cobc_seen_stdin = 1; file_is_stdin = 1; @@ -5196,7 +5320,9 @@ preprocess (struct filename *fn) #endif if (output_name - || cb_compile_level > CB_LEVEL_PREPROCESS) { + || cb_compile_level > CB_LEVEL_PREPROCESS + || cb_depend_output_only + ) { if (cb_unix_lf) { ppout = fopen(fn->preprocess, "wb"); } else { @@ -5300,7 +5426,7 @@ preprocess (struct filename *fn) fflush (stderr); } if (cb_listing_outputfile && verbose_output >= 0) { - if (strcmp (cb_listing_outputfile, COB_DASH) == 0) { + if (string_is_dash (cb_listing_outputfile)) { cb_src_list_file = stdout; } else { if (cb_unix_lf) { @@ -9157,6 +9283,47 @@ process_file (struct filename *fn, int status) cobc_set_listing_header_code (); } + if (cb_depend_output){ + struct cb_text_list *l; + const char* sep = " \\\n"; + FILE *file = NULL; + + if (cb_flag_copybook_deps) sep = ""; + if (cb_depend_file){ + file = cb_depend_file; + } else { + const char *basename = file_basename (fn->source, NULL); + const char *d_name = file_replace_extension (basename, ".d"); + file = fopen (d_name, "w"); + } + + if (cb_depend_target){ + fprintf (file, "%s:%s", cb_depend_target, sep); + } else { + const char *basename = file_basename (fn->source, NULL); + const char *target = file_replace_extension (basename, "." COB_OBJECT_EXT); + fprintf (file, "%s:%s", target, sep); + } + for (l = cb_depend_list; l; l = l->next) { + fprintf (file, " %s%s", l->text, l->next ? sep : "\n\n"); + } + /* These lines should only be added with -MP */ + if (cb_depend_add_phony){ + for (l = cb_depend_list; l; l = l->next) { + fprintf (file, "%s:\n", l->text); + } + } + if (!cb_depend_file){ + fclose (file); + } + + /* For now, we don't need to free this space as it is + allocated by cobc_plex_malloc() for which no + cobc_plex_free() exists. Everything is freed at the + end. */ + cb_depend_list = NULL; + } + if (cobc_list_file) { putc ('\n', cb_listing_file); } @@ -9322,7 +9489,7 @@ main (int argc, char **argv) memset (cb_listing_header, 0, sizeof (cb_listing_header)); /* If -P=file specified, all lists go to this file */ if (cobc_list_file) { - if (strcmp (cobc_list_file, COB_DASH) == 0) { + if (string_is_dash (cobc_list_file)) { cb_listing_file = stdout; } else if (cb_unix_lf) { @@ -9337,7 +9504,7 @@ main (int argc, char **argv) /* internal complete source listing file */ if (cb_listing_outputfile) { - if (strcmp (cb_listing_outputfile, COB_DASH) == 0) { + if (string_is_dash (cb_listing_outputfile)) { cb_src_list_file = stdout; } else { if (cb_unix_lf) { @@ -9418,15 +9585,7 @@ main (int argc, char **argv) } /* Output dependency list */ - if (cb_depend_file) { - struct cb_text_list *l; - fprintf (cb_depend_file, "%s: \\\n", cb_depend_target); - for (l = cb_depend_list; l; l = l->next) { - fprintf (cb_depend_file, " %s%s\n", l->text, l->next ? " \\" : "\n"); - } - for (l = cb_depend_list; l; l = l->next) { - fprintf (cb_depend_file, "%s:\n", l->text); - } + if (cb_depend_file && cb_depend_file != stdout){ fclose (cb_depend_file); } diff --git a/cobc/cobc.h b/cobc/cobc.h index 7b5f30bbd..86771c8f2 100644 --- a/cobc/cobc.h +++ b/cobc/cobc.h @@ -472,6 +472,8 @@ extern int cb_saveargc; extern FILE *cb_listing_file; extern FILE *cb_src_list_file; extern FILE *cb_depend_file; +extern int cb_depend_output; +extern int cb_depend_keep_missing; 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; diff --git a/cobc/flag.def b/cobc/flag.def index ea7f0c98a..44672a24f 100644 --- a/cobc/flag.def +++ b/cobc/flag.def @@ -134,6 +134,9 @@ CB_FLAG (cb_flag_stack_extended, 1, "stack-extended", CB_FLAG_ON (cb_flag_fast_compare, 0, "fast-compare", _(" -fno-fast-compare disables inline comparisions")) +CB_FLAG (cb_flag_copybook_deps, 0, "copybook-deps", + _(" -fcopybook-deps output copybook names as dependencies")) + /* Normal flags */ CB_FLAG_ON (cb_flag_remove_unreachable, 1, "remove-unreachable", diff --git a/cobc/help.c b/cobc/help.c index 3e95a2e19..e4f844609 100644 --- a/cobc/help.c +++ b/cobc/help.c @@ -135,8 +135,13 @@ cobc_print_usage_common_options (void) puts (_(" --list-system display system routines")); puts (_(" --save-temps[=<dir>] save intermediate files\n" " * default: current directory")); + puts (_(" -M output dependency list in Makefile format")); puts (_(" -MT <target> set/add target file used in dependency list")); + puts (_(" -MQ <target> same as -MT but with Makefile-quoting of the target")); puts (_(" -MF <file> place dependency list into <file>")); + puts (_(" -MP create phony targets for all dependencies")); + puts (_(" -MG output missing dependencies without complaining")); + puts (_(" -MD output dependencies in .d files while compiling")); puts (_(" -ext <extension> add file extension for resolving COPY")); putchar ('\n'); } diff --git a/cobc/pplex.l b/cobc/pplex.l index 02bb2640c..77aa3babe 100644 --- a/cobc/pplex.l +++ b/cobc/pplex.l @@ -1435,7 +1435,7 @@ ppopen (const char *name, struct cb_replace_list *replacing_list) } /* add opened file to dependency list */ - if (cb_depend_file) { + if (cb_depend_output && !cb_flag_copybook_deps) { cb_depend_list = pp_text_list_add (cb_depend_list, name, strlen (name)); } @@ -1628,6 +1628,20 @@ ppcopy (const char *name, const char *lib, struct cb_replace_list *replace_list) plexbuff1 = cobc_malloc ((size_t)COB_SMALL_BUFF); } + if (cb_depend_output && cb_flag_copybook_deps){ + + if (lib) { + snprintf (plexbuff1, (size_t)COB_SMALL_MAX, "%s%c%s", + lib, SLASH_CHAR, name); + plexbuff1[COB_SMALL_MAX] = 0; + } else { + strcpy (plexbuff1, name); + } + cb_depend_list = + pp_text_list_add (cb_depend_list, plexbuff1, + strlen (plexbuff1)); + } + /* TODO: open with path relative to the current file's path, if any (applies both to with and without "lib") */ @@ -1698,10 +1712,22 @@ ppcopy (const char *name, const char *lib, struct cb_replace_list *replace_list) } /* otherwise fall-trough to error handling */ } else { - /* ensure to have errno from name as specified, not from another file */ - (void)access (plexbuff1, R_OK); - /* pass file error as we have no more places to check */ - cb_error ("%s: %s", plexbuff1, cb_get_strerror ()); + /* do not output error if looking only for copybook deps */ + if (!cb_flag_copybook_deps){ + + /* add opened file to dependency list */ + if (cb_depend_output && cb_depend_keep_missing) { + const char *depname = cobc_plex_stradd (plexbuff1, cb_extension_list->text); + + cb_depend_list = pp_text_list_add (cb_depend_list, depname, strlen (depname)); + } else { + + /* ensure to have errno from name as specified, not from another file */ + (void)access (plexbuff1, R_OK); + /* pass file error as we have no more places to check */ + cb_error ("%s: %s", plexbuff1, cb_get_strerror ()); + } + } } /* On COPY, open error restore old file */ diff --git a/tests/testsuite.src/used_binaries.at b/tests/testsuite.src/used_binaries.at index d7266092e..1d1cf61ed 100644 --- a/tests/testsuite.src/used_binaries.at +++ b/tests/testsuite.src/used_binaries.at @@ -279,30 +279,6 @@ AT_CHECK([$GREP 'PARAGRAPH_00_l_4:' prog.c], [0], ignore, []) AT_CHECK([$GREP 'PARAGRAPH_EX_l_7:' prog.c], [0], ignore, []) AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [bluBb END], []) -AT_CAPTURE_FILE([prog.d]) -AT_CHECK([$COBC -I sub/copy prog.cob -ext=cpy -o prog.i -MF prog.d -MT "prog.c prog.h" -MT prog$COB_EXE_EXT -MT prog.$COB_OBJECT_EXT -MT prog.i -fsyntax-only], [0], [], []) -AT_CHECK([$GREP 'prog.c prog.h ' prog.d], [0], ignore, []) -AT_CHECK([$GREP ' prog.i:' prog.d], [0], ignore, []) -AT_CHECK([$GREP 'sub/copy/PROC.cpy' prog.d], [0], ignore, [], [ - # Previous test "failed" --> no entry with slash available, check backslash for this and following tests - AT_CHECK([$GREP ' sub\\copy\\PROC.cpy \\' prog.d], [0], ignore, []) - AT_CHECK([$GREP ' sub\\PROCE.cpy' prog.d], [0], ignore, []) - AT_CHECK([$GREP 'sub\\copy\\PROC.cpy:' prog.d], [0], ignore, []) - AT_CHECK([$GREP 'sub\\PROCE.cpy:' prog.d], [0], ignore, []) -], [ - AT_CHECK([$GREP ' sub/copy/PROC.cpy \\' prog.d], [0], ignore, []) - AT_CHECK([$GREP ' sub/PROCE.cpy' prog.d], [0], ignore, []) - AT_CHECK([$GREP 'sub/copy/PROC.cpy:' prog.d], [0], ignore, []) - AT_CHECK([$GREP 'sub/PROCE.cpy:' prog.d], [0], ignore, []) -]) - -# test again with trailing slash which should not result in different files -AT_CHECK([$COBC -I sub/copy/ prog.cob -ext=cpy -o prog.i -MF prog.d -MT "prog.c prog.h" -MT prog$COB_EXE_EXT -MT prog.$COB_OBJECT_EXT -MT prog.i -fsyntax-only], [0], [], []) -AT_CHECK([$GREP 'sub/copy/PROC.cpy' prog.d], [0], ignore, [], [ - # Previous test "failed" --> no entry with slash available, check backslash for this test - AT_CHECK([$GREP 'sub\\copy\\PROC.cpy' prog.d], [0], ignore, []) -]) - AT_CLEANUP @@ -1139,3 +1115,178 @@ AT_CHECK([$COMPILE_MODULE -Wno-unfinished --copy "f.copy" -fstatic-call prog2.co ]) AT_CLEANUP + +AT_SETUP([output dependencies]) + +# AT_KEYWORDS([]) +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + COPY COPY1. + PROCEDURE DIVISION. + MAIN-PROC SECTION. + 00. + COPY COPY2. + END-PROC SECTION. + COPY COPY3 in "sub". + EX. + STOP RUN. +]) + +AT_CHECK([mkdir -p sub]) +AT_DATA([COPY1.CPY], []) +AT_DATA([COPY2.CPY], [ DISPLAY "Hello". +]) +AT_DATA([sub/COPY3.CPY], []) + +AT_CHECK([$COMPILE_ONLY prog.cob]) + +AT_CHECK([$COMPILE_ONLY -M prog.cob prog.cob], [0], +[prog.o: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + sub/COPY3.CPY + +prog.o: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + sub/COPY3.CPY + +]) + +AT_CHECK([$COMPILE_ONLY -M -MF prog.dep prog.cob]) + +AT_CHECK([cat prog.dep], [0], +[prog.o: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + sub/COPY3.CPY + +]) + +AT_CHECK([$COMPILE_ONLY -M -fcopybook-deps prog.cob], [0], +[prog.o: COPY1 COPY2 sub/COPY3 + +]) + +AT_CHECK([$COMPILE_ONLY -M -MT prog.so prog.cob], [0], +[prog.so: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + sub/COPY3.CPY + +]) + +AT_CHECK([$COMPILE_ONLY -M -MQ '$(target)#toto' prog.cob], [0], +[$$(target)\#toto: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + sub/COPY3.CPY + +]) + +AT_CHECK([rm -f prog.d]) +AT_CAPTURE_FILE([prog.d]) + +AT_CHECK([$COMPILE -MD prog.cob]) + +AT_CHECK([$COMPILE -MD prog.cob]) + +AT_CHECK([cat prog.d], [0], +[prog.o: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + sub/COPY3.CPY + +]) + +AT_CHECK([$COMPILE -MD -o sub/prog.exe prog.cob]) + +AT_CHECK([cat sub/prog.d], [0], +[prog.o: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + sub/COPY3.CPY + +]) + +AT_CHECK([rm sub/COPY3.CPY]) + +AT_CHECK([$COMPILE_ONLY -M prog.cob], [1], +[prog.o: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY + +], +[prog.cob:12: error: sub/COPY3: No such file or directory +]) + +AT_CHECK([$COMPILE_ONLY -M -MG prog.cob], [0], +[prog.o: \ + prog.cob \ + COPY1.CPY \ + COPY2.CPY \ + sub/COPY3.CPY + +]) +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 BLA PIC X(5) VALUE 'bluBb'. + PROCEDURE DIVISION. + MAIN-PROC SECTION. + 00. + COPY PROC. + END-PROC SECTION. + COPY PROCE in "sub". + EX. + STOP RUN. +]) + +AT_CHECK([mkdir -p sub/copy]) +AT_DATA([sub/copy/PROC.cpy], [ + DISPLAY BLA NO ADVANCING. +]) +AT_DATA([sub/PROCE.cpy], [ + DISPLAY ' END' NO ADVANCING. +]) + +AT_CAPTURE_FILE([prog.d]) +AT_CHECK([$COBC -I sub/copy prog.cob -ext=cpy -o prog.i -M -MP -MF prog.d -MT "prog.c prog.h" -MT prog$COB_EXE_EXT -MT prog.$COB_OBJECT_EXT -MT prog.i -fsyntax-only]) +AT_CHECK([$GREP 'prog.c prog.h ' prog.d], [0], [ignore]) +AT_CHECK([$GREP ' prog.i:' prog.d], [0], [ignore]) +AT_CHECK([$GREP 'sub/copy/PROC.cpy' prog.d], [0], [ignore], [], [ + # Previous test "failed" --> no entry with slash available, check backslash for this and following tests + AT_CHECK([$GREP ' sub\\copy\\PROC.cpy \\' prog.d], [0], [ignore]) + AT_CHECK([$GREP ' sub\\PROCE.cpy' prog.d], [0], [ignore]) + AT_CHECK([$GREP 'sub\\copy\\PROC.cpy:' prog.d], [0], [ignore]) + AT_CHECK([$GREP 'sub\\PROCE.cpy:' prog.d], [0], [ignore]) +], [ + AT_CHECK([$GREP ' sub/copy/PROC.cpy \\' prog.d], [0], [ignore]) + AT_CHECK([$GREP ' sub/PROCE.cpy' prog.d], [0], [ignore]) + AT_CHECK([$GREP 'sub/copy/PROC.cpy:' prog.d], [0], [ignore]) + AT_CHECK([$GREP 'sub/PROCE.cpy:' prog.d], [0], [ignore]) +]) + +# test again with trailing slash which should not result in different files +AT_CHECK([$COBC -I sub/copy/ prog.cob -ext=cpy -o prog.i -M -MP -MF prog.d -MT "prog.c prog.h" -MT prog$COB_EXE_EXT -MT prog.$COB_OBJECT_EXT -MT prog.i -fsyntax-only]) +AT_CHECK([$GREP 'sub/copy/PROC.cpy' prog.d], [0], [ignore], [], [ + # Previous test "failed" --> no entry with slash available, check backslash for this test + AT_CHECK([$GREP 'sub\\copy\\PROC.cpy' prog.d], [0], [ignore]) +]) + +AT_CLEANUP + +