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[] = "$XConsortium: UilSarObj.c /main/14 1995/07/14 09:37:30 drk $"
26 #endif
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32
33 /*
34 **++
35 ** FACILITY:
36 **
37 ** User Interface Language Compiler (UIL)
38 **
39 ** ABSTRACT:
40 **
41 ** This module contains the semantic action routines for
42 ** object definitions in the UIL.
43 **
44 **--
45 **/
46
47
48 /*
49 **
50 ** INCLUDE FILES
51 **
52 **/
53
54 #include "UilDefI.h"
55
56
57 /*
58 **
59 ** DEFINE and MACRO DEFINITIONS
60 **
61 **/
62
63 /*
64 ** This is a fast algorithm for mapping an integer (_size) to
65 ** 0 _size <= 8
66 ** 1 8 < _size <= 16
67 ** 2 16 < _size <= 32
68 ** 3 32 < _size <= 64
69 ** 4 64 < _size
70 ** The algorithm is based on the notion that the floating pt representation
71 ** of an integer has an exponent that is the log_base2( int ).
72 **
73 ** This algorithm is specific to the VAX. An alternate layout of the
74 ** internal represention of a floating pt number could be supplied for
75 ** other architectures.
76 */
77
78 #define _compute_node_index( _size, _index ) \
79 { unsigned short j, k; \
80 j = (_size); \
81 if (j <= 8) k = 0; \
82 else if (j <= 16) k = 1; \
83 else if (j <= 32) k = 2; \
84 else if (j <= 64) k = 3; \
85 else k = 4; \
86 (_index) = k; \
87 }
88
89
90
91 /*
92 **
93 ** EXTERNAL VARIABLE DECLARATIONS
94 **
95 **/
96
97 extern yystype gz_yynullval;
98 extern yystype yylval;
99
100
101 /*
102 **
103 ** GLOBAL VARIABLE DECLARATIONS
104 **
105 **/
106
107
108
109 /*
110 **
111 ** OWN VARIABLE DECLARATIONS
112 **
113 **/
114
115
116
117 /*
118 **++
119 ** FUNCTIONAL DESCRIPTION:
120 **
121 ** This routine associates the latest comment block
122 ** with the current object frame. RAP
123 **
124 ** FORMAL PARAMETERS:
125 **
126 ** object_frame address of the parse stack frame for this
127 ** object.
128 **
129 **
130 **
131 ** IMPLICIT INPUTS:
132 **
133 ** none
134 **
135 ** IMPLICIT OUTPUTS:
136 **
137 ** none
138 **
139 ** FUNCTION VALUE:
140 **
141 ** void
142 **
143 ** SIDE EFFECTS:
144 **
145 ** the object frame contains the comment for this object.
146 **
147 **--
148 **/
149
sar_assoc_comment(object)150 void sar_assoc_comment( object )
151
152 sym_obj_entry_type *object;
153 {
154
155 object->obj_header.az_comment = (char *)_get_memory(strlen(comment_text)+1);
156 strcpy(object->obj_header.az_comment, comment_text);
157 comment_text[0] = '\0';
158
159 }
160
161
162 /*
163 **++
164 ** FUNCTIONAL DESCRIPTION:
165 **
166 ** This routine creates the symbol node for the object, and
167 ** saves it in the object frame on the parse stack.
168 **
169 ** FORMAL PARAMETERS:
170 **
171 ** object_frame address of the parse stack frame for this
172 ** object.
173 **
174 ** object_type type literal for this object.
175 **
176 ** IMPLICIT INPUTS:
177 **
178 ** none
179 **
180 ** IMPLICIT OUTPUTS:
181 **
182 ** none
183 **
184 ** FUNCTION VALUE:
185 **
186 ** void
187 **
188 ** SIDE EFFECTS:
189 **
190 ** the object frame contains the symbol node for this object.
191 **
192 **--
193 **/
194
sar_create_object(yystype * object_frame,unsigned char object_type)195 void sar_create_object
196 ( yystype *object_frame, unsigned char object_type )
197
198 {
199
200 sym_name_entry_type * name_entry;
201 sym_obj_entry_type * obj_entry;
202 int node_size = 0;
203 yystype * source_frame;
204
205 source_frame = & yylval;
206
207 if (object_frame->b_tag != sar_k_null_frame)
208 {
209
210 /*
211 ** First we check on the name to see if it has been previously used.
212 ** This function returns NULL if name cannot be used.
213 */
214 name_entry = (sym_name_entry_type *) sem_dcl_name (object_frame);
215 }
216 else
217 {
218 name_entry = NULL;
219 }
220
221 /* Determine the size of the symbol node to allocate. */
222
223 switch (object_type)
224 {
225 case sym_k_gadget_entry:
226 case sym_k_widget_entry:
227 node_size = sym_k_widget_entry_size;
228 break;
229
230 case sym_k_list_entry:
231 node_size = sym_k_list_entry_size;
232 break;
233
234 default:
235 _assert (FALSE, "unexpected object type");
236 break;
237 }
238
239 /*
240 * Allocate the symbol node, connect it to its name, and save source info
241 */
242 obj_entry = (sym_obj_entry_type *)
243 sem_allocate_node (object_type, node_size);
244 if (name_entry != NULL)
245 {
246 name_entry->az_object = (sym_entry_type *)obj_entry;
247 obj_entry->obj_header.az_name = (sym_name_entry_type *)name_entry;
248 }
249 _sar_save_source_pos (&obj_entry->header, source_frame );
250 sar_assoc_comment(obj_entry); /* preserve comments */
251 /*
252 * Set the definition in progress bit.
253 */
254 obj_entry->obj_header.b_flags |= sym_m_def_in_progress;
255
256 /*
257 * Save the symbol node in the object frame.
258 */
259 object_frame->b_tag = sar_k_object_frame;
260 object_frame->b_type = object_type;
261 object_frame->value.az_symbol_entry = (sym_entry_type *)obj_entry;
262
263 }
264
265
266 /*
267 **++
268 ** FUNCTIONAL DESCRIPTION:
269 **
270 ** This routine creates the symbol node for the child, and
271 ** saves it in the object frame on the parse stack.
272 **
273 ** FORMAL PARAMETERS:
274 **
275 ** object_frame address of the parse stack frame for this
276 ** object.
277 **
278 ** IMPLICIT INPUTS:
279 **
280 ** none
281 **
282 ** IMPLICIT OUTPUTS:
283 **
284 ** none
285 **
286 ** FUNCTION VALUE:
287 **
288 ** void
289 **
290 ** SIDE EFFECTS:
291 **
292 ** the object frame contains the symbol node for this child.
293 **
294 **--
295 **/
296
sar_create_child(yystype * object_frame)297 void sar_create_child
298 ( yystype *object_frame )
299
300 {
301 sym_obj_entry_type * obj_entry;
302 yystype * source_frame;
303
304 source_frame = & yylval;
305
306 /*
307 * Allocate the symbol node, set its type, and save source info
308 */
309 obj_entry = (sym_obj_entry_type *)
310 sem_allocate_node (sym_k_child_entry, sym_k_widget_entry_size);
311 obj_entry->header.b_type =
312 object_frame->value.az_keyword_entry->b_subclass;
313
314 _sar_save_source_pos (&obj_entry->header, source_frame );
315 sar_assoc_comment(obj_entry); /* preserve comments */
316 /*
317 * Indicate in compress table that this child type is used.
318 */
319 uil_child_compr[(int)obj_entry->header.b_type] = 1;
320
321 /*
322 * Set the definition in progress bit.
323 */
324 obj_entry->obj_header.b_flags |= sym_m_def_in_progress;
325
326 /*
327 * Save the symbol node in the object frame.
328 */
329 object_frame->b_tag = sar_k_object_frame;
330 object_frame->b_type = sym_k_child_entry;
331 object_frame->value.az_symbol_entry = (sym_entry_type *)obj_entry;
332
333 }
334
335
336 /*
337 **++
338 ** FUNCTIONAL DESCRIPTION:
339 **
340 ** This routine creates and links a section node into the symbol table
341 **
342 ** FORMAL PARAMETERS:
343 **
344 ** id_frame the token frame with the id for this entry.
345 **
346 ** IMPLICIT INPUTS:
347 **
348 ** sym_az_current_section_entry global pointer to the "current" section
349 **
350 ** IMPLICIT OUTPUTS:
351 **
352 ** none
353 **
354 ** FUNCTION VALUE:
355 **
356 ** void
357 **
358 ** SIDE EFFECTS:
359 **
360 **--
361 **/
362
sar_link_section(id_frame)363 void sar_link_section ( id_frame )
364
365 yystype * id_frame;
366
367 {
368 sym_section_entry_type * section_entry;
369
370 /*
371 * Allocate a section entry. Link this entry of of the current section list
372 */
373 section_entry = (sym_section_entry_type *) sem_allocate_node
374 (sym_k_section_entry, sym_k_section_entry_size);
375 section_entry->next = (sym_entry_type *)
376 sym_az_current_section_entry->entries;
377 sym_az_current_section_entry->entries = (sym_entry_type *) section_entry;
378 section_entry->entries = id_frame->value.az_symbol_entry;
379
380 }
381
382 /*
383 **++
384 ** FUNCTIONAL DESCRIPTION:
385 **
386 ** This routine saves the source information about where this
387 ** semi-colon entry ends.
388 **
389 ** FORMAL PARAMETERS:
390 **
391 ** semi_frame the token frame for the terminating semi-colon
392 ** for this entry.
393 **
394 ** IMPLICIT INPUTS:
395 **
396 ** sym_az_current_section_entry global pointer to the
397 ** "current" section list
398 **
399 ** IMPLICIT OUTPUTS:
400 **
401 ** none
402 **
403 ** FUNCTION VALUE:
404 **
405 ** void
406 **
407 ** SIDE EFFECTS:
408 **
409 ** none
410 **
411 **--
412 **/
413
sar_save_src_semicolon_pos(semi_frame)414 void sar_save_src_semicolon_pos (semi_frame)
415
416 yystype * semi_frame;
417
418 {
419 sym_section_entry_type * section_entry;
420
421 section_entry = (sym_section_entry_type *)
422 sym_az_current_section_entry->entries;
423 _sar_save_source_pos (§ion_entry->entries->header, semi_frame);
424
425 }
426
427
428 /*
429 **++
430 ** FUNCTIONAL DESCRIPTION:
431 **
432 ** This function saves the title end source for lists (i.e. "ARGUMENTS",
433 ** "CALLBACKS", "PROCEDURES", and "CONTROLS"). The source saved here
434 ** should be "}" or posibly an id_ref.
435 **
436 ** PARAMETERS:
437 **
438 ** close_frame ptr to token frame for the closing source
439 **
440 ** IMPLICIT INPUTS:
441 **
442 ** the "current" list on the frame stack as returned by sem_find_object
443 **
444 ** IMPLICIT OUTPUTS:
445 **
446 ** none
447 **
448 ** FUNCTION VALUE:
449 **
450 ** void
451 **
452 ** SIDE EFFECTS:
453 **
454 ** none
455 **--
456 **/
457
sar_save_list_end(close_frame)458 void sar_save_list_end (close_frame)
459
460 yystype *close_frame;
461
462 {
463 sym_list_entry_type * list_entry;
464 yystype * list_frame;
465
466 /*
467 ** Search the syntax stack for the object frame.
468 */
469
470 list_frame = sem_find_object (close_frame - 1);
471 list_entry = (sym_list_entry_type *) list_frame->value.az_symbol_entry;
472
473 _sar_save_source_pos ( &list_entry->header , close_frame );
474
475 }
476
477 /*
478 **++
479 ** FUNCTIONAL DESCRIPTION:
480 **
481 ** This function saves the end source for just about any type
482 ** of entry.
483 **
484 ** PARAMETERS:
485 **
486 ** close_frame ptr to token frame for the closing source (probably
487 ** a semi-colon).
488 **
489 ** IMPLICIT INPUTS:
490 **
491 ** the "current" list on the frame stack as returned by sem_find_object
492 **
493 ** IMPLICIT OUTPUTS:
494 **
495 ** none
496 **
497 ** FUNCTION VALUE:
498 **
499 ** void
500 **
501 ** SIDE EFFECTS:
502 **
503 ** none
504 **--
505 **/
506
sar_save_src_entry_end(close_frame,entry_frame)507 void sar_save_src_entry_end (close_frame, entry_frame)
508
509 yystype *close_frame;
510 yystype *entry_frame;
511
512 {
513 sym_entry_type * entry;
514
515 /*
516 ** Extract the entry from the frame.
517 */
518
519 entry = (sym_entry_type *) entry_frame->value.az_symbol_entry;
520
521 /*
522 ** Case on the type of entry (source gets put in a different spot for
523 ** control entries).
524 */
525
526 if (entry->header.b_tag == sym_k_control_entry)
527 {
528 sym_control_entry_type *control_entry = (sym_control_entry_type *)entry;
529
530 _sar_save_source_pos (&control_entry->az_con_obj->header, close_frame);
531 }
532
533 /*
534 ** Save the source info in the default place
535 */
536
537 _sar_save_source_pos ( &entry->header , close_frame );
538
539 }
540
541 /*
542 **++
543 ** FUNCTIONAL DESCRIPTION:
544 **
545 ** This routine sets flags in the stack entry for the object.
546 **
547 ** FORMAL PARAMETERS:
548 **
549 ** current_frame address of the current syntax stack frame
550 **
551 ** mask mask of flags to be set.
552 **
553 ** IMPLICIT INPUTS:
554 **
555 ** none
556 **
557 ** IMPLICIT OUTPUTS:
558 **
559 ** none
560 **
561 ** FUNCTION VALUE:
562 **
563 ** void
564 **
565 ** SIDE EFFECTS:
566 **
567 ** none
568 **
569 **--
570 **/
571
sar_set_object_flags(yystype * current_frame,unsigned char mask)572 void sar_set_object_flags
573
574 (yystype *current_frame, unsigned char mask )
575
576 {
577
578 sym_obj_entry_type * obj_entry;
579 yystype * object_frame;
580
581 /* Search the syntax stack for the object frame. */
582
583 object_frame = sem_find_object (current_frame - 1);
584 obj_entry = (sym_obj_entry_type *) object_frame->value.az_symbol_entry;
585
586 /* Set the flags for the object entry. */
587
588 obj_entry->obj_header.b_flags |= mask;
589
590 /* If this is an exported or private object and it has a name,
591 ** make an external entry for it.
592 */
593
594 if ((mask & (sym_m_exported | sym_m_private)) &&
595 (obj_entry->obj_header.az_name != NULL))
596 {
597 sym_make_external_def (obj_entry->obj_header.az_name);
598 }
599
600 }
601
602
603 /*
604 **++
605 ** FUNCTIONAL DESCRIPTION:
606 **
607 ** This routine unsets flags in the stack entry for the object.
608 **
609 ** FORMAL PARAMETERS:
610 **
611 ** current_frame address of the current syntax stack frame
612 **
613 ** mask mask of flags to be unset.
614 **
615 ** IMPLICIT INPUTS:
616 **
617 ** none
618 **
619 ** IMPLICIT OUTPUTS:
620 **
621 ** none
622 **
623 ** FUNCTION VALUE:
624 **
625 ** void
626 **
627 ** SIDE EFFECTS:
628 **
629 ** none
630 **
631 **--
632 **/
633
sar_unset_object_flags(yystype * current_frame,unsigned char mask)634 void sar_unset_object_flags
635
636 (yystype *current_frame, unsigned char mask )
637
638 {
639 yystype * object_frame;
640
641 /* Search the syntax stack for the object frame. */
642
643 object_frame = sem_find_object (current_frame - 1);
644
645 /* Unset the flags for the object entry. */
646
647 object_frame->b_flags &= ~mask;
648
649 }
650
651
652 /*
653 **++
654 ** FUNCTIONAL DESCRIPTION:
655 **
656 ** This routine sets the type in the stack entry for the (list) object.
657 **
658 ** FORMAL PARAMETERS:
659 **
660 ** current_frame address of the current syntax stack frame
661 **
662 ** IMPLICIT INPUTS:
663 **
664 ** none
665 **
666 ** IMPLICIT OUTPUTS:
667 **
668 ** none
669 **
670 ** FUNCTION VALUE:
671 **
672 ** void
673 **
674 ** SIDE EFFECTS:
675 **
676 ** none
677 **
678 **--
679 **/
680
sar_set_list_type(current_frame)681 void sar_set_list_type
682 ( current_frame )
683
684 yystype * current_frame;
685
686 {
687
688 sym_obj_entry_type * obj_entry;
689 yystype * list_frame;
690
691 /* Search the syntax stack for the list frame. */
692 list_frame = sem_find_object (current_frame-1);
693 obj_entry = (sym_obj_entry_type *) list_frame->value.az_symbol_entry;
694
695 /* Set the type for the list entry. */
696 obj_entry->header.b_type = current_frame->b_type;
697
698 }
699
700
701 /*
702 **++
703 ** FUNCTIONAL DESCRIPTION:
704 **
705 ** This routine sets the type in the stack entry for the (widget) object.
706 **
707 ** FORMAL PARAMETERS:
708 **
709 ** current_frame address of the current syntax stack frame
710 **
711 ** IMPLICIT INPUTS:
712 **
713 ** none
714 **
715 ** IMPLICIT OUTPUTS:
716 **
717 ** none
718 **
719 ** FUNCTION VALUE:
720 **
721 ** void
722 **
723 ** SIDE EFFECTS:
724 **
725 ** none
726 **
727 **--
728 **/
729
sar_set_object_class(current_frame)730 void sar_set_object_class
731 ( current_frame )
732
733 yystype * current_frame;
734
735 {
736
737 sym_obj_entry_type * obj_entry;
738 yystype * object_frame;
739
740 /* Search the syntax stack for the object frame. */
741 object_frame = sem_find_object (current_frame-1);
742 obj_entry = (sym_obj_entry_type *) object_frame->value.az_symbol_entry;
743
744 /* Set the type for the object entry. */
745 obj_entry->header.b_type =
746 current_frame->value.az_keyword_entry->b_subclass;
747
748 /*
749 ** Indicate in compression table that this object type is used.
750 ** Note that user defined widgets don't get compression code entires.
751 ** We always identify user defined widgets as MrmwcUnknown.
752 */
753 if ( obj_entry->header.b_type != uil_sym_user_defined_object )
754 uil_widget_compr[(int)obj_entry->header.b_type] = 1;
755
756 }
757
758
759 /*
760 **++
761 ** FUNCTIONAL DESCRIPTION:
762 **
763 ** This routine sets the variant in the stack entry for the object.
764 **
765 ** FORMAL PARAMETERS:
766 **
767 ** current_frame address of the current syntax stack frame
768 **
769 ** IMPLICIT INPUTS:
770 **
771 ** none
772 **
773 ** IMPLICIT OUTPUTS:
774 **
775 ** none
776 **
777 ** FUNCTION VALUE:
778 **
779 ** void
780 **
781 ** SIDE EFFECTS:
782 **
783 ** none
784 **
785 **--
786 **/
787
sar_set_object_variant(current_frame)788 void sar_set_object_variant
789 ( current_frame )
790
791 yystype * current_frame;
792
793 {
794
795 sym_obj_entry_type * obj_entry;
796 yystype * object_frame;
797
798 /* Search the syntax stack for the object frame. */
799
800 object_frame = sem_find_object (current_frame - 1);
801 obj_entry = (sym_obj_entry_type *) object_frame->value.az_symbol_entry;
802
803 /* Set the variant for the object entry. */
804
805 switch (current_frame->b_type)
806 {
807
808 /* Use the module default for this object type. */
809 case 0:
810 {
811 unsigned int obj_type;
812
813 /*
814 * Pick up gadget variant (or widget variant) as specified
815 * by the module tables and the gadget variants
816 */
817 obj_type = obj_entry->header.b_type;
818 if (uil_urm_variant[obj_type] == sym_k_gadget_entry)
819 {
820 obj_entry->obj_header.b_flags |= sym_m_obj_is_gadget;
821 obj_entry->header.b_type = uil_gadget_variants [obj_type];
822 }
823
824 break;
825 }
826
827 case sym_k_widget_entry:
828 break;
829
830 case sym_k_gadget_entry:
831 {
832 unsigned int obj_type;
833
834 /*
835 * Check if gadgets are supported for this object type.
836 * If so, change the object type to the matching code for
837 * the widget class which is the gadget.
838 */
839 obj_type = obj_entry->header.b_type;
840 if (uil_gadget_variants[obj_type] == 0)
841 {
842 yystype * source_frame;
843
844 source_frame = & yylval;
845 diag_issue_diagnostic
846 (d_gadget_not_sup,
847 _sar_source_position (source_frame ),
848 diag_object_text(obj_type),
849 diag_object_text(obj_type) );
850 }
851 else
852 {
853 obj_entry->obj_header.b_flags |= sym_m_obj_is_gadget;
854 obj_entry->header.b_type = uil_gadget_variants [obj_type];
855 }
856
857 break;
858 }
859
860 default:
861 _assert (FALSE, "unexpected variant type");
862 break;
863 }
864
865 /*
866 ** If this object is a gadget, mark that gadgets of this type have been
867 ** used so we can later assign it a compression code. This is a safety
868 ** set against the actual widget class.
869 */
870
871 if ((obj_entry->obj_header.b_flags & sym_m_obj_is_gadget) != 0)
872 uil_widget_compr[(int)obj_entry->header.b_type] = 1;
873
874 }
875
876
877 /*
878 **++
879 ** FUNCTIONAL DESCRIPTION:
880 **
881 ** This routine finds the object frame on the parse stack.
882 **
883 ** FORMAL PARAMETERS:
884 **
885 ** current_frame address of the current parse stack frame.
886 **
887 ** IMPLICIT INPUTS:
888 **
889 ** none
890 **
891 ** IMPLICIT OUTPUTS:
892 **
893 ** none
894 **
895 ** FUNCTION VALUE:
896 **
897 ** address of the parse stack frame for this object.
898 **
899 ** SIDE EFFECTS:
900 **
901 ** none
902 **
903 **--
904 **/
905
sem_find_object(current_frame)906 yystype * sem_find_object ( current_frame )
907
908 yystype * current_frame;
909
910 {
911
912 yystype * object_frame;
913
914 object_frame = current_frame;
915
916 /* Search the syntax stack for the object frame. */
917
918 while ( (object_frame->b_tag != sar_k_object_frame) &&
919 (object_frame->b_tag != sar_k_module_frame) )
920 object_frame--;
921
922 if (object_frame->b_tag != sar_k_object_frame)
923 _assert (FALSE, "missing object frame on the parser stack");
924
925 return (object_frame);
926
927 }
928
929 /*
930 **++
931 ** FUNCTIONAL DESCRIPTION:
932 **
933 ** This routine processes a reference to an object in the
934 ** UIL. The reference may be a forward reference.
935 **
936 ** FORMAL PARAMETERS:
937 **
938 ** ref_frame address of the parse stack frame for
939 ** the object reference.
940 **
941 ** IMPLICIT INPUTS:
942 **
943 ** none
944 **
945 ** IMPLICIT OUTPUTS:
946 **
947 ** none
948 **
949 ** FUNCTION VALUE:
950 **
951 ** none
952 **
953 ** SIDE EFFECTS:
954 **
955 ** none
956 **
957 **--
958 **/
959
sar_object_reference(ref_frame)960 void sar_object_reference ( ref_frame )
961 yystype * ref_frame;
962
963 {
964 yystype * obj_frame;
965 sym_obj_entry_type * obj_entry;
966 sym_name_entry_type * ref_name;
967 sym_obj_entry_type * ref_entry;
968 sym_value_entry_type * ref_value;
969 boolean invalid_ref;
970
971 yystype * source_frame;
972
973 source_frame = & yylval;
974
975 /* Search the syntax stack for the object frame. */
976
977 obj_frame = sem_find_object (ref_frame - 1);
978 obj_entry = (sym_obj_entry_type *) obj_frame->value.az_symbol_entry;
979 ref_name = (sym_name_entry_type *) ref_frame->value.az_symbol_entry;
980 ref_value = (sym_value_entry_type *) ref_name->az_object;
981 ref_entry = (sym_obj_entry_type *) ref_name->az_object;
982
983 /* Check if this name was previously defined for a different usage. */
984
985 if (ref_entry != NULL)
986 {
987 if ( ref_entry->header.b_tag==sym_k_widget_entry ||
988 ref_entry->header.b_tag==sym_k_gadget_entry ||
989 ref_entry->header.b_tag==sym_k_child_entry )
990 invalid_ref =
991 (ref_entry->header.b_tag!=obj_entry->header.b_tag) ||
992 ((ref_entry->header.b_type!=obj_entry->header.b_type) &&
993 (uil_gadget_variants[(int)ref_entry->header.b_type]!=
994 obj_entry->header.b_type) &&
995 (uil_gadget_variants[(int)obj_entry->header.b_type]!=
996 ref_entry->header.b_type));
997 else
998 invalid_ref =
999 (ref_entry->header.b_tag!=obj_entry->header.b_tag) ||
1000 (ref_entry->header.b_type!=obj_entry->header.b_type);
1001
1002 if ( invalid_ref )
1003 {
1004
1005 char * expected_type, * found_type;
1006
1007 if (ref_entry->header.b_tag == sym_k_list_entry)
1008 found_type = diag_tag_text (ref_entry->header.b_type);
1009 else if (ref_entry->header.b_tag == sym_k_widget_entry)
1010 found_type = diag_object_text (ref_entry->header.b_type);
1011 else if (ref_entry->header.b_tag == sym_k_gadget_entry)
1012 found_type = diag_object_text (ref_entry->header.b_type);
1013 else if (ref_entry->header.b_tag == sym_k_value_entry)
1014 found_type = diag_value_text
1015 (((sym_value_entry_type *) ref_entry)->b_type);
1016 else
1017 found_type = "";
1018
1019 if (obj_entry->header.b_tag == sym_k_list_entry)
1020 expected_type =
1021 diag_tag_text (obj_entry->header.b_type);
1022 else
1023 expected_type =
1024 diag_object_text (obj_entry->header.b_type);
1025
1026 diag_issue_diagnostic
1027 ( d_obj_type,
1028 _sar_source_position ( source_frame ),
1029 found_type,
1030 diag_tag_text (ref_entry->header.b_tag),
1031 expected_type,
1032 diag_tag_text (obj_entry->header.b_tag) );
1033
1034 obj_entry->header.b_tag = sym_k_error_entry;
1035
1036 return;
1037 }
1038 }
1039
1040 switch (obj_entry->header.b_tag)
1041 {
1042
1043 case sym_k_list_entry:
1044 {
1045
1046 /* Add this entry to the list. A copy of the list will be made. */
1047
1048 if ((ref_value != 0) &&
1049 ((ref_value->obj_header.b_flags & sym_m_forward_ref) == 0))
1050 {
1051 ref_frame->value.az_symbol_entry = (sym_entry_type *)ref_entry;
1052 sar_add_list_entry (ref_frame);
1053 }
1054 else
1055 sar_add_forward_list_entry (ref_frame);
1056
1057 break;
1058 }
1059
1060 case sym_k_gadget_entry:
1061 case sym_k_widget_entry:
1062 {
1063 int make_fwd_ref;
1064
1065 /* Mark the widget as referenced. */
1066
1067 ref_name->b_flags |= sym_m_referenced;
1068
1069 /* Mark the referencing object */
1070
1071 obj_entry->obj_header.b_flags |= sym_m_obj_is_reference;
1072
1073 /* Forward references are allowed for widgets or gadgets. */
1074
1075 if (ref_entry == NULL)
1076 make_fwd_ref = TRUE;
1077 else
1078 {
1079
1080 /* A widget can reference itself; treat it as a forward reference. */
1081
1082 if (ref_entry->obj_header.b_flags & sym_m_def_in_progress)
1083 make_fwd_ref = TRUE;
1084 else
1085 make_fwd_ref = FALSE;
1086 }
1087
1088 if (make_fwd_ref)
1089 {
1090 /* Add forward reference entry for this widget. */
1091
1092 sym_make_forward_ref
1093 (ref_frame,
1094 obj_entry->header.b_type,
1095 (char*)& obj_entry->obj_header.az_reference );
1096 }
1097 else
1098 {
1099 /* Save this reference in the widget. */
1100
1101 obj_entry->obj_header.az_reference = (sym_entry_type *)ref_entry;
1102 }
1103
1104 break;
1105 }
1106
1107 default:
1108 {
1109 _assert (FALSE, "unexpected object reference type");
1110 break;
1111 }
1112 }
1113
1114 }
1115
1116 /*
1117 **++
1118 ** FUNCTIONAL DESCRIPTION:
1119 **
1120 ** This routine updates the parent list of every object in the controls
1121 ** list(s) for this object. Parent lists are required in order to check
1122 ** constraint arguments.
1123 **
1124 ** FORMAL PARAMETERS:
1125 **
1126 ** control_list_frame address of the parse stack frame for
1127 ** the control list.
1128 **
1129 ** IMPLICIT INPUTS:
1130 **
1131 ** none
1132 **
1133 ** IMPLICIT OUTPUTS:
1134 **
1135 ** none
1136 **
1137 ** FUNCTION VALUE:
1138 **
1139 ** none
1140 **
1141 ** SIDE EFFECTS:
1142 **
1143 ** none
1144 **
1145 **--
1146 **/
1147
sar_update_parent_list(control_list_frame)1148 void sar_update_parent_list
1149 ( control_list_frame )
1150
1151 yystype * control_list_frame;
1152
1153 {
1154 yystype * widget_frame;
1155 sym_widget_entry_type * widget_entry;
1156 sym_list_entry_type * control_list_entry;
1157
1158 /* Search the syntax stack for the widget frame. */
1159
1160 widget_frame = sem_find_object (control_list_frame - 1);
1161 widget_entry = (sym_widget_entry_type *)
1162 widget_frame->value.az_symbol_entry;
1163
1164 _assert (widget_entry->header.b_tag == sym_k_widget_entry ||
1165 widget_entry->header.b_tag == sym_k_gadget_entry ||
1166 widget_entry->header.b_tag == sym_k_child_entry,
1167 "widget missing from the stack");
1168
1169 /* Get the control_list entry from the widget */
1170
1171 control_list_entry = (sym_list_entry_type *)
1172 control_list_frame->value.az_symbol_entry;
1173
1174 _assert ((control_list_entry->header.b_tag == sym_k_list_entry ||
1175 control_list_entry->header.b_tag == sym_k_error_entry),
1176 "list entry missing");
1177
1178 /* The control list contains control list entries as well as nested lists,
1179 ** which in turn contain list entries and nested lists.
1180 ** We need to call a recursive routine to traverse all the entries.
1181 */
1182
1183 parent_list_traverse(widget_entry, control_list_entry);
1184
1185 }
1186
1187
1188 /*
1189 **++
1190 ** FUNCTIONAL DESCRIPTION:
1191 **
1192 ** This routine recursively traverses a control_list. Control lists
1193 ** may contain control list entries as well as nested control lists.
1194 **
1195 ** This routine also updates the parent list of every object in the
1196 ** controls list(s) for this object. Parent lists are required in order
1197 ** to check constraint arguments.
1198 **
1199 ** FORMAL PARAMETERS:
1200 **
1201 ** widget_entry the widget to be entered in lists
1202 ** control_list_entry A control_list or nested control list
1203 **
1204 **
1205 ** IMPLICIT INPUTS:
1206 **
1207 ** none
1208 **
1209 ** IMPLICIT OUTPUTS:
1210 **
1211 ** none
1212 **
1213 ** FUNCTION VALUE:
1214 **
1215 ** none
1216 **
1217 ** SIDE EFFECTS:
1218 **
1219 ** none
1220 **
1221 **--
1222 **/
1223
parent_list_traverse(widget_entry,control_list_entry)1224 void parent_list_traverse (widget_entry, control_list_entry)
1225 sym_widget_entry_type *widget_entry;
1226 sym_list_entry_type *control_list_entry;
1227
1228 {
1229 sym_obj_entry_type *control_list_member;
1230 sym_control_entry_type *control_entry;
1231 sym_nested_list_entry_type *nested_control_list_entry;
1232 sym_widget_entry_type *control_widget;
1233 int found;
1234 sym_forward_ref_entry_type *fwd_ref_entry;
1235 sym_parent_list_type *parent_node;
1236 sym_parent_list_type *parent_ptr;
1237
1238
1239 for (control_list_member = (sym_obj_entry_type *)control_list_entry ->
1240 obj_header.az_next;
1241 control_list_member != NULL;
1242 control_list_member = (sym_obj_entry_type *)control_list_member ->
1243 obj_header.az_next)
1244 {
1245 switch (control_list_member->header.b_tag)
1246 {
1247 case sym_k_nested_list_entry:
1248 nested_control_list_entry = (sym_nested_list_entry_type *)
1249 control_list_member;
1250 /* Begin fixing DTS 9497 */
1251 if(nested_control_list_entry->az_list)
1252 parent_list_traverse (widget_entry,
1253 nested_control_list_entry->az_list);
1254 /* End fixing DTS 9497 */
1255 break;
1256 case sym_k_control_entry:
1257 control_entry = (sym_control_entry_type *) control_list_member;
1258
1259 /* Get a pointer to one of the actual widgets in the control list */
1260
1261 control_widget = control_entry->az_con_obj;
1262
1263 /*
1264 ** If it's a widget reference, go find it. If you can't find it, it must
1265 ** be a forward reference. If so, find the forward reference entry for it
1266 ** and update it with a pointer to its parent.
1267 */
1268
1269 if ( control_widget->
1270 obj_header.b_flags & sym_m_obj_is_reference)
1271 if ( control_widget->obj_header.az_reference == NULL )
1272 {
1273
1274 /* Forward reference. Update forward reference entry. */
1275
1276 found = FALSE;
1277 for (fwd_ref_entry = sym_az_forward_ref_chain;
1278 ((fwd_ref_entry != NULL) && (found == FALSE));
1279 fwd_ref_entry = fwd_ref_entry->az_next_ref)
1280 {
1281 if (fwd_ref_entry->a_update_location ==
1282 (char *) & control_widget->
1283 obj_header.az_reference)
1284 {
1285 found = TRUE;
1286 fwd_ref_entry->parent = widget_entry;
1287 }
1288 }
1289 }
1290 else
1291 {
1292 /* A widget reference, but already defined. Go update its entry. */
1293
1294 control_widget = (sym_widget_entry_type *)
1295 control_widget->obj_header.az_reference;
1296 found = FALSE;
1297 for (parent_ptr = control_widget->parent_list;
1298 ((parent_ptr != NULL) && (found == FALSE));
1299 parent_ptr = parent_ptr->next)
1300 {
1301 if (parent_ptr->parent == widget_entry)
1302 found = TRUE;
1303 }
1304 if (found == FALSE)
1305 {
1306 parent_node = (sym_parent_list_type *)
1307 sem_allocate_node (sym_k_parent_list_entry,
1308 sym_k_parent_list_size);
1309 parent_node->next = control_widget->parent_list;
1310 control_widget->parent_list = parent_node;
1311 parent_node->parent = widget_entry;
1312 }
1313 }
1314 else
1315 {
1316 /* An inline widget definition. Go update its entry. */
1317
1318 found = FALSE;
1319 for (parent_ptr = control_widget->parent_list;
1320 ((parent_ptr != NULL) && (found == FALSE));
1321 parent_ptr = parent_ptr->next)
1322 {
1323 if (parent_ptr->parent == widget_entry)
1324 found = TRUE;
1325 }
1326 if (found == FALSE)
1327 {
1328 parent_node = (sym_parent_list_type *)
1329 sem_allocate_node (sym_k_parent_list_entry,
1330 sym_k_parent_list_size);
1331 parent_node->next = control_widget->parent_list;
1332 control_widget->parent_list = parent_node;
1333 parent_node->parent = widget_entry;
1334 }
1335 }
1336 }
1337 }
1338
1339 }
1340
1341
1342 /*
1343 **++
1344 ** FUNCTIONAL DESCRIPTION:
1345 **
1346 ** This routine saves a widget feature in the widget symbol node.
1347 **
1348 ** FORMAL PARAMETERS:
1349 **
1350 ** feature_frame address of the parse stack frame for
1351 ** the widget feature.
1352 **
1353 ** IMPLICIT INPUTS:
1354 **
1355 ** none
1356 **
1357 ** IMPLICIT OUTPUTS:
1358 **
1359 ** none
1360 **
1361 ** FUNCTION VALUE:
1362 **
1363 ** none
1364 **
1365 ** SIDE EFFECTS:
1366 **
1367 ** none
1368 **
1369 **--
1370 **/
1371
sar_save_feature(feature_frame)1372 void sar_save_feature
1373 ( feature_frame )
1374
1375 yystype * feature_frame;
1376
1377 {
1378 yystype * widget_frame;
1379 sym_widget_entry_type * widget_entry;
1380 sym_entry_type * feature_entry;
1381 sym_entry_type * * ptr = NULL;
1382
1383 yystype * source_frame;
1384
1385 source_frame = & yylval;
1386
1387 /* Search the syntax stack for the widget frame. */
1388
1389 widget_frame = sem_find_object (feature_frame - 1);
1390 widget_entry = (sym_widget_entry_type *)
1391 widget_frame->value.az_symbol_entry;
1392
1393 _assert (widget_entry->header.b_tag == sym_k_widget_entry ||
1394 widget_entry->header.b_tag == sym_k_gadget_entry ||
1395 widget_entry->header.b_tag == sym_k_child_entry,
1396 "widget missing from the stack");
1397
1398 feature_entry = feature_frame->value.az_symbol_entry;
1399
1400 _assert ((feature_entry->header.b_tag == sym_k_list_entry ||
1401 feature_entry->header.b_tag == sym_k_error_entry),
1402 "list entry missing");
1403
1404 switch (feature_entry->header.b_type)
1405 {
1406
1407 case sym_k_argument_entry:
1408 ptr = (sym_entry_type * *) & widget_entry->az_arguments;
1409 break;
1410
1411 case sym_k_control_entry:
1412 ptr = (sym_entry_type * *) & widget_entry->az_controls;
1413 break;
1414
1415 case sym_k_callback_entry:
1416 ptr = (sym_entry_type * *) & widget_entry->az_callbacks;
1417 break;
1418
1419 case sym_k_error_entry:
1420 return;
1421
1422 default:
1423 _assert (FALSE, "unexpected widget feature");
1424 break;
1425 }
1426
1427 /* Check for duplicate features. */
1428
1429 if (* ptr != NULL)
1430 {
1431 diag_issue_diagnostic
1432 ( d_dup_list,
1433 _sar_source_position ( source_frame ),
1434 diag_tag_text (feature_entry->header.b_type),
1435 diag_tag_text (feature_entry->header.b_tag),
1436 diag_object_text (widget_entry->header.b_type),
1437 diag_tag_text (widget_entry->header.b_tag) );
1438
1439 return;
1440 }
1441
1442 /* Save the feature in the widget. */
1443
1444 (* ptr) = feature_entry;
1445
1446 /* Clear the feature frame from the stack. */
1447
1448 feature_frame->b_tag = sar_k_null_frame;
1449
1450 }
1451
1452 /*
1453 **++
1454 ** FUNCTIONAL DESCRIPTION:
1455 **
1456 ** This routine processes an argument pair for an object.
1457 **
1458 ** FORMAL PARAMETERS:
1459 **
1460 ** argument_frame address of the parse stack frame for
1461 ** the argument reference.
1462 **
1463 ** value_frame address of the parse stack frame for
1464 ** the argument value.
1465 **
1466 ** equals_frame address of the parse stack frame for the
1467 ** equals sign.
1468 **
1469 ** IMPLICIT INPUTS:
1470 **
1471 ** none
1472 **
1473 ** IMPLICIT OUTPUTS:
1474 **
1475 ** none
1476 **
1477 ** FUNCTION VALUE:
1478 **
1479 ** none
1480 **
1481 ** SIDE EFFECTS:
1482 **
1483 ** none
1484 **
1485 **--
1486 **/
sar_save_argument_pair(argument_frame,value_frame,equals_frame)1487 void sar_save_argument_pair
1488 ( argument_frame, value_frame, equals_frame)
1489
1490 yystype * argument_frame;
1491 yystype * value_frame;
1492 yystype * equals_frame;
1493
1494 {
1495
1496 yystype * object_frame;
1497 sym_argument_entry_type * arg_entry;
1498 sym_list_entry_type * list_entry;
1499 sym_value_entry_type * val_value_entry;
1500 sym_value_entry_type * arg_value_entry;
1501 unsigned char actual_tag;
1502
1503 yystype * source_frame;
1504
1505
1506 source_frame = & yylval;
1507
1508 /* Search the syntax stack for the object frame. */
1509
1510 object_frame = sem_find_object (argument_frame - 1);
1511
1512 list_entry = (sym_list_entry_type *)
1513 object_frame->value.az_symbol_entry;
1514
1515 _assert (list_entry->header.b_tag == sym_k_list_entry,
1516 "list entry missing");
1517
1518 arg_value_entry =
1519 (sym_value_entry_type *) argument_frame->value.az_symbol_entry;
1520
1521 _assert (arg_value_entry->header.b_tag == sym_k_value_entry,
1522 "argument value entry missing");
1523
1524 /*
1525 ** Save the source information (?)
1526 */
1527
1528 _sar_save_source_info ( &arg_value_entry->header , argument_frame ,
1529 argument_frame );
1530
1531 val_value_entry = (sym_value_entry_type *) value_frame->value.az_symbol_entry;
1532 actual_tag = val_value_entry->header.b_tag;
1533
1534 /* Create and fill in the argument node. */
1535
1536 arg_entry = (sym_argument_entry_type *) sem_allocate_node (
1537 sym_k_argument_entry, sym_k_argument_entry_size);
1538
1539 /*
1540 ** If the argument is a forward reference, we'll patch in the
1541 ** address of the the referenced arg between passes. Otherwise,
1542 ** just point to the referenced arg node.
1543 */
1544
1545 if ((argument_frame->b_flags & sym_m_forward_ref) != 0)
1546 sym_make_value_forward_ref (argument_frame,
1547 (char*)&(arg_entry->az_arg_name), sym_k_patch_add);
1548 else
1549 arg_entry->az_arg_name =
1550 (sym_value_entry_type *) argument_frame->value.az_symbol_entry;
1551
1552 /*
1553 ** If the argument value is a forward reference, we'll patch in the
1554 ** address of the the referenced arg value between passes. Otherwise,
1555 ** just point to the referenced arg value node.
1556 */
1557
1558 if ((value_frame->b_flags & sym_m_forward_ref) != 0)
1559 sym_make_value_forward_ref (value_frame,
1560 (char*)&(arg_entry->az_arg_value), sym_k_patch_add);
1561 else
1562 arg_entry->az_arg_value = val_value_entry;
1563
1564 argument_frame->b_tag = sar_k_null_frame;
1565 argument_frame->value.az_symbol_entry = (sym_entry_type *) arg_entry;
1566
1567
1568 }
1569
1570 /*
1571 **++
1572 ** FUNCTIONAL DESCRIPTION:
1573 **
1574 ** This routine processes a reason to procedure or procedure list binding
1575 ** for a callback object in UIL.
1576 **
1577 ** FORMAL PARAMETERS:
1578 **
1579 ** reason_frame address of the parse stack frame for
1580 ** the reason reference.
1581 **
1582 ** proc_ref_frame address of the parse stack frame for
1583 ** the procedure reference.
1584 **
1585 ** equals_frame address if the parse stack frame for
1586 ** the equals sign.
1587 **
1588 ** IMPLICIT INPUTS:
1589 **
1590 ** none
1591 **
1592 ** IMPLICIT OUTPUTS:
1593 **
1594 ** none
1595 **
1596 ** FUNCTION VALUE:
1597 **
1598 ** none
1599 **
1600 ** SIDE EFFECTS:
1601 **
1602 ** none
1603 **
1604 **--
1605 **/
1606
sar_save_reason_binding(reason_frame,proc_ref_frame,equals_frame)1607 void sar_save_reason_binding
1608 ( reason_frame, proc_ref_frame, equals_frame )
1609
1610 yystype * reason_frame;
1611 yystype * proc_ref_frame;
1612 yystype * equals_frame;
1613
1614 {
1615
1616 yystype * object_frame;
1617 sym_callback_entry_type * callback_entry;
1618 sym_list_entry_type * list_entry;
1619 yystype * source_frame;
1620
1621 source_frame = & yylval;
1622
1623 /* Search the syntax stack for the object frame. */
1624
1625 object_frame = sem_find_object (reason_frame - 1);
1626
1627 list_entry = (sym_list_entry_type *) object_frame->value.az_symbol_entry;
1628
1629 _assert (list_entry->header.b_tag == sym_k_list_entry,
1630 "list entry missing");
1631
1632 /*
1633 ** Create and fill in the callback node.
1634 */
1635
1636 callback_entry = (sym_callback_entry_type *) sem_allocate_node (
1637 sym_k_callback_entry, sym_k_callback_entry_size);
1638
1639 /*
1640 ** If the reason is a forward reference, we'll patch in the
1641 ** address of the the referenced reason between passes. Otherwise,
1642 ** just point to the referenced reason node.
1643 */
1644
1645 if ((reason_frame->b_flags & sym_m_forward_ref) != 0)
1646 sym_make_value_forward_ref (reason_frame,
1647 (char*)&(callback_entry->az_call_reason_name), sym_k_patch_add);
1648 else
1649 callback_entry->az_call_reason_name =
1650 (sym_value_entry_type *) reason_frame->value.az_symbol_entry;
1651
1652
1653 /*
1654 ** Save source information
1655 */
1656 /* _sar_save_source_info ( &reason_value_entry->header , reason_frame ,
1657 ** reason_frame );
1658 */
1659
1660 /*
1661 ** Note that proc_ref_frame may point to either a procedure reference
1662 ** or to a list of procedure reference nodes
1663 */
1664
1665 if ( proc_ref_frame->b_type == sym_k_list_entry)
1666 callback_entry->az_call_proc_ref_list =
1667 (sym_list_entry_type *) proc_ref_frame->value.az_symbol_entry;
1668 else
1669 callback_entry->az_call_proc_ref =
1670 (sym_proc_ref_entry_type *) proc_ref_frame->value.az_symbol_entry;
1671
1672 reason_frame->b_tag = sar_k_null_frame;
1673 reason_frame->value.az_symbol_entry = (sym_entry_type *) callback_entry;
1674
1675 }
1676
1677 /*
1678 **++
1679 ** FUNCTIONAL DESCRIPTION:
1680 **
1681 ** This routine processes a control clause.
1682 **
1683 ** FORMAL PARAMETERS:
1684 **
1685 ** managed_frame address of the parse stack frame for
1686 ** the managed flag for this control.
1687 **
1688 ** item_frame address of the parse stack frame for
1689 ** the control item object.
1690 **
1691 ** IMPLICIT INPUTS:
1692 **
1693 ** none
1694 **
1695 ** IMPLICIT OUTPUTS:
1696 **
1697 ** none
1698 **
1699 ** FUNCTION VALUE:
1700 **
1701 ** none
1702 **
1703 ** SIDE EFFECTS:
1704 **
1705 ** none
1706 **
1707 **--
1708 **/
1709
sar_save_control_item(managed_frame,item_frame)1710 void sar_save_control_item
1711 ( managed_frame, item_frame )
1712
1713 yystype * managed_frame;
1714 yystype * item_frame;
1715
1716 {
1717
1718 yystype * object_frame;
1719 sym_control_entry_type * control_entry;
1720 sym_list_entry_type * list_entry;
1721 yystype * source_frame;
1722
1723 source_frame = & yylval;
1724
1725 /* Search the syntax stack for the object frame. */
1726
1727 object_frame = sem_find_object (managed_frame - 1);
1728
1729 list_entry =
1730 (sym_list_entry_type *) object_frame->value.az_symbol_entry;
1731
1732 _assert (list_entry->header.b_tag == sym_k_list_entry,
1733 "list entry missing");
1734
1735 /* Verify that this type of item is allowed on this list. */
1736
1737 if (list_entry->header.b_type != sym_k_control_entry)
1738 {
1739 diag_issue_diagnostic
1740 ( d_list_item,
1741 _sar_source_position ( source_frame ),
1742 diag_tag_text (sym_k_control_entry),
1743 diag_tag_text (list_entry->header.b_type),
1744 diag_tag_text (list_entry->header.b_tag) );
1745
1746 return;
1747 }
1748
1749 /* Create and fill in the control node. */
1750
1751 control_entry = (sym_control_entry_type *) sem_allocate_node (
1752 sym_k_control_entry, sym_k_control_entry_size);
1753
1754 control_entry->az_con_obj =
1755 (sym_widget_entry_type *) item_frame->value.az_symbol_entry;
1756
1757 control_entry->obj_header.b_flags = ( item_frame->b_flags |
1758 managed_frame->b_flags );
1759
1760 managed_frame->b_tag =
1761 item_frame->b_tag = sar_k_null_frame;
1762
1763 managed_frame->value.az_symbol_entry = (sym_entry_type *) control_entry;
1764
1765 }
1766
1767 /*
1768 **++
1769 ** FUNCTIONAL DESCRIPTION:
1770 **
1771 ** This routine processes a control clause when an id is created in that
1772 ** clause.
1773 **
1774 ** FORMAL PARAMETERS:
1775 **
1776 ** control_frame address of the parse stack frame for
1777 ** the control list.
1778 **
1779 ** item_frame address of the parse stack frame for
1780 ** the control item id.
1781 **
1782 ** IMPLICIT INPUTS:
1783 **
1784 ** none
1785 **
1786 ** IMPLICIT OUTPUTS:
1787 **
1788 ** none
1789 **
1790 ** FUNCTION VALUE:
1791 **
1792 ** none
1793 **
1794 ** SIDE EFFECTS:
1795 **
1796 ** none
1797 **
1798 **--
1799 **/
1800
sar_save_control_widget(control_frame,item_frame)1801 void sar_save_control_widget
1802 ( control_frame, item_frame )
1803
1804 yystype * control_frame;
1805 yystype * item_frame;
1806
1807 {
1808
1809 yystype * object_frame;
1810 sym_control_entry_type * control_entry;
1811 sym_list_entry_type * list_entry;
1812 yystype * source_frame;
1813 yystype temp_frame;
1814
1815 /*
1816 ** move the item_frame to the control_frame and
1817 ** the control_frame to the null_frame. This is done
1818 ** because the item_frame needs to be second in the list
1819 */
1820
1821 temp_frame = *item_frame;
1822 *item_frame = *control_frame;
1823 *control_frame = temp_frame;
1824
1825 source_frame = & yylval;
1826
1827 /* Search the syntax stack for the object frame. */
1828
1829 object_frame = sem_find_object (control_frame - 1);
1830
1831 list_entry =
1832 (sym_list_entry_type *) object_frame->value.az_symbol_entry;
1833
1834 _assert (list_entry->header.b_tag == sym_k_list_entry,
1835 "list entry missing");
1836
1837 /* Verify that this type of item is allowed on this list. */
1838
1839 if (list_entry->header.b_type != sym_k_control_entry)
1840 {
1841 diag_issue_diagnostic
1842 ( d_list_item,
1843 _sar_source_position ( source_frame ),
1844 diag_tag_text (sym_k_control_entry),
1845 diag_tag_text (list_entry->header.b_type),
1846 diag_tag_text (list_entry->header.b_tag) );
1847
1848 return;
1849 }
1850
1851 /* Create and fill in the control node. */
1852
1853 control_entry = (sym_control_entry_type *) sem_allocate_node
1854 (sym_k_control_entry, sym_k_control_entry_size);
1855
1856 control_entry->az_con_obj =
1857 (sym_widget_entry_type *) item_frame->value.az_symbol_entry;
1858
1859 control_entry->obj_header.b_flags = item_frame->b_flags;
1860
1861 control_frame->b_tag =
1862 item_frame->b_tag = sar_k_null_frame;
1863
1864 control_frame->value.az_symbol_entry = (sym_entry_type *) control_entry;
1865
1866 }
1867
1868 /*
1869 **++
1870 ** FUNCTIONAL DESCRIPTION:
1871 **
1872 ** This routine saves the source for a user defined create procedure
1873 **
1874 ** FORMAL PARAMETERS:
1875 **
1876 ** procedure_frame address of the parse stack frame for
1877 ** the text "PROCEDURE".
1878 **
1879 ** proc_id_frame address of the parse stack frame for
1880 ** the procedure reference.
1881 **
1882 ** proc_arg_frame address of the parse stack frame for
1883 ** the procedure argument value.
1884 **
1885 ** IMPLICIT INPUTS:
1886 **
1887 ** none
1888 **
1889 ** IMPLICIT OUTPUTS:
1890 **
1891 ** none
1892 **
1893 ** FUNCTION VALUE:
1894 **
1895 ** none
1896 **
1897 ** SIDE EFFECTS:
1898 **
1899 ** none
1900 **
1901 **--
1902 **/
1903
sar_save_user_proc_ref_src(procedure_frame,proc_id_frame,proc_arg_frame)1904 void sar_save_user_proc_ref_src
1905 ( procedure_frame, proc_id_frame, proc_arg_frame)
1906
1907 yystype * procedure_frame;
1908 yystype * proc_id_frame;
1909 yystype * proc_arg_frame;
1910
1911 {
1912 sym_proc_ref_entry_type * proc_ref_entry;
1913
1914 proc_ref_entry = (sym_proc_ref_entry_type *)proc_id_frame->value.az_symbol_entry;
1915
1916 /*
1917 ** If the parameter arg clause was ommitted the source info should be null.
1918 ** We want to save the source for the "args" if it is there.
1919 */
1920 _sar_save_source_info (& proc_ref_entry->header, procedure_frame, proc_arg_frame );
1921
1922 }
1923
1924 /*
1925 **++
1926 ** FUNCTIONAL DESCRIPTION:
1927 **
1928 ** This routine processes a procedure reference.
1929 **
1930 ** FORMAL PARAMETERS:
1931 **
1932 ** proc_id_frame address of the parse stack frame for
1933 ** the procedure reference.
1934 **
1935 ** proc_arg_frame address of the parse stack frame for
1936 ** the procedure argument value.
1937 **
1938 ** context indicates whether this is a callback
1939 ** or a user-defined procedure reference.
1940 **
1941 ** IMPLICIT INPUTS:
1942 **
1943 ** none
1944 **
1945 ** IMPLICIT OUTPUTS:
1946 **
1947 ** none
1948 **
1949 ** FUNCTION VALUE:
1950 **
1951 ** none
1952 **
1953 ** SIDE EFFECTS:
1954 **
1955 ** none
1956 **
1957 **--
1958 **/
1959
sar_process_proc_ref(proc_id_frame,proc_arg_frame,context)1960 void sar_process_proc_ref
1961 ( proc_id_frame, proc_arg_frame, context )
1962
1963 yystype * proc_id_frame;
1964 yystype * proc_arg_frame;
1965 int context;
1966
1967 {
1968
1969 /* Call the common routine to get the procedure reference node, and
1970 return it in the stack frame. */
1971
1972 proc_id_frame->value.az_symbol_entry = (sym_entry_type *)
1973 sem_reference_procedure (
1974 proc_id_frame, proc_arg_frame,
1975 context );
1976
1977 /* If this is the create proc for a user_defined widget, save it
1978 in the object node. */
1979
1980 if (context == sym_k_object_proc)
1981 {
1982 yystype * widget_frame;
1983 sym_widget_entry_type * widget_entry;
1984
1985 /* Search the syntax stack for the widget frame. NOTE: gadgets can
1986 not have creation procedures; the grammar enforces this. */
1987
1988 widget_frame = sem_find_object (proc_id_frame - 1);
1989 widget_entry =
1990 (sym_widget_entry_type *) widget_frame->value.az_symbol_entry;
1991
1992 _assert (widget_entry->header.b_tag == sym_k_widget_entry,
1993 "widget missing from the stack");
1994
1995 if (widget_entry->header.b_type != uil_sym_user_defined_object)
1996 {
1997 yystype * source_frame;
1998
1999 source_frame = & yylval;
2000 diag_issue_diagnostic
2001 (d_create_proc,
2002 _sar_source_position ( source_frame ),
2003 diag_object_text (widget_entry->header.b_type) );
2004
2005 return;
2006 }
2007 else
2008 {
2009 widget_entry->az_create_proc =
2010 (sym_proc_ref_entry_type *) proc_id_frame->value.az_symbol_entry;
2011 }
2012
2013 }
2014
2015 return;
2016
2017 }
2018
2019 /*
2020 **++
2021 ** FUNCTIONAL DESCRIPTION:
2022 **
2023 ** This routine adds an entry to a list.
2024 **
2025 ** FORMAL PARAMETERS:
2026 **
2027 ** entry_frame address of the parse stack frame for
2028 ** the entry to be added to the list.
2029 **
2030 ** IMPLICIT INPUTS:
2031 **
2032 ** none
2033 **
2034 ** IMPLICIT OUTPUTS:
2035 **
2036 ** none
2037 **
2038 ** FUNCTION VALUE:
2039 **
2040 ** none
2041 **
2042 ** SIDE EFFECTS:
2043 **
2044 ** none
2045 **
2046 **--
2047 **/
2048
sar_add_list_entry(entry_frame)2049 void sar_add_list_entry
2050 ( entry_frame )
2051
2052 yystype * entry_frame;
2053
2054 {
2055 yystype * list_frame;
2056 sym_list_entry_type * list_entry;
2057 sym_obj_entry_type * entry_entry;
2058
2059 yystype * source_frame;
2060
2061 source_frame = & yylval;
2062
2063 /* Search the syntax stack for the list frame. */
2064
2065 list_frame = sem_find_object (entry_frame - 1);
2066 list_entry = (sym_list_entry_type *) list_frame->value.az_symbol_entry;
2067
2068 _assert (list_entry->header.b_tag == sym_k_list_entry,
2069 "list entry missing");
2070
2071 entry_entry = (sym_obj_entry_type *) entry_frame->value.az_symbol_entry;
2072
2073 /*
2074 ** If we are including a list within a list, put a nested list entry
2075 ** in the list, and point it to the actual list.
2076 */
2077
2078 if (entry_entry->header.b_tag == sym_k_list_entry)
2079 {
2080 sym_nested_list_entry_type *nested_entry;
2081
2082 /*
2083 ** If this list is a reference to a previously defined list,
2084 ** then use the previously defined list.
2085 */
2086 if (entry_entry->obj_header.az_reference != NULL)
2087 {
2088 entry_entry = (sym_obj_entry_type *)
2089 entry_entry->obj_header.az_reference;
2090 _assert (entry_entry->header.b_tag == sym_k_list_entry,
2091 "entry list entry missing");
2092 }
2093
2094 /*
2095 ** Create a nested list entry to reference the nested list. This
2096 ** becomes the entry which will be added to the current list.
2097 */
2098 nested_entry = (sym_nested_list_entry_type *)
2099 sem_allocate_node (sym_k_nested_list_entry,
2100 sym_k_nested_list_entry_size);
2101 nested_entry->header.b_type = entry_entry->header.b_type;
2102 nested_entry->az_list = (sym_list_entry_type *) entry_entry;
2103 entry_entry = (sym_obj_entry_type *) nested_entry;
2104 }
2105 else
2106 if (entry_entry->header.b_tag == sym_k_name_entry)
2107 {
2108 sym_nested_list_entry_type *nested_entry;
2109 /*
2110 ** This is a forward reference to a named, nested list.
2111 */
2112 nested_entry = (sym_nested_list_entry_type *)
2113 sem_allocate_node (sym_k_nested_list_entry,
2114 sym_k_nested_list_entry_size);
2115
2116 sym_make_value_forward_ref (entry_frame,
2117 (char*)&(nested_entry->az_list),
2118 sym_k_patch_list_add);
2119
2120 entry_entry = (sym_obj_entry_type *) nested_entry;
2121 }
2122
2123 /*
2124 ** Add the entry to front of the list
2125 ** The nested entry created above is included in this processing.
2126 */
2127 entry_entry->obj_header.az_next =
2128 (sym_entry_type *) list_entry->obj_header.az_next;
2129 list_entry->obj_header.az_next =
2130 (sym_entry_type *) entry_entry;
2131 list_entry->w_count++;
2132
2133 entry_frame->b_tag = sar_k_null_frame;
2134
2135 }
2136
2137 /*
2138 **++
2139 ** FUNCTIONAL DESCRIPTION:
2140 **
2141 ** This routine adds a forward referenced list entry to a list.
2142 **
2143 **
2144 ** FORMAL PARAMETERS:
2145 **
2146 ** entry_frame address of the parse stack frame for
2147 ** the entry to be added to the list.
2148 **
2149 ** IMPLICIT INPUTS:
2150 **
2151 ** none
2152 **
2153 ** IMPLICIT OUTPUTS:
2154 **
2155 ** none
2156 **
2157 ** FUNCTION VALUE:
2158 **
2159 ** none
2160 **
2161 ** SIDE EFFECTS:
2162 **
2163 ** none
2164 **
2165 **--
2166 **/
2167
sar_add_forward_list_entry(entry_frame)2168 void sar_add_forward_list_entry
2169 ( entry_frame )
2170
2171 yystype * entry_frame;
2172
2173 {
2174 yystype * list_frame;
2175 sym_list_entry_type * list_entry;
2176 sym_obj_entry_type * entry_entry;
2177 sym_name_entry_type * name_entry;
2178 yystype * source_frame;
2179 sym_nested_list_entry_type *nested_entry;
2180
2181 source_frame = & yylval;
2182
2183 /* Search the syntax stack for the list frame. */
2184
2185 list_frame = sem_find_object (entry_frame - 1);
2186 list_entry = (sym_list_entry_type *) list_frame->value.az_symbol_entry;
2187
2188 _assert (list_entry->header.b_tag == sym_k_list_entry,
2189 "list entry missing");
2190
2191 name_entry = (sym_name_entry_type *) entry_frame->value.az_symbol_entry;
2192
2193 nested_entry = (sym_nested_list_entry_type *)
2194 sem_allocate_node (sym_k_nested_list_entry,
2195 sym_k_nested_list_entry_size);
2196
2197 sym_make_value_forward_ref (entry_frame,
2198 (char*)&(nested_entry->az_list),
2199 sym_k_patch_list_add);
2200
2201 entry_entry = (sym_obj_entry_type *) nested_entry;
2202
2203 /*
2204 ** Add the entry to front of the list
2205 ** The nested entry created above is included in this processing.
2206 */
2207 entry_entry->obj_header.az_next =
2208 (sym_entry_type *) list_entry->obj_header.az_next;
2209 list_entry->obj_header.az_next =
2210 (sym_entry_type *) entry_entry;
2211 list_entry->w_count++;
2212
2213 entry_frame->b_tag = sar_k_null_frame;
2214
2215 }
2216
2217 /*
2218 **++
2219 ** FUNCTIONAL DESCRIPTION:
2220 **
2221 ** This routine verifies that the list or widget has been defined
2222 ** correctly. Virtually all such validation is actually done in pass 2.
2223 **
2224 ** FORMAL PARAMETERS:
2225 **
2226 ** current_frame address of the current syntax stack frame
2227 **
2228 ** IMPLICIT INPUTS:
2229 **
2230 ** none
2231 **
2232 ** IMPLICIT OUTPUTS:
2233 **
2234 ** none
2235 **
2236 ** FUNCTION VALUE:
2237 **
2238 ** void
2239 **
2240 ** SIDE EFFECTS:
2241 **
2242 ** none
2243 **
2244 **--
2245 **/
2246
sar_verify_object(current_frame)2247 void sar_verify_object ( current_frame )
2248
2249 yystype * current_frame;
2250
2251 {
2252 yystype * obj_frame;
2253 sym_widget_entry_type * widget_entry;
2254 unsigned int widget_type;
2255 sym_obj_entry_type * obj_entry;
2256 yystype * source_frame;
2257
2258
2259
2260 /*
2261 * Search the syntax stack for the object frame.
2262 */
2263 source_frame = & yylval;
2264 obj_frame = sem_find_object (current_frame - 1);
2265 obj_entry = (sym_obj_entry_type *) obj_frame->value.az_symbol_entry;
2266
2267 switch (obj_entry->header.b_tag)
2268 {
2269 case sym_k_gadget_entry:
2270 case sym_k_widget_entry:
2271
2272 /*
2273 * Clear the definition in progress bit.
2274 */
2275 _assert (obj_entry->obj_header.b_flags & sym_m_def_in_progress,
2276 "widget definition not in progress");
2277 obj_entry->obj_header.b_flags &= (~ sym_m_def_in_progress);
2278 break;
2279 case sym_k_list_entry:
2280 /*
2281 * Clear the definition in progress bit and return.
2282 */
2283 _assert (obj_entry->obj_header.b_flags & sym_m_def_in_progress,
2284 "list definition not in progress");
2285 obj_entry->obj_header.b_flags &= (~ sym_m_def_in_progress);
2286 return;
2287
2288 case sym_k_error_entry:
2289 return;
2290
2291 default:
2292 _assert (FALSE, "list or widget missing from the stack");
2293 break;
2294 }
2295
2296
2297 /*
2298 * If this is a user_defined widget, be sure the create proc was
2299 * specified if this is a declaration, and not specified if it
2300 * is a reference.
2301 */
2302 widget_entry = (sym_widget_entry_type *) obj_entry;
2303 widget_type = widget_entry->header.b_type;
2304 if (widget_type == uil_sym_user_defined_object)
2305 {
2306 if ((widget_entry->obj_header.b_flags & sym_m_obj_is_reference) != 0)
2307 {
2308 if (widget_entry->az_create_proc != NULL)
2309 {
2310 diag_issue_diagnostic
2311 (d_create_proc_inv,
2312 _sar_source_pos2(widget_entry),
2313 diag_object_text (widget_type) );
2314 widget_entry->header.b_type = sym_k_error_object;
2315 }
2316 }
2317 else
2318 {
2319 if (widget_entry->az_create_proc == NULL)
2320 {
2321 diag_issue_diagnostic
2322 (d_create_proc_req,
2323 _sar_source_pos2(widget_entry),
2324 diag_object_text (widget_type) );
2325 widget_entry->header.b_type = sym_k_error_object;
2326 }
2327 }
2328 }
2329
2330 }
2331
2332
2333
2334 /*
2335 **++
2336 ** FUNCTIONAL DESCRIPTION:
2337 **
2338 ** This routine allocates a symbol node of the specified size
2339 ** and type.
2340 **
2341 ** FORMAL PARAMETERS:
2342 **
2343 ** node_tag tag of node to allocate
2344 ** node_size size of node to allocate
2345 **
2346 ** IMPLICIT INPUTS:
2347 **
2348 **
2349 ** IMPLICIT OUTPUTS:
2350 **
2351 **
2352 ** FUNCTION VALUE:
2353 **
2354 ** the address of the allocated node
2355 **
2356 ** SIDE EFFECTS:
2357 **
2358 ** The node is saved in the allocated node list
2359 **
2360 **--
2361 **/
2362
sem_allocate_node(unsigned char node_tag,unsigned short node_size)2363 sym_entry_type * sem_allocate_node
2364 (unsigned char node_tag, unsigned short node_size )
2365
2366 {
2367
2368 sym_entry_type * node_ptr;
2369
2370 node_ptr = (sym_entry_type *) XtCalloc (1, node_size);
2371 node_ptr->header.w_node_size = node_size;
2372 node_ptr->header.b_tag = node_tag;
2373 UrmPlistAppendPointer (sym_az_allocated_nodes, (XtPointer)node_ptr);
2374
2375 return node_ptr;
2376
2377 }
2378
2379
2380 /*
2381 **++
2382 ** FUNCTIONAL DESCRIPTION:
2383 **
2384 ** This routine puts a symbol node on the free node list.
2385 **
2386 ** FORMAL PARAMETERS:
2387 **
2388 ** node_ptr address of node to put on the free list
2389 **
2390 ** IMPLICIT INPUTS:
2391 **
2392 **
2393 ** IMPLICIT OUTPUTS:
2394 **
2395 **
2396 ** FUNCTION VALUE:
2397 **
2398 ** void
2399 **
2400 ** SIDE EFFECTS:
2401 **
2402 **--
2403 **/
2404
sem_free_node(node_ptr)2405 void sem_free_node ( node_ptr )
2406
2407 sym_entry_type * node_ptr;
2408
2409 {
2410
2411 UrmPlistAppendPointer (sym_az_freed_nodes, (XtPointer)node_ptr);
2412
2413 }
2414
2415