📄 gtype.c
字号:
do { guint i; IFaceEntry *check; i = (n_ifaces + 1) >> 1; check = ifaces + i; if (iface_type == check->iface_type) return check; else if (iface_type > check->iface_type) { n_ifaces -= i; ifaces = check; } else /* if (iface_type < check->iface_type) */ n_ifaces = i - 1; } while (n_ifaces); } return NULL;}static inline gbooleantype_lookup_prerequisite_L (TypeNode *iface, GType prerequisite_type){ if (NODE_IS_IFACE (iface) && IFACE_NODE_N_PREREQUISITES (iface)) { GType *prerequisites = IFACE_NODE_PREREQUISITES (iface) - 1; guint n_prerequisites = IFACE_NODE_N_PREREQUISITES (iface); do { guint i; GType *check; i = (n_prerequisites + 1) >> 1; check = prerequisites + i; if (prerequisite_type == *check) return TRUE; else if (prerequisite_type > *check) { n_prerequisites -= i; prerequisites = check; } else /* if (prerequisite_type < *check) */ n_prerequisites = i - 1; } while (n_prerequisites); } return FALSE;}static gchar*type_descriptive_name_I (GType type){ if (type) { TypeNode *node = lookup_type_node_I (type); return node ? NODE_NAME (node) : "<unknown>"; } else return "<invalid>";}/* --- type consistency checks --- */static gbooleancheck_plugin_U (GTypePlugin *plugin, gboolean need_complete_type_info, gboolean need_complete_interface_info, const gchar *type_name){ /* G_IS_TYPE_PLUGIN() and G_TYPE_PLUGIN_GET_CLASS() are external calls: _U */ if (!plugin) { g_warning ("plugin handle for type `%s' is NULL", type_name); return FALSE; } if (!G_IS_TYPE_PLUGIN (plugin)) { g_warning ("plugin pointer (%p) for type `%s' is invalid", plugin, type_name); return FALSE; } if (need_complete_type_info && !G_TYPE_PLUGIN_GET_CLASS (plugin)->complete_type_info) { g_warning ("plugin for type `%s' has no complete_type_info() implementation", type_name); return FALSE; } if (need_complete_interface_info && !G_TYPE_PLUGIN_GET_CLASS (plugin)->complete_interface_info) { g_warning ("plugin for type `%s' has no complete_interface_info() implementation", type_name); return FALSE; } return TRUE;}static gbooleancheck_type_name_I (const gchar *type_name){ static const gchar *extra_chars = "-_+"; const gchar *p = type_name; gboolean name_valid; if (!type_name[0] || !type_name[1] || !type_name[2]) { g_warning ("type name `%s' is too short", type_name); return FALSE; } /* check the first letter */ name_valid = (p[0] >= 'A' && p[0] <= 'Z') || (p[0] >= 'a' && p[0] <= 'z') || p[0] == '_'; for (p = type_name + 1; *p; p++) name_valid &= ((p[0] >= 'A' && p[0] <= 'Z') || (p[0] >= 'a' && p[0] <= 'z') || (p[0] >= '0' && p[0] <= '9') || strchr (extra_chars, p[0])); if (!name_valid) { g_warning ("type name `%s' contains invalid characters", type_name); return FALSE; } if (g_type_from_name (type_name)) { g_warning ("cannot register existing type `%s'", type_name); return FALSE; } return TRUE;}static gbooleancheck_derivation_I (GType parent_type, const gchar *type_name){ TypeNode *pnode; GTypeFundamentalInfo* finfo; pnode = lookup_type_node_I (parent_type); if (!pnode) { g_warning ("cannot derive type `%s' from invalid parent type `%s'", type_name, type_descriptive_name_I (parent_type)); return FALSE; } finfo = type_node_fundamental_info_I (pnode); /* ensure flat derivability */ if (!(finfo->type_flags & G_TYPE_FLAG_DERIVABLE)) { g_warning ("cannot derive `%s' from non-derivable parent type `%s'", type_name, NODE_NAME (pnode)); return FALSE; } /* ensure deep derivability */ if (parent_type != NODE_FUNDAMENTAL_TYPE (pnode) && !(finfo->type_flags & G_TYPE_FLAG_DEEP_DERIVABLE)) { g_warning ("cannot derive `%s' from non-fundamental parent type `%s'", type_name, NODE_NAME (pnode)); return FALSE; } return TRUE;}static gbooleancheck_collect_format_I (const gchar *collect_format){ const gchar *p = collect_format; gchar valid_format[] = { G_VALUE_COLLECT_INT, G_VALUE_COLLECT_LONG, G_VALUE_COLLECT_INT64, G_VALUE_COLLECT_DOUBLE, G_VALUE_COLLECT_POINTER, 0 }; while (*p) if (!strchr (valid_format, *p++)) return FALSE; return p - collect_format <= G_VALUE_COLLECT_FORMAT_MAX_LENGTH;}static gbooleancheck_value_table_I (const gchar *type_name, const GTypeValueTable *value_table){ if (!value_table) return FALSE; else if (value_table->value_init == NULL) { if (value_table->value_free || value_table->value_copy || value_table->value_peek_pointer || value_table->collect_format || value_table->collect_value || value_table->lcopy_format || value_table->lcopy_value) g_warning ("cannot handle uninitializable values of type `%s'", type_name); return FALSE; } else /* value_table->value_init != NULL */ { if (!value_table->value_free) { /* +++ optional +++ * g_warning ("missing `value_free()' for type `%s'", type_name); * return FALSE; */ } if (!value_table->value_copy) { g_warning ("missing `value_copy()' for type `%s'", type_name); return FALSE; } if ((value_table->collect_format || value_table->collect_value) && (!value_table->collect_format || !value_table->collect_value)) { g_warning ("one of `collect_format' and `collect_value()' is unspecified for type `%s'", type_name); return FALSE; } if (value_table->collect_format && !check_collect_format_I (value_table->collect_format)) { g_warning ("the `%s' specification for type `%s' is too long or invalid", "collect_format", type_name); return FALSE; } if ((value_table->lcopy_format || value_table->lcopy_value) && (!value_table->lcopy_format || !value_table->lcopy_value)) { g_warning ("one of `lcopy_format' and `lcopy_value()' is unspecified for type `%s'", type_name); return FALSE; } if (value_table->lcopy_format && !check_collect_format_I (value_table->lcopy_format)) { g_warning ("the `%s' specification for type `%s' is too long or invalid", "lcopy_format", type_name); return FALSE; } } return TRUE;}static gbooleancheck_type_info_I (TypeNode *pnode, GType ftype, const gchar *type_name, const GTypeInfo *info){ GTypeFundamentalInfo *finfo = type_node_fundamental_info_I (lookup_type_node_I (ftype)); gboolean is_interface = ftype == G_TYPE_INTERFACE; g_assert (ftype <= G_TYPE_FUNDAMENTAL_MAX && !(ftype & TYPE_ID_MASK)); /* check instance members */ if (!(finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) && (info->instance_size || info->n_preallocs || info->instance_init)) { if (pnode) g_warning ("cannot instantiate `%s', derived from non-instantiatable parent type `%s'", type_name, NODE_NAME (pnode)); else g_warning ("cannot instantiate `%s' as non-instantiatable fundamental", type_name); return FALSE; } /* check class & interface members */ if (!(finfo->type_flags & G_TYPE_FLAG_CLASSED) && (info->class_init || info->class_finalize || info->class_data || (!is_interface && (info->class_size || info->base_init || info->base_finalize)))) { if (pnode) g_warning ("cannot create class for `%s', derived from non-classed parent type `%s'", type_name, NODE_NAME (pnode)); else g_warning ("cannot create class for `%s' as non-classed fundamental", type_name); return FALSE; } /* check interface size */ if (is_interface && info->class_size < sizeof (GTypeInterface)) { g_warning ("specified interface size for type `%s' is smaller than `GTypeInterface' size", type_name); return FALSE; } /* check class size */ if (finfo->type_flags & G_TYPE_FLAG_CLASSED) { if (info->class_size < sizeof (GTypeClass)) { g_warning ("specified class size for type `%s' is smaller than `GTypeClass' size", type_name); return FALSE; } if (pnode && info->class_size < pnode->data->class.class_size) { g_warning ("specified class size for type `%s' is smaller " "than the parent type's `%s' class size", type_name, NODE_NAME (pnode)); return FALSE; } } /* check instance size */ if (finfo->type_flags & G_TYPE_FLAG_INSTANTIATABLE) { if (info->instance_size < sizeof (GTypeInstance)) { g_warning ("specified instance size for type `%s' is smaller than `GTypeInstance' size", type_name); return FALSE; } if (pnode && info->instance_size < pnode->data->instance.instance_size) { g_warning ("specified instance size for type `%s' is smaller " "than the parent type's `%s' instance size", type_name, NODE_NAME (pnode)); return FALSE; } } return TRUE;}static TypeNode*find_conforming_child_type_L (TypeNode *pnode, TypeNode *iface){ TypeNode *node = NULL; guint i; if (type_lookup_iface_entry_L (pnode, iface)) return pnode; for (i = 0; i < pnode->n_children && !node; i++) node = find_conforming_child_type_L (lookup_type_node_I (pnode->children[i]), iface); return node;}static gbooleancheck_add_interface_L (GType instance_type, GType iface_type){ TypeNode *node = lookup_type_node_I (instance_type); TypeNode *iface = lookup_type_node_I (iface_type); IFaceEntry *entry; TypeNode *tnode; GType *prerequisites; guint i; if (!node || !node->is_instantiatable) { g_warning ("cannot add interfaces to invalid (non-instantiatable) type `%s'", type_descriptive_name_I (instance_type)); return FALSE; } if (!iface || !NODE_IS_IFACE (iface)) { g_warning ("cannot add invalid (non-interface) type `%s' to type `%s'", type_descriptive_name_I (iface_type), NODE_NAME (node)); return FALSE; } tnode = lookup_type_node_I (NODE_PARENT_TYPE (iface)); if (NODE_PARENT_TYPE (tnode) && !type_lookup_iface_entry_L (node, tnode)) { /* 2001/7/31:timj: erk, i guess this warning is junk as interface derivation is flat */ g_warning ("cannot add sub-interface `%s' to type `%s' which does not conform to super-interface `%s'", NODE_NAME (iface), NODE_NAME (node), NODE_NAME (tnode)); return FALSE; } /* allow overriding of interface type introduced for parent type */ entry = type_lookup_iface_entry_L (node, iface); if (entry && entry->vtable == NULL && !type_iface_peek_holder_L (iface, NODE_TYPE (node))) { /* ok, we do conform to this interface already, but the interface vtable was not * yet intialized, and we just conform to the interface because it got added to * one of our parents. so we allow overriding of holder info here. */ return TRUE; } /* check whether one of our children already conforms (or whether the interface * got added to this node already) */ tnode = find_conforming_child_type_L (node, iface); /* tnode is_a node */ if (tnode) { g_warning ("cannot add interface type `%s' to type `%s', since type `%s' already conforms to interface", NODE_NAME (iface), NODE_NAME (node), NODE_NAME (tnode)); return FALSE; } prerequisites = IFACE_NODE_PREREQUISITES (iface); for (i = 0; i < IFACE_NODE_N_PREREQUISITES (iface); i++) { tnode = lookup_type_node_I (prerequisites[i]); if (!type_node_is_a_L (node, tnode)) { g_warning ("cannot add interface type `%s' to type `%s' which does not conform to prerequisite `%s'", NODE_NAME (iface), NODE_NAME (node), NODE_NAME (tnode)); return FALSE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -