/*
* Motif
*
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/*
* HISTORY
*/
#ifdef REV_INFO
#ifndef lint
static char rcsid[] = "$XConsortium: UilP2Reslv.c /main/11 1995/07/14 09:36:35 drk $"
#endif
#endif
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/*
* (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
/*
**++
** FACILITY:
**
** User Interface Language Compiler (UIL)
**
** ABSTRACT:
**
** This module contain the second pass routines for resolving forward
** references.
**
**--
**/
/*
**
** INCLUDE FILES
**
**/
#include "UilDefI.h"
/*
**
** DEFINE and MACRO DEFINITIONS
**
**/
/*
**
** EXTERNAL VARIABLE DECLARATIONS
**
**/
/*
**
** GLOBAL VARIABLE DECLARATIONS
**
**/
/*
**
** OWN VARIABLE DECLARATIONS
**
**/
/*
**++
** FUNCTIONAL DESCRIPTION:
**
** This function processes forward references from the first pass.
**
** FORMAL PARAMETERS:
**
** none
**
** IMPLICIT INPUTS:
**
** sym_az_forward_ref_chain
** sym_az_val_forward_ref_chain
**
** IMPLICIT OUTPUTS:
**
** none
**
** FUNCTION VALUE:
**
** void
**
** SIDE EFFECTS:
**
** error messages may be issued for objects that are still undefined
** or of the wrong type
**
**--
**/
void sem_resolve_forward_refs()
{
sym_forward_ref_entry_type * fwd_entry;
sym_forward_ref_entry_type * next_fwd_entry;
sym_val_forward_ref_entry_type * fwd_val_entry;
sym_val_forward_ref_entry_type * next_fwd_val_entry;
sym_widget_entry_type ** target_obj_entry;
sym_value_entry_type ** target_val_entry;
sym_parent_list_type * parent_node;
sym_parent_list_type * parent_ptr;
int found;
/*
** Forward references are placed on a chain by the first pass of
** the compiler. This routine walks the chain checking that
** 1) name is now defined
** 2) name points to the correct type of object
*/
for (fwd_entry = sym_az_forward_ref_chain;
fwd_entry != NULL;
fwd_entry = next_fwd_entry)
{
sym_name_entry_type * name_entry;
sym_widget_entry_type * object_entry;
unsigned short int object_type;
/*
** Save the pointer to the next forward entry so we can free the current
** entry after it is processed.
*/
next_fwd_entry = fwd_entry->az_next_ref;
/*
** Call the Status callback routine to report our progress.
*/
/* %COMPLETE */
Uil_percent_complete = 60;
if (Uil_cmd_z_command.status_cb != (Uil_continue_type(*)())NULL)
diag_report_status();
object_type = fwd_entry->header.b_type;
name_entry = fwd_entry->az_name;
object_entry = (sym_widget_entry_type *) name_entry->az_object;
if (object_entry == NULL)
{
diag_issue_diagnostic
( d_never_def,
_sar_source_pos2 (fwd_entry),
diag_object_text( object_type ),
name_entry->c_text );
continue;
}
/*
** Make sure object references are to correct type of object.
** A forward reference naming a widget class may be correctly
** resolved by the corresponding gadget class, and vice versa.
*/
if ((object_entry->header.b_type!=object_type) &&
(uil_gadget_variants[object_entry->header.b_type]!=object_type) &&
(uil_gadget_variants[object_type]!=object_entry->header.b_type))
{
diag_issue_diagnostic
(d_ctx_req,
_sar_source_pos2(fwd_entry),
diag_object_text(object_type),
diag_object_text(object_entry->header.b_type));
continue;
}
target_obj_entry =
(sym_widget_entry_type * *) fwd_entry->a_update_location;
*target_obj_entry = object_entry;
/*
** Update objects on forward refernce chain so that their parent_lists point
** to the objects which reference them
*/
if (fwd_entry -> parent != NULL)
{
found = FALSE;
for (parent_ptr = object_entry -> parent_list;
((parent_ptr != NULL) && (found == FALSE));
parent_ptr = parent_ptr -> next)
{
if (parent_ptr -> parent == fwd_entry -> parent)
found = TRUE;
}
if (found == FALSE)
{
parent_node = (sym_parent_list_type *)
sem_allocate_node (sym_k_parent_list_entry,
sym_k_parent_list_size);
parent_node -> next = object_entry -> parent_list;
object_entry -> parent_list = parent_node;
parent_node -> parent = fwd_entry -> parent;
}
}
/*
** Free the Forward reference entry now that it is no longer needed
*/
sem_free_node(( sym_entry_type *)fwd_entry);
}
/*
** Now resolve the forward references to values
**/
/*
** Forward references are placed on a chain by the first pass of
** the compiler. This routine walks the chain checking that
** 1) name is now defined
** 2) name points to the correct type of value
*/
for (fwd_val_entry = sym_az_val_forward_ref_chain;
fwd_val_entry != NULL;
fwd_val_entry = next_fwd_val_entry)
{
sym_name_entry_type * name_entry;
sym_value_entry_type * value_entry;
sym_obj_entry_type * obj_entry;
/*
** Save the pointer to the next forward entry so we can free the current
** entry after it is processed.
*/
next_fwd_val_entry = fwd_val_entry->az_next_ref;
/*
** Call the Status callback routine to report our progress.
*/
/* %COMPLETE */
Uil_percent_complete = 60;
if (Uil_cmd_z_command.status_cb != (Uil_continue_type(*)())NULL)
diag_report_status();
name_entry = fwd_val_entry->az_name;
value_entry = (sym_value_entry_type *) name_entry->az_object;
obj_entry = (sym_obj_entry_type *) name_entry->az_object;
if (value_entry == NULL)
{
diag_issue_diagnostic
( d_never_def,
_sar_source_pos2 (fwd_val_entry),
"value",
name_entry->c_text );
continue;
}
switch (fwd_val_entry->fwd_ref_flags)
{
case (sym_k_patch_add):
case (sym_k_patch_list_add):
{
target_val_entry =
(sym_value_entry_type * *) fwd_val_entry->a_update_location;
*target_val_entry = value_entry;
break;
}
default:
_assert(FALSE, "Illegal forward reference");
}
/*
** Free the Forward reference entry now that it is no longer needed
*/
sem_free_node(( sym_entry_type *)fwd_val_entry);
}
}