From 53fef30db0aecc191384dae81882b50eba79da1a Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Thu, 13 Apr 2017 15:56:15 +0200 Subject: [PATCH] eolian: allow extending eolian-generated classes from within C If you define either the macro MY_CLASS_EXTRA_OPS for normal methods/properties or MY_CLASS_EXTRA_CLASS_OPS for class methods or properties, which contains a comma-delimited list of ops defs (i.e. EFL_OBJECT_OP_FUNC(...), ...) right before including the generated my_class.eo.c file, the definitions from these will be included in the actual class. This can be used to override certain things in a class internally without exposing it to Eolian, or for testing/debugging. --- src/bin/eolian/sources.c | 51 +++++++++++++++++++++----------- src/tests/eolian/data/class_simple_ref.c | 18 +++++++++-- src/tests/eolian/data/override_ref.c | 18 +++++++++-- 3 files changed, 65 insertions(+), 22 deletions(-) diff --git a/src/bin/eolian/sources.c b/src/bin/eolian/sources.c index f264f53..6004a9e 100644 --- a/src/bin/eolian/sources.c +++ b/src/bin/eolian/sources.c @@ -532,12 +532,13 @@ _gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf) } eina_iterator_free(itr); - char *cnamel = NULL; - eo_gen_class_names_get(cl, NULL, NULL, &cnamel); + char *cnamel = NULL, *cnameu = NULL; + eo_gen_class_names_get(cl, NULL, &cnameu, &cnamel); eina_strbuf_append(buf, "\nstatic Eina_Bool\n_"); eina_strbuf_append(buf, cnamel); eina_strbuf_append(buf, "_class_initializer(Efl_Class *klass)\n{\n"); + eina_strbuf_append(buf, " const Efl_Object_Ops *opsp = NULL, *copsp = NULL;\n\n"); Eina_Strbuf *ops = eina_strbuf_new(), *cops = eina_strbuf_new(); @@ -584,37 +585,51 @@ _gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf) } eina_iterator_free(itr); - /* strip the final comma before appending */ if (eina_strbuf_length_get(ops)) { - eina_strbuf_remove(ops, eina_strbuf_length_get(ops) - 2, - eina_strbuf_length_get(ops)); - eina_strbuf_append(ops, "\n );\n"); + /* make sure the extras are defined */ + eina_strbuf_append_printf(buf, "#ifndef %s_EXTRA_OPS\n", cnameu); + eina_strbuf_append_printf(buf, "#define %s_EXTRA_OPS\n", cnameu); + eina_strbuf_append(buf, "#endif\n\n"); + + eina_strbuf_append_printf(ops, " %s_EXTRA_OPS\n );\n", cnameu); eina_strbuf_append(buf, eina_strbuf_string_get(ops)); + eina_strbuf_append(buf, " opsp = &ops;\n\n"); + } + else + { + /* no predefined, but if custom ones are required define it anyway */ + eina_strbuf_append_printf(buf, "#ifdef %s_EXTRA_OPS\n", cnameu); + eina_strbuf_append_printf(buf, " EFL_OPS_DEFINE(ops, %s_EXTRA_OPS);\n", cnameu); + eina_strbuf_append(buf, " opsp = &ops;\n"); + eina_strbuf_append(buf, "#endif\n\n"); } if (eina_strbuf_length_get(cops)) { - eina_strbuf_remove(cops, eina_strbuf_length_get(cops) - 2, - eina_strbuf_length_get(cops)); - eina_strbuf_append(cops, "\n );\n"); + eina_strbuf_append_printf(buf, "#ifndef %s_EXTRA_CLASS_OPS\n", cnameu); + eina_strbuf_append_printf(buf, "#define %s_EXTRA_CLASS_OPS\n", cnameu); + eina_strbuf_append(buf, "#endif\n\n"); + + eina_strbuf_append_printf(cops, " %s_EXTRA_CLASS_OPS\n );\n", cnameu); eina_strbuf_append(buf, eina_strbuf_string_get(cops)); + eina_strbuf_append(buf, " copsp = &cops;\n\n"); } - - eina_strbuf_append(buf, " return efl_class_functions_set(klass, "); - if (eina_strbuf_length_get(ops)) - eina_strbuf_append(buf, "&ops, "); - else - eina_strbuf_append(buf, "NULL, "); - if (eina_strbuf_length_get(cops)) - eina_strbuf_append(buf, "&cops);\n"); else - eina_strbuf_append(buf, "NULL);\n"); + { + eina_strbuf_append_printf(buf, "#ifdef %s_EXTRA_CLASS_OPS\n", cnameu); + eina_strbuf_append_printf(buf, " EFL_OPS_DEFINE(cops, %s_EXTRA_CLASS_OPS);\n", cnameu); + eina_strbuf_append(buf, " copsp = &cops;\n"); + eina_strbuf_append(buf, "#endif\n\n"); + } + + eina_strbuf_append(buf, " return efl_class_functions_set(klass, opsp, copsp);\n"); eina_strbuf_free(ops); eina_strbuf_free(cops); eina_strbuf_append(buf, "}\n\n"); + free(cnameu); free(cnamel); return EINA_TRUE; diff --git a/src/tests/eolian/data/class_simple_ref.c b/src/tests/eolian/data/class_simple_ref.c index baa47d6..ea0fdac 100644 --- a/src/tests/eolian/data/class_simple_ref.c +++ b/src/tests/eolian/data/class_simple_ref.c @@ -29,14 +29,28 @@ EOAPI EFL_FUNC_BODYV(efl_canvas_object_simple_bar, int *, NULL, EFL_FUNC_CALL(x) static Eina_Bool _class_simple_class_initializer(Efl_Class *klass) { + const Efl_Object_Ops *opsp = NULL, *copsp = NULL; + +#ifndef CLASS_SIMPLE_EXTRA_OPS +#define CLASS_SIMPLE_EXTRA_OPS +#endif + EFL_OPS_DEFINE(ops, EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_a_set, _class_simple_a_set), EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_a_get, _class_simple_a_get), EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_b_set, _class_simple_b_set), EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_foo, __eolian_class_simple_foo), - EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_bar, _class_simple_bar) + EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_bar, _class_simple_bar), + CLASS_SIMPLE_EXTRA_OPS ); - return efl_class_functions_set(klass, &ops, NULL); + opsp = &ops; + +#ifdef CLASS_SIMPLE_EXTRA_CLASS_OPS + EFL_OPS_DEFINE(cops, CLASS_SIMPLE_EXTRA_CLASS_OPS); + copsp = &cops; +#endif + + return efl_class_functions_set(klass, opsp, copsp); } static const Efl_Class_Description _class_simple_class_desc = { diff --git a/src/tests/eolian/data/override_ref.c b/src/tests/eolian/data/override_ref.c index 76b9f40..c3226d7 100644 --- a/src/tests/eolian/data/override_ref.c +++ b/src/tests/eolian/data/override_ref.c @@ -67,6 +67,12 @@ static void __eolian_override_base_z_get(Eo *obj EINA_UNUSED, Override_Data *pd, static Eina_Bool _override_class_initializer(Efl_Class *klass) { + const Efl_Object_Ops *opsp = NULL, *copsp = NULL; + +#ifndef OVERRIDE_EXTRA_OPS +#define OVERRIDE_EXTRA_OPS +#endif + EFL_OPS_DEFINE(ops, EFL_OBJECT_OP_FUNC(override_a_set, NULL), EFL_OBJECT_OP_FUNC(override_a_get, _override_a_get), @@ -78,9 +84,17 @@ _override_class_initializer(Efl_Class *klass) EFL_OBJECT_OP_FUNC(override_bar, __eolian_override_bar), EFL_OBJECT_OP_FUNC(base_constructor, _override_base_constructor), EFL_OBJECT_OP_FUNC(base_z_set, __eolian_override_base_z_set), - EFL_OBJECT_OP_FUNC(base_z_get, __eolian_override_base_z_get) + EFL_OBJECT_OP_FUNC(base_z_get, __eolian_override_base_z_get), + OVERRIDE_EXTRA_OPS ); - return efl_class_functions_set(klass, &ops, NULL); + opsp = &ops; + +#ifdef OVERRIDE_EXTRA_CLASS_OPS + EFL_OPS_DEFINE(cops, OVERRIDE_EXTRA_CLASS_OPS); + copsp = &cops; +#endif + + return efl_class_functions_set(klass, opsp, copsp); } static const Efl_Class_Description _override_class_desc = { -- 2.7.4