eo: Fix leak in eo_override and allow NULL to reset
authorJean-Philippe Andre <jp.andre@samsung.com>
Mon, 18 Jul 2016 08:44:51 +0000 (17:44 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Mon, 18 Jul 2016 08:55:58 +0000 (17:55 +0900)
eo_override would leak the vtable if called multiple times, this
fixes that. Also, it is now possible to revert back to the original
class' vtable by passing in { NULL, 0 }

I believe it is thus possible to incrementally override more
functions on an object. Absolutely not recommended, but should work.
But it is not possible to selectively revert back to the original
class implementation on a single method. Use eo_super for that,
or revert back the entire object overrides.

PS: Is it normal that we pass in a struct? We never do that in EFL...

src/lib/eo/eo.c

index cb6776e..014d859 100644 (file)
@@ -1343,9 +1343,23 @@ eo_override(Eo *eo_id, Eo_Ops ops)
    EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, EINA_FALSE);
    EO_CLASS_POINTER_RETURN_VAL(EO_OVERRIDE_CLASS, klass, EINA_FALSE);
    Eo_Vtable *previous = obj->vtable;
-   obj->vtable = calloc(1, sizeof(*obj->vtable));
-   _vtable_init(obj->vtable, previous->size);
-   _vtable_copy_all(obj->vtable, previous);
+
+   if (!ops.descs)
+     {
+        if (obj->vtable != &obj->klass->vtable)
+          {
+             free(obj->vtable);
+             obj->vtable = (Eo_Vtable *) &obj->klass->vtable;
+          }
+        return EINA_TRUE;
+     }
+
+   if (obj->vtable == &obj->klass->vtable)
+     {
+        obj->vtable = calloc(1, sizeof(*obj->vtable));
+        _vtable_init(obj->vtable, previous->size);
+        _vtable_copy_all(obj->vtable, previous);
+     }
 
    if (!_eo_class_funcs_set(obj->vtable, &ops, obj->klass, klass, EINA_TRUE))
      {