summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@samsung.com>2019-01-29 20:37:11 +0100
committerDaniel Kolesa <d.kolesa@samsung.com>2019-02-28 01:09:02 +0100
commit4cbc010d8fefe25a390a4d4cfe5bdcbe77e9ff73 (patch)
tree9797f1c79e580e78b9890c5967f32977d210100f
parent6609a0d17ee6995fc07cd4ce7cea94f6aae5d9da (diff)
downloadefl-4cbc010d8fefe25a390a4d4cfe5bdcbe77e9ff73.tar.gz
eolian_gen: better freeing for inarray
This one will only loop the inarray if it contains a struct with owned fields, however it will not do iterative free for container fields in that kind of struct. That may be added later, or Eolian might be restricted further.
-rw-r--r--src/bin/eolian/sources.c63
1 files changed, 57 insertions, 6 deletions
diff --git a/src/bin/eolian/sources.c b/src/bin/eolian/sources.c
index 352bbc60be..e9da5b294d 100644
--- a/src/bin/eolian/sources.c
+++ b/src/bin/eolian/sources.c
@@ -242,6 +242,53 @@ _generate_loop_content(Eina_Strbuf **buf, const Eolian_Type *inner_type, const E
eina_strbuf_append(*buf, " }\n");
}
+static const Eolian_Typedecl *
+_have_struct_owned_fields(const Eolian_Type *tp)
+{
+ const Eolian_Type *btp = eolian_type_aliased_base_get(tp);
+ const Eolian_Typedecl *tdecl = eolian_type_typedecl_get(btp);
+ if (!tdecl || eolian_typedecl_type_get(tdecl) != EOLIAN_TYPEDECL_STRUCT)
+ return NULL;
+
+ Eina_Iterator *itr = eolian_typedecl_struct_fields_get(tdecl);
+ const Eolian_Struct_Type_Field *sf;
+ EINA_ITERATOR_FOREACH(itr, sf)
+ {
+ const Eolian_Type *ftp = eolian_typedecl_struct_field_type_get(sf);
+ if (eolian_type_is_owned(ftp))
+ {
+ eina_iterator_free(itr);
+ return tdecl;
+ }
+ }
+ eina_iterator_free(itr);
+ return NULL;
+}
+
+static void
+_generate_inarray_loop(Eina_Strbuf **buf, const Eolian_Typedecl *tdecl,
+ const Eina_Strbuf *iter_param)
+{
+ eina_strbuf_append(*buf, " {\n");
+ Eina_Iterator *itr = eolian_typedecl_struct_fields_get(tdecl);
+ const Eolian_Struct_Type_Field *sf;
+ Eina_Strbuf *fldbuf = eina_strbuf_new();
+ EINA_ITERATOR_FOREACH(itr, sf)
+ {
+ const Eolian_Type *ftp = eolian_typedecl_struct_field_type_get(sf);
+ if (!eolian_type_is_owned(ftp))
+ continue;
+ eina_strbuf_reset(fldbuf);
+ eina_strbuf_append_buffer(fldbuf, iter_param);
+ eina_strbuf_append(fldbuf, "->");
+ eina_strbuf_append(fldbuf, eolian_typedecl_struct_field_name_get(sf));
+ _generate_normal_free(buf, ftp, fldbuf, " ");
+ }
+ eina_strbuf_free(fldbuf);
+ eina_iterator_free(itr);
+ eina_strbuf_append(*buf, " }\n");
+}
+
static void
_generate_iterative_free(Eina_Strbuf **buf, const Eolian_Type *type, const Eolian_Type *inner_type, Eolian_Function_Parameter *parameter, Eina_Strbuf *param)
{
@@ -276,12 +323,16 @@ _generate_iterative_free(Eina_Strbuf **buf, const Eolian_Type *type, const Eolia
}
else if (t == EOLIAN_TYPE_BUILTIN_INARRAY)
{
- eina_strbuf_append_printf(*buf, " EINA_INARRAY_FOREACH(");
- eina_strbuf_append_buffer(*buf, param);
- eina_strbuf_append_char(*buf, ',');
- eina_strbuf_append_buffer(*buf, iter_param);
- eina_strbuf_append(*buf, ")\n");
- _generate_loop_content(buf, inner_type, iter_param);
+ const Eolian_Typedecl *ts = _have_struct_owned_fields(inner_type);
+ if (ts)
+ {
+ eina_strbuf_append_printf(*buf, " EINA_INARRAY_FOREACH(");
+ eina_strbuf_append_buffer(*buf, param);
+ eina_strbuf_append_char(*buf, ',');
+ eina_strbuf_append_buffer(*buf, iter_param);
+ eina_strbuf_append(*buf, ")\n");
+ _generate_inarray_loop(buf, ts, iter_param);
+ }
_write_free_call(*buf, "eina_inarray_free", param, "");
}
else if (t == EOLIAN_TYPE_BUILTIN_INLIST)