eolian: add API to retrieve the C name of an object

This is to prepare for type/class renaming support. This adds
the necessary API to retrieve C-specific names. Other refactoring
is necessary elsewhere for now.

This also renames the old API eolian_class_c_name_get to
eolian_class_c_macro_get to avoid conflict as well as clarify
the intention.
This commit is contained in:
Daniel Kolesa 2019-05-16 15:31:37 +02:00
parent 7f45f94af0
commit 4ab1f2388e
15 changed files with 141 additions and 19 deletions

View File

@ -205,7 +205,7 @@ eo_gen_header_gen(const Eolian_State *state, const Eolian_Class *cl,
}
}
Eina_Stringshare *mname = eolian_class_c_name_get(cl);
Eina_Stringshare *mname = eolian_class_c_macro_get(cl);
Eina_Stringshare *gname = eolian_class_c_get_function_name_get(cl);
eina_strbuf_append_printf(buf, "#define %s %s()\n\n", mname, gname);
eina_stringshare_del(mname);

View File

@ -1163,14 +1163,14 @@ eo_gen_source_gen(const Eolian_Class *cl, Eina_Strbuf *buf)
eina_strbuf_append(buf, ", NULL");
else
{
Eina_Stringshare *mname = eolian_class_c_name_get(icl);
Eina_Stringshare *mname = eolian_class_c_macro_get(icl);
eina_strbuf_append_printf(buf, ", %s", mname);
eina_stringshare_del(mname);
}
Eina_Iterator *itr = eolian_class_extensions_get(cl);
EINA_ITERATOR_FOREACH(itr, icl)
{
Eina_Stringshare *mname = eolian_class_c_name_get(icl);
Eina_Stringshare *mname = eolian_class_c_macro_get(icl);
eina_strbuf_append_printf(buf, ", %s", mname);
eina_stringshare_del(mname);
}
@ -1342,7 +1342,7 @@ _gen_proto(const Eolian_Class *cl, const Eolian_Function *fid,
if (!strcmp(efname + strlen(efname) - sizeof("destructor") + 1, "destructor"))
{
Eina_Stringshare *fcn = eolian_function_full_c_name_get(fid, ftype);
Eina_Stringshare *mname = eolian_class_c_name_get(cl);
Eina_Stringshare *mname = eolian_class_c_macro_get(cl);
eina_strbuf_append(buf, " ");
eina_strbuf_append(buf, fcn);
eina_stringshare_del(fcn);

View File

@ -301,6 +301,7 @@ ffi.cdef [[
int eolian_object_line_get(const Eolian_Object *obj);
int eolian_object_column_get(const Eolian_Object *obj);
const char *eolian_object_name_get(const Eolian_Object *obj);
const char *eolian_object_c_name_get(const Eolian_Object *obj);
const char *eolian_object_short_name_get(const Eolian_Object *obj);
Eina_Iterator *eolian_object_namespaces_get(const Eolian_Object *obj);
Eina_Bool eolian_object_is_beta(const Eolian_Object *obj);
@ -409,7 +410,7 @@ ffi.cdef [[
const char *eolian_class_c_get_function_name_get(const Eolian_Class *klass);
Eolian_Type_Type eolian_type_type_get(const Eolian_Type *tp);
Eolian_Type_Builtin_Type eolian_type_builtin_type_get(const Eolian_Type *tp);
const char *eolian_class_c_name_get(const Eolian_Class *klass);
const char *eolian_class_c_macro_get(const Eolian_Class *klass);
const char *eolian_class_c_data_type_get(const Eolian_Class *klass);
Eolian_Typedecl_Type eolian_typedecl_type_get(const Eolian_Typedecl *tp);
Eina_Iterator *eolian_typedecl_struct_fields_get(const Eolian_Typedecl *tp);
@ -587,6 +588,14 @@ local object_idx, wrap_object = gen_wrap {
return ffi.string(v)
end,
c_name_get = function(self)
local v = eolian.eolian_object_c_name_get(cast_obj(self))
if v == nil then
return nil
end
return ffi.string(v)
end,
short_name_get = function(self)
local v = eolian.eolian_object_short_name_get(cast_obj(self))
if v == nil then
@ -1510,8 +1519,8 @@ M.Class = ffi.metatype("Eolian_Class", {
return ffi_stringshare(v)
end,
c_name_get = function(self)
local v = eolian.eolian_class_c_name_get(self)
c_macro_get = function(self)
local v = eolian.eolian_class_c_macro_get(self)
if v == nil then return nil end
return ffi_stringshare(v)
end,

View File

@ -586,6 +586,7 @@ EAPI void *eolian_state_error_data_set(Eolian_State *state, void *data);
* @see eolian_object_line_get
* @see eolian_object_column_get
* @see eolian_object_name_get
* @see eolian_object_c_name_get
*
* @ingroup Eolian
*/
@ -601,6 +602,7 @@ EAPI Eolian_Object_Type eolian_object_type_get(const Eolian_Object *obj);
* @see eolian_object_line_get
* @see eolian_object_column_get
* @see eolian_object_name_get
* @see eolian_object_c_name_get
*
* @ingroup Eolian
*/
@ -617,6 +619,7 @@ EAPI const Eolian_Unit *eolian_object_unit_get(const Eolian_Object *obj);
* @see eolian_object_line_get
* @see eolian_object_column_get
* @see eolian_object_name_get
* @see eolian_object_c_name_get
*
* @ingroup Eolian
*/
@ -632,6 +635,7 @@ EAPI const char *eolian_object_file_get(const Eolian_Object *obj);
* @see eolian_object_file_get
* @see eolian_object_column_get
* @see eolian_object_name_get
* @see eolian_object_c_name_get
*
* @ingroup Eolian
*/
@ -650,6 +654,7 @@ EAPI int eolian_object_line_get(const Eolian_Object *obj);
* @see eolian_object_file_get
* @see eolian_object_line_get
* @see eolian_object_name_get
* @see eolian_object_c_name_get
*
* @ingroup Eolian
*/
@ -669,11 +674,34 @@ EAPI int eolian_object_column_get(const Eolian_Object *obj);
* @see eolian_object_column_get
* @see eolian_object_short_name_get
* @see eolian_object_namespaces_get
* @see eolian_object_c_name_get
*
* @ingroup Eolian
*/
EAPI const char *eolian_object_name_get(const Eolian_Object *obj);
/*
* @brief Get the C name of an object.
*
* This is the full name, but for C. It is typically derived from the
* regular full name, with namespaces flattened to underscores, but
* some things may be explicitly renamed. Only classes, types (both
* declarations and instances) and variables have C names, as others
* are never referred to by name directly in C.
*
* @see eolian_object_unit_get
* @see eolian_object_type_get
* @see eolian_object_file_get
* @see eolian_object_line_get
* @see eolian_object_column_get
* @see eolian_object_short_name_get
* @see eolian_object_namespaces_get
* @see eolian_object_name_get
*
* @ingroup Eolian
*/
EAPI const char *eolian_object_c_name_get(const Eolian_Object *obj);
/*
* @brief Get the short name of an object.
*
@ -1391,6 +1419,19 @@ eolian_class_name_get(const Eolian_Class *klass)
return eolian_object_name_get(EOLIAN_OBJECT(klass));
}
/*
* @brief A helper function to get the C name of a class.
*
* @see eolian_object_c_name_get
*
* @ingroup Eolian
*/
static inline const char *
eolian_class_c_name_get(const Eolian_Class *klass)
{
return eolian_object_c_name_get(EOLIAN_OBJECT(klass));
}
/*
* @brief A helper function to get the short name of a class.
*
@ -2278,12 +2319,12 @@ EAPI Eina_Bool eolian_class_dtor_enable_get(const Eolian_Class *klass);
EAPI Eina_Stringshare *eolian_class_c_get_function_name_get(const Eolian_Class *klass);
/*
* @brief Get the C name of the class.
* @brief Get the C macro of the class.
*
* @param[in] klass the class
* @return the C name
* @return the C symbol
*
* The C name is the name of the macro the class is accessed through, in format
* This is the name by which the class is accessed in C environment, in format
* CLASS_NAME_SUFFIX where SUFFIX is CLASS, MIXIN or INTERFACE. You're responsible
* for the stringshare afterwards.
*
@ -2291,7 +2332,7 @@ EAPI Eina_Stringshare *eolian_class_c_get_function_name_get(const Eolian_Class *
*
* @ingroup Eolian
*/
EAPI Eina_Stringshare *eolian_class_c_name_get(const Eolian_Class *klass);
EAPI Eina_Stringshare *eolian_class_c_macro_get(const Eolian_Class *klass);
/*
* @brief Get the C data type of the class.
@ -2559,6 +2600,19 @@ eolian_typedecl_name_get(const Eolian_Typedecl *tp)
return eolian_object_name_get(EOLIAN_OBJECT(tp));
}
/*
* @brief A helper function to get the C name of a typedecl.
*
* @see eolian_object_c_name_get
*
* @ingroup Eolian
*/
static inline const char *
eolian_typedecl_c_name_get(const Eolian_Typedecl *tp)
{
return eolian_object_c_name_get(EOLIAN_OBJECT(tp));
}
/*
* @brief A helper function to get the short name of a typedecl.
*
@ -2754,6 +2808,19 @@ eolian_type_name_get(const Eolian_Type *tp)
return eolian_object_name_get(EOLIAN_OBJECT(tp));
}
/*
* @brief A helper function to get the C name of a type.
*
* @see eolian_object_c_name_get
*
* @ingroup Eolian
*/
static inline const char *
eolian_type_c_name_get(const Eolian_Type *tp)
{
return eolian_object_c_name_get(EOLIAN_OBJECT(tp));
}
/*
* @brief A helper function to get the short name of a type.
*
@ -2997,6 +3064,19 @@ eolian_variable_name_get(const Eolian_Variable *tp)
return eolian_object_name_get(EOLIAN_OBJECT(tp));
}
/*
* @brief A helper function to get the C name of a variable.
*
* @see eolian_object_c_name_get
*
* @ingroup Eolian
*/
static inline const char *
eolian_variable_c_name_get(const Eolian_Variable *tp)
{
return eolian_object_c_name_get(EOLIAN_OBJECT(tp));
}
/*
* @brief A helper function to get the short name of a variable.
*

View File

@ -18,6 +18,7 @@ database_class_del(Eolian_Class *cl)
eina_stringshare_del(cl->base.file);
eina_stringshare_del(cl->base.name);
eina_stringshare_del(cl->base.c_name);
EINA_LIST_FREE(cl->implements, impl)
database_implement_del(impl);

View File

@ -178,7 +178,7 @@ eolian_class_c_get_function_name_get(const Eolian_Class *cl)
}
EAPI Eina_Stringshare *
eolian_class_c_name_get(const Eolian_Class *cl)
eolian_class_c_macro_get(const Eolian_Class *cl)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(cl, NULL);
Eina_Stringshare *ret;

View File

@ -11,6 +11,7 @@ database_type_del(Eolian_Type *tp)
if (!tp || eolian_object_unref(&tp->base)) return;
eina_stringshare_del(tp->base.file);
eina_stringshare_del(tp->base.name);
eina_stringshare_del(tp->base.c_name);
database_type_del(tp->base_type);
database_type_del(tp->next_type);
if (tp->freefunc) eina_stringshare_del(tp->freefunc);
@ -23,6 +24,7 @@ database_typedecl_del(Eolian_Typedecl *tp)
if (!tp || eolian_object_unref(&tp->base)) return;
eina_stringshare_del(tp->base.file);
eina_stringshare_del(tp->base.name);
eina_stringshare_del(tp->base.c_name);
database_type_del(tp->base_type);
if (tp->fields) eina_hash_free(tp->fields);
if (tp->field_list) eina_list_free(tp->field_list);

View File

@ -11,6 +11,7 @@ database_var_del(Eolian_Variable *var)
if (!var || eolian_object_unref(&var->base)) return;
eina_stringshare_del(var->base.file);
eina_stringshare_del(var->base.name);
eina_stringshare_del(var->base.c_name);
if (var->base_type)
database_type_del(var->base_type);
if (var->value) database_expr_del(var->value);

View File

@ -98,6 +98,17 @@ check_match(Eo_Lexer *ls, int what, int who, int where, int col)
}
}
static Eina_Stringshare *
make_c_name(const char *fulln)
{
char *mbuf = strdup(fulln);
for (char *p = mbuf; (p = strchr(p, '.')); ++p)
*p = '_';
Eina_Stringshare *ret = eina_stringshare_add(mbuf);
free(mbuf);
return ret;
}
static Eina_Bool
compare_class_file(const char *fn1, const char *fn2)
{
@ -440,6 +451,7 @@ parse_struct(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
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)
@ -499,6 +511,7 @@ parse_enum(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
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_ENUM;
def->fields = eina_hash_string_small_new(EINA_FREE_CB(_enum_field_free));
check_next(ls, '{');
@ -672,6 +685,7 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ptr)
{
def->btype = ls->t.kw - KW_byte + 1;
def->base.name = eina_stringshare_ref(ls->t.value.s);
def->base.c_name = eina_stringshare_ref(def->base.name);
eo_lexer_get(ls);
if ((tpid >= KW_accessor && tpid <= KW_list) ||
(tpid >= KW_slice && tpid <= KW_rw_slice))
@ -723,6 +737,7 @@ 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);
}
@ -760,6 +775,7 @@ 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);
Eolian_Object *decl = _eolian_decl_get(ls, def->base.name);
if (decl)
{
@ -805,6 +821,7 @@ 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);
Eolian_Object *decl = _eolian_decl_get(ls, def->base.name);
if (decl)
{
@ -1257,6 +1274,7 @@ parse_function_pointer(Eo_Lexer *ls)
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);
eo_lexer_dtor_pop(ls);
meth = calloc(1, sizeof(Eolian_Function));
@ -2047,6 +2065,7 @@ 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);
Eolian_Object *decl = _eolian_decl_get(ls, ls->klass->base.name);
if (decl)
{
@ -2246,6 +2265,7 @@ postparams:
eo_lexer_dtor_pop(ls);
}
def->base.name = 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);

View File

@ -60,6 +60,13 @@ eolian_object_name_get(const Eolian_Object *obj)
return obj->name;
}
EAPI const char *
eolian_object_c_name_get(const Eolian_Object *obj)
{
if (!obj) return NULL;
return obj->c_name;
}
typedef struct _Eolian_Namespace_List
{
Eina_Iterator itr;

View File

@ -85,6 +85,7 @@ struct _Eolian_Object
Eolian_Unit *unit;
Eina_Stringshare *file;
Eina_Stringshare *name;
Eina_Stringshare *c_name;
int line;
int column;
int refcount;

View File

@ -636,8 +636,8 @@ class Class(Object):
return "<eolian.Class '{0.name}', {0.type!s}>".format(self)
@cached_property
def c_name(self):
s = lib.eolian_class_c_name_get(self)
def c_macro(self):
s = lib.eolian_class_c_macro_get(self)
ret = _str_to_py(s)
lib.eina_stringshare_del(c_void_p(s))
return ret

View File

@ -306,9 +306,9 @@ lib.eolian_class_dtor_enable_get.restype = c_bool
lib.eolian_class_c_get_function_name_get.argtypes = (c_void_p,)
lib.eolian_class_c_get_function_name_get.restype = c_void_p # Stringshare TO BE FREED
# EAPI Eina_Stringshare *eolian_class_c_name_get(const Eolian_Class *klass);
lib.eolian_class_c_name_get.argtypes = (c_void_p,)
lib.eolian_class_c_name_get.restype = c_void_p # Stringshare TO BE FREED
# EAPI Eina_Stringshare *eolian_class_c_macro_get(const Eolian_Class *klass);
lib.eolian_class_c_macro_get.argtypes = (c_void_p,)
lib.eolian_class_c_macro_get.restype = c_void_p # Stringshare TO BE FREED
# EAPI Eina_Stringshare *eolian_class_c_data_type_get(const Eolian_Class *klass);
lib.eolian_class_c_data_type_get.argtypes = (c_void_p,)

View File

@ -333,7 +333,7 @@ class TestEolianClass(unittest.TestCase):
self.assertFalse(cls.ctor_enable)
self.assertFalse(cls.dtor_enable)
self.assertEqual(cls.c_get_function_name, 'efl_loop_timer_class_get')
self.assertEqual(cls.c_name, 'EFL_LOOP_TIMER_CLASS')
self.assertEqual(cls.c_macro, 'EFL_LOOP_TIMER_CLASS')
self.assertEqual(cls.c_data_type, 'Efl_Loop_Timer_Data')
self.assertEqual([f.name for f in cls.methods], ['reset','loop_reset','delay'])
self.assertEqual([f.name for f in cls.properties], ['interval','pending'])

View File

@ -575,9 +575,10 @@ EFL_START_TEST(eolian_simple_parsing)
eina_stringshare_del(string);
/* c name */
fail_if(!(string = eolian_class_c_name_get(class)));
fail_if(!(string = eolian_class_c_macro_get(class)));
fail_if(strcmp(string, "CLASS_SIMPLE_CLASS"));
eina_stringshare_del(string);
fail_if(strcmp(eolian_class_c_name_get(class), "Class_Simple"));
/* Property */
fail_if(!(fid = eolian_class_function_by_name_get(class, "a", EOLIAN_PROPERTY)));