3 #include "forb-idl-c-backend.h"
5 /* This file copied from the old IDL compiler forb-c-skelimpl.c, with minimal changes. */
7 static void forb_cbe_write_skelimpl(FILE *outfile, IDL_tree tree, const char *hdrname);
10 forb_idl_output_c_skelimpl(IDL_tree tree, OIDL_Run_Info *rinfo, OIDL_C_Info *ci)
12 forb_cbe_write_skelimpl(ci->fh, tree, ci->base_name);
25 /* Abbreviations used here:
26 "cbe" stands for "C backend"
27 "hdr" -> "header" (duh :)
35 enum { PASS_SERVANTS, PASS_PROTOS, PASS_EPVS, PASS_VEPVS,
36 PASS_IMPLSTUBS, PASS_LAST } pass;
39 static const char *passnames[] = {
40 "App-specific servant structures",
41 "Implementation stub prototypes",
44 "Stub implementations",
48 static void forb_cbe_ski_process_piece(CBESkelImplInfo *ski);
49 static void cbe_ski_do_list(CBESkelImplInfo *ski);
50 static void cbe_ski_do_inherited_attr_dcl(CBESkelImplInfo *ski, IDL_tree current_interface);
51 static void cbe_ski_do_attr_dcl(CBESkelImplInfo *ski);
52 static void cbe_ski_do_inherited_op_dcl(CBESkelImplInfo *ski, IDL_tree current_interface);
53 static void cbe_ski_do_op_dcl(CBESkelImplInfo *ski);
54 static void cbe_ski_do_param_dcl(CBESkelImplInfo *ski);
55 static void cbe_ski_do_interface(CBESkelImplInfo *ski);
56 static void cbe_ski_do_module(CBESkelImplInfo *ski);
59 forb_cbe_write_skelimpl(FILE *outfile, IDL_tree tree, const char *hdrname)
61 CBESkelImplInfo ski = {NULL, NULL, PASS_SERVANTS};
66 g_return_if_fail(IDL_NODE_TYPE(tree) == IDLN_LIST);
68 fprintf(outfile, "/* This is a template file generated by command */\n");
69 fprintf(outfile, "/* forb-idl-2 --skeleton-impl %s.idl */\n", hdrname);
70 fprintf(outfile, "/* User must edit this file, inserting servant */\n");
71 fprintf(outfile, "/* specific code between markers. */\n\n");
73 fprintf(outfile, "#include \"%s.h\"\n", hdrname);
75 for(ski.pass = PASS_SERVANTS; ski.pass < PASS_LAST; ski.pass++) {
76 fprintf(ski.of, "\n/*** %s ***/\n\n", passnames[ski.pass]);
77 forb_cbe_ski_process_piece(&ski);
82 forb_cbe_ski_process_piece(CBESkelImplInfo *ski)
84 /* I'm not implementing this as an array of function pointers
85 because we may want to do special logic for particular cases in
86 the future. Hope this is clear enough. -ECL */
88 switch(IDL_NODE_TYPE(ski->tree)) {
90 cbe_ski_do_attr_dcl(ski);
93 cbe_ski_do_interface(ski);
99 cbe_ski_do_module(ski);
102 cbe_ski_do_op_dcl(ski);
105 cbe_ski_do_param_dcl(ski);
113 cbe_ski_do_module(CBESkelImplInfo *ski)
115 CBESkelImplInfo subski = *ski;
116 subski.tree = IDL_MODULE(ski->tree).definition_list;
117 cbe_ski_do_list(&subski);
120 /* Returns 1 if the previous character written to f */
121 /* was '\n', 0 otherwise. */
122 static inline unsigned char
123 prev_char_is_nl(FILE *f)
128 unsigned char retv = 0;
131 if (pos < sizeof(char))
132 return 0; /* beginning of file */
134 if (fseek(f, (-1)*sizeof(char), SEEK_CUR))
137 count = fread((void*)&c, sizeof(char), 1, f);
138 if (sizeof(char) == count)
139 retv = ('\n' == c) ? 1 : 0;
142 fseek(f, pos, SEEK_SET);
147 cbe_ski_do_list(CBESkelImplInfo *ski)
149 CBESkelImplInfo subski = *ski;
152 for(curitem = ski->tree; curitem; curitem = IDL_LIST(curitem).next) {
153 subski.tree = IDL_LIST(curitem).data;
154 forb_cbe_ski_process_piece(&subski);
155 if(!prev_char_is_nl(ski->of))
156 fprintf(ski->of, "\n");
161 cbe_ski_do_attr_dcl_internal(CBESkelImplInfo *ski, IDL_tree current_interface, gboolean inherited)
163 IDL_tree curop, curitem;
164 GString *attrname = g_string_new(NULL);
165 CBESkelImplInfo subski = *ski;
167 if(ski->pass == PASS_SERVANTS) {
168 for(curitem = IDL_ATTR_DCL(ski->tree).simple_declarations; curitem;
169 curitem = IDL_LIST(curitem).next) {
170 forb_cbe_write_typespec(ski->of, IDL_ATTR_DCL(ski->tree).param_type_spec);
171 fprintf(ski->of, " attr_%s;\n", IDL_IDENT(IDL_LIST(curitem).data).str);
175 for(curitem = IDL_ATTR_DCL(ski->tree).simple_declarations;
176 curitem; curitem = IDL_LIST(curitem).next) {
178 /* Fake the attribute get/set methods as operation declarations */
179 IDL_tree ident, ns_data_save;
182 for (i = 0; i < 2; ++i) {
184 if (i && IDL_ATTR_DCL(ski->tree).f_readonly)
186 /* Output the operation on this attribute */
187 g_string_printf(attrname, i ? "_set_%s" : "_get_%s",
188 IDL_IDENT(IDL_LIST(curitem).data).str);
189 ident = IDL_ident_new(g_strdup(attrname->str));
191 /* Tell the ident where our namespace node is, and request a return value
192 if this is the _get operation */
193 IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(IDL_LIST(curitem).data);
194 curop = IDL_op_dcl_new(0, i == 0 ?
195 IDL_ATTR_DCL(ski->tree).param_type_spec : NULL,
196 ident, NULL, NULL, NULL);
198 curop->up = ski->tree->up;
201 /* Save the namespace ident (IDL_GENTREE data) reference, assign
202 back to the temporary tree, output the operation, then restore
203 the namespace ident link */
204 ns_data_save = IDL_GENTREE(IDL_IDENT_TO_NS(IDL_LIST(curitem).data)).data;
205 IDL_GENTREE(IDL_IDENT_TO_NS(IDL_LIST(curitem).data)).data = ident;
208 /* The set routine also needs the value, so we
209 temporarily add that to the operation
211 IDL_OP_DCL(curop).parameter_dcls = IDL_list_new(
212 IDL_param_dcl_new(IDL_PARAM_IN,
213 IDL_ATTR_DCL(ski->tree).param_type_spec,
214 IDL_ident_new(g_strdup("value"))));
218 cbe_ski_do_inherited_op_dcl(&subski, current_interface);
220 forb_cbe_ski_process_piece(&subski);
222 /* Restore the fake link to the original in the namespace */
223 IDL_GENTREE(IDL_IDENT_TO_NS(IDL_LIST(curitem).data)).data = ns_data_save;
226 /* Free only what we've created for the fake node, so remove
227 the attribute node element and then free the rest */
228 IDL_PARAM_DCL(IDL_LIST(
229 IDL_OP_DCL(curop).parameter_dcls).data).param_type_spec = NULL;
232 /* Remove what we've "borrowed" from ATTR_DCL from the
233 fake curop node then free the rest */
234 IDL_OP_DCL(curop).op_type_spec = NULL;
235 IDL_tree_free(curop);
239 g_string_free(attrname, TRUE);
243 cbe_ski_do_attr_dcl(CBESkelImplInfo *ski)
245 cbe_ski_do_attr_dcl_internal(ski, NULL, FALSE);
249 cbe_ski_do_inherited_attr_dcl(CBESkelImplInfo *ski, IDL_tree current_interface)
251 cbe_ski_do_attr_dcl_internal(ski, current_interface, TRUE);
255 cbe_ski_do_op_dcl(CBESkelImplInfo *ski)
257 /* If you fix anything here, please also fix it in
258 cbe_ski_do_inherited_op_dcl(), which is almost a
259 cut-and-paste of this routine */
262 IDL_tree curitem, op;
264 CBESkelImplInfo subski = *ski;
269 curitem = IDL_get_parent_node(ski->tree, IDLN_INTERFACE, &level);
272 id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(ski->tree).ident), "_", 0);
273 id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(curitem).ident), "_", 0);
275 /* protect with #ifdef block */
276 if(PASS_PROTOS == ski->pass)
277 fprintf(ski->of, "#if !defined(_decl_impl_");
279 fprintf(ski->of, "#if !defined(_impl_");
280 fprintf(ski->of, "%s_)\n", id);
282 if(PASS_PROTOS == ski->pass)
283 fprintf(ski->of, "#define _decl_impl_");
285 fprintf(ski->of, "#define _impl_");
286 fprintf(ski->of, "%s_ 1\n", id);
288 fprintf(ski->of, "static ");
289 forb_cbe_write_param_typespec(ski->of, ski->tree);
290 fprintf(ski->of, "\nimpl_%s(impl_POA_%s *servant,\n", id, id2);
291 g_free(id); g_free(id2);
294 for(curitem = IDL_OP_DCL(ski->tree).parameter_dcls;
295 curitem; curitem = IDL_LIST(curitem).next) {
296 subski.tree = IDL_LIST(curitem).data;
297 forb_cbe_ski_process_piece(&subski);
300 if(IDL_OP_DCL(op).context_expr)
301 fprintf(ski->of, "CORBA_Context ctx,\n");
303 fprintf(ski->of, "CORBA_Environment *ev)");
304 if(ski->pass == PASS_IMPLSTUBS) {
305 fprintf(ski->of, "\n{\n");
306 if(IDL_OP_DCL(op).op_type_spec) {
307 forb_cbe_write_param_typespec(ski->of, ski->tree);
308 fprintf(ski->of, " retval;\n");
309 fprintf(ski->of, " /* ------ insert method code here ------ */\n");
310 fprintf(ski->of, " /* ------ ---------- end ------------ ------ */\n");
311 fprintf(ski->of, "\nreturn retval;\n");
315 fprintf(ski->of, " /* ------ insert method code here ------ */\n");
316 fprintf(ski->of, " /* ------ ---------- end ------------ ------ */\n");
318 fprintf(ski->of, "}\n");
319 } else /* PASS_PROTOS */
320 fprintf(ski->of, ";\n");
322 fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
323 break; /* End PASS_PROTOS | PASS_IMPLSTUBS */
325 id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_OP_DCL(ski->tree).ident), "_", 0);
326 fprintf(ski->of, "(gpointer)&impl_%s,\n", id);
335 cbe_ski_do_inherited_op_dcl(CBESkelImplInfo *ski, IDL_tree current_interface)
338 IDL_tree ident, curitem, intf, op;
340 CBESkelImplInfo subski = *ski;
342 id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(current_interface).ident), "_", 0);
343 intf = IDL_get_parent_node(ski->tree, IDLN_INTERFACE, NULL);
344 id2 = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(intf).ident), "_", 0);
346 ident=IDL_OP_DCL(ski->tree).ident;
352 curitem = IDL_get_parent_node(ski->tree, IDLN_INTERFACE, &level);
355 /* protect with #ifdef block */
356 if(PASS_PROTOS == ski->pass)
357 fprintf(ski->of, "#if !defined(_decl_impl_");
359 fprintf(ski->of, "#if !defined(_impl_");
360 fprintf(ski->of, "%s_%s_)\n", id, IDL_IDENT(ident).str);
362 if(PASS_PROTOS == ski->pass)
363 fprintf(ski->of, "#define _decl_impl_");
365 fprintf(ski->of, "#define _impl_");
366 fprintf(ski->of, "%s_%s_ 1\n", id, IDL_IDENT(ident).str);
368 fprintf(ski->of, "static ");
369 forb_cbe_write_param_typespec(ski->of, ski->tree);
370 fprintf(ski->of, "\nimpl_%s_%s(impl_POA_%s *servant,\n", id, IDL_IDENT(ident).str, id);
373 for(curitem = IDL_OP_DCL(ski->tree).parameter_dcls;
374 curitem; curitem = IDL_LIST(curitem).next) {
375 subski.tree = IDL_LIST(curitem).data;
376 forb_cbe_ski_process_piece(&subski);
379 if(IDL_OP_DCL(op).context_expr)
380 fprintf(ski->of, "CORBA_Context ctx,\n");
382 fprintf(ski->of, "CORBA_Environment *ev)");
383 if(ski->pass == PASS_IMPLSTUBS) {
384 fprintf(ski->of, "\n{\n");
385 if(IDL_OP_DCL(op).op_type_spec) {
386 forb_cbe_write_param_typespec(ski->of, ski->tree);
387 fprintf(ski->of, " retval;\n");
388 fprintf(ski->of, " /* ------ insert method code here ------ */\n");
389 fprintf(ski->of, " /* ------ ---------- end ------------ ------ */\n");
390 fprintf(ski->of, "\nreturn retval;\n");
394 fprintf(ski->of, " /* ------ insert method code here ------ */\n");
395 fprintf(ski->of, " /* ------ ---------- end ------------ ------ */\n");
397 fprintf(ski->of, "}\n");
398 } else /* PASS_PROTOS */
399 fprintf(ski->of, ";\n");
401 fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
402 break; /* End PASS_PROTOS | PASS_IMPLSTUBS */
404 ident=IDL_OP_DCL(ski->tree).ident;
407 fprintf(ski->of, "(gpointer)&impl_%s_%s,\n", id, IDL_IDENT(ident).str);
417 cbe_ski_do_param_dcl(CBESkelImplInfo *ski)
419 forb_cbe_write_param_typespec(ski->of, ski->tree);
420 fprintf(ski->of, " %s,\n", IDL_IDENT(IDL_PARAM_DCL(ski->tree).simple_declarator).str);
424 cbe_ski_do_interface_vepv_entry(IDL_tree interface, CBESkelImplInfo *ski)
426 char *id, *inherit_id;
428 if(interface==ski->tree) {
429 id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident), "_", 0);
430 fprintf(ski->of, "&impl_%s_epv,\n", id);
435 id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident), "_", 0);
436 inherit_id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(interface).ident),
438 fprintf(ski->of, "&impl_%s_%s_epv,\n", id, inherit_id);
445 cbe_ski_do_inherited_methods(IDL_tree interface, CBESkelImplInfo *ski)
447 CBESkelImplInfo subski= *ski;
449 char *id = NULL, *inherit_id = NULL; /* Quiet gcc */
451 if(interface==ski->tree)
454 if(ski->pass==PASS_EPVS) {
455 id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident),
457 inherit_id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(interface).ident),
459 /* protect with #ifdef block */
460 fprintf(ski->of, "#if !defined(_impl_%s_%s_epv_)\n", id, inherit_id);
461 fprintf(ski->of, "#define _impl_%s_%s_epv_ 1\n", id, inherit_id);
462 fprintf(ski->of, "static POA_%s__epv impl_%s_%s_epv = {\nNULL, /* _private */\n", inherit_id, id, inherit_id);
465 for(curitem = IDL_INTERFACE(interface).body; curitem; curitem=IDL_LIST(curitem).next) {
466 subski.tree=IDL_LIST(curitem).data;
468 switch(IDL_NODE_TYPE(IDL_LIST(curitem).data)) {
470 cbe_ski_do_inherited_op_dcl(&subski, ski->tree);
473 cbe_ski_do_inherited_attr_dcl(&subski, ski->tree);
480 if(ski->pass==PASS_EPVS) {
481 fprintf(ski->of, "};\n");
482 fprintf(ski->of, "#endif\n"); /* end of protective #ifdef block */
490 cbe_ski_do_interface(CBESkelImplInfo *ski)
493 CBESkelImplInfo subski = *ski;
495 id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ski->tree).ident), "_", 0);
499 /* protect with #ifdef block */
500 fprintf(ski->of, "#if !defined(_typedef_impl_POA_%s_)\n", id);
501 fprintf(ski->of, "#define _typedef_impl_POA_%s_ 1\n", id);
503 fprintf(ski->of, "typedef struct {\nPOA_%s servant;\nPortableServer_POA poa;\n", id);
504 subski.tree = IDL_INTERFACE(ski->tree).body;
505 cbe_ski_do_list(&subski);
506 IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_inherited_methods, ski);
507 fprintf(ski->of, " /* ------ add private attributes here ------ */\n");
508 fprintf(ski->of, " /* ------ ---------- end ------------ ------ */\n");
509 fprintf(ski->of, "} impl_POA_%s;\n", id);
511 fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
514 /* protect with #ifdef block */
515 fprintf(ski->of, "#if !defined(_impl_%s_base_epv_)\n", id);
516 fprintf(ski->of, "#define _impl_%s_base_epv_ 1\n", id);
517 fprintf(ski->of, "static PortableServer_ServantBase__epv impl_%s_base_epv = {\n", id);
518 fprintf(ski->of, "NULL, /* _private data */\n");
519 fprintf(ski->of, "(gpointer) & impl_%s__destroy, /* finalize routine */\n", id);
520 fprintf(ski->of, "NULL, /* default_POA routine */\n");
521 fprintf(ski->of, "};\n");
522 fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
524 /* protect with #ifdef block */
525 fprintf(ski->of, "#if !defined(_impl_%s_epv_)\n", id);
526 fprintf(ski->of, "#define _impl_%s_epv_ 1\n", id);
527 fprintf(ski->of, "static POA_%s__epv impl_%s_epv = {\nNULL, /* _private */\n", id, id);
528 subski.tree = IDL_INTERFACE(ski->tree).body;
529 cbe_ski_do_list(&subski);
530 fprintf(ski->of, "};\n");
531 fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
533 IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_inherited_methods, ski);
536 /* protect with #ifdef block */
537 fprintf(ski->of, "#if !defined(_impl_%s_vepv_)\n", id);
538 fprintf(ski->of, "#define _impl_%s_vepv_ 1\n", id);
540 fprintf(ski->of, "static POA_%s__vepv impl_%s_vepv = {\n", id, id);
541 fprintf(ski->of, "&impl_%s_base_epv,\n", id);
542 IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_interface_vepv_entry, ski);
543 fprintf(ski->of, "};\n");
545 fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
548 /* protect __create with #ifdef block */
549 fprintf(ski->of, "#if !defined(_impl_%s__create_)\n", id);
550 fprintf(ski->of, "#define _impl_%s__create_ 1\n", id);
551 fprintf(ski->of, "static %s impl_%s__create(PortableServer_POA poa, CORBA_Environment *ev)\n", id, id);
552 fprintf(ski->of, "{\n%s retval;\nimpl_POA_%s *newservant;\nPortableServer_ObjectId *objid;\n\n", id, id);
553 fprintf(ski->of, "newservant = g_new0(impl_POA_%s, 1);\n", id);
554 fprintf(ski->of, "newservant->servant.vepv = &impl_%s_vepv;\n", id);
555 fprintf(ski->of, "newservant->poa = (PortableServer_POA) CORBA_Object_duplicate((CORBA_Object)poa, ev);\n");
556 fprintf(ski->of, "POA_%s__init((PortableServer_Servant)newservant, ev);\n", id);
557 fprintf(ski->of, " /* Before servant is going to be activated all\n");
558 fprintf(ski->of, " * private attributes must be initialized. */\n");
559 fprintf(ski->of, "\n");
560 fprintf(ski->of, " /* ------ init private attributes here ------ */\n");
561 fprintf(ski->of, " /* ------ ---------- end ------------- ------ */\n");
562 fprintf(ski->of, "\n");
563 fprintf(ski->of, "objid = PortableServer_POA_activate_object(poa, newservant, ev);\n");
564 fprintf(ski->of, "CORBA_free(objid);\n");
565 fprintf(ski->of, "retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);\n");
566 fprintf(ski->of, "\nreturn retval;\n}\n");
567 fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
569 /* protect __destroy with #ifdef block */
570 fprintf(ski->of, "#if !defined(_impl_%s__destroy_)\n", id);
571 fprintf(ski->of, "#define _impl_%s__destroy_ 1\n", id);
572 fprintf(ski->of, "static void\nimpl_%s__destroy(impl_POA_%s *servant, CORBA_Environment *ev)\n{\n", id, id);
573 fprintf(ski->of, " CORBA_Object_release ((CORBA_Object) servant->poa, ev);\n\n");
574 fprintf(ski->of, " /* No further remote method calls are delegated to \n");
575 fprintf(ski->of, " * servant and you may free your private attributes. */\n");
576 fprintf(ski->of, " /* ------ free private attributes here ------ */\n");
577 fprintf(ski->of, " /* ------ ---------- end ------------- ------ */\n");
578 fprintf(ski->of, "\nPOA_%s__fini((PortableServer_Servant)servant, ev);\n", id);
579 fprintf(ski->of, "\ng_free (servant);\n");
580 fprintf(ski->of, "}\n");
581 fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
583 subski.tree = IDL_INTERFACE(ski->tree).body;
584 cbe_ski_do_list(&subski);
585 IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_inherited_methods, ski);
588 /* protect __destroy declaration with #ifdef block */
589 fprintf(ski->of, "#if !defined(_decl_impl_%s__destroy_)\n", id);
590 fprintf(ski->of, "#define _decl_impl_%s__destroy_ 1\n", id);
591 fprintf(ski->of, "static void impl_%s__destroy(impl_POA_%s *servant,\nCORBA_Environment *ev);\n", id, id);
592 fprintf(ski->of, "#endif\n\n"); /* end of protective #ifdef block */
594 subski.tree = IDL_INTERFACE(ski->tree).body;
595 cbe_ski_do_list(&subski);
596 IDL_tree_traverse_parents(ski->tree, (GFunc)&cbe_ski_do_inherited_methods, ski);