eolian: add internal api for dep deferring + parsing without dep

This is cleaner than adding into a hash manually. Additionally, it
is now possible to request that the file be parsed not as a dep,
but rather standalone, which will be useful later.
This commit is contained in:
Daniel Kolesa 2018-04-18 15:23:07 +02:00
parent 311fada0d2
commit 28b1dd25c7
4 changed files with 34 additions and 20 deletions

View File

@ -280,10 +280,10 @@ doc_ref_class(Eo_Lexer *ls, const char *cname)
*p = tolower(*p);
}
memcpy(buf + clen, ".eo", sizeof(".eo"));
const char *eop = eina_hash_find(ls->state->filenames_eo, buf);
if (!eop)
if (!eina_hash_find(ls->state->filenames_eo, buf))
return;
eina_hash_set(ls->state->defer, buf, eop);
/* ref'd classes do not become dependencies */
database_defer(ls->state, buf, EINA_FALSE);
}
static void

View File

@ -753,11 +753,10 @@ parse_type_void(Eo_Lexer *ls)
fnm = database_class_to_filename(nm);
if (!compare_class_file(bnm, fnm))
{
const char *fname = eina_hash_find(ls->state->filenames_eo, fnm);
eina_stringshare_del(bnm);
if (fname)
if (eina_hash_find(ls->state->filenames_eo, fnm))
{
eina_hash_set(ls->state->defer, fnm, fname);
database_defer(ls->state, fnm, EINA_TRUE);
def->type = EOLIAN_TYPE_CLASS;
}
free(fnm);
@ -1459,8 +1458,7 @@ parse_part(Eo_Lexer *ls)
parse_name(ls, buf);
const char *nm = eina_strbuf_string_get(buf);
char *fnm = database_class_to_filename(nm);
const char *fname = eina_hash_find(ls->state->filenames_eo, fnm);
if (!fname)
if (!eina_hash_find(ls->state->filenames_eo, fnm))
{
free(fnm);
char ebuf[PATH_MAX];
@ -1469,7 +1467,7 @@ parse_part(Eo_Lexer *ls)
eo_lexer_syntax_error(ls, ebuf);
return;
}
eina_hash_set(ls->state->defer, fnm, fname);
database_defer(ls->state, fnm, EINA_TRUE);
free(fnm);
part->klass_name = eina_stringshare_add(nm);
eo_lexer_dtor_pop(ls);
@ -1947,7 +1945,7 @@ parse_class_body(Eo_Lexer *ls, Eolian_Class_Type type)
static void
_inherit_dep(Eo_Lexer *ls, Eina_Strbuf *buf)
{
const char *fname, *iname;
const char *iname;
char *fnm;
eina_strbuf_reset(buf);
eo_lexer_context_push(ls);
@ -1964,8 +1962,7 @@ _inherit_dep(Eo_Lexer *ls, Eina_Strbuf *buf)
eo_lexer_syntax_error(ls, ebuf);
return; /* unreachable (longjmp above), make static analysis shut up */
}
fname = eina_hash_find(ls->state->filenames_eo, fnm);
if (!fname)
if (!eina_hash_find(ls->state->filenames_eo, fnm))
{
char ebuf[PATH_MAX];
free(fnm);
@ -1991,7 +1988,7 @@ _inherit_dep(Eo_Lexer *ls, Eina_Strbuf *buf)
return;
}
}
eina_hash_set(ls->state->defer, fnm, fname);
database_defer(ls->state, fnm, EINA_TRUE);
ls->klass->inherits = eina_list_append(ls->klass->inherits, inames);
free(fnm);
eo_lexer_context_pop(ls);
@ -2079,17 +2076,16 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot)
{
Eina_Strbuf *buf = eina_strbuf_new();
eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf);
const char *found = NULL;
char errbuf[PATH_MAX];
eo_lexer_get(ls);
check(ls, TOK_VALUE);
eina_strbuf_append(buf, ls->t.value.s);
eina_strbuf_append(buf, ".eot");
if (!(found = eina_hash_find(ls->state->filenames_eot, eina_strbuf_string_get(buf))))
if (!eina_hash_find(ls->state->filenames_eot, eina_strbuf_string_get(buf)))
{
size_t buflen = eina_strbuf_length_get(buf);
eina_strbuf_remove(buf, buflen - 1, buflen);
if (!(found = eina_hash_find(ls->state->filenames_eo, eina_strbuf_string_get(buf))))
if (!eina_hash_find(ls->state->filenames_eo, eina_strbuf_string_get(buf)))
{
eo_lexer_dtor_pop(ls);
snprintf(errbuf, sizeof(errbuf),
@ -2097,7 +2093,7 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot)
eo_lexer_syntax_error(ls, errbuf);
}
}
eina_hash_set(ls->state->defer, eina_strbuf_string_get(buf), found);
database_defer(ls->state, eina_strbuf_string_get(buf), EINA_TRUE);
eo_lexer_dtor_pop(ls);
eo_lexer_get(ls);
check_next(ls, ';');

View File

@ -845,6 +845,18 @@ _state_clean(Eolian_State *state)
_hashlist_free_buckets(st->objects_f);
}
void
database_defer(Eolian_State *state, const char *fname, Eina_Bool isdep)
{
void *nval = (void *)((size_t)isdep + 1);
size_t found = (size_t)eina_hash_find(state->defer, fname);
/* add if not found or upgrade to dep if requested */
if (!found)
eina_hash_add(state->defer, fname, nval);
else if ((found <= 1) && isdep)
eina_hash_set(state->defer, fname, nval);
}
static Eina_Bool _parse_deferred(Eolian_Unit *parent);
typedef struct _Defer_Data
@ -854,11 +866,15 @@ typedef struct _Defer_Data
} Defer_Data;
static Eina_Bool
_defer_hash_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED,
void *data, void *fdata)
_defer_hash_cb(const Eina_Hash *hash EINA_UNUSED, const void *key,
void *data EINA_UNUSED, void *fdata)
{
Defer_Data *d = fdata;
Eolian_Unit *pdep = _eolian_file_parse_nodep(d->parent, data);
Eolian_Unit *parent = d->parent;
/* not a dependency; parse standalone */
//if ((size_t)data <= 1)
// parent = parent->state;
Eolian_Unit *pdep = _eolian_file_parse_nodep(parent, key);
return (d->succ = (pdep && _parse_deferred(pdep)));
}

View File

@ -377,6 +377,8 @@ struct _Eolian_Variable
char *database_class_to_filename(const char *cname);
Eina_Bool database_validate(const Eolian_Unit *src);
/* if isdep is EINA_TRUE, parse as a dependency of current unit */
void database_defer(Eolian_State *state, const char *fname, Eina_Bool isdep);
void database_object_add(Eolian_Unit *unit, const Eolian_Object *obj);