From: Daniel Kolesa Date: Wed, 9 Jul 2014 10:18:21 +0000 (+0100) Subject: eolian: proper resource management for types/structs X-Git-Tag: upstream/1.10.0+1149+ga3a15b1~289 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dda93f467e5a96101d0d818916dce1a9bcc431c7;p=platform%2Fupstream%2Fefl.git 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. --- 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: