#include "orbit-c-backend.h" #include #include #include #include typedef struct { FILE *of; IDL_ns ns; IDL_tree tree; } CBEStubInfo; /* Pass either DATA_IN or DATA_OUT, tells you how many parameters (including the return value) will cause data to be sent or received */ static void orbit_cbe_stub_process_piece(CBEStubInfo *ski); static void cbe_stub_do_attr_dcl(CBEStubInfo *sti); static void cbe_stub_do_inherited_attr_dcl(CBEStubInfo *sti, IDL_tree current_interface); static void cbe_stub_do_binop(CBEStubInfo *sti); static void cbe_stub_do_boolean(CBEStubInfo *sti); static void cbe_stub_do_case_stmt(CBEStubInfo *sti); static void cbe_stub_do_char(CBEStubInfo *sti); static void cbe_stub_do_const_dcl(CBEStubInfo *sti); static void cbe_stub_do_except_dcl(CBEStubInfo *sti); static void cbe_stub_do_fixed(CBEStubInfo *sti); static void cbe_stub_do_float(CBEStubInfo *sti); static void cbe_stub_do_forward_dcl(CBEStubInfo *sti); static void cbe_stub_do_gentree(CBEStubInfo *sti); static void cbe_stub_do_ident(CBEStubInfo *sti); static void cbe_stub_do_integer(CBEStubInfo *sti); static void cbe_stub_do_interface(CBEStubInfo *sti); static void cbe_stub_do_list(CBEStubInfo *sti); static void cbe_stub_do_member(CBEStubInfo *sti); static void cbe_stub_do_module(CBEStubInfo *sti); static void cbe_stub_do_none(CBEStubInfo *sti); static void cbe_stub_do_string(CBEStubInfo *sti); static void cbe_stub_do_type_any(CBEStubInfo *sti); static void cbe_stub_do_type_array(CBEStubInfo *sti); static void cbe_stub_do_type_boolean(CBEStubInfo *sti); static void cbe_stub_do_type_char(CBEStubInfo *sti); static void cbe_stub_do_type_dcl(CBEStubInfo *sti); static void cbe_stub_do_type_enum(CBEStubInfo *sti); static void cbe_stub_do_type_fixed(CBEStubInfo *sti); static void cbe_stub_do_type_float(CBEStubInfo *sti); static void cbe_stub_do_type_integer(CBEStubInfo *sti); static void cbe_stub_do_type_object(CBEStubInfo *sti); static void cbe_stub_do_type_octet(CBEStubInfo *sti); static void cbe_stub_do_type_sequence(CBEStubInfo *sti); static void cbe_stub_do_type_string(CBEStubInfo *sti); static void cbe_stub_do_type_struct(CBEStubInfo *sti); static void cbe_stub_do_type_union(CBEStubInfo *sti); static void cbe_stub_do_type_wide_char(CBEStubInfo *sti); static void cbe_stub_do_type_wide_string(CBEStubInfo *sti); static void cbe_stub_do_unaryop(CBEStubInfo *sti); static void cbe_stub_do_wide_char(CBEStubInfo *sti); static void cbe_stub_do_wide_string(CBEStubInfo *sti); static void cbe_stub_do_op_dcl(CBEStubInfo *sti); static void cbe_stub_do_inherited_op_dcl(CBEStubInfo *sti, IDL_tree current_interface); static void cbe_stub_op_params_marshal(CBEStubInfo *sti); static void cbe_stub_op_params_demarshal(CBEStubInfo *sti); static void cbe_stub_op_param_free(FILE *of, IDL_tree node, GString *tmpstr); static void cbe_stub_op_param_alloc(FILE *of, IDL_tree node, GString *tmpstr); static void cbe_stub_op_params_alloc(CBEStubInfo *sti); void orbit_cbe_write_stubs(FILE *outfile, IDL_ns ns, IDL_tree tree, const char *header_filename) { CBEStubInfo sti; sti.of = outfile; sti.ns = ns; sti.tree = tree; fprintf(outfile, "/*\n" " * This file was generated by orbit-idl - DO NOT EDIT!\n" " */\n\n"); fprintf(outfile, "#include \n"); fprintf(outfile, "#include \"%s\"\n\n", header_filename); fprintf(outfile, "#define GET_ATOM(x) G_STMT_START{ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->decoder(&x, (GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur), sizeof(x)); ((guchar *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) += sizeof(x); }G_STMT_END\n"); orbit_cbe_stub_process_piece(&sti); } static void orbit_cbe_stub_process_piece(CBEStubInfo *sti) { g_return_if_fail(sti != NULL); g_return_if_fail(sti->tree != NULL); switch(IDL_NODE_TYPE(sti->tree)) { case IDLN_ATTR_DCL: cbe_stub_do_attr_dcl(sti); break; case IDLN_BINOP: cbe_stub_do_binop(sti); break; case IDLN_BOOLEAN: cbe_stub_do_boolean(sti); break; case IDLN_CASE_STMT: cbe_stub_do_case_stmt(sti); break; case IDLN_CHAR: cbe_stub_do_char(sti); break; case IDLN_CONST_DCL: cbe_stub_do_const_dcl(sti); break; case IDLN_EXCEPT_DCL: cbe_stub_do_except_dcl(sti); break; case IDLN_FIXED: cbe_stub_do_fixed(sti); break; case IDLN_FLOAT: cbe_stub_do_float(sti); break; case IDLN_FORWARD_DCL: cbe_stub_do_forward_dcl(sti); break; case IDLN_GENTREE: cbe_stub_do_gentree(sti); break; case IDLN_IDENT: cbe_stub_do_ident(sti); break; case IDLN_INTEGER: cbe_stub_do_integer(sti); break; case IDLN_INTERFACE: cbe_stub_do_interface(sti); break; case IDLN_LIST: cbe_stub_do_list(sti); break; case IDLN_MEMBER: cbe_stub_do_member(sti); break; case IDLN_MODULE: cbe_stub_do_module(sti); break; case IDLN_NONE: cbe_stub_do_none(sti); break; case IDLN_OP_DCL: cbe_stub_do_op_dcl(sti); break; case IDLN_PARAM_DCL: g_assert(!"Can't do a PARAM outside of an operation!\n"); break; case IDLN_STRING: cbe_stub_do_string(sti); break; case IDLN_TYPE_ANY: cbe_stub_do_type_any(sti); break; case IDLN_TYPE_ARRAY: cbe_stub_do_type_array(sti); break; case IDLN_TYPE_BOOLEAN: cbe_stub_do_type_boolean(sti); break; case IDLN_TYPE_CHAR: cbe_stub_do_type_char(sti); break; case IDLN_TYPE_DCL: cbe_stub_do_type_dcl(sti); break; case IDLN_TYPE_ENUM: cbe_stub_do_type_enum(sti); break; case IDLN_TYPE_FIXED: cbe_stub_do_type_fixed(sti); break; case IDLN_TYPE_FLOAT: cbe_stub_do_type_float(sti); break; case IDLN_TYPE_INTEGER: cbe_stub_do_type_integer(sti); break; case IDLN_TYPE_OBJECT: cbe_stub_do_type_object(sti); break; case IDLN_TYPE_OCTET: cbe_stub_do_type_octet(sti); break; case IDLN_TYPE_SEQUENCE: cbe_stub_do_type_sequence(sti); break; case IDLN_TYPE_STRING: cbe_stub_do_type_string(sti); break; case IDLN_TYPE_STRUCT: cbe_stub_do_type_struct(sti); break; case IDLN_TYPE_UNION: cbe_stub_do_type_union(sti); break; case IDLN_TYPE_WIDE_CHAR: cbe_stub_do_type_wide_char(sti); break; case IDLN_TYPE_WIDE_STRING: cbe_stub_do_type_wide_string(sti); break; case IDLN_UNARYOP: cbe_stub_do_unaryop(sti); break; case IDLN_WIDE_CHAR: cbe_stub_do_wide_char(sti); break; case IDLN_WIDE_STRING: cbe_stub_do_wide_string(sti); break; case IDLN_NATIVE: break; default: g_warning("%s not handled in stubs", IDL_tree_type_names[IDL_NODE_TYPE(sti->tree)]); break; } } static void cbe_stub_do_attr_dcl_internal(CBEStubInfo *sti, IDL_tree current_interface, gboolean inherited) { IDL_tree curop, curitem; GString *attrname = g_string_new(NULL); CBEStubInfo substi = *sti; if(!enable_inherited_ops) return; for(curitem = IDL_ATTR_DCL(sti->tree).simple_declarations; curitem; curitem = IDL_LIST(curitem).next) { /* Fake the attribute get/set methods as operation declarations */ IDL_tree ident, ns_data_save; int i; for (i = 0; i < 2; ++i) { if (i && IDL_ATTR_DCL(sti->tree).f_readonly) break; /* Output the operation on this attribute */ g_string_sprintf(attrname, i ? "_set_%s" : "_get_%s", IDL_IDENT(IDL_LIST(curitem).data).str); ident = IDL_ident_new(g_strdup(attrname->str)); /* Tell the ident where our namespace node is, and request a return value if this is the _get operation */ IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(IDL_LIST(curitem).data); curop = IDL_op_dcl_new(0, i == 0 ? IDL_ATTR_DCL(sti->tree).param_type_spec : NULL, ident, NULL, NULL, NULL); curop->up = sti->tree->up; substi.tree = curop; /* Save the namespace ident (IDL_GENTREE data) reference, assign back to the temporary tree, output the operation, then restore the namespace ident link */ ns_data_save = IDL_GENTREE(IDL_IDENT_TO_NS(IDL_LIST(curitem).data)).data; IDL_GENTREE(IDL_IDENT_TO_NS(IDL_LIST(curitem).data)).data = ident; if (i) { /* The set routine also needs the value, so we temporarily add that to the operation declaration */ IDL_OP_DCL(curop).parameter_dcls = IDL_list_new( IDL_param_dcl_new(IDL_PARAM_IN, IDL_ATTR_DCL(sti->tree).param_type_spec, IDL_ident_new(g_strdup("value")))); } if(inherited==TRUE) cbe_stub_do_inherited_op_dcl(&substi, current_interface); else orbit_cbe_stub_process_piece(&substi); /* Restore the fake link to the original in the namespace */ IDL_GENTREE(IDL_IDENT_TO_NS(IDL_LIST(curitem).data)).data = ns_data_save; if (i) { /* Free only what we've created for the fake node, so remove the attribute node element and then free the rest */ IDL_PARAM_DCL(IDL_LIST( IDL_OP_DCL(curop).parameter_dcls).data).param_type_spec = NULL; } /* Remove what we've "borrowed" from ATTR_DCL from the fake curop node then free the rest */ IDL_OP_DCL(curop).op_type_spec = NULL; IDL_tree_free(curop); } } g_string_free(attrname, TRUE); } static void cbe_stub_do_attr_dcl(CBEStubInfo *sti) { cbe_stub_do_attr_dcl_internal(sti, NULL, FALSE); } static void cbe_stub_do_inherited_attr_dcl(CBEStubInfo *sti, IDL_tree current_interface) { cbe_stub_do_attr_dcl_internal(sti, current_interface, TRUE); } static void cbe_stub_do_binop(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_boolean(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_case_stmt(CBEStubInfo *sti) { /* Nothing to do in stubs (???) */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_char(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_const_dcl(CBEStubInfo *sti) { /* Nothing to do in stubs. */ /* g_assert(!"Not yet implemented"); */ } static void cbe_stub_do_except_dcl(CBEStubInfo *sti) { CBEDemarshalInfo dmi; char *id; GString *tmpstr = g_string_new(NULL); id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_EXCEPT_DCL(sti->tree).ident), "_", 0); fprintf(sti->of, "static void %s_demarshal(GIOPRecvBuffer *_ORBIT_recv_buffer, CORBA_Environment *ev)\n", id); fprintf(sti->of, "{\n"); fprintf(sti->of, " CORBA_exception_set(ev, CORBA_USER_EXCEPTION, TC_%s_struct.repo_id, %s__alloc());\n", id, id); fprintf(sti->of, " if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {\n"); dmi.of = sti->of; dmi.previous_param = NULL; dmi.param = dmi.typespec = sti->tree; dmi.byteswap_version = TRUE; dmi.allocate_memory = TRUE; g_string_sprintf(tmpstr, "(*((%s *)ev->_params))", id); dmi.param_name = tmpstr->str; dmi.orb_name = "GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->connection->orb_data"; cbe_output_demarshaller(&dmi); fprintf(sti->of, " } else {\n"); dmi.previous_param = NULL; dmi.byteswap_version = FALSE; cbe_output_demarshaller(&dmi); fprintf(sti->of, " }\n"); fprintf(sti->of, "}\n"); g_free(id); g_string_free(tmpstr, TRUE); } static void cbe_stub_do_fixed(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_float(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_forward_dcl(CBEStubInfo *sti) { /* Nothing to do in stubs. */ /* g_assert(!"Not yet implemented"); */ } static void cbe_stub_do_gentree(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_ident(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_integer(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_interface_print_inheritance_ops(IDL_tree node, CBEStubInfo *current) { CBEStubInfo substi = *current; IDL_tree curitem; char *id; g_assert(current->tree); g_assert(IDL_NODE_TYPE(node) == IDLN_INTERFACE); if(node == current->tree) { /* We don't inherit from ourself... */ return; } id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(node).ident), "_", 0); fprintf(current->of, "/* From interface %s */\n", id); g_free(id); /* Print the operations defined for this interface, but in current's namespace */ for(curitem = IDL_INTERFACE(node).body; curitem; curitem = IDL_LIST(curitem).next) { substi.tree = IDL_LIST(curitem).data; switch(IDL_NODE_TYPE(IDL_LIST(curitem).data)) { case IDLN_OP_DCL: cbe_stub_do_inherited_op_dcl(&substi, current->tree); break; case IDLN_ATTR_DCL: cbe_stub_do_inherited_attr_dcl(&substi, current->tree); break; default: break; } } } static void cbe_stub_do_interface(CBEStubInfo *sti) { CBEStubInfo substi = *sti; char *id; if(IDL_INTERFACE(sti->tree).body) { substi.tree = IDL_INTERFACE(sti->tree).body; orbit_cbe_stub_process_piece(&substi); } if(enable_inherited_ops && IDL_INTERFACE(sti->tree).inheritance_spec != NULL) { id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(sti->tree).ident), "_", 0); fprintf(sti->of, "/* Begin inherited operations for %s */\n\n", id); substi.tree = IDL_INTERFACE(sti->tree).inheritance_spec; IDL_tree_traverse_parents(substi.tree, (gpointer)cbe_stub_interface_print_inheritance_ops, sti); fprintf(sti->of, "/* End inherited operations for %s */\n\n", id); g_free(id); } } static void cbe_stub_do_list(CBEStubInfo *sti) { IDL_tree curitem; CBEStubInfo substi = *sti; for(curitem = sti->tree; curitem; curitem = IDL_LIST(curitem).next) { substi.tree = IDL_LIST(curitem).data; orbit_cbe_stub_process_piece(&substi); } } static void cbe_stub_do_member(CBEStubInfo *sti) { /* Nothing to do in stubs (?) */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_module(CBEStubInfo *sti) { char *id; id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_MODULE(sti->tree).ident), "_", 1); fprintf(sti->of, "/***************** Begin module %s ***************/\n", id); sti->tree = IDL_MODULE(sti->tree).definition_list; orbit_cbe_stub_process_piece(sti); fprintf(sti->of, "/***************** End module %s ***************/\n", id); g_free(id); } static void cbe_stub_do_none(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_string(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_type_any(CBEStubInfo *sti) { /* Nothing to do in stubs. */ /* g_assert(!"Not yet implemented"); */ } static void cbe_stub_do_type_array(CBEStubInfo *sti) { /* Nothing to do in stubs. */ /* g_assert(!"Not yet implemented"); */ } static void cbe_stub_do_type_boolean(CBEStubInfo *sti) { /* Nothing to do in stubs. */ /* g_assert(!"Not yet implemented"); */ } static void cbe_stub_do_type_char(CBEStubInfo *sti) { /* Nothing to do in stubs. */ /* g_assert(!"Not yet implemented"); */ } static void cbe_stub_do_type_dcl(CBEStubInfo *sti) { /* Nothing to do in stubs. */ /* g_assert(!"Not yet implemented"); */ } static void cbe_stub_do_type_enum(CBEStubInfo *sti) { /* Nothing to do in stubs. */ /* g_assert(!"Not yet implemented"); */ } static void cbe_stub_do_type_fixed(CBEStubInfo *sti) { /* Nothing to do in stubs. */ /* g_assert(!"Not yet implemented"); */ } static void cbe_stub_do_type_float(CBEStubInfo *sti) { /* Nothing to do in stubs. */ /* g_assert(!"Not yet implemented"); */ } static void cbe_stub_do_type_integer(CBEStubInfo *sti) { /* Nothing to do in stubs. */ /* g_assert(!"Not yet implemented"); */ } static void cbe_stub_do_type_object(CBEStubInfo *sti) { /* Nothing to do in stubs. */ /* g_assert(!"Not yet implemented"); */ } static void cbe_stub_do_type_octet(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_type_sequence(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_type_string(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_type_struct(CBEStubInfo *sti) { /* Nothing to do in stubs. */ /* g_assert(!"Not yet implemented"); */ } static void cbe_stub_do_type_union(CBEStubInfo *sti) { /* Nothing to do in stubs. */ /* g_assert(!"Not yet implemented"); */ } static void cbe_stub_do_type_wide_char(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_type_wide_string(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_unaryop(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_wide_char(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } static void cbe_stub_do_wide_string(CBEStubInfo *sti) { /* Nothing to do in stubs. */ g_assert(!"Not yet implemented"); } void cbe_print_var_dcl(FILE *of, IDL_tree tree, gboolean for_skels) { /* variant of print_param_dcl */ IDL_ParamRole r = DATA_IN; IDL_tree ts; int i, n; if(IDL_NODE_TYPE(tree) != IDLN_PARAM_DCL) { orbit_cbe_write_typespec(of, tree); ts = cbe_get_typespec(tree); if(IDL_NODE_TYPE(ts) == IDLN_TYPE_ARRAY) fprintf(of, "_slice*"); n = orbit_cbe_param_numptrs(tree, DATA_RETURN); for(i = 0; i < n; i++) fprintf(of, "*"); fprintf(of, " _ORBIT_retval"); } else { ts = cbe_get_typespec(IDL_PARAM_DCL(tree).param_type_spec); orbit_cbe_write_typespec(of, IDL_PARAM_DCL(tree).param_type_spec); r = cbe_attr_to_paramrole(IDL_PARAM_DCL(tree).attr); if((IDL_NODE_TYPE(ts) == IDLN_TYPE_ARRAY) && (r == DATA_OUT) && !cbe_type_is_fixed_length(ts)) fprintf(of, "_slice*"); n = orbit_cbe_param_numptrs(IDL_PARAM_DCL(tree).param_type_spec, r); for(i = 0; i < (n - for_skels); i++) { fprintf(of, "*"); } fprintf(of, " %s", IDL_IDENT(IDL_PARAM_DCL(tree).simple_declarator).str); if((n - for_skels) <= 0) switch(IDL_NODE_TYPE(ts)) { case IDLN_TYPE_ANY: fprintf(of, "= {NULL, NULL, CORBA_FALSE}"); break; case IDLN_TYPE_SEQUENCE: fprintf(of, "= {0, 0, NULL, CORBA_FALSE}"); break; default: break; } } } void cbe_print_param_dcl(FILE *of, IDL_tree tree) { IDL_ParamRole r = DATA_IN; if(IDL_NODE_TYPE(tree) != IDLN_PARAM_DCL) { orbit_cbe_write_typespec(of, tree); orbit_cbe_param_printptrs(of, tree, DATA_RETURN); fprintf(of, " _ORBIT_retval"); } else { if(IDL_PARAM_DCL(tree).attr == IDL_PARAM_IN) fprintf(of, "const "); orbit_cbe_write_typespec(of, IDL_PARAM_DCL(tree).param_type_spec); r = cbe_attr_to_paramrole(IDL_PARAM_DCL(tree).attr); orbit_cbe_param_printptrs(of, IDL_PARAM_DCL(tree).param_type_spec, r); fprintf(of, " %s", IDL_IDENT(IDL_PARAM_DCL(tree).simple_declarator).str); } } static void cbe_stub_do_op_dcl_shared(CBEStubInfo *sti) { /* XXX we don't handle contexts here yet - fix that */ IDL_tree curitem; CBEStubInfo substi; GString *tmpstr = g_string_new(NULL); char *id; for(curitem = IDL_OP_DCL(sti->tree).parameter_dcls; curitem; curitem = IDL_LIST(curitem).next) { cbe_print_param_dcl(sti->of, IDL_LIST(curitem).data); fprintf(sti->of, ",\n"); } fprintf(sti->of, "CORBA_Environment *ev)\n{\n"); /* output local variables */ fprintf(sti->of, "GIOP_unsigned_long _ORBIT_request_id;\n"); fprintf(sti->of, "GIOPSendBuffer *_ORBIT_send_buffer;\n"); if(!IDL_OP_DCL(sti->tree).f_oneway) fprintf(sti->of, "GIOPRecvBuffer *_ORBIT_recv_buffer;\n"); fprintf(sti->of, "static const struct { CORBA_unsigned_long len; char opname[%d]; } _ORBIT_operation_name_data = { %d, \"%s\" };\n", strlen(IDL_IDENT(IDL_OP_DCL(sti->tree).ident).str) + 1, strlen(IDL_IDENT(IDL_OP_DCL(sti->tree).ident).str) + 1, IDL_IDENT(IDL_OP_DCL(sti->tree).ident).str); fprintf(sti->of, "static const struct iovec _ORBIT_operation_vec = {(gpointer)&_ORBIT_operation_name_data, %d};\n", sizeof(CORBA_unsigned_long) + strlen(IDL_IDENT(IDL_OP_DCL(sti->tree).ident).str) + 1); if(IDL_OP_DCL(sti->tree).raises_expr) { fprintf(sti->of, "static const ORBit_exception_demarshal_info _ORBIT_user_exceptions[] = { "); for(curitem = IDL_OP_DCL(sti->tree).raises_expr; curitem; curitem = IDL_LIST(curitem).next) { IDL_tree curnode = IDL_LIST(curitem).data; id = orbit_cbe_get_typename(curnode); fprintf(sti->of, "{(const CORBA_TypeCode)&TC_%s_struct, (gpointer)%s_demarshal},", id, id); g_free(id); } fprintf(sti->of, "{CORBA_OBJECT_NIL, NULL}};\n"); } if(IDL_OP_DCL(sti->tree).op_type_spec) { cbe_print_var_dcl(sti->of, IDL_OP_DCL(sti->tree).op_type_spec, FALSE); fprintf(sti->of, ";\n"); } fprintf(sti->of, "GIOPConnection *_cnx;\n"); fprintf(sti->of, "\n\n"); /* Check if we can do a direct call, and if so, do it */ curitem = IDL_get_parent_node(sti->tree, IDLN_INTERFACE, 0); g_assert(curitem); id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(curitem).ident), "_", 0); fprintf(sti->of, "if(_obj->servant && _obj->vepv && %s__classid)\n{\n", id); fprintf(sti->of, "%s((POA_%s__epv *)_obj->vepv[%s__classid])->%s(_obj->servant, ", IDL_OP_DCL(sti->tree).op_type_spec?"return ":"", id, id, IDL_IDENT(IDL_OP_DCL(sti->tree).ident).str); g_free(id); for(curitem = IDL_OP_DCL(sti->tree).parameter_dcls; curitem; curitem = IDL_LIST(curitem).next) { fprintf(sti->of, "%s, ", IDL_IDENT(IDL_PARAM_DCL(IDL_LIST(curitem).data).simple_declarator).str); } fprintf(sti->of, "ev);\n"); fprintf(sti->of, "%s\n}\n", IDL_OP_DCL(sti->tree).op_type_spec?"":"return;"); /* set things up */ fprintf(sti->of, "_cnx = ORBit_object_get_connection(_obj);\n"); fprintf(sti->of, "retry_request:\n"); fprintf(sti->of, "_ORBIT_request_id = giop_get_request_id();\n"); fprintf(sti->of, "if((_cnx == NULL) || (_obj->active_profile == NULL)) {\n"); fprintf(sti->of, "CORBA_exception_set_system(ev, ex_CORBA_COMM_FAILURE, CORBA_COMPLETED_NO);\nreturn%s;\n}\n", IDL_OP_DCL(sti->tree).op_type_spec?" _ORBIT_retval":""); fprintf(sti->of, "_ORBIT_send_buffer = \n"); fprintf(sti->of, "giop_send_request_buffer_use(_cnx, NULL,\n"); fprintf(sti->of, " _ORBIT_request_id, %s, &(_obj->active_profile->object_key_vec),\n", IDL_OP_DCL(sti->tree).f_oneway?"CORBA_FALSE":"CORBA_TRUE"); fprintf(sti->of, " &_ORBIT_operation_vec, &ORBit_default_principal_iovec);\n\n"); fprintf(sti->of, "if(!_ORBIT_send_buffer) {\n"); fprintf(sti->of, "CORBA_exception_set_system(ev, ex_CORBA_COMM_FAILURE, CORBA_COMPLETED_NO);\nreturn%s;\n}\n", IDL_OP_DCL(sti->tree).op_type_spec?" _ORBIT_retval":""); /* marshal all parameters */ substi = *sti; cbe_stub_op_params_marshal(&substi); fprintf(sti->of, "giop_send_buffer_write(_ORBIT_send_buffer);\n"); /* NOTE: I've put the "unuse" before the reply receive because I figured that this data structure shuffling is best done while the network is sending the data and the remote end is processing the request. If I'm wrong, please move it elsewhere */ fprintf(sti->of, "giop_send_buffer_unuse(_ORBIT_send_buffer);\n"); if(!IDL_OP_DCL(sti->tree).f_oneway) { fprintf(sti->of, "_ORBIT_recv_buffer = giop_recv_reply_buffer_use_2(ORBit_object_get_connection(_obj), _ORBIT_request_id, TRUE);\n"); fprintf(sti->of, "if(_ORBIT_recv_buffer == NULL || _ORBIT_recv_buffer->message_buffer.message_header.message_type != GIOP_REPLY) {\n"); fprintf(sti->of, "CORBA_exception_set_system(ev, ex_CORBA_COMM_FAILURE, CORBA_COMPLETED_MAYBE);\n if(_ORBIT_recv_buffer) giop_recv_buffer_unuse(_ORBIT_recv_buffer);\n"); fprintf(sti->of, "return%s;\n }\n", IDL_OP_DCL(sti->tree).op_type_spec?" _ORBIT_retval":""); fprintf(sti->of, "if(_ORBIT_recv_buffer->message.u.reply.reply_status != GIOP_NO_EXCEPTION) {\n"); /* deal with LOCATION_FORWARD exceptions */ fprintf(sti->of, "if(_ORBIT_recv_buffer->message.u.reply.reply_status == GIOP_LOCATION_FORWARD) {\n"); fprintf(sti->of, "if(_obj->forward_locations != NULL)\n"); fprintf(sti->of, "ORBit_delete_profiles(_obj->forward_locations);\n"); fprintf(sti->of, "_obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);\n"); fprintf(sti->of, "_cnx = ORBit_object_get_forwarded_connection(_obj);\n"); fprintf(sti->of, "giop_recv_buffer_unuse(_ORBIT_recv_buffer);\n"); fprintf(sti->of, "\ngoto retry_request;\n"); fprintf(sti->of, "} else {\n"); /* This should also pass a structure that lists info about the operation-specific exceptions raised. */ fprintf(sti->of, "ORBit_handle_exception(_ORBIT_recv_buffer, ev, %s,_obj->orb);\n", IDL_OP_DCL(sti->tree).raises_expr?"_ORBIT_user_exceptions":"NULL"); fprintf(sti->of, "giop_recv_buffer_unuse(_ORBIT_recv_buffer);\n"); fprintf(sti->of, "return%s;\n }\n", IDL_OP_DCL(sti->tree).op_type_spec?" _ORBIT_retval":""); fprintf(sti->of, "}\n"); substi = *sti; if(cbe_op_dcl_nparams(sti->tree, DATA_INOUT|DATA_OUT|DATA_RETURN) > 0) { cbe_stub_op_params_alloc(&substi); cbe_stub_op_params_demarshal(&substi); } fprintf(sti->of, " giop_recv_buffer_unuse(_ORBIT_recv_buffer);\n"); fprintf(sti->of, " ev->_major = CORBA_NO_EXCEPTION;\n"); if(IDL_OP_DCL(sti->tree).op_type_spec) { fprintf(sti->of, " return _ORBIT_retval;\n"); } } fprintf(sti->of, "}\n\n"); g_string_free(tmpstr, TRUE); } static void cbe_stub_do_op_dcl(CBEStubInfo *sti) { char *id, *id2; IDL_tree curitem; int level; id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(sti->tree).ident), "_", 0); if(IDL_OP_DCL(sti->tree).op_type_spec && IDL_OP_DCL(sti->tree).f_oneway) { g_error("[%s] You cannot have a return value from a oneway operation!", id); } orbit_cbe_write_typespec(sti->of, IDL_OP_DCL(sti->tree).op_type_spec); orbit_cbe_param_printptrs(sti->of, IDL_OP_DCL(sti->tree).op_type_spec, DATA_RETURN); curitem = IDL_get_parent_node(sti->tree, IDLN_INTERFACE, &level); g_assert(curitem); id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(curitem).ident), "_", 0); fprintf(sti->of, "\n%s(%s _obj,\n", id, id2); g_free(id); g_free(id2); cbe_stub_do_op_dcl_shared(sti); } /* FIXME This function should check for redefined inherited ops, it doesn't currently - RHP */ static void cbe_stub_do_inherited_op_dcl(CBEStubInfo *sti, IDL_tree current_interface) { char *id; IDL_tree ident; id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(current_interface).ident), "_", 0); ident = IDL_OP_DCL(sti->tree).ident; g_assert(ident); if(IDL_OP_DCL(sti->tree).op_type_spec && IDL_OP_DCL(sti->tree).f_oneway) { g_error("[%s_%s] You cannot have a return value from a oneway operation!", id, IDL_IDENT(ident).str); } orbit_cbe_write_typespec(sti->of, IDL_OP_DCL(sti->tree).op_type_spec); orbit_cbe_param_printptrs(sti->of, IDL_OP_DCL(sti->tree).op_type_spec, DATA_RETURN); fprintf(sti->of, "\n%s_%s(%s _obj,\n", id, IDL_IDENT(ident).str, id); g_free(id); cbe_stub_do_op_dcl_shared(sti); } static void cbe_stub_op_params_marshal(CBEStubInfo *sti) { IDL_tree curitem; int n, i; GString *tmpstr = g_string_new(NULL); CBEMarshalInfo mi = {NULL, NULL, NULL, NULL, NULL, FALSE}; mi.of = sti->of; for(curitem = IDL_OP_DCL(sti->tree).parameter_dcls; curitem; curitem = IDL_LIST(curitem).next) { if(IDL_PARAM_DCL(IDL_LIST(curitem).data).attr == IDL_PARAM_IN || IDL_PARAM_DCL(IDL_LIST(curitem).data).attr == IDL_PARAM_INOUT) { /* mi.previous_param = mi.param; */ /* This gets set by the marshallers themselves */ mi.param = IDL_LIST(curitem).data; if(IDL_PARAM_DCL(mi.param).attr == IDL_PARAM_INOUT) n = orbit_cbe_param_numptrs(mi.param, DATA_INOUT); else n = orbit_cbe_param_numptrs(mi.param, DATA_IN); g_string_assign(tmpstr, ""); for(i = 0; i < n; i++) g_string_append_c(tmpstr, '*'); g_string_sprintfa(tmpstr, "%s", IDL_IDENT(IDL_PARAM_DCL(mi.param).simple_declarator).str); mi.param_name = tmpstr->str; fprintf(sti->of, "\n\n /* marshal parameter %s */\n", mi.param_name); cbe_output_marshaller(&mi); } } fprintf(sti->of, "\n"); g_string_free(tmpstr, TRUE); } static void cbe_stub_op_retval_alloc(FILE *of, IDL_tree node, GString *tmpstr) { int n; char *id; IDL_tree ts = cbe_get_typespec(node); n = orbit_cbe_param_numptrs(node, DATA_RETURN); if((n <= 0) && (IDL_NODE_TYPE(ts) != IDLN_TYPE_ARRAY)) return; #if 0 g_string_assign(tmpstr, ""); for(i = 0; i < n - 1; i++) g_string_append_c(tmpstr, '*'); #endif g_string_assign(tmpstr, "_ORBIT_retval"); switch(IDL_NODE_TYPE(ts)) { case IDLN_TYPE_UNION: case IDLN_TYPE_STRUCT: if(cbe_type_is_fixed_length(ts)) return; case IDLN_TYPE_ANY: case IDLN_TYPE_SEQUENCE: case IDLN_TYPE_ARRAY: break; default: return; } id = orbit_cbe_get_typename(node); fprintf(of, "%s = %s__alloc();\n", tmpstr->str, id); g_free(id); } static void cbe_stub_op_param_alloc(FILE *of, IDL_tree node, GString *tmpstr) { int n, i; char *id; IDL_tree ts = cbe_get_typespec(node); n = orbit_cbe_param_numptrs(node, cbe_attr_to_paramrole(IDL_PARAM_DCL(node).attr)); if(((n - 1) <= 0) && IDL_NODE_TYPE(ts) != IDLN_TYPE_ARRAY) return; switch(IDL_NODE_TYPE(ts)) { case IDLN_TYPE_ARRAY: if((IDL_PARAM_DCL(node).attr != IDL_PARAM_OUT) || cbe_type_is_fixed_length(ts)) return; n++; break; case IDLN_TYPE_SEQUENCE: case IDLN_TYPE_ANY: if(IDL_PARAM_DCL(node).attr == IDL_PARAM_INOUT) return; break; case IDLN_TYPE_UNION: case IDLN_TYPE_STRUCT: if(cbe_type_is_fixed_length(ts)) return; default: break; } g_string_assign(tmpstr, ""); for(i = 0; i < n - 1; i++) g_string_append_c(tmpstr, '*'); g_string_sprintfa(tmpstr, "%s", IDL_IDENT(IDL_PARAM_DCL(node).simple_declarator).str); id = orbit_cbe_get_typename(IDL_PARAM_DCL(node).param_type_spec); fprintf(of, "%s = %s__alloc();\n", tmpstr->str, id); g_free(id); } static void cbe_stub_op_param_free(FILE *of, IDL_tree node, GString *tmpstr) { int n, i; IDL_tree ts; char *id; ts = cbe_get_typespec(IDL_PARAM_DCL(node).param_type_spec); n = orbit_cbe_param_numptrs(node, DATA_INOUT); g_string_assign(tmpstr, ""); if(IDL_NODE_TYPE(ts) == IDLN_TYPE_STRUCT || IDL_NODE_TYPE(ts) == IDLN_TYPE_UNION) n--; for(i = 0; i < n; i++) g_string_append_c(tmpstr, '*'); g_string_sprintfa(tmpstr, "%s", IDL_IDENT(IDL_PARAM_DCL(node).simple_declarator).str); switch(IDL_NODE_TYPE(ts)) { case IDLN_TYPE_ANY: fprintf(of, "if((%s)._release) CORBA_free((%s)._value);\n", tmpstr->str, tmpstr->str); fprintf(of, "CORBA_Object_release((%s)._type, ev);\n", tmpstr->str); break; case IDLN_TYPE_SEQUENCE: fprintf(of, "if((%s)._release) CORBA_free((%s)._buffer);\n", tmpstr->str, tmpstr->str); break; case IDLN_TYPE_STRUCT: case IDLN_TYPE_UNION: case IDLN_TYPE_ARRAY: if(cbe_type_is_fixed_length(ts)) break; id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_TYPE_STRUCT(ts).ident), "_", 0); fprintf(of, "%s__free(%s, NULL, CORBA_TRUE);\n", id, tmpstr->str); g_free(id); break; case IDLN_TYPE_STRING: fprintf(of, "CORBA_free(%s);\n", tmpstr->str + 1); default: break; } } static void cbe_stub_op_params_alloc(CBEStubInfo *sti) { IDL_tree curitem, param; GString *tmpstr = g_string_new(NULL); if(IDL_OP_DCL(sti->tree).op_type_spec) cbe_stub_op_retval_alloc(sti->of, IDL_OP_DCL(sti->tree).op_type_spec, tmpstr); for(curitem = IDL_OP_DCL(sti->tree).parameter_dcls; curitem; curitem = IDL_LIST(curitem).next) { param = IDL_LIST(curitem).data; if(IDL_PARAM_DCL(param).attr == IDL_PARAM_INOUT || IDL_PARAM_DCL(param).attr == IDL_PARAM_OUT) { if(IDL_PARAM_DCL(param).attr == IDL_PARAM_INOUT) cbe_stub_op_param_free(sti->of, param, tmpstr); cbe_stub_op_param_alloc(sti->of, param, tmpstr); } } g_string_free(tmpstr, TRUE); } static void cbe_stub_op_params_demarshal(CBEStubInfo *sti) { CBEDemarshalInfo dmi = {NULL, NULL, NULL, NULL, NULL, TRUE, TRUE, "(_obj->orb)"}; IDL_tree curitem; int n, i; GString *tmpstr = g_string_new(NULL); dmi.of = sti->of; dmi.param = NULL; fprintf(sti->of, "if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {\n"); do { /* This do loop is here basically so we generate two different versions of the same code - the "byteswapping needed" and "no byteswapping needed" versions */ dmi.previous_param = NULL; if(IDL_OP_DCL(sti->tree).op_type_spec) { fprintf(sti->of, "/* demarshal return value */\n"); dmi.param = IDL_OP_DCL(sti->tree).op_type_spec; n = orbit_cbe_param_numptrs(dmi.param, DATA_RETURN); g_string_assign(tmpstr, ""); for(i = 0; i < n; i++) g_string_append_c(tmpstr, '*'); g_string_append(tmpstr, "_ORBIT_retval"); dmi.param_name = tmpstr->str; cbe_output_demarshaller(&dmi); } for(curitem = IDL_OP_DCL(sti->tree).parameter_dcls; curitem; curitem = IDL_LIST(curitem).next) { if(IDL_PARAM_DCL(IDL_LIST(curitem).data).attr == IDL_PARAM_OUT || IDL_PARAM_DCL(IDL_LIST(curitem).data).attr == IDL_PARAM_INOUT) { dmi.param = IDL_LIST(curitem).data; if(IDL_PARAM_DCL(IDL_LIST(curitem).data).attr == IDL_PARAM_OUT) n = orbit_cbe_param_numptrs(dmi.param, DATA_OUT); else n = orbit_cbe_param_numptrs(dmi.param, DATA_INOUT); /* Clarify */ g_string_assign(tmpstr, ""); for(i = 0; i < n; i++) g_string_append_c(tmpstr, '*'); g_string_append(tmpstr, IDL_IDENT(IDL_PARAM_DCL(dmi.param).simple_declarator).str); dmi.param_name = tmpstr->str; fprintf(sti->of, "/* demarshal parameter %s */\n", dmi.param_name); cbe_output_demarshaller(&dmi); } } if(dmi.byteswap_version) fprintf(sti->of, " } else {\n"); } while(dmi.byteswap_version-- > 0); fprintf(sti->of, " }\n\n"); g_string_free(tmpstr, TRUE); } int cbe_op_dcl_nparams(IDL_tree op, IDL_ParamRole role) { IDL_tree curitem; int retval; for(retval = 0, curitem = IDL_OP_DCL(op).parameter_dcls; curitem; curitem = IDL_LIST(curitem).next) { switch(IDL_PARAM_DCL(IDL_LIST(curitem).data).attr) { case IDL_PARAM_IN: if(role & DATA_IN) retval++; break; case IDL_PARAM_OUT: if(role & DATA_OUT) retval++; break; case IDL_PARAM_INOUT: if(role & DATA_INOUT) retval++; break; } } if((role & DATA_RETURN) && IDL_OP_DCL(op).op_type_spec) retval++; return retval; }