forked from enlightenment/efl
Merging 'devs/q66/eolian_experimental'
This gets in several changes - such as new eolian API for deduplication of names, support for eot files and processing of classes and typedefs in sequence.
This commit is contained in:
commit
8d6e47107b
|
@ -57,6 +57,7 @@ getopt.parse {
|
|||
for i, v in ipairs(opts["I"] or {}) do
|
||||
lualian.include_dir(v)
|
||||
end
|
||||
lualian.load_eot_files()
|
||||
for i, fname in ipairs(args) do
|
||||
gen_file(opts, i, fname)
|
||||
end
|
||||
|
|
|
@ -122,20 +122,6 @@ local typeconv = function(tps, expr, isin)
|
|||
return build_calln(tps, expr, false)
|
||||
end
|
||||
|
||||
local dedup_name = function(classn, funcn)
|
||||
local suffix = classn:match(".+_(.+)" ) or classn
|
||||
local prefix = funcn:match("([^_]+)_.+") or funcn
|
||||
if prefix == suffix then
|
||||
if classn == suffix then
|
||||
return funcn
|
||||
else
|
||||
return classn:match("(.+_).+") .. funcn
|
||||
end
|
||||
else
|
||||
return classn .. "_" .. funcn
|
||||
end
|
||||
end
|
||||
|
||||
local Node = util.Object:clone {
|
||||
generate = function(self, s)
|
||||
end,
|
||||
|
@ -184,7 +170,7 @@ local Method = Node:clone {
|
|||
local allocs = {}
|
||||
proto.allocs = allocs
|
||||
|
||||
proto.full_name = dedup_name(self.parent_node.prefix, proto.name)
|
||||
proto.full_name = meth:full_c_name_get(self.parent_node.prefix)
|
||||
|
||||
local dirs = eolian.parameter_dir
|
||||
|
||||
|
@ -280,7 +266,7 @@ local Property = Method:clone {
|
|||
local allocs = {}
|
||||
proto.allocs = allocs
|
||||
|
||||
proto.full_name = dedup_name(self.parent_node.prefix, proto.name)
|
||||
proto.full_name = prop:full_c_name_get(self.parent_node.prefix)
|
||||
.. proto.suffix
|
||||
|
||||
local dirs = eolian.parameter_dir
|
||||
|
@ -691,6 +677,10 @@ M.include_dir = function(dir)
|
|||
end
|
||||
end
|
||||
|
||||
M.load_eot_files = function()
|
||||
return eolian.all_eot_files_parse()
|
||||
end
|
||||
|
||||
M.generate = function(fname, modname, libname, fstream)
|
||||
if not eolian.eo_file_parse(fname) then
|
||||
error("Failed parsing file: " .. fname)
|
||||
|
|
|
@ -50,7 +50,8 @@ _class_env_create(const Eolian_Class class, const char *over_classname, _eolian_
|
|||
void
|
||||
_class_func_env_create(const Eolian_Class class, const char *funcname, Eolian_Function_Type ftype, _eolian_class_func_vars *env)
|
||||
{
|
||||
char *p, *ret;
|
||||
char *p;
|
||||
const char *ret;
|
||||
const char *suffix = "";
|
||||
const char *legacy = NULL;
|
||||
Eolian_Function funcid = eolian_class_function_find_by_name(class, funcname, ftype);
|
||||
|
@ -72,15 +73,15 @@ _class_func_env_create(const Eolian_Class class, const char *funcname, Eolian_Fu
|
|||
p = strncpy(env->upper_func, funcname, PATH_MAX - 1);
|
||||
eina_str_toupper(&p);
|
||||
|
||||
ret = _func_name_dedup(tmp_env.upper_eo_prefix, funcname);
|
||||
ret = eolian_function_full_c_name_get(funcid, tmp_env.upper_eo_prefix);
|
||||
sprintf(p = env->upper_eo_func, "%s%s", ret, suffix);
|
||||
eina_str_toupper(&p);
|
||||
free(ret);
|
||||
eina_stringshare_del(ret);
|
||||
|
||||
ret = _func_name_dedup(tmp_env.lower_eo_prefix, funcname);
|
||||
ret = eolian_function_full_c_name_get(funcid, tmp_env.lower_eo_prefix);
|
||||
sprintf(p = env->lower_eo_func, "%s%s", ret, suffix);
|
||||
eina_str_tolower(&p);
|
||||
free(ret);
|
||||
eina_stringshare_del(ret);
|
||||
|
||||
env->legacy_func[0] = '\0';
|
||||
if (legacy && !strcmp(legacy, "null")) goto end;
|
||||
|
@ -164,36 +165,3 @@ _source_desc_get(const char *str)
|
|||
eina_strbuf_free(part);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
_func_name_dedup(const char *classn, const char *funcn)
|
||||
{
|
||||
const char *last_p = strrchr(classn, '_');
|
||||
const char *func_p = strchr(funcn, '_');
|
||||
Eina_Strbuf *buf = eina_strbuf_new();
|
||||
int len;
|
||||
char *ret;
|
||||
|
||||
if (!last_p) last_p = classn;
|
||||
else last_p++;
|
||||
if (!func_p) len = strlen(funcn);
|
||||
else len = func_p - funcn;
|
||||
|
||||
if ((int)strlen(last_p) != len || strncmp(last_p, funcn, len))
|
||||
{
|
||||
eina_strbuf_append(buf, classn);
|
||||
eina_strbuf_append_char(buf, '_');
|
||||
eina_strbuf_append(buf, funcn);
|
||||
ret = eina_strbuf_string_steal(buf);
|
||||
eina_strbuf_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (last_p != classn)
|
||||
eina_strbuf_append_n(buf, classn, last_p - classn); /* includes _ */
|
||||
|
||||
eina_strbuf_append(buf, funcn);
|
||||
ret = eina_strbuf_string_steal(buf);
|
||||
eina_strbuf_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -66,6 +66,4 @@ void _class_env_create(const Eolian_Class class, const char *over_classname, _eo
|
|||
|
||||
void _class_func_env_create(const Eolian_Class class, const char *funcname, Eolian_Function_Type ftype EINA_UNUSED, _eolian_class_func_vars *env);
|
||||
|
||||
char *_func_name_dedup(const char *classn, const char *funcn);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -597,8 +597,8 @@ eo_source_end_generate(const Eolian_Class class, Eina_Strbuf *buf)
|
|||
Eolian_Function_Type ftype;
|
||||
Eolian_Function fnid = NULL;
|
||||
const char *funcname = NULL;
|
||||
const char *ret;
|
||||
char *tp = implname;
|
||||
char *ret;
|
||||
|
||||
if (eolian_implement_information_get(impl_desc, &impl_class, &fnid, &ftype))
|
||||
{
|
||||
|
@ -616,7 +616,7 @@ eo_source_end_generate(const Eolian_Class class, Eina_Strbuf *buf)
|
|||
goto end;
|
||||
}
|
||||
|
||||
ret = _func_name_dedup(impl_env.lower_eo_prefix, funcname);
|
||||
ret = eolian_function_full_c_name_get(fnid, impl_env.lower_eo_prefix);
|
||||
switch (ftype)
|
||||
{
|
||||
case EOLIAN_PROP_SET: case EOLIAN_PROP_GET: case EOLIAN_PROPERTY:
|
||||
|
@ -640,7 +640,7 @@ eo_source_end_generate(const Eolian_Class class, Eina_Strbuf *buf)
|
|||
eo_bind_func_generate(class, fnid, ftype, str_bodyf, &impl_env);
|
||||
break;
|
||||
}
|
||||
free(ret);
|
||||
eina_stringshare_del(ret);
|
||||
}
|
||||
|
||||
//Constructors
|
||||
|
|
|
@ -321,6 +321,8 @@ int main(int argc, char **argv)
|
|||
goto end;
|
||||
}
|
||||
|
||||
eolian_all_eot_files_parse();
|
||||
|
||||
const char *filename;
|
||||
EINA_LIST_FOREACH(files4gen, itr, filename)
|
||||
{
|
||||
|
|
|
@ -15,31 +15,11 @@
|
|||
#include "comments.hh"
|
||||
|
||||
static std::string
|
||||
_dedup_func_name(const std::string &classn, const std::string &funcn)
|
||||
_dedup_func_name(Eolian_Function func, const std::string &classn)
|
||||
{
|
||||
size_t last_p = classn.rfind('_');
|
||||
size_t func_p = funcn.find('_');
|
||||
std::string ret;
|
||||
size_t len;
|
||||
|
||||
if (last_p == std::string::npos) last_p = 0;
|
||||
else last_p++;
|
||||
if (func_p == std::string::npos) len = funcn.size();
|
||||
else len = func_p;
|
||||
|
||||
if ((classn.size() - last_p) != len
|
||||
|| classn.compare(last_p, len, funcn, 0, len))
|
||||
{
|
||||
ret += classn;
|
||||
ret += '_';
|
||||
ret += funcn;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (last_p)
|
||||
ret += classn.substr(0, last_p);
|
||||
|
||||
ret += funcn;
|
||||
const char *s = eolian_function_full_c_name_get(func, classn.c_str());
|
||||
std::string ret(s);
|
||||
eina_stringshare_del(s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -110,7 +90,7 @@ _get_properties(const Eolian_Class klass)
|
|||
efl::eolian::eo_function getter;
|
||||
getter.type = efl::eolian::eo_function::regular_;
|
||||
getter.name = name + "_get";
|
||||
getter.impl = _dedup_func_name((prefix != "" ? prefix : cxx_classname), getter.name);
|
||||
getter.impl = _dedup_func_name(property, (prefix != "" ? prefix : cxx_classname)) + "_get";
|
||||
std::string ret = safe_str
|
||||
(eolian_function_return_type_get(property, EOLIAN_PROP_GET));
|
||||
if (ret == "") ret = "void";
|
||||
|
@ -155,7 +135,7 @@ _get_properties(const Eolian_Class klass)
|
|||
efl::eolian::eo_function setter;
|
||||
setter.type = efl::eolian::eo_function::regular_;
|
||||
setter.name = name + "_set";
|
||||
setter.impl = _dedup_func_name((prefix != "" ? prefix : cxx_classname), setter.name);
|
||||
setter.impl = _dedup_func_name(property, (prefix != "" ? prefix : cxx_classname)) + "_set";
|
||||
setter.params = params;
|
||||
setter.ret = safe_str(eolian_function_return_type_get
|
||||
(property, EOLIAN_PROP_SET));
|
||||
|
@ -243,8 +223,8 @@ convert_eolian_constructors(efl::eolian::eo_class& cls, const Eolian_Class klass
|
|||
{
|
||||
Eolian_Function eolian_constructor = static_cast<Eolian_Function>(curr);
|
||||
efl::eolian::eo_constructor constructor;
|
||||
constructor.name = _dedup_func_name((prefix != "" ? prefix : cls.name),
|
||||
safe_str(eolian_function_name_get(eolian_constructor)));
|
||||
constructor.name = _dedup_func_name(eolian_constructor,
|
||||
(prefix != "" ? prefix : cls.name));
|
||||
constructor.params = _get_params
|
||||
(eolian_parameters_list_get(eolian_constructor));
|
||||
constructor.comment = detail::eolian_constructor_comment
|
||||
|
@ -269,7 +249,7 @@ convert_eolian_functions(efl::eolian::eo_class& cls, const Eolian_Class klass)
|
|||
// XXX Eolian only provides regular methods so far
|
||||
function.type = efl::eolian::eo_function::regular_;
|
||||
function.name = safe_str(eolian_function_name_get(eolian_function));
|
||||
function.impl = _dedup_func_name((prefix != "" ? prefix : cls.name), function.name);
|
||||
function.impl = _dedup_func_name(eolian_function, (prefix != "" ? prefix : cls.name));
|
||||
function.ret = safe_str(eolian_function_return_type_get
|
||||
(eolian_function, EOLIAN_METHOD));
|
||||
if(function.ret == "") function.ret = "void";
|
||||
|
|
|
@ -244,12 +244,29 @@ _resolve_classname(options_type& opts)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_scan_directories(options_type const& opts)
|
||||
{
|
||||
for (auto src : opts.in_srcs)
|
||||
{
|
||||
if (eina_str_has_suffix(src.c_str(), EO_SUFFIX)) continue;
|
||||
eolian_read_from_fs(src.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_load_eot()
|
||||
{
|
||||
eolian_all_eot_files_parse();
|
||||
}
|
||||
|
||||
static void
|
||||
_load_classes(options_type const& opts)
|
||||
{
|
||||
for (auto src : opts.in_srcs)
|
||||
{
|
||||
if (eolian_read_from_fs(src.c_str()) == NULL)
|
||||
if (!eina_str_has_suffix(src.c_str(), EO_SUFFIX)) continue;
|
||||
if ( eolian_read_from_fs(src.c_str()) == NULL)
|
||||
{
|
||||
EINA_CXX_DOM_LOG_WARN(::domain)
|
||||
<< "Couldn't load eolian file: " << src;
|
||||
|
@ -352,6 +369,8 @@ int main(int argc, char **argv)
|
|||
domain.set_level(efl::eina::log_level::debug);
|
||||
#endif
|
||||
options_type opts = _read_options(argc, argv);
|
||||
_scan_directories(opts);
|
||||
_load_eot();
|
||||
_load_classes(opts);
|
||||
_resolve_classname(opts);
|
||||
_validate_options(opts);
|
||||
|
|
|
@ -47,10 +47,12 @@ ffi.cdef [[
|
|||
} Eolian_Function_Scope;
|
||||
|
||||
Eina_Bool eolian_eo_file_parse(const char *filename);
|
||||
Eina_Bool eolian_eot_file_parse(const char *filepath);
|
||||
int eolian_init(void);
|
||||
int eolian_shutdown(void);
|
||||
Eina_Bool eolian_directory_scan(const char *dir);
|
||||
Eina_Bool eolian_all_eo_files_parse();
|
||||
Eina_Bool eolian_all_eot_files_parse();
|
||||
Eina_Bool eolian_show(const Eolian_Class *klass);
|
||||
Eolian_Class *eolian_class_find_by_name(const char *class_name);
|
||||
Eolian_Class *eolian_class_find_by_file(const char *file_name);
|
||||
|
@ -69,6 +71,7 @@ ffi.cdef [[
|
|||
Eolian_Function_Type eolian_function_type_get(Eolian_Function *function_id);
|
||||
Eolian_Function_Scope eolian_function_scope_get(Eolian_Function *function_id);
|
||||
const char *eolian_function_name_get(Eolian_Function *function_id);
|
||||
const char *eolian_function_full_c_name_get(Eolian_Function function_id, const char *prefix);
|
||||
Eolian_Function *eolian_class_function_find_by_name(const Eolian_Class *klass, const char *func_name, Eolian_Function_Type f_type);
|
||||
const char *eolian_function_data_get(Eolian_Function *function_id, const char *key);
|
||||
Eina_Bool eolian_function_is_virtual_pure(Eolian_Function *function_id, Eolian_Function_Type f_type);
|
||||
|
@ -134,6 +137,14 @@ M.eo_file_parse = function(fname)
|
|||
return eolian.eolian_eo_file_parse(fname) ~= 0
|
||||
end
|
||||
|
||||
M.all_eot_files_parse = function()
|
||||
return eolian.eolian_all_eot_files_parse() ~= 0
|
||||
end
|
||||
|
||||
M.eot_file_parse = function(fname)
|
||||
return eolian.eolian_eot_file_parse(fname) ~= 0
|
||||
end
|
||||
|
||||
M.show = function(klass)
|
||||
return eolian.eolian_show(klass) ~= 0
|
||||
end
|
||||
|
@ -180,6 +191,12 @@ M.Function = ffi.metatype("Eolian_Function", {
|
|||
return ffi.string(v)
|
||||
end,
|
||||
|
||||
full_c_name_get = function(self)
|
||||
local v = eolian.eolian_function_full_c_name_get(self)
|
||||
if v == nil then return nil end
|
||||
return ffi.string(v)
|
||||
end,
|
||||
|
||||
data_get = function(self, key)
|
||||
local v = eolian.eolian_function_data_get(self, key)
|
||||
if v == nil then return nil end
|
||||
|
|
|
@ -120,11 +120,22 @@ typedef enum
|
|||
* all the information related to this class.
|
||||
*
|
||||
* @param[in] filename Name of the file to parse.
|
||||
* @see eolian_eot_file_parse
|
||||
*
|
||||
* @ingroup Eolian
|
||||
*/
|
||||
EAPI Eina_Bool eolian_eo_file_parse(const char *filename);
|
||||
|
||||
/*
|
||||
* @brief Parse a given .eot file and fill the database.
|
||||
*
|
||||
* @param[in] filename Name of the file to parse.
|
||||
* @see eolian_eo_file_parse
|
||||
*
|
||||
* @ingroup Eolian
|
||||
*/
|
||||
EAPI Eina_Bool eolian_eot_file_parse(const char *filepath);
|
||||
|
||||
/*
|
||||
* @brief Init Eolian.
|
||||
*
|
||||
|
@ -140,7 +151,7 @@ EAPI int eolian_init(void);
|
|||
EAPI int eolian_shutdown(void);
|
||||
|
||||
/*
|
||||
* @brief Scan the given directory and search for .eo files.
|
||||
* @brief Scan the given directory and search for .eo and .eot files.
|
||||
*
|
||||
* The found files are just open to extract the class name.
|
||||
*
|
||||
|
@ -152,17 +163,31 @@ EAPI int eolian_shutdown(void);
|
|||
EAPI Eina_Bool eolian_directory_scan(const char *dir);
|
||||
|
||||
/*
|
||||
* @brief Force parsing of all the files located in the directories
|
||||
* @brief Force parsing of all the .eo files located in the directories
|
||||
* given in eolian_directory_scan..
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE otherwise.
|
||||
*
|
||||
* @see eolian_directory_scan
|
||||
* @see eolian_all_eot_files_parse
|
||||
*
|
||||
* @ingroup Eolian
|
||||
*/
|
||||
EAPI Eina_Bool eolian_all_eo_files_parse();
|
||||
|
||||
/*
|
||||
* @brief Force parsing of all the .eot files located in the directories
|
||||
* given in eolian_directory_scan..
|
||||
*
|
||||
* @return EINA_TRUE on success, EINA_FALSE otherwise.
|
||||
*
|
||||
* @see eolian_directory_scan
|
||||
* @see eolian_all_eo_files_parse
|
||||
*
|
||||
* @ingroup Eolian
|
||||
*/
|
||||
EAPI Eina_Bool eolian_all_eot_files_parse();
|
||||
|
||||
/*
|
||||
* @brief Show information about a given class.
|
||||
*
|
||||
|
@ -356,6 +381,19 @@ EAPI Eolian_Function_Scope eolian_function_scope_get(Eolian_Function function_id
|
|||
*/
|
||||
EAPI const char *eolian_function_name_get(Eolian_Function function_id);
|
||||
|
||||
/*
|
||||
* @brief Returns the full C name of a function (with prefix). It's here
|
||||
* because the C API names are deduplicated (prefix of function and suffix
|
||||
* of prefix merge if applicable) and this helps generators not write the
|
||||
* same code over and over.
|
||||
*
|
||||
* @param[in] function_id Id of the function
|
||||
* @return the function name
|
||||
*
|
||||
* @ingroup Eolian
|
||||
*/
|
||||
EAPI const char *eolian_function_full_c_name_get(Eolian_Function function_id, const char *prefix);
|
||||
|
||||
/*
|
||||
* @brief Find a function in a class by its name and type
|
||||
*
|
||||
|
|
|
@ -275,19 +275,28 @@ eo_lexer_set_input(Eo_Lexer *ls, const char *source)
|
|||
void
|
||||
eo_lexer_free(Eo_Lexer *ls)
|
||||
{
|
||||
Eo_Class_Def *kls;
|
||||
Eo_Type_Def *type;
|
||||
Eo_Node *nd;
|
||||
|
||||
if (!ls) return;
|
||||
if (ls->source) eina_stringshare_del(ls->source);
|
||||
if (ls->buff ) eina_strbuf_free (ls->buff);
|
||||
if (ls->handle) eina_file_close (ls->handle);
|
||||
|
||||
EINA_LIST_FREE(ls->classes, kls)
|
||||
eo_definitions_class_def_free(kls);
|
||||
|
||||
EINA_LIST_FREE(ls->typedefs, type)
|
||||
eo_definitions_type_def_free(type);
|
||||
EINA_LIST_FREE(ls->nodes, nd)
|
||||
{
|
||||
switch (nd->type)
|
||||
{
|
||||
case NODE_CLASS:
|
||||
eo_definitions_class_def_free(nd->def_class);
|
||||
break;
|
||||
case NODE_TYPEDEF:
|
||||
eo_definitions_type_def_free(nd->def_type);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
free(nd);
|
||||
}
|
||||
|
||||
eo_definitions_temps_free(&ls->tmp);
|
||||
|
||||
|
|
|
@ -42,6 +42,22 @@ typedef struct _Eo_Token
|
|||
int kw;
|
||||
} Eo_Token;
|
||||
|
||||
enum Nodes
|
||||
{
|
||||
NODE_CLASS = 0,
|
||||
NODE_TYPEDEF
|
||||
};
|
||||
|
||||
typedef struct _Eo_Node
|
||||
{
|
||||
unsigned char type;
|
||||
union {
|
||||
void *def;
|
||||
Eo_Class_Def *def_class;
|
||||
Eo_Type_Def *def_type;
|
||||
};
|
||||
} Eo_Node;
|
||||
|
||||
typedef struct _Eo_Lexer
|
||||
{
|
||||
int current;
|
||||
|
@ -54,8 +70,7 @@ typedef struct _Eo_Lexer
|
|||
const char *stream_end;
|
||||
jmp_buf err_jmp;
|
||||
|
||||
Eina_List *classes;
|
||||
Eina_List *typedefs;
|
||||
Eina_List *nodes;
|
||||
Eo_Lexer_Temps tmp;
|
||||
} Eo_Lexer;
|
||||
|
||||
|
|
|
@ -103,6 +103,15 @@ pop_strbuf(Eo_Lexer *ls)
|
|||
ls->tmp.str_bufs = eina_list_remove_list(ls->tmp.str_bufs, ls->tmp.str_bufs);
|
||||
}
|
||||
|
||||
static void
|
||||
append_node(Eo_Lexer *ls, int type, void *def)
|
||||
{
|
||||
Eo_Node *nd = calloc(1, sizeof(Eo_Node));
|
||||
nd->type = type;
|
||||
nd->def = def;
|
||||
ls->nodes = eina_list_append(ls->nodes, nd);
|
||||
}
|
||||
|
||||
static Eina_Strbuf *
|
||||
parse_name(Eo_Lexer *ls, Eina_Strbuf *buf)
|
||||
{
|
||||
|
@ -850,42 +859,49 @@ parse_class(Eo_Lexer *ls, Eina_Bool allow_ctors, Eolian_Class_Type type)
|
|||
}
|
||||
|
||||
static void
|
||||
parse_unit(Eo_Lexer *ls)
|
||||
parse_unit(Eo_Lexer *ls, Eina_Bool eot)
|
||||
{
|
||||
switch (ls->t.kw)
|
||||
{
|
||||
case KW_abstract:
|
||||
if (eot) goto def;
|
||||
parse_class(ls, EINA_TRUE, EOLIAN_CLASS_ABSTRACT);
|
||||
goto found_class;
|
||||
case KW_class:
|
||||
if (eot) goto def;
|
||||
parse_class(ls, EINA_TRUE, EOLIAN_CLASS_REGULAR);
|
||||
goto found_class;
|
||||
case KW_mixin:
|
||||
if (eot) goto def;
|
||||
parse_class(ls, EINA_FALSE, EOLIAN_CLASS_MIXIN);
|
||||
goto found_class;
|
||||
case KW_interface:
|
||||
if (eot) goto def;
|
||||
parse_class(ls, EINA_FALSE, EOLIAN_CLASS_INTERFACE);
|
||||
goto found_class;
|
||||
case KW_type:
|
||||
{
|
||||
parse_typedef(ls);
|
||||
ls->typedefs = eina_list_append(ls->typedefs, ls->tmp.type_def);
|
||||
append_node(ls, NODE_TYPEDEF, ls->tmp.type_def);
|
||||
ls->tmp.type_def = NULL;
|
||||
break;
|
||||
}
|
||||
def:
|
||||
default:
|
||||
eo_lexer_syntax_error(ls, "invalid token");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
found_class:
|
||||
ls->classes = eina_list_append(ls->classes, ls->tmp.kls);
|
||||
append_node(ls, NODE_CLASS, ls->tmp.kls);
|
||||
ls->tmp.kls = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_chunk(Eo_Lexer *ls)
|
||||
parse_chunk(Eo_Lexer *ls, Eina_Bool eot)
|
||||
{
|
||||
while (ls->t.token != TOK_EOF)
|
||||
parse_unit(ls);
|
||||
parse_unit(ls, eot);
|
||||
}
|
||||
|
||||
static char *_accessor_type_str[ACCESSOR_TYPE_LAST] = { "setter", "getter" };
|
||||
|
@ -908,14 +924,12 @@ _print_type(FILE *f, Eolian_Type tp)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
eo_parser_dump(Eo_Lexer *ls)
|
||||
static void
|
||||
_dump_class(Eo_Class_Def *kls)
|
||||
{
|
||||
const char *s;
|
||||
Eina_List *k, *l, *m;
|
||||
Eina_List *l, *m;
|
||||
|
||||
Eo_Type_Def *type;
|
||||
Eo_Class_Def *kls;
|
||||
Eo_Property_Def *prop;
|
||||
Eo_Method_Def *meth;
|
||||
Eo_Param_Def *param;
|
||||
|
@ -923,8 +937,6 @@ eo_parser_dump(Eo_Lexer *ls)
|
|||
Eo_Event_Def *sgn;
|
||||
Eo_Implement_Def *impl;
|
||||
|
||||
EINA_LIST_FOREACH(ls->classes, k, kls)
|
||||
{
|
||||
printf("Class: %s (%s)\n",
|
||||
kls->name, (kls->comment ? kls->comment : "-"));
|
||||
printf(" inherits from :");
|
||||
|
@ -938,7 +950,6 @@ eo_parser_dump(Eo_Lexer *ls)
|
|||
printf(" events:\n");
|
||||
EINA_LIST_FOREACH(kls->events, l, sgn)
|
||||
printf(" %s <%s> (%s)\n", sgn->name, sgn->type, sgn->comment);
|
||||
|
||||
EINA_LIST_FOREACH(kls->constructors, l, meth)
|
||||
{
|
||||
printf(" constructors: %s\n", meth->name);
|
||||
|
@ -1000,35 +1011,55 @@ eo_parser_dump(Eo_Lexer *ls)
|
|||
printf(" (%s)\n", param->comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(ls->typedefs, k, type)
|
||||
{
|
||||
static void
|
||||
_dump_type(Eo_Type_Def *type)
|
||||
{
|
||||
printf("Typedef: %s ", type->alias);
|
||||
_print_type(stdout, type->type);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
eo_parser_dump(Eo_Lexer *ls)
|
||||
{
|
||||
Eina_List *k;
|
||||
Eo_Node *nd;
|
||||
|
||||
EINA_LIST_FOREACH(ls->nodes, k, nd)
|
||||
{
|
||||
switch (nd->type)
|
||||
{
|
||||
case NODE_CLASS:
|
||||
_dump_class(nd->def_class);
|
||||
break;
|
||||
case NODE_TYPEDEF:
|
||||
_dump_type(nd->def_type);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
eo_parser_walk(Eo_Lexer *ls)
|
||||
eo_parser_walk(Eo_Lexer *ls, Eina_Bool eot)
|
||||
{
|
||||
if (!setjmp(ls->err_jmp))
|
||||
{
|
||||
parse_chunk(ls);
|
||||
parse_chunk(ls, eot);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
eo_parser_database_fill(const char *filename)
|
||||
static Eina_Bool
|
||||
_db_fill_class(Eo_Class_Def *kls, const char *filename)
|
||||
{
|
||||
const char *s;
|
||||
Eina_List *k, *l, *m;
|
||||
Eina_List *l, *m;
|
||||
|
||||
Eo_Class_Def *kls;
|
||||
Eo_Type_Def *type_def;
|
||||
Eo_Property_Def *prop;
|
||||
Eo_Method_Def *meth;
|
||||
Eo_Param_Def *param;
|
||||
|
@ -1036,31 +1067,6 @@ eo_parser_database_fill(const char *filename)
|
|||
Eo_Event_Def *event;
|
||||
Eo_Implement_Def *impl;
|
||||
|
||||
Eo_Lexer *ls = eo_lexer_new(filename);
|
||||
if (!ls)
|
||||
{
|
||||
ERR("unable to create lexer");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/* read first token */
|
||||
eo_lexer_get(ls);
|
||||
|
||||
if (!eo_parser_walk(ls))
|
||||
{
|
||||
eo_lexer_free(ls);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (!ls->classes)
|
||||
{
|
||||
ERR("No classes for file %s", filename);
|
||||
eo_lexer_free(ls);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(ls->classes, k, kls)
|
||||
{
|
||||
Eolian_Class class = database_class_add(kls->name, kls->type);
|
||||
Eina_Bool is_iface = (kls->type == EOLIAN_CLASS_INTERFACE);
|
||||
database_class_file_set(class, filename);
|
||||
|
@ -1228,7 +1234,6 @@ eo_parser_database_fill(const char *filename)
|
|||
if (!foo_id)
|
||||
{
|
||||
ERR("Error - %s not known in class %s", impl_name + 8, eolian_class_name_get(class));
|
||||
eo_lexer_free(ls);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
database_function_set_as_virtual_pure(foo_id, ftype);
|
||||
|
@ -1244,14 +1249,77 @@ eo_parser_database_fill(const char *filename)
|
|||
database_class_event_add(class, ev);
|
||||
}
|
||||
|
||||
}
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EINA_LIST_FOREACH(ls->typedefs, k, type_def)
|
||||
{
|
||||
static Eina_Bool
|
||||
_db_fill_type(Eo_Type_Def *type_def)
|
||||
{
|
||||
database_type_add(type_def->alias, type_def->type);
|
||||
type_def->type = NULL;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
eo_parser_database_fill(const char *filename, Eina_Bool eot)
|
||||
{
|
||||
Eina_List *k;
|
||||
Eo_Node *nd;
|
||||
Eina_Bool has_class = EINA_FALSE;
|
||||
|
||||
Eo_Lexer *ls = eo_lexer_new(filename);
|
||||
if (!ls)
|
||||
{
|
||||
ERR("unable to create lexer");
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
/* read first token */
|
||||
eo_lexer_get(ls);
|
||||
|
||||
if (!eo_parser_walk(ls, eot))
|
||||
{
|
||||
eo_lexer_free(ls);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (eot) goto nodeloop;
|
||||
|
||||
EINA_LIST_FOREACH(ls->nodes, k, nd) if (nd->type == NODE_CLASS)
|
||||
{
|
||||
has_class = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!has_class)
|
||||
{
|
||||
ERR("No classes for file %s", filename);
|
||||
eo_lexer_free(ls);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
nodeloop:
|
||||
EINA_LIST_FOREACH(ls->nodes, k, nd)
|
||||
{
|
||||
switch (nd->type)
|
||||
{
|
||||
case NODE_CLASS:
|
||||
if (!_db_fill_class(nd->def_class, filename))
|
||||
goto error;
|
||||
break;
|
||||
case NODE_TYPEDEF:
|
||||
if (!_db_fill_type(nd->def_type))
|
||||
goto error;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eo_lexer_free(ls);
|
||||
return EINA_TRUE;
|
||||
|
||||
error:
|
||||
eo_lexer_free(ls);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#include "eo_lexer.h"
|
||||
|
||||
Eina_Bool eo_parser_walk (Eo_Lexer *ls);
|
||||
void eo_parser_dump (Eo_Lexer *ls);
|
||||
Eina_Bool eo_parser_database_fill(const char *filename);
|
||||
Eina_Bool eo_parser_walk (Eo_Lexer *ls, Eina_Bool eot);
|
||||
Eina_Bool eo_parser_database_fill(const char *filename, Eina_Bool eot);
|
||||
|
||||
#endif /* __EO_PARSER_H__ */
|
|
@ -17,6 +17,7 @@
|
|||
static Eina_List *_classes = NULL;
|
||||
static Eina_Hash *_types = NULL;
|
||||
static Eina_Hash *_filenames = NULL; /* Hash: filename without extension -> full path */
|
||||
static Eina_Hash *_tfilenames = NULL;
|
||||
static int _database_init_count = 0;
|
||||
|
||||
typedef struct
|
||||
|
@ -177,6 +178,7 @@ database_init()
|
|||
eina_init();
|
||||
_types = eina_hash_stringshared_new(_type_hash_free_cb);
|
||||
_filenames = eina_hash_string_small_new(free);
|
||||
_tfilenames = eina_hash_string_small_new(free);
|
||||
return ++_database_init_count;
|
||||
}
|
||||
|
||||
|
@ -197,6 +199,7 @@ database_shutdown()
|
|||
_class_del((_Class_Desc *)class);
|
||||
eina_hash_free(_types);
|
||||
eina_hash_free(_filenames);
|
||||
eina_hash_free(_tfilenames);
|
||||
eina_shutdown();
|
||||
}
|
||||
return _database_init_count;
|
||||
|
@ -674,6 +677,40 @@ eolian_function_name_get(Eolian_Function function_id)
|
|||
return fid->name;
|
||||
}
|
||||
|
||||
EAPI const char *
|
||||
eolian_function_full_c_name_get(Eolian_Function foo_id, const char *prefix)
|
||||
{
|
||||
const char *funcn = eolian_function_name_get(foo_id);
|
||||
const char *last_p = strrchr(prefix, '_');
|
||||
const char *func_p = strchr(funcn, '_');
|
||||
Eina_Strbuf *buf = eina_strbuf_new();
|
||||
Eina_Stringshare *ret;
|
||||
int len;
|
||||
|
||||
if (!last_p) last_p = prefix;
|
||||
else last_p++;
|
||||
if (!func_p) len = strlen(funcn);
|
||||
else len = func_p - funcn;
|
||||
|
||||
if ((int)strlen(last_p) != len || strncmp(last_p, funcn, len))
|
||||
{
|
||||
eina_strbuf_append(buf, prefix);
|
||||
eina_strbuf_append_char(buf, '_');
|
||||
eina_strbuf_append(buf, funcn);
|
||||
ret = eina_stringshare_add(eina_strbuf_string_get(buf));
|
||||
eina_strbuf_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (last_p != prefix)
|
||||
eina_strbuf_append_n(buf, prefix, last_p - prefix); /* includes _ */
|
||||
|
||||
eina_strbuf_append(buf, funcn);
|
||||
ret = eina_stringshare_add(eina_strbuf_string_get(buf));
|
||||
eina_strbuf_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
database_function_set_as_virtual_pure(Eolian_Function function_id, Eolian_Function_Type ftype)
|
||||
{
|
||||
|
@ -1368,6 +1405,16 @@ eolian_show(const Eolian_Class class)
|
|||
}
|
||||
|
||||
#define EO_SUFFIX ".eo"
|
||||
#define EOT_SUFFIX ".eot"
|
||||
#define EO_SCAN_BODY(suffix, hash) \
|
||||
if (eina_str_has_suffix(file, suffix)) \
|
||||
{ \
|
||||
int len = strlen(file); \
|
||||
int idx = len - 1; \
|
||||
while (idx >= 0 && file[idx] != '/' && file[idx] != '\\') idx--; \
|
||||
eina_hash_add(hash, eina_stringshare_add_length(file+idx+1, len - idx - sizeof(suffix)), strdup(file)); \
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
eolian_directory_scan(const char *dir)
|
||||
{
|
||||
|
@ -1375,16 +1422,10 @@ eolian_directory_scan(const char *dir)
|
|||
char *file;
|
||||
/* Get all files from directory. Not recursively!!! */
|
||||
Eina_Iterator *dir_files = eina_file_ls(dir);
|
||||
EINA_ITERATOR_FOREACH(dir_files, file)
|
||||
{
|
||||
if (eina_str_has_suffix(file, EO_SUFFIX))
|
||||
{
|
||||
int len = strlen(file);
|
||||
int idx = len - 1;
|
||||
while (idx >= 0 && file[idx] != '/' && file[idx] != '\\') idx--;
|
||||
eina_hash_add(_filenames, eina_stringshare_add_length(file+idx+1, len - idx - sizeof(EO_SUFFIX)), strdup(file));
|
||||
}
|
||||
}
|
||||
EINA_ITERATOR_FOREACH(dir_files, file) EO_SCAN_BODY(EO_SUFFIX, _filenames);
|
||||
eina_iterator_free(dir_files);
|
||||
dir_files = eina_file_ls(dir);
|
||||
EINA_ITERATOR_FOREACH(dir_files, file) EO_SCAN_BODY(EOT_SUFFIX, _tfilenames);
|
||||
eina_iterator_free(dir_files);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
@ -1405,7 +1446,14 @@ _eolian_class_to_filename(const char *filename)
|
|||
return ret;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool eolian_eo_file_parse(const char *filepath)
|
||||
EAPI Eina_Bool
|
||||
eolian_eot_file_parse(const char *filepath)
|
||||
{
|
||||
return eo_parser_database_fill(filepath, EINA_TRUE);
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
eolian_eo_file_parse(const char *filepath)
|
||||
{
|
||||
const Eina_List *itr;
|
||||
Eolian_Class class = eolian_class_find_by_file(filepath);
|
||||
|
@ -1413,7 +1461,7 @@ EAPI Eina_Bool eolian_eo_file_parse(const char *filepath)
|
|||
Eolian_Implement impl;
|
||||
if (!class)
|
||||
{
|
||||
if (!eo_parser_database_fill(filepath)) return EINA_FALSE;
|
||||
if (!eo_parser_database_fill(filepath, EINA_FALSE)) return EINA_FALSE;
|
||||
class = eolian_class_find_by_file(filepath);
|
||||
if (!class)
|
||||
{
|
||||
|
@ -1456,6 +1504,21 @@ EAPI Eina_Bool eolian_eo_file_parse(const char *filepath)
|
|||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool _tfile_parse(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
|
||||
{
|
||||
Eina_Bool *ret = fdata;
|
||||
if (*ret) *ret = eolian_eot_file_parse(data);
|
||||
return *ret;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
eolian_all_eot_files_parse()
|
||||
{
|
||||
Eina_Bool ret = EINA_TRUE;
|
||||
eina_hash_foreach(_tfilenames, _tfile_parse, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Eina_Bool _file_parse(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
|
||||
{
|
||||
Eina_Bool *ret = fdata;
|
||||
|
|
Loading…
Reference in New Issue