3 #include "forb-idl-c-backend.h"
12 * @param ts Type spec.
14 * @param use_name use identifier from name
15 * @param var_prefix prefix for identifier taken from name
16 * @param serialization
19 forb_cbe_write_ser_var(FILE *of, IDL_tree ts, IDL_tree name,
22 enum forb_ser serialization)
25 GString *id = g_string_new("");
26 char *serialize = (serialization == SERIALIZE) ? "serialize" : "deserialize";
27 gboolean use_ampersand = TRUE;
29 switch(IDL_NODE_TYPE(name)) {
33 g_string_assign(id, IDL_IDENT(name).str);
35 if (IDL_NODE_TYPE(forb_cbe_get_typespec(ts)) == IDLN_TYPE_ARRAY)
36 use_ampersand = FALSE;
38 /* printf("%s%s:\n", var_prefix, use_name ? id->str:""); */
39 /* forb_idl_print_node(forb_cbe_get_typespec(ts), 2); */
47 g_string_assign(id, IDL_IDENT(IDL_TYPE_ARRAY(name).ident).str);
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)
55 g_string_append_printf(id, "[%c]", var);
61 for(curitem = IDL_TYPE_ARRAY(name).size_list; curitem; curitem = IDL_LIST(curitem).next) {
63 for (i=0; i<indent+1; i++)
65 fprintf(of, "for (%c=0; %c<%" PRId64 "; %c++) \n",
66 var, var, IDL_INTEGER(IDL_LIST(curitem).data).value, var);
71 for (i=0; i<indent+2; i++)
77 g_error("Weird varname - %s", IDL_tree_type_names[IDL_NODE_TYPE(name)]);
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);
87 g_string_free(id, TRUE);
92 forb_cbe_get_typecode_name (IDL_tree tree)
95 return g_strdup ("TC_FIXME");
97 return g_strconcat ("TC_", forb_cbe_get_typespec_str (tree), NULL);
101 forb_cbe_type_is_builtin(IDL_tree tree)
104 switch(IDL_NODE_TYPE(tree)) {
113 g_error("Strange type for being a builtin");
117 case IDLN_WIDE_STRING:
124 case IDLN_TYPE_INTEGER:
125 case IDLN_TYPE_FLOAT:
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:
133 case IDLN_TYPE_OBJECT:
134 case IDLN_TYPE_TYPECODE:
136 case IDLN_TYPE_SEQUENCE:
140 case IDLN_EXCEPT_DCL:
144 case IDLN_TYPE_FIXED:
145 case IDLN_TYPE_ARRAY:
146 case IDLN_TYPE_STRUCT:
147 case IDLN_TYPE_UNION:
150 case IDLN_FORWARD_DCL:
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.
165 forb_cbe_get_typespec_str(IDL_tree tree)
168 GString *tmpstr = NULL;
171 return g_strdup("void");
174 switch(IDL_NODE_TYPE(tree)) {
176 return forb_cbe_get_typespec_str(IDL_MEMBER(tree).type_spec);
179 retval = "CORBA_any";
181 case IDLN_TYPE_FLOAT:
182 switch(IDL_TYPE_FLOAT(tree).f_type) {
183 case IDL_FLOAT_TYPE_FLOAT:
184 retval = "CORBA_float";
186 case IDL_FLOAT_TYPE_DOUBLE:
187 retval = "CORBA_double";
189 case IDL_FLOAT_TYPE_LONGDOUBLE:
190 retval = "CORBA_long_double";
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);
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_");
205 switch(IDL_TYPE_INTEGER(tree).f_type) {
206 case IDL_INTEGER_TYPE_SHORT:
207 g_string_append(tmpstr, "short");
209 case IDL_INTEGER_TYPE_LONGLONG:
210 g_string_append(tmpstr, "long_");
212 case IDL_INTEGER_TYPE_LONG:
213 g_string_append(tmpstr, "long");
217 case IDLN_TYPE_STRING:
218 retval = "CORBA_string"; /* this is non-standard! */
220 case IDLN_TYPE_OCTET:
221 retval = "CORBA_octet";
223 case IDLN_TYPE_WIDE_STRING:
224 retval = "CORBA_wstring"; /* this is non-standard! */
227 retval = "CORBA_char";
229 case IDLN_TYPE_WIDE_CHAR:
230 retval = "CORBA_wchar";
232 case IDLN_TYPE_BOOLEAN:
233 retval = "CORBA_boolean";
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);
244 return forb_cbe_get_typespec_str(IDL_TYPE_ENUM(tree).ident);
246 return IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(tree), "_", 0);
248 return forb_cbe_get_typespec_str(IDL_PARAM_DCL(tree).param_type_spec);
249 case IDLN_TYPE_SEQUENCE:
251 IDL_tree subtype = IDL_TYPE_SEQUENCE(tree).simple_type_spec;
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);
263 retval = forb_cbe_get_typespec_str(IDL_NATIVE(tree).ident);
265 case IDLN_FORWARD_DCL:
267 return forb_cbe_get_typespec_str(IDL_INTERFACE(tree).ident);
268 case IDLN_TYPE_OBJECT:
269 retval = "CORBA_Object";
271 case IDLN_TYPE_TYPECODE:
272 retval = "CORBA_TypeCode";
275 g_error("We were asked to get a typename for a %s",
276 IDL_tree_type_names[IDL_NODE_TYPE(tree)]);
281 return g_strdup (retval);
283 return g_string_free (tmpstr, FALSE);
287 forb_cbe_write_typespec(FILE *of, IDL_tree tree)
289 char *name = forb_cbe_get_typespec_str(tree);
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.
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).
306 forb_cbe_write_param_typespec_str(IDL_tree ts, IDL_ParamRole role)
311 GString *str = g_string_sized_new (23);
312 IDL_tree typedef_spec;
315 n = oidl_param_info (ts, role, &isSlice);
316 name = forb_cbe_get_typespec_str (ts);
318 if ( role == DATA_IN ) {
319 /* We want to check if this is a typedef for CORBA_string so we can do special handling
322 typedef_spec = forb_cbe_get_typespec (ts);
323 typedef_name = forb_cbe_get_typespec_str (typedef_spec);
325 g_string_printf (str, "const %s",
326 !strcmp (typedef_name, "CORBA_string") ?
327 "CORBA_char *" : name);
329 g_free (typedef_name);
331 g_string_printf (str, "%s", name);
336 g_string_append (str, "_slice");
338 for (i = 0; i < n; i++)
339 g_string_append_c (str, '*');
341 return g_string_free (str, FALSE);
345 forb_cbe_write_param_typespec_raw (FILE *of, IDL_tree ts, IDL_ParamRole role)
348 str = forb_cbe_write_param_typespec_str (ts, role);
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 */;
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;
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);
368 g_assert_not_reached();
370 forb_cbe_write_param_typespec_raw(of, ts, role);
374 forb_cbe_op_write_proto (FILE *of,
376 const char *nom_prefix,
382 g_assert (IDL_NODE_TYPE(op) == IDLN_OP_DCL);
384 forb_cbe_write_param_typespec (of, op);
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);
391 fprintf (of, "\t(*%s%s)", nom_prefix ? nom_prefix : "",
392 IDL_IDENT(IDL_OP_DCL(op).ident).str);
394 fprintf (of, " %s%s_%s", nom_prefix ? nom_prefix : "",
395 id, IDL_IDENT (IDL_OP_DCL (op).ident).str);
400 /* fprintf (of, "PortableServer_Servant _servant, "); */
402 fprintf (of, "%s _obj, ", id);
406 for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
407 IDL_tree parm = IDL_LIST (sub).data;
409 forb_cbe_write_param_typespec (of, parm);
411 fprintf (of, " %s, ", IDL_IDENT (IDL_PARAM_DCL (parm).simple_declarator).str);
414 if (IDL_OP_DCL (op).context_expr)
415 fprintf (of, "CORBA_Context _ctx, ");
417 fprintf (of, "CORBA_Environment *ev)");
420 /* Writes the value of the constant in 'tree' to file handle 'of' */
422 forb_cbe_get_const(IDL_tree tree)
424 char *opc = NULL, *retval, *ctmp;
425 GString *tmpstr = g_string_new(NULL);
427 switch(IDL_NODE_TYPE(tree)) {
429 g_string_printf(tmpstr, "%s", IDL_BOOLEAN(tree).value?"CORBA_TRUE":"CORBA_FALSE");
432 g_string_printf(tmpstr, "'\\x%X'", *(unsigned char *)IDL_CHAR(tree).value);
435 g_string_printf(tmpstr, "%f", IDL_FLOAT(tree).value);
438 g_string_printf(tmpstr, "%" PRId64 "", IDL_INTEGER(tree).value);
441 g_string_printf(tmpstr, "\"%s\"", IDL_STRING(tree).value);
444 g_string_printf(tmpstr, "L'%ls'", IDL_WIDE_CHAR(tree).value);
446 case IDLN_WIDE_STRING:
447 g_string_printf(tmpstr, "L\"%ls\"", IDL_WIDE_STRING(tree).value);
450 g_string_printf(tmpstr, "(");
451 ctmp = forb_cbe_get_const(IDL_BINOP(tree).left);
452 g_string_append(tmpstr, ctmp);
454 switch(IDL_BINOP(tree).op) {
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);
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;
497 ctmp = forb_cbe_get_const(IDL_UNARYOP(tree).operand);
498 g_string_printf(tmpstr, "%s%s", opc, ctmp);
504 id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(tree), "_", 0);
505 g_string_printf(tmpstr, "%s", id);
510 g_error("We were asked to print a constant for %s", IDL_tree_type_names[tree->_type]);
514 retval = tmpstr->str;
516 g_string_free(tmpstr, FALSE);
522 forb_cbe_write_const(FILE *of, IDL_tree tree)
526 ctmp = forb_cbe_get_const(tree);
527 fprintf(of, "%s", ctmp);
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. */
534 forb_cbe_id_define_hack(FILE *fh, const char *def_prefix, const char *def_name, const char *def_value)
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]);
543 forb_cbe_id_cond_hack(FILE *fh, const char *def_prefix, const char *def_name, const char *def_value)
546 n = strlen(def_value);
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]);
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: \
566 #define STRING_TYPES \
568 case IDLN_TYPE_WIDE_STRING
570 #define OBJREF_TYPES \
572 case IDLN_INTERFACE: \
573 case IDLN_FORWARD_DCL
576 forb_cbe_flatten_ref (IDL_ParamRole role, IDL_tree typespec)
580 is_fixed = forb_cbe_type_is_fixed_length (typespec);
584 switch (IDL_NODE_TYPE (typespec)) {
588 case IDLN_TYPE_TYPECODE:
590 return "(gpointer)&";
592 case IDLN_TYPE_STRUCT:
593 case IDLN_TYPE_UNION:
595 case IDLN_TYPE_SEQUENCE:
596 case IDLN_TYPE_ARRAY:
600 case IDLN_TYPE_FIXED:
601 g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
606 switch (IDL_NODE_TYPE (typespec)) {
610 case IDLN_TYPE_TYPECODE:
611 case IDLN_TYPE_STRUCT:
612 case IDLN_TYPE_UNION:
613 case IDLN_TYPE_ARRAY:
616 case IDLN_TYPE_SEQUENCE:
620 case IDLN_TYPE_FIXED:
621 g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
626 switch (IDL_NODE_TYPE (typespec)) {
630 case IDLN_TYPE_TYPECODE:
634 case IDLN_TYPE_STRUCT:
635 case IDLN_TYPE_UNION:
636 case IDLN_TYPE_ARRAY:
639 else /* drop through */
641 case IDLN_TYPE_SEQUENCE:
646 case IDLN_TYPE_FIXED:
647 g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
652 g_error ("No data return handler");
660 forb_cbe_flatten_args (IDL_tree tree, FILE *of, const char *name)
665 for (l = IDL_OP_DCL(tree).parameter_dcls; l;
666 l = IDL_LIST(l).next)
669 fprintf (of, "gpointer %s[%d];\n", name, i);
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);
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;
683 g_error("Unknown IDL_PARAM type");
686 fprintf (of, "%s[%d] = %s%s;\n",
688 forb_cbe_flatten_ref (r, tspec),
689 IDL_IDENT (IDL_PARAM_DCL (decl).simple_declarator).str);
695 forb_cbe_unflatten_ref (IDL_ParamRole role, IDL_tree typespec)
701 is_fixed = forb_cbe_type_is_fixed_length (typespec);
703 typestr = forb_cbe_write_param_typespec_str (typespec, role);
707 switch (IDL_NODE_TYPE (typespec)) {
711 case IDLN_TYPE_TYPECODE:
713 retval = g_strdup_printf ("*(%s *)", typestr);
717 case IDLN_TYPE_ARRAY:
718 retval = g_strdup_printf ("(%s_slice *)", typestr);
721 case IDLN_TYPE_STRUCT:
722 case IDLN_TYPE_UNION:
724 case IDLN_TYPE_SEQUENCE:
725 retval = g_strdup_printf ("(%s)", typestr);
729 case IDLN_TYPE_FIXED:
730 g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
737 switch (IDL_NODE_TYPE (typespec)) {
738 case IDLN_TYPE_ARRAY:
739 retval = g_strdup_printf ("(%s_slice *)", typestr);
745 case IDLN_TYPE_TYPECODE:
746 case IDLN_TYPE_STRUCT:
747 case IDLN_TYPE_UNION:
750 case IDLN_TYPE_SEQUENCE:
751 retval = g_strdup_printf ("(%s)", typestr);
755 case IDLN_TYPE_FIXED:
756 g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
763 switch (IDL_NODE_TYPE (typespec)) {
767 case IDLN_TYPE_TYPECODE:
769 retval = g_strdup_printf ("*(%s *)", typestr);
772 case IDLN_TYPE_ARRAY:
774 retval = g_strdup_printf ("*(%s_slice **)", typestr);
779 case IDLN_TYPE_STRUCT:
780 case IDLN_TYPE_UNION:
782 retval = g_strdup_printf ("*(%s *)", typestr);
787 case IDLN_TYPE_SEQUENCE:
789 retval = g_strdup_printf ("(%s)", typestr);
793 case IDLN_TYPE_FIXED:
794 g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
802 g_error ("No data return handler");
813 forb_cbe_unflatten_args (IDL_tree tree, FILE *of, const char *name)
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);
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;
830 g_error("Unknown IDL_PARAM type");
833 unflatten = forb_cbe_unflatten_ref (r, tspec);
834 fprintf (of, "%s%s[%d], ", unflatten, name, i++);