3 #include "forb-idl-c-backend.h"
11 * @param ts Type spec.
13 * @param use_name use identifier from name
14 * @param var_prefix prefix for identifier taken from name
15 * @param serialization
18 forb_cbe_write_ser_var(FILE *of, IDL_tree ts, IDL_tree name,
21 enum forb_ser serialization)
24 GString *id = g_string_new("");
25 char *serialize = (serialization == SERIALIZE) ? "serialize" : "deserialize";
26 gboolean use_ampersand = TRUE;
28 switch(IDL_NODE_TYPE(name)) {
32 g_string_assign(id, IDL_IDENT(name).str);
34 if (IDL_NODE_TYPE(forb_cbe_get_typespec(ts)) == IDLN_TYPE_ARRAY)
35 use_ampersand = FALSE;
37 /* printf("%s%s:\n", var_prefix, use_name ? id->str:""); */
38 /* forb_idl_print_node(forb_cbe_get_typespec(ts), 2); */
46 g_string_assign(id, IDL_IDENT(IDL_TYPE_ARRAY(name).ident).str);
49 fprintf(of, " {\n CORBA_unsigned_long ");
50 for(curitem = IDL_TYPE_ARRAY(name).size_list; curitem; curitem = IDL_LIST(curitem).next) {
51 fprintf(of, "%c", var);
52 if (IDL_LIST(curitem).next)
54 g_string_append_printf(id, "[%c]", var);
60 for(curitem = IDL_TYPE_ARRAY(name).size_list; curitem; curitem = IDL_LIST(curitem).next) {
62 for (i=0; i<indent+1; i++)
64 fprintf(of, "for (%c=0; %c<%" IDL_LL "d; %c++) \n",
65 var, var, IDL_INTEGER(IDL_LIST(curitem).data).value, var);
70 for (i=0; i<indent+2; i++)
76 g_error("Weird varname - %s", IDL_tree_type_names[IDL_NODE_TYPE(name)]);
80 forb_cbe_write_typespec(of, ts);
81 fprintf(of, "_%s(codec, %s%s%s)) goto ser_exception;\n",
82 serialize, use_ampersand ? "&":"", var_prefix, id->str);
86 g_string_free(id, TRUE);
91 forb_cbe_get_typecode_name (IDL_tree tree)
94 return g_strdup ("TC_FIXME");
96 return g_strconcat ("TC_", forb_cbe_get_typespec_str (tree), NULL);
100 forb_cbe_type_is_builtin(IDL_tree tree)
103 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:
160 Gets the "type" of {tree} as known in C.
161 The return value was alloc'd via g_malloc, and must be g_free'd.
164 forb_cbe_get_typespec_str(IDL_tree tree)
167 GString *tmpstr = NULL;
170 return g_strdup("void");
173 switch(IDL_NODE_TYPE(tree)) {
175 return forb_cbe_get_typespec_str(IDL_MEMBER(tree).type_spec);
178 retval = "CORBA_any";
180 case IDLN_TYPE_FLOAT:
181 switch(IDL_TYPE_FLOAT(tree).f_type) {
182 case IDL_FLOAT_TYPE_FLOAT:
183 retval = "CORBA_float";
185 case IDL_FLOAT_TYPE_DOUBLE:
186 retval = "CORBA_double";
188 case IDL_FLOAT_TYPE_LONGDOUBLE:
189 retval = "CORBA_long_double";
193 case IDLN_TYPE_FIXED:
194 return g_strdup_printf( "CORBA_fixed_%" IDL_LL "d_%" IDL_LL "d",
195 IDL_INTEGER(IDL_TYPE_FIXED(tree).positive_int_const).value,
196 IDL_INTEGER(IDL_TYPE_FIXED(tree).integer_lit).value);
198 case IDLN_TYPE_INTEGER:
199 tmpstr = g_string_new(NULL);
200 g_string_append(tmpstr, "CORBA_");
201 if(!IDL_TYPE_INTEGER(tree).f_signed)
202 g_string_append(tmpstr, "unsigned_");
204 switch(IDL_TYPE_INTEGER(tree).f_type) {
205 case IDL_INTEGER_TYPE_SHORT:
206 g_string_append(tmpstr, "short");
208 case IDL_INTEGER_TYPE_LONGLONG:
209 g_string_append(tmpstr, "long_");
211 case IDL_INTEGER_TYPE_LONG:
212 g_string_append(tmpstr, "long");
216 case IDLN_TYPE_STRING:
217 retval = "CORBA_string"; /* this is non-standard! */
219 case IDLN_TYPE_OCTET:
220 retval = "CORBA_octet";
222 case IDLN_TYPE_WIDE_STRING:
223 retval = "CORBA_wstring"; /* this is non-standard! */
226 retval = "CORBA_char";
228 case IDLN_TYPE_WIDE_CHAR:
229 retval = "CORBA_wchar";
231 case IDLN_TYPE_BOOLEAN:
232 retval = "CORBA_boolean";
234 case IDLN_TYPE_STRUCT:
235 return forb_cbe_get_typespec_str(IDL_TYPE_STRUCT(tree).ident);
236 case IDLN_EXCEPT_DCL:
237 return forb_cbe_get_typespec_str(IDL_EXCEPT_DCL(tree).ident);
238 case IDLN_TYPE_ARRAY:
239 return forb_cbe_get_typespec_str(IDL_TYPE_ARRAY(tree).ident);
240 case IDLN_TYPE_UNION:
241 return forb_cbe_get_typespec_str(IDL_TYPE_UNION(tree).ident);
243 return forb_cbe_get_typespec_str(IDL_TYPE_ENUM(tree).ident);
245 return IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(tree), "_", 0);
247 return forb_cbe_get_typespec_str(IDL_PARAM_DCL(tree).param_type_spec);
248 case IDLN_TYPE_SEQUENCE:
250 IDL_tree subtype = IDL_TYPE_SEQUENCE(tree).simple_type_spec;
252 ctmp = forb_cbe_get_typespec_str(subtype);
253 /* We should have built-in alias to make this next line not needed */
254 base = forb_cbe_type_is_builtin(subtype)
255 ? ctmp + strlen("CORBA_") : ctmp;
256 retval = g_strdup_printf( "CORBA_sequence_%s", base);
262 retval = "gpointer"; /* FIXME: */
264 case IDLN_FORWARD_DCL:
266 return forb_cbe_get_typespec_str(IDL_INTERFACE(tree).ident);
267 case IDLN_TYPE_OBJECT:
268 retval = "CORBA_Object";
270 case IDLN_TYPE_TYPECODE:
271 retval = "CORBA_TypeCode";
274 g_error("We were asked to get a typename for a %s",
275 IDL_tree_type_names[IDL_NODE_TYPE(tree)]);
280 return g_strdup (retval);
282 return g_string_free (tmpstr, FALSE);
286 forb_cbe_write_typespec(FILE *of, IDL_tree tree)
288 char *name = forb_cbe_get_typespec_str(tree);
294 Parameters (e.g., arguments to methods, and the return value
295 have some complicated rules in the C mapping for how many
296 levels of pointer and the exact type involved. This function
297 generates the externally visible parameter type.
299 Note the hack below because "const CORBA_string" is not
300 promotable to "const CORBA_char*" (the later the standard
301 to which apps are written, while the former is what would
302 be produced without the hack).
305 forb_cbe_write_param_typespec_str(IDL_tree ts, IDL_ParamRole role)
310 GString *str = g_string_sized_new (23);
311 IDL_tree typedef_spec;
314 n = oidl_param_info (ts, role, &isSlice);
315 name = forb_cbe_get_typespec_str (ts);
317 if ( role == DATA_IN ) {
318 /* We want to check if this is a typedef for CORBA_string so we can do special handling
321 typedef_spec = forb_cbe_get_typespec (ts);
322 typedef_name = forb_cbe_get_typespec_str (typedef_spec);
324 g_string_printf (str, "const %s",
325 !strcmp (typedef_name, "CORBA_string") ?
326 "CORBA_char *" : name);
328 g_free (typedef_name);
330 g_string_printf (str, "%s", name);
335 g_string_append (str, "_slice");
337 for (i = 0; i < n; i++)
338 g_string_append_c (str, '*');
340 return g_string_free (str, FALSE);
344 forb_cbe_write_param_typespec_raw (FILE *of, IDL_tree ts, IDL_ParamRole role)
347 str = forb_cbe_write_param_typespec_str (ts, role);
353 forb_cbe_write_param_typespec(FILE *of, IDL_tree tree) {
354 IDL_tree ts = NULL /* Quiet gcc */;
355 IDL_ParamRole role = 0 /* Quiet gcc */;
357 switch ( IDL_NODE_TYPE(tree) ) {
358 case IDLN_OP_DCL: /* means return value of method */
359 ts = IDL_OP_DCL(tree).op_type_spec;
362 case IDLN_PARAM_DCL: /* one of the parameters */
363 ts = IDL_PARAM_DCL(tree).param_type_spec;
364 role = oidl_attr_to_paramrole(IDL_PARAM_DCL(tree).attr);
367 g_assert_not_reached();
369 forb_cbe_write_param_typespec_raw(of, ts, role);
373 forb_cbe_op_write_proto (FILE *of,
375 const char *nom_prefix,
381 g_assert (IDL_NODE_TYPE(op) == IDLN_OP_DCL);
383 forb_cbe_write_param_typespec (of, op);
385 id = IDL_ns_ident_to_qstring (
386 IDL_IDENT_TO_NS (IDL_INTERFACE (
387 IDL_get_parent_node (op, IDLN_INTERFACE, NULL)).ident), "_", 0);
390 fprintf (of, "\t(*%s%s)", nom_prefix ? nom_prefix : "",
391 IDL_IDENT(IDL_OP_DCL(op).ident).str);
393 fprintf (of, " %s%s_%s", nom_prefix ? nom_prefix : "",
394 id, IDL_IDENT (IDL_OP_DCL (op).ident).str);
399 /* fprintf (of, "PortableServer_Servant _servant, "); */
401 fprintf (of, "%s _obj, ", id);
405 for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
406 IDL_tree parm = IDL_LIST (sub).data;
408 forb_cbe_write_param_typespec (of, parm);
410 fprintf (of, " %s, ", IDL_IDENT (IDL_PARAM_DCL (parm).simple_declarator).str);
413 if (IDL_OP_DCL (op).context_expr)
414 fprintf (of, "CORBA_Context _ctx, ");
416 fprintf (of, "CORBA_Environment *ev)");
419 /* Writes the value of the constant in 'tree' to file handle 'of' */
421 forb_cbe_get_const(IDL_tree tree)
423 char *opc = NULL, *retval, *ctmp;
424 GString *tmpstr = g_string_new(NULL);
426 switch(IDL_NODE_TYPE(tree)) {
428 g_string_printf(tmpstr, "%s", IDL_BOOLEAN(tree).value?"CORBA_TRUE":"CORBA_FALSE");
431 g_string_printf(tmpstr, "'\\x%X'", *(unsigned char *)IDL_CHAR(tree).value);
434 g_string_printf(tmpstr, "%f", IDL_FLOAT(tree).value);
437 g_string_printf(tmpstr, "%" IDL_LL "d", IDL_INTEGER(tree).value);
440 g_string_printf(tmpstr, "\"%s\"", IDL_STRING(tree).value);
443 g_string_printf(tmpstr, "L'%ls'", IDL_WIDE_CHAR(tree).value);
445 case IDLN_WIDE_STRING:
446 g_string_printf(tmpstr, "L\"%ls\"", IDL_WIDE_STRING(tree).value);
449 g_string_printf(tmpstr, "(");
450 ctmp = forb_cbe_get_const(IDL_BINOP(tree).left);
451 g_string_append(tmpstr, ctmp);
453 switch(IDL_BINOP(tree).op) {
485 g_string_append_printf(tmpstr, " %s ", opc);
486 ctmp = forb_cbe_get_const(IDL_BINOP(tree).right);
487 g_string_append_printf(tmpstr, "%s)", ctmp);
491 switch(IDL_UNARYOP(tree).op) {
492 case IDL_UNARYOP_PLUS: opc = "+"; break;
493 case IDL_UNARYOP_MINUS: opc = "-"; break;
494 case IDL_UNARYOP_COMPLEMENT: opc = "~"; break;
496 ctmp = forb_cbe_get_const(IDL_UNARYOP(tree).operand);
497 g_string_printf(tmpstr, "%s%s", opc, ctmp);
503 id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(tree), "_", 0);
504 g_string_printf(tmpstr, "%s", id);
509 g_error("We were asked to print a constant for %s", IDL_tree_type_names[tree->_type]);
513 retval = tmpstr->str;
515 g_string_free(tmpstr, FALSE);
521 forb_cbe_write_const(FILE *of, IDL_tree tree)
525 ctmp = forb_cbe_get_const(tree);
526 fprintf(of, "%s", ctmp);
530 /* This is the WORST HACK in the WORLD, really truly, but the C preprocessor doesn't allow us to use
531 strings, so we have to work around it by using individual characters. */
533 forb_cbe_id_define_hack(FILE *fh, const char *def_prefix, const char *def_name, const char *def_value)
536 n = strlen(def_value);
537 for(i = 0; i < n; i++)
538 fprintf(fh, "#define %s_%s_%d '%c'\n", def_prefix, def_name, i, def_value[i]);
542 forb_cbe_id_cond_hack(FILE *fh, const char *def_prefix, const char *def_name, const char *def_value)
545 n = strlen(def_value);
551 for(i = 0; i < n; i++)
552 fprintf(fh, "%s (%s_%s_%d == '%c') \\\n", i?"&&":"", def_prefix, def_name, i, def_value[i]);
558 case IDLN_TYPE_FLOAT: \
559 case IDLN_TYPE_ENUM: \
560 case IDLN_TYPE_BOOLEAN: \
561 case IDLN_TYPE_CHAR: \
562 case IDLN_TYPE_WIDE_CHAR: \
565 #define STRING_TYPES \
567 case IDLN_TYPE_WIDE_STRING
569 #define OBJREF_TYPES \
571 case IDLN_INTERFACE: \
572 case IDLN_FORWARD_DCL
575 forb_cbe_flatten_ref (IDL_ParamRole role, IDL_tree typespec)
579 is_fixed = forb_cbe_type_is_fixed_length (typespec);
583 switch (IDL_NODE_TYPE (typespec)) {
587 case IDLN_TYPE_TYPECODE:
589 return "(gpointer)&";
591 case IDLN_TYPE_STRUCT:
592 case IDLN_TYPE_UNION:
594 case IDLN_TYPE_SEQUENCE:
595 case IDLN_TYPE_ARRAY:
599 case IDLN_TYPE_FIXED:
600 g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
605 switch (IDL_NODE_TYPE (typespec)) {
609 case IDLN_TYPE_TYPECODE:
610 case IDLN_TYPE_STRUCT:
611 case IDLN_TYPE_UNION:
612 case IDLN_TYPE_ARRAY:
615 case IDLN_TYPE_SEQUENCE:
619 case IDLN_TYPE_FIXED:
620 g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
625 switch (IDL_NODE_TYPE (typespec)) {
629 case IDLN_TYPE_TYPECODE:
633 case IDLN_TYPE_STRUCT:
634 case IDLN_TYPE_UNION:
635 case IDLN_TYPE_ARRAY:
638 else /* drop through */
640 case IDLN_TYPE_SEQUENCE:
645 case IDLN_TYPE_FIXED:
646 g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
651 g_error ("No data return handler");
659 forb_cbe_flatten_args (IDL_tree tree, FILE *of, const char *name)
664 for (l = IDL_OP_DCL(tree).parameter_dcls; l;
665 l = IDL_LIST(l).next)
668 fprintf (of, "gpointer %s[%d];\n", name, i);
671 for (l = IDL_OP_DCL(tree).parameter_dcls; l;
672 l = IDL_LIST(l).next) {
673 IDL_tree decl = IDL_LIST (l).data;
674 IDL_tree tspec = forb_cbe_get_typespec (decl);
677 switch(IDL_PARAM_DCL(decl).attr) {
678 case IDL_PARAM_IN: r = DATA_IN; break;
679 case IDL_PARAM_INOUT: r = DATA_INOUT; break;
680 case IDL_PARAM_OUT: r = DATA_OUT; break;
682 g_error("Unknown IDL_PARAM type");
685 fprintf (of, "%s[%d] = %s%s;\n",
687 forb_cbe_flatten_ref (r, tspec),
688 IDL_IDENT (IDL_PARAM_DCL (decl).simple_declarator).str);
694 forb_cbe_unflatten_ref (IDL_ParamRole role, IDL_tree typespec)
700 is_fixed = forb_cbe_type_is_fixed_length (typespec);
702 typestr = forb_cbe_write_param_typespec_str (typespec, role);
706 switch (IDL_NODE_TYPE (typespec)) {
710 case IDLN_TYPE_TYPECODE:
712 retval = g_strdup_printf ("*(%s *)", typestr);
716 case IDLN_TYPE_ARRAY:
717 retval = g_strdup_printf ("(%s_slice *)", typestr);
720 case IDLN_TYPE_STRUCT:
721 case IDLN_TYPE_UNION:
723 case IDLN_TYPE_SEQUENCE:
724 retval = g_strdup_printf ("(%s)", typestr);
728 case IDLN_TYPE_FIXED:
729 g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
736 switch (IDL_NODE_TYPE (typespec)) {
737 case IDLN_TYPE_ARRAY:
738 retval = g_strdup_printf ("(%s_slice *)", typestr);
744 case IDLN_TYPE_TYPECODE:
745 case IDLN_TYPE_STRUCT:
746 case IDLN_TYPE_UNION:
749 case IDLN_TYPE_SEQUENCE:
750 retval = g_strdup_printf ("(%s)", typestr);
754 case IDLN_TYPE_FIXED:
755 g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
762 switch (IDL_NODE_TYPE (typespec)) {
766 case IDLN_TYPE_TYPECODE:
768 retval = g_strdup_printf ("*(%s *)", typestr);
771 case IDLN_TYPE_ARRAY:
773 retval = g_strdup_printf ("*(%s_slice **)", typestr);
778 case IDLN_TYPE_STRUCT:
779 case IDLN_TYPE_UNION:
781 retval = g_strdup_printf ("*(%s *)", typestr);
786 case IDLN_TYPE_SEQUENCE:
788 retval = g_strdup_printf ("(%s)", typestr);
792 case IDLN_TYPE_FIXED:
793 g_error ("Hit evil type %d", IDL_NODE_TYPE (typespec));
801 g_error ("No data return handler");
812 forb_cbe_unflatten_args (IDL_tree tree, FILE *of, const char *name)
817 for (l = IDL_OP_DCL(tree).parameter_dcls; l;
818 l = IDL_LIST(l).next) {
819 IDL_tree decl = IDL_LIST (l).data;
820 IDL_tree tspec = forb_cbe_get_typespec (decl);
824 switch(IDL_PARAM_DCL(decl).attr) {
825 case IDL_PARAM_IN: r = DATA_IN; break;
826 case IDL_PARAM_INOUT: r = DATA_INOUT; break;
827 case IDL_PARAM_OUT: r = DATA_OUT; break;
829 g_error("Unknown IDL_PARAM type");
832 unflatten = forb_cbe_unflatten_ref (r, tspec);
833 fprintf (of, "%s%s[%d], ", unflatten, name, i++);