From 93a64c5eab5d4404b878bead5ea07f13ee2d175f Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Thu, 22 Mar 2018 15:34:32 +0100 Subject: [PATCH] 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); \ }