eolian: Added eolian_function_is_constructor().
authorSavio Sena <savio@expertisesolutions.com.br>
Fri, 12 Sep 2014 19:51:37 +0000 (16:51 -0300)
committerSavio Sena <savio@expertisesolutions.com.br>
Fri, 12 Sep 2014 19:51:37 +0000 (16:51 -0300)
This patch adds a list of strings called 'ctor_of' to
_Eolian_Function. This list will contain all classes in which this
function is a constructing function.

ctor_of is filled in two moments:

* When filling the constructors of a class, class->full_name is inserted
  in the 'ctor_of' of each constructor's function.

* When filling the implements of a class, if the function is a
  constructor of its superclass it also becomes a constructor of the
  current class, so class->full_name is also inserted in the 'ctor_of'
  of each implement's function.

eolian_function_is_constructor gets a func and klass arguments. It goes
through ctor_of of func and returns EINA_TRUE if klass->full_name is
found, otherwise it returns EINA_FALSE.

src/lib/eolian/Eolian.h
src/lib/eolian/database_function.c
src/lib/eolian/database_function_api.c
src/lib/eolian/database_implement.c
src/lib/eolian/eolian_database.c
src/lib/eolian/eolian_database.h

index 320a2cb..108c4f3 100644 (file)
@@ -779,6 +779,17 @@ EAPI Eina_Bool eolian_function_is_legacy_only(const Eolian_Function *function_id
 EAPI Eina_Bool eolian_function_is_class(const Eolian_Function *function_id);
 
 /*
+ * @brief Indicates if a function is a constructing function of a given class.
+ *
+ * @param[in] klass the class
+ * @param[in] function_id Id of the function
+ * @return EINA_TRUE and EINA_FALSE respectively
+ *
+ * @ingroup Eolian
+ */
+EAPI Eina_Bool eolian_function_is_constructor(const Eolian_Function *function_id, const Eolian_Class *klass);
+
+/*
  * @brief Returns a parameter of a function pointed by its id.
  *
  * @param[in] function_id Id of the function
index c29f079..ef59bcf 100644 (file)
@@ -5,12 +5,14 @@ void
 database_function_del(Eolian_Function *fid)
 {
    Eolian_Function_Parameter *param;
+   Eina_Stringshare *cls_name;
    if (!fid) return;
 
    if (fid->base.file) eina_stringshare_del(fid->base.file);
    eina_stringshare_del(fid->name);
    EINA_LIST_FREE(fid->keys, param) database_parameter_del(param);
    EINA_LIST_FREE(fid->params, param) database_parameter_del(param);
+   EINA_LIST_FREE(fid->ctor_of, cls_name) eina_stringshare_del(cls_name);
    database_type_del(fid->get_ret_type);
    database_type_del(fid->set_ret_type);
    database_expr_del(fid->get_ret_val);
@@ -23,3 +25,29 @@ database_function_del(Eolian_Function *fid)
    if (fid->set_return_comment) eina_stringshare_del(fid->set_return_comment);
    free(fid);
 }
+
+static Eina_List*
+_list_sorted_insert_no_dup(Eina_List *l, Eina_Compare_Cb func, const void *data)
+{
+   Eina_List *lnear;
+   int cmp;
+
+   if (!l)
+     return eina_list_append(NULL, data);
+   else
+     lnear = eina_list_search_sorted_near_list(l, func, data, &cmp);
+
+   if (cmp < 0)
+     return eina_list_append_relative_list(l, data, lnear);
+   else if (cmp > 0)
+     return eina_list_prepend_relative_list(l, data, lnear);
+   return l;
+}
+
+void
+database_function_constructor_add(Eolian_Function *func, const Eolian_Class *cls)
+{
+   func->ctor_of = _list_sorted_insert_no_dup
+     (func->ctor_of, EINA_COMPARE_CB(strcmp),
+      eina_stringshare_ref(cls->full_name));
+}
index 7a25353..a0462d0 100644 (file)
@@ -135,6 +135,17 @@ eolian_function_is_class(const Eolian_Function *fid)
    return fid->is_class;
 }
 
+EAPI Eina_Bool
+eolian_function_is_constructor(const Eolian_Function *fid, const Eolian_Class *klass)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(fid, EINA_FALSE);
+   Eina_Stringshare *s = eina_stringshare_ref(klass->full_name);
+   Eina_Bool r = !!eina_list_search_sorted_list
+     (fid->ctor_of, EINA_COMPARE_CB(strcmp), s);
+   eina_stringshare_del(s);
+   return r;
+}
+
 EAPI const Eolian_Function_Parameter *
 eolian_function_parameter_get_by_name(const Eolian_Function *fid, const char *param_name)
 {
index 5d9d349..ce49ecd 100644 (file)
@@ -9,3 +9,10 @@ database_implement_del(Eolian_Implement *impl)
    if (impl->full_name) eina_stringshare_del(impl->full_name);
    free(impl);
 }
+
+void
+database_implement_constructor_add(Eolian_Implement *impl, const Eolian_Class *klass)
+{
+   if (eolian_function_is_constructor(impl->foo_id, impl->klass))
+     database_function_constructor_add((Eolian_Function*)impl->foo_id, klass);
+}
index 5bae78d..0ae847a 100644 (file)
@@ -292,6 +292,8 @@ inherits:
              ERR("Unable to find function %s", eolian_implement_full_name_get(impl));
              goto error;
           }
+        else
+          database_implement_constructor_add(impl, class);
      }
    eina_iterator_free(itr);
    itr = eolian_class_constructors_get(class);
@@ -303,6 +305,8 @@ inherits:
              ERR("Unable to find function %s", eolian_constructor_full_name_get(ctor));
              goto error;
           }
+        else
+          database_function_constructor_add((Eolian_Function*)ctor_func, ctor->klass);
      }
    eina_iterator_free(itr);
 
index 6777e5a..c9433b8 100644 (file)
@@ -117,6 +117,7 @@ struct _Eolian_Function
    Eina_Bool get_only_legacy: 1;
    Eina_Bool set_only_legacy: 1;
    Eina_Bool is_class :1;
+   Eina_List *ctor_of;
 };
 
 struct _Eolian_Function_Parameter
@@ -274,12 +275,14 @@ void database_class_del(Eolian_Class *cl);
 
 /* functions */
 void database_function_del(Eolian_Function *fid);
+void database_function_constructor_add(Eolian_Function *func, const Eolian_Class *klass);
 
 /* func parameters */
 void database_parameter_del(Eolian_Function_Parameter *pdesc);
 
 /* implements */
 void database_implement_del(Eolian_Implement *impl);
+void database_implement_constructor_add(Eolian_Implement *impl, const Eolian_Class *klass);
 
 /* constructors */
 void database_constructor_del(Eolian_Constructor *ctor);