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