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

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

Orbit2 modified for use with NOM

File size: 14.8 KB
Line 
1#include "config.h"
2
3#include "orbit-idl-c-backend.h"
4
5#include <string.h>
6
7typedef struct {
8 IDL_tree tree;
9 GSList *methods; /* IDLN_OP_DCLs */
10} Interface;
11
12typedef struct {
13 FILE *of;
14 IDL_tree cur_node; /* Current Interface */
15 char *cur_id;
16 guint parents;
17} CCSmallInterfaceTraverseInfo;
18
19/* TypeCodes */
20
21static void cc_output_typecodes (IDL_tree tree,
22 OIDL_C_Info *ci);
23
24static void
25cc_typecode_prep_sequence (IDL_tree tree,
26 OIDL_C_Info *ci)
27{
28 IDL_tree seq_type;
29 IDL_tree fake_seq_type = NULL;
30 char *type_str;
31 char *seq_type_str;
32
33 seq_type = orbit_cbe_get_typespec (IDL_TYPE_SEQUENCE (tree).simple_type_spec);
34
35 if (IDL_NODE_TYPE (seq_type) != IDLN_INTERFACE)
36 seq_type_str = orbit_cbe_get_typespec_str (seq_type);
37 else {
38 seq_type_str = g_strdup ("CORBA_Object");
39 fake_seq_type = IDL_type_object_new ();
40 }
41
42 type_str = orbit_cbe_get_typespec_str (IDL_TYPE_SEQUENCE (tree).simple_type_spec);
43
44 if (strcmp (type_str, seq_type_str)) {
45 IDL_tree fake_seq;
46
47 fake_seq = IDL_type_sequence_new (
48 fake_seq_type ? fake_seq_type : seq_type,
49 NULL);
50 IDL_NODE_UP (fake_seq) = IDL_NODE_UP (tree);
51
52 cc_output_typecodes (fake_seq, ci);
53
54 IDL_TYPE_SEQUENCE (fake_seq).simple_type_spec = NULL;
55 IDL_tree_free (fake_seq);
56 }
57
58 if (fake_seq_type)
59 IDL_tree_free (fake_seq_type);
60
61 g_free (type_str);
62 g_free (seq_type_str);
63}
64
65static gboolean
66cc_output_tc_walker (IDL_tree_func_data *tfd,
67 OIDL_C_Info *ci)
68{
69 IDL_tree tree = tfd->tree;
70
71 switch(IDL_NODE_TYPE (tree)) {
72 case IDLN_CONST_DCL:
73 case IDLN_ATTR_DCL:
74 case IDLN_OP_DCL:
75 return FALSE; /* dont recurse into these */
76
77 case IDLN_TYPE_SEQUENCE:
78 if (!tfd->step) {
79 cc_typecode_prep_sequence (tree, ci);
80 break;
81 }
82 /* drop through */
83
84 case IDLN_INTERFACE:
85 case IDLN_EXCEPT_DCL:
86 case IDLN_TYPE_STRUCT:
87 case IDLN_TYPE_UNION:
88 case IDLN_TYPE_DCL:
89 case IDLN_TYPE_ENUM:
90 case IDLN_TYPE_FIXED:
91 if (tfd->step)
92 orbit_output_typecode (ci, tree);
93 break;
94 default:
95 break;
96 }
97
98 return TRUE; /* continue walking */
99}
100
101static void
102cc_output_typecodes (IDL_tree tree,
103 OIDL_C_Info *ci)
104{
105 IDL_tree_walk2 (tree, NULL, IDL_WalkF_TypespecOnly,
106 (IDL_tree_func) cc_output_tc_walker,
107 (IDL_tree_func) cc_output_tc_walker,
108 ci);
109}
110
111/* class ids */
112
113static void
114cc_output_class_id (IDL_tree tree,
115 OIDL_Run_Info *rinfo,
116 OIDL_C_Info *ci)
117{
118 char *iface_id;
119
120 iface_id = IDL_ns_ident_to_qstring (
121 IDL_IDENT_TO_NS (IDL_INTERFACE (tree).ident), "_", 0);
122
123 fprintf (ci->fh, "\n#ifndef ORBIT_IDL_C_IMODULE_%s\n",ci->c_base_name);
124 fprintf (ci->fh, "CORBA_unsigned_long %s__classid = 0;\n", iface_id);
125 fprintf (ci->fh, "#endif\n");
126
127 g_free (iface_id);
128}
129
130static void
131cc_output_class_ids (IDL_tree tree,
132 OIDL_Run_Info *rinfo,
133 OIDL_C_Info *ci)
134{
135 if (!tree || (tree->declspec & IDLF_DECLSPEC_PIDL))
136 return;
137
138 switch (IDL_NODE_TYPE (tree)) {
139 case IDLN_MODULE:
140 cc_output_class_ids (IDL_MODULE (tree).definition_list, rinfo, ci);
141 break;
142 case IDLN_LIST: {
143 IDL_tree node;
144
145 for (node = tree; node; node = IDL_LIST (node).next)
146 cc_output_class_ids (IDL_LIST (node).data, rinfo, ci);
147 break;
148 }
149 case IDLN_INTERFACE:
150 cc_output_class_id (tree, rinfo, ci);
151 break;
152 default:
153 break;
154 }
155}
156
157/* IInterfaces */
158
159static void
160cc_output_iargs (FILE *of, const char *method, IDL_tree tree)
161{
162 IDL_tree sub;
163 int arg_count = 0;
164
165 /* Build a list of IArgs */
166 for (sub = IDL_OP_DCL (tree).parameter_dcls; sub;
167 sub = IDL_LIST (sub).next) {
168 IDL_tree parm;
169 char *tc;
170
171 if (!arg_count)
172 fprintf (of, "static ORBit_IArg %s__arginfo [] = {\n", method);
173
174 parm = IDL_LIST(sub).data;
175
176 fprintf (of, "\t{ ");
177
178 /* TypeCode tc */
179 tc = orbit_cbe_get_typecode_name (
180 IDL_PARAM_DCL (parm).param_type_spec);
181 if (!tc) {
182 g_warning ("Can't get typecode");
183 tc = g_strdup ("NULL /* no typecode */");
184 }
185 fprintf (of, "%s, ", tc);
186
187 /* IArgFlag flags */
188 switch (IDL_PARAM_DCL (parm).attr) {
189 case IDL_PARAM_IN:
190 fprintf (of, " ORBit_I_ARG_IN ");
191 break;
192 case IDL_PARAM_OUT:
193 fprintf (of, " ORBit_I_ARG_OUT ");
194 break;
195 case IDL_PARAM_INOUT:
196 fprintf (of, " ORBit_I_ARG_INOUT ");
197 break;
198 }
199
200 if (orbit_cbe_type_is_fixed_length (
201 IDL_PARAM_DCL (parm).param_type_spec))
202 fprintf (of, "| ORBit_I_COMMON_FIXED_SIZE");
203
204 else if (IDL_PARAM_DCL(parm).attr == IDL_PARAM_OUT) {
205
206 IDL_tree ts = orbit_cbe_get_typespec (
207 IDL_PARAM_DCL (parm).param_type_spec);
208
209 switch(IDL_NODE_TYPE (ts)) {
210 case IDLN_TYPE_STRUCT:
211 case IDLN_TYPE_UNION:
212 case IDLN_TYPE_ARRAY:
213/* fprintf (of, "| ORBIT_I_ARG_FIXED");*/
214 break;
215 default:
216 break;
217 };
218 }
219
220 fprintf (of, ", ");
221
222 /* string name */
223 fprintf (of, "\"%s\"", IDL_IDENT (IDL_PARAM_DCL (
224 IDL_LIST (sub).data).simple_declarator).str);
225
226 fprintf (of, " }%s\n", IDL_LIST (sub).next ? "," : "");
227
228 g_free (tc);
229 arg_count++;
230 }
231
232 if (arg_count)
233 fprintf (of, "};\n");
234}
235
236static void
237cc_output_contexts (FILE *of, const char *method, IDL_tree tree)
238{
239 /* Build a list of contest names */
240 if (IDL_OP_DCL (tree).context_expr) {
241 IDL_tree curitem;
242
243 fprintf (of, "/* Exceptions */\n");
244 fprintf (of, "static CORBA_string %s__contextinfo [] = {\n",
245 method);
246
247 for (curitem = IDL_OP_DCL (tree).context_expr; curitem;
248 curitem = IDL_LIST (curitem).next) {
249 fprintf (of, "\"%s\"%c",
250 IDL_STRING (IDL_LIST (curitem).data).value,
251 IDL_LIST (curitem).next ? ',' : ' ');
252 }
253
254 fprintf (of, "};\n");
255 }
256}
257
258static void
259cc_output_exceptinfo (FILE *of, const char *method, IDL_tree tree)
260{
261 /* Build a list of exception typecodes */
262 if (IDL_OP_DCL (tree).raises_expr) {
263 IDL_tree curitem;
264
265 fprintf (of, "/* Exceptions */\n");
266 fprintf (of, "static CORBA_TypeCode %s__exceptinfo [] = {\n",
267 method);
268
269 for (curitem = IDL_OP_DCL (tree).raises_expr; curitem;
270 curitem = IDL_LIST(curitem).next) {
271 char *type_id;
272 IDL_tree curnode = IDL_LIST(curitem).data;
273
274 type_id = orbit_cbe_get_typecode_name (curnode);
275 fprintf (of, "\t%s,\n", type_id);
276 g_free (type_id);
277 }
278 fprintf (of, "\tNULL\n};\n");
279 }
280}
281
282static void
283cc_output_method_bits (IDL_tree tree, const char *id, OIDL_C_Info *ci)
284{
285 FILE *of = ci->fh;
286 char *fullname;
287
288 fullname = g_strconcat (id, "_", IDL_IDENT (
289 IDL_OP_DCL (tree).ident).str, NULL);
290
291 cc_output_iargs (of, fullname, tree);
292
293 cc_output_contexts (of, fullname, tree);
294
295 cc_output_exceptinfo (of, fullname, tree);
296
297 g_free (fullname);
298}
299
300static void
301cc_output_method (FILE *of, IDL_tree tree, const char *id)
302{
303 int arg_count;
304 int except_count;
305 int context_count;
306 const char *method;
307 char *fullname;
308
309 fullname = g_strconcat (id, "_", IDL_IDENT (
310 IDL_OP_DCL (tree).ident).str, NULL);
311
312 arg_count = IDL_list_length (IDL_OP_DCL (tree).parameter_dcls);
313 except_count = IDL_list_length (IDL_OP_DCL (tree).raises_expr);
314 context_count = IDL_list_length (IDL_OP_DCL (tree).context_expr);
315
316 fprintf (of, "\t{\n");
317
318 /* IArgs arguments */
319 if (arg_count)
320 fprintf (of, "\t\t{ %d, %d, %s__arginfo, FALSE },\n",
321 arg_count, arg_count, fullname);
322 else
323 fprintf (of, "\t\t{ 0, 0, NULL, FALSE },\n");
324
325 /* IContexts contexts */
326 if (context_count)
327 fprintf (of, "\t\t{ %d, %d, %s__contextinfo, FALSE },\n",
328 context_count, context_count, fullname);
329 else
330 fprintf (of, "\t\t{ 0, 0, NULL, FALSE },\n");
331
332 /* ITypes exceptions */
333 if (IDL_OP_DCL (tree).raises_expr)
334 fprintf (of, "\t\t{ %d, %d, %s__exceptinfo, FALSE },\n",
335 except_count, except_count, fullname);
336 else
337 fprintf (of, "\t\t{ 0, 0, NULL, FALSE },\n");
338
339 /* TypeCode ret */
340 if (IDL_OP_DCL (tree).op_type_spec) {
341 char *type_id;
342
343 type_id = orbit_cbe_get_typespec_str (
344 IDL_OP_DCL (tree).op_type_spec);
345 fprintf (of, "\t\tTC_%s, ", type_id);
346 g_free (type_id);
347 } else
348 fprintf (of, "TC_void, ");
349
350 /* string name, long name_len */
351 method = IDL_IDENT (IDL_OP_DCL (tree).ident).str;
352 fprintf (of, "\"%s\", %d,\n", method, strlen (method));
353
354 /* IMethodFlags flags */
355 fprintf (of, "\t\t0");
356
357 if (IDL_OP_DCL(tree).f_oneway)
358 fprintf (of, " | ORBit_I_METHOD_1_WAY");
359
360/* FIXME: re-scan for no_out */
361/* if (no_out)
362 fprintf (of, " | ORBit_I_METHOD_NO_OUT");*/
363
364 if (IDL_OP_DCL (tree).op_type_spec &&
365 orbit_cbe_type_is_fixed_length (
366 IDL_OP_DCL (tree).op_type_spec))
367 fprintf (of, "| ORBit_I_COMMON_FIXED_SIZE");
368
369 if (IDL_OP_DCL(tree).context_expr)
370 fprintf (of, "| ORBit_I_METHOD_HAS_CONTEXT");
371
372 fprintf (of, "\n}\n");
373
374 g_free (fullname);
375}
376
377static void
378cc_output_base_itypes(IDL_tree node, CCSmallInterfaceTraverseInfo *iti)
379{
380 if (iti->cur_node == node)
381 return;
382
383 fprintf (iti->of, "\"%s\",\n",
384 IDL_IDENT(IDL_INTERFACE(node).ident).repo_id);
385
386 iti->parents++;
387}
388
389static void
390cc_output_itypes (GSList *list, OIDL_C_Info *ci)
391{
392 GSList *l;
393 FILE *of = ci->fh;
394
395 for (l = list; l; l = l->next) {
396 CCSmallInterfaceTraverseInfo iti;
397 Interface *i = l->data;
398 char *id;
399 GSList *m;
400
401 id = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (
402 IDL_INTERFACE (i->tree).ident), "_", 0);
403
404 for (m = i->methods; m; m = m->next)
405 cc_output_method_bits (m->data, id, ci);
406
407 if (i->methods) {
408 fprintf (of, "\n#ifdef ORBIT_IDL_C_IMODULE_%s\n",
409 ci->c_base_name);
410 fprintf (of, "static\n");
411 fprintf (of, "#endif\n");
412
413 fprintf (of, "ORBit_IMethod %s__imethods [] = {\n", id);
414
415 if (!(m = i->methods))
416 fprintf (of, "{{0}}");
417
418 else for (; m; m = m->next) {
419 cc_output_method (of, m->data, id);
420 if (m->next)
421 fprintf(of, ", ");
422 }
423
424 fprintf (of, "};");
425 }
426
427 fprintf (of, "static CORBA_string %s__base_itypes[] = {\n", id);
428
429 iti.of = of;
430 iti.cur_node = i->tree;
431 iti.cur_id = id;
432 iti.parents = 0;
433 IDL_tree_traverse_parents(i->tree, (GFunc)cc_output_base_itypes, &iti);
434
435 fprintf (of, "\"IDL:omg.org/CORBA/Object:1.0\"\n};");
436
437 fprintf (of, "\n#ifdef ORBIT_IDL_C_IMODULE_%s\n",
438 ci->c_base_name);
439 fprintf (of, "static\n");
440 fprintf (of, "#endif\n");
441 fprintf (of, "ORBit_IInterface %s__iinterface = {\n", id);
442 fprintf (of, "TC_%s,", id);
443 fprintf (of, "{%d, %d, %s__imethods, FALSE},\n",
444 g_slist_length (i->methods),
445 g_slist_length (i->methods), id);
446
447 fprintf (of, "{%d, %d, %s__base_itypes, FALSE}\n",
448 iti.parents + 1, iti.parents + 1, id);
449
450 fprintf (of, "};\n\n");
451
452 g_free (id);
453 }
454
455 for (l = list; l; l = l->next) {
456 g_slist_free (((Interface *)l->data)->methods);
457 g_free (l->data);
458 }
459
460 g_slist_free (list);
461}
462
463static GSList *
464cc_build_interfaces (GSList *list, IDL_tree tree)
465{
466 if (!tree)
467 return list;
468
469 switch (IDL_NODE_TYPE (tree)) {
470 case IDLN_MODULE:
471 list = cc_build_interfaces (
472 list, IDL_MODULE (tree).definition_list);
473 break;
474 case IDLN_LIST: {
475 IDL_tree sub;
476 for (sub = tree; sub; sub = IDL_LIST (sub).next)
477 list = cc_build_interfaces (
478 list, IDL_LIST (sub).data);
479 break;
480 }
481 case IDLN_ATTR_DCL: {
482 IDL_tree curitem;
483
484 for (curitem = IDL_ATTR_DCL (tree).simple_declarations;
485 curitem; curitem = IDL_LIST (curitem).next) {
486 OIDL_Attr_Info *ai = IDL_LIST (curitem).data->data;
487
488 list = cc_build_interfaces (list, ai->op1);
489 if (ai->op2)
490 list = cc_build_interfaces (list, ai->op2);
491 }
492 break;
493 }
494 case IDLN_INTERFACE: {
495 Interface *i = g_new0 (Interface, 1);
496
497 i->tree = tree;
498
499 list = g_slist_append (list, i);
500
501 list = cc_build_interfaces (list, IDL_INTERFACE(tree).body);
502
503 break;
504 }
505 case IDLN_OP_DCL: {
506 Interface *i;
507
508 g_return_val_if_fail (list != NULL, NULL);
509
510 i = ( g_slist_last(list) )->data;
511 i->methods = g_slist_append (i->methods, tree);
512 break;
513 }
514 case IDLN_EXCEPT_DCL:
515 break;
516 default:
517 break;
518 }
519
520 return list;
521}
522
523static void
524cc_output_skel (IDL_tree tree,
525 OIDL_C_Info *ci,
526 int *idx)
527{
528 IDL_tree intf;
529 gboolean has_args;
530 gboolean has_retval;
531 char *opname;
532 char *ifname;
533
534 g_return_if_fail (idx != NULL);
535
536 intf = IDL_get_parent_node (tree, IDLN_INTERFACE, NULL);
537
538 has_args = IDL_OP_DCL (tree).parameter_dcls != NULL;
539 has_retval = IDL_OP_DCL (tree).op_type_spec != NULL;
540
541 opname = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (IDL_OP_DCL (tree).ident), "_", 0);
542 ifname = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident), "_", 0);
543
544 fprintf (ci->fh, "void _ORBIT_skel_small_%s("
545 "POA_%s *_o_servant, "
546 "gpointer _o_retval,"
547 "gpointer *_o_args,"
548 "CORBA_Context _o_ctx,"
549 "CORBA_Environment *_o_ev,\n", opname, ifname);
550
551 orbit_cbe_op_write_proto (ci->fh, tree, "_impl_", TRUE);
552
553 fprintf (ci->fh, ") {\n");
554
555 if (has_retval) {
556 fprintf (ci->fh, "*(");
557 orbit_cbe_write_param_typespec (ci->fh, tree);
558 fprintf (ci->fh, " *)_o_retval = ");
559 }
560
561 fprintf (ci->fh, "_impl_%s (_o_servant, ", IDL_IDENT (IDL_OP_DCL (tree).ident).str);
562
563 orbit_cbe_unflatten_args (tree, ci->fh, "_o_args");
564
565 if (IDL_OP_DCL (tree).context_expr)
566 fprintf (ci->fh, "_o_ctx, ");
567
568 fprintf (ci->fh, "_o_ev);\n");
569
570 fprintf (ci->fh, "}\n");
571
572 g_free (opname);
573 g_free (ifname);
574
575 (*idx)++;
576}
577
578static void
579cc_output_skels (IDL_tree tree,
580 OIDL_Run_Info *rinfo,
581 OIDL_C_Info *ci,
582 int *idx)
583{
584 if (!tree || (tree->declspec & IDLF_DECLSPEC_PIDL))
585 return;
586
587 switch (IDL_NODE_TYPE (tree)) {
588 case IDLN_MODULE:
589 cc_output_skels (IDL_MODULE (tree).definition_list, rinfo, ci, idx);
590 break;
591 case IDLN_LIST: {
592 IDL_tree node;
593
594 for (node = tree; node; node = IDL_LIST (node).next)
595 cc_output_skels (IDL_LIST (node).data, rinfo, ci, idx);
596 break;
597 }
598 case IDLN_ATTR_DCL: {
599 OIDL_Attr_Info *ai = tree->data;
600 IDL_tree node;
601
602 for (node = IDL_ATTR_DCL (tree).simple_declarations; node; node = IDL_LIST (node).next) {
603 ai = IDL_LIST (node).data->data;
604
605 cc_output_skels (ai->op1, rinfo, ci, idx);
606 if (ai->op2)
607 cc_output_skels (ai->op2, rinfo, ci, idx);
608 }
609 break;
610 }
611 case IDLN_INTERFACE: {
612 int real_idx = 0;
613
614 cc_output_skels (IDL_INTERFACE (tree).body, rinfo, ci, &real_idx);
615 }
616 break;
617 case IDLN_OP_DCL:
618 cc_output_skel (tree, ci, idx);
619 break;
620 default:
621 break;
622 }
623}
624
625void
626orbit_idl_output_c_common (IDL_tree tree,
627 OIDL_Run_Info *rinfo,
628 OIDL_C_Info *ci)
629{
630 fprintf (ci->fh, OIDL_C_WARNING);
631 fprintf (ci->fh, "#include <string.h>\n");
632 fprintf (ci->fh, "#define ORBIT2_STUBS_API\n");
633 fprintf (ci->fh, "#define ORBIT_IDL_C_COMMON\n");
634 fprintf (ci->fh, "#define %s_COMMON\n", ci->c_base_name);
635 fprintf (ci->fh, "#include \"%s.h\"\n\n", ci->base_name);
636 fprintf (ci->fh, "static const CORBA_unsigned_long ORBit_zero_int = 0;\n");
637
638 /* FIXME: this is slightly nasty, but we need these in common,
639 and this fixes an internal build issue */
640 if (rinfo->enabled_passes & OUTPUT_SKELS ||
641 rinfo->enabled_passes & OUTPUT_STUBS) {
642 fprintf (ci->fh, "\n#ifndef ORBIT_IDL_C_IMODULE_%s\n",ci->c_base_name);
643 cc_output_skels (tree, rinfo, ci, NULL);
644 fprintf (ci->fh, "\n#endif\n");
645 }
646
647 cc_output_typecodes (tree, ci);
648
649 cc_output_class_ids (tree, rinfo, ci);
650
651 if (rinfo->idata) {
652 GSList *list = NULL;
653
654 fprintf (ci->fh, "\n/* Interface type data */\n\n");
655
656 list = cc_build_interfaces (list, tree);
657 cc_output_itypes (list, ci);
658 }
659}
Note: See TracBrowser for help on using the repository browser.