]> rtime.felk.cvut.cz Git - frescor/forb.git/blob - forb-idl/forb-idl-c-utils.c
Continuation of code generation for FORB
[frescor/forb.git] / forb-idl / forb-idl-c-utils.c
1 #include "config.h"
2
3 #include "forb-idl-c-backend.h"
4
5 #include <string.h>
6
7 char *
8 forb_cbe_get_typecode_name (IDL_tree tree)
9 {
10         if (!tree)
11                 return g_strdup ("TC_FIXME");
12         else
13                 return g_strconcat ("TC_", forb_cbe_get_typespec_str (tree), NULL);
14 }
15
16 gboolean
17 forb_cbe_type_is_builtin(IDL_tree tree)
18
19   return FALSE;
20   switch(IDL_NODE_TYPE(tree)) {
21   case IDLN_LIST:
22   case IDLN_GENTREE:
23   case IDLN_MEMBER:
24   case IDLN_NATIVE:
25   case IDLN_CASE_STMT:
26   case IDLN_MODULE:
27   case IDLN_BINOP:
28   case IDLN_UNARYOP:
29   case IDLN_CODEFRAG:
30     g_error("Strange type for being a builtin");
31     break;
32   case IDLN_INTEGER:
33   case IDLN_STRING:
34   case IDLN_WIDE_STRING:
35   case IDLN_CHAR:
36   case IDLN_WIDE_CHAR:
37   case IDLN_FIXED:
38   case IDLN_FLOAT:
39   case IDLN_BOOLEAN:
40   case IDLN_CONST_DCL:
41   case IDLN_TYPE_INTEGER:
42   case IDLN_TYPE_FLOAT:
43   case IDLN_TYPE_CHAR:
44   case IDLN_TYPE_WIDE_CHAR:
45   case IDLN_TYPE_STRING:
46   case IDLN_TYPE_WIDE_STRING:
47   case IDLN_TYPE_BOOLEAN:
48   case IDLN_TYPE_OCTET:
49   case IDLN_TYPE_ANY:
50   case IDLN_TYPE_OBJECT:
51   case IDLN_TYPE_TYPECODE:
52   case IDLN_TYPE_ENUM:
53     return TRUE;
54     break;
55   case IDLN_TYPE_DCL:
56   case IDLN_EXCEPT_DCL:
57   case IDLN_ATTR_DCL:
58   case IDLN_OP_DCL:
59   case IDLN_PARAM_DCL:
60   case IDLN_TYPE_FIXED:
61   case IDLN_TYPE_SEQUENCE:
62   case IDLN_TYPE_ARRAY:
63   case IDLN_TYPE_STRUCT:
64   case IDLN_TYPE_UNION:
65   case IDLN_IDENT:
66   case IDLN_INTERFACE:
67   case IDLN_FORWARD_DCL:
68   default:
69     return FALSE;
70     break;
71   }
72
73   return FALSE;
74 }
75
76 /**
77     Gets the "type" of {tree} as known in C.
78     The return value was alloc'd via g_malloc, and must be g_free'd.
79 **/
80 char *
81 forb_cbe_get_typespec_str(IDL_tree tree)
82 {
83   char *retval = NULL;
84   GString *tmpstr = NULL;
85
86   if(!tree) {
87     return g_strdup("void");
88   }
89
90   switch(IDL_NODE_TYPE(tree)) {
91   case IDLN_MEMBER:
92     return forb_cbe_get_typespec_str(IDL_MEMBER(tree).type_spec);
93     break;
94   case IDLN_TYPE_ANY:
95     retval = "CORBA_any";
96     break;
97   case IDLN_TYPE_FLOAT:
98     switch(IDL_TYPE_FLOAT(tree).f_type) {
99     case IDL_FLOAT_TYPE_FLOAT:
100       retval = "CORBA_float";
101       break;
102     case IDL_FLOAT_TYPE_DOUBLE:
103       retval = "CORBA_double";
104       break;
105     case IDL_FLOAT_TYPE_LONGDOUBLE:
106       retval = "CORBA_long_double";
107       break;
108     }
109     break;
110   case IDLN_TYPE_FIXED:
111     return g_strdup_printf( "CORBA_fixed_%" IDL_LL "d_%" IDL_LL "d",
112                      IDL_INTEGER(IDL_TYPE_FIXED(tree).positive_int_const).value,
113                      IDL_INTEGER(IDL_TYPE_FIXED(tree).integer_lit).value);
114     break;
115   case IDLN_TYPE_INTEGER:
116     tmpstr = g_string_new(NULL);
117     g_string_append(tmpstr, "CORBA_");
118     if(!IDL_TYPE_INTEGER(tree).f_signed)
119         g_string_append(tmpstr, "unsigned_");
120
121     switch(IDL_TYPE_INTEGER(tree).f_type) {
122     case IDL_INTEGER_TYPE_SHORT:
123         g_string_append(tmpstr, "short");
124         break;
125     case IDL_INTEGER_TYPE_LONGLONG:
126         g_string_append(tmpstr, "long_");
127         /* FALLTHROUGH */
128     case IDL_INTEGER_TYPE_LONG:
129         g_string_append(tmpstr, "long");
130         break;
131     }
132     break;
133   case IDLN_TYPE_STRING:
134     retval = "CORBA_string";    /* this is non-standard! */
135     break;
136   case IDLN_TYPE_OCTET:
137     retval = "CORBA_octet";
138     break;
139   case IDLN_TYPE_WIDE_STRING:
140     retval = "CORBA_wstring";   /* this is non-standard! */
141     break;
142   case IDLN_TYPE_CHAR:
143     retval = "CORBA_char";
144     break;
145   case IDLN_TYPE_WIDE_CHAR:
146     retval = "CORBA_wchar";
147     break;
148   case IDLN_TYPE_BOOLEAN:
149     retval = "CORBA_boolean";
150     break;
151   case IDLN_TYPE_STRUCT:
152     return forb_cbe_get_typespec_str(IDL_TYPE_STRUCT(tree).ident);
153   case IDLN_EXCEPT_DCL:
154     return forb_cbe_get_typespec_str(IDL_EXCEPT_DCL(tree).ident);
155   case IDLN_TYPE_ARRAY:
156     return forb_cbe_get_typespec_str(IDL_TYPE_ARRAY(tree).ident);
157   case IDLN_TYPE_UNION:
158     return forb_cbe_get_typespec_str(IDL_TYPE_UNION(tree).ident);
159   case IDLN_TYPE_ENUM:
160     return forb_cbe_get_typespec_str(IDL_TYPE_ENUM(tree).ident);
161   case IDLN_IDENT:
162     return IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(tree), "_", 0);
163   case IDLN_PARAM_DCL:
164     return forb_cbe_get_typespec_str(IDL_PARAM_DCL(tree).param_type_spec);
165   case IDLN_TYPE_SEQUENCE:
166     {
167         IDL_tree subtype = IDL_TYPE_SEQUENCE(tree).simple_type_spec;
168         char *ctmp, *base;
169         ctmp = forb_cbe_get_typespec_str(subtype);
170         /* We should have built-in alias to make this next line not needed */
171         base = forb_cbe_type_is_builtin(subtype)
172           ? ctmp + strlen("CORBA_") : ctmp;
173         retval = g_strdup_printf( "CORBA_sequence_%s", base);
174         g_free(ctmp);
175         return retval;
176     }
177     break;
178   case IDLN_NATIVE:
179     retval = "gpointer";
180     break;
181   case IDLN_FORWARD_DCL:
182   case IDLN_INTERFACE:
183     return forb_cbe_get_typespec_str(IDL_INTERFACE(tree).ident);
184   case IDLN_TYPE_OBJECT:
185     retval = "CORBA_Object";
186     break;
187   case IDLN_TYPE_TYPECODE:
188     retval = "CORBA_TypeCode";
189     break;
190   default:
191     g_error("We were asked to get a typename for a %s",
192             IDL_tree_type_names[IDL_NODE_TYPE(tree)]);
193     break;
194   }
195
196   if (retval)
197     return g_strdup (retval);
198   else
199     return g_string_free (tmpstr, FALSE);
200 }
201
202 void
203 forb_cbe_write_typespec(FILE *of, IDL_tree tree)
204 {
205     char *name = forb_cbe_get_typespec_str(tree);
206     fprintf( of, name);
207     g_free(name);
208 }
209
210 /**
211     Parameters (e.g., arguments to methods, and the return value
212     have some complicated rules in the C mapping for how many
213     levels of pointer and the exact type involved. This function
214     generates the externally visible parameter type.
215
216     Note the hack below because "const CORBA_string" is not
217     promotable to "const CORBA_char*" (the later the standard
218     to which apps are written, while the former is what would
219     be produced without the hack).
220 **/
221 static char *
222 forb_cbe_write_param_typespec_str(IDL_tree ts, IDL_ParamRole role)
223 {
224         int      i, n;
225         gboolean isSlice;
226         char    *name;
227         GString *str = g_string_sized_new (23);
228         IDL_tree typedef_spec;
229         char *typedef_name;
230
231         n = oidl_param_info (ts, role, &isSlice);
232         name = forb_cbe_get_typespec_str (ts);
233
234         if ( role == DATA_IN ) {
235                 /* We want to check if this is a typedef for CORBA_string so we can do special handling 
236                  * in that case. 
237                  */
238                 typedef_spec = forb_cbe_get_typespec (ts);
239                 typedef_name = forb_cbe_get_typespec_str (typedef_spec);
240
241                 g_string_printf (str, "const %s", 
242                                  !strcmp (typedef_name, "CORBA_string") ?
243                                  "CORBA_char *" : name);
244
245                 g_free (typedef_name);
246         } else
247                 g_string_printf (str, "%s", name);
248
249         g_free (name);
250
251         if ( isSlice )
252                 g_string_append (str, "_slice");
253
254         for (i = 0; i < n; i++)
255                 g_string_append_c (str, '*');
256
257         return g_string_free (str, FALSE);
258 }
259
260 static void
261 forb_cbe_write_param_typespec_raw (FILE *of, IDL_tree ts, IDL_ParamRole role)
262 {
263     char *str;
264     str = forb_cbe_write_param_typespec_str (ts, role);
265     fprintf (of, str);
266     g_free (str);
267 }
268
269 void
270 forb_cbe_write_param_typespec(FILE *of, IDL_tree tree) {
271     IDL_tree            ts = NULL /* Quiet gcc */;
272     IDL_ParamRole       role = 0 /* Quiet gcc */;
273
274     switch ( IDL_NODE_TYPE(tree) ) {
275     case IDLN_OP_DCL: /* means return value of method */
276         ts = IDL_OP_DCL(tree).op_type_spec;
277         role = DATA_RETURN;
278         break;
279     case IDLN_PARAM_DCL: /* one of the parameters */
280         ts = IDL_PARAM_DCL(tree).param_type_spec;
281         role = oidl_attr_to_paramrole(IDL_PARAM_DCL(tree).attr);
282         break;
283     default:
284         g_assert_not_reached();
285     }
286     forb_cbe_write_param_typespec_raw(of, ts, role);
287 }
288
289 void
290 forb_cbe_op_write_proto (FILE       *of,
291                           IDL_tree    op,
292                           const char *nom_prefix,
293                           gboolean    for_epv)
294 {
295         IDL_tree  sub;
296         char     *id;
297
298         g_assert (IDL_NODE_TYPE(op) == IDLN_OP_DCL);
299
300         forb_cbe_write_param_typespec (of, op);
301
302         id = IDL_ns_ident_to_qstring (
303                 IDL_IDENT_TO_NS (IDL_INTERFACE (
304                         IDL_get_parent_node (op, IDLN_INTERFACE, NULL)).ident), "_", 0);
305
306         if (for_epv)
307                 fprintf (of, "\t(*%s%s)", nom_prefix ? nom_prefix : "",
308                          IDL_IDENT(IDL_OP_DCL(op).ident).str);
309         else 
310                 fprintf (of, " %s%s_%s", nom_prefix ? nom_prefix : "",
311                          id, IDL_IDENT (IDL_OP_DCL (op).ident).str);
312
313         fprintf (of, "(");
314
315 /*      if (for_epv) */
316 /*              fprintf (of, "PortableServer_Servant _servant, "); */
317 /*      else */
318                 fprintf (of, "%s _obj, ", id);
319
320         g_free (id);
321
322         for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
323                 IDL_tree parm = IDL_LIST (sub).data;
324
325                 forb_cbe_write_param_typespec (of, parm);
326
327                 fprintf (of, " %s, ", IDL_IDENT (IDL_PARAM_DCL (parm).simple_declarator).str);
328         }
329
330         if (IDL_OP_DCL (op).context_expr)
331                 fprintf (of, "CORBA_Context _ctx, ");
332
333         fprintf (of, "CORBA_Environment *ev)");
334 }
335
336 /* Writes the value of the constant in 'tree' to file handle 'of' */
337 static char *
338 forb_cbe_get_const(IDL_tree tree)
339 {
340   char *opc = NULL, *retval, *ctmp;
341   GString *tmpstr = g_string_new(NULL);
342
343   switch(IDL_NODE_TYPE(tree)) {
344   case IDLN_BOOLEAN:
345     g_string_printf(tmpstr, "%s", IDL_BOOLEAN(tree).value?"CORBA_TRUE":"CORBA_FALSE");
346     break;
347   case IDLN_CHAR:
348     g_string_printf(tmpstr, "'\\x%X'", *(unsigned char *)IDL_CHAR(tree).value);
349     break;
350   case IDLN_FLOAT:
351     g_string_printf(tmpstr, "%f", IDL_FLOAT(tree).value);
352     break;
353   case IDLN_INTEGER:
354     g_string_printf(tmpstr, "%" IDL_LL "d", IDL_INTEGER(tree).value);
355     break;
356   case IDLN_STRING:
357     g_string_printf(tmpstr, "\"%s\"", IDL_STRING(tree).value);
358     break;
359   case IDLN_WIDE_CHAR:
360     g_string_printf(tmpstr, "L'%ls'", IDL_WIDE_CHAR(tree).value);
361     break;
362   case IDLN_WIDE_STRING:
363     g_string_printf(tmpstr, "L\"%ls\"", IDL_WIDE_STRING(tree).value);
364     break;
365   case IDLN_BINOP:
366     g_string_printf(tmpstr, "(");
367     ctmp = forb_cbe_get_const(IDL_BINOP(tree).left);
368     g_string_append(tmpstr, ctmp);
369     g_free(ctmp);
370     switch(IDL_BINOP(tree).op) {
371     case IDL_BINOP_OR:
372       opc = "|";
373       break;
374     case IDL_BINOP_XOR:
375       opc = "^";
376       break;
377     case IDL_BINOP_AND:
378       opc = "&";
379       break;
380     case IDL_BINOP_SHR:
381       opc = ">>";
382       break;
383     case IDL_BINOP_SHL:
384       opc = "<<";
385       break;
386     case IDL_BINOP_ADD:
387       opc = "+";
388       break;
389     case IDL_BINOP_SUB:
390       opc = "-";
391       break;
392     case IDL_BINOP_MULT:
393       opc = "*";
394       break;
395     case IDL_BINOP_DIV:
396       opc = "/";
397       break;
398     case IDL_BINOP_MOD:
399       opc = "%";
400       break;
401     }
402     g_string_append_printf(tmpstr, " %s ", opc);
403     ctmp = forb_cbe_get_const(IDL_BINOP(tree).right);
404     g_string_append_printf(tmpstr, "%s)", ctmp);
405     g_free(ctmp);
406     break;
407   case IDLN_UNARYOP:
408     switch(IDL_UNARYOP(tree).op) {
409     case IDL_UNARYOP_PLUS: opc = "+"; break;
410     case IDL_UNARYOP_MINUS: opc = "-"; break;
411     case IDL_UNARYOP_COMPLEMENT: opc = "~"; break;
412     }
413     ctmp = forb_cbe_get_const(IDL_UNARYOP(tree).operand);
414     g_string_printf(tmpstr, "%s%s", opc, ctmp);
415     g_free(ctmp);
416     break;
417   case IDLN_IDENT:
418     {
419       char *id;
420       id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(tree), "_", 0);
421       g_string_printf(tmpstr, "%s", id);
422       g_free(id);
423     }
424     break;
425   default:
426     g_error("We were asked to print a constant for %s", IDL_tree_type_names[tree->_type]);
427     break;
428   }
429
430   retval = tmpstr->str;
431
432   g_string_free(tmpstr, FALSE);
433
434   return retval;
435 }
436
437 void
438 forb_cbe_write_const(FILE *of, IDL_tree tree)
439 {
440   char *ctmp;
441
442   ctmp = forb_cbe_get_const(tree);
443   fprintf(of, "%s", ctmp);
444   g_free(ctmp);
445 }
446
447 /* This is the WORST HACK in the WORLD, really truly, but the C preprocessor doesn't allow us to use
448    strings, so we have to work around it by using individual characters. */
449 void
450 forb_cbe_id_define_hack(FILE *fh, const char *def_prefix, const char *def_name, const char *def_value)
451 {
452   int i, n;
453   n = strlen(def_value);
454   for(i = 0; i < n; i++)
455     fprintf(fh, "#define %s_%s_%d '%c'\n", def_prefix, def_name, i, def_value[i]);
456 }
457
458 void
459 forb_cbe_id_cond_hack(FILE *fh, const char *def_prefix, const char *def_name, const char *def_value)
460 {
461   int i, n;
462   n = strlen(def_value);
463   if(n <= 0)
464     return;
465
466   fprintf(fh, "(");
467
468   for(i = 0; i < n; i++)
469     fprintf(fh, "%s (%s_%s_%d == '%c') \\\n", i?"&&":"", def_prefix, def_name, i, def_value[i]);
470   fprintf(fh, ")");
471 }
472
473 #define BASE_TYPES \
474              IDLN_TYPE_INTEGER: \
475         case IDLN_TYPE_FLOAT: \
476         case IDLN_TYPE_ENUM: \
477         case IDLN_TYPE_BOOLEAN: \
478         case IDLN_TYPE_CHAR: \
479         case IDLN_TYPE_WIDE_CHAR: \
480         case IDLN_TYPE_OCTET
481
482 #define STRING_TYPES \
483              IDLN_TYPE_STRING: \
484         case IDLN_TYPE_WIDE_STRING
485
486 #define OBJREF_TYPES \
487              IDLN_TYPE_OBJECT: \
488         case IDLN_INTERFACE: \
489         case IDLN_FORWARD_DCL
490
491 static const char *
492 forb_cbe_flatten_ref (IDL_ParamRole role, IDL_tree typespec)
493 {
494         gboolean is_fixed;
495
496         is_fixed = forb_cbe_type_is_fixed_length (typespec);
497
498         switch (role) {
499         case DATA_IN:
500                 switch (IDL_NODE_TYPE (typespec)) {
501                 case BASE_TYPES:
502                 case STRING_TYPES:
503                 case OBJREF_TYPES:
504                 case IDLN_TYPE_TYPECODE:
505                 case IDLN_NATIVE:
506                         return "(gpointer)&";
507
508                 case IDLN_TYPE_STRUCT:
509                 case IDLN_TYPE_UNION:
510                 case IDLN_TYPE_ANY:
511                 case IDLN_TYPE_SEQUENCE:
512                 case IDLN_TYPE_ARRAY:
513                         return "(gpointer)";
514                         
515                 default:
516                 case IDLN_TYPE_FIXED:
517                         g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
518                 };
519                 return NULL;
520
521         case DATA_INOUT:
522                 switch (IDL_NODE_TYPE (typespec)) {
523                 case BASE_TYPES:
524                 case STRING_TYPES:
525                 case OBJREF_TYPES:
526                 case IDLN_TYPE_TYPECODE:
527                 case IDLN_TYPE_STRUCT:
528                 case IDLN_TYPE_UNION:
529                 case IDLN_TYPE_ARRAY:
530                 case IDLN_NATIVE:
531                 case IDLN_TYPE_ANY:
532                 case IDLN_TYPE_SEQUENCE:
533                         return "";
534
535                 default:
536                 case IDLN_TYPE_FIXED:
537                         g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
538                 };
539                 return NULL;
540
541         case DATA_OUT:
542                 switch (IDL_NODE_TYPE (typespec)) {
543                 case BASE_TYPES:
544                 case STRING_TYPES:
545                 case OBJREF_TYPES:
546                 case IDLN_TYPE_TYPECODE:
547                 case IDLN_NATIVE:
548                         return "&";
549
550                 case IDLN_TYPE_STRUCT:
551                 case IDLN_TYPE_UNION:
552                 case IDLN_TYPE_ARRAY:
553                         if (is_fixed)
554                                 return "&";
555                         else /* drop through */
556
557                 case IDLN_TYPE_SEQUENCE:
558                 case IDLN_TYPE_ANY:
559                         return "";
560
561                 default:
562                 case IDLN_TYPE_FIXED:
563                         g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
564                 };
565                 return NULL;
566
567         case DATA_RETURN:
568                 g_error ("No data return handler");
569                 return NULL;
570         }
571
572         return NULL;
573 }
574
575 void
576 forb_cbe_flatten_args (IDL_tree tree, FILE *of, const char *name)
577 {
578         int i = 0;
579         IDL_tree l;
580
581         for (l = IDL_OP_DCL(tree).parameter_dcls; l;
582              l = IDL_LIST(l).next)
583                 i++;
584
585         fprintf (of, "gpointer %s[%d];\n", name, i);
586         
587         i = 0;
588         for (l = IDL_OP_DCL(tree).parameter_dcls; l;
589              l = IDL_LIST(l).next) {
590                 IDL_tree decl = IDL_LIST (l).data;
591                 IDL_tree tspec = forb_cbe_get_typespec (decl);
592                 IDL_ParamRole r = 0;
593
594                 switch(IDL_PARAM_DCL(decl).attr) {
595                 case IDL_PARAM_IN:    r = DATA_IN;    break;
596                 case IDL_PARAM_INOUT: r = DATA_INOUT; break;
597                 case IDL_PARAM_OUT:   r = DATA_OUT;   break;
598                 default:
599                         g_error("Unknown IDL_PARAM type");
600                 }
601                 
602                 fprintf (of, "%s[%d] = %s%s;\n",
603                          name, i,
604                          forb_cbe_flatten_ref (r, tspec),
605                          IDL_IDENT (IDL_PARAM_DCL (decl).simple_declarator).str);
606                 i++;
607         }
608 }
609
610 static char *
611 forb_cbe_unflatten_ref (IDL_ParamRole role, IDL_tree typespec)
612 {
613         gboolean is_fixed;
614         char    *typestr;
615         char    *retval;
616
617         is_fixed = forb_cbe_type_is_fixed_length (typespec);
618
619         typestr = forb_cbe_write_param_typespec_str (typespec, role);
620
621         switch (role) {
622         case DATA_IN:
623                 switch (IDL_NODE_TYPE (typespec)) {
624                 case BASE_TYPES:
625                 case STRING_TYPES:
626                 case OBJREF_TYPES:
627                 case IDLN_TYPE_TYPECODE:
628                 case IDLN_NATIVE:
629                         retval = g_strdup_printf ("*(%s *)", typestr);
630                         break;
631
632
633                 case IDLN_TYPE_ARRAY:
634                         retval = g_strdup_printf ("(%s_slice *)", typestr);
635                         break;
636
637                 case IDLN_TYPE_STRUCT:
638                 case IDLN_TYPE_UNION:
639                 case IDLN_TYPE_ANY:
640                 case IDLN_TYPE_SEQUENCE:
641                         retval = g_strdup_printf ("(%s)", typestr);
642                         break;
643                         
644                 default:
645                 case IDLN_TYPE_FIXED:
646                         g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
647                         retval = NULL;
648                         break;
649                 };
650                 break;
651
652         case DATA_INOUT:
653                 switch (IDL_NODE_TYPE (typespec)) {
654                 case IDLN_TYPE_ARRAY:
655                         retval = g_strdup_printf ("(%s_slice *)", typestr);
656                         break;
657
658                 case BASE_TYPES:
659                 case STRING_TYPES:
660                 case OBJREF_TYPES:
661                 case IDLN_TYPE_TYPECODE:
662                 case IDLN_TYPE_STRUCT:
663                 case IDLN_TYPE_UNION:
664                 case IDLN_NATIVE:
665                 case IDLN_TYPE_ANY:
666                 case IDLN_TYPE_SEQUENCE:
667                         retval = g_strdup_printf ("(%s)", typestr);
668                         break;
669
670                 default:
671                 case IDLN_TYPE_FIXED:
672                         g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
673                         retval = NULL;
674                         break;
675                 };
676                 break;
677
678         case DATA_OUT:
679                 switch (IDL_NODE_TYPE (typespec)) {
680                 case BASE_TYPES:
681                 case STRING_TYPES:
682                 case OBJREF_TYPES:
683                 case IDLN_TYPE_TYPECODE:
684                 case IDLN_NATIVE:
685                         retval = g_strdup_printf ("*(%s *)", typestr);
686                         break;
687
688                 case IDLN_TYPE_ARRAY:
689                         if (is_fixed) {
690                                 retval = g_strdup_printf ("*(%s_slice **)", typestr);
691                                 break;
692                         }
693                         /* drop through */
694
695                 case IDLN_TYPE_STRUCT:
696                 case IDLN_TYPE_UNION:
697                         if (is_fixed) {
698                                 retval = g_strdup_printf ("*(%s *)", typestr);
699                                 break;
700                         }
701                         /* drop through */
702
703                 case IDLN_TYPE_SEQUENCE:
704                 case IDLN_TYPE_ANY:
705                         retval = g_strdup_printf ("(%s)", typestr);
706                         break;
707
708                 default:
709                 case IDLN_TYPE_FIXED:
710                         g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
711                         retval = NULL;
712                         break;
713                 };
714                 break;
715
716         case DATA_RETURN:
717         default:
718                 g_error ("No data return handler");
719                 retval = NULL;
720                 break;
721         }
722
723         g_free (typestr);
724
725         return retval;
726 }
727
728 void
729 forb_cbe_unflatten_args (IDL_tree tree, FILE *of, const char *name)
730 {
731         IDL_tree l;
732         int      i = 0;
733
734         for (l = IDL_OP_DCL(tree).parameter_dcls; l;
735              l = IDL_LIST(l).next) {
736                 IDL_tree decl = IDL_LIST (l).data;
737                 IDL_tree tspec = forb_cbe_get_typespec (decl);
738                 IDL_ParamRole r = 0;
739                 char *unflatten;
740
741                 switch(IDL_PARAM_DCL(decl).attr) {
742                 case IDL_PARAM_IN:    r = DATA_IN;    break;
743                 case IDL_PARAM_INOUT: r = DATA_INOUT; break;
744                 case IDL_PARAM_OUT:   r = DATA_OUT;   break;
745                 default:
746                         g_error("Unknown IDL_PARAM type");
747                 }
748
749                 unflatten = forb_cbe_unflatten_ref (r, tspec);
750                 fprintf (of, "%s%s[%d], ", unflatten, name, i++);
751                 g_free (unflatten);
752         }
753 }