1 /*
2  * Motif
3  *
4  * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22 */
23 #ifdef REV_INFO
24 #ifndef lint
25 static char rcsid[] = "$TOG: UilSemVal.c /main/18 1997/09/15 14:15:21 cshi $"
26 #endif
27 #endif
28 
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 
33 
34 /*
35 **++
36 **  FACILITY:
37 **
38 **      User Interface Language Compiler (UIL)
39 **
40 **  ABSTRACT:
41 **
42 **      This module contains the second pass routines for performing
43 **	semantic validation.
44 **
45 **--
46 **/
47 
48 
49 /*
50 **
51 **  INCLUDE FILES
52 **
53 **/
54 
55 #include <stdlib.h>
56 #include <setjmp.h>
57 #include <Mrm/MrmAppl.h>
58 #include <Xm/XmStrDefs.h>
59 
60 
61 #include "UilDefI.h"
62 
63 
64 /*
65 **
66 **  DEFINE and MACRO DEFINITIONS
67 **
68 **  The order of these constants is significant. The constants lower in
69 **  value than error_arg_type are basically numeric types and various
70 **  conversions may be done on those types. Those constants are compared
71 **  numerically with error_arg_type to determine whether they may be
72 **  converted. Furthermore, the numeric_convert_table is indexed by
73 **  those constants. If you are adding new arg types, add before error_arg_type
74 **  if it is a numeric type, but also remember to update the numeric_
75 **  convert_table below to have an entry for that type. Add the new type
76 **  after error_arg_type if it is not numeric. lstr_arg_type must be after
77 **  char_arg_type and before cstr_arg_type.  When done, update all the constants
78 **  to be sequential.
79 **
80 **/
81 
82 #define	boolean_arg_type    		0
83 #define	integer_arg_type    		1
84 #define single_float_arg_type 		2
85 #define float_arg_type	    		3
86 #define horizontal_integer_arg_type 	4
87 #define vertical_integer_arg_type 	5
88 #define horizontal_float_arg_type 	6
89 #define vertical_float_arg_type 	7
90 #define error_arg_type	    		8
91 
92 #define	char_arg_type	    		9
93 #define lstr_arg_type			10
94 #define	cstr_arg_type	    		11
95 #define keysym_arg_type  		12
96 #define font_arg_type	    		13
97 #define color_arg_type	    		14
98 #define xbitmap_arg_type   		15
99 #define reason_arg_type	   		16
100 #define argument_arg_type  		17
101 #define font_table_arg_type 		18
102 #define wcstr_arg_type			19
103 #define fontset_arg_type		20
104 /*  BEGIN HaL fix CR 5429 */
105 #define classrec_arg_type     		21
106 /* END HaL Fix CR 5429 */
107 
108 /*
109 **
110 **  EXTERNAL VARIABLE DECLARATIONS
111 **
112 **/
113 
114 
115 /*
116 **
117 **  GLOBAL VARIABLE DECLARATIONS
118 **
119 **/
120 
121 
122 /*
123 **
124 **  OWN VARIABLE DECLARATIONS
125 **
126 **/
127 
128 static unsigned int		ref_chk_value = 0;
129 static short			in_expr = 0;
130 static int			cycle_id = 1;
131 
132 /*
133 **  This table is indexed by arg_types defined above that are less than
134 **  error_arg_type.
135 **/
136 
137 static int ( * numeric_convert_table[])() = {
138 	    0,
139 	    sem_convert_to_integer,
140 	    sem_convert_to_single_float,
141 	    sem_convert_to_float,
142 	    sem_convert_to_integer,
143 	    sem_convert_to_integer,
144 	    sem_convert_to_float,
145 	    sem_convert_to_float,
146 	    sem_convert_to_error };
147 
148 /*
149  * The next two definitions must match value sets defining
150  * expression operators in UilSymDef.h
151  */
152 
153 static unsigned int legal_operand_type[ ] = {
154     /* unused */	0,
155     /* not */		1 << sym_k_bool_value | 1 << sym_k_integer_value,
156     /* unary plus */	1 << sym_k_integer_value |
157       			1 << sym_k_horizontal_integer_value |
158       			1 << sym_k_vertical_integer_value |
159       			1 << sym_k_float_value |
160 			1 << sym_k_horizontal_float_value |
161 			1 << sym_k_vertical_float_value |
162                         1 << sym_k_single_float_value,
163     /* unary minus */	1 << sym_k_integer_value |
164       			1 << sym_k_horizontal_integer_value |
165       			1 << sym_k_vertical_integer_value |
166       			1 << sym_k_float_value |
167 			1 << sym_k_horizontal_float_value |
168 			1 << sym_k_vertical_float_value |
169                         1 << sym_k_single_float_value,
170     /* comp_str */	1 << sym_k_char_8_value |
171 			1 << sym_k_localized_string_value |
172 			1 << sym_k_compound_string_value,
173     /* wchar_str */	1 << sym_k_localized_string_value,
174     /* multiply */	1 << sym_k_integer_value |
175       			1 << sym_k_horizontal_integer_value |
176       			1 << sym_k_vertical_integer_value |
177       			1 << sym_k_float_value |
178 			1 << sym_k_horizontal_float_value |
179 			1 << sym_k_vertical_float_value |
180                         1 << sym_k_single_float_value,
181     /* divide */	1 << sym_k_integer_value |
182       			1 << sym_k_horizontal_integer_value |
183       			1 << sym_k_vertical_integer_value |
184       			1 << sym_k_float_value |
185 			1 << sym_k_horizontal_float_value |
186 			1 << sym_k_vertical_float_value |
187                         1 << sym_k_single_float_value,
188     /* add */		1 << sym_k_integer_value |
189       			1 << sym_k_horizontal_integer_value |
190       			1 << sym_k_vertical_integer_value |
191       			1 << sym_k_float_value |
192 			1 << sym_k_horizontal_float_value |
193 			1 << sym_k_vertical_float_value |
194                         1 << sym_k_single_float_value,
195     /* subtract */	1 << sym_k_integer_value |
196       			1 << sym_k_horizontal_integer_value |
197       			1 << sym_k_vertical_integer_value |
198       			1 << sym_k_float_value |
199 			1 << sym_k_horizontal_float_value |
200 			1 << sym_k_vertical_float_value |
201                         1 << sym_k_single_float_value,
202     /* left shift */	1 << sym_k_integer_value,
203     /* right shift */	1 << sym_k_integer_value,
204     /* and */		1 << sym_k_bool_value |
205                         1 << sym_k_integer_value |
206 			1 << sym_k_char_8_value |
207 			1 << sym_k_localized_string_value |
208 			1 << sym_k_compound_string_value |
209 			1 << sym_k_localized_string_value,
210     /* xor */		1 << sym_k_bool_value | 1 << sym_k_integer_value,
211     /* or */		1 << sym_k_bool_value | 1 << sym_k_integer_value,
212     /* cat */		1 << sym_k_char_8_value |
213 			1 << sym_k_compound_string_value |
214 			1 << sym_k_localized_string_value,
215     /* valref */	0xFFFFFFFF,
216     /* coerce */	0xFFFFFFFF
217 				  };
218 static char	*operator_symbol[ ] = {
219     /* unused */	"** OPERATOR ERROR**",
220     /* not */		"not operator",
221     /* unary plus */	"unary plus operator",
222     /* unary minus */	"unary minus operator",
223     /* comp str */	"compound string function",
224     /* wchar str */	"wide_character string function",
225     /* multiply */	"multiply operator",
226     /* divide */	"divide operator",
227     /* add */		"add operator",
228     /* subtract */	"subtract operator",
229     /* left shift */	"left shift operator",
230     /* right shift */	"right shift operator",
231     /* and */		"and operator",
232     /* xor */		"exclusive or operator",
233     /* or */		"or operator",
234     /* cat */		"concatenate operator",
235     /* coerce */	"coerce operator",
236 				  };
237 
238 static char	*value_text[ ] = {
239     /* boolean */	"boolean expression",
240     /* integer */	"integer expression",
241     /* float */		"floating point expression",
242 			};
243 
244 static sym_argument_entry_type		**arg_seen;
245 static sym_callback_entry_type		**reason_seen;
246 
247 
248 
249 
250 /*
251 **++
252 **  FUNCTIONAL DESCRIPTION:
253 **
254 **      This function walks the entire parse tree for the input, and
255 **	performs semantic validation. It guarantees type matching,
256 **	that arguments and controls and legal, etc.
257 **
258 **  FORMAL PARAMETERS:
259 **
260 **      none
261 **
262 **  IMPLICIT INPUTS:
263 **
264 **      sym_az_root_entry
265 **
266 **  IMPLICIT OUTPUTS:
267 **
268 **      none
269 **
270 **  FUNCTION VALUE:
271 **
272 **      void
273 **
274 **  SIDE EFFECTS:
275 **
276 **      error messages may be issued for objects that are still undefined
277 **	or of the wrong type
278 **
279 **--
280 **/
281 
sem_validation()282 void	sem_validation ()
283 {
284 
285 /*
286  * Allocate storage if required
287  */
288 if ( arg_seen == NULL )
289     arg_seen = (sym_argument_entry_type **)
290 	XtMalloc (sizeof(sym_argument_entry_type *)*(uil_max_arg+1));
291 if ( reason_seen == NULL )
292     reason_seen = (sym_callback_entry_type **)
293 	XtMalloc (sizeof(sym_argument_entry_type *)*(uil_max_reason+1));
294 
295 /*
296  * Walk the parse tree, performing validation on each node which
297  * requires it.
298  */
299 sem_validate_node (( sym_entry_type *)sym_az_root_entry->sections);
300 
301 }
302 
303 
304 
305 /*
306 **++
307 **  FUNCTIONAL DESCRIPTION:
308 **
309 **      This routine recursively walks through the parse tree. It
310 **	ignores any nodes which require no pass 2 validation, and
311 **	calls a specialized routine for any others. It checks for
312 **	any requests to terminate.
313 **
314 **  FORMAL PARAMETERS:
315 **
316 **      node		current parse tree node
317 **
318 **  IMPLICIT INPUTS:
319 **
320 **      >
321 **
322 **  IMPLICIT OUTPUTS:
323 **
324 **      >
325 **
326 **  FUNCTION VALUE:
327 **
328 **      void
329 **
330 **  SIDE EFFECTS:
331 **
332 **      may terminate processing
333 **
334 **--
335 **/
336 
sem_validate_node(node)337 void sem_validate_node (node)
338     sym_entry_type		*node;
339 
340 {
341 
342 /*
343  * Local variables
344  */
345 sym_value_entry_type		*value_node;
346 sym_widget_entry_type		*widget_node;
347 sym_widget_entry_type		*child_node;
348 sym_list_entry_type		*list_node;
349 sym_include_file_entry_type	*ifile_node;
350 sym_section_entry_type		*section_node;
351 sym_obj_entry_type		*entry_node;
352 sym_obj_entry_type		*list_member;
353 sym_nested_list_entry_type	*nested_list_entry;
354 sym_control_entry_type		*control_entry;
355 
356 /*
357  * Call the status callback routine to report progress and check status
358  */
359 /* %COMPLETE */
360 Uil_percent_complete = 80;
361 if ( Uil_cmd_z_command.status_cb != (Uil_continue_type(*)())NULL )
362     diag_report_status ();
363 
364 /*
365  * Switch on the node type for validation and recursion.
366  */
367 if ( node == NULL ) return;
368 switch ( node->header.b_tag )
369     {
370     case sym_k_value_entry:
371         value_node = (sym_value_entry_type *) node;
372 	sem_validate_value_node (value_node);
373 	break;
374     case sym_k_widget_entry:
375     case sym_k_gadget_entry:
376     case sym_k_child_entry:
377 	widget_node = (sym_widget_entry_type *) node;
378 	sem_validate_widget_node (widget_node);
379 
380 	/*
381 	 * Recurse for children and validate all children. Duplicate
382 	 * validation will not occur since sem_validate_widget_node checks
383 	 * bflags for validated flag.
384 	 */
385  	sem_validate_node (( sym_entry_type *)widget_node->az_controls);
386 	break;
387     case sym_k_list_entry:
388 	/*
389 	 * recursive entry point for processing controls lists.
390 	 */
391 	list_node = (sym_list_entry_type *) node;
392 	if ( list_node->header.b_type != sym_k_control_list )
393 	    break;
394 	for (list_member=(sym_obj_entry_type *)list_node->obj_header.az_next;
395 	     list_member!=NULL;
396 	     list_member=(sym_obj_entry_type *)list_member->obj_header.az_next)
397 	    switch ( list_member->header.b_tag )
398 		{
399 		case sym_k_nested_list_entry:
400 		    nested_list_entry =
401 			(sym_nested_list_entry_type *) list_member;
402 		    sem_validate_node (( sym_entry_type *)nested_list_entry->az_list);
403 		    break;
404 		case sym_k_control_entry:
405 		    control_entry = (sym_control_entry_type *) list_member;
406 		    child_node = (sym_widget_entry_type *)
407 			control_entry->az_con_obj;
408 		    sem_validate_node (( sym_entry_type *)child_node);
409 		break;
410 		}
411 	break;
412     case sym_k_include_file_entry:
413 	ifile_node = (sym_include_file_entry_type *) node;
414 	sem_validate_node (( sym_entry_type *)ifile_node->sections);
415 	break;
416     case sym_k_section_entry:
417 	section_node = (sym_section_entry_type *) node;
418 	sem_validate_node (( sym_entry_type *)section_node->next);
419 	switch ( section_node->header.b_type )
420 	    {
421 	    case sym_k_section_tail:
422 		break;
423 	    default:
424 	        entry_node = (sym_obj_entry_type *) section_node->entries;
425 		sem_validate_node (( sym_entry_type *)entry_node);
426 		break;
427 	    }
428 	break;
429     }
430 
431 }
432 
433 
434 
435 /*
436 **++
437 **  FUNCTIONAL DESCRIPTION:
438 **
439 **      This routine validates a value node
440 **
441 **  FORMAL PARAMETERS:
442 **
443 **      value_node		the symbol table node to be validated.
444 **
445 **  IMPLICIT INPUTS:
446 **
447 **  IMPLICIT OUTPUTS:
448 **
449 **  FUNCTION VALUE:
450 **
451 **      pointer to the value node resulting from the operation (may be
452 **      different from input)
453 **
454 **  SIDE EFFECTS:
455 **
456 **      error reporting
457 **
458 **--
459 **/
460 
sem_validate_value_node(value_node)461 sym_value_entry_type *sem_validate_value_node (value_node)
462     sym_value_entry_type	*value_node;
463 
464 {
465 
466 /*
467  * Local variables
468  */
469 
470 
471 /*
472  * Both evaluation and validation are done by the value evaluation routine
473  */
474 if ( value_node == NULL )
475     return NULL;
476 if ( value_node->obj_header.b_flags & sym_m_validated )
477     return value_node;
478 
479 sem_evaluate_value (value_node);
480 value_node->obj_header.b_flags |= sym_m_validated;
481 return value_node;
482 }
483 
484 
485 
486 /*
487 **++
488 **  FUNCTIONAL DESCRIPTION:
489 **
490 **      This routine validates a widget node
491 **
492 **  FORMAL PARAMETERS:
493 **
494 **      widget_node		the symbol table node to be validated.
495 **
496 **  IMPLICIT INPUTS:
497 **
498 **  IMPLICIT OUTPUTS:
499 **
500 **  FUNCTION VALUE:
501 **
502 **  SIDE EFFECTS:
503 **
504 **      error reporting
505 **
506 **--
507 **/
508 
sem_validate_widget_node(widget_node)509 void sem_validate_widget_node (widget_node)
510     sym_widget_entry_type	*widget_node;
511 
512 {
513 
514 /*
515  * Local variables
516  */
517 unsigned int			widget_type;
518 sym_list_entry_type		*list_entry;	/* for various lists */
519 
520 /*
521  * if this widget has already been validated just return
522  */
523 if (widget_node->obj_header.b_flags & sym_m_validated)
524     return;
525 
526 /*
527  * Pick up widget parameters
528  */
529 if (widget_node->header.b_tag == sym_k_child_entry)
530   widget_type = child_class_table[(int)widget_node->header.b_type];
531 else widget_type = widget_node->header.b_type;
532 
533 /*
534  * Validate the arguments. Each argument in the list is validated
535  * by an argument validation routine.
536  */
537 if ( widget_node->az_arguments != NULL )
538     {
539     int			ndx;
540     for ( ndx=0 ; ndx<uil_max_arg+1 ; ndx++ )
541 	arg_seen[ndx] = 0;
542     sem_validate_argument_list (widget_node, widget_type,
543 				widget_node->az_arguments, arg_seen);
544     }
545 
546 /*
547  * Validate the callbacks. Each callback is validated by a validation
548  * routine
549  */
550 if ( widget_node->az_callbacks != NULL )
551     {
552     int			ndx;
553     for ( ndx=0 ; ndx<uil_max_reason+1 ; ndx++ )
554 	reason_seen[ndx] = 0;
555     sem_validate_callback_list (widget_node, widget_type,
556 				widget_node->az_callbacks, reason_seen);
557     }
558 
559 /*
560  * Validate the controls. Each is validated by a validation routine.
561  * Also check the node for cycles.
562  */
563 if ( widget_node->az_controls != NULL )
564     {
565     int					gadget_count = 0;
566 
567     list_entry = (sym_list_entry_type *) widget_node->az_controls;
568     sem_validate_control_list (widget_node, widget_type,
569 			       list_entry, &gadget_count);
570     list_entry->w_gadget_count = gadget_count;
571     sem_validate_widget_cycle (list_entry, widget_node->obj_header.az_name);
572     }
573 
574 /*
575  * Mark the widget as validated
576  */
577 widget_node->obj_header.b_flags |= sym_m_validated;
578 }
579 
580 
581 
582 /*
583 **++
584 **  FUNCTIONAL DESCRIPTION:
585 **
586 **      This routine validates all the arguments in an argument list.
587 **	It recurse down nested lists.
588 **
589 **  FORMAL PARAMETERS:
590 **
591 **      widget_node	the current widget
592 **	widget_type	the current widget's type
593 **	list_entry	list to be validated
594 **	seen  	        flag table to detect duplicate arguments
595 **
596 **  IMPLICIT INPUTS:
597 **
598 **  IMPLICIT OUTPUTS:
599 **
600 **  FUNCTION VALUE:
601 **
602 **  SIDE EFFECTS:
603 **
604 **--
605 **/
606 
sem_validate_argument_list(widget_node,widget_type,list_entry,seen)607 void sem_validate_argument_list	(widget_node, widget_type, list_entry, seen)
608     sym_widget_entry_type		*widget_node;
609     unsigned int			widget_type;
610     sym_list_entry_type			*list_entry;
611     sym_argument_entry_type		**seen;
612 
613 {
614 
615 /*
616  * Local variables
617  */
618 sym_obj_entry_type		*list_member;
619 sym_nested_list_entry_type	*nested_list_entry;
620 sym_argument_entry_type		*argument_entry;
621 /* For fixing DTS 9540 */
622 static    int nest_count=0;
623 static    sym_list_entry_type *nest_head = NULL;
624 
625 
626 /*
627  * loop down the list
628  */
629 if ( list_entry == NULL ) return;
630 for (list_member=(sym_obj_entry_type *)list_entry->obj_header.az_next;
631      list_member!=NULL;
632      list_member=(sym_obj_entry_type *)list_member->obj_header.az_next)
633     switch ( list_member->header.b_tag )
634 	{
635 	case sym_k_nested_list_entry:
636 	    nested_list_entry = (sym_nested_list_entry_type *) list_member;
637             /* Begin fixing DTS 9540 */
638             if(!nest_count)
639                nest_head = nested_list_entry->az_list;
640             nest_count++;
641             if(nest_count == 1 || nest_head != nested_list_entry->az_list){
642 	    	sem_validate_argument_list (widget_node, widget_type,
643 					nested_list_entry->az_list, seen);
644                 nest_count--;
645             }else
646     		diag_issue_diagnostic
647 			(d_circular_ref,
648 	 		_sar_source_pos2(list_entry),
649 	 		"argument name");
650             /* End fixing DTS 9540 */
651 	    break;
652 	case sym_k_argument_entry:
653 	    argument_entry = (sym_argument_entry_type *) list_member;
654 	    sem_validate_argument_entry	(widget_node, widget_type,
655 					 list_entry, argument_entry, seen);
656 	    break;
657 	default:
658 	    diag_issue_diagnostic
659 	        ( d_list_item,
660 	          _sar_source_pos2 ( list_entry ),
661 	          diag_tag_text (sym_k_argument_entry),
662 	          diag_tag_text (list_entry->header.b_type),
663 	          diag_tag_text (list_entry->header.b_tag) );
664 	}
665 
666 }
667 
668 
669 
670 /*
671 **++
672 **  FUNCTIONAL DESCRIPTION:
673 **
674 **      This routine performs validation for a single argument entry
675 **	for the current widget node.
676 **
677 **  FORMAL PARAMETERS:
678 **
679 **      widget_node	the current widget
680 **	widget_type	the current widget's type
681 **	list_entry	list entry for current argument entry
682 **	argument_entry	the current argument entry
683 **	seen 	       flag table to detect duplicate arguments
684 **
685 **  IMPLICIT INPUTS:
686 **
687 **
688 **  IMPLICIT OUTPUTS:
689 **
690 **  FUNCTION VALUE:
691 **
692 **      void
693 **
694 **  SIDE EFFECTS:
695 **
696 **      error reporting
697 **
698 **--
699 **/
700 
sem_validate_argument_entry(widget_node,widget_type,list_entry,argument_entry,seen)701 void sem_validate_argument_entry
702 	(widget_node, widget_type, list_entry, argument_entry, seen)
703     sym_widget_entry_type		*widget_node;
704     unsigned int			widget_type;
705     sym_list_entry_type			*list_entry;
706     sym_argument_entry_type		*argument_entry;
707     sym_argument_entry_type		**seen;
708 
709 {
710 
711 /*
712  * Local variables
713  */
714 sym_value_entry_type		*argname_value_entry;
715 sym_value_entry_type		*argvalue_value_entry;
716 key_keytable_entry_type		*keytable_entry;
717 sym_argument_entry_type		**seen_entry;
718 boolean				supported_flag;
719 unsigned char			expected_type, actual_type = 0, actual_tag;
720 boolean				valid_value;
721 
722 
723 /*
724  * ignore error entries, consistency check
725  */
726 if ( argument_entry->header.b_tag == sym_k_error_entry ) return;
727 _assert (argument_entry->header.b_tag==sym_k_argument_entry,
728 	 "unexpected non argument entry");
729 
730 /*
731  * Validate and evaluate the argument name and argument value entries.
732  */
733 
734 sem_validate_node (( sym_entry_type *)argument_entry->az_arg_name);
735 
736 /*
737  * There is no need to validate the value if it is a widget since widgets are
738  * validated elsewhere and you can't define widgets in an argument list anyway.
739  */
740 
741 if ( argument_entry->az_arg_value == NULL )
742     return;
743 
744 if ((argument_entry->az_arg_value->header.b_tag != sym_k_widget_entry) &&
745     (argument_entry->az_arg_value->header.b_tag != sym_k_gadget_entry))
746     sem_validate_node (( sym_entry_type *)argument_entry->az_arg_value);
747 
748 argname_value_entry = (sym_value_entry_type *) argument_entry->az_arg_name;
749 if ( argname_value_entry == NULL )
750     {
751     diag_issue_diagnostic
752 	(d_bad_argument,
753 	 _sar_source_pos2(argument_entry),
754 	 "argument name");
755     return;
756     }
757 
758 sem_evaluate_value_expr(argname_value_entry);
759 _assert (argname_value_entry->header.b_tag==sym_k_value_entry,
760 	 "invalid argument name value_entry");
761 if (argname_value_entry->b_type != sym_k_argument_value)
762     {
763     diag_issue_diagnostic
764 	(d_list_item,
765 	 _sar_source_pos2(argname_value_entry),
766 	 diag_value_text(argname_value_entry->b_type),
767 	 diag_tag_text(list_entry->header.b_type),
768 	 diag_tag_text(list_entry->header.b_tag));
769     return;
770     }
771 
772 argvalue_value_entry = (sym_value_entry_type *) argument_entry->az_arg_value;
773 
774 /* BEGIN HAL Fix CR 3857 */
775 if ((argument_entry->az_arg_value->header.b_tag != sym_k_widget_entry) &&
776     (argument_entry->az_arg_value->header.b_tag != sym_k_gadget_entry))
777 /* END HAL Fix CR 3857 */
778   sem_evaluate_value_expr(argvalue_value_entry);
779 
780 /*
781  * Check for unsupported arguments. Validate constraints.
782  * This check is required for known toolkit arguments in
783  * toolkit widgets.
784  */
785 if ( (argname_value_entry->obj_header.b_flags&sym_m_builtin) &&
786      (widget_type!=uil_sym_user_defined_object) &&
787      (argname_value_entry->obj_header.az_name == NULL) )
788     {
789     /*
790      * Pick up the token keytable entry for the argument.
791      * Fork on whether it is a constraint argument
792      */
793     keytable_entry = (key_keytable_entry_type *)
794 	argname_value_entry->value.az_data;
795     _assert (keytable_entry->b_class==tkn_k_class_argument,
796 	     "unexpected non-argument keytable entry");
797     if ( _constraint_check(keytable_entry->b_subclass) )
798 	sem_validate_constraint_entry (widget_node, argument_entry, widget_type);
799     else
800 	{
801 	supported_flag = sem_argument_allowed
802 	    (keytable_entry->b_subclass, widget_type);
803 	if ( ! supported_flag )
804 	    diag_issue_diagnostic
805 		(d_unsupported,
806 		 _sar_source_pos2(argument_entry),
807 		 keytable_entry->at_name,
808 		 diag_tag_text(argument_entry->header.b_tag),
809 		 diag_object_text(widget_type));
810 	}
811 
812     /*
813      * Check for duplicate arguments. A warning is issued, but the
814      * argument is not removed from the list, since it may occur in
815      * an argument list - and the argument list may be referenced in
816      * another context where this argument is not duplicated.
817      */
818     seen_entry = (sym_argument_entry_type **)
819 	&seen[keytable_entry->b_subclass];
820     if ( *seen_entry != NULL )
821 	{
822 	diag_issue_diagnostic
823 	    (d_supersede,
824 	     _sar_source_pos2(argument_entry),
825 	     keytable_entry->at_name,
826 	     diag_tag_text(argument_entry->header.b_tag),
827 	     diag_tag_text(list_entry->header.b_type),
828 	     diag_tag_text(list_entry->header.b_tag));
829 	}
830     else
831 	{
832 	*seen_entry = argument_entry;
833 	}
834 
835     /*
836      * Make sure that any enumeration value reference is valid.
837      */
838     sem_validate_argument_enumset (argument_entry,
839 				   keytable_entry->b_subclass,
840 				   argvalue_value_entry);
841     }
842 
843 /*
844 **  Verify the value type for this argument, if it is a
845 **  built-in argument or a user_defined argument. Check for
846 **  proper enumeration set match
847 */
848 if ( (argname_value_entry->obj_header.b_flags & sym_m_builtin) &&
849      (argname_value_entry->obj_header.az_name == NULL) )
850     {
851     key_keytable_entry_type		* keytable_entry;
852 
853     keytable_entry =
854 	(key_keytable_entry_type *) argname_value_entry->value.az_data;
855     _assert (keytable_entry->b_class==tkn_k_class_argument,
856 	     "name is not an argument");
857     expected_type = argument_type_table[keytable_entry->b_subclass];
858     }
859 else
860     expected_type = argname_value_entry->b_arg_type;
861 
862 /*
863 ** Argument value validation
864 **
865 ** Acquire and evaluate argument value.
866 ** Allow a widget reference as the value of an argument.  NOTE: gadgets
867 ** are not allowed as argument values, only controls.
868 **
869 ** This entry may be absent due to extensive compilation errors.
870 */
871 if ( argvalue_value_entry == NULL ) return;
872 
873 actual_tag = argvalue_value_entry->header.b_tag;
874 switch ( actual_tag )
875     {
876     case sym_k_value_entry:
877         actual_type = argvalue_value_entry->b_type;
878 	break;
879     case sym_k_widget_entry:
880 	actual_type = sym_k_widget_ref_value;
881 	break;
882     default:
883 	_assert (FALSE, "value entry missing");
884 	break;
885     }
886 valid_value = (actual_type == expected_type);
887 
888 /*
889 ** Coerce actual_type to expected_type for certain special cases.
890 ** We'll do this by creating a new value node for the coerced value with
891 ** the coerce unary operator set.  We'll actually perform the coersion
892 ** operation here and set the flag indicating that expression evaluation
893 ** has already taken place.
894 */
895 if ( expected_type == sym_k_any_value )
896     valid_value = TRUE;
897 if ( actual_type == sym_k_any_value )
898     valid_value = TRUE;
899 if ( actual_type == sym_k_identifier_value )
900     valid_value = TRUE;
901 if (( expected_type == sym_k_pixmap_value ) &&
902     ( actual_type == sym_k_icon_value ))
903     valid_value = TRUE;
904 if (( expected_type == sym_k_pixmap_value ) &&
905     ( actual_type == sym_k_xbitmapfile_value ))
906     valid_value = TRUE;
907 if (( expected_type == sym_k_color_value) &&      /* RAP rgb data type */
908     ( actual_type == sym_k_rgb_value))
909     valid_value = TRUE;
910 /*  BEGIN HaL fix CR 5429 */
911 if (( expected_type == sym_k_class_rec_name_value) &&
912     ( actual_type == sym_k_class_rec_name_value))
913     valid_value = TRUE;
914 /*  END HaL fix CR 5429 */
915 /* For boolean values converted to enums */
916 if ((expected_type == sym_k_integer_value) &&
917     (actual_type == sym_k_bool_value))
918     valid_value = TRUE;
919 if (( expected_type == sym_k_char_8_value ) &&
920     ( actual_type == sym_k_localized_string_value ))
921     valid_value = TRUE;
922 if (( expected_type == sym_k_compound_string_value ) &&
923     ( actual_type == sym_k_char_8_value ))
924     {
925     valid_value = TRUE;
926     if ( (argvalue_value_entry->obj_header.b_flags & sym_m_private) != 0)
927 	{
928 	sym_value_entry_type   *cstr_value;
929 
930 	cstr_value = (sym_value_entry_type *) sem_create_cstr();
931 	cstr_value->b_expr_opr = sym_k_coerce_op;
932 	cstr_value->az_exp_op1 = argvalue_value_entry;
933 	sem_evaluate_value_expr (cstr_value);
934 	argument_entry->az_arg_value = cstr_value;
935 	}
936     }
937 if (( expected_type == sym_k_compound_string_value ) &&
938     ( actual_type == sym_k_localized_string_value ))
939     {
940     valid_value = TRUE;
941     if ( (argvalue_value_entry->obj_header.b_flags & sym_m_private) != 0)
942 	{
943 	sym_value_entry_type   *cstr_value;
944 
945 	cstr_value = (sym_value_entry_type *) sem_create_cstr();
946 	cstr_value->b_expr_opr = sym_k_coerce_op;
947 	cstr_value->az_exp_op1 = argvalue_value_entry;
948 	sem_evaluate_value_expr (cstr_value);
949 	argument_entry->az_arg_value = cstr_value;
950 	}
951     }
952 if (( expected_type == sym_k_wchar_string_value ) &&
953     ( actual_type == sym_k_localized_string_value ))
954     {
955     valid_value = TRUE;
956     if ( (argvalue_value_entry->obj_header.b_flags & sym_m_private) != 0)
957 	{
958 	sym_value_entry_type   *wcstr_value;
959 
960 	wcstr_value = (sym_value_entry_type *) sem_create_wchar_str();
961 	wcstr_value->b_expr_opr = sym_k_coerce_op;
962 	wcstr_value->az_exp_op1 = argvalue_value_entry;
963 	sem_evaluate_value_expr (wcstr_value);
964 	argument_entry->az_arg_value = wcstr_value;
965 	}
966     }
967 if (( expected_type == sym_k_font_table_value ) &&
968     (( actual_type == sym_k_font_value ) ||
969      ( actual_type == sym_k_fontset_value )))
970     {
971     valid_value = TRUE;
972     if ( (argvalue_value_entry->obj_header.b_flags & sym_m_private) != 0)
973 	{
974         sym_value_entry_type	*font_table;
975 
976         font_table =
977 	    sem_create_value_entry
978 	        ((char*)&argvalue_value_entry, sizeof(long),
979 		 sym_k_font_table_value);
980         font_table->b_table_count = 1;
981         font_table->az_first_table_value = argvalue_value_entry;
982         font_table->b_expr_opr = sym_k_coerce_op;
983         font_table->az_exp_op1 = argvalue_value_entry;
984         font_table->b_aux_flags |= sym_m_exp_eval;
985         argument_entry->az_arg_value = sem_evaluate_value (font_table);
986 	}
987     }
988 if (( expected_type == sym_k_keysym_value ) &&
989     ( actual_type == sym_k_integer_value ))
990     {
991 /*
992  * If an integer is incountered when expecting a keysym then just make the
993  * integer into a keysym if the integer is private. If it isn't give an error
994  * message because Mrm won't be able to handle that problem.
995  * When allocating the space for c_value the size of the string is one since an
996  * integer can only be one character.
997  */
998     if ( (argvalue_value_entry->obj_header.b_flags & sym_m_private) != 0)
999 	{
1000 	char	   tmp;
1001 
1002 	valid_value = TRUE;
1003 	tmp = argument_entry->az_arg_value->value.l_integer;
1004 	argument_entry->az_arg_value->value.c_value = (char *) XtCalloc(1,2);
1005 	/*
1006 	 * This is a very strange move. While we Calloc 2 bytes we only need to move
1007 	 * one of those bytes. We calloc 2 bytes for a null termination so HP type
1008 	 * machines will work. It looks wierd but it works.
1009 	 */
1010 	_move (argument_entry->az_arg_value->value.c_value, &tmp, 1);
1011 	argument_entry->az_arg_value->b_type = sym_k_keysym_value;
1012 	argument_entry->az_arg_value->w_length = 1;
1013 	}
1014     }
1015 
1016 if ((( expected_type == sym_k_horizontal_integer_value ) ||
1017      ( expected_type == sym_k_vertical_integer_value ))
1018     &&
1019     (( actual_type == sym_k_integer_value) ||
1020      ( actual_type == sym_k_float_value)))
1021     {
1022 	/* If the expected type was either a horizontal or
1023 	   vertical integer and we got an integer, then simply make
1024 	   the actual type become the expected type. */
1025 	valid_value = TRUE;
1026 	argument_entry->az_arg_value->b_type = expected_type;
1027 	/* If the actual_type is a float then coerce it into
1028 	   being an integer */
1029 	if (actual_type == sym_k_float_value)
1030 	  argument_entry->az_arg_value->value.l_integer =
1031 	    (long) argument_entry->az_arg_value->value.d_real;
1032 	/* XmPIXELS currently has a value of 0 so the following
1033 	   isn't really necessary but I suppose it is more robust. */
1034 	if (argument_entry->az_arg_value->b_arg_type == 0)
1035 	  argument_entry->az_arg_value->b_arg_type = XmPIXELS;
1036     }
1037 
1038 if ((( expected_type == sym_k_horizontal_float_value ) ||
1039      ( expected_type == sym_k_vertical_float_value ))
1040     &&
1041     (( actual_type == sym_k_horizontal_integer_value ) ||
1042      ( actual_type == sym_k_vertical_integer_value )))
1043     {
1044 	/* If the expected type was either a horizontal or
1045 	   vertical float and we got a horizontal or
1046 	   vertical integer, then make the actual type become
1047 	   a horizontal or vertical integer, respectively. */
1048 	valid_value = TRUE;
1049 	if (expected_type == sym_k_horizontal_float_value)
1050 	  argument_entry->az_arg_value->b_type =
1051 	    sym_k_horizontal_integer_value;
1052 	else if (expected_type == sym_k_vertical_float_value)
1053 	  argument_entry->az_arg_value->b_type = sym_k_vertical_integer_value;
1054 	/* Coerce the value into being a float */
1055 	argument_entry->az_arg_value->value.d_real =
1056 	  (double) argument_entry->az_arg_value->value.l_integer;
1057 	/* XmPIXELS currently has a value of 0 so the following
1058 	   isn't really necessary but I suppose it is more robust. */
1059 	if (argument_entry->az_arg_value->b_arg_type == 0)
1060 	  argument_entry->az_arg_value->b_arg_type = XmPIXELS;
1061     }
1062 
1063 if ((( expected_type == sym_k_horizontal_integer_value ) ||
1064      ( expected_type == sym_k_vertical_integer_value ))
1065     &&
1066     (( actual_type == sym_k_horizontal_float_value ) ||
1067      ( actual_type == sym_k_vertical_float_value )))
1068     {
1069 	/* If the expected type was either a horizontal or
1070 	   vertical integer and we got a horizontal or vertical
1071 	   float, then make the actual type become a horizontal
1072 	   or vertical float, respectively. */
1073 	valid_value = TRUE;
1074 	if (expected_type == sym_k_horizontal_integer_value)
1075 	  argument_entry->az_arg_value->b_type = sym_k_horizontal_float_value;
1076 	else if (expected_type == sym_k_vertical_integer_value)
1077 	  argument_entry->az_arg_value->b_type = sym_k_vertical_float_value;
1078 	/* Coerce the value into being an integer */
1079 	argument_entry->az_arg_value->value.l_integer =
1080 	  (long) argument_entry->az_arg_value->value.d_real;
1081 	/* XmPIXELS currently has a value of 0 so the following
1082 	   isn't really necessary but I suppose it is more robust. */
1083 	if (argument_entry->az_arg_value->b_arg_type == 0)
1084 	  argument_entry->az_arg_value->b_arg_type = XmPIXELS;
1085     }
1086 
1087 if ((( expected_type == sym_k_horizontal_float_value ) ||
1088      ( expected_type == sym_k_vertical_float_value ))
1089     &&
1090     (( actual_type == sym_k_integer_value) ||
1091      ( actual_type == sym_k_float_value)))
1092     {
1093 	/* If the expected type was either a horizontal or
1094 	   vertical float and we got a float, then simply make
1095 	   the actual type become the expected type. */
1096 	valid_value = TRUE;
1097 	argument_entry->az_arg_value->b_type = expected_type;
1098 	/* If actual_type is an integer, then coerce into being
1099 	   a float */
1100 	if (actual_type == sym_k_integer_value)
1101 	  argument_entry->az_arg_value->value.d_real =
1102 	    (double) argument_entry->az_arg_value->value.l_integer;
1103 	/* XmPIXELS currently has a value of 0 so the following
1104 	   isn't really necessary but I suppose it is more robust. */
1105 	if (argument_entry->az_arg_value->b_arg_type == 0)
1106 	  argument_entry->az_arg_value->b_arg_type = XmPIXELS;
1107     }
1108 
1109 /* It is also possible for us to encounter a horizontal float or
1110    int when we are expecting a vertical float or int. When using
1111    'value' defined constants, we coerce the type of the constant
1112    the first time it is used. We have to be able to accept the
1113    coerced value in a different context later. */
1114 if ((( expected_type == sym_k_horizontal_float_value ) &&
1115      ( actual_type == sym_k_vertical_float_value ))
1116     ||
1117     (( expected_type == sym_k_horizontal_integer_value ) &&
1118      ( actual_type == sym_k_vertical_integer_value )))
1119 {
1120     /* Leave the actual type and value alone, but flag it as
1121        an acceptable value. This will mean that the first orientation
1122        the value is coerced to will be the orientation for all
1123        occurences of the value. */
1124     valid_value = TRUE;
1125 }
1126 
1127 if (!valid_value)
1128     diag_issue_diagnostic
1129 	(d_obj_type,
1130 	 _sar_source_pos2(argname_value_entry),
1131 	 diag_value_text(actual_type),
1132 	 diag_tag_text(actual_tag),
1133 	 diag_value_text(expected_type),
1134 	 diag_tag_text(sym_k_value_entry) );
1135 
1136 }
1137 
1138 
1139 
1140 /*
1141 **++
1142 **  FUNCTIONAL DESCRIPTION:
1143 **
1144 **      This routine performs enumeration set validation for a single
1145 **	argument entry. If it's value is an enumeration set reference,
1146 **	then we verify that the value comes from the argument's supported
1147 **	enumeration set.
1148 **
1149 **  FORMAL PARAMETERS:
1150 **
1151 **	argument_entry	the current argument entry
1152 **	arg_code	the sym_k_..._arg code for the argument
1153 **	arg_value_entry	the value node for the argument value
1154 **
1155 **  IMPLICIT INPUTS:
1156 **
1157 **  IMPLICIT OUTPUTS:
1158 **
1159 **  FUNCTION VALUE:
1160 **
1161 **      void
1162 **
1163 **  SIDE EFFECTS:
1164 **
1165 **      error reporting
1166 **
1167 **--
1168 **/
1169 
sem_validate_argument_enumset(argument_entry,arg_code,arg_value_entry)1170 void sem_validate_argument_enumset
1171 	(argument_entry, arg_code, arg_value_entry)
1172     sym_argument_entry_type		*argument_entry;
1173     int					arg_code;
1174     sym_value_entry_type		*arg_value_entry;
1175 
1176 {
1177 
1178 /*
1179  * Local variables
1180  */
1181 unsigned short int	enumval_code;
1182 unsigned short int	enumset_code;
1183 int			ndx;
1184 
1185 
1186 /*
1187  * No action if value is not an integer enumeration value. Else:
1188  *	- argument must support enumeration set
1189  *	- value must be from set
1190  */
1191 if ( arg_value_entry == NULL ) return;
1192 if ((arg_value_entry->b_type != sym_k_integer_value) &&
1193     (arg_value_entry->b_type != sym_k_bool_value)) return;
1194 enumval_code = arg_value_entry->b_enumeration_value_code;
1195 if ( enumval_code == 0 ) return;
1196 enumset_code = argument_enumset_table[arg_code];
1197 if ( enumset_code == 0 )
1198   {
1199     if (arg_value_entry->b_type != sym_k_bool_value)
1200       diag_issue_diagnostic(d_no_enumset,
1201 			    _sar_source_pos2(argument_entry),
1202 			    uil_argument_names[arg_code]);
1203     return;
1204   }
1205 for ( ndx=0 ; ndx<enum_set_table[enumset_code].values_cnt ; ndx++ )
1206     if ( enum_set_table[enumset_code].values[ndx] == enumval_code ) return;
1207 diag_issue_diagnostic (d_invalid_enumval,
1208 		       _sar_source_pos2(argument_entry),
1209 		       uil_argument_names[arg_code],
1210 		       uil_enumval_names[enumval_code]);
1211 return;
1212 
1213 }
1214 
1215 
1216 
1217 /*
1218 **++
1219 **  FUNCTIONAL DESCRIPTION:
1220 **
1221 **      This routine validates a constraint entry. It checks to make
1222 **	sure that the constraint reference is valid in each of the
1223 **	parents of the widget using the constraint
1224 **
1225 **  FORMAL PARAMETERS:
1226 **
1227 **      widget_node	the widget using the constraint
1228 **	argument_entry	the constraint argument
1229 **
1230 **  IMPLICIT INPUTS:
1231 **
1232 **      >
1233 **
1234 **  IMPLICIT OUTPUTS:
1235 **
1236 **  FUNCTION VALUE:
1237 **
1238 **      void
1239 **
1240 **  SIDE EFFECTS:
1241 **
1242 **      error reporting
1243 **
1244 **--
1245 **/
1246 
sem_validate_constraint_entry(widget_node,argument_entry,widget_type)1247 void sem_validate_constraint_entry (widget_node, argument_entry, widget_type)
1248     sym_widget_entry_type		*widget_node;
1249     sym_argument_entry_type		*argument_entry;
1250     unsigned int			widget_type;
1251 {
1252 
1253 /*
1254  * Local variables
1255  */
1256 sym_parent_list_type		*parent_entry;
1257 sym_widget_entry_type		*parent_object;
1258 unsigned int			parent_type;
1259 unsigned int			parent_tag;
1260 key_keytable_entry_type		*keytable_entry;
1261 sym_value_entry_type		*arg_name_entry;
1262 boolean				supported_flag;
1263 
1264 
1265 /*
1266  * Validate the constraint with each of the referencing widget's parents
1267  */
1268 for (parent_entry=widget_node->parent_list;
1269      parent_entry!=NULL;
1270      parent_entry=parent_entry->next)
1271     {
1272 
1273     /*
1274      * Acquire the parent object and its type
1275      */
1276     parent_object = parent_entry->parent;
1277     parent_type = parent_object->header.b_type;
1278     if ( parent_object->obj_header.b_flags & sym_m_obj_is_gadget )
1279 	{
1280 	parent_tag = sym_k_gadget_entry;
1281 	}
1282     else
1283 	{
1284 	parent_tag = sym_k_widget_entry;
1285 	}
1286 
1287     /*
1288      * Acquire the appropriate pointers, and validate the reference
1289      */
1290     arg_name_entry = (sym_value_entry_type *)argument_entry->az_arg_name;
1291     keytable_entry = (key_keytable_entry_type *)arg_name_entry->value.az_data;
1292     supported_flag = sem_argument_allowed(keytable_entry->b_subclass,
1293 					  parent_type);
1294     if (!supported_flag)
1295       {
1296 	/* Check for both argument and constraint, e.g. decimalPoints. */
1297 	supported_flag = sem_argument_allowed(keytable_entry->b_subclass,
1298 					      widget_type);
1299 	if (!supported_flag)
1300 	  diag_issue_diagnostic(d_unsupp_const,
1301 				_sar_source_pos2(argument_entry),
1302 				keytable_entry->at_name,
1303 				diag_object_text(parent_type),
1304 				diag_tag_text(parent_tag));
1305       }
1306   }
1307 
1308 /*
1309  * Checks on nodes pointed to by this node
1310  *
1311  * There is no need to validate the value if it is a widget since widgets are
1312  * validated elsewhere and you can't define widgets in an argument list anyway.
1313  */
1314 
1315 if ((argument_entry->az_arg_value->header.b_tag != sym_k_widget_entry) &&
1316     (argument_entry->az_arg_value->header.b_tag != sym_k_gadget_entry))
1317     sem_validate_node (( sym_entry_type *)argument_entry->az_arg_value);
1318 
1319 }
1320 
1321 
1322 
1323 /*
1324 **++
1325 **  FUNCTIONAL DESCRIPTION:
1326 **
1327 **      This routine validates all the callbacks in an callback list.
1328 **	It recurse down nested lists.
1329 **
1330 **  FORMAL PARAMETERS:
1331 **
1332 **      widget_node	the current widget
1333 **	widget_type	the current widget's type
1334 **	list_entry	list to be validated
1335 **	seen  	        flag table to detect duplicate callbacks
1336 **
1337 **  IMPLICIT INPUTS:
1338 **
1339 **  IMPLICIT OUTPUTS:
1340 **
1341 **  FUNCTION VALUE:
1342 **
1343 **  SIDE EFFECTS:
1344 **
1345 **--
1346 **/
1347 
sem_validate_callback_list(widget_node,widget_type,list_entry,seen)1348 void sem_validate_callback_list	(widget_node, widget_type, list_entry, seen)
1349     sym_widget_entry_type		*widget_node;
1350     unsigned int			widget_type;
1351     sym_list_entry_type			*list_entry;
1352     sym_callback_entry_type		**seen;
1353 
1354 {
1355 
1356 /*
1357  * Local variables
1358  */
1359 sym_obj_entry_type		*list_member;
1360 sym_nested_list_entry_type	*nested_list_entry;
1361 sym_callback_entry_type		*callback_entry;
1362 
1363 
1364 /*
1365  * loop down the list
1366  */
1367 if ( list_entry == NULL ) return;
1368 for (list_member=(sym_obj_entry_type *)list_entry->obj_header.az_next;
1369      list_member!=NULL;
1370      list_member=(sym_obj_entry_type *)list_member->obj_header.az_next)
1371     switch ( list_member->header.b_tag )
1372 	{
1373 	case sym_k_nested_list_entry:
1374 	    nested_list_entry = (sym_nested_list_entry_type *) list_member;
1375 	    sem_validate_callback_list (widget_node, widget_type,
1376 					nested_list_entry->az_list, seen);
1377 	    break;
1378 	case sym_k_callback_entry:
1379 	    callback_entry = (sym_callback_entry_type *) list_member;
1380 	    sem_validate_callback_entry	(widget_node, widget_type,
1381 					 list_entry, callback_entry, seen);
1382 	    break;
1383 	default:
1384 	    diag_issue_diagnostic
1385 	        ( d_list_item,
1386 	          _sar_source_pos2 ( list_entry ),
1387 	          diag_tag_text (sym_k_callback_entry),
1388 	          diag_tag_text (list_entry->header.b_type),
1389 	          diag_tag_text (list_entry->header.b_tag) );
1390 	}
1391 
1392 }
1393 
1394 
1395 
1396 /*
1397 **++
1398 **  FUNCTIONAL DESCRIPTION:
1399 **
1400 **      This routine performs validation for a single callback entry
1401 **	for the current widget node.
1402 **
1403 **  FORMAL PARAMETERS:
1404 **
1405 **      widget_node	the current widget
1406 **	widget_type	the current widget's type
1407 **	list_entry	list entry for current callback entry
1408 **	callback_entry	the current callback entry
1409 **	seen 	 	flag table to detect duplicate callbacks
1410 **
1411 **  IMPLICIT INPUTS:
1412 **
1413 **  IMPLICIT OUTPUTS:
1414 **
1415 **  FUNCTION VALUE:
1416 **
1417 **      void
1418 **
1419 **  SIDE EFFECTS:
1420 **
1421 **      error reporting
1422 **
1423 **--
1424 **/
1425 
sem_validate_callback_entry(widget_node,widget_type,list_entry,callback_entry,seen)1426 void sem_validate_callback_entry
1427 	(widget_node, widget_type, list_entry, callback_entry, seen)
1428     sym_widget_entry_type		*widget_node;
1429     unsigned int			widget_type;
1430     sym_list_entry_type			*list_entry;
1431     sym_callback_entry_type		*callback_entry;
1432     sym_callback_entry_type		**seen;
1433 
1434 {
1435 
1436 /*
1437  * Local variables
1438  */
1439 sym_value_entry_type		*reason_value_entry;
1440 key_keytable_entry_type		*keytable_entry;
1441 sym_callback_entry_type		**seen_entry;
1442 boolean				supported_flag;
1443 static sym_value_entry_type     *widget_az_arg_value = NULL;
1444 
1445 
1446 /*
1447  * ignore error entries, consistency check
1448  */
1449 if ( callback_entry->header.b_tag == sym_k_error_entry ) return;
1450 _assert (callback_entry->header.b_tag==sym_k_callback_entry,
1451 	 "unexpected non callback entry");
1452 
1453 reason_value_entry = (sym_value_entry_type *)
1454     callback_entry->az_call_reason_name;
1455 
1456 /*
1457  * Force expression evaluation
1458  */
1459 sem_evaluate_value_expr (reason_value_entry);
1460 
1461 if (reason_value_entry == NULL)
1462     return;
1463 
1464 _assert (reason_value_entry->header.b_tag == sym_k_value_entry,
1465 	 "reason value entry missing");
1466 
1467 if (reason_value_entry->b_type != sym_k_reason_value) {
1468     diag_issue_diagnostic
1469 	( d_list_item,
1470 	  _sar_source_pos2 ( reason_value_entry ),
1471 	  diag_value_text (reason_value_entry->b_type),
1472 	  diag_tag_text (list_entry->header.b_type),
1473 	  diag_tag_text (list_entry->header.b_tag) );
1474     return;
1475     }
1476 
1477 /*
1478  * Check for unsupported callbacks.
1479  * This check is required for known toolkit callbacks in
1480  * toolkit widgets.
1481  */
1482 if ( (reason_value_entry->obj_header.b_flags&sym_m_builtin) &&
1483      (widget_type!=uil_sym_user_defined_object) )
1484     {
1485     /*
1486      * Pick up the token keytable entry for the callback.
1487      * Validate that the reason is supported
1488      */
1489     keytable_entry = (key_keytable_entry_type *)
1490 	reason_value_entry->value.az_data;
1491     _assert (keytable_entry->b_class==tkn_k_class_reason,
1492 	     "unexpected non-reason keytable entry");
1493     supported_flag = sem_reason_allowed
1494 	(keytable_entry->b_subclass, widget_type);
1495     if ( ! supported_flag )
1496 	diag_issue_diagnostic
1497 	    (d_unsupported,
1498 	     _sar_source_pos2(callback_entry),
1499 	     keytable_entry->at_name,
1500 	     diag_tag_text(callback_entry->header.b_tag),
1501 	     diag_object_text(widget_type));
1502 
1503     /*
1504      * Check for duplicate callbacks. A warning is issued, but the
1505      * callback is not removed from the list, since it may occur in
1506      * an callback list - and the callback list may be referenced in
1507      * another context where this callback is not duplicated.
1508      */
1509     seen_entry = (sym_callback_entry_type **)
1510 	&seen[keytable_entry->b_subclass];
1511     if ( *seen_entry != NULL )
1512 	{
1513 	diag_issue_diagnostic
1514 	    (d_supersede,
1515 	     _sar_source_pos2(callback_entry),
1516 	     keytable_entry->at_name,
1517 	     diag_tag_text(callback_entry->header.b_tag),
1518 	     diag_tag_text(list_entry->header.b_type),
1519 	     diag_tag_text(list_entry->header.b_tag));
1520 	}
1521     else
1522 	{
1523 	*seen_entry = callback_entry;
1524 	}
1525     }
1526 
1527 /*
1528  * Checks on nodes pointed to by this node
1529  */
1530     /* Begin fixing DTS 10391 and OSF CR 8715*/
1531     if(callback_entry->az_call_proc_ref &&
1532       callback_entry->az_call_proc_ref->az_arg_value &&
1533       (callback_entry->az_call_proc_ref->az_arg_value->header.b_tag
1534         == sym_k_widget_entry ||
1535         callback_entry->az_call_proc_ref->az_arg_value->header.b_tag
1536         == sym_k_gadget_entry) &&
1537         widget_az_arg_value == callback_entry->az_call_proc_ref->az_arg_value){
1538            diag_issue_diagnostic
1539                         (d_circular_def,
1540                         _sar_source_pos2(callback_entry),
1541                         "callback client_data");
1542     }else{
1543         if(callback_entry->az_call_proc_ref &&
1544         callback_entry->az_call_proc_ref->az_arg_value &&
1545         (callback_entry->az_call_proc_ref->az_arg_value->header.b_tag
1546            == sym_k_widget_entry ||
1547            callback_entry->az_call_proc_ref->az_arg_value->header.b_tag
1548            == sym_k_gadget_entry) && !widget_az_arg_value)
1549 	      widget_az_arg_value = callback_entry->az_call_proc_ref->az_arg_value;
1550 	sem_validate_procref_entry (callback_entry->az_call_proc_ref);
1551 	sem_validate_procref_list (callback_entry->az_call_proc_ref_list);
1552      }
1553     widget_az_arg_value = NULL;
1554     /* End fixing DTS 10391 and OSF CR 8715*/
1555 }
1556 
1557 
1558 
1559 /*
1560 **++
1561 **  FUNCTIONAL DESCRIPTION:
1562 **
1563 **      This routine validates all the controls in an control list.
1564 **	It recurse down nested lists.
1565 **
1566 **  FORMAL PARAMETERS:
1567 **
1568 **      widget_node	the current widget
1569 **	widget_type	the current widget's type
1570 **	list_entry	list to be validated
1571 **	count		to return gadget count
1572 **
1573 **  IMPLICIT INPUTS:
1574 **
1575 **  IMPLICIT OUTPUTS:
1576 **
1577 **  FUNCTION VALUE:
1578 **
1579 **  SIDE EFFECTS:
1580 **
1581 **--
1582 **/
1583 
sem_validate_control_list(widget_node,widget_type,list_entry,count)1584 void sem_validate_control_list (widget_node, widget_type, list_entry, count)
1585     sym_widget_entry_type		*widget_node;
1586     unsigned int			widget_type;
1587     sym_list_entry_type			*list_entry;
1588     int					*count;
1589 
1590 {
1591 
1592 /*
1593  * Local variables
1594  */
1595 sym_obj_entry_type		*list_member;
1596 sym_nested_list_entry_type	*nested_list_entry;
1597 sym_control_entry_type		*control_entry;
1598 
1599 
1600 /*
1601  * loop down the list
1602  */
1603 if ( list_entry == NULL ) return;
1604 for (list_member=(sym_obj_entry_type *)list_entry->obj_header.az_next;
1605      list_member!=NULL;
1606      list_member=(sym_obj_entry_type *)list_member->obj_header.az_next)
1607     switch ( list_member->header.b_tag )
1608 	{
1609 	case sym_k_nested_list_entry:
1610 	    nested_list_entry = (sym_nested_list_entry_type *) list_member;
1611 	    sem_validate_control_list
1612 		(widget_node, widget_type, nested_list_entry->az_list, count);
1613 	    break;
1614 	case sym_k_control_entry:
1615 	    control_entry = (sym_control_entry_type *) list_member;
1616 	    sem_validate_control_entry
1617 		(widget_node, widget_type, list_entry, control_entry, count);
1618 	    break;
1619 	}
1620 
1621 }
1622 
1623 
1624 
1625 /*
1626 **++
1627 **  FUNCTIONAL DESCRIPTION:
1628 **
1629 **      This routine performs validation for a single control entry
1630 **	for the current widget node.
1631 **
1632 **  FORMAL PARAMETERS:
1633 **
1634 **      widget_node	the current widget
1635 **	widget_type	the current widget's type
1636 **	list_entry	list entry for current control entry
1637 **	control_entry	the current control entry
1638 **	gadget_count	to accumulate count of controlled gadgets
1639 **
1640 **  IMPLICIT INPUTS:
1641 **
1642 **  IMPLICIT OUTPUTS:
1643 **
1644 **  FUNCTION VALUE:
1645 **
1646 **      void
1647 **
1648 **  SIDE EFFECTS:
1649 **
1650 **      error reporting
1651 **
1652 **--
1653 **/
1654 
sem_validate_control_entry(widget_node,widget_type,list_entry,control_entry,gadget_count)1655 void sem_validate_control_entry
1656 	(widget_node, widget_type, list_entry, control_entry, gadget_count)
1657     sym_widget_entry_type		*widget_node;
1658     unsigned int			widget_type;
1659     sym_list_entry_type			*list_entry;
1660     sym_control_entry_type		*control_entry;
1661     int					*gadget_count;
1662 
1663 {
1664 
1665 /*
1666  * Local variables
1667  */
1668 sym_widget_entry_type		*control_obj_entry;
1669 boolean				supported_flag;
1670 
1671 
1672 /*
1673  * ignore error entries, consistency check
1674  */
1675 if ( control_entry->header.b_tag == sym_k_error_entry ) return;
1676 _assert (control_entry->header.b_tag==sym_k_control_entry,
1677 	 "unexpected non control entry");
1678 
1679 /*
1680  * Similar checks for the object being controlled
1681  */
1682 control_obj_entry = (sym_widget_entry_type *) control_entry->az_con_obj;
1683 if ( control_obj_entry->header.b_tag == sym_k_error_entry )
1684     {
1685     control_entry->header.b_tag = sym_k_error_entry;
1686     return;
1687     }
1688 _assert (control_obj_entry->header.b_tag==sym_k_widget_entry ||
1689 	 control_obj_entry->header.b_tag==sym_k_gadget_entry ||
1690 	 control_obj_entry->header.b_tag==sym_k_child_entry,
1691 	 "unexpected non-control object entry");
1692 
1693 if ( control_obj_entry->header.b_tag == sym_k_gadget_entry )
1694     *gadget_count += 1;
1695 
1696 /*
1697  * Check for unsupported controls or automatic children.
1698  */
1699 if (control_obj_entry->header.b_tag == sym_k_child_entry)
1700   {
1701     supported_flag =
1702       sem_child_allowed(control_obj_entry->header.b_type, widget_type);
1703     if ( ! supported_flag )
1704       diag_issue_diagnostic
1705 	(d_unsupported,
1706 	 _sar_source_pos2(control_entry),
1707 	 uil_child_names[(int)control_obj_entry->header.b_type],
1708 	 "automatic child",
1709 	 diag_object_text(widget_type));
1710   }
1711 else
1712   {
1713     supported_flag =
1714       sem_control_allowed(control_obj_entry->header.b_type, widget_type);
1715     if ( ! supported_flag )
1716       diag_issue_diagnostic
1717 	(d_unsupported,
1718 	 _sar_source_pos2(control_entry),
1719 	 diag_object_text(control_obj_entry->header.b_type),
1720 	 diag_tag_text(control_entry->header.b_tag),
1721 	 diag_object_text(widget_type));
1722   }
1723 
1724 }
1725 
1726 
1727 
1728 /*
1729 **++
1730 **  FUNCTIONAL DESCRIPTION:
1731 **
1732 **      This routine recursively checks for cycles in a widget hierarchy.
1733 **	A cycle is defined as the appearance of a widget's name in its
1734 **	subtree hierarchy. A cycle is detected by setting a unique id
1735 **	for this cycle check in each name entry encountered. If this id
1736 **	is ever encountered again, there is a cycle.
1737 **
1738 **	This is the root routine of the recursion, which is responsible
1739 **	for setting flags in the name entry.
1740 **
1741 **  FORMAL PARAMETERS:
1742 **
1743 **	list_entry	list to be validated
1744 **	cycle_name	if non-NULL, a widget name for cycle check
1745 **
1746 **  IMPLICIT INPUTS:
1747 **
1748 **  IMPLICIT OUTPUTS:
1749 **
1750 **  FUNCTION VALUE:
1751 **
1752 **  SIDE EFFECTS:
1753 **
1754 **--
1755 **/
1756 
sem_validate_widget_cycle(list_entry,cycle_name)1757 void sem_validate_widget_cycle (list_entry, cycle_name)
1758     sym_list_entry_type			*list_entry;
1759     sym_name_entry_type			*cycle_name;
1760 
1761 {
1762 
1763 /*
1764  * Local variables
1765  */
1766 boolean				cycle_res;
1767 
1768 
1769 /*
1770  * Acquire a new cycle id value.Call the auxiliary recursion routine,
1771  * and set results in the name entry.
1772  */
1773 if ( cycle_name == NULL ) return;
1774 cycle_id += 1;
1775 cycle_name->az_cycle_id = cycle_id;
1776 cycle_res = sem_validate_widget_cycle_aux (list_entry, cycle_name);
1777 cycle_name->b_flags |= sym_m_cycle_checked;
1778 if ( cycle_res )
1779     cycle_name->b_flags |= sym_m_has_cycle;
1780 
1781 }
1782 
1783 
1784 
1785 /*
1786 **++
1787 **  FUNCTIONAL DESCRIPTION:
1788 **
1789 **      This routine recursively checks for cycles in a widget hierarchy.
1790 **	A cycle is defined as the appearance of a widget's name in its
1791 **	subtree hierarchy. This is the fully recursive auxiliary for
1792 **	sem_validate_widget_cycle
1793 **
1794 **	Checking is based on the fact that for any named widget, its
1795 **	subtree definition is fixed and can be checked exactly once. Once
1796 **	checked, it is marked as checked, and also flagged if it contains
1797 **	a cycle. Since any tree containing a subtree which has a cycle also
1798 **	has a cycle, checking stops immediately if such a subtree is detected,
1799 **	and subtrees must always be (recursively) checked in advance of
1800 **	the current check.
1801 **
1802 **  FORMAL PARAMETERS:
1803 **
1804 **	list_entry	list to be validated
1805 **	cycle_name	if non-NULL, a widget name for cycle check
1806 **
1807 **  IMPLICIT INPUTS:
1808 **
1809 **  IMPLICIT OUTPUTS:
1810 **
1811 **  FUNCTION VALUE:
1812 **			TRUE	cycle detected
1813 **			FALSE	no cycle detected
1814 **
1815 **  SIDE EFFECTS:
1816 **
1817 **--
1818 **/
1819 
sem_validate_widget_cycle_aux(list_entry,cycle_name)1820 boolean sem_validate_widget_cycle_aux (list_entry, cycle_name)
1821     sym_list_entry_type			*list_entry;
1822     sym_name_entry_type			*cycle_name;
1823 
1824 {
1825 
1826 /*
1827  * Local variables
1828  */
1829 sym_obj_entry_type		*list_member;
1830 sym_nested_list_entry_type	*nested_list_entry;
1831 sym_control_entry_type		*control_entry;
1832 sym_widget_entry_type		*control_obj_entry;
1833 sym_name_entry_type		*control_obj_name;
1834 
1835 
1836 /*
1837  * loop down the list. Check for cycles in each leaf (widget) node. Note
1838  * we must step through the az_reference for named widgets. If a cycle is
1839  * ever detected, we exit (or we'll recurse forever). Note that an error
1840  * node returns TRUE, as if it had a cycle (which inhibits further checking).
1841  *
1842  * If we encounter a previously visited node, we may have either a cycle
1843  * or a legitimate multiple reference. Verify that it is a cycle, and
1844  * issue an error message if so. If it is not verified, it need not be
1845  * checked again.
1846  */
1847 if ( list_entry == NULL ) return FALSE;
1848 if ( cycle_name == NULL ) return FALSE;
1849 if ( cycle_name->b_flags & sym_m_cycle_checked )
1850     return (cycle_name->b_flags&sym_m_has_cycle) == 1;
1851 
1852 for (list_member=(sym_obj_entry_type *)list_entry->obj_header.az_next;
1853      list_member!=NULL;
1854      list_member=(sym_obj_entry_type *)list_member->obj_header.az_next)
1855     switch ( list_member->header.b_tag )
1856 	{
1857 	case sym_k_nested_list_entry:
1858 	    nested_list_entry = (sym_nested_list_entry_type *) list_member;
1859 	    if ( sem_validate_widget_cycle_aux
1860 		     (nested_list_entry->az_list, cycle_name) )
1861 		return TRUE;
1862 	    break;
1863 	case sym_k_control_entry:
1864 	    control_entry = (sym_control_entry_type *) list_member;
1865 	    control_obj_entry =
1866 		(sym_widget_entry_type *) control_entry->az_con_obj;
1867 	    if ( control_obj_entry->header.b_tag == sym_k_error_entry )
1868 		return TRUE;
1869 	    _assert (control_obj_entry->header.b_tag==sym_k_widget_entry ||
1870 		     control_obj_entry->header.b_tag==sym_k_gadget_entry ||
1871 		     control_obj_entry->header.b_tag==sym_k_child_entry,
1872 		     "unexpected non-control object entry");
1873 	    if ( control_obj_entry->obj_header.az_reference != NULL )
1874 		control_obj_entry = (sym_widget_entry_type *)
1875 		    control_obj_entry->obj_header.az_reference;
1876 	    if ( control_obj_entry->az_controls == NULL )
1877 		break;
1878 	    control_obj_name = control_obj_entry->obj_header.az_name;
1879 	    if ( control_obj_name != NULL )
1880 		{
1881 		if ( control_obj_name->az_cycle_id == cycle_id )
1882 		    {
1883 		    if ( sem_validate_verify_cycle
1884 			     (control_obj_entry,
1885 			      control_obj_entry->az_controls) )
1886 			{
1887 			diag_issue_diagnostic
1888 			    (d_widget_cycle,
1889 			     _sar_source_pos2(control_entry),
1890 			     control_obj_name->c_text);
1891 			control_obj_name->b_flags |= sym_m_cycle_checked;
1892 			control_obj_name->b_flags |= sym_m_has_cycle;
1893 			return TRUE;
1894 			}
1895 		    else
1896 			{
1897 			control_obj_name->b_flags |= sym_m_cycle_checked;
1898 			break;
1899 			}
1900 		    }
1901 		control_obj_name->az_cycle_id = cycle_id;
1902 		}
1903 	    if ( sem_validate_widget_cycle_aux
1904 		(control_obj_entry->az_controls, cycle_name) )
1905 		return TRUE;
1906 	    break;
1907 	}
1908 return FALSE;
1909 
1910 }
1911 
1912 
1913 
1914 /*
1915 **++
1916 **  FUNCTIONAL DESCRIPTION:
1917 **
1918 **	This routine verifies that a cycle found by widget_cycle_aux is
1919 **	really a cycle. widget_cycle_aux may have detected a legitimate
1920 **	multiple appearance of a widget in a hierarchy which is not a cycle.
1921 **	This routine uses a pointer-marching technique to see if the given
1922 **	node is in a real cycle. If the cycle_obj is ever encountered in
1923 **	the pointer march, then there is a cycle. Otherwise, the march
1924 **	terminates.
1925 **
1926 **
1927 **  FORMAL PARAMETERS:
1928 **
1929 **	cycle_obj	object to be found in cycle
1930 **	list_entry	current controls list
1931 **
1932 **  IMPLICIT INPUTS:
1933 **
1934 **  IMPLICIT OUTPUTS:
1935 **
1936 **  FUNCTION VALUE:
1937 **			TRUE	cycle detected
1938 **			FALSE	no cycle detected
1939 **
1940 **  SIDE EFFECTS:
1941 **
1942 **--
1943 **/
1944 
sem_validate_verify_cycle(cycle_obj,list_entry)1945 boolean sem_validate_verify_cycle (cycle_obj, list_entry)
1946     sym_widget_entry_type		*cycle_obj;
1947     sym_list_entry_type			*list_entry;
1948 
1949 {
1950 
1951 /*
1952  * Local variables
1953  */
1954 sym_obj_entry_type		*list_member;
1955 sym_nested_list_entry_type	*nested_list_entry;
1956 sym_control_entry_type		*control_entry;
1957 sym_widget_entry_type		*control_obj_entry;
1958 
1959 
1960 /*
1961  * Search all objects in the controls list, and recurse.
1962  * objects controlled by the current object.
1963  */
1964 if ( list_entry == NULL )
1965     return FALSE;
1966 for (list_member=(sym_obj_entry_type *)list_entry->obj_header.az_next;
1967      list_member!=NULL;
1968      list_member=(sym_obj_entry_type *)list_member->obj_header.az_next)
1969     switch ( list_member->header.b_tag )
1970 	{
1971 	case sym_k_nested_list_entry:
1972 	    nested_list_entry = (sym_nested_list_entry_type *) list_member;
1973 	    if ( sem_validate_verify_cycle
1974 		     (cycle_obj, nested_list_entry->az_list) )
1975 		return TRUE;
1976 	    break;
1977 	case sym_k_control_entry:
1978 	    control_entry = (sym_control_entry_type *) list_member;
1979 	    control_obj_entry =
1980 		(sym_widget_entry_type *) control_entry->az_con_obj;
1981 	    if ( control_obj_entry->obj_header.az_reference != NULL )
1982 		control_obj_entry = (sym_widget_entry_type *)
1983 		    control_obj_entry->obj_header.az_reference;
1984 	    if ( control_obj_entry == cycle_obj )
1985 		return TRUE;
1986 	    if ( control_obj_entry->az_controls == NULL )
1987 		break;
1988 	    if ( sem_validate_verify_cycle
1989 		     (cycle_obj, control_obj_entry->az_controls) )
1990 		return TRUE;
1991 	    break;
1992 	}
1993 return FALSE;
1994 
1995 }
1996 
1997 
1998 
1999 /*
2000 **++
2001 **  FUNCTIONAL DESCRIPTION:
2002 **
2003 **      This routine validates all the procrefs in an procref list.
2004 **	It recurses down nested lists.
2005 **
2006 **  FORMAL PARAMETERS:
2007 **
2008 **	list_entry	list to be validated
2009 **
2010 **  IMPLICIT INPUTS:
2011 **
2012 **  IMPLICIT OUTPUTS:
2013 **
2014 **  FUNCTION VALUE:
2015 **
2016 **  SIDE EFFECTS:
2017 **
2018 **--
2019 **/
2020 
sem_validate_procref_list(list_entry)2021 void sem_validate_procref_list (list_entry)
2022     sym_list_entry_type			*list_entry;
2023 
2024 {
2025 
2026 /*
2027  * Local variables
2028  */
2029 sym_obj_entry_type		*list_member;
2030 sym_nested_list_entry_type	*nested_list_entry;
2031 sym_proc_ref_entry_type		*procref_entry;
2032 
2033 
2034 /*
2035  * loop down the list
2036  */
2037 if ( list_entry == NULL ) return;
2038 for (list_member=(sym_obj_entry_type *)list_entry->obj_header.az_next;
2039      list_member!=NULL;
2040      list_member=(sym_obj_entry_type *)list_member->obj_header.az_next)
2041     switch ( list_member->header.b_tag )
2042 	{
2043 	case sym_k_nested_list_entry:
2044 	    nested_list_entry = (sym_nested_list_entry_type *) list_member;
2045 	    sem_validate_procref_list (nested_list_entry->az_list);
2046 	    break;
2047 	case sym_k_proc_ref_entry:
2048 	    procref_entry = (sym_proc_ref_entry_type *) list_member;
2049 	    sem_validate_procref_entry (procref_entry);
2050 	    break;
2051 	}
2052 
2053 }
2054 
2055 
2056 
2057 /*
2058 **++
2059 **  FUNCTIONAL DESCRIPTION:
2060 **
2061 **      This routine performs validation for a single procref entry.
2062 **
2063 **  FORMAL PARAMETERS:
2064 **
2065 **	procref_entry	the current procref entry
2066 **
2067 **  IMPLICIT INPUTS:
2068 **
2069 **  IMPLICIT OUTPUTS:
2070 **
2071 **  FUNCTION VALUE:
2072 **
2073 **      void
2074 **
2075 **  SIDE EFFECTS:
2076 **
2077 **      error reporting
2078 **
2079 **--
2080 **/
2081 
sem_validate_procref_entry(procref_entry)2082 void sem_validate_procref_entry (procref_entry)
2083     sym_proc_ref_entry_type		*procref_entry;
2084 
2085 {
2086 
2087 /*
2088  * Local variables
2089  */
2090 sym_value_entry_type    	*value_entry;
2091 sym_proc_def_entry_type 	*proc_def_entry;
2092 int			    	actual_arg_count;
2093 int			    	expected_arg_type;
2094 int			    	actual_arg_type;
2095 int			    	arg_checking;
2096 
2097 
2098 /*
2099  * ignore error entries, consistency check
2100  */
2101 if ( procref_entry == NULL ) return;
2102 if ( procref_entry->header.b_tag == sym_k_error_entry ) return;
2103 _assert (procref_entry->header.b_tag==sym_k_proc_ref_entry,
2104 	 "unexpected non procref entry");
2105 
2106 
2107     /*
2108     ** Validate procedure reference argument:
2109     **	Correct number of args
2110     **	Correct datatype of arg - coerce if necessary
2111     */
2112 
2113     proc_def_entry = procref_entry->az_proc_def;
2114     /* Could be NULL due to previous compilation errors. */
2115     if (proc_def_entry == NULL) return;
2116 
2117     /*
2118     **	if checking is required, check that the values
2119     **	agree with the parameters
2120     */
2121 
2122     arg_checking = proc_def_entry->v_arg_checking;
2123 
2124     value_entry = procref_entry->az_arg_value;
2125 
2126     if (arg_checking)
2127     {
2128 	boolean	    valid_arg;
2129 
2130         if (value_entry == NULL)
2131 	    {
2132 	    actual_arg_count = 0;
2133 	    actual_arg_type = sym_k_no_value;
2134 	    }
2135         else
2136 	    {
2137             sem_evaluate_value_expr(value_entry);
2138 	    actual_arg_count = 1;
2139 	    actual_arg_type = value_entry->b_type;
2140 	    }
2141 
2142 	if (actual_arg_count != proc_def_entry->b_arg_count)
2143 	{
2144 	    diag_issue_diagnostic
2145 		( d_arg_count,
2146 		  _sar_source_pos2 (procref_entry),
2147 		  proc_def_entry->obj_header.az_name->c_text,
2148 		  proc_def_entry->b_arg_count );
2149 
2150 	    return;
2151 	}
2152 
2153 	expected_arg_type = proc_def_entry->b_arg_type;
2154 	valid_arg = (actual_arg_type == expected_arg_type);
2155 
2156 	if ( expected_arg_type == sym_k_any_value )
2157 	    valid_arg = TRUE;
2158 
2159 	if ( actual_arg_type == sym_k_identifier_value )
2160 	    valid_arg = TRUE;
2161 
2162 	if (( expected_arg_type == sym_k_pixmap_value ) &&
2163 	    ( actual_arg_type == sym_k_icon_value ))
2164 	    valid_arg = TRUE;
2165 
2166 	if (( expected_arg_type == sym_k_color_value) &&/* RAP rgb data type */
2167 	    ( actual_arg_type == sym_k_rgb_value))
2168 	  valid_arg = TRUE;
2169 
2170 	if ((expected_arg_type == sym_k_char_8_value) &&
2171 	    (actual_arg_type == sym_k_localized_string_value))
2172 	  valid_arg = TRUE;
2173 
2174 	if (( expected_arg_type == sym_k_compound_string_value ) &&
2175 	    ( actual_arg_type == sym_k_char_8_value ))
2176 	{
2177 	    valid_arg = TRUE;
2178 	    if ( (value_entry->obj_header.b_flags & sym_m_private) != 0)
2179 	    {
2180 		sym_value_entry_type   *cstr_value;
2181 
2182 		cstr_value = (sym_value_entry_type *) sem_create_cstr();
2183 		cstr_value->b_expr_opr = sym_k_coerce_op;
2184 		cstr_value->az_exp_op1 = value_entry;
2185 		sem_evaluate_value_expr (cstr_value);
2186 	    }
2187 	}
2188 
2189 	if (( expected_arg_type == sym_k_compound_string_value ) &&
2190 	    ( actual_arg_type == sym_k_localized_string_value ))
2191 	{
2192 	    valid_arg = TRUE;
2193 	    if ( (value_entry->obj_header.b_flags & sym_m_private) != 0)
2194 	    {
2195 		sym_value_entry_type   *cstr_value;
2196 
2197 		cstr_value = (sym_value_entry_type *) sem_create_cstr();
2198 		cstr_value->b_expr_opr = sym_k_coerce_op;
2199 		cstr_value->az_exp_op1 = value_entry;
2200 		sem_evaluate_value_expr (cstr_value);
2201 	    }
2202 	}
2203 
2204 	if (( expected_arg_type == sym_k_wchar_string_value ) &&
2205 	    ( actual_arg_type == sym_k_localized_string_value ))
2206 	{
2207 	    valid_arg = TRUE;
2208 	    if ( (value_entry->obj_header.b_flags & sym_m_private) != 0)
2209 	    {
2210 		sym_value_entry_type   *wcstr_value;
2211 
2212 		wcstr_value = (sym_value_entry_type *) sem_create_wchar_str();
2213 		wcstr_value->b_expr_opr = sym_k_coerce_op;
2214 		wcstr_value->az_exp_op1 = value_entry;
2215 		sem_evaluate_value_expr (wcstr_value);
2216 	    }
2217 	}
2218 
2219 	if (( expected_arg_type == sym_k_font_table_value ) &&
2220 	    (( actual_arg_type == sym_k_font_value ) ||
2221 	     ( actual_arg_type == sym_k_fontset_value )))
2222 	{
2223 	    valid_arg = TRUE;
2224 	    if ( (value_entry->obj_header.b_flags & sym_m_private) != 0)
2225 	    {
2226 		sym_value_entry_type   *font_table;
2227 
2228 		font_table =
2229 		    sem_create_value_entry
2230 			( (char*)&value_entry, sizeof(long),
2231 			 sym_k_font_table_value );
2232 		font_table->b_expr_opr = sym_k_coerce_op;
2233 		font_table->az_exp_op1 = value_entry;
2234 		value_entry = sem_evaluate_value (font_table);
2235 	    }
2236 	}
2237 
2238 	if ((expected_arg_type == sym_k_widget_ref_value) &&
2239 	    (value_entry->header.b_tag == sym_k_widget_entry))
2240 	  {
2241 	    expected_arg_type = proc_def_entry->b_widget_type;
2242 	    actual_arg_type = value_entry->header.b_type;
2243 
2244 	    if ((expected_arg_type > uil_max_object) ||
2245 		(actual_arg_type == expected_arg_type))
2246 	      {
2247 		valid_arg = TRUE;
2248 	      }
2249 	    else
2250 	      {
2251 		diag_issue_diagnostic
2252 		  (d_arg_type,
2253 		   _sar_source_pos2(procref_entry),
2254 		   diag_object_text(actual_arg_type),
2255 		   proc_def_entry->obj_header.az_name->c_text,
2256 		   diag_object_text(expected_arg_type));
2257 
2258 		return;
2259 	      }
2260 	  }
2261 
2262 	if (!valid_arg)
2263 	{
2264 	    diag_issue_diagnostic
2265 		( d_arg_type,
2266 		  _sar_source_pos2 (procref_entry),
2267 		  diag_value_text( actual_arg_type ),
2268 		  proc_def_entry->obj_header.az_name->c_text,
2269 		  diag_value_text( expected_arg_type ) );
2270 
2271 	    return;
2272 	}
2273     }
2274 
2275 /*
2276  * Perform validation of tags
2277  */
2278 sem_validate_node (( sym_entry_type *)procref_entry->az_arg_value);
2279 }
2280 
2281 
2282 /*
2283 **++
2284 **  FUNCTIONAL DESCRIPTION:
2285 **
2286 **      This predicate specifies if an argument is allowed in a class.
2287 **
2288 **  FORMAL PARAMETERS:
2289 **
2290 **      arg_code	The sym_k_..._arg code for the argument
2291 **	class_code	The sym_k_..._object code for the class
2292 **
2293 **  IMPLICIT INPUTS:
2294 **
2295 **      allowed_argument_table
2296 **
2297 **  IMPLICIT OUTPUTS:
2298 **
2299 **  FUNCTION VALUE:
2300 **
2301 **      TRUE		argument is allowed
2302 **	FALSE		argument is not allowed
2303 **
2304 **  SIDE EFFECTS:
2305 **
2306 **--
2307 **/
2308 
sem_argument_allowed(arg_code,class_code)2309 boolean sem_argument_allowed (arg_code, class_code)
2310     unsigned int		arg_code;
2311     unsigned int		class_code;
2312 
2313 {
2314 
2315 unsigned char		*entry_vec;
2316 unsigned char		vec_byte;
2317 
2318 entry_vec = allowed_argument_table[arg_code];
2319 vec_byte = entry_vec[_BIT_INDEX(class_code)];
2320 return (boolean) vec_byte & _BIT_MASK(class_code);
2321 
2322 }
2323 
2324 
2325 
2326 /*
2327 **++
2328 **  FUNCTIONAL DESCRIPTION:
2329 **
2330 **      This predicate specifies if a reason is allowed in a class.
2331 **
2332 **  FORMAL PARAMETERS:
2333 **
2334 **      rsn_code	The sym_k_..._reason code for the reason
2335 **	class_code	The sym_k_..._object code for the class
2336 **
2337 **  IMPLICIT INPUTS:
2338 **
2339 **      allowed_reason_table
2340 **
2341 **  IMPLICIT OUTPUTS:
2342 **
2343 **  FUNCTION VALUE:
2344 **
2345 **      TRUE		reason is allowed
2346 **	FALSE		reason is not allowed
2347 **
2348 **  SIDE EFFECTS:
2349 **
2350 **--
2351 **/
2352 
sem_reason_allowed(rsn_code,class_code)2353 boolean sem_reason_allowed (rsn_code, class_code)
2354     unsigned int		rsn_code;
2355     unsigned int		class_code;
2356 
2357 {
2358 
2359 unsigned char		*entry_vec;
2360 unsigned char		vec_byte;
2361 
2362 entry_vec = allowed_reason_table[rsn_code];
2363 vec_byte = entry_vec[_BIT_INDEX(class_code)];
2364 return (boolean) vec_byte & _BIT_MASK(class_code);
2365 
2366 }
2367 
2368 
2369 
2370 /*
2371 **++
2372 **  FUNCTIONAL DESCRIPTION:
2373 **
2374 **      This predicate specifies if a control is allowed in a class.
2375 **
2376 **  FORMAL PARAMETERS:
2377 **
2378 **      ctl_code	The sym_k_..._object code for the control, that is,
2379 **			the class of object which is to be a child of
2380 **			the class below.
2381 **	class_code	The sym_k_..._object code for the class
2382 **
2383 **  IMPLICIT INPUTS:
2384 **
2385 **      allowed_control_table
2386 **
2387 **  IMPLICIT OUTPUTS:
2388 **
2389 **  FUNCTION VALUE:
2390 **
2391 **      TRUE		control is allowed
2392 **	FALSE		control is not allowed
2393 **
2394 **  SIDE EFFECTS:
2395 **
2396 **--
2397 **/
2398 
sem_control_allowed(ctl_code,class_code)2399 boolean sem_control_allowed (ctl_code, class_code)
2400     unsigned int		ctl_code;
2401     unsigned int		class_code;
2402 
2403 {
2404 
2405 unsigned char		*entry_vec;
2406 unsigned char		vec_byte;
2407 
2408 entry_vec = allowed_control_table[ctl_code];
2409 vec_byte = entry_vec[_BIT_INDEX(class_code)];
2410 return (boolean) vec_byte & _BIT_MASK(class_code);
2411 
2412 }
2413 
2414 
2415 
2416 /*
2417 **++
2418 **  FUNCTIONAL DESCRIPTION:
2419 **
2420 **      This predicate specifies if an automatically create child is
2421 **	 allowed in a class.
2422 **
2423 **  FORMAL PARAMETERS:
2424 **
2425 **      ctl_code	The sym_k_..._child code for the child, that is,
2426 **			the class of child which is to be automatically
2427 **			created in the class below.
2428 **	class_code	The sym_k_..._object code for the class
2429 **
2430 **  IMPLICIT INPUTS:
2431 **
2432 **      allowed_child_table
2433 **
2434 **  IMPLICIT OUTPUTS:
2435 **
2436 **  FUNCTION VALUE:
2437 **
2438 **      TRUE		child is allowed
2439 **	FALSE		child is not allowed
2440 **
2441 **  SIDE EFFECTS:
2442 **
2443 **--
2444 **/
2445 
sem_child_allowed(ctl_code,class_code)2446 boolean sem_child_allowed (ctl_code, class_code)
2447     unsigned int		ctl_code;
2448     unsigned int		class_code;
2449 
2450 {
2451 
2452 unsigned char		*entry_vec;
2453 unsigned char		vec_byte;
2454 
2455 entry_vec = allowed_child_table[ctl_code];
2456 vec_byte = entry_vec[_BIT_INDEX(class_code)];
2457 return (boolean) vec_byte & _BIT_MASK(class_code);
2458 
2459 }
2460 
2461 
2462 /*
2463 **++
2464 **  FUNCTIONAL DESCRIPTION:
2465 **
2466 **	This function does evaluation and validation of value nodes. It
2467 **	guarantees that a value usable by the output routine or other consumers
2468 **	of values is available in the value union of the node, with
2469 **	any other corollary fields also set. The result of the operation may
2470 **	be a new node, if coercion is required.
2471 **
2472 **  FORMAL PARAMETERS:
2473 **
2474 **	val_entry	pointer to the value node to be evaluated
2475 **
2476 **  IMPLICIT INPUTS:
2477 **
2478 **      none
2479 **
2480 **  IMPLICIT OUTPUTS:
2481 **
2482 **      none
2483 **
2484 **  FUNCTION VALUE:
2485 **
2486 **      The value node which results from the evaluation/validation operation
2487 **
2488 **  SIDE EFFECTS:
2489 **
2490 **      The value union and other fields may be modified.
2491 **
2492 **--
2493 **/
2494 
sem_evaluate_value(val_entry)2495 sym_value_entry_type *sem_evaluate_value (val_entry)
2496     sym_value_entry_type	*val_entry;
2497 
2498 {
2499 /*
2500  * Force expression evaluation
2501  */
2502 sem_evaluate_value_expr (val_entry);
2503 
2504 /* BEGIN HAL Fix CR 4774 */
2505 /* 	Do not execute case statement if val_entry was previously
2506  *      a sym_k_valref_op node type.  This can be determined by
2507  *      examining the state of the sym_m_exp_eval flag in the
2508  *      b_aux_flags field.
2509  */
2510 
2511 
2512 if ((val_entry->b_aux_flags & sym_m_exp_eval) == 0)
2513   /*
2514    * Perform evaluations which depend on the type of the value
2515    */
2516   switch ( val_entry->b_type )
2517 /* END HAL Fix CR 4774 */
2518     {
2519     case sym_k_integer_value:
2520     case sym_k_horizontal_integer_value:
2521     case sym_k_vertical_integer_value:
2522 	break;
2523     case sym_k_compound_string_value:
2524         sem_evaluate_value_cs (val_entry);
2525 	break;
2526 /* BEGIN OSF Fix CR 4859 */
2527 /* END OSF Fix CR 4859 */
2528     case sym_k_string_table_value:
2529 	{
2530 	sym_value_entry_type *value_segment;
2531 	for (value_segment=val_entry->az_first_table_value;
2532 	     value_segment!=NULL;
2533 	     value_segment=value_segment->az_next_table_value)
2534 	    {
2535 	    sem_evaluate_value_expr (value_segment);
2536 	    if ((value_segment->b_type == sym_k_char_8_value) ||
2537 		(value_segment->b_type == sym_k_localized_string_value))
2538 		{
2539 		sym_value_entry_type	*cstr;
2540 		sym_value_entry_type	*save_next;
2541 
2542 		save_next = (sym_value_entry_type *)
2543 		    (value_segment -> az_next_table_value);
2544 	        cstr = (sym_value_entry_type *) sem_create_cstr();
2545 	        sem_append_str_to_cstr( cstr,
2546 		    value_segment, FALSE);
2547 		_sym_copy_entry (value_segment,
2548 		    cstr,
2549 		    sym_k_value_entry_size );
2550 		value_segment -> az_next_table_value =
2551 		    save_next;
2552 		cstr->value.xms_value = NULL;
2553 		cstr->az_first_table_value = NULL;
2554 		sem_free_node (( sym_entry_type *)cstr);
2555 		}
2556 	    if (value_segment->b_type != sym_k_compound_string_value)
2557 		diag_issue_diagnostic
2558 		    ( d_wrong_type,
2559 		      _sar_source_pos2( value_segment ),
2560 		      diag_value_text( value_segment->b_type),
2561 		      diag_value_text( sym_k_compound_string_value ) );
2562 	    sem_evaluate_value_cs (value_segment);
2563 	    }
2564         }
2565 	break;
2566     case sym_k_integer_table_value:
2567 	{
2568 	sym_value_entry_type *value_segment;
2569 
2570 	for (value_segment=val_entry->az_first_table_value;
2571 	     value_segment!=NULL;
2572 	     value_segment=value_segment->az_next_table_value)
2573 	    {
2574 	    sem_evaluate_value_expr (value_segment);
2575 	    if (value_segment->b_type != sym_k_integer_value &&
2576 		value_segment->b_type != sym_k_horizontal_integer_value &&
2577 		value_segment->b_type != sym_k_vertical_integer_value)
2578 		diag_issue_diagnostic
2579 		    ( d_wrong_type,
2580 		      _sar_source_pos2( value_segment ),
2581 		      diag_value_text( value_segment->b_type),
2582 		      diag_value_text( sym_k_integer_value ) );
2583 	    }
2584 	}
2585 	break;
2586     case sym_k_asciz_table_value:
2587     case sym_k_trans_table_value:
2588 	{
2589 	sym_value_entry_type *value_segment;
2590 
2591 	for (value_segment=val_entry->az_first_table_value;
2592 	     value_segment!=NULL;
2593 	     value_segment=value_segment->az_next_table_value)
2594 	    {
2595 	    sem_evaluate_value_expr (value_segment);
2596 	    if ((value_segment->b_type != sym_k_char_8_value) &&
2597 		(value_segment->b_type != sym_k_localized_string_value))
2598 		diag_issue_diagnostic
2599 		    ( d_wrong_type,
2600 		      _sar_source_pos2( value_segment ),
2601 		      diag_value_text( value_segment->b_type),
2602 		      diag_value_text( sym_k_char_8_value ) );
2603 	    }
2604 	}
2605 	break;
2606     case sym_k_font_table_value:
2607 	{
2608 	sym_value_entry_type *value_segment;
2609 
2610 	for (value_segment=val_entry->az_first_table_value;
2611 	     value_segment!=NULL;
2612 	     value_segment=value_segment->az_next_table_value)
2613 	    {
2614 	    sem_evaluate_value_expr (value_segment);
2615 	    if ((value_segment->b_type != sym_k_char_8_value) &&
2616 		(value_segment->b_type != sym_k_localized_string_value) &&
2617 		(value_segment->b_type != sym_k_font_value) &&
2618 		(value_segment->b_type != sym_k_fontset_value))
2619 		diag_issue_diagnostic
2620 		    ( d_wrong_type,
2621 		      _sar_source_pos2( value_segment ),
2622 		      diag_value_text( value_segment->b_type),
2623 		      diag_value_text( sym_k_char_8_value ) );
2624 	    }
2625 	break;
2626 	}
2627 /*
2628  * Fix for CR 5403 - check to make sure each item in the rgb table is an
2629  *                   integer value.  If not, print an error message.  Treat
2630  *                   this exactly like the integer_table_value section above.
2631  */
2632     case sym_k_rgb_value:
2633         {
2634         sym_value_entry_type *value_segment;
2635 
2636         for (value_segment=val_entry->az_first_table_value;
2637              value_segment!=NULL;
2638              value_segment=value_segment->az_next_table_value)
2639             {
2640             sem_evaluate_value_expr (value_segment);
2641             if (value_segment->b_type != sym_k_integer_value &&
2642                 value_segment->b_type != sym_k_identifier_value &&
2643 		value_segment->b_type != sym_k_horizontal_integer_value &&
2644 		value_segment->b_type != sym_k_vertical_integer_value)
2645                 diag_issue_diagnostic
2646                     ( d_wrong_type,
2647                       _sar_source_pos2( value_segment ),
2648                       diag_value_text( value_segment->b_type),
2649                       diag_value_text( sym_k_integer_value ) );
2650             }
2651         }
2652         break;
2653 /*
2654  * End Fix for CR 5403
2655  */
2656     case sym_k_color_table_value:
2657 	{
2658 	sym_color_element	*colorVec;
2659 	int			ndx;
2660 
2661 	colorVec = val_entry->value.z_color;
2662 	for ( ndx=0 ; ndx<(int)val_entry->b_table_count ; ndx++ )
2663 	    if ( (int)colorVec[ndx].b_index > 1 )	/* omit FG, BG */
2664 /*
2665  * Fix for CR 5428 - check to make sure that the expression result is a
2666  *                   color value.  If not, print diagnostics.
2667  */
2668             {
2669 		sem_evaluate_value_expr (colorVec[ndx].az_color);
2670                 if ((colorVec[ndx].az_color->b_type != sym_k_color_value) &&
2671 		    ( colorVec[ndx].az_color->b_type != sym_k_rgb_value))
2672                   diag_issue_diagnostic
2673                     ( d_wrong_type,
2674                       _sar_source_pos2( colorVec[ndx].az_color ),
2675                       diag_value_text( colorVec[ndx].az_color->b_type),
2676                       diag_value_text( sym_k_color_value ) );
2677              }
2678 /*
2679  * End Fix for CR 5428
2680  */
2681 	break;
2682 	}
2683     case sym_k_pixmap_value:
2684     case sym_k_icon_value:
2685 	{
2686 	sym_icon_element	*iconDesc;
2687 	sym_value_entry_type	*cTable;
2688 
2689 	iconDesc = val_entry->value.z_icon;
2690 
2691 /* BEGIN OSF Fix pir 2869*/
2692 	if ( iconDesc == NULL )
2693 	    break;
2694 	else cTable = iconDesc->az_color_table;
2695 /* END OSF Fix pir 2869 */
2696 	if ( cTable == NULL )
2697 	    break;
2698 	switch ( cTable->b_type )
2699 	    {
2700 	    case sym_k_color_table_value:
2701 	        {
2702 		sym_color_element	*colorVec;
2703 		int			vecLen = cTable->b_table_count;
2704 		int			ndx;
2705 		int			i, j;
2706 		boolean			found;
2707 		char			*row;
2708 		sym_value_entry_type	*rowEntry;
2709 
2710 		/*
2711 		 * Find each icon character in the table, and replace its
2712 		 * character by its index.
2713 		 */
2714 		colorVec = cTable->value.z_color;
2715 		rowEntry = iconDesc->az_rows;
2716 		for ( ndx=0 ;
2717 		     ndx<(int)iconDesc->w_height ;
2718 		     ndx++, rowEntry=rowEntry->az_next_table_value )
2719 		    for ( row = rowEntry->value.c_value, i = 0 ;
2720 			 i<(int)rowEntry->w_length ;
2721 			 i++)
2722 			{
2723 			found = FALSE;
2724 			for ( j=0 ; j<vecLen ; j++ )
2725 			    {
2726 			    if (colorVec[j].b_letter == row[i])
2727 				{
2728 				found = TRUE;
2729 				row[i] = colorVec[j].b_index;
2730 				break;
2731 				}
2732 			    }
2733 
2734 			if ( ! found )
2735 			    {
2736 			    diag_issue_diagnostic
2737 				(d_icon_letter,
2738 				 _sar_source_pos2(rowEntry),
2739 				 ndx+1,
2740 				 i+1,
2741 				 row[i]);
2742 			    }
2743 			}
2744 
2745 		}
2746 	    case sym_k_error_value:
2747 		break;
2748 	    default:
2749 		diag_issue_diagnostic
2750 		    (d_wrong_type,
2751 		     _sar_source_pos2(cTable),
2752 		     diag_value_text(cTable->b_type),
2753 		     diag_value_text(sym_k_color_table_value));
2754 		break;
2755 	    }
2756 	break;
2757 	}
2758     }
2759 /*
2760  * Perform evaluations which depend on evaluating expressions
2761  */
2762 return(sem_evaluate_value_expr (val_entry));
2763 
2764 }
2765 
2766 
2767 
2768 /*
2769 **++
2770 **  FUNCTIONAL DESCRIPTION:
2771 **
2772 **	This function evaluates a compound string value node, and
2773 **	returns the resulting compound string.
2774 **
2775 **  FORMAL PARAMETERS:
2776 **
2777 **	csval_entry	pointer to the value node to be evaluated
2778 **
2779 **  IMPLICIT INPUTS:
2780 **
2781 **      none
2782 **
2783 **  IMPLICIT OUTPUTS:
2784 **
2785 **      none
2786 **
2787 **  FUNCTION VALUE:
2788 **
2789 **      none
2790 **
2791 **  SIDE EFFECTS:
2792 **
2793 **      The value and length fields for the value entry are set.
2794 **
2795 **--
2796 **/
2797 
sem_evaluate_value_cs(csval_entry)2798 sym_value_entry_type *sem_evaluate_value_cs (csval_entry)
2799     sym_value_entry_type	*csval_entry;
2800 
2801 {
2802 
2803 sym_value_entry_type	*next_segment;
2804 
2805 XmString		cstr_1;
2806 XmString		cstr_r;
2807 int			charset;		/* sym_k_..._charset */
2808 char			*csetptr;		/* charset name string */
2809 
2810 _assert( (csval_entry->header.b_tag == sym_k_value_entry) &&
2811 	(csval_entry->b_type == sym_k_compound_string_value),
2812 	"value not compound string" );
2813 
2814 /*
2815  **	You can't do anyting about imported compound strings so return.
2816  */
2817 if ((csval_entry->obj_header.b_flags & sym_m_imported) != 0)
2818     return(csval_entry);
2819 
2820 /*
2821  **	If the pointer to the first segment of the compound string has been
2822  **	cleared (az_first_table_value) and there's a pointer to the evaluated
2823  **	compound string (value.xms_value), then we must have already evaluated
2824  **	this compound string.  Leave!
2825  */
2826 if ((csval_entry->az_first_table_value == NULL) &&
2827     (csval_entry->value.xms_value != NULL))
2828     return(csval_entry);
2829 
2830 /*
2831  **	Get the first segment of the compound string and create
2832  **	a compound string for it.
2833  */
2834 next_segment = csval_entry->az_first_table_value;
2835 _assert( next_segment != NULL, "compound string with no segments" );
2836 
2837 /*
2838  **	If the csval_entry direction is set reset the first segments
2839  **	direction (actually it will be the only segments direction).
2840  */
2841 if (csval_entry->b_direction != NOSTRING_DIRECTION)
2842     {
2843     next_segment->b_direction = csval_entry->b_direction;
2844     };
2845 
2846 /*
2847  **  Initial segment: acquire character set, then
2848  **  create initial segment.
2849  */
2850 charset = sem_map_subclass_to_charset (next_segment->b_charset );
2851     csetptr = sem_charset_name
2852 	(charset, next_segment->az_charset_value);
2853 
2854 if (next_segment->b_type == sym_k_localized_string_value)
2855   cstr_r = XmStringCreateLocalized(next_segment->value.c_value);
2856 else
2857   cstr_r =
2858     XmStringConcatAndFree(XmStringDirectionCreate(next_segment->b_direction),
2859 			  XmStringCreate(next_segment->value.c_value,
2860 					 csetptr));
2861 
2862 if (next_segment->b_aux_flags & sym_m_separate)
2863   cstr_r = XmStringConcatAndFree(cstr_r,
2864 				 XmStringSeparatorCreate());
2865 
2866 /*
2867  **  Loop through the rest of the segments of the string and append
2868  **  them to the first segment of the string.
2869  */
2870 for (next_segment = next_segment->az_next_table_value;
2871      next_segment != NULL;
2872      next_segment = next_segment->az_next_table_value)
2873     {
2874     /*
2875      **  Acquire each segment, and set the character set, as for the
2876      **  initial segment.
2877      */
2878     charset = sem_map_subclass_to_charset (next_segment->b_charset );
2879     csetptr = sem_charset_name
2880 	(charset, next_segment->az_charset_value);
2881 
2882     /*
2883      **  Create this segment, then concatenate to the result string.
2884      **  Free the two inputs now that a concatenated result string
2885      **  exists.
2886      */
2887     cstr_1 =
2888       XmStringConcatAndFree(XmStringDirectionCreate(next_segment->b_direction),
2889 			    XmStringCreate(next_segment->value.c_value,
2890 					   csetptr));
2891 
2892     if (next_segment->b_aux_flags & sym_m_separate)
2893       cstr_1 = XmStringConcatAndFree(cstr_1,
2894 				     XmStringSeparatorCreate());
2895 
2896     cstr_r = XmStringConcatAndFree(cstr_r, cstr_1);
2897     }
2898 
2899 csval_entry->value.xms_value = cstr_r;
2900 csval_entry->w_length = XmStringLength (cstr_r);
2901 
2902 /*
2903 ** Now deallocate the nodes for the compound string segments and put a null
2904 ** in az_first_table_value
2905 */
2906 for (next_segment = csval_entry->az_first_table_value;
2907      next_segment != NULL;
2908      next_segment = next_segment->az_next_table_value)
2909 	sem_free_node (( sym_entry_type *)next_segment);
2910 
2911 csval_entry->az_first_table_value = NULL;
2912 
2913 _assert( csval_entry->w_length <= MrmMaxResourceSize, "compound string too long" );
2914 
2915 return (csval_entry);
2916 }
2917 /* BEGIN OSF Fix CR 4859 */
2918 
2919 /* END OSF Fix CR 4859 */
2920 
2921 /*
2922 **++
2923 **  FUNCTIONAL DESCRIPTION:
2924 **
2925 **	This function evaluates an expression, placing the resulting value
2926 **	in the top-level value node of the expression tree.  A flag is set
2927 **	in the top-level node to indicate whether the evaluation has taken
2928 **	place.  The expression tree is left intact so that programs using
2929 **	the callable UIL compiler will have access to the expression as well
2930 **	as its evalutated value.
2931 **
2932 **  FORMAL PARAMETERS:
2933 **
2934 **	value_entry		the top-level value node of the expression
2935 **
2936 **  IMPLICIT INPUTS:
2937 **
2938 **  IMPLICIT OUTPUTS:
2939 **
2940 **  FUNCTION VALUE:
2941 **
2942 **	The value node resulting from this operation
2943 **
2944 **  SIDE EFFECTS:
2945 **
2946 **--
2947 **/
2948 
sem_evaluate_value_expr(value_entry)2949 sym_value_entry_type *sem_evaluate_value_expr (value_entry)
2950     sym_value_entry_type	*value_entry;
2951 
2952 {
2953 
2954     /*
2955      * Local variables
2956      */
2957     char		    		op1_type;
2958     char		    		op2_type;
2959     char		    		res_type;
2960     data_value_type	    		op1_data;
2961     data_value_type	    		op2_data;
2962     sym_value_entry_type    	*op1_entry = NULL;
2963     sym_value_entry_type    	*op2_entry = NULL;
2964     data_value_type	    		*op1_ptr = NULL;
2965     data_value_type	    		*op2_ptr = NULL;
2966     data_value_type	    		res_data;
2967     sym_value_entry_type		*cat_str_entry;
2968 
2969 
2970     /*
2971      ** If this isn't an operation or if we've already evaluated it, just
2972      ** leave. Also, guard against attempting to deal with NULLs.
2973      */
2974     if ( value_entry == NULL )
2975       return value_entry;
2976     if ( (value_entry->b_aux_flags & sym_m_exp_eval) != 0 )
2977       return value_entry;
2978     if ( value_entry->b_expr_opr == sym_k_unspecified_op )
2979       return value_entry;
2980 
2981     /*
2982      ** If we're just beginning to evaluate a new expression, increment the
2983      ** value for checking circular references.
2984      */
2985 
2986     if (!in_expr)
2987       ref_chk_value++;
2988     in_expr = TRUE;
2989 
2990     /*
2991      ** Check for circular references.
2992      ** Place a value in each node of this expression.  If we see the same
2993      ** value again as we evaluate the expression, we've been here before
2994      ** (kind of like dropping bread crumbs).
2995      */
2996 
2997     if (value_entry->l_circular_ref_chk == ref_chk_value)
2998     {
2999 	if ( value_entry->obj_header.az_name != NULL )
3000 	  diag_issue_diagnostic
3001 	    (d_circular_ref,
3002 	     _sar_source_pos2(value_entry),
3003 	     value_entry->obj_header.az_name->c_text);
3004 	else
3005 	  diag_issue_diagnostic
3006 	    (d_circular_ref,
3007 	     _sar_source_pos2(value_entry),
3008 	     "unnamed value");
3009 	return NULL;
3010     }
3011     value_entry->l_circular_ref_chk = ref_chk_value;
3012 
3013     /*
3014      ** Validate the first argument for the expression. If it is NULL,
3015      ** then return with no further processing, since this is usually
3016      ** due to previous compilation errors.
3017      */
3018     if ( value_entry->az_exp_op1 == NULL )
3019       return NULL;
3020     sem_evaluate_value_expr(value_entry->az_exp_op1);
3021     in_expr = TRUE;
3022     op1_type = validate_arg (value_entry->az_exp_op1,
3023 			     value_entry->b_expr_opr);
3024     op1_entry = value_entry->az_exp_op1;
3025     res_type = op1_type;
3026     /*
3027      ** If it's a binary expression, evaluate the second argument and
3028      ** perform any necessary conversions
3029      */
3030     if (value_entry->az_exp_op2 != NULL)
3031     {
3032 	sem_evaluate_value_expr(value_entry->az_exp_op2);
3033 	in_expr = TRUE;
3034 	op2_type = validate_arg (value_entry->az_exp_op2,
3035 				 value_entry->b_expr_opr);
3036 
3037 	/*
3038 	 ** Perform conversions
3039 	 */
3040 
3041 	op2_entry = value_entry->az_exp_op2;
3042 
3043         res_type = op1_type;
3044 	if (res_type < op2_type)
3045 	  res_type = op2_type;
3046 
3047 	if (op1_type != res_type)
3048 	{
3049 	    op1_ptr  = &op1_data;
3050 	    if (res_type <= error_arg_type)
3051 	      op1_type = (* numeric_convert_table[ (int)res_type ])
3052 		( op1_entry, op1_ptr );
3053 	    else if ((res_type != cstr_arg_type) &&
3054 		     (res_type != lstr_arg_type))
3055 	    {
3056 		diag_issue_diagnostic
3057 		  ( d_cannot_convert,
3058 		   _sar_source_pos2( value_entry),
3059 		   diag_value_text( op1_entry->b_type ),
3060 		   diag_value_text( res_type ) );
3061 		res_type = error_arg_type;
3062 		goto continue_after_error;
3063 	    }
3064 	}
3065 	else
3066 	{
3067 	    op1_ptr = (data_value_type *) &(op1_entry->value);
3068 	}
3069 
3070 
3071 	if (op2_type != res_type)
3072 	{
3073 	    op2_ptr  = &op2_data;
3074 	    if (res_type <= error_arg_type)
3075 	      op2_type = (* numeric_convert_table[ (int)res_type ])
3076 		( op2_entry, op2_ptr );
3077 	    else if ((res_type != cstr_arg_type) &&
3078 		     (res_type != lstr_arg_type))
3079 	    {
3080 		diag_issue_diagnostic
3081 		  ( d_cannot_convert,
3082 		   _sar_source_pos2( value_entry),
3083 		   diag_value_text( op1_entry->b_type ),
3084 		   diag_value_text( res_type ) );
3085 		res_type = error_arg_type;
3086 		goto continue_after_error;
3087 	    }
3088 	}
3089 	else
3090 	{
3091 	    op2_ptr = (data_value_type *) &(op2_entry->value);
3092 	}
3093     }
3094 
3095     /*
3096      ** Perform the operation
3097      */
3098 
3099     switch (value_entry->b_expr_opr)
3100     {
3101       case sym_k_unary_plus_op:
3102 	switch (op1_type)
3103 	{
3104 	  case integer_arg_type:
3105 	  case horizontal_integer_arg_type:
3106 	  case vertical_integer_arg_type:
3107 	    value_entry->value.l_integer = op1_entry->value.l_integer;
3108 	    value_entry->b_arg_type = op1_entry->b_arg_type;
3109 	    break;
3110 
3111 	  case float_arg_type:
3112 	  case horizontal_float_arg_type:
3113 	  case vertical_float_arg_type:
3114 	    value_entry->value.d_real = op1_entry->value.d_real;
3115 	    value_entry->b_arg_type = op1_entry->b_arg_type;
3116 	    break;
3117 
3118 	  case single_float_arg_type: /* single float data type RAP */
3119 	    value_entry->value.single_float = op1_entry->value.single_float;
3120 	    break;
3121 
3122 	  case error_arg_type:
3123 	    break;
3124 
3125 	  default:
3126 	    diag_issue_diagnostic
3127 	      ( d_cannot_convert,
3128 	       _sar_source_pos2( value_entry),
3129 	       diag_value_text( op1_entry->b_type ),
3130 	       diag_value_text( value_entry->b_type ) );
3131 	    res_type = error_arg_type;
3132 	}
3133 	break;
3134 
3135       case sym_k_unary_minus_op:
3136 	switch (op1_type)
3137 	{
3138 	  case integer_arg_type:
3139 	  case horizontal_integer_arg_type:
3140 	  case vertical_integer_arg_type:
3141 	    value_entry->value.l_integer = - op1_entry->value.l_integer;
3142 	    value_entry->b_arg_type = op1_entry->b_arg_type;
3143 	    break;
3144 
3145 	  case float_arg_type:
3146 	  case horizontal_float_arg_type:
3147 	  case vertical_float_arg_type:
3148 	    value_entry->value.d_real = - op1_entry->value.d_real;
3149 	    value_entry->b_arg_type = op1_entry->b_arg_type;
3150 	    break;
3151 
3152 	  case single_float_arg_type: /* single float data type RAP */
3153 	    value_entry->value.single_float = - op1_entry->value.single_float;
3154 	    break;
3155 
3156 	  case error_arg_type:
3157 	    break;
3158 
3159 	  default:
3160 	    diag_issue_diagnostic
3161 	      ( d_cannot_convert,
3162 	       _sar_source_pos2( value_entry),
3163 	       diag_value_text( op1_entry->b_type ),
3164 	       diag_value_text( value_entry->b_type ) );
3165 	    res_type = error_arg_type;
3166 	}
3167 	break;
3168 
3169       case sym_k_not_op:
3170 	switch (op1_type)
3171 	{
3172 	  case boolean_arg_type:
3173 	    value_entry->value.l_integer = ! op1_entry->value.l_integer;
3174 	    break;
3175 
3176 	  case integer_arg_type:
3177 	    value_entry->value.l_integer = ~ op1_entry->value.l_integer;
3178 	    break;
3179 
3180 	  case error_arg_type:
3181 	    break;
3182 
3183 	  default:
3184 	    diag_issue_diagnostic
3185 	      ( d_cannot_convert,
3186 	       _sar_source_pos2( value_entry),
3187 	       diag_value_text( op1_entry->b_type ),
3188 	       diag_value_text( value_entry->b_type ) );
3189 	    res_type = error_arg_type;
3190 	}
3191 	break;
3192 
3193       case sym_k_comp_str_op:
3194 	switch (op1_type)
3195 	{
3196 	case char_arg_type:	/* char_8_type */
3197 	case lstr_arg_type:
3198 	  sem_append_str_to_cstr(value_entry, value_entry->az_exp_op1, FALSE);
3199 	  value_entry->az_first_table_value->b_aux_flags =
3200 	    value_entry->b_aux_flags;
3201              /*
3202               * Fix for CN 16149 (DTS 10023) part 2 -- If it exists, put the
3203               * charset info collected by sar_chk_comp_str_attr() onto the
3204               * char_8 string data structure.
3205               */
3206              if (value_entry->b_charset != sym_k_error_charset) {
3207                   value_entry->az_first_table_value->b_charset =
3208                         value_entry->b_charset;
3209                   if (value_entry->az_charset_value)
3210                         value_entry->az_first_table_value->az_charset_value =
3211                                 value_entry->az_charset_value;
3212              }
3213              /* End fix for CN 16149 */
3214 	    sem_evaluate_value_cs(value_entry);
3215 	    res_type = cstr_arg_type;
3216 	    break;
3217 	  case cstr_arg_type:	/*  comp_str */;
3218 	  {
3219 	      XmString	cstr;
3220 
3221 	      /*
3222 	       * If we're dealing with a combination 1-byte, 2-byte
3223 	       * string, then we have to evaluate it first. (if not
3224 	       * already done)
3225 	       */
3226 	      if (value_entry->az_exp_op1->az_first_table_value != NULL)
3227 	      {
3228 		  sem_evaluate_value_cs(value_entry->az_exp_op1);
3229 	      }
3230 	      /*
3231 	       * If there is a separater invoved, makes sure it gets
3232 	       * concatendated onto the end of the string.  Also free
3233 	       * up used memory.
3234 	       */
3235 	      if ((value_entry->b_aux_flags
3236 		   & sym_m_separate) != 0 )
3237 	      {
3238 		  cstr = XmStringSeparatorCreate();
3239 		  value_entry->value.l_integer =
3240 		    (long)XmStringConcatAndFree((XmString)value_entry->az_exp_op1->
3241 						value.l_integer, cstr);
3242 	      }
3243 	      else
3244 	      {
3245 		  value_entry->value.l_integer =
3246 		    value_entry->az_exp_op1->value.l_integer;
3247 	      }
3248 
3249 	      sem_evaluate_value_cs(value_entry);
3250 
3251 	      res_type = cstr_arg_type;
3252 	  };
3253 	    break;
3254 	  default:
3255 	    diag_issue_diagnostic
3256 	      ( d_cannot_convert,
3257 	       _sar_source_pos2( value_entry),
3258 	       diag_value_text( op1_entry->b_type ),
3259 	       diag_value_text( value_entry->b_type ) );
3260 	    res_type = error_arg_type;
3261 	}
3262         break;
3263 
3264       case sym_k_wchar_str_op:
3265 	switch (op1_type)
3266 	{
3267 	  case lstr_arg_type:	/* localized string type */
3268 	    sem_append_str_to_cstr(value_entry, value_entry->az_exp_op1, FALSE);
3269 	    value_entry->az_first_table_value->b_aux_flags =
3270 	      value_entry->b_aux_flags;
3271 	    /* BEGIN OSF Fix CR 4859 */
3272 	    /* END OSF Fix CR 4859 */
3273 	    res_type = wcstr_arg_type;
3274 	    break;
3275 	  default:
3276 	    diag_issue_diagnostic
3277 	      ( d_cannot_convert,
3278 	       _sar_source_pos2( value_entry),
3279 	       diag_value_text( op1_entry->b_type ),
3280 	       diag_value_text( value_entry->b_type ) );
3281 	    res_type = error_arg_type;
3282 	}
3283         break;
3284 
3285       case sym_k_coerce_op:
3286 	switch (value_entry->b_type)
3287 	{
3288 	  case sym_k_compound_string_value:
3289 	    switch (op1_entry->b_type)
3290 	    {
3291 	      case sym_k_char_8_value:
3292 	      case sym_k_localized_string_value:
3293 		sem_append_str_to_cstr
3294 		  (value_entry,
3295 		   op1_entry,
3296 		   FALSE);
3297 		sem_evaluate_value_cs(value_entry);
3298 		res_type = cstr_arg_type;
3299 		break;
3300 	      case sym_k_compound_string_value:
3301 		_sym_copy_entry (value_entry,
3302 				 op1_entry,
3303 				 sym_k_value_entry_size);
3304 		res_type = cstr_arg_type;
3305 		break;
3306 	      default:
3307 		diag_issue_diagnostic
3308 		  ( d_cannot_convert,
3309 		   _sar_source_pos2( value_entry),
3310 		   diag_value_text( op1_entry->b_type ),
3311 		   diag_value_text( value_entry->b_type ) );
3312 		res_type = error_arg_type;
3313 		break;
3314 	    }
3315 	    break;
3316 
3317 	  case sym_k_wchar_string_value:
3318 	    switch (op1_entry->b_type)
3319 	    {
3320 	      case sym_k_localized_string_value:
3321 		sem_append_str_to_cstr
3322 		  (value_entry,
3323 		   op1_entry,
3324 		   FALSE);
3325 		/* BEGIN OSF Fix CR 4859 */
3326 		/* END OSF Fix CR 4859 */
3327 		res_type = wcstr_arg_type;
3328 		break;
3329 	      default:
3330 		diag_issue_diagnostic
3331 		  ( d_cannot_convert,
3332 		   _sar_source_pos2( value_entry),
3333 		   diag_value_text( op1_entry->b_type ),
3334 		   diag_value_text( value_entry->b_type ) );
3335 		res_type = error_arg_type;
3336 		break;
3337 	    }
3338 	    break;
3339 
3340 	  case sym_k_font_table_value:
3341 	    if ((op1_entry->b_type == sym_k_font_value) ||
3342 		(op1_entry->b_type == sym_k_fontset_value))
3343 	    {
3344 		value_entry->b_table_count = 1;
3345 		value_entry->az_first_table_value = op1_entry;
3346 		res_type = font_table_arg_type;
3347 	    }
3348 	    else
3349 	    {
3350 		diag_issue_diagnostic
3351 		  ( d_cannot_convert,
3352 		   _sar_source_pos2( value_entry),
3353 		   diag_value_text( op1_entry->b_type ),
3354 		   diag_value_text( value_entry->b_type ) );
3355 		res_type = error_arg_type;
3356 	    }
3357 	    break;
3358 
3359 	  case sym_k_font_value:
3360 	    if ((op1_entry->b_type == sym_k_char_8_value) ||
3361 		(op1_entry->b_type == sym_k_localized_string_value) ||
3362 		(op1_entry->b_type == sym_k_font_value))
3363 	    {
3364 	        value_entry->value.c_value = op1_entry->value.c_value;
3365 	        value_entry->w_length = op1_entry->w_length;
3366 		res_type = font_arg_type;
3367 	    }
3368 	    else
3369 	    {
3370 		diag_issue_diagnostic
3371 		  ( d_cannot_convert,
3372 		   _sar_source_pos2( value_entry),
3373 		   diag_value_text( op1_entry->b_type ),
3374 		   diag_value_text( value_entry->b_type ) );
3375 		res_type = error_arg_type;
3376 	    }
3377 	    break;
3378 
3379 	  case sym_k_fontset_value:
3380 	    if ((op1_entry->b_type == sym_k_char_8_value) ||
3381 		(op1_entry->b_type == sym_k_localized_string_value) ||
3382 		(op1_entry->b_type == sym_k_fontset_value))
3383 	    {
3384 	        value_entry->value.c_value = op1_entry->value.c_value;
3385 	        value_entry->w_length = op1_entry->w_length;
3386 		res_type = fontset_arg_type;
3387 	    }
3388 	    else
3389 	    {
3390 		diag_issue_diagnostic
3391 		  ( d_cannot_convert,
3392 		   _sar_source_pos2( value_entry),
3393 		   diag_value_text( op1_entry->b_type ),
3394 		   diag_value_text( value_entry->b_type ) );
3395 		res_type = error_arg_type;
3396 	    }
3397 
3398 	  case sym_k_color_value:
3399 	  case sym_k_xbitmapfile_value:
3400 	  case sym_k_reason_value:
3401 	  case sym_k_argument_value:
3402 	  case sym_k_keysym_value:
3403 	  case sym_k_class_rec_name_value:
3404 	    switch (value_entry->b_type)
3405 	    {
3406 	      case sym_k_color_value:
3407 		res_type = color_arg_type;
3408 		break;
3409 	      case sym_k_xbitmapfile_value:
3410 		res_type = xbitmap_arg_type;
3411 		break;
3412 	      case sym_k_reason_value:
3413 		res_type = reason_arg_type;
3414 		break;
3415 	      case sym_k_argument_value:
3416 		res_type = argument_arg_type;
3417 		break;
3418 	      case sym_k_keysym_value:
3419 		res_type = keysym_arg_type;
3420 		break;
3421 		/*  Begin fixing CR 5429 */
3422 	      case sym_k_class_rec_name_value:
3423 		res_type = classrec_arg_type;
3424 		break;
3425 		/*  End fixing CR 5429 */
3426 	    }
3427 	    switch (op1_entry->b_type)
3428 	    {
3429 	    case sym_k_char_8_value:
3430 	    case sym_k_localized_string_value:
3431 	        value_entry->value.c_value = op1_entry->value.c_value;
3432 	        value_entry->w_length = op1_entry->w_length;
3433 		break;
3434 	      default:
3435 		diag_issue_diagnostic
3436 		  ( d_cannot_convert,
3437 		   _sar_source_pos2( value_entry),
3438 		   diag_value_text( op1_entry->b_type ),
3439 		   diag_value_text( value_entry->b_type ) );
3440 		res_type = error_arg_type;
3441 		break;
3442 	    }
3443 	    break;
3444 
3445 	  case sym_k_integer_value:
3446 	  case sym_k_horizontal_integer_value:
3447 	  case sym_k_vertical_integer_value:
3448 	    res_type = integer_arg_type;
3449 	    switch (op1_entry->b_type)
3450 	    {
3451 	      case sym_k_bool_value:
3452 	      case sym_k_integer_value:
3453 	      case sym_k_horizontal_integer_value:
3454 	      case sym_k_vertical_integer_value:
3455 	        value_entry->value.l_integer = op1_entry->value.l_integer;
3456 		value_entry->b_arg_type = op1_entry->b_arg_type;
3457 	        break;
3458 	      case sym_k_float_value:
3459 	      case sym_k_horizontal_float_value:
3460 	      case sym_k_vertical_float_value:
3461 	        res_type = sem_convert_to_integer( op1_entry, &res_data );
3462 	        value_entry->value.l_integer = res_data.integer_value;
3463 		value_entry->b_arg_type = op1_entry->b_arg_type;
3464 	        break;
3465 	      case sym_k_single_float_value: /* single float data type RAP */
3466 		res_type = sem_convert_to_integer( op1_entry, &res_data );
3467 	        value_entry->value.l_integer = res_data.integer_value;
3468                 break;
3469 	      default:
3470 		diag_issue_diagnostic
3471 		  ( d_cannot_convert,
3472 		   _sar_source_pos2( value_entry),
3473 		   diag_value_text( op1_entry->b_type ),
3474 		   diag_value_text( value_entry->b_type ) );
3475 		res_type = error_arg_type;
3476 		break;
3477 	    }
3478 	    break;
3479 	  case sym_k_float_value:
3480 	  case sym_k_horizontal_float_value:
3481 	  case sym_k_vertical_float_value:
3482 	    res_type = float_arg_type;
3483 	    switch (op1_entry->b_type)
3484 	    {
3485 	      case sym_k_bool_value:
3486 	      case sym_k_integer_value:
3487 	      case sym_k_single_float_value: /* single float data type RAP */
3488 	      case sym_k_horizontal_integer_value:
3489 	      case sym_k_vertical_integer_value:
3490 	        res_type = sem_convert_to_float( op1_entry, &res_data );
3491 	        value_entry->value.d_real = res_data.real_value;
3492 		value_entry->b_arg_type = op1_entry->b_arg_type;
3493 	        break;
3494 	      case sym_k_float_value:
3495 	      case sym_k_horizontal_float_value:
3496 	      case sym_k_vertical_float_value:
3497 	        value_entry->value.d_real = op1_entry->value.d_real;
3498 		value_entry->b_arg_type = op1_entry->b_arg_type;
3499 	        break;
3500 	      default:
3501 		diag_issue_diagnostic
3502 		  ( d_cannot_convert,
3503 		   _sar_source_pos2( value_entry),
3504 		   diag_value_text( op1_entry->b_type ),
3505 		   diag_value_text( value_entry->b_type ) );
3506 		res_type = error_arg_type;
3507 		break;
3508 	    }
3509 	    break;
3510 	  case sym_k_single_float_value:
3511 	    res_type = single_float_arg_type;
3512 	    switch (op1_entry->b_type)
3513 	    {
3514 	      case sym_k_bool_value:
3515 	      case sym_k_integer_value:
3516 	      case sym_k_horizontal_integer_value:
3517 	      case sym_k_vertical_integer_value:
3518 	      case sym_k_float_value:
3519 	      case sym_k_horizontal_float_value:
3520 	      case sym_k_vertical_float_value:
3521 		res_type = sem_convert_to_single_float( op1_entry, &res_data );
3522 		value_entry->value.single_float = res_data.single_float_value;
3523 		value_entry->b_arg_type = op1_entry->b_arg_type;
3524 		break;
3525 	      case sym_k_single_float_value:
3526 		value_entry->value.single_float = op1_entry->value.single_float;
3527 		break;
3528 	      default:
3529 		diag_issue_diagnostic
3530 		  ( d_cannot_convert,
3531 		   _sar_source_pos2( value_entry),
3532 		   diag_value_text( op1_entry->b_type ),
3533 		   diag_value_text( value_entry->b_type ) );
3534 		res_type = error_arg_type;
3535 		break;
3536 	    }
3537 	    break;
3538 
3539 	  case sym_k_error_value:
3540 	    break;
3541 
3542 	  default:
3543 	    /*  Begin fixing CR 5429 */
3544 	    if ((op1_entry->b_type != sym_k_char_8_value) &&
3545 		(op1_entry->b_type != sym_k_localized_string_value))
3546 	      diag_issue_diagnostic
3547 	        ( d_wrong_type,
3548 		 _sar_source_pos2( value_entry ),
3549 		 diag_value_text( op1_entry->b_type ),
3550 		 diag_value_text( sym_k_char_8_value ) );
3551 	    else
3552 	      diag_issue_diagnostic
3553                 ( d_wrong_type,
3554 		 _sar_source_pos2( value_entry ),
3555 		 "wrong",
3556 		 diag_value_text( sym_k_char_8_value  ) );
3557 	    value_entry = sym_az_error_value_entry;
3558 	    res_type = error_arg_type;
3559 	}
3560 	break;
3561 	/*  End fixing CR 5429 */
3562 
3563       case sym_k_valref_op:
3564       {
3565 	  /*
3566 	   ** Copy all the value-related fields from the referenced
3567 	   ** node to the referencing node. All non value-related fields
3568 	   ** are left intact, except that the forward reference flag
3569 	   ** is turned off
3570 	   */
3571 	  value_entry->obj_header.b_flags &= ~sym_m_forward_ref;
3572 	  value_entry->b_type = op1_entry->b_type;
3573 	  value_entry->w_length = op1_entry->w_length;
3574 	  value_entry->b_table_count = op1_entry->b_table_count;
3575 	  value_entry->b_aux_flags = op1_entry->b_aux_flags;
3576 	  value_entry->b_arg_type = op1_entry->b_arg_type;
3577 	  value_entry->b_data_offset = op1_entry->b_data_offset;
3578 	  value_entry->b_pixel_type = op1_entry->b_pixel_type;
3579 	  value_entry->b_charset = op1_entry->b_charset;
3580 	  value_entry->b_direction = op1_entry->b_direction;
3581 	  value_entry->b_enumeration_value_code =
3582 	    op1_entry->b_enumeration_value_code;
3583 	  value_entry->az_first_table_value = op1_entry->az_first_table_value;
3584 	  value_entry->az_charset_value = op1_entry->az_charset_value;
3585 	  /*
3586 	   ** Because of alignment requirements, we can't just move the largest
3587 	   ** field of the union, but actually have to move the correct value
3588 	   ** field based upon the datatype.
3589 	   */
3590 	  switch (op1_entry->b_type)
3591 	  {
3592 	    case sym_k_integer_value:
3593 	    case sym_k_horizontal_integer_value:
3594 	    case sym_k_vertical_integer_value:
3595 	      value_entry->value.l_integer = op1_entry->value.l_integer;
3596 	      value_entry->b_arg_type = op1_entry->b_arg_type;
3597 	      break;
3598 	    case sym_k_float_value:
3599 	    case sym_k_horizontal_float_value:
3600 	    case sym_k_vertical_float_value:
3601 	      value_entry->value.d_real = op1_entry->value.d_real;
3602 	      value_entry->b_arg_type = op1_entry->b_arg_type;
3603 	      break;
3604 	    case sym_k_char_8_value:
3605 	    case sym_k_localized_string_value:
3606 	      value_entry->value.c_value = op1_entry->value.c_value;
3607 	      break;
3608 	    case sym_k_single_float_value:
3609 	      value_entry->value.single_float = op1_entry->value.single_float;
3610 	      break;
3611 	    case sym_k_color_value:
3612 	      value_entry->value.z_color = op1_entry->value.z_color;
3613 	      break;
3614 	    case sym_k_icon_value:
3615 	      value_entry->value.z_icon = op1_entry->value.z_icon;
3616 	      break;
3617 	    default:
3618 	      value_entry->value.az_data = op1_entry->value.az_data;
3619 	      break;
3620 	  }
3621 	  break;
3622       }
3623 
3624       case sym_k_add_op:
3625 	switch (res_type)
3626 	{
3627 	  case integer_arg_type:
3628 	  case horizontal_integer_arg_type:
3629 	  case vertical_integer_arg_type:
3630 	    value_entry->value.l_integer =
3631 	      op1_ptr->integer_value + op2_ptr->integer_value;
3632 	    if (op1_entry->b_arg_type != op2_entry->b_arg_type)
3633 	      {
3634 		diag_issue_diagnostic(d_different_units,
3635 				      _sar_source_pos2(value_entry));
3636 		res_type = error_arg_type;
3637 	      }
3638 	    else value_entry->b_arg_type = op1_entry->b_arg_type;
3639             break;
3640 
3641 	  case float_arg_type:
3642 	  case horizontal_float_arg_type:
3643 	  case vertical_float_arg_type:
3644             value_entry->value.d_real =
3645 	      op1_ptr->real_value + op2_ptr->real_value;
3646 	    if (op1_entry->b_arg_type != op2_entry->b_arg_type)
3647 	      {
3648 		diag_issue_diagnostic(d_different_units,
3649 				      _sar_source_pos2(value_entry));
3650 		res_type = error_arg_type;
3651 	      }
3652 	    else value_entry->b_arg_type = op1_entry->b_arg_type;
3653             break;
3654 
3655 	  case single_float_arg_type:
3656             value_entry->value.single_float =
3657 	      op1_ptr->single_float_value + op2_ptr->single_float_value;
3658             break;
3659 
3660 	  case error_arg_type:
3661             break;
3662 
3663 	  default:
3664 	    diag_issue_diagnostic
3665 	      ( d_cannot_convert,
3666 	       _sar_source_pos2( value_entry),
3667 	       diag_value_text( op1_entry->b_type ),
3668 	       diag_value_text( value_entry->b_type ) );
3669 	    res_type = error_arg_type;
3670         }
3671 	break;
3672 
3673       case sym_k_subtract_op:
3674 	switch (res_type)
3675 	{
3676 	  case integer_arg_type:
3677 	  case horizontal_integer_arg_type:
3678 	  case vertical_integer_arg_type:
3679 	    value_entry->value.l_integer =
3680 	      op1_ptr->integer_value - op2_ptr->integer_value;
3681 	    if (op1_entry->b_arg_type != op2_entry->b_arg_type)
3682 	      {
3683 		diag_issue_diagnostic(d_different_units,
3684 				      _sar_source_pos2(value_entry));
3685 		res_type = error_arg_type;
3686 	      }
3687 	    else value_entry->b_arg_type = op1_entry->b_arg_type;
3688 	    break;
3689 
3690 	  case float_arg_type:
3691 	  case horizontal_float_arg_type:
3692 	  case vertical_float_arg_type:
3693 	    value_entry->value.d_real =
3694 	      op1_ptr->real_value - op2_ptr->real_value;
3695 	    if (op1_entry->b_arg_type != op2_entry->b_arg_type)
3696 	      {
3697 		diag_issue_diagnostic(d_different_units,
3698 				      _sar_source_pos2(value_entry));
3699 		res_type = error_arg_type;
3700 	      }
3701 	    else value_entry->b_arg_type = op1_entry->b_arg_type;
3702 	    break;
3703 
3704 	  case single_float_arg_type:
3705             value_entry->value.single_float =
3706 	      op1_ptr->single_float_value - op2_ptr->single_float_value;
3707             break;
3708 
3709 	  case error_arg_type:
3710 	    break;
3711 
3712 	  default:
3713 	    diag_issue_diagnostic
3714 	      ( d_cannot_convert,
3715 	       _sar_source_pos2( value_entry),
3716 	       diag_value_text( op1_entry->b_type ),
3717 	       diag_value_text( value_entry->b_type ) );
3718 	    res_type = error_arg_type;
3719 	}
3720 	break;
3721 
3722       case sym_k_multiply_op:
3723 	switch (res_type)
3724 	{
3725 	  case integer_arg_type:
3726 	  case horizontal_integer_arg_type:
3727 	  case vertical_integer_arg_type:
3728 	    value_entry->value.l_integer =
3729 	      op1_ptr->integer_value * op2_ptr->integer_value;
3730 	    if (op1_entry->b_arg_type != op2_entry->b_arg_type)
3731 	      {
3732 		diag_issue_diagnostic(d_different_units,
3733 				      _sar_source_pos2(value_entry));
3734 		res_type = error_arg_type;
3735 	      }
3736 	    else value_entry->b_arg_type = op1_entry->b_arg_type;
3737 	    break;
3738 
3739 	  case float_arg_type:
3740 	  case horizontal_float_arg_type:
3741 	  case vertical_float_arg_type:
3742 	    value_entry->value.d_real =
3743 	      op1_ptr->real_value * op2_ptr->real_value;
3744 	    if (op1_entry->b_arg_type != op2_entry->b_arg_type)
3745 	      {
3746 		diag_issue_diagnostic(d_different_units,
3747 				      _sar_source_pos2(value_entry));
3748 		res_type = error_arg_type;
3749 	      }
3750 	    else value_entry->b_arg_type = op1_entry->b_arg_type;
3751 	    break;
3752 
3753 	  case single_float_arg_type:
3754             value_entry->value.single_float =
3755 	      op1_ptr->single_float_value * op2_ptr->single_float_value;
3756             break;
3757 
3758 	  case error_arg_type:
3759 	    break;
3760 
3761 	  default:
3762 	    diag_issue_diagnostic
3763 	      ( d_cannot_convert,
3764 	       _sar_source_pos2( value_entry),
3765 	       diag_value_text( op1_entry->b_type ),
3766 	       diag_value_text( value_entry->b_type ) );
3767 	    res_type = error_arg_type;
3768 	}
3769 	break;
3770 
3771       case sym_k_divide_op:
3772 	switch (res_type)
3773 	{
3774 	  case integer_arg_type:
3775 	  case horizontal_integer_arg_type:
3776 	  case vertical_integer_arg_type:
3777 	    value_entry->value.l_integer =
3778 	      op1_ptr->integer_value / op2_ptr->integer_value;
3779 	    if (op1_entry->b_arg_type != op2_entry->b_arg_type)
3780 	      {
3781 		diag_issue_diagnostic(d_different_units,
3782 				      _sar_source_pos2(value_entry));
3783 		res_type = error_arg_type;
3784 	      }
3785 	    else value_entry->b_arg_type = op1_entry->b_arg_type;
3786 	    break;
3787 
3788 	  case float_arg_type:
3789 	  case horizontal_float_arg_type:
3790 	  case vertical_float_arg_type:
3791 	    value_entry->value.d_real =
3792 	      op1_ptr->real_value / op2_ptr->real_value;
3793 	    if (op1_entry->b_arg_type != op2_entry->b_arg_type)
3794 	      {
3795 		diag_issue_diagnostic(d_different_units,
3796 				      _sar_source_pos2(value_entry));
3797 		res_type = error_arg_type;
3798 	      }
3799 	    else value_entry->b_arg_type = op1_entry->b_arg_type;
3800 	    break;
3801 
3802 	  case single_float_arg_type:
3803             value_entry->value.single_float =
3804 	      op1_ptr->single_float_value / op2_ptr->single_float_value;
3805             break;
3806 
3807 	  case error_arg_type:
3808 	    break;
3809 
3810 	  default:
3811 	    diag_issue_diagnostic
3812 	      ( d_cannot_convert,
3813 	       _sar_source_pos2( value_entry),
3814 	       diag_value_text( op1_entry->b_type ),
3815 	       diag_value_text( value_entry->b_type ) );
3816 	    res_type = error_arg_type;
3817 	}
3818 	break;
3819 
3820       case sym_k_left_shift_op:
3821 	switch (res_type)
3822 	{
3823 	  case integer_arg_type:
3824 	  {
3825 	      int	    shift_count;
3826 
3827 	      shift_count = op2_ptr->integer_value;
3828 
3829 	      if ((shift_count < 0) || (shift_count > 32))
3830 		goto error_occurred;
3831 
3832 	      value_entry->value.l_integer =
3833 		op1_ptr->integer_value << op2_ptr->integer_value;
3834 
3835 	      break;
3836 	  }
3837 
3838 	case error_arg_type:
3839 	  break;
3840 
3841 	default:
3842 	  diag_issue_diagnostic
3843 	    ( d_cannot_convert,
3844 	     _sar_source_pos2( value_entry),
3845 	     diag_value_text( op1_entry->b_type ),
3846 	     diag_value_text( value_entry->b_type ) );
3847 	  res_type = error_arg_type;
3848       }
3849 	break;
3850 
3851       case sym_k_right_shift_op:
3852 	switch (res_type)
3853 	{
3854 	  case integer_arg_type:
3855 	  {
3856 	      int	    shift_count;
3857 
3858 	      shift_count = op2_ptr->integer_value;
3859 
3860 	      if ((shift_count < 0) || (shift_count > 32))
3861 		goto error_occurred;
3862 
3863 	      value_entry->value.l_integer =
3864 		op1_ptr->integer_value >> op2_ptr->integer_value;
3865 
3866 	      break;
3867 	  }
3868 
3869 	case error_arg_type:
3870 	  break;
3871 
3872 	default:
3873 	  diag_issue_diagnostic
3874 	    ( d_cannot_convert,
3875 	     _sar_source_pos2( value_entry),
3876 	     diag_value_text( op1_entry->b_type ),
3877 	     diag_value_text( value_entry->b_type ) );
3878 	  res_type = error_arg_type;
3879       }
3880 	break;
3881 
3882       case sym_k_and_op:
3883 	switch (res_type)
3884 	{
3885 	  case integer_arg_type:
3886 	  case boolean_arg_type:
3887 	    value_entry->value.l_integer =
3888 	      op1_ptr->integer_value & op2_ptr->integer_value;
3889 	    break;
3890 	  case char_arg_type:
3891 	  case lstr_arg_type:
3892 	    sar_cat_value_entry( &cat_str_entry, op1_entry, op2_entry );
3893 	    value_entry->b_type = cat_str_entry->b_type;
3894 	    if (cat_str_entry->b_type == sym_k_compound_string_value)
3895 	    {
3896 		res_type = cstr_arg_type;
3897 		value_entry->az_first_table_value = cat_str_entry->az_first_table_value;
3898 	    }
3899 	    value_entry->b_charset = cat_str_entry->b_charset;
3900 	    value_entry->b_direction = cat_str_entry->b_direction;
3901 	    value_entry->value.c_value = cat_str_entry->value.c_value;
3902 	    value_entry->w_length = cat_str_entry->w_length;
3903 	    cat_str_entry->value.c_value = NULL;
3904 	    sem_free_node (( sym_entry_type *)cat_str_entry);
3905 	    break;
3906 	  case cstr_arg_type:
3907 	    sar_cat_value_entry( &cat_str_entry, op1_entry, op2_entry );
3908 	    value_entry->b_type = cat_str_entry->b_type;
3909 	    value_entry->b_charset = cat_str_entry->b_charset;
3910 	    value_entry->b_direction = cat_str_entry->b_direction;
3911 	    value_entry->value.xms_value = cat_str_entry->value.xms_value;
3912 	    value_entry->az_first_table_value =
3913 	      cat_str_entry->az_first_table_value;
3914 	    value_entry->w_length = cat_str_entry->w_length;
3915 	    sem_evaluate_value_cs (value_entry);
3916 	    cat_str_entry->value.xms_value = NULL;
3917 	    sem_free_node (( sym_entry_type *)cat_str_entry);
3918 	    break;
3919 	  case error_arg_type:
3920 	    break;
3921 
3922 	  default:
3923 	    diag_issue_diagnostic
3924 	      ( d_cannot_convert,
3925 	       _sar_source_pos2( value_entry),
3926 	       diag_value_text( op1_entry->b_type ),
3927 	       diag_value_text( value_entry->b_type ) );
3928 	    res_type = error_arg_type;
3929 	}
3930 	break;
3931 
3932       case sym_k_or_op:
3933 	switch (res_type)
3934 	{
3935 	  case integer_arg_type:
3936 	  case boolean_arg_type:
3937 	    value_entry->value.l_integer =
3938 	      op1_ptr->integer_value | op2_ptr->integer_value;
3939 	    break;
3940 
3941 	  case error_arg_type:
3942 	    break;
3943 
3944 	  default:
3945 	    diag_issue_diagnostic
3946 	      ( d_cannot_convert,
3947 	       _sar_source_pos2( value_entry),
3948 	       diag_value_text( op1_entry->b_type ),
3949 	       diag_value_text( value_entry->b_type ) );
3950 	    res_type = error_arg_type;
3951 	}
3952 	break;
3953 
3954       case sym_k_xor_op:
3955 	switch (res_type)
3956 	{
3957 	  case integer_arg_type:
3958 	  case boolean_arg_type:
3959 	    value_entry->value.l_integer =
3960 	      op1_ptr->integer_value ^ op2_ptr->integer_value;
3961 	    break;
3962 
3963 	  case error_arg_type:
3964 	    break;
3965 
3966 	  default:
3967 	    diag_issue_diagnostic
3968 	      ( d_cannot_convert,
3969 	       _sar_source_pos2( value_entry),
3970 	       diag_value_text( op1_entry->b_type ),
3971 	       diag_value_text( value_entry->b_type ) );
3972 	    res_type = error_arg_type;
3973 	}
3974 	break;
3975       default:
3976 	_assert( FALSE, "unexpected operator" );
3977     }	/* End of switch statement */
3978 
3979 
3980   continue_after_error:
3981 
3982     /*
3983      ** Set data type for expression value.  If binary operation, use res_type
3984      ** because conversions may have taken place.  Otherwise use b_type from
3985      ** the operand of the unary operator.
3986      */
3987 
3988     if (value_entry->b_expr_opr == sym_k_valref_op)
3989       value_entry->b_type = op1_entry->b_type;
3990     else
3991       switch (res_type)
3992       {
3993         case boolean_arg_type:
3994 	  value_entry->b_type = sym_k_bool_value;
3995 	  break;
3996 
3997         case integer_arg_type:
3998 	  value_entry->b_type = sym_k_integer_value;
3999 	  break;
4000 
4001         case single_float_arg_type:
4002 	  value_entry->b_type = sym_k_single_float_value;
4003 	  break;
4004 
4005         case float_arg_type:
4006 	  value_entry->b_type = sym_k_float_value;
4007 	  break;
4008 
4009 	case horizontal_integer_arg_type:
4010 	  value_entry->b_type = sym_k_horizontal_integer_value;
4011 	  break;
4012 
4013 	case vertical_integer_arg_type:
4014 	  value_entry->b_type = sym_k_vertical_integer_value;
4015 	  break;
4016 
4017 	case horizontal_float_arg_type:
4018 	  value_entry->b_type = sym_k_horizontal_float_value;
4019 	  break;
4020 
4021 	case vertical_float_arg_type:
4022 	  value_entry->b_type = sym_k_vertical_float_value;
4023 	  break;
4024 
4025 	case keysym_arg_type:
4026 	  value_entry->b_type = sym_k_keysym_value;
4027 	  break;
4028 
4029         case char_arg_type:
4030 	case lstr_arg_type:
4031 	  value_entry->b_type = sym_k_char_8_value;
4032 	  break;
4033 
4034         case cstr_arg_type:
4035 	  value_entry->b_type = sym_k_compound_string_value;
4036 	  break;
4037 
4038         case wcstr_arg_type:
4039 	  value_entry->b_type = sym_k_wchar_string_value;
4040 	  break;
4041 
4042 	case font_arg_type:
4043 	  value_entry->b_type = sym_k_font_value;
4044 	  break;
4045 
4046 	case fontset_arg_type:
4047 	  value_entry->b_type = sym_k_fontset_value;
4048 	  break;
4049 
4050 	case color_arg_type:
4051 	  value_entry->b_type = sym_k_color_value;
4052 	  break;
4053 
4054 	  /*  Begin fixing CR 5429 */
4055 	case classrec_arg_type:
4056 	  value_entry->b_type = sym_k_class_rec_name_value;
4057 	  break;
4058 	  /*  End fixing CR 5429 */
4059 
4060 	case xbitmap_arg_type:
4061 	  value_entry->b_type = sym_k_xbitmapfile_value;
4062 	  break;
4063 
4064 	case reason_arg_type:
4065 	  value_entry->b_type = sym_k_reason_value;
4066 	  break;
4067 
4068 	case argument_arg_type:
4069 	  value_entry->b_type = sym_k_argument_value;
4070 	  break;
4071 
4072 	case font_table_arg_type:
4073 	  value_entry->b_type = sym_k_font_table_value;
4074 	  break;
4075 
4076 	case error_arg_type:
4077 	  value_entry->b_type = sym_k_error_value;
4078 	  break;
4079 
4080         default:
4081 	  _assert( FALSE, "unexpected type" );
4082       }
4083 
4084     /*
4085      ** indicate that this expression has been evaluated
4086      */
4087 
4088     value_entry->b_aux_flags |= sym_m_exp_eval;
4089     in_expr = FALSE;
4090     return value_entry;
4091 
4092     /*
4093      **	Point where errors are transferred
4094      */
4095 
4096   error_occurred:
4097 
4098     diag_issue_diagnostic
4099       ( d_out_range,
4100        _sar_source_pos2( value_entry ),
4101        value_text[ (int)res_type ],
4102        ""
4103        );
4104     res_type = error_arg_type;
4105     diag_reset_overflow_handler();
4106 
4107     goto continue_after_error;
4108 }
4109 
4110 
validate_arg(operand_entry,operator)4111 int validate_arg( operand_entry, operator)
4112 
4113 sym_value_entry_type    *operand_entry;
4114 int	    		operator;
4115 
4116 {
4117 
4118     char    operand_type;
4119 
4120     operand_type = operand_entry->b_type;
4121 
4122     if (operand_type == sym_k_error_value )
4123         return error_arg_type;
4124 
4125     if ((( 1 << operand_type ) & legal_operand_type[ operator ]) == 0)
4126     {
4127 	diag_issue_diagnostic
4128 	    ( d_operand_type,
4129 	      _sar_source_pos2( operand_entry ),
4130 	      diag_value_text( operand_type ),
4131 	      operator_symbol[ operator ]
4132 	    );
4133 	return error_arg_type;
4134     }
4135 
4136     if ((operand_entry->obj_header.b_flags & sym_m_imported) != 0)
4137     {
4138 	sym_value_entry_type    *value_entry;
4139 
4140 	value_entry = operand_entry;
4141 
4142 	diag_issue_diagnostic
4143 	    ( d_nonpvt,
4144 	      _sar_source_pos2( operand_entry ),
4145 	      value_entry->obj_header.az_name->c_text
4146 	    );
4147 	return error_arg_type;
4148     }
4149 
4150     switch (operand_type)
4151     {
4152     case sym_k_bool_value:
4153 	return boolean_arg_type;
4154 
4155     case sym_k_integer_value:
4156 	return integer_arg_type;
4157 
4158     case sym_k_float_value:
4159 	return float_arg_type;
4160 
4161     case sym_k_single_float_value:
4162 	return single_float_arg_type;
4163 
4164     case sym_k_horizontal_integer_value:
4165 	return horizontal_integer_arg_type;
4166 
4167     case sym_k_vertical_integer_value:
4168 	return vertical_integer_arg_type;
4169 
4170     case sym_k_horizontal_float_value:
4171 	return horizontal_float_arg_type;
4172 
4173     case sym_k_vertical_float_value:
4174 	return vertical_float_arg_type;
4175 
4176     case sym_k_char_8_value:
4177 	return char_arg_type;
4178 
4179     case sym_k_compound_string_value:
4180 	return cstr_arg_type;
4181 
4182     case sym_k_localized_string_value:
4183 	return lstr_arg_type;
4184 
4185     case sym_k_wchar_string_value:
4186 	return wcstr_arg_type;
4187 
4188     case sym_k_font_value:
4189 	return font_arg_type;
4190 
4191     case sym_k_fontset_value:
4192 	return fontset_arg_type;
4193 
4194     case sym_k_color_value:
4195 	return color_arg_type;
4196 
4197     default:
4198 	return error_arg_type;
4199     }
4200 }
4201 
4202 /*
4203 **++
4204 **  FUNCTIONAL DESCRIPTION:
4205 **
4206 **      This function converts a value to floating point.
4207 **
4208 **  FORMAL PARAMETERS:
4209 **
4210 **      operand_entry	    frame of the value to convert
4211 **	data_value	    data structure to hold float result
4212 **
4213 **  IMPLICIT INPUTS:
4214 **
4215 **      none
4216 **
4217 **  IMPLICIT OUTPUTS:
4218 **
4219 **      none
4220 **
4221 **  FUNCTION VALUE:
4222 **
4223 **      float_arg_type	    if operation succeeds
4224 **	error_arg_type	    if operation fails
4225 **
4226 **  SIDE EFFECTS:
4227 **
4228 **      none
4229 **
4230 **--
4231 **/
sem_convert_to_float(operand_entry,data_value)4232 int	sem_convert_to_float(operand_entry, data_value)
4233 
4234 sym_value_entry_type	*operand_entry;
4235 data_value_type	    	*data_value;
4236 
4237 {
4238     switch (operand_entry->b_type)
4239     {
4240     case sym_k_error_value:
4241 	return error_arg_type;
4242 
4243     case sym_k_integer_value:
4244     case sym_k_horizontal_integer_value:
4245     case sym_k_vertical_integer_value:
4246     case sym_k_bool_value:
4247 	data_value->real_value = operand_entry->value.l_integer;
4248 	return float_arg_type;
4249 
4250       case sym_k_single_float_value: /* single float data type RAP */
4251 	data_value->real_value = operand_entry->value.single_float;
4252 	return float_arg_type;
4253 
4254     case sym_k_float_value:
4255     case sym_k_horizontal_float_value:
4256     case sym_k_vertical_float_value:
4257 	data_value->real_value = operand_entry->value.d_real;
4258 	return float_arg_type;
4259 
4260     default:
4261 	_assert( FALSE, "unexpected operand type" );
4262     }
4263     return error_arg_type;
4264 }
4265 
4266 /*
4267 **++
4268 **  FUNCTIONAL DESCRIPTION:
4269 **
4270 **      This function converts a value to type integer
4271 **
4272 **  FORMAL PARAMETERS:
4273 **
4274 **      operand_entry	    frame of the value to convert
4275 **	data_value	    data structure to hold integer result
4276 **
4277 **  IMPLICIT INPUTS:
4278 **
4279 **      none
4280 **
4281 **  IMPLICIT OUTPUTS:
4282 **
4283 **      none
4284 **
4285 **  FUNCTION VALUE:
4286 **
4287 **      integer_arg_type    if operation succeeds
4288 **	error_arg_type	    if operation fails
4289 **
4290 **  SIDE EFFECTS:
4291 **
4292 **      none
4293 **
4294 **--
4295 **/
sem_convert_to_integer(operand_entry,data_value)4296 int	sem_convert_to_integer(operand_entry, data_value)
4297 
4298 sym_value_entry_type	*operand_entry;
4299 data_value_type	    	*data_value;
4300 
4301 {
4302     int			    res_type = 0;
4303 
4304     uil_az_error_env_valid = TRUE;
4305     if (setjmp(uil_az_error_env_block) == 0 )
4306       {
4307 	switch (operand_entry->b_type)
4308 	  {
4309 	  case sym_k_error_value:
4310 	    res_type = error_arg_type;
4311 	    break;
4312 
4313 	  case sym_k_integer_value:
4314 	  case sym_k_horizontal_integer_value:
4315 	  case sym_k_vertical_integer_value:
4316 	  case sym_k_bool_value:
4317 	    data_value->integer_value = operand_entry->value.l_integer;
4318 	    res_type = integer_arg_type;
4319 	    break;
4320 
4321 	  case sym_k_float_value:
4322 	  case sym_k_horizontal_float_value:
4323 	  case sym_k_vertical_float_value:
4324 	    data_value->integer_value = operand_entry->value.d_real;
4325 	    res_type = integer_arg_type;
4326 	    break;
4327 
4328 	  case sym_k_single_float_value: /* single float data type RAP */
4329 	    data_value->integer_value =
4330 	      (int) operand_entry->value.single_float;
4331 	    res_type = integer_arg_type;
4332 	    break;
4333 
4334 	  default:
4335 	    _assert( FALSE, "unexpected operand type" );
4336 	  }
4337 
4338 	uil_az_error_env_valid = FALSE;
4339 	return res_type;
4340       }
4341     else
4342       {
4343 	diag_issue_diagnostic
4344 	  ( d_out_range,
4345 	   _sar_source_pos2( operand_entry ),
4346 	   value_text[ integer_arg_type ],
4347 	   ""
4348 	   );
4349 	diag_reset_overflow_handler();
4350 	uil_az_error_env_valid = FALSE;
4351 	return error_arg_type;
4352       }
4353 }
4354 
4355 /*
4356 **++
4357 **  FUNCTIONAL DESCRIPTION:
4358 **
4359 **      This function converts a value to single floating point.
4360 **  (RAP single float data type)
4361 **
4362 **  FORMAL PARAMETERS:
4363 **
4364 **      operand_entry	    symbol table entry of the value to convert
4365 **	data_value	    data structure to hold float result
4366 **
4367 **  IMPLICIT INPUTS:
4368 **
4369 **      none
4370 **
4371 **  IMPLICIT OUTPUTS:
4372 **
4373 **      none
4374 **
4375 **  FUNCTION VALUE:
4376 **
4377 **      single_float_arg_type	    if operation succeeds
4378 **	error_arg_type   	    if operation fails
4379 **
4380 **  SIDE EFFECTS:
4381 **
4382 **      none
4383 **
4384 **--
4385 **/
sem_convert_to_single_float(operand_entry,data_value)4386 int	sem_convert_to_single_float(operand_entry, data_value)
4387 
4388 sym_value_entry_type	    *operand_entry;
4389 data_value_type	    *data_value;
4390 
4391 {
4392     switch (operand_entry->b_type)
4393     {
4394     case sym_k_error_value:
4395 	return error_arg_type;
4396 
4397     case sym_k_integer_value:
4398     case sym_k_horizontal_integer_value:
4399     case sym_k_vertical_integer_value:
4400     case sym_k_bool_value:
4401 	data_value->single_float_value = (float)operand_entry->value.l_integer;
4402 	return single_float_arg_type;
4403 
4404     case sym_k_float_value:
4405     case sym_k_horizontal_float_value:
4406     case sym_k_vertical_float_value:
4407 	data_value->single_float_value = (float)operand_entry->value.d_real;
4408 	return single_float_arg_type;
4409 
4410     default:
4411 	_assert( FALSE, "unexpected operand type" );
4412     }
4413     return error_arg_type;
4414 }
4415 
4416 /*
4417 **++
4418 **  FUNCTIONAL DESCRIPTION:
4419 **
4420 **      This function converts a value to an error - just needed to
4421 **	fill a slot in the conversion table.
4422 **
4423 **  FORMAL PARAMETERS:
4424 **
4425 **      operand_entry	    frame of the value to convert
4426 **	data_value	    not used
4427 **
4428 **  IMPLICIT INPUTS:
4429 **
4430 **      none
4431 **
4432 **  IMPLICIT OUTPUTS:
4433 **
4434 **      none
4435 **
4436 **  FUNCTION VALUE:
4437 **
4438 **	error_arg_type
4439 **
4440 **  SIDE EFFECTS:
4441 **
4442 **      none
4443 **
4444 **--
4445 **/
sem_convert_to_error(operand_entry,data_value)4446 int	sem_convert_to_error(operand_entry, data_value)
4447 
4448 sym_value_entry_type	*operand_entry;
4449 data_value_type	    	*data_value;
4450 
4451 {
4452     return error_arg_type;
4453 }
4454 
4455 /*
4456 **++
4457 **  FUNCTIONAL DESCRIPTION:
4458 **
4459 **      This function processes the concatenation of 2 strings.
4460 **
4461 **  FORMAL PARAMETERS:
4462 **
4463 **      operator_entry	[in/out] pointer to resultant value stack frame
4464 **      op1_entry	[in] pointer to operand 1 value frame
4465 **      op2_entry	[in] pointer to operand 2 value frame
4466 **
4467 **  IMPLICIT INPUTS:
4468 **
4469 **      none
4470 **
4471 **  IMPLICIT OUTPUTS:
4472 **
4473 **      none
4474 **
4475 **  FUNCTION VALUE:
4476 **
4477 **      void
4478 **
4479 **  SIDE EFFECTS:
4480 **
4481 **      error message is issued if value is out of range
4482 **
4483 **--
4484 **/
4485 
sar_cat_value_entry(target_entry,op1_entry,op2_entry)4486 void	sar_cat_value_entry( target_entry, op1_entry, op2_entry )
4487 
4488 sym_value_entry_type	    **target_entry;
4489 sym_value_entry_type	    *op1_entry;
4490 sym_value_entry_type	    *op2_entry;
4491 
4492 {
4493 
4494 /*
4495 **  For pcc conversion, use defines instead of this enum.
4496 **
4497 **    enum op_state
4498 **    {
4499 **	error=0, simple, compound,
4500 **    };
4501 */
4502 
4503 #define		k_op_state_error	0
4504 #define		k_op_state_simple	1
4505 #define		k_op_state_compound	2
4506 #define		k_op_state_localized	4
4507 
4508     int			    target_type;
4509     sym_value_entry_type    *value1_entry;
4510     sym_value_entry_type    *value2_entry;
4511     unsigned int	    op1_state;
4512     unsigned int	    op2_state;
4513 
4514     /*
4515     **  The target type is dependent on the type of the sources.  If both
4516     **	operands are primitive and have the same writing direction and
4517     **	charset, the result is still of that type.  If both operands are
4518     **	localized strings, the result is a localized string. If not, the result
4519     **	is a compound string.
4520     */
4521 
4522     switch (op1_entry->b_type)
4523     {
4524     case sym_k_char_8_value:
4525 	op1_state = k_op_state_simple;
4526 	break;
4527     case sym_k_compound_string_value:
4528 	op1_state = k_op_state_compound;
4529 	break;
4530     case sym_k_localized_string_value:
4531 	op1_state = k_op_state_localized;
4532 	break;
4533     case sym_k_error_value:
4534 	op1_state = k_op_state_error;
4535 	break;
4536     default:
4537 	diag_issue_diagnostic
4538 	    ( d_wrong_type,
4539 	      _sar_source_pos2( op1_entry ),
4540 	      diag_value_text( op1_entry->b_type),
4541 	      "string or compound string" );
4542 	op1_state = k_op_state_error;
4543     }
4544 
4545     switch (op2_entry->b_type)
4546     {
4547     case sym_k_char_8_value:
4548 	op2_state = k_op_state_simple;
4549 	break;
4550     case sym_k_compound_string_value:
4551 	op2_state = k_op_state_compound;
4552 	break;
4553     case sym_k_localized_string_value:
4554 	op2_state = k_op_state_localized;
4555 	break;
4556     case sym_k_error_value:
4557 	op2_state = k_op_state_error;
4558 	break;
4559     default:
4560 	diag_issue_diagnostic
4561 	    ( d_wrong_type,
4562 	      _sar_source_pos2( op2_entry ),
4563 	      diag_value_text( op2_entry->b_type),
4564 	      "string or compound string" );
4565 	op2_state = k_op_state_error;
4566     }
4567 
4568     value1_entry = op1_entry;
4569     value2_entry = op2_entry;
4570 
4571     /*
4572     **	Verify that both operands are private values
4573     */
4574     /* Begin fixing OSF CR 5509 */
4575     if ((op1_entry->obj_header.b_flags & (sym_m_private|sym_m_exported)) == 0)
4576 	{
4577 	op1_state = k_op_state_error;
4578 	diag_issue_diagnostic
4579 		(d_nonpvt,
4580 		_sar_source_pos2 (op1_entry),
4581 		value1_entry->obj_header.az_name->c_text );
4582 	}
4583     if ((op2_entry->obj_header.b_flags & (sym_m_private|sym_m_exported)) == 0)
4584 	{
4585 	op2_state = k_op_state_error;
4586 	diag_issue_diagnostic
4587 		(d_nonpvt,
4588 		_sar_source_pos2 (op2_entry),
4589 		value2_entry->obj_header.az_name->c_text );
4590 	}
4591     /* End fixing OSF CR 5509 */
4592     switch (op1_state + (op2_state<<3))
4593     {
4594     /*
4595     **	This is the case of appending two simple strings or a simple string
4596     **	and a localized	string.  Just append them
4597     **	unless they have different directions or the first one has the separate
4598     **	attribute.
4599     */
4600     case k_op_state_simple + (k_op_state_simple<<3):
4601     case k_op_state_simple + (k_op_state_localized<<3):
4602     case k_op_state_localized + (k_op_state_simple<<3):
4603 	if ((value1_entry->b_charset == value2_entry->b_charset)
4604 	    &&
4605 	    ((value1_entry->b_direction) == (value2_entry->b_direction))
4606 	    &&
4607 	    ((value1_entry->b_aux_flags & sym_m_separate) == 0))
4608 	{
4609 	    *target_entry = (sym_value_entry_type *)
4610 		sem_cat_str_to_str
4611 		    (value1_entry, FALSE,
4612 		     value2_entry, FALSE);
4613 	    target_type  = sym_k_char_8_value;
4614 	}
4615 	else
4616 	{
4617 	    *target_entry = (sym_value_entry_type *) sem_create_cstr( );
4618 	    sem_append_str_to_cstr
4619 		(*target_entry,
4620 		 value1_entry, FALSE);
4621 	    sem_append_str_to_cstr
4622 		(*target_entry,
4623 		 value2_entry, FALSE);
4624 	    sem_evaluate_value_cs(*target_entry);
4625 	    target_type  = sym_k_compound_string_value;
4626 	}
4627 	break;
4628 
4629     /*
4630     **	This is the case of one simple/localized and one compound string.
4631     **	Change the
4632     **	simple/localized to a compound and append them together.  Depend on
4633     **	the append
4634     **	routine to do the right thing.
4635     */
4636     case k_op_state_simple + (k_op_state_compound<<3):
4637     case k_op_state_localized + (k_op_state_compound<<3):
4638 	*target_entry = (sym_value_entry_type *) sem_create_cstr( );
4639 	sem_append_str_to_cstr
4640 	    (*target_entry,
4641 	     value1_entry, FALSE);
4642 	sem_evaluate_value_cs(*target_entry);
4643 	/*
4644 	 * We must evaluate both  entries to the XmStringConcat routine so
4645 	 * that it will work properly.   However this MAY be a pointer to
4646 	 * a compound string, use that value instead or we will concat a
4647 	 * NULL value and lose part of the string.
4648 	 */
4649 	if ((value2_entry->az_first_table_value == NULL) &&
4650 	    (value2_entry->value.xms_value == NULL))
4651 	    value2_entry->value.xms_value =
4652 		value2_entry->az_exp_op1->value.xms_value;
4653 	else
4654 	    sem_evaluate_value_cs(value2_entry);
4655 
4656 	(*target_entry)->value.xms_value =
4657 	    XmStringConcat((*target_entry)->value.xms_value,
4658 			   value2_entry->value.xms_value);
4659 	target_type  = sym_k_compound_string_value;
4660 	break;
4661 
4662     /*
4663     **	This is the case of one simple/localized and one compound string.
4664     **  Append the simple/localized to the compound.
4665     */
4666     case k_op_state_compound + (k_op_state_simple<<3):
4667     case k_op_state_compound + (k_op_state_localized<<3):
4668 
4669 	*target_entry = (sym_value_entry_type *) sem_create_cstr( );
4670 	sem_append_str_to_cstr
4671 	    (*target_entry,
4672 	     value2_entry, FALSE);
4673 	sem_evaluate_value_cs (*target_entry);
4674 	/*
4675 	 * We must evaluate both  entries to the XmStringConcat routine so
4676 	 * that it will work properly.   However this MAY be a pointer to
4677 	 * a compound string, use that value instead or we will concat a
4678 	 * NULL value and lose part of the string.
4679 	 */
4680 	if ((value1_entry->az_first_table_value == NULL) &&
4681 	    (value1_entry->value.xms_value == NULL))
4682 	    value1_entry->value.xms_value =
4683 		value1_entry->az_exp_op1->value.xms_value;
4684 	else
4685 	    sem_evaluate_value_cs(value1_entry);
4686 
4687 	(*target_entry)->value.xms_value =
4688 	    XmStringConcat (value1_entry->value.xms_value,
4689 			    (*target_entry)->value.xms_value);
4690 	target_type  = sym_k_compound_string_value;
4691 	break;
4692 
4693     /*
4694     **  This is the case of two compound strings.  Just let the append routine
4695     **  do the right thing.
4696     */
4697     case k_op_state_compound + (k_op_state_compound<<3):
4698 	*target_entry = (sym_value_entry_type *) sem_create_cstr( );
4699 	/*
4700 	 * We must evaluate both  entries to the XmStringConcat routine so
4701 	 * that it will work properly.   However this MAY be a pointer to
4702 	 * a compound string, use that value instead or we will concat a
4703 	 * NULL value and lose part of the string.
4704 	 */
4705 	if ((value1_entry->az_first_table_value == NULL) &&
4706 	    (value1_entry->value.xms_value == NULL))
4707 	    value1_entry->value.xms_value =
4708 		value1_entry->az_exp_op1->value.xms_value;
4709 	else
4710 	    sem_evaluate_value_cs(value1_entry);
4711 
4712 	if ((value2_entry->az_first_table_value == NULL) &&
4713 	    (value2_entry->value.xms_value == NULL))
4714 	    value2_entry->value.xms_value =
4715 		value2_entry->az_exp_op1->value.xms_value;
4716 	else
4717 	    sem_evaluate_value_cs(value2_entry);
4718 
4719 	(*target_entry)->value.xms_value =
4720 	    XmStringConcat(value1_entry->value.xms_value,
4721 			   value2_entry->value.xms_value);
4722 	target_type  = sym_k_compound_string_value;
4723 	break;
4724 
4725     /*
4726     **	This is the case of two localized strings.  Just concatenate them.
4727     */
4728     case k_op_state_localized + (k_op_state_localized<<3):
4729       *target_entry = (sym_value_entry_type *)
4730 	sem_cat_str_to_str
4731 	  (value1_entry, FALSE,
4732 	   value2_entry, FALSE);
4733 	target_type  = sym_k_localized_string_value;
4734 
4735     default:   /* some form of error */
4736 	target_type = sym_k_error_value;
4737 	*target_entry = (sym_value_entry_type *) sym_az_error_value_entry;
4738 	break;
4739     }
4740 
4741 }
4742 
4743