1
0
Files
2022-09-29 17:59:04 +03:00

1129 lines
40 KiB
C

/*
* @OSF_COPYRIGHT@
* COPYRIGHT NOTICE
* Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
* ALL RIGHTS RESERVED (DCE). See the file named COPYRIGHT.DCE in the
* src directory for the full copyright text.
*/
/*
* HISTORY
* $Log: oolrtns.c,v $
* Revision 1.1 1993/08/31 06:48:01 jwag
* Initial revision
*
* Revision 1.1.4.3 1993/01/03 21:41:16 bbelch
* Embedding copyright notice
* [1993/01/03 14:37:54 bbelch]
*
* Revision 1.1.4.2 1992/12/23 18:50:46 zeliff
* Embedding copyright notice
* [1992/12/23 01:05:12 zeliff]
*
* Revision 1.1.2.2 1992/05/13 19:04:19 harrow
* Propagat a flag for use in correcting [transmit_as] on a field of an [out_of_line] structure
* [1992/05/13 11:42:00 harrow]
*
* Revision 1.1 1992/01/19 03:01:46 devrcs
* Initial revision
*
* $EndLog$
*/
/*
**
** Copyright (c) 1990, 1991 by
** Hewlett-Packard Company, Palo Alto, Ca. &
** Digital Equipment Corporation, Maynard, Mass.
**
** NAME:
**
** oolrtns.c
**
** FACILITY:
**
** Interface Definition Language (IDL) Compiler
**
** ABSTRACT:
**
** Routines supporting out_of_line marshalling
**
** VERSION: DCE 1.0
*/
#include <nidl.h>
#include <ast.h>
#include <bedeck.h>
#include <cspell.h>
#include <decorate.h>
#include <dflags.h>
#include <dutils.h>
#include <flatten.h>
#include <hdgen.h>
#include <marshall.h>
#include <mmarsh.h>
#include <nametbl.h>
#include <nodmarsh.h>
#include <nodunmar.h>
#include <oolrtns.h>
#include <backend.h>
#include <inpipes.h>
#include <outpipes.h>
#include <bounds.h>
#include <localvar.h>
/******************************************************************************/
/* */
/* Does a type have any pointer fields? */
/* */
/******************************************************************************/
boolean BE_type_has_pointers
#ifdef PROTO
(
AST_type_n_t *p_type
)
#else
( p_type )
AST_type_n_t *p_type;
#endif
{
AST_parameter_n_t dummy_param;
AST_parameter_n_t *open_array = NULL;
AST_operation_n_t dummy_oper;
dummy_param.be_info.param = NULL;
dummy_oper.be_info.oper = (BE_oper_i_t *)BE_ctx_malloc(sizeof(BE_oper_i_t));
dummy_oper.be_info.oper->local_vars = NULL;
dummy_oper.be_info.oper->flags = 0;
dummy_param.uplink = &dummy_oper;
dummy_param.flags = 0;
dummy_param.field_attrs = NULL;
return( BE_any_pointers ( BE_flatten_parameter( &dummy_param,
NAMETABLE_add_id("(*p_node)"), p_type, BE_client_side,
true, &open_array, BE_F_PA_RTN | BE_F_OOL_RTN ) ) );
}
/******************************************************************************/
/* */
/* Spell the name of a routine for un/marshalling an out_of_line type */
/* */
/******************************************************************************/
void CSPELL_ool_routine_name
#ifdef PROTO
(
FILE *fid,
AST_type_n_t *p_type,
BE_call_side_t call_side,
BE_marshalling_k_t to_or_from_wire,
boolean varying,
boolean pointees
)
#else
(fid, p_type, call_side, to_or_from_wire, varying, pointees)
FILE *fid;
AST_type_n_t *p_type;
BE_call_side_t call_side;
BE_marshalling_k_t to_or_from_wire;
boolean varying;
boolean pointees;
#endif
{
spell_name( fid, p_type->name );
fprintf( fid, "%c%c%c",
(pointees) ? 'P' : 'O',
(to_or_from_wire == BE_marshalling_k) ? 'm' : 'u',
(call_side == BE_caller) ? 'r' : 'e' );
}
/******************************************************************************/
/* */
/* Spell the setting up of variables used in un/marshalling varying arrays */
/* */
/******************************************************************************/
void BE_ool_spell_varying_info
#ifdef PROTO
(
FILE *fid,
AST_parameter_n_t *flattened_type
)
#else
(fid, flattened_type)
FILE *fid;
AST_parameter_n_t *flattened_type;
#endif
{
AST_parameter_n_t *elt;
int i;
for (elt = flattened_type; elt; elt = elt->next)
{
if( (BE_PI_Flags(elt) & BE_ARRAY_HEADER) && AST_VARYING_SET(elt) )
{
/*
* ool routines for arrays must be conditionalized to handle
* varying or non-varying array instance.
*/
if (!(BE_PI_Flags(elt) & BE_FIELD))
fprintf(fid, "if (NIDL_varying)\n{\n");
/* Varying case. */
if (!AST_SMALL_SET(elt))
{
for (i = 0;
i < elt->type->type_structure.array->index_count;
i++)
{
fprintf(fid, "%s = %s;\n%s = %s;\n",
BE_get_name(BE_Array_Info(elt)->A[i]),
BE_Array_Info(elt)->A_exps[i],
BE_get_name(BE_Array_Info(elt)->B[i]),
BE_Array_Info(elt)->B_exps[i]);
}
fprintf(fid, "%s = %s;\n",
BE_get_name(BE_Array_Info(elt)->count_var),
BE_Array_Info(elt)->count_exp);
}
else
{
fprintf(fid, "%s = %s;\n",
BE_get_name(BE_Array_Info(elt)->count_var),
BE_Array_Info(elt)->count_exp);
}
/* Non-varying case. */
if (!(BE_PI_Flags(elt) & BE_FIELD))
{
fprintf(fid, "}\nelse\n{\n");
if (!AST_SMALL_SET(elt))
{
AST_array_index_n_t *index_p =
elt->type->type_structure.array->index_vec;
for (i = 0;
i < elt->type->type_structure.array->index_count;
i++)
{
if (AST_FIXED_LOWER_SET(index_p)
&& index_p->lower_bound->value.int_val == 0)
{
fprintf(fid, "%s = %ld;\n",
BE_get_name(BE_Array_Info(elt)->A[i]),
index_p->lower_bound->value.int_val);
if (AST_FIXED_UPPER_SET(index_p))
fprintf(fid, "%s = %ld;\n",
BE_get_name(BE_Array_Info(elt)->B[i]),
index_p->upper_bound->value.int_val-
index_p->lower_bound->value.int_val+1);
else
fprintf(fid, "%s = %s;\n",
BE_get_name(BE_Array_Info(elt)->B[i]),
BE_get_name(BE_Array_Info(elt)->Z[i]));
}
else
INTERNAL_ERROR("Array with nonzero lower bound not supported");
index_p++;
}
fprintf(fid, "%s = %s;\n",
BE_get_name(BE_Array_Info(elt)->count_var),
BE_Array_Info(elt)->count_exp);
}
else
{
fprintf(fid, "%s = %s;\n",
BE_get_name(BE_Array_Info(elt)->count_var),
BE_Array_Info(elt)->size_exp);
}
fprintf(fid, "}\n");
}
}
}
}
/******************************************************************************/
/* */
/* Output the declaration part of a out_of_line type marshalling routine */
/* */
/******************************************************************************/
void CSPELL_marshall_ool_type_decl
#ifdef PROTO
(
FILE *fid,
AST_type_n_t *p_type, /* Type of node to be marshalled */
BE_call_side_t call_side,
boolean in_header, /* TRUE if decl to be emitted to header file */
AST_parameter_n_t *flattened_type,
boolean varying, /* TRUE if rtn is for [non]varying array */
boolean has_pointers, /* TRUE if the type includes any pointers */
boolean pointee_routine, /* TRUE for routines that marshall pointees */
boolean v1_stringifiable /* TRUE if v1_array && !v1_string */
)
#else
( fid, p_type, call_side, in_header, flattened_type, varying, has_pointers,
pointee_routine, v1_stringifiable )
FILE *fid;
AST_type_n_t *p_type; /* Type of node to be marshalled */
BE_call_side_t call_side;
boolean in_header; /* TRUE if decl to be emitted to header file */
AST_parameter_n_t *flattened_type;
boolean varying;
boolean has_pointers;
boolean pointee_routine;
boolean v1_stringifiable;
#endif
{
int i;
int num_array_dimensions;
AST_parameter_n_t *array_desc;
fprintf( fid, "\n");
CSPELL_ool_routine_name( fid, p_type, call_side, BE_marshalling_k, varying,
pointee_routine );
if ( (p_type->kind == AST_array_k) || AST_CONFORMANT_SET(p_type) )
{
array_desc = (p_type->kind == AST_structure_k)
? BE_Open_Array(flattened_type) : flattened_type;
if ( ! AST_SMALL_SET(array_desc) )
num_array_dimensions =
array_desc->type->type_structure.array->index_count;
}
#if 0
fprintf( fid, "\n#ifdef IDL_PROTOTYPES\n");
fprintf( fid, "(\n");
spell_name( fid, p_type->name );
fprintf( fid, " *p_node,\n");
if ( (p_type->kind == AST_array_k) || AST_CONFORMANT_SET(p_type) )
{
array_desc = (p_type->kind == AST_structure_k)
? BE_Open_Array(flattened_type) : flattened_type;
if ( AST_SMALL_SET(array_desc) )
{
if ( AST_CONFORMANT_SET(p_type) )
{
fprintf( fid, "ndr_ulong_int " );
spell_name( fid, BE_Array_Info(array_desc)->size_var );
fprintf( fid, ",\n" );
}
if (varying)
{
fprintf( fid, "ndr_ulong_int " );
spell_name( fid, BE_Array_Info(array_desc)->count_var );
fprintf( fid, ",\n" );
}
}
else
{
num_array_dimensions =
array_desc->type->type_structure.array->index_count;
for (i=0; i<num_array_dimensions; i++)
{
if ( AST_CONFORMANT_SET(p_type) )
{
fprintf( fid, "ndr_ulong_int " );
spell_name( fid, BE_Array_Info(array_desc)->Z[i] );
fprintf( fid, ",\n" );
}
if ( varying )
{
fprintf( fid, "ndr_ulong_int " );
spell_name( fid, BE_Array_Info(array_desc)->A[i] );
fprintf( fid, ",\n" );
fprintf( fid, "ndr_ulong_int " );
spell_name( fid, BE_Array_Info(array_desc)->B[i] );
fprintf( fid, ",\n" );
}
}
}
}
if ( (call_side == BE_caller) )
{
fprintf( fid, "rpc_ss_marsh_state_t *NIDL_msp\n");
}
fprintf( fid, ")\n" );
fprintf( fid, "#else\n");
#endif
if ( in_header )
{
fprintf( fid, "()\n");
}
else
{
/* Spell parameter list. */
fprintf( fid, "( p_node, NIDL_msp" );
if ( varying )
fprintf( fid, ", NIDL_varying" );
if ( v1_stringifiable )
fprintf( fid, ", v1_string_flag" );
if ( (p_type->kind == AST_array_k) || AST_CONFORMANT_SET(p_type) )
{
if ( AST_SMALL_SET(array_desc) )
{
if ( AST_CONFORMANT_SET(p_type) )
{
fprintf( fid, ", " );
spell_name( fid, BE_Array_Info(array_desc)->size_var );
}
if (varying)
{
fprintf( fid, ", " );
spell_name( fid, BE_Array_Info(array_desc)->count_var );
}
}
else
{
for (i=0; i<num_array_dimensions; i++)
{
if ( AST_CONFORMANT_SET(p_type) )
{
fprintf( fid, ", " );
spell_name( fid, BE_Array_Info(array_desc)->Z[i] );
}
if ( varying )
{
fprintf( fid, ", " );
spell_name( fid, BE_Array_Info(array_desc)->A[i] );
fprintf( fid, ", " );
spell_name( fid, BE_Array_Info(array_desc)->B[i] );
}
}
}
}
fprintf( fid, " )\n");
/* Spell parameter declarations. */
spell_name( fid, p_type->name );
fprintf( fid, " *p_node;\n" );
fprintf( fid, "rpc_ss_marsh_state_t *NIDL_msp;\n" );
if ( varying )
fprintf( fid, "idl_boolean NIDL_varying;\n" );
/*
* Add a parameter to OOL marshalling routines for types that may
* be V1_stringified but are not themselves marked with a V1_string
* attribute. [OOL routines for stringified types will marshall
* their data as per string NDR without having to be so told by
* the in-line call.]
*/
if ( v1_stringifiable )
{
fprintf( fid, "idl_boolean v1_string_flag;\n" );
}
if ( (p_type->kind == AST_array_k) || AST_CONFORMANT_SET(p_type) )
{
if ( AST_SMALL_SET(array_desc) )
{
if ( AST_CONFORMANT_SET(p_type) )
{
fprintf( fid, "ndr_ulong_int " );
spell_name( fid, BE_Array_Info(array_desc)->size_var );
fprintf( fid, ";\n" );
}
if (varying)
{
fprintf( fid, "ndr_ulong_int " );
spell_name( fid, BE_Array_Info(array_desc)->count_var );
fprintf( fid, ";\n" );
}
}
else
{
for (i=0; i<num_array_dimensions; i++)
{
if ( AST_CONFORMANT_SET(p_type) )
{
fprintf( fid, "ndr_ulong_int " );
spell_name( fid, BE_Array_Info(array_desc)->Z[i] );
fprintf( fid, ";\n" );
}
if ( varying )
{
fprintf( fid, "ndr_ulong_int " );
spell_name( fid, BE_Array_Info(array_desc)->A[i] );
fprintf( fid, ";\n" );
fprintf( fid, "ndr_ulong_int " );
spell_name( fid, BE_Array_Info(array_desc)->B[i] );
fprintf( fid, ";\n" );
}
}
}
}
}
#if 0
fprintf( fid, "#endif\n");
#endif
if ( in_header )
{
fprintf( fid, ";\n");
}
}
/******************************************************************************/
/* */
/* Output the code to marshall an out_of_line type */
/* */
/******************************************************************************/
static void CSPELL_marshall_ool_type
#ifdef PROTO
(
FILE *fid,
AST_type_n_t *p_type, /* Type of node to be marshalled */
BE_call_side_t call_side
)
#else
( fid, p_type, call_side )
FILE *fid;
AST_type_n_t *p_type; /* Type of node to be marshalled */
BE_call_side_t call_side;
#endif
{
AST_parameter_n_t dummy_param;
AST_parameter_n_t *open_array = NULL;
AST_parameter_n_t *flattened_type, *pointees;
AST_parameter_n_t *tp;
AST_operation_n_t dummy_oper;
AST_parameter_n_t *elt;
AST_parameter_n_t *array_desc;
BE_dflags_t flags;
int dummy_slots_used;
boolean varying;
boolean has_pointers;
boolean v1_stringifiable;
boolean routine_mode; /* FALSE if mp and op have been set up for
in-line marshalling */
int i;
/*
* ool types must be named types. Even if the type has no varying instances
* in this interface, it could have varying instances in another interface
* that imports this one. Thus, ool routines for arrays are always generic
* so that they can handle a varying or non-varying instance; below we
* always flatten an array as varying.
*/
varying = (p_type->kind == AST_array_k
|| AST_STRING_SET(p_type) || AST_STRING0_SET(p_type));
/* Prepare to emit code */
dummy_param.be_info.param = NULL;
dummy_oper.be_info.oper = (BE_oper_i_t *)BE_ctx_malloc(sizeof(BE_oper_i_t));
dummy_oper.be_info.oper->local_vars = NULL;
dummy_oper.be_info.oper->flags = 0;
dummy_param.uplink = &dummy_oper;
dummy_param.flags = varying ? AST_VARYING : 0;
dummy_param.field_attrs = NULL;
flattened_type = BE_flatten_parameter( &dummy_param,
NAMETABLE_add_id("(*p_node)"), p_type, BE_client_side,
true, &open_array, BE_F_OOL_RTN );
BE_propagate_orecord_info( flattened_type );
pointees = BE_yank_pointers( flattened_type );
BE_flatten_field_attrs( flattened_type );
for ( tp = flattened_type; tp != NULL; tp = tp->next)
{
flags = 0;
if ( (p_type->kind == AST_array_k) || AST_CONFORMANT_SET(p_type) )
{
flags |= (BE_D_PARRAY | BE_D_OARRAYM);
}
if (p_type->kind == AST_array_k)
{
flags |= BE_D_PARRAYM ;
}
BE_decorate_parameter( &dummy_oper, tp, BE_client_side,flags );
}
BE_flag_alignment( flattened_type, 1 );
BE_flatten_field_attrs( pointees );
for ( tp = pointees; tp != NULL; tp = tp->next)
BE_decorate_parameter( &dummy_oper, tp, BE_client_side, 0 );
BE_flag_alignment( pointees, 1 );
has_pointers = BE_any_pointers( flattened_type );
v1_stringifiable = (varying
&& AST_SMALL_SET(p_type)
&& !AST_STRING0_SET(p_type)
&& !has_pointers);
#ifdef DEBUG_VERBOSE
if (BE_dump_mool)
{
printf("\nmool dump : CSPELL_marshall_ool_type\n");
printf( "------------------------------------\n");
traverse(flattened_type, 2);
traverse(pointees, 2);
}
#endif
/* Routine declaration */
CSPELL_marshall_ool_type_decl( fid, p_type, call_side, false,
flattened_type, varying, has_pointers, false, v1_stringifiable );
fprintf( fid, "{\n");
/* Declare local variables */
CSPELL_local_var_decls( fid, &dummy_oper );
fprintf( fid, "unsigned long space_for_node;\n");
fprintf( fid, "rpc_mp_t mp;\n");
fprintf( fid, "rpc_op_t op;\n\n");
/* Do we need to change buffers before marshalling the fields? */
fprintf( fid, "space_for_node=%s+7;\n", BE_list_size_exp(flattened_type) );
fprintf( fid, "if (space_for_node > NIDL_msp->space_in_buff)\n");
fprintf( fid, "{\n");
fprintf( fid, "rpc_ss_marsh_change_buff(NIDL_msp,space_for_node);\n");
CSPELL_return_on_status( fid );
fprintf( fid, "}\n");
/*
* Omit the gap for singleton [ref] pointers
*/
if (p_type->kind == AST_pointer_k && AST_REF_SET(p_type))
;
else
{
/*
* Marshall the fields of the structure
*/
if ( AST_CONFORMANT_SET(p_type) )
{
/* Special processing of open record header */
if (p_type->kind == AST_structure_k)
array_desc = BE_Open_Array(flattened_type);
else array_desc = flattened_type;
fprintf(fid, "%s = %s;\n",
BE_get_name(BE_Array_Info(array_desc)->size_var),
BE_Array_Info(array_desc)->size_exp);
if (varying)
{
fprintf( fid, "mp = NIDL_msp->mp;\n");
fprintf( fid, "op = NIDL_msp->op;\n");
routine_mode = false;
BE_spell_varying_marshall( fid, array_desc, BE_M_NODE |
BE_M_OOL_RTN | BE_M_MAINTAIN_OP | BE_M_SLOTLESS );
}
else
{
fprintf(fid, "%s = %s;\n",
BE_get_name(BE_Array_Info(array_desc)->count_var),
BE_get_name(BE_Array_Info(array_desc)->size_var));
routine_mode = true;
}
elt = flattened_type->next;
}
else
{
elt = flattened_type;
routine_mode = true;
}
for ( ; elt; elt = elt->next)
{
if (BE_PI_Flags(elt) & BE_SKIP)
continue;
BE_marshall_param( fid, elt, BE_M_NODE | BE_M_ADVANCE_MP |
BE_M_ALIGN_MP | BE_M_OOL_RTN | BE_M_BUFF_EXISTS |
BE_M_SLOTLESS | BE_M_MAINTAIN_OP |
((call_side==BE_caller) ? BE_M_CALLER : BE_M_CALLEE), 0,
&dummy_slots_used, &routine_mode, 0 );
}
if (!routine_mode)
{
fprintf( fid, "NIDL_msp->space_in_buff -= (op - NIDL_msp->op);\n");
fprintf( fid, "NIDL_msp->mp = mp;\n");
fprintf( fid, "NIDL_msp->op = op;\n");
routine_mode = true;
}
}
fprintf( fid, "}\n");
if (has_pointers)
{
CSPELL_marshall_ool_type_decl( fid, p_type, call_side, false,
flattened_type, varying, true, true, false );
fprintf( fid, "{\n");
CSPELL_local_var_decls( fid, &dummy_oper );
if ( AST_CONFORMANT_SET(p_type) )
{
/* Special processing of open record header */
if (p_type->kind == AST_structure_k)
array_desc = BE_Open_Array(flattened_type);
else array_desc = flattened_type;
fprintf(fid, "%s = %s;\n",
BE_get_name(BE_Array_Info(array_desc)->size_var),
BE_Array_Info(array_desc)->size_exp);
if ( ! varying)
{
fprintf(fid, "%s = %s;\n",
BE_get_name(BE_Array_Info(array_desc)->count_var),
BE_get_name(BE_Array_Info(array_desc)->size_var));
}
}
BE_ool_spell_varying_info( fid, flattened_type );
for (elt = pointees; elt; elt = elt->next)
{
if (BE_PI_Flags(elt) & BE_SKIP)
continue;
BE_marshall_param( fid, elt, BE_M_NODE | BE_M_ADVANCE_MP |
BE_M_SLOTLESS | BE_M_MAINTAIN_OP | BE_M_BUFF_EXISTS |
BE_M_OOL_RTN |
((call_side==BE_caller) ? BE_M_CALLER : BE_M_CALLEE), 0,
&dummy_slots_used, &routine_mode, 0 );
}
fprintf( fid, "}\n");
}
}
/******************************************************************************/
/* */
/* Output the declaration part of a node unmarshalling routine */
/* */
/******************************************************************************/
void CSPELL_unmarshall_ool_type_decl
#ifdef PROTO
(
FILE *fid,
AST_type_n_t *p_type, /* Type of node to be marshalled */
BE_call_side_t call_side,
boolean in_header, /* TRUE if decl to be emitted to header file */
AST_parameter_n_t *flattened_type,
boolean varying, /* TRUE if rtn is for [non]varying array */
boolean has_pointers, /* TRUE if the type includes any pointers */
boolean pointee_routine, /* TRUE for routines that unmarshall pointees */
boolean v1_stringifiable /* TRUE if v1_array && !v1_string */
)
#else
( fid, p_type, call_side, in_header, flattened_type, varying, has_pointers,
pointee_routine, v1_stringifiable )
FILE *fid;
AST_type_n_t *p_type; /* Type of node to be marshalled */
BE_call_side_t call_side;
boolean in_header; /* TRUE if decl to be emitted to header file */
AST_parameter_n_t *flattened_type;
boolean varying;
boolean has_pointers;
boolean pointee_routine;
boolean v1_stringifiable;
#endif
{
int i;
int num_array_dimensions;
AST_parameter_n_t *array_desc;
fprintf( fid, "\n");
CSPELL_ool_routine_name( fid, p_type, call_side, BE_unmarshalling_k,
varying, pointee_routine );
if ( (p_type->kind == AST_array_k) || AST_CONFORMANT_SET(p_type) )
{
array_desc = (p_type->kind == AST_structure_k)
? BE_Open_Array(flattened_type) : flattened_type;
if ( ! AST_SMALL_SET(array_desc) )
num_array_dimensions =
array_desc->type->type_structure.array->index_count;
}
#if 0
fprintf( fid, "\n#ifdef IDL_PROTOTYPES\n");
fprintf( fid, "(\n");
spell_name( fid, p_type->name );
fprintf( fid, " *p_node,\n");
if ( AST_CONFORMANT_SET(p_type) )
{
array_desc = (p_type->kind == AST_structure_k)
? BE_Open_Array(flattened_type) : flattened_type;
if ( AST_SMALL_SET(array_desc) )
{
fprintf( fid, "ndr_ulong_int " );
spell_name( fid, BE_Array_Info(array_desc)->size_var );
fprintf( fid, ",\n" );
}
else
{
num_array_dimensions =
array_desc->type->type_structure.array->index_count;
for (i=0; i<num_array_dimensions; i++)
{
fprintf( fid, "ndr_ulong_int " );
spell_name( fid, BE_Array_Info(array_desc)->Z[i] );
fprintf( fid, ",\n" );
}
}
}
if ( (call_side == BE_caller) && (has_pointers) )
{
if ( pointee_routine )
{
fprintf( fid, "idl_boolean NIDL_new_node,\n" );
}
}
if ( (call_side == BE_callee) && (pointee_routine) )
{
fprintf( fid, "rpc_ss_node_type_k_t NIDL_node_type,\n" );
}
fprintf( fid, "rpc_ss_marsh_state_t *p_unmar_params\n");
fprintf( fid, ")\n" );
fprintf( fid, "#else\n");
#endif
if ( in_header )
{
fprintf( fid, "()\n");
}
else
{
/* Spell parameter list. */
fprintf( fid, "( p_node" );
if ( (call_side == BE_caller) && (has_pointers) )
{
if ( pointee_routine )
{
fprintf( fid, ", NIDL_new_node" );
}
}
if ( (call_side == BE_callee) && (pointee_routine) )
{
fprintf( fid, ", NIDL_node_type" );
}
fprintf( fid, ", p_unmar_params" );
if ( varying )
fprintf( fid, ", NIDL_varying" );
if ( v1_stringifiable )
fprintf( fid, ", v1_string_flag" );
if ( AST_CONFORMANT_SET(p_type) )
{
if ( AST_SMALL_SET(array_desc) )
{
fprintf( fid, ", " );
spell_name( fid, BE_Array_Info(array_desc)->size_var );
}
else
{
for (i=0; i<num_array_dimensions; i++)
{
fprintf( fid, ", " );
spell_name( fid, BE_Array_Info(array_desc)->Z[i] );
}
}
}
fprintf( fid, " )\n");
/* Spell parameter declarations. */
spell_name( fid, p_type->name );
fprintf( fid, " *p_node;\n" );
if ( (call_side == BE_caller) && (has_pointers) )
{
if ( pointee_routine )
{
fprintf( fid, "idl_boolean NIDL_new_node;\n" );
}
}
if ( (call_side == BE_callee) && (pointee_routine) )
{
fprintf( fid, "rpc_ss_node_type_k_t NIDL_node_type;\n" );
}
fprintf( fid, "rpc_ss_marsh_state_t *p_unmar_params;\n" );
if ( varying )
fprintf( fid, "idl_boolean NIDL_varying;\n" );
/*
* Add a parameter to OOL unmarshalling routines for types that may
* be V1_stringified but are not themselves marked with a V1_string
* attribute. [OOL routines for stringified types will unmarshall
* their data as per string NDR without having to be so told by
* the in-line call.]
*/
if ( v1_stringifiable )
{
fprintf( fid, "idl_boolean v1_string_flag;\n" );
}
if ( AST_CONFORMANT_SET(p_type) )
{
if ( AST_SMALL_SET(array_desc) )
{
fprintf( fid, "ndr_ulong_int " );
spell_name( fid, BE_Array_Info(array_desc)->size_var );
fprintf( fid, ";\n" );
}
else
{
for (i=0; i<num_array_dimensions; i++)
{
fprintf( fid, "ndr_ulong_int " );
spell_name( fid, BE_Array_Info(array_desc)->Z[i] );
fprintf( fid, ";\n" );
}
}
}
}
#if 0
fprintf( fid, "#endif\n");
#endif
if ( in_header )
{
fprintf( fid, ";\n");
}
}
/******************************************************************************/
/* */
/* Output the code to unmarshal a node of a specific type */
/* */
/******************************************************************************/
static void CSPELL_unmarshall_ool_type
#ifdef PROTO
(
FILE *fid,
AST_type_n_t *p_type, /* Type of node to be unmarshalled */
BE_call_side_t call_side
)
#else
( fid, p_type, call_side )
FILE *fid;
AST_type_n_t *p_type; /* Type of node to be unmarshalled */
BE_call_side_t call_side;
#endif
{
AST_parameter_n_t dummy_param;
AST_parameter_n_t *open_array = NULL;
AST_parameter_n_t *flattened_type, *pointees;
AST_parameter_n_t *tp;
AST_operation_n_t dummy_oper;
AST_parameter_n_t *elt;
AST_parameter_n_t *array_desc;
boolean varying;
boolean has_pointers;
boolean v1_stringifiable;
boolean routine_mode = false; /* Only used at top level */
/*
* ool types must be named types. Even if the type has no varying instances
* in this interface, it could have varying instances in another interface
* that imports this one. Thus, ool routines for arrays are always generic
* so that they can handle a varying or non-varying instance; below we
* always flatten an array as varying.
*/
varying = (p_type->kind == AST_array_k
|| AST_STRING_SET(p_type) || AST_STRING0_SET(p_type));
/* Prepare to emit code */
dummy_param.be_info.param = NULL;
dummy_oper.be_info.oper = (BE_oper_i_t *)BE_ctx_malloc(sizeof(BE_oper_i_t));
(dummy_oper.be_info.oper)->local_vars = NULL;
(dummy_oper.be_info.oper)->next_local_var = 0;
dummy_oper.be_info.oper->flags = 0;
dummy_param.uplink = &dummy_oper;
dummy_param.flags = varying ? AST_VARYING : 0;
dummy_param.field_attrs = NULL;
flattened_type = BE_flatten_parameter( &dummy_param,
NAMETABLE_add_id("(*p_node)"), p_type, BE_server_side,
true, &open_array, BE_F_OOL_RTN );
BE_propagate_orecord_info( flattened_type );
pointees = BE_yank_pointers( flattened_type );
BE_flatten_field_attrs( flattened_type );
for ( tp = flattened_type; tp != NULL; tp = tp->next)
BE_decorate_parameter( &dummy_oper, tp, BE_client_side,
( (p_type->kind == AST_array_k) || AST_CONFORMANT_SET(p_type) )
? BE_D_PARRAY | BE_D_OARRAYU : 0 );
BE_flag_alignment( flattened_type, 1 );
BE_flatten_field_attrs( pointees );
for ( tp = pointees; tp != NULL; tp = tp->next)
BE_decorate_parameter( &dummy_oper, tp, BE_client_side, 0 );
BE_flag_alignment( pointees, 1 );
has_pointers = BE_any_pointers( flattened_type );
v1_stringifiable = (varying
&& AST_SMALL_SET(p_type)
&& !AST_STRING0_SET(p_type)
&& !has_pointers);
#ifdef DEBUG_VERBOSE
if (BE_dump_uool)
{
printf("\nuool dump : CSPELL_unmarshall_ool_type\n");
printf( "--------------------------------------\n");
traverse(flattened_type, 2);
traverse(pointees, 2);
}
#endif
/* Routine declaration */
CSPELL_unmarshall_ool_type_decl( fid, p_type, call_side, false,
flattened_type, varying, has_pointers, false, v1_stringifiable);
fprintf( fid, "{\n");
/* Declare local variables */
CSPELL_local_var_decls( fid, &dummy_oper );
if ( BE_any_pointers(flattened_type) )
{
fprintf( fid, "unsigned long node_number;\n");
}
fprintf( fid, "ndr_boolean buffer_changed;\n");
/* Start of executable code */
if ( p_type->kind == AST_structure_k)
{
if ( AST_CONFORMANT_SET(p_type) &&
!AST_SMALL_SET(BE_Open_Array(flattened_type)))
{
spell_name(fid,
BE_Array_Info(BE_Open_Array(flattened_type))->size_var);
fprintf(fid, "= %s;\n",
BE_Array_Info(BE_Open_Array(flattened_type))->size_exp);
}
if ( AST_CONFORMANT_SET(p_type) )
{
fprintf(fid, "%s = %s;\n",
BE_get_name(BE_Array_Info(BE_Open_Array(flattened_type))->count_var),
BE_get_name(BE_Array_Info(BE_Open_Array(flattened_type))->size_var));
}
}
if ( p_type->kind == AST_array_k)
{
if ( AST_CONFORMANT_SET(p_type) )
{
spell_name(fid, BE_Array_Info(flattened_type)->size_var);
fprintf(fid, "= %s;\n", BE_Array_Info(flattened_type)->size_exp);
if ( ! varying )
{
fprintf(fid, "%s = %s;\n",
BE_get_name(BE_Array_Info(flattened_type)->count_var),
BE_get_name(BE_Array_Info(flattened_type)->size_var));
}
}
}
/*
* Omit the garbage part of singleton [ref] pointers
*/
if (p_type->kind == AST_pointer_k && AST_REF_SET(p_type))
;
else
{
/* Unmarshall the fields of the structure */
for (elt = flattened_type; elt; elt = elt->next)
{
if (BE_PI_Flags(elt) & BE_SKIP)
continue;
BE_unmarshall_param(fid, elt,
BE_M_NODE | BE_M_CHECK_BUFFER | BE_M_CONVERT |
BE_M_ADVANCE_MP | BE_M_MAINTAIN_OP | BE_M_BUFF_EXISTS |
BE_M_ALIGN_MP | BE_M_OOL_RTN |
((call_side==BE_caller) ? BE_M_CALLER : BE_M_CALLEE),
&BE_unmarshall_node_names, &routine_mode );
}
}
fprintf( fid, "}\n");
/* Now for each pointer, unmarshall the pointee */
if (has_pointers)
{
CSPELL_unmarshall_ool_type_decl( fid, p_type, call_side, false,
flattened_type, varying, true, true, false );
fprintf( fid, "{\n");
CSPELL_local_var_decls( fid, &dummy_oper );
if ( p_type->kind == AST_structure_k)
{
if ( AST_CONFORMANT_SET(p_type) &&
!AST_SMALL_SET(BE_Open_Array(flattened_type)))
{
spell_name(fid,
BE_Array_Info(BE_Open_Array(flattened_type))->size_var);
fprintf(fid, "= %s;\n",
BE_Array_Info(BE_Open_Array(flattened_type))->size_exp);
}
if ( AST_CONFORMANT_SET(p_type) )
{
fprintf(fid, "%s = %s;\n",
BE_get_name(BE_Array_Info
(BE_Open_Array(flattened_type))->count_var),
BE_get_name(BE_Array_Info
(BE_Open_Array(flattened_type))->size_var));
}
}
if ( p_type->kind == AST_array_k)
{
if ( AST_CONFORMANT_SET(p_type) )
{
spell_name(fid, BE_Array_Info(flattened_type)->size_var);
fprintf(fid, "= %s;\n", BE_Array_Info(flattened_type)->size_exp);
if ( ! varying )
{
fprintf(fid, "%s = %s;\n",
BE_get_name(BE_Array_Info(flattened_type)->count_var),
BE_get_name(BE_Array_Info(flattened_type)->size_var));
}
}
}
BE_ool_spell_varying_info( fid, flattened_type );
for (elt = pointees; elt; elt = elt->next)
{
if (BE_PI_Flags(elt) & BE_SKIP)
continue;
BE_unmarshall_param(fid, elt, BE_M_NODE | BE_M_CHECK_BUFFER |
BE_M_CONVERT | BE_M_ADVANCE_MP |
BE_M_MAINTAIN_OP | BE_M_BUFF_EXISTS | BE_M_OOL_RTN |
((call_side==BE_caller) ? BE_M_CALLER : BE_M_CALLEE),
&BE_unmarshall_node_names, &routine_mode );
}
fprintf( fid, "}\n");
}
}
/******************************************************************************/
/* */
/* Spell the routines for un/marshalling out_of_line types */
/* */
/******************************************************************************/
void BE_out_of_line_routines
#ifdef PROTO
(
FILE *fid,
AST_interface_n_t *p_interface,
BE_call_side_t call_side
)
#else
( fid, p_interface, call_side )
FILE *fid;
AST_interface_n_t *p_interface;
BE_call_side_t call_side;
#endif
{
AST_type_p_n_t *curr_ool_type_link;
/* Position in list of out_of_line types */
boolean routine_mode = false; /* Only used at top level */
for( curr_ool_type_link = p_interface->ool_types;
curr_ool_type_link != NULL;
curr_ool_type_link = curr_ool_type_link->next )
{
if (curr_ool_type_link->type->kind == AST_handle_k)
continue; /* Don't out of line types that resolve to handle_t */
BE_push_malloc_ctx();
NAMETABLE_set_temp_name_mode();
/* Generate ool routines for non-pipes */
if (curr_ool_type_link->type->kind != AST_pipe_k)
{
CSPELL_marshall_ool_type( fid, curr_ool_type_link->type, call_side );
CSPELL_unmarshall_ool_type( fid, curr_ool_type_link->type, call_side );
}
/* Generate pipe ool routines on client side */
else if (call_side == BE_caller)
{
CSPELL_marshall_in_pipe(fid, curr_ool_type_link->type, "(*p_node)",
0, "iovec", true);
CSPELL_unmarshall_out_pipe(fid, curr_ool_type_link->type,
"(*p_node)", 0,
"(p_unmar_params->mp)", "(p_unmar_params->op)",
"(p_unmar_params->src_drep)", "(p_unmar_params->p_rcvd_data)",
"(p_unmar_params->call_h)", "(*p_unmar_params->p_st)", true,
&routine_mode);
}
NAMETABLE_clear_temp_name_mode();
BE_pop_malloc_ctx();
}
}