/* By Elliot Lee Copyright (C) 1998 Red Hat Software. */ #include "config.h" #include #include #include #include #include #include #include "orbit-idl.h" #include "orbit-c-backend.h" /* Input: main part of filename to write, namespace & tree from parser Output: (in files) header, skeletons, stubs, and common code. */ #ifdef HAVE_INDENT_KR # define INDENT "indent -npro -kr -i8 -bad -fca -sc -sob" #else # ifdef HAVE_INDENT # define INDENT "indent -npro -bad -bap -bc -sob -br -ce -cli2 -npcs -di1 -psl -i3 -lp" # else # define INDENT "cat" # endif #endif void orbit_IDL_tree_to_c(const char *base_filename, IDL_ns namespace, IDL_tree tree) { FILE *curfile; GString *curfile_name = g_string_new(NULL); char *hdrname; if(debuglevel >= 4) orbit_cbe_print_node(tree, 0); base_filename = g_basename(base_filename); if(!disable_headers) { g_string_sprintf(curfile_name, INDENT " > %s.h", base_filename); curfile = popen(curfile_name->str, "w"); if(!curfile) { g_warning("Failed to open %s for writing: %s", curfile_name->str, g_strerror(errno)); return; } orbit_cbe_write_header(curfile, namespace, tree); fflush(curfile); fclose(curfile); } g_string_sprintf(curfile_name, "%s.h", base_filename); hdrname = g_strdup(g_basename(curfile_name->str)); if(!disable_common) { g_string_sprintf(curfile_name, INDENT " > %s-common.c", base_filename); curfile = popen(curfile_name->str, "w"); if(!curfile) { g_warning("Failed to open %s for writing: %s", curfile_name->str, g_strerror(errno)); return; } orbit_cbe_write_common(curfile, namespace, tree, hdrname); fflush(curfile); fclose(curfile); } if(!disable_stubs) { g_string_sprintf(curfile_name, INDENT " > %s-stubs.c", base_filename); curfile = popen(curfile_name->str, "w"); if(!curfile) { g_warning("Failed to open %s for writing: %s", curfile_name->str, g_strerror(errno)); return; } orbit_cbe_write_stubs(curfile, namespace, tree, hdrname); fflush(curfile); fclose(curfile); } if(!disable_skels) { g_string_sprintf(curfile_name, INDENT " > %s-skels.c", base_filename); curfile = popen(curfile_name->str, "w"); if(!curfile) { g_warning("Failed to open %s for writing: %s", curfile_name->str, g_strerror(errno)); return; } orbit_cbe_write_skeletons(curfile, namespace, tree, hdrname); fflush(curfile); fclose(curfile); } if(enable_skeleton_impl) { g_string_sprintf(curfile_name, INDENT " > %s-impl.c", base_filename); curfile = popen(curfile_name->str, "w"); if(!curfile) { g_warning("Failed to open %s for writing: %s", curfile_name->str, g_strerror(errno)); return; } orbit_cbe_write_skelimpl(curfile, namespace, tree, hdrname); fflush(curfile); fclose(curfile); } g_string_free(curfile_name, TRUE); g_free(hdrname); } void indent(int level) { int i; for(i = 0; i < level; i++) g_print(" "); } void orbit_cbe_print_node(IDL_tree node, int indent_level) { IDL_tree curnode; char *s; indent(indent_level); if(node == NULL) { g_print("(null)\n"); return; } g_print("[%d] ", IDL_NODE_REFS(node)); switch(IDL_NODE_TYPE(node)) { case IDLN_NONE: g_print("NONE\n"); break; case IDLN_LIST: g_print("LIST:\n"); for(curnode = node; curnode; curnode = IDL_LIST(curnode).next) { orbit_cbe_print_node(IDL_LIST(curnode).data, indent_level + 2); } break; case IDLN_GENTREE: g_print("GENTREE:\n"); #if 0 /* Changed in libIDL. But don't need it here anyway. */ orbit_cbe_print_node(IDL_GENTREE(node).data, indent_level + 2); indent(indent_level + 2); g_print("children:\n"); orbit_cbe_print_node(IDL_GENTREE(node).children, indent_level + 4); #endif break; case IDLN_INTEGER: g_print("INTEGER: %" IDL_LL "d\n", IDL_INTEGER(node).value); break; case IDLN_STRING: g_print("STRING: %s\n", IDL_STRING(node).value); break; case IDLN_WIDE_STRING: g_print("WIDE STRING: %ls\n", IDL_WIDE_STRING(node).value); break; case IDLN_CHAR: g_print("CHAR: %s\n", IDL_CHAR(node).value); break; case IDLN_WIDE_CHAR: g_print("WIDE CHAR: %ls\n", IDL_WIDE_CHAR(node).value); break; case IDLN_FIXED: g_print("FIXED: %s\n", IDL_FIXED(node).value); break; case IDLN_FLOAT: g_print("FLOAT: %f\n", IDL_FLOAT(node).value); break; case IDLN_BOOLEAN: g_print("BOOLEAN: %s\n", (IDL_BOOLEAN(node).value)?"True":"False"); break; case IDLN_IDENT: s = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(node), "_", 0); g_print("IDENT: %s NSQ: %s RID: \"%s\"\n", IDL_IDENT(node).str, s, IDL_IDENT_REPO_ID(node) ? IDL_IDENT_REPO_ID(node) : ""); g_free(s); break; case IDLN_TYPE_DCL: g_print("TYPE DCL:\n"); orbit_cbe_print_node(IDL_TYPE_DCL(node).type_spec, indent_level + 2); indent(indent_level + 2); g_print("decls:\n"); orbit_cbe_print_node(IDL_TYPE_DCL(node).dcls, indent_level + 4); break; case IDLN_CONST_DCL: g_print("CONST DCL:\n"); orbit_cbe_print_node(IDL_CONST_DCL(node).const_type, indent_level + 2); indent(indent_level + 2); g_print("ident:\n"); orbit_cbe_print_node(IDL_CONST_DCL(node).ident, indent_level + 4); indent(indent_level + 2); g_print("const_exp:\n"); orbit_cbe_print_node(IDL_CONST_DCL(node).const_exp, indent_level + 4); break; case IDLN_EXCEPT_DCL: g_print("EXCEPT DCL:\n"); orbit_cbe_print_node(IDL_EXCEPT_DCL(node).ident, indent_level + 2); indent(indent_level + 2); g_print("members:\n"); orbit_cbe_print_node(IDL_EXCEPT_DCL(node).members, indent_level + 4); break; case IDLN_ATTR_DCL: g_print("ATTR_DCL (%s):\n", (IDL_ATTR_DCL(node).f_readonly)?"readonly":"rw"); orbit_cbe_print_node(IDL_ATTR_DCL(node).param_type_spec, indent_level + 2); indent(indent_level + 2); g_print("simple_declarations:\n"); orbit_cbe_print_node(IDL_ATTR_DCL(node).simple_declarations, indent_level + 4); break; case IDLN_OP_DCL: g_print("OP DCL (%s):\n", (IDL_OP_DCL(node).f_oneway)?"oneway":"normal"); orbit_cbe_print_node(IDL_OP_DCL(node).ident, indent_level + 2); indent(indent_level + 2); g_print("op_type_spec:\n"); orbit_cbe_print_node(IDL_OP_DCL(node).op_type_spec, indent_level + 4); indent(indent_level + 2); g_print("parameter_dcls:\n"); orbit_cbe_print_node(IDL_OP_DCL(node).parameter_dcls, indent_level + 4); indent(indent_level + 2); g_print("raises_expr:\n"); orbit_cbe_print_node(IDL_OP_DCL(node).raises_expr, indent_level + 4); indent(indent_level + 2); g_print("context_expr:\n"); orbit_cbe_print_node(IDL_OP_DCL(node).context_expr, indent_level + 4); break; case IDLN_PARAM_DCL: g_print("PARAM DCL: "); switch(IDL_PARAM_DCL(node).attr) { case IDL_PARAM_IN: g_print("(in)\n"); break; case IDL_PARAM_OUT: g_print("(out)\n"); break; case IDL_PARAM_INOUT: g_print("(inout)\n"); break; } orbit_cbe_print_node(IDL_PARAM_DCL(node).param_type_spec, indent_level + 2); indent(indent_level + 2); g_print("simple_declarator:\n"); orbit_cbe_print_node(IDL_PARAM_DCL(node).simple_declarator, indent_level + 4); break; case IDLN_FORWARD_DCL: g_print("FORWARD DCL:\n"); orbit_cbe_print_node(IDL_FORWARD_DCL(node).ident, indent_level + 2); break; case IDLN_INTERFACE: g_print("INTERFACE:\n"); orbit_cbe_print_node(IDL_INTERFACE(node).ident, indent_level + 2); indent(indent_level + 2); g_print("inheritance_spec:\n"); orbit_cbe_print_node(IDL_INTERFACE(node).inheritance_spec, indent_level + 4); indent(indent_level + 2); g_print("body:\n"); orbit_cbe_print_node(IDL_INTERFACE(node).body, indent_level + 4); break; case IDLN_MODULE: g_print("MODULE:\n"); orbit_cbe_print_node(IDL_MODULE(node).ident, indent_level + 2); indent(indent_level + 2); g_print("definition_list:\n"); orbit_cbe_print_node(IDL_MODULE(node).definition_list, indent_level + 4); break; case IDLN_TYPE_INTEGER: if(!IDL_TYPE_INTEGER(node).f_signed) g_print("TYPE unsigned "); switch(IDL_TYPE_INTEGER(node).f_type) { case IDL_INTEGER_TYPE_SHORT: g_print("short\n"); break; case IDL_INTEGER_TYPE_LONG: g_print("long\n"); break; case IDL_INTEGER_TYPE_LONGLONG: g_print("long long\n"); break; } break; case IDLN_TYPE_FLOAT: switch(IDL_TYPE_FLOAT(node).f_type) { case IDL_FLOAT_TYPE_FLOAT: g_print("TYPE float\n"); break; case IDL_FLOAT_TYPE_DOUBLE: g_print("TYPE double\n"); break; case IDL_FLOAT_TYPE_LONGDOUBLE: g_print("TYPE long double\n"); break; } break; case IDLN_TYPE_FIXED: g_print("TYPE fixed:\n"); orbit_cbe_print_node(IDL_TYPE_FIXED(node).positive_int_const, indent_level + 2); orbit_cbe_print_node(IDL_TYPE_FIXED(node).integer_lit, indent_level + 2); break; case IDLN_TYPE_STRING: g_print("TYPE string:\n"); orbit_cbe_print_node(IDL_TYPE_STRING(node).positive_int_const, indent_level + 2); break; case IDLN_TYPE_WIDE_STRING: g_print("TYPE wide string:\n"); orbit_cbe_print_node(IDL_TYPE_WIDE_STRING(node).positive_int_const, indent_level + 2); break; case IDLN_TYPE_ENUM: g_print("TYPE enum:\n"); orbit_cbe_print_node(IDL_TYPE_ENUM(node).ident, indent_level + 2); indent(indent_level + 2); g_print("enumerator_list:\n"); orbit_cbe_print_node(IDL_TYPE_ENUM(node).enumerator_list, indent_level + 4); break; case IDLN_TYPE_ARRAY: g_print("TYPE array:\n"); orbit_cbe_print_node(IDL_TYPE_ARRAY(node).ident, indent_level + 2); indent(indent_level + 2); g_print("size_list:\n"); orbit_cbe_print_node(IDL_TYPE_ARRAY(node).size_list, indent_level + 4); break; case IDLN_TYPE_SEQUENCE: g_print("TYPE sequence:\n"); orbit_cbe_print_node(IDL_TYPE_SEQUENCE(node).simple_type_spec, indent_level + 2); indent(indent_level + 2); g_print("positive_int_const:\n"); orbit_cbe_print_node(IDL_TYPE_SEQUENCE(node).positive_int_const, indent_level + 4); break; case IDLN_TYPE_STRUCT: g_print("TYPE struct:\n"); orbit_cbe_print_node(IDL_TYPE_STRUCT(node).ident, indent_level + 2); indent(indent_level + 2); g_print("member_list:\n"); orbit_cbe_print_node(IDL_TYPE_STRUCT(node).member_list, indent_level + 4); break; case IDLN_TYPE_UNION: g_print("TYPE union:\n"); orbit_cbe_print_node(IDL_TYPE_UNION(node).ident, indent_level + 2); indent(indent_level + 2); g_print("switch_type_spec:\n"); orbit_cbe_print_node(IDL_TYPE_UNION(node).switch_type_spec, indent_level + 4); indent(indent_level + 2); g_print("switch_body:\n"); orbit_cbe_print_node(IDL_TYPE_UNION(node).switch_body, indent_level + 4); break; case IDLN_MEMBER: g_print("MEMBER:\n"); orbit_cbe_print_node(IDL_MEMBER(node).type_spec, indent_level + 2); indent(indent_level + 2); g_print("dcls:\n"); orbit_cbe_print_node(IDL_MEMBER(node).dcls, indent_level + 4); break; case IDLN_CASE_STMT: g_print("CASE_STMT:\n"); orbit_cbe_print_node(IDL_CASE_STMT(node).labels, indent_level + 2); indent(indent_level + 2); g_print("element_spec:\n"); orbit_cbe_print_node(IDL_CASE_STMT(node).element_spec, indent_level + 4); break; case IDLN_BINOP: g_print("BINOP "); switch(IDL_BINOP(node).op) { case IDL_BINOP_OR: g_print("or:\n"); break; case IDL_BINOP_XOR: g_print("xor:\n"); break; case IDL_BINOP_AND: g_print("and:\n"); break; case IDL_BINOP_SHR: g_print("shr:\n"); break; case IDL_BINOP_SHL: g_print("shl:\n"); break; case IDL_BINOP_ADD: g_print("add:\n"); break; case IDL_BINOP_SUB: g_print("sub:\n"); break; case IDL_BINOP_MULT: g_print("mult:\n"); break; case IDL_BINOP_DIV: g_print("div:\n"); break; case IDL_BINOP_MOD: g_print("mod:\n"); break; } indent(indent_level + 2); g_print("left:\n"); orbit_cbe_print_node(IDL_BINOP(node).left, indent_level + 4); indent(indent_level + 2); g_print("right:\n"); orbit_cbe_print_node(IDL_BINOP(node).right, indent_level + 4); break; case IDLN_UNARYOP: g_print("UNARYOP "); switch(IDL_UNARYOP(node).op) { case IDL_UNARYOP_PLUS: g_print("plus:\n"); break; case IDL_UNARYOP_MINUS: g_print("minus:\n"); break; case IDL_UNARYOP_COMPLEMENT: g_print("complement:\n"); break; } orbit_cbe_print_node(IDL_UNARYOP(node).operand, indent_level + 2); break; case IDLN_TYPE_CHAR: g_print("TYPE char\n"); break; case IDLN_TYPE_WIDE_CHAR: g_print("TYPE wide char\n"); break; case IDLN_TYPE_BOOLEAN: g_print("TYPE boolean\n"); break; case IDLN_TYPE_OCTET: g_print("TYPE octet\n"); break; case IDLN_TYPE_OBJECT: g_print("TYPE object\n"); break; case IDLN_TYPE_ANY: g_print("TYPE any\n"); break; case IDLN_TYPE_TYPECODE: g_print("TYPE TypeCode\n"); break; default: g_print("unhandled %d\n", IDL_NODE_TYPE(node)); } } char * orbit_cbe_get_typename(IDL_tree tree) { GString *tmpstr; char *retval = NULL; if(!tree) { return g_strdup("void"); } tmpstr = g_string_new(NULL); switch(IDL_NODE_TYPE(tree)) { case IDLN_TYPE_ANY: retval = "CORBA_any"; break; case IDLN_TYPE_FLOAT: switch(IDL_TYPE_FLOAT(tree).f_type) { case IDL_FLOAT_TYPE_FLOAT: retval = "CORBA_float"; break; case IDL_FLOAT_TYPE_DOUBLE: retval = "CORBA_double"; break; case IDL_FLOAT_TYPE_LONGDOUBLE: retval = "CORBA_long_double"; break; } break; case IDLN_TYPE_FIXED: #if 0 fprintf(of, "CORBA_fixed_%d_%d", IDL_TYPE_FIXED(tree).positive_int_const, IDL_TYPE_FIXED(tree).integer_lit); #else retval = "CORBA_fixed_d_s"; #endif break; case IDLN_TYPE_INTEGER: g_string_assign(tmpstr, "CORBA_"); if(!IDL_TYPE_INTEGER(tree).f_signed) g_string_append(tmpstr, "unsigned_"); switch(IDL_TYPE_INTEGER(tree).f_type) { case IDL_INTEGER_TYPE_SHORT: g_string_append(tmpstr, "short"); break; case IDL_INTEGER_TYPE_LONGLONG: g_string_append(tmpstr, "long_"); case IDL_INTEGER_TYPE_LONG: g_string_append(tmpstr, "long"); break; } break; case IDLN_TYPE_STRING: retval = "CORBA_string"; break; case IDLN_TYPE_OCTET: retval = "CORBA_octet"; break; case IDLN_TYPE_WIDE_STRING: retval = "CORBA_wstring"; break; case IDLN_TYPE_CHAR: retval = "CORBA_char"; break; case IDLN_TYPE_WIDE_CHAR: retval = "CORBA_wchar"; break; case IDLN_TYPE_BOOLEAN: retval = "CORBA_boolean"; break; case IDLN_TYPE_STRUCT: retval = orbit_cbe_get_typename(IDL_TYPE_STRUCT(tree).ident); g_string_assign(tmpstr, retval); g_free(retval); retval = NULL; break; case IDLN_EXCEPT_DCL: retval = orbit_cbe_get_typename(IDL_EXCEPT_DCL(tree).ident); g_string_assign(tmpstr, retval); g_free(retval); retval = NULL; break; case IDLN_TYPE_ARRAY: retval = orbit_cbe_get_typename(IDL_TYPE_ARRAY(tree).ident); g_string_assign(tmpstr, retval); g_free(retval); retval = NULL; break; case IDLN_TYPE_UNION: retval = orbit_cbe_get_typename(IDL_TYPE_UNION(tree).ident); g_string_assign(tmpstr, retval); g_free(retval); retval = NULL; break; case IDLN_TYPE_ENUM: retval = orbit_cbe_get_typename(IDL_TYPE_ENUM(tree).ident); g_string_assign(tmpstr, retval); g_free(retval); retval = NULL; break; case IDLN_IDENT: { char *id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(tree), "_", 0); g_string_assign(tmpstr, id); g_free(id); } break; case IDLN_PARAM_DCL: return orbit_cbe_get_typename(IDL_PARAM_DCL(tree).param_type_spec); break; case IDLN_TYPE_SEQUENCE: return orbit_cbe_get_typename(IDL_get_parent_node(tree, IDLN_TYPE_DCL, NULL)); break; case IDLN_INTERFACE: retval = orbit_cbe_get_typename(IDL_INTERFACE(tree).ident); g_string_assign(tmpstr, retval); g_free(retval); retval = NULL; break; case IDLN_NATIVE: retval = "gpointer"; break; case IDLN_TYPE_OBJECT: retval = "CORBA_Object"; break; case IDLN_TYPE_TYPECODE: retval = "CORBA_TypeCode"; break; default: g_error("We were asked to get a typename for a %s", IDL_tree_type_names[IDL_NODE_TYPE(tree)]); } if(retval) return g_strdup(retval); else { retval = g_strdup(tmpstr->str); g_string_free(tmpstr, TRUE); return retval; } } void orbit_cbe_write_typename(FILE *of, IDL_tree tree) { char *t = orbit_cbe_get_typename(tree); fprintf(of, "%s", t); g_free(t); } void orbit_cbe_write_typespec(FILE *of, IDL_tree tree) { if(!tree) { fprintf(of, "void"); return; } switch(IDL_NODE_TYPE(tree)) { case IDLN_TYPE_FLOAT: switch(IDL_TYPE_FLOAT(tree).f_type) { case IDL_FLOAT_TYPE_FLOAT: fprintf(of, "CORBA_float"); break; case IDL_FLOAT_TYPE_DOUBLE: fprintf(of, "CORBA_double"); break; case IDL_FLOAT_TYPE_LONGDOUBLE: fprintf(of, "CORBA_long_double"); break; }; break; case IDLN_TYPE_BOOLEAN: fprintf(of, "CORBA_boolean"); break; case IDLN_TYPE_FIXED: #if 0 fprintf(of, "CORBA_fixed_%d_%d", IDL_TYPE_FIXED(tree).positive_int_const, IDL_TYPE_FIXED(tree).integer_lit); #else fprintf(of, "CORBA_fixed_d_s"); #endif break; case IDLN_TYPE_INTEGER: fprintf(of, "CORBA_"); if(!IDL_TYPE_INTEGER(tree).f_signed) fprintf(of, "unsigned_"); switch(IDL_TYPE_INTEGER(tree).f_type) { case IDL_INTEGER_TYPE_SHORT: fprintf(of, "short"); break; case IDL_INTEGER_TYPE_LONGLONG: fprintf(of, "long_"); case IDL_INTEGER_TYPE_LONG: fprintf(of, "long"); break; } break; case IDLN_TYPE_STRING: fprintf(of, "CORBA_char *"); break; case IDLN_TYPE_OCTET: fprintf(of, "CORBA_octet"); break; case IDLN_TYPE_WIDE_STRING: fprintf(of, "CORBA_wchar *"); break; case IDLN_TYPE_CHAR: fprintf(of, "CORBA_char"); break; case IDLN_TYPE_WIDE_CHAR: fprintf(of, "CORBA_wchar"); break; case IDLN_TYPE_STRUCT: fprintf(of, "struct "); case IDLN_TYPE_ARRAY: case IDLN_TYPE_UNION: case IDLN_TYPE_ENUM: case IDLN_EXCEPT_DCL: { char *id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(IDL_TYPE_ENUM(tree).ident), "_", 0); fprintf(of, "%s", id); g_free(id); } break; case IDLN_IDENT: { char *id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(tree), "_", 0); fprintf(of, "%s", id); g_free(id); } break; case IDLN_TYPE_OBJECT: fprintf(of, "CORBA_Object"); break; case IDLN_TYPE_SEQUENCE: fprintf(of, "struct { CORBA_unsigned_long _maximum, _length;\n"); orbit_cbe_write_typespec(of, IDL_TYPE_SEQUENCE(tree).simple_type_spec); fprintf(of, " *_buffer;\nCORBA_boolean _release; } \n"); break; case IDLN_TYPE_ANY: fprintf(of, "CORBA_any"); break; case IDLN_NATIVE: fprintf(of, "gpointer"); break; case IDLN_TYPE_TYPECODE: fprintf(of, "CORBA_TypeCode"); break; default: g_error("We were asked to print a typespec %s", IDL_tree_type_names[tree->_type]); } } /* Writes the value of the constant in 'tree' to file handle 'of' */ void orbit_cbe_write_const(FILE *of, IDL_tree tree) { char *opc = NULL; switch(IDL_NODE_TYPE(tree)) { case IDLN_BOOLEAN: fprintf(of, "%s", IDL_BOOLEAN(tree).value?"CORBA_TRUE":"CORBA_FALSE"); break; case IDLN_CHAR: fprintf(of, "'%s'", IDL_CHAR(tree).value); break; case IDLN_FLOAT: fprintf(of, "%f", IDL_FLOAT(tree).value); break; case IDLN_INTEGER: fprintf(of, "%" IDL_LL "d", IDL_INTEGER(tree).value); break; case IDLN_STRING: fprintf(of, "\"%s\"", IDL_STRING(tree).value); break; case IDLN_WIDE_CHAR: fprintf(of, "L'%ls'", IDL_WIDE_CHAR(tree).value); break; case IDLN_WIDE_STRING: fprintf(of, "L\"%ls\"", IDL_WIDE_STRING(tree).value); break; case IDLN_BINOP: fprintf(of, "("); orbit_cbe_write_const(of, IDL_BINOP(tree).left); switch(IDL_BINOP(tree).op) { case IDL_BINOP_OR: opc = "|"; break; case IDL_BINOP_XOR: opc = "!!!"; break; case IDL_BINOP_AND: opc = "&"; break; case IDL_BINOP_SHR: opc = ">>"; break; case IDL_BINOP_SHL: opc = "<<"; break; case IDL_BINOP_ADD: opc = "+"; break; case IDL_BINOP_SUB: opc = "-"; break; case IDL_BINOP_MULT: opc = "*"; break; case IDL_BINOP_DIV: opc = "/"; break; case IDL_BINOP_MOD: opc = "%"; break; } fprintf(of, " %s ", opc); orbit_cbe_write_const(of, IDL_BINOP(tree).right); fprintf(of, ")"); break; case IDLN_UNARYOP: switch(IDL_UNARYOP(tree).op) { case IDL_UNARYOP_PLUS: opc = "+"; break; case IDL_UNARYOP_MINUS: opc = "-"; break; case IDL_UNARYOP_COMPLEMENT: opc = "~"; break; } fprintf(of, "%s", opc); orbit_cbe_write_const(of, IDL_UNARYOP(tree).operand); break; case IDLN_IDENT: { /* XXX fixme, brokenness */ char *id; id = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(tree), "_", 0); fprintf(of, "%s", id); g_free(id); } break; default: g_error("We were asked to print a constant for %s", IDL_tree_type_names[tree->_type]); } } static const int * const orbit_cbe_get_typeoffsets_table (void) { static int typeoffsets[IDLN_LAST]; static gboolean initialized = FALSE; if (!initialized) { int i; for (i = 0; i < IDLN_LAST; ++i) typeoffsets[i] = -1; typeoffsets[IDLN_FORWARD_DCL] = 8; /* (same as objref) */ typeoffsets[IDLN_TYPE_INTEGER] = 0; typeoffsets[IDLN_TYPE_FLOAT] = 0; typeoffsets[IDLN_TYPE_FIXED] = 3; typeoffsets[IDLN_TYPE_CHAR] = 5; typeoffsets[IDLN_TYPE_WIDE_CHAR] = 6; typeoffsets[IDLN_TYPE_STRING] = 12; typeoffsets[IDLN_TYPE_WIDE_STRING] = 13; typeoffsets[IDLN_TYPE_BOOLEAN] = 4; typeoffsets[IDLN_TYPE_OCTET] = 7; typeoffsets[IDLN_TYPE_ANY] = 16; typeoffsets[IDLN_TYPE_OBJECT] = 9; typeoffsets[IDLN_TYPE_TYPECODE] = 9; typeoffsets[IDLN_TYPE_ENUM] = 8; typeoffsets[IDLN_TYPE_SEQUENCE] = 14; typeoffsets[IDLN_TYPE_ARRAY] = 15; typeoffsets[IDLN_TYPE_STRUCT] = 10; typeoffsets[IDLN_TYPE_UNION] = 11; typeoffsets[IDLN_NATIVE] = 15; /* no pointers ever, same as fixed array */ typeoffsets[IDLN_INTERFACE] = 9; /* (same as objref) */ initialized = TRUE; } return typeoffsets; } /******* This is a rather hairy function. Its purpose is to output the required number of *'s that indicate the amount of indirection for input, output, & input-output parameters, and return values. We do this by having a table of the number of *'s for each type and purpose (nptrrefs_required), taken from 19.20 of the CORBA 2.2 spec, and then having a table that translates from the IDLN_* enums into an index into nptrrefs_required (typeoffsets) *******/ gint orbit_cbe_param_numptrs(IDL_tree param, IDL_ParamRole role) { const int * const typeoffsets = orbit_cbe_get_typeoffsets_table (); const int nptrrefs_required[][4] = { {0,1,1,0} /* float */, {0,1,1,0} /* double */, {0,1,1,0} /* long double */, {1,1,1,0} /* fixed_d_s 3 */, {0,1,1,0} /* boolean */, {0,1,1,0} /* char */, {0,1,1,0} /* wchar */, {0,1,1,0} /* octet */, {0,1,1,0} /* enum */, {0,1,1,0} /* objref */, {1,1,1,0} /* fixed struct 10 */, {1,1,1,0} /* fixed union */, {0,1,1,0} /* string */, {0,1,1,0} /* wstring */, {1,1,2,1} /* sequence */, {0,0,0,0} /* fixed array */, {1,1,2,1} /* any 16 */ }; int retval = 0; if(!param) /* void */ return 0; /* Now, how do we use this table? :) */ param = cbe_get_typespec(param); g_assert(param); switch(IDL_NODE_TYPE(param)) { case IDLN_TYPE_STRUCT: case IDLN_TYPE_UNION: if(((role == DATA_RETURN) || (role == DATA_OUT)) && !cbe_type_is_fixed_length(param)) retval++; break; case IDLN_TYPE_ARRAY: if(!cbe_type_is_fixed_length(param) && role == DATA_OUT) retval++; break; default: break; } g_assert(typeoffsets[IDL_NODE_TYPE(param)] >= 0); switch(role) { case DATA_IN: role = 0; break; case DATA_INOUT: role = 1; break; case DATA_OUT: role = 2; break; case DATA_RETURN: role = 3; break; } retval+=nptrrefs_required[typeoffsets[IDL_NODE_TYPE(param)]][role]; return retval; } void orbit_cbe_param_printptrs(FILE *of, IDL_tree param, IDL_ParamRole role) { int i, n; if(param == NULL) return; param = cbe_get_typespec(param); n = orbit_cbe_param_numptrs(param, role); if(IDL_NODE_TYPE(param) == IDLN_TYPE_ARRAY && ((role == DATA_OUT) || (role == DATA_RETURN))) { if(role == DATA_RETURN) fprintf(of, "_slice*"); else if(!cbe_type_is_fixed_length(param)) /* && role == DATA_OUT */ fprintf(of, "_slice*"); } for(i = 0; i < n; i++) fprintf(of, "*"); } gboolean cbe_type_is_fixed_length(IDL_tree ts) { gboolean is_fixed = TRUE; IDL_tree curitem; ts = cbe_get_typespec(ts); switch(IDL_NODE_TYPE(ts)) { case IDLN_TYPE_FLOAT: case IDLN_TYPE_INTEGER: case IDLN_TYPE_ENUM: case IDLN_TYPE_CHAR: case IDLN_TYPE_WIDE_CHAR: case IDLN_TYPE_OCTET: case IDLN_TYPE_BOOLEAN: return TRUE; break; case IDLN_TYPE_SEQUENCE: case IDLN_TYPE_STRING: case IDLN_TYPE_WIDE_STRING: case IDLN_TYPE_OBJECT: case IDLN_FORWARD_DCL: case IDLN_INTERFACE: case IDLN_TYPE_ANY: case IDLN_NATIVE: case IDLN_TYPE_TYPECODE: return FALSE; break; case IDLN_TYPE_UNION: #if 1 for(curitem = IDL_TYPE_UNION(ts).switch_body; curitem; curitem = IDL_LIST(curitem).next) { is_fixed &= cbe_type_is_fixed_length(IDL_LIST(IDL_CASE_STMT(IDL_LIST(curitem).data).element_spec).data); } return is_fixed; break; #endif case IDLN_EXCEPT_DCL: case IDLN_TYPE_STRUCT: for(curitem = IDL_TYPE_STRUCT(ts).member_list; curitem; curitem = IDL_LIST(curitem).next) { is_fixed &= cbe_type_is_fixed_length(IDL_LIST(curitem).data); } return is_fixed; break; case IDLN_TYPE_ARRAY: return cbe_type_is_fixed_length(IDL_TYPE_DCL(IDL_get_parent_node(ts, IDLN_TYPE_DCL, NULL)).type_spec); break; default: g_warning("I'm not sure if type %s is fixed-length", IDL_tree_type_names[IDL_NODE_TYPE(ts)]); return FALSE; } } IDL_tree cbe_get_typespec(IDL_tree node) { if(node == NULL) return NULL; switch(IDL_NODE_TYPE(node)) { case IDLN_TYPE_INTEGER: case IDLN_TYPE_FLOAT: case IDLN_TYPE_FIXED: case IDLN_TYPE_CHAR: case IDLN_TYPE_WIDE_CHAR: case IDLN_TYPE_STRING: case IDLN_TYPE_WIDE_STRING: case IDLN_TYPE_BOOLEAN: case IDLN_TYPE_OCTET: case IDLN_TYPE_ANY: case IDLN_TYPE_OBJECT: case IDLN_TYPE_ENUM: case IDLN_TYPE_SEQUENCE: case IDLN_TYPE_ARRAY: case IDLN_TYPE_STRUCT: case IDLN_TYPE_UNION: case IDLN_EXCEPT_DCL: case IDLN_INTERFACE: case IDLN_NATIVE: case IDLN_TYPE_TYPECODE: return node; break; case IDLN_TYPE_DCL: return cbe_get_typespec(IDL_TYPE_DCL(node).type_spec); break; case IDLN_PARAM_DCL: return cbe_get_typespec(IDL_PARAM_DCL(node).param_type_spec); break; case IDLN_MEMBER: return cbe_get_typespec(IDL_MEMBER(node).type_spec); break; case IDLN_FORWARD_DCL: return cbe_get_typespec(IDL_FORWARD_DCL(node).ident); break; case IDLN_LIST: case IDLN_IDENT: return cbe_get_typespec(IDL_get_parent_node(node, IDLN_ANY, NULL)); break; default: g_warning("Unhandled node type %s!", IDL_tree_type_names[IDL_NODE_TYPE(node)]); return NULL; } } int cbe_get_type_head_alignment(IDL_tree typespec) { switch(IDL_NODE_TYPE(typespec)) { case IDLN_TYPE_INTEGER: switch(IDL_TYPE_INTEGER(typespec).f_type) { case IDL_INTEGER_TYPE_SHORT: return sizeof(CORBA_short); case IDL_INTEGER_TYPE_LONG: return sizeof(CORBA_long); case IDL_INTEGER_TYPE_LONGLONG: return sizeof(CORBA_long_long); } break; case IDLN_TYPE_FLOAT: switch(IDL_TYPE_FLOAT(typespec).f_type) { case IDL_FLOAT_TYPE_FLOAT: return sizeof(CORBA_float); case IDL_FLOAT_TYPE_DOUBLE: return sizeof(CORBA_double); case IDL_FLOAT_TYPE_LONGDOUBLE: return sizeof(CORBA_long_double); } break; case IDLN_TYPE_FIXED: return sizeof(CORBA_short); break; case IDLN_TYPE_CHAR: return sizeof(CORBA_char); break; case IDLN_TYPE_WIDE_CHAR: return sizeof(CORBA_wchar); break; case IDLN_TYPE_STRING: case IDLN_INTERFACE: case IDLN_TYPE_OBJECT: case IDLN_FORWARD_DCL: case IDLN_TYPE_TYPECODE: return sizeof(CORBA_unsigned_long); break; case IDLN_TYPE_WIDE_STRING: case IDLN_TYPE_BOOLEAN: case IDLN_TYPE_OCTET: case IDLN_NATIVE: return 1; break; case IDLN_TYPE_ANY: case IDLN_TYPE_ENUM: case IDLN_TYPE_SEQUENCE: case IDLN_EXCEPT_DCL: return sizeof(CORBA_unsigned_long); break; case IDLN_TYPE_ARRAY: return cbe_get_type_head_alignment(cbe_get_typespec(IDL_TYPE_ARRAY(typespec).ident)); break; case IDLN_TYPE_STRUCT: return cbe_get_type_head_alignment(cbe_get_typespec(IDL_LIST(IDL_TYPE_STRUCT(typespec).member_list).data)); break; case IDLN_TYPE_UNION: return cbe_get_type_head_alignment(cbe_get_typespec(IDL_TYPE_UNION(typespec).switch_type_spec)); break; default: return cbe_get_type_head_alignment(cbe_get_typespec(typespec)); } return 0; } int cbe_get_type_tail_alignment(IDL_tree typespec) { int minalign; IDL_tree curitem; switch(IDL_NODE_TYPE(typespec)) { case IDLN_TYPE_INTEGER: switch(IDL_TYPE_INTEGER(typespec).f_type) { case IDL_INTEGER_TYPE_SHORT: return sizeof(CORBA_short); case IDL_INTEGER_TYPE_LONG: return sizeof(CORBA_long); case IDL_INTEGER_TYPE_LONGLONG: return sizeof(CORBA_long_long); } break; case IDLN_TYPE_FLOAT: switch(IDL_TYPE_FLOAT(typespec).f_type) { case IDL_FLOAT_TYPE_FLOAT: return sizeof(CORBA_float); case IDL_FLOAT_TYPE_DOUBLE: return sizeof(CORBA_double); case IDL_FLOAT_TYPE_LONGDOUBLE: return sizeof(CORBA_long_double); } break; case IDLN_TYPE_FIXED: return sizeof(CORBA_short); break; case IDLN_TYPE_CHAR: return sizeof(CORBA_char); break; case IDLN_TYPE_WIDE_CHAR: return sizeof(CORBA_wchar); break; case IDLN_TYPE_STRING: case IDLN_TYPE_WIDE_STRING: case IDLN_TYPE_BOOLEAN: case IDLN_TYPE_OCTET: case IDLN_INTERFACE: case IDLN_TYPE_OBJECT: case IDLN_FORWARD_DCL: case IDLN_TYPE_ANY: case IDLN_NATIVE: case IDLN_TYPE_TYPECODE: return 1; break; case IDLN_TYPE_ENUM: return sizeof(CORBA_unsigned_long); break; case IDLN_TYPE_SEQUENCE: return cbe_get_type_tail_alignment(cbe_get_typespec(IDL_TYPE_SEQUENCE(typespec).simple_type_spec)); break; case IDLN_TYPE_ARRAY: return cbe_get_type_tail_alignment(cbe_get_typespec(IDL_TYPE_ARRAY(typespec).ident)); break; case IDLN_EXCEPT_DCL: case IDLN_TYPE_STRUCT: curitem = IDL_list_nth(IDL_TYPE_STRUCT(typespec).member_list, IDL_list_length(IDL_TYPE_STRUCT(typespec).member_list) - 1); return cbe_get_type_tail_alignment(cbe_get_typespec(IDL_LIST(curitem).data)); break; case IDLN_TYPE_UNION: for(minalign = 8 /* FIXME */, curitem = IDL_TYPE_UNION(typespec).switch_body; curitem && minalign > 1; curitem = IDL_LIST(curitem).next) { IDL_tree uts; uts = IDL_CASE_STMT(IDL_LIST(curitem).data).element_spec; minalign = MIN(cbe_get_type_tail_alignment(cbe_get_typespec(uts)), minalign); } return minalign; break; default: return cbe_get_type_tail_alignment(cbe_get_typespec(typespec)); } return 0; } static void IDL_tree_traverse_helper(IDL_tree p, GFunc f, gconstpointer func_data, GHashTable *visited_nodes) { IDL_tree curitem; if(g_hash_table_lookup(visited_nodes, p)) return; g_hash_table_insert(visited_nodes, p, ((gpointer)1)); for(curitem = IDL_INTERFACE(p).inheritance_spec; curitem; curitem = IDL_LIST(curitem).next) { IDL_tree_traverse_helper(IDL_get_parent_node(IDL_LIST(curitem).data, IDLN_INTERFACE, NULL), f, func_data, visited_nodes); } f(p, (gpointer)func_data); } void IDL_tree_traverse_parents(IDL_tree p, GFunc f, gconstpointer func_data) { GHashTable *visited_nodes = g_hash_table_new(NULL, g_direct_equal); if(!(p && f)) return; if(IDL_NODE_TYPE(p) != IDLN_INTERFACE) p = IDL_get_parent_node(p, IDLN_INTERFACE, NULL); if(!p) return; IDL_tree_traverse_helper(p, f, func_data, visited_nodes); g_hash_table_destroy(visited_nodes); } IDL_ParamRole cbe_attr_to_paramrole(enum IDL_param_attr attr) { switch(attr) { case IDL_PARAM_IN: return DATA_IN; case IDL_PARAM_OUT: return DATA_OUT; case IDL_PARAM_INOUT: return DATA_INOUT; default: g_warning("Unknown IDL_param_attr %d", attr); return -1; } } gboolean cbe_type_is_endian_sensitive(IDL_tree typespec) { IDL_tree curitem; gboolean retval; switch(IDL_NODE_TYPE(typespec)) { case IDLN_TYPE_CHAR: case IDLN_TYPE_BOOLEAN: case IDLN_TYPE_OCTET: return FALSE; case IDLN_TYPE_ARRAY: curitem = IDL_get_parent_node(typespec, IDLN_ANY, NULL); curitem = IDL_get_parent_node(curitem, IDLN_ANY, NULL); return cbe_type_is_endian_sensitive(IDL_MEMBER(curitem).type_spec); case IDLN_TYPE_STRUCT: retval = TRUE; for(curitem = IDL_TYPE_STRUCT(typespec).member_list; curitem; curitem = IDL_LIST(curitem).next) { retval = retval && cbe_type_is_endian_sensitive(IDL_LIST(curitem).data); } return retval; break; default: return TRUE; } }