summaryrefslogtreecommitdiff
path: root/modules/tools
diff options
context:
space:
mode:
Diffstat (limited to 'modules/tools')
-rw-r--r--modules/tools/.nix/derivation.nix11
-rw-r--r--modules/tools/SConstruct6
-rw-r--r--modules/tools/c++/SConscript (renamed from modules/tools/SConscript)9
-rw-r--r--modules/tools/c++/c_gen_iface.hpp271
-rw-r--r--modules/tools/c++/cli_analyzer.hpp (renamed from modules/tools/cli_analyzer.hpp)0
-rw-r--r--modules/tools/c_gen_iface.cpp11
-rw-r--r--modules/tools/c_gen_iface.hpp526
-rw-r--r--modules/tools/tests/SConscript31
-rw-r--r--modules/tools/tests/c_iface.cpp56
9 files changed, 376 insertions, 545 deletions
diff --git a/modules/tools/.nix/derivation.nix b/modules/tools/.nix/derivation.nix
index 6e3fbe1..81052f3 100644
--- a/modules/tools/.nix/derivation.nix
+++ b/modules/tools/.nix/derivation.nix
@@ -24,8 +24,15 @@ in stdenv.mkDerivation {
forstio.core
forstio.async
forstio.io
- forstio.codec
- ];
+ forstio.codec
+ forstio.codec-json
+ ];
+
+ doCheck = true;
+ checkPhase = ''
+ scons test
+ ./bin/tests
+ '';
outputs = ["out" "dev"];
}
diff --git a/modules/tools/SConstruct b/modules/tools/SConstruct
index 9a02291..20af11b 100644
--- a/modules/tools/SConstruct
+++ b/modules/tools/SConstruct
@@ -49,7 +49,8 @@ env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[],
LIBS=[
'forstio-core',
'forstio-async',
- 'forstio-codec'
+ 'forstio-codec',
+ 'forstio-codec-json'
]
);
env.__class__.add_source_files = add_kel_source_files
@@ -62,7 +63,8 @@ env.headers = [];
env.targets = [];
Export('env')
-SConscript('SConscript')
+SConscript('c++/SConscript')
+SConscript('tests/SConscript')
env.Alias('cdb', env.cdb);
env.Alias('all', [env.targets]);
diff --git a/modules/tools/SConscript b/modules/tools/c++/SConscript
index 9b1ad89..9ff46d0 100644
--- a/modules/tools/SConscript
+++ b/modules/tools/c++/SConscript
@@ -21,12 +21,13 @@ env.headers += tools_env.headers;
## Static lib
objects_static = []
tools_env.add_source_files(objects_static, tools_env.sources, shared=False);
-tools_env.c_array_example = tools_env.Program('#build/forstio-c-array-example', [objects_static]);
+env.library_static = tools_env.StaticLibrary('#build/forstio-tools', [objects_static]);
# Set Alias
-env.Alias('tools_c_array_example', [tools_env.c_array_example]);
+env.Alias('library_tools', [env.library_static]);
-env.targets += ['tools_c_array_example'];
+env.targets += ['library_tools'];
# Install
-env.Install('$prefix/bin/', [tools_env.c_array_example]);
+env.Install('$prefix/lib/', [env.library_static]);
+env.Install('$prefix/include/forstio/tools/', [tools_env.headers]);
diff --git a/modules/tools/c++/c_gen_iface.hpp b/modules/tools/c++/c_gen_iface.hpp
new file mode 100644
index 0000000..b25e5eb
--- /dev/null
+++ b/modules/tools/c++/c_gen_iface.hpp
@@ -0,0 +1,271 @@
+#include <forstio/error.hpp>
+#include <forstio/codec/data.hpp>
+#include <forstio/codec/schema.hpp>
+#include <forstio/codec/schema_stringify.hpp>
+#include <forstio/templates.hpp>
+
+#include <string>
+#include <sstream>
+#include <map>
+
+#include <iostream>
+
+namespace saw {
+
+namespace schema {
+
+using CVar = Struct<
+ Member<schema::String, "schema">,
+ Member<schema::String, "type">,
+ Member<schema::String, "name">
+>;
+
+using CStruct = Struct<
+ Member<schema::String, "schema">,
+ Member<schema::String, "name">,
+ Member<Array<CVar>, "members">
+>;
+
+using CFunction = Struct<
+ Member<schema::String, "schema">,
+ Member<schema::String, "name">,
+ Member<Array<CVar>, "params">,
+ Member<CVar, "return">
+>;
+
+using CIface = Struct<
+ Member<schema::String, "schema">,
+ Member<Array<CStruct>,"structs">,
+ Member<Array<CFunction>,"functions">
+>;
+}
+/**
+ * Type meant to provide future help if I decide to introduce more maps
+ */
+/**
+namespace schema {
+using namespace saw::schema;
+Pseudo flattened
+using Foo = Struct<
+ Member<Array<Int32>, "a">
+ Member<Array<Float32>, "b">
+>;
+
+Needs to be flattened to
+
+template<typename InnerSchema>
+using FlattenedSchemaElement = Struct<
+ Member<Array<String>, "path">,
+ Member<InnerSchema, "inner_schema">
+>;
+
+// Illegal, but doable with more lines of code
+// Just use typename... T and
+// "T..." for
+// "Member<FlattenedSchemaElement<Ele>,Names>...>"
+// and specialize somewhere else
+template<typename... Ele, string_literal... Names>
+using FlattenedSchema = Struct<
+ Member<String, "top_schema">,
+ Member<FlattenedSchemaElement<Ele>, Names>...
+>;
+}
+ */
+template<typename T, typename Res>
+struct schema_flattener {
+ static_assert(always_false<T>, "Not supported");
+};
+
+template<typename T0, string_literal Name0, typename... T, string_literal... Names, typename Res>
+struct schema_flattener<schema::Struct<schema::Member<T0,Name0>,schema::Member<T,Names>...>, Res> {
+};
+
+/**
+ * Helper to determine if we are dealing with primitive types
+ */
+template<typename Schema>
+struct c_is_primitive {
+ static constexpr bool value = false;
+};
+
+template<typename T, size_t N>
+struct c_is_primitive<schema::Primitive<T,N>> {
+ static constexpr bool value = true;
+};
+
+template<typename Schema>
+struct c_primitive_string {
+ static_assert(always_false<Schema>, "Not supported");
+};
+
+template<>
+struct c_primitive_string<schema::Int8> {
+ static constexpr std::string_view value = "int8_t";
+};
+
+template<>
+struct c_primitive_string<schema::Int16> {
+ static constexpr std::string_view value = "int16_t";
+};
+
+template<>
+struct c_primitive_string<schema::Int32> {
+ static constexpr std::string_view value = "int32_t";
+};
+
+template<>
+struct c_primitive_string<schema::Int64> {
+ static constexpr std::string_view value = "int64_t";
+};
+
+template<>
+struct c_primitive_string<schema::UInt8> {
+ static constexpr std::string_view value = "uint8_t";
+};
+
+template<>
+struct c_primitive_string<schema::UInt16> {
+ static constexpr std::string_view value = "uint16_t";
+};
+
+template<>
+struct c_primitive_string<schema::UInt32> {
+ static constexpr std::string_view value = "uint32_t";
+};
+
+template<>
+struct c_primitive_string<schema::UInt64> {
+ static constexpr std::string_view value = "uint64_t";
+};
+
+template<>
+struct c_primitive_string<schema::Float32> {
+ static constexpr std::string_view value = "float";
+};
+
+template<>
+struct c_primitive_string<schema::Float64> {
+ static constexpr std::string_view value = "double";
+};
+
+bool c_interface_function_exists(data<schema::CIface>& state, const std::string_view& name){
+ auto& funcs = state.template get<"functions">();
+ for(uint64_t i = 0; i < funcs.size(); ++i){
+ if(funcs.at(i).get<"name">() == name){
+ return true;
+ }
+ }
+ return false;
+}
+
+template<typename Schema>
+struct c_data_translater {
+ static_assert(always_false<Schema>, "Not supported");
+};
+
+template<typename T, uint64_t N>
+struct c_data_translater<schema::Primitive<T,N>> {
+ using Schema = schema::Primitive<T,N>;
+
+ static error_or<void> generate(data<schema::CIface>& state, data<schema::CVar>& prim){
+ /// @TODO Check if exists in CVars already
+ try{
+ std::stringstream iss;
+ schema_stringify<Schema>::apply(iss);
+ prim.template get<"schema">().set(iss.str());
+ }catch(const std::exception&){
+ return make_error<err::out_of_memory>();
+ }
+
+ return void_t{};
+ }
+};
+
+template<typename Req, typename Ret>
+struct c_data_translater<schema::Function<Req,Ret>> {
+ using Schema = schema::Function<Req,Ret>;
+
+ static error_or<void> generate(data<schema::CIface>& state, const std::string_view& func_name){
+ if(c_interface_function_exists(state, func_name)){
+ return make_error<err::invalid_state>("Function already exists");
+ }
+
+ auto& funcs = state.template get<"functions">();
+ data<schema::CFunction> function;
+ function.template get<"name">().set(std::string{func_name});
+
+ try{
+ std::stringstream iss;
+ schema_stringify<Schema>::apply(iss);
+ function.template get<"schema">().set(iss.str());
+ }catch(const std::exception&){
+ return make_error<err::out_of_memory>();
+ }
+
+ {
+ auto& c_var = function.template get<"return">();
+ c_var.template get<"name">().set("ret_val");
+ auto eov = c_data_translater<Ret>::generate(state, c_var);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+
+ {
+ auto eov = funcs.add(std::move(function));
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+
+ return void_t{};
+ }
+};
+
+template<typename... Funcs, string_literal... Names>
+struct c_data_translater<schema::Interface<schema::Member<Funcs,Names>...>> {
+ using Schema = schema::Interface<schema::Member<Funcs, Names>...>;
+
+ template<std::size_t i>
+ static error_or<void> generate_ele(data<schema::CIface>& state){
+ using InnerSchema = typename parameter_pack_type<i, Funcs...>::type;
+ constexpr string_literal Literal = parameter_key_pack_type<i, Names...>::literal;
+ {
+ auto eov = c_data_translater<InnerSchema>::generate(state, Literal.view());
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+
+ /**
+ * Continue if elements remain or finish
+ */
+ if constexpr ( (i+1) < sizeof...(Funcs) ){
+ return generate_ele<i+1>(state);
+ }
+ return void_t{};
+ }
+
+ static error_or<void> generate(data<schema::CIface>& state){
+ try{
+ std::stringstream iss;
+ schema_stringify<Schema>::apply(iss);
+ state.template get<"schema">().set(iss.str());
+ }catch(const std::exception&){
+ return make_error<err::out_of_memory>();
+ }
+
+ if constexpr (sizeof...(Funcs) > 0){
+ return generate_ele<0>(state);
+ }
+ return void_t{};
+ }
+};
+
+template<typename Interface>
+error_or<void> generate_c_interface(data<schema::CIface>& state){
+ auto eov = c_data_translater<Interface>::generate(state);
+ return eov;
+}
+
+}
diff --git a/modules/tools/cli_analyzer.hpp b/modules/tools/c++/cli_analyzer.hpp
index 402f03c..402f03c 100644
--- a/modules/tools/cli_analyzer.hpp
+++ b/modules/tools/c++/cli_analyzer.hpp
diff --git a/modules/tools/c_gen_iface.cpp b/modules/tools/c_gen_iface.cpp
deleted file mode 100644
index 996f3c3..0000000
--- a/modules/tools/c_gen_iface.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "c_gen_iface.hpp"
-
-int main(){
- // saw::generate_array_example();
-
- auto eov = saw::generate_iface_example();
- if(eov.is_error()){
- return -1;
- }
- return 0;
-}
diff --git a/modules/tools/c_gen_iface.hpp b/modules/tools/c_gen_iface.hpp
deleted file mode 100644
index 08cf2f4..0000000
--- a/modules/tools/c_gen_iface.hpp
+++ /dev/null
@@ -1,526 +0,0 @@
-#include <forstio/error.hpp>
-#include <forstio/templates.hpp>
-#include <forstio/codec/schema.hpp>
-
-#include <string>
-#include <sstream>
-#include <map>
-
-#include <iostream>
-
-#include <forstio/codec/schema_stringify.hpp>
-
-namespace saw {
-
-namespace impl {
-namespace schema {
-using namespace saw::schema;
-
-using CVar = Struct<
- Member<schema::String, "schema">,
- Member<schema::String, "type">,
- Member<schema::String, "name">
->;
-
-using CStruct = Struct<
- Member<schema::String, "schema">,
- Member<schema::String, "name">,
- Member<Array<CVar>, "members">
->;
-
-using CFunction = Struct<
- Member<schema::String, "schema">,
- Member<schema::String, "name">,
- Member<Array<CVar>, "params">
->;
-
-using CIface = Struct<
- Member<schema::String, "schema">,
- Member<Array<CStruct>,"structs">,
- Member<Array<CFunction>,"function">
->;
-}
-/**
- * Type meant to provide future help if I decide to introduce more maps
- */
-struct c_types {
-
- struct c_member {
- std::string key;
- std::string name;
- bool is_primitive;
- };
-
- struct c_struct {
- std::string kind;
- std::string type;
- std::string cpp_schema;
- std::vector<c_member> members;
- };
-
- struct c_response {
- std::string key;
- bool is_primitive;
- };
-
- struct c_func {
- std::string cpp_schema;
- std::string cpp_name;
- c_response response;
- std::vector<c_member> requests;
- };
-
- using c_struct_map = std::map<std::string, c_struct>;
- using c_func_map = std::map<std::string, c_func>;
-
- struct state {
- std::string interface_schema;
- c_struct_map struct_map;
- c_func_map func_map;
- std::string prefix;
- std::string postfix;
- std::string encoding;
- };
-};
-
-namespace schema {
-using namespace saw::schema;
-/**
-Pseudo flattened
-using Foo = Struct<
- Member<Array<Int32>, "a">
- Member<Array<Float32>, "b">
->;
-
-Needs to be flattened to
-
-template<typename InnerSchema>
-using FlattenedSchemaElement = Struct<
- Member<Array<String>, "path">,
- Member<InnerSchema, "inner_schema">
->;
-
-// Illegal, but doable with more lines of code
-// Just use typename... T and
-// "T..." for
-// "Member<FlattenedSchemaElement<Ele>,Names>...>"
-// and specialize somewhere else
-template<typename... Ele, string_literal... Names>
-using FlattenedSchema = Struct<
- Member<String, "top_schema">,
- Member<FlattenedSchemaElement<Ele>, Names>...
->;
- */
-template<typename T, typename Res>
-struct schema_flattener {
- static_assert(always_false<T>, "Not supported");
-};
-
-template<typename T0, string_literal Name0, typename... T, string_literal... Names, typename Res>
-struct schema_flattener<schema::Struct<schema::Member<T0,Name0>,schema::Member<T,Names>...>, Res> {
-};
-
-using StructBindingSchema = Struct<
- Member<String, "kind">,
- Member<String, "key">,
- Member<String, "cpp_schema">,
- Member<Array<String>, "members">
->;
-
-using FunctionBindingSchema = Struct<
- Member<String, "cpp_schema">,
- Member<String, "name">,
- Member<String, "foo">
->;
-
-using BindingSchema = Struct<
- Member<String, "interface_schema">,
- Member<String, "prefix">,
- Member<String, "postfix">,
- Member<String, "encoding">,
- Member<Array<StructBindingSchema>, "structs">,
- Member<Array<FunctionBindingSchema>, "functions">
->;
-}
-
-/**
- * Helper to determine if we are dealing with primitive types
- */
-template<typename Schema>
-struct c_is_primitive {
- static constexpr bool value = false;
-};
-
-template<typename T, size_t N>
-struct c_is_primitive<schema::Primitive<T,N>> {
- static constexpr bool value = true;
-};
-
-template<typename Schema>
-struct c_primitive_string {
- static_assert(always_false<Schema>, "Not supported");
-};
-
-template<>
-struct c_primitive_string<schema::Int8> {
- static constexpr std::string_view value = "int8_t";
-};
-
-template<>
-struct c_primitive_string<schema::Int16> {
- static constexpr std::string_view value = "int16_t";
-};
-
-template<>
-struct c_primitive_string<schema::Int32> {
- static constexpr std::string_view value = "int32_t";
-};
-
-template<>
-struct c_primitive_string<schema::Int64> {
- static constexpr std::string_view value = "int64_t";
-};
-
-template<>
-struct c_primitive_string<schema::UInt8> {
- static constexpr std::string_view value = "uint8_t";
-};
-
-template<>
-struct c_primitive_string<schema::UInt16> {
- static constexpr std::string_view value = "uint16_t";
-};
-
-template<>
-struct c_primitive_string<schema::UInt32> {
- static constexpr std::string_view value = "uint32_t";
-};
-
-template<>
-struct c_primitive_string<schema::UInt64> {
- static constexpr std::string_view value = "uint64_t";
-};
-
-template<>
-struct c_primitive_string<schema::Float32> {
- static constexpr std::string_view value = "float";
-};
-
-template<>
-struct c_primitive_string<schema::Float64> {
- static constexpr std::string_view value = "double";
-};
-
-template<typename Schema>
-struct c_data_translater {
- static_assert(always_false<Schema>, "Not supported");
-};
-
-template<typename T, size_t N>
-struct c_data_translater<schema::Primitive<T,N>> {
- using StructMap = typename c_types::c_struct_map;
- using Schema = schema::Primitive<T,N>;
-
- static error_or<void> generate(c_types::state& c_state, std::string& str){
- (void) c_state;
- str += c_primitive_string<Schema>::value;
- return void_t{};
- }
-};
-
-template<typename T, size_t Dim>
-struct c_data_translater<schema::Array<T,Dim>> {
- using Schema = schema::Array<T,Dim>;
- using StructMap = typename c_types::c_struct_map;
-
- static error_or<void> generate(c_types::state& c_state, std::string& type_str){
- type_str = "array_";
-
- std::string inner_type_str;
- auto eov = impl::c_data_translater<T>::generate(c_state, inner_type_str);
- if(eov.is_error()){
- return eov;
- }
-
- type_str += inner_type_str;
-
- if(Dim > 1){
- type_str += "_";
- type_str += std::to_string(Dim);
- type_str += "d";
- }
-
- if(c_state.struct_map.find(type_str) != c_state.struct_map.end()){
- return void_t{};
- }
-
- c_types::c_struct str;
-
- try {
- std::stringstream iss;
- schema_stringify<Schema>::apply(iss);
- str.cpp_schema = iss.str();
- }catch(const std::exception& e){
- return make_error<err::critical>();
- }
-
- /**
- * Adding heap alloc data ptr
- */
- {
- c_types::c_member memb;
- memb.key = inner_type_str;
- memb.name = "data";
- memb.is_primitive = c_is_primitive<T>::value;
- // fn.members.emplace_back(std::move(memb));
-
- str.members.emplace_back(std::move(memb));
- }
- {
- c_types::c_member memb;
- }
-
-
- str.type = "struct ";
- str.type += type_str;
-
- str.type += " {\n";
-
- str.type += "\t" + inner_type_str + "* data;\n";
- str.type += "\tsize_t size;\n";
- if( Dim > 1 ){
- str.type += "\tsize_t dims["+std::to_string(Dim)+"];\n";
- }
-
- str.type += "};\n";
-
- c_state.struct_map.emplace(std::make_pair(type_str, std::move(str)));
- return void_t{};
- }
-};
-
-template<typename Interface>
-struct c_iface_translater {
- static_assert(always_false<Interface>,"Not supported");
-};
-
-template<class... Request, class Response, string_literal... Lits>
-struct c_iface_translater<schema::Function<schema::Struct<schema::Member<Request, Lits>...>, Response>> {
- using StructMap = typename c_types::c_struct_map;
- using FuncMap = typename c_types::c_func_map;
-
- template<size_t i>
- static error_or<void> generate_request_member(c_types::state& c_state, std::array<std::string, sizeof...(Request)>& type_arr){
- using Type = typename parameter_pack_type<i, Request...>::type;
- // constexpr string_literal lit = parameter_key_pack_type<i, Lits...>::literal;
-
- auto eov = c_data_translater<Type>::generate(c_state, type_arr.at(i));
- if(eov.is_error()){
- return eov;
- }
-
- if constexpr ((i+1) < sizeof...(Request)){
- auto eov = generate_request_member<i+1>(c_state, type_arr);
- return eov;
- }
-
- return void_t{};
- }
-
- template<size_t i>
- static error_or<void> generate_parameter(std::string& param_use, const std::array<std::string, sizeof...(Request)>& req_type_arr){
- using Type = typename parameter_pack_type<i, Request...>::type;
- constexpr string_literal lit = parameter_key_pack_type<i, Lits...>::literal;
-
- std::string used_param;
- if constexpr (c_is_primitive<Type>::value){
- used_param += req_type_arr.at(i);
- } else {
- used_param += "const " + req_type_arr.at(i) + "*";
- }
- param_use += used_param + " " + std::string{lit.view()};
-
- if constexpr ( (i+1) < sizeof...(Request) ){
- param_use += ", ";
- return generate_parameter<i+1>(param_use, req_type_arr);
- }
-
- return void_t{};
- }
-
- static error_or<void> generate(c_types::state& c_state, const std::string& func_name){
- std::array<std::string, sizeof...(Request)> request_type_arr;
-
- if constexpr (sizeof...(Request) > 0){
- auto eov = generate_request_member<0>(c_state, request_type_arr);
- if(eov.is_error()){
- return eov;
- }
- }
- std::string response_type_str;
- {
- auto eov = c_data_translater<Response>::generate(c_state, response_type_str);
- if(eov.is_error()){
- return eov;
- }
- }
-
- c_types::c_func fn;
- fn.cpp_name = func_name;
-
-
- c_state.func_map.emplace(std::make_pair(fn.cpp_name, std::move(fn)));
-
- return void_t{};
- }
-};
-
-template<class... Requests, class... Responses, string_literal... Names>
-struct c_iface_translater<schema::Interface<schema::Member<schema::Function<Requests, Responses>, Names>...>> {
- using Schema = schema::Interface<schema::Member<schema::Function<Requests, Responses>, Names>...>;
-
- template<size_t i>
- static error_or<void> generate_member(c_types::state& c_state){
- using Req = typename parameter_pack_type<i,Requests...>::type;
- using Resp = typename parameter_pack_type<i,Responses...>::type;
- constexpr string_literal lit = parameter_key_pack_type<i, Names...>::literal;
-
- try{
- std::stringstream iss;
- schema_stringify<Schema>::apply(iss);
- c_state.interface_schema = iss.str();
- }catch(const std::exception& e){
- (void) e;
- return make_error<err::critical>();
- }
-
- std::string c_func_name = c_state.prefix + "_" + std::string{lit.view()};
- if(c_state.func_map.find(c_func_name) != c_state.func_map.end()){
- return make_error<err::already_exists>();
- }
-
- {
- std::string type_str;
- auto eov = c_iface_translater<schema::Function<Req, Resp>>::generate(c_state, std::string{lit.view()});
- if(eov.is_error()){
- return eov;
- }
- }
-
- if constexpr ((i+1) < sizeof...(Requests) ){
- return generate_member<i+1>(c_state);
- }
- return void_t{};
- }
-
- static error_or<void> generate(c_types::state& c_state){
- if constexpr ( sizeof...(Requests) > 0 ){
- return generate_member<0>(c_state);
- }
-
- return void_t{};
- }
-};
-}
-
-template<typename Interface>
-error_or<void> generate_c_interface(typename impl::c_types::state& state){
- auto eov = impl::c_iface_translater<Interface>::generate(state);
- return eov;
-}
-
-error_or<void> generate_iface_example(){
- using Request1 = schema::Struct<
- schema::Member<schema::Int32, "foo">,
- schema::Member<schema::Float64, "bar">,
- schema::Member<schema::Array<schema::Float32,1>, "baz">
- >;
- using Response1 = schema::Int32;
-
- using Func1 = schema::Function<Request1, Response1>;
-
- using Iface = schema::Interface<
- schema::Member<Func1, "func_one">
- >;
-
- using CIfaceDesc = schema::Struct<
- Member<schema::String, "prefix">,
- Member<schema::String, "encoding">
- >;
-
- impl::c_types::state c_state;
- c_state.prefix = "c_saw";
- c_state.encoding = "saw::encode::Native";
-
- typename impl::c_types::c_struct_map& type_map = c_state.struct_map;
- typename impl::c_types::c_func_map& func_map = c_state.func_map;
- auto eov = generate_c_interface<Iface>(c_state);
- if(eov.is_error()){
- return eov;
- }
- std::cout<<"Interface: "<<c_state.interface_schema<<std::endl;
- std::cout<<"Prefix: "<<c_state.prefix<<std::endl;
- std::cout<<"\nTypes: "<<std::endl;
-
- for(auto& iter : type_map){
- std::cout<<"\nType: \""<<iter.first<<"\""<<std::endl;
- std::cout<<"Definition:\n\"\"\"\n";
- std::cout<<iter.second.type;
- std::cout<<"\"\"\""<<std::endl;
- std::cout<<"Schema: "<<iter.second.cpp_schema<<std::endl;
- }
- std::cout<<"\nFunctions: "<<std::endl;
-
- for(auto& iter : func_map){
- std::cout<<"\nSymbol: \""<<iter.first<<"\""<<std::endl;
- std::cout<<"Definition:\n\"\"\"\n";
- std::cout<<iter.second.cpp_name<<";\n";
- }
-
- return eov;
-}
-
-error_or<void> generate_array_example(){
- using Schema1 = schema::Array<schema::Int32,2>;
-
- using Schema2 = schema::Array<schema::Float64,5>;
-
- using Schema3 = schema::Array<schema::UInt16,1>;
-
- std::string prefix = "c_saw";
- impl::c_types::state c_state;
- c_state.prefix = prefix;
- {
- std::string type_str;
- auto eov = impl::c_data_translater<Schema1>::generate(c_state, type_str);
- if(eov.is_error()){
- return eov;
- }
- }
- {
- std::string type_str;
- auto eov = impl::c_data_translater<Schema2>::generate(c_state, type_str);
- if(eov.is_error()){
- return eov;
- }
- }
- {
- std::string type_str;
- auto eov = impl::c_data_translater<Schema3>::generate(c_state, type_str);
- if(eov.is_error()){
- return eov;
- }
- }
-
- std::cout<<"Prefix: "<<c_state.prefix<<std::endl;
-
- for(auto& iter : c_state.struct_map){
- std::cout<<"\nType: \""<<iter.first<<"\""<<std::endl;
- std::cout<<"Definition:\n\"\"\"\n";
- std::cout<<iter.second.type;
- std::cout<<"\"\"\""<<std::endl;
- }
-
- return void_t{};
-}
-}
diff --git a/modules/tools/tests/SConscript b/modules/tools/tests/SConscript
new file mode 100644
index 0000000..f8ffc92
--- /dev/null
+++ b/modules/tools/tests/SConscript
@@ -0,0 +1,31 @@
+#!/bin/false
+
+import os
+import os.path
+import glob
+
+
+Import('env')
+
+dir_path = Dir('.').abspath
+
+# Environment for base library
+test_cases_env = env.Clone();
+
+test_cases_env.Append(LIBS=['forstio-test']);
+
+test_cases_env.sources = sorted(glob.glob(dir_path + "/*.cpp"))
+test_cases_env.headers = sorted(glob.glob(dir_path + "/*.hpp"))
+
+env.sources += test_cases_env.sources;
+env.headers += test_cases_env.headers;
+
+objects_static = []
+test_cases_env.add_source_files(objects_static, test_cases_env.sources, shared=False);
+test_cases_env.program = test_cases_env.Program('#bin/tests', [objects_static, env.library_static]);
+
+# Set Alias
+env.Alias('test', test_cases_env.program);
+env.Alias('check', test_cases_env.program);
+
+env.targets += ['test','check'];
diff --git a/modules/tools/tests/c_iface.cpp b/modules/tools/tests/c_iface.cpp
new file mode 100644
index 0000000..121605a
--- /dev/null
+++ b/modules/tools/tests/c_iface.cpp
@@ -0,0 +1,56 @@
+#include <forstio/test/suite.hpp>
+#include <forstio/codec/json/json.hpp>
+
+#include "../c++/c_gen_iface.hpp"
+
+#include <iostream>
+
+namespace {
+namespace schema {
+using namespace saw::schema;
+
+using TestEmptyInterface = Interface<>;
+
+using TestOneFunctionInterface = Interface<
+ Member<Function<Int32, Int32>, "one">
+>;
+}
+
+template<typename Schema>
+void test_generate(std::string& res){
+ using namespace saw;
+
+ data<schema::CIface> c_iface;
+ {
+ auto eov = generate_c_interface<Schema>(c_iface);
+ SAW_EXPECT(eov.is_value(), "Couldn't generate interface info");
+ }
+
+ data<schema::CIface, encode::Json> j_data;
+ codec<schema::CIface, encode::Json> j_codec;
+
+ {
+ auto eov = j_codec.encode(c_iface, j_data);
+ SAW_EXPECT(eov.is_value(), "Couldn't encode data");
+ }
+
+ res = convert_to_string(j_data.get_buffer());
+}
+
+SAW_TEST("CIface Empty Interface"){
+ using namespace saw;
+
+ std::string res;
+ test_generate<schema::TestEmptyInterface>(res);
+
+ std::cout<<"\n"<<res<<"\n"<<std::endl;
+}
+
+SAW_TEST("CIface One Function Interface"){
+ using namespace saw;
+
+ std::string res;
+ test_generate<schema::TestOneFunctionInterface>(res);
+ std::cout<<"\n"<<res<<"\n"<<std::endl;
+}
+}