1 /*
2 Copyright (C) 2001-2020 Free Software Foundation, Inc.
3 Written by Keisuke Nishida, Roger While, Simon Sobisch, Ron Norman,
4 Edward Hart
5
6 This file is part of GnuCOBOL.
7
8 The GnuCOBOL compiler is free software: you can redistribute it
9 and/or modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation, either version 3 of the
11 License, or (at your option) any later version.
12
13 GnuCOBOL is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GnuCOBOL. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22
23 #include <config.h>
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <stddef.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <limits.h>
31
32 #include "cobc.h"
33 #include "tree.h"
34
35 /* sanity checks */
36 #if COB_MAX_FIELD_SIZE > INT_MAX
37 #error COB_MAX_FIELD_SIZE is too big, must be less than INT_MAX
38 #endif
39 #if COB_MAX_UNBOUNDED_SIZE > INT_MAX
40 #error COB_MAX_UNBOUNDED_SIZE is too big, must be less than INT_MAX
41 #endif
42
43 /* Function prototypes */
44 static unsigned int validate_field_1 (struct cb_field *f);
45
46 /* Global variables */
47
48 cb_tree cb_depend_check = NULL;
49 size_t cb_needs_01 = 0;
50
51 /* Local variables */
52
53 static struct cb_field *last_real_field = NULL;
54 static int occur_align_size = 0;
55 static const unsigned char pic_digits[] = { 2, 4, 7, 9, 12, 14, 16, 18 };
56 #define CB_MAX_OPS 32
57 static int op_pos = 1, op_val_pos;
58 static char op_type [CB_MAX_OPS+1];
59 static char op_prec [CB_MAX_OPS+1];
60 static cob_s64_t op_val [CB_MAX_OPS+1];
61 static int op_scale[CB_MAX_OPS+1];
62
63 /* Is list of values really an expression */
64 static int
cb_is_expr(cb_tree ch)65 cb_is_expr (cb_tree ch)
66 {
67 cb_tree t, l;
68 int num;
69
70 if (op_pos >= 0) {
71 for (num=0; num < CB_MAX_OPS; num++) {
72 op_type [num] = ' ';
73 op_prec [num] = 0;
74 op_val [num] = 0;
75 }
76 }
77 op_pos = op_val_pos = -1;
78 num = 0;
79 for (l = ch; l; l = CB_CHAIN (l)) {
80 t = CB_VALUE (l);
81 if (t && CB_LITERAL_P (t)) {
82 if (++num > 1)
83 return 1;
84 }
85 }
86 return 0;
87 }
88
89 static void
cb_eval_op(void)90 cb_eval_op ( void )
91 {
92 cob_s64_t lval, rval, xval;
93 int lscale, rscale, xscale;
94
95 if (op_pos >= 0
96 && op_val_pos > 0) {
97 lval = op_val [op_val_pos-1];
98 lscale = op_scale [op_val_pos-1];
99 rval = op_val [op_val_pos];
100 rscale = op_scale [op_val_pos];
101 op_val_pos--;
102 switch (op_type [op_pos]) {
103 case '+':
104 case '-':
105 while (lscale > rscale) {
106 rval = rval * 10;
107 rscale++;
108 }
109 while (lscale < rscale) {
110 lval = lval * 10;
111 lscale++;
112 }
113 xscale = lscale;
114 if (op_type [op_pos] == '+')
115 xval = lval + rval;
116 else
117 xval = lval - rval;
118 break;
119 case '*':
120 xscale = lscale + rscale;
121 xval = lval * rval;
122 break;
123 case '/':
124 while (rscale > 0) {
125 lval = lval * 10;
126 rscale--;
127 }
128 if (rval == 0) {
129 xscale = 0;
130 xval = 0;
131 cb_error (_("constant expression has Divide by ZERO"));
132 } else {
133 xscale = lscale;
134 xval = lval / rval;
135 }
136 break;
137 case '^':
138 while (rscale > 0) { /* Only whole number exponents */
139 rval = rval / 10;
140 rscale--;
141 }
142 if (rval == 0 || lval == 1) {
143 xval = 1;
144 xscale = 0;
145 } else {
146 xval = lval;
147 xscale = lscale;
148 while(--rval > 0) {
149 xscale = xscale + lscale;
150 xval = xval * lval;
151 }
152 }
153 break;
154 case '&':
155 xscale = 0;
156 xval = (lval && rval);
157 break;
158 case '|':
159 xscale = 0;
160 xval = (lval || rval);
161 break;
162 case '>':
163 xscale = 0;
164 xval = (lval > rval);
165 break;
166 case '<':
167 xscale = 0;
168 xval = (lval < rval);
169 break;
170 case '=':
171 xscale = 0;
172 xval = (lval == rval);
173 break;
174 case ']':
175 xscale = 0;
176 xval = (lval >= rval);
177 break;
178 case '[':
179 xscale = 0;
180 xval = (lval <= rval);
181 break;
182 case '~':
183 xscale = 0;
184 xval = (lval != rval);
185 break;
186 case '(':
187 cb_error (_("missing right parenthesis"));
188 op_pos--;
189 return;
190 default:
191 op_pos--;
192 return;
193 }
194 op_pos--;
195 while (xscale > 0
196 && (xval % 10) == 0) {
197 xscale--;
198 xval = xval / 10;
199 }
200 op_scale [op_val_pos] = xscale;
201 op_val [op_val_pos] = xval;
202 }
203 }
204
205 static void
cb_push_op(char op,int prec)206 cb_push_op ( char op, int prec )
207 {
208 while (op_pos >= 0
209 && op_val_pos > 0
210 && prec > 0
211 && op_type [op_pos] != '('
212 && prec <= op_prec [op_pos]) {
213 cb_eval_op ();
214 }
215 if (op_pos >= CB_MAX_OPS) {
216 cb_error (_("expression stack overflow at %d entries for operation '%c'"), op_pos, op);
217 return;
218 }
219 op_pos++;
220 op_type [op_pos] = op;
221 op_prec [op_pos] = (char) prec;
222 }
223
224 /* Evaluate expression and store as new Numeric Literal */
225 static cb_tree
cb_evaluate_expr(cb_tree ch,int normal_prec)226 cb_evaluate_expr (cb_tree ch, int normal_prec)
227 {
228 cb_tree t, l;
229 cob_s64_t xval;
230 int unop = 1, xscale, k;
231 char result[48];
232 struct cb_literal *lp;
233
234 for (l = ch; l; l = CB_CHAIN (l)) {
235 t = CB_VALUE (l);
236 if (t && CB_LITERAL_P (t)) {
237 lp = CB_LITERAL (t);
238 if (CB_NUMERIC_LITERAL_P (t)) {
239 xval = atoll((const char *)lp->data);
240 xscale = lp->scale;
241 if (unop) {
242 if (lp->sign < 0) /* Unary op, change sign */
243 xval = -xval;
244 } else {
245 if (lp->sign < 0) { /* Treat 'sign' as binary op */
246 cb_push_op ('-', 4);
247 } else if (lp->sign > 0) {
248 cb_push_op ('+', 4);
249 }
250 }
251 while (xscale > 0
252 && (xval % 10) == 0) { /* Remove decimal zeros */
253 xscale--;
254 xval = xval / 10;
255 }
256 if (op_val_pos >= CB_MAX_OPS) {
257 cb_error (_("expression stack overflow at %d entries"), op_val_pos);
258 return cb_error_node;
259 }
260 op_val_pos++;
261 op_val [op_val_pos] = xval;
262 op_scale [op_val_pos] = xscale;
263 unop = 0;
264 } else {
265 switch (lp->data[0]) {
266 case '(':
267 cb_push_op ('(', 0);
268 unop = 1;
269 break;
270 case ')':
271 unop = 0;
272 for (k=op_pos; k > 0 && op_type[k] != '('; k--);
273 if (op_type [k] != '(')
274 cb_error (_("missing left parenthesis"));
275 while (op_pos >= 0
276 && op_val_pos > 0) {
277 if (op_type [op_pos] == '(') {
278 break;
279 }
280 cb_eval_op ();
281 }
282 if (op_pos >= 0
283 && op_type [op_pos] == '(')
284 op_pos--;
285 break;
286 case '+':
287 cb_push_op ('+', 4);
288 unop = 1;
289 break;
290 case '-':
291 cb_push_op ('-', 4);
292 unop = 1;
293 break;
294 case '*':
295 cb_push_op ('*', normal_prec ? 6 : 4);
296 unop = 1;
297 break;
298 case '/':
299 cb_push_op ('/', normal_prec ? 6 : 4);
300 unop = 1;
301 break;
302 case '&':
303 cb_push_op ('&', normal_prec ? 8 : 4);
304 unop = 1;
305 break;
306 case '|':
307 cb_push_op ('|', normal_prec ? 8 : 4);
308 unop = 1;
309 break;
310 case '^':
311 cb_push_op ('^', normal_prec ? 7 : 4);
312 unop = 1;
313 break;
314 default:
315 cb_error (_("invalid operator '%s' in expression"),lp->data);
316 break;
317 }
318 }
319 }
320 }
321 while (op_pos >= 0
322 && op_val_pos > 0) {
323 if (op_type [op_pos] == '(') {
324 cb_error (_("missing right parenthesis"));
325 op_pos--;
326 continue;
327 }
328 cb_eval_op ();
329 }
330 if (op_pos >= 0) {
331 if (op_type[op_pos] == '(') {
332 cb_error (_("missing right parenthesis"));
333 } else {
334 cb_error (_("'%c' operator misplaced"), op_type [op_pos]);
335 }
336 }
337 xval = op_val [0];
338 xscale = op_scale [0];
339 while (xscale > 0) { /* Reduce to 'fixed point numeric' */
340 xscale--;
341 xval = xval / 10;
342 }
343 while (xscale < 0) { /* Reduce to 'fixed point numeric' */
344 xscale++;
345 xval = xval * 10;
346 }
347 sprintf (result, CB_FMT_LLD, xval);
348 return cb_build_numeric_literal (0, result, xscale);
349 }
350
351 int
cb_get_level(cb_tree x)352 cb_get_level (cb_tree x)
353 {
354 #if 1 /* level always contains a valid tree with valid numeric values only
355 --> all validation is done in scanner.l */
356 return atoi (CB_NAME (x));
357 #else
358 const unsigned char *p;
359 const char *name;
360 int level;
361
362 if (CB_INVALID_TREE (x)) {
363 return 0;
364 }
365 name = CB_NAME (x);
366 level = 0;
367 /* Get level */
368 for (p = (const unsigned char *)name; *p; p++) {
369 if (!isdigit ((int)(*p))) {
370 goto level_error;
371 }
372 level = level * 10 + (*p - '0');
373 if (level > 88) {
374 goto level_error;
375 }
376 }
377
378 /* Check level */
379 switch (level) {
380 case 66:
381 case 77:
382 case 78:
383 case 88:
384 break;
385 default:
386 if (level < 1 || level > 49) {
387 goto level_error;
388 }
389 break;
390 }
391
392 return level;
393
394 level_error:
395 cb_error_x (x, _("invalid level number '%s'"), name);
396 return 0;
397 #endif
398 }
399
400 cb_tree
cb_build_field_tree(cb_tree level,cb_tree name,struct cb_field * last_field,enum cb_storage storage,struct cb_file * fn,const int expl_level)401 cb_build_field_tree (cb_tree level, cb_tree name, struct cb_field *last_field,
402 enum cb_storage storage, struct cb_file *fn,
403 const int expl_level)
404 {
405 struct cb_reference *r;
406 struct cb_field *f;
407 struct cb_field *p;
408 struct cb_field *field_fill;
409 cb_tree dummy_fill;
410 cb_tree l;
411 cb_tree x;
412 int lv;
413
414 if (!expl_level) {
415 /* note: the level number is always a valid tree here, but the
416 name may be a defined constant which leads to an error node */
417 if (name == cb_error_node) {
418 return cb_error_node;
419 }
420 /* Check the level number */
421 lv = cb_get_level (level);
422 #if 0 /*level is always valid --> 01 thru 49, 77, 66, 78, 88 */
423 if (!lv) {
424 return cb_error_node;
425 }
426 #endif
427 } else {
428 lv = expl_level;
429 }
430
431 /* Build the field */
432 r = CB_REFERENCE (name);
433 f = CB_FIELD (cb_build_field (name));
434 f->storage = storage;
435 last_real_field = last_field;
436 if (lv == 78) {
437 f->level = 01;
438 f->flag_item_78 = 1;
439 f->flag_constant = 0;
440 return CB_TREE (f);
441 } else {
442 f->level = lv;
443 }
444 if (f->level == 01 && storage == CB_STORAGE_FILE && fn) {
445 if (fn->flag_external) {
446 f->flag_external = 1;
447 current_program->flag_has_external = 1;
448 } else if (fn->flag_global) {
449 f->flag_is_global = 1;
450 }
451 }
452 if (last_field) {
453 if (last_field->level == 77 && f->level != 01 &&
454 f->level != 77 && f->level != 66 && f->level != 88) {
455 cb_error_x (name, _("level number must begin with 01 or 77"));
456 return cb_error_node;
457 }
458 }
459
460 /* Checks for redefinition */
461 if (cb_warn_opt_val[cb_warn_redefinition]
462 && r->word->count > 1 && !r->flag_filler_ref) {
463 if (f->level == 01 || f->level == 77) {
464 redefinition_warning (name, NULL);
465 } else {
466 for (l = r->word->items; l; l = CB_CHAIN (l)) {
467 x = CB_VALUE (l);
468 if (!CB_FIELD_P (x) ||
469 CB_FIELD (x)->level == 01 ||
470 CB_FIELD (x)->level == 77 ||
471 (last_field && f->level == last_field->level &&
472 CB_FIELD (x)->parent == last_field->parent)) {
473 redefinition_warning (name, x);
474 break;
475 }
476 }
477 }
478 }
479
480 if (last_field && last_field->level == 88) {
481 last_field = last_field->parent;
482 }
483
484 /* Link the field into the tree */
485 if (f->level == 01 || f->level == 77) {
486 /* Top level */
487 cb_needs_01 = 0;
488 if (last_field) {
489 cb_field_founder (last_field)->sister = f;
490 }
491 } else if (!last_field || cb_needs_01) {
492 /* Invalid top level */
493 cb_error_x (name, _("level number must begin with 01 or 77"));
494 return cb_error_node;
495 } else if (f->level == 66) {
496 /* Level 66 */
497 f->parent = cb_field_founder (last_field);
498 for (p = f->parent->children; p && p->sister; p = p->sister) ;
499 if (p) {
500 p->sister = f;
501 }
502 } else if (f->level == 88) {
503 /* Level 88 */
504 f->parent = last_field;
505 if (last_real_field && last_real_field->level == 88) {
506 /* Level 88 sister */
507 last_real_field->sister = f;
508 } else {
509 /* First Level 88 on this item */
510 last_field->validation = f;
511 last_field = f;
512 }
513 } else if (f->level > last_field->level) {
514 /* Lower level */
515 last_field->children = f;
516 f->parent = last_field;
517 } else if (f->level == last_field->level) {
518 /* Same level */
519 same_level:
520 last_field->sister = f;
521 f->parent = last_field->parent;
522 } else {
523 /* Upper level */
524 for (p = last_field->parent; p /* <- silence warnings */; p = p->parent) {
525 if (p->level == f->level) {
526 last_field = p;
527 goto same_level;
528 }
529 if (cb_relax_level_hierarchy && p->level < f->level) {
530 break;
531 }
532 }
533 if (cb_relax_level_hierarchy
534 && p /* <- silence warnings */) {
535 dummy_fill = cb_build_filler ();
536 field_fill = CB_FIELD (cb_build_field (dummy_fill));
537 cb_warning_x (COBC_WARN_FILLER, name,
538 _("no previous data item of level %02d"),
539 f->level);
540 field_fill->level = f->level;
541 field_fill->flag_filler = 1;
542 field_fill->storage = storage;
543 field_fill->children = p->children;
544 field_fill->parent = p;
545 for (p = p->children; p; p = p->sister) {
546 p->parent = field_fill;
547 }
548 field_fill->parent->children = field_fill;
549 field_fill->sister = f;
550 f->parent = field_fill->parent;
551 /* last_field = field_fill; */
552 } else {
553 cb_error_x (name,
554 _("no previous data item of level %02d"),
555 f->level);
556 return cb_error_node;
557 }
558 }
559
560 /* Inherit parents properties */
561 if (f->parent) {
562 struct cb_field *parent = f->parent;
563 f->usage = parent->usage;
564 f->indexes = parent->indexes;
565 f->flag_sign_leading = parent->flag_sign_leading;
566 f->flag_sign_separate = parent->flag_sign_separate;
567 f->flag_is_global = parent->flag_is_global;
568 if (f->level <= 66) {
569 f->flag_volatile = parent->flag_volatile;
570 }
571 }
572
573 return CB_TREE (f);
574 }
575
576 cb_tree
cb_build_full_field_reference(struct cb_field * field)577 cb_build_full_field_reference (struct cb_field* field)
578 {
579 cb_tree ret = NULL;
580 cb_tree ref = NULL;
581 cb_tree rchain = NULL;
582
583 while (field) {
584 if (field->flag_filler) continue;
585 rchain = cb_build_reference (field->name);
586 if (ref) {
587 CB_REFERENCE (ref)->chain = rchain;
588 } else {
589 ret = rchain;
590 }
591 ref = rchain;
592 field = field->parent;
593 }
594
595 return ret;
596 }
597
598 struct cb_field *
cb_resolve_redefines(struct cb_field * field,cb_tree redefines)599 cb_resolve_redefines (struct cb_field *field, cb_tree redefines)
600 {
601 struct cb_field *f;
602 struct cb_reference *r;
603 const char *name;
604 cb_tree x;
605 cb_tree candidate;
606 cb_tree items;
607
608 r = CB_REFERENCE (redefines);
609 name = CB_NAME (redefines);
610 x = CB_TREE (field);
611
612 /* Check qualification */
613 if (r->chain) {
614 cb_error_x (x, _("'%s' cannot be qualified here"), name);
615 return NULL;
616 }
617
618 /* Check subscripts */
619 if (r->subs) {
620 cb_error_x (x, _("'%s' cannot be subscripted here"), name);
621 return NULL;
622 }
623
624 /* Resolve the name in the current group (if any) */
625 if (field->parent && field->parent->children) {
626 for (f = field->parent->children; f; f = f->sister) {
627 if (strcasecmp (f->name, name) == 0) {
628 break;
629 }
630 }
631 if (f == NULL) {
632 cb_error_x (x, _("'%s' is not defined in '%s'"), name, field->parent->name);
633 return NULL;
634 }
635 } else {
636 /* Get last defined name */
637 candidate = NULL;
638 items = r->word->items;
639 for (; items; items = CB_CHAIN (items)) {
640 if (CB_FIELD_P (CB_VALUE (items))) {
641 candidate = CB_VALUE (items);
642 }
643 }
644 if (!candidate) {
645 undefined_error (redefines);
646 return NULL;
647 }
648 f = CB_FIELD_PTR (candidate);
649 }
650
651 /* Check level number */
652 if (f->level != field->level) {
653 cb_error_x (x, _("level number of REDEFINES entries must be identical"));
654 return NULL;
655 }
656
657 if (!cb_indirect_redefines && f->redefines) {
658 cb_error_x (x, _("'%s' is not the original definition"), f->name);
659 return NULL;
660 }
661
662 /* Return the original definition */
663 while (f->redefines) {
664 f = f->redefines;
665 }
666 return f;
667 }
668
669 static void copy_into_field_recursive (struct cb_field *, struct cb_field *, const int);
670
671 static void
copy_children(struct cb_field * child,struct cb_field * target,const int level,const int outer_indexes,const enum cb_storage storage)672 copy_children (struct cb_field *child, struct cb_field *target,
673 const int level, const int outer_indexes, const enum cb_storage storage)
674 {
675 int level_child;
676 cb_tree n, x;
677
678 if (child->level > level) {
679 level_child = child->level;
680 } else {
681 level_child = level + 1;
682 if (level_child == 66 || level_child == 78 || level_child == 88) {
683 level_child++;
684 } else if (level_child == 77) {
685 level_child = 79;
686 }
687 }
688
689 if (child->name) {
690 n = cb_build_reference (child->name);
691 } else {
692 n = cb_build_filler ();
693 }
694 x = cb_build_field_tree (NULL, n, target, storage, NULL, level_child);
695 if (x != cb_error_node) {
696 copy_into_field_recursive (child, CB_FIELD (x), outer_indexes);
697 }
698 }
699
700 #define field_attribute_copy(attribute) \
701 if (source->attribute) target->attribute = source->attribute
702 #define field_attribute_override(attribute) \
703 target->attribute = source->attribute
704
705 static void
copy_into_field_recursive(struct cb_field * source,struct cb_field * target,const int outer_indexes)706 copy_into_field_recursive (struct cb_field *source, struct cb_field *target,
707 const int outer_indexes)
708 {
709 field_attribute_override (usage);
710
711 /* checkme: how to handle DEPENDING and INDICES here ? */
712 field_attribute_override (occurs_min);
713 field_attribute_override (occurs_max);
714 field_attribute_override (flag_occurs);
715 if (CB_VALID_TREE (source->depending)) {
716 #if 0 /* TODO: check if DEPENDING field is part of the original TYPEDEF,
717 if yes then full-qualify the reference */
718 struct cb_field *dep_field = CB_FIELD_PTR (source->depending);
719 struct cb_field *field;
720 target->depending = cb_build_reference (CB_NAME(source->depending));
721 dep_field = dep_field->parent;
722 if (dep_field) {
723 for (field = target->parent; field; field = field->parent) {
724 if (dep_field == field) {
725 cb_tree rchain = cb_build_full_field_reference (field);
726 CB_REFERENCE (target->depending)->chain = rchain;
727 break;
728 }
729 }
730 }
731 #else
732 target->depending = cb_build_reference (CB_NAME (source->depending));
733 #endif
734 CB_ADD_TO_CHAIN (target->depending, current_program->reference_list);
735 }
736 field_attribute_override (nkeys);
737 if (source->keys) {
738 cb_tree ref = NULL;
739 cb_tree rchain = NULL;
740 int i;
741
742 /* create reference chaing all the way up
743 as later fields may have same name */
744 rchain = cb_build_full_field_reference (target);
745
746 target->keys = cobc_parse_malloc (sizeof (struct cb_key) * target->nkeys);
747 for (i = 0; i < target->nkeys; i++) {
748 const struct cb_reference* r = CB_REFERENCE (source->keys[i].key);
749 ref = cb_build_reference (r->word->name);
750 CB_REFERENCE (ref)->chain = rchain;
751 target->keys[i].key = ref;
752 CB_ADD_TO_CHAIN (ref, current_program->reference_list);
753 field_attribute_override (keys[i].dir);
754 }
755 }
756 if (source->index_list) {
757 cb_tree x;
758 target->index_list = NULL;
759 for (x = source->index_list; x; x = CB_CHAIN (x)) {
760 cb_tree ind_ref = cb_build_reference (CB_FIELD_PTR (CB_VALUE (x))->name);
761 cb_tree entry = cb_build_index (ind_ref, cb_int1, 1U, target);
762 CB_FIELD_PTR (entry)->index_type = CB_STATIC_INT_INDEX;
763 if (!target->index_list) {
764 target->index_list = CB_LIST_INIT (entry);
765 } else {
766 target->index_list = cb_list_add (target->index_list, entry);
767 }
768 }
769 }
770
771 field_attribute_override (values);
772 field_attribute_override (flag_blank_zero);
773 field_attribute_override (flag_justified);
774 field_attribute_override (flag_sign_clause);
775 field_attribute_override (flag_sign_leading);
776 field_attribute_override (flag_sign_separate);
777 field_attribute_override (flag_synchronized);
778 field_attribute_override (flag_item_based);
779 field_attribute_override (flag_any_length);
780 field_attribute_override (flag_any_numeric);
781 field_attribute_override (flag_invalid);
782
783 if (CB_VALID_TREE (source->redefines)) {
784 cb_tree ref = cb_build_reference (source->redefines->name);
785 target->redefines = cb_resolve_redefines (target, ref);
786 }
787
788 if (source->children) {
789 copy_children (source->children, target, target->level, outer_indexes, target->storage);
790 } else if (source->pic){
791 target->pic = CB_PICTURE (cb_build_picture (source->pic->orig));
792 }
793
794 if (source->sister) {
795 /* for children: all sister entries need to be copied */
796 cb_tree n, x;
797 if (source->sister->name) {
798 n = cb_build_reference (source->sister->name);
799 } else {
800 n = cb_build_filler ();
801 }
802 x = cb_build_field_tree (NULL, n, target, target->storage, NULL, target->level);
803 if (x != cb_error_node) {
804 copy_into_field_recursive (source->sister, CB_FIELD (x), outer_indexes);
805 }
806 }
807 /* special case: normally incremented during parse */
808 target->indexes = source->indexes + outer_indexes;
809 cb_validate_field (target);
810 }
811
812
813 /* note: same message in parser.y */
814 static int
duplicate_clause_message(cb_tree x,const char * clause)815 duplicate_clause_message (cb_tree x, const char *clause)
816 {
817 /* FIXME: replace by a new warning level that is set
818 to warn/error depending on cb_relaxed_syntax_checks */
819 if (cb_relaxed_syntax_checks) {
820 cb_warning_x (COBC_WARN_FILLER, x, _("duplicate %s clause"), clause);
821 return 0;
822 }
823
824 cb_error_x (x, _("duplicate %s clause"), clause);
825 return 1;
826 }
827
828 void
copy_into_field(struct cb_field * source,struct cb_field * target)829 copy_into_field (struct cb_field *source, struct cb_field *target)
830 {
831 #if 0
832 cb_tree external_definition = target->external_definition;
833 #endif
834
835 /* note: EXTERNAL is always applied from the typedef (if level (1/77),
836 but may be specified on the field */
837 if (target->level == 1 || target->level == 77) {
838 field_attribute_copy (flag_external);
839 }
840 target->usage = source->usage;
841 if (source->values) {
842 if (target->values) {
843 duplicate_clause_message (target->values, "VALUE");
844 } else {
845 target->values = source->values;
846 }
847 }
848 field_attribute_copy (flag_blank_zero);
849 field_attribute_copy (flag_justified);
850 field_attribute_copy (flag_sign_clause);
851 field_attribute_copy (flag_sign_leading);
852 field_attribute_copy (flag_sign_separate);
853 field_attribute_copy (flag_synchronized);
854 field_attribute_copy (flag_item_based);
855 field_attribute_override (flag_any_length);
856 field_attribute_override (flag_any_numeric);
857
858 if (unlikely (!target->like_modifier)) {
859 if (source->children) {
860 copy_children (source->children, target, target->level, target->indexes, target->storage);
861 } else if (source->pic) {
862 target->pic = CB_PICTURE (cb_build_picture (source->pic->orig));
863 }
864 } else {
865 struct cb_picture* new_pic = NULL;
866 int modifier = cb_get_int (target->like_modifier);
867 if (modifier) {
868 switch (target->usage) {
869
870 case CB_USAGE_COMP_X:
871 case CB_USAGE_COMP_N:
872 if (target->pic->category == CB_CATEGORY_ALPHANUMERIC) {
873 char pic[8];
874 unsigned char newsize;
875 if (target->pic->size > 8) {
876 newsize = 36;
877 } else {
878 newsize = pic_digits[target->pic->size - 1];
879 }
880 newsize += modifier;
881 if (newsize > 36) {
882 newsize = 36;
883 }
884 sprintf (pic, "9(%u)", newsize);
885 new_pic = CB_PICTURE (cb_build_picture (pic));
886 break;
887 }
888
889 case CB_USAGE_BINARY:
890 case CB_USAGE_PACKED:
891 case CB_USAGE_COMP_5:
892 case CB_USAGE_COMP_6:
893 if (target->pic->orig[0] == '9') {
894 char pic[38];
895 /* only a prototype here,
896 TODO: add handling for S and friends... */
897 if (modifier > 0) {
898 sprintf (pic, "9(%d)", modifier);
899 strcat (pic, target->pic->orig);
900 new_pic = CB_PICTURE (cb_build_picture (pic));
901 } else {
902 CB_PENDING_X (CB_TREE (target), "LIKE ... negative-integer");
903 }
904 } else {
905 cb_error_x (CB_TREE (target), _ ("%s clause not compatible with PIC %s"),
906 "LIKE", target->pic->orig);
907 target->flag_invalid = 1;
908 }
909 break;
910
911 case CB_USAGE_DISPLAY:
912 case CB_USAGE_NATIONAL:
913 break;
914
915 default:
916 cb_error_x (CB_TREE (target), _("%s clause not compatible with USAGE %s"),
917 "LIKE", cb_get_usage_string (target->usage));
918 target->flag_invalid = 1;
919 }
920
921 #if 0 /* TODO, also syntax-check for usage here */
922 if (target->cat is_numeric) {
923 sprintf (pic, "9(%d)", size_implied);
924 } else {
925 sprintf (pic, "X(%d)", size_implied);
926 }
927 new_pic = CB_PICTURE (cb_build_picture (pic));
928 #endif
929 }
930 if (new_pic) {
931 target->pic = new_pic;
932 } else if (target->pic) {
933 target->pic = CB_PICTURE (cb_build_picture (target->pic->orig));
934 }
935 }
936
937 /* adjust reference counter to allow "no codegen" if only used as type */
938 source->count--;
939 #if 0
940 target->count--;
941 target->external_definition = external_definition;
942 #endif
943
944 /* validate field to ensure applying its own attributes
945 in relation to its childs) */
946 cb_validate_field (target);
947 }
948
949 static COB_INLINE COB_A_INLINE void
emit_incompatible_pic_and_usage_error(cb_tree item,const enum cb_usage usage)950 emit_incompatible_pic_and_usage_error (cb_tree item, const enum cb_usage usage)
951 {
952 cb_error_x (item, _("%s clause not compatible with USAGE %s"),
953 "PICTURE", cb_get_usage_string (usage));
954 }
955
956 static COB_INLINE COB_A_INLINE int
is_numeric_usage(const enum cb_usage usage)957 is_numeric_usage (const enum cb_usage usage)
958 {
959 switch (usage) {
960 case CB_USAGE_DISPLAY:
961 case CB_USAGE_NATIONAL:
962 case CB_USAGE_OBJECT:
963 return 0;
964 /* case CB_USAGE_ERROR: assume numeric */
965 default:
966 return 1;
967 }
968 }
969
970 /* create an implicit picture for items that miss it but need one,
971 return 1 if not possible */
972 static unsigned int
create_implicit_picture(struct cb_field * f)973 create_implicit_picture (struct cb_field *f)
974 {
975 cb_tree x = CB_TREE (f);
976 cb_tree first_value;
977 char *pp;
978 struct cb_literal *lp;
979 int size_implied = 1;
980 int is_numeric = 0;
981 int ret;
982 char pic[24];
983
984 if (f->values) {
985 first_value = CB_VALUE (f->values);
986 if (first_value == cb_error_node) {
987 first_value = NULL;
988 } else {
989 if (CB_LITERAL_P (first_value)) {
990 size_implied = (int)CB_LITERAL (first_value)->size;
991 is_numeric = CB_NUMERIC_LITERAL_P (first_value);
992 } else if (CB_CONST_P (first_value)) {
993 size_implied = 1;
994 if (first_value == cb_zero) {
995 is_numeric = 1;
996 } else {
997 is_numeric = 0;
998 }
999 } else {
1000 cobc_err_msg (_("unexpected tree tag: %d"), (int)CB_TREE_TAG (x));
1001 COBC_ABORT (); /* LCOV_EXCL_LINE */
1002 }
1003 }
1004 } else {
1005 first_value = NULL;
1006 }
1007
1008 if (!first_value) {
1009 /* FIXME: ensure this in another place */
1010 if (f->flag_item_78) {
1011 level_require_error (x, "VALUE");
1012 return 1;
1013 }
1014 is_numeric = is_numeric_usage (f->usage);
1015 }
1016
1017 if (f->storage == CB_STORAGE_SCREEN) {
1018 cb_tree impl_tree = f->screen_from ? f->screen_from : f->screen_to ? f->screen_to : NULL;
1019 if (impl_tree) {
1020 if (impl_tree == cb_error_node) {
1021 return 1;
1022 }
1023 if (!CB_CONST_P (impl_tree)) {
1024 size_implied = cb_field_size (impl_tree);
1025 is_numeric = CB_TREE_CATEGORY (impl_tree) == CB_CATEGORY_NUMERIC;
1026 } else {
1027 size_implied = FIELD_SIZE_UNKNOWN;
1028 }
1029 } else if (first_value) {
1030 /* done later*/
1031 } else {
1032 f->flag_no_field = 1;
1033 f->pic = CB_PICTURE (cb_build_picture ("X"));
1034 return 0;
1035 }
1036
1037 if (size_implied == FIELD_SIZE_UNKNOWN) {
1038 cb_error_x (x, _("PICTURE clause required for '%s'"),
1039 cb_name (x));
1040 return 1;
1041 }
1042
1043 if (is_numeric) {
1044 sprintf (pic, "9(%d)", size_implied);
1045 } else {
1046 sprintf (pic, "X(%d)", size_implied);
1047 }
1048 f->pic = CB_PICTURE (cb_build_picture (pic));
1049 return 0;
1050 }
1051
1052 if (f->storage == CB_STORAGE_REPORT) {
1053 if (first_value) {
1054 sprintf (pic, "X(%d)", size_implied);
1055 } else {
1056 /* CHECKME: Where do we want to generate a not-field in the C code?
1057 instead of raising an error here? */
1058 f->flag_no_field = 1;
1059 strcpy (pic, "X");
1060 }
1061 f->pic = CB_PICTURE (cb_build_picture (pic));
1062 return 0;
1063 }
1064
1065 if (f->flag_item_78 && first_value && CB_LITERAL_P (first_value)) {
1066 #if 0 /* CHECKME: Do we need this here? */
1067 f->count++;
1068 #endif
1069 lp = CB_LITERAL (first_value);
1070 if (CB_NUMERIC_LITERAL_P (first_value)) {
1071 memset (pic, 0, sizeof (pic));
1072 pp = pic;
1073 if (lp->sign) {
1074 *pp++ = 'S';
1075 }
1076 size_implied = (int)lp->size - lp->scale;
1077 if (size_implied) {
1078 pp += sprintf (pp, "9(%d)", size_implied);
1079 }
1080 if (lp->scale) {
1081 sprintf (pp, "V9(%d)", lp->scale);
1082 }
1083 if (lp->size < 10) {
1084 f->usage = CB_USAGE_COMP_5;
1085 } else {
1086 f->usage = CB_USAGE_DISPLAY;
1087 }
1088 f->pic = CB_PICTURE (cb_build_picture (pic));
1089 f->pic->category = CB_CATEGORY_NUMERIC;
1090 } else {
1091 sprintf (pic, "X(%d)", (int)lp->size);
1092 f->pic = CB_PICTURE (cb_build_picture (pic));
1093 f->pic->category = CB_CATEGORY_ALPHANUMERIC;
1094 f->usage = CB_USAGE_DISPLAY;
1095 }
1096 return 0;
1097 }
1098
1099 ret = 0;
1100
1101 if (f->level == 1 || f->level == 77 || !first_value) {
1102 cb_error_x (x, _("PICTURE clause required for '%s'"),
1103 cb_name (x));
1104 ret = 1;
1105 }
1106
1107 if (first_value && CB_NUMERIC_LITERAL_P (first_value)) {
1108 if (!is_numeric_usage(f->usage)) {
1109 cb_error_x (x, _("a non-numeric literal is expected for '%s'"),
1110 cb_name (x));
1111 }
1112 if (!ret) {
1113 cb_error_x (x, _("PICTURE clause required for '%s'"),
1114 cb_name (x));
1115 ret = 1;
1116 }
1117 }
1118
1119 /* Checkme: should we raise an error for !cb_relaxed_syntax_checks? */
1120 if (!ret) {
1121 cb_warning_x (cb_warn_additional, x, _("defining implicit picture size %d for '%s'"),
1122 size_implied, cb_name (x));
1123 }
1124 if (is_numeric) {
1125 sprintf (pic, "9(%d)", size_implied);
1126 } else {
1127 sprintf (pic, "X(%d)", size_implied);
1128 }
1129 f->pic = CB_PICTURE (cb_build_picture (pic));
1130 f->pic->category = CB_CATEGORY_ALPHANUMERIC;
1131 f->usage = CB_USAGE_DISPLAY;
1132 return ret;
1133 }
1134
1135 static unsigned int
validate_any_length_item(struct cb_field * f)1136 validate_any_length_item (struct cb_field *f)
1137 {
1138 cb_tree x = CB_TREE (f);
1139
1140 if (f->storage != CB_STORAGE_LINKAGE) {
1141 cb_error_x (x, _("'%s' ANY LENGTH only allowed in LINKAGE"), cb_name (x));
1142 return 1;
1143 }
1144 if (f->level != 01) {
1145 cb_error_x (x, _("'%s' ANY LENGTH must be 01 level"), cb_name (x));
1146 return 1;
1147 }
1148 if (f->flag_item_based || f->flag_external) {
1149 cb_error_x (x, _("'%s' ANY LENGTH cannot be BASED/EXTERNAL"), cb_name (x));
1150 return 1;
1151 }
1152 if (f->flag_occurs || f->depending ||
1153 f->children || f->values || f->flag_blank_zero) {
1154 cb_error_x (x, _("'%s' ANY LENGTH has invalid definition"), cb_name (x));
1155 return 1;
1156 }
1157 if (!f->pic) {
1158 if (f->flag_any_numeric) {
1159 f->pic = CB_PICTURE (cb_build_picture ("9"));
1160 } else {
1161 f->pic = CB_PICTURE (cb_build_picture ("X"));
1162 }
1163 } else if (f->flag_any_numeric) {
1164 if (f->pic->category != CB_CATEGORY_NUMERIC) {
1165 cb_error_x (x, _("'%s' ANY NUMERIC must be PIC 9"),
1166 f->name);
1167 }
1168 } else if (f->pic->category != CB_CATEGORY_ALPHANUMERIC
1169 && f->pic->category != CB_CATEGORY_NATIONAL
1170 && f->pic->category != CB_CATEGORY_BOOLEAN) {
1171 cb_error_x (x, _("'%s' ANY LENGTH must be PIC X, PIC N or PIC 1"),
1172 f->name);
1173 }
1174 /*
1175 TO-DO: Replace pic->category check with f->usage == CB_USAGE_NATIONAL.
1176 Currently NATIONAL items are marked as having USAGE DISPLAY.
1177 */
1178 if (!((f->pic->size == 1 && f->usage == CB_USAGE_DISPLAY)
1179 || (f->pic->size == 2 && f->pic->category == CB_CATEGORY_NATIONAL))) {
1180 if (f->flag_any_numeric) {
1181 cb_error_x (x, _("'%s' ANY NUMERIC has invalid definition"), cb_name (x));
1182 } else {
1183 cb_error_x (x, _("'%s' ANY LENGTH has invalid definition"), cb_name (x));
1184 }
1185 return 1;
1186 }
1187
1188 /* CHECKME: Why do we increase the reference counter here
1189 (to ensure the field is generated)?
1190 Better would be to add the check for 'f->count != 0' to the place
1191 where it possibly is missing... */
1192 f->count++;
1193 return 0;
1194 }
1195
1196 static void
validate_external(const struct cb_field * const f)1197 validate_external (const struct cb_field * const f)
1198 {
1199 const cb_tree x = CB_TREE (f);
1200
1201 if (f->level != 01 && f->level != 77) {
1202 cb_error_x (x, _("'%s' EXTERNAL must be specified at 01/77 level"), cb_name (x));
1203 }
1204 if (f->storage != CB_STORAGE_WORKING &&
1205 f->storage != CB_STORAGE_FILE) {
1206 cb_error_x (x, _("'%s' EXTERNAL can only be specified in WORKING-STORAGE section"),
1207 cb_name (x));
1208 }
1209 if (f->flag_item_based) {
1210 cb_error_x (x, _("'%s' EXTERNAL and BASED are mutually exclusive"), cb_name (x));
1211 }
1212 if (f->redefines) {
1213 cb_error_x (x, _("'%s' EXTERNAL not allowed with REDEFINES"), cb_name (x));
1214 }
1215 }
1216
1217 static void
validate_based(const struct cb_field * const f)1218 validate_based (const struct cb_field * const f)
1219 {
1220 const cb_tree x = CB_TREE (f);
1221
1222 if (f->storage != CB_STORAGE_WORKING &&
1223 f->storage != CB_STORAGE_LOCAL &&
1224 f->storage != CB_STORAGE_LINKAGE) {
1225 cb_error_x (x, _("'%s' BASED not allowed here"), cb_name (x));
1226 }
1227 if (f->redefines) {
1228 cb_error_x (x, _("'%s' BASED not allowed with REDEFINES"), cb_name (x));
1229 }
1230 if (f->level != 01 && f->level != 77) {
1231 cb_error_x (x, _("'%s' BASED only allowed at the 01 and 77 levels"), cb_name (x));
1232 }
1233 }
1234
1235 static void
validate_occurs(const struct cb_field * const f)1236 validate_occurs (const struct cb_field * const f)
1237 {
1238 const cb_tree x = CB_TREE (f);
1239 const struct cb_field *p;
1240
1241 if ((f->level == 01 || f->level == 77)
1242 && !cb_verify_x (x, cb_top_level_occurs_clause, "01/77 OCCURS")) {
1243 cb_error_x (x, _("level %02d item '%s' cannot have a %s clause"),
1244 f->level, cb_name (x), "OCCURS");
1245 }
1246
1247 /* Validate OCCURS DEPENDING */
1248 if (f->depending) {
1249 /* Cache field for later checking */
1250 cb_depend_check = cb_list_add (cb_depend_check, x);
1251
1252 if (!cb_complex_odo) {
1253 /* The data item that contains a OCCURS DEPENDING clause shall not
1254 be subordinate to a data item that has an OCCURS clause */
1255 for (p = f->parent; p; p = p->parent) {
1256 if (p->flag_occurs) {
1257 cb_error_x (CB_TREE (p),
1258 _("'%s' cannot have the OCCURS clause due to '%s'"),
1259 cb_name (CB_TREE (p)),
1260 cb_name (x));
1261 break;
1262 }
1263 }
1264 }
1265 }
1266 }
1267
1268 static void
validate_redefines(const struct cb_field * const f)1269 validate_redefines (const struct cb_field * const f)
1270 {
1271 const cb_tree x = CB_TREE (f);
1272 const struct cb_field *p;
1273
1274 /* Check OCCURS */
1275 if (f->redefines->flag_occurs) {
1276 cb_warning_x (COBC_WARN_FILLER, x,
1277 _("the original definition '%s' should not have OCCURS clause"),
1278 f->redefines->name);
1279 }
1280
1281 /* Check definition */
1282 for (p = f->redefines->sister; p && p != f; p = p->sister) {
1283 if (!p->redefines) {
1284 cb_error_x (x, _("REDEFINES must follow the original definition"));
1285 break;
1286 }
1287 }
1288
1289 /* Check variable occurrence */
1290 if (f->depending || cb_field_variable_size (f)) {
1291 cb_error_x (x, _("'%s' cannot be variable length"), f->name);
1292 }
1293 if (cb_field_variable_size (f->redefines)) {
1294 cb_error_x (x, _("the original definition '%s' cannot be variable length"),
1295 f->redefines->name);
1296 }
1297 }
1298
1299 /* Perform group-specific validation of f. */
1300 static unsigned int
validate_group(struct cb_field * f)1301 validate_group (struct cb_field *f)
1302 {
1303 cb_tree x = CB_TREE (f);
1304 unsigned int ret = 0;
1305
1306 if (f->pic) {
1307 group_error (x, "PICTURE");
1308 }
1309 if (f->flag_justified) {
1310 group_error (x, "JUSTIFIED RIGHT");
1311 }
1312 if (f->flag_blank_zero) {
1313 group_error (x, "BLANK WHEN ZERO");
1314 }
1315
1316 if (f->storage == CB_STORAGE_SCREEN &&
1317 (f->screen_from || f->screen_to || f->values || f->pic)) {
1318 cb_error_x (x, _("SCREEN group item '%s' has invalid clause"),
1319 cb_name (x));
1320 ret = 1;
1321 }
1322
1323 for (f = f->children; f; f = f->sister) {
1324 ret |= validate_field_1 (f);
1325 }
1326
1327 return ret;
1328 }
1329
1330 static unsigned int
validate_pic(struct cb_field * f)1331 validate_pic (struct cb_field *f)
1332 {
1333 int need_picture;
1334 cb_tree x = CB_TREE (f);
1335
1336 switch (f->usage) {
1337 case CB_USAGE_INDEX:
1338 case CB_USAGE_HNDL:
1339 case CB_USAGE_HNDL_WINDOW:
1340 case CB_USAGE_HNDL_SUBWINDOW:
1341 case CB_USAGE_HNDL_FONT:
1342 case CB_USAGE_HNDL_THREAD:
1343 case CB_USAGE_HNDL_MENU:
1344 case CB_USAGE_HNDL_VARIANT:
1345 case CB_USAGE_HNDL_LM:
1346 case CB_USAGE_LENGTH:
1347 case CB_USAGE_OBJECT:
1348 case CB_USAGE_POINTER:
1349 case CB_USAGE_PROGRAM_POINTER:
1350 case CB_USAGE_FLOAT:
1351 case CB_USAGE_DOUBLE:
1352 case CB_USAGE_LONG_DOUBLE:
1353 case CB_USAGE_FP_BIN32:
1354 case CB_USAGE_FP_BIN64:
1355 case CB_USAGE_FP_BIN128:
1356 case CB_USAGE_FP_DEC64:
1357 case CB_USAGE_FP_DEC128:
1358 case CB_USAGE_SIGNED_CHAR:
1359 case CB_USAGE_SIGNED_SHORT:
1360 case CB_USAGE_SIGNED_INT:
1361 case CB_USAGE_SIGNED_LONG:
1362 case CB_USAGE_UNSIGNED_CHAR:
1363 case CB_USAGE_UNSIGNED_SHORT:
1364 case CB_USAGE_UNSIGNED_INT:
1365 case CB_USAGE_UNSIGNED_LONG:
1366 need_picture = 0;
1367 break;
1368 case CB_USAGE_ERROR:
1369 return 1;
1370 default:
1371 need_picture = !f->flag_is_external_form;
1372 break;
1373 }
1374
1375 if (f->pic == NULL && need_picture) {
1376 /* try to built an implicit picture, stop if not possible */
1377 if (create_implicit_picture (f)) {
1378 return 1;
1379 }
1380 }
1381
1382 /* ACUCOBOL/RM-COBOL-style COMP-1 ignores the PICTURE clause. */
1383 if (f->flag_comp_1 && cb_binary_comp_1) {
1384 return 0;
1385 }
1386
1387 /* if picture is not needed it is an error to specify it
1388 note: we may have set the picture internal */
1389 if (f->pic != NULL && !f->pic->flag_is_calculated && !need_picture) {
1390 cb_error_x (x, _("'%s' cannot have PICTURE clause"),
1391 cb_name (x));
1392 }
1393
1394 return 0;
1395 }
1396
1397 static int
validate_usage(struct cb_field * const f)1398 validate_usage (struct cb_field * const f)
1399 {
1400 cb_tree x = CB_TREE (f);
1401
1402 if ((f->storage == CB_STORAGE_SCREEN
1403 || f->storage == CB_STORAGE_REPORT)
1404 && f->usage != CB_USAGE_DISPLAY
1405 && f->usage != CB_USAGE_NATIONAL) {
1406 cb_error_x (CB_TREE(f),
1407 _("%s item '%s' should be USAGE DISPLAY"),
1408 enum_explain_storage (f->storage), cb_name (x));
1409 return 1;
1410 }
1411
1412 switch (f->usage) {
1413 case CB_USAGE_BINARY:
1414 case CB_USAGE_PACKED:
1415 case CB_USAGE_BIT:
1416 if (f->pic
1417 && f->pic->category != CB_CATEGORY_NUMERIC) {
1418 emit_incompatible_pic_and_usage_error (x, f->usage);
1419 return 1;
1420 }
1421 break;
1422 case CB_USAGE_COMP_6:
1423 if (f->pic
1424 && f->pic->category != CB_CATEGORY_NUMERIC) {
1425 emit_incompatible_pic_and_usage_error (x, f->usage);
1426 return 1;
1427 }
1428 if (f->pic
1429 && f->pic->have_sign) {
1430 cb_warning_x (COBC_WARN_FILLER, x, _("'%s' COMP-6 with sign - changing to COMP-3"), cb_name (x));
1431 f->usage = CB_USAGE_PACKED;
1432 }
1433 break;
1434 case CB_USAGE_COMP_5:
1435 case CB_USAGE_COMP_X:
1436 case CB_USAGE_COMP_N:
1437 if (f->pic
1438 && f->pic->category != CB_CATEGORY_NUMERIC
1439 && f->pic->category != CB_CATEGORY_ALPHANUMERIC) {
1440 emit_incompatible_pic_and_usage_error (x, f->usage);
1441 return 1;
1442 }
1443 break;
1444 default:
1445 break;
1446 }
1447 return 0;
1448 }
1449
1450 static void
validate_sign(const struct cb_field * const f)1451 validate_sign (const struct cb_field * const f)
1452 {
1453 const cb_tree x = CB_TREE (f);
1454
1455 if (!(f->pic && f->pic->have_sign)) {
1456 cb_error_x (x, _("elementary items with SIGN clause must have S in PICTURE"));
1457 } else if (f->usage != CB_USAGE_DISPLAY
1458 && f->usage != CB_USAGE_NATIONAL) {
1459 cb_error_x (x, _("elementary items with SIGN clause must be USAGE DISPLAY or NATIONAL"));
1460 }
1461 }
1462
1463 static void
validate_justified_right(const struct cb_field * const f)1464 validate_justified_right (const struct cb_field * const f)
1465 {
1466 const cb_tree x = CB_TREE (f);
1467
1468 /* TO-DO: Error if no PIC? */
1469
1470 if (f->flag_justified
1471 && f->pic
1472 && f->pic->category != CB_CATEGORY_ALPHABETIC
1473 && f->pic->category != CB_CATEGORY_ALPHANUMERIC
1474 && f->pic->category != CB_CATEGORY_BOOLEAN
1475 && f->pic->category != CB_CATEGORY_NATIONAL) {
1476 cb_error_x (x, _("'%s' cannot have JUSTIFIED RIGHT"), cb_name (x));
1477 }
1478 }
1479
1480 static void
validate_blank_when_zero(const struct cb_field * const f)1481 validate_blank_when_zero (const struct cb_field * const f)
1482 {
1483 const cb_tree x = CB_TREE (f);
1484 int i;
1485
1486 if (f->pic
1487 && f->pic->have_sign
1488 && f->pic->category != CB_CATEGORY_NUMERIC_EDITED) {
1489 cb_error_x (x, _("'%s' cannot have S in PICTURE string and BLANK WHEN ZERO"),
1490 cb_name (x));
1491 }
1492
1493 if (f->usage != CB_USAGE_DISPLAY && f->usage != CB_USAGE_NATIONAL) {
1494 cb_error_x (x, _("'%s' cannot have BLANK WHEN ZERO without being USAGE DISPLAY or NATIONAL"),
1495 cb_name (x));
1496 }
1497
1498 if (f->pic) {
1499 switch (f->pic->category) {
1500 case CB_CATEGORY_NUMERIC:
1501 break;
1502 case CB_CATEGORY_NUMERIC_EDITED:
1503 for (i = 0; f->pic->str[i].symbol != '\0'; ++i) {
1504 if (f->pic->str[i].symbol == '*') {
1505 cb_error_x (x, _("'%s' cannot have * in PICTURE string and BLANK WHEN ZERO"),
1506 cb_name (x));
1507 break;
1508 }
1509 }
1510 break;
1511 default:
1512 cb_error_x (x, _("'%s' is not numeric, so cannot have BLANK WHEN ZERO"), cb_name (x));
1513 break;
1514 }
1515 }
1516 }
1517
1518 static void
validate_elem_value(const struct cb_field * const f)1519 validate_elem_value (const struct cb_field * const f)
1520 {
1521 const cb_tree x = CB_TREE (f);
1522 const struct cb_field *p;
1523
1524 if (CB_PAIR_P (CB_VALUE (f->values)) || CB_CHAIN (f->values)) {
1525 cb_error_x (x, _("only level 88 items may have multiple values"));
1526 }
1527
1528 /* ISO+IEC+1989-2002: 13.16.42.2-10 */
1529 if (cb_warn_opt_val[cb_warn_ignored_initial_val] != COBC_WARN_DISABLED) {
1530 for (p = f; p; p = p->parent) {
1531 if (p->flag_external) {
1532 cb_warning_x (cb_warn_ignored_initial_val, x,
1533 _("initial VALUE clause ignored for %s item '%s'"),
1534 "EXTERNAL", cb_name (CB_TREE(f)));
1535 } else if (p->redefines) {
1536 cb_warning_x (cb_warn_ignored_initial_val, x,
1537 _("initial VALUE clause ignored for %s item '%s'"),
1538 "REDEFINES", cb_name (CB_TREE(f)));
1539 }
1540 }
1541 }
1542 }
1543
1544 static void
warn_full_on_numeric_items_is_useless(const struct cb_field * const f)1545 warn_full_on_numeric_items_is_useless (const struct cb_field * const f)
1546 {
1547 if ((f->screen_flag & COB_SCREEN_FULL)
1548 && f->pic && f->pic->category == CB_CATEGORY_NUMERIC) {
1549 cb_warning_x (cb_warn_additional, CB_TREE (f),
1550 _("FULL has no effect on numeric items; you may want REQUIRED or PIC Z"));
1551 }
1552 }
1553
1554 static int
has_std_needed_screen_clause(const struct cb_field * const f)1555 has_std_needed_screen_clause (const struct cb_field * const f)
1556 {
1557 return (f->pic && (f->screen_from
1558 || f->screen_to
1559 || (f->values && CB_NUMERIC_LITERAL_P (CB_VALUE (f->values)))))
1560 || (f->values
1561 && (CB_LITERAL_P (CB_VALUE (f->values))
1562 || CB_CONST_P (CB_VALUE (f->values)))
1563 && (CB_TREE_CATEGORY (CB_VALUE (f->values)) == CB_CATEGORY_ALPHANUMERIC
1564 || CB_TREE_CATEGORY (CB_VALUE (f->values)) == CB_CATEGORY_BOOLEAN
1565 || CB_TREE_CATEGORY (CB_VALUE (f->values)) == CB_CATEGORY_NATIONAL))
1566 || f->screen_flag & COB_SCREEN_BELL
1567 || f->screen_flag & COB_SCREEN_BLANK_LINE
1568 || f->screen_flag & COB_SCREEN_BLANK_SCREEN
1569 || f->screen_flag & COB_SCREEN_ERASE_EOL
1570 || f->screen_flag & COB_SCREEN_ERASE_EOS;
1571 }
1572
1573 static void
error_value_figurative_constant(const struct cb_field * const f)1574 error_value_figurative_constant(const struct cb_field * const f)
1575 {
1576 if (f->values
1577 && cb_is_figurative_constant (CB_VALUE (f->values))) {
1578 cb_error_x (CB_TREE (f), _("VALUE may not contain a figurative constant"));
1579 }
1580 }
1581
1582 static void
error_both_full_and_justified(const struct cb_field * const f)1583 error_both_full_and_justified (const struct cb_field * const f)
1584 {
1585 if ((f->screen_flag & COB_SCREEN_FULL) && f->flag_justified) {
1586 cb_error_x (CB_TREE (f), _("cannot specify both FULL and JUSTIFIED"));
1587 }
1588 }
1589
1590 static int
warn_from_to_using_without_pic(const struct cb_field * const f)1591 warn_from_to_using_without_pic (const struct cb_field * const f)
1592 {
1593 const cb_tree x = CB_TREE (f);
1594
1595 if ((f->screen_from || f->screen_to) && !f->pic) {
1596 /* TO-DO: Change to dialect option */
1597 cb_warning_x (cb_warn_additional, x,
1598 _("'%s' has FROM, TO or USING without PIC; PIC will be implied"),
1599 cb_name (x));
1600 /* TO-DO: Add setting of PIC below here or move warnings to the code which sets the PIC */
1601 return 1;
1602 } else {
1603 return 0;
1604 }
1605 }
1606
1607 static int
warn_pic_for_numeric_value_implied(const struct cb_field * const f)1608 warn_pic_for_numeric_value_implied (const struct cb_field * const f)
1609 {
1610 if (f->values && CB_NUMERIC_LITERAL_P (CB_VALUE (f->values))) {
1611 cb_warning_x (cb_warn_additional, CB_TREE (f),
1612 _("'%s' has numeric VALUE without PIC; PIC will be implied"),
1613 cb_name (CB_TREE (f)));
1614 return 1;
1615 } else {
1616 return 0;
1617 }
1618 }
1619
1620 static void
validate_elem_screen_clauses_std(struct cb_field * const f)1621 validate_elem_screen_clauses_std (struct cb_field * const f)
1622 {
1623 const cb_tree x = CB_TREE (f);
1624
1625 if (!has_std_needed_screen_clause (f)) {
1626 if (f->pic) {
1627 cb_error_x (x, _("'%s' cannot have PIC without FROM, TO, USING or numeric VALUE"),
1628 cb_name (x));
1629 } else if (warn_from_to_using_without_pic (f)) {
1630 /*
1631 The above rule is not explicitly stated, but the general rules of FROM,
1632 TO and USING assume the item has a PICTURE clause.
1633 */
1634 ;
1635 } else if (warn_pic_for_numeric_value_implied (f)) {
1636 ;
1637 /* TO-DO: Add setting of PIC below here or move warnings to the code which sets the PIC */
1638 } else {
1639 cb_error_x (x, _("'%s' needs a PIC, FROM, TO, USING, VALUE, BELL, BLANK or ERASE clause"),
1640 cb_name (x));
1641 }
1642 }
1643
1644 error_both_full_and_justified (f);
1645
1646 error_value_figurative_constant (f);
1647 }
1648
1649 static void
error_both_pic_and_value(const struct cb_field * const f)1650 error_both_pic_and_value (const struct cb_field * const f)
1651 {
1652 if (f->pic && f->values) {
1653 cb_error_x (CB_TREE (f), _("cannot specify both PIC and VALUE"));
1654 }
1655 }
1656
1657 static void
error_pic_without_from_to_using(const struct cb_field * const f)1658 error_pic_without_from_to_using (const struct cb_field * const f)
1659 {
1660 if (f->pic && !(f->screen_from || f->screen_to)) {
1661 cb_error_x (CB_TREE (f), _("cannot have PIC without FROM, TO or USING"));
1662 }
1663 }
1664
1665 static void
error_from_to_using_without_pic(const struct cb_field * const f)1666 error_from_to_using_without_pic (const struct cb_field * const f)
1667 {
1668 /* TO-DO: Replace warning, like in validate_elem_screen_clauses_std? */
1669 if ((f->screen_from || f->screen_to) && !f->pic) {
1670 cb_error_x (CB_TREE (f), _("cannot have FROM, TO or USING without PIC"));
1671 }
1672 }
1673
1674 static void
error_value_numeric(const struct cb_field * const f)1675 error_value_numeric (const struct cb_field * const f)
1676 {
1677 if (f->values
1678 && CB_TREE_CATEGORY (CB_VALUE (f->values)) == CB_CATEGORY_NUMERIC) {
1679 cb_error_x (CB_TREE (f), _("VALUE item may not be numeric"));
1680 }
1681 }
1682
1683 static void
error_no_screen_clause_needed_by_xopen(const struct cb_field * const f)1684 error_no_screen_clause_needed_by_xopen (const struct cb_field * const f)
1685 {
1686 const cb_tree x = CB_TREE (f);
1687
1688 if (!(f->pic
1689 || f->screen_column
1690 || f->screen_flag & COB_SCREEN_BELL
1691 || f->screen_flag & COB_SCREEN_BLANK_LINE
1692 || f->screen_flag & COB_SCREEN_BLANK_SCREEN
1693 || f->screen_line
1694 || f->values)) {
1695 cb_error_x (x, _("'%s' needs a PIC, COL, LINE, VALUE, BELL or BLANK clause"),
1696 cb_name (x));
1697 }
1698 }
1699
1700 static void
validate_elem_screen_clauses_mf(const struct cb_field * const f)1701 validate_elem_screen_clauses_mf (const struct cb_field * const f)
1702 {
1703 const cb_tree x = CB_TREE (f);
1704
1705 error_no_screen_clause_needed_by_xopen (f);
1706
1707 error_both_pic_and_value (f);
1708 error_pic_without_from_to_using (f);
1709
1710 /*
1711 The below rule isn't explicitly stated, but it follows from the
1712 PICTURE's general rule which says the PIC character string determines
1713 the length and category of the item.
1714 */
1715 warn_from_to_using_without_pic (f);
1716
1717 error_value_figurative_constant (f);
1718 error_value_numeric (f);
1719
1720 if (!f->screen_to
1721 && ((f->screen_flag & COB_SCREEN_AUTO)
1722 || (f->screen_flag & COB_SCREEN_FULL)
1723 || (f->screen_flag & COB_SCREEN_PROMPT)
1724 || (f->screen_flag & COB_SCREEN_REQUIRED)
1725 || (f->screen_flag & COB_SCREEN_SECURE))) {
1726 cb_error_x (x, _("cannot use AUTO, FULL, PROMPT, REQUIRED or SECURE on elementary item without TO or USING"));
1727 }
1728 if (!f->screen_from && !f->screen_to
1729 && (f->flag_blank_zero
1730 || f->flag_justified
1731 || f->flag_occurs
1732 || f->flag_sign_clause)) {
1733 cb_error_x (x, _("cannot use BLANK WHEN ZERO, JUSTIFIED, OCCURS or SIGN on item without FROM, TO or USING"));
1734 }
1735 }
1736
1737 static void
validate_elem_screen_clauses_rm(struct cb_field * f)1738 validate_elem_screen_clauses_rm (struct cb_field *f)
1739 {
1740 const cb_tree x = CB_TREE (f);
1741
1742 error_both_pic_and_value (f);
1743 error_pic_without_from_to_using (f);
1744 error_from_to_using_without_pic (f);
1745
1746 error_value_numeric (f);
1747
1748 if (!f->pic) {
1749 if ((f->screen_flag & COB_SCREEN_AUTO)
1750 || (f->screen_flag & COB_SCREEN_FULL)
1751 || (f->screen_flag & COB_SCREEN_REQUIRED)
1752 || (f->screen_flag & COB_SCREEN_SECURE)) {
1753 cb_error_x (x, _("cannot use AUTO, FULL, REQUIRED or SECURE on elementary item without FROM, TO or USING"));
1754 }
1755 if (f->flag_blank_zero
1756 || f->flag_justified
1757 || f->flag_sign_clause) {
1758 cb_error_x (x, _("cannot use BLANK WHEN ZERO, JUSTIFIED or SIGN without FROM, TO or USING"));
1759 }
1760 }
1761 }
1762
1763 static void
validate_elem_screen_clauses_acu(struct cb_field * f)1764 validate_elem_screen_clauses_acu (struct cb_field *f)
1765 {
1766 const cb_tree x = CB_TREE (f);
1767
1768 error_both_pic_and_value (f);
1769 error_pic_without_from_to_using (f);
1770
1771 error_value_numeric (f);
1772
1773 warn_from_to_using_without_pic (f);
1774 if (!f->pic) {
1775 if (f->flag_blank_zero) {
1776 cb_error_x (x, _("cannot have BLANK WHEN ZERO without PIC"));
1777 }
1778 if (f->flag_justified) {
1779 cb_error_x (x, _("cannot have JUSTIFIED without PIC"));
1780 }
1781 }
1782 }
1783
1784 static void
validate_elem_screen_clauses_xopen(struct cb_field * f)1785 validate_elem_screen_clauses_xopen (struct cb_field *f)
1786 {
1787 const cb_tree x = CB_TREE (f);
1788
1789 error_no_screen_clause_needed_by_xopen (f);
1790
1791 error_both_pic_and_value (f);
1792 error_pic_without_from_to_using (f);
1793 error_from_to_using_without_pic (f);
1794
1795 error_value_numeric (f);
1796
1797 if (!f->screen_to && !f->screen_from
1798 && (f->screen_flag & COB_SCREEN_AUTO)) {
1799 cb_error_x (x, _("cannot have AUTO without FROM, TO or USING"));
1800 }
1801 if (!f->screen_to
1802 && ((f->screen_flag & COB_SCREEN_FULL)
1803 || (f->screen_flag & COB_SCREEN_REQUIRED))) {
1804 cb_error_x (x, _("cannot use FULL or REQUIRED on item without TO or USING"));
1805 }
1806
1807 error_both_full_and_justified (f);
1808
1809 if ((f->screen_flag & COB_SCREEN_SECURE)) {
1810 if (f->screen_from) {
1811 cb_error_x (x, _("SECURE can be used with TO only"));
1812 } else if (!f->screen_to) {
1813 cb_error_x (x, _("SECURE must be used with TO"));
1814 }
1815 }
1816 }
1817
1818 static void
warn_has_no_useful_clause(const struct cb_field * const f)1819 warn_has_no_useful_clause (const struct cb_field * const f)
1820 {
1821 if (!( f->screen_column
1822 || f->screen_flag & COB_SCREEN_BELL
1823 || f->screen_flag & COB_SCREEN_BLANK_LINE
1824 || f->screen_flag & COB_SCREEN_BLANK_SCREEN
1825 || f->screen_flag & COB_SCREEN_ERASE_EOL
1826 || f->screen_flag & COB_SCREEN_ERASE_EOS
1827 || f->screen_from
1828 || f->screen_line
1829 || f->screen_to
1830 || f->values)) {
1831 cb_warning_x (COBC_WARN_FILLER, CB_TREE (f),
1832 _("'%s' does nothing"), cb_name (CB_TREE (f)));
1833 }
1834 }
1835
1836 static void
validate_elem_screen_clauses_gc(const struct cb_field * const f)1837 validate_elem_screen_clauses_gc (const struct cb_field * const f)
1838 {
1839 /* We aim for the least restrictive rules possible. */
1840 warn_has_no_useful_clause (f);
1841 warn_from_to_using_without_pic (f);
1842 warn_pic_for_numeric_value_implied (f);
1843 }
1844
1845 static void
validate_elem_screen(struct cb_field * f)1846 validate_elem_screen (struct cb_field *f)
1847 {
1848 switch (cb_screen_section_clauses) {
1849 case CB_STD_SCREEN_RULES:
1850 validate_elem_screen_clauses_std (f);
1851 break;
1852 case CB_MF_SCREEN_RULES:
1853 validate_elem_screen_clauses_mf (f);
1854 break;
1855 case CB_ACU_SCREEN_RULES:
1856 validate_elem_screen_clauses_acu (f);
1857 break;
1858 case CB_RM_SCREEN_RULES:
1859 validate_elem_screen_clauses_rm (f);
1860 break;
1861 case CB_XOPEN_SCREEN_RULES:
1862 validate_elem_screen_clauses_xopen (f);
1863 break;
1864 case CB_GC_SCREEN_RULES:
1865 validate_elem_screen_clauses_gc (f);
1866 break;
1867 }
1868
1869 warn_full_on_numeric_items_is_useless (f);
1870 }
1871
1872 /* Perform validation of a non-66-or-88-level elementary item. */
1873 static unsigned int
validate_elementary_item(struct cb_field * f)1874 validate_elementary_item (struct cb_field *f)
1875 {
1876 unsigned int ret;
1877
1878 ret = validate_usage (f);
1879 if (f->flag_sign_clause) {
1880 validate_sign (f);
1881 }
1882 validate_justified_right (f);
1883
1884 if (f->flag_blank_zero) {
1885 validate_blank_when_zero (f);
1886 }
1887
1888 if (f->values) {
1889 validate_elem_value (f);
1890 }
1891 if (!ret && f->storage == CB_STORAGE_SCREEN) {
1892 validate_elem_screen (f);
1893 }
1894
1895 /* Validate PICTURE */
1896 ret |= validate_pic (f);
1897
1898 /* TO-DO: This is not validation and should be elsewhere. */
1899 switch (f->usage) {
1900 case CB_USAGE_DISPLAY:
1901 if (current_program
1902 && current_program->flag_trailing_separate
1903 && f->pic
1904 && f->pic->category == CB_CATEGORY_NUMERIC
1905 && !f->flag_sign_leading) {
1906 f->flag_sign_separate = 1;
1907 }
1908 break;
1909 case CB_USAGE_SIGNED_CHAR:
1910 f->usage = CB_USAGE_COMP_5;
1911 f->pic = cb_build_binary_picture ("BINARY-CHAR", 2, 1);
1912 f->flag_real_binary = 1;
1913 break;
1914 case CB_USAGE_SIGNED_SHORT:
1915 f->usage = CB_USAGE_COMP_5;
1916 f->pic = cb_build_binary_picture ("BINARY-SHORT", 4, 1);
1917 f->flag_real_binary = 1;
1918 break;
1919 case CB_USAGE_SIGNED_INT:
1920 f->usage = CB_USAGE_COMP_5;
1921 f->pic = cb_build_binary_picture ("BINARY-LONG", 9, 1);
1922 f->flag_real_binary = 1;
1923 break;
1924 case CB_USAGE_SIGNED_LONG:
1925 f->usage = CB_USAGE_COMP_5;
1926 f->pic = cb_build_binary_picture ("BINARY-DOUBLE", 18, 1);
1927 f->flag_real_binary = 1;
1928 break;
1929 case CB_USAGE_UNSIGNED_CHAR:
1930 f->usage = CB_USAGE_COMP_5;
1931 f->pic = cb_build_binary_picture ("BINARY-CHAR", 2, 0);
1932 f->flag_real_binary = 1;
1933 break;
1934 case CB_USAGE_UNSIGNED_SHORT:
1935 f->usage = CB_USAGE_COMP_5;
1936 f->pic = cb_build_binary_picture ("BINARY-SHORT", 4, 0);
1937 f->flag_real_binary = 1;
1938 break;
1939 case CB_USAGE_UNSIGNED_INT:
1940 f->usage = CB_USAGE_COMP_5;
1941 f->pic = cb_build_binary_picture ("BINARY-LONG", 9, 0);
1942 f->flag_real_binary = 1;
1943 break;
1944 case CB_USAGE_POINTER:
1945 if (cb_numeric_pointer) {
1946 f->pic = cb_build_binary_picture ("BINARY-DOUBLE", 18, 0);
1947 f->flag_real_binary = 1;
1948 }
1949 break;
1950 case CB_USAGE_UNSIGNED_LONG:
1951 f->usage = CB_USAGE_COMP_5;
1952 f->pic = cb_build_binary_picture ("BINARY-DOUBLE", 18, 0);
1953 f->flag_real_binary = 1;
1954 break;
1955 case CB_USAGE_COMP_5:
1956 f->flag_real_binary = 1;
1957 break;
1958 default:
1959 break;
1960 }
1961
1962 /* TO-DO: Also move, this is not validation */
1963 if (f->flag_blank_zero
1964 && f->pic
1965 && f->pic->category == CB_CATEGORY_NUMERIC) {
1966 cob_pic_symbol *pstr;
1967 int n;
1968 /* Reconstruct the picture string */
1969 if (f->pic->scale > 0) {
1970 /* Size for genned string */
1971 if (f->pic->have_sign) {
1972 n = 4;
1973 } else {
1974 n = 3;
1975 }
1976 f->pic->str = cobc_parse_malloc ((size_t)n * sizeof (cob_pic_symbol));
1977 pstr = f->pic->str;
1978 if (f->pic->have_sign) {
1979 pstr->symbol = '+';
1980 pstr->times_repeated = 1;
1981 ++pstr;
1982 }
1983 pstr->symbol = '9';
1984 pstr->times_repeated = (int)f->pic->digits - f->pic->scale;
1985 ++pstr;
1986 pstr->symbol = 'V';
1987 pstr->times_repeated = 1;
1988 ++pstr;
1989
1990 pstr->symbol = '9';
1991 pstr->times_repeated = f->pic->scale;
1992 ++pstr;
1993
1994 f->pic->size++;
1995 } else {
1996 /* Size for genned string */
1997 if (f->pic->have_sign) {
1998 n = 2;
1999 } else {
2000 n = 1;
2001 }
2002 f->pic->str = cobc_parse_malloc ((size_t)n * sizeof(cob_pic_symbol));
2003 pstr = f->pic->str;
2004 if (f->pic->have_sign) {
2005 pstr->symbol = '+';
2006 pstr->times_repeated = 1;
2007 ++pstr;
2008 }
2009 pstr->symbol = '9';
2010 pstr->times_repeated = f->pic->digits;
2011 }
2012 f->pic->lenstr = n;
2013 f->pic->category = CB_CATEGORY_NUMERIC_EDITED;
2014 }
2015
2016 return ret;
2017 }
2018
2019 static unsigned int
validate_field_1(struct cb_field * f)2020 validate_field_1 (struct cb_field *f)
2021 {
2022 cb_tree x;
2023
2024 #if 0
2025 /* LCOV_EXCL_START */
2026 if (unlikely (!f)) { /* checked to keep the analyzer happy */
2027 cobc_err_msg (_("call to %s with NULL pointer"), "validate_field_1");
2028 COBC_ABORT();
2029 }
2030 /* LCOV_EXCL_STOP */
2031 #endif
2032
2033 if (f->flag_invalid) {
2034 return 1;
2035 }
2036
2037 if (f->flag_any_length) {
2038 return validate_any_length_item (f);
2039 }
2040
2041 x = CB_TREE (f);
2042 if (f->level == 77) {
2043 if (f->storage != CB_STORAGE_WORKING &&
2044 f->storage != CB_STORAGE_LOCAL &&
2045 f->storage != CB_STORAGE_LINKAGE) {
2046 cb_error_x (x, _("'%s' 77 level is not allowed here"), cb_name (x));
2047 }
2048 }
2049
2050 if (f->flag_external) {
2051 validate_external (f);
2052 } else
2053 if (f->flag_item_based) {
2054 validate_based (f);
2055 }
2056
2057 if (f->flag_occurs) {
2058 /* TO-DO: Not validation, so should not be in this function! */
2059 cb_tree l;
2060 for (l = f->index_list; l; l = CB_CHAIN (l)) {
2061 CB_FIELD_PTR (CB_VALUE (l))->flag_is_global = f->flag_is_global;
2062 }
2063 /* END: Not validation */
2064 validate_occurs (f);
2065 }
2066
2067 if (f->level == 66) {
2068 /* no check for redefines here */
2069 return 0;
2070 }
2071 if (f->redefines) {
2072 /* CHECKME - seems to be missing:
2073 COBOL 202x doesn't allow REDEFINES in SCREEN/REPORT */
2074 validate_redefines (f);
2075 }
2076
2077 if (f->children) {
2078 return validate_group (f);
2079 } else {
2080 return validate_elementary_item (f);
2081 }
2082 }
2083
2084 static void
setup_parameters(struct cb_field * f)2085 setup_parameters (struct cb_field *f)
2086 {
2087 if (f->children) {
2088 /* Group field */
2089 unsigned int flag_local = !!f->flag_local;
2090 for (f = f->children; f; f = f->sister) {
2091 f->flag_local = flag_local;
2092 setup_parameters (f);
2093 }
2094 return;
2095 }
2096
2097 /* Regular field */
2098 /* Determine the class */
2099 switch (f->usage) {
2100 case CB_USAGE_BINARY:
2101 #ifndef WORDS_BIGENDIAN
2102 if (cb_binary_byteorder == CB_BYTEORDER_BIG_ENDIAN) {
2103 f->flag_binary_swap = 1;
2104 }
2105 #endif
2106 break;
2107
2108 case CB_USAGE_INDEX:
2109 case CB_USAGE_HNDL:
2110 case CB_USAGE_HNDL_WINDOW:
2111 case CB_USAGE_HNDL_SUBWINDOW:
2112 case CB_USAGE_HNDL_FONT:
2113 case CB_USAGE_HNDL_THREAD:
2114 case CB_USAGE_HNDL_MENU:
2115 case CB_USAGE_HNDL_VARIANT:
2116 case CB_USAGE_HNDL_LM:
2117 f->pic = CB_PICTURE (cb_build_picture ("S9(9)"));
2118 f->pic->flag_is_calculated = 1;
2119 #if 0
2120 /* REMIND: The category should be set, but doing so causes
2121 * other problems as more checks need to be added to
2122 * accept a category of CB_CATEGORY_INDEX so this change
2123 * is deferred until a later time
2124 * RJN: Nov 2017
2125 */
2126 f->pic->category = CB_CATEGORY_INDEX;
2127 #endif
2128 break;
2129
2130 case CB_USAGE_LENGTH:
2131 f->pic = CB_PICTURE (cb_build_picture ("9(9)"));
2132 f->pic->flag_is_calculated = 1;
2133 break;
2134
2135 case CB_USAGE_POINTER:
2136 case CB_USAGE_PROGRAM_POINTER:
2137 #ifdef COB_64_BIT_POINTER
2138 f->pic = CB_PICTURE (cb_build_picture ("9(17)"));
2139 #else
2140 f->pic = CB_PICTURE (cb_build_picture ("9(10)"));
2141 #endif
2142 f->pic->flag_is_calculated = 1;
2143 break;
2144 case CB_USAGE_FLOAT:
2145 f->pic = CB_PICTURE (cb_build_picture ("S9(7)V9(8)"));
2146 f->pic->flag_is_calculated = 1;
2147 break;
2148 case CB_USAGE_DOUBLE:
2149 f->pic = CB_PICTURE (cb_build_picture ("S9(17)V9(17)"));
2150 f->pic->flag_is_calculated = 1;
2151 break;
2152 case CB_USAGE_FP_DEC64:
2153 /* RXWRXW - Scale Fix me */
2154 f->pic = CB_PICTURE (cb_build_picture ("S9(17)V9(16)"));
2155 f->pic->flag_is_calculated = 1;
2156 break;
2157 case CB_USAGE_FP_DEC128:
2158 /* RXWRXW - Scale Fix me */
2159 f->pic = CB_PICTURE (cb_build_picture ("S999V9(34)"));
2160 f->pic->flag_is_calculated = 1;
2161 break;
2162
2163 case CB_USAGE_COMP_5:
2164 f->flag_real_binary = 1;
2165 /* Fall-through */
2166 case CB_USAGE_COMP_X:
2167 case CB_USAGE_COMP_N:
2168 if (f->pic->category == CB_CATEGORY_ALPHANUMERIC) {
2169 if (f->pic->size > 8) {
2170 f->pic = CB_PICTURE (cb_build_picture ("9(36)"));
2171 } else {
2172 char pic[8];
2173 sprintf (pic, "9(%u)", pic_digits[f->pic->size - 1]);
2174 f->pic = CB_PICTURE (cb_build_picture (pic));
2175 }
2176 }
2177 #ifndef WORDS_BIGENDIAN
2178 if (f->usage == CB_USAGE_COMP_X &&
2179 cb_binary_byteorder == CB_BYTEORDER_BIG_ENDIAN) {
2180 f->flag_binary_swap = 1;
2181 }
2182 if (f->usage == CB_USAGE_COMP_N) {
2183 f->flag_binary_swap = 1;
2184 }
2185 #endif
2186 break;
2187
2188 case CB_USAGE_DISPLAY:
2189 /* in case of usage display we often don't have the category
2190 setup correctly, work around this explicit resolving it here */
2191 cb_tree_category (CB_TREE (f));
2192 break;
2193
2194 default:
2195 break;
2196 }
2197 }
2198
2199 static void
compute_binary_size(struct cb_field * f,const int size)2200 compute_binary_size (struct cb_field *f, const int size)
2201 {
2202 switch (cb_binary_size) {
2203 case CB_BINARY_SIZE_1_2_4_8:
2204 f->size = ((size <= 2) ? 1 :
2205 (size <= 4) ? 2 :
2206 (size <= 9) ? 4 : (size <= 18) ? 8 : 16);
2207 return;
2208 case CB_BINARY_SIZE_2_4_8:
2209 if (f->flag_real_binary && size <= 2) {
2210 f->size = 1;
2211 } else {
2212 f->size = ((size <= 4) ? 2 :
2213 (size <= 9) ? 4 : (size <= 18) ? 8 : 16);
2214 }
2215 return;
2216 case CB_BINARY_SIZE_1__8:
2217 if (f->pic->have_sign) {
2218 switch (size) {
2219 case 0:
2220 case 1:
2221 case 2:
2222 f->size = 1;
2223 return;
2224 case 3:
2225 case 4:
2226 f->size = 2;
2227 return;
2228 case 5:
2229 case 6:
2230 f->size = 3;
2231 return;
2232 case 7:
2233 case 8:
2234 case 9:
2235 f->size = 4;
2236 return;
2237 case 10:
2238 case 11:
2239 f->size = 5;
2240 return;
2241 case 12:
2242 case 13:
2243 case 14:
2244 f->size = 6;
2245 return;
2246 case 15:
2247 case 16:
2248 f->size = 7;
2249 return;
2250 case 17:
2251 case 18:
2252 f->size = 8;
2253 return;
2254 case 19:
2255 case 20:
2256 case 21:
2257 f->size = 9;
2258 return;
2259 case 22:
2260 case 23:
2261 f->size = 10;
2262 return;
2263 case 24:
2264 case 25:
2265 case 26:
2266 f->size = 11;
2267 return;
2268 case 27:
2269 case 28:
2270 f->size = 12;
2271 return;
2272 case 29:
2273 case 30:
2274 case 31:
2275 f->size = 13;
2276 return;
2277 case 32:
2278 case 33:
2279 f->size = 14;
2280 return;
2281 case 34:
2282 case 35:
2283 f->size = 15;
2284 return;
2285 default:
2286 f->size = 16;
2287 return;
2288 }
2289 }
2290 switch (size) {
2291 case 0:
2292 case 1:
2293 case 2:
2294 f->size = 1;
2295 return;
2296 case 3:
2297 case 4:
2298 f->size = 2;
2299 return;
2300 case 5:
2301 case 6:
2302 case 7:
2303 f->size = 3;
2304 return;
2305 case 8:
2306 case 9:
2307 f->size = 4;
2308 return;
2309 case 10:
2310 case 11:
2311 case 12:
2312 f->size = 5;
2313 return;
2314 case 13:
2315 case 14:
2316 f->size = 6;
2317 return;
2318 case 15:
2319 case 16:
2320 f->size = 7;
2321 return;
2322 case 17:
2323 case 18:
2324 case 19:
2325 f->size = 8;
2326 return;
2327 case 20:
2328 case 21:
2329 f->size = 9;
2330 return;
2331 case 22:
2332 case 23:
2333 case 24:
2334 f->size = 10;
2335 return;
2336 case 25:
2337 case 26:
2338 f->size = 11;
2339 return;
2340 case 27:
2341 case 28:
2342 f->size = 12;
2343 return;
2344 case 29:
2345 case 30:
2346 case 31:
2347 f->size = 13;
2348 return;
2349 case 32:
2350 case 33:
2351 f->size = 14;
2352 return;
2353 case 34:
2354 case 35:
2355 case 36:
2356 f->size = 15;
2357 return;
2358 default:
2359 f->size = 16;
2360 return;
2361 }
2362 return;
2363 #if 0 /* how should this happen ... */
2364 default:
2365 f->size = size;
2366 return;
2367 #endif
2368 }
2369 }
2370
2371 static struct cb_field *
get_last_child(struct cb_field * f)2372 get_last_child (struct cb_field *f)
2373 {
2374 do {
2375 f = f->children;
2376 while (f->sister) {
2377 f = f->sister;
2378 }
2379 } while (f->children);
2380
2381 return f;
2382 }
2383
2384 static void
set_report_field_offset(struct cb_field * f)2385 set_report_field_offset (struct cb_field *f)
2386 {
2387 struct cb_field *pp;
2388
2389 #if 0 /* That would be a bad error as this function is only called for report_column > 0 */
2390 if (f->storage != CB_STORAGE_REPORT) {
2391 return;
2392 }
2393 #endif
2394 if (!(f->report_flag & COB_REPORT_COLUMN_PLUS)) {
2395 f->offset = f->report_column - 1; /* offset based on COLUMN value */
2396 return;
2397 }
2398 pp = f->parent;
2399 if (pp) {
2400 if (pp->children == f) {
2401 f->offset = f->report_column - 1; /* First in line */
2402 } else {
2403 struct cb_field *c;
2404 for (c = pp->children; c; c = c->sister) { /* Find previous field */
2405 if (c->sister == f) {
2406 if (c->occurs_max > 1) {
2407 f->offset = c->offset + c->size * c->occurs_max + f->report_column;
2408 }
2409 else {
2410 f->offset = c->offset + c->size + f->report_column;
2411 }
2412 break;
2413 }
2414 }
2415 }
2416 }
2417 }
2418
2419 static int
compute_size(struct cb_field * f)2420 compute_size (struct cb_field *f)
2421 {
2422 struct cb_field *c;
2423 int size = 0;
2424 int size_check = 0;
2425 int align_size;
2426 int pad;
2427 int unbounded_items = 0;
2428 int unbounded_parts = 1;
2429
2430 int maxsz;
2431 struct cb_field *c0;
2432
2433 if (f->storage == CB_STORAGE_REPORT) {
2434 if (f->report_num_col > 1) {
2435 if (f->flag_occurs) {
2436 /* FIXME: this is no size calculation and likely not reachable (if it is: move) */
2437 cb_error_x (CB_TREE (f), _("OCCURS and multi COLUMNs is not allowed"));
2438 } else {
2439 f->occurs_max = f->occurs_min = f->report_num_col;
2440 f->flag_occurs = 1;
2441 f->indexes = 1;
2442 }
2443 }
2444 }
2445 if (f->level == 66) {
2446 /* Rename */
2447 if (f->rename_thru) {
2448 f->size = f->rename_thru->offset + f->rename_thru->size -
2449 f->redefines->offset;
2450 } else {
2451 f->size = f->redefines->size;
2452 }
2453 return f->size;
2454 }
2455 if (f->storage == CB_STORAGE_REPORT
2456 && (f->report_flag & COB_REPORT_LINE)
2457 && !(f->report_flag & COB_REPORT_LINE_PLUS)
2458 && f->parent
2459 && f->parent->children != f) {
2460 for(c = f->parent->children; c && c != f; c = c->sister) {
2461 if ((c->report_flag & COB_REPORT_LINE)
2462 && !(c->report_flag & COB_REPORT_LINE_PLUS)
2463 && c->report_line == f->report_line) {
2464 cb_warning_x (cb_warn_additional, CB_TREE (f),
2465 _("duplicate LINE %d ignored"), f->report_line);
2466 f->report_line = 0;
2467 f->report_flag &= ~COB_REPORT_LINE;
2468 }
2469 }
2470 }
2471
2472 if (f->children) {
2473 if (f->storage == CB_STORAGE_REPORT
2474 && (f->report_flag & COB_REPORT_LINE) ) {
2475 f->offset = 0;
2476 }
2477
2478 /* Groups */
2479 if (f->flag_synchronized) {
2480 cb_warning_x (cb_warn_additional, CB_TREE (f),
2481 _("ignoring SYNCHRONIZED for group item '%s'"),
2482 cb_name (CB_TREE (f)));
2483 }
2484 unbounded_again:
2485 size_check = 0;
2486 occur_align_size = 1;
2487 for (c = f->children; c; c = c->sister) {
2488 if (c->redefines) {
2489 c->offset = c->redefines->offset;
2490 compute_size (c);
2491 /* Increase the size if redefinition is larger */
2492 if (c->level != 66 &&
2493 c->size * c->occurs_max >
2494 c->redefines->size * c->redefines->occurs_max) {
2495 if (cb_larger_redefines_ok) {
2496 cb_warning_x (cb_warn_additional, CB_TREE (c),
2497 _("size of '%s' larger than size of '%s'"),
2498 c->name, c->redefines->name);
2499 maxsz = c->redefines->size * c->redefines->occurs_max;
2500 for (c0 = c->redefines->sister; c0 != c; c0 = c0->sister) {
2501 if (c0->size * c0->occurs_max > maxsz) {
2502 maxsz = c0->size * c0->occurs_max;
2503 }
2504 }
2505 if (c->size * c->occurs_max > maxsz) {
2506 size_check += (c->size * c->occurs_max) - maxsz;
2507 }
2508 } else {
2509 cb_error_x (CB_TREE (c),
2510 _("size of '%s' larger than size of '%s'"),
2511 c->name, c->redefines->name);
2512 }
2513 }
2514 } else {
2515 c->offset = f->offset + (int) size_check;
2516 compute_size (c);
2517 if (c->flag_unbounded) {
2518 unbounded_items++;
2519 c->occurs_max = (COB_MAX_UNBOUNDED_SIZE / c->size / unbounded_parts) - 1;
2520 }
2521 size_check += c->size * c->occurs_max;
2522
2523 if (c->report_column > 0) { /* offset based on COLUMN value */
2524 set_report_field_offset(c);
2525 }
2526
2527 /* Word alignment */
2528 if (c->flag_synchronized) {
2529 align_size = 1;
2530 switch (c->usage) {
2531 case CB_USAGE_BINARY:
2532 case CB_USAGE_COMP_5:
2533 case CB_USAGE_COMP_X:
2534 case CB_USAGE_COMP_N:
2535 case CB_USAGE_FLOAT:
2536 case CB_USAGE_DOUBLE:
2537 case CB_USAGE_LONG_DOUBLE:
2538 case CB_USAGE_FP_BIN32:
2539 case CB_USAGE_FP_BIN64:
2540 case CB_USAGE_FP_BIN128:
2541 case CB_USAGE_FP_DEC64:
2542 case CB_USAGE_FP_DEC128:
2543 if (c->size == 2 ||
2544 c->size == 4 ||
2545 c->size == 8 ||
2546 c->size == 16) {
2547 align_size = c->size;
2548 }
2549 break;
2550 case CB_USAGE_INDEX:
2551 case CB_USAGE_HNDL:
2552 case CB_USAGE_HNDL_WINDOW:
2553 case CB_USAGE_HNDL_SUBWINDOW:
2554 case CB_USAGE_HNDL_FONT:
2555 case CB_USAGE_HNDL_THREAD:
2556 case CB_USAGE_HNDL_MENU:
2557 case CB_USAGE_HNDL_VARIANT:
2558 case CB_USAGE_HNDL_LM:
2559 case CB_USAGE_LENGTH:
2560 align_size = sizeof (int);
2561 break;
2562 case CB_USAGE_OBJECT:
2563 case CB_USAGE_POINTER:
2564 case CB_USAGE_PROGRAM_POINTER:
2565 align_size = sizeof (void *);
2566 break;
2567 default:
2568 break;
2569 }
2570 if (c->offset % align_size != 0) {
2571 pad = align_size - (c->offset % align_size);
2572 c->offset += pad;
2573 size_check += pad;
2574 }
2575 if (align_size > occur_align_size) {
2576 occur_align_size = align_size;
2577 }
2578 }
2579 }
2580
2581 if (c->sister == NULL
2582 && c->storage == CB_STORAGE_REPORT) { /* To set parent size */
2583 if((c->offset + c->size) > size_check)
2584 size_check = (c->offset + c->size);
2585 }
2586 }
2587 /* Ensure items within OCCURS are aligned correctly. */
2588 if (f->occurs_max > 1 && (size_check % occur_align_size) != 0) {
2589 pad = occur_align_size - (size_check % occur_align_size);
2590 size_check += pad;
2591 /*
2592 Add padding to last item, which will be (partly)
2593 responsible for misalignment. If the item is not SYNC,
2594 we have no problem. If it is SYNC, then it has been
2595 aligned on a smaller boundary than occur_align_size: a
2596 2-, 4- or 8-byte boundary. The needed padding will
2597 be a multiple of 2, 4 or 8 bytes, so adding extra
2598 padding will not break its alignment.
2599 */
2600 if (f->children) {
2601 get_last_child (f)->offset += pad;
2602 } else {
2603 /* ToDo: add appropriate message (untranslated) */
2604 COBC_ABORT (); /* LCOV_EXCL_LINE */
2605 }
2606 }
2607 /* size check for group items */
2608 if (unbounded_items) {
2609 if (size_check > COB_MAX_UNBOUNDED_SIZE) {
2610 /* Hack: run again for finding the correct max_occurs for unbounded items */
2611 if (unbounded_parts == 1 && unbounded_items != 1) {
2612 unbounded_parts = unbounded_items;
2613 } else {
2614 unbounded_parts++;
2615 }
2616 goto unbounded_again;
2617 }
2618 } else if (size_check > COB_MAX_FIELD_SIZE) {
2619 cb_error_x (CB_TREE (f),
2620 _("'%s' cannot be larger than %d bytes"),
2621 f->name, COB_MAX_FIELD_SIZE);
2622 }
2623 f->size = (int) size_check;
2624 } else if (!f->flag_is_external_form) {
2625 /* Elementary item */
2626 if (f->report_column > 0) { /* offset based on COLUMN value */
2627 set_report_field_offset (f);
2628 }
2629
2630 switch (f->usage) {
2631 case CB_USAGE_COMP_X:
2632 case CB_USAGE_COMP_N:
2633 if (f->pic->category == CB_CATEGORY_ALPHANUMERIC) {
2634 break;
2635 }
2636 size = f->pic->size;
2637 f->size = ((size <= 2) ? 1 : (size <= 4) ? 2 :
2638 (size <= 7) ? 3 : (size <= 9) ? 4 :
2639 (size <= 12) ? 5 : (size <= 14) ? 6 :
2640 (size <= 16) ? 7 : (size <= 19) ? 8 :
2641 (size <= 21) ? 9 : (size <= 24) ? 10 :
2642 (size <= 26) ? 11 : (size <= 28) ? 12 :
2643 (size <= 31) ? 13 : (size <= 33) ? 14 :
2644 (size <= 36) ? 15 : 16);
2645 break;
2646 case CB_USAGE_BINARY:
2647 case CB_USAGE_COMP_5:
2648 size = f->pic->size;
2649 #if 0 /* RXWRXW - Max binary */
2650 if (size > COB_MAX_BINARY) {
2651 f->flag_binary_swap = 0;
2652 size = 38;
2653 cb_error_x (CB_TREE (f),
2654 _("'%s' binary field cannot be larger than %d digits"),
2655 f->name, COB_MAX_BINARY);
2656 }
2657 #else
2658 if (size > 18) {
2659 f->flag_binary_swap = 0;
2660 size = 18;
2661 cb_error_x (CB_TREE (f),
2662 _("'%s' binary field cannot be larger than %d digits"),
2663 f->name, 18);
2664 }
2665 #endif
2666 compute_binary_size (f, size);
2667 break;
2668 case CB_USAGE_DISPLAY:
2669 /* boolean items without USAGE BIT */
2670 if (f->pic->category == CB_CATEGORY_BOOLEAN) {
2671 f->size = f->pic->size / 8;
2672 if (f->pic->size % 8 != 0) {
2673 f->size++;
2674 }
2675 break;
2676 }
2677 f->size = f->pic->size;
2678 /* size check for single items */
2679 if (f->size > COB_MAX_FIELD_SIZE) {
2680 cb_error_x (CB_TREE (f),
2681 _("'%s' cannot be larger than %d bytes"),
2682 f->name, COB_MAX_FIELD_SIZE);
2683 }
2684 if (f->pic->have_sign && f->flag_sign_separate) {
2685 f->size++;
2686 }
2687 break;
2688 case CB_USAGE_PACKED:
2689 f->size = f->pic->size / 2 + 1;
2690 break;
2691 case CB_USAGE_COMP_6:
2692 f->size = (f->pic->size + 1) / 2;
2693 break;
2694 case CB_USAGE_INDEX:
2695 case CB_USAGE_HNDL:
2696 case CB_USAGE_HNDL_WINDOW:
2697 case CB_USAGE_HNDL_SUBWINDOW:
2698 case CB_USAGE_HNDL_FONT:
2699 case CB_USAGE_HNDL_THREAD:
2700 case CB_USAGE_HNDL_MENU:
2701 case CB_USAGE_HNDL_VARIANT:
2702 case CB_USAGE_HNDL_LM:
2703 case CB_USAGE_LENGTH:
2704 f->size = sizeof (int);
2705 break;
2706 case CB_USAGE_FLOAT:
2707 f->size = sizeof (float);
2708 break;
2709 case CB_USAGE_DOUBLE:
2710 f->size = sizeof (double);
2711 break;
2712 case CB_USAGE_LONG_DOUBLE:
2713 f->size = 16;
2714 break;
2715 case CB_USAGE_FP_BIN32:
2716 f->size = 4;
2717 break;
2718 case CB_USAGE_FP_BIN64:
2719 case CB_USAGE_FP_DEC64:
2720 f->size = 8;
2721 break;
2722 case CB_USAGE_FP_BIN128:
2723 case CB_USAGE_FP_DEC128:
2724 f->size = 16;
2725 break;
2726 case CB_USAGE_OBJECT:
2727 case CB_USAGE_POINTER:
2728 case CB_USAGE_PROGRAM_POINTER:
2729 f->size = sizeof (void *);
2730 break;
2731 case CB_USAGE_BIT:
2732 /* note: similar is found in DISPLAY */
2733 f->size = f->pic->size / 8;
2734 if (f->pic->size % 8 != 0) {
2735 f->size++;
2736 }
2737 break;
2738 /* LCOV_EXCL_START */
2739 default:
2740 cobc_err_msg (_("unexpected USAGE: %d"),
2741 (int)f->usage);
2742 COBC_ABORT ();
2743 /* LCOV_EXCL_STOP */
2744 }
2745 }
2746
2747 /* The size of redefining field should not be larger than
2748 the size of redefined field unless the redefined field
2749 is level 01 and non-external */
2750 if (f->redefines && f->redefines->flag_external &&
2751 (f->size * f->occurs_max > f->redefines->size * f->redefines->occurs_max)) {
2752 if (cb_larger_redefines_ok) {
2753 cb_warning_x (cb_warn_additional, CB_TREE (f),
2754 _("size of '%s' larger than size of '%s'"),
2755 f->name, f->redefines->name);
2756 } else {
2757 cb_error_x (CB_TREE (f), _("size of '%s' larger than size of '%s'"),
2758 f->name, f->redefines->name);
2759 }
2760 }
2761
2762 return f->size;
2763 }
2764
2765 static int
validate_field_value(struct cb_field * f)2766 validate_field_value (struct cb_field *f)
2767 {
2768 if (f->values) {
2769 validate_move (CB_VALUE (f->values), CB_TREE (f), 1, NULL);
2770 }
2771
2772 if (f->children) {
2773 for (f = f->children; f; f = f->sister) {
2774 validate_field_value (f);
2775 }
2776 }
2777
2778 return 0;
2779 }
2780
2781 void
cb_validate_field(struct cb_field * f)2782 cb_validate_field (struct cb_field *f)
2783 {
2784 if (f->flag_is_verified) {
2785 return;
2786 }
2787 if (validate_field_1 (f) != 0) {
2788 f->flag_invalid = 1;
2789 return;
2790 }
2791 if (f->flag_item_78) {
2792 f->flag_is_verified = 1;
2793 return;
2794 }
2795
2796 /* Set up parameters */
2797 if (f->storage == CB_STORAGE_LOCAL ||
2798 f->storage == CB_STORAGE_LINKAGE ||
2799 f->flag_item_based) {
2800 f->flag_local = 1;
2801 }
2802 if (f->storage == CB_STORAGE_LINKAGE || f->flag_item_based) {
2803 f->flag_base = 1;
2804 }
2805 setup_parameters (f);
2806
2807 /* Compute size */
2808 occur_align_size = 1;
2809 compute_size (f);
2810 if (!f->redefines) {
2811 f->memory_size = f->size * f->occurs_max;
2812 } else if (f->redefines->memory_size < f->size * f->occurs_max) {
2813 f->redefines->memory_size = f->size * f->occurs_max;
2814 }
2815
2816 validate_field_value (f);
2817 if (f->flag_is_global) {
2818 struct cb_field *c;
2819 #if 0 /* CHECKME: Why should we adjust the field count here? */
2820 f->count++;
2821 for (c = f->children; c; c = c->sister) {
2822 c->flag_is_global = 1;
2823 c->count++;
2824 }
2825 #else
2826 for (c = f->children; c; c = c->sister) {
2827 c->flag_is_global = 1;
2828 }
2829 #endif
2830 }
2831
2832 f->flag_is_verified = 1;
2833 }
2834
2835 void
cb_validate_88_item(struct cb_field * f)2836 cb_validate_88_item (struct cb_field *f)
2837 {
2838 cb_tree x = CB_TREE (f);
2839 cb_tree l;
2840 cb_tree t;
2841
2842 if (CB_VALID_TREE (f->parent) &&
2843 CB_TREE_CLASS (f->parent) == CB_CLASS_NUMERIC) {
2844 for (l = f->values; l; l = CB_CHAIN (l)) {
2845 t = CB_VALUE (l);
2846 if (t == cb_space || t == cb_low ||
2847 t == cb_high || t == cb_quote) {
2848 cb_error_x (x, _("literal type does not match numeric data type"));
2849 }
2850 }
2851 }
2852 }
2853
2854 struct cb_field *
cb_validate_78_item(struct cb_field * f,const cob_u32_t no78add)2855 cb_validate_78_item (struct cb_field *f, const cob_u32_t no78add)
2856 {
2857 cb_tree x;
2858 cob_u32_t noadd, prec;
2859
2860 if (!f) {
2861 return last_real_field;
2862 }
2863 if (f->flag_internal_constant) { /* Keep all internal CONSTANTs */
2864 prec = 1;
2865 } else if (f->flag_constant) { /* 01 CONSTANT is verified in parser.y */
2866 prec = 1;
2867 } else {
2868 cb_verify (cb_constant_78, "78 VALUE");
2869 prec = 0;
2870 }
2871
2872 if (cb_is_expr (f->values) ) {
2873 f->values = CB_LIST_INIT(cb_evaluate_expr (f->values, prec));
2874 }
2875
2876 x = CB_TREE (f);
2877 noadd = no78add;
2878 if (CB_INVALID_TREE (f->values)) {
2879 level_require_error (x, "VALUE");
2880 noadd = 1;
2881 } else if (CB_INVALID_TREE (CB_VALUE (f->values))) {
2882 noadd = 1;
2883 }
2884
2885 if (!noadd) {
2886 cb_add_78 (f);
2887 }
2888 return last_real_field;
2889 }
2890
2891 static struct cb_field *
get_next_record_field(const struct cb_field * f)2892 get_next_record_field (const struct cb_field *f)
2893 {
2894 if (f->children) {
2895 return f->children;
2896 }
2897
2898 while (f) {
2899 if (f->sister) {
2900 return f->sister;
2901 } else {
2902 f = f->parent;
2903 }
2904 }
2905
2906 return NULL;
2907 }
2908
2909 static int
error_if_rename_thru_is_before_redefines(const struct cb_field * const item)2910 error_if_rename_thru_is_before_redefines (const struct cb_field * const item)
2911 {
2912 struct cb_field *f = cb_field_founder (item->redefines);
2913
2914 /*
2915 Perform depth-first search on the record containing the RENAMES items.
2916 */
2917 while (f) {
2918 /* Error if we find rename_thru before redefines */
2919 if (f == item->rename_thru) {
2920 cb_error_x (CB_TREE (item),
2921 _("THRU item '%s' may not come before '%s'"),
2922 cb_name (CB_TREE (item->rename_thru)),
2923 cb_name (CB_TREE (item->redefines)));
2924 return 1;
2925 } else if (f == item->redefines) {
2926 return 0;
2927 }
2928
2929 f = get_next_record_field (f);
2930 }
2931
2932 return 0;
2933 }
2934
2935 static int
error_if_is_or_in_occurs(const struct cb_field * const field,const struct cb_field * const referring_field)2936 error_if_is_or_in_occurs (const struct cb_field * const field,
2937 const struct cb_field * const referring_field)
2938 {
2939 struct cb_field *parent;
2940 int ret = 0;
2941
2942 if (field->flag_occurs) {
2943 cb_error_x (CB_TREE (referring_field),
2944 _("RENAMES cannot start/end at the OCCURS item '%s'"),
2945 cb_name (CB_TREE (field)));
2946 ret = 1;
2947 }
2948
2949 for (parent = field->parent; parent; parent = parent->parent) {
2950 if (parent->flag_occurs) {
2951 cb_error_x (CB_TREE (referring_field),
2952 _("cannot use RENAMES on part of the table '%s'"),
2953 cb_name (CB_TREE (parent)));
2954 ret = 1;
2955 }
2956 }
2957
2958 return ret;
2959 }
2960
2961 static int
error_if_invalid_type_in_renames_range(const struct cb_field * const item)2962 error_if_invalid_type_in_renames_range (const struct cb_field * const item)
2963 {
2964 const struct cb_field *end;
2965 const struct cb_field *f = item->redefines;
2966 enum cb_category category;
2967 int ret = 0;
2968
2969 /* Find last item in RENAMES range */
2970 if (item->rename_thru) {
2971 if (item->rename_thru->children) {
2972 end = get_last_child (item->rename_thru);
2973 } else {
2974 end = item->rename_thru;
2975 }
2976 } else {
2977 end = item->redefines;
2978 }
2979
2980 /*
2981 Check all items are not pointers, object references or OCCURS
2982 DEPENDING tables.
2983 */
2984 while (f) {
2985 category = cb_tree_category (CB_TREE (f));
2986 if (category == CB_CATEGORY_OBJECT_REFERENCE
2987 || category == CB_CATEGORY_DATA_POINTER
2988 || category == CB_CATEGORY_PROGRAM_POINTER) {
2989 cb_error_x (CB_TREE (item),
2990 _("RENAMES may not contain '%s' as it is a pointer or object reference"),
2991 cb_name (CB_TREE (f)));
2992 ret = 1;
2993 } else if (f->depending) {
2994 cb_error_x (CB_TREE (item),
2995 _("RENAMES may not contain '%s' as it is an OCCURS DEPENDING table"),
2996 cb_name (CB_TREE (f)));
2997 ret = 1;
2998 }
2999
3000 if (f == end) {
3001 break;
3002 } else {
3003 f = get_next_record_field (f);
3004 }
3005 }
3006 return ret;
3007 }
3008
3009 static int
error_if_invalid_level_for_renames(struct cb_field const * field,cb_tree ref)3010 error_if_invalid_level_for_renames (struct cb_field const *field, cb_tree ref)
3011 {
3012 int level = field->level;
3013
3014 if (level == 1 || level == 66 || level == 77) {
3015 /* don't pass error here as this should not invalidate the field */
3016 cb_verify_x (ref, cb_renames_uncommon_levels,
3017 _("RENAMES of 01-, 66- and 77-level items"));
3018 } else if (level == 88) {
3019 cb_error_x (ref, _("RENAMES may not reference a level 88"));
3020 return 1;
3021 }
3022 return 0;
3023 }
3024
3025 int
cb_validate_renames_item(struct cb_field * item,cb_tree ref_renames,cb_tree ref_thru)3026 cb_validate_renames_item (struct cb_field *item,
3027 cb_tree ref_renames, cb_tree ref_thru)
3028 {
3029 const cb_tree item_tree = CB_TREE (item);
3030 const char *redefines_name = cb_name (CB_TREE (item->redefines));
3031 const char *rename_thru_name = cb_name (CB_TREE (item->rename_thru));
3032 struct cb_field *founder;
3033 struct cb_field *f;
3034 int ret = 0;
3035
3036 if (error_if_invalid_level_for_renames (item->redefines, ref_renames)) {
3037 return 1;
3038 }
3039
3040 founder = cb_field_founder (item->redefines);
3041 if (item->parent != founder) {
3042 cb_error_x (item_tree,
3043 _("'%s' must immediately follow the record '%s'"),
3044 cb_name (item_tree),
3045 cb_name (CB_TREE (founder)));
3046 ret = 1;
3047 }
3048
3049 if (item->redefines == item->rename_thru) {
3050 cb_error_x (item_tree,
3051 _("THRU item must be different to '%s'"),
3052 redefines_name);
3053 ret = 1;
3054 } else if (item->rename_thru) {
3055 if (founder != cb_field_founder (item->rename_thru)) {
3056 cb_error_x (item_tree,
3057 _("'%s' and '%s' must be in the same record"),
3058 redefines_name, rename_thru_name);
3059 return 1;
3060 }
3061 if (error_if_rename_thru_is_before_redefines (item)
3062 || error_if_invalid_level_for_renames (item->rename_thru, ref_thru)) {
3063 return 1;
3064 }
3065 for (f = item->rename_thru; f; f = f->parent) {
3066 if (f->parent == item->redefines) {
3067 cb_error_x (item_tree,
3068 _("THRU item '%s' may not be subordinate to '%s'"),
3069 rename_thru_name, redefines_name);
3070 return 1;
3071 }
3072 }
3073 }
3074 ret |= error_if_invalid_type_in_renames_range (item);
3075
3076 if (!error_if_is_or_in_occurs (item->redefines, item)
3077 && item->rename_thru) {
3078 ret |= error_if_is_or_in_occurs (item->rename_thru, item);
3079 }
3080
3081 return ret;
3082 }
3083
3084 void
cb_clear_real_field(void)3085 cb_clear_real_field (void)
3086 {
3087 last_real_field = NULL;
3088 }
3089
3090 struct cb_field *
cb_get_real_field(void)3091 cb_get_real_field (void)
3092 {
3093 return last_real_field;
3094 }
3095
3096 const char *
cb_get_usage_string(const enum cb_usage usage)3097 cb_get_usage_string (const enum cb_usage usage)
3098 {
3099 switch (usage) {
3100 case CB_USAGE_BINARY:
3101 return "COMP";
3102 case CB_USAGE_BIT:
3103 return "BIT";
3104 case CB_USAGE_COMP_5:
3105 return "COMP-5";
3106 case CB_USAGE_COMP_X:
3107 return "COMP-X";
3108 case CB_USAGE_COMP_N:
3109 return "COMP-N";
3110 case CB_USAGE_DISPLAY:
3111 return "DISPLAY";
3112 case CB_USAGE_FLOAT:
3113 return "COMP-1";
3114 /* return "FLOAT-SHORT"; */
3115 case CB_USAGE_DOUBLE:
3116 return "COMP-2";
3117 /* return "FLOAT-LONG"; */
3118 case CB_USAGE_INDEX:
3119 return "INDEX";
3120 case CB_USAGE_NATIONAL:
3121 return "NATIONAL";
3122 case CB_USAGE_OBJECT:
3123 return "OBJECT REFERENCE";
3124 case CB_USAGE_PACKED:
3125 return "COMP-3";
3126 /* return "PACKED-DECIMAL"; */
3127 case CB_USAGE_POINTER:
3128 return "POINTER";
3129 case CB_USAGE_LENGTH:
3130 /* Probably---generates a cob_u32_t item.*/
3131 return "BINARY-LONG";
3132 case CB_USAGE_PROGRAM_POINTER:
3133 return "PROGRAM-POINTER";
3134 case CB_USAGE_UNSIGNED_CHAR:
3135 return "UNSIGNED-CHAR";
3136 case CB_USAGE_SIGNED_CHAR:
3137 return "SIGNED-CHAR";
3138 case CB_USAGE_UNSIGNED_SHORT:
3139 return "UNSIGNED-SHORT";
3140 case CB_USAGE_SIGNED_SHORT:
3141 return "SIGNED-SHORT";
3142 case CB_USAGE_UNSIGNED_INT:
3143 return "UNSIGNED-INT";
3144 case CB_USAGE_SIGNED_INT:
3145 return "SIGNED-INT";
3146 case CB_USAGE_UNSIGNED_LONG:
3147 return "UNSIGNED-LONG";
3148 case CB_USAGE_SIGNED_LONG:
3149 return "SIGNED-LONG";
3150 case CB_USAGE_COMP_6:
3151 return "COMP-6";
3152 case CB_USAGE_FP_DEC64:
3153 return "FLOAT-DECIMAL-16";
3154 case CB_USAGE_FP_DEC128:
3155 return "FLOAT-DECIMAL-34";
3156 case CB_USAGE_FP_BIN32:
3157 return "FLOAT-BINARY-32";
3158 case CB_USAGE_FP_BIN64:
3159 return "FLOAT-BINARY-64";
3160 case CB_USAGE_FP_BIN128:
3161 return "FLOAT-BINARY-128";
3162 case CB_USAGE_LONG_DOUBLE:
3163 return "FLOAT-EXTENDED";
3164 case CB_USAGE_HNDL:
3165 return "HANDLE";
3166 case CB_USAGE_HNDL_WINDOW:
3167 return "HANDLE OF WINDOW";
3168 case CB_USAGE_HNDL_SUBWINDOW:
3169 return "HANDLE OF SUBWINDOW";
3170 case CB_USAGE_HNDL_FONT:
3171 return "HANDLE OF FONT";
3172 case CB_USAGE_HNDL_THREAD:
3173 return "HANDLE OF THREAD";
3174 case CB_USAGE_HNDL_MENU:
3175 return "HANDLE OF MENU";
3176 case CB_USAGE_HNDL_VARIANT:
3177 return "VARIANT";
3178 case CB_USAGE_HNDL_LM:
3179 return "HANDLE OF LAYOUT-MANAGER";
3180 /* LCOV_EXCL_START */
3181 default:
3182 cb_error (_("unexpected USAGE: %d"), usage);
3183 COBC_ABORT ();
3184 /* LCOV_EXCL_STOP */
3185 }
3186 }
3187
3188 int
cb_is_figurative_constant(const cb_tree x)3189 cb_is_figurative_constant (const cb_tree x)
3190 {
3191 return x == cb_null
3192 || x == cb_zero
3193 || x == cb_space
3194 || x == cb_low
3195 || x == cb_norm_low
3196 || x == cb_high
3197 || x == cb_norm_high
3198 || x == cb_quote
3199 || (CB_REFERENCE_P (x)
3200 && CB_REFERENCE (x)->flag_all);
3201 }
3202
3203 int
cb_field_is_ignored_in_ml_gen(struct cb_field * const f)3204 cb_field_is_ignored_in_ml_gen (struct cb_field * const f)
3205 {
3206 return f->flag_filler || f->redefines || f->rename_thru;
3207 }
3208