From b5529e54569d6271641f5bb38b0901f19d438830 Mon Sep 17 00:00:00 2001 From: Mislav Novakovic Date: Mon, 29 Feb 2016 11:42:43 +0100 Subject: [PATCH 1/3] change variable name from private to priv because of swig bindings to javascript Signed-off-by: Mislav Novakovic --- src/tree_schema.c | 8 ++++---- src/tree_schema.h | 28 ++++++++++++++-------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/tree_schema.c b/src/tree_schema.c index ee344cab2..deb6ad289 100644 --- a/src/tree_schema.c +++ b/src/tree_schema.c @@ -1873,8 +1873,8 @@ lys_node_free(struct lys_node *node, void (*private_destructor)(const struct lys ctx = node->module->ctx; /* remove private object */ - if (node->private && private_destructor) { - private_destructor(node, node->private); + if (node->priv && private_destructor) { + private_destructor(node, node->priv); } /* common part */ @@ -2756,8 +2756,8 @@ lys_set_private(const struct lys_node *node, void *priv) return NULL; } - prev = node->private; - ((struct lys_node *)node)->private = priv; + prev = node->priv; + ((struct lys_node *)node)->priv = priv; return prev; } diff --git a/src/tree_schema.h b/src/tree_schema.h index 5fcd2e96a..639484c0d 100644 --- a/src/tree_schema.h +++ b/src/tree_schema.h @@ -523,7 +523,7 @@ struct lys_node { uint8_t features_size; /**< number of elements in the #features array */ struct lys_feature **features; /**< array of pointers to feature definitions, this is not the array of feature definitions themselves, but the array of if-feature references */ - void *private; /**< private caller's data, not used by libyang */ + void *priv; /**< private caller's data, not used by libyang */ }; /** @@ -555,7 +555,7 @@ struct lys_node_container { uint8_t features_size; /**< number of elements in the #features array */ struct lys_feature **features; /**< array of pointers to feature definitions, this is not the array of feature definitions themselves, but the array of if-feature references */ - void *private; /**< private caller's data, not used by libyang */ + void *priv; /**< private caller's data, not used by libyang */ /* specific container's data */ struct lys_when *when; /**< when statement (optional) */ @@ -597,7 +597,7 @@ struct lys_node_choice { uint8_t features_size; /**< number of elements in the #features array */ struct lys_feature **features; /**< array of pointers to feature definitions, this is not the array of feature definitions themselves, but the array of if-feature references */ - void *private; /**< private caller's data, not used by libyang */ + void *priv; /**< private caller's data, not used by libyang */ /* specific choice's data */ struct lys_when *when; /**< when statement (optional) */ @@ -639,7 +639,7 @@ struct lys_node_leaf { uint8_t features_size; /**< number of elements in the #features array */ struct lys_feature **features; /**< array of pointers to feature definitions, this is not the array of feature definitions themselves, but the array of if-feature references */ - void *private; /**< private caller's data, not used by libyang */ + void *priv; /**< private caller's data, not used by libyang */ /* specific leaf's data */ struct lys_when *when; /**< when statement (optional) */ @@ -687,7 +687,7 @@ struct lys_node_leaflist { uint8_t features_size; /**< number of elements in the #features array */ struct lys_feature **features; /**< array of pointers to feature definitions, this is not the array of feature definitions themselves, but the array of if-feature references */ - void *private; /**< private caller's data, not used by libyang */ + void *priv; /**< private caller's data, not used by libyang */ /* specific leaf-list's data */ struct lys_when *when; /**< when statement (optional) */ @@ -731,7 +731,7 @@ struct lys_node_list { uint8_t features_size; /**< number of elements in the #features array */ struct lys_feature **features; /**< array of pointers to feature definitions, this is not the array of feature definitions themselves, but the array of if-feature references */ - void *private; /**< private caller's data, not used by libyang */ + void *priv; /**< private caller's data, not used by libyang */ /* specific list's data */ struct lys_when *when; /**< when statement (optional) */ @@ -781,7 +781,7 @@ struct lys_node_anyxml { uint8_t features_size; /**< number of elements in the #features array */ struct lys_feature **features; /**< array of pointers to feature definitions, this is not the array of feature definitions themselves, but the array of if-feature references */ - void *private; /**< private caller's data, not used by libyang */ + void *priv; /**< private caller's data, not used by libyang */ /* specific anyxml's data */ struct lys_when *when; /**< when statement (optional) */ @@ -821,7 +821,7 @@ struct lys_node_uses { uint8_t features_size; /**< number of elements in the #features array */ struct lys_feature **features; /**< array of pointers to feature definitions, this is not the array of feature definitions themselves, but the array of if-feature references */ - void *private; /**< private caller's data, not used by libyang */ + void *priv; /**< private caller's data, not used by libyang */ /* specific uses's data */ struct lys_when *when; /**< when statement (optional) */ @@ -865,7 +865,7 @@ struct lys_node_grp { uint8_t features_size; /**< number of elements in the #features array */ struct lys_feature **features; /**< array of pointers to feature definitions, this is not the array of feature definitions themselves, but the array of if-feature references */ - void *private; /**< private caller's data, not used by libyang */ + void *priv; /**< private caller's data, not used by libyang */ /* specific grouping's data */ uint8_t tpdf_size; /**< number of elements in #tpdf array */ @@ -900,7 +900,7 @@ struct lys_node_case { uint8_t features_size; /**< number of elements in the #features array */ struct lys_feature **features; /**< array of pointers to feature definitions, this is not the array of feature definitions themselves, but the array of if-feature references */ - void *private; /**< private caller's data, not used by libyang */ + void *priv; /**< private caller's data, not used by libyang */ /* specific case's data */ struct lys_when *when; /**< when statement (optional) */ @@ -936,7 +936,7 @@ struct lys_node_rpc_inout { struct lys_tpdf *tpdf; /**< array of typedefs */ /* again ::lys_node compatible data */ - void *private; /**< private caller's data, not used by libyang */ + void *priv; /**< private caller's data, not used by libyang */ }; /** @@ -965,7 +965,7 @@ struct lys_node_notif { uint8_t features_size; /**< number of elements in the #features array */ struct lys_feature **features; /**< array of pointers to feature definitions, this is not the array of feature definitions themselves, but the array of if-feature references */ - void *private; /**< private caller's data, not used by libyang */ + void *priv; /**< private caller's data, not used by libyang */ /* specific rpc's data */ uint8_t tpdf_size; /**< number of elements in the #tpdf array */ @@ -998,7 +998,7 @@ struct lys_node_rpc { uint8_t features_size; /**< number of elements in the #features array */ struct lys_feature **features; /**< array of pointers to feature definitions, this is not the array of feature definitions themselves, but the array of if-feature references */ - void *private; /**< private caller's data, not used by libyang */ + void *priv; /**< private caller's data, not used by libyang */ /* specific rpc's data */ uint8_t tpdf_size; /**< number of elements in the #tpdf array */ @@ -1043,7 +1043,7 @@ struct lys_node_augment { uint8_t features_size; /**< number of elements in the #features array */ struct lys_feature **features; /**< array of pointers to feature definitions, this is not the array of feature definitions themselves, but the array of if-feature references */ - void *private; /**< private caller's data, not used by libyang */ + void *priv; /**< private caller's data, not used by libyang */ }; From a827b5f252c3c614073fc713ba21f365025dc30f Mon Sep 17 00:00:00 2001 From: Mislav Novakovic Date: Mon, 29 Feb 2016 11:47:22 +0100 Subject: [PATCH 2/3] add swig javascript bindings Signed-off-by: Mislav Novakovic --- CMakeLists.txt | 4 + CMakeModules/FindNodejs.cmake | 94 ++++++++++++++++++++++ swig/javascript/CMakeLists.txt | 116 +++++++++++++++++++++++++++ swig/javascript/binding.gyp.cmake | 34 ++++++++ swig/javascript/libyang_javascript.i | 16 ++++ swig/javascript/package.json.cmake | 9 +++ 6 files changed, 273 insertions(+) create mode 100644 CMakeModules/FindNodejs.cmake create mode 100644 swig/javascript/CMakeLists.txt create mode 100644 swig/javascript/binding.gyp.cmake create mode 100644 swig/javascript/libyang_javascript.i create mode 100644 swig/javascript/package.json.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fc72a421..c1ad9f444 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,3 +146,7 @@ if(ENABLE_BUILD_TESTS) add_subdirectory(tests) endif(CMOCKA_FOUND) endif(ENABLE_BUILD_TESTS) + +if(JAVASCRIPT_BINDING) + include(swig/javascript/CMakeLists.txt) +endif() diff --git a/CMakeModules/FindNodejs.cmake b/CMakeModules/FindNodejs.cmake new file mode 100644 index 000000000..50307688b --- /dev/null +++ b/CMakeModules/FindNodejs.cmake @@ -0,0 +1,94 @@ + # Macro to add directory to NODEJS_INCLUDE_DIRS if it exists and is not /usr/include + macro(add_include_dir dir) + if (IS_DIRECTORY ${dir} AND NOT ${dir} STREQUAL "/usr/include") + set(NODEJS_INCLUDE_DIRS ${NODEJS_INCLUDE_DIRS} ${dir}) + endif() +endmacro() + + +find_program (NODEJS_EXECUTABLE NAMES node nodejs + HINTS + $ENV{NODE_DIR} + PATH_SUFFIXES bin + DOC "Node.js interpreter" +) + +include (FindPackageHandleStandardArgs) + +# If compat-libuv package exists, it must be at start of include path +find_path (UV_ROOT_DIR "uv.h" PATHS /usr/include/compat-libuv010 NO_DEFAULT_PATH) +if (UV_ROOT_DIR) + # set (NODEJS_INCLUDE_DIRS ${UV_ROOT_DIR}) + add_include_dir(${UV_ROOT_DIR}) +endif() + +# Now look for node. Flag an error if not found +find_path (NODE_ROOT_DIR "node/node.h" "src/node.h" + PATHS /usr/include/nodejs /usr/local/include/nodejs /usr/local/include) +if (NODE_ROOT_DIR) + add_include_dir(${NODE_ROOT_DIR}/src) + add_include_dir(${NODE_ROOT_DIR}/node) + add_include_dir(${NODE_ROOT_DIR}/deps/v8/include) + add_include_dir(${NODE_ROOT_DIR}/deps/uv/include) +else() + unset(NODEJS_INCLUDE_DIRS) + message(ERROR " - node.h not found") +endif() + +# Check that v8.h is in NODEJS_INCLUDE_DIRS +find_path (V8_ROOT_DIR "v8.h" PATHS ${NODEJS_INCLUDE_DIRS}) +if (NOT V8_ROOT_DIR) + unset(NODEJS_INCLUDE_DIRS) + message(ERROR " - v8.h not found") +endif() + +# Check that uv.h is in NODEJS_INCLUDE_DIRS +find_path (UV_ROOT_DIR "uv.h" PATHS ${NODEJS_INCLUDE_DIRS}) +if (NOT UV_ROOT_DIR) + unset(NODEJS_INCLUDE_DIRS) + message(ERROR " - uv.h not found") +endif() + +find_package_handle_standard_args (Nodejs DEFAULT_MSG + NODEJS_EXECUTABLE + NODEJS_INCLUDE_DIRS +) + +if (NODEJS_EXECUTABLE) + execute_process(COMMAND ${NODEJS_EXECUTABLE} --version + OUTPUT_VARIABLE _VERSION + RESULT_VARIABLE _NODE_VERSION_RESULT) + execute_process(COMMAND ${NODEJS_EXECUTABLE} -e "console.log(process.versions.v8)" + OUTPUT_VARIABLE _V8_VERSION + RESULT_VARIABLE _V8_RESULT) + if (NOT _NODE_VERSION_RESULT AND NOT _V8_RESULT) + string (REPLACE "v" "" NODE_VERSION_STRING "${_VERSION}") + string (REPLACE "." ";" _VERSION_LIST "${NODE_VERSION_STRING}") + list (GET _VERSION_LIST 0 NODE_VERSION_MAJOR) + list (GET _VERSION_LIST 1 NODE_VERSION_MINOR) + list (GET _VERSION_LIST 2 NODE_VERSION_PATCH) + set (V8_VERSION_STRING ${_V8_VERSION}) + string (REPLACE "." ";" _V8_VERSION_LIST "${_V8_VERSION}") + list (GET _V8_VERSION_LIST 0 V8_VERSION_MAJOR) + list (GET _V8_VERSION_LIST 1 V8_VERSION_MINOR) + list (GET _V8_VERSION_LIST 2 V8_VERSION_PATCH) + # we end up with a nasty newline so strip everything that isn't a number + string (REGEX MATCH "^[0-9]*" V8_VERSION_PATCH ${V8_VERSION_PATCH}) + else () + set (NODE_VERSION_STRING "0.10.30") + set (NODE_VERSION_MAJOR "0") + set (NODE_VERSION_MINOR "10") + set (NODE_VERSION_PATCH "30") + set (V8_VERSION_MAJOR "3") + set (V8_VERSION_MINOR"14") + set (V8_VERSION_PATCH "5") + set (V8_VERSION_STRING "3.28.72") + message ("defaulted to node 0.10.30") + endif () + string (REGEX REPLACE "\n" "" NODE_VERSION_STRING ${NODE_VERSION_STRING}) + string (REGEX REPLACE "\n" "" V8_VERSION_STRING ${V8_VERSION_STRING}) + message ("INFO - Node version is " ${NODE_VERSION_STRING}) + message ("INFO - Node using v8 " ${V8_VERSION_STRING}) + mark_as_advanced (NODEJS_EXECUTABLE) +endif () + diff --git a/swig/javascript/CMakeLists.txt b/swig/javascript/CMakeLists.txt new file mode 100644 index 000000000..5ac9d520e --- /dev/null +++ b/swig/javascript/CMakeLists.txt @@ -0,0 +1,116 @@ +find_package(Nodejs REQUIRED) +find_package(SWIG REQUIRED) +include(${SWIG_USE_FILE}) + +include_directories( + ${NODEJS_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_SOURCE_DIR}/src +) + +set(V8_VERSION_HEX 0x0${V8_VERSION_MAJOR}${V8_VERSION_MINOR}${V8_VERSION_PATCH}) +string(LENGTH "${V8_VERSION_HEX}" V8_VERSION_HEX_length) +while(V8_VERSION_HEX_length LESS 8) + set(V8_VERSION_HEX "${V8_VERSION_HEX}0") + message(DEBUG " - Padded V8 version to match SWIG format") + string(LENGTH "${V8_VERSION_HEX}" V8_VERSION_HEX_length) +endwhile() + +set_property(SOURCE ${CMAKE_SOURCE_DIR}/swig/javascript/libyang_javascript.i PROPERTY SWIG_FLAGS "-node" "-I${CMAKE_BINARY_DIR}/src" "-DV8_VERSION=${V8_VERSION_HEX}") + +set_source_files_properties(${CMAKE_SOURCE_DIR}/swig/javascript/libyang_javascript.i PROPERTIES CPLUSPLUS ON) + +swig_add_module(libyang_javascript javascript ${CMAKE_SOURCE_DIR}/swig/javascript/libyang_javascript.i ${libsrc} ${PCRE_INCLUDE_DIRS} ) + +# link math +swig_link_libraries(libyang_javascript m) + +# find pthreads +swig_link_libraries(libyang_javascript ${CMAKE_THREAD_LIBS_INIT}) + +# find PCRE library +swig_link_libraries(libyang_javascript ${PCRE_LIBRARIES}) + + +set_target_properties(libyang_javascript PROPERTIES + COMPILE_FLAGS " -DJAVASCRIPT_BINDING=ON" + PREFIX "" + OUTPUT_NAME libyang_javascript + SUFFIX ".node" +) + +function(PREPEND var prefix) + set(listVar "") + foreach(f ${ARGN}) + list(APPEND listVar "${prefix}/${f}") + endforeach(f) + set(${var} "${listVar}" PARENT_SCOPE) +endfunction(PREPEND) + +message(INFO " - swig Version ${SWIG_VERSION}") +message(INFO " - CXX compiler Version ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") + +if(${V8_VERSION_MAJOR} GREATER 3) + message(INFO " - Using V8 version > 3 so requiring C++11 compiler") + if(CMAKE_VERSION VERSION_LESS "3.1") + message(INFO " - **WARNING** Need to use CMAKE version 3.1+, but it is ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}") + message(INFO " - So a workaround will be used.") + if(CMAKE_COMPILER_IS_GNUCXX) + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.7") + message(FATAL_ERROR " FATAL ERROR: GNU gcc compiler is also too old (need 4.7+, but ${CMAKE_CXX_COMPILER_VERSION}) and does not support C++11 standard.") + endif() + set(LIBYANG_CXX11_WORKAROUND_OPTION "-std=gnu++11") + else() + set(LIBYANG_CXX11_WORKAROUND_OPTION "-std=c++11") + endif() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBYANG_CXX11_WORKAROUND_OPTION} ") + endif() +endif() + +macro (libyang_CREATE_INSTALL_PACKAGE_JSON generated_file install_location) + configure_file(${CMAKE_SOURCE_DIR}/swig/javascript/${generated_file}.cmake ${CMAKE_CURRENT_BINARY_DIR}/${generated_file} @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${generated_file} DESTINATION ${install_location}) +endmacro (libyang_CREATE_INSTALL_PACKAGE_JSON) +libyang_create_install_package_json(package.json lib/node_modules/libyang) + +macro (libyang_CREATE_BINDING_GYP generated_file) + set(libyang_LIB_SRCS_GYP "") + #set(libyang_NPM_SRCS ${libsrc}) + PREPEND(libyang_NPM_SRCS ${PROJECT_SOURCE_DIR} ${libsrc}) + + foreach(srcfile ${libyang_NPM_SRCS}) + file(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${srcfile}) + set(libyang_LIB_SRCS_GYP "'${rel}',\n${libyang_LIB_SRCS_GYP}") + endforeach(srcfile) + + PREPEND(libyang_NPM_LIBS ${PROJECT_SOURCE_DIR} "${PCRE_LIBRARIES}") + foreach(srcfile ${libyang_NPM_LIBS}) + file(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${srcfile}) + set(libyang_LIB_THIRD_PARTY_GYP "'-L/${rel}',\n${libyang_LIB_THIRD_PARTY_GYP}") + endforeach(srcfile) + + PREPEND(libyang_LIB_INCLUDE_DIRS ${PROJECT_SOURCE_DIR} ${PCRE_LIBRARIES}) + PREPEND(${libyang_LIB_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR} ${PCRE_INCLUDE_DIRS}) + foreach(includedir ${libyang_LIB_INCLUDE_DIRS}) + file(RELATIVE_PATH rel ${CMAKE_SOURCE_DIR} ${includedir}) + set(libyang_LIB_INCLUDE_DIRS_GYP "'${rel}',\n${libyang_LIB_INCLUDE_DIRS_GYP}") + endforeach(includedir) + + configure_file(${CMAKE_SOURCE_DIR}/swig/javascript/${generated_file}.cmake ${CMAKE_CURRENT_BINARY_DIR}/${generated_file} @ONLY) +endmacro (libyang_CREATE_BINDING_GYP) +libyang_create_binding_gyp(binding.gyp) + +set(SWIG_DEST "javascript") +file(COPY "${CMAKE_SOURCE_DIR}/src" DESTINATION ${SWIG_DEST}) +file(COPY "${CMAKE_SOURCE_DIR}/models" DESTINATION ${SWIG_DEST}) + +add_custom_target(npmpkg) +add_custom_command(TARGET npmpkg POST_BUILD + COMMENT "start building node package" + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/libyang_javascriptJAVASCRIPT_wrap.cxx "${SWIG_DEST}/src/" + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/package.json ${SWIG_DEST} + COMMAND sed -i "'s/libyang.node/build\\/Release\\/libyang.node/'" ${SWIG_DEST}/package.json + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/binding.gyp ${SWIG_DEST} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/libyang_javascript.node ${SWIG_DEST}) +add_dependencies (npmpkg libyang_javascript) + diff --git a/swig/javascript/binding.gyp.cmake b/swig/javascript/binding.gyp.cmake new file mode 100644 index 000000000..999615dd5 --- /dev/null +++ b/swig/javascript/binding.gyp.cmake @@ -0,0 +1,34 @@ +{ + 'targets': [{ + 'target_name': 'libyang', + 'sources': [ +@libyang_LIB_SRCS_GYP@ + 'src/libyang_javascriptJAVASCRIPT_wrap.cxx' ], + 'include_dirs': [ +@libyang_LIB_INCLUDE_DIRS_GYP@ + ], + 'libraries': [ + "-lpcre" + ], + 'variables': { + "arch%": "= 0.10.x" + }, +} From d8e86860f2e76a7e62d37c3228fb2dcdd0802abf Mon Sep 17 00:00:00 2001 From: Mislav Novakovic Date: Tue, 1 Mar 2016 13:18:01 +0100 Subject: [PATCH 3/3] add README for javascript bindings Signed-off-by: Mislav Novakovic --- README.md | 17 +++++++++++++++++ swig/javascript/README.md | 26 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 swig/javascript/README.md diff --git a/README.md b/README.md index b7c646d77..fb46e1d4c 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,23 @@ Tests can be run by the make's `test` target: $ make test ``` +## node binding + +Requirements + +* swig +* node +* node-gyp + +``` +$ cmake -DJAVASCRIPT_BINDING=ON .. +$ make npmpkg +$ cd javascript +$ node-gyp configure build +``` + +There is also [README](./swig/javascript/README.md) describing this more in detail. + ## yanglint libyang source codes include a simple example tool to demanstrate how an application diff --git a/swig/javascript/README.md b/swig/javascript/README.md new file mode 100644 index 000000000..7ef7248d4 --- /dev/null +++ b/swig/javascript/README.md @@ -0,0 +1,26 @@ +## Requirements + +* swig +* node +* node-gyp + +## Istall + +``` +$ cmake -DJAVASCRIPT_BINDING=ON .. +$ make +$ make npmpkg +$ cd javascript +$ node-gyp configure build +``` + +More details on swig's javascript bindings can be found at [SWIG](http://www.swig.org/Doc3.0/Javascript.html#Javascript_node_extensions). + +## Usage + +To include the node bindings simply use it with. + +``` +yang = require("/javascript/build/Release/yang") +``` +