applied patch from Matthias Clasen <maclas@gmx.de> to check for

Tue Mar 19 18:57:12 2002  Tim Janik  <timj@gtk.org>

        * gtype.c (check_add_interface_L): applied patch from Matthias Clasen
        <maclas@gmx.de> to check for prerequisite of interfaces, fixes #74427.
        fixed mutex recursion in his patch (we can't call g_type_is_a() while
        holding a read lock).

        * gparam.c (canonalize_key): cleanup.
This commit is contained in:
Tim Janik 2002-03-19 19:26:27 +00:00 committed by Tim Janik
parent c938a77376
commit 3f4617caab
3 changed files with 67 additions and 19 deletions

View File

@ -1,3 +1,12 @@
Tue Mar 19 18:57:12 2002 Tim Janik <timj@gtk.org>
* gtype.c (check_add_interface_L): applied patch from Matthias Clasen
<maclas@gmx.de> to check for prerequisite of interfaces, fixes #74427.
fixed mutex recursion in his patch (we can't call g_type_is_a() while
holding a read lock).
* gparam.c (canonalize_key): cleanup.
2002-03-13 Alexander Larsson <alla@lysator.liu.se> 2002-03-13 Alexander Larsson <alla@lysator.liu.se>
* gparam.c (canonalize_key): * gparam.c (canonalize_key):

View File

@ -258,12 +258,14 @@ g_param_spec_get_blurb (GParamSpec *pspec)
} }
static void static void
canonalize_key(gchar *key) canonalize_key (gchar *key)
{ {
gchar *p, c; gchar *p;
for (p = key; (c = *p) != 0; p++) for (p = key; *p != 0; p++)
{ {
gchar c = *p;
if (c != '-' && if (c != '-' &&
(c < '0' || c > '9') && (c < '0' || c > '9') &&
(c < 'A' || c > 'Z') && (c < 'A' || c > 'Z') &&
@ -280,18 +282,18 @@ g_param_spec_internal (GType param_type,
GParamFlags flags) GParamFlags flags)
{ {
GParamSpec *pspec; GParamSpec *pspec;
g_return_val_if_fail (G_TYPE_IS_PARAM (param_type) && param_type != G_TYPE_PARAM, NULL); g_return_val_if_fail (G_TYPE_IS_PARAM (param_type) && param_type != G_TYPE_PARAM, NULL);
g_return_val_if_fail (name != NULL, NULL); g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail ((name[0] >= 'A' && name[0] <= 'Z') || (name[0] >= 'a' && name[0] <= 'z'), NULL); g_return_val_if_fail ((name[0] >= 'A' && name[0] <= 'Z') || (name[0] >= 'a' && name[0] <= 'z'), NULL);
pspec = (gpointer) g_type_create_instance (param_type); pspec = (gpointer) g_type_create_instance (param_type);
pspec->name = g_strdup (name); pspec->name = g_strdup (name);
canonalize_key (pspec->name); canonalize_key (pspec->name);
pspec->_nick = g_strdup (nick); pspec->_nick = g_strdup (nick);
pspec->_blurb = g_strdup (blurb); pspec->_blurb = g_strdup (blurb);
pspec->flags = (flags & G_PARAM_USER_MASK) | (flags & G_PARAM_MASK); pspec->flags = (flags & G_PARAM_USER_MASK) | (flags & G_PARAM_MASK);
return pspec; return pspec;
} }

View File

@ -137,6 +137,8 @@ static inline void type_set_qdata_W (TypeNode *node,
gpointer data); gpointer data);
static IFaceHolder* type_iface_peek_holder_L (TypeNode *iface, static IFaceHolder* type_iface_peek_holder_L (TypeNode *iface,
GType instance_type); GType instance_type);
static gboolean type_node_is_a_L (TypeNode *node,
TypeNode *iface_node);
/* --- structures --- */ /* --- structures --- */
@ -776,6 +778,9 @@ check_add_interface_L (GType instance_type,
TypeNode *iface = lookup_type_node_I (iface_type); TypeNode *iface = lookup_type_node_I (iface_type);
IFaceEntry *entry; IFaceEntry *entry;
TypeNode *tnode; TypeNode *tnode;
GType *prerequisites;
guint i;
if (!node || !node->is_instantiatable) if (!node || !node->is_instantiatable)
{ {
@ -822,6 +827,19 @@ check_add_interface_L (GType instance_type,
NODE_NAME (tnode)); NODE_NAME (tnode));
return FALSE; 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;
}
}
return TRUE; return TRUE;
} }
@ -2180,11 +2198,12 @@ g_type_next_base (GType type,
} }
static inline gboolean static inline gboolean
type_node_is_a_U (TypeNode *node, type_node_check_conformities_UorL (TypeNode *node,
TypeNode *iface_node, TypeNode *iface_node,
/* support_inheritance */ /* support_inheritance */
gboolean support_interfaces, gboolean support_interfaces,
gboolean support_prerequisites) gboolean support_prerequisites,
gboolean have_lock)
{ {
gboolean match; gboolean match;
@ -2198,16 +2217,34 @@ type_node_is_a_U (TypeNode *node,
match = FALSE; match = FALSE;
if (support_interfaces || support_prerequisites) if (support_interfaces || support_prerequisites)
{ {
G_READ_LOCK (&type_rw_lock); if (!have_lock)
G_READ_LOCK (&type_rw_lock);
if (support_interfaces && type_lookup_iface_entry_L (node, iface_node)) if (support_interfaces && type_lookup_iface_entry_L (node, iface_node))
match = TRUE; match = TRUE;
else if (support_prerequisites && type_lookup_prerequisite_L (node, NODE_TYPE (iface_node))) else if (support_prerequisites && type_lookup_prerequisite_L (node, NODE_TYPE (iface_node)))
match = TRUE; match = TRUE;
G_READ_UNLOCK (&type_rw_lock); if (!have_lock)
G_READ_UNLOCK (&type_rw_lock);
} }
return match; return match;
} }
static gboolean
type_node_is_a_L (TypeNode *node,
TypeNode *iface_node)
{
return type_node_check_conformities_UorL (node, iface_node, TRUE, TRUE, TRUE);
}
static inline gboolean
type_node_conforms_to_U (TypeNode *node,
TypeNode *iface_node,
gboolean support_interfaces,
gboolean support_prerequisites)
{
return type_node_check_conformities_UorL (node, iface_node, support_interfaces, support_prerequisites, FALSE);
}
gboolean gboolean
g_type_is_a (GType type, g_type_is_a (GType type,
GType iface_type) GType iface_type)
@ -2217,7 +2254,7 @@ g_type_is_a (GType type,
node = lookup_type_node_I (type); node = lookup_type_node_I (type);
iface_node = lookup_type_node_I (iface_type); iface_node = lookup_type_node_I (iface_type);
is_a = node && iface_node && type_node_is_a_U (node, iface_node, TRUE, TRUE); is_a = node && iface_node && type_node_conforms_to_U (node, iface_node, TRUE, TRUE);
return is_a; return is_a;
} }
@ -2567,7 +2604,7 @@ g_type_check_instance_is_a (GTypeInstance *type_instance,
node = lookup_type_node_I (type_instance->g_class->g_type); node = lookup_type_node_I (type_instance->g_class->g_type);
iface = lookup_type_node_I (iface_type); iface = lookup_type_node_I (iface_type);
check = node && node->is_instantiatable && iface && type_node_is_a_U (node, iface, TRUE, FALSE); check = node && node->is_instantiatable && iface && type_node_conforms_to_U (node, iface, TRUE, FALSE);
return check; return check;
} }
@ -2584,7 +2621,7 @@ g_type_check_class_is_a (GTypeClass *type_class,
node = lookup_type_node_I (type_class->g_type); node = lookup_type_node_I (type_class->g_type);
iface = lookup_type_node_I (is_a_type); iface = lookup_type_node_I (is_a_type);
check = node && node->is_classed && iface && type_node_is_a_U (node, iface, FALSE, FALSE); check = node && node->is_classed && iface && type_node_conforms_to_U (node, iface, FALSE, FALSE);
return check; return check;
} }
@ -2603,7 +2640,7 @@ g_type_check_instance_cast (GTypeInstance *type_instance,
node = lookup_type_node_I (type_instance->g_class->g_type); node = lookup_type_node_I (type_instance->g_class->g_type);
is_instantiatable = node && node->is_instantiatable; is_instantiatable = node && node->is_instantiatable;
iface = lookup_type_node_I (iface_type); iface = lookup_type_node_I (iface_type);
check = is_instantiatable && iface && type_node_is_a_U (node, iface, TRUE, FALSE); check = is_instantiatable && iface && type_node_conforms_to_U (node, iface, TRUE, FALSE);
if (check) if (check)
return type_instance; return type_instance;
@ -2639,7 +2676,7 @@ g_type_check_class_cast (GTypeClass *type_class,
node = lookup_type_node_I (type_class->g_type); node = lookup_type_node_I (type_class->g_type);
is_classed = node && node->is_classed; is_classed = node && node->is_classed;
iface = lookup_type_node_I (is_a_type); iface = lookup_type_node_I (is_a_type);
check = is_classed && iface && type_node_is_a_U (node, iface, FALSE, FALSE); check = is_classed && iface && type_node_conforms_to_U (node, iface, FALSE, FALSE);
if (check) if (check)
return type_class; return type_class;