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