q66 pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=49e5d4ffb9c9f369b28b6da6b4d434142ce45be0
commit 49e5d4ffb9c9f369b28b6da6b4d434142ce45be0 Author: Daniel Kolesa <[email protected]> Date: Tue Aug 26 11:06:54 2014 +0100 eolian: flatten dependencies of a file before parsing them (remove cycles) --- src/lib/eolian/eo_parser.c | 25 ++++++++++++++-------- src/lib/eolian/eolian_database.c | 45 ++++++++++++++++++++++++++++++++++++++++ src/lib/eolian/eolian_database.h | 11 ++++++++++ 3 files changed, 72 insertions(+), 9 deletions(-) diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c index b0299f0..33062c6 100644 --- a/src/lib/eolian/eo_parser.c +++ b/src/lib/eolian/eo_parser.c @@ -775,6 +775,19 @@ parse_struct_attrs(Eo_Lexer *ls, Eina_Bool is_enum, Eina_Bool allow_named, } } +static void +_append_dep(Eo_Lexer *ls, const char *fname, const char *name, int line, int col) +{ + Eolian_Dependency *dep = calloc(1, sizeof(Eolian_Dependency)); + dep->base.file = eina_stringshare_ref(ls->filename); + dep->base.line = line; + dep->base.column = col; + dep->filename = eina_stringshare_add(fname); + dep->name = eina_stringshare_add(name); + eina_hash_set(_depclasses, ls->filename, eina_list_append((Eina_List*) + eina_hash_find(_depclasses, ls->filename), dep)); +} + static Eolian_Type * parse_type_named_void(Eo_Lexer *ls, Eina_Bool allow_named) { @@ -926,10 +939,10 @@ parse_type_named_void(Eo_Lexer *ls, Eina_Bool allow_named) } else { + int dline = ls->line_number, dcol = ls->column; const char *bnm, *nm; char *fnm; buf = push_strbuf(ls); - eo_lexer_context_push(ls); parse_name(ls, buf); nm = eina_strbuf_string_get(buf); bnm = eina_stringshare_ref(ls->filename); @@ -941,13 +954,8 @@ parse_type_named_void(Eo_Lexer *ls, Eina_Bool allow_named) free(fnm); if (fname) { - if (!eolian_class_get_by_name(nm) - && !eolian_eo_file_parse(fname)) - { - eo_lexer_context_restore(ls); - eo_lexer_syntax_error(ls, - "failed to parse dependency"); - } + if (!eolian_class_get_by_name(nm)) + _append_dep(ls, fname, nm, dline, dcol); def->type = EOLIAN_TYPE_CLASS; } } @@ -957,7 +965,6 @@ parse_type_named_void(Eo_Lexer *ls, Eina_Bool allow_named) free(fnm); def->type = EOLIAN_TYPE_CLASS; } - eo_lexer_context_pop(ls); _fill_type_name(def, eina_stringshare_add(nm)); pop_strbuf(ls); } diff --git a/src/lib/eolian/eolian_database.c b/src/lib/eolian/eolian_database.c index 757f889..5484a2d 100644 --- a/src/lib/eolian/eolian_database.c +++ b/src/lib/eolian/eolian_database.c @@ -17,6 +17,7 @@ Eina_Hash *_globalsf = NULL; Eina_Hash *_constantsf = NULL; Eina_Hash *_filenames = NULL; Eina_Hash *_tfilenames = NULL; +Eina_Hash *_depclasses = NULL; static int _database_init_count = 0; @@ -26,6 +27,19 @@ _hashlist_free(void *data) eina_list_free((Eina_List*)data); } +void +database_deplist_free(Eina_List *data) +{ + Eolian_Dependency *dep; + EINA_LIST_FREE(data, dep) + { + eina_stringshare_del(dep->base.file); + eina_stringshare_del(dep->filename); + eina_stringshare_del(dep->name); + free(dep); + } +} + int database_init() { @@ -45,6 +59,7 @@ database_init() _constantsf = eina_hash_stringshared_new(_hashlist_free); _filenames = eina_hash_string_small_new(free); _tfilenames = eina_hash_string_small_new(free); + _depclasses = eina_hash_stringshared_new(EINA_FREE_CB(database_deplist_free)); return ++_database_init_count; } @@ -74,6 +89,7 @@ database_shutdown() eina_hash_free(_constantsf); _constantsf = NULL; eina_hash_free(_filenames ); _filenames = NULL; eina_hash_free(_tfilenames); _tfilenames = NULL; + eina_hash_free(_depclasses); _depclasses = NULL; eina_shutdown(); } return _database_init_count; @@ -154,11 +170,14 @@ EAPI Eina_Bool eolian_eo_file_parse(const char *filepath) { Eina_Iterator *itr; + Eina_List *depl; + Eolian_Dependency *dep; char *bfiledup = strdup(filepath); char *bfilename = basename(bfiledup); const Eolian_Class *class = eolian_class_get_by_file(bfilename); const char *inherit_name; Eolian_Implement *impl; + Eina_Bool failed_dep = EINA_FALSE; if (!class) { if (!eo_parser_database_fill(filepath, EINA_FALSE)) @@ -175,6 +194,32 @@ eolian_eo_file_parse(const char *filepath) } } free(bfiledup); + /* parse dependencies first */ + depl = eina_hash_find(_depclasses, eolian_class_file_get(class)); + if (!depl) + goto inherits; + eina_hash_set(_depclasses, eolian_class_file_get(class), NULL); + EINA_LIST_FREE(depl, dep) + { + if (failed_dep) goto free; + if (!eolian_class_get_by_name(dep->name) && + !eolian_eo_file_parse(dep->filename)) + { + eina_log_print(_eolian_log_dom, EINA_LOG_LEVEL_ERR, + dep->base.file, "", dep->base.line, "failed to parse " + "dependency '%s' at column %d", dep->name, dep->base.column); + failed_dep = EINA_TRUE; /* do not parse anymore stuff */ + } +free: + eina_stringshare_del(dep->base.file); + eina_stringshare_del(dep->filename); + eina_stringshare_del(dep->name); + free(dep); + } + if (failed_dep) + goto error; + /* and then inherits */ +inherits: itr = eolian_class_inherits_get(class); EINA_ITERATOR_FOREACH(itr, inherit_name) { diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h index 57ac6fd..17ee3e0 100644 --- a/src/lib/eolian/eolian_database.h +++ b/src/lib/eolian/eolian_database.h @@ -46,6 +46,9 @@ extern Eina_Hash *_constantsf; extern Eina_Hash *_filenames; /* Hash: filename without extension -> full path */ extern Eina_Hash *_tfilenames; +/* a hash holding lists of deps */ +extern Eina_Hash *_depclasses; + typedef struct _Eolian_Object { const char *file; @@ -53,6 +56,13 @@ typedef struct _Eolian_Object int column; } Eolian_Object; +typedef struct _Eolian_Dependency +{ + Eolian_Object base; + Eina_Stringshare *filename; + Eina_Stringshare *name; +} Eolian_Dependency; + struct _Eolian_Class { Eolian_Object base; @@ -254,6 +264,7 @@ int database_shutdown(); char *database_class_to_filename(const char *cname); Eina_Bool database_validate(void); +void database_deplist_free(Eina_List *data); /* types */ --
