eolian: partially clean up implement filling logic

This commit is contained in:
Daniel Kolesa 2017-01-02 14:35:17 +01:00
parent 692d445dcf
commit 0b2c070b06
2 changed files with 47 additions and 57 deletions

View File

@ -7,44 +7,52 @@
static Eina_Bool
_func_error(Eolian_Class *cl, Eolian_Implement *impl)
{
fprintf(stderr, "eolian:%s:%d:%d: '%s%s' not known in class '%s'\n",
fprintf(stderr, "eolian:%s:%d:%d: '%s' not known in class '%s'\n",
impl->base.file, impl->base.line, impl->base.column, impl->full_name,
(impl->is_prop_get ? ".get" : (impl->is_prop_set ? ".set" : "")),
eolian_class_name_get(cl));
return EINA_FALSE;
}
static Eina_Bool
_get_impl_func(Eolian_Class *cl, Eolian_Implement *impl,
_get_impl_func(Eolian_Class *cl EINA_UNUSED, Eolian_Implement *impl,
Eolian_Function_Type ftype, Eolian_Function **foo_id)
{
size_t cllen = strlen(cl->full_name);
size_t imlen = strlen(impl->full_name);
const char *imstr = impl->full_name;
*foo_id = NULL;
if (imstr[0] == '.')
++imstr;
else if ((imlen > (cllen + 1)) && (*(imstr + cllen) == '.')
&& !strncmp(imstr, cl->full_name, cllen))
imstr += cllen + 1;
else
return EINA_TRUE;
if (strchr(imstr, '.'))
return EINA_TRUE;
impl->klass = cl;
*foo_id = (Eolian_Function*)eolian_class_function_get_by_name(cl, imstr,
ftype);
impl->foo_id = *foo_id;
return !!*foo_id;
char *clbuf = alloca(imlen + 1);
memcpy(clbuf, impl->full_name, imlen + 1);
char *ldot = strrchr(clbuf, '.');
if (!ldot)
return EINA_FALSE; /* unreachable in practice, for static analysis */
*ldot = '\0'; /* split between class name and func name */
const char *clname = clbuf;
const char *fnname = ldot + 1;
const Eolian_Class *tcl = eolian_class_get_by_name(clname);
if (!tcl)
return EINA_FALSE;
impl->klass = tcl;
const Eolian_Function *fid = eolian_class_function_get_by_name(tcl, fnname, ftype);
if (!fid)
return EINA_FALSE;
*foo_id = (Eolian_Function *)fid;
impl->foo_id = fid;
return EINA_TRUE;
}
static void
_write_impl(Eolian_Function *fid, Eolian_Implement *impl)
_write_impl(Eolian_Function *fid, Eolian_Function_Type ftype,
Eolian_Implement *impl)
{
if (impl->is_prop_set)
fid->set_impl = impl;
else if (impl->is_prop_get)
if (ftype == EOLIAN_PROP_GET)
fid->get_impl = impl;
else if (ftype == EOLIAN_PROP_SET)
fid->set_impl = impl;
else
fid->get_impl = fid->set_impl = impl;
}
@ -52,12 +60,12 @@ _write_impl(Eolian_Function *fid, Eolian_Implement *impl)
static Eina_Bool
_db_fill_implement(Eolian_Class *cl, Eolian_Implement *impl)
{
const char *impl_name = impl->full_name;
Eolian_Function *foo_id;
Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
if (impl->is_prop_get)
if (impl->is_prop_get && impl->is_prop_set)
ftype = EOLIAN_PROPERTY;
else if (impl->is_prop_get)
ftype = EOLIAN_PROP_GET;
else if (impl->is_prop_set)
ftype = EOLIAN_PROP_SET;
@ -66,47 +74,28 @@ _db_fill_implement(Eolian_Class *cl, Eolian_Implement *impl)
{
if (!_get_impl_func(cl, impl, ftype, &foo_id))
return _func_error(cl, impl);
if (!foo_id)
goto pasttags;
if (impl->is_prop_set)
foo_id->set_auto = EINA_TRUE;
else
foo_id->get_auto = EINA_TRUE;
_write_impl(foo_id, impl);
foo_id->get_auto = impl->is_prop_get;
foo_id->set_auto = impl->is_prop_set;
_write_impl(foo_id, ftype, impl);
}
else if (impl->is_empty)
{
if (!_get_impl_func(cl, impl, ftype, &foo_id))
return _func_error(cl, impl);
if (!foo_id)
goto pasttags;
if (impl->is_prop_set)
foo_id->set_empty = EINA_TRUE;
else
foo_id->get_empty = EINA_TRUE;
_write_impl(foo_id, impl);
foo_id->get_empty = impl->is_prop_get;
foo_id->set_empty = impl->is_prop_set;
_write_impl(foo_id, ftype, impl);
}
else if (!_get_impl_func(cl, impl, ftype, &foo_id))
return _func_error(cl, impl);
if (foo_id && foo_id->klass == cl && eolian_function_is_virtual_pure(foo_id, ftype))
{
fprintf(stderr, "eolian:%s:%d:%d: impl of pure virtual '%s%s'\n",
impl->base.file, impl->base.line, impl->base.column, impl->full_name,
(impl->is_prop_get ? ".get" : (impl->is_prop_set ? ".set" : "")));
fprintf(stderr, "eolian:%s:%d:%d: impl of pure virtual '%s'\n",
impl->base.file, impl->base.line, impl->base.column, impl->full_name);
return EINA_FALSE;
}
pasttags:
if (impl_name[0] == '.')
{
impl->full_name = eina_stringshare_printf("%s%s", cl->full_name,
impl_name);
eina_stringshare_del(impl_name);
}
return EINA_TRUE;
}

View File

@ -1536,15 +1536,16 @@ parse_implement(Eo_Lexer *ls, Eina_Bool iface)
if (ls->t.token == '.')
{
if (!impl->is_auto && !impl->is_empty)
goto fullclass;
eo_lexer_syntax_error(ls, "class name expected");
check_next(ls, '.');
if (ls->t.token != TOK_VALUE)
eo_lexer_syntax_error(ls, "name expected");
impl->full_name = eina_stringshare_printf(".%s", ls->t.value.s);
impl->full_name = eina_stringshare_printf("%s.%s",
ls->tmp.kls->full_name,
ls->t.value.s);
eo_lexer_get(ls);
goto propbeg;
}
fullclass:
if (ls->t.token != TOK_VALUE)
eo_lexer_syntax_error(ls, "class name expected");
buf = push_strbuf(ls);