Eobj: Ensure we don't allow calling super functions out of place.

And improved error reporting.

SVN revision: 70287
This commit is contained in:
Tom Hacohen 2012-04-18 07:58:34 +00:00
parent 6728cb8c5b
commit 25ab72e2ee
3 changed files with 55 additions and 19 deletions

View File

@ -20,6 +20,8 @@ _a_set(Eobj *obj, void *class_data __UNUSED__, va_list *list)
printf("%s %d\n", eobj_class_name_get(_my_class), a); printf("%s %d\n", eobj_class_name_get(_my_class), a);
eobj_do(obj, SIMPLE_A_PRINT()); eobj_do(obj, SIMPLE_A_PRINT());
eobj_do_super(obj, SIMPLE_A_SET(a + 1)); eobj_do_super(obj, SIMPLE_A_SET(a + 1));
fail_if(eobj_do_super(obj, SIMPLE_A_PRINT()));
} }
static void static void

View File

@ -35,6 +35,12 @@ main(int argc, char *argv[])
obj = eobj_add(SIMPLE_CLASS, NULL); obj = eobj_add(SIMPLE_CLASS, NULL);
fail_if(eobj_do(obj, INHERIT2_PRINT2())); fail_if(eobj_do(obj, INHERIT2_PRINT2()));
fail_if(eobj_do_super(obj, SIMPLE_A_PRINT()));
eobj_constructor_super(obj);
eobj_destructor_super(obj);
eobj_unref(obj); eobj_unref(obj);
eobj_shutdown(); eobj_shutdown();

View File

@ -190,6 +190,31 @@ dich_func_clean_all(Eobj_Class *klass)
/* END OF DICH */ /* END OF DICH */
static const Eobj_Op_Description noop_desc =
EOBJ_OP_DESCRIPTION(EOBJ_NOOP, "", "No operation.");
static const Eobj_Op_Description *
_eobj_op_id_desc_get(Eobj_Op op)
{
const Eobj_Class *klass = OP_CLASS_GET(op);
Eobj_Op sub_id = OP_SUB_ID_GET(op);
if (op == EOBJ_NOOP)
return &noop_desc;
if (klass && (sub_id < klass->desc->ops.count))
return klass->desc->ops.descs + sub_id;
return NULL;
}
static const char *
_eobj_op_id_name_get(Eobj_Op op)
{
const Eobj_Op_Description *desc = _eobj_op_id_desc_get(op);
return (desc) ? desc->name : NULL;
}
typedef struct typedef struct
{ {
EINA_INLIST; EINA_INLIST;
@ -245,10 +270,20 @@ _eobj_kls_itr_get(Eobj *obj)
} }
static inline const Eobj_Class * static inline const Eobj_Class *
_eobj_kls_itr_next(Eobj *obj) _eobj_kls_itr_next(Eobj *obj, Eobj_Op op)
{ {
Eobj_Kls_Itr_Node *node = Eobj_Kls_Itr_Node *node =
EINA_INLIST_CONTAINER_GET(obj->kls_itr, Eobj_Kls_Itr_Node); EINA_INLIST_CONTAINER_GET(obj->kls_itr, Eobj_Kls_Itr_Node);
if (!node || (node->op != op))
{
Eobj_Op node_op = (node) ? node->op : EOBJ_NOOP;
ERR("Called with op %d ('%s') while expecting: %d ('%s'). This probaly means you called eobj_*_super functions from a wrong place.",
op, _eobj_op_id_name_get(op),
node_op, _eobj_op_id_name_get(node_op));
return NULL;
}
const Eobj_Class **kls_itr = node->kls_itr; const Eobj_Class **kls_itr = node->kls_itr;
if (*kls_itr) if (*kls_itr)
{ {
@ -271,18 +306,6 @@ _eobj_kls_itr_reached_end(const Eobj *obj)
return !(*kls_itr && *(kls_itr + 1)); return !(*kls_itr && *(kls_itr + 1));
} }
static const Eobj_Op_Description *
_eobj_op_id_desc_get(Eobj_Op op)
{
const Eobj_Class *klass = OP_CLASS_GET(op);
Eobj_Op sub_id = OP_SUB_ID_GET(op);
if (klass && (sub_id < klass->desc->ops.count))
return klass->desc->ops.descs + sub_id;
return NULL;
}
static Eina_Bool static Eina_Bool
_eobj_op_internal(Eobj *obj, Eobj_Op op, va_list *p_list) _eobj_op_internal(Eobj *obj, Eobj_Op op, va_list *p_list)
{ {
@ -303,7 +326,7 @@ _eobj_op_internal(Eobj *obj, Eobj_Op op, va_list *p_list)
goto end; goto end;
} }
klass = _eobj_kls_itr_next(obj); klass = _eobj_kls_itr_next(obj, op);
} }
/* Try composite objects */ /* Try composite objects */
@ -373,10 +396,15 @@ eobj_do_super(Eobj *obj, Eobj_Op op, ...)
Eina_Bool ret = EINA_TRUE; Eina_Bool ret = EINA_TRUE;
va_list p_list; va_list p_list;
va_start(p_list, op);
/* Advance the kls itr. */ /* Advance the kls itr. */
obj_klass = _eobj_kls_itr_next(obj); obj_klass = _eobj_kls_itr_next(obj, op);
if (!obj_klass)
{
return EINA_FALSE;
}
va_start(p_list, op);
if (!_eobj_op_internal(obj, op, &p_list)) if (!_eobj_op_internal(obj, op, &p_list))
{ {
const Eobj_Op_Description *desc = _eobj_op_id_desc_get(op); const Eobj_Op_Description *desc = _eobj_op_id_desc_get(op);
@ -1006,13 +1034,13 @@ eobj_class_destructor(Eobj *obj, const Eobj_Class *klass)
EAPI void EAPI void
eobj_constructor_super(Eobj *obj) eobj_constructor_super(Eobj *obj)
{ {
eobj_class_constructor(obj, _eobj_kls_itr_next(obj)); eobj_class_constructor(obj, _eobj_kls_itr_next(obj, EOBJ_NOOP));
} }
EAPI void EAPI void
eobj_destructor_super(Eobj *obj) eobj_destructor_super(Eobj *obj)
{ {
eobj_class_destructor(obj, _eobj_kls_itr_next(obj)); eobj_class_destructor(obj, _eobj_kls_itr_next(obj, EOBJ_NOOP));
} }
EAPI void * EAPI void *