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 */
 

-- 


Reply via email to