From 4e05a6193c839162e38b74563b72a1701ebaf480 Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Tue, 24 Apr 2012 08:04:14 +0000 Subject: [PATCH] Eobj: Added infrastructure for const functions and eobj_query. SVN revision: 70431 --- legacy/eobj/examples/access/inherit.c | 6 +- legacy/eobj/examples/composite_objects/comp.c | 6 +- legacy/eobj/examples/composite_objects/simple.c | 8 +- legacy/eobj/examples/constructors/mixin.c | 8 +- legacy/eobj/examples/constructors/simple.c | 12 +-- legacy/eobj/examples/evas/evas_obj.c | 6 +- legacy/eobj/examples/evas/evas_obj.h | 4 +- legacy/eobj/examples/function_overrides/simple.c | 8 +- legacy/eobj/examples/mixin/mixin.c | 8 +- legacy/eobj/examples/mixin/mixin2.c | 11 +-- legacy/eobj/examples/mixin/mixin3.c | 11 +-- legacy/eobj/examples/mixin/simple.c | 12 +-- legacy/eobj/lib/Eobj.h | 99 ++++++++++++++++++++++-- legacy/eobj/lib/eobj.c | 34 ++++++-- legacy/eobj/lib/eobj_base_class.c | 9 ++- legacy/eobj/tests/class_simple.c | 8 +- legacy/eobj/tests/eobj_test_class_errors.c | 60 ++++++++++++++ legacy/eobj/tests/eobj_test_general.c | 6 ++ 18 files changed, 243 insertions(+), 73 deletions(-) diff --git a/legacy/eobj/examples/access/inherit.c b/legacy/eobj/examples/access/inherit.c index 26860bc..b2fc51a 100644 --- a/legacy/eobj/examples/access/inherit.c +++ b/legacy/eobj/examples/access/inherit.c @@ -11,7 +11,7 @@ EAPI Eobj_Op INHERIT_BASE_ID = 0; #define MY_CLASS INHERIT_CLASS static void -_prot_print(Eobj *obj, void *class_data EINA_UNUSED, va_list *list) +_prot_print(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list) { Simple_Protected_Data *pd = eobj_data_get(obj, SIMPLE_CLASS); (void) list; @@ -22,7 +22,7 @@ static void _class_constructor(Eobj_Class *klass) { const Eobj_Op_Func_Description func_desc[] = { - EOBJ_OP_FUNC(INHERIT_ID(INHERIT_SUB_ID_PROT_PRINT), _prot_print), + EOBJ_OP_FUNC_CONST(INHERIT_ID(INHERIT_SUB_ID_PROT_PRINT), _prot_print), EOBJ_OP_FUNC_SENTINEL }; @@ -30,7 +30,7 @@ _class_constructor(Eobj_Class *klass) } static const Eobj_Op_Description op_desc[] = { - EOBJ_OP_DESCRIPTION(INHERIT_SUB_ID_PROT_PRINT, "", "Print protected var x1."), + EOBJ_OP_DESCRIPTION_CONST(INHERIT_SUB_ID_PROT_PRINT, "", "Print protected var x1."), EOBJ_OP_DESCRIPTION_SENTINEL }; diff --git a/legacy/eobj/examples/composite_objects/comp.c b/legacy/eobj/examples/composite_objects/comp.c index 0129a1e..d1239b8 100644 --- a/legacy/eobj/examples/composite_objects/comp.c +++ b/legacy/eobj/examples/composite_objects/comp.c @@ -11,11 +11,11 @@ EAPI Eobj_Op COMP_BASE_ID = 0; #define MY_CLASS COMP_CLASS static void -_a_get(Eobj *obj, void *class_data EINA_UNUSED, va_list *list) +_a_get(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list) { int *a; a = va_arg(*list, int *); - eobj_do_super(obj, SIMPLE_A_GET(a)); + eobj_query_super(obj, SIMPLE_A_GET(a)); } static void @@ -39,7 +39,7 @@ static void _class_constructor(Eobj_Class *klass) { const Eobj_Op_Func_Description func_desc[] = { - EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get), + EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get), EOBJ_OP_FUNC_SENTINEL }; diff --git a/legacy/eobj/examples/composite_objects/simple.c b/legacy/eobj/examples/composite_objects/simple.c index 446ff35..5687eb0 100644 --- a/legacy/eobj/examples/composite_objects/simple.c +++ b/legacy/eobj/examples/composite_objects/simple.c @@ -23,9 +23,9 @@ _a_set(Eobj *obj, void *class_data, va_list *list) } static void -_a_get(Eobj *obj EINA_UNUSED, void *class_data, va_list *list) +_a_get(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list) { - Simple_Public_Data *pd = class_data; + const Simple_Public_Data *pd = class_data; int *a; a = va_arg(*list, int *); *a = pd->a; @@ -36,7 +36,7 @@ _class_constructor(Eobj_Class *klass) { const Eobj_Op_Func_Description func_desc[] = { EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set), - EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get), + EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get), EOBJ_OP_FUNC_SENTINEL }; @@ -45,7 +45,7 @@ _class_constructor(Eobj_Class *klass) static const Eobj_Op_Description op_desc[] = { EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"), - EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "i", "Get property A"), + EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_GET, "i", "Get property A"), EOBJ_OP_DESCRIPTION_SENTINEL }; diff --git a/legacy/eobj/examples/constructors/mixin.c b/legacy/eobj/examples/constructors/mixin.c index 8ecfd65..3399537 100644 --- a/legacy/eobj/examples/constructors/mixin.c +++ b/legacy/eobj/examples/constructors/mixin.c @@ -9,10 +9,10 @@ EAPI Eobj_Op MIXIN_BASE_ID = 0; #define MY_CLASS MIXIN_CLASS static void -_add_and_print_set(Eobj *obj, void *class_data EINA_UNUSED, va_list *list) +_add_and_print_set(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list) { int a, b, x; - eobj_do(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b)); + eobj_query(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b)); x = va_arg(*list, const int); printf("%s %d\n", __func__, a + b + x); } @@ -39,7 +39,7 @@ static void _class_constructor(Eobj_Class *klass) { const Eobj_Op_Func_Description func_desc[] = { - EOBJ_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_ADD_AND_SET), _add_and_print_set), + EOBJ_OP_FUNC_CONST(MIXIN_ID(MIXIN_SUB_ID_ADD_AND_SET), _add_and_print_set), EOBJ_OP_FUNC_SENTINEL }; @@ -47,7 +47,7 @@ _class_constructor(Eobj_Class *klass) } static const Eobj_Op_Description op_desc[] = { - EOBJ_OP_DESCRIPTION(MIXIN_SUB_ID_ADD_AND_SET, "i", "Add A + B + param and print it"), + EOBJ_OP_DESCRIPTION_CONST(MIXIN_SUB_ID_ADD_AND_SET, "i", "Add A + B + param and print it"), EOBJ_OP_DESCRIPTION_SENTINEL }; diff --git a/legacy/eobj/examples/constructors/simple.c b/legacy/eobj/examples/constructors/simple.c index c127776..3f050c4 100644 --- a/legacy/eobj/examples/constructors/simple.c +++ b/legacy/eobj/examples/constructors/simple.c @@ -18,9 +18,9 @@ static char *class_var = NULL; #define _GET_SET_FUNC(name) \ static void \ -_##name##_get(Eobj *obj EINA_UNUSED, void *class_data, va_list *list) \ +_##name##_get(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list) \ { \ - Private_Data *pd = class_data; \ + const Private_Data *pd = class_data; \ int *name; \ name = va_arg(*list, int *); \ *name = pd->name; \ @@ -62,9 +62,9 @@ _class_constructor(Eobj_Class *klass) { const Eobj_Op_Func_Description func_desc[] = { EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set), - EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get), + EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get), EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_SET), _b_set), - EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get), + EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get), EOBJ_OP_FUNC_SENTINEL }; @@ -81,9 +81,9 @@ _class_destructor(Eobj_Class *klass EINA_UNUSED) static const Eobj_Op_Description op_desc[] = { EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"), - EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "i", "Get property A"), + EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_GET, "i", "Get property A"), EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_SET, "i", "Set property B"), - EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_GET, "i", "Get property B"), + EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_B_GET, "i", "Get property B"), EOBJ_OP_DESCRIPTION_SENTINEL }; diff --git a/legacy/eobj/examples/evas/evas_obj.c b/legacy/eobj/examples/evas/evas_obj.c index 4289804..a7cb3d8 100644 --- a/legacy/eobj/examples/evas/evas_obj.c +++ b/legacy/eobj/examples/evas/evas_obj.c @@ -47,7 +47,7 @@ _color_set(Eobj *obj, void *class_data EINA_UNUSED, va_list *list) } static void -_color_get(Eobj *obj, void *class_data EINA_UNUSED, va_list *list) +_color_get(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list) { Evas_Object *evas_obj = eobj_evas_object_get(obj); int *r, *g, *b, *a; @@ -109,7 +109,7 @@ _class_constructor(Eobj_Class *klass) EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_POSITION_SET), _position_set), EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_SIZE_SET), _size_set), EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_COLOR_SET), _color_set), - EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_COLOR_GET), _color_get), + EOBJ_OP_FUNC_CONST(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_COLOR_GET), _color_get), EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_VISIBILITY_SET), _visibility_set), EOBJ_OP_FUNC(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_CHILD_ADD), _child_add), EOBJ_OP_FUNC_SENTINEL @@ -122,7 +122,7 @@ static const Eobj_Op_Description op_desc[] = { EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_POSITION_SET, "ii", "Position of an evas object."), EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_SIZE_SET, "ii", "Size of an evas object."), EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_COLOR_SET, "iiii", "Color of an evas object."), - EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_COLOR_GET, "iiii", "Color of an evas object."), + EOBJ_OP_DESCRIPTION_CONST(EVAS_OBJ_SUB_ID_COLOR_GET, "iiii", "Color of an evas object."), EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_VISIBILITY_SET, "b", "Visibility of an evas object."), EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_CHILD_ADD, "o", "Add a child eobj."), EOBJ_OP_DESCRIPTION_SENTINEL diff --git a/legacy/eobj/examples/evas/evas_obj.h b/legacy/eobj/examples/evas/evas_obj.h index 28c50e4..67f7951 100644 --- a/legacy/eobj/examples/evas/evas_obj.h +++ b/legacy/eobj/examples/evas/evas_obj.h @@ -73,10 +73,10 @@ const Eobj_Class *evas_object_class_get(void) EINA_CONST; #define EVAS_OBJ_STR "Evas_Obj" /* FIXME: Hack in the meanwhile. */ static inline Evas_Object * -eobj_evas_object_get(Eobj *obj) +eobj_evas_object_get(const Eobj *obj) { void *data; - eobj_do(obj, EOBJ_BASE_DATA_GET(EVAS_OBJ_STR, &data)); + eobj_query(obj, EOBJ_BASE_DATA_GET(EVAS_OBJ_STR, &data)); return data; } diff --git a/legacy/eobj/examples/function_overrides/simple.c b/legacy/eobj/examples/function_overrides/simple.c index 1399c2c..adeabfb 100644 --- a/legacy/eobj/examples/function_overrides/simple.c +++ b/legacy/eobj/examples/function_overrides/simple.c @@ -18,9 +18,9 @@ _a_set(Eobj *obj EINA_UNUSED, void *class_data, va_list *list) } static void -_a_print(Eobj *obj EINA_UNUSED, void *class_data, va_list *list) +_a_print(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list) { - Simple_Public_Data *pd = class_data; + const Simple_Public_Data *pd = class_data; (void) list; printf("Print %s %d\n", eobj_class_name_get(MY_CLASS), pd->a); } @@ -30,7 +30,7 @@ _class_constructor(Eobj_Class *klass) { const Eobj_Op_Func_Description func_desc[] = { EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set), - EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print), + EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print), EOBJ_OP_FUNC_SENTINEL }; @@ -39,7 +39,7 @@ _class_constructor(Eobj_Class *klass) static const Eobj_Op_Description op_desc[] = { EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"), - EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"), + EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"), EOBJ_OP_DESCRIPTION_SENTINEL }; diff --git a/legacy/eobj/examples/mixin/mixin.c b/legacy/eobj/examples/mixin/mixin.c index 2938097..dae8284 100644 --- a/legacy/eobj/examples/mixin/mixin.c +++ b/legacy/eobj/examples/mixin/mixin.c @@ -9,10 +9,10 @@ EAPI Eobj_Op MIXIN_BASE_ID = 0; #define MY_CLASS MIXIN_CLASS static void -_ab_sum_get(Eobj *obj, void *class_data EINA_UNUSED, va_list *list) +_ab_sum_get(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list) { int a, b; - eobj_do(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b)); + eobj_query(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b)); int *sum = va_arg(*list, int *); if (sum) *sum = a + b; @@ -35,7 +35,7 @@ static void _class_constructor(Eobj_Class *klass) { const Eobj_Op_Func_Description func_desc[] = { - EOBJ_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get), + EOBJ_OP_FUNC_CONST(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get), EOBJ_OP_FUNC_SENTINEL }; @@ -44,7 +44,7 @@ _class_constructor(Eobj_Class *klass) static const Eobj_Op_Description op_desc[] = { - EOBJ_OP_DESCRIPTION(MIXIN_SUB_ID_AB_SUM_GET, "i", "Get the sum of a and b."), + EOBJ_OP_DESCRIPTION_CONST(MIXIN_SUB_ID_AB_SUM_GET, "i", "Get the sum of a and b."), EOBJ_OP_DESCRIPTION_SENTINEL }; diff --git a/legacy/eobj/examples/mixin/mixin2.c b/legacy/eobj/examples/mixin/mixin2.c index f663f69..bd638f4 100644 --- a/legacy/eobj/examples/mixin/mixin2.c +++ b/legacy/eobj/examples/mixin/mixin2.c @@ -10,19 +10,20 @@ #define MY_CLASS MIXIN2_CLASS static void -_ab_sum_get(Eobj *obj, void *class_data, va_list *list) +_ab_sum_get(const Eobj *obj, const void *class_data, va_list *list) { - Mixin2_Public_Data *pd = class_data; + /* This cast is a hack just for the tests... */ + Mixin2_Public_Data *pd = (Mixin2_Public_Data *) class_data; int *sum = va_arg(*list, int *); printf("%s %s\n", eobj_class_name_get(MY_CLASS), __func__); - eobj_do_super(obj, MIXIN_AB_SUM_GET(sum)); + eobj_query_super(obj, MIXIN_AB_SUM_GET(sum)); ++*sum; pd->count += 2; { int _a, _b; - eobj_do(obj, SIMPLE_A_GET(&_a), SIMPLE_B_GET(&_b)); + eobj_query(obj, SIMPLE_A_GET(&_a), SIMPLE_B_GET(&_b)); fail_if(*sum != _a + _b + 1); } } @@ -43,7 +44,7 @@ static void _class_constructor(Eobj_Class *klass) { const Eobj_Op_Func_Description func_desc[] = { - EOBJ_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get), + EOBJ_OP_FUNC_CONST(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get), EOBJ_OP_FUNC_SENTINEL }; diff --git a/legacy/eobj/examples/mixin/mixin3.c b/legacy/eobj/examples/mixin/mixin3.c index 4737828..349fe83 100644 --- a/legacy/eobj/examples/mixin/mixin3.c +++ b/legacy/eobj/examples/mixin/mixin3.c @@ -10,19 +10,20 @@ #define MY_CLASS MIXIN3_CLASS static void -_ab_sum_get(Eobj *obj, void *class_data EINA_UNUSED, va_list *list) +_ab_sum_get(const Eobj *obj, const void *class_data EINA_UNUSED, va_list *list) { - Mixin3_Public_Data *pd = class_data; + /* This cast is just a hack for the test. */ + Mixin3_Public_Data *pd = (Mixin3_Public_Data *) class_data; int *sum = va_arg(*list, int *); printf("%s %s\n", eobj_class_name_get(MY_CLASS), __func__); - eobj_do_super(obj, MIXIN_AB_SUM_GET(sum)); + eobj_query_super(obj, MIXIN_AB_SUM_GET(sum)); ++*sum; pd->count += 3; { int _a, _b; - eobj_do(obj, SIMPLE_A_GET(&_a), SIMPLE_B_GET(&_b)); + eobj_query(obj, SIMPLE_A_GET(&_a), SIMPLE_B_GET(&_b)); fail_if(*sum != _a + _b + 2); } } @@ -43,7 +44,7 @@ static void _class_constructor(Eobj_Class *klass) { const Eobj_Op_Func_Description func_desc[] = { - EOBJ_OP_FUNC(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get), + EOBJ_OP_FUNC_CONST(MIXIN_ID(MIXIN_SUB_ID_AB_SUM_GET), _ab_sum_get), EOBJ_OP_FUNC_SENTINEL }; diff --git a/legacy/eobj/examples/mixin/simple.c b/legacy/eobj/examples/mixin/simple.c index 2d9ca2b..f6c6232 100644 --- a/legacy/eobj/examples/mixin/simple.c +++ b/legacy/eobj/examples/mixin/simple.c @@ -18,9 +18,9 @@ typedef struct #define _GET_SET_FUNC(name) \ static void \ -_##name##_get(Eobj *obj EINA_UNUSED, void *class_data, va_list *list) \ +_##name##_get(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list) \ { \ - Private_Data *pd = class_data; \ + const Private_Data *pd = class_data; \ int *name; \ name = va_arg(*list, int *); \ *name = pd->name; \ @@ -44,9 +44,9 @@ _class_constructor(Eobj_Class *klass) { const Eobj_Op_Func_Description func_desc[] = { EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set), - EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get), + EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get), EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_SET), _b_set), - EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get), + EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get), EOBJ_OP_FUNC_SENTINEL }; @@ -55,9 +55,9 @@ _class_constructor(Eobj_Class *klass) static const Eobj_Op_Description op_desc[] = { EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"), - EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "i", "Get property A"), + EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_GET, "i", "Get property A"), EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_SET, "i", "Set property B"), - EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_GET, "i", "Get property B"), + EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_B_GET, "i", "Get property B"), EOBJ_OP_DESCRIPTION_SENTINEL }; diff --git a/legacy/eobj/lib/Eobj.h b/legacy/eobj/lib/Eobj.h index b149d89..68eb4bd 100644 --- a/legacy/eobj/lib/Eobj.h +++ b/legacy/eobj/lib/Eobj.h @@ -86,10 +86,22 @@ typedef unsigned int Eobj_Op; * @typedef eobj_op_func_type * The type of the Op functions. This is the type of the functions used by * Eobj. + * + * @see eobj_op_func_type_const */ typedef void (*eobj_op_func_type)(Eobj *, void *class_data, va_list *list); /** + * @typedef eobj_op_func_type_const + * The type of the const Op functions. This is the type of the functions used + * by Eobj. This is the same as #eobj_op_func_type, except that this should + * be used with functions that don't modify the data. + * + * @see eobj_op_func_type + */ +typedef void (*eobj_op_func_type_const)(const Eobj *, const void *class_data, va_list *list); + +/** * @addtogroup Eobj_Events Eobj's Event Handling * @{ */ @@ -207,6 +219,7 @@ struct _Eobj_Op_Func_Description { Eobj_Op op; /**< The op */ eobj_op_func_type func; /**< The function to call for the op. */ + Eina_Bool constant; /**< #EINA_TRUE if this function is a const. */ }; /** @@ -219,15 +232,27 @@ typedef struct _Eobj_Op_Func_Description Eobj_Op_Func_Description; * @def EOBJ_OP_FUNC(op, func) * A convenience macro to be used when populating the #Eobj_Op_Func_Description * array. + * + * @see EOBJ_OP_FUNC_CONST + */ +#define EOBJ_OP_FUNC(op, func) { op, EOBJ_TYPECHECK(eobj_op_func_type, func), EINA_FALSE } + +/** + * @def EOBJ_OP_FUNC_CONST(op, func) + * A convenience macro to be used when populating the #Eobj_Op_Func_Description + * array. + * The same as #EOBJ_OP_FUNC but for const functions. + * + * @see EOBJ_OP_FUNC */ -#define EOBJ_OP_FUNC(op, func) { op, func } +#define EOBJ_OP_FUNC_CONST(op, func) { op, (eobj_op_func_type) EOBJ_TYPECHECK(eobj_op_func_type_const, func), EINA_TRUE } /** * @def EOBJ_OP_FUNC_SENTINEL * A convenience macro to be used when populating the #Eobj_Op_Func_Description * array. It must appear at the end of the ARRAY. */ -#define EOBJ_OP_FUNC_SENTINEL { 0, NULL } +#define EOBJ_OP_FUNC_SENTINEL { 0, NULL, EINA_FALSE } /** * @struct _Eobj_Op_Description @@ -239,6 +264,7 @@ struct _Eobj_Op_Description const char *name; /**< The name of the op. */ const char *type; /**< descripbes the Op's function signature. */ const char *doc; /**< Explanation about the Op. */ + Eina_Bool constant; /**< #EINA_TRUE if this op's implementation should not change the obj. */ }; /** @@ -292,9 +318,25 @@ typedef struct _Eobj_Class_Description Eobj_Class_Description; * @param type The type string for the op. * @param doc Additional doc for the op. * @see Eobj_Op_Description + * @see EOBJ_OP_DESCRIPTION_CONST * @see EOBJ_OP_DESCRIPTION_SENTINEL */ -#define EOBJ_OP_DESCRIPTION(sub_id, type, doc) { sub_id, #sub_id, type, doc } +#define EOBJ_OP_DESCRIPTION(sub_id, type, doc) { sub_id, #sub_id, type, doc, EINA_FALSE } + +/** + * @def EOBJ_OP_DESCRIPTION_CONST(op, type, doc) + * An helper macro to help populating #Eobj_Op_Description + * This macro is the same as EOBJ_OP_DESCRIPTION but indicates that the op's + * implementation should not change the object. + * @param sub_id The sub id of the op being described. + * @param type The type string for the op. + * @param doc Additional doc for the op. + * @see Eobj_Op_Description + * @see EOBJ_OP_DESCRIPTION + * @see EOBJ_OP_DESCRIPTION_SENTINEL + */ +#define EOBJ_OP_DESCRIPTION_CONST(sub_id, type, doc) { sub_id, #sub_id, type, doc, EINA_TRUE } + /** * @def EOBJ_OP_DESCRIPTION_SENTINEL * An helper macro to help populating #Eobj_Op_Description @@ -302,7 +344,7 @@ typedef struct _Eobj_Class_Description Eobj_Class_Description; * @see Eobj_Op_Description * @see EOBJ_OP_DESCRIPTION */ -#define EOBJ_OP_DESCRIPTION_SENTINEL { 0, NULL, NULL, NULL } +#define EOBJ_OP_DESCRIPTION_SENTINEL { 0, NULL, NULL, NULL, EINA_FALSE } /** * @brief Create a new class. @@ -361,11 +403,19 @@ EAPI Eina_Bool eobj_shutdown(void); * A convenience wrapper around eobj_do_internal() * @see eobj_do_internal */ -#define eobj_do(object, ...) eobj_do_internal(object, __VA_ARGS__, (Eobj_Op) 0) +#define eobj_do(obj, ...) eobj_do_internal(obj, EINA_FALSE, __VA_ARGS__, EOBJ_NOOP) + +/** + * @def eobj_query + * Same as #eobj_do but only for const ops. + * @see eobj_do + */ +#define eobj_query(obj, ...) eobj_do_internal((Eobj *) EOBJ_TYPECHECK(const Eobj *, obj), EINA_TRUE, __VA_ARGS__, EOBJ_NOOP) /** * @brief Issues ops on an object. * @param obj The object to work on + * @param constant #EINA_TRUE if this call is on a constant object. * @param ... NULL terminated list of OPs and parameters. * @return #EINA_TRUE on success. * @@ -374,20 +424,53 @@ EAPI Eina_Bool eobj_shutdown(void); * * @see #eobj_do */ -EAPI Eina_Bool eobj_do_internal(Eobj *obj, ...); +EAPI Eina_Bool eobj_do_internal(Eobj *obj, Eina_Bool constant, ...); /** * @brief Calls the super function for the specific op. * @param obj The object to work on - * @param op The wanted op. * @param ... list of parameters. * @return #EINA_TRUE on success. * + * Unlike eobj_do() and eobj_query(), this function only accepts one op. + * * Use the helper macros, don't pass the parameters manually. * + * Same as eobj_do_super() just for const objects. + * + * @see #eobj_query + * @see eobj_do_super() + */ +#define eobj_query_super(obj, ...) eobj_do_super_internal((Eobj *) EOBJ_TYPECHECK(const Eobj *, obj), EINA_TRUE, __VA_ARGS__) + +/** + * @brief Calls the super function for the specific op. + * @param obj The object to work on + * @param ... list of parameters. + * @return #EINA_TRUE on success. + * + * Unlike eobj_do() and eobj_query(), this function only accepts one op. + * + * @see #eobj_query + * @see eobj_query_super() + */ +#define eobj_do_super(obj, ...) eobj_do_super_internal((Eobj *) EOBJ_TYPECHECK(const Eobj *, obj), EINA_FALSE, __VA_ARGS__) + +/** + * @brief Calls the super function for the specific op. + * @param obj The object to work on + * @param constant #EINA_TRUE if this call is on a constant object. + * @param op The wanted op. + * @param ... list of parameters. + * @return #EINA_TRUE on success. + * + * Don't use this function, use the wrapping macros instead. + * * @see #eobj_do + * @see #eobj_do_super + * @see #eobj_query_super */ -EAPI Eina_Bool eobj_do_super(Eobj *obj, Eobj_Op op, ...); +EAPI Eina_Bool eobj_do_super_internal(Eobj *obj, Eina_Bool constant, Eobj_Op op, ...); /** * @brief Gets the class of the object. diff --git a/legacy/eobj/lib/eobj.c b/legacy/eobj/lib/eobj.c index eb8f8d4..6580abb 100644 --- a/legacy/eobj/lib/eobj.c +++ b/legacy/eobj/lib/eobj.c @@ -345,12 +345,21 @@ _eobj_kls_itr_reached_end(const Eobj *obj) } static Eina_Bool -_eobj_op_internal(Eobj *obj, Eobj_Op op, va_list *p_list) +_eobj_op_internal(Eobj *obj, Eina_Bool constant, Eobj_Op op, va_list *p_list) { const Eobj_Class *klass; Eina_Bool ret = EINA_FALSE; Eina_Bool _itr_init; + const Eobj_Op_Description *op_desc = _eobj_op_id_desc_get(op); + + if (op_desc && + ((constant == EINA_TRUE) && (op_desc->constant == EINA_FALSE))) + { + ERR("Tried calling non-const or non-existant op '%s' (%d) from a const (query) function.", (op_desc) ? op_desc->name : NULL, op); + return EINA_FALSE; + } + _itr_init = _eobj_kls_itr_init(obj, op); klass = _eobj_kls_itr_get(obj); while (klass) @@ -373,7 +382,7 @@ _eobj_op_internal(Eobj *obj, Eobj_Op op, va_list *p_list) Eobj *emb_obj; EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj) { - if (_eobj_op_internal(emb_obj, op, p_list)) + if (_eobj_op_internal(emb_obj, constant, op, p_list)) { ret = EINA_TRUE; goto end; @@ -388,7 +397,7 @@ end: } EAPI Eina_Bool -eobj_do_internal(Eobj *obj, ...) +eobj_do_internal(Eobj *obj, Eina_Bool constant, ...) { Eina_Bool ret = EINA_TRUE; Eobj_Op op = EOBJ_NOOP; @@ -398,12 +407,12 @@ eobj_do_internal(Eobj *obj, ...) eobj_ref(obj); - va_start(p_list, obj); + va_start(p_list, constant); op = va_arg(p_list, Eobj_Op); while (op) { - if (!_eobj_op_internal(obj, op, &p_list)) + if (!_eobj_op_internal(obj, constant, op, &p_list)) { const Eobj_Class *op_klass = OP_CLASS_GET(op); const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL; @@ -423,7 +432,7 @@ eobj_do_internal(Eobj *obj, ...) } EAPI Eina_Bool -eobj_do_super(Eobj *obj, Eobj_Op op, ...) +eobj_do_super_internal(Eobj *obj, Eina_Bool constant, Eobj_Op op, ...) { const Eobj_Class *obj_klass; Eina_Bool ret = EINA_TRUE; @@ -439,7 +448,7 @@ eobj_do_super(Eobj *obj, Eobj_Op op, ...) } va_start(p_list, op); - if (!_eobj_op_internal(obj, op, &p_list)) + if (!_eobj_op_internal(obj, constant, op, &p_list)) { const Eobj_Class *op_klass = OP_CLASS_GET(op); const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL; @@ -616,7 +625,16 @@ eobj_class_funcs_set(Eobj_Class *klass, const Eobj_Op_Func_Description *func_des { for ( ; itr->op != 0 ; itr++) { - dich_func_set(klass, itr->op, itr->func); + const Eobj_Op_Description *op_desc = _eobj_op_id_desc_get(itr->op); + + if (EINA_LIKELY(!op_desc || (itr->constant == op_desc->constant))) + { + dich_func_set(klass, itr->op, itr->func); + } + else + { + ERR("Set function's constant property (%d) is different than the one in the op description (%d) for op '%s' in class '%s'.", itr->constant, op_desc->constant, op_desc->name, klass->desc->name); + } } } } diff --git a/legacy/eobj/lib/eobj_base_class.c b/legacy/eobj/lib/eobj_base_class.c index a48265c..abdf523 100644 --- a/legacy/eobj/lib/eobj_base_class.c +++ b/legacy/eobj/lib/eobj_base_class.c @@ -67,9 +67,10 @@ _data_set(Eobj *obj, void *class_data, va_list *list) } static void -_data_get(Eobj *obj EINA_UNUSED, void *class_data, va_list *list) +_data_get(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list) { - Private_Data *pd = class_data; + /* We don't really change it... */ + Private_Data *pd = (Private_Data *) class_data; const char *key = va_arg(*list, const char *); void **data = va_arg(*list, void **); Eobj_Generic_Data_Node *node; @@ -145,7 +146,7 @@ _class_constructor(Eobj_Class *klass) { const Eobj_Op_Func_Description func_desc[] = { EOBJ_OP_FUNC(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_SET), _data_set), - EOBJ_OP_FUNC(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_GET), _data_get), + EOBJ_OP_FUNC_CONST(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_GET), _data_get), EOBJ_OP_FUNC(EOBJ_BASE_ID(EOBJ_BASE_SUB_ID_DATA_DEL), _data_del), EOBJ_OP_FUNC_SENTINEL }; @@ -155,7 +156,7 @@ _class_constructor(Eobj_Class *klass) static const Eobj_Op_Description op_desc[] = { EOBJ_OP_DESCRIPTION(EOBJ_BASE_SUB_ID_DATA_SET, "?", "Set data for key."), - EOBJ_OP_DESCRIPTION(EOBJ_BASE_SUB_ID_DATA_GET, "?", "Get data for key."), + EOBJ_OP_DESCRIPTION_CONST(EOBJ_BASE_SUB_ID_DATA_GET, "?", "Get data for key."), EOBJ_OP_DESCRIPTION(EOBJ_BASE_SUB_ID_DATA_DEL, "?", "Del key."), EOBJ_OP_DESCRIPTION_SENTINEL }; diff --git a/legacy/eobj/tests/class_simple.c b/legacy/eobj/tests/class_simple.c index 3b90760..aba52ff 100644 --- a/legacy/eobj/tests/class_simple.c +++ b/legacy/eobj/tests/class_simple.c @@ -18,9 +18,9 @@ _a_set(Eobj *obj EINA_UNUSED, void *class_data, va_list *list) } static void -_a_print(Eobj *obj EINA_UNUSED, void *class_data, va_list *list) +_a_print(const Eobj *obj EINA_UNUSED, const void *class_data, va_list *list) { - Simple_Public_Data *pd = class_data; + const Simple_Public_Data *pd = class_data; (void) list; printf("Print %s %d\n", eobj_class_name_get(MY_CLASS), pd->a); } @@ -30,7 +30,7 @@ _class_constructor(Eobj_Class *klass) { const Eobj_Op_Func_Description func_desc[] = { EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set), - EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print), + EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _a_print), EOBJ_OP_FUNC_SENTINEL }; @@ -39,7 +39,7 @@ _class_constructor(Eobj_Class *klass) static const Eobj_Op_Description op_desc[] = { EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"), - EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"), + EOBJ_OP_DESCRIPTION_CONST(SIMPLE_SUB_ID_A_PRINT, "", "Print property A"), EOBJ_OP_DESCRIPTION_SENTINEL }; diff --git a/legacy/eobj/tests/eobj_test_class_errors.c b/legacy/eobj/tests/eobj_test_class_errors.c index 5637905..b7bfbfd 100644 --- a/legacy/eobj/tests/eobj_test_class_errors.c +++ b/legacy/eobj/tests/eobj_test_class_errors.c @@ -293,10 +293,70 @@ START_TEST(eobj_bad_interface) } END_TEST +static int _const_ops_counter = 0; + +static void +_const_ops_a_set(const Eobj *obj EINA_UNUSED, const void *class_data EINA_UNUSED, va_list *list) +{ + int a = va_arg(*list, int); + (void) a; + _const_ops_counter++; +} + +static void +_const_ops_a_print(Eobj *obj EINA_UNUSED, void *class_data EINA_UNUSED, va_list *list EINA_UNUSED) +{ + _const_ops_counter++; +} + +static void +_const_ops_class_constructor(Eobj_Class *klass) +{ + const Eobj_Op_Func_Description func_desc[] = { + EOBJ_OP_FUNC_CONST(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _const_ops_a_set), + EOBJ_OP_FUNC(SIMPLE_ID(SIMPLE_SUB_ID_A_PRINT), _const_ops_a_print), + EOBJ_OP_FUNC_SENTINEL + }; + + eobj_class_funcs_set(klass, func_desc); +} + +START_TEST(eobj_const_ops) +{ + eobj_init(); + + const Eobj_Class *klass; + + static Eobj_Class_Description class_desc = { + "Simple", + EOBJ_CLASS_TYPE_REGULAR, + EOBJ_CLASS_DESCRIPTION_OPS(NULL, NULL, 0), + NULL, + 0, + NULL, + NULL, + _const_ops_class_constructor, + NULL + }; + + klass = eobj_class_new(&class_desc, SIMPLE_CLASS, NULL); + fail_if(!klass); + + Eobj *obj = eobj_add(klass, NULL); + eobj_do(obj, SIMPLE_A_SET(7), SIMPLE_A_PRINT()); + fail_if(_const_ops_counter != 0); + + eobj_unref(obj); + + eobj_shutdown(); +} +END_TEST + void eobj_test_class_errors(TCase *tc) { tcase_add_test(tc, eobj_incomplete_desc); tcase_add_test(tc, eobj_inherit_errors); tcase_add_test(tc, eobj_inconsistent_mro); tcase_add_test(tc, eobj_bad_interface); + tcase_add_test(tc, eobj_const_ops); } diff --git a/legacy/eobj/tests/eobj_test_general.c b/legacy/eobj/tests/eobj_test_general.c index d3aed07..cf43e4c 100644 --- a/legacy/eobj/tests/eobj_test_general.c +++ b/legacy/eobj/tests/eobj_test_general.c @@ -165,6 +165,12 @@ START_TEST(eobj_op_errors) fail_if(eobj_ref_get(obj) != 1); eobj_unref(obj); + + obj = eobj_add(SIMPLE_CLASS, NULL); + fail_if(!eobj_do(obj, SIMPLE_A_PRINT())); + fail_if(!eobj_query(obj, SIMPLE_A_PRINT())); + fail_if(eobj_query(obj, SIMPLE_A_SET(1))); + eobj_shutdown(); } END_TEST -- 2.7.4