summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--c++/tools/.nix/derivation.nix31
-rw-r--r--c++/tools/SConscript32
-rw-r--r--c++/tools/SConstruct71
-rw-r--r--c++/tools/c_rpc_iface.cpp8
-rw-r--r--c++/tools/c_rpc_iface.hpp240
-rw-r--r--default.nix9
6 files changed, 390 insertions, 1 deletions
diff --git a/c++/tools/.nix/derivation.nix b/c++/tools/.nix/derivation.nix
new file mode 100644
index 0000000..6e3fbe1
--- /dev/null
+++ b/c++/tools/.nix/derivation.nix
@@ -0,0 +1,31 @@
+{ lib
+, stdenv
+, scons
+, clang-tools
+, version
+, forstio
+}:
+
+let
+
+in stdenv.mkDerivation {
+ pname = "forstio-tools";
+ inherit version;
+ src = ./..;
+
+ enableParallelBuilding = true;
+
+ nativeBuildInputs = [
+ scons
+ clang-tools
+ ];
+
+ buildInputs = [
+ forstio.core
+ forstio.async
+ forstio.io
+ forstio.codec
+ ];
+
+ outputs = ["out" "dev"];
+}
diff --git a/c++/tools/SConscript b/c++/tools/SConscript
new file mode 100644
index 0000000..7c9efd7
--- /dev/null
+++ b/c++/tools/SConscript
@@ -0,0 +1,32 @@
+#!/bin/false
+
+import os
+import os.path
+import glob
+
+
+Import('env')
+
+dir_path = Dir('.').abspath
+
+# Environment for base library
+tools_env = env.Clone();
+
+tools_env.sources = sorted(glob.glob(dir_path + "/*.cpp"))
+tools_env.headers = sorted(glob.glob(dir_path + "/*.h"))
+
+env.sources += tools_env.sources;
+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]);
+
+# Set Alias
+env.Alias('tools_c_array_example', [tools_env.c_array_example]);
+
+env.targets += ['tools_c_array_example'];
+
+# Install
+env.Install('$prefix/bin/', [tools_env.c_array_example]);
diff --git a/c++/tools/SConstruct b/c++/tools/SConstruct
new file mode 100644
index 0000000..9a02291
--- /dev/null
+++ b/c++/tools/SConstruct
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+
+import sys
+import os
+import os.path
+import glob
+import re
+
+
+if sys.version_info < (3,):
+ def isbasestring(s):
+ return isinstance(s,basestring)
+else:
+ def isbasestring(s):
+ return isinstance(s, (str,bytes))
+
+def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, target_post=""):
+
+ if isbasestring(filetype):
+ dir_path = self.Dir('.').abspath
+ filetype = sorted(glob.glob(dir_path+"/"+filetype))
+
+ for path in filetype:
+ target_name = re.sub( r'(.*?)(\.cpp|\.c\+\+)', r'\1' + target_post, path )
+ if shared:
+ target_name+='.os'
+ sources.append( self.SharedObject( target=target_name, source=path ) )
+ else:
+ target_name+='.o'
+ sources.append( self.StaticObject( target=target_name, source=path ) )
+ pass
+
+def isAbsolutePath(key, dirname, env):
+ assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,)
+
+env_vars = Variables(
+ args=ARGUMENTS
+)
+
+env_vars.Add('prefix',
+ help='Installation target location of build results and headers',
+ default='/usr/local/',
+ validator=isAbsolutePath
+)
+
+env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[],
+ CPPDEFINES=['SAW_UNIX'],
+ CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'],
+ LIBS=[
+ 'forstio-core',
+ 'forstio-async',
+ 'forstio-codec'
+ ]
+);
+env.__class__.add_source_files = add_kel_source_files
+env.Tool('compilation_db');
+env.cdb = env.CompilationDatabase('compile_commands.json');
+
+env.objects = [];
+env.sources = [];
+env.headers = [];
+env.targets = [];
+
+Export('env')
+SConscript('SConscript')
+
+env.Alias('cdb', env.cdb);
+env.Alias('all', [env.targets]);
+env.Default('all');
+
+env.Alias('install', '$prefix')
diff --git a/c++/tools/c_rpc_iface.cpp b/c++/tools/c_rpc_iface.cpp
new file mode 100644
index 0000000..3402eec
--- /dev/null
+++ b/c++/tools/c_rpc_iface.cpp
@@ -0,0 +1,8 @@
+#include "c_rpc_iface.hpp"
+
+int main(){
+
+
+ saw::generate_array_example();
+ return 0;
+}
diff --git a/c++/tools/c_rpc_iface.hpp b/c++/tools/c_rpc_iface.hpp
new file mode 100644
index 0000000..867fe60
--- /dev/null
+++ b/c++/tools/c_rpc_iface.hpp
@@ -0,0 +1,240 @@
+#include <forstio/core/error.h>
+#include <forstio/codec/schema.h>
+
+#include <string>
+#include <sstream>
+#include <map>
+
+#include <iostream>
+
+namespace saw {
+
+namespace impl {
+
+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 Schema = schema::Primitive<T,N>;
+ static error_or<void> generate(std::map<std::string,std::string>& map_str, std::string& str, const std::string& prefix){
+ str += c_primitive_string<Schema>::value;
+ return void_t{};
+ }
+};
+
+template<typename T, size_t Dim>
+struct c_data_translater<schema::Array<T,Dim>> {
+ static error_or<void> generate(std::map<std::string, std::string>& map_str, std::string& type_str, const std::string& prefix){
+ type_str = prefix + "_";
+ type_str += "array_";
+
+ std::string inner_type_str;
+ auto eov = impl::c_data_translater<T>::generate(map_str, inner_type_str, prefix);
+ 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(map_str.find(type_str) != map_str.end()){
+ return void_t{};
+ }
+
+ std::string str = "struct ";
+ str += type_str;
+
+ str += " {\n";
+
+ str += "\t" + inner_type_str + "* data;\n";
+ str += "\tsize_t size;\n";
+ if( Dim > 1 ){
+ str += "\tsize_t dims["+std::to_string(Dim)+"];\n";
+ }
+
+ str += "};\n";
+
+ map_str.insert(std::make_pair(std::move(type_str), std::move(str)));
+ return void_t{};
+ }
+};
+
+template<typename Interface>
+struct c_rpc_translater {
+ static_assert(always_false<Interface>,"Not supported");
+};
+
+template<class Request, class Response>
+struct c_rpc_translater<schema::Function<Request, Response>> {
+ using Map = std::map<std::string, std::string>;
+
+ static error_or<void> generate(const std::string& prefix, Map& type_map, Map& func_map){
+
+ return void_t{};
+ }
+};
+
+template<class... Requests, class... Responses, string_literal... Names>
+struct c_rpc_translater<schema::Interface<schema::Member<schema::Function<Requests, Responses>, Names>...>> {
+ using Map = std::map<std::string, std::string>;
+
+ template<size_t i>
+ static error_or<void> generate_member(const std::string& prefix, Map& type_map, Map& func_map){
+ 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;
+
+ std::string func_name{lit.view()};
+ if(func_map.find(func_name) != func_map.end()){
+ return make_error<err::already_exists>();
+ }
+
+ {
+ std::string type_str;
+ auto eov = c_rpc_translater<schema::Function<Req, Resp>>::generate(prefix, type_map, func_map);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+
+ if constexpr ((i+1) < sizeof...(Requests) ){
+ return generate_member<i+1>(prefix, type_map, func_map);
+ }
+ return void_t{};
+ }
+
+ static error_or<void> generate(const std::string& prefix){
+ Map type_map, func_map;
+
+ if constexpr ( sizeof...(Requests) > 0 ){
+ return generate_member<0>(prefix, type_map, func_map);
+ }
+
+ return void_t{};
+ }
+};
+}
+
+template<typename Interface>
+error_or<std::string> generate_c_rpc_interface(){
+ std::stringstream iss;
+ auto eov = impl::c_rpc_translater<Interface>::generate(iss, "c_saw");
+
+ if(eov.is_error()){
+ return std::move(eov.get_error());
+ }
+
+ try {
+ return iss.str();
+ }catch(const std::exception& e){
+ // Do nothing for now
+ }
+ return make_error<err::out_of_memory>();
+}
+
+error_or<void> generate_array_example(){
+ using Schema = schema::Array<schema::Int32,2>;
+
+ using Schema2 = schema::Array<schema::Float64,5>;
+
+ using Schema3 = schema::Array<schema::UInt16,1>;
+
+ std::string prefix = "c_saw";
+ std::map<std::string,std::string> map_str;
+ {
+ std::string type_str;
+ auto eov = impl::c_data_translater<Schema>::generate(map_str, type_str, prefix);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ std::string type_str;
+ auto eov = impl::c_data_translater<Schema2>::generate(map_str, type_str, prefix);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+ {
+ std::string type_str;
+ auto eov = impl::c_data_translater<Schema3>::generate(map_str, type_str, prefix);
+ if(eov.is_error()){
+ return eov;
+ }
+ }
+
+ std::cout<<"Prefix: "<<prefix<<std::endl;
+
+ for(auto& iter : map_str){
+ std::cout<<"\nType: \""<<iter.first<<"\""<<std::endl;
+ std::cout<<"Definition:\n\"\"\"\n";
+ std::cout<<iter.second;
+ std::cout<<"\"\"\""<<std::endl;
+ }
+
+ return void_t{};
+}
+}
diff --git a/default.nix b/default.nix
index 16e7c73..02ba8d0 100644
--- a/default.nix
+++ b/default.nix
@@ -74,7 +74,14 @@ in rec {
inherit forstio;
inherit stdenv;
inherit clang-tools;
- };
+ };
+ tools = pkgs.callPackage c++/tools/.nix/derivation.nix {
+ inherit version;
+ inherit forstio;
+ inherit stdenv;
+ inherit clang-tools;
+ };
+
};
forstio-test-cases = pkgs.callPackage tests/.nix/derivation.nix {