q66 pushed a commit to branch master.

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

commit 93a64c5eab5d4404b878bead5ea07f13ee2d175f
Author: Daniel Kolesa <[email protected]>
Date:   Thu Mar 22 15:34:32 2018 +0100

    eolian: clean rollback support
    
    Previously, when an error happened in Eolian, the state was left
    in a presumably unusable and inconsistent condition. This work
    aims to change that, as all changes are committed into a staging
    area before being validated and merged back into main state.
    
    This is not yet complete, as units and by-file lookups are not
    currently involved in the rollback. This will change in the
    subsequent commits.
    
    @feature
---
 src/lib/eolian/eo_parser.c       |  2 ++
 src/lib/eolian/eolian_database.c | 22 ++++++++++++++++++++--
 src/lib/eolian/eolian_database.h |  2 +-
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c
index 5cd4726157..6f87fcda54 100644
--- a/src/lib/eolian/eo_parser.c
+++ b/src/lib/eolian/eo_parser.c
@@ -109,6 +109,8 @@ static Eolian_Object *
 _eolian_decl_get(Eo_Lexer *ls, const char *name)
 {
    Eolian_Object *obj = eina_hash_find(ls->state->unit.objects, name);
+   if (!obj)
+     obj = eina_hash_find(ls->state->staging.objects, name);
    if (obj && ((obj->type == EOLIAN_OBJECT_CLASS) ||
                (obj->type == EOLIAN_OBJECT_TYPEDECL) ||
                (obj->type == EOLIAN_OBJECT_VARIABLE)))
diff --git a/src/lib/eolian/eolian_database.c b/src/lib/eolian/eolian_database.c
index d928e3f456..4e337f6ed4 100644
--- a/src/lib/eolian/eolian_database.c
+++ b/src/lib/eolian/eolian_database.c
@@ -13,7 +13,7 @@ database_object_add(Eolian_Unit *unit, const Eolian_Object 
*obj)
 {
    /* object storage */
    eina_hash_add(unit->objects, obj->name, obj);
-   eina_hash_add(unit->state->unit.objects, obj->name, obj);
+   eina_hash_add(unit->state->staging.objects, obj->name, obj);
    eina_hash_set(unit->state->objects_f, obj->file, eina_list_append
                  ((Eina_List *)eina_hash_find(unit->state->objects_f, 
obj->file), obj));
 }
@@ -828,6 +828,16 @@ _merge_unit_cb(const Eina_Hash *hash EINA_UNUSED,
    return EINA_TRUE;
 }
 
+static Eina_Bool
+_merge_unit_cb_noref(const Eina_Hash *hash EINA_UNUSED,
+               const void *key, void *data, void *fdata)
+{
+   Eina_Hash *dest = fdata;
+   if (!eina_hash_find(dest, key))
+     eina_hash_add(dest, key, data);
+   return EINA_TRUE;
+}
+
 static void
 _merge_unit(Eolian_Unit *dest, Eolian_Unit *src)
 {
@@ -837,7 +847,7 @@ _merge_unit(Eolian_Unit *dest, Eolian_Unit *src)
    eina_hash_foreach(src->aliases, _merge_unit_cb, dest->aliases);
    eina_hash_foreach(src->structs, _merge_unit_cb, dest->structs);
    eina_hash_foreach(src->enums, _merge_unit_cb, dest->enums);
-   eina_hash_foreach(src->objects, _merge_unit_cb, dest->objects);
+   eina_hash_foreach(src->objects, _merge_unit_cb_noref, dest->objects);
 }
 
 typedef struct _Merge_Data
@@ -885,6 +895,8 @@ eolian_state_file_parse(Eolian_State *state, const char 
*filepath)
    _merge_units(ret);
    if (!database_validate(ret))
      return NULL;
+   _merge_unit(&state->unit, &state->staging);
+   _state_clean(state);
    return &state->unit;
 }
 
@@ -920,6 +932,9 @@ eolian_state_all_eot_files_parse(Eolian_State *state)
    if (pd.ret && !database_validate(&state->unit))
      return EINA_FALSE;
 
+   _merge_unit(&state->unit, &state->staging);
+   _state_clean(state);
+
    return pd.ret;
 }
 
@@ -949,6 +964,9 @@ eolian_state_all_eo_files_parse(Eolian_State *state)
    if (pd.ret && !database_validate(&state->unit))
      return EINA_FALSE;
 
+   _merge_unit(&state->unit, &state->staging);
+   _state_clean(state);
+
    return pd.ret;
 }
 
diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h
index 72adf48013..a359cdd44a 100644
--- a/src/lib/eolian/eolian_database.h
+++ b/src/lib/eolian/eolian_database.h
@@ -107,7 +107,7 @@ eolian_object_add(Eolian_Object *obj, Eina_Stringshare 
*name, Eina_Hash *hash)
 
 #define EOLIAN_OBJECT_ADD(tunit, name, obj, memb) \
 { \
-   eolian_object_add(&obj->base, name, tunit->state->unit.memb); \
+   eolian_object_add(&obj->base, name, tunit->state->staging.memb); \
    eolian_object_add(&obj->base, name, tunit->memb); \
 }
 

-- 


Reply via email to