forked from enlightenment/efl
eolian-cxx: Added namespaces and more (see below)
Implemented namespaces Added eolian_wrappers.hh with C++ code wrapping Eolain API Changed eolian_cxx program options. Now they're eolian_gen's Added functions to safe_str.hh (safe_lower, safe_upper, normalize_spaces, path_base) Added a mocked version of type_lookup.hh in advance. The full version will come as soon as complex-types are added. Made apply again by Daniel Kolesa, original implementation by Savio Sena.
This commit is contained in:
parent
bd41cfe9ea
commit
c05493b480
|
@ -27,6 +27,7 @@ TESTS += tests/edje_cxx/cxx_compile_test
|
|||
|
||||
tests_edje_cxx_cxx_compile_test_SOURCES = tests/edje_cxx/cxx_compile_test.cc
|
||||
tests_edje_cxx_cxx_compile_test_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-I$(top_builddir)/src/lib/evas/canvas/ \
|
||||
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/edje_cxx\" \
|
||||
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/edje_cxx\" \
|
||||
@CHECK_CFLAGS@ @ECORE_CXX_CFLAGS@ @EINA_CXX_CFLAGS@ @EDJE_CXX_CFLAGS@ @EO_CXX_CFLAGS@ \
|
||||
|
|
|
@ -16,7 +16,7 @@ installed_eoliancxxgrammarheadersdir = $(includedir)/eolian-cxx-@VMAJ@/grammar/
|
|||
dist_installed_eoliancxxgrammarheaders_DATA = \
|
||||
lib/eolian_cxx/grammar/comment.hh \
|
||||
lib/eolian_cxx/grammar/eo_class_constructors_generator.hh \
|
||||
lib/eolian_cxx/grammar/eo_class_events.generator.hh \
|
||||
lib/eolian_cxx/grammar/eo_class_events_generator.hh \
|
||||
lib/eolian_cxx/grammar/eo_class_functions_generator.hh \
|
||||
lib/eolian_cxx/grammar/eo_class_generator.hh \
|
||||
lib/eolian_cxx/grammar/eo_header_generator.hh \
|
||||
|
@ -26,15 +26,14 @@ lib/eolian_cxx/grammar/tab.hh
|
|||
|
||||
### Binary
|
||||
|
||||
|
||||
bin_PROGRAMS += bin/eolian_cxx/eolian_cxx
|
||||
|
||||
bin_eolian_cxx_eolian_cxx_SOURCES = \
|
||||
bin/eolian_cxx/comments.cc \
|
||||
bin/eolian_cxx/comments.hh \
|
||||
bin/eolian_cxx/convert_comments.cc \
|
||||
bin/eolian_cxx/convert_comments.hh \
|
||||
bin/eolian_cxx/convert.cc \
|
||||
bin/eolian_cxx/convert.hh \
|
||||
bin/eolian_cxx/eo_read.h \
|
||||
bin/eolian_cxx/eolian_wrappers.hh \
|
||||
bin/eolian_cxx/safe_strings.hh \
|
||||
bin/eolian_cxx/eolian_cxx.cc
|
||||
|
||||
|
|
|
@ -13,6 +13,6 @@ am__v_EOLCXX_0 = @echo " EOLCXX " $@;
|
|||
SUFFIXES += .eo.hh
|
||||
|
||||
%.eo.hh: %.eo $(_EOLIAN_CXX_DEP)
|
||||
$(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -I $< -o $@
|
||||
$(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -o $@ $<
|
||||
|
||||
CLEANFILES += $(BUILT_SOURCES)
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_EOLIAN_CONVERT_COMMENTS_HH
|
||||
#define EOLIAN_CXX_EOLIAN_CONVERT_COMMENTS_HH
|
||||
|
||||
#include <string>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <Eina.h>
|
||||
#include <Eolian.h>
|
||||
}
|
||||
|
||||
#include <Eolian_Cxx.hh>
|
||||
|
||||
namespace detail {
|
||||
|
||||
std::string eolian_class_comment(const Eolian_Class kls);
|
||||
|
||||
std::string eolian_constructor_comment(Eolian_Function constructor);
|
||||
|
||||
std::string eolian_function_comment(Eolian_Function function);
|
||||
|
||||
std::string eolian_property_getter_comment(Eolian_Function function);
|
||||
|
||||
std::string eolian_property_setter_comment(Eolian_Function function);
|
||||
|
||||
}
|
||||
|
||||
#endif // EOLIAN_CXX_EOLIAN_CONVERT_COMMENTS_HH
|
|
@ -1,18 +1,26 @@
|
|||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Eina.h>
|
||||
#include <Eina.hh>
|
||||
#include <Eolian.h>
|
||||
|
||||
#include "eo_types.hh"
|
||||
#include "eo_validate.hh"
|
||||
|
||||
#include "safe_strings.hh"
|
||||
#include "comments.hh"
|
||||
#include "convert_comments.hh"
|
||||
#include "eolian_wrappers.hh"
|
||||
|
||||
namespace eolian_cxx {
|
||||
|
||||
extern efl::eina::log_domain domain;
|
||||
|
||||
static std::string
|
||||
_dedup_func_name(Eolian_Function func, const std::string &classn)
|
||||
|
@ -23,145 +31,147 @@ _dedup_func_name(Eolian_Function func, const std::string &classn)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static std::string
|
||||
_resolve_param_type(Eolian_Function_Parameter id, bool is_get)
|
||||
{
|
||||
Eolian_Parameter_Dir dir;
|
||||
Eolian_Type typet;
|
||||
const char *type = NULL;
|
||||
bool is_const;
|
||||
std::string res;
|
||||
|
||||
eolian_parameter_information_get(id, &dir, &typet, NULL, NULL);
|
||||
if (typet) type = eolian_type_c_type_get(typet);
|
||||
is_const = eolian_parameter_const_attribute_get(id, is_get);
|
||||
res = safe_str(type);
|
||||
eina_stringshare_del(type);
|
||||
assert(res != "");
|
||||
if (is_const) res = std::string("const ") + res;
|
||||
if (dir == EOLIAN_OUT_PARAM || dir == EOLIAN_INOUT_PARAM) res += "*";
|
||||
return res;
|
||||
}
|
||||
|
||||
static efl::eolian::parameters_container_type
|
||||
_get_params(const Eina_List *eolian_params, bool is_get = false)
|
||||
convert_eolian_parameters(Eina_List const* parameters,
|
||||
Eolian_Function_Type func_type)
|
||||
{
|
||||
if (parameters == NULL) return {};
|
||||
assert(func_type != EOLIAN_PROPERTY);
|
||||
|
||||
const Eina_List *it;
|
||||
void *curr;
|
||||
if (eolian_params == NULL)
|
||||
{
|
||||
return efl::eolian::parameters_container_type();
|
||||
}
|
||||
efl::eolian::parameters_container_type list;
|
||||
EINA_LIST_FOREACH (eolian_params, it, curr)
|
||||
EINA_LIST_FOREACH (parameters, it, curr)
|
||||
{
|
||||
Eolian_Function_Parameter id =
|
||||
(static_cast<Eolian_Function_Parameter>(curr));
|
||||
list.push_back({
|
||||
_resolve_param_type(id, is_get),
|
||||
safe_strshare(eolian_parameter_name_get(id))
|
||||
});
|
||||
list.push_back
|
||||
({
|
||||
parameter_type(id, func_type),
|
||||
parameter_name(id)
|
||||
});
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
static efl::eolian::parameters_container_type
|
||||
convert_eolian_parameters(Eolian_Function const& function,
|
||||
getter_t func_type)
|
||||
{
|
||||
return convert_eolian_parameters
|
||||
(::eolian_parameters_list_get(function), func_type.value);
|
||||
}
|
||||
|
||||
static efl::eolian::parameters_container_type
|
||||
convert_eolian_parameters(Eina_List const* parameters,
|
||||
getter_t func_type)
|
||||
{
|
||||
return convert_eolian_parameters(parameters, func_type.value);
|
||||
}
|
||||
|
||||
static efl::eolian::parameters_container_type
|
||||
convert_eolian_parameters(Eina_List const* parameters,
|
||||
setter_t func_type)
|
||||
{
|
||||
return convert_eolian_parameters(parameters, func_type.value);
|
||||
}
|
||||
|
||||
static efl::eolian::parameters_container_type
|
||||
convert_eolian_parameters(Eolian_Function const& function)
|
||||
{
|
||||
assert(function_type(function) != EOLIAN_PROPERTY);
|
||||
return convert_eolian_parameters
|
||||
(::eolian_parameters_list_get(function), function_type(function));
|
||||
}
|
||||
|
||||
static efl::eolian::functions_container_type
|
||||
_get_properties(const Eolian_Class klass)
|
||||
convert_eolian_property_to_functions(Eolian_Class const& klass)
|
||||
{
|
||||
efl::eolian::functions_container_type container;
|
||||
|
||||
std::string cxx_classname = eolian_class_name_get(klass);
|
||||
std::transform(cxx_classname.begin(), cxx_classname.end(),
|
||||
cxx_classname.begin(), ::tolower);
|
||||
|
||||
const Eina_List *properties;
|
||||
properties = eolian_class_functions_list_get(klass, EOLIAN_PROPERTY);
|
||||
|
||||
std::string cxx_classname = safe_lower(class_name(klass));
|
||||
const Eina_List *properties =
|
||||
eolian_class_functions_list_get(klass, EOLIAN_PROPERTY); // XXX
|
||||
const Eina_List *it;
|
||||
void *curr;
|
||||
std::string prefix(safe_str(eolian_class_eo_prefix_get(klass)));
|
||||
std::string prefix(class_prefix(klass));
|
||||
EINA_LIST_FOREACH (properties, it, curr)
|
||||
{
|
||||
Eolian_Function property = static_cast<Eolian_Function>(curr);
|
||||
Eolian_Function_Type type = eolian_function_type_get(property);
|
||||
std::string name = safe_str(eolian_function_name_get(property));
|
||||
if (type == EOLIAN_PROP_GET || type == EOLIAN_PROPERTY)
|
||||
Eolian_Function prop_ = static_cast<Eolian_Function>(curr);
|
||||
if (property_is_getter(prop_))
|
||||
{
|
||||
const Eina_List *keys_ = eolian_property_keys_list_get(property);
|
||||
efl::eolian::parameters_container_type params = _get_params
|
||||
(eolian_parameters_list_get(property), true);
|
||||
efl::eolian::eo_function getter;
|
||||
getter.type = efl::eolian::eo_function::regular_;
|
||||
getter.name = name + "_get";
|
||||
getter.impl = _dedup_func_name(property, (prefix != "" ? prefix : cxx_classname)) + "_get";
|
||||
Eolian_Type tp = eolian_function_return_type_get(property, EOLIAN_PROP_GET);
|
||||
const char *tps = NULL;
|
||||
if (tp) tps = eolian_type_c_type_get(tp);
|
||||
std::string ret = safe_str(tps);
|
||||
if (tps) eina_stringshare_del(tps);
|
||||
if (ret == "") ret = "void";
|
||||
efl::eolian::parameters_container_type params
|
||||
= convert_eolian_parameters(prop_, eolian_cxx::getter);
|
||||
|
||||
// if the getter has a single parameter and void return
|
||||
// we translate it to a getter with no parameters that
|
||||
// returns its type.
|
||||
if ((ret == "void") && params.size() == 1)
|
||||
efl::eolian::eo_function get_;
|
||||
get_.type = efl::eolian::eo_function::regular_;
|
||||
get_.name = function_name(prop_) + "_get";
|
||||
get_.impl = _dedup_func_name(prop_, prefix) + "_get";
|
||||
|
||||
efl::eolian::eolian_type_instance ret =
|
||||
function_return_type(prop_, eolian_cxx::getter);
|
||||
|
||||
// if the getter has a single parameter and a void return
|
||||
// it is transformed into a getter with no parameters
|
||||
// that actually returns what would be the first argument.
|
||||
if (params.size() == 1 && efl::eolian::type_is_void(ret))
|
||||
{
|
||||
getter.ret = params[0].type;
|
||||
getter.params.clear();
|
||||
get_.ret = params[0].type;
|
||||
get_.params.clear();
|
||||
}
|
||||
else // otherwise just create the described getter
|
||||
{
|
||||
getter.ret = ret;
|
||||
getter.params = params;
|
||||
get_.ret = ret;
|
||||
get_.params = params;
|
||||
std::transform
|
||||
(params.begin(), params.end(), getter.params.begin(),
|
||||
(params.begin(), params.end(), get_.params.begin(),
|
||||
[](efl::eolian::eo_parameter const& param)
|
||||
{
|
||||
efl::eolian::eolian_type getter_param_type =
|
||||
type_to_native(param.type);
|
||||
getter_param_type/*.native*/ += "*"; // XXX implement complex types
|
||||
return efl::eolian::eo_parameter
|
||||
{ param.type + "*", param.name };
|
||||
{ { getter_param_type }, param.name };
|
||||
});
|
||||
}
|
||||
if (eina_list_count(keys_) > 0)
|
||||
efl::eolian::parameters_container_type keys =
|
||||
convert_eolian_parameters(::eolian_property_keys_list_get(prop_),
|
||||
eolian_cxx::getter);
|
||||
if (!keys.empty())
|
||||
{
|
||||
efl::eolian::parameters_container_type keys = _get_params(keys_, true);
|
||||
keys.reserve(keys.size() + getter.params.size());
|
||||
keys.insert(keys.end(), getter.params.begin(), getter.params.end());
|
||||
getter.params = keys;
|
||||
keys.reserve(keys.size() + get_.params.size());
|
||||
keys.insert(keys.end(), get_.params.begin(),
|
||||
get_.params.end());
|
||||
get_.params = keys;
|
||||
}
|
||||
getter.comment = detail::eolian_property_getter_comment(property);
|
||||
container.push_back(getter);
|
||||
get_.comment = convert_comments_function(prop_, eolian_cxx::getter);
|
||||
container.push_back(get_);
|
||||
}
|
||||
if (type == EOLIAN_PROP_SET || type == EOLIAN_PROPERTY)
|
||||
if (property_is_setter(prop_))
|
||||
{
|
||||
const Eina_List *keys_ = eolian_property_keys_list_get(property);
|
||||
const Eina_List *args_ = eolian_parameters_list_get(property);
|
||||
const Eina_List *keys_ = eolian_property_keys_list_get(prop_);
|
||||
const Eina_List *args_ = eolian_parameters_list_get(prop_);
|
||||
Eina_List *params_ = eina_list_merge(eina_list_clone(keys_), eina_list_clone(args_));
|
||||
efl::eolian::parameters_container_type params = _get_params(params_);
|
||||
efl::eolian::parameters_container_type params =
|
||||
convert_eolian_parameters(params_, eolian_cxx::setter);
|
||||
eina_list_free(params_);
|
||||
efl::eolian::eo_function setter;
|
||||
setter.type = efl::eolian::eo_function::regular_;
|
||||
setter.name = name + "_set";
|
||||
setter.impl = _dedup_func_name(property, (prefix != "" ? prefix : cxx_classname)) + "_set";
|
||||
setter.params = params;
|
||||
Eolian_Type tp = eolian_function_return_type_get(property, EOLIAN_PROP_SET);
|
||||
const char *tps = NULL;
|
||||
if (tp) tps = eolian_type_c_type_get(tp);
|
||||
setter.ret = safe_str(tps);
|
||||
if (tps) eina_stringshare_del(tps);
|
||||
if (setter.ret == "") setter.ret = "void";
|
||||
setter.comment = detail::eolian_property_setter_comment(property);
|
||||
container.push_back(setter);
|
||||
efl::eolian::eo_function set_;
|
||||
set_.type = efl::eolian::eo_function::regular_;
|
||||
set_.name = function_name(prop_) + "_set";
|
||||
set_.impl = _dedup_func_name(prop_, prefix) + "_set";
|
||||
set_.params = params;
|
||||
set_.ret = function_return_type(prop_, eolian_cxx::setter);
|
||||
set_.comment = convert_comments_function(prop_, eolian_cxx::setter);
|
||||
container.push_back(set_);
|
||||
}
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
void
|
||||
convert_eolian_inheritances(efl::eolian::eo_class& cls, const Eolian_Class klass)
|
||||
convert_eolian_inheritances(efl::eolian::eo_class& cls, Eolian_Class const& klass)
|
||||
{
|
||||
const Eina_List *inheritances = eolian_class_inherits_list_get(klass);
|
||||
const Eina_List *inheritances =
|
||||
::eolian_class_inherits_list_get(klass);
|
||||
const Eina_List *it;
|
||||
void *curr;
|
||||
|
||||
|
@ -173,29 +183,31 @@ convert_eolian_inheritances(efl::eolian::eo_class& cls, const Eolian_Class klass
|
|||
}
|
||||
else
|
||||
{
|
||||
std::string parent =
|
||||
static_cast<const char*>(eina_list_data_get(inheritances));
|
||||
std::transform(parent.begin(), parent.end(), parent.begin(), ::tolower);
|
||||
// "eo_base" is the Eolian name for EO_BASE_CLASS.
|
||||
cls.parent = (parent == "eo_base" || parent == "") ? "efl::eo::base" : parent;
|
||||
}
|
||||
const char *ptr = static_cast<const char*>
|
||||
(eina_list_data_get(inheritances));
|
||||
std::string parent = class_format_cxx(safe_lower(ptr));
|
||||
|
||||
// "eo_base" is the Eolian name for EO_BASE_CLASS.
|
||||
cls.parent =
|
||||
(parent == "eo_base" || parent == "eo::base" || parent == "")
|
||||
? "efl::eo::base"
|
||||
: parent;
|
||||
}
|
||||
inheritances = eina_list_next(inheritances);
|
||||
EINA_LIST_FOREACH (inheritances, it, curr)
|
||||
{
|
||||
std::string extension = static_cast<const char*>(curr);
|
||||
std::transform
|
||||
(extension.begin(), extension.end(), extension.begin(), ::tolower);
|
||||
cls.extensions.push_back(extension);
|
||||
std::string extension = safe_lower(static_cast<const char*>(curr));
|
||||
cls.extensions.push_back(class_format_cxx(extension));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
convert_eolian_implements(efl::eolian::eo_class& cls, const Eolian_Class klass)
|
||||
convert_eolian_implements(efl::eolian::eo_class& cls, Eolian_Class const& klass)
|
||||
{
|
||||
const Eina_List *it;
|
||||
std::string prefix(safe_str(eolian_class_eo_prefix_get(klass)));
|
||||
std::string prefix(class_prefix(klass));
|
||||
void *impl_desc_;
|
||||
|
||||
EINA_LIST_FOREACH(eolian_class_implements_list_get(klass), it, impl_desc_)
|
||||
{
|
||||
Eolian_Implement impl_desc = static_cast<Eolian_Implement>(impl_desc_);
|
||||
|
@ -207,43 +219,37 @@ convert_eolian_implements(efl::eolian::eo_class& cls, const Eolian_Class klass)
|
|||
if (impl_type == EOLIAN_CTOR)
|
||||
{
|
||||
efl::eolian::eo_constructor constructor;
|
||||
std::string parent = safe_str(eolian_class_full_name_get(impl_class));
|
||||
if(parent == "Eo_Base") parent = "eo";
|
||||
else std::transform(parent.begin(), parent.end(), parent.begin(), ::tolower);
|
||||
constructor.name = parent + "_" + safe_str(eolian_function_name_get(impl_func));
|
||||
constructor.params = _get_params
|
||||
(eolian_parameters_list_get(impl_func));
|
||||
constructor.comment = detail::eolian_constructor_comment
|
||||
(impl_func);
|
||||
std::string parent = safe_lower(eolian_class_full_name_get(impl_class));
|
||||
if (parent == "eo_base" || parent == "eo.base") parent = "eo";
|
||||
constructor.name = parent + "_" + function_name(impl_func);
|
||||
constructor.params = convert_eolian_parameters(impl_func);
|
||||
constructor.comment = convert_comments_function(impl_func, eolian_cxx::ctor);
|
||||
cls.constructors.push_back(constructor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
convert_eolian_constructors(efl::eolian::eo_class& cls, const Eolian_Class klass)
|
||||
convert_eolian_constructors(efl::eolian::eo_class& cls, Eolian_Class const& klass)
|
||||
{
|
||||
const Eina_List *it;
|
||||
void *curr;
|
||||
std::string prefix(safe_str(eolian_class_eo_prefix_get(klass)));
|
||||
std::string prefix(class_prefix(klass));
|
||||
const Eina_List *constructors =
|
||||
eolian_class_functions_list_get(klass, EOLIAN_CTOR);
|
||||
EINA_LIST_FOREACH (constructors, it, curr)
|
||||
{
|
||||
Eolian_Function eolian_constructor = static_cast<Eolian_Function>(curr);
|
||||
Eolian_Function eo_constructor = static_cast<Eolian_Function>(curr);
|
||||
efl::eolian::eo_constructor 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
|
||||
(eolian_constructor);
|
||||
constructor.name = _dedup_func_name(eo_constructor, prefix);
|
||||
constructor.params = convert_eolian_parameters(eo_constructor);
|
||||
constructor.comment = convert_comments_function(eo_constructor, eolian_cxx::ctor);
|
||||
cls.constructors.push_back(constructor);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
convert_eolian_functions(efl::eolian::eo_class& cls, const Eolian_Class klass)
|
||||
convert_eolian_functions(efl::eolian::eo_class& cls, Eolian_Class const& klass)
|
||||
{
|
||||
const Eina_List *it;
|
||||
void *curr;
|
||||
|
@ -254,60 +260,60 @@ convert_eolian_functions(efl::eolian::eo_class& cls, const Eolian_Class klass)
|
|||
{
|
||||
efl::eolian::eo_function function;
|
||||
Eolian_Function eolian_function = static_cast<Eolian_Function>(curr);
|
||||
std::string prefix(safe_str(eolian_class_eo_prefix_get(klass)));
|
||||
std::string prefix(class_prefix(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(eolian_function, (prefix != "" ? prefix : cls.name));
|
||||
Eolian_Type tp = eolian_function_return_type_get(eolian_function, EOLIAN_METHOD);
|
||||
const char *tps = NULL;
|
||||
if (tp) tps = eolian_type_c_type_get(tp);
|
||||
function.ret = safe_str(tps);
|
||||
if (tps) eina_stringshare_del(tps);
|
||||
if(function.ret == "") function.ret = "void";
|
||||
function.params = _get_params(eolian_parameters_list_get(eolian_function));
|
||||
function.comment = detail::eolian_function_comment(eolian_function);
|
||||
function.name = function_name(eolian_function);
|
||||
function.impl = _dedup_func_name(eolian_function, prefix);
|
||||
function.ret = function_return_type(eolian_function);
|
||||
function.params = convert_eolian_parameters(eolian_function);
|
||||
function.comment = convert_comments_function(eolian_function, eolian_cxx::method);
|
||||
cls.functions.push_back(function);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
convert_eolian_properties(efl::eolian::eo_class& cls, const Eolian_Class klass)
|
||||
convert_eolian_properties(efl::eolian::eo_class& cls, Eolian_Class const& klass)
|
||||
{
|
||||
efl::eolian::functions_container_type properties = _get_properties(klass);
|
||||
cls.functions.insert(cls.functions.end(), properties.begin(), properties.end());
|
||||
efl::eolian::functions_container_type properties
|
||||
= convert_eolian_property_to_functions(klass);
|
||||
cls.functions.insert
|
||||
(cls.functions.end(), properties.begin(), properties.end());
|
||||
}
|
||||
|
||||
} // namespace detail {
|
||||
void
|
||||
convert_eolian_events(efl::eolian::eo_class& cls, Eolian_Class const& klass)
|
||||
{
|
||||
efl::eolian::events_container_type events = event_list(klass);
|
||||
cls.events.reserve(cls.events.size() + events.size());
|
||||
cls.events.insert(cls.events.end(), events.begin(), events.end());
|
||||
}
|
||||
|
||||
efl::eolian::eo_class
|
||||
_cxx_new(const Eolian_Class klass)
|
||||
convert_eolian_class_new(Eolian_Class const& klass)
|
||||
{
|
||||
using namespace efl::eolian;
|
||||
eo_class cls;
|
||||
Eolian_Class_Type cls_type = ::eolian_class_type_get(klass);
|
||||
if (cls_type == EOLIAN_CLASS_REGULAR) cls.type = eo_class::regular_;
|
||||
else if (cls_type == EOLIAN_CLASS_ABSTRACT) cls.type = eo_class::regular_noninst_;
|
||||
else if (cls_type == EOLIAN_CLASS_MIXIN) cls.type = eo_class::mixin_;
|
||||
else if (cls_type == EOLIAN_CLASS_INTERFACE) cls.type = eo_class::interface_;
|
||||
else { assert(false); }
|
||||
cls.name = eolian_class_name_get(klass);
|
||||
cls.eo_name = cls.name + "_CLASS";
|
||||
cls.comment = detail::eolian_class_comment(klass);
|
||||
std::transform(cls.name.begin(), cls.name.end(), cls.name.begin(), ::tolower);
|
||||
std::transform(cls.eo_name.begin(), cls.eo_name.end(), cls.eo_name.begin(), ::toupper);
|
||||
efl::eolian::eo_class cls;
|
||||
cls.type = class_type(klass);
|
||||
cls.name = safe_lower(class_name(klass));
|
||||
cls.name_space = safe_lower(class_namespace_full(klass));
|
||||
cls.eo_name = class_eo_name(klass);
|
||||
cls.comment = convert_comments_class(klass);
|
||||
return cls;
|
||||
}
|
||||
|
||||
efl::eolian::eo_class
|
||||
c_to_cxx(const char *classname)
|
||||
convert_eolian_class(const Eolian_Class klass)
|
||||
{
|
||||
Eolian_Class klass = eolian_class_find_by_name(classname);
|
||||
efl::eolian::eo_class cls(_cxx_new(klass));
|
||||
detail::convert_eolian_inheritances(cls, klass);
|
||||
detail::convert_eolian_implements(cls, klass);
|
||||
detail::convert_eolian_constructors(cls, klass);
|
||||
detail::convert_eolian_functions(cls, klass);
|
||||
detail::convert_eolian_properties(cls, klass);
|
||||
assert(klass != NULL);
|
||||
efl::eolian::eo_class cls(eolian_cxx::convert_eolian_class_new(klass));
|
||||
eolian_cxx::convert_eolian_inheritances(cls, klass);
|
||||
eolian_cxx::convert_eolian_implements(cls, klass);
|
||||
eolian_cxx::convert_eolian_constructors(cls, klass);
|
||||
eolian_cxx::convert_eolian_functions(cls, klass);
|
||||
eolian_cxx::convert_eolian_properties(cls, klass);
|
||||
eolian_cxx::convert_eolian_events(cls, klass);
|
||||
efl::eolian::eo_class_validate(cls);
|
||||
return cls;
|
||||
}
|
||||
|
||||
} // namespace eolian_cxx {
|
||||
|
|
|
@ -4,6 +4,16 @@
|
|||
|
||||
#include "eo_types.hh"
|
||||
|
||||
efl::eolian::eo_class c_to_cxx(const char *classname);
|
||||
namespace eolian_cxx
|
||||
{
|
||||
|
||||
///
|
||||
/// @brief Retrieve a efl::eolian::eo_class from an Eolian_Class name.
|
||||
/// @param cls The Eolian class.
|
||||
/// @return The @p eo_class describing @p classname.
|
||||
///
|
||||
efl::eolian::eo_class convert_eolian_class(Eolian_Class klass);
|
||||
|
||||
}
|
||||
|
||||
#endif // EOLIAN_CXX_EOLIAN_CONVERT_CLASSES_HH
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
|
||||
#include "comments.hh"
|
||||
#include "convert_comments.hh"
|
||||
#include "safe_strings.hh"
|
||||
|
||||
namespace eolian_cxx {
|
||||
|
||||
static std::string
|
||||
_comment_parameter(Eolian_Function_Parameter param)
|
||||
{
|
||||
|
@ -74,41 +76,20 @@ _comment_return(Eolian_Function function,
|
|||
return doc;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
std::string
|
||||
eolian_class_comment(const Eolian_Class kls)
|
||||
convert_comments_class(Eolian_Class const& klass)
|
||||
{
|
||||
return safe_str(eolian_class_description_get(kls));
|
||||
return safe_str(eolian_class_description_get(klass));
|
||||
}
|
||||
|
||||
std::string
|
||||
eolian_constructor_comment(Eolian_Function constructor)
|
||||
{
|
||||
return _comment_brief_and_params(constructor);
|
||||
}
|
||||
|
||||
std::string eolian_function_comment(Eolian_Function function)
|
||||
convert_comments_function(Eolian_Function const& function,
|
||||
Eolian_Function_Type func_type)
|
||||
{
|
||||
std::string doc = _comment_brief_and_params(function);
|
||||
doc += _comment_return(function, EOLIAN_METHOD);
|
||||
if (func_type != eolian_cxx::ctor.value)
|
||||
doc += _comment_return(function, func_type);
|
||||
return doc;
|
||||
}
|
||||
|
||||
std::string eolian_property_getter_comment(Eolian_Function property)
|
||||
{
|
||||
std::string doc = _comment_brief_and_params
|
||||
(property, EOLIAN_COMMENT_GET);
|
||||
doc += _comment_return(property, EOLIAN_PROP_GET);
|
||||
return doc;
|
||||
}
|
||||
|
||||
std::string eolian_property_setter_comment(Eolian_Function property)
|
||||
{
|
||||
std::string doc = _comment_brief_and_params
|
||||
(property, EOLIAN_COMMENT_SET);
|
||||
doc += _comment_return(property, EOLIAN_PROP_SET);
|
||||
return doc;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace eolian_cxx
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_CONVERT_COMMENTS_HH
|
||||
#define EOLIAN_CXX_CONVERT_COMMENTS_HH
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <Eolian.h>
|
||||
#include <Eolian_Cxx.hh>
|
||||
|
||||
#include "eolian_wrappers.hh"
|
||||
|
||||
namespace eolian_cxx {
|
||||
|
||||
std::string convert_comments_class(Eolian_Class const& kls);
|
||||
|
||||
std::string convert_comments_function(Eolian_Function const& function,
|
||||
Eolian_Function_Type func_type);
|
||||
|
||||
inline std::string
|
||||
convert_comments_function(Eolian_Function const& constructor_, ctor_t func_type_)
|
||||
{
|
||||
return convert_comments_function(constructor_, func_type_.value);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
convert_comments_function(Eolian_Function const& function_, method_t func_type_)
|
||||
{
|
||||
return convert_comments_function(function_, func_type_.value);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
convert_comments_function(Eolian_Function const& property_, getter_t func_type_)
|
||||
{
|
||||
return convert_comments_function(property_, func_type_.value);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
convert_comments_function(Eolian_Function const& property_, setter_t func_type_)
|
||||
{
|
||||
return convert_comments_function(property_, func_type_.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // EOLIAN_CXX_CONVERT_COMMENTS_HH
|
|
@ -1,62 +0,0 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_EOLIAN_HELPER_H
|
||||
#define EOLIAN_CXX_EOLIAN_HELPER_H
|
||||
|
||||
#include <Eina.h>
|
||||
#include <Eolian.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define EO_SUFFIX ".eo"
|
||||
|
||||
inline Eina_List*
|
||||
_list_dir(const char *dir, const char *suffix, Eina_Bool recurse)
|
||||
{
|
||||
Eina_List *files = NULL;
|
||||
Eina_Iterator *ls;
|
||||
Eina_File_Direct_Info *info;
|
||||
|
||||
ls = eina_file_direct_ls(dir);
|
||||
if(ls == NULL) return NULL;
|
||||
|
||||
EINA_ITERATOR_FOREACH (ls, info)
|
||||
{
|
||||
assert(info && info->path);
|
||||
if (info->type == EINA_FILE_DIR && recurse)
|
||||
{
|
||||
files = eina_list_merge
|
||||
(files, _list_dir(info->path, suffix, recurse));
|
||||
}
|
||||
else if (eina_str_has_suffix(&info->path[info->name_start], suffix))
|
||||
{
|
||||
files = eina_list_append(files, strdup(info->path));
|
||||
}
|
||||
}
|
||||
eina_iterator_free(ls);
|
||||
return eina_list_sort
|
||||
(files, eina_list_count(files), EINA_COMPARE_CB(strcoll));
|
||||
}
|
||||
|
||||
inline Eina_List*
|
||||
eolian_read_from_fs(const char *path)
|
||||
{
|
||||
if (eina_str_has_suffix(path, EO_SUFFIX))
|
||||
{
|
||||
if(!eolian_eo_file_parse(path))
|
||||
{
|
||||
/* XXX: fprintf? */
|
||||
fprintf(stderr, "Couldn't load input file: %s\n", path);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!eolian_directory_scan(path))
|
||||
{
|
||||
/* XXX: fprintf? */
|
||||
fprintf(stderr, "Error scanning directory: %s\n", path);
|
||||
}
|
||||
}
|
||||
return eina_list_clone(eolian_class_names_list_get());
|
||||
}
|
||||
|
||||
#endif /* EOLIAN_CXX_EOLIAN_HELPER_H */
|
|
@ -13,42 +13,40 @@
|
|||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Eina.h>
|
||||
#include <Eolian.h>
|
||||
}
|
||||
|
||||
#include <Eina.hh>
|
||||
#include <Eolian_Cxx.hh>
|
||||
|
||||
#include "eo_read.h"
|
||||
#include "convert.hh"
|
||||
#include "type_lookup.hh"
|
||||
|
||||
#include "convert.hh"
|
||||
#include "eolian_wrappers.hh"
|
||||
#include "safe_strings.hh"
|
||||
|
||||
namespace {
|
||||
namespace eolian_cxx {
|
||||
|
||||
// Program options.
|
||||
/// Program options.
|
||||
struct options_type
|
||||
{
|
||||
std::vector<std::string> in_srcs;
|
||||
std::vector<std::string> include_dirs;
|
||||
std::string in_file;
|
||||
std::string out_file;
|
||||
std::string out_dir;
|
||||
std::string classname;
|
||||
std::string name_space;
|
||||
bool recurse;
|
||||
bool generate_all;
|
||||
|
||||
options_type()
|
||||
: in_srcs()
|
||||
, out_file("")
|
||||
, out_dir("")
|
||||
, classname("")
|
||||
, name_space("")
|
||||
: include_dirs()
|
||||
, in_file()
|
||||
, out_file()
|
||||
, out_dir()
|
||||
, classname()
|
||||
, recurse(false)
|
||||
, generate_all(false)
|
||||
{}
|
||||
|
@ -56,112 +54,80 @@ struct options_type
|
|||
|
||||
efl::eina::log_domain domain("eolian_cxx");
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
_opt_error(std::string message)
|
||||
static bool
|
||||
opts_check(eolian_cxx::options_type const& opts)
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(::domain) << message << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void
|
||||
_assert_not_dup(std::string option, std::string value)
|
||||
{
|
||||
if (value != "")
|
||||
if (!opts.generate_all && opts.in_file.empty())
|
||||
{
|
||||
_opt_error("Option -" + option + " already set (" + value + ")");
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Nothing to generate?" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to guess classname from input filenames.
|
||||
// Precondition: Input sources must be loaded into Eolian Database
|
||||
// otherwise we can't infer the classname from the .eo files.
|
||||
// Precondition: Input options must have opts.classname == "".
|
||||
static std::string
|
||||
_guess_classname_from_sources(::options_type& opts)
|
||||
{
|
||||
for (auto filename : opts.in_srcs)
|
||||
else if (opts.generate_all && !opts.in_file.empty())
|
||||
{
|
||||
if (Eolian_Class klass = eolian_class_find_by_file(filename.c_str()))
|
||||
{
|
||||
return eolian_class_full_name_get(klass);
|
||||
}
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Didn't expect to receive input files (" << opts.in_file
|
||||
<< ") with parameter -a."
|
||||
<< std::endl;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::pair<std::string, std::string> get_filename_info(std::string path)
|
||||
{
|
||||
const size_t last = path.rfind("lib/");
|
||||
if (last != std::string::npos)
|
||||
{
|
||||
path.erase(0, last+4);
|
||||
|
||||
std::string::iterator slash
|
||||
= std::find(path.begin(), path.end(), '/');
|
||||
if(slash != path.end())
|
||||
{
|
||||
std::string namespace_ (path.begin(), slash);
|
||||
std::string filename (slash+1, path.end());
|
||||
return {filename, namespace_};
|
||||
}
|
||||
}
|
||||
std::string::reverse_iterator slash
|
||||
= std::find(path.rbegin(), path.rend(), '/');
|
||||
return {std::string(slash.base(), path.end()), std::string()};
|
||||
else if (opts.generate_all && !opts.out_file.empty())
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Can't use -a and -o together." << std::endl;
|
||||
}
|
||||
else if (opts.generate_all && opts.include_dirs.empty())
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Option -a requires at least one include directory (-I)."
|
||||
<< std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true; // valid.
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
efl::eolian::eo_generator_options
|
||||
_resolve_includes(std::string const& classname)
|
||||
generator_options(const Eolian_Class klass)
|
||||
{
|
||||
efl::eolian::eo_generator_options gen_opts;
|
||||
|
||||
std::string cls_name = classname;
|
||||
Eolian_Class klass = eolian_class_find_by_name(classname.c_str());
|
||||
std::transform(cls_name.begin(), cls_name.end(), cls_name.begin(), ::tolower);
|
||||
|
||||
std::string eo_file = safe_str(eolian_class_file_get(klass));
|
||||
gen_opts.c_headers.push_back(get_filename_info(eo_file).first + ".h");
|
||||
gen_opts.c_headers.push_back(class_base_file(klass) + ".h");
|
||||
|
||||
void *cur = NULL;
|
||||
const Eina_List *itr, *inheritances = eolian_class_inherits_list_get(klass);
|
||||
EINA_LIST_FOREACH(inheritances, itr, cur)
|
||||
{
|
||||
Eolian_Class ext = eolian_class_find_by_name(static_cast<const char*>(cur));
|
||||
std::string eo_parent_file = safe_str(eolian_class_file_get(ext));
|
||||
std::string eo_parent_file = class_base_file(ext);
|
||||
if (!eo_parent_file.empty())
|
||||
{
|
||||
std::string filename, namespace_;
|
||||
std::tie(filename, namespace_) = get_filename_info(eo_parent_file);
|
||||
// we have our own eo_base.hh
|
||||
std::string eo_base_eo = "eo_base.eo";
|
||||
if (filename.length() < eo_base_eo.length() ||
|
||||
if (eo_parent_file.length() < eo_base_eo.length() ||
|
||||
!std::equal(eo_base_eo.begin(), eo_base_eo.end(),
|
||||
filename.end() - eo_base_eo.length()))
|
||||
eo_parent_file.end() - eo_base_eo.length()))
|
||||
{
|
||||
gen_opts.cxx_headers.push_back(filename + ".hh");
|
||||
gen_opts.cxx_headers.push_back(eo_parent_file + ".hh");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(::domain)
|
||||
<< "Couldn't find source file for class '" << ext << "'";
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Couldn't find source file for class '" << ext << "'"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
return gen_opts;
|
||||
}
|
||||
|
||||
static void
|
||||
_generate(const std::string classname, ::options_type const& opts)
|
||||
static bool
|
||||
generate(const Eolian_Class klass, eolian_cxx::options_type const& opts)
|
||||
{
|
||||
efl::eolian::eo_class cls = ::c_to_cxx(classname.c_str());
|
||||
cls.name_space = opts.name_space;
|
||||
efl::eolian::eo_class_validate(cls);
|
||||
efl::eolian::eo_generator_options gen_opts = _resolve_includes(classname);
|
||||
std::string outname = (opts.out_file == "") ? (cls.name + ".eo.hh") : opts.out_file;
|
||||
|
||||
if (opts.out_dir != "")
|
||||
assert(!!klass);
|
||||
efl::eolian::eo_class cls = eolian_cxx::convert_eolian_class(klass);
|
||||
efl::eolian::eo_generator_options gen_opts = generator_options(klass);
|
||||
std::string outname = opts.out_file.empty() ? (class_base_file(klass) + ".hh") : opts.out_file;
|
||||
if (!opts.out_dir.empty())
|
||||
{
|
||||
outname = opts.out_dir + "/" + outname;
|
||||
}
|
||||
|
@ -173,33 +139,90 @@ _generate(const std::string classname, ::options_type const& opts)
|
|||
{
|
||||
std::ofstream outfile;
|
||||
outfile.open(outname);
|
||||
assert(outfile.good());
|
||||
efl::eolian::generate(outfile, cls, gen_opts);
|
||||
outfile.close();
|
||||
if (outfile.good())
|
||||
{
|
||||
efl::eolian::generate(outfile, cls, gen_opts);
|
||||
outfile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Can't open output file: " << outname << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
_run(options_type const& opts)
|
||||
run(options_type const& opts)
|
||||
{
|
||||
if (opts.classname != "")
|
||||
Eolian_Class klass = NULL;
|
||||
if (!opts.classname.empty())
|
||||
klass = class_from_name(opts.classname);
|
||||
else if (!opts.in_file.empty())
|
||||
klass = class_from_file(opts.in_file);
|
||||
if (klass)
|
||||
{
|
||||
_generate(opts.classname.c_str(), opts);
|
||||
if (!generate(klass, opts))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
efl::eina::range_ptr_list<const char* const>
|
||||
classes(eolian_class_names_list_get());
|
||||
for (auto cls : classes)
|
||||
auto classes = class_list_all();
|
||||
for (const Eolian_Class c : classes)
|
||||
{
|
||||
if (opts.classname == "" || opts.classname == cls)
|
||||
if (!generate(c, opts))
|
||||
{
|
||||
_generate(cls, opts);
|
||||
klass = c;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
err:
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Error generating: " << class_name(klass)
|
||||
<< std::endl;
|
||||
std::abort();
|
||||
}
|
||||
|
||||
static void
|
||||
database_load(options_type const& opts)
|
||||
{
|
||||
for (auto src : opts.include_dirs)
|
||||
{
|
||||
if (!::eolian_directory_scan(src.c_str()))
|
||||
{
|
||||
EINA_CXX_DOM_LOG_WARN(eolian_cxx::domain)
|
||||
<< "Couldn't load eolian from '" << src << "'.";
|
||||
}
|
||||
}
|
||||
if (!::eolian_all_eot_files_parse())
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Eolian failed parsing eot files";
|
||||
std::abort();
|
||||
}
|
||||
if (!opts.in_file.empty())
|
||||
{
|
||||
if (!::eolian_eo_file_parse(opts.in_file.c_str()))
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Failed parsing: " << opts.in_file << ".";
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
if (!::eolian_all_eo_files_parse())
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
|
||||
<< "Eolian failed parsing input files";
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace eolian_cxx {
|
||||
|
||||
static void
|
||||
_print_version()
|
||||
{
|
||||
|
@ -208,78 +231,13 @@ _print_version()
|
|||
<< PACKAGE_VERSION << ")" << std::endl;
|
||||
}
|
||||
|
||||
static void
|
||||
_validate_options(::options_type const& opts)
|
||||
{
|
||||
if (opts.in_srcs.size() == 0)
|
||||
{
|
||||
_opt_error("You must provide at least one input source (-I). "
|
||||
"Either an .eo file or a directory of .eo files.");
|
||||
}
|
||||
else if (opts.out_file != "" && opts.generate_all)
|
||||
{
|
||||
_opt_error("Options -a and -o can't be used together.");
|
||||
}
|
||||
else if (!opts.generate_all && opts.classname == "")
|
||||
{
|
||||
_opt_error("Neither -a nor -c provided. "
|
||||
"Don't know what to generate.");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_resolve_classname(options_type& opts)
|
||||
{
|
||||
if (opts.classname == "")
|
||||
{
|
||||
std::string cls = _guess_classname_from_sources(opts);
|
||||
opts.classname = cls;
|
||||
}
|
||||
if (opts.classname == "" && opts.out_file != "")
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(::domain)
|
||||
<< "Unknown output class for " << opts.out_file
|
||||
<< " : Missing '-c' option?";
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
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 (!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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_usage(const char *progname)
|
||||
{
|
||||
std::cerr
|
||||
<< progname
|
||||
<< " [options]" << std::endl
|
||||
<< " [options] [file.eo]" << std::endl
|
||||
<< " A single input file must be provided (unless -a is specified)." << std::endl
|
||||
<< "Options:" << std::endl
|
||||
<< " -a, --all Generate bindings for all Eo classes." << std::endl
|
||||
<< " -c, --class <name> The Eo class name to generate code for." << std::endl
|
||||
|
@ -293,10 +251,20 @@ _usage(const char *progname)
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static ::options_type
|
||||
_read_options(int argc, char **argv)
|
||||
static void
|
||||
_assert_not_dup(std::string option, std::string value)
|
||||
{
|
||||
::options_type opts;
|
||||
if (value != "")
|
||||
{
|
||||
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain) <<
|
||||
"Option -" + option + " already set (" + value + ")";
|
||||
}
|
||||
}
|
||||
|
||||
static eolian_cxx::options_type
|
||||
opts_get(int argc, char **argv)
|
||||
{
|
||||
eolian_cxx::options_type opts;
|
||||
|
||||
const struct option long_options[] =
|
||||
{
|
||||
|
@ -304,21 +272,20 @@ _read_options(int argc, char **argv)
|
|||
{ "out-dir", required_argument, 0, 'D' },
|
||||
{ "out-file", required_argument, 0, 'o' },
|
||||
{ "class", required_argument, 0, 'c' },
|
||||
{ "namespace", required_argument, 0, 'n' },
|
||||
{ "all", no_argument, 0, 'a' },
|
||||
{ "recurse", no_argument, 0, 'r' },
|
||||
{ "version", no_argument, 0, 'v' },
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
const char* options = "I:D:o:c:n:arvh";
|
||||
const char* options = "I:D:o:c:arvh";
|
||||
|
||||
int c, idx;
|
||||
while ( (c = getopt_long(argc, argv, options, long_options, &idx)) != -1)
|
||||
{
|
||||
if (c == 'I')
|
||||
{
|
||||
opts.in_srcs.push_back(optarg);
|
||||
opts.include_dirs.push_back(optarg);
|
||||
}
|
||||
else if (c == 'D')
|
||||
{
|
||||
|
@ -335,11 +302,6 @@ _read_options(int argc, char **argv)
|
|||
_assert_not_dup("c", opts.classname);
|
||||
opts.classname = optarg;
|
||||
}
|
||||
else if (c == 'n')
|
||||
{
|
||||
_assert_not_dup("n", opts.name_space);
|
||||
opts.name_space = optarg;
|
||||
}
|
||||
else if (c == 'a')
|
||||
{
|
||||
opts.generate_all = true;
|
||||
|
@ -358,6 +320,17 @@ _read_options(int argc, char **argv)
|
|||
if (argc == 2) exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
if (optind == argc-1)
|
||||
{
|
||||
opts.in_file = argv[optind];
|
||||
}
|
||||
|
||||
if (!eolian_cxx::opts_check(opts))
|
||||
{
|
||||
_usage(argv[0]);
|
||||
std::abort();
|
||||
}
|
||||
|
||||
return opts;
|
||||
}
|
||||
|
||||
|
@ -365,15 +338,8 @@ int main(int argc, char **argv)
|
|||
{
|
||||
efl::eina::eina_init eina_init;
|
||||
efl::eolian::eolian_init eolian_init;
|
||||
#if DEBUG
|
||||
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);
|
||||
_run(opts);
|
||||
eolian_cxx::options_type opts = opts_get(argc, argv);
|
||||
eolian_cxx::database_load(opts);
|
||||
eolian_cxx::run(opts);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,318 @@
|
|||
#ifndef EOLIAN_CXX_EOLIAN_WRAPPERS_HH
|
||||
#define EOLIAN_CXX_EOLIAN_WRAPPERS_HH
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <Eolian.h>
|
||||
|
||||
#include "eo_types.hh"
|
||||
#include "safe_strings.hh"
|
||||
#include "type_lookup.hh"
|
||||
|
||||
namespace eolian_cxx
|
||||
{
|
||||
|
||||
struct property_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_PROPERTY; };
|
||||
property_t const property = {};
|
||||
|
||||
struct setter_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_PROP_SET; };
|
||||
setter_t const setter = {};
|
||||
|
||||
struct getter_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_PROP_GET; };
|
||||
getter_t const getter = {};
|
||||
|
||||
struct method_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_METHOD; };
|
||||
method_t const method = {};
|
||||
|
||||
struct ctor_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_CTOR; };
|
||||
ctor_t const ctor = {};
|
||||
|
||||
inline Eolian_Class
|
||||
class_from_file(std::string const& file)
|
||||
{
|
||||
return ::eolian_class_find_by_file(file.c_str());
|
||||
}
|
||||
|
||||
inline std::string
|
||||
class_file(Eolian_Class const& klass)
|
||||
{
|
||||
return safe_str(::eolian_class_file_get(klass));
|
||||
}
|
||||
|
||||
inline std::string
|
||||
class_base_file(Eolian_Class const& klass)
|
||||
{
|
||||
return path_base(safe_str(::eolian_class_file_get(klass)));
|
||||
}
|
||||
|
||||
inline std::string
|
||||
class_name(Eolian_Class const& klass)
|
||||
{
|
||||
return safe_str(::eolian_class_name_get(klass));
|
||||
}
|
||||
|
||||
inline std::string
|
||||
class_full_name(Eolian_Class const& klass)
|
||||
{
|
||||
return safe_str(::eolian_class_full_name_get(klass));
|
||||
}
|
||||
|
||||
inline Eolian_Class
|
||||
class_from_name(std::string const& classname)
|
||||
{
|
||||
return ::eolian_class_find_by_name(classname.c_str());
|
||||
}
|
||||
|
||||
inline std::string
|
||||
class_eo_name(Eolian_Class const& klass)
|
||||
{
|
||||
std::string s = class_full_name(klass) + "_CLASS";
|
||||
std::transform(s.begin(), s.end(), s.begin(),
|
||||
[](int c)
|
||||
{
|
||||
return c == '.' ? '_' : c ;
|
||||
});
|
||||
return safe_upper(s);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
class_format_cxx(std::string const& fullname)
|
||||
{
|
||||
std::string s = fullname;
|
||||
auto found = s.find(".");
|
||||
while (found != std::string::npos)
|
||||
{
|
||||
s.replace(found, 1, "::");
|
||||
found = s.find(".");
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
inline std::string
|
||||
class_prefix(Eolian_Class const& klass)
|
||||
{
|
||||
std::string prefix = safe_lower(::eolian_class_eo_prefix_get(klass));
|
||||
if (prefix.empty())
|
||||
prefix = safe_lower(class_name(klass));
|
||||
assert(!prefix.empty());
|
||||
return prefix;
|
||||
}
|
||||
|
||||
inline efl::eolian::eo_class::eo_class_type
|
||||
class_type(Eolian_Class const& klass)
|
||||
{
|
||||
assert(klass != NULL);
|
||||
efl::eolian::eo_class::eo_class_type type;
|
||||
Eolian_Class_Type cls_type = ::eolian_class_type_get(klass);
|
||||
|
||||
if (cls_type == EOLIAN_CLASS_REGULAR)
|
||||
type = efl::eolian::eo_class::regular_;
|
||||
else if (cls_type == EOLIAN_CLASS_ABSTRACT)
|
||||
type = efl::eolian::eo_class::regular_noninst_;
|
||||
else if (cls_type == EOLIAN_CLASS_MIXIN)
|
||||
type = efl::eolian::eo_class::mixin_;
|
||||
else if (cls_type == EOLIAN_CLASS_INTERFACE)
|
||||
type = efl::eolian::eo_class::interface_;
|
||||
else assert(false);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
inline std::string
|
||||
class_namespace_full(Eolian_Class const& klass)
|
||||
{
|
||||
std::string s;
|
||||
const Eina_List* list =
|
||||
::eolian_class_namespaces_list_get(klass), *itr;
|
||||
void* name;
|
||||
EINA_LIST_FOREACH(list, itr, name)
|
||||
{
|
||||
s += static_cast<const char*>(name);
|
||||
s += "::";
|
||||
}
|
||||
if (s.size() >= 2)
|
||||
s = s.substr(0, s.size()-2);
|
||||
return s;
|
||||
}
|
||||
|
||||
inline efl::eina::range_ptr_list<const Eolian_Class>
|
||||
class_list_all()
|
||||
{
|
||||
return ::eolian_class_names_list_get();
|
||||
}
|
||||
|
||||
inline std::string
|
||||
function_name(Eolian_Function const& function)
|
||||
{
|
||||
return safe_str(::eolian_function_name_get(function));
|
||||
}
|
||||
|
||||
inline Eolian_Function_Type
|
||||
function_type(Eolian_Function const& function)
|
||||
{
|
||||
return ::eolian_function_type_get(function);
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type_instance
|
||||
function_return_type(Eolian_Function const& function, Eolian_Function_Type func_type = method_t::value)
|
||||
{
|
||||
return type_lookup
|
||||
(::eolian_function_return_type_get(function, func_type));
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type_instance
|
||||
function_return_type(Eolian_Function const& function, setter_t func_type)
|
||||
{
|
||||
return function_return_type(function, func_type.value);
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type_instance
|
||||
function_return_type(Eolian_Function const& function, getter_t func_type)
|
||||
{
|
||||
return function_return_type(function, func_type.value);
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type_instance
|
||||
function_return_type(Eolian_Function const& function, method_t func_type)
|
||||
{
|
||||
return function_return_type(function, func_type.value);
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type_instance
|
||||
function_return_type(Eolian_Function const& function, ctor_t func_type)
|
||||
{
|
||||
return function_return_type(function, func_type.value);
|
||||
}
|
||||
|
||||
inline bool
|
||||
property_is_getter(Eolian_Function_Type func_type)
|
||||
{
|
||||
return func_type == property_t::value || func_type == getter_t::value;
|
||||
}
|
||||
|
||||
inline bool
|
||||
property_is_getter(Eolian_Function const& function)
|
||||
{
|
||||
return property_is_getter(function_type(function));
|
||||
}
|
||||
|
||||
inline bool
|
||||
property_is_setter(Eolian_Function_Type func_type)
|
||||
{
|
||||
return func_type == property_t::value || func_type == setter_t::value;
|
||||
}
|
||||
|
||||
inline bool
|
||||
property_is_setter(Eolian_Function const& function)
|
||||
{
|
||||
return property_is_setter(function_type(function));
|
||||
}
|
||||
|
||||
inline std::string
|
||||
parameter_name(Eolian_Function_Parameter const& parameter)
|
||||
{
|
||||
return safe_strshare(::eolian_parameter_name_get(parameter));
|
||||
}
|
||||
|
||||
inline bool
|
||||
parameter_is_out(Eolian_Function_Parameter const& parameter)
|
||||
{
|
||||
Eolian_Parameter_Dir direction;
|
||||
::eolian_parameter_information_get(parameter, &direction, NULL, NULL, NULL);
|
||||
return direction == EOLIAN_OUT_PARAM || direction == EOLIAN_INOUT_PARAM;
|
||||
}
|
||||
|
||||
inline bool
|
||||
parameter_is_const(Eolian_Function_Parameter const& parameter,
|
||||
Eolian_Function_Type func_type)
|
||||
{
|
||||
return ::eolian_parameter_const_attribute_get
|
||||
(parameter, property_is_getter(func_type));
|
||||
}
|
||||
|
||||
inline bool
|
||||
parameter_is_const(Eolian_Function_Parameter const& parameter,
|
||||
getter_t func_type)
|
||||
{
|
||||
return ::eolian_parameter_const_attribute_get
|
||||
(parameter, property_is_getter(func_type.value));
|
||||
}
|
||||
|
||||
inline bool
|
||||
parameter_is_const(Eolian_Function_Parameter const& parameter,
|
||||
setter_t func_type)
|
||||
{
|
||||
return ::eolian_parameter_const_attribute_get
|
||||
(parameter, property_is_getter(func_type.value));
|
||||
}
|
||||
|
||||
inline bool
|
||||
parameter_is_const(Eolian_Function_Parameter const& parameter,
|
||||
Eolian_Function const& function)
|
||||
{
|
||||
assert(function_type(function) != EOLIAN_PROPERTY);
|
||||
return ::eolian_parameter_const_attribute_get
|
||||
(parameter, property_is_getter(function));
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type_instance
|
||||
parameter_type(Eolian_Function_Parameter const& parameter,
|
||||
Eolian_Function_Type func_type = method_t::value)
|
||||
{
|
||||
efl::eolian::eolian_type_instance type
|
||||
(type_lookup(::eolian_parameter_type_get(parameter)));
|
||||
assert(!type.empty());
|
||||
// XXX implement complex types.
|
||||
if (parameter_is_out(parameter))
|
||||
type = { type_to_native(type) + "*" };
|
||||
if (parameter_is_const(parameter, func_type))
|
||||
type.insert(0, "const ");
|
||||
return type;
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type_instance
|
||||
parameter_type(Eolian_Function_Parameter const& parameter, getter_t func_type)
|
||||
{
|
||||
return parameter_type(parameter, func_type.value);
|
||||
}
|
||||
|
||||
inline efl::eolian::eolian_type_instance
|
||||
parameter_type(Eolian_Function_Parameter const& parameter, setter_t func_type)
|
||||
{
|
||||
return parameter_type(parameter, func_type.value);
|
||||
}
|
||||
|
||||
inline efl::eolian::eo_event
|
||||
event_create(Eolian_Class const& klass, const Eolian_Event event_)
|
||||
{
|
||||
efl::eolian::eo_event event;
|
||||
const char *name, *type, *comment;
|
||||
if(::eolian_class_event_information_get(event_, &name, &type, &comment))
|
||||
{
|
||||
std::string name_ = safe_str(name);
|
||||
std::transform(name_.begin(), name_.end(), name_.begin(),
|
||||
[](int c) { return c != ',' ? c : '_'; });
|
||||
event.name = normalize_spaces(name_);
|
||||
event.eo_name = safe_upper(class_name(klass) + "_EVENT_" + event.name);
|
||||
event.comment = safe_str(comment);
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
inline efl::eolian::events_container_type
|
||||
event_list(Eolian_Class const& klass)
|
||||
{
|
||||
efl::eolian::events_container_type events;
|
||||
const Eina_List* list = eolian_class_events_list_get(klass);
|
||||
unsigned int length = eina_list_count(list);
|
||||
for (unsigned int i = 0; i < length; ++i)
|
||||
{
|
||||
Eolian_Event e = static_cast<Eolian_Event>(eina_list_nth(list, i));
|
||||
events.push_back(event_create(klass, e));
|
||||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // EOLIAN_CXX_EOLIAN_WRAPPERS_HH
|
|
@ -3,20 +3,26 @@
|
|||
#define EOLIAN_CXX_BIN_SAFE_STRINGS_HH
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cctype>
|
||||
#include <iterator>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <Eina.h>
|
||||
}
|
||||
|
||||
/// @brief Safely convert an const char* to std::string.
|
||||
/// @brief Safely convert const char* to std::string.
|
||||
///
|
||||
inline std::string
|
||||
safe_str(const char* str)
|
||||
{
|
||||
return (str != NULL) ? str : "";
|
||||
}
|
||||
|
||||
/// @brief Safely convert an Eina_Stringshare to std::string.
|
||||
/// @brief Safely convert Eina_Stringshare to std::string.
|
||||
///
|
||||
inline std::string
|
||||
safe_strshare(Eina_Stringshare* strsh)
|
||||
{
|
||||
|
@ -25,4 +31,76 @@ safe_strshare(Eina_Stringshare* strsh)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/// @brief Get a lower-case copy of string.
|
||||
///
|
||||
inline std::string
|
||||
safe_lower(std::string const& s)
|
||||
{
|
||||
std::string res;
|
||||
res.resize(s.size());
|
||||
std::transform(s.begin(), s.end(), res.begin(), ::tolower);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// @brief Get a lower-case copy of string.
|
||||
///
|
||||
inline std::string
|
||||
safe_lower(const char *s)
|
||||
{
|
||||
return safe_lower(safe_str(s));
|
||||
}
|
||||
|
||||
/// @brief Get a upper-case copy of string.
|
||||
///
|
||||
inline std::string
|
||||
safe_upper(std::string const& s)
|
||||
{
|
||||
std::string res;
|
||||
res.resize(s.size());
|
||||
std::transform(s.begin(), s.end(), res.begin(), ::toupper);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// @brief Get a upper-case copy of string.
|
||||
///
|
||||
inline std::string
|
||||
safe_upper(const char* s)
|
||||
{
|
||||
return safe_upper(safe_str(s));
|
||||
}
|
||||
|
||||
/// @brief Trim both ends of the string and replaces any
|
||||
/// subsequence of contiguous spaces with a single space.
|
||||
///
|
||||
inline std::string
|
||||
normalize_spaces(std::string const& s)
|
||||
{
|
||||
std::ostringstream os;
|
||||
bool prev_is_space = true;
|
||||
std::remove_copy_if
|
||||
(s.begin(), s.end(),
|
||||
std::ostream_iterator<char>(os),
|
||||
[&prev_is_space] (char c)
|
||||
{
|
||||
bool r = ::isspace(c);
|
||||
if (r && prev_is_space)
|
||||
return true;
|
||||
prev_is_space = r;
|
||||
return false;
|
||||
});
|
||||
std::string r = os.str();
|
||||
if (!r.empty() && ::isspace(r.back()))
|
||||
r.erase(r.end()-1, r.end());
|
||||
return r;
|
||||
}
|
||||
|
||||
inline std::string
|
||||
path_base(std::string path)
|
||||
{
|
||||
std::string::reverse_iterator
|
||||
slash = std::find(path.rbegin(), path.rend(), '/');
|
||||
return std::string(slash.base(), path.end());
|
||||
}
|
||||
|
||||
|
||||
#endif // EOLIAN_CXX_BIN_SAFE_STRINGS_HH
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
#ifndef EOLIAN_CXX_TYPE_LOOKUP_HH
|
||||
#define EOLIAN_CXX_TYPE_LOOKUP_HH
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cctype>
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
|
||||
#include <Eolian.h>
|
||||
#include <Eina.hh>
|
||||
|
||||
#include "eo_types.hh"
|
||||
#include "safe_strings.hh"
|
||||
|
||||
namespace eolian_cxx {
|
||||
|
||||
inline std::string
|
||||
type_lookup(Eolian_Type type)
|
||||
{
|
||||
if (type == NULL)
|
||||
return "void";
|
||||
// XXX add complex types implementation.
|
||||
const char *tps = eolian_type_c_type_get(type);
|
||||
std::string ret = normalize_spaces(safe_str(tps));
|
||||
::eina_stringshare_del(tps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
} // namespace eolian_cxx {
|
||||
|
||||
#endif // EOLIAN_CXX_TYPE_LOOKUP_HH
|
|
@ -99,7 +99,7 @@ eolian_cxx_inherit_01_SOURCES = \
|
|||
eolian_cxx_inherit_01.$(OBJEXT): $(GENERATED)
|
||||
|
||||
%.eo.hh: %.eo
|
||||
$(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -I$< -o $@
|
||||
$(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -I${abs_srcdir} -o $@ $<
|
||||
|
||||
%.eo.c: %.eo
|
||||
$(AM_V_EOL)$(EOLIAN_GEN) --eo --legacy $(EOLIAN_FLAGS) --gc -o $@ $<
|
||||
|
@ -114,7 +114,7 @@ clean-local:
|
|||
|
||||
install-examples:
|
||||
mkdir -p $(datadir)/eolian_cxx/examples
|
||||
$(install_sh_DATA) -c $(SRCS) $(DATA_FILES) $(datadir)/eolian_cxx/examples
|
||||
cd $(abs_srcdir) && $(install_sh_DATA) -c $(SRCS) $(DATA_FILES) $(datadir)/eolian_cxx/examples
|
||||
|
||||
uninstall-local:
|
||||
for f in $(SRCS) $(DATA_FILES); do \
|
||||
|
|
|
@ -64,7 +64,5 @@ main()
|
|||
|
||||
assert(obj1.colour_get() == obj2.colour_get());
|
||||
|
||||
// ColourableFoo obj3(10, 0xc0ffee);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
extern "C"
|
||||
{
|
||||
#include <Eolian.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include <Eolian.h>
|
||||
}
|
||||
|
||||
namespace efl { namespace eolian {
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
#ifndef EOLIAN_CXX_EO_GENERATE_HH
|
||||
#define EOLIAN_CXX_EO_GENERATE_HH
|
||||
|
||||
#include "eo_types.hh"
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
#include "eo_types.hh"
|
||||
#include "grammar/eo_header_generator.hh"
|
||||
|
||||
namespace efl { namespace eolian {
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
#ifndef EOLIAN_CXX_EO_TYPES_HH
|
||||
#define EOLIAN_CXX_EO_TYPES_HH
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
namespace efl { namespace eolian {
|
||||
|
||||
|
@ -13,6 +15,7 @@ struct eo_function;
|
|||
struct eo_event;
|
||||
|
||||
typedef std::vector<std::string> extensions_container_type;
|
||||
typedef std::vector<std::string> includes_container_type;
|
||||
typedef std::vector<eo_constructor> constructors_container_type;
|
||||
typedef std::vector<eo_function> functions_container_type;
|
||||
typedef std::vector<eo_parameter> parameters_container_type;
|
||||
|
@ -20,8 +23,8 @@ typedef std::vector<eo_event> events_container_type;
|
|||
|
||||
struct eo_generator_options
|
||||
{
|
||||
std::vector<std::string> cxx_headers;
|
||||
std::vector<std::string> c_headers;
|
||||
includes_container_type cxx_headers;
|
||||
includes_container_type c_headers;
|
||||
};
|
||||
|
||||
struct eo_class
|
||||
|
@ -73,17 +76,40 @@ struct eo_function
|
|||
inline bool
|
||||
function_is_void(eo_function const& func)
|
||||
{
|
||||
return func.ret == "void" || func.ret == "";
|
||||
return func.ret.empty() || func.ret.compare("void") == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
function_is_static(eo_function const& func)
|
||||
{
|
||||
return func.type == eo_function::class_;
|
||||
}
|
||||
|
||||
struct eo_event
|
||||
{
|
||||
std::string name;
|
||||
parameters_container_type params;
|
||||
bool is_hot;
|
||||
std::string eo_name;
|
||||
std::string comment;
|
||||
};
|
||||
|
||||
|
||||
// XXX mocked implementation. waiting for complex types...
|
||||
typedef std::string eolian_type_instance;
|
||||
typedef std::string eolian_type;
|
||||
inline bool
|
||||
type_is_void(eolian_type_instance const& type)
|
||||
{
|
||||
return type.empty() || type.compare("void") == 0;
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
namespace eolian_cxx {
|
||||
inline efl::eolian::eolian_type
|
||||
type_to_native(efl::eolian::eolian_type const& type)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // EFL_EOLIAN_CXX_EO_TYPES_HH
|
||||
|
|
|
@ -2,70 +2,73 @@
|
|||
#ifndef EOLIAN_CXX_EO_CLASS_VALIDATE_HH
|
||||
#define EOLIAN_CXX_EO_CLASS_VALIDATE_HH
|
||||
|
||||
#include <iostream> // XXX
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#include <cstdlib>
|
||||
#include "eo_types.hh"
|
||||
|
||||
namespace efl { namespace eolian {
|
||||
|
||||
inline bool
|
||||
_isvalid(const std::string& name)
|
||||
_is_valid(std::string const& value)
|
||||
{
|
||||
return name.size() > 0 and isalpha(name[0]);
|
||||
return !value.empty() and isalpha(value[0]);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void
|
||||
_validate(T val, const eo_class& cls)
|
||||
{
|
||||
if(!_is_valid(val))
|
||||
{
|
||||
static_cast<void>(cls);
|
||||
#ifndef NDEBUG
|
||||
std::abort();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
eo_class_validate(const eo_class& cls)
|
||||
{
|
||||
assert(_isvalid(cls.name));
|
||||
|
||||
// class name and type
|
||||
_validate(cls.name, cls);
|
||||
assert(cls.type != eo_class::regular_ ||
|
||||
cls.type != eo_class::regular_noninst_ ||
|
||||
cls.type != eo_class::interface_ ||
|
||||
cls.type != eo_class::mixin_);
|
||||
|
||||
{
|
||||
constructors_container_type::const_iterator it,
|
||||
first = cls.constructors.begin(),
|
||||
last = cls.constructors.end();
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
parameters_container_type::const_iterator
|
||||
param = (*it).params.begin(),
|
||||
last_param = (*it).params.end();
|
||||
assert(_isvalid((*it).name));
|
||||
for (; param != last_param; ++param)
|
||||
{
|
||||
assert(_isvalid((*param).name));
|
||||
assert(_isvalid((*param).type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
functions_container_type::const_iterator it,
|
||||
first = cls.functions.begin(),
|
||||
last = cls.functions.end();
|
||||
for (it = first; it != last; ++it)
|
||||
{
|
||||
assert(_isvalid((*it).name));
|
||||
assert(_isvalid((*it).impl));
|
||||
assert(_isvalid((*it).ret));
|
||||
parameters_container_type::const_iterator
|
||||
param = (*it).params.begin(),
|
||||
last_param = (*it).params.end();
|
||||
for (; param != last_param; ++param)
|
||||
{
|
||||
assert(_isvalid((*param).name));
|
||||
assert(_isvalid((*param).type));
|
||||
}
|
||||
}
|
||||
}
|
||||
// constructors
|
||||
for (auto it = cls.constructors.cbegin(), last = cls.constructors.cend();
|
||||
it != last; ++it)
|
||||
{
|
||||
_validate((*it).name, cls);
|
||||
// parameters
|
||||
for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
|
||||
it_p != last_p; ++it_p)
|
||||
{
|
||||
_validate((*it_p).name, cls);
|
||||
_validate((*it_p).type, cls);
|
||||
}
|
||||
}
|
||||
// functions
|
||||
for (auto it = cls.functions.begin(), last = cls.functions.end();
|
||||
it != last; ++it)
|
||||
{
|
||||
_validate((*it).name, cls);
|
||||
_validate((*it).impl, cls);
|
||||
_validate((*it).ret, cls);
|
||||
// parameters
|
||||
for (auto it_p = (*it).params.begin(), last_p = (*it).params.end();
|
||||
it_p != last_p; ++it_p)
|
||||
{
|
||||
_validate((*it_p).name, cls);
|
||||
_validate((*it_p).type, cls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} } // namespace efl { namespace eolian {
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
#ifndef EOLIAN_CXX_STD_COMMENT_HH
|
||||
#define EOLIAN_CXX_STD_COMMENT_HH
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iosfwd>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "tab.hh"
|
||||
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
#ifndef EOLIAN_CXX_STD_EO_HEADER_GENERATOR_HH
|
||||
#define EOLIAN_CXX_STD_EO_HEADER_GENERATOR_HH
|
||||
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
#include <iosfwd>
|
||||
#include <ctype.h>
|
||||
#include <cctype>
|
||||
|
||||
#include "eo_types.hh"
|
||||
#include "tab.hh"
|
||||
|
@ -84,10 +86,11 @@ namespace_tail(std::ostream& out, eo_class const& cls)
|
|||
}
|
||||
|
||||
inline void
|
||||
include_headers(std::ostream& out, eo_generator_options const& opts)
|
||||
include_headers(std::ostream& out,
|
||||
eo_class const& cls EINA_UNUSED,
|
||||
eo_generator_options const& opts)
|
||||
{
|
||||
out << "#include <Eo.h>" << endl
|
||||
<< "#include <Eo.hh>" << endl << endl
|
||||
out << "#include <Eo.hh>" << endl << endl
|
||||
<< "extern \"C\"" << endl
|
||||
<< "{" << endl;
|
||||
for (auto c_header : opts.c_headers)
|
||||
|
@ -99,14 +102,13 @@ include_headers(std::ostream& out, eo_generator_options const& opts)
|
|||
{
|
||||
out << "#include \"" << cxx_header << "\"" << endl;
|
||||
}
|
||||
out << endl;
|
||||
}
|
||||
|
||||
inline void
|
||||
eo_header_generator(std::ostream& out, eo_class const& cls, eo_generator_options const& opts)
|
||||
{
|
||||
onceguard_head(out, cls);
|
||||
include_headers(out, opts);
|
||||
include_headers(out, cls, opts);
|
||||
namespace_head(out, cls);
|
||||
eo_class_generator(out, cls);
|
||||
namespace_tail(out, cls);
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
#ifndef EOLIAN_CXX_STD_TAB_HH
|
||||
#define EOLIAN_CXX_STD_TAB_HH
|
||||
|
||||
#include <iosfwd>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace efl { namespace eolian { namespace grammar {
|
||||
|
||||
|
@ -26,27 +25,6 @@ operator<<(std::ostream& out, efl::eolian::grammar::tab tab)
|
|||
return out;
|
||||
}
|
||||
|
||||
struct tabify
|
||||
{
|
||||
int _n;
|
||||
std::string _text;
|
||||
tabify(int n, std::string const& text)
|
||||
: _n(n), _text(text)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, efl::eolian::grammar::tabify const& x)
|
||||
{
|
||||
std::string line, tab(tabsize*x._n, ' ');
|
||||
std::istringstream ss(x._text);
|
||||
while (std::getline(ss, line))
|
||||
{
|
||||
out << tab << line << endl;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
#endif // EOLIAN_CXX_STD_TAB_HH
|
||||
|
|
Loading…
Reference in New Issue