q66 pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=cd49130df7656d22cb950145d1faa2f3466f3aa5
commit cd49130df7656d22cb950145d1faa2f3466f3aa5 Author: Daniel Kolesa <[email protected]> Date: Thu Mar 15 14:12:18 2018 +0100 eolian: generic dtor management for lexer --- src/lib/eolian/eo_lexer.c | 30 +++++++++---- src/lib/eolian/eo_lexer.h | 14 +++++- src/lib/eolian/eo_parser.c | 106 +++++++++++++++++++-------------------------- 3 files changed, 79 insertions(+), 71 deletions(-) diff --git a/src/lib/eolian/eo_lexer.c b/src/lib/eolian/eo_lexer.c index b1cd08771c..653a8ba0c9 100644 --- a/src/lib/eolian/eo_lexer.c +++ b/src/lib/eolian/eo_lexer.c @@ -1102,11 +1102,9 @@ _node_free(Eolian_Object *obj) static void _temps_free(Eo_Lexer_Temps *tmp) { - Eina_Strbuf *buf; Eolian_Type *tp; Eolian_Typedecl *tpd; Eolian_Object *obj; - const char *s; if (tmp->kls) database_class_del(tmp->kls); @@ -1114,18 +1112,12 @@ _temps_free(Eo_Lexer_Temps *tmp) if (tmp->var) database_var_del(tmp->var); - EINA_LIST_FREE(tmp->str_bufs, buf) - eina_strbuf_free(buf); - EINA_LIST_FREE(tmp->type_defs, tp) database_type_del(tp); EINA_LIST_FREE(tmp->type_decls, tpd) database_typedecl_del(tpd); - EINA_LIST_FREE(tmp->strs, s) - if (s) eina_stringshare_del(s); - EINA_LIST_FREE(tmp->nodes, obj) _node_free(obj); } @@ -1151,6 +1143,23 @@ _free_tok(Eo_Token *tok) } void +eo_lexer_dtor_push(Eo_Lexer *ls, Eina_Free_Cb free_cb, void *data) +{ + Eo_Lexer_Dtor *dt = malloc(sizeof(Eo_Lexer_Dtor)); + dt->free_cb = free_cb; + dt->data = data; + ls->dtors = eina_list_prepend(ls->dtors, dt); +} + +void +eo_lexer_dtor_pop(Eo_Lexer *ls) +{ + Eo_Lexer_Dtor *dt = eina_list_data_get(ls->dtors); + ls->dtors = eina_list_remove_list(ls->dtors, ls->dtors); + free(dt); +} + +void eo_lexer_free(Eo_Lexer *ls) { if (!ls) return; @@ -1162,6 +1171,11 @@ eo_lexer_free(Eo_Lexer *ls) _free_tok(&ls->t); eo_lexer_context_clear(ls); _temps_free(&ls->tmp); + + Eo_Lexer_Dtor *dtor; + EINA_LIST_FREE(ls->dtors, dtor) + dtor->free_cb(dtor->data); + free(ls); } diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h index d6a53aad55..af0cb352ec 100644 --- a/src/lib/eolian/eo_lexer.h +++ b/src/lib/eolian/eo_lexer.h @@ -123,14 +123,18 @@ typedef struct _Eo_Lexer_Temps { Eolian_Class *kls; Eolian_Variable *var; - Eina_List *str_bufs; Eina_List *type_defs; Eina_List *type_decls; Eina_List *expr_defs; - Eina_List *strs; Eina_List *nodes; } Eo_Lexer_Temps; +typedef struct _Eo_Lexer_Dtor +{ + Eina_Free_Cb free_cb; + void *data; +} Eo_Lexer_Dtor; + /* keeps all lexer state */ typedef struct _Eo_Lexer { @@ -184,6 +188,7 @@ typedef struct _Eo_Lexer Eo_Lexer_Temps tmp; Eolian_Class *klass; + Eina_List *dtors; /* whether we allow lexing expression related tokens */ Eina_Bool expr_mode; @@ -220,7 +225,12 @@ void eo_lexer_context_pop (Eo_Lexer *ls); void eo_lexer_context_restore(Eo_Lexer *ls); void eo_lexer_context_clear (Eo_Lexer *ls); +/* node ("heap") management */ Eolian_Object *eo_lexer_node_new(Eo_Lexer *ls, size_t objsize); +/* "stack" management, only to protect against errors (jumps) in parsing */ +void eo_lexer_dtor_push(Eo_Lexer *ls, Eina_Free_Cb free_cb, void *data); +void eo_lexer_dtor_pop(Eo_Lexer *ls); + #endif /* __EO_LEXER_H__ */ diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c index 0bb4fdffdc..bdbb175d4f 100644 --- a/src/lib/eolian/eo_parser.c +++ b/src/lib/eolian/eo_parser.c @@ -97,22 +97,6 @@ check_match(Eo_Lexer *ls, int what, int who, int where, int col) } } -static Eina_Strbuf * -push_strbuf(Eo_Lexer *ls) -{ - Eina_Strbuf *buf = eina_strbuf_new(); - ls->tmp.str_bufs = eina_list_prepend(ls->tmp.str_bufs, buf); - return buf; -} - -static void -pop_strbuf(Eo_Lexer *ls) -{ - Eina_Strbuf *buf = eina_list_data_get(ls->tmp.str_bufs); - eina_strbuf_free(buf); - ls->tmp.str_bufs = eina_list_remove_list(ls->tmp.str_bufs, ls->tmp.str_bufs); -} - static Eolian_Type * push_type(Eo_Lexer *ls) { @@ -141,20 +125,6 @@ pop_typedecl(Eo_Lexer *ls) ls->tmp.type_decls = eina_list_remove_list(ls->tmp.type_decls, ls->tmp.type_decls); } -static Eina_Stringshare * -push_str(Eo_Lexer *ls, const char *val) -{ - Eina_Stringshare *shr = eina_stringshare_add(val); - ls->tmp.strs = eina_list_prepend(ls->tmp.strs, shr); - return shr; -} - -static void -pop_str(Eo_Lexer *ls) -{ - ls->tmp.strs = eina_list_remove_list(ls->tmp.strs, ls->tmp.strs); -} - static Eina_Bool compare_class_file(const char *fn1, const char *fn2) { @@ -408,13 +378,14 @@ parse_expr_simple(Eo_Lexer *ls) } default: { - Eina_Strbuf *buf = push_strbuf(ls); + Eina_Strbuf *buf = eina_strbuf_new(); + eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf); expr = push_expr(ls); expr->type = EOLIAN_EXPR_NAME; parse_name(ls, buf); expr->value.s = eina_stringshare_add(eina_strbuf_string_get (buf)); - pop_strbuf(ls); + eo_lexer_dtor_pop(ls); break; } } @@ -509,7 +480,7 @@ parse_struct(Eo_Lexer *ls, const char *name, Eina_Bool is_extern, def->type = EOLIAN_TYPEDECL_STRUCT; def->fields = eina_hash_string_small_new(EINA_FREE_CB(_struct_field_free)); def->freefunc = freefunc; - pop_str(ls); + eo_lexer_dtor_pop(ls); check_next(ls, '{'); FILL_DOC(ls, def, doc); while (ls->t.token != '}') @@ -679,7 +650,8 @@ parse_struct_attrs(Eo_Lexer *ls, Eina_Bool is_enum, Eina_Bool *is_extern, int pline = ls->line_number, pcol = ls->column; check_next(ls, '('); check(ls, TOK_VALUE); - *freefunc = push_str(ls, ls->t.value.s); + *freefunc = eina_stringshare_add(ls->t.value.s); + eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_stringshare_del), (void *)*freefunc); eo_lexer_get(ls); check_match(ls, ')', '(', pline, pcol); break; @@ -809,7 +781,8 @@ parse_type_void(Eo_Lexer *ls) { const char *bnm, *nm; char *fnm; - buf = push_strbuf(ls); + buf = eina_strbuf_new(); + eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf); eo_lexer_context_push(ls); parse_name(ls, buf); nm = eina_strbuf_string_get(buf); @@ -834,7 +807,7 @@ parse_type_void(Eo_Lexer *ls) } def->base.name = eina_stringshare_add(nm); eo_lexer_context_pop(ls); - pop_strbuf(ls); + eo_lexer_dtor_pop(ls); } } return def; @@ -850,10 +823,11 @@ parse_typedef(Eo_Lexer *ls) eo_lexer_get(ls); parse_struct_attrs(ls, EINA_FALSE, &has_extern, &freefunc); def->freefunc = freefunc; - pop_str(ls); + eo_lexer_dtor_pop(ls); def->type = EOLIAN_TYPEDECL_ALIAS; def->is_extern = has_extern; - buf = push_strbuf(ls); + buf = eina_strbuf_new(); + eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf); eo_lexer_context_push(ls); FILL_BASE(def->base, ls, ls->line_number, ls->column, TYPEDECL); parse_name(ls, buf); @@ -870,7 +844,7 @@ parse_typedef(Eo_Lexer *ls) pop_type(ls); check_next(ls, ';'); FILL_DOC(ls, def, doc); - pop_strbuf(ls); + eo_lexer_dtor_pop(ls); return def; } @@ -887,7 +861,8 @@ parse_variable(Eo_Lexer *ls, Eina_Bool global) eo_lexer_get(ls); } def->type = global ? EOLIAN_VAR_GLOBAL : EOLIAN_VAR_CONSTANT; - buf = push_strbuf(ls); + buf = eina_strbuf_new(); + eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf); eo_lexer_context_push(ls); FILL_BASE(def->base, ls, ls->line_number, ls->column, VARIABLE); parse_name(ls, buf); @@ -916,7 +891,7 @@ parse_variable(Eo_Lexer *ls, Eina_Bool global) } check_next(ls, ';'); FILL_DOC(ls, def, doc); - pop_strbuf(ls); + eo_lexer_dtor_pop(ls); return def; } @@ -1332,7 +1307,8 @@ parse_function_pointer(Eo_Lexer *ls) int line = ls->line_number, col = ls->column; Eolian_Typedecl *def = push_typedecl(ls); - Eina_Strbuf *buf = push_strbuf(ls); + Eina_Strbuf *buf = eina_strbuf_new(); + eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf); Eolian_Function *meth = NULL; Eina_Bool has_params = EINA_FALSE, @@ -1347,7 +1323,7 @@ parse_function_pointer(Eo_Lexer *ls) parse_name(ls, buf); def->base.name = eina_stringshare_add(eina_strbuf_string_get(buf)); - pop_strbuf(ls); + eo_lexer_dtor_pop(ls); meth = calloc(1, sizeof(Eolian_Function)); meth->klass = NULL; @@ -1509,7 +1485,8 @@ parse_part(Eo_Lexer *ls) part->base.name = eina_stringshare_ref(ls->t.value.s); eo_lexer_get(ls); check_next(ls, ':'); - Eina_Strbuf *buf = push_strbuf(ls); + Eina_Strbuf *buf = eina_strbuf_new(); + eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf); eo_lexer_context_push(ls); parse_name(ls, buf); const char *nm = eina_strbuf_string_get(buf); @@ -1527,7 +1504,7 @@ parse_part(Eo_Lexer *ls) eina_hash_set(ls->state->defer, fnm, fname); free(fnm); part->klass_name = eina_stringshare_add(nm); - pop_strbuf(ls); + eo_lexer_dtor_pop(ls); check_next(ls, ';'); FILL_DOC(ls, part, doc); } @@ -1605,7 +1582,8 @@ parse_implement(Eo_Lexer *ls, Eina_Bool iface) } if (ls->t.token != TOK_VALUE) eo_lexer_syntax_error(ls, "class name expected"); - buf = push_strbuf(ls); + buf = eina_strbuf_new(); + eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf); eina_strbuf_append(buf, ls->t.value.s); eo_lexer_get(ls); check_next(ls, '.'); @@ -1694,7 +1672,7 @@ propend: if (buf) { impl->base.name = eina_stringshare_add(eina_strbuf_string_get(buf)); - pop_strbuf(ls); + eo_lexer_dtor_pop(ls); } } @@ -1725,7 +1703,8 @@ parse_constructor(Eo_Lexer *ls) return; } check(ls, TOK_VALUE); - buf = push_strbuf(ls); + buf = eina_strbuf_new(); + eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf); eina_strbuf_append(buf, ls->t.value.s); eo_lexer_get(ls); check_next(ls, '.'); @@ -1746,7 +1725,7 @@ parse_constructor(Eo_Lexer *ls) } check_next(ls, ';'); ctor->base.name = eina_stringshare_add(eina_strbuf_string_get(buf)); - pop_strbuf(ls); + eo_lexer_dtor_pop(ls); } static void @@ -1755,7 +1734,8 @@ parse_event(Eo_Lexer *ls) Eolian_Event *ev = calloc(1, sizeof(Eolian_Event)); FILL_BASE(ev->base, ls, ls->line_number, ls->column, EVENT); ev->scope = EOLIAN_SCOPE_PUBLIC; - Eina_Strbuf *buf = push_strbuf(ls); + Eina_Strbuf *buf = eina_strbuf_new(); + eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf); ls->klass->events = eina_list_append(ls->klass->events, ev); eolian_object_ref(&ev->base); check(ls, TOK_VALUE); @@ -1770,7 +1750,7 @@ parse_event(Eo_Lexer *ls) eo_lexer_get(ls); } ev->base.name = eina_stringshare_add(eina_strbuf_string_get(buf)); - pop_strbuf(ls); + eo_lexer_dtor_pop(ls); Eina_Bool has_scope = EINA_FALSE, has_beta = EINA_FALSE, has_hot = EINA_FALSE, has_restart = EINA_FALSE, has_owned = EINA_FALSE; @@ -2057,7 +2037,8 @@ parse_class(Eo_Lexer *ls, Eolian_Class_Type type) char *fnm; Eina_Bool same; int line, col; - Eina_Strbuf *buf = push_strbuf(ls); + Eina_Strbuf *buf = eina_strbuf_new(); + eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf); ls->klass = (ls->tmp.kls = calloc(1, sizeof(Eolian_Class))); FILL_BASE(ls->klass->base, ls, ls->line_number, ls->column, CLASS); eo_lexer_get(ls); @@ -2082,7 +2063,7 @@ parse_class(Eo_Lexer *ls, Eolian_Class_Type type) redef_error(ls, decl, &ls->klass->base); } eo_lexer_context_pop(ls); - pop_strbuf(ls); + eo_lexer_dtor_pop(ls); if (ls->t.token != '{') { line = ls->line_number; @@ -2090,11 +2071,12 @@ parse_class(Eo_Lexer *ls, Eolian_Class_Type type) check_next(ls, '('); if (ls->t.token != ')') { - Eina_Strbuf *ibuf = push_strbuf(ls); + Eina_Strbuf *ibuf = eina_strbuf_new(); + eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), ibuf); _inherit_dep(ls, ibuf); while (test_next(ls, ',')) _inherit_dep(ls, ibuf); - pop_strbuf(ls); + eo_lexer_dtor_pop(ls); } check_match(ls, ')', '(', line, col); } @@ -2128,7 +2110,8 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot) goto found_class; case KW_import: { - Eina_Strbuf *buf = push_strbuf(ls); + Eina_Strbuf *buf = eina_strbuf_new(); + eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf); const char *found = NULL; char errbuf[PATH_MAX]; eo_lexer_get(ls); @@ -2141,14 +2124,14 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot) eina_strbuf_remove(buf, buflen - 1, buflen); if (!(found = eina_hash_find(ls->state->filenames_eo, eina_strbuf_string_get(buf)))) { - pop_strbuf(ls); + eo_lexer_dtor_pop(ls); snprintf(errbuf, sizeof(errbuf), "unknown import '%s'", ls->t.value.s); eo_lexer_syntax_error(ls, errbuf); } } eina_hash_set(ls->state->defer, eina_strbuf_string_get(buf), found); - pop_strbuf(ls); + eo_lexer_dtor_pop(ls); eo_lexer_get(ls); check_next(ls, ';'); break; @@ -2184,7 +2167,8 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot) Eina_Strbuf *buf; eo_lexer_get(ls); parse_struct_attrs(ls, is_enum, &has_extern, &freefunc); - buf = push_strbuf(ls); + buf = eina_strbuf_new(); + eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf); eo_lexer_context_push(ls); line = ls->line_number; col = ls->column; @@ -2201,14 +2185,14 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot) redef_error(ls, decl, &tdecl.base); } eo_lexer_context_pop(ls); - pop_strbuf(ls); + eo_lexer_dtor_pop(ls); if (!is_enum && ls->t.token == ';') { Eolian_Typedecl *def = push_typedecl(ls); def->is_extern = has_extern; def->type = EOLIAN_TYPEDECL_STRUCT_OPAQUE; def->freefunc = freefunc; - pop_str(ls); + eo_lexer_dtor_pop(ls); def->base.name = name; eo_lexer_get(ls); FILL_DOC(ls, def, doc); --
