/*
*
* (c) Copyright 1989 OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1989 HEWLETT-PACKARD COMPANY
* (c) Copyright 1989 DIGITAL EQUIPMENT CORPORATION
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this
* file for any purpose is hereby granted without fee, provided that
* the above copyright notices and this notice appears in all source
* code copies, and that none of the names of Open Software
* Foundation, Inc., Hewlett-Packard Company, or Digital Equipment
* Corporation be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission. Neither Open Software Foundation, Inc., Hewlett-
* Packard Company, nor Digital Equipment Corporation makes any
* representations about the suitability of this software for any
* purpose.
*
*/
/*
**
** NAME:
**
** acf.y
**
** FACILITY:
**
** Interface Definition Language (IDL) Compiler
**
** ABSTRACT:
**
** "yacc" source file for Attribute Configuration File (ACF) parser.
**
** VERSION: DCE 1.0
**
*/
/*******************************
* yacc declarations section *
*******************************/
%{
/*----------------------*
* yacc included code *
*----------------------*/
/* Declarations in this section are copied from yacc source to y_tab.c. */
#include <nidl.h> /* IDL compiler-wide defs */
#include <acf.h> /* ACF include file - keep first! */
#include <ast.h> /* Abstract Syntax Tree defs */
#include <astp.h> /* Import AST processing routine defs */
#include <command.h> /* Command line defs */
#include <message.h> /* Error message defs */
#include <nidlmsg.h> /* Error message IDs */
#include <files.h>
#include <propagat.h>
#include <checker.h>
extern AST_interface_n_t *the_interface; /* Ptr to AST interface node */
extern boolean ASTP_parsing_main_idl; /* True when parsing main IDL */
typedef union /* Attributes bitmask */
{
struct
{
unsigned auto_handle : 1;
unsigned binding_callout: 1;
unsigned code : 1;
unsigned comm_status : 1;
unsigned cs_char : 1;
unsigned cs_drtag : 1;
unsigned cs_rtag : 1;
unsigned cs_stag : 1;
unsigned cs_tag_rtn : 1;
unsigned decode : 1;
unsigned enable_allocate: 1;
unsigned encode : 1;
unsigned explicit_handle: 1;
unsigned extern_exceps : 1;
unsigned fault_status : 1;
unsigned heap : 1;
unsigned implicit_handle: 1;
unsigned in_line : 1;
unsigned nocode : 1;
unsigned out_of_line : 1;
unsigned represent_as : 1;
} bit;
long mask;
} acf_attrib_t;
typedef struct acf_param_t /* ACF parameter info structure */
{
struct acf_param_t *next; /* Forward link */
acf_attrib_t parameter_attr; /* Parameter attributes */
NAMETABLE_id_t param_id; /* Parameter name */
} acf_param_t;
static acf_attrib_t interface_attr, /* Interface attributes */
type_attr, /* Type attributes */
operation_attr, /* Operation attributes */
parameter_attr; /* Parameter attributes */
static char *interface_name, /* Interface name */
*impl_name, /* Implicit handle name */
*type_name, /* Current type name */
*repr_type_name, /* Current represent_as type */
*cs_char_type_name, /* Current cs_char type */
*operation_name, /* Current operation name */
*cs_tag_rtn_name, /* Current cs_tag_rtn name */
*binding_callout_name; /* Current binding_callout name */
static boolean named_type; /* True if parsed type is named type */
static AST_include_n_t *include_list, /* List of AST include nodes */
*include_p; /* Ptr to a created include node */
static acf_param_t *parameter_list, /* Param list for curr. operation */
*parameter_free_list; /* List of available acf_param_t */
static boolean parameter_attr_list; /* True if param attrs specified */
static boolean *cmd_opt; /* Array of command option flags */
static void **cmd_val; /* Array of command option values */
/*
* Some function prototypes
*/
static acf_param_t *alloc_param(void);
static void acf_error ();
static void acf_warning ();
static void process_cs_char_type (AST_interface_n_t *, AST_type_n_t *, char *);
static void process_rep_as_type (AST_interface_n_t *, AST_type_n_t *, char *);
static void append_parameter (AST_operation_n_t *, char *, acf_attrib_t *);
#ifdef DUMPERS
static void dump_attributes (char *, char *, acf_attrib_t *node_attr_p);
#endif
void add_param_to_list (acf_param_t *, acf_param_t **);
static void free_param_list (acf_param_t **);
static boolean lookup_parameter (AST_operation_n_t *, char *, boolean, NAMETABLE_id_t *, AST_parameter_n_t **);
static boolean lookup_exception (NAMETABLE_id_t, boolean, AST_exception_n_t **);
static boolean lookup_type (char *, boolean, NAMETABLE_id_t *, AST_type_n_t **);
static boolean lookup_operation (char *, boolean, NAMETABLE_id_t *, AST_operation_n_t **);
%}
/*------------------------------------*
* yylval and yyval type definition *
*------------------------------------*/
/*
* Union declaration defines the possible datatypes of the external variables
* yylval and yyval.
*/
%union
{
NAMETABLE_id_t y_id; /* Identifier */
STRTAB_str_t y_string; /* Text string */
}
/*-----------------------------*
* Tokens used by the parser *
*-----------------------------*/
/* Keywords */
%token AUTO_HANDLE_KW
%token BINDING_CALLOUT_KW
%token CODE_KW
%token COMM_STATUS_KW
%token CS_CHAR_KW
%token CS_TAG_RTN_KW
%token ENABLE_ALLOCATE_KW
%token EXPLICIT_HANDLE_KW
%token EXTERN_EXCEPS_KW
%token FAULT_STATUS_KW
%token HANDLE_T_KW
%token HEAP_KW
%token IMPLICIT_HANDLE_KW
%token INCLUDE_KW
%token INTERFACE_KW
%token IN_LINE_KW
%token NOCODE_KW
%token OUT_OF_LINE_KW
%token REPRESENT_AS_KW
%token TYPEDEF_KW
/* Punctuation */
%token COMMA
%token LBRACE
%token LBRACKET
%token LPAREN
%token RBRACE
%token RBRACKET
%token RPAREN
%token SEMI
%token UNKNOWN /* Unrecognized by LEX */
/* Tokens setting yylval */
%token <y_id> IDENTIFIER
%token <y_string> STRING
/*-----------------------------*
* Starting state for parser *
*-----------------------------*/
%start acf_interface
%%
/************************
* yacc rules section *
************************/
acf_interface:
acf_interface_header acf_interface_body
;
acf_interface_header:
acf_interface_attr_list INTERFACE_KW acf_interface_name
{
char *ast_int_name; /* Interface name in AST node */
NAMETABLE_id_t type_id; /* Nametable id of impl_handle type */
NAMETABLE_id_t impl_name_id; /* Nametable id of impl_handle var */
AST_type_n_t *type_p; /* Ptr to implicit_handle type node */
#ifdef DUMPERS
if (cmd_opt[opt_dump_acf])
dump_attributes("ACF interface", interface_name, &interface_attr);
#endif
/* Store source information. */
if (the_interface->fe_info != NULL)
{
the_interface->fe_info->acf_file = error_file_name_id;
the_interface->fe_info->acf_source_line = acf_yylineno;
}
/*
* Interface attributes are saved for main and imported interfaces.
* the_interface = pointer to main or imported interface node
*
* Make sure that the interface name in the ACF agrees with the
* interface name in the main IDL file. Then set the parsed
* attributes in the interface node.
*
* interface_attr = bitmask of interface attributes parsed.
* interface_name = ACF interface name parsed.
*/
NAMETABLE_id_to_string(the_interface->name, &ast_int_name);
if (strcmp(interface_name, ast_int_name) != 0)
{
char *acf_int_name; /* Ptr to permanent copy */
NAMETABLE_id_t name_id; /* Handle on permanent copy */
char *file_name; /* Related file name */
name_id = NAMETABLE_add_id(interface_name);
NAMETABLE_id_to_string(name_id, &acf_int_name);
STRTAB_str_to_string(the_interface->fe_info->file, &file_name);
acf_error(NIDL_INTNAMDIF, acf_int_name, ast_int_name);
acf_error(NIDL_NAMEDECLAT, ast_int_name, file_name,
the_interface->fe_info->source_line);
}
else
{
if (interface_attr.bit.code)
AST_SET_CODE(the_interface);
if (interface_attr.bit.nocode)
AST_SET_NO_CODE(the_interface);
if (interface_attr.bit.decode)
AST_SET_DECODE(the_interface);
if (interface_attr.bit.encode)
AST_SET_ENCODE(the_interface);
if (interface_attr.bit.explicit_handle)
AST_SET_EXPLICIT_HANDLE(the_interface);
if (interface_attr.bit.in_line)
AST_SET_IN_LINE(the_interface);
if (interface_attr.bit.out_of_line)
AST_SET_OUT_OF_LINE(the_interface);
if (interface_attr.bit.auto_handle)
AST_SET_AUTO_HANDLE(the_interface);
if (interface_attr.bit.cs_tag_rtn)
the_interface->cs_tag_rtn_name = NAMETABLE_add_id(cs_tag_rtn_name);
if (interface_attr.bit.binding_callout)
the_interface->binding_callout_name = NAMETABLE_add_id(binding_callout_name);
if (interface_attr.bit.implicit_handle)
{
/* Store the [implicit_handle] variable name in nametbl. */
impl_name_id = NAMETABLE_add_id(impl_name);
/*
* Store the type and name information in the AST. If a
* named type, determine whether it is an IDL-defined type
* and process accordingly. Otherwise the type is handle_t.
*/
if (named_type)
{
if (lookup_type(type_name, FALSE, &type_id, &type_p))
{
the_interface->implicit_handle_name = impl_name_id;
the_interface->implicit_handle_type = type_p;
the_interface->implicit_handle_type_name = type_p->name;
if (AST_HANDLE_SET(type_p))
AST_SET_IMPLICIT_HANDLE_G(the_interface);
}
else /* A user-defined type, not defined in IDL */
{
/* Store the user type name in nametbl. */
the_interface->implicit_handle_type_name
= NAMETABLE_add_id(type_name);
the_interface->implicit_handle_name = impl_name_id;
the_interface->implicit_handle_type = NULL;
AST_SET_IMPLICIT_HANDLE_G(the_interface);
}
}
else
{
the_interface->implicit_handle_name = impl_name_id;
the_interface->implicit_handle_type = ASTP_handle_ptr;
}
}
}
interface_name = NULL;
type_name = NULL;
impl_name = NULL;
binding_callout_name = NULL;
cs_tag_rtn_name = NULL;
interface_attr.mask = 0; /* Reset attribute mask */
}
;
acf_interface_attr_list:
LBRACKET acf_interface_attrs RBRACKET
| /* Nothing */
;
acf_interface_attrs:
acf_interface_attr
| acf_interface_attrs COMMA acf_interface_attr
;
acf_interface_attr:
acf_code_attr
{
if (interface_attr.bit.code)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
interface_attr.bit.code = TRUE;
}
| acf_nocode_attr
{
if (interface_attr.bit.nocode)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
interface_attr.bit.nocode = TRUE;
}
| acf_binding_callout_attr
{
if (interface_attr.bit.binding_callout)
log_error(acf_yylineno, NIDL_ATTRUSEMULT);
interface_attr.bit.binding_callout = TRUE;
}
| acf_cs_tag_rtn_attr
{
if (interface_attr.bit.cs_tag_rtn)
log_error(acf_yylineno, NIDL_ATTRUSEMULT);
interface_attr.bit.cs_tag_rtn = TRUE;
}
| acf_explicit_handle_attr
{
if (interface_attr.bit.explicit_handle)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
interface_attr.bit.explicit_handle = TRUE;
}
| acf_inline_attr
{
if (interface_attr.bit.in_line)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
interface_attr.bit.in_line = TRUE;
}
| acf_outofline_attr
{
if (interface_attr.bit.out_of_line)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
interface_attr.bit.out_of_line = TRUE;
}
| acf_implicit_handle_attr
{
if (interface_attr.bit.implicit_handle)
log_error(acf_yylineno, NIDL_ATTRUSEMULT);
interface_attr.bit.implicit_handle = TRUE;
}
| acf_auto_handle_attr
{
if (interface_attr.bit.auto_handle)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
interface_attr.bit.auto_handle = TRUE;
}
| acf_extern_exceps_attr
{
if (interface_attr.bit.extern_exceps)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
interface_attr.bit.extern_exceps = TRUE;
}
| IDENTIFIER
{
if (NAMETABLE_add_id("decode") == $<y_id>1)
{
if (interface_attr.bit.decode)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
interface_attr.bit.decode = TRUE;
}
else if (NAMETABLE_add_id("encode") == $<y_id>1)
{
if (interface_attr.bit.encode)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
interface_attr.bit.encode = TRUE;
}
else
log_error(acf_yylineno, NIDL_ERRINATTR);
}
;
acf_implicit_handle_attr:
IMPLICIT_HANDLE_KW LPAREN acf_implicit_handle RPAREN
;
acf_implicit_handle:
acf_impl_type acf_impl_name
;
acf_impl_type:
acf_handle_type
{
named_type = FALSE;
}
| IDENTIFIER
{
NAMETABLE_id_to_string($<y_id>1, &type_name);
named_type = TRUE;
}
;
acf_handle_type:
HANDLE_T_KW
;
acf_impl_name:
IDENTIFIER
{
NAMETABLE_id_to_string($<y_id>1, &impl_name);
}
;
acf_extern_exceps_attr:
EXTERN_EXCEPS_KW LPAREN acf_ext_excep_list RPAREN
| EXTERN_EXCEPS_KW
{
if (ASTP_parsing_main_idl)
{
AST_exception_n_t *excep_p;
for (excep_p = the_interface->exceptions;
excep_p != NULL;
excep_p = excep_p->next)
{
AST_SET_EXTERN(excep_p);
}
}
}
;
acf_ext_excep_list:
acf_ext_excep
| acf_ext_excep_list COMMA acf_ext_excep
;
acf_ext_excep:
IDENTIFIER
{
AST_exception_n_t *excep_p;
if (ASTP_parsing_main_idl)
if (lookup_exception($<y_id>1, TRUE, &excep_p))
AST_SET_EXTERN(excep_p);
}
;
acf_interface_name:
IDENTIFIER
{
NAMETABLE_id_to_string($<y_id>1, &interface_name);
}
;
acf_interface_body:
LBRACE acf_body_elements RBRACE
| LBRACE RBRACE
| error
{ log_error(acf_yylineno, NIDL_SYNTAXERR); }
| error RBRACE
{ log_error(acf_yylineno, NIDL_SYNTAXERR); }
;
acf_body_elements:
acf_body_element
| acf_body_elements acf_body_element
;
acf_body_element:
acf_include SEMI
| acf_type_declaration SEMI
| acf_operation_declaration SEMI
| error SEMI
{
log_error(acf_yylineno, NIDL_SYNTAXERR);
/* Re-initialize attr masks to avoid sticky attributes */
interface_attr.mask = 0;
type_attr.mask = 0;
operation_attr.mask = 0;
parameter_attr.mask = 0;
}
;
acf_include:
INCLUDE_KW acf_include_list
{
if (ASTP_parsing_main_idl)
the_interface->includes = (AST_include_n_t *)
AST_concat_element((ASTP_node_t *)the_interface->includes,
(ASTP_node_t *)include_list);
include_list = NULL;
}
| INCLUDE_KW error
{ log_error(acf_yylineno, NIDL_SYNTAXERR); }
;
acf_include_list:
acf_include_name
| acf_include_list COMMA acf_include_name
;
acf_include_name:
STRING
{
if (ASTP_parsing_main_idl)
{
char *parsed_include_file;
char include_type[PATH_MAX];
char include_file[PATH_MAX];
STRTAB_str_t include_file_id;
STRTAB_str_to_string($<y_string>1, &parsed_include_file);
/*
* Log warning if include name contains a file extension.
* Tack on the correct extension based on the -lang option.
*/
FILE_parse(parsed_include_file, (char *)NULL, (char *)NULL,
include_type);
if (include_type[0] != '\0')
acf_warning(NIDL_INCLUDEXT);
FILE_form_filespec(parsed_include_file, (char *)NULL,
".h",
(char *)NULL, include_file);
/* Create an include node. */
include_file_id = STRTAB_add_string(include_file);
include_p = AST_include_node(include_file_id, $<y_string>1);
/* Store source information. */
if (include_p->fe_info != NULL)
{
include_p->fe_info->acf_file = error_file_name_id;
include_p->fe_info->acf_source_line = acf_yylineno;
}
include_list = (AST_include_n_t *)
AST_concat_element((ASTP_node_t *)include_list,
(ASTP_node_t *)include_p);
}
}
;
acf_type_declaration:
TYPEDEF_KW error
{ log_error(acf_yylineno, NIDL_SYNTAXERR); }
| TYPEDEF_KW acf_type_attr_list acf_named_type_list
{
type_attr.mask = 0; /* Reset attribute mask */
repr_type_name = NULL; /* Reset represent_as type name */
cs_char_type_name = NULL; /* Reset cs_char type name */
}
;
acf_named_type_list:
acf_named_type
{
type_name = NULL; /* Reset type name */
}
| acf_named_type_list COMMA acf_named_type
{
type_name = NULL; /* Reset type name */
}
;
acf_named_type:
IDENTIFIER
{
NAMETABLE_id_t type_id; /* Nametable id of type name */
AST_type_n_t *type_p; /* Ptr to AST type node */
NAMETABLE_id_to_string($<y_id>1, &type_name);
#ifdef DUMPERS
if (cmd_opt[opt_dump_acf])
dump_attributes("ACF type", type_name, &type_attr);
#endif
/*
* Lookup the type_name parsed and verify that it is a valid type
* node. Then set the parsed attributes in the type node.
*
* type_attr = bitmask of type attributes parsed.
* type_name = name of type_t node to look up.
* [repr_type_name] = name of represent_as type.
* [cs_char_type_name] = name of cs_char type.
*/
if (lookup_type(type_name, TRUE, &type_id, &type_p))
{
/* Store source information. */
if (type_p->fe_info != NULL)
{
type_p->fe_info->acf_file = error_file_name_id;
type_p->fe_info->acf_source_line = acf_yylineno;
}
if (type_attr.bit.heap
&& type_p->kind != AST_pipe_k
&& !AST_CONTEXT_RD_SET(type_p))
PROP_set_type_attr(type_p,AST_HEAP);
if (type_attr.bit.in_line)
PROP_set_type_attr(type_p,AST_IN_LINE);
if ((type_attr.bit.out_of_line) &&
(type_p->kind != AST_pointer_k) &&
(type_p->xmit_as_type == NULL))
PROP_set_type_attr(type_p,AST_OUT_OF_LINE);
if (type_attr.bit.represent_as)
process_rep_as_type(the_interface, type_p, repr_type_name);
if (type_attr.bit.cs_char)
process_cs_char_type(the_interface, type_p, cs_char_type_name);
}
}
;
acf_type_attr_list:
LBRACKET acf_rest_of_attr_list
| /* Nothing */
;
acf_rest_of_attr_list:
acf_type_attrs RBRACKET
| error SEMI
{
log_error(acf_yylineno, NIDL_MISSONATTR);
}
| error RBRACKET
{
log_error(acf_yylineno, NIDL_ERRINATTR);
}
;
acf_type_attrs:
acf_type_attr
| acf_type_attrs COMMA acf_type_attr
;
acf_type_attr:
acf_represent_attr
{
if (type_attr.bit.represent_as)
log_error(acf_yylineno, NIDL_ATTRUSEMULT);
type_attr.bit.represent_as = TRUE;
}
| acf_cs_char_attr
{
if (type_attr.bit.cs_char)
log_error(acf_yylineno, NIDL_ATTRUSEMULT);
type_attr.bit.cs_char = TRUE;
}
| acf_heap_attr
{
if (type_attr.bit.heap)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
type_attr.bit.heap = TRUE;
}
| acf_inline_attr
{
if (type_attr.bit.in_line)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
type_attr.bit.in_line = TRUE;
}
| acf_outofline_attr
{
if (type_attr.bit.out_of_line)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
type_attr.bit.out_of_line = TRUE;
}
;
acf_represent_attr:
REPRESENT_AS_KW LPAREN acf_repr_type RPAREN
;
acf_repr_type:
IDENTIFIER
{
NAMETABLE_id_to_string($<y_id>1, &repr_type_name);
}
;
acf_cs_char_attr:
CS_CHAR_KW LPAREN acf_cs_char_type RPAREN
;
acf_cs_char_type:
IDENTIFIER
{
NAMETABLE_id_to_string($<y_id>1, &cs_char_type_name);
}
;
acf_operation_declaration:
acf_op_attr_list acf_operations
{
operation_attr.mask = 0; /* Reset attribute mask */
cs_tag_rtn_name = NULL; /* Reset cs_tag_rtn name */
}
;
acf_operations:
acf_operation
| acf_operations COMMA acf_operation
;
acf_operation:
IDENTIFIER LPAREN acf_parameter_list RPAREN
{
acf_param_t *p; /* Ptr to local parameter structure */
NAMETABLE_id_t op_id; /* Nametable id of operation name */
NAMETABLE_id_t param_id; /* Nametable id of parameter name */
AST_operation_n_t *op_p; /* Ptr to AST operation node */
AST_parameter_n_t *param_p; /* Ptr to AST parameter node */
boolean log_error; /* TRUE => error if name not found */
char *param_name;/* character string of param id */
NAMETABLE_id_to_string($<y_id>1, &operation_name);
#ifdef DUMPERS
if (cmd_opt[opt_dump_acf])
dump_attributes("ACF operation", operation_name, &operation_attr);
#endif
/*
* Operation and parameter attributes are ignored for imported
* interfaces. Operations and parameters within imported interfaces
* are not put in the AST.
*/
if (ASTP_parsing_main_idl)
{
/*
* Lookup the operation_name parsed and verify that it is a valid
* operation node. Then set the parsed attributes in the operation
* node. For each parameter_name that was parsed for this
* operation, chase the parameter list off the AST operation node
* to verify that it is a valid parameter for that operation.
* Then set the parsed attributes for that parameter into the
* relevant parameter node.
*
* operation_attr = bitmask of operation attributes parsed.
* operation_name = name of routine_t node to look up.
* [cs_tag_rtn_name] = cs_tag_rtn name.
* parameter_list = linked list of parameter information.
*/
if (lookup_operation(operation_name, TRUE, &op_id, &op_p))
{
/* Store source information. */
if (op_p->fe_info != NULL)
{
op_p->fe_info->acf_file = error_file_name_id;
op_p->fe_info->acf_source_line = acf_yylineno;
}
if (operation_attr.bit.comm_status)
{
/*
* Assume the AST Builder always builds a result param,
* even for void operations.
*/
AST_SET_COMM_STATUS(op_p->result);
}
if (operation_attr.bit.fault_status)
AST_SET_FAULT_STATUS(op_p->result);
if (operation_attr.bit.code)
AST_SET_CODE(op_p);
if (operation_attr.bit.nocode)
AST_SET_NO_CODE(op_p);
if (operation_attr.bit.decode)
AST_SET_DECODE(op_p);
if (operation_attr.bit.encode)
AST_SET_ENCODE(op_p);
if (operation_attr.bit.enable_allocate)
AST_SET_ENABLE_ALLOCATE(op_p);
if (operation_attr.bit.explicit_handle)
AST_SET_EXPLICIT_HANDLE(op_p);
if (operation_attr.bit.cs_tag_rtn)
op_p->cs_tag_rtn_name = NAMETABLE_add_id(cs_tag_rtn_name);
for (p = parameter_list ; p != NULL ; p = p->next)
{
/*
* Most parameter attributes, if present, require that the
* referenced parameter be defined in the IDL. If only
* [comm_status] and/or [fault_status] is present, the
* parameter needn't be IDL-defined.
*/
if (!p->parameter_attr.bit.heap
&& !p->parameter_attr.bit.in_line
&& !p->parameter_attr.bit.out_of_line
&& !p->parameter_attr.bit.cs_stag
&& !p->parameter_attr.bit.cs_drtag
&& !p->parameter_attr.bit.cs_rtag
&& (p->parameter_attr.bit.comm_status
|| p->parameter_attr.bit.fault_status))
log_error = FALSE;
else
log_error = TRUE;
NAMETABLE_id_to_string(p->param_id, ¶m_name);
if (lookup_parameter(op_p, param_name, log_error,
¶m_id, ¶m_p))
{
/* Store source information. */
if (param_p->fe_info != NULL)
{
param_p->fe_info->acf_file = error_file_name_id;
param_p->fe_info->acf_source_line = acf_yylineno;
}
if (p->parameter_attr.bit.comm_status)
AST_SET_COMM_STATUS(param_p);
if (p->parameter_attr.bit.fault_status)
AST_SET_FAULT_STATUS(param_p);
if (p->parameter_attr.bit.heap)
{
AST_type_n_t *ref_type_p;
ref_type_p = param_follow_ref_ptr(param_p,
CHK_follow_ref);
if (ref_type_p->kind != AST_pipe_k
&& !AST_CONTEXT_SET(param_p)
&& !AST_CONTEXT_RD_SET(ref_type_p)
&& !type_is_scalar(ref_type_p))
AST_SET_HEAP(param_p);
}
if (p->parameter_attr.bit.in_line)
AST_SET_IN_LINE(param_p);
/*
* We parse the [out_of_line] parameter attribute,
* but disallow it.
*/
if (p->parameter_attr.bit.out_of_line)
acf_error(NIDL_INVOOLPRM);
if (p->parameter_attr.bit.cs_stag)
AST_SET_CS_STAG(param_p);
if (p->parameter_attr.bit.cs_drtag)
AST_SET_CS_DRTAG(param_p);
if (p->parameter_attr.bit.cs_rtag)
AST_SET_CS_RTAG(param_p);
}
else if (log_error == FALSE)
{
/*
* Lookup failed, but OK since the parameter only has
* attribute(s) that specify an additional parameter.
* Append a parameter to the operation parameter list.
*/
NAMETABLE_id_to_string(p->param_id, ¶m_name);
append_parameter(op_p, param_name, &p->parameter_attr);
}
}
}
}
free_param_list(¶meter_list); /* Free parameter list */
operation_name = NULL;
}
;
acf_op_attr_list:
LBRACKET acf_op_attrs RBRACKET
| /* Nothing */
;
acf_op_attrs:
acf_op_attr
| acf_op_attrs COMMA acf_op_attr
;
acf_op_attr:
acf_commstat_attr
{
if (operation_attr.bit.comm_status)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
operation_attr.bit.comm_status = TRUE;
}
| acf_code_attr
{
if (operation_attr.bit.code)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
operation_attr.bit.code = TRUE;
}
| acf_nocode_attr
{
if (operation_attr.bit.nocode)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
operation_attr.bit.nocode = TRUE;
}
| acf_cs_tag_rtn_attr
{
if (operation_attr.bit.cs_tag_rtn)
log_error(acf_yylineno, NIDL_ATTRUSEMULT);
operation_attr.bit.cs_tag_rtn = TRUE;
}
| acf_enable_allocate_attr
{
if (operation_attr.bit.enable_allocate)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
operation_attr.bit.enable_allocate = TRUE;
}
| acf_explicit_handle_attr
{
if (operation_attr.bit.explicit_handle)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
operation_attr.bit.explicit_handle = TRUE;
}
| acf_faultstat_attr
{
if (operation_attr.bit.fault_status)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
operation_attr.bit.fault_status = TRUE;
}
| IDENTIFIER
{
if (NAMETABLE_add_id("decode") == $<y_id>1)
{
if (operation_attr.bit.decode)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
operation_attr.bit.decode = TRUE;
}
else if (NAMETABLE_add_id("encode") == $<y_id>1)
{
if (operation_attr.bit.encode)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
operation_attr.bit.encode = TRUE;
}
else
log_error(acf_yylineno, NIDL_ERRINATTR);
}
;
acf_binding_callout_attr:
BINDING_CALLOUT_KW LPAREN acf_binding_callout_name RPAREN
;
acf_binding_callout_name:
IDENTIFIER
{
NAMETABLE_id_to_string($<y_id>1, &binding_callout_name);
}
;
acf_cs_tag_rtn_attr:
CS_TAG_RTN_KW LPAREN acf_cs_tag_rtn_name RPAREN
;
acf_cs_tag_rtn_name:
IDENTIFIER
{
NAMETABLE_id_to_string($<y_id>1, &cs_tag_rtn_name);
}
;
acf_parameter_list:
acf_parameters
| /* Nothing */
;
acf_parameters:
acf_parameter
| acf_parameters COMMA acf_parameter
;
acf_parameter:
acf_param_attr_list IDENTIFIER
{
#ifdef DUMPERS
if (cmd_opt[opt_dump_acf])
{
char *param_name;
NAMETABLE_id_to_string($<y_id>2, ¶m_name);
dump_attributes("ACF parameter", param_name, ¶meter_attr);
}
#endif
if (parameter_attr_list) /* If there were param attributes: */
{
acf_param_t *p; /* Pointer to parameter record */
/*
* Allocate and initialize a parameter record.
*/
p = alloc_param();
p->parameter_attr = parameter_attr;
p->param_id = $<y_id>2;
/*
* Add to end of parameter list.
*/
add_param_to_list(p, ¶meter_list);
parameter_attr.mask = 0;
}
}
;
acf_param_attr_list:
LBRACKET acf_param_attrs RBRACKET
{
parameter_attr_list = TRUE; /* Flag that we have param attributes */
}
| /* Nothing */
{
parameter_attr_list = FALSE;
}
;
acf_param_attrs:
acf_param_attr
| acf_param_attrs COMMA acf_param_attr
;
acf_param_attr:
acf_commstat_attr
{
if (parameter_attr.bit.comm_status)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
parameter_attr.bit.comm_status = TRUE;
}
| acf_faultstat_attr
{
if (parameter_attr.bit.fault_status)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
parameter_attr.bit.fault_status = TRUE;
}
| acf_heap_attr
{
if (parameter_attr.bit.heap)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
parameter_attr.bit.heap = TRUE;
}
| acf_inline_attr
{
if (parameter_attr.bit.in_line)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
parameter_attr.bit.in_line = TRUE;
}
| acf_outofline_attr
{
if (parameter_attr.bit.out_of_line)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
parameter_attr.bit.out_of_line = TRUE;
}
| IDENTIFIER
{
if (NAMETABLE_add_id("cs_stag") == $<y_id>1)
{
if (parameter_attr.bit.cs_stag)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
parameter_attr.bit.cs_stag = TRUE;
}
else if (NAMETABLE_add_id("cs_drtag") == $<y_id>1)
{
if (parameter_attr.bit.cs_drtag)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
parameter_attr.bit.cs_drtag = TRUE;
}
else if (NAMETABLE_add_id("cs_rtag") == $<y_id>1)
{
if (parameter_attr.bit.cs_rtag)
log_warning(acf_yylineno, NIDL_MULATTRDEF);
parameter_attr.bit.cs_rtag = TRUE;
}
else
log_error(acf_yylineno, NIDL_ERRINATTR);
}
;
acf_auto_handle_attr: AUTO_HANDLE_KW;
acf_code_attr: CODE_KW;
acf_nocode_attr: NOCODE_KW;
acf_enable_allocate_attr: ENABLE_ALLOCATE_KW;
acf_explicit_handle_attr: EXPLICIT_HANDLE_KW;
acf_heap_attr: HEAP_KW;
acf_inline_attr: IN_LINE_KW;
acf_outofline_attr: OUT_OF_LINE_KW;
acf_commstat_attr: COMM_STATUS_KW;
acf_faultstat_attr: FAULT_STATUS_KW;
%%
/***************************
* yacc programs section *
***************************/
/*
* a c f _ i n i t
*
* Function: Called before ACF parsing to initialize variables.
*
*/
void acf_init
(
boolean *cmd_opt_arr, /* [in] Array of command option flags */
void **cmd_val_arr, /* [in] Array of command option values */
char *acf_file /* [in] ACF file name */
)
{
/* Save passed command array and interface node addrs in static storage. */
cmd_opt = cmd_opt_arr;
cmd_val = cmd_val_arr;
/* Set global (STRTAB_str_t error_file_name_id) for error processing. */
set_name_for_errors(acf_file);
interface_attr.mask = 0;
type_attr.mask = 0;
operation_attr.mask = 0;
parameter_attr.mask = 0;
interface_name = NULL;
type_name = NULL;
repr_type_name = NULL;
cs_char_type_name = NULL;
operation_name = NULL;
binding_callout_name= NULL;
cs_tag_rtn_name = NULL;
include_list = NULL;
parameter_list = NULL;
parameter_free_list = NULL;
}
/*
* a c f _ c l e a n u p
*
* Function: Called after ACF parsing to free allocated memory.
*
*/
void acf_cleanup(void)
{
acf_param_t *p, *q; /* Ptrs to parameter record */
p = parameter_free_list;
while (p != NULL)
{
q = p;
p = p->next;
FREE(q);
}
}
/*
** a c f _ e r r o r
**
** Issues an error message, and bumps the error count.
**
** Note: This function is not prototyped since the way we use it allows
** it to be called with 1 to 6 arguments.
*/
static void acf_error(msgid, arg1, arg2, arg3, arg4, arg5)
long msgid; /* [in] Message id */
char *arg1; /* [in] 0 to 5 arguments to fill in message */
char *arg2; /* directives */
char *arg3;
char *arg4;
char *arg5;
{
log_error(acf_yylineno, msgid, arg1, arg2, arg3, arg4, arg5);
}
/*
** a c f _ w a r n i n g
**
** Issues a warning message.
**
** Note: This function is not prototyped since the way we use it allows
** it to be called with 1 to 6 arguments.
*/
static void acf_warning(msgid, arg1, arg2, arg3, arg4, arg5)
long msgid; /* [in] Message id */
char *arg1; /* [in] 0 to 5 arguments to fill in message */
char *arg2; /* directives */
char *arg3;
char *arg4;
char *arg5;
{
log_warning(acf_yylineno, msgid, arg1, arg2, arg3, arg4, arg5);
}
/*
** l o o k u p _ e x c e p t i o n
**
** Looks up a name in the nametable, and if it is bound to a valid exception
** node, returns the address of the exception node.
**
** Returns: TRUE if lookup succeeds, FALSE otherwise.
*/
static boolean lookup_exception
(
NAMETABLE_id_t excep_id, /* [in] Nametable id of exception name */
boolean log_error, /* [in] TRUE => log error if name not found */
AST_exception_n_t **excep_ptr /*[out] Ptr to AST exception node */
)
{
AST_exception_n_t *excep_p; /* Ptr to node bound to looked up name */
char *perm_excep_name; /* Ptr to permanent copy */
if (excep_id != NAMETABLE_NIL_ID)
{
excep_p = (AST_exception_n_t *)NAMETABLE_lookup_binding(excep_id);
if (excep_p != NULL && excep_p->fe_info->node_kind == fe_exception_n_k)
{
*excep_ptr = excep_p;
return TRUE;
}
}
if (log_error)
{
NAMETABLE_id_to_string(excep_id, &perm_excep_name);
acf_error(NIDL_EXCNOTDEF, perm_excep_name);
}
*excep_ptr = NULL;
return FALSE;
}
/*
** l o o k u p _ t y p e
**
** Looks up a name in the nametable, and if it is bound to a valid type
** node, returns the address of the type node.
**
** Returns: TRUE if lookup succeeds, FALSE otherwise.
*/
static boolean lookup_type
(
char *type_name, /* [in] Name to look up */
boolean log_error, /* [in] TRUE => log error if name not found */
NAMETABLE_id_t *type_id, /*[out] Nametable id of type name */
AST_type_n_t **type_ptr /*[out] Ptr to AST type node */
)
{
AST_type_n_t *type_p; /* Ptr to node bound to looked up name */
char *perm_type_name; /* Ptr to permanent copy */
NAMETABLE_id_t name_id; /* Handle on permanent copy */
*type_id = NAMETABLE_lookup_id(type_name);
if (*type_id != NAMETABLE_NIL_ID)
{
type_p = (AST_type_n_t *)NAMETABLE_lookup_binding(*type_id);
if (type_p != NULL && type_p->fe_info->node_kind == fe_type_n_k)
{
*type_ptr = type_p;
return TRUE;
}
}
if (log_error)
{
name_id = NAMETABLE_add_id(type_name);
NAMETABLE_id_to_string(name_id, &perm_type_name);
acf_error(NIDL_TYPNOTDEF, perm_type_name);
}
*type_ptr = NULL;
return FALSE;
}
/*
** l o o k u p _ o p e r a t i o n
**
** Looks up a name in the nametable, and if it is bound to a valid operation
** node, returns the address of the operation node.
**
** Returns: TRUE if lookup succeeds, FALSE otherwise.
*/
static boolean lookup_operation
(
char *op_name, /* [in] Name to look up */
boolean log_error, /* [in] TRUE => log error if name not found */
NAMETABLE_id_t *op_id, /*[out] Nametable id of operation name */
AST_operation_n_t **op_ptr /*[out] Ptr to AST operation node */
)
{
AST_operation_n_t *op_p; /* Ptr to node bound to looked up name */
char *perm_op_name; /* Ptr to permanent copy */
NAMETABLE_id_t name_id; /* Handle on permanent copy */
*op_id = NAMETABLE_lookup_id(op_name);
if (*op_id != NAMETABLE_NIL_ID)
{
op_p = (AST_operation_n_t *)NAMETABLE_lookup_binding(*op_id);
if (op_p != NULL && op_p->fe_info->node_kind == fe_operation_n_k)
{
*op_ptr = op_p;
return TRUE;
}
}
if (log_error)
{
name_id = NAMETABLE_add_id(op_name);
NAMETABLE_id_to_string(name_id, &perm_op_name);
acf_error(NIDL_OPNOTDEF, perm_op_name);
}
*op_ptr = NULL;
return FALSE;
}
/*
** l o o k u p _ p a r a m e t e r
**
** Searches an operation node's parameter list for the parameter name passed.
** If found, returns the address of the parameter node.
**
** Returns: TRUE if lookup succeeds, FALSE otherwise.
*/
static boolean lookup_parameter
(
AST_operation_n_t *op_p, /* [in] Ptr to AST operation node */
char *param_name, /* [in] Parameter name to look up */
boolean log_error, /* [in] TRUE=> log error if not found */
NAMETABLE_id_t *param_id, /*[out] Nametable id of param name */
AST_parameter_n_t **param_ptr /*[out] Ptr to AST parameter node */
)
{
AST_parameter_n_t *param_p; /* Ptr to operation parameter node */
char *op_param_name; /* Name of an operation parameter */
char *op_name; /* Operation name */
char *perm_param_name; /* Ptr to permanent copy */
NAMETABLE_id_t name_id; /* Handle on permanent copy */
for (param_p = op_p->parameters ; param_p != NULL ; param_p = param_p->next)
{
NAMETABLE_id_to_string(param_p->name, &op_param_name);
if (strcmp(param_name, op_param_name) == 0)
{
*param_id = param_p->name;
*param_ptr = param_p;
return TRUE;
}
}
if (log_error)
{
char *file_name; /* Related file name */
NAMETABLE_id_to_string(op_p->name, &op_name);
name_id = NAMETABLE_add_id(param_name);
NAMETABLE_id_to_string(name_id, &perm_param_name);
STRTAB_str_to_string(op_p->fe_info->file, &file_name);
acf_error(NIDL_PRMNOTDEF, perm_param_name, op_name);
acf_error(NIDL_NAMEDECLAT, op_name, file_name,
op_p->fe_info->source_line);
}
return FALSE;
}
/*
** l o o k u p _ r e p _ a s _ n a m e
**
** Scans a list of type nodes that have represent_as types for a match with
** the type name given by the parameter repr_name_id. If so, returns the
** address of the found type node and a pointer to the associated
** represent_as type name.
**
** Returns: TRUE if lookup succeeds, FALSE otherwise.
*/
static boolean lookup_rep_as_name
(
AST_type_p_n_t *typep_p, /* [in] Listhead of type ptr nodes */
NAMETABLE_id_t repr_name_id, /* [in] represent_as name to look up */
AST_type_n_t **ret_type_p, /*[out] Type node if found */
char **ret_type_name /*[out] Type name if found */
)
{
AST_type_n_t *type_p; /* Ptr to a type node */
for ( ; typep_p != NULL ; typep_p = typep_p->next )
{
type_p = typep_p->type;
if (type_p->name == repr_name_id)
{
*ret_type_p = type_p;
NAMETABLE_id_to_string(type_p->rep_as_type->type_name,
ret_type_name);
return TRUE;
}
}
return FALSE;
}
/*
** l o o k u p _ c s _ c h a r _ n a m e
**
** Scans a list of type nodes that have cs_char types for a match with
** the type name given by the parameter cs_char_name_id. If so, returns the
** address of the found type node and a pointer to the associated
** cs_char type name.
**
** Returns: TRUE if lookup succeeds, FALSE otherwise.
*/
static boolean lookup_cs_char_name
(
AST_type_p_n_t *typep_p, /* [in] Listhead of type ptr nodes */
NAMETABLE_id_t cs_char_name_id, /* [in] cs_char name to look up */
AST_type_n_t **ret_type_p, /*[out] Type node if found */
char **ret_type_name /*[out] Type name if found */
)
{
AST_type_n_t *type_p; /* Ptr to a type node */
for ( ; typep_p != NULL ; typep_p = typep_p->next )
{
type_p = typep_p->type;
if (type_p->name == cs_char_name_id)
{
*ret_type_p = type_p;
NAMETABLE_id_to_string(type_p->cs_char_type->type_name,
ret_type_name);
return TRUE;
}
}
return FALSE;
}
/*
* a c f _ a l l o c _ p a r a m
*
* Function: Allocates an acf_param_t, either from the free list or heap.
*
* Returns: Address of acf_param_t
*
* Globals: parameter_free_list - listhead for free list
*
* Side Effects: Exits program if unable to allocate memory.
*/
static acf_param_t *alloc_param(void)
{
acf_param_t *p; /* Ptr to parameter record */
if (parameter_free_list != NULL)
{
p = parameter_free_list;
parameter_free_list = parameter_free_list->next;
}
else
{
p = (acf_param_t *)MALLOC(sizeof(acf_param_t));
p->next = NULL;
p->parameter_attr.mask = 0;
p->param_id = NAMETABLE_NIL_ID;
}
return p;
}
/*
* a c f _ f r e e _ p a r a m
*
* Function: Frees an acf_param_t by reinitilizing it and returning it to
* the head of the free list.
*
* Input: p - Pointer to acf_param_t record
*
* Globals: parameter_free_list - listhead for free list
*/
static void free_param
(
acf_param_t *p /* [in] Pointer to acf_param_t record */
)
{
p->parameter_attr.mask = 0;
p->param_id = NAMETABLE_NIL_ID;
p->next = parameter_free_list;
parameter_free_list = p;
}
/*
* a c f _ f r e e _ p a r a m _ l i s t
*
* Function: Frees a list of acf_param_t records.
*
* Input: list - Address of list pointer
*
* Output: list pointer = NULL
*/
static void free_param_list
(
acf_param_t **list /* [in] Address of list pointer */
)
{
acf_param_t *p, *q; /* Ptrs to parameter record */
p = *list;
while (p != NULL)
{
q = p;
p = p->next;
free_param(q);
}
*list = NULL; /* List now empty */
}
/*
* a d d _ p a r a m _ t o _ l i s t
*
* Function: Add a acf_param_t record to the end of a list.
*
* Inputs: p - Pointer to parameter record
* list - Address of list pointer
*
* Outputs: List is modified.
*/
void add_param_to_list
(
acf_param_t *p, /* [in] Pointer to parameter record */
acf_param_t **list /* [in] Address of list pointer */
)
{
acf_param_t *q; /* Ptr to parameter record */
if (*list == NULL) /* If list empty */
*list = p; /* then list now points at param */
else
{
for (q = *list ; q->next != NULL ; q = q->next)
;
q->next = p; /* else last record in list now points at param */
}
p->next = NULL; /* Param is now last in list */
}
/*
** a p p e n d _ p a r a m e t e r
**
** Appends a parameter to an operation's parameter list.
*/
static void append_parameter
(
AST_operation_n_t *op_p, /* [in] Ptr to AST operation node */
char *param_name, /* [in] Parameter name */
acf_attrib_t *param_attr /* [in] Parameter attributes */
)
{
NAMETABLE_id_t new_param_id; /* Nametable id of new parameter name */
AST_parameter_n_t *new_param_p; /* Ptr to new parameter node */
AST_type_n_t *new_type_p; /* Ptr to new parameter type node */
AST_pointer_n_t *new_ptr_p; /* Ptr to new pointer node */
NAMETABLE_id_t status_id; /* Nametable id of status_t */
AST_type_n_t *status_type_p; /* Type node bound to status_t name */
AST_parameter_n_t *param_p; /* Ptr to operation parameter node */
/* Look up error_status_t type. */
status_id = NAMETABLE_add_id("error_status_t");
status_type_p = (AST_type_n_t *)NAMETABLE_lookup_binding(status_id);
if (status_type_p == NULL)
{
acf_error(NIDL_ERRSTATDEF, "error_status_t", "nbase.idl");
return;
}
/*
* Have to create an '[out] error_status_t *param_name' parameter
* that has the specified parameter attributes.
*/
new_param_id = NAMETABLE_add_id(param_name);
new_param_p = AST_parameter_node(new_param_id);
new_type_p = AST_type_node(AST_pointer_k);
new_ptr_p = AST_pointer_node(status_type_p);
new_type_p->type_structure.pointer = new_ptr_p;
AST_SET_REF(new_type_p);
new_param_p->name = new_param_id;
new_param_p->type = new_type_p;
new_param_p->uplink = op_p;
if (param_attr->bit.comm_status)
AST_SET_ADD_COMM_STATUS(new_param_p);
if (param_attr->bit.fault_status)
AST_SET_ADD_FAULT_STATUS(new_param_p);
AST_SET_OUT(new_param_p);
AST_SET_REF(new_param_p);
param_p = op_p->parameters;
if (param_p == NULL)
{
/* Was null param list, now has one param. */
op_p->parameters = new_param_p;
}
else if (param_p->last == NULL)
{
/* Was one param, now have two params. */
param_p->next = new_param_p;
param_p->last = new_param_p;
}
else
{
/* Was more than one param, now have one more. */
param_p->last->next = new_param_p;
param_p->last = new_param_p;
}
}
/*
** p r o c e s s _ r e p _ a s _ t y p e
**
** Processes a [represent_as] clause applied to a type. Validates that
** [represent_as] types are not nested. Adds the type to a list of types
** that have the [represent_as] attribute.
*/
static void process_rep_as_type
(
AST_interface_n_t *int_p, /* [in] Ptr to AST interface node */
AST_type_n_t *type_p, /* [in] Ptr to AST type node */
char *ref_type_name /* [in] Name in represent_as() clause */
)
{
NAMETABLE_id_t ref_type_id; /* Nametable id of referenced name */
char *file_name; /* Related file name */
char *perm_name; /* Permanent copy of referenced name */
AST_type_n_t *parent_type_p; /* Parent type with same attribute */
char *parent_name; /* Name of parent type */
ref_type_id = NAMETABLE_add_id(ref_type_name);
/*
* Report error if the type name referenced in the attribute is an AST
* type which also has the same attribute, i.e. types with this attribute
* cannot nest.
*/
if (lookup_rep_as_name(int_p->ra_types, ref_type_id, &parent_type_p,
&perm_name))
{
NAMETABLE_id_to_string(parent_type_p->name, &parent_name);
STRTAB_str_to_string(parent_type_p->fe_info->acf_file, &file_name);
acf_error(NIDL_REPASNEST);
acf_error(NIDL_TYPEREPAS, parent_name, perm_name);
acf_error(NIDL_NAMEDECLAT, parent_name, file_name,
parent_type_p->fe_info->acf_source_line);
}
/*
* If the type node already has a type name for this attribute,
* this one must duplicate that same name.
*/
if (type_p->rep_as_type != NULL)
{
NAMETABLE_id_to_string(type_p->rep_as_type->type_name, &perm_name);
if (strcmp(perm_name, ref_type_name) != 0)
{
char *new_ref_type_name; /* Ptr to permanent copy */
NAMETABLE_id_t name_id; /* Handle on perm copy */
name_id = NAMETABLE_add_id(ref_type_name);
NAMETABLE_id_to_string(name_id, &new_ref_type_name);
STRTAB_str_to_string(
type_p->rep_as_type->fe_info->acf_file, &file_name);
acf_error(NIDL_CONFREPRTYPE, new_ref_type_name, perm_name);
acf_error(NIDL_NAMEDECLAT, perm_name, file_name,
type_p->rep_as_type->fe_info->acf_source_line);
}
}
else
{
/*
* Process valid [represent_as] clause.
*/
AST_type_p_n_t *typep_p; /* Used to link type nodes */
AST_rep_as_n_t *repas_p; /* Ptr to represent_as node */
/* Add represent_as type name and build rep_as AST node. */
repas_p = type_p->rep_as_type = AST_represent_as_node(ref_type_id);
/* Store source information. */
if (repas_p->fe_info != NULL)
{
repas_p->fe_info->acf_file = error_file_name_id;
repas_p->fe_info->acf_source_line = acf_yylineno;
}
/* Check for associated def-as-tag node. */
if (type_p->fe_info->tag_ptr != NULL)
type_p->fe_info->tag_ptr->rep_as_type = type_p->rep_as_type;
/* Link type node into list of represent_as types. */
typep_p = AST_type_ptr_node();
typep_p->type = type_p;
int_p->ra_types = (AST_type_p_n_t *)AST_concat_element(
(ASTP_node_t *)int_p->ra_types,
(ASTP_node_t *)typep_p);
}
}
/*
** p r o c e s s _ c s _ c h a r _ t y p e
**
** Processes a [cs_char] clause applied to a type. Validates that
** [cs_char] types are not nested. Adds the type to a list of types
** that have the [cs_char] attribute.
*/
static void process_cs_char_type
(
AST_interface_n_t *int_p, /* [in] Ptr to AST interface node */
AST_type_n_t *type_p, /* [in] Ptr to AST type node */
char *ref_type_name /* [in] Name in cs_char() clause */
)
{
NAMETABLE_id_t ref_type_id; /* Nametable id of referenced name */
char *file_name; /* Related file name */
char *perm_name; /* Permanent copy of referenced name */
AST_type_n_t *parent_type_p; /* Parent type with same attribute */
char *parent_name; /* Name of parent type */
ref_type_id = NAMETABLE_add_id(ref_type_name);
/*
* Report error if the type name referenced in the attribute is an AST
* type which also has the same attribute, i.e. types with this attribute
* cannot nest.
*/
if (lookup_cs_char_name(int_p->cs_types, ref_type_id, &parent_type_p,
&perm_name))
{
NAMETABLE_id_to_string(parent_type_p->name, &parent_name);
STRTAB_str_to_string(parent_type_p->fe_info->acf_file, &file_name);
/*** This needs updating ***/
acf_error(NIDL_REPASNEST);
acf_error(NIDL_TYPEREPAS, parent_name, perm_name);
acf_error(NIDL_NAMEDECLAT, parent_name, file_name,
parent_type_p->fe_info->acf_source_line);
}
/*
* If the type node already has a type name for this attribute,
* this one must duplicate that same name.
*/
if (type_p->cs_char_type != NULL)
{
NAMETABLE_id_to_string(type_p->cs_char_type->type_name, &perm_name);
if (strcmp(perm_name, ref_type_name) != 0)
{
char *new_ref_type_name; /* Ptr to permanent copy */
NAMETABLE_id_t name_id; /* Handle on perm copy */
name_id = NAMETABLE_add_id(ref_type_name);
NAMETABLE_id_to_string(name_id, &new_ref_type_name);
STRTAB_str_to_string(
type_p->cs_char_type->fe_info->acf_file, &file_name);
/*** This needs updating ***/
acf_error(NIDL_CONFREPRTYPE, new_ref_type_name, perm_name);
acf_error(NIDL_NAMEDECLAT, perm_name, file_name,
type_p->cs_char_type->fe_info->acf_source_line);
}
}
else
{
/*
* Process valid [cs_char] clause.
*/
AST_type_p_n_t *typep_p; /* Used to link type nodes */
AST_cs_char_n_t *cschar_p; /* Ptr to cs_char node */
/* Add cs_char type name and build cs_char AST node. */
cschar_p = type_p->cs_char_type = AST_cs_char_node(ref_type_id);
/* Store source information. */
if (cschar_p->fe_info != NULL)
{
cschar_p->fe_info->acf_file = error_file_name_id;
cschar_p->fe_info->acf_source_line = acf_yylineno;
}
/* Check for associated def-as-tag node. */
if (type_p->fe_info->tag_ptr != NULL)
type_p->fe_info->tag_ptr->cs_char_type = type_p->cs_char_type;
/* Link type node into list of cs_char types. */
typep_p = AST_type_ptr_node();
typep_p->type = type_p;
int_p->cs_types = (AST_type_p_n_t *)AST_concat_element(
(ASTP_node_t *)int_p->cs_types,
(ASTP_node_t *)typep_p);
}
}
#ifdef DUMPERS
/*
* d u m p _ a t t r i b u t e s
*
* Function: Prints list of attributes parsed for a particular node type
*
* Inputs: header_text - Initial text before node name and attributes
* node_name - Name of interface, type, operation, or parameter
* node_attr_p - Address of node attributes structure
*
* Globals: repr_type_name - represent_as type name, used if bit is set
* cs_char_type_name - cs_char type name, used if bit is set
* cs_tag_rtn_name - cs_tag_rtn name, used if bit is set
* binding_callout_name - binding_callout name, used if bit is set
*/
static void dump_attributes
(
char *header_text, /* [in] Initial output text */
char *node_name, /* [in] Name of tree node */
acf_attrib_t *node_attr_p /* [in] Node attributes ptr */
)
#define MAX_ATTR_TEXT 1024 /* Big enough for lots of extern_exceptions */
{
char attr_text[MAX_ATTR_TEXT]; /* Buf for formatting attrs */
int pos; /* Position in buffer */
acf_attrib_t node_attr; /* Node attributes */
node_attr = *node_attr_p;
printf("%s %s", header_text, node_name);
if (node_attr.mask == 0)
printf("\n");
else
{
printf(" attributes: ");
strcpy(attr_text, "[");
if (node_attr.bit.auto_handle)
strcat(attr_text, "auto_handle, ");
if (node_attr.bit.code)
strcat(attr_text, "code, ");
if (node_attr.bit.nocode)
strcat(attr_text, "nocode, ");
if (node_attr.bit.comm_status)
strcat(attr_text, "comm_status, ");
if (node_attr.bit.decode)
strcat(attr_text, "decode, ");
if (node_attr.bit.enable_allocate)
strcat(attr_text, "enable_allocate, ");
if (node_attr.bit.encode)
strcat(attr_text, "encode, ");
if (node_attr.bit.explicit_handle)
strcat(attr_text, "explicit_handle, ");
if (node_attr.bit.extern_exceps && ASTP_parsing_main_idl)
{
AST_exception_n_t *excep_p;
char *name;
strcat(attr_text, "extern_exceptions(");
for (excep_p = the_interface->exceptions;
excep_p != NULL;
excep_p = excep_p->next)
{
if (AST_EXTERN_SET(excep_p))
{
NAMETABLE_id_to_string(excep_p->name, &name);
strcat(attr_text, name);
strcat(attr_text, ",");
}
}
attr_text[strlen(attr_text)-1] = '\0'; /* overwrite trailing ',' */
strcat(attr_text, "), ");
}
if (node_attr.bit.fault_status)
strcat(attr_text, "fault_status, ");
if (node_attr.bit.heap)
strcat(attr_text, "heap, ");
if (node_attr.bit.implicit_handle)
strcat(attr_text, "implicit_handle, ");
if (node_attr.bit.in_line)
strcat(attr_text, "in_line, ");
if (node_attr.bit.out_of_line)
strcat(attr_text, "out_of_line, ");
if (node_attr.bit.cs_stag)
strcat(attr_text, "cs_stag, ");
if (node_attr.bit.cs_drtag)
strcat(attr_text, "cs_drtag, ");
if (node_attr.bit.cs_rtag)
strcat(attr_text, "cs_rtag, ");
if (node_attr.bit.represent_as)
{
strcat(attr_text, "represent_as(");
strcat(attr_text, repr_type_name);
strcat(attr_text, "), ");
}
if (node_attr.bit.cs_char)
{
strcat(attr_text, "cs_char(");
strcat(attr_text, cs_char_type_name);
strcat(attr_text, "), ");
}
if (node_attr.bit.cs_tag_rtn)
{
strcat(attr_text, "cs_tag_rtn(");
strcat(attr_text, cs_tag_rtn_name);
strcat(attr_text, "), ");
}
if (node_attr.bit.binding_callout)
{
strcat(attr_text, "binding_callout(");
strcat(attr_text, binding_callout_name);
strcat(attr_text, "), ");
}
/* Overwrite trailing ", " with "]" */
pos = strlen(attr_text) - strlen(", ");
attr_text[pos] = ']';
attr_text[pos+1] = '\0';
printf("%s\n", attr_text);
}
}
#endif