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
This commit is contained in:
parent
d9a8fe0fca
commit
93a64c5eab
|
@ -109,6 +109,8 @@ static Eolian_Object *
|
||||||
_eolian_decl_get(Eo_Lexer *ls, const char *name)
|
_eolian_decl_get(Eo_Lexer *ls, const char *name)
|
||||||
{
|
{
|
||||||
Eolian_Object *obj = eina_hash_find(ls->state->unit.objects, 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) ||
|
if (obj && ((obj->type == EOLIAN_OBJECT_CLASS) ||
|
||||||
(obj->type == EOLIAN_OBJECT_TYPEDECL) ||
|
(obj->type == EOLIAN_OBJECT_TYPEDECL) ||
|
||||||
(obj->type == EOLIAN_OBJECT_VARIABLE)))
|
(obj->type == EOLIAN_OBJECT_VARIABLE)))
|
||||||
|
|
|
@ -13,7 +13,7 @@ database_object_add(Eolian_Unit *unit, const Eolian_Object *obj)
|
||||||
{
|
{
|
||||||
/* object storage */
|
/* object storage */
|
||||||
eina_hash_add(unit->objects, obj->name, obj);
|
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_hash_set(unit->state->objects_f, obj->file, eina_list_append
|
||||||
((Eina_List *)eina_hash_find(unit->state->objects_f, obj->file), obj));
|
((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;
|
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
|
static void
|
||||||
_merge_unit(Eolian_Unit *dest, Eolian_Unit *src)
|
_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->aliases, _merge_unit_cb, dest->aliases);
|
||||||
eina_hash_foreach(src->structs, _merge_unit_cb, dest->structs);
|
eina_hash_foreach(src->structs, _merge_unit_cb, dest->structs);
|
||||||
eina_hash_foreach(src->enums, _merge_unit_cb, dest->enums);
|
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
|
typedef struct _Merge_Data
|
||||||
|
@ -885,6 +895,8 @@ eolian_state_file_parse(Eolian_State *state, const char *filepath)
|
||||||
_merge_units(ret);
|
_merge_units(ret);
|
||||||
if (!database_validate(ret))
|
if (!database_validate(ret))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
_merge_unit(&state->unit, &state->staging);
|
||||||
|
_state_clean(state);
|
||||||
return &state->unit;
|
return &state->unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -920,6 +932,9 @@ eolian_state_all_eot_files_parse(Eolian_State *state)
|
||||||
if (pd.ret && !database_validate(&state->unit))
|
if (pd.ret && !database_validate(&state->unit))
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
|
||||||
|
_merge_unit(&state->unit, &state->staging);
|
||||||
|
_state_clean(state);
|
||||||
|
|
||||||
return pd.ret;
|
return pd.ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -949,6 +964,9 @@ eolian_state_all_eo_files_parse(Eolian_State *state)
|
||||||
if (pd.ret && !database_validate(&state->unit))
|
if (pd.ret && !database_validate(&state->unit))
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
|
||||||
|
_merge_unit(&state->unit, &state->staging);
|
||||||
|
_state_clean(state);
|
||||||
|
|
||||||
return pd.ret;
|
return pd.ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ eolian_object_add(Eolian_Object *obj, Eina_Stringshare *name, Eina_Hash *hash)
|
||||||
|
|
||||||
#define EOLIAN_OBJECT_ADD(tunit, name, obj, memb) \
|
#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); \
|
eolian_object_add(&obj->base, name, tunit->memb); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue