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 (&section_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