465 lines
11 KiB
C
465 lines
11 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-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
|
|
*/
|
|
/*
|
|
* @OSF_COPYRIGHT@
|
|
* COPYRIGHT NOTICE
|
|
* Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
|
|
* ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
|
|
* the full copyright text.
|
|
*/
|
|
/*
|
|
* HISTORY
|
|
*/
|
|
#ifdef REV_INFO
|
|
#ifndef lint
|
|
static char rcsid[] = "$XConsortium: UilSarProc.c /main/12 1995/07/14 09:37:43 drk $"
|
|
#endif
|
|
#endif
|
|
|
|
/*
|
|
* (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
|
|
|
|
/*
|
|
**++
|
|
** FACILITY:
|
|
**
|
|
** User Interface Language Compiler (UIL)
|
|
**
|
|
** ABSTRACT:
|
|
**
|
|
** This module contain the routines for processing procedures.
|
|
**
|
|
**--
|
|
**/
|
|
|
|
|
|
/*
|
|
**
|
|
** INCLUDE FILES
|
|
**
|
|
**/
|
|
|
|
#include "UilDefI.h"
|
|
|
|
|
|
/*
|
|
**
|
|
** DEFINE and MACRO DEFINITIONS
|
|
**
|
|
**/
|
|
|
|
|
|
|
|
/*
|
|
**
|
|
** EXTERNAL VARIABLE DECLARATIONS
|
|
**
|
|
**/
|
|
|
|
|
|
/*
|
|
**
|
|
** GLOBAL VARIABLE DECLARATIONS
|
|
**
|
|
**/
|
|
|
|
|
|
/*
|
|
**
|
|
** OWN VARIABLE DECLARATIONS
|
|
**
|
|
**/
|
|
|
|
|
|
/*
|
|
**++
|
|
** FUNCTIONAL DESCRIPTION:
|
|
**
|
|
** This function create the procedure definition entry symbol
|
|
** node a procedure declaration.
|
|
**
|
|
** FORMAL PARAMETERS:
|
|
**
|
|
** id_frame ptr to token frame for the procedure name
|
|
** param_frame ptr to token frame or null frame holding the
|
|
** type of the argument
|
|
** class_frame ptr to frame whose b_flags holds private, etc. info
|
|
**
|
|
** IMPLICIT INPUTS:
|
|
**
|
|
** sym_az_current_section_entry the "current" section list
|
|
**
|
|
** IMPLICIT OUTPUTS:
|
|
**
|
|
** none
|
|
**
|
|
** FUNCTION VALUE:
|
|
**
|
|
** void
|
|
**
|
|
** SIDE EFFECTS:
|
|
**
|
|
** errors may be issued for previously defined name
|
|
**
|
|
**--
|
|
**/
|
|
|
|
void
|
|
sar_create_procedure(XmConst yystype *id_frame,
|
|
XmConst yystype *param_frame,
|
|
XmConst yystype *class_frame,
|
|
XmConst yystype *semi_frame)
|
|
{
|
|
sym_name_entry_type *name_entry;
|
|
sym_proc_def_entry_type *proc_def_entry;
|
|
sym_section_entry_type *section_entry;
|
|
sym_obj_entry_type *obj_entry;
|
|
|
|
/*
|
|
** Call standard routine to check name entry for id_frame.
|
|
** This routine handles font name, color names, etc used as ids
|
|
*/
|
|
|
|
name_entry = (sym_name_entry_type *) sem_dcl_name( id_frame );
|
|
|
|
if (name_entry == NULL)
|
|
return;
|
|
|
|
/*
|
|
** Allocate the procedure definition entry and fill it in
|
|
*/
|
|
|
|
proc_def_entry = (sym_proc_def_entry_type *)
|
|
sem_allocate_node (sym_k_proc_def_entry, sym_k_proc_def_entry_size);
|
|
|
|
proc_def_entry->b_widget_type = uil_max_object + 1;
|
|
proc_def_entry->obj_header.az_name = (sym_name_entry_type *) name_entry;
|
|
name_entry->az_object = (sym_entry_type *) proc_def_entry;
|
|
|
|
/*
|
|
** Parameter frame has 4 cases:
|
|
** 1) no argument checking desired
|
|
** syntax: PROCEDURE id
|
|
** 2) argument checking desired - no argument
|
|
** syntax: PROCEDURE id( )
|
|
** 3) argument checking desired - single argument
|
|
** syntax: PROCEDURE id( type )
|
|
** 4) argument checking desired - single typed widget argument
|
|
** syntax: PROCEDURE id( CLASS_NAME )
|
|
** These cases are distinguished as follows:
|
|
** 1) tag = null type = 0
|
|
** 2) tag = null type = sar_k_no_value
|
|
** 3) tag = token type = argument type
|
|
** 4) tag = object type = widget type
|
|
*/
|
|
|
|
proc_def_entry->v_arg_checking = TRUE;
|
|
|
|
switch (param_frame->b_tag)
|
|
{
|
|
case sar_k_null_frame:
|
|
if (param_frame->b_type == sym_k_no_value )
|
|
{
|
|
proc_def_entry->b_arg_count = 0;
|
|
proc_def_entry->b_arg_type = sym_k_no_value;
|
|
}
|
|
else
|
|
proc_def_entry->v_arg_checking = FALSE;
|
|
|
|
break;
|
|
|
|
case sar_k_token_frame:
|
|
proc_def_entry->b_arg_type = param_frame->b_type;
|
|
proc_def_entry->b_arg_count = 1;
|
|
break;
|
|
|
|
case sar_k_object_frame:
|
|
_assert((param_frame->b_type == sym_k_widget_entry),
|
|
"object frame not widget entry");
|
|
|
|
obj_entry =
|
|
(sym_obj_entry_type *)param_frame->value.az_symbol_entry;
|
|
|
|
proc_def_entry->b_arg_type = sym_k_widget_ref_value;
|
|
proc_def_entry->b_arg_count = 1;
|
|
proc_def_entry->b_widget_type = obj_entry->header.b_type;
|
|
break;
|
|
|
|
default:
|
|
_assert( FALSE, "param frame in error" );
|
|
|
|
}
|
|
|
|
/*
|
|
** Process the class clause
|
|
*/
|
|
|
|
switch (class_frame->b_flags)
|
|
{
|
|
case sym_m_exported:
|
|
sym_make_external_def( name_entry );
|
|
|
|
case sym_m_private:
|
|
case sym_m_imported:
|
|
break;
|
|
|
|
default:
|
|
_assert( FALSE, "class frame in error" );
|
|
|
|
}
|
|
|
|
proc_def_entry->obj_header.b_flags = class_frame->b_flags;
|
|
|
|
/*
|
|
** save the source file info for this procedure entry
|
|
*/
|
|
_sar_save_source_info (&proc_def_entry->header, id_frame, semi_frame );
|
|
sar_assoc_comment((sym_obj_entry_type *)proc_def_entry); /* preserve comments */
|
|
|
|
/*
|
|
** allocate a section entry to link the proc_def entry into the structure
|
|
*/
|
|
section_entry = (sym_section_entry_type *) sem_allocate_node
|
|
(sym_k_section_entry, sym_k_section_entry_size);
|
|
|
|
/*
|
|
** Link this entry off of the current section list
|
|
*/
|
|
section_entry->next = (sym_entry_type *) sym_az_current_section_entry->entries;
|
|
sym_az_current_section_entry->entries = (sym_entry_type *) section_entry;
|
|
|
|
section_entry->entries = (sym_entry_type *) proc_def_entry;
|
|
|
|
}
|
|
|
|
/*
|
|
**++
|
|
** FUNCTIONAL DESCRIPTION:
|
|
**
|
|
** This function processes a reference to a procedure.
|
|
**
|
|
** FORMAL PARAMETERS:
|
|
**
|
|
** id_frame ptr to token frame for the procedure name
|
|
** value_frame ptr to token frame or null frame holding the
|
|
** value of the argument to the procedure
|
|
** context value indicating how the procedure is being used
|
|
**
|
|
** IMPLICIT INPUTS:
|
|
**
|
|
** none
|
|
**
|
|
** IMPLICIT OUTPUTS:
|
|
**
|
|
** none
|
|
**
|
|
** FUNCTION VALUE:
|
|
**
|
|
** a procedure reference entry / NULL in case of an illegal reference
|
|
**
|
|
** SIDE EFFECTS:
|
|
**
|
|
** errors may be issued
|
|
**
|
|
**--
|
|
**/
|
|
|
|
sym_proc_ref_entry_type
|
|
*sem_reference_procedure( yystype *id_frame,
|
|
XmConst yystype *value_frame,
|
|
XmConst int context )
|
|
{
|
|
sym_value_entry_type *value_entry;
|
|
sym_proc_def_entry_type *proc_def_entry;
|
|
sym_proc_ref_entry_type *proc_ref_entry;
|
|
|
|
/*
|
|
** Call standard routine to check name entry for id_frame.
|
|
** This routine handles font name, color names, etc used as ids
|
|
*/
|
|
|
|
proc_def_entry =
|
|
(sym_proc_def_entry_type *)
|
|
sem_ref_name( id_frame, sym_k_proc_def_entry );
|
|
|
|
switch (value_frame->b_tag)
|
|
{
|
|
case sar_k_null_frame:
|
|
value_entry = NULL;
|
|
break;
|
|
|
|
case sar_k_value_frame:
|
|
if ((value_frame->b_flags & sym_m_forward_ref) != 0)
|
|
value_entry = NULL;
|
|
else
|
|
value_entry = (sym_value_entry_type *)
|
|
value_frame->value.az_symbol_entry;
|
|
break;
|
|
|
|
case sar_k_object_frame:
|
|
value_entry =
|
|
(sym_value_entry_type *) value_frame->value.az_symbol_entry;
|
|
break;
|
|
|
|
default:
|
|
_assert( FALSE, "actual arg in error" );
|
|
}
|
|
|
|
/*
|
|
** Allocate the procedure reference entry and fill it in
|
|
*/
|
|
|
|
proc_ref_entry = (sym_proc_ref_entry_type *)
|
|
sem_allocate_node (sym_k_proc_ref_entry, sym_k_proc_ref_entry_size);
|
|
|
|
if ((id_frame->b_flags & sym_m_forward_ref) != 0)
|
|
sym_make_value_forward_ref (id_frame,
|
|
(char*)&(proc_ref_entry->az_proc_def), sym_k_patch_list_add);
|
|
else
|
|
proc_ref_entry->az_proc_def = proc_def_entry;
|
|
|
|
if ((value_frame->b_flags & sym_m_forward_ref) != 0)
|
|
sym_make_value_forward_ref (value_frame,
|
|
(char*)&(proc_ref_entry->az_arg_value), sym_k_patch_add);
|
|
else
|
|
proc_ref_entry->az_arg_value = value_entry;
|
|
|
|
/*
|
|
** Apply context constraints
|
|
**
|
|
** If this is a procedure being used as a user object,
|
|
** it should not have any arguments. The arguments to such
|
|
** a procedure are always a parent widget id and an argument list.
|
|
** This constraint is currently inforced by the grammar.
|
|
**
|
|
** At this time the compiler permits all types of values for callback
|
|
** arguments. This may be limited shortly when we see if it is
|
|
** reasonable to pass fonts, colors, reasons, etc.
|
|
*/
|
|
|
|
return proc_ref_entry;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
**++
|
|
** FUNCTIONAL DESCRIPTION:
|
|
**
|
|
** This function checks to see if a object is defined with the name
|
|
** corresponding to the id given in the first parameter.
|
|
**
|
|
** FORMAL PARAMETERS:
|
|
**
|
|
** id_frame ptr to a token frame on the parse stack holding the name
|
|
** tag the type of construct needed
|
|
**
|
|
** IMPLICIT INPUTS:
|
|
**
|
|
** none
|
|
**
|
|
** IMPLICIT OUTPUTS:
|
|
**
|
|
** none
|
|
**
|
|
** FUNCTION VALUE:
|
|
**
|
|
** ptr to a symbol entry for construct or NULL
|
|
**
|
|
** SIDE EFFECTS:
|
|
**
|
|
** error message if the name is undefined or for a different construct
|
|
** forward_ref bit may be turned on in id_frame
|
|
**--
|
|
**/
|
|
|
|
sym_entry_type
|
|
*sem_ref_name(yystype *id_frame,
|
|
XmConst int tag)
|
|
{
|
|
sym_name_entry_type *name_entry;
|
|
sym_entry_type *symbol_entry;
|
|
|
|
_assert( id_frame->b_tag == sar_k_token_frame, "arg1 not id frame" );
|
|
|
|
/*
|
|
** The id frame may hold a name or the keyword for a font name, color
|
|
** name, reason name etc. If it is one of these special name, then
|
|
** we must see if the symbol table holds a name for the special type.
|
|
*/
|
|
|
|
if (id_frame->b_type != NAME)
|
|
{
|
|
name_entry =
|
|
sym_find_name
|
|
( id_frame->value.az_keyword_entry->b_length,
|
|
id_frame->value.az_keyword_entry->at_name );
|
|
|
|
if (name_entry == NULL)
|
|
{
|
|
diag_issue_diagnostic
|
|
( d_undefined,
|
|
_sar_source_position( id_frame ),
|
|
diag_tag_text( sym_k_proc_def_entry ),
|
|
id_frame->value.az_keyword_entry->at_name );
|
|
|
|
return NULL;
|
|
}
|
|
|
|
}
|
|
else
|
|
name_entry =
|
|
(sym_name_entry_type *) id_frame->value.az_symbol_entry;
|
|
|
|
/*
|
|
** If the name entry already has no object linked from it, we are
|
|
** referencing an undefined object.
|
|
*/
|
|
|
|
symbol_entry = name_entry->az_object;
|
|
|
|
if (symbol_entry == NULL )
|
|
{
|
|
id_frame->b_flags |= sym_m_forward_ref;
|
|
return NULL;
|
|
}
|
|
/*
|
|
** If the name entry has the wrong type of object, this is also
|
|
** an error.
|
|
*/
|
|
|
|
if (symbol_entry->header.b_tag != tag )
|
|
{
|
|
diag_issue_diagnostic
|
|
( d_ctx_req,
|
|
_sar_source_position( id_frame ),
|
|
diag_tag_text( tag ),
|
|
diag_tag_text( symbol_entry->header.b_tag ) );
|
|
|
|
return NULL;
|
|
}
|
|
|
|
return symbol_entry;
|
|
|
|
}
|