source: trunk/ORBit2-2.14.0/src/idl-compiler/orbit-idl-c-stubs.c

Last change on this file was 211, checked in by cinc, 19 years ago

Output default headers into c-template file.

File size: 16.2 KB
Line 
1#include "config.h"
2#include "orbit-idl-c-backend.h"
3#include <string.h>
4
5typedef struct {
6 FILE *of;
7 IDL_tree realif;
8 char* chrOverridenMethodName;
9 char* chrClassName;
10} InheritedOutputInfo2;
11
12static void
13VoyagerOutputOverridenMethodTemplate(IDL_tree curif, InheritedOutputInfo2 *ioi)
14{
15 char *id, *realid;
16 IDL_tree curitem;
17 char* overridenMethodName;
18
19 if(curif == ioi->realif)
20 return;
21
22 overridenMethodName=ioi->chrOverridenMethodName;
23
24
25 realid = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(ioi->realif).ident), "_", 0);
26
27 id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_INTERFACE(curif).ident), "_", 0);
28
29
30 for(curitem = IDL_INTERFACE(curif).body; curitem; curitem = IDL_LIST(curitem).next) {
31 IDL_tree curop = IDL_LIST(curitem).data;
32
33 switch(IDL_NODE_TYPE(curop)) {
34 case IDLN_OP_DCL:
35 {
36 /* Check if the current method (introduced by some parent) is the one to be
37 overriden. */
38 if(!strcmp(overridenMethodName, IDL_IDENT(IDL_OP_DCL(curop).ident).str)){
39 fprintf(ioi->of, "/* Call parent */\n");
40
41 fprintf(ioi->of, "/* %s_%s_parent_resolved()*/\n",
42 realid, IDL_IDENT(IDL_OP_DCL(curop).ident).str);
43
44#if 0
45 fprintf(ioi->of, "#define %s_%s() \\\n %s_%s()\n",
46 realid, IDL_IDENT(IDL_OP_DCL(curop).ident).str,
47 id, IDL_IDENT(IDL_OP_DCL(curop).ident).str);
48#endif
49 }
50 break;
51 }
52 default:
53 break;
54 }
55 }
56
57 g_free(id);
58 g_free(realid);
59
60}
61
62static
63void VoyagerWriteParamsForParentCall(IDL_tree curif, InheritedOutputInfo2 *ioi)
64{
65 IDL_tree curitem;
66 char* overridenMethodName;
67
68 if(curif == ioi->realif)
69 return;
70
71 overridenMethodName=ioi->chrOverridenMethodName;
72
73 for(curitem = IDL_INTERFACE(curif).body; curitem; curitem = IDL_LIST(curitem).next) {
74 IDL_tree curop = IDL_LIST(curitem).data;
75
76 switch(IDL_NODE_TYPE(curop)) {
77 case IDLN_OP_DCL:
78 {
79 /* Check if the current method (introduced by some parent) is the one to be
80 overriden. */
81 if(!strcmp(overridenMethodName, IDL_IDENT(IDL_OP_DCL(curop).ident).str)){
82 IDL_tree sub;
83
84 for (sub = IDL_OP_DCL (curop).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
85 IDL_tree parm = IDL_LIST (sub).data;
86 fprintf (ioi->of, "%s, ", IDL_IDENT (IDL_PARAM_DCL (parm).simple_declarator).str);
87 }
88 }
89 break;
90 }
91 default:
92 break;
93 }
94 }
95}
96
97static void
98VoyagerWriteProtoForParentCall (FILE *of,
99 IDL_tree op,
100 const char *nom_prefix,
101 gboolean for_epv)
102{
103 char *id;
104 char * id2;
105 char * ptr;
106 IDL_tree tmptree;
107
108 g_assert (IDL_NODE_TYPE(op) == IDLN_OP_DCL);
109
110 // orbit_cbe_write_param_typespec (of, op);
111
112 id = IDL_ns_ident_to_qstring (
113 IDL_IDENT_TO_NS (IDL_INTERFACE (
114 IDL_get_parent_node (op, IDLN_INTERFACE, NULL)).ident), "_", 0);
115
116 id2=g_strdup(IDL_IDENT (IDL_OP_DCL (op).ident).str);
117 if((ptr=strstr(id2, NOM_OVERRIDE_STRING))!=NULL)
118 *ptr='\0';
119 fprintf (of, " /* %s, %s line %d */\n", __FILE__, __FUNCTION__, __LINE__);
120 fprintf (of, " %s%s_%s_parent", nom_prefix ? nom_prefix : "",
121 id, id2);
122
123 fprintf (of, "(");
124 fprintf (of, "nomSelf, ");
125
126 tmptree = IDL_get_parent_node(op, IDLN_INTERFACE, NULL);
127
128 if(IDL_INTERFACE(tmptree).inheritance_spec) {
129 InheritedOutputInfo2 ioi;
130
131 ioi.of = of;
132 ioi.realif = tmptree;
133 ioi.chrOverridenMethodName=id2;
134 ioi.chrOverridenMethodName="";
135 IDL_tree_traverse_parents(IDL_INTERFACE(tmptree).inheritance_spec, (GFunc)VoyagerWriteParamsForParentCall, &ioi);
136 }
137
138 g_free(id2);
139 g_free (id);
140 fprintf (of, " ev);\n");
141}
142
143/*
144 This function is called for each parent to check if the current parent introduced the
145 overriden method. If yes, the parameter info is taken from this parent and put into the
146 file.
147 */
148static
149void VoyagerDoWriteParamsForOverridenMethod(IDL_tree curif, InheritedOutputInfo2 *ioi)
150{
151 IDL_tree curitem;
152 char* overridenMethodName;
153
154 if(curif == ioi->realif)
155 return;
156
157 overridenMethodName=ioi->chrOverridenMethodName;
158
159 for(curitem = IDL_INTERFACE(curif).body; curitem; curitem = IDL_LIST(curitem).next) {
160 IDL_tree curop = IDL_LIST(curitem).data;
161
162 switch(IDL_NODE_TYPE(curop)) {
163 case IDLN_OP_DCL:
164 {
165 /* Check if the current method (introduced by some parent) is the one to be
166 overriden. */
167 if(!strcmp(overridenMethodName, IDL_IDENT(IDL_OP_DCL(curop).ident).str)){
168 IDL_tree sub;
169
170 g_assert (IDL_NODE_TYPE(curop) == IDLN_OP_DCL);
171
172 /* return typespec */
173 orbit_cbe_write_param_typespec (ioi->of, curop);
174
175 /* The methodname */
176 fprintf (ioi->of, " %s%s_%s", "NOMLINK impl_",
177 ioi->chrClassName, overridenMethodName);
178
179 fprintf (ioi->of, "(%s* nomSelf, ", ioi->chrClassName);
180
181 /* Write the params including the typespec */
182 for (sub = IDL_OP_DCL (curop).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
183 IDL_tree parm = IDL_LIST (sub).data;
184
185 orbit_cbe_write_param_typespec (ioi->of, parm);
186
187 fprintf (ioi->of, " %s, ", IDL_IDENT (IDL_PARAM_DCL (parm).simple_declarator).str);
188 }
189
190 if (IDL_OP_DCL (curop).context_expr)
191 fprintf (ioi->of, "CORBA_Context _ctx, ");
192
193 fprintf (ioi->of, "CORBA_Environment *ev)");
194 }
195 break;
196 }
197 default:
198 break;
199 }
200 }
201}
202
203/*
204 Overriden methods are introduced by some parent class. This function gets the parent node and
205 climbs down the list of classes to find the one introducing the method. A support function called
206 for every node while traversing actually writes the info.
207*/
208static void
209VoyagerWriteParamsForOverridenMethod(FILE *of,
210 IDL_tree op,
211 const char *nom_prefix,
212 gboolean for_epv)
213{
214 char *id;
215 char * id2;
216 char * ptr;
217 IDL_tree tmptree;
218
219 g_assert (IDL_NODE_TYPE(op) == IDLN_OP_DCL);
220
221 id = IDL_ns_ident_to_qstring (
222 IDL_IDENT_TO_NS (IDL_INTERFACE (
223 IDL_get_parent_node (op, IDLN_INTERFACE, NULL)).ident), "_", 0);
224
225 id2=g_strdup(IDL_IDENT (IDL_OP_DCL (op).ident).str);
226 if((ptr=strstr(id2, NOM_OVERRIDE_STRING))!=NULL)
227 *ptr='\0';
228
229 tmptree = IDL_get_parent_node(op, IDLN_INTERFACE, NULL);
230
231 if(IDL_INTERFACE(tmptree).inheritance_spec) {
232 InheritedOutputInfo2 ioi;
233
234 ioi.of = of;
235 ioi.realif = tmptree;
236 ioi.chrOverridenMethodName=id2;
237 ioi.chrClassName=id; /* The current class name. In the called function the parent is searched introducing the method.
238 When this parent is found, the current class info isn't easy to get again but it's needed. */
239 IDL_tree_traverse_parents(IDL_INTERFACE(tmptree).inheritance_spec, (GFunc)VoyagerDoWriteParamsForOverridenMethod, &ioi);
240 }
241 g_free(id2);
242 g_free (id);
243}
244
245
246static void
247cs_output_stub (IDL_tree tree,
248 OIDL_C_Info *ci,
249 int *idx)
250{
251 FILE *of = ci->fh;
252 char *iface_id;
253 char *opname;
254 gboolean has_retval, has_args;
255 g_return_if_fail (idx != NULL);
256 iface_id = IDL_ns_ident_to_qstring (
257 IDL_IDENT_TO_NS (IDL_INTERFACE (
258 IDL_get_parent_node (tree, IDLN_INTERFACE, NULL)
259 ).ident), "_", 0);
260 opname = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (IDL_OP_DCL (tree).ident), "_", 0);
261 has_retval = IDL_OP_DCL (tree).op_type_spec != NULL;
262 has_args = IDL_OP_DCL (tree).parameter_dcls != NULL;
263#ifdef USE_LIBIDL_CODE
264 orbit_cbe_op_write_proto (of, tree, "", FALSE);
265 fprintf (of, "{\n");
266
267 if (has_retval) {
268 orbit_cbe_write_param_typespec (of, tree);
269 fprintf (of, " " ORBIT_RETVAL_VAR_NAME ";\n");
270 }
271 fprintf (ci->fh, "POA_%s__epv *%s;\n", iface_id, ORBIT_EPV_VAR_NAME);
272 fprintf (ci->fh, "gpointer _ORBIT_servant;\n");
273 /* in-proc part */
274 fprintf (ci->fh, "if ((%s = ORBit_c_stub_invoke\n", ORBIT_EPV_VAR_NAME);
275 fprintf (ci->fh, " (_obj, %s__classid, &_ORBIT_servant,\n", iface_id);
276 fprintf (ci->fh, " G_STRUCT_OFFSET (POA_%s__epv, %s)))) {\n",
277 iface_id, IDL_IDENT (IDL_OP_DCL (tree).ident).str);
278 fprintf (ci->fh, "if (ORBit_small_flags & ORBIT_SMALL_FAST_LOCALS && \n");
279 fprintf (ci->fh, " ORBIT_STUB_IsBypass (_obj, %s__classid) && \n", iface_id);
280 fprintf (ci->fh, " (%s = (POA_%s__epv*) ORBIT_STUB_GetEpv (_obj, %s__classid))->%s) {\n",
281 ORBIT_EPV_VAR_NAME, iface_id, iface_id, IDL_IDENT (IDL_OP_DCL (tree).ident).str);
282 fprintf (ci->fh, "ORBIT_STUB_PreCall (_obj);\n");
283 fprintf (ci->fh, "%s%s->%s (_ORBIT_servant, ",
284 IDL_OP_DCL (tree).op_type_spec? ORBIT_RETVAL_VAR_NAME " = ":"",
285 ORBIT_EPV_VAR_NAME,
286 IDL_IDENT (IDL_OP_DCL (tree).ident).str);
287 for (node = IDL_OP_DCL (tree).parameter_dcls; node; node = IDL_LIST (node).next)
288 fprintf (ci->fh, "%s, ",
289 IDL_IDENT (IDL_PARAM_DCL (IDL_LIST (node).data).simple_declarator).str);
290 if (IDL_OP_DCL (tree).context_expr)
291 fprintf (ci->fh, "_ctx, ");
292 fprintf (ci->fh, "ev);\n");
293 fprintf (ci->fh, "ORBit_stub_post_invoke (_obj, %s);\n", ORBIT_EPV_VAR_NAME);
294 fprintf (of, " } else { /* remote marshal */\n");
295
296 /* remote invocation part */
297 if (has_args)
298 orbit_cbe_flatten_args (tree, of, "_args");
299 fprintf (of, "ORBit_c_stub_invoke (_obj, "
300 "&%s__iinterface.methods, %d, ", iface_id, *idx);
301 if (has_retval)
302 fprintf (of, "&_ORBIT_retval, ");
303 else
304 fprintf (of, "NULL, ");
305 if (has_args)
306 fprintf (of, "_args, ");
307 else
308 fprintf (of, "NULL, ");
309 if (IDL_OP_DCL (tree).context_expr)
310 fprintf (ci->fh, "_ctx, ");
311 else
312 fprintf (ci->fh, "NULL, ");
313
314 fprintf (of, "ev, ");
315 fprintf (of, "%s__classid, G_STRUCT_OFFSET (POA_%s__epv, %s),\n",
316 iface_id, iface_id, IDL_IDENT (IDL_OP_DCL (tree).ident).str);
317 fprintf (of, "(ORBitSmallSkeleton) _ORBIT_skel_small_%s);\n\n", opname);
318 if (has_retval)
319 fprintf (of, "return " ORBIT_RETVAL_VAR_NAME ";\n");
320 fprintf (of, "}\n");
321#else
322 /*** This is Voyager stuff... ***/
323 if(strstr(opname, NOM_INSTANCEVAR_STRING)==NULL &&
324 strstr(opname, NOM_OVERRIDE_STRING)==NULL)
325 {
326 /* Skip specially marked methods containing "__INSTANCEVAR__ */
327 fprintf (of, "NOM_Scope ");
328 orbit_cbe_op_write_proto (of, tree, "NOMLINK impl_", FALSE);
329 fprintf (of, "\n{\n");
330 fprintf (of, "/* %sData* nomThis=%sGetData(nomSelf); */\n",
331 iface_id, iface_id);
332 if (has_retval) {
333 fprintf (of, " ");
334 orbit_cbe_write_param_typespec (of, tree);
335 fprintf (of, " " ORBIT_RETVAL_VAR_NAME ";\n\n");
336
337 fprintf (of, " return " ORBIT_RETVAL_VAR_NAME ";\n");
338 }
339 else
340 fprintf (of, "\n"); /* Beautyfication... */
341
342 fprintf (of, "}\n\n");
343 }
344 if(strstr(opname, NOM_OVERRIDE_STRING)!=NULL)
345 {
346 /* There's an overriden method here */
347 fprintf (of, "\n/* %s, %s line %d */\n", __FILE__, __FUNCTION__, __LINE__);
348 fprintf (of, "NOM_Scope ");
349
350 VoyagerWriteParamsForOverridenMethod (of, tree, "", FALSE);
351
352 fprintf (of, "\n{\n");
353 fprintf (of, "/* %sData* nomThis=%sGetData(nomSelf); */\n",
354 iface_id, iface_id);
355 if (has_retval) {
356 fprintf (of, " ");
357 orbit_cbe_write_param_typespec (of, tree);
358 fprintf (of, " " ORBIT_RETVAL_VAR_NAME ";\n\n");
359
360 fprintf (of, " return " ORBIT_RETVAL_VAR_NAME ";\n");
361 }
362 else
363 fprintf (of, "\n"); /* Beautyfication... */
364
365 fprintf (of, "#if 0\n");
366 if (has_retval)
367 fprintf (of, " return ");
368 VoyagerWriteProtoForParentCall (of, tree, "", FALSE);
369
370 fprintf (of, "#endif\n");
371#if 0
372 /* Inherited */
373 tmptree = IDL_get_parent_node(tree, IDLN_INTERFACE, NULL);;
374 if(IDL_INTERFACE(tmptree).inheritance_spec) {
375 char * ptr=opname;
376 char * str;
377
378 printf("!!!! %s\n", opname);
379 InheritedOutputInfo ioi;
380 ioi.of = ci->fh;
381 ioi.realif = tmptree;
382
383 // str= IDL_ns_ident_to_qstring( IDL_IDENT_TO_NS (IDL_INTERFACE(tree).ident), "_", 0);
384
385 if((ptr=strchr(opname, '_'))!=NULL)
386 ptr++;
387 str=g_strdup(ptr);
388 if((ptr=strchr(str, '_'))!=NULL)
389 *ptr='\0';
390
391 ioi.chrOverridenMethodName=str;
392 IDL_tree_traverse_parents(IDL_INTERFACE(tmptree).inheritance_spec, (GFunc)VoyagerOutputOverridenMethodTemplate, &ioi);
393 if(NULL!=ptr)
394 *ptr='_';
395 }
396#endif
397
398 fprintf (of, "}\n\n");
399 }
400#endif
401
402 g_free (iface_id);
403 (*idx)++;
404}
405
406
407static void
408cs_output_stubs (IDL_tree tree,
409 OIDL_C_Info *ci,
410 int *idx)
411{
412 if (!tree)
413 return;
414 switch (IDL_NODE_TYPE (tree)) {
415 case IDLN_MODULE:
416 cs_output_stubs (IDL_MODULE (tree).definition_list, ci, idx);
417 break;
418 case IDLN_LIST: {
419 IDL_tree sub;
420 for (sub = tree; sub; sub = IDL_LIST (sub).next)
421 cs_output_stubs (IDL_LIST (sub).data, ci, idx);
422 break;
423 }
424 case IDLN_ATTR_DCL: {
425 IDL_tree node;
426
427 for (node = IDL_ATTR_DCL (tree).simple_declarations; node; node = IDL_LIST (node).next) {
428 OIDL_Attr_Info *ai;
429 ai = IDL_LIST (node).data->data;
430
431 cs_output_stubs (ai->op1, ci, idx);
432 if (ai->op2)
433 cs_output_stubs (ai->op2, ci, idx);
434 }
435 break;
436 }
437 case IDLN_INTERFACE: {
438 int real_idx = 0;
439 cs_output_stubs (IDL_INTERFACE (tree).body, ci, &real_idx);
440 break;
441 }
442 case IDLN_OP_DCL:
443 cs_output_stub (tree, ci, idx);
444 break;
445 default:
446 break;
447 }
448}
449
450/*
451 This function returns the interface name from the given tree. It returns the first
452 name found. Works for what it's build for (getting the toplevel name for single class
453 IDL files). No idea what happens with files containing several interfaces...
454 */
455static void
456VoyagerFindInterfaceName(IDL_tree tree, char** iface_id)
457{
458
459 if (!tree)
460 return;
461
462 switch (IDL_NODE_TYPE (tree)) {
463 case IDLN_MODULE:
464 break;
465 case IDLN_LIST: {
466 IDL_tree sub;
467 for (sub = tree; sub; sub = IDL_LIST (sub).next){
468 VoyagerFindInterfaceName((IDL_LIST (sub).data), iface_id);
469 }
470 break;
471 }
472 case IDLN_ATTR_DCL: {
473 break;
474 }
475 case IDLN_INTERFACE: {
476 VoyagerFindInterfaceName(IDL_INTERFACE (tree).body, iface_id);
477 break;
478 }
479 case IDLN_OP_DCL:
480 {
481 char *priviface_id = IDL_ns_ident_to_qstring (
482 IDL_IDENT_TO_NS (IDL_INTERFACE (
483 IDL_get_parent_node (tree, IDLN_INTERFACE, NULL)
484 ).ident), "_", 0);
485 //printf("----------> %s\n", priviface_id);
486 if(priviface_id)
487 *iface_id=priviface_id; /* This is a copy */
488 break;
489 }
490 default:
491 break;
492 }
493 return;
494}
495
496void
497orbit_idl_output_c_stubs (IDL_tree tree,
498 OIDL_Run_Info *rinfo,
499 OIDL_C_Info *ci)
500{
501 char *iface_id=NULL;
502 fprintf (ci->fh, OIDL_C_WARNING);
503 VoyagerFindInterfaceName(tree, &iface_id); /* get name of this interface/class */
504 g_assert(iface_id);
505 fprintf (ci->fh, "#ifndef NOM_%s_IMPLEMENTATION_FILE\n", iface_id);
506 fprintf (ci->fh, "#define NOM_%s_IMPLEMENTATION_FILE\n#endif\n\n", iface_id);
507 /* Output include files always needed */
508 fprintf (ci->fh, "#define INCL_DOS\n");
509 fprintf (ci->fh, "#include <os2.h>\n\n");
510
511 fprintf (ci->fh, "#include \"nom.h\"\n");
512 fprintf (ci->fh, "#include <nomtk.h>\n\n");
513
514 //fprintf (ci->fh, "#include <string.h>\n");
515#ifdef USE_LIBIDL_CODE
516 fprintf (ci->fh, "#define ORBIT2_STUBS_API\n");
517#endif
518 fprintf (ci->fh, "#include \"%s.ih\"\n\n", ci->base_name);
519 cs_output_stubs (tree, ci, NULL);
520
521}
522
523
524
525
526
527
Note: See TracBrowser for help on using the repository browser.