From a791d97bfcc7ae66f63e9fa694292bd7a0fc3610 Mon Sep 17 00:00:00 2001 From: Tom Hacohen Date: Mon, 23 Feb 2015 16:06:40 +0000 Subject: [PATCH] Eo: Remove GCCism and make it more portable. This affects eo_do() and eo_add() that used to use the ({}) GCCism. Following a discussion with Peter de Ridder after my talk at FOSDEM, we've decided to reopen the GCCism (works with other gcc compatible compilers like clang and intelc) discussion, and after a bit of back and forth it was decided to make things more portable, at the cost of ease of use. For example: if (eo_do(obj, visible_get())) is no longer allowed, the portable alternative Eina_Bool tmp; if (eo_do_ret(obj, tmp, visible_get())) is to be used instead. However: eo_do(obj, a = a_get(), b = b_get(), bool_set(!bool_get)) are still allowed and OK. eo_do(obj, if (a_get()) return;); is no longer allowed, but: eo_do(obj, if (a_get()) something()); is still allowed. For clarity, this commit only incorporates the Eo changes, and not the EFL changes to make the efl conform with this change. Thanks again to Peter de Ridder for triggering this important discussion which led to this change. --- src/lib/eo/Eo.h | 55 +++++++++---------- src/lib/eo/eo.c | 20 +++++-- src/lib/eo/eo_base_class.c | 3 +- .../composite_objects_comp.c | 5 +- .../composite_objects_main.c | 17 +++--- .../eo/constructors/constructors_simple.c | 5 +- src/tests/eo/suite/eo_test_general.c | 5 +- 7 files changed, 64 insertions(+), 46 deletions(-) diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h index 037b33faa4..3d302dce4e 100644 --- a/src/lib/eo/Eo.h +++ b/src/lib/eo/Eo.h @@ -576,24 +576,35 @@ EAPI Eina_Bool _eo_call_resolve(const char *func_name, const Eo_Op op, Eo_Op_Cal EAPI Eina_Bool _eo_do_start(const Eo *obj, const Eo_Class *cur_klass, Eina_Bool is_super, const char *file, const char *func, int line); // end of the eo_do barrier, unref the obj, move the stack pointer -EAPI void _eo_do_end(const Eo **ojb); +EAPI void _eo_do_end(void); -#define EO_DO_CLEANUP __attribute__((cleanup(_eo_do_end))) +// end of the eo_add. Calls finalize among others +EAPI Eo * _eo_add_end(void); // eo object method calls batch, #define _eo_do_common(eoid, clsid, is_super, ...) \ - ({ \ - const Eo *_eoid_ EO_DO_CLEANUP = eoid; \ - _eo_do_start(_eoid_, clsid, is_super, __FILE__, __FUNCTION__, __LINE__); \ + do { \ + _eo_do_start(eoid, clsid, is_super, __FILE__, __FUNCTION__, __LINE__); \ __VA_ARGS__; \ - }) + _eo_do_end(); \ + } while (0) + +#define _eo_do_common_ret(eoid, clsid, is_super, ret_tmp, func) \ + ( \ + _eo_do_start(eoid, clsid, is_super, __FILE__, __FUNCTION__, __LINE__), \ + ret_tmp = func, \ + _eo_do_end(), \ + ret_tmp \ + ) #define eo_do(eoid, ...) _eo_do_common(eoid, NULL, EINA_FALSE, __VA_ARGS__) #define eo_do_super(eoid, clsid, func) _eo_do_common(eoid, clsid, EINA_TRUE, func) +#define eo_do_ret(eoid, ret_tmp, func) _eo_do_common_ret(eoid, NULL, EINA_FALSE, ret_tmp, func) + /*****************************************************************************/ /** @@ -618,6 +629,14 @@ EAPI const Eo_Class *eo_class_get(const Eo *obj); EAPI void eo_error_set_internal(const Eo *obj, const char *file, int line); /* @endcond */ +#define _eo_add_common(klass, parent, is_ref, ...) \ + ( \ + _eo_do_start(_eo_add_internal_start(__FILE__, __LINE__, klass, parent, is_ref), \ + klass, EINA_FALSE, __FILE__, __FUNCTION__, __LINE__), \ + eo_constructor(), ##__VA_ARGS__, \ + (Eo *) _eo_add_end() \ + ) + /** * @def eo_add * @brief Create a new object with the default constructor. @@ -633,17 +652,7 @@ EAPI void eo_error_set_internal(const Eo *obj, const char *file, int line); * @param ... The ops to run. * @return An handle to the new object on success, NULL otherwise. */ -#define eo_add(klass, parent, ...) \ - ({ \ - const Eo_Class *_tmp_klass = klass; \ - Eo *_tmp_obj = _eo_add_internal_start(__FILE__, __LINE__, _tmp_klass, parent, EINA_FALSE); \ - eo_do(_tmp_obj, \ - eo_constructor(); \ - __VA_ARGS__; \ - _tmp_obj = eo_finalize(); \ - ); \ - _tmp_obj; \ - }) +#define eo_add(klass, parent, ...) _eo_add_common(klass, parent, EINA_FALSE, ##__VA_ARGS__) /** * @def eo_add_ref @@ -657,17 +666,7 @@ EAPI void eo_error_set_internal(const Eo *obj, const char *file, int line); * @param ... The ops to run. * @return An handle to the new object on success, NULL otherwise. */ -#define eo_add_ref(klass, parent, ...) \ - ({ \ - const Eo_Class *_tmp_klass = klass; \ - Eo *_tmp_obj = _eo_add_internal_start(__FILE__, __LINE__, _tmp_klass, parent, EINA_TRUE); \ - eo_do(_tmp_obj, \ - eo_constructor(); \ - __VA_ARGS__; \ - _tmp_obj = eo_finalize(); \ - ); \ - _tmp_obj; \ - }) +#define eo_add_ref(klass, parent, ...) _eo_add_common(klass, parent, EINA_TRUE, ##__VA_ARGS__) EAPI Eo * _eo_add_internal_start(const char *file, int line, const Eo_Class *klass_id, Eo *parent, Eina_Bool ref); diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index a0adecd318..166e6385bf 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -533,7 +533,7 @@ _eo_do_start(const Eo *eo_id, const Eo_Class *cur_klass_id, Eina_Bool is_super, } EAPI void -_eo_do_end(const Eo **eo_id EINA_UNUSED) +_eo_do_end(void) { Eo_Stack_Frame *fptr; Eo_Call_Stack *stack = _eo_call_stack_get(eina_main_loop_is()); // Is it possible to extract information from the scope ? @@ -910,9 +910,12 @@ _eo_add_internal_start(const char *file, int line, const Eo_Class *klass_id, Eo /* If there's a parent. Unref. Eo_add should return an object with either a * parent ref, or with the lack of, just a ref. */ - if (!ref && eo_do(eo_id, eo_parent_get())) { - _eo_unref(obj); + Eo *parent_tmp; + if (!ref && eo_do_ret(eo_id, parent_tmp, eo_parent_get())) + { + _eo_unref(obj); + } } return eo_id; @@ -957,6 +960,14 @@ _eo_add_internal_end(Eo *eo_id) return (Eo *)eo_id; } +EAPI Eo * +_eo_add_end(void) +{ + Eo *ret = eo_finalize(); + _eo_do_end(); + return ret; +} + /*****************************************************************************/ #define _EO_OP_ERR_NO_OP_PRINT(file, line, op, klass) \ @@ -1544,7 +1555,8 @@ eo_unref(const Eo *obj_id) EAPI void eo_del(const Eo *obj) { - if (eo_do(obj, eo_parent_get())) + Eo *parent_tmp; + if (eo_do_ret(obj, parent_tmp, eo_parent_get())) { eo_do(obj, eo_parent_set(NULL)); } diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c index 8b7f1d01f4..d088d76736 100644 --- a/src/lib/eo/eo_base_class.c +++ b/src/lib/eo/eo_base_class.c @@ -101,10 +101,11 @@ _eo_base_key_data_get(Eo *obj EINA_UNUSED, Eo_Base_Data *pd, const char *key) EOLIAN static void _eo_base_parent_set(Eo *obj, Eo_Base_Data *pd, Eo *parent_id) { + Eina_Bool tmp; if (pd->parent == parent_id) return; - if (eo_do(obj, eo_composite_part_is()) && pd->parent) + if (eo_do_ret(obj, tmp, eo_composite_part_is()) && pd->parent) { eo_do(pd->parent, eo_composite_detach(obj)); } diff --git a/src/tests/eo/composite_objects/composite_objects_comp.c b/src/tests/eo/composite_objects/composite_objects_comp.c index d08d492b8f..d11b806167 100644 --- a/src/tests/eo/composite_objects/composite_objects_comp.c +++ b/src/tests/eo/composite_objects/composite_objects_comp.c @@ -22,14 +22,15 @@ _a_get(Eo *obj, void *class_data EINA_UNUSED) static void _constructor(Eo *obj, void *class_data EINA_UNUSED) { + Eina_Bool tmp; eo_do_super(obj, MY_CLASS, eo_constructor()); Eo *simple = eo_add(SIMPLE_CLASS, obj); eo_do(obj, eo_composite_attach(simple)); eo_do(simple, eo_event_callback_forwarder_add(EV_A_CHANGED, obj)); - fail_if(eo_do(obj, eo_composite_part_is())); - fail_if(!eo_do(simple, eo_composite_part_is())); + fail_if(eo_do_ret(obj, tmp, eo_composite_part_is())); + fail_if(!eo_do_ret(simple, tmp, eo_composite_part_is())); eo_do(obj, eo_key_data_set("simple-obj", simple, NULL)); } diff --git a/src/tests/eo/composite_objects/composite_objects_main.c b/src/tests/eo/composite_objects/composite_objects_main.c index 5967122b97..0db210ac45 100644 --- a/src/tests/eo/composite_objects/composite_objects_main.c +++ b/src/tests/eo/composite_objects/composite_objects_main.c @@ -26,6 +26,7 @@ _a_changed_cb(void *data, Eo *obj, const Eo_Event_Description *desc, void *event int main(int argc, char *argv[]) { + Eina_Bool tmp; (void) argc; (void) argv; eo_init(); @@ -65,15 +66,15 @@ main(int argc, char *argv[]) eo_do(obj, simple_a_set(2)); fail_if(cb_called); - fail_if(!eo_do(simple, eo_composite_part_is())); - fail_if(!eo_do(obj, eo_composite_detach(simple))); - fail_if(eo_do(obj, eo_composite_detach(simple))); - fail_if(eo_do(simple, eo_composite_part_is())); - fail_if(!eo_do(obj, eo_composite_attach(simple))); - fail_if(!eo_do(simple, eo_composite_part_is())); - fail_if(eo_do(obj, eo_composite_attach(simple))); + fail_if(!eo_do_ret(simple, tmp,eo_composite_part_is())); + fail_if(!eo_do_ret(obj, tmp,eo_composite_detach(simple))); + fail_if(eo_do_ret(obj, tmp,eo_composite_detach(simple))); + fail_if(eo_do_ret(simple, tmp,eo_composite_part_is())); + fail_if(!eo_do_ret(obj, tmp,eo_composite_attach(simple))); + fail_if(!eo_do_ret(simple, tmp,eo_composite_part_is())); + fail_if(eo_do_ret(obj, tmp,eo_composite_attach(simple))); - fail_if(eo_do(simple, eo_composite_attach(obj))); + fail_if(eo_do_ret(simple, tmp,eo_composite_attach(obj))); eo_unref(simple); eo_unref(obj); diff --git a/src/tests/eo/constructors/constructors_simple.c b/src/tests/eo/constructors/constructors_simple.c index 9a25e2bcf5..5e9b60f0d1 100644 --- a/src/tests/eo/constructors/constructors_simple.c +++ b/src/tests/eo/constructors/constructors_simple.c @@ -50,11 +50,14 @@ _constructor(Eo *obj, void *class_data EINA_UNUSED) static Eo* _finalize(Eo *obj, void *class_data EINA_UNUSED) { + Eo *ret; Private_Data *pd = class_data; if (pd->a < 0) eo_error_set(obj); - return eo_do_super(obj, MY_CLASS, eo_finalize()); + eo_do_super(obj, MY_CLASS, ret = eo_finalize()); + + return ret; } static void diff --git a/src/tests/eo/suite/eo_test_general.c b/src/tests/eo/suite/eo_test_general.c index feef06a31a..baef2fe569 100644 --- a/src/tests/eo/suite/eo_test_general.c +++ b/src/tests/eo/suite/eo_test_general.c @@ -271,6 +271,7 @@ END_TEST START_TEST(eo_composite_tests) { + Eina_Bool tmp; eo_init(); Eo *obj = eo_add(SIMPLE_CLASS, NULL); @@ -280,7 +281,7 @@ START_TEST(eo_composite_tests) eo_do(obj, eo_composite_attach(obj2)); eo_do(obj2, eo_parent_set(NULL)); - fail_if(eo_do(obj2, eo_composite_part_is())); + fail_if(eo_do_ret(obj2, tmp, eo_composite_part_is())); eo_unref(obj2); eo_unref(obj); @@ -803,7 +804,7 @@ START_TEST(eo_add_do_and_custom) obj = eo_add(SIMPLE_CLASS, NULL, finalized = eo_finalized_get()); fail_if(finalized); - finalized = eo_do(obj, eo_finalized_get()); + eo_do(obj, finalized = eo_finalized_get()); fail_if(!finalized); eo_unref(obj);