3 #include "forb-idl-c-backend.h"
11 } CBESkelInterfaceTraverseInfo;
20 static void cbe_skel_do_interface(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci);
23 ck_output_poastuff(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
25 if( !tree || (tree->declspec & IDLF_DECLSPEC_PIDL)!=0 )
28 switch(IDL_NODE_TYPE(tree)) {
30 ck_output_poastuff(IDL_MODULE(tree).definition_list, rinfo, ci);
35 for(sub = tree; sub; sub = IDL_LIST(sub).next) {
36 ck_output_poastuff(IDL_LIST(sub).data, rinfo, ci);
41 cbe_skel_do_interface(tree, rinfo, ci);
49 /* cbe_skel_compare_op_dcls(CBESkelOpInfo *op1, CBESkelOpInfo *op2) */
51 /* return strcmp(op1->opname, op2->opname); */
55 /* cbe_skel_free_op_info(CBESkelOpInfo *op) */
57 /* g_free(op->opname); */
58 /* g_free(op->iface_id); */
63 /* cbe_skel_interface_add_relayer (IDL_tree intf, CBESkelInterfaceTraverseInfo *iti) */
65 /* CBESkelOpInfo *newopi; */
66 /* IDL_tree curitem, curdcl, curattr, curattrdcl; */
71 /* IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(intf).ident), */
74 /* for(curitem = IDL_INTERFACE(intf).body; curitem; */
75 /* curitem = IDL_LIST(curitem).next) { */
76 /* curdcl = IDL_LIST(curitem).data; */
78 /* switch(IDL_NODE_TYPE(curdcl)) { */
79 /* case IDLN_OP_DCL: */
80 /* newopi = g_new0(CBESkelOpInfo, 1); */
81 /* newopi->iface_id = g_strdup(iface_id); */
82 /* newopi->opname = g_strdup(IDL_IDENT(IDL_OP_DCL(curdcl).ident).str); */
83 /* newopi->idx = idx++; */
84 /* iti->oplist = g_slist_insert_sorted(iti->oplist, newopi, */
85 /* (GCompareFunc)cbe_skel_compare_op_dcls); */
87 /* case IDLN_ATTR_DCL: */
88 /* for(curattr = IDL_ATTR_DCL(curdcl).simple_declarations; */
89 /* curattr; curattr = IDL_LIST(curattr).next) { */
90 /* curattrdcl = IDL_LIST(curattr).data; */
92 /* newopi = g_new0(CBESkelOpInfo, 1); */
93 /* newopi->iface_id = g_strdup(iface_id); */
94 /* newopi->opname = g_strdup_printf("_get_%s", IDL_IDENT(curattrdcl).str); */
95 /* newopi->idx = idx++; */
96 /* iti->oplist = g_slist_insert_sorted(iti->oplist, newopi, */
97 /* (GCompareFunc)cbe_skel_compare_op_dcls); */
98 /* if(!IDL_ATTR_DCL(curdcl).f_readonly) { */
99 /* newopi = g_new0(CBESkelOpInfo, 1); */
100 /* newopi->iface_id = g_strdup(iface_id); */
101 /* newopi->opname = g_strdup_printf("_set_%s", IDL_IDENT(curattrdcl).str); */
102 /* newopi->idx = idx++; */
103 /* iti->oplist = g_slist_insert_sorted(iti->oplist, newopi, */
104 /* (GCompareFunc)cbe_skel_compare_op_dcls); */
113 /* g_free(iface_id); */
117 /* cbe_skel_interface_print_relayers(const CBESkelInterfaceTraverseInfo *iti) */
119 /* CBESkelInterfaceTraverseInfo subiti = *iti; */
120 /* GSList *curnode; */
121 /* CBESkelOpInfo *opi; */
124 /* curnode = iti->oplist; */
125 /* subiti.curlevel = iti->curlevel+1; */
126 /* fprintf(iti->ci->fh, "switch(opname[%d]) {\n", iti->curlevel); */
127 /* while(curnode) { */
128 /* opi = (CBESkelOpInfo *)curnode->data; */
129 /* if(iti->curlevel > strlen(opi->opname)) { */
130 /* curnode = g_slist_next(curnode); */
133 /* curchar = opi->opname[iti->curlevel]; */
135 /* fprintf(iti->ci->fh, "case '%c':\n", curchar); */
137 /* fprintf(iti->ci->fh, "case '\\0':\n"); */
138 /* subiti.oplist = NULL; */
139 /* while(curnode && ((CBESkelOpInfo *)curnode->data)->opname[iti->curlevel] */
141 /* subiti.oplist = g_slist_append(subiti.oplist, curnode->data); */
142 /* curnode = g_slist_next(curnode); */
145 /* if(g_slist_length(subiti.oplist) > 1) { */
147 /* cbe_skel_interface_print_relayers(&subiti); */
149 /* g_error("two ops with same name!!!!"); */
151 /* if(strlen(opi->opname + iti->curlevel)) */
152 /* fprintf(iti->ci->fh, "if(strcmp((opname + %d), \"%s\")) break;\n", */
153 /* iti->curlevel + 1, opi->opname + iti->curlevel+1); */
154 /* fprintf(iti->ci->fh, "*impl = (gpointer)servant->vepv->%s_epv->%s;\n", */
155 /* opi->iface_id, opi->opname); */
156 /* fprintf(iti->ci->fh, "{Forb_IInterface *volatile _t_=&%s__iinterface;*m_data = (gpointer)&_t_->methods._buffer [%d];}\n", */
157 /* opi->iface_id, opi->idx); */
158 /* fprintf(iti->ci->fh, "return (ForbSmallSkeleton)_FORB_skel_small_%s_%s;\n", */
159 /* opi->iface_id, opi->opname); */
161 /* fprintf(iti->ci->fh, "break;\n"); */
162 /* g_slist_free(subiti.oplist); */
164 /* fprintf(iti->ci->fh, "default: break; \n}\n"); */
168 /* cbe_skel_interface_print_relayer(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci) */
171 /* CBESkelInterfaceTraverseInfo iti; */
173 /* id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(tree).ident), "_", 0); */
174 /* fprintf(ci->fh, "static ForbSmallSkeleton get_skel_small_%s(POA_%s *servant,\nconst char *opname," */
175 /* "gpointer *m_data, gpointer *impl)\n{\n", id, id); */
178 /* iti.oplist = NULL; */
179 /* iti.curlevel = 0; */
181 /* IDL_tree_traverse_parents(tree, */
182 /* (GFunc)cbe_skel_interface_add_relayer, &iti); */
184 /* cbe_skel_interface_print_relayers(&iti); */
186 /* g_slist_foreach(iti.oplist, (GFunc)cbe_skel_free_op_info, NULL); */
187 /* g_slist_free(iti.oplist); */
189 /* fprintf(ci->fh, "return NULL;\n"); */
190 /* fprintf(ci->fh, "}\n\n"); */
198 } CBESkelVEPVMapTraverseInfo;
201 /* cbe_skel_interface_print_vepvmap_offsets (IDL_tree node, CBESkelVEPVMapTraverseInfo *ti) */
204 /* id = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (IDL_INTERFACE (node).ident), "_", 0); */
205 /* fprintf (ti->ci->fh, "(CORBA_unsigned_long) %s__classid,\n", id); */
206 /* fprintf (ti->ci->fh, "FORB_VEPV_OFFSET (POA_%s__vepv, %s_epv),\n", ti->for_id, id); */
211 * If the type specified in @a type_spec is dynamically allocated
212 * (such as string, sequence or object reference), the parameters of
213 * this type must be freed after they are not needed. For input
214 * parameter this is after the implementation is called, for out and
215 * inout return parameters after the returned value is serialized.
217 static void free_memory_if_needed(IDL_tree type_spec, const char *name, int n, OIDL_C_Info *ci)
219 type_spec = forb_cbe_get_typespec(type_spec);
220 /* forb_idl_print_node(type_spec, 7); */
221 switch(IDL_NODE_TYPE(type_spec)) {
222 case IDLN_TYPE_STRING:
223 case IDLN_TYPE_WIDE_STRING:
224 fprintf(ci->fh, " ");
225 fprintf(ci->fh, "forb_free(%s);\n", name);
227 case IDLN_TYPE_ARRAY:
229 case IDLN_TYPE_SEQUENCE: {
230 char *dot = n==2?"->":".";
231 IDL_tree simple_type = forb_cbe_get_typespec(IDL_TYPE_SEQUENCE(type_spec).simple_type_spec);
233 fprintf(ci->fh, " if (CORBA_sequence_get_release(%s%s)) {\n",
235 if (IDLN_NATIVE == IDL_NODE_TYPE(simple_type)) {
236 fprintf(ci->fh, " int i;\n"
237 " for (i=0; i<%s%s_length; i++)\n"
238 " %s_free(%s%s_buffer[i]);\n",
239 name, dot, forb_cbe_get_typespec_str(IDL_NATIVE(type_spec).ident),
242 fprintf(ci->fh, " forb_free(%s%s_buffer);\n"
245 fprintf(ci->fh, " ");
246 fprintf(ci->fh, "forb_free(%s);\n", name);
251 fprintf(ci->fh, " ");
252 fprintf(ci->fh, "%s_free(%s);\n",
253 forb_cbe_get_typespec_str(IDL_NATIVE(type_spec).ident),
257 fprintf(ci->fh, " ");
258 fprintf(ci->fh, "forb_object_release(%s);\n", name);
266 static void ck_output_op_skel(IDL_tree op, char *intf_id, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
270 gboolean has_retval/* , has_args */;
271 const char *const seq_init = " = {0,0,NULL}";
273 has_retval = IDL_OP_DCL (op).op_type_spec != NULL;
274 /* has_args = IDL_OP_DCL (op).parameter_dcls != NULL; */
276 id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(op).ident), "_", 0);
277 id_plain = IDL_IDENT(IDL_OP_DCL(op).ident).str;
278 fprintf(ci->fh, "static void\n"
279 "forb_skel_%s(FORB_CDR_Codec *cin, FORB_CDR_Codec *cout, %s _obj, struct forb_env *env)\n"
282 /* fprintf(ci->fh, " if (_obj->interface != %s_interface) {\n", intf_id); */
283 /* fprintf(ci->fh, " env->major = FORB_EX_BAD_OPERATION;\n" */
286 fprintf(ci->fh, " if (_%s_impl(_obj) && _%s_impl(_obj)->%s) {\n", intf_id, intf_id, id_plain);
288 /* Declare variables for parameters */
289 for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
290 IDL_tree parm = IDL_LIST (sub).data;
292 IDL_tree ts = forb_cbe_get_typespec(parm);
295 char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
296 role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
297 n = oidl_param_info (ts, role, &isSlice);
299 fprintf(ci->fh, " ");
300 forb_cbe_write_typespec(ci->fh, IDL_PARAM_DCL(parm).param_type_spec);
301 fprintf(ci->fh, " %s%s%s;\n",
304 (n < 2 && IDL_NODE_TYPE(ts) == IDLN_TYPE_SEQUENCE)?seq_init : "");
307 fprintf (ci->fh, " ");
308 forb_cbe_write_param_typespec (ci->fh, op);
309 fprintf (ci->fh, " _forb_ret;\n"); /* TODO: seq_init */
312 /* Deserialize in parameters */
313 for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
314 IDL_tree parm = IDL_LIST (sub).data;
316 role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
317 if (role == DATA_IN || role == DATA_INOUT) {
318 char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
319 fprintf(ci->fh, " if (!");
320 forb_cbe_write_typespec(ci->fh, IDL_PARAM_DCL(parm).param_type_spec);
321 fprintf(ci->fh, "_deserialize(cin, &%s)) {\n", name);
322 fprintf(ci->fh, " env->major = FORB_EX_MARSHAL; goto exception;\n }\n");
326 /* Call the implementation */
327 fprintf(ci->fh, " ");
329 fprintf(ci->fh, "_forb_ret = ");
330 fprintf(ci->fh, "_%s_impl(_obj)->%s(_obj, ",
332 for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
333 IDL_tree parm = IDL_LIST (sub).data;
335 IDL_tree ts = forb_cbe_get_typespec(parm);
338 char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
339 role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
340 n = oidl_param_info (ts, role, &isSlice);
342 fprintf(ci->fh, "%s%s, ", n?"&":"", name);
344 fprintf(ci->fh, "env);\n");
346 " if (forb_exception_occurred(env)) goto exception;\n");
348 fprintf(ci->fh, " ");
349 forb_cbe_write_typespec(ci->fh, IDL_OP_DCL(op).op_type_spec);
350 fprintf(ci->fh, "_serialize(cout, &_forb_ret);\n");
352 for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
353 IDL_tree parm = IDL_LIST (sub).data;
355 IDL_tree ts = forb_cbe_get_typespec(parm);
358 char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
359 role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
360 n = oidl_param_info (ts, role, &isSlice);
361 if (role == DATA_OUT || role == DATA_INOUT) {
362 fprintf(ci->fh, " ");
363 forb_cbe_write_typespec(ci->fh, IDL_PARAM_DCL(parm).param_type_spec);
364 fprintf(ci->fh, "_serialize(cout, %s%s);\n", n==2?"":"&", name);
367 fprintf(ci->fh, "exception:;\n");
369 /* Free all dynamically allocated parameteres and retvals */
371 free_memory_if_needed(IDL_OP_DCL(op).op_type_spec, "_forb_ret", 0, ci);
373 for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
374 IDL_tree parm = IDL_LIST (sub).data;
375 char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
377 IDL_tree ts = forb_cbe_get_typespec(parm);
380 role = oidl_attr_to_paramrole(IDL_PARAM_DCL(parm).attr);
381 n = oidl_param_info (ts, role, &isSlice);
382 free_memory_if_needed(IDL_PARAM_DCL(parm).param_type_spec, name, n, ci);
385 fprintf(ci->fh, " } else {\n");
386 fprintf(ci->fh, " env->major = FORB_EX_NO_IMPLEMENT;\n");
387 fprintf(ci->fh, " }\n");
388 fprintf(ci->fh, "}\n\n");
393 cbe_skel_do_interface(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
399 //CBESkelVEPVMapTraverseInfo ti;
402 /* PIDL methods dont have normal skel functions. */
403 for ( pnt=tree; pnt; pnt=IDL_NODE_UP(pnt) ) {
404 if ( pnt->declspec & IDLF_DECLSPEC_PIDL )
408 id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(tree).ident), "_", 0);
410 fprintf(ci->fh, "#define _%s_impl(obj) ((struct forb_%s_impl*)(obj)->implementation)\n\n", id, id);
411 fprintf(ci->fh, "static const struct forb_interface %s_interface;\n\n", id);
413 for(sub = IDL_INTERFACE(tree).body; sub; sub = IDL_LIST(sub).next) {
414 IDL_tree cur = IDL_LIST(sub).data;
416 switch(IDL_NODE_TYPE(cur)) {
418 ck_output_op_skel(cur, id, rinfo, ci);
426 fprintf(ci->fh, "static const forb_skel_func %s_skeletons[%d] = {\n",
428 for(sub = IDL_INTERFACE(tree).body; sub; sub = IDL_LIST(sub).next) {
429 IDL_tree cur = IDL_LIST(sub).data;
431 switch(IDL_NODE_TYPE(cur)) {
434 op_id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(cur).ident), "_", 0);
435 fprintf(ci->fh, " forb_skel_%s,\n", op_id);
443 fprintf(ci->fh, "};\n\n");
445 fprintf(ci->fh, "static const struct forb_interface %s_interface = {\n", id);
446 fprintf(ci->fh, " .name = \"%s\",\n", id);
447 fprintf(ci->fh, " .num_methods = %d,\n", num_methods);
448 fprintf(ci->fh, " .skeletons = %s_skeletons,\n", id);
449 fprintf(ci->fh, " .type_hash = 0 /* not implemented */\n");
450 fprintf(ci->fh, "};\n\n");
452 /* fprintf(ci->fh, "void forb_register_%s_interface(void)\n" */
454 /* " forb_register_interface(&%s_interface);\n" */
455 /* "}\n\n", id, id); */
457 fprintf(ci->fh, "%s forb_%s_new(forb_orb orb, const struct forb_%s_impl *impl,"
458 "void *instance_data)\n"
460 " %s obj = forb_object_new(orb, NULL, 0);\n"
462 " obj->instance_data = instance_data;\n"
463 " obj->implementation = impl;\n"
464 " obj->interface = &%s_interface;\n"
467 "}\n\n", id, id, id, id, id);
468 fprintf(ci->fh, "\n");
471 /* cbe_skel_interface_print_relayer(tree, rinfo, ci); */
473 /* fprintf(ci->fh, */
474 /* "void POA_%s__init(PortableServer_Servant servant,\nCORBA_Environment *env)\n", */
476 /* fprintf(ci->fh, "{\n"); */
477 /* fprintf(ci->fh," static PortableServer_ClassInfo class_info = {"); */
479 /* fprintf(ci->fh, "NULL, (Forb_small_impl_finder)&get_skel_small_%s, ", id); */
481 /* fprintf(ci->fh,"\"%s\", &%s__classid, NULL, &%s__iinterface};\n", */
482 /* IDL_IDENT(IDL_INTERFACE(tree).ident).repo_id, id, id); */
484 /* fprintf(ci->fh," PortableServer_ServantBase__init (" */
485 /* " ((PortableServer_ServantBase *)servant), env);\n"); */
487 /* for(curitem = IDL_INTERFACE(tree).inheritance_spec; curitem; */
488 /* curitem = IDL_LIST(curitem).next) { */
489 /* id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_LIST(curitem).data), */
491 /* fprintf(ci->fh, " POA_%s__init(servant, env);\n", id2); */
495 /* registering after other __inits() makes the classids increment nicely. */
496 /* fprintf (ci->fh, " Forb_skel_class_register (&class_info,\n"); */
497 /* fprintf (ci->fh, " (PortableServer_ServantBase *)servant, POA_%s__fini,\n", id); */
498 /* fprintf (ci->fh, " FORB_VEPV_OFFSET (POA_%s__vepv, %s_epv),\n", id, id); */
499 /* ti.for_id = id; ti.ci = ci; */
500 /* IDL_tree_traverse_parents_full (tree, (GFunc) cbe_skel_interface_print_vepvmap_offsets, &ti, FALSE); */
501 /* fprintf (ci->fh, " (CORBA_unsigned_long) 0);"); */
503 /* fprintf(ci->fh, "}\n\n"); */
505 /* fprintf(ci->fh, */
506 /* "void POA_%s__fini(PortableServer_Servant servant,\nCORBA_Environment *env)\n", */
508 /* fprintf(ci->fh, "{\n"); */
509 /* if(IDL_INTERFACE(tree).inheritance_spec) */
511 /* for(i = IDL_list_length(IDL_INTERFACE(tree).inheritance_spec) - 1; */
513 /* curitem = IDL_list_nth(IDL_INTERFACE(tree).inheritance_spec, i); */
514 /* id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_LIST(curitem).data), */
516 /* /\* XXX fixme - this is going to call ServantBase__fini multiple times *\/ */
517 /* fprintf(ci->fh, " POA_%s__fini(servant, env);\n", */
522 /* fprintf(ci->fh, " PortableServer_ServantBase__fini(servant, env);\n"); */
523 /* fprintf(ci->fh, "}\n\n"); */
529 forb_idl_output_c_skeletons (IDL_tree tree,
530 OIDL_Run_Info *rinfo,
533 fprintf (ci->fh, OIDL_C_WARNING);
534 /* fprintf (ci->fh, "#include <string.h>\n"); */
535 /* fprintf (ci->fh, "#define FORB2_STUBS_API\n"); */
536 fprintf (ci->fh, "#include \"%s.h\"\n\n", ci->base_name);
537 fprintf(ci->fh, "#include <forb/cdr.h>\n");
538 fprintf(ci->fh, "#include <forb/forb-internal.h>\n");
539 fprintf(ci->fh, "#include <forb/object.h>\n\n");
541 ck_output_poastuff (tree, rinfo, ci);