#include <nidl.h>
#include <ast.h>
#include <command.h>
#include <cspell.h>
#include <cspeldcl.h>
#include <ddbe.h>
#include <ifspec.h>
#include <commstat.h>
#include <clihamts.h>
#include <cstubgen.h>
#include <mtsbacke.h>
#include <cstubmts.h>
#include <user_exc.h>
#include <icharsup.h>
#include <hdgen.h>
BE_handle_info_t BE_handle_info;
static AST_interface_n_t * the_interface = NULL;
static AST_cpp_quote_n_t * global_cppquotes = NULL;
static AST_cpp_quote_n_t * global_cppquotes_post = NULL;
void CSPELL_test_status
(
FILE *fid
)
{
fprintf(fid,
"if (IDL_ms.IDL_status != error_status_ok) goto IDL_closedown;\n");
}
void CSPELL_test_transceive_status
(
FILE *fid
)
{
fprintf(fid, "if (IDL_ms.IDL_status != error_status_ok)\n{\n");
fprintf(fid, "IDL_ms.IDL_elt_p = NULL;\n");
if ( ( BE_handle_info.handle_type == BE_auto_handle_k )
&& ( ! BE_handle_info.auto_handle_idempotent_op ) )
{
fprintf(fid,
"IDL_ms.IDL_restartable=IDL_ms.IDL_restartable&&(!(rpc_call_did_mgr_execute\n");
fprintf(fid," ((rpc_call_handle_t)IDL_ms.IDL_call_h,&IDL_st2)));\n");
}
fprintf(fid, "goto IDL_closedown;\n}\n");
}
void CSPELL_csr_header
(
FILE *fid,
char const *p_interface_name,
AST_operation_n_t *p_operation,
boolean use_internal_name
)
{
char op_internal_name[3 * MAX_ID];
NAMETABLE_id_t emitted_name;
AST_parameter_n_t * handle_param = NULL;
if (use_internal_name) {
sprintf(op_internal_name, "op%d_csr", p_operation->op_number);
emitted_name = NAMETABLE_add_id(op_internal_name);
fprintf(fid, "\nstatic ");
}
else if (AST_OBJECT_SET(the_interface)) {
sprintf(op_internal_name, "%sProxy::%s", p_interface_name,
BE_get_name(p_operation->name));
emitted_name = NAMETABLE_add_id(op_internal_name);
if (BE_is_handle_param(p_operation->parameters)) {
handle_param = p_operation->parameters;
p_operation->parameters = p_operation->parameters->next;
}
} else {
fprintf (fid, "\n");
emitted_name = p_operation->name;
}
CSPELL_function_def_header (fid, p_operation, emitted_name);
CSPELL_finish_synopsis (fid, p_operation->parameters);
if (handle_param)
p_operation->parameters->next = handle_param;
}
static void CSPELL_client_stub_routine
(
FILE *fid,
AST_interface_n_t *p_interface,
language_k_t language ATTRIBUTE_UNUSED,
AST_operation_n_t *p_operation,
char const *p_interface_name,
unsigned long op_num,
boolean *cmd_opt,
int num_declared_exceptions,
int num_extern_exceptions
)
{
BE_stat_info_t comm_stat_info;
BE_stat_info_t fault_stat_info;
BE_cs_info_t cs_info;
boolean use_internal_name = cmd_opt[opt_cepv];
boolean midl_mode = cmd_opt[opt_midl];
BE_get_comm_stat_info( p_operation, &comm_stat_info );
BE_get_fault_stat_info( p_operation, &fault_stat_info );
CSPELL_csr_header(fid, p_interface_name, p_operation,
use_internal_name);
fprintf (fid, "{\n");
if (AST_OBJECT_SET(p_interface)) {
if (BE_is_handle_param(p_operation->parameters))
CSPELL_var_decl(fid, p_operation->parameters->type,
p_operation->parameters->name);
}
BE_setup_client_handle (fid, p_interface, p_operation, &BE_handle_info);
BE_cs_analyze_and_spell_vars(fid, p_operation, BE_client_side, &cs_info);
fprintf(fid, "rpc_transfer_syntax_t\t\tIDL_transfer_syntax;\n");
fprintf(fid, "rpc_iovector_elt_t\t\tIDL_outs;\n");
fprintf(fid, "volatile ndr_ulong_int\t\tIDL_fault_code=error_status_ok;\n");
fprintf(fid, "volatile ndr_ulong_int\t\tIDL_user_fault_id=0;\n");
fprintf(fid,
"volatile RPC_SS_THREADS_CANCEL_STATE_T IDL_async_cancel_state;\n");
fprintf(fid, "IDL_ms_t\t\tIDL_ms;\n");
fprintf(fid, "idl_byte\t\tIDL_stack_packet[IDL_STACK_PACKET_SIZE];\n");
DDBE_spell_param_vec_def( fid, p_operation, BE_client_side,
BE_cmd_opt, BE_cmd_val );
if ( (p_operation->result->type->kind != AST_void_k)
)
{
CSPELL_typed_name(fid, p_operation->result->type,
NAMETABLE_add_id("IDL_function_result"),
NULL, false, true, false);
fprintf(fid, ";\n");
}
fprintf(fid, "\nRPC_SS_INIT_CLIENT\n");
fprintf(fid, "RPC_SS_THREADS_DISABLE_ASYNC(IDL_async_cancel_state);\n");
if ( BE_handle_info.handle_type == BE_auto_handle_k )
{
fprintf( fid, "IDL_ms.IDL_restartable=idl_true;\n" );
fprintf(fid,
"RPC_SS_THREADS_ONCE(&IDL_interface_client_once,IDL_auto_handle_init);\n");
}
else
{
#ifdef NO_TRY_CATCH_FINALLY
fprintf(fid, "DCETHREAD_TRY\n");
#endif
}
if (num_declared_exceptions != 0)
{
fprintf(fid,
"RPC_SS_THREADS_ONCE(&IDL_exception_once,IDL_exceptions_init);\n");
}
fprintf(fid, "rpc_ss_init_marsh_state(IDL_type_vec, &IDL_ms);\n");
if (midl_mode)
{
fprintf(fid, "IDL_ms.IDL_mem_handle.alloc = midl_user_allocate;\n");
fprintf(fid, "IDL_ms.IDL_mem_handle.free = midl_user_free;\n");
fprintf(fid, "rpc_ss_set_client_alloc_free(IDL_midl_user_allocate, IDL_midl_user_free);\n");
}
fprintf(fid,
"IDL_ms.IDL_stack_packet_status = IDL_stack_packet_unused_k;\n");
fprintf(fid, "IDL_ms.IDL_stack_packet_addr = IDL_stack_packet;\n");
fprintf(fid, "DCETHREAD_TRY\n");
fprintf(fid, "IDL_ms.IDL_call_h = 0;\n");
fprintf(fid, "IDL_ms.IDL_elt_p = NULL;\n");
fprintf(fid, "IDL_ms.IDL_offset_vec = IDL_offset_vec;\n");
fprintf(fid, "IDL_ms.IDL_rtn_vec = IDL_rtn_vec;\n");
DDBE_spell_param_vec_init( fid, p_operation, BE_client_side,
BE_cmd_opt, BE_cmd_val );
fprintf(fid, "IDL_ms.IDL_param_vec = IDL_param_vec;\n");
fprintf(fid, "IDL_ms.IDL_side = IDL_client_side_k;\n");
fprintf(fid, "IDL_ms.IDL_language = ");
fprintf(fid, "IDL_lang_c_k");
fprintf(fid, ";\n");
if (AST_HAS_FULL_PTRS_SET(p_operation) &&
(AST_HAS_IN_PTRS_SET(p_operation) || AST_HAS_OUT_PTRS_SET(p_operation)))
{
fprintf(fid,
"rpc_ss_init_node_table(&IDL_ms.IDL_node_table,&IDL_ms.IDL_mem_handle);\n");
}
if (AST_HAS_OUT_PTRS_SET(p_operation) )
{
fprintf(fid, "rpc_ss_mts_client_estab_alloc(&IDL_ms);\n");
}
BE_spell_cs_state(fid, "IDL_ms.", BE_client_side, &cs_info);
BE_spell_cs_tag_rtn_call(fid, "IDL_ms.", p_operation, BE_client_side,
&BE_handle_info, &cs_info, false);
CSPELL_call_start(fid, &BE_handle_info, p_interface, p_operation, op_num,
&comm_stat_info, &fault_stat_info);
if (AST_HAS_IN_CTX_SET(p_operation)
|| AST_HAS_OUT_CTX_SET(p_operation)
|| cs_info.cs_machinery)
{
fprintf(fid, "IDL_ms.IDL_h=(handle_t)%c%s;\n",
BE_handle_info.deref_assoc, BE_handle_info.assoc_name);
}
DDBE_spell_marsh_or_unmar( fid, p_operation, "rpc_ss_ndr_marsh_interp",
"&IDL_ms", BE_client_side, BE_marshalling_k );
fprintf(fid,"IDL_ms.IDL_elt_p = &IDL_outs;\n");
fprintf(fid,
"rpc_call_transceive((rpc_call_handle_t)IDL_ms.IDL_call_h,(rpc_iovector_p_t)&IDL_ms.IDL_iovec,\n");
fprintf(fid,
" IDL_ms.IDL_elt_p,&IDL_ms.IDL_drep,(unsigned32*)&IDL_ms.IDL_status);\n");
if (AST_MAYBE_SET(p_operation))
fprintf(fid, "IDL_outs.buff_dealloc=NULL;\n");
CSPELL_test_transceive_status(fid);
DDBE_spell_marsh_or_unmar( fid, p_operation, "rpc_ss_ndr_unmar_interp",
"&IDL_ms", BE_client_side, BE_unmarshalling_k );
fprintf(fid, "IDL_closedown: __IDL_UNUSED_LABEL__;\n");
fprintf(fid, "DCETHREAD_CATCH(rpc_x_ss_pipe_comm_error)\n");
if ( BE_handle_info.handle_type == BE_auto_handle_k )
{
DDBE_spell_restart_logic( fid, p_operation );
fprintf(fid, "IDL_auto_binding_failure:;\n");
}
else {
#ifdef NO_TRY_CATCH_FINALLY
fprintf(fid, "DCETHREAD_ENDTRY\n");
#endif
}
fprintf(fid, "DCETHREAD_FINALLY\n");
fprintf(fid, "rpc_ss_ndr_clean_up(&IDL_ms);\n");
if ( BE_handle_info.handle_type == BE_auto_handle_k )
fprintf(fid, "if(IDL_ms.IDL_call_h!=NULL)");
fprintf(fid,
"rpc_ss_call_end_2(&IDL_ms.IDL_call_h,&IDL_fault_code,&IDL_user_fault_id,&IDL_ms.IDL_status);\n");
CSPELL_binding_free_if_needed( fid, &BE_handle_info );
if ((BE_handle_info.handle_type == BE_parm_user_handle_k)
|| (BE_handle_info.handle_type == BE_impl_user_handle_k))
{
fprintf (fid, "DCETHREAD_TRY\n");
fprintf (fid, "%s_unbind(%c%s%s, (handle_t)IDL_assoc_handle);\n",
BE_handle_info.type_name, BE_handle_info.deref_generic,
BE_handle_info.user_handle_name,
"");
fprintf (fid, "DCETHREAD_FINALLY\n");
}
if ((BE_handle_info.handle_type == BE_rep_as_handle_t_k)
|| (BE_handle_info.handle_type == BE_rep_as_handle_t_p_k))
{
fprintf (fid, "DCETHREAD_TRY\n");
fprintf( fid, "%s_free_inst((handle_t *)%s);\n",
BE_get_name(BE_handle_info.rep_as_type),
assoc_handle_ptr );
fprintf (fid, "DCETHREAD_FINALLY\n");
}
fprintf(fid, "if (IDL_ms.IDL_mem_handle.memory)\n{\n");
fprintf(fid, " rpc_ss_mem_free(&IDL_ms.IDL_mem_handle);\n}\n");
CSPELL_return_status( fid, &comm_stat_info, &fault_stat_info,
"IDL_ms.IDL_status",
( (comm_stat_info.type == BE_stat_result_k)
|| (fault_stat_info.type == BE_stat_result_k) )
? "IDL_function_result" : (char *)NULL,
num_declared_exceptions + num_extern_exceptions, "&IDL_ms" );
fprintf(fid, "RPC_SS_THREADS_RESTORE_ASYNC(IDL_async_cancel_state);\n");
if ((BE_handle_info.handle_type == BE_parm_user_handle_k)
|| (BE_handle_info.handle_type == BE_impl_user_handle_k)
|| (BE_handle_info.handle_type == BE_rep_as_handle_t_k)
|| (BE_handle_info.handle_type == BE_rep_as_handle_t_p_k))
{
fprintf(fid, "DCETHREAD_ENDTRY\n");
}
fprintf(fid, "DCETHREAD_ENDTRY\n");
if ( (p_operation->result->type->kind != AST_void_k)
)
fprintf(fid, "return IDL_function_result;\n");
fprintf (fid, "}\n");
}
void DDBE_spell_pickling_stub
(
FILE *fid,
AST_interface_n_t *p_interface,
char const *p_interface_name,
AST_operation_n_t *p_operation,
boolean use_internal_name
)
{
boolean encode_decode;
const char *action_type;
BE_stat_info_t comm_stat_info;
BE_stat_info_t fault_stat_info;
BE_cs_info_t cs_info;
BE_get_comm_stat_info( p_operation, &comm_stat_info );
BE_get_fault_stat_info( p_operation, &fault_stat_info );
BE_setup_client_handle (fid, p_interface, p_operation, &BE_handle_info);
encode_decode = (AST_ENCODE_SET(p_operation)
&& AST_DECODE_SET(p_operation));
CSPELL_csr_header(fid, p_interface_name, p_operation, use_internal_name);
fprintf(fid, "{\n");
fprintf(fid, "volatile ndr_ulong_int IDL_fault_code=error_status_ok;\n");
fprintf(fid, "volatile ndr_ulong_int IDL_user_fault_id=0;\n");
fprintf(fid,
"volatile RPC_SS_THREADS_CANCEL_STATE_T IDL_async_cancel_state;\n");
fprintf(fid, "IDL_es_state_t *IDL_es_state_p;\n");
fprintf(fid, "volatile IDL_ms_t *IDL_msp;\n");
fprintf(fid, "idl_es_transfer_syntax_t IDL_es_transfer_syntax;\n");
DDBE_spell_param_vec_def( fid, p_operation, BE_client_side,
BE_cmd_opt, BE_cmd_val );
if ( (p_operation->result->type->kind != AST_void_k)
)
{
CSPELL_typed_name(fid, p_operation->result->type,
NAMETABLE_add_id("IDL_function_result"),
NULL, false, true, false);
fprintf(fid, ";\n");
}
BE_cs_analyze_and_spell_vars(fid, p_operation, BE_client_side, &cs_info);
fprintf(fid, "RPC_SS_INIT_CLIENT\n");
fprintf(fid, "RPC_SS_THREADS_DISABLE_ASYNC(IDL_async_cancel_state);\n");
fprintf(fid, "IDL_es_state_p = (IDL_es_state_t *)%c%s;\n",
BE_handle_info.deref_assoc, BE_handle_info.assoc_name);
fprintf(fid, "IDL_msp = (volatile IDL_ms_t *)IDL_es_state_p->IDL_msp;\n");
fprintf(fid, "IDL_msp->IDL_offset_vec = IDL_offset_vec;\n");
fprintf(fid, "IDL_msp->IDL_rtn_vec = IDL_rtn_vec;\n");
fprintf(fid, "DCETHREAD_TRY\n");
DDBE_spell_param_vec_init( fid, p_operation, BE_client_side,
BE_cmd_opt, BE_cmd_val );
fprintf(fid, "IDL_msp->IDL_param_vec = IDL_param_vec;\n");
fprintf(fid, "IDL_msp->IDL_side = IDL_client_side_k;\n");
fprintf(fid, "IDL_msp->IDL_language = ");
fprintf(fid, "IDL_lang_c_k");
fprintf(fid, ";\n");
if (AST_HAS_FULL_PTRS_SET(p_operation) &&
(AST_HAS_IN_PTRS_SET(p_operation) || AST_HAS_OUT_PTRS_SET(p_operation)))
{
fprintf(fid,
"rpc_ss_init_node_table(&IDL_msp->IDL_node_table,&IDL_msp->IDL_mem_handle);\n");
}
if (AST_HAS_OUT_PTRS_SET(p_operation) )
{
fprintf(fid, "rpc_ss_mts_client_estab_alloc(IDL_msp);\n");
}
BE_spell_cs_state(fid, "IDL_msp->", BE_client_side, &cs_info);
if (cs_info.cs_machinery)
fprintf(fid, "IDL_msp->IDL_h=NULL;\n");
if (encode_decode)
action_type = "IDL_both_k";
else if (AST_ENCODE_SET(p_operation))
action_type = "IDL_encoding_k";
else
action_type = "IDL_decoding_k";
fprintf(fid,
"idl_es_before_interp_call(%c%s,(rpc_if_handle_t)&IDL_ifspec,\n",
BE_handle_info.deref_assoc, BE_handle_info.assoc_name);
fprintf(fid,
" IDL_type_vec,%d,%s,&IDL_es_transfer_syntax,(IDL_msp_t)IDL_msp);\n",
p_operation->op_number, action_type);
BE_spell_cs_tag_rtn_call(fid, "IDL_msp->", p_operation, BE_client_side,
&BE_handle_info, &cs_info, true);
if (encode_decode)
fprintf(fid,
"if (IDL_es_state_p->IDL_action == IDL_encoding_k)\n{\n");
if (AST_ENCODE_SET(p_operation))
DDBE_spell_marsh_or_unmar( fid, p_operation,
"rpc_ss_ndr_marsh_interp",
"(IDL_msp_t)IDL_msp",
BE_client_side, BE_marshalling_k );
if (encode_decode)
fprintf(fid, "}\nelse\n{\n");
if (AST_DECODE_SET(p_operation))
DDBE_spell_marsh_or_unmar( fid, p_operation,
"rpc_ss_ndr_unmar_interp",
"(IDL_msp_t)IDL_msp",
BE_client_side, BE_unmarshalling_k );
if (encode_decode)
fprintf(fid, "}\n");
fprintf(fid, "idl_es_after_interp_call((IDL_msp_t)IDL_msp);\n");
fprintf(fid, "DCETHREAD_CATCH(rpc_x_ss_pipe_comm_error)\n");
fprintf(fid, "DCETHREAD_FINALLY\n");
fprintf(fid, "idl_es_clean_up((IDL_msp_t)IDL_msp);\n");
CSPELL_return_status( fid, &comm_stat_info, &fault_stat_info,
"IDL_msp->IDL_status",
( (comm_stat_info.type == BE_stat_result_k)
|| (fault_stat_info.type == BE_stat_result_k) )
? "IDL_function_result" : (char *)NULL,
0, "(IDL_msp_t)IDL_msp" );
fprintf(fid, "RPC_SS_THREADS_RESTORE_ASYNC(IDL_async_cancel_state);\n");
fprintf(fid, "DCETHREAD_ENDTRY\n");
if ( (p_operation->result->type->kind != AST_void_k)
)
{
fprintf(fid, "return IDL_function_result;\n");
}
fprintf (fid, "}\n");
}
void DDBE_gen_cstub
(
FILE *fid,
AST_interface_n_t *p_interface,
language_k_t language,
char header_name[],
boolean *cmd_opt,
void **cmd_val,
DDBE_vectors_t *dd_vip
)
{
AST_export_n_t *p_export;
AST_operation_n_t *p_operation;
char const *p_interface_name;
boolean first;
int num_declared_exceptions;
int num_extern_exceptions;
boolean midl_mode = cmd_opt[opt_midl];
the_interface = p_interface;
NAMETABLE_id_to_string(p_interface->name, &p_interface_name);
CSPELL_suppress_stub_warnings(fid);
CSPELL_mts_includes(fid, header_name);
if (midl_mode)
{
CSPELL_midl_compatibility_allocators(fid);
}
CSPELL_interface_def(fid, p_interface, BE_client_stub_k, false);
if ( AST_AUTO_HANDLE_SET(p_interface) || AST_OBJECT_SET(p_interface))
{
CSPELL_auto_handle_statics( fid );
}
if (AST_OBJECT_SET(p_interface)) {
BE_gen_orpc_defs(fid, p_interface, proxy_def);
}
if (p_interface->implicit_handle_name != NAMETABLE_NIL_ID)
{
fprintf( fid, "globaldef " );
if ( ! AST_IMPLICIT_HANDLE_G_SET(p_interface) )
{
fprintf(fid, "handle_t ");
}
else
{
spell_name( fid, p_interface->implicit_handle_type_name);
fprintf( fid, " " );
}
spell_name( fid, p_interface->implicit_handle_name);
fprintf( fid, ";\n" );
}
DDBE_user_exceptions(fid, p_interface,
&num_declared_exceptions, &num_extern_exceptions);
DDBE_spell_offset_vec( fid, dd_vip, cmd_opt, cmd_val );
DDBE_spell_rtn_vec( fid, dd_vip, cmd_opt, cmd_val, TRUE );
DDBE_spell_type_vec( fid, dd_vip, cmd_opt, cmd_val );
for (p_export = p_interface->exports; p_export; p_export = p_export->next)
{
if (p_export->kind == AST_operation_k)
{
BE_push_malloc_ctx();
NAMETABLE_set_temp_name_mode();
p_operation = p_export->thing_p.exported_operation;
if (!AST_NO_CODE_SET(p_operation))
{
if (AST_ENCODE_SET(p_operation) || AST_DECODE_SET(p_operation))
DDBE_spell_pickling_stub(fid, p_interface,
p_interface_name, p_operation, cmd_opt[opt_cepv]);
else
CSPELL_client_stub_routine(
fid, p_interface, language,
p_operation, p_interface_name, p_operation->op_number,
cmd_opt, num_declared_exceptions,
num_extern_exceptions);
}
NAMETABLE_clear_temp_name_mode();
BE_pop_malloc_ctx();
}
}
if (cmd_opt[opt_cepv]) {
fprintf(fid, "/* global */ %s_v%ld_%ld_epv_t %s_v%ld_%ld_c_epv = {\n",
p_interface_name,
(p_interface->version%65536), (p_interface->version/65536),
p_interface_name,
(p_interface->version%65536), (p_interface->version/65536));
first = true;
for (p_export = p_interface->exports; p_export;
p_export = p_export->next)
if (p_export->kind == AST_operation_k)
{
if (first) first = false;
else fprintf (fid, ",\n");
p_operation = p_export->thing_p.exported_operation;
if (!AST_NO_CODE_SET(p_operation))
{
fprintf(fid, " op%d_csr", p_operation->op_number);
}
else fprintf(fid, " NULL");
}
fprintf (fid, "\n};\n");
}
CSPELL_restore_stub_warnings(fid);
the_interface = NULL;
}