#include "orbit-c-backend.h" #include #include #include #include typedef struct { FILE *of; IDL_ns ns; IDL_tree tree; char *free_internal; } CBESkelInfo; typedef struct { char *iface_id; char *opname; IDL_tree op; } CBESkelOpInfo; typedef struct { CBESkelInfo *ski; GSList *oplist; gint curlevel; } CBESkelInterfaceTraverseInfo; static void orbit_cbe_skel_process_piece(CBESkelInfo *ski); static void cbe_skel_do_attr_dcl(CBESkelInfo *ski); static void cbe_skel_do_inherited_attr_dcl(CBESkelInfo *ski, IDL_tree current_interface); static void cbe_skel_do_binop(CBESkelInfo *ski); static void cbe_skel_do_boolean(CBESkelInfo *ski); static void cbe_skel_do_case_stmt(CBESkelInfo *ski); static void cbe_skel_do_char(CBESkelInfo *ski); static void cbe_skel_do_const_dcl(CBESkelInfo *ski); static void cbe_skel_do_except_dcl(CBESkelInfo *ski); static void cbe_skel_do_fixed(CBESkelInfo *ski); static void cbe_skel_do_float(CBESkelInfo *ski); static void cbe_skel_do_forward_dcl(CBESkelInfo *ski); static void cbe_skel_do_gentree(CBESkelInfo *ski); static void cbe_skel_do_ident(CBESkelInfo *ski); static void cbe_skel_do_integer(CBESkelInfo *ski); static void cbe_skel_do_interface(CBESkelInfo *ski); static void cbe_skel_do_list(CBESkelInfo *ski); static void cbe_skel_do_member(CBESkelInfo *ski); static void cbe_skel_do_module(CBESkelInfo *ski); static void cbe_skel_do_none(CBESkelInfo *ski); static void cbe_skel_do_op_dcl(CBESkelInfo *ski); static void cbe_skel_do_inherited_op_dcl(CBESkelInfo *ski, IDL_tree current_interface); static void cbe_skel_op_params_marshal(CBESkelInfo *ski); static void cbe_skel_op_params_demarshal(CBESkelInfo *ski); static void cbe_skel_op_params_free(CBESkelInfo *ski); static void cbe_skel_do_param_dcl(CBESkelInfo *ski); static void cbe_skel_do_string(CBESkelInfo *ski); static void cbe_skel_do_type_any(CBESkelInfo *ski); static void cbe_skel_do_type_array(CBESkelInfo *ski); static void cbe_skel_do_type_boolean(CBESkelInfo *ski); static void cbe_skel_do_type_char(CBESkelInfo *ski); static void cbe_skel_do_type_dcl(CBESkelInfo *ski); static void cbe_skel_do_type_enum(CBESkelInfo *ski); static void cbe_skel_do_type_fixed(CBESkelInfo *ski); static void cbe_skel_do_type_float(CBESkelInfo *ski); static void cbe_skel_do_type_integer(CBESkelInfo *ski); static void cbe_skel_do_type_object(CBESkelInfo *ski); static void cbe_skel_do_type_octet(CBESkelInfo *ski); static void cbe_skel_do_type_sequence(CBESkelInfo *ski); static void cbe_skel_do_type_string(CBESkelInfo *ski); static void cbe_skel_do_type_struct(CBESkelInfo *ski); static void cbe_skel_do_type_union(CBESkelInfo *ski); static void cbe_skel_do_type_wide_char(CBESkelInfo *ski); static void cbe_skel_do_type_wide_string(CBESkelInfo *ski); static void cbe_skel_do_unaryop(CBESkelInfo *ski); static void cbe_skel_do_wide_char(CBESkelInfo *ski); static void cbe_skel_do_wide_string(CBESkelInfo *ski); void orbit_cbe_write_skeletons(FILE *outfile, IDL_ns ns, IDL_tree tree, const char *header_filename) { CBESkelInfo ski; ski.of = outfile; ski.ns = ns; ski.tree = tree; ski.free_internal = "CORBA_TRUE"; 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", 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\n"); orbit_cbe_skel_process_piece(&ski); } static void orbit_cbe_skel_process_piece(CBESkelInfo *ski) { switch(IDL_NODE_TYPE(ski->tree)) { case IDLN_ATTR_DCL: cbe_skel_do_attr_dcl(ski); break; case IDLN_BINOP: cbe_skel_do_binop(ski); break; case IDLN_BOOLEAN: cbe_skel_do_boolean(ski); break; case IDLN_CASE_STMT: cbe_skel_do_case_stmt(ski); break; case IDLN_CHAR: cbe_skel_do_char(ski); break; case IDLN_CONST_DCL: cbe_skel_do_const_dcl(ski); break; case IDLN_EXCEPT_DCL: cbe_skel_do_except_dcl(ski); break; case IDLN_FIXED: cbe_skel_do_fixed(ski); break; case IDLN_FLOAT: cbe_skel_do_float(ski); break; case IDLN_FORWARD_DCL: cbe_skel_do_forward_dcl(ski); break; case IDLN_GENTREE: cbe_skel_do_gentree(ski); break; case IDLN_IDENT: cbe_skel_do_ident(ski); break; case IDLN_INTEGER: cbe_skel_do_integer(ski); break; case IDLN_INTERFACE: cbe_skel_do_interface(ski); break; case IDLN_LIST: cbe_skel_do_list(ski); break; case IDLN_MEMBER: cbe_skel_do_member(ski); break; case IDLN_MODULE: cbe_skel_do_module(ski); break; case IDLN_NONE: cbe_skel_do_none(ski); break; case IDLN_OP_DCL: cbe_skel_do_op_dcl(ski); break; case IDLN_PARAM_DCL: cbe_skel_do_param_dcl(ski); break; case IDLN_STRING: cbe_skel_do_string(ski); break; case IDLN_TYPE_ANY: cbe_skel_do_type_any(ski); break; case IDLN_TYPE_ARRAY: cbe_skel_do_type_array(ski); break; case IDLN_TYPE_BOOLEAN: cbe_skel_do_type_boolean(ski); break; case IDLN_TYPE_CHAR: cbe_skel_do_type_char(ski); break; case IDLN_TYPE_DCL: cbe_skel_do_type_dcl(ski); break; case IDLN_TYPE_ENUM: cbe_skel_do_type_enum(ski); break; case IDLN_TYPE_FIXED: cbe_skel_do_type_fixed(ski); break; case IDLN_TYPE_FLOAT: cbe_skel_do_type_float(ski); break; case IDLN_TYPE_INTEGER: cbe_skel_do_type_integer(ski); break; case IDLN_TYPE_OBJECT: cbe_skel_do_type_object(ski); break; case IDLN_TYPE_OCTET: cbe_skel_do_type_octet(ski); break; case IDLN_TYPE_SEQUENCE: cbe_skel_do_type_sequence(ski); break; case IDLN_TYPE_STRING: cbe_skel_do_type_string(ski); break; case IDLN_TYPE_STRUCT: cbe_skel_do_type_struct(ski); break; case IDLN_TYPE_UNION: cbe_skel_do_type_union(ski); break; case IDLN_TYPE_WIDE_CHAR: cbe_skel_do_type_wide_char(ski); break; case IDLN_TYPE_WIDE_STRING: cbe_skel_do_type_wide_string(ski); break; case IDLN_UNARYOP: cbe_skel_do_unaryop(ski); break; case IDLN_WIDE_CHAR: cbe_skel_do_wide_char(ski); break; case IDLN_WIDE_STRING: cbe_skel_do_wide_string(ski); break; case IDLN_ANY: g_error("IDLN_ANY not handled"); break; case IDLN_NATIVE: break; default: g_warning("Unhandled node type %s", IDL_tree_type_names[IDL_NODE_TYPE(ski->tree)]); } } static void cbe_skel_do_attr_dcl_internal(CBESkelInfo *ski, IDL_tree current_interface, gboolean inherited) { IDL_tree curop, curitem; GString *attrname = g_string_new(NULL); CBESkelInfo subski = *ski; for(curitem = IDL_ATTR_DCL(ski->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(ski->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(ski->tree).param_type_spec : NULL, ident, NULL, NULL, NULL); curop->up = ski->tree->up; subski.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(ski->tree).param_type_spec, IDL_ident_new(g_strdup("value")))); } if(inherited==TRUE) cbe_skel_do_inherited_op_dcl(&subski, current_interface); else orbit_cbe_skel_process_piece(&subski); /* 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_skel_do_attr_dcl(CBESkelInfo *ski) { cbe_skel_do_attr_dcl_internal(ski, NULL, FALSE); } #if 0 static void cbe_skel_do_inherited_attr_dcl(CBESkelInfo *ski, IDL_tree current_interface) { cbe_skel_do_attr_dcl_internal(ski, current_interface, TRUE); } #endif static void cbe_skel_do_binop(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_boolean(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_case_stmt(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_char(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_const_dcl(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_except_dcl(CBESkelInfo *ski) { /* Generate a marshaller routine */ CBEMarshalInfo mi; char *id; GString *tmpstr = g_string_new(NULL); id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_EXCEPT_DCL(ski->tree).ident), "_", 0); fprintf(ski->of, "static void %s_marshal(GIOPSendBuffer *_ORBIT_send_buffer, CORBA_Environment *ev)\n", id); fprintf(ski->of, "{\n"); mi.of = ski->of; mi.previous_param = NULL; mi.param = mi.typespec = ski->tree; mi.require_indirect = FALSE; g_string_sprintf(tmpstr, "(*((%s *)ev->_params))", id); mi.param_name = tmpstr->str; cbe_output_marshaller(&mi); fprintf(ski->of, "}\n"); g_free(id); g_string_free(tmpstr, TRUE); cbe_skel_do_type_struct(ski); } static void cbe_skel_do_fixed(CBESkelInfo *ski) { /* g_assert(!"Not yet implemented"); */ } static void cbe_skel_do_float(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_forward_dcl(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_gentree(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_ident(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_integer(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } void cbe_skel_print_skelptr(FILE *of, IDL_tree tree) { char *id = NULL; IDL_tree curitem; switch(IDL_NODE_TYPE(tree)) { case IDLN_OP_DCL: id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(tree).ident), "_", 0); fprintf(of, " skel_%s,\n", id); break; case IDLN_ATTR_DCL: id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(IDL_get_parent_node(tree, IDLN_INTERFACE, NULL)).ident), "_", 0); for(curitem = IDL_ATTR_DCL(tree).simple_declarations; curitem; curitem = IDL_LIST(curitem).data) { fprintf(of, " skel_%s__get_%s,\n", id, IDL_IDENT(IDL_LIST(curitem).data).str); if(!IDL_ATTR_DCL(tree).f_readonly) fprintf(of, " skel_%s__set_%s,\n", id, IDL_IDENT(IDL_LIST(curitem).data).str); } break; default: break; } g_free(id); } static gint cbe_skel_compare_op_dcls(CBESkelOpInfo *op1, CBESkelOpInfo *op2) { return strcmp(op1->opname, op2->opname); } static void cbe_skel_free_op_info(CBESkelOpInfo *op) { g_free(op->opname); g_free(op->iface_id); g_free(op); } static void cbe_skel_interface_add_relayer(IDL_tree intf, CBESkelInterfaceTraverseInfo *iti) { CBESkelOpInfo *newopi; IDL_tree curitem, curdcl, curattr, curattrdcl; char *iface_id; iface_id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(intf).ident), "_", 0); for(curitem = IDL_INTERFACE(intf).body; curitem; curitem = IDL_LIST(curitem).next) { curdcl = IDL_LIST(curitem).data; switch(IDL_NODE_TYPE(curdcl)) { case IDLN_OP_DCL: newopi = g_new0(CBESkelOpInfo, 1); newopi->iface_id = g_strdup(iface_id); newopi->opname = g_strdup(IDL_IDENT(IDL_OP_DCL(curdcl).ident).str); iti->oplist = g_slist_insert_sorted(iti->oplist, newopi, (GCompareFunc)cbe_skel_compare_op_dcls); break; case IDLN_ATTR_DCL: for(curattr = IDL_ATTR_DCL(curdcl).simple_declarations; curattr; curattr = IDL_LIST(curattr).next) { curattrdcl = IDL_LIST(curattr).data; newopi = g_new0(CBESkelOpInfo, 1); newopi->iface_id = g_strdup(iface_id); newopi->opname = g_strdup_printf("_get_%s", IDL_IDENT(curattrdcl).str); iti->oplist = g_slist_insert_sorted(iti->oplist, newopi, (GCompareFunc)cbe_skel_compare_op_dcls); if(!IDL_ATTR_DCL(curdcl).f_readonly) { newopi = g_new0(CBESkelOpInfo, 1); newopi->iface_id = g_strdup(iface_id); newopi->opname = g_strdup_printf("_set_%s", IDL_IDENT(curattrdcl).str); iti->oplist = g_slist_insert_sorted(iti->oplist, newopi, (GCompareFunc)cbe_skel_compare_op_dcls); } } break; default: break; } } g_free(iface_id); } #if 0 static void cbe_skel_interface_print_relayer_internal(CBESkelInfo *ski, IDL_tree curitem, char *iface_id, char *cur_id) { IDL_tree curdcl; switch(IDL_NODE_TYPE(IDL_LIST(curitem).data)) { case IDLN_OP_DCL: fprintf(ski->of, " if(!strcmp(_ORBIT_recv_buffer->message.u.request.operation, \"%s\")) {\n", IDL_IDENT(IDL_OP_DCL(IDL_LIST(curitem).data).ident).str); fprintf(ski->of, " *epv = servant->vepv->%s_epv->%s;\n", iface_id, IDL_IDENT(IDL_OP_DCL(IDL_LIST(curitem).data).ident).str); fprintf(ski->of, " return (gpointer)skel_%s_%s;\n", cur_id, IDL_IDENT(IDL_OP_DCL(IDL_LIST(curitem).data).ident).str); fprintf(ski->of, " } else"); break; case IDLN_ATTR_DCL: for(curdcl = IDL_ATTR_DCL(IDL_LIST(curitem).data).simple_declarations; curdcl; curdcl = IDL_LIST(curdcl).next) { fprintf(ski->of, " if(!strcmp(_ORBIT_recv_buffer->message.u.request.operation, \"_get_%s\")) {\n", IDL_IDENT(IDL_LIST(curdcl).data).str); fprintf(ski->of, " *epv = servant->vepv->%s_epv->_get_%s;\n", iface_id, IDL_IDENT(IDL_LIST(curdcl).data).str); fprintf(ski->of, " return (gpointer)skel_%s__get_%s;\n", cur_id, IDL_IDENT(IDL_LIST(curdcl).data).str); fprintf(ski->of, " } else"); if(!IDL_ATTR_DCL(IDL_LIST(curitem).data).f_readonly) { fprintf(ski->of, " if(!strcmp(_ORBIT_recv_buffer->message.u.request.operation, \"_set_%s\")) {\n", IDL_IDENT(IDL_LIST(curdcl).data).str); fprintf(ski->of, " *epv = servant->vepv->%s_epv->_set_%s;\n", iface_id, IDL_IDENT(IDL_LIST(curdcl).data).str); fprintf(ski->of, " return (gpointer)skel_%s__set_%s;\n", cur_id, IDL_IDENT(IDL_LIST(curdcl).data).str); fprintf(ski->of, " } else"); } } break; default: break; } } static void cbe_skel_interface_print_inheritance_relayer(IDL_tree node, CBESkelInfo *current) { IDL_tree curitem; char *iface_id, *cur_id; g_assert(current->tree); g_assert(IDL_NODE_TYPE(node) == IDLN_INTERFACE); if(node==current->tree) { /* We don't inherit from ourself... */ return; } /* Print the operations defined for this interface, but in current's namespace */ iface_id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(node).ident), "_", 0); cur_id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(current->tree).ident), "_", 0); for(curitem = IDL_INTERFACE(node).body; curitem; curitem = IDL_LIST(curitem).next) { cbe_skel_interface_print_relayer_internal(current, curitem, iface_id, cur_id); } g_free(iface_id); g_free(cur_id); } #endif static void cbe_skel_interface_print_relayers(const CBESkelInterfaceTraverseInfo *iti) { CBESkelInterfaceTraverseInfo subiti = *iti; GSList *curnode; CBESkelOpInfo *opi; char curchar; curnode = iti->oplist; subiti.curlevel = iti->curlevel+1; fprintf(iti->ski->of, "switch(opname[%d]) {\n", iti->curlevel); while(curnode) { opi = (CBESkelOpInfo *)curnode->data; if(iti->curlevel > strlen(opi->opname)) { curnode = g_slist_next(curnode); continue; } curchar = opi->opname[iti->curlevel]; if(curchar) fprintf(iti->ski->of, "case '%c':\n", curchar); else fprintf(iti->ski->of, "case '\\0':\n"); subiti.oplist = NULL; while(curnode && ((CBESkelOpInfo *)curnode->data)->opname[iti->curlevel] == curchar) { subiti.oplist = g_slist_append(subiti.oplist, curnode->data); curnode = g_slist_next(curnode); } if(g_slist_length(subiti.oplist) > 1) { if(curchar) cbe_skel_interface_print_relayers(&subiti); else g_error("two ops with same name!!!!"); } else { fprintf(iti->ski->of, "*impl = servant->vepv->%s_epv->%s;\n", opi->iface_id, opi->opname); fprintf(iti->ski->of, "return (gpointer)skel_%s_%s;\n", opi->iface_id, opi->opname); } fprintf(iti->ski->of, "break;\n"); g_slist_free(subiti.oplist); } fprintf(iti->ski->of, "default: return NULL;\n}\n"); } static void cbe_skel_interface_print_relayer(CBESkelInfo *ski) { char *id; CBESkelInterfaceTraverseInfo iti; id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident), "_", 0); fprintf(ski->of, "static ORBitSkeleton get_skel_%s(POA_%s *servant,\nGIOPRecvBuffer *_ORBIT_recv_buffer,\ngpointer *impl)\n", id, id); fprintf(ski->of, "{\n"); fprintf(ski->of, "gchar *opname = _ORBIT_recv_buffer->message.u.request.operation;\n\n"); iti.ski = ski; iti.oplist = NULL; iti.curlevel = 0; IDL_tree_traverse_parents(ski->tree, (GFunc)cbe_skel_interface_add_relayer, &iti); cbe_skel_interface_print_relayers(&iti); g_slist_foreach(iti.oplist, (GFunc)cbe_skel_free_op_info, NULL); g_slist_free(iti.oplist); fprintf(ski->of, "}\n\n"); g_free(id); } static void cbe_skel_interface_print_initializer(IDL_tree node, CBESkelInfo *ski) { char *id; g_assert(IDL_NODE_TYPE(node) == IDLN_INTERFACE); /* Print the operations defined for this interface, but in current's namespace */ id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(node).ident), "_", 0); fprintf(ski->of, "obj->vepv[%s__classid] = servant->vepv->%s_epv;\n", id, id); g_free(id); } static void cbe_skel_interface_print_objref_initializer(CBESkelInfo *ski) { char *id; id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident), "_", 0); fprintf(ski->of, "static void init_local_objref_%s(CORBA_Object obj, POA_%s *servant)\n", id, id); fprintf(ski->of, "{\n"); g_free(id); IDL_tree_traverse_parents(ski->tree, (gpointer)cbe_skel_interface_print_initializer, ski); fprintf(ski->of, "}\n"); } #if 0 static void cbe_skel_interface_print_inheritance_ops(IDL_tree node, CBESkelInfo *current) { CBESkelInfo subski = *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) { subski.tree = IDL_LIST(curitem).data; switch(IDL_NODE_TYPE(IDL_LIST(curitem).data)) { case IDLN_OP_DCL: cbe_skel_do_inherited_op_dcl(&subski, current->tree); break; case IDLN_ATTR_DCL: cbe_skel_do_inherited_attr_dcl(&subski, current->tree); break; default: break; } } } #endif static void cbe_skel_do_interface(CBESkelInfo *ski) { CBESkelInfo subski = *ski; char *id, *id2; IDL_tree curitem; int i; subski.tree = IDL_INTERFACE(ski->tree).body; if(subski.tree) orbit_cbe_skel_process_piece(&subski); id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident), "_", 0); #if 0 /* useless... */ subski.tree = IDL_INTERFACE(ski->tree).inheritance_spec; if(subski.tree != NULL) { fprintf(ski->of, "/* Begin inherited operations for %s */\n\n", id); IDL_tree_traverse_parents(subski.tree, (gpointer)cbe_skel_interface_print_inheritance_ops, ski); fprintf(ski->of, "/* End inherited operations for %s */\n\n", id); } #endif cbe_skel_interface_print_relayer(ski); cbe_skel_interface_print_objref_initializer(ski); fprintf(ski->of, "void POA_%s__init(POA_%s *servant,\nCORBA_Environment *env)\n", id, id); fprintf(ski->of, "{\n"); fprintf(ski->of, " static const PortableServer_ClassInfo class_info = {(gpointer)&get_skel_%s, \"%s\", (gpointer)&init_local_objref_%s};\n", id, IDL_IDENT(IDL_INTERFACE(ski->tree).ident).repo_id, id); fprintf(ski->of, " PortableServer_ServantBase__init(((PortableServer_ServantBase *)servant), env);\n"); for(curitem = IDL_INTERFACE(ski->tree).inheritance_spec; curitem; curitem = IDL_LIST(curitem).next) { id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_LIST(curitem).data), "_", 0); fprintf(ski->of, " POA_%s__init(((POA_%s *)servant), env);\n", id2, id2); g_free(id2); } fprintf(ski->of, " ORBIT_OBJECT_KEY(servant->_private)->class_info = (PortableServer_ClassInfo*) &class_info;\n"); fprintf(ski->of, "if(!%s__classid)\n%s__classid = ORBit_register_class(&class_info);\n", id, id); fprintf(ski->of, "}\n\n"); fprintf(ski->of, "void POA_%s__fini(POA_%s *servant,\nCORBA_Environment *env)\n", id, id); fprintf(ski->of, "{\n"); if(IDL_INTERFACE(ski->tree).inheritance_spec) { for(i = IDL_list_length(IDL_INTERFACE(ski->tree).inheritance_spec) - 1; i >= 0; i--) { curitem = IDL_list_nth(IDL_INTERFACE(ski->tree).inheritance_spec, i); id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_LIST(curitem).data), "_", 0); fprintf(ski->of, " POA_%s__fini(((POA_%s *)servant), env);\n", id2, id2); g_free(id2); } } fprintf(ski->of, " PortableServer_ServantBase__fini(servant, env);\n"); fprintf(ski->of, "}\n\n"); g_free(id); } static void cbe_skel_do_list(CBESkelInfo *ski) { IDL_tree curitem; CBESkelInfo subski = *ski; for(curitem = ski->tree; curitem; curitem = IDL_LIST(curitem).next) { subski.tree = IDL_LIST(curitem).data; orbit_cbe_skel_process_piece(&subski); } } static void cbe_skel_do_member(CBESkelInfo *ski) { g_assert(!"Not yet implemented"); } static void cbe_skel_do_module(CBESkelInfo *ski) { char *id; id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_MODULE(ski->tree).ident), "_", 1); fprintf(ski->of, "/***************** Begin module %s ***************/\n", id); ski->tree = IDL_MODULE(ski->tree).definition_list; orbit_cbe_skel_process_piece(ski); fprintf(ski->of, "/***************** End module %s ***************/\n", id); g_free(id); } static void cbe_skel_do_none(CBESkelInfo *ski) { g_assert(!"Not yet implemented"); } static void cbe_skel_op_dcl_print_call_param(CBESkelInfo *ski) { int i, n; n = orbit_cbe_param_numptrs(ski->tree, cbe_attr_to_paramrole(IDL_PARAM_DCL(ski->tree).attr)); n = n && n; /* just one & */ for(i = 0; i < n; i++) fprintf(ski->of, "&("); fprintf(ski->of, "%s", IDL_IDENT(IDL_PARAM_DCL(ski->tree).simple_declarator).str); for(i = 0; i < n; i++) fprintf(ski->of, ")"); } static void cbe_skel_do_op_dcl_shared(CBESkelInfo *ski) { /* XXX we don't handle contexts here yet - fix that */ IDL_tree curitem; GString *tmpstr = g_string_new(NULL); CBESkelInfo subski = *ski; char *id; orbit_cbe_write_typespec(ski->of, IDL_OP_DCL(ski->tree).op_type_spec); orbit_cbe_param_printptrs(ski->of, IDL_OP_DCL(ski->tree).op_type_spec, DATA_RETURN); fprintf(ski->of, " (*_impl_%s)(PortableServer_Servant servant,\n", IDL_IDENT(IDL_OP_DCL(ski->tree).ident).str); for(curitem = IDL_OP_DCL(ski->tree).parameter_dcls; curitem; curitem = IDL_LIST(curitem).next) { cbe_print_param_dcl(ski->of, IDL_LIST(curitem).data); fprintf(ski->of, ",\n"); } fprintf(ski->of, "CORBA_Environment *ev))\n"); fprintf(ski->of, "{\n"); /* Print the variables into with we will be demarshalling & marshalling parameters */ for(curitem = IDL_OP_DCL(ski->tree).parameter_dcls; curitem; curitem = IDL_LIST(curitem).next) { fprintf(ski->of, " "); cbe_print_var_dcl(ski->of, IDL_LIST(curitem).data, TRUE); fprintf(ski->of, ";\n"); } if(IDL_OP_DCL(ski->tree).op_type_spec) { fprintf(ski->of, " "); cbe_print_var_dcl(ski->of, IDL_OP_DCL(ski->tree).op_type_spec, TRUE); fprintf(ski->of, ";\n"); } if(!IDL_OP_DCL(ski->tree).f_oneway) fprintf(ski->of, " GIOPSendBuffer *_ORBIT_send_buffer;\n"); if(IDL_OP_DCL(ski->tree).raises_expr) { fprintf(ski->of, "static const ORBit_exception_marshal_info _ORBIT_user_exceptions[] = {"); for(curitem = IDL_OP_DCL(ski->tree).raises_expr; curitem; curitem = IDL_LIST(curitem).next) { IDL_tree curnode = IDL_LIST(curitem).data; id = orbit_cbe_get_typename(curnode); fprintf(ski->of, "{(CORBA_TypeCode)&TC_%s_struct, (gpointer)%s_marshal},", id, id); g_free(id); } fprintf(ski->of, "{CORBA_OBJECT_NIL, NULL}};\n"); } fprintf(ski->of, "\n"); if(cbe_op_dcl_nparams(ski->tree, DATA_INOUT|DATA_IN) > 0) cbe_skel_op_params_demarshal(ski); /* Make things happen - call the implementation function */ if(IDL_OP_DCL(ski->tree).op_type_spec) fprintf(ski->of, " _ORBIT_retval = "); fprintf(ski->of, "_impl_%s(_ORBIT_servant, ", IDL_IDENT(IDL_OP_DCL(ski->tree).ident).str); for(curitem = IDL_OP_DCL(ski->tree).parameter_dcls; curitem; curitem = IDL_LIST(curitem).next) { subski.tree = IDL_LIST(curitem).data; cbe_skel_op_dcl_print_call_param(&subski); fprintf(ski->of, ",\n"); } fprintf(ski->of, " ev);\n"); /* Now marshal any return params and send it out over the wire */ if(!IDL_OP_DCL(ski->tree).f_oneway) { fprintf(ski->of, " _ORBIT_send_buffer = \n"); fprintf(ski->of, " giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->connection, NULL,\n"); fprintf(ski->of, " _ORBIT_recv_buffer->message.u.request.request_id,\n"); fprintf(ski->of, " ev->_major);\n\n"); fprintf(ski->of, "if(ev->_major == CORBA_NO_EXCEPTION) {\n"); cbe_skel_op_params_marshal(ski); fprintf(ski->of, "} else if(ev->_major == CORBA_SYSTEM_EXCEPTION)\n"); fprintf(ski->of, " ORBit_send_system_exception(_ORBIT_send_buffer, ev);"); fprintf(ski->of, "else if(ev->_major == CORBA_USER_EXCEPTION)\n"); fprintf(ski->of, " ORBit_send_user_exception(_ORBIT_send_buffer, ev, %s);", IDL_OP_DCL(ski->tree).raises_expr?"_ORBIT_user_exceptions":"NULL"); fprintf(ski->of, " giop_send_buffer_write(_ORBIT_send_buffer);\n"); fprintf(ski->of, " giop_send_buffer_unuse(_ORBIT_send_buffer);\n"); cbe_skel_op_params_free(ski); } fprintf(ski->of, "}\n\n"); g_string_free(tmpstr, TRUE); } static void cbe_skel_do_op_dcl(CBESkelInfo *ski) { /* XXX we don't handle contexts here yet - fix that */ char *id, *id2; IDL_tree curitem; int level; id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(ski->tree).ident), "_", 0); if(IDL_OP_DCL(ski->tree).op_type_spec && IDL_OP_DCL(ski->tree).f_oneway) { g_error("[%s] You cannot have a return value from a oneway operation!", id); } curitem = IDL_get_parent_node(ski->tree, IDLN_INTERFACE, &level); g_assert(curitem); id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(curitem).ident), "_", 0); fprintf(ski->of, "\nstatic void\nskel_%s(POA_%s *_ORBIT_servant,\nGIOPRecvBuffer *_ORBIT_recv_buffer,\nCORBA_Environment *ev,\n", id, id2); g_free(id); g_free(id2); cbe_skel_do_op_dcl_shared(ski); } /* FIXME This function should check for redefined inherited ops, it doesn't currently - RHP */ static void cbe_skel_do_inherited_op_dcl(CBESkelInfo *ski, 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(ski->tree).ident; g_assert(ident); if(IDL_OP_DCL(ski->tree).op_type_spec && IDL_OP_DCL(ski->tree).f_oneway) { g_error("[%s_%s] You cannot have a return value from a oneway operation!", id, IDL_IDENT(ident).str); } fprintf(ski->of, "\nstatic void\nskel_%s_%s(POA_%s *_ORBIT_servant,\nGIOPRecvBuffer *_ORBIT_recv_buffer,\nCORBA_Environment *ev,\n", id, IDL_IDENT(ident).str, id); g_free(id); cbe_skel_do_op_dcl_shared(ski); } static void cbe_skel_op_params_marshal(CBESkelInfo *ski) { CBEMarshalInfo mi = {NULL, NULL, NULL, NULL, NULL}; IDL_tree curitem; GString *tmpstr; int n, i; mi.of = ski->of; if(cbe_op_dcl_nparams(ski->tree, DATA_INOUT|DATA_OUT|DATA_RETURN) <= 0) return; tmpstr = g_string_new(NULL); mi.param = mi.previous_param = NULL; if(IDL_OP_DCL(ski->tree).op_type_spec) { fprintf(ski->of, " /* marshal return value */\n"); mi.param = IDL_OP_DCL(ski->tree).op_type_spec; n = orbit_cbe_param_numptrs(mi.param, DATA_RETURN); g_string_assign(tmpstr, ""); for(i = 0; i < n; i++) g_string_append_c(tmpstr, '*'); g_string_append(tmpstr, "_ORBIT_retval"); mi.param_name = tmpstr->str; cbe_output_marshaller(&mi); } for(curitem = IDL_OP_DCL(ski->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) { mi.param = IDL_LIST(curitem).data; n = orbit_cbe_param_numptrs(mi.param, cbe_attr_to_paramrole(IDL_PARAM_DCL(mi.param).attr)) - 1; if(cbe_type_is_fixed_length(mi.param)) n = 0; 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(ski->of, " /* marshal parameter %s */\n", mi.param_name); cbe_output_marshaller(&mi); } } g_string_free(tmpstr, TRUE); } static void cbe_skel_param_subfree(CBESkelInfo *ski) { char *id, *varname; if(IDL_NODE_TYPE(ski->tree) != IDLN_PARAM_DCL) { id = orbit_cbe_get_typename(ski->tree); varname = "_ORBIT_retval"; } else { id = orbit_cbe_get_typename(IDL_PARAM_DCL(ski->tree).param_type_spec); varname = IDL_IDENT(IDL_PARAM_DCL(ski->tree).simple_declarator).str; } fprintf(ski->of, "%s__free(&%s, NULL, %s);\n", id, varname, ski->free_internal); g_free(id); } static void cbe_skel_op_retval_free(CBESkelInfo *ski) { IDL_tree ts; ts = cbe_get_typespec(ski->tree); switch(IDL_NODE_TYPE(ts)) { case IDLN_TYPE_UNION: case IDLN_TYPE_STRUCT: if(cbe_type_is_fixed_length(ts)) return; case IDLN_TYPE_SEQUENCE: case IDLN_TYPE_STRING: case IDLN_TYPE_ARRAY: case IDLN_TYPE_ANY: break; case IDLN_TYPE_OBJECT: case IDLN_INTERFACE: case IDLN_FORWARD_DCL: fprintf(ski->of, "if(ev->_major == CORBA_NO_EXCEPTION) CORBA_Object_release(_ORBIT_retval, ev);\n"); default: return; } fprintf(ski->of, "if(ev->_major == CORBA_NO_EXCEPTION) CORBA_free(_ORBIT_retval);\n"); } static gboolean cbe_skel_op_param_has_sequence(IDL_tree ts) { gboolean has_seq = FALSE, subhas; IDL_tree curitem, sn; ts = cbe_get_typespec(ts); switch(IDL_NODE_TYPE(ts)) { case IDLN_TYPE_UNION: for(curitem = IDL_TYPE_UNION(ts).switch_body; curitem; curitem = IDL_LIST(curitem).next) { sn = IDL_MEMBER(IDL_CASE_STMT(IDL_LIST(curitem).data).element_spec).type_spec; subhas = cbe_skel_op_param_has_sequence(sn); has_seq = has_seq || subhas; } return has_seq; break; case IDLN_TYPE_STRUCT: for(curitem = IDL_TYPE_STRUCT(ts).member_list; curitem; curitem = IDL_LIST(curitem).next) { sn = IDL_MEMBER(IDL_LIST(curitem).data).type_spec; subhas = cbe_skel_op_param_has_sequence(sn); has_seq = has_seq || subhas; } return has_seq; break; case IDLN_TYPE_ARRAY: return cbe_skel_op_param_has_sequence(IDL_TYPE_DCL(IDL_get_parent_node(ts, IDLN_TYPE_DCL, NULL)).type_spec); break; case IDLN_TYPE_SEQUENCE: return TRUE; default: return FALSE; } } static void cbe_skel_op_param_free(CBESkelInfo *ski) { IDL_tree ts; ts = cbe_get_typespec(ski->tree); switch(IDL_PARAM_DCL(ski->tree).attr) { case IDL_PARAM_IN: if(cbe_type_is_fixed_length(ts)) return; ski->free_internal = "CORBA_FALSE"; switch(IDL_NODE_TYPE(ts)) { case IDLN_TYPE_SEQUENCE: case IDLN_TYPE_UNION: case IDLN_TYPE_STRUCT: case IDLN_TYPE_ARRAY: case IDLN_TYPE_ANY: cbe_skel_param_subfree(ski); break; case IDLN_TYPE_OBJECT: case IDLN_INTERFACE: case IDLN_FORWARD_DCL: fprintf(ski->of, "CORBA_Object_release(%s, ev);\n", IDL_IDENT(IDL_PARAM_DCL(ski->tree).simple_declarator).str); break; default: break; } break; case IDL_PARAM_OUT: if(cbe_type_is_fixed_length(ts)) return; fprintf(ski->of, "if(ev->_major == CORBA_NO_EXCEPTION)"); switch(IDL_NODE_TYPE(ts)) { case IDLN_TYPE_OBJECT: case IDLN_INTERFACE: fprintf(ski->of, "CORBA_Object_release(%s, ev);\n", IDL_IDENT(IDL_PARAM_DCL(ski->tree).simple_declarator).str); break; default: fprintf(ski->of, "CORBA_free(%s);\n", IDL_IDENT(IDL_PARAM_DCL(ski->tree).simple_declarator).str); } break; case IDL_PARAM_INOUT: if(cbe_type_is_fixed_length(ts)) return; switch(IDL_NODE_TYPE(ts)) { case IDLN_TYPE_OBJECT: case IDLN_INTERFACE: fprintf(ski->of, "CORBA_Object_release(%s, ev);\n", IDL_IDENT(IDL_PARAM_DCL(ski->tree).simple_declarator).str); break; default: cbe_skel_param_subfree(ski); } break; } } static void cbe_skel_op_params_free(CBESkelInfo *ski) { IDL_tree curitem; CBESkelInfo subski = *ski; if(IDL_OP_DCL(ski->tree).op_type_spec) { subski.tree = IDL_OP_DCL(ski->tree).op_type_spec; cbe_skel_op_retval_free(&subski); } for(curitem = IDL_OP_DCL(ski->tree).parameter_dcls; curitem; curitem = IDL_LIST(curitem).next) { subski.tree = IDL_LIST(curitem).data; subski.free_internal = "CORBA_TRUE"; cbe_skel_op_param_free(&subski); } } static void cbe_skel_op_params_demarshal(CBESkelInfo *ski) { CBEDemarshalInfo dmi = {NULL, NULL, NULL, NULL, NULL, TRUE, FALSE, "(((ORBit_ObjectKey *)_ORBIT_servant->_private)->object->orb)"}; IDL_tree curitem; GString *tmpstr = g_string_new(NULL); dmi.of = ski->of; fprintf(ski->of, " if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {\n"); do { dmi.previous_param = NULL; for(curitem = IDL_OP_DCL(ski->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) { if(IDL_PARAM_DCL(IDL_LIST(curitem).data).attr == IDL_PARAM_INOUT) dmi.allocate_memory = TRUE; else dmi.allocate_memory = FALSE; dmi.param = IDL_LIST(curitem).data; g_string_assign(tmpstr, ""); g_string_sprintfa(tmpstr, "%s", IDL_IDENT(IDL_PARAM_DCL(dmi.param).simple_declarator).str); dmi.param_name = tmpstr->str; fprintf(ski->of, "\n\n /* demarshal parameter %s */\n", dmi.param_name); cbe_output_demarshaller(&dmi); } } if(dmi.byteswap_version) fprintf(ski->of, " } else {\n"); } while(dmi.byteswap_version-- > 0); fprintf(ski->of, " }\n\n"); g_string_free(tmpstr, TRUE); } static void cbe_skel_do_param_dcl(CBESkelInfo *ski) { g_assert(!"Not yet implemented"); } static void cbe_skel_do_string(CBESkelInfo *ski) { g_assert(!"Not yet implemented"); } static void cbe_skel_do_type_any(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_array(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_boolean(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_char(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_dcl(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_enum(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_fixed(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_float(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_integer(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_object(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_octet(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_sequence(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_string(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_struct(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_union(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_wide_char(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_type_wide_string(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_unaryop(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_wide_char(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } static void cbe_skel_do_wide_string(CBESkelInfo *ski) { /*g_assert(!"Not yet implemented");*/ } /* Dead code repo */ #if 0 /* not sure if we need this at all, unless we think up a generic version of the relayer */ fprintf(ski->of, "static ORBitSkeleton %s_skeletons[] = {\n", id); for(curitem = IDL_INTERFACE(ski->tree).body; curitem; curitem = IDL_LIST(curitem).next) { cbe_skel_print_skelptr(ski->of, IDL_LIST(curitem).data); } fprintf(ski->of, "};\n\n"); #endif