/* * Common method verification code, called by *op_dcl in the various backends. */ gboolean verify_method_declaration(IDL_tree method_tree) { struct _IDL_OP_DCL *op = &IDL_OP_DCL(method_tree); IDL_tree iface; IDL_tree iter; gboolean notxpcom; gboolean scriptable_interface; gboolean scriptable_method; gboolean seen_retval = FALSE; const char *method_name = IDL_IDENT(IDL_OP_DCL(method_tree).ident).str; /* We don't support attributes named IID, conflicts with static GetIID * member. The conflict is due to certain compilers (VC++) choosing a * different vtable order, placing GetIID at the beginning regardless * of it's placement */ if (strcmp(method_name, "GetIID") == 0) { IDL_tree_error(method_tree, "Methods named GetIID not supported, causes vtable " "ordering problems"); return FALSE; } if (op->f_varargs) { /* We don't currently support varargs. */ IDL_tree_error(method_tree, "varargs are not currently supported"); return FALSE; } /* * Verify that we've been called on an interface, and decide if the * interface was marked [scriptable]. */ if (IDL_NODE_UP(method_tree) && IDL_NODE_UP(IDL_NODE_UP(method_tree)) && IDL_NODE_TYPE(iface = IDL_NODE_UP(IDL_NODE_UP(method_tree))) == IDLN_INTERFACE) { scriptable_interface = (IDL_tree_property_get(IDL_INTERFACE(iface).ident, "scriptable") != NULL); } else { IDL_tree_error(method_tree, "verify_method_declaration called on a non-interface?"); return FALSE; } /* * Require that any method in an interface marked as [scriptable], that * *isn't* scriptable because it refers to some native type, be marked * [noscript] or [notxpcom]. * * Also check that iid_is points to nsid, and length_is, size_is points * to unsigned long. */ notxpcom = IDL_tree_property_get(op->ident, "notxpcom") != NULL; scriptable_method = scriptable_interface && !notxpcom && IDL_tree_property_get(op->ident, "noscript") == NULL; /* Loop through the parameters and check. */ for (iter = op->parameter_dcls; iter; iter = IDL_LIST(iter).next) { IDL_tree param = IDL_LIST(iter).data; IDL_tree param_type = IDL_PARAM_DCL(param).param_type_spec; IDL_tree simple_decl = IDL_PARAM_DCL(param).simple_declarator; const char *param_name = IDL_IDENT(simple_decl).str; /* * Reject this method if it should be scriptable and some parameter is * native that isn't marked with either nsid, domstring, utf8string, * cstring, astring or iid_is. */ if (scriptable_method && UP_IS_NATIVE(param_type) && IDL_tree_property_get(param_type, "nsid") == NULL && IDL_tree_property_get(simple_decl, "iid_is") == NULL && IDL_tree_property_get(param_type, "domstring") == NULL && IDL_tree_property_get(param_type, "utf8string") == NULL && IDL_tree_property_get(param_type, "cstring") == NULL && IDL_tree_property_get(param_type, "astring") == NULL) { IDL_tree_error(method_tree, "methods in [scriptable] interfaces that are " "non-scriptable because they refer to native " "types (parameter \"%s\") must be marked " "[noscript]", param_name); return FALSE; } /* * nsid's parameters that aren't ptr's or ref's are not currently * supported in xpcom or non-xpcom (marked with [notxpcom]) methods * as input parameters */ if (!(notxpcom && IDL_PARAM_DCL(param).attr != IDL_PARAM_IN) && IDL_tree_property_get(param_type, "nsid") != NULL && IDL_tree_property_get(param_type, "ptr") == NULL && IDL_tree_property_get(param_type, "ref") == NULL) { IDL_tree_error(method_tree, "Feature currently not supported: " "parameter \"%s\" is of type nsid and " "must be marked either [ptr] or [ref] " "or method \"%s\" must be marked [notxpcom] " "and must not be an input parameter", param_name, method_name); return FALSE; } /* * Sanity checks on return values. */ if (IDL_tree_property_get(simple_decl, "retval") != NULL) { if (IDL_LIST(iter).next != NULL) { IDL_tree_error(method_tree, "only the last parameter can be marked [retval]"); return FALSE; } if (op->op_type_spec) { IDL_tree_error(method_tree, "can't have [retval] with non-void return type"); return FALSE; } /* In case XPConnect relaxes the retval-is-last restriction. */ if (seen_retval) { IDL_tree_error(method_tree, "can't have more than one [retval] parameter"); return FALSE; } seen_retval = TRUE; } /* * Confirm that [shared] attributes are only used with string, wstring, * or native (but not nsid, domstring, utf8string, cstring or astring) * and can't be used with [array]. */ if (IDL_tree_property_get(simple_decl, "shared") != NULL) { IDL_tree real_type; real_type = find_underlying_type(param_type); real_type = real_type ? real_type : param_type; if (IDL_tree_property_get(simple_decl, "array") != NULL) { IDL_tree_error(method_tree, "[shared] parameter \"%s\" cannot " "be of array type", param_name); return FALSE; } if (!(IDL_NODE_TYPE(real_type) == IDLN_TYPE_STRING || IDL_NODE_TYPE(real_type) == IDLN_TYPE_WIDE_STRING || (UP_IS_NATIVE(real_type) && !IDL_tree_property_get(real_type, "nsid") && !IDL_tree_property_get(real_type, "domstring") && !IDL_tree_property_get(real_type, "utf8string") && !IDL_tree_property_get(real_type, "cstring") && !IDL_tree_property_get(real_type, "astring")))) { IDL_tree_error(method_tree, "[shared] parameter \"%s\" must be of type " "string, wstring or native", param_name); return FALSE; } } /* * inout is not allowed with "domstring", "UTF8String", "CString" * and "AString" types */ if (IDL_PARAM_DCL(param).attr == IDL_PARAM_INOUT && UP_IS_NATIVE(param_type) && (IDL_tree_property_get(param_type, "domstring") != NULL || IDL_tree_property_get(param_type, "utf8string") != NULL || IDL_tree_property_get(param_type, "cstring") != NULL || IDL_tree_property_get(param_type, "astring") != NULL )) { IDL_tree_error(method_tree, "[domstring], [utf8string], [cstring], [astring] " "types cannot be used as inout parameters"); return FALSE; } /* * arrays of domstring, utf8string, cstring, astring types not allowed */ if (IDL_tree_property_get(simple_decl, "array") != NULL && UP_IS_NATIVE(param_type) && (IDL_tree_property_get(param_type, "domstring") != NULL || IDL_tree_property_get(param_type, "utf8string") != NULL || IDL_tree_property_get(param_type, "cstring") != NULL || IDL_tree_property_get(param_type, "astring") != NULL)) { IDL_tree_error(method_tree, "[domstring], [utf8string], [cstring], [astring] " "types cannot be used in array parameters"); return FALSE; } if (!check_param_attribute(method_tree, param, IID_IS) || !check_param_attribute(method_tree, param, LENGTH_IS) || !check_param_attribute(method_tree, param, SIZE_IS)) return FALSE; /* * Run additional error checks on the parameter type if targetting an * older version of XPConnect. */ if (!verify_type_fits_version(param_type, method_tree)) return FALSE; } /* XXX q: can return type be nsid? */ /* Native return type? */ if (scriptable_method && op->op_type_spec != NULL && UP_IS_NATIVE(op->op_type_spec) && IDL_tree_property_get(op->op_type_spec, "nsid") == NULL && IDL_tree_property_get(op->op_type_spec, "domstring") == NULL && IDL_tree_property_get(op->op_type_spec, "utf8string") == NULL && IDL_tree_property_get(op->op_type_spec, "cstring") == NULL && IDL_tree_property_get(op->op_type_spec, "astring") == NULL) { IDL_tree_error(method_tree, "methods in [scriptable] interfaces that are " "non-scriptable because they return native " "types must be marked [noscript]"); return FALSE; } /* * nsid's parameters that aren't ptr's or ref's are not currently * supported in xpcom */ if (!notxpcom && op->op_type_spec != NULL && IDL_tree_property_get(op->op_type_spec, "nsid") != NULL && IDL_tree_property_get(op->op_type_spec, "ptr") == NULL && IDL_tree_property_get(op->op_type_spec, "ref") == NULL) { IDL_tree_error(method_tree, "Feature currently not supported: " "return value is of type nsid and " "must be marked either [ptr] or [ref], " "or else method \"%s\" must be marked [notxpcom] ", method_name); return FALSE; } /* * Run additional error checks on the return type if targetting an * older version of XPConnect. */ if (op->op_type_spec != NULL && !verify_type_fits_version(op->op_type_spec, method_tree)) { return FALSE; } return TRUE; }
gboolean verify_const_declaration(IDL_tree const_tree) { struct _IDL_CONST_DCL *dcl = &IDL_CONST_DCL(const_tree); const char *name = IDL_IDENT(dcl->ident).str; IDL_tree real_type; /* const -> list -> interface */ if (!IDL_NODE_UP(IDL_NODE_UP(const_tree)) || IDL_NODE_TYPE(IDL_NODE_UP(IDL_NODE_UP(const_tree))) != IDLN_INTERFACE) { IDL_tree_error(const_tree, "const declaration \'%s\' outside interface", name); return FALSE; } /* Could be a typedef; try to map it to the real type. */ real_type = find_underlying_type(dcl->const_type); real_type = real_type ? real_type : dcl->const_type; if (IDL_NODE_TYPE(real_type) == IDLN_TYPE_INTEGER && (IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_SHORT || IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_LONG)) { if (!IDL_TYPE_INTEGER(real_type).f_signed && IDL_INTEGER(dcl->const_exp).value < 0) { #ifndef G_HAVE_GINT64 /* * For platforms without longlong support turned on we can get * confused by the high bit of the long value and think that it * represents a negative value in an unsigned declaration. * In that case we don't know if it is the programmer who is * confused or the compiler. So we issue a warning instead of * an error. */ if (IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_LONG) { XPIDL_WARNING((const_tree, IDL_WARNING1, "unsigned const declaration \'%s\' " "initialized with (possibly) negative constant", name)); return TRUE; } #endif IDL_tree_error(const_tree, "unsigned const declaration \'%s\' initialized with " "negative constant", name); return FALSE; } } else { IDL_tree_error(const_tree, "const declaration \'%s\' must be of type short or long", name); return FALSE; } return TRUE; }
int IDL_ns_scope_levels_from_here (IDL_ns ns, IDL_tree ident, IDL_tree parent) { IDL_tree p, scope_here, scope_ident; int levels; g_return_val_if_fail (ns != NULL, 1); g_return_val_if_fail (ident != NULL, 1); while (parent && !IDL_NODE_IS_SCOPED (parent)) parent = IDL_NODE_UP (parent); if (parent == NULL) return 1; if ((scope_here = IDL_tree_get_scope (parent)) == NULL || (scope_ident = IDL_tree_get_scope (ident)) == NULL) return 1; assert (IDL_NODE_TYPE (scope_here) == IDLN_GENTREE); assert (IDL_NODE_TYPE (scope_ident) == IDLN_GENTREE); for (levels = 1; scope_ident; ++levels, scope_ident = IDL_NODE_UP (scope_ident)) { p = IDL_ns_resolve_this_scope_ident ( ns, scope_here, IDL_GENTREE (scope_ident).data); if (p == scope_ident) return levels; } return 1; }
IDL_tree IDL_ns_place_new (IDL_ns ns, IDL_tree ident) { IDL_tree p, up_save; gboolean does_conflict; IDL_NS_ASSERTS; p = IDL_ns_lookup_cur_scope (ns, ident, &does_conflict); if (p != NULL && does_conflict) return NULL; /* The namespace tree is separate from the primary parse tree, so keep the primary tree node's parent the same */ up_save = IDL_NODE_UP (ident); p = IDL_gentree_chain_child (IDL_NS (ns).current, ident); IDL_NODE_UP (ident) = up_save; if (p == NULL) return NULL; assert (IDL_NODE_TYPE (p) == IDLN_GENTREE); IDL_IDENT_TO_NS (ident) = p; assert (IDL_NODE_UP (IDL_IDENT_TO_NS (ident)) == IDL_NS (ns).current); /* Generate default repository ID */ IDL_IDENT_REPO_ID (ident) = IDL_ns_ident_make_repo_id (__IDL_root_ns, p, NULL, NULL, NULL); return p; }
static gboolean find_arg_with_name(TreeState *state, const char *name, int16 *argnum) { int16 count; IDL_tree params; XPT_ASSERT(state); XPT_ASSERT(name); XPT_ASSERT(argnum); params = IDL_OP_DCL(IDL_NODE_UP(IDL_NODE_UP(state->tree))).parameter_dcls; for (count = 0; params != NULL && IDL_LIST(params).data != NULL; params = IDL_LIST(params).next, count++) { const char *cur_name = IDL_IDENT( IDL_PARAM_DCL(IDL_LIST(params).data).simple_declarator).str; if (!strcmp(cur_name, name)) { /* XXX ought to verify that this is the right type here */ /* XXX for iid_is this must be an iid */ /* XXX for size_is and length_is this must be a uint32 */ *argnum = count; return TRUE; } } return FALSE; }
void IDL_ns_pop_scope (IDL_ns ns) { IDL_NS_ASSERTS; if (IDL_NODE_UP (IDL_NS (ns).current) != NULL) IDL_NS (ns).current = IDL_NODE_UP (IDL_NS (ns).current); }
/* Return true if adds went okay */ static int IDL_ns_load_idents_to_tables (IDL_tree interface_ident, IDL_tree ident_scope, GTree *ident_heap, GHashTable *visited_interfaces) { IDL_tree q, scope; InsertHeapData data; assert (ident_scope != NULL); assert (IDL_NODE_TYPE (ident_scope) == IDLN_IDENT); scope = IDL_IDENT_TO_NS (ident_scope); if (!scope) return TRUE; assert (IDL_NODE_TYPE (scope) == IDLN_GENTREE); assert (IDL_GENTREE (scope).data != NULL); assert (IDL_NODE_TYPE (IDL_GENTREE (scope).data) == IDLN_IDENT); assert (IDL_NODE_UP (IDL_GENTREE (scope).data) != NULL); assert (IDL_NODE_TYPE (IDL_NODE_UP (IDL_GENTREE (scope).data)) == IDLN_INTERFACE); if (is_visited_interface (visited_interfaces, scope)) return TRUE; /* Search this namespace */ data.interface_ident = interface_ident; data.ident_heap = ident_heap; data.insert_conflict = 0; g_hash_table_foreach (IDL_GENTREE (scope).children, (GHFunc)insert_heap_cb, &data); /* If there are inherited namespaces, look in those before giving up */ q = IDL_GENTREE (scope)._import; if (!q) data.insert_conflict = 0; else assert (IDL_NODE_TYPE (q) == IDLN_LIST); /* Add inherited namespace identifiers into heap */ for (; q != NULL; q = IDL_LIST (q).next) { int r; assert (IDL_LIST (q).data != NULL); assert (IDL_NODE_TYPE (IDL_LIST (q).data) == IDLN_IDENT); assert (IDL_IDENT_TO_NS (IDL_LIST (q).data) != NULL); assert (IDL_NODE_TYPE (IDL_IDENT_TO_NS (IDL_LIST (q).data)) == IDLN_GENTREE); assert (IDL_NODE_TYPE (IDL_NODE_UP (IDL_LIST (q).data)) == IDLN_INTERFACE); if (!(r = IDL_ns_load_idents_to_tables (interface_ident, IDL_LIST (q).data, ident_heap, visited_interfaces))) data.insert_conflict = 1; } mark_visited_interface (visited_interfaces, scope); return data.insert_conflict == 0; }
IDL_tree IDL_ns_lookup_this_scope (IDL_ns ns, IDL_tree scope, IDL_tree ident, gboolean *conflict) { IDL_tree p, q; IDL_NS_ASSERTS; if (conflict) *conflict = TRUE; if (scope == NULL) return NULL; assert (IDL_NODE_TYPE (scope) == IDLN_GENTREE); /* Search this namespace */ if (g_hash_table_lookup_extended ( IDL_GENTREE (scope).children, ident, NULL, (gpointer)&p)) { assert (IDL_GENTREE (p).data != NULL); assert (IDL_NODE_TYPE (IDL_GENTREE (p).data) == IDLN_IDENT); return p; } /* If there are inherited namespaces, look in those before giving up */ q = IDL_GENTREE (scope)._import; if (!q) return NULL; assert (IDL_NODE_TYPE (q) == IDLN_LIST); for (; q != NULL; q = IDL_LIST (q).next) { IDL_tree r; assert (IDL_LIST (q).data != NULL); assert (IDL_NODE_TYPE (IDL_LIST (q).data) == IDLN_IDENT); assert (IDL_IDENT_TO_NS (IDL_LIST (q).data) != NULL); assert (IDL_NODE_TYPE (IDL_IDENT_TO_NS (IDL_LIST (q).data)) == IDLN_GENTREE); /* Search imported namespace scope q */ if (g_hash_table_lookup_extended ( IDL_GENTREE (IDL_IDENT_TO_NS (IDL_LIST (q).data)).children, ident, NULL, (gpointer)&p)) { assert (IDL_GENTREE (p).data != NULL); assert (IDL_NODE_TYPE (IDL_GENTREE (p).data) == IDLN_IDENT); /* This needs more work, it won't do full ambiguity detection */ if (conflict && !is_inheritance_conflict (p)) *conflict = FALSE; return p; } /* Search up one level */ if (IDL_NODE_TYPE (IDL_NODE_UP (IDL_LIST (q).data)) == IDLN_INTERFACE && (r = IDL_ns_lookup_this_scope ( ns, IDL_IDENT_TO_NS (IDL_LIST (q).data), ident, conflict))) return r; } return NULL; }
static int is_inheritance_conflict (IDL_tree p) { if (IDL_GENTREE (p).data == NULL) return FALSE; assert (IDL_NODE_TYPE (IDL_GENTREE (p).data) == IDLN_IDENT); if (IDL_NODE_UP (IDL_GENTREE (p).data) == NULL) return FALSE; if (!(IDL_NODE_TYPE (IDL_NODE_UP (IDL_GENTREE (p).data)) == IDLN_OP_DCL || (IDL_NODE_UP (IDL_GENTREE (p).data) && IDL_NODE_TYPE (IDL_NODE_UP (IDL_NODE_UP (IDL_GENTREE (p).data))) == IDLN_ATTR_DCL))) return FALSE; return TRUE; }
/* * Find the underlying type of an identifier typedef. * * All the needed tree-walking seems pretty shaky; isn't there something in * libIDL to automate this? */ IDL_tree /* IDL_TYPE_DCL */ find_underlying_type(IDL_tree typedef_ident) { IDL_tree up; if (typedef_ident == NULL || IDL_NODE_TYPE(typedef_ident) != IDLN_IDENT) return NULL; up = IDL_NODE_UP(typedef_ident); if (up == NULL || IDL_NODE_TYPE(up) != IDLN_LIST) return NULL; up = IDL_NODE_UP(up); if (up == NULL || IDL_NODE_TYPE(up) != IDLN_TYPE_DCL) return NULL; return IDL_TYPE_DCL(up).type_spec; }
/* If insertion was made, return true, else there was a collision */ static gboolean heap_insert_ident (IDL_tree interface_ident, GTree *heap, IDL_tree any) { IDL_tree p; assert (any != NULL); assert (heap != NULL); if ((p = g_tree_lookup (heap, any))) { char *newi; char *i1, *i2; char *what1 = "identifier", *what2 = what1; char *who1, *who2; IDL_tree q; assert (IDL_NODE_TYPE (p) == IDLN_IDENT); newi = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (interface_ident), "::", 0); i1 = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (p), "::", 0); i2 = IDL_ns_ident_to_qstring (IDL_IDENT_TO_NS (any), "::", 0); q = p; while (q && (IDL_NODE_TYPE (q) == IDLN_IDENT || IDL_NODE_TYPE (q) == IDLN_LIST)) q = IDL_NODE_UP (q); assert (q != NULL); IDL_tree_get_node_info (q, &what1, &who1); q = any; while (q && (IDL_NODE_TYPE (q) == IDLN_IDENT || IDL_NODE_TYPE (q) == IDLN_LIST)) q = IDL_NODE_UP (q); assert (q != NULL); IDL_tree_get_node_info (q, &what2, &who2); yyerrorv ("Ambiguous inheritance in interface `%s' from %s `%s' and %s `%s'", newi, what1, i1, what2, i2); IDL_tree_error (p, "%s `%s' conflicts with", what1, i1); IDL_tree_error (any, "%s `%s'", what2, i2); g_free (newi); g_free (i1); g_free (i2); return FALSE; } g_tree_insert (heap, any, any); return TRUE; }
void IDL_ns_push_scope (IDL_ns ns, IDL_tree ns_ident) { IDL_NS_ASSERTS; assert (IDL_NODE_TYPE (ns_ident) == IDLN_GENTREE); assert (IDL_NODE_TYPE (IDL_GENTREE (ns_ident).data) == IDLN_IDENT); assert (IDL_NS (ns).current == IDL_NODE_UP (ns_ident)); IDL_NS (ns).current = ns_ident; }
IDL_tree IDL_ns_qualified_ident_new (IDL_tree nsid) { IDL_tree l = NULL, item; while (nsid != NULL) { if (IDL_GENTREE (nsid).data == NULL) { nsid = IDL_NODE_UP (nsid); continue; } assert (IDL_GENTREE (nsid).data != NULL); assert (IDL_NODE_TYPE (IDL_GENTREE (nsid).data) == IDLN_IDENT); item = IDL_list_new (IDL_ident_new ( g_strdup (IDL_IDENT (IDL_GENTREE (nsid).data).str))); l = IDL_list_concat (item, l); nsid = IDL_NODE_UP (nsid); } return l; }
void orte_idl_attr_fake_ops(IDL_tree attr, IDL_ns ns) { IDL_tree attr_name, ident, curnode, op1, op2, intf; GString *attrname; OIDL_Attr_Info *setme; g_assert(attr && IDL_NODE_TYPE(attr) == IDLN_ATTR_DCL); attrname = g_string_new(NULL); for(curnode = IDL_ATTR_DCL(attr).simple_declarations; curnode; curnode = IDL_LIST(curnode).next) { op1 = op2 = NULL; attr_name = IDL_LIST(curnode).data; g_string_printf(attrname, "_get_%s", IDL_IDENT(attr_name).str); ident = IDL_ident_new(g_strdup(attrname->str)); IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(attr_name); op1 = IDL_op_dcl_new(0, IDL_ATTR_DCL(attr).param_type_spec, ident, NULL, NULL, NULL); IDL_NODE_UP(op1) = IDL_NODE_UP(attr); intf = IDL_NODE_UP (IDL_NODE_UP (op1)); IDL_NS(ns).current = IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident); IDL_ns_place_new(ns, ident); if(!IDL_ATTR_DCL(attr).f_readonly) { g_string_printf(attrname, "_set_%s", IDL_IDENT(attr_name).str); ident = IDL_ident_new(g_strdup(attrname->str)); IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(attr_name); op2 = IDL_op_dcl_new(0, NULL, ident, NULL, NULL, NULL); IDL_NODE_UP(op2) = IDL_NODE_UP(attr); intf = IDL_NODE_UP (IDL_NODE_UP (op2)); IDL_NS(ns).current = IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident); IDL_ns_place_new(ns, ident); IDL_OP_DCL(op2).parameter_dcls = IDL_list_new( IDL_param_dcl_new(IDL_PARAM_IN, IDL_ATTR_DCL(attr).param_type_spec, IDL_ident_new(g_strdup("value")))); } setme = g_new0(OIDL_Attr_Info, 1); setme->op1 = op1; setme->op2 = op2; attr_name->data = setme; } g_string_free(attrname, TRUE); }
static void cc_typecode_prep_sequence (IDL_tree tree, OIDL_C_Info *ci) { IDL_tree seq_type; IDL_tree fake_seq_type = NULL; char *type_str; char *seq_type_str; seq_type = orbit_cbe_get_typespec (IDL_TYPE_SEQUENCE (tree).simple_type_spec); if (IDL_NODE_TYPE (seq_type) != IDLN_INTERFACE) seq_type_str = orbit_cbe_get_typespec_str (seq_type); else { seq_type_str = g_strdup ("CORBA_Object"); fake_seq_type = IDL_type_object_new (); } type_str = orbit_cbe_get_typespec_str (IDL_TYPE_SEQUENCE (tree).simple_type_spec); if (strcmp (type_str, seq_type_str)) { IDL_tree fake_seq; fake_seq = IDL_type_sequence_new ( fake_seq_type ? fake_seq_type : seq_type, NULL); IDL_NODE_UP (fake_seq) = IDL_NODE_UP (tree); cc_output_typecodes (fake_seq, ci); IDL_TYPE_SEQUENCE (fake_seq).simple_type_spec = NULL; IDL_tree_free (fake_seq); } if (fake_seq_type) IDL_tree_free (fake_seq_type); g_free (type_str); g_free (seq_type_str); }
/* * If p is an ident for an interface, and we don't have an entry in the * interface map yet, add one. */ static gboolean add_interface_maybe(IDL_tree_func_data *tfd, gpointer user_data) { TreeState *state = user_data; IDL_tree up; if (IDL_NODE_TYPE(tfd->tree) == IDLN_IDENT) { IDL_tree_type node_type = IDL_NODE_TYPE((up = IDL_NODE_UP(tfd->tree))); if (node_type == IDLN_INTERFACE || node_type == IDLN_FORWARD_DCL) { /* We only want to add a new entry if there is no entry by this * name or if the previously found entry was just a forward * declaration and the new entry is not. */ char *iface = IDL_IDENT(tfd->tree).str; NewInterfaceHolder *old_holder = (NewInterfaceHolder *) g_hash_table_lookup(IFACE_MAP(state), iface); if (old_holder && old_holder->is_forward_dcl && node_type != IDLN_FORWARD_DCL) { g_hash_table_remove(IFACE_MAP(state), iface); DeleteNewInterfaceHolder(old_holder); old_holder = NULL; } if (!old_holder) { /* XXX should we parse here and store a struct nsID *? */ char *iid = (char *)IDL_tree_property_get(tfd->tree, "uuid"); char *name_space = (char *) IDL_tree_property_get(tfd->tree, "namespace"); NewInterfaceHolder *holder = CreateNewInterfaceHolder(iface, name_space, iid, (gboolean) node_type == IDLN_FORWARD_DCL); if (!holder) return FALSE; g_hash_table_insert(IFACE_MAP(state), holder->full_name, holder); IFACES(state)++; #ifdef DEBUG_shaver_ifaces fprintf(stderr, "adding interface #%d: %s/%s\n", IFACES(state), iface, iid[0] ? iid : "<unresolved>"); #endif } } else { #ifdef DEBUG_shaver_ifaces fprintf(stderr, "ident %s isn't an interface (%s)\n", IDL_IDENT(tfd->tree).str, IDL_NODE_TYPE_NAME(up)); #endif } } return TRUE; }
IDL_tree IDL_ns_resolve_this_scope_ident (IDL_ns ns, IDL_tree scope, IDL_tree ident) { IDL_tree p, q; IDL_NS_ASSERTS; p = scope; while (p != NULL) { q = IDL_ns_lookup_this_scope (ns, p, ident, NULL); if (q != NULL) return q; p = IDL_NODE_UP (p); } return p; }
gboolean orte_cbe_type_is_fixed_length(IDL_tree ts) { gboolean is_fixed = TRUE; IDL_tree curitem; ts = orte_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: for(curitem = IDL_TYPE_UNION(ts).switch_body; curitem; curitem = IDL_LIST(curitem).next) { is_fixed &= orte_cbe_type_is_fixed_length(IDL_LIST(IDL_CASE_STMT(IDL_LIST(curitem).data).element_spec).data); } return is_fixed; break; case IDLN_EXCEPT_DCL: case IDLN_TYPE_STRUCT: for(curitem = IDL_TYPE_STRUCT(ts).member_list; curitem; curitem = IDL_LIST(curitem).next) { is_fixed &= orte_cbe_type_is_fixed_length(IDL_LIST(curitem).data); } return is_fixed; break; case IDLN_TYPE_ARRAY: return orte_cbe_type_is_fixed_length(IDL_TYPE_DCL(IDL_get_parent_node(ts, IDLN_TYPE_DCL, NULL)).type_spec); break; case IDLN_TYPE_DCL: return orte_cbe_type_is_fixed_length(IDL_TYPE_DCL(ts).type_spec); break; case IDLN_IDENT: case IDLN_LIST: return orte_cbe_type_is_fixed_length(IDL_NODE_UP(ts)); break; case IDLN_MEMBER: return orte_cbe_type_is_fixed_length(IDL_MEMBER(ts).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; } }
static gboolean write_type(IDL_tree type_tree, gboolean is_out, FILE *outfile) { if (!type_tree) { fputs("void", outfile); return TRUE; } switch (IDL_NODE_TYPE(type_tree)) { case IDLN_TYPE_INTEGER: { gboolean sign = IDL_TYPE_INTEGER(type_tree).f_signed; switch (IDL_TYPE_INTEGER(type_tree).f_type) { case IDL_INTEGER_TYPE_SHORT: fputs(sign ? "PRInt16" : "PRUint16", outfile); break; case IDL_INTEGER_TYPE_LONG: fputs(sign ? "PRInt32" : "PRUint32", outfile); break; case IDL_INTEGER_TYPE_LONGLONG: fputs(sign ? "PRInt64" : "PRUint64", outfile); break; default: g_error("Unknown integer type %d\n", IDL_TYPE_INTEGER(type_tree).f_type); return FALSE; } break; } case IDLN_TYPE_CHAR: fputs("char", outfile); break; case IDLN_TYPE_WIDE_CHAR: fputs("PRUnichar", outfile); /* wchar_t? */ break; case IDLN_TYPE_WIDE_STRING: fputs("PRUnichar *", outfile); break; case IDLN_TYPE_STRING: fputs("char *", outfile); break; case IDLN_TYPE_BOOLEAN: fputs("PRBool", outfile); break; case IDLN_TYPE_OCTET: fputs("PRUint8", outfile); break; case IDLN_TYPE_FLOAT: switch (IDL_TYPE_FLOAT(type_tree).f_type) { case IDL_FLOAT_TYPE_FLOAT: fputs("float", outfile); break; case IDL_FLOAT_TYPE_DOUBLE: fputs("double", outfile); break; /* XXX 'long double' just ignored, or what? */ default: fprintf(outfile, "unknown_type_%d", IDL_NODE_TYPE(type_tree)); break; } break; case IDLN_IDENT: if (UP_IS_NATIVE(type_tree)) { if (IDL_tree_property_get(type_tree, "domstring") || IDL_tree_property_get(type_tree, "astring")) { fputs("nsAString", outfile); } else if (IDL_tree_property_get(type_tree, "utf8string")) { fputs("nsACString", outfile); } else if (IDL_tree_property_get(type_tree, "cstring")) { fputs("nsACString", outfile); } else { fputs(IDL_NATIVE(IDL_NODE_UP(type_tree)).user_type, outfile); } if (IDL_tree_property_get(type_tree, "ptr")) { fputs(" *", outfile); } else if (IDL_tree_property_get(type_tree, "ref")) { fputs(" &", outfile); } } else { fputs(IDL_IDENT(type_tree).str, outfile); } if (UP_IS_AGGREGATE(type_tree)) fputs(" *", outfile); break; default: fprintf(outfile, "unknown_type_%d", IDL_NODE_TYPE(type_tree)); break; } return TRUE; }
gboolean MateCORBA_imodule_type_is_fixed_length (IDL_tree tree) { gboolean is_fixed = TRUE; IDL_tree iter; IDL_tree typespec; typespec = MateCORBA_imodule_get_typespec (tree); switch (IDL_NODE_TYPE (typespec)) { 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: is_fixed = 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: is_fixed = FALSE; break; case IDLN_TYPE_UNION: for (iter = IDL_TYPE_UNION (typespec).switch_body; iter; iter = IDL_LIST (iter).next) is_fixed &= MateCORBA_imodule_type_is_fixed_length ( IDL_LIST (IDL_CASE_STMT ( IDL_LIST (iter).data).element_spec).data); break; case IDLN_EXCEPT_DCL: case IDLN_TYPE_STRUCT: for (iter = IDL_TYPE_STRUCT (typespec).member_list; iter; iter = IDL_LIST (iter).next) is_fixed &= MateCORBA_imodule_type_is_fixed_length (IDL_LIST (iter).data); break; case IDLN_TYPE_ARRAY: is_fixed = MateCORBA_imodule_type_is_fixed_length ( IDL_TYPE_DCL (IDL_get_parent_node ( typespec, IDLN_TYPE_DCL, NULL)).type_spec); break; case IDLN_TYPE_DCL: is_fixed = MateCORBA_imodule_type_is_fixed_length ( IDL_TYPE_DCL (typespec).type_spec); break; case IDLN_IDENT: case IDLN_LIST: is_fixed = MateCORBA_imodule_type_is_fixed_length (IDL_NODE_UP (typespec)); break; case IDLN_MEMBER: is_fixed = MateCORBA_imodule_type_is_fixed_length (IDL_MEMBER (typespec).type_spec); break; default: g_error ("Cannot determine if type %s is fixed-length", IDL_tree_type_names [IDL_NODE_TYPE (typespec)]); break; } return is_fixed; }
CORBA_TypeCode MateCORBA_imodule_get_typecode (GHashTable *typecodes, IDL_tree tree) { CORBA_Environment env; CORBA_TypeCode retval = CORBA_OBJECT_NIL; if (!tree) return CORBA_OBJECT_NIL; CORBA_exception_init (&env); switch (IDL_NODE_TYPE (tree)) { case IDLN_MEMBER: retval = MateCORBA_imodule_get_typecode ( typecodes, IDL_MEMBER (tree).type_spec); break; case IDLN_TYPE_ANY: retval = (CORBA_TypeCode) CORBA_Object_duplicate ( (CORBA_Object) TC_CORBA_any, NULL); break; case IDLN_TYPE_FLOAT: switch (IDL_TYPE_FLOAT (tree).f_type) { case IDL_FLOAT_TYPE_FLOAT: retval = TC_CORBA_float; break; case IDL_FLOAT_TYPE_DOUBLE: retval = TC_CORBA_double; break; case IDL_FLOAT_TYPE_LONGDOUBLE: retval = TC_CORBA_long_double; break; } break; case IDLN_TYPE_FIXED: retval = CORBA_ORB_create_fixed_tc (NULL, IDL_INTEGER (IDL_TYPE_FIXED (tree).positive_int_const).value, IDL_INTEGER (IDL_TYPE_FIXED (tree).integer_lit).value, &env); break; case IDLN_TYPE_INTEGER: if (!IDL_TYPE_INTEGER (tree).f_signed) switch (IDL_TYPE_INTEGER (tree).f_type) { case IDL_INTEGER_TYPE_SHORT: retval = TC_CORBA_unsigned_short; break; case IDL_INTEGER_TYPE_LONGLONG: retval = TC_CORBA_unsigned_long_long; break; case IDL_INTEGER_TYPE_LONG: retval = TC_CORBA_unsigned_long; break; default: g_assert_not_reached (); } else switch (IDL_TYPE_INTEGER (tree).f_type) { case IDL_INTEGER_TYPE_SHORT: retval = TC_CORBA_short; break; case IDL_INTEGER_TYPE_LONGLONG: retval = TC_CORBA_long_long; break; case IDL_INTEGER_TYPE_LONG: retval = TC_CORBA_long; break; default: g_assert_not_reached (); } break; case IDLN_TYPE_STRING: retval = (CORBA_TypeCode) CORBA_Object_duplicate ( (CORBA_Object) TC_CORBA_string, NULL); break; case IDLN_TYPE_WIDE_STRING: retval = (CORBA_TypeCode) CORBA_Object_duplicate ( (CORBA_Object) TC_CORBA_wstring, NULL); break; case IDLN_TYPE_OCTET: retval = (CORBA_TypeCode) CORBA_Object_duplicate ( (CORBA_Object) TC_CORBA_octet, NULL); break; case IDLN_TYPE_CHAR: retval = (CORBA_TypeCode) CORBA_Object_duplicate ( (CORBA_Object) TC_CORBA_char, NULL); break; case IDLN_TYPE_WIDE_CHAR: retval = (CORBA_TypeCode) CORBA_Object_duplicate ( (CORBA_Object) TC_CORBA_wchar, NULL); break; case IDLN_TYPE_BOOLEAN: retval = (CORBA_TypeCode) CORBA_Object_duplicate ( (CORBA_Object) TC_CORBA_boolean, NULL); break; case IDLN_TYPE_STRUCT: retval = MateCORBA_imodule_lookup_typecode ( typecodes, IDL_IDENT (IDL_TYPE_STRUCT (tree).ident).repo_id); if (!retval) { CORBA_StructMemberSeq *members; members = MateCORBA_imodule_get_struct_members ( typecodes, tree, &env); retval = CORBA_ORB_create_struct_tc (NULL, IDL_IDENT (IDL_TYPE_STRUCT (tree).ident).repo_id, IDL_IDENT (IDL_TYPE_STRUCT (tree).ident).str, members, &env); MateCORBA_imodule_register_typecode ( typecodes, IDL_IDENT (IDL_TYPE_STRUCT (tree).ident).repo_id, retval); CORBA_free (members); } break; case IDLN_EXCEPT_DCL: retval = MateCORBA_imodule_lookup_typecode ( typecodes, IDL_IDENT (IDL_EXCEPT_DCL (tree).ident).repo_id); if (!retval) { CORBA_StructMemberSeq *members; members = MateCORBA_imodule_get_struct_members ( typecodes, tree, &env); retval = CORBA_ORB_create_exception_tc (NULL, IDL_IDENT (IDL_EXCEPT_DCL (tree).ident).repo_id, IDL_IDENT (IDL_EXCEPT_DCL (tree).ident).str, members, &env); MateCORBA_imodule_register_typecode ( typecodes, IDL_IDENT (IDL_EXCEPT_DCL (tree).ident).repo_id, retval); CORBA_free (members); } break; case IDLN_TYPE_ARRAY: { CORBA_TypeCode subtc; IDL_tree sizer; IDL_tree type_dcl; sizer = IDL_list_nth (IDL_TYPE_ARRAY (tree).size_list, IDL_list_length (IDL_TYPE_ARRAY (tree).size_list) - 1); g_assert (IDL_NODE_TYPE (IDL_LIST (sizer).data) == IDLN_INTEGER); type_dcl = IDL_NODE_UP (IDL_NODE_UP (tree)); g_assert (IDL_NODE_TYPE (type_dcl) == IDLN_TYPE_DCL); subtc = MateCORBA_imodule_get_typecode ( typecodes, IDL_TYPE_DCL (type_dcl).type_spec), retval = CORBA_ORB_create_array_tc (NULL, IDL_INTEGER (IDL_LIST (sizer).data).value, subtc, &env); retval->c_align = subtc->c_align; CORBA_Object_release ((CORBA_Object) subtc, NULL); for (sizer = IDL_LIST (sizer).prev; sizer; sizer = IDL_LIST (sizer).prev) { subtc = retval; retval = CORBA_ORB_create_array_tc (NULL, IDL_INTEGER (IDL_LIST (sizer).data).value, subtc, &env); retval->c_align = subtc->c_align; CORBA_Object_release ((CORBA_Object) subtc, NULL); } subtc = retval; retval = MateCORBA_imodule_create_alias_typecode ( typecodes, IDL_TYPE_ARRAY (tree).ident, subtc); CORBA_Object_release ((CORBA_Object) subtc, NULL); } break; case IDLN_TYPE_UNION: retval = MateCORBA_imodule_lookup_typecode ( typecodes, IDL_IDENT (IDL_TYPE_UNION (tree).ident).repo_id); if (!retval) { CORBA_UnionMemberSeq *members; CORBA_TypeCode switchtc; switchtc = MateCORBA_imodule_get_typecode ( typecodes, IDL_TYPE_UNION (tree).switch_type_spec); members = MateCORBA_imodule_get_union_members ( typecodes, tree, switchtc, &env); retval = CORBA_ORB_create_union_tc (NULL, IDL_IDENT (IDL_TYPE_UNION (tree).ident).repo_id, IDL_IDENT (IDL_TYPE_UNION (tree).ident).str, switchtc, members, &env); CORBA_Object_release ((CORBA_Object) switchtc, NULL); MateCORBA_imodule_register_typecode ( typecodes, IDL_IDENT (IDL_TYPE_UNION (tree).ident).repo_id, retval); CORBA_free (members); } break; case IDLN_TYPE_ENUM: retval = MateCORBA_imodule_lookup_typecode ( typecodes, IDL_IDENT (IDL_TYPE_ENUM (tree).ident).repo_id); if (!retval) { CORBA_EnumMemberSeq *members; members = MateCORBA_imodule_get_enum_members (tree, &env); retval = CORBA_ORB_create_enum_tc (NULL, IDL_IDENT (IDL_TYPE_ENUM (tree).ident).repo_id, IDL_IDENT (IDL_TYPE_ENUM (tree).ident).str, members, &env); MateCORBA_imodule_register_typecode ( typecodes, IDL_IDENT (IDL_TYPE_ENUM (tree).ident).repo_id, retval); CORBA_free (members); } break; case IDLN_IDENT: retval = MateCORBA_imodule_lookup_typecode ( typecodes, IDL_IDENT (tree).repo_id); g_assert (retval != NULL); break; case IDLN_TYPE_SEQUENCE: { CORBA_TypeCode subtc; int bound = 0; if (IDL_TYPE_SEQUENCE (tree).positive_int_const) bound = IDL_INTEGER (IDL_TYPE_SEQUENCE (tree).positive_int_const).value; subtc = MateCORBA_imodule_get_typecode ( typecodes, IDL_TYPE_SEQUENCE (tree).simple_type_spec), retval = CORBA_ORB_create_sequence_tc (NULL, bound, subtc, &env); CORBA_Object_release ((CORBA_Object) subtc, NULL); /* * FIXME: and what about recursive sequences? */ } break; case IDLN_FORWARD_DCL: case IDLN_INTERFACE: retval = MateCORBA_imodule_lookup_typecode ( typecodes, IDL_IDENT (IDL_TYPE_ENUM (tree).ident).repo_id); if (!retval) { retval = CORBA_ORB_create_interface_tc (NULL, IDL_IDENT (IDL_TYPE_ENUM (tree).ident).repo_id, IDL_IDENT (IDL_TYPE_ENUM (tree).ident).str, &env); MateCORBA_imodule_register_typecode ( typecodes, IDL_IDENT (IDL_TYPE_ENUM (tree).ident).repo_id, retval); } break; case IDLN_TYPE_OBJECT: retval = (CORBA_TypeCode) CORBA_Object_duplicate ( (CORBA_Object) TC_CORBA_Object, NULL); break; case IDLN_TYPE_TYPECODE: retval = (CORBA_TypeCode) CORBA_Object_duplicate ( (CORBA_Object) TC_CORBA_TypeCode, NULL); break; default: g_error ("We were asked to get a typecode for a %s", IDL_tree_type_names [IDL_NODE_TYPE (tree)]); break; } if (retval && retval->c_align == 0) retval->c_align = MateCORBA_imodule_find_c_align (tree); if (env._major != CORBA_NO_EXCEPTION) g_warning ("MateCORBA_imodule_get_typecode: exception %s", env._id); CORBA_exception_free (&env); return retval; }
static gboolean constant_declaration(TreeState *state) { /* * The C++ header XPIDL module only allows for shorts and longs (ints) * to be constants, so we will follow the same convention */ struct _IDL_CONST_DCL *declaration = &IDL_CONST_DCL(state->tree); const char *name = IDL_IDENT(declaration->ident).str; IDL_tree real_type; gboolean success; gboolean isshort = FALSE; if (!verify_const_declaration(state->tree)) return FALSE; /* Could be a typedef; try to map it to the real type. */ real_type = find_underlying_type(declaration->const_type); real_type = real_type ? real_type : declaration->const_type; /* * Consts must be in an interface */ if (!IDL_NODE_UP(IDL_NODE_UP(state->tree)) || IDL_NODE_TYPE(IDL_NODE_UP(IDL_NODE_UP(state->tree))) != IDLN_INTERFACE) { XPIDL_WARNING((state->tree, IDL_WARNING1, "A constant \"%s\" was declared outside an interface." " It was ignored.", name)); return TRUE; } /* * Make sure this is a numeric short or long constant. */ success = (IDLN_TYPE_INTEGER == IDL_NODE_TYPE(real_type)); if (success) { /* * We aren't successful yet, we know it's an integer, but what *kind* * of integer? */ switch(IDL_TYPE_INTEGER(real_type).f_type) { case IDL_INTEGER_TYPE_SHORT: /* * We're OK */ isshort = TRUE; break; case IDL_INTEGER_TYPE_LONG: /* * We're OK */ break; default: /* * Whoops, it's some other kind of number */ success = FALSE; } } else { IDL_tree_error(state->tree, "const declaration \'%s\' must be of type short or long", name); return FALSE; } /* if (doc_comments != NULL) { fputs(" ", state->file); printlist(state->file, doc_comments); } */ if (success) { /* Since Java does not have any concept of 'unsigned short', we need * to check that the value is in the proper range. If not, promote * it to an 'int'. */ int value = (int) IDL_INTEGER(declaration->const_exp).value; if (isshort && (value < -32768 || value > 32767)) isshort = FALSE; fputc('\n', state->file); xpidl_write_comment(state, 4); /* write_comment(state); */ fprintf(state->file, " public static final %s %s = %d;\n", (isshort ? "short" : "int"), subscriptIdentifier(state, (char*) name), (int) IDL_INTEGER(declaration->const_exp).value); } else { XPIDL_WARNING((state->tree, IDL_WARNING1, "A constant \"%s\" was not of type short or long." " It was ignored.", name)); } return TRUE; }
gboolean verify_attribute_declaration(IDL_tree attr_tree) { IDL_tree iface; IDL_tree ident; IDL_tree attr_type; gboolean scriptable_interface; /* We don't support attributes named IID, conflicts with static GetIID * member. The conflict is due to certain compilers (VC++) choosing a * different vtable order, placing GetIID at the beginning regardless * of it's placement */ if (strcmp( IDL_IDENT( IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).data).str, "IID") == 0) { IDL_tree_error(attr_tree, "Attributes named IID not supported, causes vtable " "ordering problems"); return FALSE; } /* * Verify that we've been called on an interface, and decide if the * interface was marked [scriptable]. */ if (IDL_NODE_UP(attr_tree) && IDL_NODE_UP(IDL_NODE_UP(attr_tree)) && IDL_NODE_TYPE(iface = IDL_NODE_UP(IDL_NODE_UP(attr_tree))) == IDLN_INTERFACE) { scriptable_interface = (IDL_tree_property_get(IDL_INTERFACE(iface).ident, "scriptable") != NULL); } else { IDL_tree_error(attr_tree, "verify_attribute_declaration called on a non-interface?"); return FALSE; } /* * Grab the first of the list of idents and hope that it'll * say scriptable or no. */ ident = IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).data; /* * If the interface isn't scriptable, or the attribute is marked noscript, * there's no need to check. */ if (!scriptable_interface || IDL_tree_property_get(ident, "noscript") != NULL) return TRUE; /* * If it should be scriptable, check that the type is non-native. nsid, * domstring, utf8string, cstring, astring are exempted. */ attr_type = IDL_ATTR_DCL(attr_tree).param_type_spec; if (attr_type != NULL) { if (UP_IS_NATIVE(attr_type) && IDL_tree_property_get(attr_type, "nsid") == NULL && IDL_tree_property_get(attr_type, "domstring") == NULL && IDL_tree_property_get(attr_type, "utf8string") == NULL && IDL_tree_property_get(attr_type, "cstring") == NULL && IDL_tree_property_get(attr_type, "astring") == NULL) { IDL_tree_error(attr_tree, "attributes in [scriptable] interfaces that are " "non-scriptable because they refer to native " "types must be marked [noscript]\n"); return FALSE; } /* * We currently don't support properties of type nsid that aren't * pointers or references, unless they are marked [notxpcom} and * must be read-only */ if ((IDL_tree_property_get(ident, "notxpcom") == NULL || !(IDL_ATTR_DCL(attr_tree).f_readonly)) && IDL_tree_property_get(attr_type,"nsid") != NULL && IDL_tree_property_get(attr_type,"ptr") == NULL && IDL_tree_property_get(attr_type,"ref") == NULL) { IDL_tree_error(attr_tree, "Feature not currently supported: " "attributes with a type of nsid must be marked " "either [ptr] or [ref], or " "else must be marked [notxpcom] " "and must be read-only\n"); return FALSE; } /* * Run additional error checks on the attribute type if targetting an * older version of XPConnect. */ if (!verify_type_fits_version(attr_type, attr_tree)) return FALSE; } if (IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).next != NULL) { IDL_tree_error(attr_tree, "multiple attributes in a single declaration is not supported\n"); return FALSE; } return TRUE; }
static gboolean xpcom_to_java_type(TreeState *state, IDL_tree type) { IDL_tree real_type; IDL_tree up; if (!type) { fputs("Object", state->file); return TRUE; } /* Could be a typedef; try to map it to the real type */ real_type = find_underlying_type(type); type = real_type ? real_type : type; switch(IDL_NODE_TYPE(type)) { case IDLN_TYPE_INTEGER: { switch(IDL_TYPE_INTEGER(type).f_type) { case IDL_INTEGER_TYPE_SHORT: fputs("short", state->file); break; case IDL_INTEGER_TYPE_LONG: fputs("int", state->file); break; case IDL_INTEGER_TYPE_LONGLONG: fputs("long", state->file); break; default: g_error(" Unknown integer type: %d\n", IDL_TYPE_INTEGER(type).f_type); return FALSE; } break; } case IDLN_TYPE_CHAR: case IDLN_TYPE_WIDE_CHAR: fputs("char", state->file); break; case IDLN_TYPE_WIDE_STRING: case IDLN_TYPE_STRING: fputs("String", state->file); break; case IDLN_TYPE_BOOLEAN: fputs("boolean", state->file); break; case IDLN_TYPE_OCTET: fputs("byte", state->file); break; case IDLN_TYPE_FLOAT: switch(IDL_TYPE_FLOAT(type).f_type) { case IDL_FLOAT_TYPE_FLOAT: fputs("float", state->file); break; case IDL_FLOAT_TYPE_DOUBLE: fputs("double", state->file); break; default: g_error(" Unknown floating point typ: %d\n", IDL_NODE_TYPE(type)); break; } break; case IDLN_IDENT: if (!(up = IDL_NODE_UP(type))) { IDL_tree_error(state->tree, "ERROR: orphan ident %s in param list\n", IDL_IDENT(state->tree).str); return FALSE; } switch (IDL_NODE_TYPE(up)) { case IDLN_FORWARD_DCL: case IDLN_INTERFACE: { char *className; const char *iid_is; handle_iid_is: /* might get here via the goto, so re-check type */ if (IDL_NODE_TYPE(up) == IDLN_INTERFACE) className = IDL_IDENT(IDL_INTERFACE(up).ident).str; else if (IDL_NODE_TYPE(up) == IDLN_FORWARD_DCL) className = IDL_IDENT(IDL_FORWARD_DCL(up).ident).str; else className = IDL_IDENT(IDL_NATIVE(up).ident).str; iid_is = NULL; if (IDL_NODE_TYPE(state->tree) == IDLN_PARAM_DCL) { iid_is = IDL_tree_property_get(IDL_PARAM_DCL(state->tree).simple_declarator, "iid_is"); } if (iid_is) { fputs("nsISupports", state->file); } else { /* XXX How do we want to handle this? If it's an IDLN_INTERFACE, * then we can just output the name of the class, since the IDL * files exist for those classes. However, if it's an * IDLN_FORWARD_DCL, some of those interfaces are not defined in * IDL files, so we get an error when trying to compile the java * files. So, for now, we just output them as the base iface * (nsISupports). */ if (IDL_NODE_TYPE(up) == IDLN_FORWARD_DCL) fputs("nsISupports", state->file); else fprintf(state->file, "%s", className); } break; } case IDLN_NATIVE: { char *ident; /* jband - adding goto for iid_is when type is native */ if (IDL_NODE_TYPE(state->tree) == IDLN_PARAM_DCL && IDL_tree_property_get(IDL_PARAM_DCL(state->tree).simple_declarator, "iid_is")) { goto handle_iid_is; /* fputs("nsISupports", state->file); */ break; } ident = IDL_IDENT(type).str; if (IDL_tree_property_get(type, "nsid")) { fputs("String", state->file); } else if (IDL_tree_property_get(type, "domstring")) { fputs("String", state->file); } else if (IDL_tree_property_get(type, "astring")) { fputs("String", state->file); } else if (IDL_tree_property_get(type, "utf8string")) { fputs("String", state->file); } else if (IDL_tree_property_get(type, "cstring")) { fputs("String", state->file); } else { const char* user_type = IDL_NATIVE(IDL_NODE_UP(type)).user_type; IDL_tree real_type = g_hash_table_lookup(TYPEDEFS(state), user_type); if (real_type) { return xpcom_to_java_type(state, real_type); } else { if (strcmp(user_type, "PRInt8") == 0 || strcmp(user_type, "PRUint8") == 0) { fputs("byte", state->file); } else if (strcmp(user_type, "PRInt16") == 0 || strcmp(user_type, "PRUint16") == 0) { fputs("short", state->file); } else if (strcmp(user_type, "PRInt32") == 0 || strcmp(user_type, "PRUint32") == 0 || strcmp(user_type, "int") == 0) { fputs("int", state->file); } else if (strcmp(user_type, "PRInt64") == 0 || strcmp(user_type, "PRUint64") == 0) { fputs("long", state->file); } else if (strcmp(user_type, "PRBool") == 0) { fputs("boolean", state->file); } else if (strncmp(user_type, "char", 4) == 0 || strncmp(user_type, "const char", 10) == 0 || strncmp(user_type, "unsigned char", 13) == 0) { if (IDL_tree_property_get(type, "ptr")) { fputs("byte[]", state->file); } else { fputs("char", state->file); } } else if (strcmp(user_type, "nsIID") == 0) { fputs("String", state->file); } else if (strcmp(user_type, "nsString") == 0 || strcmp(user_type, "nsAString") == 0 || strcmp(user_type, "nsACString") == 0) { fputs("String", state->file); } else { fputs("int", state->file); } } } break; } default: if (IDL_NODE_TYPE(IDL_NODE_UP(up)) == IDLN_TYPE_DCL) { /* restart with the underlying type */ IDL_tree new_type; new_type = IDL_TYPE_DCL(IDL_NODE_UP(up)).type_spec; if (new_type) { gboolean rc = xpcom_to_java_type(state, new_type); return rc; } else { /* do what we would do in recursion if !type */ fputs("Object", state->file); return TRUE; } } IDL_tree_error(state->tree, "can't handle %s ident in param list\n", "that type of" ); return FALSE; } break; default: IDL_tree_error(state->tree, "can't handle %s in param list\n", #ifdef DEBUG_shaver /* XXX is this safe to use on Win now? */ IDL_NODE_TYPE_NAME(IDL_NODE_UP(type)) #else "that type" #endif ); return FALSE; } return TRUE; }
static gboolean fill_td_from_type(TreeState *state, XPTTypeDescriptor *td, IDL_tree type) { IDL_tree up; int16 size_is_argnum; int16 length_is_argnum; gboolean has_size_is; gboolean has_length_is; gboolean is_array = FALSE; if (type) { /* deal with array */ if (IDL_NODE_TYPE(state->tree) == IDLN_PARAM_DCL) { IDL_tree sd = IDL_PARAM_DCL(state->tree).simple_declarator; if (IDL_tree_property_get(sd, "array")) { is_array = TRUE; /* size_is is required! */ if (!get_size_and_length(state, type, &size_is_argnum, &length_is_argnum, &has_size_is, &has_length_is)) { /* error was reported by helper function */ return FALSE; } if (!has_size_is) { IDL_tree_error(state->tree, "[array] requires [size_is()]\n"); return FALSE; } td->prefix.flags = TD_ARRAY | XPT_TDP_POINTER; td->argnum = size_is_argnum; if (has_length_is) td->argnum2 = length_is_argnum; else td->argnum2 = size_is_argnum; /* * XXX - NOTE - this will be broken for multidimensional * arrays because of the realloc XPT_InterfaceDescriptorAddTypes * uses. The underlying 'td' can change as we recurse in to get * additional dimensions. Luckily, we don't yet support more * than on dimension in the arrays */ /* setup the additional_type */ if (!XPT_InterfaceDescriptorAddTypes(ARENA(state), CURRENT(state), 1)) { g_error("out of memory\n"); return FALSE; } td->type.additional_type = NEXT_TYPE(state); td = &CURRENT(state)->additional_types[NEXT_TYPE(state)]; NEXT_TYPE(state)++ ; } } handle_typedef: switch (IDL_NODE_TYPE(type)) { case IDLN_TYPE_INTEGER: { gboolean sign = IDL_TYPE_INTEGER(type).f_signed; switch(IDL_TYPE_INTEGER(type).f_type) { case IDL_INTEGER_TYPE_SHORT: td->prefix.flags = sign ? TD_INT16 : TD_UINT16; break; case IDL_INTEGER_TYPE_LONG: td->prefix.flags = sign ? TD_INT32 : TD_UINT32; break; case IDL_INTEGER_TYPE_LONGLONG: td->prefix.flags = sign ? TD_INT64 : TD_UINT64; break; } break; } case IDLN_TYPE_CHAR: td->prefix.flags = TD_CHAR; break; case IDLN_TYPE_WIDE_CHAR: td->prefix.flags = TD_WCHAR; break; case IDLN_TYPE_STRING: if (is_array) { td->prefix.flags = TD_PSTRING | XPT_TDP_POINTER; } else { if (!get_size_and_length(state, type, &size_is_argnum, &length_is_argnum, &has_size_is, &has_length_is)) { /* error was reported by helper function */ return FALSE; } if (has_size_is) { td->prefix.flags = TD_PSTRING_SIZE_IS | XPT_TDP_POINTER; td->argnum = size_is_argnum; if (has_length_is) td->argnum2 = length_is_argnum; else td->argnum2 = size_is_argnum; } else { td->prefix.flags = TD_PSTRING | XPT_TDP_POINTER; } } break; case IDLN_TYPE_WIDE_STRING: if (is_array) { td->prefix.flags = TD_PWSTRING | XPT_TDP_POINTER; } else { if (!get_size_and_length(state, type, &size_is_argnum, &length_is_argnum, &has_size_is, &has_length_is)) { /* error was reported by helper function */ return FALSE; } if (has_size_is) { td->prefix.flags = TD_PWSTRING_SIZE_IS | XPT_TDP_POINTER; td->argnum = size_is_argnum; if (has_length_is) td->argnum2 = length_is_argnum; else td->argnum2 = size_is_argnum; } else { td->prefix.flags = TD_PWSTRING | XPT_TDP_POINTER; } } break; case IDLN_TYPE_BOOLEAN: td->prefix.flags = TD_BOOL; break; case IDLN_TYPE_OCTET: td->prefix.flags = TD_UINT8; break; case IDLN_TYPE_FLOAT: switch (IDL_TYPE_FLOAT (type).f_type) { case IDL_FLOAT_TYPE_FLOAT: td->prefix.flags = TD_FLOAT; break; case IDL_FLOAT_TYPE_DOUBLE: td->prefix.flags = TD_DOUBLE; break; /* XXX 'long double' just ignored, or what? */ default: break; } break; case IDLN_IDENT: if (!(up = IDL_NODE_UP(type))) { IDL_tree_error(state->tree, "ERROR: orphan ident %s in param list\n", IDL_IDENT(type).str); return FALSE; } switch (IDL_NODE_TYPE(up)) { /* This whole section is abominably ugly */ case IDLN_FORWARD_DCL: case IDLN_INTERFACE: { XPTInterfaceDirectoryEntry *ide, *ides; uint16 num_ifaces; char *className; const char *iid_is; handle_iid_is: ides = HEADER(state)->interface_directory; num_ifaces = HEADER(state)->num_interfaces; /* might get here via the goto, so re-check type */ if (IDL_NODE_TYPE(up) == IDLN_INTERFACE) className = IDL_IDENT(IDL_INTERFACE(up).ident).str; else if (IDL_NODE_TYPE(up) == IDLN_FORWARD_DCL) className = IDL_IDENT(IDL_FORWARD_DCL(up).ident).str; else className = IDL_IDENT(IDL_NATIVE(up).ident).str; iid_is = NULL; if (IDL_NODE_TYPE(state->tree) == IDLN_PARAM_DCL) { iid_is = IDL_tree_property_get(IDL_PARAM_DCL(state->tree).simple_declarator, "iid_is"); } if (iid_is) { int16 argnum; if (!find_arg_with_name(state, iid_is, &argnum)) { IDL_tree_error(state->tree, "can't find matching argument for " "[iid_is(%s)]\n", iid_is); return FALSE; } td->prefix.flags = TD_INTERFACE_IS_TYPE | XPT_TDP_POINTER; td->argnum = argnum; } else { td->prefix.flags = TD_INTERFACE_TYPE | XPT_TDP_POINTER; ide = FindInterfaceByName(ides, num_ifaces, className); if (!ide || ide < ides || ide > ides + num_ifaces) { IDL_tree_error(state->tree, "unknown iface %s in param\n", className); return FALSE; } td->type.iface = ide - ides + 1; #ifdef DEBUG_shaver_index fprintf(stderr, "DBG: index %d for %s\n", td->type.iface, className); #endif } break; } case IDLN_NATIVE: { char *ident; /* jband - adding goto for iid_is when type is native */ if (IDL_NODE_TYPE(state->tree) == IDLN_PARAM_DCL && IDL_tree_property_get(IDL_PARAM_DCL(state->tree).simple_declarator, "iid_is")) goto handle_iid_is; ident = IDL_IDENT(type).str; if (IDL_tree_property_get(type, "nsid")) { td->prefix.flags = TD_PNSIID; if (IDL_tree_property_get(type, "ref")) td->prefix.flags |= XPT_TDP_POINTER | XPT_TDP_REFERENCE; else if (IDL_tree_property_get(type,"ptr")) td->prefix.flags |= XPT_TDP_POINTER; } else if (IDL_tree_property_get(type, "domstring")) { td->prefix.flags = TD_DOMSTRING | XPT_TDP_POINTER; if (IDL_tree_property_get(type, "ref")) td->prefix.flags |= XPT_TDP_REFERENCE; } else if (IDL_tree_property_get(type, "astring")) { td->prefix.flags = TD_ASTRING | XPT_TDP_POINTER; if (IDL_tree_property_get(type, "ref")) td->prefix.flags |= XPT_TDP_REFERENCE; } else if (IDL_tree_property_get(type, "utf8string")) { td->prefix.flags = TD_UTF8STRING | XPT_TDP_POINTER; if (IDL_tree_property_get(type, "ref")) td->prefix.flags |= XPT_TDP_REFERENCE; } else if (IDL_tree_property_get(type, "cstring")) { td->prefix.flags = TD_CSTRING | XPT_TDP_POINTER; if (IDL_tree_property_get(type, "ref")) td->prefix.flags |= XPT_TDP_REFERENCE; } else if (IDL_tree_property_get(type, "jsval")) { td->prefix.flags = TD_JSVAL; if (IDL_tree_property_get(type, "ptr")) td->prefix.flags |= XPT_TDP_POINTER; } else { td->prefix.flags = TD_VOID | XPT_TDP_POINTER; } break; } default: if (IDL_NODE_TYPE(IDL_NODE_UP(up)) == IDLN_TYPE_DCL) { /* restart with the underlying type */ IDL_tree new_type; new_type = IDL_TYPE_DCL(IDL_NODE_UP(up)).type_spec; #ifdef DEBUG_shaver_misc fprintf(stderr, "following %s typedef to %s\n", IDL_IDENT(type).str, IDL_NODE_TYPE_NAME(new_type)); #endif /* * Do a nice messy goto rather than recursion so that * we can avoid screwing up the *array* information. */ /* return fill_td_from_type(state, td, new_type); */ if (new_type) { type = new_type; goto handle_typedef; } else { /* do what we would do in recursion if !type */ td->prefix.flags = TD_VOID; return TRUE; } } IDL_tree_error(state->tree, "can't handle %s ident in param list\n", #ifdef DEBUG_shaver /* XXX is this safe to use on Win now? */ IDL_NODE_TYPE_NAME(IDL_NODE_UP(type)) #else "that type of" #endif ); #ifdef DEBUG_shaver XPT_ASSERT(0); #endif return FALSE; } break; default: IDL_tree_error(state->tree, "can't handle %s in param list\n", #ifdef DEBUG_shaver /* XXX is this safe to use on Win now? */ IDL_NODE_TYPE_NAME(IDL_NODE_UP(type)) #else "that type" #endif ); return FALSE; } } else { td->prefix.flags = TD_VOID; } return TRUE; }
static gboolean xpcom_to_java_type (TreeState *state) { IDL_tree real_type; if (!state->tree) { fputs("Object", FILENAME(state)); return TRUE; } /* Could be a typedef; try to map it to the real type */ real_type = find_underlying_type(state->tree); state->tree = real_type ? real_type : state->tree; switch(IDL_NODE_TYPE(state->tree)) { case IDLN_TYPE_INTEGER: { switch(IDL_TYPE_INTEGER(state->tree).f_type) { case IDL_INTEGER_TYPE_SHORT: fputs("short", FILENAME(state)); break; case IDL_INTEGER_TYPE_LONG: fputs("int", FILENAME(state)); break; case IDL_INTEGER_TYPE_LONGLONG: fputs("long", FILENAME(state)); break; default: g_error(" Unknown integer type: %d\n", IDL_TYPE_INTEGER(state->tree).f_type); return FALSE; } break; } case IDLN_TYPE_CHAR: case IDLN_TYPE_WIDE_CHAR: fputs("char", FILENAME(state)); break; case IDLN_TYPE_WIDE_STRING: case IDLN_TYPE_STRING: fputs("String", FILENAME(state)); break; case IDLN_TYPE_BOOLEAN: fputs("boolean", FILENAME(state)); break; case IDLN_TYPE_OCTET: fputs("byte", FILENAME(state)); break; case IDLN_TYPE_FLOAT: switch(IDL_TYPE_FLOAT(state->tree).f_type) { case IDL_FLOAT_TYPE_FLOAT: fputs("float", FILENAME(state)); break; case IDL_FLOAT_TYPE_DOUBLE: fputs("double", FILENAME(state)); break; default: g_error(" Unknown floating point typ: %d\n", IDL_NODE_TYPE(state->tree)); break; } break; case IDLN_IDENT: if (IDL_NODE_UP(state->tree) && IDL_NODE_TYPE(IDL_NODE_UP(state->tree)) == IDLN_NATIVE) { const char *user_type = IDL_NATIVE(IDL_NODE_UP(state->tree)).user_type; const char *ident_str = IDL_IDENT(IDL_NATIVE(IDL_NODE_UP(state->tree)).ident).str; if (strcmp(user_type, "void") == 0) { /*it should not happend for scriptable methods*/ fputs("Object", FILENAME(state)); } /* XXX: s.b test for "id" attribute */ /* XXX: special class for nsIDs */ else if (strcmp(user_type, "nsID") == 0) { fputs("ID", FILENAME(state)); } else if (strcmp(user_type, "nsIID") == 0) { fputs("IID", FILENAME(state)); } else if (strcmp(user_type, "nsCID") == 0) { fputs("CID", FILENAME(state)); } else { /* XXX: special class for opaque types */ /*it should not happend for scriptable methods*/ fputs("OpaqueValue", FILENAME(state)); } } else { const char *ident_str = IDL_IDENT(state->tree).str; /* XXX: big kludge; s.b. way to match to typedefs */ if (strcmp(ident_str, "PRInt8") == 0 || strcmp(ident_str, "PRUint8") == 0) { fputs("byte", FILENAME(state)); } else if (strcmp(ident_str, "PRInt16") == 0 || strcmp(ident_str, "PRUint16") == 0) { fputs("short", FILENAME(state)); } else if (strcmp(ident_str, "PRInt32") == 0 || strcmp(ident_str, "PRUint32") == 0) { fputs("int", FILENAME(state)); } else if (strcmp(ident_str, "PRInt64") == 0 || strcmp(ident_str, "PRUint64") == 0) { fputs("long", FILENAME(state)); } else if (strcmp(ident_str, "PRBool") == 0) { fputs("boolean", FILENAME(state)); } else if (strcmp(ident_str, "nsrefcnt") == 0) { fputs("int", FILENAME(state)); } else { IDL_tree real_type = g_hash_table_lookup(TYPEDEFS(state), ident_str); if (real_type) { IDL_tree orig_tree = state->tree; state->tree = real_type; xpcom_to_java_type(state); state->tree = orig_tree; } else { fputs(subscriptIdentifier(state, (char*) ident_str), FILENAME(state)); } } } break; case IDLN_TYPE_ENUM: case IDLN_TYPE_OBJECT: default: g_error(" Unknown type: %d\n", IDL_TYPE_FLOAT(state->tree).f_type); break; } return TRUE; }