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@ \
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 \
### 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
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)
+++ /dev/null
-
-#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
+
#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)
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::functions_container_type
-_get_properties(const Eolian_Class klass)
+static efl::eolian::parameters_container_type
+convert_eolian_parameters(Eolian_Function const& function,
+ getter_t func_type)
{
- efl::eolian::functions_container_type container;
+ return convert_eolian_parameters
+ (::eolian_parameters_list_get(function), func_type.value);
+}
- std::string cxx_classname = eolian_class_name_get(klass);
- std::transform(cxx_classname.begin(), cxx_classname.end(),
- cxx_classname.begin(), ::tolower);
+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);
+}
- const Eina_List *properties;
- properties = eolian_class_functions_list_get(klass, EOLIAN_PROPERTY);
+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
+convert_eolian_property_to_functions(Eolian_Class const& klass)
+{
+ efl::eolian::functions_container_type container;
+ 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);
+
+ 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";
- // 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::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;
}
else
{
- std::string parent =
- static_cast<const char*>(eina_list_data_get(inheritances));
- std::transform(parent.begin(), parent.end(), parent.begin(), ::tolower);
+ 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 == "") ? "efl::eo::base" : parent;
+ 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_);
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;
{
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 {
#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
-#include "comments.hh"
+#include "convert_comments.hh"
#include "safe_strings.hh"
+namespace eolian_cxx {
+
static std::string
_comment_parameter(Eolian_Function_Parameter param)
{
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);
- 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);
+ if (func_type != eolian_cxx::ctor.value)
+ doc += _comment_return(function, func_type);
return doc;
}
-} // namespace detail
+} // namespace eolian_cxx
--- /dev/null
+
+#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
+++ /dev/null
-
-#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 */
#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)
{}
efl::eina::log_domain domain("eolian_cxx");
-}
-
-static void
-_opt_error(std::string message)
-{
- EINA_CXX_DOM_LOG_ERR(::domain) << message << std::endl;
- exit(EXIT_FAILURE);
-}
-
-static void
-_assert_not_dup(std::string option, std::string value)
+static bool
+opts_check(eolian_cxx::options_type const& opts)
{
- 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;
}
{
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
-_print_version()
+database_load(options_type const& opts)
{
- std::cerr
- << "Eolian C++ Binding Generator (EFL "
- << 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)
+ for (auto src : opts.include_dirs)
{
- _opt_error("Options -a and -o can't be used together.");
+ if (!::eolian_directory_scan(src.c_str()))
+ {
+ EINA_CXX_DOM_LOG_WARN(eolian_cxx::domain)
+ << "Couldn't load eolian from '" << src << "'.";
+ }
}
- else if (!opts.generate_all && opts.classname == "")
+ if (!::eolian_all_eot_files_parse())
{
- _opt_error("Neither -a nor -c provided. "
- "Don't know what to generate.");
+ EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
+ << "Eolian failed parsing eot files";
+ std::abort();
}
-}
-
-static void
-_resolve_classname(options_type& opts)
-{
- if (opts.classname == "")
+ if (!opts.in_file.empty())
{
- std::string cls = _guess_classname_from_sources(opts);
- opts.classname = cls;
+ 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 (opts.classname == "" && opts.out_file != "")
+ if (!::eolian_all_eo_files_parse())
{
- EINA_CXX_DOM_LOG_ERR(::domain)
- << "Unknown output class for " << opts.out_file
- << " : Missing '-c' option?";
+ EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
+ << "Eolian failed parsing input files";
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();
-}
+} // namespace eolian_cxx {
static void
-_load_classes(options_type const& opts)
+_print_version()
{
- 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;
- }
- }
+ std::cerr
+ << "Eolian C++ Binding Generator (EFL "
+ << PACKAGE_VERSION << ")" << std::endl;
}
static void
{
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
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[] =
{
{ "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')
{
_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;
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;
}
{
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;
}
--- /dev/null
+#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
#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)
{
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
--- /dev/null
+
+#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
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 $@ $<
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 \
assert(obj1.colour_get() == obj2.colour_get());
- // ColourableFoo obj3(10, 0xc0ffee);
-
return 0;
}
extern "C"
{
-#include <Eolian.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
+#include <Eolian.h>
}
namespace efl { namespace eolian {
#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 {
#ifndef EOLIAN_CXX_EO_TYPES_HH
#define EOLIAN_CXX_EO_TYPES_HH
+#include <algorithm>
#include <string>
#include <vector>
+#include <cassert>
namespace efl { namespace eolian {
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;
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
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
#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
-eo_class_validate(const eo_class& cls)
+_validate(T val, const eo_class& cls)
{
- assert(_isvalid(cls.name));
+ if(!_is_valid(val))
+ {
+ static_cast<void>(cls);
+#ifndef NDEBUG
+ std::abort();
+#endif
+ }
+}
+inline void
+eo_class_validate(const eo_class& cls)
+{
+ // 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 {
#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"
#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"
}
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)
{
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);
#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 {
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