1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** NAME: 79** 80** cstubmts.c 81** 82** FACILITY: 83** 84** Interface Definition Language (IDL) Compiler 85** 86** ABSTRACT: 87** 88** Generation of server stub file for MTS compiler 89** 90*/ 91 92#include <nidl.h> 93#include <ast.h> 94#include <command.h> 95#include <cspell.h> 96#include <cspeldcl.h> 97#include <ddbe.h> 98#include <ifspec.h> 99#include <commstat.h> 100#include <clihamts.h> 101#include <cstubgen.h> 102#include <mtsbacke.h> 103#include <cstubmts.h> 104#include <user_exc.h> 105#include <icharsup.h> 106#include <hdgen.h> 107 108BE_handle_info_t BE_handle_info; 109 110static AST_interface_n_t * the_interface = NULL; 111 112//centeris wfu to keep track of the cpp_quotes in between interfaces 113static AST_cpp_quote_n_t * global_cppquotes = NULL; 114 115static AST_cpp_quote_n_t * global_cppquotes_post = NULL; 116 117/******************************************************************************/ 118/* */ 119/* Spell test of status after runtime call */ 120/* */ 121/******************************************************************************/ 122void CSPELL_test_status 123( 124 FILE *fid 125) 126{ 127 fprintf(fid, 128 "if (IDL_ms.IDL_status != error_status_ok) goto IDL_closedown;\n"); 129} 130 131/******************************************************************************/ 132/* */ 133/* Spell test of status after rpc_call_transceive */ 134/* */ 135/******************************************************************************/ 136void CSPELL_test_transceive_status 137( 138 FILE *fid 139) 140{ 141 fprintf(fid, "if (IDL_ms.IDL_status != error_status_ok)\n{\n"); 142 fprintf(fid, "IDL_ms.IDL_elt_p = NULL;\n"); 143 if ( ( BE_handle_info.handle_type == BE_auto_handle_k ) 144 && ( ! BE_handle_info.auto_handle_idempotent_op ) ) 145 { 146 fprintf(fid, 147"IDL_ms.IDL_restartable=IDL_ms.IDL_restartable&&(!(rpc_call_did_mgr_execute\n"); 148 fprintf(fid," ((rpc_call_handle_t)IDL_ms.IDL_call_h,&IDL_st2)));\n"); 149 } 150 fprintf(fid, "goto IDL_closedown;\n}\n"); 151} 152 153/******************************************************************************/ 154/* */ 155/* Spell client stub routine header */ 156/* */ 157/******************************************************************************/ 158void CSPELL_csr_header 159( 160 FILE *fid, 161 char const *p_interface_name, /* Ptr to name of interface */ 162 AST_operation_n_t *p_operation, /* Ptr to operation node */ 163 boolean use_internal_name /* use internal name if true */ 164) 165{ 166 char op_internal_name[3 * MAX_ID]; 167 NAMETABLE_id_t emitted_name; 168 AST_parameter_n_t * handle_param = NULL; 169 170 if (use_internal_name) { 171 sprintf(op_internal_name, "op%d_csr", p_operation->op_number); 172 emitted_name = NAMETABLE_add_id(op_internal_name); 173 fprintf(fid, "\nstatic "); 174 } 175 else if (AST_OBJECT_SET(the_interface)) { 176 sprintf(op_internal_name, "%sProxy::%s", p_interface_name, 177 BE_get_name(p_operation->name)); 178 emitted_name = NAMETABLE_add_id(op_internal_name); 179 180 /* Skip handle params */ 181 if (BE_is_handle_param(p_operation->parameters)) { 182 handle_param = p_operation->parameters; 183 p_operation->parameters = p_operation->parameters->next; 184 } 185 } else { 186 fprintf (fid, "\n"); 187 emitted_name = p_operation->name; 188 } 189 190 CSPELL_function_def_header (fid, p_operation, emitted_name); 191 192 CSPELL_finish_synopsis (fid, p_operation->parameters); 193 194 /* restore skipped handle params */ 195 if (handle_param) 196 p_operation->parameters->next = handle_param; 197 198} 199 200/******************************************************************************/ 201/* */ 202/* Generation of a stub for a client operation call */ 203/* */ 204/******************************************************************************/ 205static void CSPELL_client_stub_routine 206( 207 FILE *fid, /* Handle for emitted C text */ 208 AST_interface_n_t *p_interface, /* Ptr to AST interface node */ 209 language_k_t language ATTRIBUTE_UNUSED, /* Language stub is to interface to */ 210 AST_operation_n_t *p_operation, /* Ptr to AST operation node */ 211 char const *p_interface_name, /* Ptr to name of interface */ 212 unsigned long op_num, /* Number of current operation */ 213 boolean *cmd_opt, /* Command line options */ 214 int num_declared_exceptions, /* Count of user declared exceptions */ 215 int num_extern_exceptions /* Count of user extern_exceptions */ 216) 217{ 218 BE_stat_info_t comm_stat_info; 219 BE_stat_info_t fault_stat_info; 220 BE_cs_info_t cs_info; /* I-char machinery description */ 221 boolean use_internal_name = cmd_opt[opt_cepv]; 222 boolean midl_mode = cmd_opt[opt_midl]; 223 224 /* What sort of status reporting? */ 225 BE_get_comm_stat_info( p_operation, &comm_stat_info ); 226 BE_get_fault_stat_info( p_operation, &fault_stat_info ); 227 228 /* Routine header */ 229 CSPELL_csr_header(fid, p_interface_name, p_operation, 230 use_internal_name); 231 232 fprintf (fid, "{\n"); 233 234 if (AST_OBJECT_SET(p_interface)) { 235 /* If we skipped a handle param, add it as a local var */ 236 if (BE_is_handle_param(p_operation->parameters)) 237 CSPELL_var_decl(fid, p_operation->parameters->type, 238 p_operation->parameters->name); 239 240 } 241 242 /* 243 * Analyze the association handle the call is being made on; 244 * declare assoc_handle if necessary 245 */ 246 BE_setup_client_handle (fid, p_interface, p_operation, &BE_handle_info); 247 248 /* 249 * Does operation use I-char machinery? If so, declare any needed variables 250 */ 251 BE_cs_analyze_and_spell_vars(fid, p_operation, BE_client_side, &cs_info); 252 253 /* 254 * Standard local variables 255 */ 256 fprintf(fid, "rpc_transfer_syntax_t\t\tIDL_transfer_syntax;\n"); 257 fprintf(fid, "rpc_iovector_elt_t\t\tIDL_outs;\n"); 258 fprintf(fid, "volatile ndr_ulong_int\t\tIDL_fault_code=error_status_ok;\n"); 259 fprintf(fid, "volatile ndr_ulong_int\t\tIDL_user_fault_id=0;\n"); 260 fprintf(fid, 261 "volatile RPC_SS_THREADS_CANCEL_STATE_T IDL_async_cancel_state;\n"); 262 fprintf(fid, "IDL_ms_t\t\tIDL_ms;\n"); 263 fprintf(fid, "idl_byte\t\tIDL_stack_packet[IDL_STACK_PACKET_SIZE];\n"); 264 265 DDBE_spell_param_vec_def( fid, p_operation, BE_client_side, 266 BE_cmd_opt, BE_cmd_val ); 267 268 /* If there is a function result, we need somewhere to put it */ 269 if ( (p_operation->result->type->kind != AST_void_k) 270 ) 271 { 272 CSPELL_typed_name(fid, p_operation->result->type, 273 NAMETABLE_add_id("IDL_function_result"), 274 NULL, false, true, false); 275 fprintf(fid, ";\n"); 276 } 277 278 /* 279 * Start of executable code 280 */ 281 fprintf(fid, "\nRPC_SS_INIT_CLIENT\n"); 282 fprintf(fid, "RPC_SS_THREADS_DISABLE_ASYNC(IDL_async_cancel_state);\n"); 283 if ( BE_handle_info.handle_type == BE_auto_handle_k ) 284 { 285 fprintf( fid, "IDL_ms.IDL_restartable=idl_true;\n" ); 286 fprintf(fid, 287 "RPC_SS_THREADS_ONCE(&IDL_interface_client_once,IDL_auto_handle_init);\n"); 288 } 289 else 290 { 291 /* 292 * To support those platforms which do not allow both a CATCH and 293 * FINALLY clause on the same TRY, we generate one TRY block with a 294 * catch clause nested inside another TRY block with the FINALLY 295 * clause. We conditionally generate the extra TRY statement only for 296 * non-auto handle case because for auto-handle we already have an 297 * nest TRY block. 298 */ 299#ifdef NO_TRY_CATCH_FINALLY 300 fprintf(fid, "DCETHREAD_TRY\n"); 301#endif 302 } 303 304 /* If there are user exceptions which are not external, initialize them */ 305 if (num_declared_exceptions != 0) 306 { 307 fprintf(fid, 308 "RPC_SS_THREADS_ONCE(&IDL_exception_once,IDL_exceptions_init);\n"); 309 } 310 311 fprintf(fid, "rpc_ss_init_marsh_state(IDL_type_vec, &IDL_ms);\n"); 312 313 /* Centeris: set alloc/free function pointers if in MIDL mode */ 314 315 if (midl_mode) 316 { 317 fprintf(fid, "IDL_ms.IDL_mem_handle.alloc = midl_user_allocate;\n"); 318 fprintf(fid, "IDL_ms.IDL_mem_handle.free = midl_user_free;\n"); 319 fprintf(fid, "rpc_ss_set_client_alloc_free(IDL_midl_user_allocate, IDL_midl_user_free);\n"); 320 } 321 322 fprintf(fid, 323 "IDL_ms.IDL_stack_packet_status = IDL_stack_packet_unused_k;\n"); 324 fprintf(fid, "IDL_ms.IDL_stack_packet_addr = IDL_stack_packet;\n"); 325 fprintf(fid, "DCETHREAD_TRY\n"); 326 fprintf(fid, "IDL_ms.IDL_call_h = 0;\n"); 327 fprintf(fid, "IDL_ms.IDL_elt_p = NULL;\n"); 328 fprintf(fid, "IDL_ms.IDL_offset_vec = IDL_offset_vec;\n"); 329 fprintf(fid, "IDL_ms.IDL_rtn_vec = IDL_rtn_vec;\n"); 330 DDBE_spell_param_vec_init( fid, p_operation, BE_client_side, 331 BE_cmd_opt, BE_cmd_val ); 332 fprintf(fid, "IDL_ms.IDL_param_vec = IDL_param_vec;\n"); 333 fprintf(fid, "IDL_ms.IDL_side = IDL_client_side_k;\n"); 334 fprintf(fid, "IDL_ms.IDL_language = "); 335 fprintf(fid, "IDL_lang_c_k"); 336 fprintf(fid, ";\n"); 337 338 if (AST_HAS_FULL_PTRS_SET(p_operation) && 339 (AST_HAS_IN_PTRS_SET(p_operation) || AST_HAS_OUT_PTRS_SET(p_operation))) 340 { 341 fprintf(fid, 342"rpc_ss_init_node_table(&IDL_ms.IDL_node_table,&IDL_ms.IDL_mem_handle);\n"); 343 } 344 345 if (AST_HAS_OUT_PTRS_SET(p_operation) ) 346 { 347 /* The following call is done here to enable PRT testing */ 348 fprintf(fid, "rpc_ss_mts_client_estab_alloc(&IDL_ms);\n"); 349 } 350 351 /* Does operation use I-char machinery? If so, set up needed state */ 352 BE_spell_cs_state(fid, "IDL_ms.", BE_client_side, &cs_info); 353 /* And call the [cs_tag_rtn] if there is one */ 354 BE_spell_cs_tag_rtn_call(fid, "IDL_ms.", p_operation, BE_client_side, 355 &BE_handle_info, &cs_info, false); 356 357/* WEZ:setup the handle here ? */ 358 359 CSPELL_call_start(fid, &BE_handle_info, p_interface, p_operation, op_num, 360 &comm_stat_info, &fault_stat_info); 361 362 if (AST_HAS_IN_CTX_SET(p_operation) 363 || AST_HAS_OUT_CTX_SET(p_operation) 364 || cs_info.cs_machinery) 365 { 366 fprintf(fid, "IDL_ms.IDL_h=(handle_t)%c%s;\n", 367 BE_handle_info.deref_assoc, BE_handle_info.assoc_name); 368 } 369 370 /* Marshall the ins */ 371 DDBE_spell_marsh_or_unmar( fid, p_operation, "rpc_ss_ndr_marsh_interp", 372 "&IDL_ms", BE_client_side, BE_marshalling_k ); 373 374 fprintf(fid,"IDL_ms.IDL_elt_p = &IDL_outs;\n"); 375 fprintf(fid, 376"rpc_call_transceive((rpc_call_handle_t)IDL_ms.IDL_call_h,(rpc_iovector_p_t)&IDL_ms.IDL_iovec,\n"); 377 fprintf(fid, 378" IDL_ms.IDL_elt_p,&IDL_ms.IDL_drep,(unsigned32*)&IDL_ms.IDL_status);\n"); 379 380 /* !!WORKAROUND!! for problem with buff_dealloc for [maybe] operation 381 with CN runtime */ 382 if (AST_MAYBE_SET(p_operation)) 383 fprintf(fid, "IDL_outs.buff_dealloc=NULL;\n"); 384 385 CSPELL_test_transceive_status(fid); 386 387 /* Unmarshall the outs */ 388 DDBE_spell_marsh_or_unmar( fid, p_operation, "rpc_ss_ndr_unmar_interp", 389 "&IDL_ms", BE_client_side, BE_unmarshalling_k ); 390 391 fprintf(fid, "IDL_closedown: __IDL_UNUSED_LABEL__;\n"); 392 393 /* 394 * Catch the error that indicates that st has be set to a failing status 395 * that should be reported, and then do normal cleanup processing. If 396 * for some reason the status is not set, then set it. 397 */ 398 fprintf(fid, "DCETHREAD_CATCH(rpc_x_ss_pipe_comm_error)\n"); 399 if ( BE_handle_info.handle_type == BE_auto_handle_k ) 400 { 401 DDBE_spell_restart_logic( fid, p_operation ); 402 403 /* 404 * This label is used when no valid auto-handle binding can be 405 * found. The call to this is generated in CSPELL_bind_auto_handle 406 * when no valid binding can be found. 407 */ 408 fprintf(fid, "IDL_auto_binding_failure:;\n"); 409 } 410 else { 411 /* 412 * Add the matching ENDTRY for the nested TRY/CATCH block, if 413 * necessary, as decribed above. 414 */ 415#ifdef NO_TRY_CATCH_FINALLY 416 fprintf(fid, "DCETHREAD_ENDTRY\n"); 417#endif 418 } 419 420 /* 421 * Normal cleanup processing to free up resources and end the call and 422 * and report any faults or failing statuses. 423 */ 424 fprintf(fid, "DCETHREAD_FINALLY\n"); 425 fprintf(fid, "rpc_ss_ndr_clean_up(&IDL_ms);\n"); 426 427 /* End the call, but only if we have one to end for auto handle */ 428 if ( BE_handle_info.handle_type == BE_auto_handle_k ) 429 fprintf(fid, "if(IDL_ms.IDL_call_h!=NULL)"); 430 fprintf(fid, 431"rpc_ss_call_end_2(&IDL_ms.IDL_call_h,&IDL_fault_code,&IDL_user_fault_id,&IDL_ms.IDL_status);\n"); 432 CSPELL_binding_free_if_needed( fid, &BE_handle_info ); 433 434 /* Must free user binding after ending the call */ 435 if ((BE_handle_info.handle_type == BE_parm_user_handle_k) 436 || (BE_handle_info.handle_type == BE_impl_user_handle_k)) 437 { 438 /* There is a user handle to unbind. As we are inside an exception 439 handler, we don't want any exception the unbind causes */ 440 fprintf (fid, "DCETHREAD_TRY\n"); 441 fprintf (fid, "%s_unbind(%c%s%s, (handle_t)IDL_assoc_handle);\n", 442 BE_handle_info.type_name, BE_handle_info.deref_generic, 443 BE_handle_info.user_handle_name, 444 ""); 445 fprintf (fid, "DCETHREAD_FINALLY\n"); 446 } 447 448 /* If [represent_as] on handle_t parameter, release the handle_t */ 449 if ((BE_handle_info.handle_type == BE_rep_as_handle_t_k) 450 || (BE_handle_info.handle_type == BE_rep_as_handle_t_p_k)) 451 { 452 fprintf (fid, "DCETHREAD_TRY\n"); 453 fprintf( fid, "%s_free_inst((handle_t *)%s);\n", 454 BE_get_name(BE_handle_info.rep_as_type), 455 assoc_handle_ptr ); 456 fprintf (fid, "DCETHREAD_FINALLY\n"); 457 } 458 459 /* Release memory allocated by stub code */ 460 fprintf(fid, "if (IDL_ms.IDL_mem_handle.memory)\n{\n"); 461 fprintf(fid, " rpc_ss_mem_free(&IDL_ms.IDL_mem_handle);\n}\n"); 462 463 /* Give status information to client, or raise the appropriate exception */ 464 CSPELL_return_status( fid, &comm_stat_info, &fault_stat_info, 465 "IDL_ms.IDL_status", 466 ( (comm_stat_info.type == BE_stat_result_k) 467 || (fault_stat_info.type == BE_stat_result_k) ) 468 ? "IDL_function_result" : (char *)NULL, 469 num_declared_exceptions + num_extern_exceptions, "&IDL_ms" ); 470 471 fprintf(fid, "RPC_SS_THREADS_RESTORE_ASYNC(IDL_async_cancel_state);\n"); 472 if ((BE_handle_info.handle_type == BE_parm_user_handle_k) 473 || (BE_handle_info.handle_type == BE_impl_user_handle_k) 474 || (BE_handle_info.handle_type == BE_rep_as_handle_t_k) 475 || (BE_handle_info.handle_type == BE_rep_as_handle_t_p_k)) 476 { 477 fprintf(fid, "DCETHREAD_ENDTRY\n"); 478 } 479 fprintf(fid, "DCETHREAD_ENDTRY\n"); 480 481 /* Set the return value */ 482 if ( (p_operation->result->type->kind != AST_void_k) 483 ) 484 fprintf(fid, "return IDL_function_result;\n"); 485 fprintf (fid, "}\n"); 486/* WEZ:we could spell out c -> c++ mappings here */ 487} 488 489/******************************************************************************/ 490/* */ 491/* Stub for an operation with [encode] or [decode] attribute */ 492/* */ 493/******************************************************************************/ 494void DDBE_spell_pickling_stub 495( 496 FILE *fid, 497 AST_interface_n_t *p_interface, /* Ptr to AST interface node */ 498 char const *p_interface_name, /* Ptr to name of interface */ 499 AST_operation_n_t *p_operation, /* Ptr to operation node */ 500 boolean use_internal_name /* use internal name if true */ 501) 502{ 503 boolean encode_decode; /* True if operation has [encode] and [decode] */ 504 const char *action_type; 505 BE_stat_info_t comm_stat_info; 506 BE_stat_info_t fault_stat_info; 507 BE_cs_info_t cs_info; /* I-char machinery description */ 508 509 /* What sort of status reporting? */ 510 BE_get_comm_stat_info( p_operation, &comm_stat_info ); 511 BE_get_fault_stat_info( p_operation, &fault_stat_info ); 512 513 BE_setup_client_handle (fid, p_interface, p_operation, &BE_handle_info); 514 encode_decode = (AST_ENCODE_SET(p_operation) 515 && AST_DECODE_SET(p_operation)); 516 517 CSPELL_csr_header(fid, p_interface_name, p_operation, use_internal_name); 518 519 fprintf(fid, "{\n"); 520 /* 521 * Standard local variables 522 */ 523 fprintf(fid, "volatile ndr_ulong_int IDL_fault_code=error_status_ok;\n"); 524 fprintf(fid, "volatile ndr_ulong_int IDL_user_fault_id=0;\n"); 525 fprintf(fid, 526 "volatile RPC_SS_THREADS_CANCEL_STATE_T IDL_async_cancel_state;\n"); 527 fprintf(fid, "IDL_es_state_t *IDL_es_state_p;\n"); 528 fprintf(fid, "volatile IDL_ms_t *IDL_msp;\n"); 529 fprintf(fid, "idl_es_transfer_syntax_t IDL_es_transfer_syntax;\n"); 530 DDBE_spell_param_vec_def( fid, p_operation, BE_client_side, 531 BE_cmd_opt, BE_cmd_val ); 532 533 /* If there is a function result, we need somewhere to put it */ 534 if ( (p_operation->result->type->kind != AST_void_k) 535 ) 536 { 537 CSPELL_typed_name(fid, p_operation->result->type, 538 NAMETABLE_add_id("IDL_function_result"), 539 NULL, false, true, false); 540 fprintf(fid, ";\n"); 541 } 542 543 /* 544 * Does operation use I-char machinery? If so, declare any needed variables 545 */ 546 BE_cs_analyze_and_spell_vars(fid, p_operation, BE_client_side, &cs_info); 547 548 /* 549 * Start of executable code 550 */ 551 fprintf(fid, "RPC_SS_INIT_CLIENT\n"); 552 fprintf(fid, "RPC_SS_THREADS_DISABLE_ASYNC(IDL_async_cancel_state);\n"); 553 fprintf(fid, "IDL_es_state_p = (IDL_es_state_t *)%c%s;\n", 554 BE_handle_info.deref_assoc, BE_handle_info.assoc_name); 555 fprintf(fid, "IDL_msp = (volatile IDL_ms_t *)IDL_es_state_p->IDL_msp;\n"); 556 fprintf(fid, "IDL_msp->IDL_offset_vec = IDL_offset_vec;\n"); 557 fprintf(fid, "IDL_msp->IDL_rtn_vec = IDL_rtn_vec;\n"); 558 fprintf(fid, "DCETHREAD_TRY\n"); 559 DDBE_spell_param_vec_init( fid, p_operation, BE_client_side, 560 BE_cmd_opt, BE_cmd_val ); 561 fprintf(fid, "IDL_msp->IDL_param_vec = IDL_param_vec;\n"); 562 fprintf(fid, "IDL_msp->IDL_side = IDL_client_side_k;\n"); 563 fprintf(fid, "IDL_msp->IDL_language = "); 564 fprintf(fid, "IDL_lang_c_k"); 565 fprintf(fid, ";\n"); 566 567 if (AST_HAS_FULL_PTRS_SET(p_operation) && 568 (AST_HAS_IN_PTRS_SET(p_operation) || AST_HAS_OUT_PTRS_SET(p_operation))) 569 { 570 fprintf(fid, 571"rpc_ss_init_node_table(&IDL_msp->IDL_node_table,&IDL_msp->IDL_mem_handle);\n"); 572 } 573 574 if (AST_HAS_OUT_PTRS_SET(p_operation) ) 575 { 576 fprintf(fid, "rpc_ss_mts_client_estab_alloc(IDL_msp);\n"); 577 } 578 579 /* Does operation use I-char machinery? If so, set up needed state */ 580 BE_spell_cs_state(fid, "IDL_msp->", BE_client_side, &cs_info); 581 if (cs_info.cs_machinery) 582 fprintf(fid, "IDL_msp->IDL_h=NULL;\n"); 583 584 if (encode_decode) 585 action_type = "IDL_both_k"; 586 else if (AST_ENCODE_SET(p_operation)) 587 action_type = "IDL_encoding_k"; 588 else 589 action_type = "IDL_decoding_k"; 590 fprintf(fid, 591"idl_es_before_interp_call(%c%s,(rpc_if_handle_t)&IDL_ifspec,\n", 592 BE_handle_info.deref_assoc, BE_handle_info.assoc_name); 593 fprintf(fid, 594" IDL_type_vec,%d,%s,&IDL_es_transfer_syntax,(IDL_msp_t)IDL_msp);\n", 595 p_operation->op_number, action_type); 596 597 /* If there is I-char machinery, call the [cs_tag_rtn] if there is one */ 598 BE_spell_cs_tag_rtn_call(fid, "IDL_msp->", p_operation, BE_client_side, 599 &BE_handle_info, &cs_info, true); 600 601 if (encode_decode) 602 fprintf(fid, 603 "if (IDL_es_state_p->IDL_action == IDL_encoding_k)\n{\n"); 604 if (AST_ENCODE_SET(p_operation)) 605 DDBE_spell_marsh_or_unmar( fid, p_operation, 606 "rpc_ss_ndr_marsh_interp", 607 "(IDL_msp_t)IDL_msp", 608 BE_client_side, BE_marshalling_k ); 609 if (encode_decode) 610 fprintf(fid, "}\nelse\n{\n"); 611 if (AST_DECODE_SET(p_operation)) 612 DDBE_spell_marsh_or_unmar( fid, p_operation, 613 "rpc_ss_ndr_unmar_interp", 614 "(IDL_msp_t)IDL_msp", 615 BE_client_side, BE_unmarshalling_k ); 616 if (encode_decode) 617 fprintf(fid, "}\n"); 618 fprintf(fid, "idl_es_after_interp_call((IDL_msp_t)IDL_msp);\n"); 619 fprintf(fid, "DCETHREAD_CATCH(rpc_x_ss_pipe_comm_error)\n"); 620 fprintf(fid, "DCETHREAD_FINALLY\n"); 621 622 /* Clean-up code */ 623 fprintf(fid, "idl_es_clean_up((IDL_msp_t)IDL_msp);\n"); 624 625 /* Give status information to client, or raise the appropriate exception */ 626 CSPELL_return_status( fid, &comm_stat_info, &fault_stat_info, 627 "IDL_msp->IDL_status", 628 ( (comm_stat_info.type == BE_stat_result_k) 629 || (fault_stat_info.type == BE_stat_result_k) ) 630 ? "IDL_function_result" : (char *)NULL, 631 0, "(IDL_msp_t)IDL_msp" ); 632 fprintf(fid, "RPC_SS_THREADS_RESTORE_ASYNC(IDL_async_cancel_state);\n"); 633 634 fprintf(fid, "DCETHREAD_ENDTRY\n"); 635 636 /* Set the return value */ 637 if ( (p_operation->result->type->kind != AST_void_k) 638 ) 639 { 640 fprintf(fid, "return IDL_function_result;\n"); 641 } 642 fprintf (fid, "}\n"); 643} 644 645/******************************************************************************/ 646/* */ 647/* Main control flow for generating a client stub */ 648/* */ 649/******************************************************************************/ 650void DDBE_gen_cstub 651( 652 FILE *fid, /* Handle for emitted C text */ 653 AST_interface_n_t *p_interface, /* Ptr to AST interface node */ 654 language_k_t language, /* Language stub is to interface to */ 655 char header_name[], /* Name of header file to be included in stub */ 656 boolean *cmd_opt, 657 void **cmd_val, 658 DDBE_vectors_t *dd_vip /* Data driven BE vector information ptr */ 659) 660{ 661 AST_export_n_t *p_export; 662 AST_operation_n_t *p_operation; 663 char const *p_interface_name; 664 boolean first; 665 /* Exceptions may be declared or external. We need a count of both */ 666 int num_declared_exceptions; 667 int num_extern_exceptions; 668 boolean midl_mode = cmd_opt[opt_midl]; 669 670 the_interface = p_interface; 671 NAMETABLE_id_to_string(p_interface->name, &p_interface_name); 672 673 /* 674 * Emit a #pragma nostandard to suppress warnings on non-standard C usage 675 */ 676 CSPELL_suppress_stub_warnings(fid); 677 678 /* 679 * Emit #defines and #includes 680 */ 681 CSPELL_mts_includes(fid, header_name); 682 683 /* 684 * Emit MIDL-compatible allocator wrappers 685 */ 686 if (midl_mode) 687 { 688 CSPELL_midl_compatibility_allocators(fid); 689 } 690 691 /* 692 * Emit if_spec definition 693 */ 694 CSPELL_interface_def(fid, p_interface, BE_client_stub_k, false); 695 696 /* If necessary, emit statics needed for [auto_handle] */ 697 if ( AST_AUTO_HANDLE_SET(p_interface) || AST_OBJECT_SET(p_interface)) 698 { 699 CSPELL_auto_handle_statics( fid ); 700 } 701 702 /* Declare the Proxy class for ORPC */ 703 if (AST_OBJECT_SET(p_interface)) { 704 BE_gen_orpc_defs(fid, p_interface, proxy_def); 705 } 706 707 /* If there is an implicit handle, declare it */ 708 if (p_interface->implicit_handle_name != NAMETABLE_NIL_ID) 709 { 710 fprintf( fid, "globaldef " ); 711 if ( ! AST_IMPLICIT_HANDLE_G_SET(p_interface) ) 712 { 713 fprintf(fid, "handle_t "); 714 } 715 else 716 { 717 spell_name( fid, p_interface->implicit_handle_type_name); 718 fprintf( fid, " " ); 719 } 720 spell_name( fid, p_interface->implicit_handle_name); 721 fprintf( fid, ";\n" ); 722 } 723 724 /* If there are any user exceptions, emit the necessary declarations */ 725 DDBE_user_exceptions(fid, p_interface, 726 &num_declared_exceptions, &num_extern_exceptions); 727 728 /* 729 * Set up interpreter data structures 730 */ 731 DDBE_spell_offset_vec( fid, dd_vip, cmd_opt, cmd_val ); 732 DDBE_spell_rtn_vec( fid, dd_vip, cmd_opt, cmd_val, TRUE ); 733 DDBE_spell_type_vec( fid, dd_vip, cmd_opt, cmd_val ); 734 735 /* 736 * Emit operation definitions 737 */ 738 for (p_export = p_interface->exports; p_export; p_export = p_export->next) 739 { 740 if (p_export->kind == AST_operation_k) 741 { 742 BE_push_malloc_ctx(); 743 NAMETABLE_set_temp_name_mode(); 744 p_operation = p_export->thing_p.exported_operation; 745 if (!AST_NO_CODE_SET(p_operation)) 746 { 747 if (AST_ENCODE_SET(p_operation) || AST_DECODE_SET(p_operation)) 748 DDBE_spell_pickling_stub(fid, p_interface, 749 p_interface_name, p_operation, cmd_opt[opt_cepv]); 750 else 751 CSPELL_client_stub_routine( 752 fid, p_interface, language, 753 p_operation, p_interface_name, p_operation->op_number, 754 /* cmd_opt[opt_cepv], */ cmd_opt, num_declared_exceptions, 755 num_extern_exceptions); 756 } 757 NAMETABLE_clear_temp_name_mode(); 758 BE_pop_malloc_ctx(); 759 } 760 } 761 762 if (cmd_opt[opt_cepv]) { 763 /* 764 * Emit EPV declarations 765 */ 766 fprintf(fid, "/* global */ %s_v%ld_%ld_epv_t %s_v%ld_%ld_c_epv = {\n", 767 p_interface_name, 768 (p_interface->version%65536), (p_interface->version/65536), 769 p_interface_name, 770 (p_interface->version%65536), (p_interface->version/65536)); 771 772 first = true; 773 774 for (p_export = p_interface->exports; p_export; 775 p_export = p_export->next) 776 if (p_export->kind == AST_operation_k) 777 { 778 if (first) first = false; 779 else fprintf (fid, ",\n"); 780 p_operation = p_export->thing_p.exported_operation; 781 if (!AST_NO_CODE_SET(p_operation)) 782 { 783 fprintf(fid, " op%d_csr", p_operation->op_number); 784 } 785 else fprintf(fid, " NULL"); 786 } 787 fprintf (fid, "\n};\n"); 788 } 789 790 /* 791 * Emit a closing #pragma standard to match the nostandard pragma above 792 */ 793 CSPELL_restore_stub_warnings(fid); 794 795 the_interface = NULL; 796} 797