From cbb57aadbfe11269297c36f578d4a440a3602436 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Sat, 24 Dec 2016 11:54:21 +0100 Subject: First implementation of Python wrappers --- CMakeLists.txt | 13 +++ TODO.txt | 2 - config.h.in | 1 + src/bindings/CMakeLists.txt | 9 +- src/bindings/swig/python/CMakeLists.txt | 54 +++++++++++ src/bindings/swig/python/uscxml.i | 163 ++++++++++++++++++++++++++++++++ src/bindings/swig/stl_list.i | 4 +- src/uscxml/plugins/InvokerImpl.h | 2 +- 8 files changed, 240 insertions(+), 8 deletions(-) create mode 100644 src/bindings/swig/python/CMakeLists.txt create mode 100644 src/bindings/swig/python/uscxml.i diff --git a/CMakeLists.txt b/CMakeLists.txt index acea546..11a391c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -199,6 +199,7 @@ endif() OPTION(BUILD_BINDING_JAVA "Build language bindings for Java" ON) OPTION(BUILD_BINDING_LUA "Build language bindings for Lua" ON) OPTION(BUILD_BINDING_CSHARP "Build language bindings for CSharp" ON) +OPTION(BUILD_BINDING_PYTHON "Build language bindings for Python" ON) OPTION(BUILD_BINDING_PHP "Build language bindings for PHP" OFF) @@ -371,6 +372,18 @@ if (WITH_DM_LUA) endif() endif() +# Python +OPTION(WITH_DM_PYTHON "Do search for the Python libraries" ON) +if (WITH_DM_PYTHON) + find_package(PythonLibs) + if (PYTHONLIBS_FOUND) + include_directories (${PYTHON_INCLUDE_DIRS}) + list (APPEND USCXML_OPT_LIBS ${PYTHON_LIBRARIES}) + else() + set(WITH_DM_PYTHON ON) + endif() +endif() + OPTION(WITH_DM_C89 "Do build with C89 datamodel support" OFF) if (WITH_DM_C89) include("${CMAKE_MODULE_PATH}/BuildPicoC.cmake") diff --git a/TODO.txt b/TODO.txt index df47675..020fdfa 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,6 +1,4 @@ -C# / Java Bindings Plugins -VHDL Transformer HTTPS respond element Arraybuffers diff --git a/config.h.in b/config.h.in index 77b1ecb..2990f30 100644 --- a/config.h.in +++ b/config.h.in @@ -68,6 +68,7 @@ #cmakedefine WITH_DM_ECMA_V8 #cmakedefine WITH_DM_ECMA_JSC #cmakedefine WITH_DM_LUA +#cmakedefine WITH_DM_PYTHON #cmakedefine WITH_DM_C89 #cmakedefine WITH_DM_PROMELA diff --git a/src/bindings/CMakeLists.txt b/src/bindings/CMakeLists.txt index 123ec9c..b02b229 100644 --- a/src/bindings/CMakeLists.txt +++ b/src/bindings/CMakeLists.txt @@ -33,9 +33,12 @@ if (SWIG_FOUND) if (BUILD_BINDING_CSHARP) add_subdirectory(swig/csharp) endif() - # if (BUILD_BINDING_PHP) - # add_subdirectory(swig/php) - # endif() + if (BUILD_BINDING_PYTHON) + add_subdirectory(swig/python) + endif() + if (BUILD_BINDING_PHP) + add_subdirectory(swig/php) + endif() if(SWIG_VERSION VERSION_LESS 3.0.0) message(STATUS "SWIG version > 3.0 is recommended, found ${SWIG_VERSION}") diff --git a/src/bindings/swig/python/CMakeLists.txt b/src/bindings/swig/python/CMakeLists.txt new file mode 100644 index 0000000..3335ef2 --- /dev/null +++ b/src/bindings/swig/python/CMakeLists.txt @@ -0,0 +1,54 @@ +if (CMAKE_CROSSCOMPILING) + return() +endif() + +set(Python_ADDITIONAL_VERSIONS) +find_package(PythonLibs) +if(NOT PYTHONLIBS_FOUND) + return() +endif() + +if(NOT PYTHON_INCLUDE_DIRS) + return() +else() + list(REMOVE_ITEM PYTHON_INCLUDE_DIRS "PYTHON_INCLUDE_DIR-NOTFOUND") + if(NOT PYTHON_INCLUDE_DIRS) + return() + endif() +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${PYTHON_INCLUDE_DIRS}) + +# -includeall? +SET(CMAKE_SWIG_FLAGS "-threads" "-c++") + +SET_SOURCE_FILES_PROPERTIES(uscxml.i PROPERTIES SWIG_MODULE_NAME "uscxmlNativePython") +SET_SOURCE_FILES_PROPERTIES(uscxml.i PROPERTIES SWIG_FLAGS "-w401,362;") +SET_SOURCE_FILES_PROPERTIES(uscxml.i PROPERTIES CPLUSPLUS ON) + +SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/uscxmlPYTHON_wrap.cxx PROPERTIES LANGUAGE CXX) +SWIG_ADD_MODULE(uscxmlNativePython python uscxml.i) + +if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/uscxmlPYTHON_wrap.cxx PROPERTIES COMPILE_FLAGS "-Wno-dynamic-class-memaccess") +endif() + +SWIG_LINK_LIBRARIES(uscxmlNativePython ${PYTHON_LIBRARIES}) +SWIG_LINK_LIBRARIES(uscxmlNativePython uscxml) + +set_target_properties(_uscxmlNativePython PROPERTIES FOLDER "Bindings") +set_target_properties(_uscxmlNativePython PROPERTIES COMPILE_FLAGS "-DSWIG") + +ADD_CUSTOM_COMMAND( + TARGET _uscxmlNativePython + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_BINARY_DIR}/uscxmlNativePython.py + ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/uscxmlNativePython.py +) + + +set(USCXML_LANGUAGE_BINDINGS "python ${USCXML_LANGUAGE_BINDINGS}") +set(USCXML_LANGUAGE_BINDINGS ${USCXML_LANGUAGE_BINDINGS} PARENT_SCOPE) + diff --git a/src/bindings/swig/python/uscxml.i b/src/bindings/swig/python/uscxml.i new file mode 100644 index 0000000..c501223 --- /dev/null +++ b/src/bindings/swig/python/uscxml.i @@ -0,0 +1,163 @@ +%module(directors="1") uscxmlNativePython + +// provide a macro for the header files +#define SWIGIMPORTED 1 + +%include +%include +%include +// the std_list.i from SWIG 3.0.10 fails to generate valid c++ code? +/*%include */ +%include "../stl_list.i" + +%include +%include + +// these are needed at least for the templates to work +typedef uscxml::Blob Blob; +typedef uscxml::Data Data; +typedef uscxml::Event Event; +typedef uscxml::Invoker Invoker; +typedef uscxml::IOProcessor IOProcessor; +typedef uscxml::DataModel DataModel; +typedef uscxml::DataModelExtension DataModelExtension; +typedef uscxml::ExecutableContent ExecutableContent; +typedef uscxml::InvokerImpl InvokerImpl; +typedef uscxml::IOProcessorImpl IOProcessorImpl; +typedef uscxml::DataModelImpl DataModelImpl; +typedef uscxml::ExecutableContentImpl ExecutableContentImpl; +typedef uscxml::InterpreterIssue InterpreterIssue; + +%feature("director") uscxml::WrappedInvoker; +%feature("director") uscxml::WrappedDataModel; +%feature("director") uscxml::WrappedDataModelExtension; +%feature("director") uscxml::WrappedIOProcessor; +%feature("director") uscxml::WrappedExecutableContent; +%feature("director") uscxml::WrappedInterpreterMonitor; + +// disable warning related to unknown base class +#pragma SWIG nowarn=401 +// do not warn when we override symbols via extend +#pragma SWIG nowarn=302 +// do not warn when ignoring overrided method +#pragma SWIG nowarn=516 + +%rename(equals) operator==; // signature is wrong, still useful +%rename(isValid) operator bool; + +//************************************************** +// This ends up in the generated wrapper code +//************************************************** + +%{ + +#include "uscxml/config.h" +#include "../../../uscxml/Interpreter.h" +#include "../../../uscxml/debug/InterpreterIssue.h" +#include "../../../uscxml/interpreter/InterpreterState.h" +#include "../../../uscxml/interpreter/InterpreterMonitor.h" + +#include "../../../uscxml/messages/Data.h" +#include "../../../uscxml/messages/Event.h" +#include "../../../uscxml/util/DOM.h" + +#include "../../../uscxml/plugins/Factory.h" +#include "../../../uscxml/plugins/DataModelImpl.h" + +#include "../wrapped/WrappedInvoker.h" +#include "../wrapped/WrappedDataModel.h" +#include "../wrapped/WrappedActionLanguage.h" +#include "../wrapped/WrappedExecutableContent.h" +#include "../wrapped/WrappedIOProcessor.h" +#include "../wrapped/WrappedInterpreterMonitor.h" + +using namespace uscxml; +using namespace XERCESC_NS; + +// the wrapped* C++ classes get rid of DOM nodes and provide more easily wrapped base classes +#include "../wrapped/WrappedInvoker.cpp" +#include "../wrapped/WrappedDataModel.cpp" +#include "../wrapped/WrappedActionLanguage.cpp" +#include "../wrapped/WrappedExecutableContent.cpp" +#include "../wrapped/WrappedIOProcessor.cpp" +#include "../wrapped/WrappedInterpreterMonitor.cpp" + +%} + +%include "../uscxml_ignores.i" + +// bytearray for Blob::data +// see: http://stackoverflow.com/questions/9934059/swig-technique-to-wrap-unsigned-binary-data + +#if 0 +%apply (char *STRING, size_t LENGTH) { (const char* data, size_t size) }; + +%typemap(jni) char* getData "jbyteArray" +%typemap(jtype) char* getData "byte[]" +%typemap(jstype) char* getData "byte[]" +%typemap(javaout) char* getData { + return $jnicall; +} + +%typemap(out) char* getData { + $result = JCALL1(NewByteArray, jenv, ((uscxml::Blob const *)arg1)->getSize()); + JCALL4(SetByteArrayRegion, jenv, $result, 0, ((uscxml::Blob const *)arg1)->getSize(), (jbyte *)$1); +} +#endif + +//*********************************************** +// Beautify important classes +//*********************************************** + + +%include "../uscxml_beautify.i" + + +//*********************************************** +// Parse the header file to generate wrappers +//*********************************************** + +%include "../../../uscxml/Common.h" +%include "../../../uscxml/messages/Blob.h" +%include "../../../uscxml/messages/Data.h" +%include "../../../uscxml/messages/Event.h" + +%include "../../../uscxml/plugins/Factory.h" +%include "../../../uscxml/interpreter/InterpreterState.h" +%include "../../../uscxml/interpreter/InterpreterMonitor.h" + +//%include "../../../uscxml/interpreter/MicroStep.h" +//%include "../../../uscxml/interpreter/ContentExecutor.h" + +%include "../../../uscxml/Interpreter.h" +%include "../../../uscxml/debug/InterpreterIssue.h" + +%include "../../../uscxml/plugins/EventHandler.h" + +%include "../../../uscxml/plugins/DataModel.h" +%include "../../../uscxml/plugins/DataModelImpl.h" +%include "../../../uscxml/plugins/ExecutableContent.h" +%include "../../../uscxml/plugins/ExecutableContentImpl.h" +%include "../../../uscxml/plugins/Invoker.h" +%include "../../../uscxml/plugins/InvokerImpl.h" +%include "../../../uscxml/plugins/IOProcessor.h" +%include "../../../uscxml/plugins/IOProcessorImpl.h" + +%include "../wrapped/WrappedInvoker.h" +%include "../wrapped/WrappedDataModel.h" +%include "../wrapped/WrappedActionLanguage.h" +%include "../wrapped/WrappedExecutableContent.h" +%include "../wrapped/WrappedIOProcessor.h" +%include "../wrapped/WrappedInterpreterMonitor.h" + + +/*%template(IssueList) std::list; +%template(DataList) std::list; +%template(StringList) std::list; +*/ +%template(DataMap) std::map; +%template(StringSet) std::set; +%template(StringVector) std::vector; +%template(ParamMap) std::map >; +%template(IOProcMap) std::map; +%template(InvokerMap) std::map; diff --git a/src/bindings/swig/stl_list.i b/src/bindings/swig/stl_list.i index aabd448..ee1bcda 100644 --- a/src/bindings/swig/stl_list.i +++ b/src/bindings/swig/stl_list.i @@ -43,7 +43,7 @@ namespace std { }; } -%define specialize_std_list(T) +/*%define specialize_std_list(T) #warning "specialize_std_list - specialization for type T no longer needed" %enddef - +*/ diff --git a/src/uscxml/plugins/InvokerImpl.h b/src/uscxml/plugins/InvokerImpl.h index 7f2e578..b000ce2 100644 --- a/src/uscxml/plugins/InvokerImpl.h +++ b/src/uscxml/plugins/InvokerImpl.h @@ -63,7 +63,7 @@ public: virtual void uninvoke() = 0; /** - * Interpreter received an event from the SCXML Interpreter. + * Invoker received an event from the SCXML Interpreter. */ virtual void eventFromSCXML(const Event& event) = 0; -- cgit v0.12