summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@samsung.com>2019-05-30 16:20:09 +0200
committerDaniel Kolesa <d.kolesa@samsung.com>2019-05-30 16:29:51 +0200
commit9cba6a4f0e9d76935c7c6875b94aaa0bf790097c (patch)
tree36e7a0bad74b8d9eb768a679caf1a372897dddf8
parent8113f3f5658f655de1605f188b56db697453d101 (diff)
downloadefl-9cba6a4f0e9d76935c7c6875b94aaa0bf790097c.tar.gz
eolian: allow complete symbol renaming for C
This adds a new unified syntax for giving declarations C names. Classes: class @c_name(Foo) Foo ... Types: type @c_name(Foo) Foo: Bar ... Structs: struct @c_name(Foo) Foo ... and so on. Type instances properly inherit those. This also cleans up some other parts of the source code. Fixes T6716.
-rw-r--r--src/lib/eolian/database_type.c28
-rw-r--r--src/lib/eolian/database_validate.c2
-rw-r--r--src/lib/eolian/eo_parser.c148
3 files changed, 134 insertions, 44 deletions
diff --git a/src/lib/eolian/database_type.c b/src/lib/eolian/database_type.c
index 2523527a2d..a0d9652f9d 100644
--- a/src/lib/eolian/database_type.c
+++ b/src/lib/eolian/database_type.c
@@ -98,20 +98,6 @@ _buf_add_suffix(Eina_Strbuf *buf, const char *suffix)
eina_strbuf_append(buf, suffix);
}
-static void
-_append_name(const Eolian_Object *obj, Eina_Strbuf *buf)
-{
- Eina_Iterator *itr = eolian_object_namespaces_get(obj);
- const char *sp;
- EINA_ITERATOR_FOREACH(itr, sp)
- {
- eina_strbuf_append(buf, sp);
- eina_strbuf_append_char(buf, '_');
- }
- eina_strbuf_append(buf, eolian_object_short_name_get(obj));
- eina_iterator_free(itr);
-}
-
void
database_type_to_str(const Eolian_Type *tp,
Eina_Strbuf *buf, const char *name,
@@ -132,7 +118,7 @@ database_type_to_str(const Eolian_Type *tp,
if (kw && eo_lexer_is_type_keyword(kw))
eina_strbuf_append(buf, eo_lexer_get_c_type(kw));
else
- _append_name(&tp->base, buf);
+ eina_strbuf_append(buf, tp->base.c_name);
}
else if (tp->type == EOLIAN_TYPE_VOID)
eina_strbuf_append(buf, "void");
@@ -158,7 +144,7 @@ static void
_stype_to_str(const Eolian_Typedecl *tp, Eina_Strbuf *buf)
{
eina_strbuf_append(buf, "struct ");
- _append_name(&tp->base, buf);
+ eina_strbuf_append(buf, tp->base.c_name);
if (tp->type == EOLIAN_TYPEDECL_STRUCT_OPAQUE)
return;
eina_strbuf_append(buf, " { ");
@@ -177,7 +163,7 @@ static void
_etype_to_str(const Eolian_Typedecl *tp, Eina_Strbuf *buf)
{
eina_strbuf_append(buf, "enum ");
- _append_name(&tp->base, buf);
+ eina_strbuf_append(buf, tp->base.c_name);
eina_strbuf_append(buf, " { ");
Eina_List *l;
Eolian_Enum_Type_Field *ef;
@@ -210,17 +196,13 @@ _atype_to_str(const Eolian_Typedecl *tp, Eina_Strbuf *buf)
if (!strcmp(tp->base_type->base.name, "__builtin_free_cb"))
{
eina_strbuf_append(buf, "void (*");
- _append_name(&tp->base, buf);
+ eina_strbuf_append(buf, tp->base.c_name);
eina_strbuf_append(buf, ")(void *data)");
return;
}
}
-
- Eina_Strbuf *fulln = eina_strbuf_new();
- _append_name(&tp->base, fulln);
- database_type_to_str(tp->base_type, buf, eina_strbuf_string_get(fulln),
+ database_type_to_str(tp->base_type, buf, tp->base.c_name,
EOLIAN_C_TYPE_DEFAULT);
- eina_strbuf_free(fulln);
}
void
diff --git a/src/lib/eolian/database_validate.c b/src/lib/eolian/database_validate.c
index 9026f38247..71c05d7d8f 100644
--- a/src/lib/eolian/database_validate.c
+++ b/src/lib/eolian/database_validate.c
@@ -331,6 +331,7 @@ _validate_type(Validate_State *vals, Eolian_Type *tp)
return EINA_FALSE;
if (tp->tdecl->freefunc && !tp->freefunc)
tp->freefunc = eina_stringshare_ref(tp->tdecl->freefunc);
+ tp->base.c_name = eina_stringshare_ref(tp->tdecl->base.c_name);
return _validate_ownable(tp);
}
case EOLIAN_TYPE_CLASS:
@@ -350,6 +351,7 @@ _validate_type(Validate_State *vals, Eolian_Type *tp)
}
if (!tp->freefunc)
tp->freefunc = eina_stringshare_add(eo_obj_free);
+ tp->base.c_name = eina_stringshare_ref(tp->tdecl->base.c_name);
return _validate_ownable(tp);
}
default:
diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c
index cb1c7e4ed9..ee056b7cf5 100644
--- a/src/lib/eolian/eo_parser.c
+++ b/src/lib/eolian/eo_parser.c
@@ -202,6 +202,25 @@ parse_name(Eo_Lexer *ls, Eina_Strbuf *buf)
return buf;
}
+static Eina_Stringshare *
+parse_c_name(Eo_Lexer *ls)
+{
+ eo_lexer_get(ls);
+ int pline = ls->line_number, pcol = ls->column;
+ check_next(ls, '(');
+ check(ls, TOK_VALUE);
+ if (eo_lexer_is_type_keyword(ls->t.kw))
+ eo_lexer_syntax_error(ls, "invalid name");
+ Eina_Stringshare *cname = eina_stringshare_add(ls->t.value.s);
+ eo_lexer_get(ls);
+ if (ls->t.token != ')')
+ {
+ eina_stringshare_del(cname);
+ check_match(ls, ')', '(', pline, pcol);
+ }
+ return cname;
+}
+
static Eolian_Binary_Operator
get_binop_id(int tok)
{
@@ -445,21 +464,33 @@ _struct_field_free(Eolian_Struct_Type_Field *def)
static Eolian_Typedecl *
parse_struct(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
- Eina_Bool is_beta, int line, int column, const char *freefunc)
+ Eina_Bool is_beta, int line, int column, const char *freefunc,
+ const char *cname)
{
int bline = ls->line_number, bcolumn = ls->column;
Eolian_Typedecl *def = eo_lexer_typedecl_new(ls);
def->is_extern = is_extern;
def->base.is_beta = is_beta;
def->base.name = name;
- def->base.c_name = make_c_name(name);
def->type = EOLIAN_TYPEDECL_STRUCT;
def->fields = eina_hash_string_small_new(EINA_FREE_CB(_struct_field_free));
if (freefunc)
+ def->freefunc = eina_stringshare_ref(freefunc);
+ if (cname)
{
- def->freefunc = eina_stringshare_ref(freefunc);
+ def->base.c_name = cname;
eo_lexer_dtor_pop(ls);
}
+ else
+ def->base.c_name = make_c_name(name);
+ /* we can't know the order, pop when both are filled */
+ if (freefunc && cname)
+ {
+ eo_lexer_dtor_pop(ls);
+ eo_lexer_dtor_pop(ls);
+ }
+ else if (freefunc || cname)
+ eo_lexer_dtor_pop(ls);
check_next(ls, '{');
FILL_DOC(ls, def, doc);
while (ls->t.token != '}')
@@ -505,14 +536,20 @@ _enum_field_free(Eolian_Enum_Type_Field *def)
static Eolian_Typedecl *
parse_enum(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
- Eina_Bool is_beta, int line, int column)
+ Eina_Bool is_beta, int line, int column, const char *cname)
{
int bline = ls->line_number, bcolumn = ls->column;
Eolian_Typedecl *def = eo_lexer_typedecl_new(ls);
def->is_extern = is_extern;
def->base.is_beta = is_beta;
def->base.name = name;
- def->base.c_name = make_c_name(name);
+ if (cname)
+ {
+ def->base.c_name = cname;
+ eo_lexer_dtor_pop(ls);
+ }
+ else
+ def->base.c_name = make_c_name(name);
def->type = EOLIAN_TYPEDECL_ENUM;
def->fields = eina_hash_string_small_new(EINA_FREE_CB(_enum_field_free));
check_next(ls, '{');
@@ -738,7 +775,6 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ptr)
def->type = EOLIAN_TYPE_CLASS;
}
def->base.name = eina_stringshare_add(nm);
- def->base.c_name = make_c_name(nm);
eo_lexer_context_pop(ls);
eo_lexer_dtor_pop(ls);
}
@@ -752,7 +788,8 @@ parse_typedef(Eo_Lexer *ls)
Eolian_Typedecl *def = eo_lexer_typedecl_new(ls);
Eina_Strbuf *buf;
eo_lexer_get(ls);
- Eina_Bool has_extern = EINA_FALSE, has_beta = EINA_FALSE;
+ Eina_Stringshare *cname = NULL;
+ Eina_Bool has_extern = EINA_FALSE, has_beta = EINA_FALSE, has_c_name = EINA_FALSE;
for (;;) switch (ls->t.kw)
{
case KW_at_extern:
@@ -765,6 +802,11 @@ parse_typedef(Eo_Lexer *ls)
def->base.is_beta = EINA_TRUE;
eo_lexer_get(ls);
break;
+ case KW_at_c_name:
+ CASE_LOCK(ls, c_name, "@c_name specifier");
+ cname = parse_c_name(ls);
+ eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_stringshare_del), (void *)cname);
+ break;
default:
goto tags_done;
}
@@ -776,7 +818,13 @@ tags_done:
FILL_BASE(def->base, ls, ls->line_number, ls->column, TYPEDECL);
parse_name(ls, buf);
def->base.name = eina_stringshare_add(eina_strbuf_string_get(buf));
- def->base.c_name = make_c_name(def->base.name);
+ if (cname)
+ {
+ def->base.c_name = cname;
+ eo_lexer_dtor_pop(ls);
+ }
+ else
+ def->base.c_name = make_c_name(def->base.name);
Eolian_Object *decl = _eolian_decl_get(ls, def->base.name);
if (decl)
{
@@ -798,7 +846,8 @@ parse_variable(Eo_Lexer *ls, Eina_Bool global)
Eolian_Variable *def = eo_lexer_variable_new(ls);
Eina_Strbuf *buf;
eo_lexer_get(ls);
- Eina_Bool has_extern = EINA_FALSE, has_beta = EINA_FALSE;
+ Eina_Stringshare *cname = NULL;
+ Eina_Bool has_extern = EINA_FALSE, has_beta = EINA_FALSE, has_c_name = EINA_FALSE;
for (;;) switch (ls->t.kw)
{
case KW_at_extern:
@@ -811,6 +860,11 @@ parse_variable(Eo_Lexer *ls, Eina_Bool global)
def->base.is_beta = EINA_TRUE;
eo_lexer_get(ls);
break;
+ case KW_at_c_name:
+ CASE_LOCK(ls, c_name, "@c_name specifier");
+ cname = parse_c_name(ls);
+ eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_stringshare_del), (void *)cname);
+ break;
default:
goto tags_done;
}
@@ -822,7 +876,13 @@ tags_done:
FILL_BASE(def->base, ls, ls->line_number, ls->column, VARIABLE);
parse_name(ls, buf);
def->base.name = eina_stringshare_add(eina_strbuf_string_get(buf));
- def->base.c_name = make_c_name(def->base.name);
+ if (cname)
+ {
+ def->base.c_name = cname;
+ eo_lexer_dtor_pop(ls);
+ }
+ else
+ def->base.c_name = make_c_name(def->base.name);
Eolian_Object *decl = _eolian_decl_get(ls, def->base.name);
if (decl)
{
@@ -1236,8 +1296,10 @@ parse_function_pointer(Eo_Lexer *ls)
eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), buf);
Eolian_Function *meth = NULL;
+ Eina_Stringshare *cname = NULL;
Eina_Bool has_params = EINA_FALSE,
- has_return = EINA_FALSE;
+ has_return = EINA_FALSE,
+ has_c_name = EINA_FALSE;
eo_lexer_get(ls);
@@ -1255,13 +1317,24 @@ parse_function_pointer(Eo_Lexer *ls)
def->base.is_beta = EINA_TRUE;
eo_lexer_get(ls);
break;
+ case KW_at_c_name:
+ CASE_LOCK(ls, c_name, "@c_name specifier");
+ cname = parse_c_name(ls);
+ eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_stringshare_del), (void *)cname);
+ break;
default:
goto tags_done;
}
tags_done:
parse_name(ls, buf);
def->base.name = eina_stringshare_add(eina_strbuf_string_get(buf));
- def->base.c_name = make_c_name(def->base.name);
+ if (cname)
+ {
+ def->base.c_name = cname;
+ eo_lexer_dtor_pop(ls);
+ }
+ else
+ def->base.c_name = make_c_name(def->base.name);
eo_lexer_dtor_pop(ls);
meth = calloc(1, sizeof(Eolian_Function));
@@ -2035,11 +2108,24 @@ parse_class(Eo_Lexer *ls, Eolian_Class_Type type)
eo_lexer_get(ls);
ls->klass->type = type;
eo_lexer_context_push(ls);
- if (ls->t.kw == KW_at_beta)
+ Eina_Stringshare *cname = NULL;
+ Eina_Bool has_beta = EINA_FALSE, has_c_name = EINA_FALSE;
+ for (;;) switch (ls->t.kw)
{
+ case KW_at_beta:
+ CASE_LOCK(ls, beta, "beta qualifier");
ls->klass->base.is_beta = EINA_TRUE;
eo_lexer_get(ls);
+ break;
+ case KW_at_c_name:
+ CASE_LOCK(ls, c_name, "@c_name specifier");
+ cname = parse_c_name(ls);
+ eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_stringshare_del), (void *)cname);
+ break;
+ default:
+ goto tags_done;
}
+tags_done:
parse_name(ls, buf);
bnm = eina_stringshare_ref(ls->filename);
fnm = database_class_to_filename(eina_strbuf_string_get(buf));
@@ -2052,7 +2138,13 @@ parse_class(Eo_Lexer *ls, Eolian_Class_Type type)
eo_lexer_syntax_error(ls, "class and file names differ");
}
ls->klass->base.name = eina_stringshare_add(eina_strbuf_string_get(buf));
- ls->klass->base.c_name = make_c_name(ls->klass->base.name);
+ if (cname)
+ {
+ ls->klass->base.c_name = cname;
+ eo_lexer_dtor_pop(ls);
+ }
+ else
+ ls->klass->base.c_name = make_c_name(ls->klass->base.name);
Eolian_Object *decl = _eolian_decl_get(ls, ls->klass->base.name);
if (decl)
{
@@ -2187,10 +2279,11 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot)
Eina_Bool is_enum = (ls->t.kw == KW_enum);
const char *name;
int line, col;
- const char *freefunc = NULL;
+ const char *freefunc = NULL, *cname = NULL;
Eina_Strbuf *buf;
eo_lexer_get(ls);
- Eina_Bool has_extern = EINA_FALSE, has_free = EINA_FALSE, has_beta = EINA_FALSE;
+ Eina_Bool has_extern = EINA_FALSE, has_free = EINA_FALSE,
+ has_beta = EINA_FALSE, has_c_name = EINA_FALSE;
for (;;) switch (ls->t.kw)
{
case KW_at_extern:
@@ -2201,6 +2294,11 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot)
CASE_LOCK(ls, beta, "@beta qualifier")
eo_lexer_get(ls);
break;
+ case KW_at_c_name:
+ CASE_LOCK(ls, c_name, "@c_name specifier");
+ cname = parse_c_name(ls);
+ eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_stringshare_del), (void *)cname);
+ break;
case KW_at_free:
{
CASE_LOCK(ls, free, "@free qualifier")
@@ -2247,12 +2345,20 @@ postparams:
def->base.is_beta = has_beta;
def->type = EOLIAN_TYPEDECL_STRUCT_OPAQUE;
if (freefunc)
+ def->freefunc = eina_stringshare_ref(freefunc);
+ def->base.name = name;
+ if (cname)
+ def->base.c_name = cname;
+ /* we can't know the order, pop when both are filled */
+ if (freefunc && cname)
{
- def->freefunc = eina_stringshare_ref(freefunc);
+ eo_lexer_dtor_pop(ls);
eo_lexer_dtor_pop(ls);
}
- def->base.name = name;
- def->base.c_name = make_c_name(name);
+ else if (freefunc || cname)
+ eo_lexer_dtor_pop(ls);
+ if (!def->base.c_name)
+ def->base.c_name = make_c_name(name);
eo_lexer_get(ls);
FILL_DOC(ls, def, doc);
FILL_BASE(def->base, ls, line, col, TYPEDECL);
@@ -2260,9 +2366,9 @@ postparams:
break;
}
if (is_enum)
- parse_enum(ls, name, has_extern, has_beta, line, col);
+ parse_enum(ls, name, has_extern, has_beta, line, col, cname);
else
- parse_struct(ls, name, has_extern, has_beta, line, col, freefunc);
+ parse_struct(ls, name, has_extern, has_beta, line, col, freefunc, cname);
break;
}
def: