q66 pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=dda93f467e5a96101d0d818916dce1a9bcc431c7

commit dda93f467e5a96101d0d818916dce1a9bcc431c7
Author: Daniel Kolesa <[email protected]>
Date:   Wed Jul 9 11:18:21 2014 +0100

    eolian: proper resource management for types/structs
    
    Because types can have other types in each other, we need a stack of a sort 
to keep track of
    the types for error handling. Doing it otherwise would result in potential 
resource leaks.
---
 src/lib/eolian/eo_definitions.c |  5 ++--
 src/lib/eolian/eo_definitions.h |  2 +-
 src/lib/eolian/eo_parser.c      | 54 +++++++++++++++++++++++++++++------------
 3 files changed, 43 insertions(+), 18 deletions(-)

diff --git a/src/lib/eolian/eo_definitions.c b/src/lib/eolian/eo_definitions.c
index bbb7fe8..cb86ddd 100644
--- a/src/lib/eolian/eo_definitions.c
+++ b/src/lib/eolian/eo_definitions.c
@@ -188,6 +188,7 @@ eo_definitions_temps_free(Eo_Lexer_Temps *tmp)
 {
    Eina_Strbuf *buf;
    Eo_Param_Def *par;
+   Eo_Type_Def *tp;
    const char *s;
 
    EINA_LIST_FREE(tmp->str_bufs, buf)
@@ -208,8 +209,8 @@ eo_definitions_temps_free(Eo_Lexer_Temps *tmp)
    if (tmp->typedef_def)
      eo_definitions_typedef_def_free(tmp->typedef_def);
 
-   if (tmp->type_def)
-     eo_definitions_type_free(tmp->type_def);
+   EINA_LIST_FREE(tmp->type_defs, tp)
+     eo_definitions_type_free(tp);
 
    if (tmp->prop)
      eo_definitions_property_def_free(tmp->prop);
diff --git a/src/lib/eolian/eo_definitions.h b/src/lib/eolian/eo_definitions.h
index a8ba72e..ebb1d2f 100644
--- a/src/lib/eolian/eo_definitions.h
+++ b/src/lib/eolian/eo_definitions.h
@@ -160,7 +160,7 @@ typedef struct _Eo_Lexer_Temps
    Eo_Class_Def *kls;
    Eo_Ret_Def *ret_def;
    Eo_Typedef_Def *typedef_def;
-   Eo_Type_Def *type_def;
+   Eina_List *type_defs;
    Eo_Property_Def *prop;
    Eo_Method_Def *meth;
    Eo_Param_Def *param;
diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c
index da898ac..fba9717 100644
--- a/src/lib/eolian/eo_parser.c
+++ b/src/lib/eolian/eo_parser.c
@@ -101,6 +101,20 @@ pop_strbuf(Eo_Lexer *ls)
    ls->tmp.str_bufs = eina_list_remove_list(ls->tmp.str_bufs, 
ls->tmp.str_bufs);
 }
 
+static Eo_Type_Def *
+push_type(Eo_Lexer *ls)
+{
+   Eo_Type_Def *def = calloc(1, sizeof(Eo_Type_Def));
+   ls->tmp.type_defs = eina_list_prepend(ls->tmp.type_defs, def);
+   return def;
+}
+
+static void
+pop_type(Eo_Lexer *ls)
+{
+   ls->tmp.type_defs = eina_list_remove_list(ls->tmp.type_defs, 
ls->tmp.type_defs);
+}
+
 static void
 append_node(Eo_Lexer *ls, int type, void *def)
 {
@@ -182,21 +196,27 @@ static Eo_Type_Def *
 parse_function_type(Eo_Lexer *ls)
 {
    int line, col;
-   Eo_Type_Def *def = calloc(1, sizeof(Eo_Type_Def));
-   ls->tmp.type_def = def;
+   Eo_Type_Def *def = push_type(ls);
    eo_lexer_get(ls);
    if (ls->t.kw == KW_void)
      eo_lexer_get(ls);
    else
-     def->ret_type = parse_type_void(ls);
+     {
+        def->ret_type = parse_type_void(ls);
+        pop_type(ls);
+     }
    line = ls->line_number;
    col = ls->column;
    check_next(ls, '(');
    if (ls->t.token != ')')
      {
         def->arguments = eina_list_append(def->arguments, parse_type(ls));
+        pop_type(ls);
         while (test_next(ls, ','))
-          def->arguments = eina_list_append(def->arguments, parse_type(ls));
+          {
+             def->arguments = eina_list_append(def->arguments, parse_type(ls));
+             pop_type(ls);
+          }
      }
    check_match(ls, ')', '(', line, col);
    return def;
@@ -206,8 +226,7 @@ static Eo_Type_Def *
 parse_struct(Eo_Lexer *ls, const char *name)
 {
    int line = ls->line_number, column = ls->column;
-   Eo_Type_Def *def = calloc(1, sizeof(Eo_Type_Def));
-   ls->tmp.type_def = def;
+   Eo_Type_Def *def = push_type(ls);
    def->name = name;
    def->type = EOLIAN_TYPE_STRUCT;
    def->fields = 
eina_hash_string_small_new(EINA_FREE_CB(eo_definitions_type_free));
@@ -223,6 +242,7 @@ parse_struct(Eo_Lexer *ls, const char *name)
         check_next(ls, ':');
         eina_hash_add(def->fields, fname, parse_type_struct_nonvoid(ls,
                       EINA_TRUE, EINA_FALSE));
+        pop_type(ls);
         eina_stringshare_del(fname);
         check_next(ls, ';');
         if (ls->t.token == TOK_COMMENT)
@@ -297,8 +317,7 @@ parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct, 
Eina_Bool allow_anon)
       default:
         break;
      }
-   def = calloc(1, sizeof(Eo_Type_Def));
-   ls->tmp.type_def = def;
+   def = push_type(ls);
    if (ls->t.kw == KW_void && !has_struct)
      def->type = EOLIAN_TYPE_VOID;
    else
@@ -315,8 +334,9 @@ parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct, 
Eina_Bool allow_anon)
 parse_ptr:
    while (ls->t.token == '*')
      {
-        Eo_Type_Def *pdef = calloc(1, sizeof(Eo_Type_Def));
-        ls->tmp.type_def = pdef;
+        Eo_Type_Def *pdef;
+        pop_type(ls);
+        pdef = push_type(ls);
         pdef->base_type = def;
         pdef->type = EOLIAN_TYPE_POINTER;
         def = pdef;
@@ -327,8 +347,12 @@ parse_ptr:
         int line = ls->line_number, col = ls->column;
         eo_lexer_get(ls);
         def->subtypes = eina_list_append(def->subtypes, parse_type(ls));
+        pop_type(ls);
         while (test_next(ls, ','))
-           def->subtypes = eina_list_append(def->subtypes, parse_type(ls));
+          {
+             def->subtypes = eina_list_append(def->subtypes, parse_type(ls));
+             pop_type(ls);
+          }
         check_match(ls, '>', '<', line, col);
      }
    return def;
@@ -351,7 +375,7 @@ parse_typedef(Eo_Lexer *ls)
    (void)!!test_next(ls, ':');
    ls->tmp.typedef_def->type = parse_type_struct_nonvoid(ls, EINA_TRUE,
                                                          EINA_TRUE);
-   ls->tmp.type_def = NULL;
+   pop_type(ls);
    check_next(ls, ';');
 }
 
@@ -365,7 +389,7 @@ parse_return(Eo_Lexer *ls, Eina_Bool allow_void)
      ret->type = parse_type_void(ls);
    else
      ret->type = parse_type(ls);
-   ls->tmp.type_def = NULL;
+   pop_type(ls);
    if (ls->t.token == '(')
      {
         int line = ls->line_number, col = ls->column;
@@ -416,7 +440,7 @@ parse_param(Eo_Lexer *ls, Eina_Bool allow_inout)
      par->type = parse_type_void(ls);
    else
      par->type = parse_type(ls);
-   ls->tmp.type_def = NULL;
+   pop_type(ls);
    check(ls, TOK_VALUE);
    par->name = eina_stringshare_add(ls->t.value);
    eo_lexer_get(ls);
@@ -995,7 +1019,7 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot)
            name = eina_stringshare_add(ls->t.value);
            eo_lexer_get(ls);
            parse_struct(ls, name);
-           ls->tmp.type_def = NULL;
+           pop_type(ls);
            break;
         }
       def:

-- 


Reply via email to