diff --git a/cobc/ChangeLog b/cobc/ChangeLog index 75d9c7a4a..656c80604 100644 --- a/cobc/ChangeLog +++ b/cobc/ChangeLog @@ -960,6 +960,11 @@ including "no identifier at all" and use of subscripting / ref-mod which previously were all silently ignored +2023-03-14 Samuel Belondrade + + * codegen.c (output_report_control): add a loop to check if the variable + exist (bug: #863) + 2023-03-08 Emilien Lemaire * reserved.c (get_user_specified_reserved_word): add check for diff --git a/cobc/codegen.c b/cobc/codegen.c index 68355652f..17a693cb7 100644 --- a/cobc/codegen.c +++ b/cobc/codegen.c @@ -10029,71 +10029,71 @@ output_report_control (struct cb_report *p, int id, cb_tree ctl, cb_tree nx) int i, bfound, prvid, seq; x = CB_VALUE (ctl); - s = cb_code_field(x); + s = cb_code_field (x); if(nx) { - output_report_control(p, id, nx, CB_CHAIN(nx)); + output_report_control (p, id, nx, CB_CHAIN (nx)); } - output_local("/* Report %s: CONTROL %s */\n",p->name,s->name); + + output_local ("/* Report %s: CONTROL %s */\n",p->name,s->name); prvid = 0; - for(i = 0; i < p->num_lines; i++) { - if(p->line_ids[i]->report_control) { + for (i = 0; i < p->num_lines; i++) { + if (p->line_ids[i]->report_control) { struct cb_field *c = cb_code_field (p->line_ids[i]->report_control); - if(c == s) { + if (c == s) { f = p->line_ids[i]; - if(f->report_flag & COB_REPORT_CONTROL_HEADING) { - output_local("/* CONTROL HEADING: %s */\n",s->name); - } else if(f->report_flag & COB_REPORT_CONTROL_FOOTING) { - output_local("/* CONTROL FOOTING: %s */\n",s->name); + if (f->report_flag & COB_REPORT_CONTROL_HEADING) { + output_local ("/* CONTROL HEADING: %s */\n",s->name); + } else if (f->report_flag & COB_REPORT_CONTROL_FOOTING) { + output_local ("/* CONTROL FOOTING: %s */\n",s->name); } - output_local("static cob_report_control_ref %s%d = {", + output_local ("static cob_report_control_ref %s%d = {", CB_PREFIX_REPORT_REF,p->line_ids[i]->id); - if(prvid == 0) { + if (prvid == 0) { output_local("NULL,"); } else { - output_local("&%s%d,",CB_PREFIX_REPORT_REF,prvid); + output_local ("&%s%d,",CB_PREFIX_REPORT_REF,prvid); } - output_local("&%s%d",CB_PREFIX_REPORT_LINE,p->line_ids[i]->id); - output_local("};\n"); + output_local ("&%s%d",CB_PREFIX_REPORT_LINE,p->line_ids[i]->id); + output_local ("};\n"); prvid = p->line_ids[i]->id; } } } output_local ("static cob_report_control %s%d_%d\t= {", CB_PREFIX_REPORT_CONTROL,id,s->id); if(nx) { - output_local("&%s%d_%d,",CB_PREFIX_REPORT_CONTROL,id,cb_code_field(CB_VALUE(nx))->id); + output_local ("&%s%d_%d,",CB_PREFIX_REPORT_CONTROL,id,cb_code_field(CB_VALUE(nx))->id); } else { - output_local("NULL,"); + output_local ("NULL,"); } output_local ("\"%s\",",s->name); - output_local("&%s%d,NULL,NULL",CB_PREFIX_FIELD,s->id); + output_local ("&%s%d,NULL,NULL",CB_PREFIX_FIELD,s->id); bfound = 0; /* CB_PREFIX_REPORT_REF */ - for(i= p->num_lines-1; i >= 0; i--) { - if(p->line_ids[i]->report_control) { + for (i = p->num_lines-1; i >= 0; i--) { + if (p->line_ids[i]->report_control) { struct cb_field *c = cb_code_field (p->line_ids[i]->report_control); if(c == s) { bfound = 1; - output_local(",&%s%d",CB_PREFIX_REPORT_REF,p->line_ids[i]->id); + output_local (",&%s%d",CB_PREFIX_REPORT_REF,p->line_ids[i]->id); break; } } } - if(!bfound) { - printf("Control field %s is not referenced in report\n",s->name); - output_local(",NULL"); + if (!bfound) { + output_local (",NULL"); } seq = i = 0; for (l = p->controls; l; l = CB_CHAIN (l)) { x = CB_VALUE (l); - f = cb_code_field(x); + f = cb_code_field (x); i++; if(s == f) { seq = i; break; } } - output_local(",%d,0,0,0,0",seq); - output_local("};\n"); + output_local (",%d,0,0,0,0",seq); + output_local ("};\n"); } static void @@ -10372,16 +10372,7 @@ output_report_define_lines (int top, struct cb_field *f, struct cb_report *r) sprintf (fname, "%s of ", f->name); } output_local("\n/* %s%s ",fname,r->name); - if ((f->report_flag & COB_REPORT_LINE) - && f->children - && (f->children->report_flag & COB_REPORT_LINE)) { - printf("Warning: Ignoring nested LINE %s %d\n", - (f->report_flag & COB_REPORT_LINE_PLUS)?"PLUS":"", - f->report_line); - f->report_line = 0; - f->report_flag &= ~COB_REPORT_LINE_PLUS; - f->report_flag &= ~COB_REPORT_LINE; - } + cb_emit_ingnoring_nested_line (f); if (f->report_flag & COB_REPORT_LINE) output_local("LINE %s %d ", (f->report_flag & COB_REPORT_LINE_PLUS)?"PLUS":"", @@ -10593,6 +10584,32 @@ output_report_sum_counters (const int top, struct cb_field *f, struct cb_report sum_prv = sum_nxt; } +static void +check_reference_in_report (struct cb_report *p, cb_tree ctl, cb_tree nx) +{ + if (nx) { + check_reference_in_report (p, nx, CB_CHAIN (nx)); + } + + struct cb_field *s; + cb_tree x; + int bfound = 0; + int i; + + x = CB_VALUE (ctl); + s = cb_code_field (x); + for (i = p->num_lines-1; i >= 0; i--) { + if (p->line_ids[i]->report_control) { + struct cb_field *c = cb_code_field (p->line_ids[i]->report_control); + if (c == s) { + bfound = 1; + break; + } + } + } + cb_not_referenced_in_report (bfound, p, s->name); +} + static void output_report_definition (struct cb_report *p, struct cb_report *n) { @@ -10600,22 +10617,26 @@ output_report_definition (struct cb_report *p, struct cb_report *n) struct cb_field *s = NULL; cb_tree l; - output_local("\n"); - for(i= p->num_lines - 1; i >= 0; i--) { + output_local ("\n"); + if (p->controls) { + check_reference_in_report (p, p->controls, CB_CHAIN (p->controls)); + } + for (i = p->num_lines - 1; i >= 0; i--) { if(p->line_ids[i]->level == 1) output_report_define_lines(1,p->line_ids[i], p); } output_local ("\n"); - if(p->controls) { + + if (p->controls) { for (l = p->controls; l; l = CB_CHAIN (l)) { - s = cb_code_field(l); + s = cb_code_field (l); s->count++; } - output_report_control(p,++r_ctl_id,p->controls,CB_CHAIN(p->controls)); + output_report_control (p,++r_ctl_id,p->controls,CB_CHAIN(p->controls)); output_local ("\n"); } sum_prv = 0; - for (i= p->num_lines - 1; i >= 0; i--) { + for (i = p->num_lines - 1; i >= 0; i--) { if (p->line_ids[i]->level == 1) { output_report_sum_counters (1, p->line_ids[i], p); } diff --git a/cobc/tree.h b/cobc/tree.h index fdb2f9e89..e38dba6fe 100644 --- a/cobc/tree.h +++ b/cobc/tree.h @@ -2603,6 +2603,8 @@ extern cb_tree cb_build_xml_parse (cb_tree, cb_tree, const int, cb_tree, cb_tree); extern void cb_emit_json_generate (cb_tree, cb_tree, cb_tree, cb_tree, cb_tree); +extern void cb_emit_ingnoring_nested_line (struct cb_field *f); +extern void cb_not_referenced_in_report (int bfound, struct cb_report *p, const char *name); #ifdef COB_TREE_DEBUG extern cb_tree cobc_tree_cast_check (const cb_tree, const char *, diff --git a/cobc/typeck.c b/cobc/typeck.c index f29df4c8d..e06f872ae 100644 --- a/cobc/typeck.c +++ b/cobc/typeck.c @@ -15662,3 +15662,29 @@ cb_emit_json_generate (cb_tree out, cb_tree from, cb_tree count, cb_emit (CB_BUILD_FUNCALL_4 ("cob_json_generate_new", out, CB_TREE (tree), count, cb_int (decimal_point))); } + +void +cb_emit_ingnoring_nested_line (struct cb_field *f) +{ + if ((f->report_flag & COB_REPORT_LINE) + && f->children + && (f->children->report_flag & COB_REPORT_LINE)) { + cb_warning (COBC_WARN_FILLER, + _("ignoring nested LINE %s %d"), + (f->report_flag & COB_REPORT_LINE_PLUS)?"PLUS":"", + f->report_line); + f->report_line = 0; + f->report_flag &= ~COB_REPORT_LINE_PLUS; + f->report_flag &= ~COB_REPORT_LINE; + } +} + +void +cb_not_referenced_in_report (int bfound, struct cb_report *p, const char *name) +{ + if (!bfound) { + cb_warning (COBC_WARN_FILLER, + _("control field %s is not referenced in report"), name); + p->controls = NULL; + } +} diff --git a/tests/testsuite.src/run_reportwriter.at b/tests/testsuite.src/run_reportwriter.at index dc9552027..0cefff9d5 100644 --- a/tests/testsuite.src/run_reportwriter.at +++ b/tests/testsuite.src/run_reportwriter.at @@ -9626,4 +9626,3 @@ BEFORE FINAL - SHOULD DISPLAY ], []) AT_CLEANUP - diff --git a/tests/testsuite.src/syn_reportwriter.at b/tests/testsuite.src/syn_reportwriter.at index 6dae153f0..5347153fb 100644 --- a/tests/testsuite.src/syn_reportwriter.at +++ b/tests/testsuite.src/syn_reportwriter.at @@ -689,3 +689,51 @@ prog.cob:37: warning: non-numeric PICTURE clause for SUM WSI-V AT_CLEANUP +AT_SETUP([Check if the variable is referenced in the report]) +AT_KEYWORDS([report]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. MAIN. + ENVIRONMENT DIVISION. + CONFIGURATION SECTION. + INPUT-OUTPUT SECTION. + FILE-CONTROL. + SELECT A_1 ASSIGN TO EXTERNAL A_1. + SELECT A_2 ASSIGN TO EXTERNAL A_2. + DATA DIVISION. + FILE SECTION. + FD A_1. + COPY test. + FD A_2 REPORT ETAT. + WORKING-STORAGE SECTION. + REPORT SECTION. + RD ETAT + CONTROL FINAL ERROR-1 ERROR-2 + PAGE LIMIT 66. + PROCEDURE DIVISION. + STOP RUN. +]) + +AT_DATA([test.cpy], [ + 01 TEST-01. + 03 TEST-03. + 88 TEST-88 VALUE "0000000". + 09 ERROR-1. + 88 E-TEST-1 VALUE "111". + 10 E-TEST-10 PIC 9(3). + 03 E-TEST-03. + 04 E-TEST-04. + 05 FILLER PIC X(21). + 88 E-TEST-2 VALUE " SM". + 03 E-TEST-2-03. + 09 ERROR-2 PIC 9(3). +]) + +AT_CHECK([$COMPILE prog.cob], [0], [], +[prog.cob: warning: control field ERROR-1 is not referenced in report +prog.cob: warning: control field ERROR-2 is not referenced in report +]) +AT_CHECK([$COMPILE -w prog.cob], [0], [], []) + +AT_CLEANUP