]> rtime.felk.cvut.cz Git - frescor/forb.git/blob - forb-idl/forb-idl-utils.c
Fixed warnings on printf() on 64 bit systems
[frescor/forb.git] / forb-idl / forb-idl-utils.c
1 #include "config.h"
2 #include "forb-idl2.h"
3 #include <string.h>
4 #include <inttypes.h>
5
6 void
7 forb_idl_check_oneway_op (IDL_tree op)
8 {
9         g_assert (IDL_NODE_TYPE(op) == IDLN_OP_DCL);
10
11         if (IDL_OP_DCL (op).f_oneway) {
12                 IDL_tree sub;
13
14                 for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
15                         IDL_tree param = IDL_LIST (sub).data;
16
17                         if (IDL_PARAM_DCL (param).attr == IDL_PARAM_OUT ||
18                             IDL_PARAM_DCL (param).attr == IDL_PARAM_INOUT) {
19                                 g_warning ("Out or Inout parameter in declaration of oneway '%s'",
20                                            IDL_IDENT(IDL_OP_DCL(op).ident).str);
21                                 break;
22                         }
23                 }
24
25                 if (IDL_OP_DCL (op).op_type_spec)
26                         g_warning ("Return value in declaration of oneway '%s'",
27                                    IDL_IDENT(IDL_OP_DCL(op).ident).str);
28         }
29 }
30
31 void
32 forb_idl_attr_fake_ops(IDL_tree attr, IDL_ns ns)
33 {
34   IDL_tree attr_name, ident, curnode, op1, op2, intf;
35   GString *attrname;
36   OIDL_Attr_Info *setme;
37
38   g_assert(attr && IDL_NODE_TYPE(attr) == IDLN_ATTR_DCL);
39
40   attrname = g_string_new(NULL);
41
42   for(curnode = IDL_ATTR_DCL(attr).simple_declarations; curnode; curnode = IDL_LIST(curnode).next) {
43     op1 = op2 = NULL;
44
45     attr_name = IDL_LIST(curnode).data;
46
47     g_string_printf(attrname, "_get_%s",
48                      IDL_IDENT(attr_name).str);
49     ident = IDL_ident_new(g_strdup(attrname->str));
50     IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(attr_name);
51     op1 = IDL_op_dcl_new(0, IDL_ATTR_DCL(attr).param_type_spec, ident, NULL, NULL, NULL);
52     IDL_NODE_UP(op1) = IDL_NODE_UP(attr);
53     intf = IDL_NODE_UP (IDL_NODE_UP (op1));
54     IDL_NS(ns).current = IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident);
55     IDL_ns_place_new(ns, ident);
56
57     if(!IDL_ATTR_DCL(attr).f_readonly) {
58       g_string_printf(attrname, "_set_%s",
59                        IDL_IDENT(attr_name).str);
60       ident = IDL_ident_new(g_strdup(attrname->str));
61       IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(attr_name);
62       op2 = IDL_op_dcl_new(0, NULL, ident, NULL, NULL, NULL);
63       IDL_NODE_UP(op2) = IDL_NODE_UP(attr);
64       intf = IDL_NODE_UP (IDL_NODE_UP (op2));
65       IDL_NS(ns).current = IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident);
66       IDL_ns_place_new(ns, ident);
67       IDL_OP_DCL(op2).parameter_dcls = IDL_list_new(
68                                                     IDL_param_dcl_new(IDL_PARAM_IN,
69                                                                       IDL_ATTR_DCL(attr).param_type_spec,
70                                                                       IDL_ident_new(g_strdup("value"))));
71     }
72
73     setme = g_new0(OIDL_Attr_Info, 1);
74     setme->op1 = op1;
75     setme->op2 = op2;
76     attr_name->data = setme;
77   }
78
79   g_string_free(attrname, TRUE);
80 }
81
82 #define INDENT_INCREMENT_1 2
83 #define INDENT_INCREMENT_2 4
84
85 static void do_indent(int level) {
86   int i;
87   for(i = 0; i < level; i++) g_print(" ");
88 }
89
90 void
91 forb_idl_print_node(IDL_tree node, int indent_level)
92 {
93   IDL_tree curnode;
94   char *s;
95
96   do_indent(indent_level);
97
98   if(node == NULL) {
99     g_print("(null)\n");
100     return;
101   }
102
103   g_print("[%d] ", IDL_NODE_REFS(node));
104
105   switch(IDL_NODE_TYPE(node)) {
106
107   case IDLN_NONE:
108     g_print("NONE\n");
109     break;
110
111   case IDLN_LIST:
112     g_print("LIST:\n");
113     for(curnode = node; curnode;
114         curnode = IDL_LIST(curnode).next) {
115       forb_idl_print_node(IDL_LIST(curnode).data, indent_level + INDENT_INCREMENT_1);
116     }
117     break;
118
119   case IDLN_GENTREE:
120     break;
121
122   case IDLN_INTEGER:
123     g_print("INTEGER: %" PRId64 "\n", IDL_INTEGER(node).value);
124     break;
125
126   case IDLN_STRING:
127     g_print("STRING: %s\n", IDL_STRING(node).value);
128     break;
129
130   case IDLN_WIDE_STRING:
131     g_print("WIDE STRING: %ls\n", IDL_WIDE_STRING(node).value);
132     break;
133
134   case IDLN_CHAR:
135     g_print("CHAR: %s\n", IDL_CHAR(node).value);
136     break;
137
138   case IDLN_WIDE_CHAR:
139     g_print("WIDE CHAR: %ls\n", IDL_WIDE_CHAR(node).value);
140     break;
141
142   case IDLN_FIXED:
143     g_print("FIXED: %s\n", IDL_FIXED(node).value);
144     break;
145
146   case IDLN_FLOAT:
147     g_print("FLOAT: %f\n", IDL_FLOAT(node).value);
148     break;
149
150   case IDLN_BOOLEAN:
151     g_print("BOOLEAN: %s\n", (IDL_BOOLEAN(node).value)?"True":"False");
152     break;
153
154   case IDLN_IDENT:
155     s = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(node), "_", 0);
156     g_print("IDENT: %s NSQ: %s RID: \"%s\"\n",
157             IDL_IDENT(node).str, s,
158             IDL_IDENT_REPO_ID(node) ? IDL_IDENT_REPO_ID(node) : "");
159     g_free(s);
160     break;
161
162   case IDLN_TYPE_DCL:
163     g_print("TYPE DCL:\n");
164     forb_idl_print_node(IDL_TYPE_DCL(node).type_spec, indent_level + INDENT_INCREMENT_1);
165     do_indent(indent_level + INDENT_INCREMENT_1); g_print("decls:\n");
166     forb_idl_print_node(IDL_TYPE_DCL(node).dcls, indent_level + INDENT_INCREMENT_2);
167     break;
168
169   case IDLN_CONST_DCL:
170     g_print("CONST DCL:\n");
171     forb_idl_print_node(IDL_CONST_DCL(node).const_type, indent_level + INDENT_INCREMENT_1);
172     do_indent(indent_level + INDENT_INCREMENT_1); g_print("ident:\n");
173     forb_idl_print_node(IDL_CONST_DCL(node).ident, indent_level + INDENT_INCREMENT_2);
174     do_indent(indent_level + INDENT_INCREMENT_1); g_print("const_exp:\n");
175     forb_idl_print_node(IDL_CONST_DCL(node).const_exp, indent_level + INDENT_INCREMENT_2);
176     break;
177
178   case IDLN_EXCEPT_DCL:
179     g_print("EXCEPT DCL:\n");
180     forb_idl_print_node(IDL_EXCEPT_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
181     do_indent(indent_level + INDENT_INCREMENT_1); g_print("members:\n");
182     forb_idl_print_node(IDL_EXCEPT_DCL(node).members, indent_level + INDENT_INCREMENT_2);
183     break;
184
185   case IDLN_ATTR_DCL:
186     g_print("ATTR_DCL (%s):\n", (IDL_ATTR_DCL(node).f_readonly)?"readonly":"rw");
187     forb_idl_print_node(IDL_ATTR_DCL(node).param_type_spec, indent_level + INDENT_INCREMENT_1);
188     do_indent(indent_level + INDENT_INCREMENT_1); g_print("simple_declarations:\n");
189     forb_idl_print_node(IDL_ATTR_DCL(node).simple_declarations, indent_level + INDENT_INCREMENT_2);
190     break;
191
192   case IDLN_OP_DCL:
193     g_print("OP DCL (%s):\n", (IDL_OP_DCL(node).f_oneway)?"oneway":"normal");
194     forb_idl_print_node(IDL_OP_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
195     do_indent(indent_level + INDENT_INCREMENT_1); g_print("op_type_spec:\n");
196     forb_idl_print_node(IDL_OP_DCL(node).op_type_spec, indent_level + INDENT_INCREMENT_2);
197     do_indent(indent_level + INDENT_INCREMENT_1); g_print("parameter_dcls:\n");
198     forb_idl_print_node(IDL_OP_DCL(node).parameter_dcls, indent_level + INDENT_INCREMENT_2);
199     do_indent(indent_level + INDENT_INCREMENT_1); g_print("raises_expr:\n");
200     forb_idl_print_node(IDL_OP_DCL(node).raises_expr, indent_level + INDENT_INCREMENT_2);
201     do_indent(indent_level + INDENT_INCREMENT_1); g_print("context_expr:\n");
202     forb_idl_print_node(IDL_OP_DCL(node).context_expr, indent_level + INDENT_INCREMENT_2);
203     break;
204
205   case IDLN_PARAM_DCL:
206     g_print("PARAM DCL: ");
207     switch(IDL_PARAM_DCL(node).attr) {
208     case IDL_PARAM_IN: g_print("(in)\n"); break;
209     case IDL_PARAM_OUT: g_print("(out)\n"); break;
210     case IDL_PARAM_INOUT: g_print("(inout)\n"); break;
211     }
212     forb_idl_print_node(IDL_PARAM_DCL(node).param_type_spec, indent_level + INDENT_INCREMENT_1);
213     do_indent(indent_level + INDENT_INCREMENT_1); g_print("simple_declarator:\n");
214     forb_idl_print_node(IDL_PARAM_DCL(node).simple_declarator, indent_level + INDENT_INCREMENT_2);
215     break;
216   case IDLN_FORWARD_DCL:
217     g_print("FORWARD DCL:\n");
218     forb_idl_print_node(IDL_FORWARD_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
219     break;
220   case IDLN_INTERFACE:
221     g_print("INTERFACE:\n");
222     forb_idl_print_node(IDL_INTERFACE(node).ident, indent_level + INDENT_INCREMENT_1);
223     do_indent(indent_level + INDENT_INCREMENT_1); g_print("inheritance_spec:\n");
224     forb_idl_print_node(IDL_INTERFACE(node).inheritance_spec, indent_level + INDENT_INCREMENT_2);
225     do_indent(indent_level + INDENT_INCREMENT_1); g_print("body:\n");
226     forb_idl_print_node(IDL_INTERFACE(node).body, indent_level + INDENT_INCREMENT_2);
227     break;
228   case IDLN_MODULE:
229     g_print("MODULE:\n");
230     forb_idl_print_node(IDL_MODULE(node).ident, indent_level + INDENT_INCREMENT_1);
231     do_indent(indent_level + INDENT_INCREMENT_1); g_print("definition_list:\n");
232     forb_idl_print_node(IDL_MODULE(node).definition_list, indent_level + INDENT_INCREMENT_2);
233     break;
234
235   case IDLN_TYPE_INTEGER:
236     if(!IDL_TYPE_INTEGER(node).f_signed) g_print("TYPE unsigned ");
237     switch(IDL_TYPE_INTEGER(node).f_type) {
238     case IDL_INTEGER_TYPE_SHORT: g_print("short\n"); break;
239     case IDL_INTEGER_TYPE_LONG: g_print("long\n"); break;
240     case IDL_INTEGER_TYPE_LONGLONG: g_print("long long\n"); break;
241     }
242     break;
243   case IDLN_TYPE_FLOAT:
244     switch(IDL_TYPE_FLOAT(node).f_type) {
245     case IDL_FLOAT_TYPE_FLOAT: g_print("TYPE float\n"); break;
246     case IDL_FLOAT_TYPE_DOUBLE: g_print("TYPE double\n"); break;
247     case IDL_FLOAT_TYPE_LONGDOUBLE: g_print("TYPE long double\n"); break;
248     }
249     break;
250   case IDLN_TYPE_FIXED:
251     g_print("TYPE fixed:\n");
252     forb_idl_print_node(IDL_TYPE_FIXED(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
253     forb_idl_print_node(IDL_TYPE_FIXED(node).integer_lit, indent_level + INDENT_INCREMENT_1);
254     break;
255   case IDLN_TYPE_STRING:
256     g_print("TYPE string:\n");
257     forb_idl_print_node(IDL_TYPE_STRING(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
258     break;
259   case IDLN_TYPE_WIDE_STRING:
260     g_print("TYPE wide string:\n");
261     forb_idl_print_node(IDL_TYPE_WIDE_STRING(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
262     break;
263   case IDLN_TYPE_ENUM:
264     g_print("TYPE enum:\n");
265     forb_idl_print_node(IDL_TYPE_ENUM(node).ident, indent_level + INDENT_INCREMENT_1);
266     do_indent(indent_level + INDENT_INCREMENT_1); g_print("enumerator_list:\n");
267     forb_idl_print_node(IDL_TYPE_ENUM(node).enumerator_list, indent_level + INDENT_INCREMENT_2);
268     break;
269   case IDLN_TYPE_ARRAY:
270     g_print("TYPE array:\n");
271     forb_idl_print_node(IDL_TYPE_ARRAY(node).ident, indent_level + INDENT_INCREMENT_1);
272     do_indent(indent_level + INDENT_INCREMENT_1); g_print("size_list:\n");
273     forb_idl_print_node(IDL_TYPE_ARRAY(node).size_list, indent_level + INDENT_INCREMENT_2);
274     break;
275   case IDLN_TYPE_SEQUENCE:
276     g_print("TYPE sequence:\n");
277     forb_idl_print_node(IDL_TYPE_SEQUENCE(node).simple_type_spec, indent_level + INDENT_INCREMENT_1);
278     do_indent(indent_level + INDENT_INCREMENT_1); g_print("positive_int_const:\n");
279     forb_idl_print_node(IDL_TYPE_SEQUENCE(node).positive_int_const, indent_level + INDENT_INCREMENT_2);
280     break;
281   case IDLN_TYPE_STRUCT:
282     g_print("TYPE struct:\n");
283     forb_idl_print_node(IDL_TYPE_STRUCT(node).ident, indent_level + INDENT_INCREMENT_1);
284     do_indent(indent_level + INDENT_INCREMENT_1); g_print("member_list:\n");
285     forb_idl_print_node(IDL_TYPE_STRUCT(node).member_list, indent_level + INDENT_INCREMENT_2);
286     break;
287   case IDLN_TYPE_UNION:
288     g_print("TYPE union:\n");
289     forb_idl_print_node(IDL_TYPE_UNION(node).ident, indent_level + INDENT_INCREMENT_1);
290     do_indent(indent_level + INDENT_INCREMENT_1); g_print("switch_type_spec:\n");
291     forb_idl_print_node(IDL_TYPE_UNION(node).switch_type_spec, indent_level + INDENT_INCREMENT_2);
292     do_indent(indent_level + INDENT_INCREMENT_1); g_print("switch_body:\n");
293     forb_idl_print_node(IDL_TYPE_UNION(node).switch_body, indent_level + INDENT_INCREMENT_2);
294     break;
295   case IDLN_MEMBER:
296     g_print("MEMBER:\n");
297     forb_idl_print_node(IDL_MEMBER(node).type_spec, indent_level + INDENT_INCREMENT_1);
298     do_indent(indent_level + INDENT_INCREMENT_1); g_print("dcls:\n");
299     forb_idl_print_node(IDL_MEMBER(node).dcls, indent_level + INDENT_INCREMENT_2);
300     break;
301   case IDLN_CASE_STMT:
302     g_print("CASE_STMT:\n");
303     forb_idl_print_node(IDL_CASE_STMT(node).labels, indent_level + INDENT_INCREMENT_1);
304     do_indent(indent_level + INDENT_INCREMENT_1); g_print("element_spec:\n");
305     forb_idl_print_node(IDL_CASE_STMT(node).element_spec, indent_level + INDENT_INCREMENT_2);
306     break;
307   case IDLN_BINOP:
308     g_print("BINOP ");
309     switch(IDL_BINOP(node).op) {
310     case IDL_BINOP_OR: g_print("or:\n"); break;
311     case IDL_BINOP_XOR: g_print("xor:\n"); break;
312     case IDL_BINOP_AND: g_print("and:\n"); break;
313     case IDL_BINOP_SHR: g_print("shr:\n"); break;
314     case IDL_BINOP_SHL: g_print("shl:\n"); break;
315     case IDL_BINOP_ADD: g_print("add:\n"); break;
316     case IDL_BINOP_SUB: g_print("sub:\n"); break;
317     case IDL_BINOP_MULT: g_print("mult:\n"); break;
318     case IDL_BINOP_DIV: g_print("div:\n"); break;
319     case IDL_BINOP_MOD: g_print("mod:\n"); break;
320     }
321     do_indent(indent_level + INDENT_INCREMENT_1); g_print("left:\n");
322     forb_idl_print_node(IDL_BINOP(node).left, indent_level + INDENT_INCREMENT_2);
323     do_indent(indent_level + INDENT_INCREMENT_1); g_print("right:\n");
324     forb_idl_print_node(IDL_BINOP(node).right, indent_level + INDENT_INCREMENT_2);
325     break;
326   case IDLN_UNARYOP:
327     g_print("UNARYOP ");
328     switch(IDL_UNARYOP(node).op) {
329     case IDL_UNARYOP_PLUS: g_print("plus:\n"); break;
330     case IDL_UNARYOP_MINUS: g_print("minus:\n"); break;
331     case IDL_UNARYOP_COMPLEMENT: g_print("complement:\n"); break;
332     }
333     forb_idl_print_node(IDL_UNARYOP(node).operand, indent_level + INDENT_INCREMENT_1);
334     break;
335   case IDLN_TYPE_CHAR:
336     g_print("TYPE char\n");
337     break;
338   case IDLN_TYPE_WIDE_CHAR:
339     g_print("TYPE wide char\n");
340     break;
341   case IDLN_TYPE_BOOLEAN:
342     g_print("TYPE boolean\n");
343     break;
344   case IDLN_TYPE_OCTET:
345     g_print("TYPE octet\n");
346     break;
347   case IDLN_TYPE_OBJECT:
348     g_print("TYPE object\n");
349     break;
350   case IDLN_TYPE_ANY:
351     g_print("TYPE any\n");
352     break;
353   case IDLN_TYPE_TYPECODE:
354     g_print("TYPE TypeCode\n");
355     break;
356   case IDLN_CODEFRAG:
357     g_print("CODEFRAG\n");
358     break;
359   case IDLN_SRCFILE:
360     g_print("SRCFILE %s\n", IDL_SRCFILE(node).filename);
361     break;
362   default:
363     g_print("unhandled %d\n", IDL_NODE_TYPE(node));
364   }
365 }
366
367 static void
368 IDL_tree_traverse_helper(IDL_tree p, GFunc f,
369                          gconstpointer func_data,
370                          GHashTable *visited_nodes,
371                          gboolean    include_self)
372 {
373         IDL_tree curitem;
374
375         if (g_hash_table_lookup (visited_nodes, p))
376                 return;
377
378         g_hash_table_insert (visited_nodes, p, ((gpointer)1));
379
380         for (curitem = IDL_INTERFACE (p).inheritance_spec; curitem;
381              curitem = IDL_LIST (curitem).next) {
382                 IDL_tree_traverse_helper (IDL_get_parent_node 
383                         (IDL_LIST (curitem).data, IDLN_INTERFACE, NULL), f, func_data, visited_nodes, TRUE);
384         }
385
386         if (include_self)
387                 f(p, (gpointer)func_data);
388 }
389
390 void
391 IDL_tree_traverse_parents_full (IDL_tree      p,
392                                 GFunc         f,
393                                 gconstpointer func_data,
394                                 gboolean      include_self)
395 {
396         GHashTable *visited_nodes = g_hash_table_new (NULL, g_direct_equal);
397
398         if (!(p && f))
399                 return;
400
401         if (IDL_NODE_TYPE(p) != IDLN_INTERFACE)
402                 p = IDL_get_parent_node (p, IDLN_INTERFACE, NULL);
403
404         if (!p)
405                 return;
406
407         IDL_tree_traverse_helper (p, f, func_data, visited_nodes, include_self);
408
409         g_hash_table_destroy (visited_nodes);
410 }
411
412 void
413 IDL_tree_traverse_parents (IDL_tree p,
414                            GFunc f,
415                            gconstpointer func_data)
416 {
417         IDL_tree_traverse_parents_full (p, f, func_data, TRUE);
418 }
419
420 /* For use by below function */
421 static const int *
422 forb_cbe_get_typeoffsets_table (void)
423 {
424   static int typeoffsets[IDLN_LAST];
425   static gboolean initialized = FALSE;
426   
427   if (!initialized) {
428     int i;
429
430     for (i = 0; i < IDLN_LAST; ++i)
431       typeoffsets[i] = -1;
432
433     typeoffsets[IDLN_FORWARD_DCL] = 8; /* (same as objref) */
434     typeoffsets[IDLN_TYPE_INTEGER] = 0;
435     typeoffsets[IDLN_TYPE_FLOAT] = 0;
436     typeoffsets[IDLN_TYPE_FIXED] = 3;
437     typeoffsets[IDLN_TYPE_CHAR] = 5;
438     typeoffsets[IDLN_TYPE_WIDE_CHAR] = 6;
439     typeoffsets[IDLN_TYPE_STRING] = 12;
440     typeoffsets[IDLN_TYPE_WIDE_STRING] = 13;
441     typeoffsets[IDLN_TYPE_BOOLEAN] = 4;
442     typeoffsets[IDLN_TYPE_OCTET] = 7;
443     typeoffsets[IDLN_TYPE_ANY] = 16;
444     typeoffsets[IDLN_TYPE_OBJECT] = 9;
445     typeoffsets[IDLN_TYPE_TYPECODE] = 9;
446     typeoffsets[IDLN_TYPE_ENUM] = 8;
447     typeoffsets[IDLN_TYPE_SEQUENCE] = 14;
448     typeoffsets[IDLN_TYPE_ARRAY] = 15;
449     typeoffsets[IDLN_TYPE_STRUCT] = 10;
450     typeoffsets[IDLN_TYPE_UNION] = 11;
451     typeoffsets[IDLN_NATIVE] = 15; /* no pointers ever, same as fixed array */
452     typeoffsets[IDLN_INTERFACE] = 9; /* (same as objref) */
453     
454     initialized = TRUE;
455   }
456   
457   return typeoffsets;
458 }
459
460
461 /**
462         This is a rather hairy function. Its purpose is to output the
463         required number of *'s that indicate the amount of indirection
464         for input, output, & input-output parameters, and return
465         values.  We do this by having a table of the number of *'s for
466         each type and purpose (nptrrefs_required), taken from 19.20
467         of the CORBA 2.2 spec, and then having a table that translates
468         from the IDLN_* enums into an index into nptrrefs_required (typeoffsets)
469 **/
470 gint
471 oidl_param_info(IDL_tree in_param, IDL_ParamRole role, gboolean *isSlice)
472 {
473         IDL_tree param;
474         const int * const typeoffsets = forb_cbe_get_typeoffsets_table ();
475         const int nptrrefs_required[][4] = {
476                 {0,1,1,0} /* float */,
477                 {0,1,1,0} /* double */,
478                 {0,1,1,0} /* long double */,
479                 {1,1,1,0} /* fixed_d_s 3 */, 
480                 {0,1,1,0} /* boolean */,
481                 {0,1,1,0} /* char */,
482                 {0,1,1,0} /* wchar */,
483                 {0,1,1,0} /* octet */,
484                 {0,1,1,0} /* enum */,
485                 {0,1,1,0} /* objref */,
486                 {1,1,1,0} /* fixed struct 10 */,
487                 {1,1,1,0} /* fixed union */,
488                 {0,1,1,0} /* string */,
489                 {0,1,1,0} /* wstring */,
490                 {1,1,2,1} /* sequence */,
491                 {0,0,0,0} /* fixed array */,
492                 {1,1,2,1} /* any 16 */
493         };
494         int retval = 0;
495         int typeidx;
496
497         *isSlice = FALSE;
498
499         if(!in_param)
500                 return 0; /* void */
501
502         /* Now, how do we use this table? :) */
503         param = forb_cbe_get_typespec (in_param);
504
505         g_assert (param);
506
507         switch (IDL_NODE_TYPE (param)) {
508         case IDLN_TYPE_STRUCT:
509         case IDLN_TYPE_UNION:
510                 if (((role == DATA_RETURN) || (role == DATA_OUT)) &&
511                     !forb_cbe_type_is_fixed_length(param))
512                         retval++;
513                 break;
514
515         case IDLN_TYPE_ARRAY:
516                 if ( role == DATA_RETURN ) {
517                         *isSlice = TRUE;
518                         retval = 1;
519
520                 } else if (role == DATA_OUT &&
521                            !forb_cbe_type_is_fixed_length (param)) {
522                         *isSlice = TRUE;
523                         retval = 2;
524                 }
525                 break;
526
527         case IDLN_NATIVE:
528                 if ( IDL_NATIVE (param).user_type
529                      && strcmp (IDL_NATIVE (param).user_type,
530                                 "IDL_variable_length_struct") == 0 ) {
531                         return role == DATA_OUT ? 2 : 1;
532                 }
533                 else {
534                         return role == DATA_IN ? 0 : 1;
535                   
536                 }
537                 break;
538
539         case IDLN_EXCEPT_DCL:
540                 fprintf (stderr, "Error: exception declared at '%s:%d' cannot be "
541                          "used as a method parameter\n", in_param->_file,
542                          in_param->_line);
543                 exit (1);
544                 break;
545         default:
546                 break;
547         }
548
549         /* ERROR ! */
550         typeidx = typeoffsets [IDL_NODE_TYPE (param)];
551         g_assert (typeidx >= 0);
552
553         switch (role) {
554         case DATA_IN:
555                 role = 0;
556                 break;
557         case DATA_INOUT:
558                 role = 1;
559                 break;
560         case DATA_OUT:
561                 role = 2;
562                 break;
563         case DATA_RETURN:
564                 role = 3;
565                 break;
566         default:
567                 g_assert_not_reached ();
568                 break;
569         }
570
571         retval += nptrrefs_required [typeidx] [role];
572
573         return retval;
574 }
575
576 /**
577     Fixed-length-ness is a property that CORBA defines, and it is
578     a property of each type, not each kind.  Furthermore, it doesnt
579     depend on the language mapping. Generally, the GIOP coding
580     a fixed length variable will be a known length (determined by the TC),
581     regardless of the data within the variable.
582
583     With the C mapping, fixed --> nothing to free in this node
584     Note that in the C mapping, everything is a struct and is
585     fixed length in that sense. Thus variable length types show
586     up in C as pointers.
587
588     Recursive types introduced by sequences are not a problem for this
589     func, because sequences are not fixed length, and terminate
590     the recursion.
591 **/
592  
593 gboolean
594 forb_cbe_type_is_fixed_length(IDL_tree ts)
595 {
596   gboolean is_fixed = TRUE;
597   IDL_tree curitem;
598
599   ts = forb_cbe_get_typespec(ts);
600   switch(IDL_NODE_TYPE(ts)) {
601   case IDLN_TYPE_FLOAT:
602   case IDLN_TYPE_INTEGER:
603   case IDLN_TYPE_ENUM:
604   case IDLN_TYPE_CHAR:
605   case IDLN_TYPE_WIDE_CHAR:
606   case IDLN_TYPE_OCTET:
607   case IDLN_TYPE_BOOLEAN:
608     return TRUE;
609     break;
610   case IDLN_TYPE_SEQUENCE:
611   case IDLN_TYPE_STRING:
612   case IDLN_TYPE_WIDE_STRING:
613   case IDLN_TYPE_OBJECT:
614   case IDLN_FORWARD_DCL:
615   case IDLN_INTERFACE:
616   case IDLN_TYPE_ANY:
617   case IDLN_NATIVE:
618   case IDLN_TYPE_TYPECODE:
619     return FALSE;
620     break;
621   case IDLN_TYPE_UNION:
622     for(curitem = IDL_TYPE_UNION(ts).switch_body; curitem;
623         curitem = IDL_LIST(curitem).next) {
624       is_fixed &= forb_cbe_type_is_fixed_length(IDL_LIST(IDL_CASE_STMT(IDL_LIST(curitem).data).element_spec).data);
625     }
626     return is_fixed;
627     break;
628   case IDLN_EXCEPT_DCL:
629   case IDLN_TYPE_STRUCT:
630     for(curitem = IDL_TYPE_STRUCT(ts).member_list; curitem;
631         curitem = IDL_LIST(curitem).next) {
632       is_fixed &= forb_cbe_type_is_fixed_length(IDL_LIST(curitem).data);
633     }
634     return is_fixed;
635     break;
636   case IDLN_TYPE_ARRAY:
637     return forb_cbe_type_is_fixed_length(IDL_TYPE_DCL(IDL_get_parent_node(ts, IDLN_TYPE_DCL, NULL)).type_spec);
638     break;
639   case IDLN_TYPE_DCL:
640     return forb_cbe_type_is_fixed_length(IDL_TYPE_DCL(ts).type_spec);
641     break;
642   case IDLN_IDENT:
643   case IDLN_LIST:
644     return forb_cbe_type_is_fixed_length(IDL_NODE_UP(ts));
645     break;
646   case IDLN_MEMBER:
647     return forb_cbe_type_is_fixed_length(IDL_MEMBER(ts).type_spec);
648     break;
649   default:
650     g_warning("I'm not sure if type %s is fixed-length", IDL_tree_type_names[IDL_NODE_TYPE(ts)]);
651     return FALSE;
652   }
653 }
654
655 IDL_tree
656 forb_cbe_get_typespec(IDL_tree node)
657 {
658   if(node == NULL)
659     return NULL;
660
661   switch(IDL_NODE_TYPE(node)) {
662   case IDLN_TYPE_INTEGER:
663   case IDLN_TYPE_FLOAT:
664   case IDLN_TYPE_FIXED:
665   case IDLN_TYPE_CHAR:
666   case IDLN_TYPE_WIDE_CHAR:
667   case IDLN_TYPE_STRING:
668   case IDLN_TYPE_WIDE_STRING:
669   case IDLN_TYPE_BOOLEAN:
670   case IDLN_TYPE_OCTET:
671   case IDLN_TYPE_ANY:
672   case IDLN_TYPE_OBJECT:
673   case IDLN_TYPE_ENUM:
674   case IDLN_TYPE_SEQUENCE:
675   case IDLN_TYPE_ARRAY:
676   case IDLN_TYPE_STRUCT:
677   case IDLN_TYPE_UNION:
678   case IDLN_EXCEPT_DCL:
679   case IDLN_FORWARD_DCL:
680   case IDLN_INTERFACE:
681   case IDLN_NATIVE:
682   case IDLN_TYPE_TYPECODE:
683     return node;
684     break;
685   case IDLN_TYPE_DCL:
686     return forb_cbe_get_typespec(IDL_TYPE_DCL(node).type_spec);
687     break;
688   case IDLN_PARAM_DCL:
689     return forb_cbe_get_typespec(IDL_PARAM_DCL(node).param_type_spec);
690     break;
691   case IDLN_MEMBER:
692     return forb_cbe_get_typespec(IDL_MEMBER(node).type_spec);
693     break;
694   case IDLN_LIST:
695   case IDLN_IDENT:
696     return forb_cbe_get_typespec(IDL_get_parent_node(node, IDLN_ANY, NULL));
697     break;
698   default:
699     g_error("Unhandled node type %s!", IDL_tree_type_names[IDL_NODE_TYPE(node)]);
700     return NULL;
701   }
702 }
703
704 IDL_ParamRole
705 oidl_attr_to_paramrole(enum IDL_param_attr attr)
706 {
707   switch(attr) {
708   case IDL_PARAM_IN:
709     return DATA_IN;
710   case IDL_PARAM_OUT:
711     return DATA_OUT;
712   case IDL_PARAM_INOUT:
713     return DATA_INOUT;
714   default:
715     g_warning("Unknown IDL_param_attr %d", attr);
716     return -1;
717   }
718 }