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