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