diff --git a/.gitignore b/.gitignore index 47b965b2..38795343 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ build docs/html + +thirdparty/cpp-peglib diff --git a/CMakeLists.txt b/CMakeLists.txt index b5b9bbea..c4f18ff7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,9 +135,14 @@ if(XTYPES_BUILD_EXAMPLES) compile_example(${PROJECT_NAME}_example_module SOURCE examples/module.cpp) compile_example(${PROJECT_NAME}_example_iterators SOURCE examples/iterators.cpp) compile_example(${PROJECT_NAME}_example_exceptions_asserts SOURCE examples/exceptions_asserts.cpp) + compile_example(${PROJECT_NAME}_example_load_idl SOURCE examples/load_idl.cpp) # ... + + # Export resources for examples + file(COPY examples/resources DESTINATION ${PROJECT_BINARY_DIR}) endif() + ##################################################################################### # Tests ##################################################################################### diff --git a/examples/load_idl.cpp b/examples/load_idl.cpp new file mode 100644 index 00000000..bfc0b39b --- /dev/null +++ b/examples/load_idl.cpp @@ -0,0 +1,126 @@ +#include +#include + +#include + +using namespace eprosima::xtypes; + +int main() +{ + + // Loading idl + try + { + std::cout << "LOADING" << std::endl; + std::cout << "-------" << std::endl; + + idl::Context context = idl::parse_file("resources/example.idl"); + + if (context.success) + { + std::cout << "Context loaded correctly" << std::endl; + } + else + { + std::cout << "Error loading idl file" << std::endl; + return 1; + } + + // Getting a map with all the structures + std::map types_map = context.module().get_all_types(); + + std::cout << std::endl << "Types loaded: " << types_map.size() << std::endl; + for (auto type_name : types_map) + { + std::cout << " " << type_name.first << std::endl; + } + + std::cout << std::endl << "INTROSPECTION" << std::endl; + std::cout << "-------------" << std::endl; + + // Introspect types + for (auto struct_type : types_map) + { + if (context.module().has_structure(struct_type.first)) + { + const StructType& type = context.module().structure(struct_type.first); + std::cout << struct_type.first << ": " << type << std::endl; + } + else if (context.module().has_enum_32(struct_type.first)) + { + const EnumerationType& enum_type = context.module().enum_32(struct_type.first); + std::cout << struct_type.first << ": " << enum_type << std::endl; + } + else if (context.module().has_submodule(struct_type.first)) + { + const std::shared_ptr submodule_type = context.module().submodule(struct_type.first); + std::cout << struct_type.first << ": " << submodule_type << std::endl; + } + else + { + std::cout << "Unkown type: " << struct_type.first << std::endl; + } + } + + std::cout << "ACCESS" << std::endl; + std::cout << "------" << std::endl; + + const StructType& my_complex_struct = context.module().structure("MyComplexType"); + DynamicData data(my_complex_struct); + + ///// + // Access primitive type + + // set value + data["myPrimitiveType"]["my_float"] = 3.1415f; // Important: the 'f' to set as float and not double + + // get value + std::cout << "Value inside complex struct: " + << data["myPrimitiveType"]["my_float"].value() << std::endl; + + ///// + // Access complex type in collection + + // Types required + const StructType& my_string_struct = context.module().structure("MyStringType"); + StringType string_type; + + // set value + DynamicData string_key(string_type); + string_key = "key_on_map"; + + DynamicData string_data(my_string_struct); + string_data["my_string"] = "value_on_map"; + + data["myCollectionType"]["my_map"][string_key] = string_data; + + // get value + DynamicData new_string_data(my_string_struct); + new_string_data = data["myCollectionType"]["my_map"][string_key]; + std::cout << "Value inside collection inside complex struct: '" + << new_string_data["my_string"].value() << "'" << std::endl; + + ///// + // Access primitive type + + // Types required + const EnumerationType& my_enum_type = context.module().enum_32("MyEnumerationType"); + + // set value + DynamicData my_enum_data(my_enum_type); + my_enum_data = my_enum_type.value("BLUE"); + + data["mySubmoduleType"] = my_enum_data; + + // get value + std::cout << "Value inside submodule struct: " + << data["mySubmoduleType"]["my_enum"].value() << std::endl; + } + catch(const std::runtime_error& e) + { + std::cout << "Exception catched: " << e.what() << std::endl; + return 1; + } + + return 0; +} diff --git a/examples/resources/example.idl b/examples/resources/example.idl new file mode 100644 index 00000000..e8cbe409 --- /dev/null +++ b/examples/resources/example.idl @@ -0,0 +1,11 @@ +#include "sub_modules/example_aux.idl" + +struct MyComplexType +{ + MyAllPrimitiveType myPrimitiveType; + MyStringType myStringType; + MyInheritStringType myInheritStringType; + MyCollectionType myCollectionType; + MyEnumerationType myEnumerationType; + submodule::MySubModuleType mySubmoduleType; +}; diff --git a/examples/resources/sub_modules/example_aux.idl b/examples/resources/sub_modules/example_aux.idl new file mode 100644 index 00000000..5f927d64 --- /dev/null +++ b/examples/resources/sub_modules/example_aux.idl @@ -0,0 +1,54 @@ + +// All Primitive types +struct MyAllPrimitiveType +{ + boolean my_boolean; + char my_char; + octet my_octet; + short my_short; + unsigned short my_unsigned_short; + long my_long; + unsigned long my_unsigned_long; + long long my_long_long; + unsigned long long my_unsigned_long_long; + float my_float; + double my_double; + long double my_long_double; +}; + +// Struct with a string (non primitive struct) +struct MyStringType +{ + string my_string; +}; + +// Struct wthat inherits from other struct +struct MyInheritStringType : MyStringType +{ + string my_child_string; +}; + +// Struct of collection of primitive and non primitive types +struct MyCollectionType +{ + long my_array_long[5]; + sequence my_sequence_long[5]; + map my_map; +}; + +// Enumeration +enum MyEnumerationType +{ + RED, + GREEN, + BLUE +}; + +// Struct under a module (namespace) +module submodule +{ + struct MySubModuleType + { + MyEnumerationType my_enum; + }; +}; diff --git a/include/xtypes/idl/Module.hpp b/include/xtypes/idl/Module.hpp index bdb3778f..3e53405e 100644 --- a/include/xtypes/idl/Module.hpp +++ b/include/xtypes/idl/Module.hpp @@ -379,7 +379,7 @@ class Module for (const auto& pair : inner_) { - pair.second->fill_all_types(map, add_scope); + pair.second->fill_all_types(map, true); } } diff --git a/include/xtypes/idl/parser.hpp b/include/xtypes/idl/parser.hpp index 618acd48..e720ac1e 100644 --- a/include/xtypes/idl/parser.hpp +++ b/include/xtypes/idl/parser.hpp @@ -513,7 +513,7 @@ class Parser str.replace(pos, froms, escaped); pos = str.find(from, pos + escaped_size); } - + } } diff --git a/test/unitary/parser/parser_test.cpp b/test/unitary/parser/parser_test.cpp index 40bd4a37..30123747 100644 --- a/test/unitary/parser/parser_test.cpp +++ b/test/unitary/parser/parser_test.cpp @@ -753,7 +753,7 @@ TEST (IDLParser, include_from_string) )"); std::map result = context.module().get_all_types(); EXPECT_EQ(2, result.size()); - const DynamicType* my_struct = result["Test00"].get(); + const DynamicType* my_struct = result["include::Test00"].get(); DynamicData data(*my_struct); ASSERT_EQ(data["incl"]["my_string"].type().name(), "std::string"); } @@ -1541,9 +1541,9 @@ TEST (IDLParser, same_struct_id_in_different_modules) ); std::map result = context.module().get_all_types(); EXPECT_EQ(1, result.size()); - const DynamicType* my_struct = result["MyStruct"].get(); + const DynamicType* my_struct = result["a::b::c::MyStruct"].get(); EXPECT_EQ(my_struct->name(), "a::b::c::MyStruct"); - first_struct = result["MyStruct"]; + first_struct = result["a::b::c::MyStruct"]; EXPECT_EQ(first_struct.get()->name(), "a::b::c::MyStruct"); } @@ -1565,7 +1565,7 @@ TEST (IDLParser, same_struct_id_in_different_modules) ); std::map result = context.module().get_all_types(); EXPECT_EQ(1, result.size()); - const DynamicType* my_struct = result["MyStruct"].get(); + const DynamicType* my_struct = result["x::y::MyStruct"].get(); EXPECT_EQ(my_struct->name(), "x::y::MyStruct"); }