4 * Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
5 * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
6 * the full copyright text.
13 static char rcsid[] = "$XConsortium: UilSarObj.c /main/14 1995/07/14 09:37:30 drk $"
18 * (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
24 ** User Interface Language Compiler (UIL)
28 ** This module contains the semantic action routines for
29 ** object definitions in the UIL.
46 ** DEFINE and MACRO DEFINITIONS
51 ** This is a fast algorithm for mapping an integer (_size) to
57 ** The algorithm is based on the notion that the floating pt representation
58 ** of an integer has an exponent that is the log_base2( int ).
60 ** This algorithm is specific to the VAX. An alternate layout of the
61 ** internal represention of a floating pt number could be supplied for
62 ** other architectures.
65 #define _compute_node_index( _size, _index ) \
66 { unsigned short j, k; \
69 else if (j <= 16) k = 1; \
70 else if (j <= 32) k = 2; \
71 else if (j <= 64) k = 3; \
80 ** EXTERNAL VARIABLE DECLARATIONS
84 extern yystype gz_yynullval;
85 extern yystype yylval;
90 ** GLOBAL VARIABLE DECLARATIONS
98 ** OWN VARIABLE DECLARATIONS
106 ** FUNCTIONAL DESCRIPTION:
108 ** This routine associates the latest comment block
109 ** with the current object frame. RAP
111 ** FORMAL PARAMETERS:
113 ** object_frame address of the parse stack frame for this
132 ** the object frame contains the comment for this object.
137 void sar_assoc_comment( object )
139 sym_obj_entry_type *object;
142 object->obj_header.az_comment = (char *)_get_memory(strlen(comment_text)+1);
143 strcpy(object->obj_header.az_comment, comment_text);
144 comment_text[0] = '\0';
151 ** FUNCTIONAL DESCRIPTION:
153 ** This routine creates the symbol node for the object, and
154 ** saves it in the object frame on the parse stack.
156 ** FORMAL PARAMETERS:
158 ** object_frame address of the parse stack frame for this
161 ** object_type type literal for this object.
177 ** the object frame contains the symbol node for this object.
182 void sar_create_object
183 ( yystype *object_frame, unsigned char object_type )
187 sym_name_entry_type * name_entry;
188 sym_obj_entry_type * obj_entry;
190 yystype * source_frame;
192 source_frame = & yylval;
194 if (object_frame->b_tag != sar_k_null_frame)
198 ** First we check on the name to see if it has been previously used.
199 ** This function returns NULL if name cannot be used.
201 name_entry = (sym_name_entry_type *) sem_dcl_name (object_frame);
208 /* Determine the size of the symbol node to allocate. */
212 case sym_k_gadget_entry:
213 case sym_k_widget_entry:
214 node_size = sym_k_widget_entry_size;
217 case sym_k_list_entry:
218 node_size = sym_k_list_entry_size;
222 _assert (FALSE, "unexpected object type");
227 * Allocate the symbol node, connect it to its name, and save source info
229 obj_entry = (sym_obj_entry_type *)
230 sem_allocate_node (object_type, node_size);
231 if (name_entry != NULL)
233 name_entry->az_object = (sym_entry_type *)obj_entry;
234 obj_entry->obj_header.az_name = (sym_name_entry_type *)name_entry;
236 _sar_save_source_pos (&obj_entry->header, source_frame );
237 sar_assoc_comment(obj_entry); /* preserve comments */
239 * Set the definition in progress bit.
241 obj_entry->obj_header.b_flags |= sym_m_def_in_progress;
244 * Save the symbol node in the object frame.
246 object_frame->b_tag = sar_k_object_frame;
247 object_frame->b_type = object_type;
248 object_frame->value.az_symbol_entry = (sym_entry_type *)obj_entry;
255 ** FUNCTIONAL DESCRIPTION:
257 ** This routine creates the symbol node for the child, and
258 ** saves it in the object frame on the parse stack.
260 ** FORMAL PARAMETERS:
262 ** object_frame address of the parse stack frame for this
279 ** the object frame contains the symbol node for this child.
284 void sar_create_child
285 ( yystype *object_frame )
288 sym_obj_entry_type * obj_entry;
289 yystype * source_frame;
291 source_frame = & yylval;
294 * Allocate the symbol node, set its type, and save source info
296 obj_entry = (sym_obj_entry_type *)
297 sem_allocate_node (sym_k_child_entry, sym_k_widget_entry_size);
298 obj_entry->header.b_type =
299 object_frame->value.az_keyword_entry->b_subclass;
301 _sar_save_source_pos (&obj_entry->header, source_frame );
302 sar_assoc_comment(obj_entry); /* preserve comments */
304 * Indicate in compress table that this child type is used.
306 uil_child_compr[obj_entry->header.b_type] = 1;
309 * Set the definition in progress bit.
311 obj_entry->obj_header.b_flags |= sym_m_def_in_progress;
314 * Save the symbol node in the object frame.
316 object_frame->b_tag = sar_k_object_frame;
317 object_frame->b_type = sym_k_child_entry;
318 object_frame->value.az_symbol_entry = (sym_entry_type *)obj_entry;
325 ** FUNCTIONAL DESCRIPTION:
327 ** This routine creates and links a section node into the symbol table
329 ** FORMAL PARAMETERS:
331 ** id_frame the token frame with the id for this entry.
335 ** sym_az_current_section_entry global pointer to the "current" section
350 void sar_link_section ( id_frame )
355 sym_section_entry_type * section_entry;
358 * Allocate a section entry. Link this entry of of the current section list
360 section_entry = (sym_section_entry_type *) sem_allocate_node
361 (sym_k_section_entry, sym_k_section_entry_size);
362 section_entry->next = (sym_entry_type *)
363 sym_az_current_section_entry->entries;
364 sym_az_current_section_entry->entries = (sym_entry_type *) section_entry;
365 section_entry->entries = id_frame->value.az_symbol_entry;
371 ** FUNCTIONAL DESCRIPTION:
373 ** This routine saves the source information about where this
374 ** semi-colon entry ends.
376 ** FORMAL PARAMETERS:
378 ** semi_frame the token frame for the terminating semi-colon
383 ** sym_az_current_section_entry global pointer to the
384 ** "current" section list
401 void sar_save_src_semicolon_pos (semi_frame)
403 yystype * semi_frame;
406 sym_section_entry_type * section_entry;
408 section_entry = (sym_section_entry_type *)
409 sym_az_current_section_entry->entries;
410 _sar_save_source_pos (§ion_entry->entries->header, semi_frame);
417 ** FUNCTIONAL DESCRIPTION:
419 ** This function saves the title end source for lists (i.e. "ARGUMENTS",
420 ** "CALLBACKS", "PROCEDURES", and "CONTROLS"). The source saved here
421 ** should be "}" or posibly an id_ref.
425 ** close_frame ptr to token frame for the closing source
429 ** the "current" list on the frame stack as returned by sem_find_object
445 void sar_save_list_end (close_frame)
447 yystype *close_frame;
450 sym_list_entry_type * list_entry;
451 yystype * list_frame;
454 ** Search the syntax stack for the object frame.
457 list_frame = sem_find_object (close_frame - 1);
458 list_entry = (sym_list_entry_type *) list_frame->value.az_symbol_entry;
460 _sar_save_source_pos ( &list_entry->header , close_frame );
466 ** FUNCTIONAL DESCRIPTION:
468 ** This function saves the end source for just about any type
473 ** close_frame ptr to token frame for the closing source (probably
478 ** the "current" list on the frame stack as returned by sem_find_object
494 void sar_save_src_entry_end (close_frame, entry_frame)
496 yystype *close_frame;
497 yystype *entry_frame;
500 sym_entry_type * entry;
503 ** Extract the entry from the frame.
506 entry = (sym_entry_type *) entry_frame->value.az_symbol_entry;
509 ** Case on the type of entry (source gets put in a different spot for
513 if (entry->header.b_tag == sym_k_control_entry)
515 sym_control_entry_type *control_entry = (sym_control_entry_type *)entry;
517 _sar_save_source_pos (&control_entry->az_con_obj->header, close_frame);
521 ** Save the source info in the default place
524 _sar_save_source_pos ( &entry->header , close_frame );
530 ** FUNCTIONAL DESCRIPTION:
532 ** This routine sets flags in the stack entry for the object.
534 ** FORMAL PARAMETERS:
536 ** current_frame address of the current syntax stack frame
538 ** mask mask of flags to be set.
559 void sar_set_object_flags
561 (yystype *current_frame, unsigned char mask )
565 sym_obj_entry_type * obj_entry;
566 yystype * object_frame;
568 /* Search the syntax stack for the object frame. */
570 object_frame = sem_find_object (current_frame - 1);
571 obj_entry = (sym_obj_entry_type *) object_frame->value.az_symbol_entry;
573 /* Set the flags for the object entry. */
575 obj_entry->obj_header.b_flags |= mask;
577 /* If this is an exported or private object and it has a name,
578 ** make an external entry for it.
581 if ((mask & (sym_m_exported | sym_m_private)) &&
582 (obj_entry->obj_header.az_name != NULL))
584 sym_make_external_def (obj_entry->obj_header.az_name);
592 ** FUNCTIONAL DESCRIPTION:
594 ** This routine unsets flags in the stack entry for the object.
596 ** FORMAL PARAMETERS:
598 ** current_frame address of the current syntax stack frame
600 ** mask mask of flags to be unset.
621 void sar_unset_object_flags
623 (yystype *current_frame, unsigned char mask )
626 yystype * object_frame;
628 /* Search the syntax stack for the object frame. */
630 object_frame = sem_find_object (current_frame - 1);
632 /* Unset the flags for the object entry. */
634 object_frame->b_flags &= ~mask;
641 ** FUNCTIONAL DESCRIPTION:
643 ** This routine sets the type in the stack entry for the (list) object.
645 ** FORMAL PARAMETERS:
647 ** current_frame address of the current syntax stack frame
668 void sar_set_list_type
671 yystype * current_frame;
675 sym_obj_entry_type * obj_entry;
676 yystype * list_frame;
678 /* Search the syntax stack for the list frame. */
679 list_frame = sem_find_object (current_frame-1);
680 obj_entry = (sym_obj_entry_type *) list_frame->value.az_symbol_entry;
682 /* Set the type for the list entry. */
683 obj_entry->header.b_type = current_frame->b_type;
690 ** FUNCTIONAL DESCRIPTION:
692 ** This routine sets the type in the stack entry for the (widget) object.
694 ** FORMAL PARAMETERS:
696 ** current_frame address of the current syntax stack frame
717 void sar_set_object_class
720 yystype * current_frame;
724 sym_obj_entry_type * obj_entry;
725 yystype * object_frame;
727 /* Search the syntax stack for the object frame. */
728 object_frame = sem_find_object (current_frame-1);
729 obj_entry = (sym_obj_entry_type *) object_frame->value.az_symbol_entry;
731 /* Set the type for the object entry. */
732 obj_entry->header.b_type =
733 current_frame->value.az_keyword_entry->b_subclass;
736 ** Indicate in compression table that this object type is used.
737 ** Note that user defined widgets don't get compression code entires.
738 ** We always identify user defined widgets as MrmwcUnknown.
740 if ( obj_entry->header.b_type != uil_sym_user_defined_object )
741 uil_widget_compr[obj_entry->header.b_type] = 1;
748 ** FUNCTIONAL DESCRIPTION:
750 ** This routine sets the variant in the stack entry for the object.
752 ** FORMAL PARAMETERS:
754 ** current_frame address of the current syntax stack frame
775 void sar_set_object_variant
778 yystype * current_frame;
782 sym_obj_entry_type * obj_entry;
783 yystype * object_frame;
785 /* Search the syntax stack for the object frame. */
787 object_frame = sem_find_object (current_frame - 1);
788 obj_entry = (sym_obj_entry_type *) object_frame->value.az_symbol_entry;
790 /* Set the variant for the object entry. */
792 switch (current_frame->b_type)
795 /* Use the module default for this object type. */
798 unsigned int obj_type;
801 * Pick up gadget variant (or widget variant) as specified
802 * by the module tables and the gadget variants
804 obj_type = obj_entry->header.b_type;
805 if (uil_urm_variant[obj_type] == sym_k_gadget_entry)
807 obj_entry->obj_header.b_flags |= sym_m_obj_is_gadget;
808 obj_entry->header.b_type = uil_gadget_variants [obj_type];
814 case sym_k_widget_entry:
817 case sym_k_gadget_entry:
819 unsigned int obj_type;
822 * Check if gadgets are supported for this object type.
823 * If so, change the object type to the matching code for
824 * the widget class which is the gadget.
826 obj_type = obj_entry->header.b_type;
827 if (uil_gadget_variants[obj_type] == 0)
829 yystype * source_frame;
831 source_frame = & yylval;
832 diag_issue_diagnostic
834 _sar_source_position (source_frame ),
835 diag_object_text(obj_type),
836 diag_object_text(obj_type) );
840 obj_entry->obj_header.b_flags |= sym_m_obj_is_gadget;
841 obj_entry->header.b_type = uil_gadget_variants [obj_type];
848 _assert (FALSE, "unexpected variant type");
853 ** If this object is a gadget, mark that gadgets of this type have been
854 ** used so we can later assign it a compression code. This is a safety
855 ** set against the actual widget class.
858 if ((obj_entry->obj_header.b_flags & sym_m_obj_is_gadget) != 0)
859 uil_widget_compr[obj_entry->header.b_type] = 1;
866 ** FUNCTIONAL DESCRIPTION:
868 ** This routine finds the object frame on the parse stack.
870 ** FORMAL PARAMETERS:
872 ** current_frame address of the current parse stack frame.
884 ** address of the parse stack frame for this object.
893 yystype * sem_find_object ( current_frame )
895 yystype * current_frame;
899 yystype * object_frame;
901 object_frame = current_frame;
903 /* Search the syntax stack for the object frame. */
905 while ( (object_frame->b_tag != sar_k_object_frame) &&
906 (object_frame->b_tag != sar_k_module_frame) )
909 if (object_frame->b_tag != sar_k_object_frame)
910 _assert (FALSE, "missing object frame on the parser stack");
912 return (object_frame);
918 ** FUNCTIONAL DESCRIPTION:
920 ** This routine processes a reference to an object in the
921 ** UIL. The reference may be a forward reference.
923 ** FORMAL PARAMETERS:
925 ** ref_frame address of the parse stack frame for
926 ** the object reference.
947 void sar_object_reference ( ref_frame )
952 sym_obj_entry_type * obj_entry;
953 sym_name_entry_type * ref_name;
954 sym_obj_entry_type * ref_entry;
955 sym_value_entry_type * ref_value;
958 yystype * source_frame;
960 source_frame = & yylval;
962 /* Search the syntax stack for the object frame. */
964 obj_frame = sem_find_object (ref_frame - 1);
965 obj_entry = (sym_obj_entry_type *) obj_frame->value.az_symbol_entry;
966 ref_name = (sym_name_entry_type *) ref_frame->value.az_symbol_entry;
967 ref_value = (sym_value_entry_type *) ref_name->az_object;
968 ref_entry = (sym_obj_entry_type *) ref_name->az_object;
970 /* Check if this name was previously defined for a different usage. */
972 if (ref_entry != NULL)
974 if ( ref_entry->header.b_tag==sym_k_widget_entry ||
975 ref_entry->header.b_tag==sym_k_gadget_entry ||
976 ref_entry->header.b_tag==sym_k_child_entry )
978 (ref_entry->header.b_tag!=obj_entry->header.b_tag) ||
979 ((ref_entry->header.b_type!=obj_entry->header.b_type) &&
980 (uil_gadget_variants[ref_entry->header.b_type]!=
981 obj_entry->header.b_type) &&
982 (uil_gadget_variants[obj_entry->header.b_type]!=
983 ref_entry->header.b_type));
986 (ref_entry->header.b_tag!=obj_entry->header.b_tag) ||
987 (ref_entry->header.b_type!=obj_entry->header.b_type);
992 char * expected_type, * found_type;
994 if (ref_entry->header.b_tag == sym_k_list_entry)
995 found_type = diag_tag_text (ref_entry->header.b_type);
996 else if (ref_entry->header.b_tag == sym_k_widget_entry)
997 found_type = diag_object_text (ref_entry->header.b_type);
998 else if (ref_entry->header.b_tag == sym_k_gadget_entry)
999 found_type = diag_object_text (ref_entry->header.b_type);
1000 else if (ref_entry->header.b_tag == sym_k_value_entry)
1001 found_type = diag_value_text
1002 (((sym_value_entry_type *) ref_entry)->b_type);
1006 if (obj_entry->header.b_tag == sym_k_list_entry)
1008 diag_tag_text (obj_entry->header.b_type);
1011 diag_object_text (obj_entry->header.b_type);
1013 diag_issue_diagnostic
1015 _sar_source_position ( source_frame ),
1017 diag_tag_text (ref_entry->header.b_tag),
1019 diag_tag_text (obj_entry->header.b_tag) );
1021 obj_entry->header.b_tag = sym_k_error_entry;
1027 switch (obj_entry->header.b_tag)
1030 case sym_k_list_entry:
1033 /* Add this entry to the list. A copy of the list will be made. */
1035 if ((ref_value != 0) &&
1036 ((ref_value->obj_header.b_flags & sym_m_forward_ref) == 0))
1038 ref_frame->value.az_symbol_entry = (sym_entry_type *)ref_entry;
1039 sar_add_list_entry (ref_frame);
1042 sar_add_forward_list_entry (ref_frame);
1047 case sym_k_gadget_entry:
1048 case sym_k_widget_entry:
1052 /* Mark the widget as referenced. */
1054 ref_name->b_flags |= sym_m_referenced;
1056 /* Mark the referencing object */
1058 obj_entry->obj_header.b_flags |= sym_m_obj_is_reference;
1060 /* Forward references are allowed for widgets or gadgets. */
1062 if (ref_entry == NULL)
1063 make_fwd_ref = TRUE;
1067 /* A widget can reference itself; treat it as a forward reference. */
1069 if (ref_entry->obj_header.b_flags & sym_m_def_in_progress)
1070 make_fwd_ref = TRUE;
1072 make_fwd_ref = FALSE;
1077 /* Add forward reference entry for this widget. */
1079 sym_make_forward_ref
1081 obj_entry->header.b_type,
1082 (char*)& obj_entry->obj_header.az_reference );
1086 /* Save this reference in the widget. */
1088 obj_entry->obj_header.az_reference = (sym_entry_type *)ref_entry;
1096 _assert (FALSE, "unexpected object reference type");
1105 ** FUNCTIONAL DESCRIPTION:
1107 ** This routine updates the parent list of every object in the controls
1108 ** list(s) for this object. Parent lists are required in order to check
1109 ** constraint arguments.
1111 ** FORMAL PARAMETERS:
1113 ** control_list_frame address of the parse stack frame for
1114 ** the control list.
1120 ** IMPLICIT OUTPUTS:
1135 void sar_update_parent_list
1136 ( control_list_frame )
1138 yystype * control_list_frame;
1141 yystype * widget_frame;
1142 sym_widget_entry_type * widget_entry;
1143 sym_list_entry_type * control_list_entry;
1145 /* Search the syntax stack for the widget frame. */
1147 widget_frame = sem_find_object (control_list_frame - 1);
1148 widget_entry = (sym_widget_entry_type *)
1149 widget_frame->value.az_symbol_entry;
1151 _assert (widget_entry->header.b_tag == sym_k_widget_entry ||
1152 widget_entry->header.b_tag == sym_k_gadget_entry ||
1153 widget_entry->header.b_tag == sym_k_child_entry,
1154 "widget missing from the stack");
1156 /* Get the control_list entry from the widget */
1158 control_list_entry = (sym_list_entry_type *)
1159 control_list_frame->value.az_symbol_entry;
1161 _assert ((control_list_entry->header.b_tag == sym_k_list_entry ||
1162 control_list_entry->header.b_tag == sym_k_error_entry),
1163 "list entry missing");
1165 /* The control list contains control list entries as well as nested lists,
1166 ** which in turn contain list entries and nested lists.
1167 ** We need to call a recursive routine to traverse all the entries.
1170 parent_list_traverse(widget_entry, control_list_entry);
1177 ** FUNCTIONAL DESCRIPTION:
1179 ** This routine recursively traverses a control_list. Control lists
1180 ** may contain control list entries as well as nested control lists.
1182 ** This routine also updates the parent list of every object in the
1183 ** controls list(s) for this object. Parent lists are required in order
1184 ** to check constraint arguments.
1186 ** FORMAL PARAMETERS:
1188 ** widget_entry the widget to be entered in lists
1189 ** control_list_entry A control_list or nested control list
1196 ** IMPLICIT OUTPUTS:
1211 void parent_list_traverse (widget_entry, control_list_entry)
1212 sym_widget_entry_type *widget_entry;
1213 sym_list_entry_type *control_list_entry;
1216 sym_obj_entry_type *control_list_member;
1217 sym_control_entry_type *control_entry;
1218 sym_nested_list_entry_type *nested_control_list_entry;
1219 sym_widget_entry_type *control_widget;
1221 sym_forward_ref_entry_type *fwd_ref_entry;
1222 sym_parent_list_type *parent_node;
1223 sym_parent_list_type *parent_ptr;
1226 for (control_list_member = (sym_obj_entry_type *)control_list_entry ->
1228 control_list_member != NULL;
1229 control_list_member = (sym_obj_entry_type *)control_list_member ->
1232 switch (control_list_member->header.b_tag)
1234 case sym_k_nested_list_entry:
1235 nested_control_list_entry = (sym_nested_list_entry_type *)
1236 control_list_member;
1237 /* Begin fixing DTS 9497 */
1238 if(nested_control_list_entry->az_list)
1239 parent_list_traverse (widget_entry,
1240 nested_control_list_entry->az_list);
1241 /* End fixing DTS 9497 */
1243 case sym_k_control_entry:
1244 control_entry = (sym_control_entry_type *) control_list_member;
1246 /* Get a pointer to one of the actual widgets in the control list */
1248 control_widget = control_entry->az_con_obj;
1251 ** If it's a widget reference, go find it. If you can't find it, it must
1252 ** be a forward reference. If so, find the forward reference entry for it
1253 ** and update it with a pointer to its parent.
1256 if ( control_widget->
1257 obj_header.b_flags & sym_m_obj_is_reference)
1258 if ( control_widget->obj_header.az_reference == NULL )
1261 /* Forward reference. Update forward reference entry. */
1264 for (fwd_ref_entry = sym_az_forward_ref_chain;
1265 ((fwd_ref_entry != NULL) && (found == FALSE));
1266 fwd_ref_entry = fwd_ref_entry->az_next_ref)
1268 if (fwd_ref_entry->a_update_location ==
1269 (char *) & control_widget->
1270 obj_header.az_reference)
1273 fwd_ref_entry->parent = widget_entry;
1279 /* A widget reference, but already defined. Go update its entry. */
1281 control_widget = (sym_widget_entry_type *)
1282 control_widget->obj_header.az_reference;
1284 for (parent_ptr = control_widget->parent_list;
1285 ((parent_ptr != NULL) && (found == FALSE));
1286 parent_ptr = parent_ptr->next)
1288 if (parent_ptr->parent == widget_entry)
1293 parent_node = (sym_parent_list_type *)
1294 sem_allocate_node (sym_k_parent_list_entry,
1295 sym_k_parent_list_size);
1296 parent_node->next = control_widget->parent_list;
1297 control_widget->parent_list = parent_node;
1298 parent_node->parent = widget_entry;
1303 /* An inline widget definition. Go update its entry. */
1306 for (parent_ptr = control_widget->parent_list;
1307 ((parent_ptr != NULL) && (found == FALSE));
1308 parent_ptr = parent_ptr->next)
1310 if (parent_ptr->parent == widget_entry)
1315 parent_node = (sym_parent_list_type *)
1316 sem_allocate_node (sym_k_parent_list_entry,
1317 sym_k_parent_list_size);
1318 parent_node->next = control_widget->parent_list;
1319 control_widget->parent_list = parent_node;
1320 parent_node->parent = widget_entry;
1331 ** FUNCTIONAL DESCRIPTION:
1333 ** This routine saves a widget feature in the widget symbol node.
1335 ** FORMAL PARAMETERS:
1337 ** feature_frame address of the parse stack frame for
1338 ** the widget feature.
1344 ** IMPLICIT OUTPUTS:
1359 void sar_save_feature
1362 yystype * feature_frame;
1365 yystype * widget_frame;
1366 sym_widget_entry_type * widget_entry;
1367 sym_entry_type * feature_entry;
1368 sym_entry_type * * ptr;
1370 yystype * source_frame;
1372 source_frame = & yylval;
1374 /* Search the syntax stack for the widget frame. */
1376 widget_frame = sem_find_object (feature_frame - 1);
1377 widget_entry = (sym_widget_entry_type *)
1378 widget_frame->value.az_symbol_entry;
1380 _assert (widget_entry->header.b_tag == sym_k_widget_entry ||
1381 widget_entry->header.b_tag == sym_k_gadget_entry ||
1382 widget_entry->header.b_tag == sym_k_child_entry,
1383 "widget missing from the stack");
1385 feature_entry = feature_frame->value.az_symbol_entry;
1387 _assert ((feature_entry->header.b_tag == sym_k_list_entry ||
1388 feature_entry->header.b_tag == sym_k_error_entry),
1389 "list entry missing");
1391 switch (feature_entry->header.b_type)
1394 case sym_k_argument_entry:
1395 ptr = (sym_entry_type * *) & widget_entry->az_arguments;
1398 case sym_k_control_entry:
1399 ptr = (sym_entry_type * *) & widget_entry->az_controls;
1402 case sym_k_callback_entry:
1403 ptr = (sym_entry_type * *) & widget_entry->az_callbacks;
1406 case sym_k_error_entry:
1410 _assert (FALSE, "unexpected widget feature");
1414 /* Check for duplicate features. */
1418 diag_issue_diagnostic
1420 _sar_source_position ( source_frame ),
1421 diag_tag_text (feature_entry->header.b_type),
1422 diag_tag_text (feature_entry->header.b_tag),
1423 diag_object_text (widget_entry->header.b_type),
1424 diag_tag_text (widget_entry->header.b_tag) );
1429 /* Save the feature in the widget. */
1431 (* ptr) = feature_entry;
1433 /* Clear the feature frame from the stack. */
1435 feature_frame->b_tag = sar_k_null_frame;
1441 ** FUNCTIONAL DESCRIPTION:
1443 ** This routine processes an argument pair for an object.
1445 ** FORMAL PARAMETERS:
1447 ** argument_frame address of the parse stack frame for
1448 ** the argument reference.
1450 ** value_frame address of the parse stack frame for
1451 ** the argument value.
1453 ** equals_frame address of the parse stack frame for the
1460 ** IMPLICIT OUTPUTS:
1474 void sar_save_argument_pair
1475 ( argument_frame, value_frame, equals_frame)
1477 yystype * argument_frame;
1478 yystype * value_frame;
1479 yystype * equals_frame;
1483 yystype * object_frame;
1484 sym_argument_entry_type * arg_entry;
1485 sym_list_entry_type * list_entry;
1486 sym_value_entry_type * val_value_entry;
1487 sym_value_entry_type * arg_value_entry;
1488 unsigned char actual_tag;
1490 yystype * source_frame;
1493 source_frame = & yylval;
1495 /* Search the syntax stack for the object frame. */
1497 object_frame = sem_find_object (argument_frame - 1);
1499 list_entry = (sym_list_entry_type *)
1500 object_frame->value.az_symbol_entry;
1502 _assert (list_entry->header.b_tag == sym_k_list_entry,
1503 "list entry missing");
1506 (sym_value_entry_type *) argument_frame->value.az_symbol_entry;
1508 _assert (arg_value_entry->header.b_tag == sym_k_value_entry,
1509 "argument value entry missing");
1512 ** Save the source information (?)
1515 _sar_save_source_info ( &arg_value_entry->header , argument_frame ,
1518 val_value_entry = (sym_value_entry_type *) value_frame->value.az_symbol_entry;
1519 actual_tag = val_value_entry->header.b_tag;
1521 /* Create and fill in the argument node. */
1523 arg_entry = (sym_argument_entry_type *) sem_allocate_node (
1524 sym_k_argument_entry, sym_k_argument_entry_size);
1527 ** If the argument is a forward reference, we'll patch in the
1528 ** address of the the referenced arg between passes. Otherwise,
1529 ** just point to the referenced arg node.
1532 if ((argument_frame->b_flags & sym_m_forward_ref) != 0)
1533 sym_make_value_forward_ref (argument_frame,
1534 (char*)&(arg_entry->az_arg_name), sym_k_patch_add);
1536 arg_entry->az_arg_name =
1537 (sym_value_entry_type *) argument_frame->value.az_symbol_entry;
1540 ** If the argument value is a forward reference, we'll patch in the
1541 ** address of the the referenced arg value between passes. Otherwise,
1542 ** just point to the referenced arg value node.
1545 if ((value_frame->b_flags & sym_m_forward_ref) != 0)
1546 sym_make_value_forward_ref (value_frame,
1547 (char*)&(arg_entry->az_arg_value), sym_k_patch_add);
1549 arg_entry->az_arg_value = val_value_entry;
1551 argument_frame->b_tag = sar_k_null_frame;
1552 argument_frame->value.az_symbol_entry = (sym_entry_type *) arg_entry;
1559 ** FUNCTIONAL DESCRIPTION:
1561 ** This routine processes a reason to procedure or procedure list binding
1562 ** for a callback object in UIL.
1564 ** FORMAL PARAMETERS:
1566 ** reason_frame address of the parse stack frame for
1567 ** the reason reference.
1569 ** proc_ref_frame address of the parse stack frame for
1570 ** the procedure reference.
1572 ** equals_frame address if the parse stack frame for
1579 ** IMPLICIT OUTPUTS:
1594 void sar_save_reason_binding
1595 ( reason_frame, proc_ref_frame, equals_frame )
1597 yystype * reason_frame;
1598 yystype * proc_ref_frame;
1599 yystype * equals_frame;
1603 yystype * object_frame;
1604 sym_callback_entry_type * callback_entry;
1605 sym_list_entry_type * list_entry;
1606 yystype * source_frame;
1608 source_frame = & yylval;
1610 /* Search the syntax stack for the object frame. */
1612 object_frame = sem_find_object (reason_frame - 1);
1614 list_entry = (sym_list_entry_type *) object_frame->value.az_symbol_entry;
1616 _assert (list_entry->header.b_tag == sym_k_list_entry,
1617 "list entry missing");
1620 ** Create and fill in the callback node.
1623 callback_entry = (sym_callback_entry_type *) sem_allocate_node (
1624 sym_k_callback_entry, sym_k_callback_entry_size);
1627 ** If the reason is a forward reference, we'll patch in the
1628 ** address of the the referenced reason between passes. Otherwise,
1629 ** just point to the referenced reason node.
1632 if ((reason_frame->b_flags & sym_m_forward_ref) != 0)
1633 sym_make_value_forward_ref (reason_frame,
1634 (char*)&(callback_entry->az_call_reason_name), sym_k_patch_add);
1636 callback_entry->az_call_reason_name =
1637 (sym_value_entry_type *) reason_frame->value.az_symbol_entry;
1641 ** Save source information
1643 /* _sar_save_source_info ( &reason_value_entry->header , reason_frame ,
1648 ** Note that proc_ref_frame may point to either a procedure reference
1649 ** or to a list of procedure reference nodes
1652 if ( proc_ref_frame->b_type == sym_k_list_entry)
1653 callback_entry->az_call_proc_ref_list =
1654 (sym_list_entry_type *) proc_ref_frame->value.az_symbol_entry;
1656 callback_entry->az_call_proc_ref =
1657 (sym_proc_ref_entry_type *) proc_ref_frame->value.az_symbol_entry;
1659 reason_frame->b_tag = sar_k_null_frame;
1660 reason_frame->value.az_symbol_entry = (sym_entry_type *) callback_entry;
1666 ** FUNCTIONAL DESCRIPTION:
1668 ** This routine processes a control clause.
1670 ** FORMAL PARAMETERS:
1672 ** managed_frame address of the parse stack frame for
1673 ** the managed flag for this control.
1675 ** item_frame address of the parse stack frame for
1676 ** the control item object.
1682 ** IMPLICIT OUTPUTS:
1697 void sar_save_control_item
1698 ( managed_frame, item_frame )
1700 yystype * managed_frame;
1701 yystype * item_frame;
1705 yystype * object_frame;
1706 sym_control_entry_type * control_entry;
1707 sym_list_entry_type * list_entry;
1708 yystype * source_frame;
1710 source_frame = & yylval;
1712 /* Search the syntax stack for the object frame. */
1714 object_frame = sem_find_object (managed_frame - 1);
1717 (sym_list_entry_type *) object_frame->value.az_symbol_entry;
1719 _assert (list_entry->header.b_tag == sym_k_list_entry,
1720 "list entry missing");
1722 /* Verify that this type of item is allowed on this list. */
1724 if (list_entry->header.b_type != sym_k_control_entry)
1726 diag_issue_diagnostic
1728 _sar_source_position ( source_frame ),
1729 diag_tag_text (sym_k_control_entry),
1730 diag_tag_text (list_entry->header.b_type),
1731 diag_tag_text (list_entry->header.b_tag) );
1736 /* Create and fill in the control node. */
1738 control_entry = (sym_control_entry_type *) sem_allocate_node (
1739 sym_k_control_entry, sym_k_control_entry_size);
1741 control_entry->az_con_obj =
1742 (sym_widget_entry_type *) item_frame->value.az_symbol_entry;
1744 control_entry->obj_header.b_flags = ( item_frame->b_flags |
1745 managed_frame->b_flags );
1747 managed_frame->b_tag =
1748 item_frame->b_tag = sar_k_null_frame;
1750 managed_frame->value.az_symbol_entry = (sym_entry_type *) control_entry;
1756 ** FUNCTIONAL DESCRIPTION:
1758 ** This routine processes a control clause when an id is created in that
1761 ** FORMAL PARAMETERS:
1763 ** control_frame address of the parse stack frame for
1764 ** the control list.
1766 ** item_frame address of the parse stack frame for
1767 ** the control item id.
1773 ** IMPLICIT OUTPUTS:
1788 void sar_save_control_widget
1789 ( control_frame, item_frame )
1791 yystype * control_frame;
1792 yystype * item_frame;
1796 yystype * object_frame;
1797 sym_control_entry_type * control_entry;
1798 sym_list_entry_type * list_entry;
1799 yystype * source_frame;
1803 ** move the item_frame to the control_frame and
1804 ** the control_frame to the null_frame. This is done
1805 ** because the item_frame needs to be second in the list
1808 temp_frame = *item_frame;
1809 *item_frame = *control_frame;
1810 *control_frame = temp_frame;
1812 source_frame = & yylval;
1814 /* Search the syntax stack for the object frame. */
1816 object_frame = sem_find_object (control_frame - 1);
1819 (sym_list_entry_type *) object_frame->value.az_symbol_entry;
1821 _assert (list_entry->header.b_tag == sym_k_list_entry,
1822 "list entry missing");
1824 /* Verify that this type of item is allowed on this list. */
1826 if (list_entry->header.b_type != sym_k_control_entry)
1828 diag_issue_diagnostic
1830 _sar_source_position ( source_frame ),
1831 diag_tag_text (sym_k_control_entry),
1832 diag_tag_text (list_entry->header.b_type),
1833 diag_tag_text (list_entry->header.b_tag) );
1838 /* Create and fill in the control node. */
1840 control_entry = (sym_control_entry_type *) sem_allocate_node
1841 (sym_k_control_entry, sym_k_control_entry_size);
1843 control_entry->az_con_obj =
1844 (sym_widget_entry_type *) item_frame->value.az_symbol_entry;
1846 control_entry->obj_header.b_flags = item_frame->b_flags;
1848 control_frame->b_tag =
1849 item_frame->b_tag = sar_k_null_frame;
1851 control_frame->value.az_symbol_entry = (sym_entry_type *) control_entry;
1857 ** FUNCTIONAL DESCRIPTION:
1859 ** This routine saves the source for a user defined create procedure
1861 ** FORMAL PARAMETERS:
1863 ** procedure_frame address of the parse stack frame for
1864 ** the text "PROCEDURE".
1866 ** proc_id_frame address of the parse stack frame for
1867 ** the procedure reference.
1869 ** proc_arg_frame address of the parse stack frame for
1870 ** the procedure argument value.
1876 ** IMPLICIT OUTPUTS:
1891 void sar_save_user_proc_ref_src
1892 ( procedure_frame, proc_id_frame, proc_arg_frame)
1894 yystype * procedure_frame;
1895 yystype * proc_id_frame;
1896 yystype * proc_arg_frame;
1899 sym_proc_ref_entry_type * proc_ref_entry;
1901 proc_ref_entry = (sym_proc_ref_entry_type *)proc_id_frame->value.az_symbol_entry;
1904 ** If the parameter arg clause was ommitted the source info should be null.
1905 ** We want to save the source for the "args" if it is there.
1907 _sar_save_source_info (& proc_ref_entry->header, procedure_frame, proc_arg_frame );
1913 ** FUNCTIONAL DESCRIPTION:
1915 ** This routine processes a procedure reference.
1917 ** FORMAL PARAMETERS:
1919 ** proc_id_frame address of the parse stack frame for
1920 ** the procedure reference.
1922 ** proc_arg_frame address of the parse stack frame for
1923 ** the procedure argument value.
1925 ** context indicates whether this is a callback
1926 ** or a user-defined procedure reference.
1932 ** IMPLICIT OUTPUTS:
1947 void sar_process_proc_ref
1948 ( proc_id_frame, proc_arg_frame, context )
1950 yystype * proc_id_frame;
1951 yystype * proc_arg_frame;
1956 /* Call the common routine to get the procedure reference node, and
1957 return it in the stack frame. */
1959 proc_id_frame->value.az_symbol_entry = (sym_entry_type *)
1960 sem_reference_procedure (
1961 proc_id_frame, proc_arg_frame,
1964 /* If this is the create proc for a user_defined widget, save it
1965 in the object node. */
1967 if (context == sym_k_object_proc)
1969 yystype * widget_frame;
1970 sym_widget_entry_type * widget_entry;
1972 /* Search the syntax stack for the widget frame. NOTE: gadgets can
1973 not have creation procedures; the grammar enforces this. */
1975 widget_frame = sem_find_object (proc_id_frame - 1);
1977 (sym_widget_entry_type *) widget_frame->value.az_symbol_entry;
1979 _assert (widget_entry->header.b_tag == sym_k_widget_entry,
1980 "widget missing from the stack");
1982 if (widget_entry->header.b_type != uil_sym_user_defined_object)
1984 yystype * source_frame;
1986 source_frame = & yylval;
1987 diag_issue_diagnostic
1989 _sar_source_position ( source_frame ),
1990 diag_object_text (widget_entry->header.b_type) );
1996 widget_entry->az_create_proc =
1997 (sym_proc_ref_entry_type *) proc_id_frame->value.az_symbol_entry;
2008 ** FUNCTIONAL DESCRIPTION:
2010 ** This routine adds an entry to a list.
2012 ** FORMAL PARAMETERS:
2014 ** entry_frame address of the parse stack frame for
2015 ** the entry to be added to the list.
2021 ** IMPLICIT OUTPUTS:
2036 void sar_add_list_entry
2039 yystype * entry_frame;
2042 yystype * list_frame;
2043 sym_list_entry_type * list_entry;
2044 sym_obj_entry_type * entry_entry;
2046 yystype * source_frame;
2048 source_frame = & yylval;
2050 /* Search the syntax stack for the list frame. */
2052 list_frame = sem_find_object (entry_frame - 1);
2053 list_entry = (sym_list_entry_type *) list_frame->value.az_symbol_entry;
2055 _assert (list_entry->header.b_tag == sym_k_list_entry,
2056 "list entry missing");
2058 entry_entry = (sym_obj_entry_type *) entry_frame->value.az_symbol_entry;
2061 ** If we are including a list within a list, put a nested list entry
2062 ** in the list, and point it to the actual list.
2065 if (entry_entry->header.b_tag == sym_k_list_entry)
2067 sym_nested_list_entry_type *nested_entry;
2070 ** If this list is a reference to a previously defined list,
2071 ** then use the previously defined list.
2073 if (entry_entry->obj_header.az_reference != NULL)
2075 entry_entry = (sym_obj_entry_type *)
2076 entry_entry->obj_header.az_reference;
2077 _assert (entry_entry->header.b_tag == sym_k_list_entry,
2078 "entry list entry missing");
2082 ** Create a nested list entry to reference the nested list. This
2083 ** becomes the entry which will be added to the current list.
2085 nested_entry = (sym_nested_list_entry_type *)
2086 sem_allocate_node (sym_k_nested_list_entry,
2087 sym_k_nested_list_entry_size);
2088 nested_entry->header.b_type = entry_entry->header.b_type;
2089 nested_entry->az_list = (sym_list_entry_type *) entry_entry;
2090 entry_entry = (sym_obj_entry_type *) nested_entry;
2093 if (entry_entry->header.b_tag == sym_k_name_entry)
2095 sym_nested_list_entry_type *nested_entry;
2097 ** This is a forward reference to a named, nested list.
2099 nested_entry = (sym_nested_list_entry_type *)
2100 sem_allocate_node (sym_k_nested_list_entry,
2101 sym_k_nested_list_entry_size);
2103 sym_make_value_forward_ref (entry_frame,
2104 (char*)&(nested_entry->az_list),
2105 sym_k_patch_list_add);
2107 entry_entry = (sym_obj_entry_type *) nested_entry;
2111 ** Add the entry to front of the list
2112 ** The nested entry created above is included in this processing.
2114 entry_entry->obj_header.az_next =
2115 (sym_entry_type *) list_entry->obj_header.az_next;
2116 list_entry->obj_header.az_next =
2117 (sym_entry_type *) entry_entry;
2118 list_entry->w_count++;
2120 entry_frame->b_tag = sar_k_null_frame;
2126 ** FUNCTIONAL DESCRIPTION:
2128 ** This routine adds a forward referenced list entry to a list.
2131 ** FORMAL PARAMETERS:
2133 ** entry_frame address of the parse stack frame for
2134 ** the entry to be added to the list.
2140 ** IMPLICIT OUTPUTS:
2155 void sar_add_forward_list_entry
2158 yystype * entry_frame;
2161 yystype * list_frame;
2162 sym_list_entry_type * list_entry;
2163 sym_obj_entry_type * entry_entry;
2164 sym_name_entry_type * name_entry;
2165 yystype * source_frame;
2166 sym_nested_list_entry_type *nested_entry;
2168 source_frame = & yylval;
2170 /* Search the syntax stack for the list frame. */
2172 list_frame = sem_find_object (entry_frame - 1);
2173 list_entry = (sym_list_entry_type *) list_frame->value.az_symbol_entry;
2175 _assert (list_entry->header.b_tag == sym_k_list_entry,
2176 "list entry missing");
2178 name_entry = (sym_name_entry_type *) entry_frame->value.az_symbol_entry;
2180 nested_entry = (sym_nested_list_entry_type *)
2181 sem_allocate_node (sym_k_nested_list_entry,
2182 sym_k_nested_list_entry_size);
2184 sym_make_value_forward_ref (entry_frame,
2185 (char*)&(nested_entry->az_list),
2186 sym_k_patch_list_add);
2188 entry_entry = (sym_obj_entry_type *) nested_entry;
2191 ** Add the entry to front of the list
2192 ** The nested entry created above is included in this processing.
2194 entry_entry->obj_header.az_next =
2195 (sym_entry_type *) list_entry->obj_header.az_next;
2196 list_entry->obj_header.az_next =
2197 (sym_entry_type *) entry_entry;
2198 list_entry->w_count++;
2200 entry_frame->b_tag = sar_k_null_frame;
2206 ** FUNCTIONAL DESCRIPTION:
2208 ** This routine verifies that the list or widget has been defined
2209 ** correctly. Virtually all such validation is actually done in pass 2.
2211 ** FORMAL PARAMETERS:
2213 ** current_frame address of the current syntax stack frame
2219 ** IMPLICIT OUTPUTS:
2234 void sar_verify_object ( current_frame )
2236 yystype * current_frame;
2239 yystype * obj_frame;
2240 sym_widget_entry_type * widget_entry;
2241 unsigned int widget_type;
2242 sym_obj_entry_type * obj_entry;
2243 yystype * source_frame;
2248 * Search the syntax stack for the object frame.
2250 source_frame = & yylval;
2251 obj_frame = sem_find_object (current_frame - 1);
2252 obj_entry = (sym_obj_entry_type *) obj_frame->value.az_symbol_entry;
2254 switch (obj_entry->header.b_tag)
2256 case sym_k_gadget_entry:
2257 case sym_k_widget_entry:
2260 * Clear the definition in progress bit.
2262 _assert (obj_entry->obj_header.b_flags & sym_m_def_in_progress,
2263 "widget definition not in progress");
2264 obj_entry->obj_header.b_flags &= (~ sym_m_def_in_progress);
2266 case sym_k_list_entry:
2268 * Clear the definition in progress bit and return.
2270 _assert (obj_entry->obj_header.b_flags & sym_m_def_in_progress,
2271 "list definition not in progress");
2272 obj_entry->obj_header.b_flags &= (~ sym_m_def_in_progress);
2275 case sym_k_error_entry:
2279 _assert (FALSE, "list or widget missing from the stack");
2285 * If this is a user_defined widget, be sure the create proc was
2286 * specified if this is a declaration, and not specified if it
2289 widget_entry = (sym_widget_entry_type *) obj_entry;
2290 widget_type = widget_entry->header.b_type;
2291 if (widget_type == uil_sym_user_defined_object)
2293 if ((widget_entry->obj_header.b_flags & sym_m_obj_is_reference) != 0)
2295 if (widget_entry->az_create_proc != NULL)
2297 diag_issue_diagnostic
2299 _sar_source_pos2(widget_entry),
2300 diag_object_text (widget_type) );
2301 widget_entry->header.b_type = sym_k_error_object;
2306 if (widget_entry->az_create_proc == NULL)
2308 diag_issue_diagnostic
2310 _sar_source_pos2(widget_entry),
2311 diag_object_text (widget_type) );
2312 widget_entry->header.b_type = sym_k_error_object;
2323 ** FUNCTIONAL DESCRIPTION:
2325 ** This routine allocates a symbol node of the specified size
2328 ** FORMAL PARAMETERS:
2330 ** node_tag tag of node to allocate
2331 ** node_size size of node to allocate
2336 ** IMPLICIT OUTPUTS:
2341 ** the address of the allocated node
2345 ** The node is saved in the allocated node list
2350 sym_entry_type * sem_allocate_node
2351 (unsigned char node_tag, unsigned short node_size )
2355 sym_entry_type * node_ptr;
2357 node_ptr = (sym_entry_type *) XtCalloc (1, node_size);
2358 node_ptr->header.w_node_size = node_size;
2359 node_ptr->header.b_tag = node_tag;
2360 UrmPlistAppendPointer (sym_az_allocated_nodes, (XtPointer)node_ptr);
2369 ** FUNCTIONAL DESCRIPTION:
2371 ** This routine puts a symbol node on the free node list.
2373 ** FORMAL PARAMETERS:
2375 ** node_ptr address of node to put on the free list
2380 ** IMPLICIT OUTPUTS:
2392 void sem_free_node ( node_ptr )
2394 sym_entry_type * node_ptr;
2398 UrmPlistAppendPointer (sym_az_freed_nodes, (XtPointer)node_ptr);