summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitor Sousa <vitorsousasilva@gmail.com>2017-12-12 12:06:46 -0200
committerVitor Sousa <vitorsousasilva@gmail.com>2017-12-15 22:26:29 -0200
commitacd99be98bc6f3218af9322b23acb52ed29fb008 (patch)
tree3cee18189cc4ab31f4595721ca904bf0cc8d6847
parentb20dd869a4a10fb28a9c743910e2f2a1d2e7d1cc (diff)
efl_mono: tests and better support for structs, plus some other fixes
Fix several integer binding type deduction based in its size on C. Generation for function pointers no longer use modified argument name which is different from the parameter name. New generation context for structs. bool from UnmanagedType.I1 to UnmanagedType.U1 (correct use inside structs according to mono documentation). byte (signed char) and int8 now is correctly represented by sbyte in C#. Check parameter direction in some out generators in parameter.hh. Add efl_libs.csv to gitignore. Make eina.Value pointer constructor public. Add missing fields to efl.kw_event.Description struct. Remove eina.File workaround (let struct gen handle it). Remove is_function_ptr bool from regular_type_def and add a typedecl_type enum to it. Also add some helper methods for easier comparison. Left some test cases commented for when pointer parameters are properly working.
-rw-r--r--src/Makefile_Efl_Mono.am1
-rw-r--r--src/bin/eolian_mono/eolian/mono/function_pointer.hh4
-rw-r--r--src/bin/eolian_mono/eolian/mono/generation_contexts.hh1
-rw-r--r--src/bin/eolian_mono/eolian/mono/helpers.hh59
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_annotation.hh8
-rw-r--r--src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh8
-rw-r--r--src/bin/eolian_mono/eolian/mono/parameter.hh114
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_definition.hh437
-rw-r--r--src/bin/eolian_mono/eolian/mono/type_impl.hh39
-rw-r--r--src/bin/eolian_mono/eolian_mono.cc3
-rw-r--r--src/bindings/mono/efl_mono/.gitignore1
-rw-r--r--src/bindings/mono/eina_mono/eina_value.cs2
-rw-r--r--src/bindings/mono/eo_mono/workaround.cs17
-rw-r--r--src/lib/eolian_cxx/grammar/converting_argument.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/klass_def.hpp89
-rw-r--r--src/lib/eolian_cxx/grammar/parameter.hpp2
-rw-r--r--src/tests/efl_mono/Structs.cs355
-rw-r--r--src/tests/efl_mono/libefl_mono_native_test.c394
-rw-r--r--src/tests/efl_mono/test_testing.eo184
19 files changed, 1618 insertions, 102 deletions
diff --git a/src/Makefile_Efl_Mono.am b/src/Makefile_Efl_Mono.am
index 72a1916515..ad45a22b81 100644
--- a/src/Makefile_Efl_Mono.am
+++ b/src/Makefile_Efl_Mono.am
@@ -371,6 +371,7 @@ tests_efl_mono_efl_mono_exe_SOURCES = \
371 tests/efl_mono/Events.cs \ 371 tests/efl_mono/Events.cs \
372 tests/efl_mono/FunctionPointers.cs \ 372 tests/efl_mono/FunctionPointers.cs \
373 tests/efl_mono/Strings.cs \ 373 tests/efl_mono/Strings.cs \
374 tests/efl_mono/Structs.cs \
374 tests/efl_mono/TestUtils.cs \ 375 tests/efl_mono/TestUtils.cs \
375 tests/efl_mono/Value.cs \ 376 tests/efl_mono/Value.cs \
376 tests/efl_mono/ValueEolian.cs 377 tests/efl_mono/ValueEolian.cs
diff --git a/src/bin/eolian_mono/eolian/mono/function_pointer.hh b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
index 84fdb79881..0f91a4c41c 100644
--- a/src/bin/eolian_mono/eolian/mono/function_pointer.hh
+++ b/src/bin/eolian_mono/eolian/mono/function_pointer.hh
@@ -69,14 +69,14 @@ struct function_pointer {
69 69
70 << scope_tab << "public " << type << " ManagedCb(" << (parameter % ",") << ")\n" 70 << scope_tab << "public " << type << " ManagedCb(" << (parameter % ",") << ")\n"
71 << scope_tab << "{\n" 71 << scope_tab << "{\n"
72 << scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return ": "") << "_cb(_cb_data, " << (argument_invocation % ", ") << ");\n" 72 << scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return ": "") << "_cb(_cb_data, " << (argument_invocation_no_conversion % ", ") << ");\n"
73 << scope_tab << "}\n\n" 73 << scope_tab << "}\n\n"
74 74
75 << scope_tab << "public static " << type << " Cb(IntPtr cb_data, " << (parameter % ", ") << ")\n" 75 << scope_tab << "public static " << type << " Cb(IntPtr cb_data, " << (parameter % ", ") << ")\n"
76 << scope_tab << "{\n" 76 << scope_tab << "{\n"
77 << scope_tab << scope_tab << "GCHandle handle = GCHandle.FromIntPtr(cb_data);\n" 77 << scope_tab << scope_tab << "GCHandle handle = GCHandle.FromIntPtr(cb_data);\n"
78 << scope_tab << scope_tab << string << " cb = (" << string << ")handle.Target;\n" 78 << scope_tab << scope_tab << string << " cb = (" << string << ")handle.Target;\n"
79 << scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return " : "") << "cb(" << (argument_invocation % ", ") << ");\n" 79 << scope_tab << scope_tab << (f.return_type.c_type != "void" ? "return " : "") << "cb(" << (argument_invocation_no_conversion % ", ") << ");\n"
80 << scope_tab << "}\n" 80 << scope_tab << "}\n"
81 << "}\n" 81 << "}\n"
82 ).generate(sink, std::make_tuple(f.return_type, f.parameters, f.parameters, f.return_type, f.parameters, f_name, f_name, f.parameters), context)) 82 ).generate(sink, std::make_tuple(f.return_type, f.parameters, f.parameters, f.return_type, f.parameters, f_name, f_name, f.parameters), context))
diff --git a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
index f220c94cb6..8563afcb12 100644
--- a/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
+++ b/src/bin/eolian_mono/eolian/mono/generation_contexts.hh
@@ -10,6 +10,7 @@ struct class_context
10 concrete, 10 concrete,
11 inherit, 11 inherit,
12 inherit_native, 12 inherit_native,
13 structs,
13 }; 14 };
14 wrapper_kind current_wrapper_kind; 15 wrapper_kind current_wrapper_kind;
15}; 16};
diff --git a/src/bin/eolian_mono/eolian/mono/helpers.hh b/src/bin/eolian_mono/eolian/mono/helpers.hh
new file mode 100644
index 0000000000..28b54a5aef
--- /dev/null
+++ b/src/bin/eolian_mono/eolian/mono/helpers.hh
@@ -0,0 +1,59 @@
1#ifndef EOLIAN_MONO_HELPERS_HH
2#define EOLIAN_MONO_HELPERS_HH
3
4#include "grammar/klass_def.hpp"
5
6namespace eolian_mono {
7
8namespace attributes = efl::eolian::grammar::attributes;
9
10inline std::string type_full_name(attributes::regular_type_def const& type)
11{
12 std::string full_name;
13 for (auto& name : type.namespaces)
14 {
15 full_name += name + ".";
16 }
17 full_name += type.base_type;
18 return full_name;
19}
20
21inline std::string struct_full_name(attributes::struct_def const& struct_)
22{
23 std::string full_name;
24 for (auto& name : struct_.namespaces)
25 {
26 full_name += name + ".";
27 }
28 full_name += struct_.cxx_name;
29 return full_name;
30}
31
32// Blacklist structs that require some kind of manual binding.
33inline bool is_struct_blacklisted(std::string const& full_name)
34{
35 return full_name == "Efl.Event.Description"
36 // || full_name == "Eina.File"
37 || full_name == "Eina.Binbuf"
38 || full_name == "Eina.Slice"
39 || full_name == "Eina.Rw_Slice";
40}
41
42inline bool is_struct_blacklisted(attributes::struct_def const& struct_)
43{
44 return is_struct_blacklisted(struct_full_name(struct_));
45}
46
47inline bool is_struct_blacklisted(attributes::regular_type_def const& struct_)
48{
49 return is_struct_blacklisted(type_full_name(struct_));
50}
51
52inline bool need_struct_conversion(attributes::regular_type_def const* regular)
53{
54 return regular && regular->is_struct() && !is_struct_blacklisted(*regular);
55}
56
57}
58
59#endif
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
index 2765dcdc25..8774cd855c 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_annotation.hh
@@ -51,7 +51,7 @@ struct marshall_annotation_visitor_generate
51 match const parameter_match_table[] = 51 match const parameter_match_table[] =
52 { 52 {
53 // signed primitives 53 // signed primitives
54 {"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.I1)]"; }}, 54 {"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.U1)]"; }},
55 {"string", true, [&] { 55 {"string", true, [&] {
56 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]"; 56 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]";
57 }}, 57 }},
@@ -80,7 +80,7 @@ struct marshall_annotation_visitor_generate
80 match const return_match_table[] = 80 match const return_match_table[] =
81 { 81 {
82 // signed primitives 82 // signed primitives
83 {"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.I1)]"; }}, 83 {"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.U1)]"; }},
84 {"string", true, [&] { 84 {"string", true, [&] {
85 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]"; 85 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]";
86 }}, 86 }},
@@ -170,7 +170,7 @@ struct marshall_native_annotation_visitor_generate
170 match const parameter_match_table[] = 170 match const parameter_match_table[] =
171 { 171 {
172 // signed primitives 172 // signed primitives
173 {"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.I1)]"; }}, 173 {"bool", nullptr, [&] { return " [MarshalAs(UnmanagedType.U1)]"; }},
174 {"string", true, [&] { 174 {"string", true, [&] {
175 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]"; 175 return " [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]";
176 }}, 176 }},
@@ -191,7 +191,7 @@ struct marshall_native_annotation_visitor_generate
191 match const return_match_table[] = 191 match const return_match_table[] =
192 { 192 {
193 // signed primitives 193 // signed primitives
194 {"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.I1)]"; }}, 194 {"bool", nullptr, [&] { return " [return: MarshalAs(UnmanagedType.U1)]"; }},
195 {"string", true, [&] { 195 {"string", true, [&] {
196 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]"; 196 return " [return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(efl.eo.StringPassOwnershipMarshaler))]";
197 }}, 197 }},
diff --git a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
index caeb17f83f..7950b31213 100644
--- a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
+++ b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh
@@ -4,6 +4,7 @@
4#include "grammar/generator.hpp" 4#include "grammar/generator.hpp"
5#include "grammar/klass_def.hpp" 5#include "grammar/klass_def.hpp"
6#include "grammar/case.hpp" 6#include "grammar/case.hpp"
7#include "helpers.hh"
7#include "namespace.hh" 8#include "namespace.hh"
8#include "type_impl.hh" 9#include "type_impl.hh"
9#include "generation_contexts.hh" 10#include "generation_contexts.hh"
@@ -148,7 +149,12 @@ struct marshall_type_visitor_generate
148 }} 149 }}
149 }; 150 };
150 151
151 if(eina::optional<bool> b = call_match 152 if (regular.is_struct() && !is_struct_blacklisted(regular))
153 {
154 return as_generator(*(lower_case[string] << ".") << string << "_StructInternal")
155 .generate(sink, std::make_tuple(eolian_mono::escape_namespace(regular.namespaces), regular.base_type), *context);
156 }
157 else if (eina::optional<bool> b = call_match
152 (match_table 158 (match_table
153 , [&] (match const& m) 159 , [&] (match const& m)
154 { 160 {
diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh
index e9aa957ad7..0e3fa326d5 100644
--- a/src/bin/eolian_mono/eolian/mono/parameter.hh
+++ b/src/bin/eolian_mono/eolian/mono/parameter.hh
@@ -4,6 +4,7 @@
4#include "grammar/generator.hpp" 4#include "grammar/generator.hpp"
5#include "grammar/klass_def.hpp" 5#include "grammar/klass_def.hpp"
6#include "grammar/case.hpp" 6#include "grammar/case.hpp"
7#include "helpers.hh"
7#include "marshall_type.hh" 8#include "marshall_type.hh"
8#include "type.hh" 9#include "type.hh"
9#include "using_decl.hh" 10#include "using_decl.hh"
@@ -226,6 +227,9 @@ inline bool param_is_acceptable(attributes::parameter_def const &param, std::str
226 227
227inline bool param_should_use_out_var(attributes::parameter_def const& param, bool native) 228inline bool param_should_use_out_var(attributes::parameter_def const& param, bool native)
228{ 229{
230 if (param.direction == attributes::parameter_direction::in)
231 return false;
232
229 if ((native && param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT)) 233 if ((native && param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT))
230 || (native && param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT)) 234 || (native && param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT))
231 || param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT) 235 || param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT)
@@ -261,11 +265,18 @@ inline bool param_should_use_out_var(attributes::parameter_def const& param, boo
261 ) 265 )
262 return true; 266 return true;
263 267
268 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
269 if (need_struct_conversion(regular))
270 return true;
271
264 return false; 272 return false;
265} 273}
266 274
267inline bool param_should_use_in_var(attributes::parameter_def const& param, bool /*native*/) 275inline bool param_should_use_in_var(attributes::parameter_def const& param, bool /*native*/)
268{ 276{
277 if (param.direction != attributes::parameter_direction::in)
278 return false;
279
269 if (param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, !WANT_OUT) 280 if (param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, !WANT_OUT)
270 || param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, !WANT_OUT) 281 || param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, !WANT_OUT)
271 || param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, !WANT_OUT) 282 || param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, !WANT_OUT)
@@ -299,6 +310,10 @@ inline bool param_should_use_in_var(attributes::parameter_def const& param, bool
299 ) 310 )
300 return true; 311 return true;
301 312
313 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
314 if (need_struct_conversion(regular))
315 return true;
316
302 return false; 317 return false;
303} 318}
304 319
@@ -320,7 +335,9 @@ inline std::string direction_modifier(attributes::parameter_def const& param)
320 } 335 }
321 else if (param.direction != attributes::parameter_direction::in) 336 else if (param.direction != attributes::parameter_direction::in)
322 { 337 {
323 if (param.type.c_type == "Eina_Slice" || param.type.c_type == "Eina_Rw_Slice") 338 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
339 if (param.type.c_type == "Eina_Slice" || param.type.c_type == "Eina_Rw_Slice"
340 || need_struct_conversion(regular))
324 return " ref "; 341 return " ref ";
325 else 342 else
326 return " out "; 343 return " out ";
@@ -335,7 +352,7 @@ struct is_fp_visitor
335 352
336 bool operator()(grammar::attributes::regular_type_def const &type) const 353 bool operator()(grammar::attributes::regular_type_def const &type) const
337 { 354 {
338 return type.is_function_ptr; 355 return type.is_function_ptr();
339 } 356 }
340 357
341 template<typename T> 358 template<typename T>
@@ -445,14 +462,18 @@ struct native_argument_invocation_generator
445// Generates the correct parameter name when invoking a function 462// Generates the correct parameter name when invoking a function
446struct argument_invocation_generator 463struct argument_invocation_generator
447{ 464{
465 constexpr argument_invocation_generator(bool conversion_vars)
466 : use_conversion_vars(conversion_vars)
467 {}
468
448 template <typename OutputIterator, typename Context> 469 template <typename OutputIterator, typename Context>
449 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const 470 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
450 { 471 {
451 std::string arg = direction_modifier(param); 472 std::string arg = direction_modifier(param);
452 473
453 if (param_should_use_out_var(param, false)) 474 if (use_conversion_vars && param_should_use_out_var(param, false))
454 arg += out_variable_name(param.param_name); 475 arg += out_variable_name(param.param_name);
455 else if (param_should_use_in_var(param, false)) 476 else if (use_conversion_vars && param_should_use_in_var(param, false))
456 arg += in_variable_name(param.param_name); 477 arg += in_variable_name(param.param_name);
457 else if (param.type.original_type.visit(is_fp_visitor{})) 478 else if (param.type.original_type.visit(is_fp_visitor{}))
458 { 479 {
@@ -465,7 +486,11 @@ struct argument_invocation_generator
465 486
466 return as_generator(arg).generate(sink, attributes::unused, context); 487 return as_generator(arg).generate(sink, attributes::unused, context);
467 } 488 }
468} const argument_invocation {}; 489
490 bool const use_conversion_vars;
491} const argument_invocation {true};
492
493argument_invocation_generator const argument_invocation_no_conversion {false};
469 494
470struct native_convert_in_variable_generator 495struct native_convert_in_variable_generator
471{ 496{
@@ -475,7 +500,14 @@ struct native_convert_in_variable_generator
475 if (param.direction != attributes::parameter_direction::in) 500 if (param.direction != attributes::parameter_direction::in)
476 return true; 501 return true;
477 502
478 if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *") 503 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
504 if (need_struct_conversion(regular))
505 {
506 return as_generator(
507 "var " << string << " = " << type << "_StructConvertion.ToExternal(" << escape_keyword(param.param_name) << ");\n"
508 ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
509 }
510 else if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *")
479 { 511 {
480 return as_generator( 512 return as_generator(
481 "var " << string << " = new eina.Binbuf(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false") << ");\n" 513 "var " << string << " = new eina.Binbuf(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false") << ");\n"
@@ -530,7 +562,14 @@ struct convert_in_variable_generator
530 if (param.direction != attributes::parameter_direction::in) 562 if (param.direction != attributes::parameter_direction::in)
531 return true; 563 return true;
532 564
533 if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *") 565 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
566 if (need_struct_conversion(regular))
567 {
568 return as_generator(
569 "var " << string << " = " << type << "_StructConvertion.ToInternal(" << escape_keyword(param.param_name) << ");\n"
570 ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
571 }
572 else if (param.type.c_type == "Eina_Binbuf *" || param.type.c_type == "const Eina_Binbuf *")
534 { 573 {
535 auto var_name = in_variable_name(param.param_name); 574 auto var_name = in_variable_name(param.param_name);
536 if (!as_generator( 575 if (!as_generator(
@@ -608,7 +647,17 @@ struct convert_out_variable_generator
608 template <typename OutputIterator, typename Context> 647 template <typename OutputIterator, typename Context>
609 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const 648 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
610 { 649 {
611 if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT) 650 if (param.direction == attributes::parameter_direction::in)
651 return true;
652
653 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
654 if (need_struct_conversion(regular))
655 {
656 return as_generator(
657 "var " << string << " = new " << marshall_type << "();\n"
658 ).generate(sink, std::make_tuple(out_variable_name(param.param_name), param.type), context);
659 }
660 else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
612 || param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT) 661 || param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT)
613 || param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT) 662 || param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT)
614 || param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT) 663 || param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT)
@@ -665,7 +714,12 @@ struct native_convert_out_variable_generator
665 template <typename OutputIterator, typename Context> 714 template <typename OutputIterator, typename Context>
666 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const 715 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
667 { 716 {
668 if (param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT) 717 if (param.direction == attributes::parameter_direction::in)
718 return true;
719
720 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
721 if (need_struct_conversion(regular)
722 || param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT)
669 || param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT)) 723 || param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT))
670 { 724 {
671 return as_generator( 725 return as_generator(
@@ -740,7 +794,17 @@ struct convert_out_assign_generator
740 template <typename OutputIterator, typename Context> 794 template <typename OutputIterator, typename Context>
741 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const 795 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
742 { 796 {
743 if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT) 797 if (param.direction == attributes::parameter_direction::in)
798 return true;
799
800 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
801 if (need_struct_conversion(regular))
802 {
803 return as_generator(
804 string << " = " << type << "_StructConvertion.ToExternal(" << out_variable_name(param.param_name) << ");\n"
805 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context);
806 }
807 else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
744 || param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT) 808 || param_is_acceptable(param, "Eina_Binbuf *", !WANT_OWN, WANT_OUT)
745 || param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT) 809 || param_is_acceptable(param, "const Eina_Binbuf *", WANT_OWN, WANT_OUT)
746 || param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT) 810 || param_is_acceptable(param, "const Eina_Binbuf *", !WANT_OWN, WANT_OUT)
@@ -829,7 +893,14 @@ struct convert_return_generator
829 template <typename OutputIterator, typename Context> 893 template <typename OutputIterator, typename Context>
830 bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const 894 bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const
831 { 895 {
832 if (ret_type.c_type == "Eina_Binbuf *" || ret_type.c_type == "const Eina_Binbuf *") 896 auto regular = efl::eina::get<attributes::regular_type_def>(&ret_type.original_type);
897 if (need_struct_conversion(regular))
898 {
899 return as_generator(
900 "return " << type << "_StructConvertion.ToExternal(_ret_var);\n"
901 ).generate(sink, ret_type, context);
902 }
903 else if (ret_type.c_type == "Eina_Binbuf *" || ret_type.c_type == "const Eina_Binbuf *")
833 { 904 {
834 if (!as_generator("var _binbuf_ret = new eina.Binbuf(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"} << ");\n" 905 if (!as_generator("var _binbuf_ret = new eina.Binbuf(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"} << ");\n"
835 << scope_tab << scope_tab << "return _binbuf_ret;\n") 906 << scope_tab << scope_tab << "return _binbuf_ret;\n")
@@ -881,7 +952,17 @@ struct native_convert_out_assign_generator
881 template <typename OutputIterator, typename Context> 952 template <typename OutputIterator, typename Context>
882 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const 953 bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
883 { 954 {
884 if (param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT)) 955 if (param.direction == attributes::parameter_direction::in)
956 return true;
957
958 auto regular = efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
959 if (need_struct_conversion(regular))
960 {
961 return as_generator(
962 string << " = " << type << "_StructConvertion.ToInternal(" << string << ");\n"
963 ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context);
964 }
965 else if (param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT))
885 { 966 {
886 return as_generator( 967 return as_generator(
887 string << "= efl.eo.Globals.cached_stringshare_to_intptr(((" << string << "Inherit)wrapper).cached_stringshares, " << string << ");\n" 968 string << "= efl.eo.Globals.cached_stringshare_to_intptr(((" << string << "Inherit)wrapper).cached_stringshares, " << string << ");\n"
@@ -1001,7 +1082,14 @@ struct native_convert_return_generator
1001 template <typename OutputIterator, typename Context> 1082 template <typename OutputIterator, typename Context>
1002 bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const 1083 bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const
1003 { 1084 {
1004 if (ret_type.c_type == "const char *") 1085 auto regular = efl::eina::get<attributes::regular_type_def>(&ret_type.original_type);
1086 if (need_struct_conversion(regular))
1087 {
1088 return as_generator(
1089 "return " << type << "_StructConvertion.ToInternal(_ret_var);\n"
1090 ).generate(sink, ret_type, context);
1091 }
1092 else if (ret_type.c_type == "const char *")
1005 { 1093 {
1006 if(!ret_type.has_own) 1094 if(!ret_type.has_own)
1007 { 1095 {
diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
index ee05852904..62992357f2 100644
--- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
@@ -6,28 +6,28 @@
6#include "grammar/indentation.hpp" 6#include "grammar/indentation.hpp"
7#include "grammar/list.hpp" 7#include "grammar/list.hpp"
8#include "grammar/alternative.hpp" 8#include "grammar/alternative.hpp"
9#include "helpers.hh"
9#include "type.hh" 10#include "type.hh"
10#include "keyword.hh" 11#include "keyword.hh"
11#include "using_decl.hh" 12#include "using_decl.hh"
12 13
13namespace eolian_mono { 14namespace eolian_mono {
14 15
15// Blacklist structs that require some kind of manual binding. 16inline std::string binding_struct_name(attributes::struct_def const& struct_)
16static bool is_struct_blacklisted(attributes::struct_def const& struct_)
17{ 17{
18 std::string full_name; 18 return struct_.cxx_name;
19 19}
20 for (auto it=struct_.namespaces.begin(); it != struct_.namespaces.end(); it++) 20
21 { 21inline std::string binding_struct_internal_name(attributes::struct_def const& struct_)
22 full_name += *it + "."; 22{
23 } 23 return struct_.cxx_name + "_StructInternal";
24 24}
25 full_name += struct_.cxx_name; 25
26 return full_name == "Efl.Event.Description" 26inline std::string to_field_name(std::string const& in)
27 || full_name == "Eina.File" 27{
28 || full_name == "Eina.Binbuf" 28 std::string field_name = in;
29 || full_name == "Eina.Slice" 29 field_name[0] = std::toupper(field_name[0]); // Hack to allow 'static' as a field name
30 || full_name == "Eina.Rw_Slice"; 30 return field_name;
31} 31}
32 32
33struct struct_definition_generator 33struct struct_definition_generator
@@ -35,33 +35,22 @@ struct struct_definition_generator
35 template <typename OutputIterator, typename Context> 35 template <typename OutputIterator, typename Context>
36 bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const 36 bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
37 { 37 {
38 if (is_struct_blacklisted(struct_))
39 return true;
40
41 std::vector<std::string> cpp_namespaces = escape_namespace(attributes::cpp_namespaces(struct_.namespaces));
42
43 auto open_namespace = *("namespace " << string << " { ") << "\n";
44 if(!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context))) return false;
45
46 if(!as_generator 38 if(!as_generator
47 ( 39 (
40 "[StructLayout(LayoutKind.Sequential)]\n"
48 "public struct " << string << "\n{\n" 41 "public struct " << string << "\n{\n"
49 ) 42 )
50 .generate(sink, struct_.cxx_name, context)) 43 .generate(sink, binding_struct_name(struct_), context))
51 return false; 44 return false;
52 45
53 // iterate struct fields 46 // iterate struct fields
54 for(auto first = std::begin(struct_.fields) 47 for (auto const& field : struct_.fields)
55 , last = std::end(struct_.fields); first != last; ++first)
56 { 48 {
57 auto field_name = (*first).name;
58 auto field_type = (*first).type;
59 field_name[0] = std::toupper(field_name[0]); // Hack to allow 'static' as a field name
60 if (!as_generator 49 if (!as_generator
61 ( 50 (
62 "public " << type << " " << string << ";\n" 51 " public " << type << " " << string << ";\n"
63 ) 52 )
64 .generate(sink, std::make_tuple(field_type, field_name), context)) 53 .generate(sink, std::make_tuple(field.type, to_field_name(field.name)), context))
65 return false; 54 return false;
66 } 55 }
67 56
@@ -77,14 +66,354 @@ struct struct_definition_generator
77 66
78 if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false; 67 if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false;
79 68
69 return true;
70 }
71} const struct_definition {};
72
73
74struct struct_internal_definition_generator
75{
76 template <typename OutputIterator, typename Context>
77 bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
78 {
79 if (!as_generator
80 (
81 "[StructLayout(LayoutKind.Sequential)]\n"
82 "public struct " << string << "\n{\n"
83 )
84 .generate(sink, binding_struct_internal_name(struct_), context))
85 return false;
86
87 // iterate struct fields
88 for (auto const& field : struct_.fields)
89 {
90 auto field_name = to_field_name(field.name);
91 auto klass = efl::eina::get<attributes::klass_name>(&field.type.original_type);
92 auto regular = efl::eina::get<attributes::regular_type_def>(&field.type.original_type);
93
94 if (klass
95 || (regular && (regular->base_type == "string"
96 || regular->base_type == "mstring"
97 || regular->base_type == "stringshare"
98 || regular->base_type == "any_value_ptr")))
99 {
100 if (!as_generator(" public System.IntPtr " << string << ";\n")
101 .generate(sink, field_name, context))
102 return false;
103 }
104 else if (!as_generator(eolian_mono::marshall_annotation(false) << " public " << eolian_mono::marshall_type(false) << " " << string << ";\n")
105 .generate(sink, std::make_tuple(field.type, field.type, field_name), context))
106 return false;
107 }
108
109 // Check whether this is an extern struct without declared fields in .eo file and generate a
110 // placeholder field if positive.
111 // Mono's JIT is picky when generating function pointer for delegates with empty structs, leading to
112 // those 'mini-amd64.c condition fields not met' crashes.
113 if (struct_.fields.size() == 0)
114 {
115 if (!as_generator("public IntPtr field;\n").generate(sink, nullptr, context))
116 return false;
117 }
118
119 if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false;
120
121 return true;
122 }
123} const struct_internal_definition {};
124
125
126// Conversors generation //
127
128struct to_internal_field_convert_generator
129{
130 template <typename OutputIterator, typename Context>
131 bool generate(OutputIterator sink, attributes::struct_field_def const& field, Context const& context) const
132 {
133 auto field_name = to_field_name(field.name);
134 auto regular = efl::eina::get<attributes::regular_type_def>(&field.type.original_type);
135 auto klass = efl::eina::get<attributes::klass_name>(&field.type.original_type);
136 auto complex = efl::eina::get<attributes::complex_type_def>(&field.type.original_type);
137
138 if (klass)
139 {
140 if (!as_generator(
141 scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ".raw_handle;\n")
142 .generate(sink, std::make_tuple(field_name, field_name), context))
143 return false;
144 }
145 else if ((complex && (complex->outer.base_type == "array"
146 || complex->outer.base_type == "inarray"
147 || complex->outer.base_type == "list"
148 || complex->outer.base_type == "inlist"
149 || complex->outer.base_type == "iterator"
150 || complex->outer.base_type == "hash"))
151 || field.type.c_type == "Eina_Binbuf *" || field.type.c_type == "const Eina_Binbuf *")
152 {
153 // Always assumes pointer
154 if (!as_generator(
155 scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ".Handle;\n")
156 .generate(sink, std::make_tuple(field_name, field_name), context))
157 return false;
158 }
159 else if (need_struct_conversion(regular))
160 {
161 if (!as_generator(
162 scope_tab << scope_tab << "_internal_struct." << string << " = " << type << "_StructConvertion.ToInternal(_external_struct." << string << ");\n")
163 .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
164 return false;
165 }
166 else if (regular && (regular->base_type == "string" || regular->base_type == "mstring"))
167 {
168 if (!as_generator(
169 scope_tab << scope_tab << "_internal_struct." << string << " = eina.MemoryNative.StrDup(_external_struct." << string << ");\n")
170 .generate(sink, std::make_tuple(field_name, field_name), context))
171 return false;
172 }
173 else if (regular && regular->base_type == "stringshare")
174 {
175 if (!as_generator(
176 scope_tab << scope_tab << "_internal_struct." << string << " = eina.Stringshare.eina_stringshare_add(_external_struct." << string << ");\n")
177 .generate(sink, std::make_tuple(field_name, field_name), context))
178 return false;
179 }
180 else if (field.type.c_type == "Eina_Slice" || field.type.c_type == "const Eina_Slice"
181 || field.type.c_type == "Eina_Rw_Slice" || field.type.c_type == "const Eina_Rw_Slice")
182 {
183 if (!as_generator(
184 "\n" <<
185 scope_tab << scope_tab << "_internal_struct." << field_name << ".Len = _external_struct." << field_name << ".Len;\n" <<
186 scope_tab << scope_tab << "_internal_struct." << field_name << ".Mem = _external_struct." << field_name << ".Mem;\n\n")
187 .generate(sink, attributes::unused, context))
188 return false;
189 }
190 else if (field.type.c_type == "Eina_Value" || field.type.c_type == "const Eina_Value")
191 {
192 if (!as_generator(
193 scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ".GetNative();\n"
194 ).generate(sink, std::make_tuple(field_name, field_name), context))
195 return false;
196 }
197 else if (field.type.c_type == "Eina_Value *" || field.type.c_type == "const Eina_Value *")
198 {
199 if (!as_generator(
200 scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ".Handle;\n"
201 ).generate(sink, std::make_tuple(field_name, field_name), context))
202 return false;
203 }
204 else // primitives and enums
205 {
206 if (!as_generator(
207 scope_tab << scope_tab << "_internal_struct." << string << " = _external_struct." << string << ";\n")
208 .generate(sink, std::make_tuple(field_name, field_name), context))
209 return false;
210 }
211 return true;
212 }
213} const to_internal_field_convert {};
214
215struct to_external_field_convert_generator
216{
217 template <typename OutputIterator, typename Context>
218 bool generate(OutputIterator sink, attributes::struct_field_def const& field, Context const& context) const
219 {
220 auto field_name = to_field_name(field.name);
221 auto regular = efl::eina::get<attributes::regular_type_def>(&field.type.original_type);
222 auto klass = efl::eina::get<attributes::klass_name>(&field.type.original_type);
223 auto complex = efl::eina::get<attributes::complex_type_def>(&field.type.original_type);
224
225 if (klass)
226 {
227 if (!as_generator(
228 "\n"
229 << scope_tab << scope_tab << "_external_struct." << string
230 << " = (" << type << ") System.Activator.CreateInstance(typeof("
231 << type << "Concrete), new System.Object[] {_internal_struct." << string << "});\n"
232 << scope_tab << scope_tab << "efl.eo.Globals.efl_ref(_internal_struct." << string << ");\n\n")
233 .generate(sink, std::make_tuple(field_name, field.type, field.type, field_name, field_name), context))
234 return false;
235 }
236 else if (field.type.c_type == "Eina_Binbuf *" || field.type.c_type == "const Eina_Binbuf *")
237 {
238 if (!as_generator(
239 scope_tab << scope_tab << "_external_struct." << string << " = new " << type << "(_internal_struct." << string << ", false);\n")
240 .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
241 return false;
242 }
243 else if (complex && (complex->outer.base_type == "array"
244 || complex->outer.base_type == "inarray"
245 || complex->outer.base_type == "list"
246 || complex->outer.base_type == "inlist"
247 || complex->outer.base_type == "iterator"))
248 {
249 // Always assumes pointer
250 if (!as_generator(
251 scope_tab << scope_tab << "_external_struct." << string << " = new " << type << "(_internal_struct." << string << ", false, false);\n")
252 .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
253 return false;
254 }
255 else if (complex && complex->outer.base_type == "hash")
256 {
257 if (!as_generator(
258 scope_tab << scope_tab << "_external_struct." << string << " = new " << type << "(_internal_struct." << string << ", false, false, false);\n")
259 .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
260 return false;
261 }
262 else if (need_struct_conversion(regular))
263 {
264 if (!as_generator(
265 scope_tab << scope_tab << "_external_struct." << string << " = " << type << "_StructConvertion.ToExternal(_internal_struct." << string << ");\n")
266 .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
267 return false;
268 }
269 else if (regular && (regular->base_type == "string" || regular->base_type == "mstring" || regular->base_type == "stringshare"))
270 {
271 if (!as_generator(
272 scope_tab << scope_tab << "_external_struct." << string << " = eina.StringConversion.NativeUtf8ToManagedString(_internal_struct." << string << ");\n")
273 .generate(sink, std::make_tuple(field_name, field_name), context))
274 return false;
275 }
276 else if (field.type.c_type == "Eina_Slice" || field.type.c_type == "const Eina_Slice"
277 || field.type.c_type == "Eina_Rw_Slice" || field.type.c_type == "const Eina_Rw_Slice")
278 {
279 if (!as_generator(
280 "\n" <<
281 scope_tab << scope_tab << "_external_struct." << field_name << ".Len = _internal_struct." << field_name << ".Len;\n" <<
282 scope_tab << scope_tab << "_external_struct." << field_name << ".Mem = _internal_struct." << field_name << ".Mem;\n\n")
283 .generate(sink, attributes::unused, context))
284 return false;
285 }
286 else if (field.type.c_type == "Eina_Value" || field.type.c_type == "const Eina_Value")
287 {
288 if (!as_generator(
289 scope_tab << scope_tab << "_external_struct." << string << " = new eina.Value(_internal_struct." << string << ");\n"
290 ).generate(sink, std::make_tuple(field_name, field_name), context))
291 return false;
292 }
293 else if (field.type.c_type == "Eina_Value *" || field.type.c_type == "const Eina_Value *")
294 {
295 if (!as_generator(
296 scope_tab << scope_tab << "_external_struct." << string << " = new eina.Value(_internal_struct." << string << ", eina.ValueOwnership.Unmanaged);\n"
297 ).generate(sink, std::make_tuple(field_name, field_name), context))
298 return false;
299 }
300 else // primitives and enums
301 {
302 if (!as_generator(
303 scope_tab << scope_tab << "_external_struct." << string << " = _internal_struct." << string << ";\n")
304 .generate(sink, std::make_tuple(field_name, field_name), context))
305 return false;
306 }
307 return true;
308 }
309} const to_external_field_convert {};
310
311struct struct_binding_conversion_functions_generator
312{
313 template <typename OutputIterator, typename Context>
314 bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
315 {
316 // Open conversion class
317 if (!as_generator
318 (
319 "public static class " << string << "_StructConvertion\n{\n"
320 )
321 .generate(sink, struct_.cxx_name, context))
322 return false;
323
324 // to internal
325 if (!as_generator
326 (
327 scope_tab << "public static " << string << " ToInternal(" << string << " _external_struct)\n"
328 << scope_tab << "{\n"
329 << scope_tab << scope_tab << "var _internal_struct = new " << string << "();\n\n"
330 )
331 .generate(sink, std::make_tuple(binding_struct_internal_name(struct_)
332 , binding_struct_name(struct_)
333 , binding_struct_internal_name(struct_)
334 ), context))
335 return false;
336
337 for (auto const& field : struct_.fields)
338 {
339 if (!to_internal_field_convert.generate(sink, field, context))
340 return false;
341 }
342
343 if (!as_generator
344 (
345 "\n"
346 << scope_tab << scope_tab << "return _internal_struct;\n"
347 << scope_tab << "}\n\n"
348 )
349 .generate(sink, attributes::unused, context))
350 return false;
351
352 // to external
353 if (!as_generator
354 (
355 scope_tab << "public static " << string << " ToExternal(" << string << " _internal_struct)\n"
356 << scope_tab << "{\n"
357 << scope_tab << scope_tab << "var _external_struct = new " << string << "();\n\n"
358 )
359 .generate(sink, std::make_tuple(binding_struct_name(struct_)
360 , binding_struct_internal_name(struct_)
361 , binding_struct_name(struct_)
362 ), context))
363 return false;
364
365 for (auto const& field : struct_.fields)
366 {
367 if (!to_external_field_convert.generate(sink, field, context))
368 return false;
369 }
370
371 if (!as_generator
372 (
373 "\n"
374 << scope_tab << scope_tab << "return _external_struct;\n"
375 << scope_tab << "}\n\n"
376 )
377 .generate(sink, attributes::unused, context))
378 return false;
379
380 // Close conversion class
381 if (!as_generator("}\n").generate(sink, attributes::unused, context))
382 return false;
383
384 return true;
385 }
386} const struct_binding_conversion_functions {};
387
388struct struct_entities_generator
389{
390 template <typename OutputIterator, typename Context>
391 bool generate(OutputIterator sink, attributes::struct_def const& struct_, Context const& context) const
392 {
393 if (is_struct_blacklisted(struct_))
394 return true;
395
396 std::vector<std::string> cpp_namespaces = escape_namespace(attributes::cpp_namespaces(struct_.namespaces));
397
398 auto open_namespace = *("namespace " << string << " { ") << "\n";
399 if (!as_generator(open_namespace).generate(sink, cpp_namespaces, add_lower_case_context(context)))
400 return false;
401
402 if (!struct_definition.generate(sink, struct_, context))
403 return false;
404
405 if (!struct_internal_definition.generate(sink, struct_, context))
406 return false;
407
408 if (!struct_binding_conversion_functions.generate(sink, struct_, context))
409 return false;
410
80 auto close_namespace = *(lit("} ")) << "\n"; 411 auto close_namespace = *(lit("} ")) << "\n";
81 if(!as_generator(close_namespace).generate(sink, cpp_namespaces, context)) return false; 412 if(!as_generator(close_namespace).generate(sink, cpp_namespaces, context)) return false;
82 413
83 return true; 414 return true;
84 } 415 }
85}; 416} const struct_entities {};
86
87struct_definition_generator const struct_definition = {};
88 417
89} 418}
90 419
@@ -95,9 +424,49 @@ struct is_eager_generator< ::eolian_mono::struct_definition_generator> : std::tr
95template <> 424template <>
96struct is_generator< ::eolian_mono::struct_definition_generator> : std::true_type {}; 425struct is_generator< ::eolian_mono::struct_definition_generator> : std::true_type {};
97 426
427template <>
428struct is_eager_generator< ::eolian_mono::struct_internal_definition_generator> : std::true_type {};
429template <>
430struct is_generator< ::eolian_mono::struct_internal_definition_generator> : std::true_type {};
431
432template <>
433struct is_eager_generator< ::eolian_mono::to_internal_field_convert_generator> : std::true_type {};
434template <>
435struct is_generator< ::eolian_mono::to_internal_field_convert_generator> : std::true_type {};
436
437template <>
438struct is_eager_generator< ::eolian_mono::to_external_field_convert_generator> : std::true_type {};
439template <>
440struct is_generator< ::eolian_mono::to_external_field_convert_generator> : std::true_type {};
441
442template <>
443struct is_eager_generator< ::eolian_mono::struct_binding_conversion_functions_generator> : std::true_type {};
444template <>
445struct is_generator< ::eolian_mono::struct_binding_conversion_functions_generator> : std::true_type {};
446
447template <>
448struct is_eager_generator< ::eolian_mono::struct_entities_generator> : std::true_type {};
449template <>
450struct is_generator< ::eolian_mono::struct_entities_generator> : std::true_type {};
451
98namespace type_traits { 452namespace type_traits {
99template <> 453template <>
100struct attributes_needed< ::eolian_mono::struct_definition_generator> : std::integral_constant<int, 1> {}; 454struct attributes_needed< ::eolian_mono::struct_definition_generator> : std::integral_constant<int, 1> {};
455
456template <>
457struct attributes_needed< ::eolian_mono::struct_internal_definition_generator> : std::integral_constant<int, 1> {};
458
459template <>
460struct attributes_needed< ::eolian_mono::to_internal_field_convert_generator> : std::integral_constant<int, 1> {};
461
462template <>
463struct attributes_needed< ::eolian_mono::to_external_field_convert_generator> : std::integral_constant<int, 1> {};
464
465template <>
466struct attributes_needed< ::eolian_mono::struct_binding_conversion_functions_generator> : std::integral_constant<int, 1> {};
467
468template <>
469struct attributes_needed< ::eolian_mono::struct_entities_generator> : std::integral_constant<int, 1> {};
101} 470}
102 471
103} } } 472} } }
diff --git a/src/bin/eolian_mono/eolian/mono/type_impl.hh b/src/bin/eolian_mono/eolian/mono/type_impl.hh
index d6d753b88d..3d3950c172 100644
--- a/src/bin/eolian_mono/eolian/mono/type_impl.hh
+++ b/src/bin/eolian_mono/eolian/mono/type_impl.hh
@@ -13,12 +13,28 @@ namespace eina = efl::eina;
13template <typename T> 13template <typename T>
14T const* as_const_pointer(T* p) { return p; } 14T const* as_const_pointer(T* p) { return p; }
15 15
16inline
16attributes::regular_type_def replace_base_type(attributes::regular_type_def v, std::string name) 17attributes::regular_type_def replace_base_type(attributes::regular_type_def v, std::string name)
17{ 18{
18 v.base_type = name; 19 v.base_type = name;
19 return v; 20 return v;
20} 21}
21 22
23template <typename T>
24attributes::regular_type_def replace_base_integer(attributes::regular_type_def v)
25{
26 bool s = std::is_signed<T>::value;
27 switch (sizeof(T))
28 {
29 case 1: return s ? replace_base_type(v, " sbyte") : replace_base_type(v, " byte");
30 case 2: return s ? replace_base_type(v, " short") : replace_base_type(v, " ushort");
31 case 4: return s ? replace_base_type(v, " int") : replace_base_type(v, " uint");
32 case 8: return s ? replace_base_type(v, " long") : replace_base_type(v, " ulong");
33 default: return v;
34 }
35}
36
37inline
22attributes::complex_type_def replace_outer(attributes::complex_type_def v, attributes::regular_type_def const& regular) 38attributes::complex_type_def replace_outer(attributes::complex_type_def v, attributes::regular_type_def const& regular)
23{ 39{
24 v.outer = regular; 40 v.outer = regular;
@@ -62,26 +78,29 @@ struct visitor_generate
62 const match_table[] = 78 const match_table[] =
63 { 79 {
64 // signed primitives 80 // signed primitives
65 {"byte", nullptr, [&] { return replace_base_type(regular, " byte"); }} 81 {"byte", nullptr, [&] { return replace_base_type(regular, " sbyte"); }}
66 , {"llong", nullptr, [&] { return replace_base_type(regular, " long"); }} 82 , {"short", nullptr, [&] { return replace_base_integer<short>(regular); }}
67 , {"int8", nullptr, [&] { return replace_base_type(regular, " byte"); }} 83 , {"int", nullptr, [&] { return replace_base_integer<int>(regular); }}
84 , {"long", nullptr, [&] { return replace_base_integer<long>(regular); }}
85 , {"llong", nullptr, [&] { return replace_base_integer<long long>(regular); }}
86 , {"int8", nullptr, [&] { return replace_base_type(regular, " sbyte"); }}
68 , {"int16", nullptr, [&] { return replace_base_type(regular, " short"); }} 87 , {"int16", nullptr, [&] { return replace_base_type(regular, " short"); }}
69 , {"int32", nullptr, [&] { return replace_base_type(regular, " int"); }} 88 , {"int32", nullptr, [&] { return replace_base_type(regular, " int"); }}
70 , {"int64", nullptr, [&] { return replace_base_type(regular, " long"); }} 89 , {"int64", nullptr, [&] { return replace_base_type(regular, " long"); }}
71 , {"ssize", nullptr, [&] { return replace_base_type(regular, " long"); }} 90 , {"ssize", nullptr, [&] { return replace_base_integer<ssize_t>(regular); }}
72 // unsigned primitives 91 // unsigned primitives
73 , {"ubyte", nullptr, [&] { return replace_base_type(regular, " byte"); }} 92 , {"ubyte", nullptr, [&] { return replace_base_type(regular, " byte"); }}
74 , {"ushort", nullptr, [&] { return replace_base_type(regular, " ushort"); }} 93 , {"ushort", nullptr, [&] { return replace_base_integer<unsigned short>(regular); }}
75 , {"uint", nullptr, [&] { return replace_base_type(regular, " uint"); }} 94 , {"uint", nullptr, [&] { return replace_base_integer<unsigned int>(regular); }}
76 , {"ulong", nullptr, [&] { return replace_base_type(regular, " ulong"); }} 95 , {"ulong", nullptr, [&] { return replace_base_integer<unsigned long>(regular); }}
77 , {"ullong", nullptr, [&] { return replace_base_type(regular, " ulong"); }} 96 , {"ullong", nullptr, [&] { return replace_base_integer<unsigned long long>(regular); }}
78 , {"uint8", nullptr, [&] { return replace_base_type(regular, " byte"); }} 97 , {"uint8", nullptr, [&] { return replace_base_type(regular, " byte"); }}
79 , {"uint16", nullptr, [&] { return replace_base_type(regular, " ushort"); }} 98 , {"uint16", nullptr, [&] { return replace_base_type(regular, " ushort"); }}
80 , {"uint32", nullptr, [&] { return replace_base_type(regular, " uint"); }} 99 , {"uint32", nullptr, [&] { return replace_base_type(regular, " uint"); }}
81 , {"uint64", nullptr, [&] { return replace_base_type(regular, " ulong"); }} 100 , {"uint64", nullptr, [&] { return replace_base_type(regular, " ulong"); }}
82 , {"size", nullptr, [&] { return replace_base_type(regular, " ulong"); }} 101 , {"size", nullptr, [&] { return replace_base_integer<size_t>(regular); }}
83 102
84 , {"ptrdiff", nullptr, [&] { return replace_base_type(regular, " long"); }} 103 , {"ptrdiff", nullptr, [&] { return replace_base_integer<ptrdiff_t>(regular); }}
85 , {"intptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }} 104 , {"intptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }}
86 , {"void_ptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }} 105 , {"void_ptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }}
87 , {"void", nullptr, [&] 106 , {"void", nullptr, [&]
diff --git a/src/bin/eolian_mono/eolian_mono.cc b/src/bin/eolian_mono/eolian_mono.cc
index 43eebfc1f2..db50906318 100644
--- a/src/bin/eolian_mono/eolian_mono.cc
+++ b/src/bin/eolian_mono/eolian_mono.cc
@@ -183,7 +183,8 @@ run(options_type const& opts)
183 , struct_last; struct_iterator != struct_last; ++struct_iterator) 183 , struct_last; struct_iterator != struct_last; ++struct_iterator)
184 { 184 {
185 efl::eolian::grammar::attributes::struct_def struct_(&*struct_iterator, opts.unit); 185 efl::eolian::grammar::attributes::struct_def struct_(&*struct_iterator, opts.unit);
186 if (!eolian_mono::struct_definition.generate(iterator, struct_, efl::eolian::grammar::context_null())) 186 auto structs_cxt = context_add_tag(class_context{class_context::structs}, context);
187 if (!eolian_mono::struct_entities.generate(iterator, struct_, structs_cxt))
187 { 188 {
188 throw std::runtime_error("Failed to generate struct"); 189 throw std::runtime_error("Failed to generate struct");
189 } 190 }
diff --git a/src/bindings/mono/efl_mono/.gitignore b/src/bindings/mono/efl_mono/.gitignore
index cc8a6c3119..ebc334c1d4 100644
--- a/src/bindings/mono/efl_mono/.gitignore
+++ b/src/bindings/mono/efl_mono/.gitignore
@@ -1 +1,2 @@
1/efl_libs.cs 1/efl_libs.cs
2/efl_libs.csv
diff --git a/src/bindings/mono/eina_mono/eina_value.cs b/src/bindings/mono/eina_mono/eina_value.cs
index 1c9a78ce8d..15c06590fa 100644
--- a/src/bindings/mono/eina_mono/eina_value.cs
+++ b/src/bindings/mono/eina_mono/eina_value.cs
@@ -681,7 +681,7 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
681 this.Ownership = ValueOwnership.Managed; 681 this.Ownership = ValueOwnership.Managed;
682 } 682 }
683 683
684 internal Value(IntPtr handle, ValueOwnership ownership=ValueOwnership.Managed) { 684 public Value(IntPtr handle, ValueOwnership ownership=ValueOwnership.Managed) {
685 this.Handle = handle; 685 this.Handle = handle;
686 this.Ownership = ownership; 686 this.Ownership = ownership;
687 } 687 }
diff --git a/src/bindings/mono/eo_mono/workaround.cs b/src/bindings/mono/eo_mono/workaround.cs
index 7e338de8ef..d29ce3969f 100644
--- a/src/bindings/mono/eo_mono/workaround.cs
+++ b/src/bindings/mono/eo_mono/workaround.cs
@@ -59,7 +59,10 @@ namespace efl { namespace kw_event {
59 59
60[StructLayout(LayoutKind.Sequential)] 60[StructLayout(LayoutKind.Sequential)]
61public struct Description { 61public struct Description {
62 IntPtr pointer; // Opaque type, just pass the pointer. What about hot/freeze/etc? 62 public IntPtr Name;
63 [MarshalAs(UnmanagedType.U1)] public bool Unfreezable;
64 [MarshalAs(UnmanagedType.U1)] public bool Legacy_is;
65 [MarshalAs(UnmanagedType.U1)] public bool Restart;
63 66
64 private static Dictionary<string, IntPtr> descriptions = new Dictionary<string, IntPtr>(); 67 private static Dictionary<string, IntPtr> descriptions = new Dictionary<string, IntPtr>();
65 68
@@ -76,7 +79,10 @@ public struct Description {
76 descriptions.Add(name, data); 79 descriptions.Add(name, data);
77 } 80 }
78 81
79 this.pointer = descriptions[name]; 82 this.Name = descriptions[name];
83 this.Unfreezable = false;
84 this.Legacy_is = false;
85 this.Restart = false;
80 } 86 }
81}; 87};
82 88
@@ -241,6 +247,7 @@ public struct Efl_Font_Size {
241 247
242namespace eina { 248namespace eina {
243 249
250[StructLayout(LayoutKind.Sequential)]
244public struct Rectangle { 251public struct Rectangle {
245 public int x; 252 public int x;
246 public int y; 253 public int y;
@@ -250,12 +257,6 @@ public struct Rectangle {
250 257
251} 258}
252 259
253namespace eina {
254
255public interface File {}
256
257}
258
259namespace evas { 260namespace evas {
260 261
261/* Copied from Evas_Legacy.h */ 262/* Copied from Evas_Legacy.h */
diff --git a/src/lib/eolian_cxx/grammar/converting_argument.hpp b/src/lib/eolian_cxx/grammar/converting_argument.hpp
index eb7ef57376..c419d36b7c 100644
--- a/src/lib/eolian_cxx/grammar/converting_argument.hpp
+++ b/src/lib/eolian_cxx/grammar/converting_argument.hpp
@@ -26,7 +26,7 @@ struct converting_argument_generator
26 bool operator()(T const&) const { return false;} 26 bool operator()(T const&) const { return false;}
27 bool operator()(attributes::regular_type_def const& r) const 27 bool operator()(attributes::regular_type_def const& r) const
28 { 28 {
29 return r.is_function_ptr; 29 return r.is_function_ptr();
30 } 30 }
31 } static const is_function_ptr; 31 } static const is_function_ptr;
32 template <typename OutputIterator, typename Context> 32 template <typename OutputIterator, typename Context>
diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp
index d1fce8f6d9..f95b765cee 100644
--- a/src/lib/eolian_cxx/grammar/klass_def.hpp
+++ b/src/lib/eolian_cxx/grammar/klass_def.hpp
@@ -24,7 +24,7 @@ namespace efl { namespace eolian { namespace grammar {
24namespace attributes { 24namespace attributes {
25 25
26struct complex_type_def; 26struct complex_type_def;
27 27
28} 28}
29 29
30namespace attributes { 30namespace attributes {
@@ -64,16 +64,44 @@ bool lexicographical_compare(std::tuple<T, U> const& lhs
64 || (!(std::get<0>(rhs) < std::get<0>(lhs)) 64 || (!(std::get<0>(rhs) < std::get<0>(lhs))
65 && std::get<1>(lhs) < std::get<1>(rhs)); 65 && std::get<1>(lhs) < std::get<1>(rhs));
66} 66}
67 67
68enum class typedecl_type
69{
70 unknown,
71 struct_,
72 struct_opaque,
73 enum_,
74 alias,
75 function_ptr,
76};
77
78inline typedecl_type typedecl_type_get(Eolian_Typedecl const* decl)
79{
80 if (!decl)
81 return typedecl_type::unknown;
82
83 Eolian_Typedecl_Type t = eolian_typedecl_type_get(decl);
84 switch (t)
85 {
86 case EOLIAN_TYPEDECL_UNKNOWN: return typedecl_type::unknown;
87 case EOLIAN_TYPEDECL_STRUCT: return typedecl_type::struct_;
88 case EOLIAN_TYPEDECL_STRUCT_OPAQUE: return typedecl_type::struct_opaque;
89 case EOLIAN_TYPEDECL_ENUM: return typedecl_type::enum_;
90 case EOLIAN_TYPEDECL_ALIAS: return typedecl_type::alias;
91 case EOLIAN_TYPEDECL_FUNCTION_POINTER: return typedecl_type::function_ptr;
92 default: return typedecl_type::unknown;
93 }
94}
95
68struct type_def; 96struct type_def;
69bool operator==(type_def const& rhs, type_def const& lhs); 97bool operator==(type_def const& rhs, type_def const& lhs);
70bool operator!=(type_def const& rhs, type_def const& lhs); 98bool operator!=(type_def const& rhs, type_def const& lhs);
71 99
72enum class class_type 100enum class class_type
73{ 101{
74 regular, abstract_, mixin, interface_ 102 regular, abstract_, mixin, interface_
75}; 103};
76 104
77struct klass_name 105struct klass_name
78{ 106{
79 std::vector<std::string> namespaces; 107 std::vector<std::string> namespaces;
@@ -168,19 +196,28 @@ get(klass_name const& klass)
168{ 196{
169 return tuple_element<N, klass_name>::get(klass); 197 return tuple_element<N, klass_name>::get(klass);
170} 198}
171 199
172struct regular_type_def 200struct regular_type_def
173{ 201{
174 regular_type_def() : is_undefined(false), is_function_ptr(false) {} 202 regular_type_def() : type_type(typedecl_type::unknown), is_undefined(false) {}
175 regular_type_def(std::string base_type, qualifier_def qual, std::vector<std::string> namespaces 203 regular_type_def(std::string base_type, qualifier_def qual, std::vector<std::string> namespaces
176 , bool is_undefined = false, bool is_function_ptr = false) 204 , typedecl_type type_type = typedecl_type::unknown, bool is_undefined = false)
177 : base_type(std::move(base_type)), base_qualifier(qual), namespaces(std::move(namespaces)) 205 : base_type(std::move(base_type)), base_qualifier(qual), namespaces(std::move(namespaces))
178 , is_undefined(is_undefined), is_function_ptr(is_function_ptr) {} 206 , type_type(type_type), is_undefined(is_undefined) {}
179 207
208 bool is_type(typedecl_type tt) const { return type_type == tt; }
209 bool is_unknown() const { return is_type(typedecl_type::unknown); }
210 bool is_struct() const { return is_type(typedecl_type::struct_); }
211 bool is_struct_opaque() const { return is_type(typedecl_type::struct_opaque); }
212 bool is_enum() const { return is_type(typedecl_type::enum_); }
213 bool is_alias() const { return is_type(typedecl_type::alias); }
214 bool is_function_ptr() const { return is_type(typedecl_type::function_ptr); }
215
180 std::string base_type; 216 std::string base_type;
181 qualifier_def base_qualifier; 217 qualifier_def base_qualifier;
182 std::vector<std::string> namespaces; 218 std::vector<std::string> namespaces;
183 bool is_undefined, is_function_ptr; 219 typedecl_type type_type;
220 bool is_undefined;
184}; 221};
185 222
186inline bool operator==(regular_type_def const& rhs, regular_type_def const& lhs) 223inline bool operator==(regular_type_def const& rhs, regular_type_def const& lhs)
@@ -245,7 +282,7 @@ struct get_qualifier_visitor
245 return complex.outer.base_qualifier; 282 return complex.outer.base_qualifier;
246 } 283 }
247}; 284};
248 285
249inline bool operator==(type_def const& lhs, type_def const& rhs) 286inline bool operator==(type_def const& lhs, type_def const& rhs)
250{ 287{
251 return lhs.original_type == rhs.original_type && lhs.c_type == rhs.c_type; 288 return lhs.original_type == rhs.original_type && lhs.c_type == rhs.c_type;
@@ -254,9 +291,9 @@ inline bool operator!=(type_def const& lhs, type_def const& rhs)
254{ 291{
255 return !(lhs == rhs); 292 return !(lhs == rhs);
256} 293}
257 294
258type_def const void_ {attributes::regular_type_def{"void", {qualifier_info::is_none, {}}, {}, false}, "void", false}; 295type_def const void_ {attributes::regular_type_def{"void", {qualifier_info::is_none, {}}, {}}, "void", false};
259 296
260inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype) 297inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* unit, Eolian_C_Type_Type ctype)
261{ 298{
262 c_type = ::eolian_type_c_type_get(unit, eolian_type, ctype); 299 c_type = ::eolian_type_c_type_get(unit, eolian_type, ctype);
@@ -267,14 +304,14 @@ inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* uni
267 switch( ::eolian_type_type_get(eolian_type)) 304 switch( ::eolian_type_type_get(eolian_type))
268 { 305 {
269 case EOLIAN_TYPE_VOID: 306 case EOLIAN_TYPE_VOID:
270 original_type = attributes::regular_type_def{"void", {qualifiers(eolian_type), {}}, {}, false}; 307 original_type = attributes::regular_type_def{"void", {qualifiers(eolian_type), {}}, {}};
271 break; 308 break;
272 case EOLIAN_TYPE_REGULAR: 309 case EOLIAN_TYPE_REGULAR:
273 if (!stp) 310 if (!stp)
274 { 311 {
275 bool is_undefined = false; 312 bool is_undefined = false;
276 Eolian_Typedecl const* decl = eolian_type_typedecl_get(unit, eolian_type); 313 Eolian_Typedecl const* decl = eolian_type_typedecl_get(unit, eolian_type);
277 bool is_function_ptr = decl && eolian_typedecl_type_get(decl) == EOLIAN_TYPEDECL_FUNCTION_POINTER; 314 typedecl_type type_type = (decl ? typedecl_type_get(decl) : typedecl_type::unknown);
278 if(decl && eolian_typedecl_type_get(decl) == EOLIAN_TYPEDECL_ALIAS) 315 if(decl && eolian_typedecl_type_get(decl) == EOLIAN_TYPEDECL_ALIAS)
279 { 316 {
280 Eolian_Type const* aliased = eolian_typedecl_base_type_get(decl); 317 Eolian_Type const* aliased = eolian_typedecl_base_type_get(decl);
@@ -289,7 +326,7 @@ inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* uni
289 for(efl::eina::iterator<const char> namespace_iterator( ::eolian_type_namespaces_get(eolian_type)) 326 for(efl::eina::iterator<const char> namespace_iterator( ::eolian_type_namespaces_get(eolian_type))
290 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator) 327 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
291 namespaces.push_back(&*namespace_iterator); 328 namespaces.push_back(&*namespace_iterator);
292 original_type = {regular_type_def{ ::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, namespaces, is_undefined, is_function_ptr}}; 329 original_type = {regular_type_def{ ::eolian_type_name_get(eolian_type), {qualifiers(eolian_type), {}}, namespaces, type_type, is_undefined}};
293 } 330 }
294 else 331 else
295 { 332 {
@@ -320,7 +357,7 @@ inline void type_def::set(Eolian_Expression_Type eolian_exp_type)
320 switch(eolian_exp_type) 357 switch(eolian_exp_type)
321 { 358 {
322 case EOLIAN_EXPR_INT: 359 case EOLIAN_EXPR_INT:
323 original_type = attributes::regular_type_def{"int", {{}, {}}, {}, false}; 360 original_type = attributes::regular_type_def{"int", {{}, {}}, {}};
324 c_type = "int"; 361 c_type = "int";
325 break; 362 break;
326 default: 363 default:
@@ -351,7 +388,7 @@ struct add_optional_qualifier_visitor
351 } 388 }
352}; 389};
353} 390}
354 391
355struct parameter_def 392struct parameter_def
356{ 393{
357 parameter_direction direction; 394 parameter_direction direction;
@@ -369,7 +406,7 @@ struct parameter_def
369 { 406 {
370 return !(lhs == rhs); 407 return !(lhs == rhs);
371 } 408 }
372 409
373 parameter_def(parameter_direction direction, type_def type, std::string param_name, Eolian_Unit const* unit) 410 parameter_def(parameter_direction direction, type_def type, std::string param_name, Eolian_Unit const* unit)
374 : direction(std::move(direction)), type(std::move(type)), param_name(std::move(param_name)), unit(unit) {} 411 : direction(std::move(direction)), type(std::move(type)), param_name(std::move(param_name)), unit(unit) {}
375 parameter_def(Eolian_Function_Parameter const* param, Eolian_Unit const* unit) 412 parameter_def(Eolian_Function_Parameter const* param, Eolian_Unit const* unit)
@@ -545,7 +582,7 @@ struct function_def
545 { 582 {
546 attributes::regular_type_def const* typ = 583 attributes::regular_type_def const* typ =
547 efl::eina::get<attributes::regular_type_def>(&param.type.original_type); 584 efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
548 if (typ && typ->is_function_ptr) 585 if (typ && typ->is_function_ptr())
549 { 586 {
550 char typenam[2] = { 0, }; 587 char typenam[2] = { 0, };
551 typenam[0] = template_typename++; 588 typenam[0] = template_typename++;
@@ -568,7 +605,7 @@ struct function_def
568 { 605 {
569 attributes::regular_type_def const* typ = 606 attributes::regular_type_def const* typ =
570 efl::eina::get<attributes::regular_type_def>(&param.type.original_type); 607 efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
571 if (typ && typ->is_function_ptr) 608 if (typ && typ->is_function_ptr())
572 { 609 {
573 char typenam[2] = { 0, }; 610 char typenam[2] = { 0, };
574 typenam[0] = template_typename++; 611 typenam[0] = template_typename++;
@@ -652,8 +689,8 @@ struct event_def
652 friend inline bool operator!=(event_def const& lhs, event_def const& rhs) 689 friend inline bool operator!=(event_def const& lhs, event_def const& rhs)
653 { 690 {
654 return !(lhs == rhs); 691 return !(lhs == rhs);
655 } 692 }
656 693
657 event_def(type_def type, std::string name, std::string c_name, bool beta, bool protect) 694 event_def(type_def type, std::string name, std::string c_name, bool beta, bool protect)
658 : type(type), name(name), c_name(c_name), beta(beta), protect(protect) {} 695 : type(type), name(name), c_name(c_name), beta(beta), protect(protect) {}
659 event_def(Eolian_Event const* event, Eolian_Unit const* unit) 696 event_def(Eolian_Event const* event, Eolian_Unit const* unit)
@@ -835,7 +872,7 @@ struct klass_def
835 Eolian_Class const* inherit = &*inherit_iterator; 872 Eolian_Class const* inherit = &*inherit_iterator;
836 immediate_inherits.insert({inherit, {}}); 873 immediate_inherits.insert({inherit, {}});
837 } 874 }
838 std::function<void(Eolian_Class const*)> inherit_algo = 875 std::function<void(Eolian_Class const*)> inherit_algo =
839 [&] (Eolian_Class const* inherit_klass) 876 [&] (Eolian_Class const* inherit_klass)
840 { 877 {
841 for(efl::eina::iterator<Eolian_Class const> inherit_iterator ( ::eolian_class_inherits_get(inherit_klass)) 878 for(efl::eina::iterator<Eolian_Class const> inherit_iterator ( ::eolian_class_inherits_get(inherit_klass))
@@ -1100,7 +1137,7 @@ template <>
1100struct is_tuple<attributes::parameter_def> : std::true_type {}; 1137struct is_tuple<attributes::parameter_def> : std::true_type {};
1101template <> 1138template <>
1102struct is_tuple<attributes::event_def> : std::true_type {}; 1139struct is_tuple<attributes::event_def> : std::true_type {};
1103 1140
1104} 1141}
1105 1142
1106} } } 1143} } }
diff --git a/src/lib/eolian_cxx/grammar/parameter.hpp b/src/lib/eolian_cxx/grammar/parameter.hpp
index 68f5450dd1..e06cfeaaf0 100644
--- a/src/lib/eolian_cxx/grammar/parameter.hpp
+++ b/src/lib/eolian_cxx/grammar/parameter.hpp
@@ -28,7 +28,7 @@ struct parameter_type_generator
28 28
29 attributes::regular_type_def const* typ = 29 attributes::regular_type_def const* typ =
30 efl::eina::get<attributes::regular_type_def>(&param.type.original_type); 30 efl::eina::get<attributes::regular_type_def>(&param.type.original_type);
31 if (typ && typ->is_function_ptr) 31 if (typ && typ->is_function_ptr())
32 return as_generator("F").generate(sink, attributes::unused, context); 32 return as_generator("F").generate(sink, attributes::unused, context);
33 33
34 return as_generator 34 return as_generator
diff --git a/src/tests/efl_mono/Structs.cs b/src/tests/efl_mono/Structs.cs
new file mode 100644
index 0000000000..dcdea0d757
--- /dev/null
+++ b/src/tests/efl_mono/Structs.cs
@@ -0,0 +1,355 @@
1using System;
2using System.Runtime.InteropServices;
3using System.Linq;
4
5using static EinaTestData.BaseData;
6
7namespace TestSuite
8{
9
10class TestStructs
11{
12 // Auxiliary function //
13
14 private static test.StructSimple structSimpleWithValues()
15 {
16 var simple = new test.StructSimple();
17
18 simple.Fbyte = (sbyte)-126;
19 simple.Fubyte = (byte) 254u;
20 simple.Fchar = '~';
21 simple.Fshort = (short) -32766;
22 simple.Fushort = (ushort) 65534u;
23 simple.Fint = -32766;
24 simple.Fuint = 65534u;
25 simple.Flong = -2147483646;
26 simple.Fulong = 4294967294u;
27 simple.Fllong = -9223372036854775806;
28 simple.Fullong = 18446744073709551614u;
29 simple.Fint8 = (sbyte) -126;
30 simple.Fuint8 = (byte) 254u;
31 simple.Fint16 = (short) -32766;
32 simple.Fuint16 = (ushort) 65534u;
33 simple.Fint32 = -2147483646;
34 simple.Fuint32 = 4294967294u;
35 simple.Fint64 = -9223372036854775806;
36 simple.Fuint64 = 18446744073709551614u;
37 simple.Fssize = -2147483646;
38 simple.Fsize = 4294967294u;
39 simple.Fintptr = (IntPtr) 0xFE;
40 simple.Fptrdiff = -2147483646;
41 simple.Ffloat = -16777216.0f;
42 simple.Fdouble = -9007199254740992.0;
43 simple.Fbool = true;
44 simple.Fvoid_ptr = (IntPtr) 0xFE;
45 simple.Fenum = test.SampleEnum.V2;
46 simple.Fstring = "test/string";
47 simple.Fmstring = "test/mstring";
48 simple.Fstringshare = "test/stringshare";
49
50 return simple;
51 }
52
53 private static void checkStructSimple(test.StructSimple simple)
54 {
55 Test.Assert(simple.Fbyte == (sbyte) -126);
56 Test.Assert(simple.Fubyte == (byte) 254u);
57 Test.Assert(simple.Fchar == '~');
58 Test.Assert(simple.Fshort == (short) -32766);
59 Test.Assert(simple.Fushort == (ushort) 65534u);
60 Test.Assert(simple.Fint == -32766);
61 Test.Assert(simple.Fuint == 65534u);
62 Test.Assert(simple.Flong == -2147483646);
63 Test.Assert(simple.Fulong == 4294967294u);
64 Test.Assert(simple.Fllong == -9223372036854775806);
65 Test.Assert(simple.Fullong == 18446744073709551614u);
66 Test.Assert(simple.Fint8 == (sbyte) -126);
67 Test.Assert(simple.Fuint8 == (byte) 254u);
68 Test.Assert(simple.Fint16 == (short) -32766);
69 Test.Assert(simple.Fuint16 == (ushort) 65534u);
70 Test.Assert(simple.Fint32 == -2147483646);
71 Test.Assert(simple.Fuint32 == 4294967294u);
72 Test.Assert(simple.Fint64 == -9223372036854775806);
73 Test.Assert(simple.Fuint64 == 18446744073709551614u);
74 Test.Assert(simple.Fssize == -2147483646);
75 Test.Assert(simple.Fsize == 4294967294u);
76 Test.Assert(simple.Fintptr == (IntPtr) 0xFE);
77 Test.Assert(simple.Fptrdiff == -2147483646);
78 Test.Assert(simple.Ffloat == -16777216.0f);
79 Test.Assert(simple.Fdouble == -9007199254740992.0);
80 Test.Assert(simple.Fbool == true);
81 Test.Assert(simple.Fvoid_ptr == (IntPtr) 0xFE);
82 Test.Assert(simple.Fenum == test.SampleEnum.V2);
83 Test.Assert(simple.Fstring == "test/string");
84 Test.Assert(simple.Fmstring == "test/mstring");
85 Test.Assert(simple.Fstringshare == "test/stringshare");
86 }
87
88 private static void checkZeroedStructSimple(test.StructSimple simple)
89 {
90 Test.Assert(simple.Fbyte == 0);
91 Test.Assert(simple.Fubyte == 0);
92 Test.Assert(simple.Fchar == '\0');
93 Test.Assert(simple.Fshort == 0);
94 Test.Assert(simple.Fushort == 0);
95 Test.Assert(simple.Fint == 0);
96 Test.Assert(simple.Fuint == 0);
97 Test.Assert(simple.Flong == 0);
98 Test.Assert(simple.Fulong == 0);
99 Test.Assert(simple.Fllong == 0);
100 Test.Assert(simple.Fullong == 0);
101 Test.Assert(simple.Fint8 == 0);
102 Test.Assert(simple.Fuint8 == 0);
103 Test.Assert(simple.Fint16 == 0);
104 Test.Assert(simple.Fuint16 == 0);
105 Test.Assert(simple.Fint32 == 0);
106 Test.Assert(simple.Fuint32 == 0);
107 Test.Assert(simple.Fint64 == 0);
108 Test.Assert(simple.Fuint64 == 0);
109 Test.Assert(simple.Fssize == 0);
110 Test.Assert(simple.Fsize == 0);
111 Test.Assert(simple.Fintptr == IntPtr.Zero);
112 Test.Assert(simple.Fptrdiff == 0);
113 Test.Assert(simple.Ffloat == 0);
114 Test.Assert(simple.Fdouble == 0);
115 Test.Assert(simple.Fbool == false);
116 Test.Assert(simple.Fvoid_ptr == IntPtr.Zero);
117 Test.Assert(simple.Fenum == test.SampleEnum.V0);
118 Test.Assert(simple.Fstring == null);
119 Test.Assert(simple.Fmstring == null);
120 Test.Assert(simple.Fstringshare == null);
121 }
122
123 private static test.StructComplex structComplexWithValues()
124 {
125 var complex = new test.StructComplex();
126
127 complex.Farray = new eina.Array<int>();
128 complex.Farray.Push(0x0);
129 complex.Farray.Push(0x2A);
130 complex.Farray.Push(0x42);
131
132 complex.Finarray = new eina.Inarray<int>();
133 complex.Finarray.Push(0x0);
134 complex.Finarray.Push(0x2A);
135 complex.Finarray.Push(0x42);
136
137
138 complex.Flist = new eina.List<string>();
139 complex.Flist.Append("0x0");
140 complex.Flist.Append("0x2A");
141 complex.Flist.Append("0x42");
142
143 complex.Finlist = new eina.Inlist<int>();
144 complex.Finlist.Append(0x0);
145 complex.Finlist.Append(0x2A);
146 complex.Finlist.Append(0x42);
147
148 complex.Fhash = new eina.Hash<string, string>();
149 complex.Fhash["aa"] = "aaa";
150 complex.Fhash["bb"] = "bbb";
151 complex.Fhash["cc"] = "ccc";
152
153 complex.Fiterator = complex.Farray.GetIterator();
154
155 complex.Fany_value = new eina.Value(eina.ValueType.Double);
156 complex.Fany_value.Set(-9007199254740992.0);
157
158 complex.Fany_value_ptr = new eina.Value(eina.ValueType.String);
159 complex.Fany_value_ptr.Set("abc");
160
161 complex.Fbinbuf = new eina.Binbuf();
162 complex.Fbinbuf.Append(126);
163
164 complex.Fslice.Length = 1;
165 complex.Fslice.Mem = eina.MemoryNative.Alloc(1);
166 Marshal.WriteByte(complex.Fslice.Mem, 125);
167
168 complex.Fobj = new test.NumberwrapperConcrete();
169 complex.Fobj.SetNumber(42);
170
171 return complex;
172 }
173
174 private static void checkStructComplex(test.StructComplex complex)
175 {
176 Test.Assert(complex.Farray.ToArray().SequenceEqual(base_seq_int));
177
178 Test.Assert(complex.Finarray.ToArray().SequenceEqual(base_seq_int));
179
180 Test.Assert(complex.Flist.ToArray().SequenceEqual(base_seq_str));
181
182 Test.Assert(complex.Finlist.ToArray().SequenceEqual(base_seq_int));
183
184 Test.Assert(complex.Fhash["aa"] == "aaa");
185 Test.Assert(complex.Fhash["bb"] == "bbb");
186 Test.Assert(complex.Fhash["cc"] == "ccc");
187
188 int idx = 0;
189 foreach (int e in complex.Fiterator)
190 {
191 Test.Assert(e == base_seq_int[idx]);
192 ++idx;
193 }
194
195 double double_val = 0;
196 Test.Assert(complex.Fany_value.Get(out double_val));
197 Test.Assert(double_val == -9007199254740992.0);
198
199 string str_val = null;
200 Test.Assert(complex.Fany_value_ptr.Get(out str_val));
201 Test.Assert(str_val == "abc");
202
203 Test.Assert(complex.Fbinbuf.Length == 1);
204 Test.Assert(complex.Fbinbuf.GetBytes()[0] == 126);
205
206 Test.Assert(complex.Fslice.Length == 1);
207 Test.Assert(complex.Fslice.GetBytes()[0] == 125);
208
209 Test.Assert(complex.Fobj != null);
210 Test.Assert(complex.Fobj.GetNumber() == 42);
211 }
212
213
214 private static void checkZeroedStructComplex(test.StructComplex complex)
215 {
216 Test.Assert(complex.Farray == null);
217 Test.Assert(complex.Finarray == null);
218 Test.Assert(complex.Flist == null);
219 Test.Assert(complex.Finlist == null);
220 Test.Assert(complex.Fhash == null);
221 Test.Assert(complex.Fiterator == null);
222 Test.Assert(complex.Fany_value == null);
223 Test.Assert(complex.Fany_value_ptr == null);
224 Test.Assert(complex.Fbinbuf == null);
225
226 Test.Assert(complex.Fslice.Length == 0);
227 Test.Assert(complex.Fslice.Mem == IntPtr.Zero);
228
229 Test.Assert(complex.Fobj == null);
230 }
231
232 // Test cases //
233
234 // Default initialization (C# side)
235
236 private static void simple_default_instantiation()
237 {
238 var simple = new test.StructSimple();
239 checkZeroedStructSimple(simple);
240 }
241
242 private static void complex_default_instantiation()
243 {
244 var complex = new test.StructComplex();
245 checkZeroedStructComplex(complex);
246 }
247
248 // As parameters
249
250 public static void simple_in()
251 {
252 var simple = structSimpleWithValues();
253 test.Testing t = new test.TestingConcrete();
254 bool r = t.StructSimpleIn(simple);
255 Test.Assert(r, "Function returned false");
256 }
257
258 // public static void simple_ptr_in()
259 // {
260 // var simple = structSimpleWithValues();
261 // test.Testing t = new test.TestingConcrete();
262 // bool r = t.struct_simple_ptr_in(simple);
263 // Test.Assert(r, "Function returned false");
264 // }
265
266 // public static void simple_ptr_in_own()
267 // {
268 // var simple = structSimpleWithValues();
269 // test.Testing t = new test.TestingConcrete();
270 // bool r = t.struct_simple_ptr_in_own(simple);
271 // Test.Assert(r, "Function returned false");
272 // }
273
274 public static void simple_out()
275 {
276 var simple = new test.StructSimple();
277 test.Testing t = new test.TestingConcrete();
278 bool r = t.StructSimpleOut(ref simple);
279 Test.Assert(r, "Function returned false");
280 checkStructSimple(simple);
281 }
282
283 // public static void simple_ptr_out()
284 // {
285 // }
286
287 // public static void simple_ptr_out_own()
288 // {
289 // }
290
291 public static void simple_return()
292 {
293 test.Testing t = new test.TestingConcrete();
294 var simple = t.StructSimpleReturn();
295 checkStructSimple(simple);
296 }
297
298 // public static void simple_ptr_return()
299 // {
300 // }
301
302 // public static void simple_ptr_return_own()
303 // {
304 // }
305
306 public static void complex_in()
307 {
308 var complex = structComplexWithValues();
309 test.Testing t = new test.TestingConcrete();
310 bool r = t.StructComplexIn(complex);
311 Test.Assert(r, "Function returned false");
312 }
313
314 // public static void complex_ptr_in()
315 // {
316 // }
317
318 // public static void complex_ptr_in_own()
319 // {
320 // }
321
322 public static void complex_out()
323 {
324 var complex = new test.StructComplex();
325 test.Testing t = new test.TestingConcrete();
326 bool r = t.StructComplexOut(ref complex);
327 Test.Assert(r, "Function returned false");
328 checkStructComplex(complex);
329 }
330
331 // public static void complex_ptr_out()
332 // {
333 // }
334
335 // public static void complex_ptr_out_own()
336 // {
337 // }
338
339 public static void complex_return()
340 {
341 test.Testing t = new test.TestingConcrete();
342 var complex = t.StructComplexReturn();
343 checkStructComplex(complex);
344 }
345
346 // public static void complex_ptr_return()
347 // {
348 // }
349
350 // public static void complex_ptr_return_own()
351 // {
352 // }
353}
354
355}
diff --git a/src/tests/efl_mono/libefl_mono_native_test.c b/src/tests/efl_mono/libefl_mono_native_test.c
index 0b73d7e76b..b8cc8d58e4 100644
--- a/src/tests/efl_mono/libefl_mono_native_test.c
+++ b/src/tests/efl_mono/libefl_mono_native_test.c
@@ -34,6 +34,9 @@
34#include "test_numberwrapper.eo.h" 34#include "test_numberwrapper.eo.h"
35#include "test_testing.eo.h" 35#include "test_testing.eo.h"
36 36
37#define EQUAL(a, b) ((a) == (b) ? 1 : (fprintf(stderr, "NOT EQUAL! %s:%i (%s)", __FILE__, __LINE__, __FUNCTION__), fflush(stderr), 0))
38#define STR_EQUAL(a, b) (strcmp((a), (b)) == 0 ? 1 : (fprintf(stderr, "NOT EQUAL! %s:%i (%s) '%s' != '%s'", __FILE__, __LINE__, __FUNCTION__, (a), (b)), fflush(stderr), 0))
39
37typedef struct Test_Testing_Data 40typedef struct Test_Testing_Data
38{ 41{
39 Test_SimpleCb cb; 42 Test_SimpleCb cb;
@@ -3123,6 +3126,397 @@ Eina_Error _test_testing_returns_error(EINA_UNUSED Eo *obj, Test_Testing_Data *p
3123 return pd->error_code; 3126 return pd->error_code;
3124} 3127}
3125 3128
3129// //
3130// Structs //
3131// //
3132
3133// auxiliary functions
3134
3135static
3136void struct_simple_with_values(Test_StructSimple *simple)
3137{
3138 simple->fbyte = -126;
3139 simple->fubyte = 254u;
3140 simple->fchar = '~';
3141 simple->fshort = -32766;
3142 simple->fushort = 65534u;
3143 simple->fint = -32766;
3144 simple->fuint = 65534u;
3145 simple->flong = -2147483646;
3146 simple->fulong = 4294967294u;
3147 simple->fllong = -9223372036854775806;
3148 simple->fullong = 18446744073709551614u;
3149 simple->fint8 = -126;
3150 simple->fuint8 = 254u;
3151 simple->fint16 = -32766;
3152 simple->fuint16 = 65534u;
3153 simple->fint32 = -2147483646;
3154 simple->fuint32 = 4294967294u;
3155 simple->fint64 = -9223372036854775806;
3156 simple->fuint64 = 18446744073709551614u;
3157 simple->fssize = -2147483646;
3158 simple->fsize = 4294967294u;
3159 simple->fintptr = 0xFE;
3160 simple->fptrdiff = -2147483646;
3161 simple->ffloat = -16777216.0;
3162 simple->fdouble = -9007199254740992.0;
3163 simple->fbool = EINA_TRUE;
3164 simple->fvoid_ptr = (void*) 0xFE;
3165 simple->fenum = TEST_SAMPLEENUM_V2;
3166 simple->fstring = "test/string";
3167 simple->fmstring = strdup("test/mstring");
3168 simple->fstringshare = eina_stringshare_add("test/stringshare");
3169}
3170
3171static
3172Eina_Bool check_and_modify_struct_simple(Test_StructSimple *simple)
3173{
3174 Eina_Bool ret =
3175 EQUAL(simple->fbyte, -126)
3176 && EQUAL(simple->fubyte, 254u)
3177 && EQUAL(simple->fchar, '~')
3178 && EQUAL(simple->fshort, -32766)
3179 && EQUAL(simple->fushort, 65534u)
3180 && EQUAL(simple->fint, -32766)
3181 && EQUAL(simple->fuint, 65534u)
3182 && EQUAL(simple->flong, -2147483646)
3183 && EQUAL(simple->fulong, 4294967294u)
3184 && EQUAL(simple->fllong, -9223372036854775806)
3185 && EQUAL(simple->fullong, 18446744073709551614u)
3186 && EQUAL(simple->fint8, -126)
3187 && EQUAL(simple->fuint8, 254u)
3188 && EQUAL(simple->fint16, -32766)
3189 && EQUAL(simple->fuint16, 65534u)
3190 && EQUAL(simple->fint32, -2147483646)
3191 && EQUAL(simple->fuint32, 4294967294u)
3192 && EQUAL(simple->fint64, -9223372036854775806)
3193 && EQUAL(simple->fuint64, 18446744073709551614u)
3194 && EQUAL(simple->fssize, -2147483646)
3195 && EQUAL(simple->fsize, 4294967294u)
3196 && EQUAL(simple->fintptr, 0xFE)
3197 && EQUAL(simple->fptrdiff, -2147483646)
3198 && EQUAL(simple->ffloat, -16777216.0)
3199 && EQUAL(simple->fdouble, -9007199254740992.0)
3200 && EQUAL(simple->fbool, EINA_TRUE)
3201 && EQUAL(simple->fvoid_ptr, (void*) 0xFE)
3202 && EQUAL(simple->fenum, TEST_SAMPLEENUM_V2)
3203 && STR_EQUAL(simple->fstring, "test/string")
3204 && STR_EQUAL(simple->fmstring, "test/mstring")
3205 && STR_EQUAL(simple->fstringshare, "test/stringshare")
3206 ;
3207
3208 if (!ret)
3209 return ret;
3210
3211 simple->fmstring[4] = '-';
3212 return strcmp(simple->fmstring, "test-mstring") == 0;
3213}
3214
3215static
3216Eina_Bool check_zeroed_struct_simple(Test_StructSimple *simple)
3217{
3218 Eina_Bool ret =
3219 simple->fbyte == 0
3220 && simple->fubyte == 0
3221 && simple->fchar == '\0'
3222 && simple->fshort == 0
3223 && simple->fushort == 0
3224 && simple->fint == 0
3225 && simple->fuint == 0
3226 && simple->flong == 0
3227 && simple->fulong == 0
3228 && simple->fllong == 0
3229 && simple->fullong == 0
3230 && simple->fint8 == 0
3231 && simple->fuint8 == 0
3232 && simple->fint16 == 0
3233 && simple->fuint16 == 0
3234 && simple->fint32 == 0
3235 && simple->fuint32 == 0
3236 && simple->fint64 == 0
3237 && simple->fuint64 == 0
3238 && simple->fssize == 0
3239 && simple->fsize == 0
3240 && simple->fintptr == 0x00
3241 && simple->fptrdiff == 0
3242 && simple->ffloat == 0
3243 && simple->fdouble == 0
3244 && simple->fbool == EINA_FALSE
3245 && simple->fvoid_ptr == NULL
3246 && simple->fenum == TEST_SAMPLEENUM_V0
3247 && simple->fstring == NULL
3248 && simple->fmstring == NULL
3249 && simple->fstringshare == NULL
3250 ;
3251
3252 return ret;
3253}
3254
3255static
3256void struct_complex_with_values(Test_StructComplex *complex)
3257{
3258 complex->farray = eina_array_new(4);
3259 eina_array_push(complex->farray, _new_int(0x0));
3260 eina_array_push(complex->farray, _new_int(0x2A));
3261 eina_array_push(complex->farray, _new_int(0x42));
3262
3263 complex->finarray = eina_inarray_new(sizeof(int), 0);
3264 eina_inarray_push(complex->finarray, _int_ref(0x0));
3265 eina_inarray_push(complex->finarray, _int_ref(0x2A));
3266 eina_inarray_push(complex->finarray, _int_ref(0x42));
3267
3268 complex->flist = eina_list_append(complex->flist, strdup("0x0"));
3269 complex->flist = eina_list_append(complex->flist, strdup("0x2A"));
3270 complex->flist = eina_list_append(complex->flist, strdup("0x42"));
3271
3272 complex->finlist = eina_inlist_append(complex->finlist, _new_inlist_int(0x0));
3273 complex->finlist = eina_inlist_append(complex->finlist, _new_inlist_int(0x2A));
3274 complex->finlist = eina_inlist_append(complex->finlist, _new_inlist_int(0x42));
3275
3276 complex->fhash = eina_hash_string_superfast_new(NULL);
3277 eina_hash_add(complex->fhash, "aa", strdup("aaa"));
3278 eina_hash_add(complex->fhash, "bb", strdup("bbb"));
3279 eina_hash_add(complex->fhash, "cc", strdup("ccc"));
3280
3281 complex->fiterator = eina_array_iterator_new(complex->farray);
3282
3283 eina_value_setup(&complex->fany_value, EINA_VALUE_TYPE_DOUBLE);
3284 eina_value_set(&complex->fany_value, -9007199254740992.0);
3285
3286 complex->fany_value_ptr = eina_value_new(EINA_VALUE_TYPE_STRING);
3287 eina_value_set(complex->fany_value_ptr, "abc");
3288
3289 complex->fbinbuf = eina_binbuf_new();
3290 eina_binbuf_append_char(complex->fbinbuf, 126);
3291
3292 complex->fslice.len = 1;
3293 complex->fslice.mem = malloc(1);
3294 memset((void*)complex->fslice.mem, 125, 1);
3295
3296 complex->fobj = _new_obj(42);
3297}
3298
3299static
3300Eina_Bool check_and_modify_struct_complex(Test_StructComplex *complex)
3301{
3302 if (!_array_int_equal(complex->farray, base_seq_int, base_seq_int_size))
3303 return EINA_FALSE;
3304
3305 if (!_inarray_int_equal(complex->finarray, base_seq_int, base_seq_int_size))
3306 return EINA_FALSE;
3307
3308 if (!_list_str_equal(complex->flist, base_seq_str, base_seq_str_size))
3309 return EINA_FALSE;
3310
3311 if (!_inlist_int_equal(complex->finlist, base_seq_int, base_seq_int_size))
3312 return EINA_FALSE;
3313
3314 if (!_hash_str_check(complex->fhash, "aa", "aaa")
3315 || !_hash_str_check(complex->fhash, "bb", "bbb")
3316 || !_hash_str_check(complex->fhash, "cc", "ccc"))
3317 return EINA_FALSE;
3318
3319 if (!_iterator_int_equal(complex->fiterator, base_seq_int, base_seq_int_size, EINA_FALSE))
3320 return EINA_FALSE;
3321
3322 double double_val = 0;
3323 if (!eina_value_get(&complex->fany_value, &double_val) || double_val != -9007199254740992.0)
3324 return EINA_FALSE;
3325
3326 const char *str_val = NULL;
3327 if (!eina_value_get(complex->fany_value_ptr, &str_val) || strcmp(str_val, "abc") != 0)
3328 return EINA_FALSE;
3329
3330 if (eina_binbuf_length_get(complex->fbinbuf) != 1 || eina_binbuf_string_get(complex->fbinbuf)[0] != 126)
3331 return EINA_FALSE;
3332
3333 if (complex->fslice.len != 1 || *(char*)complex->fslice.mem != 125)
3334 return EINA_FALSE;
3335
3336 if (complex->fobj == NULL || test_numberwrapper_number_get(complex->fobj) != 42)
3337 return EINA_FALSE;
3338
3339 return EINA_TRUE;
3340}
3341
3342static
3343Eina_Bool check_zeroed_struct_complex(Test_StructComplex *complex)
3344{
3345 Eina_Bool ret =
3346 complex->farray == NULL
3347 && complex->finarray == NULL
3348 && complex->flist == NULL
3349 && complex->finlist == NULL
3350 && complex->fhash == NULL
3351 && complex->fiterator == NULL
3352
3353 && complex->fany_value.type == NULL
3354 && complex->fany_value.value._guarantee == 0
3355
3356 && complex->fany_value_ptr == NULL
3357 && complex->fbinbuf == NULL
3358
3359 && complex->fslice.len == 0
3360 && complex->fslice.mem == NULL
3361
3362 && complex->fobj == NULL
3363 ;
3364
3365 return ret;
3366}
3367
3368// with simple types
3369
3370EOLIAN
3371Eina_Bool _test_testing_struct_simple_in(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple simple)
3372{
3373 return check_and_modify_struct_simple(&simple);
3374}
3375
3376EOLIAN
3377Eina_Bool _test_testing_struct_simple_ptr_in(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple *simple)
3378{
3379 (void) simple;
3380 EINA_LOG_ERR("Not implemented!");
3381 return EINA_FALSE;
3382}
3383
3384EOLIAN
3385Eina_Bool _test_testing_struct_simple_ptr_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple *simple)
3386{
3387 (void) simple;
3388 EINA_LOG_ERR("Not implemented!");
3389 return EINA_FALSE;
3390}
3391
3392EOLIAN
3393Eina_Bool _test_testing_struct_simple_out(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple *simple)
3394{
3395 if (!simple)
3396 {
3397 EINA_LOG_ERR("Null struct pointer");
3398 return EINA_FALSE;
3399 }
3400
3401 struct_simple_with_values(simple);
3402
3403 return EINA_TRUE;
3404}
3405
3406EOLIAN
3407Eina_Bool _test_testing_struct_simple_ptr_out(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple **simple)
3408{
3409 (void) simple;
3410 EINA_LOG_ERR("Not implemented!");
3411 return EINA_FALSE;
3412}
3413
3414EOLIAN
3415Eina_Bool _test_testing_struct_simple_ptr_out_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructSimple **simple)
3416{
3417 (void) simple;
3418 EINA_LOG_ERR("Not implemented!");
3419 return EINA_FALSE;
3420}
3421
3422EOLIAN
3423Test_StructSimple _test_testing_struct_simple_return(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
3424{
3425 Test_StructSimple simple = {0,};
3426 struct_simple_with_values(&simple);
3427 return simple;
3428}
3429
3430EOLIAN
3431Test_StructSimple *_test_testing_struct_simple_ptr_return(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
3432{
3433 EINA_LOG_ERR("Not implemented!");
3434 return NULL;
3435}
3436
3437EOLIAN
3438Test_StructSimple *_test_testing_struct_simple_ptr_return_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
3439{
3440 EINA_LOG_ERR("Not implemented!");
3441 return NULL;
3442}
3443
3444// with complex types
3445
3446EOLIAN
3447Eina_Bool _test_testing_struct_complex_in(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructComplex complex)
3448{
3449 return check_and_modify_struct_complex(&complex);
3450}
3451
3452EOLIAN
3453Eina_Bool _test_testing_struct_complex_ptr_in(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructComplex *complex)
3454{
3455 (void) complex;
3456 EINA_LOG_ERR("Not implemented!");
3457 return EINA_FALSE;
3458}
3459
3460EOLIAN
3461Eina_Bool _test_testing_struct_complex_ptr_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructComplex *complex)
3462{
3463 (void) complex;
3464 EINA_LOG_ERR("Not implemented!");
3465 return EINA_FALSE;
3466}
3467
3468EOLIAN
3469Eina_Bool _test_testing_struct_complex_out(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructComplex *complex)
3470{
3471 if (!complex)
3472 {
3473 EINA_LOG_ERR("Null struct pointer");
3474 return EINA_FALSE;
3475 }
3476
3477 struct_complex_with_values(complex);
3478
3479 return EINA_TRUE;
3480}
3481
3482EOLIAN
3483Eina_Bool _test_testing_struct_complex_ptr_out(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructComplex **complex)
3484{
3485 (void) complex;
3486 EINA_LOG_ERR("Not implemented!");
3487 return EINA_FALSE;
3488}
3489
3490EOLIAN
3491Eina_Bool _test_testing_struct_complex_ptr_out_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd, Test_StructComplex **complex)
3492{
3493 (void) complex;
3494 EINA_LOG_ERR("Not implemented!");
3495 return EINA_FALSE;
3496}
3497
3498EOLIAN
3499Test_StructComplex _test_testing_struct_complex_return(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
3500{
3501 Test_StructComplex complex = {0,};
3502 struct_complex_with_values(&complex);
3503 return complex;
3504}
3505
3506EOLIAN
3507Test_StructComplex* _test_testing_struct_complex_ptr_return(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
3508{
3509 EINA_LOG_ERR("Not implemented!");
3510 return NULL;
3511}
3512
3513EOLIAN
3514Test_StructComplex* _test_testing_struct_complex_ptr_return_own(EINA_UNUSED Eo *obj, EINA_UNUSED Test_Testing_Data *pd)
3515{
3516 EINA_LOG_ERR("Not implemented!");
3517 return NULL;
3518}
3519
3126// // 3520// //
3127// Class constructor 3521// Class constructor
3128// // 3522// //
diff --git a/src/tests/efl_mono/test_testing.eo b/src/tests/efl_mono/test_testing.eo
index bf13a57283..7d7ab51275 100644
--- a/src/tests/efl_mono/test_testing.eo
+++ b/src/tests/efl_mono/test_testing.eo
@@ -1,5 +1,79 @@
1import eina_types; 1import eina_types;
2 2
3enum Test.SampleEnum {
4 v0,
5 v1,
6 v2,
7 v3,
8 v4,
9}
10
11struct Test.StructSimple
12{
13 fbyte: byte;
14 fubyte: ubyte;
15 fchar: char;
16 fshort: short;
17 fushort: ushort;
18 fint: int;
19 fuint: uint;
20 flong: long;
21 fulong: ulong;
22 fllong: llong;
23 fullong: ullong;
24 fint8: int8;
25 fuint8: uint8;
26 fint16: int16;
27 fuint16: uint16;
28 fint32: int32;
29 fuint32: uint32;
30 fint64: int64;
31 fuint64: uint64;
32 fssize: ssize;
33 fsize: size;
34 fintptr: intptr;
35 // fuintptr: uintptr; // TODO
36 fptrdiff: ptrdiff;
37 ffloat: float;
38 fdouble: double;
39 fbool: bool;
40 fvoid_ptr: void_ptr;
41 fenum: Test.SampleEnum;
42 // fboolptr: ptr(bool); // TODO
43 // fbyteptr: ptr(byte);
44 // fubyteptr: ptr(ubyte);
45 // fcharptr: ptr(char);
46 // fuint8ptr: ptr(uint8);
47 // fint16ptr: ptr(int16);
48 // fuint64ptr: ptr(uint64);
49 // fssizeptr: ptr(ssize);
50 // fsizeptr: ptr(size);
51 // fintptrptr: ptr(intptr);
52 // fptrdiffptr: ptr(ptrdiff);
53 // ffloatptr: ptr(float);
54 // fdoubleptr: ptr(double);
55 // fvoid_ptrptr: ptr(void_ptr);
56 // fenumptr: ptr(Test.SampleEnum);
57 fstring: string;
58 fmstring: mstring;
59 fstringshare: stringshare;
60}
61
62struct Test.StructComplex {
63 farray: array<ptr(int)>;
64 finarray: inarray<int>;
65 flist: list<string>;
66 finlist: inlist<ptr(int)>;
67 fhash: hash<string, string>;
68 fiterator: iterator<ptr(int)>;
69 fany_value: any_value;
70 fany_value_ptr: any_value_ptr;
71 fbinbuf: ptr(Eina.Binbuf);
72 fslice: Eina.Slice;
73 // fslice: ptr(Eina.Slice); // TODO
74 fobj: Test.Numberwrapper;
75}
76
3function Test.SimpleCb { 77function Test.SimpleCb {
4 params { 78 params {
5 a: int; 79 a: int;
@@ -1238,6 +1312,116 @@ class Test.Testing (Efl.Object) {
1238 @out value: any_value; 1312 @out value: any_value;
1239 } 1313 }
1240 } 1314 }
1315
1316 /* Structs */
1317
1318 struct_simple_in {
1319 params {
1320 @in simple: Test.StructSimple;
1321 }
1322 return: bool;
1323 }
1324
1325 // struct_simple_ptr_in {
1326 // params {
1327 // @in simple: ptr(Test.StructSimple);
1328 // }
1329 // return: bool;
1330 // }
1331 //
1332 // struct_simple_ptr_in_own {
1333 // params {
1334 // @in simple: ptr(Test.StructSimple) @owned;
1335 // }
1336 // return: bool;
1337 // }
1338
1339 struct_simple_out {
1340 params {
1341 @out simple: Test.StructSimple;
1342 }
1343 return: bool;
1344 }
1345
1346 // struct_simple_ptr_out {
1347 // params {
1348 // @out simple: ptr(Test.StructSimple);
1349 // }
1350 // return: bool;
1351 // }
1352 //
1353 // struct_simple_ptr_out_own {
1354 // params {
1355 // @out simple: ptr(Test.StructSimple) @owned;
1356 // }
1357 // return: bool;
1358 // }
1359
1360 struct_simple_return {
1361 return: Test.StructSimple;
1362 }
1363
1364 // struct_simple_ptr_return {
1365 // return: ptr(Test.StructSimple);
1366 // }
1367 //
1368 // struct_simple_ptr_return_own {
1369 // return: ptr(Test.StructSimple) @owned;
1370 // }
1371
1372 struct_complex_in {
1373 params {
1374 @in complex: Test.StructComplex;
1375 }
1376 return: bool;
1377 }
1378
1379 // struct_complex_ptr_in {
1380 // params {
1381 // @in complex: ptr(Test.StructComplex);
1382 // }
1383 // return: bool;
1384 // }
1385 //
1386 // struct_complex_ptr_in_own {
1387 // params {
1388 // @in complex: ptr(Test.StructComplex) @owned;
1389 // }
1390 // return: bool;
1391 // }
1392
1393 struct_complex_out {
1394 params {
1395 @out complex: Test.StructComplex;
1396 }
1397 return: bool;
1398 }
1399
1400 // struct_complex_ptr_out {
1401 // params {
1402 // @out complex: ptr(Test.StructComplex);
1403 // }
1404 // return: bool;
1405 // }
1406 //
1407 // struct_complex_ptr_out_own {
1408 // params {
1409 // @out complex: ptr(Test.StructComplex) @owned;
1410 // }
1411 // return: bool;
1412 // }
1413
1414 struct_complex_return {
1415 return: Test.StructComplex;
1416 }
1417
1418 // struct_complex_ptr_return {
1419 // return: ptr(Test.StructComplex);
1420 // }
1421 //
1422 // struct_complex_ptr_return_own {
1423 // return: ptr(Test.StructComplex) @owned;
1424 // }
1241 } 1425 }
1242 implements { 1426 implements {
1243 class.constructor; 1427 class.constructor;